1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)encrypt.c 5.1 (Berkeley) 02/28/91"; 10 #endif /* not lint */ 11 12 /* 13 * Copyright (C) 1990 by the Massachusetts Institute of Technology 14 * 15 * Export of this software from the United States of America is assumed 16 * to require a specific license from the United States Government. 17 * It is the responsibility of any person or organization contemplating 18 * export to obtain such a license before exporting. 19 * 20 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 21 * distribute this software and its documentation for any purpose and 22 * without fee is hereby granted, provided that the above copyright 23 * notice appear in all copies and that both that copyright notice and 24 * this permission notice appear in supporting documentation, and that 25 * the name of M.I.T. not be used in advertising or publicity pertaining 26 * to distribution of the software without specific, written prior 27 * permission. M.I.T. makes no representations about the suitability of 28 * this software for any purpose. It is provided "as is" without express 29 * or implied warranty. 30 */ 31 32 #if defined(ENCRYPT) 33 34 #define ENCRYPT_NAMES 35 #include <arpa/telnet.h> 36 37 #include "encrypt.h" 38 #include "misc.h" 39 40 #ifdef __STDC__ 41 #include <stdlib.h> 42 #endif 43 #ifdef NO_STRING_H 44 #include <strings.h> 45 #else 46 #include <string.h> 47 #endif 48 49 /* 50 * These functions pointers point to the current routines 51 * for encrypting and decrypting data. 52 */ 53 void (*encrypt_output) P((unsigned char *, int)); 54 int (*decrypt_input) P((int)); 55 56 int encrypt_debug_mode = 0; 57 static int decrypt_mode = 0; 58 static int encrypt_mode = 0; 59 static int encrypt_verbose = 0; 60 static int autoencrypt = 0; 61 static int autodecrypt = 0; 62 static int havesessionkey = 0; 63 static int encrypt_mark = 0; 64 static int decrypt_mark = 0; 65 static int Server = 0; 66 static char *Name = "Noname"; 67 68 #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 69 70 static long i_support_encrypt = typemask(ENCTYPE_KRBDES); 71 static long i_support_decrypt = typemask(ENCTYPE_KRBDES); 72 static long remote_supports_encrypt = 0; 73 static long remote_supports_decrypt = 0; 74 75 static Encryptions encryptions[] = { 76 #if defined(KRBDES_ENCRYPT) 77 { "KRBDES", ENCTYPE_KRBDES, 78 krbdes_encrypt, 79 krbdes_decrypt, 80 krbdes_init, 81 krbdes_start, 82 krbdes_is, 83 krbdes_reply, 84 krbdes_session, 85 krbdes_printsub }, 86 #endif 87 { 0, }, 88 }; 89 90 static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, 91 ENCRYPT_SUPPORT, }; 92 static unsigned char str_suplen = 0; 93 static unsigned char str_start[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; 94 static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; 95 96 Encryptions * 97 findencryption(type) 98 int type; 99 { 100 Encryptions *ep = encryptions; 101 102 if (!(i_support_encrypt & remote_supports_decrypt & typemask(type))) 103 return(0); 104 while (ep->type && ep->type != type) 105 ++ep; 106 return(ep->type ? ep : 0); 107 } 108 109 Encryptions * 110 finddecryption(type) 111 int type; 112 { 113 Encryptions *ep = encryptions; 114 115 if (!(i_support_decrypt & remote_supports_encrypt & typemask(type))) 116 return(0); 117 while (ep->type && ep->type != type) 118 ++ep; 119 return(ep->type ? ep : 0); 120 } 121 122 void 123 encrypt_init(name, server) 124 char *name; 125 int server; 126 { 127 Encryptions *ep = encryptions; 128 129 Name = name; 130 Server = server; 131 i_support_encrypt = i_support_decrypt = 0; 132 remote_supports_encrypt = remote_supports_decrypt = 0; 133 encrypt_mode = 0; 134 decrypt_mode = 0; 135 encrypt_output = 0; 136 decrypt_input = 0; 137 #ifdef notdef 138 encrypt_verbose = !server; 139 #endif 140 141 str_suplen = 4; 142 143 while (ep->type) { 144 if (encrypt_debug_mode) 145 printf(">>>%s: I will support %s\r\n", 146 Name, ENCTYPE_NAME(ep->type)); 147 i_support_encrypt |= typemask(ep->type); 148 i_support_decrypt |= typemask(ep->type); 149 if ((str_send[str_suplen++] = ep->type) == IAC) 150 str_send[str_suplen++] = IAC; 151 if (ep->init) 152 (*ep->init)(Server); 153 ++ep; 154 } 155 str_send[str_suplen++] = IAC; 156 str_send[str_suplen++] = SE; 157 } 158 159 void 160 encrypt_list_types() 161 { 162 Encryptions *ep = encryptions; 163 164 printf("Valid encryption types:\n"); 165 while (ep->type) { 166 printf("\t%s\n\n", ENCTYPE_NAME(ep->type)); 167 ++ep; 168 } 169 } 170 171 int 172 EncryptEnable(type, mode) 173 char *type, *mode; 174 { 175 if (isprefix(type, "help") || isprefix(type, "?")) { 176 printf("Usage: encrypt enable <type> [input|output]\n"); 177 encrypt_list_types(); 178 return(0); 179 } 180 if (EncryptType(type, mode)) 181 return(EncryptStart(mode)); 182 return(0); 183 } 184 185 int 186 EncryptType(type, mode) 187 char *type; 188 char *mode; 189 { 190 register Encryptions *ep; 191 192 if (isprefix(type, "help") || isprefix(type, "?")) { 193 printf("Usage: encrypt type <type> [input|output]\n"); 194 encrypt_list_types(); 195 return(0); 196 } 197 198 ep = (Encryptions *)genget(type, encryptions, sizeof(Encryptions)); 199 200 if (ep == 0) { 201 printf("%s: invalid encryption type\n", type); 202 return(0); 203 } 204 if (Ambiguous(ep)) { 205 printf("Ambiguous type '%s'\n", type); 206 return(0); 207 } 208 209 if (mode) { 210 if (isprefix(mode, "input")) 211 decrypt_mode = ep->type; 212 else if (isprefix(mode, "output")) 213 encrypt_mode = ep->type; 214 else { 215 printf("%s: invalid encryption mode\n", mode); 216 return(0); 217 } 218 } else 219 decrypt_mode = encrypt_mode = ep->type; 220 return(1); 221 } 222 223 int 224 EncryptStart(mode) 225 char *mode; 226 { 227 register int ret = 0; 228 if (mode) { 229 if (isprefix(mode, "input")) 230 return(EncryptStartInput()); 231 if (isprefix(mode, "output")) 232 return(EncryptStartOutput()); 233 if (isprefix(mode, "help") || isprefix(mode, "?")) { 234 printf("Usage: encrypt start [input|output]\n"); 235 return(0); 236 } 237 printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode); 238 return(0); 239 } 240 ret += EncryptStartInput(); 241 ret += EncryptStartOutput(); 242 return(ret); 243 } 244 245 int 246 EncryptStartInput() 247 { 248 if (decrypt_mode) { 249 encrypt_send_request_start(); 250 return(1); 251 } 252 printf("No previous decryption mode, decryption not enabled\r\n"); 253 return(0); 254 } 255 256 int 257 EncryptStartOutput() 258 { 259 if (encrypt_mode) { 260 encrypt_start_output(encrypt_mode); 261 return(1); 262 } 263 printf("No previous encryption mode, encryption not enabled\r\n"); 264 return(0); 265 } 266 267 int 268 EncryptStop(mode) 269 char *mode; 270 { 271 int ret = 0; 272 if (mode) { 273 if (isprefix(mode, "input")) 274 return(EncryptStopInput()); 275 if (isprefix(mode, "output")) 276 return(EncryptStopOutput()); 277 if (isprefix(mode, "help") || isprefix(mode, "?")) { 278 printf("Usage: encrypt stop [input|output]\n"); 279 return(0); 280 } 281 printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode); 282 return(0); 283 } 284 ret += EncryptStopInput(); 285 ret += EncryptStopOutput(); 286 return(ret); 287 } 288 289 int 290 EncryptStopInput() 291 { 292 encrypt_send_request_end(); 293 return(1); 294 } 295 296 int 297 EncryptStopOutput() 298 { 299 encrypt_send_end(); 300 return(1); 301 } 302 303 void 304 encrypt_display() 305 { 306 if (encrypt_output) 307 printf("Currently encrypting output with %s\r\n", 308 ENCTYPE_NAME(encrypt_mode)); 309 if (decrypt_input) 310 printf("Currently decrypting input with %s\r\n", 311 ENCTYPE_NAME(decrypt_mode)); 312 } 313 314 int 315 EncryptStatus() 316 { 317 if (encrypt_output) 318 printf("Currently encrypting output with %s\r\n", 319 ENCTYPE_NAME(encrypt_mode)); 320 else if (encrypt_mode) { 321 printf("Currently output is clear text.\r\n"); 322 printf("Last encryption mode was %s\r\n", 323 ENCTYPE_NAME(encrypt_mode)); 324 } 325 if (decrypt_input) { 326 printf("Currently decrypting input with %s\r\n", 327 ENCTYPE_NAME(decrypt_mode)); 328 } else if (decrypt_mode) { 329 printf("Currently input is clear text.\r\n"); 330 printf("Last decryption mode was %s\r\n", 331 ENCTYPE_NAME(decrypt_mode)); 332 } 333 return 1; 334 } 335 336 void 337 encrypt_send_support() 338 { 339 if (str_suplen) { 340 /* 341 * If the user has requested that decryption start 342 * immediatly, then send a "REQUEST START" before 343 * we negotiate the type. 344 */ 345 if (!Server && autodecrypt) 346 encrypt_send_request_start(); 347 net_write(str_send, str_suplen); 348 printsub('>', &str_send[2], str_suplen - 2); 349 str_suplen = 0; 350 } 351 } 352 353 int 354 EncryptTogDebug() 355 { 356 encrypt_debug_mode ^= 1; 357 printf("Encryption debugging %s\r\n", 358 encrypt_debug_mode ? "enabled" : "disabled"); 359 return(1); 360 } 361 362 int 363 EncryptTogVerbose() 364 { 365 encrypt_verbose ^= 1; 366 printf("Encryption %s verbose\r\n", 367 encrypt_verbose ? "is" : "is not"); 368 return(1); 369 } 370 371 int 372 EncryptTogAuto() 373 { 374 autoencrypt ^= 1; 375 autodecrypt ^= 1; 376 printf("Automatic encryption of data is %s\r\n", 377 autoencrypt ? "enabled" : "disabled"); 378 return(1); 379 } 380 381 382 /* 383 * Called when ENCRYPT SUPPORT is received. 384 */ 385 void 386 encrypt_support(typelist, cnt) 387 unsigned char *typelist; 388 int cnt; 389 { 390 register int type, use_type = 0; 391 Encryptions *ep; 392 393 /* 394 * Forget anything the other side has previously told us. 395 */ 396 remote_supports_decrypt = 0; 397 398 while (cnt-- > 0) { 399 type = *typelist++; 400 if (encrypt_debug_mode) 401 printf(">>>%s: He is supporting %s (%d)\r\n", 402 Name, 403 ENCTYPE_NAME(type), type); 404 if ((type < ENCTYPE_CNT) && 405 (i_support_encrypt & typemask(type))) { 406 remote_supports_decrypt |= typemask(type); 407 if (use_type == 0) 408 use_type = type; 409 } 410 } 411 if (use_type) { 412 ep = findencryption(use_type); 413 if (!ep) 414 return; 415 type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0; 416 if (encrypt_debug_mode) 417 printf(">>>%s: (*ep->start)() returned %d\r\n", 418 Name, type); 419 if (type < 0) 420 return; 421 encrypt_mode = type; 422 if (type == 0) 423 encrypt_start_output(use_type); 424 } 425 } 426 427 void 428 encrypt_is(data, cnt) 429 unsigned char *data; 430 int cnt; 431 { 432 Encryptions *ep; 433 register int type, ret; 434 435 if (--cnt < 0) 436 return; 437 type = *data++; 438 if (type < ENCTYPE_CNT) 439 remote_supports_encrypt |= typemask(type); 440 if (!(ep = finddecryption(type))) { 441 if (encrypt_debug_mode) 442 printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 443 Name, 444 ENCTYPE_NAME(data[-1]), data[1]); 445 return; 446 } 447 if (!ep->is) { 448 if (encrypt_debug_mode) 449 printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 450 Name, 451 ENCTYPE_NAME(type), type); 452 ret = 0; 453 } else { 454 ret = (*ep->is)(data, cnt); 455 /*@*/ if (encrypt_debug_mode) 456 /*@*/ printf("(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt, 457 /*@*/ (ret < 0) ? "FAIL " : 458 /*@*/ (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 459 } 460 if (ret < 0) { 461 autodecrypt = 0; 462 } else { 463 decrypt_mode = type; 464 if (ret == 0 && autodecrypt) 465 encrypt_send_request_start(); 466 } 467 } 468 469 void 470 encrypt_reply(data, cnt) 471 unsigned char *data; 472 int cnt; 473 { 474 Encryptions *ep; 475 register int ret, type; 476 477 if (--cnt < 0) 478 return; 479 type = *data++; 480 if (!(ep = findencryption(type))) { 481 if (encrypt_debug_mode) 482 printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 483 Name, 484 ENCTYPE_NAME(data[-1]), data[1]); 485 return; 486 } 487 if (!ep->reply) { 488 if (encrypt_debug_mode) 489 printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 490 Name, 491 ENCTYPE_NAME(data[-1]), data[1]); 492 ret = 0; 493 } else { 494 ret = (*ep->reply)(data, cnt); 495 /*@*/ if (encrypt_debug_mode) 496 /*@*/ printf("(*ep->reply)(%x, %d) returned %s(%d)\n", 497 /*@*/ data, cnt, 498 /*@*/ (ret < 0) ? "FAIL " : 499 /*@*/ (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 500 } 501 if (encrypt_debug_mode) 502 printf(">>>%s: encrypt_reply returned %d\n", Name, ret); 503 if (ret < 0) { 504 autoencrypt = 0; 505 } else { 506 encrypt_mode = type; 507 if (ret == 0 && autoencrypt) 508 encrypt_start_output(type); 509 } 510 } 511 512 /* 513 * Called when a ENCRYPT START command is received. 514 */ 515 void 516 encrypt_start() 517 { 518 Encryptions *ep; 519 520 if (!decrypt_mode) { 521 /* 522 * Something is wrong. We should not get a START 523 * command without having already picked our 524 * decryption scheme. Send a REQUEST-END to 525 * attempt to clear the channel... 526 */ 527 printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name); 528 encrypt_send_request_end(); 529 return; 530 } 531 532 if (ep = finddecryption(decrypt_mode)) { 533 decrypt_input = ep->input; 534 if (encrypt_verbose) 535 printf("[ Input is now decrypted with type %s ]\r\n", 536 ENCTYPE_NAME(decrypt_mode)); 537 if (encrypt_debug_mode) 538 printf(">>>%s: Start to decrypt input with type %s\r\n", 539 Name, ENCTYPE_NAME(decrypt_mode)); 540 } else { 541 printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n", 542 Name, ENCTYPE_NAME(decrypt_mode), decrypt_mode); 543 encrypt_send_request_end(); 544 } 545 } 546 547 void 548 encrypt_session_key(key, server) 549 Session_Key *key; 550 int server; 551 { 552 Encryptions *ep = encryptions; 553 554 havesessionkey = 1; 555 556 while (ep->type) { 557 if (ep->session) 558 (*ep->session)(key, server); 559 if (!encrypt_output && autoencrypt && !server) 560 encrypt_start_output(ep->type); 561 if (!decrypt_input && autodecrypt && !server) 562 encrypt_send_request_start(); 563 ++ep; 564 } 565 } 566 567 /* 568 * Called when ENCRYPT END is received. 569 */ 570 void 571 encrypt_end() 572 { 573 decrypt_input = 0; 574 if (encrypt_debug_mode) 575 printf(">>>%s: Input is back to clear text\r\n", Name); 576 if (encrypt_verbose) 577 printf("[ Input is now clear text ]\r\n"); 578 } 579 580 /* 581 * Called when ENCRYPT REQUEST-END is received. 582 */ 583 void 584 encrypt_request_end() 585 { 586 encrypt_send_end(); 587 } 588 589 /* 590 * Called when ENCRYPT REQUEST-START is received. If we receive 591 * this before a type is picked, then that indicates that the 592 * other side wants us to start encrypting data as soon as we 593 * can. 594 */ 595 void 596 encrypt_request_start() 597 { 598 if (!encrypt_mode && Server) { 599 autoencrypt = 1; 600 return; 601 } 602 encrypt_start_output(encrypt_mode); 603 } 604 605 void 606 encrypt_auto() 607 { 608 autoencrypt = 1; 609 autodecrypt = 1; 610 } 611 612 void 613 encrypt_start_output(type) 614 int type; 615 { 616 Encryptions *ep; 617 register int ret; 618 619 if (!(ep = findencryption(type))) { 620 if (encrypt_debug_mode) { 621 printf(">>>%s: Marking type %s for later encryption use\r\n", 622 Name, 623 ENCTYPE_NAME(type)); 624 } 625 encrypt_mark |= typemask(type); 626 return; 627 } 628 if (ep->start) { 629 ret = (*ep->start)(DIR_ENCRYPT, Server); 630 if (ret) { 631 if (encrypt_debug_mode) { 632 if (ret < 0) 633 printf(">>>%s: Start failed for %s\r\n", 634 Name, ENCTYPE_NAME(type)); 635 else 636 printf(">>>%s: Start: initial negotiation in progress%s\r\n", 637 Name, ENCTYPE_NAME(type)); 638 } 639 640 return; 641 } 642 } 643 str_start[3] = ENCRYPT_START; 644 net_write(str_start, sizeof(str_start)); 645 net_encrypt(); 646 printsub('>', &str_start[2], sizeof(str_start) - 2); 647 /* 648 * If we are already encrypting in some mode, then 649 * encrypt the ring (which includes our request) in 650 * the old mode, mark it all as "clear text" and then 651 * switch to the new mode. 652 */ 653 encrypt_output = ep->output; 654 encrypt_mode = type; 655 if (encrypt_debug_mode) 656 printf(">>>%s: Started to encrypt output with type %s\r\n", 657 Name, ENCTYPE_NAME(type)); 658 if (encrypt_verbose) 659 printf("[ Output is now encrypted with type %s ]\r\n", 660 ENCTYPE_NAME(type)); 661 } 662 663 void 664 encrypt_send_end() 665 { 666 if (!encrypt_output) 667 return; 668 669 str_end[3] = ENCRYPT_END; 670 net_write(str_end, sizeof(str_end)); 671 net_encrypt(); 672 printsub('>', &str_end[2], sizeof(str_end) - 2); 673 /* 674 * Encrypt the output buffer now because it will not be done by 675 * netflush... 676 */ 677 encrypt_output = 0; 678 if (encrypt_debug_mode) 679 printf(">>>%s: Output is back to clear text\r\n", Name); 680 if (encrypt_verbose) 681 printf("[ Output is now clear text ]\r\n"); 682 } 683 684 void 685 encrypt_send_request_start() 686 { 687 #ifdef notdef 688 Encryptions *ep; 689 690 if (!(ep = findencryption(type))) { 691 if (encrypt_debug_mode) { 692 printf(">>>%s: Marking type %s for later decryption use\r\n", 693 Name, 694 ENCTYPE_NAME(type)); 695 } 696 decrypt_mark |= typemask(type); 697 return; 698 } 699 700 if (ep->start && (*ep->start)(DIR_DECRYPT, Server)) { 701 if (encrypt_debug_mode) { 702 printf(">>>%s: Request failed for %s\r\n", 703 Name, 704 ENCTYPE_NAME(type)); 705 } 706 return; 707 } 708 #endif 709 710 str_start[3] = ENCRYPT_REQSTART; 711 net_write(str_start, sizeof(str_start)); 712 printsub('>', &str_start[2], sizeof(str_start) - 2); 713 if (encrypt_debug_mode) 714 printf(">>>%s: Request input to be encrypted\r\n", Name); 715 } 716 717 void 718 encrypt_send_request_end() 719 { 720 str_end[3] = ENCRYPT_REQEND; 721 net_write(str_end, sizeof(str_end)); 722 printsub('>', &str_end[2], sizeof(str_end) - 2); 723 724 if (encrypt_debug_mode) 725 printf(">>>%s: Request input to be clear text\r\n", Name); 726 } 727 728 void 729 encrypt_wait() 730 { 731 register int encrypt, decrypt; 732 if (encrypt_debug_mode) 733 printf(">>>%s: in encrypt_wait\r\n", Name); 734 if (!havesessionkey || !(i_support_encrypt & remote_supports_decrypt)) 735 return; 736 while (autoencrypt && !encrypt_output) 737 if (telnet_spin()) 738 return; 739 } 740 741 void 742 encrypt_debug(mode) 743 int mode; 744 { 745 encrypt_debug_mode = mode; 746 } 747 748 void 749 encrypt_gen_printsub(data, cnt, buf, buflen) 750 unsigned char *data, *buf; 751 int cnt, buflen; 752 { 753 char tbuf[16], *cp; 754 755 cnt -= 2; 756 data += 2; 757 buf[buflen-1] = '\0'; 758 buf[buflen-2] = '*'; 759 buflen -= 2;; 760 for (; cnt > 0; cnt--, data++) { 761 sprintf(tbuf, " %d", *data); 762 for (cp = tbuf; *cp && buflen > 0; --buflen) 763 *buf++ = *cp++; 764 if (buflen <= 0) 765 return; 766 } 767 *buf = '\0'; 768 } 769 770 void 771 encrypt_printsub(data, cnt, buf, buflen) 772 unsigned char *data, *buf; 773 int cnt, buflen; 774 { 775 Encryptions *ep; 776 register int type = data[1]; 777 778 for (ep = encryptions; ep->type && ep->type != type; ep++) 779 ; 780 781 if (ep->printsub) 782 (*ep->printsub)(data, cnt, buf, buflen); 783 else 784 encrypt_gen_printsub(data, cnt, buf, buflen); 785 } 786 #endif 787