summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile16
-rw-r--r--autologin.c154
-rw-r--r--autologin.h43
-rw-r--r--config.h4
-rw-r--r--docs/mactelnet.16
-rw-r--r--mactelnet.c46
6 files changed, 203 insertions, 66 deletions
diff --git a/Makefile b/Makefile
index 7bf4f1f..ac91d91 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,10 @@ pot: po/mactelnet.pot
po/mactelnet.pot: *.c
xgettext --package-name=mactelnet --msgid-bugs-address=haakon.nessjoen@gmail.com -d mactelnet -C -c_ -k_ -kgettext_noop *.c -o po/mactelnet.pot
-
+
+autologin.o: autologin.c autologin.h
+ ${CC} -Wall ${CFLAGS} -c autologin.c
+
users.o: users.c users.h
${CC} -Wall ${CFLAGS} -DUSERSFILE='"/etc/mactelnetd.users"' -c users.c
@@ -47,11 +50,14 @@ interfaces.o: interfaces.c interfaces.h
md5.o: md5.c md5.h
${CC} -Wall ${CFLAGS} -c md5.c
-mactelnet: config.h mactelnet.c mactelnet.h protocol.o console.c console.h interfaces.o md5.o mndp.c
- ${CC} -Wall ${CFLAGS} ${LDFLAGS} -o mactelnet mactelnet.c protocol.o console.c interfaces.o md5.o -DFROM_MACTELNET mndp.c ${LIBS}
+console.o: console.c
+ ${CC} -Wall ${CFLAGS} -c console.c
+
+mactelnet: config.h mactelnet.c mactelnet.h protocol.o console.o interfaces.o md5.o mndp.c autologin.o
+ ${CC} -Wall ${CFLAGS} ${LDFLAGS} -o mactelnet mactelnet.c protocol.o console.o interfaces.o md5.o autologin.o -DFROM_MACTELNET mndp.c ${LIBS}
-mactelnetd: config.h mactelnetd.c protocol.o interfaces.o console.c console.h users.o users.h md5.o
- ${CC} -Wall ${CFLAGS} ${LDFLAGS} -o mactelnetd mactelnetd.c protocol.o console.c interfaces.o users.o md5.o ${LIBS}
+mactelnetd: config.h mactelnetd.c protocol.o interfaces.o console.o users.o users.h md5.o
+ ${CC} -Wall ${CFLAGS} ${LDFLAGS} -o mactelnetd mactelnetd.c protocol.o console.o interfaces.o users.o md5.o ${LIBS}
mndp: config.h mndp.c protocol.o
${CC} -Wall ${CFLAGS} ${LDFLAGS} -o mndp mndp.c protocol.o ${LIBS}
diff --git a/autologin.c b/autologin.c
index 45a269a..b3d5d5e 100644
--- a/autologin.c
+++ b/autologin.c
@@ -1,42 +1,89 @@
+/*
+ Mac-Telnet - Connect to RouterOS or mactelnetd devices via MAC address
+ Copyright (C) 2010, Håkon Nessjøen <haakon.nessjoen@gmail.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <libintl.h>
+#include <locale.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include "autologin.h"
+#include "config.h"
+
+#define _(String) gettext (String)
+
+struct autologin_profile login_profiles[AUTOLOGIN_MAXPROFILES];
+
+struct autologin_profile *autologin_find_profile(char *identifier) {
+ int i;
+ struct autologin_profile *default_profile = NULL;
+
+ if (strlen(identifier) == 0) return NULL;
+
+ for (i = 0; i < AUTOLOGIN_MAXPROFILES; ++i) {
+ if (login_profiles[i].inuse && strcasecmp(identifier, login_profiles[i].identifier) == 0) {
+ return &login_profiles[i];
+ }
+ if (login_profiles[i].inuse && strcasecmp("default", login_profiles[i].identifier) == 0) {
+ default_profile = &login_profiles[i];
+ }
+ }
+ return default_profile;
+}
+
+static char *tilde_to_path(char *path) {
+ char *homepath;
+ if (*path == '~' && (homepath = getenv("HOME"))) {
+ static char newpath[256];
+ memset(newpath, 0, sizeof(newpath));
+ strncpy(newpath, homepath, 255);
+ strncat(newpath, path+1, 255);
+ return newpath;
+ }
+ return path;
+}
-#define AUTOLOGIN_PATH ".mactelnet"
-#define AUTOLOGIN_MAXSTR 100
-#define AUTOLOGIN_MAXPROFILES 100
-
-struct autologin {
- char identifier[AUTOLOGIN_MAXSTR];
- char username[AUTOLOGIN_MAXSTR];
- char password[AUTOLOGIN_MAXSTR];
- char inuse:1;
- char hasUsername:1;
- char hasPassword:1;
-};
-
-struct autologin logins[AUTOLOGIN_MAXPROFILES];
-
-enum autologin_state {
- ALS_NONE,
- ALS_PREIDENTIFIER,
- ALS_IDENTIFIER,
- ALS_PREKEY,
- ALS_KEY,
- ALS_PREVALUE,
- ALS_VALUE
-};
-#define AL_NONE 0
-
-int main() {
+int autologin_readfile(char *configfile) {
FILE *fp;
char c;
int i = -1;
char *p;
+ char *file_to_read;
char key[AUTOLOGIN_MAXSTR];
char value[AUTOLOGIN_MAXSTR];
int line_counter=1;
enum autologin_state state = ALS_NONE;
- fp = fopen(AUTOLOGIN_PATH, "r");
+
+ memset(login_profiles, 0, sizeof(login_profiles));
+
+ /* Convert ~/path to /home/username/path */
+ file_to_read = tilde_to_path(configfile);
+
+ fp = fopen(file_to_read, "r");
+ if (fp <= 0) {
+ if (strcmp(configfile, AUTOLOGIN_PATH) == 0) {
+ /* Silent ignore? */
+ } else {
+ fprintf(stderr, _("Error opening autologin file %s: %s\n"), file_to_read, strerror(errno));
+ }
+ return 0;
+ }
while ((c = fgetc(fp)) && !feof(fp)) {
if (c == '#') {
while ((c = fgetc(fp)) != '\n' && !feof(fp));
@@ -48,7 +95,7 @@ int main() {
if (i == AUTOLOGIN_MAXPROFILES) {
goto done;
}
- p = logins[i].identifier;
+ p = login_profiles[i].identifier;
state++;
break;
@@ -56,7 +103,7 @@ int main() {
memset(key, 0, AUTOLOGIN_MAXSTR);
memset(value, 0, AUTOLOGIN_MAXSTR);
p = key;
- logins[i].inuse = 1;
+ login_profiles[i].inuse = 1;
state++;
break;
@@ -65,6 +112,8 @@ int main() {
p = value;
state++;
break;
+ default:
+ break;
}
switch (state) {
@@ -76,19 +125,18 @@ int main() {
case ALS_IDENTIFIER:
if (c == ']') {
- //fprintf(stderr, "debug: identifier %s on line %d\n", logins[i].identifier, line_counter);
state = ALS_PREKEY;
break;
}
if (c == '\n') {
- fprintf(stderr, "Error on line %d in %s: New line in middle of identifier\n", line_counter, AUTOLOGIN_PATH);
+ fprintf(stderr, _("Error on line %d in %s: New line in middle of identifier\n"), line_counter, configfile);
state = ALS_NONE;
break;
}
*p++ = c;
- if (p - logins[i].identifier == AUTOLOGIN_MAXSTR-1) {
+ if (p - login_profiles[i].identifier == AUTOLOGIN_MAXSTR-1) {
*p = 0;
- fprintf(stderr, "Error on line %d in %s: Identifier string too long.\n", line_counter, AUTOLOGIN_PATH);
+ fprintf(stderr, _("Error on line %d in %s: Identifier string too long.\n"), line_counter, configfile);
while ((c = fgetc(fp)) != '\n' && c != ']' && !feof(fp));
state = ALS_PREKEY;
break;
@@ -105,18 +153,18 @@ int main() {
state = ALS_PREIDENTIFIER;
break;
}
- if (c == ' ') { // ignore whitespace
+ if (c == ' ') { /* ignore whitespace */
break;
}
if (c == '\n') {
- fprintf(stderr, "Error on line %d in %s: Newline before '=' character\n", line_counter, AUTOLOGIN_PATH);
+ fprintf(stderr, _("Error on line %d in %s: Newline before '=' character\n"), line_counter, configfile);
state = ALS_PREKEY;
break;
}
*p++ = c;
if (p - key == AUTOLOGIN_MAXSTR-1) {
*p = 0;
- fprintf(stderr, "Error on line %d in %s: Key string too long.\n", line_counter, AUTOLOGIN_PATH);
+ fprintf(stderr, _("Error on line %d in %s: Key string too long.\n"), line_counter, configfile);
while ((c = fgetc(fp)) != '\n' && c != '=' && !feof(fp));
if (c == '\n') {
state = ALS_PREKEY;
@@ -130,30 +178,33 @@ int main() {
if (p == value && c == '\n') break;
if (c == '\n') {
if (strncasecmp(key, "user", AUTOLOGIN_MAXSTR) == 0) {
- strncpy(logins[i].username, value, AUTOLOGIN_MAXSTR);
- logins[i].hasUsername = 1;
+ strncpy(login_profiles[i].username, value, AUTOLOGIN_MAXSTR);
+ login_profiles[i].hasUsername = 1;
} else if (strncasecmp(key, "password", AUTOLOGIN_MAXSTR) == 0) {
- strncpy(logins[i].password, value, AUTOLOGIN_MAXSTR);
- logins[i].hasPassword = 1;
+ strncpy(login_profiles[i].password, value, AUTOLOGIN_MAXSTR);
+ login_profiles[i].hasPassword = 1;
} else {
- fprintf(stderr, "Warning on line %d of %s: Unknown parameter %s, ignoring.\n", line_counter, AUTOLOGIN_PATH, key);
+ fprintf(stderr, _("Warning on line %d of %s: Unknown parameter %s, ignoring.\n"), line_counter, configfile, key);
}
state = ALS_PREKEY;
break;
}
- if (c == ' ') { // ignore whitespace
+ if (c == ' ') { /* ignore whitespace */
break;
}
*p++ = c;
if (p - value == AUTOLOGIN_MAXSTR-1) {
*p = 0;
- fprintf(stderr, "Error on line %d in %s: Value string too long.\n", line_counter, AUTOLOGIN_PATH);
+ fprintf(stderr, _("Error on line %d in %s: Value string too long.\n"), line_counter, configfile);
while ((c = fgetc(fp)) != '\n' && !feof(fp));
if (c == '\n') {
state = ALS_PREKEY;
}
}
break;
+
+ default:
+ break;
}
if (c == '\n') {
line_counter++;
@@ -166,18 +217,5 @@ int main() {
done:
fclose(fp);
- printf("\n\nConfig:\n");
- for (i = 0; i < 100; ++i) {
- if (logins[i].inuse) {
- printf("Profile: '%s'\n", logins[i].identifier);
- if (logins[i].hasUsername) {
- printf("\tUsername: '%s'\n", logins[i].username);
- }
- if (logins[i].hasPassword) {
- printf("\tPassword: '%s'\n", logins[i].password);
- }
- printf("\n");
- }
- }
-
+ return 1;
}
diff --git a/autologin.h b/autologin.h
new file mode 100644
index 0000000..2877dfe
--- /dev/null
+++ b/autologin.h
@@ -0,0 +1,43 @@
+/*
+ Mac-Telnet - Connect to RouterOS or mactelnetd devices via MAC address
+ Copyright (C) 2010, Håkon Nessjøen <haakon.nessjoen@gmail.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#define AUTOLOGIN_MAXSTR 100
+#define AUTOLOGIN_MAXPROFILES 100
+
+struct autologin_profile {
+ char identifier[AUTOLOGIN_MAXSTR];
+ char username[AUTOLOGIN_MAXSTR];
+ char password[AUTOLOGIN_MAXSTR];
+ char inuse:1;
+ char hasUsername:1;
+ char hasPassword:1;
+};
+
+enum autologin_state {
+ ALS_NONE,
+ ALS_PREIDENTIFIER,
+ ALS_IDENTIFIER,
+ ALS_PREKEY,
+ ALS_KEY,
+ ALS_PREVALUE,
+ ALS_VALUE
+};
+
+extern struct autologin_profile login_profiles[AUTOLOGIN_MAXPROFILES];
+struct autologin_profile *autologin_find_profile(char *identifier);
+int autologin_readfile(char *configfile);
diff --git a/config.h b/config.h
index c6c4148..80d81d3 100644
--- a/config.h
+++ b/config.h
@@ -21,7 +21,9 @@
#define DEBUG 0
-#define PROGRAM_VERSION "0.4.0"
+#define PROGRAM_VERSION "0.4.1"
+
+#define AUTOLOGIN_PATH "~/.mactelnet"
#if defined(__APPLE__) && defined(__MACH__)
#define PLATFORM_NAME "Mac OS X"
diff --git a/docs/mactelnet.1 b/docs/mactelnet.1
index d29591d..e711f7f 100644
--- a/docs/mactelnet.1
+++ b/docs/mactelnet.1
@@ -33,6 +33,12 @@ Specify username. Without this option, you will need to enter the username in a
.B \-p
Specify password. Without this option, you will need to enter the password in a interactive prompt.
.TP
+.B \-a
+Specify the path of the autologin configuration file. The default path for this file is ~/.mactelnet. The format for this file is standard INI file layout.
+.TP
+.B \-A
+Do not use the autologin configuration file. Interactively ask for username and password.
+.TP
.B \-h
Show summary of options.
.TP
diff --git a/mactelnet.c b/mactelnet.c
index 7710cc1..0f86250 100644
--- a/mactelnet.c
+++ b/mactelnet.c
@@ -46,6 +46,7 @@
#include "config.h"
#include "mactelnet.h"
#include "mndp.h"
+#include "autologin.h"
#define PROGRAM_NAME "MAC-Telnet"
@@ -76,6 +77,9 @@ static int mndp_timeout = 0;
static int is_a_tty = 1;
static int quiet_mode = 0;
static int batch_mode = 0;
+static int no_autologin = 0;
+
+static char autologin_path[255];
static int keepalive_counter = 0;
@@ -434,18 +438,21 @@ int main (int argc, char **argv) {
int result;
struct mt_packet data;
struct sockaddr_in si_me;
+ struct autologin_profile *login_profile;
unsigned char buff[1500];
unsigned char print_help = 0, have_username = 0, have_password = 0;
unsigned char drop_priv = 0;
int c;
int optval = 1;
+ strncpy(autologin_path, AUTOLOGIN_PATH, 254);
+
setlocale(LC_ALL, "");
bindtextdomain("mactelnet","/usr/share/locale");
textdomain("mactelnet");
while (1) {
- c = getopt(argc, argv, "lnqt:u:p:U:vh?B");
+ c = getopt(argc, argv, "lnqt:u:p:U:vh?BAa:");
if (c == -1) {
break;
@@ -501,6 +508,15 @@ int main (int argc, char **argv) {
case 'B':
batch_mode = 1;
+ break;
+
+ case 'A':
+ no_autologin = 1;
+ break;
+
+ case 'a':
+ strncpy(autologin_path, optarg, 254);
+ break;
case 'h':
case '?':
@@ -514,7 +530,7 @@ int main (int argc, char **argv) {
}
if (argc - optind < 1 || print_help) {
print_version();
- fprintf(stderr, _("Usage: %s <MAC|identity> [-h] [-n] [-t <timeout>] [-u <user>] [-p <password>] [-U <user>] | -l [-B] [-t <timeout>]\n"), argv[0]);
+ fprintf(stderr, _("Usage: %s <MAC|identity> [-h] [-n] [-a <path>] [-A] [-t <timeout>] [-u <user>] [-p <password>] [-U <user>] | -l [-B] [-t <timeout>]\n"), argv[0]);
if (print_help) {
fprintf(stderr, _("\nParameters:\n"
@@ -526,6 +542,8 @@ int main (int argc, char **argv) {
" -B Batch mode. Use computer readable output (CSV), for use with -l.\n"
" -n Do not use broadcast packets. Less insecure but requires\n"
" root privileges.\n"
+ " -a <path> Use specified path instead of the default: " AUTOLOGIN_PATH " for autologin config file.\n"
+ " -A Disable autologin feature.\n"
" -t <timeout> Amount of seconds to wait for a response on each interface.\n"
" -u <user> Specify username on command line.\n"
" -p <password> Specify password on command line.\n"
@@ -543,6 +561,30 @@ int main (int argc, char **argv) {
quiet_mode = 1;
}
+ if (!no_autologin) {
+ autologin_readfile(autologin_path);
+ login_profile = autologin_find_profile(argv[optind]);
+
+ if (!quiet_mode && login_profile != NULL && (login_profile->hasUsername || login_profile->hasPassword)) {
+ fprintf(stderr, _("Using autologin credentials from %s\n"), autologin_path);
+ }
+ if (!have_username) {
+ if (login_profile != NULL && login_profile->hasUsername) {
+ have_username = 1;
+ strncpy(username, login_profile->username, sizeof(username) - 1);
+ username[sizeof(username) - 1] = '\0';
+ }
+ }
+
+ if (!have_password) {
+ if (login_profile != NULL && login_profile->hasPassword) {
+ have_password = 1;
+ strncpy(password, login_profile->password, sizeof(password) - 1);
+ password[sizeof(password) - 1] = '\0';
+ }
+ }
+ }
+
/* Seed randomizer */
srand(time(NULL));