home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-B.05 / NETKIT-B / NetKit-B-0.05 / libtelnet / encrypt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-17  |  22.1 KB  |  995 lines

  1. /*-
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. /*static char sccsid[] = "from: @(#)encrypt.c    5.2 (Berkeley) 3/22/91";*/
  36. static char rcsid[] = "$Id: encrypt.c,v 1.2 1993/08/01 18:32:42 mycroft Exp $";
  37. #endif /* not lint */
  38.  
  39. /*
  40.  * Copyright (C) 1990 by the Massachusetts Institute of Technology
  41.  *
  42.  * Export of this software from the United States of America is assumed
  43.  * to require a specific license from the United States Government.
  44.  * It is the responsibility of any person or organization contemplating
  45.  * export to obtain such a license before exporting.
  46.  *
  47.  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  48.  * distribute this software and its documentation for any purpose and
  49.  * without fee is hereby granted, provided that the above copyright
  50.  * notice appear in all copies and that both that copyright notice and
  51.  * this permission notice appear in supporting documentation, and that
  52.  * the name of M.I.T. not be used in advertising or publicity pertaining
  53.  * to distribution of the software without specific, written prior
  54.  * permission.  M.I.T. makes no representations about the suitability of
  55.  * this software for any purpose.  It is provided "as is" without express
  56.  * or implied warranty.
  57.  */
  58.  
  59. #if    defined(ENCRYPT)
  60.  
  61. #define    ENCRYPT_NAMES
  62. #include <arpa/telnet.h>
  63.  
  64. #include "encrypt.h"
  65. #include "misc.h"
  66.  
  67. #ifdef    __STDC__
  68. #include <stdlib.h>
  69. #endif
  70. #ifdef    NO_STRING_H
  71. #include <strings.h>
  72. #else
  73. #include <string.h>
  74. #endif
  75.  
  76. /*
  77.  * These functions pointers point to the current routines
  78.  * for encrypting and decrypting data.
  79.  */
  80. void    (*encrypt_output) P((unsigned char *, int));
  81. int    (*decrypt_input) P((int));
  82.  
  83. int encrypt_debug_mode = 0;
  84. static int decrypt_mode = 0;
  85. static int encrypt_mode = 0;
  86. static int encrypt_verbose = 0;
  87. static int autoencrypt = 0;
  88. static int autodecrypt = 0;
  89. static int havesessionkey = 0;
  90. static int Server = 0;
  91. static char *Name = "Noname";
  92.  
  93. #define    typemask(x)    ((x) > 0 ? 1 << ((x)-1) : 0)
  94.  
  95. static long i_support_encrypt = typemask(ENCTYPE_DES_CFB64)
  96.                 | typemask(ENCTYPE_DES_OFB64);
  97. static long i_support_decrypt = typemask(ENCTYPE_DES_CFB64)
  98.                 | typemask(ENCTYPE_DES_OFB64);
  99. static long i_wont_support_encrypt = 0;
  100. static long i_wont_support_decrypt = 0;
  101. #define    I_SUPPORT_ENCRYPT    (i_support_encrypt & ~i_wont_support_encrypt)
  102. #define    I_SUPPORT_DECRYPT    (i_support_decrypt & ~i_wont_support_decrypt)
  103.  
  104. static long remote_supports_encrypt = 0;
  105. static long remote_supports_decrypt = 0;
  106.  
  107. static Encryptions encryptions[] = {
  108. #if    defined(DES_ENCRYPT)
  109.     { "DES_CFB64",    ENCTYPE_DES_CFB64,
  110.             cfb64_encrypt,    
  111.             cfb64_decrypt,
  112.             cfb64_init,
  113.             cfb64_start,
  114.             cfb64_is,
  115.             cfb64_reply,
  116.             cfb64_session,
  117.             cfb64_keyid,
  118.             cfb64_printsub },
  119.     { "DES_OFB64",    ENCTYPE_DES_OFB64,
  120.             ofb64_encrypt,    
  121.             ofb64_decrypt,
  122.             ofb64_init,
  123.             ofb64_start,
  124.             ofb64_is,
  125.             ofb64_reply,
  126.             ofb64_session,
  127.             ofb64_keyid,
  128.             ofb64_printsub },
  129. #endif
  130.     { 0, },
  131. };
  132.  
  133. static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT,
  134.                      ENCRYPT_SUPPORT };
  135. static unsigned char str_suplen = 0;
  136. static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT };
  137. static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE };
  138.  
  139.     Encryptions *
  140. findencryption(type)
  141.     int type;
  142. {
  143.     Encryptions *ep = encryptions;
  144.  
  145.     if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & typemask(type)))
  146.         return(0);
  147.     while (ep->type && ep->type != type)
  148.         ++ep;
  149.     return(ep->type ? ep : 0);
  150. }
  151.  
  152.     Encryptions *
  153. finddecryption(type)
  154.     int type;
  155. {
  156.     Encryptions *ep = encryptions;
  157.  
  158.     if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & typemask(type)))
  159.         return(0);
  160.     while (ep->type && ep->type != type)
  161.         ++ep;
  162.     return(ep->type ? ep : 0);
  163. }
  164.  
  165. #define    MAXKEYLEN 64
  166.  
  167. static struct key_info {
  168.     unsigned char keyid[MAXKEYLEN];
  169.     int keylen;
  170.     int dir;
  171.     int *modep;
  172.     Encryptions *(*getcrypt)();
  173. } ki[2] = {
  174.     { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption },
  175.     { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption },
  176. };
  177.  
  178.     void
  179. encrypt_init(name, server)
  180.     char *name;
  181.     int server;
  182. {
  183.     Encryptions *ep = encryptions;
  184.  
  185.     Name = name;
  186.     Server = server;
  187.     i_support_encrypt = i_support_decrypt = 0;
  188.     remote_supports_encrypt = remote_supports_decrypt = 0;
  189.     encrypt_mode = 0;
  190.     decrypt_mode = 0;
  191.     encrypt_output = 0;
  192.     decrypt_input = 0;
  193. #ifdef notdef
  194.     encrypt_verbose = !server;
  195. #endif
  196.  
  197.     str_suplen = 4;
  198.  
  199.     while (ep->type) {
  200.         if (encrypt_debug_mode)
  201.             printf(">>>%s: I will support %s\r\n",
  202.                 Name, ENCTYPE_NAME(ep->type));
  203.         i_support_encrypt |= typemask(ep->type);
  204.         i_support_decrypt |= typemask(ep->type);
  205.         if ((i_wont_support_decrypt & typemask(ep->type)) == 0)
  206.             if ((str_send[str_suplen++] = ep->type) == IAC)
  207.                 str_send[str_suplen++] = IAC;
  208.         if (ep->init)
  209.             (*ep->init)(Server);
  210.         ++ep;
  211.     }
  212.     str_send[str_suplen++] = IAC;
  213.     str_send[str_suplen++] = SE;
  214. }
  215.  
  216.     void
  217. encrypt_list_types()
  218. {
  219.     Encryptions *ep = encryptions;
  220.  
  221.     printf("Valid encryption types:\n");
  222.     while (ep->type) {
  223.         printf("\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type);
  224.         ++ep;
  225.     }
  226. }
  227.  
  228.     int
  229. EncryptEnable(type, mode)
  230.     char *type, *mode;
  231. {
  232.     if (isprefix(type, "help") || isprefix(type, "?")) {
  233.         printf("Usage: encrypt enable <type> [input|output]\n");
  234.         encrypt_list_types();
  235.         return(0);
  236.     }
  237.     if (EncryptType(type, mode))
  238.         return(EncryptStart(mode));
  239.     return(0);
  240. }
  241.  
  242.     int
  243. EncryptDisable(type, mode)
  244.     char *type, *mode;
  245. {
  246.     register Encryptions *ep;
  247.     int ret = 0;
  248.  
  249.     if (isprefix(type, "help") || isprefix(type, "?")) {
  250.         printf("Usage: encrypt disable <type> [input|output]\n");
  251.         encrypt_list_types();
  252.     } else if ((ep = (Encryptions *)genget(type, encryptions,
  253.                         sizeof(Encryptions))) == 0) {
  254.         printf("%s: invalid encryption type\n", type);
  255.     } else if (Ambiguous(ep)) {
  256.         printf("Ambiguous type '%s'\n", type);
  257.     } else {
  258.         if ((mode == 0) || (isprefix(mode, "input") ? 1 : 0)) {
  259.             if (decrypt_mode == ep->type)
  260.                 EncryptStopInput();
  261.             i_wont_support_decrypt |= typemask(ep->type);
  262.             ret = 1;
  263.         }
  264.         if ((mode == 0) || (isprefix(mode, "output"))) {
  265.             if (encrypt_mode == ep->type)
  266.                 EncryptStopOutput();
  267.             i_wont_support_encrypt |= typemask(ep->type);
  268.             ret = 1;
  269.         }
  270.         if (ret == 0)
  271.             printf("%s: invalid encryption mode\n", mode);
  272.     }
  273.     return(ret);
  274. }
  275.  
  276.     int
  277. EncryptType(type, mode)
  278.     char *type;
  279.     char *mode;
  280. {
  281.     register Encryptions *ep;
  282.     int ret = 0;
  283.  
  284.     if (isprefix(type, "help") || isprefix(type, "?")) {
  285.         printf("Usage: encrypt type <type> [input|output]\n");
  286.         encrypt_list_types();
  287.     } else if ((ep = (Encryptions *)genget(type, encryptions,
  288.                         sizeof(Encryptions))) == 0) {
  289.         printf("%s: invalid encryption type\n", type);
  290.     } else if (Ambiguous(ep)) {
  291.         printf("Ambiguous type '%s'\n", type);
  292.     } else {
  293.         if ((mode == 0) || isprefix(mode, "input")) {
  294.             decrypt_mode = ep->type;
  295.             i_wont_support_decrypt &= ~typemask(ep->type);
  296.             ret = 1;
  297.         }
  298.         if ((mode == 0) || isprefix(mode, "output")) {
  299.             encrypt_mode = ep->type;
  300.             i_wont_support_encrypt &= ~typemask(ep->type);
  301.             ret = 1;
  302.         }
  303.         if (ret == 0)
  304.             printf("%s: invalid encryption mode\n", mode);
  305.     }
  306.     return(ret);
  307. }
  308.  
  309.     int
  310. EncryptStart(mode)
  311.     char *mode;
  312. {
  313.     register int ret = 0;
  314.     if (mode) {
  315.         if (isprefix(mode, "input"))
  316.             return(EncryptStartInput());
  317.         if (isprefix(mode, "output"))
  318.             return(EncryptStartOutput());
  319.         if (isprefix(mode, "help") || isprefix(mode, "?")) {
  320.             printf("Usage: encrypt start [input|output]\n");
  321.             return(0);
  322.         }
  323.         printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode);
  324.         return(0);
  325.     }
  326.     ret += EncryptStartInput();
  327.     ret += EncryptStartOutput();
  328.     return(ret);
  329. }
  330.  
  331.     int
  332. EncryptStartInput()
  333. {
  334.     if (decrypt_mode) {
  335.         encrypt_send_request_start();
  336.         return(1);
  337.     }
  338.     printf("No previous decryption mode, decryption not enabled\r\n");
  339.     return(0);
  340. }
  341.  
  342.     int
  343. EncryptStartOutput()
  344. {
  345.     if (encrypt_mode) {
  346.         encrypt_start_output(encrypt_mode);
  347.         return(1);
  348.     }
  349.     printf("No previous encryption mode, encryption not enabled\r\n");
  350.     return(0);
  351. }
  352.  
  353.     int
  354. EncryptStop(mode)
  355.     char *mode;
  356. {
  357.     int ret = 0;
  358.     if (mode) {
  359.         if (isprefix(mode, "input"))
  360.             return(EncryptStopInput());
  361.         if (isprefix(mode, "output"))
  362.             return(EncryptStopOutput());
  363.         if (isprefix(mode, "help") || isprefix(mode, "?")) {
  364.             printf("Usage: encrypt stop [input|output]\n");
  365.             return(0);
  366.         }
  367.         printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode);
  368.         return(0);
  369.     }
  370.     ret += EncryptStopInput();
  371.     ret += EncryptStopOutput();
  372.     return(ret);
  373. }
  374.  
  375.     int
  376. EncryptStopInput()
  377. {
  378.     encrypt_send_request_end();
  379.     return(1);
  380. }
  381.  
  382.     int
  383. EncryptStopOutput()
  384. {
  385.     encrypt_send_end();
  386.     return(1);
  387. }
  388.  
  389.     void
  390. encrypt_display()
  391. {
  392.     if (encrypt_output)
  393.         printf("Currently encrypting output with %s\r\n",
  394.             ENCTYPE_NAME(encrypt_mode));
  395.     if (decrypt_input)
  396.         printf("Currently decrypting input with %s\r\n",
  397.             ENCTYPE_NAME(decrypt_mode));
  398. }
  399.  
  400.     int
  401. EncryptStatus()
  402. {
  403.     if (encrypt_output)
  404.         printf("Currently encrypting output with %s\r\n",
  405.             ENCTYPE_NAME(encrypt_mode));
  406.     else if (encrypt_mode) {
  407.         printf("Currently output is clear text.\r\n");
  408.         printf("Last encryption mode was %s\r\n",
  409.             ENCTYPE_NAME(encrypt_mode));
  410.     }
  411.     if (decrypt_input) {
  412.         printf("Currently decrypting input with %s\r\n",
  413.             ENCTYPE_NAME(decrypt_mode));
  414.     } else if (decrypt_mode) {
  415.         printf("Currently input is clear text.\r\n");
  416.         printf("Last decryption mode was %s\r\n",
  417.             ENCTYPE_NAME(decrypt_mode));
  418.     }
  419.     return 1;
  420. }
  421.  
  422.     void
  423. encrypt_send_support()
  424. {
  425.     if (str_suplen) {
  426.         /*
  427.          * If the user has requested that decryption start
  428.          * immediatly, then send a "REQUEST START" before
  429.          * we negotiate the type.
  430.          */
  431.         if (!Server && autodecrypt)
  432.             encrypt_send_request_start();
  433.         net_write(str_send, str_suplen);
  434.         printsub('>', &str_send[2], str_suplen - 2);
  435.         str_suplen = 0;
  436.     }
  437. }
  438.  
  439.     int
  440. EncryptDebug(on)
  441.     int on;
  442. {
  443.     if (on < 0)
  444.         encrypt_debug_mode ^= 1;
  445.     else
  446.         encrypt_debug_mode = on;
  447.     printf("Encryption debugging %s\r\n",
  448.         encrypt_debug_mode ? "enabled" : "disabled");
  449.     return(1);
  450. }
  451.  
  452.     int
  453. EncryptVerbose(on)
  454.     int on;
  455. {
  456.     if (on < 0)
  457.         encrypt_verbose ^= 1;
  458.     else
  459.         encrypt_verbose = on;
  460.     printf("Encryption %s verbose\r\n",
  461.         encrypt_verbose ? "is" : "is not");
  462.     return(1);
  463. }
  464.  
  465.     int
  466. EncryptAutoEnc(on)
  467.     int on;
  468. {
  469.     encrypt_auto(on);
  470.     printf("Automatic encryption of output is %s\r\n",
  471.         autoencrypt ? "enabled" : "disabled");
  472.     return(1);
  473. }
  474.  
  475.     int
  476. EncryptAutoDec(on)
  477.     int on;
  478. {
  479.     decrypt_auto(on);
  480.     printf("Automatic decryption of input is %s\r\n",
  481.         autodecrypt ? "enabled" : "disabled");
  482.     return(1);
  483. }
  484.  
  485. /*
  486.  * Called when ENCRYPT SUPPORT is received.
  487.  */
  488.     void
  489. encrypt_support(typelist, cnt)
  490.     unsigned char *typelist;
  491.     int cnt;
  492. {
  493.     register int type, use_type = 0;
  494.     Encryptions *ep;
  495.  
  496.     /*
  497.      * Forget anything the other side has previously told us.
  498.      */
  499.     remote_supports_decrypt = 0;
  500.  
  501.     while (cnt-- > 0) {
  502.         type = *typelist++;
  503.         if (encrypt_debug_mode)
  504.             printf(">>>%s: He is supporting %s (%d)\r\n",
  505.                 Name,
  506.                 ENCTYPE_NAME(type), type);
  507.         if ((type < ENCTYPE_CNT) &&
  508.             (I_SUPPORT_ENCRYPT & typemask(type))) {
  509.             remote_supports_decrypt |= typemask(type);
  510.             if (use_type == 0)
  511.                 use_type = type;
  512.         }
  513.     }
  514.     if (use_type) {
  515.         ep = findencryption(use_type);
  516.         if (!ep)
  517.             return;
  518.         type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0;
  519.         if (encrypt_debug_mode)
  520.             printf(">>>%s: (*ep->start)() returned %d\r\n",
  521.                     Name, type);
  522.         if (type < 0)
  523.             return;
  524.         encrypt_mode = use_type;
  525.         if (type == 0)
  526.             encrypt_start_output(use_type);
  527.     }
  528. }
  529.  
  530.     void
  531. encrypt_is(data, cnt)
  532.     unsigned char *data;
  533.     int cnt;
  534. {
  535.     Encryptions *ep;
  536.     register int type, ret;
  537.  
  538.     if (--cnt < 0)
  539.         return;
  540.     type = *data++;
  541.     if (type < ENCTYPE_CNT)
  542.         remote_supports_encrypt |= typemask(type);
  543.     if (!(ep = finddecryption(type))) {
  544.         if (encrypt_debug_mode)
  545.             printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
  546.                 Name,
  547.                 ENCTYPE_NAME_OK(type)
  548.                     ? ENCTYPE_NAME(type) : "(unknown)",
  549.                 type);
  550.         return;
  551.     }
  552.     if (!ep->is) {
  553.         if (encrypt_debug_mode)
  554.             printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n",
  555.                 Name,
  556.                 ENCTYPE_NAME_OK(type)
  557.                     ? ENCTYPE_NAME(type) : "(unknown)",
  558.                 type);
  559.         ret = 0;
  560.     } else {
  561.         ret = (*ep->is)(data, cnt);
  562.         if (encrypt_debug_mode)
  563.             printf("(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt,
  564.                 (ret < 0) ? "FAIL " :
  565.                 (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
  566.     }
  567.     if (ret < 0) {
  568.         autodecrypt = 0;
  569.     } else {
  570.         decrypt_mode = type;
  571.         if (ret == 0 && autodecrypt)
  572.             encrypt_send_request_start();
  573.     }
  574. }
  575.  
  576.     void
  577. encrypt_reply(data, cnt)
  578.     unsigned char *data;
  579.     int cnt;
  580. {
  581.     Encryptions *ep;
  582.     register int ret, type;
  583.  
  584.     if (--cnt < 0)
  585.         return;
  586.     type = *data++;
  587.     if (!(ep = findencryption(type))) {
  588.         if (encrypt_debug_mode)
  589.             printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
  590.                 Name,
  591.                 ENCTYPE_NAME_OK(type)
  592.                     ? ENCTYPE_NAME(type) : "(unknown)",
  593.                 type);
  594.         return;
  595.     }
  596.     if (!ep->reply) {
  597.         if (encrypt_debug_mode)
  598.             printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n",
  599.                 Name,
  600.                 ENCTYPE_NAME_OK(type)
  601.                     ? ENCTYPE_NAME(type) : "(unknown)",
  602.                 type);
  603.         ret = 0;
  604.     } else {
  605.         ret = (*ep->reply)(data, cnt);
  606.         if (encrypt_debug_mode)
  607.             printf("(*ep->reply)(%x, %d) returned %s(%d)\n",
  608.                 data, cnt,
  609.                 (ret < 0) ? "FAIL " :
  610.                 (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
  611.     }
  612.     if (encrypt_debug_mode)
  613.         printf(">>>%s: encrypt_reply returned %d\n", Name, ret);
  614.     if (ret < 0) {
  615.         autoencrypt = 0;
  616.     } else {
  617.         encrypt_mode = type;
  618.         if (ret == 0 && autoencrypt)
  619.             encrypt_start_output(type);
  620.     }
  621. }
  622.  
  623. /*
  624.  * Called when a ENCRYPT START command is received.
  625.  */
  626.     void
  627. encrypt_start(data, cnt)
  628.     unsigned char *data;
  629.     int cnt;
  630. {
  631.     Encryptions *ep;
  632.  
  633.     if (!decrypt_mode) {
  634.         /*
  635.          * Something is wrong.  We should not get a START
  636.          * command without having already picked our
  637.          * decryption scheme.  Send a REQUEST-END to
  638.          * attempt to clear the channel...
  639.          */
  640.         printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name);
  641.         encrypt_send_request_end();
  642.         return;
  643.     }
  644.  
  645.     if (ep = finddecryption(decrypt_mode)) {
  646.         decrypt_input = ep->input;
  647.         if (encrypt_verbose)
  648.             printf("[ Input is now decrypted with type %s ]\r\n",
  649.                 ENCTYPE_NAME(decrypt_mode));
  650.         if (encrypt_debug_mode)
  651.             printf(">>>%s: Start to decrypt input with type %s\r\n",
  652.                 Name, ENCTYPE_NAME(decrypt_mode));
  653.     } else {
  654.         printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n",
  655.                 Name,
  656.                 ENCTYPE_NAME_OK(decrypt_mode)
  657.                     ? ENCTYPE_NAME(decrypt_mode)
  658.                     : "(unknown)",
  659.                 decrypt_mode);
  660.         encrypt_send_request_end();
  661.     }
  662. }
  663.  
  664.     void
  665. encrypt_session_key(key, server)
  666.     Session_Key *key;
  667.     int server;
  668. {
  669.     Encryptions *ep = encryptions;
  670.  
  671.     havesessionkey = 1;
  672.  
  673.     while (ep->type) {
  674.         if (ep->session)
  675.             (*ep->session)(key, server);
  676.         ++ep;
  677.     }
  678. }
  679.  
  680. /*
  681.  * Called when ENCRYPT END is received.
  682.  */
  683.     void
  684. encrypt_end()
  685. {
  686.     decrypt_input = 0;
  687.     if (encrypt_debug_mode)
  688.         printf(">>>%s: Input is back to clear text\r\n", Name);
  689.     if (encrypt_verbose)
  690.         printf("[ Input is now clear text ]\r\n");
  691. }
  692.  
  693. /*
  694.  * Called when ENCRYPT REQUEST-END is received.
  695.  */
  696.     void
  697. encrypt_request_end()
  698. {
  699.     encrypt_send_end();
  700. }
  701.  
  702. /*
  703.  * Called when ENCRYPT REQUEST-START is received.  If we receive
  704.  * this before a type is picked, then that indicates that the
  705.  * other side wants us to start encrypting data as soon as we
  706.  * can. 
  707.  */
  708.     void
  709. encrypt_request_start(data, cnt)
  710.     unsigned char *data;
  711.     int cnt;
  712. {
  713.     if (encrypt_mode == 0)  {
  714.         if (Server)
  715.             autoencrypt = 1;
  716.         return;
  717.     }
  718.     encrypt_start_output(encrypt_mode);
  719. }
  720.  
  721. static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT };
  722.  
  723. encrypt_enc_keyid(keyid, len)
  724.     unsigned char *keyid;
  725.     int len;
  726. {
  727.     encrypt_keyid(&ki[1], keyid, len);
  728. }
  729.  
  730. encrypt_dec_keyid(keyid, len)
  731.     unsigned char *keyid;
  732.     int len;
  733. {
  734.     encrypt_keyid(&ki[0], keyid, len);
  735. }
  736.  
  737. encrypt_keyid(kp, keyid, len)
  738.     struct key_info *kp;
  739.     unsigned char *keyid;
  740.     int len;
  741. {
  742.     Encryptions *ep;
  743.     unsigned char *strp, *cp;
  744.     int dir = kp->dir;
  745.     register int ret = 0;
  746.  
  747.     if (!(ep = (*kp->getcrypt)(*kp->modep))) {
  748.         if (len == 0)
  749.             return;
  750.         kp->keylen = 0;
  751.     } else if (len == 0) {
  752.         /*
  753.          * Empty option, indicates a failure.
  754.          */
  755.         if (kp->keylen == 0)
  756.             return;
  757.         kp->keylen = 0;
  758.         if (ep->keyid)
  759.             (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
  760.  
  761.     } else if ((len != kp->keylen) || (bcmp(keyid, kp->keyid, len) != 0)) {
  762.         /*
  763.          * Length or contents are different
  764.          */
  765.         kp->keylen = len;
  766.         bcopy(keyid, kp->keyid, len);
  767.         if (ep->keyid)
  768.             (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
  769.     } else {
  770.         if (ep->keyid)
  771.             ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen);
  772.         if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt)
  773.             encrypt_start_output(*kp->modep);
  774.         return;
  775.     }
  776.  
  777.     encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0);
  778. }
  779.  
  780.     void
  781. encrypt_send_keyid(dir, keyid, keylen, saveit)
  782.     int dir;
  783.     unsigned char *keyid;
  784.     int keylen;
  785.     int saveit;
  786. {
  787.     unsigned char *strp;
  788.  
  789.     str_keyid[3] = (dir == DIR_ENCRYPT)
  790.             ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID;
  791.     if (saveit) {
  792.         struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1];
  793.         bcopy(keyid, kp->keyid, keylen);
  794.         kp->keylen = keylen;
  795.     }
  796.  
  797.     for (strp = &str_keyid[4]; keylen > 0; --keylen) {
  798.         if ((*strp++ = *keyid++) == IAC)
  799.             *strp++ = IAC;
  800.     }
  801.     *strp++ = IAC;
  802.     *strp++ = SE;
  803.     net_write(str_keyid, strp - str_keyid);
  804.     printsub('>', &str_keyid[2], strp - str_keyid - 2);
  805. }
  806.  
  807.     void
  808. encrypt_auto(on)
  809.     int on;
  810. {
  811.     if (on < 0)
  812.         autoencrypt ^= 1;
  813.     else
  814.         autoencrypt = on ? 1 : 0;
  815. }
  816.  
  817.     void
  818. decrypt_auto(on)
  819.     int on;
  820. {
  821.     if (on < 0)
  822.         autodecrypt ^= 1;
  823.     else
  824.         autodecrypt = on ? 1 : 0;
  825. }
  826.  
  827.     void
  828. encrypt_start_output(type)
  829.     int type;
  830. {
  831.     Encryptions *ep;
  832.     register unsigned char *p;
  833.     register int i;
  834.  
  835.     if (!(ep = findencryption(type))) {
  836.         if (encrypt_debug_mode) {
  837.             printf(">>>%s: Can't encrypt with type %s (%d)\r\n",
  838.                 Name,
  839.                 ENCTYPE_NAME_OK(type)
  840.                     ? ENCTYPE_NAME(type) : "(unknown)",
  841.                 type);
  842.         }
  843.         return;
  844.     }
  845.     if (ep->start) {
  846.         i = (*ep->start)(DIR_ENCRYPT, Server);
  847.         if (encrypt_debug_mode) {
  848.             printf(">>>%s: Encrypt start: %s (%d) %s\r\n",
  849.                 Name, 
  850.                 (i < 0) ? "failed" :
  851.                     "initial negotiation in progress",
  852.                 i, ENCTYPE_NAME(type));
  853.         }
  854.         if (i)
  855.             return;
  856.     }
  857.     p = str_start + 3;
  858.     *p++ = ENCRYPT_START;
  859.     for (i = 0; i < ki[0].keylen; ++i) {
  860.         if ((*p++ = ki[0].keyid[i]) == IAC)
  861.             *p++ = IAC;
  862.     }
  863.     *p++ = IAC;
  864.     *p++ = SE;
  865.     net_write(str_start, p - str_start);
  866.     net_encrypt();
  867.     printsub('>', &str_start[2], p - &str_start[2]);
  868.     /*
  869.      * If we are already encrypting in some mode, then
  870.      * encrypt the ring (which includes our request) in
  871.      * the old mode, mark it all as "clear text" and then
  872.      * switch to the new mode.
  873.      */
  874.     encrypt_output = ep->output;
  875.     encrypt_mode = type;
  876.     if (encrypt_debug_mode)
  877.         printf(">>>%s: Started to encrypt output with type %s\r\n",
  878.             Name, ENCTYPE_NAME(type));
  879.     if (encrypt_verbose)
  880.         printf("[ Output is now encrypted with type %s ]\r\n",
  881.             ENCTYPE_NAME(type));
  882. }
  883.  
  884.     void
  885. encrypt_send_end()
  886. {
  887.     if (!encrypt_output)
  888.         return;
  889.  
  890.     str_end[3] = ENCRYPT_END;
  891.     net_write(str_end, sizeof(str_end));
  892.     net_encrypt();
  893.     printsub('>', &str_end[2], sizeof(str_end) - 2);
  894.     /*
  895.      * Encrypt the output buffer now because it will not be done by
  896.      * netflush...
  897.      */
  898.     encrypt_output = 0;
  899.     if (encrypt_debug_mode)
  900.         printf(">>>%s: Output is back to clear text\r\n", Name);
  901.     if (encrypt_verbose)
  902.         printf("[ Output is now clear text ]\r\n");
  903. }
  904.  
  905.     void
  906. encrypt_send_request_start()
  907. {
  908.     register unsigned char *p;
  909.     register int i;
  910.  
  911.     p = &str_start[3];
  912.     *p++ = ENCRYPT_REQSTART;
  913.     for (i = 0; i < ki[1].keylen; ++i) {
  914.         if ((*p++ = ki[1].keyid[i]) == IAC)
  915.             *p++ = IAC;
  916.     }
  917.     *p++ = IAC;
  918.     *p++ = SE;
  919.     net_write(str_start, p - str_start);
  920.     printsub('>', &str_start[2], p - &str_start[2]);
  921.     if (encrypt_debug_mode)
  922.         printf(">>>%s: Request input to be encrypted\r\n", Name);
  923. }
  924.  
  925.     void
  926. encrypt_send_request_end()
  927. {
  928.     str_end[3] = ENCRYPT_REQEND;
  929.     net_write(str_end, sizeof(str_end));
  930.     printsub('>', &str_end[2], sizeof(str_end) - 2);
  931.  
  932.     if (encrypt_debug_mode)
  933.         printf(">>>%s: Request input to be clear text\r\n", Name);
  934. }
  935.  
  936.     void
  937. encrypt_wait()
  938. {
  939.     register int encrypt, decrypt;
  940.     if (encrypt_debug_mode)
  941.         printf(">>>%s: in encrypt_wait\r\n", Name);
  942.     if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt))
  943.         return;
  944.     while (autoencrypt && !encrypt_output)
  945.         if (telnet_spin())
  946.             return;
  947. }
  948.  
  949.     void
  950. encrypt_debug(mode)
  951.     int mode;
  952. {
  953.     encrypt_debug_mode = mode;
  954. }
  955.  
  956.     void
  957. encrypt_gen_printsub(data, cnt, buf, buflen)
  958.     unsigned char *data, *buf;
  959.     int cnt, buflen;
  960. {
  961.     char tbuf[16], *cp;
  962.  
  963.     cnt -= 2;
  964.     data += 2;
  965.     buf[buflen-1] = '\0';
  966.     buf[buflen-2] = '*';
  967.     buflen -= 2;;
  968.     for (; cnt > 0; cnt--, data++) {
  969.         sprintf(tbuf, " %d", *data);
  970.         for (cp = tbuf; *cp && buflen > 0; --buflen)
  971.             *buf++ = *cp++;
  972.         if (buflen <= 0)
  973.             return;
  974.     }
  975.     *buf = '\0';
  976. }
  977.  
  978.     void
  979. encrypt_printsub(data, cnt, buf, buflen)
  980.     unsigned char *data, *buf;
  981.     int cnt, buflen;
  982. {
  983.     Encryptions *ep;
  984.     register int type = data[1];
  985.  
  986.     for (ep = encryptions; ep->type && ep->type != type; ep++)
  987.         ;
  988.  
  989.     if (ep->printsub)
  990.         (*ep->printsub)(data, cnt, buf, buflen);
  991.     else
  992.         encrypt_gen_printsub(data, cnt, buf, buflen);
  993. }
  994. #endif
  995.