diff --git a/AUTHORS b/AUTHORS index 01fbc534..fd7be13c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -43,4 +43,7 @@ Vince Coen 2:257/609@fidonet Joachim Kuwan 2:249/591@fidonet Greek greek@voyager.nnov.ru Sergey Nechaev 2:5015/53@fidonet +Serge Terekhov 2:5000/13@fidonet +Vadim Kurland vadim@gu.kiev.ua +Vadim Zaliva lord@crocodile.kiev.ua diff --git a/ChangeLog b/ChangeLog index 873dc943..11c9e854 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,30 @@ $Id$ v0.39.2 21-Nov-2003 + general: + With the use of a proxy based on the iftelnetd from the ifmail + package incoming telnet sessions are now supported. Outgoing + telnet still doesn't work. + + upgrade: + See mbtelnetd.html how to install mbtelnetd. + + mbcico: + If called by inetd with the -t itn parameters, mbcico aborts + and writes a short instruction in the log to install mbtelnetd. + + mbtelnetd: + New program, a proxy to handle incoming telnet/vmodem sessions. + Based on the work of Serge Terekhov, 2:5000/13@fidonet and + Vadim Kurland, vadim@gu.kiev.ua and Vadim Zaliva, + lord@crocodile.kiev.ua. + + SETUP.sh: + Added installation of mbtelnetd for new systems. + + html: + Added mbtelnetd page. + v0.39.1 22-Oct-2003 - 21-Nov-2003 diff --git a/SETUP.sh b/SETUP.sh index 87b6a0fa..69d5e5db 100644 --- a/SETUP.sh +++ b/SETUP.sh @@ -414,7 +414,8 @@ if [ "$FIDO" = "TRUE" ] || [ "$BINKD" = "TRUE" ]; then echo "binkp 24554/tcp # mbcico IBN mode">>/etc/services fi if [ "$FIDO" = "TRUE" ]; then - echo -n ", fido at port 60179" + echo -n ", fido at ports 60177, 60179" + echo "tfido 60177/tcp # mbtelnetd ITN proxy">>/etc/services echo "fido 60179/tcp # mbcico IFC mode">>/etc/services fi chmod 644 /etc/services @@ -434,6 +435,7 @@ cat << EOF >>/etc/inetd.conf #:MBSE-BBS: bbs service binkp stream tcp nowait mbse $MHOME/bin/mbcico mbcico -t ibn fido stream tcp nowait mbse $MHOME/bin/mbcico mbcico -t ifc +tfido stream tcp nowait mbse $MHOME/bin/mbtelnetd mbtelnetd EOF chmod 644 /etc/inetd.conf @@ -460,7 +462,7 @@ if [ -f /etc/xinetd.conf ]; then cat << EOF >> $XINET #:MBSE BBS services are defined here. # -# Author: Michiel Broek , 20-Jan-2002 +# Author: Michiel Broek , 22-Nov-2003 service binkp { @@ -483,6 +485,16 @@ service fido server = $MHOME/bin/mbcico server_args = -t ifc } + +service tfido +{ + socket_type = stream + protocol = tcp + wait = no + user = mbse + instances = 10 + server = $MHOME/bin/mbtelnetd +} EOF fi diff --git a/config.h.in b/config.h.in index 50bc2286..852067ae 100644 --- a/config.h.in +++ b/config.h.in @@ -8,6 +8,9 @@ #undef VERSION_REVISION #undef VERSION +/* Compile experimental telnet code */ +#undef USE_TELNET + /* Define if you have the snprintf function. */ #undef HAVE_SNPRINTF diff --git a/configure b/configure index 239e9a09..5c55a6eb 100755 --- a/configure +++ b/configure @@ -837,6 +837,11 @@ if test -n "$ac_init_help"; then cat <<\_ACEOF +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-telnet Compile experimental telnet code + Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) @@ -1777,6 +1782,21 @@ fi CFLAGS="$CFLAGS -Wall -Wshadow -Wwrite-strings -Wstrict-prototypes" +# Check whether --enable-telnet or --disable-telnet was given. +if test "${enable_telnet+set}" = set; then + enableval="$enable_telnet" + telnet=$enableval +else + telnet=no +fi; + +if test "$telnet" = "yes"; then + cat >>confdefs.h <<\_ACEOF +#define USE_TELNET 1 +_ACEOF + +fi + cat >>confdefs.h <<_ACEOF #define RESTAMP_OLD_POSTINGS 21 _ACEOF diff --git a/configure.in b/configure.in index 3862b41a..87b7363a 100644 --- a/configure.in +++ b/configure.in @@ -53,6 +53,13 @@ AC_CHECK_PROG(ZIP, zip, zip) AC_PATH_PROG(CHOWN, chown, chown, /bin:/sbin:/usr/bin:/usr/sbin:) CFLAGS="$CFLAGS -Wall -Wshadow -Wwrite-strings -Wstrict-prototypes" +dnl Additional commandline switches +AC_ARG_ENABLE(telnet, [ --enable-telnet Compile experimental telnet code], [ telnet=$enableval ], [ telnet=no ]) + +if test "$telnet" = "yes"; then + AC_DEFINE(USE_TELNET) +fi + dnl Defines for MBSE BBS (must use tests or --enable-stuff later) AC_DEFINE_UNQUOTED(RESTAMP_OLD_POSTINGS, 21) AC_DEFINE(RESTAMP_FUTURE_POSTINGS) diff --git a/html/Makefile b/html/Makefile index a48692c0..6cd3a9b9 100644 --- a/html/Makefile +++ b/html/Makefile @@ -65,7 +65,7 @@ H_PROGS = programs/mbfido.html programs/mbmon.html \ programs/mbaff.html programs/mbdiff.html \ programs/mbindex.html programs/mbout.html \ programs/mbsetup.html programs/mbuseradd.html \ - programs/mball.html \ + programs/mball.html programs/mbtelnetd.html \ programs/mblang.html programs/mbsebbs.html \ programs/mbstat.html programs/mbpasswd.html \ programs/mbtask.html diff --git a/html/index.htm.in b/html/index.htm.in index 65745589..0b14c3c8 100644 --- a/html/index.htm.in +++ b/html/index.htm.in @@ -16,7 +16,7 @@
MBSE

