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