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#if 0
35#ifndef lint
36static const char sccsid[] = "@(#)telnetd.c	8.4 (Berkeley) 5/30/95";
37#endif
38#endif
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD: src/contrib/telnet/telnetd/telnetd.c,v 1.28 2005/05/21 15:28:42 ume Exp $");
41
42#include "telnetd.h"
43#include "pathnames.h"
44
45//#include <sys/mman.h>
46#include <err.h>
47#include <libutil.h>
48#include <paths.h>
49#include <termcap.h>
50#if (!defined(__BEOS__) && !defined(__HAIKU__))
51# include <utmp.h>
52#endif
53
54#include <arpa/inet.h>
55
56#ifdef	AUTHENTICATION
57#include <libtelnet/auth.h>
58int	auth_level = 0;
59#endif
60#ifdef	ENCRYPTION
61#include <libtelnet/encrypt.h>
62#endif
63#include <libtelnet/misc.h>
64
65char	remote_hostname[MAXHOSTNAMELEN];
66size_t	utmp_len = sizeof(remote_hostname) - 1;
67int	registerd_host_only = 0;
68
69
70/*
71 * I/O data buffers,
72 * pointers, and counters.
73 */
74char	ptyibuf[BUFSIZ], *ptyip = ptyibuf;
75char	ptyibuf2[BUFSIZ];
76
77int readstream(int, char *, int);
78void doit(struct sockaddr *);
79int terminaltypeok(char *);
80
81int	hostinfo = 1;			/* do we print login banner? */
82
83static int debug = 0;
84int keepalive = 1;
85const char *altlogin;
86
87void doit(struct sockaddr *);
88int terminaltypeok(char *);
89void startslave(char *, int, char *);
90extern void usage(void);
91static void _gettermname(void);
92
93/*
94 * The string to pass to getopt().  We do it this way so
95 * that only the actual options that we support will be
96 * passed off to getopt().
97 */
98char valid_opts[] = {
99	'd', ':', 'h', 'k', 'n', 'p', ':', 'S', ':', 'u', ':', 'U',
100	'4', '6',
101#ifdef	AUTHENTICATION
102	'a', ':', 'X', ':',
103#endif
104#ifdef BFTPDAEMON
105	'B',
106#endif
107#ifdef DIAGNOSTICS
108	'D', ':',
109#endif
110#ifdef	ENCRYPTION
111	'e', ':',
112#endif
113#ifdef	LINEMODE
114	'l',
115#endif
116	'\0'
117};
118
119int family = AF_INET;
120
121#ifndef	MAXHOSTNAMELEN
122#define	MAXHOSTNAMELEN 256
123#endif	/* MAXHOSTNAMELEN */
124
125char *hostname;
126char host_name[MAXHOSTNAMELEN];
127
128extern void telnet(int, int, char *);
129
130int level;
131char user_name[256];
132
133int
134main(int argc, char *argv[])
135{
136	struct sockaddr_storage from;
137	int on = 1, fromlen;
138	int ch;
139#if (!defined(__BEOS__) && !defined(__HAIKU__))
140	u_long ultmp;
141	char *ep;
142#endif
143#if	defined(IPPROTO_IP) && defined(IP_TOS)
144	int tos = -1;
145#endif
146
147	pfrontp = pbackp = ptyobuf;
148	netip = netibuf;
149	nfrontp = nbackp = netobuf;
150#ifdef	ENCRYPTION
151	nclearto = 0;
152#endif	/* ENCRYPTION */
153
154	/*
155	 * This initialization causes linemode to default to a configuration
156	 * that works on all telnet clients, including the FreeBSD client.
157	 * This is not quite the same as the telnet client issuing a "mode
158	 * character" command, but has most of the same benefits, and is
159	 * preferable since some clients (like usofts) don't have the
160	 * mode character command anyway and linemode breaks things.
161	 * The most notable symptom of fix is that csh "set filec" operations
162	 * like <ESC> (filename completion) and ^D (choices) keys now work
163	 * in telnet sessions and can be used more than once on the same line.
164	 * CR/LF handling is also corrected in some termio modes.  This
165	 * change resolves problem reports bin/771 and bin/1037.
166	 */
167
168	linemode=1;	/*Default to mode that works on bulk of clients*/
169
170	while ((ch = getopt(argc, argv, valid_opts)) != -1) {
171		switch(ch) {
172
173#ifdef	AUTHENTICATION
174		case 'a':
175			/*
176			 * Check for required authentication level
177			 */
178			if (strcmp(optarg, "debug") == 0) {
179				extern int auth_debug_mode;
180				auth_debug_mode = 1;
181			} else if (strcasecmp(optarg, "none") == 0) {
182				auth_level = 0;
183			} else if (strcasecmp(optarg, "other") == 0) {
184				auth_level = AUTH_OTHER;
185			} else if (strcasecmp(optarg, "user") == 0) {
186				auth_level = AUTH_USER;
187			} else if (strcasecmp(optarg, "valid") == 0) {
188				auth_level = AUTH_VALID;
189			} else if (strcasecmp(optarg, "off") == 0) {
190				/*
191				 * This hack turns off authentication
192				 */
193				auth_level = -1;
194			} else {
195				warnx("unknown authorization level for -a");
196			}
197			break;
198#endif	/* AUTHENTICATION */
199
200#ifdef BFTPDAEMON
201		case 'B':
202			bftpd++;
203			break;
204#endif /* BFTPDAEMON */
205
206		case 'd':
207			if (strcmp(optarg, "ebug") == 0) {
208				debug++;
209				break;
210			}
211			usage();
212			/* NOTREACHED */
213			break;
214
215#ifdef DIAGNOSTICS
216		case 'D':
217			/*
218			 * Check for desired diagnostics capabilities.
219			 */
220			if (!strcmp(optarg, "report")) {
221				diagnostic |= TD_REPORT|TD_OPTIONS;
222			} else if (!strcmp(optarg, "exercise")) {
223				diagnostic |= TD_EXERCISE;
224			} else if (!strcmp(optarg, "netdata")) {
225				diagnostic |= TD_NETDATA;
226			} else if (!strcmp(optarg, "ptydata")) {
227				diagnostic |= TD_PTYDATA;
228			} else if (!strcmp(optarg, "options")) {
229				diagnostic |= TD_OPTIONS;
230			} else {
231				usage();
232				/* NOT REACHED */
233			}
234			break;
235#endif /* DIAGNOSTICS */
236
237#ifdef	ENCRYPTION
238		case 'e':
239			if (strcmp(optarg, "debug") == 0) {
240				extern int encrypt_debug_mode;
241				encrypt_debug_mode = 1;
242				break;
243			}
244			usage();
245			/* NOTREACHED */
246			break;
247#endif	/* ENCRYPTION */
248
249		case 'h':
250			hostinfo = 0;
251			break;
252
253#ifdef	LINEMODE
254		case 'l':
255			alwayslinemode = 1;
256			break;
257#endif	/* LINEMODE */
258
259		case 'k':
260#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
261			lmodetype = NO_AUTOKLUDGE;
262#else
263			/* ignore -k option if built without kludge linemode */
264#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
265			break;
266
267		case 'n':
268			keepalive = 0;
269			break;
270
271		case 'p':
272			altlogin = optarg;
273			break;
274
275		case 'S':
276#if (defined(__BEOS__) || defined(__HAIKU__))
277			fprintf(stderr, "-S option is not supported\n");
278#else
279# ifdef	HAS_GETTOS
280			if ((tos = parsetos(optarg, "tcp")) < 0)
281				warnx("%s%s%s",
282					"bad TOS argument '", optarg,
283					"'; will try to use default TOS");
284# else
285# define	MAXTOS	255
286			ultmp = strtoul(optarg, &ep, 0);
287			if (*ep || ep == optarg || ultmp > MAXTOS)
288				warnx("%s%s%s",
289					"bad TOS argument '", optarg,
290					"'; will try to use default TOS");
291			else
292				tos = ultmp;
293# endif
294#endif	/* !__BEOS__ */
295			break;
296
297		case 'u':
298			utmp_len = (size_t)atoi(optarg);
299			if (utmp_len >= sizeof(remote_hostname))
300				utmp_len = sizeof(remote_hostname) - 1;
301			break;
302
303		case 'U':
304			registerd_host_only = 1;
305			break;
306
307#ifdef	AUTHENTICATION
308		case 'X':
309			/*
310			 * Check for invalid authentication types
311			 */
312			auth_disable_name(optarg);
313			break;
314#endif	/* AUTHENTICATION */
315
316		case '4':
317			family = AF_INET;
318			break;
319
320#ifdef INET6
321		case '6':
322			family = AF_INET6;
323			break;
324#endif
325
326		default:
327			warnx("%c: unknown option", ch);
328			/* FALLTHROUGH */
329		case '?':
330			usage();
331			/* NOTREACHED */
332		}
333	}
334
335	argc -= optind;
336	argv += optind;
337
338	if (debug) {
339	    int s, ns, foo, error;
340	    const char *service = "telnet";
341	    struct addrinfo hints, *res;
342
343	    if (argc > 1) {
344		usage();
345		/* NOT REACHED */
346	    } else if (argc == 1)
347		service = *argv;
348
349	    memset(&hints, 0, sizeof(hints));
350	    hints.ai_flags = AI_PASSIVE;
351	    hints.ai_family = family;
352	    hints.ai_socktype = SOCK_STREAM;
353	    hints.ai_protocol = 0;
354	    error = getaddrinfo(NULL, service, &hints, &res);
355
356	    if (error) {
357		errx(1, "tcp/%s: %s\n", service, gai_strerror(error));
358		if (error == EAI_SYSTEM)
359		    errx(1, "tcp/%s: %s\n", service, strerror(errno));
360		usage();
361	    }
362
363	    s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
364	    if (s < 0)
365		    err(1, "socket");
366	    (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
367				(char *)&on, sizeof(on));
368	    if (debug > 1)
369	        (void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
370				(char *)&on, sizeof(on));
371	    if (bind(s, res->ai_addr, res->ai_addrlen) < 0)
372		err(1, "bind");
373	    if (listen(s, 1) < 0)
374		err(1, "listen");
375	    foo = res->ai_addrlen;
376	    ns = accept(s, res->ai_addr, &foo);
377	    if (ns < 0)
378		err(1, "accept");
379	    (void) setsockopt(ns, SOL_SOCKET, SO_DEBUG,
380				(char *)&on, sizeof(on));
381	    (void) dup2(ns, 0);
382	    (void) close(ns);
383	    (void) close(s);
384#ifdef convex
385	} else if (argc == 1) {
386		; /* VOID*/		/* Just ignore the host/port name */
387#endif
388	} else if (argc > 0) {
389		usage();
390		/* NOT REACHED */
391	}
392
393	openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
394	fromlen = sizeof (from);
395	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
396		warn("getpeername");
397		_exit(1);
398	}
399	if (keepalive &&
400	    setsockopt(0, SOL_SOCKET, SO_KEEPALIVE,
401			(char *)&on, sizeof (on)) < 0) {
402		syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
403	}
404
405#if	defined(IPPROTO_IP) && defined(IP_TOS)
406	if (from.ss_family == AF_INET) {
407# if	defined(HAS_GETTOS)
408		struct tosent *tp;
409		if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
410			tos = tp->t_tos;
411# endif
412		if (tos < 0)
413			tos = 020;	/* Low Delay bit */
414		if (tos
415		   && (setsockopt(0, IPPROTO_IP, IP_TOS,
416				  (char *)&tos, sizeof(tos)) < 0)
417		   && (errno != ENOPROTOOPT) )
418			syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
419	}
420#endif	/* defined(IPPROTO_IP) && defined(IP_TOS) */
421	net = 0;
422	doit((struct sockaddr *)&from);
423	/* NOTREACHED */
424	return(0);
425}  /* end of main */
426
427	void
428usage()
429{
430	fprintf(stderr, "usage: telnetd");
431#ifdef	AUTHENTICATION
432	fprintf(stderr,
433	    " [-4] [-6] [-a (debug|other|user|valid|off|none)]\n\t");
434#endif
435#ifdef BFTPDAEMON
436	fprintf(stderr, " [-B]");
437#endif
438	fprintf(stderr, " [-debug]");
439#ifdef DIAGNOSTICS
440	fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t");
441#endif
442#ifdef	AUTHENTICATION
443	fprintf(stderr, " [-edebug]");
444#endif
445	fprintf(stderr, " [-h]");
446#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
447	fprintf(stderr, " [-k]");
448#endif
449#ifdef LINEMODE
450	fprintf(stderr, " [-l]");
451#endif
452	fprintf(stderr, " [-n]");
453	fprintf(stderr, "\n\t");
454#ifdef	HAS_GETTOS
455	fprintf(stderr, " [-S tos]");
456#endif
457#ifdef	AUTHENTICATION
458	fprintf(stderr, " [-X auth-type]");
459#endif
460	fprintf(stderr, " [-u utmp_hostname_length] [-U]");
461	fprintf(stderr, " [port]\n");
462	exit(1);
463}
464
465/*
466 * getterminaltype
467 *
468 *	Ask the other end to send along its terminal type and speed.
469 * Output is the variable terminaltype filled in.
470 */
471static unsigned char ttytype_sbbuf[] = {
472	IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE
473};
474
475
476#ifndef	AUTHENTICATION
477#define undef2 __unused
478#else
479#define undef2
480#endif
481
482static int
483getterminaltype(char *name undef2)
484{
485    int retval = -1;
486
487    settimer(baseline);
488#ifdef	AUTHENTICATION
489    /*
490     * Handle the Authentication option before we do anything else.
491     */
492    send_do(TELOPT_AUTHENTICATION, 1);
493    while (his_will_wont_is_changing(TELOPT_AUTHENTICATION))
494	ttloop();
495    if (his_state_is_will(TELOPT_AUTHENTICATION)) {
496	retval = auth_wait(name);
497    }
498#endif
499
500#ifdef	ENCRYPTION
501    send_will(TELOPT_ENCRYPT, 1);
502#endif	/* ENCRYPTION */
503    send_do(TELOPT_TTYPE, 1);
504    send_do(TELOPT_TSPEED, 1);
505    send_do(TELOPT_XDISPLOC, 1);
506    send_do(TELOPT_NEW_ENVIRON, 1);
507    send_do(TELOPT_OLD_ENVIRON, 1);
508    while (
509#ifdef	ENCRYPTION
510	   his_do_dont_is_changing(TELOPT_ENCRYPT) ||
511#endif	/* ENCRYPTION */
512	   his_will_wont_is_changing(TELOPT_TTYPE) ||
513	   his_will_wont_is_changing(TELOPT_TSPEED) ||
514	   his_will_wont_is_changing(TELOPT_XDISPLOC) ||
515	   his_will_wont_is_changing(TELOPT_NEW_ENVIRON) ||
516	   his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) {
517	ttloop();
518    }
519#ifdef	ENCRYPTION
520    /*
521     * Wait for the negotiation of what type of encryption we can
522     * send with.  If autoencrypt is not set, this will just return.
523     */
524    if (his_state_is_will(TELOPT_ENCRYPT)) {
525	encrypt_wait();
526    }
527#endif	/* ENCRYPTION */
528    if (his_state_is_will(TELOPT_TSPEED)) {
529	static unsigned char sb[] =
530			{ IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
531
532	output_datalen(sb, sizeof sb);
533	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
534    }
535    if (his_state_is_will(TELOPT_XDISPLOC)) {
536	static unsigned char sb[] =
537			{ IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
538
539	output_datalen(sb, sizeof sb);
540	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
541    }
542    if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
543	static unsigned char sb[] =
544			{ IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE };
545
546	output_datalen(sb, sizeof sb);
547	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
548    }
549    else if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
550	static unsigned char sb[] =
551			{ IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE };
552
553	output_datalen(sb, sizeof sb);
554	DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
555    }
556    if (his_state_is_will(TELOPT_TTYPE)) {
557
558	output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf);
559	DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
560					sizeof ttytype_sbbuf - 2););
561    }
562    if (his_state_is_will(TELOPT_TSPEED)) {
563	while (sequenceIs(tspeedsubopt, baseline))
564	    ttloop();
565    }
566    if (his_state_is_will(TELOPT_XDISPLOC)) {
567	while (sequenceIs(xdisplocsubopt, baseline))
568	    ttloop();
569    }
570    if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
571	while (sequenceIs(environsubopt, baseline))
572	    ttloop();
573    }
574    if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
575	while (sequenceIs(oenvironsubopt, baseline))
576	    ttloop();
577    }
578    if (his_state_is_will(TELOPT_TTYPE)) {
579	char first[256], last[256];
580
581	while (sequenceIs(ttypesubopt, baseline))
582	    ttloop();
583
584	/*
585	 * If the other side has already disabled the option, then
586	 * we have to just go with what we (might) have already gotten.
587	 */
588	if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) {
589	    (void) strncpy(first, terminaltype, sizeof(first)-1);
590	    first[sizeof(first)-1] = '\0';
591	    for(;;) {
592		/*
593		 * Save the unknown name, and request the next name.
594		 */
595		(void) strncpy(last, terminaltype, sizeof(last)-1);
596		last[sizeof(last)-1] = '\0';
597		_gettermname();
598		if (terminaltypeok(terminaltype))
599		    break;
600		if ((strncmp(last, terminaltype, sizeof(last)) == 0) ||
601		    his_state_is_wont(TELOPT_TTYPE)) {
602		    /*
603		     * We've hit the end.  If this is the same as
604		     * the first name, just go with it.
605		     */
606		    if (strncmp(first, terminaltype, sizeof(first)) == 0)
607			break;
608		    /*
609		     * Get the terminal name one more time, so that
610		     * RFC1091 compliant telnets will cycle back to
611		     * the start of the list.
612		     */
613		     _gettermname();
614		    if (strncmp(first, terminaltype, sizeof(first)) != 0) {
615			(void) strncpy(terminaltype, first, sizeof(terminaltype)-1);
616			terminaltype[sizeof(terminaltype)-1] = '\0';
617		    }
618		    break;
619		}
620	    }
621	}
622    }
623    return(retval);
624}  /* end of getterminaltype */
625
626static void
627_gettermname(void)
628{
629    /*
630     * If the client turned off the option,
631     * we can't send another request, so we
632     * just return.
633     */
634    if (his_state_is_wont(TELOPT_TTYPE))
635	return;
636    settimer(baseline);
637    output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf);
638    DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
639					sizeof ttytype_sbbuf - 2););
640    while (sequenceIs(ttypesubopt, baseline))
641	ttloop();
642}
643
644int
645terminaltypeok(char *s)
646{
647    char buf[1024];
648
649    if (terminaltype == NULL)
650	return(1);
651
652    /*
653     * tgetent() will return 1 if the type is known, and
654     * 0 if it is not known.  If it returns -1, it couldn't
655     * open the database.  But if we can't open the database,
656     * it won't help to say we failed, because we won't be
657     * able to verify anything else.  So, we treat -1 like 1.
658     */
659    if (tgetent(buf, s) == 0)
660	return(0);
661    return(1);
662}
663
664/*
665 * Get a pty, scan input lines.
666 */
667void
668doit(struct sockaddr *who)
669{
670	int err_; /* XXX */
671	int ptynum;
672
673	/*
674	 * Find an available pty to use.
675	 */
676#ifndef	convex
677	pty = getpty(&ptynum);
678	if (pty < 0)
679		fatal(net, "All network ports in use");
680#else
681	for (;;) {
682		char *lp;
683
684		if ((lp = getpty()) == NULL)
685			fatal(net, "Out of ptys");
686
687		if ((pty = open(lp, 2)) >= 0) {
688			strlcpy(line,lp,sizeof(line));
689			line[5] = 't';
690			break;
691		}
692	}
693#endif
694
695	/* get name of connected client */
696	if (realhostname_sa(remote_hostname, sizeof(remote_hostname) - 1,
697	    who, who->sa_len) == HOSTNAME_INVALIDADDR && registerd_host_only)
698		fatal(net, "Couldn't resolve your address into a host name.\r\n\
699	Please contact your net administrator");
700	remote_hostname[sizeof(remote_hostname) - 1] = '\0';
701
702#if (!defined(__BEOS__) && !defined(__HAIKU__))
703	trimdomain(remote_hostname, UT_HOSTSIZE);
704#endif
705	if (!isdigit(remote_hostname[0]) && strlen(remote_hostname) > utmp_len)
706		err_ = getnameinfo(who, who->sa_len, remote_hostname,
707				  sizeof(remote_hostname), NULL, 0,
708				  NI_NUMERICHOST);
709		/* XXX: do 'err_' check */
710
711	(void) gethostname(host_name, sizeof(host_name) - 1);
712	host_name[sizeof(host_name) - 1] = '\0';
713	hostname = host_name;
714
715#ifdef	AUTHENTICATION
716#ifdef	ENCRYPTION
717/* The above #ifdefs should actually be "or"'ed, not "and"'ed.
718 * This is a byproduct of needing "#ifdef" and not "#if defined()"
719 * for unifdef. XXX MarkM
720 */
721	auth_encrypt_init(hostname, remote_hostname, "TELNETD", 1);
722#endif
723#endif
724
725	init_env();
726	/*
727	 * get terminal type.
728	 */
729	*user_name = 0;
730	level = getterminaltype(user_name);
731	setenv("TERM", terminaltype ? terminaltype : "network", 1);
732
733	telnet(net, pty, remote_hostname);	/* begin server process */
734
735	/*NOTREACHED*/
736}  /* end of doit */
737
738/*
739 * Main loop.  Select from pty and network, and
740 * hand data to telnet receiver finite state machine.
741 */
742void
743telnet(int f, int p, char *host)
744{
745	int on = 1;
746#define	TABBUFSIZ	512
747	char	defent[TABBUFSIZ];
748	char	defstrs[TABBUFSIZ];
749#undef	TABBUFSIZ
750	char *HE;
751	char *HN;
752	char *IM;
753	int nfd;
754
755	/*
756	 * Initialize the slc mapping table.
757	 */
758	get_slc_defaults();
759
760	/*
761	 * Do some tests where it is desireable to wait for a response.
762	 * Rather than doing them slowly, one at a time, do them all
763	 * at once.
764	 */
765	if (my_state_is_wont(TELOPT_SGA))
766		send_will(TELOPT_SGA, 1);
767	/*
768	 * Is the client side a 4.2 (NOT 4.3) system?  We need to know this
769	 * because 4.2 clients are unable to deal with TCP urgent data.
770	 *
771	 * To find out, we send out a "DO ECHO".  If the remote system
772	 * answers "WILL ECHO" it is probably a 4.2 client, and we note
773	 * that fact ("WILL ECHO" ==> that the client will echo what
774	 * WE, the server, sends it; it does NOT mean that the client will
775	 * echo the terminal input).
776	 */
777	send_do(TELOPT_ECHO, 1);
778
779#ifdef	LINEMODE
780	if (his_state_is_wont(TELOPT_LINEMODE)) {
781		/* Query the peer for linemode support by trying to negotiate
782		 * the linemode option.
783		 */
784		linemode = 0;
785		editmode = 0;
786		send_do(TELOPT_LINEMODE, 1);  /* send do linemode */
787	}
788#endif	/* LINEMODE */
789
790	/*
791	 * Send along a couple of other options that we wish to negotiate.
792	 */
793	send_do(TELOPT_NAWS, 1);
794	send_will(TELOPT_STATUS, 1);
795	flowmode = 1;		/* default flow control state */
796	restartany = -1;	/* uninitialized... */
797	send_do(TELOPT_LFLOW, 1);
798
799	/*
800	 * Spin, waiting for a response from the DO ECHO.  However,
801	 * some REALLY DUMB telnets out there might not respond
802	 * to the DO ECHO.  So, we spin looking for NAWS, (most dumb
803	 * telnets so far seem to respond with WONT for a DO that
804	 * they don't understand...) because by the time we get the
805	 * response, it will already have processed the DO ECHO.
806	 * Kludge upon kludge.
807	 */
808	while (his_will_wont_is_changing(TELOPT_NAWS))
809		ttloop();
810
811	/*
812	 * But...
813	 * The client might have sent a WILL NAWS as part of its
814	 * startup code; if so, we'll be here before we get the
815	 * response to the DO ECHO.  We'll make the assumption
816	 * that any implementation that understands about NAWS
817	 * is a modern enough implementation that it will respond
818	 * to our DO ECHO request; hence we'll do another spin
819	 * waiting for the ECHO option to settle down, which is
820	 * what we wanted to do in the first place...
821	 */
822	if (his_want_state_is_will(TELOPT_ECHO) &&
823	    his_state_is_will(TELOPT_NAWS)) {
824		while (his_will_wont_is_changing(TELOPT_ECHO))
825			ttloop();
826	}
827	/*
828	 * On the off chance that the telnet client is broken and does not
829	 * respond to the DO ECHO we sent, (after all, we did send the
830	 * DO NAWS negotiation after the DO ECHO, and we won't get here
831	 * until a response to the DO NAWS comes back) simulate the
832	 * receipt of a will echo.  This will also send a WONT ECHO
833	 * to the client, since we assume that the client failed to
834	 * respond because it believes that it is already in DO ECHO
835	 * mode, which we do not want.
836	 */
837	if (his_want_state_is_will(TELOPT_ECHO)) {
838		DIAG(TD_OPTIONS, output_data("td: simulating recv\r\n"));
839		willoption(TELOPT_ECHO);
840	}
841
842	/*
843	 * Finally, to clean things up, we turn on our echo.  This
844	 * will break stupid 4.2 telnets out of local terminal echo.
845	 */
846
847	if (my_state_is_wont(TELOPT_ECHO))
848		send_will(TELOPT_ECHO, 1);
849
850#if (!defined(__BEOS__) && !defined(__HAIKU__))
851	/*
852	 * Turn on packet mode
853	 */
854	(void) ioctl(p, TIOCPKT, (char *)&on);
855#endif
856
857#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
858	/*
859	 * Continuing line mode support.  If client does not support
860	 * real linemode, attempt to negotiate kludge linemode by sending
861	 * the do timing mark sequence.
862	 */
863	if (lmodetype < REAL_LINEMODE)
864		send_do(TELOPT_TM, 1);
865#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
866
867	/*
868	 * Call telrcv() once to pick up anything received during
869	 * terminal type negotiation, 4.2/4.3 determination, and
870	 * linemode negotiation.
871	 */
872	telrcv();
873
874	(void) ioctl(f, FIONBIO, (char *)&on);
875	(void) ioctl(p, FIONBIO, (char *)&on);
876
877#if	defined(SO_OOBINLINE)
878	(void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE,
879				(char *)&on, sizeof on);
880#endif	/* defined(SO_OOBINLINE) */
881
882#ifdef	SIGTSTP
883	(void) signal(SIGTSTP, SIG_IGN);
884#endif
885#ifdef	SIGTTOU
886	/*
887	 * Ignoring SIGTTOU keeps the kernel from blocking us
888	 * in ttioct() in /sys/tty.c.
889	 */
890	(void) signal(SIGTTOU, SIG_IGN);
891#endif
892
893	(void) signal(SIGCHLD, cleanup);
894
895#ifdef  TIOCNOTTY
896	{
897		int t;
898		t = open(_PATH_TTY, O_RDWR);
899		if (t >= 0) {
900			(void) ioctl(t, TIOCNOTTY, (char *)0);
901			(void) close(t);
902		}
903	}
904#endif
905
906	/*
907	 * Show banner that getty never gave.
908	 *
909	 * We put the banner in the pty input buffer.  This way, it
910	 * gets carriage return null processing, etc., just like all
911	 * other pty --> client data.
912	 */
913
914	if (getent(defent, "default") == 1) {
915		char *cp=defstrs;
916
917		HE = Getstr("he", &cp);
918		HN = Getstr("hn", &cp);
919		IM = Getstr("im", &cp);
920		if (HN && *HN)
921			(void) strlcpy(host_name, HN, sizeof(host_name));
922		if (IM == 0)
923			IM = strdup("");
924	} else {
925		IM = strdup(DEFAULT_IM);
926		HE = 0;
927	}
928	edithost(HE, host_name);
929	if (hostinfo && *IM)
930		putf(IM, ptyibuf2);
931
932	if (pcc)
933		(void) strncat(ptyibuf2, ptyip, pcc+1);
934	ptyip = ptyibuf2;
935	pcc = strlen(ptyip);
936#ifdef	LINEMODE
937	/*
938	 * Last check to make sure all our states are correct.
939	 */
940	init_termbuf();
941	localstat();
942#endif	/* LINEMODE */
943
944	DIAG(TD_REPORT, output_data("td: Entering processing loop\r\n"));
945
946	/*
947	 * Startup the login process on the slave side of the terminal
948	 * now.  We delay this until here to insure option negotiation
949	 * is complete.
950	 */
951	startslave(host, level, user_name);
952
953	nfd = ((f > p) ? f : p) + 1;
954	for (;;) {
955		fd_set ibits, obits, xbits;
956		int c;
957
958		if (ncc < 0 && pcc < 0)
959			break;
960
961		FD_ZERO(&ibits);
962		FD_ZERO(&obits);
963		FD_ZERO(&xbits);
964		/*
965		 * Never look for input if there's still
966		 * stuff in the corresponding output buffer
967		 */
968		if (nfrontp - nbackp || pcc > 0) {
969			FD_SET(f, &obits);
970		} else {
971			FD_SET(p, &ibits);
972		}
973		if (pfrontp - pbackp || ncc > 0) {
974			FD_SET(p, &obits);
975		} else {
976			FD_SET(f, &ibits);
977		}
978		if (!SYNCHing) {
979			FD_SET(f, &xbits);
980		}
981		if ((c = select(nfd, &ibits, &obits, &xbits,
982						(struct timeval *)0)) < 1) {
983			if (c == -1) {
984				if (errno == EINTR) {
985					continue;
986				}
987			}
988			sleep(5);
989			continue;
990		}
991
992		/*
993		 * Any urgent data?
994		 */
995		if (FD_ISSET(net, &xbits)) {
996		    SYNCHing = 1;
997		}
998
999		/*
1000		 * Something to read from the network...
1001		 */
1002		if (FD_ISSET(net, &ibits)) {
1003#if	!defined(SO_OOBINLINE)
1004			/*
1005			 * In 4.2 (and 4.3 beta) systems, the
1006			 * OOB indication and data handling in the kernel
1007			 * is such that if two separate TCP Urgent requests
1008			 * come in, one byte of TCP data will be overlaid.
1009			 * This is fatal for Telnet, but we try to live
1010			 * with it.
1011			 *
1012			 * In addition, in 4.2 (and...), a special protocol
1013			 * is needed to pick up the TCP Urgent data in
1014			 * the correct sequence.
1015			 *
1016			 * What we do is:  if we think we are in urgent
1017			 * mode, we look to see if we are "at the mark".
1018			 * If we are, we do an OOB receive.  If we run
1019			 * this twice, we will do the OOB receive twice,
1020			 * but the second will fail, since the second
1021			 * time we were "at the mark", but there wasn't
1022			 * any data there (the kernel doesn't reset
1023			 * "at the mark" until we do a normal read).
1024			 * Once we've read the OOB data, we go ahead
1025			 * and do normal reads.
1026			 *
1027			 * There is also another problem, which is that
1028			 * since the OOB byte we read doesn't put us
1029			 * out of OOB state, and since that byte is most
1030			 * likely the TELNET DM (data mark), we would
1031			 * stay in the TELNET SYNCH (SYNCHing) state.
1032			 * So, clocks to the rescue.  If we've "just"
1033			 * received a DM, then we test for the
1034			 * presence of OOB data when the receive OOB
1035			 * fails (and AFTER we did the normal mode read
1036			 * to clear "at the mark").
1037			 */
1038		    if (SYNCHing) {
1039			int atmark;
1040
1041			(void) ioctl(net, SIOCATMARK, (char *)&atmark);
1042			if (atmark) {
1043			    ncc = recv(net, netibuf, sizeof (netibuf), MSG_OOB);
1044			    if ((ncc == -1) && (errno == EINVAL)) {
1045				ncc = read(net, netibuf, sizeof (netibuf));
1046				if (sequenceIs(didnetreceive, gotDM)) {
1047				    SYNCHing = stilloob(net);
1048				}
1049			    }
1050			} else {
1051			    ncc = read(net, netibuf, sizeof (netibuf));
1052			}
1053		    } else {
1054			ncc = read(net, netibuf, sizeof (netibuf));
1055		    }
1056		    settimer(didnetreceive);
1057#else	/* !defined(SO_OOBINLINE)) */
1058		    ncc = read(net, netibuf, sizeof (netibuf));
1059#endif	/* !defined(SO_OOBINLINE)) */
1060		    if (ncc < 0 && errno == EWOULDBLOCK)
1061			ncc = 0;
1062		    else {
1063			if (ncc <= 0) {
1064			    break;
1065			}
1066			netip = netibuf;
1067		    }
1068		    DIAG((TD_REPORT | TD_NETDATA),
1069			output_data("td: netread %d chars\r\n", ncc));
1070		    DIAG(TD_NETDATA, printdata("nd", netip, ncc));
1071		}
1072
1073		/*
1074		 * Something to read from the pty...
1075		 */
1076		if (FD_ISSET(p, &ibits)) {
1077			pcc = read(p, ptyibuf, BUFSIZ);
1078			/*
1079			 * On some systems, if we try to read something
1080			 * off the master side before the slave side is
1081			 * opened, we get EIO.
1082			 */
1083			if (pcc < 0 && (errno == EWOULDBLOCK ||
1084#ifdef	EAGAIN
1085					errno == EAGAIN ||
1086#endif
1087					errno == EIO)) {
1088				pcc = 0;
1089			} else {
1090				if (pcc <= 0)
1091					break;
1092#ifdef	LINEMODE
1093				/*
1094				 * If ioctl from pty, pass it through net
1095				 */
1096				if (ptyibuf[0] & TIOCPKT_IOCTL) {
1097					copy_termbuf(ptyibuf+1, pcc-1);
1098					localstat();
1099					pcc = 1;
1100				}
1101#endif	/* LINEMODE */
1102#if (!defined(__BEOS__) && !defined(__HAIKU__))
1103				if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {
1104					netclear();	/* clear buffer back */
1105# ifndef	NO_URGENT
1106					/*
1107					 * There are client telnets on some
1108					 * operating systems get screwed up
1109					 * royally if we send them urgent
1110					 * mode data.
1111					 */
1112					output_data("%c%c", IAC, DM);
1113					neturg = nfrontp-1; /* off by one XXX */
1114					DIAG(TD_OPTIONS,
1115					    printoption("td: send IAC", DM));
1116
1117# endif
1118				}
1119				if (his_state_is_will(TELOPT_LFLOW) &&
1120				    (ptyibuf[0] &
1121				     (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) {
1122					int newflow =
1123					    ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0;
1124					if (newflow != flowmode) {
1125						flowmode = newflow;
1126						output_data("%c%c%c%c%c%c",
1127							IAC, SB, TELOPT_LFLOW,
1128							flowmode ? LFLOW_ON
1129								 : LFLOW_OFF,
1130							IAC, SE);
1131						DIAG(TD_OPTIONS, printsub('>',
1132						    (unsigned char *)nfrontp-4,
1133						    4););
1134					}
1135				}
1136				pcc--;
1137#endif	/* !__BEOS__ */
1138				//ptyip = ptyibuf+1;
1139				ptyip = ptyibuf;
1140			}
1141		}
1142
1143		while (pcc > 0) {
1144			if ((&netobuf[BUFSIZ] - nfrontp) < 2)
1145				break;
1146			c = *ptyip++ & 0377, pcc--;
1147			if (c == IAC)
1148				output_data("%c", c);
1149			output_data("%c", c);
1150			if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) {
1151				if (pcc > 0 && ((*ptyip & 0377) == '\n')) {
1152					output_data("%c", *ptyip++ & 0377);
1153					pcc--;
1154				} else
1155					output_data("%c", '\0');
1156			}
1157		}
1158
1159		if (FD_ISSET(f, &obits) && (nfrontp - nbackp) > 0)
1160			netflush();
1161		if (ncc > 0)
1162			telrcv();
1163		if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0)
1164			ptyflush();
1165	}
1166	cleanup(0);
1167}  /* end of telnet */
1168
1169#ifndef	TCSIG
1170# ifdef	TIOCSIG
1171#  define TCSIG TIOCSIG
1172# endif
1173#endif
1174
1175/*
1176 * Send interrupt to process on other side of pty.
1177 * If it is in raw mode, just write NULL;
1178 * otherwise, write intr char.
1179 */
1180void
1181interrupt(void)
1182{
1183	ptyflush();	/* half-hearted */
1184
1185#ifdef	TCSIG
1186	(void) ioctl(pty, TCSIG, (char *)SIGINT);
1187#else	/* TCSIG */
1188	init_termbuf();
1189	*pfrontp++ = slctab[SLC_IP].sptr ?
1190			(unsigned char)*slctab[SLC_IP].sptr : '\177';
1191#endif	/* TCSIG */
1192}
1193
1194/*
1195 * Send quit to process on other side of pty.
1196 * If it is in raw mode, just write NULL;
1197 * otherwise, write quit char.
1198 */
1199void
1200sendbrk(void)
1201{
1202	ptyflush();	/* half-hearted */
1203#ifdef	TCSIG
1204	(void) ioctl(pty, TCSIG, (char *)SIGQUIT);
1205#else	/* TCSIG */
1206	init_termbuf();
1207	*pfrontp++ = slctab[SLC_ABORT].sptr ?
1208			(unsigned char)*slctab[SLC_ABORT].sptr : '\034';
1209#endif	/* TCSIG */
1210}
1211
1212void
1213sendsusp(void)
1214{
1215#ifdef	SIGTSTP
1216	ptyflush();	/* half-hearted */
1217# ifdef	TCSIG
1218	(void) ioctl(pty, TCSIG, (char *)SIGTSTP);
1219# else	/* TCSIG */
1220	*pfrontp++ = slctab[SLC_SUSP].sptr ?
1221			(unsigned char)*slctab[SLC_SUSP].sptr : '\032';
1222# endif	/* TCSIG */
1223#endif	/* SIGTSTP */
1224}
1225
1226/*
1227 * When we get an AYT, if ^T is enabled, use that.  Otherwise,
1228 * just send back "[Yes]".
1229 */
1230void
1231recv_ayt(void)
1232{
1233#if	defined(SIGINFO) && defined(TCSIG)
1234	if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) {
1235		(void) ioctl(pty, TCSIG, (char *)SIGINFO);
1236		return;
1237	}
1238#endif
1239	output_data("\r\n[Yes]\r\n");
1240}
1241
1242void
1243doeof(void)
1244{
1245	init_termbuf();
1246
1247#if	defined(LINEMODE) && defined(USE_TERMIO) && (VEOF == VMIN)
1248	if (!tty_isediting()) {
1249		extern char oldeofc;
1250		*pfrontp++ = oldeofc;
1251		return;
1252	}
1253#endif
1254	*pfrontp++ = slctab[SLC_EOF].sptr ?
1255			(unsigned char)*slctab[SLC_EOF].sptr : '\004';
1256}
1257