1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T
29  * All Rights Reserved.
30  */
31 
32 /*
33  * University Copyright- Copyright (c) 1982, 1986, 1988
34  * The Regents of the University of California.
35  * All Rights Reserved.
36  *
37  * University Acknowledgment- Portions of this document are derived from
38  * software developed by the University of California, Berkeley, and its
39  * contributors.
40  */
41 
42 /*
43  * Telnet server.
44  */
45 #include <sys/types.h>
46 #include <sys/param.h>
47 #include <sys/socket.h>
48 #include <sys/wait.h>
49 #include <sys/file.h>
50 #include <sys/stat.h>
51 #include <sys/filio.h>
52 #include <sys/time.h>
53 #include <sys/stropts.h>
54 #include <sys/stream.h>
55 #include <sys/tihdr.h>
56 #include <sys/utsname.h>
57 #include <unistd.h>
58 
59 #include <netinet/in.h>
60 
61 #define	AUTHWHO_STR
62 #define	AUTHTYPE_NAMES
63 #define	AUTHHOW_NAMES
64 #define	AUTHRSP_NAMES
65 #define	ENCRYPT_NAMES
66 
67 #include <arpa/telnet.h>
68 #include <arpa/inet.h>
69 #include <stdio.h>
70 #include <stdarg.h>
71 #include <signal.h>
72 #include <errno.h>
73 #include <netdb.h>
74 #include <syslog.h>
75 #include <ctype.h>
76 #include <fcntl.h>
77 #include <sac.h>	/* for SC_WILDC */
78 #include <utmpx.h>
79 #include <sys/ttold.h>
80 #include <malloc.h>
81 #include <string.h>
82 #include <security/pam_appl.h>
83 #include <sys/tihdr.h>
84 #include <sys/logindmux.h>
85 #include <sys/telioctl.h>
86 #include <deflt.h>
87 #include <stdlib.h>
88 #include <string.h>
89 #include <stropts.h>
90 #include <termios.h>
91 
92 #include <com_err.h>
93 #include <krb5.h>
94 #include <krb5_repository.h>
95 #include <des/des.h>
96 #include <rpc/des_crypt.h>
97 #include <sys/cryptmod.h>
98 #include <bsm/adt.h>
99 
100 #define	TELNETD_OPTS "Ss:a:dEXUhR:M:"
101 #ifdef DEBUG
102 #define	DEBUG_OPTS "p:e"
103 #else
104 #define	DEBUG_OPTS ""
105 #endif /* DEBUG */
106 
107 #define	OPT_NO			0		/* won't do this option */
108 #define	OPT_YES			1		/* will do this option */
109 #define	OPT_YES_BUT_ALWAYS_LOOK	2
110 #define	OPT_NO_BUT_ALWAYS_LOOK	3
111 
112 #define	MAXOPTLEN 256
113 #define	MAXUSERNAMELEN 256
114 
115 static char	remopts[MAXOPTLEN];
116 static char	myopts[MAXOPTLEN];
117 static uchar_t	doopt[] = { (uchar_t)IAC, (uchar_t)DO, '%', 'c', 0 };
118 static uchar_t	dont[] = { (uchar_t)IAC, (uchar_t)DONT, '%', 'c', 0 };
119 static uchar_t	will[] = { (uchar_t)IAC, (uchar_t)WILL, '%', 'c', 0 };
120 static uchar_t	wont[] = { (uchar_t)IAC, (uchar_t)WONT, '%', 'c', 0 };
121 /*
122  * I/O data buffers, pointers, and counters.
123  */
124 static char	ptyobuf[BUFSIZ], *pfrontp = ptyobuf, *pbackp = ptyobuf;
125 
126 static char	*netibuf, *netip;
127 static int	netibufsize;
128 
129 #define	NIACCUM(c)	{   *netip++ = c; \
130 			    ncc++; \
131 			}
132 
133 static char	netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf;
134 static char	*neturg = 0;		/* one past last bye of urgent data */
135 /* the remote system seems to NOT be an old 4.2 */
136 static int	not42 = 1;
137 static char	defaultfile[] = "/etc/default/telnetd";
138 static char	bannervar[] = "BANNER=";
139 
140 static char BANNER1[] = "\r\n\r\n";
141 static char BANNER2[] = "\r\n\r\0\r\n\r\0";
142 
143 /*
144  * buffer for sub-options - enlarged to 4096 to handle credentials
145  * from AUTH options
146  */
147 static char	subbuffer[4096], *subpointer = subbuffer, *subend = subbuffer;
148 #define	SB_CLEAR()	subpointer = subbuffer;
149 #define	SB_TERM()	{ subend = subpointer; SB_CLEAR(); }
150 #define	SB_ACCUM(c)	if (subpointer < (subbuffer+sizeof (subbuffer))) { \
151 				*subpointer++ = (c); \
152 			}
153 #define	SB_GET()	((*subpointer++)&0xff)
154 #define	SB_EOF()	(subpointer >= subend)
155 #define	SB_LEN()	(subend - subpointer)
156 
157 #define	MAXERRSTRLEN 1024
158 #define	MAXPRINCLEN 256
159 
160 extern uint_t kwarn_add_warning(char *, int);
161 extern uint_t kwarn_del_warning(char *);
162 
163 static boolean_t auth_debug = 0;
164 static boolean_t negotiate_auth_krb5 = 1;
165 static boolean_t auth_negotiated = 0;
166 static int auth_status = 0;
167 static int auth_level = 0;
168 static char	*AuthenticatingUser = NULL;
169 static char	*krb5_name = NULL;
170 
171 static krb5_address rsaddr = { 0, 0, 0, NULL };
172 static krb5_address rsport = { 0, 0, 0, NULL };
173 
174 static krb5_context telnet_context = 0;
175 static krb5_auth_context auth_context = 0;
176 
177 /* telnetd gets session key from here */
178 static krb5_ticket *ticket = NULL;
179 static krb5_keyblock *session_key = NULL;
180 static char *telnet_srvtab = NULL;
181 
182 typedef struct {
183 	uchar_t AuthName;
184 	uchar_t AuthHow;
185 	char  *AuthString;
186 } AuthInfo;
187 
188 static AuthInfo auth_list[] = {
189 	{AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT | AUTH_HOW_MUTUAL |
190 	AUTH_ENCRYPT_ON, "KRB5 MUTUAL CRYPTO"},
191 	{AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT | AUTH_HOW_MUTUAL,
192 	"KRB5 MUTUAL" },
193 	{AUTHTYPE_KERBEROS_V5,	AUTH_WHO_CLIENT | AUTH_HOW_ONE_WAY,
194 	"KRB5 1-WAY" },
195 	{0, 0, "NONE"}
196 };
197 
198 static AuthInfo NoAuth = {0, 0, NULL};
199 
200 static AuthInfo *authenticated = NULL;
201 
202 #define	PREAMBLE_SIZE		5	/* for auth_reply_str allocation */
203 #define	POSTAMBLE_SIZE		5
204 #define	STR_DATA_LEN(len)	((len) * 2 + PREAMBLE_SIZE + POSTAMBLE_SIZE)
205 
206 static void auth_name(uchar_t *, int);
207 static void auth_is(uchar_t *, int);
208 
209 #define	NO_ENCRYPTION   0x00
210 #define	SEND_ENCRYPTED  0x01
211 #define	RECV_ENCRYPTED  0x02
212 #define	ENCRYPT_BOTH_WAYS    (SEND_ENCRYPTED | RECV_ENCRYPTED)
213 
214 static telnet_enc_data_t  encr_data;
215 static boolean_t negotiate_encrypt = B_TRUE;
216 static boolean_t sent_encrypt_support = B_FALSE;
217 static boolean_t sent_will_encrypt = B_FALSE;
218 static boolean_t sent_do_encrypt = B_FALSE;
219 static boolean_t enc_debug = 0;
220 
221 static void encrypt_session_key(Session_Key *key, cipher_info_t *cinfo);
222 static int  encrypt_send_encrypt_is();
223 
224 extern void mit_des_fixup_key_parity(Block);
225 extern int krb5_setenv(const char *, const char *, int);
226 /* need to know what FD to use to talk to the crypto module */
227 static int cryptmod_fd = -1;
228 
229 #define	LOGIN_PROGRAM "/bin/login"
230 
231 /*
232  * State for recv fsm
233  */
234 #define	TS_DATA		0	/* base state */
235 #define	TS_IAC		1	/* look for double IAC's */
236 #define	TS_CR		2	/* CR-LF ->'s CR */
237 #define	TS_SB		3	/* throw away begin's... */
238 #define	TS_SE		4	/* ...end's (suboption negotiation) */
239 #define	TS_WILL		5	/* will option negotiation */
240 #define	TS_WONT		6	/* wont " */
241 #define	TS_DO		7	/* do " */
242 #define	TS_DONT		8	/* dont " */
243 
244 static int	ncc;
245 static int	master;		/* master side of pty */
246 static int	pty;		/* side of pty that gets ioctls */
247 static int	net;
248 static int	inter;
249 extern char **environ;
250 static char	*line;
251 static int	SYNCHing = 0;		/* we are in TELNET SYNCH mode */
252 static int	state = TS_DATA;
253 
254 static int env_ovar = -1;	/* XXX.sparker */
255 static int env_ovalue = -1;	/* XXX.sparker */
256 static char pam_svc_name[64];
257 static boolean_t	telmod_init_done = B_FALSE;
258 
259 static void	doit(int, struct sockaddr_storage *);
260 static void	willoption(int);
261 static void	wontoption(int);
262 static void	dooption(int);
263 static void	dontoption(int);
264 static void	fatal(int, char *);
265 static void	fatalperror(int, char *, int);
266 static void	mode(int, int);
267 static void	interrupt(void);
268 static void	drainstream(int);
269 static int	readstream(int, char *, int);
270 static int	send_oob(int fd, char *ptr, int count);
271 static int	local_setenv(const char *name, const char *value, int rewrite);
272 static void	local_unsetenv(const char *name);
273 static void	suboption(void);
274 static int	removemod(int f, char *modname);
275 static void	willoption(int option);
276 static void	wontoption(int option);
277 static void	dooption(int option);
278 static void	dontoption(int option);
279 static void	write_data(const char *, ...);
280 static void	write_data_len(const char *, int);
281 static void	rmut(void);
282 static void	cleanup(int);
283 static void	telnet(int, int);
284 static void	telrcv(void);
285 static void	sendbrk(void);
286 static void	ptyflush(void);
287 static void	netclear(void);
288 static void	netflush(void);
289 static void	showbanner(void);
290 static void	map_banner(char *);
291 static void	defbanner(void);
292 static void ttloop(void);
293 
294 /*
295  * The env_list linked list is used to store the environment variables
296  * until the final exec of login.  A malevolent client might try to
297  * send an environment variable intended to affect the telnet daemon's
298  * execution.  Right now the BANNER expansion is the only instance.
299  * Note that it is okay to pass the environment variables to login
300  * because login protects itself against environment variables mischief.
301  */
302 
303 struct envlist {
304 	struct envlist	*next;
305 	char		*name;
306 	char		*value;
307 	int		delete;
308 };
309 
310 static struct envlist *envlist_head = NULL;
311 
312 /*
313  * The following are some clocks used to decide how to interpret
314  * the relationship between various variables.
315  */
316 
317 static struct {
318 	int
319 	system,			/* what the current time is */
320 	echotoggle,		/* last time user entered echo character */
321 	modenegotiated,		/* last time operating mode negotiated */
322 	didnetreceive,		/* last time we read data from network */
323 	ttypeopt,		/* ttype will/won't received */
324 	ttypesubopt,		/* ttype subopt is received */
325 	getterminal,		/* time started to get terminal information */
326 	xdisplocopt,		/* xdisploc will/wont received */
327 	xdisplocsubopt,		/* xdisploc suboption received */
328 	nawsopt,		/* window size will/wont received */
329 	nawssubopt,		/* window size received */
330 	environopt,		/* environment option will/wont received */
331 	oenvironopt,		/* "old" environ option will/wont received */
332 	environsubopt,		/* environment option suboption received */
333 	oenvironsubopt,		/* "old environ option suboption received */
334 	gotDM;			/* when did we last see a data mark */
335 
336 	int getauth;
337 	int authopt;	/* Authentication option negotiated */
338 	int authdone;
339 
340 	int getencr;
341 	int encropt;
342 	int encr_support;
343 } clocks;
344 
345 static int init_neg_done = 0;
346 static boolean_t resolve_hostname = 0;
347 static boolean_t show_hostinfo = 1;
348 
349 #define	settimer(x)	(clocks.x = ++clocks.system)
350 #define	sequenceIs(x, y)	(clocks.x < clocks.y)
351 
352 static void send_will(int);
353 static void send_wont(int);
354 static void send_do(int);
355 static char *__findenv(const char *name, int *offset);
356 
357 /* ARGSUSED */
358 static void
auth_finished(AuthInfo * ap,int result)359 auth_finished(AuthInfo *ap, int result)
360 {
361 	if ((authenticated = ap) == NULL) {
362 		authenticated = &NoAuth;
363 		if (myopts[TELOPT_ENCRYPT] == OPT_YES)
364 			send_wont(TELOPT_ENCRYPT);
365 		myopts[TELOPT_ENCRYPT] = remopts[TELOPT_ENCRYPT] = OPT_NO;
366 		encr_data.encrypt.autoflag = 0;
367 	} else if (result != AUTH_REJECT &&
368 		myopts[TELOPT_ENCRYPT] == OPT_YES &&
369 		remopts[TELOPT_ENCRYPT] == OPT_YES) {
370 
371 		/*
372 		 * Authentication successful, so we have a session key, and
373 		 * we're willing to do ENCRYPT, so send our ENCRYPT SUPPORT.
374 		 *
375 		 * Can't have sent ENCRYPT SUPPORT yet!  And if we're sending it
376 		 * now it's really only because we did the DO ENCRYPT/WILL
377 		 * ENCRYPT dance before authentication, which is ok, but not too
378 		 * bright since we have to do the DONT ENCRYPT/WONT ENCRYPT
379 		 * dance if authentication fails, though clients typically just
380 		 * don't care.
381 		 */
382 		write_data("%c%c%c%c%c%c%c",
383 			(uchar_t)IAC,
384 			(uchar_t)SB,
385 			(uchar_t)TELOPT_ENCRYPT,
386 			(uchar_t)ENCRYPT_SUPPORT,
387 			(uchar_t)TELOPT_ENCTYPE_DES_CFB64,
388 			(uchar_t)IAC,
389 			(uchar_t)SE);
390 
391 		netflush();
392 
393 		sent_encrypt_support = B_TRUE;
394 
395 		if (enc_debug)
396 			(void) fprintf(stderr,
397 			"SENT ENCRYPT SUPPORT\n");
398 
399 		(void) encrypt_send_encrypt_is();
400 	}
401 
402 	auth_status = result;
403 
404 	settimer(authdone);
405 }
406 
407 static void
reply_to_client(AuthInfo * ap,int type,void * data,int len)408 reply_to_client(AuthInfo *ap, int type, void *data, int len)
409 {
410 	uchar_t reply[BUFSIZ];
411 	uchar_t *p = reply;
412 	uchar_t *cd = (uchar_t *)data;
413 
414 	if (len == -1 && data != NULL)
415 		len = strlen((char *)data);
416 	else if (len > (sizeof (reply) - 9)) {
417 		syslog(LOG_ERR,
418 		    "krb5 auth reply length too large (%d)", len);
419 		if (auth_debug)
420 			(void) fprintf(stderr,
421 				    "krb5 auth reply length too large (%d)\n",
422 				    len);
423 		return;
424 	} else if (data == NULL)
425 		len = 0;
426 
427 	*p++ = IAC;
428 	*p++ = SB;
429 	*p++ = TELOPT_AUTHENTICATION;
430 	*p++ = AUTHTYPE_KERBEROS_V5;
431 	*p++ = ap->AuthName;
432 	*p++ = ap->AuthHow; /* MUTUAL, ONE-WAY, etc */
433 	*p++ = type;	    /* RESPONSE or ACCEPT */
434 	while (len-- > 0) {
435 		if ((*p++ = *cd++) == IAC)
436 			*p++ = IAC;
437 	}
438 	*p++ = IAC;
439 	*p++ = SE;
440 
441 	/* queue the data to be sent */
442 	write_data_len((const char *)reply, p-reply);
443 
444 #if defined(AUTHTYPE_NAMES) && defined(AUTHWHO_STR) &&\
445 defined(AUTHHOW_NAMES) && defined(AUTHRSP_NAMES)
446 	if (auth_debug) {
447 		(void) fprintf(stderr, "SENT TELOPT_AUTHENTICATION REPLY "
448 			    "%s %s|%s %s\n",
449 			    AUTHTYPE_NAME(ap->AuthName),
450 			    AUTHWHO_NAME(ap->AuthHow & AUTH_WHO_MASK),
451 			    AUTHHOW_NAME(ap->AuthHow & AUTH_HOW_MASK),
452 			    AUTHRSP_NAME(type));
453 	}
454 #endif /* AUTHTYPE_NAMES && AUTHWHO_NAMES && AUTHHOW_NAMES && AUTHRSP_NAMES */
455 
456 	netflush();
457 }
458 
459 /* Decode, decrypt and store the forwarded creds in the local ccache. */
460 static krb5_error_code
rd_and_store_forwarded_creds(krb5_context context,krb5_auth_context auth_context,krb5_data * inbuf,krb5_ticket * ticket,char * username)461 rd_and_store_forwarded_creds(krb5_context context,
462 			    krb5_auth_context auth_context,
463 			    krb5_data *inbuf, krb5_ticket *ticket,
464 			    char *username)
465 {
466 	krb5_creds **creds;
467 	krb5_error_code retval;
468 	char ccname[MAXPATHLEN];
469 	krb5_ccache ccache = NULL;
470 	char *client_name = NULL;
471 
472 	if (retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL))
473 		return (retval);
474 
475 	(void) sprintf(ccname, "FILE:/tmp/krb5cc_p%ld", getpid());
476 	(void) krb5_setenv("KRB5CCNAME", ccname, 1);
477 
478 	if ((retval = krb5_cc_default(context, &ccache)))
479 		goto cleanup;
480 
481 	if ((retval = krb5_cc_initialize(context, ccache,
482 					ticket->enc_part2->client)) != 0)
483 		goto cleanup;
484 
485 	if ((retval = krb5_cc_store_cred(context, ccache, *creds)) != 0)
486 		goto cleanup;
487 
488 	if ((retval = krb5_cc_close(context, ccache)) != 0)
489 		goto cleanup;
490 
491 	/* Register with ktkt_warnd(1M) */
492 	if ((retval = krb5_unparse_name(context, (*creds)->client,
493 					&client_name)) != 0)
494 		goto cleanup;
495 	(void) kwarn_del_warning(client_name);
496 	if (kwarn_add_warning(client_name, (*creds)->times.endtime) != 0) {
497 		syslog(LOG_AUTH|LOG_NOTICE,
498 		    "rd_and_store_forwarded_creds: kwarn_add_warning"
499 		    " failed: ktkt_warnd(1M) down? ");
500 		if (auth_debug)
501 			(void) fprintf(stderr,
502 				    "kwarn_add_warning failed:"
503 				    " ktkt_warnd(1M) down?\n");
504 	}
505 	free(client_name);
506 	client_name = NULL;
507 
508 	if (username != NULL) {
509 		/*
510 		 * This verifies that the user is valid on the local system,
511 		 * maps the username from KerberosV5 to unix,
512 		 * and moves the KRB5CCNAME file to the correct place
513 		 *  /tmp/krb5cc_[uid] with correct ownership (0600 uid gid).
514 		 *
515 		 * NOTE: the user must be in the gsscred table in order to map
516 		 * from KRB5 to Unix.
517 		 */
518 		(void) krb5_kuserok(context, ticket->enc_part2->client,
519 				username);
520 	}
521 	if (auth_debug)
522 		(void) fprintf(stderr,
523 			    "Successfully stored forwarded creds\n");
524 
525 cleanup:
526 	krb5_free_creds(context, *creds);
527 	return (retval);
528 }
529 
530 static void
kerberos5_is(AuthInfo * ap,uchar_t * data,int cnt)531 kerberos5_is(AuthInfo *ap, uchar_t *data, int cnt)
532 {
533 	krb5_error_code err = 0;
534 	krb5_principal server;
535 	krb5_keyblock *newkey = NULL;
536 	krb5_keytab keytabid = 0;
537 	krb5_data outbuf;
538 	krb5_data inbuf;
539 	krb5_authenticator *authenticator;
540 	char errbuf[MAXERRSTRLEN];
541 	char *name;
542 	krb5_data auth;
543 
544 	Session_Key skey;
545 
546 	if (cnt-- < 1)
547 		return;
548 	switch (*data++) {
549 	case KRB_AUTH:
550 		auth.data = (char *)data;
551 		auth.length = cnt;
552 
553 		if (auth_context == NULL) {
554 			err = krb5_auth_con_init(telnet_context, &auth_context);
555 			if (err)
556 				syslog(LOG_ERR,
557 				    "Error getting krb5 auth "
558 				    "context: %s", error_message(err));
559 		}
560 		if (!err) {
561 			krb5_rcache rcache;
562 
563 			err = krb5_auth_con_getrcache(telnet_context,
564 						    auth_context,
565 						    &rcache);
566 			if (!err && !rcache) {
567 				err = krb5_sname_to_principal(telnet_context,
568 							    0, 0,
569 							    KRB5_NT_SRV_HST,
570 							    &server);
571 				if (!err) {
572 					err = krb5_get_server_rcache(
573 						telnet_context,
574 						krb5_princ_component(
575 							telnet_context,
576 							server, 0),
577 						&rcache);
578 
579 					krb5_free_principal(telnet_context,
580 							    server);
581 				}
582 			}
583 			if (err)
584 				syslog(LOG_ERR,
585 				    "Error allocating krb5 replay cache: %s",
586 				    error_message(err));
587 			else {
588 				err = krb5_auth_con_setrcache(telnet_context,
589 							    auth_context,
590 							    rcache);
591 				if (err)
592 					syslog(LOG_ERR,
593 					    "Error creating krb5 "
594 					    "replay cache: %s",
595 					    error_message(err));
596 			}
597 		}
598 		if (!err && telnet_srvtab != NULL)
599 			err = krb5_kt_resolve(telnet_context,
600 					    telnet_srvtab, &keytabid);
601 		if (!err)
602 			err = krb5_rd_req(telnet_context, &auth_context, &auth,
603 					NULL, keytabid, NULL, &ticket);
604 		if (err) {
605 			(void) snprintf(errbuf, sizeof (errbuf),
606 				"Error reading krb5 auth information:"
607 				" %s", error_message(err));
608 			goto errout;
609 		}
610 
611 		/*
612 		 * Verify that the correct principal was used
613 		 */
614 		if (krb5_princ_component(telnet_context,
615 				ticket->server, 0)->length < MAXPRINCLEN) {
616 			char princ[MAXPRINCLEN];
617 			(void) strncpy(princ,
618 				    krb5_princ_component(telnet_context,
619 						ticket->server, 0)->data,
620 				    krb5_princ_component(telnet_context,
621 					    ticket->server, 0)->length);
622 			princ[krb5_princ_component(telnet_context,
623 					ticket->server, 0)->length] = '\0';
624 			if (strcmp("host", princ)) {
625 				if (strlen(princ) < sizeof (errbuf) - 39) {
626 				    (void) snprintf(errbuf, sizeof (errbuf),
627 						"incorrect service "
628 						    "name: \"%s\" != "
629 						    "\"host\"",
630 						    princ);
631 			    } else {
632 				    (void) strncpy(errbuf,
633 						"incorrect service "
634 						"name: principal != "
635 						"\"host\"",
636 						sizeof (errbuf));
637 			    }
638 			    goto errout;
639 			}
640 		} else {
641 			(void) strlcpy(errbuf, "service name too long",
642 					sizeof (errbuf));
643 			goto errout;
644 		}
645 
646 		err = krb5_auth_con_getauthenticator(telnet_context,
647 						auth_context,
648 						&authenticator);
649 		if (err) {
650 			(void) snprintf(errbuf, sizeof (errbuf),
651 				"Failed to get authenticator: %s",
652 				error_message(err));
653 			goto errout;
654 		}
655 		if ((ap->AuthHow & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON &&
656 			!authenticator->checksum) {
657 			(void) strlcpy(errbuf,
658 				    "authenticator is missing checksum",
659 				    sizeof (errbuf));
660 			goto errout;
661 		}
662 		if (authenticator->checksum) {
663 			char type_check[2];
664 			krb5_checksum *cksum = authenticator->checksum;
665 			krb5_keyblock *key;
666 			krb5_data input;
667 			krb5_boolean valid;
668 
669 			type_check[0] = ap->AuthName;
670 			type_check[1] = ap->AuthHow;
671 
672 			err = krb5_auth_con_getkey(telnet_context,
673 						auth_context, &key);
674 			if (err) {
675 				(void) snprintf(errbuf, sizeof (errbuf),
676 					"Failed to get key from "
677 					"authenticator: %s",
678 					error_message(err));
679 				goto errout;
680 			}
681 
682 			input.data = type_check;
683 			input.length = 2;
684 			err = krb5_c_verify_checksum(telnet_context,
685 							key, 0,
686 							&input,
687 							cksum,
688 							&valid);
689 			if (!err && !valid)
690 				err = KRB5KRB_AP_ERR_BAD_INTEGRITY;
691 
692 			if (err) {
693 				(void) snprintf(errbuf, sizeof (errbuf),
694 						"Kerberos checksum "
695 						"verification failed: "
696 						"%s",
697 						error_message(err));
698 				goto errout;
699 			}
700 			krb5_free_keyblock(telnet_context, key);
701 		}
702 
703 		krb5_free_authenticator(telnet_context, authenticator);
704 		if ((ap->AuthHow & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
705 			/* do ap_rep stuff here */
706 			if ((err = krb5_mk_rep(telnet_context, auth_context,
707 					    &outbuf))) {
708 				(void) snprintf(errbuf, sizeof (errbuf),
709 						"Failed to make "
710 						"Kerberos auth reply: "
711 						"%s",
712 						error_message(err));
713 				goto errout;
714 			}
715 			reply_to_client(ap, KRB_RESPONSE, outbuf.data,
716 					outbuf.length);
717 		}
718 		if (krb5_unparse_name(telnet_context,
719 				    ticket->enc_part2->client,
720 				    &name))
721 			name = 0;
722 		reply_to_client(ap, KRB_ACCEPT, name, name ? -1 : 0);
723 		if (auth_debug) {
724 			syslog(LOG_NOTICE,
725 			    "\tKerberos5 identifies user as ``%s''\r\n",
726 			    name ? name : "");
727 		}
728 		if (name != NULL) {
729 			krb5_name = (char *)strdup(name);
730 		}
731 		auth_finished(ap, AUTH_USER);
732 
733 		if (name != NULL)
734 			free(name);
735 		(void) krb5_auth_con_getremotesubkey(telnet_context,
736 		    auth_context, &newkey);
737 		if (session_key != NULL) {
738 			krb5_free_keyblock(telnet_context, session_key);
739 			session_key = 0;
740 		}
741 		if (newkey != NULL) {
742 			(void) krb5_copy_keyblock(telnet_context,
743 			    newkey, &session_key);
744 			krb5_free_keyblock(telnet_context, newkey);
745 		} else {
746 			(void) krb5_copy_keyblock(telnet_context,
747 			    ticket->enc_part2->session, &session_key);
748 		}
749 
750 		/*
751 		 * Initialize encryption stuff.  Currently, we are only
752 		 * supporting 8 byte keys and blocks. Check for this later.
753 		 */
754 		skey.type = SK_DES;
755 		skey.length = DES_BLOCKSIZE;
756 		skey.data = session_key->contents;
757 		encrypt_session_key(&skey, &encr_data.encrypt);
758 		encrypt_session_key(&skey, &encr_data.decrypt);
759 		break;
760 	case KRB_FORWARD:
761 		inbuf.length = cnt;
762 		inbuf.data = (char *)data;
763 		if (auth_debug)
764 			(void) fprintf(stderr,
765 				    "RCVD KRB_FORWARD data (%d bytes)\n", cnt);
766 
767 		if (auth_context != NULL) {
768 			krb5_rcache rcache;
769 
770 			err = krb5_auth_con_getrcache(telnet_context,
771 						    auth_context, &rcache);
772 			if (!err && !rcache) {
773 				err = krb5_sname_to_principal(telnet_context,
774 					0, 0, KRB5_NT_SRV_HST, &server);
775 				if (!err) {
776 					err = krb5_get_server_rcache(
777 						telnet_context,
778 						krb5_princ_component(
779 							telnet_context,
780 							server, 0),
781 						&rcache);
782 					krb5_free_principal(telnet_context,
783 								server);
784 				}
785 			}
786 			if (err) {
787 				syslog(LOG_ERR,
788 				    "Error allocating krb5 replay cache: %s",
789 				    error_message(err));
790 			} else {
791 				err = krb5_auth_con_setrcache(telnet_context,
792 					auth_context, rcache);
793 				if (err)
794 					syslog(LOG_ERR,
795 					    "Error creating krb5 replay cache:"
796 					    " %s",
797 					    error_message(err));
798 			}
799 		}
800 		/*
801 		 * Use the 'rsaddr' and 'rsport' (remote service addr/port)
802 		 * from the original connection.  This data is used to
803 		 * verify the forwarded credentials.
804 		 */
805 		if (!(err = krb5_auth_con_setaddrs(telnet_context, auth_context,
806 					    NULL, &rsaddr)))
807 			err = krb5_auth_con_setports(telnet_context,
808 						auth_context, NULL, &rsport);
809 
810 		if (err == 0)
811 			/*
812 			 * If all is well, store the forwarded creds in
813 			 * the users local credential cache.
814 			 */
815 			err = rd_and_store_forwarded_creds(telnet_context,
816 							auth_context, &inbuf,
817 							ticket,
818 							AuthenticatingUser);
819 		if (err) {
820 			(void) snprintf(errbuf, sizeof (errbuf),
821 					"Read forwarded creds failed: %s",
822 					error_message(err));
823 			syslog(LOG_ERR, "%s", errbuf);
824 
825 			reply_to_client(ap, KRB_FORWARD_REJECT, errbuf, -1);
826 			if (auth_debug)
827 				(void) fprintf(stderr,
828 					    "\tCould not read "
829 					    "forwarded credentials\r\n");
830 		} else
831 			reply_to_client(ap, KRB_FORWARD_ACCEPT, (void *) 0, 0);
832 
833 		if (rsaddr.contents != NULL)
834 			free(rsaddr.contents);
835 
836 		if (rsport.contents != NULL)
837 			free(rsport.contents);
838 
839 		if (auth_debug)
840 			(void) fprintf(stderr, "\tForwarded "
841 						"credentials obtained\r\n");
842 		break;
843 	default:
844 		if (auth_debug)
845 			(void) fprintf(stderr,
846 				    "\tUnknown Kerberos option %d\r\n",
847 				    data[-1]);
848 		reply_to_client(ap, KRB_REJECT, (void *) 0, 0);
849 		break;
850 	}
851 	return;
852 
853 errout:
854 	reply_to_client(ap, KRB_REJECT, errbuf, -1);
855 
856 	if (auth_debug)
857 		(void) fprintf(stderr, "\tKerberos V5 error: %s\r\n", errbuf);
858 
859 	syslog(LOG_ERR, "%s", errbuf);
860 
861 	if (auth_context != NULL) {
862 		(void) krb5_auth_con_free(telnet_context, auth_context);
863 		auth_context = 0;
864 	}
865 }
866 
867 static int
krb5_init()868 krb5_init()
869 {
870 	int code = 0;
871 
872 	if (telnet_context == NULL) {
873 		code = krb5_init_context(&telnet_context);
874 		if (code != 0 && auth_debug)
875 			syslog(LOG_NOTICE,
876 			    "Cannot initialize Kerberos V5: %s",
877 			    error_message(code));
878 	}
879 
880 	return (code);
881 }
882 
883 static void
auth_name(uchar_t * data,int cnt)884 auth_name(uchar_t *data, int cnt)
885 {
886 	char namebuf[MAXPRINCLEN];
887 
888 	if (cnt < 1) {
889 		if (auth_debug)
890 			(void) fprintf(stderr,
891 				    "\t(auth_name) Empty NAME in auth "
892 				    "reply\n");
893 		return;
894 	}
895 	if (cnt > sizeof (namebuf)-1) {
896 		if (auth_debug)
897 			(void) fprintf(stderr,
898 				    "\t(auth_name) NAME exceeds %d bytes\n",
899 				sizeof (namebuf)-1);
900 		return;
901 	}
902 	(void) memcpy((void *)namebuf, (void *)data, cnt);
903 	namebuf[cnt] = 0;
904 	if (auth_debug)
905 		(void) fprintf(stderr, "\t(auth_name) name [%s]\n", namebuf);
906 	AuthenticatingUser = (char *)strdup(namebuf);
907 }
908 
909 static void
auth_is(uchar_t * data,int cnt)910 auth_is(uchar_t *data, int cnt)
911 {
912 	AuthInfo *aptr = auth_list;
913 
914 	if (cnt < 2)
915 		return;
916 
917 	/*
918 	 * We failed to negoiate secure authentication
919 	 */
920 	if (data[0] == AUTHTYPE_NULL) {
921 		auth_finished(0, AUTH_REJECT);
922 		return;
923 	}
924 
925 	while (aptr->AuthName != 0 &&
926 	    (aptr->AuthName != data[0] || aptr->AuthHow != data[1]))
927 		aptr++;
928 
929 	if (aptr != NULL) {
930 		if (auth_debug)
931 			(void) fprintf(stderr, "\t(auth_is) auth type is %s "
932 				"(%d bytes)\n",	aptr->AuthString, cnt);
933 
934 		if (aptr->AuthName == AUTHTYPE_KERBEROS_V5)
935 			kerberos5_is(aptr, data+2, cnt-2);
936 	}
937 }
938 
939 static int
krb5_user_status(char * name,int namelen,int level)940 krb5_user_status(char *name, int namelen, int level)
941 {
942 	int retval = AUTH_USER;
943 
944 	if (auth_debug)
945 		(void) fprintf(stderr, "\t(krb5_user_status) level = %d "
946 			"auth_level = %d  user = %s\n",
947 			level, auth_level,
948 			(AuthenticatingUser != NULL ? AuthenticatingUser : ""));
949 
950 	if (level < AUTH_USER)
951 		return (level);
952 
953 	if (AuthenticatingUser != NULL &&
954 	    (retval = krb5_kuserok(telnet_context, ticket->enc_part2->client,
955 			    AuthenticatingUser))) {
956 		(void) strncpy(name, AuthenticatingUser, namelen);
957 		return (AUTH_VALID);
958 	} else {
959 		if (!retval)
960 			syslog(LOG_ERR,
961 			    "Krb5 principal lacks permission to "
962 			    "access local account for %s",
963 			    AuthenticatingUser);
964 		return (AUTH_USER);
965 	}
966 }
967 
968 /*
969  * Wrapper around /dev/urandom
970  */
971 static int
getrandom(char * buf,int buflen)972 getrandom(char *buf, int buflen)
973 {
974 	static int devrandom = -1;
975 
976 	if (devrandom == -1 &&
977 	    (devrandom = open("/dev/urandom", O_RDONLY)) == -1) {
978 		fatalperror(net, "Unable to open /dev/urandom: ",
979 			    errno);
980 		return (-1);
981 	}
982 
983 	if (read(devrandom, buf, buflen) == -1) {
984 		fatalperror(net, "Unable to read from /dev/urandom: ",
985 			    errno);
986 		return (-1);
987 	}
988 
989 	return (0);
990 }
991 
992 /*
993  * encrypt_init
994  *
995  * Initialize the encryption data structures
996  */
997 static void
encrypt_init()998 encrypt_init()
999 {
1000 	(void) memset(&encr_data.encrypt, 0, sizeof (cipher_info_t));
1001 	(void) memset(&encr_data.decrypt, 0, sizeof (cipher_info_t));
1002 
1003 	encr_data.encrypt.state = ENCR_STATE_NOT_READY;
1004 	encr_data.decrypt.state = ENCR_STATE_NOT_READY;
1005 }
1006 
1007 /*
1008  * encrypt_send_request_start
1009  *
1010  * Request that the remote side automatically start sending
1011  * encrypted output
1012  */
1013 static void
encrypt_send_request_start()1014 encrypt_send_request_start()
1015 {
1016 	uchar_t buf[6+TELNET_MAXKEYIDLEN], *p;
1017 
1018 	p = buf;
1019 
1020 	*p++ = IAC;
1021 	*p++ = SB;
1022 	*p++ = TELOPT_ENCRYPT;
1023 	*p++ = ENCRYPT_REQSTART;
1024 	/*
1025 	 * We are telling the remote side which
1026 	 * decrypt key we will use so that it may
1027 	 * encrypt in the same key.
1028 	 */
1029 	(void) memcpy(p, encr_data.decrypt.keyid, encr_data.decrypt.keyidlen);
1030 	p += encr_data.decrypt.keyidlen;
1031 
1032 	*p++ = IAC;
1033 	*p++ = SE;
1034 
1035 	write_data_len((const char *)buf, p-buf);
1036 	netflush();
1037 	if (enc_debug)
1038 		(void) fprintf(stderr,
1039 			    "SENT TELOPT_ENCRYPT ENCRYPT_REQSTART\n");
1040 }
1041 
1042 /*
1043  * encrypt_is
1044  *
1045  * When we receive the TELOPT_ENCRYPT ENCRYPT_IS ...
1046  * message, the client is telling us that it will be sending
1047  * encrypted data using the indicated cipher.
1048  * We must initialize the read (decrypt) side of our connection
1049  */
1050 static void
encrypt_is(uchar_t * data,int cnt)1051 encrypt_is(uchar_t *data, int cnt)
1052 {
1053 	register int type;
1054 	register int iv_status = CFB64_IV_OK;
1055 	register int lstate = 0;
1056 
1057 	uchar_t sbbuf[] = {
1058 		(uchar_t)IAC,
1059 		(uchar_t)SB,
1060 		(uchar_t)TELOPT_ENCRYPT,
1061 		(uchar_t)ENCRYPT_REPLY,
1062 		(uchar_t)0,		/* placeholder:  sbbuf[4] */
1063 		(uchar_t)CFB64_IV_OK,	/* placeholder:  sbbuf[5] */
1064 		(uchar_t)IAC,
1065 		(uchar_t)SE,
1066 	};
1067 
1068 	if (--cnt < 0)
1069 		return;
1070 
1071 	type = sbbuf[4] = *data++;
1072 
1073 	/*
1074 	 * Steps to take:
1075 	 *   1. Create the proper stream Initialization vector
1076 	 *		- copy the correct 'seed' to IV and output blocks
1077 	 *		- set the correct key schedule
1078 	 *   2. Generate reply for the other side:
1079 	 *		IAC SB TELOPT_ENCRYPT ENCRYPT_REPLY type CFB64_IV_OK
1080 	 *		[ data ... ] IAC SE
1081 	 *   3. Tell crypto module:  method, direction, IV
1082 	 */
1083 	switch (type) {
1084 	case TELOPT_ENCTYPE_DES_CFB64:
1085 		encr_data.decrypt.type = type;
1086 
1087 		lstate = encr_data.decrypt.state;
1088 		if (enc_debug)
1089 			(void) fprintf(stderr,
1090 				    "\t(encrypt_is) initial state = %d\n",
1091 				    lstate);
1092 		/*
1093 		 * Before we extract the IV bytes, make sure we got
1094 		 * enough data.
1095 		 */
1096 		if (cnt < sizeof (Block)) {
1097 			iv_status = CFB64_IV_BAD;
1098 			if (enc_debug)
1099 				(void) fprintf(stderr,
1100 					    "\t(encrypt_is) Not enough "
1101 					    "IV bytes\n");
1102 			lstate = ENCR_STATE_NOT_READY;
1103 		} else {
1104 			data++; /* skip over the CFB64_IV byte */
1105 			(void) memcpy(encr_data.decrypt.ivec, data,
1106 				    sizeof (Block));
1107 			lstate = ENCR_STATE_IN_PROGRESS;
1108 		}
1109 		break;
1110 	case TELOPT_ENCTYPE_NULL:
1111 		encr_data.decrypt.type = type;
1112 		lstate &= ~ENCR_STATE_NO_RECV_IV;
1113 		lstate &= ~ENCR_STATE_NO_SEND_IV;
1114 		if (enc_debug)
1115 			(void) fprintf(stderr,
1116 				"\t(encrypt_is) We accept NULL encr\n");
1117 		break;
1118 	default:
1119 		iv_status = CFB64_IV_BAD;
1120 		encr_data.decrypt.type = 0;
1121 		if (enc_debug)
1122 			(void) fprintf(stderr,
1123 				    "\t(encrypt_is) Can't find type (%d) "
1124 				    "for initial negotiation\r\n",
1125 				    type);
1126 		lstate = ENCR_STATE_NOT_READY;
1127 		break;
1128 	}
1129 
1130 	sbbuf[5] = (uchar_t)iv_status; /* either CFB64_IV_OK or BAD */
1131 
1132 	if (iv_status == CFB64_IV_OK) {
1133 		/*
1134 		 * send IV to crypto module and indicate it is for
1135 		 * decrypt only
1136 		 */
1137 		lstate &= ~ENCR_STATE_NO_RECV_IV;  /* we received an OK IV */
1138 		lstate &= ~ENCR_STATE_NO_SEND_IV;  /* we dont send an IV */
1139 	} else {
1140 		/* tell crypto module to disable crypto on "read" stream */
1141 		lstate = ENCR_STATE_NOT_READY;
1142 	}
1143 
1144 	write_data_len((const char *)sbbuf, sizeof (sbbuf));
1145 	netflush();
1146 #ifdef ENCRYPT_NAMES
1147 	if (enc_debug)
1148 		(void) fprintf(stderr,
1149 			    "SENT TELOPT_ENCRYPT ENCRYPT_REPLY %s %s\n",
1150 			    ENCTYPE_NAME(type),
1151 			    (iv_status == CFB64_IV_OK ? "CFB64_IV_OK" :
1152 			    "CFB64_IV_BAD"));
1153 #endif /* ENCRYPT_NAMES */
1154 	/* Update the state of the decryption negotiation */
1155 	encr_data.decrypt.state = lstate;
1156 
1157 	if (lstate == ENCR_STATE_NOT_READY)
1158 		encr_data.decrypt.autoflag = 0;
1159 	else {
1160 		if (lstate == ENCR_STATE_OK && encr_data.decrypt.autoflag)
1161 			encrypt_send_request_start();
1162 	}
1163 	if (enc_debug)
1164 		(void) fprintf(stderr,
1165 			    "\t(encrypt_is) final DECRYPT state = %d\n",
1166 			    encr_data.decrypt.state);
1167 }
1168 
1169 /*
1170  * encrypt_send_encrypt_is
1171  *
1172  * Tell the client what encryption we will use
1173  * and what our IV will be.
1174  */
1175 static int
encrypt_send_encrypt_is()1176 encrypt_send_encrypt_is()
1177 {
1178 	register int lstate;
1179 	krb5_error_code kret;
1180 	uchar_t sbbuf[MAXOPTLEN], *p;
1181 	int i;
1182 
1183 	lstate = encr_data.encrypt.state;
1184 
1185 	if (encr_data.encrypt.type == ENCTYPE_NULL) {
1186 		/*
1187 		 * Haven't received ENCRYPT SUPPORT yet or we couldn't agree
1188 		 * on a cipher.
1189 		 */
1190 		return (lstate);
1191 	}
1192 
1193 	/*
1194 	 * - Create a random DES key
1195 	 *
1196 	 * - DES ECB encrypt
1197 	 *   encrypt the IV using itself as the key.
1198 	 *
1199 	 * - Send response
1200 	 *   IAC SB TELOPT_ENCRYPT ENCRYPT_IS CFB64 FB64_IV [ feed block ]
1201 	 *   IAC SE
1202 	 *
1203 	 */
1204 	if (lstate == ENCR_STATE_NOT_READY)
1205 		lstate = ENCR_STATE_IN_PROGRESS;
1206 	else if ((lstate & ENCR_STATE_NO_SEND_IV) == 0) {
1207 		if (enc_debug)
1208 			(void) fprintf(stderr,
1209 				"\t(encrypt_send_is) IV already sent,"
1210 				" state = %d\n", lstate);
1211 		return (lstate);
1212 	}
1213 
1214 	if (!VALIDKEY(encr_data.encrypt.krbdes_key)) {
1215 		/*
1216 		 * Invalid key, set flag so we try again later
1217 		 * when we get a good one
1218 		 */
1219 		encr_data.encrypt.need_start = 1;
1220 		if (enc_debug)
1221 			(void) fprintf(stderr,
1222 				"\t(encrypt_send_is) No Key, cannot "
1223 				"start encryption yet\n");
1224 		return (lstate);
1225 	}
1226 	if (enc_debug)
1227 		(void) fprintf(stderr,
1228 			    "\t(encrypt_send_is) Creating new feed\n");
1229 
1230 	/*
1231 	 * Create a random feed and send it over.
1232 	 *
1233 	 * Use the /dev/[u]random interface to generate
1234 	 * our encryption IV.
1235 	 */
1236 	kret = getrandom((char *)encr_data.encrypt.ivec, sizeof (Block));
1237 
1238 	if (kret) {
1239 		if (enc_debug)
1240 			(void) fprintf(stderr,
1241 				    "\t(encrypt_send_is) error from "
1242 				    "getrandom: %d\n", kret);
1243 		syslog(LOG_ERR, "Failed to create encryption key (err %d)\n");
1244 		encr_data.encrypt.type = ENCTYPE_NULL;
1245 	} else {
1246 		mit_des_fixup_key_parity(encr_data.encrypt.ivec);
1247 	}
1248 
1249 	p = sbbuf;
1250 	*p++ = IAC;
1251 	*p++ = SB;
1252 	*p++ = TELOPT_ENCRYPT;
1253 	*p++ = ENCRYPT_IS;
1254 	*p++ = encr_data.encrypt.type;
1255 	*p++ = CFB64_IV;
1256 
1257 	/*
1258 	 * Copy the IV bytes individually so that when a
1259 	 * 255 (telnet IAC) is used, it can be "escaped" by
1260 	 * adding it twice (telnet RFC 854).
1261 	 */
1262 	for (i = 0; i < sizeof (Block); i++)
1263 		if ((*p++ = encr_data.encrypt.ivec[i]) == IAC)
1264 			*p++ = IAC;
1265 
1266 	*p++ = IAC;
1267 	*p++ = SE;
1268 	write_data_len((const char *)sbbuf, (size_t)(p-sbbuf));
1269 	netflush();
1270 
1271 	if (!kret) {
1272 		lstate &= ~ENCR_STATE_NO_SEND_IV; /* we sent our IV */
1273 		lstate &= ~ENCR_STATE_NO_SEND_IV; /* dont need decrypt IV */
1274 	}
1275 	encr_data.encrypt.state = lstate;
1276 
1277 	if (enc_debug) {
1278 		int i;
1279 		(void) fprintf(stderr,
1280 			    "SENT TELOPT_ENCRYPT ENCRYPT_IS %d CFB64_IV ",
1281 			    encr_data.encrypt.type);
1282 		for (i = 0; i < (p-sbbuf); i++)
1283 			(void) fprintf(stderr, "%d ", (int)sbbuf[i]);
1284 		(void) fprintf(stderr, "\n");
1285 	}
1286 
1287 	return (lstate);
1288 }
1289 
1290 /*
1291  * stop_stream
1292  *
1293  * Utility routine to send a CRIOCSTOP ioctl to the
1294  * crypto module (cryptmod).
1295  */
1296 static void
stop_stream(int fd,int dir)1297 stop_stream(int fd, int dir)
1298 {
1299 	struct strioctl  crioc;
1300 	uint32_t stopdir = dir;
1301 
1302 	crioc.ic_cmd = CRYPTIOCSTOP;
1303 	crioc.ic_timout = -1;
1304 	crioc.ic_len = sizeof (stopdir);
1305 	crioc.ic_dp = (char *)&stopdir;
1306 
1307 	if (ioctl(fd, I_STR, &crioc)) {
1308 		syslog(LOG_ERR, "Error sending CRYPTIOCSTOP ioctl: %m");
1309 	}
1310 }
1311 
1312 /*
1313  * start_stream
1314  *
1315  * Utility routine to send a CRYPTIOCSTART ioctl to the
1316  * crypto module (cryptmod).  This routine may contain optional
1317  * payload data that the cryptmod will interpret as bytes that
1318  * need to be decrypted and sent back up to the application
1319  * via the data stream.
1320  */
1321 static void
start_stream(int fd,int dir,int datalen,char * data)1322 start_stream(int fd, int dir, int datalen, char *data)
1323 {
1324 	struct strioctl crioc;
1325 
1326 	crioc.ic_cmd = (dir == CRYPT_ENCRYPT ? CRYPTIOCSTARTENC :
1327 			CRYPTIOCSTARTDEC);
1328 	crioc.ic_timout = -1;
1329 	crioc.ic_len = datalen;
1330 	crioc.ic_dp = data;
1331 
1332 	if (ioctl(fd, I_STR, &crioc)) {
1333 		syslog(LOG_ERR, "Error sending CRYPTIOCSTART ioctl: %m");
1334 	}
1335 }
1336 
1337 /*
1338  * encrypt_start_output
1339  *
1340  * Tell the other side to start encrypting its data
1341  */
1342 static void
encrypt_start_output()1343 encrypt_start_output()
1344 {
1345 	int lstate;
1346 	uchar_t *p;
1347 	uchar_t sbbuf[MAXOPTLEN];
1348 	struct strioctl crioc;
1349 	struct cr_info_t cki;
1350 
1351 	/*
1352 	 * Initialize crypto and send the ENCRYPT_IS msg
1353 	 */
1354 	lstate = encrypt_send_encrypt_is();
1355 
1356 	if (lstate != ENCR_STATE_OK) {
1357 		if (enc_debug)
1358 			(void) fprintf(stderr,
1359 				"\t(encrypt_start_output) ENCRYPT state "
1360 				"= %d\n", lstate);
1361 		return;
1362 	}
1363 
1364 	p = sbbuf;
1365 
1366 	*p++ = IAC;
1367 	*p++ = SB;
1368 	*p++ = TELOPT_ENCRYPT;
1369 	*p++ = ENCRYPT_START;
1370 
1371 	(void) memcpy(p, encr_data.encrypt.keyid, encr_data.encrypt.keyidlen);
1372 	p += encr_data.encrypt.keyidlen;
1373 
1374 	*p++ = IAC;
1375 	*p++ = SE;
1376 
1377 	/* Flush this data out before we start encrypting */
1378 	write_data_len((const char *)sbbuf, (int)(p-sbbuf));
1379 	netflush();
1380 
1381 	if (enc_debug)
1382 		(void) fprintf(stderr, "SENT TELOPT_ENCRYPT ENCRYPT_START %d "
1383 			"(lstate = %d) data waiting = %d\n",
1384 			(int)encr_data.encrypt.keyid[0],
1385 			lstate, nfrontp-nbackp);
1386 
1387 	encr_data.encrypt.state = lstate;
1388 
1389 	/*
1390 	 * tell crypto module what key to use for encrypting
1391 	 * Note that the ENCRYPT has not yet been enabled, but we
1392 	 * need to first set the crypto key to use.
1393 	 */
1394 	cki.direction_mask = CRYPT_ENCRYPT;
1395 
1396 	if (encr_data.encrypt.type == TELOPT_ENCTYPE_DES_CFB64) {
1397 		cki.crypto_method = CRYPT_METHOD_DES_CFB;
1398 	} else {
1399 		if (enc_debug)
1400 			(void) fprintf(stderr,
1401 				"\t(encrypt_start_output) - unknown "
1402 				"crypto_method %d\n",
1403 				encr_data.encrypt.type);
1404 		syslog(LOG_ERR, "unrecognized crypto encrypt method: %d",
1405 				encr_data.encrypt.type);
1406 
1407 		return;
1408 	}
1409 
1410 	/*
1411 	 * If we previously configured this crypto method, we dont want to
1412 	 * overwrite the key or ivec information already given to the crypto
1413 	 * module as it will cause the cipher data between the client and server
1414 	 * to become out of synch and impossible to decipher.
1415 	 */
1416 	if (encr_data.encrypt.setup == cki.crypto_method) {
1417 		cki.keylen = 0;
1418 		cki.iveclen = 0;
1419 	} else {
1420 		cki.keylen = DES_BLOCKSIZE;
1421 		(void) memcpy(cki.key, (void *)encr_data.encrypt.krbdes_key,
1422 		    DES_BLOCKSIZE);
1423 
1424 		cki.iveclen = DES_BLOCKSIZE;
1425 		(void) memcpy(cki.ivec, (void *)encr_data.encrypt.ivec,
1426 		    DES_BLOCKSIZE);
1427 
1428 		cki.ivec_usage = IVEC_ONETIME;
1429 	}
1430 
1431 	cki.option_mask = 0;
1432 
1433 	/* Stop encrypt side prior to setup so we dont lose data */
1434 	stop_stream(cryptmod_fd, CRYPT_ENCRYPT);
1435 
1436 	crioc.ic_cmd = CRYPTIOCSETUP;
1437 	crioc.ic_timout = -1;
1438 	crioc.ic_len = sizeof (struct cr_info_t);
1439 	crioc.ic_dp = (char *)&cki;
1440 
1441 	if (ioctl(cryptmod_fd, I_STR, &crioc)) {
1442 		perror("ioctl(CRYPTIOCSETUP) [encrypt_start_output] error");
1443 	} else {
1444 		/* Setup completed OK */
1445 		encr_data.encrypt.setup = cki.crypto_method;
1446 	}
1447 
1448 	/*
1449 	 * We do not check for "stuck" data when setting up the
1450 	 * outbound "encrypt" channel.  Any data queued prior to
1451 	 * this IOCTL will get processed correctly without our help.
1452 	 */
1453 	start_stream(cryptmod_fd, CRYPT_ENCRYPT, 0, NULL);
1454 
1455 	/*
1456 	 * tell crypto module to start encrypting
1457 	 */
1458 	if (enc_debug)
1459 		(void) fprintf(stderr,
1460 			"\t(encrypt_start_output) Encrypting output\n");
1461 }
1462 
1463 /*
1464  * encrypt_request_start
1465  *
1466  * The client requests that we start encryption immediately after
1467  * successful negotiation
1468  */
1469 static void
encrypt_request_start(void)1470 encrypt_request_start(void)
1471 {
1472 	if (encr_data.encrypt.type == ENCTYPE_NULL) {
1473 		encr_data.encrypt.autoflag = 1;
1474 		if (enc_debug)
1475 			(void) fprintf(stderr, "\t(encrypt_request_start) "
1476 				"autoencrypt = ON\n");
1477 	} else {
1478 		encrypt_start_output();
1479 	}
1480 }
1481 
1482 /*
1483  * encrypt_end
1484  *
1485  * ENCRYPT END received, stop decrypting the read stream
1486  */
1487 static void
encrypt_end(int direction)1488 encrypt_end(int direction)
1489 {
1490 	struct cr_info_t cki;
1491 	struct strioctl  crioc;
1492 	uint32_t stopdir;
1493 
1494 	stopdir = (direction == TELNET_DIR_DECRYPT ? CRYPT_DECRYPT :
1495 		CRYPT_ENCRYPT);
1496 
1497 	stop_stream(cryptmod_fd, stopdir);
1498 
1499 	/*
1500 	 * Call this function when we wish to disable crypto in
1501 	 * either direction (ENCRYPT or DECRYPT)
1502 	 */
1503 	cki.direction_mask = (direction == TELNET_DIR_DECRYPT ? CRYPT_DECRYPT :
1504 			    CRYPT_ENCRYPT);
1505 	cki.crypto_method = CRYPT_METHOD_NONE;
1506 	cki.option_mask = 0;
1507 
1508 	cki.keylen = 0;
1509 	cki.iveclen = 0;
1510 	cki.ivec_usage = IVEC_ONETIME;
1511 
1512 	crioc.ic_cmd = CRYPTIOCSETUP;
1513 	crioc.ic_timout = -1;
1514 	crioc.ic_len = sizeof (cki);
1515 	crioc.ic_dp = (char *)&cki;
1516 
1517 	if (ioctl(cryptmod_fd, I_STR, &crioc)) {
1518 		perror("ioctl(CRYPTIOCSETUP) [encrypt_end] error");
1519 	}
1520 
1521 	start_stream(cryptmod_fd, stopdir, 0, NULL);
1522 }
1523 
1524 /*
1525  * encrypt_request_end
1526  *
1527  * When we receive a REQEND from the client, it means
1528  * that we are supposed to stop encrypting
1529  */
1530 static void
encrypt_request_end()1531 encrypt_request_end()
1532 {
1533 	/*
1534 	 * Tell the other side we are done encrypting
1535 	 */
1536 
1537 	write_data("%c%c%c%c%c%c",
1538 		(uchar_t)IAC,
1539 		(uchar_t)SB,
1540 		(uchar_t)TELOPT_ENCRYPT,
1541 		(uchar_t)ENCRYPT_END,
1542 		(uchar_t)IAC,
1543 		(uchar_t)SE);
1544 	netflush();
1545 	if (enc_debug)
1546 		(void) fprintf(stderr, "SENT TELOPT_ENCRYPT ENCRYPT_END\n");
1547 
1548 	/*
1549 	 * Turn off encryption of the write stream
1550 	 */
1551 	encrypt_end(TELNET_DIR_ENCRYPT);
1552 }
1553 
1554 /*
1555  * encrypt_send_request_end
1556  *
1557  * We stop encrypting the write stream and tell the other side about it.
1558  */
1559 static void
encrypt_send_request_end()1560 encrypt_send_request_end()
1561 {
1562 	write_data("%c%c%c%c%c%c",
1563 		(uchar_t)IAC,
1564 		(uchar_t)SB,
1565 		(uchar_t)TELOPT_ENCRYPT,
1566 		(uchar_t)ENCRYPT_REQEND,
1567 		(uchar_t)IAC,
1568 		(uchar_t)SE);
1569 	netflush();
1570 	if (enc_debug)
1571 		(void) fprintf(stderr, "SENT TELOPT_ENCRYPT ENCRYPT_REQEND\n");
1572 }
1573 
1574 /*
1575  * encrypt_start
1576  *
1577  * The client is going to start sending encrypted data
1578  * using the previously negotiated cipher (see what we set
1579  * when we did the REPLY in encrypt_is).
1580  */
1581 static void
encrypt_start(void)1582 encrypt_start(void)
1583 {
1584 	struct cr_info_t cki;
1585 	struct strioctl  crioc;
1586 	int bytes = 0;
1587 	char *dataptr = NULL;
1588 
1589 	if (encr_data.decrypt.type == ENCTYPE_NULL) {
1590 		if (enc_debug)
1591 			(void) fprintf(stderr,
1592 				"\t(encrypt_start) No DECRYPT method "
1593 				"defined yet\n");
1594 		encrypt_send_request_end();
1595 		return;
1596 	}
1597 
1598 	cki.direction_mask = CRYPT_DECRYPT;
1599 
1600 	if (encr_data.decrypt.type == TELOPT_ENCTYPE_DES_CFB64) {
1601 		cki.crypto_method = CRYPT_METHOD_DES_CFB;
1602 	} else {
1603 		if (enc_debug)
1604 			(void) fprintf(stderr,
1605 				"\t(encrypt_start) - unknown "
1606 				"crypto_method %d\n", encr_data.decrypt.type);
1607 
1608 		syslog(LOG_ERR, "unrecognized crypto decrypt method: %d",
1609 				encr_data.decrypt.type);
1610 
1611 		return;
1612 	}
1613 
1614 	/*
1615 	 * Don't overwrite previously configured key and ivec info
1616 	 */
1617 	if (encr_data.decrypt.setup != cki.crypto_method) {
1618 		(void) memcpy(cki.key, (void *)encr_data.decrypt.krbdes_key,
1619 		    DES_BLOCKSIZE);
1620 		(void) memcpy(cki.ivec, (void *)encr_data.decrypt.ivec,
1621 		    DES_BLOCKSIZE);
1622 
1623 		cki.keylen = DES_BLOCKSIZE;
1624 		cki.iveclen = DES_BLOCKSIZE;
1625 		cki.ivec_usage = IVEC_ONETIME;
1626 	} else {
1627 		cki.keylen = 0;
1628 		cki.iveclen = 0;
1629 	}
1630 	cki.option_mask = 0;
1631 
1632 	stop_stream(cryptmod_fd, CRYPT_DECRYPT);
1633 
1634 	crioc.ic_cmd = CRYPTIOCSETUP;
1635 	crioc.ic_timout = -1;
1636 	crioc.ic_len = sizeof (struct cr_info_t);
1637 	crioc.ic_dp = (char *)&cki;
1638 
1639 	if (ioctl(cryptmod_fd, I_STR, &crioc)) {
1640 		syslog(LOG_ERR, "ioctl(CRYPTIOCSETUP) [encrypt_start] "
1641 		    "error: %m");
1642 	} else {
1643 		encr_data.decrypt.setup = cki.crypto_method;
1644 	}
1645 	if (enc_debug)
1646 		(void) fprintf(stderr,
1647 			    "\t(encrypt_start) called CRYPTIOCSETUP for "
1648 			    "decrypt side\n");
1649 
1650 	/*
1651 	 * Read any data stuck between the cryptmod and the application
1652 	 * so we can pass it back down to be properly decrypted after
1653 	 * this operation finishes.
1654 	 */
1655 	if (ioctl(cryptmod_fd, I_NREAD, &bytes) < 0) {
1656 		syslog(LOG_ERR, "I_NREAD returned error %m");
1657 		bytes = 0;
1658 	}
1659 
1660 	/*
1661 	 * Any data which was read AFTER the ENCRYPT START message
1662 	 * must be sent back down to be decrypted properly.
1663 	 *
1664 	 * 'ncc' is the number of bytes that have been read but
1665 	 * not yet processed by the telnet state machine.
1666 	 *
1667 	 * 'bytes' is the number of bytes waiting to be read from
1668 	 * the stream.
1669 	 *
1670 	 * If either one is a positive value, then those bytes
1671 	 * must be pulled up and sent back down to be decrypted.
1672 	 */
1673 	if (ncc || bytes) {
1674 		drainstream(bytes);
1675 		if (enc_debug)
1676 			(void) fprintf(stderr,
1677 				"\t(encrypt_start) after drainstream, "
1678 				"ncc=%d bytes = %d\n", ncc, bytes);
1679 		bytes += ncc;
1680 		dataptr = netip;
1681 	}
1682 
1683 	start_stream(cryptmod_fd, CRYPT_DECRYPT, bytes, dataptr);
1684 
1685 	/*
1686 	 * The bytes putback into the stream are no longer
1687 	 * available to be read by the server, so adjust the
1688 	 * counter accordingly.
1689 	 */
1690 	ncc = 0;
1691 	netip = netibuf;
1692 	(void) memset(netip, 0, netibufsize);
1693 
1694 #ifdef ENCRYPT_NAMES
1695 	if (enc_debug) {
1696 		(void) fprintf(stderr,
1697 			    "\t(encrypt_start) Start DECRYPT using %s\n",
1698 			    ENCTYPE_NAME(encr_data.decrypt.type));
1699 	}
1700 #endif /* ENCRYPT_NAMES */
1701 }
1702 
1703 /*
1704  * encrypt_support
1705  *
1706  * Called when we recieve the TELOPT_ENCRYPT SUPPORT [ encr type list ]
1707  * message from a client.
1708  *
1709  * Choose an agreeable method (DES_CFB64) and
1710  * respond with  TELOPT_ENCRYPT ENCRYPT_IS [ desired crypto method ]
1711  *
1712  * from: RFC 2946
1713  */
1714 static void
encrypt_support(char * data,int cnt)1715 encrypt_support(char *data, int cnt)
1716 {
1717 	int lstate = ENCR_STATE_NOT_READY;
1718 	int type, use_type = 0;
1719 
1720 	while (cnt-- > 0 && use_type == 0) {
1721 		type = *data++;
1722 #ifdef ENCRYPT_NAMES
1723 		if (enc_debug)
1724 			(void) fprintf(stderr,
1725 				    "RCVD ENCRYPT SUPPORT %s\n",
1726 				    ENCTYPE_NAME(type));
1727 #endif /* ENCRYPT_NAMES */
1728 		/*
1729 		 * Prefer CFB64
1730 		 */
1731 		if (type == TELOPT_ENCTYPE_DES_CFB64) {
1732 			use_type = type;
1733 		}
1734 	}
1735 	encr_data.encrypt.type = use_type;
1736 
1737 	if (use_type != TELOPT_ENCTYPE_NULL &&
1738 	    authenticated != NULL && authenticated != &NoAuth &&
1739 	    auth_status != AUTH_REJECT) {
1740 
1741 		/* Authenticated -> have session key -> send ENCRYPT IS */
1742 		lstate = encrypt_send_encrypt_is();
1743 		if (lstate == ENCR_STATE_OK)
1744 			encrypt_start_output();
1745 	} else if (use_type == TELOPT_ENCTYPE_NULL) {
1746 		if (enc_debug)
1747 			(void) fprintf(stderr,
1748 				    "\t(encrypt_support) Cannot agree "
1749 				    "on crypto algorithm, output encryption "
1750 				    "disabled.\n");
1751 
1752 		/*
1753 		 * Cannot agree on crypto algorithm
1754 		 * RFC 2946 sez:
1755 		 *    send "IAC SB ENCRYPT IS NULL IAC SE"
1756 		 *    optionally, also send IAC WONT ENCRYPT
1757 		 */
1758 		write_data("%c%c%c%c%c%c%c",
1759 			(uchar_t)IAC,
1760 			(uchar_t)SB,
1761 			(uchar_t)TELOPT_ENCRYPT,
1762 			(uchar_t)ENCRYPT_IS,
1763 			(uchar_t)TELOPT_ENCTYPE_NULL,
1764 			(uchar_t)IAC,
1765 			(uchar_t)SE);
1766 		send_wont(TELOPT_ENCRYPT);
1767 		netflush();
1768 		if (enc_debug)
1769 			(void) fprintf(stderr,
1770 				    "SENT TELOPT_ENCRYPT ENCRYPT_IS "
1771 				    "[NULL]\n");
1772 
1773 		remopts[TELOPT_ENCRYPT] = OPT_NO;
1774 	}
1775 	settimer(encr_support);
1776 }
1777 
1778 /*
1779  * encrypt_send_keyid
1780  *
1781  * Sent the key id we will use to the client
1782  */
1783 static void
encrypt_send_keyid(int dir,uchar_t * keyid,int keylen,boolean_t saveit)1784 encrypt_send_keyid(int dir, uchar_t *keyid, int keylen, boolean_t saveit)
1785 {
1786 	uchar_t sbbuf[128], *p;
1787 
1788 	p = sbbuf;
1789 
1790 	*p++ = IAC;
1791 	*p++ = SB;
1792 	*p++ = TELOPT_ENCRYPT;
1793 	*p++ = (dir == TELNET_DIR_ENCRYPT ? ENCRYPT_ENC_KEYID :
1794 		ENCRYPT_DEC_KEYID);
1795 	if (saveit) {
1796 		if (enc_debug)
1797 			(void) fprintf(stderr,
1798 				"\t(send_keyid) store %d byte %s keyid\n",
1799 				keylen,
1800 				(dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" :
1801 				"DECRYPT"));
1802 
1803 		if (dir == TELNET_DIR_ENCRYPT) {
1804 			(void) memcpy(encr_data.encrypt.keyid, keyid, keylen);
1805 			encr_data.encrypt.keyidlen = keylen;
1806 		} else {
1807 			(void) memcpy(encr_data.decrypt.keyid, keyid, keylen);
1808 			encr_data.decrypt.keyidlen = keylen;
1809 		}
1810 	}
1811 	(void) memcpy(p, keyid, keylen);
1812 	p += keylen;
1813 
1814 	*p++ = IAC;
1815 	*p++ = SE;
1816 	write_data_len((const char *)sbbuf, (size_t)(p-sbbuf));
1817 	netflush();
1818 
1819 	if (enc_debug)
1820 		(void) fprintf(stderr, "SENT TELOPT_ENCRYPT %s %d\n",
1821 			(dir == TELNET_DIR_ENCRYPT ? "ENC_KEYID" :
1822 			"DEC_KEYID"), keyid[0]);
1823 }
1824 
1825 /*
1826  * encrypt_reply
1827  *
1828  * When we receive the TELOPT_ENCRYPT REPLY [crtype] CFB64_IV_OK IAC SE
1829  * message, process it accordingly.
1830  * If the vector is acceptable, tell client we are encrypting and
1831  * enable encryption on our write stream.
1832  *
1833  * Negotiate the KEYID next..
1834  * RFC 2946, 2952
1835  */
1836 static void
encrypt_reply(char * data,int len)1837 encrypt_reply(char *data, int len)
1838 {
1839 	uchar_t type = (uchar_t)(*data++);
1840 	uchar_t result = (uchar_t)(*data);
1841 	int lstate;
1842 
1843 #ifdef ENCRYPT_NAMES
1844 	if (enc_debug)
1845 		(void) fprintf(stderr,
1846 			"\t(encrypt_reply) ENCRYPT REPLY %s %s [len=%d]\n",
1847 			ENCRYPT_NAME(type),
1848 			(result == CFB64_IV_OK ? "CFB64_IV_OK" :
1849 			"CFB64_IV_BAD"), len);
1850 #endif /* ENCRYPT_NAMES */
1851 
1852 	lstate = encr_data.encrypt.state;
1853 	if (enc_debug)
1854 		(void) fprintf(stderr,
1855 			"\t(encrypt_reply) initial ENCRYPT state = %d\n",
1856 			lstate);
1857 	switch (result) {
1858 	case CFB64_IV_OK:
1859 		if (lstate == ENCR_STATE_NOT_READY)
1860 			lstate = ENCR_STATE_IN_PROGRESS;
1861 		lstate &= ~ENCR_STATE_NO_RECV_IV; /* we got the IV */
1862 		lstate &= ~ENCR_STATE_NO_SEND_IV; /* we dont need to send IV */
1863 
1864 		/*
1865 		 * The correct response here is to send the encryption key id
1866 		 * RFC 2752.
1867 		 *
1868 		 * Send keyid 0 to indicate that we will just use default
1869 		 * keys.
1870 		 */
1871 		encrypt_send_keyid(TELNET_DIR_ENCRYPT, (uchar_t *)"\0", 1, 1);
1872 
1873 		break;
1874 	case CFB64_IV_BAD:
1875 		/*
1876 		 * Clear the ivec
1877 		 */
1878 		(void) memset(encr_data.encrypt.ivec, 0, sizeof (Block));
1879 		lstate = ENCR_STATE_NOT_READY;
1880 		break;
1881 	default:
1882 		if (enc_debug)
1883 			(void) fprintf(stderr,
1884 				"\t(encrypt_reply) Got unknown IV value in "
1885 				"REPLY message\n");
1886 		lstate = ENCR_STATE_NOT_READY;
1887 		break;
1888 	}
1889 
1890 	encr_data.encrypt.state = lstate;
1891 	if (lstate == ENCR_STATE_NOT_READY) {
1892 		encr_data.encrypt.autoflag = 0;
1893 		encr_data.encrypt.type = ENCTYPE_NULL;
1894 		if (enc_debug)
1895 			(void) fprintf(stderr,
1896 				    "\t(encrypt_reply) encrypt.autoflag = "
1897 				    "OFF\n");
1898 	} else {
1899 		encr_data.encrypt.type = type;
1900 		if ((lstate == ENCR_STATE_OK) && encr_data.encrypt.autoflag)
1901 			encrypt_start_output();
1902 	}
1903 
1904 	if (enc_debug)
1905 		(void) fprintf(stderr,
1906 			    "\t(encrypt_reply) ENCRYPT final state = %d\n",
1907 			    lstate);
1908 }
1909 
1910 static void
encrypt_set_keyid_state(uchar_t * keyid,int * keyidlen,int dir)1911 encrypt_set_keyid_state(uchar_t *keyid, int *keyidlen, int dir)
1912 {
1913 	int lstate;
1914 
1915 	lstate = (dir == TELNET_DIR_ENCRYPT ? encr_data.encrypt.state :
1916 		encr_data.decrypt.state);
1917 
1918 	if (enc_debug)
1919 		(void) fprintf(stderr,
1920 			    "\t(set_keyid_state) %s initial state = %d\n",
1921 			    (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" :
1922 			    "DECRYPT"), lstate);
1923 
1924 	/*
1925 	 * Currently, we only support using the default keyid,
1926 	 * so it should be an error if the len > 1 or the keyid != 0.
1927 	 */
1928 	if (*keyidlen != 1 || (*keyid != '\0')) {
1929 		if (enc_debug)
1930 			(void) fprintf(stderr,
1931 				    "\t(set_keyid_state) unexpected keyid: "
1932 				    "len=%d value=%d\n", *keyidlen, *keyid);
1933 		*keyidlen = 0;
1934 		syslog(LOG_ERR, "rcvd unexpected keyid %d  - only keyid of 0 "
1935 		    "is supported",  *keyid);
1936 	} else {
1937 		/*
1938 		 * We move to the "IN_PROGRESS" state.
1939 		 */
1940 		if (lstate == ENCR_STATE_NOT_READY)
1941 			lstate = ENCR_STATE_IN_PROGRESS;
1942 		/*
1943 		 * Clear the NO_KEYID bit because we now have a valid keyid
1944 		 */
1945 		lstate &= ~ENCR_STATE_NO_KEYID;
1946 	}
1947 
1948 	if (enc_debug)
1949 		(void) fprintf(stderr,
1950 			    "\t(set_keyid_state) %s final state = %d\n",
1951 			    (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" :
1952 			    "DECRYPT"), lstate);
1953 
1954 	if (dir == TELNET_DIR_ENCRYPT)
1955 		encr_data.encrypt.state = lstate;
1956 	else
1957 		encr_data.decrypt.state = lstate;
1958 }
1959 
1960 /*
1961  * encrypt_keyid
1962  *
1963  * Set the keyid value in the key_info structure.
1964  * if necessary send a response to the sender
1965  */
1966 static void
encrypt_keyid(uchar_t * newkeyid,int * keyidlen,uchar_t * keyid,int len,int dir)1967 encrypt_keyid(uchar_t *newkeyid, int *keyidlen, uchar_t *keyid,
1968 	int len, int dir)
1969 {
1970 	if (len > TELNET_MAXNUMKEYS) {
1971 		if (enc_debug)
1972 			(void) fprintf(stderr,
1973 				    "\t(keyid) keylen too big (%d)\n", len);
1974 		return;
1975 	}
1976 
1977 	if (enc_debug) {
1978 		(void) fprintf(stderr, "\t(keyid) set KEYID for %s len = %d\n",
1979 			    (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" :
1980 			    "DECRYPT"), len);
1981 	}
1982 
1983 	if (len == 0) {
1984 		if (*keyidlen == 0) {
1985 			if (enc_debug)
1986 				(void) fprintf(stderr,
1987 					    "\t(keyid) Got 0 length keyid - "
1988 					    "failure\n");
1989 			return;
1990 		}
1991 		*keyidlen = 0;
1992 		encrypt_set_keyid_state(newkeyid, keyidlen, dir);
1993 
1994 	} else if (len != *keyidlen || memcmp(keyid, newkeyid, len)) {
1995 		if (enc_debug)
1996 			(void) fprintf(stderr,
1997 				    "\t(keyid) Setting new key (%d bytes)\n",
1998 				    len);
1999 
2000 		*keyidlen = len;
2001 		(void) memcpy(newkeyid, keyid, len);
2002 
2003 		encrypt_set_keyid_state(newkeyid, keyidlen, dir);
2004 	} else {
2005 		encrypt_set_keyid_state(newkeyid, keyidlen, dir);
2006 
2007 		if (enc_debug)
2008 			(void) fprintf(stderr,
2009 				    "\t(keyid) %s Key already in place,"
2010 				    "state = %d autoflag=%d\n",
2011 			(dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : "DECRYPT"),
2012 			(dir == TELNET_DIR_ENCRYPT ? encr_data.encrypt.state:
2013 			encr_data.decrypt.state),
2014 			(dir == TELNET_DIR_ENCRYPT ?
2015 				encr_data.encrypt.autoflag:
2016 				encr_data.decrypt.autoflag));
2017 
2018 		/* key already in place */
2019 		if ((encr_data.encrypt.state == ENCR_STATE_OK) &&
2020 		    dir == TELNET_DIR_ENCRYPT && encr_data.encrypt.autoflag) {
2021 			encrypt_start_output();
2022 		}
2023 		return;
2024 	}
2025 
2026 	if (enc_debug)
2027 		(void) fprintf(stderr, "\t(keyid) %s final state = %d\n",
2028 			    (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" :
2029 			    "DECRYPT"),
2030 			    (dir == TELNET_DIR_ENCRYPT ?
2031 			    encr_data.encrypt.state :
2032 			    encr_data.decrypt.state));
2033 
2034 	encrypt_send_keyid(dir, newkeyid, *keyidlen, 0);
2035 }
2036 
2037 /*
2038  * encrypt_enc_keyid
2039  *
2040  * We received the ENC_KEYID message from a client indicating that
2041  * the client wishes to verify that the indicated keyid maps to a
2042  * valid key.
2043  */
2044 static void
encrypt_enc_keyid(char * data,int cnt)2045 encrypt_enc_keyid(char *data, int cnt)
2046 {
2047 	/*
2048 	 * Verify the decrypt keyid is valid
2049 	 */
2050 	encrypt_keyid(encr_data.decrypt.keyid, &encr_data.decrypt.keyidlen,
2051 		    (uchar_t *)data, cnt, TELNET_DIR_DECRYPT);
2052 }
2053 
2054 /*
2055  * encrypt_dec_keyid
2056  *
2057  * We received the DEC_KEYID message from a client indicating that
2058  * the client wants to verify that the indicated keyid maps to a valid key.
2059  */
2060 static void
encrypt_dec_keyid(char * data,int cnt)2061 encrypt_dec_keyid(char *data, int cnt)
2062 {
2063 	encrypt_keyid(encr_data.encrypt.keyid, &encr_data.encrypt.keyidlen,
2064 		    (uchar_t *)data, cnt, TELNET_DIR_ENCRYPT);
2065 }
2066 
2067 /*
2068  * encrypt_session_key
2069  *
2070  * Store the session key in the encryption data record
2071  */
2072 static void
encrypt_session_key(Session_Key * key,cipher_info_t * cinfo)2073 encrypt_session_key(Session_Key *key, cipher_info_t *cinfo)
2074 {
2075 	if (key == NULL || key->type != SK_DES) {
2076 		if (enc_debug)
2077 			(void) fprintf(stderr,
2078 				    "\t(session_key) Cannot set krb5 "
2079 				    "session key (unknown type = %d)\n",
2080 				    key ? key->type : -1);
2081 	}
2082 	if (enc_debug)
2083 		(void) fprintf(stderr,
2084 			    "\t(session_key) Settting session key "
2085 			    "for server\n");
2086 
2087 	/* store the key in the cipher info data struct */
2088 	(void) memcpy(cinfo->krbdes_key, (void *)key->data, sizeof (Block));
2089 
2090 	/*
2091 	 * Now look to see if we still need to send the key and start
2092 	 * encrypting.
2093 	 *
2094 	 * If so, go ahead an call it now that we have the key.
2095 	 */
2096 	if (cinfo->need_start) {
2097 		if (encrypt_send_encrypt_is() == ENCR_STATE_OK) {
2098 			cinfo->need_start = 0;
2099 		}
2100 	}
2101 }
2102 
2103 /*
2104  * new_env
2105  *
2106  * Used to add an environment variable and value to the
2107  * linked list structure.
2108  */
2109 static int
new_env(const char * name,const char * value)2110 new_env(const char *name, const char *value)
2111 {
2112 	struct envlist *env;
2113 
2114 	env = malloc(sizeof (struct envlist));
2115 	if (env == NULL)
2116 		return (1);
2117 	if ((env->name = strdup(name)) == NULL) {
2118 		free(env);
2119 		return (1);
2120 	}
2121 	if ((env->value = strdup(value)) == NULL) {
2122 		free(env->name);
2123 		free(env);
2124 		return (1);
2125 	}
2126 	env->delete = 0;
2127 	env->next = envlist_head;
2128 	envlist_head = env;
2129 	return (0);
2130 }
2131 
2132 /*
2133  * del_env
2134  *
2135  * Used to delete an environment variable from the linked list
2136  * structure.  We just set a flag because we will delete the list
2137  * anyway before we exec login.
2138  */
2139 static int
del_env(const char * name)2140 del_env(const char *name)
2141 {
2142 	struct envlist *env;
2143 
2144 	for (env = envlist_head; env; env = env->next) {
2145 		if (strcmp(env->name, name) == 0) {
2146 			env->delete = 1;
2147 			break;
2148 		}
2149 	}
2150 	return (0);
2151 }
2152 
2153 static int
issock(int fd)2154 issock(int fd)
2155 {
2156 	struct stat stats;
2157 
2158 	if (fstat(fd, &stats) == -1)
2159 		return (0);
2160 	return (S_ISSOCK(stats.st_mode));
2161 }
2162 
2163 /*
2164  * audit_telnet_settid stores the terminal id while it is still
2165  * available.  Subsequent calls to adt_load_hostname() return
2166  * the id which is stored here.
2167  */
2168 static int
audit_telnet_settid(int sock)2169 audit_telnet_settid(int sock) {
2170 	adt_session_data_t	*ah;
2171 	adt_termid_t		*termid;
2172 	int			rc;
2173 
2174 	if ((rc = adt_start_session(&ah, NULL, 0)) == 0) {
2175 		if ((rc = adt_load_termid(sock, &termid)) == 0) {
2176 			if ((rc = adt_set_user(ah, ADT_NO_AUDIT,
2177 			    ADT_NO_AUDIT, 0, ADT_NO_AUDIT,
2178 			    termid, ADT_SETTID)) == 0)
2179 				(void) adt_set_proc(ah);
2180 			free(termid);
2181 		}
2182 		(void) adt_end_session(ah);
2183 	}
2184 	return (rc);
2185 }
2186 
2187 /* ARGSUSED */
2188 int
main(int argc,char * argv[])2189 main(int argc, char *argv[])
2190 {
2191 	struct sockaddr_storage from;
2192 	int on = 1;
2193 	socklen_t fromlen;
2194 	int issocket;
2195 #if	defined(DEBUG)
2196 	ushort_t porttouse = 0;
2197 	boolean_t standalone = 0;
2198 #endif /* defined(DEBUG) */
2199 	extern char *optarg;
2200 	char c;
2201 	int tos = -1;
2202 
2203 	while ((c = getopt(argc, argv, TELNETD_OPTS DEBUG_OPTS)) != -1) {
2204 		switch (c) {
2205 #if defined(DEBUG)
2206 		case 'p':
2207 			/*
2208 			 * note: alternative port number only used in
2209 			 * standalone mode.
2210 			 */
2211 			porttouse = atoi(optarg);
2212 			standalone = 1;
2213 			break;
2214 		case 'e':
2215 			enc_debug = 1;
2216 			break;
2217 #endif /* DEBUG */
2218 		case 'a':
2219 			if (strcasecmp(optarg, "none") == 0) {
2220 				auth_level = 0;
2221 			} else if (strcasecmp(optarg, "user") == 0) {
2222 				auth_level = AUTH_USER;
2223 			} else if (strcasecmp(optarg, "valid") == 0) {
2224 				auth_level = AUTH_VALID;
2225 			} else if (strcasecmp(optarg, "off") == 0) {
2226 				auth_level = -1;
2227 				negotiate_auth_krb5 = 0;
2228 			} else if (strcasecmp(optarg, "debug") == 0) {
2229 				auth_debug = 1;
2230 			} else {
2231 				syslog(LOG_ERR,
2232 				    "unknown authentication level specified "
2233 				    "with \'-a\' option (%s)", optarg);
2234 				auth_level = AUTH_USER;
2235 			}
2236 			break;
2237 		case 'X':
2238 			/* disable authentication negotiation */
2239 			negotiate_auth_krb5 = 0;
2240 			break;
2241 		case 'R':
2242 		case 'M':
2243 			if (optarg != NULL) {
2244 				int ret = krb5_init();
2245 				if (ret) {
2246 					syslog(LOG_ERR,
2247 						"Unable to use Kerberos V5 as "
2248 						"requested, exiting");
2249 					exit(1);
2250 				}
2251 				(void) krb5_set_default_realm(telnet_context,
2252 				    optarg);
2253 				syslog(LOG_NOTICE,
2254 				    "using %s as default KRB5 realm", optarg);
2255 			}
2256 			break;
2257 		case 'S':
2258 			telnet_srvtab = (char *)strdup(optarg);
2259 			break;
2260 		case 'E': /* disable automatic encryption */
2261 			negotiate_encrypt = B_FALSE;
2262 			break;
2263 		case 'U':
2264 			resolve_hostname = 1;
2265 			break;
2266 		case 's':
2267 			if (optarg == NULL || (tos = atoi(optarg)) < 0 ||
2268 			    tos > 255) {
2269 				syslog(LOG_ERR, "telnetd: illegal tos value: "
2270 				    "%s\n", optarg);
2271 			} else {
2272 				if (tos < 0)
2273 					tos = 020;
2274 			}
2275 			break;
2276 		case 'h':
2277 			show_hostinfo = 0;
2278 			break;
2279 		default:
2280 			syslog(LOG_ERR, "telnetd: illegal cmd line option %c",
2281 			    c);
2282 			break;
2283 		}
2284 	}
2285 
2286 	netibufsize = BUFSIZ;
2287 	if (!(netibuf = (char *)malloc(netibufsize)))
2288 		syslog(LOG_ERR, "netibuf malloc failed\n");
2289 	(void) memset(netibuf, 0, netibufsize);
2290 	netip = netibuf;
2291 
2292 #if	defined(DEBUG)
2293 	if (standalone) {
2294 		int s, ns, foo;
2295 		struct servent *sp;
2296 		static struct sockaddr_in6 sin6 = { AF_INET6 };
2297 		int option = 1;
2298 
2299 		if (porttouse) {
2300 			sin6.sin6_port = htons(porttouse);
2301 		} else {
2302 			sp = getservbyname("telnet", "tcp");
2303 			if (sp == 0) {
2304 				(void) fprintf(stderr,
2305 					    "telnetd: tcp/telnet: "
2306 					    "unknown service\n");
2307 				exit(EXIT_FAILURE);
2308 			}
2309 			sin6.sin6_port = sp->s_port;
2310 		}
2311 
2312 		s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
2313 		if (s < 0) {
2314 			perror("telnetd: socket");
2315 			exit(EXIT_FAILURE);
2316 		}
2317 		if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&option,
2318 		    sizeof (option)) == -1)
2319 			perror("setsockopt SO_REUSEADDR");
2320 		if (bind(s, (struct sockaddr *)&sin6, sizeof (sin6)) < 0) {
2321 			perror("bind");
2322 			exit(EXIT_FAILURE);
2323 		}
2324 		if (listen(s, 32) < 0) {
2325 			perror("listen");
2326 			exit(EXIT_FAILURE);
2327 		}
2328 
2329 		/* automatically reap all child processes */
2330 		(void) signal(SIGCHLD, SIG_IGN);
2331 
2332 		for (;;) {
2333 			pid_t pid;
2334 
2335 			foo = sizeof (sin6);
2336 			ns = accept(s, (struct sockaddr *)&sin6, &foo);
2337 			if (ns < 0) {
2338 				perror("accept");
2339 				exit(EXIT_FAILURE);
2340 			}
2341 			pid = fork();
2342 			if (pid == -1) {
2343 				perror("fork");
2344 				exit(EXIT_FAILURE);
2345 			}
2346 			if (pid == 0) {
2347 				(void) dup2(ns, 0);
2348 				(void) close(s);
2349 				(void) signal(SIGCHLD, SIG_DFL);
2350 				break;
2351 			}
2352 			(void) close(ns);
2353 		}
2354 	}
2355 #endif /* defined(DEBUG) */
2356 
2357 	openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
2358 
2359 	issocket = issock(0);
2360 	if (!issocket)
2361 		fatal(0, "stdin is not a socket file descriptor");
2362 
2363 	fromlen = (socklen_t)sizeof (from);
2364 	(void) memset((char *)&from, 0, sizeof (from));
2365 	if (getpeername(0, (struct sockaddr *)&from, &fromlen)
2366 	    < 0) {
2367 		(void) fprintf(stderr, "%s: ", argv[0]);
2368 		perror("getpeername");
2369 		_exit(EXIT_FAILURE);
2370 	}
2371 
2372 	if (audit_telnet_settid(0)) {	/* set terminal ID */
2373 		(void) fprintf(stderr, "%s: ", argv[0]);
2374 		perror("audit");
2375 		exit(EXIT_FAILURE);
2376 	}
2377 
2378 	if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (const char *)&on,
2379 						sizeof (on)) < 0) {
2380 		syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
2381 	}
2382 
2383 	/*
2384 	 * Set the TOS value
2385 	 */
2386 	if (tos != -1 &&
2387 	    setsockopt(0, IPPROTO_IP, IP_TOS,
2388 		    (char *)&tos, sizeof (tos)) < 0 &&
2389 		errno != ENOPROTOOPT) {
2390 		syslog(LOG_ERR, "setsockopt (IP_TOS %d): %m", tos);
2391 	}
2392 
2393 	if (setsockopt(net, SOL_SOCKET, SO_OOBINLINE, (char *)&on,
2394 	    sizeof (on)) < 0) {
2395 		syslog(LOG_WARNING, "setsockopt (SO_OOBINLINE): %m");
2396 	}
2397 
2398 	/* set the default PAM service name */
2399 	(void) strcpy(pam_svc_name, "telnet");
2400 
2401 	doit(0, &from);
2402 	return (EXIT_SUCCESS);
2403 }
2404 
2405 static char	*terminaltype = 0;
2406 
2407 /*
2408  * ttloop
2409  *
2410  *	A small subroutine to flush the network output buffer, get some data
2411  * from the network, and pass it through the telnet state machine.  We
2412  * also flush the pty input buffer (by dropping its data) if it becomes
2413  * too full.
2414  */
2415 static void
ttloop(void)2416 ttloop(void)
2417 {
2418 	if (nfrontp-nbackp) {
2419 		netflush();
2420 	}
2421 read_again:
2422 	ncc = read(net, netibuf, netibufsize);
2423 	if (ncc < 0) {
2424 		if (errno == EINTR)
2425 			goto read_again;
2426 		syslog(LOG_INFO, "ttloop:  read: %m");
2427 		exit(EXIT_FAILURE);
2428 	} else if (ncc == 0) {
2429 		syslog(LOG_INFO, "ttloop:  peer closed connection\n");
2430 		exit(EXIT_FAILURE);
2431 	}
2432 
2433 	netip = netibuf;
2434 	telrcv();		/* state machine */
2435 	if (ncc > 0) {
2436 		pfrontp = pbackp = ptyobuf;
2437 		telrcv();
2438 	}
2439 }
2440 
2441 static void
send_do(int option)2442 send_do(int option)
2443 {
2444 	write_data("%c%c%c", (uchar_t)IAC, (uchar_t)DO, (uchar_t)option);
2445 }
2446 
2447 static void
send_will(int option)2448 send_will(int option)
2449 {
2450 	write_data("%c%c%c", (uchar_t)IAC, (uchar_t)WILL, (uchar_t)option);
2451 }
2452 
2453 static void
send_wont(int option)2454 send_wont(int option)
2455 {
2456 	write_data("%c%c%c", (uchar_t)IAC, (uchar_t)WONT, (uchar_t)option);
2457 }
2458 
2459 
2460 /*
2461  * getauthtype
2462  *
2463  * Negotiate automatic authentication, is possible.
2464  */
2465 static int
getauthtype(char * username,int * len)2466 getauthtype(char *username, int *len)
2467 {
2468 	int init_status = -1;
2469 
2470 	init_status = krb5_init();
2471 
2472 	if (auth_level == -1 || init_status != 0) {
2473 		remopts[TELOPT_AUTHENTICATION] = OPT_NO;
2474 		myopts[TELOPT_AUTHENTICATION] = OPT_NO;
2475 		negotiate_auth_krb5 = B_FALSE;
2476 		negotiate_encrypt = B_FALSE;
2477 		return (AUTH_REJECT);
2478 	}
2479 
2480 	if (init_status == 0 && auth_level != -1) {
2481 		if (negotiate_auth_krb5) {
2482 			/*
2483 			 * Negotiate Authentication FIRST
2484 			 */
2485 			send_do(TELOPT_AUTHENTICATION);
2486 			remopts[TELOPT_AUTHENTICATION] =
2487 				OPT_YES_BUT_ALWAYS_LOOK;
2488 		}
2489 		while (sequenceIs(authopt, getauth))
2490 			ttloop();
2491 
2492 		if (remopts[TELOPT_AUTHENTICATION] == OPT_YES) {
2493 			/*
2494 			 * Request KRB5 Mutual authentication and if that fails,
2495 			 * KRB5 1-way client authentication
2496 			 */
2497 			uchar_t sbbuf[MAXOPTLEN], *p;
2498 			p = sbbuf;
2499 			*p++ = (uchar_t)IAC;
2500 			*p++ = (uchar_t)SB;
2501 			*p++ = (uchar_t)TELOPT_AUTHENTICATION;
2502 			*p++ = (uchar_t)TELQUAL_SEND;
2503 			if (negotiate_auth_krb5) {
2504 				*p++ = (uchar_t)AUTHTYPE_KERBEROS_V5;
2505 				*p++ = (uchar_t)(AUTH_WHO_CLIENT |
2506 						AUTH_HOW_MUTUAL |
2507 						AUTH_ENCRYPT_ON);
2508 				*p++ = (uchar_t)AUTHTYPE_KERBEROS_V5;
2509 				*p++ = (uchar_t)(AUTH_WHO_CLIENT |
2510 						AUTH_HOW_MUTUAL);
2511 				*p++ = (uchar_t)AUTHTYPE_KERBEROS_V5;
2512 				*p++ = (uchar_t)(AUTH_WHO_CLIENT|
2513 						AUTH_HOW_ONE_WAY);
2514 			} else {
2515 				*p++ = (uchar_t)AUTHTYPE_NULL;
2516 			}
2517 			*p++ = (uchar_t)IAC;
2518 			*p++ = (uchar_t)SE;
2519 
2520 			write_data_len((const char *)sbbuf,
2521 				    (size_t)(p - sbbuf));
2522 			netflush();
2523 			if (auth_debug)
2524 				(void) fprintf(stderr,
2525 					    "SENT TELOPT_AUTHENTICATION "
2526 					    "[data]\n");
2527 
2528 			/* auth_wait returns the authentication level */
2529 			/* status = auth_wait(username, len); */
2530 			while (sequenceIs(authdone, getauth))
2531 				ttloop();
2532 			/*
2533 			 * Now check to see if the user is valid or not
2534 			 */
2535 			if (authenticated == NULL || authenticated == &NoAuth)
2536 				auth_status = AUTH_REJECT;
2537 			else {
2538 				/*
2539 				 * We cant be VALID until the user status is
2540 				 * checked.
2541 				 */
2542 				if (auth_status == AUTH_VALID)
2543 					auth_status = AUTH_USER;
2544 
2545 				if (authenticated->AuthName ==
2546 					AUTHTYPE_KERBEROS_V5)
2547 					auth_status = krb5_user_status(
2548 						username, *len, auth_status);
2549 			}
2550 		}
2551 	}
2552 	return (auth_status);
2553 }
2554 
2555 static void
getencrtype(void)2556 getencrtype(void)
2557 {
2558 	if (krb5_privacy_allowed() && negotiate_encrypt) {
2559 		if (myopts[TELOPT_ENCRYPT] != OPT_YES) {
2560 			if (!sent_will_encrypt) {
2561 				send_will(TELOPT_ENCRYPT);
2562 				sent_will_encrypt = B_TRUE;
2563 			}
2564 			if (enc_debug)
2565 				(void) fprintf(stderr, "SENT WILL ENCRYPT\n");
2566 		}
2567 		if (remopts[TELOPT_ENCRYPT] != OPT_YES) {
2568 			if (!sent_do_encrypt) {
2569 				send_do(TELOPT_ENCRYPT);
2570 				sent_do_encrypt = B_TRUE;
2571 				remopts[TELOPT_ENCRYPT] =
2572 				    OPT_YES_BUT_ALWAYS_LOOK;
2573 			}
2574 			if (enc_debug)
2575 				(void) fprintf(stderr, "SENT DO ENCRYPT\n");
2576 		}
2577 		myopts[TELOPT_ENCRYPT] = OPT_YES;
2578 
2579 		while (sequenceIs(encropt, getencr))
2580 		    ttloop();
2581 
2582 		if (auth_status != AUTH_REJECT &&
2583 		    remopts[TELOPT_ENCRYPT] == OPT_YES &&
2584 		    myopts[TELOPT_ENCRYPT] == OPT_YES) {
2585 
2586 			if (sent_encrypt_support == B_FALSE) {
2587 				write_data("%c%c%c%c%c%c%c",
2588 					(uchar_t)IAC,
2589 					(uchar_t)SB,
2590 					(uchar_t)TELOPT_ENCRYPT,
2591 					(uchar_t)ENCRYPT_SUPPORT,
2592 					(uchar_t)TELOPT_ENCTYPE_DES_CFB64,
2593 					(uchar_t)IAC,
2594 					(uchar_t)SE);
2595 
2596 				netflush();
2597 			}
2598 			/*
2599 			 * Now wait for a response to these messages before
2600 			 * continuing...
2601 			 * Look for TELOPT_ENCRYPT suboptions
2602 			 */
2603 			while (sequenceIs(encr_support, getencr))
2604 				ttloop();
2605 		}
2606 	} else {
2607 		/* Dont need responses to these, so dont wait for them */
2608 		settimer(encropt);
2609 		remopts[TELOPT_ENCRYPT] = OPT_NO;
2610 		myopts[TELOPT_ENCRYPT] = OPT_NO;
2611 	}
2612 
2613 }
2614 
2615 /*
2616  * getterminaltype
2617  *
2618  * Ask the other end to send along its terminal type.
2619  * Output is the variable terminaltype filled in.
2620  */
2621 static void
getterminaltype(void)2622 getterminaltype(void)
2623 {
2624 	/*
2625 	 * The remote side may have already sent this info, so
2626 	 * dont ask for these options if the other side already
2627 	 * sent the information.
2628 	 */
2629 	if (sequenceIs(ttypeopt, getterminal)) {
2630 		send_do(TELOPT_TTYPE);
2631 		remopts[TELOPT_TTYPE] = OPT_YES_BUT_ALWAYS_LOOK;
2632 	}
2633 
2634 	if (sequenceIs(nawsopt, getterminal)) {
2635 		send_do(TELOPT_NAWS);
2636 		remopts[TELOPT_NAWS] = OPT_YES_BUT_ALWAYS_LOOK;
2637 	}
2638 
2639 	if (sequenceIs(xdisplocopt, getterminal)) {
2640 		send_do(TELOPT_XDISPLOC);
2641 		remopts[TELOPT_XDISPLOC] = OPT_YES_BUT_ALWAYS_LOOK;
2642 	}
2643 
2644 	if (sequenceIs(environopt, getterminal)) {
2645 		send_do(TELOPT_NEW_ENVIRON);
2646 		remopts[TELOPT_NEW_ENVIRON] = OPT_YES_BUT_ALWAYS_LOOK;
2647 	}
2648 
2649 	if (sequenceIs(oenvironopt, getterminal)) {
2650 		send_do(TELOPT_OLD_ENVIRON);
2651 		remopts[TELOPT_OLD_ENVIRON] = OPT_YES_BUT_ALWAYS_LOOK;
2652 	}
2653 
2654 	/* make sure encryption is started here */
2655 	while (auth_status != AUTH_REJECT &&
2656 		authenticated != &NoAuth && authenticated != NULL &&
2657 		remopts[TELOPT_ENCRYPT] == OPT_YES &&
2658 		encr_data.encrypt.autoflag &&
2659 		encr_data.encrypt.state != ENCR_STATE_OK) {
2660 	    if (enc_debug)
2661 		(void) fprintf(stderr, "getterminaltype() forcing encrypt\n");
2662 	    ttloop();
2663 	}
2664 
2665 	if (enc_debug) {
2666 	    (void) fprintf(stderr, "getterminaltype() encryption %sstarted\n",
2667 		    encr_data.encrypt.state == ENCR_STATE_OK ? "" : "not ");
2668 	}
2669 
2670 	while (sequenceIs(ttypeopt, getterminal) ||
2671 	    sequenceIs(nawsopt, getterminal) ||
2672 	    sequenceIs(xdisplocopt, getterminal) ||
2673 	    sequenceIs(environopt, getterminal) ||
2674 	    sequenceIs(oenvironopt, getterminal)) {
2675 		ttloop();
2676 	}
2677 
2678 
2679 	if (remopts[TELOPT_TTYPE] == OPT_YES) {
2680 		static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB,
2681 		    (uchar_t)TELOPT_TTYPE, (uchar_t)TELQUAL_SEND,
2682 		    (uchar_t)IAC, (uchar_t)SE };
2683 
2684 		write_data_len((const char *)sbbuf, sizeof (sbbuf));
2685 	}
2686 	if (remopts[TELOPT_XDISPLOC] == OPT_YES) {
2687 		static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB,
2688 		    (uchar_t)TELOPT_XDISPLOC, (uchar_t)TELQUAL_SEND,
2689 		    (uchar_t)IAC, (uchar_t)SE };
2690 
2691 		write_data_len((const char *)sbbuf, sizeof (sbbuf));
2692 	}
2693 	if (remopts[TELOPT_NEW_ENVIRON] == OPT_YES) {
2694 		static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB,
2695 		    (uchar_t)TELOPT_NEW_ENVIRON, (uchar_t)TELQUAL_SEND,
2696 		    (uchar_t)IAC, (uchar_t)SE };
2697 
2698 		write_data_len((const char *)sbbuf, sizeof (sbbuf));
2699 	}
2700 	if (remopts[TELOPT_OLD_ENVIRON] == OPT_YES) {
2701 		static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB,
2702 		    (uchar_t)TELOPT_OLD_ENVIRON, (uchar_t)TELQUAL_SEND,
2703 		    (uchar_t)IAC, (uchar_t)SE };
2704 
2705 		write_data_len((const char *)sbbuf, sizeof (sbbuf));
2706 	}
2707 
2708 	if (remopts[TELOPT_TTYPE] == OPT_YES) {
2709 		while (sequenceIs(ttypesubopt, getterminal)) {
2710 			ttloop();
2711 		}
2712 	}
2713 	if (remopts[TELOPT_XDISPLOC] == OPT_YES) {
2714 		while (sequenceIs(xdisplocsubopt, getterminal)) {
2715 			ttloop();
2716 		}
2717 	}
2718 	if (remopts[TELOPT_NEW_ENVIRON] == OPT_YES) {
2719 		while (sequenceIs(environsubopt, getterminal)) {
2720 			ttloop();
2721 		}
2722 	}
2723 	if (remopts[TELOPT_OLD_ENVIRON] == OPT_YES) {
2724 		while (sequenceIs(oenvironsubopt, getterminal)) {
2725 			ttloop();
2726 		}
2727 	}
2728 	init_neg_done = 1;
2729 }
2730 
2731 pid_t pid;
2732 
2733 /*
2734  * Get a pty, scan input lines.
2735  */
2736 static void
doit(int f,struct sockaddr_storage * who)2737 doit(int f, struct sockaddr_storage *who)
2738 {
2739 	char *host;
2740 	char host_name[MAXHOSTNAMELEN];
2741 	int p, t, tt;
2742 	struct sgttyb b;
2743 	int	ptmfd;	/* fd of logindmux connected to pty */
2744 	int	netfd;	/* fd of logindmux connected to netf */
2745 	struct	stat	buf;
2746 	struct	protocol_arg	telnetp;
2747 	struct	strioctl	telnetmod;
2748 	struct	envlist	*env, *next;
2749 	int	nsize = 0;
2750 	char abuf[INET6_ADDRSTRLEN];
2751 	struct sockaddr_in *sin;
2752 	struct sockaddr_in6 *sin6;
2753 	socklen_t wholen;
2754 	char username[MAXUSERNAMELEN];
2755 	int len;
2756 	uchar_t passthru;
2757 	char *slavename;
2758 
2759 	if ((p = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) {
2760 		fatalperror(f, "open /dev/ptmx", errno);
2761 	}
2762 	if (grantpt(p) == -1)
2763 		fatal(f, "could not grant slave pty");
2764 	if (unlockpt(p) == -1)
2765 		fatal(f, "could not unlock slave pty");
2766 	if ((slavename = ptsname(p)) == NULL)
2767 		fatal(f, "could not enable slave pty");
2768 	(void) dup2(f, 0);
2769 	if ((t = open(slavename, O_RDWR | O_NOCTTY)) == -1)
2770 		fatal(f, "could not open slave pty");
2771 	if (ioctl(t, I_PUSH, "ptem") == -1)
2772 		fatalperror(f, "ioctl I_PUSH ptem", errno);
2773 	if (ioctl(t, I_PUSH, "ldterm") == -1)
2774 		fatalperror(f, "ioctl I_PUSH ldterm", errno);
2775 	if (ioctl(t, I_PUSH, "ttcompat") == -1)
2776 		fatalperror(f, "ioctl I_PUSH ttcompat", errno);
2777 
2778 	line = slavename;
2779 
2780 	pty = t;
2781 
2782 	if (ioctl(t, TIOCGETP, &b) == -1)
2783 		syslog(LOG_INFO, "ioctl TIOCGETP pty t: %m\n");
2784 	b.sg_flags = O_CRMOD|O_XTABS|O_ANYP;
2785 	/* XXX - ispeed and ospeed must be non-zero */
2786 	b.sg_ispeed = B38400;
2787 	b.sg_ospeed = B38400;
2788 	if (ioctl(t, TIOCSETN, &b) == -1)
2789 		syslog(LOG_INFO, "ioctl TIOCSETN pty t: %m\n");
2790 	if (ioctl(pty, TIOCGETP, &b) == -1)
2791 		syslog(LOG_INFO, "ioctl TIOCGETP pty pty: %m\n");
2792 	b.sg_flags &= ~O_ECHO;
2793 	if (ioctl(pty, TIOCSETN, &b) == -1)
2794 		syslog(LOG_INFO, "ioctl TIOCSETN pty pty: %m\n");
2795 
2796 	if (who->ss_family == AF_INET) {
2797 		char *addrbuf = NULL;
2798 		char *portbuf = NULL;
2799 
2800 		sin = (struct sockaddr_in *)who;
2801 		wholen = sizeof (struct sockaddr_in);
2802 
2803 		addrbuf = (char *)malloc(wholen);
2804 		if (addrbuf == NULL)
2805 			fatal(f, "Cannot alloc memory for address info\n");
2806 		portbuf = (char *)malloc(sizeof (sin->sin_port));
2807 		if (portbuf == NULL) {
2808 			free(addrbuf);
2809 			fatal(f, "Cannot alloc memory for port info\n");
2810 		}
2811 
2812 		(void) memcpy(addrbuf, (const void *)&sin->sin_addr, wholen);
2813 		(void) memcpy(portbuf, (const void *)&sin->sin_port,
2814 			    sizeof (sin->sin_port));
2815 
2816 		if (rsaddr.contents != NULL)
2817 			free(rsaddr.contents);
2818 
2819 		rsaddr.contents = (krb5_octet *)addrbuf;
2820 		rsaddr.length = wholen;
2821 		rsaddr.addrtype = ADDRTYPE_INET;
2822 
2823 		if (rsport.contents != NULL)
2824 			free(rsport.contents);
2825 
2826 		rsport.contents = (krb5_octet *)portbuf;
2827 		rsport.length = sizeof (sin->sin_port);
2828 		rsport.addrtype = ADDRTYPE_IPPORT;
2829 	} else if (who->ss_family == AF_INET6) {
2830 		struct in_addr ipv4_addr;
2831 		char *addrbuf = NULL;
2832 		char *portbuf = NULL;
2833 
2834 		sin6 = (struct sockaddr_in6 *)who;
2835 		wholen = sizeof (struct sockaddr_in6);
2836 
2837 		IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr,
2838 				    &ipv4_addr);
2839 
2840 		addrbuf = (char *)malloc(wholen);
2841 		if (addrbuf == NULL)
2842 			fatal(f, "Cannot alloc memory for address info\n");
2843 
2844 		portbuf = (char *)malloc(sizeof (sin6->sin6_port));
2845 		if (portbuf == NULL) {
2846 			free(addrbuf);
2847 			fatal(f, "Cannot alloc memory for port info\n");
2848 		}
2849 
2850 		(void) memcpy((void *) addrbuf,
2851 			    (const void *)&ipv4_addr,
2852 			    wholen);
2853 		/*
2854 		 * If we already used rsaddr.contents, free the previous
2855 		 * buffer.
2856 		 */
2857 		if (rsaddr.contents != NULL)
2858 			free(rsaddr.contents);
2859 
2860 		rsaddr.contents = (krb5_octet *)addrbuf;
2861 		rsaddr.length = sizeof (ipv4_addr);
2862 		rsaddr.addrtype = ADDRTYPE_INET;
2863 
2864 		(void) memcpy((void *) portbuf, (const void *)&sin6->sin6_port,
2865 			    sizeof (sin6->sin6_port));
2866 
2867 		if (rsport.contents != NULL)
2868 			free(rsport.contents);
2869 
2870 		rsport.contents = (krb5_octet *)portbuf;
2871 		rsport.length = sizeof (sin6->sin6_port);
2872 		rsport.addrtype = ADDRTYPE_IPPORT;
2873 	} else {
2874 		syslog(LOG_ERR, "unknown address family %d\n",
2875 		    who->ss_family);
2876 		fatal(f, "getpeername: unknown address family\n");
2877 	}
2878 
2879 	if (getnameinfo((const struct sockaddr *) who, wholen, host_name,
2880 	    sizeof (host_name), NULL, 0, 0) == 0) {
2881 		host = host_name;
2882 	} else {
2883 		/*
2884 		 * If the '-U' option was given on the cmd line, we must
2885 		 * be able to lookup the hostname
2886 		 */
2887 		if (resolve_hostname) {
2888 			fatal(f, "Couldn't resolve your address into a "
2889 			    "host name.\r\nPlease contact your net "
2890 			    "administrator");
2891 		}
2892 
2893 		if (who->ss_family == AF_INET6) {
2894 			if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
2895 				struct in_addr ipv4_addr;
2896 
2897 				IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr,
2898 				    &ipv4_addr);
2899 				host = (char *)inet_ntop(AF_INET,
2900 				    &ipv4_addr, abuf, sizeof (abuf));
2901 			} else {
2902 				host = (char *)inet_ntop(AF_INET6,
2903 				    &sin6->sin6_addr, abuf,
2904 				    sizeof (abuf));
2905 			}
2906 		} else if (who->ss_family == AF_INET) {
2907 				host = (char *)inet_ntop(AF_INET,
2908 				    &sin->sin_addr, abuf, sizeof (abuf));
2909 			}
2910 	}
2911 	/*
2912 	 * Note that sockmod has to be removed since readstream assumes
2913 	 * a "raw" TPI endpoint (e.g. it uses getmsg).
2914 	 */
2915 	if (removemod(f, "sockmod") < 0)
2916 		fatalperror(f, "couldn't remove sockmod", errno);
2917 
2918 	encrypt_init();
2919 
2920 	/*
2921 	 * Push the crypto module on the stream before 'telmod' so it
2922 	 * can encrypt/decrypt without interfering with telmod functionality
2923 	 * We must push it now because many of the crypto options negotiated
2924 	 * initially must be saved in the crypto module (via IOCTL calls).
2925 	 */
2926 	if (ioctl(f, I_PUSH, "cryptmod") < 0)
2927 		fatalperror(f, "ioctl I_PUSH cryptmod", errno);
2928 
2929 	cryptmod_fd = f;
2930 	/*
2931 	 * gotta set the encryption clock now because it is often negotiated
2932 	 * immediately by the client, and if we wait till after we negotiate
2933 	 * auth, it will be out of whack with when the WILL/WONT ENCRYPT
2934 	 * option is received.
2935 	 */
2936 	settimer(getencr);
2937 
2938 	/*
2939 	 * get terminal type.
2940 	 */
2941 	username[0] = '\0';
2942 	len = sizeof (username);
2943 
2944 	settimer(getterminal);
2945 	settimer(getauth);
2946 	/*
2947 	 * Exchange TELOPT_AUTHENTICATE options per RFC 2941/2942
2948 	 */
2949 	auth_status = getauthtype(username, &len);
2950 	/*
2951 	 * Exchange TELOPT_ENCRYPT options per RFC 2946
2952 	 */
2953 	getencrtype();
2954 	getterminaltype();
2955 
2956 	if (ioctl(f, I_PUSH, "telmod") < 0)
2957 		fatalperror(f, "ioctl I_PUSH telmod", errno);
2958 
2959 	/*
2960 	 * Make sure telmod will pass unrecognized IOCTLs to cryptmod
2961 	 */
2962 	passthru = 1;
2963 
2964 	telnetmod.ic_cmd = CRYPTPASSTHRU;
2965 	telnetmod.ic_timout = -1;
2966 	telnetmod.ic_len = sizeof (uchar_t);
2967 	telnetmod.ic_dp = (char *)&passthru;
2968 
2969 	if (ioctl(f, I_STR, &telnetmod) < 0)
2970 		fatal(f, "ioctl CRPASSTHRU failed\n");
2971 
2972 	if (!ncc)
2973 		netip = netibuf;
2974 
2975 	/*
2976 	 * readstream will do a getmsg till it receives M_PROTO type
2977 	 * T_DATA_REQ from telnetmodopen().  This signals that all data
2978 	 * in-flight before telmod was pushed has been received at the
2979 	 * stream head.
2980 	 */
2981 	while ((nsize = readstream(f, netibuf, ncc + netip - netibuf)) > 0) {
2982 		ncc += nsize;
2983 	}
2984 
2985 	if (nsize < 0) {
2986 		fatalperror(f, "readstream failed\n", errno);
2987 	}
2988 
2989 	/*
2990 	 * open logindmux drivers and link them with network and ptm
2991 	 * file descriptors.
2992 	 */
2993 	if ((ptmfd = open("/dev/logindmux", O_RDWR)) == -1) {
2994 		fatalperror(f, "open /dev/logindmux", errno);
2995 	}
2996 	if ((netfd = open("/dev/logindmux", O_RDWR)) == -1) {
2997 		fatalperror(f, "open /dev/logindmux", errno);
2998 	}
2999 
3000 	if (ioctl(ptmfd, I_LINK, p) < 0)
3001 		fatal(f, "ioctl I_LINK of /dev/ptmx failed\n");
3002 	if (ioctl(netfd, I_LINK, f) < 0)
3003 		fatal(f, "ioctl I_LINK of tcp connection failed\n");
3004 
3005 	/*
3006 	 * Figure out the device number of ptm's mux fd, and pass that
3007 	 * to the net's mux.
3008 	 */
3009 	if (fstat(ptmfd, &buf) < 0) {
3010 		fatalperror(f, "fstat ptmfd failed", errno);
3011 	}
3012 	telnetp.dev = buf.st_rdev;
3013 	telnetp.flag = 0;
3014 
3015 	telnetmod.ic_cmd = LOGDMX_IOC_QEXCHANGE;
3016 	telnetmod.ic_timout = -1;
3017 	telnetmod.ic_len = sizeof (struct protocol_arg);
3018 	telnetmod.ic_dp = (char *)&telnetp;
3019 
3020 	if (ioctl(netfd, I_STR, &telnetmod) < 0)
3021 		fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of netfd failed\n");
3022 
3023 	/*
3024 	 * Figure out the device number of the net's mux fd, and pass that
3025 	 * to the ptm's mux.
3026 	 */
3027 	if (fstat(netfd, &buf) < 0) {
3028 		fatalperror(f, "fstat netfd failed", errno);
3029 	}
3030 	telnetp.dev = buf.st_rdev;
3031 	telnetp.flag = 1;
3032 
3033 	telnetmod.ic_cmd = LOGDMX_IOC_QEXCHANGE;
3034 	telnetmod.ic_timout = -1;
3035 	telnetmod.ic_len = sizeof (struct protocol_arg);
3036 	telnetmod.ic_dp = (char *)&telnetp;
3037 
3038 	if (ioctl(ptmfd, I_STR, &telnetmod) < 0)
3039 		fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of ptmfd failed\n");
3040 
3041 	net = netfd;
3042 	master = ptmfd;
3043 	cryptmod_fd = netfd;
3044 
3045 	/*
3046 	 * Show banner that getty never gave, but
3047 	 * only if the user did not automatically authenticate.
3048 	 */
3049 	if (getenv("USER") == NULL && auth_status < AUTH_USER)
3050 		showbanner();
3051 
3052 	/*
3053 	 * If the user automatically authenticated with Kerberos
3054 	 * we must set the service name that PAM will use.  We
3055 	 * need to do it BEFORE the child fork so that 'cleanup'
3056 	 * in the parent can call the PAM cleanup stuff with the
3057 	 * same PAM service that /bin/login will use to authenticate
3058 	 * this session.
3059 	 */
3060 	if (auth_level >= 0 && auth_status >= AUTH_USER &&
3061 	    (AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) {
3062 		(void) strcpy(pam_svc_name, "ktelnet");
3063 	}
3064 	/*
3065 	 * Request to do suppress go ahead.
3066 	 *
3067 	 * Send this before sending the TELOPT_ECHO stuff below because
3068 	 * some clients (MIT KRB5 telnet) have quirky 'kludge mode' support
3069 	 * that has them turn off local echo mode if SGA is not received first.
3070 	 * This also has the odd side-effect of causing the client to enable
3071 	 * encryption and then immediately disable it during the ECHO option
3072 	 * negotiations.  Its just better to to SGA first now that we support
3073 	 * encryption.
3074 	 */
3075 	if (!myopts[TELOPT_SGA]) {
3076 	    dooption(TELOPT_SGA);
3077 	}
3078 
3079 	/*
3080 	 * Pretend we got a DO ECHO from the client if we have not
3081 	 * yet negotiated the ECHO.
3082 	 */
3083 	if (!myopts[TELOPT_ECHO]) {
3084 	    dooption(TELOPT_ECHO);
3085 	}
3086 
3087 	/*
3088 	 * Is the client side a 4.2 (NOT 4.3) system?  We need to know this
3089 	 * because 4.2 clients are unable to deal with TCP urgent data.
3090 	 *
3091 	 * To find out, we send out a "DO ECHO".  If the remote system
3092 	 * answers "WILL ECHO" it is probably a 4.2 client, and we note
3093 	 * that fact ("WILL ECHO" ==> that the client will echo what
3094 	 * WE, the server, sends it; it does NOT mean that the client will
3095 	 * echo the terminal input).
3096 	 */
3097 	send_do(TELOPT_ECHO);
3098 	remopts[TELOPT_ECHO] = OPT_YES_BUT_ALWAYS_LOOK;
3099 
3100 	if ((pid = fork()) < 0)
3101 		fatalperror(netfd, "fork", errno);
3102 	if (pid)
3103 		telnet(net, master);
3104 	/*
3105 	 * The child process needs to be the session leader
3106 	 * and have the pty as its controlling tty.  Thus we need
3107 	 * to re-open the slave side of the pty no without
3108 	 * the O_NOCTTY flag that we have been careful to
3109 	 * use up to this point.
3110 	 */
3111 	(void) setsid();
3112 
3113 	tt = open(line, O_RDWR);
3114 	if (tt < 0)
3115 		fatalperror(netfd, line, errno);
3116 	(void) close(netfd);
3117 	(void) close(ptmfd);
3118 	(void) close(f);
3119 	(void) close(p);
3120 	(void) close(t);
3121 	if (tt != 0)
3122 		(void) dup2(tt, 0);
3123 	if (tt != 1)
3124 		(void) dup2(tt, 1);
3125 	if (tt != 2)
3126 		(void) dup2(tt, 2);
3127 	if (tt > 2)
3128 		(void) close(tt);
3129 
3130 	if (terminaltype)
3131 		(void) local_setenv("TERM", terminaltype+5, 1);
3132 	/*
3133 	 * 	-h : pass on name of host.
3134 	 *		WARNING:  -h is accepted by login if and only if
3135 	 *			getuid() == 0.
3136 	 * 	-p : don't clobber the environment (so terminal type stays set).
3137 	 */
3138 	{
3139 		/* System V login expects a utmp entry to already be there */
3140 		struct utmpx ut;
3141 		(void) memset((char *)&ut, 0, sizeof (ut));
3142 		(void) strncpy(ut.ut_user, ".telnet", sizeof (ut.ut_user));
3143 		(void) strncpy(ut.ut_line, line, sizeof (ut.ut_line));
3144 		ut.ut_pid = getpid();
3145 		ut.ut_id[0] = 't';
3146 		ut.ut_id[1] = (char)SC_WILDC;
3147 		ut.ut_id[2] = (char)SC_WILDC;
3148 		ut.ut_id[3] = (char)SC_WILDC;
3149 		ut.ut_type = LOGIN_PROCESS;
3150 		ut.ut_exit.e_termination = 0;
3151 		ut.ut_exit.e_exit = 0;
3152 		(void) time(&ut.ut_tv.tv_sec);
3153 		if (makeutx(&ut) == NULL)
3154 			syslog(LOG_INFO, "in.telnetd:\tmakeutx failed");
3155 	}
3156 
3157 	/*
3158 	 * Load in the cached environment variables and either
3159 	 * set/unset them in the environment.
3160 	 */
3161 	for (next = envlist_head; next; ) {
3162 		env = next;
3163 		if (env->delete)
3164 			(void) local_unsetenv(env->name);
3165 		else
3166 			(void) local_setenv(env->name, env->value, 1);
3167 		free(env->name);
3168 		free(env->value);
3169 		next = env->next;
3170 		free(env);
3171 	}
3172 
3173 	if (!username || !username[0])
3174 		auth_status = AUTH_REJECT; /* we dont know who this is */
3175 
3176 	/* If the current auth status is less than the required level, exit */
3177 	if (auth_status < auth_level) {
3178 		fatal(net, "Authentication failed\n");
3179 		exit(EXIT_FAILURE);
3180 	}
3181 
3182 	/*
3183 	 * If AUTH_VALID (proper authentication REQUIRED and we have
3184 	 * a krb5_name), exec '/bin/login', make sure it uses the
3185 	 * correct PAM service name (pam_svc_name). If possible,
3186 	 * make sure the krb5 authenticated user's name (krb5_name)
3187 	 * is in the PAM REPOSITORY for krb5.
3188 	 */
3189 	if (auth_level >= 0 &&
3190 	    (auth_status == AUTH_VALID || auth_status == AUTH_USER) &&
3191 	    ((krb5_name != NULL) && strlen(krb5_name)) &&
3192 	    ((AuthenticatingUser != NULL) && strlen(AuthenticatingUser))) {
3193 		(void) execl(LOGIN_PROGRAM, "login",
3194 			    "-p",
3195 			    "-d", slavename,
3196 			    "-h", host,
3197 			    "-u", krb5_name,
3198 			    "-s", pam_svc_name,
3199 			    "-R", KRB5_REPOSITORY_NAME,
3200 			    AuthenticatingUser, 0);
3201 	} else if (auth_level >= 0 &&
3202 		auth_status >= AUTH_USER &&
3203 		(((AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) ||
3204 		getenv("USER"))) {
3205 		/*
3206 		 * If we only know the name but not the principal,
3207 		 * login will have to authenticate further.
3208 		 */
3209 		(void) execl(LOGIN_PROGRAM, "login",
3210 		    "-p",
3211 		    "-d", slavename,
3212 		    "-h", host,
3213 		    "-s", pam_svc_name, "--",
3214 		    (AuthenticatingUser != NULL ? AuthenticatingUser :
3215 			getenv("USER")), 0);
3216 
3217 	} else /* default, no auth. info available, login does it all */ {
3218 		(void) execl(LOGIN_PROGRAM, "login",
3219 		    "-p", "-h", host, "-d", slavename, "--",
3220 		    getenv("USER"), 0);
3221 	}
3222 
3223 	fatalperror(netfd, LOGIN_PROGRAM, errno);
3224 	/*NOTREACHED*/
3225 }
3226 
3227 static void
fatal(int f,char * msg)3228 fatal(int f, char *msg)
3229 {
3230 	char buf[BUFSIZ];
3231 
3232 	(void) snprintf(buf, sizeof (buf), "telnetd: %s.\r\n", msg);
3233 	(void) write(f, buf, strlen(buf));
3234 	exit(EXIT_FAILURE);
3235 	/*NOTREACHED*/
3236 }
3237 
3238 static void
fatalperror(int f,char * msg,int errnum)3239 fatalperror(int f, char *msg, int errnum)
3240 {
3241 	char buf[BUFSIZ];
3242 
3243 	(void) snprintf(buf, sizeof (buf),
3244 			"%s: %s\r\n", msg, strerror(errnum));
3245 	fatal(f, buf);
3246 	/*NOTREACHED*/
3247 }
3248 
3249 /*
3250  * Main loop.  Select from pty and network, and
3251  * hand data to telnet receiver finite state machine
3252  * when it receives telnet protocol. Regular data
3253  * flow between pty and network takes place through
3254  * inkernel telnet streams module (telmod).
3255  */
3256 static void
telnet(int net,int master)3257 telnet(int net, int master)
3258 {
3259 	int on = 1;
3260 	char mode;
3261 	struct	strioctl	telnetmod;
3262 	int	nsize = 0;
3263 	char	binary_in = 0;
3264 	char binary_out = 0;
3265 
3266 	if (ioctl(net, FIONBIO, &on) == -1)
3267 		syslog(LOG_INFO, "ioctl FIONBIO net: %m\n");
3268 	if (ioctl(master, FIONBIO, &on) == -1)
3269 		syslog(LOG_INFO, "ioctl FIONBIO pty p: %m\n");
3270 	(void) signal(SIGTSTP, SIG_IGN);
3271 	(void) signal(SIGCHLD, (void (*)())cleanup);
3272 	(void) setpgrp();
3273 
3274 	/*
3275 	 * Call telrcv() once to pick up anything received during
3276 	 * terminal type negotiation.
3277 	 */
3278 	telrcv();
3279 
3280 	netflush();
3281 	ptyflush();
3282 
3283 	for (;;) {
3284 		fd_set ibits, obits, xbits;
3285 		int c;
3286 
3287 		if (ncc < 0)
3288 			break;
3289 
3290 		FD_ZERO(&ibits);
3291 		FD_ZERO(&obits);
3292 		FD_ZERO(&xbits);
3293 
3294 		/*
3295 		 * If we couldn't flush all our output to the network,
3296 		 * keep checking for when we can.
3297 		 */
3298 		if (nfrontp - nbackp)
3299 			FD_SET(net, &obits);
3300 		/*
3301 		 * Never look for input if there's still
3302 		 * stuff in the corresponding output buffer
3303 		 */
3304 		if (pfrontp - pbackp) {
3305 			FD_SET(master, &obits);
3306 		} else {
3307 			FD_SET(net, &ibits);
3308 		}
3309 		if (!SYNCHing) {
3310 			FD_SET(net, &xbits);
3311 		}
3312 
3313 #define	max(x, y)	(((x) < (y)) ? (y) : (x))
3314 
3315 		/*
3316 		 * make an ioctl to telnet module (net side) to send
3317 		 * binary mode of telnet daemon. binary_in and
3318 		 * binary_out are 0 if not in binary mode.
3319 		 */
3320 		if (binary_in != myopts[TELOPT_BINARY] ||
3321 		    binary_out != remopts[TELOPT_BINARY]) {
3322 
3323 			mode = 0;
3324 			if (myopts[TELOPT_BINARY] != OPT_NO)
3325 				mode |= TEL_BINARY_IN;
3326 
3327 			if (remopts[TELOPT_BINARY] != OPT_NO)
3328 				mode |= TEL_BINARY_OUT;
3329 
3330 			telnetmod.ic_cmd = TEL_IOC_MODE;
3331 			telnetmod.ic_timout = -1;
3332 			telnetmod.ic_len = 1;
3333 			telnetmod.ic_dp = &mode;
3334 
3335 			syslog(LOG_DEBUG, "TEL_IOC_MODE binary has changed\n");
3336 
3337 			if (ioctl(net, I_STR, &telnetmod) < 0)
3338 				fatal(net, "ioctl TEL_IOC_MODE failed\n");
3339 			binary_in = myopts[TELOPT_BINARY];
3340 			binary_out = remopts[TELOPT_BINARY];
3341 		}
3342 		if (state == TS_DATA) {
3343 			if ((nfrontp == nbackp) &&
3344 				(pfrontp == pbackp)) {
3345 				if (ioctl(net, I_NREAD, &nsize) < 0)
3346 					fatalperror(net,
3347 					    "ioctl I_NREAD failed\n", errno);
3348 				if (nsize)
3349 					drainstream(nsize);
3350 
3351 				/*
3352 				 * make an ioctl to reinsert remaining data at
3353 				 * streamhead. After this, ioctl reenables the
3354 				 * telnet lower put queue. This queue was
3355 				 * noenabled by telnet module after sending
3356 				 * protocol/urgent data to telnetd.
3357 				 */
3358 
3359 				telnetmod.ic_cmd = TEL_IOC_ENABLE;
3360 				telnetmod.ic_timout = -1;
3361 				if (ncc || nsize) {
3362 					telnetmod.ic_len = ncc + nsize;
3363 					telnetmod.ic_dp = netip;
3364 				} else {
3365 					telnetmod.ic_len = 0;
3366 					telnetmod.ic_dp = NULL;
3367 				}
3368 				if (ioctl(net, I_STR, &telnetmod) < 0)
3369 					fatal(net, "ioctl TEL_IOC_ENABLE \
3370 						failed\n");
3371 
3372 				telmod_init_done = B_TRUE;
3373 
3374 				netip = netibuf;
3375 				(void) memset(netibuf, 0, netibufsize);
3376 
3377 				ncc = 0;
3378 			}
3379 		} else {
3380 			/*
3381 			 * state not changed to TS_DATA and hence, more to read
3382 			 * send ioctl to get one more message block.
3383 			 */
3384 			telnetmod.ic_cmd = TEL_IOC_GETBLK;
3385 			telnetmod.ic_timout = -1;
3386 			telnetmod.ic_len = 0;
3387 			telnetmod.ic_dp = NULL;
3388 
3389 			if (ioctl(net, I_STR, &telnetmod) < 0)
3390 				fatal(net, "ioctl TEL_IOC_GETBLK failed\n");
3391 		}
3392 
3393 		if ((c = select(max(net, master) + 1, &ibits, &obits, &xbits,
3394 		    (struct timeval *)0)) < 1) {
3395 			if (c == -1) {
3396 				if (errno == EINTR) {
3397 					continue;
3398 				}
3399 			}
3400 			(void) sleep(5);
3401 			continue;
3402 		}
3403 
3404 		/*
3405 		 * Any urgent data?
3406 		 */
3407 		if (FD_ISSET(net, &xbits)) {
3408 			SYNCHing = 1;
3409 		}
3410 
3411 		/*
3412 		 * Something to read from the network...
3413 		 */
3414 		if (FD_ISSET(net, &ibits)) {
3415 		    ncc = read(net, netibuf, netibufsize);
3416 		    if (ncc < 0 && errno == EWOULDBLOCK)
3417 			ncc = 0;
3418 		    else {
3419 			if (ncc <= 0) {
3420 			    break;
3421 			}
3422 			netip = netibuf;
3423 		    }
3424 		}
3425 
3426 		if (FD_ISSET(net, &obits) && (nfrontp - nbackp) > 0)
3427 			netflush();
3428 		if (ncc > 0)
3429 			telrcv();
3430 		if (FD_ISSET(master, &obits) && (pfrontp - pbackp) > 0)
3431 			ptyflush();
3432 	}
3433 	cleanup(0);
3434 }
3435 
3436 static void
telrcv(void)3437 telrcv(void)
3438 {
3439 	int c;
3440 
3441 	while (ncc > 0) {
3442 		if ((&ptyobuf[BUFSIZ] - pfrontp) < 2)
3443 			return;
3444 		c = *netip & 0377;
3445 		/*
3446 		 * Once we hit data, we want to transition back to
3447 		 * in-kernel processing.  However, this code is shared
3448 		 * by getterminaltype()/ttloop() which run before the
3449 		 * in-kernel plumbing is available.  So if we are still
3450 		 * processing the initial option negotiation, even TS_DATA
3451 		 * must be processed here.
3452 		 */
3453 		if (c != IAC && state == TS_DATA && init_neg_done) {
3454 			break;
3455 		}
3456 		netip++;
3457 		ncc--;
3458 		switch (state) {
3459 
3460 		case TS_CR:
3461 			state = TS_DATA;
3462 			/* Strip off \n or \0 after a \r */
3463 			if ((c == 0) || (c == '\n')) {
3464 				break;
3465 			}
3466 			/* FALLTHRU */
3467 
3468 		case TS_DATA:
3469 			if (c == IAC) {
3470 				state = TS_IAC;
3471 				break;
3472 			}
3473 			if (inter > 0)
3474 				break;
3475 			/*
3476 			 * We map \r\n ==> \r, since
3477 			 * We now map \r\n ==> \r for pragmatic reasons.
3478 			 * Many client implementations send \r\n when
3479 			 * the user hits the CarriageReturn key.
3480 			 *
3481 			 * We USED to map \r\n ==> \n, since \r\n says
3482 			 * that we want to be in column 1 of the next
3483 			 * line.
3484 			 */
3485 			if (c == '\r' && (myopts[TELOPT_BINARY] == OPT_NO)) {
3486 				state = TS_CR;
3487 			}
3488 			*pfrontp++ = c;
3489 			break;
3490 
3491 		case TS_IAC:
3492 			switch (c) {
3493 
3494 			/*
3495 			 * Send the process on the pty side an
3496 			 * interrupt.  Do this with a NULL or
3497 			 * interrupt char; depending on the tty mode.
3498 			 */
3499 			case IP:
3500 				interrupt();
3501 				break;
3502 
3503 			case BREAK:
3504 				sendbrk();
3505 				break;
3506 
3507 			/*
3508 			 * Are You There?
3509 			 */
3510 			case AYT:
3511 				write_data_len("\r\n[Yes]\r\n", 9);
3512 				break;
3513 
3514 			/*
3515 			 * Abort Output
3516 			 */
3517 			case AO: {
3518 					struct ltchars tmpltc;
3519 
3520 					ptyflush();	/* half-hearted */
3521 					if (ioctl(pty, TIOCGLTC, &tmpltc) == -1)
3522 						syslog(LOG_INFO,
3523 						    "ioctl TIOCGLTC: %m\n");
3524 					if (tmpltc.t_flushc != '\377') {
3525 						*pfrontp++ = tmpltc.t_flushc;
3526 					}
3527 					netclear();	/* clear buffer back */
3528 					write_data("%c%c", (uchar_t)IAC,
3529 						(uchar_t)DM);
3530 
3531 					neturg = nfrontp-1; /* off by one XXX */
3532 					netflush();
3533 					netflush(); /* XXX.sparker */
3534 					break;
3535 				}
3536 
3537 			/*
3538 			 * Erase Character and
3539 			 * Erase Line
3540 			 */
3541 			case EC:
3542 			case EL: {
3543 					struct sgttyb b;
3544 					char ch;
3545 
3546 					ptyflush();	/* half-hearted */
3547 					if (ioctl(pty, TIOCGETP, &b) == -1)
3548 						syslog(LOG_INFO,
3549 						    "ioctl TIOCGETP: %m\n");
3550 					ch = (c == EC) ?
3551 						b.sg_erase : b.sg_kill;
3552 					if (ch != '\377') {
3553 						*pfrontp++ = ch;
3554 					}
3555 					break;
3556 				}
3557 
3558 			/*
3559 			 * Check for urgent data...
3560 			 */
3561 			case DM:
3562 				break;
3563 
3564 			/*
3565 			 * Begin option subnegotiation...
3566 			 */
3567 			case SB:
3568 				state = TS_SB;
3569 				SB_CLEAR();
3570 				continue;
3571 
3572 			case WILL:
3573 				state = TS_WILL;
3574 				continue;
3575 
3576 			case WONT:
3577 				state = TS_WONT;
3578 				continue;
3579 
3580 			case DO:
3581 				state = TS_DO;
3582 				continue;
3583 
3584 			case DONT:
3585 				state = TS_DONT;
3586 				continue;
3587 
3588 			case IAC:
3589 				*pfrontp++ = c;
3590 				break;
3591 			}
3592 			state = TS_DATA;
3593 			break;
3594 		case TS_SB:
3595 			if (c == IAC) {
3596 				state = TS_SE;
3597 			} else {
3598 				SB_ACCUM(c);
3599 			}
3600 			break;
3601 		case TS_SE:
3602 			if (c != SE) {
3603 				if (c != IAC) {
3604 					SB_ACCUM((uchar_t)IAC);
3605 				}
3606 				SB_ACCUM(c);
3607 				state = TS_SB;
3608 
3609 			} else {
3610 				SB_TERM();
3611 				suboption();	/* handle sub-option */
3612 				state = TS_DATA;
3613 			}
3614 			break;
3615 
3616 		case TS_WILL:
3617 			if (remopts[c] != OPT_YES)
3618 				willoption(c);
3619 			state = TS_DATA;
3620 			continue;
3621 
3622 		case TS_WONT:
3623 			if (remopts[c] != OPT_NO)
3624 				wontoption(c);
3625 			state = TS_DATA;
3626 			continue;
3627 
3628 		case TS_DO:
3629 			if (myopts[c] != OPT_YES)
3630 				dooption(c);
3631 			state = TS_DATA;
3632 			continue;
3633 
3634 		case TS_DONT:
3635 			if (myopts[c] != OPT_NO) {
3636 				dontoption(c);
3637 			}
3638 			state = TS_DATA;
3639 			continue;
3640 
3641 		default:
3642 			syslog(LOG_ERR, "telnetd: panic state=%d\n", state);
3643 			(void) printf("telnetd: panic state=%d\n", state);
3644 			exit(EXIT_FAILURE);
3645 		}
3646 	}
3647 }
3648 
3649 static void
willoption(int option)3650 willoption(int option)
3651 {
3652 	uchar_t *fmt;
3653 	boolean_t send_reply = B_TRUE;
3654 
3655 	switch (option) {
3656 	case TELOPT_BINARY:
3657 		mode(O_RAW, 0);
3658 		fmt = doopt;
3659 		break;
3660 
3661 	case TELOPT_ECHO:
3662 		not42 = 0;		/* looks like a 4.2 system */
3663 		/*
3664 		 * Now, in a 4.2 system, to break them out of ECHOing
3665 		 * (to the terminal) mode, we need to send a "WILL ECHO".
3666 		 * Kludge upon kludge!
3667 		 */
3668 		if (myopts[TELOPT_ECHO] == OPT_YES) {
3669 			dooption(TELOPT_ECHO);
3670 		}
3671 		fmt = dont;
3672 		break;
3673 	case TELOPT_TTYPE:
3674 		settimer(ttypeopt);
3675 		goto common;
3676 
3677 	case TELOPT_NAWS:
3678 		settimer(nawsopt);
3679 		goto common;
3680 
3681 	case TELOPT_XDISPLOC:
3682 		settimer(xdisplocopt);
3683 		goto common;
3684 
3685 	case TELOPT_NEW_ENVIRON:
3686 		settimer(environopt);
3687 		goto common;
3688 
3689 	case TELOPT_AUTHENTICATION:
3690 		settimer(authopt);
3691 		if (remopts[option] == OPT_NO ||
3692 		    negotiate_auth_krb5 == 0)
3693 			fmt = dont;
3694 		else
3695 			fmt = doopt;
3696 		break;
3697 
3698 	case TELOPT_OLD_ENVIRON:
3699 		settimer(oenvironopt);
3700 		goto common;
3701 common:
3702 		if (remopts[option] == OPT_YES_BUT_ALWAYS_LOOK) {
3703 			remopts[option] = OPT_YES;
3704 			return;
3705 		}
3706 		/*FALLTHRU*/
3707 	case TELOPT_SGA:
3708 		fmt = doopt;
3709 		break;
3710 
3711 	case TELOPT_TM:
3712 		fmt = dont;
3713 		break;
3714 
3715 	case TELOPT_ENCRYPT:
3716 		settimer(encropt); /* got response to do/dont */
3717 		if (enc_debug)
3718 			(void) fprintf(stderr,
3719 				    "RCVD IAC WILL TELOPT_ENCRYPT\n");
3720 		if (krb5_privacy_allowed()) {
3721 			fmt = doopt;
3722 			if (sent_do_encrypt)
3723 				send_reply = B_FALSE;
3724 			else
3725 				sent_do_encrypt = B_TRUE;
3726 		} else {
3727 			fmt = dont;
3728 		}
3729 		break;
3730 
3731 	default:
3732 		fmt = dont;
3733 		break;
3734 	}
3735 	if (fmt == doopt) {
3736 		remopts[option] = OPT_YES;
3737 	} else {
3738 		remopts[option] = OPT_NO;
3739 	}
3740 	if (send_reply) {
3741 		write_data((const char *)fmt, option);
3742 		netflush();
3743 	}
3744 }
3745 
3746 static void
wontoption(int option)3747 wontoption(int option)
3748 {
3749 	uchar_t *fmt;
3750 	int send_reply = 1;
3751 
3752 	switch (option) {
3753 	case TELOPT_ECHO:
3754 		not42 = 1;		/* doesn't seem to be a 4.2 system */
3755 		break;
3756 
3757 	case TELOPT_BINARY:
3758 		mode(0, O_RAW);
3759 		break;
3760 
3761 	case TELOPT_TTYPE:
3762 		settimer(ttypeopt);
3763 		break;
3764 
3765 	case TELOPT_NAWS:
3766 		settimer(nawsopt);
3767 		break;
3768 
3769 	case TELOPT_XDISPLOC:
3770 		settimer(xdisplocopt);
3771 		break;
3772 
3773 	case TELOPT_NEW_ENVIRON:
3774 		settimer(environopt);
3775 		break;
3776 
3777 	case TELOPT_OLD_ENVIRON:
3778 		settimer(oenvironopt);
3779 		break;
3780 
3781 	case TELOPT_AUTHENTICATION:
3782 		settimer(authopt);
3783 		auth_finished(0, AUTH_REJECT);
3784 		if (auth_debug)
3785 			(void) fprintf(stderr,
3786 				    "RCVD WONT TELOPT_AUTHENTICATE\n");
3787 
3788 		remopts[option] = OPT_NO;
3789 		send_reply = 0;
3790 		break;
3791 
3792 	case TELOPT_ENCRYPT:
3793 		if (enc_debug)
3794 			(void) fprintf(stderr,
3795 				    "RCVD IAC WONT TELOPT_ENCRYPT\n");
3796 		settimer(encropt); /* got response to will/wont */
3797 		/*
3798 		 * Remote side cannot send encryption. No reply necessary
3799 		 * Treat this as if "IAC SB ENCRYPT END IAC SE" were
3800 		 * received (RFC 2946) and disable crypto.
3801 		 */
3802 		encrypt_end(TELNET_DIR_DECRYPT);
3803 		send_reply = 0;
3804 		break;
3805 	}
3806 
3807 	fmt = dont;
3808 	remopts[option] = OPT_NO;
3809 	if (send_reply) {
3810 		write_data((const char *)fmt, option);
3811 	}
3812 }
3813 
3814 /*
3815  * We received an "IAC DO ..." message from the client, change our state
3816  * to OPT_YES.
3817  */
3818 static void
dooption(int option)3819 dooption(int option)
3820 {
3821 	uchar_t *fmt;
3822 	boolean_t send_reply = B_TRUE;
3823 
3824 	switch (option) {
3825 
3826 	case TELOPT_TM:
3827 		fmt = wont;
3828 		break;
3829 
3830 	case TELOPT_ECHO:
3831 		mode(O_ECHO|O_CRMOD, 0);
3832 		fmt = will;
3833 		break;
3834 
3835 	case TELOPT_BINARY:
3836 		mode(O_RAW, 0);
3837 		fmt = will;
3838 		break;
3839 
3840 	case TELOPT_SGA:
3841 		fmt = will;
3842 		break;
3843 
3844 	case TELOPT_LOGOUT:
3845 		/*
3846 		 * Options don't get much easier.  Acknowledge the option,
3847 		 * and then clean up and exit.
3848 		 */
3849 		write_data((const char *)will, option);
3850 		netflush();
3851 		cleanup(0);
3852 		/*NOTREACHED*/
3853 
3854 	case TELOPT_ENCRYPT:
3855 		if (enc_debug)
3856 			(void) fprintf(stderr, "RCVD DO TELOPT_ENCRYPT\n");
3857 		settimer(encropt);
3858 		/*
3859 		 * We received a "DO".  This indicates that the other side
3860 		 * wants us to encrypt our data (pending negotiatoin).
3861 		 * reply with "IAC WILL ENCRYPT" if we are able to send
3862 		 * encrypted data.
3863 		 */
3864 		if (krb5_privacy_allowed() && negotiate_encrypt) {
3865 			fmt = will;
3866 			if (sent_will_encrypt)
3867 				send_reply = B_FALSE;
3868 			else
3869 				sent_will_encrypt = B_TRUE;
3870 			/* return if we already sent "WILL ENCRYPT" */
3871 			if (myopts[option] == OPT_YES)
3872 				return;
3873 		} else {
3874 			fmt = wont;
3875 		}
3876 		break;
3877 
3878 	case TELOPT_AUTHENTICATION:
3879 		if (auth_debug) {
3880 			(void) fprintf(stderr,
3881 				    "RCVD DO TELOPT_AUTHENTICATION\n");
3882 		}
3883 		/*
3884 		 * RFC 2941 - only the server can send
3885 		 * "DO TELOPT_AUTHENTICATION".
3886 		 * if a server receives this, it must respond with WONT...
3887 		 */
3888 		fmt = wont;
3889 		break;
3890 
3891 	default:
3892 		fmt = wont;
3893 		break;
3894 	}
3895 	if (fmt == will) {
3896 		myopts[option] = OPT_YES;
3897 	} else {
3898 		myopts[option] = OPT_NO;
3899 	}
3900 	if (send_reply) {
3901 		write_data((const char *)fmt, option);
3902 		netflush();
3903 	}
3904 }
3905 
3906 /*
3907  * We received an "IAC DONT ..." message from client.
3908  * Client does not agree with the option so act accordingly.
3909  */
3910 static void
dontoption(int option)3911 dontoption(int option)
3912 {
3913 	int send_reply = 1;
3914 	switch (option) {
3915 	case TELOPT_ECHO:
3916 		/*
3917 		 * we should stop echoing, since the client side will be doing
3918 		 * it, but keep mapping CR since CR-LF will be mapped to it.
3919 		 */
3920 		mode(0, O_ECHO);
3921 		break;
3922 
3923 	case TELOPT_ENCRYPT:
3924 		if (enc_debug)
3925 			(void) fprintf(stderr, "RCVD IAC DONT ENCRYPT\n");
3926 		settimer(encropt);
3927 		/*
3928 		 * Remote side cannot receive any encrypted data,
3929 		 * so dont send any.  No reply n