157416Smarkm/*- 257416Smarkm * Copyright (c) 1991, 1993 357416Smarkm * The Regents of the University of California. All rights reserved. 457416Smarkm * 557416Smarkm * Redistribution and use in source and binary forms, with or without 657416Smarkm * modification, are permitted provided that the following conditions 757416Smarkm * are met: 857416Smarkm * 1. Redistributions of source code must retain the above copyright 957416Smarkm * notice, this list of conditions and the following disclaimer. 1057416Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1157416Smarkm * notice, this list of conditions and the following disclaimer in the 1257416Smarkm * documentation and/or other materials provided with the distribution. 1357416Smarkm * 3. All advertising materials mentioning features or use of this software 1457416Smarkm * must display the following acknowledgement: 1557416Smarkm * This product includes software developed by the University of 1657416Smarkm * California, Berkeley and its contributors. 1757416Smarkm * 4. Neither the name of the University nor the names of its contributors 1857416Smarkm * may be used to endorse or promote products derived from this software 1957416Smarkm * without specific prior written permission. 2057416Smarkm * 2157416Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2257416Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2357416Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2457416Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2557416Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2657416Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2757416Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2857416Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2957416Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3057416Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3157416Smarkm * SUCH DAMAGE. 3257416Smarkm */ 3357416Smarkm 3457416Smarkm/* 3557416Smarkm * Copyright (C) 1990 by the Massachusetts Institute of Technology 3657416Smarkm * 3757416Smarkm * Export of this software from the United States of America is assumed 3857416Smarkm * to require a specific license from the United States Government. 3957416Smarkm * It is the responsibility of any person or organization contemplating 4057416Smarkm * export to obtain such a license before exporting. 4157416Smarkm * 4257416Smarkm * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 4357416Smarkm * distribute this software and its documentation for any purpose and 4457416Smarkm * without fee is hereby granted, provided that the above copyright 4557416Smarkm * notice appear in all copies and that both that copyright notice and 4657416Smarkm * this permission notice appear in supporting documentation, and that 4757416Smarkm * the name of M.I.T. not be used in advertising or publicity pertaining 4857416Smarkm * to distribution of the software without specific, written prior 4957416Smarkm * permission. M.I.T. makes no representations about the suitability of 5057416Smarkm * this software for any purpose. It is provided "as is" without express 5157416Smarkm * or implied warranty. 5257416Smarkm */ 5357416Smarkm 5457416Smarkm#include <config.h> 5557416Smarkm 56233294SstasRCSID("$Id$"); 5757416Smarkm 5857416Smarkm#if defined(AUTHENTICATION) 5957416Smarkm#include <stdio.h> 6057416Smarkm#ifdef HAVE_SYS_TYPES_H 6157416Smarkm#include <sys/types.h> 6257416Smarkm#endif 6357416Smarkm#include <signal.h> 6457416Smarkm#define AUTH_NAMES 6557416Smarkm#ifdef HAVE_ARPA_TELNET_H 6657416Smarkm#include <arpa/telnet.h> 6757416Smarkm#endif 6857416Smarkm#include <stdlib.h> 6957416Smarkm#include <string.h> 7057416Smarkm 7157416Smarkm#include <roken.h> 7257416Smarkm 7357416Smarkm#ifdef SOCKS 7457416Smarkm#include <socks.h> 7557416Smarkm#endif 7657416Smarkm 7757416Smarkm#include "encrypt.h" 7857416Smarkm#include "auth.h" 7957416Smarkm#include "misc-proto.h" 8057416Smarkm#include "auth-proto.h" 8157416Smarkm 8257416Smarkm#define typemask(x) (1<<((x)-1)) 8357416Smarkm 8457416Smarkm#ifdef RSA_ENCPWD 8557416Smarkmextern rsaencpwd_init(); 8657416Smarkmextern rsaencpwd_send(); 8757416Smarkmextern rsaencpwd_is(); 8857416Smarkmextern rsaencpwd_reply(); 8957416Smarkmextern rsaencpwd_status(); 9057416Smarkmextern rsaencpwd_printsub(); 9157416Smarkm#endif 9257416Smarkm 9357416Smarkmint auth_debug_mode = 0; 9490926Snectarint auth_has_failed = 0; 9590926Snectarint auth_enable_encrypt = 0; 9657416Smarkmstatic const char *Name = "Noname"; 9757416Smarkmstatic int Server = 0; 9857416Smarkmstatic Authenticator *authenticated = 0; 9957416Smarkmstatic int authenticating = 0; 10057416Smarkmstatic int validuser = 0; 10157416Smarkmstatic unsigned char _auth_send_data[256]; 10257416Smarkmstatic unsigned char *auth_send_data; 10357416Smarkmstatic int auth_send_cnt = 0; 10457416Smarkm 10557416Smarkm/* 10657416Smarkm * Authentication types supported. Plese note that these are stored 10757416Smarkm * in priority order, i.e. try the first one first. 10857416Smarkm */ 10957416SmarkmAuthenticator authenticators[] = { 11057416Smarkm#ifdef UNSAFE 11157416Smarkm { AUTHTYPE_UNSAFE, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 11257416Smarkm unsafe_init, 11357416Smarkm unsafe_send, 11457416Smarkm unsafe_is, 11557416Smarkm unsafe_reply, 11657416Smarkm unsafe_status, 11757416Smarkm unsafe_printsub }, 11857416Smarkm#endif 11957416Smarkm#ifdef SRA 12057416Smarkm { AUTHTYPE_SRA, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 12157416Smarkm sra_init, 12257416Smarkm sra_send, 12357416Smarkm sra_is, 12457416Smarkm sra_reply, 12557416Smarkm sra_status, 12657416Smarkm sra_printsub }, 12757416Smarkm#endif 12857416Smarkm#ifdef SPX 12957416Smarkm { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 13057416Smarkm spx_init, 13157416Smarkm spx_send, 13257416Smarkm spx_is, 13357416Smarkm spx_reply, 13457416Smarkm spx_status, 13557416Smarkm spx_printsub }, 13657416Smarkm { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 13757416Smarkm spx_init, 13857416Smarkm spx_send, 13957416Smarkm spx_is, 14057416Smarkm spx_reply, 14157416Smarkm spx_status, 14257416Smarkm spx_printsub }, 14357416Smarkm#endif 14457416Smarkm#ifdef KRB5 14557416Smarkm { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 14657416Smarkm kerberos5_init, 14757416Smarkm kerberos5_send_mutual, 14857416Smarkm kerberos5_is, 14957416Smarkm kerberos5_reply, 15057416Smarkm kerberos5_status, 15157416Smarkm kerberos5_printsub }, 15257416Smarkm { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 15357416Smarkm kerberos5_init, 15457416Smarkm kerberos5_send_oneway, 15557416Smarkm kerberos5_is, 15657416Smarkm kerberos5_reply, 15757416Smarkm kerberos5_status, 15857416Smarkm kerberos5_printsub }, 15957416Smarkm#endif 16057416Smarkm#ifdef RSA_ENCPWD 16157416Smarkm { AUTHTYPE_RSA_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 16257416Smarkm rsaencpwd_init, 16357416Smarkm rsaencpwd_send, 16457416Smarkm rsaencpwd_is, 16557416Smarkm rsaencpwd_reply, 16657416Smarkm rsaencpwd_status, 16757416Smarkm rsaencpwd_printsub }, 16857416Smarkm#endif 16957416Smarkm { 0, }, 17057416Smarkm}; 17157416Smarkm 17257416Smarkmstatic Authenticator NoAuth = { 0 }; 17357416Smarkm 17457416Smarkmstatic int i_support = 0; 17557416Smarkmstatic int i_wont_support = 0; 17657416Smarkm 17757416SmarkmAuthenticator * 17857416Smarkmfindauthenticator(int type, int way) 17957416Smarkm{ 18057416Smarkm Authenticator *ap = authenticators; 18157416Smarkm 18257416Smarkm while (ap->type && (ap->type != type || ap->way != way)) 18357416Smarkm ++ap; 18457416Smarkm return(ap->type ? ap : 0); 18557416Smarkm} 18657416Smarkm 18757416Smarkmvoid 18857416Smarkmauth_init(const char *name, int server) 18957416Smarkm{ 19057416Smarkm Authenticator *ap = authenticators; 19157416Smarkm 19257416Smarkm Server = server; 19357416Smarkm Name = name; 19457416Smarkm 19557416Smarkm i_support = 0; 19657416Smarkm authenticated = 0; 19757416Smarkm authenticating = 0; 19857416Smarkm while (ap->type) { 19957416Smarkm if (!ap->init || (*ap->init)(ap, server)) { 20057416Smarkm i_support |= typemask(ap->type); 20157416Smarkm if (auth_debug_mode) 20257416Smarkm printf(">>>%s: I support auth type %d %d\r\n", 20357416Smarkm Name, 20457416Smarkm ap->type, ap->way); 20557416Smarkm } 20657416Smarkm else if (auth_debug_mode) 20757416Smarkm printf(">>>%s: Init failed: auth type %d %d\r\n", 20857416Smarkm Name, ap->type, ap->way); 20957416Smarkm ++ap; 21057416Smarkm } 21157416Smarkm} 21257416Smarkm 21357416Smarkmvoid 21457416Smarkmauth_disable_name(char *name) 21557416Smarkm{ 21657416Smarkm int x; 21757416Smarkm for (x = 0; x < AUTHTYPE_CNT; ++x) { 21857416Smarkm if (!strcasecmp(name, AUTHTYPE_NAME(x))) { 21957416Smarkm i_wont_support |= typemask(x); 22057416Smarkm break; 22157416Smarkm } 22257416Smarkm } 22357416Smarkm} 22457416Smarkm 22557416Smarkmint 22657416Smarkmgetauthmask(char *type, int *maskp) 22757416Smarkm{ 22857416Smarkm int x; 22957416Smarkm 23057416Smarkm if (!strcasecmp(type, AUTHTYPE_NAME(0))) { 23157416Smarkm *maskp = -1; 23257416Smarkm return(1); 23357416Smarkm } 23457416Smarkm 23557416Smarkm for (x = 1; x < AUTHTYPE_CNT; ++x) { 23657416Smarkm if (!strcasecmp(type, AUTHTYPE_NAME(x))) { 23757416Smarkm *maskp = typemask(x); 23857416Smarkm return(1); 23957416Smarkm } 24057416Smarkm } 24157416Smarkm return(0); 24257416Smarkm} 24357416Smarkm 24457416Smarkmint 24557416Smarkmauth_enable(char *type) 24657416Smarkm{ 24757416Smarkm return(auth_onoff(type, 1)); 24857416Smarkm} 24957416Smarkm 25057416Smarkmint 25157416Smarkmauth_disable(char *type) 25257416Smarkm{ 25357416Smarkm return(auth_onoff(type, 0)); 25457416Smarkm} 25557416Smarkm 25657416Smarkmint 25757416Smarkmauth_onoff(char *type, int on) 25857416Smarkm{ 25957416Smarkm int i, mask = -1; 26057416Smarkm Authenticator *ap; 26157416Smarkm 26257416Smarkm if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) { 26357416Smarkm printf("auth %s 'type'\n", on ? "enable" : "disable"); 26457416Smarkm printf("Where 'type' is one of:\n"); 26557416Smarkm printf("\t%s\n", AUTHTYPE_NAME(0)); 26657416Smarkm mask = 0; 26757416Smarkm for (ap = authenticators; ap->type; ap++) { 26857416Smarkm if ((mask & (i = typemask(ap->type))) != 0) 26957416Smarkm continue; 27057416Smarkm mask |= i; 27157416Smarkm printf("\t%s\n", AUTHTYPE_NAME(ap->type)); 27257416Smarkm } 27357416Smarkm return(0); 27457416Smarkm } 27557416Smarkm 27657416Smarkm if (!getauthmask(type, &mask)) { 27757416Smarkm printf("%s: invalid authentication type\n", type); 27857416Smarkm return(0); 27957416Smarkm } 28057416Smarkm if (on) 28157416Smarkm i_wont_support &= ~mask; 28257416Smarkm else 28357416Smarkm i_wont_support |= mask; 28457416Smarkm return(1); 28557416Smarkm} 28657416Smarkm 28757416Smarkmint 28857416Smarkmauth_togdebug(int on) 28957416Smarkm{ 29057416Smarkm if (on < 0) 29157416Smarkm auth_debug_mode ^= 1; 29257416Smarkm else 29357416Smarkm auth_debug_mode = on; 29457416Smarkm printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled"); 29557416Smarkm return(1); 29657416Smarkm} 29757416Smarkm 29857416Smarkmint 29957416Smarkmauth_status(void) 30057416Smarkm{ 30157416Smarkm Authenticator *ap; 30257416Smarkm int i, mask; 30357416Smarkm 30457416Smarkm if (i_wont_support == -1) 30557416Smarkm printf("Authentication disabled\n"); 30657416Smarkm else 30757416Smarkm printf("Authentication enabled\n"); 30857416Smarkm 30957416Smarkm mask = 0; 31057416Smarkm for (ap = authenticators; ap->type; ap++) { 31157416Smarkm if ((mask & (i = typemask(ap->type))) != 0) 31257416Smarkm continue; 31357416Smarkm mask |= i; 31457416Smarkm printf("%s: %s\n", AUTHTYPE_NAME(ap->type), 31557416Smarkm (i_wont_support & typemask(ap->type)) ? 31657416Smarkm "disabled" : "enabled"); 31757416Smarkm } 31857416Smarkm return(1); 31957416Smarkm} 32057416Smarkm 32157416Smarkm/* 32257416Smarkm * This routine is called by the server to start authentication 32357416Smarkm * negotiation. 32457416Smarkm */ 32557416Smarkmvoid 32657416Smarkmauth_request(void) 32757416Smarkm{ 32857416Smarkm static unsigned char str_request[64] = { IAC, SB, 32957416Smarkm TELOPT_AUTHENTICATION, 33057416Smarkm TELQUAL_SEND, }; 33157416Smarkm Authenticator *ap = authenticators; 33257416Smarkm unsigned char *e = str_request + 4; 33357416Smarkm 33457416Smarkm if (!authenticating) { 33557416Smarkm authenticating = 1; 33657416Smarkm while (ap->type) { 33757416Smarkm if (i_support & ~i_wont_support & typemask(ap->type)) { 33857416Smarkm if (auth_debug_mode) { 33957416Smarkm printf(">>>%s: Sending type %d %d\r\n", 34057416Smarkm Name, ap->type, ap->way); 34157416Smarkm } 34257416Smarkm *e++ = ap->type; 34357416Smarkm *e++ = ap->way; 34457416Smarkm } 34557416Smarkm ++ap; 34657416Smarkm } 34757416Smarkm *e++ = IAC; 34857416Smarkm *e++ = SE; 34957416Smarkm telnet_net_write(str_request, e - str_request); 35057416Smarkm printsub('>', &str_request[2], e - str_request - 2); 35157416Smarkm } 35257416Smarkm} 35357416Smarkm 35457416Smarkm/* 35557416Smarkm * This is called when an AUTH SEND is received. 35657416Smarkm * It should never arrive on the server side (as only the server can 35757416Smarkm * send an AUTH SEND). 35857416Smarkm * You should probably respond to it if you can... 35957416Smarkm * 36057416Smarkm * If you want to respond to the types out of order (i.e. even 36157416Smarkm * if he sends LOGIN KERBEROS and you support both, you respond 36257416Smarkm * with KERBEROS instead of LOGIN (which is against what the 36357416Smarkm * protocol says)) you will have to hack this code... 36457416Smarkm */ 36557416Smarkmvoid 36657416Smarkmauth_send(unsigned char *data, int cnt) 36757416Smarkm{ 36857416Smarkm Authenticator *ap; 36957416Smarkm static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION, 37057416Smarkm TELQUAL_IS, AUTHTYPE_NULL, 0, 37157416Smarkm IAC, SE }; 37257416Smarkm if (Server) { 37357416Smarkm if (auth_debug_mode) { 37457416Smarkm printf(">>>%s: auth_send called!\r\n", Name); 37557416Smarkm } 37657416Smarkm return; 37757416Smarkm } 37857416Smarkm 37957416Smarkm if (auth_debug_mode) { 38057416Smarkm printf(">>>%s: auth_send got:", Name); 38157416Smarkm printd(data, cnt); printf("\r\n"); 38257416Smarkm } 38357416Smarkm 38457416Smarkm /* 38557416Smarkm * Save the data, if it is new, so that we can continue looking 38657416Smarkm * at it if the authorization we try doesn't work 38757416Smarkm */ 38857416Smarkm if (data < _auth_send_data || 38957416Smarkm data > _auth_send_data + sizeof(_auth_send_data)) { 39057416Smarkm auth_send_cnt = cnt > sizeof(_auth_send_data) 39157416Smarkm ? sizeof(_auth_send_data) 39257416Smarkm : cnt; 39357416Smarkm memmove(_auth_send_data, data, auth_send_cnt); 39457416Smarkm auth_send_data = _auth_send_data; 39557416Smarkm } else { 39657416Smarkm /* 39757416Smarkm * This is probably a no-op, but we just make sure 39857416Smarkm */ 39957416Smarkm auth_send_data = data; 40057416Smarkm auth_send_cnt = cnt; 40157416Smarkm } 40257416Smarkm while ((auth_send_cnt -= 2) >= 0) { 40357416Smarkm if (auth_debug_mode) 40457416Smarkm printf(">>>%s: He supports %d\r\n", 40557416Smarkm Name, *auth_send_data); 40657416Smarkm if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) { 40757416Smarkm ap = findauthenticator(auth_send_data[0], 40857416Smarkm auth_send_data[1]); 40957416Smarkm if (ap && ap->send) { 41057416Smarkm if (auth_debug_mode) 41157416Smarkm printf(">>>%s: Trying %d %d\r\n", 41257416Smarkm Name, auth_send_data[0], 41357416Smarkm auth_send_data[1]); 41457416Smarkm if ((*ap->send)(ap)) { 41557416Smarkm /* 41657416Smarkm * Okay, we found one we like 41757416Smarkm * and did it. 41857416Smarkm * we can go home now. 41957416Smarkm */ 42057416Smarkm if (auth_debug_mode) 42157416Smarkm printf(">>>%s: Using type %d\r\n", 42257416Smarkm Name, *auth_send_data); 42357416Smarkm auth_send_data += 2; 42457416Smarkm return; 42557416Smarkm } 42657416Smarkm } 42757416Smarkm /* else 42857416Smarkm * just continue on and look for the 42957416Smarkm * next one if we didn't do anything. 43057416Smarkm */ 43157416Smarkm } 43257416Smarkm auth_send_data += 2; 43357416Smarkm } 43457416Smarkm telnet_net_write(str_none, sizeof(str_none)); 43557416Smarkm printsub('>', &str_none[2], sizeof(str_none) - 2); 43657416Smarkm if (auth_debug_mode) 43757416Smarkm printf(">>>%s: Sent failure message\r\n", Name); 43857416Smarkm auth_finished(0, AUTH_REJECT); 43990926Snectar auth_has_failed = 1; 44057416Smarkm#ifdef KANNAN 44157416Smarkm /* 44257416Smarkm * We requested strong authentication, however no mechanisms worked. 44357416Smarkm * Therefore, exit on client end. 44457416Smarkm */ 44557416Smarkm printf("Unable to securely authenticate user ... exit\n"); 44657416Smarkm exit(0); 44757416Smarkm#endif /* KANNAN */ 44857416Smarkm} 44957416Smarkm 45057416Smarkmvoid 45157416Smarkmauth_send_retry(void) 45257416Smarkm{ 45357416Smarkm /* 45457416Smarkm * if auth_send_cnt <= 0 then auth_send will end up rejecting 45557416Smarkm * the authentication and informing the other side of this. 45657416Smarkm */ 45757416Smarkm auth_send(auth_send_data, auth_send_cnt); 45857416Smarkm} 45957416Smarkm 46057416Smarkmvoid 46157416Smarkmauth_is(unsigned char *data, int cnt) 46257416Smarkm{ 46357416Smarkm Authenticator *ap; 46457416Smarkm 46557416Smarkm if (cnt < 2) 46657416Smarkm return; 46757416Smarkm 46857416Smarkm if (data[0] == AUTHTYPE_NULL) { 46957416Smarkm auth_finished(0, AUTH_REJECT); 47057416Smarkm return; 47157416Smarkm } 47257416Smarkm 47357416Smarkm if ((ap = findauthenticator(data[0], data[1]))) { 47457416Smarkm if (ap->is) 47557416Smarkm (*ap->is)(ap, data+2, cnt-2); 47657416Smarkm } else if (auth_debug_mode) 47757416Smarkm printf(">>>%s: Invalid authentication in IS: %d\r\n", 47857416Smarkm Name, *data); 47957416Smarkm} 48057416Smarkm 48157416Smarkmvoid 48257416Smarkmauth_reply(unsigned char *data, int cnt) 48357416Smarkm{ 48457416Smarkm Authenticator *ap; 48557416Smarkm 48657416Smarkm if (cnt < 2) 48757416Smarkm return; 48857416Smarkm 48957416Smarkm if ((ap = findauthenticator(data[0], data[1]))) { 49057416Smarkm if (ap->reply) 49157416Smarkm (*ap->reply)(ap, data+2, cnt-2); 49257416Smarkm } else if (auth_debug_mode) 49357416Smarkm printf(">>>%s: Invalid authentication in SEND: %d\r\n", 49457416Smarkm Name, *data); 49557416Smarkm} 49657416Smarkm 49757416Smarkmvoid 49857416Smarkmauth_name(unsigned char *data, int cnt) 49957416Smarkm{ 50057416Smarkm char savename[256]; 50157416Smarkm 50257416Smarkm if (cnt < 1) { 50357416Smarkm if (auth_debug_mode) 50457416Smarkm printf(">>>%s: Empty name in NAME\r\n", Name); 50557416Smarkm return; 50657416Smarkm } 50757416Smarkm if (cnt > sizeof(savename) - 1) { 50857416Smarkm if (auth_debug_mode) 50957416Smarkm printf(">>>%s: Name in NAME (%d) exceeds %lu length\r\n", 51057416Smarkm Name, cnt, (unsigned long)(sizeof(savename)-1)); 51157416Smarkm return; 51257416Smarkm } 51357416Smarkm memmove(savename, data, cnt); 51457416Smarkm savename[cnt] = '\0'; /* Null terminate */ 51557416Smarkm if (auth_debug_mode) 51657416Smarkm printf(">>>%s: Got NAME [%s]\r\n", Name, savename); 51757416Smarkm auth_encrypt_user(savename); 51857416Smarkm} 51957416Smarkm 52057416Smarkmint 52157416Smarkmauth_sendname(unsigned char *cp, int len) 52257416Smarkm{ 52357416Smarkm static unsigned char str_request[256+6] 52457416Smarkm = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, }; 52557416Smarkm unsigned char *e = str_request + 4; 52657416Smarkm unsigned char *ee = &str_request[sizeof(str_request)-2]; 52757416Smarkm 52857416Smarkm while (--len >= 0) { 52957416Smarkm if ((*e++ = *cp++) == IAC) 53057416Smarkm *e++ = IAC; 53157416Smarkm if (e >= ee) 53257416Smarkm return(0); 53357416Smarkm } 53457416Smarkm *e++ = IAC; 53557416Smarkm *e++ = SE; 53657416Smarkm telnet_net_write(str_request, e - str_request); 53757416Smarkm printsub('>', &str_request[2], e - &str_request[2]); 53857416Smarkm return(1); 53957416Smarkm} 54057416Smarkm 54157416Smarkmvoid 54257416Smarkmauth_finished(Authenticator *ap, int result) 54357416Smarkm{ 54457416Smarkm if (!(authenticated = ap)) 54557416Smarkm authenticated = &NoAuth; 54657416Smarkm validuser = result; 54757416Smarkm} 54857416Smarkm 54957416Smarkm/* ARGSUSED */ 55057416Smarkmstatic void 55157416Smarkmauth_intr(int sig) 55257416Smarkm{ 55357416Smarkm auth_finished(0, AUTH_REJECT); 55457416Smarkm} 55557416Smarkm 55657416Smarkmint 55757416Smarkmauth_wait(char *name, size_t name_sz) 55857416Smarkm{ 55957416Smarkm if (auth_debug_mode) 56057416Smarkm printf(">>>%s: in auth_wait.\r\n", Name); 56157416Smarkm 56257416Smarkm if (Server && !authenticating) 56357416Smarkm return(0); 56457416Smarkm 56557416Smarkm signal(SIGALRM, auth_intr); 56657416Smarkm alarm(30); 56757416Smarkm while (!authenticated) 56857416Smarkm if (telnet_spin()) 56957416Smarkm break; 57057416Smarkm alarm(0); 57157416Smarkm signal(SIGALRM, SIG_DFL); 57257416Smarkm 57357416Smarkm /* 57457416Smarkm * Now check to see if the user is valid or not 57557416Smarkm */ 57657416Smarkm if (!authenticated || authenticated == &NoAuth) 57757416Smarkm return(AUTH_REJECT); 57857416Smarkm 57957416Smarkm if (validuser == AUTH_VALID) 58057416Smarkm validuser = AUTH_USER; 58157416Smarkm 58257416Smarkm if (authenticated->status) 58357416Smarkm validuser = (*authenticated->status)(authenticated, 58457416Smarkm name, name_sz, 58557416Smarkm validuser); 58657416Smarkm return(validuser); 58757416Smarkm} 58857416Smarkm 58957416Smarkmvoid 59057416Smarkmauth_debug(int mode) 59157416Smarkm{ 59257416Smarkm auth_debug_mode = mode; 59357416Smarkm} 59457416Smarkm 59557416Smarkmvoid 596233294Sstasauth_printsub(unsigned char *data, size_t cnt, 597233294Sstas unsigned char *buf, size_t buflen) 59857416Smarkm{ 59957416Smarkm Authenticator *ap; 60057416Smarkm 60157416Smarkm if ((ap = findauthenticator(data[1], data[2])) && ap->printsub) 60257416Smarkm (*ap->printsub)(data, cnt, buf, buflen); 60357416Smarkm else 60457416Smarkm auth_gen_printsub(data, cnt, buf, buflen); 60557416Smarkm} 60657416Smarkm 60757416Smarkmvoid 608233294Sstasauth_gen_printsub(unsigned char *data, size_t cnt, 609233294Sstas unsigned char *buf, size_t buflen) 61057416Smarkm{ 61157416Smarkm unsigned char *cp; 61257416Smarkm unsigned char tbuf[16]; 61357416Smarkm 61457416Smarkm cnt -= 3; 61557416Smarkm data += 3; 61657416Smarkm buf[buflen-1] = '\0'; 61757416Smarkm buf[buflen-2] = '*'; 61857416Smarkm buflen -= 2; 61957416Smarkm for (; cnt > 0; cnt--, data++) { 62090926Snectar snprintf((char*)tbuf, sizeof(tbuf), " %d", *data); 62157416Smarkm for (cp = tbuf; *cp && buflen > 0; --buflen) 62257416Smarkm *buf++ = *cp++; 62357416Smarkm if (buflen <= 0) 62457416Smarkm return; 62557416Smarkm } 62657416Smarkm *buf = '\0'; 62757416Smarkm} 62857416Smarkm#endif 629