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 return (EXIT_SUCCESS); 2384 } 2385 2386 static char *terminaltype = 0; 2387 2388 /* 2389 * ttloop 2390 * 2391 * A small subroutine to flush the network output buffer, get some data 2392 * from the network, and pass it through the telnet state machine. We 2393 * also flush the pty input buffer (by dropping its data) if it becomes 2394 * too full. 2395 */ 2396 static void 2397 ttloop(void) 2398 { 2399 if (nfrontp-nbackp) { 2400 netflush(); 2401 } 2402 read_again: 2403 ncc = read(net, netibuf, netibufsize); 2404 if (ncc < 0) { 2405 if (errno == EINTR) 2406 goto read_again; 2407 syslog(LOG_INFO, "ttloop: read: %m"); 2408 exit(EXIT_FAILURE); 2409 } else if (ncc == 0) { 2410 syslog(LOG_INFO, "ttloop: peer closed connection\n"); 2411 exit(EXIT_FAILURE); 2412 } 2413 2414 netip = netibuf; 2415 telrcv(); /* state machine */ 2416 if (ncc > 0) { 2417 pfrontp = pbackp = ptyobuf; 2418 telrcv(); 2419 } 2420 } 2421 2422 static void 2423 send_do(int option) 2424 { 2425 write_data("%c%c%c", (uchar_t)IAC, (uchar_t)DO, (uchar_t)option); 2426 } 2427 2428 static void 2429 send_will(int option) 2430 { 2431 write_data("%c%c%c", (uchar_t)IAC, (uchar_t)WILL, (uchar_t)option); 2432 } 2433 2434 static void 2435 send_wont(int option) 2436 { 2437 write_data("%c%c%c", (uchar_t)IAC, (uchar_t)WONT, (uchar_t)option); 2438 } 2439 2440 2441 /* 2442 * getauthtype 2443 * 2444 * Negotiate automatic authentication, is possible. 2445 */ 2446 static int 2447 getauthtype(char *username, int *len) 2448 { 2449 int init_status = -1; 2450 2451 init_status = krb5_init(); 2452 2453 if (auth_level == -1 || init_status != 0) { 2454 remopts[TELOPT_AUTHENTICATION] = OPT_NO; 2455 myopts[TELOPT_AUTHENTICATION] = OPT_NO; 2456 negotiate_auth_krb5 = B_FALSE; 2457 negotiate_encrypt = B_FALSE; 2458 return (AUTH_REJECT); 2459 } 2460 2461 if (init_status == 0 && auth_level != -1) { 2462 if (negotiate_auth_krb5) { 2463 /* 2464 * Negotiate Authentication FIRST 2465 */ 2466 send_do(TELOPT_AUTHENTICATION); 2467 remopts[TELOPT_AUTHENTICATION] = 2468 OPT_YES_BUT_ALWAYS_LOOK; 2469 } 2470 while (sequenceIs(authopt, getauth)) 2471 ttloop(); 2472 2473 if (remopts[TELOPT_AUTHENTICATION] == OPT_YES) { 2474 /* 2475 * Request KRB5 Mutual authentication and if that fails, 2476 * KRB5 1-way client authentication 2477 */ 2478 uchar_t sbbuf[MAXOPTLEN], *p; 2479 p = sbbuf; 2480 *p++ = (uchar_t)IAC; 2481 *p++ = (uchar_t)SB; 2482 *p++ = (uchar_t)TELOPT_AUTHENTICATION; 2483 *p++ = (uchar_t)TELQUAL_SEND; 2484 if (negotiate_auth_krb5) { 2485 *p++ = (uchar_t)AUTHTYPE_KERBEROS_V5; 2486 *p++ = (uchar_t)(AUTH_WHO_CLIENT | 2487 AUTH_HOW_MUTUAL | 2488 AUTH_ENCRYPT_ON); 2489 *p++ = (uchar_t)AUTHTYPE_KERBEROS_V5; 2490 *p++ = (uchar_t)(AUTH_WHO_CLIENT | 2491 AUTH_HOW_MUTUAL); 2492 *p++ = (uchar_t)AUTHTYPE_KERBEROS_V5; 2493 *p++ = (uchar_t)(AUTH_WHO_CLIENT| 2494 AUTH_HOW_ONE_WAY); 2495 } else { 2496 *p++ = (uchar_t)AUTHTYPE_NULL; 2497 } 2498 *p++ = (uchar_t)IAC; 2499 *p++ = (uchar_t)SE; 2500 2501 write_data_len((const char *)sbbuf, 2502 (size_t)(p - sbbuf)); 2503 netflush(); 2504 if (auth_debug) 2505 (void) fprintf(stderr, 2506 "SENT TELOPT_AUTHENTICATION " 2507 "[data]\n"); 2508 2509 /* auth_wait returns the authentication level */ 2510 /* status = auth_wait(username, len); */ 2511 while (sequenceIs(authdone, getauth)) 2512 ttloop(); 2513 /* 2514 * Now check to see if the user is valid or not 2515 */ 2516 if (authenticated == NULL || authenticated == &NoAuth) 2517 auth_status = AUTH_REJECT; 2518 else { 2519 /* 2520 * We cant be VALID until the user status is 2521 * checked. 2522 */ 2523 if (auth_status == AUTH_VALID) 2524 auth_status = AUTH_USER; 2525 2526 if (authenticated->AuthName == 2527 AUTHTYPE_KERBEROS_V5) 2528 auth_status = krb5_user_status( 2529 username, *len, auth_status); 2530 } 2531 } 2532 } 2533 return (auth_status); 2534 } 2535 2536 static void 2537 getencrtype(void) 2538 { 2539 if (krb5_privacy_allowed() && negotiate_encrypt) { 2540 if (myopts[TELOPT_ENCRYPT] != OPT_YES) { 2541 if (!sent_will_encrypt) { 2542 send_will(TELOPT_ENCRYPT); 2543 sent_will_encrypt = B_TRUE; 2544 } 2545 if (enc_debug) 2546 (void) fprintf(stderr, "SENT WILL ENCRYPT\n"); 2547 } 2548 if (remopts[TELOPT_ENCRYPT] != OPT_YES) { 2549 if (!sent_do_encrypt) { 2550 send_do(TELOPT_ENCRYPT); 2551 sent_do_encrypt = B_TRUE; 2552 remopts[TELOPT_ENCRYPT] = 2553 OPT_YES_BUT_ALWAYS_LOOK; 2554 } 2555 if (enc_debug) 2556 (void) fprintf(stderr, "SENT DO ENCRYPT\n"); 2557 } 2558 myopts[TELOPT_ENCRYPT] = OPT_YES; 2559 2560 while (sequenceIs(encropt, getencr)) 2561 ttloop(); 2562 2563 if (auth_status != AUTH_REJECT && 2564 remopts[TELOPT_ENCRYPT] == OPT_YES && 2565 myopts[TELOPT_ENCRYPT] == OPT_YES) { 2566 2567 if (sent_encrypt_support == B_FALSE) { 2568 write_data("%c%c%c%c%c%c%c", 2569 (uchar_t)IAC, 2570 (uchar_t)SB, 2571 (uchar_t)TELOPT_ENCRYPT, 2572 (uchar_t)ENCRYPT_SUPPORT, 2573 (uchar_t)TELOPT_ENCTYPE_DES_CFB64, 2574 (uchar_t)IAC, 2575 (uchar_t)SE); 2576 2577 netflush(); 2578 } 2579 /* 2580 * Now wait for a response to these messages before 2581 * continuing... 2582 * Look for TELOPT_ENCRYPT suboptions 2583 */ 2584 while (sequenceIs(encr_support, getencr)) 2585 ttloop(); 2586 } 2587 } else { 2588 /* Dont need responses to these, so dont wait for them */ 2589 settimer(encropt); 2590 remopts[TELOPT_ENCRYPT] = OPT_NO; 2591 myopts[TELOPT_ENCRYPT] = OPT_NO; 2592 } 2593 2594 } 2595 2596 /* 2597 * getterminaltype 2598 * 2599 * Ask the other end to send along its terminal type. 2600 * Output is the variable terminaltype filled in. 2601 */ 2602 static void 2603 getterminaltype(void) 2604 { 2605 /* 2606 * The remote side may have already sent this info, so 2607 * dont ask for these options if the other side already 2608 * sent the information. 2609 */ 2610 if (sequenceIs(ttypeopt, getterminal)) { 2611 send_do(TELOPT_TTYPE); 2612 remopts[TELOPT_TTYPE] = OPT_YES_BUT_ALWAYS_LOOK; 2613 } 2614 2615 if (sequenceIs(nawsopt, getterminal)) { 2616 send_do(TELOPT_NAWS); 2617 remopts[TELOPT_NAWS] = OPT_YES_BUT_ALWAYS_LOOK; 2618 } 2619 2620 if (sequenceIs(xdisplocopt, getterminal)) { 2621 send_do(TELOPT_XDISPLOC); 2622 remopts[TELOPT_XDISPLOC] = OPT_YES_BUT_ALWAYS_LOOK; 2623 } 2624 2625 if (sequenceIs(environopt, getterminal)) { 2626 send_do(TELOPT_NEW_ENVIRON); 2627 remopts[TELOPT_NEW_ENVIRON] = OPT_YES_BUT_ALWAYS_LOOK; 2628 } 2629 2630 if (sequenceIs(oenvironopt, getterminal)) { 2631 send_do(TELOPT_OLD_ENVIRON); 2632 remopts[TELOPT_OLD_ENVIRON] = OPT_YES_BUT_ALWAYS_LOOK; 2633 } 2634 2635 /* make sure encryption is started here */ 2636 while (auth_status != AUTH_REJECT && 2637 authenticated != &NoAuth && authenticated != NULL && 2638 remopts[TELOPT_ENCRYPT] == OPT_YES && 2639 encr_data.encrypt.autoflag && 2640 encr_data.encrypt.state != ENCR_STATE_OK) { 2641 if (enc_debug) 2642 (void) fprintf(stderr, "getterminaltype() forcing encrypt\n"); 2643 ttloop(); 2644 } 2645 2646 if (enc_debug) { 2647 (void) fprintf(stderr, "getterminaltype() encryption %sstarted\n", 2648 encr_data.encrypt.state == ENCR_STATE_OK ? "" : "not "); 2649 } 2650 2651 while (sequenceIs(ttypeopt, getterminal) || 2652 sequenceIs(nawsopt, getterminal) || 2653 sequenceIs(xdisplocopt, getterminal) || 2654 sequenceIs(environopt, getterminal) || 2655 sequenceIs(oenvironopt, getterminal)) { 2656 ttloop(); 2657 } 2658 2659 2660 if (remopts[TELOPT_TTYPE] == OPT_YES) { 2661 static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB, 2662 (uchar_t)TELOPT_TTYPE, (uchar_t)TELQUAL_SEND, 2663 (uchar_t)IAC, (uchar_t)SE }; 2664 2665 write_data_len((const char *)sbbuf, sizeof (sbbuf)); 2666 } 2667 if (remopts[TELOPT_XDISPLOC] == OPT_YES) { 2668 static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB, 2669 (uchar_t)TELOPT_XDISPLOC, (uchar_t)TELQUAL_SEND, 2670 (uchar_t)IAC, (uchar_t)SE }; 2671 2672 write_data_len((const char *)sbbuf, sizeof (sbbuf)); 2673 } 2674 if (remopts[TELOPT_NEW_ENVIRON] == OPT_YES) { 2675 static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB, 2676 (uchar_t)TELOPT_NEW_ENVIRON, (uchar_t)TELQUAL_SEND, 2677 (uchar_t)IAC, (uchar_t)SE }; 2678 2679 write_data_len((const char *)sbbuf, sizeof (sbbuf)); 2680 } 2681 if (remopts[TELOPT_OLD_ENVIRON] == OPT_YES) { 2682 static uchar_t sbbuf[] = { (uchar_t)IAC, (uchar_t)SB, 2683 (uchar_t)TELOPT_OLD_ENVIRON, (uchar_t)TELQUAL_SEND, 2684 (uchar_t)IAC, (uchar_t)SE }; 2685 2686 write_data_len((const char *)sbbuf, sizeof (sbbuf)); 2687 } 2688 2689 if (remopts[TELOPT_TTYPE] == OPT_YES) { 2690 while (sequenceIs(ttypesubopt, getterminal)) { 2691 ttloop(); 2692 } 2693 } 2694 if (remopts[TELOPT_XDISPLOC] == OPT_YES) { 2695 while (sequenceIs(xdisplocsubopt, getterminal)) { 2696 ttloop(); 2697 } 2698 } 2699 if (remopts[TELOPT_NEW_ENVIRON] == OPT_YES) { 2700 while (sequenceIs(environsubopt, getterminal)) { 2701 ttloop(); 2702 } 2703 } 2704 if (remopts[TELOPT_OLD_ENVIRON] == OPT_YES) { 2705 while (sequenceIs(oenvironsubopt, getterminal)) { 2706 ttloop(); 2707 } 2708 } 2709 init_neg_done = 1; 2710 } 2711 2712 pid_t pid; 2713 2714 /* 2715 * Get a pty, scan input lines. 2716 */ 2717 static void 2718 doit(int f, struct sockaddr_storage *who) 2719 { 2720 char *host; 2721 char host_name[MAXHOSTNAMELEN]; 2722 int p, t, tt; 2723 struct sgttyb b; 2724 int ptmfd; /* fd of logindmux connected to pty */ 2725 int netfd; /* fd of logindmux connected to netf */ 2726 struct stat buf; 2727 struct protocol_arg telnetp; 2728 struct strioctl telnetmod; 2729 struct envlist *env, *next; 2730 int nsize = 0; 2731 char abuf[INET6_ADDRSTRLEN]; 2732 struct sockaddr_in *sin; 2733 struct sockaddr_in6 *sin6; 2734 socklen_t wholen; 2735 char username[MAXUSERNAMELEN]; 2736 int len; 2737 uchar_t passthru; 2738 char *slavename; 2739 2740 if ((p = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) { 2741 fatalperror(f, "open /dev/ptmx", errno); 2742 } 2743 if (grantpt(p) == -1) 2744 fatal(f, "could not grant slave pty"); 2745 if (unlockpt(p) == -1) 2746 fatal(f, "could not unlock slave pty"); 2747 if ((slavename = ptsname(p)) == NULL) 2748 fatal(f, "could not enable slave pty"); 2749 (void) dup2(f, 0); 2750 if ((t = open(slavename, O_RDWR | O_NOCTTY)) == -1) 2751 fatal(f, "could not open slave pty"); 2752 if (ioctl(t, I_PUSH, "ptem") == -1) 2753 fatalperror(f, "ioctl I_PUSH ptem", errno); 2754 if (ioctl(t, I_PUSH, "ldterm") == -1) 2755 fatalperror(f, "ioctl I_PUSH ldterm", errno); 2756 if (ioctl(t, I_PUSH, "ttcompat") == -1) 2757 fatalperror(f, "ioctl I_PUSH ttcompat", errno); 2758 2759 line = slavename; 2760 2761 pty = t; 2762 2763 if (ioctl(t, TIOCGETP, &b) == -1) 2764 syslog(LOG_INFO, "ioctl TIOCGETP pty t: %m\n"); 2765 b.sg_flags = O_CRMOD|O_XTABS|O_ANYP; 2766 /* XXX - ispeed and ospeed must be non-zero */ 2767 b.sg_ispeed = B38400; 2768 b.sg_ospeed = B38400; 2769 if (ioctl(t, TIOCSETN, &b) == -1) 2770 syslog(LOG_INFO, "ioctl TIOCSETN pty t: %m\n"); 2771 if (ioctl(pty, TIOCGETP, &b) == -1) 2772 syslog(LOG_INFO, "ioctl TIOCGETP pty pty: %m\n"); 2773 b.sg_flags &= ~O_ECHO; 2774 if (ioctl(pty, TIOCSETN, &b) == -1) 2775 syslog(LOG_INFO, "ioctl TIOCSETN pty pty: %m\n"); 2776 2777 if (who->ss_family == AF_INET) { 2778 char *addrbuf = NULL; 2779 char *portbuf = NULL; 2780 2781 sin = (struct sockaddr_in *)who; 2782 wholen = sizeof (struct sockaddr_in); 2783 2784 addrbuf = (char *)malloc(wholen); 2785 if (addrbuf == NULL) 2786 fatal(f, "Cannot alloc memory for address info\n"); 2787 portbuf = (char *)malloc(sizeof (sin->sin_port)); 2788 if (portbuf == NULL) { 2789 free(addrbuf); 2790 fatal(f, "Cannot alloc memory for port info\n"); 2791 } 2792 2793 (void) memcpy(addrbuf, (const void *)&sin->sin_addr, wholen); 2794 (void) memcpy(portbuf, (const void *)&sin->sin_port, 2795 sizeof (sin->sin_port)); 2796 2797 if (rsaddr.contents != NULL) 2798 free(rsaddr.contents); 2799 2800 rsaddr.contents = (krb5_octet *)addrbuf; 2801 rsaddr.length = wholen; 2802 rsaddr.addrtype = ADDRTYPE_INET; 2803 2804 if (rsport.contents != NULL) 2805 free(rsport.contents); 2806 2807 rsport.contents = (krb5_octet *)portbuf; 2808 rsport.length = sizeof (sin->sin_port); 2809 rsport.addrtype = ADDRTYPE_IPPORT; 2810 } else if (who->ss_family == AF_INET6) { 2811 struct in_addr ipv4_addr; 2812 char *addrbuf = NULL; 2813 char *portbuf = NULL; 2814 2815 sin6 = (struct sockaddr_in6 *)who; 2816 wholen = sizeof (struct sockaddr_in6); 2817 2818 IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr, 2819 &ipv4_addr); 2820 2821 addrbuf = (char *)malloc(wholen); 2822 if (addrbuf == NULL) 2823 fatal(f, "Cannot alloc memory for address info\n"); 2824 2825 portbuf = (char *)malloc(sizeof (sin6->sin6_port)); 2826 if (portbuf == NULL) { 2827 free(addrbuf); 2828 fatal(f, "Cannot alloc memory for port info\n"); 2829 } 2830 2831 (void) memcpy((void *) addrbuf, 2832 (const void *)&ipv4_addr, 2833 wholen); 2834 /* 2835 * If we already used rsaddr.contents, free the previous 2836 * buffer. 2837 */ 2838 if (rsaddr.contents != NULL) 2839 free(rsaddr.contents); 2840 2841 rsaddr.contents = (krb5_octet *)addrbuf; 2842 rsaddr.length = sizeof (ipv4_addr); 2843 rsaddr.addrtype = ADDRTYPE_INET; 2844 2845 (void) memcpy((void *) portbuf, (const void *)&sin6->sin6_port, 2846 sizeof (sin6->sin6_port)); 2847 2848 if (rsport.contents != NULL) 2849 free(rsport.contents); 2850 2851 rsport.contents = (krb5_octet *)portbuf; 2852 rsport.length = sizeof (sin6->sin6_port); 2853 rsport.addrtype = ADDRTYPE_IPPORT; 2854 } else { 2855 syslog(LOG_ERR, "unknown address family %d\n", 2856 who->ss_family); 2857 fatal(f, "getpeername: unknown address family\n"); 2858 } 2859 2860 if (getnameinfo((const struct sockaddr *) who, wholen, host_name, 2861 sizeof (host_name), NULL, 0, 0) == 0) { 2862 host = host_name; 2863 } else { 2864 /* 2865 * If the '-U' option was given on the cmd line, we must 2866 * be able to lookup the hostname 2867 */ 2868 if (resolve_hostname) { 2869 fatal(f, "Couldn't resolve your address into a " 2870 "host name.\r\nPlease contact your net " 2871 "administrator"); 2872 } 2873 2874 if (who->ss_family == AF_INET6) { 2875 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 2876 struct in_addr ipv4_addr; 2877 2878 IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr, 2879 &ipv4_addr); 2880 host = (char *)inet_ntop(AF_INET, 2881 &ipv4_addr, abuf, sizeof (abuf)); 2882 } else { 2883 host = (char *)inet_ntop(AF_INET6, 2884 &sin6->sin6_addr, abuf, 2885 sizeof (abuf)); 2886 } 2887 } else if (who->ss_family == AF_INET) { 2888 host = (char *)inet_ntop(AF_INET, 2889 &sin->sin_addr, abuf, sizeof (abuf)); 2890 } 2891 } 2892 /* 2893 * Note that sockmod has to be removed since readstream assumes 2894 * a "raw" TPI endpoint (e.g. it uses getmsg). 2895 */ 2896 if (removemod(f, "sockmod") < 0) 2897 fatalperror(f, "couldn't remove sockmod", errno); 2898 2899 encrypt_init(); 2900 2901 /* 2902 * Push the crypto module on the stream before 'telmod' so it 2903 * can encrypt/decrypt without interfering with telmod functionality 2904 * We must push it now because many of the crypto options negotiated 2905 * initially must be saved in the crypto module (via IOCTL calls). 2906 */ 2907 if (ioctl(f, I_PUSH, "cryptmod") < 0) 2908 fatalperror(f, "ioctl I_PUSH cryptmod", errno); 2909 2910 cryptmod_fd = f; 2911 /* 2912 * gotta set the encryption clock now because it is often negotiated 2913 * immediately by the client, and if we wait till after we negotiate 2914 * auth, it will be out of whack with when the WILL/WONT ENCRYPT 2915 * option is received. 2916 */ 2917 settimer(getencr); 2918 2919 /* 2920 * get terminal type. 2921 */ 2922 username[0] = '\0'; 2923 len = sizeof (username); 2924 2925 settimer(getterminal); 2926 settimer(getauth); 2927 /* 2928 * Exchange TELOPT_AUTHENTICATE options per RFC 2941/2942 2929 */ 2930 auth_status = getauthtype(username, &len); 2931 /* 2932 * Exchange TELOPT_ENCRYPT options per RFC 2946 2933 */ 2934 getencrtype(); 2935 getterminaltype(); 2936 2937 if (ioctl(f, I_PUSH, "telmod") < 0) 2938 fatalperror(f, "ioctl I_PUSH telmod", errno); 2939 2940 /* 2941 * Make sure telmod will pass unrecognized IOCTLs to cryptmod 2942 */ 2943 passthru = 1; 2944 2945 telnetmod.ic_cmd = CRYPTPASSTHRU; 2946 telnetmod.ic_timout = -1; 2947 telnetmod.ic_len = sizeof (uchar_t); 2948 telnetmod.ic_dp = (char *)&passthru; 2949 2950 if (ioctl(f, I_STR, &telnetmod) < 0) 2951 fatal(f, "ioctl CRPASSTHRU failed\n"); 2952 2953 if (!ncc) 2954 netip = netibuf; 2955 2956 /* 2957 * readstream will do a getmsg till it receives M_PROTO type 2958 * T_DATA_REQ from telnetmodopen(). This signals that all data 2959 * in-flight before telmod was pushed has been received at the 2960 * stream head. 2961 */ 2962 while ((nsize = readstream(f, netibuf, ncc + netip - netibuf)) > 0) { 2963 ncc += nsize; 2964 } 2965 2966 if (nsize < 0) { 2967 fatalperror(f, "readstream failed\n", errno); 2968 } 2969 2970 /* 2971 * open logindmux drivers and link them with network and ptm 2972 * file descriptors. 2973 */ 2974 if ((ptmfd = open("/dev/logindmux", O_RDWR)) == -1) { 2975 fatalperror(f, "open /dev/logindmux", errno); 2976 } 2977 if ((netfd = open("/dev/logindmux", O_RDWR)) == -1) { 2978 fatalperror(f, "open /dev/logindmux", errno); 2979 } 2980 2981 if (ioctl(ptmfd, I_LINK, p) < 0) 2982 fatal(f, "ioctl I_LINK of /dev/ptmx failed\n"); 2983 if (ioctl(netfd, I_LINK, f) < 0) 2984 fatal(f, "ioctl I_LINK of tcp connection failed\n"); 2985 2986 /* 2987 * Figure out the device number of ptm's mux fd, and pass that 2988 * to the net's mux. 2989 */ 2990 if (fstat(ptmfd, &buf) < 0) { 2991 fatalperror(f, "fstat ptmfd failed", errno); 2992 } 2993 telnetp.dev = buf.st_rdev; 2994 telnetp.flag = 0; 2995 2996 telnetmod.ic_cmd = LOGDMX_IOC_QEXCHANGE; 2997 telnetmod.ic_timout = -1; 2998 telnetmod.ic_len = sizeof (struct protocol_arg); 2999 telnetmod.ic_dp = (char *)&telnetp; 3000 3001 if (ioctl(netfd, I_STR, &telnetmod) < 0) 3002 fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of netfd failed\n"); 3003 3004 /* 3005 * Figure out the device number of the net's mux fd, and pass that 3006 * to the ptm's mux. 3007 */ 3008 if (fstat(netfd, &buf) < 0) { 3009 fatalperror(f, "fstat netfd failed", errno); 3010 } 3011 telnetp.dev = buf.st_rdev; 3012 telnetp.flag = 1; 3013 3014 telnetmod.ic_cmd = LOGDMX_IOC_QEXCHANGE; 3015 telnetmod.ic_timout = -1; 3016 telnetmod.ic_len = sizeof (struct protocol_arg); 3017 telnetmod.ic_dp = (char *)&telnetp; 3018 3019 if (ioctl(ptmfd, I_STR, &telnetmod) < 0) 3020 fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of ptmfd failed\n"); 3021 3022 net = netfd; 3023 master = ptmfd; 3024 cryptmod_fd = netfd; 3025 3026 /* 3027 * Show banner that getty never gave, but 3028 * only if the user did not automatically authenticate. 3029 */ 3030 if (getenv("USER") == '\0' && auth_status < AUTH_USER) 3031 showbanner(); 3032 3033 /* 3034 * If the user automatically authenticated with Kerberos 3035 * we must set the service name that PAM will use. We 3036 * need to do it BEFORE the child fork so that 'cleanup' 3037 * in the parent can call the PAM cleanup stuff with the 3038 * same PAM service that /bin/login will use to authenticate 3039 * this session. 3040 */ 3041 if (auth_level >= 0 && auth_status >= AUTH_USER && 3042 (AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) { 3043 (void) strcpy(pam_svc_name, "ktelnet"); 3044 } 3045 /* 3046 * Request to do suppress go ahead. 3047 * 3048 * Send this before sending the TELOPT_ECHO stuff below because 3049 * some clients (MIT KRB5 telnet) have quirky 'kludge mode' support 3050 * that has them turn off local echo mode if SGA is not received first. 3051 * This also has the odd side-effect of causing the client to enable 3052 * encryption and then immediately disable it during the ECHO option 3053 * negotiations. Its just better to to SGA first now that we support 3054 * encryption. 3055 */ 3056 if (!myopts[TELOPT_SGA]) { 3057 dooption(TELOPT_SGA); 3058 } 3059 3060 /* 3061 * Pretend we got a DO ECHO from the client if we have not 3062 * yet negotiated the ECHO. 3063 */ 3064 if (!myopts[TELOPT_ECHO]) { 3065 dooption(TELOPT_ECHO); 3066 } 3067 3068 /* 3069 * Is the client side a 4.2 (NOT 4.3) system? We need to know this 3070 * because 4.2 clients are unable to deal with TCP urgent data. 3071 * 3072 * To find out, we send out a "DO ECHO". If the remote system 3073 * answers "WILL ECHO" it is probably a 4.2 client, and we note 3074 * that fact ("WILL ECHO" ==> that the client will echo what 3075 * WE, the server, sends it; it does NOT mean that the client will 3076 * echo the terminal input). 3077 */ 3078 send_do(TELOPT_ECHO); 3079 remopts[TELOPT_ECHO] = OPT_YES_BUT_ALWAYS_LOOK; 3080 3081 if ((pid = fork()) < 0) 3082 fatalperror(netfd, "fork", errno); 3083 if (pid) 3084 telnet(net, master); 3085 /* 3086 * The child process needs to be the session leader 3087 * and have the pty as its controlling tty. Thus we need 3088 * to re-open the slave side of the pty no without 3089 * the O_NOCTTY flag that we have been careful to 3090 * use up to this point. 3091 */ 3092 (void) setsid(); 3093 3094 tt = open(line, O_RDWR); 3095 if (tt < 0) 3096 fatalperror(netfd, line, errno); 3097 (void) close(netfd); 3098 (void) close(ptmfd); 3099 (void) close(f); 3100 (void) close(p); 3101 (void) close(t); 3102 if (tt != 0) 3103 (void) dup2(tt, 0); 3104 if (tt != 1) 3105 (void) dup2(tt, 1); 3106 if (tt != 2) 3107 (void) dup2(tt, 2); 3108 if (tt > 2) 3109 (void) close(tt); 3110 3111 if (terminaltype) 3112 (void) local_setenv("TERM", terminaltype+5, 1); 3113 /* 3114 * -h : pass on name of host. 3115 * WARNING: -h is accepted by login if and only if 3116 * getuid() == 0. 3117 * -p : don't clobber the environment (so terminal type stays set). 3118 */ 3119 { 3120 /* System V login expects a utmp entry to already be there */ 3121 struct utmpx ut; 3122 (void) memset((char *)&ut, 0, sizeof (ut)); 3123 (void) strncpy(ut.ut_user, ".telnet", sizeof (ut.ut_user)); 3124 (void) strncpy(ut.ut_line, line, sizeof (ut.ut_line)); 3125 ut.ut_pid = getpid(); 3126 ut.ut_id[0] = 't'; 3127 ut.ut_id[1] = (char)SC_WILDC; 3128 ut.ut_id[2] = (char)SC_WILDC; 3129 ut.ut_id[3] = (char)SC_WILDC; 3130 ut.ut_type = LOGIN_PROCESS; 3131 ut.ut_exit.e_termination = 0; 3132 ut.ut_exit.e_exit = 0; 3133 (void) time(&ut.ut_tv.tv_sec); 3134 if (makeutx(&ut) == NULL) 3135 syslog(LOG_INFO, "in.telnetd:\tmakeutx failed"); 3136 } 3137 3138 /* 3139 * Load in the cached environment variables and either 3140 * set/unset them in the environment. 3141 */ 3142 for (next = envlist_head; next; ) { 3143 env = next; 3144 if (env->delete) 3145 (void) local_unsetenv(env->name); 3146 else 3147 (void) local_setenv(env->name, env->value, 1); 3148 free(env->name); 3149 free(env->value); 3150 next = env->next; 3151 free(env); 3152 } 3153 3154 if (!username || !username[0]) 3155 auth_status = AUTH_REJECT; /* we dont know who this is */ 3156 3157 /* If the current auth status is less than the required level, exit */ 3158 if (auth_status < auth_level) { 3159 fatal(net, "Authentication failed\n"); 3160 exit(EXIT_FAILURE); 3161 } 3162 3163 /* 3164 * If AUTH_VALID (proper authentication REQUIRED and we have 3165 * a krb5_name), exec '/bin/login', make sure it uses the 3166 * correct PAM service name (pam_svc_name). If possible, 3167 * make sure the krb5 authenticated user's name (krb5_name) 3168 * is in the PAM REPOSITORY for krb5. 3169 */ 3170 if (auth_level >= 0 && 3171 (auth_status == AUTH_VALID || auth_status == AUTH_USER) && 3172 ((krb5_name != NULL) && strlen(krb5_name)) && 3173 ((AuthenticatingUser != NULL) && strlen(AuthenticatingUser))) { 3174 (void) execl(LOGIN_PROGRAM, "login", 3175 "-p", 3176 "-d", slavename, 3177 "-h", host, 3178 "-u", krb5_name, 3179 "-s", pam_svc_name, 3180 "-R", KRB5_REPOSITORY_NAME, 3181 AuthenticatingUser, 0); 3182 } else if (auth_level >= 0 && 3183 auth_status >= AUTH_USER && 3184 (((AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) || 3185 getenv("USER"))) { 3186 /* 3187 * If we only know the name but not the principal, 3188 * login will have to authenticate further. 3189 */ 3190 (void) execl(LOGIN_PROGRAM, "login", 3191 "-p", 3192 "-d", slavename, 3193 "-h", host, 3194 "-s", pam_svc_name, 3195 (AuthenticatingUser != NULL ? AuthenticatingUser : 3196 getenv("USER")), 3197 0); 3198 3199 } else /* default, no auth. info available, login does it all */ { 3200 (void) execl(LOGIN_PROGRAM, "login", 3201 "-p", "-h", host, "-d", slavename, 3202 getenv("USER"), 0); 3203 } 3204 3205 fatalperror(netfd, LOGIN_PROGRAM, errno); 3206 /*NOTREACHED*/ 3207 } 3208 3209 static void 3210 fatal(int f, char *msg) 3211 { 3212 char buf[BUFSIZ]; 3213 3214 (void) snprintf(buf, sizeof (buf), "telnetd: %s.\r\n", msg); 3215 (void) write(f, buf, strlen(buf)); 3216 exit(EXIT_FAILURE); 3217 /*NOTREACHED*/ 3218 } 3219 3220 static void 3221 fatalperror(int f, char *msg, int errnum) 3222 { 3223 char buf[BUFSIZ]; 3224 3225 (void) snprintf(buf, sizeof (buf), 3226 "%s: %s\r\n", msg, strerror(errnum)); 3227 fatal(f, buf); 3228 /*NOTREACHED*/ 3229 } 3230 3231 /* 3232 * Main loop. Select from pty and network, and 3233 * hand data to telnet receiver finite state machine 3234 * when it receives telnet protocol. Regular data 3235 * flow between pty and network takes place through 3236 * inkernel telnet streams module (telmod). 3237 */ 3238 static void 3239 telnet(int net, int master) 3240 { 3241 int on = 1; 3242 char mode; 3243 struct strioctl telnetmod; 3244 int nsize = 0; 3245 char binary_in = 0; 3246 char binary_out = 0; 3247 3248 if (ioctl(net, FIONBIO, &on) == -1) 3249 syslog(LOG_INFO, "ioctl FIONBIO net: %m\n"); 3250 if (ioctl(master, FIONBIO, &on) == -1) 3251 syslog(LOG_INFO, "ioctl FIONBIO pty p: %m\n"); 3252 (void) signal(SIGTSTP, SIG_IGN); 3253 (void) signal(SIGCHLD, (void (*)())cleanup); 3254 (void) setpgrp(); 3255 3256 /* 3257 * Call telrcv() once to pick up anything received during 3258 * terminal type negotiation. 3259 */ 3260 telrcv(); 3261 3262 netflush(); 3263 ptyflush(); 3264 3265 for (;;) { 3266 fd_set ibits, obits, xbits; 3267 int c; 3268 3269 if (ncc < 0) 3270 break; 3271 3272 FD_ZERO(&ibits); 3273 FD_ZERO(&obits); 3274 FD_ZERO(&xbits); 3275 3276 /* 3277 * If we couldn't flush all our output to the network, 3278 * keep checking for when we can. 3279 */ 3280 if (nfrontp - nbackp) 3281 FD_SET(net, &obits); 3282 /* 3283 * Never look for input if there's still 3284 * stuff in the corresponding output buffer 3285 */ 3286 if (pfrontp - pbackp) { 3287 FD_SET(master, &obits); 3288 } else { 3289 FD_SET(net, &ibits); 3290 } 3291 if (!SYNCHing) { 3292 FD_SET(net, &xbits); 3293 } 3294 3295 #define max(x, y) (((x) < (y)) ? (y) : (x)) 3296 3297 /* 3298 * make an ioctl to telnet module (net side) to send 3299 * binary mode of telnet daemon. binary_in and 3300 * binary_out are 0 if not in binary mode. 3301 */ 3302 if (binary_in != myopts[TELOPT_BINARY] || 3303 binary_out != remopts[TELOPT_BINARY]) { 3304 3305 mode = 0; 3306 if (myopts[TELOPT_BINARY] != OPT_NO) 3307 mode |= TEL_BINARY_IN; 3308 3309 if (remopts[TELOPT_BINARY] != OPT_NO) 3310 mode |= TEL_BINARY_OUT; 3311 3312 telnetmod.ic_cmd = TEL_IOC_MODE; 3313 telnetmod.ic_timout = -1; 3314 telnetmod.ic_len = 1; 3315 telnetmod.ic_dp = &mode; 3316 3317 syslog(LOG_DEBUG, "TEL_IOC_MODE binary has changed\n"); 3318 3319 if (ioctl(net, I_STR, &telnetmod) < 0) 3320 fatal(net, "ioctl TEL_IOC_MODE failed\n"); 3321 binary_in = myopts[TELOPT_BINARY]; 3322 binary_out = remopts[TELOPT_BINARY]; 3323 } 3324 if (state == TS_DATA) { 3325 if ((nfrontp == nbackp) && 3326 (pfrontp == pbackp)) { 3327 if (ioctl(net, I_NREAD, &nsize) < 0) 3328 fatalperror(net, 3329 "ioctl I_NREAD failed\n", errno); 3330 if (nsize) 3331 drainstream(nsize); 3332 3333 /* 3334 * make an ioctl to reinsert remaining data at 3335 * streamhead. After this, ioctl reenables the 3336 * telnet lower put queue. This queue was 3337 * noenabled by telnet module after sending 3338 * protocol/urgent data to telnetd. 3339 */ 3340 3341 telnetmod.ic_cmd = TEL_IOC_ENABLE; 3342 telnetmod.ic_timout = -1; 3343 if (ncc || nsize) { 3344 telnetmod.ic_len = ncc + nsize; 3345 telnetmod.ic_dp = netip; 3346 } else { 3347 telnetmod.ic_len = 0; 3348 telnetmod.ic_dp = NULL; 3349 } 3350 if (ioctl(net, I_STR, &telnetmod) < 0) 3351 fatal(net, "ioctl TEL_IOC_ENABLE \ 3352 failed\n"); 3353 3354 telmod_init_done = B_TRUE; 3355 3356 netip = netibuf; 3357 (void) memset(netibuf, 0, netibufsize); 3358 3359 ncc = 0; 3360 } 3361 } else { 3362 /* 3363 * state not changed to TS_DATA and hence, more to read 3364 * send ioctl to get one more message block. 3365 */ 3366 telnetmod.ic_cmd = TEL_IOC_GETBLK; 3367 telnetmod.ic_timout = -1; 3368 telnetmod.ic_len = 0; 3369 telnetmod.ic_dp = NULL; 3370 3371 if (ioctl(net, I_STR, &telnetmod) < 0) 3372 fatal(net, "ioctl TEL_IOC_GETBLK failed\n"); 3373 } 3374 3375 if ((c = select(max(net, master) + 1, &ibits, &obits, &xbits, 3376 (struct timeval *)0)) < 1) { 3377 if (c == -1) { 3378 if (errno == EINTR) { 3379 continue; 3380 } 3381 } 3382 (void) sleep(5); 3383 continue; 3384 } 3385 3386 /* 3387 * Any urgent data? 3388 */ 3389 if (FD_ISSET(net, &xbits)) { 3390 SYNCHing = 1; 3391 } 3392 3393 /* 3394 * Something to read from the network... 3395 */ 3396 if (FD_ISSET(net, &ibits)) { 3397 ncc = read(net, netibuf, netibufsize); 3398 if (ncc < 0 && errno == EWOULDBLOCK) 3399 ncc = 0; 3400 else { 3401 if (ncc <= 0) { 3402 break; 3403 } 3404 netip = netibuf; 3405 } 3406 } 3407 3408 if (FD_ISSET(net, &obits) && (nfrontp - nbackp) > 0) 3409 netflush(); 3410 if (ncc > 0) 3411 telrcv(); 3412 if (FD_ISSET(master, &obits) && (pfrontp - pbackp) > 0) 3413 ptyflush(); 3414 } 3415 cleanup(0); 3416 } 3417 3418 static void 3419 telrcv(void) 3420 { 3421 int c; 3422 3423 while (ncc > 0) { 3424 if ((&ptyobuf[BUFSIZ] - pfrontp) < 2) 3425 return; 3426 c = *netip & 0377; 3427 /* 3428 * Once we hit data, we want to transition back to 3429 * in-kernel processing. However, this code is shared 3430 * by getterminaltype()/ttloop() which run before the 3431 * in-kernel plumbing is available. So if we are still 3432 * processing the initial option negotiation, even TS_DATA 3433 * must be processed here. 3434 */ 3435 if (c != IAC && state == TS_DATA && init_neg_done) { 3436 break; 3437 } 3438 netip++; 3439 ncc--; 3440 switch (state) { 3441 3442 case TS_CR: 3443 state = TS_DATA; 3444 /* Strip off \n or \0 after a \r */ 3445 if ((c == 0) || (c == '\n')) { 3446 break; 3447 } 3448 /* FALLTHRU */ 3449 3450 case TS_DATA: 3451 if (c == IAC) { 3452 state = TS_IAC; 3453 break; 3454 } 3455 if (inter > 0) 3456 break; 3457 /* 3458 * We map \r\n ==> \r, since 3459 * We now map \r\n ==> \r for pragmatic reasons. 3460 * Many client implementations send \r\n when 3461 * the user hits the CarriageReturn key. 3462 * 3463 * We USED to map \r\n ==> \n, since \r\n says 3464 * that we want to be in column 1 of the next 3465 * line. 3466 */ 3467 if (c == '\r' && (myopts[TELOPT_BINARY] == OPT_NO)) { 3468 state = TS_CR; 3469 } 3470 *pfrontp++ = c; 3471 break; 3472 3473 case TS_IAC: 3474 switch (c) { 3475 3476 /* 3477 * Send the process on the pty side an 3478 * interrupt. Do this with a NULL or 3479 * interrupt char; depending on the tty mode. 3480 */ 3481 case IP: 3482 interrupt(); 3483 break; 3484 3485 case BREAK: 3486 sendbrk(); 3487 break; 3488 3489 /* 3490 * Are You There? 3491 */ 3492 case AYT: 3493 write_data_len("\r\n[Yes]\r\n", 9); 3494 break; 3495 3496 /* 3497 * Abort Output 3498 */ 3499 case AO: { 3500 struct ltchars tmpltc; 3501 3502 ptyflush(); /* half-hearted */ 3503 if (ioctl(pty, TIOCGLTC, &tmpltc) == -1) 3504 syslog(LOG_INFO, 3505 "ioctl TIOCGLTC: %m\n"); 3506 if (tmpltc.t_flushc != '\377') { 3507 *pfrontp++ = tmpltc.t_flushc; 3508 } 3509 netclear(); /* clear buffer back */ 3510 write_data("%c%c", (uchar_t)IAC, 3511 (uchar_t)DM); 3512 3513 neturg = nfrontp-1; /* off by one XXX */ 3514 netflush(); 3515 netflush(); /* XXX.sparker */ 3516 break; 3517 } 3518 3519 /* 3520 * Erase Character and 3521 * Erase Line 3522 */ 3523 case EC: 3524 case EL: { 3525 struct sgttyb b; 3526 char ch; 3527 3528 ptyflush(); /* half-hearted */ 3529 if (ioctl(pty, TIOCGETP, &b) == -1) 3530 syslog(LOG_INFO, 3531 "ioctl TIOCGETP: %m\n"); 3532 ch = (c == EC) ? 3533 b.sg_erase : b.sg_kill; 3534 if (ch != '\377') { 3535 *pfrontp++ = ch; 3536 } 3537 break; 3538 } 3539 3540 /* 3541 * Check for urgent data... 3542 */ 3543 case DM: 3544 break; 3545 3546 /* 3547 * Begin option subnegotiation... 3548 */ 3549 case SB: 3550 state = TS_SB; 3551 SB_CLEAR(); 3552 continue; 3553 3554 case WILL: 3555 state = TS_WILL; 3556 continue; 3557 3558 case WONT: 3559 state = TS_WONT; 3560 continue; 3561 3562 case DO: 3563 state = TS_DO; 3564 continue; 3565 3566 case DONT: 3567 state = TS_DONT; 3568 continue; 3569 3570 case IAC: 3571 *pfrontp++ = c; 3572 break; 3573 } 3574 state = TS_DATA; 3575 break; 3576 case TS_SB: 3577 if (c == IAC) { 3578 state = TS_SE; 3579 } else { 3580 SB_ACCUM(c); 3581 } 3582 break; 3583 case TS_SE: 3584 if (c != SE) { 3585 if (c != IAC) { 3586 SB_ACCUM((uchar_t)IAC); 3587 } 3588 SB_ACCUM(c); 3589 state = TS_SB; 3590 3591 } else { 3592 SB_TERM(); 3593 suboption(); /* handle sub-option */ 3594 state = TS_DATA; 3595 } 3596 break; 3597 3598 case TS_WILL: 3599 if (remopts[c] != OPT_YES) 3600 willoption(c); 3601 state = TS_DATA; 3602 continue; 3603 3604 case TS_WONT: 3605 if (remopts[c] != OPT_NO) 3606 wontoption(c); 3607 state = TS_DATA; 3608 continue; 3609 3610 case TS_DO: 3611 if (myopts[c] != OPT_YES) 3612 dooption(c); 3613 state = TS_DATA; 3614 continue; 3615 3616 case TS_DONT: 3617 if (myopts[c] != OPT_NO) { 3618 dontoption(c); 3619 } 3620 state = TS_DATA; 3621 continue; 3622 3623 default: 3624 syslog(LOG_ERR, "telnetd: panic state=%d\n", state); 3625 (void) printf("telnetd: panic state=%d\n", state); 3626 exit(EXIT_FAILURE); 3627 } 3628 } 3629 } 3630 3631 static void 3632 willoption(int option) 3633 { 3634 uchar_t *fmt; 3635 boolean_t send_reply = B_TRUE; 3636 3637 switch (option) { 3638 case TELOPT_BINARY: 3639 mode(O_RAW, 0); 3640 fmt = doopt; 3641 break; 3642 3643 case TELOPT_ECHO: 3644 not42 = 0; /* looks like a 4.2 system */ 3645 /* 3646 * Now, in a 4.2 system, to break them out of ECHOing 3647 * (to the terminal) mode, we need to send a "WILL ECHO". 3648 * Kludge upon kludge! 3649 */ 3650 if (myopts[TELOPT_ECHO] == OPT_YES) { 3651 dooption(TELOPT_ECHO); 3652 } 3653 fmt = dont; 3654 break; 3655 case TELOPT_TTYPE: 3656 settimer(ttypeopt); 3657 goto common; 3658 3659 case TELOPT_NAWS: 3660 settimer(nawsopt); 3661 goto common; 3662 3663 case TELOPT_XDISPLOC: 3664 settimer(xdisplocopt); 3665 goto common; 3666 3667 case TELOPT_NEW_ENVIRON: 3668 settimer(environopt); 3669 goto common; 3670 3671 case TELOPT_AUTHENTICATION: 3672 settimer(authopt); 3673 if (remopts[option] == OPT_NO || 3674 negotiate_auth_krb5 == 0) 3675 fmt = dont; 3676 else 3677 fmt = doopt; 3678 break; 3679 3680 case TELOPT_OLD_ENVIRON: 3681 settimer(oenvironopt); 3682 goto common; 3683 common: 3684 if (remopts[option] == OPT_YES_BUT_ALWAYS_LOOK) { 3685 remopts[option] = OPT_YES; 3686 return; 3687 } 3688 /*FALLTHRU*/ 3689 case TELOPT_SGA: 3690 fmt = doopt; 3691 break; 3692 3693 case TELOPT_TM: 3694 fmt = dont; 3695 break; 3696 3697 case TELOPT_ENCRYPT: 3698 settimer(encropt); /* got response to do/dont */ 3699 if (enc_debug) 3700 (void) fprintf(stderr, 3701 "RCVD IAC WILL TELOPT_ENCRYPT\n"); 3702 if (krb5_privacy_allowed()) { 3703 fmt = doopt; 3704 if (sent_do_encrypt) 3705 send_reply = B_FALSE; 3706 else 3707 sent_do_encrypt = B_TRUE; 3708 } else { 3709 fmt = dont; 3710 } 3711 break; 3712 3713 default: 3714 fmt = dont; 3715 break; 3716 } 3717 if (fmt == doopt) { 3718 remopts[option] = OPT_YES; 3719 } else { 3720 remopts[option] = OPT_NO; 3721 } 3722 if (send_reply) { 3723 write_data((const char *)fmt, option); 3724 netflush(); 3725 } 3726 } 3727 3728 static void 3729 wontoption(int option) 3730 { 3731 uchar_t *fmt; 3732 int send_reply = 1; 3733 3734 switch (option) { 3735 case TELOPT_ECHO: 3736 not42 = 1; /* doesn't seem to be a 4.2 system */ 3737 break; 3738 3739 case TELOPT_BINARY: 3740 mode(0, O_RAW); 3741 break; 3742 3743 case TELOPT_TTYPE: 3744 settimer(ttypeopt); 3745 break; 3746 3747 case TELOPT_NAWS: 3748 settimer(nawsopt); 3749 break; 3750 3751 case TELOPT_XDISPLOC: 3752 settimer(xdisplocopt); 3753 break; 3754 3755 case TELOPT_NEW_ENVIRON: 3756 settimer(environopt); 3757 break; 3758 3759 case TELOPT_OLD_ENVIRON: 3760 settimer(oenvironopt); 3761 break; 3762 3763 case TELOPT_AUTHENTICATION: 3764 settimer(authopt); 3765 auth_finished(0, AUTH_REJECT); 3766 if (auth_debug) 3767 (void) fprintf(stderr, 3768 "RCVD WONT TELOPT_AUTHENTICATE\n"); 3769 3770 remopts[option] = OPT_NO; 3771 send_reply = 0; 3772 break; 3773 3774 case TELOPT_ENCRYPT: 3775 if (enc_debug) 3776 (void) fprintf(stderr, 3777 "RCVD IAC WONT TELOPT_ENCRYPT\n"); 3778 settimer(encropt); /* got response to will/wont */ 3779 /* 3780 * Remote side cannot send encryption. No reply necessary 3781 * Treat this as if "IAC SB ENCRYPT END IAC SE" were 3782 * received (RFC 2946) and disable crypto. 3783 */ 3784 encrypt_end(TELNET_DIR_DECRYPT); 3785 send_reply = 0; 3786 break; 3787 } 3788 3789 fmt = dont; 3790 remopts[option] = OPT_NO; 3791 if (send_reply) { 3792 write_data((const char *)fmt, option); 3793 } 3794 } 3795 3796 /* 3797 * We received an "IAC DO ..." message from the client, change our state 3798 * to OPT_YES. 3799 */ 3800 static void 3801 dooption(int option) 3802 { 3803 uchar_t *fmt; 3804 boolean_t send_reply = B_TRUE; 3805 3806 switch (option) { 3807 3808 case TELOPT_TM: 3809 fmt = wont; 3810 break; 3811 3812 case TELOPT_ECHO: 3813 mode(O_ECHO|O_CRMOD, 0); 3814 fmt = will; 3815 break; 3816 3817 case TELOPT_BINARY: 3818 mode(O_RAW, 0); 3819 fmt = will; 3820 break; 3821 3822 case TELOPT_SGA: 3823 fmt = will; 3824 break; 3825 3826 case TELOPT_LOGOUT: 3827 /* 3828 * Options don't get much easier. Acknowledge the option, 3829 * and then clean up and exit. 3830 */ 3831 write_data((const char *)will, option); 3832 netflush(); 3833 cleanup(0); 3834 /*NOTREACHED*/ 3835 3836 case TELOPT_ENCRYPT: 3837 if (enc_debug) 3838 (void) fprintf(stderr, "RCVD DO TELOPT_ENCRYPT\n"); 3839 settimer(encropt); 3840 /* 3841 * We received a "DO". This indicates that the other side 3842 * wants us to encrypt our data (pending negotiatoin). 3843 * reply with "IAC WILL ENCRYPT" if we are able to send 3844 * encrypted data. 3845 */ 3846 if (krb5_privacy_allowed() && negotiate_encrypt) { 3847 fmt = will; 3848 if (sent_will_encrypt) 3849 send_reply = B_FALSE; 3850 else 3851 sent_will_encrypt = B_TRUE; 3852 /* return if we already sent "WILL ENCRYPT" */ 3853 if (myopts[option] == OPT_YES) 3854 return; 3855 } else { 3856 fmt = wont; 3857 } 3858 break; 3859 3860 case TELOPT_AUTHENTICATION: 3861 if (auth_debug) { 3862 (void) fprintf(stderr, 3863 "RCVD DO TELOPT_AUTHENTICATION\n"); 3864 } 3865 /* 3866 * RFC 2941 - only the server can send 3867 * "DO TELOPT_AUTHENTICATION". 3868 * if a server receives this, it must respond with WONT... 3869 */ 3870 fmt = wont; 3871 break; 3872 3873 default: 3874 fmt = wont; 3875 break; 3876 } 3877 if (fmt == will) { 3878 myopts[option] = OPT_YES; 3879 } else { 3880 myopts[option] = OPT_NO; 3881 } 3882 if (send_reply) { 3883 write_data((const char *)fmt, option); 3884 netflush(); 3885 } 3886 } 3887 3888 /* 3889 * We received an "IAC DONT ..." message from client. 3890 * Client does not agree with the option so act accordingly. 3891 */ 3892 static void 3893 dontoption(int option) 3894 { 3895 int send_reply = 1; 3896 switch (option) { 3897 case TELOPT_ECHO: 3898 /* 3899 * we should stop echoing, since the client side will be doing 3900 * it, but keep mapping CR since CR-LF will be mapped to it. 3901 */ 3902 mode(0, O_ECHO); 3903 break; 3904 3905 case TELOPT_ENCRYPT: 3906 if (enc_debug) 3907 (void) fprintf(stderr, "RCVD IAC DONT ENCRYPT\n"); 3908 settimer(encropt); 3909 /* 3910 * Remote side cannot receive any encrypted data, 3911 * so dont send any. No reply necessary. 3912 */ 3913 send_reply = 0; 3914 break; 3915 3916 default: 3917 break; 3918 } 3919 3920 myopts[option] = OPT_NO; 3921 3922 if (send_reply) { 3923 write_data((const char *)wont, option); 3924 } 3925 } 3926 3927 /* 3928 * suboption() 3929 * 3930 * Look at the sub-option buffer, and try to be helpful to the other 3931 * side. 3932 * 3933 */ 3934 static void 3935 suboption(void) 3936 { 3937 int subchar; 3938 3939 switch (subchar = SB_GET()) { 3940 case TELOPT_TTYPE: { /* Yaaaay! */ 3941 static char terminalname[5+41] = "TERM="; 3942 3943 settimer(ttypesubopt); 3944 3945 if (SB_GET() != TELQUAL_IS) { 3946 return; /* ??? XXX but, this is the most robust */ 3947 } 3948 3949 terminaltype = terminalname+strlen(terminalname); 3950 3951 while (terminaltype < (terminalname + sizeof (terminalname) - 3952 1) && !SB_EOF()) { 3953 int c; 3954 3955 c = SB_GET(); 3956 if (isupper(c)) { 3957 c = tolower(c); 3958 } 3959 *terminaltype++ = c; /* accumulate name */ 3960 } 3961 *terminaltype = 0; 3962 terminaltype = terminalname; 3963 break; 3964 } 3965 3966 case TELOPT_NAWS: { 3967 struct winsize ws; 3968 3969 if (SB_EOF()) { 3970 return; 3971 } 3972 ws.ws_col = SB_GET() << 8; 3973 if (SB_EOF()) { 3974 return; 3975 } 3976 ws.ws_col |= SB_GET(); 3977 if (SB_EOF()) { 3978 return; 3979 } 3980 ws.ws_row = SB_GET() << 8; 3981 if (SB_EOF()) { 3982 return; 3983 } 3984 ws.ws_row |= SB_GET(); 3985 ws.ws_xpixel = 0; ws.ws_ypixel = 0; 3986 (void) ioctl(pty, TIOCSWINSZ, &ws); 3987 settimer(nawsopt); 3988 break; 3989 } 3990 3991 case TELOPT_XDISPLOC: { 3992 if (SB_EOF() || SB_GET() != TELQUAL_IS) { 3993 return; 3994 } 3995 settimer(xdisplocsubopt); 3996 subpointer[SB_LEN()] = '\0'; 3997 if ((new_env("DISPLAY", subpointer)) == 1) 3998 perror("malloc"); 3999 break; 4000 } 4001 4002 case TELOPT_NEW_ENVIRON: 4003 case TELOPT_OLD_ENVIRON: { 4004 int c; 4005 char *cp, *varp, *valp; 4006 4007 if (SB_EOF()) 4008 return; 4009 c = SB_GET(); 4010 if (c == TELQUAL_IS) { 4011 if (subchar == TELOPT_OLD_ENVIRON) 4012 settimer(oenvironsubopt); 4013 else 4014 settimer(environsubopt); 4015 } else if (c != TELQUAL_INFO) { 4016 return; 4017 } 4018 4019 if (subchar == TELOPT_NEW_ENVIRON) { 4020 while (!SB_EOF()) { 4021 c = SB_GET(); 4022 if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR)) 4023 break; 4024 } 4025 } else 4026 { 4027 while (!SB_EOF()) { 4028 c = SB_GET(); 4029 if ((c == env_ovar) || (c == ENV_USERVAR)) 4030 break; 4031 } 4032 } 4033 4034 if (SB_EOF()) 4035 return; 4036 4037 cp = varp = (char *)subpointer; 4038 valp = 0; 4039 4040 while (!SB_EOF()) { 4041 c = SB_GET(); 4042 if (subchar == TELOPT_OLD_ENVIRON) { 4043 if (c == env_ovar) 4044 c = NEW_ENV_VAR; 4045 else if (c == env_ovalue) 4046 c = NEW_ENV_VALUE; 4047 } 4048 switch (c) { 4049 4050 case NEW_ENV_VALUE: 4051 *cp = '\0'; 4052 cp = valp = (char *)subpointer; 4053 break; 4054 4055 case NEW_ENV_VAR: 4056 case ENV_USERVAR: 4057 *cp = '\0'; 4058 if (valp) { 4059 if ((new_env(varp, valp)) == 1) { 4060 perror("malloc"); 4061 } 4062 } else { 4063 (void) del_env(varp); 4064 } 4065 cp = varp = (char *)subpointer; 4066 valp = 0; 4067 break; 4068 4069 case ENV_ESC: 4070 if (SB_EOF()) 4071 break; 4072 c = SB_GET(); 4073 /* FALL THROUGH */ 4074 default: 4075 *cp++ = c; 4076 break; 4077 } 4078 } 4079 *cp = '\0'; 4080 if (valp) { 4081 if ((new_env(varp, valp)) == 1) { 4082 perror("malloc"); 4083 } 4084 } else { 4085 (void) del_env(varp); 4086 } 4087 break; 4088 } /* end of case TELOPT_NEW_ENVIRON */ 4089 4090 case TELOPT_AUTHENTICATION: 4091 if (SB_EOF()) 4092 break; 4093 switch (SB_GET()) { 4094 case TELQUAL_SEND: 4095 case TELQUAL_REPLY: 4096 /* 4097 * These are sent server only and cannot be sent by the 4098 * client. 4099 */ 4100 break; 4101 case TELQUAL_IS: 4102 if (auth_debug) 4103 (void) fprintf(stderr, 4104 "RCVD AUTHENTICATION IS " 4105 "(%d bytes)\n", 4106 SB_LEN()); 4107 if (!auth_negotiated) 4108 auth_is((uchar_t *)subpointer, SB_LEN()); 4109 break; 4110 case TELQUAL_NAME: 4111 if (auth_debug) 4112 (void) fprintf(stderr, 4113 "RCVD AUTHENTICATION NAME " 4114 "(%d bytes)\n", 4115 SB_LEN()); 4116 if (!auth_negotiated) 4117 auth_name((uchar_t *)subpointer, SB_LEN()); 4118 break; 4119 } 4120 break; 4121 4122 case TELOPT_ENCRYPT: { 4123 int c; 4124 if (SB_EOF()) 4125 break; 4126 c = SB_GET(); 4127 #ifdef ENCRYPT_NAMES 4128 if (enc_debug) 4129 (void) fprintf(stderr, "RCVD ENCRYPT %s\n", 4130 ENCRYPT_NAME(c)); 4131 #endif /* ENCRYPT_NAMES */ 4132 switch (c) { 4133 case ENCRYPT_SUPPORT: 4134 encrypt_support(subpointer, SB_LEN()); 4135 break; 4136 case ENCRYPT_IS: 4137 encrypt_is((uchar_t *)subpointer, SB_LEN()); 4138 break; 4139 case ENCRYPT_REPLY: 4140 (void) encrypt_reply(subpointer, SB_LEN()); 4141 break; 4142 case ENCRYPT_START: 4143 encrypt_start(); 4144 break; 4145 case ENCRYPT_END: 4146 encrypt_end(TELNET_DIR_DECRYPT); 4147 break; 4148 case ENCRYPT_REQSTART: 4149 encrypt_request_start(); 4150 break; 4151 case ENCRYPT_REQEND: 4152 /* 4153 * We can always send an REQEND so that we cannot 4154 * get stuck encrypting. We should only get this 4155 * if we have been able to get in the correct mode 4156 * anyhow. 4157 */ 4158 encrypt_request_end(); 4159 break; 4160 case ENCRYPT_ENC_KEYID: 4161 encrypt_enc_keyid(subpointer, SB_LEN()); 4162 break; 4163 case ENCRYPT_DEC_KEYID: 4164 encrypt_dec_keyid(subpointer, SB_LEN()); 4165 break; 4166 default: 4167 break; 4168 } 4169 } 4170 break; 4171 4172 default: 4173 break; 4174 } 4175 } 4176 4177 static void 4178 mode(int on, int off) 4179 { 4180 struct termios tios; 4181 4182 ptyflush(); 4183 if (tcgetattr(pty, &tios) < 0) 4184 syslog(LOG_INFO, "tcgetattr: %m\n"); 4185 4186 if (on & O_RAW) { 4187 tios.c_cflag |= CS8; 4188 tios.c_iflag &= ~IUCLC; 4189 tios.c_lflag &= ~(XCASE|IEXTEN); 4190 } 4191 if (off & O_RAW) { 4192 if ((tios.c_cflag & PARENB) != 0) 4193 tios.c_cflag &= ~CS8; 4194 tios.c_lflag |= IEXTEN; 4195 } 4196 4197 if (on & O_ECHO) 4198 tios.c_lflag |= ECHO; 4199 if (off & O_ECHO) 4200 tios.c_lflag &= ~ECHO; 4201 4202 if (on & O_CRMOD) { 4203 tios.c_iflag |= ICRNL; 4204 tios.c_oflag |= ONLCR; 4205 } 4206 /* 4207 * Because "O_CRMOD" will never be set in "off" we don't have to 4208 * handle this case here. 4209 */ 4210 4211 if (tcsetattr(pty, TCSANOW, &tios) < 0) 4212 syslog(LOG_INFO, "tcsetattr: %m\n"); 4213 } 4214 4215 /* 4216 * Send interrupt to process on other side of pty. 4217 * If it is in raw mode, just write NULL; 4218 * otherwise, write intr char. 4219 */ 4220 static void 4221 interrupt(void) 4222 { 4223 struct sgttyb b; 4224 struct tchars tchars; 4225 4226 ptyflush(); /* half-hearted */ 4227 if (ioctl(pty, TIOCGETP, &b) == -1) 4228 syslog(LOG_INFO, "ioctl TIOCGETP: %m\n"); 4229 if (b.sg_flags & O_RAW) { 4230 *pfrontp++ = '\0'; 4231 return; 4232 } 4233 *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ? 4234 '\177' : tchars.t_intrc; 4235 } 4236 4237 /* 4238 * Send quit to process on other side of pty. 4239 * If it is in raw mode, just write NULL; 4240 * otherwise, write quit char. 4241 */ 4242 static void 4243 sendbrk(void) 4244 { 4245 struct sgttyb b; 4246 struct tchars tchars; 4247 4248 ptyflush(); /* half-hearted */ 4249 (void) ioctl(pty, TIOCGETP, &b); 4250 if (b.sg_flags & O_RAW) { 4251 *pfrontp++ = '\0'; 4252 return; 4253 } 4254 *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ? 4255 '\034' : tchars.t_quitc; 4256 } 4257 4258 static void 4259 ptyflush(void) 4260 { 4261 int n; 4262 4263 if ((n = pfrontp - pbackp) > 0) 4264 n = write(master, pbackp, n); 4265 if (n < 0) 4266 return; 4267 pbackp += n; 4268 if (pbackp == pfrontp) 4269 pbackp = pfrontp = ptyobuf; 4270 } 4271 4272 /* 4273 * nextitem() 4274 * 4275 * Return the address of the next "item" in the TELNET data 4276 * stream. This will be the address of the next character if 4277 * the current address is a user data character, or it will 4278 * be the address of the character following the TELNET command 4279 * if the current address is a TELNET IAC ("I Am a Command") 4280 * character. 4281 */ 4282 4283 static char * 4284 nextitem(char *current) 4285 { 4286 if ((*current&0xff) != IAC) { 4287 return (current+1); 4288 } 4289 switch (*(current+1)&0xff) { 4290 case DO: 4291 case DONT: 4292 case WILL: 4293 case WONT: 4294 return (current+3); 4295 case SB: /* loop forever looking for the SE */ 4296 { 4297 char *look = current+2; 4298 4299 for (;;) { 4300 if ((*look++&0xff) == IAC) { 4301 if ((*look++&0xff) == SE) { 4302 return (look); 4303 } 4304 } 4305 } 4306 } 4307 default: 4308 return (current+2); 4309 } 4310 } 4311 4312 4313 /* 4314 * netclear() 4315 * 4316 * We are about to do a TELNET SYNCH operation. Clear 4317 * the path to the network. 4318 * 4319 * Things are a bit tricky since we may have sent the first 4320 * byte or so of a previous TELNET command into the network. 4321 * So, we have to scan the network buffer from the beginning 4322 * until we are up to where we want to be. 4323 * 4324 * A side effect of what we do, just to keep things 4325 * simple, is to clear the urgent data pointer. The principal 4326 * caller should be setting the urgent data pointer AFTER calling 4327 * us in any case. 4328 */ 4329 static void 4330 netclear(void) 4331 { 4332 char *thisitem, *next; 4333 char *good; 4334 #define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \ 4335 ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL)) 4336 4337 thisitem = netobuf; 4338 4339 while ((next = nextitem(thisitem)) <= nbackp) { 4340 thisitem = next; 4341 } 4342 4343 /* Now, thisitem is first before/at boundary. */ 4344 4345 good = netobuf; /* where the good bytes go */ 4346 4347 while (nfrontp > thisitem) { 4348 if (wewant(thisitem)) { 4349 int length; 4350 4351 next = thisitem; 4352 do { 4353 next = nextitem(next); 4354 } while (wewant(next) && (nfrontp > next)); 4355 length = next-thisitem; 4356 (void) memmove(good, thisitem, length); 4357 good += length; 4358 thisitem = next; 4359 } else { 4360 thisitem = nextitem(thisitem); 4361 } 4362 } 4363 4364 nbackp = netobuf; 4365 nfrontp = good; /* next byte to be sent */ 4366 neturg = 0; 4367 } 4368 4369 4370 /* 4371 * netflush 4372 * Send as much data as possible to the network, 4373 * handling requests for urgent data. 4374 */ 4375 static void 4376 netflush(void) 4377 { 4378 int n; 4379 4380 if ((n = nfrontp - nbackp) > 0) { 4381 /* 4382 * if no urgent data, or if the other side appears to be an 4383 * old 4.2 client (and thus unable to survive TCP urgent data), 4384 * write the entire buffer in non-OOB mode. 4385 */ 4386 if ((neturg == 0) || (not42 == 0)) { 4387 n = write(net, nbackp, n); /* normal write */ 4388 } else { 4389 n = neturg - nbackp; 4390 /* 4391 * In 4.2 (and 4.3) systems, there is some question 4392 * about what byte in a sendOOB operation is the "OOB" 4393 * data. To make ourselves compatible, we only send ONE 4394 * byte out of band, the one WE THINK should be OOB 4395 * (though we really have more the TCP philosophy of 4396 * urgent data rather than the Unix philosophy of OOB 4397 * data). 4398 */ 4399 if (n > 1) { 4400 /* send URGENT all by itself */ 4401 n = write(net, nbackp, n-1); 4402 } else { 4403 /* URGENT data */ 4404 n = send_oob(net, nbackp, n); 4405 } 4406 } 4407 } 4408 if (n < 0) { 4409 if (errno == EWOULDBLOCK) 4410 return; 4411 /* should blow this guy away... */ 4412 return; 4413 } 4414 4415 nbackp += n; 4416 4417 if (nbackp >= neturg) { 4418 neturg = 0; 4419 } 4420 if (nbackp == nfrontp) { 4421 nbackp = nfrontp = netobuf; 4422 } 4423 } 4424 4425 /* ARGSUSED */ 4426 static void 4427 cleanup(int signum) 4428 { 4429 /* 4430 * If the TEL_IOC_ENABLE ioctl hasn't completed, then we need to 4431 * handle closing differently. We close "net" first and then 4432 * "master" in that order. We do close(net) first because 4433 * we have no other way to disconnect forwarding between the network 4434 * and master. So by issuing the close()'s we ensure that no further 4435 * data rises from TCP. A more complex fix would be adding proper 4436 * support for throwing a "stop" switch for forwarding data between 4437 * logindmux peers. It's possible to block in the close of the tty 4438 * while the network still receives data and the telmod module is 4439 * TEL_STOPPED. A denial-of-service attack generates this case, 4440 * see 4102102. 4441 */ 4442 4443 if (!telmod_init_done) { 4444 (void) close(net); 4445 (void) close(master); 4446 } 4447 rmut(); 4448 4449 exit(EXIT_FAILURE); 4450 } 4451 4452 static void 4453 rmut(void) 4454 { 4455 pam_handle_t *pamh; 4456 struct utmpx *up; 4457 char user[sizeof (up->ut_user) + 1]; 4458 char ttyn[sizeof (up->ut_line) + 1]; 4459 char rhost[sizeof (up->ut_host) + 1]; 4460 4461 /* while cleaning up don't allow disruption */ 4462 (void) signal(SIGCHLD, SIG_IGN); 4463 4464 setutxent(); 4465 while (up = getutxent()) { 4466 if (up->ut_pid == pid) { 4467 if (up->ut_type == DEAD_PROCESS) { 4468 /* 4469 * Cleaned up elsewhere. 4470 */ 4471 break; 4472 } 4473 4474 /* 4475 * call pam_close_session if login changed 4476 * the utmpx user entry from type LOGIN_PROCESS 4477 * to type USER_PROCESS, which happens 4478 * after pam_open_session is called. 4479 */ 4480 if (up->ut_type == USER_PROCESS) { 4481 (void) strlcpy(user, up->ut_user, 4482 sizeof (user)); 4483 (void) strlcpy(ttyn, up->ut_line, 4484 sizeof (ttyn)); 4485 (void) strlcpy(rhost, up->ut_host, 4486 sizeof (rhost)); 4487 if ((pam_start("telnet", user, NULL, &pamh)) == 4488 PAM_SUCCESS) { 4489 (void) pam_set_item(pamh, PAM_TTY, 4490 ttyn); 4491 (void) pam_set_item(pamh, PAM_RHOST, 4492 rhost); 4493 (void) pam_close_session(pamh, 0); 4494 (void) pam_end(pamh, PAM_SUCCESS); 4495 } 4496 } 4497 4498 up->ut_type = DEAD_PROCESS; 4499 up->ut_exit.e_termination = WTERMSIG(0); 4500 up->ut_exit.e_exit = WEXITSTATUS(0); 4501 (void) time(&up->ut_tv.tv_sec); 4502 4503 if (modutx(up) == NULL) { 4504 /* 4505 * Since modutx failed we'll 4506 * write out the new entry 4507 * ourselves. 4508 */ 4509 (void) pututxline(up); 4510 updwtmpx("wtmpx", up); 4511 } 4512 break; 4513 } 4514 } 4515 4516 endutxent(); 4517 4518 (void) signal(SIGCHLD, (void (*)())cleanup); 4519 } 4520 4521 static int 4522 readstream(int fd, char *buf, int offset) 4523 { 4524 struct strbuf ctlbuf, datbuf; 4525 union T_primitives tpi; 4526 int ret = 0; 4527 int flags = 0; 4528 int bytes_avail, count; 4529 4530 (void) memset((char *)&ctlbuf, 0, sizeof (ctlbuf)); 4531 (void) memset((char *)&datbuf, 0, sizeof (datbuf)); 4532 4533 ctlbuf.buf = (char *)&tpi; 4534 ctlbuf.maxlen = sizeof (tpi); 4535 4536 if (ioctl(fd, I_NREAD, &bytes_avail) < 0) { 4537 syslog(LOG_ERR, "I_NREAD returned error %m"); 4538 return (-1); 4539 } 4540 if (bytes_avail > netibufsize - offset) { 4541 count = netip - netibuf; 4542 netibuf = (char *)realloc(netibuf, 4543 (unsigned)netibufsize + bytes_avail); 4544 if (netibuf == NULL) { 4545 fatal(net, "netibuf realloc failed\n"); 4546 } 4547 netibufsize += bytes_avail; 4548 netip = netibuf + count; 4549 buf = netibuf; 4550 } 4551 datbuf.buf = buf + offset; 4552 datbuf.maxlen = netibufsize; 4553 ret = getmsg(fd, &ctlbuf, &datbuf, &flags); 4554 if (ret < 0) { 4555 syslog(LOG_ERR, "getmsg returned -1, errno %d\n", 4556 errno); 4557 return (-1); 4558 } 4559 if (ctlbuf.len <= 0) { 4560 return (datbuf.len); 4561 } 4562 4563 if (tpi.type == T_DATA_REQ) { 4564 return (0); 4565 } 4566 4567 if ((tpi.type == T_ORDREL_IND) || (tpi.type == T_DISCON_IND)) 4568 cleanup(0); 4569 fatal(fd, "no data or protocol element recognized"); 4570 return (0); 4571 } 4572 4573 static void 4574 drainstream(int size) 4575 { 4576 int nbytes; 4577 int tsize; 4578 4579 tsize = netip - netibuf; 4580 4581 if ((tsize + ncc + size) > netibufsize) { 4582 if (!(netibuf = (char *)realloc(netibuf, 4583 (unsigned)tsize + ncc + size))) 4584 fatalperror(net, "netibuf realloc failed\n", errno); 4585 netibufsize = tsize + ncc + size; 4586 4587 netip = netibuf + tsize; 4588 } 4589 4590 if ((nbytes = read(net, (char *)netip + ncc, size)) != size) 4591 syslog(LOG_ERR, "read %d bytes\n", nbytes); 4592 } 4593 4594 /* 4595 * TPI style replacement for socket send() primitive, so we don't require 4596 * sockmod to be on the stream. 4597 */ 4598 static int 4599 send_oob(int fd, char *ptr, int count) 4600 { 4601 struct T_exdata_req exd_req; 4602 struct strbuf hdr, dat; 4603 int ret; 4604 4605 exd_req.PRIM_type = T_EXDATA_REQ; 4606 exd_req.MORE_flag = 0; 4607 4608 hdr.buf = (char *)&exd_req; 4609 hdr.len = sizeof (exd_req); 4610 4611 dat.buf = ptr; 4612 dat.len = count; 4613 4614 ret = putmsg(fd, &hdr, &dat, 0); 4615 if (ret == 0) { 4616 ret = count; 4617 } 4618 return (ret); 4619 } 4620 4621 4622 /* 4623 * local_setenv -- 4624 * Set the value of the environmental variable "name" to be 4625 * "value". If rewrite is set, replace any current value. 4626 */ 4627 static int 4628 local_setenv(const char *name, const char *value, int rewrite) 4629 { 4630 static int alloced; /* if allocated space before */ 4631 char *c; 4632 int l_value, offset; 4633 4634 /* 4635 * Do not allow environment variables which begin with LD_ to be 4636 * inserted into the environment. While normally the dynamic linker 4637 * protects the login program, that is based on the assumption hostile 4638 * invocation of login are from non-root users. However, since telnetd 4639 * runs as root, this cannot be utilized. So instead we simply 4640 * prevent LD_* from being inserted into the environment. 4641 * This also applies to other environment variables that 4642 * are to be ignored in setugid apps. 4643 * Note that at this point name can contain '='! 4644 * Also, do not allow TTYPROMPT to be passed along here. 4645 */ 4646 if (strncmp(name, "LD_", 3) == 0 || 4647 strncmp(name, "NLSPATH", 7) == 0 || 4648 (strncmp(name, "TTYPROMPT", 9) == 0 && 4649 (name[9] == '\0' || name[9] == '='))) { 4650 return (-1); 4651 } 4652 if (*value == '=') /* no `=' in value */ 4653 ++value; 4654 l_value = strlen(value); 4655 if ((c = __findenv(name, &offset))) { /* find if already exists */ 4656 if (!rewrite) 4657 return (0); 4658 if ((int)strlen(c) >= l_value) { /* old larger; copy over */ 4659 while (*c++ = *value++); 4660 return (0); 4661 } 4662 } else { /* create new slot */ 4663 int cnt; 4664 char **p; 4665 4666 for (p = environ, cnt = 0; *p; ++p, ++cnt); 4667 if (alloced) { /* just increase size */ 4668 environ = (char **)realloc((char *)environ, 4669 (size_t)(sizeof (char *) * (cnt + 2))); 4670 if (!environ) 4671 return (-1); 4672 } else { /* get new space */ 4673 alloced = 1; /* copy old entries into it */ 4674 p = (char **)malloc((size_t)(sizeof (char *)* 4675 (cnt + 2))); 4676 if (!p) 4677 return (-1); 4678 (void) memcpy(p, environ, cnt * sizeof (char *)); 4679 environ = p; 4680 } 4681 environ[cnt + 1] = NULL; 4682 offset = cnt; 4683 } 4684 for (c = (char *)name; *c && *c != '='; ++c); /* no `=' in name */ 4685 if (!(environ[offset] = /* name + `=' + value */ 4686 malloc((size_t)((int)(c - name) + l_value + 2)))) 4687 return (-1); 4688 for (c = environ[offset]; ((*c = *name++) != 0) && (*c != '='); ++c); 4689 for (*c++ = '='; *c++ = *value++; ); 4690 return (0); 4691 } 4692 4693 /* 4694 * local_unsetenv(name) -- 4695 * Delete environmental variable "name". 4696 */ 4697 static void 4698 local_unsetenv(const char *name) 4699 { 4700 char **p; 4701 int offset; 4702 4703 while (__findenv(name, &offset)) /* if set multiple times */ 4704 for (p = &environ[offset]; ; ++p) 4705 if ((*p = *(p + 1)) == 0) 4706 break; 4707 } 4708 4709 /* 4710 * __findenv -- 4711 * Returns pointer to value associated with name, if any, else NULL. 4712 * Sets offset to be the offset of the name/value combination in the 4713 * environmental array, for use by local_setenv() and local_unsetenv(). 4714 * Explicitly removes '=' in argument name. 4715 */ 4716 static char * 4717 __findenv(const char *name, int *offset) 4718 { 4719 extern char **environ; 4720 int len; 4721 const char *np; 4722 char **p, *c; 4723 4724 if (name == NULL || environ == NULL) 4725 return (NULL); 4726 for (np = name; *np && *np != '='; ++np) 4727 continue; 4728 len = np - name; 4729 for (p = environ; (c = *p) != NULL; ++p) 4730 if (strncmp(c, name, len) == 0 && c[len] == '=') { 4731 *offset = p - environ; 4732 return (c + len + 1); 4733 } 4734 return (NULL); 4735 } 4736 4737 static void 4738 showbanner(void) 4739 { 4740 char *cp; 4741 char evalbuf[BUFSIZ]; 4742 4743 if (defopen(defaultfile) == 0) { 4744 int flags; 4745 4746 /* ignore case */ 4747 flags = defcntl(DC_GETFLAGS, 0); 4748 TURNOFF(flags, DC_CASE); 4749 defcntl(DC_SETFLAGS, flags); 4750 if (cp = defread(bannervar)) { 4751 FILE *fp; 4752 4753 if (strlen(cp) + strlen("eval echo '") + strlen("'\n") 4754 + 1 < sizeof (evalbuf)) { 4755 (void) strlcpy(evalbuf, "eval echo '", 4756 sizeof (evalbuf)); 4757 (void) strlcat(evalbuf, cp, sizeof (evalbuf)); 4758 (void) strlcat(evalbuf, "'\n", 4759 sizeof (evalbuf)); 4760 4761 if (fp = popen(evalbuf, "r")) { 4762 char buf[BUFSIZ]; 4763 size_t size; 4764 4765 /* 4766 * Pipe I/O atomicity guarantees we 4767 * need only one read. 4768 */ 4769 if ((size = fread(buf, 1, 4770 sizeof (buf) - 1, 4771 fp)) != 0) { 4772 char *p; 4773 buf[size] = '\0'; 4774 p = strrchr(buf, '\n'); 4775 if (p != NULL) 4776 *p = '\0'; 4777 if (strlen(buf)) { 4778 map_banner(buf); 4779 netflush(); 4780 } 4781 } 4782 (void) pclose(fp); 4783 /* close default file */ 4784 (void) defopen(NULL); 4785 return; 4786 } 4787 } 4788 } 4789 (void) defopen(NULL); /* close default file */ 4790 } 4791 4792 defbanner(); 4793 netflush(); 4794 } 4795 4796 static void 4797 map_banner(char *p) 4798 { 4799 char *q; 4800 4801 /* 4802 * Map the banner: "\n" -> "\r\n" and "\r" -> "\r\0" 4803 */ 4804 for (q = nfrontp; p && *p && q < nfrontp + sizeof (netobuf) - 1; ) 4805 if (*p == '\n') { 4806 *q++ = '\r'; 4807 *q++ = '\n'; 4808 p++; 4809 } else if (*p == '\r') { 4810 *q++ = '\r'; 4811 *q++ = '\0'; 4812 p++; 4813 } else 4814 *q++ = *p++; 4815 4816 nfrontp += q - netobuf; 4817 } 4818 4819 /* 4820 * Show banner that getty never gave. By default, this is `uname -sr`. 4821 * 4822 * The banner includes some null's (for TELNET CR disambiguation), 4823 * so we have to be somewhat complicated. 4824 */ 4825 static void 4826 defbanner(void) 4827 { 4828 struct utsname u; 4829 4830 /* 4831 * Dont show this if the '-h' option was present 4832 */ 4833 if (!show_hostinfo) 4834 return; 4835 4836 if (uname(&u) == -1) 4837 return; 4838 4839 write_data_len((const char *) BANNER1, sizeof (BANNER1) - 1); 4840 write_data_len(u.sysname, strlen(u.sysname)); 4841 write_data_len(" ", 1); 4842 write_data_len(u.release, strlen(u.release)); 4843 write_data_len((const char *)BANNER2, sizeof (BANNER2) - 1); 4844 } 4845 4846 /* 4847 * Verify that the named module is at the top of the stream 4848 * and then pop it off. 4849 */ 4850 static int 4851 removemod(int f, char *modname) 4852 { 4853 char topmodname[BUFSIZ]; 4854 4855 if (ioctl(f, I_LOOK, topmodname) < 0) 4856 return (-1); 4857 if (strcmp(modname, topmodname) != 0) { 4858 errno = ENXIO; 4859 return (-1); 4860 } 4861 if (ioctl(f, I_POP, 0) < 0) 4862 return (-1); 4863 return (0); 4864 } 4865 4866 static void 4867 write_data(const char *format, ...) 4868 { 4869 va_list args; 4870 int len; 4871 char argp[BUFSIZ]; 4872 4873 va_start(args, format); 4874 4875 if ((len = vsnprintf(argp, sizeof (argp), format, args)) == -1) 4876 return; 4877 4878 write_data_len(argp, len); 4879 va_end(args); 4880 } 4881 4882 static void 4883 write_data_len(const char *buf, int len) 4884 { 4885 int remaining, copied; 4886 4887 remaining = BUFSIZ - (nfrontp - netobuf); 4888 while (len > 0) { 4889 /* 4890 * If there's not enough space in netobuf then 4891 * try to make some. 4892 */ 4893 if ((len > BUFSIZ ? BUFSIZ : len) > remaining) { 4894 netflush(); 4895 remaining = BUFSIZ - (nfrontp - netobuf); 4896 } 4897 /* Copy as much as we can */ 4898 copied = remaining > len ? len : remaining; 4899 (void) memmove(nfrontp, buf, copied); 4900 nfrontp += copied; 4901 len -= copied; 4902 remaining -= copied; 4903 buf += copied; 4904 } 4905 } 4906