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