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