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