From cdd4bc0b411d6834952434b80313b5ee0b131db0 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sat, 5 Dec 2015 13:20:26 -0500 Subject: telnet support --- Makefile | 2 +- src/client.c | 9 +++++++++ src/netcosm.h | 8 ++++++++ src/telnet.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/telnet.h | 20 ++++++++++++++++++++ 5 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/telnet.c create mode 100644 src/telnet.h diff --git a/Makefile b/Makefile index 45107c1..0539e7d 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CC = clang OUT = build PLATFORM = unix -NETCOSM_OBJ = src/server.o src/client.o src/auth.o +NETCOSM_OBJ = src/server.o src/client.o src/auth.o src/telnet.o CFLAGS = -O0 -g -I src/ -I target/$(PLATFORM) -Wall -Wextra LDFLAGS = -lgcrypt diff --git a/src/client.c b/src/client.c index 5555bd5..18c390c 100644 --- a/src/client.c +++ b/src/client.c @@ -13,6 +13,11 @@ void __attribute__((format(printf,1,2))) out(const char *fmt, ...) write(client_fd, buf, sizeof(buf)); } +void out_raw(const unsigned char *buf, size_t len) +{ + write(client_fd, buf, len); +} + #define BUFSZ 128 char *client_read(void) @@ -32,6 +37,8 @@ tryagain: printf("Read '%s'\n", buf); if(buf[0] & 0x80) { + telnet_handle_command((unsigned char*)buf); + free(buf); goto tryagain; } @@ -54,6 +61,8 @@ void client_main(int fd, struct sockaddr_in *addr, int total) { client_fd = fd; + telnet_init(); + char *ip = inet_ntoa(addr->sin_addr); printf("New client %s\n", ip); printf("Total clients: %d\n", total); diff --git a/src/netcosm.h b/src/netcosm.h index 4f04e5b..c8566da 100644 --- a/src/netcosm.h +++ b/src/netcosm.h @@ -18,6 +18,8 @@ #include #include +#include "telnet.h" + #define USERFILE "users.dat" #define MAX_FAILURES 3 #define NETCOSM_VERSION "v0.1" @@ -40,3 +42,9 @@ struct authinfo_t auth_check(const char*, const char*); /* add or change a user */ bool add_change_user(const char *user2, const char *pass2, int level); bool auth_remove(const char*); +void telnet_handle_command(const unsigned char*); +#define ARRAYLEN(x) (sizeof(x)/sizeof(x[0])) + +void out(const char *fmt, ...) __attribute__((format(printf,1,2))); +void out_raw(const unsigned char*, size_t); +void telnet_init(void); diff --git a/src/telnet.c b/src/telnet.c new file mode 100644 index 0000000..2e86195 --- /dev/null +++ b/src/telnet.c @@ -0,0 +1,61 @@ +#include "netcosm.h" + +void telnet_handle_command(const unsigned char *buf) +{ + bool cmd = false; + + while(*buf) + { + unsigned char c = *buf; + + const struct telnet_cmd { + int val; + const char *name; + } commands[] = { + { IAC, "IAC" }, + { DONT, "DONT" }, + { DO, "DO" }, + { WONT, "WONT" }, + { WILL, "WILL" }, + { GA, "GA" }, + { AYT, "AYT" }, + { NOP, "NOP" }, + { SB, "SB" }, + { SE, "SE" }, + { ECHO, "ECHO" }, + { SGA, "SGA" }, + { STATUS, "STATUS" }, + { NAWS, "NAWS" } + }; + + for(unsigned int i = 0; i < ARRAYLEN(commands); ++i) + { + if(c == commands[i].val) + { + printf("%s ", commands[i].name); + cmd = true; + goto found; + } + } + printf("??? "); + found: + + ++buf; + } + + if(cmd) + printf("\n"); +} + +void telnet_init(void) +{ + const unsigned char init_seq[] = { + IAC, WONT, SGA, + IAC, DONT, SGA, + IAC, WONT, NAWS, + IAC, DONT, NAWS, + IAC, WONT, STATUS, + IAC, DONT, STATUS, + }; + out_raw(init_seq, ARRAYLEN(init_seq)); +} diff --git a/src/telnet.h b/src/telnet.h new file mode 100644 index 0000000..475cfce --- /dev/null +++ b/src/telnet.h @@ -0,0 +1,20 @@ +/* commands */ + +#define IAC 255 +#define DONT 254 +#define DO 253 +#define WONT 252 +#define WILL 251 +#define SB 250 +#define GA 249 +#define EL 248 +#define EC 247 +#define AYT 246 +#define NOP 241 +#define SE 240 + +/* options */ +#define ECHO 1 +#define SGA 3 +#define STATUS 5 +#define NAWS 31 -- cgit v1.1