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