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 2007 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 #pragma ident "%Z%%M% %I% %E% SMI" 43 44 /* 45 * Telnet server. 46 */ 47 #include <sys/types.h> 48 #include <sys/param.h> 49 #include <sys/socket.h> 50 #include <sys/wait.h> 51 #include <sys/file.h> 52 #include <sys/stat.h> 53 #include <sys/filio.h> 54 #include <sys/time.h> 55 #include <sys/stropts.h> 56 #include <sys/stream.h> 57 #include <sys/tihdr.h> 58 #include <sys/utsname.h> 59 #include <unistd.h> 60 61 #include <netinet/in.h> 62 63 #define AUTHWHO_STR 64 #define AUTHTYPE_NAMES 65 #define AUTHHOW_NAMES 66 #define AUTHRSP_NAMES 67 #define ENCRYPT_NAMES 68 69 #include <arpa/telnet.h> 70 #include <arpa/inet.h> 71 #include <stdio.h> 72 #include <stdarg.h> 73 #include <signal.h> 74 #include <errno.h> 75 #include <netdb.h> 76 #include <syslog.h> 77 #include <ctype.h> 78 #include <fcntl.h> 79 #include <sac.h> /* for SC_WILDC */ 80 #include <utmpx.h> 81 #include <sys/ttold.h> 82 #include <malloc.h> 83 #include <string.h> 84 #include <security/pam_appl.h> 85 #include <sys/tihdr.h> 86 #include <sys/logindmux.h> 87 #include <sys/telioctl.h> 88 #include <deflt.h> 89 #include <stdlib.h> 90 #include <string.h> 91 #include <stropts.h> 92 #include <termios.h> 93 94 #include <com_err.h> 95 #include <krb5.h> 96 #include <krb5_repository.h> 97 #include <des/des.h> 98 #include <rpc/des_crypt.h> 99 #include <sys/cryptmod.h> 100 #include <bsm/adt.h> 101 102 #define TELNETD_OPTS "Ss:a:dEXUhR:M:" 103 #ifdef DEBUG 104 #define DEBUG_OPTS "p:e" 105 #else 106 #define DEBUG_OPTS "" 107 #endif /* DEBUG */ 108 109 #define OPT_NO 0 /* won't do this option */ 110 #define OPT_YES 1 /* will do this option */ 111 #define OPT_YES_BUT_ALWAYS_LOOK 2 112 #define OPT_NO_BUT_ALWAYS_LOOK 3 113 114 #define MAXOPTLEN 256 115 #define MAXUSERNAMELEN 256 116 117 static char remopts[MAXOPTLEN]; 118 static char myopts[MAXOPTLEN]; 119 static uchar_t doopt[] = { (uchar_t)IAC, (uchar_t)DO, '%', 'c', 0 }; 120 static uchar_t dont[] = { (uchar_t)IAC, (uchar_t)DONT, '%', 'c', 0 }; 121 static uchar_t will[] = { (uchar_t)IAC, (uchar_t)WILL, '%', 'c', 0 }; 122 static uchar_t wont[] = { (uchar_t)IAC, (uchar_t)WONT, '%', 'c', 0 }; 123 /* 124 * I/O data buffers, pointers, and counters. 125 */ 126 static char ptyobuf[BUFSIZ], *pfrontp = ptyobuf, *pbackp = ptyobuf; 127 128 static char *netibuf, *netip; 129 static int netibufsize; 130 131 #define NIACCUM(c) { *netip++ = c; \ 132 ncc++; \ 133 } 134 135 static char netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf; 136 static char *neturg = 0; /* one past last bye of urgent data */ 137 /* the remote system seems to NOT be an old 4.2 */ 138 static int not42 = 1; 139 static char defaultfile[] = "/etc/default/telnetd"; 140 static char bannervar[] = "BANNER="; 141 142 static char BANNER1[] = "\r\n\r\n"; 143 static char BANNER2[] = "\r\n\r\0\r\n\r\0"; 144 145 /* 146 * buffer for sub-options - enlarged to 4096 to handle credentials 147 * from AUTH options 148 */ 149 static char subbuffer[4096], *subpointer = subbuffer, *subend = subbuffer; 150 #define SB_CLEAR() subpointer = subbuffer; 151 #define SB_TERM() { subend = subpointer; SB_CLEAR(); } 152 #define SB_ACCUM(c) if (subpointer < (subbuffer+sizeof (subbuffer))) { \ 153 *subpointer++ = (c); \ 154 } 155 #define SB_GET() ((*subpointer++)&0xff) 156 #define SB_EOF() (subpointer >= subend) 157 #define SB_LEN() (subend - subpointer) 158 159 #define MAXCCACHENAMELEN 36 160 #define MAXERRSTRLEN 1024 161 #define MAXPRINCLEN 256 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[MAXCCACHENAMELEN]; 469 krb5_ccache ccache = NULL; 470 471 if (retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL)) 472 return (retval); 473 474 (void) sprintf(ccname, "FILE:/tmp/krb5cc_p%ld", getpid()); 475 (void) krb5_setenv("KRB5CCNAME", ccname, 1); 476 477 if ((retval = krb5_cc_default(context, &ccache))) 478 goto cleanup; 479 480 if ((retval = krb5_cc_initialize(context, ccache, 481 ticket->enc_part2->client)) != 0) 482 goto cleanup; 483 484 if ((retval = krb5_cc_store_cred(context, ccache, *creds)) != 0) 485 goto cleanup; 486 487 if ((retval = krb5_cc_close(context, ccache)) != 0) 488 goto cleanup; 489 490 if (username != NULL) { 491 /* 492 * This verifies that the user is valid on the local system, 493 * maps the username from KerberosV5 to unix, 494 * and moves the KRB5CCNAME file to the correct place 495 * /tmp/krb5cc_[uid] with correct ownership (0600 uid gid). 496 * 497 * NOTE: the user must be in the gsscred table in order to map 498 * from KRB5 to Unix. 499 */ 500 (void) krb5_kuserok(context, ticket->enc_part2->client, 501 username); 502 } 503 if (auth_debug) 504 (void) fprintf(stderr, 505 "Successfully stored forwarded creds\n"); 506 507 cleanup: 508 krb5_free_creds(context, *creds); 509 return (retval); 510 } 511 512 static void 513 kerberos5_is(AuthInfo *ap, uchar_t *data, int cnt) 514 { 515 krb5_error_code err = 0; 516 krb5_principal server; 517 krb5_keyblock *newkey = NULL; 518 krb5_keytab keytabid = 0; 519 krb5_data outbuf; 520 krb5_data inbuf; 521 krb5_authenticator *authenticator; 522 char errbuf[MAXERRSTRLEN]; 523 char *name; 524 krb5_data auth; 525 526 Session_Key skey; 527 528 if (cnt-- < 1) 529 return; 530 switch (*data++) { 531 case KRB_AUTH: 532 auth.data = (char *)data; 533 auth.length = cnt; 534 535 if (auth_context == NULL) { 536 err = krb5_auth_con_init(telnet_context, &auth_context); 537 if (err) 538 syslog(LOG_ERR, 539 "Error getting krb5 auth " 540 "context: %s", error_message(err)); 541 } 542 if (!err) { 543 krb5_rcache rcache; 544 545 err = krb5_auth_con_getrcache(telnet_context, 546 auth_context, 547 &rcache); 548 if (!err && !rcache) { 549 err = krb5_sname_to_principal(telnet_context, 550 0, 0, 551 KRB5_NT_SRV_HST, 552 &server); 553 if (!err) { 554 err = krb5_get_server_rcache( 555 telnet_context, 556 krb5_princ_component( 557 telnet_context, 558 server, 0), 559 &rcache); 560 561 krb5_free_principal(telnet_context, 562 server); 563 } 564 } 565 if (err) 566 syslog(LOG_ERR, 567 "Error allocating krb5 replay cache: %s", 568 error_message(err)); 569 else { 570 err = krb5_auth_con_setrcache(telnet_context, 571 auth_context, 572 rcache); 573 if (err) 574 syslog(LOG_ERR, 575 "Error creating krb5 " 576 "replay cache: %s", 577 error_message(err)); 578 } 579 } 580 if (!err && telnet_srvtab != NULL) 581 err = krb5_kt_resolve(telnet_context, 582 telnet_srvtab, &keytabid); 583 if (!err) 584 err = krb5_rd_req(telnet_context, &auth_context, &auth, 585 NULL, keytabid, NULL, &ticket); 586 if (err) { 587 (void) snprintf(errbuf, sizeof (errbuf), 588 "Error reading krb5 auth information:" 589 " %s", error_message(err)); 590 goto errout; 591 } 592 593 /* 594 * Verify that the correct principal was used 595 */ 596 if (krb5_princ_component(telnet_context, 597 ticket->server, 0)->length < MAXPRINCLEN) { 598 char princ[MAXPRINCLEN]; 599 (void) strncpy(princ, 600 krb5_princ_component(telnet_context, 601 ticket->server, 0)->data, 602 krb5_princ_component(telnet_context, 603 ticket->server, 0)->length); 604 princ[krb5_princ_component(telnet_context, 605 ticket->server, 0)->length] = '\0'; 606 if (strcmp("host", princ)) { 607 if (strlen(princ) < sizeof (errbuf) - 39) { 608 (void) snprintf(errbuf, sizeof (errbuf), 609 "incorrect service " 610 "name: \"%s\" != " 611 "\"host\"", 612 princ); 613 } else { 614 (void) strncpy(errbuf, 615 "incorrect service " 616 "name: principal != " 617 "\"host\"", 618 sizeof (errbuf)); 619 } 620 goto errout; 621 } 622 } else { 623 (void) strlcpy(errbuf, "service name too long", 624 sizeof (errbuf)); 625 goto errout; 626 } 627 628 err = krb5_auth_con_getauthenticator(telnet_context, 629 auth_context, 630 &authenticator); 631 if (err) { 632 (void) snprintf(errbuf, sizeof (errbuf), 633 "Failed to get authenticator: %s", 634 error_message(err)); 635 goto errout; 636 } 637 if ((ap->AuthHow & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON && 638 !authenticator->checksum) { 639 (void) strlcpy(errbuf, 640 "authenticator is missing checksum", 641 sizeof (errbuf)); 642 goto errout; 643 } 644 if (authenticator->checksum) { 645 char type_check[2]; 646 krb5_checksum *cksum = authenticator->checksum; 647 krb5_keyblock *key; 648 krb5_data input; 649 krb5_boolean valid; 650 651 type_check[0] = ap->AuthName; 652 type_check[1] = ap->AuthHow; 653 654 err = krb5_auth_con_getkey(telnet_context, 655 auth_context, &key); 656 if (err) { 657 (void) snprintf(errbuf, sizeof (errbuf), 658 "Failed to get key from " 659 "authenticator: %s", 660 error_message(err)); 661 goto errout; 662 } 663 664 input.data = type_check; 665 input.length = 2; 666 err = krb5_c_verify_checksum(telnet_context, 667 key, 0, 668 &input, 669 cksum, 670 &valid); 671 if (!err && !valid) 672 err = KRB5KRB_AP_ERR_BAD_INTEGRITY; 673 674 if (err) { 675 (void) snprintf(errbuf, sizeof (errbuf), 676 "Kerberos checksum " 677 "verification failed: " 678 "%s", 679 error_message(err)); 680 goto errout; 681 } 682 krb5_free_keyblock(telnet_context, key); 683 } 684 685 krb5_free_authenticator(telnet_context, authenticator); 686 if ((ap->AuthHow & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 687 /* do ap_rep stuff here */ 688 if ((err = krb5_mk_rep(telnet_context, auth_context, 689 &outbuf))) { 690 (void) snprintf(errbuf, sizeof (errbuf), 691 "Failed to make " 692 "Kerberos auth reply: " 693 "%s", 694 error_message(err)); 695 goto errout; 696 } 697 reply_to_client(ap, KRB_RESPONSE, outbuf.data, 698 outbuf.length); 699 } 700 if (krb5_unparse_name(telnet_context, 701 ticket->enc_part2->client, 702 &name)) 703 name = 0; 704 reply_to_client(ap, KRB_ACCEPT, name, name ? -1 : 0); 705 if (auth_debug) { 706 syslog(LOG_NOTICE, 707 "\tKerberos5 identifies user as ``%s''\r\n", 708 name ? name : ""); 709 } 710 if (name != NULL) { 711 krb5_name = (char *)strdup(name); 712 } 713 auth_finished(ap, AUTH_USER); 714 715 if (name != NULL) 716 free(name); 717 krb5_auth_con_getremotesubkey(telnet_context, auth_context, 718 &newkey); 719 if (session_key != NULL) { 720 krb5_free_keyblock(telnet_context, session_key); 721 session_key = 0; 722 } 723 if (newkey != NULL) { 724 krb5_copy_keyblock(telnet_context, 725 newkey, &session_key); 726 krb5_free_keyblock(telnet_context, newkey); 727 } else { 728 krb5_copy_keyblock(telnet_context, 729 ticket->enc_part2->session, 730 &session_key); 731 } 732 733 /* 734 * Initialize encryption stuff. Currently, we are only 735 * supporting 8 byte keys and blocks. Check for this later. 736 */ 737 skey.type = SK_DES; 738 skey.length = DES_BLOCKSIZE; 739 skey.data = session_key->contents; 740 encrypt_session_key(&skey, &encr_data.encrypt); 741 encrypt_session_key(&skey, &encr_data.decrypt); 742 break; 743 case KRB_FORWARD: 744 inbuf.length = cnt; 745 inbuf.data = (char *)data; 746 if (auth_debug) 747 (void) fprintf(stderr, 748 "RCVD KRB_FORWARD data (%d bytes)\n", cnt); 749 750 if (auth_context != NULL) { 751 krb5_rcache rcache; 752 753 err = krb5_auth_con_getrcache(telnet_context, 754 auth_context, &rcache); 755 if (!err && !rcache) { 756 err = krb5_sname_to_principal(telnet_context, 757 0, 0, KRB5_NT_SRV_HST, &server); 758 if (!err) { 759 err = krb5_get_server_rcache( 760 telnet_context, 761 krb5_princ_component( 762 telnet_context, 763 server, 0), 764 &rcache); 765 krb5_free_principal(telnet_context, 766 server); 767 } 768 } 769 if (err) { 770 syslog(LOG_ERR, 771 "Error allocating krb5 replay cache: %s", 772 error_message(err)); 773 } else { 774 err = krb5_auth_con_setrcache(telnet_context, 775 auth_context, rcache); 776 if (err) 777 syslog(LOG_ERR, 778 "Error creating krb5 replay cache:" 779 " %s", 780 error_message(err)); 781 } 782 } 783 /* 784 * Use the 'rsaddr' and 'rsport' (remote service addr/port) 785 * from the original connection. This data is used to 786 * verify the forwarded credentials. 787 */ 788 if (!(err = krb5_auth_con_setaddrs(telnet_context, auth_context, 789 NULL, &rsaddr))) 790 err = krb5_auth_con_setports(telnet_context, 791 auth_context, NULL, &rsport); 792 793 if (err == 0) 794 /* 795 * If all is well, store the forwarded creds in 796 * the users local credential cache. 797 */ 798 err = rd_and_store_forwarded_creds(telnet_context, 799 auth_context, &inbuf, 800 ticket, 801 AuthenticatingUser); 802 if (err) { 803 (void) snprintf(errbuf, sizeof (errbuf), 804 "Read forwarded creds failed: %s", 805 error_message(err)); 806 syslog(LOG_ERR, "%s", errbuf); 807 808 reply_to_client(ap, KRB_FORWARD_REJECT, errbuf, -1); 809 if (auth_debug) 810 (void) fprintf(stderr, 811 "\tCould not read " 812 "forwarded credentials\r\n"); 813 } else 814 reply_to_client(ap, KRB_FORWARD_ACCEPT, (void *) 0, 0); 815 816 if (rsaddr.contents != NULL) 817 free(rsaddr.contents); 818 819 if (rsport.contents != NULL) 820 free(rsport.contents); 821 822 if (auth_debug) 823 (void) fprintf(stderr, "\tForwarded " 824 "credentials obtained\r\n"); 825 break; 826 default: 827 if (auth_debug) 828 (void) fprintf(stderr, 829 "\tUnknown Kerberos option %d\r\n", 830 data[-1]); 831 reply_to_client(ap, KRB_REJECT, (void *) 0, 0); 832 break; 833 } 834 return; 835 836 errout: 837 reply_to_client(ap, KRB_REJECT, errbuf, -1); 838 839 if (auth_debug) 840 (void) fprintf(stderr, "\tKerberos V5 error: %s\r\n", errbuf); 841 842 syslog(LOG_ERR, "%s", errbuf); 843 844 if (auth_context != NULL) { 845 krb5_auth_con_free(telnet_context, auth_context); 846 auth_context = 0; 847 } 848 } 849 850 static int 851 krb5_init() 852 { 853 int code = 0; 854 855 if (telnet_context == NULL) { 856 code = krb5_init_context(&telnet_context); 857 if (code != 0 && auth_debug) 858 syslog(LOG_NOTICE, 859 "Cannot initialize Kerberos V5: %s", 860 error_message(code)); 861 } 862 863 return (code); 864 } 865 866 static void 867 auth_name(uchar_t *data, int cnt) 868 { 869 char namebuf[MAXPRINCLEN]; 870 871 if (cnt < 1) { 872 if (auth_debug) 873 (void) fprintf(stderr, 874 "\t(auth_name) Empty NAME in auth " 875 "reply\n"); 876 return; 877 } 878 if (cnt > sizeof (namebuf)-1) { 879 if (auth_debug) 880 (void) fprintf(stderr, 881 "\t(auth_name) NAME exceeds %d bytes\n", 882 sizeof (namebuf)-1); 883 return; 884 } 885 (void) memcpy((void *)namebuf, (void *)data, cnt); 886 namebuf[cnt] = 0; 887 if (auth_debug) 888 (void) fprintf(stderr, "\t(auth_name) name [%s]\n", namebuf); 889 AuthenticatingUser = (char *)strdup(namebuf); 890 } 891 892 static void 893 auth_is(uchar_t *data, int cnt) 894 { 895 AuthInfo *aptr = auth_list; 896 897 if (cnt < 2) 898 return; 899 900 /* 901 * We failed to negoiate secure authentication 902 */ 903 if (data[0] == AUTHTYPE_NULL) { 904 auth_finished(0, AUTH_REJECT); 905 return; 906 } 907 908 while (aptr->AuthName != NULL && 909 (aptr->AuthName != data[0] || aptr->AuthHow != data[1])) 910 aptr++; 911 912 if (aptr != NULL) { 913 if (auth_debug) 914 (void) fprintf(stderr, "\t(auth_is) auth type is %s " 915 "(%d bytes)\n", aptr->AuthString, cnt); 916 917 if (aptr->AuthName == AUTHTYPE_KERBEROS_V5) 918 kerberos5_is(aptr, data+2, cnt-2); 919 } 920 } 921 922 static int 923 krb5_user_status(char *name, int namelen, int level) 924 { 925 int retval = AUTH_USER; 926 927 if (auth_debug) 928 (void) fprintf(stderr, "\t(krb5_user_status) level = %d " 929 "auth_level = %d user = %s\n", 930 level, auth_level, 931 (AuthenticatingUser != NULL ? AuthenticatingUser : "")); 932 933 if (level < AUTH_USER) 934 return (level); 935 936 if (AuthenticatingUser != NULL && 937 (retval = krb5_kuserok(telnet_context, ticket->enc_part2->client, 938 AuthenticatingUser))) { 939 (void) strncpy(name, AuthenticatingUser, namelen); 940 return (AUTH_VALID); 941 } else { 942 if (!retval) 943 syslog(LOG_ERR, 944 "Krb5 principal lacks permission to " 945 "access local account for %s", 946 AuthenticatingUser); 947 return (AUTH_USER); 948 } 949 } 950 951 /* 952 * Wrapper around /dev/urandom 953 */ 954 static int 955 getrandom(char *buf, int buflen) 956 { 957 static int devrandom = -1; 958 959 if (devrandom == -1 && 960 (devrandom = open("/dev/urandom", O_RDONLY)) == -1) { 961 fatalperror(net, "Unable to open /dev/urandom: ", 962 errno); 963 return (-1); 964 } 965 966 if (read(devrandom, buf, buflen) == -1) { 967 fatalperror(net, "Unable to read from /dev/urandom: ", 968 errno); 969 return (-1); 970 } 971 972 return (0); 973 } 974 975 /* 976 * encrypt_init 977 * 978 * Initialize the encryption data structures 979 */ 980 static void 981 encrypt_init() 982 { 983 (void) memset(&encr_data.encrypt, 0, sizeof (cipher_info_t)); 984 (void) memset(&encr_data.decrypt, 0, sizeof (cipher_info_t)); 985 986 encr_data.encrypt.state = ENCR_STATE_NOT_READY; 987 encr_data.decrypt.state = ENCR_STATE_NOT_READY; 988 } 989 990 /* 991 * encrypt_send_request_start 992 * 993 * Request that the remote side automatically start sending 994 * encrypted output 995 */ 996 static void 997 encrypt_send_request_start() 998 { 999 uchar_t buf[6+TELNET_MAXKEYIDLEN], *p; 1000 1001 p = buf; 1002 1003 *p++ = IAC; 1004 *p++ = SB; 1005 *p++ = TELOPT_ENCRYPT; 1006 *p++ = ENCRYPT_REQSTART; 1007 /* 1008 * We are telling the remote side which 1009 * decrypt key we will use so that it may 1010 * encrypt in the same key. 1011 */ 1012 (void) memcpy(p, encr_data.decrypt.keyid, encr_data.decrypt.keyidlen); 1013 p += encr_data.decrypt.keyidlen; 1014 1015 *p++ = IAC; 1016 *p++ = SE; 1017 1018 write_data_len((const char *)buf, p-buf); 1019 netflush(); 1020 if (enc_debug) 1021 (void) fprintf(stderr, 1022 "SENT TELOPT_ENCRYPT ENCRYPT_REQSTART\n"); 1023 } 1024 1025 /* 1026 * encrypt_is 1027 * 1028 * When we receive the TELOPT_ENCRYPT ENCRYPT_IS ... 1029 * message, the client is telling us that it will be sending 1030 * encrypted data using the indicated cipher. 1031 * We must initialize the read (decrypt) side of our connection 1032 */ 1033 static void 1034 encrypt_is(uchar_t *data, int cnt) 1035 { 1036 register int type; 1037 register int iv_status = CFB64_IV_OK; 1038 register int lstate = 0; 1039 1040 uchar_t sbbuf[] = { 1041 (uchar_t)IAC, 1042 (uchar_t)SB, 1043 (uchar_t)TELOPT_ENCRYPT, 1044 (uchar_t)ENCRYPT_REPLY, 1045 (uchar_t)0, /* placeholder: sbbuf[4] */ 1046 (uchar_t)CFB64_IV_OK, /* placeholder: sbbuf[5] */ 1047 (uchar_t)IAC, 1048 (uchar_t)SE, 1049 }; 1050 1051 if (--cnt < 0) 1052 return; 1053 1054 type = sbbuf[4] = *data++; 1055 1056 /* 1057 * Steps to take: 1058 * 1. Create the proper stream Initialization vector 1059 * - copy the correct 'seed' to IV and output blocks 1060 * - set the correct key schedule 1061 * 2. Generate reply for the other side: 1062 * IAC SB TELOPT_ENCRYPT ENCRYPT_REPLY type CFB64_IV_OK 1063 * [ data ... ] IAC SE 1064 * 3. Tell crypto module: method, direction, IV 1065 */ 1066 switch (type) { 1067 case TELOPT_ENCTYPE_DES_CFB64: 1068 encr_data.decrypt.type = type; 1069 1070 lstate = encr_data.decrypt.state; 1071 if (enc_debug) 1072 (void) fprintf(stderr, 1073 "\t(encrypt_is) initial state = %d\n", 1074 lstate); 1075 /* 1076 * Before we extract the IV bytes, make sure we got 1077 * enough data. 1078 */ 1079 if (cnt < sizeof (Block)) { 1080 iv_status = CFB64_IV_BAD; 1081 if (enc_debug) 1082 (void) fprintf(stderr, 1083 "\t(encrypt_is) Not enough " 1084 "IV bytes\n"); 1085 lstate = ENCR_STATE_NOT_READY; 1086 } else { 1087 data++; /* skip over the CFB64_IV byte */ 1088 (void) memcpy(encr_data.decrypt.ivec, data, 1089 sizeof (Block)); 1090 lstate = ENCR_STATE_IN_PROGRESS; 1091 } 1092 break; 1093 case TELOPT_ENCTYPE_NULL: 1094 encr_data.decrypt.type = type; 1095 lstate &= ~ENCR_STATE_NO_RECV_IV; 1096 lstate &= ~ENCR_STATE_NO_SEND_IV; 1097 if (enc_debug) 1098 (void) fprintf(stderr, 1099 "\t(encrypt_is) We accept NULL encr\n"); 1100 break; 1101 default: 1102 iv_status = CFB64_IV_BAD; 1103 encr_data.decrypt.type = NULL; 1104 if (enc_debug) 1105 (void) fprintf(stderr, 1106 "\t(encrypt_is) Can't find type (%d) " 1107 "for initial negotiation\r\n", 1108 type); 1109 lstate = ENCR_STATE_NOT_READY; 1110 break; 1111 } 1112 1113 sbbuf[5] = (uchar_t)iv_status; /* either CFB64_IV_OK or BAD */ 1114 1115 if (iv_status == CFB64_IV_OK) { 1116 /* 1117 * send IV to crypto module and indicate it is for 1118 * decrypt only 1119 */ 1120 lstate &= ~ENCR_STATE_NO_RECV_IV; /* we received an OK IV */ 1121 lstate &= ~ENCR_STATE_NO_SEND_IV; /* we dont send an IV */ 1122 } else { 1123 /* tell crypto module to disable crypto on "read" stream */ 1124 lstate = ENCR_STATE_NOT_READY; 1125 } 1126 1127 write_data_len((const char *)sbbuf, sizeof (sbbuf)); 1128 netflush(); 1129 #ifdef ENCRYPT_NAMES 1130 if (enc_debug) 1131 (void) fprintf(stderr, 1132 "SENT TELOPT_ENCRYPT ENCRYPT_REPLY %s %s\n", 1133 ENCTYPE_NAME(type), 1134 (iv_status == CFB64_IV_OK ? "CFB64_IV_OK" : 1135 "CFB64_IV_BAD")); 1136 #endif /* ENCRYPT_NAMES */ 1137 /* Update the state of the decryption negotiation */ 1138 encr_data.decrypt.state = lstate; 1139 1140 if (lstate == ENCR_STATE_NOT_READY) 1141 encr_data.decrypt.autoflag = 0; 1142 else { 1143 if (lstate == ENCR_STATE_OK && encr_data.decrypt.autoflag) 1144 encrypt_send_request_start(); 1145 } 1146 if (enc_debug) 1147 (void) fprintf(stderr, 1148 "\t(encrypt_is) final DECRYPT state = %d\n", 1149 encr_data.decrypt.state); 1150 } 1151 1152 /* 1153 * encrypt_send_encrypt_is 1154 * 1155 * Tell the client what encryption we will use 1156 * and what our IV will be. 1157 */ 1158 static int 1159 encrypt_send_encrypt_is() 1160 { 1161 register int lstate; 1162 krb5_error_code kret; 1163 uchar_t sbbuf[MAXOPTLEN], *p; 1164 int i; 1165 1166 lstate = encr_data.encrypt.state; 1167 1168 if (encr_data.encrypt.type == ENCTYPE_NULL) { 1169 /* 1170 * Haven't received ENCRYPT SUPPORT yet or we couldn't agree 1171 * on a cipher. 1172 */ 1173 return (lstate); 1174 } 1175 1176 /* 1177 * - Create a random DES key 1178 * 1179 * - DES ECB encrypt 1180 * encrypt the IV using itself as the key. 1181 * 1182 * - Send response 1183 * IAC SB TELOPT_ENCRYPT ENCRYPT_IS CFB64 FB64_IV [ feed block ] 1184 * IAC SE 1185 * 1186 */ 1187 if (lstate == ENCR_STATE_NOT_READY) 1188 lstate = ENCR_STATE_IN_PROGRESS; 1189 else if ((lstate & ENCR_STATE_NO_SEND_IV) == 0) { 1190 if (enc_debug) 1191 (void) fprintf(stderr, 1192 "\t(encrypt_send_is) IV already sent," 1193 " state = %d\n", lstate); 1194 return (lstate); 1195 } 1196 1197 if (!VALIDKEY(encr_data.encrypt.krbdes_key)) { 1198 /* 1199 * Invalid key, set flag so we try again later 1200 * when we get a good one 1201 */ 1202 encr_data.encrypt.need_start = 1; 1203 if (enc_debug) 1204 (void) fprintf(stderr, 1205 "\t(encrypt_send_is) No Key, cannot " 1206 "start encryption yet\n"); 1207 return (lstate); 1208 } 1209 if (enc_debug) 1210 (void) fprintf(stderr, 1211 "\t(encrypt_send_is) Creating new feed\n"); 1212 1213 /* 1214 * Create a random feed and send it over. 1215 * 1216 * Use the /dev/[u]random interface to generate 1217 * our encryption IV. 1218 */ 1219 kret = getrandom((char *)encr_data.encrypt.ivec, sizeof (Block)); 1220 1221 if (kret) { 1222 if (enc_debug) 1223 (void) fprintf(stderr, 1224 "\t(encrypt_send_is) error from " 1225 "getrandom: %d\n", kret); 1226 syslog(LOG_ERR, "Failed to create encryption key (err %d)\n"); 1227 encr_data.encrypt.type = ENCTYPE_NULL; 1228 } else { 1229 mit_des_fixup_key_parity(encr_data.encrypt.ivec); 1230 } 1231 1232 p = sbbuf; 1233 *p++ = IAC; 1234 *p++ = SB; 1235 *p++ = TELOPT_ENCRYPT; 1236 *p++ = ENCRYPT_IS; 1237 *p++ = encr_data.encrypt.type; 1238 *p++ = CFB64_IV; 1239 1240 /* 1241 * Copy the IV bytes individually so that when a 1242 * 255 (telnet IAC) is used, it can be "escaped" by 1243 * adding it twice (telnet RFC 854). 1244 */ 1245 for (i = 0; i < sizeof (Block); i++) 1246 if ((*p++ = encr_data.encrypt.ivec[i]) == IAC) 1247 *p++ = IAC; 1248 1249 *p++ = IAC; 1250 *p++ = SE; 1251 write_data_len((const char *)sbbuf, (size_t)(p-sbbuf)); 1252 netflush(); 1253 1254 if (!kret) { 1255 lstate &= ~ENCR_STATE_NO_SEND_IV; /* we sent our IV */ 1256 lstate &= ~ENCR_STATE_NO_SEND_IV; /* dont need decrypt IV */ 1257 } 1258 encr_data.encrypt.state = lstate; 1259 1260 if (enc_debug) { 1261 int i; 1262 (void) fprintf(stderr, 1263 "SENT TELOPT_ENCRYPT ENCRYPT_IS %d CFB64_IV ", 1264 encr_data.encrypt.type); 1265 for (i = 0; i < (p-sbbuf); i++) 1266 (void) fprintf(stderr, "%d ", (int)sbbuf[i]); 1267 (void) fprintf(stderr, "\n"); 1268 } 1269 1270 return (lstate); 1271 } 1272 1273 /* 1274 * stop_stream 1275 * 1276 * Utility routine to send a CRIOCSTOP ioctl to the 1277 * crypto module (cryptmod). 1278 */ 1279 static void 1280 stop_stream(int fd, int dir) 1281 { 1282 struct strioctl crioc; 1283 uint32_t stopdir = dir; 1284 1285 crioc.ic_cmd = CRYPTIOCSTOP; 1286 crioc.ic_timout = -1; 1287 crioc.ic_len = sizeof (stopdir); 1288 crioc.ic_dp = (char *)&stopdir; 1289 1290 if (ioctl(fd, I_STR, &crioc)) { 1291 syslog(LOG_ERR, "Error sending CRYPTIOCSTOP ioctl: %m"); 1292 } 1293 } 1294 1295 /* 1296 * start_stream 1297 * 1298 * Utility routine to send a CRYPTIOCSTART ioctl to the 1299 * crypto module (cryptmod). This routine may contain optional 1300 * payload data that the cryptmod will interpret as bytes that 1301 * need to be decrypted and sent back up to the application 1302 * via the data stream. 1303 */ 1304 static void 1305 start_stream(int fd, int dir, int datalen, char *data) 1306 { 1307 struct strioctl crioc; 1308 1309 crioc.ic_cmd = (dir == CRYPT_ENCRYPT ? CRYPTIOCSTARTENC : 1310 CRYPTIOCSTARTDEC); 1311 crioc.ic_timout = -1; 1312 crioc.ic_len = datalen; 1313 crioc.ic_dp = data; 1314 1315 if (ioctl(fd, I_STR, &crioc)) { 1316 syslog(LOG_ERR, "Error sending CRYPTIOCSTART ioctl: %m"); 1317 } 1318 } 1319 1320 /* 1321 * encrypt_start_output 1322 * 1323 * Tell the other side to start encrypting its data 1324 */ 1325 static void 1326 encrypt_start_output() 1327 { 1328 int lstate; 1329 uchar_t *p; 1330 uchar_t sbbuf[MAXOPTLEN]; 1331 struct strioctl crioc; 1332 struct cr_info_t cki; 1333 1334 /* 1335 * Initialize crypto and send the ENCRYPT_IS msg 1336 */ 1337 lstate = encrypt_send_encrypt_is(); 1338 1339 if (lstate != ENCR_STATE_OK) { 1340 if (enc_debug) 1341 (void) fprintf(stderr, 1342 "\t(encrypt_start_output) ENCRYPT state " 1343 "= %d\n", lstate); 1344 return; 1345 } 1346 1347 p = sbbuf; 1348 1349 *p++ = IAC; 1350 *p++ = SB; 1351 *p++ = TELOPT_ENCRYPT; 1352 *p++ = ENCRYPT_START; 1353 1354 (void) memcpy(p, encr_data.encrypt.keyid, encr_data.encrypt.keyidlen); 1355 p += encr_data.encrypt.keyidlen; 1356 1357 *p++ = IAC; 1358 *p++ = SE; 1359 1360 /* Flush this data out before we start encrypting */ 1361 write_data_len((const char *)sbbuf, (int)(p-sbbuf)); 1362 netflush(); 1363 1364 if (enc_debug) 1365 (void) fprintf(stderr, "SENT TELOPT_ENCRYPT ENCRYPT_START %d " 1366 "(lstate = %d) data waiting = %d\n", 1367 (int)encr_data.encrypt.keyid[0], 1368 lstate, nfrontp-nbackp); 1369 1370 encr_data.encrypt.state = lstate; 1371 1372 /* 1373 * tell crypto module what key to use for encrypting 1374 * Note that the ENCRYPT has not yet been enabled, but we 1375 * need to first set the crypto key to use. 1376 */ 1377 cki.direction_mask = CRYPT_ENCRYPT; 1378 1379 if (encr_data.encrypt.type == TELOPT_ENCTYPE_DES_CFB64) { 1380 cki.crypto_method = CRYPT_METHOD_DES_CFB; 1381 } else { 1382 if (enc_debug) 1383 (void) fprintf(stderr, 1384 "\t(encrypt_start_output) - unknown " 1385 "crypto_method %d\n", 1386 encr_data.encrypt.type); 1387 syslog(LOG_ERR, "unrecognized crypto encrypt method: %d", 1388 encr_data.encrypt.type); 1389 1390 return; 1391 } 1392 1393 /* 1394 * If we previously configured this crypto method, we dont want to 1395 * overwrite the key or ivec information already given to the crypto 1396 * module as it will cause the cipher data between the client and server 1397 * to become out of synch and impossible to decipher. 1398 */ 1399 if (encr_data.encrypt.setup == cki.crypto_method) { 1400 cki.keylen = 0; 1401 cki.iveclen = 0; 1402 } else { 1403 cki.keylen = DES_BLOCKSIZE; 1404 (void) memcpy(cki.key, (void *)encr_data.encrypt.krbdes_key, 1405 DES_BLOCKSIZE); 1406 1407 cki.iveclen = DES_BLOCKSIZE; 1408 (void) memcpy(cki.ivec, (void *)encr_data.encrypt.ivec, 1409 DES_BLOCKSIZE); 1410 1411 cki.ivec_usage = IVEC_ONETIME; 1412 } 1413 1414 cki.option_mask = 0; 1415 1416 /* Stop encrypt side prior to setup so we dont lose data */ 1417 stop_stream(cryptmod_fd, CRYPT_ENCRYPT); 1418 1419 crioc.ic_cmd = CRYPTIOCSETUP; 1420 crioc.ic_timout = -1; 1421 crioc.ic_len = sizeof (struct cr_info_t); 1422 crioc.ic_dp = (char *)&cki; 1423 1424 if (ioctl(cryptmod_fd, I_STR, &crioc)) { 1425 perror("ioctl(CRYPTIOCSETUP) [encrypt_start_output] error"); 1426 } else { 1427 /* Setup completed OK */ 1428 encr_data.encrypt.setup = cki.crypto_method; 1429 } 1430 1431 /* 1432 * We do not check for "stuck" data when setting up the 1433 * outbound "encrypt" channel. Any data queued prior to 1434 * this IOCTL will get processed correctly without our help. 1435 */ 1436 start_stream(cryptmod_fd, CRYPT_ENCRYPT, 0, NULL); 1437 1438 /* 1439 * tell crypto module to start encrypting 1440 */ 1441 if (enc_debug) 1442 (void) fprintf(stderr, 1443 "\t(encrypt_start_output) Encrypting output\n"); 1444 } 1445 1446 /* 1447 * encrypt_request_start 1448 * 1449 * The client requests that we start encryption immediately after 1450 * successful negotiation 1451 */ 1452 static void 1453 encrypt_request_start(void) 1454 { 1455 if (encr_data.encrypt.type == ENCTYPE_NULL) { 1456 encr_data.encrypt.autoflag = 1; 1457 if (enc_debug) 1458 (void) fprintf(stderr, "\t(encrypt_request_start) " 1459 "autoencrypt = ON\n"); 1460 } else { 1461 encrypt_start_output(); 1462 } 1463 } 1464 1465 /* 1466 * encrypt_end 1467 * 1468 * ENCRYPT END received, stop decrypting the read stream 1469 */ 1470 static void 1471 encrypt_end(int direction) 1472 { 1473 struct cr_info_t cki; 1474 struct strioctl crioc; 1475 uint32_t stopdir; 1476 1477 stopdir = (direction == TELNET_DIR_DECRYPT ? CRYPT_DECRYPT : 1478 CRYPT_ENCRYPT); 1479 1480 stop_stream(cryptmod_fd, stopdir); 1481 1482 /* 1483 * Call this function when we wish to disable crypto in 1484 * either direction (ENCRYPT or DECRYPT) 1485 */ 1486 cki.direction_mask = (direction == TELNET_DIR_DECRYPT ? CRYPT_DECRYPT : 1487 CRYPT_ENCRYPT); 1488 cki.crypto_method = CRYPT_METHOD_NONE; 1489 cki.option_mask = 0; 1490 1491 cki.keylen = 0; 1492 cki.iveclen = 0; 1493 cki.ivec_usage = IVEC_ONETIME; 1494 1495 crioc.ic_cmd = CRYPTIOCSETUP; 1496 crioc.ic_timout = -1; 1497 crioc.ic_len = sizeof (cki); 1498 crioc.ic_dp = (char *)&cki; 1499 1500 if (ioctl(cryptmod_fd, I_STR, &crioc)) { 1501 perror("ioctl(CRYPTIOCSETUP) [encrypt_end] error"); 1502 } 1503 1504 start_stream(cryptmod_fd, stopdir, 0, NULL); 1505 } 1506 1507 /* 1508 * encrypt_request_end 1509 * 1510 * When we receive a REQEND from the client, it means 1511 * that we are supposed to stop encrypting 1512 */ 1513 static void 1514 encrypt_request_end() 1515 { 1516 /* 1517 * Tell the other side we are done encrypting 1518 */ 1519 1520 write_data("%c%c%c%c%c%c", 1521 (uchar_t)IAC, 1522 (uchar_t)SB, 1523 (uchar_t)TELOPT_ENCRYPT, 1524 (uchar_t)ENCRYPT_END, 1525 (uchar_t)IAC, 1526 (uchar_t)SE); 1527 netflush(); 1528 if (enc_debug) 1529 (void) fprintf(stderr, "SENT TELOPT_ENCRYPT ENCRYPT_END\n"); 1530 1531 /* 1532 * Turn off encryption of the write stream 1533 */ 1534 encrypt_end(TELNET_DIR_ENCRYPT); 1535 } 1536 1537 /* 1538 * encrypt_send_request_end 1539 * 1540 * We stop encrypting the write stream and tell the other side about it. 1541 */ 1542 static void 1543 encrypt_send_request_end() 1544 { 1545 write_data("%c%c%c%c%c%c", 1546 (uchar_t)IAC, 1547 (uchar_t)SB, 1548 (uchar_t)TELOPT_ENCRYPT, 1549 (uchar_t)ENCRYPT_REQEND, 1550 (uchar_t)IAC, 1551 (uchar_t)SE); 1552 netflush(); 1553 if (enc_debug) 1554 (void) fprintf(stderr, "SENT TELOPT_ENCRYPT ENCRYPT_REQEND\n"); 1555 } 1556 1557 /* 1558 * encrypt_start 1559 * 1560 * The client is going to start sending encrypted data 1561 * using the previously negotiated cipher (see what we set 1562 * when we did the REPLY in encrypt_is). 1563 */ 1564 static void 1565 encrypt_start(void) 1566 { 1567 struct cr_info_t cki; 1568 struct strioctl crioc; 1569 int bytes = 0; 1570 char *dataptr = NULL; 1571 1572 if (encr_data.decrypt.type == ENCTYPE_NULL) { 1573 if (enc_debug) 1574 (void) fprintf(stderr, 1575 "\t(encrypt_start) No DECRYPT method " 1576 "defined yet\n"); 1577 encrypt_send_request_end(); 1578 return; 1579 } 1580 1581 cki.direction_mask = CRYPT_DECRYPT; 1582 1583 if (encr_data.decrypt.type == TELOPT_ENCTYPE_DES_CFB64) { 1584 cki.crypto_method = CRYPT_METHOD_DES_CFB; 1585 } else { 1586 if (enc_debug) 1587 (void) fprintf(stderr, 1588 "\t(encrypt_start) - unknown " 1589 "crypto_method %d\n", encr_data.decrypt.type); 1590 1591 syslog(LOG_ERR, "unrecognized crypto decrypt method: %d", 1592 encr_data.decrypt.type); 1593 1594 return; 1595 } 1596 1597 /* 1598 * Don't overwrite previously configured key and ivec info 1599 */ 1600 if (encr_data.decrypt.setup != cki.crypto_method) { 1601 (void) memcpy(cki.key, (void *)encr_data.decrypt.krbdes_key, 1602 DES_BLOCKSIZE); 1603 (void) memcpy(cki.ivec, (void *)encr_data.decrypt.ivec, 1604 DES_BLOCKSIZE); 1605 1606 cki.keylen = DES_BLOCKSIZE; 1607 cki.iveclen = DES_BLOCKSIZE; 1608 cki.ivec_usage = IVEC_ONETIME; 1609 } else { 1610 cki.keylen = 0; 1611 cki.iveclen = 0; 1612 } 1613 cki.option_mask = 0; 1614 1615 stop_stream(cryptmod_fd, CRYPT_DECRYPT); 1616 1617 crioc.ic_cmd = CRYPTIOCSETUP; 1618 crioc.ic_timout = -1; 1619 crioc.ic_len = sizeof (struct cr_info_t); 1620 crioc.ic_dp = (char *)&cki; 1621 1622 if (ioctl(cryptmod_fd, I_STR, &crioc)) { 1623 syslog(LOG_ERR, "ioctl(CRYPTIOCSETUP) [encrypt_start] " 1624 "error: %m"); 1625 } else { 1626 encr_data.decrypt.setup = cki.crypto_method; 1627 } 1628 if (enc_debug) 1629 (void) fprintf(stderr, 1630 "\t(encrypt_start) called CRYPTIOCSETUP for " 1631 "decrypt side\n"); 1632 1633 /* 1634 * Read any data stuck between the cryptmod and the application 1635 * so we can pass it back down to be properly decrypted after 1636 * this operation finishes. 1637 */ 1638 if (ioctl(cryptmod_fd, I_NREAD, &bytes) < 0) { 1639 syslog(LOG_ERR, "I_NREAD returned error %m"); 1640 bytes = 0; 1641 } 1642 1643 /* 1644 * Any data which was read AFTER the ENCRYPT START message 1645 * must be sent back down to be decrypted properly. 1646 * 1647 * 'ncc' is the number of bytes that have been read but 1648 * not yet processed by the telnet state machine. 1649 * 1650 * 'bytes' is the number of bytes waiting to be read from 1651 * the stream. 1652 * 1653 * If either one is a positive value, then those bytes 1654 * must be pulled up and sent back down to be decrypted. 1655 */ 1656 if (ncc || bytes) { 1657 drainstream(bytes); 1658 if (enc_debug) 1659 (void) fprintf(stderr, 1660 "\t(encrypt_start) after drainstream, " 1661 "ncc=%d bytes = %d\n", ncc, bytes); 1662 bytes += ncc; 1663 dataptr = netip; 1664 } 1665 1666 start_stream(cryptmod_fd, CRYPT_DECRYPT, bytes, dataptr); 1667 1668 /* 1669 * The bytes putback into the stream are no longer 1670 * available to be read by the server, so adjust the 1671 * counter accordingly. 1672 */ 1673 ncc = 0; 1674 netip = netibuf; 1675 (void) memset(netip, 0, netibufsize); 1676 1677 #ifdef ENCRYPT_NAMES 1678 if (enc_debug) { 1679 (void) fprintf(stderr, 1680 "\t(encrypt_start) Start DECRYPT using %s\n", 1681 ENCTYPE_NAME(encr_data.decrypt.type)); 1682 } 1683 #endif /* ENCRYPT_NAMES */ 1684 } 1685 1686 /* 1687 * encrypt_support 1688 * 1689 * Called when we recieve the TELOPT_ENCRYPT SUPPORT [ encr type list ] 1690 * message from a client. 1691 * 1692 * Choose an agreeable method (DES_CFB64) and 1693 * respond with TELOPT_ENCRYPT ENCRYPT_IS [ desired crypto method ] 1694 * 1695 * from: RFC 2946 1696 */ 1697 static void 1698 encrypt_support(char *data, int cnt) 1699 { 1700 int lstate = ENCR_STATE_NOT_READY; 1701 int type, use_type = 0; 1702 1703 while (cnt-- > 0 && use_type == 0) { 1704 type = *data++; 1705 #ifdef ENCRYPT_NAMES 1706 if (enc_debug) 1707 (void) fprintf(stderr, 1708 "RCVD ENCRYPT SUPPORT %s\n", 1709 ENCTYPE_NAME(type)); 1710 #endif /* ENCRYPT_NAMES */ 1711 /* 1712 * Prefer CFB64 1713 */ 1714 if (type == TELOPT_ENCTYPE_DES_CFB64) { 1715 use_type = type; 1716 } 1717 } 1718 encr_data.encrypt.type = use_type; 1719 1720 if (use_type != TELOPT_ENCTYPE_NULL && 1721 authenticated != NULL && authenticated != &NoAuth && 1722 auth_status != AUTH_REJECT) { 1723 1724 /* Authenticated -> have session key -> send ENCRYPT IS */ 1725 lstate = encrypt_send_encrypt_is(); 1726 if (lstate == ENCR_STATE_OK) 1727 encrypt_start_output(); 1728 } else if (use_type == TELOPT_ENCTYPE_NULL) { 1729 if (enc_debug) 1730 (void) fprintf(stderr, 1731 "\t(encrypt_support) Cannot agree " 1732 "on crypto algorithm, output encryption " 1733 "disabled.\n"); 1734 1735 /* 1736 * Cannot agree on crypto algorithm 1737 * RFC 2946 sez: 1738 * send "IAC SB ENCRYPT IS NULL IAC SE" 1739 * optionally, also send IAC WONT ENCRYPT 1740 */ 1741 write_data("%c%c%c%c%c%c%c", 1742 (uchar_t)IAC, 1743 (uchar_t)SB, 1744 (uchar_t)TELOPT_ENCRYPT, 1745 (uchar_t)ENCRYPT_IS, 1746 (uchar_t)TELOPT_ENCTYPE_NULL, 1747 (uchar_t)IAC, 1748 (uchar_t)SE); 1749 send_wont(TELOPT_ENCRYPT); 1750 netflush(); 1751 if (enc_debug) 1752 (void) fprintf(stderr, 1753 "SENT TELOPT_ENCRYPT ENCRYPT_IS " 1754 "[NULL]\n"); 1755 1756 remopts[TELOPT_ENCRYPT] = OPT_NO; 1757 } 1758 settimer(encr_support); 1759 } 1760 1761 /* 1762 * encrypt_send_keyid 1763 * 1764 * Sent the key id we will use to the client 1765 */ 1766 static void 1767 encrypt_send_keyid(int dir, uchar_t *keyid, int keylen, boolean_t saveit) 1768 { 1769 uchar_t sbbuf[128], *p; 1770 1771 p = sbbuf; 1772 1773 *p++ = IAC; 1774 *p++ = SB; 1775 *p++ = TELOPT_ENCRYPT; 1776 *p++ = (dir == TELNET_DIR_ENCRYPT ? ENCRYPT_ENC_KEYID : 1777 ENCRYPT_DEC_KEYID); 1778 if (saveit) { 1779 if (enc_debug) 1780 (void) fprintf(stderr, 1781 "\t(send_keyid) store %d byte %s keyid\n", 1782 keylen, 1783 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : 1784 "DECRYPT")); 1785 1786 if (dir == TELNET_DIR_ENCRYPT) { 1787 (void) memcpy(encr_data.encrypt.keyid, keyid, keylen); 1788 encr_data.encrypt.keyidlen = keylen; 1789 } else { 1790 (void) memcpy(encr_data.decrypt.keyid, keyid, keylen); 1791 encr_data.decrypt.keyidlen = keylen; 1792 } 1793 } 1794 (void) memcpy(p, keyid, keylen); 1795 p += keylen; 1796 1797 *p++ = IAC; 1798 *p++ = SE; 1799 write_data_len((const char *)sbbuf, (size_t)(p-sbbuf)); 1800 netflush(); 1801 1802 if (enc_debug) 1803 (void) fprintf(stderr, "SENT TELOPT_ENCRYPT %s %d\n", 1804 (dir == TELNET_DIR_ENCRYPT ? "ENC_KEYID" : 1805 "DEC_KEYID"), keyid[0]); 1806 } 1807 1808 /* 1809 * encrypt_reply 1810 * 1811 * When we receive the TELOPT_ENCRYPT REPLY [crtype] CFB64_IV_OK IAC SE 1812 * message, process it accordingly. 1813 * If the vector is acceptable, tell client we are encrypting and 1814 * enable encryption on our write stream. 1815 * 1816 * Negotiate the KEYID next.. 1817 * RFC 2946, 2952 1818 */ 1819 static void 1820 encrypt_reply(char *data, int len) 1821 { 1822 uchar_t type = (uchar_t)(*data++); 1823 uchar_t result = (uchar_t)(*data); 1824 int lstate; 1825 1826 #ifdef ENCRYPT_NAMES 1827 if (enc_debug) 1828 (void) fprintf(stderr, 1829 "\t(encrypt_reply) ENCRYPT REPLY %s %s [len=%d]\n", 1830 ENCRYPT_NAME(type), 1831 (result == CFB64_IV_OK ? "CFB64_IV_OK" : 1832 "CFB64_IV_BAD"), len); 1833 #endif /* ENCRYPT_NAMES */ 1834 1835 lstate = encr_data.encrypt.state; 1836 if (enc_debug) 1837 (void) fprintf(stderr, 1838 "\t(encrypt_reply) initial ENCRYPT state = %d\n", 1839 lstate); 1840 switch (result) { 1841 case CFB64_IV_OK: 1842 if (lstate == ENCR_STATE_NOT_READY) 1843 lstate = ENCR_STATE_IN_PROGRESS; 1844 lstate &= ~ENCR_STATE_NO_RECV_IV; /* we got the IV */ 1845 lstate &= ~ENCR_STATE_NO_SEND_IV; /* we dont need to send IV */ 1846 1847 /* 1848 * The correct response here is to send the encryption key id 1849 * RFC 2752. 1850 * 1851 * Send keyid 0 to indicate that we will just use default 1852 * keys. 1853 */ 1854 encrypt_send_keyid(TELNET_DIR_ENCRYPT, (uchar_t *)"\0", 1, 1); 1855 1856 break; 1857 case CFB64_IV_BAD: 1858 /* 1859 * Clear the ivec 1860 */ 1861 (void) memset(encr_data.encrypt.ivec, 0, sizeof (Block)); 1862 lstate = ENCR_STATE_NOT_READY; 1863 break; 1864 default: 1865 if (enc_debug) 1866 (void) fprintf(stderr, 1867 "\t(encrypt_reply) Got unknown IV value in " 1868 "REPLY message\n"); 1869 lstate = ENCR_STATE_NOT_READY; 1870 break; 1871 } 1872 1873 encr_data.encrypt.state = lstate; 1874 if (lstate == ENCR_STATE_NOT_READY) { 1875 encr_data.encrypt.autoflag = 0; 1876 encr_data.encrypt.type = ENCTYPE_NULL; 1877 if (enc_debug) 1878 (void) fprintf(stderr, 1879 "\t(encrypt_reply) encrypt.autoflag = " 1880 "OFF\n"); 1881 } else { 1882 encr_data.encrypt.type = type; 1883 if ((lstate == ENCR_STATE_OK) && encr_data.encrypt.autoflag) 1884 encrypt_start_output(); 1885 } 1886 1887 if (enc_debug) 1888 (void) fprintf(stderr, 1889 "\t(encrypt_reply) ENCRYPT final state = %d\n", 1890 lstate); 1891 } 1892 1893 static void 1894 encrypt_set_keyid_state(uchar_t *keyid, int *keyidlen, int dir) 1895 { 1896 int lstate; 1897 1898 lstate = (dir == TELNET_DIR_ENCRYPT ? encr_data.encrypt.state : 1899 encr_data.decrypt.state); 1900 1901 if (enc_debug) 1902 (void) fprintf(stderr, 1903 "\t(set_keyid_state) %s initial state = %d\n", 1904 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : 1905 "DECRYPT"), lstate); 1906 1907 /* 1908 * Currently, we only support using the default keyid, 1909 * so it should be an error if the len > 1 or the keyid != 0. 1910 */ 1911 if (*keyidlen != 1 || (*keyid != '\0')) { 1912 if (enc_debug) 1913 (void) fprintf(stderr, 1914 "\t(set_keyid_state) unexpected keyid: " 1915 "len=%d value=%d\n", *keyidlen, *keyid); 1916 *keyidlen = 0; 1917 syslog(LOG_ERR, "rcvd unexpected keyid %d - only keyid of 0 " 1918 "is supported", *keyid); 1919 } else { 1920 /* 1921 * We move to the "IN_PROGRESS" state. 1922 */ 1923 if (lstate == ENCR_STATE_NOT_READY) 1924 lstate = ENCR_STATE_IN_PROGRESS; 1925 /* 1926 * Clear the NO_KEYID bit because we now have a valid keyid 1927 */ 1928 lstate &= ~ENCR_STATE_NO_KEYID; 1929 } 1930 1931 if (enc_debug) 1932 (void) fprintf(stderr, 1933 "\t(set_keyid_state) %s final state = %d\n", 1934 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : 1935 "DECRYPT"), lstate); 1936 1937 if (dir == TELNET_DIR_ENCRYPT) 1938 encr_data.encrypt.state = lstate; 1939 else 1940 encr_data.decrypt.state = lstate; 1941 } 1942 1943 /* 1944 * encrypt_keyid 1945 * 1946 * Set the keyid value in the key_info structure. 1947 * if necessary send a response to the sender 1948 */ 1949 static void 1950 encrypt_keyid(uchar_t *newkeyid, int *keyidlen, uchar_t *keyid, 1951 int len, int dir) 1952 { 1953 if (len > TELNET_MAXNUMKEYS) { 1954 if (enc_debug) 1955 (void) fprintf(stderr, 1956 "\t(keyid) keylen too big (%d)\n", len); 1957 return; 1958 } 1959 1960 if (enc_debug) { 1961 (void) fprintf(stderr, "\t(keyid) set KEYID for %s len = %d\n", 1962 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : 1963 "DECRYPT"), len); 1964 } 1965 1966 if (len == 0) { 1967 if (*keyidlen == 0) { 1968 if (enc_debug) 1969 (void) fprintf(stderr, 1970 "\t(keyid) Got 0 length keyid - " 1971 "failure\n"); 1972 return; 1973 } 1974 *keyidlen = 0; 1975 encrypt_set_keyid_state(newkeyid, keyidlen, dir); 1976 1977 } else if (len != *keyidlen || memcmp(keyid, newkeyid, len)) { 1978 if (enc_debug) 1979 (void) fprintf(stderr, 1980 "\t(keyid) Setting new key (%d bytes)\n", 1981 len); 1982 1983 *keyidlen = len; 1984 (void) memcpy(newkeyid, keyid, len); 1985 1986 encrypt_set_keyid_state(newkeyid, keyidlen, dir); 1987 } else { 1988 encrypt_set_keyid_state(newkeyid, keyidlen, dir); 1989 1990 if (enc_debug) 1991 (void) fprintf(stderr, 1992 "\t(keyid) %s Key already in place," 1993 "state = %d autoflag=%d\n", 1994 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : "DECRYPT"), 1995 (dir == TELNET_DIR_ENCRYPT ? encr_data.encrypt.state: 1996 encr_data.decrypt.state), 1997 (dir == TELNET_DIR_ENCRYPT ? 1998 encr_data.encrypt.autoflag: 1999 encr_data.decrypt.autoflag)); 2000 2001 /* key already in place */ 2002 if ((encr_data.encrypt.state == ENCR_STATE_OK) && 2003 dir == TELNET_DIR_ENCRYPT && encr_data.encrypt.autoflag) { 2004 encrypt_start_output(); 2005 } 2006 return; 2007 } 2008 2009 if (enc_debug) 2010 (void) fprintf(stderr, "\t(keyid) %s final state = %d\n", 2011 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : 2012 "DECRYPT"), 2013 (dir == TELNET_DIR_ENCRYPT ? 2014 encr_data.encrypt.state : 2015 encr_data.decrypt.state)); 2016 2017 encrypt_send_keyid(dir, newkeyid, *keyidlen, 0); 2018 } 2019 2020 /* 2021 * encrypt_enc_keyid 2022 * 2023 * We received the ENC_KEYID message from a client indicating that 2024 * the client wishes to verify that the indicated keyid maps to a 2025 * valid key. 2026 */ 2027 static void 2028 encrypt_enc_keyid(char *data, int cnt) 2029 { 2030 /* 2031 * Verify the decrypt keyid is valid 2032 */ 2033 encrypt_keyid(encr_data.decrypt.keyid, &encr_data.decrypt.keyidlen, 2034 (uchar_t *)data, cnt, TELNET_DIR_DECRYPT); 2035 } 2036 2037 /* 2038 * encrypt_dec_keyid 2039 * 2040 * We received the DEC_KEYID message from a client indicating that 2041 * the client wants to verify that the indicated keyid maps to a valid key. 2042 */ 2043 static void 2044 encrypt_dec_keyid(char *data, int cnt) 2045 { 2046 encrypt_keyid(encr_data.encrypt.keyid, &encr_data.encrypt.keyidlen, 2047 (uchar_t *)data, cnt, TELNET_DIR_ENCRYPT); 2048 } 2049 2050 /* 2051 * encrypt_session_key 2052 * 2053 * Store the session key in the encryption data record 2054 */ 2055 static void 2056 encrypt_session_key(Session_Key *key, cipher_info_t *cinfo) 2057 { 2058 if (key == NULL || key->type != SK_DES) { 2059 if (enc_debug) 2060 (void) fprintf(stderr, 2061 "\t(session_key) Cannot set krb5 " 2062 "session key (unknown type = %d)\n", 2063 key ? key->type : -1); 2064 } 2065 if (enc_debug) 2066 (void) fprintf(stderr, 2067 "\t(session_key) Settting session key " 2068 "for server\n"); 2069 2070 /* store the key in the cipher info data struct */ 2071 (void) memcpy(cinfo->krbdes_key, (void *)key->data, sizeof (Block)); 2072 2073 /* 2074 * Now look to see if we still need to send the key and start 2075 * encrypting. 2076 * 2077 * If so, go ahead an call it now that we have the key. 2078 */ 2079 if (cinfo->need_start) { 2080 if (encrypt_send_encrypt_is() == ENCR_STATE_OK) { 2081 cinfo->need_start = 0; 2082 } 2083 } 2084 } 2085 2086 /* 2087 * new_env 2088 * 2089 * Used to add an environment variable and value to the 2090 * linked list structure. 2091 */ 2092 static int 2093 new_env(const char *name, const char *value) 2094 { 2095 struct envlist *env; 2096 2097 env = malloc(sizeof (struct envlist)); 2098 if (env == NULL) 2099 return (1); 2100 if ((env->name = strdup(name)) == NULL) { 2101 free(env); 2102 return (1); 2103 } 2104 if ((env->value = strdup(value)) == NULL) { 2105 free(env->name); 2106 free(env); 2107 return (1); 2108 } 2109 env->delete = 0; 2110 env->next = envlist_head; 2111 envlist_head = env; 2112 return (0); 2113 } 2114 2115 /* 2116 * del_env 2117 * 2118 * Used to delete an environment variable from the linked list 2119 * structure. We just set a flag because we will delete the list 2120 * anyway before we exec login. 2121 */ 2122 static int 2123 del_env(const char *name) 2124 { 2125 struct envlist *env; 2126 2127 for (env = envlist_head; env; env = env->next) { 2128 if (strcmp(env->name, name) == 0) { 2129 env->delete = 1; 2130 break; 2131 } 2132 } 2133 return (0); 2134 } 2135 2136 static int 2137 issock(int fd) 2138 { 2139 struct stat stats; 2140 2141 if (fstat(fd, &stats) == -1) 2142 return (0); 2143 return (S_ISSOCK(stats.st_mode)); 2144 } 2145 2146 /* 2147 * audit_telnet_settid stores the terminal id while it is still 2148 * available. Subsequent calls to adt_load_hostname() return 2149 * the id which is stored here. 2150 */ 2151 static int 2152 audit_telnet_settid(int sock) { 2153 adt_session_data_t *ah; 2154 adt_termid_t *termid; 2155 int rc; 2156 2157 if ((rc = adt_start_session(&ah, NULL, 0)) == 0) { 2158 if ((rc = adt_load_termid(sock, &termid)) == 0) { 2159 if ((rc = adt_set_user(ah, ADT_NO_AUDIT, 2160 ADT_NO_AUDIT, 0, ADT_NO_AUDIT, 2161 termid, ADT_SETTID)) == 0) 2162 (void) adt_set_proc(ah); 2163 free(termid); 2164 } 2165 (void) adt_end_session(ah); 2166 } 2167 return (rc); 2168 } 2169 2170 /* ARGSUSED */ 2171 int 2172 main(int argc, char *argv[]) 2173 { 2174 struct sockaddr_storage from; 2175 int on = 1; 2176 socklen_t fromlen; 2177 int issocket; 2178 #if defined(DEBUG) 2179 ushort_t porttouse = 0; 2180 boolean_t standalone = 0; 2181 #endif /* defined(DEBUG) */ 2182 extern char *optarg; 2183 char c; 2184 int tos = -1; 2185 2186 while ((c = getopt(argc, argv, TELNETD_OPTS DEBUG_OPTS)) != -1) { 2187 switch (c) { 2188 #if defined(DEBUG) 2189 case 'p': 2190 /* 2191 * note: alternative port number only used in 2192 * standalone mode. 2193 */ 2194 porttouse = atoi(optarg); 2195 standalone = 1; 2196 break; 2197 case 'e': 2198 enc_debug = 1; 2199 break; 2200 #endif /* DEBUG */ 2201 case 'a': 2202 if (strcasecmp(optarg, "none") == 0) { 2203 auth_level = 0; 2204 } else if (strcasecmp(optarg, "user") == 0) { 2205 auth_level = AUTH_USER; 2206 } else if (strcasecmp(optarg, "valid") == 0) { 2207 auth_level = AUTH_VALID; 2208 } else if (strcasecmp(optarg, "off") == 0) { 2209 auth_level = -1; 2210 negotiate_auth_krb5 = 0; 2211 } else if (strcasecmp(optarg, "debug") == 0) { 2212 auth_debug = 1; 2213 } else { 2214 syslog(LOG_ERR, 2215 "unknown authentication level specified " 2216 "with \'-a\' option (%s)", optarg); 2217 auth_level = AUTH_USER; 2218 } 2219 break; 2220 case 'X': 2221 /* disable authentication negotiation */ 2222 negotiate_auth_krb5 = 0; 2223 break; 2224 case 'R': 2225 case 'M': 2226 if (optarg != NULL) { 2227 int ret = krb5_init(); 2228 if (ret) { 2229 syslog(LOG_ERR, 2230 "Unable to use Kerberos V5 as " 2231 "requested, exiting"); 2232 exit(1); 2233 } 2234 krb5_set_default_realm(telnet_context, optarg); 2235 syslog(LOG_NOTICE, 2236 "using %s as default KRB5 realm", optarg); 2237 } 2238 break; 2239 case 'S': 2240 telnet_srvtab = (char *)strdup(optarg); 2241 break; 2242 case 'E': /* disable automatic encryption */ 2243 negotiate_encrypt = B_FALSE; 2244 break; 2245 case 'U': 2246 resolve_hostname = 1; 2247 break; 2248 case 's': 2249 if (optarg == NULL || (tos = atoi(optarg)) < 0 || 2250 tos > 255) { 2251 syslog(LOG_ERR, "telnetd: illegal tos value: " 2252 "%s\n", optarg); 2253 } else { 2254 if (tos < 0) 2255 tos = 020; 2256 } 2257 break; 2258 case 'h': 2259 show_hostinfo = 0; 2260 break; 2261 default: 2262 syslog(LOG_ERR, "telnetd: illegal cmd line option %c", 2263 c); 2264 break; 2265 } 2266 } 2267 2268 netibufsize = BUFSIZ; 2269 if (!(netibuf = (char *)malloc(netibufsize))) 2270 syslog(LOG_ERR, "netibuf malloc failed\n"); 2271 (void) memset(netibuf, 0, netibufsize); 2272 netip = netibuf; 2273 2274 #if defined(DEBUG) 2275 if (standalone) { 2276 int s, ns, foo; 2277 struct servent *sp; 2278 static struct sockaddr_in6 sin6 = { AF_INET6 }; 2279 int option = 1; 2280 2281 if (porttouse) { 2282 sin6.sin6_port = htons(porttouse); 2283 } else { 2284 sp = getservbyname("telnet", "tcp"); 2285 if (sp == 0) { 2286 (void) fprintf(stderr, 2287 "telnetd: tcp/telnet: " 2288 "unknown service\n"); 2289 exit(EXIT_FAILURE); 2290 } 2291 sin6.sin6_port = sp->s_port; 2292 } 2293 2294 s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); 2295 if (s < 0) { 2296 perror("telnetd: socket"); 2297 exit(EXIT_FAILURE); 2298 } 2299 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&option, 2300 sizeof (option)) == -1) 2301 perror("setsockopt SO_REUSEADDR"); 2302 if (bind(s, (struct sockaddr *)&sin6, sizeof (sin6)) < 0) { 2303 perror("bind"); 2304 exit(EXIT_FAILURE); 2305 } 2306 if (listen(s, 32) < 0) { 2307 perror("listen"); 2308 exit(EXIT_FAILURE); 2309 } 2310 2311 /* automatically reap all child processes */ 2312 (void) signal(SIGCHLD, SIG_IGN); 2313 2314 for (;;) { 2315 pid_t pid; 2316 2317 foo = sizeof (sin6); 2318 ns = accept(s, (struct sockaddr *)&sin6, &foo); 2319 if (ns < 0) { 2320 perror("accept"); 2321 exit(EXIT_FAILURE); 2322 } 2323 pid = fork(); 2324 if (pid == -1) { 2325 perror("fork"); 2326 exit(EXIT_FAILURE); 2327 } 2328 if (pid == 0) { 2329 (void) dup2(ns, 0); 2330 (void) close(s); 2331 (void) signal(SIGCHLD, SIG_DFL); 2332 break; 2333 } 2334 (void) close(ns); 2335 } 2336 } 2337 #endif /* defined(DEBUG) */ 2338 2339 openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON); 2340 2341 issocket = issock(0); 2342 if (!issocket) 2343 fatal(0, "stdin is not a socket file descriptor"); 2344 2345 fromlen = (socklen_t)sizeof (from); 2346 (void) memset((char *)&from, 0, sizeof (from)); 2347 if (getpeername(0, (struct sockaddr *)&from, &fromlen) 2348 < 0) { 2349 (void) fprintf(stderr, "%s: ", argv[0]); 2350 perror("getpeername"); 2351 _exit(EXIT_FAILURE); 2352 } 2353 2354 if (audit_telnet_settid(0)) { /* set terminal ID */ 2355 (void) fprintf(stderr, "%s: ", argv[0]); 2356 perror("audit"); 2357 exit(EXIT_FAILURE); 2358 } 2359 2360 if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (const char *)&on, 2361 sizeof (on)) < 0) { 2362 syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 2363 } 2364 2365 /* 2366 * Set the TOS value 2367 */ 2368 if (tos != -1 && 2369 setsockopt(0, IPPROTO_IP, IP_TOS, 2370 (char *)&tos, sizeof (tos)) < 0 && 2371 errno != ENOPROTOOPT) { 2372 syslog(LOG_ERR, "setsockopt (IP_TOS %d): %m", tos); 2373 } 2374 2375 if (setsockopt(net, SOL_SOCKET, SO_OOBINLINE, (char *)&on, 2376 sizeof (on)) < 0) { 2377 syslog(LOG_WARNING, "setsockopt (SO_OOBINLINE): %m"); 2378 } 2379 2380 /* set the default PAM service name */ 2381 (void) strcpy(pam_svc_name, "telnet"); 2382 2383 doit(0, &from); 2384 return (EXIT_SUCCESS); 2385 } 2386 2387 static char *terminaltype = 0; 2388 2389 /* 2390 * ttloop 2391 * 2392 * A small subroutine to flush the network output buffer, get some data 2393 * from the network, and pass it through the telnet state machine. We 2394 * also flush the pty input buffer (by dropping its data) if it becomes 2395 * too full. 2396 */ 2397 static void 2398 ttloop(void) 2399 { 2400 if (nfrontp-nbackp) { 2401 netflush(); 2402 } 2403 read_again: 2404 ncc = read(net, netibuf, netibufsize); 2405 if (ncc < 0) { 2406 if (errno == EINTR) 2407 goto read_again; 2408 syslog(LOG_INFO, "ttloop: read: %m"); 2409 exit(EXIT_FAILURE); 2410 } else if (ncc == 0) { 2411 syslog(LOG_INFO, "ttloop: peer closed connection\n"); 2412 exit(EXIT_FAILURE); 2413 } 2414 2415 netip = netibuf; 2416 telrcv(); /* state machine */ 2417 if (ncc > 0) { 2418 pfrontp = pbackp = ptyobuf; 2419 telrcv(); 2420 } 2421 } 2422 2423 static void 2424 send_do(int option) 2425 { 2426 write_data("%c%c%c", (uchar_t)IAC, (uchar_t)DO, (uchar_t)option); 2427 } 2428 2429 static void 2430 send_will(int option) 2431 { 2432 write_data("%c%c%c", (uchar_t)IAC, (uchar_t)WILL, (uchar_t)option); 2433 } 2434 2435 static void 2436 send_wont(int option) 2437 { 2438 write_data("%c%c%c", (uchar_t)IAC, (uchar_t)WONT, (uchar_t)option); 2439 } 2440 2441 2442 /* 2443 * getauthtype 2444 * 2445 * Negotiate automatic authentication, is possible. 2446 */ 2447 static int 2448 getauthtype(char *username, int *len) 2449 { 2450 int init_status = -1; 2451 2452 init_status = krb5_init(); 2453 2454 if (auth_level == -1 || init_status != 0) { 2455 remopts[TELOPT_AUTHENTICATION] = OPT_NO; 2456 myopts[TELOPT_AUTHENTICATION] = OPT_NO; 2457 negotiate_auth_krb5 = B_FALSE; 2458 negotiate_encrypt = B_FALSE; 2459 return (AUTH_REJECT); 2460 } 2461 2462 if (init_status == 0 && auth_level != -1) { 2463 if (negotiate_auth_krb5) { 2464 /* 2465 * Negotiate Authentication FIRST 2466 */ 2467 send_do(TELOPT_AUTHENTICATION); 2468 remopts[TELOPT_AUTHENTICATION] = 2469 OPT_YES_BUT_ALWAYS_LOOK; 2470 } 2471 while (sequenceIs(authopt, getauth)) 2472 ttloop(); 2473 2474 if (remopts[TELOPT_AUTHENTICATION] == OPT_YES) { 2475 /* 2476 * Request KRB5 Mutual authentication and if that fails, 2477 * KRB5 1-way client authentication 2478 */ 2479 uchar_t sbbuf[MAXOPTLEN], *p; 2480 p = sbbuf; 2481 *p++ = (uchar_t)IAC; 2482 *p++ = (uchar_t)SB; 2483 *p++ = (uchar_t)TELOPT_AUTHENTICATION; 2484 *p++ = (uchar_t)TELQUAL_SEND; 2485 if (negotiate_auth_krb5) { 2486 *p++ = (uchar_t)AUTHTYPE_KERBEROS_V5; 2487 *p++ = (uchar_t)(AUTH_WHO_CLIENT | 2488 AUTH_HOW_MUTUAL | 2489 AUTH_ENCRYPT_ON); 2490 *p++ = (uchar_t)AUTHTYPE_KERBEROS_V5; 2491 *p++ = (uchar_t)(AUTH_WHO_CLIENT | 2492 AUTH_HOW_MUTUAL); 2493 *p++ = (uchar_t)AUTHTYPE_KERBEROS_V5; 2494 *p++ = (uchar_t)(AUTH_WHO_CLIENT| 2495 AUTH_HOW_ONE_WAY); 2496 } else { 2497 *p++ = (uchar_t)AUTHTYPE_NULL; 2498 } 2499 *p++ = (uchar_t)IAC; 2500 *p++ = (uchar_t)SE; 2501 2502 write_data_len((const char *)sbbuf, 2503 (size_t)(p - sbbuf)); 2504 netflush(); 2505 if (auth_debug) 2506 (void) fprintf(stderr, 2507 "SENT TELOPT_AUTHENTICATION " 2508 "[data]\n"); 2509 2510 /* auth_wait returns the authentication level */ 2511 /* status = auth_wait(username, len); */ 2512 while (sequenceIs(authdone, getauth)) 2513 ttloop(); 2514 /* 2515 * Now check to see if the user is valid or not 2516 */ 2517 if (authenticated == NULL || authenticated == &NoAuth) 2518 auth_status = AUTH_REJECT; 2519 else { 2520 /* 2521 * We cant be VALID until the user status is 2522 * checked. 2523 */ 2524 if (auth_status == AUTH_VALID) 2525 auth_status = AUTH_USER; 2526 2527 if (authenticated->AuthName == 2528 AUTHTYPE_KERBEROS_V5) 2529 auth_status = krb5_user_status( 2530 username, *len, auth_status); 2531 } 2532 } 2533 } 2534 return (auth_status); 2535 } 2536 2537 static void 2538 getencrtype(void) 2539 { 2540 if (krb5_privacy_allowed() && negotiate_encrypt) { 2541 if (myopts[TELOPT_ENCRYPT] != OPT_YES) { 2542 if (!sent_will_encrypt) { 2543 send_will(TELOPT_ENCRYPT); 2544 sent_will_encrypt = B_TRUE; 2545 } 2546 if (enc_debug) 2547 (void) fprintf(stderr, "SENT WILL ENCRYPT\n"); 2548 } 2549 if (remopts[TELOPT_ENCRYPT] != OPT_YES) { 2550 if (!sent_do_encrypt) { 2551 send_do(TELOPT_ENCRYPT); 2552 sent_do_encrypt = B_TRUE; 2553 remopts[TELOPT_ENCRYPT] = 2554 OPT_YES_BUT_ALWAYS_LOOK; 2555 } 2556 if (enc_debug) 2557 (void) fprintf(stderr, "SENT DO ENCRYPT\n"); 2558 } 2559 myopts[TELOPT_ENCRYPT] = OPT_YES; 2560 2561 while (sequenceIs(encropt, getencr)) 2562 ttloop(); 2563 2564 if (auth_status != AUTH_REJECT && 2565 remopts[TELOPT_ENCRYPT] == OPT_YES && 2566 myopts[TELOPT_ENCRYPT] == OPT_YES) { 2567 2568 if (sent_encrypt_support == B_FALSE) { 2569 write_data("%c%c%c%c%c%c%c", 2570 (uchar_t)IAC, 2571 (uchar_t)SB, 2572 (uchar_t)TELOPT_ENCRYPT, 2573 (uchar_t)ENCRYPT_SUPPORT, 2574 (uchar_t)TELOPT_ENCTYPE_DES_CFB64, 2575 (uchar_t)IAC, 2576 (uchar_t)SE); 2577 2578 netflush(); 2579 } 2580 /* 2581 * Now wait for a response to these messages before 2582 * continuing... 2583 * Look for TELOPT_ENCRYPT suboptions 2584 */ 2585 while (sequenceIs(encr_support, getencr)) 2586 ttloop(); 2587 } 2588 } else { 2589 /* Dont need responses to these, so dont wait for them */ 2590 settimer(encropt); 2591 remopts[TELOPT_ENCRYPT] = OPT_NO; 2592 myopts[TELOPT_ENCRYPT] = OPT_NO; 2593 } 2594 2595 } 2596 2597 /* 2598 * getterminaltype 2599 * 2600 * Ask the other end to send along its terminal type. 2601 * Output is the variable terminaltype filled in. 2602 */ 2603 static void 2604 getterminaltype(void) 2605 { 2606 /* 2607 * The remote side may have already sent this info, so 2608 * dont ask for these options if the other side already 2609 * sent the information. 2610 */ 2611 if (sequenceIs(ttypeopt, getterminal)) { 2612 send_do(TELOPT_TTYPE); 2613 remopts[TELOPT_TTYPE] = OPT_YES_BUT_ALWAYS_LOOK; 2614 } 2615 2616 if (sequenceIs(nawsopt, getterminal)) { 2617 send_do(TELOPT_NAWS); 2618 remopts[TELOPT_NAWS] = OPT_YES_BUT_ALWAYS_LOOK; 2619 } 2620 2621 if (sequenceIs(xdisplocopt, getterminal)) { 2622 send_do(TELOPT_XDISPLOC); 2623 remopts[TELOPT_XDISPLOC] = OPT_YES_BUT_ALWAYS_LOOK; 2624 } 2625 2626 if (sequenceIs(environopt, getterminal)) { 2627 send_do(TELOPT_NEW_ENVIRON); 2628 remopts[TELOPT_NEW_ENVIRON] = OPT_YES_BUT_ALWAYS_LOOK; 2629 } 2630 2631 if (sequenceIs(oenvironopt, getterminal)) { 2632 send_do(TELOPT_OLD_ENVIRON); 2633 remopts[TELOPT_OLD_ENVIRON] = OPT_YES_BUT_ALWAYS_LOOK; 2634 } 2635 2636 /* make sure encryption is started here */ 2637 while (auth_status != AUTH_REJECT && 2638 authenticated != &NoAuth && authenticated != NULL && 2639 remopts[TELOPT_ENCRYPT] == OPT_YES && 2640 encr_data.encrypt.autoflag && 2641 encr_data.encrypt.state != ENCR_STATE_OK) { 2642 if (enc_debug) 2643 (void) fprintf(stderr, "getterminaltype() forcing encrypt\n"); 2644 ttloop(); 2645 } 2646 2647 if (enc_debug) { 2648 (void) fprintf(stderr, "getterminaltype() encryption %sstarted\n", 2649 encr_data.encrypt.state == ENCR_STATE_OK ? "" : "not "); 2650 } 2651 2652 while (sequenceIs(ttypeopt, getterminal) || 2653 sequenceIs(nawsopt, getterminal) || 2654 sequenceIs(xdisplocopt, getterminal) || 2655 sequenceIs(environopt, getterminal) || 2656 sequenceIs(oenvironopt, getterminal)) { 2657 ttloop(); 2658 } 2659 2660 2661 if (remopts[TELOPT_TTYPE] == OPT_YES) { 2662 static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB, 2663 (uchar_t)TELOPT_TTYPE, (uchar_t)TELQUAL_SEND, 2664 (uchar_t)IAC, (uchar_t)SE }; 2665 2666 write_data_len((const char *)sbbuf, sizeof (sbbuf)); 2667 } 2668 if (remopts[TELOPT_XDISPLOC] == OPT_YES) { 2669 static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB, 2670 (uchar_t)TELOPT_XDISPLOC, (uchar_t)TELQUAL_SEND, 2671 (uchar_t)IAC, (uchar_t)SE }; 2672 2673 write_data_len((const char *)sbbuf, sizeof (sbbuf)); 2674 } 2675 if (remopts[TELOPT_NEW_ENVIRON] == OPT_YES) { 2676 static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB, 2677 (uchar_t)TELOPT_NEW_ENVIRON, (uchar_t)TELQUAL_SEND, 2678 (uchar_t)IAC, (uchar_t)SE }; 2679 2680 write_data_len((const char *)sbbuf, sizeof (sbbuf)); 2681 } 2682 if (remopts[TELOPT_OLD_ENVIRON] == OPT_YES) { 2683 static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB, 2684 (uchar_t)TELOPT_OLD_ENVIRON, (uchar_t)TELQUAL_SEND, 2685 (uchar_t)IAC, (uchar_t)SE }; 2686 2687 write_data_len((const char *)sbbuf, sizeof (sbbuf)); 2688 } 2689 2690 if (remopts[TELOPT_TTYPE] == OPT_YES) { 2691 while (sequenceIs(ttypesubopt, getterminal)) { 2692 ttloop(); 2693 } 2694 } 2695 if (remopts[TELOPT_XDISPLOC] == OPT_YES) { 2696 while (sequenceIs(xdisplocsubopt, getterminal)) { 2697 ttloop(); 2698 } 2699 } 2700 if (remopts[TELOPT_NEW_ENVIRON] == OPT_YES) { 2701 while (sequenceIs(environsubopt, getterminal)) { 2702 ttloop(); 2703 } 2704 } 2705 if (remopts[TELOPT_OLD_ENVIRON] == OPT_YES) { 2706 while (sequenceIs(oenvironsubopt, getterminal)) { 2707 ttloop(); 2708 } 2709 } 2710 init_neg_done = 1; 2711 } 2712 2713 pid_t pid; 2714 2715 /* 2716 * Get a pty, scan input lines. 2717 */ 2718 static void 2719 doit(int f, struct sockaddr_storage *who) 2720 { 2721 char *host; 2722 char host_name[MAXHOSTNAMELEN]; 2723 int p, t, tt; 2724 struct sgttyb b; 2725 int ptmfd; /* fd of logindmux connected to pty */ 2726 int netfd; /* fd of logindmux connected to netf */ 2727 struct stat buf; 2728 struct protocol_arg telnetp; 2729 struct strioctl telnetmod; 2730 struct envlist *env, *next; 2731 int nsize = 0; 2732 char abuf[INET6_ADDRSTRLEN]; 2733 struct sockaddr_in *sin; 2734 struct sockaddr_in6 *sin6; 2735 socklen_t wholen; 2736 char username[MAXUSERNAMELEN]; 2737 int len; 2738 uchar_t passthru; 2739 char *slavename; 2740 2741 if ((p = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) { 2742 fatalperror(f, "open /dev/ptmx", errno); 2743 } 2744 if (grantpt(p) == -1) 2745 fatal(f, "could not grant slave pty"); 2746 if (unlockpt(p) == -1) 2747 fatal(f, "could not unlock slave pty"); 2748 if ((slavename = ptsname(p)) == NULL) 2749 fatal(f, "could not enable slave pty"); 2750 (void) dup2(f, 0); 2751 if ((t = open(slavename, O_RDWR | O_NOCTTY)) == -1) 2752 fatal(f, "could not open slave pty"); 2753 if (ioctl(t, I_PUSH, "ptem") == -1) 2754 fatalperror(f, "ioctl I_PUSH ptem", errno); 2755 if (ioctl(t, I_PUSH, "ldterm") == -1) 2756 fatalperror(f, "ioctl I_PUSH ldterm", errno); 2757 if (ioctl(t, I_PUSH, "ttcompat") == -1) 2758 fatalperror(f, "ioctl I_PUSH ttcompat", errno); 2759 2760 line = slavename; 2761 2762 pty = t; 2763 2764 if (ioctl(t, TIOCGETP, &b) == -1) 2765 syslog(LOG_INFO, "ioctl TIOCGETP pty t: %m\n"); 2766 b.sg_flags = O_CRMOD|O_XTABS|O_ANYP; 2767 /* XXX - ispeed and ospeed must be non-zero */ 2768 b.sg_ispeed = B38400; 2769 b.sg_ospeed = B38400; 2770 if (ioctl(t, TIOCSETN, &b) == -1) 2771 syslog(LOG_INFO, "ioctl TIOCSETN pty t: %m\n"); 2772 if (ioctl(pty, TIOCGETP, &b) == -1) 2773 syslog(LOG_INFO, "ioctl TIOCGETP pty pty: %m\n"); 2774 b.sg_flags &= ~O_ECHO; 2775 if (ioctl(pty, TIOCSETN, &b) == -1) 2776 syslog(LOG_INFO, "ioctl TIOCSETN pty pty: %m\n"); 2777 2778 if (who->ss_family == AF_INET) { 2779 char *addrbuf = NULL; 2780 char *portbuf = NULL; 2781 2782 sin = (struct sockaddr_in *)who; 2783 wholen = sizeof (struct sockaddr_in); 2784 2785 addrbuf = (char *)malloc(wholen); 2786 if (addrbuf == NULL) 2787 fatal(f, "Cannot alloc memory for address info\n"); 2788 portbuf = (char *)malloc(sizeof (sin->sin_port)); 2789 if (portbuf == NULL) { 2790 free(addrbuf); 2791 fatal(f, "Cannot alloc memory for port info\n"); 2792 } 2793 2794 (void) memcpy(addrbuf, (const void *)&sin->sin_addr, wholen); 2795 (void) memcpy(portbuf, (const void *)&sin->sin_port, 2796 sizeof (sin->sin_port)); 2797 2798 if (rsaddr.contents != NULL) 2799 free(rsaddr.contents); 2800 2801 rsaddr.contents = (krb5_octet *)addrbuf; 2802 rsaddr.length = wholen; 2803 rsaddr.addrtype = ADDRTYPE_INET; 2804 2805 if (rsport.contents != NULL) 2806 free(rsport.contents); 2807 2808 rsport.contents = (krb5_octet *)portbuf; 2809 rsport.length = sizeof (sin->sin_port); 2810 rsport.addrtype = ADDRTYPE_IPPORT; 2811 } else if (who->ss_family == AF_INET6) { 2812 struct in_addr ipv4_addr; 2813 char *addrbuf = NULL; 2814 char *portbuf = NULL; 2815 2816 sin6 = (struct sockaddr_in6 *)who; 2817 wholen = sizeof (struct sockaddr_in6); 2818 2819 IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr, 2820 &ipv4_addr); 2821 2822 addrbuf = (char *)malloc(wholen); 2823 if (addrbuf == NULL) 2824 fatal(f, "Cannot alloc memory for address info\n"); 2825 2826 portbuf = (char *)malloc(sizeof (sin6->sin6_port)); 2827 if (portbuf == NULL) { 2828 free(addrbuf); 2829 fatal(f, "Cannot alloc memory for port info\n"); 2830 } 2831 2832 (void) memcpy((void *) addrbuf, 2833 (const void *)&ipv4_addr, 2834 wholen); 2835 /* 2836 * If we already used rsaddr.contents, free the previous 2837 * buffer. 2838 */ 2839 if (rsaddr.contents != NULL) 2840 free(rsaddr.contents); 2841 2842 rsaddr.contents = (krb5_octet *)addrbuf; 2843 rsaddr.length = sizeof (ipv4_addr); 2844 rsaddr.addrtype = ADDRTYPE_INET; 2845 2846 (void) memcpy((void *) portbuf, (const void *)&sin6->sin6_port, 2847 sizeof (sin6->sin6_port)); 2848 2849 if (rsport.contents != NULL) 2850 free(rsport.contents); 2851 2852 rsport.contents = (krb5_octet *)portbuf; 2853 rsport.length = sizeof (sin6->sin6_port); 2854 rsport.addrtype = ADDRTYPE_IPPORT; 2855 } else { 2856 syslog(LOG_ERR, "unknown address family %d\n", 2857 who->ss_family); 2858 fatal(f, "getpeername: unknown address family\n"); 2859 } 2860 2861 if (getnameinfo((const struct sockaddr *) who, wholen, host_name, 2862 sizeof (host_name), NULL, 0, 0) == 0) { 2863 host = host_name; 2864 } else { 2865 /* 2866 * If the '-U' option was given on the cmd line, we must 2867 * be able to lookup the hostname 2868 */ 2869 if (resolve_hostname) { 2870 fatal(f, "Couldn't resolve your address into a " 2871 "host name.\r\nPlease contact your net " 2872 "administrator"); 2873 } 2874 2875 if (who->ss_family == AF_INET6) { 2876 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 2877 struct in_addr ipv4_addr; 2878 2879 IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr, 2880 &ipv4_addr); 2881 host = (char *)inet_ntop(AF_INET, 2882 &ipv4_addr, abuf, sizeof (abuf)); 2883 } else { 2884 host = (char *)inet_ntop(AF_INET6, 2885 &sin6->sin6_addr, abuf, 2886 sizeof (abuf)); 2887 } 2888 } else if (who->ss_family == AF_INET) { 2889 host = (char *)inet_ntop(AF_INET, 2890 &sin->sin_addr, abuf, sizeof (abuf)); 2891 } 2892 } 2893 /* 2894 * Note that sockmod has to be removed since readstream assumes 2895 * a "raw" TPI endpoint (e.g. it uses getmsg). 2896 */ 2897 if (removemod(f, "sockmod") < 0) 2898 fatalperror(f, "couldn't remove sockmod", errno); 2899 2900 encrypt_init(); 2901 2902 /* 2903 * Push the crypto module on the stream before 'telmod' so it 2904 * can encrypt/decrypt without interfering with telmod functionality 2905 * We must push it now because many of the crypto options negotiated 2906 * initially must be saved in the crypto module (via IOCTL calls). 2907 */ 2908 if (ioctl(f, I_PUSH, "cryptmod") < 0) 2909 fatalperror(f, "ioctl I_PUSH cryptmod", errno); 2910 2911 cryptmod_fd = f; 2912 /* 2913 * gotta set the encryption clock now because it is often negotiated 2914 * immediately by the client, and if we wait till after we negotiate 2915 * auth, it will be out of whack with when the WILL/WONT ENCRYPT 2916 * option is received. 2917 */ 2918 settimer(getencr); 2919 2920 /* 2921 * get terminal type. 2922 */ 2923 username[0] = '\0'; 2924 len = sizeof (username); 2925 2926 settimer(getterminal); 2927 settimer(getauth); 2928 /* 2929 * Exchange TELOPT_AUTHENTICATE options per RFC 2941/2942 2930 */ 2931 auth_status = getauthtype(username, &len); 2932 /* 2933 * Exchange TELOPT_ENCRYPT options per RFC 2946 2934 */ 2935 getencrtype(); 2936 getterminaltype(); 2937 2938 if (ioctl(f, I_PUSH, "telmod") < 0) 2939 fatalperror(f, "ioctl I_PUSH telmod", errno); 2940 2941 /* 2942 * Make sure telmod will pass unrecognized IOCTLs to cryptmod 2943 */ 2944 passthru = 1; 2945 2946 telnetmod.ic_cmd = CRYPTPASSTHRU; 2947 telnetmod.ic_timout = -1; 2948 telnetmod.ic_len = sizeof (uchar_t); 2949 telnetmod.ic_dp = (char *)&passthru; 2950 2951 if (ioctl(f, I_STR, &telnetmod) < 0) 2952 fatal(f, "ioctl CRPASSTHRU failed\n"); 2953 2954 if (!ncc) 2955 netip = netibuf; 2956 2957 /* 2958 * readstream will do a getmsg till it receives M_PROTO type 2959 * T_DATA_REQ from telnetmodopen(). This signals that all data 2960 * in-flight before telmod was pushed has been received at the 2961 * stream head. 2962 */ 2963 while ((nsize = readstream(f, netibuf, ncc + netip - netibuf)) > 0) { 2964 ncc += nsize; 2965 } 2966 2967 if (nsize < 0) { 2968 fatalperror(f, "readstream failed\n", errno); 2969 } 2970 2971 /* 2972 * open logindmux drivers and link them with network and ptm 2973 * file descriptors. 2974 */ 2975 if ((ptmfd = open("/dev/logindmux", O_RDWR)) == -1) { 2976 fatalperror(f, "open /dev/logindmux", errno); 2977 } 2978 if ((netfd = open("/dev/logindmux", O_RDWR)) == -1) { 2979 fatalperror(f, "open /dev/logindmux", errno); 2980 } 2981 2982 if (ioctl(ptmfd, I_LINK, p) < 0) 2983 fatal(f, "ioctl I_LINK of /dev/ptmx failed\n"); 2984 if (ioctl(netfd, I_LINK, f) < 0) 2985 fatal(f, "ioctl I_LINK of tcp connection failed\n"); 2986 2987 /* 2988 * Figure out the device number of ptm's mux fd, and pass that 2989 * to the net's mux. 2990 */ 2991 if (fstat(ptmfd, &buf) < 0) { 2992 fatalperror(f, "fstat ptmfd failed", errno); 2993 } 2994 telnetp.dev = buf.st_rdev; 2995 telnetp.flag = 0; 2996 2997 telnetmod.ic_cmd = LOGDMX_IOC_QEXCHANGE; 2998 telnetmod.ic_timout = -1; 2999 telnetmod.ic_len = sizeof (struct protocol_arg); 3000 telnetmod.ic_dp = (char *)&telnetp; 3001 3002 if (ioctl(netfd, I_STR, &telnetmod) < 0) 3003 fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of netfd failed\n"); 3004 3005 /* 3006 * Figure out the device number of the net's mux fd, and pass that 3007 * to the ptm's mux. 3008 */ 3009 if (fstat(netfd, &buf) < 0) { 3010 fatalperror(f, "fstat netfd failed", errno); 3011 } 3012 telnetp.dev = buf.st_rdev; 3013 telnetp.flag = 1; 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(ptmfd, I_STR, &telnetmod) < 0) 3021 fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of ptmfd failed\n"); 3022 3023 net = netfd; 3024 master = ptmfd; 3025 cryptmod_fd = netfd; 3026 3027 /* 3028 * Show banner that getty never gave, but 3029 * only if the user did not automatically authenticate. 3030 */ 3031 if (getenv("USER") == '\0' && auth_status < AUTH_USER) 3032 showbanner(); 3033 3034 /* 3035 * If the user automatically authenticated with Kerberos 3036 * we must set the service name that PAM will use. We 3037 * need to do it BEFORE the child fork so that 'cleanup' 3038 * in the parent can call the PAM cleanup stuff with the 3039 * same PAM service that /bin/login will use to authenticate 3040 * this session. 3041 */ 3042 if (auth_level >= 0 && auth_status >= AUTH_USER && 3043 (AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) { 3044 (void) strcpy(pam_svc_name, "ktelnet"); 3045 } 3046 /* 3047 * Request to do suppress go ahead. 3048 * 3049 * Send this before sending the TELOPT_ECHO stuff below because 3050 * some clients (MIT KRB5 telnet) have quirky 'kludge mode' support 3051 * that has them turn off local echo mode if SGA is not received first. 3052 * This also has the odd side-effect of causing the client to enable 3053 * encryption and then immediately disable it during the ECHO option 3054 * negotiations. Its just better to to SGA first now that we support 3055 * encryption. 3056 */ 3057 if (!myopts[TELOPT_SGA]) { 3058 dooption(TELOPT_SGA); 3059 } 3060 3061 /* 3062 * Pretend we got a DO ECHO from the client if we have not 3063 * yet negotiated the ECHO. 3064 */ 3065 if (!myopts[TELOPT_ECHO]) { 3066 dooption(TELOPT_ECHO); 3067 } 3068 3069 /* 3070 * Is the client side a 4.2 (NOT 4.3) system? We need to know this 3071 * because 4.2 clients are unable to deal with TCP urgent data. 3072 * 3073 * To find out, we send out a "DO ECHO". If the remote system 3074 * answers "WILL ECHO" it is probably a 4.2 client, and we note 3075 * that fact ("WILL ECHO" ==> that the client will echo what 3076 * WE, the server, sends it; it does NOT mean that the client will 3077 * echo the terminal input). 3078 */ 3079 send_do(TELOPT_ECHO); 3080 remopts[TELOPT_ECHO] = OPT_YES_BUT_ALWAYS_LOOK; 3081 3082 if ((pid = fork()) < 0) 3083 fatalperror(netfd, "fork", errno); 3084 if (pid) 3085 telnet(net, master); 3086 /* 3087 * The child process needs to be the session leader 3088 * and have the pty as its controlling tty. Thus we need 3089 * to re-open the slave side of the pty no without 3090 * the O_NOCTTY flag that we have been careful to 3091 * use up to this point. 3092 */ 3093 (void) setsid(); 3094 3095 tt = open(line, O_RDWR); 3096 if (tt < 0) 3097 fatalperror(netfd, line, errno); 3098 (void) close(netfd); 3099 (void) close(ptmfd); 3100 (void) close(f); 3101 (void) close(p); 3102 (void) close(t); 3103 if (tt != 0) 3104 (void) dup2(tt, 0); 3105 if (tt != 1) 3106 (void) dup2(tt, 1); 3107 if (tt != 2) 3108 (void) dup2(tt, 2); 3109 if (tt > 2) 3110 (void) close(tt); 3111 3112 if (terminaltype) 3113 (void) local_setenv("TERM", terminaltype+5, 1); 3114 /* 3115 * -h : pass on name of host. 3116 * WARNING: -h is accepted by login if and only if 3117 * getuid() == 0. 3118 * -p : don't clobber the environment (so terminal type stays set). 3119 */ 3120 { 3121 /* System V login expects a utmp entry to already be there */ 3122 struct utmpx ut; 3123 (void) memset((char *)&ut, 0, sizeof (ut)); 3124 (void) strncpy(ut.ut_user, ".telnet", sizeof (ut.ut_user)); 3125 (void) strncpy(ut.ut_line, line, sizeof (ut.ut_line)); 3126 ut.ut_pid = getpid(); 3127 ut.ut_id[0] = 't'; 3128 ut.ut_id[1] = (char)SC_WILDC; 3129 ut.ut_id[2] = (char)SC_WILDC; 3130 ut.ut_id[3] = (char)SC_WILDC; 3131 ut.ut_type = LOGIN_PROCESS; 3132 ut.ut_exit.e_termination = 0; 3133 ut.ut_exit.e_exit = 0; 3134 (void) time(&ut.ut_tv.tv_sec); 3135 if (makeutx(&ut) == NULL) 3136 syslog(LOG_INFO, "in.telnetd:\tmakeutx failed"); 3137 } 3138 3139 /* 3140 * Load in the cached environment variables and either 3141 * set/unset them in the environment. 3142 */ 3143 for (next = envlist_head; next; ) { 3144 env = next; 3145 if (env->delete) 3146 (void) local_unsetenv(env->name); 3147 else 3148 (void) local_setenv(env->name, env->value, 1); 3149 free(env->name); 3150 free(env->value); 3151 next = env->next; 3152 free(env); 3153 } 3154 3155 if (!username || !username[0]) 3156 auth_status = AUTH_REJECT; /* we dont know who this is */ 3157 3158 /* If the current auth status is less than the required level, exit */ 3159 if (auth_status < auth_level) { 3160 fatal(net, "Authentication failed\n"); 3161 exit(EXIT_FAILURE); 3162 } 3163 3164 /* 3165 * If AUTH_VALID (proper authentication REQUIRED and we have 3166 * a krb5_name), exec '/bin/login', make sure it uses the 3167 * correct PAM service name (pam_svc_name). If possible, 3168 * make sure the krb5 authenticated user's name (krb5_name) 3169 * is in the PAM REPOSITORY for krb5. 3170 */ 3171 if (auth_level >= 0 && 3172 (auth_status == AUTH_VALID || auth_status == AUTH_USER) && 3173 ((krb5_name != NULL) && strlen(krb5_name)) && 3174 ((AuthenticatingUser != NULL) && strlen(AuthenticatingUser))) { 3175 (void) execl(LOGIN_PROGRAM, "login", 3176 "-p", 3177 "-d", slavename, 3178 "-h", host, 3179 "-u", krb5_name, 3180 "-s", pam_svc_name, 3181 "-R", KRB5_REPOSITORY_NAME, 3182 AuthenticatingUser, 0); 3183 } else if (auth_level >= 0 && 3184 auth_status >= AUTH_USER && 3185 (((AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) || 3186 getenv("USER"))) { 3187 /* 3188 * If we only know the name but not the principal, 3189 * login will have to authenticate further. 3190 */ 3191 (void) execl(LOGIN_PROGRAM, "login", 3192 "-p", 3193 "-d", slavename, 3194 "-h", host, 3195 "-s", pam_svc_name, "--", 3196 (AuthenticatingUser != NULL ? AuthenticatingUser : 3197 getenv("USER")), 0); 3198 3199 } else /* default, no auth. info available, login does it all */ { 3200 (void) execl(LOGIN_PROGRAM, "login", 3201 "-p", "-h", host, "-d", slavename, "--", 3202 getenv("USER"), 0); 3203 } 3204 3205 fatalperror(netfd, LOGIN_PROGRAM, errno); 3206 /*NOTREACHED*/ 3207 } 3208 3209 static void 3210 fatal(int f, char *msg) 3211 { 3212 char buf[BUFSIZ]; 3213 3214 (void) snprintf(buf, sizeof (buf), "telnetd: %s.\r\n", msg); 3215 (void) write(f, buf, strlen(buf)); 3216 exit(EXIT_FAILURE); 3217 /*NOTREACHED*/ 3218 } 3219 3220 static void 3221 fatalperror(int f, char *msg, int errnum) 3222 { 3223 char buf[BUFSIZ]; 3224 3225 (void) snprintf(buf, sizeof (buf), 3226 "%s: %s\r\n", msg, strerror(errnum)); 3227 fatal(f, buf); 3228 /*NOTREACHED*/ 3229 } 3230 3231 /* 3232 * Main loop. Select from pty and network, and 3233 * hand data to telnet receiver finite state machine 3234 * when it receives telnet protocol. Regular data 3235 * flow between pty and network takes place through 3236 * inkernel telnet streams module (telmod). 3237 */ 3238 static void 3239 telnet(int net, int master) 3240 { 3241 int on = 1; 3242 char mode; 3243 struct strioctl telnetmod; 3244 int nsize = 0; 3245 char binary_in = 0; 3246 char binary_out = 0; 3247 3248 if (ioctl(net, FIONBIO, &on) == -1) 3249 syslog(LOG_INFO, "ioctl FIONBIO net: %m\n"); 3250 if (ioctl(master, FIONBIO, &on) == -1) 3251 syslog(LOG_INFO, "ioctl FIONBIO pty p: %m\n"); 3252 (void) signal(SIGTSTP, SIG_IGN); 3253 (void) signal(SIGCHLD, (void (*)())cleanup); 3254 (void) setpgrp(); 3255 3256 /* 3257 * Call telrcv() once to pick up anything received during 3258 * terminal type negotiation. 3259 */ 3260 telrcv(); 3261 3262 netflush(); 3263 ptyflush(); 3264 3265 for (;;) { 3266 fd_set ibits, obits, xbits; 3267 int c; 3268 3269 if (ncc < 0) 3270 break; 3271 3272 FD_ZERO(&ibits); 3273 FD_ZERO(&obits); 3274 FD_ZERO(&xbits); 3275 3276 /* 3277 * If we couldn't flush all our output to the network, 3278 * keep checking for when we can. 3279 */ 3280 if (nfrontp - nbackp) 3281 FD_SET(net, &obits); 3282 /* 3283 * Never look for input if there's still 3284 * stuff in the corresponding output buffer 3285 */ 3286 if (pfrontp - pbackp) { 3287 FD_SET(master, &obits); 3288 } else { 3289 FD_SET(net, &ibits); 3290 } 3291 if (!SYNCHing) { 3292 FD_SET(net, &xbits); 3293 } 3294 3295 #define max(x, y) (((x) < (y)) ? (y) : (x)) 3296 3297 /* 3298 * make an ioctl to telnet module (net side) to send 3299 * binary mode of telnet daemon. binary_in and 3300 * binary_out are 0 if not in binary mode. 3301 */ 3302 if (binary_in != myopts[TELOPT_BINARY] || 3303 binary_out != remopts[TELOPT_BINARY]) { 3304 3305 mode = 0; 3306 if (myopts[TELOPT_BINARY] != OPT_NO) 3307 mode |= TEL_BINARY_IN; 3308 3309 if (remopts[TELOPT_BINARY] != OPT_NO) 3310 mode |= TEL_BINARY_OUT; 3311 3312 telnetmod.ic_cmd = TEL_IOC_MODE; 3313 telnetmod.ic_timout = -1; 3314 telnetmod.ic_len = 1; 3315 telnetmod.ic_dp = &mode; 3316 3317 syslog(LOG_DEBUG, "TEL_IOC_MODE binary has changed\n"); 3318 3319 if (ioctl(net, I_STR, &telnetmod) < 0) 3320 fatal(net, "ioctl TEL_IOC_MODE failed\n"); 3321 binary_in = myopts[TELOPT_BINARY]; 3322 binary_out = remopts[TELOPT_BINARY]; 3323 } 3324 if (state == TS_DATA) { 3325 if ((nfrontp == nbackp) && 3326 (pfrontp == pbackp)) { 3327 if (ioctl(net, I_NREAD, &nsize) < 0) 3328 fatalperror(net, 3329 "ioctl I_NREAD failed\n", errno); 3330 if (nsize) 3331 drainstream(nsize); 3332 3333 /* 3334 * make an ioctl to reinsert remaining data at 3335 * streamhead. After this, ioctl reenables the 3336 * telnet lower put queue. This queue was 3337 * noenabled by telnet module after sending 3338 * protocol/urgent data to telnetd. 3339 */ 3340 3341 telnetmod.ic_cmd = TEL_IOC_ENABLE; 3342 telnetmod.ic_timout = -1; 3343 if (ncc || nsize) { 3344 telnetmod.ic_len = ncc + nsize; 3345 telnetmod.ic_dp = netip; 3346 } else { 3347 telnetmod.ic_len = 0; 3348 telnetmod.ic_dp = NULL; 3349 } 3350 if (ioctl(net, I_STR, &telnetmod) < 0) 3351 fatal(net, "ioctl TEL_IOC_ENABLE \ 3352 failed\n"); 3353 3354 telmod_init_done = B_TRUE; 3355 3356 netip = netibuf; 3357 (void) memset(netibuf, 0, netibufsize); 3358 3359 ncc = 0; 3360 } 3361 } else { 3362 /* 3363 * state not changed to TS_DATA and hence, more to read 3364 * send ioctl to get one more message block. 3365 */ 3366 telnetmod.ic_cmd = TEL_IOC_GETBLK; 3367 telnetmod.ic_timout = -1; 3368 telnetmod.ic_len = 0; 3369 telnetmod.ic_dp = NULL; 3370 3371 if (ioctl(net, I_STR, &telnetmod) < 0) 3372 fatal(net, "ioctl TEL_IOC_GETBLK failed\n"); 3373 } 3374 3375 if ((c = select(max(net, master) + 1, &ibits, &obits, &xbits, 3376 (struct timeval *)0)) < 1) { 3377 if (c == -1) { 3378 if (errno == EINTR) { 3379 continue; 3380 } 3381 } 3382 (void) sleep(5); 3383 continue; 3384 } 3385 3386 /* 3387 * Any urgent data? 3388 */ 3389 if (FD_ISSET(net, &xbits)) { 3390 SYNCHing = 1; 3391 } 3392 3393 /* 3394 * Something to read from the network... 3395 */ 3396 if (FD_ISSET(net, &ibits)) { 3397 ncc = read(net, netibuf, netibufsize); 3398 if (ncc < 0 && errno == EWOULDBLOCK) 3399 ncc = 0; 3400 else { 3401 if (ncc <= 0) { 3402 break; 3403 } 3404 netip = netibuf; 3405 } 3406 } 3407 3408 if (FD_ISSET(net, &obits) && (nfrontp - nbackp) > 0) 3409 netflush(); 3410 if (ncc > 0) 3411 telrcv(); 3412 if (FD_ISSET(master, &obits) && (pfrontp - pbackp) > 0) 3413 ptyflush(); 3414 } 3415 cleanup(0); 3416 } 3417 3418 static void 3419 telrcv(void) 3420 { 3421 int c; 3422 3423 while (ncc > 0) { 3424 if ((&ptyobuf[BUFSIZ] - pfrontp) < 2) 3425 return; 3426 c = *netip & 0377; 3427 /* 3428 * Once we hit data, we want to transition back to 3429 * in-kernel processing. However, this code is shared 3430 * by getterminaltype()/ttloop() which run before the 3431 * in-kernel plumbing is available. So if we are still 3432 * processing the initial option negotiation, even TS_DATA 3433 * must be processed here. 3434 */ 3435 if (c != IAC && state == TS_DATA && init_neg_done) { 3436 break; 3437 } 3438 netip++; 3439 ncc--; 3440 switch (state) { 3441 3442 case TS_CR: 3443 state = TS_DATA; 3444 /* Strip off \n or \0 after a \r */ 3445 if ((c == 0) || (c == '\n')) { 3446 break; 3447 } 3448 /* FALLTHRU */ 3449 3450 case TS_DATA: 3451 if (c == IAC) { 3452 state = TS_IAC; 3453 break; 3454 } 3455 if (inter > 0) 3456 break; 3457 /* 3458 * We map \r\n ==> \r, since 3459 * We now map \r\n ==> \r for pragmatic reasons. 3460 * Many client implementations send \r\n when 3461 * the user hits the CarriageReturn key. 3462 * 3463 * We USED to map \r\n ==> \n, since \r\n says 3464 * that we want to be in column 1 of the next 3465 * line. 3466 */ 3467 if (c == '\r' && (myopts[TELOPT_BINARY] == OPT_NO)) { 3468 state = TS_CR; 3469 } 3470 *pfrontp++ = c; 3471 break; 3472 3473 case TS_IAC: 3474 switch (c) { 3475 3476 /* 3477 * Send the process on the pty side an 3478 * interrupt. Do this with a NULL or 3479 * interrupt char; depending on the tty mode. 3480 */ 3481 case IP: 3482 interrupt(); 3483 break; 3484 3485 case BREAK: 3486 sendbrk(); 3487 break; 3488 3489 /* 3490 * Are You There? 3491 */ 3492 case AYT: 3493 write_data_len("\r\n[Yes]\r\n", 9); 3494 break; 3495 3496 /* 3497 * Abort Output 3498 */ 3499 case AO: { 3500 struct ltchars tmpltc; 3501 3502 ptyflush(); /* half-hearted */ 3503 if (ioctl(pty, TIOCGLTC, &tmpltc) == -1) 3504 syslog(LOG_INFO, 3505 "ioctl TIOCGLTC: %m\n"); 3506 if (tmpltc.t_flushc != '\377') { 3507 *pfrontp++ = tmpltc.t_flushc; 3508 } 3509 netclear(); /* clear buffer back */ 3510 write_data("%c%c", (uchar_t)IAC, 3511 (uchar_t)DM); 3512 3513 neturg = nfrontp-1; /* off by one XXX */ 3514 netflush(); 3515 netflush(); /* XXX.sparker */ 3516 break; 3517 } 3518 3519 /* 3520 * Erase Character and 3521 * Erase Line 3522 */ 3523 case EC: 3524 case EL: { 3525 struct sgttyb b; 3526 char ch; 3527 3528 ptyflush(); /* half-hearted */ 3529 if (ioctl(pty, TIOCGETP, &b) == -1) 3530 syslog(LOG_INFO, 3531 "ioctl TIOCGETP: %m\n"); 3532 ch = (c == EC) ? 3533 b.sg_erase : b.sg_kill; 3534 if (ch != '\377') { 3535 *pfrontp++ = ch; 3536 } 3537 break; 3538 } 3539 3540 /* 3541 * Check for urgent data... 3542 */ 3543 case DM: 3544 break; 3545 3546 /* 3547 * Begin option subnegotiation... 3548 */ 3549 case SB: 3550 state = TS_SB; 3551 SB_CLEAR(); 3552 continue; 3553 3554 case WILL: 3555 state = TS_WILL; 3556 continue; 3557 3558 case WONT: 3559 state = TS_WONT; 3560 continue; 3561 3562 case DO: 3563 state = TS_DO; 3564 continue; 3565 3566 case DONT: 3567 state = TS_DONT; 3568 continue; 3569 3570 case IAC: 3571 *pfrontp++ = c; 3572 break; 3573 } 3574 state = TS_DATA; 3575 break; 3576 case TS_SB: 3577 if (c == IAC) { 3578 state = TS_SE; 3579 } else { 3580 SB_ACCUM(c); 3581 } 3582 break; 3583 case TS_SE: 3584 if (c != SE) { 3585 if (c != IAC) { 3586 SB_ACCUM((uchar_t)IAC); 3587 } 3588 SB_ACCUM(c); 3589 state = TS_SB; 3590 3591 } else { 3592 SB_TERM(); 3593 suboption(); /* handle sub-option */ 3594 state = TS_DATA; 3595 } 3596 break; 3597 3598 case TS_WILL: 3599 if (remopts[c] != OPT_YES) 3600 willoption(c); 3601 state = TS_DATA; 3602 continue; 3603 3604 case TS_WONT: 3605 if (remopts[c] != OPT_NO) 3606 wontoption(c); 3607 state = TS_DATA; 3608 continue; 3609 3610 case TS_DO: 3611 if (myopts[c] != OPT_YES) 3612 dooption(c); 3613 state = TS_DATA; 3614 continue; 3615 3616 case TS_DONT: 3617 if (myopts[c] != OPT_NO) { 3618 dontoption(c); 3619 } 3620 state = TS_DATA; 3621 continue; 3622 3623 default: 3624 syslog(LOG_ERR, "telnetd: panic state=%d\n", state); 3625 (void) printf("telnetd: panic state=%d\n", state); 3626 exit(EXIT_FAILURE); 3627 } 3628 } 3629 } 3630 3631 static void 3632 willoption(int option) 3633 { 3634 uchar_t *fmt; 3635 boolean_t send_reply = B_TRUE; 3636 3637 switch (option) { 3638 case TELOPT_BINARY: 3639 mode(O_RAW, 0); 3640 fmt = doopt; 3641 break; 3642 3643 case TELOPT_ECHO: 3644 not42 = 0; /* looks like a 4.2 system */ 3645 /* 3646 * Now, in a 4.2 system, to break them out of ECHOing 3647 * (to the terminal) mode, we need to send a "WILL ECHO". 3648 * Kludge upon kludge! 3649 */ 3650 if (myopts[TELOPT_ECHO] == OPT_YES) { 3651 dooption(TELOPT_ECHO); 3652 } 3653 fmt = dont; 3654 break; 3655 case TELOPT_TTYPE: 3656 settimer(ttypeopt); 3657 goto common; 3658 3659 case TELOPT_NAWS: 3660 settimer(nawsopt); 3661 goto common; 3662 3663 case TELOPT_XDISPLOC: 3664 settimer(xdisplocopt); 3665 goto common; 3666 3667 case TELOPT_NEW_ENVIRON: 3668 settimer(environopt); 3669 goto common; 3670 3671 case TELOPT_AUTHENTICATION: 3672 settimer(authopt); 3673 if (remopts[option] == OPT_NO || 3674 negotiate_auth_krb5 == 0) 3675 fmt = dont; 3676 else 3677 fmt = doopt; 3678 break; 3679 3680 case TELOPT_OLD_ENVIRON: 3681 settimer(oenvironopt); 3682 goto common; 3683 common: 3684 if (remopts[option] == OPT_YES_BUT_ALWAYS_LOOK) { 3685 remopts[option] = OPT_YES; 3686 return; 3687 } 3688 /*FALLTHRU*/ 3689 case TELOPT_SGA: 3690 fmt = doopt; 3691 break; 3692 3693 case TELOPT_TM: 3694 fmt = dont; 3695 break; 3696 3697 case TELOPT_ENCRYPT: 3698 settimer(encropt); /* got response to do/dont */ 3699 if (enc_debug) 3700 (void) fprintf(stderr, 3701 "RCVD IAC WILL TELOPT_ENCRYPT\n"); 3702 if (krb5_privacy_allowed()) { 3703 fmt = doopt; 3704 if (sent_do_encrypt) 3705 send_reply = B_FALSE; 3706 else 3707 sent_do_encrypt = B_TRUE; 3708 } else { 3709 fmt = dont; 3710 } 3711 break; 3712 3713 default: 3714 fmt = dont; 3715 break; 3716 } 3717 if (fmt == doopt) { 3718 remopts[option] = OPT_YES; 3719 } else { 3720 remopts[option] = OPT_NO; 3721 } 3722 if (send_reply) { 3723 write_data((const char *)fmt, option); 3724 netflush(); 3725 } 3726 } 3727 3728 static void 3729 wontoption(int option) 3730 { 3731 uchar_t *fmt; 3732 int send_reply = 1; 3733 3734 switch (option) { 3735 case TELOPT_ECHO: 3736 not42 = 1; /* doesn't seem to be a 4.2 system */ 3737 break; 3738 3739 case TELOPT_BINARY: 3740 mode(0, O_RAW); 3741 break; 3742 3743 case TELOPT_TTYPE: 3744 settimer(ttypeopt); 3745 break; 3746 3747 case TELOPT_NAWS: 3748 settimer(nawsopt); 3749 break; 3750 3751 case TELOPT_XDISPLOC: 3752 settimer(xdisplocopt); 3753 break; 3754 3755 case TELOPT_NEW_ENVIRON: 3756 settimer(environopt); 3757 break; 3758 3759 case TELOPT_OLD_ENVIRON: 3760 settimer(oenvironopt); 3761 break; 3762 3763 case TELOPT_AUTHENTICATION: 3764 settimer(authopt); 3765 auth_finished(0, AUTH_REJECT); 3766 if (auth_debug) 3767 (void) fprintf(stderr, 3768 "RCVD WONT TELOPT_AUTHENTICATE\n"); 3769 3770 remopts[option] = OPT_NO; 3771 send_reply = 0; 3772 break; 3773 3774 case TELOPT_ENCRYPT: 3775 if (enc_debug) 3776 (void) fprintf(stderr, 3777 "RCVD IAC WONT TELOPT_ENCRYPT\n"); 3778 settimer(encropt); /* got response to will/wont */ 3779 /* 3780 * Remote side cannot send encryption. No reply necessary 3781 * Treat this as if "IAC SB ENCRYPT END IAC SE" were 3782 * received (RFC 2946) and disable crypto. 3783 */ 3784 encrypt_end(TELNET_DIR_DECRYPT); 3785 send_reply = 0; 3786 break; 3787 } 3788 3789 fmt = dont; 3790 remopts[option] = OPT_NO; 3791 if (send_reply) { 3792 write_data((const char *)fmt, option); 3793 } 3794 } 3795 3796 /* 3797 * We received an "IAC DO ..." message from the client, change our state 3798 * to OPT_YES. 3799 */ 3800 static void 3801 dooption(int option) 3802 { 3803 uchar_t *fmt; 3804 boolean_t send_reply = B_TRUE; 3805 3806 switch (option) { 3807 3808 case TELOPT_TM: 3809 fmt = wont; 3810 break; 3811 3812 case TELOPT_ECHO: 3813 mode(O_ECHO|O_CRMOD, 0); 3814 fmt = will; 3815 break; 3816 3817 case TELOPT_BINARY: 3818 mode(O_RAW, 0); 3819 fmt = will; 3820 break; 3821 3822 case TELOPT_SGA: 3823 fmt = will; 3824 break; 3825 3826 case TELOPT_LOGOUT: 3827 /* 3828 * Options don't get much easier. Acknowledge the option, 3829 * and then clean up and exit. 3830 */ 3831 write_data((const char *)will, option); 3832 netflush(); 3833 cleanup(0); 3834 /*NOTREACHED*/ 3835 3836 case TELOPT_ENCRYPT: 3837 if (enc_debug) 3838 (void) fprintf(stderr, "RCVD DO TELOPT_ENCRYPT\n"); 3839 settimer(encropt); 3840 /* 3841 * We received a "DO". This indicates that the other side 3842 * wants us to encrypt our data (pending negotiatoin). 3843 * reply with "IAC WILL ENCRYPT" if we are able to send 3844 * encrypted data. 3845 */ 3846 if (krb5_privacy_allowed() && negotiate_encrypt) { 3847 fmt = will; 3848 if (sent_will_encrypt) 3849 send_reply = B_FALSE; 3850 else 3851 sent_will_encrypt = B_TRUE; 3852 /* return if we already sent "WILL ENCRYPT" */ 3853 if (myopts[option] == OPT_YES) 3854 return; 3855 } else { 3856 fmt = wont; 3857 } 3858 break; 3859 3860 case TELOPT_AUTHENTICATION: 3861 if (auth_debug) { 3862 (void) fprintf(stderr, 3863 "RCVD DO TELOPT_AUTHENTICATION\n"); 3864 } 3865 /* 3866 * RFC 2941 - only the server can send 3867 * "DO TELOPT_AUTHENTICATION". 3868 * if a server receives this, it must respond with WONT... 3869 */ 3870 fmt = wont; 3871 break; 3872 3873 default: 3874 fmt = wont; 3875 break; 3876 } 3877 if (fmt == will) { 3878 myopts[option] = OPT_YES; 3879 } else { 3880 myopts[option] = OPT_NO; 3881 } 3882 if (send_reply) { 3883 write_data((const char *)fmt, option); 3884 netflush(); 3885 } 3886 } 3887 3888 /* 3889 * We received an "IAC DONT ..." message from client. 3890 * Client does not agree with the option so act accordingly. 3891 */ 3892 static void 3893 dontoption(int option) 3894 { 3895 int send_reply = 1; 3896 switch (option) { 3897 case TELOPT_ECHO: 3898 /* 3899 * we should stop echoing, since the client side will be doing 3900 * it, but keep mapping CR since CR-LF will be mapped to it. 3901 */ 3902 mode(0, O_ECHO); 3903 break; 3904 3905 case TELOPT_ENCRYPT: 3906 if (enc_debug) 3907 (void) fprintf(stderr, "RCVD IAC DONT ENCRYPT\n"); 3908 settimer(encropt); 3909 /* 3910 * Remote side cannot receive any encrypted data, 3911 * so dont send any. No reply necessary. 3912 */ 3913 send_reply = 0; 3914 break; 3915 3916 default: 3917 break; 3918 } 3919 3920 myopts[option] = OPT_NO; 3921 3922 if (send_reply) { 3923 write_data((const char *)wont, option); 3924 } 3925 } 3926 3927 /* 3928 * suboption() 3929 * 3930 * Look at the sub-option buffer, and try to be helpful to the other 3931 * side. 3932 * 3933 */ 3934 static void 3935 suboption(void) 3936 { 3937 int subchar; 3938 3939 switch (subchar = SB_GET()) { 3940 case TELOPT_TTYPE: { /* Yaaaay! */ 3941 static char terminalname[5+41] = "TERM="; 3942 3943 settimer(ttypesubopt); 3944 3945 if (SB_GET() != TELQUAL_IS) { 3946 return; /* ??? XXX but, this is the most robust */ 3947 } 3948 3949 terminaltype = terminalname+strlen(terminalname); 3950 3951 while (terminaltype < (terminalname + sizeof (terminalname) - 3952 1) && !SB_EOF()) { 3953 int c; 3954 3955 c = SB_GET(); 3956 if (isupper(c)) { 3957 c = tolower(c); 3958 } 3959 *terminaltype++ = c; /* accumulate name */ 3960 } 3961 *terminaltype = 0; 3962 terminaltype = terminalname; 3963 break; 3964 } 3965 3966 case TELOPT_NAWS: { 3967 struct winsize ws; 3968 3969 if (SB_EOF()) { 3970 return; 3971 } 3972 ws.ws_col = SB_GET() << 8; 3973 if (SB_EOF()) { 3974 return; 3975 } 3976 ws.ws_col |= SB_GET(); 3977 if (SB_EOF()) { 3978 return; 3979 } 3980 ws.ws_row = SB_GET() << 8; 3981 if (SB_EOF()) { 3982 return; 3983 } 3984 ws.ws_row |= SB_GET(); 3985 ws.ws_xpixel = 0; ws.ws_ypixel = 0; 3986 (void) ioctl(pty, TIOCSWINSZ, &ws); 3987 settimer(nawsopt); 3988 break; 3989 } 3990 3991 case TELOPT_XDISPLOC: { 3992 if (SB_EOF() || SB_GET() != TELQUAL_IS) { 3993 return; 3994 } 3995 settimer(xdisplocsubopt); 3996 subpointer[SB_LEN()] = '\0'; 3997 if ((new_env("DISPLAY", subpointer)) == 1) 3998 perror("malloc"); 3999 break; 4000 } 4001 4002 case TELOPT_NEW_ENVIRON: 4003 case TELOPT_OLD_ENVIRON: { 4004 int c; 4005 char *cp, *varp, *valp; 4006 4007 if (SB_EOF()) 4008 return; 4009 c = SB_GET(); 4010 if (c == TELQUAL_IS) { 4011 if (subchar == TELOPT_OLD_ENVIRON) 4012 settimer(oenvironsubopt); 4013 else 4014 settimer(environsubopt); 4015 } else if (c != TELQUAL_INFO) { 4016 return; 4017 } 4018 4019 if (subchar == TELOPT_NEW_ENVIRON) { 4020 while (!SB_EOF()) { 4021 c = SB_GET(); 4022 if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR)) 4023 break; 4024 } 4025 } else 4026 { 4027 while (!SB_EOF()) { 4028 c = SB_GET(); 4029 if ((c == env_ovar) || (c == ENV_USERVAR)) 4030 break; 4031 } 4032 } 4033 4034 if (SB_EOF()) 4035 return; 4036 4037 cp = varp = (char *)subpointer; 4038 valp = 0; 4039 4040 while (!SB_EOF()) { 4041 c = SB_GET(); 4042 if (subchar == TELOPT_OLD_ENVIRON) { 4043 if (c == env_ovar) 4044 c = NEW_ENV_VAR; 4045 else if (c == env_ovalue) 4046 c = NEW_ENV_VALUE; 4047 } 4048 switch (c) { 4049 4050 case NEW_ENV_VALUE: 4051 *cp = '\0'; 4052 cp = valp = (char *)subpointer; 4053 break; 4054 4055 case NEW_ENV_VAR: 4056 case ENV_USERVAR: 4057 *cp = '\0'; 4058 if (valp) { 4059 if ((new_env(varp, valp)) == 1) { 4060 perror("malloc"); 4061 } 4062 } else { 4063 (void) del_env(varp); 4064 } 4065 cp = varp = (char *)subpointer; 4066 valp = 0; 4067 break; 4068 4069 case ENV_ESC: 4070 if (SB_EOF()) 4071 break; 4072 c = SB_GET(); 4073 /* FALL THROUGH */ 4074 default: 4075 *cp++ = c; 4076 break; 4077 } 4078 } 4079 *cp = '\0'; 4080 if (valp) { 4081 if ((new_env(varp, valp)) == 1) { 4082 perror("malloc"); 4083 } 4084 } else { 4085 (void) del_env(varp); 4086 } 4087 break; 4088 } /* end of case TELOPT_NEW_ENVIRON */ 4089 4090 case TELOPT_AUTHENTICATION: 4091 if (SB_EOF()) 4092 break; 4093 switch (SB_GET()) { 4094 case TELQUAL_SEND: 4095 case TELQUAL_REPLY: 4096 /* 4097 * These are sent server only and cannot be sent by the 4098 * client. 4099 */ 4100 break; 4101 case TELQUAL_IS: 4102 if (auth_debug) 4103 (void) fprintf(stderr, 4104 "RCVD AUTHENTICATION IS " 4105 "(%d bytes)\n", 4106 SB_LEN()); 4107 if (!auth_negotiated) 4108 auth_is((uchar_t *)subpointer, SB_LEN()); 4109 break; 4110 case TELQUAL_NAME: 4111 if (auth_debug) 4112 (void) fprintf(stderr, 4113 "RCVD AUTHENTICATION NAME " 4114 "(%d bytes)\n", 4115 SB_LEN()); 4116 if (!auth_negotiated) 4117 auth_name((uchar_t *)subpointer, SB_LEN()); 4118 break; 4119 } 4120 break; 4121 4122 case TELOPT_ENCRYPT: { 4123 int c; 4124 if (SB_EOF()) 4125 break; 4126 c = SB_GET(); 4127 #ifdef ENCRYPT_NAMES 4128 if (enc_debug) 4129 (void) fprintf(stderr, "RCVD ENCRYPT %s\n", 4130 ENCRYPT_NAME(c)); 4131 #endif /* ENCRYPT_NAMES */ 4132 switch (c) { 4133 case ENCRYPT_SUPPORT: 4134 encrypt_support(subpointer, SB_LEN()); 4135 break; 4136 case ENCRYPT_IS: 4137 encrypt_is((uchar_t *)subpointer, SB_LEN()); 4138 break; 4139 case ENCRYPT_REPLY: 4140 (void) encrypt_reply(subpointer, SB_LEN()); 4141 break; 4142 case ENCRYPT_START: 4143 encrypt_start(); 4144 break; 4145 case ENCRYPT_END: 4146 encrypt_end(TELNET_DIR_DECRYPT); 4147 break; 4148 case ENCRYPT_REQSTART: 4149 encrypt_request_start(); 4150 break; 4151 case ENCRYPT_REQEND: 4152 /* 4153 * We can always send an REQEND so that we cannot 4154 * get stuck encrypting. We should only get this 4155 * if we have been able to get in the correct mode 4156 * anyhow. 4157 */ 4158 encrypt_request_end(); 4159 break; 4160 case ENCRYPT_ENC_KEYID: 4161 encrypt_enc_keyid(subpointer, SB_LEN()); 4162 break; 4163 case ENCRYPT_DEC_KEYID: 4164 encrypt_dec_keyid(subpointer, SB_LEN()); 4165 break; 4166 default: 4167 break; 4168 } 4169 } 4170 break; 4171 4172 default: 4173 break; 4174 } 4175 } 4176 4177 static void 4178 mode(int on, int off) 4179 { 4180 struct termios tios; 4181 4182 ptyflush(); 4183 if (tcgetattr(pty, &tios) < 0) 4184 syslog(LOG_INFO, "tcgetattr: %m\n"); 4185 4186 if (on & O_RAW) { 4187 tios.c_cflag |= CS8; 4188 tios.c_iflag &= ~IUCLC; 4189 tios.c_lflag &= ~(XCASE|IEXTEN); 4190 } 4191 if (off & O_RAW) { 4192 if ((tios.c_cflag & PARENB) != 0) 4193 tios.c_cflag &= ~CS8; 4194 tios.c_lflag |= IEXTEN; 4195 } 4196 4197 if (on & O_ECHO) 4198 tios.c_lflag |= ECHO; 4199 if (off & O_ECHO) 4200 tios.c_lflag &= ~ECHO; 4201 4202 if (on & O_CRMOD) { 4203 tios.c_iflag |= ICRNL; 4204 tios.c_oflag |= ONLCR; 4205 } 4206 /* 4207 * Because "O_CRMOD" will never be set in "off" we don't have to 4208 * handle this case here. 4209 */ 4210 4211 if (tcsetattr(pty, TCSANOW, &tios) < 0) 4212 syslog(LOG_INFO, "tcsetattr: %m\n"); 4213 } 4214 4215 /* 4216 * Send interrupt to process on other side of pty. 4217 * If it is in raw mode, just write NULL; 4218 * otherwise, write intr char. 4219 */ 4220 static void 4221 interrupt(void) 4222 { 4223 struct sgttyb b; 4224 struct tchars tchars; 4225 4226 ptyflush(); /* half-hearted */ 4227 if (ioctl(pty, TIOCGETP, &b) == -1) 4228 syslog(LOG_INFO, "ioctl TIOCGETP: %m\n"); 4229 if (b.sg_flags & O_RAW) { 4230 *pfrontp++ = '\0'; 4231 return; 4232 } 4233 *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ? 4234 '\177' : tchars.t_intrc; 4235 } 4236 4237 /* 4238 * Send quit to process on other side of pty. 4239 * If it is in raw mode, just write NULL; 4240 * otherwise, write quit char. 4241 */ 4242 static void 4243 sendbrk(void) 4244 { 4245 struct sgttyb b; 4246 struct tchars tchars; 4247 4248 ptyflush(); /* half-hearted */ 4249 (void) ioctl(pty, TIOCGETP, &b); 4250 if (b.sg_flags & O_RAW) { 4251 *pfrontp++ = '\0'; 4252 return; 4253 } 4254 *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ? 4255 '\034' : tchars.t_quitc; 4256 } 4257 4258 static void 4259 ptyflush(void) 4260 { 4261 int n; 4262 4263 if ((n = pfrontp - pbackp) > 0) 4264 n = write(master, pbackp, n); 4265 if (n < 0) 4266 return; 4267 pbackp += n; 4268 if (pbackp == pfrontp) 4269 pbackp = pfrontp = ptyobuf; 4270 } 4271 4272 /* 4273 * nextitem() 4274 * 4275 * Return the address of the next "item" in the TELNET data 4276 * stream. This will be the address of the next character if 4277 * the current address is a user data character, or it will 4278 * be the address of the character following the TELNET command 4279 * if the current address is a TELNET IAC ("I Am a Command") 4280 * character. 4281 */ 4282 4283 static char * 4284 nextitem(char *current) 4285 { 4286 if ((*current&0xff) != IAC) { 4287 return (current+1); 4288 } 4289 switch (*(current+1)&0xff) { 4290 case DO: 4291 case DONT: 4292 case WILL: 4293 case WONT: 4294 return (current+3); 4295 case SB: /* loop forever looking for the SE */ 4296 { 4297 char *look = current+2; 4298 4299 for (;;) { 4300 if ((*look++&0xff) == IAC) { 4301 if ((*look++&0xff) == SE) { 4302 return (look); 4303 } 4304 } 4305 } 4306 } 4307 default: 4308 return (current+2); 4309 } 4310 } 4311 4312 4313 /* 4314 * netclear() 4315 * 4316 * We are about to do a TELNET SYNCH operation. Clear 4317 * the path to the network. 4318 * 4319 * Things are a bit tricky since we may have sent the first 4320 * byte or so of a previous TELNET command into the network. 4321 * So, we have to scan the network buffer from the beginning 4322 * until we are up to where we want to be. 4323 * 4324 * A side effect of what we do, just to keep things 4325 * simple, is to clear the urgent data pointer. The principal 4326 * caller should be setting the urgent data pointer AFTER calling 4327 * us in any case. 4328 */ 4329 static void 4330 netclear(void) 4331 { 4332 char *thisitem, *next; 4333 char *good; 4334 #define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \ 4335 ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL)) 4336 4337 thisitem = netobuf; 4338 4339 while ((next = nextitem(thisitem)) <= nbackp) { 4340 thisitem = next; 4341 } 4342 4343 /* Now, thisitem is first before/at boundary. */ 4344 4345 good = netobuf; /* where the good bytes go */ 4346 4347 while (nfrontp > thisitem) { 4348 if (wewant(thisitem)) { 4349 int length; 4350 4351 next = thisitem; 4352 do { 4353 next = nextitem(next); 4354 } while (wewant(next) && (nfrontp > next)); 4355 length = next-thisitem; 4356 (void) memmove(good, thisitem, length); 4357 good += length; 4358 thisitem = next; 4359 } else { 4360 thisitem = nextitem(thisitem); 4361 } 4362 } 4363 4364 nbackp = netobuf; 4365 nfrontp = good; /* next byte to be sent */ 4366 neturg = 0; 4367 } 4368 4369 4370 /* 4371 * netflush 4372 * Send as much data as possible to the network, 4373 * handling requests for urgent data. 4374 */ 4375 static void 4376 netflush(void) 4377 { 4378 int n; 4379 4380 if ((n = nfrontp - nbackp) > 0) { 4381 /* 4382 * if no urgent data, or if the other side appears to be an 4383 * old 4.2 client (and thus unable to survive TCP urgent data), 4384 * write the entire buffer in non-OOB mode. 4385 */ 4386 if ((neturg == 0) || (not42 == 0)) { 4387 n = write(net, nbackp, n); /* normal write */ 4388 } else { 4389 n = neturg - nbackp; 4390 /* 4391 * In 4.2 (and 4.3) systems, there is some question 4392 * about what byte in a sendOOB operation is the "OOB" 4393 * data. To make ourselves compatible, we only send ONE 4394 * byte out of band, the one WE THINK should be OOB 4395 * (though we really have more the TCP philosophy of 4396 * urgent data rather than the Unix philosophy of OOB 4397 * data). 4398 */ 4399 if (n > 1) { 4400 /* send URGENT all by itself */ 4401 n = write(net, nbackp, n-1); 4402 } else { 4403 /* URGENT data */ 4404 n = send_oob(net, nbackp, n); 4405 } 4406 } 4407 } 4408 if (n < 0) { 4409 if (errno == EWOULDBLOCK) 4410 return; 4411 /* should blow this guy away... */ 4412 return; 4413 } 4414 4415 nbackp += n; 4416 4417 if (nbackp >= neturg) { 4418 neturg = 0; 4419 } 4420 if (nbackp == nfrontp) { 4421 nbackp = nfrontp = netobuf; 4422 } 4423 } 4424 4425 /* ARGSUSED */ 4426 static void 4427 cleanup(int signum) 4428 { 4429 /* 4430 * If the TEL_IOC_ENABLE ioctl hasn't completed, then we need to 4431 * handle closing differently. We close "net" first and then 4432 * "master" in that order. We do close(net) first because 4433 * we have no other way to disconnect forwarding between the network 4434 * and master. So by issuing the close()'s we ensure that no further 4435 * data rises from TCP. A more complex fix would be adding proper 4436 * support for throwing a "stop" switch for forwarding data between 4437 * logindmux peers. It's possible to block in the close of the tty 4438 * while the network still receives data and the telmod module is 4439 * TEL_STOPPED. A denial-of-service attack generates this case, 4440 * see 4102102. 4441 */ 4442 4443 if (!telmod_init_done) { 4444 (void) close(net); 4445 (void) close(master); 4446 } 4447 rmut(); 4448 4449 exit(EXIT_FAILURE); 4450 } 4451 4452 static void 4453 rmut(void) 4454 { 4455 pam_handle_t *pamh; 4456 struct utmpx *up; 4457 char user[sizeof (up->ut_user) + 1]; 4458 char ttyn[sizeof (up->ut_line) + 1]; 4459 char rhost[sizeof (up->ut_host) + 1]; 4460 4461 /* while cleaning up don't allow disruption */ 4462 (void) signal(SIGCHLD, SIG_IGN); 4463 4464 setutxent(); 4465 while (up = getutxent()) { 4466 if (up->ut_pid == pid) { 4467 if (up->ut_type == DEAD_PROCESS) { 4468 /* 4469 * Cleaned up elsewhere. 4470 */ 4471 break; 4472 } 4473 4474 /* 4475 * call pam_close_session if login changed 4476 * the utmpx user entry from type LOGIN_PROCESS 4477 * to type USER_PROCESS, which happens 4478 * after pam_open_session is called. 4479 */ 4480 if (up->ut_type == USER_PROCESS) { 4481 (void) strlcpy(user, up->ut_user, 4482 sizeof (user)); 4483 (void) strlcpy(ttyn, up->ut_line, 4484 sizeof (ttyn)); 4485 (void) strlcpy(rhost, up->ut_host, 4486 sizeof (rhost)); 4487 if ((pam_start("telnet", user, NULL, &pamh)) == 4488 PAM_SUCCESS) { 4489 (void) pam_set_item(pamh, PAM_TTY, 4490 ttyn); 4491 (void) pam_set_item(pamh, PAM_RHOST, 4492 rhost); 4493 (void) pam_close_session(pamh, 0); 4494 (void) pam_end(pamh, PAM_SUCCESS); 4495 } 4496 } 4497 4498 up->ut_type = DEAD_PROCESS; 4499 up->ut_exit.e_termination = WTERMSIG(0); 4500 up->ut_exit.e_exit = WEXITSTATUS(0); 4501 (void) time(&up->ut_tv.tv_sec); 4502 4503 if (modutx(up) == NULL) { 4504 /* 4505 * Since modutx failed we'll 4506 * write out the new entry 4507 * ourselves. 4508 */ 4509 (void) pututxline(up); 4510 updwtmpx("wtmpx", up); 4511 } 4512 break; 4513 } 4514 } 4515 4516 endutxent(); 4517 4518 (void) signal(SIGCHLD, (void (*)())cleanup); 4519 } 4520 4521 static int 4522 readstream(int fd, char *buf, int offset) 4523 { 4524 struct strbuf ctlbuf, datbuf; 4525 union T_primitives tpi; 4526 int ret = 0; 4527 int flags = 0; 4528 int bytes_avail, count; 4529 4530 (void) memset((char *)&ctlbuf, 0, sizeof (ctlbuf)); 4531 (void) memset((char *)&datbuf, 0, sizeof (datbuf)); 4532 4533 ctlbuf.buf = (char *)&tpi; 4534 ctlbuf.maxlen = sizeof (tpi); 4535 4536 if (ioctl(fd, I_NREAD, &bytes_avail) < 0) { 4537 syslog(LOG_ERR, "I_NREAD returned error %m"); 4538 return (-1); 4539 } 4540 if (bytes_avail > netibufsize - offset) { 4541 count = netip - netibuf; 4542 netibuf = (char *)realloc(netibuf, 4543 (unsigned)netibufsize + bytes_avail); 4544 if (netibuf == NULL) { 4545 fatal(net, "netibuf realloc failed\n"); 4546 } 4547 netibufsize += bytes_avail; 4548 netip = netibuf + count; 4549 buf = netibuf; 4550 } 4551 datbuf.buf = buf + offset; 4552 datbuf.maxlen = netibufsize; 4553 ret = getmsg(fd, &ctlbuf, &datbuf, &flags); 4554 if (ret < 0) { 4555 syslog(LOG_ERR, "getmsg returned -1, errno %d\n", 4556 errno); 4557 return (-1); 4558 } 4559 if (ctlbuf.len <= 0) { 4560 return (datbuf.len); 4561 } 4562 4563 if (tpi.type == T_DATA_REQ) { 4564 return (0); 4565 } 4566 4567 if ((tpi.type == T_ORDREL_IND) || (tpi.type == T_DISCON_IND)) 4568 cleanup(0); 4569 fatal(fd, "no data or protocol element recognized"); 4570 return (0); 4571 } 4572 4573 static void 4574 drainstream(int size) 4575 { 4576 int nbytes; 4577 int tsize; 4578 4579 tsize = netip - netibuf; 4580 4581 if ((tsize + ncc + size) > netibufsize) { 4582 if (!(netibuf = (char *)realloc(netibuf, 4583 (unsigned)tsize + ncc + size))) 4584 fatalperror(net, "netibuf realloc failed\n", errno); 4585 netibufsize = tsize + ncc + size; 4586 4587 netip = netibuf + tsize; 4588 } 4589 4590 if ((nbytes = read(net, (char *)netip + ncc, size)) != size) 4591 syslog(LOG_ERR, "read %d bytes\n", nbytes); 4592 } 4593 4594 /* 4595 * TPI style replacement for socket send() primitive, so we don't require 4596 * sockmod to be on the stream. 4597 */ 4598 static int 4599 send_oob(int fd, char *ptr, int count) 4600 { 4601 struct T_exdata_req exd_req; 4602 struct strbuf hdr, dat; 4603 int ret; 4604 4605 exd_req.PRIM_type = T_EXDATA_REQ; 4606 exd_req.MORE_flag = 0; 4607 4608 hdr.buf = (char *)&exd_req; 4609 hdr.len = sizeof (exd_req); 4610 4611 dat.buf = ptr; 4612 dat.len = count; 4613 4614 ret = putmsg(fd, &hdr, &dat, 0); 4615 if (ret == 0) { 4616 ret = count; 4617 } 4618 return (ret); 4619 } 4620 4621 4622 /* 4623 * local_setenv -- 4624 * Set the value of the environmental variable "name" to be 4625 * "value". If rewrite is set, replace any current value. 4626 */ 4627 static int 4628 local_setenv(const char *name, const char *value, int rewrite) 4629 { 4630 static int alloced; /* if allocated space before */ 4631 char *c; 4632 int l_value, offset; 4633 4634 /* 4635 * Do not allow environment variables which begin with LD_ to be 4636 * inserted into the environment. While normally the dynamic linker 4637 * protects the login program, that is based on the assumption hostile 4638 * invocation of login are from non-root users. However, since telnetd 4639 * runs as root, this cannot be utilized. So instead we simply 4640 * prevent LD_* from being inserted into the environment. 4641 * This also applies to other environment variables that 4642 * are to be ignored in setugid apps. 4643 * Note that at this point name can contain '='! 4644 * Also, do not allow TTYPROMPT to be passed along here. 4645 */ 4646 if (strncmp(name, "LD_", 3) == 0 || 4647 strncmp(name, "NLSPATH", 7) == 0 || 4648 (strncmp(name, "TTYPROMPT", 9) == 0 && 4649 (name[9] == '\0' || name[9] == '='))) { 4650 return (-1); 4651 } 4652 if (*value == '=') /* no `=' in value */ 4653 ++value; 4654 l_value = strlen(value); 4655 if ((c = __findenv(name, &offset))) { /* find if already exists */ 4656 if (!rewrite) 4657 return (0); 4658 if ((int)strlen(c) >= l_value) { /* old larger; copy over */ 4659 while (*c++ = *value++); 4660 return (0); 4661 } 4662 } else { /* create new slot */ 4663 int cnt; 4664 char **p; 4665 4666 for (p = environ, cnt = 0; *p; ++p, ++cnt); 4667 if (alloced) { /* just increase size */ 4668 environ = (char **)realloc((char *)environ, 4669 (size_t)(sizeof (char *) * (cnt + 2))); 4670 if (!environ) 4671 return (-1); 4672 } else { /* get new space */ 4673 alloced = 1; /* copy old entries into it */ 4674 p = (char **)malloc((size_t)(sizeof (char *)* 4675 (cnt + 2))); 4676 if (!p) 4677 return (-1); 4678 (void) memcpy(p, environ, cnt * sizeof (char *)); 4679 environ = p; 4680 } 4681 environ[cnt + 1] = NULL; 4682 offset = cnt; 4683 } 4684 for (c = (char *)name; *c && *c != '='; ++c); /* no `=' in name */ 4685 if (!(environ[offset] = /* name + `=' + value */ 4686 malloc((size_t)((int)(c - name) + l_value + 2)))) 4687 return (-1); 4688 for (c = environ[offset]; ((*c = *name++) != 0) && (*c != '='); ++c); 4689 for (*c++ = '='; *c++ = *value++; ); 4690 return (0); 4691 } 4692 4693 /* 4694 * local_unsetenv(name) -- 4695 * Delete environmental variable "name". 4696 */ 4697 static void 4698 local_unsetenv(const char *name) 4699 { 4700 char **p; 4701 int offset; 4702 4703 while (__findenv(name, &offset)) /* if set multiple times */ 4704 for (p = &environ[offset]; ; ++p) 4705 if ((*p = *(p + 1)) == 0) 4706 break; 4707 } 4708 4709 /* 4710 * __findenv -- 4711 * Returns pointer to value associated with name, if any, else NULL. 4712 * Sets offset to be the offset of the name/value combination in the 4713 * environmental array, for use by local_setenv() and local_unsetenv(). 4714 * Explicitly removes '=' in argument name. 4715 */ 4716 static char * 4717 __findenv(const char *name, int *offset) 4718 { 4719 extern char **environ; 4720 int len; 4721 const char *np; 4722 char **p, *c; 4723 4724 if (name == NULL || environ == NULL) 4725 return (NULL); 4726 for (np = name; *np && *np != '='; ++np) 4727 continue; 4728 len = np - name; 4729 for (p = environ; (c = *p) != NULL; ++p) 4730 if (strncmp(c, name, len) == 0 && c[len] == '=') { 4731 *offset = p - environ; 4732 return (c + len + 1); 4733 } 4734 return (NULL); 4735 } 4736 4737 static void 4738 showbanner(void) 4739 { 4740 char *cp; 4741 char evalbuf[BUFSIZ]; 4742 4743 if (defopen(defaultfile) == 0) { 4744 int flags; 4745 4746 /* ignore case */ 4747 flags = defcntl(DC_GETFLAGS, 0); 4748 TURNOFF(flags, DC_CASE); 4749 (void) defcntl(DC_SETFLAGS, flags); 4750 if (cp = defread(bannervar)) { 4751 FILE *fp; 4752 4753 if (strlen(cp) + strlen("eval echo '") + strlen("'\n") 4754 + 1 < sizeof (evalbuf)) { 4755 (void) strlcpy(evalbuf, "eval echo '", 4756 sizeof (evalbuf)); 4757 (void) strlcat(evalbuf, cp, sizeof (evalbuf)); 4758 (void) strlcat(evalbuf, "'\n", 4759 sizeof (evalbuf)); 4760 4761 if (fp = popen(evalbuf, "r")) { 4762 char buf[BUFSIZ]; 4763 size_t size; 4764 4765 /* 4766 * Pipe I/O atomicity guarantees we 4767 * need only one read. 4768 */ 4769 if ((size = fread(buf, 1, 4770 sizeof (buf) - 1, 4771 fp)) != 0) { 4772 char *p; 4773 buf[size] = '\0'; 4774 p = strrchr(buf, '\n'); 4775 if (p != NULL) 4776 *p = '\0'; 4777 if (strlen(buf)) { 4778 map_banner(buf); 4779 netflush(); 4780 } 4781 } 4782 (void) pclose(fp); 4783 /* close default file */ 4784 (void) defopen(NULL); 4785 return; 4786 } 4787 } 4788 } 4789 (void) defopen(NULL); /* close default file */ 4790 } 4791 4792 defbanner(); 4793 netflush(); 4794 } 4795 4796 static void 4797 map_banner(char *p) 4798 { 4799 char *q; 4800 4801 /* 4802 * Map the banner: "\n" -> "\r\n" and "\r" -> "\r\0" 4803 */ 4804 for (q = nfrontp; p && *p && q < nfrontp + sizeof (netobuf) - 1; ) 4805 if (*p == '\n') { 4806 *q++ = '\r'; 4807 *q++ = '\n'; 4808 p++; 4809 } else if (*p == '\r') { 4810 *q++ = '\r'; 4811 *q++ = '\0'; 4812 p++; 4813 } else 4814 *q++ = *p++; 4815 4816 nfrontp += q - netobuf; 4817 } 4818 4819 /* 4820 * Show banner that getty never gave. By default, this is `uname -sr`. 4821 * 4822 * The banner includes some null's (for TELNET CR disambiguation), 4823 * so we have to be somewhat complicated. 4824 */ 4825 static void 4826 defbanner(void) 4827 { 4828 struct utsname u; 4829 4830 /* 4831 * Dont show this if the '-h' option was present 4832 */ 4833 if (!show_hostinfo) 4834 return; 4835 4836 if (uname(&u) == -1) 4837 return; 4838 4839 write_data_len((const char *) BANNER1, sizeof (BANNER1) - 1); 4840 write_data_len(u.sysname, strlen(u.sysname)); 4841 write_data_len(" ", 1); 4842 write_data_len(u.release, strlen(u.release)); 4843 write_data_len((const char *)BANNER2, sizeof (BANNER2) - 1); 4844 } 4845 4846 /* 4847 * Verify that the named module is at the top of the stream 4848 * and then pop it off. 4849 */ 4850 static int 4851 removemod(int f, char *modname) 4852 { 4853 char topmodname[BUFSIZ]; 4854 4855 if (ioctl(f, I_LOOK, topmodname) < 0) 4856 return (-1); 4857 if (strcmp(modname, topmodname) != 0) { 4858 errno = ENXIO; 4859 return (-1); 4860 } 4861 if (ioctl(f, I_POP, 0) < 0) 4862 return (-1); 4863 return (0); 4864 } 4865 4866 static void 4867 write_data(const char *format, ...) 4868 { 4869 va_list args; 4870 int len; 4871 char argp[BUFSIZ]; 4872 4873 va_start(args, format); 4874 4875 if ((len = vsnprintf(argp, sizeof (argp), format, args)) == -1) 4876 return; 4877 4878 write_data_len(argp, len); 4879 va_end(args); 4880 } 4881 4882 static void 4883 write_data_len(const char *buf, int len) 4884 { 4885 int remaining, copied; 4886 4887 remaining = BUFSIZ - (nfrontp - netobuf); 4888 while (len > 0) { 4889 /* 4890 * If there's not enough space in netobuf then 4891 * try to make some. 4892 */ 4893 if ((len > BUFSIZ ? BUFSIZ : len) > remaining) { 4894 netflush(); 4895 remaining = BUFSIZ - (nfrontp - netobuf); 4896 } 4897 /* Copy as much as we can */ 4898 copied = remaining > len ? len : remaining; 4899 (void) memmove(nfrontp, buf, copied); 4900 nfrontp += copied; 4901 len -= copied; 4902 remaining -= copied; 4903 buf += copied; 4904 } 4905 } 4906