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