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