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. 1383129c0bSEd Maste * 3. Neither the name of the University nor the names of its contributors 1481cb6ddcSMark Murray * may be used to endorse or promote products derived from this software 1581cb6ddcSMark Murray * without specific prior written permission. 1681cb6ddcSMark Murray * 1781cb6ddcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1881cb6ddcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1981cb6ddcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2081cb6ddcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2181cb6ddcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2281cb6ddcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2381cb6ddcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2481cb6ddcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2581cb6ddcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2681cb6ddcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2781cb6ddcSMark Murray * SUCH DAMAGE. 2881cb6ddcSMark Murray */ 2981cb6ddcSMark Murray 30f2ac7de9SMark Murray #include <sys/cdefs.h> 318fa113e5SMark Murray 32f2ac7de9SMark Murray __FBSDID("$FreeBSD$"); 33f2ac7de9SMark Murray 3481cb6ddcSMark Murray #ifndef lint 35ecece7e3SPeter Wemm #if 0 3604c426ccSMark Murray static const char sccsid[] = "@(#)encrypt.c 8.2 (Berkeley) 5/30/95"; 37ecece7e3SPeter Wemm #endif 3881cb6ddcSMark Murray #endif /* not lint */ 3981cb6ddcSMark Murray 4081cb6ddcSMark Murray /* 4181cb6ddcSMark Murray * Copyright (C) 1990 by the Massachusetts Institute of Technology 4281cb6ddcSMark Murray * 4381cb6ddcSMark Murray * Export of this software from the United States of America is assumed 4481cb6ddcSMark Murray * to require a specific license from the United States Government. 4581cb6ddcSMark Murray * It is the responsibility of any person or organization contemplating 4681cb6ddcSMark Murray * export to obtain such a license before exporting. 4781cb6ddcSMark Murray * 4881cb6ddcSMark Murray * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 4981cb6ddcSMark Murray * distribute this software and its documentation for any purpose and 5081cb6ddcSMark Murray * without fee is hereby granted, provided that the above copyright 5181cb6ddcSMark Murray * notice appear in all copies and that both that copyright notice and 5281cb6ddcSMark Murray * this permission notice appear in supporting documentation, and that 5381cb6ddcSMark Murray * the name of M.I.T. not be used in advertising or publicity pertaining 5481cb6ddcSMark Murray * to distribution of the software without specific, written prior 5581cb6ddcSMark Murray * permission. M.I.T. makes no representations about the suitability of 5681cb6ddcSMark Murray * this software for any purpose. It is provided "as is" without express 5781cb6ddcSMark Murray * or implied warranty. 5881cb6ddcSMark Murray */ 5981cb6ddcSMark Murray 6081cb6ddcSMark Murray #ifdef ENCRYPTION 6181cb6ddcSMark Murray 6278455da4SMark Murray #include <sys/types.h> 6381cb6ddcSMark Murray #define ENCRYPT_NAMES 6481cb6ddcSMark Murray #include <arpa/telnet.h> 658fa113e5SMark Murray #include <stdio.h> 668fa113e5SMark Murray #include <stdlib.h> 678fa113e5SMark Murray #include <string.h> 6881cb6ddcSMark Murray 6981cb6ddcSMark Murray #include "encrypt.h" 7081cb6ddcSMark Murray #include "misc.h" 7181cb6ddcSMark Murray 72*42b4e3fbSKyle Evans /* 73*42b4e3fbSKyle Evans * These functions pointers point to the current routines 74*42b4e3fbSKyle Evans * for encrypting and decrypting data. 75*42b4e3fbSKyle Evans */ 76*42b4e3fbSKyle Evans void (*encrypt_output)(unsigned char *, int); 77*42b4e3fbSKyle Evans int (*decrypt_input)(int); 78*42b4e3fbSKyle Evans 7904c426ccSMark Murray int EncryptType(char *type, char *mode); 8004c426ccSMark Murray int EncryptStart(char *mode); 8104c426ccSMark Murray int EncryptStop(char *mode); 8204c426ccSMark Murray int EncryptStartInput(void); 8304c426ccSMark Murray int EncryptStartOutput(void); 8404c426ccSMark Murray int EncryptStopInput(void); 8504c426ccSMark Murray int EncryptStopOutput(void); 8604c426ccSMark Murray 8781cb6ddcSMark Murray int encrypt_debug_mode = 0; 8881cb6ddcSMark Murray static int decrypt_mode = 0; 8981cb6ddcSMark Murray static int encrypt_mode = 0; 9081cb6ddcSMark Murray static int encrypt_verbose = 0; 9181cb6ddcSMark Murray static int autoencrypt = 0; 9281cb6ddcSMark Murray static int autodecrypt = 0; 9381cb6ddcSMark Murray static int havesessionkey = 0; 9481cb6ddcSMark Murray static int Server = 0; 958fa113e5SMark Murray static const char *Name = "Noname"; 9681cb6ddcSMark Murray 9781cb6ddcSMark Murray #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 9881cb6ddcSMark Murray 9978455da4SMark Murray static u_long i_support_encrypt = 0 1000f8c8396SNick Sayer | typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64) 1010f8c8396SNick Sayer |0; 10278455da4SMark Murray static u_long i_support_decrypt = 0 1030f8c8396SNick Sayer | typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64) 1040f8c8396SNick Sayer |0; 1050f8c8396SNick Sayer 10678455da4SMark Murray static u_long i_wont_support_encrypt = 0; 10778455da4SMark Murray static u_long i_wont_support_decrypt = 0; 10881cb6ddcSMark Murray #define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt) 10981cb6ddcSMark Murray #define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt) 11081cb6ddcSMark Murray 11178455da4SMark Murray static u_long remote_supports_encrypt = 0; 11278455da4SMark Murray static u_long remote_supports_decrypt = 0; 11381cb6ddcSMark Murray 11481cb6ddcSMark Murray static Encryptions encryptions[] = { 11581cb6ddcSMark Murray { "DES_CFB64", ENCTYPE_DES_CFB64, 11681cb6ddcSMark Murray cfb64_encrypt, 11781cb6ddcSMark Murray cfb64_decrypt, 11881cb6ddcSMark Murray cfb64_init, 11981cb6ddcSMark Murray cfb64_start, 12081cb6ddcSMark Murray cfb64_is, 12181cb6ddcSMark Murray cfb64_reply, 12281cb6ddcSMark Murray cfb64_session, 12381cb6ddcSMark Murray cfb64_keyid, 12481cb6ddcSMark Murray cfb64_printsub }, 12581cb6ddcSMark Murray { "DES_OFB64", ENCTYPE_DES_OFB64, 12681cb6ddcSMark Murray ofb64_encrypt, 12781cb6ddcSMark Murray ofb64_decrypt, 12881cb6ddcSMark Murray ofb64_init, 12981cb6ddcSMark Murray ofb64_start, 13081cb6ddcSMark Murray ofb64_is, 13181cb6ddcSMark Murray ofb64_reply, 13281cb6ddcSMark Murray ofb64_session, 13381cb6ddcSMark Murray ofb64_keyid, 13481cb6ddcSMark Murray ofb64_printsub }, 1358fa113e5SMark Murray { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 13681cb6ddcSMark Murray }; 13781cb6ddcSMark Murray 13881cb6ddcSMark Murray static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, 13981cb6ddcSMark Murray ENCRYPT_SUPPORT }; 14081cb6ddcSMark Murray static unsigned char str_suplen = 0; 14181cb6ddcSMark Murray static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT }; 14281cb6ddcSMark Murray static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; 14381cb6ddcSMark Murray 14481cb6ddcSMark Murray Encryptions * 1458fa113e5SMark Murray findencryption(int type) 14681cb6ddcSMark Murray { 14781cb6ddcSMark Murray Encryptions *ep = encryptions; 14881cb6ddcSMark Murray 1498fa113e5SMark Murray if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & (unsigned)typemask(type))) 15081cb6ddcSMark Murray return(0); 15181cb6ddcSMark Murray while (ep->type && ep->type != type) 15281cb6ddcSMark Murray ++ep; 15381cb6ddcSMark Murray return(ep->type ? ep : 0); 15481cb6ddcSMark Murray } 15581cb6ddcSMark Murray 1568fa113e5SMark Murray static Encryptions * 1578fa113e5SMark Murray finddecryption(int type) 15881cb6ddcSMark Murray { 15981cb6ddcSMark Murray Encryptions *ep = encryptions; 16081cb6ddcSMark Murray 1618fa113e5SMark Murray if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & (unsigned)typemask(type))) 16281cb6ddcSMark Murray return(0); 16381cb6ddcSMark Murray while (ep->type && ep->type != type) 16481cb6ddcSMark Murray ++ep; 16581cb6ddcSMark Murray return(ep->type ? ep : 0); 16681cb6ddcSMark Murray } 16781cb6ddcSMark Murray 16881cb6ddcSMark Murray #define MAXKEYLEN 64 16981cb6ddcSMark Murray 17081cb6ddcSMark Murray static struct key_info { 17181cb6ddcSMark Murray unsigned char keyid[MAXKEYLEN]; 17281cb6ddcSMark Murray int keylen; 17381cb6ddcSMark Murray int dir; 17481cb6ddcSMark Murray int *modep; 1758fa113e5SMark Murray Encryptions *(*getcrypt)(int); 17681cb6ddcSMark Murray } ki[2] = { 17781cb6ddcSMark Murray { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption }, 17881cb6ddcSMark Murray { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption }, 17981cb6ddcSMark Murray }; 18081cb6ddcSMark Murray 18104c426ccSMark Murray static void encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len); 18204c426ccSMark Murray 18381cb6ddcSMark Murray void 1848fa113e5SMark Murray encrypt_init(const char *name, int server) 18581cb6ddcSMark Murray { 18681cb6ddcSMark Murray Encryptions *ep = encryptions; 18781cb6ddcSMark Murray 18881cb6ddcSMark Murray Name = name; 18981cb6ddcSMark Murray Server = server; 19081cb6ddcSMark Murray i_support_encrypt = i_support_decrypt = 0; 19181cb6ddcSMark Murray remote_supports_encrypt = remote_supports_decrypt = 0; 19281cb6ddcSMark Murray encrypt_mode = 0; 19381cb6ddcSMark Murray decrypt_mode = 0; 19481cb6ddcSMark Murray encrypt_output = 0; 19581cb6ddcSMark Murray decrypt_input = 0; 19681cb6ddcSMark Murray 19781cb6ddcSMark Murray str_suplen = 4; 19881cb6ddcSMark Murray 19981cb6ddcSMark Murray while (ep->type) { 20081cb6ddcSMark Murray if (encrypt_debug_mode) 20181cb6ddcSMark Murray printf(">>>%s: I will support %s\r\n", 20281cb6ddcSMark Murray Name, ENCTYPE_NAME(ep->type)); 20381cb6ddcSMark Murray i_support_encrypt |= typemask(ep->type); 20481cb6ddcSMark Murray i_support_decrypt |= typemask(ep->type); 20581cb6ddcSMark Murray if ((i_wont_support_decrypt & typemask(ep->type)) == 0) 20681cb6ddcSMark Murray if ((str_send[str_suplen++] = ep->type) == IAC) 20781cb6ddcSMark Murray str_send[str_suplen++] = IAC; 20881cb6ddcSMark Murray if (ep->init) 20981cb6ddcSMark Murray (*ep->init)(Server); 21081cb6ddcSMark Murray ++ep; 21181cb6ddcSMark Murray } 21281cb6ddcSMark Murray str_send[str_suplen++] = IAC; 21381cb6ddcSMark Murray str_send[str_suplen++] = SE; 21481cb6ddcSMark Murray } 21581cb6ddcSMark Murray 2168fa113e5SMark Murray static void 2178fa113e5SMark Murray encrypt_list_types(void) 21881cb6ddcSMark Murray { 21981cb6ddcSMark Murray Encryptions *ep = encryptions; 22081cb6ddcSMark Murray 22181cb6ddcSMark Murray printf("Valid encryption types:\n"); 22281cb6ddcSMark Murray while (ep->type) { 22381cb6ddcSMark Murray printf("\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type); 22481cb6ddcSMark Murray ++ep; 22581cb6ddcSMark Murray } 22681cb6ddcSMark Murray } 22781cb6ddcSMark Murray 22881cb6ddcSMark Murray int 2298fa113e5SMark Murray EncryptEnable(char *type, char *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 2428fa113e5SMark Murray EncryptDisable(char *type, char *mode) 24381cb6ddcSMark Murray { 2448fa113e5SMark Murray Encryptions *ep; 24581cb6ddcSMark Murray int ret = 0; 24681cb6ddcSMark Murray 24781cb6ddcSMark Murray if (isprefix(type, "help") || isprefix(type, "?")) { 24881cb6ddcSMark Murray printf("Usage: encrypt disable <type> [input|output]\n"); 24981cb6ddcSMark Murray encrypt_list_types(); 25004c426ccSMark Murray } else if ((ep = (Encryptions *)genget(type, (char **)encryptions, 25181cb6ddcSMark Murray sizeof(Encryptions))) == 0) { 25281cb6ddcSMark Murray printf("%s: invalid encryption type\n", type); 25304c426ccSMark Murray } else if (Ambiguous((char **)ep)) { 25481cb6ddcSMark Murray printf("Ambiguous type '%s'\n", type); 25581cb6ddcSMark Murray } else { 25681cb6ddcSMark Murray if ((mode == 0) || (isprefix(mode, "input") ? 1 : 0)) { 25781cb6ddcSMark Murray if (decrypt_mode == ep->type) 25881cb6ddcSMark Murray EncryptStopInput(); 25981cb6ddcSMark Murray i_wont_support_decrypt |= typemask(ep->type); 26081cb6ddcSMark Murray ret = 1; 26181cb6ddcSMark Murray } 26281cb6ddcSMark Murray if ((mode == 0) || (isprefix(mode, "output"))) { 26381cb6ddcSMark Murray if (encrypt_mode == ep->type) 26481cb6ddcSMark Murray EncryptStopOutput(); 26581cb6ddcSMark Murray i_wont_support_encrypt |= typemask(ep->type); 26681cb6ddcSMark Murray ret = 1; 26781cb6ddcSMark Murray } 26881cb6ddcSMark Murray if (ret == 0) 26981cb6ddcSMark Murray printf("%s: invalid encryption mode\n", mode); 27081cb6ddcSMark Murray } 27181cb6ddcSMark Murray return(ret); 27281cb6ddcSMark Murray } 27381cb6ddcSMark Murray 27481cb6ddcSMark Murray int 2758fa113e5SMark Murray EncryptType(char *type, char *mode) 27681cb6ddcSMark Murray { 2778fa113e5SMark Murray Encryptions *ep; 27881cb6ddcSMark Murray int ret = 0; 27981cb6ddcSMark Murray 28081cb6ddcSMark Murray if (isprefix(type, "help") || isprefix(type, "?")) { 28181cb6ddcSMark Murray printf("Usage: encrypt type <type> [input|output]\n"); 28281cb6ddcSMark Murray encrypt_list_types(); 28304c426ccSMark Murray } else if ((ep = (Encryptions *)genget(type, (char **)encryptions, 28481cb6ddcSMark Murray sizeof(Encryptions))) == 0) { 28581cb6ddcSMark Murray printf("%s: invalid encryption type\n", type); 28604c426ccSMark Murray } else if (Ambiguous((char **)ep)) { 28781cb6ddcSMark Murray printf("Ambiguous type '%s'\n", type); 28881cb6ddcSMark Murray } else { 28981cb6ddcSMark Murray if ((mode == 0) || isprefix(mode, "input")) { 29081cb6ddcSMark Murray decrypt_mode = ep->type; 29181cb6ddcSMark Murray i_wont_support_decrypt &= ~typemask(ep->type); 29281cb6ddcSMark Murray ret = 1; 29381cb6ddcSMark Murray } 29481cb6ddcSMark Murray if ((mode == 0) || isprefix(mode, "output")) { 29581cb6ddcSMark Murray encrypt_mode = ep->type; 29681cb6ddcSMark Murray i_wont_support_encrypt &= ~typemask(ep->type); 29781cb6ddcSMark Murray ret = 1; 29881cb6ddcSMark Murray } 29981cb6ddcSMark Murray if (ret == 0) 30081cb6ddcSMark Murray printf("%s: invalid encryption mode\n", mode); 30181cb6ddcSMark Murray } 30281cb6ddcSMark Murray return(ret); 30381cb6ddcSMark Murray } 30481cb6ddcSMark Murray 30581cb6ddcSMark Murray int 3068fa113e5SMark Murray EncryptStart(char *mode) 30781cb6ddcSMark Murray { 3088fa113e5SMark Murray int ret = 0; 30981cb6ddcSMark Murray if (mode) { 31081cb6ddcSMark Murray if (isprefix(mode, "input")) 31181cb6ddcSMark Murray return(EncryptStartInput()); 31281cb6ddcSMark Murray if (isprefix(mode, "output")) 31381cb6ddcSMark Murray return(EncryptStartOutput()); 31481cb6ddcSMark Murray if (isprefix(mode, "help") || isprefix(mode, "?")) { 31581cb6ddcSMark Murray printf("Usage: encrypt start [input|output]\n"); 31681cb6ddcSMark Murray return(0); 31781cb6ddcSMark Murray } 31881cb6ddcSMark Murray printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode); 31981cb6ddcSMark Murray return(0); 32081cb6ddcSMark Murray } 32181cb6ddcSMark Murray ret += EncryptStartInput(); 32281cb6ddcSMark Murray ret += EncryptStartOutput(); 32381cb6ddcSMark Murray return(ret); 32481cb6ddcSMark Murray } 32581cb6ddcSMark Murray 32681cb6ddcSMark Murray int 3278fa113e5SMark Murray EncryptStartInput(void) 32881cb6ddcSMark Murray { 32981cb6ddcSMark Murray if (decrypt_mode) { 33081cb6ddcSMark Murray encrypt_send_request_start(); 33181cb6ddcSMark Murray return(1); 33281cb6ddcSMark Murray } 33381cb6ddcSMark Murray printf("No previous decryption mode, decryption not enabled\r\n"); 33481cb6ddcSMark Murray return(0); 33581cb6ddcSMark Murray } 33681cb6ddcSMark Murray 33781cb6ddcSMark Murray int 3388fa113e5SMark Murray EncryptStartOutput(void) 33981cb6ddcSMark Murray { 34081cb6ddcSMark Murray if (encrypt_mode) { 34181cb6ddcSMark Murray encrypt_start_output(encrypt_mode); 34281cb6ddcSMark Murray return(1); 34381cb6ddcSMark Murray } 34481cb6ddcSMark Murray printf("No previous encryption mode, encryption not enabled\r\n"); 34581cb6ddcSMark Murray return(0); 34681cb6ddcSMark Murray } 34781cb6ddcSMark Murray 34881cb6ddcSMark Murray int 3498fa113e5SMark Murray EncryptStop(char *mode) 35081cb6ddcSMark Murray { 35181cb6ddcSMark Murray int ret = 0; 35281cb6ddcSMark Murray if (mode) { 35381cb6ddcSMark Murray if (isprefix(mode, "input")) 35481cb6ddcSMark Murray return(EncryptStopInput()); 35581cb6ddcSMark Murray if (isprefix(mode, "output")) 35681cb6ddcSMark Murray return(EncryptStopOutput()); 35781cb6ddcSMark Murray if (isprefix(mode, "help") || isprefix(mode, "?")) { 35881cb6ddcSMark Murray printf("Usage: encrypt stop [input|output]\n"); 35981cb6ddcSMark Murray return(0); 36081cb6ddcSMark Murray } 36181cb6ddcSMark Murray printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode); 36281cb6ddcSMark Murray return(0); 36381cb6ddcSMark Murray } 36481cb6ddcSMark Murray ret += EncryptStopInput(); 36581cb6ddcSMark Murray ret += EncryptStopOutput(); 36681cb6ddcSMark Murray return(ret); 36781cb6ddcSMark Murray } 36881cb6ddcSMark Murray 36981cb6ddcSMark Murray int 3708fa113e5SMark Murray EncryptStopInput(void) 37181cb6ddcSMark Murray { 37281cb6ddcSMark Murray encrypt_send_request_end(); 37381cb6ddcSMark Murray return(1); 37481cb6ddcSMark Murray } 37581cb6ddcSMark Murray 37681cb6ddcSMark Murray int 3778fa113e5SMark Murray EncryptStopOutput(void) 37881cb6ddcSMark Murray { 37981cb6ddcSMark Murray encrypt_send_end(); 38081cb6ddcSMark Murray return(1); 38181cb6ddcSMark Murray } 38281cb6ddcSMark Murray 38381cb6ddcSMark Murray void 3848fa113e5SMark Murray encrypt_display(void) 38581cb6ddcSMark Murray { 38681cb6ddcSMark Murray if (encrypt_output) 38781cb6ddcSMark Murray printf("Currently encrypting output with %s\r\n", 38881cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 38981cb6ddcSMark Murray if (decrypt_input) 39081cb6ddcSMark Murray printf("Currently decrypting input with %s\r\n", 39181cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 39281cb6ddcSMark Murray } 39381cb6ddcSMark Murray 39481cb6ddcSMark Murray int 3958fa113e5SMark Murray EncryptStatus(void) 39681cb6ddcSMark Murray { 39781cb6ddcSMark Murray if (encrypt_output) 39881cb6ddcSMark Murray printf("Currently encrypting output with %s\r\n", 39981cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 40081cb6ddcSMark Murray else if (encrypt_mode) { 40181cb6ddcSMark Murray printf("Currently output is clear text.\r\n"); 40281cb6ddcSMark Murray printf("Last encryption mode was %s\r\n", 40381cb6ddcSMark Murray ENCTYPE_NAME(encrypt_mode)); 40481cb6ddcSMark Murray } 40581cb6ddcSMark Murray if (decrypt_input) { 40681cb6ddcSMark Murray printf("Currently decrypting input with %s\r\n", 40781cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 40881cb6ddcSMark Murray } else if (decrypt_mode) { 40981cb6ddcSMark Murray printf("Currently input is clear text.\r\n"); 41081cb6ddcSMark Murray printf("Last decryption mode was %s\r\n", 41181cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 41281cb6ddcSMark Murray } 41381cb6ddcSMark Murray return 1; 41481cb6ddcSMark Murray } 41581cb6ddcSMark Murray 41681cb6ddcSMark Murray void 4178fa113e5SMark Murray encrypt_send_support(void) 41881cb6ddcSMark Murray { 41981cb6ddcSMark Murray if (str_suplen) { 42081cb6ddcSMark Murray /* 42181cb6ddcSMark Murray * If the user has requested that decryption start 42281cb6ddcSMark Murray * immediatly, then send a "REQUEST START" before 42381cb6ddcSMark Murray * we negotiate the type. 42481cb6ddcSMark Murray */ 42581cb6ddcSMark Murray if (!Server && autodecrypt) 42681cb6ddcSMark Murray encrypt_send_request_start(); 42781cb6ddcSMark Murray net_write(str_send, str_suplen); 42881cb6ddcSMark Murray printsub('>', &str_send[2], str_suplen - 2); 42981cb6ddcSMark Murray str_suplen = 0; 43081cb6ddcSMark Murray } 43181cb6ddcSMark Murray } 43281cb6ddcSMark Murray 43381cb6ddcSMark Murray int 4348fa113e5SMark Murray EncryptDebug(int on) 43581cb6ddcSMark Murray { 43681cb6ddcSMark Murray if (on < 0) 43781cb6ddcSMark Murray encrypt_debug_mode ^= 1; 43881cb6ddcSMark Murray else 43981cb6ddcSMark Murray encrypt_debug_mode = on; 44081cb6ddcSMark Murray printf("Encryption debugging %s\r\n", 44181cb6ddcSMark Murray encrypt_debug_mode ? "enabled" : "disabled"); 44281cb6ddcSMark Murray return(1); 44381cb6ddcSMark Murray } 44481cb6ddcSMark Murray 44581cb6ddcSMark Murray int 4468fa113e5SMark Murray EncryptVerbose(int on) 44781cb6ddcSMark Murray { 44881cb6ddcSMark Murray if (on < 0) 44981cb6ddcSMark Murray encrypt_verbose ^= 1; 45081cb6ddcSMark Murray else 45181cb6ddcSMark Murray encrypt_verbose = on; 45281cb6ddcSMark Murray printf("Encryption %s verbose\r\n", 45381cb6ddcSMark Murray encrypt_verbose ? "is" : "is not"); 45481cb6ddcSMark Murray return(1); 45581cb6ddcSMark Murray } 45681cb6ddcSMark Murray 45781cb6ddcSMark Murray int 4588fa113e5SMark Murray EncryptAutoEnc(int on) 45981cb6ddcSMark Murray { 46081cb6ddcSMark Murray encrypt_auto(on); 46181cb6ddcSMark Murray printf("Automatic encryption of output is %s\r\n", 46281cb6ddcSMark Murray autoencrypt ? "enabled" : "disabled"); 46381cb6ddcSMark Murray return(1); 46481cb6ddcSMark Murray } 46581cb6ddcSMark Murray 46681cb6ddcSMark Murray int 4678fa113e5SMark Murray EncryptAutoDec(int on) 46881cb6ddcSMark Murray { 46981cb6ddcSMark Murray decrypt_auto(on); 47081cb6ddcSMark Murray printf("Automatic decryption of input is %s\r\n", 47181cb6ddcSMark Murray autodecrypt ? "enabled" : "disabled"); 47281cb6ddcSMark Murray return(1); 47381cb6ddcSMark Murray } 47481cb6ddcSMark Murray 47581cb6ddcSMark Murray /* 47681cb6ddcSMark Murray * Called when ENCRYPT SUPPORT is received. 47781cb6ddcSMark Murray */ 47881cb6ddcSMark Murray void 4798fa113e5SMark Murray encrypt_support(unsigned char *typelist, int cnt) 48081cb6ddcSMark Murray { 4818fa113e5SMark Murray int type, use_type = 0; 48281cb6ddcSMark Murray Encryptions *ep; 48381cb6ddcSMark Murray 48481cb6ddcSMark Murray /* 48581cb6ddcSMark Murray * Forget anything the other side has previously told us. 48681cb6ddcSMark Murray */ 48781cb6ddcSMark Murray remote_supports_decrypt = 0; 48881cb6ddcSMark Murray 48981cb6ddcSMark Murray while (cnt-- > 0) { 49081cb6ddcSMark Murray type = *typelist++; 49181cb6ddcSMark Murray if (encrypt_debug_mode) 49281cb6ddcSMark Murray printf(">>>%s: He is supporting %s (%d)\r\n", 49381cb6ddcSMark Murray Name, 49481cb6ddcSMark Murray ENCTYPE_NAME(type), type); 49581cb6ddcSMark Murray if ((type < ENCTYPE_CNT) && 49681cb6ddcSMark Murray (I_SUPPORT_ENCRYPT & typemask(type))) { 49781cb6ddcSMark Murray remote_supports_decrypt |= typemask(type); 49881cb6ddcSMark Murray if (use_type == 0) 49981cb6ddcSMark Murray use_type = type; 50081cb6ddcSMark Murray } 50181cb6ddcSMark Murray } 50281cb6ddcSMark Murray if (use_type) { 50381cb6ddcSMark Murray ep = findencryption(use_type); 50481cb6ddcSMark Murray if (!ep) 50581cb6ddcSMark Murray return; 50681cb6ddcSMark Murray type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0; 50781cb6ddcSMark Murray if (encrypt_debug_mode) 50881cb6ddcSMark Murray printf(">>>%s: (*ep->start)() returned %d\r\n", 50981cb6ddcSMark Murray Name, type); 51081cb6ddcSMark Murray if (type < 0) 51181cb6ddcSMark Murray return; 51281cb6ddcSMark Murray encrypt_mode = use_type; 51381cb6ddcSMark Murray if (type == 0) 51481cb6ddcSMark Murray encrypt_start_output(use_type); 51581cb6ddcSMark Murray } 51681cb6ddcSMark Murray } 51781cb6ddcSMark Murray 51881cb6ddcSMark Murray void 5198fa113e5SMark Murray encrypt_is(unsigned char *data, int cnt) 52081cb6ddcSMark Murray { 52181cb6ddcSMark Murray Encryptions *ep; 5228fa113e5SMark Murray int type, ret; 52381cb6ddcSMark Murray 52481cb6ddcSMark Murray if (--cnt < 0) 52581cb6ddcSMark Murray return; 52681cb6ddcSMark Murray type = *data++; 52781cb6ddcSMark Murray if (type < ENCTYPE_CNT) 52881cb6ddcSMark Murray remote_supports_encrypt |= typemask(type); 52981cb6ddcSMark Murray if (!(ep = finddecryption(type))) { 53081cb6ddcSMark Murray if (encrypt_debug_mode) 53181cb6ddcSMark Murray printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 53281cb6ddcSMark Murray Name, 53381cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 53481cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 53581cb6ddcSMark Murray type); 53681cb6ddcSMark Murray return; 53781cb6ddcSMark Murray } 53881cb6ddcSMark Murray if (!ep->is) { 53981cb6ddcSMark Murray if (encrypt_debug_mode) 54081cb6ddcSMark Murray printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 54181cb6ddcSMark Murray Name, 54281cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 54381cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 54481cb6ddcSMark Murray type); 54581cb6ddcSMark Murray ret = 0; 54681cb6ddcSMark Murray } else { 54781cb6ddcSMark Murray ret = (*ep->is)(data, cnt); 54881cb6ddcSMark Murray if (encrypt_debug_mode) 54904c426ccSMark Murray printf("(*ep->is)(%p, %d) returned %s(%d)\n", data, cnt, 55081cb6ddcSMark Murray (ret < 0) ? "FAIL " : 55181cb6ddcSMark Murray (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 55281cb6ddcSMark Murray } 55381cb6ddcSMark Murray if (ret < 0) { 55481cb6ddcSMark Murray autodecrypt = 0; 55581cb6ddcSMark Murray } else { 55681cb6ddcSMark Murray decrypt_mode = type; 55781cb6ddcSMark Murray if (ret == 0 && autodecrypt) 55881cb6ddcSMark Murray encrypt_send_request_start(); 55981cb6ddcSMark Murray } 56081cb6ddcSMark Murray } 56181cb6ddcSMark Murray 56281cb6ddcSMark Murray void 5638fa113e5SMark Murray encrypt_reply(unsigned char *data, int cnt) 56481cb6ddcSMark Murray { 56581cb6ddcSMark Murray Encryptions *ep; 5668fa113e5SMark Murray int ret, type; 56781cb6ddcSMark Murray 56881cb6ddcSMark Murray if (--cnt < 0) 56981cb6ddcSMark Murray return; 57081cb6ddcSMark Murray type = *data++; 57181cb6ddcSMark Murray if (!(ep = findencryption(type))) { 57281cb6ddcSMark Murray if (encrypt_debug_mode) 57381cb6ddcSMark Murray printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 57481cb6ddcSMark Murray Name, 57581cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 57681cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 57781cb6ddcSMark Murray type); 57881cb6ddcSMark Murray return; 57981cb6ddcSMark Murray } 58081cb6ddcSMark Murray if (!ep->reply) { 58181cb6ddcSMark Murray if (encrypt_debug_mode) 58281cb6ddcSMark Murray printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 58381cb6ddcSMark Murray Name, 58481cb6ddcSMark Murray ENCTYPE_NAME_OK(type) 58581cb6ddcSMark Murray ? ENCTYPE_NAME(type) : "(unknown)", 58681cb6ddcSMark Murray type); 58781cb6ddcSMark Murray ret = 0; 58881cb6ddcSMark Murray } else { 58981cb6ddcSMark Murray ret = (*ep->reply)(data, cnt); 59081cb6ddcSMark Murray if (encrypt_debug_mode) 59104c426ccSMark Murray printf("(*ep->reply)(%p, %d) returned %s(%d)\n", 59281cb6ddcSMark Murray data, cnt, 59381cb6ddcSMark Murray (ret < 0) ? "FAIL " : 59481cb6ddcSMark Murray (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 59581cb6ddcSMark Murray } 59681cb6ddcSMark Murray if (encrypt_debug_mode) 59781cb6ddcSMark Murray printf(">>>%s: encrypt_reply returned %d\n", Name, ret); 59881cb6ddcSMark Murray if (ret < 0) { 59981cb6ddcSMark Murray autoencrypt = 0; 60081cb6ddcSMark Murray } else { 60181cb6ddcSMark Murray encrypt_mode = type; 60281cb6ddcSMark Murray if (ret == 0 && autoencrypt) 60381cb6ddcSMark Murray encrypt_start_output(type); 60481cb6ddcSMark Murray } 60581cb6ddcSMark Murray } 60681cb6ddcSMark Murray 60781cb6ddcSMark Murray /* 60881cb6ddcSMark Murray * Called when a ENCRYPT START command is received. 60981cb6ddcSMark Murray */ 61081cb6ddcSMark Murray void 6118fa113e5SMark Murray encrypt_start(unsigned char *data __unused, int cnt __unused) 61281cb6ddcSMark Murray { 61381cb6ddcSMark Murray Encryptions *ep; 61481cb6ddcSMark Murray 61581cb6ddcSMark Murray if (!decrypt_mode) { 61681cb6ddcSMark Murray /* 61781cb6ddcSMark Murray * Something is wrong. We should not get a START 61881cb6ddcSMark Murray * command without having already picked our 61981cb6ddcSMark Murray * decryption scheme. Send a REQUEST-END to 62081cb6ddcSMark Murray * attempt to clear the channel... 62181cb6ddcSMark Murray */ 62281cb6ddcSMark Murray printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name); 62381cb6ddcSMark Murray encrypt_send_request_end(); 62481cb6ddcSMark Murray return; 62581cb6ddcSMark Murray } 62681cb6ddcSMark Murray 62704c426ccSMark Murray if ((ep = finddecryption(decrypt_mode))) { 62881cb6ddcSMark Murray decrypt_input = ep->input; 62981cb6ddcSMark Murray if (encrypt_verbose) 63081cb6ddcSMark Murray printf("[ Input is now decrypted with type %s ]\r\n", 63181cb6ddcSMark Murray ENCTYPE_NAME(decrypt_mode)); 63281cb6ddcSMark Murray if (encrypt_debug_mode) 63381cb6ddcSMark Murray printf(">>>%s: Start to decrypt input with type %s\r\n", 63481cb6ddcSMark Murray Name, ENCTYPE_NAME(decrypt_mode)); 63581cb6ddcSMark Murray } else { 63681cb6ddcSMark Murray printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n", 63781cb6ddcSMark Murray Name, 63881cb6ddcSMark Murray ENCTYPE_NAME_OK(decrypt_mode) 63981cb6ddcSMark Murray ? ENCTYPE_NAME(decrypt_mode) 64081cb6ddcSMark Murray : "(unknown)", 64181cb6ddcSMark Murray decrypt_mode); 64281cb6ddcSMark Murray encrypt_send_request_end(); 64381cb6ddcSMark Murray } 64481cb6ddcSMark Murray } 64581cb6ddcSMark Murray 64681cb6ddcSMark Murray void 6478fa113e5SMark Murray encrypt_session_key( Session_Key *key, int server) 64881cb6ddcSMark Murray { 64981cb6ddcSMark Murray Encryptions *ep = encryptions; 65081cb6ddcSMark Murray 65181cb6ddcSMark Murray havesessionkey = 1; 65281cb6ddcSMark Murray 65381cb6ddcSMark Murray while (ep->type) { 65481cb6ddcSMark Murray if (ep->session) 65581cb6ddcSMark Murray (*ep->session)(key, server); 65681cb6ddcSMark Murray ++ep; 65781cb6ddcSMark Murray } 65881cb6ddcSMark Murray } 65981cb6ddcSMark Murray 66081cb6ddcSMark Murray /* 66181cb6ddcSMark Murray * Called when ENCRYPT END is received. 66281cb6ddcSMark Murray */ 66381cb6ddcSMark Murray void 6648fa113e5SMark Murray encrypt_end(void) 66581cb6ddcSMark Murray { 66681cb6ddcSMark Murray decrypt_input = 0; 66781cb6ddcSMark Murray if (encrypt_debug_mode) 66881cb6ddcSMark Murray printf(">>>%s: Input is back to clear text\r\n", Name); 66981cb6ddcSMark Murray if (encrypt_verbose) 67081cb6ddcSMark Murray printf("[ Input is now clear text ]\r\n"); 67181cb6ddcSMark Murray } 67281cb6ddcSMark Murray 67381cb6ddcSMark Murray /* 67481cb6ddcSMark Murray * Called when ENCRYPT REQUEST-END is received. 67581cb6ddcSMark Murray */ 67681cb6ddcSMark Murray void 6778fa113e5SMark Murray encrypt_request_end(void) 67881cb6ddcSMark Murray { 67981cb6ddcSMark Murray encrypt_send_end(); 68081cb6ddcSMark Murray } 68181cb6ddcSMark Murray 68281cb6ddcSMark Murray /* 68381cb6ddcSMark Murray * Called when ENCRYPT REQUEST-START is received. If we receive 68481cb6ddcSMark Murray * this before a type is picked, then that indicates that the 68581cb6ddcSMark Murray * other side wants us to start encrypting data as soon as we 68681cb6ddcSMark Murray * can. 68781cb6ddcSMark Murray */ 68881cb6ddcSMark Murray void 6898fa113e5SMark Murray encrypt_request_start(unsigned char *data __unused, int cnt __unused) 69081cb6ddcSMark Murray { 69181cb6ddcSMark Murray if (encrypt_mode == 0) { 69281cb6ddcSMark Murray if (Server) 69381cb6ddcSMark Murray autoencrypt = 1; 69481cb6ddcSMark Murray return; 69581cb6ddcSMark Murray } 69681cb6ddcSMark Murray encrypt_start_output(encrypt_mode); 69781cb6ddcSMark Murray } 69881cb6ddcSMark Murray 69981cb6ddcSMark Murray static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT }; 70081cb6ddcSMark Murray 70104c426ccSMark Murray void 7028fa113e5SMark Murray encrypt_enc_keyid(unsigned char *keyid, int len) 70381cb6ddcSMark Murray { 70481cb6ddcSMark Murray encrypt_keyid(&ki[1], keyid, len); 70581cb6ddcSMark Murray } 70681cb6ddcSMark Murray 70704c426ccSMark Murray void 7088fa113e5SMark Murray encrypt_dec_keyid(unsigned char *keyid, int len) 70981cb6ddcSMark Murray { 71081cb6ddcSMark Murray encrypt_keyid(&ki[0], keyid, len); 71181cb6ddcSMark Murray } 71281cb6ddcSMark Murray 71304c426ccSMark Murray void 7148fa113e5SMark Murray encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len) 71581cb6ddcSMark Murray { 71681cb6ddcSMark Murray Encryptions *ep; 71781cb6ddcSMark Murray int dir = kp->dir; 7188fa113e5SMark Murray int ret = 0; 71981cb6ddcSMark Murray 7203e65b9c6SColin Percival if (len > MAXKEYLEN) 7213e65b9c6SColin Percival len = MAXKEYLEN; 7223e65b9c6SColin Percival 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