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