telnetd.c revision 78527
1/*
2 * Copyright (c) 1989, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "telnetd.h"
35
36RCSID("$Id: telnetd.c,v 1.64 2001/02/08 16:06:27 assar Exp $");
37
38#ifdef _SC_CRAY_SECURE_SYS
39#include <sys/sysv.h>
40#include <sys/secdev.h>
41#include <sys/secparm.h>
42#include <sys/usrv.h>
43int	secflag;
44char	tty_dev[16];
45struct	secdev dv;
46struct	sysv sysv;
47struct	socksec ss;
48#endif	/* _SC_CRAY_SECURE_SYS */
49
50#ifdef AUTHENTICATION
51int	auth_level = 0;
52#endif
53
54extern	int utmp_len;
55int	registerd_host_only = 0;
56
57#ifdef	STREAMSPTY
58# include <stropts.h>
59# include <termios.h>
60#ifdef HAVE_SYS_UIO_H
61#include <sys/uio.h>
62#endif /* HAVE_SYS_UIO_H */
63#ifdef HAVE_SYS_STREAM_H
64#include <sys/stream.h>
65#endif
66#ifdef _AIX
67#include <sys/termio.h>
68#endif
69# ifdef HAVE_SYS_STRTTY_H
70# include <sys/strtty.h>
71# endif
72# ifdef HAVE_SYS_STR_TTY_H
73# include <sys/str_tty.h>
74# endif
75/* make sure we don't get the bsd version */
76/* what is this here for? solaris? /joda */
77# ifdef HAVE_SYS_TTY_H
78# include "/usr/include/sys/tty.h"
79# endif
80# ifdef HAVE_SYS_PTYVAR_H
81# include <sys/ptyvar.h>
82# endif
83
84/*
85 * Because of the way ptyibuf is used with streams messages, we need
86 * ptyibuf+1 to be on a full-word boundary.  The following wierdness
87 * is simply to make that happen.
88 */
89long	ptyibufbuf[BUFSIZ/sizeof(long)+1];
90char	*ptyibuf = ((char *)&ptyibufbuf[1])-1;
91char	*ptyip = ((char *)&ptyibufbuf[1])-1;
92char	ptyibuf2[BUFSIZ];
93unsigned char ctlbuf[BUFSIZ];
94struct	strbuf strbufc, strbufd;
95
96int readstream(int, char*, int);
97
98#else	/* ! STREAMPTY */
99
100/*
101 * I/O data buffers,
102 * pointers, and counters.
103 */
104char	ptyibuf[BUFSIZ], *ptyip = ptyibuf;
105char	ptyibuf2[BUFSIZ];
106
107#endif /* ! STREAMPTY */
108
109int	hostinfo = 1;			/* do we print login banner? */
110
111#ifdef	_CRAY
112extern int      newmap; /* nonzero if \n maps to ^M^J */
113int	lowpty = 0, highpty;	/* low, high pty numbers */
114#endif /* CRAY */
115
116int debug = 0;
117int keepalive = 1;
118char *progname;
119
120static void usage (void);
121
122/*
123 * The string to pass to getopt().  We do it this way so
124 * that only the actual options that we support will be
125 * passed off to getopt().
126 */
127char valid_opts[] = "Bd:hklnS:u:UL:y"
128#ifdef AUTHENTICATION
129		    "a:X:z"
130#endif
131#ifdef DIAGNOSTICS
132		    "D:"
133#endif
134#ifdef _CRAY
135		    "r:"
136#endif
137		    ;
138
139static void doit(struct sockaddr*, int);
140
141int
142main(int argc, char **argv)
143{
144    struct sockaddr_storage __ss;
145    struct sockaddr *sa = (struct sockaddr *)&__ss;
146    int on = 1;
147    socklen_t sa_size;
148    int ch;
149#if	defined(IPPROTO_IP) && defined(IP_TOS)
150    int tos = -1;
151#endif
152#ifdef ENCRYPTION
153    extern int des_check_key;
154    des_check_key = 1;	/* Kludge for Mac NCSA telnet 2.6 /bg */
155#endif
156    pfrontp = pbackp = ptyobuf;
157    netip = netibuf;
158    nfrontp = nbackp = netobuf;
159
160    progname = *argv;
161#ifdef ENCRYPTION
162    nclearto = 0;
163#endif
164
165#ifdef _CRAY
166    /*
167     * Get number of pty's before trying to process options,
168     * which may include changing pty range.
169     */
170    highpty = getnpty();
171#endif /* CRAY */
172
173    while ((ch = getopt(argc, argv, valid_opts)) != -1) {
174	switch(ch) {
175
176#ifdef	AUTHENTICATION
177	case 'a':
178	    /*
179	     * Check for required authentication level
180	     */
181	    if (strcmp(optarg, "debug") == 0) {
182		auth_debug_mode = 1;
183	    } else if (strcasecmp(optarg, "none") == 0) {
184		auth_level = 0;
185	    } else if (strcasecmp(optarg, "otp") == 0) {
186		auth_level = 0;
187		require_otp = 1;
188	    } else if (strcasecmp(optarg, "other") == 0) {
189		auth_level = AUTH_OTHER;
190	    } else if (strcasecmp(optarg, "user") == 0) {
191		auth_level = AUTH_USER;
192	    } else if (strcasecmp(optarg, "valid") == 0) {
193		auth_level = AUTH_VALID;
194	    } else if (strcasecmp(optarg, "off") == 0) {
195		/*
196		 * This hack turns off authentication
197		 */
198		auth_level = -1;
199	    } else {
200		fprintf(stderr,
201			"telnetd: unknown authorization level for -a\n");
202	    }
203	    break;
204#endif	/* AUTHENTICATION */
205
206	case 'B': /* BFTP mode is not supported any more */
207	    break;
208	case 'd':
209	    if (strcmp(optarg, "ebug") == 0) {
210		debug++;
211		break;
212	    }
213	    usage();
214	    /* NOTREACHED */
215	    break;
216
217#ifdef DIAGNOSTICS
218	case 'D':
219	    /*
220	     * Check for desired diagnostics capabilities.
221	     */
222	    if (!strcmp(optarg, "report")) {
223		diagnostic |= TD_REPORT|TD_OPTIONS;
224	    } else if (!strcmp(optarg, "exercise")) {
225		diagnostic |= TD_EXERCISE;
226	    } else if (!strcmp(optarg, "netdata")) {
227		diagnostic |= TD_NETDATA;
228	    } else if (!strcmp(optarg, "ptydata")) {
229		diagnostic |= TD_PTYDATA;
230	    } else if (!strcmp(optarg, "options")) {
231		diagnostic |= TD_OPTIONS;
232	    } else {
233		usage();
234		/* NOT REACHED */
235	    }
236	    break;
237#endif /* DIAGNOSTICS */
238
239
240	case 'h':
241	    hostinfo = 0;
242	    break;
243
244	case 'k': /* Linemode is not supported any more */
245	case 'l':
246	    break;
247
248	case 'n':
249	    keepalive = 0;
250	    break;
251
252#ifdef _CRAY
253	case 'r':
254	    {
255		char *strchr();
256		char *c;
257
258		/*
259		 * Allow the specification of alterations
260		 * to the pty search range.  It is legal to
261		 * specify only one, and not change the
262		 * other from its default.
263		 */
264		c = strchr(optarg, '-');
265		if (c) {
266		    *c++ = '\0';
267		    highpty = atoi(c);
268		}
269		if (*optarg != '\0')
270		    lowpty = atoi(optarg);
271		if ((lowpty > highpty) || (lowpty < 0) ||
272		    (highpty > 32767)) {
273		    usage();
274		    /* NOT REACHED */
275		}
276		break;
277	    }
278#endif	/* CRAY */
279
280	case 'S':
281#ifdef	HAVE_PARSETOS
282	    if ((tos = parsetos(optarg, "tcp")) < 0)
283		fprintf(stderr, "%s%s%s\n",
284			"telnetd: Bad TOS argument '", optarg,
285			"'; will try to use default TOS");
286#else
287	    fprintf(stderr, "%s%s\n", "TOS option unavailable; ",
288		    "-S flag not supported\n");
289#endif
290	    break;
291
292	case 'u': {
293	    char *eptr;
294
295	    utmp_len = strtol(optarg, &eptr, 0);
296	    if (optarg == eptr)
297		fprintf(stderr, "telnetd: unknown utmp len (%s)\n", optarg);
298	    break;
299	}
300
301	case 'U':
302	    registerd_host_only = 1;
303	    break;
304
305#ifdef	AUTHENTICATION
306	case 'X':
307	    /*
308	     * Check for invalid authentication types
309	     */
310	    auth_disable_name(optarg);
311	    break;
312#endif
313	case 'y':
314	    no_warn = 1;
315	    break;
316#ifdef AUTHENTICATION
317	case 'z':
318	    log_unauth = 1;
319	    break;
320
321#endif	/* AUTHENTICATION */
322
323	case 'L':
324	    new_login = optarg;
325	    break;
326
327	default:
328	    fprintf(stderr, "telnetd: %c: unknown option\n", ch);
329	    /* FALLTHROUGH */
330	case '?':
331	    usage();
332	    /* NOTREACHED */
333	}
334    }
335
336    argc -= optind;
337    argv += optind;
338
339    if (debug) {
340	int port = 0;
341	struct servent *sp;
342
343	if (argc > 1) {
344	    usage ();
345	} else if (argc == 1) {
346	    sp = roken_getservbyname (*argv, "tcp");
347	    if (sp)
348		port = sp->s_port;
349	    else
350		port = htons(atoi(*argv));
351	} else {
352#ifdef KRB5
353	    port = krb5_getportbyname (NULL, "telnet", "tcp", 23);
354#else
355	    port = k_getportbyname("telnet", "tcp", htons(23));
356#endif
357	}
358	mini_inetd (port);
359    } else if (argc > 0) {
360	usage();
361	/* NOT REACHED */
362    }
363
364#ifdef _SC_CRAY_SECURE_SYS
365    secflag = sysconf(_SC_CRAY_SECURE_SYS);
366
367    /*
368     *	Get socket's security label
369     */
370    if (secflag)  {
371	socklen_t szss = sizeof(ss);
372	int sock_multi;
373	socklen_t szi = sizeof(int);
374
375	memset(&dv, 0, sizeof(dv));
376
377	if (getsysv(&sysv, sizeof(struct sysv)) != 0)
378	    fatalperror(net, "getsysv");
379
380	/*
381	 *	Get socket security label and set device values
382	 *	   {security label to be set on ttyp device}
383	 */
384#ifdef SO_SEC_MULTI			/* 8.0 code */
385	if ((getsockopt(0, SOL_SOCKET, SO_SECURITY,
386			(void *)&ss, &szss) < 0) ||
387	    (getsockopt(0, SOL_SOCKET, SO_SEC_MULTI,
388			(void *)&sock_multi, &szi) < 0))
389	    fatalperror(net, "getsockopt");
390	else {
391	    dv.dv_actlvl = ss.ss_actlabel.lt_level;
392	    dv.dv_actcmp = ss.ss_actlabel.lt_compart;
393	    if (!sock_multi) {
394		dv.dv_minlvl = dv.dv_maxlvl = dv.dv_actlvl;
395		dv.dv_valcmp = dv.dv_actcmp;
396	    } else {
397		dv.dv_minlvl = ss.ss_minlabel.lt_level;
398		dv.dv_maxlvl = ss.ss_maxlabel.lt_level;
399		dv.dv_valcmp = ss.ss_maxlabel.lt_compart;
400	    }
401	    dv.dv_devflg = 0;
402	}
403#else /* SO_SEC_MULTI */		/* 7.0 code */
404	if (getsockopt(0, SOL_SOCKET, SO_SECURITY,
405		       (void *)&ss, &szss) >= 0) {
406	    dv.dv_actlvl = ss.ss_slevel;
407	    dv.dv_actcmp = ss.ss_compart;
408	    dv.dv_minlvl = ss.ss_minlvl;
409	    dv.dv_maxlvl = ss.ss_maxlvl;
410	    dv.dv_valcmp = ss.ss_maxcmp;
411	}
412#endif /* SO_SEC_MULTI */
413    }
414#endif	/* _SC_CRAY_SECURE_SYS */
415
416    roken_openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
417    sa_size = sizeof (__ss);
418    if (getpeername(STDIN_FILENO, sa, &sa_size) < 0) {
419	fprintf(stderr, "%s: ", progname);
420	perror("getpeername");
421	_exit(1);
422    }
423    if (keepalive &&
424	setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
425		   (void *)&on, sizeof (on)) < 0) {
426	syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
427    }
428
429#if	defined(IPPROTO_IP) && defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
430    {
431# ifdef HAVE_GETTOSBYNAME
432	struct tosent *tp;
433	if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
434	    tos = tp->t_tos;
435# endif
436	if (tos < 0)
437	    tos = 020;	/* Low Delay bit */
438	if (tos
439	    && sa->sa_family == AF_INET
440	    && (setsockopt(STDIN_FILENO, IPPROTO_IP, IP_TOS,
441			   (void *)&tos, sizeof(tos)) < 0)
442	    && (errno != ENOPROTOOPT) )
443	    syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
444    }
445#endif	/* defined(IPPROTO_IP) && defined(IP_TOS) */
446    net = STDIN_FILENO;
447    doit(sa, sa_size);
448    /* NOTREACHED */
449    return 0;
450}  /* end of main */
451
452static void
453usage(void)
454{
455    fprintf(stderr, "Usage: telnetd");
456#ifdef	AUTHENTICATION
457    fprintf(stderr, " [-a (debug|other|otp|user|valid|off|none)]\n\t");
458#endif
459    fprintf(stderr, " [-debug]");
460#ifdef DIAGNOSTICS
461    fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t");
462#endif
463#ifdef	AUTHENTICATION
464    fprintf(stderr, " [-edebug]");
465#endif
466    fprintf(stderr, " [-h]");
467    fprintf(stderr, " [-L login]");
468    fprintf(stderr, " [-n]");
469#ifdef	_CRAY
470    fprintf(stderr, " [-r[lowpty]-[highpty]]");
471#endif
472    fprintf(stderr, "\n\t");
473#ifdef	HAVE_GETTOSBYNAME
474    fprintf(stderr, " [-S tos]");
475#endif
476#ifdef	AUTHENTICATION
477    fprintf(stderr, " [-X auth-type] [-y] [-z]");
478#endif
479    fprintf(stderr, " [-u utmp_hostname_length] [-U]");
480    fprintf(stderr, " [port]\n");
481    exit(1);
482}
483
484/*
485 * getterminaltype
486 *
487 *	Ask the other end to send along its terminal type and speed.
488 * Output is the variable terminaltype filled in.
489 */
490static unsigned char ttytype_sbbuf[] = {
491    IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE
492};
493
494int
495getterminaltype(char *name, size_t name_sz)
496{
497    int retval = -1;
498
499    settimer(baseline);
500#ifdef AUTHENTICATION
501    /*
502     * Handle the Authentication option before we do anything else.
503     */
504    send_do(TELOPT_AUTHENTICATION, 1);
505    while (his_will_wont_is_changing(TELOPT_AUTHENTICATION))
506	ttloop();
507    if (his_state_is_will(TELOPT_AUTHENTICATION)) {
508	retval = auth_wait(name, name_sz);
509    }
510#endif
511
512#ifdef ENCRYPTION
513    send_will(TELOPT_ENCRYPT, 1);
514    send_do(TELOPT_ENCRYPT, 1);	/* esc@magic.fi */
515#endif
516    send_do(TELOPT_TTYPE, 1);
517    send_do(TELOPT_TSPEED, 1);
518    send_do(TELOPT_XDISPLOC, 1);
519    send_do(TELOPT_NEW_ENVIRON, 1);
520    send_do(TELOPT_OLD_ENVIRON, 1);
521    while (
522#ifdef ENCRYPTION
523	   his_do_dont_is_changing(TELOPT_ENCRYPT) ||
524#endif
525	   his_will_wont_is_changing(TELOPT_TTYPE) ||
526	   his_will_wont_is_changing(TELOPT_TSPEED) ||
527	   his_will_wont_is_changing(TELOPT_XDISPLOC) ||
528	   his_will_wont_is_changing(TELOPT_NEW_ENVIRON) ||
529	   his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) {
530	ttloop();
531    }
532#ifdef ENCRYPTION
533    /*
534     * Wait for the negotiation of what type of encryption we can
535     * send with.  If autoencrypt is not set, this will just return.
536     */
537    if (his_state_is_will(TELOPT_ENCRYPT)) {
538	encrypt_wait();
539    }
540#endif
541    if (his_state_is_will(TELOPT_TSPEED)) {
542	static unsigned char sb[] =
543	{ IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
544
545	telnet_net_write (sb, sizeof sb);
546	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
547    }
548    if (his_state_is_will(TELOPT_XDISPLOC)) {
549	static unsigned char sb[] =
550	{ IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
551
552	telnet_net_write (sb, sizeof sb);
553	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
554    }
555    if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
556	static unsigned char sb[] =
557	{ IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE };
558
559	telnet_net_write (sb, sizeof sb);
560	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
561    }
562    else if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
563	static unsigned char sb[] =
564	{ IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE };
565
566	telnet_net_write (sb, sizeof sb);
567	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
568    }
569    if (his_state_is_will(TELOPT_TTYPE)) {
570
571	telnet_net_write (ttytype_sbbuf, sizeof ttytype_sbbuf);
572	DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
573				  sizeof ttytype_sbbuf - 2););
574    }
575    if (his_state_is_will(TELOPT_TSPEED)) {
576	while (sequenceIs(tspeedsubopt, baseline))
577	    ttloop();
578    }
579    if (his_state_is_will(TELOPT_XDISPLOC)) {
580	while (sequenceIs(xdisplocsubopt, baseline))
581	    ttloop();
582    }
583    if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
584	while (sequenceIs(environsubopt, baseline))
585	    ttloop();
586    }
587    if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
588	while (sequenceIs(oenvironsubopt, baseline))
589	    ttloop();
590    }
591    if (his_state_is_will(TELOPT_TTYPE)) {
592	char first[256], last[256];
593
594	while (sequenceIs(ttypesubopt, baseline))
595	    ttloop();
596
597	/*
598	 * If the other side has already disabled the option, then
599	 * we have to just go with what we (might) have already gotten.
600	 */
601	if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) {
602	    strlcpy(first, terminaltype, sizeof(first));
603	    for(;;) {
604		/*
605		 * Save the unknown name, and request the next name.
606		 */
607		strlcpy(last, terminaltype, sizeof(last));
608		_gettermname();
609		if (terminaltypeok(terminaltype))
610		    break;
611		if ((strncmp(last, terminaltype, sizeof(last)) == 0) ||
612		    his_state_is_wont(TELOPT_TTYPE)) {
613		    /*
614		     * We've hit the end.  If this is the same as
615		     * the first name, just go with it.
616		     */
617		    if (strncmp(first, terminaltype, sizeof(first)) == 0)
618			break;
619		    /*
620		     * Get the terminal name one more time, so that
621		     * RFC1091 compliant telnets will cycle back to
622		     * the start of the list.
623		     */
624		    _gettermname();
625		    if (strncmp(first, terminaltype, sizeof(first)) != 0)
626			strcpy(terminaltype, first);
627		    break;
628		}
629	    }
630	}
631    }
632    return(retval);
633}  /* end of getterminaltype */
634
635void
636_gettermname(void)
637{
638    /*
639     * If the client turned off the option,
640     * we can't send another request, so we
641     * just return.
642     */
643    if (his_state_is_wont(TELOPT_TTYPE))
644	return;
645    settimer(baseline);
646    telnet_net_write (ttytype_sbbuf, sizeof ttytype_sbbuf);
647    DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
648			      sizeof ttytype_sbbuf - 2););
649    while (sequenceIs(ttypesubopt, baseline))
650	ttloop();
651}
652
653int
654terminaltypeok(char *s)
655{
656    return 1;
657}
658
659
660char host_name[MaxHostNameLen];
661char remote_host_name[MaxHostNameLen];
662char remote_utmp_name[MaxHostNameLen];
663
664/*
665 * Get a pty, scan input lines.
666 */
667static void
668doit(struct sockaddr *who, int who_len)
669{
670    int level;
671    int ptynum;
672    char user_name[256];
673    int error;
674
675    /*
676     * Find an available pty to use.
677     */
678    ourpty = getpty(&ptynum);
679    if (ourpty < 0)
680	fatal(net, "All network ports in use");
681
682#ifdef _SC_CRAY_SECURE_SYS
683    /*
684     *	set ttyp line security label
685     */
686    if (secflag) {
687	char slave_dev[16];
688
689	snprintf(tty_dev, sizeof(tty_dev), "/dev/pty/%03d", ptynum);
690	if (setdevs(tty_dev, &dv) < 0)
691	    fatal(net, "cannot set pty security");
692	snprintf(slave_dev, sizeof(slave_dev), "/dev/ttyp%03d", ptynum);
693	if (setdevs(slave_dev, &dv) < 0)
694	    fatal(net, "cannot set tty security");
695    }
696#endif	/* _SC_CRAY_SECURE_SYS */
697
698    error = getnameinfo_verified (who, who_len,
699				  remote_host_name,
700				  sizeof(remote_host_name),
701				  NULL, 0,
702				  registerd_host_only ? NI_NAMEREQD : 0);
703    if (error)
704	fatal(net, "Couldn't resolve your address into a host name.\r\n\
705Please contact your net administrator");
706
707    gethostname(host_name, sizeof (host_name));
708
709    strlcpy (remote_utmp_name, remote_host_name, sizeof(remote_utmp_name));
710
711    /* Only trim if too long (and possible) */
712    if (strlen(remote_utmp_name) > utmp_len) {
713	char *domain = strchr(host_name, '.');
714	char *p = strchr(remote_utmp_name, '.');
715	if (domain != NULL && p != NULL && (strcmp(p, domain) == 0))
716	    *p = '\0'; /* remove domain part */
717    }
718
719    /*
720     * If hostname still doesn't fit utmp, use ipaddr.
721     */
722    if (strlen(remote_utmp_name) > utmp_len) {
723	error = getnameinfo (who, who_len,
724			     remote_utmp_name,
725			     sizeof(remote_utmp_name),
726			     NULL, 0,
727			     NI_NUMERICHOST);
728	if (error)
729	    fatal(net, "Couldn't get numeric address\r\n");
730    }
731
732#ifdef AUTHENTICATION
733    auth_encrypt_init(host_name, remote_host_name, "TELNETD", 1);
734#endif
735
736    init_env();
737    /*
738     * get terminal type.
739     */
740    *user_name = 0;
741    level = getterminaltype(user_name, sizeof(user_name));
742    esetenv("TERM", terminaltype ? terminaltype : "network", 1);
743
744#ifdef _SC_CRAY_SECURE_SYS
745    if (secflag) {
746	if (setulvl(dv.dv_actlvl) < 0)
747	    fatal(net,"cannot setulvl()");
748	if (setucmp(dv.dv_actcmp) < 0)
749	    fatal(net, "cannot setucmp()");
750    }
751#endif	/* _SC_CRAY_SECURE_SYS */
752
753    /* begin server processing */
754    my_telnet(net, ourpty, remote_host_name, remote_utmp_name,
755	      level, user_name);
756    /*NOTREACHED*/
757}  /* end of doit */
758
759/* output contents of /etc/issue.net, or /etc/issue */
760static void
761show_issue(void)
762{
763    FILE *f;
764    char buf[128];
765    f = fopen("/etc/issue.net", "r");
766    if(f == NULL)
767	f = fopen("/etc/issue", "r");
768    if(f){
769	while(fgets(buf, sizeof(buf)-2, f)){
770	    strcpy(buf + strcspn(buf, "\r\n"), "\r\n");
771	    writenet((unsigned char*)buf, strlen(buf));
772	}
773	fclose(f);
774    }
775}
776
777/*
778 * Main loop.  Select from pty and network, and
779 * hand data to telnet receiver finite state machine.
780 */
781void
782my_telnet(int f, int p, const char *host, const char *utmp_host,
783	  int level, char *autoname)
784{
785    int on = 1;
786    char *he;
787    char *IM;
788    int nfd;
789    int startslave_called = 0;
790    time_t timeout;
791
792    /*
793     * Initialize the slc mapping table.
794     */
795    get_slc_defaults();
796
797    /*
798     * Do some tests where it is desireable to wait for a response.
799     * Rather than doing them slowly, one at a time, do them all
800     * at once.
801     */
802    if (my_state_is_wont(TELOPT_SGA))
803	send_will(TELOPT_SGA, 1);
804    /*
805     * Is the client side a 4.2 (NOT 4.3) system?  We need to know this
806     * because 4.2 clients are unable to deal with TCP urgent data.
807     *
808     * To find out, we send out a "DO ECHO".  If the remote system
809     * answers "WILL ECHO" it is probably a 4.2 client, and we note
810     * that fact ("WILL ECHO" ==> that the client will echo what
811     * WE, the server, sends it; it does NOT mean that the client will
812     * echo the terminal input).
813     */
814    send_do(TELOPT_ECHO, 1);
815
816    /*
817     * Send along a couple of other options that we wish to negotiate.
818     */
819    send_do(TELOPT_NAWS, 1);
820    send_will(TELOPT_STATUS, 1);
821    flowmode = 1;		/* default flow control state */
822    restartany = -1;	/* uninitialized... */
823    send_do(TELOPT_LFLOW, 1);
824
825    /*
826     * Spin, waiting for a response from the DO ECHO.  However,
827     * some REALLY DUMB telnets out there might not respond
828     * to the DO ECHO.  So, we spin looking for NAWS, (most dumb
829     * telnets so far seem to respond with WONT for a DO that
830     * they don't understand...) because by the time we get the
831     * response, it will already have processed the DO ECHO.
832     * Kludge upon kludge.
833     */
834    while (his_will_wont_is_changing(TELOPT_NAWS))
835	ttloop();
836
837    /*
838     * But...
839     * The client might have sent a WILL NAWS as part of its
840     * startup code; if so, we'll be here before we get the
841     * response to the DO ECHO.  We'll make the assumption
842     * that any implementation that understands about NAWS
843     * is a modern enough implementation that it will respond
844     * to our DO ECHO request; hence we'll do another spin
845     * waiting for the ECHO option to settle down, which is
846     * what we wanted to do in the first place...
847     */
848    if (his_want_state_is_will(TELOPT_ECHO) &&
849	his_state_is_will(TELOPT_NAWS)) {
850	while (his_will_wont_is_changing(TELOPT_ECHO))
851	    ttloop();
852    }
853    /*
854     * On the off chance that the telnet client is broken and does not
855     * respond to the DO ECHO we sent, (after all, we did send the
856     * DO NAWS negotiation after the DO ECHO, and we won't get here
857     * until a response to the DO NAWS comes back) simulate the
858     * receipt of a will echo.  This will also send a WONT ECHO
859     * to the client, since we assume that the client failed to
860     * respond because it believes that it is already in DO ECHO
861     * mode, which we do not want.
862     */
863    if (his_want_state_is_will(TELOPT_ECHO)) {
864	DIAG(TD_OPTIONS,
865	     {output_data("td: simulating recv\r\n");
866	     });
867	willoption(TELOPT_ECHO);
868    }
869
870    /*
871     * Finally, to clean things up, we turn on our echo.  This
872     * will break stupid 4.2 telnets out of local terminal echo.
873     */
874
875    if (my_state_is_wont(TELOPT_ECHO))
876	send_will(TELOPT_ECHO, 1);
877
878#ifdef TIOCPKT
879#ifdef	STREAMSPTY
880    if (!really_stream)
881#endif
882	/*
883	 * Turn on packet mode
884	 */
885	ioctl(p, TIOCPKT, (char *)&on);
886#endif
887
888
889    /*
890     * Call telrcv() once to pick up anything received during
891     * terminal type negotiation, 4.2/4.3 determination, and
892     * linemode negotiation.
893     */
894    telrcv();
895
896    ioctl(f, FIONBIO, (char *)&on);
897    ioctl(p, FIONBIO, (char *)&on);
898
899#if	defined(SO_OOBINLINE) && defined(HAVE_SETSOCKOPT)
900    setsockopt(net, SOL_SOCKET, SO_OOBINLINE,
901	       (void *)&on, sizeof on);
902#endif	/* defined(SO_OOBINLINE) */
903
904#ifdef	SIGTSTP
905    signal(SIGTSTP, SIG_IGN);
906#endif
907#ifdef	SIGTTOU
908    /*
909     * Ignoring SIGTTOU keeps the kernel from blocking us
910     * in ttioct() in /sys/tty.c.
911     */
912    signal(SIGTTOU, SIG_IGN);
913#endif
914
915    signal(SIGCHLD, cleanup);
916
917#ifdef  TIOCNOTTY
918    {
919	int t;
920	t = open(_PATH_TTY, O_RDWR);
921	if (t >= 0) {
922	    ioctl(t, TIOCNOTTY, (char *)0);
923	    close(t);
924	}
925    }
926#endif
927
928    show_issue();
929    /*
930     * Show banner that getty never gave.
931     *
932     * We put the banner in the pty input buffer.  This way, it
933     * gets carriage return null processing, etc., just like all
934     * other pty --> client data.
935     */
936
937    if (getenv("USER"))
938	hostinfo = 0;
939
940    IM = DEFAULT_IM;
941    he = 0;
942    edithost(he, host_name);
943    if (hostinfo && *IM)
944	putf(IM, ptyibuf2);
945
946    if (pcc)
947	strncat(ptyibuf2, ptyip, pcc+1);
948    ptyip = ptyibuf2;
949    pcc = strlen(ptyip);
950
951    DIAG(TD_REPORT, {
952	output_data("td: Entering processing loop\r\n");
953    });
954
955
956    nfd = ((f > p) ? f : p) + 1;
957    timeout = time(NULL) + 5;
958    for (;;) {
959	fd_set ibits, obits, xbits;
960	int c;
961
962	/* wait for encryption to be turned on, but don't wait
963           indefinitely */
964	if(!startslave_called && (!encrypt_delay() || timeout > time(NULL))){
965	    startslave_called = 1;
966	    startslave(host, utmp_host, level, autoname);
967	}
968
969	if (ncc < 0 && pcc < 0)
970	    break;
971
972	FD_ZERO(&ibits);
973	FD_ZERO(&obits);
974	FD_ZERO(&xbits);
975
976	if (f >= FD_SETSIZE
977	    || p >= FD_SETSIZE)
978	    fatal(net, "fd too large");
979
980	/*
981	 * Never look for input if there's still
982	 * stuff in the corresponding output buffer
983	 */
984	if (nfrontp - nbackp || pcc > 0) {
985	    FD_SET(f, &obits);
986	} else {
987	    FD_SET(p, &ibits);
988	}
989	if (pfrontp - pbackp || ncc > 0) {
990	    FD_SET(p, &obits);
991	} else {
992	    FD_SET(f, &ibits);
993	}
994	if (!SYNCHing) {
995	    FD_SET(f, &xbits);
996	}
997	if ((c = select(nfd, &ibits, &obits, &xbits,
998			(struct timeval *)0)) < 1) {
999	    if (c == -1) {
1000		if (errno == EINTR) {
1001		    continue;
1002		}
1003	    }
1004	    sleep(5);
1005	    continue;
1006	}
1007
1008	/*
1009	 * Any urgent data?
1010	 */
1011	if (FD_ISSET(net, &xbits)) {
1012	    SYNCHing = 1;
1013	}
1014
1015	/*
1016	 * Something to read from the network...
1017	 */
1018	if (FD_ISSET(net, &ibits)) {
1019#ifndef SO_OOBINLINE
1020	    /*
1021	     * In 4.2 (and 4.3 beta) systems, the
1022	     * OOB indication and data handling in the kernel
1023	     * is such that if two separate TCP Urgent requests
1024	     * come in, one byte of TCP data will be overlaid.
1025	     * This is fatal for Telnet, but we try to live
1026	     * with it.
1027	     *
1028	     * In addition, in 4.2 (and...), a special protocol
1029	     * is needed to pick up the TCP Urgent data in
1030	     * the correct sequence.
1031	     *
1032	     * What we do is:  if we think we are in urgent
1033	     * mode, we look to see if we are "at the mark".
1034	     * If we are, we do an OOB receive.  If we run
1035	     * this twice, we will do the OOB receive twice,
1036	     * but the second will fail, since the second
1037	     * time we were "at the mark", but there wasn't
1038	     * any data there (the kernel doesn't reset
1039	     * "at the mark" until we do a normal read).
1040	     * Once we've read the OOB data, we go ahead
1041	     * and do normal reads.
1042	     *
1043	     * There is also another problem, which is that
1044	     * since the OOB byte we read doesn't put us
1045	     * out of OOB state, and since that byte is most
1046	     * likely the TELNET DM (data mark), we would
1047	     * stay in the TELNET SYNCH (SYNCHing) state.
1048	     * So, clocks to the rescue.  If we've "just"
1049	     * received a DM, then we test for the
1050	     * presence of OOB data when the receive OOB
1051	     * fails (and AFTER we did the normal mode read
1052	     * to clear "at the mark").
1053	     */
1054	    if (SYNCHing) {
1055		int atmark;
1056
1057		ioctl(net, SIOCATMARK, (char *)&atmark);
1058		if (atmark) {
1059		    ncc = recv(net, netibuf, sizeof (netibuf), MSG_OOB);
1060		    if ((ncc == -1) && (errno == EINVAL)) {
1061			ncc = read(net, netibuf, sizeof (netibuf));
1062			if (sequenceIs(didnetreceive, gotDM)) {
1063			    SYNCHing = stilloob(net);
1064			}
1065		    }
1066		} else {
1067		    ncc = read(net, netibuf, sizeof (netibuf));
1068		}
1069	    } else {
1070		ncc = read(net, netibuf, sizeof (netibuf));
1071	    }
1072	    settimer(didnetreceive);
1073#else	/* !defined(SO_OOBINLINE)) */
1074	    ncc = read(net, netibuf, sizeof (netibuf));
1075#endif	/* !defined(SO_OOBINLINE)) */
1076	    if (ncc < 0 && errno == EWOULDBLOCK)
1077		ncc = 0;
1078	    else {
1079		if (ncc <= 0) {
1080		    break;
1081		}
1082		netip = netibuf;
1083	    }
1084	    DIAG((TD_REPORT | TD_NETDATA), {
1085		output_data("td: netread %d chars\r\n", ncc);
1086		});
1087	    DIAG(TD_NETDATA, printdata("nd", netip, ncc));
1088	}
1089
1090	/*
1091	 * Something to read from the pty...
1092	 */
1093	if (FD_ISSET(p, &ibits)) {
1094#ifdef STREAMSPTY
1095	    if (really_stream)
1096		pcc = readstream(p, ptyibuf, BUFSIZ);
1097	    else
1098#endif
1099		pcc = read(p, ptyibuf, BUFSIZ);
1100
1101	    /*
1102	     * On some systems, if we try to read something
1103	     * off the master side before the slave side is
1104	     * opened, we get EIO.
1105	     */
1106	    if (pcc < 0 && (errno == EWOULDBLOCK ||
1107#ifdef	EAGAIN
1108			    errno == EAGAIN ||
1109#endif
1110			    errno == EIO)) {
1111		pcc = 0;
1112	    } else {
1113		if (pcc <= 0)
1114		    break;
1115		if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {
1116		    netclear();	/* clear buffer back */
1117#ifndef	NO_URGENT
1118		    /*
1119		     * There are client telnets on some
1120		     * operating systems get screwed up
1121		     * royally if we send them urgent
1122		     * mode data.
1123		     */
1124		    output_data ("%c%c", IAC, DM);
1125
1126		    neturg = nfrontp-1; /* off by one XXX */
1127		    DIAG(TD_OPTIONS,
1128			 printoption("td: send IAC", DM));
1129
1130#endif
1131		}
1132		if (his_state_is_will(TELOPT_LFLOW) &&
1133		    (ptyibuf[0] &
1134		     (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) {
1135		    int newflow =
1136			ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0;
1137		    if (newflow != flowmode) {
1138			flowmode = newflow;
1139			output_data("%c%c%c%c%c%c",
1140				    IAC, SB, TELOPT_LFLOW,
1141				    flowmode ? LFLOW_ON
1142				    : LFLOW_OFF,
1143				    IAC, SE);
1144			DIAG(TD_OPTIONS, printsub('>',
1145						  (unsigned char *)nfrontp-4,
1146						  4););
1147		    }
1148		}
1149		pcc--;
1150		ptyip = ptyibuf+1;
1151	    }
1152	}
1153
1154	while (pcc > 0) {
1155	    if ((&netobuf[BUFSIZ] - nfrontp) < 3)
1156		break;
1157	    c = *ptyip++ & 0377, pcc--;
1158	    if (c == IAC)
1159		*nfrontp++ = c;
1160	    *nfrontp++ = c;
1161	    if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) {
1162		if (pcc > 0 && ((*ptyip & 0377) == '\n')) {
1163		    *nfrontp++ = *ptyip++ & 0377;
1164		    pcc--;
1165		} else
1166		    *nfrontp++ = '\0';
1167	    }
1168	}
1169
1170	if (FD_ISSET(f, &obits) && (nfrontp - nbackp) > 0)
1171	    netflush();
1172	if (ncc > 0)
1173	    telrcv();
1174	if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0)
1175	    ptyflush();
1176    }
1177    cleanup(0);
1178}
1179
1180#ifndef	TCSIG
1181# ifdef	TIOCSIG
1182#  define TCSIG TIOCSIG
1183# endif
1184#endif
1185
1186#ifdef	STREAMSPTY
1187
1188    int flowison = -1;  /* current state of flow: -1 is unknown */
1189
1190int
1191readstream(int p, char *ibuf, int bufsize)
1192{
1193    int flags = 0;
1194    int ret = 0;
1195    struct termios *tsp;
1196#if 0
1197    struct termio *tp;
1198#endif
1199    struct iocblk *ip;
1200    char vstop, vstart;
1201    int ixon;
1202    int newflow;
1203
1204    strbufc.maxlen = BUFSIZ;
1205    strbufc.buf = (char *)ctlbuf;
1206    strbufd.maxlen = bufsize-1;
1207    strbufd.len = 0;
1208    strbufd.buf = ibuf+1;
1209    ibuf[0] = 0;
1210
1211    ret = getmsg(p, &strbufc, &strbufd, &flags);
1212    if (ret < 0)  /* error of some sort -- probably EAGAIN */
1213	return(-1);
1214
1215    if (strbufc.len <= 0 || ctlbuf[0] == M_DATA) {
1216	/* data message */
1217	if (strbufd.len > 0) {			/* real data */
1218	    return(strbufd.len + 1);	/* count header char */
1219	} else {
1220	    /* nothing there */
1221	    errno = EAGAIN;
1222	    return(-1);
1223	}
1224    }
1225
1226    /*
1227     * It's a control message.  Return 1, to look at the flag we set
1228     */
1229
1230    switch (ctlbuf[0]) {
1231    case M_FLUSH:
1232	if (ibuf[1] & FLUSHW)
1233	    ibuf[0] = TIOCPKT_FLUSHWRITE;
1234	return(1);
1235
1236    case M_IOCTL:
1237	ip = (struct iocblk *) (ibuf+1);
1238
1239	switch (ip->ioc_cmd) {
1240#ifdef TCSETS
1241	case TCSETS:
1242	case TCSETSW:
1243	case TCSETSF:
1244	    tsp = (struct termios *)
1245		(ibuf+1 + sizeof(struct iocblk));
1246	    vstop = tsp->c_cc[VSTOP];
1247	    vstart = tsp->c_cc[VSTART];
1248	    ixon = tsp->c_iflag & IXON;
1249	    break;
1250#endif
1251#if 0
1252	case TCSETA:
1253	case TCSETAW:
1254	case TCSETAF:
1255	    tp = (struct termio *) (ibuf+1 + sizeof(struct iocblk));
1256	    vstop = tp->c_cc[VSTOP];
1257	    vstart = tp->c_cc[VSTART];
1258	    ixon = tp->c_iflag & IXON;
1259	    break;
1260#endif
1261	default:
1262	    errno = EAGAIN;
1263	    return(-1);
1264	}
1265
1266	newflow =  (ixon && (vstart == 021) && (vstop == 023)) ? 1 : 0;
1267	if (newflow != flowison) {  /* it's a change */
1268	    flowison = newflow;
1269	    ibuf[0] = newflow ? TIOCPKT_DOSTOP : TIOCPKT_NOSTOP;
1270	    return(1);
1271	}
1272    }
1273
1274    /* nothing worth doing anything about */
1275    errno = EAGAIN;
1276    return(-1);
1277}
1278#endif /* STREAMSPTY */
1279
1280/*
1281 * Send interrupt to process on other side of pty.
1282 * If it is in raw mode, just write NULL;
1283 * otherwise, write intr char.
1284 */
1285void
1286interrupt()
1287{
1288    ptyflush();	/* half-hearted */
1289
1290#if defined(STREAMSPTY) && defined(TIOCSIGNAL)
1291    /* Streams PTY style ioctl to post a signal */
1292    if (really_stream)
1293	{
1294	    int sig = SIGINT;
1295	    ioctl(ourpty, TIOCSIGNAL, &sig);
1296	    ioctl(ourpty, I_FLUSH, FLUSHR);
1297	}
1298#else
1299#ifdef	TCSIG
1300    ioctl(ourpty, TCSIG, (char *)SIGINT);
1301#else	/* TCSIG */
1302    init_termbuf();
1303    *pfrontp++ = slctab[SLC_IP].sptr ?
1304	(unsigned char)*slctab[SLC_IP].sptr : '\177';
1305#endif	/* TCSIG */
1306#endif
1307}
1308
1309/*
1310 * Send quit to process on other side of pty.
1311 * If it is in raw mode, just write NULL;
1312 * otherwise, write quit char.
1313 */
1314void
1315sendbrk()
1316{
1317    ptyflush();	/* half-hearted */
1318#ifdef	TCSIG
1319    ioctl(ourpty, TCSIG, (char *)SIGQUIT);
1320#else	/* TCSIG */
1321    init_termbuf();
1322    *pfrontp++ = slctab[SLC_ABORT].sptr ?
1323	(unsigned char)*slctab[SLC_ABORT].sptr : '\034';
1324#endif	/* TCSIG */
1325}
1326
1327void
1328sendsusp()
1329{
1330#ifdef	SIGTSTP
1331    ptyflush();	/* half-hearted */
1332# ifdef	TCSIG
1333    ioctl(ourpty, TCSIG, (char *)SIGTSTP);
1334# else	/* TCSIG */
1335    *pfrontp++ = slctab[SLC_SUSP].sptr ?
1336	(unsigned char)*slctab[SLC_SUSP].sptr : '\032';
1337# endif	/* TCSIG */
1338#endif	/* SIGTSTP */
1339}
1340
1341/*
1342 * When we get an AYT, if ^T is enabled, use that.  Otherwise,
1343 * just send back "[Yes]".
1344 */
1345void
1346recv_ayt()
1347{
1348#if	defined(SIGINFO) && defined(TCSIG)
1349    if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) {
1350	ioctl(ourpty, TCSIG, (char *)SIGINFO);
1351	return;
1352    }
1353#endif
1354    output_data("\r\n[Yes]\r\n");
1355}
1356
1357void
1358doeof()
1359{
1360    init_termbuf();
1361
1362    *pfrontp++ = slctab[SLC_EOF].sptr ?
1363	(unsigned char)*slctab[SLC_EOF].sptr : '\004';
1364}
1365