1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * 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 #ifndef lint 35 static char sccsid[] = "@(#)encrypt.c 5.2 (Berkeley) 3/22/91"; 36 #endif /* not lint */ 37 38 /* 39 * Copyright (C) 1990 by the Massachusetts Institute of Technology 40 * 41 * Export of this software from the United States of America is assumed 42 * to require a specific license from the United States Government. 43 * It is the responsibility of any person or organization contemplating 44 * export to obtain such a license before exporting. 45 * 46 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 47 * distribute this software and its documentation for any purpose and 48 * without fee is hereby granted, provided that the above copyright 49 * notice appear in all copies and that both that copyright notice and 50 * this permission notice appear in supporting documentation, and that 51 * the name of M.I.T. not be used in advertising or publicity pertaining 52 * to distribution of the software without specific, written prior 53 * permission. M.I.T. makes no representations about the suitability of 54 * this software for any purpose. It is provided "as is" without express 55 * or implied warranty. 56 */ 57 58 #if defined(ENCRYPT) 59 60 #define ENCRYPT_NAMES 61 #include <arpa/telnet.h> 62 63 #include "encrypt.h" 64 #include "misc.h" 65 66 #ifdef __STDC__ 67 #include <stdlib.h> 68 #endif 69 #ifdef NO_STRING_H 70 #include <strings.h> 71 #else 72 #include <string.h> 73 #endif 74 75 /* 76 * These functions pointers point to the current routines 77 * for encrypting and decrypting data. 78 */ 79 void (*encrypt_output) P((unsigned char *, int)); 80 int (*decrypt_input) P((int)); 81 82 int encrypt_debug_mode = 0; 83 static int decrypt_mode = 0; 84 static int encrypt_mode = 0; 85 static int encrypt_verbose = 0; 86 static int autoencrypt = 0; 87 static int autodecrypt = 0; 88 static int havesessionkey = 0; 89 static int Server = 0; 90 static char *Name = "Noname"; 91 92 #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 93 94 static long i_support_encrypt = typemask(ENCTYPE_DES_CFB64) 95 | typemask(ENCTYPE_DES_OFB64); 96 static long i_support_decrypt = typemask(ENCTYPE_DES_CFB64) 97 | typemask(ENCTYPE_DES_OFB64); 98 static long i_wont_support_encrypt = 0; 99 static long i_wont_support_decrypt = 0; 100 #define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt) 101 #define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt) 102 103 static long remote_supports_encrypt = 0; 104 static long remote_supports_decrypt = 0; 105 106 static Encryptions encryptions[] = { 107 #if defined(DES_ENCRYPT) 108 { "DES_CFB64", ENCTYPE_DES_CFB64, 109 cfb64_encrypt, 110 cfb64_decrypt, 111 cfb64_init, 112 cfb64_start, 113 cfb64_is, 114 cfb64_reply, 115 cfb64_session, 116 cfb64_keyid, 117 cfb64_printsub }, 118 { "DES_OFB64", ENCTYPE_DES_OFB64, 119 ofb64_encrypt, 120 ofb64_decrypt, 121 ofb64_init, 122 ofb64_start, 123 ofb64_is, 124 ofb64_reply, 125 ofb64_session, 126 ofb64_keyid, 127 ofb64_printsub }, 128 #endif 129 { 0, }, 130 }; 131 132 static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, 133 ENCRYPT_SUPPORT }; 134 static unsigned char str_suplen = 0; 135 static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT }; 136 static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; 137 138 Encryptions * 139 findencryption(type) 140 int type; 141 { 142 Encryptions *ep = encryptions; 143 144 if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & typemask(type))) 145 return(0); 146 while (ep->type && ep->type != type) 147 ++ep; 148 return(ep->type ? ep : 0); 149 } 150 151 Encryptions * 152 finddecryption(type) 153 int type; 154 { 155 Encryptions *ep = encryptions; 156 157 if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & typemask(type))) 158 return(0); 159 while (ep->type && ep->type != type) 160 ++ep; 161 return(ep->type ? ep : 0); 162 } 163 164 #define MAXKEYLEN 64 165 166 static struct key_info { 167 unsigned char keyid[MAXKEYLEN]; 168 int keylen; 169 int dir; 170 int *modep; 171 Encryptions *(*getcrypt)(); 172 } ki[2] = { 173 { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption }, 174 { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption }, 175 }; 176 177 void 178 encrypt_init(name, server) 179 char *name; 180 int server; 181 { 182 Encryptions *ep = encryptions; 183 184 Name = name; 185 Server = server; 186 i_support_encrypt = i_support_decrypt = 0; 187 remote_supports_encrypt = remote_supports_decrypt = 0; 188 encrypt_mode = 0; 189 decrypt_mode = 0; 190 encrypt_output = 0; 191 decrypt_input = 0; 192 #ifdef notdef 193 encrypt_verbose = !server; 194 #endif 195 196 str_suplen = 4; 197 198 while (ep->type) { 199 if (encrypt_debug_mode) 200 printf(">>>%s: I will support %s\r\n", 201 Name, ENCTYPE_NAME(ep->type)); 202 i_support_encrypt |= typemask(ep->type); 203 i_support_decrypt |= typemask(ep->type); 204 if ((i_wont_support_decrypt & typemask(ep->type)) == 0) 205 if ((str_send[str_suplen++] = ep->type) == IAC) 206 str_send[str_suplen++] = IAC; 207 if (ep->init) 208 (*ep->init)(Server); 209 ++ep; 210 } 211 str_send[str_suplen++] = IAC; 212 str_send[str_suplen++] = SE; 213 } 214 215 void 216 encrypt_list_types() 217 { 218 Encryptions *ep = encryptions; 219 220 printf("Valid encryption types:\n"); 221 while (ep->type) { 222 printf("\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type); 223 ++ep; 224 } 225 } 226 227 int 228 EncryptEnable(type, mode) 229 char *type, *mode; 230 { 231 if (isprefix(type, "help") || isprefix(type, "?")) { 232 printf("Usage: encrypt enable <type> [input|output]\n"); 233 encrypt_list_types(); 234 return(0); 235 } 236 if (EncryptType(type, mode)) 237 return(EncryptStart(mode)); 238 return(0); 239 } 240 241 int 242 EncryptDisable(type, mode) 243 char *type, *mode; 244 { 245 register Encryptions *ep; 246 int ret = 0; 247 248 if (isprefix(type, "help") || isprefix(type, "?")) { 249 printf("Usage: encrypt disable <type> [input|output]\n"); 250 encrypt_list_types(); 251 } else if ((ep = (Encryptions *)genget(type, encryptions, 252 sizeof(Encryptions))) == 0) { 253 printf("%s: invalid encryption type\n", type); 254 } else if (Ambiguous(ep)) { 255 printf("Ambiguous type '%s'\n", type); 256 } else { 257 if ((mode == 0) || (isprefix(mode, "input") ? 1 : 0)) { 258 if (decrypt_mode == ep->type) 259 EncryptStopInput(); 260 i_wont_support_decrypt |= typemask(ep->type); 261 ret = 1; 262 } 263 if ((mode == 0) || (isprefix(mode, "output"))) { 264 if (encrypt_mode == ep->type) 265 EncryptStopOutput(); 266 i_wont_support_encrypt |= typemask(ep->type); 267 ret = 1; 268 } 269 if (ret == 0) 270 printf("%s: invalid encryption mode\n", mode); 271 } 272 return(ret); 273 } 274 275 int 276 EncryptType(type, mode) 277 char *type; 278 char *mode; 279 { 280 register Encryptions *ep; 281 int ret = 0; 282 283 if (isprefix(type, "help") || isprefix(type, "?")) { 284 printf("Usage: encrypt type <type> [input|output]\n"); 285 encrypt_list_types(); 286 } else if ((ep = (Encryptions *)genget(type, encryptions, 287 sizeof(Encryptions))) == 0) { 288 printf("%s: invalid encryption type\n", type); 289 } else if (Ambiguous(ep)) { 290 printf("Ambiguous type '%s'\n", type); 291 } else { 292 if ((mode == 0) || isprefix(mode, "input")) { 293 decrypt_mode = ep->type; 294 i_wont_support_decrypt &= ~typemask(ep->type); 295 ret = 1; 296 } 297 if ((mode == 0) || isprefix(mode, "output")) { 298 encrypt_mode = ep->type; 299 i_wont_support_encrypt &= ~typemask(ep->type); 300 ret = 1; 301 } 302 if (ret == 0) 303 printf("%s: invalid encryption mode\n", mode); 304 } 305 return(ret); 306 } 307 308 int 309 EncryptStart(mode) 310 char *mode; 311 { 312 register int ret = 0; 313 if (mode) { 314 if (isprefix(mode, "input")) 315 return(EncryptStartInput()); 316 if (isprefix(mode, "output")) 317 return(EncryptStartOutput()); 318 if (isprefix(mode, "help") || isprefix(mode, "?")) { 319 printf("Usage: encrypt start [input|output]\n"); 320 return(0); 321 } 322 printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode); 323 return(0); 324 } 325 ret += EncryptStartInput(); 326 ret += EncryptStartOutput(); 327 return(ret); 328 } 329 330 int 331 EncryptStartInput() 332 { 333 if (decrypt_mode) { 334 encrypt_send_request_start(); 335 return(1); 336 } 337 printf("No previous decryption mode, decryption not enabled\r\n"); 338 return(0); 339 } 340 341 int 342 EncryptStartOutput() 343 { 344 if (encrypt_mode) { 345 encrypt_start_output(encrypt_mode); 346 return(1); 347 } 348 printf("No previous encryption mode, encryption not enabled\r\n"); 349 return(0); 350 } 351 352 int 353 EncryptStop(mode) 354 char *mode; 355 { 356 int ret = 0; 357 if (mode) { 358 if (isprefix(mode, "input")) 359 return(EncryptStopInput()); 360 if (isprefix(mode, "output")) 361 return(EncryptStopOutput()); 362 if (isprefix(mode, "help") || isprefix(mode, "?")) { 363 printf("Usage: encrypt stop [input|output]\n"); 364 return(0); 365 } 366 printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode); 367 return(0); 368 } 369 ret += EncryptStopInput(); 370 ret += EncryptStopOutput(); 371 return(ret); 372 } 373 374 int 375 EncryptStopInput() 376 { 377 encrypt_send_request_end(); 378 return(1); 379 } 380 381 int 382 EncryptStopOutput() 383 { 384 encrypt_send_end(); 385 return(1); 386 } 387 388 void 389 encrypt_display() 390 { 391 if (encrypt_output) 392 printf("Currently encrypting output with %s\r\n", 393 ENCTYPE_NAME(encrypt_mode)); 394 if (decrypt_input) 395 printf("Currently decrypting input with %s\r\n", 396 ENCTYPE_NAME(decrypt_mode)); 397 } 398 399 int 400 EncryptStatus() 401 { 402 if (encrypt_output) 403 printf("Currently encrypting output with %s\r\n", 404 ENCTYPE_NAME(encrypt_mode)); 405 else if (encrypt_mode) { 406 printf("Currently output is clear text.\r\n"); 407 printf("Last encryption mode was %s\r\n", 408 ENCTYPE_NAME(encrypt_mode)); 409 } 410 if (decrypt_input) { 411 printf("Currently decrypting input with %s\r\n", 412 ENCTYPE_NAME(decrypt_mode)); 413 } else if (decrypt_mode) { 414 printf("Currently input is clear text.\r\n"); 415 printf("Last decryption mode was %s\r\n", 416 ENCTYPE_NAME(decrypt_mode)); 417 } 418 return 1; 419 } 420 421 void 422 encrypt_send_support() 423 { 424 if (str_suplen) { 425 /* 426 * If the user has requested that decryption start 427 * immediatly, then send a "REQUEST START" before 428 * we negotiate the type. 429 */ 430 if (!Server && autodecrypt) 431 encrypt_send_request_start(); 432 net_write(str_send, str_suplen); 433 printsub('>', &str_send[2], str_suplen - 2); 434 str_suplen = 0; 435 } 436 } 437 438 int 439 EncryptDebug(on) 440 int on; 441 { 442 if (on < 0) 443 encrypt_debug_mode ^= 1; 444 else 445 encrypt_debug_mode = on; 446 printf("Encryption debugging %s\r\n", 447 encrypt_debug_mode ? "enabled" : "disabled"); 448 return(1); 449 } 450 451 int 452 EncryptVerbose(on) 453 int on; 454 { 455 if (on < 0) 456 encrypt_verbose ^= 1; 457 else 458 encrypt_verbose = on; 459 printf("Encryption %s verbose\r\n", 460 encrypt_verbose ? "is" : "is not"); 461 return(1); 462 } 463 464 int 465 EncryptAutoEnc(on) 466 int on; 467 { 468 encrypt_auto(on); 469 printf("Automatic encryption of output is %s\r\n", 470 autoencrypt ? "enabled" : "disabled"); 471 return(1); 472 } 473 474 int 475 EncryptAutoDec(on) 476 int on; 477 { 478 decrypt_auto(on); 479 printf("Automatic decryption of input is %s\r\n", 480 autodecrypt ? "enabled" : "disabled"); 481 return(1); 482 } 483 484 /* 485 * Called when ENCRYPT SUPPORT is received. 486 */ 487 void 488 encrypt_support(typelist, cnt) 489 unsigned char *typelist; 490 int cnt; 491 { 492 register int type, use_type = 0; 493 Encryptions *ep; 494 495 /* 496 * Forget anything the other side has previously told us. 497 */ 498 remote_supports_decrypt = 0; 499 500 while (cnt-- > 0) { 501 type = *typelist++; 502 if (encrypt_debug_mode) 503 printf(">>>%s: He is supporting %s (%d)\r\n", 504 Name, 505 ENCTYPE_NAME(type), type); 506 if ((type < ENCTYPE_CNT) && 507 (I_SUPPORT_ENCRYPT & typemask(type))) { 508 remote_supports_decrypt |= typemask(type); 509 if (use_type == 0) 510 use_type = type; 511 } 512 } 513 if (use_type) { 514 ep = findencryption(use_type); 515 if (!ep) 516 return; 517 type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0; 518 if (encrypt_debug_mode) 519 printf(">>>%s: (*ep->start)() returned %d\r\n", 520 Name, type); 521 if (type < 0) 522 return; 523 encrypt_mode = use_type; 524 if (type == 0) 525 encrypt_start_output(use_type); 526 } 527 } 528 529 void 530 encrypt_is(data, cnt) 531 unsigned char *data; 532 int cnt; 533 { 534 Encryptions *ep; 535 register int type, ret; 536 537 if (--cnt < 0) 538 return; 539 type = *data++; 540 if (type < ENCTYPE_CNT) 541 remote_supports_encrypt |= typemask(type); 542 if (!(ep = finddecryption(type))) { 543 if (encrypt_debug_mode) 544 printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 545 Name, 546 ENCTYPE_NAME_OK(type) 547 ? ENCTYPE_NAME(type) : "(unknown)", 548 type); 549 return; 550 } 551 if (!ep->is) { 552 if (encrypt_debug_mode) 553 printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 554 Name, 555 ENCTYPE_NAME_OK(type) 556 ? ENCTYPE_NAME(type) : "(unknown)", 557 type); 558 ret = 0; 559 } else { 560 ret = (*ep->is)(data, cnt); 561 if (encrypt_debug_mode) 562 printf("(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt, 563 (ret < 0) ? "FAIL " : 564 (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 565 } 566 if (ret < 0) { 567 autodecrypt = 0; 568 } else { 569 decrypt_mode = type; 570 if (ret == 0 && autodecrypt) 571 encrypt_send_request_start(); 572 } 573 } 574 575 void 576 encrypt_reply(data, cnt) 577 unsigned char *data; 578 int cnt; 579 { 580 Encryptions *ep; 581 register int ret, type; 582 583 if (--cnt < 0) 584 return; 585 type = *data++; 586 if (!(ep = findencryption(type))) { 587 if (encrypt_debug_mode) 588 printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 589 Name, 590 ENCTYPE_NAME_OK(type) 591 ? ENCTYPE_NAME(type) : "(unknown)", 592 type); 593 return; 594 } 595 if (!ep->reply) { 596 if (encrypt_debug_mode) 597 printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 598 Name, 599 ENCTYPE_NAME_OK(type) 600 ? ENCTYPE_NAME(type) : "(unknown)", 601 type); 602 ret = 0; 603 } else { 604 ret = (*ep->reply)(data, cnt); 605 if (encrypt_debug_mode) 606 printf("(*ep->reply)(%x, %d) returned %s(%d)\n", 607 data, cnt, 608 (ret < 0) ? "FAIL " : 609 (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 610 } 611 if (encrypt_debug_mode) 612 printf(">>>%s: encrypt_reply returned %d\n", Name, ret); 613 if (ret < 0) { 614 autoencrypt = 0; 615 } else { 616 encrypt_mode = type; 617 if (ret == 0 && autoencrypt) 618 encrypt_start_output(type); 619 } 620 } 621 622 /* 623 * Called when a ENCRYPT START command is received. 624 */ 625 void 626 encrypt_start(data, cnt) 627 unsigned char *data; 628 int cnt; 629 { 630 Encryptions *ep; 631 632 if (!decrypt_mode) { 633 /* 634 * Something is wrong. We should not get a START 635 * command without having already picked our 636 * decryption scheme. Send a REQUEST-END to 637 * attempt to clear the channel... 638 */ 639 printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name); 640 encrypt_send_request_end(); 641 return; 642 } 643 644 if (ep = finddecryption(decrypt_mode)) { 645 decrypt_input = ep->input; 646 if (encrypt_verbose) 647 printf("[ Input is now decrypted with type %s ]\r\n", 648 ENCTYPE_NAME(decrypt_mode)); 649 if (encrypt_debug_mode) 650 printf(">>>%s: Start to decrypt input with type %s\r\n", 651 Name, ENCTYPE_NAME(decrypt_mode)); 652 } else { 653 printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n", 654 Name, 655 ENCTYPE_NAME_OK(decrypt_mode) 656 ? ENCTYPE_NAME(decrypt_mode) 657 : "(unknown)", 658 decrypt_mode); 659 encrypt_send_request_end(); 660 } 661 } 662 663 void 664 encrypt_session_key(key, server) 665 Session_Key *key; 666 int server; 667 { 668 Encryptions *ep = encryptions; 669 670 havesessionkey = 1; 671 672 while (ep->type) { 673 if (ep->session) 674 (*ep->session)(key, server); 675 ++ep; 676 } 677 } 678 679 /* 680 * Called when ENCRYPT END is received. 681 */ 682 void 683 encrypt_end() 684 { 685 decrypt_input = 0; 686 if (encrypt_debug_mode) 687 printf(">>>%s: Input is back to clear text\r\n", Name); 688 if (encrypt_verbose) 689 printf("[ Input is now clear text ]\r\n"); 690 } 691 692 /* 693 * Called when ENCRYPT REQUEST-END is received. 694 */ 695 void 696 encrypt_request_end() 697 { 698 encrypt_send_end(); 699 } 700 701 /* 702 * Called when ENCRYPT REQUEST-START is received. If we receive 703 * this before a type is picked, then that indicates that the 704 * other side wants us to start encrypting data as soon as we 705 * can. 706 */ 707 void 708 encrypt_request_start(data, cnt) 709 unsigned char *data; 710 int cnt; 711 { 712 if (encrypt_mode == 0) { 713 if (Server) 714 autoencrypt = 1; 715 return; 716 } 717 encrypt_start_output(encrypt_mode); 718 } 719 720 static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT }; 721 722 encrypt_enc_keyid(keyid, len) 723 unsigned char *keyid; 724 int len; 725 { 726 encrypt_keyid(&ki[1], keyid, len); 727 } 728 729 encrypt_dec_keyid(keyid, len) 730 unsigned char *keyid; 731 int len; 732 { 733 encrypt_keyid(&ki[0], keyid, len); 734 } 735 736 encrypt_keyid(kp, keyid, len) 737 struct key_info *kp; 738 unsigned char *keyid; 739 int len; 740 { 741 Encryptions *ep; 742 unsigned char *strp, *cp; 743 int dir = kp->dir; 744 register int ret = 0; 745 746 if (!(ep = (*kp->getcrypt)(*kp->modep))) { 747 if (len == 0) 748 return; 749 kp->keylen = 0; 750 } else if (len == 0) { 751 /* 752 * Empty option, indicates a failure. 753 */ 754 if (kp->keylen == 0) 755 return; 756 kp->keylen = 0; 757 if (ep->keyid) 758 (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); 759 760 } else if ((len != kp->keylen) || (bcmp(keyid, kp->keyid, len) != 0)) { 761 /* 762 * Length or contents are different 763 */ 764 kp->keylen = len; 765 bcopy(keyid, kp->keyid, len); 766 if (ep->keyid) 767 (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); 768 } else { 769 if (ep->keyid) 770 ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen); 771 if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt) 772 encrypt_start_output(*kp->modep); 773 return; 774 } 775 776 encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0); 777 } 778 779 void 780 encrypt_send_keyid(dir, keyid, keylen, saveit) 781 int dir; 782 unsigned char *keyid; 783 int keylen; 784 int saveit; 785 { 786 unsigned char *strp; 787 788 str_keyid[3] = (dir == DIR_ENCRYPT) 789 ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID; 790 if (saveit) { 791 struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1]; 792 bcopy(keyid, kp->keyid, keylen); 793 kp->keylen = keylen; 794 } 795 796 for (strp = &str_keyid[4]; keylen > 0; --keylen) { 797 if ((*strp++ = *keyid++) == IAC) 798 *strp++ = IAC; 799 } 800 *strp++ = IAC; 801 *strp++ = SE; 802 net_write(str_keyid, strp - str_keyid); 803 printsub('>', &str_keyid[2], strp - str_keyid - 2); 804 } 805 806 void 807 encrypt_auto(on) 808 int on; 809 { 810 if (on < 0) 811 autoencrypt ^= 1; 812 else 813 autoencrypt = on ? 1 : 0; 814 } 815 816 void 817 decrypt_auto(on) 818 int on; 819 { 820 if (on < 0) 821 autodecrypt ^= 1; 822 else 823 autodecrypt = on ? 1 : 0; 824 } 825 826 void 827 encrypt_start_output(type) 828 int type; 829 { 830 Encryptions *ep; 831 register unsigned char *p; 832 register int i; 833 834 if (!(ep = findencryption(type))) { 835 if (encrypt_debug_mode) { 836 printf(">>>%s: Can't encrypt with type %s (%d)\r\n", 837 Name, 838 ENCTYPE_NAME_OK(type) 839 ? ENCTYPE_NAME(type) : "(unknown)", 840 type); 841 } 842 return; 843 } 844 if (ep->start) { 845 i = (*ep->start)(DIR_ENCRYPT, Server); 846 if (encrypt_debug_mode) { 847 printf(">>>%s: Encrypt start: %s (%d) %s\r\n", 848 Name, 849 (i < 0) ? "failed" : 850 "initial negotiation in progress", 851 i, ENCTYPE_NAME(type)); 852 } 853 if (i) 854 return; 855 } 856 p = str_start + 3; 857 *p++ = ENCRYPT_START; 858 for (i = 0; i < ki[0].keylen; ++i) { 859 if ((*p++ = ki[0].keyid[i]) == IAC) 860 *p++ = IAC; 861 } 862 *p++ = IAC; 863 *p++ = SE; 864 net_write(str_start, p - str_start); 865 net_encrypt(); 866 printsub('>', &str_start[2], p - &str_start[2]); 867 /* 868 * If we are already encrypting in some mode, then 869 * encrypt the ring (which includes our request) in 870 * the old mode, mark it all as "clear text" and then 871 * switch to the new mode. 872 */ 873 encrypt_output = ep->output; 874 encrypt_mode = type; 875 if (encrypt_debug_mode) 876 printf(">>>%s: Started to encrypt output with type %s\r\n", 877 Name, ENCTYPE_NAME(type)); 878 if (encrypt_verbose) 879 printf("[ Output is now encrypted with type %s ]\r\n", 880 ENCTYPE_NAME(type)); 881 } 882 883 void 884 encrypt_send_end() 885 { 886 if (!encrypt_output) 887 return; 888 889 str_end[3] = ENCRYPT_END; 890 net_write(str_end, sizeof(str_end)); 891 net_encrypt(); 892 printsub('>', &str_end[2], sizeof(str_end) - 2); 893 /* 894 * Encrypt the output buffer now because it will not be done by 895 * netflush... 896 */ 897 encrypt_output = 0; 898 if (encrypt_debug_mode) 899 printf(">>>%s: Output is back to clear text\r\n", Name); 900 if (encrypt_verbose) 901 printf("[ Output is now clear text ]\r\n"); 902 } 903 904 void 905 encrypt_send_request_start() 906 { 907 register unsigned char *p; 908 register int i; 909 910 p = &str_start[3]; 911 *p++ = ENCRYPT_REQSTART; 912 for (i = 0; i < ki[1].keylen; ++i) { 913 if ((*p++ = ki[1].keyid[i]) == IAC) 914 *p++ = IAC; 915 } 916 *p++ = IAC; 917 *p++ = SE; 918 net_write(str_start, p - str_start); 919 printsub('>', &str_start[2], p - &str_start[2]); 920 if (encrypt_debug_mode) 921 printf(">>>%s: Request input to be encrypted\r\n", Name); 922 } 923 924 void 925 encrypt_send_request_end() 926 { 927 str_end[3] = ENCRYPT_REQEND; 928 net_write(str_end, sizeof(str_end)); 929 printsub('>', &str_end[2], sizeof(str_end) - 2); 930 931 if (encrypt_debug_mode) 932 printf(">>>%s: Request input to be clear text\r\n", Name); 933 } 934 935 void 936 encrypt_wait() 937 { 938 register int encrypt, decrypt; 939 if (encrypt_debug_mode) 940 printf(">>>%s: in encrypt_wait\r\n", Name); 941 if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt)) 942 return; 943 while (autoencrypt && !encrypt_output) 944 if (telnet_spin()) 945 return; 946 } 947 948 void 949 encrypt_debug(mode) 950 int mode; 951 { 952 encrypt_debug_mode = mode; 953 } 954 955 void 956 encrypt_gen_printsub(data, cnt, buf, buflen) 957 unsigned char *data, *buf; 958 int cnt, buflen; 959 { 960 char tbuf[16], *cp; 961 962 cnt -= 2; 963 data += 2; 964 buf[buflen-1] = '\0'; 965 buf[buflen-2] = '*'; 966 buflen -= 2;; 967 for (; cnt > 0; cnt--, data++) { 968 sprintf(tbuf, " %d", *data); 969 for (cp = tbuf; *cp && buflen > 0; --buflen) 970 *buf++ = *cp++; 971 if (buflen <= 0) 972 return; 973 } 974 *buf = '\0'; 975 } 976 977 void 978 encrypt_printsub(data, cnt, buf, buflen) 979 unsigned char *data, *buf; 980 int cnt, buflen; 981 { 982 Encryptions *ep; 983 register int type = data[1]; 984 985 for (ep = encryptions; ep->type && ep->type != type; ep++) 986 ; 987 988 if (ep->printsub) 989 (*ep->printsub)(data, cnt, buf, buflen); 990 else 991 encrypt_gen_printsub(data, cnt, buf, buflen); 992 } 993 #endif 994