aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2015-12-05 13:20:26 -0500
committerFranklin Wei <git@fwei.tk>2015-12-05 13:20:26 -0500
commitcdd4bc0b411d6834952434b80313b5ee0b131db0 (patch)
tree215ce96e0f2de497bd257f582384aba49d5942bf
parent8fca7ee4076aaefe7122be86abda5e9ae6a50ff7 (diff)
downloadnetcosm-cdd4bc0b411d6834952434b80313b5ee0b131db0.zip
netcosm-cdd4bc0b411d6834952434b80313b5ee0b131db0.tar.gz
netcosm-cdd4bc0b411d6834952434b80313b5ee0b131db0.tar.bz2
netcosm-cdd4bc0b411d6834952434b80313b5ee0b131db0.tar.xz
telnet support
-rw-r--r--Makefile2
-rw-r--r--src/client.c9
-rw-r--r--src/netcosm.h8
-rw-r--r--src/telnet.c61
-rw-r--r--src/telnet.h20
5 files changed, 99 insertions, 1 deletions
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 <time.h>
#include <unistd.h>
+#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