1068e7061SPeter Avalos /*-
2068e7061SPeter Avalos * Copyright (c) 1991, 1993
3068e7061SPeter Avalos * The Regents of the University of California. All rights reserved.
4068e7061SPeter Avalos *
5068e7061SPeter Avalos * Redistribution and use in source and binary forms, with or without
6068e7061SPeter Avalos * modification, are permitted provided that the following conditions
7068e7061SPeter Avalos * are met:
8068e7061SPeter Avalos * 1. Redistributions of source code must retain the above copyright
9068e7061SPeter Avalos * notice, this list of conditions and the following disclaimer.
10068e7061SPeter Avalos * 2. Redistributions in binary form must reproduce the above copyright
11068e7061SPeter Avalos * notice, this list of conditions and the following disclaimer in the
12068e7061SPeter Avalos * documentation and/or other materials provided with the distribution.
13dc71b7abSJustin C. Sherrill * 3. Neither the name of the University nor the names of its contributors
14068e7061SPeter Avalos * may be used to endorse or promote products derived from this software
15068e7061SPeter Avalos * without specific prior written permission.
16068e7061SPeter Avalos *
17068e7061SPeter Avalos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18068e7061SPeter Avalos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19068e7061SPeter Avalos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20068e7061SPeter Avalos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21068e7061SPeter Avalos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22068e7061SPeter Avalos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23068e7061SPeter Avalos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24068e7061SPeter Avalos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25068e7061SPeter Avalos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26068e7061SPeter Avalos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27068e7061SPeter Avalos * SUCH DAMAGE.
28068e7061SPeter Avalos *
29068e7061SPeter Avalos * @(#)encrypt.c 8.2 (Berkeley) 5/30/95
30068e7061SPeter Avalos * $FreeBSD: src/crypto/telnet/libtelnet/encrypt.c,v 1.3.2.2 2002/04/13 10:59:07 markm Exp $
31068e7061SPeter Avalos */
32068e7061SPeter Avalos
33068e7061SPeter Avalos /*
34068e7061SPeter Avalos * Copyright (C) 1990 by the Massachusetts Institute of Technology
35068e7061SPeter Avalos *
36068e7061SPeter Avalos * Export of this software from the United States of America is assumed
37068e7061SPeter Avalos * to require a specific license from the United States Government.
38068e7061SPeter Avalos * It is the responsibility of any person or organization contemplating
39068e7061SPeter Avalos * export to obtain such a license before exporting.
40068e7061SPeter Avalos *
41068e7061SPeter Avalos * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
42068e7061SPeter Avalos * distribute this software and its documentation for any purpose and
43068e7061SPeter Avalos * without fee is hereby granted, provided that the above copyright
44068e7061SPeter Avalos * notice appear in all copies and that both that copyright notice and
45068e7061SPeter Avalos * this permission notice appear in supporting documentation, and that
46068e7061SPeter Avalos * the name of M.I.T. not be used in advertising or publicity pertaining
47068e7061SPeter Avalos * to distribution of the software without specific, written prior
48068e7061SPeter Avalos * permission. M.I.T. makes no representations about the suitability of
49068e7061SPeter Avalos * this software for any purpose. It is provided "as is" without express
50068e7061SPeter Avalos * or implied warranty.
51068e7061SPeter Avalos */
52068e7061SPeter Avalos
53068e7061SPeter Avalos #ifdef ENCRYPTION
54068e7061SPeter Avalos
55068e7061SPeter Avalos #define ENCRYPT_NAMES
56068e7061SPeter Avalos #include <arpa/telnet.h>
57068e7061SPeter Avalos #include <stdio.h>
58068e7061SPeter Avalos #include <stdlib.h>
59068e7061SPeter Avalos #include <string.h>
60068e7061SPeter Avalos
61068e7061SPeter Avalos #include "encrypt.h"
62068e7061SPeter Avalos #include "misc.h"
63068e7061SPeter Avalos
64*1c6ee455SSascha Wildner /*
65*1c6ee455SSascha Wildner * These functions pointers point to the current routines
66*1c6ee455SSascha Wildner * for encrypting and decrypting data.
67*1c6ee455SSascha Wildner */
68*1c6ee455SSascha Wildner void (*encrypt_output)(unsigned char *, int);
69*1c6ee455SSascha Wildner int (*decrypt_input)(int);
70*1c6ee455SSascha Wildner
71068e7061SPeter Avalos int EncryptType(char *type, char *mode);
72068e7061SPeter Avalos int EncryptStart(char *mode);
73068e7061SPeter Avalos int EncryptStop(char *mode);
74068e7061SPeter Avalos int EncryptStartInput(void);
75068e7061SPeter Avalos int EncryptStartOutput(void);
76068e7061SPeter Avalos int EncryptStopInput(void);
77068e7061SPeter Avalos int EncryptStopOutput(void);
78068e7061SPeter Avalos
79068e7061SPeter Avalos int encrypt_debug_mode = 0;
80068e7061SPeter Avalos static int decrypt_mode = 0;
81068e7061SPeter Avalos static int encrypt_mode = 0;
82068e7061SPeter Avalos static int encrypt_verbose = 0;
83068e7061SPeter Avalos static int autoencrypt = 0;
84068e7061SPeter Avalos static int autodecrypt = 0;
85068e7061SPeter Avalos static int havesessionkey = 0;
86068e7061SPeter Avalos static int Server = 0;
87068e7061SPeter Avalos static const char *Name = "Noname";
88068e7061SPeter Avalos
89068e7061SPeter Avalos #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0)
90068e7061SPeter Avalos
91068e7061SPeter Avalos static long i_support_encrypt = 0
92068e7061SPeter Avalos | typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64)
93068e7061SPeter Avalos |0;
94068e7061SPeter Avalos static long i_support_decrypt = 0
95068e7061SPeter Avalos | typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64)
96068e7061SPeter Avalos |0;
97068e7061SPeter Avalos
98068e7061SPeter Avalos static long i_wont_support_encrypt = 0;
99068e7061SPeter Avalos static long i_wont_support_decrypt = 0;
100068e7061SPeter Avalos #define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt)
101068e7061SPeter Avalos #define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt)
102068e7061SPeter Avalos
103068e7061SPeter Avalos static long remote_supports_encrypt = 0;
104068e7061SPeter Avalos static long remote_supports_decrypt = 0;
105068e7061SPeter Avalos
106068e7061SPeter Avalos static Encryptions encryptions[] = {
107068e7061SPeter Avalos { "DES_CFB64", ENCTYPE_DES_CFB64,
108068e7061SPeter Avalos cfb64_encrypt,
109068e7061SPeter Avalos cfb64_decrypt,
110068e7061SPeter Avalos cfb64_init,
111068e7061SPeter Avalos cfb64_start,
112068e7061SPeter Avalos cfb64_is,
113068e7061SPeter Avalos cfb64_reply,
114068e7061SPeter Avalos cfb64_session,
115068e7061SPeter Avalos cfb64_keyid,
116068e7061SPeter Avalos cfb64_printsub },
117068e7061SPeter Avalos { "DES_OFB64", ENCTYPE_DES_OFB64,
118068e7061SPeter Avalos ofb64_encrypt,
119068e7061SPeter Avalos ofb64_decrypt,
120068e7061SPeter Avalos ofb64_init,
121068e7061SPeter Avalos ofb64_start,
122068e7061SPeter Avalos ofb64_is,
123068e7061SPeter Avalos ofb64_reply,
124068e7061SPeter Avalos ofb64_session,
125068e7061SPeter Avalos ofb64_keyid,
126068e7061SPeter Avalos ofb64_printsub },
127068e7061SPeter Avalos { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
128068e7061SPeter Avalos };
129068e7061SPeter Avalos
130068e7061SPeter Avalos static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT,
131068e7061SPeter Avalos ENCRYPT_SUPPORT };
132068e7061SPeter Avalos static unsigned char str_suplen = 0;
133068e7061SPeter Avalos static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT };
134068e7061SPeter Avalos static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE };
135068e7061SPeter Avalos
136068e7061SPeter Avalos Encryptions *
findencryption(int type)137068e7061SPeter Avalos findencryption(int type)
138068e7061SPeter Avalos {
139068e7061SPeter Avalos Encryptions *ep = encryptions;
140068e7061SPeter Avalos
141068e7061SPeter Avalos if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & (unsigned)typemask(type)))
142068e7061SPeter Avalos return(0);
143068e7061SPeter Avalos while (ep->type && ep->type != type)
144068e7061SPeter Avalos ++ep;
145068e7061SPeter Avalos return(ep->type ? ep : 0);
146068e7061SPeter Avalos }
147068e7061SPeter Avalos
148068e7061SPeter Avalos static Encryptions *
finddecryption(int type)149068e7061SPeter Avalos finddecryption(int type)
150068e7061SPeter Avalos {
151068e7061SPeter Avalos Encryptions *ep = encryptions;
152068e7061SPeter Avalos
153068e7061SPeter Avalos if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & (unsigned)typemask(type)))
154068e7061SPeter Avalos return(0);
155068e7061SPeter Avalos while (ep->type && ep->type != type)
156068e7061SPeter Avalos ++ep;
157068e7061SPeter Avalos return(ep->type ? ep : 0);
158068e7061SPeter Avalos }
159068e7061SPeter Avalos
160068e7061SPeter Avalos #define MAXKEYLEN 64
161068e7061SPeter Avalos
162068e7061SPeter Avalos static struct key_info {
163068e7061SPeter Avalos unsigned char keyid[MAXKEYLEN];
164068e7061SPeter Avalos int keylen;
165068e7061SPeter Avalos int dir;
166068e7061SPeter Avalos int *modep;
167068e7061SPeter Avalos Encryptions *(*getcrypt)(int);
168068e7061SPeter Avalos } ki[2] = {
169068e7061SPeter Avalos { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption },
170068e7061SPeter Avalos { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption },
171068e7061SPeter Avalos };
172068e7061SPeter Avalos
173068e7061SPeter Avalos static void encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len);
174068e7061SPeter Avalos
175068e7061SPeter Avalos void
encrypt_init(const char * name,int server)176068e7061SPeter Avalos encrypt_init(const char *name, int server)
177068e7061SPeter Avalos {
178068e7061SPeter Avalos Encryptions *ep = encryptions;
179068e7061SPeter Avalos
180068e7061SPeter Avalos Name = name;
181068e7061SPeter Avalos Server = server;
182068e7061SPeter Avalos i_support_encrypt = i_support_decrypt = 0;
183068e7061SPeter Avalos remote_supports_encrypt = remote_supports_decrypt = 0;
184068e7061SPeter Avalos encrypt_mode = 0;
185068e7061SPeter Avalos decrypt_mode = 0;
186678e8cc6SSascha Wildner encrypt_output = NULL;
187678e8cc6SSascha Wildner decrypt_input = NULL;
188068e7061SPeter Avalos
189068e7061SPeter Avalos str_suplen = 4;
190068e7061SPeter Avalos
191068e7061SPeter Avalos while (ep->type) {
192068e7061SPeter Avalos if (encrypt_debug_mode)
193068e7061SPeter Avalos printf(">>>%s: I will support %s\r\n",
194068e7061SPeter Avalos Name, ENCTYPE_NAME(ep->type));
195068e7061SPeter Avalos i_support_encrypt |= typemask(ep->type);
196068e7061SPeter Avalos i_support_decrypt |= typemask(ep->type);
197068e7061SPeter Avalos if ((i_wont_support_decrypt & typemask(ep->type)) == 0)
198068e7061SPeter Avalos if ((str_send[str_suplen++] = ep->type) == IAC)
199068e7061SPeter Avalos str_send[str_suplen++] = IAC;
200068e7061SPeter Avalos if (ep->init)
201068e7061SPeter Avalos (*ep->init)(Server);
202068e7061SPeter Avalos ++ep;
203068e7061SPeter Avalos }
204068e7061SPeter Avalos str_send[str_suplen++] = IAC;
205068e7061SPeter Avalos str_send[str_suplen++] = SE;
206068e7061SPeter Avalos }
207068e7061SPeter Avalos
208068e7061SPeter Avalos static void
encrypt_list_types(void)209068e7061SPeter Avalos encrypt_list_types(void)
210068e7061SPeter Avalos {
211068e7061SPeter Avalos Encryptions *ep = encryptions;
212068e7061SPeter Avalos
213068e7061SPeter Avalos printf("Valid encryption types:\n");
214068e7061SPeter Avalos while (ep->type) {
215068e7061SPeter Avalos printf("\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type);
216068e7061SPeter Avalos ++ep;
217068e7061SPeter Avalos }
218068e7061SPeter Avalos }
219068e7061SPeter Avalos
220068e7061SPeter Avalos int
EncryptEnable(char * type,char * mode)221068e7061SPeter Avalos EncryptEnable(char *type, char *mode)
222068e7061SPeter Avalos {
223068e7061SPeter Avalos if (isprefix(type, "help") || isprefix(type, "?")) {
224068e7061SPeter Avalos printf("Usage: encrypt enable <type> [input|output]\n");
225068e7061SPeter Avalos encrypt_list_types();
226068e7061SPeter Avalos return(0);
227068e7061SPeter Avalos }
228068e7061SPeter Avalos if (EncryptType(type, mode))
229068e7061SPeter Avalos return(EncryptStart(mode));
230068e7061SPeter Avalos return(0);
231068e7061SPeter Avalos }
232068e7061SPeter Avalos
233068e7061SPeter Avalos int
EncryptDisable(char * type,char * mode)234068e7061SPeter Avalos EncryptDisable(char *type, char *mode)
235068e7061SPeter Avalos {
236068e7061SPeter Avalos Encryptions *ep;
237068e7061SPeter Avalos int ret = 0;
238068e7061SPeter Avalos
239068e7061SPeter Avalos if (isprefix(type, "help") || isprefix(type, "?")) {
240068e7061SPeter Avalos printf("Usage: encrypt disable <type> [input|output]\n");
241068e7061SPeter Avalos encrypt_list_types();
242068e7061SPeter Avalos } else if ((ep = (Encryptions *)genget(type, (char **)encryptions,
243678e8cc6SSascha Wildner sizeof(Encryptions))) == NULL) {
244068e7061SPeter Avalos printf("%s: invalid encryption type\n", type);
245068e7061SPeter Avalos } else if (Ambiguous((char **)ep)) {
246068e7061SPeter Avalos printf("Ambiguous type '%s'\n", type);
247068e7061SPeter Avalos } else {
248678e8cc6SSascha Wildner if ((mode == NULL) || (isprefix(mode, "input") ? 1 : 0)) {
249068e7061SPeter Avalos if (decrypt_mode == ep->type)
250068e7061SPeter Avalos EncryptStopInput();
251068e7061SPeter Avalos i_wont_support_decrypt |= typemask(ep->type);
252068e7061SPeter Avalos ret = 1;
253068e7061SPeter Avalos }
254678e8cc6SSascha Wildner if ((mode == NULL) || (isprefix(mode, "output"))) {
255068e7061SPeter Avalos if (encrypt_mode == ep->type)
256068e7061SPeter Avalos EncryptStopOutput();
257068e7061SPeter Avalos i_wont_support_encrypt |= typemask(ep->type);
258068e7061SPeter Avalos ret = 1;
259068e7061SPeter Avalos }
260068e7061SPeter Avalos if (ret == 0)
261068e7061SPeter Avalos printf("%s: invalid encryption mode\n", mode);
262068e7061SPeter Avalos }
263068e7061SPeter Avalos return(ret);
264068e7061SPeter Avalos }
265068e7061SPeter Avalos
266068e7061SPeter Avalos int
EncryptType(char * type,char * mode)267068e7061SPeter Avalos EncryptType(char *type, char *mode)
268068e7061SPeter Avalos {
269068e7061SPeter Avalos Encryptions *ep;
270068e7061SPeter Avalos int ret = 0;
271068e7061SPeter Avalos
272068e7061SPeter Avalos if (isprefix(type, "help") || isprefix(type, "?")) {
273068e7061SPeter Avalos printf("Usage: encrypt type <type> [input|output]\n");
274068e7061SPeter Avalos encrypt_list_types();
275068e7061SPeter Avalos } else if ((ep = (Encryptions *)genget(type, (char **)encryptions,
276678e8cc6SSascha Wildner sizeof(Encryptions))) == NULL) {
277068e7061SPeter Avalos printf("%s: invalid encryption type\n", type);
278068e7061SPeter Avalos } else if (Ambiguous((char **)ep)) {
279068e7061SPeter Avalos printf("Ambiguous type '%s'\n", type);
280068e7061SPeter Avalos } else {
281678e8cc6SSascha Wildner if ((mode == NULL) || isprefix(mode, "input")) {
282068e7061SPeter Avalos decrypt_mode = ep->type;
283068e7061SPeter Avalos i_wont_support_decrypt &= ~typemask(ep->type);
284068e7061SPeter Avalos ret = 1;
285068e7061SPeter Avalos }
286678e8cc6SSascha Wildner if ((mode == NULL) || isprefix(mode, "output")) {
287068e7061SPeter Avalos encrypt_mode = ep->type;
288068e7061SPeter Avalos i_wont_support_encrypt &= ~typemask(ep->type);
289068e7061SPeter Avalos ret = 1;
290068e7061SPeter Avalos }
291068e7061SPeter Avalos if (ret == 0)
292068e7061SPeter Avalos printf("%s: invalid encryption mode\n", mode);
293068e7061SPeter Avalos }
294068e7061SPeter Avalos return(ret);
295068e7061SPeter Avalos }
296068e7061SPeter Avalos
297068e7061SPeter Avalos int
EncryptStart(char * mode)298068e7061SPeter Avalos EncryptStart(char *mode)
299068e7061SPeter Avalos {
300068e7061SPeter Avalos int ret = 0;
301068e7061SPeter Avalos if (mode) {
302068e7061SPeter Avalos if (isprefix(mode, "input"))
303068e7061SPeter Avalos return(EncryptStartInput());
304068e7061SPeter Avalos if (isprefix(mode, "output"))
305068e7061SPeter Avalos return(EncryptStartOutput());
306068e7061SPeter Avalos if (isprefix(mode, "help") || isprefix(mode, "?")) {
307068e7061SPeter Avalos printf("Usage: encrypt start [input|output]\n");
308068e7061SPeter Avalos return(0);
309068e7061SPeter Avalos }
310068e7061SPeter Avalos printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode);
311068e7061SPeter Avalos return(0);
312068e7061SPeter Avalos }
313068e7061SPeter Avalos ret += EncryptStartInput();
314068e7061SPeter Avalos ret += EncryptStartOutput();
315068e7061SPeter Avalos return(ret);
316068e7061SPeter Avalos }
317068e7061SPeter Avalos
318068e7061SPeter Avalos int
EncryptStartInput(void)319068e7061SPeter Avalos EncryptStartInput(void)
320068e7061SPeter Avalos {
321068e7061SPeter Avalos if (decrypt_mode) {
322068e7061SPeter Avalos encrypt_send_request_start();
323068e7061SPeter Avalos return(1);
324068e7061SPeter Avalos }
325068e7061SPeter Avalos printf("No previous decryption mode, decryption not enabled\r\n");
326068e7061SPeter Avalos return(0);
327068e7061SPeter Avalos }
328068e7061SPeter Avalos
329068e7061SPeter Avalos int
EncryptStartOutput(void)330068e7061SPeter Avalos EncryptStartOutput(void)
331068e7061SPeter Avalos {
332068e7061SPeter Avalos if (encrypt_mode) {
333068e7061SPeter Avalos encrypt_start_output(encrypt_mode);
334068e7061SPeter Avalos return(1);
335068e7061SPeter Avalos }
336068e7061SPeter Avalos printf("No previous encryption mode, encryption not enabled\r\n");
337068e7061SPeter Avalos return(0);
338068e7061SPeter Avalos }
339068e7061SPeter Avalos
340068e7061SPeter Avalos int
EncryptStop(char * mode)341068e7061SPeter Avalos EncryptStop(char *mode)
342068e7061SPeter Avalos {
343068e7061SPeter Avalos int ret = 0;
344068e7061SPeter Avalos if (mode) {
345068e7061SPeter Avalos if (isprefix(mode, "input"))
346068e7061SPeter Avalos return(EncryptStopInput());
347068e7061SPeter Avalos if (isprefix(mode, "output"))
348068e7061SPeter Avalos return(EncryptStopOutput());
349068e7061SPeter Avalos if (isprefix(mode, "help") || isprefix(mode, "?")) {
350068e7061SPeter Avalos printf("Usage: encrypt stop [input|output]\n");
351068e7061SPeter Avalos return(0);
352068e7061SPeter Avalos }
353068e7061SPeter Avalos printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode);
354068e7061SPeter Avalos return(0);
355068e7061SPeter Avalos }
356068e7061SPeter Avalos ret += EncryptStopInput();
357068e7061SPeter Avalos ret += EncryptStopOutput();
358068e7061SPeter Avalos return(ret);
359068e7061SPeter Avalos }
360068e7061SPeter Avalos
361068e7061SPeter Avalos int
EncryptStopInput(void)362068e7061SPeter Avalos EncryptStopInput(void)
363068e7061SPeter Avalos {
364068e7061SPeter Avalos encrypt_send_request_end();
365068e7061SPeter Avalos return(1);
366068e7061SPeter Avalos }
367068e7061SPeter Avalos
368068e7061SPeter Avalos int
EncryptStopOutput(void)369068e7061SPeter Avalos EncryptStopOutput(void)
370068e7061SPeter Avalos {
371068e7061SPeter Avalos encrypt_send_end();
372068e7061SPeter Avalos return(1);
373068e7061SPeter Avalos }
374068e7061SPeter Avalos
375068e7061SPeter Avalos void
encrypt_display(void)376068e7061SPeter Avalos encrypt_display(void)
377068e7061SPeter Avalos {
378068e7061SPeter Avalos if (encrypt_output)
379068e7061SPeter Avalos printf("Currently encrypting output with %s\r\n",
380068e7061SPeter Avalos ENCTYPE_NAME(encrypt_mode));
381068e7061SPeter Avalos if (decrypt_input)
382068e7061SPeter Avalos printf("Currently decrypting input with %s\r\n",
383068e7061SPeter Avalos ENCTYPE_NAME(decrypt_mode));
384068e7061SPeter Avalos }
385068e7061SPeter Avalos
386068e7061SPeter Avalos int
EncryptStatus(void)387068e7061SPeter Avalos EncryptStatus(void)
388068e7061SPeter Avalos {
389068e7061SPeter Avalos if (encrypt_output)
390068e7061SPeter Avalos printf("Currently encrypting output with %s\r\n",
391068e7061SPeter Avalos ENCTYPE_NAME(encrypt_mode));
392068e7061SPeter Avalos else if (encrypt_mode) {
393068e7061SPeter Avalos printf("Currently output is clear text.\r\n");
394068e7061SPeter Avalos printf("Last encryption mode was %s\r\n",
395068e7061SPeter Avalos ENCTYPE_NAME(encrypt_mode));
396068e7061SPeter Avalos }
397068e7061SPeter Avalos if (decrypt_input) {
398068e7061SPeter Avalos printf("Currently decrypting input with %s\r\n",
399068e7061SPeter Avalos ENCTYPE_NAME(decrypt_mode));
400068e7061SPeter Avalos } else if (decrypt_mode) {
401068e7061SPeter Avalos printf("Currently input is clear text.\r\n");
402068e7061SPeter Avalos printf("Last decryption mode was %s\r\n",
403068e7061SPeter Avalos ENCTYPE_NAME(decrypt_mode));
404068e7061SPeter Avalos }
405068e7061SPeter Avalos return 1;
406068e7061SPeter Avalos }
407068e7061SPeter Avalos
408068e7061SPeter Avalos void
encrypt_send_support(void)409068e7061SPeter Avalos encrypt_send_support(void)
410068e7061SPeter Avalos {
411068e7061SPeter Avalos if (str_suplen) {
412068e7061SPeter Avalos /*
413068e7061SPeter Avalos * If the user has requested that decryption start
414068e7061SPeter Avalos * immediatly, then send a "REQUEST START" before
415068e7061SPeter Avalos * we negotiate the type.
416068e7061SPeter Avalos */
417068e7061SPeter Avalos if (!Server && autodecrypt)
418068e7061SPeter Avalos encrypt_send_request_start();
419068e7061SPeter Avalos net_write(str_send, str_suplen);
420068e7061SPeter Avalos printsub('>', &str_send[2], str_suplen - 2);
421068e7061SPeter Avalos str_suplen = 0;
422068e7061SPeter Avalos }
423068e7061SPeter Avalos }
424068e7061SPeter Avalos
425068e7061SPeter Avalos int
EncryptDebug(int on)426068e7061SPeter Avalos EncryptDebug(int on)
427068e7061SPeter Avalos {
428068e7061SPeter Avalos if (on < 0)
429068e7061SPeter Avalos encrypt_debug_mode ^= 1;
430068e7061SPeter Avalos else
431068e7061SPeter Avalos encrypt_debug_mode = on;
432068e7061SPeter Avalos printf("Encryption debugging %s\r\n",
433068e7061SPeter Avalos encrypt_debug_mode ? "enabled" : "disabled");
434068e7061SPeter Avalos return(1);
435068e7061SPeter Avalos }
436068e7061SPeter Avalos
437068e7061SPeter Avalos int
EncryptVerbose(int on)438068e7061SPeter Avalos EncryptVerbose(int on)
439068e7061SPeter Avalos {
440068e7061SPeter Avalos if (on < 0)
441068e7061SPeter Avalos encrypt_verbose ^= 1;
442068e7061SPeter Avalos else
443068e7061SPeter Avalos encrypt_verbose = on;
444068e7061SPeter Avalos printf("Encryption %s verbose\r\n",
445068e7061SPeter Avalos encrypt_verbose ? "is" : "is not");
446068e7061SPeter Avalos return(1);
447068e7061SPeter Avalos }
448068e7061SPeter Avalos
449068e7061SPeter Avalos int
EncryptAutoEnc(int on)450068e7061SPeter Avalos EncryptAutoEnc(int on)
451068e7061SPeter Avalos {
452068e7061SPeter Avalos encrypt_auto(on);
453068e7061SPeter Avalos printf("Automatic encryption of output is %s\r\n",
454068e7061SPeter Avalos autoencrypt ? "enabled" : "disabled");
455068e7061SPeter Avalos return(1);
456068e7061SPeter Avalos }
457068e7061SPeter Avalos
458068e7061SPeter Avalos int
EncryptAutoDec(int on)459068e7061SPeter Avalos EncryptAutoDec(int on)
460068e7061SPeter Avalos {
461068e7061SPeter Avalos decrypt_auto(on);
462068e7061SPeter Avalos printf("Automatic decryption of input is %s\r\n",
463068e7061SPeter Avalos autodecrypt ? "enabled" : "disabled");
464068e7061SPeter Avalos return(1);
465068e7061SPeter Avalos }
466068e7061SPeter Avalos
467068e7061SPeter Avalos /*
468068e7061SPeter Avalos * Called when ENCRYPT SUPPORT is received.
469068e7061SPeter Avalos */
470068e7061SPeter Avalos void
encrypt_support(unsigned char * typelist,int cnt)471068e7061SPeter Avalos encrypt_support(unsigned char *typelist, int cnt)
472068e7061SPeter Avalos {
473068e7061SPeter Avalos int type, use_type = 0;
474068e7061SPeter Avalos Encryptions *ep;
475068e7061SPeter Avalos
476068e7061SPeter Avalos /*
477068e7061SPeter Avalos * Forget anything the other side has previously told us.
478068e7061SPeter Avalos */
479068e7061SPeter Avalos remote_supports_decrypt = 0;
480068e7061SPeter Avalos
481068e7061SPeter Avalos while (cnt-- > 0) {
482068e7061SPeter Avalos type = *typelist++;
483068e7061SPeter Avalos if (encrypt_debug_mode)
484068e7061SPeter Avalos printf(">>>%s: He is supporting %s (%d)\r\n",
485068e7061SPeter Avalos Name,
486068e7061SPeter Avalos ENCTYPE_NAME(type), type);
487068e7061SPeter Avalos if ((type < ENCTYPE_CNT) &&
488068e7061SPeter Avalos (I_SUPPORT_ENCRYPT & typemask(type))) {
489068e7061SPeter Avalos remote_supports_decrypt |= typemask(type);
490068e7061SPeter Avalos if (use_type == 0)
491068e7061SPeter Avalos use_type = type;
492068e7061SPeter Avalos }
493068e7061SPeter Avalos }
494068e7061SPeter Avalos if (use_type) {
495068e7061SPeter Avalos ep = findencryption(use_type);
496068e7061SPeter Avalos if (!ep)
497068e7061SPeter Avalos return;
498068e7061SPeter Avalos type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0;
499068e7061SPeter Avalos if (encrypt_debug_mode)
500068e7061SPeter Avalos printf(">>>%s: (*ep->start)() returned %d\r\n",
501068e7061SPeter Avalos Name, type);
502068e7061SPeter Avalos if (type < 0)
503068e7061SPeter Avalos return;
504068e7061SPeter Avalos encrypt_mode = use_type;
505068e7061SPeter Avalos if (type == 0)
506068e7061SPeter Avalos encrypt_start_output(use_type);
507068e7061SPeter Avalos }
508068e7061SPeter Avalos }
509068e7061SPeter Avalos
510068e7061SPeter Avalos void
encrypt_is(unsigned char * data,int cnt)511068e7061SPeter Avalos encrypt_is(unsigned char *data, int cnt)
512068e7061SPeter Avalos {
513068e7061SPeter Avalos Encryptions *ep;
514068e7061SPeter Avalos int type, ret;
515068e7061SPeter Avalos
516068e7061SPeter Avalos if (--cnt < 0)
517068e7061SPeter Avalos return;
518068e7061SPeter Avalos type = *data++;
519068e7061SPeter Avalos if (type < ENCTYPE_CNT)
520068e7061SPeter Avalos remote_supports_encrypt |= typemask(type);
521068e7061SPeter Avalos if (!(ep = finddecryption(type))) {
522068e7061SPeter Avalos if (encrypt_debug_mode)
523068e7061SPeter Avalos printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
524068e7061SPeter Avalos Name,
525068e7061SPeter Avalos ENCTYPE_NAME_OK(type)
526068e7061SPeter Avalos ? ENCTYPE_NAME(type) : "(unknown)",
527068e7061SPeter Avalos type);
528068e7061SPeter Avalos return;
529068e7061SPeter Avalos }
530068e7061SPeter Avalos if (!ep->is) {
531068e7061SPeter Avalos if (encrypt_debug_mode)
532068e7061SPeter Avalos printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n",
533068e7061SPeter Avalos Name,
534068e7061SPeter Avalos ENCTYPE_NAME_OK(type)
535068e7061SPeter Avalos ? ENCTYPE_NAME(type) : "(unknown)",
536068e7061SPeter Avalos type);
537068e7061SPeter Avalos ret = 0;
538068e7061SPeter Avalos } else {
539068e7061SPeter Avalos ret = (*ep->is)(data, cnt);
540068e7061SPeter Avalos if (encrypt_debug_mode)
541068e7061SPeter Avalos printf("(*ep->is)(%p, %d) returned %s(%d)\n", data, cnt,
542068e7061SPeter Avalos (ret < 0) ? "FAIL " :
543068e7061SPeter Avalos (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
544068e7061SPeter Avalos }
545068e7061SPeter Avalos if (ret < 0) {
546068e7061SPeter Avalos autodecrypt = 0;
547068e7061SPeter Avalos } else {
548068e7061SPeter Avalos decrypt_mode = type;
549068e7061SPeter Avalos if (ret == 0 && autodecrypt)
550068e7061SPeter Avalos encrypt_send_request_start();
551068e7061SPeter Avalos }
552068e7061SPeter Avalos }
553068e7061SPeter Avalos
554068e7061SPeter Avalos void
encrypt_reply(unsigned char * data,int cnt)555068e7061SPeter Avalos encrypt_reply(unsigned char *data, int cnt)
556068e7061SPeter Avalos {
557068e7061SPeter Avalos Encryptions *ep;
558068e7061SPeter Avalos int ret, type;
559068e7061SPeter Avalos
560068e7061SPeter Avalos if (--cnt < 0)
561068e7061SPeter Avalos return;
562068e7061SPeter Avalos type = *data++;
563068e7061SPeter Avalos if (!(ep = findencryption(type))) {
564068e7061SPeter Avalos if (encrypt_debug_mode)
565068e7061SPeter Avalos printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
566068e7061SPeter Avalos Name,
567068e7061SPeter Avalos ENCTYPE_NAME_OK(type)
568068e7061SPeter Avalos ? ENCTYPE_NAME(type) : "(unknown)",
569068e7061SPeter Avalos type);
570068e7061SPeter Avalos return;
571068e7061SPeter Avalos }
572068e7061SPeter Avalos if (!ep->reply) {
573068e7061SPeter Avalos if (encrypt_debug_mode)
574068e7061SPeter Avalos printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n",
575068e7061SPeter Avalos Name,
576068e7061SPeter Avalos ENCTYPE_NAME_OK(type)
577068e7061SPeter Avalos ? ENCTYPE_NAME(type) : "(unknown)",
578068e7061SPeter Avalos type);
579068e7061SPeter Avalos ret = 0;
580068e7061SPeter Avalos } else {
581068e7061SPeter Avalos ret = (*ep->reply)(data, cnt);
582068e7061SPeter Avalos if (encrypt_debug_mode)
583068e7061SPeter Avalos printf("(*ep->reply)(%p, %d) returned %s(%d)\n",
584068e7061SPeter Avalos data, cnt,
585068e7061SPeter Avalos (ret < 0) ? "FAIL " :
586068e7061SPeter Avalos (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
587068e7061SPeter Avalos }
588068e7061SPeter Avalos if (encrypt_debug_mode)
589068e7061SPeter Avalos printf(">>>%s: encrypt_reply returned %d\n", Name, ret);
590068e7061SPeter Avalos if (ret < 0) {
591068e7061SPeter Avalos autoencrypt = 0;
592068e7061SPeter Avalos } else {
593068e7061SPeter Avalos encrypt_mode = type;
594068e7061SPeter Avalos if (ret == 0 && autoencrypt)
595068e7061SPeter Avalos encrypt_start_output(type);
596068e7061SPeter Avalos }
597068e7061SPeter Avalos }
598068e7061SPeter Avalos
599068e7061SPeter Avalos /*
600068e7061SPeter Avalos * Called when a ENCRYPT START command is received.
601068e7061SPeter Avalos */
602068e7061SPeter Avalos void
encrypt_start(unsigned char * data __unused,int cnt __unused)603068e7061SPeter Avalos encrypt_start(unsigned char *data __unused, int cnt __unused)
604068e7061SPeter Avalos {
605068e7061SPeter Avalos Encryptions *ep;
606068e7061SPeter Avalos
607068e7061SPeter Avalos if (!decrypt_mode) {
608068e7061SPeter Avalos /*
609068e7061SPeter Avalos * Something is wrong. We should not get a START
610068e7061SPeter Avalos * command without having already picked our
611068e7061SPeter Avalos * decryption scheme. Send a REQUEST-END to
612068e7061SPeter Avalos * attempt to clear the channel...
613068e7061SPeter Avalos */
614068e7061SPeter Avalos printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name);
615068e7061SPeter Avalos encrypt_send_request_end();
616068e7061SPeter Avalos return;
617068e7061SPeter Avalos }
618068e7061SPeter Avalos
619068e7061SPeter Avalos if ((ep = finddecryption(decrypt_mode))) {
620068e7061SPeter Avalos decrypt_input = ep->input;
621068e7061SPeter Avalos if (encrypt_verbose)
622068e7061SPeter Avalos printf("[ Input is now decrypted with type %s ]\r\n",
623068e7061SPeter Avalos ENCTYPE_NAME(decrypt_mode));
624068e7061SPeter Avalos if (encrypt_debug_mode)
625068e7061SPeter Avalos printf(">>>%s: Start to decrypt input with type %s\r\n",
626068e7061SPeter Avalos Name, ENCTYPE_NAME(decrypt_mode));
627068e7061SPeter Avalos } else {
628068e7061SPeter Avalos printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n",
629068e7061SPeter Avalos Name,
630068e7061SPeter Avalos ENCTYPE_NAME_OK(decrypt_mode)
631068e7061SPeter Avalos ? ENCTYPE_NAME(decrypt_mode)
632068e7061SPeter Avalos : "(unknown)",
633068e7061SPeter Avalos decrypt_mode);
634068e7061SPeter Avalos encrypt_send_request_end();
635068e7061SPeter Avalos }
636068e7061SPeter Avalos }
637068e7061SPeter Avalos
638068e7061SPeter Avalos void
encrypt_session_key(Session_Key * key,int server)639068e7061SPeter Avalos encrypt_session_key( Session_Key *key, int server)
640068e7061SPeter Avalos {
641068e7061SPeter Avalos Encryptions *ep = encryptions;
642068e7061SPeter Avalos
643068e7061SPeter Avalos havesessionkey = 1;
644068e7061SPeter Avalos
645068e7061SPeter Avalos while (ep->type) {
646068e7061SPeter Avalos if (ep->session)
647068e7061SPeter Avalos (*ep->session)(key, server);
648068e7061SPeter Avalos ++ep;
649068e7061SPeter Avalos }
650068e7061SPeter Avalos }
651068e7061SPeter Avalos
652068e7061SPeter Avalos /*
653068e7061SPeter Avalos * Called when ENCRYPT END is received.
654068e7061SPeter Avalos */
655068e7061SPeter Avalos void
encrypt_end(void)656068e7061SPeter Avalos encrypt_end(void)
657068e7061SPeter Avalos {
658678e8cc6SSascha Wildner decrypt_input = NULL;
659068e7061SPeter Avalos if (encrypt_debug_mode)
660068e7061SPeter Avalos printf(">>>%s: Input is back to clear text\r\n", Name);
661068e7061SPeter Avalos if (encrypt_verbose)
662068e7061SPeter Avalos printf("[ Input is now clear text ]\r\n");
663068e7061SPeter Avalos }
664068e7061SPeter Avalos
665068e7061SPeter Avalos /*
666068e7061SPeter Avalos * Called when ENCRYPT REQUEST-END is received.
667068e7061SPeter Avalos */
668068e7061SPeter Avalos void
encrypt_request_end(void)669068e7061SPeter Avalos encrypt_request_end(void)
670068e7061SPeter Avalos {
671068e7061SPeter Avalos encrypt_send_end();
672068e7061SPeter Avalos }
673068e7061SPeter Avalos
674068e7061SPeter Avalos /*
675068e7061SPeter Avalos * Called when ENCRYPT REQUEST-START is received. If we receive
676068e7061SPeter Avalos * this before a type is picked, then that indicates that the
677068e7061SPeter Avalos * other side wants us to start encrypting data as soon as we
678068e7061SPeter Avalos * can.
679068e7061SPeter Avalos */
680068e7061SPeter Avalos void
encrypt_request_start(unsigned char * data __unused,int cnt __unused)681068e7061SPeter Avalos encrypt_request_start(unsigned char *data __unused, int cnt __unused)
682068e7061SPeter Avalos {
683068e7061SPeter Avalos if (encrypt_mode == 0) {
684068e7061SPeter Avalos if (Server)
685068e7061SPeter Avalos autoencrypt = 1;
686068e7061SPeter Avalos return;
687068e7061SPeter Avalos }
688068e7061SPeter Avalos encrypt_start_output(encrypt_mode);
689068e7061SPeter Avalos }
690068e7061SPeter Avalos
691068e7061SPeter Avalos static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT };
692068e7061SPeter Avalos
693068e7061SPeter Avalos void
encrypt_enc_keyid(unsigned char * keyid,int len)694068e7061SPeter Avalos encrypt_enc_keyid(unsigned char *keyid, int len)
695068e7061SPeter Avalos {
696068e7061SPeter Avalos encrypt_keyid(&ki[1], keyid, len);
697068e7061SPeter Avalos }
698068e7061SPeter Avalos
699068e7061SPeter Avalos void
encrypt_dec_keyid(unsigned char * keyid,int len)700068e7061SPeter Avalos encrypt_dec_keyid(unsigned char *keyid, int len)
701068e7061SPeter Avalos {
702068e7061SPeter Avalos encrypt_keyid(&ki[0], keyid, len);
703068e7061SPeter Avalos }
704068e7061SPeter Avalos
705068e7061SPeter Avalos void
encrypt_keyid(struct key_info * kp,unsigned char * keyid,int len)706068e7061SPeter Avalos encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len)
707068e7061SPeter Avalos {
708068e7061SPeter Avalos Encryptions *ep;
709068e7061SPeter Avalos int dir = kp->dir;
710068e7061SPeter Avalos int ret = 0;
711068e7061SPeter Avalos
712e2decfa0SPeter Avalos if (len > MAXKEYLEN)
713e2decfa0SPeter Avalos len = MAXKEYLEN;
714e2decfa0SPeter Avalos
715068e7061SPeter Avalos if (!(ep = (*kp->getcrypt)(*kp->modep))) {
716068e7061SPeter Avalos if (len == 0)
717068e7061SPeter Avalos return;
718068e7061SPeter Avalos kp->keylen = 0;
719068e7061SPeter Avalos } else if (len == 0) {
720068e7061SPeter Avalos /*
721068e7061SPeter Avalos * Empty option, indicates a failure.
722068e7061SPeter Avalos */
723068e7061SPeter Avalos if (kp->keylen == 0)
724068e7061SPeter Avalos return;
725068e7061SPeter Avalos kp->keylen = 0;
726068e7061SPeter Avalos if (ep->keyid)
727068e7061SPeter Avalos (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
728068e7061SPeter Avalos
729068e7061SPeter Avalos } else if ((len != kp->keylen) ||
730068e7061SPeter Avalos (memcmp(keyid, kp->keyid, len) != 0)) {
731068e7061SPeter Avalos /*
732068e7061SPeter Avalos * Length or contents are different
733068e7061SPeter Avalos */
734068e7061SPeter Avalos kp->keylen = len;
735068e7061SPeter Avalos memmove(kp->keyid, keyid, len);
736068e7061SPeter Avalos if (ep->keyid)
737068e7061SPeter Avalos (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
738068e7061SPeter Avalos } else {
739068e7061SPeter Avalos if (ep->keyid)
740068e7061SPeter Avalos ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen);
741068e7061SPeter Avalos if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt)
742068e7061SPeter Avalos encrypt_start_output(*kp->modep);
743068e7061SPeter Avalos return;
744068e7061SPeter Avalos }
745068e7061SPeter Avalos
746068e7061SPeter Avalos encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0);
747068e7061SPeter Avalos }
748068e7061SPeter Avalos
749068e7061SPeter Avalos void
encrypt_send_keyid(int dir,const char * keyid,int keylen,int saveit)750068e7061SPeter Avalos encrypt_send_keyid(int dir, const char *keyid, int keylen, int saveit)
751068e7061SPeter Avalos {
752068e7061SPeter Avalos unsigned char *strp;
753068e7061SPeter Avalos
754068e7061SPeter Avalos str_keyid[3] = (dir == DIR_ENCRYPT)
755068e7061SPeter Avalos ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID;
756068e7061SPeter Avalos if (saveit) {
757068e7061SPeter Avalos struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1];
758068e7061SPeter Avalos memmove(kp->keyid, keyid, keylen);
759068e7061SPeter Avalos kp->keylen = keylen;
760068e7061SPeter Avalos }
761068e7061SPeter Avalos
762068e7061SPeter Avalos for (strp = &str_keyid[4]; keylen > 0; --keylen) {
763068e7061SPeter Avalos if ((*strp++ = *keyid++) == IAC)
764068e7061SPeter Avalos *strp++ = IAC;
765068e7061SPeter Avalos }
766068e7061SPeter Avalos *strp++ = IAC;
767068e7061SPeter Avalos *strp++ = SE;
768068e7061SPeter Avalos net_write(str_keyid, strp - str_keyid);
769068e7061SPeter Avalos printsub('>', &str_keyid[2], strp - str_keyid - 2);
770068e7061SPeter Avalos }
771068e7061SPeter Avalos
772068e7061SPeter Avalos void
encrypt_auto(int on)773068e7061SPeter Avalos encrypt_auto(int on)
774068e7061SPeter Avalos {
775068e7061SPeter Avalos if (on < 0)
776068e7061SPeter Avalos autoencrypt ^= 1;
777068e7061SPeter Avalos else
778068e7061SPeter Avalos autoencrypt = on ? 1 : 0;
779068e7061SPeter Avalos }
780068e7061SPeter Avalos
781068e7061SPeter Avalos void
decrypt_auto(int on)782068e7061SPeter Avalos decrypt_auto(int on)
783068e7061SPeter Avalos {
784068e7061SPeter Avalos if (on < 0)
785068e7061SPeter Avalos autodecrypt ^= 1;
786068e7061SPeter Avalos else
787068e7061SPeter Avalos autodecrypt = on ? 1 : 0;
788068e7061SPeter Avalos }
789068e7061SPeter Avalos
790068e7061SPeter Avalos void
encrypt_start_output(int type)791068e7061SPeter Avalos encrypt_start_output(int type)
792068e7061SPeter Avalos {
793068e7061SPeter Avalos Encryptions *ep;
794068e7061SPeter Avalos unsigned char *p;
795068e7061SPeter Avalos int i;
796068e7061SPeter Avalos
797068e7061SPeter Avalos if (!(ep = findencryption(type))) {
798068e7061SPeter Avalos if (encrypt_debug_mode) {
799068e7061SPeter Avalos printf(">>>%s: Can't encrypt with type %s (%d)\r\n",
800068e7061SPeter Avalos Name,
801068e7061SPeter Avalos ENCTYPE_NAME_OK(type)
802068e7061SPeter Avalos ? ENCTYPE_NAME(type) : "(unknown)",
803068e7061SPeter Avalos type);
804068e7061SPeter Avalos }
805068e7061SPeter Avalos return;
806068e7061SPeter Avalos }
807068e7061SPeter Avalos if (ep->start) {
808068e7061SPeter Avalos i = (*ep->start)(DIR_ENCRYPT, Server);
809068e7061SPeter Avalos if (encrypt_debug_mode) {
810068e7061SPeter Avalos printf(">>>%s: Encrypt start: %s (%d) %s\r\n",
811068e7061SPeter Avalos Name,
812068e7061SPeter Avalos (i < 0) ? "failed" :
813068e7061SPeter Avalos "initial negotiation in progress",
814068e7061SPeter Avalos i, ENCTYPE_NAME(type));
815068e7061SPeter Avalos }
816068e7061SPeter Avalos if (i)
817068e7061SPeter Avalos return;
818068e7061SPeter Avalos }
819068e7061SPeter Avalos p = str_start + 3;
820068e7061SPeter Avalos *p++ = ENCRYPT_START;
821068e7061SPeter Avalos for (i = 0; i < ki[0].keylen; ++i) {
822068e7061SPeter Avalos if ((*p++ = ki[0].keyid[i]) == IAC)
823068e7061SPeter Avalos *p++ = IAC;
824068e7061SPeter Avalos }
825068e7061SPeter Avalos *p++ = IAC;
826068e7061SPeter Avalos *p++ = SE;
827068e7061SPeter Avalos net_write(str_start, p - str_start);
828068e7061SPeter Avalos net_encrypt();
829068e7061SPeter Avalos printsub('>', &str_start[2], p - &str_start[2]);
830068e7061SPeter Avalos /*
831068e7061SPeter Avalos * If we are already encrypting in some mode, then
832068e7061SPeter Avalos * encrypt the ring (which includes our request) in
833068e7061SPeter Avalos * the old mode, mark it all as "clear text" and then
834068e7061SPeter Avalos * switch to the new mode.
835068e7061SPeter Avalos */
836068e7061SPeter Avalos encrypt_output = ep->output;
837068e7061SPeter Avalos encrypt_mode = type;
838068e7061SPeter Avalos if (encrypt_debug_mode)
839068e7061SPeter Avalos printf(">>>%s: Started to encrypt output with type %s\r\n",
840068e7061SPeter Avalos Name, ENCTYPE_NAME(type));
841068e7061SPeter Avalos if (encrypt_verbose)
842068e7061SPeter Avalos printf("[ Output is now encrypted with type %s ]\r\n",
843068e7061SPeter Avalos ENCTYPE_NAME(type));
844068e7061SPeter Avalos }
845068e7061SPeter Avalos
846068e7061SPeter Avalos void
encrypt_send_end(void)847068e7061SPeter Avalos encrypt_send_end(void)
848068e7061SPeter Avalos {
849068e7061SPeter Avalos if (!encrypt_output)
850068e7061SPeter Avalos return;
851068e7061SPeter Avalos
852068e7061SPeter Avalos str_end[3] = ENCRYPT_END;
853068e7061SPeter Avalos net_write(str_end, sizeof(str_end));
854068e7061SPeter Avalos net_encrypt();
855068e7061SPeter Avalos printsub('>', &str_end[2], sizeof(str_end) - 2);
856068e7061SPeter Avalos /*
857068e7061SPeter Avalos * Encrypt the output buffer now because it will not be done by
858068e7061SPeter Avalos * netflush...
859068e7061SPeter Avalos */
860678e8cc6SSascha Wildner encrypt_output = NULL;
861068e7061SPeter Avalos if (encrypt_debug_mode)
862068e7061SPeter Avalos printf(">>>%s: Output is back to clear text\r\n", Name);
863068e7061SPeter Avalos if (encrypt_verbose)
864068e7061SPeter Avalos printf("[ Output is now clear text ]\r\n");
865068e7061SPeter Avalos }
866068e7061SPeter Avalos
867068e7061SPeter Avalos void
encrypt_send_request_start(void)868068e7061SPeter Avalos encrypt_send_request_start(void)
869068e7061SPeter Avalos {
870068e7061SPeter Avalos unsigned char *p;
871068e7061SPeter Avalos int i;
872068e7061SPeter Avalos
873068e7061SPeter Avalos p = &str_start[3];
874068e7061SPeter Avalos *p++ = ENCRYPT_REQSTART;
875068e7061SPeter Avalos for (i = 0; i < ki[1].keylen; ++i) {
876068e7061SPeter Avalos if ((*p++ = ki[1].keyid[i]) == IAC)
877068e7061SPeter Avalos *p++ = IAC;
878068e7061SPeter Avalos }
879068e7061SPeter Avalos *p++ = IAC;
880068e7061SPeter Avalos *p++ = SE;
881068e7061SPeter Avalos net_write(str_start, p - str_start);
882068e7061SPeter Avalos printsub('>', &str_start[2], p - &str_start[2]);
883068e7061SPeter Avalos if (encrypt_debug_mode)
884068e7061SPeter Avalos printf(">>>%s: Request input to be encrypted\r\n", Name);
885068e7061SPeter Avalos }
886068e7061SPeter Avalos
887068e7061SPeter Avalos void
encrypt_send_request_end(void)888068e7061SPeter Avalos encrypt_send_request_end(void)
889068e7061SPeter Avalos {
890068e7061SPeter Avalos str_end[3] = ENCRYPT_REQEND;
891068e7061SPeter Avalos net_write(str_end, sizeof(str_end));
892068e7061SPeter Avalos printsub('>', &str_end[2], sizeof(str_end) - 2);
893068e7061SPeter Avalos
894068e7061SPeter Avalos if (encrypt_debug_mode)
895068e7061SPeter Avalos printf(">>>%s: Request input to be clear text\r\n", Name);
896068e7061SPeter Avalos }
897068e7061SPeter Avalos
898068e7061SPeter Avalos void
encrypt_wait(void)899068e7061SPeter Avalos encrypt_wait(void)
900068e7061SPeter Avalos {
901068e7061SPeter Avalos if (encrypt_debug_mode)
902068e7061SPeter Avalos printf(">>>%s: in encrypt_wait\r\n", Name);
903068e7061SPeter Avalos if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt))
904068e7061SPeter Avalos return;
905068e7061SPeter Avalos while (autoencrypt && !encrypt_output)
906068e7061SPeter Avalos if (telnet_spin())
907068e7061SPeter Avalos return;
908068e7061SPeter Avalos }
909068e7061SPeter Avalos
910068e7061SPeter Avalos void
encrypt_gen_printsub(unsigned char * data,int cnt,unsigned char * buf,int buflen)911068e7061SPeter Avalos encrypt_gen_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
912068e7061SPeter Avalos {
913068e7061SPeter Avalos char tbuf[16], *cp;
914068e7061SPeter Avalos
915068e7061SPeter Avalos cnt -= 2;
916068e7061SPeter Avalos data += 2;
917068e7061SPeter Avalos buf[buflen-1] = '\0';
918068e7061SPeter Avalos buf[buflen-2] = '*';
9193598cc14SSascha Wildner buflen -= 2;
920068e7061SPeter Avalos for (; cnt > 0; cnt--, data++) {
921068e7061SPeter Avalos sprintf(tbuf, " %d", *data);
922068e7061SPeter Avalos for (cp = tbuf; *cp && buflen > 0; --buflen)
923068e7061SPeter Avalos *buf++ = *cp++;
924068e7061SPeter Avalos if (buflen <= 0)
925068e7061SPeter Avalos return;
926068e7061SPeter Avalos }
927068e7061SPeter Avalos *buf = '\0';
928068e7061SPeter Avalos }
929068e7061SPeter Avalos
930068e7061SPeter Avalos void
encrypt_printsub(unsigned char * data,int cnt,unsigned char * buf,int buflen)931068e7061SPeter Avalos encrypt_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
932068e7061SPeter Avalos {
933068e7061SPeter Avalos Encryptions *ep;
934068e7061SPeter Avalos int type = data[1];
935068e7061SPeter Avalos
936068e7061SPeter Avalos for (ep = encryptions; ep->type && ep->type != type; ep++)
937068e7061SPeter Avalos ;
938068e7061SPeter Avalos
939068e7061SPeter Avalos if (ep->printsub)
940068e7061SPeter Avalos (*ep->printsub)(data, cnt, buf, buflen);
941068e7061SPeter Avalos else
942068e7061SPeter Avalos encrypt_gen_printsub(data, cnt, buf, buflen);
943068e7061SPeter Avalos }
944068e7061SPeter Avalos #endif /* ENCRYPTION */
945