[BACK]Return to encrypt.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / telnet

Annotation of src/usr.bin/telnet/encrypt.c, Revision 1.3.20.1

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