From 3c51f002ab43eb6f6ebc6b34d9de857f5f341ddb Mon Sep 17 00:00:00 2001 From: Michiel Broek Date: Wed, 26 Nov 2003 21:24:15 +0000 Subject: [PATCH] Added mbtelind program --- ChangeLog | 23 +-- SETUP.sh | 7 +- html/Makefile | 2 +- html/index.htm.in | 3 +- html/programs/index.htm | 3 +- html/programs/mbtelind.html | 69 +++++++ mbcico/.cvsignore | 2 +- mbcico/Makefile | 13 +- mbcico/mbtelind.c | 393 ++++++++++++++++++++++++++++++++++++ mbcico/mbtelind.h | 25 +++ 10 files changed, 517 insertions(+), 23 deletions(-) create mode 100644 html/programs/mbtelind.html create mode 100644 mbcico/mbtelind.c create mode 100644 mbcico/mbtelind.h diff --git a/ChangeLog b/ChangeLog index 4a7adcf0..443c6718 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,16 +7,9 @@ v0.39.2 21-Nov-2003 Well, almost certain that it will be removed. This version is in cvs because I need to test it on several machines at once. - TESTS: - Originating calls: send and receive with Radius Ok. - Answering call: send and receive with Radius Ok. - Originating calls: send to MBSE/mbtelnetd Ok. - receive from MBSE/mbtelnetd Error. - Problem is in TCP protocol in telnet mode. Hydra is OK. - Cause: wrong blocklength with transmitter? - general: - Outgoing telnet finally works. + Incoming telnet mailer connections are handled using a telnet + proxy daemon: mbtelind. common.a: A small fix in printable log function. @@ -26,14 +19,20 @@ v0.39.2 21-Nov-2003 mbcico: All internal references to tfido port changed to telnet port because we now default to telnet port 23 for ITN calls. - Made outgoing telnet calls working with the help of sources - from other open source projects. + Incoming calls using the -t itn commandline parameters are not + supported anymore, they need to go via mbtelind. + + mbtelind: + New program, a incoming telnet proxy daemon to accept incoming + calls and transfer these via port 60179 to mbcico that will + handle the call in raw ifcico mode. mbtask: Restored ITN protocol. SETUP.sh: - Added installation of mailer telnet answer back for port 60177. + Changed installation for incoming mailer telnet connections to + install mbtelind. examples: Updated file menus, added View File command. diff --git a/SETUP.sh b/SETUP.sh index 547c971b..37c6b76f 100644 --- a/SETUP.sh +++ b/SETUP.sh @@ -435,7 +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/mbcico mbcico -t itn +tfido stream tcp nowait mbse $MHOME/bin/mbtelind mbtelind EOF chmod 644 /etc/inetd.conf @@ -462,7 +462,7 @@ if [ -f /etc/xinetd.conf ]; then cat << EOF >> $XINET #:MBSE BBS services are defined here. # -# Author: Michiel Broek , 22-Nov-2003 +# Author: Michiel Broek , 26-Nov-2003 service binkp { @@ -493,8 +493,7 @@ service tfido wait = no user = mbse instances = 10 - server = $MHOME/bin/mbcico - server_args = -t itn + server = $MHOME/bin/mbtelind } EOF diff --git a/html/Makefile b/html/Makefile index 7c11551f..60c18005 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/mbtelind.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 0b14c3c8..1fb84dff 100644 --- a/html/index.htm.in +++ b/html/index.htm.in @@ -16,7 +16,7 @@
MBSE

MBSE BBS System Guide @VERSION@

-
Last update 22-Nov-2003
+
Last update 26-Nov-2003

Introduction

