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 manager; /* manager 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(8) */
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(8) down? ");
500 if (auth_debug)
501 (void) fprintf(stderr,
502 "kwarn_add_warning failed:"
503 " ktkt_warnd(8) 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 int 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 *subsidname;
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 subsidiary pty");
2764 if (unlockpt(p) == -1)
2765 fatal(f, "could not unlock subsidiary pty");
2766 if ((subsidname = ptsname(p)) == NULL)
2767 fatal(f, "could not enable subsidiary pty");
2768 (void) dup2(f, 0);
2769 if ((t = open(subsidname, O_RDWR | O_NOCTTY)) == -1)
2770 fatal(f, "could not open subsidiary 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 = subsidname;
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 manager = 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, manager);
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 subsidiary 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", subsidname,
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", subsidname,
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", subsidname, "--",
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 manager)3257 telnet(int net, int manager)
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(manager, 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(manager, &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, manager) + 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(manager, &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 necessary.
3930 */
3931 send_reply = 0;
3932 break;
3933
3934 default:
3935 break;
3936 }
3937
3938 myopts[option] = OPT_NO;
3939
3940 if (send_reply) {
3941 write_data((const char *)wont, option);
3942 }
3943 }
3944
3945 /*
3946 * suboption()
3947 *
3948 * Look at the sub-option buffer, and try to be helpful to the other
3949 * side.
3950 *
3951 */
3952 static void
suboption(void)3953 suboption(void)
3954 {
3955 int subchar;
3956
3957 switch (subchar = SB_GET()) {
3958 case TELOPT_TTYPE: { /* Yaaaay! */
3959 static char terminalname[5+41] = "TERM=";
3960
3961 settimer(ttypesubopt);
3962
3963 if (SB_GET() != TELQUAL_IS) {
3964 return; /* ??? XXX but, this is the most robust */
3965 }
3966
3967 terminaltype = terminalname+strlen(terminalname);
3968
3969 while (terminaltype < (terminalname + sizeof (terminalname) -
3970 1) && !SB_EOF()) {
3971 int c;
3972
3973 c = SB_GET();
3974 if (isupper(c)) {
3975 c = tolower(c);
3976 }
3977 *terminaltype++ = c; /* accumulate name */
3978 }
3979 *terminaltype = 0;
3980 terminaltype = terminalname;
3981 break;
3982 }
3983
3984 case TELOPT_NAWS: {
3985 struct winsize ws;
3986
3987 if (SB_EOF()) {
3988 return;
3989 }
3990 ws.ws_col = SB_GET() << 8;
3991 if (SB_EOF()) {
3992 return;
3993 }
3994 ws.ws_col |= SB_GET();
3995 if (SB_EOF()) {
3996 return;
3997 }
3998 ws.ws_row = SB_GET() << 8;
3999 if (SB_EOF()) {
4000 return;
4001 }
4002 ws.ws_row |= SB_GET();
4003 ws.ws_xpixel = 0; ws.ws_ypixel = 0;
4004 (void) ioctl(pty, TIOCSWINSZ, &ws);
4005 settimer(nawsopt);
4006 break;
4007 }
4008
4009 case TELOPT_XDISPLOC: {
4010 if (SB_EOF() || SB_GET() != TELQUAL_IS) {
4011 return;
4012 }
4013 settimer(xdisplocsubopt);
4014 subpointer[SB_LEN()] = '\0';
4015 if ((new_env("DISPLAY", subpointer)) == 1)
4016 perror("malloc");
4017 break;
4018 }
4019
4020 case TELOPT_NEW_ENVIRON:
4021 case TELOPT_OLD_ENVIRON: {
4022 int c;
4023 char *cp, *varp, *valp;
4024
4025 if (SB_EOF())
4026 return;
4027 c = SB_GET();
4028 if (c == TELQUAL_IS) {
4029 if (subchar == TELOPT_OLD_ENVIRON)
4030 settimer(oenvironsubopt);
4031 else
4032 settimer(environsubopt);
4033 } else if (c != TELQUAL_INFO) {
4034 return;
4035 }
4036
4037 if (subchar == TELOPT_NEW_ENVIRON) {
4038 while (!SB_EOF()) {
4039 c = SB_GET();
4040 if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR))
4041 break;
4042 }
4043 } else
4044 {
4045 while (!SB_EOF()) {
4046 c = SB_GET();
4047 if ((c == env_ovar) || (c == ENV_USERVAR))
4048 break;
4049 }
4050 }
4051
4052 if (SB_EOF())
4053 return;
4054
4055 cp = varp = (char *)subpointer;
4056 valp = 0;
4057
4058 while (!SB_EOF()) {
4059 c = SB_GET();
4060 if (subchar == TELOPT_OLD_ENVIRON) {
4061 if (c == env_ovar)
4062 c = NEW_ENV_VAR;
4063 else if (c == env_ovalue)
4064 c = NEW_ENV_VALUE;
4065 }
4066 switch (c) {
4067
4068 case NEW_ENV_VALUE:
4069 *cp = '\0';
4070 cp = valp = (char *)subpointer;
4071 break;
4072
4073 case NEW_ENV_VAR:
4074 case ENV_USERVAR:
4075 *cp = '\0';
4076 if (valp) {
4077 if ((new_env(varp, valp)) == 1) {
4078 perror("malloc");
4079 }
4080 } else {
4081 (void) del_env(varp);
4082 }
4083 cp = varp = (char *)subpointer;
4084 valp = 0;
4085 break;
4086
4087 case ENV_ESC:
4088 if (SB_EOF())
4089 break;
4090 c = SB_GET();
4091 /* FALL THROUGH */
4092 default:
4093 *cp++ = c;
4094 break;
4095 }
4096 }
4097 *cp = '\0';
4098 if (valp) {
4099 if ((new_env(varp, valp)) == 1) {
4100 perror("malloc");
4101 }
4102 } else {
4103 (void) del_env(varp);
4104 }
4105 break;
4106 } /* end of case TELOPT_NEW_ENVIRON */
4107
4108 case TELOPT_AUTHENTICATION:
4109 if (SB_EOF())
4110 break;
4111 switch (SB_GET()) {
4112 case TELQUAL_SEND:
4113 case TELQUAL_REPLY:
4114 /*
4115 * These are sent server only and cannot be sent by the
4116 * client.
4117 */
4118 break;
4119 case TELQUAL_IS:
4120 if (auth_debug)
4121 (void) fprintf(stderr,
4122 "RCVD AUTHENTICATION IS "
4123 "(%d bytes)\n",
4124 SB_LEN());
4125 if (!auth_negotiated)
4126 auth_is((uchar_t *)subpointer, SB_LEN());
4127 break;
4128 case TELQUAL_NAME:
4129 if (auth_debug)
4130 (void) fprintf(stderr,
4131 "RCVD AUTHENTICATION NAME "
4132 "(%d bytes)\n",
4133 SB_LEN());
4134 if (!auth_negotiated)
4135 auth_name((uchar_t *)subpointer, SB_LEN());
4136 break;
4137 }
4138 break;
4139
4140 case TELOPT_ENCRYPT: {
4141 int c;
4142 if (SB_EOF())
4143 break;
4144 c = SB_GET();
4145 #ifdef ENCRYPT_NAMES
4146 if (enc_debug)
4147 (void) fprintf(stderr, "RCVD ENCRYPT %s\n",
4148 ENCRYPT_NAME(c));
4149 #endif /* ENCRYPT_NAMES */
4150 switch (c) {
4151 case ENCRYPT_SUPPORT:
4152 encrypt_support(subpointer, SB_LEN());
4153 break;
4154 case ENCRYPT_IS:
4155 encrypt_is((uchar_t *)subpointer, SB_LEN());
4156 break;
4157 case ENCRYPT_REPLY:
4158 (void) encrypt_reply(subpointer, SB_LEN());
4159 break;
4160 case ENCRYPT_START:
4161 encrypt_start();
4162 break;
4163 case ENCRYPT_END:
4164 encrypt_end(TELNET_DIR_DECRYPT);
4165 break;
4166 case ENCRYPT_REQSTART:
4167 encrypt_request_start();
4168 break;
4169 case ENCRYPT_REQEND:
4170 /*
4171 * We can always send an REQEND so that we cannot
4172 * get stuck encrypting. We should only get this
4173 * if we have been able to get in the correct mode
4174 * anyhow.
4175 */
4176 encrypt_request_end();
4177 break;
4178 case ENCRYPT_ENC_KEYID:
4179 encrypt_enc_keyid(subpointer, SB_LEN());
4180 break;
4181 case ENCRYPT_DEC_KEYID:
4182 encrypt_dec_keyid(subpointer, SB_LEN());
4183 break;
4184 default:
4185 break;
4186 }
4187 }
4188 break;
4189
4190 default:
4191 break;
4192 }
4193 }
4194
4195 static void
mode(int on,int off)4196 mode(int on, int off)
4197 {
4198 struct termios tios;
4199
4200 ptyflush();
4201 if (tcgetattr(pty, &tios) < 0)
4202 syslog(LOG_INFO, "tcgetattr: %m\n");
4203
4204 if (on & O_RAW) {
4205 tios.c_cflag |= CS8;
4206 tios.c_iflag &= ~IUCLC;
4207 tios.c_lflag &= ~(XCASE|IEXTEN);
4208 }
4209 if (off & O_RAW) {
4210 if ((tios.c_cflag & PARENB) != 0)
4211 tios.c_cflag &= ~CS8;
4212 tios.c_lflag |= IEXTEN;
4213 }
4214
4215 if (on & O_ECHO)
4216 tios.c_lflag |= ECHO;
4217 if (off & O_ECHO)
4218 tios.c_lflag &= ~ECHO;
4219
4220 if (on & O_CRMOD) {
4221 tios.c_iflag |= ICRNL;
4222 tios.c_oflag |= ONLCR;
4223 }
4224 /*
4225 * Because "O_CRMOD" will never be set in "off" we don't have to
4226 * handle this case here.
4227 */
4228
4229 if (tcsetattr(pty, TCSANOW, &tios) < 0)
4230 syslog(LOG_INFO, "tcsetattr: %m\n");
4231 }
4232
4233 /*
4234 * Send interrupt to process on other side of pty.
4235 * If it is in raw mode, just write NULL;
4236 * otherwise, write intr char.
4237 */
4238 static void
interrupt(void)4239 interrupt(void)
4240 {
4241 struct sgttyb b;
4242 struct tchars tchars;
4243
4244 ptyflush(); /* half-hearted */
4245 if (ioctl(pty, TIOCGETP, &b) == -1)
4246 syslog(LOG_INFO, "ioctl TIOCGETP: %m\n");
4247 if (b.sg_flags & O_RAW) {
4248 *pfrontp++ = '\0';
4249 return;
4250 }
4251 *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ?
4252 '\177' : tchars.t_intrc;
4253 }
4254
4255 /*
4256 * Send quit to process on other side of pty.
4257 * If it is in raw mode, just write NULL;
4258 * otherwise, write quit char.
4259 */
4260 static void
sendbrk(void)4261 sendbrk(void)
4262 {
4263 struct sgttyb b;
4264 struct tchars tchars;
4265
4266 ptyflush(); /* half-hearted */
4267 (void) ioctl(pty, TIOCGETP, &b);
4268 if (b.sg_flags & O_RAW) {
4269 *pfrontp++ = '\0';
4270 return;
4271 }
4272 *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ?
4273 '\034' : tchars.t_quitc;
4274 }
4275
4276 static void
ptyflush(void)4277 ptyflush(void)
4278 {
4279 int n;
4280
4281 if ((n = pfrontp - pbackp) > 0)
4282 n = write(manager, pbackp, n);
4283 if (n < 0)
4284 return;
4285 pbackp += n;
4286 if (pbackp == pfrontp)
4287 pbackp = pfrontp = ptyobuf;
4288 }
4289
4290 /*
4291 * nextitem()
4292 *
4293 * Return the address of the next "item" in the TELNET data
4294 * stream. This will be the address of the next character if
4295 * the current address is a user data character, or it will
4296 * be the address of the character following the TELNET command
4297 * if the current address is a TELNET IAC ("I Am a Command")
4298 * character.
4299 */
4300
4301 static char *
nextitem(char * current)4302 nextitem(char *current)
4303 {
4304 if ((*current&0xff) != IAC) {
4305 return (current+1);
4306 }
4307 switch (*(current+1)&0xff) {
4308 case DO:
4309 case DONT:
4310 case WILL:
4311 case WONT:
4312 return (current+3);
4313 case SB: /* loop forever looking for the SE */
4314 {
4315 char *look = current+2;
4316
4317 for (;;) {
4318 if ((*look++&0xff) == IAC) {
4319 if ((*look++&0xff) == SE) {
4320 return (look);
4321 }
4322 }
4323 }
4324 }
4325 default:
4326 return (current+2);
4327 }
4328 }
4329
4330
4331 /*
4332 * netclear()
4333 *
4334 * We are about to do a TELNET SYNCH operation. Clear
4335 * the path to the network.
4336 *
4337 * Things are a bit tricky since we may have sent the first
4338 * byte or so of a previous TELNET command into the network.
4339 * So, we have to scan the network buffer from the beginning
4340 * until we are up to where we want to be.
4341 *
4342 * A side effect of what we do, just to keep things
4343 * simple, is to clear the urgent data pointer. The principal
4344 * caller should be setting the urgent data pointer AFTER calling
4345 * us in any case.
4346 */
4347 static void
netclear(void)4348 netclear(void)
4349 {
4350 char *thisitem, *next;
4351 char *good;
4352 #define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \
4353 ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
4354
4355 thisitem = netobuf;
4356
4357 while ((next = nextitem(thisitem)) <= nbackp) {
4358 thisitem = next;
4359 }
4360
4361 /* Now, thisitem is first before/at boundary. */
4362
4363 good = netobuf; /* where the good bytes go */
4364
4365 while (nfrontp > thisitem) {
4366 if (wewant(thisitem)) {
4367 int length;
4368
4369 next = thisitem;
4370 do {
4371 next = nextitem(next);
4372 } while (wewant(next) && (nfrontp > next));
4373 length = next-thisitem;
4374 (void) memmove(good, thisitem, length);
4375 good += length;
4376 thisitem = next;
4377 } else {
4378 thisitem = nextitem(thisitem);
4379 }
4380 }
4381
4382 nbackp = netobuf;
4383 nfrontp = good; /* next byte to be sent */
4384 neturg = 0;
4385 }
4386
4387
4388 /*
4389 * netflush
4390 * Send as much data as possible to the network,
4391 * handling requests for urgent data.
4392 */
4393 static void
netflush(void)4394 netflush(void)
4395 {
4396 int n;
4397
4398 if ((n = nfrontp - nbackp) > 0) {
4399 /*
4400 * if no urgent data, or if the other side appears to be an
4401 * old 4.2 client (and thus unable to survive TCP urgent data),
4402 * write the entire buffer in non-OOB mode.
4403 */
4404 if ((neturg == 0) || (not42 == 0)) {
4405 n = write(net, nbackp, n); /* normal write */
4406 } else {
4407 n = neturg - nbackp;
4408 /*
4409 * In 4.2 (and 4.3) systems, there is some question
4410 * about what byte in a sendOOB operation is the "OOB"
4411 * data. To make ourselves compatible, we only send ONE
4412 * byte out of band, the one WE THINK should be OOB
4413 * (though we really have more the TCP philosophy of
4414 * urgent data rather than the Unix philosophy of OOB
4415 * data).
4416 */
4417 if (n > 1) {
4418 /* send URGENT all by itself */
4419 n = write(net, nbackp, n-1);
4420 } else {
4421 /* URGENT data */
4422 n = send_oob(net, nbackp, n);
4423 }
4424 }
4425 }
4426 if (n < 0) {
4427 if (errno == EWOULDBLOCK)
4428 return;
4429 /* should blow this guy away... */
4430 return;
4431 }
4432
4433 nbackp += n;
4434
4435 if (nbackp >= neturg) {
4436 neturg = 0;
4437 }
4438 if (nbackp == nfrontp) {
4439 nbackp = nfrontp = netobuf;
4440 }
4441 }
4442
4443 /* ARGSUSED */
4444 static void
cleanup(int signum)4445 cleanup(int signum)
4446 {
4447 /*
4448 * If the TEL_IOC_ENABLE ioctl hasn't completed, then we need to
4449 * handle closing differently. We close "net" first and then
4450 * "manager" in that order. We do close(net) first because
4451 * we have no other way to disconnect forwarding between the network
4452 * and manager. So by issuing the close()'s we ensure that no further
4453 * data rises from TCP. A more complex fix would be adding proper
4454 * support for throwing a "stop" switch for forwarding data between
4455 * logindmux peers. It's possible to block in the close of the tty
4456 * while the network still receives data and the telmod module is
4457 * TEL_STOPPED. A denial-of-service attack generates this case,
4458 * see 4102102.
4459 */
4460
4461 if (!telmod_init_done) {
4462 (void) close(net);
4463 (void) close(manager);
4464 }
4465 rmut();
4466
4467 exit(EXIT_FAILURE);
4468 }
4469
4470 static void
rmut(void)4471 rmut(void)
4472 {
4473 pam_handle_t *pamh;
4474 struct utmpx *up;
4475 char user[sizeof (up->ut_user) + 1];
4476 char ttyn[sizeof (up->ut_line) + 1];
4477 char rhost[sizeof (up->ut_host) + 1];
4478
4479 /* while cleaning up don't allow disruption */
4480 (void) signal(SIGCHLD, SIG_IGN);
4481
4482 setutxent();
4483 while (up = getutxent()) {
4484 if (up->ut_pid == pid) {
4485 if (up->ut_type == DEAD_PROCESS) {
4486 /*
4487 * Cleaned up elsewhere.
4488 */
4489 break;
4490 }
4491
4492 /*
4493 * call pam_close_session if login changed
4494 * the utmpx user entry from type LOGIN_PROCESS
4495 * to type USER_PROCESS, which happens
4496 * after pam_open_session is called.
4497 */
4498 if (up->ut_type == USER_PROCESS) {
4499 (void) strlcpy(user, up->ut_user,
4500 sizeof (user));
4501 (void) strlcpy(ttyn, up->ut_line,
4502 sizeof (ttyn));
4503 (void) strlcpy(rhost, up->ut_host,
4504 sizeof (rhost));
4505 if ((pam_start("telnet", user, NULL, &pamh)) ==
4506 PAM_SUCCESS) {
4507 (void) pam_set_item(pamh, PAM_TTY,
4508 ttyn);
4509 (void) pam_set_item(pamh, PAM_RHOST,
4510 rhost);
4511 (void) pam_close_session(pamh, 0);
4512 (void) pam_end(pamh, PAM_SUCCESS);
4513 }
4514 }
4515
4516 up->ut_type = DEAD_PROCESS;
4517 up->ut_exit.e_termination = WTERMSIG(0);
4518 up->ut_exit.e_exit = WEXITSTATUS(0);
4519 (void) time(&up->ut_tv.tv_sec);
4520
4521 if (modutx(up) == NULL) {
4522 /*
4523 * Since modutx failed we'll
4524 * write out the new entry
4525 * ourselves.
4526 */
4527 (void) pututxline(up);
4528 updwtmpx("wtmpx", up);
4529 }
4530 break;
4531 }
4532 }
4533
4534 endutxent();
4535
4536 (void) signal(SIGCHLD, (void (*)())cleanup);
4537 }
4538
4539 static int
readstream(int fd,char * buf,int offset)4540 readstream(int fd, char *buf, int offset)
4541 {
4542 struct strbuf ctlbuf, datbuf;
4543 union T_primitives tpi;
4544 int ret = 0;
4545 int flags = 0;
4546 int bytes_avail, count;
4547
4548 (void) memset((char *)&ctlbuf, 0, sizeof (ctlbuf));
4549 (void) memset((char *)&datbuf, 0, sizeof (datbuf));
4550
4551 ctlbuf.buf = (char *)&tpi;
4552 ctlbuf.maxlen = sizeof (tpi);
4553
4554 if (ioctl(fd, I_NREAD, &bytes_avail) < 0) {
4555 syslog(LOG_ERR, "I_NREAD returned error %m");
4556 return (-1);
4557 }
4558 if (bytes_avail > netibufsize - offset) {
4559 count = netip - netibuf;
4560 netibuf = (char *)realloc(netibuf,
4561 (unsigned)netibufsize + bytes_avail);
4562 if (netibuf == NULL) {
4563 fatal(net, "netibuf realloc failed\n");
4564 }
4565 netibufsize += bytes_avail;
4566 netip = netibuf + count;
4567 buf = netibuf;
4568 }
4569 datbuf.buf = buf + offset;
4570 datbuf.maxlen = netibufsize;
4571 ret = getmsg(fd, &ctlbuf, &datbuf, &flags);
4572 if (ret < 0) {
4573 syslog(LOG_ERR, "getmsg returned -1, errno %d\n",
4574 errno);
4575 return (-1);
4576 }
4577 if (ctlbuf.len <= 0) {
4578 return (datbuf.len);
4579 }
4580
4581 if (tpi.type == T_DATA_REQ) {
4582 return (0);
4583 }
4584
4585 if ((tpi.type == T_ORDREL_IND) || (tpi.type == T_DISCON_IND))
4586 cleanup(0);
4587 fatal(fd, "no data or protocol element recognized");
4588 return (0);
4589 }
4590
4591 static void
drainstream(int size)4592 drainstream(int size)
4593 {
4594 int nbytes;
4595 int tsize;
4596
4597 tsize = netip - netibuf;
4598
4599 if ((tsize + ncc + size) > netibufsize) {
4600 if (!(netibuf = (char *)realloc(netibuf,
4601 (unsigned)tsize + ncc + size)))
4602 fatalperror(net, "netibuf realloc failed\n", errno);
4603 netibufsize = tsize + ncc + size;
4604
4605 netip = netibuf + tsize;
4606 }
4607
4608 if ((nbytes = read(net, (char *)netip + ncc, size)) != size)
4609 syslog(LOG_ERR, "read %d bytes\n", nbytes);
4610 }
4611
4612 /*
4613 * TPI style replacement for socket send() primitive, so we don't require
4614 * sockmod to be on the stream.
4615 */
4616 static int
send_oob(int fd,char * ptr,int count)4617 send_oob(int fd, char *ptr, int count)
4618 {
4619 struct T_exdata_req exd_req;
4620 struct strbuf hdr, dat;
4621 int ret;
4622
4623 exd_req.PRIM_type = T_EXDATA_REQ;
4624 exd_req.MORE_flag = 0;
4625
4626 hdr.buf = (char *)&exd_req;
4627 hdr.len = sizeof (exd_req);
4628
4629 dat.buf = ptr;
4630 dat.len = count;
4631
4632 ret = putmsg(fd, &hdr, &dat, 0);
4633 if (ret == 0) {
4634 ret = count;
4635 }
4636 return (ret);
4637 }
4638
4639
4640 /*
4641 * local_setenv --
4642 * Set the value of the environmental variable "name" to be
4643 * "value". If rewrite is set, replace any current value.
4644 */
4645 static int
local_setenv(const char * name,const char * value,int rewrite)4646 local_setenv(const char *name, const char *value, int rewrite)
4647 {
4648 static int alloced; /* if allocated space before */
4649 char *c;
4650 int l_value, offset;
4651
4652 /*
4653 * Do not allow environment variables which begin with LD_ to be
4654 * inserted into the environment. While normally the dynamic linker
4655 * protects the login program, that is based on the assumption hostile
4656 * invocation of login are from non-root users. However, since telnetd
4657 * runs as root, this cannot be utilized. So instead we simply
4658 * prevent LD_* from being inserted into the environment.
4659 * This also applies to other environment variables that
4660 * are to be ignored in setugid apps.
4661 * Note that at this point name can contain '='!
4662 * Also, do not allow TTYPROMPT to be passed along here.
4663 */
4664 if (strncmp(name, "LD_", 3) == 0 ||
4665 strncmp(name, "NLSPATH", 7) == 0 ||
4666 (strncmp(name, "TTYPROMPT", 9) == 0 &&
4667 (name[9] == '\0' || name[9] == '='))) {
4668 return (-1);
4669 }
4670 if (*value == '=') /* no `=' in value */
4671 ++value;
4672 l_value = strlen(value);
4673 if ((c = __findenv(name, &offset))) { /* find if already exists */
4674 if (!rewrite)
4675 return (0);
4676 if ((int)strlen(c) >= l_value) { /* old larger; copy over */
4677 while (*c++ = *value++)
4678 ;
4679 return (0);
4680 }
4681 } else { /* create new slot */
4682 int cnt;
4683 char **p;
4684
4685 for (p = environ, cnt = 0; *p; ++p, ++cnt)
4686 ;
4687 if (alloced) { /* just increase size */
4688 environ = (char **)realloc((char *)environ,
4689 (size_t)(sizeof (char *) * (cnt + 2)));
4690 if (!environ)
4691 return (-1);
4692 } else { /* get new space */
4693 alloced = 1; /* copy old entries into it */
4694 p = (char **)malloc((size_t)(sizeof (char *)*
4695 (cnt + 2)));
4696 if (!p)
4697 return (-1);
4698 (void) memcpy(p, environ, cnt * sizeof (char *));
4699 environ = p;
4700 }
4701 environ[cnt + 1] = NULL;
4702 offset = cnt;
4703 }
4704 for (c = (char *)name; *c && *c != '='; ++c) /* no `=' in name */
4705 ;
4706 if (!(environ[offset] = /* name + `=' + value */
4707 malloc((size_t)((int)(c - name) + l_value + 2))))
4708 return (-1);
4709 for (c = environ[offset]; ((*c = *name++) != 0) && (*c != '='); ++c)
4710 ;
4711 for (*c++ = '='; *c++ = *value++; )
4712 ;
4713 return (0);
4714 }
4715
4716 /*
4717 * local_unsetenv(name) --
4718 * Delete environmental variable "name".
4719 */
4720 static void
local_unsetenv(const char * name)4721 local_unsetenv(const char *name)
4722 {
4723 char **p;
4724 int offset;
4725
4726 while (__findenv(name, &offset)) /* if set multiple times */
4727 for (p = &environ[offset]; ; ++p)
4728 if ((*p = *(p + 1)) == 0)
4729 break;
4730 }
4731
4732 /*
4733 * __findenv --
4734 * Returns pointer to value associated with name, if any, else NULL.
4735 * Sets offset to be the offset of the name/value combination in the
4736 * environmental array, for use by local_setenv() and local_unsetenv().
4737 * Explicitly removes '=' in argument name.
4738 */
4739 static char *
__findenv(const char * name,int * offset)4740 __findenv(const char *name, int *offset)
4741 {
4742 extern char **environ;
4743 int len;
4744 const char *np;
4745 char **p, *c;
4746
4747 if (name == NULL || environ == NULL)
4748 return (NULL);
4749 for (np = name; *np && *np != '='; ++np)
4750 continue;
4751 len = np - name;
4752 for (p = environ; (c = *p) != NULL; ++p)
4753 if (strncmp(c, name, len) == 0 && c[len] == '=') {
4754 *offset = p - environ;
4755 return (c + len + 1);
4756 }
4757 return (NULL);
4758 }
4759
4760 static void
showbanner(void)4761 showbanner(void)
4762 {
4763 char *cp;
4764 char evalbuf[BUFSIZ];
4765
4766 if (defopen(defaultfile) == 0) {
4767 int flags;
4768
4769 /* ignore case */
4770 flags = defcntl(DC_GETFLAGS, 0);
4771 TURNOFF(flags, DC_CASE);
4772 (void) defcntl(DC_SETFLAGS, flags);
4773 if (cp = defread(bannervar)) {
4774 FILE *fp;
4775
4776 if (strlen(cp) + strlen("eval echo '") + strlen("'\n")
4777 + 1 < sizeof (evalbuf)) {
4778 (void) strlcpy(evalbuf, "eval echo '",
4779 sizeof (evalbuf));
4780 (void) strlcat(evalbuf, cp, sizeof (evalbuf));
4781 (void) strlcat(evalbuf, "'\n",
4782 sizeof (evalbuf));
4783
4784 if (fp = popen(evalbuf, "r")) {
4785 char buf[BUFSIZ];
4786 size_t size;
4787
4788 /*
4789 * Pipe I/O atomicity guarantees we
4790 * need only one read.
4791 */
4792 if ((size = fread(buf, 1,
4793 sizeof (buf) - 1,
4794 fp)) != 0) {
4795 char *p;
4796 buf[size] = '\0';
4797 p = strrchr(buf, '\n');
4798 if (p != NULL)
4799 *p = '\0';
4800 if (strlen(buf)) {
4801 map_banner(buf);
4802 netflush();
4803 }
4804 }
4805 (void) pclose(fp);
4806 /* close default file */
4807 (void) defopen(NULL);
4808 return;
4809 }
4810 }
4811 }
4812 (void) defopen(NULL); /* close default file */
4813 }
4814
4815 defbanner();
4816 netflush();
4817 }
4818
4819 static void
map_banner(char * p)4820 map_banner(char *p)
4821 {
4822 char *q;
4823
4824 /*
4825 * Map the banner: "\n" -> "\r\n" and "\r" -> "\r\0"
4826 */
4827 for (q = nfrontp; p && *p && q < nfrontp + sizeof (netobuf) - 1; )
4828 if (*p == '\n') {
4829 *q++ = '\r';
4830 *q++ = '\n';
4831 p++;
4832 } else if (*p == '\r') {
4833 *q++ = '\r';
4834 *q++ = '\0';
4835 p++;
4836 } else
4837 *q++ = *p++;
4838
4839 nfrontp += q - netobuf;
4840 }
4841
4842 /*
4843 * Show banner that getty never gave. By default, this is `uname -sr`.
4844 *
4845 * The banner includes some null's (for TELNET CR disambiguation),
4846 * so we have to be somewhat complicated.
4847 */
4848 static void
defbanner(void)4849 defbanner(void)
4850 {
4851 struct utsname u;
4852
4853 /*
4854 * Dont show this if the '-h' option was present
4855 */
4856 if (!show_hostinfo)
4857 return;
4858
4859 if (uname(&u) == -1)
4860 return;
4861
4862 write_data_len((const char *) BANNER1, sizeof (BANNER1) - 1);
4863 write_data_len(u.sysname, strlen(u.sysname));
4864 write_data_len(" ", 1);
4865 write_data_len(u.release, strlen(u.release));
4866 write_data_len((const char *)BANNER2, sizeof (BANNER2) - 1);
4867 }
4868
4869 /*
4870 * Verify that the named module is at the top of the stream
4871 * and then pop it off.
4872 */
4873 static int
removemod(int f,char * modname)4874 removemod(int f, char *modname)
4875 {
4876 char topmodname[BUFSIZ];
4877
4878 if (ioctl(f, I_LOOK, topmodname) < 0)
4879 return (-1);
4880 if (strcmp(modname, topmodname) != 0) {
4881 errno = ENXIO;
4882 return (-1);
4883 }
4884 if (ioctl(f, I_POP, 0) < 0)
4885 return (-1);
4886 return (0);
4887 }
4888
4889 static void
write_data(const char * format,...)4890 write_data(const char *format, ...)
4891 {
4892 va_list args;
4893 int len;
4894 char argp[BUFSIZ];
4895
4896 va_start(args, format);
4897
4898 if ((len = vsnprintf(argp, sizeof (argp), format, args)) == -1)
4899 return;
4900
4901 write_data_len(argp, len);
4902 va_end(args);
4903 }
4904
4905 static void
write_data_len(const char * buf,int len)4906 write_data_len(const char *buf, int len)
4907 {
4908 int remaining, copied;
4909
4910 remaining = BUFSIZ - (nfrontp - netobuf);
4911 while (len > 0) {
4912 /*
4913 * If there's not enough space in netobuf then
4914 * try to make some.
4915 */
4916 if ((len > BUFSIZ ? BUFSIZ : len) > remaining) {
4917 netflush();
4918 remaining = BUFSIZ - (nfrontp - netobuf);
4919 }
4920 /* Copy as much as we can */
4921 copied = remaining > len ? len : remaining;
4922 (void) memmove(nfrontp, buf, copied);
4923 nfrontp += copied;
4924 len -= copied;
4925 remaining -= copied;
4926 buf += copied;
4927 }
4928 }
4929