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