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