telnetd cleanup

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@1695 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
1997-05-11 06:30:05 +00:00
parent 5bc01fea42
commit 5da8f7da41
11 changed files with 3751 additions and 5702 deletions

View File

@@ -31,18 +31,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "telnetd.h"
#ifdef SOCKS
#include <socks.h>
#endif
RCSID("$Id$"); RCSID("$Id$");
#if defined(AUTHENTICATION) || defined(ENCRYPTION) #ifdef AUTHENTICATION
#include "telnetd.h"
#include <libtelnet/misc.h>
int int
net_write(unsigned char *str, int len) net_write(unsigned char *str, int len)
{ {
if (nfrontp + len < netobuf + BUFSIZ) { if (nfrontp + len < netobuf + BUFSIZ) {
@@ -53,10 +48,10 @@ net_write(unsigned char *str, int len)
return(0); return(0);
} }
void void
net_encrypt(void) net_encrypt(void)
{ {
#if defined(ENCRYPTION) #ifdef ENCRYPTION
char *s = (nclearto > nbackp) ? nclearto : nbackp; char *s = (nclearto > nbackp) ? nclearto : nbackp;
if (s < nfrontp && encrypt_output) { if (s < nfrontp && encrypt_output) {
(*encrypt_output)((unsigned char *)s, nfrontp - s); (*encrypt_output)((unsigned char *)s, nfrontp - s);
@@ -65,21 +60,21 @@ net_encrypt(void)
#endif #endif
} }
int int
telnet_spin(void) telnet_spin(void)
{ {
ttloop(); ttloop();
return(0); return(0);
} }
char * char *
telnet_getenv(char *val) telnet_getenv(char *val)
{ {
extern char *getenv(const char *); extern char *getenv(const char *);
return(getenv(val)); return(getenv(val));
} }
char * char *
telnet_gets(char *prompt, char *result, int length, int echo) telnet_gets(char *prompt, char *result, int length, int echo)
{ {
return NULL; return NULL;

View File

@@ -36,8 +36,9 @@
/* /*
* Telnet server defines * Telnet server defines
*/ */
#include <sys/types.h>
#include <sys/param.h> #ifndef __DEFS_H__
#define __DEFS_H__
#ifndef BSD #ifndef BSD
# define BSD 43 # define BSD 43
@@ -49,82 +50,6 @@
#define SLC_NAMES #define SLC_NAMES
#endif #endif
#include <sys/socket.h>
#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 */
#ifndef CRAY
#include <sys/wait.h>
#endif /* CRAY */
#include <fcntl.h>
#include <sys/file.h>
#include <sys/stat.h>
/* including both <sys/ioctl.h> and <termios.h> in SunOS 4 generates a
lot of warnings */
#if defined(HAVE_SYS_IOCTL_H) && SunOS != 4
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <netdb.h>
#include <syslog.h>
#ifndef LOG_DAEMON
#define LOG_DAEMON 0
#endif
#ifndef LOG_ODELAY
#define LOG_ODELAY 0
#endif
#include <ctype.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#ifndef _POSIX_VDISABLE
# ifdef VDISABLE
# define _POSIX_VDISABLE VDISABLE
# else
# define _POSIX_VDISABLE ((unsigned char)'\377')
# endif
#endif
#ifdef CRAY
# ifdef CRAY1
# include <sys/pty.h>
# ifndef FD_ZERO
# include <sys/select.h>
# endif /* FD_ZERO */
# endif /* CRAY1 */
#include <memory.h>
#endif /* CRAY */
#ifdef __hpux
#include <sys/ptyio.h>
#endif
#if !defined(TIOCSCTTY) && defined(TCSETCTTY) #if !defined(TIOCSCTTY) && defined(TCSETCTTY)
# define TIOCSCTTY TCSETCTTY # define TIOCSCTTY TCSETCTTY
#endif #endif
@@ -156,7 +81,7 @@ typedef struct fd_set { int fds_bits[1]; } fd_set;
* I/O data buffers defines * I/O data buffers defines
*/ */
#define NETSLOP 64 #define NETSLOP 64
#ifdef CRAY #ifdef _CRAY
#undef BUFSIZ #undef BUFSIZ
#define BUFSIZ 2048 #define BUFSIZ 2048
#endif #endif
@@ -169,15 +94,6 @@ typedef struct fd_set { int fds_bits[1]; } fd_set;
#define settimer(x) (clocks.x = ++clocks.system) #define settimer(x) (clocks.x = ++clocks.system)
#define sequenceIs(x,y) (clocks.x < clocks.y) #define sequenceIs(x,y) (clocks.x < clocks.y)
/*
* Linemode support states, in decreasing order of importance
*/
#define REAL_LINEMODE 0x04
#define KLUDGE_OK 0x03
#define NO_AUTOKLUDGE 0x02
#define KLUDGE_LINEMODE 0x01
#define NO_LINEMODE 0x00
/* /*
* Structures of information for each special character function. * Structures of information for each special character function.
*/ */
@@ -281,3 +197,5 @@ typedef struct {
#define his_will_wont_is_changing my_do_dont_is_changing #define his_will_wont_is_changing my_do_dont_is_changing
#define his_do_dont_is_changing my_will_wont_is_changing #define his_do_dont_is_changing my_will_wont_is_changing
#endif /* __DEFS_H__ */

View File

@@ -35,29 +35,22 @@
/* $Id$ */ /* $Id$ */
#ifndef __EXT_H__
#define __EXT_H__
/* /*
* Telnet server variable declarations * Telnet server variable declarations
*/ */
extern char options[256]; extern char options[256];
extern char do_dont_resp[256]; extern char do_dont_resp[256];
extern char will_wont_resp[256]; extern char will_wont_resp[256];
extern int linemode; /* linemode on/off */
#ifdef LINEMODE
extern int uselinemode; /* what linemode to use (on/off) */
extern int editmode; /* edit modes in use */
extern int useeditmode; /* edit modes to use */
extern int alwayslinemode; /* command line option */
# ifdef KLUDGELINEMODE
extern int lmodetype; /* Client support for linemode */
# endif /* KLUDGELINEMODE */
#endif /* LINEMODE */
extern int flowmode; /* current flow control state */ extern int flowmode; /* current flow control state */
extern int restartany; /* restart output on any character state */ extern int restartany; /* restart output on any character state */
#ifdef DIAGNOSTICS #ifdef DIAGNOSTICS
extern int diagnostic; /* telnet diagnostic capabilities */ extern int diagnostic; /* telnet diagnostic capabilities */
#endif /* DIAGNOSTICS */ #endif /* DIAGNOSTICS */
extern int require_otp; extern int require_otp;
#if defined(AUTHENTICATION) #ifdef AUTHENTICATION
extern int auth_level; extern int auth_level;
#endif #endif
extern char *new_login; extern char *new_login;
@@ -82,101 +75,84 @@ extern int ourpty, net;
extern char *line; extern char *line;
extern int SYNCHing; /* we are in TELNET SYNCH mode */ extern int SYNCHing; /* we are in TELNET SYNCH mode */
extern void int net_write (unsigned char *str, int len);
_termstat (void), void net_encrypt (void);
add_slc (int, int, int), int telnet_spin (void);
check_slc (void), char *telnet_getenv (char *val);
change_slc (int, int, int), char *telnet_gets (char *prompt, char *result, int length, int echo);
cleanup (int), void get_slc_defaults (void);
clientstat (int, int, int), void telrcv (void);
copy_termbuf (char *, int), void send_do (int option, int init);
deferslc (void), void willoption (int option);
defer_terminit (void), void send_dont (int option, int init);
do_opt_slc (unsigned char *, int), void wontoption (int option);
doeof (void), void send_will (int option, int init);
dooption (int), void dooption (int option);
dontoption (int), void send_wont (int option, int init);
edithost (char *, char *), void dontoption (int option);
fatal (int, char *), void suboption (void);
fatalperror (int, char *), void doclientstat (void);
get_slc_defaults (void), void send_status (void);
init_env (void), void init_termbuf (void);
init_termbuf (void), void set_termbuf (void);
interrupt (void), int spcset (int func, cc_t *valp, cc_t **valpp);
localstat (void), void set_utid (void);
flowstat (void), int getpty (int *ptynum);
netclear (void), int tty_isecho (void);
netflush (void), int tty_flowmode (void);
#ifdef DIAGNOSTICS int tty_restartany (void);
printoption (char *, int), void tty_setecho (int on);
printdata (char *, char *, int), int tty_israw (void);
printsub (int, unsigned char *, int), void tty_binaryin (int on);
#endif void tty_binaryout (int on);
ptyflush (void), int tty_isbinaryin (void);
putchr (int), int tty_isbinaryout (void);
putf (char *, char *), int tty_issofttab (void);
recv_ayt (void), void tty_setsofttab (int on);
send_do (int, int), int tty_islitecho (void);
send_dont (int, int), void tty_setlitecho (int on);
send_slc (void), int tty_iscrnl (void);
send_status (void), void tty_tspeed (int val);
send_will (int, int), void tty_rspeed (int val);
send_wont (int, int), void getptyslave (void);
sendbrk (void), int cleanopen (char *line);
sendsusp (void), void startslave (char *host, int autologin, char *autoname);
set_termbuf (void), void init_env (void);
start_login (char *, int, char *), void start_login (char *host, int autologin, char *name);
start_slc (int), void cleanup (int sig);
#if defined(AUTHENTICATION) int main (int argc, char **argv);
start_slave (char *), void usage (void);
#else int getterminaltype (char *name);
start_slave (char *, int, char *), void _gettermname (void);
#endif int terminaltypeok (char *s);
suboption (void), void doit (struct sockaddr_in *who);
telrcv (void), void telnet (int f, int p);
ttloop (void), void interrupt (void);
tty_binaryin (int), void sendbrk (void);
tty_binaryout (int); void sendsusp (void);
void recv_ayt (void);
void doeof (void);
void flowstat (void);
void clientstat (int code, int parm1, int parm2);
void 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, 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);
extern int
end_slc (unsigned char **),
getnpty (void),
#ifndef convex
getpty (int *),
#endif
login_tty (int),
spcset (int, cc_t *, cc_t **),
stilloob (int),
terminit (void),
termstat (void),
tty_flowmode (void),
tty_restartany (void),
tty_isbinaryin (void),
tty_isbinaryout (void),
tty_iscrnl (void),
tty_isecho (void),
tty_isediting (void),
tty_islitecho (void),
tty_isnewmap (void),
tty_israw (void),
tty_issofttab (void),
tty_istrapsig (void),
tty_linemode (void);
extern void #ifdef ENCRYPTION
tty_rspeed (int),
tty_setecho (int),
tty_setedit (int),
tty_setlinemode (int),
tty_setlitecho (int),
tty_setsig (int),
tty_setsofttab (int),
tty_tspeed (int),
willoption (int),
wontoption (int),
writenet (unsigned char *, int);
#if defined(ENCRYPTION)
extern void (*encrypt_output) (unsigned char *, int); extern void (*encrypt_output) (unsigned char *, int);
extern int (*decrypt_input) (int); extern int (*decrypt_input) (int);
extern char *nclearto; extern char *nclearto;
@@ -223,4 +199,6 @@ extern int really_stream;
# endif # endif
#endif #endif
#define DEFAULT_IM "\r\n\r\n" USE_IM "\r\n\r\n\n\r" #define DEFAULT_IM "\r\n\r\n" USE_IM "\r\n\r\n\r\n"
#endif /* __EXT_H__ */

View File

@@ -34,17 +34,10 @@
/* a *lot* of ugly global definitions that really should be removed... /* a *lot* of ugly global definitions that really should be removed...
*/ */
#include <config.h> #include "telnetd.h"
#ifdef SOCKS
#include <socks.h>
#endif
RCSID("$Id$"); RCSID("$Id$");
#include "defs.h"
#include "ext.h"
/* /*
* Telnet server variable declarations * Telnet server variable declarations
*/ */
@@ -52,15 +45,6 @@ char options[256];
char do_dont_resp[256]; char do_dont_resp[256];
char will_wont_resp[256]; char will_wont_resp[256];
int linemode; /* linemode on/off */ int linemode; /* linemode on/off */
#ifdef LINEMODE
int uselinemode; /* what linemode to use (on/off) */
int editmode; /* edit modes in use */
int useeditmode; /* edit modes to use */
int alwayslinemode; /* command line option */
# ifdef KLUDGELINEMODE
int lmodetype; /* Client support for linemode */
# endif /* KLUDGELINEMODE */
#endif /* LINEMODE */
int flowmode; /* current flow control state */ int flowmode; /* current flow control state */
int restartany; /* restart output on any character state */ int restartany; /* restart output on any character state */
#ifdef DIAGNOSTICS #ifdef DIAGNOSTICS
@@ -100,3 +84,24 @@ int log_unauth;
/* do not print warning if connection is not encrypted */ /* do not print warning if connection is not encrypted */
int no_warn; 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;
}

View File

@@ -31,80 +31,16 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h>
#ifdef SOCKS
#include <socks.h>
#endif
RCSID("$Id$");
#include "telnetd.h" #include "telnetd.h"
#ifdef LINEMODE RCSID("$Id$");
/*
* local varibles
*/
static unsigned char *def_slcbuf = (unsigned char *)0;
static int def_slclen = 0;
static int slcchange; /* change to slc is requested */
static unsigned char *slcptr; /* pointer into slc buffer */
static unsigned char slcbuf[NSLC*6]; /* buffer for slc negotiation */
/*
* send_slc
*
* Write out the current special characters to the client.
*/
void
send_slc()
{
int i;
/*
* Send out list of triplets of special characters
* to client. We only send info on the characters
* that are currently supported.
*/
for (i = 1; i <= NSLC; i++) {
if ((slctab[i].defset.flag & SLC_LEVELBITS) == SLC_NOSUPPORT)
continue;
add_slc((unsigned char)i, slctab[i].current.flag,
slctab[i].current.val);
}
} /* end of send_slc */
/*
* default_slc
*
* Set pty special characters to all the defaults.
*/
void
default_slc()
{
int i;
for (i = 1; i <= NSLC; i++) {
slctab[i].current.val = slctab[i].defset.val;
if (slctab[i].current.val == (cc_t)(_POSIX_VDISABLE))
slctab[i].current.flag = SLC_NOSUPPORT;
else
slctab[i].current.flag = slctab[i].defset.flag;
if (slctab[i].sptr) {
*(slctab[i].sptr) = slctab[i].defset.val;
}
}
slcchange = 1;
} /* end of default_slc */
#endif /* LINEMODE */
/* /*
* get_slc_defaults * get_slc_defaults
* *
* Initialize the slc mapping table. * Initialize the slc mapping table.
*/ */
void void
get_slc_defaults(void) get_slc_defaults(void)
{ {
int i; int i;
@@ -118,379 +54,4 @@ get_slc_defaults(void)
slctab[i].current.val = 0; slctab[i].current.val = 0;
} }
} /* end of get_slc_defaults */ }
#ifdef LINEMODE
/*
* add_slc
*
* Add an slc triplet to the slc buffer.
*/
void
add_slc(func, flag, val)
char func, flag;
cc_t val;
{
if ((*slcptr++ = (unsigned char)func) == 0xff)
*slcptr++ = 0xff;
if ((*slcptr++ = (unsigned char)flag) == 0xff)
*slcptr++ = 0xff;
if ((*slcptr++ = (unsigned char)val) == 0xff)
*slcptr++ = 0xff;
} /* end of add_slc */
/*
* start_slc
*
* Get ready to process incoming slc's and respond to them.
*
* The parameter getit is non-zero if it is necessary to grab a copy
* of the terminal control structures.
*/
void
start_slc(getit)
int getit;
{
slcchange = 0;
if (getit)
init_termbuf();
snprintf((char *)slcbuf, sizeof(slcbuf),
"%c%c%c%c",
IAC, SB, TELOPT_LINEMODE, LM_SLC);
slcptr = slcbuf + 4;
} /* end of start_slc */
/*
* end_slc
*
* Finish up the slc negotiation. If something to send, then send it.
*/
int
end_slc(bufp)
unsigned char **bufp;
{
int len;
void netflush();
/*
* If a change has occured, store the new terminal control
* structures back to the terminal driver.
*/
if (slcchange) {
set_termbuf();
}
/*
* If the pty state has not yet been fully processed and there is a
* deferred slc request from the client, then do not send any
* sort of slc negotiation now. We will respond to the client's
* request very soon.
*/
if (def_slcbuf && (terminit() == 0)) {
return(0);
}
if (slcptr > (slcbuf + 4)) {
if (bufp) {
*bufp = &slcbuf[4];
return(slcptr - slcbuf - 4);
} else {
snprintf((char *)slcptr, sizeof(slcbuf) - (slcptr - slcbuf),
"%c%c", IAC, SE);
slcptr += 2;
len = slcptr - slcbuf;
writenet(slcbuf, len);
netflush(); /* force it out immediately */
DIAG(TD_OPTIONS, printsub('>', slcbuf+2, len-2););
}
}
return (0);
} /* end of end_slc */
/*
* process_slc
*
* Figure out what to do about the client's slc
*/
void
process_slc(func, flag, val)
unsigned char func, flag;
cc_t val;
{
int hislevel, mylevel, ack;
/*
* Ensure that we know something about this function
*/
if (func > NSLC) {
add_slc(func, SLC_NOSUPPORT, 0);
return;
}
/*
* Process the special case requests of 0 SLC_DEFAULT 0
* and 0 SLC_VARIABLE 0. Be a little forgiving here, don't
* worry about whether the value is actually 0 or not.
*/
if (func == 0) {
if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT) {
default_slc();
send_slc();
} else if (flag == SLC_VARIABLE) {
send_slc();
}
return;
}
/*
* Appears to be a function that we know something about. So
* get on with it and see what we know.
*/
hislevel = flag & SLC_LEVELBITS;
mylevel = slctab[func].current.flag & SLC_LEVELBITS;
ack = flag & SLC_ACK;
/*
* ignore the command if:
* the function value and level are the same as what we already have;
* or the level is the same and the ack bit is set
*/
if (hislevel == mylevel && (val == slctab[func].current.val || ack)) {
return;
} else if (ack) {
/*
* If we get here, we got an ack, but the levels don't match.
* This shouldn't happen. If it does, it is probably because
* we have sent two requests to set a variable without getting
* a response between them, and this is the first response.
* So, ignore it, and wait for the next response.
*/
return;
} else {
change_slc(func, flag, val);
}
} /* end of process_slc */
/*
* change_slc
*
* Process a request to change one of our special characters.
* Compare client's request with what we are capable of supporting.
*/
void
change_slc(func, flag, val)
char func, flag;
cc_t val;
{
int hislevel, mylevel;
hislevel = flag & SLC_LEVELBITS;
mylevel = slctab[func].defset.flag & SLC_LEVELBITS;
/*
* If client is setting a function to NOSUPPORT
* or DEFAULT, then we can easily and directly
* accomodate the request.
*/
if (hislevel == SLC_NOSUPPORT) {
slctab[func].current.flag = flag;
slctab[func].current.val = (cc_t)_POSIX_VDISABLE;
flag |= SLC_ACK;
add_slc(func, flag, val);
return;
}
if (hislevel == SLC_DEFAULT) {
/*
* Special case here. If client tells us to use
* the default on a function we don't support, then
* return NOSUPPORT instead of what we may have as a
* default level of DEFAULT.
*/
if (mylevel == SLC_DEFAULT) {
slctab[func].current.flag = SLC_NOSUPPORT;
} else {
slctab[func].current.flag = slctab[func].defset.flag;
}
slctab[func].current.val = slctab[func].defset.val;
add_slc(func, slctab[func].current.flag,
slctab[func].current.val);
return;
}
/*
* Client wants us to change to a new value or he
* is telling us that he can't change to our value.
* Some of the slc's we support and can change,
* some we do support but can't change,
* and others we don't support at all.
* If we can change it then we have a pointer to
* the place to put the new value, so change it,
* otherwise, continue the negotiation.
*/
if (slctab[func].sptr) {
/*
* We can change this one.
*/
slctab[func].current.val = val;
*(slctab[func].sptr) = val;
slctab[func].current.flag = flag;
flag |= SLC_ACK;
slcchange = 1;
add_slc(func, flag, val);
} else {
/*
* It is not possible for us to support this
* request as he asks.
*
* If our level is DEFAULT, then just ack whatever was
* sent.
*
* If he can't change and we can't change,
* then degenerate to NOSUPPORT.
*
* Otherwise we send our level back to him, (CANTCHANGE
* or NOSUPPORT) and if CANTCHANGE, send
* our value as well.
*/
if (mylevel == SLC_DEFAULT) {
slctab[func].current.flag = flag;
slctab[func].current.val = val;
flag |= SLC_ACK;
} else if (hislevel == SLC_CANTCHANGE &&
mylevel == SLC_CANTCHANGE) {
flag &= ~SLC_LEVELBITS;
flag |= SLC_NOSUPPORT;
slctab[func].current.flag = flag;
} else {
flag &= ~SLC_LEVELBITS;
flag |= mylevel;
slctab[func].current.flag = flag;
if (mylevel == SLC_CANTCHANGE) {
slctab[func].current.val =
slctab[func].defset.val;
val = slctab[func].current.val;
}
}
add_slc(func, flag, val);
}
} /* end of change_slc */
#if VEOF == VMIN
cc_t oldeofc = '\004';
#endif
/*
* check_slc
*
* Check the special characters in use and notify the client if any have
* changed. Only those characters that are capable of being changed are
* likely to have changed. If a local change occurs, kick the support level
* and flags up to the defaults.
*/
void
check_slc()
{
int i;
for (i = 1; i <= NSLC; i++) {
#if VEOF == VMIN
/*
* In a perfect world this would be a neat little
* function. But in this world, we should not notify
* client of changes to the VEOF char when
* ICANON is off, because it is not representing
* a special character.
*/
if (i == SLC_EOF) {
if (!tty_isediting())
continue;
else if (slctab[i].sptr)
oldeofc = *(slctab[i].sptr);
}
#endif
if (slctab[i].sptr &&
(*(slctab[i].sptr) != slctab[i].current.val)) {
slctab[i].current.val = *(slctab[i].sptr);
if (*(slctab[i].sptr) == (cc_t)_POSIX_VDISABLE)
slctab[i].current.flag = SLC_NOSUPPORT;
else
slctab[i].current.flag = slctab[i].defset.flag;
add_slc((unsigned char)i, slctab[i].current.flag,
slctab[i].current.val);
}
}
} /* check_slc */
/*
* do_opt_slc
*
* Process an slc option buffer. Defer processing of incoming slc's
* until after the terminal state has been processed. Save the first slc
* request that comes along, but discard all others.
*
* ptr points to the beginning of the buffer, len is the length.
*/
void
do_opt_slc(ptr, len)
unsigned char *ptr;
int len;
{
unsigned char func, flag;
cc_t val;
unsigned char *end = ptr + len;
if (terminit()) { /* go ahead */
while (ptr < end) {
func = *ptr++;
if (ptr >= end) break;
flag = *ptr++;
if (ptr >= end) break;
val = (cc_t)*ptr++;
process_slc(func, flag, val);
}
} else {
/*
* save this slc buffer if it is the first, otherwise dump
* it.
*/
if (def_slcbuf == (unsigned char *)0) {
def_slclen = len;
def_slcbuf = (unsigned char *)malloc((unsigned)len);
if (def_slcbuf == (unsigned char *)0)
return; /* too bad */
memmove(def_slcbuf, ptr, len);
}
}
} /* end of do_opt_slc */
/*
* deferslc
*
* Do slc stuff that was deferred.
*/
void
deferslc()
{
if (def_slcbuf) {
start_slc(1);
do_opt_slc(def_slcbuf, def_slclen);
end_slc(0);
free(def_slcbuf);
def_slcbuf = (unsigned char *)0;
def_slclen = 0;
}
} /* end of deferslc */
#endif /* LINEMODE */

View File

@@ -31,18 +31,10 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "telnetd.h"
#ifdef SOCKS
#include <socks.h>
#endif
RCSID("$Id$"); RCSID("$Id$");
#include "telnetd.h"
#if defined(AUTHENTICATION)
#include <libtelnet/auth.h>
#endif
unsigned char doopt[] = { IAC, DO, '%', 'c', 0 }; unsigned char doopt[] = { IAC, DO, '%', 'c', 0 };
unsigned char dont[] = { IAC, DONT, '%', 'c', 0 }; unsigned char dont[] = { IAC, DONT, '%', 'c', 0 };
unsigned char will[] = { IAC, WILL, '%', 'c', 0 }; unsigned char will[] = { IAC, WILL, '%', 'c', 0 };
@@ -84,7 +76,7 @@ unsigned char *subsave;
#define TS_DO 7 /* do -''- */ #define TS_DO 7 /* do -''- */
#define TS_DONT 8 /* dont -''- */ #define TS_DONT 8 /* dont -''- */
void void
telrcv(void) telrcv(void)
{ {
int c; int c;
@@ -94,7 +86,7 @@ telrcv(void)
if ((&ptyobuf[BUFSIZ] - pfrontp) < 2) if ((&ptyobuf[BUFSIZ] - pfrontp) < 2)
break; break;
c = *netip++ & 0377, ncc--; c = *netip++ & 0377, ncc--;
#if defined(ENCRYPTION) #ifdef ENCRYPTION
if (decrypt_input) if (decrypt_input)
c = (*decrypt_input)(c); c = (*decrypt_input)(c);
#endif #endif
@@ -126,23 +118,12 @@ telrcv(void)
*/ */
if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) { if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) {
int nc = *netip; int nc = *netip;
#if defined(ENCRYPTION) #ifdef ENCRYPTION
if (decrypt_input) if (decrypt_input)
nc = (*decrypt_input)(nc & 0xff); nc = (*decrypt_input)(nc & 0xff);
#endif
#ifdef LINEMODE
/*
* If we are operating in linemode,
* convert to local end-of-line.
*/
if (linemode && (ncc > 0) && (('\n' == nc) ||
((0 == nc) && tty_iscrnl())) ) {
netip++; ncc--;
c = '\n';
} else
#endif #endif
{ {
#if defined(ENCRYPTION) #ifdef ENCRYPTION
if (decrypt_input) if (decrypt_input)
(void)(*decrypt_input)(-1); (void)(*decrypt_input)(-1);
#endif #endif
@@ -153,7 +134,7 @@ telrcv(void)
break; break;
case TS_IAC: case TS_IAC:
gotiac: switch (c) { gotiac: switch (c) {
/* /*
* Send the process on the pty side an * Send the process on the pty side an
@@ -198,8 +179,7 @@ gotiac: switch (c) {
} }
netclear(); /* clear buffer back */ netclear(); /* clear buffer back */
*nfrontp++ = IAC; output_data ("%c%c", IAC, DM);
*nfrontp++ = DM;
neturg = nfrontp-1; /* off by one XXX */ neturg = nfrontp-1; /* off by one XXX */
DIAG(TD_OPTIONS, DIAG(TD_OPTIONS,
printoption("td: send IAC", DM)); printoption("td: send IAC", DM));
@@ -418,7 +398,7 @@ gotiac: switch (c) {
* is complete. * is complete.
* *
*/ */
void void
send_do(int option, int init) send_do(int option, int init)
{ {
if (init) { if (init) {
@@ -436,9 +416,7 @@ send_do(int option, int init)
set_his_want_state_will(option); set_his_want_state_will(option);
do_dont_resp[option]++; do_dont_resp[option]++;
} }
snprintf(nfrontp, BUFSIZ - (nfrontp - netobuf), output_data((const char *)doopt, option);
(char *)doopt, option);
nfrontp += sizeof (dont) - 2;
DIAG(TD_OPTIONS, printoption("td: send do", option)); DIAG(TD_OPTIONS, printoption("td: send do", option));
} }
@@ -446,14 +424,11 @@ send_do(int option, int init)
#ifdef AUTHENTICATION #ifdef AUTHENTICATION
extern void auth_request(void); extern void auth_request(void);
#endif #endif
#ifdef LINEMODE
extern void doclientstat();
#endif
#ifdef ENCRYPTION #ifdef ENCRYPTION
extern void encrypt_send_support(); extern void encrypt_send_support();
#endif #endif
void void
willoption(int option) willoption(int option)
{ {
int changeok = 0; int changeok = 0;
@@ -489,35 +464,6 @@ willoption(int option)
break; break;
case TELOPT_TM: case TELOPT_TM:
#if defined(LINEMODE) && defined(KLUDGELINEMODE)
/*
* This telnetd implementation does not really
* support timing marks, it just uses them to
* support the kludge linemode stuff. If we
* receive a will or wont TM in response to our
* do TM request that may have been sent to
* determine kludge linemode support, process
* it, otherwise TM should get a negative
* response back.
*/
/*
* Handle the linemode kludge stuff.
* If we are not currently supporting any
* linemode at all, then we assume that this
* is the client telling us to use kludge
* linemode in response to our query. Set the
* linemode type that is to be supported, note
* that the client wishes to use linemode, and
* eat the will TM as though it never arrived.
*/
if (lmodetype < KLUDGE_LINEMODE) {
lmodetype = KLUDGE_LINEMODE;
clientstat(TELOPT_LINEMODE, WILL, 0);
send_wont(TELOPT_SGA, 1);
} else if (lmodetype == NO_AUTOKLUDGE) {
lmodetype = KLUDGE_OK;
}
#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
/* /*
* We never respond to a WILL TM, and * We never respond to a WILL TM, and
* we leave the state WONT. * we leave the state WONT.
@@ -544,18 +490,6 @@ willoption(int option)
changeok++; changeok++;
break; break;
#ifdef LINEMODE
case TELOPT_LINEMODE:
# ifdef KLUDGELINEMODE
/*
* Note client's desire to use linemode.
*/
lmodetype = REAL_LINEMODE;
# endif /* KLUDGELINEMODE */
func = doclientstat;
changeok++;
break;
#endif /* LINEMODE */
#ifdef AUTHENTICATION #ifdef AUTHENTICATION
case TELOPT_AUTHENTICATION: case TELOPT_AUTHENTICATION:
@@ -611,17 +545,6 @@ willoption(int option)
* all is well. * all is well.
*/ */
break; break;
#ifdef LINEMODE
case TELOPT_LINEMODE:
# ifdef KLUDGELINEMODE
/*
* Note client's desire to use linemode.
*/
lmodetype = REAL_LINEMODE;
# endif /* KLUDGELINEMODE */
func = doclientstat;
break;
#endif /* LINEMODE */
#ifdef AUTHENTICATION #ifdef AUTHENTICATION
case TELOPT_AUTHENTICATION: case TELOPT_AUTHENTICATION:
@@ -646,7 +569,7 @@ willoption(int option)
(*func)(); (*func)();
} /* end of willoption */ } /* end of willoption */
void void
send_dont(int option, int init) send_dont(int option, int init)
{ {
if (init) { if (init) {
@@ -656,14 +579,12 @@ send_dont(int option, int init)
set_his_want_state_wont(option); set_his_want_state_wont(option);
do_dont_resp[option]++; do_dont_resp[option]++;
} }
snprintf(nfrontp, BUFSIZ - (nfrontp - netobuf), output_data((const char *)dont, option);
(char *)dont, option);
nfrontp += sizeof (doopt) - 2;
DIAG(TD_OPTIONS, printoption("td: send dont", option)); DIAG(TD_OPTIONS, printoption("td: send dont", option));
} }
void void
wontoption(int option) wontoption(int option)
{ {
/* /*
@@ -691,20 +612,6 @@ wontoption(int option)
set_termbuf(); set_termbuf();
break; break;
#ifdef LINEMODE
case TELOPT_LINEMODE:
# ifdef KLUDGELINEMODE
/*
* If real linemode is supported, then client is
* asking to turn linemode off.
*/
if (lmodetype != REAL_LINEMODE)
break;
# endif /* KLUDGELINEMODE */
clientstat(TELOPT_LINEMODE, WONT, 0);
break;
#endif /* LINEMODE */
case TELOPT_TM: case TELOPT_TM:
/* /*
* If we get a WONT TM, and had sent a DO TM, * If we get a WONT TM, and had sent a DO TM,
@@ -727,7 +634,7 @@ wontoption(int option)
slctab[SLC_XOFF].defset.flag |= SLC_CANTCHANGE; slctab[SLC_XOFF].defset.flag |= SLC_CANTCHANGE;
break; break;
#if defined(AUTHENTICATION) #ifdef AUTHENTICATION
case TELOPT_AUTHENTICATION: case TELOPT_AUTHENTICATION:
auth_finished(0, AUTH_REJECT); auth_finished(0, AUTH_REJECT);
break; break;
@@ -770,17 +677,9 @@ wontoption(int option)
} else { } else {
switch (option) { switch (option) {
case TELOPT_TM: case TELOPT_TM:
#if defined(LINEMODE) && defined(KLUDGELINEMODE)
if (lmodetype < NO_AUTOKLUDGE) {
lmodetype = NO_LINEMODE;
clientstat(TELOPT_LINEMODE, WONT, 0);
send_will(TELOPT_SGA, 1);
send_will(TELOPT_ECHO, 1);
}
#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
break; break;
#if defined(AUTHENTICATION) #ifdef AUTHENTICATION
case TELOPT_AUTHENTICATION: case TELOPT_AUTHENTICATION:
auth_finished(0, AUTH_REJECT); auth_finished(0, AUTH_REJECT);
break; break;
@@ -794,7 +693,7 @@ wontoption(int option)
} /* end of wontoption */ } /* end of wontoption */
void void
send_will(int option, int init) send_will(int option, int init)
{ {
if (init) { if (init) {
@@ -804,14 +703,11 @@ send_will(int option, int init)
set_my_want_state_will(option); set_my_want_state_will(option);
will_wont_resp[option]++; will_wont_resp[option]++;
} }
snprintf(nfrontp, BUFSIZ - (nfrontp - netobuf), output_data ((const char *)will, option);
(char *)will, option);
nfrontp += sizeof (doopt) - 2;
DIAG(TD_OPTIONS, printoption("td: send will", option)); DIAG(TD_OPTIONS, printoption("td: send will", option));
} }
#if !defined(LINEMODE) || !defined(KLUDGELINEMODE)
/* /*
* When we get a DONT SGA, we will try once to turn it * When we get a DONT SGA, we will try once to turn it
* back on. If the other side responds DONT SGA, we * back on. If the other side responds DONT SGA, we
@@ -820,9 +716,8 @@ send_will(int option, int init)
* we'll keep them in char-at-a-time mode. * we'll keep them in char-at-a-time mode.
*/ */
int turn_on_sga = 0; int turn_on_sga = 0;
#endif
void void
dooption(int option) dooption(int option)
{ {
int changeok = 0; int changeok = 0;
@@ -841,13 +736,6 @@ dooption(int option)
if ((will_wont_resp[option] == 0) && (my_want_state_is_wont(option))) { if ((will_wont_resp[option] == 0) && (my_want_state_is_wont(option))) {
switch (option) { switch (option) {
case TELOPT_ECHO: case TELOPT_ECHO:
#ifdef LINEMODE
# ifdef KLUDGELINEMODE
if (lmodetype == NO_LINEMODE)
# else
if (his_state_is_wont(TELOPT_LINEMODE))
# endif
#endif
{ {
init_termbuf(); init_termbuf();
tty_setecho(1); tty_setecho(1);
@@ -864,32 +752,7 @@ dooption(int option)
break; break;
case TELOPT_SGA: case TELOPT_SGA:
#if defined(LINEMODE) && defined(KLUDGELINEMODE)
/*
* If kludge linemode is in use, then we must
* process an incoming do SGA for linemode
* purposes.
*/
if (lmodetype == KLUDGE_LINEMODE) {
/*
* Receipt of "do SGA" in kludge
* linemode is the peer asking us to
* turn off linemode. Make note of
* the request.
*/
clientstat(TELOPT_LINEMODE, WONT, 0);
/*
* If linemode did not get turned off
* then don't tell peer that we did.
* Breaking here forces a wont SGA to
* be returned.
*/
if (linemode)
break;
}
#else
turn_on_sga = 0; turn_on_sga = 0;
#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
changeok++; changeok++;
break; break;
@@ -922,7 +785,7 @@ dooption(int option)
/* NOT REACHED */ /* NOT REACHED */
break; break;
#if defined(ENCRYPTION) #ifdef ENCRYPTION
case TELOPT_ENCRYPT: case TELOPT_ENCRYPT:
changeok++; changeok++;
break; break;
@@ -952,7 +815,7 @@ dooption(int option)
} /* end of dooption */ } /* end of dooption */
void void
send_wont(int option, int init) send_wont(int option, int init)
{ {
if (init) { if (init) {
@@ -962,14 +825,12 @@ send_wont(int option, int init)
set_my_want_state_wont(option); set_my_want_state_wont(option);
will_wont_resp[option]++; will_wont_resp[option]++;
} }
snprintf(nfrontp, BUFSIZ - (nfrontp - netobuf), output_data ((const char *)wont, option);
(char *)wont, option);
nfrontp += sizeof (wont) - 2;
DIAG(TD_OPTIONS, printoption("td: send wont", option)); DIAG(TD_OPTIONS, printoption("td: send wont", option));
} }
void void
dontoption(int option) dontoption(int option)
{ {
/* /*
@@ -993,14 +854,6 @@ dontoption(int option)
break; break;
case TELOPT_ECHO: /* we should stop echoing */ case TELOPT_ECHO: /* we should stop echoing */
#ifdef LINEMODE
# ifdef KLUDGELINEMODE
if ((lmodetype != REAL_LINEMODE) &&
(lmodetype != KLUDGE_LINEMODE))
# else
if (his_state_is_wont(TELOPT_LINEMODE))
# endif
#endif
{ {
init_termbuf(); init_termbuf();
tty_setecho(0); tty_setecho(0);
@@ -1009,29 +862,6 @@ dontoption(int option)
break; break;
case TELOPT_SGA: case TELOPT_SGA:
#if defined(LINEMODE) && defined(KLUDGELINEMODE)
/*
* If kludge linemode is in use, then we
* must process an incoming do SGA for
* linemode purposes.
*/
if ((lmodetype == KLUDGE_LINEMODE) ||
(lmodetype == KLUDGE_OK)) {
/*
* The client is asking us to turn
* linemode on.
*/
lmodetype = KLUDGE_LINEMODE;
clientstat(TELOPT_LINEMODE, WILL, 0);
/*
* If we did not turn line mode on,
* then what do we say? Will SGA?
* This violates design of telnet.
* Gross. Very Gross.
*/
}
break;
#else
set_my_want_state_wont(option); set_my_want_state_wont(option);
if (my_state_is_will(option)) if (my_state_is_will(option))
send_wont(option, 0); send_wont(option, 0);
@@ -1039,7 +869,6 @@ dontoption(int option)
if (turn_on_sga ^= 1) if (turn_on_sga ^= 1)
send_will(option, 1); send_will(option, 1);
return; return;
#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
default: default:
break; break;
@@ -1074,7 +903,7 @@ int env_ovalue = -1;
* Window size * Window size
* Terminal speed * Terminal speed
*/ */
void void
suboption(void) suboption(void)
{ {
int subchar; int subchar;
@@ -1159,54 +988,6 @@ suboption(void)
} /* end of case TELOPT_NAWS */ } /* end of case TELOPT_NAWS */
#ifdef LINEMODE
case TELOPT_LINEMODE: {
int request;
if (his_state_is_wont(TELOPT_LINEMODE)) /* Ignore if option disabled */
break;
/*
* Process linemode suboptions.
*/
if (SB_EOF())
break; /* garbage was sent */
request = SB_GET(); /* get will/wont */
if (SB_EOF())
break; /* another garbage check */
if (request == LM_SLC) { /* SLC is not preceeded by WILL or WONT */
/*
* Process suboption buffer of slc's
*/
start_slc(1);
do_opt_slc(subpointer, subend - subpointer);
end_slc(0);
break;
} else if (request == LM_MODE) {
if (SB_EOF())
return;
useeditmode = SB_GET(); /* get mode flag */
clientstat(LM_MODE, 0, 0);
break;
}
if (SB_EOF())
break;
switch (SB_GET()) { /* what suboption? */
case LM_FORWARDMASK:
/*
* According to spec, only server can send request for
* forwardmask, and client can only return a positive response.
* So don't worry about it.
*/
default:
break;
}
break;
} /* end of case TELOPT_LINEMODE */
#endif
case TELOPT_STATUS: { case TELOPT_STATUS: {
int mode; int mode;
@@ -1359,11 +1140,9 @@ suboption(void)
env_ovar_wrong: env_ovar_wrong:
env_ovar = OLD_ENV_VALUE; env_ovar = OLD_ENV_VALUE;
env_ovalue = OLD_ENV_VAR; env_ovalue = OLD_ENV_VAR;
DIAG(TD_OPTIONS, {snprintf(nfrontp, DIAG(TD_OPTIONS, {
BUFSIZ - output_data("ENVIRON VALUE and VAR are reversed!\r\n");
(nfrontp - netobuf), });
"ENVIRON VALUE and VAR are reversed!\r\n");
nfrontp += strlen(nfrontp);});
} }
} }
@@ -1426,7 +1205,7 @@ suboption(void)
unsetenv(varp); unsetenv(varp);
break; break;
} /* end of case TELOPT_NEW_ENVIRON */ } /* end of case TELOPT_NEW_ENVIRON */
#if defined(AUTHENTICATION) #ifdef AUTHENTICATION
case TELOPT_AUTHENTICATION: case TELOPT_AUTHENTICATION:
if (SB_EOF()) if (SB_EOF())
break; break;
@@ -1447,7 +1226,7 @@ suboption(void)
} }
break; break;
#endif #endif
#if defined(ENCRYPTION) #ifdef ENCRYPTION
case TELOPT_ENCRYPT: case TELOPT_ENCRYPT:
if (SB_EOF()) if (SB_EOF())
break; break;
@@ -1497,7 +1276,7 @@ suboption(void)
} /* end of suboption */ } /* end of suboption */
void void
doclientstat(void) doclientstat(void)
{ {
clientstat(TELOPT_LINEMODE, WILL, 0); clientstat(TELOPT_LINEMODE, WILL, 0);
@@ -1505,7 +1284,8 @@ doclientstat(void)
#define ADD(c) *ncp++ = c #define ADD(c) *ncp++ = c
#define ADD_DATA(c) { *ncp++ = c; if (c == SE || c == IAC) *ncp++ = c; } #define ADD_DATA(c) { *ncp++ = c; if (c == SE || c == IAC) *ncp++ = c; }
void
void
send_status(void) send_status(void)
{ {
unsigned char statusbuf[256]; unsigned char statusbuf[256];
@@ -1562,28 +1342,6 @@ send_status(void)
} }
} }
#ifdef LINEMODE
if (his_want_state_is_will(TELOPT_LINEMODE)) {
unsigned char *cp, *cpe;
int len;
ADD(SB);
ADD(TELOPT_LINEMODE);
ADD(LM_MODE);
ADD_DATA(editmode);
ADD(SE);
ADD(SB);
ADD(TELOPT_LINEMODE);
ADD(LM_SLC);
start_slc(0);
send_slc();
len = end_slc(&cp);
for (cpe = cp + len; cp < cpe; cp++)
ADD_DATA(*cp);
ADD(SE);
}
#endif /* LINEMODE */
ADD(IAC); ADD(IAC);
ADD(SE); ADD(SE);

View File

@@ -31,35 +31,21 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "telnetd.h"
#ifdef SOCKS
#include <socks.h>
#endif
RCSID("$Id$"); RCSID("$Id$");
#include "telnetd.h" #if defined(_CRAY) || (defined(__hpux) && !defined(HAVE_UTMPX_H))
#include "pathnames.h"
#ifdef AUTHENTICATION
#include <libtelnet/auth.h>
#endif
#if defined(CRAY) || (defined(__hpux) && !defined(HAVE_UTMPX_H))
# define PARENT_DOES_UTMP # define PARENT_DOES_UTMP
#endif #endif
#ifdef NEWINIT #ifdef HAVE_UTMPX
#error NEWINIT not supported
#endif
#ifdef HAVE_UTMPX_H
#include <utmpx.h> #include <utmpx.h>
struct utmpx wtmp; struct utmpx wtmp;
#else #else
#include <utmp.h> #include <utmp.h>
struct utmp wtmp; struct utmp wtmp;
#endif /* HAVE_UTMPX_H */ #endif /* HAVE_UTMPX */
#ifdef HAVE_UT_HOST #ifdef HAVE_UT_HOST
int utmp_len = sizeof(wtmp.ut_host); int utmp_len = sizeof(wtmp.ut_host);
@@ -73,7 +59,7 @@ char utmpf[] = "/etc/utmp";
char wtmpf[] = "/etc/wtmp"; char wtmpf[] = "/etc/wtmp";
#endif /* PARENT_DOES_UTMP */ #endif /* PARENT_DOES_UTMP */
#ifdef CRAY #ifdef _CRAY
#include <tmpdir.h> #include <tmpdir.h>
#include <sys/wait.h> #include <sys/wait.h>
#endif /* CRAY */ #endif /* CRAY */
@@ -127,6 +113,10 @@ char wtmpf[] = "/etc/wtmp";
#endif #endif
#endif #endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
# ifndef TCSANOW # ifndef TCSANOW
# ifdef TCSETS # ifdef TCSETS
# define TCSANOW TCSETS # define TCSANOW TCSETS
@@ -145,7 +135,7 @@ char wtmpf[] = "/etc/wtmp";
# endif # endif
# define tcsetattr(f, a, t) ioctl(f, a, t) # define tcsetattr(f, a, t) ioctl(f, a, t)
# define cfsetospeed(tp, val) (tp)->c_cflag &= ~CBAUD; \ # define cfsetospeed(tp, val) (tp)->c_cflag &= ~CBAUD; \
(tp)->c_cflag |= (val) (tp)->c_cflag |= (val)
# define cfgetospeed(tp) ((tp)->c_cflag & CBAUD) # define cfgetospeed(tp) ((tp)->c_cflag & CBAUD)
# ifdef CIBAUD # ifdef CIBAUD
# define cfsetispeed(tp, val) (tp)->c_cflag &= ~CIBAUD; \ # define cfsetispeed(tp, val) (tp)->c_cflag &= ~CIBAUD; \
@@ -157,13 +147,13 @@ char wtmpf[] = "/etc/wtmp";
# define cfgetispeed(tp) ((tp)->c_cflag & CBAUD) # define cfgetispeed(tp) ((tp)->c_cflag & CBAUD)
# endif # endif
# endif /* TCSANOW */ # endif /* TCSANOW */
struct termios termbuf, termbuf2; /* pty control structure */ struct termios termbuf, termbuf2; /* pty control structure */
# ifdef STREAMSPTY # ifdef STREAMSPTY
static int ttyfd = -1; static int ttyfd = -1;
int really_stream = 0; int really_stream = 0;
# endif # endif
char *new_login = LOGIN_PATH; char *new_login = LOGIN_PATH;
/* /*
* init_termbuf() * init_termbuf()
@@ -176,8 +166,8 @@ char *new_login = LOGIN_PATH;
* set_termbuf() writes the structure into the kernel. * set_termbuf() writes the structure into the kernel.
*/ */
void void
init_termbuf(void) init_termbuf(void)
{ {
# ifdef STREAMSPTY # ifdef STREAMSPTY
if (really_stream) if (really_stream)
@@ -188,20 +178,7 @@ init_termbuf(void)
termbuf2 = termbuf; termbuf2 = termbuf;
} }
#if defined(LINEMODE) && defined(TIOCPKT_IOCTL) void
void
copy_termbuf(cp, len)
char *cp;
int len;
{
if (len > sizeof(termbuf))
len = sizeof(termbuf);
memmove(&termbuf, cp, len);
termbuf2 = termbuf;
}
#endif /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */
void
set_termbuf(void) set_termbuf(void)
{ {
/* /*
@@ -229,7 +206,7 @@ set_termbuf(void)
*/ */
int int
spcset(int func, cc_t *valp, cc_t **valpp) spcset(int func, cc_t *valp, cc_t **valpp)
{ {
@@ -321,13 +298,13 @@ spcset(int func, cc_t *valp, cc_t **valpp)
} }
} }
#ifdef CRAY #ifdef _CRAY
/* /*
* getnpty() * getnpty()
* *
* Return the number of pty's configured into the system. * Return the number of pty's configured into the system.
*/ */
int int
getnpty() getnpty()
{ {
#ifdef _SC_CRAY_NPTY #ifdef _SC_CRAY_NPTY
@@ -356,8 +333,8 @@ char *line = Xline;
char *line_nodev; char *line_nodev;
char *line_notty; char *line_notty;
#ifdef CRAY #ifdef _CRAY
char myline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; char *myline = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
#endif /* CRAY */ #endif /* CRAY */
#ifndef HAVE_PTSNAME #ifndef HAVE_PTSNAME
@@ -371,7 +348,7 @@ static char *ptsname(int fd)
} }
#endif #endif
#ifdef HAVE_UTMPX_H #ifdef HAVE_UTMPX
static char utid[32]; /* XXX larger than ut_id */ static char utid[32]; /* XXX larger than ut_id */
void void
@@ -427,7 +404,9 @@ int getpty(int *ptynum)
int p; int p;
char *cp, *p1, *p2; char *cp, *p1, *p2;
int i; int i;
#if SunOS == 4
int dummy; int dummy;
#endif
#if 0 /* && defined(HAVE_OPENPTY) */ #if 0 /* && defined(HAVE_OPENPTY) */
int master; int master;
int slave; int slave;
@@ -456,7 +435,7 @@ int getpty(int *ptynum)
} }
} }
#endif /* STREAMSPTY */ #endif /* STREAMSPTY */
#ifndef CRAY #ifndef _CRAY
#ifndef __hpux #ifndef __hpux
snprintf(line, sizeof(Xline), "/dev/ptyXX"); snprintf(line, sizeof(Xline), "/dev/ptyXX");
@@ -549,73 +528,26 @@ int getpty(int *ptynum)
#endif #endif
} }
#ifdef LINEMODE
/*
* tty_flowmode() Find out if flow control is enabled or disabled.
* tty_linemode() Find out if linemode (external processing) is enabled.
* tty_setlinemod(on) Turn on/off linemode.
* tty_isecho() Find out if echoing is turned on.
* tty_setecho(on) Enable/disable character echoing.
* tty_israw() Find out if terminal is in RAW mode.
* tty_binaryin(on) Turn on/off BINARY on input.
* tty_binaryout(on) Turn on/off BINARY on output.
* tty_isediting() Find out if line editing is enabled.
* tty_istrapsig() Find out if signal trapping is enabled.
* tty_setedit(on) Turn on/off line editing.
* tty_setsig(on) Turn on/off signal trapping.
* tty_issofttab() Find out if tab expansion is enabled.
* tty_setsofttab(on) Turn on/off soft tab expansion.
* tty_islitecho() Find out if typed control chars are echoed literally
* tty_setlitecho() Turn on/off literal echo of control chars
* tty_tspeed(val) Set transmit speed to val.
* tty_rspeed(val) Set receive speed to val.
*/
int
int
tty_linemode()
{
return(termbuf.c_lflag & EXTPROC);
}
void
tty_setlinemode(on)
int on;
{
#ifdef TIOCEXT
set_termbuf();
ioctl(ourpty, TIOCEXT, (char *)&on);
init_termbuf();
#else /* !TIOCEXT */
# ifdef EXTPROC
if (on)
termbuf.c_lflag |= EXTPROC;
else
termbuf.c_lflag &= ~EXTPROC;
# endif
#endif /* TIOCEXT */
}
#endif /* LINEMODE */
int
tty_isecho(void) tty_isecho(void)
{ {
return (termbuf.c_lflag & ECHO); return (termbuf.c_lflag & ECHO);
} }
int int
tty_flowmode(void) tty_flowmode(void)
{ {
return((termbuf.c_iflag & IXON) ? 1 : 0); return((termbuf.c_iflag & IXON) ? 1 : 0);
} }
int int
tty_restartany(void) tty_restartany(void)
{ {
return((termbuf.c_iflag & IXANY) ? 1 : 0); return((termbuf.c_iflag & IXANY) ? 1 : 0);
} }
void void
tty_setecho(int on) tty_setecho(int on)
{ {
if (on) if (on)
@@ -624,24 +556,13 @@ tty_setecho(int on)
termbuf.c_lflag &= ~ECHO; termbuf.c_lflag &= ~ECHO;
} }
int int
tty_israw(void) tty_israw(void)
{ {
return(!(termbuf.c_lflag & ICANON)); return(!(termbuf.c_lflag & ICANON));
} }
#if defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R) void
int
tty_setraw(on)
{
if (on)
termbuf.c_lflag &= ~ICANON;
else
termbuf.c_lflag |= ICANON;
}
#endif
void
tty_binaryin(int on) tty_binaryin(int on)
{ {
if (on) { if (on) {
@@ -651,7 +572,7 @@ tty_binaryin(int on)
} }
} }
void void
tty_binaryout(int on) tty_binaryout(int on)
{ {
if (on) { if (on) {
@@ -665,53 +586,20 @@ tty_binaryout(int on)
} }
} }
int int
tty_isbinaryin(void) tty_isbinaryin(void)
{ {
return(!(termbuf.c_iflag & ISTRIP)); return(!(termbuf.c_iflag & ISTRIP));
} }
int int
tty_isbinaryout(void) tty_isbinaryout(void)
{ {
return(!(termbuf.c_oflag&OPOST)); return(!(termbuf.c_oflag&OPOST));
} }
#ifdef LINEMODE
int
tty_isediting()
{
return(termbuf.c_lflag & ICANON);
}
int int
tty_istrapsig()
{
return(termbuf.c_lflag & ISIG);
}
void
tty_setedit(on)
int on;
{
if (on)
termbuf.c_lflag |= ICANON;
else
termbuf.c_lflag &= ~ICANON;
}
void
tty_setsig(on)
int on;
{
if (on)
termbuf.c_lflag |= ISIG;
else
termbuf.c_lflag &= ~ISIG;
}
#endif /* LINEMODE */
int
tty_issofttab(void) tty_issofttab(void)
{ {
# ifdef OXTABS # ifdef OXTABS
@@ -722,7 +610,7 @@ tty_issofttab(void)
# endif # endif
} }
void void
tty_setsofttab(int on) tty_setsofttab(int on)
{ {
if (on) { if (on) {
@@ -744,7 +632,7 @@ tty_setsofttab(int on)
} }
} }
int int
tty_islitecho(void) tty_islitecho(void)
{ {
# ifdef ECHOCTL # ifdef ECHOCTL
@@ -758,7 +646,7 @@ tty_islitecho(void)
# endif # endif
} }
void void
tty_setlitecho(int on) tty_setlitecho(int on)
{ {
# ifdef ECHOCTL # ifdef ECHOCTL
@@ -775,7 +663,7 @@ tty_setlitecho(int on)
# endif # endif
} }
int int
tty_iscrnl(void) tty_iscrnl(void)
{ {
return (termbuf.c_iflag & ICRNL); return (termbuf.c_iflag & ICRNL);
@@ -831,7 +719,7 @@ struct termspeeds {
}; };
#endif /* DECODE_BUAD */ #endif /* DECODE_BUAD */
void void
tty_tspeed(int val) tty_tspeed(int val)
{ {
#ifdef DECODE_BAUD #ifdef DECODE_BAUD
@@ -847,7 +735,7 @@ tty_tspeed(int val)
#endif /* DECODE_BUAD */ #endif /* DECODE_BUAD */
} }
void void
tty_rspeed(int val) tty_rspeed(int val)
{ {
#ifdef DECODE_BAUD #ifdef DECODE_BAUD
@@ -942,9 +830,6 @@ void getptyslave(void)
{ {
int t = -1; int t = -1;
# ifdef LINEMODE
int waslm;
# endif
struct winsize ws; struct winsize ws;
extern int def_row, def_col; extern int def_row, def_col;
extern int def_tspeed, def_rspeed; extern int def_tspeed, def_rspeed;
@@ -956,9 +841,6 @@ void getptyslave(void)
* terminal speed * terminal speed
* so that we can re-set them if we need to. * so that we can re-set them if we need to.
*/ */
# ifdef LINEMODE
waslm = tty_linemode();
# endif
/* /*
@@ -1040,7 +922,7 @@ void getptyslave(void)
/* /*
* Settings for UNICOS (and HPUX) * Settings for UNICOS (and HPUX)
*/ */
# if defined(CRAY) || defined(__hpux) # if defined(_CRAY) || defined(__hpux)
termbuf.c_oflag = OPOST|ONLCR|TAB3; termbuf.c_oflag = OPOST|ONLCR|TAB3;
termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON; termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK; termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
@@ -1052,7 +934,7 @@ void getptyslave(void)
* systems, other than 4.4BSD. In 4.4BSD the * systems, other than 4.4BSD. In 4.4BSD the
* kernel does the initial terminal setup. * kernel does the initial terminal setup.
*/ */
# if !(defined(CRAY) || defined(__hpux)) && (BSD <= 43) # if !(defined(_CRAY) || defined(__hpux)) && (BSD <= 43)
# ifndef OXTABS # ifndef OXTABS
# define OXTABS 0 # define OXTABS 0
# endif # endif
@@ -1063,10 +945,6 @@ void getptyslave(void)
# endif # endif
tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600); tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600);
tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600); tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);
# ifdef LINEMODE
if (waslm)
tty_setlinemode(1);
# endif /* LINEMODE */
/* /*
* Set the tty modes, and make this our controlling tty. * Set the tty modes, and make this our controlling tty.
@@ -1076,17 +954,10 @@ void getptyslave(void)
fatalperror(net, "login_tty"); fatalperror(net, "login_tty");
if (net > 2) if (net > 2)
close(net); close(net);
#if defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
/*
* Leave the pty open so that we can write out the rlogin
* protocol for /bin/login, if the authentication works.
*/
#else
if (ourpty > 2) { if (ourpty > 2) {
close(ourpty); close(ourpty);
ourpty = -1; ourpty = -1;
} }
#endif
} }
#ifndef O_NOCTTY #ifndef O_NOCTTY
@@ -1113,7 +984,7 @@ int cleanopen(char *line)
chmod(line, 0600); chmod(line, 0600);
} }
# if !defined(CRAY) && (BSD > 43) # if !defined(_CRAY) && (BSD > 43)
revoke(line); revoke(line);
# endif # endif
@@ -1126,7 +997,7 @@ int cleanopen(char *line)
* Hangup anybody else using this ttyp, then reopen it for * Hangup anybody else using this ttyp, then reopen it for
* ourselves. * ourselves.
*/ */
# if !(defined(CRAY) || defined(__hpux)) && (BSD <= 43) && !defined(STREAMSPTY) # if !(defined(_CRAY) || defined(__hpux)) && (BSD <= 43) && !defined(STREAMSPTY)
signal(SIGHUP, SIG_IGN); signal(SIGHUP, SIG_IGN);
#ifdef HAVE_VHANGUP #ifdef HAVE_VHANGUP
vhangup(); vhangup();
@@ -1137,7 +1008,7 @@ int cleanopen(char *line)
if (t < 0) if (t < 0)
return(-1); return(-1);
# endif # endif
# if defined(CRAY) && defined(TCVHUP) # if defined(_CRAY) && defined(TCVHUP)
{ {
int i; int i;
signal(SIGHUP, SIG_IGN); signal(SIGHUP, SIG_IGN);
@@ -1159,25 +1030,10 @@ int cleanopen(char *line)
int login_tty(int t) int login_tty(int t)
{ {
#if 0 /* setsid done in other place */
#if defined(HAVE_SETSID) && !defined(_AIX)
if (setsid() < 0) {
#ifdef ultrix
/*
* The setsid() may have failed because we
* already have a pgrp == pid. Zero out
* our pgrp and try again...
*/
if ((setpgrp(0, 0) < 0) || (setsid() < 0))
#endif
fatalperror(net, "setsid()");
}
#endif /* HAVE_SETSID */
#endif
# if defined(TIOCSCTTY) && !defined(__hpux) # if defined(TIOCSCTTY) && !defined(__hpux)
if (ioctl(t, TIOCSCTTY, (char *)0) < 0) if (ioctl(t, TIOCSCTTY, (char *)0) < 0)
fatalperror(net, "ioctl(sctty)"); fatalperror(net, "ioctl(sctty)");
# if defined(CRAY) # ifdef _CRAY
/* /*
* Close the hard fd to /dev/ttypXXX, and re-open through * Close the hard fd to /dev/ttypXXX, and re-open through
* the indirect /dev/tty interface. * the indirect /dev/tty interface.
@@ -1194,7 +1050,7 @@ int login_tty(int t)
* setsid() call above may have set our pgrp, so clear * setsid() call above may have set our pgrp, so clear
* it out before opening the tty... * it out before opening the tty...
*/ */
#if defined HAVE_SETPGID #ifdef HAVE_SETPGID
setpgid(0, 0); setpgid(0, 0);
#else #else
setpgrp(0, 0); /* if setpgid isn't available, setpgrp setpgrp(0, 0); /* if setpgid isn't available, setpgrp
@@ -1222,13 +1078,12 @@ int login_tty(int t)
*/ */
/* ARGSUSED */ /* ARGSUSED */
void void
startslave(char *host, int autologin, char *autoname) startslave(char *host, int autologin, char *autoname)
{ {
int i; int i;
char name[256];
#if defined(AUTHENTICATION) #ifdef AUTHENTICATION
if (!autoname || !autoname[0]) if (!autoname || !autoname[0])
autologin = 0; autologin = 0;
@@ -1285,7 +1140,7 @@ startslave(char *host, int autologin, char *autoname)
write(i, &wtmp, sizeof(struct utmp)); write(i, &wtmp, sizeof(struct utmp));
close(i); close(i);
} }
#ifdef CRAY #ifdef _CRAY
signal(WJSIGNAL, sigjob); signal(WJSIGNAL, sigjob);
#endif #endif
utmp_sig_notify(pid); utmp_sig_notify(pid);
@@ -1300,7 +1155,7 @@ startslave(char *host, int autologin, char *autoname)
char *envinit[3]; char *envinit[3];
extern char **environ; extern char **environ;
void void
init_env(void) init_env(void)
{ {
extern char *getenv(const char *); extern char *getenv(const char *);
@@ -1309,7 +1164,7 @@ init_env(void)
envp = envinit; envp = envinit;
if (*envp = getenv("TZ")) if (*envp = getenv("TZ"))
*envp++ -= 3; *envp++ -= 3;
#if defined(CRAY) || defined(__hpux) #if defined(_CRAY) || defined(__hpux)
else else
*envp++ = "TZ=GMT0"; *envp++ = "TZ=GMT0";
#endif #endif
@@ -1349,7 +1204,7 @@ struct arg_val {
char **argv; char **argv;
}; };
int addarg(struct arg_val*, char*); static int addarg(struct arg_val*, char*);
/* /*
* start_login(host) * start_login(host)
@@ -1360,15 +1215,14 @@ int addarg(struct arg_val*, char*);
void start_login(char *host, int autologin, char *name) void start_login(char *host, int autologin, char *name)
{ {
char *cp;
struct arg_val argv; struct arg_val argv;
struct timeval tmp;
#ifdef HAVE_UTMPX_H #ifdef HAVE_UTMPX
char id_buf[3]; char id_buf[3];
int ptynum; int ptynum;
int pid = getpid(); int pid = getpid();
struct utmpx utmpx; struct utmpx utmpx;
struct timeval tmp;
/* /*
* Create utmp entry for child * Create utmp entry for child
@@ -1405,40 +1259,11 @@ void start_login(char *host, int autologin, char *name)
argv.size=0; argv.size=0;
argv.argc=0; argv.argc=0;
argv.argv=(char**)malloc(0); /*so we can call realloc later */ argv.argv=(char**)malloc(0); /*so we can call realloc later */
addarg(&argv, "login"); addarg(&argv, "login");
#if !defined(NO_LOGIN_H)
# if defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
/*
* Don't add the "-h host" option if we are going
* to be adding the "-r host" option down below...
*/
if ((auth_level < 0) || (autologin != AUTH_VALID))
# endif
{
addarg(&argv, "-h"); addarg(&argv, "-h");
addarg(&argv, host); addarg(&argv, host);
}
#endif
#if !defined(NO_LOGIN_P)
addarg(&argv, "-p"); addarg(&argv, "-p");
#endif #ifdef AUTHENTICATION
#ifdef LINEMODE
/*
* Set the environment variable "LINEMODE" to either
* "real" or "kludge" if we are operating in either
* real or kludge linemode.
*/
if (lmodetype == REAL_LINEMODE)
setenv("LINEMODE", "real", 1);
# ifdef KLUDGELINEMODE
else if (lmodetype == KLUDGE_LINEMODE || lmodetype == KLUDGE_OK)
setenv("LINEMODE", "kludge", 1);
# endif
#endif
#if defined (AUTHENTICATION)
if (auth_level < 0 || autologin != AUTH_VALID) { if (auth_level < 0 || autologin != AUTH_VALID) {
if(!no_warn) if(!no_warn)
printf("User not authenticated. " printf("User not authenticated. "
@@ -1457,101 +1282,14 @@ void start_login(char *host, int autologin, char *name)
} }
} }
if (auth_level >= 0 && autologin == AUTH_VALID) { if (auth_level >= 0 && autologin == AUTH_VALID) {
# if !defined(NO_LOGIN_F)
addarg(&argv, "-f"); addarg(&argv, "-f");
addarg(&argv, "--"); addarg(&argv, "--");
addarg(&argv, name); addarg(&argv, name);
# else
# if defined(LOGIN_R)
/*
* We don't have support for "login -f", but we
* can fool /bin/login into thinking that we are
* rlogind, and allow us to log in without a
* password. The rlogin protocol expects
* local-user\0remote-user\0term/speed\0
*/
if (ourpty > 2) {
char *cp;
char speed[128];
int isecho, israw, xpty, len;
extern int def_rspeed;
# ifndef LOGIN_HOST
/*
* Tell login that we are coming from "localhost".
* If we passed in the real host name, then the
* user would have to allow .rhost access from
* every machine that they want authenticated
* access to work from, which sort of defeats
* the purpose of an authenticated login...
* So, we tell login that the session is coming
* from "localhost", and the user will only have
* to have "localhost" in their .rhost file.
*/
# define LOGIN_HOST "localhost"
# endif /* LOGIN_HOST */
addarg(&argv, "-r");
addarg(&argv, LOGIN_HOST);
xpty = ourpty;
#ifdef STREAMSPTY
if (really_stream)
ttyfd = 0;
else
#endif
pty = 0;
init_termbuf();
isecho = tty_isecho();
israw = tty_israw();
if (isecho || !israw) {
tty_setecho(0); /* Turn off echo */
tty_setraw(1); /* Turn on raw */
set_termbuf();
}
len = strlen(name)+1;
write(xpty, name, len);
write(xpty, name, len);
snprintf(speed, sizeof(speed),
"%s/%d", (cp = getenv("TERM")) ? cp : "",
(def_rspeed > 0) ? def_rspeed : 9600);
len = strlen(speed)+1;
write(xpty, speed, len);
if (isecho || !israw) {
init_termbuf();
tty_setecho(isecho);
tty_setraw(israw);
set_termbuf();
if (!israw) {
/*
* Write a newline to ensure
* that login will be able to
* read the line...
*/
write(xpty, "\n", 1);
}
}
ourpty = xpty;
}
# else /* LOGIN_R */
addarg(&argv, "--");
addarg(&argv, name);
# endif
# endif /* NO_LOGIN_F */
} /* else */ /* esc@magic.fi; removed stupid else */ } /* else */ /* esc@magic.fi; removed stupid else */
#endif #endif
if (getenv("USER")) { if (getenv("USER")) {
addarg(&argv, "--"); addarg(&argv, "--");
addarg(&argv, getenv("USER")); addarg(&argv, strdup(getenv("USER")));
#if defined(LOGIN_ARGS) && defined(NO_LOGIN_P)
{
char **cpp;
for (cpp = environ; *cpp; cpp++) {
addarg(&argv, *cpp);
}
}
#endif
/* /*
* Assume that login will set the USER variable * Assume that login will set the USER variable
* correctly. For SysV systems, this means that * correctly. For SysV systems, this means that
@@ -1564,10 +1302,6 @@ void start_login(char *host, int autologin, char *name)
*/ */
unsetenv("USER"); unsetenv("USER");
} }
#if defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
if (ourpty > 2)
close(ourpty);
#endif
closelog(); closelog();
/* /*
* This sleep(1) is in here so that telnetd can * This sleep(1) is in here so that telnetd can
@@ -1575,14 +1309,6 @@ void start_login(char *host, int autologin, char *name)
* the login banner message gets lost... * the login banner message gets lost...
*/ */
sleep(1); sleep(1);
#ifdef SHOW_LOGIN_ARGS
{
int i;
for(i=0;argv.argv[i];i++)
fprintf(stderr, "%s ", argv.argv[i]);
fprintf(stderr, "\n");
}
#endif
execv(new_login, argv.argv); execv(new_login, argv.argv);
@@ -1593,7 +1319,7 @@ void start_login(char *host, int autologin, char *name)
int addarg(struct arg_val *argv, char *val) static int addarg(struct arg_val *argv, char *val)
{ {
if(argv->size <= argv->argc+1){ if(argv->size <= argv->argc+1){
argv->argv = (char**)realloc(argv->argv, sizeof(char*) * (argv->size + 10)); argv->argv = (char**)realloc(argv->argv, sizeof(char*) * (argv->size + 10));
@@ -1614,7 +1340,7 @@ int addarg(struct arg_val *argv, char *val)
* remove the utmp entry for this person. * remove the utmp entry for this person.
*/ */
#ifdef HAVE_UTMPX_H #ifdef HAVE_UTMPX
static void static void
rmut(void) rmut(void)
{ {
@@ -1638,17 +1364,12 @@ rmut(void)
if (utxp) { if (utxp) {
strcpy(utxp->ut_user, ""); strcpy(utxp->ut_user, "");
utxp->ut_type = DEAD_PROCESS; utxp->ut_type = DEAD_PROCESS;
#ifdef __osf__ /* XXX */
utxp->ut_exit.ut_termination = 0;
utxp->ut_exit.ut_exit = 0;
#else
#ifdef _STRUCT___EXIT_STATUS #ifdef _STRUCT___EXIT_STATUS
utxp->ut_exit.__e_termination = 0; utxp->ut_exit.__e_termination = 0;
utxp->ut_exit.__e_exit = 0; utxp->ut_exit.__e_exit = 0;
#else #else
utxp->ut_exit.e_termination = 0; utxp->ut_exit.e_termination = 0;
utxp->ut_exit.e_exit = 0; utxp->ut_exit.e_exit = 0;
#endif
#endif #endif
gettimeofday(&tmp, NULL); gettimeofday(&tmp, NULL);
utxp->ut_tv.tv_sec = tmp.tv_sec; utxp->ut_tv.tv_sec = tmp.tv_sec;
@@ -1662,7 +1383,7 @@ rmut(void)
} /* end of rmut */ } /* end of rmut */
#endif #endif
#if !defined(HAVE_UTMPX_H) && !(defined(CRAY) || defined(__hpux)) && BSD <= 43 #if !defined(HAVE_UTMPX) && !(defined(_CRAY) || defined(__hpux)) && BSD <= 43
static void static void
rmut(void) rmut(void)
{ {
@@ -1719,7 +1440,7 @@ rmut(void)
} /* end of rmut */ } /* end of rmut */
#endif /* CRAY */ #endif /* CRAY */
#if defined(__hpux) && !defined(HAVE_UTMPX_H) #if defined(__hpux) && !defined(HAVE_UTMPX)
static void static void
rmut (char *line) rmut (char *line)
{ {
@@ -1770,7 +1491,7 @@ rmut (char *line)
void void
cleanup(int sig) cleanup(int sig)
{ {
# ifdef CRAY #ifdef _CRAY
static int incleanup = 0; static int incleanup = 0;
int t; int t;
int child_status; /* status of child process as returned by waitpid */ int child_status; /* status of child process as returned by waitpid */
@@ -1806,14 +1527,14 @@ cleanup(int sig)
t = cleantmp(&wtmp); t = cleantmp(&wtmp);
setutent(); /* just to make sure */ setutent(); /* just to make sure */
# endif /* CRAY */ #endif /* CRAY */
rmut(line); rmut(line);
close(ourpty); close(ourpty);
shutdown(net, 2); shutdown(net, 2);
# ifdef CRAY #ifdef _CRAY
if (t == 0) if (t == 0)
cleantmp(&wtmp); cleantmp(&wtmp);
# endif /* CRAY */ #endif /* CRAY */
exit(1); exit(1);
} }
@@ -1822,7 +1543,7 @@ cleanup(int sig)
void void
cleanup(int sig) cleanup(int sig)
{ {
#if defined(HAVE_UTMPX_H) || !defined(HAVE_LOGWTMP) #if defined(HAVE_UTMPX) || !defined(HAVE_LOGWTMP)
rmut(); rmut();
#ifdef HAVE_VHANGUP #ifdef HAVE_VHANGUP
vhangup(); /* XXX */ vhangup(); /* XXX */
@@ -1845,7 +1566,7 @@ cleanup(int sig)
#endif /* PARENT_DOES_UTMP */ #endif /* PARENT_DOES_UTMP */
#if defined(PARENT_DOES_UTMP) #ifdef PARENT_DOES_UTMP
/* /*
* _utmp_sig_rcv * _utmp_sig_rcv
* utmp_sig_init * utmp_sig_init
@@ -1859,7 +1580,7 @@ cleanup(int sig)
static int caught=0; /* NZ when signal intercepted */ static int caught=0; /* NZ when signal intercepted */
static void (*func)(); /* address of previous handler */ static void (*func)(); /* address of previous handler */
void void
_utmp_sig_rcv(sig) _utmp_sig_rcv(sig)
int sig; int sig;
{ {
@@ -1867,7 +1588,7 @@ _utmp_sig_rcv(sig)
signal(SIGUSR1, func); signal(SIGUSR1, func);
} }
void void
utmp_sig_init() utmp_sig_init()
{ {
/* /*
@@ -1877,7 +1598,7 @@ utmp_sig_init()
fatalperror(net, "telnetd/signal"); fatalperror(net, "telnetd/signal");
} }
void void
utmp_sig_reset() utmp_sig_reset()
{ {
signal(SIGUSR1, func); /* reset handler to default */ signal(SIGUSR1, func); /* reset handler to default */
@@ -1888,7 +1609,7 @@ utmp_sig_reset()
# define sigon() /* do nothing */ # define sigon() /* do nothing */
# endif # endif
void void
utmp_sig_wait() utmp_sig_wait()
{ {
/* /*
@@ -1902,17 +1623,17 @@ utmp_sig_wait()
sigon(); /* turn on signals again */ sigon(); /* turn on signals again */
} }
void void
utmp_sig_notify(pid) utmp_sig_notify(pid)
{ {
kill(pid, SIGUSR1); kill(pid, SIGUSR1);
} }
# ifdef CRAY #ifdef _CRAY
static int gotsigjob = 0; static int gotsigjob = 0;
/*ARGSUSED*/ /*ARGSUSED*/
void void
sigjob(sig) sigjob(sig)
int sig; int sig;
{ {
@@ -1934,7 +1655,7 @@ sigjob(sig)
* to find the correct $TMPDIR to cleanup. * to find the correct $TMPDIR to cleanup.
*/ */
struct utmp * struct utmp *
jid_getutid(jid) jid_getutid(jid)
int jid; int jid;
{ {
@@ -1958,7 +1679,7 @@ jid_getutid(jid)
* when this is called the second time it will wait * when this is called the second time it will wait
* for the signal that the job is done. * for the signal that the job is done.
*/ */
int int
cleantmp(wtp) cleantmp(wtp)
struct utmp *wtp; struct utmp *wtp;
{ {
@@ -1999,7 +1720,7 @@ cleantmp(wtp)
return(ret); return(ret);
} }
int int
jobend(jid, path, user) jobend(jid, path, user)
int jid; int jid;
char *path; char *path;
@@ -2085,5 +1806,5 @@ cleantmpdir(jid, tpath, user)
break; break;
} }
} }
# endif /* CRAY */ #endif /* CRAY */
#endif /* defined(PARENT_DOES_UTMP) && !defined(NEWINIT) */ #endif /* defined(PARENT_DOES_UTMP) */

View File

@@ -31,47 +31,23 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifdef HAVE_CONFIG_H #include "telnetd.h"
#include <config.h>
#endif
#ifdef SOCKS
#include <socks.h>
#endif
RCSID("$Id$"); RCSID("$Id$");
#include "telnetd.h" #ifdef _SC_CRAY_SECURE_SYS
#include "pathnames.h"
#if defined(_SC_CRAY_SECURE_SYS) && !defined(SCM_SECURITY)
/*
* UNICOS 6.0/6.1 do not have SCM_SECURITY defined, so we can
* use it to tell us to turn off all the socket security code,
* since that is only used in UNICOS 7.0 and later.
*/
# undef _SC_CRAY_SECURE_SYS
#endif
#if defined(_SC_CRAY_SECURE_SYS)
#include <sys/sysv.h> #include <sys/sysv.h>
#include <sys/secdev.h> #include <sys/secdev.h>
# ifdef SO_SEC_MULTI /* 8.0 code */
#include <sys/secparm.h> #include <sys/secparm.h>
#include <sys/usrv.h> #include <sys/usrv.h>
# endif /* SO_SEC_MULTI */
int secflag; int secflag;
char tty_dev[16]; char tty_dev[16];
struct secdev dv; struct secdev dv;
struct sysv sysv; struct sysv sysv;
# ifdef SO_SEC_MULTI /* 8.0 code */
struct socksec ss; struct socksec ss;
# else /* SO_SEC_MULTI */ /* 7.0 code */
struct socket_security ss;
# endif /* SO_SEC_MULTI */
#endif /* _SC_CRAY_SECURE_SYS */ #endif /* _SC_CRAY_SECURE_SYS */
#if defined(AUTHENTICATION) #ifdef AUTHENTICATION
#include <libtelnet/auth.h>
int auth_level = 0; int auth_level = 0;
#endif #endif
@@ -87,7 +63,7 @@ int registerd_host_only = 0;
#ifdef HAVE_SYS_STREAM_H #ifdef HAVE_SYS_STREAM_H
#include <sys/stream.h> #include <sys/stream.h>
#endif #endif
#if defined(_AIX) #ifdef _AIX
#include <sys/termio.h> #include <sys/termio.h>
#endif #endif
# ifdef HAVE_SYS_STRTTY_H # ifdef HAVE_SYS_STRTTY_H
@@ -104,6 +80,12 @@ int registerd_host_only = 0;
# ifdef HAVE_SYS_PTYVAR_H # ifdef HAVE_SYS_PTYVAR_H
# include <sys/ptyvar.h> # include <sys/ptyvar.h>
# endif # endif
#ifdef HAVE_CURSES_H
#include <curses.h>
#endif
#ifdef HAVE_TERM_H
#include <term.h>
#endif
/* /*
* Because of the way ptyibuf is used with streams messages, we need * Because of the way ptyibuf is used with streams messages, we need
@@ -132,7 +114,7 @@ char ptyibuf2[BUFSIZ];
int hostinfo = 1; /* do we print login banner? */ int hostinfo = 1; /* do we print login banner? */
#ifdef CRAY #ifdef _CRAY
extern int newmap; /* nonzero if \n maps to ^M^J */ extern int newmap; /* nonzero if \n maps to ^M^J */
int lowpty = 0, highpty; /* low, high pty numbers */ int lowpty = 0, highpty; /* low, high pty numbers */
#endif /* CRAY */ #endif /* CRAY */
@@ -149,17 +131,14 @@ extern void usage (void);
* passed off to getopt(). * passed off to getopt().
*/ */
char valid_opts[] = { char valid_opts[] = {
'd', ':', 'h', 'k', 'n', 'S', ':', 'u', ':', 'U', 'B', 'd', ':', 'h', 'k', 'l', 'n', 'S', ':', 'u', ':', 'U',
#ifdef AUTHENTICATION #ifdef AUTHENTICATION
'a', ':', 'X', ':', 'a', ':', 'X', ':',
#endif #endif
#ifdef DIAGNOSTICS #ifdef DIAGNOSTICS
'D', ':', 'D', ':',
#endif #endif
#ifdef LINEMODE #ifdef _CRAY
'l',
#endif
#ifdef CRAY
'r', ':', 'r', ':',
#endif #endif
'L', ':', 'L', ':',
@@ -189,11 +168,11 @@ int main(int argc, char **argv)
nfrontp = nbackp = netobuf; nfrontp = nbackp = netobuf;
progname = *argv; progname = *argv;
#if defined(ENCRYPTION) #ifdef ENCRYPTION
nclearto = 0; nclearto = 0;
#endif #endif
#ifdef CRAY #ifdef _CRAY
/* /*
* Get number of pty's before trying to process options, * Get number of pty's before trying to process options,
* which may include changing pty range. * which may include changing pty range.
@@ -234,6 +213,8 @@ int main(int argc, char **argv)
break; break;
#endif /* AUTHENTICATION */ #endif /* AUTHENTICATION */
case 'B': /* BFTP mode is not supported any more */
break;
case 'd': case 'd':
if (strcmp(optarg, "ebug") == 0) { if (strcmp(optarg, "ebug") == 0) {
debug++; debug++;
@@ -270,25 +251,15 @@ int main(int argc, char **argv)
hostinfo = 0; hostinfo = 0;
break; break;
#ifdef LINEMODE case 'k': /* Linemode is not supported any more */
case 'l': case 'l':
alwayslinemode = 1;
break;
#endif /* LINEMODE */
case 'k':
#if defined(LINEMODE) && defined(KLUDGELINEMODE)
lmodetype = NO_AUTOKLUDGE;
#else
/* ignore -k option if built without kludge linemode */
#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
break; break;
case 'n': case 'n':
keepalive = 0; keepalive = 0;
break; break;
#ifdef CRAY #ifdef _CRAY
case 'r': case 'r':
{ {
char *strchr(); char *strchr();
@@ -389,7 +360,7 @@ int main(int argc, char **argv)
/* NOT REACHED */ /* NOT REACHED */
} }
#if defined(_SC_CRAY_SECURE_SYS) #ifdef _SC_CRAY_SECURE_SYS
secflag = sysconf(_SC_CRAY_SECURE_SYS); secflag = sysconf(_SC_CRAY_SECURE_SYS);
/* /*
@@ -397,10 +368,8 @@ int main(int argc, char **argv)
*/ */
if (secflag) { if (secflag) {
int szss = sizeof(ss); int szss = sizeof(ss);
#ifdef SO_SEC_MULTI /* 8.0 code */
int sock_multi; int sock_multi;
int szi = sizeof(int); int szi = sizeof(int);
#endif /* SO_SEC_MULTI */
memset(&dv, 0, sizeof(dv)); memset(&dv, 0, sizeof(dv));
@@ -461,7 +430,7 @@ int main(int argc, char **argv)
#if defined(IPPROTO_IP) && defined(IP_TOS) && defined(HAVE_SETSOCKOPT) #if defined(IPPROTO_IP) && defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
{ {
# if defined(HAS_GETTOS) # ifdef HAS_GETTOS
struct tosent *tp; struct tosent *tp;
if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
tos = tp->t_tos; tos = tp->t_tos;
@@ -480,7 +449,7 @@ int main(int argc, char **argv)
/* NOTREACHED */ /* NOTREACHED */
} /* end of main */ } /* end of main */
void void
usage() usage()
{ {
fprintf(stderr, "Usage: telnetd"); fprintf(stderr, "Usage: telnetd");
@@ -495,15 +464,9 @@ usage()
fprintf(stderr, " [-edebug]"); fprintf(stderr, " [-edebug]");
#endif #endif
fprintf(stderr, " [-h]"); fprintf(stderr, " [-h]");
#if defined(LINEMODE) && defined(KLUDGELINEMODE)
fprintf(stderr, " [-k]");
#endif
#ifdef LINEMODE
fprintf(stderr, " [-l]");
#endif
fprintf(stderr, " [-L login]"); fprintf(stderr, " [-L login]");
fprintf(stderr, " [-n]"); fprintf(stderr, " [-n]");
#ifdef CRAY #ifdef _CRAY
fprintf(stderr, " [-r[lowpty]-[highpty]]"); fprintf(stderr, " [-r[lowpty]-[highpty]]");
#endif #endif
fprintf(stderr, "\n\t"); fprintf(stderr, "\n\t");
@@ -528,15 +491,14 @@ static unsigned char ttytype_sbbuf[] = {
IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE
}; };
int int
getterminaltype(name) getterminaltype(char *name)
char *name;
{ {
int retval = -1; int retval = -1;
void _gettermname(); void _gettermname();
settimer(baseline); settimer(baseline);
#if defined(AUTHENTICATION) #ifdef AUTHENTICATION
/* /*
* Handle the Authentication option before we do anything else. * Handle the Authentication option before we do anything else.
*/ */
@@ -548,7 +510,7 @@ getterminaltype(name)
} }
#endif #endif
#if defined(ENCRYPTION) #ifdef ENCRYPTION
send_will(TELOPT_ENCRYPT, 1); send_will(TELOPT_ENCRYPT, 1);
send_do(TELOPT_ENCRYPT, 1); /* esc@magic.fi */ send_do(TELOPT_ENCRYPT, 1); /* esc@magic.fi */
#endif #endif
@@ -558,7 +520,7 @@ getterminaltype(name)
send_do(TELOPT_NEW_ENVIRON, 1); send_do(TELOPT_NEW_ENVIRON, 1);
send_do(TELOPT_OLD_ENVIRON, 1); send_do(TELOPT_OLD_ENVIRON, 1);
while ( while (
#if defined(ENCRYPTION) #ifdef ENCRYPTION
his_do_dont_is_changing(TELOPT_ENCRYPT) || his_do_dont_is_changing(TELOPT_ENCRYPT) ||
#endif #endif
his_will_wont_is_changing(TELOPT_TTYPE) || his_will_wont_is_changing(TELOPT_TTYPE) ||
@@ -568,7 +530,7 @@ getterminaltype(name)
his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) { his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) {
ttloop(); ttloop();
} }
#if defined(ENCRYPTION) #ifdef ENCRYPTION
/* /*
* Wait for the negotiation of what type of encryption we can * Wait for the negotiation of what type of encryption we can
* send with. If autoencrypt is not set, this will just return. * send with. If autoencrypt is not set, this will just return.
@@ -581,38 +543,33 @@ getterminaltype(name)
static unsigned char sb[] = static unsigned char sb[] =
{ IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
memmove(nfrontp, sb, sizeof sb); net_write (sb, sizeof sb);
nfrontp += sizeof sb;
DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
} }
if (his_state_is_will(TELOPT_XDISPLOC)) { if (his_state_is_will(TELOPT_XDISPLOC)) {
static unsigned char sb[] = static unsigned char sb[] =
{ IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE }; { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
memmove(nfrontp, sb, sizeof sb); net_write (sb, sizeof sb);
nfrontp += sizeof sb;
DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
} }
if (his_state_is_will(TELOPT_NEW_ENVIRON)) { if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
static unsigned char sb[] = static unsigned char sb[] =
{ IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE }; { IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE };
memmove(nfrontp, sb, sizeof sb); net_write (sb, sizeof sb);
nfrontp += sizeof sb;
DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
} }
else if (his_state_is_will(TELOPT_OLD_ENVIRON)) { else if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
static unsigned char sb[] = static unsigned char sb[] =
{ IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE }; { IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE };
memmove(nfrontp, sb, sizeof sb); net_write (sb, sizeof sb);
nfrontp += sizeof sb;
DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
} }
if (his_state_is_will(TELOPT_TTYPE)) { if (his_state_is_will(TELOPT_TTYPE)) {
memmove(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); net_write (ttytype_sbbuf, sizeof ttytype_sbbuf);
nfrontp += sizeof ttytype_sbbuf;
DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2, DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
sizeof ttytype_sbbuf - 2);); sizeof ttytype_sbbuf - 2););
} }
@@ -676,7 +633,7 @@ getterminaltype(name)
return(retval); return(retval);
} /* end of getterminaltype */ } /* end of getterminaltype */
void void
_gettermname() _gettermname()
{ {
/* /*
@@ -687,17 +644,15 @@ _gettermname()
if (his_state_is_wont(TELOPT_TTYPE)) if (his_state_is_wont(TELOPT_TTYPE))
return; return;
settimer(baseline); settimer(baseline);
memmove(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); net_write (ttytype_sbbuf, sizeof ttytype_sbbuf);
nfrontp += sizeof ttytype_sbbuf;
DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2, DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
sizeof ttytype_sbbuf - 2);); sizeof ttytype_sbbuf - 2););
while (sequenceIs(ttypesubopt, baseline)) while (sequenceIs(ttypesubopt, baseline))
ttloop(); ttloop();
} }
int int
terminaltypeok(s) terminaltypeok(char *s)
char *s;
{ {
char buf[1024]; char buf[1024];
@@ -726,10 +681,10 @@ extern void telnet (int, int);
/* /*
* Get a pty, scan input lines. * Get a pty, scan input lines.
*/ */
void doit(struct sockaddr_in *who) void
doit(struct sockaddr_in *who)
{ {
const char *host; char *host;
int t;
struct hostent *hp; struct hostent *hp;
int level; int level;
int ptynum; int ptynum;
@@ -743,7 +698,7 @@ void doit(struct sockaddr_in *who)
fatal(net, "All network ports in use"); fatal(net, "All network ports in use");
set_utid(); set_utid();
#if defined(_SC_CRAY_SECURE_SYS) #ifdef _SC_CRAY_SECURE_SYS
/* /*
* set ttyp line security label * set ttyp line security label
*/ */
@@ -765,7 +720,7 @@ void doit(struct sockaddr_in *who)
if (hp == NULL && registerd_host_only) { if (hp == NULL && registerd_host_only) {
fatal(net, "Couldn't resolve your address into a host name.\r\n\ fatal(net, "Couldn't resolve your address into a host name.\r\n\
Please contact your net administrator"); Please contact your net administrator");
} else if (hp) { } else if (hp) {
host = hp->h_name; host = hp->h_name;
} else { } else {
@@ -803,7 +758,7 @@ void doit(struct sockaddr_in *who)
inet_ntoa(who->sin_addr), inet_ntoa(who->sin_addr),
sizeof(remote_host_name)-1); sizeof(remote_host_name)-1);
#if defined(AUTHENTICATION) || defined(ENCRYPTION) #ifdef AUTHENTICATION
auth_encrypt_init(hostname, host, "TELNETD", 1); auth_encrypt_init(hostname, host, "TELNETD", 1);
#endif #endif
@@ -820,7 +775,7 @@ void doit(struct sockaddr_in *who)
*/ */
startslave(host, level, user_name); startslave(host, level, user_name);
#if defined(_SC_CRAY_SECURE_SYS) #ifdef _SC_CRAY_SECURE_SYS
if (secflag) { if (secflag) {
if (setulvl(dv.dv_actlvl) < 0) if (setulvl(dv.dv_actlvl) < 0)
fatal(net,"cannot setulvl()"); fatal(net,"cannot setulvl()");
@@ -837,9 +792,8 @@ void doit(struct sockaddr_in *who)
* Main loop. Select from pty and network, and * Main loop. Select from pty and network, and
* hand data to telnet receiver finite state machine. * hand data to telnet receiver finite state machine.
*/ */
void void
telnet(f, p) telnet(int f, int p)
int f, p;
{ {
int on = 1; int on = 1;
#define TABBUFSIZ 512 #define TABBUFSIZ 512
@@ -876,17 +830,6 @@ telnet(f, p)
*/ */
send_do(TELOPT_ECHO, 1); send_do(TELOPT_ECHO, 1);
#ifdef LINEMODE
if (his_state_is_wont(TELOPT_LINEMODE)) {
/* Query the peer for linemode support by trying to negotiate
* the linemode option.
*/
linemode = 0;
editmode = 0;
send_do(TELOPT_LINEMODE, 1); /* send do linemode */
}
#endif /* LINEMODE */
/* /*
* Send along a couple of other options that we wish to negotiate. * Send along a couple of other options that we wish to negotiate.
*/ */
@@ -936,9 +879,8 @@ telnet(f, p)
*/ */
if (his_want_state_is_will(TELOPT_ECHO)) { if (his_want_state_is_will(TELOPT_ECHO)) {
DIAG(TD_OPTIONS, DIAG(TD_OPTIONS,
{snprintf(nfrontp, BUFSIZ - (nfrontp - netobuf), {output_data("td: simulating recv\r\n");
"td: simulating recv\r\n"); });
nfrontp += strlen(nfrontp);});
willoption(TELOPT_ECHO); willoption(TELOPT_ECHO);
} }
@@ -960,15 +902,6 @@ telnet(f, p)
ioctl(p, TIOCPKT, (char *)&on); ioctl(p, TIOCPKT, (char *)&on);
#endif #endif
#if defined(LINEMODE) && defined(KLUDGELINEMODE)
/*
* Continuing line mode support. If client does not support
* real linemode, attempt to negotiate kludge linemode by sending
* the do timing mark sequence.
*/
if (lmodetype < REAL_LINEMODE)
send_do(TELOPT_TM, 1);
#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
/* /*
* Call telrcv() once to pick up anything received during * Call telrcv() once to pick up anything received during
@@ -1020,21 +953,8 @@ telnet(f, p)
if (getenv("USER")) if (getenv("USER"))
hostinfo = 0; hostinfo = 0;
if (getent(defent, "default") == 1) {
char *getstr();
char *cp=defstrs;
HE = getstr("he", &cp);
HN = getstr("hn", &cp);
IM = getstr("im", &cp);
if (HN && *HN)
strcpy(host_name, HN);
if (IM == 0)
IM = "";
} else {
IM = DEFAULT_IM; IM = DEFAULT_IM;
HE = 0; HE = 0;
}
edithost(HE, host_name); edithost(HE, host_name);
if (hostinfo && *IM) if (hostinfo && *IM)
putf(IM, ptyibuf2); putf(IM, ptyibuf2);
@@ -1043,18 +963,10 @@ telnet(f, p)
strncat(ptyibuf2, ptyip, pcc+1); strncat(ptyibuf2, ptyip, pcc+1);
ptyip = ptyibuf2; ptyip = ptyibuf2;
pcc = strlen(ptyip); pcc = strlen(ptyip);
#ifdef LINEMODE
/*
* Last check to make sure all our states are correct.
*/
init_termbuf();
localstat();
#endif /* LINEMODE */
DIAG(TD_REPORT, DIAG(TD_REPORT, {
{snprintf(nfrontp, BUFSIZ - (nfrontp - netobuf), output_data("td: Entering processing loop\r\n");
"td: Entering processing loop\r\n"); });
nfrontp += strlen(nfrontp);});
nfd = ((f > p) ? f : p) + 1; nfd = ((f > p) ? f : p) + 1;
@@ -1107,7 +1019,7 @@ telnet(f, p)
* Something to read from the network... * Something to read from the network...
*/ */
if (FD_ISSET(net, &ibits)) { if (FD_ISSET(net, &ibits)) {
#if !defined(SO_OOBINLINE) #ifndef SO_OOBINLINE
/* /*
* In 4.2 (and 4.3 beta) systems, the * In 4.2 (and 4.3 beta) systems, the
* OOB indication and data handling in the kernel * OOB indication and data handling in the kernel
@@ -1172,10 +1084,9 @@ telnet(f, p)
} }
netip = netibuf; netip = netibuf;
} }
DIAG((TD_REPORT | TD_NETDATA), DIAG((TD_REPORT | TD_NETDATA), {
{snprintf(nfrontp, BUFSIZ - (nfrontp - netobuf), output_data("td: netread %d chars\r\n", ncc);
"td: netread %d chars\r\n", ncc); });
nfrontp += strlen(nfrontp);});
DIAG(TD_NETDATA, printdata("nd", netip, ncc)); DIAG(TD_NETDATA, printdata("nd", netip, ncc));
} }
@@ -1204,16 +1115,6 @@ telnet(f, p)
} else { } else {
if (pcc <= 0) if (pcc <= 0)
break; break;
#ifdef LINEMODE
/*
* If ioctl from pty, pass it through net
*/
if (ptyibuf[0] & TIOCPKT_IOCTL) {
copy_termbuf(ptyibuf+1, pcc-1);
localstat();
pcc = 1;
}
#endif /* LINEMODE */
if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) { if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {
netclear(); /* clear buffer back */ netclear(); /* clear buffer back */
#ifndef NO_URGENT #ifndef NO_URGENT
@@ -1223,8 +1124,8 @@ telnet(f, p)
* royally if we send them urgent * royally if we send them urgent
* mode data. * mode data.
*/ */
*nfrontp++ = IAC; output_data ("%c%c", IAC, DM);
*nfrontp++ = DM;
neturg = nfrontp-1; /* off by one XXX */ neturg = nfrontp-1; /* off by one XXX */
DIAG(TD_OPTIONS, DIAG(TD_OPTIONS,
printoption("td: send IAC", DM)); printoption("td: send IAC", DM));
@@ -1238,15 +1139,11 @@ telnet(f, p)
ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0; ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0;
if (newflow != flowmode) { if (newflow != flowmode) {
flowmode = newflow; flowmode = newflow;
snprintf(nfrontp, output_data("%c%c%c%c%c%c",
BUFSIZ -
(nfrontp - netobuf),
"%c%c%c%c%c%c",
IAC, SB, TELOPT_LFLOW, IAC, SB, TELOPT_LFLOW,
flowmode ? LFLOW_ON flowmode ? LFLOW_ON
: LFLOW_OFF, : LFLOW_OFF,
IAC, SE); IAC, SE);
nfrontp += 6;
DIAG(TD_OPTIONS, printsub('>', DIAG(TD_OPTIONS, printsub('>',
(unsigned char *)nfrontp-4, (unsigned char *)nfrontp-4,
4);); 4););
@@ -1258,7 +1155,7 @@ telnet(f, p)
} }
while (pcc > 0) { while (pcc > 0) {
if ((&netobuf[BUFSIZ] - nfrontp) < 2) if ((&netobuf[BUFSIZ] - nfrontp) < 3)
break; break;
c = *ptyip++ & 0377, pcc--; c = *ptyip++ & 0377, pcc--;
if (c == IAC) if (c == IAC)
@@ -1281,7 +1178,7 @@ telnet(f, p)
ptyflush(); ptyflush();
} }
cleanup(0); cleanup(0);
} /* end of telnet */ }
#ifndef TCSIG #ifndef TCSIG
# ifdef TIOCSIG # ifdef TIOCSIG
@@ -1291,9 +1188,10 @@ telnet(f, p)
#ifdef STREAMSPTY #ifdef STREAMSPTY
int flowison = -1; /* current state of flow: -1 is unknown */ int flowison = -1; /* current state of flow: -1 is unknown */
int readstream(int p, char *ibuf, int bufsize) int
readstream(int p, char *ibuf, int bufsize)
{ {
int flags = 0; int flags = 0;
int ret = 0; int ret = 0;
@@ -1387,7 +1285,7 @@ int readstream(int p, char *ibuf, int bufsize)
* If it is in raw mode, just write NULL; * If it is in raw mode, just write NULL;
* otherwise, write intr char. * otherwise, write intr char.
*/ */
void void
interrupt() interrupt()
{ {
ptyflush(); /* half-hearted */ ptyflush(); /* half-hearted */
@@ -1416,7 +1314,7 @@ interrupt()
* If it is in raw mode, just write NULL; * If it is in raw mode, just write NULL;
* otherwise, write quit char. * otherwise, write quit char.
*/ */
void void
sendbrk() sendbrk()
{ {
ptyflush(); /* half-hearted */ ptyflush(); /* half-hearted */
@@ -1429,7 +1327,7 @@ sendbrk()
#endif /* TCSIG */ #endif /* TCSIG */
} }
void void
sendsusp() sendsusp()
{ {
#ifdef SIGTSTP #ifdef SIGTSTP
@@ -1447,7 +1345,7 @@ sendsusp()
* When we get an AYT, if ^T is enabled, use that. Otherwise, * When we get an AYT, if ^T is enabled, use that. Otherwise,
* just send back "[Yes]". * just send back "[Yes]".
*/ */
void void
recv_ayt() recv_ayt()
{ {
#if defined(SIGINFO) && defined(TCSIG) #if defined(SIGINFO) && defined(TCSIG)
@@ -1456,22 +1354,14 @@ recv_ayt()
return; return;
} }
#endif #endif
strcpy(nfrontp, "\r\n[Yes]\r\n"); output_data("\r\n[Yes]\r\n");
nfrontp += 9;
} }
void void
doeof() doeof()
{ {
init_termbuf(); init_termbuf();
#if defined(LINEMODE) && (VEOF == VMIN)
if (!tty_isediting()) {
extern char oldeofc;
*pfrontp++ = oldeofc;
return;
}
#endif
*pfrontp++ = slctab[SLC_EOF].sptr ? *pfrontp++ = slctab[SLC_EOF].sptr ?
(unsigned char)*slctab[SLC_EOF].sptr : '\004'; (unsigned char)*slctab[SLC_EOF].sptr : '\004';
} }

View File

@@ -34,9 +34,119 @@
*/ */
#include <config.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#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 */
#ifndef _CRAY
#include <sys/wait.h>
#endif /* CRAY */
#include <fcntl.h>
#include <sys/file.h>
#include <sys/stat.h>
/* including both <sys/ioctl.h> and <termios.h> in SunOS 4 generates a
lot of warnings */
#if defined(HAVE_SYS_IOCTL_H) && SunOS != 4
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>
#include <netdb.h>
#include <syslog.h>
#ifndef LOG_DAEMON
#define LOG_DAEMON 0
#endif
#ifndef LOG_ODELAY
#define LOG_ODELAY 0
#endif
#include <ctype.h>
#ifdef HAVE_CURSES_H
#include <curses.h>
#endif
#include <termios.h>
#include <unistd.h>
#include "defs.h" #include "defs.h"
#include <arpa/telnet.h>
#ifndef _POSIX_VDISABLE
# ifdef VDISABLE
# define _POSIX_VDISABLE VDISABLE
# else
# define _POSIX_VDISABLE ((unsigned char)'\377')
# endif
#endif
#ifdef _CRAY
# ifdef CRAY1
# include <sys/pty.h>
# ifndef FD_ZERO
# include <sys/select.h>
# endif /* FD_ZERO */
# endif /* CRAY1 */
#include <memory.h>
#endif /* _CRAY */
#ifdef __hpux
#include <sys/ptyio.h>
#endif
#ifdef HAVE_UNAME
#include <sys/utsname.h>
#endif
#include "ext.h" #include "ext.h"
#include "pathnames.h"
#include <protos.h> #include <protos.h>
#ifdef SOCKS
#include <socks.h>
#endif
#ifdef KRB4
#include <des.h>
#include <krb.h>
#endif
#ifdef AUTHENTICATION
#include <libtelnet/auth.h>
#include <libtelnet/misc.h>
#ifdef ENCRYPTION
#include <libtelnet/encrypt.h>
#endif
#endif
#include <roken.h> #include <roken.h>
#ifdef DIAGNOSTICS #ifdef DIAGNOSTICS
@@ -49,3 +159,11 @@
extern char **environ; extern char **environ;
extern int errno; extern int errno;
/* prototypes */
/* appends data to nfrontp and advances */
int output_data (const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
;

View File

@@ -31,15 +31,10 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "telnetd.h"
#ifdef SOCKS
#include <socks.h>
#endif
RCSID("$Id$"); RCSID("$Id$");
#include "telnetd.h"
/* /*
* local variables * local variables
*/ */
@@ -47,333 +42,30 @@ int def_tspeed = -1, def_rspeed = -1;
#ifdef TIOCSWINSZ #ifdef TIOCSWINSZ
int def_row = 0, def_col = 0; int def_row = 0, def_col = 0;
#endif #endif
#ifdef LINEMODE
static int _terminit = 0;
#endif /* LINEMODE */
#ifdef LINEMODE
/*
* localstat
*
* This function handles all management of linemode.
*
* Linemode allows the client to do the local editing of data
* and send only complete lines to the server. Linemode state is
* based on the state of the pty driver. If the pty is set for
* external processing, then we can use linemode. Further, if we
* can use real linemode, then we can look at the edit control bits
* in the pty to determine what editing the client should do.
*
* Linemode support uses the following state flags to keep track of
* current and desired linemode state.
* alwayslinemode : true if -l was specified on the telnetd
* command line. It means to have linemode on as much as
* possible.
*
* lmodetype: signifies whether the client can
* handle real linemode, or if use of kludgeomatic linemode
* is preferred. It will be set to one of the following:
* REAL_LINEMODE : use linemode option
* NO_KLUDGE : don't initiate kludge linemode.
* KLUDGE_LINEMODE : use kludge linemode
* NO_LINEMODE : client is ignorant of linemode
*
* linemode, uselinemode : linemode is true if linemode
* is currently on, uselinemode is the state that we wish
* to be in. If another function wishes to turn linemode
* on or off, it sets or clears uselinemode.
*
* editmode, useeditmode : like linemode/uselinemode, but
* these contain the edit mode states (edit and trapsig).
*
* The state variables correspond to some of the state information
* in the pty.
* linemode:
* In real linemode, this corresponds to whether the pty
* expects external processing of incoming data.
* In kludge linemode, this more closely corresponds to the
* whether normal processing is on or not. (ICANON in
* system V, or COOKED mode in BSD.)
* If the -l option was specified (alwayslinemode), then
* an attempt is made to force external processing on at
* all times.
*
* The following heuristics are applied to determine linemode
* handling within the server.
* 1) Early on in starting up the server, an attempt is made
* to negotiate the linemode option. If this succeeds
* then lmodetype is set to REAL_LINEMODE and all linemode
* processing occurs in the context of the linemode option.
* 2) If the attempt to negotiate the linemode option failed,
* and the "-k" (don't initiate kludge linemode) isn't set,
* then we try to use kludge linemode. We test for this
* capability by sending "do Timing Mark". If a positive
* response comes back, then we assume that the client
* understands kludge linemode (ech!) and the
* lmodetype flag is set to KLUDGE_LINEMODE.
* 3) Otherwise, linemode is not supported at all and
* lmodetype remains set to NO_LINEMODE (which happens
* to be 0 for convenience).
* 4) At any time a command arrives that implies a higher
* state of linemode support in the client, we move to that
* linemode support.
*
* A short explanation of kludge linemode is in order here.
* 1) The heuristic to determine support for kludge linemode
* is to send a do timing mark. We assume that a client
* that supports timing marks also supports kludge linemode.
* A risky proposition at best.
* 2) Further negotiation of linemode is done by changing the
* the server's state regarding SGA. If server will SGA,
* then linemode is off, if server won't SGA, then linemode
* is on.
*/
void
localstat()
{
void netflush();
int need_will_echo = 0;
/*
* Check for state of BINARY options.
*/
if (tty_isbinaryin()) {
if (his_want_state_is_wont(TELOPT_BINARY))
send_do(TELOPT_BINARY, 1);
} else {
if (his_want_state_is_will(TELOPT_BINARY))
send_dont(TELOPT_BINARY, 1);
}
if (tty_isbinaryout()) {
if (my_want_state_is_wont(TELOPT_BINARY))
send_will(TELOPT_BINARY, 1);
} else {
if (my_want_state_is_will(TELOPT_BINARY))
send_wont(TELOPT_BINARY, 1);
}
/*
* Check for changes to flow control if client supports it.
*/
flowstat();
/*
* Check linemode on/off state
*/
uselinemode = tty_linemode();
/*
* If alwayslinemode is on, and pty is changing to turn it off, then
* force linemode back on.
*/
if (alwayslinemode && linemode && !uselinemode) {
uselinemode = 1;
tty_setlinemode(uselinemode);
}
#if defined(ENCRYPTION)
/*
* If the terminal is not echoing, but editing is enabled,
* something like password input is going to happen, so
* if we the other side is not currently sending encrypted
* data, ask the other side to start encrypting.
*/
if (his_state_is_will(TELOPT_ENCRYPT)) {
static int enc_passwd = 0;
if (uselinemode && !tty_isecho() && tty_isediting()
&& (enc_passwd == 0) && !decrypt_input) {
encrypt_send_request_start();
enc_passwd = 1;
} else if (enc_passwd) {
encrypt_send_request_end();
enc_passwd = 0;
}
}
#endif
/*
* Do echo mode handling as soon as we know what the
* linemode is going to be.
* If the pty has echo turned off, then tell the client that
* the server will echo. If echo is on, then the server
* will echo if in character mode, but in linemode the
* client should do local echoing. The state machine will
* not send anything if it is unnecessary, so don't worry
* about that here.
*
* If we need to send the WILL ECHO (because echo is off),
* then delay that until after we have changed the MODE.
* This way, when the user is turning off both editing
* and echo, the client will get editing turned off first.
* This keeps the client from going into encryption mode
* and then right back out if it is doing auto-encryption
* when passwords are being typed.
*/
if (uselinemode) {
if (tty_isecho())
send_wont(TELOPT_ECHO, 1);
else
need_will_echo = 1;
#ifdef KLUDGELINEMODE
if (lmodetype == KLUDGE_OK)
lmodetype = KLUDGE_LINEMODE;
#endif
}
/*
* If linemode is being turned off, send appropriate
* command and then we're all done.
*/
if (!uselinemode && linemode) {
# ifdef KLUDGELINEMODE
if (lmodetype == REAL_LINEMODE) {
# endif /* KLUDGELINEMODE */
send_dont(TELOPT_LINEMODE, 1);
# ifdef KLUDGELINEMODE
} else if (lmodetype == KLUDGE_LINEMODE)
send_will(TELOPT_SGA, 1);
# endif /* KLUDGELINEMODE */
send_will(TELOPT_ECHO, 1);
linemode = uselinemode;
goto done;
}
# ifdef KLUDGELINEMODE
/*
* If using real linemode check edit modes for possible later use.
* If we are in kludge linemode, do the SGA negotiation.
*/
if (lmodetype == REAL_LINEMODE) {
# endif /* KLUDGELINEMODE */
useeditmode = 0;
if (tty_isediting())
useeditmode |= MODE_EDIT;
if (tty_istrapsig())
useeditmode |= MODE_TRAPSIG;
if (tty_issofttab())
useeditmode |= MODE_SOFT_TAB;
if (tty_islitecho())
useeditmode |= MODE_LIT_ECHO;
# ifdef KLUDGELINEMODE
} else if (lmodetype == KLUDGE_LINEMODE) {
if (tty_isediting() && uselinemode)
send_wont(TELOPT_SGA, 1);
else
send_will(TELOPT_SGA, 1);
}
# endif /* KLUDGELINEMODE */
/*
* Negotiate linemode on if pty state has changed to turn it on.
* Send appropriate command and send along edit mode, then all done.
*/
if (uselinemode && !linemode) {
# ifdef KLUDGELINEMODE
if (lmodetype == KLUDGE_LINEMODE) {
send_wont(TELOPT_SGA, 1);
} else if (lmodetype == REAL_LINEMODE) {
# endif /* KLUDGELINEMODE */
send_do(TELOPT_LINEMODE, 1);
/* send along edit modes */
snprintf(nfrontp,
BUFSIZ - (nfrontp - netobuf),
"%c%c%c%c%c%c%c", IAC, SB,
TELOPT_LINEMODE, LM_MODE, useeditmode,
IAC, SE);
nfrontp += 7;
editmode = useeditmode;
# ifdef KLUDGELINEMODE
}
# endif /* KLUDGELINEMODE */
linemode = uselinemode;
goto done;
}
# ifdef KLUDGELINEMODE
/*
* None of what follows is of any value if not using
* real linemode.
*/
if (lmodetype < REAL_LINEMODE)
goto done;
# endif /* KLUDGELINEMODE */
if (linemode && his_state_is_will(TELOPT_LINEMODE)) {
/*
* If edit mode changed, send edit mode.
*/
if (useeditmode != editmode) {
/*
* Send along appropriate edit mode mask.
*/
snprintf(nfrontp,
BUFSIZ - (nfrontp - netobuf),
"%c%c%c%c%c%c%c", IAC, SB,
TELOPT_LINEMODE, LM_MODE, useeditmode,
IAC, SE);
nfrontp += 7;
editmode = useeditmode;
}
/*
* Check for changes to special characters in use.
*/
start_slc(0);
check_slc();
end_slc(0);
}
done:
if (need_will_echo)
send_will(TELOPT_ECHO, 1);
/*
* Some things should be deferred until after the pty state has
* been set by the local process. Do those things that have been
* deferred now. This only happens once.
*/
if (_terminit == 0) {
_terminit = 1;
defer_terminit();
}
netflush();
set_termbuf();
return;
} /* end of localstat */
#endif /* LINEMODE */
/* /*
* flowstat * flowstat
* *
* Check for changes to flow control * Check for changes to flow control
*/ */
void void
flowstat() flowstat()
{ {
if (his_state_is_will(TELOPT_LFLOW)) { if (his_state_is_will(TELOPT_LFLOW)) {
if (tty_flowmode() != flowmode) { if (tty_flowmode() != flowmode) {
flowmode = tty_flowmode(); flowmode = tty_flowmode();
snprintf(nfrontp, output_data("%c%c%c%c%c%c",
BUFSIZ - (nfrontp - netobuf),
"%c%c%c%c%c%c",
IAC, SB, TELOPT_LFLOW, IAC, SB, TELOPT_LFLOW,
flowmode ? LFLOW_ON : LFLOW_OFF, flowmode ? LFLOW_ON : LFLOW_OFF,
IAC, SE); IAC, SE);
nfrontp += 6;
} }
if (tty_restartany() != restartany) { if (tty_restartany() != restartany) {
restartany = tty_restartany(); restartany = tty_restartany();
snprintf(nfrontp, output_data("%c%c%c%c%c%c",
BUFSIZ - (nfrontp - netobuf),
"%c%c%c%c%c%c",
IAC, SB, TELOPT_LFLOW, IAC, SB, TELOPT_LFLOW,
restartany ? LFLOW_RESTART_ANY restartany ? LFLOW_RESTART_ANY
: LFLOW_RESTART_XON, : LFLOW_RESTART_XON,
IAC, SE); IAC, SE);
nfrontp += 6;
} }
} }
} }
@@ -386,9 +78,8 @@ flowstat()
* at a time, and if using kludge linemode, then only linemode may be * at a time, and if using kludge linemode, then only linemode may be
* affected. * affected.
*/ */
void void
clientstat(code, parm1, parm2) clientstat(int code, int parm1, int parm2)
int code, parm1, parm2;
{ {
void netflush(); void netflush();
@@ -401,129 +92,6 @@ clientstat(code, parm1, parm2)
* Process request from client. code tells what it is. * Process request from client. code tells what it is.
*/ */
switch (code) { switch (code) {
#ifdef LINEMODE
case TELOPT_LINEMODE:
/*
* Don't do anything unless client is asking us to change
* modes.
*/
uselinemode = (parm1 == WILL);
if (uselinemode != linemode) {
# ifdef KLUDGELINEMODE
/*
* If using kludge linemode, make sure that
* we can do what the client asks.
* We can not turn off linemode if alwayslinemode
* and the ICANON bit is set.
*/
if (lmodetype == KLUDGE_LINEMODE) {
if (alwayslinemode && tty_isediting()) {
uselinemode = 1;
}
}
/*
* Quit now if we can't do it.
*/
if (uselinemode == linemode)
return;
/*
* If using real linemode and linemode is being
* turned on, send along the edit mode mask.
*/
if (lmodetype == REAL_LINEMODE && uselinemode)
# else /* KLUDGELINEMODE */
if (uselinemode)
# endif /* KLUDGELINEMODE */
{
useeditmode = 0;
if (tty_isediting())
useeditmode |= MODE_EDIT;
if (tty_istrapsig)
useeditmode |= MODE_TRAPSIG;
if (tty_issofttab())
useeditmode |= MODE_SOFT_TAB;
if (tty_islitecho())
useeditmode |= MODE_LIT_ECHO;
snprintf(nfrontp,
BUFSIZ - (nfrontp - netobuf),
"%c%c%c%c%c%c%c", IAC,
SB, TELOPT_LINEMODE, LM_MODE,
useeditmode, IAC, SE);
nfrontp += 7;
editmode = useeditmode;
}
tty_setlinemode(uselinemode);
linemode = uselinemode;
if (!linemode)
send_will(TELOPT_ECHO, 1);
}
break;
case LM_MODE:
{
int ack, changed;
/*
* Client has sent along a mode mask. If it agrees with
* what we are currently doing, ignore it; if not, it could
* be viewed as a request to change. Note that the server
* will change to the modes in an ack if it is different from
* what we currently have, but we will not ack the ack.
*/
useeditmode &= MODE_MASK;
ack = (useeditmode & MODE_ACK);
useeditmode &= ~MODE_ACK;
if (changed = (useeditmode ^ editmode)) {
/*
* This check is for a timing problem. If the
* state of the tty has changed (due to the user
* application) we need to process that info
* before we write in the state contained in the
* ack!!! This gets out the new MODE request,
* and when the ack to that command comes back
* we'll set it and be in the right mode.
*/
if (ack)
localstat();
if (changed & MODE_EDIT)
tty_setedit(useeditmode & MODE_EDIT);
if (changed & MODE_TRAPSIG)
tty_setsig(useeditmode & MODE_TRAPSIG);
if (changed & MODE_SOFT_TAB)
tty_setsofttab(useeditmode & MODE_SOFT_TAB);
if (changed & MODE_LIT_ECHO)
tty_setlitecho(useeditmode & MODE_LIT_ECHO);
set_termbuf();
if (!ack) {
snprintf(nfrontp,
BUFSIZ - (nfrontp - netobuf),
"%c%c%c%c%c%c%c", IAC,
SB, TELOPT_LINEMODE, LM_MODE,
useeditmode|MODE_ACK,
IAC, SE);
nfrontp += 7;
}
editmode = useeditmode;
}
break;
} /* end of case LM_MODE */
#endif /* LINEMODE */
case TELOPT_NAWS: case TELOPT_NAWS:
#ifdef TIOCSWINSZ #ifdef TIOCSWINSZ
{ {
@@ -531,14 +99,6 @@ clientstat(code, parm1, parm2)
def_col = parm1; def_col = parm1;
def_row = parm2; def_row = parm2;
#ifdef LINEMODE
/*
* Defer changing window size until after terminal is
* initialized.
*/
if (terminit() == 0)
return;
#endif /* LINEMODE */
/* /*
* Change window size as requested by client. * Change window size as requested by client.
@@ -556,13 +116,6 @@ clientstat(code, parm1, parm2)
{ {
def_tspeed = parm1; def_tspeed = parm1;
def_rspeed = parm2; def_rspeed = parm2;
#ifdef LINEMODE
/*
* Defer changing the terminal speed.
*/
if (terminit() == 0)
return;
#endif /* LINEMODE */
/* /*
* Change terminal speed as requested by client. * Change terminal speed as requested by client.
* We set the receive speed first, so that if we can't * We set the receive speed first, so that if we can't
@@ -584,56 +137,4 @@ clientstat(code, parm1, parm2)
netflush(); netflush();
} /* end of clientstat */ }
#ifdef LINEMODE
/*
* defer_terminit
*
* Some things should not be done until after the login process has started
* and all the pty modes are set to what they are supposed to be. This
* function is called when the pty state has been processed for the first time.
* It calls other functions that do things that were deferred in each module.
*/
void
defer_terminit()
{
/*
* local stuff that got deferred.
*/
if (def_tspeed != -1) {
clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed);
def_tspeed = def_rspeed = 0;
}
#ifdef TIOCSWINSZ
if (def_col || def_row) {
struct winsize ws;
memset(&ws, 0, sizeof(ws));
ws.ws_col = def_col;
ws.ws_row = def_row;
ioctl(ourpty, TIOCSWINSZ, (char *)&ws);
}
#endif
/*
* The only other module that currently defers anything.
*/
deferslc();
} /* end of defer_terminit */
/*
* terminit
*
* Returns true if the pty state has been processed yet.
*/
int
terminit()
{
return(_terminit);
} /* end of terminit */
#endif /* LINEMODE */

File diff suppressed because it is too large Load Diff