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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 * 22 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T 28 * All Rights Reserved. 29 */ 30 31 /* 32 * University Copyright- Copyright (c) 1982, 1986, 1988 33 * The Regents of the University of California. 34 * All Rights Reserved. 35 * 36 * University Acknowledgment- Portions of this document are derived from 37 * software developed by the University of California, Berkeley, and its 38 * contributors. 39 */ 40 41 #pragma ident "%Z%%M% %I% %E% SMI" 42 43 /* 44 * Telnet server. 45 */ 46 #include <sys/types.h> 47 #include <sys/param.h> 48 #include <sys/socket.h> 49 #include <sys/wait.h> 50 #include <sys/file.h> 51 #include <sys/stat.h> 52 #include <sys/filio.h> 53 #include <sys/time.h> 54 #include <sys/stropts.h> 55 #include <sys/stream.h> 56 #include <sys/tihdr.h> 57 #include <sys/utsname.h> 58 #include <unistd.h> 59 60 #include <netinet/in.h> 61 62 #define AUTHWHO_STR 63 #define AUTHTYPE_NAMES 64 #define AUTHHOW_NAMES 65 #define AUTHRSP_NAMES 66 #define ENCRYPT_NAMES 67 68 #include <arpa/telnet.h> 69 #include <arpa/inet.h> 70 #include <stdio.h> 71 #include <stdarg.h> 72 #include <signal.h> 73 #include <errno.h> 74 #include <netdb.h> 75 #include <syslog.h> 76 #include <ctype.h> 77 #include <fcntl.h> 78 #include <sac.h> /* for SC_WILDC */ 79 #include <utmpx.h> 80 #include <sys/ttold.h> 81 #include <malloc.h> 82 #include <string.h> 83 #include <security/pam_appl.h> 84 #include <sys/tihdr.h> 85 #include <sys/logindmux.h> 86 #include <sys/telioctl.h> 87 #include <deflt.h> 88 #include <stdlib.h> 89 #include <string.h> 90 #include <stropts.h> 91 #include <termios.h> 92 93 #include <com_err.h> 94 #include <krb5.h> 95 #include <krb5_repository.h> 96 #include <des/des.h> 97 #include <rpc/des_crypt.h> 98 #include <sys/cryptmod.h> 99 #include <bsm/adt.h> 100 101 #define TELNETD_OPTS "Ss:a:dEXUhR:M:" 102 #ifdef DEBUG 103 #define DEBUG_OPTS "p:e" 104 #else 105 #define DEBUG_OPTS "" 106 #endif /* DEBUG */ 107 108 #define OPT_NO 0 /* won't do this option */ 109 #define OPT_YES 1 /* will do this option */ 110 #define OPT_YES_BUT_ALWAYS_LOOK 2 111 #define OPT_NO_BUT_ALWAYS_LOOK 3 112 113 #define MAXOPTLEN 256 114 #define MAXUSERNAMELEN 256 115 116 static char remopts[MAXOPTLEN]; 117 static char myopts[MAXOPTLEN]; 118 static uchar_t doopt[] = { (uchar_t)IAC, (uchar_t)DO, '%', 'c', 0 }; 119 static uchar_t dont[] = { (uchar_t)IAC, (uchar_t)DONT, '%', 'c', 0 }; 120 static uchar_t will[] = { (uchar_t)IAC, (uchar_t)WILL, '%', 'c', 0 }; 121 static uchar_t wont[] = { (uchar_t)IAC, (uchar_t)WONT, '%', 'c', 0 }; 122 /* 123 * I/O data buffers, pointers, and counters. 124 */ 125 static char ptyobuf[BUFSIZ], *pfrontp = ptyobuf, *pbackp = ptyobuf; 126 127 static char *netibuf, *netip; 128 static int netibufsize; 129 130 #define NIACCUM(c) { *netip++ = c; \ 131 ncc++; \ 132 } 133 134 static char netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf; 135 static char *neturg = 0; /* one past last bye of urgent data */ 136 /* the remote system seems to NOT be an old 4.2 */ 137 static int not42 = 1; 138 static char defaultfile[] = "/etc/default/telnetd"; 139 static char bannervar[] = "BANNER="; 140 141 static char BANNER1[] = "\r\n\r\n"; 142 static char BANNER2[] = "\r\n\r\0\r\n\r\0"; 143 144 /* 145 * buffer for sub-options - enlarged to 4096 to handle credentials 146 * from AUTH options 147 */ 148 static char subbuffer[4096], *subpointer = subbuffer, *subend = subbuffer; 149 #define SB_CLEAR() subpointer = subbuffer; 150 #define SB_TERM() { subend = subpointer; SB_CLEAR(); } 151 #define SB_ACCUM(c) if (subpointer < (subbuffer+sizeof (subbuffer))) { \ 152 *subpointer++ = (c); \ 153 } 154 #define SB_GET() ((*subpointer++)&0xff) 155 #define SB_EOF() (subpointer >= subend) 156 #define SB_LEN() (subend - subpointer) 157 158 #define MAXCCACHENAMELEN 36 159 #define MAXERRSTRLEN 1024 160 #define MAXPRINCLEN 256 161 162 static boolean_t auth_debug = 0; 163 static boolean_t negotiate_auth_krb5 = 1; 164 static boolean_t auth_negotiated = 0; 165 static int auth_status = 0; 166 static int auth_level = 0; 167 static char *AuthenticatingUser = NULL; 168 static char *krb5_name = NULL; 169 170 static krb5_address rsaddr = { 0, 0, 0, NULL }; 171 static krb5_address rsport = { 0, 0, 0, NULL }; 172 173 static krb5_context telnet_context = 0; 174 static krb5_auth_context auth_context = 0; 175 176 /* telnetd gets session key from here */ 177 static krb5_ticket *ticket = NULL; 178 static krb5_keyblock *session_key = NULL; 179 static char *telnet_srvtab = NULL; 180 181 typedef struct { 182 uchar_t AuthName; 183 uchar_t AuthHow; 184 char *AuthString; 185 } AuthInfo; 186 187 static AuthInfo auth_list[] = { 188 {AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT | AUTH_HOW_MUTUAL | 189 AUTH_ENCRYPT_ON, "KRB5 MUTUAL CRYPTO"}, 190 {AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT | AUTH_HOW_MUTUAL, 191 "KRB5 MUTUAL" }, 192 {AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT | AUTH_HOW_ONE_WAY, 193 "KRB5 1-WAY" }, 194 {0, 0, "NONE"} 195 }; 196 197 static AuthInfo NoAuth = {0, 0, NULL}; 198 199 static AuthInfo *authenticated = NULL; 200 201 #define PREAMBLE_SIZE 5 /* for auth_reply_str allocation */ 202 #define POSTAMBLE_SIZE 5 203 #define STR_DATA_LEN(len) ((len) * 2 + PREAMBLE_SIZE + POSTAMBLE_SIZE) 204 205 static void auth_name(uchar_t *, int); 206 static void auth_is(uchar_t *, int); 207 208 #define NO_ENCRYPTION 0x00 209 #define SEND_ENCRYPTED 0x01 210 #define RECV_ENCRYPTED 0x02 211 #define ENCRYPT_BOTH_WAYS (SEND_ENCRYPTED | RECV_ENCRYPTED) 212 213 static telnet_enc_data_t encr_data; 214 static boolean_t negotiate_encrypt = B_TRUE; 215 static boolean_t sent_encrypt_support = B_FALSE; 216 static boolean_t sent_will_encrypt = B_FALSE; 217 static boolean_t sent_do_encrypt = B_FALSE; 218 static boolean_t enc_debug = 0; 219 220 static void encrypt_session_key(Session_Key *key, cipher_info_t *cinfo); 221 static int encrypt_send_encrypt_is(); 222 223 extern void mit_des_fixup_key_parity(Block); 224 extern int krb5_setenv(const char *, const char *, int); 225 /* need to know what FD to use to talk to the crypto module */ 226 static int cryptmod_fd = -1; 227 228 #define LOGIN_PROGRAM "/bin/login" 229 230 /* 231 * State for recv fsm 232 */ 233 #define TS_DATA 0 /* base state */ 234 #define TS_IAC 1 /* look for double IAC's */ 235 #define TS_CR 2 /* CR-LF ->'s CR */ 236 #define TS_SB 3 /* throw away begin's... */ 237 #define TS_SE 4 /* ...end's (suboption negotiation) */ 238 #define TS_WILL 5 /* will option negotiation */ 239 #define TS_WONT 6 /* wont " */ 240 #define TS_DO 7 /* do " */ 241 #define TS_DONT 8 /* dont " */ 242 243 static int ncc; 244 static int master; /* master side of pty */ 245 static int pty; /* side of pty that gets ioctls */ 246 static int net; 247 static int inter; 248 extern char **environ; 249 static char *line; 250 static int SYNCHing = 0; /* we are in TELNET SYNCH mode */ 251 static int state = TS_DATA; 252 253 static int env_ovar = -1; /* XXX.sparker */ 254 static int env_ovalue = -1; /* XXX.sparker */ 255 static char pam_svc_name[64]; 256 static boolean_t telmod_init_done = B_FALSE; 257 258 static void doit(int, struct sockaddr_storage *); 259 static void willoption(int); 260 static void wontoption(int); 261 static void dooption(int); 262 static void dontoption(int); 263 static void fatal(int, char *); 264 static void fatalperror(int, char *, int); 265 static void mode(int, int); 266 static void interrupt(void); 267 static void drainstream(int); 268 static int readstream(int, char *, int); 269 static int send_oob(int fd, char *ptr, int count); 270 static int local_setenv(const char *name, const char *value, int rewrite); 271 static void local_unsetenv(const char *name); 272 static void suboption(void); 273 static int removemod(int f, char *modname); 274 static void willoption(int option); 275 static void wontoption(int option); 276 static void dooption(int option); 277 static void dontoption(int option); 278 static void write_data(const char *, ...); 279 static void write_data_len(const char *, int); 280 static void rmut(void); 281 static void cleanup(int); 282 static void telnet(int, int); 283 static void telrcv(void); 284 static void sendbrk(void); 285 static void ptyflush(void); 286 static void netclear(void); 287 static void netflush(void); 288 static void showbanner(void); 289 static void map_banner(char *); 290 static void defbanner(void); 291 static void ttloop(void); 292 293 /* 294 * The env_list linked list is used to store the environment variables 295 * until the final exec of login. A malevolent client might try to 296 * send an environment variable intended to affect the telnet daemon's 297 * execution. Right now the BANNER expansion is the only instance. 298 * Note that it is okay to pass the environment variables to login 299 * because login protects itself against environment variables mischief. 300 */ 301 302 struct envlist { 303 struct envlist *next; 304 char *name; 305 char *value; 306 int delete; 307 }; 308 309 static struct envlist *envlist_head = NULL; 310 311 /* 312 * The following are some clocks used to decide how to interpret 313 * the relationship between various variables. 314 */ 315 316 static struct { 317 int 318 system, /* what the current time is */ 319 echotoggle, /* last time user entered echo character */ 320 modenegotiated, /* last time operating mode negotiated */ 321 didnetreceive, /* last time we read data from network */ 322 ttypeopt, /* ttype will/won't received */ 323 ttypesubopt, /* ttype subopt is received */ 324 getterminal, /* time started to get terminal information */ 325 xdisplocopt, /* xdisploc will/wont received */ 326 xdisplocsubopt, /* xdisploc suboption received */ 327 nawsopt, /* window size will/wont received */ 328 nawssubopt, /* window size received */ 329 environopt, /* environment option will/wont received */ 330 oenvironopt, /* "old" environ option will/wont received */ 331 environsubopt, /* environment option suboption received */ 332 oenvironsubopt, /* "old environ option suboption received */ 333 gotDM; /* when did we last see a data mark */ 334 335 int getauth; 336 int authopt; /* Authentication option negotiated */ 337 int authdone; 338 339 int getencr; 340 int encropt; 341 int encr_support; 342 } clocks; 343 344 static int init_neg_done = 0; 345 static boolean_t resolve_hostname = 0; 346 static boolean_t show_hostinfo = 1; 347 348 #define settimer(x) (clocks.x = ++clocks.system) 349 #define sequenceIs(x, y) (clocks.x < clocks.y) 350 351 static void send_will(int); 352 static void send_wont(int); 353 static void send_do(int); 354 static char *__findenv(const char *name, int *offset); 355 356 /* ARGSUSED */ 357 static void 358 auth_finished(AuthInfo *ap, int result) 359 { 360 if ((authenticated = ap) == NULL) { 361 authenticated = &NoAuth; 362 if (myopts[TELOPT_ENCRYPT] == OPT_YES) 363 send_wont(TELOPT_ENCRYPT); 364 myopts[TELOPT_ENCRYPT] = remopts[TELOPT_ENCRYPT] = OPT_NO; 365 encr_data.encrypt.autoflag = 0; 366 } else if (result != AUTH_REJECT && 367 myopts[TELOPT_ENCRYPT] == OPT_YES && 368 remopts[TELOPT_ENCRYPT] == OPT_YES) { 369 370 /* 371 * Authentication successful, so we have a session key, and 372 * we're willing to do ENCRYPT, so send our ENCRYPT SUPPORT. 373 * 374 * Can't have sent ENCRYPT SUPPORT yet! And if we're sending it 375 * now it's really only because we did the DO ENCRYPT/WILL 376 * ENCRYPT dance before authentication, which is ok, but not too 377 * bright since we have to do the DONT ENCRYPT/WONT ENCRYPT 378 * dance if authentication fails, though clients typically just 379 * don't care. 380 */ 381 write_data("%c%c%c%c%c%c%c", 382 (uchar_t)IAC, 383 (uchar_t)SB, 384 (uchar_t)TELOPT_ENCRYPT, 385 (uchar_t)ENCRYPT_SUPPORT, 386 (uchar_t)TELOPT_ENCTYPE_DES_CFB64, 387 (uchar_t)IAC, 388 (uchar_t)SE); 389 390 netflush(); 391 392 sent_encrypt_support = B_TRUE; 393 394 if (enc_debug) 395 (void) fprintf(stderr, 396 "SENT ENCRYPT SUPPORT\n"); 397 398 (void) encrypt_send_encrypt_is(); 399 } 400 401 auth_status = result; 402 403 settimer(authdone); 404 } 405 406 static void 407 reply_to_client(AuthInfo *ap, int type, void *data, int len) 408 { 409 uchar_t reply[BUFSIZ]; 410 uchar_t *p = reply; 411 uchar_t *cd = (uchar_t *)data; 412 413 if (len == -1 && data != NULL) 414 len = strlen((char *)data); 415 else if (len > (sizeof (reply) - 9)) { 416 syslog(LOG_ERR, 417 "krb5 auth reply length too large (%d)", len); 418 if (auth_debug) 419 (void) fprintf(stderr, 420 "krb5 auth reply length too large (%d)\n", 421 len); 422 return; 423 } else if (data == NULL) 424 len = 0; 425 426 *p++ = IAC; 427 *p++ = SB; 428 *p++ = TELOPT_AUTHENTICATION; 429 *p++ = AUTHTYPE_KERBEROS_V5; 430 *p++ = ap->AuthName; 431 *p++ = ap->AuthHow; /* MUTUAL, ONE-WAY, etc */ 432 *p++ = type; /* RESPONSE or ACCEPT */ 433 while (len-- > 0) { 434 if ((*p++ = *cd++) == IAC) 435 *p++ = IAC; 436 } 437 *p++ = IAC; 438 *p++ = SE; 439 440 /* queue the data to be sent */ 441 write_data_len((const char *)reply, p-reply); 442 443 #if defined(AUTHTYPE_NAMES) && defined(AUTHWHO_STR) &&\ 444 defined(AUTHHOW_NAMES) && defined(AUTHRSP_NAMES) 445 if (auth_debug) { 446 (void) fprintf(stderr, "SENT TELOPT_AUTHENTICATION REPLY " 447 "%s %s|%s %s\n", 448 AUTHTYPE_NAME(ap->AuthName), 449 AUTHWHO_NAME(ap->AuthHow & AUTH_WHO_MASK), 450 AUTHHOW_NAME(ap->AuthHow & AUTH_HOW_MASK), 451 AUTHRSP_NAME(type)); 452 } 453 #endif /* AUTHTYPE_NAMES && AUTHWHO_NAMES && AUTHHOW_NAMES && AUTHRSP_NAMES */ 454 455 netflush(); 456 } 457 458 /* Decode, decrypt and store the forwarded creds in the local ccache. */ 459 static krb5_error_code 460 rd_and_store_forwarded_creds(krb5_context context, 461 krb5_auth_context auth_context, 462 krb5_data *inbuf, krb5_ticket *ticket, 463 char *username) 464 { 465 krb5_creds **creds; 466 krb5_error_code retval; 467 char ccname[MAXCCACHENAMELEN]; 468 krb5_ccache ccache = NULL; 469 470 if (retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL)) 471 return (retval); 472 473 (void) sprintf(ccname, "FILE:/tmp/krb5cc_p%ld", getpid()); 474 (void) krb5_setenv("KRB5CCNAME", ccname, 1); 475 476 if ((retval = krb5_cc_default(context, &ccache))) 477 goto cleanup; 478 479 if ((retval = krb5_cc_initialize(context, ccache, 480 ticket->enc_part2->client)) != 0) 481 goto cleanup; 482 483 if ((retval = krb5_cc_store_cred(context, ccache, *creds)) != 0) 484 goto cleanup; 485 486 if ((retval = krb5_cc_close(context, ccache)) != 0) 487 goto cleanup; 488 489 if (username != NULL) { 490 /* 491 * This verifies that the user is valid on the local system, 492 * maps the username from KerberosV5 to unix, 493 * and moves the KRB5CCNAME file to the correct place 494 * /tmp/krb5cc_[uid] with correct ownership (0600 uid gid). 495 * 496 * NOTE: the user must be in the gsscred table in order to map 497 * from KRB5 to Unix. 498 */ 499 (void) krb5_kuserok(context, ticket->enc_part2->client, 500 username); 501 } 502 if (auth_debug) 503 (void) fprintf(stderr, 504 "Successfully stored forwarded creds\n"); 505 506 cleanup: 507 krb5_free_creds(context, *creds); 508 return (retval); 509 } 510 511 static void 512 kerberos5_is(AuthInfo *ap, uchar_t *data, int cnt) 513 { 514 krb5_error_code err = 0; 515 krb5_principal server; 516 krb5_keyblock *newkey = NULL; 517 krb5_keytab keytabid = 0; 518 krb5_data outbuf; 519 krb5_data inbuf; 520 krb5_authenticator *authenticator; 521 char errbuf[MAXERRSTRLEN]; 522 char *name; 523 krb5_data auth; 524 525 Session_Key skey; 526 527 if (cnt-- < 1) 528 return; 529 switch (*data++) { 530 case KRB_AUTH: 531 auth.data = (char *)data; 532 auth.length = cnt; 533 534 if (auth_context == NULL) { 535 err = krb5_auth_con_init(telnet_context, &auth_context); 536 if (err) 537 syslog(LOG_ERR, 538 "Error getting krb5 auth " 539 "context: %s", error_message(err)); 540 } 541 if (!err) { 542 krb5_rcache rcache; 543 544 err = krb5_auth_con_getrcache(telnet_context, 545 auth_context, 546 &rcache); 547 if (!err && !rcache) { 548 err = krb5_sname_to_principal(telnet_context, 549 0, 0, 550 KRB5_NT_SRV_HST, 551 &server); 552 if (!err) { 553 err = krb5_get_server_rcache( 554 telnet_context, 555 krb5_princ_component( 556 telnet_context, 557 server, 0), 558 &rcache); 559 560 krb5_free_principal(telnet_context, 561 server); 562 } 563 } 564 if (err) 565 syslog(LOG_ERR, 566 "Error allocating krb5 replay cache: %s", 567 error_message(err)); 568 else { 569 err = krb5_auth_con_setrcache(telnet_context, 570 auth_context, 571 rcache); 572 if (err) 573 syslog(LOG_ERR, 574 "Error creating krb5 " 575 "replay cache: %s", 576 error_message(err)); 577 } 578 } 579 if (!err && telnet_srvtab != NULL) 580 err = krb5_kt_resolve(telnet_context, 581 telnet_srvtab, &keytabid); 582 if (!err) 583 err = krb5_rd_req(telnet_context, &auth_context, &auth, 584 NULL, keytabid, NULL, &ticket); 585 if (err) { 586 (void) snprintf(errbuf, sizeof (errbuf), 587 "Error reading krb5 auth information:" 588 " %s", error_message(err)); 589 goto errout; 590 } 591 592 /* 593 * Verify that the correct principal was used 594 */ 595 if (krb5_princ_component(telnet_context, 596 ticket->server, 0)->length < MAXPRINCLEN) { 597 char princ[MAXPRINCLEN]; 598 (void) strncpy(princ, 599 krb5_princ_component(telnet_context, 600 ticket->server, 0)->data, 601 krb5_princ_component(telnet_context, 602 ticket->server, 0)->length); 603 princ[krb5_princ_component(telnet_context, 604 ticket->server, 0)->length] = '\0'; 605 if (strcmp("host", princ)) { 606 if (strlen(princ) < sizeof (errbuf) - 39) { 607 (void) snprintf(errbuf, sizeof (errbuf), 608 "incorrect service " 609 "name: \"%s\" != " 610 "\"host\"", 611 princ); 612 } else { 613 (void) strncpy(errbuf, 614 "incorrect service " 615 "name: principal != " 616 "\"host\"", 617 sizeof (errbuf)); 618 } 619 goto errout; 620 } 621 } else { 622 (void) strlcpy(errbuf, "service name too long", 623 sizeof (errbuf)); 624 goto errout; 625 } 626 627 err = krb5_auth_con_getauthenticator(telnet_context, 628 auth_context, 629 &authenticator); 630 if (err) { 631 (void) snprintf(errbuf, sizeof (errbuf), 632 "Failed to get authenticator: %s", 633 error_message(err)); 634 goto errout; 635 } 636 if ((ap->AuthHow & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON && 637 !authenticator->checksum) { 638 (void) strlcpy(errbuf, 639 "authenticator is missing checksum", 640 sizeof (errbuf)); 641 goto errout; 642 } 643 if (authenticator->checksum) { 644 char type_check[2]; 645 krb5_checksum *cksum = authenticator->checksum; 646 krb5_keyblock *key; 647 krb5_data input; 648 krb5_boolean valid; 649 650 type_check[0] = ap->AuthName; 651 type_check[1] = ap->AuthHow; 652 653 err = krb5_auth_con_getkey(telnet_context, 654 auth_context, &key); 655 if (err) { 656 (void) snprintf(errbuf, sizeof (errbuf), 657 "Failed to get key from " 658 "authenticator: %s", 659 error_message(err)); 660 goto errout; 661 } 662 663 input.data = type_check; 664 input.length = 2; 665 err = krb5_c_verify_checksum(telnet_context, 666 key, 0, 667 &input, 668 cksum, 669 &valid); 670 if (!err && !valid) 671 err = KRB5KRB_AP_ERR_BAD_INTEGRITY; 672 673 if (err) { 674 (void) snprintf(errbuf, sizeof (errbuf), 675 "Kerberos checksum " 676 "verification failed: " 677 "%s", 678 error_message(err)); 679 goto errout; 680 } 681 krb5_free_keyblock(telnet_context, key); 682 } 683 684 krb5_free_authenticator(telnet_context, authenticator); 685 if ((ap->AuthHow & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 686 /* do ap_rep stuff here */ 687 if ((err = krb5_mk_rep(telnet_context, auth_context, 688 &outbuf))) { 689 (void) snprintf(errbuf, sizeof (errbuf), 690 "Failed to make " 691 "Kerberos auth reply: " 692 "%s", 693 error_message(err)); 694 goto errout; 695 } 696 reply_to_client(ap, KRB_RESPONSE, outbuf.data, 697 outbuf.length); 698 } 699 if (krb5_unparse_name(telnet_context, 700 ticket->enc_part2->client, 701 &name)) 702 name = 0; 703 reply_to_client(ap, KRB_ACCEPT, name, name ? -1 : 0); 704 if (auth_debug) { 705 syslog(LOG_NOTICE, 706 "\tKerberos5 identifies user as ``%s''\r\n", 707 name ? name : ""); 708 } 709 if (name != NULL) { 710 krb5_name = (char *)strdup(name); 711 } 712 auth_finished(ap, AUTH_USER); 713 714 if (name != NULL) 715 free(name); 716 krb5_auth_con_getremotesubkey(telnet_context, auth_context, 717 &newkey); 718 if (session_key != NULL) { 719 krb5_free_keyblock(telnet_context, session_key); 720 session_key = 0; 721 } 722 if (newkey != NULL) { 723 krb5_copy_keyblock(telnet_context, 724 newkey, &session_key); 725 krb5_free_keyblock(telnet_context, newkey); 726 } else { 727 krb5_copy_keyblock(telnet_context, 728 ticket->enc_part2->session, 729 &session_key); 730 } 731 732 /* 733 * Initialize encryption stuff. Currently, we are only 734 * supporting 8 byte keys and blocks. Check for this later. 735 */ 736 skey.type = SK_DES; 737 skey.length = DES_BLOCKSIZE; 738 skey.data = session_key->contents; 739 encrypt_session_key(&skey, &encr_data.encrypt); 740 encrypt_session_key(&skey, &encr_data.decrypt); 741 break; 742 case KRB_FORWARD: 743 inbuf.length = cnt; 744 inbuf.data = (char *)data; 745 if (auth_debug) 746 (void) fprintf(stderr, 747 "RCVD KRB_FORWARD data (%d bytes)\n", cnt); 748 749 if (auth_context != NULL) { 750 krb5_rcache rcache; 751 752 err = krb5_auth_con_getrcache(telnet_context, 753 auth_context, &rcache); 754 if (!err && !rcache) { 755 err = krb5_sname_to_principal(telnet_context, 756 0, 0, KRB5_NT_SRV_HST, &server); 757 if (!err) { 758 err = krb5_get_server_rcache( 759 telnet_context, 760 krb5_princ_component( 761 telnet_context, 762 server, 0), 763 &rcache); 764 krb5_free_principal(telnet_context, 765 server); 766 } 767 } 768 if (err) { 769 syslog(LOG_ERR, 770 "Error allocating krb5 replay cache: %s", 771 error_message(err)); 772 } else { 773 err = krb5_auth_con_setrcache(telnet_context, 774 auth_context, rcache); 775 if (err) 776 syslog(LOG_ERR, 777 "Error creating krb5 replay cache:" 778 " %s", 779 error_message(err)); 780 } 781 } 782 /* 783 * Use the 'rsaddr' and 'rsport' (remote service addr/port) 784 * from the original connection. This data is used to 785 * verify the forwarded credentials. 786 */ 787 if (!(err = krb5_auth_con_setaddrs(telnet_context, auth_context, 788 NULL, &rsaddr))) 789 err = krb5_auth_con_setports(telnet_context, 790 auth_context, NULL, &rsport); 791 792 if (err == 0) 793 /* 794 * If all is well, store the forwarded creds in 795 * the users local credential cache. 796 */ 797 err = rd_and_store_forwarded_creds(telnet_context, 798 auth_context, &inbuf, 799 ticket, 800 AuthenticatingUser); 801 if (err) { 802 (void) snprintf(errbuf, sizeof (errbuf), 803 "Read forwarded creds failed: %s", 804 error_message(err)); 805 syslog(LOG_ERR, "%s", errbuf); 806 807 reply_to_client(ap, KRB_FORWARD_REJECT, errbuf, -1); 808 if (auth_debug) 809 (void) fprintf(stderr, 810 "\tCould not read " 811 "forwarded credentials\r\n"); 812 } else 813 reply_to_client(ap, KRB_FORWARD_ACCEPT, (void *) 0, 0); 814 815 if (rsaddr.contents != NULL) 816 free(rsaddr.contents); 817 818 if (rsport.contents != NULL) 819 free(rsport.contents); 820 821 if (auth_debug) 822 (void) fprintf(stderr, "\tForwarded " 823 "credentials obtained\r\n"); 824 break; 825 default: 826 if (auth_debug) 827 (void) fprintf(stderr, 828 "\tUnknown Kerberos option %d\r\n", 829 data[-1]); 830 reply_to_client(ap, KRB_REJECT, (void *) 0, 0); 831 break; 832 } 833 return; 834 835 errout: 836 reply_to_client(ap, KRB_REJECT, errbuf, -1); 837 838 if (auth_debug) 839 (void) fprintf(stderr, "\tKerberos V5 error: %s\r\n", errbuf); 840 841 syslog(LOG_ERR, "%s", errbuf); 842 843 if (auth_context != NULL) { 844 krb5_auth_con_free(telnet_context, auth_context); 845 auth_context = 0; 846 } 847 } 848 849 static int 850 krb5_init() 851 { 852 int code = 0; 853 854 if (telnet_context == NULL) { 855 code = krb5_init_context(&telnet_context); 856 if (code != 0 && auth_debug) 857 syslog(LOG_NOTICE, 858 "Cannot initialize Kerberos V5: %s", 859 error_message(code)); 860 } 861 862 return (code); 863 } 864 865 static void 866 auth_name(uchar_t *data, int cnt) 867 { 868 char namebuf[MAXPRINCLEN]; 869 870 if (cnt < 1) { 871 if (auth_debug) 872 (void) fprintf(stderr, 873 "\t(auth_name) Empty NAME in auth " 874 "reply\n"); 875 return; 876 } 877 if (cnt > sizeof (namebuf)-1) { 878 if (auth_debug) 879 (void) fprintf(stderr, 880 "\t(auth_name) NAME exceeds %d bytes\n", 881 sizeof (namebuf)-1); 882 return; 883 } 884 (void) memcpy((void *)namebuf, (void *)data, cnt); 885 namebuf[cnt] = 0; 886 if (auth_debug) 887 (void) fprintf(stderr, "\t(auth_name) name [%s]\n", namebuf); 888 AuthenticatingUser = (char *)strdup(namebuf); 889 } 890 891 static void 892 auth_is(uchar_t *data, int cnt) 893 { 894 AuthInfo *aptr = auth_list; 895 896 if (cnt < 2) 897 return; 898 899 /* 900 * We failed to negoiate secure authentication 901 */ 902 if (data[0] == AUTHTYPE_NULL) { 903 auth_finished(0, AUTH_REJECT); 904 return; 905 } 906 907 while (aptr->AuthName != NULL && 908 (aptr->AuthName != data[0] || aptr->AuthHow != data[1])) 909 aptr++; 910 911 if (aptr != NULL) { 912 if (auth_debug) 913 (void) fprintf(stderr, "\t(auth_is) auth type is %s " 914 "(%d bytes)\n", aptr->AuthString, cnt); 915 916 if (aptr->AuthName == AUTHTYPE_KERBEROS_V5) 917 kerberos5_is(aptr, data+2, cnt-2); 918 } 919 } 920 921 static int 922 krb5_user_status(char *name, int namelen, int level) 923 { 924 int retval = AUTH_USER; 925 926 if (auth_debug) 927 (void) fprintf(stderr, "\t(krb5_user_status) level = %d " 928 "auth_level = %d user = %s\n", 929 level, auth_level, 930 (AuthenticatingUser != NULL ? AuthenticatingUser : "")); 931 932 if (level < AUTH_USER) 933 return (level); 934 935 if (AuthenticatingUser != NULL && 936 (retval = krb5_kuserok(telnet_context, ticket->enc_part2->client, 937 AuthenticatingUser))) { 938 (void) strncpy(name, AuthenticatingUser, namelen); 939 return (AUTH_VALID); 940 } else { 941 if (!retval) 942 syslog(LOG_ERR, 943 "Krb5 principal lacks permission to " 944 "access local account for %s", 945 AuthenticatingUser); 946 return (AUTH_USER); 947 } 948 } 949 950 /* 951 * Wrapper around /dev/urandom 952 */ 953 static int 954 getrandom(char *buf, int buflen) 955 { 956 static int devrandom = -1; 957 958 if (devrandom == -1 && 959 (devrandom = open("/dev/urandom", O_RDONLY)) == -1) { 960 fatalperror(net, "Unable to open /dev/urandom: ", 961 errno); 962 return (-1); 963 } 964 965 if (read(devrandom, buf, buflen) == -1) { 966 fatalperror(net, "Unable to read from /dev/urandom: ", 967 errno); 968 return (-1); 969 } 970 971 return (0); 972 } 973 974 /* 975 * encrypt_init 976 * 977 * Initialize the encryption data structures 978 */ 979 static void 980 encrypt_init() 981 { 982 (void) memset(&encr_data.encrypt, 0, sizeof (cipher_info_t)); 983 (void) memset(&encr_data.decrypt, 0, sizeof (cipher_info_t)); 984 985 encr_data.encrypt.state = ENCR_STATE_NOT_READY; 986 encr_data.decrypt.state = ENCR_STATE_NOT_READY; 987 } 988 989 /* 990 * encrypt_send_request_start 991 * 992 * Request that the remote side automatically start sending 993 * encrypted output 994 */ 995 static void 996 encrypt_send_request_start() 997 { 998 uchar_t buf[6+TELNET_MAXKEYIDLEN], *p; 999 1000 p = buf; 1001 1002 *p++ = IAC; 1003 *p++ = SB; 1004 *p++ = TELOPT_ENCRYPT; 1005 *p++ = ENCRYPT_REQSTART; 1006 /* 1007 * We are telling the remote side which 1008 * decrypt key we will use so that it may 1009 * encrypt in the same key. 1010 */ 1011 (void) memcpy(p, encr_data.decrypt.keyid, encr_data.decrypt.keyidlen); 1012 p += encr_data.decrypt.keyidlen; 1013 1014 *p++ = IAC; 1015 *p++ = SE; 1016 1017 write_data_len((const char *)buf, p-buf); 1018 netflush(); 1019 if (enc_debug) 1020 (void) fprintf(stderr, 1021 "SENT TELOPT_ENCRYPT ENCRYPT_REQSTART\n"); 1022 } 1023 1024 /* 1025 * encrypt_is 1026 * 1027 * When we receive the TELOPT_ENCRYPT ENCRYPT_IS ... 1028 * message, the client is telling us that it will be sending 1029 * encrypted data using the indicated cipher. 1030 * We must initialize the read (decrypt) side of our connection 1031 */ 1032 static void 1033 encrypt_is(uchar_t *data, int cnt) 1034 { 1035 register int type; 1036 register int iv_status = CFB64_IV_OK; 1037 register int lstate = 0; 1038 1039 uchar_t sbbuf[] = { 1040 (uchar_t)IAC, 1041 (uchar_t)SB, 1042 (uchar_t)TELOPT_ENCRYPT, 1043 (uchar_t)ENCRYPT_REPLY, 1044 (uchar_t)0, /* placeholder: sbbuf[4] */ 1045 (uchar_t)CFB64_IV_OK, /* placeholder: sbbuf[5] */ 1046 (uchar_t)IAC, 1047 (uchar_t)SE, 1048 }; 1049 1050 if (--cnt < 0) 1051 return; 1052 1053 type = sbbuf[4] = *data++; 1054 1055 /* 1056 * Steps to take: 1057 * 1. Create the proper stream Initialization vector 1058 * - copy the correct 'seed' to IV and output blocks 1059 * - set the correct key schedule 1060 * 2. Generate reply for the other side: 1061 * IAC SB TELOPT_ENCRYPT ENCRYPT_REPLY type CFB64_IV_OK 1062 * [ data ... ] IAC SE 1063 * 3. Tell crypto module: method, direction, IV 1064 */ 1065 switch (type) { 1066 case TELOPT_ENCTYPE_DES_CFB64: 1067 encr_data.decrypt.type = type; 1068 1069 lstate = encr_data.decrypt.state; 1070 if (enc_debug) 1071 (void) fprintf(stderr, 1072 "\t(encrypt_is) initial state = %d\n", 1073 lstate); 1074 /* 1075 * Before we extract the IV bytes, make sure we got 1076 * enough data. 1077 */ 1078 if (cnt < sizeof (Block)) { 1079 iv_status = CFB64_IV_BAD; 1080 if (enc_debug) 1081 (void) fprintf(stderr, 1082 "\t(encrypt_is) Not enough " 1083 "IV bytes\n"); 1084 lstate = ENCR_STATE_NOT_READY; 1085 } else { 1086 data++; /* skip over the CFB64_IV byte */ 1087 (void) memcpy(encr_data.decrypt.ivec, data, 1088 sizeof (Block)); 1089 lstate = ENCR_STATE_IN_PROGRESS; 1090 } 1091 break; 1092 case TELOPT_ENCTYPE_NULL: 1093 encr_data.decrypt.type = type; 1094 lstate &= ~ENCR_STATE_NO_RECV_IV; 1095 lstate &= ~ENCR_STATE_NO_SEND_IV; 1096 if (enc_debug) 1097 (void) fprintf(stderr, 1098 "\t(encrypt_is) We accept NULL encr\n"); 1099 break; 1100 default: 1101 iv_status = CFB64_IV_BAD; 1102 encr_data.decrypt.type = NULL; 1103 if (enc_debug) 1104 (void) fprintf(stderr, 1105 "\t(encrypt_is) Can't find type (%d) " 1106 "for initial negotiation\r\n", 1107 type); 1108 lstate = ENCR_STATE_NOT_READY; 1109 break; 1110 } 1111 1112 sbbuf[5] = (uchar_t)iv_status; /* either CFB64_IV_OK or BAD */ 1113 1114 if (iv_status == CFB64_IV_OK) { 1115 /* 1116 * send IV to crypto module and indicate it is for 1117 * decrypt only 1118 */ 1119 lstate &= ~ENCR_STATE_NO_RECV_IV; /* we received an OK IV */ 1120 lstate &= ~ENCR_STATE_NO_SEND_IV; /* we dont send an IV */ 1121 } else { 1122 /* tell crypto module to disable crypto on "read" stream */ 1123 lstate = ENCR_STATE_NOT_READY; 1124 } 1125 1126 write_data_len((const char *)sbbuf, sizeof (sbbuf)); 1127 netflush(); 1128 #ifdef ENCRYPT_NAMES 1129 if (enc_debug) 1130 (void) fprintf(stderr, 1131 "SENT TELOPT_ENCRYPT ENCRYPT_REPLY %s %s\n", 1132 ENCTYPE_NAME(type), 1133 (iv_status == CFB64_IV_OK ? "CFB64_IV_OK" : 1134 "CFB64_IV_BAD")); 1135 #endif /* ENCRYPT_NAMES */ 1136 /* Update the state of the decryption negotiation */ 1137 encr_data.decrypt.state = lstate; 1138 1139 if (lstate == ENCR_STATE_NOT_READY) 1140 encr_data.decrypt.autoflag = 0; 1141 else { 1142 if (lstate == ENCR_STATE_OK && encr_data.decrypt.autoflag) 1143 encrypt_send_request_start(); 1144 } 1145 if (enc_debug) 1146 (void) fprintf(stderr, 1147 "\t(encrypt_is) final DECRYPT state = %d\n", 1148 encr_data.decrypt.state); 1149 } 1150 1151 /* 1152 * encrypt_send_encrypt_is 1153 * 1154 * Tell the client what encryption we will use 1155 * and what our IV will be. 1156 */ 1157 static int 1158 encrypt_send_encrypt_is() 1159 { 1160 register int lstate; 1161 krb5_error_code kret; 1162 uchar_t sbbuf[MAXOPTLEN], *p; 1163 int i; 1164 1165 lstate = encr_data.encrypt.state; 1166 1167 if (encr_data.encrypt.type == ENCTYPE_NULL) { 1168 /* 1169 * Haven't received ENCRYPT SUPPORT yet or we couldn't agree 1170 * on a cipher. 1171 */ 1172 return (lstate); 1173 } 1174 1175 /* 1176 * - Create a random DES key 1177 * 1178 * - DES ECB encrypt 1179 * encrypt the IV using itself as the key. 1180 * 1181 * - Send response 1182 * IAC SB TELOPT_ENCRYPT ENCRYPT_IS CFB64 FB64_IV [ feed block ] 1183 * IAC SE 1184 * 1185 */ 1186 if (lstate == ENCR_STATE_NOT_READY) 1187 lstate = ENCR_STATE_IN_PROGRESS; 1188 else if ((lstate & ENCR_STATE_NO_SEND_IV) == 0) { 1189 if (enc_debug) 1190 (void) fprintf(stderr, 1191 "\t(encrypt_send_is) IV already sent," 1192 " state = %d\n", lstate); 1193 return (lstate); 1194 } 1195 1196 if (!VALIDKEY(encr_data.encrypt.krbdes_key)) { 1197 /* 1198 * Invalid key, set flag so we try again later 1199 * when we get a good one 1200 */ 1201 encr_data.encrypt.need_start = 1; 1202 if (enc_debug) 1203 (void) fprintf(stderr, 1204 "\t(encrypt_send_is) No Key, cannot " 1205 "start encryption yet\n"); 1206 return (lstate); 1207 } 1208 if (enc_debug) 1209 (void) fprintf(stderr, 1210 "\t(encrypt_send_is) Creating new feed\n"); 1211 1212 /* 1213 * Create a random feed and send it over. 1214 * 1215 * Use the /dev/[u]random interface to generate 1216 * our encryption IV. 1217 */ 1218 kret = getrandom((char *)encr_data.encrypt.ivec, sizeof (Block)); 1219 1220 if (kret) { 1221 if (enc_debug) 1222 (void) fprintf(stderr, 1223 "\t(encrypt_send_is) error from " 1224 "getrandom: %d\n", kret); 1225 syslog(LOG_ERR, "Failed to create encryption key (err %d)\n"); 1226 encr_data.encrypt.type = ENCTYPE_NULL; 1227 } else { 1228 mit_des_fixup_key_parity(encr_data.encrypt.ivec); 1229 } 1230 1231 p = sbbuf; 1232 *p++ = IAC; 1233 *p++ = SB; 1234 *p++ = TELOPT_ENCRYPT; 1235 *p++ = ENCRYPT_IS; 1236 *p++ = encr_data.encrypt.type; 1237 *p++ = CFB64_IV; 1238 1239 /* 1240 * Copy the IV bytes individually so that when a 1241 * 255 (telnet IAC) is used, it can be "escaped" by 1242 * adding it twice (telnet RFC 854). 1243 */ 1244 for (i = 0; i < sizeof (Block); i++) 1245 if ((*p++ = encr_data.encrypt.ivec[i]) == IAC) 1246 *p++ = IAC; 1247 1248 *p++ = IAC; 1249 *p++ = SE; 1250 write_data_len((const char *)sbbuf, (size_t)(p-sbbuf)); 1251 netflush(); 1252 1253 if (!kret) { 1254 lstate &= ~ENCR_STATE_NO_SEND_IV; /* we sent our IV */ 1255 lstate &= ~ENCR_STATE_NO_SEND_IV; /* dont need decrypt IV */ 1256 } 1257 encr_data.encrypt.state = lstate; 1258 1259 if (enc_debug) { 1260 int i; 1261 (void) fprintf(stderr, 1262 "SENT TELOPT_ENCRYPT ENCRYPT_IS %d CFB64_IV ", 1263 encr_data.encrypt.type); 1264 for (i = 0; i < (p-sbbuf); i++) 1265 (void) fprintf(stderr, "%d ", (int)sbbuf[i]); 1266 (void) fprintf(stderr, "\n"); 1267 } 1268 1269 return (lstate); 1270 } 1271 1272 /* 1273 * stop_stream 1274 * 1275 * Utility routine to send a CRIOCSTOP ioctl to the 1276 * crypto module (cryptmod). 1277 */ 1278 static void 1279 stop_stream(int fd, int dir) 1280 { 1281 struct strioctl crioc; 1282 uint32_t stopdir = dir; 1283 1284 crioc.ic_cmd = CRYPTIOCSTOP; 1285 crioc.ic_timout = -1; 1286 crioc.ic_len = sizeof (stopdir); 1287 crioc.ic_dp = (char *)&stopdir; 1288 1289 if (ioctl(fd, I_STR, &crioc)) { 1290 syslog(LOG_ERR, "Error sending CRYPTIOCSTOP ioctl: %m"); 1291 } 1292 } 1293 1294 /* 1295 * start_stream 1296 * 1297 * Utility routine to send a CRYPTIOCSTART ioctl to the 1298 * crypto module (cryptmod). This routine may contain optional 1299 * payload data that the cryptmod will interpret as bytes that 1300 * need to be decrypted and sent back up to the application 1301 * via the data stream. 1302 */ 1303 static void 1304 start_stream(int fd, int dir, int datalen, char *data) 1305 { 1306 struct strioctl crioc; 1307 1308 crioc.ic_cmd = (dir == CRYPT_ENCRYPT ? CRYPTIOCSTARTENC : 1309 CRYPTIOCSTARTDEC); 1310 crioc.ic_timout = -1; 1311 crioc.ic_len = datalen; 1312 crioc.ic_dp = data; 1313 1314 if (ioctl(fd, I_STR, &crioc)) { 1315 syslog(LOG_ERR, "Error sending CRYPTIOCSTART ioctl: %m"); 1316 } 1317 } 1318 1319 /* 1320 * encrypt_start_output 1321 * 1322 * Tell the other side to start encrypting its data 1323 */ 1324 static void 1325 encrypt_start_output() 1326 { 1327 int lstate; 1328 uchar_t *p; 1329 uchar_t sbbuf[MAXOPTLEN]; 1330 struct strioctl crioc; 1331 struct cr_info_t cki; 1332 1333 /* 1334 * Initialize crypto and send the ENCRYPT_IS msg 1335 */ 1336 lstate = encrypt_send_encrypt_is(); 1337 1338 if (lstate != ENCR_STATE_OK) { 1339 if (enc_debug) 1340 (void) fprintf(stderr, 1341 "\t(encrypt_start_output) ENCRYPT state " 1342 "= %d\n", lstate); 1343 return; 1344 } 1345 1346 p = sbbuf; 1347 1348 *p++ = IAC; 1349 *p++ = SB; 1350 *p++ = TELOPT_ENCRYPT; 1351 *p++ = ENCRYPT_START; 1352 1353 (void) memcpy(p, encr_data.encrypt.keyid, encr_data.encrypt.keyidlen); 1354 p += encr_data.encrypt.keyidlen; 1355 1356 *p++ = IAC; 1357 *p++ = SE; 1358 1359 /* Flush this data out before we start encrypting */ 1360 write_data_len((const char *)sbbuf, (int)(p-sbbuf)); 1361 netflush(); 1362 1363 if (enc_debug) 1364 (void) fprintf(stderr, "SENT TELOPT_ENCRYPT ENCRYPT_START %d " 1365 "(lstate = %d) data waiting = %d\n", 1366 (int)encr_data.encrypt.keyid[0], 1367 lstate, nfrontp-nbackp); 1368 1369 encr_data.encrypt.state = lstate; 1370 1371 /* 1372 * tell crypto module what key to use for encrypting 1373 * Note that the ENCRYPT has not yet been enabled, but we 1374 * need to first set the crypto key to use. 1375 */ 1376 cki.direction_mask = CRYPT_ENCRYPT; 1377 1378 if (encr_data.encrypt.type == TELOPT_ENCTYPE_DES_CFB64) { 1379 cki.crypto_method = CRYPT_METHOD_DES_CFB; 1380 } else { 1381 if (enc_debug) 1382 (void) fprintf(stderr, 1383 "\t(encrypt_start_output) - unknown " 1384 "crypto_method %d\n", 1385 encr_data.encrypt.type); 1386 syslog(LOG_ERR, "unrecognized crypto encrypt method: %d", 1387 encr_data.encrypt.type); 1388 1389 return; 1390 } 1391 1392 /* 1393 * If we previously configured this crypto method, we dont want to 1394 * overwrite the key or ivec information already given to the crypto 1395 * module as it will cause the cipher data between the client and server 1396 * to become out of synch and impossible to decipher. 1397 */ 1398 if (encr_data.encrypt.setup == cki.crypto_method) { 1399 cki.keylen = 0; 1400 cki.iveclen = 0; 1401 } else { 1402 cki.keylen = DES_BLOCKSIZE; 1403 (void) memcpy(cki.key, (void *)encr_data.encrypt.krbdes_key, 1404 DES_BLOCKSIZE); 1405 1406 cki.iveclen = DES_BLOCKSIZE; 1407 (void) memcpy(cki.ivec, (void *)encr_data.encrypt.ivec, 1408 DES_BLOCKSIZE); 1409 1410 cki.ivec_usage = IVEC_ONETIME; 1411 } 1412 1413 cki.option_mask = 0; 1414 1415 /* Stop encrypt side prior to setup so we dont lose data */ 1416 stop_stream(cryptmod_fd, CRYPT_ENCRYPT); 1417 1418 crioc.ic_cmd = CRYPTIOCSETUP; 1419 crioc.ic_timout = -1; 1420 crioc.ic_len = sizeof (struct cr_info_t); 1421 crioc.ic_dp = (char *)&cki; 1422 1423 if (ioctl(cryptmod_fd, I_STR, &crioc)) { 1424 perror("ioctl(CRYPTIOCSETUP) [encrypt_start_output] error"); 1425 } else { 1426 /* Setup completed OK */ 1427 encr_data.encrypt.setup = cki.crypto_method; 1428 } 1429 1430 /* 1431 * We do not check for "stuck" data when setting up the 1432 * outbound "encrypt" channel. Any data queued prior to 1433 * this IOCTL will get processed correctly without our help. 1434 */ 1435 start_stream(cryptmod_fd, CRYPT_ENCRYPT, 0, NULL); 1436 1437 /* 1438 * tell crypto module to start encrypting 1439 */ 1440 if (enc_debug) 1441 (void) fprintf(stderr, 1442 "\t(encrypt_start_output) Encrypting output\n"); 1443 } 1444 1445 /* 1446 * encrypt_request_start 1447 * 1448 * The client requests that we start encryption immediately after 1449 * successful negotiation 1450 */ 1451 static void 1452 encrypt_request_start(void) 1453 { 1454 if (encr_data.encrypt.type == ENCTYPE_NULL) { 1455 encr_data.encrypt.autoflag = 1; 1456 if (enc_debug) 1457 (void) fprintf(stderr, "\t(encrypt_request_start) " 1458 "autoencrypt = ON\n"); 1459 } else { 1460 encrypt_start_output(); 1461 } 1462 } 1463 1464 /* 1465 * encrypt_end 1466 * 1467 * ENCRYPT END received, stop decrypting the read stream 1468 */ 1469 static void 1470 encrypt_end(int direction) 1471 { 1472 struct cr_info_t cki; 1473 struct strioctl crioc; 1474 uint32_t stopdir; 1475 1476 stopdir = (direction == TELNET_DIR_DECRYPT ? CRYPT_DECRYPT : 1477 CRYPT_ENCRYPT); 1478 1479 stop_stream(cryptmod_fd, stopdir); 1480 1481 /* 1482 * Call this function when we wish to disable crypto in 1483 * either direction (ENCRYPT or DECRYPT) 1484 */ 1485 cki.direction_mask = (direction == TELNET_DIR_DECRYPT ? CRYPT_DECRYPT : 1486 CRYPT_ENCRYPT); 1487 cki.crypto_method = CRYPT_METHOD_NONE; 1488 cki.option_mask = 0; 1489 1490 cki.keylen = 0; 1491 cki.iveclen = 0; 1492 cki.ivec_usage = IVEC_ONETIME; 1493 1494 crioc.ic_cmd = CRYPTIOCSETUP; 1495 crioc.ic_timout = -1; 1496 crioc.ic_len = sizeof (cki); 1497 crioc.ic_dp = (char *)&cki; 1498 1499 if (ioctl(cryptmod_fd, I_STR, &crioc)) { 1500 perror("ioctl(CRYPTIOCSETUP) [encrypt_end] error"); 1501 } 1502 1503 start_stream(cryptmod_fd, stopdir, 0, NULL); 1504 } 1505 1506 /* 1507 * encrypt_request_end 1508 * 1509 * When we receive a REQEND from the client, it means 1510 * that we are supposed to stop encrypting 1511 */ 1512 static void 1513 encrypt_request_end() 1514 { 1515 /* 1516 * Tell the other side we are done encrypting 1517 */ 1518 1519 write_data("%c%c%c%c%c%c", 1520 (uchar_t)IAC, 1521 (uchar_t)SB, 1522 (uchar_t)TELOPT_ENCRYPT, 1523 (uchar_t)ENCRYPT_END, 1524 (uchar_t)IAC, 1525 (uchar_t)SE); 1526 netflush(); 1527 if (enc_debug) 1528 (void) fprintf(stderr, "SENT TELOPT_ENCRYPT ENCRYPT_END\n"); 1529 1530 /* 1531 * Turn off encryption of the write stream 1532 */ 1533 encrypt_end(TELNET_DIR_ENCRYPT); 1534 } 1535 1536 /* 1537 * encrypt_send_request_end 1538 * 1539 * We stop encrypting the write stream and tell the other side about it. 1540 */ 1541 static void 1542 encrypt_send_request_end() 1543 { 1544 write_data("%c%c%c%c%c%c", 1545 (uchar_t)IAC, 1546 (uchar_t)SB, 1547 (uchar_t)TELOPT_ENCRYPT, 1548 (uchar_t)ENCRYPT_REQEND, 1549 (uchar_t)IAC, 1550 (uchar_t)SE); 1551 netflush(); 1552 if (enc_debug) 1553 (void) fprintf(stderr, "SENT TELOPT_ENCRYPT ENCRYPT_REQEND\n"); 1554 } 1555 1556 /* 1557 * encrypt_start 1558 * 1559 * The client is going to start sending encrypted data 1560 * using the previously negotiated cipher (see what we set 1561 * when we did the REPLY in encrypt_is). 1562 */ 1563 static void 1564 encrypt_start(void) 1565 { 1566 struct cr_info_t cki; 1567 struct strioctl crioc; 1568 int bytes = 0; 1569 char *dataptr = NULL; 1570 1571 if (encr_data.decrypt.type == ENCTYPE_NULL) { 1572 if (enc_debug) 1573 (void) fprintf(stderr, 1574 "\t(encrypt_start) No DECRYPT method " 1575 "defined yet\n"); 1576 encrypt_send_request_end(); 1577 return; 1578 } 1579 1580 cki.direction_mask = CRYPT_DECRYPT; 1581 1582 if (encr_data.decrypt.type == TELOPT_ENCTYPE_DES_CFB64) { 1583 cki.crypto_method = CRYPT_METHOD_DES_CFB; 1584 } else { 1585 if (enc_debug) 1586 (void) fprintf(stderr, 1587 "\t(encrypt_start) - unknown " 1588 "crypto_method %d\n", encr_data.decrypt.type); 1589 1590 syslog(LOG_ERR, "unrecognized crypto decrypt method: %d", 1591 encr_data.decrypt.type); 1592 1593 return; 1594 } 1595 1596 /* 1597 * Don't overwrite previously configured key and ivec info 1598 */ 1599 if (encr_data.decrypt.setup != cki.crypto_method) { 1600 (void) memcpy(cki.key, (void *)encr_data.decrypt.krbdes_key, 1601 DES_BLOCKSIZE); 1602 (void) memcpy(cki.ivec, (void *)encr_data.decrypt.ivec, 1603 DES_BLOCKSIZE); 1604 1605 cki.keylen = DES_BLOCKSIZE; 1606 cki.iveclen = DES_BLOCKSIZE; 1607 cki.ivec_usage = IVEC_ONETIME; 1608 } else { 1609 cki.keylen = 0; 1610 cki.iveclen = 0; 1611 } 1612 cki.option_mask = 0; 1613 1614 stop_stream(cryptmod_fd, CRYPT_DECRYPT); 1615 1616 crioc.ic_cmd = CRYPTIOCSETUP; 1617 crioc.ic_timout = -1; 1618 crioc.ic_len = sizeof (struct cr_info_t); 1619 crioc.ic_dp = (char *)&cki; 1620 1621 if (ioctl(cryptmod_fd, I_STR, &crioc)) { 1622 syslog(LOG_ERR, "ioctl(CRYPTIOCSETUP) [encrypt_start] " 1623 "error: %m"); 1624 } else { 1625 encr_data.decrypt.setup = cki.crypto_method; 1626 } 1627 if (enc_debug) 1628 (void) fprintf(stderr, 1629 "\t(encrypt_start) called CRYPTIOCSETUP for " 1630 "decrypt side\n"); 1631 1632 /* 1633 * Read any data stuck between the cryptmod and the application 1634 * so we can pass it back down to be properly decrypted after 1635 * this operation finishes. 1636 */ 1637 if (ioctl(cryptmod_fd, I_NREAD, &bytes) < 0) { 1638 syslog(LOG_ERR, "I_NREAD returned error %m"); 1639 bytes = 0; 1640 } 1641 1642 /* 1643 * Any data which was read AFTER the ENCRYPT START message 1644 * must be sent back down to be decrypted properly. 1645 * 1646 * 'ncc' is the number of bytes that have been read but 1647 * not yet processed by the telnet state machine. 1648 * 1649 * 'bytes' is the number of bytes waiting to be read from 1650 * the stream. 1651 * 1652 * If either one is a positive value, then those bytes 1653 * must be pulled up and sent back down to be decrypted. 1654 */ 1655 if (ncc || bytes) { 1656 drainstream(bytes); 1657 if (enc_debug) 1658 (void) fprintf(stderr, 1659 "\t(encrypt_start) after drainstream, " 1660 "ncc=%d bytes = %d\n", ncc, bytes); 1661 bytes += ncc; 1662 dataptr = netip; 1663 } 1664 1665 start_stream(cryptmod_fd, CRYPT_DECRYPT, bytes, dataptr); 1666 1667 /* 1668 * The bytes putback into the stream are no longer 1669 * available to be read by the server, so adjust the 1670 * counter accordingly. 1671 */ 1672 ncc = 0; 1673 netip = netibuf; 1674 (void) memset(netip, 0, netibufsize); 1675 1676 #ifdef ENCRYPT_NAMES 1677 if (enc_debug) { 1678 (void) fprintf(stderr, 1679 "\t(encrypt_start) Start DECRYPT using %s\n", 1680 ENCTYPE_NAME(encr_data.decrypt.type)); 1681 } 1682 #endif /* ENCRYPT_NAMES */ 1683 } 1684 1685 /* 1686 * encrypt_support 1687 * 1688 * Called when we recieve the TELOPT_ENCRYPT SUPPORT [ encr type list ] 1689 * message from a client. 1690 * 1691 * Choose an agreeable method (DES_CFB64) and 1692 * respond with TELOPT_ENCRYPT ENCRYPT_IS [ desired crypto method ] 1693 * 1694 * from: RFC 2946 1695 */ 1696 static void 1697 encrypt_support(char *data, int cnt) 1698 { 1699 int lstate = ENCR_STATE_NOT_READY; 1700 int type, use_type = 0; 1701 1702 while (cnt-- > 0 && use_type == 0) { 1703 type = *data++; 1704 #ifdef ENCRYPT_NAMES 1705 if (enc_debug) 1706 (void) fprintf(stderr, 1707 "RCVD ENCRYPT SUPPORT %s\n", 1708 ENCTYPE_NAME(type)); 1709 #endif /* ENCRYPT_NAMES */ 1710 /* 1711 * Prefer CFB64 1712 */ 1713 if (type == TELOPT_ENCTYPE_DES_CFB64) { 1714 use_type = type; 1715 } 1716 } 1717 encr_data.encrypt.type = use_type; 1718 1719 if (use_type != TELOPT_ENCTYPE_NULL && 1720 authenticated != NULL && authenticated != &NoAuth && 1721 auth_status != AUTH_REJECT) { 1722 1723 /* Authenticated -> have session key -> send ENCRYPT IS */ 1724 lstate = encrypt_send_encrypt_is(); 1725 if (lstate == ENCR_STATE_OK) 1726 encrypt_start_output(); 1727 } else if (use_type == TELOPT_ENCTYPE_NULL) { 1728 if (enc_debug) 1729 (void) fprintf(stderr, 1730 "\t(encrypt_support) Cannot agree " 1731 "on crypto algorithm, output encryption " 1732 "disabled.\n"); 1733 1734 /* 1735 * Cannot agree on crypto algorithm 1736 * RFC 2946 sez: 1737 * send "IAC SB ENCRYPT IS NULL IAC SE" 1738 * optionally, also send IAC WONT ENCRYPT 1739 */ 1740 write_data("%c%c%c%c%c%c%c", 1741 (uchar_t)IAC, 1742 (uchar_t)SB, 1743 (uchar_t)TELOPT_ENCRYPT, 1744 (uchar_t)ENCRYPT_IS, 1745 (uchar_t)TELOPT_ENCTYPE_NULL, 1746 (uchar_t)IAC, 1747 (uchar_t)SE); 1748 send_wont(TELOPT_ENCRYPT); 1749 netflush(); 1750 if (enc_debug) 1751 (void) fprintf(stderr, 1752 "SENT TELOPT_ENCRYPT ENCRYPT_IS " 1753 "[NULL]\n"); 1754 1755 remopts[TELOPT_ENCRYPT] = OPT_NO; 1756 } 1757 settimer(encr_support); 1758 } 1759 1760 /* 1761 * encrypt_send_keyid 1762 * 1763 * Sent the key id we will use to the client 1764 */ 1765 static void 1766 encrypt_send_keyid(int dir, uchar_t *keyid, int keylen, boolean_t saveit) 1767 { 1768 uchar_t sbbuf[128], *p; 1769 1770 p = sbbuf; 1771 1772 *p++ = IAC; 1773 *p++ = SB; 1774 *p++ = TELOPT_ENCRYPT; 1775 *p++ = (dir == TELNET_DIR_ENCRYPT ? ENCRYPT_ENC_KEYID : 1776 ENCRYPT_DEC_KEYID); 1777 if (saveit) { 1778 if (enc_debug) 1779 (void) fprintf(stderr, 1780 "\t(send_keyid) store %d byte %s keyid\n", 1781 keylen, 1782 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : 1783 "DECRYPT")); 1784 1785 if (dir == TELNET_DIR_ENCRYPT) { 1786 (void) memcpy(encr_data.encrypt.keyid, keyid, keylen); 1787 encr_data.encrypt.keyidlen = keylen; 1788 } else { 1789 (void) memcpy(encr_data.decrypt.keyid, keyid, keylen); 1790 encr_data.decrypt.keyidlen = keylen; 1791 } 1792 } 1793 (void) memcpy(p, keyid, keylen); 1794 p += keylen; 1795 1796 *p++ = IAC; 1797 *p++ = SE; 1798 write_data_len((const char *)sbbuf, (size_t)(p-sbbuf)); 1799 netflush(); 1800 1801 if (enc_debug) 1802 (void) fprintf(stderr, "SENT TELOPT_ENCRYPT %s %d\n", 1803 (dir == TELNET_DIR_ENCRYPT ? "ENC_KEYID" : 1804 "DEC_KEYID"), keyid[0]); 1805 } 1806 1807 /* 1808 * encrypt_reply 1809 * 1810 * When we receive the TELOPT_ENCRYPT REPLY [crtype] CFB64_IV_OK IAC SE 1811 * message, process it accordingly. 1812 * If the vector is acceptable, tell client we are encrypting and 1813 * enable encryption on our write stream. 1814 * 1815 * Negotiate the KEYID next.. 1816 * RFC 2946, 2952 1817 */ 1818 static void 1819 encrypt_reply(char *data, int len) 1820 { 1821 uchar_t type = (uchar_t)(*data++); 1822 uchar_t result = (uchar_t)(*data); 1823 int lstate; 1824 1825 #ifdef ENCRYPT_NAMES 1826 if (enc_debug) 1827 (void) fprintf(stderr, 1828 "\t(encrypt_reply) ENCRYPT REPLY %s %s [len=%d]\n", 1829 ENCRYPT_NAME(type), 1830 (result == CFB64_IV_OK ? "CFB64_IV_OK" : 1831 "CFB64_IV_BAD"), len); 1832 #endif /* ENCRYPT_NAMES */ 1833 1834 lstate = encr_data.encrypt.state; 1835 if (enc_debug) 1836 (void) fprintf(stderr, 1837 "\t(encrypt_reply) initial ENCRYPT state = %d\n", 1838 lstate); 1839 switch (result) { 1840 case CFB64_IV_OK: 1841 if (lstate == ENCR_STATE_NOT_READY) 1842 lstate = ENCR_STATE_IN_PROGRESS; 1843 lstate &= ~ENCR_STATE_NO_RECV_IV; /* we got the IV */ 1844 lstate &= ~ENCR_STATE_NO_SEND_IV; /* we dont need to send IV */ 1845 1846 /* 1847 * The correct response here is to send the encryption key id 1848 * RFC 2752. 1849 * 1850 * Send keyid 0 to indicate that we will just use default 1851 * keys. 1852 */ 1853 encrypt_send_keyid(TELNET_DIR_ENCRYPT, (uchar_t *)"\0", 1, 1); 1854 1855 break; 1856 case CFB64_IV_BAD: 1857 /* 1858 * Clear the ivec 1859 */ 1860 (void) memset(encr_data.encrypt.ivec, 0, sizeof (Block)); 1861 lstate = ENCR_STATE_NOT_READY; 1862 break; 1863 default: 1864 if (enc_debug) 1865 (void) fprintf(stderr, 1866 "\t(encrypt_reply) Got unknown IV value in " 1867 "REPLY message\n"); 1868 lstate = ENCR_STATE_NOT_READY; 1869 break; 1870 } 1871 1872 encr_data.encrypt.state = lstate; 1873 if (lstate == ENCR_STATE_NOT_READY) { 1874 encr_data.encrypt.autoflag = 0; 1875 encr_data.encrypt.type = ENCTYPE_NULL; 1876 if (enc_debug) 1877 (void) fprintf(stderr, 1878 "\t(encrypt_reply) encrypt.autoflag = " 1879 "OFF\n"); 1880 } else { 1881 encr_data.encrypt.type = type; 1882 if ((lstate == ENCR_STATE_OK) && encr_data.encrypt.autoflag) 1883 encrypt_start_output(); 1884 } 1885 1886 if (enc_debug) 1887 (void) fprintf(stderr, 1888 "\t(encrypt_reply) ENCRYPT final state = %d\n", 1889 lstate); 1890 } 1891 1892 static void 1893 encrypt_set_keyid_state(uchar_t *keyid, int *keyidlen, int dir) 1894 { 1895 int lstate; 1896 1897 lstate = (dir == TELNET_DIR_ENCRYPT ? encr_data.encrypt.state : 1898 encr_data.decrypt.state); 1899 1900 if (enc_debug) 1901 (void) fprintf(stderr, 1902 "\t(set_keyid_state) %s initial state = %d\n", 1903 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : 1904 "DECRYPT"), lstate); 1905 1906 /* 1907 * Currently, we only support using the default keyid, 1908 * so it should be an error if the len > 1 or the keyid != 0. 1909 */ 1910 if (*keyidlen != 1 || (*keyid != '\0')) { 1911 if (enc_debug) 1912 (void) fprintf(stderr, 1913 "\t(set_keyid_state) unexpected keyid: " 1914 "len=%d value=%d\n", *keyidlen, *keyid); 1915 *keyidlen = 0; 1916 syslog(LOG_ERR, "rcvd unexpected keyid %d - only keyid of 0 " 1917 "is supported", *keyid); 1918 } else { 1919 /* 1920 * We move to the "IN_PROGRESS" state. 1921 */ 1922 if (lstate == ENCR_STATE_NOT_READY) 1923 lstate = ENCR_STATE_IN_PROGRESS; 1924 /* 1925 * Clear the NO_KEYID bit because we now have a valid keyid 1926 */ 1927 lstate &= ~ENCR_STATE_NO_KEYID; 1928 } 1929 1930 if (enc_debug) 1931 (void) fprintf(stderr, 1932 "\t(set_keyid_state) %s final state = %d\n", 1933 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : 1934 "DECRYPT"), lstate); 1935 1936 if (dir == TELNET_DIR_ENCRYPT) 1937 encr_data.encrypt.state = lstate; 1938 else 1939 encr_data.decrypt.state = lstate; 1940 } 1941 1942 /* 1943 * encrypt_keyid 1944 * 1945 * Set the keyid value in the key_info structure. 1946 * if necessary send a response to the sender 1947 */ 1948 static void 1949 encrypt_keyid(uchar_t *newkeyid, int *keyidlen, uchar_t *keyid, 1950 int len, int dir) 1951 { 1952 if (len > TELNET_MAXNUMKEYS) { 1953 if (enc_debug) 1954 (void) fprintf(stderr, 1955 "\t(keyid) keylen too big (%d)\n", len); 1956 return; 1957 } 1958 1959 if (enc_debug) { 1960 (void) fprintf(stderr, "\t(keyid) set KEYID for %s len = %d\n", 1961 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : 1962 "DECRYPT"), len); 1963 } 1964 1965 if (len == 0) { 1966 if (*keyidlen == 0) { 1967 if (enc_debug) 1968 (void) fprintf(stderr, 1969 "\t(keyid) Got 0 length keyid - " 1970 "failure\n"); 1971 return; 1972 } 1973 *keyidlen = 0; 1974 encrypt_set_keyid_state(newkeyid, keyidlen, dir); 1975 1976 } else if (len != *keyidlen || memcmp(keyid, newkeyid, len)) { 1977 if (enc_debug) 1978 (void) fprintf(stderr, 1979 "\t(keyid) Setting new key (%d bytes)\n", 1980 len); 1981 1982 *keyidlen = len; 1983 (void) memcpy(newkeyid, keyid, len); 1984 1985 encrypt_set_keyid_state(newkeyid, keyidlen, dir); 1986 } else { 1987 encrypt_set_keyid_state(newkeyid, keyidlen, dir); 1988 1989 if (enc_debug) 1990 (void) fprintf(stderr, 1991 "\t(keyid) %s Key already in place," 1992 "state = %d autoflag=%d\n", 1993 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : "DECRYPT"), 1994 (dir == TELNET_DIR_ENCRYPT ? encr_data.encrypt.state: 1995 encr_data.decrypt.state), 1996 (dir == TELNET_DIR_ENCRYPT ? 1997 encr_data.encrypt.autoflag: 1998 encr_data.decrypt.autoflag)); 1999 2000 /* key already in place */ 2001 if ((encr_data.encrypt.state == ENCR_STATE_OK) && 2002 dir == TELNET_DIR_ENCRYPT && encr_data.encrypt.autoflag) { 2003 encrypt_start_output(); 2004 } 2005 return; 2006 } 2007 2008 if (enc_debug) 2009 (void) fprintf(stderr, "\t(keyid) %s final state = %d\n", 2010 (dir == TELNET_DIR_ENCRYPT ? "ENCRYPT" : 2011 "DECRYPT"), 2012 (dir == TELNET_DIR_ENCRYPT ? 2013 encr_data.encrypt.state : 2014 encr_data.decrypt.state)); 2015 2016 encrypt_send_keyid(dir, newkeyid, *keyidlen, 0); 2017 } 2018 2019 /* 2020 * encrypt_enc_keyid 2021 * 2022 * We received the ENC_KEYID message from a client indicating that 2023 * the client wishes to verify that the indicated keyid maps to a 2024 * valid key. 2025 */ 2026 static void 2027 encrypt_enc_keyid(char *data, int cnt) 2028 { 2029 /* 2030 * Verify the decrypt keyid is valid 2031 */ 2032 encrypt_keyid(encr_data.decrypt.keyid, &encr_data.decrypt.keyidlen, 2033 (uchar_t *)data, cnt, TELNET_DIR_DECRYPT); 2034 } 2035 2036 /* 2037 * encrypt_dec_keyid 2038 * 2039 * We received the DEC_KEYID message from a client indicating that 2040 * the client wants to verify that the indicated keyid maps to a valid key. 2041 */ 2042 static void 2043 encrypt_dec_keyid(char *data, int cnt) 2044 { 2045 encrypt_keyid(encr_data.encrypt.keyid, &encr_data.encrypt.keyidlen, 2046 (uchar_t *)data, cnt, TELNET_DIR_ENCRYPT); 2047 } 2048 2049 /* 2050 * encrypt_session_key 2051 * 2052 * Store the session key in the encryption data record 2053 */ 2054 static void 2055 encrypt_session_key(Session_Key *key, cipher_info_t *cinfo) 2056 { 2057 if (key == NULL || key->type != SK_DES) { 2058 if (enc_debug) 2059 (void) fprintf(stderr, 2060 "\t(session_key) Cannot set krb5 " 2061 "session key (unknown type = %d)\n", 2062 key ? key->type : -1); 2063 } 2064 if (enc_debug) 2065 (void) fprintf(stderr, 2066 "\t(session_key) Settting session key " 2067 "for server\n"); 2068 2069 /* store the key in the cipher info data struct */ 2070 (void) memcpy(cinfo->krbdes_key, (void *)key->data, sizeof (Block)); 2071 2072 /* 2073 * Now look to see if we still need to send the key and start 2074 * encrypting. 2075 * 2076 * If so, go ahead an call it now that we have the key. 2077 */ 2078 if (cinfo->need_start) { 2079 if (encrypt_send_encrypt_is() == ENCR_STATE_OK) { 2080 cinfo->need_start = 0; 2081 } 2082 } 2083 } 2084 2085 /* 2086 * new_env 2087 * 2088 * Used to add an environment variable and value to the 2089 * linked list structure. 2090 */ 2091 static int 2092 new_env(const char *name, const char *value) 2093 { 2094 struct envlist *env; 2095 2096 env = malloc(sizeof (struct envlist)); 2097 if (env == NULL) 2098 return (1); 2099 if ((env->name = strdup(name)) == NULL) { 2100 free(env); 2101 return (1); 2102 } 2103 if ((env->value = strdup(value)) == NULL) { 2104 free(env->name); 2105 free(env); 2106 return (1); 2107 } 2108 env->delete = 0; 2109 env->next = envlist_head; 2110 envlist_head = env; 2111 return (0); 2112 } 2113 2114 /* 2115 * del_env 2116 * 2117 * Used to delete an environment variable from the linked list 2118 * structure. We just set a flag because we will delete the list 2119 * anyway before we exec login. 2120 */ 2121 static int 2122 del_env(const char *name) 2123 { 2124 struct envlist *env; 2125 2126 for (env = envlist_head; env; env = env->next) { 2127 if (strcmp(env->name, name) == 0) { 2128 env->delete = 1; 2129 break; 2130 } 2131 } 2132 return (0); 2133 } 2134 2135 static int 2136 issock(int fd) 2137 { 2138 struct stat stats; 2139 2140 if (fstat(fd, &stats) == -1) 2141 return (0); 2142 return (S_ISSOCK(stats.st_mode)); 2143 } 2144 2145 /* 2146 * audit_telnet_settid stores the terminal id while it is still 2147 * available. Subsequent calls to adt_load_hostname() return 2148 * the id which is stored here. 2149 */ 2150 static int 2151 audit_telnet_settid(int sock) { 2152 adt_session_data_t *ah; 2153 adt_termid_t *termid; 2154 int rc; 2155 2156 if ((rc = adt_start_session(&ah, NULL, 0)) == 0) { 2157 if ((rc = adt_load_termid(sock, &termid)) == 0) { 2158 if ((rc = adt_set_user(ah, ADT_NO_AUDIT, 2159 ADT_NO_AUDIT, 0, ADT_NO_AUDIT, 2160 termid, ADT_SETTID)) == 0) 2161 (void) adt_set_proc(ah); 2162 free(termid); 2163 } 2164 (void) adt_end_session(ah); 2165 } 2166 return (rc); 2167 } 2168 2169 /* ARGSUSED */ 2170 int 2171 main(int argc, char *argv[]) 2172 { 2173 struct sockaddr_storage from; 2174 int on = 1; 2175 socklen_t fromlen; 2176 int issocket; 2177 #if defined(DEBUG) 2178 ushort_t porttouse = 0; 2179 boolean_t standalone = 0; 2180 #endif /* defined(DEBUG) */ 2181 extern char *optarg; 2182 char c; 2183 int tos = -1; 2184 2185 while ((c = getopt(argc, argv, TELNETD_OPTS DEBUG_OPTS)) != -1) { 2186 switch (c) { 2187 #if defined(DEBUG) 2188 case 'p': 2189 /* 2190 * note: alternative port number only used in 2191 * standalone mode. 2192 */ 2193 porttouse = atoi(optarg); 2194 standalone = 1; 2195 break; 2196 case 'e': 2197 enc_debug = 1; 2198 break; 2199 #endif /* DEBUG */ 2200 case 'a': 2201 if (strcasecmp(optarg, "none") == 0) { 2202 auth_level = 0; 2203 } else if (strcasecmp(optarg, "user") == 0) { 2204 auth_level = AUTH_USER; 2205 } else if (strcasecmp(optarg, "valid") == 0) { 2206 auth_level = AUTH_VALID; 2207 } else if (strcasecmp(optarg, "off") == 0) { 2208 auth_level = -1; 2209 negotiate_auth_krb5 = 0; 2210 } else if (strcasecmp(optarg, "debug") == 0) { 2211 auth_debug = 1; 2212 } else { 2213 syslog(LOG_ERR, 2214 "unknown authentication level specified " 2215 "with \'-a\' option (%s)", optarg); 2216 auth_level = AUTH_USER; 2217 } 2218 break; 2219 case 'X': 2220 /* disable authentication negotiation */ 2221 negotiate_auth_krb5 = 0; 2222 break; 2223 case 'R': 2224 case 'M': 2225 if (optarg != NULL) { 2226 int ret = krb5_init(); 2227 if (ret) { 2228 syslog(LOG_ERR, 2229 "Unable to use Kerberos V5 as " 2230 "requested, exiting"); 2231 exit(1); 2232 } 2233 krb5_set_default_realm(telnet_context, optarg); 2234 syslog(LOG_NOTICE, 2235 "using %s as default KRB5 realm", optarg); 2236 } 2237 break; 2238 case 'S': 2239 telnet_srvtab = (char *)strdup(optarg); 2240 break; 2241 case 'E': /* disable automatic encryption */ 2242 negotiate_encrypt = B_FALSE; 2243 break; 2244 case 'U': 2245 resolve_hostname = 1; 2246 break; 2247 case 's': 2248 if (optarg == NULL || (tos = atoi(optarg)) < 0 || 2249 tos > 255) { 2250 syslog(LOG_ERR, "telnetd: illegal tos value: " 2251 "%s\n", optarg); 2252 } else { 2253 if (tos < 0) 2254 tos = 020; 2255 } 2256 break; 2257 case 'h': 2258 show_hostinfo = 0; 2259 break; 2260 default: 2261 syslog(LOG_ERR, "telnetd: illegal cmd line option %c", 2262 c); 2263 break; 2264 } 2265 } 2266 2267 netibufsize = BUFSIZ; 2268 if (!(netibuf = (char *)malloc(netibufsize))) 2269 syslog(LOG_ERR, "netibuf malloc failed\n"); 2270 (void) memset(netibuf, 0, netibufsize); 2271 netip = netibuf; 2272 2273 #if defined(DEBUG) 2274 if (standalone) { 2275 int s, ns, foo; 2276 struct servent *sp; 2277 static struct sockaddr_in6 sin6 = { AF_INET6 }; 2278 int option = 1; 2279 2280 if (porttouse) { 2281 sin6.sin6_port = htons(porttouse); 2282 } else { 2283 sp = getservbyname("telnet", "tcp"); 2284 if (sp == 0) { 2285 (void) fprintf(stderr, 2286 "telnetd: tcp/telnet: " 2287 "unknown service\n"); 2288 exit(EXIT_FAILURE); 2289 } 2290 sin6.sin6_port = sp->s_port; 2291 } 2292 2293 s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); 2294 if (s < 0) { 2295 perror("telnetd: socket"); 2296 exit(EXIT_FAILURE); 2297 } 2298 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&option, 2299 sizeof (option)) == -1) 2300 perror("setsockopt SO_REUSEADDR"); 2301 if (bind(s, (struct sockaddr *)&sin6, sizeof (sin6)) < 0) { 2302 perror("bind"); 2303 exit(EXIT_FAILURE); 2304 } 2305 if (listen(s, 32) < 0) { 2306 perror("listen"); 2307 exit(EXIT_FAILURE); 2308 } 2309 2310 /* automatically reap all child processes */ 2311 (void) signal(SIGCHLD, SIG_IGN); 2312 2313 for (;;) { 2314 pid_t pid; 2315 2316 foo = sizeof (sin6); 2317 ns = accept(s, (struct sockaddr *)&sin6, &foo); 2318 if (ns < 0) { 2319 perror("accept"); 2320 exit(EXIT_FAILURE); 2321 } 2322 pid = fork(); 2323 if (pid == -1) { 2324 perror("fork"); 2325 exit(EXIT_FAILURE); 2326 } 2327 if (pid == 0) { 2328 (void) dup2(ns, 0); 2329 (void) close(s); 2330 (void) signal(SIGCHLD, SIG_DFL); 2331 break; 2332 } 2333 (void) close(ns); 2334 } 2335 } 2336 #endif /* defined(DEBUG) */ 2337 2338 openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON); 2339 2340 issocket = issock(0); 2341 if (!issocket) 2342 fatal(0, "stdin is not a socket file descriptor"); 2343 2344 fromlen = (socklen_t)sizeof (from); 2345 (void) memset((char *)&from, 0, sizeof (from)); 2346 if (getpeername(0, (struct sockaddr *)&from, &fromlen) 2347 < 0) { 2348 (void) fprintf(stderr, "%s: ", argv[0]); 2349 perror("getpeername"); 2350 _exit(EXIT_FAILURE); 2351 } 2352 2353 if (audit_telnet_settid(0)) { /* set terminal ID */ 2354 (void) fprintf(stderr, "%s: ", argv[0]); 2355 perror("audit"); 2356 exit(EXIT_FAILURE); 2357 } 2358 2359 if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (const char *)&on, 2360 sizeof (on)) < 0) { 2361 syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 2362 } 2363 2364 /* 2365 * Set the TOS value 2366 */ 2367 if (tos != -1 && 2368 setsockopt(0, IPPROTO_IP, IP_TOS, 2369 (char *)&tos, sizeof (tos)) < 0 && 2370 errno != ENOPROTOOPT) { 2371 syslog(LOG_ERR, "setsockopt (IP_TOS %d): %m", tos); 2372 } 2373 2374 if (setsockopt(net, SOL_SOCKET, SO_OOBINLINE, (char *)&on, 2375 sizeof (on)) < 0) { 2376 syslog(LOG_WARNING, "setsockopt (SO_OOBINLINE): %m"); 2377 } 2378 2379 /* set the default PAM service name */ 2380 (void) strcpy(pam_svc_name, "telnet"); 2381 2382 doit(0, &from); 2383 /* NOTREACHED */ 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 /*NOTREACHED*/ 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 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