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