diff options
Diffstat (limited to 'crypto/kerberosIV/appl/telnet/telnetd')
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/Makefile.am | 21 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/Makefile.in | 79 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/authenc.c | 81 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/defs.h | 190 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/ext.h | 202 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/global.c | 107 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/slc.c | 57 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/state.c | 1356 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/sys_term.c | 1893 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/telnetd.c | 1399 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/telnetd.h | 226 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/termstat.c | 140 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/telnet/telnetd/utility.c | 1165 |
13 files changed, 0 insertions, 6916 deletions
diff --git a/crypto/kerberosIV/appl/telnet/telnetd/Makefile.am b/crypto/kerberosIV/appl/telnet/telnetd/Makefile.am deleted file mode 100644 index c228518..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -# $Id: Makefile.am,v 1.12 1999/04/09 18:24:38 assar Exp $ - -include $(top_srcdir)/Makefile.am.common - -INCLUDES += -I$(srcdir)/.. $(INCLUDE_krb4) - -libexec_PROGRAMS = telnetd - -CHECK_LOCAL = - -telnetd_SOURCES = telnetd.c state.c termstat.c slc.c sys_term.c \ - utility.c global.c authenc.c defs.h ext.h telnetd.h - -LDADD = \ - ../libtelnet/libtelnet.a \ - $(LIB_krb5) \ - $(LIB_krb4) \ - $(top_builddir)/lib/des/libdes.la \ - $(LIB_tgetent) \ - $(LIB_logwtmp) \ - $(LIB_roken) diff --git a/crypto/kerberosIV/appl/telnet/telnetd/Makefile.in b/crypto/kerberosIV/appl/telnet/telnetd/Makefile.in deleted file mode 100644 index ed42d1d..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/Makefile.in +++ /dev/null @@ -1,79 +0,0 @@ -# $Id: Makefile.in,v 1.38 1999/03/11 13:50:16 joda Exp $ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ - -top_builddir = ../../.. - -SHELL = /bin/sh - -CC = @CC@ -LINK = @LINK@ -AR = ar -RANLIB = @RANLIB@ -DEFS = @DEFS@ -DBINDIR='"$(bindir)"' -CFLAGS = @CFLAGS@ $(WFLAGS) -WFLAGS = @WFLAGS@ -LD_FLAGS = @LD_FLAGS@ -LIBS = @LIBS@ -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -MKINSTALLDIRS = @top_srcdir@/mkinstalldirs - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -libdir = @libdir@ -libexecdir = @libexecdir@ -transform=@program_transform_name@ -EXECSUFFIX=@EXECSUFFIX@ - -PROGS = telnetd$(EXECSUFFIX) - -SOURCES=telnetd.c state.c termstat.c slc.c sys_term.c \ - utility.c global.c authenc.c - -OBJECTS=telnetd.o state.o termstat.o slc.o sys_term.o \ - utility.o global.o authenc.o - -libtop = @libtop@ - -LIBKRB = -L../../../lib/krb -lkrb -LIBDES = -L../../../lib/des -ldes -LIBKAFS = @KRB_KAFS_LIB@ -LIBROKEN = -L../../../lib/roken -lroken - -KLIB=$(LIBKAFS) $(LIBKRB) $(LIBDES) - - -all: $(PROGS) - -.c.o: - $(CC) -c $(DEFS) -I../../../include -I.. -I$(srcdir)/.. -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) $< - -telnetd$(EXECSUFFIX): $(OBJECTS) - $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ $(OBJECTS) -L../libtelnet -ltelnet $(KLIB) $(LIBROKEN) $(LIBS) @LIB_tgetent@ $(LIBROKEN) - -install: all - $(MKINSTALLDIRS) $(DESTDIR)$(libexecdir) - for x in $(PROGS); do \ - $(INSTALL_PROGRAM) $$x $(DESTDIR)$(libexecdir)/`echo $$x | sed '$(transform)'`; \ - done - -uninstall: - for x in $(PROGS); do \ - rm -f $(DESTDIR)$(libexecdir)/`echo $$x | sed '$(transform)'`; \ - done - -TAGS: $(SOURCES) - etags $(SOURCES) - -clean cleandir: - rm -f *.o *.a telnetd$(EXECSUFFIX) \#* *~ core - -distclean: clean - rm -f Makefile *~ - - -.PHONY: all install uninstall clean cleandir distclean diff --git a/crypto/kerberosIV/appl/telnet/telnetd/authenc.c b/crypto/kerberosIV/appl/telnet/telnetd/authenc.c deleted file mode 100644 index ec5f2dc..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/authenc.c +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "telnetd.h" - -RCSID("$Id: authenc.c,v 1.9 1999/09/05 19:14:50 assar Exp $"); - -#ifdef AUTHENTICATION - -int -telnet_net_write(unsigned char *str, int len) -{ - if (nfrontp + len < netobuf + BUFSIZ) { - memmove(nfrontp, str, len); - nfrontp += len; - return(len); - } - return(0); -} - -void -net_encrypt(void) -{ -#ifdef ENCRYPTION - char *s = (nclearto > nbackp) ? nclearto : nbackp; - if (s < nfrontp && encrypt_output) { - (*encrypt_output)((unsigned char *)s, nfrontp - s); - } - nclearto = nfrontp; -#endif -} - -int -telnet_spin(void) -{ - return ttloop(); -} - -char * -telnet_getenv(char *val) -{ - extern char *getenv(const char *); - return(getenv(val)); -} - -char * -telnet_gets(char *prompt, char *result, int length, int echo) -{ - return NULL; -} -#endif diff --git a/crypto/kerberosIV/appl/telnet/telnetd/defs.h b/crypto/kerberosIV/appl/telnet/telnetd/defs.h deleted file mode 100644 index dc3f842..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/defs.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)defs.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * Telnet server defines - */ - -#ifndef __DEFS_H__ -#define __DEFS_H__ - -#ifndef BSD -# define BSD 43 -#endif - -#if defined(PRINTOPTIONS) && defined(DIAGNOSTICS) -#define TELOPTS -#define TELCMDS -#define SLC_NAMES -#endif - -#if !defined(TIOCSCTTY) && defined(TCSETCTTY) -# define TIOCSCTTY TCSETCTTY -#endif - -#ifndef TIOCPKT_FLUSHWRITE -#define TIOCPKT_FLUSHWRITE 0x02 -#endif - -#ifndef TIOCPKT_NOSTOP -#define TIOCPKT_NOSTOP 0x10 -#endif - -#ifndef TIOCPKT_DOSTOP -#define TIOCPKT_DOSTOP 0x20 -#endif - -/* - * I/O data buffers defines - */ -#define NETSLOP 64 -#ifdef _CRAY -#undef BUFSIZ -#define BUFSIZ 2048 -#endif - -#define NIACCUM(c) { *netip++ = c; \ - ncc++; \ - } - -/* clock manipulations */ -#define settimer(x) (clocks.x = ++clocks.system) -#define sequenceIs(x,y) (clocks.x < clocks.y) - -/* - * Structures of information for each special character function. - */ -typedef struct { - unsigned char flag; /* the flags for this function */ - cc_t val; /* the value of the special character */ -} slcent, *Slcent; - -typedef struct { - slcent defset; /* the default settings */ - slcent current; /* the current settings */ - cc_t *sptr; /* a pointer to the char in */ - /* system data structures */ -} slcfun, *Slcfun; - -#ifdef DIAGNOSTICS -/* - * Diagnostics capabilities - */ -#define TD_REPORT 0x01 /* Report operations to client */ -#define TD_EXERCISE 0x02 /* Exercise client's implementation */ -#define TD_NETDATA 0x04 /* Display received data stream */ -#define TD_PTYDATA 0x08 /* Display data passed to pty */ -#define TD_OPTIONS 0x10 /* Report just telnet options */ -#endif /* DIAGNOSTICS */ - -/* - * We keep track of each side of the option negotiation. - */ - -#define MY_STATE_WILL 0x01 -#define MY_WANT_STATE_WILL 0x02 -#define MY_STATE_DO 0x04 -#define MY_WANT_STATE_DO 0x08 - -/* - * Macros to check the current state of things - */ - -#define my_state_is_do(opt) (options[opt]&MY_STATE_DO) -#define my_state_is_will(opt) (options[opt]&MY_STATE_WILL) -#define my_want_state_is_do(opt) (options[opt]&MY_WANT_STATE_DO) -#define my_want_state_is_will(opt) (options[opt]&MY_WANT_STATE_WILL) - -#define my_state_is_dont(opt) (!my_state_is_do(opt)) -#define my_state_is_wont(opt) (!my_state_is_will(opt)) -#define my_want_state_is_dont(opt) (!my_want_state_is_do(opt)) -#define my_want_state_is_wont(opt) (!my_want_state_is_will(opt)) - -#define set_my_state_do(opt) (options[opt] |= MY_STATE_DO) -#define set_my_state_will(opt) (options[opt] |= MY_STATE_WILL) -#define set_my_want_state_do(opt) (options[opt] |= MY_WANT_STATE_DO) -#define set_my_want_state_will(opt) (options[opt] |= MY_WANT_STATE_WILL) - -#define set_my_state_dont(opt) (options[opt] &= ~MY_STATE_DO) -#define set_my_state_wont(opt) (options[opt] &= ~MY_STATE_WILL) -#define set_my_want_state_dont(opt) (options[opt] &= ~MY_WANT_STATE_DO) -#define set_my_want_state_wont(opt) (options[opt] &= ~MY_WANT_STATE_WILL) - -/* - * Tricky code here. What we want to know is if the MY_STATE_WILL - * and MY_WANT_STATE_WILL bits have the same value. Since the two - * bits are adjacent, a little arithmatic will show that by adding - * in the lower bit, the upper bit will be set if the two bits were - * different, and clear if they were the same. - */ -#define my_will_wont_is_changing(opt) \ - ((options[opt]+MY_STATE_WILL) & MY_WANT_STATE_WILL) - -#define my_do_dont_is_changing(opt) \ - ((options[opt]+MY_STATE_DO) & MY_WANT_STATE_DO) - -/* - * Make everything symetrical - */ - -#define HIS_STATE_WILL MY_STATE_DO -#define HIS_WANT_STATE_WILL MY_WANT_STATE_DO -#define HIS_STATE_DO MY_STATE_WILL -#define HIS_WANT_STATE_DO MY_WANT_STATE_WILL - -#define his_state_is_do my_state_is_will -#define his_state_is_will my_state_is_do -#define his_want_state_is_do my_want_state_is_will -#define his_want_state_is_will my_want_state_is_do - -#define his_state_is_dont my_state_is_wont -#define his_state_is_wont my_state_is_dont -#define his_want_state_is_dont my_want_state_is_wont -#define his_want_state_is_wont my_want_state_is_dont - -#define set_his_state_do set_my_state_will -#define set_his_state_will set_my_state_do -#define set_his_want_state_do set_my_want_state_will -#define set_his_want_state_will set_my_want_state_do - -#define set_his_state_dont set_my_state_wont -#define set_his_state_wont set_my_state_dont -#define set_his_want_state_dont set_my_want_state_wont -#define set_his_want_state_wont set_my_want_state_dont - -#define his_will_wont_is_changing my_do_dont_is_changing -#define his_do_dont_is_changing my_will_wont_is_changing - -#endif /* __DEFS_H__ */ diff --git a/crypto/kerberosIV/appl/telnet/telnetd/ext.h b/crypto/kerberosIV/appl/telnet/telnetd/ext.h deleted file mode 100644 index 8f5edf1..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/ext.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ext.h 8.2 (Berkeley) 12/15/93 - */ - -/* $Id: ext.h,v 1.19 1999/09/05 19:15:21 assar Exp $ */ - -#ifndef __EXT_H__ -#define __EXT_H__ - -/* - * Telnet server variable declarations - */ -extern char options[256]; -extern char do_dont_resp[256]; -extern char will_wont_resp[256]; -extern int flowmode; /* current flow control state */ -extern int restartany; /* restart output on any character state */ -#ifdef DIAGNOSTICS -extern int diagnostic; /* telnet diagnostic capabilities */ -#endif /* DIAGNOSTICS */ -extern int require_otp; -#ifdef AUTHENTICATION -extern int auth_level; -#endif -extern const char *new_login; - -extern slcfun slctab[NSLC + 1]; /* slc mapping table */ - -extern char *terminaltype; - -/* - * I/O data buffers, pointers, and counters. - */ -extern char ptyobuf[BUFSIZ+NETSLOP], *pfrontp, *pbackp; - -extern char netibuf[BUFSIZ], *netip; - -extern char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp; -extern char *neturg; /* one past last bye of urgent data */ - -extern int pcc, ncc; - -extern int ourpty, net; -extern char *line; -extern int SYNCHing; /* we are in TELNET SYNCH mode */ - -int telnet_net_write (unsigned char *str, int len); -void net_encrypt (void); -int telnet_spin (void); -char *telnet_getenv (char *val); -char *telnet_gets (char *prompt, char *result, int length, int echo); -void get_slc_defaults (void); -void telrcv (void); -void send_do (int option, int init); -void willoption (int option); -void send_dont (int option, int init); -void wontoption (int option); -void send_will (int option, int init); -void dooption (int option); -void send_wont (int option, int init); -void dontoption (int option); -void suboption (void); -void doclientstat (void); -void send_status (void); -void init_termbuf (void); -void set_termbuf (void); -int spcset (int func, cc_t *valp, cc_t **valpp); -void set_utid (void); -int getpty (int *ptynum); -int tty_isecho (void); -int tty_flowmode (void); -int tty_restartany (void); -void tty_setecho (int on); -int tty_israw (void); -void tty_binaryin (int on); -void tty_binaryout (int on); -int tty_isbinaryin (void); -int tty_isbinaryout (void); -int tty_issofttab (void); -void tty_setsofttab (int on); -int tty_islitecho (void); -void tty_setlitecho (int on); -int tty_iscrnl (void); -void tty_tspeed (int val); -void tty_rspeed (int val); -void getptyslave (void); -int cleanopen (char *line); -void startslave (char *host, int autologin, char *autoname); -void init_env (void); -void start_login (char *host, int autologin, char *name); -void cleanup (int sig); -int main (int argc, char **argv); -int getterminaltype (char *name, size_t); -void _gettermname (void); -int terminaltypeok (char *s); -void my_telnet (int f, int p, char*, int, char*); -void interrupt (void); -void sendbrk (void); -void sendsusp (void); -void recv_ayt (void); -void doeof (void); -void flowstat (void); -void clientstat (int code, int parm1, int parm2); -int ttloop (void); -int stilloob (int s); -void ptyflush (void); -char *nextitem (char *current); -void netclear (void); -void netflush (void); -void writenet (unsigned char *ptr, int len); -void fatal (int f, char *msg); -void fatalperror (int f, const char *msg); -void edithost (char *pat, char *host); -void putstr (char *s); -void putchr (int cc); -void putf (char *cp, char *where); -void printoption (char *fmt, int option); -void printsub (int direction, unsigned char *pointer, int length); -void printdata (char *tag, char *ptr, int cnt); -int login_tty(int t); - -#ifdef ENCRYPTION -extern void (*encrypt_output) (unsigned char *, int); -extern int (*decrypt_input) (int); -extern char *nclearto; -#endif - - -/* - * The following are some clocks used to decide how to interpret - * the relationship between various variables. - */ - -struct clocks_t{ - int - system, /* what the current time is */ - echotoggle, /* last time user entered echo character */ - modenegotiated, /* last time operating mode negotiated */ - didnetreceive, /* last time we read data from network */ - ttypesubopt, /* ttype subopt is received */ - tspeedsubopt, /* tspeed subopt is received */ - environsubopt, /* environ subopt is received */ - oenvironsubopt, /* old environ subopt is received */ - xdisplocsubopt, /* xdisploc subopt is received */ - baseline, /* time started to do timed action */ - gotDM; /* when did we last see a data mark */ -}; -extern struct clocks_t clocks; - -extern int log_unauth; -extern int no_warn; - -#ifdef STREAMSPTY -extern int really_stream; -#endif - -#ifndef USE_IM -# ifdef CRAY -# define USE_IM "Cray UNICOS (%h) (%t)" -# endif -# ifdef _AIX -# define USE_IM "%s %v.%r (%h) (%t)" -# endif -# ifndef USE_IM -# define USE_IM "%s %r (%h) (%t)" -# endif -#endif - -#define DEFAULT_IM "\r\n\r\n" USE_IM "\r\n\r\n\r\n" - -#endif /* __EXT_H__ */ diff --git a/crypto/kerberosIV/appl/telnet/telnetd/global.c b/crypto/kerberosIV/appl/telnet/telnetd/global.c deleted file mode 100644 index 275cb45..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/global.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* a *lot* of ugly global definitions that really should be removed... - */ - -#include "telnetd.h" - -RCSID("$Id: global.c,v 1.12 1997/05/11 06:29:59 assar Exp $"); - -/* - * Telnet server variable declarations - */ -char options[256]; -char do_dont_resp[256]; -char will_wont_resp[256]; -int linemode; /* linemode on/off */ -int flowmode; /* current flow control state */ -int restartany; /* restart output on any character state */ -#ifdef DIAGNOSTICS -int diagnostic; /* telnet diagnostic capabilities */ -#endif /* DIAGNOSTICS */ -int require_otp; - -slcfun slctab[NSLC + 1]; /* slc mapping table */ - -char *terminaltype; - -/* - * I/O data buffers, pointers, and counters. - */ -char ptyobuf[BUFSIZ+NETSLOP], *pfrontp, *pbackp; - -char netibuf[BUFSIZ], *netip; - -char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp; -char *neturg; /* one past last bye of urgent data */ - -int pcc, ncc; - -int ourpty, net; -int SYNCHing; /* we are in TELNET SYNCH mode */ - -/* - * The following are some clocks used to decide how to interpret - * the relationship between various variables. - */ - -struct clocks_t clocks; - - -/* whether to log unauthenticated login attempts */ -int log_unauth; - -/* do not print warning if connection is not encrypted */ -int no_warn; - -/* - * This function appends data to nfrontp and advances nfrontp. - */ - -int -output_data (const char *format, ...) -{ - va_list args; - size_t remaining, ret; - - va_start(args, format); - remaining = BUFSIZ - (nfrontp - netobuf); - ret = vsnprintf (nfrontp, - remaining, - format, - args); - nfrontp += ret; - va_end(args); - return ret; -} diff --git a/crypto/kerberosIV/appl/telnet/telnetd/slc.c b/crypto/kerberosIV/appl/telnet/telnetd/slc.c deleted file mode 100644 index 799d2d8..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/slc.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "telnetd.h" - -RCSID("$Id: slc.c,v 1.10 1997/05/11 06:30:00 assar Exp $"); - -/* - * get_slc_defaults - * - * Initialize the slc mapping table. - */ -void -get_slc_defaults(void) -{ - int i; - - init_termbuf(); - - for (i = 1; i <= NSLC; i++) { - slctab[i].defset.flag = - spcset(i, &slctab[i].defset.val, &slctab[i].sptr); - slctab[i].current.flag = SLC_NOSUPPORT; - slctab[i].current.val = 0; - } - -} diff --git a/crypto/kerberosIV/appl/telnet/telnetd/state.c b/crypto/kerberosIV/appl/telnet/telnetd/state.c deleted file mode 100644 index 80b90ea..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/state.c +++ /dev/null @@ -1,1356 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "telnetd.h" - -RCSID("$Id: state.c,v 1.13 1999/05/13 23:12:50 assar Exp $"); - -unsigned char doopt[] = { IAC, DO, '%', 'c', 0 }; -unsigned char dont[] = { IAC, DONT, '%', 'c', 0 }; -unsigned char will[] = { IAC, WILL, '%', 'c', 0 }; -unsigned char wont[] = { IAC, WONT, '%', 'c', 0 }; -int not42 = 1; - -/* - * Buffer for sub-options, and macros - * for suboptions buffer manipulations - */ -unsigned char subbuffer[2048], *subpointer= subbuffer, *subend= subbuffer; - -#define SB_CLEAR() subpointer = subbuffer -#define SB_TERM() { subend = subpointer; SB_CLEAR(); } -#define SB_ACCUM(c) if (subpointer < (subbuffer+sizeof subbuffer)) { \ - *subpointer++ = (c); \ - } -#define SB_GET() ((*subpointer++)&0xff) -#define SB_EOF() (subpointer >= subend) -#define SB_LEN() (subend - subpointer) - -#ifdef ENV_HACK -unsigned char *subsave; -#define SB_SAVE() subsave = subpointer; -#define SB_RESTORE() subpointer = subsave; -#endif - - -/* - * State for recv fsm - */ -#define TS_DATA 0 /* base state */ -#define TS_IAC 1 /* look for double IAC's */ -#define TS_CR 2 /* CR-LF ->'s CR */ -#define TS_SB 3 /* throw away begin's... */ -#define TS_SE 4 /* ...end's (suboption negotiation) */ -#define TS_WILL 5 /* will option negotiation */ -#define TS_WONT 6 /* wont -''- */ -#define TS_DO 7 /* do -''- */ -#define TS_DONT 8 /* dont -''- */ - -void -telrcv(void) -{ - int c; - static int state = TS_DATA; - - while (ncc > 0) { - if ((&ptyobuf[BUFSIZ] - pfrontp) < 2) - break; - c = *netip++ & 0377, ncc--; -#ifdef ENCRYPTION - if (decrypt_input) - c = (*decrypt_input)(c); -#endif - switch (state) { - - case TS_CR: - state = TS_DATA; - /* Strip off \n or \0 after a \r */ - if ((c == 0) || (c == '\n')) { - break; - } - /* FALL THROUGH */ - - case TS_DATA: - if (c == IAC) { - state = TS_IAC; - break; - } - /* - * We now map \r\n ==> \r for pragmatic reasons. - * Many client implementations send \r\n when - * the user hits the CarriageReturn key. - * - * We USED to map \r\n ==> \n, since \r\n says - * that we want to be in column 1 of the next - * printable line, and \n is the standard - * unix way of saying that (\r is only good - * if CRMOD is set, which it normally is). - */ - if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) { - int nc = *netip; -#ifdef ENCRYPTION - if (decrypt_input) - nc = (*decrypt_input)(nc & 0xff); -#endif - { -#ifdef ENCRYPTION - if (decrypt_input) - (void)(*decrypt_input)(-1); -#endif - state = TS_CR; - } - } - *pfrontp++ = c; - break; - - case TS_IAC: - gotiac: switch (c) { - - /* - * Send the process on the pty side an - * interrupt. Do this with a NULL or - * interrupt char; depending on the tty mode. - */ - case IP: - DIAG(TD_OPTIONS, - printoption("td: recv IAC", c)); - interrupt(); - break; - - case BREAK: - DIAG(TD_OPTIONS, - printoption("td: recv IAC", c)); - sendbrk(); - break; - - /* - * Are You There? - */ - case AYT: - DIAG(TD_OPTIONS, - printoption("td: recv IAC", c)); - recv_ayt(); - break; - - /* - * Abort Output - */ - case AO: - { - DIAG(TD_OPTIONS, - printoption("td: recv IAC", c)); - ptyflush(); /* half-hearted */ - init_termbuf(); - - if (slctab[SLC_AO].sptr && - *slctab[SLC_AO].sptr != (cc_t)(_POSIX_VDISABLE)) { - *pfrontp++ = - (unsigned char)*slctab[SLC_AO].sptr; - } - - netclear(); /* clear buffer back */ - output_data ("%c%c", IAC, DM); - neturg = nfrontp-1; /* off by one XXX */ - DIAG(TD_OPTIONS, - printoption("td: send IAC", DM)); - break; - } - - /* - * Erase Character and - * Erase Line - */ - case EC: - case EL: - { - cc_t ch; - - DIAG(TD_OPTIONS, - printoption("td: recv IAC", c)); - ptyflush(); /* half-hearted */ - init_termbuf(); - if (c == EC) - ch = *slctab[SLC_EC].sptr; - else - ch = *slctab[SLC_EL].sptr; - if (ch != (cc_t)(_POSIX_VDISABLE)) - *pfrontp++ = (unsigned char)ch; - break; - } - - /* - * Check for urgent data... - */ - case DM: - DIAG(TD_OPTIONS, - printoption("td: recv IAC", c)); - SYNCHing = stilloob(net); - settimer(gotDM); - break; - - - /* - * Begin option subnegotiation... - */ - case SB: - state = TS_SB; - SB_CLEAR(); - continue; - - case WILL: - state = TS_WILL; - continue; - - case WONT: - state = TS_WONT; - continue; - - case DO: - state = TS_DO; - continue; - - case DONT: - state = TS_DONT; - continue; - case EOR: - if (his_state_is_will(TELOPT_EOR)) - doeof(); - break; - - /* - * Handle RFC 10xx Telnet linemode option additions - * to command stream (EOF, SUSP, ABORT). - */ - case xEOF: - doeof(); - break; - - case SUSP: - sendsusp(); - break; - - case ABORT: - sendbrk(); - break; - - case IAC: - *pfrontp++ = c; - break; - } - state = TS_DATA; - break; - - case TS_SB: - if (c == IAC) { - state = TS_SE; - } else { - SB_ACCUM(c); - } - break; - - case TS_SE: - if (c != SE) { - if (c != IAC) { - /* - * bad form of suboption negotiation. - * handle it in such a way as to avoid - * damage to local state. Parse - * suboption buffer found so far, - * then treat remaining stream as - * another command sequence. - */ - - /* for DIAGNOSTICS */ - SB_ACCUM(IAC); - SB_ACCUM(c); - subpointer -= 2; - - SB_TERM(); - suboption(); - state = TS_IAC; - goto gotiac; - } - SB_ACCUM(c); - state = TS_SB; - } else { - /* for DIAGNOSTICS */ - SB_ACCUM(IAC); - SB_ACCUM(SE); - subpointer -= 2; - - SB_TERM(); - suboption(); /* handle sub-option */ - state = TS_DATA; - } - break; - - case TS_WILL: - willoption(c); - state = TS_DATA; - continue; - - case TS_WONT: - wontoption(c); - if (c==TELOPT_ENCRYPT && his_do_dont_is_changing(TELOPT_ENCRYPT) ) - dontoption(c); - state = TS_DATA; - continue; - - case TS_DO: - dooption(c); - state = TS_DATA; - continue; - - case TS_DONT: - dontoption(c); - state = TS_DATA; - continue; - - default: - syslog(LOG_ERR, "telnetd: panic state=%d\n", state); - printf("telnetd: panic state=%d\n", state); - exit(1); - } - } -} /* end of telrcv */ - -/* - * The will/wont/do/dont state machines are based on Dave Borman's - * Telnet option processing state machine. - * - * These correspond to the following states: - * my_state = the last negotiated state - * want_state = what I want the state to go to - * want_resp = how many requests I have sent - * All state defaults are negative, and resp defaults to 0. - * - * When initiating a request to change state to new_state: - * - * if ((want_resp == 0 && new_state == my_state) || want_state == new_state) { - * do nothing; - * } else { - * want_state = new_state; - * send new_state; - * want_resp++; - * } - * - * When receiving new_state: - * - * if (want_resp) { - * want_resp--; - * if (want_resp && (new_state == my_state)) - * want_resp--; - * } - * if ((want_resp == 0) && (new_state != want_state)) { - * if (ok_to_switch_to new_state) - * want_state = new_state; - * else - * want_resp++; - * send want_state; - * } - * my_state = new_state; - * - * Note that new_state is implied in these functions by the function itself. - * will and do imply positive new_state, wont and dont imply negative. - * - * Finally, there is one catch. If we send a negative response to a - * positive request, my_state will be the positive while want_state will - * remain negative. my_state will revert to negative when the negative - * acknowlegment arrives from the peer. Thus, my_state generally tells - * us not only the last negotiated state, but also tells us what the peer - * wants to be doing as well. It is important to understand this difference - * as we may wish to be processing data streams based on our desired state - * (want_state) or based on what the peer thinks the state is (my_state). - * - * This all works fine because if the peer sends a positive request, the data - * that we receive prior to negative acknowlegment will probably be affected - * by the positive state, and we can process it as such (if we can; if we - * can't then it really doesn't matter). If it is that important, then the - * peer probably should be buffering until this option state negotiation - * is complete. - * - */ -void -send_do(int option, int init) -{ - if (init) { - if ((do_dont_resp[option] == 0 && his_state_is_will(option)) || - his_want_state_is_will(option)) - return; - /* - * Special case for TELOPT_TM: We send a DO, but pretend - * that we sent a DONT, so that we can send more DOs if - * we want to. - */ - if (option == TELOPT_TM) - set_his_want_state_wont(option); - else - set_his_want_state_will(option); - do_dont_resp[option]++; - } - output_data((const char *)doopt, option); - - DIAG(TD_OPTIONS, printoption("td: send do", option)); -} - -#ifdef AUTHENTICATION -extern void auth_request(void); -#endif -#ifdef ENCRYPTION -extern void encrypt_send_support(); -#endif - -void -willoption(int option) -{ - int changeok = 0; - void (*func)() = 0; - - /* - * process input from peer. - */ - - DIAG(TD_OPTIONS, printoption("td: recv will", option)); - - if (do_dont_resp[option]) { - do_dont_resp[option]--; - if (do_dont_resp[option] && his_state_is_will(option)) - do_dont_resp[option]--; - } - if (do_dont_resp[option] == 0) { - if (his_want_state_is_wont(option)) { - switch (option) { - - case TELOPT_BINARY: - init_termbuf(); - tty_binaryin(1); - set_termbuf(); - changeok++; - break; - - case TELOPT_ECHO: - /* - * See comments below for more info. - */ - not42 = 0; /* looks like a 4.2 system */ - break; - - case TELOPT_TM: - /* - * We never respond to a WILL TM, and - * we leave the state WONT. - */ - return; - - case TELOPT_LFLOW: - /* - * If we are going to support flow control - * option, then don't worry peer that we can't - * change the flow control characters. - */ - slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS; - slctab[SLC_XON].defset.flag |= SLC_DEFAULT; - slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS; - slctab[SLC_XOFF].defset.flag |= SLC_DEFAULT; - case TELOPT_TTYPE: - case TELOPT_SGA: - case TELOPT_NAWS: - case TELOPT_TSPEED: - case TELOPT_XDISPLOC: - case TELOPT_NEW_ENVIRON: - case TELOPT_OLD_ENVIRON: - changeok++; - break; - - -#ifdef AUTHENTICATION - case TELOPT_AUTHENTICATION: - func = auth_request; - changeok++; - break; -#endif - -#ifdef ENCRYPTION - case TELOPT_ENCRYPT: - func = encrypt_send_support; - changeok++; - break; -#endif - - default: - break; - } - if (changeok) { - set_his_want_state_will(option); - send_do(option, 0); - } else { - do_dont_resp[option]++; - send_dont(option, 0); - } - } else { - /* - * Option processing that should happen when - * we receive conformation of a change in - * state that we had requested. - */ - switch (option) { - case TELOPT_ECHO: - not42 = 0; /* looks like a 4.2 system */ - /* - * Egads, he responded "WILL ECHO". Turn - * it off right now! - */ - send_dont(option, 1); - /* - * "WILL ECHO". Kludge upon kludge! - * A 4.2 client is now echoing user input at - * the tty. This is probably undesireable and - * it should be stopped. The client will - * respond WONT TM to the DO TM that we send to - * check for kludge linemode. When the WONT TM - * arrives, linemode will be turned off and a - * change propogated to the pty. This change - * will cause us to process the new pty state - * in localstat(), which will notice that - * linemode is off and send a WILL ECHO - * so that we are properly in character mode and - * all is well. - */ - break; - -#ifdef AUTHENTICATION - case TELOPT_AUTHENTICATION: - func = auth_request; - break; -#endif - -#ifdef ENCRYPTION - case TELOPT_ENCRYPT: - func = encrypt_send_support; - break; -#endif - - case TELOPT_LFLOW: - func = flowstat; - break; - } - } - } - set_his_state_will(option); - if (func) - (*func)(); -} /* end of willoption */ - -void -send_dont(int option, int init) -{ - if (init) { - if ((do_dont_resp[option] == 0 && his_state_is_wont(option)) || - his_want_state_is_wont(option)) - return; - set_his_want_state_wont(option); - do_dont_resp[option]++; - } - output_data((const char *)dont, option); - - DIAG(TD_OPTIONS, printoption("td: send dont", option)); -} - -void -wontoption(int option) -{ - /* - * Process client input. - */ - - DIAG(TD_OPTIONS, printoption("td: recv wont", option)); - - if (do_dont_resp[option]) { - do_dont_resp[option]--; - if (do_dont_resp[option] && his_state_is_wont(option)) - do_dont_resp[option]--; - } - if (do_dont_resp[option] == 0) { - if (his_want_state_is_will(option)) { - /* it is always ok to change to negative state */ - switch (option) { - case TELOPT_ECHO: - not42 = 1; /* doesn't seem to be a 4.2 system */ - break; - - case TELOPT_BINARY: - init_termbuf(); - tty_binaryin(0); - set_termbuf(); - break; - - case TELOPT_TM: - /* - * If we get a WONT TM, and had sent a DO TM, - * don't respond with a DONT TM, just leave it - * as is. Short circut the state machine to - * achive this. - */ - set_his_want_state_wont(TELOPT_TM); - return; - - case TELOPT_LFLOW: - /* - * If we are not going to support flow control - * option, then let peer know that we can't - * change the flow control characters. - */ - slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS; - slctab[SLC_XON].defset.flag |= SLC_CANTCHANGE; - slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS; - slctab[SLC_XOFF].defset.flag |= SLC_CANTCHANGE; - break; - -#ifdef AUTHENTICATION - case TELOPT_AUTHENTICATION: - auth_finished(0, AUTH_REJECT); - break; -#endif - - /* - * For options that we might spin waiting for - * sub-negotiation, if the client turns off the - * option rather than responding to the request, - * we have to treat it here as if we got a response - * to the sub-negotiation, (by updating the timers) - * so that we'll break out of the loop. - */ - case TELOPT_TTYPE: - settimer(ttypesubopt); - break; - - case TELOPT_TSPEED: - settimer(tspeedsubopt); - break; - - case TELOPT_XDISPLOC: - settimer(xdisplocsubopt); - break; - - case TELOPT_OLD_ENVIRON: - settimer(oenvironsubopt); - break; - - case TELOPT_NEW_ENVIRON: - settimer(environsubopt); - break; - - default: - break; - } - set_his_want_state_wont(option); - if (his_state_is_will(option)) - send_dont(option, 0); - } else { - switch (option) { - case TELOPT_TM: - break; - -#ifdef AUTHENTICATION - case TELOPT_AUTHENTICATION: - auth_finished(0, AUTH_REJECT); - break; -#endif - default: - break; - } - } - } - set_his_state_wont(option); - -} /* end of wontoption */ - -void -send_will(int option, int init) -{ - if (init) { - if ((will_wont_resp[option] == 0 && my_state_is_will(option))|| - my_want_state_is_will(option)) - return; - set_my_want_state_will(option); - will_wont_resp[option]++; - } - output_data ((const char *)will, option); - - DIAG(TD_OPTIONS, printoption("td: send will", option)); -} - -/* - * When we get a DONT SGA, we will try once to turn it - * back on. If the other side responds DONT SGA, we - * leave it at that. This is so that when we talk to - * clients that understand KLUDGELINEMODE but not LINEMODE, - * we'll keep them in char-at-a-time mode. - */ -int turn_on_sga = 0; - -void -dooption(int option) -{ - int changeok = 0; - - /* - * Process client input. - */ - - DIAG(TD_OPTIONS, printoption("td: recv do", option)); - - if (will_wont_resp[option]) { - will_wont_resp[option]--; - if (will_wont_resp[option] && my_state_is_will(option)) - will_wont_resp[option]--; - } - if ((will_wont_resp[option] == 0) && (my_want_state_is_wont(option))) { - switch (option) { - case TELOPT_ECHO: - { - init_termbuf(); - tty_setecho(1); - set_termbuf(); - } - changeok++; - break; - - case TELOPT_BINARY: - init_termbuf(); - tty_binaryout(1); - set_termbuf(); - changeok++; - break; - - case TELOPT_SGA: - turn_on_sga = 0; - changeok++; - break; - - case TELOPT_STATUS: - changeok++; - break; - - case TELOPT_TM: - /* - * Special case for TM. We send a WILL, but - * pretend we sent a WONT. - */ - send_will(option, 0); - set_my_want_state_wont(option); - set_my_state_wont(option); - return; - - case TELOPT_LOGOUT: - /* - * When we get a LOGOUT option, respond - * with a WILL LOGOUT, make sure that - * it gets written out to the network, - * and then just go away... - */ - set_my_want_state_will(TELOPT_LOGOUT); - send_will(TELOPT_LOGOUT, 0); - set_my_state_will(TELOPT_LOGOUT); - netflush(); - cleanup(0); - /* NOT REACHED */ - break; - -#ifdef ENCRYPTION - case TELOPT_ENCRYPT: - changeok++; - break; -#endif - case TELOPT_LINEMODE: - case TELOPT_TTYPE: - case TELOPT_NAWS: - case TELOPT_TSPEED: - case TELOPT_LFLOW: - case TELOPT_XDISPLOC: -#ifdef TELOPT_ENVIRON - case TELOPT_NEW_ENVIRON: -#endif - case TELOPT_OLD_ENVIRON: - default: - break; - } - if (changeok) { - set_my_want_state_will(option); - send_will(option, 0); - } else { - will_wont_resp[option]++; - send_wont(option, 0); - } - } - set_my_state_will(option); - -} /* end of dooption */ - -void -send_wont(int option, int init) -{ - if (init) { - if ((will_wont_resp[option] == 0 && my_state_is_wont(option)) || - my_want_state_is_wont(option)) - return; - set_my_want_state_wont(option); - will_wont_resp[option]++; - } - output_data ((const char *)wont, option); - - DIAG(TD_OPTIONS, printoption("td: send wont", option)); -} - -void -dontoption(int option) -{ - /* - * Process client input. - */ - - - DIAG(TD_OPTIONS, printoption("td: recv dont", option)); - - if (will_wont_resp[option]) { - will_wont_resp[option]--; - if (will_wont_resp[option] && my_state_is_wont(option)) - will_wont_resp[option]--; - } - if ((will_wont_resp[option] == 0) && (my_want_state_is_will(option))) { - switch (option) { - case TELOPT_BINARY: - init_termbuf(); - tty_binaryout(0); - set_termbuf(); - break; - - case TELOPT_ECHO: /* we should stop echoing */ - { - init_termbuf(); - tty_setecho(0); - set_termbuf(); - } - break; - - case TELOPT_SGA: - set_my_want_state_wont(option); - if (my_state_is_will(option)) - send_wont(option, 0); - set_my_state_wont(option); - if (turn_on_sga ^= 1) - send_will(option, 1); - return; - - default: - break; - } - - set_my_want_state_wont(option); - if (my_state_is_will(option)) - send_wont(option, 0); - } - set_my_state_wont(option); - -} /* end of dontoption */ - -#ifdef ENV_HACK -int env_ovar = -1; -int env_ovalue = -1; -#else /* ENV_HACK */ -# define env_ovar OLD_ENV_VAR -# define env_ovalue OLD_ENV_VALUE -#endif /* ENV_HACK */ - -/* - * suboption() - * - * Look at the sub-option buffer, and try to be helpful to the other - * side. - * - * Currently we recognize: - * - * Terminal type is - * Linemode - * Window size - * Terminal speed - */ -void -suboption(void) -{ - int subchar; - - DIAG(TD_OPTIONS, {netflush(); printsub('<', subpointer, SB_LEN()+2);}); - - subchar = SB_GET(); - switch (subchar) { - case TELOPT_TSPEED: { - int xspeed, rspeed; - - if (his_state_is_wont(TELOPT_TSPEED)) /* Ignore if option disabled */ - break; - - settimer(tspeedsubopt); - - if (SB_EOF() || SB_GET() != TELQUAL_IS) - return; - - xspeed = atoi((char *)subpointer); - - while (SB_GET() != ',' && !SB_EOF()); - if (SB_EOF()) - return; - - rspeed = atoi((char *)subpointer); - clientstat(TELOPT_TSPEED, xspeed, rspeed); - - break; - - } /* end of case TELOPT_TSPEED */ - - case TELOPT_TTYPE: { /* Yaaaay! */ - static char terminalname[41]; - - if (his_state_is_wont(TELOPT_TTYPE)) /* Ignore if option disabled */ - break; - settimer(ttypesubopt); - - if (SB_EOF() || SB_GET() != TELQUAL_IS) { - return; /* ??? XXX but, this is the most robust */ - } - - terminaltype = terminalname; - - while ((terminaltype < (terminalname + sizeof terminalname-1)) && - !SB_EOF()) { - int c; - - c = SB_GET(); - if (isupper(c)) { - c = tolower(c); - } - *terminaltype++ = c; /* accumulate name */ - } - *terminaltype = 0; - terminaltype = terminalname; - break; - } /* end of case TELOPT_TTYPE */ - - case TELOPT_NAWS: { - int xwinsize, ywinsize; - - if (his_state_is_wont(TELOPT_NAWS)) /* Ignore if option disabled */ - break; - - if (SB_EOF()) - return; - xwinsize = SB_GET() << 8; - if (SB_EOF()) - return; - xwinsize |= SB_GET(); - if (SB_EOF()) - return; - ywinsize = SB_GET() << 8; - if (SB_EOF()) - return; - ywinsize |= SB_GET(); - clientstat(TELOPT_NAWS, xwinsize, ywinsize); - - break; - - } /* end of case TELOPT_NAWS */ - - case TELOPT_STATUS: { - int mode; - - if (SB_EOF()) - break; - mode = SB_GET(); - switch (mode) { - case TELQUAL_SEND: - if (my_state_is_will(TELOPT_STATUS)) - send_status(); - break; - - case TELQUAL_IS: - break; - - default: - break; - } - break; - } /* end of case TELOPT_STATUS */ - - case TELOPT_XDISPLOC: { - if (SB_EOF() || SB_GET() != TELQUAL_IS) - return; - settimer(xdisplocsubopt); - subpointer[SB_LEN()] = '\0'; - setenv("DISPLAY", (char *)subpointer, 1); - break; - } /* end of case TELOPT_XDISPLOC */ - -#ifdef TELOPT_NEW_ENVIRON - case TELOPT_NEW_ENVIRON: -#endif - case TELOPT_OLD_ENVIRON: { - int c; - char *cp, *varp, *valp; - - if (SB_EOF()) - return; - c = SB_GET(); - if (c == TELQUAL_IS) { - if (subchar == TELOPT_OLD_ENVIRON) - settimer(oenvironsubopt); - else - settimer(environsubopt); - } else if (c != TELQUAL_INFO) { - return; - } - -#ifdef TELOPT_NEW_ENVIRON - if (subchar == TELOPT_NEW_ENVIRON) { - while (!SB_EOF()) { - c = SB_GET(); - if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR)) - break; - } - } else -#endif - { -#ifdef ENV_HACK - /* - * We only want to do this if we haven't already decided - * whether or not the other side has its VALUE and VAR - * reversed. - */ - if (env_ovar < 0) { - int last = -1; /* invalid value */ - int empty = 0; - int got_var = 0, got_value = 0, got_uservar = 0; - - /* - * The other side might have its VALUE and VAR values - * reversed. To be interoperable, we need to determine - * which way it is. If the first recognized character - * is a VAR or VALUE, then that will tell us what - * type of client it is. If the fist recognized - * character is a USERVAR, then we continue scanning - * the suboption looking for two consecutive - * VAR or VALUE fields. We should not get two - * consecutive VALUE fields, so finding two - * consecutive VALUE or VAR fields will tell us - * what the client is. - */ - SB_SAVE(); - while (!SB_EOF()) { - c = SB_GET(); - switch(c) { - case OLD_ENV_VAR: - if (last < 0 || last == OLD_ENV_VAR - || (empty && (last == OLD_ENV_VALUE))) - goto env_ovar_ok; - got_var++; - last = OLD_ENV_VAR; - break; - case OLD_ENV_VALUE: - if (last < 0 || last == OLD_ENV_VALUE - || (empty && (last == OLD_ENV_VAR))) - goto env_ovar_wrong; - got_value++; - last = OLD_ENV_VALUE; - break; - case ENV_USERVAR: - /* count strings of USERVAR as one */ - if (last != ENV_USERVAR) - got_uservar++; - if (empty) { - if (last == OLD_ENV_VALUE) - goto env_ovar_ok; - if (last == OLD_ENV_VAR) - goto env_ovar_wrong; - } - last = ENV_USERVAR; - break; - case ENV_ESC: - if (!SB_EOF()) - c = SB_GET(); - /* FALL THROUGH */ - default: - empty = 0; - continue; - } - empty = 1; - } - if (empty) { - if (last == OLD_ENV_VALUE) - goto env_ovar_ok; - if (last == OLD_ENV_VAR) - goto env_ovar_wrong; - } - /* - * Ok, the first thing was a USERVAR, and there - * are not two consecutive VAR or VALUE commands, - * and none of the VAR or VALUE commands are empty. - * If the client has sent us a well-formed option, - * then the number of VALUEs received should always - * be less than or equal to the number of VARs and - * USERVARs received. - * - * If we got exactly as many VALUEs as VARs and - * USERVARs, the client has the same definitions. - * - * If we got exactly as many VARs as VALUEs and - * USERVARS, the client has reversed definitions. - */ - if (got_uservar + got_var == got_value) { - env_ovar_ok: - env_ovar = OLD_ENV_VAR; - env_ovalue = OLD_ENV_VALUE; - } else if (got_uservar + got_value == got_var) { - env_ovar_wrong: - env_ovar = OLD_ENV_VALUE; - env_ovalue = OLD_ENV_VAR; - DIAG(TD_OPTIONS, { - output_data("ENVIRON VALUE and VAR are reversed!\r\n"); - }); - - } - } - SB_RESTORE(); -#endif - - while (!SB_EOF()) { - c = SB_GET(); - if ((c == env_ovar) || (c == ENV_USERVAR)) - break; - } - } - - if (SB_EOF()) - return; - - cp = varp = (char *)subpointer; - valp = 0; - - while (!SB_EOF()) { - c = SB_GET(); - if (subchar == TELOPT_OLD_ENVIRON) { - if (c == env_ovar) - c = NEW_ENV_VAR; - else if (c == env_ovalue) - c = NEW_ENV_VALUE; - } - switch (c) { - - case NEW_ENV_VALUE: - *cp = '\0'; - cp = valp = (char *)subpointer; - break; - - case NEW_ENV_VAR: - case ENV_USERVAR: - *cp = '\0'; - if (valp) - setenv(varp, valp, 1); - else - unsetenv(varp); - cp = varp = (char *)subpointer; - valp = 0; - break; - - case ENV_ESC: - if (SB_EOF()) - break; - c = SB_GET(); - /* FALL THROUGH */ - default: - *cp++ = c; - break; - } - } - *cp = '\0'; - if (valp) - setenv(varp, valp, 1); - else - unsetenv(varp); - break; - } /* end of case TELOPT_NEW_ENVIRON */ -#ifdef 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 -#ifdef ENCRYPTION - case TELOPT_ENCRYPT: - if (SB_EOF()) - break; - switch(SB_GET()) { - case ENCRYPT_SUPPORT: - encrypt_support(subpointer, SB_LEN()); - break; - case ENCRYPT_IS: - encrypt_is(subpointer, SB_LEN()); - break; - case ENCRYPT_REPLY: - encrypt_reply(subpointer, SB_LEN()); - break; - case ENCRYPT_START: - encrypt_start(subpointer, SB_LEN()); - break; - case ENCRYPT_END: - encrypt_end(); - break; - case ENCRYPT_REQSTART: - encrypt_request_start(subpointer, SB_LEN()); - break; - case ENCRYPT_REQEND: - /* - * We can always send an REQEND so that we cannot - * get stuck encrypting. We should only get this - * if we have been able to get in the correct mode - * anyhow. - */ - encrypt_request_end(); - break; - case ENCRYPT_ENC_KEYID: - encrypt_enc_keyid(subpointer, SB_LEN()); - break; - case ENCRYPT_DEC_KEYID: - encrypt_dec_keyid(subpointer, SB_LEN()); - break; - default: - break; - } - break; -#endif - - default: - break; - } /* end of switch */ - -} /* end of suboption */ - -void -doclientstat(void) -{ - clientstat(TELOPT_LINEMODE, WILL, 0); -} - -#define ADD(c) *ncp++ = c -#define ADD_DATA(c) { *ncp++ = c; if (c == SE || c == IAC) *ncp++ = c; } - -void -send_status(void) -{ - unsigned char statusbuf[256]; - unsigned char *ncp; - unsigned char i; - - ncp = statusbuf; - - netflush(); /* get rid of anything waiting to go out */ - - ADD(IAC); - ADD(SB); - ADD(TELOPT_STATUS); - ADD(TELQUAL_IS); - - /* - * We check the want_state rather than the current state, - * because if we received a DO/WILL for an option that we - * don't support, and the other side didn't send a DONT/WONT - * in response to our WONT/DONT, then the "state" will be - * WILL/DO, and the "want_state" will be WONT/DONT. We - * need to go by the latter. - */ - for (i = 0; i < (unsigned char)NTELOPTS; i++) { - if (my_want_state_is_will(i)) { - ADD(WILL); - ADD_DATA(i); - } - if (his_want_state_is_will(i)) { - ADD(DO); - ADD_DATA(i); - } - } - - if (his_want_state_is_will(TELOPT_LFLOW)) { - ADD(SB); - ADD(TELOPT_LFLOW); - if (flowmode) { - ADD(LFLOW_ON); - } else { - ADD(LFLOW_OFF); - } - ADD(SE); - - if (restartany >= 0) { - ADD(SB); - ADD(TELOPT_LFLOW); - if (restartany) { - ADD(LFLOW_RESTART_ANY); - } else { - ADD(LFLOW_RESTART_XON); - } - ADD(SE); - } - } - - - ADD(IAC); - ADD(SE); - - writenet(statusbuf, ncp - statusbuf); - netflush(); /* Send it on its way */ - - DIAG(TD_OPTIONS, - {printsub('>', statusbuf, ncp - statusbuf); netflush();}); -} diff --git a/crypto/kerberosIV/appl/telnet/telnetd/sys_term.c b/crypto/kerberosIV/appl/telnet/telnetd/sys_term.c deleted file mode 100644 index 2477c42..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/sys_term.c +++ /dev/null @@ -1,1893 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "telnetd.h" - -RCSID("$Id: sys_term.c,v 1.89.2.6 2000/12/08 23:34:05 assar Exp $"); - -#if defined(_CRAY) || (defined(__hpux) && !defined(HAVE_UTMPX_H)) -# define PARENT_DOES_UTMP -#endif - -#ifdef HAVE_UTMP_H -#include <utmp.h> -#endif - -#ifdef HAVE_UTMPX_H -#include <utmpx.h> -#endif - -#ifdef HAVE_UTMPX_H -struct utmpx wtmp; -#elif defined(HAVE_UTMP_H) -struct utmp wtmp; -#endif /* HAVE_UTMPX_H */ - -#ifdef HAVE_STRUCT_UTMP_UT_HOST -int utmp_len = sizeof(wtmp.ut_host); -#else -int utmp_len = MaxHostNameLen; -#endif - -#ifndef UTMP_FILE -#ifdef _PATH_UTMP -#define UTMP_FILE _PATH_UTMP -#else -#define UTMP_FILE "/etc/utmp" -#endif -#endif - -#if !defined(WTMP_FILE) && defined(_PATH_WTMP) -#define WTMP_FILE _PATH_WTMP -#endif - -#ifndef PARENT_DOES_UTMP -#ifdef WTMP_FILE -char wtmpf[] = WTMP_FILE; -#else -char wtmpf[] = "/usr/adm/wtmp"; -#endif -char utmpf[] = UTMP_FILE; -#else /* PARENT_DOES_UTMP */ -#ifdef WTMP_FILE -char wtmpf[] = WTMP_FILE; -#else -char wtmpf[] = "/etc/wtmp"; -#endif -#endif /* PARENT_DOES_UTMP */ - -#ifdef HAVE_TMPDIR_H -#include <tmpdir.h> -#endif /* CRAY */ - -#ifdef STREAMSPTY - -#ifdef HAVE_SAC_H -#include <sac.h> -#endif - -#ifdef HAVE_SYS_STROPTS_H -#include <sys/stropts.h> -#endif - -#endif /* STREAMSPTY */ - -#ifdef HAVE_SYS_STREAM_H -#ifdef HAVE_SYS_UIO_H -#include <sys/uio.h> -#endif -#ifdef __hpux -#undef SE -#endif -#include <sys/stream.h> -#endif -#if !(defined(__sgi) || defined(__linux) || defined(_AIX)) && defined(HAVE_SYS_TTY) -#include <sys/tty.h> -#endif -#ifdef t_erase -#undef t_erase -#undef t_kill -#undef t_intrc -#undef t_quitc -#undef t_startc -#undef t_stopc -#undef t_eofc -#undef t_brkc -#undef t_suspc -#undef t_dsuspc -#undef t_rprntc -#undef t_flushc -#undef t_werasc -#undef t_lnextc -#endif - -#ifdef HAVE_TERMIOS_H -#include <termios.h> -#else -#ifdef HAVE_TERMIO_H -#include <termio.h> -#endif -#endif - -#ifdef HAVE_UTIL_H -#include <util.h> -#endif - -# ifndef TCSANOW -# ifdef TCSETS -# define TCSANOW TCSETS -# define TCSADRAIN TCSETSW -# define tcgetattr(f, t) ioctl(f, TCGETS, (char *)t) -# else -# ifdef TCSETA -# define TCSANOW TCSETA -# define TCSADRAIN TCSETAW -# define tcgetattr(f, t) ioctl(f, TCGETA, (char *)t) -# else -# define TCSANOW TIOCSETA -# define TCSADRAIN TIOCSETAW -# define tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t) -# endif -# endif -# define tcsetattr(f, a, t) ioctl(f, a, t) -# define cfsetospeed(tp, val) (tp)->c_cflag &= ~CBAUD; \ -(tp)->c_cflag |= (val) -# define cfgetospeed(tp) ((tp)->c_cflag & CBAUD) -# ifdef CIBAUD -# define cfsetispeed(tp, val) (tp)->c_cflag &= ~CIBAUD; \ - (tp)->c_cflag |= ((val)<<IBSHIFT) -# define cfgetispeed(tp) (((tp)->c_cflag & CIBAUD)>>IBSHIFT) -# else -# define cfsetispeed(tp, val) (tp)->c_cflag &= ~CBAUD; \ - (tp)->c_cflag |= (val) -# define cfgetispeed(tp) ((tp)->c_cflag & CBAUD) -# endif -# endif /* TCSANOW */ - struct termios termbuf, termbuf2; /* pty control structure */ -# ifdef STREAMSPTY - static int ttyfd = -1; - int really_stream = 0; -# endif - - const char *new_login = _PATH_LOGIN; - -/* - * init_termbuf() - * copy_termbuf(cp) - * set_termbuf() - * - * These three routines are used to get and set the "termbuf" structure - * to and from the kernel. init_termbuf() gets the current settings. - * copy_termbuf() hands in a new "termbuf" to write to the kernel, and - * set_termbuf() writes the structure into the kernel. - */ - - void - init_termbuf(void) -{ -# ifdef STREAMSPTY - if (really_stream) - tcgetattr(ttyfd, &termbuf); - else -# endif - tcgetattr(ourpty, &termbuf); - termbuf2 = termbuf; -} - -void -set_termbuf(void) -{ - /* - * Only make the necessary changes. - */ - if (memcmp(&termbuf, &termbuf2, sizeof(termbuf))) -# ifdef STREAMSPTY - if (really_stream) - tcsetattr(ttyfd, TCSANOW, &termbuf); - else -# endif - tcsetattr(ourpty, TCSANOW, &termbuf); -} - - -/* - * spcset(func, valp, valpp) - * - * This function takes various special characters (func), and - * sets *valp to the current value of that character, and - * *valpp to point to where in the "termbuf" structure that - * value is kept. - * - * It returns the SLC_ level of support for this function. - */ - - -int -spcset(int func, cc_t *valp, cc_t **valpp) -{ - -#define setval(a, b) *valp = termbuf.c_cc[a]; \ - *valpp = &termbuf.c_cc[a]; \ - return(b); -#define defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT); - - switch(func) { - case SLC_EOF: - setval(VEOF, SLC_VARIABLE); - case SLC_EC: - setval(VERASE, SLC_VARIABLE); - case SLC_EL: - setval(VKILL, SLC_VARIABLE); - case SLC_IP: - setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT); - case SLC_ABORT: - setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT); - case SLC_XON: -#ifdef VSTART - setval(VSTART, SLC_VARIABLE); -#else - defval(0x13); -#endif - case SLC_XOFF: -#ifdef VSTOP - setval(VSTOP, SLC_VARIABLE); -#else - defval(0x11); -#endif - case SLC_EW: -#ifdef VWERASE - setval(VWERASE, SLC_VARIABLE); -#else - defval(0); -#endif - case SLC_RP: -#ifdef VREPRINT - setval(VREPRINT, SLC_VARIABLE); -#else - defval(0); -#endif - case SLC_LNEXT: -#ifdef VLNEXT - setval(VLNEXT, SLC_VARIABLE); -#else - defval(0); -#endif - case SLC_AO: -#if !defined(VDISCARD) && defined(VFLUSHO) -# define VDISCARD VFLUSHO -#endif -#ifdef VDISCARD - setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT); -#else - defval(0); -#endif - case SLC_SUSP: -#ifdef VSUSP - setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN); -#else - defval(0); -#endif -#ifdef VEOL - case SLC_FORW1: - setval(VEOL, SLC_VARIABLE); -#endif -#ifdef VEOL2 - case SLC_FORW2: - setval(VEOL2, SLC_VARIABLE); -#endif - case SLC_AYT: -#ifdef VSTATUS - setval(VSTATUS, SLC_VARIABLE); -#else - defval(0); -#endif - - case SLC_BRK: - case SLC_SYNCH: - case SLC_EOR: - defval(0); - - default: - *valp = 0; - *valpp = 0; - return(SLC_NOSUPPORT); - } -} - -#ifdef _CRAY -/* - * getnpty() - * - * Return the number of pty's configured into the system. - */ -int -getnpty() -{ -#ifdef _SC_CRAY_NPTY - int numptys; - - if ((numptys = sysconf(_SC_CRAY_NPTY)) != -1) - return numptys; - else -#endif /* _SC_CRAY_NPTY */ - return 128; -} -#endif /* CRAY */ - -/* - * getpty() - * - * Allocate a pty. As a side effect, the external character - * array "line" contains the name of the slave side. - * - * Returns the file descriptor of the opened pty. - */ - -static char Xline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -char *line = Xline; - -#ifdef _CRAY -char myline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -#endif /* CRAY */ - -#if !defined(HAVE_PTSNAME) && defined(STREAMSPTY) -static char *ptsname(int fd) -{ -#ifdef HAVE_TTYNAME - return ttyname(fd); -#else - return NULL; -#endif -} -#endif - -int getpty(int *ptynum) -{ -#ifdef __osf__ /* XXX */ - int master; - int slave; - if(openpty(&master, &slave, line, 0, 0) == 0){ - close(slave); - return master; - } - return -1; -#else -#ifdef HAVE__GETPTY - int master, slave; - char *p; - p = _getpty(&master, O_RDWR, 0600, 1); - if(p == NULL) - return -1; - strlcpy(line, p, sizeof(Xline)); - return master; -#else - - int p; - char *cp, *p1, *p2; - int i; -#if SunOS == 40 - int dummy; -#endif -#if 0 /* && defined(HAVE_OPENPTY) */ - int master; - int slave; - if(openpty(&master, &slave, line, 0, 0) == 0){ - close(slave); - return master; - } -#else -#ifdef STREAMSPTY - char *clone[] = { "/dev/ptc", "/dev/ptmx", "/dev/ptm", - "/dev/ptym/clone", 0 }; - - char **q; - for(q=clone; *q; q++){ - p=open(*q, O_RDWR); - if(p >= 0){ -#ifdef HAVE_GRANTPT - grantpt(p); -#endif -#ifdef HAVE_UNLOCKPT - unlockpt(p); -#endif - strlcpy(line, ptsname(p), sizeof(Xline)); - really_stream = 1; - return p; - } - } -#endif /* STREAMSPTY */ -#ifndef _CRAY - -#ifndef __hpux - snprintf(line, sizeof(Xline), "/dev/ptyXX"); - p1 = &line[8]; - p2 = &line[9]; -#else - snprintf(line, sizeof(Xline), "/dev/ptym/ptyXX"); - p1 = &line[13]; - p2 = &line[14]; -#endif - - - for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) { - struct stat stb; - - *p1 = *cp; - *p2 = '0'; - /* - * This stat() check is just to keep us from - * looping through all 256 combinations if there - * aren't that many ptys available. - */ - if (stat(line, &stb) < 0) - break; - for (i = 0; i < 16; i++) { - *p2 = "0123456789abcdef"[i]; - p = open(line, O_RDWR); - if (p > 0) { -#ifndef __hpux - line[5] = 't'; -#else - for (p1 = &line[8]; *p1; p1++) - *p1 = *(p1+1); - line[9] = 't'; -#endif - chown(line, 0, 0); - chmod(line, 0600); -#if SunOS == 40 - if (ioctl(p, TIOCGPGRP, &dummy) == 0 - || errno != EIO) { - chmod(line, 0666); - close(p); - line[5] = 'p'; - } else -#endif /* SunOS == 40 */ - return(p); - } - } - } -#else /* CRAY */ - extern lowpty, highpty; - struct stat sb; - - for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) { - snprintf(myline, sizeof(myline), "/dev/pty/%03d", *ptynum); - p = open(myline, 2); - if (p < 0) - continue; - snprintf(line, sizeof(Xline), "/dev/ttyp%03d", *ptynum); - /* - * Here are some shenanigans to make sure that there - * are no listeners lurking on the line. - */ - if(stat(line, &sb) < 0) { - close(p); - continue; - } - if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) { - chown(line, 0, 0); - chmod(line, 0600); - close(p); - p = open(myline, 2); - if (p < 0) - continue; - } - /* - * Now it should be safe...check for accessability. - */ - if (access(line, 6) == 0) - return(p); - else { - /* no tty side to pty so skip it */ - close(p); - } - } -#endif /* CRAY */ -#endif /* STREAMSPTY */ -#endif /* OPENPTY */ - return(-1); -#endif -} - - -int -tty_isecho(void) -{ - return (termbuf.c_lflag & ECHO); -} - -int -tty_flowmode(void) -{ - return((termbuf.c_iflag & IXON) ? 1 : 0); -} - -int -tty_restartany(void) -{ - return((termbuf.c_iflag & IXANY) ? 1 : 0); -} - -void -tty_setecho(int on) -{ - if (on) - termbuf.c_lflag |= ECHO; - else - termbuf.c_lflag &= ~ECHO; -} - -int -tty_israw(void) -{ - return(!(termbuf.c_lflag & ICANON)); -} - -void -tty_binaryin(int on) -{ - if (on) { - termbuf.c_iflag &= ~ISTRIP; - } else { - termbuf.c_iflag |= ISTRIP; - } -} - -void -tty_binaryout(int on) -{ - if (on) { - termbuf.c_cflag &= ~(CSIZE|PARENB); - termbuf.c_cflag |= CS8; - termbuf.c_oflag &= ~OPOST; - } else { - termbuf.c_cflag &= ~CSIZE; - termbuf.c_cflag |= CS7|PARENB; - termbuf.c_oflag |= OPOST; - } -} - -int -tty_isbinaryin(void) -{ - return(!(termbuf.c_iflag & ISTRIP)); -} - -int -tty_isbinaryout(void) -{ - return(!(termbuf.c_oflag&OPOST)); -} - - -int -tty_issofttab(void) -{ -# ifdef OXTABS - return (termbuf.c_oflag & OXTABS); -# endif -# ifdef TABDLY - return ((termbuf.c_oflag & TABDLY) == TAB3); -# endif -} - -void -tty_setsofttab(int on) -{ - if (on) { -# ifdef OXTABS - termbuf.c_oflag |= OXTABS; -# endif -# ifdef TABDLY - termbuf.c_oflag &= ~TABDLY; - termbuf.c_oflag |= TAB3; -# endif - } else { -# ifdef OXTABS - termbuf.c_oflag &= ~OXTABS; -# endif -# ifdef TABDLY - termbuf.c_oflag &= ~TABDLY; - termbuf.c_oflag |= TAB0; -# endif - } -} - -int -tty_islitecho(void) -{ -# ifdef ECHOCTL - return (!(termbuf.c_lflag & ECHOCTL)); -# endif -# ifdef TCTLECH - return (!(termbuf.c_lflag & TCTLECH)); -# endif -# if !defined(ECHOCTL) && !defined(TCTLECH) - return (0); /* assumes ctl chars are echoed '^x' */ -# endif -} - -void -tty_setlitecho(int on) -{ -# ifdef ECHOCTL - if (on) - termbuf.c_lflag &= ~ECHOCTL; - else - termbuf.c_lflag |= ECHOCTL; -# endif -# ifdef TCTLECH - if (on) - termbuf.c_lflag &= ~TCTLECH; - else - termbuf.c_lflag |= TCTLECH; -# endif -} - -int -tty_iscrnl(void) -{ - return (termbuf.c_iflag & ICRNL); -} - -/* - * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD). - */ -#if B4800 != 4800 -#define DECODE_BAUD -#endif - -#ifdef DECODE_BAUD - -/* - * A table of available terminal speeds - */ -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 }, -#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_BUAD */ - -void -tty_tspeed(int val) -{ -#ifdef DECODE_BAUD - struct termspeeds *tp; - - 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_BUAD */ - cfsetospeed(&termbuf, val); -#endif /* DECODE_BUAD */ -} - -void -tty_rspeed(int val) -{ -#ifdef DECODE_BAUD - struct termspeeds *tp; - - 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); -#endif /* DECODE_BAUD */ -} - -#ifdef PARENT_DOES_UTMP -extern struct utmp wtmp; -extern char wtmpf[]; - -extern void utmp_sig_init (void); -extern void utmp_sig_reset (void); -extern void utmp_sig_wait (void); -extern void utmp_sig_notify (int); -# endif /* PARENT_DOES_UTMP */ - -#ifdef STREAMSPTY - -/* I_FIND seems to live a life of its own */ -static int my_find(int fd, char *module) -{ -#if defined(I_FIND) && defined(I_LIST) - static int flag; - static struct str_list sl; - int n; - int i; - - if(!flag){ - n = ioctl(fd, I_LIST, 0); - if(n < 0){ - perror("ioctl(fd, I_LIST, 0)"); - return -1; - } - sl.sl_modlist=(struct str_mlist*)malloc(n * sizeof(struct str_mlist)); - sl.sl_nmods = n; - n = ioctl(fd, I_LIST, &sl); - if(n < 0){ - perror("ioctl(fd, I_LIST, n)"); - return -1; - } - flag = 1; - } - - for(i=0; i<sl.sl_nmods; i++) - if(!strcmp(sl.sl_modlist[i].l_name, module)) - return 1; -#endif - return 0; -} - -static void maybe_push_modules(int fd, char **modules) -{ - char **p; - int err; - - for(p=modules; *p; p++){ - err = my_find(fd, *p); - if(err == 1) - break; - if(err < 0 && errno != EINVAL) - fatalperror(net, "my_find()"); - /* module not pushed or does not exist */ - } - /* p points to null or to an already pushed module, now push all - modules before this one */ - - for(p--; p >= modules; p--){ - err = ioctl(fd, I_PUSH, *p); - if(err < 0 && errno != EINVAL) - fatalperror(net, "I_PUSH"); - } -} -#endif - -/* - * getptyslave() - * - * Open the slave side of the pty, and do any initialization - * that is necessary. The return value is a file descriptor - * for the slave side. - */ -void getptyslave(void) -{ - int t = -1; - - struct winsize ws; - extern int def_row, def_col; - extern int def_tspeed, def_rspeed; - /* - * Opening the slave side may cause initilization of the - * kernel tty structure. We need remember the state of - * if linemode was turned on - * terminal window size - * terminal speed - * so that we can re-set them if we need to. - */ - - - /* - * Make sure that we don't have a controlling tty, and - * that we are the session (process group) leader. - */ - -#ifdef HAVE_SETSID - if(setsid()<0) - fatalperror(net, "setsid()"); -#else -# ifdef TIOCNOTTY - t = open(_PATH_TTY, O_RDWR); - if (t >= 0) { - ioctl(t, TIOCNOTTY, (char *)0); - close(t); - } -# endif -#endif - -# ifdef PARENT_DOES_UTMP - /* - * Wait for our parent to get the utmp stuff to get done. - */ - utmp_sig_wait(); -# endif - - t = cleanopen(line); - if (t < 0) - fatalperror(net, line); - -#ifdef STREAMSPTY - ttyfd = t; - - - /* - * Not all systems have (or need) modules ttcompat and pckt so - * don't flag it as a fatal error if they don't exist. - */ - - if (really_stream) - { - /* these are the streams modules that we want pushed. note - that they are in reverse order, ptem will be pushed - first. maybe_push_modules() will try to push all modules - before the first one that isn't already pushed. i.e if - ldterm is pushed, only ttcompat will be attempted. - - all this is because we don't know which modules are - available, and we don't know which modules are already - pushed (via autopush, for instance). - - */ - - char *ttymodules[] = { "ttcompat", "ldterm", "ptem", NULL }; - char *ptymodules[] = { "pckt", NULL }; - - maybe_push_modules(t, ttymodules); - maybe_push_modules(ourpty, ptymodules); - } -#endif - /* - * set up the tty modes as we like them to be. - */ - init_termbuf(); -# ifdef TIOCSWINSZ - if (def_row || def_col) { - memset(&ws, 0, sizeof(ws)); - ws.ws_col = def_col; - ws.ws_row = def_row; - ioctl(t, TIOCSWINSZ, (char *)&ws); - } -# endif - - /* - * Settings for sgtty based systems - */ - - /* - * Settings for UNICOS (and HPUX) - */ -# if defined(_CRAY) || defined(__hpux) - termbuf.c_oflag = OPOST|ONLCR|TAB3; - termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON; - termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK; - termbuf.c_cflag = EXTB|HUPCL|CS8; -# endif - - /* - * Settings for all other termios/termio based - * systems, other than 4.4BSD. In 4.4BSD the - * kernel does the initial terminal setup. - */ -# if !(defined(_CRAY) || defined(__hpux)) && (BSD <= 43) -# ifndef OXTABS -# define OXTABS 0 -# endif - termbuf.c_lflag |= ECHO; - termbuf.c_oflag |= ONLCR|OXTABS; - termbuf.c_iflag |= ICRNL; - termbuf.c_iflag &= ~IXOFF; -# endif - tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600); - tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600); - - /* - * Set the tty modes, and make this our controlling tty. - */ - set_termbuf(); - if (login_tty(t) == -1) - fatalperror(net, "login_tty"); - if (net > 2) - close(net); - if (ourpty > 2) { - close(ourpty); - ourpty = -1; - } -} - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif -/* - * Open the specified slave side of the pty, - * making sure that we have a clean tty. - */ - -int cleanopen(char *line) -{ - int t; - -#ifdef STREAMSPTY - if (!really_stream) -#endif - { - /* - * Make sure that other people can't open the - * slave side of the connection. - */ - chown(line, 0, 0); - chmod(line, 0600); - } - -#ifdef HAVE_REVOKE - revoke(line); -#endif - - t = open(line, O_RDWR|O_NOCTTY); - - if (t < 0) - return(-1); - - /* - * Hangup anybody else using this ttyp, then reopen it for - * ourselves. - */ -# if !(defined(_CRAY) || defined(__hpux)) && (BSD <= 43) && !defined(STREAMSPTY) - signal(SIGHUP, SIG_IGN); -#ifdef HAVE_VHANGUP - vhangup(); -#else -#endif - signal(SIGHUP, SIG_DFL); - t = open(line, O_RDWR|O_NOCTTY); - if (t < 0) - return(-1); -# endif -# if defined(_CRAY) && defined(TCVHUP) - { - int i; - signal(SIGHUP, SIG_IGN); - ioctl(t, TCVHUP, (char *)0); - signal(SIGHUP, SIG_DFL); - - i = open(line, O_RDWR); - - if (i < 0) - return(-1); - close(t); - t = i; - } -# endif /* defined(CRAY) && defined(TCVHUP) */ - return(t); -} - -#if !defined(BSD4_4) - -int login_tty(int t) -{ -# if defined(TIOCSCTTY) && !defined(__hpux) - if (ioctl(t, TIOCSCTTY, (char *)0) < 0) - fatalperror(net, "ioctl(sctty)"); -# ifdef _CRAY - /* - * Close the hard fd to /dev/ttypXXX, and re-open through - * the indirect /dev/tty interface. - */ - close(t); - if ((t = open("/dev/tty", O_RDWR)) < 0) - fatalperror(net, "open(/dev/tty)"); -# endif -# else - /* - * We get our controlling tty assigned as a side-effect - * of opening up a tty device. But on BSD based systems, - * this only happens if our process group is zero. The - * setsid() call above may have set our pgrp, so clear - * it out before opening the tty... - */ -#ifdef HAVE_SETPGID - setpgid(0, 0); -#else - setpgrp(0, 0); /* if setpgid isn't available, setpgrp - probably takes arguments */ -#endif - close(open(line, O_RDWR)); -# endif - if (t != 0) - dup2(t, 0); - if (t != 1) - dup2(t, 1); - if (t != 2) - dup2(t, 2); - if (t > 2) - close(t); - return(0); -} -#endif /* BSD <= 43 */ - -/* - * This comes from ../../bsd/tty.c and should not really be here. - */ - -/* - * Clean the tty name. Return a pointer to the cleaned version. - */ - -static char * -clean_ttyname (char *tty) -{ - char *res = tty; - - if (strncmp (res, _PATH_DEV, strlen(_PATH_DEV)) == 0) - res += strlen(_PATH_DEV); - if (strncmp (res, "pty/", 4) == 0) - res += 4; - if (strncmp (res, "ptym/", 5) == 0) - res += 5; - return res; -} - -/* - * Generate a name usable as an `ut_id', typically without `tty'. - */ - -#ifdef HAVE_STRUCT_UTMP_UT_ID -static char * -make_id (char *tty) -{ - char *res = tty; - - if (strncmp (res, "pts/", 4) == 0) - res += 4; - if (strncmp (res, "tty", 3) == 0) - res += 3; - return res; -} -#endif - -/* - * startslave(host) - * - * Given a hostname, do whatever - * is necessary to startup the login process on the slave side of the pty. - */ - -/* ARGSUSED */ -void -startslave(char *host, int autologin, char *autoname) -{ - int i; - -#ifdef AUTHENTICATION - if (!autoname || !autoname[0]) - autologin = 0; - - if (autologin < auth_level) { - fatal(net, "Authorization failed"); - exit(1); - } -#endif - - { - char *tbuf = - "\r\n*** Connection not encrypted! " - "Communication may be eavesdropped. ***\r\n"; -#ifdef ENCRYPTION - if (!no_warn && (encrypt_output == 0 || decrypt_input == 0)) -#endif - writenet((unsigned char*)tbuf, strlen(tbuf)); - } -# ifdef PARENT_DOES_UTMP - utmp_sig_init(); -# endif /* PARENT_DOES_UTMP */ - - if ((i = fork()) < 0) - fatalperror(net, "fork"); - if (i) { -# ifdef PARENT_DOES_UTMP - /* - * Cray parent will create utmp entry for child and send - * signal to child to tell when done. Child waits for signal - * before doing anything important. - */ - int pid = i; - void sigjob (int); - - setpgrp(); - utmp_sig_reset(); /* reset handler to default */ - /* - * Create utmp entry for child - */ - wtmp.ut_time = time(NULL); - wtmp.ut_type = LOGIN_PROCESS; - wtmp.ut_pid = pid; - strncpy(wtmp.ut_user, "LOGIN", sizeof(wtmp.ut_user)); - strncpy(wtmp.ut_host, host, sizeof(wtmp.ut_host)); - strncpy(wtmp.ut_line, clean_ttyname(line), sizeof(wtmp.ut_line)); -#ifdef HAVE_STRUCT_UTMP_UT_ID - strncpy(wtmp.ut_id, wtmp.ut_line + 3, sizeof(wtmp.ut_id)); -#endif - - pututline(&wtmp); - endutent(); - if ((i = open(wtmpf, O_WRONLY|O_APPEND)) >= 0) { - write(i, &wtmp, sizeof(struct utmp)); - close(i); - } -#ifdef _CRAY - signal(WJSIGNAL, sigjob); -#endif - utmp_sig_notify(pid); -# endif /* PARENT_DOES_UTMP */ - } else { - getptyslave(); - start_login(host, autologin, autoname); - /*NOTREACHED*/ - } -} - -char *envinit[3]; -extern char **environ; - -void -init_env(void) -{ - extern char *getenv(const char *); - char **envp; - - envp = envinit; - if ((*envp = getenv("TZ"))) - *envp++ -= 3; -#if defined(_CRAY) || defined(__hpux) - else - *envp++ = "TZ=GMT0"; -#endif - *envp = 0; - environ = envinit; -} - -/* - * scrub_env() - * - * We only accept the environment variables listed below. - */ - -static void -scrub_env(void) -{ - static const char *reject[] = { - "TERMCAP=/", - NULL - }; - - static const char *accept[] = { - "XAUTH=", "XAUTHORITY=", "DISPLAY=", - "TERM=", - "EDITOR=", - "PAGER=", - "PRINTER=", - "LOGNAME=", - "POSIXLY_CORRECT=", - "TERMCAP=", - NULL - }; - - char **cpp, **cpp2; - const char **p; - - for (cpp2 = cpp = environ; *cpp; cpp++) { - int reject_it = 0; - - for(p = reject; *p; p++) - if(strncmp(*cpp, *p, strlen(*p)) == 0) { - reject_it = 1; - break; - } - if (reject_it) - continue; - - for(p = accept; *p; p++) - if(strncmp(*cpp, *p, strlen(*p)) == 0) - break; - if(*p != NULL) - *cpp2++ = *cpp; - } - *cpp2 = NULL; -} - - -struct arg_val { - int size; - int argc; - char **argv; -}; - -static int addarg(struct arg_val*, char*); - -/* - * start_login(host) - * - * Assuming that we are now running as a child processes, this - * function will turn us into the login process. - */ - -void -start_login(char *host, int autologin, char *name) -{ - struct arg_val argv; - char *user; - -#ifdef HAVE_UTMPX_H - int pid = getpid(); - struct utmpx utmpx; - char *clean_tty; - - /* - * Create utmp entry for child - */ - - clean_tty = clean_ttyname(line); - memset(&utmpx, 0, sizeof(utmpx)); - strncpy(utmpx.ut_user, ".telnet", sizeof(utmpx.ut_user)); - strncpy(utmpx.ut_line, clean_tty, sizeof(utmpx.ut_line)); -#ifdef HAVE_STRUCT_UTMP_UT_ID - strncpy(utmpx.ut_id, make_id(clean_tty), sizeof(utmpx.ut_id)); -#endif - utmpx.ut_pid = pid; - - utmpx.ut_type = LOGIN_PROCESS; - - gettimeofday (&utmpx.ut_tv, NULL); - if (pututxline(&utmpx) == NULL) - fatal(net, "pututxline failed"); -#endif - - scrub_env(); - - /* - * -h : pass on name of host. - * WARNING: -h is accepted by login if and only if - * getuid() == 0. - * -p : don't clobber the environment (so terminal type stays set). - * - * -f : force this login, he has already been authenticated - */ - - /* init argv structure */ - argv.size=0; - argv.argc=0; - argv.argv=(char**)malloc(0); /*so we can call realloc later */ - addarg(&argv, "login"); - addarg(&argv, "-h"); - addarg(&argv, host); - addarg(&argv, "-p"); - if(name[0]) - user = name; - else - user = getenv("USER"); -#ifdef AUTHENTICATION - if (auth_level < 0 || autologin != AUTH_VALID) { - if(!no_warn) { - printf("User not authenticated. "); - if (require_otp) - printf("Using one-time password\r\n"); - else - printf("Using plaintext username and password\r\n"); - } - if (require_otp) { - addarg(&argv, "-a"); - addarg(&argv, "otp"); - } - if(log_unauth) - syslog(LOG_INFO, "unauthenticated access from %s (%s)", - host, user ? user : "unknown user"); - } - if (auth_level >= 0 && autologin == AUTH_VALID) - addarg(&argv, "-f"); -#endif - if(user){ - addarg(&argv, "--"); - addarg(&argv, strdup(user)); - } - if (getenv("USER")) { - /* - * Assume that login will set the USER variable - * correctly. For SysV systems, this means that - * USER will no longer be set, just LOGNAME by - * login. (The problem is that if the auto-login - * fails, and the user then specifies a different - * account name, he can get logged in with both - * LOGNAME and USER in his environment, but the - * USER value will be wrong. - */ - unsetenv("USER"); - } - closelog(); - /* - * This sleep(1) is in here so that telnetd can - * finish up with the tty. There's a race condition - * the login banner message gets lost... - */ - sleep(1); - - execv(new_login, argv.argv); - - syslog(LOG_ERR, "%s: %m\n", new_login); - fatalperror(net, new_login); - /*NOTREACHED*/ -} - - - -static int addarg(struct arg_val *argv, char *val) -{ - if(argv->size <= argv->argc+1){ - argv->argv = (char**)realloc(argv->argv, sizeof(char*) * (argv->size + 10)); - if(argv->argv == NULL) - return 1; /* this should probably be handled better */ - argv->size+=10; - } - argv->argv[argv->argc++]=val; - argv->argv[argv->argc]=NULL; - return 0; -} - - -/* - * rmut() - * - * This is the function called by cleanup() to - * remove the utmp entry for this person. - */ - -#ifdef HAVE_UTMPX_H -static void -rmut(void) -{ - struct utmpx utmpx, *non_save_utxp; - char *clean_tty = clean_ttyname(line); - - /* - * This updates the utmpx and utmp entries and make a wtmp/x entry - */ - - setutxent(); - memset(&utmpx, 0, sizeof(utmpx)); - strncpy(utmpx.ut_line, clean_tty, sizeof(utmpx.ut_line)); - utmpx.ut_type = LOGIN_PROCESS; - non_save_utxp = getutxline(&utmpx); - if (non_save_utxp) { - struct utmpx *utxp; - char user0; - - utxp = malloc(sizeof(struct utmpx)); - *utxp = *non_save_utxp; - user0 = utxp->ut_user[0]; - utxp->ut_user[0] = '\0'; - utxp->ut_type = DEAD_PROCESS; -#ifdef HAVE_STRUCT_UTMPX_UT_EXIT -#ifdef _STRUCT___EXIT_STATUS - utxp->ut_exit.__e_termination = 0; - utxp->ut_exit.__e_exit = 0; -#elif defined(__osf__) /* XXX */ - utxp->ut_exit.ut_termination = 0; - utxp->ut_exit.ut_exit = 0; -#else - utxp->ut_exit.e_termination = 0; - utxp->ut_exit.e_exit = 0; -#endif -#endif - gettimeofday(&utxp->ut_tv, NULL); - pututxline(utxp); -#ifdef WTMPX_FILE - utxp->ut_user[0] = user0; - updwtmpx(WTMPX_FILE, utxp); -#elif defined(WTMP_FILE) - /* This is a strange system with a utmpx and a wtmp! */ - { - int f = open(wtmpf, O_WRONLY|O_APPEND); - struct utmp wtmp; - if (f >= 0) { - strncpy(wtmp.ut_line, clean_tty, sizeof(wtmp.ut_line)); - strncpy(wtmp.ut_name, "", sizeof(wtmp.ut_name)); -#ifdef HAVE_STRUCT_UTMP_UT_HOST - strncpy(wtmp.ut_host, "", sizeof(wtmp.ut_host)); -#endif - wtmp.ut_time = time(NULL); - write(f, &wtmp, sizeof(wtmp)); - close(f); - } - } -#endif - free (utxp); - } - endutxent(); -} /* end of rmut */ -#endif - -#if !defined(HAVE_UTMPX_H) && !(defined(_CRAY) || defined(__hpux)) && BSD <= 43 -static void -rmut(void) -{ - int f; - int found = 0; - struct utmp *u, *utmp; - int nutmp; - struct stat statbf; - char *clean_tty = clean_ttyname(line); - - f = open(utmpf, O_RDWR); - if (f >= 0) { - fstat(f, &statbf); - utmp = (struct utmp *)malloc((unsigned)statbf.st_size); - if (!utmp) - syslog(LOG_ERR, "utmp malloc failed"); - if (statbf.st_size && utmp) { - nutmp = read(f, utmp, (int)statbf.st_size); - nutmp /= sizeof(struct utmp); - - for (u = utmp ; u < &utmp[nutmp] ; u++) { - if (strncmp(u->ut_line, - clean_tty, - sizeof(u->ut_line)) || - u->ut_name[0]==0) - continue; - lseek(f, ((long)u)-((long)utmp), L_SET); - strncpy(u->ut_name, "", sizeof(u->ut_name)); -#ifdef HAVE_STRUCT_UTMP_UT_HOST - strncpy(u->ut_host, "", sizeof(u->ut_host)); -#endif - u->ut_time = time(NULL); - write(f, u, sizeof(wtmp)); - found++; - } - } - close(f); - } - if (found) { - f = open(wtmpf, O_WRONLY|O_APPEND); - if (f >= 0) { - strncpy(wtmp.ut_line, clean_tty, sizeof(wtmp.ut_line)); - strncpy(wtmp.ut_name, "", sizeof(wtmp.ut_name)); -#ifdef HAVE_STRUCT_UTMP_UT_HOST - strncpy(wtmp.ut_host, "", sizeof(wtmp.ut_host)); -#endif - wtmp.ut_time = time(NULL); - write(f, &wtmp, sizeof(wtmp)); - close(f); - } - } - chmod(line, 0666); - chown(line, 0, 0); - line[strlen("/dev/")] = 'p'; - chmod(line, 0666); - chown(line, 0, 0); -} /* end of rmut */ -#endif /* CRAY */ - -#if defined(__hpux) && !defined(HAVE_UTMPX_H) -static void -rmut (char *line) -{ - struct utmp utmp; - struct utmp *utptr; - int fd; /* for /etc/wtmp */ - - utmp.ut_type = USER_PROCESS; - strncpy(utmp.ut_line, clean_ttyname(line), sizeof(utmp.ut_line)); - setutent(); - utptr = getutline(&utmp); - /* write it out only if it exists */ - if (utptr) { - utptr->ut_type = DEAD_PROCESS; - utptr->ut_time = time(NULL); - pututline(utptr); - /* set wtmp entry if wtmp file exists */ - if ((fd = open(wtmpf, O_WRONLY | O_APPEND)) >= 0) { - write(fd, utptr, sizeof(utmp)); - close(fd); - } - } - endutent(); - - chmod(line, 0666); - chown(line, 0, 0); - line[14] = line[13]; - line[13] = line[12]; - line[8] = 'm'; - line[9] = '/'; - line[10] = 'p'; - line[11] = 't'; - line[12] = 'y'; - chmod(line, 0666); - chown(line, 0, 0); -} -#endif - -/* - * cleanup() - * - * This is the routine to call when we are all through, to - * clean up anything that needs to be cleaned up. - */ - -#ifdef PARENT_DOES_UTMP - -void -cleanup(int sig) -{ -#ifdef _CRAY - static int incleanup = 0; - 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 - * as the signal handler. - * 2: If we are a nested cleanup(), return. - * 3: Try to clean up TMPDIR. - * 4: Fill in utmp with shutdown of process. - * 5: Close down the network and pty connections. - * 6: Finish up the TMPDIR cleanup, if needed. - */ - 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); - return; - } - incleanup = 1; - sigsetmask(t); - - t = cleantmp(&wtmp); - setutent(); /* just to make sure */ -#endif /* CRAY */ - rmut(line); - close(ourpty); - shutdown(net, 2); -#ifdef _CRAY - if (t == 0) - cleantmp(&wtmp); -#endif /* CRAY */ - exit(1); -} - -#else /* PARENT_DOES_UTMP */ - -void -cleanup(int sig) -{ -#if defined(HAVE_UTMPX_H) || !defined(HAVE_LOGWTMP) - rmut(); -#ifdef HAVE_VHANGUP -#ifndef __sgi - vhangup(); /* XXX */ -#endif -#endif -#else - char *p; - - p = line + sizeof("/dev/") - 1; - if (logout(p)) - logwtmp(p, "", ""); - chmod(line, 0666); - chown(line, 0, 0); - *p = 'p'; - chmod(line, 0666); - chown(line, 0, 0); -#endif - shutdown(net, 2); - exit(1); -} - -#endif /* PARENT_DOES_UTMP */ - -#ifdef PARENT_DOES_UTMP -/* - * _utmp_sig_rcv - * utmp_sig_init - * utmp_sig_wait - * These three functions are used to coordinate the handling of - * the utmp file between the server and the soon-to-be-login shell. - * The server actually creates the utmp structure, the child calls - * utmp_sig_wait(), until the server calls utmp_sig_notify() and - * signals the future-login shell to proceed. - */ -static int caught=0; /* NZ when signal intercepted */ -static void (*func)(); /* address of previous handler */ - -void -_utmp_sig_rcv(sig) - int sig; -{ - caught = 1; - signal(SIGUSR1, func); -} - -void -utmp_sig_init() -{ - /* - * register signal handler for UTMP creation - */ - if ((int)(func = signal(SIGUSR1, _utmp_sig_rcv)) == -1) - fatalperror(net, "telnetd/signal"); -} - -void -utmp_sig_reset() -{ - signal(SIGUSR1, func); /* reset handler to default */ -} - -# ifdef __hpux -# define sigoff() /* do nothing */ -# define sigon() /* do nothing */ -# endif - -void -utmp_sig_wait() -{ - /* - * Wait for parent to write our utmp entry. - */ - sigoff(); - while (caught == 0) { - pause(); /* wait until we get a signal (sigon) */ - sigoff(); /* turn off signals while we check caught */ - } - sigon(); /* turn on signals again */ -} - -void -utmp_sig_notify(pid) -{ - kill(pid, SIGUSR1); -} - -#ifdef _CRAY -static int gotsigjob = 0; - - /*ARGSUSED*/ -void -sigjob(sig) - int sig; -{ - int jid; - struct jobtemp *jp; - - while ((jid = waitjob(NULL)) != -1) { - if (jid == 0) { - return; - } - gotsigjob++; - jobend(jid, NULL, NULL); - } -} - -/* - * 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 - * from the utmp. If the job has already gone away, - * then we'll clean up and be done. If not, then - * when this is called the second time it will wait - * for the signal that the job is done. - */ -int -cleantmp(wtp) - struct utmp *wtp; -{ - struct utmp *utp; - static int first = 1; - int mask, omask, ret; - extern struct utmp *getutid (const struct utmp *_Id); - - - mask = sigmask(WJSIGNAL); - - if (first == 0) { - omask = sigblock(mask); - while (gotsigjob == 0) - sigpause(omask); - return(1); - } - first = 0; - setutent(); /* just to make sure */ - - utp = getutid(wtp); - if (utp == 0) { - syslog(LOG_ERR, "Can't get /etc/utmp entry to clean TMPDIR"); - return(-1); - } - /* - * Nothing to clean up if the user shell was never started. - */ - if (utp->ut_type != USER_PROCESS || utp->ut_jid == 0) - return(1); - - /* - * Block the WJSIGNAL while we are in jobend(). - */ - omask = sigblock(mask); - ret = jobend(utp->ut_jid, utp->ut_tpath, utp->ut_user); - sigsetmask(omask); - return(ret); -} - -int -jobend(jid, path, user) - int jid; - char *path; - 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)); - saved_path[sizeof(saved_path)] = '\0'; - saved_user[sizeof(saved_user)] = '\0'; - } - if (saved_jid == 0) { - 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); -} - -/* - * Fork a child process to clean up the TMPDIR - */ -cleantmpdir(jid, tpath, user) - int jid; - char *tpath; - char *user; -{ - switch(fork()) { - case -1: - syslog(LOG_ERR, "TMPDIR cleanup(%s): fork() failed: %m\n", - tpath); - break; - case 0: - execl(CLEANTMPCMD, CLEANTMPCMD, user, tpath, 0); - syslog(LOG_ERR, "TMPDIR cleanup(%s): execl(%s) failed: %m\n", - tpath, CLEANTMPCMD); - exit(1); - default: - /* - * Forget about child. We will exit, and - * /etc/init will pick it up. - */ - break; - } -} -#endif /* CRAY */ -#endif /* defined(PARENT_DOES_UTMP) */ diff --git a/crypto/kerberosIV/appl/telnet/telnetd/telnetd.c b/crypto/kerberosIV/appl/telnet/telnetd/telnetd.c deleted file mode 100644 index 0c2750e..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/telnetd.c +++ /dev/null @@ -1,1399 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "telnetd.h" - -RCSID("$Id: telnetd.c,v 1.58.2.1 2000/10/10 13:12:08 assar Exp $"); - -#ifdef _SC_CRAY_SECURE_SYS -#include <sys/sysv.h> -#include <sys/secdev.h> -#include <sys/secparm.h> -#include <sys/usrv.h> -int secflag; -char tty_dev[16]; -struct secdev dv; -struct sysv sysv; -struct socksec ss; -#endif /* _SC_CRAY_SECURE_SYS */ - -#ifdef AUTHENTICATION -int auth_level = 0; -#endif - -extern int utmp_len; -int registerd_host_only = 0; - -#ifdef STREAMSPTY -# include <stropts.h> -# include <termios.h> -#ifdef HAVE_SYS_UIO_H -#include <sys/uio.h> -#endif /* HAVE_SYS_UIO_H */ -#ifdef HAVE_SYS_STREAM_H -#include <sys/stream.h> -#endif -#ifdef _AIX -#include <sys/termio.h> -#endif -# ifdef HAVE_SYS_STRTTY_H -# include <sys/strtty.h> -# endif -# ifdef HAVE_SYS_STR_TTY_H -# include <sys/str_tty.h> -# endif -/* make sure we don't get the bsd version */ -/* what is this here for? solaris? /joda */ -# ifdef HAVE_SYS_TTY_H -# include "/usr/include/sys/tty.h" -# endif -# ifdef HAVE_SYS_PTYVAR_H -# include <sys/ptyvar.h> -# endif - -/* - * Because of the way ptyibuf is used with streams messages, we need - * ptyibuf+1 to be on a full-word boundary. The following wierdness - * is simply to make that happen. - */ -long ptyibufbuf[BUFSIZ/sizeof(long)+1]; -char *ptyibuf = ((char *)&ptyibufbuf[1])-1; -char *ptyip = ((char *)&ptyibufbuf[1])-1; -char ptyibuf2[BUFSIZ]; -unsigned char ctlbuf[BUFSIZ]; -struct strbuf strbufc, strbufd; - -int readstream(int, char*, int); - -#else /* ! STREAMPTY */ - -/* - * I/O data buffers, - * pointers, and counters. - */ -char ptyibuf[BUFSIZ], *ptyip = ptyibuf; -char ptyibuf2[BUFSIZ]; - -#endif /* ! STREAMPTY */ - -int hostinfo = 1; /* do we print login banner? */ - -#ifdef _CRAY -extern int newmap; /* nonzero if \n maps to ^M^J */ -int lowpty = 0, highpty; /* low, high pty numbers */ -#endif /* CRAY */ - -int debug = 0; -int keepalive = 1; -char *progname; - -static void usage (void); - -/* - * The string to pass to getopt(). We do it this way so - * that only the actual options that we support will be - * passed off to getopt(). - */ -char valid_opts[] = "Bd:hklnS:u:UL:y" -#ifdef AUTHENTICATION - "a:X:z" -#endif -#ifdef DIAGNOSTICS - "D:" -#endif -#ifdef _CRAY - "r:" -#endif - ; - -static void doit(struct sockaddr*, int); - -int -main(int argc, char **argv) -{ - struct sockaddr_storage __ss; - struct sockaddr *sa = (struct sockaddr *)&__ss; - int on = 1, sa_size; - int ch; -#if defined(IPPROTO_IP) && defined(IP_TOS) - int tos = -1; -#endif -#ifdef ENCRYPTION - extern int des_check_key; - des_check_key = 1; /* Kludge for Mac NCSA telnet 2.6 /bg */ -#endif - pfrontp = pbackp = ptyobuf; - netip = netibuf; - nfrontp = nbackp = netobuf; - - progname = *argv; -#ifdef ENCRYPTION - nclearto = 0; -#endif - -#ifdef _CRAY - /* - * Get number of pty's before trying to process options, - * which may include changing pty range. - */ - highpty = getnpty(); -#endif /* CRAY */ - - while ((ch = getopt(argc, argv, valid_opts)) != -1) { - switch(ch) { - -#ifdef AUTHENTICATION - case 'a': - /* - * Check for required authentication level - */ - if (strcmp(optarg, "debug") == 0) { - auth_debug_mode = 1; - } else if (strcasecmp(optarg, "none") == 0) { - auth_level = 0; - } else if (strcasecmp(optarg, "otp") == 0) { - auth_level = 0; - require_otp = 1; - } 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 { - fprintf(stderr, - "telnetd: unknown authorization level for -a\n"); - } - break; -#endif /* AUTHENTICATION */ - - case 'B': /* BFTP mode is not supported any more */ - break; - case 'd': - if (strcmp(optarg, "ebug") == 0) { - debug++; - break; - } - usage(); - /* NOTREACHED */ - break; - -#ifdef DIAGNOSTICS - case 'D': - /* - * Check for desired diagnostics capabilities. - */ - if (!strcmp(optarg, "report")) { - diagnostic |= TD_REPORT|TD_OPTIONS; - } else if (!strcmp(optarg, "exercise")) { - diagnostic |= TD_EXERCISE; - } else if (!strcmp(optarg, "netdata")) { - diagnostic |= TD_NETDATA; - } else if (!strcmp(optarg, "ptydata")) { - diagnostic |= TD_PTYDATA; - } else if (!strcmp(optarg, "options")) { - diagnostic |= TD_OPTIONS; - } else { - usage(); - /* NOT REACHED */ - } - break; -#endif /* DIAGNOSTICS */ - - - case 'h': - hostinfo = 0; - break; - - case 'k': /* Linemode is not supported any more */ - case 'l': - break; - - case 'n': - keepalive = 0; - break; - -#ifdef _CRAY - case 'r': - { - char *strchr(); - char *c; - - /* - * Allow the specification of alterations - * to the pty search range. It is legal to - * specify only one, and not change the - * other from its default. - */ - c = strchr(optarg, '-'); - if (c) { - *c++ = '\0'; - highpty = atoi(c); - } - if (*optarg != '\0') - lowpty = atoi(optarg); - if ((lowpty > highpty) || (lowpty < 0) || - (highpty > 32767)) { - usage(); - /* NOT REACHED */ - } - break; - } -#endif /* CRAY */ - - case 'S': -#ifdef HAVE_PARSETOS - if ((tos = parsetos(optarg, "tcp")) < 0) - fprintf(stderr, "%s%s%s\n", - "telnetd: Bad TOS argument '", optarg, - "'; will try to use default TOS"); -#else - fprintf(stderr, "%s%s\n", "TOS option unavailable; ", - "-S flag not supported\n"); -#endif - break; - - case 'u': - utmp_len = atoi(optarg); - break; - - case 'U': - registerd_host_only = 1; - break; - -#ifdef AUTHENTICATION - case 'X': - /* - * Check for invalid authentication types - */ - auth_disable_name(optarg); - break; -#endif - case 'y': - no_warn = 1; - break; -#ifdef AUTHENTICATION - case 'z': - log_unauth = 1; - break; - -#endif /* AUTHENTICATION */ - - case 'L': - new_login = optarg; - break; - - default: - fprintf(stderr, "telnetd: %c: unknown option\n", ch); - /* FALLTHROUGH */ - case '?': - usage(); - /* NOTREACHED */ - } - } - - argc -= optind; - argv += optind; - - if (debug) { - int port = 0; - struct servent *sp; - - if (argc > 1) { - usage (); - } else if (argc == 1) { - sp = roken_getservbyname (*argv, "tcp"); - if (sp) - port = sp->s_port; - else - port = htons(atoi(*argv)); - } else { -#ifdef KRB5 - port = krb5_getportbyname (NULL, "telnet", "tcp", 23); -#else - port = k_getportbyname("telnet", "tcp", htons(23)); -#endif - } - mini_inetd (port); - } else if (argc > 0) { - usage(); - /* NOT REACHED */ - } - -#ifdef _SC_CRAY_SECURE_SYS - secflag = sysconf(_SC_CRAY_SECURE_SYS); - - /* - * Get socket's security label - */ - if (secflag) { - int szss = sizeof(ss); - int sock_multi; - int szi = sizeof(int); - - memset(&dv, 0, sizeof(dv)); - - if (getsysv(&sysv, sizeof(struct sysv)) != 0) - fatalperror(net, "getsysv"); - - /* - * Get socket security label and set device values - * {security label to be set on ttyp device} - */ -#ifdef SO_SEC_MULTI /* 8.0 code */ - if ((getsockopt(0, SOL_SOCKET, SO_SECURITY, - (void *)&ss, &szss) < 0) || - (getsockopt(0, SOL_SOCKET, SO_SEC_MULTI, - (void *)&sock_multi, &szi) < 0)) - fatalperror(net, "getsockopt"); - else { - dv.dv_actlvl = ss.ss_actlabel.lt_level; - dv.dv_actcmp = ss.ss_actlabel.lt_compart; - if (!sock_multi) { - dv.dv_minlvl = dv.dv_maxlvl = dv.dv_actlvl; - dv.dv_valcmp = dv.dv_actcmp; - } else { - dv.dv_minlvl = ss.ss_minlabel.lt_level; - dv.dv_maxlvl = ss.ss_maxlabel.lt_level; - dv.dv_valcmp = ss.ss_maxlabel.lt_compart; - } - dv.dv_devflg = 0; - } -#else /* SO_SEC_MULTI */ /* 7.0 code */ - if (getsockopt(0, SOL_SOCKET, SO_SECURITY, - (void *)&ss, &szss) >= 0) { - dv.dv_actlvl = ss.ss_slevel; - dv.dv_actcmp = ss.ss_compart; - dv.dv_minlvl = ss.ss_minlvl; - dv.dv_maxlvl = ss.ss_maxlvl; - dv.dv_valcmp = ss.ss_maxcmp; - } -#endif /* SO_SEC_MULTI */ - } -#endif /* _SC_CRAY_SECURE_SYS */ - - roken_openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON); - sa_size = sizeof (__ss); - if (getpeername(STDIN_FILENO, sa, &sa_size) < 0) { - fprintf(stderr, "%s: ", progname); - perror("getpeername"); - _exit(1); - } - if (keepalive && - setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, - (void *)&on, sizeof (on)) < 0) { - syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); - } - -#if defined(IPPROTO_IP) && defined(IP_TOS) && defined(HAVE_SETSOCKOPT) - { -# ifdef HAVE_GETTOSBYNAME - struct tosent *tp; - if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) - tos = tp->t_tos; -# endif - if (tos < 0) - tos = 020; /* Low Delay bit */ - if (tos - && sa->sa_family == AF_INET - && (setsockopt(STDIN_FILENO, IPPROTO_IP, IP_TOS, - (void *)&tos, sizeof(tos)) < 0) - && (errno != ENOPROTOOPT) ) - syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); - } -#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ - net = STDIN_FILENO; - doit(sa, sa_size); - /* NOTREACHED */ - return 0; -} /* end of main */ - -static void -usage(void) -{ - fprintf(stderr, "Usage: telnetd"); -#ifdef AUTHENTICATION - fprintf(stderr, " [-a (debug|other|otp|user|valid|off|none)]\n\t"); -#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]"); - fprintf(stderr, " [-L login]"); - fprintf(stderr, " [-n]"); -#ifdef _CRAY - fprintf(stderr, " [-r[lowpty]-[highpty]]"); -#endif - fprintf(stderr, "\n\t"); -#ifdef HAVE_GETTOSBYNAME - fprintf(stderr, " [-S tos]"); -#endif -#ifdef AUTHENTICATION - fprintf(stderr, " [-X auth-type] [-y] [-z]"); -#endif - fprintf(stderr, " [-u utmp_hostname_length] [-U]"); - fprintf(stderr, " [port]\n"); - exit(1); -} - -/* - * getterminaltype - * - * Ask the other end to send along its terminal type and speed. - * Output is the variable terminaltype filled in. - */ -static unsigned char ttytype_sbbuf[] = { - IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE -}; - -int -getterminaltype(char *name, size_t name_sz) -{ - int retval = -1; - void _gettermname(); - - settimer(baseline); -#ifdef 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, name_sz); - } -#endif - -#ifdef ENCRYPTION - send_will(TELOPT_ENCRYPT, 1); - send_do(TELOPT_ENCRYPT, 1); /* esc@magic.fi */ -#endif - send_do(TELOPT_TTYPE, 1); - send_do(TELOPT_TSPEED, 1); - send_do(TELOPT_XDISPLOC, 1); - send_do(TELOPT_NEW_ENVIRON, 1); - send_do(TELOPT_OLD_ENVIRON, 1); - while ( -#ifdef ENCRYPTION - his_do_dont_is_changing(TELOPT_ENCRYPT) || -#endif - his_will_wont_is_changing(TELOPT_TTYPE) || - his_will_wont_is_changing(TELOPT_TSPEED) || - his_will_wont_is_changing(TELOPT_XDISPLOC) || - his_will_wont_is_changing(TELOPT_NEW_ENVIRON) || - his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) { - ttloop(); - } -#ifdef ENCRYPTION - /* - * Wait for the negotiation of what type of encryption we can - * send with. If autoencrypt is not set, this will just return. - */ - if (his_state_is_will(TELOPT_ENCRYPT)) { - encrypt_wait(); - } -#endif - if (his_state_is_will(TELOPT_TSPEED)) { - static unsigned char sb[] = - { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; - - telnet_net_write (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 }; - - telnet_net_write (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 }; - - telnet_net_write (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 }; - - telnet_net_write (sb, sizeof sb); - DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); - } - if (his_state_is_will(TELOPT_TTYPE)) { - - telnet_net_write (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)) - ttloop(); - } - if (his_state_is_will(TELOPT_XDISPLOC)) { - while (sequenceIs(xdisplocsubopt, baseline)) - ttloop(); - } - if (his_state_is_will(TELOPT_NEW_ENVIRON)) { - while (sequenceIs(environsubopt, baseline)) - ttloop(); - } - if (his_state_is_will(TELOPT_OLD_ENVIRON)) { - while (sequenceIs(oenvironsubopt, baseline)) - ttloop(); - } - if (his_state_is_will(TELOPT_TTYPE)) { - char first[256], last[256]; - - while (sequenceIs(ttypesubopt, baseline)) - ttloop(); - - /* - * If the other side has already disabled the option, then - * we have to just go with what we (might) have already gotten. - */ - if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) { - strlcpy(first, terminaltype, sizeof(first)); - for(;;) { - /* - * Save the unknown name, and request the next name. - */ - strlcpy(last, terminaltype, sizeof(last)); - _gettermname(); - if (terminaltypeok(terminaltype)) - break; - if ((strncmp(last, terminaltype, sizeof(last)) == 0) || - his_state_is_wont(TELOPT_TTYPE)) { - /* - * We've hit the end. If this is the same as - * the first name, just go with it. - */ - if (strncmp(first, terminaltype, sizeof(first)) == 0) - break; - /* - * Get the terminal name one more time, so that - * RFC1091 compliant telnets will cycle back to - * the start of the list. - */ - _gettermname(); - if (strncmp(first, terminaltype, sizeof(first)) != 0) - strcpy(terminaltype, first); - break; - } - } - } - } - return(retval); -} /* end of getterminaltype */ - -void -_gettermname() -{ - /* - * If the client turned off the option, - * we can't send another request, so we - * just return. - */ - if (his_state_is_wont(TELOPT_TTYPE)) - return; - settimer(baseline); - telnet_net_write (ttytype_sbbuf, sizeof ttytype_sbbuf); - DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2, - sizeof ttytype_sbbuf - 2);); - while (sequenceIs(ttypesubopt, baseline)) - ttloop(); -} - -int -terminaltypeok(char *s) -{ - return 1; -} - - -char *hostname; -char host_name[MaxHostNameLen]; -char remote_host_name[MaxHostNameLen]; - -/* - * Get a pty, scan input lines. - */ -static void -doit(struct sockaddr *who, int who_len) -{ - char *host = NULL; - struct hostent *hp = NULL; - int level; - int ptynum; - char user_name[256]; - int error; - char host_addr[256]; - void *addr; - int addr_sz; - const char *tmp; - int af; - - /* - * Find an available pty to use. - */ - ourpty = getpty(&ptynum); - if (ourpty < 0) - fatal(net, "All network ports in use"); - -#ifdef _SC_CRAY_SECURE_SYS - /* - * set ttyp line security label - */ - if (secflag) { - char slave_dev[16]; - - snprintf(tty_dev, sizeof(tty_dev), "/dev/pty/%03d", ptynum); - if (setdevs(tty_dev, &dv) < 0) - fatal(net, "cannot set pty security"); - snprintf(slave_dev, sizeof(slave_dev), "/dev/ttyp%03d", ptynum); - if (setdevs(slave_dev, &dv) < 0) - fatal(net, "cannot set tty security"); - } -#endif /* _SC_CRAY_SECURE_SYS */ - - af = who->sa_family; - switch (af) { - case AF_INET : { - struct sockaddr_in *sin = (struct sockaddr_in *)who; - - addr = &sin->sin_addr; - addr_sz = sizeof(sin->sin_addr); - break; - } -#ifdef HAVE_IPV6 - case AF_INET6 : { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)who; - - addr = &sin6->sin6_addr; - addr_sz = sizeof(sin6->sin6_addr); - break; - } -#endif - default : - fatal (net, "Unknown address family\r\n"); - break; - } - - hp = getipnodebyaddr (addr, addr_sz, af, &error); - - if (hp == NULL && registerd_host_only) { - fatal(net, "Couldn't resolve your address into a host name.\r\n\ -Please contact your net administrator"); - } else if (hp != NULL) { - host = hp->h_name; - } - - tmp = inet_ntop(af, addr, host_addr, sizeof(host_addr)); - if (tmp == NULL) - strlcpy (host_addr, "unknown address", sizeof(host_addr)); - - if (host == NULL) - host = host_addr; - - /* - * We must make a copy because Kerberos is probably going - * to also do a gethost* and overwrite the static data... - */ - strlcpy(remote_host_name, host, sizeof(remote_host_name)); - if (hp != NULL) - freehostent (hp); - host = remote_host_name; - - /* XXX - should be k_gethostname? */ - gethostname(host_name, sizeof (host_name)); - hostname = host_name; - - /* Only trim if too long (and possible) */ - if (strlen(remote_host_name) > abs(utmp_len)) { - char *domain = strchr(host_name, '.'); - char *p = strchr(remote_host_name, '.'); - if (domain && p && (strcmp(p, domain) == 0)) - *p = 0; /* remove domain part */ - } - - - /* - * If hostname still doesn't fit utmp, use ipaddr. - */ - if (strlen(remote_host_name) > abs(utmp_len)) - strlcpy(remote_host_name, - host_addr, - sizeof(remote_host_name)); - -#ifdef AUTHENTICATION - auth_encrypt_init(hostname, host, "TELNETD", 1); -#endif - - init_env(); - /* - * get terminal type. - */ - *user_name = 0; - level = getterminaltype(user_name, sizeof(user_name)); - setenv("TERM", terminaltype ? terminaltype : "network", 1); - -#ifdef _SC_CRAY_SECURE_SYS - if (secflag) { - if (setulvl(dv.dv_actlvl) < 0) - fatal(net,"cannot setulvl()"); - if (setucmp(dv.dv_actcmp) < 0) - fatal(net, "cannot setucmp()"); - } -#endif /* _SC_CRAY_SECURE_SYS */ - - /* begin server processing */ - my_telnet(net, ourpty, host, level, user_name); - /*NOTREACHED*/ -} /* end of doit */ - -/* output contents of /etc/issue.net, or /etc/issue */ -static void -show_issue(void) -{ - FILE *f; - char buf[128]; - f = fopen("/etc/issue.net", "r"); - if(f == NULL) - f = fopen("/etc/issue", "r"); - if(f){ - while(fgets(buf, sizeof(buf)-2, f)){ - strcpy(buf + strcspn(buf, "\r\n"), "\r\n"); - writenet((unsigned char*)buf, strlen(buf)); - } - fclose(f); - } -} - -/* - * Main loop. Select from pty and network, and - * hand data to telnet receiver finite state machine. - */ -void -my_telnet(int f, int p, char *host, int level, char *autoname) -{ - int on = 1; - char *he; - char *IM; - int nfd; - int startslave_called = 0; - time_t timeout; - - /* - * Initialize the slc mapping table. - */ - get_slc_defaults(); - - /* - * Do some tests where it is desireable to wait for a response. - * Rather than doing them slowly, one at a time, do them all - * at once. - */ - if (my_state_is_wont(TELOPT_SGA)) - send_will(TELOPT_SGA, 1); - /* - * Is the client side a 4.2 (NOT 4.3) system? We need to know this - * because 4.2 clients are unable to deal with TCP urgent data. - * - * To find out, we send out a "DO ECHO". If the remote system - * answers "WILL ECHO" it is probably a 4.2 client, and we note - * that fact ("WILL ECHO" ==> that the client will echo what - * WE, the server, sends it; it does NOT mean that the client will - * echo the terminal input). - */ - send_do(TELOPT_ECHO, 1); - - /* - * Send along a couple of other options that we wish to negotiate. - */ - send_do(TELOPT_NAWS, 1); - send_will(TELOPT_STATUS, 1); - flowmode = 1; /* default flow control state */ - restartany = -1; /* uninitialized... */ - send_do(TELOPT_LFLOW, 1); - - /* - * Spin, waiting for a response from the DO ECHO. However, - * some REALLY DUMB telnets out there might not respond - * to the DO ECHO. So, we spin looking for NAWS, (most dumb - * telnets so far seem to respond with WONT for a DO that - * they don't understand...) because by the time we get the - * response, it will already have processed the DO ECHO. - * Kludge upon kludge. - */ - while (his_will_wont_is_changing(TELOPT_NAWS)) - ttloop(); - - /* - * But... - * The client might have sent a WILL NAWS as part of its - * startup code; if so, we'll be here before we get the - * response to the DO ECHO. We'll make the assumption - * that any implementation that understands about NAWS - * is a modern enough implementation that it will respond - * to our DO ECHO request; hence we'll do another spin - * waiting for the ECHO option to settle down, which is - * what we wanted to do in the first place... - */ - if (his_want_state_is_will(TELOPT_ECHO) && - his_state_is_will(TELOPT_NAWS)) { - while (his_will_wont_is_changing(TELOPT_ECHO)) - ttloop(); - } - /* - * On the off chance that the telnet client is broken and does not - * respond to the DO ECHO we sent, (after all, we did send the - * DO NAWS negotiation after the DO ECHO, and we won't get here - * until a response to the DO NAWS comes back) simulate the - * receipt of a will echo. This will also send a WONT ECHO - * to the client, since we assume that the client failed to - * respond because it believes that it is already in DO ECHO - * mode, which we do not want. - */ - if (his_want_state_is_will(TELOPT_ECHO)) { - DIAG(TD_OPTIONS, - {output_data("td: simulating recv\r\n"); - }); - willoption(TELOPT_ECHO); - } - - /* - * Finally, to clean things up, we turn on our echo. This - * will break stupid 4.2 telnets out of local terminal echo. - */ - - if (my_state_is_wont(TELOPT_ECHO)) - send_will(TELOPT_ECHO, 1); - -#ifdef TIOCPKT -#ifdef STREAMSPTY - if (!really_stream) -#endif - /* - * Turn on packet mode - */ - ioctl(p, TIOCPKT, (char *)&on); -#endif - - - /* - * Call telrcv() once to pick up anything received during - * terminal type negotiation, 4.2/4.3 determination, and - * linemode negotiation. - */ - telrcv(); - - ioctl(f, FIONBIO, (char *)&on); - ioctl(p, FIONBIO, (char *)&on); - -#if defined(SO_OOBINLINE) && defined(HAVE_SETSOCKOPT) - setsockopt(net, SOL_SOCKET, SO_OOBINLINE, - (void *)&on, sizeof on); -#endif /* defined(SO_OOBINLINE) */ - -#ifdef SIGTSTP - signal(SIGTSTP, SIG_IGN); -#endif -#ifdef SIGTTOU - /* - * Ignoring SIGTTOU keeps the kernel from blocking us - * in ttioct() in /sys/tty.c. - */ - signal(SIGTTOU, SIG_IGN); -#endif - - signal(SIGCHLD, cleanup); - -#ifdef TIOCNOTTY - { - int t; - t = open(_PATH_TTY, O_RDWR); - if (t >= 0) { - ioctl(t, TIOCNOTTY, (char *)0); - close(t); - } - } -#endif - - show_issue(); - /* - * Show banner that getty never gave. - * - * We put the banner in the pty input buffer. This way, it - * gets carriage return null processing, etc., just like all - * other pty --> client data. - */ - - if (getenv("USER")) - hostinfo = 0; - - IM = DEFAULT_IM; - he = 0; - edithost(he, host_name); - if (hostinfo && *IM) - putf(IM, ptyibuf2); - - if (pcc) - strncat(ptyibuf2, ptyip, pcc+1); - ptyip = ptyibuf2; - pcc = strlen(ptyip); - - DIAG(TD_REPORT, { - output_data("td: Entering processing loop\r\n"); - }); - - - nfd = ((f > p) ? f : p) + 1; - timeout = time(NULL) + 5; - for (;;) { - fd_set ibits, obits, xbits; - int c; - - /* wait for encryption to be turned on, but don't wait - indefinitely */ - if(!startslave_called && (!encrypt_delay() || timeout > time(NULL))){ - startslave_called = 1; - startslave(host, level, autoname); - } - - if (ncc < 0 && pcc < 0) - break; - - FD_ZERO(&ibits); - FD_ZERO(&obits); - FD_ZERO(&xbits); - - if (f >= FD_SETSIZE - || p >= FD_SETSIZE) - fatal(net, "fd too large"); - - /* - * Never look for input if there's still - * stuff in the corresponding output buffer - */ - if (nfrontp - nbackp || pcc > 0) { - FD_SET(f, &obits); - } else { - FD_SET(p, &ibits); - } - if (pfrontp - pbackp || ncc > 0) { - FD_SET(p, &obits); - } else { - FD_SET(f, &ibits); - } - if (!SYNCHing) { - FD_SET(f, &xbits); - } - if ((c = select(nfd, &ibits, &obits, &xbits, - (struct timeval *)0)) < 1) { - if (c == -1) { - if (errno == EINTR) { - continue; - } - } - sleep(5); - continue; - } - - /* - * Any urgent data? - */ - if (FD_ISSET(net, &xbits)) { - SYNCHing = 1; - } - - /* - * Something to read from the network... - */ - if (FD_ISSET(net, &ibits)) { -#ifndef SO_OOBINLINE - /* - * In 4.2 (and 4.3 beta) systems, the - * OOB indication and data handling in the kernel - * is such that if two separate TCP Urgent requests - * come in, one byte of TCP data will be overlaid. - * This is fatal for Telnet, but we try to live - * with it. - * - * In addition, in 4.2 (and...), a special protocol - * is needed to pick up the TCP Urgent data in - * the correct sequence. - * - * What we do is: if we think we are in urgent - * mode, we look to see if we are "at the mark". - * If we are, we do an OOB receive. If we run - * this twice, we will do the OOB receive twice, - * but the second will fail, since the second - * time we were "at the mark", but there wasn't - * any data there (the kernel doesn't reset - * "at the mark" until we do a normal read). - * Once we've read the OOB data, we go ahead - * and do normal reads. - * - * There is also another problem, which is that - * since the OOB byte we read doesn't put us - * out of OOB state, and since that byte is most - * likely the TELNET DM (data mark), we would - * stay in the TELNET SYNCH (SYNCHing) state. - * So, clocks to the rescue. If we've "just" - * received a DM, then we test for the - * presence of OOB data when the receive OOB - * fails (and AFTER we did the normal mode read - * to clear "at the mark"). - */ - if (SYNCHing) { - int atmark; - - ioctl(net, SIOCATMARK, (char *)&atmark); - if (atmark) { - ncc = recv(net, netibuf, sizeof (netibuf), MSG_OOB); - if ((ncc == -1) && (errno == EINVAL)) { - ncc = read(net, netibuf, sizeof (netibuf)); - if (sequenceIs(didnetreceive, gotDM)) { - SYNCHing = stilloob(net); - } - } - } else { - ncc = read(net, netibuf, sizeof (netibuf)); - } - } else { - ncc = read(net, netibuf, sizeof (netibuf)); - } - settimer(didnetreceive); -#else /* !defined(SO_OOBINLINE)) */ - ncc = read(net, netibuf, sizeof (netibuf)); -#endif /* !defined(SO_OOBINLINE)) */ - if (ncc < 0 && errno == EWOULDBLOCK) - ncc = 0; - else { - if (ncc <= 0) { - break; - } - netip = netibuf; - } - DIAG((TD_REPORT | TD_NETDATA), { - output_data("td: netread %d chars\r\n", ncc); - }); - DIAG(TD_NETDATA, printdata("nd", netip, ncc)); - } - - /* - * Something to read from the pty... - */ - if (FD_ISSET(p, &ibits)) { -#ifdef STREAMSPTY - if (really_stream) - pcc = readstream(p, ptyibuf, BUFSIZ); - else -#endif - pcc = read(p, ptyibuf, BUFSIZ); - - /* - * On some systems, if we try to read something - * off the master side before the slave side is - * opened, we get EIO. - */ - if (pcc < 0 && (errno == EWOULDBLOCK || -#ifdef EAGAIN - errno == EAGAIN || -#endif - errno == EIO)) { - pcc = 0; - } else { - if (pcc <= 0) - break; - if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) { - netclear(); /* clear buffer back */ -#ifndef NO_URGENT - /* - * There are client telnets on some - * operating systems get screwed up - * royally if we send them urgent - * mode data. - */ - 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) && - (ptyibuf[0] & - (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) { - int newflow = - ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0; - if (newflow != flowmode) { - flowmode = newflow; - output_data("%c%c%c%c%c%c", - IAC, SB, TELOPT_LFLOW, - flowmode ? LFLOW_ON - : LFLOW_OFF, - IAC, SE); - DIAG(TD_OPTIONS, printsub('>', - (unsigned char *)nfrontp-4, - 4);); - } - } - pcc--; - ptyip = ptyibuf+1; - } - } - - while (pcc > 0) { - if ((&netobuf[BUFSIZ] - nfrontp) < 3) - break; - c = *ptyip++ & 0377, pcc--; - if (c == IAC) - *nfrontp++ = c; - *nfrontp++ = c; - if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) { - if (pcc > 0 && ((*ptyip & 0377) == '\n')) { - *nfrontp++ = *ptyip++ & 0377; - pcc--; - } else - *nfrontp++ = '\0'; - } - } - - if (FD_ISSET(f, &obits) && (nfrontp - nbackp) > 0) - netflush(); - if (ncc > 0) - telrcv(); - if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0) - ptyflush(); - } - cleanup(0); -} - -#ifndef TCSIG -# ifdef TIOCSIG -# define TCSIG TIOCSIG -# endif -#endif - -#ifdef STREAMSPTY - - int flowison = -1; /* current state of flow: -1 is unknown */ - -int -readstream(int p, char *ibuf, int bufsize) -{ - int flags = 0; - int ret = 0; - struct termios *tsp; -#if 0 - struct termio *tp; -#endif - struct iocblk *ip; - char vstop, vstart; - int ixon; - int newflow; - - strbufc.maxlen = BUFSIZ; - strbufc.buf = (char *)ctlbuf; - strbufd.maxlen = bufsize-1; - strbufd.len = 0; - strbufd.buf = ibuf+1; - ibuf[0] = 0; - - ret = getmsg(p, &strbufc, &strbufd, &flags); - if (ret < 0) /* error of some sort -- probably EAGAIN */ - return(-1); - - if (strbufc.len <= 0 || ctlbuf[0] == M_DATA) { - /* data message */ - if (strbufd.len > 0) { /* real data */ - return(strbufd.len + 1); /* count header char */ - } else { - /* nothing there */ - errno = EAGAIN; - return(-1); - } - } - - /* - * It's a control message. Return 1, to look at the flag we set - */ - - switch (ctlbuf[0]) { - case M_FLUSH: - if (ibuf[1] & FLUSHW) - ibuf[0] = TIOCPKT_FLUSHWRITE; - return(1); - - case M_IOCTL: - ip = (struct iocblk *) (ibuf+1); - - switch (ip->ioc_cmd) { -#ifdef TCSETS - case TCSETS: - case TCSETSW: - case TCSETSF: - tsp = (struct termios *) - (ibuf+1 + sizeof(struct iocblk)); - vstop = tsp->c_cc[VSTOP]; - vstart = tsp->c_cc[VSTART]; - ixon = tsp->c_iflag & IXON; - break; -#endif -#if 0 - case TCSETA: - case TCSETAW: - case TCSETAF: - tp = (struct termio *) (ibuf+1 + sizeof(struct iocblk)); - vstop = tp->c_cc[VSTOP]; - vstart = tp->c_cc[VSTART]; - ixon = tp->c_iflag & IXON; - break; -#endif - default: - errno = EAGAIN; - return(-1); - } - - newflow = (ixon && (vstart == 021) && (vstop == 023)) ? 1 : 0; - if (newflow != flowison) { /* it's a change */ - flowison = newflow; - ibuf[0] = newflow ? TIOCPKT_DOSTOP : TIOCPKT_NOSTOP; - return(1); - } - } - - /* nothing worth doing anything about */ - errno = EAGAIN; - return(-1); -} -#endif /* STREAMSPTY */ - -/* - * Send interrupt to process on other side of pty. - * If it is in raw mode, just write NULL; - * otherwise, write intr char. - */ -void -interrupt() -{ - ptyflush(); /* half-hearted */ - -#if defined(STREAMSPTY) && defined(TIOCSIGNAL) - /* Streams PTY style ioctl to post a signal */ - if (really_stream) - { - int sig = SIGINT; - ioctl(ourpty, TIOCSIGNAL, &sig); - ioctl(ourpty, I_FLUSH, FLUSHR); - } -#else -#ifdef TCSIG - ioctl(ourpty, TCSIG, (char *)SIGINT); -#else /* TCSIG */ - init_termbuf(); - *pfrontp++ = slctab[SLC_IP].sptr ? - (unsigned char)*slctab[SLC_IP].sptr : '\177'; -#endif /* TCSIG */ -#endif -} - -/* - * Send quit to process on other side of pty. - * If it is in raw mode, just write NULL; - * otherwise, write quit char. - */ -void -sendbrk() -{ - ptyflush(); /* half-hearted */ -#ifdef TCSIG - ioctl(ourpty, TCSIG, (char *)SIGQUIT); -#else /* TCSIG */ - init_termbuf(); - *pfrontp++ = slctab[SLC_ABORT].sptr ? - (unsigned char)*slctab[SLC_ABORT].sptr : '\034'; -#endif /* TCSIG */ -} - -void -sendsusp() -{ -#ifdef SIGTSTP - ptyflush(); /* half-hearted */ -# ifdef TCSIG - ioctl(ourpty, TCSIG, (char *)SIGTSTP); -# else /* TCSIG */ - *pfrontp++ = slctab[SLC_SUSP].sptr ? - (unsigned char)*slctab[SLC_SUSP].sptr : '\032'; -# endif /* TCSIG */ -#endif /* SIGTSTP */ -} - -/* - * When we get an AYT, if ^T is enabled, use that. Otherwise, - * just send back "[Yes]". - */ -void -recv_ayt() -{ -#if defined(SIGINFO) && defined(TCSIG) - if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) { - ioctl(ourpty, TCSIG, (char *)SIGINFO); - return; - } -#endif - output_data("\r\n[Yes]\r\n"); -} - -void -doeof() -{ - init_termbuf(); - - *pfrontp++ = slctab[SLC_EOF].sptr ? - (unsigned char)*slctab[SLC_EOF].sptr : '\004'; -} diff --git a/crypto/kerberosIV/appl/telnet/telnetd/telnetd.h b/crypto/kerberosIV/appl/telnet/telnetd/telnetd.h deleted file mode 100644 index 955ca1a..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/telnetd.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)telnetd.h 8.1 (Berkeley) 6/4/93 - */ -/* $FreeBSD$ */ - - -#include <config.h> - -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#elif defined(HAVE_SYS_TIME_H) -#include <sys/time.h> -#else -#include <time.h> -#endif - -#ifdef HAVE_SYS_RESOURCE_H -#include <sys/resource.h> -#endif /* HAVE_SYS_RESOURCE_H */ - -#ifdef HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_SYS_FILE_H -#include <sys/file.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -/* including both <sys/ioctl.h> and <termios.h> in SunOS 4 generates a - lot of warnings */ - -#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40 -#include <sys/ioctl.h> -#endif -#ifdef HAVE_SYS_FILIO_H -#include <sys/filio.h> -#endif - -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_NETINET_IN6_H -#include <netinet/in6.h> -#endif -#ifdef HAVE_NETINET6_IN6_H -#include <netinet6/in6.h> -#endif - -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif - -#include <signal.h> -#include <errno.h> -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_SYSLOG_H -#include <syslog.h> -#endif -#include <ctype.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <termios.h> - -#ifdef HAVE_PTY_H -#include <pty.h> -#endif - -#include "defs.h" - -#ifndef _POSIX_VDISABLE -# ifdef VDISABLE -# define _POSIX_VDISABLE VDISABLE -# else -# define _POSIX_VDISABLE ((unsigned char)'\377') -# endif -#endif - - -#ifdef HAVE_SYS_PTY_H -#include <sys/pty.h> -#endif -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#ifdef HAVE_SYS_PTYIO_H -#include <sys/ptyio.h> -#endif - -#ifdef HAVE_SYS_UTSNAME_H -#include <sys/utsname.h> -#endif - -#ifdef HAVE_PATHS_H -#include <paths.h> -#endif - -#ifdef HAVE_ARPA_TELNET_H -#include <arpa/telnet.h> -#endif - -#include "ext.h" - -#ifdef SOCKS -#include <socks.h> -/* This doesn't belong here. */ -struct tm *localtime(const time_t *); -struct hostent *gethostbyname(const char *); -#endif - -#ifdef KRB4 -#define OPENSSL_DES_LIBDES_COMPATIBILITY -#include <openssl/des.h> -#include <krb.h> -#endif - -#ifdef AUTHENTICATION -#include <libtelnet/auth.h> -#include <libtelnet/misc.h> -#ifdef ENCRYPTION -#include <libtelnet/encrypt.h> -#endif -#endif - -#ifdef HAVE_LIBUTIL_H -#include <libutil.h> -#endif - -#include <roken.h> - -/* Don't use the system login, use our version instead */ - -/* BINDIR should be defined somewhere else... */ - -#ifndef BINDIR -#define BINDIR "/usr/athena/bin" -#endif - -#undef _PATH_LOGIN -#define _PATH_LOGIN BINDIR "/login" - -/* fallbacks */ - -#ifndef _PATH_DEV -#define _PATH_DEV "/dev/" -#endif - -#ifndef _PATH_TTY -#define _PATH_TTY "/dev/tty" -#endif /* _PATH_TTY */ - -#ifdef DIAGNOSTICS -#define DIAG(a,b) if (diagnostic & (a)) b -#else -#define DIAG(a,b) -#endif - -/* other external variables */ -extern char **environ; - -/* prototypes */ - -/* appends data to nfrontp and advances */ -int output_data (const char *format, ...) -#ifdef __GNUC__ -__attribute__ ((format (printf, 1, 2))) -#endif -; diff --git a/crypto/kerberosIV/appl/telnet/telnetd/termstat.c b/crypto/kerberosIV/appl/telnet/telnetd/termstat.c deleted file mode 100644 index 80ee145..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/termstat.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "telnetd.h" - -RCSID("$Id: termstat.c,v 1.11 1997/05/11 06:30:04 assar Exp $"); - -/* - * local variables - */ -int def_tspeed = -1, def_rspeed = -1; -#ifdef TIOCSWINSZ -int def_row = 0, def_col = 0; -#endif - -/* - * flowstat - * - * Check for changes to flow control - */ -void -flowstat() -{ - if (his_state_is_will(TELOPT_LFLOW)) { - if (tty_flowmode() != flowmode) { - flowmode = tty_flowmode(); - output_data("%c%c%c%c%c%c", - IAC, SB, TELOPT_LFLOW, - flowmode ? LFLOW_ON : LFLOW_OFF, - IAC, SE); - } - if (tty_restartany() != restartany) { - restartany = tty_restartany(); - output_data("%c%c%c%c%c%c", - IAC, SB, TELOPT_LFLOW, - restartany ? LFLOW_RESTART_ANY - : LFLOW_RESTART_XON, - IAC, SE); - } - } -} - -/* - * clientstat - * - * Process linemode related requests from the client. - * Client can request a change to only one of linemode, editmode or slc's - * at a time, and if using kludge linemode, then only linemode may be - * affected. - */ -void -clientstat(int code, int parm1, int parm2) -{ - void netflush(); - - /* - * Get a copy of terminal characteristics. - */ - init_termbuf(); - - /* - * Process request from client. code tells what it is. - */ - switch (code) { - case TELOPT_NAWS: -#ifdef TIOCSWINSZ - { - struct winsize ws; - - def_col = parm1; - def_row = parm2; - - /* - * Change window size as requested by client. - */ - - ws.ws_col = parm1; - ws.ws_row = parm2; - ioctl(ourpty, TIOCSWINSZ, (char *)&ws); - } -#endif /* TIOCSWINSZ */ - - break; - - case TELOPT_TSPEED: - { - def_tspeed = parm1; - def_rspeed = parm2; - /* - * Change terminal speed as requested by client. - * We set the receive speed first, so that if we can't - * store seperate receive and transmit speeds, the transmit - * speed will take precedence. - */ - tty_rspeed(parm2); - tty_tspeed(parm1); - set_termbuf(); - - break; - - } /* end of case TELOPT_TSPEED */ - - default: - /* What? */ - break; - } /* end of switch */ - - netflush(); - -} diff --git a/crypto/kerberosIV/appl/telnet/telnetd/utility.c b/crypto/kerberosIV/appl/telnet/telnetd/utility.c deleted file mode 100644 index ff5192e..0000000 --- a/crypto/kerberosIV/appl/telnet/telnetd/utility.c +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#define PRINTOPTIONS -#include "telnetd.h" - -RCSID("$Id: utility.c,v 1.22.2.1 2000/10/10 13:12:34 assar Exp $"); - -/* - * utility functions performing io related tasks - */ - -/* - * ttloop - * - * A small subroutine to flush the network output buffer, get some - * data from the network, and pass it through the telnet state - * machine. We also flush the pty input buffer (by dropping its data) - * if it becomes too full. - * - * return 0 if OK or 1 if interrupted by a signal. - */ - -int -ttloop(void) -{ - void netflush(void); - - DIAG(TD_REPORT, { - output_data("td: ttloop\r\n"); - }); - if (nfrontp-nbackp) - netflush(); - ncc = read(net, netibuf, sizeof netibuf); - if (ncc < 0) { - if (errno == EINTR) - return 1; - syslog(LOG_INFO, "ttloop: read: %m\n"); - exit(1); - } else if (ncc == 0) { - syslog(LOG_INFO, "ttloop: peer died\n"); - exit(1); - } - DIAG(TD_REPORT, { - output_data("td: ttloop read %d chars\r\n", ncc); - }); - netip = netibuf; - telrcv(); /* state machine */ - if (ncc > 0) { - pfrontp = pbackp = ptyobuf; - telrcv(); - } - return 0; -} /* end of ttloop */ - -/* - * Check a descriptor to see if out of band data exists on it. - */ -int -stilloob(int s) -{ - static struct timeval timeout = { 0 }; - fd_set excepts; - int value; - - if (s >= FD_SETSIZE) - fatal(ourpty, "fd too large"); - - do { - FD_ZERO(&excepts); - FD_SET(s, &excepts); - value = select(s+1, 0, 0, &excepts, &timeout); - } while ((value == -1) && (errno == EINTR)); - - if (value < 0) { - fatalperror(ourpty, "select"); - } - if (FD_ISSET(s, &excepts)) { - return 1; - } else { - return 0; - } -} - -void -ptyflush(void) -{ - int n; - - if ((n = pfrontp - pbackp) > 0) { - DIAG((TD_REPORT | TD_PTYDATA), { - output_data("td: ptyflush %d chars\r\n", n); - }); - DIAG(TD_PTYDATA, printdata("pd", pbackp, n)); - n = write(ourpty, pbackp, n); - } - if (n < 0) { - if (errno == EWOULDBLOCK || errno == EINTR) - return; - cleanup(0); - } - pbackp += n; - if (pbackp == pfrontp) - pbackp = pfrontp = ptyobuf; -} - -/* - * nextitem() - * - * Return the address of the next "item" in the TELNET data - * stream. This will be the address of the next character if - * the current address is a user data character, or it will - * be the address of the character following the TELNET command - * if the current address is a TELNET IAC ("I Am a Command") - * character. - */ -char * -nextitem(char *current) -{ - if ((*current&0xff) != IAC) { - return current+1; - } - switch (*(current+1)&0xff) { - case DO: - case DONT: - case WILL: - case WONT: - return current+3; - case SB:{ - /* loop forever looking for the SE */ - char *look = current+2; - - for (;;) { - if ((*look++&0xff) == IAC) { - if ((*look++&0xff) == SE) { - return look; - } - } - } - } - default: - return current+2; - } -} - - -/* - * netclear() - * - * We are about to do a TELNET SYNCH operation. Clear - * the path to the network. - * - * Things are a bit tricky since we may have sent the first - * byte or so of a previous TELNET command into the network. - * So, we have to scan the network buffer from the beginning - * until we are up to where we want to be. - * - * A side effect of what we do, just to keep things - * simple, is to clear the urgent data pointer. The principal - * caller should be setting the urgent data pointer AFTER calling - * us in any case. - */ -void -netclear(void) -{ - char *thisitem, *next; - char *good; -#define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \ - ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL)) - -#ifdef ENCRYPTION - thisitem = nclearto > netobuf ? nclearto : netobuf; -#else - thisitem = netobuf; -#endif - - while ((next = nextitem(thisitem)) <= nbackp) { - thisitem = next; - } - - /* Now, thisitem is first before/at boundary. */ - -#ifdef ENCRYPTION - good = nclearto > netobuf ? nclearto : netobuf; -#else - good = netobuf; /* where the good bytes go */ -#endif - - while (nfrontp > thisitem) { - if (wewant(thisitem)) { - int length; - - next = thisitem; - do { - next = nextitem(next); - } while (wewant(next) && (nfrontp > next)); - length = next-thisitem; - memmove(good, thisitem, length); - good += length; - thisitem = next; - } else { - thisitem = nextitem(thisitem); - } - } - - nbackp = netobuf; - nfrontp = good; /* next byte to be sent */ - neturg = 0; -} /* end of netclear */ - -/* - * netflush - * Send as much data as possible to the network, - * handling requests for urgent data. - */ -void -netflush(void) -{ - int n; - extern int not42; - - if ((n = nfrontp - nbackp) > 0) { - DIAG(TD_REPORT, - { n += output_data("td: netflush %d chars\r\n", n); - }); -#ifdef ENCRYPTION - if (encrypt_output) { - char *s = nclearto ? nclearto : nbackp; - if (nfrontp - s > 0) { - (*encrypt_output)((unsigned char *)s, nfrontp-s); - nclearto = nfrontp; - } - } -#endif - /* - * if no urgent data, or if the other side appears to be an - * old 4.2 client (and thus unable to survive TCP urgent data), - * write the entire buffer in non-OOB mode. - */ -#if 1 /* remove this to make it work between solaris 2.6 and linux */ - if ((neturg == 0) || (not42 == 0)) { -#endif - n = write(net, nbackp, n); /* normal write */ -#if 1 /* remove this to make it work between solaris 2.6 and linux */ - } else { - n = neturg - nbackp; - /* - * In 4.2 (and 4.3) systems, there is some question about - * what byte in a sendOOB operation is the "OOB" data. - * To make ourselves compatible, we only send ONE byte - * out of band, the one WE THINK should be OOB (though - * we really have more the TCP philosophy of urgent data - * rather than the Unix philosophy of OOB data). - */ - if (n > 1) { - n = send(net, nbackp, n-1, 0); /* send URGENT all by itself */ - } else { - n = send(net, nbackp, n, MSG_OOB); /* URGENT data */ - } - } -#endif - } - if (n < 0) { - if (errno == EWOULDBLOCK || errno == EINTR) - return; - cleanup(0); - } - nbackp += n; -#ifdef ENCRYPTION - if (nbackp > nclearto) - nclearto = 0; -#endif - if (nbackp >= neturg) { - neturg = 0; - } - if (nbackp == nfrontp) { - nbackp = nfrontp = netobuf; -#ifdef ENCRYPTION - nclearto = 0; -#endif - } - return; -} - - -/* - * writenet - * - * Just a handy little function to write a bit of raw data to the net. - * It will force a transmit of the buffer if necessary - * - * arguments - * ptr - A pointer to a character string to write - * len - How many bytes to write - */ -void -writenet(unsigned char *ptr, int len) -{ - /* flush buffer if no room for new data) */ - while ((&netobuf[BUFSIZ] - nfrontp) < len) { - /* if this fails, don't worry, buffer is a little big */ - netflush(); - } - - memmove(nfrontp, ptr, len); - nfrontp += len; -} - - -/* - * miscellaneous functions doing a variety of little jobs follow ... - */ - - -void fatal(int f, char *msg) -{ - char buf[BUFSIZ]; - - snprintf(buf, sizeof(buf), "telnetd: %s.\r\n", msg); -#ifdef ENCRYPTION - if (encrypt_output) { - /* - * Better turn off encryption first.... - * Hope it flushes... - */ - encrypt_send_end(); - netflush(); - } -#endif - write(f, buf, (int)strlen(buf)); - sleep(1); /*XXX*/ - exit(1); -} - -void -fatalperror(int f, const char *msg) -{ - char buf[BUFSIZ]; - - snprintf(buf, sizeof(buf), "%s: %s", msg, strerror(errno)); - fatal(f, buf); -} - -char editedhost[32]; - -void edithost(char *pat, char *host) -{ - char *res = editedhost; - - if (!pat) - pat = ""; - while (*pat) { - switch (*pat) { - - case '#': - if (*host) - host++; - break; - - case '@': - if (*host) - *res++ = *host++; - break; - - default: - *res++ = *pat; - break; - } - if (res == &editedhost[sizeof editedhost - 1]) { - *res = '\0'; - return; - } - pat++; - } - if (*host) - strlcpy (res, host, - sizeof editedhost - (res - editedhost)); - else - *res = '\0'; - editedhost[sizeof editedhost - 1] = '\0'; -} - -static char *putlocation; - -void -putstr(char *s) -{ - - while (*s) - putchr(*s++); -} - -void -putchr(int cc) -{ - *putlocation++ = cc; -} - -/* - * This is split on two lines so that SCCS will not see the M - * between two % signs and expand it... - */ -static char fmtstr[] = { "%l:%M" "%P on %A, %d %B %Y" }; - -void putf(char *cp, char *where) -{ -#ifdef HAVE_UNAME - struct utsname name; -#endif - char *slash; - time_t t; - char db[100]; - - /* if we don't have uname, set these to sensible values */ - char *sysname = "Unix", - *machine = "", - *release = "", - *version = ""; - -#ifdef HAVE_UNAME - uname(&name); - sysname=name.sysname; - machine=name.machine; - release=name.release; - version=name.version; -#endif - - putlocation = where; - - while (*cp) { - if (*cp != '%') { - putchr(*cp++); - continue; - } - switch (*++cp) { - - case 't': -#ifdef STREAMSPTY - /* names are like /dev/pts/2 -- we want pts/2 */ - slash = strchr(line+1, '/'); -#else - slash = strrchr(line, '/'); -#endif - if (slash == (char *) 0) - putstr(line); - else - putstr(&slash[1]); - break; - - case 'h': - putstr(editedhost); - break; - - case 's': - putstr(sysname); - break; - - case 'm': - putstr(machine); - break; - - case 'r': - putstr(release); - break; - - case 'v': - putstr(version); - break; - - case 'd': - time(&t); - strftime(db, sizeof(db), fmtstr, localtime(&t)); - putstr(db); - break; - - case '%': - putchr('%'); - break; - } - cp++; - } -} - -#ifdef DIAGNOSTICS -/* - * Print telnet options and commands in plain text, if possible. - */ -void -printoption(char *fmt, int option) -{ - if (TELOPT_OK(option)) - output_data("%s %s\r\n", - fmt, - TELOPT(option)); - else if (TELCMD_OK(option)) - output_data("%s %s\r\n", - fmt, - TELCMD(option)); - else - output_data("%s %d\r\n", - fmt, - option); - return; -} - -void -printsub(int direction, unsigned char *pointer, int length) - /* '<' or '>' */ - /* where suboption data sits */ - /* length of suboption data */ -{ - int i = 0; - unsigned char buf[512]; - - if (!(diagnostic & TD_OPTIONS)) - return; - - if (direction) { - output_data("td: %s suboption ", - direction == '<' ? "recv" : "send"); - if (length >= 3) { - int j; - - i = pointer[length-2]; - j = pointer[length-1]; - - if (i != IAC || j != SE) { - output_data("(terminated by "); - if (TELOPT_OK(i)) - output_data("%s ", - TELOPT(i)); - else if (TELCMD_OK(i)) - output_data("%s ", - TELCMD(i)); - else - output_data("%d ", - i); - if (TELOPT_OK(j)) - output_data("%s", - TELOPT(j)); - else if (TELCMD_OK(j)) - output_data("%s", - TELCMD(j)); - else - output_data("%d", - j); - output_data(", not IAC SE!) "); - } - } - length -= 2; - } - if (length < 1) { - output_data("(Empty suboption??\?)"); - return; - } - switch (pointer[0]) { - case TELOPT_TTYPE: - output_data("TERMINAL-TYPE "); - switch (pointer[1]) { - case TELQUAL_IS: - output_data("IS \"%.*s\"", - length-2, - (char *)pointer+2); - break; - case TELQUAL_SEND: - output_data("SEND"); - break; - default: - output_data("- unknown qualifier %d (0x%x).", - pointer[1], pointer[1]); - } - break; - case TELOPT_TSPEED: - output_data("TERMINAL-SPEED"); - if (length < 2) { - output_data(" (empty suboption??\?)"); - break; - } - switch (pointer[1]) { - case TELQUAL_IS: - output_data(" IS %.*s", length-2, (char *)pointer+2); - break; - default: - if (pointer[1] == 1) - output_data(" SEND"); - else - output_data(" %d (unknown)", pointer[1]); - for (i = 2; i < length; i++) { - output_data(" ?%d?", pointer[i]); - } - break; - } - break; - - case TELOPT_LFLOW: - output_data("TOGGLE-FLOW-CONTROL"); - if (length < 2) { - output_data(" (empty suboption??\?)"); - break; - } - switch (pointer[1]) { - case LFLOW_OFF: - output_data(" OFF"); - break; - case LFLOW_ON: - output_data(" ON"); - break; - case LFLOW_RESTART_ANY: - output_data(" RESTART-ANY"); - break; - case LFLOW_RESTART_XON: - output_data(" RESTART-XON"); - break; - default: - output_data(" %d (unknown)", - pointer[1]); - } - for (i = 2; i < length; i++) { - output_data(" ?%d?", - pointer[i]); - } - break; - - case TELOPT_NAWS: - output_data("NAWS"); - if (length < 2) { - output_data(" (empty suboption??\?)"); - break; - } - if (length == 2) { - output_data(" ?%d?", - pointer[1]); - break; - } - output_data(" %u %u(%u)", - pointer[1], - pointer[2], - (((unsigned int)pointer[1])<<8) + pointer[2]); - if (length == 4) { - output_data(" ?%d?", - pointer[3]); - break; - } - output_data(" %u %u(%u)", - pointer[3], - pointer[4], - (((unsigned int)pointer[3])<<8) + pointer[4]); - for (i = 5; i < length; i++) { - output_data(" ?%d?", - pointer[i]); - } - break; - - case TELOPT_LINEMODE: - output_data("LINEMODE "); - if (length < 2) { - output_data(" (empty suboption??\?)"); - break; - } - switch (pointer[1]) { - case WILL: - output_data("WILL "); - goto common; - case WONT: - output_data("WONT "); - goto common; - case DO: - output_data("DO "); - goto common; - case DONT: - output_data("DONT "); - common: - if (length < 3) { - output_data("(no option??\?)"); - break; - } - switch (pointer[2]) { - case LM_FORWARDMASK: - output_data("Forward Mask"); - for (i = 3; i < length; i++) { - output_data(" %x", pointer[i]); - } - break; - default: - output_data("%d (unknown)", - pointer[2]); - for (i = 3; i < length; i++) { - output_data(" %d", - pointer[i]); - } - break; - } - break; - - case LM_SLC: - output_data("SLC"); - for (i = 2; i < length - 2; i += 3) { - if (SLC_NAME_OK(pointer[i+SLC_FUNC])) - output_data(" %s", - SLC_NAME(pointer[i+SLC_FUNC])); - else - output_data(" %d", - pointer[i+SLC_FUNC]); - switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { - case SLC_NOSUPPORT: - output_data(" NOSUPPORT"); - break; - case SLC_CANTCHANGE: - output_data(" CANTCHANGE"); - break; - case SLC_VARIABLE: - output_data(" VARIABLE"); - break; - case SLC_DEFAULT: - output_data(" DEFAULT"); - break; - } - output_data("%s%s%s", - pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", - pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", - pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); - if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| - SLC_FLUSHOUT| SLC_LEVELBITS)) { - output_data("(0x%x)", - pointer[i+SLC_FLAGS]); - } - output_data(" %d;", - pointer[i+SLC_VALUE]); - if ((pointer[i+SLC_VALUE] == IAC) && - (pointer[i+SLC_VALUE+1] == IAC)) - i++; - } - for (; i < length; i++) { - output_data(" ?%d?", - pointer[i]); - } - break; - - case LM_MODE: - output_data("MODE "); - if (length < 3) { - output_data("(no mode??\?)"); - break; - } - { - char tbuf[32]; - snprintf(tbuf, - sizeof(tbuf), - "%s%s%s%s%s", - pointer[2]&MODE_EDIT ? "|EDIT" : "", - pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", - pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", - pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", - pointer[2]&MODE_ACK ? "|ACK" : ""); - output_data("%s", - tbuf[1] ? &tbuf[1] : "0"); - } - if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) { - output_data(" (0x%x)", - pointer[2]); - } - for (i = 3; i < length; i++) { - output_data(" ?0x%x?", - pointer[i]); - } - break; - default: - output_data("%d (unknown)", - pointer[1]); - for (i = 2; i < length; i++) { - output_data(" %d", pointer[i]); - } - } - break; - - case TELOPT_STATUS: { - char *cp; - int j, k; - - output_data("STATUS"); - - switch (pointer[1]) { - default: - if (pointer[1] == TELQUAL_SEND) - output_data(" SEND"); - else - output_data(" %d (unknown)", - pointer[1]); - for (i = 2; i < length; i++) { - output_data(" ?%d?", - pointer[i]); - } - break; - case TELQUAL_IS: - output_data(" IS\r\n"); - - for (i = 2; i < length; i++) { - switch(pointer[i]) { - case DO: cp = "DO"; goto common2; - case DONT: cp = "DONT"; goto common2; - case WILL: cp = "WILL"; goto common2; - case WONT: cp = "WONT"; goto common2; - common2: - i++; - if (TELOPT_OK(pointer[i])) - output_data(" %s %s", - cp, - TELOPT(pointer[i])); - else - output_data(" %s %d", - cp, - pointer[i]); - - output_data("\r\n"); - break; - - case SB: - output_data(" SB "); - i++; - j = k = i; - while (j < length) { - if (pointer[j] == SE) { - if (j+1 == length) - break; - if (pointer[j+1] == SE) - j++; - else - break; - } - pointer[k++] = pointer[j++]; - } - printsub(0, &pointer[i], k - i); - if (i < length) { - output_data(" SE"); - i = j; - } else - i = j - 1; - - output_data("\r\n"); - - break; - - default: - output_data(" %d", - pointer[i]); - break; - } - } - break; - } - break; - } - - case TELOPT_XDISPLOC: - output_data("X-DISPLAY-LOCATION "); - switch (pointer[1]) { - case TELQUAL_IS: - output_data("IS \"%.*s\"", - length-2, - (char *)pointer+2); - break; - case TELQUAL_SEND: - output_data("SEND"); - break; - default: - output_data("- unknown qualifier %d (0x%x).", - pointer[1], pointer[1]); - } - break; - - case TELOPT_NEW_ENVIRON: - output_data("NEW-ENVIRON "); - goto env_common1; - case TELOPT_OLD_ENVIRON: - output_data("OLD-ENVIRON"); - env_common1: - switch (pointer[1]) { - case TELQUAL_IS: - output_data("IS "); - goto env_common; - case TELQUAL_SEND: - output_data("SEND "); - goto env_common; - case TELQUAL_INFO: - output_data("INFO "); - env_common: - { - int noquote = 2; - for (i = 2; i < length; i++ ) { - switch (pointer[i]) { - case NEW_ENV_VAR: - output_data("\" VAR " + noquote); - noquote = 2; - break; - - case NEW_ENV_VALUE: - output_data("\" VALUE " + noquote); - noquote = 2; - break; - - case ENV_ESC: - output_data("\" ESC " + noquote); - noquote = 2; - break; - - case ENV_USERVAR: - output_data("\" USERVAR " + noquote); - noquote = 2; - break; - - default: - if (isprint(pointer[i]) && pointer[i] != '"') { - if (noquote) { - output_data ("\""); - noquote = 0; - } - output_data ("%c", pointer[i]); - } else { - output_data("\" %03o " + noquote, - pointer[i]); - noquote = 2; - } - break; - } - } - if (!noquote) - output_data ("\""); - break; - } - } - break; - -#ifdef 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"); - - 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: - i = 2; - output_data(" NAME \"%.*s\"", - length - 2, - pointer); - break; - - default: - for (i = 2; i < length; i++) { - output_data(" ?%d?", - pointer[i]); - } - break; - } - break; -#endif - -#ifdef ENCRYPTION - case TELOPT_ENCRYPT: - output_data("ENCRYPT"); - if (length < 2) { - output_data(" (empty suboption?)"); - break; - } - switch (pointer[1]) { - case ENCRYPT_START: - output_data(" START"); - break; - - case ENCRYPT_END: - output_data(" END"); - break; - - case ENCRYPT_REQSTART: - output_data(" REQUEST-START"); - break; - - case ENCRYPT_REQEND: - output_data(" REQUEST-END"); - break; - - case ENCRYPT_IS: - case ENCRYPT_REPLY: - output_data(" %s ", - (pointer[1] == ENCRYPT_IS) ? - "IS" : "REPLY"); - if (length < 3) { - output_data(" (partial suboption?)"); - break; - } - if (ENCTYPE_NAME_OK(pointer[2])) - output_data("%s ", - ENCTYPE_NAME(pointer[2])); - else - output_data(" %d (unknown)", - pointer[2]); - - encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); - output_data("%s", - buf); - break; - - case ENCRYPT_SUPPORT: - i = 2; - output_data(" SUPPORT "); - while (i < length) { - if (ENCTYPE_NAME_OK(pointer[i])) - output_data("%s ", - ENCTYPE_NAME(pointer[i])); - else - output_data("%d ", - pointer[i]); - i++; - } - break; - - case ENCRYPT_ENC_KEYID: - output_data(" ENC_KEYID %d", pointer[1]); - goto encommon; - - case ENCRYPT_DEC_KEYID: - output_data(" DEC_KEYID %d", pointer[1]); - goto encommon; - - default: - output_data(" %d (unknown)", pointer[1]); - encommon: - 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])); - else - output_data("%d (unknown)", - pointer[i]); - for (i = 1; i < length; i++) { - output_data(" %d", pointer[i]); - } - break; - } - output_data("\r\n"); -} - -/* - * Dump a data buffer in hex and ascii to the output data stream. - */ -void -printdata(char *tag, char *ptr, int cnt) -{ - int i; - char xbuf[30]; - - while (cnt) { - /* flush net output buffer if no room for new data) */ - if ((&netobuf[BUFSIZ] - nfrontp) < 80) { - netflush(); - } - - /* add a line of output */ - output_data("%s: ", tag); - for (i = 0; i < 20 && cnt; i++) { - output_data("%02x", *ptr); - if (isprint(*ptr)) { - xbuf[i] = *ptr; - } else { - xbuf[i] = '.'; - } - if (i % 2) { - output_data(" "); - } - cnt--; - ptr++; - } - xbuf[i] = '\0'; - output_data(" %s\r\n", xbuf); - } -} -#endif /* DIAGNOSTICS */ |