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