encrypt.c revision 29088
1/*- 2 * Copyright (c) 1991, 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#ifndef lint 35static char sccsid[] = "@(#)encrypt.c 8.2 (Berkeley) 5/30/95"; 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#ifdef ENCRYPTION 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 */ 79void (*encrypt_output) P((unsigned char *, int)); 80int (*decrypt_input) P((int)); 81 82int encrypt_debug_mode = 0; 83static int decrypt_mode = 0; 84static int encrypt_mode = 0; 85static int encrypt_verbose = 0; 86static int autoencrypt = 0; 87static int autodecrypt = 0; 88static int havesessionkey = 0; 89static int Server = 0; 90static char *Name = "Noname"; 91 92#define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 93 94static long i_support_encrypt = typemask(ENCTYPE_DES_CFB64) 95 | typemask(ENCTYPE_DES_OFB64); 96static long i_support_decrypt = typemask(ENCTYPE_DES_CFB64) 97 | typemask(ENCTYPE_DES_OFB64); 98static long i_wont_support_encrypt = 0; 99static 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 103static long remote_supports_encrypt = 0; 104static long remote_supports_decrypt = 0; 105 106static Encryptions encryptions[] = { 107#ifdef DES_ENCRYPTION 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 /* DES_ENCRYPTION */ 129 { 0, }, 130}; 131 132static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, 133 ENCRYPT_SUPPORT }; 134static unsigned char str_suplen = 0; 135static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT }; 136static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; 137 138 Encryptions * 139findencryption(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 * 152finddecryption(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 166static 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 178encrypt_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 216encrypt_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 228EncryptEnable(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 242EncryptDisable(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 276EncryptType(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 309EncryptStart(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 331EncryptStartInput() 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 342EncryptStartOutput() 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 353EncryptStop(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 375EncryptStopInput() 376{ 377 encrypt_send_request_end(); 378 return(1); 379} 380 381 int 382EncryptStopOutput() 383{ 384 encrypt_send_end(); 385 return(1); 386} 387 388 void 389encrypt_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 400EncryptStatus() 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 422encrypt_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 439EncryptDebug(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 452EncryptVerbose(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 465EncryptAutoEnc(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 475EncryptAutoDec(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 488encrypt_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 530encrypt_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 576encrypt_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 626encrypt_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 664encrypt_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#ifdef notdef 676 if (!encrypt_output && autoencrypt && !server) 677 encrypt_start_output(ep->type); 678 if (!decrypt_input && autodecrypt && !server) 679 encrypt_send_request_start(); 680#endif 681 ++ep; 682 } 683} 684 685/* 686 * Called when ENCRYPT END is received. 687 */ 688 void 689encrypt_end() 690{ 691 decrypt_input = 0; 692 if (encrypt_debug_mode) 693 printf(">>>%s: Input is back to clear text\r\n", Name); 694 if (encrypt_verbose) 695 printf("[ Input is now clear text ]\r\n"); 696} 697 698/* 699 * Called when ENCRYPT REQUEST-END is received. 700 */ 701 void 702encrypt_request_end() 703{ 704 encrypt_send_end(); 705} 706 707/* 708 * Called when ENCRYPT REQUEST-START is received. If we receive 709 * this before a type is picked, then that indicates that the 710 * other side wants us to start encrypting data as soon as we 711 * can. 712 */ 713 void 714encrypt_request_start(data, cnt) 715 unsigned char *data; 716 int cnt; 717{ 718 if (encrypt_mode == 0) { 719 if (Server) 720 autoencrypt = 1; 721 return; 722 } 723 encrypt_start_output(encrypt_mode); 724} 725 726static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT }; 727 728encrypt_enc_keyid(keyid, len) 729 unsigned char *keyid; 730 int len; 731{ 732 encrypt_keyid(&ki[1], keyid, len); 733} 734 735encrypt_dec_keyid(keyid, len) 736 unsigned char *keyid; 737 int len; 738{ 739 encrypt_keyid(&ki[0], keyid, len); 740} 741 742encrypt_keyid(kp, keyid, len) 743 struct key_info *kp; 744 unsigned char *keyid; 745 int len; 746{ 747 Encryptions *ep; 748 unsigned char *strp, *cp; 749 int dir = kp->dir; 750 register int ret = 0; 751 752 if (!(ep = (*kp->getcrypt)(*kp->modep))) { 753 if (len == 0) 754 return; 755 kp->keylen = 0; 756 } else if (len == 0) { 757 /* 758 * Empty option, indicates a failure. 759 */ 760 if (kp->keylen == 0) 761 return; 762 kp->keylen = 0; 763 if (ep->keyid) 764 (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); 765 766 } else if ((len != kp->keylen) || 767 (memcmp(keyid, kp->keyid, len) != 0)) { 768 /* 769 * Length or contents are different 770 */ 771 kp->keylen = len; 772 memmove(kp->keyid, keyid, len); 773 if (ep->keyid) 774 (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); 775 } else { 776 if (ep->keyid) 777 ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen); 778 if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt) 779 encrypt_start_output(*kp->modep); 780 return; 781 } 782 783 encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0); 784} 785 786 void 787encrypt_send_keyid(dir, keyid, keylen, saveit) 788 int dir; 789 unsigned char *keyid; 790 int keylen; 791 int saveit; 792{ 793 unsigned char *strp; 794 795 str_keyid[3] = (dir == DIR_ENCRYPT) 796 ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID; 797 if (saveit) { 798 struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1]; 799 memmove(kp->keyid, keyid, keylen); 800 kp->keylen = keylen; 801 } 802 803 for (strp = &str_keyid[4]; keylen > 0; --keylen) { 804 if ((*strp++ = *keyid++) == IAC) 805 *strp++ = IAC; 806 } 807 *strp++ = IAC; 808 *strp++ = SE; 809 net_write(str_keyid, strp - str_keyid); 810 printsub('>', &str_keyid[2], strp - str_keyid - 2); 811} 812 813 void 814encrypt_auto(on) 815 int on; 816{ 817 if (on < 0) 818 autoencrypt ^= 1; 819 else 820 autoencrypt = on ? 1 : 0; 821} 822 823 void 824decrypt_auto(on) 825 int on; 826{ 827 if (on < 0) 828 autodecrypt ^= 1; 829 else 830 autodecrypt = on ? 1 : 0; 831} 832 833 void 834encrypt_start_output(type) 835 int type; 836{ 837 Encryptions *ep; 838 register unsigned char *p; 839 register int i; 840 841 if (!(ep = findencryption(type))) { 842 if (encrypt_debug_mode) { 843 printf(">>>%s: Can't encrypt with type %s (%d)\r\n", 844 Name, 845 ENCTYPE_NAME_OK(type) 846 ? ENCTYPE_NAME(type) : "(unknown)", 847 type); 848 } 849 return; 850 } 851 if (ep->start) { 852 i = (*ep->start)(DIR_ENCRYPT, Server); 853 if (encrypt_debug_mode) { 854 printf(">>>%s: Encrypt start: %s (%d) %s\r\n", 855 Name, 856 (i < 0) ? "failed" : 857 "initial negotiation in progress", 858 i, ENCTYPE_NAME(type)); 859 } 860 if (i) 861 return; 862 } 863 p = str_start + 3; 864 *p++ = ENCRYPT_START; 865 for (i = 0; i < ki[0].keylen; ++i) { 866 if ((*p++ = ki[0].keyid[i]) == IAC) 867 *p++ = IAC; 868 } 869 *p++ = IAC; 870 *p++ = SE; 871 net_write(str_start, p - str_start); 872 net_encrypt(); 873 printsub('>', &str_start[2], p - &str_start[2]); 874 /* 875 * If we are already encrypting in some mode, then 876 * encrypt the ring (which includes our request) in 877 * the old mode, mark it all as "clear text" and then 878 * switch to the new mode. 879 */ 880 encrypt_output = ep->output; 881 encrypt_mode = type; 882 if (encrypt_debug_mode) 883 printf(">>>%s: Started to encrypt output with type %s\r\n", 884 Name, ENCTYPE_NAME(type)); 885 if (encrypt_verbose) 886 printf("[ Output is now encrypted with type %s ]\r\n", 887 ENCTYPE_NAME(type)); 888} 889 890 void 891encrypt_send_end() 892{ 893 if (!encrypt_output) 894 return; 895 896 str_end[3] = ENCRYPT_END; 897 net_write(str_end, sizeof(str_end)); 898 net_encrypt(); 899 printsub('>', &str_end[2], sizeof(str_end) - 2); 900 /* 901 * Encrypt the output buffer now because it will not be done by 902 * netflush... 903 */ 904 encrypt_output = 0; 905 if (encrypt_debug_mode) 906 printf(">>>%s: Output is back to clear text\r\n", Name); 907 if (encrypt_verbose) 908 printf("[ Output is now clear text ]\r\n"); 909} 910 911 void 912encrypt_send_request_start() 913{ 914 register unsigned char *p; 915 register int i; 916 917 p = &str_start[3]; 918 *p++ = ENCRYPT_REQSTART; 919 for (i = 0; i < ki[1].keylen; ++i) { 920 if ((*p++ = ki[1].keyid[i]) == IAC) 921 *p++ = IAC; 922 } 923 *p++ = IAC; 924 *p++ = SE; 925 net_write(str_start, p - str_start); 926 printsub('>', &str_start[2], p - &str_start[2]); 927 if (encrypt_debug_mode) 928 printf(">>>%s: Request input to be encrypted\r\n", Name); 929} 930 931 void 932encrypt_send_request_end() 933{ 934 str_end[3] = ENCRYPT_REQEND; 935 net_write(str_end, sizeof(str_end)); 936 printsub('>', &str_end[2], sizeof(str_end) - 2); 937 938 if (encrypt_debug_mode) 939 printf(">>>%s: Request input to be clear text\r\n", Name); 940} 941 942 void 943encrypt_wait() 944{ 945 register int encrypt, decrypt; 946 if (encrypt_debug_mode) 947 printf(">>>%s: in encrypt_wait\r\n", Name); 948 if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt)) 949 return; 950 while (autoencrypt && !encrypt_output) 951 if (telnet_spin()) 952 return; 953} 954 955 void 956encrypt_debug(mode) 957 int mode; 958{ 959 encrypt_debug_mode = mode; 960} 961 962 void 963encrypt_gen_printsub(data, cnt, buf, buflen) 964 unsigned char *data, *buf; 965 int cnt, buflen; 966{ 967 char tbuf[16], *cp; 968 969 cnt -= 2; 970 data += 2; 971 buf[buflen-1] = '\0'; 972 buf[buflen-2] = '*'; 973 buflen -= 2;; 974 for (; cnt > 0; cnt--, data++) { 975 sprintf(tbuf, " %d", *data); 976 for (cp = tbuf; *cp && buflen > 0; --buflen) 977 *buf++ = *cp++; 978 if (buflen <= 0) 979 return; 980 } 981 *buf = '\0'; 982} 983 984 void 985encrypt_printsub(data, cnt, buf, buflen) 986 unsigned char *data, *buf; 987 int cnt, buflen; 988{ 989 Encryptions *ep; 990 register int type = data[1]; 991 992 for (ep = encryptions; ep->type && ep->type != type; ep++) 993 ; 994 995 if (ep->printsub) 996 (*ep->printsub)(data, cnt, buf, buflen); 997 else 998 encrypt_gen_printsub(data, cnt, buf, buflen); 999} 1000#endif /* ENCRYPTION */ 1001