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 3481cb6ddcSMark Murray #ifndef lint 3581cb6ddcSMark Murray static char sccsid[] = "@(#)encrypt.c 8.2 (Berkeley) 5/30/95"; 3681cb6ddcSMark Murray #endif /* not lint */ 3781cb6ddcSMark Murray 3881cb6ddcSMark Murray /* 3981cb6ddcSMark Murray * Copyright (C) 1990 by the Massachusetts Institute of Technology 4081cb6ddcSMark Murray * 4181cb6ddcSMark Murray * Export of this software from the United States of America is assumed 4281cb6ddcSMark Murray * to require a specific license from the United States Government. 4381cb6ddcSMark Murray * It is the responsibility of any person or organization contemplating 4481cb6ddcSMark Murray * export to obtain such a license before exporting. 4581cb6ddcSMark Murray * 4681cb6ddcSMark Murray * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 4781cb6ddcSMark Murray * distribute this software and its documentation for any purpose and 4881cb6ddcSMark Murray * without fee is hereby granted, provided that the above copyright 4981cb6ddcSMark Murray * notice appear in all copies and that both that copyright notice and 5081cb6ddcSMark Murray * this permission notice appear in supporting documentation, and that 5181cb6ddcSMark Murray * the name of M.I.T. not be used in advertising or publicity pertaining 5281cb6ddcSMark Murray * to distribution of the software without specific, written prior 5381cb6ddcSMark Murray * permission. M.I.T. makes no representations about the suitability of 5481cb6ddcSMark Murray * this software for any purpose. It is provided "as is" without express 5581cb6ddcSMark Murray * or implied warranty. 5681cb6ddcSMark Murray */ 5781cb6ddcSMark Murray 5881cb6ddcSMark Murray #ifdef ENCRYPTION 5981cb6ddcSMark Murray 6081cb6ddcSMark Murray #define ENCRYPT_NAMES 6181cb6ddcSMark Murray #include <arpa/telnet.h> 6281cb6ddcSMark Murray 6381cb6ddcSMark Murray #include "encrypt.h" 6481cb6ddcSMark Murray #include "misc.h" 6581cb6ddcSMark Murray 6681cb6ddcSMark Murray #ifdef __STDC__ 6781cb6ddcSMark Murray #include <stdlib.h> 6881cb6ddcSMark Murray #endif 6981cb6ddcSMark Murray #ifdef NO_STRING_H 7081cb6ddcSMark Murray #include <strings.h> 7181cb6ddcSMark Murray #else 7281cb6ddcSMark Murray #include <string.h> 7381cb6ddcSMark Murray #endif 7481cb6ddcSMark Murray 7581cb6ddcSMark Murray /* 7681cb6ddcSMark Murray * These functions pointers point to the current routines 7781cb6ddcSMark Murray * for encrypting and decrypting data. 7881cb6ddcSMark Murray */ 7981cb6ddcSMark Murray void (*encrypt_output) P((unsigned char *, int)); 8081cb6ddcSMark Murray int (*decrypt_input) P((int)); 8181cb6ddcSMark Murray 8281cb6ddcSMark Murray int encrypt_debug_mode = 0; 8381cb6ddcSMark Murray static int decrypt_mode = 0; 8481cb6ddcSMark Murray static int encrypt_mode = 0; 8581cb6ddcSMark Murray static int encrypt_verbose = 0; 8681cb6ddcSMark Murray static int autoencrypt = 0; 8781cb6ddcSMark Murray static int autodecrypt = 0; 8881cb6ddcSMark Murray static int havesessionkey = 0; 8981cb6ddcSMark Murray static int Server = 0; 9081cb6ddcSMark Murray static char *Name = "Noname"; 9181cb6ddcSMark Murray 9281cb6ddcSMark Murray #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 9381cb6ddcSMark Murray 9481cb6ddcSMark Murray static long i_support_encrypt = typemask(ENCTYPE_DES_CFB64) 9581cb6ddcSMark Murray | typemask(ENCTYPE_DES_OFB64); 9681cb6ddcSMark Murray static long i_support_decrypt = typemask(ENCTYPE_DES_CFB64) 9781cb6ddcSMark Murray | typemask(ENCTYPE_DES_OFB64); 9881cb6ddcSMark Murray static long i_wont_support_encrypt = 0; 9981cb6ddcSMark Murray static long i_wont_support_decrypt = 0; 10081cb6ddcSMark Murray #define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt) 10181cb6ddcSMark Murray #define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt) 10281cb6ddcSMark Murray 10381cb6ddcSMark Murray static long remote_supports_encrypt = 0; 10481cb6ddcSMark Murray static long remote_supports_decrypt = 0; 10581cb6ddcSMark Murray 10681cb6ddcSMark Murray static Encryptions encryptions[] = { 10781cb6ddcSMark Murray #ifdef DES_ENCRYPTION 10881cb6ddcSMark Murray { "DES_CFB64", ENCTYPE_DES_CFB64, 10981cb6ddcSMark Murray cfb64_encrypt, 11081cb6ddcSMark Murray cfb64_decrypt, 11181cb6ddcSMark Murray cfb64_init, 11281cb6ddcSMark Murray cfb64_start, 11381cb6ddcSMark Murray cfb64_is, 11481cb6ddcSMark Murray cfb64_reply, 11581cb6ddcSMark Murray cfb64_session, 11681cb6ddcSMark Murray cfb64_keyid, 11781cb6ddcSMark Murray cfb64_printsub }, 11881cb6ddcSMark Murray { "DES_OFB64", ENCTYPE_DES_OFB64, 11981cb6ddcSMark Murray ofb64_encrypt, 12081cb6ddcSMark Murray ofb64_decrypt, 12181cb6ddcSMark Murray ofb64_init, 12281cb6ddcSMark Murray ofb64_start, 12381cb6ddcSMark Murray ofb64_is, 12481cb6ddcSMark Murray ofb64_reply, 12581cb6ddcSMark Murray ofb64_session, 12681cb6ddcSMark Murray ofb64_keyid, 12781cb6ddcSMark Murray ofb64_printsub }, 12881cb6ddcSMark Murray #endif /* DES_ENCRYPTION */ 12981cb6ddcSMark Murray { 0, }, 13081cb6ddcSMark Murray }; 13181cb6ddcSMark Murray 13281cb6ddcSMark Murray static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, 13381cb6ddcSMark Murray ENCRYPT_SUPPORT }; 13481cb6ddcSMark Murray static unsigned char str_suplen = 0; 13581cb6ddcSMark Murray static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT }; 13681cb6ddcSMark Murray static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; 13781cb6ddcSMark Murray 13881cb6ddcSMark Murray Encryptions * 13981cb6ddcSMark Murray findencryption(type) 14081cb6ddcSMark Murray int type; 14181cb6ddcSMark Murray { 14281cb6ddcSMark Murray Encryptions *ep = encryptions; 14381cb6ddcSMark Murray 14481cb6ddcSMark Murray if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & typemask(type))) 14581cb6ddcSMark Murray return(0); 14681cb6ddcSMark Murray while (ep->type && ep->type != type) 14781cb6ddcSMark Murray ++ep; 14881cb6ddcSMark Murray return(ep->type ? ep : 0); 14981cb6ddcSMark Murray } 15081cb6ddcSMark Murray 15181cb6ddcSMark Murray Encryptions * 15281cb6ddcSMark Murray finddecryption(type) 15381cb6ddcSMark Murray int type; 15481cb6ddcSMark Murray { 15581cb6ddcSMark Murray Encryptions *ep = encryptions; 15681cb6ddcSMark Murray 15781cb6ddcSMark Murray if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & typemask(type))) 15881cb6ddcSMark Murray return(0); 15981cb6ddcSMark Murray while (ep->type && ep->type != type) 16081cb6ddcSMark Murray ++ep; 16181cb6ddcSMark Murray return(ep->type ? ep : 0); 16281cb6ddcSMark Murray } 16381cb6ddcSMark Murray 16481cb6ddcSMark Murray #define MAXKEYLEN 64 16581cb6ddcSMark Murray 16681cb6ddcSMark Murray static struct key_info { 16781cb6ddcSMark Murray unsigned char keyid[MAXKEYLEN]; 16881cb6ddcSMark Murray int keylen; 16981cb6ddcSMark Murray int dir; 17081cb6ddcSMark Murray int *modep; 17181cb6ddcSMark Murray Encryptions *(*getcrypt)(); 17281cb6ddcSMark Murray } ki[2] = { 17381cb6ddcSMark Murray { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption }, 17481cb6ddcSMark Murray { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption }, 17581cb6ddcSMark Murray }; 17681cb6ddcSMark Murray 17781cb6ddcSMark Murray void 17881cb6ddcSMark Murray encrypt_init(name, server) 17981cb6ddcSMark Murray char *name; 18081cb6ddcSMark Murray int server; 18181cb6ddcSMark Murray { 18281cb6ddcSMark Murray Encryptions *ep = encryptions; 18381cb6ddcSMark Murray 18481cb6ddcSMark Murray Name = name; 18581cb6ddcSMark Murray Server = server; 18681cb6ddcSMark Murray i_support_encrypt = i_support_decrypt = 0; 18781cb6ddcSMark Murray remote_supports_encrypt = remote_supports_decrypt = 0; 18881cb6ddcSMark Murray encrypt_mode = 0; 18981cb6ddcSMark Murray decrypt_mode = 0; 19081cb6ddcSMark Murray encrypt_output = 0; 19181cb6ddcSMark Murray decrypt_input = 0; 19281cb6ddcSMark Murray #ifdef notdef 19381cb6ddcSMark Murray encrypt_verbose = !server; 19481cb6ddcSMark Murray #endif 19581cb6ddcSMark Murray 19681cb6ddcSMark Murray str_suplen = 4; 19781cb6ddcSMark Murray 19881cb6ddcSMark Murray while (ep->type) { 19981cb6ddcSMark Murray if (encrypt_debug_mode) 20081cb6ddcSMark Murray printf(">>>%s: I will support %s\r\n", 20181cb6ddcSMark Murray Name, ENCTYPE_NAME(ep->type)); 20281cb6ddcSMark Murray i_support_encrypt |= typemask(ep->type); 20381cb6ddcSMark Murray i_support_decrypt |= typemask(ep->type); 20481cb6ddcSMark Murray if ((i_wont_support_decrypt & typemask(ep->type)) == 0) 20581cb6ddcSMark Murray if ((str_send[str_suplen++] = ep->type) == IAC) 20681cb6ddcSMark Murray str_send[str_suplen++] = IAC; 20781cb6ddcSMark Murray if (ep->init) 20881cb6ddcSMark Murray (*ep->init)(Server); 20981cb6ddcSMark Murray ++ep; 21081cb6ddcSMark Murray } 21181cb6ddcSMark Murray str_send[str_suplen++] = IAC; 21281cb6ddcSMark Murray str_send[str_suplen++] = SE; 21381cb6ddcSMark Murray } 21481cb6ddcSMark Murray 21581cb6ddcSMark Murray void 21681cb6ddcSMark Murray encrypt_list_types() 21781cb6ddcSMark Murray { 21881cb6ddcSMark Murray Encryptions *ep = encryptions; 21981cb6ddcSMark Murray 22081cb6ddcSMark Murray printf("Valid encryption types:\n"); 22181cb6ddcSMark Murray while (ep->type) { 22281cb6ddcSMark Murray printf("\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type); 22381cb6ddcSMark Murray ++ep; 22481cb6ddcSMark Murray } 22581cb6ddcSMark Murray } 22681cb6ddcSMark Murray 22781cb6ddcSMark Murray int 22881cb6ddcSMark Murray EncryptEnable(type, mode) 22981cb6ddcSMark Murray char *type, *mode; 23081cb6ddcSMark Murray { 23181cb6ddcSMark Murray if (isprefix(type, "help") || isprefix(type, "?")) { 23281cb6ddcSMark Murray printf("Usage: encrypt enable <type> [input|output]\n"); 23381cb6ddcSMark Murray encrypt_list_types(); 23481cb6ddcSMark Murray return(0); 23581cb6ddcSMark Murray } 23681cb6ddcSMark Murray if (EncryptType(type, mode)) 23781cb6ddcSMark Murray return(EncryptStart(mode)); 23881cb6ddcSMark Murray return(0); 23981cb6ddcSMark Murray } 24081cb6ddcSMark Murray 24181cb6ddcSMark Murray int 24281cb6ddcSMark Murray EncryptDisable(type, mode) 24381cb6ddcSMark Murray char *type, *mode; 24481cb6ddcSMark Murray { 24581cb6ddcSMark Murray register Encryptions *ep; 24681cb6ddcSMark Murray int ret = 0; 24781cb6ddcSMark Murray 24881cb6ddcSMark Murray if (isprefix(type, "help") || isprefix(type, "?")) { 24981cb6ddcSMark Murray printf("Usage: encrypt disable <type> [input|output]\n"); 25081cb6ddcSMark Murray encrypt_list_types(); 25181cb6ddcSMark Murray } else if ((ep = (Encryptions *)genget(type, encryptions, 25281cb6ddcSMark Murray sizeof(Encryptions))) == 0) { 25381cb6ddcSMark Murray printf("%s: invalid encryption type\n", type); 25481cb6ddcSMark Murray } else if (Ambiguous(ep)) { 25581cb6ddcSMark Murray printf("Ambiguous type '%s'\n", type); 25681cb6ddcSMark Murray } else { 25781cb6ddcSMark Murray if ((mode == 0) || (isprefix(mode, "input") ? 1 : 0)) { 25881cb6ddcSMark Murray if (decrypt_mode == ep->type) 25981cb6ddcSMark Murray EncryptStopInput(); 26081cb6ddcSMark Murray i_wont_support_decrypt |= typemask(ep->type); 26181cb6ddcSMark Murray ret = 1; 26281cb6ddcSMark Murray } 26381cb6ddcSMark Murray if ((mode == 0) || (isprefix(mode, "output"))) { 26481cb6ddcSMark Murray if (encrypt_mode == ep->type) 26581cb6ddcSMark Murray EncryptStopOutput(); 26681cb6ddcSMark Murray i_wont_support_encrypt |= typemask(ep->type); 26781cb6ddcSMark Murray ret = 1; 26881cb6ddcSMark Murray } 26981cb6ddcSMark Murray if (ret == 0) 27081cb6ddcSMark Murray printf("%s: invalid encryption mode\n", mode); 27181cb6ddcSMark Murray } 27281cb6ddcSMark Murray return(ret); 27381cb6ddcSMark Murray } 27481cb6ddcSMark Murray 27581cb6ddcSMark Murray int 27681cb6ddcSMark Murray EncryptType(type, mode) 27781cb6ddcSMark Murray char *type; 27881cb6ddcSMark Murray char *mode; 27981cb6ddcSMark Murray { 28081cb6ddcSMark Murray register Encryptions *ep; 28181cb6ddcSMark Murray int ret = 0; 28281cb6ddcSMark Murray 28381cb6ddcSMark Murray if (isprefix(type, "help") || isprefix(type, "?")) { 28481cb6ddcSMark Murray printf("Usage: encrypt type <type> [input|output]\n"); 28581cb6ddcSMark Murray encrypt_list_types(); 28681cb6ddcSMark Murray } else if ((ep = (Encryptions *)genget(type, encryptions, 28781cb6ddcSMark Murray sizeof(Encryptions))) == 0) { 28881cb6ddcSMark Murray printf("%s: invalid encryption type\n", type); 28981cb6ddcSMark Murray } else if (Ambiguous(ep)) { 29081cb6ddcSMark Murray printf("Ambiguous type '%s'\n", type); 29181cb6ddcSMark Murray } else { 29281cb6ddcSMark Murray if ((mode == 0) || isprefix(mode, "input")) { 29381cb6ddcSMark Murray decrypt_mode = ep->type; 29481cb6ddcSMark Murray i_wont_support_decrypt &= ~typemask(ep->type); 29581cb6ddcSMark Murray ret = 1; 29681cb6ddcSMark Murray } 29781cb6ddcSMark Murray if ((mode == 0) || isprefix(mode, "output")) { 29881cb6ddcSMark Murray encrypt_mode = ep->type; 29981cb6ddcSMark Murray i_wont_support_encrypt &= ~typemask(ep->type); 30081cb6ddcSMark Murray ret = 1; 30181cb6ddcSMark Murray } 30281cb6ddcSMark Murray if (ret == 0) 30381cb6ddcSMark Murray printf("%s: invalid encryption mode\n", mode); 30481cb6ddcSMark Murray } 30581cb6ddcSMark Murray return(ret); 30681cb6ddcSMark Murray } 30781cb6ddcSMark Murray 30881cb6ddcSMark Murray int 30981cb6ddcSMark Murray EncryptStart(mode) 31081cb6ddcSMark Murray char *mode; 31181cb6ddcSMark Murray { 31281cb6ddcSMark Murray register 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 33181cb6ddcSMark Murray EncryptStartInput() 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 34281cb6ddcSMark Murray EncryptStartOutput() 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 35381cb6ddcSMark Murray EncryptStop(mode) 35481cb6ddcSMark Murray char *mode; 35581cb6ddcSMark Murray { 35681cb6ddcSMark Murray int ret = 0; 35781cb6ddcSMark Murray if (mode) { 35881cb6ddcSMark Murray if (isprefix(mode, "input")) 35981cb6ddcSMark Murray return(EncryptStopInput()); 36081cb6ddcSMark Murray if (isprefix(mode, "output")) 36181cb6ddcSMark Murray return(EncryptStopOutput()); 36281cb6ddcSMark Murray if (isprefix(mode, "help") || isprefix(mode, "?")) { 36381cb6ddcSMark Murray printf("Usage: encrypt stop [input|output]\n"); 36481cb6ddcSMark Murray return(0); 36581cb6ddcSMark Murray } 36681cb6ddcSMark Murray printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode); 36781cb6ddcSMark Murray return(0); 36881cb6ddcSMark Murray } 36981cb6ddcSMark Murray ret += EncryptStopInput(); 37081cb6ddcSMark Murray ret += EncryptStopOutput(); 37181cb6ddcSMark Murray return(ret); 37281cb6ddcSMark Murray } 37381cb6ddcSMark Murray 37481cb6ddcSMark Murray int 37581cb6ddcSMark Murray EncryptStopInput() 37681cb6ddcSMark Murray { 37781cb6ddcSMark Murray encrypt_send_request_end(); 37881cb6ddcSMark Murray return(1); 37981cb6ddcSMark Murray } 38081cb6ddcSMark Murray 38181cb6ddcSMark Murray int 38281cb6ddcSMark Murray EncryptStopOutput() 38381cb6ddcSMark Murray { 38481cb6ddcSMark Murray encrypt_send_end(); 38581cb6ddcSMark Murray return(1); 38681cb6ddcSMark Murray } 38781cb6ddcSMark Murray 38881cb6ddcSMark Murray void 38981cb6ddcSMark Murray encrypt_display() 39081cb6ddcSMark Murray { 39181cb6ddcSMark Murray if (encrypt_output) 39281cb6ddcSMark Murray printf("Currently encrypting output with %s\r\n", 39381cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 39481cb6ddcSMark Murray if (decrypt_input) 39581cb6ddcSMark Murray printf("Currently decrypting input with %s\r\n", 39681cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 39781cb6ddcSMark Murray } 39881cb6ddcSMark Murray 39981cb6ddcSMark Murray int 40081cb6ddcSMark Murray EncryptStatus() 40181cb6ddcSMark Murray { 40281cb6ddcSMark Murray if (encrypt_output) 40381cb6ddcSMark Murray printf("Currently encrypting output with %s\r\n", 40481cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 40581cb6ddcSMark Murray else if (encrypt_mode) { 40681cb6ddcSMark Murray printf("Currently output is clear text.\r\n"); 40781cb6ddcSMark Murray printf("Last encryption mode was %s\r\n", 40881cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 40981cb6ddcSMark Murray } 41081cb6ddcSMark Murray if (decrypt_input) { 41181cb6ddcSMark Murray printf("Currently decrypting input with %s\r\n", 41281cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 41381cb6ddcSMark Murray } else if (decrypt_mode) { 41481cb6ddcSMark Murray printf("Currently input is clear text.\r\n"); 41581cb6ddcSMark Murray printf("Last decryption mode was %s\r\n", 41681cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 41781cb6ddcSMark Murray } 41881cb6ddcSMark Murray return 1; 41981cb6ddcSMark Murray } 42081cb6ddcSMark Murray 42181cb6ddcSMark Murray void 42281cb6ddcSMark Murray encrypt_send_support() 42381cb6ddcSMark Murray { 42481cb6ddcSMark Murray if (str_suplen) { 42581cb6ddcSMark Murray /* 42681cb6ddcSMark Murray * If the user has requested that decryption start 42781cb6ddcSMark Murray * immediatly, then send a "REQUEST START" before 42881cb6ddcSMark Murray * we negotiate the type. 42981cb6ddcSMark Murray */ 43081cb6ddcSMark Murray if (!Server && autodecrypt) 43181cb6ddcSMark Murray encrypt_send_request_start(); 43281cb6ddcSMark Murray net_write(str_send, str_suplen); 43381cb6ddcSMark Murray printsub('>', &str_send[2], str_suplen - 2); 43481cb6ddcSMark Murray str_suplen = 0; 43581cb6ddcSMark Murray } 43681cb6ddcSMark Murray } 43781cb6ddcSMark Murray 43881cb6ddcSMark Murray int 43981cb6ddcSMark Murray EncryptDebug(on) 44081cb6ddcSMark Murray int on; 44181cb6ddcSMark Murray { 44281cb6ddcSMark Murray if (on < 0) 44381cb6ddcSMark Murray encrypt_debug_mode ^= 1; 44481cb6ddcSMark Murray else 44581cb6ddcSMark Murray encrypt_debug_mode = on; 44681cb6ddcSMark Murray printf("Encryption debugging %s\r\n", 44781cb6ddcSMark Murray encrypt_debug_mode ? "enabled" : "disabled"); 44881cb6ddcSMark Murray return(1); 44981cb6ddcSMark Murray } 45081cb6ddcSMark Murray 45181cb6ddcSMark Murray int 45281cb6ddcSMark Murray EncryptVerbose(on) 45381cb6ddcSMark Murray int on; 45481cb6ddcSMark Murray { 45581cb6ddcSMark Murray if (on < 0) 45681cb6ddcSMark Murray encrypt_verbose ^= 1; 45781cb6ddcSMark Murray else 45881cb6ddcSMark Murray encrypt_verbose = on; 45981cb6ddcSMark Murray printf("Encryption %s verbose\r\n", 46081cb6ddcSMark Murray encrypt_verbose ? "is" : "is not"); 46181cb6ddcSMark Murray return(1); 46281cb6ddcSMark Murray } 46381cb6ddcSMark Murray 46481cb6ddcSMark Murray int 46581cb6ddcSMark Murray EncryptAutoEnc(on) 46681cb6ddcSMark Murray int on; 46781cb6ddcSMark Murray { 46881cb6ddcSMark Murray encrypt_auto(on); 46981cb6ddcSMark Murray printf("Automatic encryption of output is %s\r\n", 47081cb6ddcSMark Murray autoencrypt ? "enabled" : "disabled"); 47181cb6ddcSMark Murray return(1); 47281cb6ddcSMark Murray } 47381cb6ddcSMark Murray 47481cb6ddcSMark Murray int 47581cb6ddcSMark Murray EncryptAutoDec(on) 47681cb6ddcSMark Murray int on; 47781cb6ddcSMark Murray { 47881cb6ddcSMark Murray decrypt_auto(on); 47981cb6ddcSMark Murray printf("Automatic decryption of input is %s\r\n", 48081cb6ddcSMark Murray autodecrypt ? "enabled" : "disabled"); 48181cb6ddcSMark Murray return(1); 48281cb6ddcSMark Murray } 48381cb6ddcSMark Murray 48481cb6ddcSMark Murray /* 48581cb6ddcSMark Murray * Called when ENCRYPT SUPPORT is received. 48681cb6ddcSMark Murray */ 48781cb6ddcSMark Murray void 48881cb6ddcSMark Murray encrypt_support(typelist, cnt) 48981cb6ddcSMark Murray unsigned char *typelist; 49081cb6ddcSMark Murray int cnt; 49181cb6ddcSMark Murray { 49281cb6ddcSMark Murray register int type, use_type = 0; 49381cb6ddcSMark Murray Encryptions *ep; 49481cb6ddcSMark Murray 49581cb6ddcSMark Murray /* 49681cb6ddcSMark Murray * Forget anything the other side has previously told us. 49781cb6ddcSMark Murray */ 49881cb6ddcSMark Murray remote_supports_decrypt = 0; 49981cb6ddcSMark Murray 50081cb6ddcSMark Murray while (cnt-- > 0) { 50181cb6ddcSMark Murray type = *typelist++; 50281cb6ddcSMark Murray if (encrypt_debug_mode) 50381cb6ddcSMark Murray printf(">>>%s: He is supporting %s (%d)\r\n", 50481cb6ddcSMark Murray Name, 50581cb6ddcSMark Murray ENCTYPE_NAME(type), type); 50681cb6ddcSMark Murray if ((type < ENCTYPE_CNT) && 50781cb6ddcSMark Murray (I_SUPPORT_ENCRYPT & typemask(type))) { 50881cb6ddcSMark Murray remote_supports_decrypt |= typemask(type); 50981cb6ddcSMark Murray if (use_type == 0) 51081cb6ddcSMark Murray use_type = type; 51181cb6ddcSMark Murray } 51281cb6ddcSMark Murray } 51381cb6ddcSMark Murray if (use_type) { 51481cb6ddcSMark Murray ep = findencryption(use_type); 51581cb6ddcSMark Murray if (!ep) 51681cb6ddcSMark Murray return; 51781cb6ddcSMark Murray type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0; 51881cb6ddcSMark Murray if (encrypt_debug_mode) 51981cb6ddcSMark Murray printf(">>>%s: (*ep->start)() returned %d\r\n", 52081cb6ddcSMark Murray Name, type); 52181cb6ddcSMark Murray if (type < 0) 52281cb6ddcSMark Murray return; 52381cb6ddcSMark Murray encrypt_mode = use_type; 52481cb6ddcSMark Murray if (type == 0) 52581cb6ddcSMark Murray encrypt_start_output(use_type); 52681cb6ddcSMark Murray } 52781cb6ddcSMark Murray } 52881cb6ddcSMark Murray 52981cb6ddcSMark Murray void 53081cb6ddcSMark Murray encrypt_is(data, cnt) 53181cb6ddcSMark Murray unsigned char *data; 53281cb6ddcSMark Murray int cnt; 53381cb6ddcSMark Murray { 53481cb6ddcSMark Murray Encryptions *ep; 53581cb6ddcSMark Murray register int type, ret; 53681cb6ddcSMark Murray 53781cb6ddcSMark Murray if (--cnt < 0) 53881cb6ddcSMark Murray return; 53981cb6ddcSMark Murray type = *data++; 54081cb6ddcSMark Murray if (type < ENCTYPE_CNT) 54181cb6ddcSMark Murray remote_supports_encrypt |= typemask(type); 54281cb6ddcSMark Murray if (!(ep = finddecryption(type))) { 54381cb6ddcSMark Murray if (encrypt_debug_mode) 54481cb6ddcSMark Murray printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 54581cb6ddcSMark Murray Name, 54681cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 54781cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 54881cb6ddcSMark Murray type); 54981cb6ddcSMark Murray return; 55081cb6ddcSMark Murray } 55181cb6ddcSMark Murray if (!ep->is) { 55281cb6ddcSMark Murray if (encrypt_debug_mode) 55381cb6ddcSMark Murray printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 55481cb6ddcSMark Murray Name, 55581cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 55681cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 55781cb6ddcSMark Murray type); 55881cb6ddcSMark Murray ret = 0; 55981cb6ddcSMark Murray } else { 56081cb6ddcSMark Murray ret = (*ep->is)(data, cnt); 56181cb6ddcSMark Murray if (encrypt_debug_mode) 56281cb6ddcSMark Murray printf("(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt, 56381cb6ddcSMark Murray (ret < 0) ? "FAIL " : 56481cb6ddcSMark Murray (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 56581cb6ddcSMark Murray } 56681cb6ddcSMark Murray if (ret < 0) { 56781cb6ddcSMark Murray autodecrypt = 0; 56881cb6ddcSMark Murray } else { 56981cb6ddcSMark Murray decrypt_mode = type; 57081cb6ddcSMark Murray if (ret == 0 && autodecrypt) 57181cb6ddcSMark Murray encrypt_send_request_start(); 57281cb6ddcSMark Murray } 57381cb6ddcSMark Murray } 57481cb6ddcSMark Murray 57581cb6ddcSMark Murray void 57681cb6ddcSMark Murray encrypt_reply(data, cnt) 57781cb6ddcSMark Murray unsigned char *data; 57881cb6ddcSMark Murray int cnt; 57981cb6ddcSMark Murray { 58081cb6ddcSMark Murray Encryptions *ep; 58181cb6ddcSMark Murray register int ret, type; 58281cb6ddcSMark Murray 58381cb6ddcSMark Murray if (--cnt < 0) 58481cb6ddcSMark Murray return; 58581cb6ddcSMark Murray type = *data++; 58681cb6ddcSMark Murray if (!(ep = findencryption(type))) { 58781cb6ddcSMark Murray if (encrypt_debug_mode) 58881cb6ddcSMark Murray printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 58981cb6ddcSMark Murray Name, 59081cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 59181cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 59281cb6ddcSMark Murray type); 59381cb6ddcSMark Murray return; 59481cb6ddcSMark Murray } 59581cb6ddcSMark Murray if (!ep->reply) { 59681cb6ddcSMark Murray if (encrypt_debug_mode) 59781cb6ddcSMark Murray printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 59881cb6ddcSMark Murray Name, 59981cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 60081cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 60181cb6ddcSMark Murray type); 60281cb6ddcSMark Murray ret = 0; 60381cb6ddcSMark Murray } else { 60481cb6ddcSMark Murray ret = (*ep->reply)(data, cnt); 60581cb6ddcSMark Murray if (encrypt_debug_mode) 60681cb6ddcSMark Murray printf("(*ep->reply)(%x, %d) returned %s(%d)\n", 60781cb6ddcSMark Murray data, cnt, 60881cb6ddcSMark Murray (ret < 0) ? "FAIL " : 60981cb6ddcSMark Murray (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 61081cb6ddcSMark Murray } 61181cb6ddcSMark Murray if (encrypt_debug_mode) 61281cb6ddcSMark Murray printf(">>>%s: encrypt_reply returned %d\n", Name, ret); 61381cb6ddcSMark Murray if (ret < 0) { 61481cb6ddcSMark Murray autoencrypt = 0; 61581cb6ddcSMark Murray } else { 61681cb6ddcSMark Murray encrypt_mode = type; 61781cb6ddcSMark Murray if (ret == 0 && autoencrypt) 61881cb6ddcSMark Murray encrypt_start_output(type); 61981cb6ddcSMark Murray } 62081cb6ddcSMark Murray } 62181cb6ddcSMark Murray 62281cb6ddcSMark Murray /* 62381cb6ddcSMark Murray * Called when a ENCRYPT START command is received. 62481cb6ddcSMark Murray */ 62581cb6ddcSMark Murray void 62681cb6ddcSMark Murray encrypt_start(data, cnt) 62781cb6ddcSMark Murray unsigned char *data; 62881cb6ddcSMark Murray int cnt; 62981cb6ddcSMark Murray { 63081cb6ddcSMark Murray Encryptions *ep; 63181cb6ddcSMark Murray 63281cb6ddcSMark Murray if (!decrypt_mode) { 63381cb6ddcSMark Murray /* 63481cb6ddcSMark Murray * Something is wrong. We should not get a START 63581cb6ddcSMark Murray * command without having already picked our 63681cb6ddcSMark Murray * decryption scheme. Send a REQUEST-END to 63781cb6ddcSMark Murray * attempt to clear the channel... 63881cb6ddcSMark Murray */ 63981cb6ddcSMark Murray printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name); 64081cb6ddcSMark Murray encrypt_send_request_end(); 64181cb6ddcSMark Murray return; 64281cb6ddcSMark Murray } 64381cb6ddcSMark Murray 64481cb6ddcSMark Murray if (ep = finddecryption(decrypt_mode)) { 64581cb6ddcSMark Murray decrypt_input = ep->input; 64681cb6ddcSMark Murray if (encrypt_verbose) 64781cb6ddcSMark Murray printf("[ Input is now decrypted with type %s ]\r\n", 64881cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 64981cb6ddcSMark Murray if (encrypt_debug_mode) 65081cb6ddcSMark Murray printf(">>>%s: Start to decrypt input with type %s\r\n", 65181cb6ddcSMark Murray Name, ENCTYPE_NAME(decrypt_mode)); 65281cb6ddcSMark Murray } else { 65381cb6ddcSMark Murray printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n", 65481cb6ddcSMark Murray Name, 65581cb6ddcSMark Murray ENCTYPE_NAME_OK(decrypt_mode) 65681cb6ddcSMark Murray ? ENCTYPE_NAME(decrypt_mode) 65781cb6ddcSMark Murray : "(unknown)", 65881cb6ddcSMark Murray decrypt_mode); 65981cb6ddcSMark Murray encrypt_send_request_end(); 66081cb6ddcSMark Murray } 66181cb6ddcSMark Murray } 66281cb6ddcSMark Murray 66381cb6ddcSMark Murray void 66481cb6ddcSMark Murray encrypt_session_key(key, server) 66581cb6ddcSMark Murray Session_Key *key; 66681cb6ddcSMark Murray int server; 66781cb6ddcSMark Murray { 66881cb6ddcSMark Murray Encryptions *ep = encryptions; 66981cb6ddcSMark Murray 67081cb6ddcSMark Murray havesessionkey = 1; 67181cb6ddcSMark Murray 67281cb6ddcSMark Murray while (ep->type) { 67381cb6ddcSMark Murray if (ep->session) 67481cb6ddcSMark Murray (*ep->session)(key, server); 67581cb6ddcSMark Murray #ifdef notdef 67681cb6ddcSMark Murray if (!encrypt_output && autoencrypt && !server) 67781cb6ddcSMark Murray encrypt_start_output(ep->type); 67881cb6ddcSMark Murray if (!decrypt_input && autodecrypt && !server) 67981cb6ddcSMark Murray encrypt_send_request_start(); 68081cb6ddcSMark Murray #endif 68181cb6ddcSMark Murray ++ep; 68281cb6ddcSMark Murray } 68381cb6ddcSMark Murray } 68481cb6ddcSMark Murray 68581cb6ddcSMark Murray /* 68681cb6ddcSMark Murray * Called when ENCRYPT END is received. 68781cb6ddcSMark Murray */ 68881cb6ddcSMark Murray void 68981cb6ddcSMark Murray encrypt_end() 69081cb6ddcSMark Murray { 69181cb6ddcSMark Murray decrypt_input = 0; 69281cb6ddcSMark Murray if (encrypt_debug_mode) 69381cb6ddcSMark Murray printf(">>>%s: Input is back to clear text\r\n", Name); 69481cb6ddcSMark Murray if (encrypt_verbose) 69581cb6ddcSMark Murray printf("[ Input is now clear text ]\r\n"); 69681cb6ddcSMark Murray } 69781cb6ddcSMark Murray 69881cb6ddcSMark Murray /* 69981cb6ddcSMark Murray * Called when ENCRYPT REQUEST-END is received. 70081cb6ddcSMark Murray */ 70181cb6ddcSMark Murray void 70281cb6ddcSMark Murray encrypt_request_end() 70381cb6ddcSMark Murray { 70481cb6ddcSMark Murray encrypt_send_end(); 70581cb6ddcSMark Murray } 70681cb6ddcSMark Murray 70781cb6ddcSMark Murray /* 70881cb6ddcSMark Murray * Called when ENCRYPT REQUEST-START is received. If we receive 70981cb6ddcSMark Murray * this before a type is picked, then that indicates that the 71081cb6ddcSMark Murray * other side wants us to start encrypting data as soon as we 71181cb6ddcSMark Murray * can. 71281cb6ddcSMark Murray */ 71381cb6ddcSMark Murray void 71481cb6ddcSMark Murray encrypt_request_start(data, cnt) 71581cb6ddcSMark Murray unsigned char *data; 71681cb6ddcSMark Murray int cnt; 71781cb6ddcSMark Murray { 71881cb6ddcSMark Murray if (encrypt_mode == 0) { 71981cb6ddcSMark Murray if (Server) 72081cb6ddcSMark Murray autoencrypt = 1; 72181cb6ddcSMark Murray return; 72281cb6ddcSMark Murray } 72381cb6ddcSMark Murray encrypt_start_output(encrypt_mode); 72481cb6ddcSMark Murray } 72581cb6ddcSMark Murray 72681cb6ddcSMark Murray static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT }; 72781cb6ddcSMark Murray 72881cb6ddcSMark Murray encrypt_enc_keyid(keyid, len) 72981cb6ddcSMark Murray unsigned char *keyid; 73081cb6ddcSMark Murray int len; 73181cb6ddcSMark Murray { 73281cb6ddcSMark Murray encrypt_keyid(&ki[1], keyid, len); 73381cb6ddcSMark Murray } 73481cb6ddcSMark Murray 73581cb6ddcSMark Murray encrypt_dec_keyid(keyid, len) 73681cb6ddcSMark Murray unsigned char *keyid; 73781cb6ddcSMark Murray int len; 73881cb6ddcSMark Murray { 73981cb6ddcSMark Murray encrypt_keyid(&ki[0], keyid, len); 74081cb6ddcSMark Murray } 74181cb6ddcSMark Murray 74281cb6ddcSMark Murray encrypt_keyid(kp, keyid, len) 74381cb6ddcSMark Murray struct key_info *kp; 74481cb6ddcSMark Murray unsigned char *keyid; 74581cb6ddcSMark Murray int len; 74681cb6ddcSMark Murray { 74781cb6ddcSMark Murray Encryptions *ep; 74881cb6ddcSMark Murray unsigned char *strp, *cp; 74981cb6ddcSMark Murray int dir = kp->dir; 75081cb6ddcSMark Murray register int ret = 0; 75181cb6ddcSMark Murray 75281cb6ddcSMark Murray if (!(ep = (*kp->getcrypt)(*kp->modep))) { 75381cb6ddcSMark Murray if (len == 0) 75481cb6ddcSMark Murray return; 75581cb6ddcSMark Murray kp->keylen = 0; 75681cb6ddcSMark Murray } else if (len == 0) { 75781cb6ddcSMark Murray /* 75881cb6ddcSMark Murray * Empty option, indicates a failure. 75981cb6ddcSMark Murray */ 76081cb6ddcSMark Murray if (kp->keylen == 0) 76181cb6ddcSMark Murray return; 76281cb6ddcSMark Murray kp->keylen = 0; 76381cb6ddcSMark Murray if (ep->keyid) 76481cb6ddcSMark Murray (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); 76581cb6ddcSMark Murray 76681cb6ddcSMark Murray } else if ((len != kp->keylen) || 76781cb6ddcSMark Murray (memcmp(keyid, kp->keyid, len) != 0)) { 76881cb6ddcSMark Murray /* 76981cb6ddcSMark Murray * Length or contents are different 77081cb6ddcSMark Murray */ 77181cb6ddcSMark Murray kp->keylen = len; 77281cb6ddcSMark Murray memmove(kp->keyid, keyid, len); 77381cb6ddcSMark Murray if (ep->keyid) 77481cb6ddcSMark Murray (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); 77581cb6ddcSMark Murray } else { 77681cb6ddcSMark Murray if (ep->keyid) 77781cb6ddcSMark Murray ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen); 77881cb6ddcSMark Murray if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt) 77981cb6ddcSMark Murray encrypt_start_output(*kp->modep); 78081cb6ddcSMark Murray return; 78181cb6ddcSMark Murray } 78281cb6ddcSMark Murray 78381cb6ddcSMark Murray encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0); 78481cb6ddcSMark Murray } 78581cb6ddcSMark Murray 78681cb6ddcSMark Murray void 78781cb6ddcSMark Murray encrypt_send_keyid(dir, keyid, keylen, saveit) 78881cb6ddcSMark Murray int dir; 78981cb6ddcSMark Murray unsigned char *keyid; 79081cb6ddcSMark Murray int keylen; 79181cb6ddcSMark Murray int saveit; 79281cb6ddcSMark Murray { 79381cb6ddcSMark Murray unsigned char *strp; 79481cb6ddcSMark Murray 79581cb6ddcSMark Murray str_keyid[3] = (dir == DIR_ENCRYPT) 79681cb6ddcSMark Murray ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID; 79781cb6ddcSMark Murray if (saveit) { 79881cb6ddcSMark Murray struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1]; 79981cb6ddcSMark Murray memmove(kp->keyid, keyid, keylen); 80081cb6ddcSMark Murray kp->keylen = keylen; 80181cb6ddcSMark Murray } 80281cb6ddcSMark Murray 80381cb6ddcSMark Murray for (strp = &str_keyid[4]; keylen > 0; --keylen) { 80481cb6ddcSMark Murray if ((*strp++ = *keyid++) == IAC) 80581cb6ddcSMark Murray *strp++ = IAC; 80681cb6ddcSMark Murray } 80781cb6ddcSMark Murray *strp++ = IAC; 80881cb6ddcSMark Murray *strp++ = SE; 80981cb6ddcSMark Murray net_write(str_keyid, strp - str_keyid); 81081cb6ddcSMark Murray printsub('>', &str_keyid[2], strp - str_keyid - 2); 81181cb6ddcSMark Murray } 81281cb6ddcSMark Murray 81381cb6ddcSMark Murray void 81481cb6ddcSMark Murray encrypt_auto(on) 81581cb6ddcSMark Murray int on; 81681cb6ddcSMark Murray { 81781cb6ddcSMark Murray if (on < 0) 81881cb6ddcSMark Murray autoencrypt ^= 1; 81981cb6ddcSMark Murray else 82081cb6ddcSMark Murray autoencrypt = on ? 1 : 0; 82181cb6ddcSMark Murray } 82281cb6ddcSMark Murray 82381cb6ddcSMark Murray void 82481cb6ddcSMark Murray decrypt_auto(on) 82581cb6ddcSMark Murray int on; 82681cb6ddcSMark Murray { 82781cb6ddcSMark Murray if (on < 0) 82881cb6ddcSMark Murray autodecrypt ^= 1; 82981cb6ddcSMark Murray else 83081cb6ddcSMark Murray autodecrypt = on ? 1 : 0; 83181cb6ddcSMark Murray } 83281cb6ddcSMark Murray 83381cb6ddcSMark Murray void 83481cb6ddcSMark Murray encrypt_start_output(type) 83581cb6ddcSMark Murray int type; 83681cb6ddcSMark Murray { 83781cb6ddcSMark Murray Encryptions *ep; 83881cb6ddcSMark Murray register unsigned char *p; 83981cb6ddcSMark Murray register int i; 84081cb6ddcSMark Murray 84181cb6ddcSMark Murray if (!(ep = findencryption(type))) { 84281cb6ddcSMark Murray if (encrypt_debug_mode) { 84381cb6ddcSMark Murray printf(">>>%s: Can't encrypt with type %s (%d)\r\n", 84481cb6ddcSMark Murray Name, 84581cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 84681cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 84781cb6ddcSMark Murray type); 84881cb6ddcSMark Murray } 84981cb6ddcSMark Murray return; 85081cb6ddcSMark Murray } 85181cb6ddcSMark Murray if (ep->start) { 85281cb6ddcSMark Murray i = (*ep->start)(DIR_ENCRYPT, Server); 85381cb6ddcSMark Murray if (encrypt_debug_mode) { 85481cb6ddcSMark Murray printf(">>>%s: Encrypt start: %s (%d) %s\r\n", 85581cb6ddcSMark Murray Name, 85681cb6ddcSMark Murray (i < 0) ? "failed" : 85781cb6ddcSMark Murray "initial negotiation in progress", 85881cb6ddcSMark Murray i, ENCTYPE_NAME(type)); 85981cb6ddcSMark Murray } 86081cb6ddcSMark Murray if (i) 86181cb6ddcSMark Murray return; 86281cb6ddcSMark Murray } 86381cb6ddcSMark Murray p = str_start + 3; 86481cb6ddcSMark Murray *p++ = ENCRYPT_START; 86581cb6ddcSMark Murray for (i = 0; i < ki[0].keylen; ++i) { 86681cb6ddcSMark Murray if ((*p++ = ki[0].keyid[i]) == IAC) 86781cb6ddcSMark Murray *p++ = IAC; 86881cb6ddcSMark Murray } 86981cb6ddcSMark Murray *p++ = IAC; 87081cb6ddcSMark Murray *p++ = SE; 87181cb6ddcSMark Murray net_write(str_start, p - str_start); 87281cb6ddcSMark Murray net_encrypt(); 87381cb6ddcSMark Murray printsub('>', &str_start[2], p - &str_start[2]); 87481cb6ddcSMark Murray /* 87581cb6ddcSMark Murray * If we are already encrypting in some mode, then 87681cb6ddcSMark Murray * encrypt the ring (which includes our request) in 87781cb6ddcSMark Murray * the old mode, mark it all as "clear text" and then 87881cb6ddcSMark Murray * switch to the new mode. 87981cb6ddcSMark Murray */ 88081cb6ddcSMark Murray encrypt_output = ep->output; 88181cb6ddcSMark Murray encrypt_mode = type; 88281cb6ddcSMark Murray if (encrypt_debug_mode) 88381cb6ddcSMark Murray printf(">>>%s: Started to encrypt output with type %s\r\n", 88481cb6ddcSMark Murray Name, ENCTYPE_NAME(type)); 88581cb6ddcSMark Murray if (encrypt_verbose) 88681cb6ddcSMark Murray printf("[ Output is now encrypted with type %s ]\r\n", 88781cb6ddcSMark Murray ENCTYPE_NAME(type)); 88881cb6ddcSMark Murray } 88981cb6ddcSMark Murray 89081cb6ddcSMark Murray void 89181cb6ddcSMark Murray encrypt_send_end() 89281cb6ddcSMark Murray { 89381cb6ddcSMark Murray if (!encrypt_output) 89481cb6ddcSMark Murray return; 89581cb6ddcSMark Murray 89681cb6ddcSMark Murray str_end[3] = ENCRYPT_END; 89781cb6ddcSMark Murray net_write(str_end, sizeof(str_end)); 89881cb6ddcSMark Murray net_encrypt(); 89981cb6ddcSMark Murray printsub('>', &str_end[2], sizeof(str_end) - 2); 90081cb6ddcSMark Murray /* 90181cb6ddcSMark Murray * Encrypt the output buffer now because it will not be done by 90281cb6ddcSMark Murray * netflush... 90381cb6ddcSMark Murray */ 90481cb6ddcSMark Murray encrypt_output = 0; 90581cb6ddcSMark Murray if (encrypt_debug_mode) 90681cb6ddcSMark Murray printf(">>>%s: Output is back to clear text\r\n", Name); 90781cb6ddcSMark Murray if (encrypt_verbose) 90881cb6ddcSMark Murray printf("[ Output is now clear text ]\r\n"); 90981cb6ddcSMark Murray } 91081cb6ddcSMark Murray 91181cb6ddcSMark Murray void 91281cb6ddcSMark Murray encrypt_send_request_start() 91381cb6ddcSMark Murray { 91481cb6ddcSMark Murray register unsigned char *p; 91581cb6ddcSMark Murray register int i; 91681cb6ddcSMark Murray 91781cb6ddcSMark Murray p = &str_start[3]; 91881cb6ddcSMark Murray *p++ = ENCRYPT_REQSTART; 91981cb6ddcSMark Murray for (i = 0; i < ki[1].keylen; ++i) { 92081cb6ddcSMark Murray if ((*p++ = ki[1].keyid[i]) == IAC) 92181cb6ddcSMark Murray *p++ = IAC; 92281cb6ddcSMark Murray } 92381cb6ddcSMark Murray *p++ = IAC; 92481cb6ddcSMark Murray *p++ = SE; 92581cb6ddcSMark Murray net_write(str_start, p - str_start); 92681cb6ddcSMark Murray printsub('>', &str_start[2], p - &str_start[2]); 92781cb6ddcSMark Murray if (encrypt_debug_mode) 92881cb6ddcSMark Murray printf(">>>%s: Request input to be encrypted\r\n", Name); 92981cb6ddcSMark Murray } 93081cb6ddcSMark Murray 93181cb6ddcSMark Murray void 93281cb6ddcSMark Murray encrypt_send_request_end() 93381cb6ddcSMark Murray { 93481cb6ddcSMark Murray str_end[3] = ENCRYPT_REQEND; 93581cb6ddcSMark Murray net_write(str_end, sizeof(str_end)); 93681cb6ddcSMark Murray printsub('>', &str_end[2], sizeof(str_end) - 2); 93781cb6ddcSMark Murray 93881cb6ddcSMark Murray if (encrypt_debug_mode) 93981cb6ddcSMark Murray printf(">>>%s: Request input to be clear text\r\n", Name); 94081cb6ddcSMark Murray } 94181cb6ddcSMark Murray 94281cb6ddcSMark Murray void 94381cb6ddcSMark Murray encrypt_wait() 94481cb6ddcSMark Murray { 94581cb6ddcSMark Murray register int encrypt, decrypt; 94681cb6ddcSMark Murray if (encrypt_debug_mode) 94781cb6ddcSMark Murray printf(">>>%s: in encrypt_wait\r\n", Name); 94881cb6ddcSMark Murray if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt)) 94981cb6ddcSMark Murray return; 95081cb6ddcSMark Murray while (autoencrypt && !encrypt_output) 95181cb6ddcSMark Murray if (telnet_spin()) 95281cb6ddcSMark Murray return; 95381cb6ddcSMark Murray } 95481cb6ddcSMark Murray 95581cb6ddcSMark Murray void 95681cb6ddcSMark Murray encrypt_debug(mode) 95781cb6ddcSMark Murray int mode; 95881cb6ddcSMark Murray { 95981cb6ddcSMark Murray encrypt_debug_mode = mode; 96081cb6ddcSMark Murray } 96181cb6ddcSMark Murray 96281cb6ddcSMark Murray void 96381cb6ddcSMark Murray encrypt_gen_printsub(data, cnt, buf, buflen) 96481cb6ddcSMark Murray unsigned char *data, *buf; 96581cb6ddcSMark Murray int cnt, buflen; 96681cb6ddcSMark Murray { 96781cb6ddcSMark Murray char tbuf[16], *cp; 96881cb6ddcSMark Murray 96981cb6ddcSMark Murray cnt -= 2; 97081cb6ddcSMark Murray data += 2; 97181cb6ddcSMark Murray buf[buflen-1] = '\0'; 97281cb6ddcSMark Murray buf[buflen-2] = '*'; 97381cb6ddcSMark Murray buflen -= 2;; 97481cb6ddcSMark Murray for (; cnt > 0; cnt--, data++) { 97581cb6ddcSMark Murray sprintf(tbuf, " %d", *data); 97681cb6ddcSMark Murray for (cp = tbuf; *cp && buflen > 0; --buflen) 97781cb6ddcSMark Murray *buf++ = *cp++; 97881cb6ddcSMark Murray if (buflen <= 0) 97981cb6ddcSMark Murray return; 98081cb6ddcSMark Murray } 98181cb6ddcSMark Murray *buf = '\0'; 98281cb6ddcSMark Murray } 98381cb6ddcSMark Murray 98481cb6ddcSMark Murray void 98581cb6ddcSMark Murray encrypt_printsub(data, cnt, buf, buflen) 98681cb6ddcSMark Murray unsigned char *data, *buf; 98781cb6ddcSMark Murray int cnt, buflen; 98881cb6ddcSMark Murray { 98981cb6ddcSMark Murray Encryptions *ep; 99081cb6ddcSMark Murray register int type = data[1]; 99181cb6ddcSMark Murray 99281cb6ddcSMark Murray for (ep = encryptions; ep->type && ep->type != type; ep++) 99381cb6ddcSMark Murray ; 99481cb6ddcSMark Murray 99581cb6ddcSMark Murray if (ep->printsub) 99681cb6ddcSMark Murray (*ep->printsub)(data, cnt, buf, buflen); 99781cb6ddcSMark Murray else 99881cb6ddcSMark Murray encrypt_gen_printsub(data, cnt, buf, buflen); 99981cb6ddcSMark Murray } 100081cb6ddcSMark Murray #endif /* ENCRYPTION */ 1001