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