@@ -108,6 +108,7 @@
  • mbstat, The bbs status change program
  • mbtask, The taskmanager for the bbs system
  • mbtelnetd, The incoming telnet proxy
  • +
  • mbtelind, The telnet input proxy daemon
  • 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 721aa3f6..2354840f 100644 --- a/html/programs/index.htm +++ b/html/programs/index.htm @@ -14,7 +14,7 @@
    -
    Last update 25-Nov-2003
    +
    Last update 26-Nov-2003

    MBSE BBS Programs.

    @@ -36,6 +36,7 @@
  • mbseq, Sequence number creator
  • mbsetup, The setup program
  • mbstat, The bbs status change program +
  • mbtelind, The telnet input proxy daemon
  • mbtoberep, The toberep.data lister
  • mbuser, The userbase maintenance program
  • mbuseradd, The adduser wrapper diff --git a/html/programs/mbtelind.html b/html/programs/mbtelind.html new file mode 100644 index 00000000..0a1d9879 --- /dev/null +++ b/html/programs/mbtelind.html @@ -0,0 +1,69 @@ + + + + + + + + + + + +MBSE BBS Programs - mbtelind - Incoming telnet proxy. + + + +
    +
    Last update 26-Nov-2003
    +

    mbtelind - Incoming telnet proxy

    + +

    Synopsis.

    +

    +mbtelind +

     

    + +

    Description.

    +

    +mbtelind is a small proxy that handles incoming telnet/sio +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 as iftelnetd. This program should be installed to listen to port 60177 +and if you do not allow telnet users login also on port 23. +

    +

     

    + +

    Installation

    +

    +To accept incoming telnet sessions to allow the ITN nodelist flag you must +install mbtelind 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/mbtelind mbtelind
    +
    +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/mbtelind
    +}
    +
    +

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

    + + diff --git a/mbcico/.cvsignore b/mbcico/.cvsignore index 7d604d12..83082ec7 100644 --- a/mbcico/.cvsignore +++ b/mbcico/.cvsignore @@ -1 +1 @@ -filelist mbcico mbout +filelist mbcico mbout mbtelind diff --git a/mbcico/Makefile b/mbcico/Makefile index b1dd98c0..d3ae29cf 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 mbtelind.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 mbtelind.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 +MBTELIND_OBJS = mbtelind.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 mbtelind ############################################################################# @@ -49,6 +50,7 @@ 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} + ${INSTALL} -c -s -g ${GROUP} -o ${OWNER} -m 0755 mbtelind ${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 +mbtelind: ${MBTELIND_OBJS} ${LIBS} + ${CC} -o mbtelind ${MBTELIND_OBJS} ${LIBS} + strip mbtelind + filelist: Makefile BASE=`pwd`; \ BASE=`basename $${BASE}`; \ @@ -132,4 +138,5 @@ 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 # End of generated dependencies diff --git a/mbcico/mbtelind.c b/mbcico/mbtelind.c new file mode 100644 index 00000000..d2d29069 --- /dev/null +++ b/mbcico/mbtelind.c @@ -0,0 +1,393 @@ +/***************************************************************************** + * + * $Id$ + * Purpose ...............: Fidonet telnet input proxy daemon + * + ***************************************************************************** + * 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 "mbtelind.h" + + +/* + * Timeout, less then 10 minutes because we need to keep the connection + * with mbtask alive. + */ +#define MBT_TIMEOUT 500 +#define MBT_BUFLEN 8192 + + +char *envptr = NULL; +time_t t_start, t_end; +static int tellen; + + + +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); + } + + telnet_init(); + + tmp = calloc(81, sizeof(char )); + sprintf(tmp, "mbtelnetd v%s\r\n", VERSION); + telnet_write(tmp, strlen(tmp)); + free(tmp); + + com_gw(s); + + free(remote_name); + free(remote_port); + close(s); + die(0); + return 0; +} + + + +void com_gw(int in) +{ + fd_set fds; + int n, fdsbits; + static struct timeval tout = { MBT_TIMEOUT, 0 }; + unsigned char buf[MBT_BUFLEN]; + + 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 (telnet_write(buf, n) < 0) { + goto bad; + } + } else { + goto bad; + } + } + if (FD_ISSET(0, &fds)) { + if ((n = telnet_read(buf, sizeof buf)) > 0) { + if (write(in, buf, n) < 0) goto bad; + } else { + goto bad; + } + } + } else { + goto bad; + } + Nopper(); + } +bad: ; +} + + + +static int tellen; +static int buflen = 0; + + +/* --- This is an artwork of serge terekhov, 2:5000/13@fidonet :) --- */ + +void telnet_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 telnet_init(void) +{ + Syslog('s', "telnet_init()"); + tellen = 0; + 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); + return 1; +} + + + +/* + * Read function for mbtelnetd + */ +int telnet_read(char *buf, int len) +{ + int n = 0, m; + char *q, *p; + static char telbuf[4]; + + while ((n == 0) && (n = read (0, buf + tellen, MBT_BUFLEN - tellen)) > 0) { + + if (n < 0) { + return n; + } + + 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 != TOPT_BIN && m != TOPT_SUPP && m != TOPT_ECHO) + telnet_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 != TOPT_BIN && m != TOPT_SUPP && m != TOPT_ECHO) + telnet_answer(WONT, m); + break; + case DONT: m = (unsigned char)*q++; + --n; + Syslog('s', "TELNET: recv DONT %d", m); + break; + case IAC: Syslog('s', "TELNET: recv 2nd IAC %d", m); + *p++ = IAC; + break; + default: Syslog('s', "TELNET: recv IAC %d", m); + break; + } + } + n = p - buf; + } + } + + return n; +} + + + +/* + * Telnet output filter, IAC characters are escaped. + */ +int telnet_write(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; +} + + diff --git a/mbcico/mbtelind.h b/mbcico/mbtelind.h new file mode 100644 index 00000000..8ec0d2c2 --- /dev/null +++ b/mbcico/mbtelind.h @@ -0,0 +1,25 @@ +#ifndef _MBTELIND_H +#define _MBTELIND_H + +/* $Id$ */ + +#define MBT_WILL 251 +#define MBT_WONT 252 +#define MBT_DO 253 +#define MBT_DONT 254 +#define MBT_IAC 255 + +#define TOPT_BIN 0 +#define TOPT_ECHO 1 +#define TOPT_SUPP 3 + + +void die(int); +void com_gw(int); +void telnet_answer(int, int); +int telnet_init(void); +int telnet_read(char *, int); +int telnet_write(char *, int); +int telnet_buffer(char *, int); + +#endif