1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*7c478bd9Sstevel@tonic-gate 8*7c478bd9Sstevel@tonic-gate /* 9*7c478bd9Sstevel@tonic-gate * usr/src/cmd/cmd-inet/usr.bin/telnet/auth.c 10*7c478bd9Sstevel@tonic-gate */ 11*7c478bd9Sstevel@tonic-gate 12*7c478bd9Sstevel@tonic-gate /* 13*7c478bd9Sstevel@tonic-gate * Copyright (c) 1991, 1993 14*7c478bd9Sstevel@tonic-gate * The Regents of the University of California. All rights reserved. 15*7c478bd9Sstevel@tonic-gate * 16*7c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 17*7c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions 18*7c478bd9Sstevel@tonic-gate * are met: 19*7c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 20*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 21*7c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 22*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 23*7c478bd9Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 24*7c478bd9Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 25*7c478bd9Sstevel@tonic-gate * must display the following acknowledgement: 26*7c478bd9Sstevel@tonic-gate * This product includes software developed by the University of 27*7c478bd9Sstevel@tonic-gate * California, Berkeley and its contributors. 28*7c478bd9Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors 29*7c478bd9Sstevel@tonic-gate * may be used to endorse or promote products derived from this software 30*7c478bd9Sstevel@tonic-gate * without specific prior written permission. 31*7c478bd9Sstevel@tonic-gate * 32*7c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33*7c478bd9Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34*7c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35*7c478bd9Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36*7c478bd9Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37*7c478bd9Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38*7c478bd9Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39*7c478bd9Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40*7c478bd9Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41*7c478bd9Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42*7c478bd9Sstevel@tonic-gate * SUCH DAMAGE. 43*7c478bd9Sstevel@tonic-gate */ 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate /* based on @(#)auth.c 8.1 (Berkeley) 6/4/93 */ 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate /* 48*7c478bd9Sstevel@tonic-gate * Copyright (C) 1990 by the Massachusetts Institute of Technology 49*7c478bd9Sstevel@tonic-gate * 50*7c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 51*7c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 52*7c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 53*7c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 54*7c478bd9Sstevel@tonic-gate * 55*7c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 56*7c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 57*7c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 58*7c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 59*7c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 60*7c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 61*7c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 62*7c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 63*7c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 64*7c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 65*7c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 66*7c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 67*7c478bd9Sstevel@tonic-gate * or implied warranty. 68*7c478bd9Sstevel@tonic-gate */ 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate #include <stdio.h> 72*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 73*7c478bd9Sstevel@tonic-gate #include <signal.h> 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate #define AUTHTYPE_NAMES /* this is needed for arpa/telnet.h */ 76*7c478bd9Sstevel@tonic-gate #include <arpa/telnet.h> 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 79*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 80*7c478bd9Sstevel@tonic-gate #endif 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate #include <string.h> 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate #include "externs.h" 85*7c478bd9Sstevel@tonic-gate #include "encrypt.h" 86*7c478bd9Sstevel@tonic-gate #include "auth.h" 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate static int auth_onoff(const char *type, boolean_t on); 91*7c478bd9Sstevel@tonic-gate static void auth_gen_printsub(uchar_t *, uint_t, uchar_t *, uint_t); 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate boolean_t auth_debug_mode = B_FALSE; 94*7c478bd9Sstevel@tonic-gate boolean_t auth_has_failed = B_FALSE; 95*7c478bd9Sstevel@tonic-gate boolean_t auth_enable_encrypt = B_FALSE; 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate static char *Name = "Noname"; 98*7c478bd9Sstevel@tonic-gate static Authenticator *authenticated = NULL; 99*7c478bd9Sstevel@tonic-gate static uchar_t _auth_send_data[BUFSIZ]; 100*7c478bd9Sstevel@tonic-gate static uchar_t *auth_send_data; 101*7c478bd9Sstevel@tonic-gate static int auth_send_cnt = 0; 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate /* 104*7c478bd9Sstevel@tonic-gate * Authentication types supported. Note that these are stored 105*7c478bd9Sstevel@tonic-gate * in priority order, i.e. try the first one first. 106*7c478bd9Sstevel@tonic-gate */ 107*7c478bd9Sstevel@tonic-gate static Authenticator authenticators[] = { 108*7c478bd9Sstevel@tonic-gate { AUTHTYPE_KERBEROS_V5, 109*7c478bd9Sstevel@tonic-gate AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL|AUTH_ENCRYPT_ON, 110*7c478bd9Sstevel@tonic-gate kerberos5_init, 111*7c478bd9Sstevel@tonic-gate kerberos5_send, 112*7c478bd9Sstevel@tonic-gate kerberos5_reply, 113*7c478bd9Sstevel@tonic-gate kerberos5_status, 114*7c478bd9Sstevel@tonic-gate kerberos5_printsub }, 115*7c478bd9Sstevel@tonic-gate { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 116*7c478bd9Sstevel@tonic-gate kerberos5_init, 117*7c478bd9Sstevel@tonic-gate kerberos5_send, 118*7c478bd9Sstevel@tonic-gate kerberos5_reply, 119*7c478bd9Sstevel@tonic-gate kerberos5_status, 120*7c478bd9Sstevel@tonic-gate kerberos5_printsub }, 121*7c478bd9Sstevel@tonic-gate { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 122*7c478bd9Sstevel@tonic-gate kerberos5_init, 123*7c478bd9Sstevel@tonic-gate kerberos5_send, 124*7c478bd9Sstevel@tonic-gate kerberos5_reply, 125*7c478bd9Sstevel@tonic-gate kerberos5_status, 126*7c478bd9Sstevel@tonic-gate kerberos5_printsub }, 127*7c478bd9Sstevel@tonic-gate { 0, }, 128*7c478bd9Sstevel@tonic-gate }; 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate static Authenticator NoAuth = { 0 }; 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate static uint_t i_support = 0; 133*7c478bd9Sstevel@tonic-gate static uint_t i_wont_support = 0; 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate /* 136*7c478bd9Sstevel@tonic-gate * Traverse the Authenticator array until we find the authentication type 137*7c478bd9Sstevel@tonic-gate * and matching direction we are looking for. Return a pointer into the 138*7c478bd9Sstevel@tonic-gate * Authenticator type array. 139*7c478bd9Sstevel@tonic-gate * 140*7c478bd9Sstevel@tonic-gate * Returns: 0 - type not found (error) 141*7c478bd9Sstevel@tonic-gate * nonzero - pointer to authenticator 142*7c478bd9Sstevel@tonic-gate */ 143*7c478bd9Sstevel@tonic-gate static Authenticator * 144*7c478bd9Sstevel@tonic-gate findauthenticator(int type, int way) 145*7c478bd9Sstevel@tonic-gate { 146*7c478bd9Sstevel@tonic-gate Authenticator *ap = authenticators; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate while (ap->type && (ap->type != type || ap->way != way)) 149*7c478bd9Sstevel@tonic-gate ++ap; 150*7c478bd9Sstevel@tonic-gate return (ap->type ? ap : NULL); 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate /* 154*7c478bd9Sstevel@tonic-gate * For each authentication type in the Authenticator array, 155*7c478bd9Sstevel@tonic-gate * call the associated init routine, and update the i_support bitfield. 156*7c478bd9Sstevel@tonic-gate */ 157*7c478bd9Sstevel@tonic-gate void 158*7c478bd9Sstevel@tonic-gate auth_init(const char *name) 159*7c478bd9Sstevel@tonic-gate { 160*7c478bd9Sstevel@tonic-gate Authenticator *ap = authenticators; 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate Name = name ? strdup(name) : "Noname"; 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate i_support = 0; 165*7c478bd9Sstevel@tonic-gate authenticated = NULL; 166*7c478bd9Sstevel@tonic-gate while (ap->type) { 167*7c478bd9Sstevel@tonic-gate if (!ap->init || (*ap->init)(ap)) { 168*7c478bd9Sstevel@tonic-gate i_support |= typemask(ap->type); 169*7c478bd9Sstevel@tonic-gate if (auth_debug_mode) 170*7c478bd9Sstevel@tonic-gate (void) printf(gettext 171*7c478bd9Sstevel@tonic-gate (">>>%s: I support auth type %d %d\r\n"), 172*7c478bd9Sstevel@tonic-gate Name, ap->type, ap->way); 173*7c478bd9Sstevel@tonic-gate } 174*7c478bd9Sstevel@tonic-gate ++ap; 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate /* 179*7c478bd9Sstevel@tonic-gate * Search the Authenticator array for the authentication type 'name', 180*7c478bd9Sstevel@tonic-gate * and disable this type by updating the i_wont_support bitfield. 181*7c478bd9Sstevel@tonic-gate */ 182*7c478bd9Sstevel@tonic-gate void 183*7c478bd9Sstevel@tonic-gate auth_disable_name(const char *name) 184*7c478bd9Sstevel@tonic-gate { 185*7c478bd9Sstevel@tonic-gate uint_t x; 186*7c478bd9Sstevel@tonic-gate for (x = 0; x < AUTHTYPE_CNT; ++x) { 187*7c478bd9Sstevel@tonic-gate if (!strcasecmp(name, AUTHTYPE_NAME(x))) { 188*7c478bd9Sstevel@tonic-gate i_wont_support |= typemask(x); 189*7c478bd9Sstevel@tonic-gate break; 190*7c478bd9Sstevel@tonic-gate } 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate if (!i_wont_support) 194*7c478bd9Sstevel@tonic-gate (void) printf( 195*7c478bd9Sstevel@tonic-gate gettext("%s : invalid authentication type\n"), 196*7c478bd9Sstevel@tonic-gate name); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate /* 200*7c478bd9Sstevel@tonic-gate * Search the Authenticator array for the authentication type given 201*7c478bd9Sstevel@tonic-gate * by the character string 'type', and return its integer bitmask 202*7c478bd9Sstevel@tonic-gate * in maskp. 203*7c478bd9Sstevel@tonic-gate * 204*7c478bd9Sstevel@tonic-gate * Returns: 1 - no error 205*7c478bd9Sstevel@tonic-gate * 0 - type not found (error) 206*7c478bd9Sstevel@tonic-gate */ 207*7c478bd9Sstevel@tonic-gate static int 208*7c478bd9Sstevel@tonic-gate getauthmask(const char *type, uint_t *maskp) 209*7c478bd9Sstevel@tonic-gate { 210*7c478bd9Sstevel@tonic-gate uint_t x; 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate if (!strcasecmp(type, AUTHTYPE_NAME(0))) { 213*7c478bd9Sstevel@tonic-gate *maskp = (uint_t)-1; 214*7c478bd9Sstevel@tonic-gate return (1); 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate for (x = 1; x < AUTHTYPE_CNT; ++x) { 218*7c478bd9Sstevel@tonic-gate if (!strcasecmp(type, AUTHTYPE_NAME(x))) { 219*7c478bd9Sstevel@tonic-gate *maskp = typemask(x); 220*7c478bd9Sstevel@tonic-gate return (1); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate return (0); 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate int 227*7c478bd9Sstevel@tonic-gate auth_enable(char *type) 228*7c478bd9Sstevel@tonic-gate { 229*7c478bd9Sstevel@tonic-gate return (auth_onoff(type, B_TRUE)); 230*7c478bd9Sstevel@tonic-gate } 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate int 233*7c478bd9Sstevel@tonic-gate auth_disable(char *type) 234*7c478bd9Sstevel@tonic-gate { 235*7c478bd9Sstevel@tonic-gate return (auth_onoff(type, B_FALSE)); 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate /* 239*7c478bd9Sstevel@tonic-gate * Responds to the 'auth enable <option>' and 'auth disable <option>' commands. 240*7c478bd9Sstevel@tonic-gate * 241*7c478bd9Sstevel@tonic-gate * If <option> is: 242*7c478bd9Sstevel@tonic-gate * - a valid authentication type, turns support on / off 243*7c478bd9Sstevel@tonic-gate * - "?" or "help", print a usage message 244*7c478bd9Sstevel@tonic-gate * - not recognized, print an error message. 245*7c478bd9Sstevel@tonic-gate * 246*7c478bd9Sstevel@tonic-gate * Returns: 1 - no error, authentication is enabled or disabled 247*7c478bd9Sstevel@tonic-gate * 0 - error, or help requested 248*7c478bd9Sstevel@tonic-gate */ 249*7c478bd9Sstevel@tonic-gate static int 250*7c478bd9Sstevel@tonic-gate auth_onoff(const char *type, boolean_t on) 251*7c478bd9Sstevel@tonic-gate { 252*7c478bd9Sstevel@tonic-gate uint_t i, mask = 0; 253*7c478bd9Sstevel@tonic-gate Authenticator *ap; 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) { 256*7c478bd9Sstevel@tonic-gate (void) printf(on ? 257*7c478bd9Sstevel@tonic-gate gettext("auth enable 'type'\n") : 258*7c478bd9Sstevel@tonic-gate gettext("auth disable 'type'\n")); 259*7c478bd9Sstevel@tonic-gate (void) printf( 260*7c478bd9Sstevel@tonic-gate gettext("Where 'type' is one of:\n")); 261*7c478bd9Sstevel@tonic-gate (void) printf("\t%s\n", AUTHTYPE_NAME(0)); 262*7c478bd9Sstevel@tonic-gate for (ap = authenticators; ap->type; ap++) { 263*7c478bd9Sstevel@tonic-gate if ((mask & (i = typemask(ap->type))) != 0) 264*7c478bd9Sstevel@tonic-gate continue; 265*7c478bd9Sstevel@tonic-gate mask |= i; 266*7c478bd9Sstevel@tonic-gate (void) printf("\t%s\n", AUTHTYPE_NAME(ap->type)); 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate return (0); 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate if (!getauthmask(type, &mask)) { 272*7c478bd9Sstevel@tonic-gate (void) printf( 273*7c478bd9Sstevel@tonic-gate gettext("%s: invalid authentication type\n"), type); 274*7c478bd9Sstevel@tonic-gate return (0); 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate if (on) 277*7c478bd9Sstevel@tonic-gate i_wont_support &= ~mask; 278*7c478bd9Sstevel@tonic-gate else 279*7c478bd9Sstevel@tonic-gate i_wont_support |= mask; 280*7c478bd9Sstevel@tonic-gate return (1); 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate /* 284*7c478bd9Sstevel@tonic-gate * Responds to the 'toggle authdebug' command. 285*7c478bd9Sstevel@tonic-gate * 286*7c478bd9Sstevel@tonic-gate * Returns: 1 - always 287*7c478bd9Sstevel@tonic-gate */ 288*7c478bd9Sstevel@tonic-gate int 289*7c478bd9Sstevel@tonic-gate auth_togdebug(int on) 290*7c478bd9Sstevel@tonic-gate { 291*7c478bd9Sstevel@tonic-gate if (on < 0) 292*7c478bd9Sstevel@tonic-gate auth_debug_mode = !auth_debug_mode; 293*7c478bd9Sstevel@tonic-gate else 294*7c478bd9Sstevel@tonic-gate auth_debug_mode = on > 0 ? B_TRUE : B_FALSE; 295*7c478bd9Sstevel@tonic-gate (void) printf(auth_debug_mode ? 296*7c478bd9Sstevel@tonic-gate gettext("auth debugging enabled\n") : 297*7c478bd9Sstevel@tonic-gate gettext("auth debugging disabled\n")); 298*7c478bd9Sstevel@tonic-gate return (1); 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate /* 302*7c478bd9Sstevel@tonic-gate * Responds to the 'auth status' command. 303*7c478bd9Sstevel@tonic-gate * Traverses the authenticator array and prints enabled or disabled for 304*7c478bd9Sstevel@tonic-gate * each authentication type, depencing on the i_wont_support bitfield. 305*7c478bd9Sstevel@tonic-gate * 306*7c478bd9Sstevel@tonic-gate * Returns: 1 - always 307*7c478bd9Sstevel@tonic-gate */ 308*7c478bd9Sstevel@tonic-gate int 309*7c478bd9Sstevel@tonic-gate auth_status(void) 310*7c478bd9Sstevel@tonic-gate { 311*7c478bd9Sstevel@tonic-gate Authenticator *ap; 312*7c478bd9Sstevel@tonic-gate uint_t i, mask; 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate if (i_wont_support == (uint_t)-1) 315*7c478bd9Sstevel@tonic-gate (void) printf(gettext("Authentication disabled\n")); 316*7c478bd9Sstevel@tonic-gate else 317*7c478bd9Sstevel@tonic-gate (void) printf(gettext("Authentication enabled\n")); 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate mask = 0; 320*7c478bd9Sstevel@tonic-gate for (ap = authenticators; ap->type; ap++) { 321*7c478bd9Sstevel@tonic-gate if ((mask & (i = typemask(ap->type))) != 0) 322*7c478bd9Sstevel@tonic-gate continue; 323*7c478bd9Sstevel@tonic-gate mask |= i; 324*7c478bd9Sstevel@tonic-gate (void) printf("%s: %s\n", AUTHTYPE_NAME(ap->type), 325*7c478bd9Sstevel@tonic-gate (i_wont_support & typemask(ap->type)) ? 326*7c478bd9Sstevel@tonic-gate gettext("disabled") : gettext("enabled")); 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate return (1); 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate /* 332*7c478bd9Sstevel@tonic-gate * This is called when an AUTH SEND is received. 333*7c478bd9Sstevel@tonic-gate * data is a list of authentication mechanisms we support 334*7c478bd9Sstevel@tonic-gate */ 335*7c478bd9Sstevel@tonic-gate void 336*7c478bd9Sstevel@tonic-gate auth_send(uchar_t *data, int cnt) 337*7c478bd9Sstevel@tonic-gate { 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate if (auth_debug_mode) { 340*7c478bd9Sstevel@tonic-gate (void) printf(gettext(">>>%s: auth_send got:"), Name); 341*7c478bd9Sstevel@tonic-gate printd(data, cnt); 342*7c478bd9Sstevel@tonic-gate (void) printf("\r\n"); 343*7c478bd9Sstevel@tonic-gate } 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate /* 346*7c478bd9Sstevel@tonic-gate * Save the list of authentication mechanisms 347*7c478bd9Sstevel@tonic-gate */ 348*7c478bd9Sstevel@tonic-gate auth_send_cnt = cnt; 349*7c478bd9Sstevel@tonic-gate if (auth_send_cnt > sizeof (_auth_send_data)) 350*7c478bd9Sstevel@tonic-gate auth_send_cnt = sizeof (_auth_send_data); 351*7c478bd9Sstevel@tonic-gate (void) memcpy((void *)_auth_send_data, (void *)data, auth_send_cnt); 352*7c478bd9Sstevel@tonic-gate auth_send_data = _auth_send_data; 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate auth_send_retry(); 355*7c478bd9Sstevel@tonic-gate } 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate /* 358*7c478bd9Sstevel@tonic-gate * Try the next authentication mechanism on the list, and see if it 359*7c478bd9Sstevel@tonic-gate * works. 360*7c478bd9Sstevel@tonic-gate */ 361*7c478bd9Sstevel@tonic-gate void 362*7c478bd9Sstevel@tonic-gate auth_send_retry(void) 363*7c478bd9Sstevel@tonic-gate { 364*7c478bd9Sstevel@tonic-gate Authenticator *ap; 365*7c478bd9Sstevel@tonic-gate static uchar_t str_none[] = { IAC, SB, TELOPT_AUTHENTICATION, 366*7c478bd9Sstevel@tonic-gate TELQUAL_IS, AUTHTYPE_NULL, 0, IAC, SE }; 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate for (; (auth_send_cnt -= 2) >= 0; auth_send_data += 2) { 369*7c478bd9Sstevel@tonic-gate if (auth_debug_mode) 370*7c478bd9Sstevel@tonic-gate (void) printf( 371*7c478bd9Sstevel@tonic-gate gettext(">>>%s: Remote host supports %d\r\n"), 372*7c478bd9Sstevel@tonic-gate Name, *auth_send_data); 373*7c478bd9Sstevel@tonic-gate if (!(i_support & typemask(*auth_send_data))) 374*7c478bd9Sstevel@tonic-gate continue; 375*7c478bd9Sstevel@tonic-gate if (i_wont_support & typemask(*auth_send_data)) 376*7c478bd9Sstevel@tonic-gate continue; 377*7c478bd9Sstevel@tonic-gate ap = findauthenticator(auth_send_data[0], auth_send_data[1]); 378*7c478bd9Sstevel@tonic-gate if (!ap || !ap->send) 379*7c478bd9Sstevel@tonic-gate continue; 380*7c478bd9Sstevel@tonic-gate if ((ap->way & AUTH_ENCRYPT_MASK) && !auth_enable_encrypt) 381*7c478bd9Sstevel@tonic-gate continue; 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate if (auth_debug_mode) 384*7c478bd9Sstevel@tonic-gate (void) printf( 385*7c478bd9Sstevel@tonic-gate gettext(">>>%s: Trying %d %d\r\n"), Name, 386*7c478bd9Sstevel@tonic-gate auth_send_data[0], auth_send_data[1]); 387*7c478bd9Sstevel@tonic-gate if ((*ap->send)(ap)) { 388*7c478bd9Sstevel@tonic-gate /* 389*7c478bd9Sstevel@tonic-gate * Okay, we found one we like and did it. we can go 390*7c478bd9Sstevel@tonic-gate * home now. 391*7c478bd9Sstevel@tonic-gate */ 392*7c478bd9Sstevel@tonic-gate if (auth_debug_mode) 393*7c478bd9Sstevel@tonic-gate (void) printf(gettext(">>>%s: Using type %d\r\n"), 394*7c478bd9Sstevel@tonic-gate Name, *auth_send_data); 395*7c478bd9Sstevel@tonic-gate auth_send_data += 2; 396*7c478bd9Sstevel@tonic-gate return; 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate } 399*7c478bd9Sstevel@tonic-gate (void) net_write(str_none, sizeof (str_none)); 400*7c478bd9Sstevel@tonic-gate printsub('>', &str_none[2], sizeof (str_none) - 2); 401*7c478bd9Sstevel@tonic-gate if (auth_debug_mode) 402*7c478bd9Sstevel@tonic-gate (void) printf( 403*7c478bd9Sstevel@tonic-gate gettext(">>>%s: Sent failure message\r\n"), Name); 404*7c478bd9Sstevel@tonic-gate auth_finished(0, AUTH_REJECT); 405*7c478bd9Sstevel@tonic-gate auth_has_failed = B_TRUE; 406*7c478bd9Sstevel@tonic-gate } 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate void 409*7c478bd9Sstevel@tonic-gate auth_reply(uchar_t *data, int cnt) 410*7c478bd9Sstevel@tonic-gate { 411*7c478bd9Sstevel@tonic-gate Authenticator *ap; 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate if (cnt < 2) 414*7c478bd9Sstevel@tonic-gate return; 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate if (ap = findauthenticator(data[0], data[1])) { 417*7c478bd9Sstevel@tonic-gate if (ap->reply) 418*7c478bd9Sstevel@tonic-gate (*ap->reply)(ap, data+2, cnt-2); 419*7c478bd9Sstevel@tonic-gate } else if (auth_debug_mode) 420*7c478bd9Sstevel@tonic-gate (void) printf(gettext 421*7c478bd9Sstevel@tonic-gate (">>>%s: Invalid authentication in SEND: %d\r\n"), 422*7c478bd9Sstevel@tonic-gate Name, *data); 423*7c478bd9Sstevel@tonic-gate } 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate int 426*7c478bd9Sstevel@tonic-gate auth_sendname(uchar_t *cp, int len) 427*7c478bd9Sstevel@tonic-gate { 428*7c478bd9Sstevel@tonic-gate static uchar_t str_request[AUTH_NAME_BUFSIZ + 6] = { IAC, SB, 429*7c478bd9Sstevel@tonic-gate TELOPT_AUTHENTICATION, TELQUAL_NAME, }; 430*7c478bd9Sstevel@tonic-gate register uchar_t *e = str_request + 4; 431*7c478bd9Sstevel@tonic-gate register uchar_t *ee = &str_request[sizeof (str_request) - 2]; 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate while (--len >= 0) { 434*7c478bd9Sstevel@tonic-gate if ((*e++ = *cp++) == IAC) 435*7c478bd9Sstevel@tonic-gate *e++ = IAC; 436*7c478bd9Sstevel@tonic-gate if (e >= ee) 437*7c478bd9Sstevel@tonic-gate return (0); 438*7c478bd9Sstevel@tonic-gate } 439*7c478bd9Sstevel@tonic-gate *e++ = IAC; 440*7c478bd9Sstevel@tonic-gate *e++ = SE; 441*7c478bd9Sstevel@tonic-gate (void) net_write(str_request, e - str_request); 442*7c478bd9Sstevel@tonic-gate printsub('>', &str_request[2], e - &str_request[2]); 443*7c478bd9Sstevel@tonic-gate return (1); 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 447*7c478bd9Sstevel@tonic-gate void 448*7c478bd9Sstevel@tonic-gate auth_finished(Authenticator *ap, int result) 449*7c478bd9Sstevel@tonic-gate { 450*7c478bd9Sstevel@tonic-gate authenticated = ap; 451*7c478bd9Sstevel@tonic-gate if (authenticated == NULL) 452*7c478bd9Sstevel@tonic-gate authenticated = &NoAuth; 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate void 456*7c478bd9Sstevel@tonic-gate auth_printsub(uchar_t *data, uint_t cnt, uchar_t *buf, uint_t buflen) 457*7c478bd9Sstevel@tonic-gate { 458*7c478bd9Sstevel@tonic-gate Authenticator *ap; 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate ap = findauthenticator(data[1], data[2]); 461*7c478bd9Sstevel@tonic-gate if (ap && ap->printsub) 462*7c478bd9Sstevel@tonic-gate (*ap->printsub)(data, cnt, buf, buflen); 463*7c478bd9Sstevel@tonic-gate else 464*7c478bd9Sstevel@tonic-gate auth_gen_printsub(data, cnt, buf, buflen); 465*7c478bd9Sstevel@tonic-gate } 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate static void 468*7c478bd9Sstevel@tonic-gate auth_gen_printsub(uchar_t *data, uint_t cnt, uchar_t *buf, uint_t buflen) 469*7c478bd9Sstevel@tonic-gate { 470*7c478bd9Sstevel@tonic-gate register uchar_t *cp; 471*7c478bd9Sstevel@tonic-gate uchar_t lbuf[AUTH_LBUF_BUFSIZ]; 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate if (buflen < 2) 474*7c478bd9Sstevel@tonic-gate return; 475*7c478bd9Sstevel@tonic-gate cnt = (cnt > 3) ? cnt - 3 : 0; 476*7c478bd9Sstevel@tonic-gate data += 3; 477*7c478bd9Sstevel@tonic-gate buf[buflen - 1] = '\0'; 478*7c478bd9Sstevel@tonic-gate buf[buflen - 2] = '*'; 479*7c478bd9Sstevel@tonic-gate buflen -= 2; 480*7c478bd9Sstevel@tonic-gate for (; cnt > 0; cnt--, data++) { 481*7c478bd9Sstevel@tonic-gate (void) snprintf((char *)lbuf, AUTH_LBUF_BUFSIZ, " %d", *data); 482*7c478bd9Sstevel@tonic-gate for (cp = lbuf; (*cp != '\0') && (buflen > 0); --buflen) 483*7c478bd9Sstevel@tonic-gate *buf++ = *cp++; 484*7c478bd9Sstevel@tonic-gate if (buflen == 0) 485*7c478bd9Sstevel@tonic-gate return; 486*7c478bd9Sstevel@tonic-gate } 487*7c478bd9Sstevel@tonic-gate *buf = '\0'; 488*7c478bd9Sstevel@tonic-gate } 489