1 /* $NetBSD: telnetd.c,v 1.55 2014/02/27 18:20:21 joerg Exp $ */ 2 3 /* 4 * Copyright (C) 1997 and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1989, 1993 34 * The Regents of the University of California. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 */ 60 61 #include <sys/cdefs.h> 62 #ifndef lint 63 __COPYRIGHT("@(#) Copyright (c) 1989, 1993\ 64 The Regents of the University of California. All rights reserved."); 65 #if 0 66 static char sccsid[] = "@(#)telnetd.c 8.4 (Berkeley) 5/30/95"; 67 #else 68 __RCSID("$NetBSD: telnetd.c,v 1.55 2014/02/27 18:20:21 joerg Exp $"); 69 #endif 70 #endif /* not lint */ 71 72 #include "telnetd.h" 73 #include "pathnames.h" 74 75 #include <arpa/inet.h> 76 77 #include <err.h> 78 #include <termcap.h> 79 80 #include <limits.h> 81 82 #ifdef KRB5 83 #define Authenticator k5_Authenticator 84 #include <krb5.h> 85 #undef Authenticator 86 #include <krb5/com_err.h> 87 #endif 88 89 #ifdef AUTHENTICATION 90 int auth_level = 0; 91 #endif 92 93 #if defined(AUTHENTICATION) || defined(ENCRYPTION) 94 #include <libtelnet/misc.h> 95 #endif 96 97 #ifdef SECURELOGIN 98 int require_secure_login = 0; 99 #endif 100 101 extern int require_hwpreauth; 102 #ifdef KRB5 103 extern krb5_context telnet_context; 104 #endif 105 int registerd_host_only = 0; 106 107 108 /* 109 * I/O data buffers, 110 * pointers, and counters. 111 */ 112 char ptyibuf[BUFSIZ], *ptyip = ptyibuf; 113 char ptyibuf2[BUFSIZ]; 114 115 116 int hostinfo = 1; /* do we print login banner? */ 117 118 119 static int debug = 0; 120 int keepalive = 1; 121 const char *gettyname = "default"; 122 char *progname; 123 124 void usage(void) __dead; 125 int getterminaltype(char *, size_t); 126 int getent(char *, const char *); 127 static void doit(struct sockaddr *) __dead; 128 void _gettermname(void); 129 int terminaltypeok(char *); 130 char *getstr(const char *, char **); 131 132 /* 133 * The string to pass to getopt(). We do it this way so 134 * that only the actual options that we support will be 135 * passed off to getopt(). 136 */ 137 char valid_opts[] = { 138 'd', ':', 'g', ':', 'h', 'k', 'n', 'S', ':', 'u', ':', 'U', 139 '4', '6', 140 #ifdef AUTHENTICATION 141 'a', ':', 'X', ':', 142 #endif 143 #ifdef ENCRYPTION 144 'e', ':', 145 #endif 146 #ifdef DIAGNOSTICS 147 'D', ':', 148 #endif 149 #ifdef LINEMODE 150 'l', 151 #endif 152 #ifdef SECURELOGIN 153 's', 154 #endif 155 #ifdef KRB5 156 'R', ':', 'H', 157 #endif 158 '\0' 159 }; 160 161 int family = AF_INET; 162 struct sockaddr_storage from; 163 164 int 165 main(int argc, char *argv[]) 166 { 167 socklen_t fromlen; 168 int on = 1; 169 int ch; 170 #if defined(IPPROTO_IP) && defined(IP_TOS) 171 int tos = -1; 172 #endif 173 174 pfrontp = pbackp = ptyobuf; 175 netip = netibuf; 176 nfrontp = nbackp = netobuf; 177 #ifdef ENCRYPTION 178 nclearto = 0; 179 #endif /* ENCRYPTION */ 180 181 progname = *argv; 182 183 184 while ((ch = getopt(argc, argv, valid_opts)) != -1) { 185 switch (ch) { 186 187 #ifdef AUTHENTICATION 188 case 'a': 189 /* 190 * Check for required authentication level 191 */ 192 if (strcmp(optarg, "debug") == 0) { 193 auth_debug_mode = 1; 194 } else if (strcasecmp(optarg, "none") == 0) { 195 auth_level = 0; 196 } else if (strcasecmp(optarg, "other") == 0) { 197 auth_level = AUTH_OTHER; 198 } else if (strcasecmp(optarg, "user") == 0) { 199 auth_level = AUTH_USER; 200 } else if (strcasecmp(optarg, "valid") == 0) { 201 auth_level = AUTH_VALID; 202 } else if (strcasecmp(optarg, "off") == 0) { 203 /* 204 * This hack turns off authentication 205 */ 206 auth_level = -1; 207 } else { 208 fprintf(stderr, 209 "telnetd: unknown authorization level for -a\n"); 210 } 211 break; 212 #endif /* AUTHENTICATION */ 213 214 215 case 'd': 216 if (strcmp(optarg, "ebug") == 0) { 217 debug++; 218 break; 219 } 220 usage(); 221 /* NOTREACHED */ 222 break; 223 224 #ifdef DIAGNOSTICS 225 case 'D': 226 /* 227 * Check for desired diagnostics capabilities. 228 */ 229 if (!strcmp(optarg, "report")) { 230 diagnostic |= TD_REPORT|TD_OPTIONS; 231 } else if (!strcmp(optarg, "exercise")) { 232 diagnostic |= TD_EXERCISE; 233 } else if (!strcmp(optarg, "netdata")) { 234 diagnostic |= TD_NETDATA; 235 } else if (!strcmp(optarg, "ptydata")) { 236 diagnostic |= TD_PTYDATA; 237 } else if (!strcmp(optarg, "options")) { 238 diagnostic |= TD_OPTIONS; 239 } else { 240 usage(); 241 /* NOT REACHED */ 242 } 243 break; 244 #endif /* DIAGNOSTICS */ 245 246 #ifdef ENCRYPTION 247 case 'e': 248 if (strcmp(optarg, "debug") == 0) { 249 encrypt_debug_mode = 1; 250 break; 251 } 252 usage(); 253 /* NOTREACHED */ 254 break; 255 #endif /* ENCRYPTION */ 256 257 case 'g': 258 gettyname = optarg; 259 break; 260 261 case 'h': 262 hostinfo = 0; 263 break; 264 265 #ifdef KRB5 266 case 'H': 267 { 268 require_hwpreauth = 1; 269 break; 270 } 271 #endif /* KRB5 */ 272 273 274 #ifdef LINEMODE 275 case 'l': 276 alwayslinemode = 1; 277 break; 278 #endif /* LINEMODE */ 279 280 case 'k': 281 #if defined(LINEMODE) && defined(KLUDGELINEMODE) 282 lmodetype = NO_AUTOKLUDGE; 283 #else 284 /* ignore -k option if built without kludge linemode */ 285 #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */ 286 break; 287 288 case 'n': 289 keepalive = 0; 290 break; 291 292 293 #ifdef KRB5 294 case 'R': 295 { 296 krb5_error_code retval; 297 298 if (telnet_context == 0) { 299 retval = krb5_init_context(&telnet_context); 300 if (retval) { 301 com_err("telnetd", retval, 302 "while initializing krb5"); 303 exit(1); 304 } 305 } 306 krb5_set_default_realm(telnet_context, optarg); 307 break; 308 } 309 #endif /* KRB5 */ 310 311 #ifdef SECURELOGIN 312 case 's': 313 /* Secure login required */ 314 require_secure_login = 1; 315 break; 316 #endif /* SECURELOGIN */ 317 case 'S': 318 fprintf(stderr, "%s%s\n", "TOS option unavailable; ", 319 "-S flag not supported\n"); 320 break; 321 322 case 'u': 323 fprintf(stderr, "telnetd: -u option unneeded\n"); 324 break; 325 326 case 'U': 327 registerd_host_only = 1; 328 break; 329 330 #ifdef AUTHENTICATION 331 case 'X': 332 /* 333 * Check for invalid authentication types 334 */ 335 auth_disable_name(optarg); 336 break; 337 #endif /* AUTHENTICATION */ 338 339 case '4': 340 family = AF_INET; 341 break; 342 343 case '6': 344 family = AF_INET6; 345 break; 346 347 default: 348 fprintf(stderr, "telnetd: %c: unknown option\n", ch); 349 /* FALLTHROUGH */ 350 case '?': 351 usage(); 352 /* NOTREACHED */ 353 } 354 } 355 356 argc -= optind; 357 argv += optind; 358 359 if (debug) { 360 int s, ns, error; 361 socklen_t foo; 362 const char *service = "telnet"; 363 struct addrinfo hints, *res; 364 365 if (argc > 1) { 366 usage(); 367 /* NOT REACHED */ 368 } else if (argc == 1) 369 service = *argv; 370 371 memset(&hints, 0, sizeof(hints)); 372 hints.ai_flags = AI_PASSIVE; 373 hints.ai_family = family; 374 hints.ai_socktype = SOCK_STREAM; 375 hints.ai_protocol = 0; 376 error = getaddrinfo(NULL, service, &hints, &res); 377 378 if (error) { 379 fprintf(stderr, "tcp/%s: %s\n", service, gai_strerror(error)); 380 exit(1); 381 } 382 383 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 384 if (s < 0) { 385 perror("telnetd: socket"); 386 exit(1); 387 } 388 (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 389 (char *)&on, sizeof(on)); 390 if (bind(s, res->ai_addr, res->ai_addrlen) < 0) { 391 perror("bind"); 392 exit(1); 393 } 394 if (listen(s, 1) < 0) { 395 perror("listen"); 396 exit(1); 397 } 398 foo = res->ai_addrlen; 399 ns = accept(s, res->ai_addr, &foo); 400 if (ns < 0) { 401 perror("accept"); 402 exit(1); 403 } 404 (void) dup2(ns, 0); 405 (void) close(ns); 406 (void) close(s); 407 } else if (argc > 0) { 408 usage(); 409 /* NOT REACHED */ 410 } 411 412 openlog("telnetd", LOG_PID, LOG_DAEMON); 413 fromlen = sizeof (from); 414 if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) { 415 fprintf(stderr, "%s: ", progname); 416 perror("getpeername"); 417 _exit(1); 418 } 419 if (keepalive && 420 setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, 421 (char *)&on, sizeof (on)) < 0) { 422 syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 423 } 424 425 #if defined(IPPROTO_IP) && defined(IP_TOS) 426 if (((struct sockaddr *)&from)->sa_family == AF_INET) { 427 if (tos < 0) 428 tos = 020; /* Low Delay bit */ 429 if (tos 430 && (setsockopt(0, IPPROTO_IP, IP_TOS, 431 (char *)&tos, sizeof(tos)) < 0) 432 && (errno != ENOPROTOOPT) ) 433 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); 434 } 435 #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 436 437 net = 0; 438 doit((struct sockaddr *)&from); 439 /* NOTREACHED */ 440 #ifdef __GNUC__ 441 exit(0); 442 #endif 443 } /* end of main */ 444 445 void 446 usage(void) 447 { 448 fprintf(stderr, "Usage: telnetd"); 449 #ifdef AUTHENTICATION 450 fprintf(stderr, " [-a (debug|other|user|valid|off|none)]\n\t"); 451 #endif 452 fprintf(stderr, " [-debug]"); 453 #ifdef DIAGNOSTICS 454 fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t"); 455 #endif 456 #ifdef ENCRYPTION 457 fprintf(stderr, " [-edebug]"); 458 #endif 459 fprintf(stderr, " [-h]"); 460 #if defined(LINEMODE) && defined(KLUDGELINEMODE) 461 fprintf(stderr, " [-k]"); 462 #endif 463 #ifdef LINEMODE 464 fprintf(stderr, " [-l]"); 465 #endif 466 fprintf(stderr, " [-n]"); 467 fprintf(stderr, "\n\t"); 468 #ifdef SECURELOGIN 469 fprintf(stderr, " [-s]"); 470 #endif 471 #ifdef AUTHENTICATION 472 fprintf(stderr, " [-X auth-type]"); 473 #endif 474 fprintf(stderr, " [-u utmp_hostname_length] [-U]"); 475 fprintf(stderr, " [port]\n"); 476 exit(1); 477 } 478 479 /* 480 * getterminaltype 481 * 482 * Ask the other end to send along its terminal type and speed. 483 * Output is the variable terminaltype filled in. 484 */ 485 static unsigned char ttytype_sbbuf[] = { 486 IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE 487 }; 488 489 int 490 getterminaltype(char *name, size_t l) 491 { 492 int retval = -1; 493 494 settimer(baseline); 495 #ifdef AUTHENTICATION 496 /* 497 * Handle the Authentication option before we do anything else. 498 */ 499 send_do(TELOPT_AUTHENTICATION, 1); 500 while (his_will_wont_is_changing(TELOPT_AUTHENTICATION)) 501 ttloop(); 502 if (his_state_is_will(TELOPT_AUTHENTICATION)) { 503 retval = auth_wait(name, l); 504 } 505 #endif 506 507 #ifdef ENCRYPTION 508 send_will(TELOPT_ENCRYPT, 1); 509 #endif /* ENCRYPTION */ 510 send_do(TELOPT_TTYPE, 1); 511 send_do(TELOPT_TSPEED, 1); 512 send_do(TELOPT_XDISPLOC, 1); 513 send_do(TELOPT_NEW_ENVIRON, 1); 514 send_do(TELOPT_OLD_ENVIRON, 1); 515 while ( 516 #ifdef ENCRYPTION 517 his_do_dont_is_changing(TELOPT_ENCRYPT) || 518 #endif /* ENCRYPTION */ 519 his_will_wont_is_changing(TELOPT_TTYPE) || 520 his_will_wont_is_changing(TELOPT_TSPEED) || 521 his_will_wont_is_changing(TELOPT_XDISPLOC) || 522 his_will_wont_is_changing(TELOPT_NEW_ENVIRON) || 523 his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) { 524 ttloop(); 525 } 526 if (his_state_is_will(TELOPT_TSPEED)) { 527 static unsigned char sb[] = 528 { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; 529 530 output_datalen((const char *)sb, sizeof sb); 531 DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); 532 } 533 #ifdef ENCRYPTION 534 /* 535 * Wait for the negotiation of what type of encryption we can 536 * send with. If autoencrypt is not set, this will just return. 537 */ 538 if (his_state_is_will(TELOPT_ENCRYPT)) { 539 encrypt_wait(); 540 } 541 #endif /* ENCRYPTION */ 542 if (his_state_is_will(TELOPT_XDISPLOC)) { 543 static unsigned char sb[] = 544 { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE }; 545 546 output_datalen((const char *)sb, sizeof sb); 547 DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); 548 } 549 if (his_state_is_will(TELOPT_NEW_ENVIRON)) { 550 static unsigned char sb[] = 551 { IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE }; 552 553 output_datalen((const char *)sb, sizeof sb); 554 DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); 555 } 556 else if (his_state_is_will(TELOPT_OLD_ENVIRON)) { 557 static unsigned char sb[] = 558 { IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE }; 559 560 output_datalen((const char *)sb, sizeof sb); 561 DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); 562 } 563 if (his_state_is_will(TELOPT_TTYPE)) { 564 565 output_datalen((const char *)ttytype_sbbuf, sizeof ttytype_sbbuf); 566 DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2, 567 sizeof ttytype_sbbuf - 2);); 568 } 569 if (his_state_is_will(TELOPT_TSPEED)) { 570 while (sequenceIs(tspeedsubopt, baseline)) 571 ttloop(); 572 } 573 if (his_state_is_will(TELOPT_XDISPLOC)) { 574 while (sequenceIs(xdisplocsubopt, baseline)) 575 ttloop(); 576 } 577 if (his_state_is_will(TELOPT_NEW_ENVIRON)) { 578 while (sequenceIs(environsubopt, baseline)) 579 ttloop(); 580 } 581 if (his_state_is_will(TELOPT_OLD_ENVIRON)) { 582 while (sequenceIs(oenvironsubopt, baseline)) 583 ttloop(); 584 } 585 if (his_state_is_will(TELOPT_TTYPE)) { 586 char first[256], last[256]; 587 588 while (sequenceIs(ttypesubopt, baseline)) 589 ttloop(); 590 591 /* 592 * If the other side has already disabled the option, then 593 * we have to just go with what we (might) have already gotten. 594 */ 595 if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) { 596 (void) strlcpy(first, terminaltype, sizeof(first)); 597 for(;;) { 598 /* 599 * Save the unknown name, and request the next name. 600 */ 601 (void) strlcpy(last, terminaltype, sizeof(last)); 602 _gettermname(); 603 if (terminaltypeok(terminaltype)) 604 break; 605 if ((strncmp(last, terminaltype, sizeof(last)) == 0) || 606 his_state_is_wont(TELOPT_TTYPE)) { 607 /* 608 * We've hit the end. If this is the same as 609 * the first name, just go with it. 610 */ 611 if (strncmp(first, terminaltype, sizeof(first)) == 0) 612 break; 613 /* 614 * Get the terminal name one more time, so that 615 * RFC1091 compliant telnets will cycle back to 616 * the start of the list. 617 */ 618 _gettermname(); 619 if (strncmp(first, terminaltype, sizeof(first)) != 0) { 620 (void) strlcpy(terminaltype, first, sizeof(terminaltype)); 621 } 622 break; 623 } 624 } 625 } 626 } 627 return(retval); 628 } /* end of getterminaltype */ 629 630 void 631 _gettermname(void) 632 { 633 /* 634 * If the client turned off the option, 635 * we can't send another request, so we 636 * just return. 637 */ 638 if (his_state_is_wont(TELOPT_TTYPE)) 639 return; 640 settimer(baseline); 641 output_datalen((const char *)ttytype_sbbuf, sizeof ttytype_sbbuf); 642 DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2, 643 sizeof ttytype_sbbuf - 2);); 644 while (sequenceIs(ttypesubopt, baseline)) 645 ttloop(); 646 } 647 648 int 649 terminaltypeok(char *s) 650 { 651 char buf[1024]; 652 653 /* 654 * tgetent() will return 1 if the type is known, and 655 * 0 if it is not known. If it returns -1, it couldn't 656 * open the database. But if we can't open the database, 657 * it won't help to say we failed, because we won't be 658 * able to verify anything else. So, we treat -1 like 1. 659 */ 660 if (tgetent(buf, s) == 0) 661 return(0); 662 return(1); 663 } 664 665 char *hostname; 666 char host_name[MAXHOSTNAMELEN + 1]; 667 char remote_host_name[MAXHOSTNAMELEN + 1]; 668 669 static void telnet(int, int) __dead; 670 671 /* 672 * Get a pty, scan input lines. 673 */ 674 static void 675 doit(struct sockaddr *who) 676 { 677 char *host; 678 int error; 679 int level; 680 int ptynum; 681 int flags; 682 char user_name[256]; 683 684 /* 685 * Find an available pty to use. 686 */ 687 pty = getpty(&ptynum); 688 if (pty < 0) 689 fatal(net, "All network ports in use"); 690 691 flags = registerd_host_only ? NI_NAMEREQD : 0; 692 693 /* get name of connected client */ 694 error = getnameinfo(who, who->sa_len, remote_host_name, 695 sizeof(remote_host_name), NULL, 0, flags); 696 697 if (error) { 698 fatal(net, "Couldn't resolve your address into a host name.\r\n\ 699 Please contact your net administrator"); 700 #ifdef __GNUC__ 701 host = NULL; /* XXX gcc */ 702 #endif 703 } 704 705 remote_host_name[sizeof(remote_host_name)-1] = 0; 706 host = remote_host_name; 707 708 (void)gethostname(host_name, sizeof(host_name)); 709 host_name[sizeof(host_name) - 1] = '\0'; 710 hostname = host_name; 711 712 #if defined(AUTHENTICATION) || defined(ENCRYPTION) 713 auth_encrypt_init(hostname, host, "TELNETD", 1); 714 #endif 715 716 init_env(); 717 /* 718 * get terminal type. 719 */ 720 *user_name = 0; 721 level = getterminaltype(user_name, sizeof(user_name)); 722 setenv("TERM", terminaltype[0] ? terminaltype : "network", 1); 723 724 /* 725 * Start up the login process on the slave side of the terminal 726 */ 727 startslave(host, level, user_name); 728 729 telnet(net, pty); /* begin server processing */ 730 /*NOTREACHED*/ 731 } /* end of doit */ 732 733 734 /* 735 * Main loop. Select from pty and network, and 736 * hand data to telnet receiver finite state machine. 737 */ 738 static void 739 telnet(int f, int p) 740 { 741 int on = 1; 742 #define TABBUFSIZ 512 743 char defent[TABBUFSIZ]; 744 char defstrs[TABBUFSIZ]; 745 #undef TABBUFSIZ 746 char *HE, *HN, *IF, *ptyibuf2ptr; 747 const char *IM; 748 struct pollfd set[2]; 749 750 /* 751 * Initialize the slc mapping table. 752 */ 753 get_slc_defaults(); 754 755 /* 756 * Do some tests where it is desireable to wait for a response. 757 * Rather than doing them slowly, one at a time, do them all 758 * at once. 759 */ 760 if (my_state_is_wont(TELOPT_SGA)) 761 send_will(TELOPT_SGA, 1); 762 /* 763 * Is the client side a 4.2 (NOT 4.3) system? We need to know this 764 * because 4.2 clients are unable to deal with TCP urgent data. 765 * 766 * To find out, we send out a "DO ECHO". If the remote system 767 * answers "WILL ECHO" it is probably a 4.2 client, and we note 768 * that fact ("WILL ECHO" ==> that the client will echo what 769 * WE, the server, sends it; it does NOT mean that the client will 770 * echo the terminal input). 771 */ 772 send_do(TELOPT_ECHO, 1); 773 774 #ifdef LINEMODE 775 if (his_state_is_wont(TELOPT_LINEMODE)) { 776 /* Query the peer for linemode support by trying to negotiate 777 * the linemode option. 778 */ 779 linemode = 0; 780 editmode = 0; 781 send_do(TELOPT_LINEMODE, 1); /* send do linemode */ 782 } 783 #endif /* LINEMODE */ 784 785 /* 786 * Send along a couple of other options that we wish to negotiate. 787 */ 788 send_do(TELOPT_NAWS, 1); 789 send_will(TELOPT_STATUS, 1); 790 flowmode = 1; /* default flow control state */ 791 restartany = -1; /* uninitialized... */ 792 send_do(TELOPT_LFLOW, 1); 793 794 /* 795 * Spin, waiting for a response from the DO ECHO. However, 796 * some REALLY DUMB telnets out there might not respond 797 * to the DO ECHO. So, we spin looking for NAWS, (most dumb 798 * telnets so far seem to respond with WONT for a DO that 799 * they don't understand...) because by the time we get the 800 * response, it will already have processed the DO ECHO. 801 * Kludge upon kludge. 802 */ 803 while (his_will_wont_is_changing(TELOPT_NAWS)) 804 ttloop(); 805 806 /* 807 * But... 808 * The client might have sent a WILL NAWS as part of its 809 * startup code; if so, we'll be here before we get the 810 * response to the DO ECHO. We'll make the assumption 811 * that any implementation that understands about NAWS 812 * is a modern enough implementation that it will respond 813 * to our DO ECHO request; hence we'll do another spin 814 * waiting for the ECHO option to settle down, which is 815 * what we wanted to do in the first place... 816 */ 817 if (his_want_state_is_will(TELOPT_ECHO) && 818 his_state_is_will(TELOPT_NAWS)) { 819 while (his_will_wont_is_changing(TELOPT_ECHO)) 820 ttloop(); 821 } 822 /* 823 * On the off chance that the telnet client is broken and does not 824 * respond to the DO ECHO we sent, (after all, we did send the 825 * DO NAWS negotiation after the DO ECHO, and we won't get here 826 * until a response to the DO NAWS comes back) simulate the 827 * receipt of a will echo. This will also send a WONT ECHO 828 * to the client, since we assume that the client failed to 829 * respond because it believes that it is already in DO ECHO 830 * mode, which we do not want. 831 */ 832 if (his_want_state_is_will(TELOPT_ECHO)) { 833 DIAG(TD_OPTIONS, 834 {output_data("td: simulating recv\r\n");}); 835 willoption(TELOPT_ECHO); 836 } 837 838 /* 839 * Finally, to clean things up, we turn on our echo. This 840 * will break stupid 4.2 telnets out of local terminal echo. 841 */ 842 843 if (my_state_is_wont(TELOPT_ECHO)) 844 send_will(TELOPT_ECHO, 1); 845 846 /* 847 * Turn on packet mode 848 */ 849 (void) ioctl(p, TIOCPKT, (char *)&on); 850 851 #if defined(LINEMODE) && defined(KLUDGELINEMODE) 852 /* 853 * Continuing line mode support. If client does not support 854 * real linemode, attempt to negotiate kludge linemode by sending 855 * the do timing mark sequence. 856 */ 857 if (lmodetype < REAL_LINEMODE) 858 send_do(TELOPT_TM, 1); 859 #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */ 860 861 /* 862 * Call telrcv() once to pick up anything received during 863 * terminal type negotiation, 4.2/4.3 determination, and 864 * linemode negotiation. 865 */ 866 telrcv(); 867 868 (void) ioctl(f, FIONBIO, (char *)&on); 869 (void) ioctl(p, FIONBIO, (char *)&on); 870 871 (void) setsockopt(f, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof on); 872 873 (void) signal(SIGTSTP, SIG_IGN); 874 /* 875 * Ignoring SIGTTOU keeps the kernel from blocking us 876 * in ttioct() in /sys/tty.c. 877 */ 878 (void) signal(SIGTTOU, SIG_IGN); 879 880 (void) signal(SIGCHLD, cleanup); 881 882 883 { 884 int t; 885 t = open(_PATH_TTY, O_RDWR); 886 if (t >= 0) { 887 (void) ioctl(t, TIOCNOTTY, (char *)0); 888 (void) close(t); 889 } 890 } 891 892 893 /* 894 * Show banner that getty never gave. 895 * 896 * We put the banner in the pty input buffer. This way, it 897 * gets carriage return null processing, etc., just like all 898 * other pty --> client data. 899 */ 900 901 if (getent(defent, gettyname) == 1) { 902 char *cp=defstrs; 903 904 HE = getstr("he", &cp); 905 HN = getstr("hn", &cp); 906 IM = getstr("im", &cp); 907 IF = getstr("if", &cp); 908 if (HN && *HN) 909 (void)strlcpy(host_name, HN, sizeof(host_name)); 910 if (IM == 0) 911 IM = ""; 912 } else { 913 IM = DEFAULT_IM; 914 HE = 0; 915 IF = NULL; 916 } 917 edithost(HE, host_name); 918 ptyibuf2ptr = ptyibuf2; 919 if (hostinfo) { 920 if (IF) { 921 char buf[_POSIX2_LINE_MAX]; 922 FILE *fd; 923 924 if ((fd = fopen(IF, "r")) != NULL) { 925 while (fgets(buf, sizeof(buf) - 1, fd) != NULL) 926 ptyibuf2ptr = putf(buf, ptyibuf2ptr); 927 fclose(fd); 928 } 929 } 930 if (*IM) 931 ptyibuf2ptr = putf(IM, ptyibuf2ptr); 932 } 933 934 if (pcc) 935 strncpy(ptyibuf2ptr, ptyip, pcc+1); 936 ptyip = ptyibuf2; 937 pcc = strlen(ptyip); 938 #ifdef LINEMODE 939 /* 940 * Last check to make sure all our states are correct. 941 */ 942 init_termbuf(); 943 localstat(); 944 #endif /* LINEMODE */ 945 946 DIAG(TD_REPORT, 947 {output_data("td: Entering processing loop\r\n");}); 948 949 950 set[0].fd = f; 951 set[1].fd = p; 952 for (;;) { 953 int c; 954 955 if (ncc < 0 && pcc < 0) 956 break; 957 958 /* 959 * Never look for input if there's still 960 * stuff in the corresponding output buffer 961 */ 962 set[0].events = 0; 963 set[1].events = 0; 964 if (nfrontp - nbackp || pcc > 0) 965 set[0].events |= POLLOUT; 966 else 967 set[1].events |= POLLIN; 968 if (pfrontp - pbackp || ncc > 0) 969 set[1].events |= POLLOUT; 970 else 971 set[0].events |= POLLIN; 972 if (!SYNCHing) 973 set[0].events |= POLLPRI; 974 975 if ((c = poll(set, 2, INFTIM)) < 1) { 976 if (c == -1) { 977 if (errno == EINTR) { 978 continue; 979 } 980 } 981 sleep(5); 982 continue; 983 } 984 985 /* 986 * Any urgent data? 987 */ 988 if (set[0].revents & POLLPRI) { 989 SYNCHing = 1; 990 } 991 992 /* 993 * Something to read from the network... 994 */ 995 if (set[0].revents & POLLIN) { 996 ncc = read(f, netibuf, sizeof (netibuf)); 997 if (ncc < 0 && errno == EWOULDBLOCK) 998 ncc = 0; 999 else { 1000 if (ncc <= 0) { 1001 break; 1002 } 1003 netip = netibuf; 1004 } 1005 DIAG((TD_REPORT | TD_NETDATA), 1006 {output_data("td: netread %d chars\r\n", ncc);}); 1007 DIAG(TD_NETDATA, printdata("nd", netip, ncc)); 1008 } 1009 1010 /* 1011 * Something to read from the pty... 1012 */ 1013 if (set[1].revents & POLLIN) { 1014 pcc = read(p, ptyibuf, BUFSIZ); 1015 /* 1016 * On some systems, if we try to read something 1017 * off the master side before the slave side is 1018 * opened, we get EIO. 1019 */ 1020 if (pcc < 0 && (errno == EWOULDBLOCK || 1021 errno == EAGAIN || 1022 errno == EIO)) { 1023 pcc = 0; 1024 } else { 1025 if (pcc <= 0) 1026 break; 1027 #ifdef LINEMODE 1028 /* 1029 * If ioctl from pty, pass it through net 1030 */ 1031 if (ptyibuf[0] & TIOCPKT_IOCTL) { 1032 copy_termbuf(ptyibuf+1, pcc-1); 1033 localstat(); 1034 pcc = 1; 1035 } 1036 #endif /* LINEMODE */ 1037 if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) { 1038 netclear(); /* clear buffer back */ 1039 /* 1040 * There are client telnets on some 1041 * operating systems get screwed up 1042 * royally if we send them urgent 1043 * mode data. 1044 */ 1045 output_data("%c%c", IAC, DM); 1046 neturg = nfrontp - 1; /* off by one XXX */ 1047 DIAG(TD_OPTIONS, 1048 printoption("td: send IAC", DM)); 1049 } 1050 if (his_state_is_will(TELOPT_LFLOW) && 1051 (ptyibuf[0] & 1052 (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) { 1053 int newflow = 1054 ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0; 1055 if (newflow != flowmode) { 1056 flowmode = newflow; 1057 (void) output_data( 1058 "%c%c%c%c%c%c", 1059 IAC, SB, TELOPT_LFLOW, 1060 flowmode ? LFLOW_ON 1061 : LFLOW_OFF, 1062 IAC, SE); 1063 DIAG(TD_OPTIONS, printsub('>', 1064 (unsigned char *)nfrontp - 4, 1065 4);); 1066 } 1067 } 1068 pcc--; 1069 ptyip = ptyibuf+1; 1070 } 1071 } 1072 1073 while (pcc > 0) { 1074 if ((&netobuf[BUFSIZ] - nfrontp) < 2) 1075 break; 1076 c = *ptyip++ & 0377, pcc--; 1077 if (c == IAC) 1078 output_data("%c", c); 1079 output_data("%c", c); 1080 if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) { 1081 if (pcc > 0 && ((*ptyip & 0377) == '\n')) { 1082 output_data("%c", *ptyip++ & 0377); 1083 pcc--; 1084 } else 1085 output_datalen("\0", 1); 1086 } 1087 } 1088 1089 if ((set[0].revents & POLLOUT) && (nfrontp - nbackp) > 0) 1090 netflush(); 1091 if (ncc > 0) 1092 telrcv(); 1093 if ((set[1].revents & POLLOUT) && (pfrontp - pbackp) > 0) 1094 ptyflush(); 1095 } 1096 cleanup(0); 1097 } /* end of telnet */ 1098 1099 /* 1100 * Send interrupt to process on other side of pty. 1101 * If it is in raw mode, just write NULL; 1102 * otherwise, write intr char. 1103 */ 1104 void 1105 interrupt(void) 1106 { 1107 ptyflush(); /* half-hearted */ 1108 1109 (void) ioctl(pty, TIOCSIG, (char *)SIGINT); 1110 } 1111 1112 /* 1113 * Send quit to process on other side of pty. 1114 * If it is in raw mode, just write NULL; 1115 * otherwise, write quit char. 1116 */ 1117 void 1118 sendbrk(void) 1119 { 1120 ptyflush(); /* half-hearted */ 1121 (void) ioctl(pty, TIOCSIG, (char *)SIGQUIT); 1122 } 1123 1124 void 1125 sendsusp(void) 1126 { 1127 ptyflush(); /* half-hearted */ 1128 (void) ioctl(pty, TIOCSIG, (char *)SIGTSTP); 1129 } 1130 1131 /* 1132 * When we get an AYT, if ^T is enabled, use that. Otherwise, 1133 * just send back "[Yes]". 1134 */ 1135 void 1136 recv_ayt(void) 1137 { 1138 if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) { 1139 (void) ioctl(pty, TIOCSIG, (char *)SIGINFO); 1140 return; 1141 } 1142 (void) output_data("\r\n[Yes]\r\n"); 1143 } 1144 1145 void 1146 doeof(void) 1147 { 1148 init_termbuf(); 1149 1150 #if defined(LINEMODE) && (VEOF == VMIN) 1151 if (!tty_isediting()) { 1152 extern char oldeofc; 1153 *pfrontp++ = oldeofc; 1154 return; 1155 } 1156 #endif 1157 *pfrontp++ = slctab[SLC_EOF].sptr ? 1158 (unsigned char)*slctab[SLC_EOF].sptr : '\004'; 1159 } 1160