1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "telnetd.h" 35 36 RCSID("$Id$"); 37 38 unsigned char doopt[] = { IAC, DO, '%', 'c', 0 }; 39 unsigned char dont[] = { IAC, DONT, '%', 'c', 0 }; 40 unsigned char will[] = { IAC, WILL, '%', 'c', 0 }; 41 unsigned char wont[] = { IAC, WONT, '%', 'c', 0 }; 42 int not42 = 1; 43 44 /* 45 * Buffer for sub-options, and macros 46 * for suboptions buffer manipulations 47 */ 48 unsigned char subbuffer[1024*64], *subpointer= subbuffer, *subend= subbuffer; 49 50 #define SB_CLEAR() subpointer = subbuffer 51 #define SB_TERM() { subend = subpointer; SB_CLEAR(); } 52 #define SB_ACCUM(c) if (subpointer < (subbuffer+sizeof subbuffer)) { \ 53 *subpointer++ = (c); \ 54 } 55 #define SB_GET() ((*subpointer++)&0xff) 56 #define SB_EOF() (subpointer >= subend) 57 #define SB_LEN() (subend - subpointer) 58 59 #ifdef ENV_HACK 60 unsigned char *subsave; 61 #define SB_SAVE() subsave = subpointer; 62 #define SB_RESTORE() subpointer = subsave; 63 #endif 64 65 66 /* 67 * State for recv fsm 68 */ 69 #define TS_DATA 0 /* base state */ 70 #define TS_IAC 1 /* look for double IAC's */ 71 #define TS_CR 2 /* CR-LF ->'s CR */ 72 #define TS_SB 3 /* throw away begin's... */ 73 #define TS_SE 4 /* ...end's (suboption negotiation) */ 74 #define TS_WILL 5 /* will option negotiation */ 75 #define TS_WONT 6 /* wont -''- */ 76 #define TS_DO 7 /* do -''- */ 77 #define TS_DONT 8 /* dont -''- */ 78 79 void 80 telrcv(void) 81 { 82 int c; 83 static int state = TS_DATA; 84 85 while (ncc > 0) { 86 if ((&ptyobuf[BUFSIZ] - pfrontp) < 2) 87 break; 88 c = *netip++ & 0377, ncc--; 89 #ifdef ENCRYPTION 90 if (decrypt_input) 91 c = (*decrypt_input)(c); 92 #endif 93 switch (state) { 94 95 case TS_CR: 96 state = TS_DATA; 97 /* Strip off \n or \0 after a \r */ 98 if ((c == 0) || (c == '\n')) { 99 break; 100 } 101 /* FALL THROUGH */ 102 103 case TS_DATA: 104 if (c == IAC) { 105 state = TS_IAC; 106 break; 107 } 108 /* 109 * We now map \r\n ==> \r for pragmatic reasons. 110 * Many client implementations send \r\n when 111 * the user hits the CarriageReturn key. 112 * 113 * We USED to map \r\n ==> \n, since \r\n says 114 * that we want to be in column 1 of the next 115 * printable line, and \n is the standard 116 * unix way of saying that (\r is only good 117 * if CRMOD is set, which it normally is). 118 */ 119 if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) { 120 int nc = *netip; 121 #ifdef ENCRYPTION 122 if (decrypt_input) 123 nc = (*decrypt_input)(nc & 0xff); 124 #endif 125 { 126 #ifdef ENCRYPTION 127 if (decrypt_input) 128 (void)(*decrypt_input)(-1); 129 #endif 130 state = TS_CR; 131 } 132 } 133 *pfrontp++ = c; 134 break; 135 136 case TS_IAC: 137 gotiac: switch (c) { 138 139 /* 140 * Send the process on the pty side an 141 * interrupt. Do this with a NULL or 142 * interrupt char; depending on the tty mode. 143 */ 144 case IP: 145 DIAG(TD_OPTIONS, 146 printoption("td: recv IAC", c)); 147 interrupt(); 148 break; 149 150 case BREAK: 151 DIAG(TD_OPTIONS, 152 printoption("td: recv IAC", c)); 153 sendbrk(); 154 break; 155 156 /* 157 * Are You There? 158 */ 159 case AYT: 160 DIAG(TD_OPTIONS, 161 printoption("td: recv IAC", c)); 162 recv_ayt(); 163 break; 164 165 /* 166 * Abort Output 167 */ 168 case AO: 169 { 170 DIAG(TD_OPTIONS, 171 printoption("td: recv IAC", c)); 172 ptyflush(); /* half-hearted */ 173 init_termbuf(); 174 175 if (slctab[SLC_AO].sptr && 176 *slctab[SLC_AO].sptr != (cc_t)(_POSIX_VDISABLE)) { 177 *pfrontp++ = 178 (unsigned char)*slctab[SLC_AO].sptr; 179 } 180 181 netclear(); /* clear buffer back */ 182 output_data ("%c%c", IAC, DM); 183 neturg = nfrontp-1; /* off by one XXX */ 184 DIAG(TD_OPTIONS, 185 printoption("td: send IAC", DM)); 186 break; 187 } 188 189 /* 190 * Erase Character and 191 * Erase Line 192 */ 193 case EC: 194 case EL: 195 { 196 cc_t ch; 197 198 DIAG(TD_OPTIONS, 199 printoption("td: recv IAC", c)); 200 ptyflush(); /* half-hearted */ 201 init_termbuf(); 202 if (c == EC) 203 ch = *slctab[SLC_EC].sptr; 204 else 205 ch = *slctab[SLC_EL].sptr; 206 if (ch != (cc_t)(_POSIX_VDISABLE)) 207 *pfrontp++ = (unsigned char)ch; 208 break; 209 } 210 211 /* 212 * Check for urgent data... 213 */ 214 case DM: 215 DIAG(TD_OPTIONS, 216 printoption("td: recv IAC", c)); 217 SYNCHing = stilloob(net); 218 settimer(gotDM); 219 break; 220 221 222 /* 223 * Begin option subnegotiation... 224 */ 225 case SB: 226 state = TS_SB; 227 SB_CLEAR(); 228 continue; 229 230 case WILL: 231 state = TS_WILL; 232 continue; 233 234 case WONT: 235 state = TS_WONT; 236 continue; 237 238 case DO: 239 state = TS_DO; 240 continue; 241 242 case DONT: 243 state = TS_DONT; 244 continue; 245 case EOR: 246 if (his_state_is_will(TELOPT_EOR)) 247 doeof(); 248 break; 249 250 /* 251 * Handle RFC 10xx Telnet linemode option additions 252 * to command stream (EOF, SUSP, ABORT). 253 */ 254 case xEOF: 255 doeof(); 256 break; 257 258 case SUSP: 259 sendsusp(); 260 break; 261 262 case ABORT: 263 sendbrk(); 264 break; 265 266 case IAC: 267 *pfrontp++ = c; 268 break; 269 } 270 state = TS_DATA; 271 break; 272 273 case TS_SB: 274 if (c == IAC) { 275 state = TS_SE; 276 } else { 277 SB_ACCUM(c); 278 } 279 break; 280 281 case TS_SE: 282 if (c != SE) { 283 if (c != IAC) { 284 /* 285 * bad form of suboption negotiation. 286 * handle it in such a way as to avoid 287 * damage to local state. Parse 288 * suboption buffer found so far, 289 * then treat remaining stream as 290 * another command sequence. 291 */ 292 293 /* for DIAGNOSTICS */ 294 SB_ACCUM(IAC); 295 SB_ACCUM(c); 296 subpointer -= 2; 297 298 SB_TERM(); 299 suboption(); 300 state = TS_IAC; 301 goto gotiac; 302 } 303 SB_ACCUM(c); 304 state = TS_SB; 305 } else { 306 /* for DIAGNOSTICS */ 307 SB_ACCUM(IAC); 308 SB_ACCUM(SE); 309 subpointer -= 2; 310 311 SB_TERM(); 312 suboption(); /* handle sub-option */ 313 state = TS_DATA; 314 } 315 break; 316 317 case TS_WILL: 318 willoption(c); 319 state = TS_DATA; 320 continue; 321 322 case TS_WONT: 323 wontoption(c); 324 if (c==TELOPT_ENCRYPT && his_do_dont_is_changing(TELOPT_ENCRYPT) ) 325 dontoption(c); 326 state = TS_DATA; 327 continue; 328 329 case TS_DO: 330 dooption(c); 331 state = TS_DATA; 332 continue; 333 334 case TS_DONT: 335 dontoption(c); 336 state = TS_DATA; 337 continue; 338 339 default: 340 syslog(LOG_ERR, "telnetd: panic state=%d\n", state); 341 printf("telnetd: panic state=%d\n", state); 342 exit(1); 343 } 344 } 345 } /* end of telrcv */ 346 347 /* 348 * The will/wont/do/dont state machines are based on Dave Borman's 349 * Telnet option processing state machine. 350 * 351 * These correspond to the following states: 352 * my_state = the last negotiated state 353 * want_state = what I want the state to go to 354 * want_resp = how many requests I have sent 355 * All state defaults are negative, and resp defaults to 0. 356 * 357 * When initiating a request to change state to new_state: 358 * 359 * if ((want_resp == 0 && new_state == my_state) || want_state == new_state) { 360 * do nothing; 361 * } else { 362 * want_state = new_state; 363 * send new_state; 364 * want_resp++; 365 * } 366 * 367 * When receiving new_state: 368 * 369 * if (want_resp) { 370 * want_resp--; 371 * if (want_resp && (new_state == my_state)) 372 * want_resp--; 373 * } 374 * if ((want_resp == 0) && (new_state != want_state)) { 375 * if (ok_to_switch_to new_state) 376 * want_state = new_state; 377 * else 378 * want_resp++; 379 * send want_state; 380 * } 381 * my_state = new_state; 382 * 383 * Note that new_state is implied in these functions by the function itself. 384 * will and do imply positive new_state, wont and dont imply negative. 385 * 386 * Finally, there is one catch. If we send a negative response to a 387 * positive request, my_state will be the positive while want_state will 388 * remain negative. my_state will revert to negative when the negative 389 * acknowlegment arrives from the peer. Thus, my_state generally tells 390 * us not only the last negotiated state, but also tells us what the peer 391 * wants to be doing as well. It is important to understand this difference 392 * as we may wish to be processing data streams based on our desired state 393 * (want_state) or based on what the peer thinks the state is (my_state). 394 * 395 * This all works fine because if the peer sends a positive request, the data 396 * that we receive prior to negative acknowlegment will probably be affected 397 * by the positive state, and we can process it as such (if we can; if we 398 * can't then it really doesn't matter). If it is that important, then the 399 * peer probably should be buffering until this option state negotiation 400 * is complete. 401 * 402 */ 403 void 404 send_do(int option, int init) 405 { 406 if (init) { 407 if ((do_dont_resp[option] == 0 && his_state_is_will(option)) || 408 his_want_state_is_will(option)) 409 return; 410 /* 411 * Special case for TELOPT_TM: We send a DO, but pretend 412 * that we sent a DONT, so that we can send more DOs if 413 * we want to. 414 */ 415 if (option == TELOPT_TM) 416 set_his_want_state_wont(option); 417 else 418 set_his_want_state_will(option); 419 do_dont_resp[option]++; 420 } 421 output_data((const char *)doopt, option); 422 423 DIAG(TD_OPTIONS, printoption("td: send do", option)); 424 } 425 426 #ifdef AUTHENTICATION 427 extern void auth_request(void); 428 #endif 429 #ifdef ENCRYPTION 430 extern void encrypt_send_support(void); 431 #endif 432 433 void 434 willoption(int option) 435 { 436 int changeok = 0; 437 void (*func)(void) = NULL; 438 439 /* 440 * process input from peer. 441 */ 442 443 DIAG(TD_OPTIONS, printoption("td: recv will", option)); 444 445 if (do_dont_resp[option]) { 446 do_dont_resp[option]--; 447 if (do_dont_resp[option] && his_state_is_will(option)) 448 do_dont_resp[option]--; 449 } 450 if (do_dont_resp[option] == 0) { 451 if (his_want_state_is_wont(option)) { 452 switch (option) { 453 454 case TELOPT_BINARY: 455 init_termbuf(); 456 tty_binaryin(1); 457 set_termbuf(); 458 changeok++; 459 break; 460 461 case TELOPT_ECHO: 462 /* 463 * See comments below for more info. 464 */ 465 not42 = 0; /* looks like a 4.2 system */ 466 break; 467 468 case TELOPT_TM: 469 /* 470 * We never respond to a WILL TM, and 471 * we leave the state WONT. 472 */ 473 return; 474 475 case TELOPT_LFLOW: 476 /* 477 * If we are going to support flow control 478 * option, then don't worry peer that we can't 479 * change the flow control characters. 480 */ 481 slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS; 482 slctab[SLC_XON].defset.flag |= SLC_DEFAULT; 483 slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS; 484 slctab[SLC_XOFF].defset.flag |= SLC_DEFAULT; 485 case TELOPT_TTYPE: 486 case TELOPT_SGA: 487 case TELOPT_NAWS: 488 case TELOPT_TSPEED: 489 case TELOPT_XDISPLOC: 490 case TELOPT_NEW_ENVIRON: 491 case TELOPT_OLD_ENVIRON: 492 changeok++; 493 break; 494 495 496 #ifdef AUTHENTICATION 497 case TELOPT_AUTHENTICATION: 498 func = auth_request; 499 changeok++; 500 break; 501 #endif 502 503 #ifdef ENCRYPTION 504 case TELOPT_ENCRYPT: 505 func = encrypt_send_support; 506 changeok++; 507 break; 508 #endif 509 510 default: 511 break; 512 } 513 if (changeok) { 514 set_his_want_state_will(option); 515 send_do(option, 0); 516 } else { 517 do_dont_resp[option]++; 518 send_dont(option, 0); 519 } 520 } else { 521 /* 522 * Option processing that should happen when 523 * we receive conformation of a change in 524 * state that we had requested. 525 */ 526 switch (option) { 527 case TELOPT_ECHO: 528 not42 = 0; /* looks like a 4.2 system */ 529 /* 530 * Egads, he responded "WILL ECHO". Turn 531 * it off right now! 532 */ 533 send_dont(option, 1); 534 /* 535 * "WILL ECHO". Kludge upon kludge! 536 * A 4.2 client is now echoing user input at 537 * the tty. This is probably undesireable and 538 * it should be stopped. The client will 539 * respond WONT TM to the DO TM that we send to 540 * check for kludge linemode. When the WONT TM 541 * arrives, linemode will be turned off and a 542 * change propogated to the pty. This change 543 * will cause us to process the new pty state 544 * in localstat(), which will notice that 545 * linemode is off and send a WILL ECHO 546 * so that we are properly in character mode and 547 * all is well. 548 */ 549 break; 550 551 #ifdef AUTHENTICATION 552 case TELOPT_AUTHENTICATION: 553 func = auth_request; 554 break; 555 #endif 556 557 #ifdef ENCRYPTION 558 case TELOPT_ENCRYPT: 559 func = encrypt_send_support; 560 break; 561 #endif 562 563 case TELOPT_LFLOW: 564 func = flowstat; 565 break; 566 } 567 } 568 } 569 set_his_state_will(option); 570 if (func) 571 (*func)(); 572 } /* end of willoption */ 573 574 void 575 send_dont(int option, int init) 576 { 577 if (init) { 578 if ((do_dont_resp[option] == 0 && his_state_is_wont(option)) || 579 his_want_state_is_wont(option)) 580 return; 581 set_his_want_state_wont(option); 582 do_dont_resp[option]++; 583 } 584 output_data((const char *)dont, option); 585 586 DIAG(TD_OPTIONS, printoption("td: send dont", option)); 587 } 588 589 void 590 wontoption(int option) 591 { 592 /* 593 * Process client input. 594 */ 595 596 DIAG(TD_OPTIONS, printoption("td: recv wont", option)); 597 598 if (do_dont_resp[option]) { 599 do_dont_resp[option]--; 600 if (do_dont_resp[option] && his_state_is_wont(option)) 601 do_dont_resp[option]--; 602 } 603 if (do_dont_resp[option] == 0) { 604 if (his_want_state_is_will(option)) { 605 /* it is always ok to change to negative state */ 606 switch (option) { 607 case TELOPT_ECHO: 608 not42 = 1; /* doesn't seem to be a 4.2 system */ 609 break; 610 611 case TELOPT_BINARY: 612 init_termbuf(); 613 tty_binaryin(0); 614 set_termbuf(); 615 break; 616 617 case TELOPT_TM: 618 /* 619 * If we get a WONT TM, and had sent a DO TM, 620 * don't respond with a DONT TM, just leave it 621 * as is. Short circut the state machine to 622 * achive this. 623 */ 624 set_his_want_state_wont(TELOPT_TM); 625 return; 626 627 case TELOPT_LFLOW: 628 /* 629 * If we are not going to support flow control 630 * option, then let peer know that we can't 631 * change the flow control characters. 632 */ 633 slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS; 634 slctab[SLC_XON].defset.flag |= SLC_CANTCHANGE; 635 slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS; 636 slctab[SLC_XOFF].defset.flag |= SLC_CANTCHANGE; 637 break; 638 639 #ifdef AUTHENTICATION 640 case TELOPT_AUTHENTICATION: 641 auth_finished(0, AUTH_REJECT); 642 break; 643 #endif 644 645 /* 646 * For options that we might spin waiting for 647 * sub-negotiation, if the client turns off the 648 * option rather than responding to the request, 649 * we have to treat it here as if we got a response 650 * to the sub-negotiation, (by updating the timers) 651 * so that we'll break out of the loop. 652 */ 653 case TELOPT_TTYPE: 654 settimer(ttypesubopt); 655 break; 656 657 case TELOPT_TSPEED: 658 settimer(tspeedsubopt); 659 break; 660 661 case TELOPT_XDISPLOC: 662 settimer(xdisplocsubopt); 663 break; 664 665 case TELOPT_OLD_ENVIRON: 666 settimer(oenvironsubopt); 667 break; 668 669 case TELOPT_NEW_ENVIRON: 670 settimer(environsubopt); 671 break; 672 673 default: 674 break; 675 } 676 set_his_want_state_wont(option); 677 if (his_state_is_will(option)) 678 send_dont(option, 0); 679 } else { 680 switch (option) { 681 case TELOPT_TM: 682 break; 683 684 #ifdef AUTHENTICATION 685 case TELOPT_AUTHENTICATION: 686 auth_finished(0, AUTH_REJECT); 687 break; 688 #endif 689 default: 690 break; 691 } 692 } 693 } 694 set_his_state_wont(option); 695 696 } /* end of wontoption */ 697 698 void 699 send_will(int option, int init) 700 { 701 if (init) { 702 if ((will_wont_resp[option] == 0 && my_state_is_will(option))|| 703 my_want_state_is_will(option)) 704 return; 705 set_my_want_state_will(option); 706 will_wont_resp[option]++; 707 } 708 output_data ((const char *)will, option); 709 710 DIAG(TD_OPTIONS, printoption("td: send will", option)); 711 } 712 713 /* 714 * When we get a DONT SGA, we will try once to turn it 715 * back on. If the other side responds DONT SGA, we 716 * leave it at that. This is so that when we talk to 717 * clients that understand KLUDGELINEMODE but not LINEMODE, 718 * we'll keep them in char-at-a-time mode. 719 */ 720 int turn_on_sga = 0; 721 722 void 723 dooption(int option) 724 { 725 int changeok = 0; 726 727 /* 728 * Process client input. 729 */ 730 731 DIAG(TD_OPTIONS, printoption("td: recv do", option)); 732 733 if (will_wont_resp[option]) { 734 will_wont_resp[option]--; 735 if (will_wont_resp[option] && my_state_is_will(option)) 736 will_wont_resp[option]--; 737 } 738 if ((will_wont_resp[option] == 0) && (my_want_state_is_wont(option))) { 739 switch (option) { 740 case TELOPT_ECHO: 741 { 742 init_termbuf(); 743 tty_setecho(1); 744 set_termbuf(); 745 } 746 changeok++; 747 break; 748 749 case TELOPT_BINARY: 750 init_termbuf(); 751 tty_binaryout(1); 752 set_termbuf(); 753 changeok++; 754 break; 755 756 case TELOPT_SGA: 757 turn_on_sga = 0; 758 changeok++; 759 break; 760 761 case TELOPT_STATUS: 762 changeok++; 763 break; 764 765 case TELOPT_TM: 766 /* 767 * Special case for TM. We send a WILL, but 768 * pretend we sent a WONT. 769 */ 770 send_will(option, 0); 771 set_my_want_state_wont(option); 772 set_my_state_wont(option); 773 return; 774 775 case TELOPT_LOGOUT: 776 /* 777 * When we get a LOGOUT option, respond 778 * with a WILL LOGOUT, make sure that 779 * it gets written out to the network, 780 * and then just go away... 781 */ 782 set_my_want_state_will(TELOPT_LOGOUT); 783 send_will(TELOPT_LOGOUT, 0); 784 set_my_state_will(TELOPT_LOGOUT); 785 netflush(); 786 cleanup(0); 787 /* NOT REACHED */ 788 break; 789 790 #ifdef ENCRYPTION 791 case TELOPT_ENCRYPT: 792 changeok++; 793 break; 794 #endif 795 case TELOPT_LINEMODE: 796 case TELOPT_TTYPE: 797 case TELOPT_NAWS: 798 case TELOPT_TSPEED: 799 case TELOPT_LFLOW: 800 case TELOPT_XDISPLOC: 801 #ifdef TELOPT_ENVIRON 802 case TELOPT_NEW_ENVIRON: 803 #endif 804 case TELOPT_OLD_ENVIRON: 805 default: 806 break; 807 } 808 if (changeok) { 809 set_my_want_state_will(option); 810 send_will(option, 0); 811 } else { 812 will_wont_resp[option]++; 813 send_wont(option, 0); 814 } 815 } 816 set_my_state_will(option); 817 818 } /* end of dooption */ 819 820 void 821 send_wont(int option, int init) 822 { 823 if (init) { 824 if ((will_wont_resp[option] == 0 && my_state_is_wont(option)) || 825 my_want_state_is_wont(option)) 826 return; 827 set_my_want_state_wont(option); 828 will_wont_resp[option]++; 829 } 830 output_data ((const char *)wont, option); 831 832 DIAG(TD_OPTIONS, printoption("td: send wont", option)); 833 } 834 835 void 836 dontoption(int option) 837 { 838 /* 839 * Process client input. 840 */ 841 842 843 DIAG(TD_OPTIONS, printoption("td: recv dont", option)); 844 845 if (will_wont_resp[option]) { 846 will_wont_resp[option]--; 847 if (will_wont_resp[option] && my_state_is_wont(option)) 848 will_wont_resp[option]--; 849 } 850 if ((will_wont_resp[option] == 0) && (my_want_state_is_will(option))) { 851 switch (option) { 852 case TELOPT_BINARY: 853 init_termbuf(); 854 tty_binaryout(0); 855 set_termbuf(); 856 break; 857 858 case TELOPT_ECHO: /* we should stop echoing */ 859 { 860 init_termbuf(); 861 tty_setecho(0); 862 set_termbuf(); 863 } 864 break; 865 866 case TELOPT_SGA: 867 set_my_want_state_wont(option); 868 if (my_state_is_will(option)) 869 send_wont(option, 0); 870 set_my_state_wont(option); 871 if (turn_on_sga ^= 1) 872 send_will(option, 1); 873 return; 874 875 default: 876 break; 877 } 878 879 set_my_want_state_wont(option); 880 if (my_state_is_will(option)) 881 send_wont(option, 0); 882 } 883 set_my_state_wont(option); 884 885 } /* end of dontoption */ 886 887 #ifdef ENV_HACK 888 int env_ovar = -1; 889 int env_ovalue = -1; 890 #else /* ENV_HACK */ 891 # define env_ovar OLD_ENV_VAR 892 # define env_ovalue OLD_ENV_VALUE 893 #endif /* ENV_HACK */ 894 895 /* 896 * suboption() 897 * 898 * Look at the sub-option buffer, and try to be helpful to the other 899 * side. 900 * 901 * Currently we recognize: 902 * 903 * Terminal type is 904 * Linemode 905 * Window size 906 * Terminal speed 907 */ 908 void 909 suboption(void) 910 { 911 int subchar; 912 913 DIAG(TD_OPTIONS, {netflush(); printsub('<', subpointer, SB_LEN()+2);}); 914 915 subchar = SB_GET(); 916 switch (subchar) { 917 case TELOPT_TSPEED: { 918 int xspeed, rspeed; 919 920 if (his_state_is_wont(TELOPT_TSPEED)) /* Ignore if option disabled */ 921 break; 922 923 settimer(tspeedsubopt); 924 925 if (SB_EOF() || SB_GET() != TELQUAL_IS) 926 return; 927 928 xspeed = atoi((char *)subpointer); 929 930 while (SB_GET() != ',' && !SB_EOF()); 931 if (SB_EOF()) 932 return; 933 934 rspeed = atoi((char *)subpointer); 935 clientstat(TELOPT_TSPEED, xspeed, rspeed); 936 937 break; 938 939 } /* end of case TELOPT_TSPEED */ 940 941 case TELOPT_TTYPE: { /* Yaaaay! */ 942 char *p; 943 944 if (his_state_is_wont(TELOPT_TTYPE)) /* Ignore if option disabled */ 945 break; 946 settimer(ttypesubopt); 947 948 if (SB_EOF() || SB_GET() != TELQUAL_IS) { 949 return; /* ??? XXX but, this is the most robust */ 950 } 951 952 p = terminaltype; 953 954 while ((p < (terminaltype + sizeof terminaltype-1)) && 955 !SB_EOF()) { 956 int c; 957 958 c = SB_GET(); 959 if (isupper(c)) { 960 c = tolower(c); 961 } 962 *p++ = c; /* accumulate name */ 963 } 964 *p = 0; 965 break; 966 } /* end of case TELOPT_TTYPE */ 967 968 case TELOPT_NAWS: { 969 int xwinsize, ywinsize; 970 971 if (his_state_is_wont(TELOPT_NAWS)) /* Ignore if option disabled */ 972 break; 973 974 if (SB_EOF()) 975 return; 976 xwinsize = SB_GET() << 8; 977 if (SB_EOF()) 978 return; 979 xwinsize |= SB_GET(); 980 if (SB_EOF()) 981 return; 982 ywinsize = SB_GET() << 8; 983 if (SB_EOF()) 984 return; 985 ywinsize |= SB_GET(); 986 clientstat(TELOPT_NAWS, xwinsize, ywinsize); 987 988 break; 989 990 } /* end of case TELOPT_NAWS */ 991 992 case TELOPT_STATUS: { 993 int mode; 994 995 if (SB_EOF()) 996 break; 997 mode = SB_GET(); 998 switch (mode) { 999 case TELQUAL_SEND: 1000 if (my_state_is_will(TELOPT_STATUS)) 1001 send_status(); 1002 break; 1003 1004 case TELQUAL_IS: 1005 break; 1006 1007 default: 1008 break; 1009 } 1010 break; 1011 } /* end of case TELOPT_STATUS */ 1012 1013 case TELOPT_XDISPLOC: { 1014 if (SB_EOF() || SB_GET() != TELQUAL_IS) 1015 return; 1016 settimer(xdisplocsubopt); 1017 subpointer[SB_LEN()] = '\0'; 1018 esetenv("DISPLAY", (char *)subpointer, 1); 1019 break; 1020 } /* end of case TELOPT_XDISPLOC */ 1021 1022 #ifdef TELOPT_NEW_ENVIRON 1023 case TELOPT_NEW_ENVIRON: 1024 #endif 1025 case TELOPT_OLD_ENVIRON: { 1026 int c; 1027 char *cp, *varp, *valp; 1028 1029 if (SB_EOF()) 1030 return; 1031 c = SB_GET(); 1032 if (c == TELQUAL_IS) { 1033 if (subchar == TELOPT_OLD_ENVIRON) 1034 settimer(oenvironsubopt); 1035 else 1036 settimer(environsubopt); 1037 } else if (c != TELQUAL_INFO) { 1038 return; 1039 } 1040 1041 #ifdef TELOPT_NEW_ENVIRON 1042 if (subchar == TELOPT_NEW_ENVIRON) { 1043 while (!SB_EOF()) { 1044 c = SB_GET(); 1045 if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR)) 1046 break; 1047 } 1048 } else 1049 #endif 1050 { 1051 #ifdef ENV_HACK 1052 /* 1053 * We only want to do this if we haven't already decided 1054 * whether or not the other side has its VALUE and VAR 1055 * reversed. 1056 */ 1057 if (env_ovar < 0) { 1058 int last = -1; /* invalid value */ 1059 int empty = 0; 1060 int got_var = 0, got_value = 0, got_uservar = 0; 1061 1062 /* 1063 * The other side might have its VALUE and VAR values 1064 * reversed. To be interoperable, we need to determine 1065 * which way it is. If the first recognized character 1066 * is a VAR or VALUE, then that will tell us what 1067 * type of client it is. If the fist recognized 1068 * character is a USERVAR, then we continue scanning 1069 * the suboption looking for two consecutive 1070 * VAR or VALUE fields. We should not get two 1071 * consecutive VALUE fields, so finding two 1072 * consecutive VALUE or VAR fields will tell us 1073 * what the client is. 1074 */ 1075 SB_SAVE(); 1076 while (!SB_EOF()) { 1077 c = SB_GET(); 1078 switch(c) { 1079 case OLD_ENV_VAR: 1080 if (last < 0 || last == OLD_ENV_VAR 1081 || (empty && (last == OLD_ENV_VALUE))) 1082 goto env_ovar_ok; 1083 got_var++; 1084 last = OLD_ENV_VAR; 1085 break; 1086 case OLD_ENV_VALUE: 1087 if (last < 0 || last == OLD_ENV_VALUE 1088 || (empty && (last == OLD_ENV_VAR))) 1089 goto env_ovar_wrong; 1090 got_value++; 1091 last = OLD_ENV_VALUE; 1092 break; 1093 case ENV_USERVAR: 1094 /* count strings of USERVAR as one */ 1095 if (last != ENV_USERVAR) 1096 got_uservar++; 1097 if (empty) { 1098 if (last == OLD_ENV_VALUE) 1099 goto env_ovar_ok; 1100 if (last == OLD_ENV_VAR) 1101 goto env_ovar_wrong; 1102 } 1103 last = ENV_USERVAR; 1104 break; 1105 case ENV_ESC: 1106 if (!SB_EOF()) 1107 c = SB_GET(); 1108 /* FALL THROUGH */ 1109 default: 1110 empty = 0; 1111 continue; 1112 } 1113 empty = 1; 1114 } 1115 if (empty) { 1116 if (last == OLD_ENV_VALUE) 1117 goto env_ovar_ok; 1118 if (last == OLD_ENV_VAR) 1119 goto env_ovar_wrong; 1120 } 1121 /* 1122 * Ok, the first thing was a USERVAR, and there 1123 * are not two consecutive VAR or VALUE commands, 1124 * and none of the VAR or VALUE commands are empty. 1125 * If the client has sent us a well-formed option, 1126 * then the number of VALUEs received should always 1127 * be less than or equal to the number of VARs and 1128 * USERVARs received. 1129 * 1130 * If we got exactly as many VALUEs as VARs and 1131 * USERVARs, the client has the same definitions. 1132 * 1133 * If we got exactly as many VARs as VALUEs and 1134 * USERVARS, the client has reversed definitions. 1135 */ 1136 if (got_uservar + got_var == got_value) { 1137 env_ovar_ok: 1138 env_ovar = OLD_ENV_VAR; 1139 env_ovalue = OLD_ENV_VALUE; 1140 } else if (got_uservar + got_value == got_var) { 1141 env_ovar_wrong: 1142 env_ovar = OLD_ENV_VALUE; 1143 env_ovalue = OLD_ENV_VAR; 1144 DIAG(TD_OPTIONS, { 1145 output_data("ENVIRON VALUE and VAR are reversed!\r\n"); 1146 }); 1147 1148 } 1149 } 1150 SB_RESTORE(); 1151 #endif 1152 1153 while (!SB_EOF()) { 1154 c = SB_GET(); 1155 if ((c == env_ovar) || (c == ENV_USERVAR)) 1156 break; 1157 } 1158 } 1159 1160 if (SB_EOF()) 1161 return; 1162 1163 cp = varp = (char *)subpointer; 1164 valp = 0; 1165 1166 while (!SB_EOF()) { 1167 c = SB_GET(); 1168 if (subchar == TELOPT_OLD_ENVIRON) { 1169 if (c == env_ovar) 1170 c = NEW_ENV_VAR; 1171 else if (c == env_ovalue) 1172 c = NEW_ENV_VALUE; 1173 } 1174 switch (c) { 1175 1176 case NEW_ENV_VALUE: 1177 *cp = '\0'; 1178 cp = valp = (char *)subpointer; 1179 break; 1180 1181 case NEW_ENV_VAR: 1182 case ENV_USERVAR: 1183 *cp = '\0'; 1184 if (valp) 1185 esetenv(varp, valp, 1); 1186 else 1187 unsetenv(varp); 1188 cp = varp = (char *)subpointer; 1189 valp = 0; 1190 break; 1191 1192 case ENV_ESC: 1193 if (SB_EOF()) 1194 break; 1195 c = SB_GET(); 1196 /* FALL THROUGH */ 1197 default: 1198 *cp++ = c; 1199 break; 1200 } 1201 } 1202 *cp = '\0'; 1203 if (valp) 1204 esetenv(varp, valp, 1); 1205 else 1206 unsetenv(varp); 1207 break; 1208 } /* end of case TELOPT_NEW_ENVIRON */ 1209 #ifdef AUTHENTICATION 1210 case TELOPT_AUTHENTICATION: 1211 if (SB_EOF()) 1212 break; 1213 switch(SB_GET()) { 1214 case TELQUAL_SEND: 1215 case TELQUAL_REPLY: 1216 /* 1217 * These are sent by us and cannot be sent by 1218 * the client. 1219 */ 1220 break; 1221 case TELQUAL_IS: 1222 auth_is(subpointer, SB_LEN()); 1223 break; 1224 case TELQUAL_NAME: 1225 auth_name(subpointer, SB_LEN()); 1226 break; 1227 } 1228 break; 1229 #endif 1230 #ifdef ENCRYPTION 1231 case TELOPT_ENCRYPT: 1232 if (SB_EOF()) 1233 break; 1234 switch(SB_GET()) { 1235 case ENCRYPT_SUPPORT: 1236 encrypt_support(subpointer, SB_LEN()); 1237 break; 1238 case ENCRYPT_IS: 1239 encrypt_is(subpointer, SB_LEN()); 1240 break; 1241 case ENCRYPT_REPLY: 1242 encrypt_reply(subpointer, SB_LEN()); 1243 break; 1244 case ENCRYPT_START: 1245 encrypt_start(subpointer, SB_LEN()); 1246 break; 1247 case ENCRYPT_END: 1248 if (require_encryption) 1249 fatal(net, "Output encryption is not possible to turn off"); 1250 encrypt_end(); 1251 break; 1252 case ENCRYPT_REQSTART: 1253 encrypt_request_start(subpointer, SB_LEN()); 1254 break; 1255 case ENCRYPT_REQEND: 1256 /* 1257 * We can always send an REQEND so that we cannot 1258 * get stuck encrypting. We should only get this 1259 * if we have been able to get in the correct mode 1260 * anyhow. 1261 */ 1262 if (require_encryption) 1263 fatal(net, "Input encryption is not possible to turn off"); 1264 encrypt_request_end(); 1265 break; 1266 case ENCRYPT_ENC_KEYID: 1267 encrypt_enc_keyid(subpointer, SB_LEN()); 1268 break; 1269 case ENCRYPT_DEC_KEYID: 1270 encrypt_dec_keyid(subpointer, SB_LEN()); 1271 break; 1272 default: 1273 break; 1274 } 1275 break; 1276 #endif 1277 1278 default: 1279 break; 1280 } /* end of switch */ 1281 1282 } /* end of suboption */ 1283 1284 void 1285 doclientstat(void) 1286 { 1287 clientstat(TELOPT_LINEMODE, WILL, 0); 1288 } 1289 1290 #undef ADD 1291 #define ADD(c) *ncp++ = c 1292 #define ADD_DATA(c) { *ncp++ = c; if (c == SE || c == IAC) *ncp++ = c; } 1293 1294 void 1295 send_status(void) 1296 { 1297 unsigned char statusbuf[256]; 1298 unsigned char *ncp; 1299 unsigned char i; 1300 1301 ncp = statusbuf; 1302 1303 netflush(); /* get rid of anything waiting to go out */ 1304 1305 ADD(IAC); 1306 ADD(SB); 1307 ADD(TELOPT_STATUS); 1308 ADD(TELQUAL_IS); 1309 1310 /* 1311 * We check the want_state rather than the current state, 1312 * because if we received a DO/WILL for an option that we 1313 * don't support, and the other side didn't send a DONT/WONT 1314 * in response to our WONT/DONT, then the "state" will be 1315 * WILL/DO, and the "want_state" will be WONT/DONT. We 1316 * need to go by the latter. 1317 */ 1318 for (i = 0; i < (unsigned char)NTELOPTS; i++) { 1319 if (my_want_state_is_will(i)) { 1320 ADD(WILL); 1321 ADD_DATA(i); 1322 } 1323 if (his_want_state_is_will(i)) { 1324 ADD(DO); 1325 ADD_DATA(i); 1326 } 1327 } 1328 1329 if (his_want_state_is_will(TELOPT_LFLOW)) { 1330 ADD(SB); 1331 ADD(TELOPT_LFLOW); 1332 if (flowmode) { 1333 ADD(LFLOW_ON); 1334 } else { 1335 ADD(LFLOW_OFF); 1336 } 1337 ADD(SE); 1338 1339 if (restartany >= 0) { 1340 ADD(SB); 1341 ADD(TELOPT_LFLOW); 1342 if (restartany) { 1343 ADD(LFLOW_RESTART_ANY); 1344 } else { 1345 ADD(LFLOW_RESTART_XON); 1346 } 1347 ADD(SE); 1348 } 1349 } 1350 1351 1352 ADD(IAC); 1353 ADD(SE); 1354 1355 writenet(statusbuf, ncp - statusbuf); 1356 netflush(); /* Send it on its way */ 1357 1358 DIAG(TD_OPTIONS, 1359 {printsub('>', statusbuf, ncp - statusbuf); netflush();}); 1360 } 1361