summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHåkon Nessjøen <haakon.nessjoen@gmail.com>2010-12-23 12:42:58 +0100
committerHåkon Nessjøen <haakon.nessjoen@gmail.com>2010-12-23 12:42:58 +0100
commit20746581ba3e8c6cda0851e47b27528401168247 (patch)
tree7594f410afaed522c4b035030076fd7932dc3161
parentfae8147bc4a3c646dfa852074266b23f8a242450 (diff)
downloadMAC-Telnet-20746581ba3e8c6cda0851e47b27528401168247.tar.gz
MAC-Telnet-20746581ba3e8c6cda0851e47b27528401168247.zip
Added u/wtmp logout code, and did some minior code cleanup.
-rw-r--r--mactelnetd.c87
1 files changed, 60 insertions, 27 deletions
diff --git a/mactelnetd.c b/mactelnetd.c
index bb7ad28..157c8de 100644
--- a/mactelnetd.c
+++ b/mactelnetd.c
@@ -23,6 +23,7 @@
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
+#include <time.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/in.h>
@@ -72,26 +73,30 @@ struct mt_connection {
unsigned int incounter;
unsigned int outcounter;
time_t lastdata;
+
int terminalMode;
+ int state;
+ int ptsfd;
+ int slavefd;
+ int pid;
+ int waitForAck;
+
unsigned char username[30];
unsigned char srcip[4];
unsigned char srcmac[6];
unsigned short srcport;
unsigned char dstmac[6];
unsigned char enckey[16];
- int state;
- int ptsfd;
- int slavefd;
- int pid;
unsigned short terminal_width;
unsigned short terminal_height;
unsigned char terminal_type[30];
- int waitForAck;
-
struct mt_connection *next;
};
+void uwtmp_login(struct mt_connection *);
+void uwtmp_logout(struct mt_connection *);
+
struct mt_connection *connections_head = NULL;
void list_addConnection(struct mt_connection *conn) {
@@ -120,6 +125,7 @@ void list_removeConnection(struct mt_connection *conn) {
close(conn->slavefd);
}
+ uwtmp_logout(conn);
if (connections_head == conn) {
connections_head = conn->next;
@@ -159,7 +165,7 @@ int sendUDP(const struct mt_connection *conn, const struct mt_packet *data) {
void displayMotd() {
FILE *fp;
int c;
-
+
if ((fp = fopen("/etc/motd", "r"))) {
while ((c = getc(fp)) != EOF) {
putchar(c);
@@ -171,7 +177,7 @@ void displayMotd() {
void displayNologin() {
FILE *fp;
int c;
-
+
if ((fp = fopen(_PATH_NOLOGIN, "r"))) {
while ((c = getc(fp)) != EOF) {
putchar(c);
@@ -180,13 +186,13 @@ void displayNologin() {
}
}
-void adduwtmp(struct mt_connection *curconn) {
+void uwtmp_login(struct mt_connection *conn) {
struct utmp utent;
pid_t pid;
pid = getpid();
- char *line = ttyname(curconn->slavefd);
+ char *line = ttyname(conn->slavefd);
if (strncmp(line, "/dev/", 5) == 0)
line += 5;
@@ -194,10 +200,10 @@ void adduwtmp(struct mt_connection *curconn) {
memset((void *) &utent, 0, sizeof(utent));
utent.ut_type = USER_PROCESS;
utent.ut_pid = pid;
- strncpy(utent.ut_user, curconn->username, sizeof(utent.ut_user));
+ strncpy(utent.ut_user, conn->username, sizeof(utent.ut_user));
strncpy(utent.ut_line, line, sizeof(utent.ut_line));
strncpy(utent.ut_id, utent.ut_line + 3, sizeof(utent.ut_id));
- strncpy(utent.ut_host,ether_ntoa((const struct ether_addr *)curconn->srcmac), sizeof(utent.ut_host));
+ strncpy(utent.ut_host,ether_ntoa((const struct ether_addr *)conn->srcmac), sizeof(utent.ut_host));
time(&utent.ut_time);
/* Update utmp and/or wtmp */
@@ -207,6 +213,31 @@ void adduwtmp(struct mt_connection *curconn) {
updwtmp(_PATH_WTMP, &utent);
}
+void uwtmp_logout(struct mt_connection *conn) {
+ if (conn->pid > 0) {
+ struct utmp *utentp;
+ struct utmp utent;
+ setutent();
+
+ while ((utentp = getutent()) != NULL) {
+ if (utentp->ut_pid == conn->pid && utentp->ut_id) {
+ break;
+ }
+ }
+
+ if (utentp) {
+ utent = *utentp;
+
+ utent.ut_type = DEAD_PROCESS;
+ utent.ut_tv.tv_sec = time(NULL);
+
+ pututline(&utent);
+ endutent();
+ updwtmp(_PATH_WTMP, &utent);
+ }
+ }
+}
+
void abortConnection(struct mt_connection *curconn, struct mt_mactelnet_hdr *pkthdr, char *message) {
struct mt_packet pdata;
@@ -220,7 +251,7 @@ void abortConnection(struct mt_connection *curconn, struct mt_mactelnet_hdr *pkt
sendUDP(curconn, &pdata);
}
-void doLogin(struct mt_connection *curconn, struct mt_mactelnet_hdr *pkthdr) {
+void userLogin(struct mt_connection *curconn, struct mt_mactelnet_hdr *pkthdr) {
struct mt_packet pdata;
unsigned char md5sum[17];
unsigned char md5data[100];
@@ -252,20 +283,21 @@ void doLogin(struct mt_connection *curconn, struct mt_mactelnet_hdr *pkthdr) {
return;
}
- if (user != NULL && memcmp(md5sum, trypassword, 17) == 0) {
- curconn->state = STATE_ACTIVE;
- } else {
+ if (user == NULL || memcmp(md5sum, trypassword, 17) != 0) {
syslog(LOG_NOTICE, "(%d) Invalid login by %s.", curconn->seskey, curconn->username);
- abortConnection(curconn, pkthdr, "Login FAILED!\r\n");
+ abortConnection(curconn, pkthdr, "Login failed, incorrect username or password\r\n");
/* TODO: should wait some time (not with sleep) before returning, to minimalize brute force attacks */
return;
}
+ /* User is logged in */
+ curconn->state = STATE_ACTIVE;
+
/* Enter terminal mode */
curconn->terminalMode = 1;
-
+
/* Open pts handle */
curconn->ptsfd = posix_openpt(O_RDWR);
if (curconn->ptsfd == -1 || grantpt(curconn->ptsfd) == -1 || unlockpt(curconn->ptsfd) == -1) {
@@ -279,7 +311,7 @@ void doLogin(struct mt_connection *curconn, struct mt_mactelnet_hdr *pkthdr) {
if (slavename != NULL) {
pid_t pid;
struct stat sb;
-
+
curconn->slavefd = open(slavename, O_RDWR);
if (curconn->slavefd == -1) {
syslog(LOG_ERR, "Error opening %s: %s", slavename, strerror(errno));
@@ -295,9 +327,9 @@ void doLogin(struct mt_connection *curconn, struct mt_mactelnet_hdr *pkthdr) {
abortConnection(curconn, pkthdr, "Local user not accessible\r\n");
return;
}
-
+
/* Add login information to utmp/wtmp */
- adduwtmp(curconn);
+ uwtmp_login(curconn);
syslog(LOG_INFO, "(%d) User %s logged in.", curconn->seskey, curconn->username);
@@ -429,7 +461,7 @@ void handleDataPacket(struct mt_connection *curconn, struct mt_mactelnet_hdr *pk
}
if (gotUserPacket && gotPassPacket) {
- doLogin(curconn, pkthdr);
+ userLogin(curconn, pkthdr);
}
if (curconn->state == STATE_ACTIVE && (gotWidthPacket || gotHeightPacket)) {
@@ -620,12 +652,13 @@ int main (int argc, char **argv) {
}
daemonize();
+
openlog("mactelnetd", LOG_PID, LOG_DAEMON);
-
+
syslog(LOG_NOTICE, "Bound to %s:%d", inet_ntoa(si_me.sin_addr), sourceport);
-
+
signal(SIGTERM, terminate);
-
+
while (1) {
int reads;
struct mt_connection *p;
@@ -645,8 +678,8 @@ int main (int argc, char **argv) {
}
}
- timeout.tv_sec = 0;
- timeout.tv_usec = 100000;
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
/* Wait for data or timeout */
reads = select(maxfd+1, &read_fds, NULL, NULL, &timeout);