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