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