181cb6ddcSMark Murray /*- 281cb6ddcSMark Murray * Copyright (c) 1991, 1993 381cb6ddcSMark Murray * The Regents of the University of California. All rights reserved. 481cb6ddcSMark Murray * 581cb6ddcSMark Murray * Redistribution and use in source and binary forms, with or without 681cb6ddcSMark Murray * modification, are permitted provided that the following conditions 781cb6ddcSMark Murray * are met: 881cb6ddcSMark Murray * 1. Redistributions of source code must retain the above copyright 981cb6ddcSMark Murray * notice, this list of conditions and the following disclaimer. 1081cb6ddcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 1181cb6ddcSMark Murray * notice, this list of conditions and the following disclaimer in the 1281cb6ddcSMark Murray * documentation and/or other materials provided with the distribution. 1381cb6ddcSMark Murray * 3. All advertising materials mentioning features or use of this software 1481cb6ddcSMark Murray * must display the following acknowledgement: 1581cb6ddcSMark Murray * This product includes software developed by the University of 1681cb6ddcSMark Murray * California, Berkeley and its contributors. 1781cb6ddcSMark Murray * 4. Neither the name of the University nor the names of its contributors 1881cb6ddcSMark Murray * may be used to endorse or promote products derived from this software 1981cb6ddcSMark Murray * without specific prior written permission. 2081cb6ddcSMark Murray * 2181cb6ddcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2281cb6ddcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2381cb6ddcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2481cb6ddcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2581cb6ddcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2681cb6ddcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2781cb6ddcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2881cb6ddcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2981cb6ddcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3081cb6ddcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3181cb6ddcSMark Murray * SUCH DAMAGE. 3281cb6ddcSMark Murray */ 3381cb6ddcSMark Murray 34f2ac7de9SMark Murray #include <sys/cdefs.h> 358fa113e5SMark Murray 36f2ac7de9SMark Murray __FBSDID("$FreeBSD$"); 37f2ac7de9SMark Murray 3881cb6ddcSMark Murray #ifndef lint 39ecece7e3SPeter Wemm #if 0 4004c426ccSMark Murray static const char sccsid[] = "@(#)encrypt.c 8.2 (Berkeley) 5/30/95"; 41ecece7e3SPeter Wemm #endif 4281cb6ddcSMark Murray #endif /* not lint */ 4381cb6ddcSMark Murray 4481cb6ddcSMark Murray /* 4581cb6ddcSMark Murray * Copyright (C) 1990 by the Massachusetts Institute of Technology 4681cb6ddcSMark Murray * 4781cb6ddcSMark Murray * Export of this software from the United States of America is assumed 4881cb6ddcSMark Murray * to require a specific license from the United States Government. 4981cb6ddcSMark Murray * It is the responsibility of any person or organization contemplating 5081cb6ddcSMark Murray * export to obtain such a license before exporting. 5181cb6ddcSMark Murray * 5281cb6ddcSMark Murray * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 5381cb6ddcSMark Murray * distribute this software and its documentation for any purpose and 5481cb6ddcSMark Murray * without fee is hereby granted, provided that the above copyright 5581cb6ddcSMark Murray * notice appear in all copies and that both that copyright notice and 5681cb6ddcSMark Murray * this permission notice appear in supporting documentation, and that 5781cb6ddcSMark Murray * the name of M.I.T. not be used in advertising or publicity pertaining 5881cb6ddcSMark Murray * to distribution of the software without specific, written prior 5981cb6ddcSMark Murray * permission. M.I.T. makes no representations about the suitability of 6081cb6ddcSMark Murray * this software for any purpose. It is provided "as is" without express 6181cb6ddcSMark Murray * or implied warranty. 6281cb6ddcSMark Murray */ 6381cb6ddcSMark Murray 6481cb6ddcSMark Murray #ifdef ENCRYPTION 6581cb6ddcSMark Murray 6678455da4SMark Murray #include <sys/types.h> 6781cb6ddcSMark Murray #define ENCRYPT_NAMES 6881cb6ddcSMark Murray #include <arpa/telnet.h> 698fa113e5SMark Murray #include <stdio.h> 708fa113e5SMark Murray #include <stdlib.h> 718fa113e5SMark Murray #include <string.h> 7281cb6ddcSMark Murray 7381cb6ddcSMark Murray #include "encrypt.h" 7481cb6ddcSMark Murray #include "misc.h" 7581cb6ddcSMark Murray 7681cb6ddcSMark Murray /* 7781cb6ddcSMark Murray * These functions pointers point to the current routines 7881cb6ddcSMark Murray * for encrypting and decrypting data. 7981cb6ddcSMark Murray */ 803138440aSMark Murray void (*encrypt_output)(unsigned char *, int); 813138440aSMark Murray int (*decrypt_input)(int); 8281cb6ddcSMark Murray 8304c426ccSMark Murray int EncryptType(char *type, char *mode); 8404c426ccSMark Murray int EncryptStart(char *mode); 8504c426ccSMark Murray int EncryptStop(char *mode); 8604c426ccSMark Murray int EncryptStartInput(void); 8704c426ccSMark Murray int EncryptStartOutput(void); 8804c426ccSMark Murray int EncryptStopInput(void); 8904c426ccSMark Murray int EncryptStopOutput(void); 9004c426ccSMark Murray 9181cb6ddcSMark Murray int encrypt_debug_mode = 0; 9281cb6ddcSMark Murray static int decrypt_mode = 0; 9381cb6ddcSMark Murray static int encrypt_mode = 0; 9481cb6ddcSMark Murray static int encrypt_verbose = 0; 9581cb6ddcSMark Murray static int autoencrypt = 0; 9681cb6ddcSMark Murray static int autodecrypt = 0; 9781cb6ddcSMark Murray static int havesessionkey = 0; 9881cb6ddcSMark Murray static int Server = 0; 998fa113e5SMark Murray static const char *Name = "Noname"; 10081cb6ddcSMark Murray 10181cb6ddcSMark Murray #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 10281cb6ddcSMark Murray 10378455da4SMark Murray static u_long i_support_encrypt = 0 1040f8c8396SNick Sayer | typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64) 1050f8c8396SNick Sayer |0; 10678455da4SMark Murray static u_long i_support_decrypt = 0 1070f8c8396SNick Sayer | typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64) 1080f8c8396SNick Sayer |0; 1090f8c8396SNick Sayer 11078455da4SMark Murray static u_long i_wont_support_encrypt = 0; 11178455da4SMark Murray static u_long i_wont_support_decrypt = 0; 11281cb6ddcSMark Murray #define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt) 11381cb6ddcSMark Murray #define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt) 11481cb6ddcSMark Murray 11578455da4SMark Murray static u_long remote_supports_encrypt = 0; 11678455da4SMark Murray static u_long remote_supports_decrypt = 0; 11781cb6ddcSMark Murray 11881cb6ddcSMark Murray static Encryptions encryptions[] = { 11981cb6ddcSMark Murray { "DES_CFB64", ENCTYPE_DES_CFB64, 12081cb6ddcSMark Murray cfb64_encrypt, 12181cb6ddcSMark Murray cfb64_decrypt, 12281cb6ddcSMark Murray cfb64_init, 12381cb6ddcSMark Murray cfb64_start, 12481cb6ddcSMark Murray cfb64_is, 12581cb6ddcSMark Murray cfb64_reply, 12681cb6ddcSMark Murray cfb64_session, 12781cb6ddcSMark Murray cfb64_keyid, 12881cb6ddcSMark Murray cfb64_printsub }, 12981cb6ddcSMark Murray { "DES_OFB64", ENCTYPE_DES_OFB64, 13081cb6ddcSMark Murray ofb64_encrypt, 13181cb6ddcSMark Murray ofb64_decrypt, 13281cb6ddcSMark Murray ofb64_init, 13381cb6ddcSMark Murray ofb64_start, 13481cb6ddcSMark Murray ofb64_is, 13581cb6ddcSMark Murray ofb64_reply, 13681cb6ddcSMark Murray ofb64_session, 13781cb6ddcSMark Murray ofb64_keyid, 13881cb6ddcSMark Murray ofb64_printsub }, 1398fa113e5SMark Murray { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 14081cb6ddcSMark Murray }; 14181cb6ddcSMark Murray 14281cb6ddcSMark Murray static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, 14381cb6ddcSMark Murray ENCRYPT_SUPPORT }; 14481cb6ddcSMark Murray static unsigned char str_suplen = 0; 14581cb6ddcSMark Murray static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT }; 14681cb6ddcSMark Murray static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; 14781cb6ddcSMark Murray 14881cb6ddcSMark Murray Encryptions * 1498fa113e5SMark Murray findencryption(int type) 15081cb6ddcSMark Murray { 15181cb6ddcSMark Murray Encryptions *ep = encryptions; 15281cb6ddcSMark Murray 1538fa113e5SMark Murray if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & (unsigned)typemask(type))) 15481cb6ddcSMark Murray return(0); 15581cb6ddcSMark Murray while (ep->type && ep->type != type) 15681cb6ddcSMark Murray ++ep; 15781cb6ddcSMark Murray return(ep->type ? ep : 0); 15881cb6ddcSMark Murray } 15981cb6ddcSMark Murray 1608fa113e5SMark Murray static Encryptions * 1618fa113e5SMark Murray finddecryption(int type) 16281cb6ddcSMark Murray { 16381cb6ddcSMark Murray Encryptions *ep = encryptions; 16481cb6ddcSMark Murray 1658fa113e5SMark Murray if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & (unsigned)typemask(type))) 16681cb6ddcSMark Murray return(0); 16781cb6ddcSMark Murray while (ep->type && ep->type != type) 16881cb6ddcSMark Murray ++ep; 16981cb6ddcSMark Murray return(ep->type ? ep : 0); 17081cb6ddcSMark Murray } 17181cb6ddcSMark Murray 17281cb6ddcSMark Murray #define MAXKEYLEN 64 17381cb6ddcSMark Murray 17481cb6ddcSMark Murray static struct key_info { 17581cb6ddcSMark Murray unsigned char keyid[MAXKEYLEN]; 17681cb6ddcSMark Murray int keylen; 17781cb6ddcSMark Murray int dir; 17881cb6ddcSMark Murray int *modep; 1798fa113e5SMark Murray Encryptions *(*getcrypt)(int); 18081cb6ddcSMark Murray } ki[2] = { 18181cb6ddcSMark Murray { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption }, 18281cb6ddcSMark Murray { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption }, 18381cb6ddcSMark Murray }; 18481cb6ddcSMark Murray 18504c426ccSMark Murray static void encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len); 18604c426ccSMark Murray 18781cb6ddcSMark Murray void 1888fa113e5SMark Murray encrypt_init(const char *name, int server) 18981cb6ddcSMark Murray { 19081cb6ddcSMark Murray Encryptions *ep = encryptions; 19181cb6ddcSMark Murray 19281cb6ddcSMark Murray Name = name; 19381cb6ddcSMark Murray Server = server; 19481cb6ddcSMark Murray i_support_encrypt = i_support_decrypt = 0; 19581cb6ddcSMark Murray remote_supports_encrypt = remote_supports_decrypt = 0; 19681cb6ddcSMark Murray encrypt_mode = 0; 19781cb6ddcSMark Murray decrypt_mode = 0; 19881cb6ddcSMark Murray encrypt_output = 0; 19981cb6ddcSMark Murray decrypt_input = 0; 20081cb6ddcSMark Murray 20181cb6ddcSMark Murray str_suplen = 4; 20281cb6ddcSMark Murray 20381cb6ddcSMark Murray while (ep->type) { 20481cb6ddcSMark Murray if (encrypt_debug_mode) 20581cb6ddcSMark Murray printf(">>>%s: I will support %s\r\n", 20681cb6ddcSMark Murray Name, ENCTYPE_NAME(ep->type)); 20781cb6ddcSMark Murray i_support_encrypt |= typemask(ep->type); 20881cb6ddcSMark Murray i_support_decrypt |= typemask(ep->type); 20981cb6ddcSMark Murray if ((i_wont_support_decrypt & typemask(ep->type)) == 0) 21081cb6ddcSMark Murray if ((str_send[str_suplen++] = ep->type) == IAC) 21181cb6ddcSMark Murray str_send[str_suplen++] = IAC; 21281cb6ddcSMark Murray if (ep->init) 21381cb6ddcSMark Murray (*ep->init)(Server); 21481cb6ddcSMark Murray ++ep; 21581cb6ddcSMark Murray } 21681cb6ddcSMark Murray str_send[str_suplen++] = IAC; 21781cb6ddcSMark Murray str_send[str_suplen++] = SE; 21881cb6ddcSMark Murray } 21981cb6ddcSMark Murray 2208fa113e5SMark Murray static void 2218fa113e5SMark Murray encrypt_list_types(void) 22281cb6ddcSMark Murray { 22381cb6ddcSMark Murray Encryptions *ep = encryptions; 22481cb6ddcSMark Murray 22581cb6ddcSMark Murray printf("Valid encryption types:\n"); 22681cb6ddcSMark Murray while (ep->type) { 22781cb6ddcSMark Murray printf("\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type); 22881cb6ddcSMark Murray ++ep; 22981cb6ddcSMark Murray } 23081cb6ddcSMark Murray } 23181cb6ddcSMark Murray 23281cb6ddcSMark Murray int 2338fa113e5SMark Murray EncryptEnable(char *type, char *mode) 23481cb6ddcSMark Murray { 23581cb6ddcSMark Murray if (isprefix(type, "help") || isprefix(type, "?")) { 23681cb6ddcSMark Murray printf("Usage: encrypt enable <type> [input|output]\n"); 23781cb6ddcSMark Murray encrypt_list_types(); 23881cb6ddcSMark Murray return(0); 23981cb6ddcSMark Murray } 24081cb6ddcSMark Murray if (EncryptType(type, mode)) 24181cb6ddcSMark Murray return(EncryptStart(mode)); 24281cb6ddcSMark Murray return(0); 24381cb6ddcSMark Murray } 24481cb6ddcSMark Murray 24581cb6ddcSMark Murray int 2468fa113e5SMark Murray EncryptDisable(char *type, char *mode) 24781cb6ddcSMark Murray { 2488fa113e5SMark Murray Encryptions *ep; 24981cb6ddcSMark Murray int ret = 0; 25081cb6ddcSMark Murray 25181cb6ddcSMark Murray if (isprefix(type, "help") || isprefix(type, "?")) { 25281cb6ddcSMark Murray printf("Usage: encrypt disable <type> [input|output]\n"); 25381cb6ddcSMark Murray encrypt_list_types(); 25404c426ccSMark Murray } else if ((ep = (Encryptions *)genget(type, (char **)encryptions, 25581cb6ddcSMark Murray sizeof(Encryptions))) == 0) { 25681cb6ddcSMark Murray printf("%s: invalid encryption type\n", type); 25704c426ccSMark Murray } else if (Ambiguous((char **)ep)) { 25881cb6ddcSMark Murray printf("Ambiguous type '%s'\n", type); 25981cb6ddcSMark Murray } else { 26081cb6ddcSMark Murray if ((mode == 0) || (isprefix(mode, "input") ? 1 : 0)) { 26181cb6ddcSMark Murray if (decrypt_mode == ep->type) 26281cb6ddcSMark Murray EncryptStopInput(); 26381cb6ddcSMark Murray i_wont_support_decrypt |= typemask(ep->type); 26481cb6ddcSMark Murray ret = 1; 26581cb6ddcSMark Murray } 26681cb6ddcSMark Murray if ((mode == 0) || (isprefix(mode, "output"))) { 26781cb6ddcSMark Murray if (encrypt_mode == ep->type) 26881cb6ddcSMark Murray EncryptStopOutput(); 26981cb6ddcSMark Murray i_wont_support_encrypt |= typemask(ep->type); 27081cb6ddcSMark Murray ret = 1; 27181cb6ddcSMark Murray } 27281cb6ddcSMark Murray if (ret == 0) 27381cb6ddcSMark Murray printf("%s: invalid encryption mode\n", mode); 27481cb6ddcSMark Murray } 27581cb6ddcSMark Murray return(ret); 27681cb6ddcSMark Murray } 27781cb6ddcSMark Murray 27881cb6ddcSMark Murray int 2798fa113e5SMark Murray EncryptType(char *type, char *mode) 28081cb6ddcSMark Murray { 2818fa113e5SMark Murray Encryptions *ep; 28281cb6ddcSMark Murray int ret = 0; 28381cb6ddcSMark Murray 28481cb6ddcSMark Murray if (isprefix(type, "help") || isprefix(type, "?")) { 28581cb6ddcSMark Murray printf("Usage: encrypt type <type> [input|output]\n"); 28681cb6ddcSMark Murray encrypt_list_types(); 28704c426ccSMark Murray } else if ((ep = (Encryptions *)genget(type, (char **)encryptions, 28881cb6ddcSMark Murray sizeof(Encryptions))) == 0) { 28981cb6ddcSMark Murray printf("%s: invalid encryption type\n", type); 29004c426ccSMark Murray } else if (Ambiguous((char **)ep)) { 29181cb6ddcSMark Murray printf("Ambiguous type '%s'\n", type); 29281cb6ddcSMark Murray } else { 29381cb6ddcSMark Murray if ((mode == 0) || isprefix(mode, "input")) { 29481cb6ddcSMark Murray decrypt_mode = ep->type; 29581cb6ddcSMark Murray i_wont_support_decrypt &= ~typemask(ep->type); 29681cb6ddcSMark Murray ret = 1; 29781cb6ddcSMark Murray } 29881cb6ddcSMark Murray if ((mode == 0) || isprefix(mode, "output")) { 29981cb6ddcSMark Murray encrypt_mode = ep->type; 30081cb6ddcSMark Murray i_wont_support_encrypt &= ~typemask(ep->type); 30181cb6ddcSMark Murray ret = 1; 30281cb6ddcSMark Murray } 30381cb6ddcSMark Murray if (ret == 0) 30481cb6ddcSMark Murray printf("%s: invalid encryption mode\n", mode); 30581cb6ddcSMark Murray } 30681cb6ddcSMark Murray return(ret); 30781cb6ddcSMark Murray } 30881cb6ddcSMark Murray 30981cb6ddcSMark Murray int 3108fa113e5SMark Murray EncryptStart(char *mode) 31181cb6ddcSMark Murray { 3128fa113e5SMark Murray int ret = 0; 31381cb6ddcSMark Murray if (mode) { 31481cb6ddcSMark Murray if (isprefix(mode, "input")) 31581cb6ddcSMark Murray return(EncryptStartInput()); 31681cb6ddcSMark Murray if (isprefix(mode, "output")) 31781cb6ddcSMark Murray return(EncryptStartOutput()); 31881cb6ddcSMark Murray if (isprefix(mode, "help") || isprefix(mode, "?")) { 31981cb6ddcSMark Murray printf("Usage: encrypt start [input|output]\n"); 32081cb6ddcSMark Murray return(0); 32181cb6ddcSMark Murray } 32281cb6ddcSMark Murray printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode); 32381cb6ddcSMark Murray return(0); 32481cb6ddcSMark Murray } 32581cb6ddcSMark Murray ret += EncryptStartInput(); 32681cb6ddcSMark Murray ret += EncryptStartOutput(); 32781cb6ddcSMark Murray return(ret); 32881cb6ddcSMark Murray } 32981cb6ddcSMark Murray 33081cb6ddcSMark Murray int 3318fa113e5SMark Murray EncryptStartInput(void) 33281cb6ddcSMark Murray { 33381cb6ddcSMark Murray if (decrypt_mode) { 33481cb6ddcSMark Murray encrypt_send_request_start(); 33581cb6ddcSMark Murray return(1); 33681cb6ddcSMark Murray } 33781cb6ddcSMark Murray printf("No previous decryption mode, decryption not enabled\r\n"); 33881cb6ddcSMark Murray return(0); 33981cb6ddcSMark Murray } 34081cb6ddcSMark Murray 34181cb6ddcSMark Murray int 3428fa113e5SMark Murray EncryptStartOutput(void) 34381cb6ddcSMark Murray { 34481cb6ddcSMark Murray if (encrypt_mode) { 34581cb6ddcSMark Murray encrypt_start_output(encrypt_mode); 34681cb6ddcSMark Murray return(1); 34781cb6ddcSMark Murray } 34881cb6ddcSMark Murray printf("No previous encryption mode, encryption not enabled\r\n"); 34981cb6ddcSMark Murray return(0); 35081cb6ddcSMark Murray } 35181cb6ddcSMark Murray 35281cb6ddcSMark Murray int 3538fa113e5SMark Murray EncryptStop(char *mode) 35481cb6ddcSMark Murray { 35581cb6ddcSMark Murray int ret = 0; 35681cb6ddcSMark Murray if (mode) { 35781cb6ddcSMark Murray if (isprefix(mode, "input")) 35881cb6ddcSMark Murray return(EncryptStopInput()); 35981cb6ddcSMark Murray if (isprefix(mode, "output")) 36081cb6ddcSMark Murray return(EncryptStopOutput()); 36181cb6ddcSMark Murray if (isprefix(mode, "help") || isprefix(mode, "?")) { 36281cb6ddcSMark Murray printf("Usage: encrypt stop [input|output]\n"); 36381cb6ddcSMark Murray return(0); 36481cb6ddcSMark Murray } 36581cb6ddcSMark Murray printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode); 36681cb6ddcSMark Murray return(0); 36781cb6ddcSMark Murray } 36881cb6ddcSMark Murray ret += EncryptStopInput(); 36981cb6ddcSMark Murray ret += EncryptStopOutput(); 37081cb6ddcSMark Murray return(ret); 37181cb6ddcSMark Murray } 37281cb6ddcSMark Murray 37381cb6ddcSMark Murray int 3748fa113e5SMark Murray EncryptStopInput(void) 37581cb6ddcSMark Murray { 37681cb6ddcSMark Murray encrypt_send_request_end(); 37781cb6ddcSMark Murray return(1); 37881cb6ddcSMark Murray } 37981cb6ddcSMark Murray 38081cb6ddcSMark Murray int 3818fa113e5SMark Murray EncryptStopOutput(void) 38281cb6ddcSMark Murray { 38381cb6ddcSMark Murray encrypt_send_end(); 38481cb6ddcSMark Murray return(1); 38581cb6ddcSMark Murray } 38681cb6ddcSMark Murray 38781cb6ddcSMark Murray void 3888fa113e5SMark Murray encrypt_display(void) 38981cb6ddcSMark Murray { 39081cb6ddcSMark Murray if (encrypt_output) 39181cb6ddcSMark Murray printf("Currently encrypting output with %s\r\n", 39281cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 39381cb6ddcSMark Murray if (decrypt_input) 39481cb6ddcSMark Murray printf("Currently decrypting input with %s\r\n", 39581cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 39681cb6ddcSMark Murray } 39781cb6ddcSMark Murray 39881cb6ddcSMark Murray int 3998fa113e5SMark Murray EncryptStatus(void) 40081cb6ddcSMark Murray { 40181cb6ddcSMark Murray if (encrypt_output) 40281cb6ddcSMark Murray printf("Currently encrypting output with %s\r\n", 40381cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 40481cb6ddcSMark Murray else if (encrypt_mode) { 40581cb6ddcSMark Murray printf("Currently output is clear text.\r\n"); 40681cb6ddcSMark Murray printf("Last encryption mode was %s\r\n", 40781cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 40881cb6ddcSMark Murray } 40981cb6ddcSMark Murray if (decrypt_input) { 41081cb6ddcSMark Murray printf("Currently decrypting input with %s\r\n", 41181cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 41281cb6ddcSMark Murray } else if (decrypt_mode) { 41381cb6ddcSMark Murray printf("Currently input is clear text.\r\n"); 41481cb6ddcSMark Murray printf("Last decryption mode was %s\r\n", 41581cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 41681cb6ddcSMark Murray } 41781cb6ddcSMark Murray return 1; 41881cb6ddcSMark Murray } 41981cb6ddcSMark Murray 42081cb6ddcSMark Murray void 4218fa113e5SMark Murray encrypt_send_support(void) 42281cb6ddcSMark Murray { 42381cb6ddcSMark Murray if (str_suplen) { 42481cb6ddcSMark Murray /* 42581cb6ddcSMark Murray * If the user has requested that decryption start 42681cb6ddcSMark Murray * immediatly, then send a "REQUEST START" before 42781cb6ddcSMark Murray * we negotiate the type. 42881cb6ddcSMark Murray */ 42981cb6ddcSMark Murray if (!Server && autodecrypt) 43081cb6ddcSMark Murray encrypt_send_request_start(); 43181cb6ddcSMark Murray net_write(str_send, str_suplen); 43281cb6ddcSMark Murray printsub('>', &str_send[2], str_suplen - 2); 43381cb6ddcSMark Murray str_suplen = 0; 43481cb6ddcSMark Murray } 43581cb6ddcSMark Murray } 43681cb6ddcSMark Murray 43781cb6ddcSMark Murray int 4388fa113e5SMark Murray EncryptDebug(int on) 43981cb6ddcSMark Murray { 44081cb6ddcSMark Murray if (on < 0) 44181cb6ddcSMark Murray encrypt_debug_mode ^= 1; 44281cb6ddcSMark Murray else 44381cb6ddcSMark Murray encrypt_debug_mode = on; 44481cb6ddcSMark Murray printf("Encryption debugging %s\r\n", 44581cb6ddcSMark Murray encrypt_debug_mode ? "enabled" : "disabled"); 44681cb6ddcSMark Murray return(1); 44781cb6ddcSMark Murray } 44881cb6ddcSMark Murray 44981cb6ddcSMark Murray int 4508fa113e5SMark Murray EncryptVerbose(int on) 45181cb6ddcSMark Murray { 45281cb6ddcSMark Murray if (on < 0) 45381cb6ddcSMark Murray encrypt_verbose ^= 1; 45481cb6ddcSMark Murray else 45581cb6ddcSMark Murray encrypt_verbose = on; 45681cb6ddcSMark Murray printf("Encryption %s verbose\r\n", 45781cb6ddcSMark Murray encrypt_verbose ? "is" : "is not"); 45881cb6ddcSMark Murray return(1); 45981cb6ddcSMark Murray } 46081cb6ddcSMark Murray 46181cb6ddcSMark Murray int 4628fa113e5SMark Murray EncryptAutoEnc(int on) 46381cb6ddcSMark Murray { 46481cb6ddcSMark Murray encrypt_auto(on); 46581cb6ddcSMark Murray printf("Automatic encryption of output is %s\r\n", 46681cb6ddcSMark Murray autoencrypt ? "enabled" : "disabled"); 46781cb6ddcSMark Murray return(1); 46881cb6ddcSMark Murray } 46981cb6ddcSMark Murray 47081cb6ddcSMark Murray int 4718fa113e5SMark Murray EncryptAutoDec(int on) 47281cb6ddcSMark Murray { 47381cb6ddcSMark Murray decrypt_auto(on); 47481cb6ddcSMark Murray printf("Automatic decryption of input is %s\r\n", 47581cb6ddcSMark Murray autodecrypt ? "enabled" : "disabled"); 47681cb6ddcSMark Murray return(1); 47781cb6ddcSMark Murray } 47881cb6ddcSMark Murray 47981cb6ddcSMark Murray /* 48081cb6ddcSMark Murray * Called when ENCRYPT SUPPORT is received. 48181cb6ddcSMark Murray */ 48281cb6ddcSMark Murray void 4838fa113e5SMark Murray encrypt_support(unsigned char *typelist, int cnt) 48481cb6ddcSMark Murray { 4858fa113e5SMark Murray int type, use_type = 0; 48681cb6ddcSMark Murray Encryptions *ep; 48781cb6ddcSMark Murray 48881cb6ddcSMark Murray /* 48981cb6ddcSMark Murray * Forget anything the other side has previously told us. 49081cb6ddcSMark Murray */ 49181cb6ddcSMark Murray remote_supports_decrypt = 0; 49281cb6ddcSMark Murray 49381cb6ddcSMark Murray while (cnt-- > 0) { 49481cb6ddcSMark Murray type = *typelist++; 49581cb6ddcSMark Murray if (encrypt_debug_mode) 49681cb6ddcSMark Murray printf(">>>%s: He is supporting %s (%d)\r\n", 49781cb6ddcSMark Murray Name, 49881cb6ddcSMark Murray ENCTYPE_NAME(type), type); 49981cb6ddcSMark Murray if ((type < ENCTYPE_CNT) && 50081cb6ddcSMark Murray (I_SUPPORT_ENCRYPT & typemask(type))) { 50181cb6ddcSMark Murray remote_supports_decrypt |= typemask(type); 50281cb6ddcSMark Murray if (use_type == 0) 50381cb6ddcSMark Murray use_type = type; 50481cb6ddcSMark Murray } 50581cb6ddcSMark Murray } 50681cb6ddcSMark Murray if (use_type) { 50781cb6ddcSMark Murray ep = findencryption(use_type); 50881cb6ddcSMark Murray if (!ep) 50981cb6ddcSMark Murray return; 51081cb6ddcSMark Murray type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0; 51181cb6ddcSMark Murray if (encrypt_debug_mode) 51281cb6ddcSMark Murray printf(">>>%s: (*ep->start)() returned %d\r\n", 51381cb6ddcSMark Murray Name, type); 51481cb6ddcSMark Murray if (type < 0) 51581cb6ddcSMark Murray return; 51681cb6ddcSMark Murray encrypt_mode = use_type; 51781cb6ddcSMark Murray if (type == 0) 51881cb6ddcSMark Murray encrypt_start_output(use_type); 51981cb6ddcSMark Murray } 52081cb6ddcSMark Murray } 52181cb6ddcSMark Murray 52281cb6ddcSMark Murray void 5238fa113e5SMark Murray encrypt_is(unsigned char *data, int cnt) 52481cb6ddcSMark Murray { 52581cb6ddcSMark Murray Encryptions *ep; 5268fa113e5SMark Murray int type, ret; 52781cb6ddcSMark Murray 52881cb6ddcSMark Murray if (--cnt < 0) 52981cb6ddcSMark Murray return; 53081cb6ddcSMark Murray type = *data++; 53181cb6ddcSMark Murray if (type < ENCTYPE_CNT) 53281cb6ddcSMark Murray remote_supports_encrypt |= typemask(type); 53381cb6ddcSMark Murray if (!(ep = finddecryption(type))) { 53481cb6ddcSMark Murray if (encrypt_debug_mode) 53581cb6ddcSMark Murray printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 53681cb6ddcSMark Murray Name, 53781cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 53881cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 53981cb6ddcSMark Murray type); 54081cb6ddcSMark Murray return; 54181cb6ddcSMark Murray } 54281cb6ddcSMark Murray if (!ep->is) { 54381cb6ddcSMark Murray if (encrypt_debug_mode) 54481cb6ddcSMark Murray printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 54581cb6ddcSMark Murray Name, 54681cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 54781cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 54881cb6ddcSMark Murray type); 54981cb6ddcSMark Murray ret = 0; 55081cb6ddcSMark Murray } else { 55181cb6ddcSMark Murray ret = (*ep->is)(data, cnt); 55281cb6ddcSMark Murray if (encrypt_debug_mode) 55304c426ccSMark Murray printf("(*ep->is)(%p, %d) returned %s(%d)\n", data, cnt, 55481cb6ddcSMark Murray (ret < 0) ? "FAIL " : 55581cb6ddcSMark Murray (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 55681cb6ddcSMark Murray } 55781cb6ddcSMark Murray if (ret < 0) { 55881cb6ddcSMark Murray autodecrypt = 0; 55981cb6ddcSMark Murray } else { 56081cb6ddcSMark Murray decrypt_mode = type; 56181cb6ddcSMark Murray if (ret == 0 && autodecrypt) 56281cb6ddcSMark Murray encrypt_send_request_start(); 56381cb6ddcSMark Murray } 56481cb6ddcSMark Murray } 56581cb6ddcSMark Murray 56681cb6ddcSMark Murray void 5678fa113e5SMark Murray encrypt_reply(unsigned char *data, int cnt) 56881cb6ddcSMark Murray { 56981cb6ddcSMark Murray Encryptions *ep; 5708fa113e5SMark Murray int ret, type; 57181cb6ddcSMark Murray 57281cb6ddcSMark Murray if (--cnt < 0) 57381cb6ddcSMark Murray return; 57481cb6ddcSMark Murray type = *data++; 57581cb6ddcSMark Murray if (!(ep = findencryption(type))) { 57681cb6ddcSMark Murray if (encrypt_debug_mode) 57781cb6ddcSMark Murray printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 57881cb6ddcSMark Murray Name, 57981cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 58081cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 58181cb6ddcSMark Murray type); 58281cb6ddcSMark Murray return; 58381cb6ddcSMark Murray } 58481cb6ddcSMark Murray if (!ep->reply) { 58581cb6ddcSMark Murray if (encrypt_debug_mode) 58681cb6ddcSMark Murray printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 58781cb6ddcSMark Murray Name, 58881cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 58981cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 59081cb6ddcSMark Murray type); 59181cb6ddcSMark Murray ret = 0; 59281cb6ddcSMark Murray } else { 59381cb6ddcSMark Murray ret = (*ep->reply)(data, cnt); 59481cb6ddcSMark Murray if (encrypt_debug_mode) 59504c426ccSMark Murray printf("(*ep->reply)(%p, %d) returned %s(%d)\n", 59681cb6ddcSMark Murray data, cnt, 59781cb6ddcSMark Murray (ret < 0) ? "FAIL " : 59881cb6ddcSMark Murray (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 59981cb6ddcSMark Murray } 60081cb6ddcSMark Murray if (encrypt_debug_mode) 60181cb6ddcSMark Murray printf(">>>%s: encrypt_reply returned %d\n", Name, ret); 60281cb6ddcSMark Murray if (ret < 0) { 60381cb6ddcSMark Murray autoencrypt = 0; 60481cb6ddcSMark Murray } else { 60581cb6ddcSMark Murray encrypt_mode = type; 60681cb6ddcSMark Murray if (ret == 0 && autoencrypt) 60781cb6ddcSMark Murray encrypt_start_output(type); 60881cb6ddcSMark Murray } 60981cb6ddcSMark Murray } 61081cb6ddcSMark Murray 61181cb6ddcSMark Murray /* 61281cb6ddcSMark Murray * Called when a ENCRYPT START command is received. 61381cb6ddcSMark Murray */ 61481cb6ddcSMark Murray void 6158fa113e5SMark Murray encrypt_start(unsigned char *data __unused, int cnt __unused) 61681cb6ddcSMark Murray { 61781cb6ddcSMark Murray Encryptions *ep; 61881cb6ddcSMark Murray 61981cb6ddcSMark Murray if (!decrypt_mode) { 62081cb6ddcSMark Murray /* 62181cb6ddcSMark Murray * Something is wrong. We should not get a START 62281cb6ddcSMark Murray * command without having already picked our 62381cb6ddcSMark Murray * decryption scheme. Send a REQUEST-END to 62481cb6ddcSMark Murray * attempt to clear the channel... 62581cb6ddcSMark Murray */ 62681cb6ddcSMark Murray printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name); 62781cb6ddcSMark Murray encrypt_send_request_end(); 62881cb6ddcSMark Murray return; 62981cb6ddcSMark Murray } 63081cb6ddcSMark Murray 63104c426ccSMark Murray if ((ep = finddecryption(decrypt_mode))) { 63281cb6ddcSMark Murray decrypt_input = ep->input; 63381cb6ddcSMark Murray if (encrypt_verbose) 63481cb6ddcSMark Murray printf("[ Input is now decrypted with type %s ]\r\n", 63581cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 63681cb6ddcSMark Murray if (encrypt_debug_mode) 63781cb6ddcSMark Murray printf(">>>%s: Start to decrypt input with type %s\r\n", 63881cb6ddcSMark Murray Name, ENCTYPE_NAME(decrypt_mode)); 63981cb6ddcSMark Murray } else { 64081cb6ddcSMark Murray printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n", 64181cb6ddcSMark Murray Name, 64281cb6ddcSMark Murray ENCTYPE_NAME_OK(decrypt_mode) 64381cb6ddcSMark Murray ? ENCTYPE_NAME(decrypt_mode) 64481cb6ddcSMark Murray : "(unknown)", 64581cb6ddcSMark Murray decrypt_mode); 64681cb6ddcSMark Murray encrypt_send_request_end(); 64781cb6ddcSMark Murray } 64881cb6ddcSMark Murray } 64981cb6ddcSMark Murray 65081cb6ddcSMark Murray void 6518fa113e5SMark Murray encrypt_session_key( Session_Key *key, int server) 65281cb6ddcSMark Murray { 65381cb6ddcSMark Murray Encryptions *ep = encryptions; 65481cb6ddcSMark Murray 65581cb6ddcSMark Murray havesessionkey = 1; 65681cb6ddcSMark Murray 65781cb6ddcSMark Murray while (ep->type) { 65881cb6ddcSMark Murray if (ep->session) 65981cb6ddcSMark Murray (*ep->session)(key, server); 66081cb6ddcSMark Murray ++ep; 66181cb6ddcSMark Murray } 66281cb6ddcSMark Murray } 66381cb6ddcSMark Murray 66481cb6ddcSMark Murray /* 66581cb6ddcSMark Murray * Called when ENCRYPT END is received. 66681cb6ddcSMark Murray */ 66781cb6ddcSMark Murray void 6688fa113e5SMark Murray encrypt_end(void) 66981cb6ddcSMark Murray { 67081cb6ddcSMark Murray decrypt_input = 0; 67181cb6ddcSMark Murray if (encrypt_debug_mode) 67281cb6ddcSMark Murray printf(">>>%s: Input is back to clear text\r\n", Name); 67381cb6ddcSMark Murray if (encrypt_verbose) 67481cb6ddcSMark Murray printf("[ Input is now clear text ]\r\n"); 67581cb6ddcSMark Murray } 67681cb6ddcSMark Murray 67781cb6ddcSMark Murray /* 67881cb6ddcSMark Murray * Called when ENCRYPT REQUEST-END is received. 67981cb6ddcSMark Murray */ 68081cb6ddcSMark Murray void 6818fa113e5SMark Murray encrypt_request_end(void) 68281cb6ddcSMark Murray { 68381cb6ddcSMark Murray encrypt_send_end(); 68481cb6ddcSMark Murray } 68581cb6ddcSMark Murray 68681cb6ddcSMark Murray /* 68781cb6ddcSMark Murray * Called when ENCRYPT REQUEST-START is received. If we receive 68881cb6ddcSMark Murray * this before a type is picked, then that indicates that the 68981cb6ddcSMark Murray * other side wants us to start encrypting data as soon as we 69081cb6ddcSMark Murray * can. 69181cb6ddcSMark Murray */ 69281cb6ddcSMark Murray void 6938fa113e5SMark Murray encrypt_request_start(unsigned char *data __unused, int cnt __unused) 69481cb6ddcSMark Murray { 69581cb6ddcSMark Murray if (encrypt_mode == 0) { 69681cb6ddcSMark Murray if (Server) 69781cb6ddcSMark Murray autoencrypt = 1; 69881cb6ddcSMark Murray return; 69981cb6ddcSMark Murray } 70081cb6ddcSMark Murray encrypt_start_output(encrypt_mode); 70181cb6ddcSMark Murray } 70281cb6ddcSMark Murray 70381cb6ddcSMark Murray static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT }; 70481cb6ddcSMark Murray 70504c426ccSMark Murray void 7068fa113e5SMark Murray encrypt_enc_keyid(unsigned char *keyid, int len) 70781cb6ddcSMark Murray { 70881cb6ddcSMark Murray encrypt_keyid(&ki[1], keyid, len); 70981cb6ddcSMark Murray } 71081cb6ddcSMark Murray 71104c426ccSMark Murray void 7128fa113e5SMark Murray encrypt_dec_keyid(unsigned char *keyid, int len) 71381cb6ddcSMark Murray { 71481cb6ddcSMark Murray encrypt_keyid(&ki[0], keyid, len); 71581cb6ddcSMark Murray } 71681cb6ddcSMark Murray 71704c426ccSMark Murray void 7188fa113e5SMark Murray encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len) 71981cb6ddcSMark Murray { 72081cb6ddcSMark Murray Encryptions *ep; 72181cb6ddcSMark Murray int dir = kp->dir; 7228fa113e5SMark Murray int ret = 0; 72381cb6ddcSMark Murray 724*3e65b9c6SColin Percival if (len > MAXKEYLEN) 725*3e65b9c6SColin Percival len = MAXKEYLEN; 726*3e65b9c6SColin Percival 72781cb6ddcSMark Murray if (!(ep = (*kp->getcrypt)(*kp->modep))) { 72881cb6ddcSMark Murray if (len == 0) 72981cb6ddcSMark Murray return; 73081cb6ddcSMark Murray kp->keylen = 0; 73181cb6ddcSMark Murray } else if (len == 0) { 73281cb6ddcSMark Murray /* 73381cb6ddcSMark Murray * Empty option, indicates a failure. 73481cb6ddcSMark Murray */ 73581cb6ddcSMark Murray if (kp->keylen == 0) 73681cb6ddcSMark Murray return; 73781cb6ddcSMark Murray kp->keylen = 0; 73881cb6ddcSMark Murray if (ep->keyid) 73981cb6ddcSMark Murray (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); 74081cb6ddcSMark Murray 74181cb6ddcSMark Murray } else if ((len != kp->keylen) || 74281cb6ddcSMark Murray (memcmp(keyid, kp->keyid, len) != 0)) { 74381cb6ddcSMark Murray /* 74481cb6ddcSMark Murray * Length or contents are different 74581cb6ddcSMark Murray */ 74681cb6ddcSMark Murray kp->keylen = len; 74781cb6ddcSMark Murray memmove(kp->keyid, keyid, len); 74881cb6ddcSMark Murray if (ep->keyid) 74981cb6ddcSMark Murray (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); 75081cb6ddcSMark Murray } else { 75181cb6ddcSMark Murray if (ep->keyid) 75281cb6ddcSMark Murray ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen); 75381cb6ddcSMark Murray if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt) 75481cb6ddcSMark Murray encrypt_start_output(*kp->modep); 75581cb6ddcSMark Murray return; 75681cb6ddcSMark Murray } 75781cb6ddcSMark Murray 75881cb6ddcSMark Murray encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0); 75981cb6ddcSMark Murray } 76081cb6ddcSMark Murray 76181cb6ddcSMark Murray void 7628fa113e5SMark Murray encrypt_send_keyid(int dir, const char *keyid, int keylen, int saveit) 76381cb6ddcSMark Murray { 76481cb6ddcSMark Murray unsigned char *strp; 76581cb6ddcSMark Murray 76681cb6ddcSMark Murray str_keyid[3] = (dir == DIR_ENCRYPT) 76781cb6ddcSMark Murray ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID; 76881cb6ddcSMark Murray if (saveit) { 76981cb6ddcSMark Murray struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1]; 77081cb6ddcSMark Murray memmove(kp->keyid, keyid, keylen); 77181cb6ddcSMark Murray kp->keylen = keylen; 77281cb6ddcSMark Murray } 77381cb6ddcSMark Murray 77481cb6ddcSMark Murray for (strp = &str_keyid[4]; keylen > 0; --keylen) { 77581cb6ddcSMark Murray if ((*strp++ = *keyid++) == IAC) 77681cb6ddcSMark Murray *strp++ = IAC; 77781cb6ddcSMark Murray } 77881cb6ddcSMark Murray *strp++ = IAC; 77981cb6ddcSMark Murray *strp++ = SE; 78081cb6ddcSMark Murray net_write(str_keyid, strp - str_keyid); 78181cb6ddcSMark Murray printsub('>', &str_keyid[2], strp - str_keyid - 2); 78281cb6ddcSMark Murray } 78381cb6ddcSMark Murray 78481cb6ddcSMark Murray void 7858fa113e5SMark Murray encrypt_auto(int on) 78681cb6ddcSMark Murray { 78781cb6ddcSMark Murray if (on < 0) 78881cb6ddcSMark Murray autoencrypt ^= 1; 78981cb6ddcSMark Murray else 79081cb6ddcSMark Murray autoencrypt = on ? 1 : 0; 79181cb6ddcSMark Murray } 79281cb6ddcSMark Murray 79381cb6ddcSMark Murray void 7948fa113e5SMark Murray decrypt_auto(int on) 79581cb6ddcSMark Murray { 79681cb6ddcSMark Murray if (on < 0) 79781cb6ddcSMark Murray autodecrypt ^= 1; 79881cb6ddcSMark Murray else 79981cb6ddcSMark Murray autodecrypt = on ? 1 : 0; 80081cb6ddcSMark Murray } 80181cb6ddcSMark Murray 80281cb6ddcSMark Murray void 8038fa113e5SMark Murray encrypt_start_output(int type) 80481cb6ddcSMark Murray { 80581cb6ddcSMark Murray Encryptions *ep; 8068fa113e5SMark Murray unsigned char *p; 8078fa113e5SMark Murray int i; 80881cb6ddcSMark Murray 80981cb6ddcSMark Murray if (!(ep = findencryption(type))) { 81081cb6ddcSMark Murray if (encrypt_debug_mode) { 81181cb6ddcSMark Murray printf(">>>%s: Can't encrypt with type %s (%d)\r\n", 81281cb6ddcSMark Murray Name, 81381cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 81481cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 81581cb6ddcSMark Murray type); 81681cb6ddcSMark Murray } 81781cb6ddcSMark Murray return; 81881cb6ddcSMark Murray } 81981cb6ddcSMark Murray if (ep->start) { 82081cb6ddcSMark Murray i = (*ep->start)(DIR_ENCRYPT, Server); 82181cb6ddcSMark Murray if (encrypt_debug_mode) { 82281cb6ddcSMark Murray printf(">>>%s: Encrypt start: %s (%d) %s\r\n", 82381cb6ddcSMark Murray Name, 82481cb6ddcSMark Murray (i < 0) ? "failed" : 82581cb6ddcSMark Murray "initial negotiation in progress", 82681cb6ddcSMark Murray i, ENCTYPE_NAME(type)); 82781cb6ddcSMark Murray } 82881cb6ddcSMark Murray if (i) 82981cb6ddcSMark Murray return; 83081cb6ddcSMark Murray } 83181cb6ddcSMark Murray p = str_start + 3; 83281cb6ddcSMark Murray *p++ = ENCRYPT_START; 83381cb6ddcSMark Murray for (i = 0; i < ki[0].keylen; ++i) { 83481cb6ddcSMark Murray if ((*p++ = ki[0].keyid[i]) == IAC) 83581cb6ddcSMark Murray *p++ = IAC; 83681cb6ddcSMark Murray } 83781cb6ddcSMark Murray *p++ = IAC; 83881cb6ddcSMark Murray *p++ = SE; 83981cb6ddcSMark Murray net_write(str_start, p - str_start); 84081cb6ddcSMark Murray net_encrypt(); 84181cb6ddcSMark Murray printsub('>', &str_start[2], p - &str_start[2]); 84281cb6ddcSMark Murray /* 84381cb6ddcSMark Murray * If we are already encrypting in some mode, then 84481cb6ddcSMark Murray * encrypt the ring (which includes our request) in 84581cb6ddcSMark Murray * the old mode, mark it all as "clear text" and then 84681cb6ddcSMark Murray * switch to the new mode. 84781cb6ddcSMark Murray */ 84881cb6ddcSMark Murray encrypt_output = ep->output; 84981cb6ddcSMark Murray encrypt_mode = type; 85081cb6ddcSMark Murray if (encrypt_debug_mode) 85181cb6ddcSMark Murray printf(">>>%s: Started to encrypt output with type %s\r\n", 85281cb6ddcSMark Murray Name, ENCTYPE_NAME(type)); 85381cb6ddcSMark Murray if (encrypt_verbose) 85481cb6ddcSMark Murray printf("[ Output is now encrypted with type %s ]\r\n", 85581cb6ddcSMark Murray ENCTYPE_NAME(type)); 85681cb6ddcSMark Murray } 85781cb6ddcSMark Murray 85881cb6ddcSMark Murray void 8598fa113e5SMark Murray encrypt_send_end(void) 86081cb6ddcSMark Murray { 86181cb6ddcSMark Murray if (!encrypt_output) 86281cb6ddcSMark Murray return; 86381cb6ddcSMark Murray 86481cb6ddcSMark Murray str_end[3] = ENCRYPT_END; 86581cb6ddcSMark Murray net_write(str_end, sizeof(str_end)); 86681cb6ddcSMark Murray net_encrypt(); 86781cb6ddcSMark Murray printsub('>', &str_end[2], sizeof(str_end) - 2); 86881cb6ddcSMark Murray /* 86981cb6ddcSMark Murray * Encrypt the output buffer now because it will not be done by 87081cb6ddcSMark Murray * netflush... 87181cb6ddcSMark Murray */ 87281cb6ddcSMark Murray encrypt_output = 0; 87381cb6ddcSMark Murray if (encrypt_debug_mode) 87481cb6ddcSMark Murray printf(">>>%s: Output is back to clear text\r\n", Name); 87581cb6ddcSMark Murray if (encrypt_verbose) 87681cb6ddcSMark Murray printf("[ Output is now clear text ]\r\n"); 87781cb6ddcSMark Murray } 87881cb6ddcSMark Murray 87981cb6ddcSMark Murray void 8808fa113e5SMark Murray encrypt_send_request_start(void) 88181cb6ddcSMark Murray { 8828fa113e5SMark Murray unsigned char *p; 8838fa113e5SMark Murray int i; 88481cb6ddcSMark Murray 88581cb6ddcSMark Murray p = &str_start[3]; 88681cb6ddcSMark Murray *p++ = ENCRYPT_REQSTART; 88781cb6ddcSMark Murray for (i = 0; i < ki[1].keylen; ++i) { 88881cb6ddcSMark Murray if ((*p++ = ki[1].keyid[i]) == IAC) 88981cb6ddcSMark Murray *p++ = IAC; 89081cb6ddcSMark Murray } 89181cb6ddcSMark Murray *p++ = IAC; 89281cb6ddcSMark Murray *p++ = SE; 89381cb6ddcSMark Murray net_write(str_start, p - str_start); 89481cb6ddcSMark Murray printsub('>', &str_start[2], p - &str_start[2]); 89581cb6ddcSMark Murray if (encrypt_debug_mode) 89681cb6ddcSMark Murray printf(">>>%s: Request input to be encrypted\r\n", Name); 89781cb6ddcSMark Murray } 89881cb6ddcSMark Murray 89981cb6ddcSMark Murray void 9008fa113e5SMark Murray encrypt_send_request_end(void) 90181cb6ddcSMark Murray { 90281cb6ddcSMark Murray str_end[3] = ENCRYPT_REQEND; 90381cb6ddcSMark Murray net_write(str_end, sizeof(str_end)); 90481cb6ddcSMark Murray printsub('>', &str_end[2], sizeof(str_end) - 2); 90581cb6ddcSMark Murray 90681cb6ddcSMark Murray if (encrypt_debug_mode) 90781cb6ddcSMark Murray printf(">>>%s: Request input to be clear text\r\n", Name); 90881cb6ddcSMark Murray } 90981cb6ddcSMark Murray 91081cb6ddcSMark Murray void 9118fa113e5SMark Murray encrypt_wait(void) 91281cb6ddcSMark Murray { 91381cb6ddcSMark Murray if (encrypt_debug_mode) 91481cb6ddcSMark Murray printf(">>>%s: in encrypt_wait\r\n", Name); 91581cb6ddcSMark Murray if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt)) 91681cb6ddcSMark Murray return; 91781cb6ddcSMark Murray while (autoencrypt && !encrypt_output) 91881cb6ddcSMark Murray if (telnet_spin()) 91981cb6ddcSMark Murray return; 92081cb6ddcSMark Murray } 92181cb6ddcSMark Murray 92281cb6ddcSMark Murray void 9238fa113e5SMark Murray encrypt_gen_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 92481cb6ddcSMark Murray { 92581cb6ddcSMark Murray char tbuf[16], *cp; 92681cb6ddcSMark Murray 92781cb6ddcSMark Murray cnt -= 2; 92881cb6ddcSMark Murray data += 2; 92981cb6ddcSMark Murray buf[buflen-1] = '\0'; 93081cb6ddcSMark Murray buf[buflen-2] = '*'; 93181cb6ddcSMark Murray buflen -= 2;; 93281cb6ddcSMark Murray for (; cnt > 0; cnt--, data++) { 93381cb6ddcSMark Murray sprintf(tbuf, " %d", *data); 93481cb6ddcSMark Murray for (cp = tbuf; *cp && buflen > 0; --buflen) 93581cb6ddcSMark Murray *buf++ = *cp++; 93681cb6ddcSMark Murray if (buflen <= 0) 93781cb6ddcSMark Murray return; 93881cb6ddcSMark Murray } 93981cb6ddcSMark Murray *buf = '\0'; 94081cb6ddcSMark Murray } 94181cb6ddcSMark Murray 94281cb6ddcSMark Murray void 9438fa113e5SMark Murray encrypt_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 94481cb6ddcSMark Murray { 94581cb6ddcSMark Murray Encryptions *ep; 9468fa113e5SMark Murray int type = data[1]; 94781cb6ddcSMark Murray 94881cb6ddcSMark Murray for (ep = encryptions; ep->type && ep->type != type; ep++) 94981cb6ddcSMark Murray ; 95081cb6ddcSMark Murray 95181cb6ddcSMark Murray if (ep->printsub) 95281cb6ddcSMark Murray (*ep->printsub)(data, cnt, buf, buflen); 95381cb6ddcSMark Murray else 95481cb6ddcSMark Murray encrypt_gen_printsub(data, cnt, buf, buflen); 95581cb6ddcSMark Murray } 95681cb6ddcSMark Murray #endif /* ENCRYPTION */ 957