1*46801Sdab /*- 2*46801Sdab * Copyright (c) 1991 The Regents of the University of California. 3*46801Sdab * All rights reserved. 4*46801Sdab * 5*46801Sdab * %sccs.include.redist.c% 6*46801Sdab */ 7*46801Sdab 8*46801Sdab #ifndef lint 9*46801Sdab static char sccsid[] = "@(#)encrypt.c 5.1 (Berkeley) 02/28/91"; 10*46801Sdab #endif /* not lint */ 11*46801Sdab 12*46801Sdab /* 13*46801Sdab * Copyright (C) 1990 by the Massachusetts Institute of Technology 14*46801Sdab * 15*46801Sdab * Export of this software from the United States of America is assumed 16*46801Sdab * to require a specific license from the United States Government. 17*46801Sdab * It is the responsibility of any person or organization contemplating 18*46801Sdab * export to obtain such a license before exporting. 19*46801Sdab * 20*46801Sdab * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 21*46801Sdab * distribute this software and its documentation for any purpose and 22*46801Sdab * without fee is hereby granted, provided that the above copyright 23*46801Sdab * notice appear in all copies and that both that copyright notice and 24*46801Sdab * this permission notice appear in supporting documentation, and that 25*46801Sdab * the name of M.I.T. not be used in advertising or publicity pertaining 26*46801Sdab * to distribution of the software without specific, written prior 27*46801Sdab * permission. M.I.T. makes no representations about the suitability of 28*46801Sdab * this software for any purpose. It is provided "as is" without express 29*46801Sdab * or implied warranty. 30*46801Sdab */ 31*46801Sdab 32*46801Sdab #if defined(ENCRYPT) 33*46801Sdab 34*46801Sdab #define ENCRYPT_NAMES 35*46801Sdab #include <arpa/telnet.h> 36*46801Sdab 37*46801Sdab #include "encrypt.h" 38*46801Sdab #include "misc.h" 39*46801Sdab 40*46801Sdab #ifdef __STDC__ 41*46801Sdab #include <stdlib.h> 42*46801Sdab #endif 43*46801Sdab #ifdef NO_STRING_H 44*46801Sdab #include <strings.h> 45*46801Sdab #else 46*46801Sdab #include <string.h> 47*46801Sdab #endif 48*46801Sdab 49*46801Sdab /* 50*46801Sdab * These functions pointers point to the current routines 51*46801Sdab * for encrypting and decrypting data. 52*46801Sdab */ 53*46801Sdab void (*encrypt_output) P((unsigned char *, int)); 54*46801Sdab int (*decrypt_input) P((int)); 55*46801Sdab 56*46801Sdab int encrypt_debug_mode = 0; 57*46801Sdab static int decrypt_mode = 0; 58*46801Sdab static int encrypt_mode = 0; 59*46801Sdab static int encrypt_verbose = 0; 60*46801Sdab static int autoencrypt = 0; 61*46801Sdab static int autodecrypt = 0; 62*46801Sdab static int havesessionkey = 0; 63*46801Sdab static int encrypt_mark = 0; 64*46801Sdab static int decrypt_mark = 0; 65*46801Sdab static int Server = 0; 66*46801Sdab static char *Name = "Noname"; 67*46801Sdab 68*46801Sdab #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 69*46801Sdab 70*46801Sdab static long i_support_encrypt = typemask(ENCTYPE_KRBDES); 71*46801Sdab static long i_support_decrypt = typemask(ENCTYPE_KRBDES); 72*46801Sdab static long remote_supports_encrypt = 0; 73*46801Sdab static long remote_supports_decrypt = 0; 74*46801Sdab 75*46801Sdab static Encryptions encryptions[] = { 76*46801Sdab #if defined(KRBDES_ENCRYPT) 77*46801Sdab { "KRBDES", ENCTYPE_KRBDES, 78*46801Sdab krbdes_encrypt, 79*46801Sdab krbdes_decrypt, 80*46801Sdab krbdes_init, 81*46801Sdab krbdes_start, 82*46801Sdab krbdes_is, 83*46801Sdab krbdes_reply, 84*46801Sdab krbdes_session, 85*46801Sdab krbdes_printsub }, 86*46801Sdab #endif 87*46801Sdab { 0, }, 88*46801Sdab }; 89*46801Sdab 90*46801Sdab static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, 91*46801Sdab ENCRYPT_SUPPORT, }; 92*46801Sdab static unsigned char str_suplen = 0; 93*46801Sdab static unsigned char str_start[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; 94*46801Sdab static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; 95*46801Sdab 96*46801Sdab Encryptions * 97*46801Sdab findencryption(type) 98*46801Sdab int type; 99*46801Sdab { 100*46801Sdab Encryptions *ep = encryptions; 101*46801Sdab 102*46801Sdab if (!(i_support_encrypt & remote_supports_decrypt & typemask(type))) 103*46801Sdab return(0); 104*46801Sdab while (ep->type && ep->type != type) 105*46801Sdab ++ep; 106*46801Sdab return(ep->type ? ep : 0); 107*46801Sdab } 108*46801Sdab 109*46801Sdab Encryptions * 110*46801Sdab finddecryption(type) 111*46801Sdab int type; 112*46801Sdab { 113*46801Sdab Encryptions *ep = encryptions; 114*46801Sdab 115*46801Sdab if (!(i_support_decrypt & remote_supports_encrypt & typemask(type))) 116*46801Sdab return(0); 117*46801Sdab while (ep->type && ep->type != type) 118*46801Sdab ++ep; 119*46801Sdab return(ep->type ? ep : 0); 120*46801Sdab } 121*46801Sdab 122*46801Sdab void 123*46801Sdab encrypt_init(name, server) 124*46801Sdab char *name; 125*46801Sdab int server; 126*46801Sdab { 127*46801Sdab Encryptions *ep = encryptions; 128*46801Sdab 129*46801Sdab Name = name; 130*46801Sdab Server = server; 131*46801Sdab i_support_encrypt = i_support_decrypt = 0; 132*46801Sdab remote_supports_encrypt = remote_supports_decrypt = 0; 133*46801Sdab encrypt_mode = 0; 134*46801Sdab decrypt_mode = 0; 135*46801Sdab encrypt_output = 0; 136*46801Sdab decrypt_input = 0; 137*46801Sdab #ifdef notdef 138*46801Sdab encrypt_verbose = !server; 139*46801Sdab #endif 140*46801Sdab 141*46801Sdab str_suplen = 4; 142*46801Sdab 143*46801Sdab while (ep->type) { 144*46801Sdab if (encrypt_debug_mode) 145*46801Sdab printf(">>>%s: I will support %s\r\n", 146*46801Sdab Name, ENCTYPE_NAME(ep->type)); 147*46801Sdab i_support_encrypt |= typemask(ep->type); 148*46801Sdab i_support_decrypt |= typemask(ep->type); 149*46801Sdab if ((str_send[str_suplen++] = ep->type) == IAC) 150*46801Sdab str_send[str_suplen++] = IAC; 151*46801Sdab if (ep->init) 152*46801Sdab (*ep->init)(Server); 153*46801Sdab ++ep; 154*46801Sdab } 155*46801Sdab str_send[str_suplen++] = IAC; 156*46801Sdab str_send[str_suplen++] = SE; 157*46801Sdab } 158*46801Sdab 159*46801Sdab void 160*46801Sdab encrypt_list_types() 161*46801Sdab { 162*46801Sdab Encryptions *ep = encryptions; 163*46801Sdab 164*46801Sdab printf("Valid encryption types:\n"); 165*46801Sdab while (ep->type) { 166*46801Sdab printf("\t%s\n\n", ENCTYPE_NAME(ep->type)); 167*46801Sdab ++ep; 168*46801Sdab } 169*46801Sdab } 170*46801Sdab 171*46801Sdab int 172*46801Sdab EncryptEnable(type, mode) 173*46801Sdab char *type, *mode; 174*46801Sdab { 175*46801Sdab if (isprefix(type, "help") || isprefix(type, "?")) { 176*46801Sdab printf("Usage: encrypt enable <type> [input|output]\n"); 177*46801Sdab encrypt_list_types(); 178*46801Sdab return(0); 179*46801Sdab } 180*46801Sdab if (EncryptType(type, mode)) 181*46801Sdab return(EncryptStart(mode)); 182*46801Sdab return(0); 183*46801Sdab } 184*46801Sdab 185*46801Sdab int 186*46801Sdab EncryptType(type, mode) 187*46801Sdab char *type; 188*46801Sdab char *mode; 189*46801Sdab { 190*46801Sdab register Encryptions *ep; 191*46801Sdab 192*46801Sdab if (isprefix(type, "help") || isprefix(type, "?")) { 193*46801Sdab printf("Usage: encrypt type <type> [input|output]\n"); 194*46801Sdab encrypt_list_types(); 195*46801Sdab return(0); 196*46801Sdab } 197*46801Sdab 198*46801Sdab ep = (Encryptions *)genget(type, encryptions, sizeof(Encryptions)); 199*46801Sdab 200*46801Sdab if (ep == 0) { 201*46801Sdab printf("%s: invalid encryption type\n", type); 202*46801Sdab return(0); 203*46801Sdab } 204*46801Sdab if (Ambiguous(ep)) { 205*46801Sdab printf("Ambiguous type '%s'\n", type); 206*46801Sdab return(0); 207*46801Sdab } 208*46801Sdab 209*46801Sdab if (mode) { 210*46801Sdab if (isprefix(mode, "input")) 211*46801Sdab decrypt_mode = ep->type; 212*46801Sdab else if (isprefix(mode, "output")) 213*46801Sdab encrypt_mode = ep->type; 214*46801Sdab else { 215*46801Sdab printf("%s: invalid encryption mode\n", mode); 216*46801Sdab return(0); 217*46801Sdab } 218*46801Sdab } else 219*46801Sdab decrypt_mode = encrypt_mode = ep->type; 220*46801Sdab return(1); 221*46801Sdab } 222*46801Sdab 223*46801Sdab int 224*46801Sdab EncryptStart(mode) 225*46801Sdab char *mode; 226*46801Sdab { 227*46801Sdab register int ret = 0; 228*46801Sdab if (mode) { 229*46801Sdab if (isprefix(mode, "input")) 230*46801Sdab return(EncryptStartInput()); 231*46801Sdab if (isprefix(mode, "output")) 232*46801Sdab return(EncryptStartOutput()); 233*46801Sdab if (isprefix(mode, "help") || isprefix(mode, "?")) { 234*46801Sdab printf("Usage: encrypt start [input|output]\n"); 235*46801Sdab return(0); 236*46801Sdab } 237*46801Sdab printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode); 238*46801Sdab return(0); 239*46801Sdab } 240*46801Sdab ret += EncryptStartInput(); 241*46801Sdab ret += EncryptStartOutput(); 242*46801Sdab return(ret); 243*46801Sdab } 244*46801Sdab 245*46801Sdab int 246*46801Sdab EncryptStartInput() 247*46801Sdab { 248*46801Sdab if (decrypt_mode) { 249*46801Sdab encrypt_send_request_start(); 250*46801Sdab return(1); 251*46801Sdab } 252*46801Sdab printf("No previous decryption mode, decryption not enabled\r\n"); 253*46801Sdab return(0); 254*46801Sdab } 255*46801Sdab 256*46801Sdab int 257*46801Sdab EncryptStartOutput() 258*46801Sdab { 259*46801Sdab if (encrypt_mode) { 260*46801Sdab encrypt_start_output(encrypt_mode); 261*46801Sdab return(1); 262*46801Sdab } 263*46801Sdab printf("No previous encryption mode, encryption not enabled\r\n"); 264*46801Sdab return(0); 265*46801Sdab } 266*46801Sdab 267*46801Sdab int 268*46801Sdab EncryptStop(mode) 269*46801Sdab char *mode; 270*46801Sdab { 271*46801Sdab int ret = 0; 272*46801Sdab if (mode) { 273*46801Sdab if (isprefix(mode, "input")) 274*46801Sdab return(EncryptStopInput()); 275*46801Sdab if (isprefix(mode, "output")) 276*46801Sdab return(EncryptStopOutput()); 277*46801Sdab if (isprefix(mode, "help") || isprefix(mode, "?")) { 278*46801Sdab printf("Usage: encrypt stop [input|output]\n"); 279*46801Sdab return(0); 280*46801Sdab } 281*46801Sdab printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode); 282*46801Sdab return(0); 283*46801Sdab } 284*46801Sdab ret += EncryptStopInput(); 285*46801Sdab ret += EncryptStopOutput(); 286*46801Sdab return(ret); 287*46801Sdab } 288*46801Sdab 289*46801Sdab int 290*46801Sdab EncryptStopInput() 291*46801Sdab { 292*46801Sdab encrypt_send_request_end(); 293*46801Sdab return(1); 294*46801Sdab } 295*46801Sdab 296*46801Sdab int 297*46801Sdab EncryptStopOutput() 298*46801Sdab { 299*46801Sdab encrypt_send_end(); 300*46801Sdab return(1); 301*46801Sdab } 302*46801Sdab 303*46801Sdab void 304*46801Sdab encrypt_display() 305*46801Sdab { 306*46801Sdab if (encrypt_output) 307*46801Sdab printf("Currently encrypting output with %s\r\n", 308*46801Sdab ENCTYPE_NAME(encrypt_mode)); 309*46801Sdab if (decrypt_input) 310*46801Sdab printf("Currently decrypting input with %s\r\n", 311*46801Sdab ENCTYPE_NAME(decrypt_mode)); 312*46801Sdab } 313*46801Sdab 314*46801Sdab int 315*46801Sdab EncryptStatus() 316*46801Sdab { 317*46801Sdab if (encrypt_output) 318*46801Sdab printf("Currently encrypting output with %s\r\n", 319*46801Sdab ENCTYPE_NAME(encrypt_mode)); 320*46801Sdab else if (encrypt_mode) { 321*46801Sdab printf("Currently output is clear text.\r\n"); 322*46801Sdab printf("Last encryption mode was %s\r\n", 323*46801Sdab ENCTYPE_NAME(encrypt_mode)); 324*46801Sdab } 325*46801Sdab if (decrypt_input) { 326*46801Sdab printf("Currently decrypting input with %s\r\n", 327*46801Sdab ENCTYPE_NAME(decrypt_mode)); 328*46801Sdab } else if (decrypt_mode) { 329*46801Sdab printf("Currently input is clear text.\r\n"); 330*46801Sdab printf("Last decryption mode was %s\r\n", 331*46801Sdab ENCTYPE_NAME(decrypt_mode)); 332*46801Sdab } 333*46801Sdab return 1; 334*46801Sdab } 335*46801Sdab 336*46801Sdab void 337*46801Sdab encrypt_send_support() 338*46801Sdab { 339*46801Sdab if (str_suplen) { 340*46801Sdab /* 341*46801Sdab * If the user has requested that decryption start 342*46801Sdab * immediatly, then send a "REQUEST START" before 343*46801Sdab * we negotiate the type. 344*46801Sdab */ 345*46801Sdab if (!Server && autodecrypt) 346*46801Sdab encrypt_send_request_start(); 347*46801Sdab net_write(str_send, str_suplen); 348*46801Sdab printsub('>', &str_send[2], str_suplen - 2); 349*46801Sdab str_suplen = 0; 350*46801Sdab } 351*46801Sdab } 352*46801Sdab 353*46801Sdab int 354*46801Sdab EncryptTogDebug() 355*46801Sdab { 356*46801Sdab encrypt_debug_mode ^= 1; 357*46801Sdab printf("Encryption debugging %s\r\n", 358*46801Sdab encrypt_debug_mode ? "enabled" : "disabled"); 359*46801Sdab return(1); 360*46801Sdab } 361*46801Sdab 362*46801Sdab int 363*46801Sdab EncryptTogVerbose() 364*46801Sdab { 365*46801Sdab encrypt_verbose ^= 1; 366*46801Sdab printf("Encryption %s verbose\r\n", 367*46801Sdab encrypt_verbose ? "is" : "is not"); 368*46801Sdab return(1); 369*46801Sdab } 370*46801Sdab 371*46801Sdab int 372*46801Sdab EncryptTogAuto() 373*46801Sdab { 374*46801Sdab autoencrypt ^= 1; 375*46801Sdab autodecrypt ^= 1; 376*46801Sdab printf("Automatic encryption of data is %s\r\n", 377*46801Sdab autoencrypt ? "enabled" : "disabled"); 378*46801Sdab return(1); 379*46801Sdab } 380*46801Sdab 381*46801Sdab 382*46801Sdab /* 383*46801Sdab * Called when ENCRYPT SUPPORT is received. 384*46801Sdab */ 385*46801Sdab void 386*46801Sdab encrypt_support(typelist, cnt) 387*46801Sdab unsigned char *typelist; 388*46801Sdab int cnt; 389*46801Sdab { 390*46801Sdab register int type, use_type = 0; 391*46801Sdab Encryptions *ep; 392*46801Sdab 393*46801Sdab /* 394*46801Sdab * Forget anything the other side has previously told us. 395*46801Sdab */ 396*46801Sdab remote_supports_decrypt = 0; 397*46801Sdab 398*46801Sdab while (cnt-- > 0) { 399*46801Sdab type = *typelist++; 400*46801Sdab if (encrypt_debug_mode) 401*46801Sdab printf(">>>%s: He is supporting %s (%d)\r\n", 402*46801Sdab Name, 403*46801Sdab ENCTYPE_NAME(type), type); 404*46801Sdab if ((type < ENCTYPE_CNT) && 405*46801Sdab (i_support_encrypt & typemask(type))) { 406*46801Sdab remote_supports_decrypt |= typemask(type); 407*46801Sdab if (use_type == 0) 408*46801Sdab use_type = type; 409*46801Sdab } 410*46801Sdab } 411*46801Sdab if (use_type) { 412*46801Sdab ep = findencryption(use_type); 413*46801Sdab if (!ep) 414*46801Sdab return; 415*46801Sdab type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0; 416*46801Sdab if (encrypt_debug_mode) 417*46801Sdab printf(">>>%s: (*ep->start)() returned %d\r\n", 418*46801Sdab Name, type); 419*46801Sdab if (type < 0) 420*46801Sdab return; 421*46801Sdab encrypt_mode = type; 422*46801Sdab if (type == 0) 423*46801Sdab encrypt_start_output(use_type); 424*46801Sdab } 425*46801Sdab } 426*46801Sdab 427*46801Sdab void 428*46801Sdab encrypt_is(data, cnt) 429*46801Sdab unsigned char *data; 430*46801Sdab int cnt; 431*46801Sdab { 432*46801Sdab Encryptions *ep; 433*46801Sdab register int type, ret; 434*46801Sdab 435*46801Sdab if (--cnt < 0) 436*46801Sdab return; 437*46801Sdab type = *data++; 438*46801Sdab if (type < ENCTYPE_CNT) 439*46801Sdab remote_supports_encrypt |= typemask(type); 440*46801Sdab if (!(ep = finddecryption(type))) { 441*46801Sdab if (encrypt_debug_mode) 442*46801Sdab printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 443*46801Sdab Name, 444*46801Sdab ENCTYPE_NAME(data[-1]), data[1]); 445*46801Sdab return; 446*46801Sdab } 447*46801Sdab if (!ep->is) { 448*46801Sdab if (encrypt_debug_mode) 449*46801Sdab printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 450*46801Sdab Name, 451*46801Sdab ENCTYPE_NAME(type), type); 452*46801Sdab ret = 0; 453*46801Sdab } else { 454*46801Sdab ret = (*ep->is)(data, cnt); 455*46801Sdab /*@*/ if (encrypt_debug_mode) 456*46801Sdab /*@*/ printf("(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt, 457*46801Sdab /*@*/ (ret < 0) ? "FAIL " : 458*46801Sdab /*@*/ (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 459*46801Sdab } 460*46801Sdab if (ret < 0) { 461*46801Sdab autodecrypt = 0; 462*46801Sdab } else { 463*46801Sdab decrypt_mode = type; 464*46801Sdab if (ret == 0 && autodecrypt) 465*46801Sdab encrypt_send_request_start(); 466*46801Sdab } 467*46801Sdab } 468*46801Sdab 469*46801Sdab void 470*46801Sdab encrypt_reply(data, cnt) 471*46801Sdab unsigned char *data; 472*46801Sdab int cnt; 473*46801Sdab { 474*46801Sdab Encryptions *ep; 475*46801Sdab register int ret, type; 476*46801Sdab 477*46801Sdab if (--cnt < 0) 478*46801Sdab return; 479*46801Sdab type = *data++; 480*46801Sdab if (!(ep = findencryption(type))) { 481*46801Sdab if (encrypt_debug_mode) 482*46801Sdab printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", 483*46801Sdab Name, 484*46801Sdab ENCTYPE_NAME(data[-1]), data[1]); 485*46801Sdab return; 486*46801Sdab } 487*46801Sdab if (!ep->reply) { 488*46801Sdab if (encrypt_debug_mode) 489*46801Sdab printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", 490*46801Sdab Name, 491*46801Sdab ENCTYPE_NAME(data[-1]), data[1]); 492*46801Sdab ret = 0; 493*46801Sdab } else { 494*46801Sdab ret = (*ep->reply)(data, cnt); 495*46801Sdab /*@*/ if (encrypt_debug_mode) 496*46801Sdab /*@*/ printf("(*ep->reply)(%x, %d) returned %s(%d)\n", 497*46801Sdab /*@*/ data, cnt, 498*46801Sdab /*@*/ (ret < 0) ? "FAIL " : 499*46801Sdab /*@*/ (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); 500*46801Sdab } 501*46801Sdab if (encrypt_debug_mode) 502*46801Sdab printf(">>>%s: encrypt_reply returned %d\n", Name, ret); 503*46801Sdab if (ret < 0) { 504*46801Sdab autoencrypt = 0; 505*46801Sdab } else { 506*46801Sdab encrypt_mode = type; 507*46801Sdab if (ret == 0 && autoencrypt) 508*46801Sdab encrypt_start_output(type); 509*46801Sdab } 510*46801Sdab } 511*46801Sdab 512*46801Sdab /* 513*46801Sdab * Called when a ENCRYPT START command is received. 514*46801Sdab */ 515*46801Sdab void 516*46801Sdab encrypt_start() 517*46801Sdab { 518*46801Sdab Encryptions *ep; 519*46801Sdab 520*46801Sdab if (!decrypt_mode) { 521*46801Sdab /* 522*46801Sdab * Something is wrong. We should not get a START 523*46801Sdab * command without having already picked our 524*46801Sdab * decryption scheme. Send a REQUEST-END to 525*46801Sdab * attempt to clear the channel... 526*46801Sdab */ 527*46801Sdab printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name); 528*46801Sdab encrypt_send_request_end(); 529*46801Sdab return; 530*46801Sdab } 531*46801Sdab 532*46801Sdab if (ep = finddecryption(decrypt_mode)) { 533*46801Sdab decrypt_input = ep->input; 534*46801Sdab if (encrypt_verbose) 535*46801Sdab printf("[ Input is now decrypted with type %s ]\r\n", 536*46801Sdab ENCTYPE_NAME(decrypt_mode)); 537*46801Sdab if (encrypt_debug_mode) 538*46801Sdab printf(">>>%s: Start to decrypt input with type %s\r\n", 539*46801Sdab Name, ENCTYPE_NAME(decrypt_mode)); 540*46801Sdab } else { 541*46801Sdab printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n", 542*46801Sdab Name, ENCTYPE_NAME(decrypt_mode), decrypt_mode); 543*46801Sdab encrypt_send_request_end(); 544*46801Sdab } 545*46801Sdab } 546*46801Sdab 547*46801Sdab void 548*46801Sdab encrypt_session_key(key, server) 549*46801Sdab Session_Key *key; 550*46801Sdab int server; 551*46801Sdab { 552*46801Sdab Encryptions *ep = encryptions; 553*46801Sdab 554*46801Sdab havesessionkey = 1; 555*46801Sdab 556*46801Sdab while (ep->type) { 557*46801Sdab if (ep->session) 558*46801Sdab (*ep->session)(key, server); 559*46801Sdab if (!encrypt_output && autoencrypt && !server) 560*46801Sdab encrypt_start_output(ep->type); 561*46801Sdab if (!decrypt_input && autodecrypt && !server) 562*46801Sdab encrypt_send_request_start(); 563*46801Sdab ++ep; 564*46801Sdab } 565*46801Sdab } 566*46801Sdab 567*46801Sdab /* 568*46801Sdab * Called when ENCRYPT END is received. 569*46801Sdab */ 570*46801Sdab void 571*46801Sdab encrypt_end() 572*46801Sdab { 573*46801Sdab decrypt_input = 0; 574*46801Sdab if (encrypt_debug_mode) 575*46801Sdab printf(">>>%s: Input is back to clear text\r\n", Name); 576*46801Sdab if (encrypt_verbose) 577*46801Sdab printf("[ Input is now clear text ]\r\n"); 578*46801Sdab } 579*46801Sdab 580*46801Sdab /* 581*46801Sdab * Called when ENCRYPT REQUEST-END is received. 582*46801Sdab */ 583*46801Sdab void 584*46801Sdab encrypt_request_end() 585*46801Sdab { 586*46801Sdab encrypt_send_end(); 587*46801Sdab } 588*46801Sdab 589*46801Sdab /* 590*46801Sdab * Called when ENCRYPT REQUEST-START is received. If we receive 591*46801Sdab * this before a type is picked, then that indicates that the 592*46801Sdab * other side wants us to start encrypting data as soon as we 593*46801Sdab * can. 594*46801Sdab */ 595*46801Sdab void 596*46801Sdab encrypt_request_start() 597*46801Sdab { 598*46801Sdab if (!encrypt_mode && Server) { 599*46801Sdab autoencrypt = 1; 600*46801Sdab return; 601*46801Sdab } 602*46801Sdab encrypt_start_output(encrypt_mode); 603*46801Sdab } 604*46801Sdab 605*46801Sdab void 606*46801Sdab encrypt_auto() 607*46801Sdab { 608*46801Sdab autoencrypt = 1; 609*46801Sdab autodecrypt = 1; 610*46801Sdab } 611*46801Sdab 612*46801Sdab void 613*46801Sdab encrypt_start_output(type) 614*46801Sdab int type; 615*46801Sdab { 616*46801Sdab Encryptions *ep; 617*46801Sdab register int ret; 618*46801Sdab 619*46801Sdab if (!(ep = findencryption(type))) { 620*46801Sdab if (encrypt_debug_mode) { 621*46801Sdab printf(">>>%s: Marking type %s for later encryption use\r\n", 622*46801Sdab Name, 623*46801Sdab ENCTYPE_NAME(type)); 624*46801Sdab } 625*46801Sdab encrypt_mark |= typemask(type); 626*46801Sdab return; 627*46801Sdab } 628*46801Sdab if (ep->start) { 629*46801Sdab ret = (*ep->start)(DIR_ENCRYPT, Server); 630*46801Sdab if (ret) { 631*46801Sdab if (encrypt_debug_mode) { 632*46801Sdab if (ret < 0) 633*46801Sdab printf(">>>%s: Start failed for %s\r\n", 634*46801Sdab Name, ENCTYPE_NAME(type)); 635*46801Sdab else 636*46801Sdab printf(">>>%s: Start: initial negotiation in progress%s\r\n", 637*46801Sdab Name, ENCTYPE_NAME(type)); 638*46801Sdab } 639*46801Sdab 640*46801Sdab return; 641*46801Sdab } 642*46801Sdab } 643*46801Sdab str_start[3] = ENCRYPT_START; 644*46801Sdab net_write(str_start, sizeof(str_start)); 645*46801Sdab net_encrypt(); 646*46801Sdab printsub('>', &str_start[2], sizeof(str_start) - 2); 647*46801Sdab /* 648*46801Sdab * If we are already encrypting in some mode, then 649*46801Sdab * encrypt the ring (which includes our request) in 650*46801Sdab * the old mode, mark it all as "clear text" and then 651*46801Sdab * switch to the new mode. 652*46801Sdab */ 653*46801Sdab encrypt_output = ep->output; 654*46801Sdab encrypt_mode = type; 655*46801Sdab if (encrypt_debug_mode) 656*46801Sdab printf(">>>%s: Started to encrypt output with type %s\r\n", 657*46801Sdab Name, ENCTYPE_NAME(type)); 658*46801Sdab if (encrypt_verbose) 659*46801Sdab printf("[ Output is now encrypted with type %s ]\r\n", 660*46801Sdab ENCTYPE_NAME(type)); 661*46801Sdab } 662*46801Sdab 663*46801Sdab void 664*46801Sdab encrypt_send_end() 665*46801Sdab { 666*46801Sdab if (!encrypt_output) 667*46801Sdab return; 668*46801Sdab 669*46801Sdab str_end[3] = ENCRYPT_END; 670*46801Sdab net_write(str_end, sizeof(str_end)); 671*46801Sdab net_encrypt(); 672*46801Sdab printsub('>', &str_end[2], sizeof(str_end) - 2); 673*46801Sdab /* 674*46801Sdab * Encrypt the output buffer now because it will not be done by 675*46801Sdab * netflush... 676*46801Sdab */ 677*46801Sdab encrypt_output = 0; 678*46801Sdab if (encrypt_debug_mode) 679*46801Sdab printf(">>>%s: Output is back to clear text\r\n", Name); 680*46801Sdab if (encrypt_verbose) 681*46801Sdab printf("[ Output is now clear text ]\r\n"); 682*46801Sdab } 683*46801Sdab 684*46801Sdab void 685*46801Sdab encrypt_send_request_start() 686*46801Sdab { 687*46801Sdab #ifdef notdef 688*46801Sdab Encryptions *ep; 689*46801Sdab 690*46801Sdab if (!(ep = findencryption(type))) { 691*46801Sdab if (encrypt_debug_mode) { 692*46801Sdab printf(">>>%s: Marking type %s for later decryption use\r\n", 693*46801Sdab Name, 694*46801Sdab ENCTYPE_NAME(type)); 695*46801Sdab } 696*46801Sdab decrypt_mark |= typemask(type); 697*46801Sdab return; 698*46801Sdab } 699*46801Sdab 700*46801Sdab if (ep->start && (*ep->start)(DIR_DECRYPT, Server)) { 701*46801Sdab if (encrypt_debug_mode) { 702*46801Sdab printf(">>>%s: Request failed for %s\r\n", 703*46801Sdab Name, 704*46801Sdab ENCTYPE_NAME(type)); 705*46801Sdab } 706*46801Sdab return; 707*46801Sdab } 708*46801Sdab #endif 709*46801Sdab 710*46801Sdab str_start[3] = ENCRYPT_REQSTART; 711*46801Sdab net_write(str_start, sizeof(str_start)); 712*46801Sdab printsub('>', &str_start[2], sizeof(str_start) - 2); 713*46801Sdab if (encrypt_debug_mode) 714*46801Sdab printf(">>>%s: Request input to be encrypted\r\n", Name); 715*46801Sdab } 716*46801Sdab 717*46801Sdab void 718*46801Sdab encrypt_send_request_end() 719*46801Sdab { 720*46801Sdab str_end[3] = ENCRYPT_REQEND; 721*46801Sdab net_write(str_end, sizeof(str_end)); 722*46801Sdab printsub('>', &str_end[2], sizeof(str_end) - 2); 723*46801Sdab 724*46801Sdab if (encrypt_debug_mode) 725*46801Sdab printf(">>>%s: Request input to be clear text\r\n", Name); 726*46801Sdab } 727*46801Sdab 728*46801Sdab void 729*46801Sdab encrypt_wait() 730*46801Sdab { 731*46801Sdab register int encrypt, decrypt; 732*46801Sdab if (encrypt_debug_mode) 733*46801Sdab printf(">>>%s: in encrypt_wait\r\n", Name); 734*46801Sdab if (!havesessionkey || !(i_support_encrypt & remote_supports_decrypt)) 735*46801Sdab return; 736*46801Sdab while (autoencrypt && !encrypt_output) 737*46801Sdab if (telnet_spin()) 738*46801Sdab return; 739*46801Sdab } 740*46801Sdab 741*46801Sdab void 742*46801Sdab encrypt_debug(mode) 743*46801Sdab int mode; 744*46801Sdab { 745*46801Sdab encrypt_debug_mode = mode; 746*46801Sdab } 747*46801Sdab 748*46801Sdab void 749*46801Sdab encrypt_gen_printsub(data, cnt, buf, buflen) 750*46801Sdab unsigned char *data, *buf; 751*46801Sdab int cnt, buflen; 752*46801Sdab { 753*46801Sdab char tbuf[16], *cp; 754*46801Sdab 755*46801Sdab cnt -= 2; 756*46801Sdab data += 2; 757*46801Sdab buf[buflen-1] = '\0'; 758*46801Sdab buf[buflen-2] = '*'; 759*46801Sdab buflen -= 2;; 760*46801Sdab for (; cnt > 0; cnt--, data++) { 761*46801Sdab sprintf(tbuf, " %d", *data); 762*46801Sdab for (cp = tbuf; *cp && buflen > 0; --buflen) 763*46801Sdab *buf++ = *cp++; 764*46801Sdab if (buflen <= 0) 765*46801Sdab return; 766*46801Sdab } 767*46801Sdab *buf = '\0'; 768*46801Sdab } 769*46801Sdab 770*46801Sdab void 771*46801Sdab encrypt_printsub(data, cnt, buf, buflen) 772*46801Sdab unsigned char *data, *buf; 773*46801Sdab int cnt, buflen; 774*46801Sdab { 775*46801Sdab Encryptions *ep; 776*46801Sdab register int type = data[1]; 777*46801Sdab 778*46801Sdab for (ep = encryptions; ep->type && ep->type != type; ep++) 779*46801Sdab ; 780*46801Sdab 781*46801Sdab if (ep->printsub) 782*46801Sdab (*ep->printsub)(data, cnt, buf, buflen); 783*46801Sdab else 784*46801Sdab encrypt_gen_printsub(data, cnt, buf, buflen); 785*46801Sdab } 786*46801Sdab #endif 787