1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T 29 * All Rights Reserved. 30 */ 31 32 /* 33 * University Copyright- Copyright (c) 1982, 1986, 1988 34 * The Regents of the University of California. 35 * All Rights Reserved. 36 * 37 * University Acknowledgment- Portions of this document are derived from 38 * software developed by the University of California, Berkeley, and its 39 * contributors. 40 */ 41 42 /* 43 * Telnet server. 44 */ 45 #include <sys/types.h> 46 #include <sys/param.h> 47 #include <sys/socket.h> 48 #include <sys/wait.h> 49 #include <sys/file.h> 50 #include <sys/stat.h> 51 #include <sys/filio.h> 52 #include <sys/time.h> 53 #include <sys/stropts.h> 54 #include <sys/stream.h> 55 #include <sys/tihdr.h> 56 #include <sys/utsname.h> 57 #include <unistd.h> 58 59 #include <netinet/in.h> 60 61 #define AUTHWHO_STR 62 #define AUTHTYPE_NAMES 63 #define AUTHHOW_NAMES 64 #define AUTHRSP_NAMES 65 #define ENCRYPT_NAMES 66 67 #include <arpa/telnet.h> 68 #include <arpa/inet.h> 69 #include <stdio.h> 70 #include <stdarg.h> 71 #include <signal.h> 72 #include <errno.h> 73 #include <netdb.h> 74 #include <syslog.h> 75 #include <ctype.h> 76 #include <fcntl.h> 77 #include <sac.h> /* for SC_WILDC */ 78 #include <utmpx.h> 79 #include <sys/ttold.h> 80 #include <malloc.h> 81 #include <string.h> 82 #include <security/pam_appl.h> 83 #include <sys/tihdr.h> 84 #include <sys/logindmux.h> 85 #include <sys/telioctl.h> 86 #include <deflt.h> 87 #include <stdlib.h> 88 #include <string.h> 89 #include <stropts.h> 90 #include <termios.h> 91 92 #include <com_err.h> 93 #include <krb5.h> 94 #include <krb5_repository.h> 95 #include <des/des.h> 96 #include <rpc/des_crypt.h> 97 #include <sys/cryptmod.h> 98 #include <bsm/adt.h> 99 100 #define TELNETD_OPTS "Ss:a:dEXUhR:M:" 101 #ifdef DEBUG 102 #define DEBUG_OPTS "p:e" 103 #else 104 #define DEBUG_OPTS "" 105 #endif /* DEBUG */ 106 107 #define OPT_NO 0 /* won't do this option */ 108 #define OPT_YES 1 /* will do this option */ 109 #define OPT_YES_BUT_ALWAYS_LOOK 2 110 #define OPT_NO_BUT_ALWAYS_LOOK 3 111 112 #define MAXOPTLEN 256 113 #define MAXUSERNAMELEN 256 114 115 static char remopts[MAXOPTLEN]; 116 static char myopts[MAXOPTLEN]; 117 static uchar_t doopt[] = { (uchar_t)IAC, (uchar_t)DO, '%', 'c', 0 }; 118 static uchar_t dont[] = { (uchar_t)IAC, (uchar_t)DONT, '%', 'c', 0 }; 119 static uchar_t will[] = { (uchar_t)IAC, (uchar_t)WILL, '%', 'c', 0 }; 120 static uchar_t wont[] = { (uchar_t)IAC, (uchar_t)WONT, '%', 'c', 0 }; 121 /* 122 * I/O data buffers, pointers, and counters. 123 */ 124 static char ptyobuf[BUFSIZ], *pfrontp = ptyobuf, *pbackp = ptyobuf; 125 126 static char *netibuf, *netip; 127 static int netibufsize; 128 129 #define NIACCUM(c) { *netip++ = c; \ 130 ncc++; \ 131 } 132 133 static char netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf; 134 static char *neturg = 0; /* one past last bye of urgent data */ 135 /* the remote system seems to NOT be an old 4.2 */ 136 static int not42 = 1; 137 static char defaultfile[] = "/etc/default/telnetd"; 138 static char bannervar[] = "BANNER="; 139 140 static char BANNER1[] = "\r\n\r\n"; 141 static char BANNER2[] = "\r\n\r\0\r\n\r\0"; 142 143 /* 144 * buffer for sub-options - enlarged to 4096 to handle credentials 145 * from AUTH options 146 */ 147 static char subbuffer[4096], *subpointer = subbuffer, *subend = subbuffer; 148 #define SB_CLEAR() subpointer = subbuffer; 149 #define SB_TERM() { subend = subpointer; SB_CLEAR(); } 150 #define SB_ACCUM(c) if (subpointer < (subbuffer+sizeof (subbuffer))) { \ 151 *subpointer++ = (c); \ 152 } 153 #define SB_GET() ((*subpointer++)&0xff) 154 #define SB_EOF() (subpointer >= subend) 155 #define SB_LEN() (subend - subpointer) 156 157 #define MAXERRSTRLEN 1024 158 #define MAXPRINCLEN 256 159 160 extern uint_t kwarn_add_warning(char *, int); 161 extern uint_t kwarn_del_warning(char *); 162 163 static boolean_t auth_debug = 0; 164 static boolean_t negotiate_auth_krb5 = 1; 165 static boolean_t auth_negotiated = 0; 166 static int auth_status = 0; 167 static int auth_level = 0; 168 static char *AuthenticatingUser = NULL; 169 static char *krb5_name = NULL; 170 171 static krb5_address rsaddr = { 0, 0, 0, NULL }; 172 static krb5_address rsport = { 0, 0, 0, NULL }; 173 174 static krb5_context telnet_context = 0; 175 static krb5_auth_context auth_context = 0; 176 177 /* telnetd gets session key from here */ 178 static krb5_ticket *ticket = NULL; 179 static krb5_keyblock *session_key = NULL; 180 static char *telnet_srvtab = NULL; 181 182 typedef struct { 183 uchar_t AuthName; 184 uchar_t AuthHow; 185 char *AuthString; 186 } AuthInfo; 187 188 static AuthInfo auth_list[] = { 189 {AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT | AUTH_HOW_MUTUAL | 190 AUTH_ENCRYPT_ON, "KRB5 MUTUAL CRYPTO"}, 191 {AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT | AUTH_HOW_MUTUAL, 192 "KRB5 MUTUAL" }, 193 {AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT | AUTH_HOW_ONE_WAY, 194 "KRB5 1-WAY" }, 195 {0, 0, "NONE"} 196 }; 197 198 static AuthInfo NoAuth = {0, 0, NULL}; 199 200 static AuthInfo *authenticated = NULL; 201 202 #define PREAMBLE_SIZE 5 /* for auth_reply_str allocation */ 203 #define POSTAMBLE_SIZE 5 204 #define STR_DATA_LEN(len) ((len) * 2 + PREAMBLE_SIZE + POSTAMBLE_SIZE) 205 206 static void auth_name(uchar_t *, int); 207 static void auth_is(uchar_t *, int); 208 209 #define NO_ENCRYPTION 0x00 210 #define SEND_ENCRYPTED 0x01 211 #define RECV_ENCRYPTED 0x02 212 #define ENCRYPT_BOTH_WAYS (SEND_ENCRYPTED | RECV_ENCRYPTED) 213 214 static telnet_enc_data_t encr_data; 215 static boolean_t negotiate_encrypt = B_TRUE; 216 static boolean_t sent_encrypt_support = B_FALSE; 217 static boolean_t sent_will_encrypt = B_FALSE; 218 static boolean_t sent_do_encrypt = B_FALSE; 219 static boolean_t enc_debug = 0; 220 221 static void encrypt_session_key(Session_Key *key, cipher_info_t *cinfo); 222 static int encrypt_send_encrypt_is(); 223 224 extern void mit_des_fixup_key_parity(Block); 225 extern int krb5_setenv(const char *, const char *, int); 226 /* need to know what FD to use to talk to the crypto module */ 227 static int cryptmod_fd = -1; 228 229 #define LOGIN_PROGRAM "/bin/login" 230 231 /* 232 * State for recv fsm 233 */ 234 #define TS_DATA 0 /* base state */ 235 #define TS_IAC 1 /* look for double IAC's */ 236 #define TS_CR 2 /* CR-LF ->'s CR */ 237 #define TS_SB 3 /* throw away begin's... */ 238 #define TS_SE 4 /* ...end's (suboption negotiation) */ 239 #define TS_WILL 5 /* will option negotiation */ 240 #define TS_WONT 6 /* wont " */ 241 #define TS_DO 7 /* do " */ 242 #define TS_DONT 8 /* dont " */ 243 244 static int ncc; 245 static int master; /* master side of pty */ 246 static int pty; /* side of pty that gets ioctls */ 247 static int net; 248 static int inter; 249 extern char **environ; 250 static char *line; 251 static int SYNCHing = 0; /* we are in TELNET SYNCH mode */ 252 static int state = TS_DATA; 253 254 static int env_ovar = -1; /* XXX.sparker */ 255 static int env_ovalue = -1; /* XXX.sparker */ 256 static char pam_svc_name[64]; 257 static boolean_t telmod_init_done = B_FALSE; 258 259 static void doit(int, struct sockaddr_storage *); 260 static void willoption(int); 261 static void wontoption(int); 262 static void dooption(int); 263 static void dontoption(int); 264 static void fatal(int, char *); 265 static void fatalperror(int, char *, int); 266 static void mode(int, int); 267 static void interrupt(void); 268 static void drainstream(int); 269 static int readstream(int, char *, int); 270 static int send_oob(int fd, char *ptr, int count); 271 static int local_setenv(const char *name, const char *value, int rewrite); 272 static void local_unsetenv(const char *name); 273 static void suboption(void); 274 static int removemod(int f, char *modname); 275 static void willoption(int option); 276 static void wontoption(int option); 277 static void dooption(int option); 278 static void dontoption(int option); 279 static void write_data(const char *, ...); 280 static void write_data_len(const char *, int); 281 static void rmut(void); 282 static void cleanup(int); 283 static void telnet(int, int); 284 static void telrcv(void); 285 static void sendbrk(void); 286 static void ptyflush(void); 287 static void netclear(void); 288 static void netflush(void); 289 static void showbanner(void); 290 static void map_banner(char *); 291 static void defbanner(void); 292 static void ttloop(void); 293 294 /* 295 * The env_list linked list is used to store the environment variables 296 * until the final exec of login. A malevolent client might try to 297 * send an environment variable intended to affect the telnet daemon's 298 * execution. Right now the BANNER expansion is the only instance. 299 * Note that it is okay to pass the environment variables to login 300 * because login protects itself against environment variables mischief. 301 */ 302 303 struct envlist { 304 struct envlist *next; 305 char *name; 306 char *value; 307 int delete; 308 }; 309 310 static struct envlist *envlist_head = NULL; 311 312 /* 313 * The following are some clocks used to decide how to interpret 314 * the relationship between various variables. 315 */ 316 317 static struct { 318 int 319 system, /* what the current time is */ 320 echotoggle, /* last time user entered echo character */ 321 modenegotiated, /* last time operating mode negotiated */ 322 didnetreceive, /* last time we read data from network */ 323 ttypeopt, /* ttype will/won't received */ 324 ttypesubopt, /* ttype subopt is received */ 325 getterminal, /* time started to get terminal information */ 326 xdisplocopt, /* xdisploc will/wont received */ 327 xdisplocsubopt, /* xdisploc suboption received */ 328 nawsopt, /* window size will/wont received */ 329 nawssubopt, /* window size received */ 330 environopt, /* environment option will/wont received */ 331 oenvironopt, /* "old" environ option will/wont received */ 332 environsubopt, /* environment option suboption received */ 333 oenvironsubopt, /* "old environ option suboption received */ 334 gotDM; /* when did we last see a data mark */ 335 336 int getauth; 337 int authopt; /* Authentication option negotiated */ 338 int authdone; 339 340 int getencr; 341 int encropt; 342 int encr_support; 343 } clocks; 344 345 static int init_neg_done = 0; 346 static boolean_t resolve_hostname = 0; 347 static boolean_t show_hostinfo = 1; 348 349 #define settimer(x) (clocks.x = ++clocks.system) 350 #define sequenceIs(x, y) (clocks.x < clocks.y) 351 352 static void send_will(int); 353 static void send_wont(int); 354 static void send_do(int); 355 static char *__findenv(const char *name, int *offset); 356 357 /* ARGSUSED */ 358 static void 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 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 461 rd_and_store_forwarded_creds(krb5_context context, 462 krb5_auth_context auth_context, 463 krb5_data *inbuf, krb5_ticket *ticket, 464 char *username) 465 { 466 krb5_creds **creds; 467 krb5_error_code retval; 468 char ccname[MAXPATHLEN]; 469 krb5_ccache ccache = NULL; 470 char *client_name = NULL; 471 472 if (retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL)) 473 return (retval); 474 475 (void) sprintf(ccname, "FILE:/tmp/krb5cc_p%ld", getpid()); 476 (void) krb5_setenv("KRB5CCNAME", ccname, 1); 477 478 if ((retval = krb5_cc_default(context, &ccache))) 479 goto cleanup; 480 481 if ((retval = krb5_cc_initialize(context, ccache, 482 ticket->enc_part2->client)) != 0) 483 goto cleanup; 484 485 if ((retval = krb5_cc_store_cred(context, ccache, *creds)) != 0) 486 goto cleanup; 487 488 if ((retval = krb5_cc_close(context, ccache)) != 0) 489 goto cleanup; 490 491 /* Register with ktkt_warnd(1M) */ 492 if ((retval = krb5_unparse_name(context, (*creds)->client, 493 &client_name)) != 0) 494 goto cleanup; 495 (void) kwarn_del_warning(client_name); 496 if (kwarn_add_warning(client_name, (*creds)->times.endtime) != 0) { 497 syslog(LOG_AUTH|LOG_NOTICE, 498 "rd_and_store_forwarded_creds: kwarn_add_warning" 499 " failed: ktkt_warnd(1M) down? "); 500 if (auth_debug) 501 (void) fprintf(stderr, 502 "kwarn_add_warning failed:" 503 " ktkt_warnd(1M) down?\n"); 504 } 505 free(client_name); 506 client_name = NULL; 507 508 if (username != NULL) { 509 /* 510 * This verifies that the user is valid on the local system, 511 * maps the username from KerberosV5 to unix, 512 * and moves the KRB5CCNAME file to the correct place 513 * /tmp/krb5cc_[uid] with correct ownership (0600 uid gid). 514 * 515 * NOTE: the user must be in the gsscred table in order to map 516 * from KRB5 to Unix. 517 */ 518 (void) krb5_kuserok(context, ticket->enc_part2->client, 519 username); 520 } 521 if (auth_debug) 522 (void) fprintf(stderr, 523 "Successfully stored forwarded creds\n"); 524 525 cleanup: 526 krb5_free_creds(context, *creds); 527 return (retval); 528 } 529 530 static void 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 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 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 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 != NULL && 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 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 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 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 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 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 = NULL; 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 2189 main(int argc, char *argv[]) 2190 { 2191 struct sockaddr_storage from; 2192 int on = 1; 2193 socklen_t fromlen; 2194 int issocket; 2195 #if defined(DEBUG) 2196 ushort_t porttouse = 0; 2197 boolean_t standalone = 0; 2198 #endif /* defined(DEBUG) */ 2199 extern char *optarg; 2200 char c; 2201 int tos = -1; 2202 2203 while ((c = getopt(argc, argv, TELNETD_OPTS DEBUG_OPTS)) != -1) { 2204 switch (c) { 2205 #if defined(DEBUG) 2206 case 'p': 2207 /* 2208 * note: alternative port number only used in 2209 * standalone mode. 2210 */ 2211 porttouse = atoi(optarg); 2212 standalone = 1; 2213 break; 2214 case 'e': 2215 enc_debug = 1; 2216 break; 2217 #endif /* DEBUG */ 2218 case 'a': 2219 if (strcasecmp(optarg, "none") == 0) { 2220 auth_level = 0; 2221 } else if (strcasecmp(optarg, "user") == 0) { 2222 auth_level = AUTH_USER; 2223 } else if (strcasecmp(optarg, "valid") == 0) { 2224 auth_level = AUTH_VALID; 2225 } else if (strcasecmp(optarg, "off") == 0) { 2226 auth_level = -1; 2227 negotiate_auth_krb5 = 0; 2228 } else if (strcasecmp(optarg, "debug") == 0) { 2229 auth_debug = 1; 2230 } else { 2231 syslog(LOG_ERR, 2232 "unknown authentication level specified " 2233 "with \'-a\' option (%s)", optarg); 2234 auth_level = AUTH_USER; 2235 } 2236 break; 2237 case 'X': 2238 /* disable authentication negotiation */ 2239 negotiate_auth_krb5 = 0; 2240 break; 2241 case 'R': 2242 case 'M': 2243 if (optarg != NULL) { 2244 int ret = krb5_init(); 2245 if (ret) { 2246 syslog(LOG_ERR, 2247 "Unable to use Kerberos V5 as " 2248 "requested, exiting"); 2249 exit(1); 2250 } 2251 (void) krb5_set_default_realm(telnet_context, 2252 optarg); 2253 syslog(LOG_NOTICE, 2254 "using %s as default KRB5 realm", optarg); 2255 } 2256 break; 2257 case 'S': 2258 telnet_srvtab = (char *)strdup(optarg); 2259 break; 2260 case 'E': /* disable automatic encryption */ 2261 negotiate_encrypt = B_FALSE; 2262 break; 2263 case 'U': 2264 resolve_hostname = 1; 2265 break; 2266 case 's': 2267 if (optarg == NULL || (tos = atoi(optarg)) < 0 || 2268 tos > 255) { 2269 syslog(LOG_ERR, "telnetd: illegal tos value: " 2270 "%s\n", optarg); 2271 } else { 2272 if (tos < 0) 2273 tos = 020; 2274 } 2275 break; 2276 case 'h': 2277 show_hostinfo = 0; 2278 break; 2279 default: 2280 syslog(LOG_ERR, "telnetd: illegal cmd line option %c", 2281 c); 2282 break; 2283 } 2284 } 2285 2286 netibufsize = BUFSIZ; 2287 if (!(netibuf = (char *)malloc(netibufsize))) 2288 syslog(LOG_ERR, "netibuf malloc failed\n"); 2289 (void) memset(netibuf, 0, netibufsize); 2290 netip = netibuf; 2291 2292 #if defined(DEBUG) 2293 if (standalone) { 2294 int s, ns, foo; 2295 struct servent *sp; 2296 static struct sockaddr_in6 sin6 = { AF_INET6 }; 2297 int option = 1; 2298 2299 if (porttouse) { 2300 sin6.sin6_port = htons(porttouse); 2301 } else { 2302 sp = getservbyname("telnet", "tcp"); 2303 if (sp == 0) { 2304 (void) fprintf(stderr, 2305 "telnetd: tcp/telnet: " 2306 "unknown service\n"); 2307 exit(EXIT_FAILURE); 2308 } 2309 sin6.sin6_port = sp->s_port; 2310 } 2311 2312 s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); 2313 if (s < 0) { 2314 perror("telnetd: socket"); 2315 exit(EXIT_FAILURE); 2316 } 2317 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&option, 2318 sizeof (option)) == -1) 2319 perror("setsockopt SO_REUSEADDR"); 2320 if (bind(s, (struct sockaddr *)&sin6, sizeof (sin6)) < 0) { 2321 perror("bind"); 2322 exit(EXIT_FAILURE); 2323 } 2324 if (listen(s, 32) < 0) { 2325 perror("listen"); 2326 exit(EXIT_FAILURE); 2327 } 2328 2329 /* automatically reap all child processes */ 2330 (void) signal(SIGCHLD, SIG_IGN); 2331 2332 for (;;) { 2333 pid_t pid; 2334 2335 foo = sizeof (sin6); 2336 ns = accept(s, (struct sockaddr *)&sin6, &foo); 2337 if (ns < 0) { 2338 perror("accept"); 2339 exit(EXIT_FAILURE); 2340 } 2341 pid = fork(); 2342 if (pid == -1) { 2343 perror("fork"); 2344 exit(EXIT_FAILURE); 2345 } 2346 if (pid == 0) { 2347 (void) dup2(ns, 0); 2348 (void) close(s); 2349 (void) signal(SIGCHLD, SIG_DFL); 2350 break; 2351 } 2352 (void) close(ns); 2353 } 2354 } 2355 #endif /* defined(DEBUG) */ 2356 2357 openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON); 2358 2359 issocket = issock(0); 2360 if (!issocket) 2361 fatal(0, "stdin is not a socket file descriptor"); 2362 2363 fromlen = (socklen_t)sizeof (from); 2364 (void) memset((char *)&from, 0, sizeof (from)); 2365 if (getpeername(0, (struct sockaddr *)&from, &fromlen) 2366 < 0) { 2367 (void) fprintf(stderr, "%s: ", argv[0]); 2368 perror("getpeername"); 2369 _exit(EXIT_FAILURE); 2370 } 2371 2372 if (audit_telnet_settid(0)) { /* set terminal ID */ 2373 (void) fprintf(stderr, "%s: ", argv[0]); 2374 perror("audit"); 2375 exit(EXIT_FAILURE); 2376 } 2377 2378 if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (const char *)&on, 2379 sizeof (on)) < 0) { 2380 syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 2381 } 2382 2383 /* 2384 * Set the TOS value 2385 */ 2386 if (tos != -1 && 2387 setsockopt(0, IPPROTO_IP, IP_TOS, 2388 (char *)&tos, sizeof (tos)) < 0 && 2389 errno != ENOPROTOOPT) { 2390 syslog(LOG_ERR, "setsockopt (IP_TOS %d): %m", tos); 2391 } 2392 2393 if (setsockopt(net, SOL_SOCKET, SO_OOBINLINE, (char *)&on, 2394 sizeof (on)) < 0) { 2395 syslog(LOG_WARNING, "setsockopt (SO_OOBINLINE): %m"); 2396 } 2397 2398 /* set the default PAM service name */ 2399 (void) strcpy(pam_svc_name, "telnet"); 2400 2401 doit(0, &from); 2402 return (EXIT_SUCCESS); 2403 } 2404 2405 static char *terminaltype = 0; 2406 2407 /* 2408 * ttloop 2409 * 2410 * A small subroutine to flush the network output buffer, get some data 2411 * from the network, and pass it through the telnet state machine. We 2412 * also flush the pty input buffer (by dropping its data) if it becomes 2413 * too full. 2414 */ 2415 static void 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 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 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 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 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 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 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 2737 doit(int f, struct sockaddr_storage *who) 2738 { 2739 char *host; 2740 char host_name[MAXHOSTNAMELEN]; 2741 int p, t, tt; 2742 struct sgttyb b; 2743 int ptmfd; /* fd of logindmux connected to pty */ 2744 int netfd; /* fd of logindmux connected to netf */ 2745 struct stat buf; 2746 struct protocol_arg telnetp; 2747 struct strioctl telnetmod; 2748 struct envlist *env, *next; 2749 int nsize = 0; 2750 char abuf[INET6_ADDRSTRLEN]; 2751 struct sockaddr_in *sin; 2752 struct sockaddr_in6 *sin6; 2753 socklen_t wholen; 2754 char username[MAXUSERNAMELEN]; 2755 int len; 2756 uchar_t passthru; 2757 char *slavename; 2758 2759 if ((p = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) { 2760 fatalperror(f, "open /dev/ptmx", errno); 2761 } 2762 if (grantpt(p) == -1) 2763 fatal(f, "could not grant slave pty"); 2764 if (unlockpt(p) == -1) 2765 fatal(f, "could not unlock slave pty"); 2766 if ((slavename = ptsname(p)) == NULL) 2767 fatal(f, "could not enable slave pty"); 2768 (void) dup2(f, 0); 2769 if ((t = open(slavename, O_RDWR | O_NOCTTY)) == -1) 2770 fatal(f, "could not open slave pty"); 2771 if (ioctl(t, I_PUSH, "ptem") == -1) 2772 fatalperror(f, "ioctl I_PUSH ptem", errno); 2773 if (ioctl(t, I_PUSH, "ldterm") == -1) 2774 fatalperror(f, "ioctl I_PUSH ldterm", errno); 2775 if (ioctl(t, I_PUSH, "ttcompat") == -1) 2776 fatalperror(f, "ioctl I_PUSH ttcompat", errno); 2777 2778 line = slavename; 2779 2780 pty = t; 2781 2782 if (ioctl(t, TIOCGETP, &b) == -1) 2783 syslog(LOG_INFO, "ioctl TIOCGETP pty t: %m\n"); 2784 b.sg_flags = O_CRMOD|O_XTABS|O_ANYP; 2785 /* XXX - ispeed and ospeed must be non-zero */ 2786 b.sg_ispeed = B38400; 2787 b.sg_ospeed = B38400; 2788 if (ioctl(t, TIOCSETN, &b) == -1) 2789 syslog(LOG_INFO, "ioctl TIOCSETN pty t: %m\n"); 2790 if (ioctl(pty, TIOCGETP, &b) == -1) 2791 syslog(LOG_INFO, "ioctl TIOCGETP pty pty: %m\n"); 2792 b.sg_flags &= ~O_ECHO; 2793 if (ioctl(pty, TIOCSETN, &b) == -1) 2794 syslog(LOG_INFO, "ioctl TIOCSETN pty pty: %m\n"); 2795 2796 if (who->ss_family == AF_INET) { 2797 char *addrbuf = NULL; 2798 char *portbuf = NULL; 2799 2800 sin = (struct sockaddr_in *)who; 2801 wholen = sizeof (struct sockaddr_in); 2802 2803 addrbuf = (char *)malloc(wholen); 2804 if (addrbuf == NULL) 2805 fatal(f, "Cannot alloc memory for address info\n"); 2806 portbuf = (char *)malloc(sizeof (sin->sin_port)); 2807 if (portbuf == NULL) { 2808 free(addrbuf); 2809 fatal(f, "Cannot alloc memory for port info\n"); 2810 } 2811 2812 (void) memcpy(addrbuf, (const void *)&sin->sin_addr, wholen); 2813 (void) memcpy(portbuf, (const void *)&sin->sin_port, 2814 sizeof (sin->sin_port)); 2815 2816 if (rsaddr.contents != NULL) 2817 free(rsaddr.contents); 2818 2819 rsaddr.contents = (krb5_octet *)addrbuf; 2820 rsaddr.length = wholen; 2821 rsaddr.addrtype = ADDRTYPE_INET; 2822 2823 if (rsport.contents != NULL) 2824 free(rsport.contents); 2825 2826 rsport.contents = (krb5_octet *)portbuf; 2827 rsport.length = sizeof (sin->sin_port); 2828 rsport.addrtype = ADDRTYPE_IPPORT; 2829 } else if (who->ss_family == AF_INET6) { 2830 struct in_addr ipv4_addr; 2831 char *addrbuf = NULL; 2832 char *portbuf = NULL; 2833 2834 sin6 = (struct sockaddr_in6 *)who; 2835 wholen = sizeof (struct sockaddr_in6); 2836 2837 IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr, 2838 &ipv4_addr); 2839 2840 addrbuf = (char *)malloc(wholen); 2841 if (addrbuf == NULL) 2842 fatal(f, "Cannot alloc memory for address info\n"); 2843 2844 portbuf = (char *)malloc(sizeof (sin6->sin6_port)); 2845 if (portbuf == NULL) { 2846 free(addrbuf); 2847 fatal(f, "Cannot alloc memory for port info\n"); 2848 } 2849 2850 (void) memcpy((void *) addrbuf, 2851 (const void *)&ipv4_addr, 2852 wholen); 2853 /* 2854 * If we already used rsaddr.contents, free the previous 2855 * buffer. 2856 */ 2857 if (rsaddr.contents != NULL) 2858 free(rsaddr.contents); 2859 2860 rsaddr.contents = (krb5_octet *)addrbuf; 2861 rsaddr.length = sizeof (ipv4_addr); 2862 rsaddr.addrtype = ADDRTYPE_INET; 2863 2864 (void) memcpy((void *) portbuf, (const void *)&sin6->sin6_port, 2865 sizeof (sin6->sin6_port)); 2866 2867 if (rsport.contents != NULL) 2868 free(rsport.contents); 2869 2870 rsport.contents = (krb5_octet *)portbuf; 2871 rsport.length = sizeof (sin6->sin6_port); 2872 rsport.addrtype = ADDRTYPE_IPPORT; 2873 } else { 2874 syslog(LOG_ERR, "unknown address family %d\n", 2875 who->ss_family); 2876 fatal(f, "getpeername: unknown address family\n"); 2877 } 2878 2879 if (getnameinfo((const struct sockaddr *) who, wholen, host_name, 2880 sizeof (host_name), NULL, 0, 0) == 0) { 2881 host = host_name; 2882 } else { 2883 /* 2884 * If the '-U' option was given on the cmd line, we must 2885 * be able to lookup the hostname 2886 */ 2887 if (resolve_hostname) { 2888 fatal(f, "Couldn't resolve your address into a " 2889 "host name.\r\nPlease contact your net " 2890 "administrator"); 2891 } 2892 2893 if (who->ss_family == AF_INET6) { 2894 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 2895 struct in_addr ipv4_addr; 2896 2897 IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr, 2898 &ipv4_addr); 2899 host = (char *)inet_ntop(AF_INET, 2900 &ipv4_addr, abuf, sizeof (abuf)); 2901 } else { 2902 host = (char *)inet_ntop(AF_INET6, 2903 &sin6->sin6_addr, abuf, 2904 sizeof (abuf)); 2905 } 2906 } else if (who->ss_family == AF_INET) { 2907 host = (char *)inet_ntop(AF_INET, 2908 &sin->sin_addr, abuf, sizeof (abuf)); 2909 } 2910 } 2911 /* 2912 * Note that sockmod has to be removed since readstream assumes 2913 * a "raw" TPI endpoint (e.g. it uses getmsg). 2914 */ 2915 if (removemod(f, "sockmod") < 0) 2916 fatalperror(f, "couldn't remove sockmod", errno); 2917 2918 encrypt_init(); 2919 2920 /* 2921 * Push the crypto module on the stream before 'telmod' so it 2922 * can encrypt/decrypt without interfering with telmod functionality 2923 * We must push it now because many of the crypto options negotiated 2924 * initially must be saved in the crypto module (via IOCTL calls). 2925 */ 2926 if (ioctl(f, I_PUSH, "cryptmod") < 0) 2927 fatalperror(f, "ioctl I_PUSH cryptmod", errno); 2928 2929 cryptmod_fd = f; 2930 /* 2931 * gotta set the encryption clock now because it is often negotiated 2932 * immediately by the client, and if we wait till after we negotiate 2933 * auth, it will be out of whack with when the WILL/WONT ENCRYPT 2934 * option is received. 2935 */ 2936 settimer(getencr); 2937 2938 /* 2939 * get terminal type. 2940 */ 2941 username[0] = '\0'; 2942 len = sizeof (username); 2943 2944 settimer(getterminal); 2945 settimer(getauth); 2946 /* 2947 * Exchange TELOPT_AUTHENTICATE options per RFC 2941/2942 2948 */ 2949 auth_status = getauthtype(username, &len); 2950 /* 2951 * Exchange TELOPT_ENCRYPT options per RFC 2946 2952 */ 2953 getencrtype(); 2954 getterminaltype(); 2955 2956 if (ioctl(f, I_PUSH, "telmod") < 0) 2957 fatalperror(f, "ioctl I_PUSH telmod", errno); 2958 2959 /* 2960 * Make sure telmod will pass unrecognized IOCTLs to cryptmod 2961 */ 2962 passthru = 1; 2963 2964 telnetmod.ic_cmd = CRYPTPASSTHRU; 2965 telnetmod.ic_timout = -1; 2966 telnetmod.ic_len = sizeof (uchar_t); 2967 telnetmod.ic_dp = (char *)&passthru; 2968 2969 if (ioctl(f, I_STR, &telnetmod) < 0) 2970 fatal(f, "ioctl CRPASSTHRU failed\n"); 2971 2972 if (!ncc) 2973 netip = netibuf; 2974 2975 /* 2976 * readstream will do a getmsg till it receives M_PROTO type 2977 * T_DATA_REQ from telnetmodopen(). This signals that all data 2978 * in-flight before telmod was pushed has been received at the 2979 * stream head. 2980 */ 2981 while ((nsize = readstream(f, netibuf, ncc + netip - netibuf)) > 0) { 2982 ncc += nsize; 2983 } 2984 2985 if (nsize < 0) { 2986 fatalperror(f, "readstream failed\n", errno); 2987 } 2988 2989 /* 2990 * open logindmux drivers and link them with network and ptm 2991 * file descriptors. 2992 */ 2993 if ((ptmfd = open("/dev/logindmux", O_RDWR)) == -1) { 2994 fatalperror(f, "open /dev/logindmux", errno); 2995 } 2996 if ((netfd = open("/dev/logindmux", O_RDWR)) == -1) { 2997 fatalperror(f, "open /dev/logindmux", errno); 2998 } 2999 3000 if (ioctl(ptmfd, I_LINK, p) < 0) 3001 fatal(f, "ioctl I_LINK of /dev/ptmx failed\n"); 3002 if (ioctl(netfd, I_LINK, f) < 0) 3003 fatal(f, "ioctl I_LINK of tcp connection failed\n"); 3004 3005 /* 3006 * Figure out the device number of ptm's mux fd, and pass that 3007 * to the net's mux. 3008 */ 3009 if (fstat(ptmfd, &buf) < 0) { 3010 fatalperror(f, "fstat ptmfd failed", errno); 3011 } 3012 telnetp.dev = buf.st_rdev; 3013 telnetp.flag = 0; 3014 3015 telnetmod.ic_cmd = LOGDMX_IOC_QEXCHANGE; 3016 telnetmod.ic_timout = -1; 3017 telnetmod.ic_len = sizeof (struct protocol_arg); 3018 telnetmod.ic_dp = (char *)&telnetp; 3019 3020 if (ioctl(netfd, I_STR, &telnetmod) < 0) 3021 fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of netfd failed\n"); 3022 3023 /* 3024 * Figure out the device number of the net's mux fd, and pass that 3025 * to the ptm's mux. 3026 */ 3027 if (fstat(netfd, &buf) < 0) { 3028 fatalperror(f, "fstat netfd failed", errno); 3029 } 3030 telnetp.dev = buf.st_rdev; 3031 telnetp.flag = 1; 3032 3033 telnetmod.ic_cmd = LOGDMX_IOC_QEXCHANGE; 3034 telnetmod.ic_timout = -1; 3035 telnetmod.ic_len = sizeof (struct protocol_arg); 3036 telnetmod.ic_dp = (char *)&telnetp; 3037 3038 if (ioctl(ptmfd, I_STR, &telnetmod) < 0) 3039 fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of ptmfd failed\n"); 3040 3041 net = netfd; 3042 master = ptmfd; 3043 cryptmod_fd = netfd; 3044 3045 /* 3046 * Show banner that getty never gave, but 3047 * only if the user did not automatically authenticate. 3048 */ 3049 if (getenv("USER") == '\0' && auth_status < AUTH_USER) 3050 showbanner(); 3051 3052 /* 3053 * If the user automatically authenticated with Kerberos 3054 * we must set the service name that PAM will use. We 3055 * need to do it BEFORE the child fork so that 'cleanup' 3056 * in the parent can call the PAM cleanup stuff with the 3057 * same PAM service that /bin/login will use to authenticate 3058 * this session. 3059 */ 3060 if (auth_level >= 0 && auth_status >= AUTH_USER && 3061 (AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) { 3062 (void) strcpy(pam_svc_name, "ktelnet"); 3063 } 3064 /* 3065 * Request to do suppress go ahead. 3066 * 3067 * Send this before sending the TELOPT_ECHO stuff below because 3068 * some clients (MIT KRB5 telnet) have quirky 'kludge mode' support 3069 * that has them turn off local echo mode if SGA is not received first. 3070 * This also has the odd side-effect of causing the client to enable 3071 * encryption and then immediately disable it during the ECHO option 3072 * negotiations. Its just better to to SGA first now that we support 3073 * encryption. 3074 */ 3075 if (!myopts[TELOPT_SGA]) { 3076 dooption(TELOPT_SGA); 3077 } 3078 3079 /* 3080 * Pretend we got a DO ECHO from the client if we have not 3081 * yet negotiated the ECHO. 3082 */ 3083 if (!myopts[TELOPT_ECHO]) { 3084 dooption(TELOPT_ECHO); 3085 } 3086 3087 /* 3088 * Is the client side a 4.2 (NOT 4.3) system? We need to know this 3089 * because 4.2 clients are unable to deal with TCP urgent data. 3090 * 3091 * To find out, we send out a "DO ECHO". If the remote system 3092 * answers "WILL ECHO" it is probably a 4.2 client, and we note 3093 * that fact ("WILL ECHO" ==> that the client will echo what 3094 * WE, the server, sends it; it does NOT mean that the client will 3095 * echo the terminal input). 3096 */ 3097 send_do(TELOPT_ECHO); 3098 remopts[TELOPT_ECHO] = OPT_YES_BUT_ALWAYS_LOOK; 3099 3100 if ((pid = fork()) < 0) 3101 fatalperror(netfd, "fork", errno); 3102 if (pid) 3103 telnet(net, master); 3104 /* 3105 * The child process needs to be the session leader 3106 * and have the pty as its controlling tty. Thus we need 3107 * to re-open the slave side of the pty no without 3108 * the O_NOCTTY flag that we have been careful to 3109 * use up to this point. 3110 */ 3111 (void) setsid(); 3112 3113 tt = open(line, O_RDWR); 3114 if (tt < 0) 3115 fatalperror(netfd, line, errno); 3116 (void) close(netfd); 3117 (void) close(ptmfd); 3118 (void) close(f); 3119 (void) close(p); 3120 (void) close(t); 3121 if (tt != 0) 3122 (void) dup2(tt, 0); 3123 if (tt != 1) 3124 (void) dup2(tt, 1); 3125 if (tt != 2) 3126 (void) dup2(tt, 2); 3127 if (tt > 2) 3128 (void) close(tt); 3129 3130 if (terminaltype) 3131 (void) local_setenv("TERM", terminaltype+5, 1); 3132 /* 3133 * -h : pass on name of host. 3134 * WARNING: -h is accepted by login if and only if 3135 * getuid() == 0. 3136 * -p : don't clobber the environment (so terminal type stays set). 3137 */ 3138 { 3139 /* System V login expects a utmp entry to already be there */ 3140 struct utmpx ut; 3141 (void) memset((char *)&ut, 0, sizeof (ut)); 3142 (void) strncpy(ut.ut_user, ".telnet", sizeof (ut.ut_user)); 3143 (void) strncpy(ut.ut_line, line, sizeof (ut.ut_line)); 3144 ut.ut_pid = getpid(); 3145 ut.ut_id[0] = 't'; 3146 ut.ut_id[1] = (char)SC_WILDC; 3147 ut.ut_id[2] = (char)SC_WILDC; 3148 ut.ut_id[3] = (char)SC_WILDC; 3149 ut.ut_type = LOGIN_PROCESS; 3150 ut.ut_exit.e_termination = 0; 3151 ut.ut_exit.e_exit = 0; 3152 (void) time(&ut.ut_tv.tv_sec); 3153 if (makeutx(&ut) == NULL) 3154 syslog(LOG_INFO, "in.telnetd:\tmakeutx failed"); 3155 } 3156 3157 /* 3158 * Load in the cached environment variables and either 3159 * set/unset them in the environment. 3160 */ 3161 for (next = envlist_head; next; ) { 3162 env = next; 3163 if (env->delete) 3164 (void) local_unsetenv(env->name); 3165 else 3166 (void) local_setenv(env->name, env->value, 1); 3167 free(env->name); 3168 free(env->value); 3169 next = env->next; 3170 free(env); 3171 } 3172 3173 if (!username || !username[0]) 3174 auth_status = AUTH_REJECT; /* we dont know who this is */ 3175 3176 /* If the current auth status is less than the required level, exit */ 3177 if (auth_status < auth_level) { 3178 fatal(net, "Authentication failed\n"); 3179 exit(EXIT_FAILURE); 3180 } 3181 3182 /* 3183 * If AUTH_VALID (proper authentication REQUIRED and we have 3184 * a krb5_name), exec '/bin/login', make sure it uses the 3185 * correct PAM service name (pam_svc_name). If possible, 3186 * make sure the krb5 authenticated user's name (krb5_name) 3187 * is in the PAM REPOSITORY for krb5. 3188 */ 3189 if (auth_level >= 0 && 3190 (auth_status == AUTH_VALID || auth_status == AUTH_USER) && 3191 ((krb5_name != NULL) && strlen(krb5_name)) && 3192 ((AuthenticatingUser != NULL) && strlen(AuthenticatingUser))) { 3193 (void) execl(LOGIN_PROGRAM, "login", 3194 "-p", 3195 "-d", slavename, 3196 "-h", host, 3197 "-u", krb5_name, 3198 "-s", pam_svc_name, 3199 "-R", KRB5_REPOSITORY_NAME, 3200 AuthenticatingUser, 0); 3201 } else if (auth_level >= 0 && 3202 auth_status >= AUTH_USER && 3203 (((AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) || 3204 getenv("USER"))) { 3205 /* 3206 * If we only know the name but not the principal, 3207 * login will have to authenticate further. 3208 */ 3209 (void) execl(LOGIN_PROGRAM, "login", 3210 "-p", 3211 "-d", slavename, 3212 "-h", host, 3213 "-s", pam_svc_name, "--", 3214 (AuthenticatingUser != NULL ? AuthenticatingUser : 3215 getenv("USER")), 0); 3216 3217 } else /* default, no auth. info available, login does it all */ { 3218 (void) execl(LOGIN_PROGRAM, "login", 3219 "-p", "-h", host, "-d", slavename, "--", 3220 getenv("USER"), 0); 3221 } 3222 3223 fatalperror(netfd, LOGIN_PROGRAM, errno); 3224 /*NOTREACHED*/ 3225 } 3226 3227 static void 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 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 3257 telnet(int net, int master) 3258 { 3259 int on = 1; 3260 char mode; 3261 struct strioctl telnetmod; 3262 int nsize = 0; 3263 char binary_in = 0; 3264 char binary_out = 0; 3265 3266 if (ioctl(net, FIONBIO, &on) == -1) 3267 syslog(LOG_INFO, "ioctl FIONBIO net: %m\n"); 3268 if (ioctl(master, FIONBIO, &on) == -1) 3269 syslog(LOG_INFO, "ioctl FIONBIO pty p: %m\n"); 3270 (void) signal(SIGTSTP, SIG_IGN); 3271 (void) signal(SIGCHLD, (void (*)())cleanup); 3272 (void) setpgrp(); 3273 3274 /* 3275 * Call telrcv() once to pick up anything received during 3276 * terminal type negotiation. 3277 */ 3278 telrcv(); 3279 3280 netflush(); 3281 ptyflush(); 3282 3283 for (;;) { 3284 fd_set ibits, obits, xbits; 3285 int c; 3286 3287 if (ncc < 0) 3288 break; 3289 3290 FD_ZERO(&ibits); 3291 FD_ZERO(&obits); 3292 FD_ZERO(&xbits); 3293 3294 /* 3295 * If we couldn't flush all our output to the network, 3296 * keep checking for when we can. 3297 */ 3298 if (nfrontp - nbackp) 3299 FD_SET(net, &obits); 3300 /* 3301 * Never look for input if there's still 3302 * stuff in the corresponding output buffer 3303 */ 3304 if (pfrontp - pbackp) { 3305 FD_SET(master, &obits); 3306 } else { 3307 FD_SET(net, &ibits); 3308 } 3309 if (!SYNCHing) { 3310 FD_SET(net, &xbits); 3311 } 3312 3313 #define max(x, y) (((x) < (y)) ? (y) : (x)) 3314 3315 /* 3316 * make an ioctl to telnet module (net side) to send 3317 * binary mode of telnet daemon. binary_in and 3318 * binary_out are 0 if not in binary mode. 3319 */ 3320 if (binary_in != myopts[TELOPT_BINARY] || 3321 binary_out != remopts[TELOPT_BINARY]) { 3322 3323 mode = 0; 3324 if (myopts[TELOPT_BINARY] != OPT_NO) 3325 mode |= TEL_BINARY_IN; 3326 3327 if (remopts[TELOPT_BINARY] != OPT_NO) 3328 mode |= TEL_BINARY_OUT; 3329 3330 telnetmod.ic_cmd = TEL_IOC_MODE; 3331 telnetmod.ic_timout = -1; 3332 telnetmod.ic_len = 1; 3333 telnetmod.ic_dp = &mode; 3334 3335 syslog(LOG_DEBUG, "TEL_IOC_MODE binary has changed\n"); 3336 3337 if (ioctl(net, I_STR, &telnetmod) < 0) 3338 fatal(net, "ioctl TEL_IOC_MODE failed\n"); 3339 binary_in = myopts[TELOPT_BINARY]; 3340 binary_out = remopts[TELOPT_BINARY]; 3341 } 3342 if (state == TS_DATA) { 3343 if ((nfrontp == nbackp) && 3344 (pfrontp == pbackp)) { 3345 if (ioctl(net, I_NREAD, &nsize) < 0) 3346 fatalperror(net, 3347 "ioctl I_NREAD failed\n", errno); 3348 if (nsize) 3349 drainstream(nsize); 3350 3351 /* 3352 * make an ioctl to reinsert remaining data at 3353 * streamhead. After this, ioctl reenables the 3354 * telnet lower put queue. This queue was 3355 * noenabled by telnet module after sending 3356 * protocol/urgent data to telnetd. 3357 */ 3358 3359 telnetmod.ic_cmd = TEL_IOC_ENABLE; 3360 telnetmod.ic_timout = -1; 3361 if (ncc || nsize) { 3362 telnetmod.ic_len = ncc + nsize; 3363 telnetmod.ic_dp = netip; 3364 } else { 3365 telnetmod.ic_len = 0; 3366 telnetmod.ic_dp = NULL; 3367 } 3368 if (ioctl(net, I_STR, &telnetmod) < 0) 3369 fatal(net, "ioctl TEL_IOC_ENABLE \ 3370 failed\n"); 3371 3372 telmod_init_done = B_TRUE; 3373 3374 netip = netibuf; 3375 (void) memset(netibuf, 0, netibufsize); 3376 3377 ncc = 0; 3378 } 3379 } else { 3380 /* 3381 * state not changed to TS_DATA and hence, more to read 3382 * send ioctl to get one more message block. 3383 */ 3384 telnetmod.ic_cmd = TEL_IOC_GETBLK; 3385 telnetmod.ic_timout = -1; 3386 telnetmod.ic_len = 0; 3387 telnetmod.ic_dp = NULL; 3388 3389 if (ioctl(net, I_STR, &telnetmod) < 0) 3390 fatal(net, "ioctl TEL_IOC_GETBLK failed\n"); 3391 } 3392 3393 if ((c = select(max(net, master) + 1, &ibits, &obits, &xbits, 3394 (struct timeval *)0)) < 1) { 3395 if (c == -1) { 3396 if (errno == EINTR) { 3397 continue; 3398 } 3399 } 3400 (void) sleep(5); 3401 continue; 3402 } 3403 3404 /* 3405 * Any urgent data? 3406 */ 3407 if (FD_ISSET(net, &xbits)) { 3408 SYNCHing = 1; 3409 } 3410 3411 /* 3412 * Something to read from the network... 3413 */ 3414 if (FD_ISSET(net, &ibits)) { 3415 ncc = read(net, netibuf, netibufsize); 3416 if (ncc < 0 && errno == EWOULDBLOCK) 3417 ncc = 0; 3418 else { 3419 if (ncc <= 0) { 3420 break; 3421 } 3422 netip = netibuf; 3423 } 3424 } 3425 3426 if (FD_ISSET(net, &obits) && (nfrontp - nbackp) > 0) 3427 netflush(); 3428 if (ncc > 0) 3429 telrcv(); 3430 if (FD_ISSET(master, &obits) && (pfrontp - pbackp) > 0) 3431 ptyflush(); 3432 } 3433 cleanup(0); 3434 } 3435 3436 static void 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 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 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 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 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 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 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 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 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 4277 ptyflush(void) 4278 { 4279 int n; 4280 4281 if ((n = pfrontp - pbackp) > 0) 4282 n = write(master, 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 * 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 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 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 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 * "master" in that order. We do close(net) first because 4451 * we have no other way to disconnect forwarding between the network 4452 * and master. 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(master); 4464 } 4465 rmut(); 4466 4467 exit(EXIT_FAILURE); 4468 } 4469 4470 static 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 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 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 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 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 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 * 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 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 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 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 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 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 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