MBSE BBS System Guide @VERSION@

-
Last update 11-Oct-2003
+
Last update 22-Nov-2003

Introduction

@@ -107,6 +107,7 @@
  • mbsetup, The setup program
  • mbstat, The bbs status change program
  • mbtask, The taskmanager for the bbs system
  • +
  • mbtelnetd, The incoming telnet proxy
  • mbtoberep, The toberep.data lister
  • mbuser, The userbase maintenance program
  • mbuseradd, The useradd wrapper
  • diff --git a/html/programs/index.htm b/html/programs/index.htm index 9044df97..f51bb156 100644 --- a/html/programs/index.htm +++ b/html/programs/index.htm @@ -14,13 +14,10 @@
    -
    Last update 23-Mar-2003
    +
    Last update 22-Nov-2003

    MBSE BBS Programs.

    - - -
    1. mbaff, Announce newfiles and filefind
    2. mball, Allfiles and newfiles list creator @@ -39,6 +36,7 @@
    3. mbseq, Sequence number creator
    4. mbsetup, The setup program
    5. mbstat, The bbs status change program +
    6. mbtelnetd, The incoming telnet proxy
    7. mbtoberep, The toberep.data lister
    8. mbuser, The userbase maintenance program
    9. mbuseradd, The adduser wrapper diff --git a/html/programs/mbtelnetd.html b/html/programs/mbtelnetd.html new file mode 100755 index 00000000..c771d77b --- /dev/null +++ b/html/programs/mbtelnetd.html @@ -0,0 +1,69 @@ + + + + + + + + + + + +MBSE BBS Programs - mbtelnetd - Incoming telnet proxy. + + + +
      +
      Last update 22-Nov-2003
      +

      mbtelnetd - Incoming telnet proxy

      + +

      Synopsis.

      +

      +mbtelnetd +

       

      + +

      Description.

      +

      +mbtelnetd is a small proxy that handles incoming telnet/vmodem +sessions and calls mbcico via the network on the standard fido port (60179). +This small proxy was original written by Vadim Zaliva, lord@crocodile.kiev.ua, Serge +Terekhov, 2:5000/13@fidonet and Vadim Kurland, vadim@gu.kiev.ua for the ifmail +package. +

      +

       

      + +

      Installation

      +

      +To accept incoming telnet sessions to allow the ITN nodelist flag you must +install mbtelnetd in your system. You need to do this as root. The +example shown is for most GNU/Linux distributions. +Add the following line to /etc/services: +

      +tfido           60177/tcp
      +
      +Add the following line to /etc/inetd.conf: +
      +tfido   stream  tcp     nowait  mbse    /opt/mbse/bin/mbtelnetd mbtelnetd
      +
      +Or add the following lines to /etc/xinetd.d/mbsebbs if your system +uses xinetd instead of inetd: +
      +service tfido
      +{
      +	socket_type     = stream
      +	protocol        = tcp
      +	wait            = no
      +	user            = mbse
      +	instances       = 10
      +	server          = /opt/mbse/bin/mbtelnetd
      +}
      +
      +

      + + +IndexBack to index  +MainBack to Main index +

      + + + diff --git a/lib/nodelist.conf b/lib/nodelist.conf index 71f25889..36ad867b 100644 --- a/lib/nodelist.conf +++ b/lib/nodelist.conf @@ -80,6 +80,7 @@ reqbits RQ_WU 0x00000008 # Wazoo update # service IBN binkp 24554 service IFC fido 60179 +service ITN telnet 23 # Switched network service names, they are used to build the @@ -132,8 +133,9 @@ isdn X75 0x00000010 0x00000010 # Supported IP protocols by the mailer in order of preference. # The names must match the service names. # -tcpip IFC 0x00000001 0x00000001 -tcpip IBN 0x00000002 0x00000002 +tcpip ITN 0x00000001 0x00000001 +tcpip IFC 0x00000002 0x00000002 +tcpip IBN 0x00000004 0x00000004 # The following gives the order to search for the diff --git a/mbcico/.cvsignore b/mbcico/.cvsignore index 7d604d12..775b0604 100644 --- a/mbcico/.cvsignore +++ b/mbcico/.cvsignore @@ -1 +1 @@ -filelist mbcico mbout +filelist mbcico mbout mbtelnetd diff --git a/mbcico/Makefile b/mbcico/Makefile index aee97936..2db9b3ac 100644 --- a/mbcico/Makefile +++ b/mbcico/Makefile @@ -12,7 +12,7 @@ SRCS = zmmisc.c zmrle.c zmrecv.c zmsend.c binkp.c md5b.c \ filetime.c ftsc.c atoul.c portsel.c \ ttyio.c lutil.c scanout.c emsi.c ulock.c \ callstat.c session.c call.c mbcico.c \ - outstat.c nlinfo.c mbout.c + outstat.c nlinfo.c mbout.c mbtelnetd.c HDRS = zmodem.h binkp.h config.h statetbl.h md5b.h \ xmsend.h xmrecv.h m7recv.h m7send.h hydra.h inbound.h \ answer.h chat.h dial.h dietifna.h emsidat.h filelist.h \ @@ -21,7 +21,7 @@ HDRS = zmodem.h binkp.h config.h statetbl.h md5b.h \ filetime.h ftsc.h atoul.h portsel.h \ ttyio.h lutil.h scanout.h emsi.h ulock.h \ callstat.h session.h call.h mbcico.h \ - outstat.h nlinfo.h + outstat.h nlinfo.h mbtelnetd.h MBCICO_OBJS = zmmisc.o zmrle.o zmrecv.o zmsend.o binkp.o md5b.o \ xmsend.o xmrecv.o m7recv.o m7send.o hydra.o inbound.o \ answer.o chat.o dial.o dietifna.o emsidat.o filelist.o \ @@ -31,10 +31,11 @@ MBCICO_OBJS = zmmisc.o zmrle.o zmrecv.o zmsend.o binkp.o md5b.o \ ttyio.o lutil.o scanout.o emsi.o ulock.o \ callstat.o session.o call.o mbcico.o MBOUT_OBJS = outstat.o nlinfo.o mbout.o scanout.o callstat.o +MBTEL_OBJS = mbtelnetd.o LIBS += ../lib/libclcomm.a ../lib/libcommon.a \ ../lib/libmsgbase.a ../lib/libdbase.a ../lib/libnodelist.a OTHER = Makefile README -TARGET = mbcico mbout +TARGET = mbcico mbout mbtelnetd ############################################################################# @@ -47,8 +48,9 @@ clean: rm -f ${TARGET} *.o *.h~ *.c~ core filelist Makefile.bak install: all - ${INSTALL} -c -s -g ${GROUP} -o ${OWNER} -m 4751 mbcico ${BINDIR} - ${INSTALL} -c -s -g ${GROUP} -o ${OWNER} -m 0755 mbout ${BINDIR} + ${INSTALL} -c -s -g ${GROUP} -o ${OWNER} -m 4751 mbcico ${BINDIR} + ${INSTALL} -c -s -g ${GROUP} -o ${OWNER} -m 0755 mbout ${BINDIR} + ${INSTALL} -c -s -g ${GROUP} -o ${OWNER} -m 0755 mbtelnetd ${BINDIR} mbcico: ${MBCICO_OBJS} ${LIBS} ${CC} -o mbcico ${MBCICO_OBJS} ${LIBS} @@ -58,6 +60,10 @@ mbout: ${MBOUT_OBJS} ${LIBS} ${CC} -o mbout ${MBOUT_OBJS} ${LIBS} strip mbout +mbtelnetd: ${MBTEL_OBJS} ${LIBS} + ${CC} -o mbtelnetd ${MBTEL_OBJS} ${LIBS} + strip mbtelnetd + filelist: Makefile BASE=`pwd`; \ BASE=`basename $${BASE}`; \ @@ -126,10 +132,11 @@ scanout.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/reco emsi.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/dbnode.h ../lib/clcomm.h ../lib/mberrors.h ttyio.h session.h statetbl.h config.h emsi.h emsidat.h hydra.h rdoptions.h tcp.h wazoo.h inbound.h ulock.o: ../config.h ../lib/libs.h ../lib/clcomm.h callstat.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/clcomm.h ../lib/common.h callstat.h -session.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/mberrors.h ttyio.h statetbl.h emsi.h ftsc.h session.h yoohoo.h mbcico.h binkp.h callstat.h inbound.h +session.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/mberrors.h ttyio.h statetbl.h emsi.h ftsc.h session.h yoohoo.h mbcico.h binkp.h callstat.h inbound.h opentcp.h call.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/dbnode.h ../lib/mberrors.h session.h callstat.h call.h config.h dial.h lutil.h portsel.h openport.h opentcp.h rdoptions.h inbound.h mbcico.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 config.h answer.h call.h lutil.h mbcico.h session.h 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 +mbtelnetd.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 mbtelnetd.h # End of generated dependencies diff --git a/mbcico/call.c b/mbcico/call.c index 8df1ff3c..0dd4db11 100644 --- a/mbcico/call.c +++ b/mbcico/call.c @@ -175,6 +175,10 @@ int call(faddr *addr) tcp_mode = TCPMODE_IBN; } else if (strcmp(protocol, "fido") == 0) { tcp_mode = TCPMODE_IFC; +#ifdef USE_TELNET + } else if (strcmp(protocol, "telnet") == 0) { + tcp_mode = TCPMODE_ITN; +#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 a66e1b23..86ca3070 100644 --- a/mbcico/mbcico.c +++ b/mbcico/mbcico.c @@ -65,6 +65,7 @@ unsigned long sentbytes = 0; unsigned long rcvdbytes = 0; int tcp_mode = TCPMODE_NONE; int Loaded = FALSE; +int telnet = FALSE; extern char *myname; @@ -85,7 +86,11 @@ void usage(void) fprintf(stderr,"-a \n"); fprintf(stderr,"-n forced phone number\n"); fprintf(stderr,"-l forced tty device\n"); +#ifdef USE_TELNET + fprintf(stderr,"-t must be one of ifc|itn|ibn, forces TCP/IP\n"); +#else fprintf(stderr,"-t must be one of ifc|ibn, forces TCP/IP\n"); +#endif fprintf(stderr,"-a supply internet hostname if not in nodelist\n"); fprintf(stderr," should be in domain form, e.g. f11.n22.z3\n"); fprintf(stderr," (this implies master mode)\n"); @@ -246,6 +251,10 @@ int main(int argc, char *argv[]) } else if (strncmp(p, "ibn", 3) == 0) { tcp_mode = TCPMODE_IBN; protocol = xstrcpy((char *)"binkp"); + } else if (strncmp(p, "itn", 3) == 0) { + tcp_mode = TCPMODE_ITN; + protocol = xstrcpy((char *)"tfido"); + telnet = TRUE; } else { usage(); die(MBERR_COMMANDLINE); @@ -355,6 +364,11 @@ int main(int argc, char *argv[]) if (rc > maxrc) maxrc=rc; } else { + if (telnet) { + WriteError("Incoming telnet call is not supported anymore"); + WriteError("Install mbtelnetd to handle telnet inbound traffic"); + die(MBERR_COMMANDLINE); + } /* slave */ if (!answermode && tcp_mode == TCPMODE_IBN) answermode = xstrcpy((char *)"ibn"); diff --git a/mbcico/mbtelnetd.c b/mbcico/mbtelnetd.c new file mode 100644 index 00000000..7f0b536f --- /dev/null +++ b/mbcico/mbtelnetd.c @@ -0,0 +1,390 @@ +/***************************************************************************** + * + * $Id$ + * Purpose ...............: Fidonet telnet proxy + * + ***************************************************************************** + * Copyright (C) 1997-2003 + * + * Michiel Broek FIDO: 2:280/2802 + * Beekmansbos 10 + * 1971 BV IJmuiden + * the Netherlands + * + * This file is part of MBSE BBS. + * + * This BBS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * MBSE BBS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MBSE BBS; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + *****************************************************************************/ + + +/* + Simple proxy daemon for ifcico to work with SIO/VMODEM. + ======================================================== + Written by: Vadim Zaliva, lord@crocodile.kiev.ua, 2:463/80 + + This software is provided ``as is'' without express or implied warranty. + Feel free to distribute it. + + Feel free to contact me with improovments request + and bug reports. + + Some parts of this code are taken from + 1. serge terekhov, 2:5000/13@fidonet path for ifmail + 2. Vadim Kurland, vadim@gu.kiev.ua transl daemon. + Thanks them. + */ + +#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/dbcfg.h" +#include "../lib/mberrors.h" +#include "mbtelnetd.h" + + +#define MBT_BUFSIZ 8192 +#define MBT_TIMEOUT 3600 + + +void die(int); +int init_telnet(void); +void answer(int, int); +int read0(char *, int); +int write1(char *, int); +void com_gw(int); + + +#define WILL 251 +#define WONT 252 +#define DO 253 +#define DONT 254 +#define IAC 255 + +#define TN_TRANSMIT_BINARY 0 +#define TN_ECHO 1 +#define TN_SUPPRESS_GA 3 + + + +static int tellen; +char *envptr = NULL; +time_t t_start, t_end; + + +void die(int onsig) +{ + signal(onsig, SIG_IGN); + + if (onsig) { + if (onsig <= NSIG) + WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]); + else + Syslog('+', "Terminated with error %d", onsig); + } + + t_end = time(NULL); + Syslog(' ', "MBTELNETD finished in %s", t_elapsed(t_start, t_end)); + if (envptr) + free(envptr); + ExitClient(onsig); +} + + + +int main(int ac, char **av) +{ + struct sockaddr_in peeraddr; + int addrlen = sizeof(struct sockaddr_in); + char *remote_name = NULL; + char *remote_port = NULL; + int s; /* socket to remote*/ + int i; + struct hostent *hp; + struct servent *sp; + struct sockaddr_in server; + char *tmp = NULL; + struct passwd *pw; + + /* + * The next trick is to supply a fake environment variable + * MBSE_ROOT in case we are started from inetd or mgetty, + * this will setup the variable so InitConfig() will work. + * The /etc/passwd must point to the correct homedirectory. + */ + pw = getpwuid(getuid()); + if (getenv("MBSE_ROOT") == NULL) { + envptr = xstrcpy((char *)"MBSE_ROOT="); + envptr = xstrcat(envptr, pw->pw_dir); + putenv(envptr); + } + + InitConfig(); + t_start = time(NULL); + + InitClient(pw->pw_name, (char *)"mbtelnetd", CFG.location, CFG.logfile, + CFG.util_loglevel, CFG.error_log, CFG.mgrlog, CFG.debuglog); + + Syslog(' ', " "); + Syslog(' ', "MBTELNETDv%s", VERSION); + + /* + * Catch all signals we can, and ignore the rest. + */ + for (i = 0; i < NSIG; i++) { + if ((i == SIGINT) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM) || (i == SIGKILL)) { + signal(i, (void (*))die); + } else { + signal(i, SIG_IGN); + } + } + + remote_name = xstrcpy((char *)"localhost"); + remote_port = xstrcpy((char *)"fido"); + + if (getpeername(0,(struct sockaddr*)&peeraddr,&addrlen) == 0) { + tmp = strdup(inet_ntoa(peeraddr.sin_addr)); + Syslog('+', "Incoming TCP connection from %s", tmp ? tmp : "Unknown"); + Syslog('+', "Rerouting to %s:%s", remote_name, remote_port); + } + + if (tmp) + free(tmp); + + if ((sp = getservbyname(remote_port, "tcp")) == NULL) { + WriteError("Can't find service: %s", remote_port); + free(remote_name); + free(remote_port); + die(MBERR_INIT_ERROR); + } + + if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) { + WriteError("Can't create Internet domain socket"); + free(remote_name); + free(remote_port); + die(MBERR_INIT_ERROR); + } + + if ((hp = gethostbyname(remote_name)) == NULL) { + WriteError("%s - Unknown host", remote_name); + free(remote_name); + free(remote_port); + die(MBERR_INIT_ERROR); + } + + memset(&server,0,sizeof(server)); + memcpy((char *)&server.sin_addr,hp->h_addr,hp->h_length); + + server.sin_family=hp->h_addrtype; + server.sin_port = sp->s_port; + + if (connect(s,(struct sockaddr *)&server,sizeof(server)) == -1) { + WriteError("Can't connect %s", remote_name); + free(remote_name); + free(remote_port); + die(MBERR_INIT_ERROR); + } + + init_telnet(); + + tmp = calloc(81, sizeof(char )); + sprintf(tmp, "mbtelnetd v%s\r\n", VERSION); + write1(tmp, strlen(tmp)); + free(tmp); + + com_gw(s); + + free(remote_name); + free(remote_port); + close(s); + die(0); + return 0; +} + + + +/* --- This is an artwork of serge terekhov, 2:5000/13@fidonet :) --- */ + +void answer (int tag, int opt) +{ + char buf[3]; + char *r = (char *)"???"; + + switch (tag) { + case WILL: + r = (char *)"WILL"; + break; + case WONT: + r = (char *)"WONT"; + break; + case DO: + r = (char *)"DO"; + break; + case DONT: + r = (char *)"DONT"; + break; + } + Syslog('s', "TELNET send %s %d", r, opt); + + buf[0] = IAC; + buf[1] = tag; + buf[2] = opt; + if (write (1, buf, 3) != 3) + WriteError("$answer cant send"); +} + + + +int init_telnet(void) +{ + tellen = 0; + answer (DO, TN_SUPPRESS_GA); + answer (WILL, TN_SUPPRESS_GA); + answer (DO, TN_TRANSMIT_BINARY); + answer (WILL, TN_TRANSMIT_BINARY); + answer (DO, TN_ECHO); + answer (WILL, TN_ECHO); + return 1; +} + + + +int read0 (char *buf, int len) +{ + int n = 0, m; + char *q, *p; + static char telbuf[4]; + + while ((n == 0) && (n = read (0, buf + tellen, MBT_BUFSIZ - tellen)) > 0) { + if (tellen) { + memcpy(buf, telbuf, tellen); + n += tellen; + tellen = 0; + } + + if (memchr (buf, IAC, n)) { + for (p = q = buf; n--; ) + if ((m = (unsigned char)*q++) != IAC) + *p++ = m; + else { + if (n < 2) { + memcpy (telbuf, q - 1, tellen = n + 1); + break; + } + --n; + switch (m = (unsigned char)*q++) { + case WILL: m = (unsigned char)*q++; --n; + Syslog('s', "TELNET: recv WILL %d", m); + if (m != TN_TRANSMIT_BINARY && m != TN_SUPPRESS_GA && m != TN_ECHO) + answer (DONT, m); + break; + case WONT: m = *q++; + --n; + Syslog('s', "TELNET: recv WONT %d", m); + break; + case DO: m = (unsigned char)*q++; + --n; + Syslog('s', "TELNET: recv DO %d", m); + if (m != TN_TRANSMIT_BINARY && m != TN_SUPPRESS_GA && m != TN_ECHO) + answer (WONT, m); + break; + case DONT: m = (unsigned char)*q++; + --n; + Syslog('s', "TELNET: recv DONT %d", m); + break; + case IAC: *p++ = IAC; + break; + default: Syslog('s', "TELNET: recv IAC %d", m); + break; + } + } + n = p - buf; + } + } + + return n; +} + + + +int write1 (char *buf, int len) +{ + char *q; + int k, l; + + l = len; + while ((len > 0) && (q = memchr(buf, IAC, len))) { + k = (q - buf) + 1; + if ((write (1, buf, k) != k) || (write (1, q, 1) != 1)) { + return -1; + } + buf += k; + len -= k; + } + + if ((len > 0) && write (1, buf, len) != len) { + return -1; + } + return l; +} + + + +void com_gw(int in) +{ + fd_set fds; + int n, fdsbits; + static struct timeval tout = { MBT_TIMEOUT, 0 }; + unsigned char buf[MBT_BUFSIZ]; + + alarm(0); + fdsbits = in + 1; + + while (TRUE) { + FD_ZERO(& fds); + FD_SET (in, &fds); + FD_SET (0 , &fds); + FD_SET (1 , &fds); + + tout.tv_sec = MBT_TIMEOUT; + tout.tv_usec = 0; + if ((n = select(fdsbits, &fds, NULL, NULL, &tout)) > 0) { + if (FD_ISSET(in, &fds)) { + if ((n = read(in, buf, sizeof buf)) > 0) { + if (write1(buf, n) < 0) { + goto bad; + } + } else { + goto bad; + } + } + if (FD_ISSET(0, &fds)) { + if ((n = read0(buf, sizeof buf)) > 0) { + if (write(in, buf, n) < 0) goto bad; + } else { + goto bad; + } + } + } else { + goto bad; + } + } +bad: ; +} + + diff --git a/mbcico/mbtelnetd.h b/mbcico/mbtelnetd.h new file mode 100644 index 00000000..dbea7ed6 --- /dev/null +++ b/mbcico/mbtelnetd.h @@ -0,0 +1,7 @@ +#ifndef _MBTELNETD_H +#define _MBTELNETD_H + +/* $Id$ */ + + +#endif diff --git a/mbcico/opentcp.c b/mbcico/opentcp.c index ee563538..9e5710d8 100644 --- a/mbcico/opentcp.c +++ b/mbcico/opentcp.c @@ -44,7 +44,7 @@ #define BINKPORT 24554 -// #define TELNPORT 23 +#define TELNPORT 23 #define FIDOPORT 60179 /* Eugene G. Crossers birthday */ @@ -103,6 +103,13 @@ int opentcp(char *name) else server.sin_port = htons(FIDOPORT); break; +#ifdef USE_TELNET + case TCPMODE_ITN: if ((se = getservbyname("tfido", "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 @@ -214,3 +221,42 @@ void closetcp(void) } +#ifdef USE_TELNET + +#define WILL 251 +#define WONT 252 +#define DO 253 +#define DONT 254 +#define IAC 255 + +#define TOPT_BIN 0 +#define TOPT_ECHO 1 +#define TOPT_SUPP 3 + + +static void telnet_answer(int tag, int opt) +{ + char buf[3]; + + Syslog('s', "telnet_answer(%d, %d)", tag, opt); + buf[0]=IAC; + buf[1]=tag; + buf[2]=opt; + tty_put(buf, 3); +} + + +void telnet_init(void) +{ + Syslog('s', "telnet_init()"); + telnet_answer(DO,TOPT_SUPP); + telnet_answer(WILL,TOPT_SUPP); + telnet_answer(DO,TOPT_BIN); + telnet_answer(WILL,TOPT_BIN); + telnet_answer(DO,TOPT_ECHO); + telnet_answer(WILL,TOPT_ECHO); +} + + +#endif + diff --git a/mbcico/opentcp.h b/mbcico/opentcp.h index 0a899fd8..ee4821c4 100644 --- a/mbcico/opentcp.h +++ b/mbcico/opentcp.h @@ -6,5 +6,8 @@ int opentcp(char *); void closetcp(void); +#ifdef USE_TELNET +void telnet_init(void); +#endif #endif diff --git a/mbcico/session.c b/mbcico/session.c index 10d21541..a43c76f4 100644 --- a/mbcico/session.c +++ b/mbcico/session.c @@ -47,9 +47,13 @@ #include "binkp.h" #include "callstat.h" #include "inbound.h" +#include "opentcp.h" extern int tcp_mode; +#ifdef USE_TELNET +extern int telnet; +#endif node *nlent; @@ -99,6 +103,11 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) } else if (tcp_mode == TCPMODE_IFC) { Syslog('+', "Incoming IFC/TCP connection from %s", inet_ntoa(peeraddr.sin_addr)); IsDoing("Incoming IFC/TCP"); +#ifdef USE_TELNET + } else if (tcp_mode == TCPMODE_ITN) { + Syslog('+', "Incoming ITN/TCP connection from %s", inet_ntoa(peeraddr.sin_addr)); + IsDoing("Incoming ITN/TCP"); +#endif } else if (tcp_mode == TCPMODE_NONE) { WriteError("Unknown TCP connection, parameter missing"); die(MBERR_COMMANDLINE); @@ -106,6 +115,10 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) } session_flags |= SESSION_TCP; } +#ifdef USE_TELNET + if (telnet && (session_flags & SESSION_TCP)) + telnet_init(); +#endif if (data) free(data); diff --git a/mbcico/session.h b/mbcico/session.h index 323a8839..44576a80 100644 --- a/mbcico/session.h +++ b/mbcico/session.h @@ -5,6 +5,9 @@ #define TCPMODE_NONE 0 #define TCPMODE_IFC 1 /* ifcico native EMSI on raw TCP */ +#ifdef USE_TELNET +#define TCPMODE_ITN 2 /* EMSI encapsulation through telnet */ +#endif #define TCPMODE_IBN 3 /* Binkp protocol */ #define SESSION_UNKNOWN 0 diff --git a/mbcico/ttyio.c b/mbcico/ttyio.c index 5d25d7b7..e31c7a57 100644 --- a/mbcico/ttyio.c +++ b/mbcico/ttyio.c @@ -178,7 +178,7 @@ static int tty_read(char *buf, int size, int tot) now = time(NULL); timeout = (time_t)300; /* maximum of 5 minutes */ - for (i = 0; i < 2; i++) { + for (i = 0; i < NUMTIMERS; i++) { if (timer[i]) { if (now >= timer[i]) { tty_status=STAT_TIMEOUT; diff --git a/mbtask/outstat.c b/mbtask/outstat.c index b230e01a..af1ea4d7 100644 --- a/mbtask/outstat.c +++ b/mbtask/outstat.c @@ -203,7 +203,7 @@ int outstat() struct dirent *de; struct stat sb; struct passwd *pw; - unsigned long cmmask, ibnmask = 0, ifcmask = 0; + unsigned long cmmask, ibnmask = 0, ifcmask = 0, itnmask = 0; nodelist_modem **tmpm; cmmask = getCMmask(); @@ -212,6 +212,10 @@ int outstat() ibnmask = (*tmpm)->mask; if (strcmp((*tmpm)->name, "IFC") == 0) ifcmask = (*tmpm)->mask; +#ifdef USE_TELNET + if (strcmp((*tmpm)->name, "ITN") == 0) + itnmask = (*tmpm)->mask; +#endif } now = time(NULL); tm = gmtime(&now); /* UTC time */ @@ -334,7 +338,7 @@ int outstat() rc = load_node(tmp->addr); // Syslog('o', "Load node %s rc=%s, NoCall=%s, NoTCP=%s", fido2str(tmp->addr, 0x0f), rc?"true":"false", -// nodes.NoCall?"True":"False", (ibnmask + ifcmask)?"False":"True"); +// nodes.NoCall?"True":"False", (itnmask + ibnmask + ifcmask)?"False":"True"); /* * Zone Mail Hours, only use Fidonet Hours. @@ -418,7 +422,11 @@ int outstat() */ if (TCFG.max_tcp && (tmp->olflags & cmmask) && (((tmp->flavors) & F_IMM) || ((tmp->flavors) & F_CRASH) || ((tmp->flavors) & F_NORMAL)) && - ((tmp->ipflags & ibnmask) || (tmp->ipflags & ifcmask) )) { +#ifdef USE_TELNET + ((tmp->ipflags & ibnmask) || (tmp->ipflags & ifcmask) || (tmp->ipflags & itnmask))) { +#else + ((tmp->ipflags & ibnmask) || (tmp->ipflags & ifcmask))) { +#endif tmp->flavors |= F_CALL; } @@ -497,7 +505,11 @@ int outstat() if ((tmp->flavors) & F_CALL) { tmp->callmode = CM_NONE; +#ifdef USE_TELNET + if (TCFG.max_tcp && ((tmp->ipflags & ibnmask) || (tmp->ipflags & ifcmask) || (tmp->ipflags & itnmask))) { +#else if (TCFG.max_tcp && ((tmp->ipflags & ibnmask) || (tmp->ipflags & ifcmask))) { +#endif inet_calls++; tmp->callmode = CM_INET; }