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