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