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 6681cb6ddcSMark Murray #define ENCRYPT_NAMES 6781cb6ddcSMark Murray #include <arpa/telnet.h> 688fa113e5SMark Murray #include <stdio.h> 698fa113e5SMark Murray #include <stdlib.h> 708fa113e5SMark Murray #include <string.h> 7181cb6ddcSMark Murray 7281cb6ddcSMark Murray #include "encrypt.h" 7381cb6ddcSMark Murray #include "misc.h" 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 8204c426ccSMark Murray int EncryptType(char *type, char *mode); 8304c426ccSMark Murray int EncryptStart(char *mode); 8404c426ccSMark Murray int EncryptStop(char *mode); 8504c426ccSMark Murray int EncryptStartInput(void); 8604c426ccSMark Murray int EncryptStartOutput(void); 8704c426ccSMark Murray int EncryptStopInput(void); 8804c426ccSMark Murray int EncryptStopOutput(void); 8904c426ccSMark Murray 9081cb6ddcSMark Murray int encrypt_debug_mode = 0; 9181cb6ddcSMark Murray static int decrypt_mode = 0; 9281cb6ddcSMark Murray static int encrypt_mode = 0; 9381cb6ddcSMark Murray static int encrypt_verbose = 0; 9481cb6ddcSMark Murray static int autoencrypt = 0; 9581cb6ddcSMark Murray static int autodecrypt = 0; 9681cb6ddcSMark Murray static int havesessionkey = 0; 9781cb6ddcSMark Murray static int Server = 0; 988fa113e5SMark Murray static const char *Name = "Noname"; 9981cb6ddcSMark Murray 10081cb6ddcSMark Murray #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 10181cb6ddcSMark Murray 1020f8c8396SNick Sayer static long i_support_encrypt = 0 1030f8c8396SNick Sayer | typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64) 1040f8c8396SNick Sayer |0; 1050f8c8396SNick Sayer static long i_support_decrypt = 0 1060f8c8396SNick Sayer | typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64) 1070f8c8396SNick Sayer |0; 1080f8c8396SNick Sayer 10981cb6ddcSMark Murray static long i_wont_support_encrypt = 0; 11081cb6ddcSMark Murray static long i_wont_support_decrypt = 0; 11181cb6ddcSMark Murray #define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt) 11281cb6ddcSMark Murray #define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt) 11381cb6ddcSMark Murray 11481cb6ddcSMark Murray static long remote_supports_encrypt = 0; 11581cb6ddcSMark Murray static long remote_supports_decrypt = 0; 11681cb6ddcSMark Murray 11781cb6ddcSMark Murray static Encryptions encryptions[] = { 11881cb6ddcSMark Murray { "DES_CFB64", ENCTYPE_DES_CFB64, 11981cb6ddcSMark Murray cfb64_encrypt, 12081cb6ddcSMark Murray cfb64_decrypt, 12181cb6ddcSMark Murray cfb64_init, 12281cb6ddcSMark Murray cfb64_start, 12381cb6ddcSMark Murray cfb64_is, 12481cb6ddcSMark Murray cfb64_reply, 12581cb6ddcSMark Murray cfb64_session, 12681cb6ddcSMark Murray cfb64_keyid, 12781cb6ddcSMark Murray cfb64_printsub }, 12881cb6ddcSMark Murray { "DES_OFB64", ENCTYPE_DES_OFB64, 12981cb6ddcSMark Murray ofb64_encrypt, 13081cb6ddcSMark Murray ofb64_decrypt, 13181cb6ddcSMark Murray ofb64_init, 13281cb6ddcSMark Murray ofb64_start, 13381cb6ddcSMark Murray ofb64_is, 13481cb6ddcSMark Murray ofb64_reply, 13581cb6ddcSMark Murray ofb64_session, 13681cb6ddcSMark Murray ofb64_keyid, 13781cb6ddcSMark Murray ofb64_printsub }, 1388fa113e5SMark Murray { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 13981cb6ddcSMark Murray }; 14081cb6ddcSMark Murray 14181cb6ddcSMark Murray static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, 14281cb6ddcSMark Murray ENCRYPT_SUPPORT }; 14381cb6ddcSMark Murray static unsigned char str_suplen = 0; 14481cb6ddcSMark Murray static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT }; 14581cb6ddcSMark Murray static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; 14681cb6ddcSMark Murray 14781cb6ddcSMark Murray Encryptions * 1488fa113e5SMark Murray findencryption(int type) 14981cb6ddcSMark Murray { 15081cb6ddcSMark Murray Encryptions *ep = encryptions; 15181cb6ddcSMark Murray 1528fa113e5SMark Murray if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & (unsigned)typemask(type))) 15381cb6ddcSMark Murray return(0); 15481cb6ddcSMark Murray while (ep->type && ep->type != type) 15581cb6ddcSMark Murray ++ep; 15681cb6ddcSMark Murray return(ep->type ? ep : 0); 15781cb6ddcSMark Murray } 15881cb6ddcSMark Murray 1598fa113e5SMark Murray static Encryptions * 1608fa113e5SMark Murray finddecryption(int type) 16181cb6ddcSMark Murray { 16281cb6ddcSMark Murray Encryptions *ep = encryptions; 16381cb6ddcSMark Murray 1648fa113e5SMark Murray if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & (unsigned)typemask(type))) 16581cb6ddcSMark Murray return(0); 16681cb6ddcSMark Murray while (ep->type && ep->type != type) 16781cb6ddcSMark Murray ++ep; 16881cb6ddcSMark Murray return(ep->type ? ep : 0); 16981cb6ddcSMark Murray } 17081cb6ddcSMark Murray 17181cb6ddcSMark Murray #define MAXKEYLEN 64 17281cb6ddcSMark Murray 17381cb6ddcSMark Murray static struct key_info { 17481cb6ddcSMark Murray unsigned char keyid[MAXKEYLEN]; 17581cb6ddcSMark Murray int keylen; 17681cb6ddcSMark Murray int dir; 17781cb6ddcSMark Murray int *modep; 1788fa113e5SMark Murray Encryptions *(*getcrypt)(int); 17981cb6ddcSMark Murray } ki[2] = { 18081cb6ddcSMark Murray { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption }, 18181cb6ddcSMark Murray { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption }, 18281cb6ddcSMark Murray }; 18381cb6ddcSMark Murray 18404c426ccSMark Murray static void encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len); 18504c426ccSMark Murray 18681cb6ddcSMark Murray void 1878fa113e5SMark Murray encrypt_init(const char *name, int server) 18881cb6ddcSMark Murray { 18981cb6ddcSMark Murray Encryptions *ep = encryptions; 19081cb6ddcSMark Murray 19181cb6ddcSMark Murray Name = name; 19281cb6ddcSMark Murray Server = server; 19381cb6ddcSMark Murray i_support_encrypt = i_support_decrypt = 0; 19481cb6ddcSMark Murray remote_supports_encrypt = remote_supports_decrypt = 0; 19581cb6ddcSMark Murray encrypt_mode = 0; 19681cb6ddcSMark Murray decrypt_mode = 0; 19781cb6ddcSMark Murray encrypt_output = 0; 19881cb6ddcSMark Murray decrypt_input = 0; 19981cb6ddcSMark Murray 20081cb6ddcSMark Murray str_suplen = 4; 20181cb6ddcSMark Murray 20281cb6ddcSMark Murray while (ep->type) { 20381cb6ddcSMark Murray if (encrypt_debug_mode) 20481cb6ddcSMark Murray printf(">>>%s: I will support %s\r\n", 20581cb6ddcSMark Murray Name, ENCTYPE_NAME(ep->type)); 20681cb6ddcSMark Murray i_support_encrypt |= typemask(ep->type); 20781cb6ddcSMark Murray i_support_decrypt |= typemask(ep->type); 20881cb6ddcSMark Murray if ((i_wont_support_decrypt & typemask(ep->type)) == 0) 20981cb6ddcSMark Murray if ((str_send[str_suplen++] = ep->type) == IAC) 21081cb6ddcSMark Murray str_send[str_suplen++] = IAC; 21181cb6ddcSMark Murray if (ep->init) 21281cb6ddcSMark Murray (*ep->init)(Server); 21381cb6ddcSMark Murray ++ep; 21481cb6ddcSMark Murray } 21581cb6ddcSMark Murray str_send[str_suplen++] = IAC; 21681cb6ddcSMark Murray str_send[str_suplen++] = SE; 21781cb6ddcSMark Murray } 21881cb6ddcSMark Murray 2198fa113e5SMark Murray static void 2208fa113e5SMark Murray encrypt_list_types(void) 22181cb6ddcSMark Murray { 22281cb6ddcSMark Murray Encryptions *ep = encryptions; 22381cb6ddcSMark Murray 22481cb6ddcSMark Murray printf("Valid encryption types:\n"); 22581cb6ddcSMark Murray while (ep->type) { 22681cb6ddcSMark Murray printf("\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type); 22781cb6ddcSMark Murray ++ep; 22881cb6ddcSMark Murray } 22981cb6ddcSMark Murray } 23081cb6ddcSMark Murray 23181cb6ddcSMark Murray int 2328fa113e5SMark Murray EncryptEnable(char *type, char *mode) 23381cb6ddcSMark Murray { 23481cb6ddcSMark Murray if (isprefix(type, "help") || isprefix(type, "?")) { 23581cb6ddcSMark Murray printf("Usage: encrypt enable <type> [input|output]\n"); 23681cb6ddcSMark Murray encrypt_list_types(); 23781cb6ddcSMark Murray return(0); 23881cb6ddcSMark Murray } 23981cb6ddcSMark Murray if (EncryptType(type, mode)) 24081cb6ddcSMark Murray return(EncryptStart(mode)); 24181cb6ddcSMark Murray return(0); 24281cb6ddcSMark Murray } 24381cb6ddcSMark Murray 24481cb6ddcSMark Murray int 2458fa113e5SMark Murray EncryptDisable(char *type, char *mode) 24681cb6ddcSMark Murray { 2478fa113e5SMark Murray Encryptions *ep; 24881cb6ddcSMark Murray int ret = 0; 24981cb6ddcSMark Murray 25081cb6ddcSMark Murray if (isprefix(type, "help") || isprefix(type, "?")) { 25181cb6ddcSMark Murray printf("Usage: encrypt disable <type> [input|output]\n"); 25281cb6ddcSMark Murray encrypt_list_types(); 25304c426ccSMark Murray } else if ((ep = (Encryptions *)genget(type, (char **)encryptions, 25481cb6ddcSMark Murray sizeof(Encryptions))) == 0) { 25581cb6ddcSMark Murray printf("%s: invalid encryption type\n", type); 25604c426ccSMark Murray } else if (Ambiguous((char **)ep)) { 25781cb6ddcSMark Murray printf("Ambiguous type '%s'\n", type); 25881cb6ddcSMark Murray } else { 25981cb6ddcSMark Murray if ((mode == 0) || (isprefix(mode, "input") ? 1 : 0)) { 26081cb6ddcSMark Murray if (decrypt_mode == ep->type) 26181cb6ddcSMark Murray EncryptStopInput(); 26281cb6ddcSMark Murray i_wont_support_decrypt |= typemask(ep->type); 26381cb6ddcSMark Murray ret = 1; 26481cb6ddcSMark Murray } 26581cb6ddcSMark Murray if ((mode == 0) || (isprefix(mode, "output"))) { 26681cb6ddcSMark Murray if (encrypt_mode == ep->type) 26781cb6ddcSMark Murray EncryptStopOutput(); 26881cb6ddcSMark Murray i_wont_support_encrypt |= typemask(ep->type); 26981cb6ddcSMark Murray ret = 1; 27081cb6ddcSMark Murray } 27181cb6ddcSMark Murray if (ret == 0) 27281cb6ddcSMark Murray printf("%s: invalid encryption mode\n", mode); 27381cb6ddcSMark Murray } 27481cb6ddcSMark Murray return(ret); 27581cb6ddcSMark Murray } 27681cb6ddcSMark Murray 27781cb6ddcSMark Murray int 2788fa113e5SMark Murray EncryptType(char *type, char *mode) 27981cb6ddcSMark Murray { 2808fa113e5SMark Murray 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(); 28604c426ccSMark Murray } else if ((ep = (Encryptions *)genget(type, (char **)encryptions, 28781cb6ddcSMark Murray sizeof(Encryptions))) == 0) { 28881cb6ddcSMark Murray printf("%s: invalid encryption type\n", type); 28904c426ccSMark Murray } else if (Ambiguous((char **)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 3098fa113e5SMark Murray EncryptStart(char *mode) 31081cb6ddcSMark Murray { 3118fa113e5SMark Murray int ret = 0; 31281cb6ddcSMark Murray if (mode) { 31381cb6ddcSMark Murray if (isprefix(mode, "input")) 31481cb6ddcSMark Murray return(EncryptStartInput()); 31581cb6ddcSMark Murray if (isprefix(mode, "output")) 31681cb6ddcSMark Murray return(EncryptStartOutput()); 31781cb6ddcSMark Murray if (isprefix(mode, "help") || isprefix(mode, "?")) { 31881cb6ddcSMark Murray printf("Usage: encrypt start [input|output]\n"); 31981cb6ddcSMark Murray return(0); 32081cb6ddcSMark Murray } 32181cb6ddcSMark Murray printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode); 32281cb6ddcSMark Murray return(0); 32381cb6ddcSMark Murray } 32481cb6ddcSMark Murray ret += EncryptStartInput(); 32581cb6ddcSMark Murray ret += EncryptStartOutput(); 32681cb6ddcSMark Murray return(ret); 32781cb6ddcSMark Murray } 32881cb6ddcSMark Murray 32981cb6ddcSMark Murray int 3308fa113e5SMark Murray EncryptStartInput(void) 33181cb6ddcSMark Murray { 33281cb6ddcSMark Murray if (decrypt_mode) { 33381cb6ddcSMark Murray encrypt_send_request_start(); 33481cb6ddcSMark Murray return(1); 33581cb6ddcSMark Murray } 33681cb6ddcSMark Murray printf("No previous decryption mode, decryption not enabled\r\n"); 33781cb6ddcSMark Murray return(0); 33881cb6ddcSMark Murray } 33981cb6ddcSMark Murray 34081cb6ddcSMark Murray int 3418fa113e5SMark Murray EncryptStartOutput(void) 34281cb6ddcSMark Murray { 34381cb6ddcSMark Murray if (encrypt_mode) { 34481cb6ddcSMark Murray encrypt_start_output(encrypt_mode); 34581cb6ddcSMark Murray return(1); 34681cb6ddcSMark Murray } 34781cb6ddcSMark Murray printf("No previous encryption mode, encryption not enabled\r\n"); 34881cb6ddcSMark Murray return(0); 34981cb6ddcSMark Murray } 35081cb6ddcSMark Murray 35181cb6ddcSMark Murray int 3528fa113e5SMark Murray EncryptStop(char *mode) 35381cb6ddcSMark Murray { 35481cb6ddcSMark Murray int ret = 0; 35581cb6ddcSMark Murray if (mode) { 35681cb6ddcSMark Murray if (isprefix(mode, "input")) 35781cb6ddcSMark Murray return(EncryptStopInput()); 35881cb6ddcSMark Murray if (isprefix(mode, "output")) 35981cb6ddcSMark Murray return(EncryptStopOutput()); 36081cb6ddcSMark Murray if (isprefix(mode, "help") || isprefix(mode, "?")) { 36181cb6ddcSMark Murray printf("Usage: encrypt stop [input|output]\n"); 36281cb6ddcSMark Murray return(0); 36381cb6ddcSMark Murray } 36481cb6ddcSMark Murray printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode); 36581cb6ddcSMark Murray return(0); 36681cb6ddcSMark Murray } 36781cb6ddcSMark Murray ret += EncryptStopInput(); 36881cb6ddcSMark Murray ret += EncryptStopOutput(); 36981cb6ddcSMark Murray return(ret); 37081cb6ddcSMark Murray } 37181cb6ddcSMark Murray 37281cb6ddcSMark Murray int 3738fa113e5SMark Murray EncryptStopInput(void) 37481cb6ddcSMark Murray { 37581cb6ddcSMark Murray encrypt_send_request_end(); 37681cb6ddcSMark Murray return(1); 37781cb6ddcSMark Murray } 37881cb6ddcSMark Murray 37981cb6ddcSMark Murray int 3808fa113e5SMark Murray EncryptStopOutput(void) 38181cb6ddcSMark Murray { 38281cb6ddcSMark Murray encrypt_send_end(); 38381cb6ddcSMark Murray return(1); 38481cb6ddcSMark Murray } 38581cb6ddcSMark Murray 38681cb6ddcSMark Murray void 3878fa113e5SMark Murray encrypt_display(void) 38881cb6ddcSMark Murray { 38981cb6ddcSMark Murray if (encrypt_output) 39081cb6ddcSMark Murray printf("Currently encrypting output with %s\r\n", 39181cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 39281cb6ddcSMark Murray if (decrypt_input) 39381cb6ddcSMark Murray printf("Currently decrypting input with %s\r\n", 39481cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 39581cb6ddcSMark Murray } 39681cb6ddcSMark Murray 39781cb6ddcSMark Murray int 3988fa113e5SMark Murray EncryptStatus(void) 39981cb6ddcSMark Murray { 40081cb6ddcSMark Murray if (encrypt_output) 40181cb6ddcSMark Murray printf("Currently encrypting output with %s\r\n", 40281cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 40381cb6ddcSMark Murray else if (encrypt_mode) { 40481cb6ddcSMark Murray printf("Currently output is clear text.\r\n"); 40581cb6ddcSMark Murray printf("Last encryption mode was %s\r\n", 40681cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 40781cb6ddcSMark Murray } 40881cb6ddcSMark Murray if (decrypt_input) { 40981cb6ddcSMark Murray printf("Currently decrypting input with %s\r\n", 41081cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 41181cb6ddcSMark Murray } else if (decrypt_mode) { 41281cb6ddcSMark Murray printf("Currently input is clear text.\r\n"); 41381cb6ddcSMark Murray printf("Last decryption mode was %s\r\n", 41481cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 41581cb6ddcSMark Murray } 41681cb6ddcSMark Murray return 1; 41781cb6ddcSMark Murray } 41881cb6ddcSMark Murray 41981cb6ddcSMark Murray void 4208fa113e5SMark Murray encrypt_send_support(void) 42181cb6ddcSMark Murray { 42281cb6ddcSMark Murray if (str_suplen) { 42381cb6ddcSMark Murray /* 42481cb6ddcSMark Murray * If the user has requested that decryption start 42581cb6ddcSMark Murray * immediatly, then send a "REQUEST START" before 42681cb6ddcSMark Murray * we negotiate the type. 42781cb6ddcSMark Murray */ 42881cb6ddcSMark Murray if (!Server && autodecrypt) 42981cb6ddcSMark Murray encrypt_send_request_start(); 43081cb6ddcSMark Murray net_write(str_send, str_suplen); 43181cb6ddcSMark Murray printsub('>', &str_send[2], str_suplen - 2); 43281cb6ddcSMark Murray str_suplen = 0; 43381cb6ddcSMark Murray } 43481cb6ddcSMark Murray } 43581cb6ddcSMark Murray 43681cb6ddcSMark Murray int 4378fa113e5SMark Murray EncryptDebug(int on) 43881cb6ddcSMark Murray { 43981cb6ddcSMark Murray if (on < 0) 44081cb6ddcSMark Murray encrypt_debug_mode ^= 1; 44181cb6ddcSMark Murray else 44281cb6ddcSMark Murray encrypt_debug_mode = on; 44381cb6ddcSMark Murray printf("Encryption debugging %s\r\n", 44481cb6ddcSMark Murray encrypt_debug_mode ? "enabled" : "disabled"); 44581cb6ddcSMark Murray return(1); 44681cb6ddcSMark Murray } 44781cb6ddcSMark Murray 44881cb6ddcSMark Murray int 4498fa113e5SMark Murray EncryptVerbose(int on) 45081cb6ddcSMark Murray { 45181cb6ddcSMark Murray if (on < 0) 45281cb6ddcSMark Murray encrypt_verbose ^= 1; 45381cb6ddcSMark Murray else 45481cb6ddcSMark Murray encrypt_verbose = on; 45581cb6ddcSMark Murray printf("Encryption %s verbose\r\n", 45681cb6ddcSMark Murray encrypt_verbose ? "is" : "is not"); 45781cb6ddcSMark Murray return(1); 45881cb6ddcSMark Murray } 45981cb6ddcSMark Murray 46081cb6ddcSMark Murray int 4618fa113e5SMark Murray EncryptAutoEnc(int on) 46281cb6ddcSMark Murray { 46381cb6ddcSMark Murray encrypt_auto(on); 46481cb6ddcSMark Murray printf("Automatic encryption of output is %s\r\n", 46581cb6ddcSMark Murray autoencrypt ? "enabled" : "disabled"); 46681cb6ddcSMark Murray return(1); 46781cb6ddcSMark Murray } 46881cb6ddcSMark Murray 46981cb6ddcSMark Murray int 4708fa113e5SMark Murray EncryptAutoDec(int on) 47181cb6ddcSMark Murray { 47281cb6ddcSMark Murray decrypt_auto(on); 47381cb6ddcSMark Murray printf("Automatic decryption of input is %s\r\n", 47481cb6ddcSMark Murray autodecrypt ? "enabled" : "disabled"); 47581cb6ddcSMark Murray return(1); 47681cb6ddcSMark Murray } 47781cb6ddcSMark Murray 47881cb6ddcSMark Murray /* 47981cb6ddcSMark Murray * Called when ENCRYPT SUPPORT is received. 48081cb6ddcSMark Murray */ 48181cb6ddcSMark Murray void 4828fa113e5SMark Murray encrypt_support(unsigned char *typelist, int cnt) 48381cb6ddcSMark Murray { 4848fa113e5SMark Murray int type, use_type = 0; 48581cb6ddcSMark Murray Encryptions *ep; 48681cb6ddcSMark Murray 48781cb6ddcSMark Murray /* 48881cb6ddcSMark Murray * Forget anything the other side has previously told us. 48981cb6ddcSMark Murray */ 49081cb6ddcSMark Murray remote_supports_decrypt = 0; 49181cb6ddcSMark Murray 49281cb6ddcSMark Murray while (cnt-- > 0) { 49381cb6ddcSMark Murray type = *typelist++; 49481cb6ddcSMark Murray if (encrypt_debug_mode) 49581cb6ddcSMark Murray printf(">>>%s: He is supporting %s (%d)\r\n", 49681cb6ddcSMark Murray Name, 49781cb6ddcSMark Murray ENCTYPE_NAME(type), type); 49881cb6ddcSMark Murray if ((type < ENCTYPE_CNT) && 49981cb6ddcSMark Murray (I_SUPPORT_ENCRYPT & typemask(type))) { 50081cb6ddcSMark Murray remote_supports_decrypt |= typemask(type); 50181cb6ddcSMark Murray if (use_type == 0) 50281cb6ddcSMark Murray use_type = type; 50381cb6ddcSMark Murray } 50481cb6ddcSMark Murray } 50581cb6ddcSMark Murray if (use_type) { 50681cb6ddcSMark Murray ep = findencryption(use_type); 50781cb6ddcSMark Murray if (!ep) 50881cb6ddcSMark Murray return; 50981cb6ddcSMark Murray type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0; 51081cb6ddcSMark Murray if (encrypt_debug_mode) 51181cb6ddcSMark Murray printf(">>>%s: (*ep->start)() returned %d\r\n", 51281cb6ddcSMark Murray Name, type); 51381cb6ddcSMark Murray if (type < 0) 51481cb6ddcSMark Murray return; 51581cb6ddcSMark Murray encrypt_mode = use_type; 51681cb6ddcSMark Murray if (type == 0) 51781cb6ddcSMark Murray encrypt_start_output(use_type); 51881cb6ddcSMark Murray } 51981cb6ddcSMark Murray } 52081cb6ddcSMark Murray 52181cb6ddcSMark Murray void 5228fa113e5SMark Murray encrypt_is(unsigned char *data, int cnt) 52381cb6ddcSMark Murray { 52481cb6ddcSMark Murray Encryptions *ep; 5258fa113e5SMark Murray int type, ret; 52681cb6ddcSMark Murray 52781cb6ddcSMark Murray if (--cnt < 0) 52881cb6ddcSMark Murray return; 52981cb6ddcSMark Murray type = *data++; 53081cb6ddcSMark Murray if (type < ENCTYPE_CNT) 53181cb6ddcSMark Murray remote_supports_encrypt |= typemask(type); 53281cb6ddcSMark Murray if (!(ep = finddecryption(type))) { 53381cb6ddcSMark Murray if (encrypt_debug_mode) 53481cb6ddcSMark Murray printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 53581cb6ddcSMark Murray Name, 53681cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 53781cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 53881cb6ddcSMark Murray type); 53981cb6ddcSMark Murray return; 54081cb6ddcSMark Murray } 54181cb6ddcSMark Murray if (!ep->is) { 54281cb6ddcSMark Murray if (encrypt_debug_mode) 54381cb6ddcSMark Murray printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 54481cb6ddcSMark Murray Name, 54581cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 54681cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 54781cb6ddcSMark Murray type); 54881cb6ddcSMark Murray ret = 0; 54981cb6ddcSMark Murray } else { 55081cb6ddcSMark Murray ret = (*ep->is)(data, cnt); 55181cb6ddcSMark Murray if (encrypt_debug_mode) 55204c426ccSMark Murray printf("(*ep->is)(%p, %d) returned %s(%d)\n", data, cnt, 55381cb6ddcSMark Murray (ret < 0) ? "FAIL " : 55481cb6ddcSMark Murray (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 55581cb6ddcSMark Murray } 55681cb6ddcSMark Murray if (ret < 0) { 55781cb6ddcSMark Murray autodecrypt = 0; 55881cb6ddcSMark Murray } else { 55981cb6ddcSMark Murray decrypt_mode = type; 56081cb6ddcSMark Murray if (ret == 0 && autodecrypt) 56181cb6ddcSMark Murray encrypt_send_request_start(); 56281cb6ddcSMark Murray } 56381cb6ddcSMark Murray } 56481cb6ddcSMark Murray 56581cb6ddcSMark Murray void 5668fa113e5SMark Murray encrypt_reply(unsigned char *data, int cnt) 56781cb6ddcSMark Murray { 56881cb6ddcSMark Murray Encryptions *ep; 5698fa113e5SMark Murray int ret, type; 57081cb6ddcSMark Murray 57181cb6ddcSMark Murray if (--cnt < 0) 57281cb6ddcSMark Murray return; 57381cb6ddcSMark Murray type = *data++; 57481cb6ddcSMark Murray if (!(ep = findencryption(type))) { 57581cb6ddcSMark Murray if (encrypt_debug_mode) 57681cb6ddcSMark Murray printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 57781cb6ddcSMark Murray Name, 57881cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 57981cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 58081cb6ddcSMark Murray type); 58181cb6ddcSMark Murray return; 58281cb6ddcSMark Murray } 58381cb6ddcSMark Murray if (!ep->reply) { 58481cb6ddcSMark Murray if (encrypt_debug_mode) 58581cb6ddcSMark Murray printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 58681cb6ddcSMark Murray Name, 58781cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 58881cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 58981cb6ddcSMark Murray type); 59081cb6ddcSMark Murray ret = 0; 59181cb6ddcSMark Murray } else { 59281cb6ddcSMark Murray ret = (*ep->reply)(data, cnt); 59381cb6ddcSMark Murray if (encrypt_debug_mode) 59404c426ccSMark Murray printf("(*ep->reply)(%p, %d) returned %s(%d)\n", 59581cb6ddcSMark Murray data, cnt, 59681cb6ddcSMark Murray (ret < 0) ? "FAIL " : 59781cb6ddcSMark Murray (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 59881cb6ddcSMark Murray } 59981cb6ddcSMark Murray if (encrypt_debug_mode) 60081cb6ddcSMark Murray printf(">>>%s: encrypt_reply returned %d\n", Name, ret); 60181cb6ddcSMark Murray if (ret < 0) { 60281cb6ddcSMark Murray autoencrypt = 0; 60381cb6ddcSMark Murray } else { 60481cb6ddcSMark Murray encrypt_mode = type; 60581cb6ddcSMark Murray if (ret == 0 && autoencrypt) 60681cb6ddcSMark Murray encrypt_start_output(type); 60781cb6ddcSMark Murray } 60881cb6ddcSMark Murray } 60981cb6ddcSMark Murray 61081cb6ddcSMark Murray /* 61181cb6ddcSMark Murray * Called when a ENCRYPT START command is received. 61281cb6ddcSMark Murray */ 61381cb6ddcSMark Murray void 6148fa113e5SMark Murray encrypt_start(unsigned char *data __unused, int cnt __unused) 61581cb6ddcSMark Murray { 61681cb6ddcSMark Murray Encryptions *ep; 61781cb6ddcSMark Murray 61881cb6ddcSMark Murray if (!decrypt_mode) { 61981cb6ddcSMark Murray /* 62081cb6ddcSMark Murray * Something is wrong. We should not get a START 62181cb6ddcSMark Murray * command without having already picked our 62281cb6ddcSMark Murray * decryption scheme. Send a REQUEST-END to 62381cb6ddcSMark Murray * attempt to clear the channel... 62481cb6ddcSMark Murray */ 62581cb6ddcSMark Murray printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name); 62681cb6ddcSMark Murray encrypt_send_request_end(); 62781cb6ddcSMark Murray return; 62881cb6ddcSMark Murray } 62981cb6ddcSMark Murray 63004c426ccSMark Murray if ((ep = finddecryption(decrypt_mode))) { 63181cb6ddcSMark Murray decrypt_input = ep->input; 63281cb6ddcSMark Murray if (encrypt_verbose) 63381cb6ddcSMark Murray printf("[ Input is now decrypted with type %s ]\r\n", 63481cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 63581cb6ddcSMark Murray if (encrypt_debug_mode) 63681cb6ddcSMark Murray printf(">>>%s: Start to decrypt input with type %s\r\n", 63781cb6ddcSMark Murray Name, ENCTYPE_NAME(decrypt_mode)); 63881cb6ddcSMark Murray } else { 63981cb6ddcSMark Murray printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n", 64081cb6ddcSMark Murray Name, 64181cb6ddcSMark Murray ENCTYPE_NAME_OK(decrypt_mode) 64281cb6ddcSMark Murray ? ENCTYPE_NAME(decrypt_mode) 64381cb6ddcSMark Murray : "(unknown)", 64481cb6ddcSMark Murray decrypt_mode); 64581cb6ddcSMark Murray encrypt_send_request_end(); 64681cb6ddcSMark Murray } 64781cb6ddcSMark Murray } 64881cb6ddcSMark Murray 64981cb6ddcSMark Murray void 6508fa113e5SMark Murray encrypt_session_key( Session_Key *key, int server) 65181cb6ddcSMark Murray { 65281cb6ddcSMark Murray Encryptions *ep = encryptions; 65381cb6ddcSMark Murray 65481cb6ddcSMark Murray havesessionkey = 1; 65581cb6ddcSMark Murray 65681cb6ddcSMark Murray while (ep->type) { 65781cb6ddcSMark Murray if (ep->session) 65881cb6ddcSMark Murray (*ep->session)(key, server); 65981cb6ddcSMark Murray ++ep; 66081cb6ddcSMark Murray } 66181cb6ddcSMark Murray } 66281cb6ddcSMark Murray 66381cb6ddcSMark Murray /* 66481cb6ddcSMark Murray * Called when ENCRYPT END is received. 66581cb6ddcSMark Murray */ 66681cb6ddcSMark Murray void 6678fa113e5SMark Murray encrypt_end(void) 66881cb6ddcSMark Murray { 66981cb6ddcSMark Murray decrypt_input = 0; 67081cb6ddcSMark Murray if (encrypt_debug_mode) 67181cb6ddcSMark Murray printf(">>>%s: Input is back to clear text\r\n", Name); 67281cb6ddcSMark Murray if (encrypt_verbose) 67381cb6ddcSMark Murray printf("[ Input is now clear text ]\r\n"); 67481cb6ddcSMark Murray } 67581cb6ddcSMark Murray 67681cb6ddcSMark Murray /* 67781cb6ddcSMark Murray * Called when ENCRYPT REQUEST-END is received. 67881cb6ddcSMark Murray */ 67981cb6ddcSMark Murray void 6808fa113e5SMark Murray encrypt_request_end(void) 68181cb6ddcSMark Murray { 68281cb6ddcSMark Murray encrypt_send_end(); 68381cb6ddcSMark Murray } 68481cb6ddcSMark Murray 68581cb6ddcSMark Murray /* 68681cb6ddcSMark Murray * Called when ENCRYPT REQUEST-START is received. If we receive 68781cb6ddcSMark Murray * this before a type is picked, then that indicates that the 68881cb6ddcSMark Murray * other side wants us to start encrypting data as soon as we 68981cb6ddcSMark Murray * can. 69081cb6ddcSMark Murray */ 69181cb6ddcSMark Murray void 6928fa113e5SMark Murray encrypt_request_start(unsigned char *data __unused, int cnt __unused) 69381cb6ddcSMark Murray { 69481cb6ddcSMark Murray if (encrypt_mode == 0) { 69581cb6ddcSMark Murray if (Server) 69681cb6ddcSMark Murray autoencrypt = 1; 69781cb6ddcSMark Murray return; 69881cb6ddcSMark Murray } 69981cb6ddcSMark Murray encrypt_start_output(encrypt_mode); 70081cb6ddcSMark Murray } 70181cb6ddcSMark Murray 70281cb6ddcSMark Murray static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT }; 70381cb6ddcSMark Murray 70404c426ccSMark Murray void 7058fa113e5SMark Murray encrypt_enc_keyid(unsigned char *keyid, int len) 70681cb6ddcSMark Murray { 70781cb6ddcSMark Murray encrypt_keyid(&ki[1], keyid, len); 70881cb6ddcSMark Murray } 70981cb6ddcSMark Murray 71004c426ccSMark Murray void 7118fa113e5SMark Murray encrypt_dec_keyid(unsigned char *keyid, int len) 71281cb6ddcSMark Murray { 71381cb6ddcSMark Murray encrypt_keyid(&ki[0], keyid, len); 71481cb6ddcSMark Murray } 71581cb6ddcSMark Murray 71604c426ccSMark Murray void 7178fa113e5SMark Murray encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len) 71881cb6ddcSMark Murray { 71981cb6ddcSMark Murray Encryptions *ep; 72081cb6ddcSMark Murray int dir = kp->dir; 7218fa113e5SMark Murray int ret = 0; 72281cb6ddcSMark Murray 72381cb6ddcSMark Murray if (!(ep = (*kp->getcrypt)(*kp->modep))) { 72481cb6ddcSMark Murray if (len == 0) 72581cb6ddcSMark Murray return; 72681cb6ddcSMark Murray kp->keylen = 0; 72781cb6ddcSMark Murray } else if (len == 0) { 72881cb6ddcSMark Murray /* 72981cb6ddcSMark Murray * Empty option, indicates a failure. 73081cb6ddcSMark Murray */ 73181cb6ddcSMark Murray if (kp->keylen == 0) 73281cb6ddcSMark Murray return; 73381cb6ddcSMark Murray kp->keylen = 0; 73481cb6ddcSMark Murray if (ep->keyid) 73581cb6ddcSMark Murray (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); 73681cb6ddcSMark Murray 73781cb6ddcSMark Murray } else if ((len != kp->keylen) || 73881cb6ddcSMark Murray (memcmp(keyid, kp->keyid, len) != 0)) { 73981cb6ddcSMark Murray /* 74081cb6ddcSMark Murray * Length or contents are different 74181cb6ddcSMark Murray */ 74281cb6ddcSMark Murray kp->keylen = len; 74381cb6ddcSMark Murray memmove(kp->keyid, keyid, len); 74481cb6ddcSMark Murray if (ep->keyid) 74581cb6ddcSMark Murray (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); 74681cb6ddcSMark Murray } else { 74781cb6ddcSMark Murray if (ep->keyid) 74881cb6ddcSMark Murray ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen); 74981cb6ddcSMark Murray if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt) 75081cb6ddcSMark Murray encrypt_start_output(*kp->modep); 75181cb6ddcSMark Murray return; 75281cb6ddcSMark Murray } 75381cb6ddcSMark Murray 75481cb6ddcSMark Murray encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0); 75581cb6ddcSMark Murray } 75681cb6ddcSMark Murray 75781cb6ddcSMark Murray void 7588fa113e5SMark Murray encrypt_send_keyid(int dir, const char *keyid, int keylen, int saveit) 75981cb6ddcSMark Murray { 76081cb6ddcSMark Murray unsigned char *strp; 76181cb6ddcSMark Murray 76281cb6ddcSMark Murray str_keyid[3] = (dir == DIR_ENCRYPT) 76381cb6ddcSMark Murray ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID; 76481cb6ddcSMark Murray if (saveit) { 76581cb6ddcSMark Murray struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1]; 76681cb6ddcSMark Murray memmove(kp->keyid, keyid, keylen); 76781cb6ddcSMark Murray kp->keylen = keylen; 76881cb6ddcSMark Murray } 76981cb6ddcSMark Murray 77081cb6ddcSMark Murray for (strp = &str_keyid[4]; keylen > 0; --keylen) { 77181cb6ddcSMark Murray if ((*strp++ = *keyid++) == IAC) 77281cb6ddcSMark Murray *strp++ = IAC; 77381cb6ddcSMark Murray } 77481cb6ddcSMark Murray *strp++ = IAC; 77581cb6ddcSMark Murray *strp++ = SE; 77681cb6ddcSMark Murray net_write(str_keyid, strp - str_keyid); 77781cb6ddcSMark Murray printsub('>', &str_keyid[2], strp - str_keyid - 2); 77881cb6ddcSMark Murray } 77981cb6ddcSMark Murray 78081cb6ddcSMark Murray void 7818fa113e5SMark Murray encrypt_auto(int on) 78281cb6ddcSMark Murray { 78381cb6ddcSMark Murray if (on < 0) 78481cb6ddcSMark Murray autoencrypt ^= 1; 78581cb6ddcSMark Murray else 78681cb6ddcSMark Murray autoencrypt = on ? 1 : 0; 78781cb6ddcSMark Murray } 78881cb6ddcSMark Murray 78981cb6ddcSMark Murray void 7908fa113e5SMark Murray decrypt_auto(int on) 79181cb6ddcSMark Murray { 79281cb6ddcSMark Murray if (on < 0) 79381cb6ddcSMark Murray autodecrypt ^= 1; 79481cb6ddcSMark Murray else 79581cb6ddcSMark Murray autodecrypt = on ? 1 : 0; 79681cb6ddcSMark Murray } 79781cb6ddcSMark Murray 79881cb6ddcSMark Murray void 7998fa113e5SMark Murray encrypt_start_output(int type) 80081cb6ddcSMark Murray { 80181cb6ddcSMark Murray Encryptions *ep; 8028fa113e5SMark Murray unsigned char *p; 8038fa113e5SMark Murray int i; 80481cb6ddcSMark Murray 80581cb6ddcSMark Murray if (!(ep = findencryption(type))) { 80681cb6ddcSMark Murray if (encrypt_debug_mode) { 80781cb6ddcSMark Murray printf(">>>%s: Can't encrypt with type %s (%d)\r\n", 80881cb6ddcSMark Murray Name, 80981cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 81081cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 81181cb6ddcSMark Murray type); 81281cb6ddcSMark Murray } 81381cb6ddcSMark Murray return; 81481cb6ddcSMark Murray } 81581cb6ddcSMark Murray if (ep->start) { 81681cb6ddcSMark Murray i = (*ep->start)(DIR_ENCRYPT, Server); 81781cb6ddcSMark Murray if (encrypt_debug_mode) { 81881cb6ddcSMark Murray printf(">>>%s: Encrypt start: %s (%d) %s\r\n", 81981cb6ddcSMark Murray Name, 82081cb6ddcSMark Murray (i < 0) ? "failed" : 82181cb6ddcSMark Murray "initial negotiation in progress", 82281cb6ddcSMark Murray i, ENCTYPE_NAME(type)); 82381cb6ddcSMark Murray } 82481cb6ddcSMark Murray if (i) 82581cb6ddcSMark Murray return; 82681cb6ddcSMark Murray } 82781cb6ddcSMark Murray p = str_start + 3; 82881cb6ddcSMark Murray *p++ = ENCRYPT_START; 82981cb6ddcSMark Murray for (i = 0; i < ki[0].keylen; ++i) { 83081cb6ddcSMark Murray if ((*p++ = ki[0].keyid[i]) == IAC) 83181cb6ddcSMark Murray *p++ = IAC; 83281cb6ddcSMark Murray } 83381cb6ddcSMark Murray *p++ = IAC; 83481cb6ddcSMark Murray *p++ = SE; 83581cb6ddcSMark Murray net_write(str_start, p - str_start); 83681cb6ddcSMark Murray net_encrypt(); 83781cb6ddcSMark Murray printsub('>', &str_start[2], p - &str_start[2]); 83881cb6ddcSMark Murray /* 83981cb6ddcSMark Murray * If we are already encrypting in some mode, then 84081cb6ddcSMark Murray * encrypt the ring (which includes our request) in 84181cb6ddcSMark Murray * the old mode, mark it all as "clear text" and then 84281cb6ddcSMark Murray * switch to the new mode. 84381cb6ddcSMark Murray */ 84481cb6ddcSMark Murray encrypt_output = ep->output; 84581cb6ddcSMark Murray encrypt_mode = type; 84681cb6ddcSMark Murray if (encrypt_debug_mode) 84781cb6ddcSMark Murray printf(">>>%s: Started to encrypt output with type %s\r\n", 84881cb6ddcSMark Murray Name, ENCTYPE_NAME(type)); 84981cb6ddcSMark Murray if (encrypt_verbose) 85081cb6ddcSMark Murray printf("[ Output is now encrypted with type %s ]\r\n", 85181cb6ddcSMark Murray ENCTYPE_NAME(type)); 85281cb6ddcSMark Murray } 85381cb6ddcSMark Murray 85481cb6ddcSMark Murray void 8558fa113e5SMark Murray encrypt_send_end(void) 85681cb6ddcSMark Murray { 85781cb6ddcSMark Murray if (!encrypt_output) 85881cb6ddcSMark Murray return; 85981cb6ddcSMark Murray 86081cb6ddcSMark Murray str_end[3] = ENCRYPT_END; 86181cb6ddcSMark Murray net_write(str_end, sizeof(str_end)); 86281cb6ddcSMark Murray net_encrypt(); 86381cb6ddcSMark Murray printsub('>', &str_end[2], sizeof(str_end) - 2); 86481cb6ddcSMark Murray /* 86581cb6ddcSMark Murray * Encrypt the output buffer now because it will not be done by 86681cb6ddcSMark Murray * netflush... 86781cb6ddcSMark Murray */ 86881cb6ddcSMark Murray encrypt_output = 0; 86981cb6ddcSMark Murray if (encrypt_debug_mode) 87081cb6ddcSMark Murray printf(">>>%s: Output is back to clear text\r\n", Name); 87181cb6ddcSMark Murray if (encrypt_verbose) 87281cb6ddcSMark Murray printf("[ Output is now clear text ]\r\n"); 87381cb6ddcSMark Murray } 87481cb6ddcSMark Murray 87581cb6ddcSMark Murray void 8768fa113e5SMark Murray encrypt_send_request_start(void) 87781cb6ddcSMark Murray { 8788fa113e5SMark Murray unsigned char *p; 8798fa113e5SMark Murray int i; 88081cb6ddcSMark Murray 88181cb6ddcSMark Murray p = &str_start[3]; 88281cb6ddcSMark Murray *p++ = ENCRYPT_REQSTART; 88381cb6ddcSMark Murray for (i = 0; i < ki[1].keylen; ++i) { 88481cb6ddcSMark Murray if ((*p++ = ki[1].keyid[i]) == IAC) 88581cb6ddcSMark Murray *p++ = IAC; 88681cb6ddcSMark Murray } 88781cb6ddcSMark Murray *p++ = IAC; 88881cb6ddcSMark Murray *p++ = SE; 88981cb6ddcSMark Murray net_write(str_start, p - str_start); 89081cb6ddcSMark Murray printsub('>', &str_start[2], p - &str_start[2]); 89181cb6ddcSMark Murray if (encrypt_debug_mode) 89281cb6ddcSMark Murray printf(">>>%s: Request input to be encrypted\r\n", Name); 89381cb6ddcSMark Murray } 89481cb6ddcSMark Murray 89581cb6ddcSMark Murray void 8968fa113e5SMark Murray encrypt_send_request_end(void) 89781cb6ddcSMark Murray { 89881cb6ddcSMark Murray str_end[3] = ENCRYPT_REQEND; 89981cb6ddcSMark Murray net_write(str_end, sizeof(str_end)); 90081cb6ddcSMark Murray printsub('>', &str_end[2], sizeof(str_end) - 2); 90181cb6ddcSMark Murray 90281cb6ddcSMark Murray if (encrypt_debug_mode) 90381cb6ddcSMark Murray printf(">>>%s: Request input to be clear text\r\n", Name); 90481cb6ddcSMark Murray } 90581cb6ddcSMark Murray 90681cb6ddcSMark Murray void 9078fa113e5SMark Murray encrypt_wait(void) 90881cb6ddcSMark Murray { 90981cb6ddcSMark Murray if (encrypt_debug_mode) 91081cb6ddcSMark Murray printf(">>>%s: in encrypt_wait\r\n", Name); 91181cb6ddcSMark Murray if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt)) 91281cb6ddcSMark Murray return; 91381cb6ddcSMark Murray while (autoencrypt && !encrypt_output) 91481cb6ddcSMark Murray if (telnet_spin()) 91581cb6ddcSMark Murray return; 91681cb6ddcSMark Murray } 91781cb6ddcSMark Murray 91881cb6ddcSMark Murray void 9198fa113e5SMark Murray encrypt_gen_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 92081cb6ddcSMark Murray { 92181cb6ddcSMark Murray char tbuf[16], *cp; 92281cb6ddcSMark Murray 92381cb6ddcSMark Murray cnt -= 2; 92481cb6ddcSMark Murray data += 2; 92581cb6ddcSMark Murray buf[buflen-1] = '\0'; 92681cb6ddcSMark Murray buf[buflen-2] = '*'; 92781cb6ddcSMark Murray buflen -= 2;; 92881cb6ddcSMark Murray for (; cnt > 0; cnt--, data++) { 92981cb6ddcSMark Murray sprintf(tbuf, " %d", *data); 93081cb6ddcSMark Murray for (cp = tbuf; *cp && buflen > 0; --buflen) 93181cb6ddcSMark Murray *buf++ = *cp++; 93281cb6ddcSMark Murray if (buflen <= 0) 93381cb6ddcSMark Murray return; 93481cb6ddcSMark Murray } 93581cb6ddcSMark Murray *buf = '\0'; 93681cb6ddcSMark Murray } 93781cb6ddcSMark Murray 93881cb6ddcSMark Murray void 9398fa113e5SMark Murray encrypt_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 94081cb6ddcSMark Murray { 94181cb6ddcSMark Murray Encryptions *ep; 9428fa113e5SMark Murray int type = data[1]; 94381cb6ddcSMark Murray 94481cb6ddcSMark Murray for (ep = encryptions; ep->type && ep->type != type; ep++) 94581cb6ddcSMark Murray ; 94681cb6ddcSMark Murray 94781cb6ddcSMark Murray if (ep->printsub) 94881cb6ddcSMark Murray (*ep->printsub)(data, cnt, buf, buflen); 94981cb6ddcSMark Murray else 95081cb6ddcSMark Murray encrypt_gen_printsub(data, cnt, buf, buflen); 95181cb6ddcSMark Murray } 95281cb6ddcSMark Murray #endif /* ENCRYPTION */ 953