129088Smarkm/*- 229088Smarkm * Copyright (c) 1991, 1993 329088Smarkm * The Regents of the University of California. All rights reserved. 429088Smarkm * 529088Smarkm * Redistribution and use in source and binary forms, with or without 629088Smarkm * modification, are permitted provided that the following conditions 729088Smarkm * are met: 829088Smarkm * 1. Redistributions of source code must retain the above copyright 929088Smarkm * notice, this list of conditions and the following disclaimer. 1029088Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1129088Smarkm * notice, this list of conditions and the following disclaimer in the 1229088Smarkm * documentation and/or other materials provided with the distribution. 1329088Smarkm * 3. All advertising materials mentioning features or use of this software 1429088Smarkm * must display the following acknowledgement: 1529088Smarkm * This product includes software developed by the University of 1629088Smarkm * California, Berkeley and its contributors. 1729088Smarkm * 4. Neither the name of the University nor the names of its contributors 1829088Smarkm * may be used to endorse or promote products derived from this software 1929088Smarkm * without specific prior written permission. 2029088Smarkm * 2129088Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2229088Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2329088Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2429088Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2529088Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2629088Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2729088Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2829088Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2929088Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3029088Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3129088Smarkm * SUCH DAMAGE. 3262958Snsayer * 3329088Smarkm */ 3429088Smarkm 35114630Sobrien#if 0 3629088Smarkm#ifndef lint 3729181Smarkmstatic const char sccsid[] = "@(#)auth.c 8.3 (Berkeley) 5/30/95"; 3829088Smarkm#endif /* not lint */ 39114630Sobrien#endif 40114630Sobrien#include <sys/cdefs.h> 41114630Sobrien__FBSDID("$FreeBSD$"); 4229088Smarkm 43114630Sobrien 4429088Smarkm/* 4529088Smarkm * Copyright (C) 1990 by the Massachusetts Institute of Technology 4629088Smarkm * 4729088Smarkm * Export of this software from the United States of America is assumed 4829088Smarkm * to require a specific license from the United States Government. 4929088Smarkm * It is the responsibility of any person or organization contemplating 5029088Smarkm * export to obtain such a license before exporting. 5129088Smarkm * 5229088Smarkm * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 5329088Smarkm * distribute this software and its documentation for any purpose and 5429088Smarkm * without fee is hereby granted, provided that the above copyright 5529088Smarkm * notice appear in all copies and that both that copyright notice and 5629088Smarkm * this permission notice appear in supporting documentation, and that 5729088Smarkm * the name of M.I.T. not be used in advertising or publicity pertaining 5829088Smarkm * to distribution of the software without specific, written prior 5929088Smarkm * permission. M.I.T. makes no representations about the suitability of 6029088Smarkm * this software for any purpose. It is provided "as is" without express 6129088Smarkm * or implied warranty. 6229088Smarkm */ 6329088Smarkm 6429088Smarkm 6587139Smarkm#ifdef AUTHENTICATION 6687139Smarkm#define AUTH_NAMES 6729088Smarkm#include <sys/types.h> 6829088Smarkm#include <signal.h> 6987139Smarkm#include <stdio.h> 7029088Smarkm#include <stdlib.h> 7187139Smarkm#include <string.h> 7229181Smarkm#include <unistd.h> 7387139Smarkm#include <arpa/telnet.h> 7429088Smarkm 7529088Smarkm#include "encrypt.h" 7629088Smarkm#include "auth.h" 7729088Smarkm#include "misc-proto.h" 7829088Smarkm#include "auth-proto.h" 7929088Smarkm 8087139Smarkm#define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 8129088Smarkm 8229088Smarkm#ifdef KRB4_ENCPWD 8329088Smarkmextern krb4encpwd_init(); 8429088Smarkmextern krb4encpwd_send(); 8529088Smarkmextern krb4encpwd_is(); 8629088Smarkmextern krb4encpwd_reply(); 8729088Smarkmextern krb4encpwd_status(); 8829088Smarkmextern krb4encpwd_printsub(); 8929088Smarkm#endif 9029088Smarkm 9129088Smarkm#ifdef RSA_ENCPWD 9229088Smarkmextern rsaencpwd_init(); 9329088Smarkmextern rsaencpwd_send(); 9429088Smarkmextern rsaencpwd_is(); 9529088Smarkmextern rsaencpwd_reply(); 9629088Smarkmextern rsaencpwd_status(); 9729088Smarkmextern rsaencpwd_printsub(); 9829088Smarkm#endif 9929088Smarkm 10029088Smarkmint auth_debug_mode = 0; 10187139Smarkmstatic const char *Name = "Noname"; 10229088Smarkmstatic int Server = 0; 10329088Smarkmstatic Authenticator *authenticated = 0; 10429088Smarkmstatic int authenticating = 0; 10529088Smarkmstatic int validuser = 0; 10629088Smarkmstatic unsigned char _auth_send_data[256]; 10729088Smarkmstatic unsigned char *auth_send_data; 10829088Smarkmstatic int auth_send_cnt = 0; 10929088Smarkm 11029181Smarkmint auth_onoff(char *type, int on); 11129181Smarkmvoid auth_encrypt_user(char *name); 11229181Smarkm 11329088Smarkm/* 11429088Smarkm * Authentication types supported. Plese note that these are stored 11529088Smarkm * in priority order, i.e. try the first one first. 11629088Smarkm */ 11729088SmarkmAuthenticator authenticators[] = { 11829088Smarkm#ifdef KRB5 11929088Smarkm# ifdef ENCRYPTION 12029088Smarkm { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 12129088Smarkm kerberos5_init, 12287139Smarkm kerberos5_send_mutual, 12329088Smarkm kerberos5_is, 12429088Smarkm kerberos5_reply, 12529088Smarkm kerberos5_status, 12629088Smarkm kerberos5_printsub }, 12729088Smarkm# endif /* ENCRYPTION */ 12829088Smarkm { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 12929088Smarkm kerberos5_init, 13087139Smarkm kerberos5_send_oneway, 13129088Smarkm kerberos5_is, 13229088Smarkm kerberos5_reply, 13329088Smarkm kerberos5_status, 13429088Smarkm kerberos5_printsub }, 13529088Smarkm#endif 13629088Smarkm#ifdef KRB4 13729088Smarkm# ifdef ENCRYPTION 13829088Smarkm { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 13929088Smarkm kerberos4_init, 14029088Smarkm kerberos4_send, 14129088Smarkm kerberos4_is, 14229088Smarkm kerberos4_reply, 14329088Smarkm kerberos4_status, 14429088Smarkm kerberos4_printsub }, 14529088Smarkm# endif /* ENCRYPTION */ 14629088Smarkm { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 14729088Smarkm kerberos4_init, 14829088Smarkm kerberos4_send, 14929088Smarkm kerberos4_is, 15029088Smarkm kerberos4_reply, 15129088Smarkm kerberos4_status, 15229088Smarkm kerberos4_printsub }, 15329088Smarkm#endif 15429088Smarkm#ifdef KRB4_ENCPWD 15529088Smarkm { AUTHTYPE_KRB4_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 15629088Smarkm krb4encpwd_init, 15729088Smarkm krb4encpwd_send, 15829088Smarkm krb4encpwd_is, 15929088Smarkm krb4encpwd_reply, 16029088Smarkm krb4encpwd_status, 16129088Smarkm krb4encpwd_printsub }, 16229088Smarkm#endif 16329088Smarkm#ifdef RSA_ENCPWD 16429088Smarkm { AUTHTYPE_RSA_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 16529088Smarkm rsaencpwd_init, 16629088Smarkm rsaencpwd_send, 16729088Smarkm rsaencpwd_is, 16829088Smarkm rsaencpwd_reply, 16929088Smarkm rsaencpwd_status, 17029088Smarkm rsaencpwd_printsub }, 17129088Smarkm#endif 17249887Snsayer#ifdef SRA 17349887Snsayer { AUTHTYPE_SRA, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 17449887Snsayer sra_init, 17549887Snsayer sra_send, 17649887Snsayer sra_is, 17749887Snsayer sra_reply, 17849887Snsayer sra_status, 17949887Snsayer sra_printsub }, 18049887Snsayer 18149887Snsayer#endif 18287139Smarkm { 0, 0, 0, 0, 0, 0, 0, 0 }, 18329088Smarkm}; 18429088Smarkm 18587139Smarkmstatic Authenticator NoAuth = { 0, 0, 0, 0, 0, 0, 0, 0 }; 18629088Smarkm 18729088Smarkmstatic int i_support = 0; 18829088Smarkmstatic int i_wont_support = 0; 18929088Smarkm 19087139SmarkmAuthenticator * 19187139Smarkmfindauthenticator(int type, int way) 19229088Smarkm{ 19329088Smarkm Authenticator *ap = authenticators; 19429088Smarkm 19529088Smarkm while (ap->type && (ap->type != type || ap->way != way)) 19629088Smarkm ++ap; 19729088Smarkm return(ap->type ? ap : 0); 19829088Smarkm} 19929088Smarkm 20087139Smarkmvoid 20187139Smarkmauth_init(const char *name, int server) 20229088Smarkm{ 20329088Smarkm Authenticator *ap = authenticators; 20429088Smarkm 20529088Smarkm Server = server; 20629088Smarkm Name = name; 20729088Smarkm 20829088Smarkm i_support = 0; 20929088Smarkm authenticated = 0; 21029088Smarkm authenticating = 0; 21129088Smarkm while (ap->type) { 21229088Smarkm if (!ap->init || (*ap->init)(ap, server)) { 21329088Smarkm i_support |= typemask(ap->type); 21429088Smarkm if (auth_debug_mode) 21529088Smarkm printf(">>>%s: I support auth type %d %d\r\n", 21629088Smarkm Name, 21729088Smarkm ap->type, ap->way); 21829088Smarkm } 21929088Smarkm else if (auth_debug_mode) 22029088Smarkm printf(">>>%s: Init failed: auth type %d %d\r\n", 22129088Smarkm Name, ap->type, ap->way); 22229088Smarkm ++ap; 22329088Smarkm } 22429088Smarkm} 22529088Smarkm 22687139Smarkmvoid 22787139Smarkmauth_disable_name(char *name) 22829088Smarkm{ 22929088Smarkm int x; 23029088Smarkm for (x = 0; x < AUTHTYPE_CNT; ++x) { 23162958Snsayer if (AUTHTYPE_NAME(x) && !strcasecmp(name, AUTHTYPE_NAME(x))) { 23229088Smarkm i_wont_support |= typemask(x); 23329088Smarkm break; 23429088Smarkm } 23529088Smarkm } 23629088Smarkm} 23729088Smarkm 23887139Smarkmint 23987139Smarkmgetauthmask(char *type, int *maskp) 24029088Smarkm{ 24187139Smarkm int x; 24229088Smarkm 24374411Snsayer if (AUTHTYPE_NAME(0) && !strcasecmp(type, AUTHTYPE_NAME(0))) { 24429088Smarkm *maskp = -1; 24529088Smarkm return(1); 24629088Smarkm } 24729088Smarkm 24829088Smarkm for (x = 1; x < AUTHTYPE_CNT; ++x) { 24974411Snsayer if (AUTHTYPE_NAME(x) && !strcasecmp(type, AUTHTYPE_NAME(x))) { 25029088Smarkm *maskp = typemask(x); 25129088Smarkm return(1); 25229088Smarkm } 25329088Smarkm } 25429088Smarkm return(0); 25529088Smarkm} 25629088Smarkm 25787139Smarkmint 25887139Smarkmauth_enable(char *type) 25929088Smarkm{ 26029088Smarkm return(auth_onoff(type, 1)); 26129088Smarkm} 26229088Smarkm 26387139Smarkmint 26487139Smarkmauth_disable(char *type) 26529088Smarkm{ 26629088Smarkm return(auth_onoff(type, 0)); 26729088Smarkm} 26829088Smarkm 26987139Smarkmint 27087139Smarkmauth_onoff(char *type, int on) 27129088Smarkm{ 27229088Smarkm int i, mask = -1; 27329088Smarkm Authenticator *ap; 27429088Smarkm 27529088Smarkm if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) { 27629088Smarkm printf("auth %s 'type'\n", on ? "enable" : "disable"); 27729088Smarkm printf("Where 'type' is one of:\n"); 27829088Smarkm printf("\t%s\n", AUTHTYPE_NAME(0)); 27929088Smarkm mask = 0; 28029088Smarkm for (ap = authenticators; ap->type; ap++) { 28129088Smarkm if ((mask & (i = typemask(ap->type))) != 0) 28229088Smarkm continue; 28329088Smarkm mask |= i; 28429088Smarkm printf("\t%s\n", AUTHTYPE_NAME(ap->type)); 28529088Smarkm } 28629088Smarkm return(0); 28729088Smarkm } 28829088Smarkm 28929088Smarkm if (!getauthmask(type, &mask)) { 29029088Smarkm printf("%s: invalid authentication type\n", type); 29129088Smarkm return(0); 29229088Smarkm } 29329088Smarkm if (on) 29429088Smarkm i_wont_support &= ~mask; 29529088Smarkm else 29629088Smarkm i_wont_support |= mask; 29729088Smarkm return(1); 29829088Smarkm} 29929088Smarkm 30087139Smarkmint 30187139Smarkmauth_togdebug(int on) 30229088Smarkm{ 30329088Smarkm if (on < 0) 30429088Smarkm auth_debug_mode ^= 1; 30529088Smarkm else 30629088Smarkm auth_debug_mode = on; 30729088Smarkm printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled"); 30829088Smarkm return(1); 30929088Smarkm} 31029088Smarkm 31187139Smarkmint 31287139Smarkmauth_status(void) 31329088Smarkm{ 31429088Smarkm Authenticator *ap; 31529088Smarkm int i, mask; 31629088Smarkm 31729088Smarkm if (i_wont_support == -1) 31829088Smarkm printf("Authentication disabled\n"); 31929088Smarkm else 32029088Smarkm printf("Authentication enabled\n"); 32129088Smarkm 32229088Smarkm mask = 0; 32329088Smarkm for (ap = authenticators; ap->type; ap++) { 32429088Smarkm if ((mask & (i = typemask(ap->type))) != 0) 32529088Smarkm continue; 32629088Smarkm mask |= i; 32729088Smarkm printf("%s: %s\n", AUTHTYPE_NAME(ap->type), 32829088Smarkm (i_wont_support & typemask(ap->type)) ? 32929088Smarkm "disabled" : "enabled"); 33029088Smarkm } 33129088Smarkm return(1); 33229088Smarkm} 33329088Smarkm 33429088Smarkm/* 33529088Smarkm * This routine is called by the server to start authentication 33629088Smarkm * negotiation. 33729088Smarkm */ 33887139Smarkmvoid 33987139Smarkmauth_request(void) 34029088Smarkm{ 34129088Smarkm static unsigned char str_request[64] = { IAC, SB, 34229088Smarkm TELOPT_AUTHENTICATION, 34329088Smarkm TELQUAL_SEND, }; 34429088Smarkm Authenticator *ap = authenticators; 34529088Smarkm unsigned char *e = str_request + 4; 34629088Smarkm 34729088Smarkm if (!authenticating) { 34829088Smarkm authenticating = 1; 34929088Smarkm while (ap->type) { 35029088Smarkm if (i_support & ~i_wont_support & typemask(ap->type)) { 35129088Smarkm if (auth_debug_mode) { 35229088Smarkm printf(">>>%s: Sending type %d %d\r\n", 35329088Smarkm Name, ap->type, ap->way); 35429088Smarkm } 35529088Smarkm *e++ = ap->type; 35629088Smarkm *e++ = ap->way; 35729088Smarkm } 35829088Smarkm ++ap; 35929088Smarkm } 36029088Smarkm *e++ = IAC; 36129088Smarkm *e++ = SE; 36229088Smarkm net_write(str_request, e - str_request); 36329088Smarkm printsub('>', &str_request[2], e - str_request - 2); 36429088Smarkm } 36529088Smarkm} 36629088Smarkm 36729088Smarkm/* 36829088Smarkm * This is called when an AUTH SEND is received. 36929088Smarkm * It should never arrive on the server side (as only the server can 37029088Smarkm * send an AUTH SEND). 37129088Smarkm * You should probably respond to it if you can... 37229088Smarkm * 37329088Smarkm * If you want to respond to the types out of order (i.e. even 37429088Smarkm * if he sends LOGIN KERBEROS and you support both, you respond 37529088Smarkm * with KERBEROS instead of LOGIN (which is against what the 37629088Smarkm * protocol says)) you will have to hack this code... 37729088Smarkm */ 37887139Smarkmvoid 37987139Smarkmauth_send(unsigned char *data, int cnt) 38029088Smarkm{ 38129088Smarkm Authenticator *ap; 38229088Smarkm static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION, 38329088Smarkm TELQUAL_IS, AUTHTYPE_NULL, 0, 38429088Smarkm IAC, SE }; 38529088Smarkm if (Server) { 38629088Smarkm if (auth_debug_mode) { 38729088Smarkm printf(">>>%s: auth_send called!\r\n", Name); 38829088Smarkm } 38929088Smarkm return; 39029088Smarkm } 39129088Smarkm 39229088Smarkm if (auth_debug_mode) { 39329088Smarkm printf(">>>%s: auth_send got:", Name); 39429088Smarkm printd(data, cnt); printf("\r\n"); 39529088Smarkm } 39629088Smarkm 39729088Smarkm /* 39829088Smarkm * Save the data, if it is new, so that we can continue looking 39929088Smarkm * at it if the authorization we try doesn't work 40029088Smarkm */ 40129088Smarkm if (data < _auth_send_data || 40229088Smarkm data > _auth_send_data + sizeof(_auth_send_data)) { 40387139Smarkm auth_send_cnt = (size_t)cnt > sizeof(_auth_send_data) 40429088Smarkm ? sizeof(_auth_send_data) 40529088Smarkm : cnt; 40629088Smarkm memmove((void *)_auth_send_data, (void *)data, auth_send_cnt); 40729088Smarkm auth_send_data = _auth_send_data; 40829088Smarkm } else { 40929088Smarkm /* 41029088Smarkm * This is probably a no-op, but we just make sure 41129088Smarkm */ 41229088Smarkm auth_send_data = data; 41329088Smarkm auth_send_cnt = cnt; 41429088Smarkm } 41529088Smarkm while ((auth_send_cnt -= 2) >= 0) { 41629088Smarkm if (auth_debug_mode) 41729088Smarkm printf(">>>%s: He supports %d\r\n", 41829088Smarkm Name, *auth_send_data); 41929088Smarkm if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) { 42029088Smarkm ap = findauthenticator(auth_send_data[0], 42129088Smarkm auth_send_data[1]); 42229088Smarkm if (ap && ap->send) { 42329088Smarkm if (auth_debug_mode) 42429088Smarkm printf(">>>%s: Trying %d %d\r\n", 42529088Smarkm Name, auth_send_data[0], 42629088Smarkm auth_send_data[1]); 42729088Smarkm if ((*ap->send)(ap)) { 42829088Smarkm /* 42929088Smarkm * Okay, we found one we like 43029088Smarkm * and did it. 43129088Smarkm * we can go home now. 43229088Smarkm */ 43329088Smarkm if (auth_debug_mode) 43429088Smarkm printf(">>>%s: Using type %d\r\n", 43529088Smarkm Name, *auth_send_data); 43629088Smarkm auth_send_data += 2; 43729088Smarkm return; 43829088Smarkm } 43929088Smarkm } 44029088Smarkm /* else 44129088Smarkm * just continue on and look for the 44229088Smarkm * next one if we didn't do anything. 44329088Smarkm */ 44429088Smarkm } 44529088Smarkm auth_send_data += 2; 44629088Smarkm } 44729088Smarkm net_write(str_none, sizeof(str_none)); 44829088Smarkm printsub('>', &str_none[2], sizeof(str_none) - 2); 44929088Smarkm if (auth_debug_mode) 45029088Smarkm printf(">>>%s: Sent failure message\r\n", Name); 45129088Smarkm auth_finished(0, AUTH_REJECT); 45229088Smarkm} 45329088Smarkm 45487139Smarkmvoid 45587139Smarkmauth_send_retry(void) 45629088Smarkm{ 45729088Smarkm /* 45829088Smarkm * if auth_send_cnt <= 0 then auth_send will end up rejecting 45929088Smarkm * the authentication and informing the other side of this. 46029088Smarkm */ 46129088Smarkm auth_send(auth_send_data, auth_send_cnt); 46229088Smarkm} 46329088Smarkm 46487139Smarkmvoid 46587139Smarkmauth_is(unsigned char *data, int cnt) 46629088Smarkm{ 46729088Smarkm Authenticator *ap; 46829088Smarkm 46929088Smarkm if (cnt < 2) 47029088Smarkm return; 47129088Smarkm 47229088Smarkm if (data[0] == AUTHTYPE_NULL) { 47329088Smarkm auth_finished(0, AUTH_REJECT); 47429088Smarkm return; 47529088Smarkm } 47629088Smarkm 47729181Smarkm if ((ap = findauthenticator(data[0], data[1]))) { 47829088Smarkm if (ap->is) 47929088Smarkm (*ap->is)(ap, data+2, cnt-2); 48029088Smarkm } else if (auth_debug_mode) 48129088Smarkm printf(">>>%s: Invalid authentication in IS: %d\r\n", 48229088Smarkm Name, *data); 48329088Smarkm} 48429088Smarkm 48587139Smarkmvoid 48687139Smarkmauth_reply(unsigned char *data, int cnt) 48729088Smarkm{ 48829088Smarkm Authenticator *ap; 48929088Smarkm 49029088Smarkm if (cnt < 2) 49129088Smarkm return; 49229088Smarkm 49329181Smarkm if ((ap = findauthenticator(data[0], data[1]))) { 49429088Smarkm if (ap->reply) 49529088Smarkm (*ap->reply)(ap, data+2, cnt-2); 49629088Smarkm } else if (auth_debug_mode) 49729088Smarkm printf(">>>%s: Invalid authentication in SEND: %d\r\n", 49829088Smarkm Name, *data); 49929088Smarkm} 50029088Smarkm 50187139Smarkmvoid 50287139Smarkmauth_name(unsigned char *data, int cnt) 50329088Smarkm{ 50429088Smarkm unsigned char savename[256]; 50529088Smarkm 50629088Smarkm if (cnt < 1) { 50729088Smarkm if (auth_debug_mode) 50829088Smarkm printf(">>>%s: Empty name in NAME\r\n", Name); 50929088Smarkm return; 51029088Smarkm } 51187139Smarkm if ((size_t)cnt > sizeof(savename) - 1) { 51229088Smarkm if (auth_debug_mode) 51329088Smarkm printf(">>>%s: Name in NAME (%d) exceeds %d length\r\n", 51487266Smarkm Name, cnt, (u_int)sizeof(savename)-1); 51529088Smarkm return; 51629088Smarkm } 51729088Smarkm memmove((void *)savename, (void *)data, cnt); 51829088Smarkm savename[cnt] = '\0'; /* Null terminate */ 51929088Smarkm if (auth_debug_mode) 52029088Smarkm printf(">>>%s: Got NAME [%s]\r\n", Name, savename); 52129088Smarkm auth_encrypt_user(savename); 52229088Smarkm} 52329088Smarkm 52487139Smarkmint 52587139Smarkmauth_sendname(unsigned char *cp, int len) 52629088Smarkm{ 52729088Smarkm static unsigned char str_request[256+6] 52829088Smarkm = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, }; 52987139Smarkm unsigned char *e = str_request + 4; 53087139Smarkm unsigned char *ee = &str_request[sizeof(str_request)-2]; 53129088Smarkm 53229088Smarkm while (--len >= 0) { 53329088Smarkm if ((*e++ = *cp++) == IAC) 53429088Smarkm *e++ = IAC; 53529088Smarkm if (e >= ee) 53629088Smarkm return(0); 53729088Smarkm } 53829088Smarkm *e++ = IAC; 53929088Smarkm *e++ = SE; 54029088Smarkm net_write(str_request, e - str_request); 54129088Smarkm printsub('>', &str_request[2], e - &str_request[2]); 54229088Smarkm return(1); 54329088Smarkm} 54429088Smarkm 54587139Smarkmvoid 54687139Smarkmauth_finished(Authenticator *ap, int result) 54729088Smarkm{ 54829088Smarkm if (!(authenticated = ap)) 54929088Smarkm authenticated = &NoAuth; 55029088Smarkm validuser = result; 55129088Smarkm} 55229088Smarkm 55387139Smarkm/* ARGSUSED */ 55487139Smarkmstatic void 55587139Smarkmauth_intr(int sig __unused) 55629088Smarkm{ 55729088Smarkm auth_finished(0, AUTH_REJECT); 55829088Smarkm} 55929088Smarkm 56087139Smarkmint 56187139Smarkmauth_wait(char *name) 56229088Smarkm{ 56329088Smarkm if (auth_debug_mode) 56429088Smarkm printf(">>>%s: in auth_wait.\r\n", Name); 56529088Smarkm 56629088Smarkm if (Server && !authenticating) 56729088Smarkm return(0); 56829088Smarkm 56929088Smarkm (void) signal(SIGALRM, auth_intr); 57029088Smarkm alarm(30); 57129088Smarkm while (!authenticated) 57229088Smarkm if (telnet_spin()) 57329088Smarkm break; 57429088Smarkm alarm(0); 57529088Smarkm (void) signal(SIGALRM, SIG_DFL); 57629088Smarkm 57729088Smarkm /* 57829088Smarkm * Now check to see if the user is valid or not 57929088Smarkm */ 58029088Smarkm if (!authenticated || authenticated == &NoAuth) 58129088Smarkm return(AUTH_REJECT); 58229088Smarkm 58329088Smarkm if (validuser == AUTH_VALID) 58429088Smarkm validuser = AUTH_USER; 58529088Smarkm 58629088Smarkm if (authenticated->status) 58729088Smarkm validuser = (*authenticated->status)(authenticated, 58829088Smarkm name, validuser); 58929088Smarkm return(validuser); 59029088Smarkm} 59129088Smarkm 59287139Smarkmvoid 59387139Smarkmauth_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 59429088Smarkm{ 59529088Smarkm Authenticator *ap; 59629088Smarkm 59729088Smarkm if ((ap = findauthenticator(data[1], data[2])) && ap->printsub) 59829088Smarkm (*ap->printsub)(data, cnt, buf, buflen); 59929088Smarkm else 60029088Smarkm auth_gen_printsub(data, cnt, buf, buflen); 60129088Smarkm} 60229088Smarkm 60387139Smarkmvoid 60487139Smarkmauth_gen_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 60529088Smarkm{ 60687139Smarkm unsigned char *cp; 60729088Smarkm unsigned char tbuf[16]; 60829088Smarkm 60929088Smarkm cnt -= 3; 61029088Smarkm data += 3; 61129088Smarkm buf[buflen-1] = '\0'; 61229088Smarkm buf[buflen-2] = '*'; 61329088Smarkm buflen -= 2; 61429088Smarkm for (; cnt > 0; cnt--, data++) { 61529088Smarkm sprintf((char *)tbuf, " %d", *data); 61629088Smarkm for (cp = tbuf; *cp && buflen > 0; --buflen) 61729088Smarkm *buf++ = *cp++; 61829088Smarkm if (buflen <= 0) 61929088Smarkm return; 62029088Smarkm } 62129088Smarkm *buf = '\0'; 62229088Smarkm} 62329088Smarkm#endif 624