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