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