From a248a52b01b54a2fd2986e944cbedec68816e5bb Mon Sep 17 00:00:00 2001 From: markm Date: Mon, 20 Aug 2001 12:12:27 +0000 Subject: [PATCH] Feature merging and diff reduction between this code and crypto telnet. Also remove conditional (AUTHENTICATION) code as we have never compiled it here, and it is doubtful that it even works in this scenario. --- libexec/telnetd/Makefile | 26 +-- libexec/telnetd/ext.h | 15 +- libexec/telnetd/global.c | 2 +- libexec/telnetd/slc.c | 2 +- libexec/telnetd/state.c | 57 +------ libexec/telnetd/sys_term.c | 342 ++++++++++++++++++------------------- libexec/telnetd/telnetd.8 | 17 +- libexec/telnetd/telnetd.c | 121 ++++--------- libexec/telnetd/termstat.c | 55 +++--- libexec/telnetd/utility.c | 87 +--------- 10 files changed, 278 insertions(+), 446 deletions(-) diff --git a/libexec/telnetd/Makefile b/libexec/telnetd/Makefile index f366f5360725..b6ac1e029dbb 100644 --- a/libexec/telnetd/Makefile +++ b/libexec/telnetd/Makefile @@ -1,14 +1,17 @@ -# @(#)Makefile 8.2 (Berkeley) 12/15/93 # $FreeBSD$ -PROG= telnetd -CFLAGS+=-DLINEMODE -DUSE_TERMIO -DDIAGNOSTICS -#CFLAGS+=-DKLUDGELINEMODE -CFLAGS+=-DOLD_ENVIRON -DENV_HACK -CFLAGS+=-I${.CURDIR}/../../lib -CFLAGS+=-DINET6 -SRCS= global.c slc.c state.c sys_term.c telnetd.c \ - termstat.c utility.c +# Do not define -DKLUDGELINEMODE, as it does not interact well with many +# telnet implementations. + +PROG= telnetd +MAN= telnetd.8 + +CFLAGS+= -DLINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON \ + -DENV_HACK \ + -I${.CURDIR}/../../lib -DINET6 + +SRCS= global.c slc.c state.c sys_term.c telnetd.c \ + termstat.c utility.c .if exists(${.OBJDIR}/../../lib/libtelnet) LIBTELNET= ${.OBJDIR}/../../lib/libtelnet/libtelnet.a @@ -16,8 +19,7 @@ LIBTELNET= ${.OBJDIR}/../../lib/libtelnet/libtelnet.a LIBTELNET= ${.CURDIR}/../../lib/libtelnet/libtelnet.a .endif -DPADD= ${LIBUTIL} ${LIBTERMCAP} ${LIBTELNET} -LDADD= -lutil -ltermcap ${LIBTELNET} -MAN= telnetd.8 +DPADD= ${LIBUTIL} ${LIBTERMCAP} ${LIBTELNET} +LDADD= -lutil -ltermcap ${LIBTELNET} .include diff --git a/libexec/telnetd/ext.h b/libexec/telnetd/ext.h index 406fe903d3a2..97c2e94c6152 100644 --- a/libexec/telnetd/ext.h +++ b/libexec/telnetd/ext.h @@ -46,9 +46,7 @@ extern int uselinemode; /* what linemode to use (on/off) */ extern int editmode; /* edit modes in use */ extern int useeditmode; /* edit modes to use */ extern int alwayslinemode; /* command line option */ -# ifdef KLUDGELINEMODE extern int lmodetype; /* Client support for linemode */ -# endif /* KLUDGELINEMODE */ #endif /* LINEMODE */ extern int flowmode; /* current flow control state */ extern int restartany; /* restart output on any character state */ @@ -61,9 +59,6 @@ extern int bftpd; /* behave as bftp daemon */ #if defined(SecurID) extern int require_SecurID; #endif -#if defined(AUTHENTICATION) -extern int auth_level; -#endif extern slcfun slctab[NSLC + 1]; /* slc mapping table */ @@ -143,11 +138,7 @@ extern void set_termbuf P((void)), start_login P((char *, int, char *)), start_slc P((int)), -#if defined(AUTHENTICATION) - start_slave P((char *)), -#else start_slave P((char *, int, char *)), -#endif suboption P((void)), telrcv P((void)), ttloop P((void)), @@ -231,7 +222,11 @@ extern int needtermstat; # ifdef ultrix # define DEFAULT_IM "\r\n\r\nULTRIX (%h) (%t)\r\n\r\r\n\r" # else -# define DEFAULT_IM "\r\n\r\nFreeBSD (%h) (%t)\r\n\r\r\n\r" +# ifdef __FreeBSD__ +# define DEFAULT_IM "\r\n\r\nFreeBSD (%h) (%t)\r\n\r\r\n\r" +# else +# define DEFAULT_IM "\r\n\r\n4.4 BSD UNIX (%h) (%t)\r\n\r\r\n\r" +# endif # endif # endif # endif diff --git a/libexec/telnetd/global.c b/libexec/telnetd/global.c index cedff5770f81..0cf95dbd463e 100644 --- a/libexec/telnetd/global.c +++ b/libexec/telnetd/global.c @@ -33,7 +33,7 @@ #ifndef lint #if 0 -static char sccsid[] = "@(#)global.c 8.1 (Berkeley) 6/4/93"; +static const char sccsid[] = "@(#)global.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; diff --git a/libexec/telnetd/slc.c b/libexec/telnetd/slc.c index 7fd7536e8cc8..780adf1be1ab 100644 --- a/libexec/telnetd/slc.c +++ b/libexec/telnetd/slc.c @@ -33,7 +33,7 @@ #ifndef lint #if 0 -static char sccsid[] = "@(#)slc.c 8.1 (Berkeley) 6/4/93"; +static const char sccsid[] = "@(#)slc.c 8.2 (Berkeley) 5/30/95"; #endif static const char rcsid[] = "$FreeBSD$"; diff --git a/libexec/telnetd/state.c b/libexec/telnetd/state.c index bad22ea97824..8b7a62d575d1 100644 --- a/libexec/telnetd/state.c +++ b/libexec/telnetd/state.c @@ -33,7 +33,7 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)state.c 8.2 (Berkeley) 12/15/93"; +static const char sccsid[] = "@(#)state.c 8.5 (Berkeley) 5/30/95"; #endif static const char rcsid[] = "$FreeBSD$"; @@ -41,9 +41,6 @@ static const char rcsid[] = #include #include "telnetd.h" -#if defined(AUTHENTICATION) -#include -#endif unsigned char doopt[] = { IAC, DO, '%', 'c', 0 }; unsigned char dont[] = { IAC, DONT, '%', 'c', 0 }; @@ -449,9 +446,6 @@ send_do(option, init) DIAG(TD_OPTIONS, printoption("td: send do", option)); } -#ifdef AUTHENTICATION -extern void auth_request(); -#endif #ifdef LINEMODE extern void doclientstat(); #endif @@ -561,12 +555,6 @@ willoption(option) break; #endif /* LINEMODE */ -#ifdef AUTHENTICATION - case TELOPT_AUTHENTICATION: - func = auth_request; - changeok++; - break; -#endif default: @@ -621,11 +609,6 @@ willoption(option) break; #endif /* LINEMODE */ -#ifdef AUTHENTICATION - case TELOPT_AUTHENTICATION: - func = auth_request; - break; -#endif case TELOPT_LFLOW: func = flowstat; @@ -720,11 +703,6 @@ wontoption(option) slctab[SLC_XOFF].defset.flag |= SLC_CANTCHANGE; break; -#if defined(AUTHENTICATION) - case TELOPT_AUTHENTICATION: - auth_finished(0, AUTH_REJECT); - break; -#endif /* * For options that we might spin waiting for @@ -773,11 +751,6 @@ wontoption(option) #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */ break; -#if defined(AUTHENTICATION) - case TELOPT_AUTHENTICATION: - auth_finished(0, AUTH_REJECT); - break; -#endif default: break; } @@ -1163,7 +1136,7 @@ suboption() if (SB_EOF()) break; /* another garbage check */ - if (request == LM_SLC) { /* SLC is not preceded by WILL or WONT */ + if (request == LM_SLC) { /* SLC is not preceeded by WILL or WONT */ /* * Process suboption buffer of slc's */ @@ -1411,27 +1384,6 @@ suboption() unsetenv(varp); break; } /* end of case TELOPT_NEW_ENVIRON */ -#if defined(AUTHENTICATION) - case TELOPT_AUTHENTICATION: - if (SB_EOF()) - break; - switch(SB_GET()) { - case TELQUAL_SEND: - case TELQUAL_REPLY: - /* - * These are sent by us and cannot be sent by - * the client. - */ - break; - case TELQUAL_IS: - auth_is(subpointer, SB_LEN()); - break; - case TELQUAL_NAME: - auth_name(subpointer, SB_LEN()); - break; - } - break; -#endif default: break; @@ -1446,7 +1398,7 @@ doclientstat() } #define ADD(c) *ncp++ = c -#define ADD_DATA(c) { *ncp++ = c; if (c == SE) *ncp++ = c; } +#define ADD_DATA(c) { *ncp++ = c; if (c == SE || c == IAC) *ncp++ = c; } void send_status() { @@ -1505,7 +1457,6 @@ send_status() ADD(LFLOW_RESTART_XON); } ADD(SE); - ADD(SB); } } @@ -1518,8 +1469,6 @@ send_status() ADD(TELOPT_LINEMODE); ADD(LM_MODE); ADD_DATA(editmode); - if (editmode == IAC) - ADD(IAC); ADD(SE); ADD(SB); diff --git a/libexec/telnetd/sys_term.c b/libexec/telnetd/sys_term.c index 3102e0f8b008..a5c4aeb325cb 100644 --- a/libexec/telnetd/sys_term.c +++ b/libexec/telnetd/sys_term.c @@ -33,7 +33,7 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)sys_term.c 8.2 (Berkeley) 12/15/93"; +static const char sccsid[] = "@(#)sys_term.c 8.4+1 (Berkeley) 5/30/95"; #endif static const char rcsid[] = "$FreeBSD$"; @@ -42,11 +42,10 @@ static const char rcsid[] = #include "telnetd.h" #include "pathnames.h" -#if defined(AUTHENTICATION) -#include -#endif extern char *altlogin; +int cleanopen(char *line); +void scrub_env(void); #if defined(CRAY) || defined(__hpux) # define PARENT_DOES_UTMP @@ -78,24 +77,21 @@ char utmpf[] = "/etc/utmp"; char wtmpf[] = "/etc/wtmp"; # endif /* PARENT_DOES_UTMP */ +#include + # ifdef CRAY #include #include -# if defined(_SC_CRAY_SECURE_SYS) && !defined(SCM_SECURITY) - /* - * UNICOS 6.0/6.1 do not have SCM_SECURITY defined, so we can - * use it to tell us to turn off all the socket security code, - * since that is only used in UNICOS 7.0 and later. - */ -# undef _SC_CRAY_SECURE_SYS +# if (UNICOS_LVL == '7.0') || (UNICOS_LVL == '7.1') +# define UNICOS7x # endif -# if defined(_SC_CRAY_SECURE_SYS) +# ifdef UNICOS7x #include #include extern int secflag; extern struct sysv sysv; -# endif /* _SC_CRAY_SECURE_SYS */ +# endif /* UNICOS7x */ # endif /* CRAY */ #endif /* NEWINIT */ @@ -190,7 +186,6 @@ int ttyfd = -1; #include #include -#include int cleanopen __P((char *)); void scrub_env __P((void)); @@ -246,17 +241,19 @@ set_termbuf() * Only make the necessary changes. */ #ifndef USE_TERMIO - if (bcmp((char *)&termbuf.sg, (char *)&termbuf2.sg, sizeof(termbuf.sg))) + if (memcmp((char *)&termbuf.sg, (char *)&termbuf2.sg, + sizeof(termbuf.sg))) (void) ioctl(pty, TIOCSETN, (char *)&termbuf.sg); - if (bcmp((char *)&termbuf.tc, (char *)&termbuf2.tc, sizeof(termbuf.tc))) + if (memcmp((char *)&termbuf.tc, (char *)&termbuf2.tc, + sizeof(termbuf.tc))) (void) ioctl(pty, TIOCSETC, (char *)&termbuf.tc); - if (bcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc, + if (memcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc, sizeof(termbuf.ltc))) (void) ioctl(pty, TIOCSLTC, (char *)&termbuf.ltc); if (termbuf.lflags != termbuf2.lflags) (void) ioctl(pty, TIOCLSET, (char *)&termbuf.lflags); #else /* USE_TERMIO */ - if (bcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf))) + if (memcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf))) # ifdef STREAMSPTY (void) tcsetattr(ttyfd, TCSANOW, &termbuf); # else @@ -569,7 +566,7 @@ int *ptynum; p = open(myline, 2); if (p < 0) continue; - (void) sprintf(line, "/dev/ttyp%03d", *ptynum); + (void) sprintf(line, "%sp%03d", _PATH_TTY, *ptynum); /* * Here are some shenanigans to make sure that there * are no listeners lurking on the line. @@ -728,23 +725,6 @@ tty_israw() #endif } -#if defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R) - int -tty_setraw(on) -{ -# ifndef USE_TERMIO - if (on) - termbuf.sg.sg_flags |= RAW; - else - termbuf.sg.sg_flags &= ~RAW; -# else - if (on) - termbuf.c_lflag &= ~ICANON; - else - termbuf.c_lflag |= ICANON; -# endif -} -#endif void tty_binaryin(on) @@ -966,6 +946,7 @@ tty_iscrnl() #endif #ifdef DECODE_BAUD + /* * A table of available terminal speeds */ @@ -973,12 +954,37 @@ struct termspeeds { int speed; int value; } termspeeds[] = { - { 0, B0 }, { 50, B50 }, { 75, B75 }, - { 110, B110 }, { 134, B134 }, { 150, B150 }, - { 200, B200 }, { 300, B300 }, { 600, B600 }, - { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 }, - { 4800, B4800 }, { 9600, B9600 }, { 19200, B9600 }, - { 38400, B9600 }, { -1, B9600 } + { 0, B0 }, { 50, B50 }, { 75, B75 }, + { 110, B110 }, { 134, B134 }, { 150, B150 }, + { 200, B200 }, { 300, B300 }, { 600, B600 }, + { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 }, + { 4800, B4800 }, +#ifdef B7200 + { 7200, B7200 }, +#endif + { 9600, B9600 }, +#ifdef B14400 + { 14400, B14400 }, +#endif +#ifdef B19200 + { 19200, B19200 }, +#endif +#ifdef B28800 + { 28800, B28800 }, +#endif +#ifdef B38400 + { 38400, B38400 }, +#endif +#ifdef B57600 + { 57600, B57600 }, +#endif +#ifdef B115200 + { 115200, B115200 }, +#endif +#ifdef B230400 + { 230400, B230400 }, +#endif + { -1, 0 } }; #endif /* DECODE_BAUD */ @@ -991,6 +997,8 @@ tty_tspeed(val) for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++) ; + if (tp->speed == -1) /* back up to last valid value */ + --tp; cfsetospeed(&termbuf, tp->value); #else /* DECODE_BAUD */ cfsetospeed(&termbuf, val); @@ -1006,6 +1014,8 @@ tty_rspeed(val) for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++) ; + if (tp->speed == -1) /* back up to last valid value */ + --tp; cfsetispeed(&termbuf, tp->value); #else /* DECODE_BAUD */ cfsetispeed(&termbuf, val); @@ -1126,7 +1136,7 @@ getptyslave() init_termbuf(); # ifdef TIOCGWINSZ if (def_row || def_col) { - bzero((char *)&ws, sizeof(ws)); + memset((char *)&ws, 0, sizeof(ws)); ws.ws_col = def_col; ws.ws_row = def_row; (void)ioctl(t, TIOCSWINSZ, (char *)&ws); @@ -1182,17 +1192,10 @@ getptyslave() #endif /* !defined(CRAY) || !defined(NEWINIT) */ if (net > 2) (void) close(net); -#if defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R) - /* - * Leave the pty open so that we can write out the rlogin - * protocol for /bin/login, if the authentication works. - */ -#else if (pty > 2) { (void) close(pty); pty = -1; } -#endif } #if !defined(CRAY) || !defined(NEWINIT) @@ -1208,9 +1211,9 @@ cleanopen(line) char *line; { register int t; -#if defined(_SC_CRAY_SECURE_SYS) +#ifdef UNICOS7x struct secstat secbuf; -#endif /* _SC_CRAY_SECURE_SYS */ +#endif /* UNICOS7x */ #ifndef STREAMSPTY /* @@ -1224,7 +1227,7 @@ cleanopen(line) # if !defined(CRAY) && (BSD > 43) (void) revoke(line); # endif -#if defined(_SC_CRAY_SECURE_SYS) +#ifdef UNICOS7x if (secflag) { if (secstat(line, &secbuf) < 0) return(-1); @@ -1233,18 +1236,18 @@ cleanopen(line) if (setucmp(secbuf.st_compart) < 0) return(-1); } -#endif /* _SC_CRAY_SECURE_SYS */ +#endif /* UNICOS7x */ t = open(line, O_RDWR|O_NOCTTY); -#if defined(_SC_CRAY_SECURE_SYS) +#ifdef UNICOS7x if (secflag) { if (setulvl(sysv.sy_minlvl) < 0) return(-1); if (setucmp(0) < 0) return(-1); } -#endif /* _SC_CRAY_SECURE_SYS */ +#endif /* UNICOS7x */ if (t < 0) return(-1); @@ -1269,7 +1272,7 @@ cleanopen(line) (void) signal(SIGHUP, SIG_DFL); setpgrp(); -#if defined(_SC_CRAY_SECURE_SYS) +#ifdef UNICOS7x if (secflag) { if (secstat(line, &secbuf) < 0) return(-1); @@ -1278,18 +1281,18 @@ cleanopen(line) if (setucmp(secbuf.st_compart) < 0) return(-1); } -#endif /* _SC_CRAY_SECURE_SYS */ +#endif /* UNICOS7x */ i = open(line, O_RDWR); -#if defined(_SC_CRAY_SECURE_SYS) +#ifdef UNICOS7x if (secflag) { if (setulvl(sysv.sy_minlvl) < 0) return(-1); if (setucmp(0) < 0) return(-1); } -#endif /* _SC_CRAY_SECURE_SYS */ +#endif /* UNICOS7x */ if (i < 0) return(-1); @@ -1338,7 +1341,11 @@ login_tty(t) * setsid() call above may have set our pgrp, so clear * it out before opening the tty... */ +# ifndef SOLARIS (void) setpgrp(0, 0); +# else + (void) setpgrp(); +# endif close(open(line, O_RDWR)); # endif if (t != 0) @@ -1379,15 +1386,6 @@ startslave(host, autologin, autoname) register int n; #endif /* NEWINIT */ -#if defined(AUTHENTICATION) - if (!autoname || !autoname[0]) - autologin = 0; - - if (autologin < auth_level) { - fatal(net, "Authorization failed"); - exit(1); - } -#endif #ifndef NEWINIT # ifdef PARENT_DOES_UTMP @@ -1530,7 +1528,7 @@ start_login(host, autologin, name) char *name; { register char **argv; - char **addarg(); + char **addarg(), *user; extern char *getenv(); #ifdef UTMPX register int pid = getpid(); @@ -1546,7 +1544,7 @@ start_login(host, autologin, name) * Create utmp entry for child */ - bzero(&utmpx, sizeof(utmpx)); + memset(&utmpx, 0, sizeof(utmpx)); SCPYN(utmpx.ut_user, ".telnet"); SCPYN(utmpx.ut_line, line + sizeof(_PATH_DEV) - 1); utmpx.ut_pid = pid; @@ -1574,13 +1572,6 @@ start_login(host, autologin, name) #if !defined(NO_LOGIN_H) -# if defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R) - /* - * Don't add the "-h host" option if we are going - * to be adding the "-r host" option down below... - */ - if ((auth_level < 0) || (autologin != AUTH_VALID)) -# endif { argv = addarg(argv, "-h"); argv = addarg(argv, host); @@ -1603,6 +1594,19 @@ start_login(host, autologin, name) #if !defined(NO_LOGIN_P) argv = addarg(argv, "-p"); #endif +#ifdef LINEMODE + /* + * Set the environment variable "LINEMODE" to either + * "real" or "kludge" if we are operating in either + * real or kludge linemode. + */ + if (lmodetype == REAL_LINEMODE) + setenv("LINEMODE", "real", 1); +# ifdef KLUDGELINEMODE + else if (lmodetype == KLUDGE_LINEMODE || lmodetype == KLUDGE_OK) + setenv("LINEMODE", "kludge", 1); +# endif +#endif #ifdef BFTPDAEMON /* * Are we working as the bftp daemon? If so, then ask login @@ -1620,93 +1624,9 @@ start_login(host, autologin, name) */ if (require_SecurID) argv = addarg(argv, "-s"); -#endif -#if defined (AUTHENTICATION) - if (auth_level >= 0 && autologin == AUTH_VALID) { -# if !defined(NO_LOGIN_F) - argv = addarg(argv, "-f"); - argv = addarg(argv, "--"); - argv = addarg(argv, name); -# else -# if defined(LOGIN_R) - /* - * We don't have support for "login -f", but we - * can fool /bin/login into thinking that we are - * rlogind, and allow us to log in without a - * password. The rlogin protocol expects - * local-user\0remote-user\0term/speed\0 - */ - - if (pty > 2) { - register char *cp; - char speed[128]; - int isecho, israw, xpty, len; - extern int def_rspeed; -# ifndef LOGIN_HOST - /* - * Tell login that we are coming from "localhost". - * If we passed in the real host name, then the - * user would have to allow .rhost access from - * every machine that they want authenticated - * access to work from, which sort of defeats - * the purpose of an authenticated login... - * So, we tell login that the session is coming - * from "localhost", and the user will only have - * to have "localhost" in their .rhost file. - */ -# define LOGIN_HOST "localhost" -# endif - argv = addarg(argv, "-r"); - argv = addarg(argv, LOGIN_HOST); - - xpty = pty; -# ifndef STREAMSPTY - pty = 0; -# else - ttyfd = 0; -# endif - init_termbuf(); - isecho = tty_isecho(); - israw = tty_israw(); - if (isecho || !israw) { - tty_setecho(0); /* Turn off echo */ - tty_setraw(1); /* Turn on raw */ - set_termbuf(); - } - len = strlen(name)+1; - write(xpty, name, len); - write(xpty, name, len); - snprintf(speed, sizeof(speed), - "%s/%d", (cp = getenv("TERM")) ? cp : "", - (def_rspeed > 0) ? def_rspeed : 9600); - len = strlen(speed)+1; - write(xpty, speed, len); - - if (isecho || !israw) { - init_termbuf(); - tty_setecho(isecho); - tty_setraw(israw); - set_termbuf(); - if (!israw) { - /* - * Write a newline to ensure - * that login will be able to - * read the line... - */ - write(xpty, "\n", 1); - } - } - pty = xpty; - } -# else - argv = addarg(argv, "--"); - argv = addarg(argv, name); -# endif -# endif - } else #endif if (getenv("USER")) { - argv = addarg(argv, "--"); + argv = addarg(argv, "--"); argv = addarg(argv, getenv("USER")); #if defined(LOGIN_ARGS) && defined(NO_LOGIN_P) { @@ -1727,10 +1647,16 @@ start_login(host, autologin, name) */ unsetenv("USER"); } -#if defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R) - if (pty > 2) - close(pty); -#endif +#ifdef SOLARIS + else { + char **p; + + argv = addarg(argv, ""); /* no login name */ + for (p = environ; *p; p++) { + argv = addarg(argv, *p); + } + } +#endif /* SOLARIS */ closelog(); if (altlogin == NULL) { @@ -1762,14 +1688,14 @@ addarg(argv, val) } for (cpp = argv; *cpp; cpp++) ; - if (cpp == &argv[(long)argv[-1]]) { + if (cpp == &argv[(int)argv[-1]]) { --argv; - *argv = (char *)((long)(*argv) + 10); - argv = (char **)realloc(argv, sizeof(*argv) * ((long)(*argv) + 2)); + *argv = (char *)((int)(*argv) + 10); + argv = (char **)realloc(argv, sizeof(*argv)*((int)(*argv) + 2)); if (argv == NULL) return(NULL); argv++; - cpp = &argv[(long)argv[-1] - 10]; + cpp = &argv[(int)argv[-1] - 10]; } *cpp++ = val; *cpp = 0; @@ -1865,6 +1791,8 @@ cleanup(sig) # ifdef CRAY static int incleanup = 0; register int t; + int child_status; /* status of child process as returned by waitpid */ + int flags = WNOHANG|WUNTRACED; /* * 1: Pick up the zombie, if we are being called @@ -1875,9 +1803,17 @@ cleanup(sig) * 5: Close down the network and pty connections. * 6: Finish up the TMPDIR cleanup, if needed. */ - if (sig == SIGCHLD) - while (waitpid(-1, 0, WNOHANG) > 0) + if (sig == SIGCHLD) { + while (waitpid(-1, &child_status, flags) > 0) ; /* VOID */ + /* Check if the child process was stopped + * rather than exited. We want cleanup only if + * the child has died. + */ + if (WIFSTOPPED(child_status)) { + return; + } + } t = sigblock(sigmask(SIGCHLD)); if (incleanup) { sigsetmask(t); @@ -1885,6 +1821,7 @@ cleanup(sig) } incleanup = 1; sigsetmask(t); +#ifdef UNICOS7x if (secflag) { /* * We need to set ourselves back to a null @@ -1894,6 +1831,7 @@ cleanup(sig) setulvl(sysv.sy_minlvl); setucmp((long)0); } +#endif /* UNICOS7x */ t = cleantmp(&wtmp); setutent(); /* just to make sure */ @@ -1993,6 +1931,28 @@ sigjob(sig) } } +/* + * jid_getutid: + * called by jobend() before calling cleantmp() + * to find the correct $TMPDIR to cleanup. + */ + + struct utmp * +jid_getutid(jid) + int jid; +{ + struct utmp *cur = NULL; + + setutent(); /* just to make sure */ + while (cur = getutent()) { + if ( (cur->ut_type != NULL) && (jid == cur->ut_jid) ) { + return(cur); + } + } + + return(0); +} + /* * Clean up the TMPDIR that login created. * The first time this is called we pick up the info @@ -2049,9 +2009,27 @@ jobend(jid, path, user) register char *user; { static int saved_jid = 0; + static int pty_saved_jid = 0; static char saved_path[sizeof(wtmp.ut_tpath)+1]; static char saved_user[sizeof(wtmp.ut_user)+1]; + /* + * this little piece of code comes into play + * only when ptyreconnect is used to reconnect + * to an previous session. + * + * this is the only time when the + * "saved_jid != jid" code is executed. + */ + + if ( saved_jid && saved_jid != jid ) { + if (!path) { /* called from signal handler */ + pty_saved_jid = jid; + } else { + pty_saved_jid = saved_jid; + } + } + if (path) { strncpy(saved_path, path, sizeof(wtmp.ut_tpath)); strncpy(saved_user, user, sizeof(wtmp.ut_user)); @@ -2062,6 +2040,24 @@ jobend(jid, path, user) saved_jid = jid; return(0); } + + /* if the jid has changed, get the correct entry from the utmp file */ + + if ( saved_jid != jid ) { + struct utmp *utp = NULL; + struct utmp *jid_getutid(); + + utp = jid_getutid(pty_saved_jid); + + if (utp == 0) { + syslog(LOG_ERR, "Can't get /etc/utmp entry to clean TMPDIR"); + return(-1); + } + + cleantmpdir(jid, utp->ut_tpath, utp->ut_user); + return(1); + } + cleantmpdir(jid, saved_path, saved_user); return(1); } diff --git a/libexec/telnetd/telnetd.8 b/libexec/telnetd/telnetd.8 index f166318da8bd..20093dfb4566 100644 --- a/libexec/telnetd/telnetd.8 +++ b/libexec/telnetd/telnetd.8 @@ -29,10 +29,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)telnetd.8 8.3 (Berkeley) 3/1/94 +.\" @(#)telnetd.8 8.4 (Berkeley) 6/1/94 .\" $FreeBSD$ .\" -.Dd March 1, 1994 +.Dd January 27, 2000 .Dt TELNETD 8 .Os .Sh NAME @@ -42,7 +42,7 @@ protocol server .Sh SYNOPSIS .Nm /usr/libexec/telnetd -.Op Fl Uhlkns +.Op Fl BUhlkns .Op Fl D Ar debugmode .Op Fl I Ns Ar initid .Op Fl S Ar tos @@ -137,6 +137,17 @@ All user verification will happen through the .Xr login 1 program. .El +.It Fl B +Specify bftp server mode. In this mode, +.Nm +causes login to start a +.Xr bftp 1 +session rather than the user's +normal shell. In bftp daemon mode normal +logins are not supported, and it must be used +on a port other than the normal +.Tn TELNET +port. .It Fl D Ar debugmode This option may be used for debugging purposes. This allows diff --git a/libexec/telnetd/telnetd.c b/libexec/telnetd/telnetd.c index 011c0bc76db5..f433294dca0c 100644 --- a/libexec/telnetd/telnetd.c +++ b/libexec/telnetd/telnetd.c @@ -39,7 +39,7 @@ static const char copyright[] = #ifndef lint #if 0 -static char sccsid[] = "@(#)telnetd.c 8.2 (Berkeley) 12/15/93"; +static const char sccsid[] = "@(#)telnetd.c 8.4 (Berkeley) 5/30/95"; #endif static const char rcsid[] = "$FreeBSD$"; @@ -89,10 +89,6 @@ struct socket_security ss; # endif /* SO_SEC_MULTI */ #endif /* _SC_CRAY_SECURE_SYS */ -#if defined(AUTHENTICATION) -#include -int auth_level = 0; -#endif #if defined(SecurID) int require_SecurID = 0; #endif @@ -120,8 +116,6 @@ char ptyibuf2[BUFSIZ]; unsigned char ctlbuf[BUFSIZ]; struct strbuf strbufc, strbufd; -int readstream(); - #else /* ! STREAMPTY */ /* @@ -131,6 +125,13 @@ int readstream(); char ptyibuf[BUFSIZ], *ptyip = ptyibuf; char ptyibuf2[BUFSIZ]; +# include + +int readstream(int p, char *ibuf, int bufsize); +void doit(struct sockaddr *who); +int terminaltypeok(char *s); +void startslave(char *host, int autologin, char *autoname); + #endif /* ! STREAMPTY */ int hostinfo = 1; /* do we print login banner? */ @@ -157,9 +158,6 @@ extern void usage P((void)); char valid_opts[] = { 'd', ':', 'h', 'k', 'n', 'p', ':', 'S', ':', 'u', ':', 'U', '4', '6', -#ifdef AUTHENTICATION - 'a', ':', 'X', ':', -#endif #ifdef BFTPDAEMON 'B', #endif @@ -225,32 +223,6 @@ main(argc, argv) while ((ch = getopt(argc, argv, valid_opts)) != -1) { switch(ch) { -#ifdef AUTHENTICATION - case 'a': - /* - * Check for required authentication level - */ - if (strcmp(optarg, "debug") == 0) { - extern int auth_debug_mode; - auth_debug_mode = 1; - } else if (strcasecmp(optarg, "none") == 0) { - auth_level = 0; - } else if (strcasecmp(optarg, "other") == 0) { - auth_level = AUTH_OTHER; - } else if (strcasecmp(optarg, "user") == 0) { - auth_level = AUTH_USER; - } else if (strcasecmp(optarg, "valid") == 0) { - auth_level = AUTH_VALID; - } else if (strcasecmp(optarg, "off") == 0) { - /* - * This hack turns off authentication - */ - auth_level = -1; - } else { - warnx("unknown authorization level for -a"); - } - break; -#endif /* AUTHENTICATION */ #ifdef BFTPDAEMON case 'B': @@ -382,14 +354,6 @@ main(argc, argv) registerd_host_only = 1; break; -#ifdef AUTHENTICATION - case 'X': - /* - * Check for invalid authentication types - */ - auth_disable_name(optarg); - break; -#endif /* AUTHENTICATION */ case '4': family = AF_INET; @@ -476,7 +440,7 @@ main(argc, argv) int szi = sizeof(int); #endif /* SO_SEC_MULTI */ - bzero((char *)&dv, sizeof(dv)); + memset((char *)&dv, 0, sizeof(dv)); if (getsysv(&sysv, sizeof(struct sysv)) != 0) err(1, "getsysv"); @@ -555,18 +519,12 @@ main(argc, argv) usage() { fprintf(stderr, "usage: telnetd"); -#ifdef AUTHENTICATION - fprintf(stderr, " [-a (debug|other|user|valid|off|none)]\n\t"); -#endif #ifdef BFTPDAEMON fprintf(stderr, " [-B]"); #endif fprintf(stderr, " [-debug]"); #ifdef DIAGNOSTICS fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t"); -#endif -#ifdef AUTHENTICATION - fprintf(stderr, " [-edebug]"); #endif fprintf(stderr, " [-h]"); #if defined(CRAY) && defined(NEWINIT) @@ -588,9 +546,6 @@ usage() #endif #ifdef HAS_GETTOS fprintf(stderr, " [-S tos]"); -#endif -#ifdef AUTHENTICATION - fprintf(stderr, " [-X auth-type]"); #endif fprintf(stderr, " [-u utmp_hostname_length] [-U]"); fprintf(stderr, " [port]\n"); @@ -615,17 +570,6 @@ getterminaltype(name) void _gettermname(); settimer(baseline); -#if defined(AUTHENTICATION) - /* - * Handle the Authentication option before we do anything else. - */ - send_do(TELOPT_AUTHENTICATION, 1); - while (his_will_wont_is_changing(TELOPT_AUTHENTICATION)) - ttloop(); - if (his_state_is_will(TELOPT_AUTHENTICATION)) { - retval = auth_wait(name); - } -#endif send_do(TELOPT_TTYPE, 1); send_do(TELOPT_TSPEED, 1); @@ -645,28 +589,34 @@ getterminaltype(name) { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; output_datalen(sb, sizeof sb); + DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); } if (his_state_is_will(TELOPT_XDISPLOC)) { static unsigned char sb[] = { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE }; output_datalen(sb, sizeof sb); + DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); } if (his_state_is_will(TELOPT_NEW_ENVIRON)) { static unsigned char sb[] = { IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE }; output_datalen(sb, sizeof sb); + DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); } else if (his_state_is_will(TELOPT_OLD_ENVIRON)) { static unsigned char sb[] = { IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE }; output_datalen(sb, sizeof sb); + DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); } if (his_state_is_will(TELOPT_TTYPE)) { output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf); + DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2, + sizeof ttytype_sbbuf - 2);); } if (his_state_is_will(TELOPT_TSPEED)) { while (sequenceIs(tspeedsubopt, baseline)) @@ -744,6 +694,8 @@ _gettermname() return; settimer(baseline); output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf); + DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2, + sizeof ttytype_sbbuf - 2);); while (sequenceIs(ttypesubopt, baseline)) ttloop(); } @@ -832,7 +784,7 @@ doit(who) if (realhostname_sa(remote_hostname, sizeof(remote_hostname) - 1, who, who->sa_len) == HOSTNAME_INVALIDADDR && registerd_host_only) fatal(net, "Couldn't resolve your address into a host name.\r\n\ - Please contact your net administrator"); + Please contact your net administrator"); remote_hostname[sizeof(remote_hostname) - 1] = '\0'; trimdomain(remote_hostname, UT_HOSTSIZE); @@ -846,9 +798,6 @@ doit(who) host_name[sizeof(host_name) - 1] = '\0'; hostname = host_name; -#if defined(AUTHENTICATION) - auth_encrypt_init(hostname, remote_hostname, "TELNETD", 1); -#endif init_env(); /* @@ -904,10 +853,7 @@ telnet(f, p, host) char *HE; char *HN; char *IM; - char *IF; - char *if_buf; - int if_fd; - struct stat statbuf; + int nfd; /* * Initialize the slc mapping table. @@ -1103,11 +1049,8 @@ telnet(f, p, host) HE = Getstr("he", &cp); HN = Getstr("hn", &cp); IM = Getstr("im", &cp); - IF = Getstr("if", &cp); if (HN && *HN) (void) strlcpy(host_name, HN, sizeof(host_name)); - if (IF && (if_fd = open(IF, O_RDONLY, 000)) != -1) - IM = 0; if (IM == 0) IM = ""; } else { @@ -1117,14 +1060,6 @@ telnet(f, p, host) edithost(HE, host_name); if (hostinfo && *IM) putf(IM, ptyibuf2); - else if (IF && if_fd != -1) { - fstat (if_fd, &statbuf); - if_buf = (char *) mmap (0, statbuf.st_size, PROT_READ, - 0, if_fd, 0); - putf(if_buf, ptyibuf2); - munmap (if_buf, statbuf.st_size); - close (if_fd); - } if (pcc) (void) strncat(ptyibuf2, ptyip, pcc+1); @@ -1147,6 +1082,7 @@ telnet(f, p, host) */ startslave(host, level, user_name); + nfd = ((f > p) ? f : p) + 1; for (;;) { fd_set ibits, obits, xbits; register int c; @@ -1178,7 +1114,7 @@ telnet(f, p, host) if (!SYNCHing) { FD_SET(f, &xbits); } - if ((c = select(16, &ibits, &obits, &xbits, + if ((c = select(nfd, &ibits, &obits, &xbits, (struct timeval *)0)) < 1) { if (c == -1) { if (errno == EINTR) { @@ -1315,6 +1251,9 @@ telnet(f, p, host) */ output_data("%c%c", IAC, DM); neturg = nfrontp-1; /* off by one XXX */ + DIAG(TD_OPTIONS, + printoption("td: send IAC", DM)); + #endif } if (his_state_is_will(TELOPT_LFLOW) && @@ -1329,6 +1268,9 @@ telnet(f, p, host) flowmode ? LFLOW_ON : LFLOW_OFF, IAC, SE); + DIAG(TD_OPTIONS, printsub('>', + (unsigned char *)nfrontp-4, + 4);); } } pcc--; @@ -1494,6 +1436,14 @@ interrupt() { ptyflush(); /* half-hearted */ +#if defined(STREAMSPTY) && defined(TIOCSIGNAL) + /* Streams PTY style ioctl to post a signal */ + { + int sig = SIGINT; + (void) ioctl(pty, TIOCSIGNAL, &sig); + (void) ioctl(pty, I_FLUSH, FLUSHR); + } +#else #ifdef TCSIG (void) ioctl(pty, TCSIG, (char *)SIGINT); #else /* TCSIG */ @@ -1501,6 +1451,7 @@ interrupt() *pfrontp++ = slctab[SLC_IP].sptr ? (unsigned char)*slctab[SLC_IP].sptr : '\177'; #endif /* TCSIG */ +#endif } /* diff --git a/libexec/telnetd/termstat.c b/libexec/telnetd/termstat.c index 2a5c74cdceb0..c36e7986912e 100644 --- a/libexec/telnetd/termstat.c +++ b/libexec/telnetd/termstat.c @@ -33,7 +33,7 @@ #ifndef lint #if 0 -static char sccsid[] = "@(#)termstat.c 8.1 (Berkeley) 6/4/93"; +static const char sccsid[] = "@(#)termstat.c 8.2 (Berkeley) 5/30/95"; #endif static const char rcsid[] = "$FreeBSD$"; @@ -165,34 +165,33 @@ localstat() tty_setlinemode(uselinemode); } - if (uselinemode) { + if (uselinemode) { + /* + * Check for state of BINARY options. + * + * We only need to do the binary dance if we are actually going + * to use linemode. As this confuses some telnet clients + * that don't support linemode, and doesn't gain us + * anything, we don't do it unless we're doing linemode. + * -Crh (henrich@msu.edu) + */ - /* - * Check for state of BINARY options. - * - * We only need to do the binary dance if we are actually going - * to use linemode. As this confuses some telnet clients that dont - * support linemode, and doesnt gain us anything, we dont do it - * unless we're doing linemode. -Crh (henrich@msu.edu) - */ + if (tty_isbinaryin()) { + if (his_want_state_is_wont(TELOPT_BINARY)) + send_do(TELOPT_BINARY, 1); + } else { + if (his_want_state_is_will(TELOPT_BINARY)) + send_dont(TELOPT_BINARY, 1); + } - if (tty_isbinaryin()) { - if (his_want_state_is_wont(TELOPT_BINARY)) - send_do(TELOPT_BINARY, 1); - } else { - if (his_want_state_is_will(TELOPT_BINARY)) - send_dont(TELOPT_BINARY, 1); - } - - if (tty_isbinaryout()) { - if (my_want_state_is_wont(TELOPT_BINARY)) - send_will(TELOPT_BINARY, 1); - } else { - if (my_want_state_is_will(TELOPT_BINARY)) - send_wont(TELOPT_BINARY, 1); - } - - } + if (tty_isbinaryout()) { + if (my_want_state_is_wont(TELOPT_BINARY)) + send_will(TELOPT_BINARY, 1); + } else { + if (my_want_state_is_will(TELOPT_BINARY)) + send_wont(TELOPT_BINARY, 1); + } + } /* * Do echo mode handling as soon as we know what the @@ -618,7 +617,7 @@ defer_terminit() if (def_col || def_row) { struct winsize ws; - bzero((char *)&ws, sizeof(ws)); + memset((char *)&ws, 0, sizeof(ws)); ws.ws_col = def_col; ws.ws_row = def_row; (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); diff --git a/libexec/telnetd/utility.c b/libexec/telnetd/utility.c index 677dadbdae68..e544fb1709ae 100644 --- a/libexec/telnetd/utility.c +++ b/libexec/telnetd/utility.c @@ -33,7 +33,7 @@ #ifndef lint #if 0 -static char sccsid[] = "@(#)utility.c 8.2 (Berkeley) 12/15/93"; +static const char sccsid[] = "@(#)utility.c 8.4 (Berkeley) 5/30/95"; #endif static const char rcsid[] = "$FreeBSD$"; @@ -43,6 +43,7 @@ static const char rcsid[] = #include #include #endif +#include #define PRINTOPTIONS #include "telnetd.h" @@ -217,7 +218,7 @@ netclear() next = nextitem(next); } while (wewant(next) && (nfrontp > next)); length = next-thisitem; - bcopy(thisitem, good, length); + memmove(good, thisitem, length); good += length; thisitem = next; } else { @@ -397,11 +398,6 @@ putf(cp, where) char *slash; time_t t; char db[100]; -#ifdef STREAMSPTY - extern char *index(); -#else - extern char *rindex(); -#endif #ifdef __FreeBSD__ static struct utsname kerninfo; @@ -425,9 +421,9 @@ putf(cp, where) case 't': #ifdef STREAMSPTY /* names are like /dev/pts/2 -- we want pts/2 */ - slash = index(line+1, '/'); + slash = strchr(line+1, '/'); #else - slash = rindex(line, '/'); + slash = strrchr(line, '/'); #endif if (slash == (char *) 0) putstr(line); @@ -500,7 +496,7 @@ printsub(direction, pointer, length) { register int i = 0; - if (!(diagnostic & TD_OPTIONS)) + if (!(diagnostic & TD_OPTIONS)) return; if (direction) { @@ -874,80 +870,13 @@ printsub(direction, pointer, length) } break; -#if defined(AUTHENTICATION) - case TELOPT_AUTHENTICATION: - output_data("AUTHENTICATION"); - - if (length < 2) { - output_data(" (empty suboption??\?)"); - break; - } - switch (pointer[1]) { - case TELQUAL_REPLY: - case TELQUAL_IS: - output_data(" %s ", (pointer[1] == TELQUAL_IS) ? - "IS" : "REPLY"); - if (AUTHTYPE_NAME_OK(pointer[2])) - output_data("%s ", AUTHTYPE_NAME(pointer[2])); - else - output_data("%d ", pointer[2]); - if (length < 3) { - output_data("(partial suboption??\?)"); - break; - } - output_data("%s|%s", - ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? - "CLIENT" : "SERVER", - ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? - "MUTUAL" : "ONE-WAY"); - - { - char buf[512]; - auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); - output_data("%s", buf); - } - break; - - case TELQUAL_SEND: - i = 2; - output_data(" SEND "); - while (i < length) { - if (AUTHTYPE_NAME_OK(pointer[i])) - output_data("%s ", AUTHTYPE_NAME(pointer[i])); - else - output_data("%d ", pointer[i]); - if (++i >= length) { - output_data("(partial suboption??\?)"); - break; - } - output_data("%s|%s ", - ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? - "CLIENT" : "SERVER", - ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? - "MUTUAL" : "ONE-WAY"); - ++i; - } - break; - - case TELQUAL_NAME: - output_data(" NAME \"%.*s\"", length - 2, pointer + 2); - break; - - default: - for (i = 2; i < length; i++) { - output_data(" ?%d?", pointer[i]); - } - break; - } - break; -#endif default: if (TELOPT_OK(pointer[0])) - output_data("%s (unknown)", TELOPT(pointer[0])); + output_data("%s (unknown)", TELOPT(pointer[0])); else - output_data("%d (unknown)", pointer[i]); + output_data("%d (unknown)", pointer[i]); for (i = 1; i < length; i++) { output_data(" %d", pointer[i]); }