From 3a2b52a6191ca8eb5f652a1cfa9bab2131b0006b Mon Sep 17 00:00:00 2001 From: Michiel Broek Date: Sun, 1 Feb 2004 21:17:40 +0000 Subject: [PATCH] Finished telnet sessions --- ChangeLog | 9 ++- mbcico/Makefile | 8 +-- mbcico/call.c | 2 - mbcico/mbcico.c | 11 ---- mbcico/openport.c | 4 +- mbcico/opentcp.c | 159 ++++++++-------------------------------------- mbcico/session.c | 40 ++++++++---- mbcico/telnet.c | 30 ++++----- mbcico/telnet.h | 5 -- 9 files changed, 77 insertions(+), 191 deletions(-) diff --git a/ChangeLog b/ChangeLog index 56df0c43..a56e69c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,11 +5,14 @@ v0.39.9 29-Jan-2004 general: Changed first time installation to install mbcico itself again to handle incoming telnet sessions at port 60177. The program - mbtelind is obsolete, this was a temporary hack. + mbtelind is obsolete, this was a temporary hack. Change your + inetd or xinetd configuration for itn (tfido) calls. + See the documentation of mbcico how to do this. mbcico: - Added experimental code for telnet outbound connections. This - code is not compiled by default so don't worry or bother. + Added telnet input and output filters so we can now call and + answer telnet (ITN) sessions. We don't need mbtelind anymore + to handle incoming calls. mbsetup: Clearing the working message is now only done by the keyboard diff --git a/mbcico/Makefile b/mbcico/Makefile index 319baaf7..15108140 100644 --- a/mbcico/Makefile +++ b/mbcico/Makefile @@ -49,6 +49,8 @@ clean: install: all ${INSTALL} -c -s -g ${GROUP} -o ${OWNER} -m 4751 mbcico ${BINDIR} ${INSTALL} -c -s -g ${GROUP} -o ${OWNER} -m 0755 mbout ${BINDIR} + @rm -f ${BINDIR}/mbtelind + @rm -f ${BINDIR}/mbtelout mbcico: ${MBCICO_OBJS} ${LIBS} ${CC} -o mbcico ${MBCICO_OBJS} ${LDFLAGS} ${LIBS} @@ -105,7 +107,7 @@ emsidat.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/reco filelist.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/clcomm.h ../lib/common.h ../lib/nodelist.h config.h session.h filelist.h openfile.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/clcomm.h ../lib/common.h ../lib/users.h ../lib/records.h config.h lutil.h openfile.h openport.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h ulock.h ttyio.h mbcico.h openport.h -opentcp.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/dbnode.h session.h ttyio.h openport.h telnet.h opentcp.h +opentcp.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/dbnode.h session.h ttyio.h openport.h opentcp.h rdoptions.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/dbnode.h session.h config.h yoohoo.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/clcomm.h ../lib/common.h ../lib/nodelist.h ../lib/dbnode.h ../lib/mberrors.h statetbl.h ttyio.h session.h config.h emsi.h hydra.h rdoptions.h wazoo.h dietifna.h yoohoo.h inbound.h recvbark.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ttyio.h session.h statetbl.h recvbark.h respfreq.h filelist.h @@ -118,7 +120,7 @@ filetime.o: ../config.h ../lib/libs.h filetime.h ftsc.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/mberrors.h session.h ttyio.h statetbl.h config.h ftsc.h rdoptions.h recvbark.h filelist.h sendbark.h respfreq.h xmrecv.h xmsend.h inbound.h atoul.o: ../config.h ../lib/libs.h atoul.h portsel.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h portsel.h -telnet.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/dbnode.h telnet.h +telnet.o: ../config.h ../lib/libs.h ../lib/clcomm.h ../lib/mberrors.h telnet.h ttyio.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ttyio.h lutil.h lutil.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h lutil.h scanout.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbftn.h config.h scanout.h lutil.h @@ -131,6 +133,4 @@ mbcico.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/recor outstat.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/dbcfg.h ../lib/dbnode.h ../lib/dbftn.h ../lib/mberrors.h scanout.h callstat.h outstat.h nlinfo.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h nlinfo.h mbout.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/dbcfg.h ../lib/dbnode.h ../lib/dbftn.h ../lib/mberrors.h outstat.h nlinfo.h -mbtelind.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbcfg.h ../lib/mberrors.h mbtelind.h -mbtelout.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbcfg.h ../lib/mberrors.h mbtelout.h # End of generated dependencies diff --git a/mbcico/call.c b/mbcico/call.c index 12111f85..53cd9fdf 100644 --- a/mbcico/call.c +++ b/mbcico/call.c @@ -181,11 +181,9 @@ int call(faddr *addr) tcp_mode = TCPMODE_IBN; } else if (strcmp(protocol, "fido") == 0) { tcp_mode = TCPMODE_IFC; -#ifdef USE_EXPERIMENT } else if (strcmp(protocol, "telnet") == 0) { tcp_mode = TCPMODE_ITN; telnet = TRUE; -#endif } else { Syslog('+', "No common TCP/IP protocols for node %s", nlent->name); free(inetaddr); diff --git a/mbcico/mbcico.c b/mbcico/mbcico.c index ca364a20..80725487 100644 --- a/mbcico/mbcico.c +++ b/mbcico/mbcico.c @@ -369,17 +369,6 @@ int main(int argc, char *argv[]) /* * Slave (answer) mode */ -#ifdef USE_EXPERIMENT - if (telnet) { - Syslog('-', "Will use experimental telnet code"); - } -#else - if (telnet) { - WriteError("Answering calls with the \"-t itn\" option no longer supported"); - WriteError("Install mbtelind to answer incoming telnet calls"); - die(MBERR_COMMANDLINE); - } -#endif if (!answermode && tcp_mode == TCPMODE_IBN) answermode = xstrcpy((char *)"ibn"); rc = maxrc = answer(answermode); diff --git a/mbcico/openport.c b/mbcico/openport.c index e92a1342..118a0e81 100644 --- a/mbcico/openport.c +++ b/mbcico/openport.c @@ -5,7 +5,7 @@ * Purpose ...............: Fidonet mailer * ***************************************************************************** - * Copyright (C) 1997-2003 + * Copyright (C) 1997-2004 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -238,7 +238,7 @@ int cookedport(void) { Syslog('t', "SIGHUP => SIG_IGN"); signal(SIGHUP, SIG_IGN); - Syslog('t', "SIGHUP => SIG_IGN"); + Syslog('t', "SIGPIPE => SIG_IGN"); signal(SIGPIPE, SIG_IGN); if (isatty(0)) return tty_cooked(); diff --git a/mbcico/opentcp.c b/mbcico/opentcp.c index 59da95f5..caf093d4 100644 --- a/mbcico/opentcp.c +++ b/mbcico/opentcp.c @@ -40,7 +40,6 @@ #include "session.h" #include "ttyio.h" #include "openport.h" -#include "telnet.h" #include "opentcp.h" @@ -71,11 +70,9 @@ int opentcp(char *name) struct servent *se; struct hostent *he; struct sockaddr_in server; - int a1, a2, a3, a4, rc, Fd, Fdo, GotPort = FALSE; + int a1, a2, a3, a4, GotPort = FALSE; char *errmsg, *portname; short portnum; - int input_pipe[2], output_pipe[2]; - pid_t fpid; Syslog('+', "Open TCP connection to \"%s\"", MBSE_SS(name)); @@ -106,13 +103,11 @@ int opentcp(char *name) else server.sin_port = htons(FIDOPORT); break; -#ifdef USE_EXPERIMENT case TCPMODE_ITN: if ((se = getservbyname("telnet", "tcp"))) server.sin_port = se->s_port; else server.sin_port = htons(TELNPORT); break; -#endif case TCPMODE_IBN: if ((se = getservbyname("binkd", "tcp"))) server.sin_port = se->s_port; else @@ -145,128 +140,32 @@ int opentcp(char *name) Syslog('d', "SIGHUP => linedrop()"); signal(SIGHUP, linedrop); -#ifdef USE_EXPERIMENT - if (tcp_mode == TCPMODE_ITN) { - Syslog('s', "Installing telnet filter..."); + fflush(stdin); + fflush(stdout); + setbuf(stdin,NULL); + setbuf(stdout,NULL); + close(0); + close(1); - /* - * Create TCP socket and open - */ - if ((Fdo = socket(AF_INET,SOCK_STREAM,0)) == -1) { - WriteError("$Cannot create socket"); - return -1; - } - if (connect(Fdo,(struct sockaddr *)&server,sizeof(server)) == -1) { - Syslog('+', "Cannot connect %s",inet_ntoa(server.sin_addr)); - return -1; - } - Syslog('s', "socket %d", Fdo); - - /* - * Close stdin and stdout so that when we create the pipes to - * the telnet filter they get stdin and stdout as file descriptors. - */ - fflush(stdin); - fflush(stdout); - setbuf(stdin,NULL); - setbuf(stdout, NULL); - close(0); - close(1); - - /* - * Create output pipe and start output filter. - */ - if ((rc = pipe(output_pipe)) == -1) { - WriteError("$could not create output_pipe"); - return -1; - } - fpid = fork(); - switch (fpid) { - case -1: WriteError("fork for telout_filter failed"); - return -1; - case 0: if (close(output_pipe[1]) == -1) { - WriteError("$error close output_pipe[1]"); - return -1; - } - telout_filter(output_pipe[0], Fdo); - /* NOT REACHED */ - } - if (close(output_pipe[0] == -1)) { - WriteError("$error close output_pipe[0]"); - return -1; - } - Syslog('s', "telout_filter forked with pid %d", fpid); - - /* - * Create input pipe and start input filter - */ - if ((rc = pipe(input_pipe)) == -1) { - WriteError("$could not create input_pipe"); - return -1; - } - fpid = fork(); - switch (fpid) { - case -1: WriteError("fork for telin_filter failed"); - return -1; - case 0: if (close(input_pipe[0]) == -1) { - WriteError("$error close input_pipe[0]"); - return -1; - } - telin_filter(input_pipe[1], Fdo); - /* NOT REACHED */ - } - if (close(input_pipe[1]) == -1) { - WriteError("$error close input_pipe[1]"); - return -1; - } - Syslog('s', "telin_filter forked with pid %d", fpid); - - Syslog('s', "stdout = %d", output_pipe[1]); - Syslog('s', "stdin = %d", input_pipe[0]); - - if ((input_pipe[0] != 0) || (output_pipe[1] != 1)) { - WriteError("Failed to create pipes on stdin and stdout"); - return -1; - } - - Syslog('+', "Telnet I/O filters installed"); - telnet_init(Fdo); /* Do we need that as originating system? */ - f_flags=0; - - } else { -#endif - /* - * Transparant 8 bits connection - */ - fflush(stdin); - fflush(stdout); - setbuf(stdin,NULL); - setbuf(stdout,NULL); - close(0); - close(1); - - if ((Fd = socket(AF_INET,SOCK_STREAM,0)) != 0) { - WriteError("$Cannot create socket (got %d, expected 0)", Fd); - open("/dev/null",O_RDONLY); - open("/dev/null",O_WRONLY); - return -1; - } - if (dup(Fd) != 1) { - WriteError("$Cannot dup socket"); - open("/dev/null",O_WRONLY); - return -1; - } - clearerr(stdin); - clearerr(stdout); - if (connect(Fd,(struct sockaddr *)&server,sizeof(server)) == -1) { - Syslog('+', "Cannot connect %s",inet_ntoa(server.sin_addr)); - return -1; - } - - f_flags=0; -#ifdef USE_EXPERIMENT + if ((fd = socket(AF_INET,SOCK_STREAM,0)) != 0) { + WriteError("$Cannot create socket (got %d, expected 0)", fd); + open("/dev/null",O_RDONLY); + open("/dev/null",O_WRONLY); + return -1; } -#endif + if (dup(fd) != 1) { + WriteError("$Cannot dup socket"); + open("/dev/null",O_WRONLY); + return -1; + } + clearerr(stdin); + clearerr(stdout); + if (connect(fd,(struct sockaddr *)&server,sizeof(server)) == -1) { + Syslog('+', "Cannot connect %s",inet_ntoa(server.sin_addr)); + return -1; + } + + f_flags=0; Syslog('+', "Established %s/TCP connection with %s, port %d", (tcp_mode == TCPMODE_IFC) ? "IFC":(tcp_mode == TCPMODE_ITN) ?"ITN":(tcp_mode == TCPMODE_IBN) ? "IBN":"Unknown", @@ -287,14 +186,6 @@ void closetcp(void) if (!tcp_is_open) return; -#ifdef USE_EXPERIMENT - if (tcp_mode == TCPMODE_ITN) { - /* - * Check if telout thread is running - */ - } -#endif - shutdown(fd, 2); Syslog('d', "SIGHUP => SIG_IGN"); signal(SIGHUP, SIG_IGN); diff --git a/mbcico/session.c b/mbcico/session.c index 33e3588f..5519db3c 100644 --- a/mbcico/session.c +++ b/mbcico/session.c @@ -87,10 +87,8 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) { int rc = MBERR_OK, addrlen = sizeof(struct sockaddr_in); fa_list *tmpl; -#ifdef USE_EXPERIMENT - int Fdo, input_pipe[2], output_pipe[2]; - pid_t fpid; -#endif + int Fdo = -1, input_pipe[2], output_pipe[2]; + pid_t ipid, opid; session_flags = 0; type = tp; @@ -115,9 +113,9 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) } } session_flags |= SESSION_TCP; -#ifdef USE_EXPERIMENT - if ((tcp_mode == TCPMODE_ITN) && (role == 0)) { - Syslog('-', "Will need to install telnet receiver thread"); + + if (tcp_mode == TCPMODE_ITN) { + Syslog('s', "Installing telnet filter..."); /* * First make sure the current input socket gets a new file descriptor @@ -144,8 +142,8 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) WriteError("$could not create output_pipe"); die(MBERR_TTYIO_ERROR); } - fpid = fork(); - switch (fpid) { + opid = fork(); + switch (opid) { case -1: WriteError("fork for telout_filter failed"); die(MBERR_TTYIO_ERROR); case 0: if (close(output_pipe[1]) == -1) { @@ -159,7 +157,7 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) WriteError("$error close output_pipe[0]"); die(MBERR_TTYIO_ERROR); } - Syslog('s', "telout_filter forked with pid %d", fpid); + Syslog('s', "telout_filter forked with pid %d", opid); /* * Create input pipe and start input filter @@ -168,8 +166,8 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) WriteError("$could not create input_pipe"); die(MBERR_TTYIO_ERROR); } - fpid = fork(); - switch (fpid) { + ipid = fork(); + switch (ipid) { case -1: WriteError("fork for telin_filter failed"); die(MBERR_TTYIO_ERROR); case 0: if (close(input_pipe[0]) == -1) { @@ -183,7 +181,7 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) WriteError("$error close input_pipe[1]"); die(MBERR_TTYIO_ERROR); } - Syslog('s', "telin_filter forked with pid %d", fpid); + Syslog('s', "telin_filter forked with pid %d", ipid); Syslog('s', "stdout = %d", output_pipe[1]); Syslog('s', "stdin = %d", input_pipe[0]); @@ -195,7 +193,6 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) Syslog('+', "Telnet I/O filters installed"); telnet_init(Fdo); } -#endif } if (data) @@ -265,6 +262,21 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) putstatus(tmpl->addr, 0, 0); } + /* + * If the socket for the telnet filter is open, close it so that the telnet filters exit. + * After that wait a little while to let the filter childs die before the main program + * does, else we get zombies. + */ + if (Fdo != -1) { + Syslog('s', "shutdown filter sockets and stdio"); + shutdown(Fdo, 2); + close(0); + close(1); + close(output_pipe[1]); + close(input_pipe[0]); + msleep(100); + } + tidy_falist(&remote); if (data) free(data); diff --git a/mbcico/telnet.c b/mbcico/telnet.c index 9b0914aa..bb63771c 100644 --- a/mbcico/telnet.c +++ b/mbcico/telnet.c @@ -30,13 +30,8 @@ #include "../config.h" #include "../lib/libs.h" -#include "../lib/structs.h" -#include "../lib/users.h" -#include "../lib/records.h" -#include "../lib/common.h" #include "../lib/clcomm.h" -#include "../lib/nodelist.h" -#include "../lib/dbnode.h" +#include "../lib/mberrors.h" #include "telnet.h" @@ -45,8 +40,6 @@ */ -#ifdef USE_EXPERIMENT - /* * Send options to the remote. @@ -106,7 +99,6 @@ void telout_filter(int fdi, int fdo) while ((rc = read(fdi, &ch, 1)) > 0) { c = (int)ch & 0xff; if (c == IAC) { - Syslog('s', "telout_filter: got IAC sending twice"); /* * Escape IAC characters by sending it twice. */ @@ -114,11 +106,14 @@ void telout_filter(int fdi, int fdo) } if ((rc = write(fdo, &ch, 1)) == -1) { Syslog('s', "$telout_filter: write failed"); - exit(1); + exit(MBERR_TTYIO_ERROR); } + tcflush(fdo, TCOFLUSH); } - Syslog('s', "$telout_filter: finished rc=%d", rc); + tcflush(fdi, TCIFLUSH); + tcflush(fdo, TCOFLUSH); + Syslog('s', "telout_filter: finished rc=%d", rc); exit(0); } @@ -136,12 +131,12 @@ void telin_filter(int fdo, int fdi) while ((rc = read(fdi, &ch, 1)) > 0) { c = (int)ch & 0xff; -// Syslog('s', "telin_filter: ch=%s", printablec(c)); if (c == IAC) { - Syslog('s', "got IAC"); + if ((read(fdi, &ch, 1) < 0)) break; m = (int)ch & 0xff; + switch (m) { case WILL: read(fdi, &ch, 1); m = (int)ch & 0xff; @@ -165,22 +160,25 @@ void telin_filter(int fdo, int fdi) break; case IAC: ch = (char)m; rc = write(fdo, &ch, 1); - Syslog('s', "Telnet: got escaped IAC"); break; default: Syslog('s', "Telnet: recv IAC %d, not good", m); break; } + } else { ch = (char)c; if ((rc = write(fdo, &ch, 1)) == -1) { Syslog('s', "$telin_filter: write failed"); - exit(1); + exit(MBERR_TTYIO_ERROR); } } + tcflush(fdo, TCOFLUSH); } + tcflush(fdi, TCIFLUSH); + tcflush(fdo, TCOFLUSH); + Syslog('s', "telin_filter: finished rc=%d", rc); exit(0); } -#endif diff --git a/mbcico/telnet.h b/mbcico/telnet.h index 2a180417..b3571ea3 100644 --- a/mbcico/telnet.h +++ b/mbcico/telnet.h @@ -3,10 +3,6 @@ /* $Id$ */ -#ifdef USE_EXPERIMENT - -// #define MBT_TIMEOUT 500 -// #define MBT_BUFLEN 8192 #define TOPT_BIN 0 #define TOPT_ECHO 1 @@ -17,6 +13,5 @@ void telnet_answer(int, int, int); void telout_filter(int, int); void telin_filter(int, int); -#endif #endif