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