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 2006 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")), 3198 0); 3199 3200 } else /* default, no auth. info available, login does it all */ { 3201 (void) execl(LOGIN_PROGRAM, "login", 3202 "-p", "-h", host, "-d", slavename, 3203 getenv("USER"), 0); 3204 } 3205 3206 fatalperror(netfd, LOGIN_PROGRAM, errno); 3207 /*NOTREACHED*/ 3208 } 3209 3210 static void 3211 fatal(int f, char *msg) 3212 { 3213 char buf[BUFSIZ]; 3214 3215 (void) snprintf(buf, sizeof (buf), "telnetd: %s.\r\n", msg); 3216 (void) write(f, buf, strlen(buf)); 3217 exit(EXIT_FAILURE); 3218 /*NOTREACHED*/ 3219 } 3220 3221 static void 3222 fatalperror(int f, char *msg, int errnum) 3223 { 3224 char buf[BUFSIZ]; 3225 3226 (void) snprintf(buf, sizeof (buf), 3227 "%s: %s\r\n", msg, strerror(errnum)); 3228 fatal(f, buf); 3229 /*NOTREACHED*/ 3230 } 3231 3232 /* 3233 * Main loop. Select from pty and network, and 3234 * hand data to telnet receiver finite state machine 3235 * when it receives telnet protocol. Regular data 3236 * flow between pty and network takes place through 3237 * inkernel telnet streams module (telmod). 3238 */ 3239 static void 3240 telnet(int net, int master) 3241 { 3242 int on = 1; 3243 char mode; 3244 struct strioctl telnetmod; 3245 int nsize = 0; 3246 char binary_in = 0; 3247 char binary_out = 0; 3248 3249 if (ioctl(net, FIONBIO, &on) == -1) 3250 syslog(LOG_INFO, "ioctl FIONBIO net: %m\n"); 3251 if (ioctl(master, FIONBIO, &on) == -1) 3252 syslog(LOG_INFO, "ioctl FIONBIO pty p: %m\n"); 3253 (void) signal(SIGTSTP, SIG_IGN); 3254 (void) signal(SIGCHLD, (void (*)())cleanup); 3255 (void) setpgrp(); 3256 3257 /* 3258 * Call telrcv() once to pick up anything received during 3259 * terminal type negotiation. 3260 */ 3261 telrcv(); 3262 3263 netflush(); 3264 ptyflush(); 3265 3266 for (;;) { 3267 fd_set ibits, obits, xbits; 3268 int c; 3269 3270 if (ncc < 0) 3271 break; 3272 3273 FD_ZERO(&ibits); 3274 FD_ZERO(&obits); 3275 FD_ZERO(&xbits); 3276 3277 /* 3278 * If we couldn't flush all our output to the network, 3279 * keep checking for when we can. 3280 */ 3281 if (nfrontp - nbackp) 3282 FD_SET(net, &obits); 3283 /* 3284 * Never look for input if there's still 3285 * stuff in the corresponding output buffer 3286 */ 3287 if (pfrontp - pbackp) { 3288 FD_SET(master, &obits); 3289 } else { 3290 FD_SET(net, &ibits); 3291 } 3292 if (!SYNCHing) { 3293 FD_SET(net, &xbits); 3294 } 3295 3296 #define max(x, y) (((x) < (y)) ? (y) : (x)) 3297 3298 /* 3299 * make an ioctl to telnet module (net side) to send 3300 * binary mode of telnet daemon. binary_in and 3301 * binary_out are 0 if not in binary mode. 3302 */ 3303 if (binary_in != myopts[TELOPT_BINARY] || 3304 binary_out != remopts[TELOPT_BINARY]) { 3305 3306 mode = 0; 3307 if (myopts[TELOPT_BINARY] != OPT_NO) 3308 mode |= TEL_BINARY_IN; 3309 3310 if (remopts[TELOPT_BINARY] != OPT_NO) 3311 mode |= TEL_BINARY_OUT; 3312 3313 telnetmod.ic_cmd = TEL_IOC_MODE; 3314 telnetmod.ic_timout = -1; 3315 telnetmod.ic_len = 1; 3316 telnetmod.ic_dp = &mode; 3317 3318 syslog(LOG_DEBUG, "TEL_IOC_MODE binary has changed\n"); 3319 3320 if (ioctl(net, I_STR, &telnetmod) < 0) 3321 fatal(net, "ioctl TEL_IOC_MODE failed\n"); 3322 binary_in = myopts[TELOPT_BINARY]; 3323 binary_out = remopts[TELOPT_BINARY]; 3324 } 3325 if (state == TS_DATA) { 3326 if ((nfrontp == nbackp) && 3327 (pfrontp == pbackp)) { 3328 if (ioctl(net, I_NREAD, &nsize) < 0) 3329 fatalperror(net, 3330 "ioctl I_NREAD failed\n", errno); 3331 if (nsize) 3332 drainstream(nsize); 3333 3334 /* 3335 * make an ioctl to reinsert remaining data at 3336 * streamhead. After this, ioctl reenables the 3337 * telnet lower put queue. This queue was 3338 * noenabled by telnet module after sending 3339 * protocol/urgent data to telnetd. 3340 */ 3341 3342 telnetmod.ic_cmd = TEL_IOC_ENABLE; 3343 telnetmod.ic_timout = -1; 3344 if (ncc || nsize) { 3345 telnetmod.ic_len = ncc + nsize; 3346 telnetmod.ic_dp = netip; 3347 } else { 3348 telnetmod.ic_len = 0; 3349 telnetmod.ic_dp = NULL; 3350 } 3351 if (ioctl(net, I_STR, &telnetmod) < 0) 3352 fatal(net, "ioctl TEL_IOC_ENABLE \ 3353 failed\n"); 3354 3355 telmod_init_done = B_TRUE; 3356 3357 netip = netibuf; 3358 (void) memset(netibuf, 0, netibufsize); 3359 3360 ncc = 0; 3361 } 3362 } else { 3363 /* 3364 * state not changed to TS_DATA and hence, more to read 3365 * send ioctl to get one more message block. 3366 */ 3367 telnetmod.ic_cmd = TEL_IOC_GETBLK; 3368 telnetmod.ic_timout = -1; 3369 telnetmod.ic_len = 0; 3370 telnetmod.ic_dp = NULL; 3371 3372 if (ioctl(net, I_STR, &telnetmod) < 0) 3373 fatal(net, "ioctl TEL_IOC_GETBLK failed\n"); 3374 } 3375 3376 if ((c = select(max(net, master) + 1, &ibits, &obits, &xbits, 3377 (struct timeval *)0)) < 1) { 3378 if (c == -1) { 3379 if (errno == EINTR) { 3380 continue; 3381 } 3382 } 3383 (void) sleep(5); 3384 continue; 3385 } 3386 3387 /* 3388 * Any urgent data? 3389 */ 3390 if (FD_ISSET(net, &xbits)) { 3391 SYNCHing = 1; 3392 } 3393 3394 /* 3395 * Something to read from the network... 3396 */ 3397 if (FD_ISSET(net, &ibits)) { 3398 ncc = read(net, netibuf, netibufsize); 3399 if (ncc < 0 && errno == EWOULDBLOCK) 3400 ncc = 0; 3401 else { 3402 if (ncc <= 0) { 3403 break; 3404 } 3405 netip = netibuf; 3406 } 3407 } 3408 3409 if (FD_ISSET(net, &obits) && (nfrontp - nbackp) > 0) 3410 netflush(); 3411 if (ncc > 0) 3412 telrcv(); 3413 if (FD_ISSET(master, &obits) && (pfrontp - pbackp) > 0) 3414 ptyflush(); 3415 } 3416 cleanup(0); 3417 } 3418 3419 static void 3420 telrcv(void) 3421 { 3422 int c; 3423 3424 while (ncc > 0) { 3425 if ((&ptyobuf[BUFSIZ] - pfrontp) < 2) 3426 return; 3427 c = *netip & 0377; 3428 /* 3429 * Once we hit data, we want to transition back to 3430 * in-kernel processing. However, this code is shared 3431 * by getterminaltype()/ttloop() which run before the 3432 * in-kernel plumbing is available. So if we are still 3433 * processing the initial option negotiation, even TS_DATA 3434 * must be processed here. 3435 */ 3436 if (c != IAC && state == TS_DATA && init_neg_done) { 3437 break; 3438 } 3439 netip++; 3440 ncc--; 3441 switch (state) { 3442 3443 case TS_CR: 3444 state = TS_DATA; 3445 /* Strip off \n or \0 after a \r */ 3446 if ((c == 0) || (c == '\n')) { 3447 break; 3448 } 3449 /* FALLTHRU */ 3450 3451 case TS_DATA: 3452 if (c == IAC) { 3453 state = TS_IAC; 3454 break; 3455 } 3456 if (inter > 0) 3457 break; 3458 /* 3459 * We map \r\n ==> \r, since 3460 * We now map \r\n ==> \r for pragmatic reasons. 3461 * Many client implementations send \r\n when 3462 * the user hits the CarriageReturn key. 3463 * 3464 * We USED to map \r\n ==> \n, since \r\n says 3465 * that we want to be in column 1 of the next 3466 * line. 3467 */ 3468 if (c == '\r' && (myopts[TELOPT_BINARY] == OPT_NO)) { 3469 state = TS_CR; 3470 } 3471 *pfrontp++ = c; 3472 break; 3473 3474 case TS_IAC: 3475 switch (c) { 3476 3477 /* 3478 * Send the process on the pty side an 3479 * interrupt. Do this with a NULL or 3480 * interrupt char; depending on the tty mode. 3481 */ 3482 case IP: 3483 interrupt(); 3484 break; 3485 3486 case BREAK: 3487 sendbrk(); 3488 break; 3489 3490 /* 3491 * Are You There? 3492 */ 3493 case AYT: 3494 write_data_len("\r\n[Yes]\r\n", 9); 3495 break; 3496 3497 /* 3498 * Abort Output 3499 */ 3500 case AO: { 3501 struct ltchars tmpltc; 3502 3503 ptyflush(); /* half-hearted */ 3504 if (ioctl(pty, TIOCGLTC, &tmpltc) == -1) 3505 syslog(LOG_INFO, 3506 "ioctl TIOCGLTC: %m\n"); 3507 if (tmpltc.t_flushc != '\377') { 3508 *pfrontp++ = tmpltc.t_flushc; 3509 } 3510 netclear(); /* clear buffer back */ 3511 write_data("%c%c", (uchar_t)IAC, 3512 (uchar_t)DM); 3513 3514 neturg = nfrontp-1; /* off by one XXX */ 3515 netflush(); 3516 netflush(); /* XXX.sparker */ 3517 break; 3518 } 3519 3520 /* 3521 * Erase Character and 3522 * Erase Line 3523 */ 3524 case EC: 3525 case EL: { 3526 struct sgttyb b; 3527 char ch; 3528 3529 ptyflush(); /* half-hearted */ 3530 if (ioctl(pty, TIOCGETP, &b) == -1) 3531 syslog(LOG_INFO, 3532 "ioctl TIOCGETP: %m\n"); 3533 ch = (c == EC) ? 3534 b.sg_erase : b.sg_kill; 3535 if (ch != '\377') { 3536 *pfrontp++ = ch; 3537 } 3538 break; 3539 } 3540 3541 /* 3542 * Check for urgent data... 3543 */ 3544 case DM: 3545 break; 3546 3547 /* 3548 * Begin option subnegotiation... 3549 */ 3550 case SB: 3551 state = TS_SB; 3552 SB_CLEAR(); 3553 continue; 3554 3555 case WILL: 3556 state = TS_WILL; 3557 continue; 3558 3559 case WONT: 3560 state = TS_WONT; 3561 continue; 3562 3563 case DO: 3564 state = TS_DO; 3565 continue; 3566 3567 case DONT: 3568 state = TS_DONT; 3569 continue; 3570 3571 case IAC: 3572 *pfrontp++ = c; 3573 break; 3574 } 3575 state = TS_DATA; 3576 break; 3577 case TS_SB: 3578 if (c == IAC) { 3579 state = TS_SE; 3580 } else { 3581 SB_ACCUM(c); 3582 } 3583 break; 3584 case TS_SE: 3585 if (c != SE) { 3586 if (c != IAC) { 3587 SB_ACCUM((uchar_t)IAC); 3588 } 3589 SB_ACCUM(c); 3590 state = TS_SB; 3591 3592 } else { 3593 SB_TERM(); 3594 suboption(); /* handle sub-option */ 3595 state = TS_DATA; 3596 } 3597 break; 3598 3599 case TS_WILL: 3600 if (remopts[c] != OPT_YES) 3601 willoption(c); 3602 state = TS_DATA; 3603 continue; 3604 3605 case TS_WONT: 3606 if (remopts[c] != OPT_NO) 3607 wontoption(c); 3608 state = TS_DATA; 3609 continue; 3610 3611 case TS_DO: 3612 if (myopts[c] != OPT_YES) 3613 dooption(c); 3614 state = TS_DATA; 3615 continue; 3616 3617 case TS_DONT: 3618 if (myopts[c] != OPT_NO) { 3619 dontoption(c); 3620 } 3621 state = TS_DATA; 3622 continue; 3623 3624 default: 3625 syslog(LOG_ERR, "telnetd: panic state=%d\n", state); 3626 (void) printf("telnetd: panic state=%d\n", state); 3627 exit(EXIT_FAILURE); 3628 } 3629 } 3630 } 3631 3632 static void 3633 willoption(int option) 3634 { 3635 uchar_t *fmt; 3636 boolean_t send_reply = B_TRUE; 3637 3638 switch (option) { 3639 case TELOPT_BINARY: 3640 mode(O_RAW, 0); 3641 fmt = doopt; 3642 break; 3643 3644 case TELOPT_ECHO: 3645 not42 = 0; /* looks like a 4.2 system */ 3646 /* 3647 * Now, in a 4.2 system, to break them out of ECHOing 3648 * (to the terminal) mode, we need to send a "WILL ECHO". 3649 * Kludge upon kludge! 3650 */ 3651 if (myopts[TELOPT_ECHO] == OPT_YES) { 3652 dooption(TELOPT_ECHO); 3653 } 3654 fmt = dont; 3655 break; 3656 case TELOPT_TTYPE: 3657 settimer(ttypeopt); 3658 goto common; 3659 3660 case TELOPT_NAWS: 3661 settimer(nawsopt); 3662 goto common; 3663 3664 case TELOPT_XDISPLOC: 3665 settimer(xdisplocopt); 3666 goto common; 3667 3668 case TELOPT_NEW_ENVIRON: 3669 settimer(environopt); 3670 goto common; 3671 3672 case TELOPT_AUTHENTICATION: 3673 settimer(authopt); 3674 if (remopts[option] == OPT_NO || 3675 negotiate_auth_krb5 == 0) 3676 fmt = dont; 3677 else 3678 fmt = doopt; 3679 break; 3680 3681 case TELOPT_OLD_ENVIRON: 3682 settimer(oenvironopt); 3683 goto common; 3684 common: 3685 if (remopts[option] == OPT_YES_BUT_ALWAYS_LOOK) { 3686 remopts[option] = OPT_YES; 3687 return; 3688 } 3689 /*FALLTHRU*/ 3690 case TELOPT_SGA: 3691 fmt = doopt; 3692 break; 3693 3694 case TELOPT_TM: 3695 fmt = dont; 3696 break; 3697 3698 case TELOPT_ENCRYPT: 3699 settimer(encropt); /* got response to do/dont */ 3700 if (enc_debug) 3701 (void) fprintf(stderr, 3702 "RCVD IAC WILL TELOPT_ENCRYPT\n"); 3703 if (krb5_privacy_allowed()) { 3704 fmt = doopt; 3705 if (sent_do_encrypt) 3706 send_reply = B_FALSE; 3707 else 3708 sent_do_encrypt = B_TRUE; 3709 } else { 3710 fmt = dont; 3711 } 3712 break; 3713 3714 default: 3715 fmt = dont; 3716 break; 3717 } 3718 if (fmt == doopt) { 3719 remopts[option] = OPT_YES; 3720 } else { 3721 remopts[option] = OPT_NO; 3722 } 3723 if (send_reply) { 3724 write_data((const char *)fmt, option); 3725 netflush(); 3726 } 3727 } 3728 3729 static void 3730 wontoption(int option) 3731 { 3732 uchar_t *fmt; 3733 int send_reply = 1; 3734 3735 switch (option) { 3736 case TELOPT_ECHO: 3737 not42 = 1; /* doesn't seem to be a 4.2 system */ 3738 break; 3739 3740 case TELOPT_BINARY: 3741 mode(0, O_RAW); 3742 break; 3743 3744 case TELOPT_TTYPE: 3745 settimer(ttypeopt); 3746 break; 3747 3748 case TELOPT_NAWS: 3749 settimer(nawsopt); 3750 break; 3751 3752 case TELOPT_XDISPLOC: 3753 settimer(xdisplocopt); 3754 break; 3755 3756 case TELOPT_NEW_ENVIRON: 3757 settimer(environopt); 3758 break; 3759 3760 case TELOPT_OLD_ENVIRON: 3761 settimer(oenvironopt); 3762 break; 3763 3764 case TELOPT_AUTHENTICATION: 3765 settimer(authopt); 3766 auth_finished(0, AUTH_REJECT); 3767 if (auth_debug) 3768 (void) fprintf(stderr, 3769 "RCVD WONT TELOPT_AUTHENTICATE\n"); 3770 3771 remopts[option] = OPT_NO; 3772 send_reply = 0; 3773 break; 3774 3775 case TELOPT_ENCRYPT: 3776 if (enc_debug) 3777 (void) fprintf(stderr, 3778 "RCVD IAC WONT TELOPT_ENCRYPT\n"); 3779 settimer(encropt); /* got response to will/wont */ 3780 /* 3781 * Remote side cannot send encryption. No reply necessary 3782 * Treat this as if "IAC SB ENCRYPT END IAC SE" were 3783 * received (RFC 2946) and disable crypto. 3784 */ 3785 encrypt_end(TELNET_DIR_DECRYPT); 3786 send_reply = 0; 3787 break; 3788 } 3789 3790 fmt = dont; 3791 remopts[option] = OPT_NO; 3792 if (send_reply) { 3793 write_data((const char *)fmt, option); 3794 } 3795 } 3796 3797 /* 3798 * We received an "IAC DO ..." message from the client, change our state 3799 * to OPT_YES. 3800 */ 3801 static void 3802 dooption(int option) 3803 { 3804 uchar_t *fmt; 3805 boolean_t send_reply = B_TRUE; 3806 3807 switch (option) { 3808 3809 case TELOPT_TM: 3810 fmt = wont; 3811 break; 3812 3813 case TELOPT_ECHO: 3814 mode(O_ECHO|O_CRMOD, 0); 3815 fmt = will; 3816 break; 3817 3818 case TELOPT_BINARY: 3819 mode(O_RAW, 0); 3820 fmt = will; 3821 break; 3822 3823 case TELOPT_SGA: 3824 fmt = will; 3825 break; 3826 3827 case TELOPT_LOGOUT: 3828 /* 3829 * Options don't get much easier. Acknowledge the option, 3830 * and then clean up and exit. 3831 */ 3832 write_data((const char *)will, option); 3833 netflush(); 3834 cleanup(0); 3835 /*NOTREACHED*/ 3836 3837 case TELOPT_ENCRYPT: 3838 if (enc_debug) 3839 (void) fprintf(stderr, "RCVD DO TELOPT_ENCRYPT\n"); 3840 settimer(encropt); 3841 /* 3842 * We received a "DO". This indicates that the other side 3843 * wants us to encrypt our data (pending negotiatoin). 3844 * reply with "IAC WILL ENCRYPT" if we are able to send 3845 * encrypted data. 3846 */ 3847 if (krb5_privacy_allowed() && negotiate_encrypt) { 3848 fmt = will; 3849 if (sent_will_encrypt) 3850 send_reply = B_FALSE; 3851 else 3852 sent_will_encrypt = B_TRUE; 3853 /* return if we already sent "WILL ENCRYPT" */ 3854 if (myopts[option] == OPT_YES) 3855 return; 3856 } else { 3857 fmt = wont; 3858 } 3859 break; 3860 3861 case TELOPT_AUTHENTICATION: 3862 if (auth_debug) { 3863 (void) fprintf(stderr, 3864 "RCVD DO TELOPT_AUTHENTICATION\n"); 3865 } 3866 /* 3867 * RFC 2941 - only the server can send 3868 * "DO TELOPT_AUTHENTICATION". 3869 * if a server receives this, it must respond with WONT... 3870 */ 3871 fmt = wont; 3872 break; 3873 3874 default: 3875 fmt = wont; 3876 break; 3877 } 3878 if (fmt == will) { 3879 myopts[option] = OPT_YES; 3880 } else { 3881 myopts[option] = OPT_NO; 3882 } 3883 if (send_reply) { 3884 write_data((const char *)fmt, option); 3885 netflush(); 3886 } 3887 } 3888 3889 /* 3890 * We received an "IAC DONT ..." message from client. 3891 * Client does not agree with the option so act accordingly. 3892 */ 3893 static void 3894 dontoption(int option) 3895 { 3896 int send_reply = 1; 3897 switch (option) { 3898 case TELOPT_ECHO: 3899 /* 3900 * we should stop echoing, since the client side will be doing 3901 * it, but keep mapping CR since CR-LF will be mapped to it. 3902 */ 3903 mode(0, O_ECHO); 3904 break; 3905 3906 case TELOPT_ENCRYPT: 3907 if (enc_debug) 3908 (void) fprintf(stderr, "RCVD IAC DONT ENCRYPT\n"); 3909 settimer(encropt); 3910 /* 3911 * Remote side cannot receive any encrypted data, 3912 * so dont send any. No reply necessary. 3913 */ 3914 send_reply = 0; 3915 break; 3916 3917 default: 3918 break; 3919 } 3920 3921 myopts[option] = OPT_NO; 3922 3923 if (send_reply) { 3924 write_data((const char *)wont, option); 3925 } 3926 } 3927 3928 /* 3929 * suboption() 3930 * 3931 * Look at the sub-option buffer, and try to be helpful to the other 3932 * side. 3933 * 3934 */ 3935 static void 3936 suboption(void) 3937 { 3938 int subchar; 3939 3940 switch (subchar = SB_GET()) { 3941 case TELOPT_TTYPE: { /* Yaaaay! */ 3942 static char terminalname[5+41] = "TERM="; 3943 3944 settimer(ttypesubopt); 3945 3946 if (SB_GET() != TELQUAL_IS) { 3947 return; /* ??? XXX but, this is the most robust */ 3948 } 3949 3950 terminaltype = terminalname+strlen(terminalname); 3951 3952 while (terminaltype < (terminalname + sizeof (terminalname) - 3953 1) && !SB_EOF()) { 3954 int c; 3955 3956 c = SB_GET(); 3957 if (isupper(c)) { 3958 c = tolower(c); 3959 } 3960 *terminaltype++ = c; /* accumulate name */ 3961 } 3962 *terminaltype = 0; 3963 terminaltype = terminalname; 3964 break; 3965 } 3966 3967 case TELOPT_NAWS: { 3968 struct winsize ws; 3969 3970 if (SB_EOF()) { 3971 return; 3972 } 3973 ws.ws_col = SB_GET() << 8; 3974 if (SB_EOF()) { 3975 return; 3976 } 3977 ws.ws_col |= SB_GET(); 3978 if (SB_EOF()) { 3979 return; 3980 } 3981 ws.ws_row = SB_GET() << 8; 3982 if (SB_EOF()) { 3983 return; 3984 } 3985 ws.ws_row |= SB_GET(); 3986 ws.ws_xpixel = 0; ws.ws_ypixel = 0; 3987 (void) ioctl(pty, TIOCSWINSZ, &ws); 3988 settimer(nawsopt); 3989 break; 3990 } 3991 3992 case TELOPT_XDISPLOC: { 3993 if (SB_EOF() || SB_GET() != TELQUAL_IS) { 3994 return; 3995 } 3996 settimer(xdisplocsubopt); 3997 subpointer[SB_LEN()] = '\0'; 3998 if ((new_env("DISPLAY", subpointer)) == 1) 3999 perror("malloc"); 4000 break; 4001 } 4002 4003 case TELOPT_NEW_ENVIRON: 4004 case TELOPT_OLD_ENVIRON: { 4005 int c; 4006 char *cp, *varp, *valp; 4007 4008 if (SB_EOF()) 4009 return; 4010 c = SB_GET(); 4011 if (c == TELQUAL_IS) { 4012 if (subchar == TELOPT_OLD_ENVIRON) 4013 settimer(oenvironsubopt); 4014 else 4015 settimer(environsubopt); 4016 } else if (c != TELQUAL_INFO) { 4017 return; 4018 } 4019 4020 if (subchar == TELOPT_NEW_ENVIRON) { 4021 while (!SB_EOF()) { 4022 c = SB_GET(); 4023 if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR)) 4024 break; 4025 } 4026 } else 4027 { 4028 while (!SB_EOF()) { 4029 c = SB_GET(); 4030 if ((c == env_ovar) || (c == ENV_USERVAR)) 4031 break; 4032 } 4033 } 4034 4035 if (SB_EOF()) 4036 return; 4037 4038 cp = varp = (char *)subpointer; 4039 valp = 0; 4040 4041 while (!SB_EOF()) { 4042 c = SB_GET(); 4043 if (subchar == TELOPT_OLD_ENVIRON) { 4044 if (c == env_ovar) 4045 c = NEW_ENV_VAR; 4046 else if (c == env_ovalue) 4047 c = NEW_ENV_VALUE; 4048 } 4049 switch (c) { 4050 4051 case NEW_ENV_VALUE: 4052 *cp = '\0'; 4053 cp = valp = (char *)subpointer; 4054 break; 4055 4056 case NEW_ENV_VAR: 4057 case ENV_USERVAR: 4058 *cp = '\0'; 4059 if (valp) { 4060 if ((new_env(varp, valp)) == 1) { 4061 perror("malloc"); 4062 } 4063 } else { 4064 (void) del_env(varp); 4065 } 4066 cp = varp = (char *)subpointer; 4067 valp = 0; 4068 break; 4069 4070 case ENV_ESC: 4071 if (SB_EOF()) 4072 break; 4073 c = SB_GET(); 4074 /* FALL THROUGH */ 4075 default: 4076 *cp++ = c; 4077 break; 4078 } 4079 } 4080 *cp = '\0'; 4081 if (valp) { 4082 if ((new_env(varp, valp)) == 1) { 4083 perror("malloc"); 4084 } 4085 } else { 4086 (void) del_env(varp); 4087 } 4088 break; 4089 } /* end of case TELOPT_NEW_ENVIRON */ 4090 4091 case TELOPT_AUTHENTICATION: 4092 if (SB_EOF()) 4093 break; 4094 switch (SB_GET()) { 4095 case TELQUAL_SEND: 4096 case TELQUAL_REPLY: 4097 /* 4098 * These are sent server only and cannot be sent by the 4099 * client. 4100 */ 4101 break; 4102 case TELQUAL_IS: 4103 if (auth_debug) 4104 (void) fprintf(stderr, 4105 "RCVD AUTHENTICATION IS " 4106 "(%d bytes)\n", 4107 SB_LEN()); 4108 if (!auth_negotiated) 4109 auth_is((uchar_t *)subpointer, SB_LEN()); 4110 break; 4111 case TELQUAL_NAME: 4112 if (auth_debug) 4113 (void) fprintf(stderr, 4114 "RCVD AUTHENTICATION NAME " 4115 "(%d bytes)\n", 4116 SB_LEN()); 4117 if (!auth_negotiated) 4118 auth_name((uchar_t *)subpointer, SB_LEN()); 4119 break; 4120 } 4121 break; 4122 4123 case TELOPT_ENCRYPT: { 4124 int c; 4125 if (SB_EOF()) 4126 break; 4127 c = SB_GET(); 4128 #ifdef ENCRYPT_NAMES 4129 if (enc_debug) 4130 (void) fprintf(stderr, "RCVD ENCRYPT %s\n", 4131 ENCRYPT_NAME(c)); 4132 #endif /* ENCRYPT_NAMES */ 4133 switch (c) { 4134 case ENCRYPT_SUPPORT: 4135 encrypt_support(subpointer, SB_LEN()); 4136 break; 4137 case ENCRYPT_IS: 4138 encrypt_is((uchar_t *)subpointer, SB_LEN()); 4139 break; 4140 case ENCRYPT_REPLY: 4141 (void) encrypt_reply(subpointer, SB_LEN()); 4142 break; 4143 case ENCRYPT_START: 4144 encrypt_start(); 4145 break; 4146 case ENCRYPT_END: 4147 encrypt_end(TELNET_DIR_DECRYPT); 4148 break; 4149 case ENCRYPT_REQSTART: 4150 encrypt_request_start(); 4151 break; 4152 case ENCRYPT_REQEND: 4153 /* 4154 * We can always send an REQEND so that we cannot 4155 * get stuck encrypting. We should only get this 4156 * if we have been able to get in the correct mode 4157 * anyhow. 4158 */ 4159 encrypt_request_end(); 4160 break; 4161 case ENCRYPT_ENC_KEYID: 4162 encrypt_enc_keyid(subpointer, SB_LEN()); 4163 break; 4164 case ENCRYPT_DEC_KEYID: 4165 encrypt_dec_keyid(subpointer, SB_LEN()); 4166 break; 4167 default: 4168 break; 4169 } 4170 } 4171 break; 4172 4173 default: 4174 break; 4175 } 4176 } 4177 4178 static void 4179 mode(int on, int off) 4180 { 4181 struct termios tios; 4182 4183 ptyflush(); 4184 if (tcgetattr(pty, &tios) < 0) 4185 syslog(LOG_INFO, "tcgetattr: %m\n"); 4186 4187 if (on & O_RAW) { 4188 tios.c_cflag |= CS8; 4189 tios.c_iflag &= ~IUCLC; 4190 tios.c_lflag &= ~(XCASE|IEXTEN); 4191 } 4192 if (off & O_RAW) { 4193 if ((tios.c_cflag & PARENB) != 0) 4194 tios.c_cflag &= ~CS8; 4195 tios.c_lflag |= IEXTEN; 4196 } 4197 4198 if (on & O_ECHO) 4199 tios.c_lflag |= ECHO; 4200 if (off & O_ECHO) 4201 tios.c_lflag &= ~ECHO; 4202 4203 if (on & O_CRMOD) { 4204 tios.c_iflag |= ICRNL; 4205 tios.c_oflag |= ONLCR; 4206 } 4207 /* 4208 * Because "O_CRMOD" will never be set in "off" we don't have to 4209 * handle this case here. 4210 */ 4211 4212 if (tcsetattr(pty, TCSANOW, &tios) < 0) 4213 syslog(LOG_INFO, "tcsetattr: %m\n"); 4214 } 4215 4216 /* 4217 * Send interrupt to process on other side of pty. 4218 * If it is in raw mode, just write NULL; 4219 * otherwise, write intr char. 4220 */ 4221 static void 4222 interrupt(void) 4223 { 4224 struct sgttyb b; 4225 struct tchars tchars; 4226 4227 ptyflush(); /* half-hearted */ 4228 if (ioctl(pty, TIOCGETP, &b) == -1) 4229 syslog(LOG_INFO, "ioctl TIOCGETP: %m\n"); 4230 if (b.sg_flags & O_RAW) { 4231 *pfrontp++ = '\0'; 4232 return; 4233 } 4234 *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ? 4235 '\177' : tchars.t_intrc; 4236 } 4237 4238 /* 4239 * Send quit to process on other side of pty. 4240 * If it is in raw mode, just write NULL; 4241 * otherwise, write quit char. 4242 */ 4243 static void 4244 sendbrk(void) 4245 { 4246 struct sgttyb b; 4247 struct tchars tchars; 4248 4249 ptyflush(); /* half-hearted */ 4250 (void) ioctl(pty, TIOCGETP, &b); 4251 if (b.sg_flags & O_RAW) { 4252 *pfrontp++ = '\0'; 4253 return; 4254 } 4255 *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ? 4256 '\034' : tchars.t_quitc; 4257 } 4258 4259 static void 4260 ptyflush(void) 4261 { 4262 int n; 4263 4264 if ((n = pfrontp - pbackp) > 0) 4265 n = write(master, pbackp, n); 4266 if (n < 0) 4267 return; 4268 pbackp += n; 4269 if (pbackp == pfrontp) 4270 pbackp = pfrontp = ptyobuf; 4271 } 4272 4273 /* 4274 * nextitem() 4275 * 4276 * Return the address of the next "item" in the TELNET data 4277 * stream. This will be the address of the next character if 4278 * the current address is a user data character, or it will 4279 * be the address of the character following the TELNET command 4280 * if the current address is a TELNET IAC ("I Am a Command") 4281 * character. 4282 */ 4283 4284 static char * 4285 nextitem(char *current) 4286 { 4287 if ((*current&0xff) != IAC) { 4288 return (current+1); 4289 } 4290 switch (*(current+1)&0xff) { 4291 case DO: 4292 case DONT: 4293 case WILL: 4294 case WONT: 4295 return (current+3); 4296 case SB: /* loop forever looking for the SE */ 4297 { 4298 char *look = current+2; 4299 4300 for (;;) { 4301 if ((*look++&0xff) == IAC) { 4302 if ((*look++&0xff) == SE) { 4303 return (look); 4304 } 4305 } 4306 } 4307 } 4308 default: 4309 return (current+2); 4310 } 4311 } 4312 4313 4314 /* 4315 * netclear() 4316 * 4317 * We are about to do a TELNET SYNCH operation. Clear 4318 * the path to the network. 4319 * 4320 * Things are a bit tricky since we may have sent the first 4321 * byte or so of a previous TELNET command into the network. 4322 * So, we have to scan the network buffer from the beginning 4323 * until we are up to where we want to be. 4324 * 4325 * A side effect of what we do, just to keep things 4326 * simple, is to clear the urgent data pointer. The principal 4327 * caller should be setting the urgent data pointer AFTER calling 4328 * us in any case. 4329 */ 4330 static void 4331 netclear(void) 4332 { 4333 char *thisitem, *next; 4334 char *good; 4335 #define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \ 4336 ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL)) 4337 4338 thisitem = netobuf; 4339 4340 while ((next = nextitem(thisitem)) <= nbackp) { 4341 thisitem = next; 4342 } 4343 4344 /* Now, thisitem is first before/at boundary. */ 4345 4346 good = netobuf; /* where the good bytes go */ 4347 4348 while (nfrontp > thisitem) { 4349 if (wewant(thisitem)) { 4350 int length; 4351 4352 next = thisitem; 4353 do { 4354 next = nextitem(next); 4355 } while (wewant(next) && (nfrontp > next)); 4356 length = next-thisitem; 4357 (void) memmove(good, thisitem, length); 4358 good += length; 4359 thisitem = next; 4360 } else { 4361 thisitem = nextitem(thisitem); 4362 } 4363 } 4364 4365 nbackp = netobuf; 4366 nfrontp = good; /* next byte to be sent */ 4367 neturg = 0; 4368 } 4369 4370 4371 /* 4372 * netflush 4373 * Send as much data as possible to the network, 4374 * handling requests for urgent data. 4375 */ 4376 static void 4377 netflush(void) 4378 { 4379 int n; 4380 4381 if ((n = nfrontp - nbackp) > 0) { 4382 /* 4383 * if no urgent data, or if the other side appears to be an 4384 * old 4.2 client (and thus unable to survive TCP urgent data), 4385 * write the entire buffer in non-OOB mode. 4386 */ 4387 if ((neturg == 0) || (not42 == 0)) { 4388 n = write(net, nbackp, n); /* normal write */ 4389 } else { 4390 n = neturg - nbackp; 4391 /* 4392 * In 4.2 (and 4.3) systems, there is some question 4393 * about what byte in a sendOOB operation is the "OOB" 4394 * data. To make ourselves compatible, we only send ONE 4395 * byte out of band, the one WE THINK should be OOB 4396 * (though we really have more the TCP philosophy of 4397 * urgent data rather than the Unix philosophy of OOB 4398 * data). 4399 */ 4400 if (n > 1) { 4401 /* send URGENT all by itself */ 4402 n = write(net, nbackp, n-1); 4403 } else { 4404 /* URGENT data */ 4405 n = send_oob(net, nbackp, n); 4406 } 4407 } 4408 } 4409 if (n < 0) { 4410 if (errno == EWOULDBLOCK) 4411 return; 4412 /* should blow this guy away... */ 4413 return; 4414 } 4415 4416 nbackp += n; 4417 4418 if (nbackp >= neturg) { 4419 neturg = 0; 4420 } 4421 if (nbackp == nfrontp) { 4422 nbackp = nfrontp = netobuf; 4423 } 4424 } 4425 4426 /* ARGSUSED */ 4427 static void 4428 cleanup(int signum) 4429 { 4430 /* 4431 * If the TEL_IOC_ENABLE ioctl hasn't completed, then we need to 4432 * handle closing differently. We close "net" first and then 4433 * "master" in that order. We do close(net) first because 4434 * we have no other way to disconnect forwarding between the network 4435 * and master. So by issuing the close()'s we ensure that no further 4436 * data rises from TCP. A more complex fix would be adding proper 4437 * support for throwing a "stop" switch for forwarding data between 4438 * logindmux peers. It's possible to block in the close of the tty 4439 * while the network still receives data and the telmod module is 4440 * TEL_STOPPED. A denial-of-service attack generates this case, 4441 * see 4102102. 4442 */ 4443 4444 if (!telmod_init_done) { 4445 (void) close(net); 4446 (void) close(master); 4447 } 4448 rmut(); 4449 4450 exit(EXIT_FAILURE); 4451 } 4452 4453 static void 4454 rmut(void) 4455 { 4456 pam_handle_t *pamh; 4457 struct utmpx *up; 4458 char user[sizeof (up->ut_user) + 1]; 4459 char ttyn[sizeof (up->ut_line) + 1]; 4460 char rhost[sizeof (up->ut_host) + 1]; 4461 4462 /* while cleaning up don't allow disruption */ 4463 (void) signal(SIGCHLD, SIG_IGN); 4464 4465 setutxent(); 4466 while (up = getutxent()) { 4467 if (up->ut_pid == pid) { 4468 if (up->ut_type == DEAD_PROCESS) { 4469 /* 4470 * Cleaned up elsewhere. 4471 */ 4472 break; 4473 } 4474 4475 /* 4476 * call pam_close_session if login changed 4477 * the utmpx user entry from type LOGIN_PROCESS 4478 * to type USER_PROCESS, which happens 4479 * after pam_open_session is called. 4480 */ 4481 if (up->ut_type == USER_PROCESS) { 4482 (void) strlcpy(user, up->ut_user, 4483 sizeof (user)); 4484 (void) strlcpy(ttyn, up->ut_line, 4485 sizeof (ttyn)); 4486 (void) strlcpy(rhost, up->ut_host, 4487 sizeof (rhost)); 4488 if ((pam_start("telnet", user, NULL, &pamh)) == 4489 PAM_SUCCESS) { 4490 (void) pam_set_item(pamh, PAM_TTY, 4491 ttyn); 4492 (void) pam_set_item(pamh, PAM_RHOST, 4493 rhost); 4494 (void) pam_close_session(pamh, 0); 4495 (void) pam_end(pamh, PAM_SUCCESS); 4496 } 4497 } 4498 4499 up->ut_type = DEAD_PROCESS; 4500 up->ut_exit.e_termination = WTERMSIG(0); 4501 up->ut_exit.e_exit = WEXITSTATUS(0); 4502 (void) time(&up->ut_tv.tv_sec); 4503 4504 if (modutx(up) == NULL) { 4505 /* 4506 * Since modutx failed we'll 4507 * write out the new entry 4508 * ourselves. 4509 */ 4510 (void) pututxline(up); 4511 updwtmpx("wtmpx", up); 4512 } 4513 break; 4514 } 4515 } 4516 4517 endutxent(); 4518 4519 (void) signal(SIGCHLD, (void (*)())cleanup); 4520 } 4521 4522 static int 4523 readstream(int fd, char *buf, int offset) 4524 { 4525 struct strbuf ctlbuf, datbuf; 4526 union T_primitives tpi; 4527 int ret = 0; 4528 int flags = 0; 4529 int bytes_avail, count; 4530 4531 (void) memset((char *)&ctlbuf, 0, sizeof (ctlbuf)); 4532 (void) memset((char *)&datbuf, 0, sizeof (datbuf)); 4533 4534 ctlbuf.buf = (char *)&tpi; 4535 ctlbuf.maxlen = sizeof (tpi); 4536 4537 if (ioctl(fd, I_NREAD, &bytes_avail) < 0) { 4538 syslog(LOG_ERR, "I_NREAD returned error %m"); 4539 return (-1); 4540 } 4541 if (bytes_avail > netibufsize - offset) { 4542 count = netip - netibuf; 4543 netibuf = (char *)realloc(netibuf, 4544 (unsigned)netibufsize + bytes_avail); 4545 if (netibuf == NULL) { 4546 fatal(net, "netibuf realloc failed\n"); 4547 } 4548 netibufsize += bytes_avail; 4549 netip = netibuf + count; 4550 buf = netibuf; 4551 } 4552 datbuf.buf = buf + offset; 4553 datbuf.maxlen = netibufsize; 4554 ret = getmsg(fd, &ctlbuf, &datbuf, &flags); 4555 if (ret < 0) { 4556 syslog(LOG_ERR, "getmsg returned -1, errno %d\n", 4557 errno); 4558 return (-1); 4559 } 4560 if (ctlbuf.len <= 0) { 4561 return (datbuf.len); 4562 } 4563 4564 if (tpi.type == T_DATA_REQ) { 4565 return (0); 4566 } 4567 4568 if ((tpi.type == T_ORDREL_IND) || (tpi.type == T_DISCON_IND)) 4569 cleanup(0); 4570 fatal(fd, "no data or protocol element recognized"); 4571 return (0); 4572 } 4573 4574 static void 4575 drainstream(int size) 4576 { 4577 int nbytes; 4578 int tsize; 4579 4580 tsize = netip - netibuf; 4581 4582 if ((tsize + ncc + size) > netibufsize) { 4583 if (!(netibuf = (char *)realloc(netibuf, 4584 (unsigned)tsize + ncc + size))) 4585 fatalperror(net, "netibuf realloc failed\n", errno); 4586 netibufsize = tsize + ncc + size; 4587 4588 netip = netibuf + tsize; 4589 } 4590 4591 if ((nbytes = read(net, (char *)netip + ncc, size)) != size) 4592 syslog(LOG_ERR, "read %d bytes\n", nbytes); 4593 } 4594 4595 /* 4596 * TPI style replacement for socket send() primitive, so we don't require 4597 * sockmod to be on the stream. 4598 */ 4599 static int 4600 send_oob(int fd, char *ptr, int count) 4601 { 4602 struct T_exdata_req exd_req; 4603 struct strbuf hdr, dat; 4604 int ret; 4605 4606 exd_req.PRIM_type = T_EXDATA_REQ; 4607 exd_req.MORE_flag = 0; 4608 4609 hdr.buf = (char *)&exd_req; 4610 hdr.len = sizeof (exd_req); 4611 4612 dat.buf = ptr; 4613 dat.len = count; 4614 4615 ret = putmsg(fd, &hdr, &dat, 0); 4616 if (ret == 0) { 4617 ret = count; 4618 } 4619 return (ret); 4620 } 4621 4622 4623 /* 4624 * local_setenv -- 4625 * Set the value of the environmental variable "name" to be 4626 * "value". If rewrite is set, replace any current value. 4627 */ 4628 static int 4629 local_setenv(const char *name, const char *value, int rewrite) 4630 { 4631 static int alloced; /* if allocated space before */ 4632 char *c; 4633 int l_value, offset; 4634 4635 /* 4636 * Do not allow environment variables which begin with LD_ to be 4637 * inserted into the environment. While normally the dynamic linker 4638 * protects the login program, that is based on the assumption hostile 4639 * invocation of login are from non-root users. However, since telnetd 4640 * runs as root, this cannot be utilized. So instead we simply 4641 * prevent LD_* from being inserted into the environment. 4642 * This also applies to other environment variables that 4643 * are to be ignored in setugid apps. 4644 * Note that at this point name can contain '='! 4645 * Also, do not allow TTYPROMPT to be passed along here. 4646 */ 4647 if (strncmp(name, "LD_", 3) == 0 || 4648 strncmp(name, "NLSPATH", 7) == 0 || 4649 (strncmp(name, "TTYPROMPT", 9) == 0 && 4650 (name[9] == '\0' || name[9] == '='))) { 4651 return (-1); 4652 } 4653 if (*value == '=') /* no `=' in value */ 4654 ++value; 4655 l_value = strlen(value); 4656 if ((c = __findenv(name, &offset))) { /* find if already exists */ 4657 if (!rewrite) 4658 return (0); 4659 if ((int)strlen(c) >= l_value) { /* old larger; copy over */ 4660 while (*c++ = *value++); 4661 return (0); 4662 } 4663 } else { /* create new slot */ 4664 int cnt; 4665 char **p; 4666 4667 for (p = environ, cnt = 0; *p; ++p, ++cnt); 4668 if (alloced) { /* just increase size */ 4669 environ = (char **)realloc((char *)environ, 4670 (size_t)(sizeof (char *) * (cnt + 2))); 4671 if (!environ) 4672 return (-1); 4673 } else { /* get new space */ 4674 alloced = 1; /* copy old entries into it */ 4675 p = (char **)malloc((size_t)(sizeof (char *)* 4676 (cnt + 2))); 4677 if (!p) 4678 return (-1); 4679 (void) memcpy(p, environ, cnt * sizeof (char *)); 4680 environ = p; 4681 } 4682 environ[cnt + 1] = NULL; 4683 offset = cnt; 4684 } 4685 for (c = (char *)name; *c && *c != '='; ++c); /* no `=' in name */ 4686 if (!(environ[offset] = /* name + `=' + value */ 4687 malloc((size_t)((int)(c - name) + l_value + 2)))) 4688 return (-1); 4689 for (c = environ[offset]; ((*c = *name++) != 0) && (*c != '='); ++c); 4690 for (*c++ = '='; *c++ = *value++; ); 4691 return (0); 4692 } 4693 4694 /* 4695 * local_unsetenv(name) -- 4696 * Delete environmental variable "name". 4697 */ 4698 static void 4699 local_unsetenv(const char *name) 4700 { 4701 char **p; 4702 int offset; 4703 4704 while (__findenv(name, &offset)) /* if set multiple times */ 4705 for (p = &environ[offset]; ; ++p) 4706 if ((*p = *(p + 1)) == 0) 4707 break; 4708 } 4709 4710 /* 4711 * __findenv -- 4712 * Returns pointer to value associated with name, if any, else NULL. 4713 * Sets offset to be the offset of the name/value combination in the 4714 * environmental array, for use by local_setenv() and local_unsetenv(). 4715 * Explicitly removes '=' in argument name. 4716 */ 4717 static char * 4718 __findenv(const char *name, int *offset) 4719 { 4720 extern char **environ; 4721 int len; 4722 const char *np; 4723 char **p, *c; 4724 4725 if (name == NULL || environ == NULL) 4726 return (NULL); 4727 for (np = name; *np && *np != '='; ++np) 4728 continue; 4729 len = np - name; 4730 for (p = environ; (c = *p) != NULL; ++p) 4731 if (strncmp(c, name, len) == 0 && c[len] == '=') { 4732 *offset = p - environ; 4733 return (c + len + 1); 4734 } 4735 return (NULL); 4736 } 4737 4738 static void 4739 showbanner(void) 4740 { 4741 char *cp; 4742 char evalbuf[BUFSIZ]; 4743 4744 if (defopen(defaultfile) == 0) { 4745 int flags; 4746 4747 /* ignore case */ 4748 flags = defcntl(DC_GETFLAGS, 0); 4749 TURNOFF(flags, DC_CASE); 4750 (void) defcntl(DC_SETFLAGS, flags); 4751 if (cp = defread(bannervar)) { 4752 FILE *fp; 4753 4754 if (strlen(cp) + strlen("eval echo '") + strlen("'\n") 4755 + 1 < sizeof (evalbuf)) { 4756 (void) strlcpy(evalbuf, "eval echo '", 4757 sizeof (evalbuf)); 4758 (void) strlcat(evalbuf, cp, sizeof (evalbuf)); 4759 (void) strlcat(evalbuf, "'\n", 4760 sizeof (evalbuf)); 4761 4762 if (fp = popen(evalbuf, "r")) { 4763 char buf[BUFSIZ]; 4764 size_t size; 4765 4766 /* 4767 * Pipe I/O atomicity guarantees we 4768 * need only one read. 4769 */ 4770 if ((size = fread(buf, 1, 4771 sizeof (buf) - 1, 4772 fp)) != 0) { 4773 char *p; 4774 buf[size] = '\0'; 4775 p = strrchr(buf, '\n'); 4776 if (p != NULL) 4777 *p = '\0'; 4778 if (strlen(buf)) { 4779 map_banner(buf); 4780 netflush(); 4781 } 4782 } 4783 (void) pclose(fp); 4784 /* close default file */ 4785 (void) defopen(NULL); 4786 return; 4787 } 4788 } 4789 } 4790 (void) defopen(NULL); /* close default file */ 4791 } 4792 4793 defbanner(); 4794 netflush(); 4795 } 4796 4797 static void 4798 map_banner(char *p) 4799 { 4800 char *q; 4801 4802 /* 4803 * Map the banner: "\n" -> "\r\n" and "\r" -> "\r\0" 4804 */ 4805 for (q = nfrontp; p && *p && q < nfrontp + sizeof (netobuf) - 1; ) 4806 if (*p == '\n') { 4807 *q++ = '\r'; 4808 *q++ = '\n'; 4809 p++; 4810 } else if (*p == '\r') { 4811 *q++ = '\r'; 4812 *q++ = '\0'; 4813 p++; 4814 } else 4815 *q++ = *p++; 4816 4817 nfrontp += q - netobuf; 4818 } 4819 4820 /* 4821 * Show banner that getty never gave. By default, this is `uname -sr`. 4822 * 4823 * The banner includes some null's (for TELNET CR disambiguation), 4824 * so we have to be somewhat complicated. 4825 */ 4826 static void 4827 defbanner(void) 4828 { 4829 struct utsname u; 4830 4831 /* 4832 * Dont show this if the '-h' option was present 4833 */ 4834 if (!show_hostinfo) 4835 return; 4836 4837 if (uname(&u) == -1) 4838 return; 4839 4840 write_data_len((const char *) BANNER1, sizeof (BANNER1) - 1); 4841 write_data_len(u.sysname, strlen(u.sysname)); 4842 write_data_len(" ", 1); 4843 write_data_len(u.release, strlen(u.release)); 4844 write_data_len((const char *)BANNER2, sizeof (BANNER2) - 1); 4845 } 4846 4847 /* 4848 * Verify that the named module is at the top of the stream 4849 * and then pop it off. 4850 */ 4851 static int 4852 removemod(int f, char *modname) 4853 { 4854 char topmodname[BUFSIZ]; 4855 4856 if (ioctl(f, I_LOOK, topmodname) < 0) 4857 return (-1); 4858 if (strcmp(modname, topmodname) != 0) { 4859 errno = ENXIO; 4860 return (-1); 4861 } 4862 if (ioctl(f, I_POP, 0) < 0) 4863 return (-1); 4864 return (0); 4865 } 4866 4867 static void 4868 write_data(const char *format, ...) 4869 { 4870 va_list args; 4871 int len; 4872 char argp[BUFSIZ]; 4873 4874 va_start(args, format); 4875 4876 if ((len = vsnprintf(argp, sizeof (argp), format, args)) == -1) 4877 return; 4878 4879 write_data_len(argp, len); 4880 va_end(args); 4881 } 4882 4883 static void 4884 write_data_len(const char *buf, int len) 4885 { 4886 int remaining, copied; 4887 4888 remaining = BUFSIZ - (nfrontp - netobuf); 4889 while (len > 0) { 4890 /* 4891 * If there's not enough space in netobuf then 4892 * try to make some. 4893 */ 4894 if ((len > BUFSIZ ? BUFSIZ : len) > remaining) { 4895 netflush(); 4896 remaining = BUFSIZ - (nfrontp - netobuf); 4897 } 4898 /* Copy as much as we can */ 4899 copied = remaining > len ? len : remaining; 4900 (void) memmove(nfrontp, buf, copied); 4901 nfrontp += copied; 4902 len -= copied; 4903 remaining -= copied; 4904 buf += copied; 4905 } 4906 } 4907