From 027c047b420c26c33c8ac2f67e75ade1d2b5f469 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Thu, 1 Feb 2018 13:42:57 +1000 Subject: [PATCH] some debugging IAC codes in file transfers --- .gitignore | 1 + src/bbs.c | 65 ++++++++++++++++++++++++++++++------- src/bbs.h | 9 ++++++ src/doors.c | 45 ++++++++++++++++++++++++++ src/files.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 196 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index d16aea4..feadff4 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ config/* illusion/* scripts/* logs/* +files/* *.a deps/lua/lua deps/lua/luac diff --git a/src/bbs.c b/src/bbs.c index a21d117..8353226 100644 --- a/src/bbs.c +++ b/src/bbs.c @@ -21,6 +21,8 @@ #include "lua/lauxlib.h" +int telnet_bin_mode = 0; + int mynode = 0; struct bbs_config conf; @@ -384,9 +386,15 @@ void s_displayansi(char *file) { } } + char s_getchar() { unsigned char c; + unsigned char d; int len; + char iac_binary_will[] = {IAC, IAC_WILL, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_do[] = {IAC, IAC_DO, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_wont[] = {IAC, IAC_WONT, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_dont[] = {IAC, IAC_DONT, IAC_TRANSMIT_BINARY, '\0'}; do { @@ -401,19 +409,58 @@ char s_getchar() { } if (!sshBBS) { - while (c == 255) { + while (c == IAC) { len = read(gSocket, &c, 1); if (len == 0) { disconnect("Socket Closed"); - } else if (c == 255) { + } else if (c == IAC) { usertimeout = 10; return c; } - if (c == 254 || c == 253 || c == 252 || c == 251) { - len = read(gSocket, &c, 1); + if (c == IAC_WILL || c == IAC_WONT || c == IAC_DO || c == IAC_DONT) { + len = read(gSocket, &d, 1); if (len == 0) { disconnect("Socket Closed"); } + + switch (c) { + case IAC_WILL: + fprintf(stderr, "IAC WILL %d\n", d); + if (d == 0) { + if (telnet_bin_mode != 1) { + telnet_bin_mode = 1; + write(gSocket, iac_binary_do, 3); + } + } + break; + case IAC_WONT: + fprintf(stderr, "IAC WONT %d\n", d); + if (d == 0) { + if (telnet_bin_mode != 0) { + telnet_bin_mode = 0; + write(gSocket, iac_binary_dont, 3); + } + } + break; + case IAC_DO: + fprintf(stderr, "IAC DO %d\n", d); + if (d == 0) { + if (telnet_bin_mode != 1) { + telnet_bin_mode = 1; + write(gSocket, iac_binary_will, 3); + } + } + break; + case IAC_DONT: + fprintf(stderr, "IAC DONT %d\n", d); + if (d == 0) { + if (telnet_bin_mode != 0) { + telnet_bin_mode = 0; + write(gSocket, iac_binary_wont, 3); + } + } + break; + } } else if (c == 250) { do { len = read(gSocket, &c, 1); @@ -695,9 +742,9 @@ void runbbs_real(int socket, char *ip, int ssh) { struct stat s; FILE *nodefile; int i; - char iac_echo[] = {255, 251, 1, '\0'}; - char iac_sga[] = {255, 251, 3, '\0'}; - char iac_binary[] = {255, 251, 0, '\0'}; + char iac_echo[] = {IAC, IAC_WILL, IAC_ECHO, '\0'}; + char iac_sga[] = {IAC, IAC_WILL, IAC_SUPPRESS_GO_AHEAD, '\0'}; + struct user_record *user; struct tm thetime; struct tm oldtime; @@ -725,10 +772,6 @@ void runbbs_real(int socket, char *ip, int ssh) { dolog("Failed to send iac_sga"); exit(0); } - if (write(socket, iac_binary, 3) != 3) { - dolog("Failed to send iac_binary"); - exit(0); - } } else { sshBBS = 1; } diff --git a/src/bbs.h b/src/bbs.h index 615716a..5207758 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -23,6 +23,15 @@ #define TYPE_ECHOMAIL_AREA 2 #define TYPE_NEWSGROUP_AREA 3 +#define IAC 255 +#define IAC_WILL 251 +#define IAC_WONT 252 +#define IAC_DO 253 +#define IAC_DONT 254 +#define IAC_TRANSMIT_BINARY 0 +#define IAC_SUPPRESS_GO_AHEAD 3 +#define IAC_ECHO 1 + struct fido_addr { unsigned short zone; unsigned short net; diff --git a/src/doors.c b/src/doors.c index cb45a3e..562eaf7 100644 --- a/src/doors.c +++ b/src/doors.c @@ -31,6 +31,7 @@ extern int sshBBS; extern int bbs_stderr; int running_door_pid = 0; int running_door = 0; +extern int telnet_bin_mode; extern int timeoutpaused; @@ -251,6 +252,11 @@ void runexternal(struct user_record *user, char *cmd, int stdio, char *argv[], c size_t ouc; size_t inc; size_t sz; + int iac; + char iac_binary_will[] = {IAC, IAC_WILL, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_do[] = {IAC, IAC_DO, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_wont[] = {IAC, IAC_WONT, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_dont[] = {IAC, IAC_DONT, IAC_TRANSMIT_BINARY, '\0'}; timeoutpaused = 1; @@ -356,12 +362,51 @@ void runexternal(struct user_record *user, char *cmd, int stdio, char *argv[], c if (gotiac == 1) { if (c == 254 || c == 253 || c == 252 || c == 251) { gotiac = 2; + iac = c; } else if (c == 250) { gotiac = 3; } else { gotiac = 0; } } else if (gotiac == 2) { + switch (iac) { + case IAC_WILL: + fprintf(stderr, "IAC WILL %d\n", c); + if (c == 0) { + if (telnet_bin_mode != 1) { + telnet_bin_mode = 1; + write(master, iac_binary_do, 3); + } + } + break; + case IAC_WONT: + fprintf(stderr, "IAC WONT %d\n", c); + if (c == 0) { + if (telnet_bin_mode != 0) { + telnet_bin_mode = 0; + write(master, iac_binary_dont, 3); + } + } + break; + case IAC_DO: + fprintf(stderr, "IAC DO %d\n", c); + if (c == 0) { + if (telnet_bin_mode != 1) { + telnet_bin_mode = 1; + write(master, iac_binary_will, 3); + } + } + break; + case IAC_DONT: + fprintf(stderr, "IAC DONT %d\n", c); + if (c == 0) { + if (telnet_bin_mode != 0) { + telnet_bin_mode = 0; + write(master, iac_binary_wont, 3); + } + } + break; + } gotiac = 0; } else if (gotiac == 3) { if (c == 240) { diff --git a/src/files.c b/src/files.c index d62b7fb..70ee1ef 100644 --- a/src/files.c +++ b/src/files.c @@ -25,6 +25,8 @@ extern int bbs_stdout; extern int bbs_stderr; extern time_t userlaston; extern struct user_record *gUser; +extern int telnet_bin_mode; +extern int timeoutpaused; struct file_entry { int fid; @@ -156,6 +158,10 @@ int doIO(ZModem *zm) { int done = 0; int i; int j; + char iac_binary_will[] = {IAC, IAC_WILL, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_do[] = {IAC, IAC_DO, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_wont[] = {IAC, IAC_WONT, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_dont[] = {IAC, IAC_DONT, IAC_TRANSMIT_BINARY, '\0'}; while(!done) { FD_ZERO(&readfds); @@ -180,8 +186,53 @@ int doIO(ZModem *zm) { pos++; j++; } else { - j++; - j++; + // IAC command + if (buffer[j+1] == IAC_WILL || buffer[j+1] == IAC_WONT || buffer[j+1] == IAC_DO || buffer[j+1] == IAC_DONT) { + switch (buffer[j+1]) { + case IAC_WILL: + fprintf(stderr, "IAC WILL %d\n", buffer[j+2]); + if (buffer[j+2] == 0) { + if (telnet_bin_mode != 1) { + telnet_bin_mode = 1; + write(gSocket, iac_binary_do, 3); + } + } + break; + case IAC_WONT: + fprintf(stderr, "IAC WONT %d\n", buffer[j+2]); + if (buffer[j+2] == 0) { + if (telnet_bin_mode != 0) { + telnet_bin_mode = 0; + write(gSocket, iac_binary_dont, 3); + } + } + break; + case IAC_DO: + fprintf(stderr, "IAC DO %d\n", buffer[j+2]); + if (buffer[j+2] == 0) { + if (telnet_bin_mode != 1) { + telnet_bin_mode = 1; + write(gSocket, iac_binary_will, 3); + } + } + break; + case IAC_DONT: + fprintf(stderr, "IAC DONT %d\n", buffer[j+2]); + if (buffer[j+2] == 0) { + if (telnet_bin_mode != 0) { + telnet_bin_mode = 0; + write(gSocket, iac_binary_wont, 3); + } + } + break; + } + j+= 2; + } else if (buffer[j+1] == 250) { + j++; + do { + j++; + } while(buffer[j] != 240); + } } } else { buffer2[pos] = buffer[j]; @@ -379,13 +430,22 @@ int do_download(struct user_record *user, char *file) { char **arguments; int bpos; int len; - + char iac_binary_will[] = {IAC, IAC_WILL, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_do[] = {IAC, IAC_DO, IAC_TRANSMIT_BINARY, '\0'}; + if (conf.protocols[user->defprotocol - 1]->internal_zmodem) { if (sshBBS) { ttySetRaw(STDIN_FILENO, &oldit); ttySetRaw(STDOUT_FILENO, &oldot); - } + } else { + if (telnet_bin_mode == 0) { + write(gSocket, iac_binary_will, 3); + write(gSocket, iac_binary_do, 3); + } + } + timeoutpaused = 1; download_zmodem(user, file); + timeoutpaused = 0; if (sshBBS) { tcsetattr(STDIN_FILENO, TCSANOW, &oldit); tcsetattr(STDOUT_FILENO, TCSANOW, &oldot); @@ -452,7 +512,12 @@ int do_download(struct user_record *user, char *file) { arguments[bpos] = NULL; arguments[0] = download_command; - + if (!sshBBS) { + if (telnet_bin_mode == 0) { + write(gSocket, iac_binary_will, 3); + write(gSocket, iac_binary_do, 3); + } + } runexternal(user, download_command, conf.protocols[user->defprotocol - 1]->stdio, arguments, conf.bbs_path, 1, NULL); free(arguments); @@ -473,9 +538,19 @@ int do_upload(struct user_record *user, char *final_path) { struct dirent *dent; struct stat s; int len; - + char iac_binary_will[] = {IAC, IAC_WILL, IAC_TRANSMIT_BINARY, '\0'}; + char iac_binary_do[] = {IAC, IAC_DO, IAC_TRANSMIT_BINARY, '\0'}; + if (conf.protocols[user->defprotocol - 1]->internal_zmodem) { + if (!sshBBS) { + if (telnet_bin_mode == 0) { + write(gSocket, iac_binary_will, 3); + write(gSocket, iac_binary_do, 3); + } + } + timeoutpaused = 1; upload_zmodem(user, final_path); + timeoutpaused = 0; return 1; } else { @@ -554,6 +629,12 @@ int do_upload(struct user_record *user, char *final_path) { mkdir(upload_path, 0755); + if (!sshBBS) { + if (telnet_bin_mode == 0) { + write(gSocket, iac_binary_will, 3); + write(gSocket, iac_binary_do, 3); + } + } runexternal(user, upload_command, conf.protocols[user->defprotocol - 1]->stdio, arguments, upload_path, 1, NULL); free(arguments);