146800Sdab /*- 246800Sdab * Copyright (c) 1991 The Regents of the University of California. 346800Sdab * All rights reserved. 446800Sdab * 546800Sdab * %sccs.include.redist.c% 646800Sdab */ 746800Sdab 846800Sdab #ifndef lint 9*60150Sdab static char sccsid[] = "@(#)auth.c 5.4 (Berkeley) 05/20/93"; 1046800Sdab #endif /* not lint */ 1146800Sdab 1246800Sdab /* 1346800Sdab * Copyright (C) 1990 by the Massachusetts Institute of Technology 1446800Sdab * 1546800Sdab * Export of this software from the United States of America is assumed 1646800Sdab * to require a specific license from the United States Government. 1746800Sdab * It is the responsibility of any person or organization contemplating 1846800Sdab * export to obtain such a license before exporting. 1946800Sdab * 2046800Sdab * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 2146800Sdab * distribute this software and its documentation for any purpose and 2246800Sdab * without fee is hereby granted, provided that the above copyright 2346800Sdab * notice appear in all copies and that both that copyright notice and 2446800Sdab * this permission notice appear in supporting documentation, and that 2546800Sdab * the name of M.I.T. not be used in advertising or publicity pertaining 2646800Sdab * to distribution of the software without specific, written prior 2746800Sdab * permission. M.I.T. makes no representations about the suitability of 2846800Sdab * this software for any purpose. It is provided "as is" without express 2946800Sdab * or implied warranty. 3046800Sdab */ 3146800Sdab 3246800Sdab 3357214Sdab #if defined(AUTHENTICATION) 3446800Sdab #include <stdio.h> 3546800Sdab #include <sys/types.h> 3646800Sdab #include <signal.h> 3746800Sdab #define AUTH_NAMES 3846800Sdab #include <arpa/telnet.h> 3946800Sdab #ifdef __STDC__ 4046800Sdab #include <stdlib.h> 4146800Sdab #endif 4246800Sdab #ifdef NO_STRING_H 4346800Sdab #include <strings.h> 4446800Sdab #else 4546800Sdab #include <string.h> 4646800Sdab #endif 4746800Sdab 4846800Sdab #include "encrypt.h" 4946800Sdab #include "auth.h" 5046800Sdab #include "misc-proto.h" 5146800Sdab #include "auth-proto.h" 5246800Sdab 5346800Sdab #define typemask(x) (1<<((x)-1)) 5446800Sdab 5557214Sdab #ifdef KRB4_ENCPWD 5657214Sdab extern krb4encpwd_init(); 5757214Sdab extern krb4encpwd_send(); 5857214Sdab extern krb4encpwd_is(); 5957214Sdab extern krb4encpwd_reply(); 6057214Sdab extern krb4encpwd_status(); 6157214Sdab extern krb4encpwd_printsub(); 6257214Sdab #endif 6357214Sdab 6457214Sdab #ifdef RSA_ENCPWD 6557214Sdab extern rsaencpwd_init(); 6657214Sdab extern rsaencpwd_send(); 6757214Sdab extern rsaencpwd_is(); 6857214Sdab extern rsaencpwd_reply(); 6957214Sdab extern rsaencpwd_status(); 7057214Sdab extern rsaencpwd_printsub(); 7157214Sdab #endif 7257214Sdab 7346800Sdab int auth_debug_mode = 0; 7446800Sdab static char *Name = "Noname"; 7546800Sdab static int Server = 0; 7646800Sdab static Authenticator *authenticated = 0; 7746800Sdab static int authenticating = 0; 7846800Sdab static int validuser = 0; 7946800Sdab static unsigned char _auth_send_data[256]; 8046800Sdab static unsigned char *auth_send_data; 8146800Sdab static int auth_send_cnt = 0; 8246800Sdab 8346800Sdab /* 8446800Sdab * Authentication types supported. Plese note that these are stored 8546800Sdab * in priority order, i.e. try the first one first. 8646800Sdab */ 8746800Sdab Authenticator authenticators[] = { 8857214Sdab #ifdef SPX 8957214Sdab { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 9057214Sdab spx_init, 9157214Sdab spx_send, 9257214Sdab spx_is, 9357214Sdab spx_reply, 9457214Sdab spx_status, 9557214Sdab spx_printsub }, 9657214Sdab { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 9757214Sdab spx_init, 9857214Sdab spx_send, 9957214Sdab spx_is, 10057214Sdab spx_reply, 10157214Sdab spx_status, 10257214Sdab spx_printsub }, 10357214Sdab #endif 10446800Sdab #ifdef KRB5 10557214Sdab # ifdef ENCRYPTION 10647612Sdab { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 10747612Sdab kerberos5_init, 10847612Sdab kerberos5_send, 10947612Sdab kerberos5_is, 11047612Sdab kerberos5_reply, 11147612Sdab kerberos5_status, 11247612Sdab kerberos5_printsub }, 113*60150Sdab # endif /* ENCRYPTION */ 11446800Sdab { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 11546800Sdab kerberos5_init, 11646800Sdab kerberos5_send, 11746800Sdab kerberos5_is, 11846800Sdab kerberos5_reply, 11946800Sdab kerberos5_status, 12046800Sdab kerberos5_printsub }, 12146800Sdab #endif 12246800Sdab #ifdef KRB4 12357214Sdab # ifdef ENCRYPTION 12447612Sdab { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 12547612Sdab kerberos4_init, 12647612Sdab kerberos4_send, 12747612Sdab kerberos4_is, 12847612Sdab kerberos4_reply, 12947612Sdab kerberos4_status, 13047612Sdab kerberos4_printsub }, 131*60150Sdab # endif /* ENCRYPTION */ 13246800Sdab { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 13346800Sdab kerberos4_init, 13446800Sdab kerberos4_send, 13546800Sdab kerberos4_is, 13646800Sdab kerberos4_reply, 13746800Sdab kerberos4_status, 13846800Sdab kerberos4_printsub }, 13946800Sdab #endif 14057214Sdab #ifdef KRB4_ENCPWD 14157214Sdab { AUTHTYPE_KRB4_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 14257214Sdab krb4encpwd_init, 14357214Sdab krb4encpwd_send, 14457214Sdab krb4encpwd_is, 14557214Sdab krb4encpwd_reply, 14657214Sdab krb4encpwd_status, 14757214Sdab krb4encpwd_printsub }, 14857214Sdab #endif 14957214Sdab #ifdef RSA_ENCPWD 15057214Sdab { AUTHTYPE_RSA_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 15157214Sdab rsaencpwd_init, 15257214Sdab rsaencpwd_send, 15357214Sdab rsaencpwd_is, 15457214Sdab rsaencpwd_reply, 15557214Sdab rsaencpwd_status, 15657214Sdab rsaencpwd_printsub }, 15757214Sdab #endif 15846800Sdab { 0, }, 15946800Sdab }; 16046800Sdab 16146800Sdab static Authenticator NoAuth = { 0 }; 16246800Sdab 16346800Sdab static int i_support = 0; 16446800Sdab static int i_wont_support = 0; 16546800Sdab 16646800Sdab Authenticator * 16746800Sdab findauthenticator(type, way) 16846800Sdab int type; 16946800Sdab int way; 17046800Sdab { 17146800Sdab Authenticator *ap = authenticators; 17246800Sdab 17346800Sdab while (ap->type && (ap->type != type || ap->way != way)) 17446800Sdab ++ap; 17546800Sdab return(ap->type ? ap : 0); 17646800Sdab } 17746800Sdab 17846800Sdab void 17946800Sdab auth_init(name, server) 18046800Sdab char *name; 18146800Sdab int server; 18246800Sdab { 18346800Sdab Authenticator *ap = authenticators; 18446800Sdab 18546800Sdab Server = server; 18646800Sdab Name = name; 18746800Sdab 18846800Sdab i_support = 0; 18946800Sdab authenticated = 0; 19046800Sdab authenticating = 0; 19146800Sdab while (ap->type) { 19246800Sdab if (!ap->init || (*ap->init)(ap, server)) { 19346800Sdab i_support |= typemask(ap->type); 19446800Sdab if (auth_debug_mode) 19547612Sdab printf(">>>%s: I support auth type %d %d\r\n", 19646800Sdab Name, 19747612Sdab ap->type, ap->way); 19846800Sdab } 19946800Sdab ++ap; 20046800Sdab } 20146800Sdab } 20246800Sdab 20346800Sdab void 20446800Sdab auth_disable_name(name) 20546800Sdab char *name; 20646800Sdab { 20746800Sdab int x; 20846800Sdab for (x = 0; x < AUTHTYPE_CNT; ++x) { 20946800Sdab if (!strcasecmp(name, AUTHTYPE_NAME(x))) { 21046800Sdab i_wont_support |= typemask(x); 21146800Sdab break; 21246800Sdab } 21346800Sdab } 21446800Sdab } 21546800Sdab 21646800Sdab int 21746800Sdab getauthmask(type, maskp) 21846800Sdab char *type; 21946800Sdab int *maskp; 22046800Sdab { 22146800Sdab register int x; 22246800Sdab 22346800Sdab if (strcasecmp(type, AUTHTYPE_NAME(0))) { 22446800Sdab *maskp = -1; 22546800Sdab return(1); 22646800Sdab } 22746800Sdab 22846800Sdab for (x = 1; x < AUTHTYPE_CNT; ++x) { 22946800Sdab if (!strcasecmp(type, AUTHTYPE_NAME(x))) { 23046800Sdab *maskp = typemask(x); 23146800Sdab return(1); 23246800Sdab } 23346800Sdab } 23446800Sdab return(0); 23546800Sdab } 23646800Sdab 23746800Sdab int 23846800Sdab auth_enable(type) 23946800Sdab int type; 24046800Sdab { 24146800Sdab return(auth_onoff(type, 1)); 24246800Sdab } 24346800Sdab 24446800Sdab int 24546800Sdab auth_disable(type) 24646800Sdab int type; 24746800Sdab { 24846800Sdab return(auth_onoff(type, 0)); 24946800Sdab } 25046800Sdab 25146800Sdab int 25246800Sdab auth_onoff(type, on) 25346800Sdab char *type; 25446800Sdab int on; 25546800Sdab { 25646800Sdab int mask = -1; 25746800Sdab Authenticator *ap; 25846800Sdab 25946800Sdab if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) { 26046800Sdab printf("auth %s 'type'\n", on ? "enable" : "disable"); 26146800Sdab printf("Where 'type' is one of:\n"); 26246800Sdab printf("\t%s\n", AUTHTYPE_NAME(0)); 26346800Sdab for (ap = authenticators; ap->type; ap++) 26446800Sdab printf("\t%s\n", AUTHTYPE_NAME(ap->type)); 26546800Sdab return(0); 26646800Sdab } 26746800Sdab 26846800Sdab if (!getauthmask(type, &mask)) { 26946800Sdab printf("%s: invalid authentication type\n", type); 27046800Sdab return(0); 27146800Sdab } 27246800Sdab mask = getauthmask(type, &mask); 27346800Sdab if (on) 27446800Sdab i_wont_support &= ~mask; 27546800Sdab else 27646800Sdab i_wont_support |= mask; 27746800Sdab return(1); 27846800Sdab } 27946800Sdab 28046800Sdab int 28147612Sdab auth_togdebug(on) 28247612Sdab int on; 28346800Sdab { 28447612Sdab if (on < 0) 28547612Sdab auth_debug_mode ^= 1; 28647612Sdab else 28747612Sdab auth_debug_mode = on; 28846800Sdab printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled"); 28946800Sdab return(1); 29046800Sdab } 29146800Sdab 29246800Sdab int 29346800Sdab auth_status() 29446800Sdab { 29546800Sdab Authenticator *ap; 29646800Sdab 29746800Sdab if (i_wont_support == -1) 29846800Sdab printf("Authentication disabled\n"); 29946800Sdab else 30046800Sdab printf("Authentication enabled\n"); 30146800Sdab 30246800Sdab for (ap = authenticators; ap->type; ap++) 30346800Sdab printf("%s: %s\n", AUTHTYPE_NAME(ap->type), 30446800Sdab (i_wont_support & typemask(ap->type)) ? 30546800Sdab "disabled" : "enabled"); 30646800Sdab return(1); 30746800Sdab } 30846800Sdab 30946800Sdab /* 31046800Sdab * This routine is called by the server to start authentication 31146800Sdab * negotiation. 31246800Sdab */ 31346800Sdab void 31446800Sdab auth_request() 31546800Sdab { 31646800Sdab static unsigned char str_request[64] = { IAC, SB, 31746800Sdab TELOPT_AUTHENTICATION, 31846800Sdab TELQUAL_SEND, }; 31946800Sdab Authenticator *ap = authenticators; 32046800Sdab unsigned char *e = str_request + 4; 32146800Sdab 32246800Sdab if (!authenticating) { 32346800Sdab authenticating = 1; 32446800Sdab while (ap->type) { 32546800Sdab if (i_support & ~i_wont_support & typemask(ap->type)) { 32646800Sdab if (auth_debug_mode) { 32747612Sdab printf(">>>%s: Sending type %d %d\r\n", 32847612Sdab Name, ap->type, ap->way); 32946800Sdab } 33046800Sdab *e++ = ap->type; 33146800Sdab *e++ = ap->way; 33246800Sdab } 33346800Sdab ++ap; 33446800Sdab } 33546800Sdab *e++ = IAC; 33646800Sdab *e++ = SE; 33746800Sdab net_write(str_request, e - str_request); 33846800Sdab printsub('>', &str_request[2], e - str_request - 2); 33946800Sdab } 34046800Sdab } 34146800Sdab 34246800Sdab /* 34346800Sdab * This is called when an AUTH SEND is received. 34446800Sdab * It should never arrive on the server side (as only the server can 34546800Sdab * send an AUTH SEND). 34646800Sdab * You should probably respond to it if you can... 34746800Sdab * 34846800Sdab * If you want to respond to the types out of order (i.e. even 34946800Sdab * if he sends LOGIN KERBEROS and you support both, you respond 35046800Sdab * with KERBEROS instead of LOGIN (which is against what the 35146800Sdab * protocol says)) you will have to hack this code... 35246800Sdab */ 35346800Sdab void 35446800Sdab auth_send(data, cnt) 35546800Sdab unsigned char *data; 35646800Sdab int cnt; 35746800Sdab { 35846800Sdab Authenticator *ap; 35946800Sdab static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION, 36046800Sdab TELQUAL_IS, AUTHTYPE_NULL, 0, 36146800Sdab IAC, SE }; 36246800Sdab if (Server) { 36346800Sdab if (auth_debug_mode) { 36446800Sdab printf(">>>%s: auth_send called!\r\n", Name); 36546800Sdab } 36646800Sdab return; 36746800Sdab } 36846800Sdab 36946800Sdab if (auth_debug_mode) { 37046800Sdab printf(">>>%s: auth_send got:", Name); 37146800Sdab printd(data, cnt); printf("\r\n"); 37246800Sdab } 37346800Sdab 37446800Sdab /* 37546800Sdab * Save the data, if it is new, so that we can continue looking 37646800Sdab * at it if the authorization we try doesn't work 37746800Sdab */ 37846800Sdab if (data < _auth_send_data || 37946800Sdab data > _auth_send_data + sizeof(_auth_send_data)) { 38046800Sdab auth_send_cnt = cnt > sizeof(_auth_send_data) 38146800Sdab ? sizeof(_auth_send_data) 38246800Sdab : cnt; 38346800Sdab bcopy((void *)data, (void *)_auth_send_data, auth_send_cnt); 38446800Sdab auth_send_data = _auth_send_data; 38546800Sdab } else { 38646800Sdab /* 38746800Sdab * This is probably a no-op, but we just make sure 38846800Sdab */ 38946800Sdab auth_send_data = data; 39046800Sdab auth_send_cnt = cnt; 39146800Sdab } 39246800Sdab while ((auth_send_cnt -= 2) >= 0) { 39346800Sdab if (auth_debug_mode) 39446800Sdab printf(">>>%s: He supports %d\r\n", 39546800Sdab Name, *auth_send_data); 39646800Sdab if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) { 39746800Sdab ap = findauthenticator(auth_send_data[0], 39846800Sdab auth_send_data[1]); 39957214Sdab if (ap && ap->send) { 40046800Sdab if (auth_debug_mode) 40147612Sdab printf(">>>%s: Trying %d %d\r\n", 40247612Sdab Name, auth_send_data[0], 40347612Sdab auth_send_data[1]); 40446800Sdab if ((*ap->send)(ap)) { 40546800Sdab /* 40646800Sdab * Okay, we found one we like 40746800Sdab * and did it. 40846800Sdab * we can go home now. 40946800Sdab */ 41046800Sdab if (auth_debug_mode) 41146800Sdab printf(">>>%s: Using type %d\r\n", 41246800Sdab Name, *auth_send_data); 41346800Sdab auth_send_data += 2; 41446800Sdab return; 41546800Sdab } 41646800Sdab } 41746800Sdab /* else 41846800Sdab * just continue on and look for the 41946800Sdab * next one if we didn't do anything. 42046800Sdab */ 42146800Sdab } 42246800Sdab auth_send_data += 2; 42346800Sdab } 42446800Sdab net_write(str_none, sizeof(str_none)); 42546800Sdab printsub('>', &str_none[2], sizeof(str_none) - 2); 42646800Sdab if (auth_debug_mode) 42746800Sdab printf(">>>%s: Sent failure message\r\n", Name); 42846800Sdab auth_finished(0, AUTH_REJECT); 42957214Sdab #ifdef KANNAN 43057214Sdab /* 43157214Sdab * We requested strong authentication, however no mechanisms worked. 43257214Sdab * Therefore, exit on client end. 43357214Sdab */ 43457214Sdab printf("Unable to securely authenticate user ... exit\n"); 43557214Sdab exit(0); 43657214Sdab #endif /* KANNAN */ 43746800Sdab } 43846800Sdab 43946800Sdab void 44046800Sdab auth_send_retry() 44146800Sdab { 44246800Sdab /* 44346800Sdab * if auth_send_cnt <= 0 then auth_send will end up rejecting 44446800Sdab * the authentication and informing the other side of this. 44546800Sdab */ 44646800Sdab auth_send(auth_send_data, auth_send_cnt); 44746800Sdab } 44846800Sdab 44946800Sdab void 45046800Sdab auth_is(data, cnt) 45146800Sdab unsigned char *data; 45246800Sdab int cnt; 45346800Sdab { 45446800Sdab Authenticator *ap; 45546800Sdab 45646800Sdab if (cnt < 2) 45746800Sdab return; 45846800Sdab 45946800Sdab if (data[0] == AUTHTYPE_NULL) { 46046800Sdab auth_finished(0, AUTH_REJECT); 46146800Sdab return; 46246800Sdab } 46346800Sdab 46446800Sdab if (ap = findauthenticator(data[0], data[1])) { 46546800Sdab if (ap->is) 46646800Sdab (*ap->is)(ap, data+2, cnt-2); 46746800Sdab } else if (auth_debug_mode) 46846800Sdab printf(">>>%s: Invalid authentication in IS: %d\r\n", 46946800Sdab Name, *data); 47046800Sdab } 47146800Sdab 47246800Sdab void 47346800Sdab auth_reply(data, cnt) 47446800Sdab unsigned char *data; 47546800Sdab int cnt; 47646800Sdab { 47746800Sdab Authenticator *ap; 47846800Sdab 47946800Sdab if (cnt < 2) 48046800Sdab return; 48146800Sdab 48246800Sdab if (ap = findauthenticator(data[0], data[1])) { 48346800Sdab if (ap->reply) 48446800Sdab (*ap->reply)(ap, data+2, cnt-2); 48546800Sdab } else if (auth_debug_mode) 48646800Sdab printf(">>>%s: Invalid authentication in SEND: %d\r\n", 48746800Sdab Name, *data); 48846800Sdab } 48946800Sdab 49046800Sdab void 49147612Sdab auth_name(data, cnt) 49247612Sdab unsigned char *data; 49347612Sdab int cnt; 49447612Sdab { 49547612Sdab Authenticator *ap; 49647612Sdab unsigned char savename[256]; 49747612Sdab 49847612Sdab if (cnt < 1) { 49947612Sdab if (auth_debug_mode) 50047612Sdab printf(">>>%s: Empty name in NAME\r\n", Name); 50147612Sdab return; 50247612Sdab } 50347612Sdab if (cnt > sizeof(savename) - 1) { 50447612Sdab if (auth_debug_mode) 50547612Sdab printf(">>>%s: Name in NAME (%d) exceeds %d length\r\n", 50647612Sdab Name, cnt, sizeof(savename)-1); 50747612Sdab return; 50847612Sdab } 50947612Sdab bcopy((void *)data, (void *)savename, cnt); 51047612Sdab savename[cnt] = '\0'; /* Null terminate */ 51147612Sdab if (auth_debug_mode) 51247612Sdab printf(">>>%s: Got NAME [%s]\r\n", Name, savename); 51347612Sdab auth_encrypt_user(savename); 51447612Sdab } 51547612Sdab 51647612Sdab int 51747612Sdab auth_sendname(cp, len) 51847612Sdab unsigned char *cp; 51947612Sdab int len; 52047612Sdab { 52147612Sdab static unsigned char str_request[256+6] 52247612Sdab = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, }; 52347612Sdab register unsigned char *e = str_request + 4; 52447612Sdab register unsigned char *ee = &str_request[sizeof(str_request)-2]; 52547612Sdab 52647612Sdab while (--len >= 0) { 52747612Sdab if ((*e++ = *cp++) == IAC) 52847612Sdab *e++ = IAC; 52947612Sdab if (e >= ee) 53047612Sdab return(0); 53147612Sdab } 53247612Sdab *e++ = IAC; 53347612Sdab *e++ = SE; 53447612Sdab net_write(str_request, e - str_request); 53547612Sdab printsub('>', &str_request[2], e - &str_request[2]); 53647612Sdab return(1); 53747612Sdab } 53847612Sdab 53947612Sdab void 54046800Sdab auth_finished(ap, result) 54146800Sdab Authenticator *ap; 54246800Sdab int result; 54346800Sdab { 54446800Sdab if (!(authenticated = ap)) 54546800Sdab authenticated = &NoAuth; 54646800Sdab validuser = result; 54746800Sdab } 54846800Sdab 54946800Sdab /* ARGSUSED */ 55046800Sdab static void 55146800Sdab auth_intr(sig) 55246800Sdab int sig; 55346800Sdab { 55446800Sdab auth_finished(0, AUTH_REJECT); 55546800Sdab } 55646800Sdab 55746800Sdab int 55846800Sdab auth_wait(name) 55946800Sdab char *name; 56046800Sdab { 56146800Sdab if (auth_debug_mode) 56246800Sdab printf(">>>%s: in auth_wait.\r\n", Name); 56346800Sdab 56446800Sdab if (Server && !authenticating) 56546800Sdab return(0); 56646800Sdab 56746800Sdab (void) signal(SIGALRM, auth_intr); 56846800Sdab alarm(30); 56946800Sdab while (!authenticated) 57046800Sdab if (telnet_spin()) 57146800Sdab break; 57246800Sdab alarm(0); 57346800Sdab (void) signal(SIGALRM, SIG_DFL); 57446800Sdab 57546800Sdab /* 57646800Sdab * Now check to see if the user is valid or not 57746800Sdab */ 57846800Sdab if (!authenticated || authenticated == &NoAuth) 57946800Sdab return(AUTH_REJECT); 58046800Sdab 58146800Sdab if (validuser == AUTH_VALID) 58246800Sdab validuser = AUTH_USER; 58346800Sdab 58446800Sdab if (authenticated->status) 58546800Sdab validuser = (*authenticated->status)(authenticated, 58646800Sdab name, validuser); 58746800Sdab return(validuser); 58846800Sdab } 58946800Sdab 59046800Sdab void 59146800Sdab auth_debug(mode) 59246800Sdab int mode; 59346800Sdab { 59446800Sdab auth_debug_mode = mode; 59546800Sdab } 59646800Sdab 59746800Sdab void 59846800Sdab auth_printsub(data, cnt, buf, buflen) 59946800Sdab unsigned char *data, *buf; 60046800Sdab int cnt, buflen; 60146800Sdab { 60246800Sdab Authenticator *ap; 60346800Sdab 60446800Sdab if ((ap = findauthenticator(data[1], data[2])) && ap->printsub) 60546800Sdab (*ap->printsub)(data, cnt, buf, buflen); 60646800Sdab else 60746800Sdab auth_gen_printsub(data, cnt, buf, buflen); 60846800Sdab } 60946800Sdab 61046800Sdab void 61146800Sdab auth_gen_printsub(data, cnt, buf, buflen) 61246800Sdab unsigned char *data, *buf; 61346800Sdab int cnt, buflen; 61446800Sdab { 61546800Sdab register unsigned char *cp; 61646800Sdab unsigned char tbuf[16]; 61746800Sdab 61846800Sdab cnt -= 3; 61946800Sdab data += 3; 62046800Sdab buf[buflen-1] = '\0'; 62146800Sdab buf[buflen-2] = '*'; 62246800Sdab buflen -= 2; 62346800Sdab for (; cnt > 0; cnt--, data++) { 62446800Sdab sprintf((char *)tbuf, " %d", *data); 62546800Sdab for (cp = tbuf; *cp && buflen > 0; --buflen) 62646800Sdab *buf++ = *cp++; 62746800Sdab if (buflen <= 0) 62846800Sdab return; 62946800Sdab } 63046800Sdab *buf = '\0'; 63146800Sdab } 63246800Sdab #endif 633