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