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

Annotation of src/usr.bin/telnet/auth.c, Revision 1.2

1.2     ! deraadt     1: /*     $OpenBSD: auth.c,v 1.1 2005/05/24 03:43:56 deraadt 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: /* "$KTH: auth.c,v 1.23 2000/01/18 03:09:34 assar Exp $" */
                     65:
                     66: #if    defined(AUTHENTICATION)
                     67: #include <stdio.h>
                     68: #include <sys/types.h>
                     69: #include <unistd.h>
                     70: #include <signal.h>
                     71: #define        AUTH_NAMES
                     72: #include <arpa/telnet.h>
                     73: #include <stdlib.h>
                     74: #include <string.h>
                     75:
                     76: #include "encrypt.h"
                     77: #include "auth.h"
                     78: #include "misc-proto.h"
                     79: #include "auth-proto.h"
                     80:
                     81: #define        typemask(x)             (1<<((x)-1))
                     82:
                     83: #ifdef KRB4_ENCPWD
                     84: extern krb4encpwd_init();
                     85: extern krb4encpwd_send();
                     86: extern krb4encpwd_is();
                     87: extern krb4encpwd_reply();
                     88: extern krb4encpwd_status();
                     89: extern krb4encpwd_printsub();
                     90: #endif
                     91:
                     92: #ifdef RSA_ENCPWD
                     93: extern rsaencpwd_init();
                     94: extern rsaencpwd_send();
                     95: extern rsaencpwd_is();
                     96: extern rsaencpwd_reply();
                     97: extern rsaencpwd_status();
                     98: extern rsaencpwd_printsub();
                     99: #endif
                    100:
                    101: int auth_debug_mode = 0;
                    102: int auth_has_failed  = 0;
                    103: int auth_enable_encrypt = 0;
                    104: static         const   char    *Name = "Noname";
                    105: static int     Server = 0;
                    106: static Authenticator   *authenticated = 0;
                    107: static int     authenticating = 0;
                    108: static int     validuser = 0;
                    109: static unsigned char   _auth_send_data[256];
                    110: static unsigned char   *auth_send_data;
                    111: static int     auth_send_cnt = 0;
                    112:
                    113: /*
                    114:  * Authentication types supported.  Plese note that these are stored
                    115:  * in priority order, i.e. try the first one first.
                    116:  */
                    117: Authenticator authenticators[] = {
                    118: #ifdef UNSAFE
                    119:     { AUTHTYPE_UNSAFE, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
                    120:       unsafe_init,
                    121:       unsafe_send,
                    122:       unsafe_is,
                    123:       unsafe_reply,
                    124:       unsafe_status,
                    125:       unsafe_printsub },
                    126: #endif
                    127: #ifdef SRA
                    128:     { AUTHTYPE_SRA, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
                    129:       sra_init,
                    130:       sra_send,
                    131:       sra_is,
                    132:       sra_reply,
                    133:       sra_status,
                    134:       sra_printsub },
                    135: #endif
                    136: #ifdef SPX
                    137:     { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
                    138:       spx_init,
                    139:       spx_send,
                    140:       spx_is,
                    141:       spx_reply,
                    142:       spx_status,
                    143:       spx_printsub },
                    144:     { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
                    145:       spx_init,
                    146:       spx_send,
                    147:       spx_is,
                    148:       spx_reply,
                    149:       spx_status,
                    150:       spx_printsub },
                    151: #endif
                    152: #ifdef KRB5
                    153:     { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
                    154:       kerberos5_init,
                    155:       kerberos5_send_mutual,
                    156:       kerberos5_is,
                    157:       kerberos5_reply,
                    158:       kerberos5_status,
                    159:       kerberos5_printsub },
                    160:     { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
                    161:       kerberos5_init,
                    162:       kerberos5_send_oneway,
                    163:       kerberos5_is,
                    164:       kerberos5_reply,
                    165:       kerberos5_status,
                    166:       kerberos5_printsub },
                    167: #endif
                    168: #ifdef KRB4
                    169:     { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
                    170:       kerberos4_init,
                    171:       kerberos4_send_mutual,
                    172:       kerberos4_is,
                    173:       kerberos4_reply,
                    174:       kerberos4_status,
                    175:       kerberos4_printsub },
                    176:     { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
                    177:       kerberos4_init,
                    178:       kerberos4_send_oneway,
                    179:       kerberos4_is,
                    180:       kerberos4_reply,
                    181:       kerberos4_status,
                    182:       kerberos4_printsub },
                    183: #endif
                    184: #ifdef KRB4_ENCPWD
                    185:     { AUTHTYPE_KRB4_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
                    186:       krb4encpwd_init,
                    187:       krb4encpwd_send,
                    188:       krb4encpwd_is,
                    189:       krb4encpwd_reply,
                    190:       krb4encpwd_status,
                    191:       krb4encpwd_printsub },
                    192: #endif
                    193: #ifdef RSA_ENCPWD
                    194:     { AUTHTYPE_RSA_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
                    195:       rsaencpwd_init,
                    196:       rsaencpwd_send,
                    197:       rsaencpwd_is,
                    198:       rsaencpwd_reply,
                    199:       rsaencpwd_status,
                    200:       rsaencpwd_printsub },
                    201: #endif
                    202:     { 0, },
                    203: };
                    204:
                    205: static Authenticator NoAuth = { 0 };
                    206:
                    207: static int     i_support = 0;
                    208: static int     i_wont_support = 0;
                    209:
                    210: Authenticator *
                    211: findauthenticator(int type, int way)
                    212: {
                    213:     Authenticator *ap = authenticators;
                    214:
                    215:     while (ap->type && (ap->type != type || ap->way != way))
                    216:        ++ap;
                    217:     return(ap->type ? ap : 0);
                    218: }
                    219:
                    220: void
                    221: auth_init(const char *name, int server)
                    222: {
                    223:     Authenticator *ap = authenticators;
                    224:
                    225:     Server = server;
                    226:     Name = name;
                    227:
                    228:     i_support = 0;
                    229:     authenticated = 0;
                    230:     authenticating = 0;
                    231:     while (ap->type) {
                    232:        if (!ap->init || (*ap->init)(ap, server)) {
                    233:            i_support |= typemask(ap->type);
                    234:            if (auth_debug_mode)
                    235:                printf(">>>%s: I support auth type %d %d\r\n",
                    236:                       Name,
                    237:                       ap->type, ap->way);
                    238:        }
                    239:        else if (auth_debug_mode)
                    240:            printf(">>>%s: Init failed: auth type %d %d\r\n",
                    241:                   Name, ap->type, ap->way);
                    242:        ++ap;
                    243:     }
                    244: }
                    245:
                    246: void
                    247: auth_disable_name(char *name)
                    248: {
                    249:     int x;
                    250:     for (x = 0; x < AUTHTYPE_CNT; ++x) {
                    251:        if (!strcasecmp(name, AUTHTYPE_NAME(x))) {
                    252:            i_wont_support |= typemask(x);
                    253:            break;
                    254:        }
                    255:     }
                    256: }
                    257:
                    258: int
                    259: getauthmask(char *type, int *maskp)
                    260: {
                    261:     int x;
                    262:
                    263:     if (!strcasecmp(type, AUTHTYPE_NAME(0))) {
                    264:        *maskp = -1;
                    265:        return(1);
                    266:     }
                    267:
                    268:     for (x = 1; x < AUTHTYPE_CNT; ++x) {
                    269:        if (!strcasecmp(type, AUTHTYPE_NAME(x))) {
                    270:            *maskp = typemask(x);
                    271:            return(1);
                    272:        }
                    273:     }
                    274:     return(0);
                    275: }
                    276:
                    277: int
                    278: auth_enable(char *type)
                    279: {
                    280:     return(auth_onoff(type, 1));
                    281: }
                    282:
                    283: int
                    284: auth_disable(char *type)
                    285: {
                    286:     return(auth_onoff(type, 0));
                    287: }
                    288:
                    289: int
                    290: auth_onoff(char *type, int on)
                    291: {
                    292:     int i, mask = -1;
                    293:     Authenticator *ap;
                    294:
                    295:     if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) {
                    296:        printf("auth %s 'type'\n", on ? "enable" : "disable");
                    297:        printf("Where 'type' is one of:\n");
                    298:        printf("\t%s\n", AUTHTYPE_NAME(0));
                    299:        mask = 0;
                    300:        for (ap = authenticators; ap->type; ap++) {
                    301:            if ((mask & (i = typemask(ap->type))) != 0)
                    302:                continue;
                    303:            mask |= i;
                    304:            printf("\t%s\n", AUTHTYPE_NAME(ap->type));
                    305:        }
                    306:        return(0);
                    307:     }
                    308:
                    309:     if (!getauthmask(type, &mask)) {
                    310:        printf("%s: invalid authentication type\n", type);
                    311:        return(0);
                    312:     }
                    313:     if (on)
                    314:        i_wont_support &= ~mask;
                    315:     else
                    316:        i_wont_support |= mask;
                    317:     return(1);
                    318: }
                    319:
                    320: int
                    321: auth_togdebug(int on)
                    322: {
                    323:     if (on < 0)
                    324:        auth_debug_mode ^= 1;
                    325:     else
                    326:        auth_debug_mode = on;
                    327:     printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled");
                    328:     return(1);
                    329: }
                    330:
                    331: int
                    332: auth_status(void)
                    333: {
                    334:     Authenticator *ap;
                    335:     int i, mask;
                    336:
                    337:     if (i_wont_support == -1)
                    338:        printf("Authentication disabled\n");
                    339:     else
                    340:        printf("Authentication enabled\n");
                    341:
                    342:     mask = 0;
                    343:     for (ap = authenticators; ap->type; ap++) {
                    344:        if ((mask & (i = typemask(ap->type))) != 0)
                    345:            continue;
                    346:        mask |= i;
                    347:        printf("%s: %s\n", AUTHTYPE_NAME(ap->type),
                    348:               (i_wont_support & typemask(ap->type)) ?
                    349:               "disabled" : "enabled");
                    350:     }
                    351:     return(1);
                    352: }
                    353:
                    354: /*
                    355:  * This routine is called by the server to start authentication
                    356:  * negotiation.
                    357:  */
                    358: void
                    359: auth_request(void)
                    360: {
                    361:     static unsigned char str_request[64] = { IAC, SB,
                    362:                                             TELOPT_AUTHENTICATION,
                    363:                                             TELQUAL_SEND, };
                    364:     Authenticator *ap = authenticators;
                    365:     unsigned char *e = str_request + 4;
                    366:
                    367:     if (!authenticating) {
                    368:        authenticating = 1;
                    369:        while (ap->type) {
                    370:            if (i_support & ~i_wont_support & typemask(ap->type)) {
                    371:                if (auth_debug_mode) {
                    372:                    printf(">>>%s: Sending type %d %d\r\n",
                    373:                           Name, ap->type, ap->way);
                    374:                }
                    375:                *e++ = ap->type;
                    376:                *e++ = ap->way;
                    377:            }
                    378:            ++ap;
                    379:        }
                    380:        *e++ = IAC;
                    381:        *e++ = SE;
                    382:        telnet_net_write(str_request, e - str_request);
                    383:        printsub('>', &str_request[2], e - str_request - 2);
                    384:     }
                    385: }
                    386:
                    387: /*
                    388:  * This is called when an AUTH SEND is received.
                    389:  * It should never arrive on the server side (as only the server can
                    390:  * send an AUTH SEND).
                    391:  * You should probably respond to it if you can...
                    392:  *
                    393:  * If you want to respond to the types out of order (i.e. even
                    394:  * if he sends  LOGIN KERBEROS and you support both, you respond
                    395:  * with KERBEROS instead of LOGIN (which is against what the
                    396:  * protocol says)) you will have to hack this code...
                    397:  */
                    398: void
                    399: auth_send(unsigned char *data, int cnt)
                    400: {
                    401:     Authenticator *ap;
                    402:     static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION,
                    403:                                        TELQUAL_IS, AUTHTYPE_NULL, 0,
                    404:                                        IAC, SE };
                    405:     if (Server) {
                    406:        if (auth_debug_mode) {
                    407:            printf(">>>%s: auth_send called!\r\n", Name);
                    408:        }
                    409:        return;
                    410:     }
                    411:
                    412:     if (auth_debug_mode) {
                    413:        printf(">>>%s: auth_send got:", Name);
                    414:        printd(data, cnt); printf("\r\n");
                    415:     }
                    416:
                    417:     /*
                    418:      * Save the data, if it is new, so that we can continue looking
                    419:      * at it if the authorization we try doesn't work
                    420:      */
                    421:     if (data < _auth_send_data ||
                    422:        data > _auth_send_data + sizeof(_auth_send_data)) {
                    423:        auth_send_cnt = cnt > sizeof(_auth_send_data)
                    424:            ? sizeof(_auth_send_data)
                    425:            : cnt;
                    426:        memmove(_auth_send_data, data, auth_send_cnt);
                    427:        auth_send_data = _auth_send_data;
                    428:     } else {
                    429:        /*
                    430:         * This is probably a no-op, but we just make sure
                    431:         */
                    432:        auth_send_data = data;
                    433:        auth_send_cnt = cnt;
                    434:     }
                    435:     while ((auth_send_cnt -= 2) >= 0) {
                    436:        if (auth_debug_mode)
                    437:            printf(">>>%s: He supports %d\r\n",
                    438:                   Name, *auth_send_data);
                    439:        if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) {
                    440:            ap = findauthenticator(auth_send_data[0],
                    441:                                   auth_send_data[1]);
                    442:            if (ap && ap->send) {
                    443:                if (auth_debug_mode)
                    444:                    printf(">>>%s: Trying %d %d\r\n",
                    445:                           Name, auth_send_data[0],
                    446:                           auth_send_data[1]);
                    447:                if ((*ap->send)(ap)) {
                    448:                    /*
                    449:                     * Okay, we found one we like
                    450:                     * and did it.
                    451:                     * we can go home now.
                    452:                     */
                    453:                    if (auth_debug_mode)
                    454:                        printf(">>>%s: Using type %d\r\n",
                    455:                               Name, *auth_send_data);
                    456:                    auth_send_data += 2;
                    457:                    return;
                    458:                }
                    459:            }
                    460:            /* else
                    461:             *  just continue on and look for the
                    462:             *  next one if we didn't do anything.
                    463:             */
                    464:        }
                    465:        auth_send_data += 2;
                    466:     }
                    467:     telnet_net_write(str_none, sizeof(str_none));
                    468:     printsub('>', &str_none[2], sizeof(str_none) - 2);
                    469:     if (auth_debug_mode)
                    470:        printf(">>>%s: Sent failure message\r\n", Name);
                    471:     auth_finished(0, AUTH_REJECT);
                    472:     auth_has_failed = 1;
                    473: #ifdef KANNAN
                    474:     /*
                    475:      *  We requested strong authentication, however no mechanisms worked.
                    476:      *  Therefore, exit on client end.
                    477:      */
                    478:     printf("Unable to securely authenticate user ... exit\n");
                    479:     exit(0);
                    480: #endif /* KANNAN */
                    481: }
                    482:
                    483: void
                    484: auth_send_retry(void)
                    485: {
                    486:     /*
                    487:      * if auth_send_cnt <= 0 then auth_send will end up rejecting
                    488:      * the authentication and informing the other side of this.
                    489:         */
                    490:     auth_send(auth_send_data, auth_send_cnt);
                    491: }
                    492:
                    493: void
                    494: auth_is(unsigned char *data, int cnt)
                    495: {
                    496:     Authenticator *ap;
                    497:
                    498:     if (cnt < 2)
                    499:        return;
                    500:
                    501:     if (data[0] == AUTHTYPE_NULL) {
                    502:        auth_finished(0, AUTH_REJECT);
                    503:        return;
                    504:     }
                    505:
                    506:     if ((ap = findauthenticator(data[0], data[1]))) {
                    507:        if (ap->is)
                    508:            (*ap->is)(ap, data+2, cnt-2);
                    509:     } else if (auth_debug_mode)
                    510:        printf(">>>%s: Invalid authentication in IS: %d\r\n",
                    511:               Name, *data);
                    512: }
                    513:
                    514: void
                    515: auth_reply(unsigned char *data, int cnt)
                    516: {
                    517:     Authenticator *ap;
                    518:
                    519:     if (cnt < 2)
                    520:        return;
                    521:
                    522:     if ((ap = findauthenticator(data[0], data[1]))) {
                    523:        if (ap->reply)
                    524:            (*ap->reply)(ap, data+2, cnt-2);
                    525:     } else if (auth_debug_mode)
                    526:        printf(">>>%s: Invalid authentication in SEND: %d\r\n",
                    527:               Name, *data);
                    528: }
                    529:
                    530: void
                    531: auth_name(unsigned char *data, int cnt)
                    532: {
                    533:     char savename[256];
                    534:
                    535:     if (cnt < 1) {
                    536:        if (auth_debug_mode)
                    537:            printf(">>>%s: Empty name in NAME\r\n", Name);
                    538:        return;
                    539:     }
                    540:     if (cnt > sizeof(savename) - 1) {
                    541:        if (auth_debug_mode)
                    542:            printf(">>>%s: Name in NAME (%d) exceeds %lu length\r\n",
                    543:                   Name, cnt, (unsigned long)(sizeof(savename)-1));
                    544:        return;
                    545:     }
                    546:     memmove(savename, data, cnt);
                    547:     savename[cnt] = '\0';      /* Null terminate */
                    548:     if (auth_debug_mode)
                    549:        printf(">>>%s: Got NAME [%s]\r\n", Name, savename);
                    550:     auth_encrypt_user(savename);
                    551: }
                    552:
                    553: int
                    554: auth_sendname(unsigned char *cp, int len)
                    555: {
                    556:     static unsigned char str_request[256+6]
                    557:        = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, };
                    558:     unsigned char *e = str_request + 4;
                    559:     unsigned char *ee = &str_request[sizeof(str_request)-2];
                    560:
                    561:     while (--len >= 0) {
                    562:        if ((*e++ = *cp++) == IAC)
                    563:            *e++ = IAC;
                    564:        if (e >= ee)
                    565:            return(0);
                    566:     }
                    567:     *e++ = IAC;
                    568:     *e++ = SE;
                    569:     telnet_net_write(str_request, e - str_request);
                    570:     printsub('>', &str_request[2], e - &str_request[2]);
                    571:     return(1);
                    572: }
                    573:
                    574: void
                    575: auth_finished(Authenticator *ap, int result)
                    576: {
                    577:     if (!(authenticated = ap))
                    578:        authenticated = &NoAuth;
                    579:     validuser = result;
                    580: }
                    581:
                    582: /* ARGSUSED */
                    583: static void
                    584: auth_intr(int sig)
                    585: {
                    586:     auth_finished(0, AUTH_REJECT);
                    587: }
                    588:
                    589: int
                    590: auth_wait(char *name, size_t name_sz)
                    591: {
                    592:     if (auth_debug_mode)
                    593:        printf(">>>%s: in auth_wait.\r\n", Name);
                    594:
                    595:     if (Server && !authenticating)
                    596:        return(0);
                    597:
                    598:     signal(SIGALRM, auth_intr);
                    599:     alarm(30);
                    600:     while (!authenticated)
                    601:        if (telnet_spin())
                    602:            break;
                    603:     alarm(0);
                    604:     signal(SIGALRM, SIG_DFL);
                    605:
                    606:     /*
                    607:      * Now check to see if the user is valid or not
                    608:      */
                    609:     if (!authenticated || authenticated == &NoAuth)
                    610:        return(AUTH_REJECT);
                    611:
                    612:     if (validuser == AUTH_VALID)
                    613:        validuser = AUTH_USER;
                    614:
                    615:     if (authenticated->status)
                    616:        validuser = (*authenticated->status)(authenticated,
                    617:                                             name, name_sz,
                    618:                                             validuser);
                    619:     return(validuser);
                    620: }
                    621:
                    622: void
                    623: auth_debug(int mode)
                    624: {
                    625:     auth_debug_mode = mode;
                    626: }
                    627:
                    628: void
                    629: auth_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
                    630: {
                    631:     Authenticator *ap;
                    632:
                    633:     if ((ap = findauthenticator(data[1], data[2])) && ap->printsub)
                    634:        (*ap->printsub)(data, cnt, buf, buflen);
                    635:     else
                    636:        auth_gen_printsub(data, cnt, buf, buflen);
                    637: }
                    638:
                    639: void
                    640: auth_gen_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
                    641: {
                    642:     unsigned char *cp;
                    643:     unsigned char tbuf[16];
                    644:
                    645:     cnt -= 3;
                    646:     data += 3;
                    647:     buf[buflen-1] = '\0';
                    648:     buf[buflen-2] = '*';
                    649:     buflen -= 2;
                    650:     for (; cnt > 0; cnt--, data++) {
                    651:        snprintf(tbuf, sizeof(tbuf), " %d", *data);
                    652:        for (cp = tbuf; *cp && buflen > 0; --buflen)
                    653:            *buf++ = *cp++;
                    654:        if (buflen <= 0)
                    655:            return;
                    656:     }
                    657:     *buf = '\0';
                    658: }
                    659: #endif