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