181cb6ddcSMark Murray /*- 281cb6ddcSMark Murray * Copyright (c) 1991, 1993 381cb6ddcSMark Murray * The Regents of the University of California. All rights reserved. 481cb6ddcSMark Murray * 581cb6ddcSMark Murray * Redistribution and use in source and binary forms, with or without 681cb6ddcSMark Murray * modification, are permitted provided that the following conditions 781cb6ddcSMark Murray * are met: 881cb6ddcSMark Murray * 1. Redistributions of source code must retain the above copyright 981cb6ddcSMark Murray * notice, this list of conditions and the following disclaimer. 1081cb6ddcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 1181cb6ddcSMark Murray * notice, this list of conditions and the following disclaimer in the 1281cb6ddcSMark Murray * documentation and/or other materials provided with the distribution. 13*83129c0bSEd Maste * 3. Neither the name of the University nor the names of its contributors 1481cb6ddcSMark Murray * may be used to endorse or promote products derived from this software 1581cb6ddcSMark Murray * without specific prior written permission. 1681cb6ddcSMark Murray * 1781cb6ddcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1881cb6ddcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1981cb6ddcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2081cb6ddcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2181cb6ddcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2281cb6ddcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2381cb6ddcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2481cb6ddcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2581cb6ddcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2681cb6ddcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2781cb6ddcSMark Murray * SUCH DAMAGE. 2867bf7a0aSNick Sayer * 2981cb6ddcSMark Murray */ 3081cb6ddcSMark Murray 3177b7cdf1SDavid E. O'Brien #if 0 3281cb6ddcSMark Murray #ifndef lint 3304c426ccSMark Murray static const char sccsid[] = "@(#)auth.c 8.3 (Berkeley) 5/30/95"; 3481cb6ddcSMark Murray #endif /* not lint */ 3577b7cdf1SDavid E. O'Brien #endif 3677b7cdf1SDavid E. O'Brien #include <sys/cdefs.h> 3777b7cdf1SDavid E. O'Brien __FBSDID("$FreeBSD$"); 3877b7cdf1SDavid E. O'Brien 3981cb6ddcSMark Murray 4081cb6ddcSMark Murray /* 4181cb6ddcSMark Murray * Copyright (C) 1990 by the Massachusetts Institute of Technology 4281cb6ddcSMark Murray * 4381cb6ddcSMark Murray * Export of this software from the United States of America is assumed 4481cb6ddcSMark Murray * to require a specific license from the United States Government. 4581cb6ddcSMark Murray * It is the responsibility of any person or organization contemplating 4681cb6ddcSMark Murray * export to obtain such a license before exporting. 4781cb6ddcSMark Murray * 4881cb6ddcSMark Murray * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 4981cb6ddcSMark Murray * distribute this software and its documentation for any purpose and 5081cb6ddcSMark Murray * without fee is hereby granted, provided that the above copyright 5181cb6ddcSMark Murray * notice appear in all copies and that both that copyright notice and 5281cb6ddcSMark Murray * this permission notice appear in supporting documentation, and that 5381cb6ddcSMark Murray * the name of M.I.T. not be used in advertising or publicity pertaining 5481cb6ddcSMark Murray * to distribution of the software without specific, written prior 5581cb6ddcSMark Murray * permission. M.I.T. makes no representations about the suitability of 5681cb6ddcSMark Murray * this software for any purpose. It is provided "as is" without express 5781cb6ddcSMark Murray * or implied warranty. 5881cb6ddcSMark Murray */ 5981cb6ddcSMark Murray 6081cb6ddcSMark Murray 618fa113e5SMark Murray #ifdef AUTHENTICATION 628fa113e5SMark Murray #define AUTH_NAMES 6381cb6ddcSMark Murray #include <sys/types.h> 6481cb6ddcSMark Murray #include <signal.h> 658fa113e5SMark Murray #include <stdio.h> 6681cb6ddcSMark Murray #include <stdlib.h> 6781cb6ddcSMark Murray #include <string.h> 688fa113e5SMark Murray #include <unistd.h> 698fa113e5SMark Murray #include <arpa/telnet.h> 7081cb6ddcSMark Murray 7181cb6ddcSMark Murray #include "encrypt.h" 7281cb6ddcSMark Murray #include "auth.h" 7381cb6ddcSMark Murray #include "misc-proto.h" 7481cb6ddcSMark Murray #include "auth-proto.h" 7581cb6ddcSMark Murray 768fa113e5SMark Murray #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 7781cb6ddcSMark Murray 7881cb6ddcSMark Murray #ifdef KRB4_ENCPWD 7981cb6ddcSMark Murray extern krb4encpwd_init(); 8081cb6ddcSMark Murray extern krb4encpwd_send(); 8181cb6ddcSMark Murray extern krb4encpwd_is(); 8281cb6ddcSMark Murray extern krb4encpwd_reply(); 8381cb6ddcSMark Murray extern krb4encpwd_status(); 8481cb6ddcSMark Murray extern krb4encpwd_printsub(); 8581cb6ddcSMark Murray #endif 8681cb6ddcSMark Murray 8781cb6ddcSMark Murray #ifdef RSA_ENCPWD 8881cb6ddcSMark Murray extern rsaencpwd_init(); 8981cb6ddcSMark Murray extern rsaencpwd_send(); 9081cb6ddcSMark Murray extern rsaencpwd_is(); 9181cb6ddcSMark Murray extern rsaencpwd_reply(); 9281cb6ddcSMark Murray extern rsaencpwd_status(); 9381cb6ddcSMark Murray extern rsaencpwd_printsub(); 9481cb6ddcSMark Murray #endif 9581cb6ddcSMark Murray 9681cb6ddcSMark Murray int auth_debug_mode = 0; 978fa113e5SMark Murray static const char *Name = "Noname"; 9881cb6ddcSMark Murray static int Server = 0; 9981cb6ddcSMark Murray static Authenticator *authenticated = 0; 10081cb6ddcSMark Murray static int authenticating = 0; 10181cb6ddcSMark Murray static int validuser = 0; 10281cb6ddcSMark Murray static unsigned char _auth_send_data[256]; 10381cb6ddcSMark Murray static unsigned char *auth_send_data; 10481cb6ddcSMark Murray static int auth_send_cnt = 0; 10581cb6ddcSMark Murray 10604c426ccSMark Murray int auth_onoff(char *type, int on); 10704c426ccSMark Murray void auth_encrypt_user(char *name); 10804c426ccSMark Murray 10981cb6ddcSMark Murray /* 11081cb6ddcSMark Murray * Authentication types supported. Plese note that these are stored 11181cb6ddcSMark Murray * in priority order, i.e. try the first one first. 11281cb6ddcSMark Murray */ 11381cb6ddcSMark Murray Authenticator authenticators[] = { 11481cb6ddcSMark Murray #ifdef KRB5 11581cb6ddcSMark Murray # ifdef ENCRYPTION 11681cb6ddcSMark Murray { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 11781cb6ddcSMark Murray kerberos5_init, 1188fa113e5SMark Murray kerberos5_send_mutual, 11981cb6ddcSMark Murray kerberos5_is, 12081cb6ddcSMark Murray kerberos5_reply, 12181cb6ddcSMark Murray kerberos5_status, 12281cb6ddcSMark Murray kerberos5_printsub }, 12381cb6ddcSMark Murray # endif /* ENCRYPTION */ 12481cb6ddcSMark Murray { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 12581cb6ddcSMark Murray kerberos5_init, 1268fa113e5SMark Murray kerberos5_send_oneway, 12781cb6ddcSMark Murray kerberos5_is, 12881cb6ddcSMark Murray kerberos5_reply, 12981cb6ddcSMark Murray kerberos5_status, 13081cb6ddcSMark Murray kerberos5_printsub }, 13181cb6ddcSMark Murray #endif 13281cb6ddcSMark Murray #ifdef KRB4 13381cb6ddcSMark Murray # ifdef ENCRYPTION 13481cb6ddcSMark Murray { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 13581cb6ddcSMark Murray kerberos4_init, 13681cb6ddcSMark Murray kerberos4_send, 13781cb6ddcSMark Murray kerberos4_is, 13881cb6ddcSMark Murray kerberos4_reply, 13981cb6ddcSMark Murray kerberos4_status, 14081cb6ddcSMark Murray kerberos4_printsub }, 14181cb6ddcSMark Murray # endif /* ENCRYPTION */ 14281cb6ddcSMark Murray { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 14381cb6ddcSMark Murray kerberos4_init, 14481cb6ddcSMark Murray kerberos4_send, 14581cb6ddcSMark Murray kerberos4_is, 14681cb6ddcSMark Murray kerberos4_reply, 14781cb6ddcSMark Murray kerberos4_status, 14881cb6ddcSMark Murray kerberos4_printsub }, 14981cb6ddcSMark Murray #endif 15081cb6ddcSMark Murray #ifdef KRB4_ENCPWD 15181cb6ddcSMark Murray { AUTHTYPE_KRB4_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 15281cb6ddcSMark Murray krb4encpwd_init, 15381cb6ddcSMark Murray krb4encpwd_send, 15481cb6ddcSMark Murray krb4encpwd_is, 15581cb6ddcSMark Murray krb4encpwd_reply, 15681cb6ddcSMark Murray krb4encpwd_status, 15781cb6ddcSMark Murray krb4encpwd_printsub }, 15881cb6ddcSMark Murray #endif 15981cb6ddcSMark Murray #ifdef RSA_ENCPWD 16081cb6ddcSMark Murray { AUTHTYPE_RSA_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 16181cb6ddcSMark Murray rsaencpwd_init, 16281cb6ddcSMark Murray rsaencpwd_send, 16381cb6ddcSMark Murray rsaencpwd_is, 16481cb6ddcSMark Murray rsaencpwd_reply, 16581cb6ddcSMark Murray rsaencpwd_status, 16681cb6ddcSMark Murray rsaencpwd_printsub }, 16781cb6ddcSMark Murray #endif 1680f8c8396SNick Sayer #ifdef SRA 1690f8c8396SNick Sayer { AUTHTYPE_SRA, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 1700f8c8396SNick Sayer sra_init, 1710f8c8396SNick Sayer sra_send, 1720f8c8396SNick Sayer sra_is, 1730f8c8396SNick Sayer sra_reply, 1740f8c8396SNick Sayer sra_status, 1750f8c8396SNick Sayer sra_printsub }, 1760f8c8396SNick Sayer 1770f8c8396SNick Sayer #endif 1788fa113e5SMark Murray { 0, 0, 0, 0, 0, 0, 0, 0 }, 17981cb6ddcSMark Murray }; 18081cb6ddcSMark Murray 1818fa113e5SMark Murray static Authenticator NoAuth = { 0, 0, 0, 0, 0, 0, 0, 0 }; 18281cb6ddcSMark Murray 18381cb6ddcSMark Murray static int i_support = 0; 18481cb6ddcSMark Murray static int i_wont_support = 0; 18581cb6ddcSMark Murray 18681cb6ddcSMark Murray Authenticator * 1878fa113e5SMark Murray findauthenticator(int type, int way) 18881cb6ddcSMark Murray { 18981cb6ddcSMark Murray Authenticator *ap = authenticators; 19081cb6ddcSMark Murray 19181cb6ddcSMark Murray while (ap->type && (ap->type != type || ap->way != way)) 19281cb6ddcSMark Murray ++ap; 19381cb6ddcSMark Murray return(ap->type ? ap : 0); 19481cb6ddcSMark Murray } 19581cb6ddcSMark Murray 19681cb6ddcSMark Murray void 1978fa113e5SMark Murray auth_init(const char *name, int server) 19881cb6ddcSMark Murray { 19981cb6ddcSMark Murray Authenticator *ap = authenticators; 20081cb6ddcSMark Murray 20181cb6ddcSMark Murray Server = server; 20281cb6ddcSMark Murray Name = name; 20381cb6ddcSMark Murray 20481cb6ddcSMark Murray i_support = 0; 20581cb6ddcSMark Murray authenticated = 0; 20681cb6ddcSMark Murray authenticating = 0; 20781cb6ddcSMark Murray while (ap->type) { 20881cb6ddcSMark Murray if (!ap->init || (*ap->init)(ap, server)) { 20981cb6ddcSMark Murray i_support |= typemask(ap->type); 21081cb6ddcSMark Murray if (auth_debug_mode) 21181cb6ddcSMark Murray printf(">>>%s: I support auth type %d %d\r\n", 21281cb6ddcSMark Murray Name, 21381cb6ddcSMark Murray ap->type, ap->way); 21481cb6ddcSMark Murray } 21581cb6ddcSMark Murray else if (auth_debug_mode) 21681cb6ddcSMark Murray printf(">>>%s: Init failed: auth type %d %d\r\n", 21781cb6ddcSMark Murray Name, ap->type, ap->way); 21881cb6ddcSMark Murray ++ap; 21981cb6ddcSMark Murray } 22081cb6ddcSMark Murray } 22181cb6ddcSMark Murray 22281cb6ddcSMark Murray void 2238fa113e5SMark Murray auth_disable_name(char *name) 22481cb6ddcSMark Murray { 22581cb6ddcSMark Murray int x; 22681cb6ddcSMark Murray for (x = 0; x < AUTHTYPE_CNT; ++x) { 22767bf7a0aSNick Sayer if (AUTHTYPE_NAME(x) && !strcasecmp(name, AUTHTYPE_NAME(x))) { 22881cb6ddcSMark Murray i_wont_support |= typemask(x); 22981cb6ddcSMark Murray break; 23081cb6ddcSMark Murray } 23181cb6ddcSMark Murray } 23281cb6ddcSMark Murray } 23381cb6ddcSMark Murray 23481cb6ddcSMark Murray int 2358fa113e5SMark Murray getauthmask(char *type, int *maskp) 23681cb6ddcSMark Murray { 2378fa113e5SMark Murray int x; 23881cb6ddcSMark Murray 239989efc86SNick Sayer if (AUTHTYPE_NAME(0) && !strcasecmp(type, AUTHTYPE_NAME(0))) { 24081cb6ddcSMark Murray *maskp = -1; 24181cb6ddcSMark Murray return(1); 24281cb6ddcSMark Murray } 24381cb6ddcSMark Murray 24481cb6ddcSMark Murray for (x = 1; x < AUTHTYPE_CNT; ++x) { 245989efc86SNick Sayer if (AUTHTYPE_NAME(x) && !strcasecmp(type, AUTHTYPE_NAME(x))) { 24681cb6ddcSMark Murray *maskp = typemask(x); 24781cb6ddcSMark Murray return(1); 24881cb6ddcSMark Murray } 24981cb6ddcSMark Murray } 25081cb6ddcSMark Murray return(0); 25181cb6ddcSMark Murray } 25281cb6ddcSMark Murray 25381cb6ddcSMark Murray int 2548fa113e5SMark Murray auth_enable(char *type) 25581cb6ddcSMark Murray { 25681cb6ddcSMark Murray return(auth_onoff(type, 1)); 25781cb6ddcSMark Murray } 25881cb6ddcSMark Murray 25981cb6ddcSMark Murray int 2608fa113e5SMark Murray auth_disable(char *type) 26181cb6ddcSMark Murray { 26281cb6ddcSMark Murray return(auth_onoff(type, 0)); 26381cb6ddcSMark Murray } 26481cb6ddcSMark Murray 26581cb6ddcSMark Murray int 2668fa113e5SMark Murray auth_onoff(char *type, int on) 26781cb6ddcSMark Murray { 26881cb6ddcSMark Murray int i, mask = -1; 26981cb6ddcSMark Murray Authenticator *ap; 27081cb6ddcSMark Murray 27181cb6ddcSMark Murray if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) { 27281cb6ddcSMark Murray printf("auth %s 'type'\n", on ? "enable" : "disable"); 27381cb6ddcSMark Murray printf("Where 'type' is one of:\n"); 27481cb6ddcSMark Murray printf("\t%s\n", AUTHTYPE_NAME(0)); 27581cb6ddcSMark Murray mask = 0; 27681cb6ddcSMark Murray for (ap = authenticators; ap->type; ap++) { 27781cb6ddcSMark Murray if ((mask & (i = typemask(ap->type))) != 0) 27881cb6ddcSMark Murray continue; 27981cb6ddcSMark Murray mask |= i; 28081cb6ddcSMark Murray printf("\t%s\n", AUTHTYPE_NAME(ap->type)); 28181cb6ddcSMark Murray } 28281cb6ddcSMark Murray return(0); 28381cb6ddcSMark Murray } 28481cb6ddcSMark Murray 28581cb6ddcSMark Murray if (!getauthmask(type, &mask)) { 28681cb6ddcSMark Murray printf("%s: invalid authentication type\n", type); 28781cb6ddcSMark Murray return(0); 28881cb6ddcSMark Murray } 28981cb6ddcSMark Murray if (on) 29081cb6ddcSMark Murray i_wont_support &= ~mask; 29181cb6ddcSMark Murray else 29281cb6ddcSMark Murray i_wont_support |= mask; 29381cb6ddcSMark Murray return(1); 29481cb6ddcSMark Murray } 29581cb6ddcSMark Murray 29681cb6ddcSMark Murray int 2978fa113e5SMark Murray auth_togdebug(int on) 29881cb6ddcSMark Murray { 29981cb6ddcSMark Murray if (on < 0) 30081cb6ddcSMark Murray auth_debug_mode ^= 1; 30181cb6ddcSMark Murray else 30281cb6ddcSMark Murray auth_debug_mode = on; 30381cb6ddcSMark Murray printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled"); 30481cb6ddcSMark Murray return(1); 30581cb6ddcSMark Murray } 30681cb6ddcSMark Murray 30781cb6ddcSMark Murray int 3088fa113e5SMark Murray auth_status(void) 30981cb6ddcSMark Murray { 31081cb6ddcSMark Murray Authenticator *ap; 31181cb6ddcSMark Murray int i, mask; 31281cb6ddcSMark Murray 31381cb6ddcSMark Murray if (i_wont_support == -1) 31481cb6ddcSMark Murray printf("Authentication disabled\n"); 31581cb6ddcSMark Murray else 31681cb6ddcSMark Murray printf("Authentication enabled\n"); 31781cb6ddcSMark Murray 31881cb6ddcSMark Murray mask = 0; 31981cb6ddcSMark Murray for (ap = authenticators; ap->type; ap++) { 32081cb6ddcSMark Murray if ((mask & (i = typemask(ap->type))) != 0) 32181cb6ddcSMark Murray continue; 32281cb6ddcSMark Murray mask |= i; 32381cb6ddcSMark Murray printf("%s: %s\n", AUTHTYPE_NAME(ap->type), 32481cb6ddcSMark Murray (i_wont_support & typemask(ap->type)) ? 32581cb6ddcSMark Murray "disabled" : "enabled"); 32681cb6ddcSMark Murray } 32781cb6ddcSMark Murray return(1); 32881cb6ddcSMark Murray } 32981cb6ddcSMark Murray 33081cb6ddcSMark Murray /* 33181cb6ddcSMark Murray * This routine is called by the server to start authentication 33281cb6ddcSMark Murray * negotiation. 33381cb6ddcSMark Murray */ 33481cb6ddcSMark Murray void 3358fa113e5SMark Murray auth_request(void) 33681cb6ddcSMark Murray { 33781cb6ddcSMark Murray static unsigned char str_request[64] = { IAC, SB, 33881cb6ddcSMark Murray TELOPT_AUTHENTICATION, 33981cb6ddcSMark Murray TELQUAL_SEND, }; 34081cb6ddcSMark Murray Authenticator *ap = authenticators; 34181cb6ddcSMark Murray unsigned char *e = str_request + 4; 34281cb6ddcSMark Murray 34381cb6ddcSMark Murray if (!authenticating) { 34481cb6ddcSMark Murray authenticating = 1; 34581cb6ddcSMark Murray while (ap->type) { 34681cb6ddcSMark Murray if (i_support & ~i_wont_support & typemask(ap->type)) { 34781cb6ddcSMark Murray if (auth_debug_mode) { 34881cb6ddcSMark Murray printf(">>>%s: Sending type %d %d\r\n", 34981cb6ddcSMark Murray Name, ap->type, ap->way); 35081cb6ddcSMark Murray } 35181cb6ddcSMark Murray *e++ = ap->type; 35281cb6ddcSMark Murray *e++ = ap->way; 35381cb6ddcSMark Murray } 35481cb6ddcSMark Murray ++ap; 35581cb6ddcSMark Murray } 35681cb6ddcSMark Murray *e++ = IAC; 35781cb6ddcSMark Murray *e++ = SE; 35881cb6ddcSMark Murray net_write(str_request, e - str_request); 35981cb6ddcSMark Murray printsub('>', &str_request[2], e - str_request - 2); 36081cb6ddcSMark Murray } 36181cb6ddcSMark Murray } 36281cb6ddcSMark Murray 36381cb6ddcSMark Murray /* 36481cb6ddcSMark Murray * This is called when an AUTH SEND is received. 36581cb6ddcSMark Murray * It should never arrive on the server side (as only the server can 36681cb6ddcSMark Murray * send an AUTH SEND). 36781cb6ddcSMark Murray * You should probably respond to it if you can... 36881cb6ddcSMark Murray * 36981cb6ddcSMark Murray * If you want to respond to the types out of order (i.e. even 37081cb6ddcSMark Murray * if he sends LOGIN KERBEROS and you support both, you respond 37181cb6ddcSMark Murray * with KERBEROS instead of LOGIN (which is against what the 37281cb6ddcSMark Murray * protocol says)) you will have to hack this code... 37381cb6ddcSMark Murray */ 37481cb6ddcSMark Murray void 3758fa113e5SMark Murray auth_send(unsigned char *data, int cnt) 37681cb6ddcSMark Murray { 37781cb6ddcSMark Murray Authenticator *ap; 37881cb6ddcSMark Murray static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION, 37981cb6ddcSMark Murray TELQUAL_IS, AUTHTYPE_NULL, 0, 38081cb6ddcSMark Murray IAC, SE }; 38181cb6ddcSMark Murray if (Server) { 38281cb6ddcSMark Murray if (auth_debug_mode) { 38381cb6ddcSMark Murray printf(">>>%s: auth_send called!\r\n", Name); 38481cb6ddcSMark Murray } 38581cb6ddcSMark Murray return; 38681cb6ddcSMark Murray } 38781cb6ddcSMark Murray 38881cb6ddcSMark Murray if (auth_debug_mode) { 38981cb6ddcSMark Murray printf(">>>%s: auth_send got:", Name); 39081cb6ddcSMark Murray printd(data, cnt); printf("\r\n"); 39181cb6ddcSMark Murray } 39281cb6ddcSMark Murray 39381cb6ddcSMark Murray /* 39481cb6ddcSMark Murray * Save the data, if it is new, so that we can continue looking 39581cb6ddcSMark Murray * at it if the authorization we try doesn't work 39681cb6ddcSMark Murray */ 39781cb6ddcSMark Murray if (data < _auth_send_data || 39881cb6ddcSMark Murray data > _auth_send_data + sizeof(_auth_send_data)) { 3998fa113e5SMark Murray auth_send_cnt = (size_t)cnt > sizeof(_auth_send_data) 40081cb6ddcSMark Murray ? sizeof(_auth_send_data) 40181cb6ddcSMark Murray : cnt; 40281cb6ddcSMark Murray memmove((void *)_auth_send_data, (void *)data, auth_send_cnt); 40381cb6ddcSMark Murray auth_send_data = _auth_send_data; 40481cb6ddcSMark Murray } else { 40581cb6ddcSMark Murray /* 40681cb6ddcSMark Murray * This is probably a no-op, but we just make sure 40781cb6ddcSMark Murray */ 40881cb6ddcSMark Murray auth_send_data = data; 40981cb6ddcSMark Murray auth_send_cnt = cnt; 41081cb6ddcSMark Murray } 41181cb6ddcSMark Murray while ((auth_send_cnt -= 2) >= 0) { 41281cb6ddcSMark Murray if (auth_debug_mode) 41381cb6ddcSMark Murray printf(">>>%s: He supports %d\r\n", 41481cb6ddcSMark Murray Name, *auth_send_data); 41581cb6ddcSMark Murray if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) { 41681cb6ddcSMark Murray ap = findauthenticator(auth_send_data[0], 41781cb6ddcSMark Murray auth_send_data[1]); 41881cb6ddcSMark Murray if (ap && ap->send) { 41981cb6ddcSMark Murray if (auth_debug_mode) 42081cb6ddcSMark Murray printf(">>>%s: Trying %d %d\r\n", 42181cb6ddcSMark Murray Name, auth_send_data[0], 42281cb6ddcSMark Murray auth_send_data[1]); 42381cb6ddcSMark Murray if ((*ap->send)(ap)) { 42481cb6ddcSMark Murray /* 42581cb6ddcSMark Murray * Okay, we found one we like 42681cb6ddcSMark Murray * and did it. 42781cb6ddcSMark Murray * we can go home now. 42881cb6ddcSMark Murray */ 42981cb6ddcSMark Murray if (auth_debug_mode) 43081cb6ddcSMark Murray printf(">>>%s: Using type %d\r\n", 43181cb6ddcSMark Murray Name, *auth_send_data); 43281cb6ddcSMark Murray auth_send_data += 2; 43381cb6ddcSMark Murray return; 43481cb6ddcSMark Murray } 43581cb6ddcSMark Murray } 43681cb6ddcSMark Murray /* else 43781cb6ddcSMark Murray * just continue on and look for the 43881cb6ddcSMark Murray * next one if we didn't do anything. 43981cb6ddcSMark Murray */ 44081cb6ddcSMark Murray } 44181cb6ddcSMark Murray auth_send_data += 2; 44281cb6ddcSMark Murray } 44381cb6ddcSMark Murray net_write(str_none, sizeof(str_none)); 44481cb6ddcSMark Murray printsub('>', &str_none[2], sizeof(str_none) - 2); 44581cb6ddcSMark Murray if (auth_debug_mode) 44681cb6ddcSMark Murray printf(">>>%s: Sent failure message\r\n", Name); 44781cb6ddcSMark Murray auth_finished(0, AUTH_REJECT); 44881cb6ddcSMark Murray } 44981cb6ddcSMark Murray 45081cb6ddcSMark Murray void 4518fa113e5SMark Murray auth_send_retry(void) 45281cb6ddcSMark Murray { 45381cb6ddcSMark Murray /* 45481cb6ddcSMark Murray * if auth_send_cnt <= 0 then auth_send will end up rejecting 45581cb6ddcSMark Murray * the authentication and informing the other side of this. 45681cb6ddcSMark Murray */ 45781cb6ddcSMark Murray auth_send(auth_send_data, auth_send_cnt); 45881cb6ddcSMark Murray } 45981cb6ddcSMark Murray 46081cb6ddcSMark Murray void 4618fa113e5SMark Murray auth_is(unsigned char *data, int cnt) 46281cb6ddcSMark Murray { 46381cb6ddcSMark Murray Authenticator *ap; 46481cb6ddcSMark Murray 46581cb6ddcSMark Murray if (cnt < 2) 46681cb6ddcSMark Murray return; 46781cb6ddcSMark Murray 46881cb6ddcSMark Murray if (data[0] == AUTHTYPE_NULL) { 46981cb6ddcSMark Murray auth_finished(0, AUTH_REJECT); 47081cb6ddcSMark Murray return; 47181cb6ddcSMark Murray } 47281cb6ddcSMark Murray 47304c426ccSMark Murray if ((ap = findauthenticator(data[0], data[1]))) { 47481cb6ddcSMark Murray if (ap->is) 47581cb6ddcSMark Murray (*ap->is)(ap, data+2, cnt-2); 47681cb6ddcSMark Murray } else if (auth_debug_mode) 47781cb6ddcSMark Murray printf(">>>%s: Invalid authentication in IS: %d\r\n", 47881cb6ddcSMark Murray Name, *data); 47981cb6ddcSMark Murray } 48081cb6ddcSMark Murray 48181cb6ddcSMark Murray void 4828fa113e5SMark Murray auth_reply(unsigned char *data, int cnt) 48381cb6ddcSMark Murray { 48481cb6ddcSMark Murray Authenticator *ap; 48581cb6ddcSMark Murray 48681cb6ddcSMark Murray if (cnt < 2) 48781cb6ddcSMark Murray return; 48881cb6ddcSMark Murray 48904c426ccSMark Murray if ((ap = findauthenticator(data[0], data[1]))) { 49081cb6ddcSMark Murray if (ap->reply) 49181cb6ddcSMark Murray (*ap->reply)(ap, data+2, cnt-2); 49281cb6ddcSMark Murray } else if (auth_debug_mode) 49381cb6ddcSMark Murray printf(">>>%s: Invalid authentication in SEND: %d\r\n", 49481cb6ddcSMark Murray Name, *data); 49581cb6ddcSMark Murray } 49681cb6ddcSMark Murray 49781cb6ddcSMark Murray void 4988fa113e5SMark Murray auth_name(unsigned char *data, int cnt) 49981cb6ddcSMark Murray { 50081cb6ddcSMark Murray unsigned char savename[256]; 50181cb6ddcSMark Murray 50281cb6ddcSMark Murray if (cnt < 1) { 50381cb6ddcSMark Murray if (auth_debug_mode) 50481cb6ddcSMark Murray printf(">>>%s: Empty name in NAME\r\n", Name); 50581cb6ddcSMark Murray return; 50681cb6ddcSMark Murray } 5078fa113e5SMark Murray if ((size_t)cnt > sizeof(savename) - 1) { 50881cb6ddcSMark Murray if (auth_debug_mode) 50981cb6ddcSMark Murray printf(">>>%s: Name in NAME (%d) exceeds %d length\r\n", 51054ab3ed8SMark Murray Name, cnt, (u_int)sizeof(savename)-1); 51181cb6ddcSMark Murray return; 51281cb6ddcSMark Murray } 51381cb6ddcSMark Murray memmove((void *)savename, (void *)data, cnt); 51481cb6ddcSMark Murray savename[cnt] = '\0'; /* Null terminate */ 51581cb6ddcSMark Murray if (auth_debug_mode) 51681cb6ddcSMark Murray printf(">>>%s: Got NAME [%s]\r\n", Name, savename); 51781cb6ddcSMark Murray auth_encrypt_user(savename); 51881cb6ddcSMark Murray } 51981cb6ddcSMark Murray 52081cb6ddcSMark Murray int 5218fa113e5SMark Murray auth_sendname(unsigned char *cp, int len) 52281cb6ddcSMark Murray { 52381cb6ddcSMark Murray static unsigned char str_request[256+6] 52481cb6ddcSMark Murray = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, }; 5258fa113e5SMark Murray unsigned char *e = str_request + 4; 5268fa113e5SMark Murray unsigned char *ee = &str_request[sizeof(str_request)-2]; 52781cb6ddcSMark Murray 52881cb6ddcSMark Murray while (--len >= 0) { 52981cb6ddcSMark Murray if ((*e++ = *cp++) == IAC) 53081cb6ddcSMark Murray *e++ = IAC; 53181cb6ddcSMark Murray if (e >= ee) 53281cb6ddcSMark Murray return(0); 53381cb6ddcSMark Murray } 53481cb6ddcSMark Murray *e++ = IAC; 53581cb6ddcSMark Murray *e++ = SE; 53681cb6ddcSMark Murray net_write(str_request, e - str_request); 53781cb6ddcSMark Murray printsub('>', &str_request[2], e - &str_request[2]); 53881cb6ddcSMark Murray return(1); 53981cb6ddcSMark Murray } 54081cb6ddcSMark Murray 54181cb6ddcSMark Murray void 5428fa113e5SMark Murray auth_finished(Authenticator *ap, int result) 54381cb6ddcSMark Murray { 54481cb6ddcSMark Murray if (!(authenticated = ap)) 54581cb6ddcSMark Murray authenticated = &NoAuth; 54681cb6ddcSMark Murray validuser = result; 54781cb6ddcSMark Murray } 54881cb6ddcSMark Murray 54981cb6ddcSMark Murray /* ARGSUSED */ 55081cb6ddcSMark Murray static void 5518fa113e5SMark Murray auth_intr(int sig __unused) 55281cb6ddcSMark Murray { 55381cb6ddcSMark Murray auth_finished(0, AUTH_REJECT); 55481cb6ddcSMark Murray } 55581cb6ddcSMark Murray 55681cb6ddcSMark Murray int 5578fa113e5SMark Murray auth_wait(char *name) 55881cb6ddcSMark Murray { 55981cb6ddcSMark Murray if (auth_debug_mode) 56081cb6ddcSMark Murray printf(">>>%s: in auth_wait.\r\n", Name); 56181cb6ddcSMark Murray 56281cb6ddcSMark Murray if (Server && !authenticating) 56381cb6ddcSMark Murray return(0); 56481cb6ddcSMark Murray 56581cb6ddcSMark Murray (void) signal(SIGALRM, auth_intr); 56681cb6ddcSMark Murray alarm(30); 56781cb6ddcSMark Murray while (!authenticated) 56881cb6ddcSMark Murray if (telnet_spin()) 56981cb6ddcSMark Murray break; 57081cb6ddcSMark Murray alarm(0); 57181cb6ddcSMark Murray (void) signal(SIGALRM, SIG_DFL); 57281cb6ddcSMark Murray 57381cb6ddcSMark Murray /* 57481cb6ddcSMark Murray * Now check to see if the user is valid or not 57581cb6ddcSMark Murray */ 57681cb6ddcSMark Murray if (!authenticated || authenticated == &NoAuth) 57781cb6ddcSMark Murray return(AUTH_REJECT); 57881cb6ddcSMark Murray 57981cb6ddcSMark Murray if (validuser == AUTH_VALID) 58081cb6ddcSMark Murray validuser = AUTH_USER; 58181cb6ddcSMark Murray 58281cb6ddcSMark Murray if (authenticated->status) 58381cb6ddcSMark Murray validuser = (*authenticated->status)(authenticated, 58481cb6ddcSMark Murray name, validuser); 58581cb6ddcSMark Murray return(validuser); 58681cb6ddcSMark Murray } 58781cb6ddcSMark Murray 58881cb6ddcSMark Murray void 5898fa113e5SMark Murray auth_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 59081cb6ddcSMark Murray { 59181cb6ddcSMark Murray Authenticator *ap; 59281cb6ddcSMark Murray 59381cb6ddcSMark Murray if ((ap = findauthenticator(data[1], data[2])) && ap->printsub) 59481cb6ddcSMark Murray (*ap->printsub)(data, cnt, buf, buflen); 59581cb6ddcSMark Murray else 59681cb6ddcSMark Murray auth_gen_printsub(data, cnt, buf, buflen); 59781cb6ddcSMark Murray } 59881cb6ddcSMark Murray 59981cb6ddcSMark Murray void 6008fa113e5SMark Murray auth_gen_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 60181cb6ddcSMark Murray { 6028fa113e5SMark Murray unsigned char *cp; 60381cb6ddcSMark Murray unsigned char tbuf[16]; 60481cb6ddcSMark Murray 60581cb6ddcSMark Murray cnt -= 3; 60681cb6ddcSMark Murray data += 3; 60781cb6ddcSMark Murray buf[buflen-1] = '\0'; 60881cb6ddcSMark Murray buf[buflen-2] = '*'; 60981cb6ddcSMark Murray buflen -= 2; 61081cb6ddcSMark Murray for (; cnt > 0; cnt--, data++) { 61181cb6ddcSMark Murray sprintf((char *)tbuf, " %d", *data); 61281cb6ddcSMark Murray for (cp = tbuf; *cp && buflen > 0; --buflen) 61381cb6ddcSMark Murray *buf++ = *cp++; 61481cb6ddcSMark Murray if (buflen <= 0) 61581cb6ddcSMark Murray return; 61681cb6ddcSMark Murray } 61781cb6ddcSMark Murray *buf = '\0'; 61881cb6ddcSMark Murray } 61981cb6ddcSMark Murray #endif 620