xref: /onnv-gate/usr/src/uts/common/io/scsi/adapters/iscsi/iscsiAuthClient.c (revision 8656:d00942080f9a)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
227836SJohn.Forte@Sun.COM  * Copyright 2000 by Cisco Systems, Inc.  All rights reserved.
23*8656SPeter.Dunlap@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247836SJohn.Forte@Sun.COM  * Use is subject to license terms.
257836SJohn.Forte@Sun.COM  *
267836SJohn.Forte@Sun.COM  * This file implements the iSCSI CHAP authentication method based.
277836SJohn.Forte@Sun.COM  * The code in this file is meant to be platform independent, and
287836SJohn.Forte@Sun.COM  * makes use of only limited library functions, presently only string.h.
297836SJohn.Forte@Sun.COM  * Platform dependent routines are  defined in iscsiAuthClient.h, but
307836SJohn.Forte@Sun.COM  * implemented in another file.
317836SJohn.Forte@Sun.COM  *
327836SJohn.Forte@Sun.COM  * This code in this files assumes a single thread of execution
337836SJohn.Forte@Sun.COM  * for each IscsiAuthClient structure, and does no locking.
347836SJohn.Forte@Sun.COM  */
357836SJohn.Forte@Sun.COM 
367836SJohn.Forte@Sun.COM #include "iscsi.h"
377836SJohn.Forte@Sun.COM #include "iscsiAuthClient.h"
387836SJohn.Forte@Sun.COM 
397836SJohn.Forte@Sun.COM 
407836SJohn.Forte@Sun.COM struct iscsiAuthKeyInfo_t {
417836SJohn.Forte@Sun.COM 	const char *name;
427836SJohn.Forte@Sun.COM };
437836SJohn.Forte@Sun.COM typedef struct iscsiAuthKeyInfo_t IscsiAuthKeyInfo;
447836SJohn.Forte@Sun.COM 
457836SJohn.Forte@Sun.COM 
467836SJohn.Forte@Sun.COM IscsiAuthClientGlobalStats iscsiAuthClientGlobalStats;
477836SJohn.Forte@Sun.COM 
487836SJohn.Forte@Sun.COM /*
497836SJohn.Forte@Sun.COM  * Note: The ordering of this table must match the order
507836SJohn.Forte@Sun.COM  *       defined by IscsiAuthKeyType in iscsiAuthClient.h.
517836SJohn.Forte@Sun.COM  */
527836SJohn.Forte@Sun.COM static IscsiAuthKeyInfo iscsiAuthClientKeyInfo[iscsiAuthKeyTypeMaxCount] = {
537836SJohn.Forte@Sun.COM 	{"AuthMethod"},
547836SJohn.Forte@Sun.COM 	{"CHAP_A"},
557836SJohn.Forte@Sun.COM 	{"CHAP_N"},
567836SJohn.Forte@Sun.COM 	{"CHAP_R"},
577836SJohn.Forte@Sun.COM 	{"CHAP_I"},
587836SJohn.Forte@Sun.COM 	{"CHAP_C"}
597836SJohn.Forte@Sun.COM };
607836SJohn.Forte@Sun.COM 
617836SJohn.Forte@Sun.COM static const char iscsiAuthClientHexString[] = "0123456789abcdefABCDEF";
627836SJohn.Forte@Sun.COM static const char iscsiAuthClientBase64String[] =
637836SJohn.Forte@Sun.COM 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
647836SJohn.Forte@Sun.COM static const char iscsiAuthClientAuthMethodChapOptionName[] = "CHAP";
657836SJohn.Forte@Sun.COM 
667836SJohn.Forte@Sun.COM 
677836SJohn.Forte@Sun.COM static int
iscsiAuthClientCheckString(const char * s,unsigned int maxLength,unsigned int * pOutLength)687836SJohn.Forte@Sun.COM iscsiAuthClientCheckString(const char *s,
697836SJohn.Forte@Sun.COM     unsigned int maxLength, unsigned int *pOutLength)
707836SJohn.Forte@Sun.COM {
717836SJohn.Forte@Sun.COM 	unsigned int length;
727836SJohn.Forte@Sun.COM 
737836SJohn.Forte@Sun.COM 	if (!s) {
747836SJohn.Forte@Sun.COM 		return (TRUE);
757836SJohn.Forte@Sun.COM 	}
767836SJohn.Forte@Sun.COM 
777836SJohn.Forte@Sun.COM 	for (length = 0; length < maxLength; length++) {
787836SJohn.Forte@Sun.COM 		if (*s++ == '\0') {
797836SJohn.Forte@Sun.COM 			if (pOutLength) {
807836SJohn.Forte@Sun.COM 				*pOutLength = length;
817836SJohn.Forte@Sun.COM 			}
827836SJohn.Forte@Sun.COM 			return (FALSE);
837836SJohn.Forte@Sun.COM 		}
847836SJohn.Forte@Sun.COM 	}
857836SJohn.Forte@Sun.COM 
867836SJohn.Forte@Sun.COM 	return (TRUE);
877836SJohn.Forte@Sun.COM }
887836SJohn.Forte@Sun.COM 
897836SJohn.Forte@Sun.COM 
907836SJohn.Forte@Sun.COM static int
iscsiAuthClientStringCopy(char * stringOut,const char * stringIn,unsigned int length)917836SJohn.Forte@Sun.COM iscsiAuthClientStringCopy(char *stringOut, const char *stringIn,
927836SJohn.Forte@Sun.COM     unsigned int length)
937836SJohn.Forte@Sun.COM {
947836SJohn.Forte@Sun.COM 	if (!stringOut || !stringIn || length == 0) {
957836SJohn.Forte@Sun.COM 		return (TRUE);
967836SJohn.Forte@Sun.COM 	}
977836SJohn.Forte@Sun.COM 
987836SJohn.Forte@Sun.COM 	while ((*stringOut++ = *stringIn++) != '\0') {
997836SJohn.Forte@Sun.COM 		if (--length == 0) {
1007836SJohn.Forte@Sun.COM 			stringOut--;
1017836SJohn.Forte@Sun.COM 			*stringOut = '\0';
1027836SJohn.Forte@Sun.COM 			return (TRUE);
1037836SJohn.Forte@Sun.COM 		}
1047836SJohn.Forte@Sun.COM 	}
1057836SJohn.Forte@Sun.COM 
1067836SJohn.Forte@Sun.COM 	return (FALSE);
1077836SJohn.Forte@Sun.COM }
1087836SJohn.Forte@Sun.COM 
1097836SJohn.Forte@Sun.COM 
1107836SJohn.Forte@Sun.COM static int
iscsiAuthClientStringAppend(char * stringOut,const char * stringIn,unsigned int length)1117836SJohn.Forte@Sun.COM iscsiAuthClientStringAppend(char *stringOut, const char *stringIn,
1127836SJohn.Forte@Sun.COM     unsigned int length)
1137836SJohn.Forte@Sun.COM {
1147836SJohn.Forte@Sun.COM 	if (!stringOut || !stringIn || length == 0) {
1157836SJohn.Forte@Sun.COM 		return (TRUE);
1167836SJohn.Forte@Sun.COM 	}
1177836SJohn.Forte@Sun.COM 
1187836SJohn.Forte@Sun.COM 	while (*stringOut++ != '\0') {
1197836SJohn.Forte@Sun.COM 		if (--length == 0) {
1207836SJohn.Forte@Sun.COM 			stringOut--;
1217836SJohn.Forte@Sun.COM 			*stringOut = '\0';
1227836SJohn.Forte@Sun.COM 			return (TRUE);
1237836SJohn.Forte@Sun.COM 		}
1247836SJohn.Forte@Sun.COM 	}
1257836SJohn.Forte@Sun.COM 
1267836SJohn.Forte@Sun.COM 	stringOut--;
1277836SJohn.Forte@Sun.COM 
1287836SJohn.Forte@Sun.COM 	while ((*stringOut++ = *stringIn++) != '\0') {
1297836SJohn.Forte@Sun.COM 		if (--length == 0) {
1307836SJohn.Forte@Sun.COM 			stringOut--;
1317836SJohn.Forte@Sun.COM 			*stringOut = '\0';
1327836SJohn.Forte@Sun.COM 			return (TRUE);
1337836SJohn.Forte@Sun.COM 		}
1347836SJohn.Forte@Sun.COM 	}
1357836SJohn.Forte@Sun.COM 
1367836SJohn.Forte@Sun.COM 	return (FALSE);
1377836SJohn.Forte@Sun.COM }
1387836SJohn.Forte@Sun.COM 
1397836SJohn.Forte@Sun.COM 
1407836SJohn.Forte@Sun.COM static int
iscsiAuthClientStringIndex(const char * s,int c)1417836SJohn.Forte@Sun.COM iscsiAuthClientStringIndex(const char *s, int c)
1427836SJohn.Forte@Sun.COM {
1437836SJohn.Forte@Sun.COM 	int n = 0;
1447836SJohn.Forte@Sun.COM 
1457836SJohn.Forte@Sun.COM 	while (*s != '\0') {
1467836SJohn.Forte@Sun.COM 		if (*s++ == c) {
1477836SJohn.Forte@Sun.COM 			return (n);
1487836SJohn.Forte@Sun.COM 		}
1497836SJohn.Forte@Sun.COM 		n++;
1507836SJohn.Forte@Sun.COM 	}
1517836SJohn.Forte@Sun.COM 
1527836SJohn.Forte@Sun.COM 	return (-1);
1537836SJohn.Forte@Sun.COM }
1547836SJohn.Forte@Sun.COM 
1557836SJohn.Forte@Sun.COM 
1567836SJohn.Forte@Sun.COM static int
iscsiAuthClientCheckNodeType(int nodeType)1577836SJohn.Forte@Sun.COM iscsiAuthClientCheckNodeType(int nodeType)
1587836SJohn.Forte@Sun.COM {
1597836SJohn.Forte@Sun.COM 	if (nodeType == iscsiAuthNodeTypeInitiator ||
1607836SJohn.Forte@Sun.COM 	    nodeType == iscsiAuthNodeTypeTarget) {
1617836SJohn.Forte@Sun.COM 		return (FALSE);
1627836SJohn.Forte@Sun.COM 	}
1637836SJohn.Forte@Sun.COM 
1647836SJohn.Forte@Sun.COM 	return (TRUE);
1657836SJohn.Forte@Sun.COM }
1667836SJohn.Forte@Sun.COM 
1677836SJohn.Forte@Sun.COM 
1687836SJohn.Forte@Sun.COM static int
iscsiAuthClientCheckVersion(int value)1697836SJohn.Forte@Sun.COM iscsiAuthClientCheckVersion(int value)
1707836SJohn.Forte@Sun.COM {
1717836SJohn.Forte@Sun.COM 	if (value == iscsiAuthVersionDraft8 || value == iscsiAuthVersionRfc) {
1727836SJohn.Forte@Sun.COM 
1737836SJohn.Forte@Sun.COM 		return (FALSE);
1747836SJohn.Forte@Sun.COM 	}
1757836SJohn.Forte@Sun.COM 
1767836SJohn.Forte@Sun.COM 	return (TRUE);
1777836SJohn.Forte@Sun.COM }
1787836SJohn.Forte@Sun.COM 
1797836SJohn.Forte@Sun.COM 
1807836SJohn.Forte@Sun.COM static int
iscsiAuthClientCheckNegRole(int value)1817836SJohn.Forte@Sun.COM iscsiAuthClientCheckNegRole(int value)
1827836SJohn.Forte@Sun.COM {
1837836SJohn.Forte@Sun.COM 	if (value == iscsiAuthNegRoleOriginator ||
1847836SJohn.Forte@Sun.COM 	    value == iscsiAuthNegRoleResponder) {
1857836SJohn.Forte@Sun.COM 		return (FALSE);
1867836SJohn.Forte@Sun.COM 	}
1877836SJohn.Forte@Sun.COM 
1887836SJohn.Forte@Sun.COM 	return (TRUE);
1897836SJohn.Forte@Sun.COM }
1907836SJohn.Forte@Sun.COM 
1917836SJohn.Forte@Sun.COM 
1927836SJohn.Forte@Sun.COM static int
iscsiAuthClientCheckAuthMethodOption(int value)1937836SJohn.Forte@Sun.COM iscsiAuthClientCheckAuthMethodOption(int value)
1947836SJohn.Forte@Sun.COM {
1957836SJohn.Forte@Sun.COM 	if (value == iscsiAuthOptionNone || value == iscsiAuthMethodChap) {
1967836SJohn.Forte@Sun.COM 
1977836SJohn.Forte@Sun.COM 		return (FALSE);
1987836SJohn.Forte@Sun.COM 	}
1997836SJohn.Forte@Sun.COM 
2007836SJohn.Forte@Sun.COM 	return (TRUE);
2017836SJohn.Forte@Sun.COM }
2027836SJohn.Forte@Sun.COM 
2037836SJohn.Forte@Sun.COM 
2047836SJohn.Forte@Sun.COM static const char *
iscsiAuthClientAuthMethodOptionToText(IscsiAuthClient * client,int value)2057836SJohn.Forte@Sun.COM iscsiAuthClientAuthMethodOptionToText(IscsiAuthClient * client, int value)
2067836SJohn.Forte@Sun.COM {
2077836SJohn.Forte@Sun.COM 	const char *s;
2087836SJohn.Forte@Sun.COM 
2097836SJohn.Forte@Sun.COM 	switch (value) {
2107836SJohn.Forte@Sun.COM 	case iscsiAuthOptionReject:
2117836SJohn.Forte@Sun.COM 		s = client->rejectOptionName;
2127836SJohn.Forte@Sun.COM 		break;
2137836SJohn.Forte@Sun.COM 
2147836SJohn.Forte@Sun.COM 	case iscsiAuthOptionNone:
2157836SJohn.Forte@Sun.COM 		s = client->noneOptionName;
2167836SJohn.Forte@Sun.COM 		break;
2177836SJohn.Forte@Sun.COM 
2187836SJohn.Forte@Sun.COM 	case iscsiAuthMethodChap:
2197836SJohn.Forte@Sun.COM 		s = iscsiAuthClientAuthMethodChapOptionName;
2207836SJohn.Forte@Sun.COM 		break;
2217836SJohn.Forte@Sun.COM 
2227836SJohn.Forte@Sun.COM 	default:
2237836SJohn.Forte@Sun.COM 		s = 0;
2247836SJohn.Forte@Sun.COM 	}
2257836SJohn.Forte@Sun.COM 
2267836SJohn.Forte@Sun.COM 	return (s);
2277836SJohn.Forte@Sun.COM }
2287836SJohn.Forte@Sun.COM 
2297836SJohn.Forte@Sun.COM 
2307836SJohn.Forte@Sun.COM static int
iscsiAuthClientCheckChapAlgorithmOption(int chapAlgorithm)2317836SJohn.Forte@Sun.COM iscsiAuthClientCheckChapAlgorithmOption(int chapAlgorithm)
2327836SJohn.Forte@Sun.COM {
2337836SJohn.Forte@Sun.COM 	if (chapAlgorithm == iscsiAuthOptionNone ||
2347836SJohn.Forte@Sun.COM 	    chapAlgorithm == iscsiAuthChapAlgorithmMd5) {
2357836SJohn.Forte@Sun.COM 		return (FALSE);
2367836SJohn.Forte@Sun.COM 	}
2377836SJohn.Forte@Sun.COM 
2387836SJohn.Forte@Sun.COM 	return (TRUE);
2397836SJohn.Forte@Sun.COM }
2407836SJohn.Forte@Sun.COM 
2417836SJohn.Forte@Sun.COM 
2427836SJohn.Forte@Sun.COM static int
iscsiAuthClientDataToHex(unsigned char * data,unsigned int dataLength,char * text,unsigned int textLength)2437836SJohn.Forte@Sun.COM iscsiAuthClientDataToHex(unsigned char *data, unsigned int dataLength,
2447836SJohn.Forte@Sun.COM     char *text, unsigned int textLength)
2457836SJohn.Forte@Sun.COM {
2467836SJohn.Forte@Sun.COM 	unsigned long n;
2477836SJohn.Forte@Sun.COM 
2487836SJohn.Forte@Sun.COM 	if (!text || textLength == 0) {
2497836SJohn.Forte@Sun.COM 		return (TRUE);
2507836SJohn.Forte@Sun.COM 	}
2517836SJohn.Forte@Sun.COM 
2527836SJohn.Forte@Sun.COM 	if (!data || dataLength == 0) {
2537836SJohn.Forte@Sun.COM 		*text = '\0';
2547836SJohn.Forte@Sun.COM 		return (TRUE);
2557836SJohn.Forte@Sun.COM 	}
2567836SJohn.Forte@Sun.COM 
2577836SJohn.Forte@Sun.COM 	if (textLength < 3) {
2587836SJohn.Forte@Sun.COM 		*text = '\0';
2597836SJohn.Forte@Sun.COM 		return (TRUE);
2607836SJohn.Forte@Sun.COM 	}
2617836SJohn.Forte@Sun.COM 
2627836SJohn.Forte@Sun.COM 	*text++ = '0';
2637836SJohn.Forte@Sun.COM 	*text++ = 'x';
2647836SJohn.Forte@Sun.COM 
2657836SJohn.Forte@Sun.COM 	textLength -= 2;
2667836SJohn.Forte@Sun.COM 
2677836SJohn.Forte@Sun.COM 	while (dataLength > 0) {
2687836SJohn.Forte@Sun.COM 
2697836SJohn.Forte@Sun.COM 		if (textLength < 3) {
2707836SJohn.Forte@Sun.COM 			*text = '\0';
2717836SJohn.Forte@Sun.COM 			return (TRUE);
2727836SJohn.Forte@Sun.COM 		}
2737836SJohn.Forte@Sun.COM 
2747836SJohn.Forte@Sun.COM 		n = *data++;
2757836SJohn.Forte@Sun.COM 		dataLength--;
2767836SJohn.Forte@Sun.COM 
2777836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientHexString[(n >> 4) & 0xf];
2787836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientHexString[n & 0xf];
2797836SJohn.Forte@Sun.COM 
2807836SJohn.Forte@Sun.COM 		textLength -= 2;
2817836SJohn.Forte@Sun.COM 	}
2827836SJohn.Forte@Sun.COM 
2837836SJohn.Forte@Sun.COM 	*text = '\0';
2847836SJohn.Forte@Sun.COM 
2857836SJohn.Forte@Sun.COM 	return (FALSE);
2867836SJohn.Forte@Sun.COM }
2877836SJohn.Forte@Sun.COM 
2887836SJohn.Forte@Sun.COM 
2897836SJohn.Forte@Sun.COM static int
iscsiAuthClientDataToBase64(unsigned char * data,unsigned int dataLength,char * text,unsigned int textLength)2907836SJohn.Forte@Sun.COM iscsiAuthClientDataToBase64(unsigned char *data, unsigned int dataLength,
2917836SJohn.Forte@Sun.COM     char *text, unsigned int textLength)
2927836SJohn.Forte@Sun.COM {
2937836SJohn.Forte@Sun.COM 	unsigned long n;
2947836SJohn.Forte@Sun.COM 
2957836SJohn.Forte@Sun.COM 	if (!text || textLength == 0) {
2967836SJohn.Forte@Sun.COM 		return (TRUE);
2977836SJohn.Forte@Sun.COM 	}
2987836SJohn.Forte@Sun.COM 
2997836SJohn.Forte@Sun.COM 	if (!data || dataLength == 0) {
3007836SJohn.Forte@Sun.COM 		*text = '\0';
3017836SJohn.Forte@Sun.COM 		return (TRUE);
3027836SJohn.Forte@Sun.COM 	}
3037836SJohn.Forte@Sun.COM 
3047836SJohn.Forte@Sun.COM 	if (textLength < 3) {
3057836SJohn.Forte@Sun.COM 		*text = '\0';
3067836SJohn.Forte@Sun.COM 		return (TRUE);
3077836SJohn.Forte@Sun.COM 	}
3087836SJohn.Forte@Sun.COM 
3097836SJohn.Forte@Sun.COM 	*text++ = '0';
3107836SJohn.Forte@Sun.COM 	*text++ = 'b';
3117836SJohn.Forte@Sun.COM 
3127836SJohn.Forte@Sun.COM 	textLength -= 2;
3137836SJohn.Forte@Sun.COM 
3147836SJohn.Forte@Sun.COM 	while (dataLength >= 3) {
3157836SJohn.Forte@Sun.COM 
3167836SJohn.Forte@Sun.COM 		if (textLength < 5) {
3177836SJohn.Forte@Sun.COM 			*text = '\0';
3187836SJohn.Forte@Sun.COM 			return (TRUE);
3197836SJohn.Forte@Sun.COM 		}
3207836SJohn.Forte@Sun.COM 
3217836SJohn.Forte@Sun.COM 		n = *data++;
3227836SJohn.Forte@Sun.COM 		n = (n << 8) | *data++;
3237836SJohn.Forte@Sun.COM 		n = (n << 8) | *data++;
3247836SJohn.Forte@Sun.COM 		dataLength -= 3;
3257836SJohn.Forte@Sun.COM 
3267836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientBase64String[(n >> 18) & 0x3f];
3277836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientBase64String[(n >> 12) & 0x3f];
3287836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientBase64String[(n >> 6) & 0x3f];
3297836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientBase64String[n & 0x3f];
3307836SJohn.Forte@Sun.COM 
3317836SJohn.Forte@Sun.COM 		textLength -= 4;
3327836SJohn.Forte@Sun.COM 	}
3337836SJohn.Forte@Sun.COM 
3347836SJohn.Forte@Sun.COM 	if (dataLength == 1) {
3357836SJohn.Forte@Sun.COM 
3367836SJohn.Forte@Sun.COM 		if (textLength < 5) {
3377836SJohn.Forte@Sun.COM 			*text = '\0';
3387836SJohn.Forte@Sun.COM 			return (TRUE);
3397836SJohn.Forte@Sun.COM 		}
3407836SJohn.Forte@Sun.COM 
3417836SJohn.Forte@Sun.COM 		n = *data++;
3427836SJohn.Forte@Sun.COM 		n = n << 4;
3437836SJohn.Forte@Sun.COM 
3447836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientBase64String[(n >> 6) & 0x3f];
3457836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientBase64String[n & 0x3f];
3467836SJohn.Forte@Sun.COM 		*text++ = '=';
3477836SJohn.Forte@Sun.COM 		*text++ = '=';
3487836SJohn.Forte@Sun.COM 
3497836SJohn.Forte@Sun.COM 	} else if (dataLength == 2) {
3507836SJohn.Forte@Sun.COM 
3517836SJohn.Forte@Sun.COM 		if (textLength < 5) {
3527836SJohn.Forte@Sun.COM 			return (TRUE);
3537836SJohn.Forte@Sun.COM 		}
3547836SJohn.Forte@Sun.COM 
3557836SJohn.Forte@Sun.COM 		n = *data++;
3567836SJohn.Forte@Sun.COM 		n = (n << 8) | *data++;
3577836SJohn.Forte@Sun.COM 		n = n << 2;
3587836SJohn.Forte@Sun.COM 
3597836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientBase64String[(n >> 12) & 0x3f];
3607836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientBase64String[(n >> 6) & 0x3f];
3617836SJohn.Forte@Sun.COM 		*text++ = iscsiAuthClientBase64String[n & 0x3f];
3627836SJohn.Forte@Sun.COM 		*text++ = '=';
3637836SJohn.Forte@Sun.COM 	}
3647836SJohn.Forte@Sun.COM 
3657836SJohn.Forte@Sun.COM 	*text = '\0';
3667836SJohn.Forte@Sun.COM 
3677836SJohn.Forte@Sun.COM 	return (FALSE);
3687836SJohn.Forte@Sun.COM }
3697836SJohn.Forte@Sun.COM 
3707836SJohn.Forte@Sun.COM 
3717836SJohn.Forte@Sun.COM static int
iscsiAuthClientDataToText(int base64,unsigned char * data,unsigned int dataLength,char * text,unsigned int textLength)3727836SJohn.Forte@Sun.COM iscsiAuthClientDataToText(int base64, unsigned char *data,
3737836SJohn.Forte@Sun.COM     unsigned int dataLength, char *text, unsigned int textLength)
3747836SJohn.Forte@Sun.COM {
3757836SJohn.Forte@Sun.COM 	int status;
3767836SJohn.Forte@Sun.COM 
3777836SJohn.Forte@Sun.COM 	if (base64) {
3787836SJohn.Forte@Sun.COM 		status = iscsiAuthClientDataToBase64(
3797836SJohn.Forte@Sun.COM 		    data, dataLength, text, textLength);
3807836SJohn.Forte@Sun.COM 	} else {
3817836SJohn.Forte@Sun.COM 		status = iscsiAuthClientDataToHex(
3827836SJohn.Forte@Sun.COM 		    data, dataLength, text, textLength);
3837836SJohn.Forte@Sun.COM 	}
3847836SJohn.Forte@Sun.COM 
3857836SJohn.Forte@Sun.COM 	return (status);
3867836SJohn.Forte@Sun.COM }
3877836SJohn.Forte@Sun.COM 
3887836SJohn.Forte@Sun.COM 
3897836SJohn.Forte@Sun.COM static int
iscsiAuthClientHexToData(const char * text,unsigned int textLength,unsigned char * data,unsigned int * pDataLength)3907836SJohn.Forte@Sun.COM iscsiAuthClientHexToData(const char *text, unsigned int textLength,
3917836SJohn.Forte@Sun.COM     unsigned char *data, unsigned int *pDataLength)
3927836SJohn.Forte@Sun.COM {
3937836SJohn.Forte@Sun.COM 	int i;
3947836SJohn.Forte@Sun.COM 	unsigned int n1;
3957836SJohn.Forte@Sun.COM 	unsigned int n2;
3967836SJohn.Forte@Sun.COM 	unsigned int dataLength = *pDataLength;
3977836SJohn.Forte@Sun.COM 
3987836SJohn.Forte@Sun.COM 	if ((textLength % 2) == 1) {
3997836SJohn.Forte@Sun.COM 		i = iscsiAuthClientStringIndex(iscsiAuthClientHexString,
4007836SJohn.Forte@Sun.COM 		    *text++);
4017836SJohn.Forte@Sun.COM 		if (i < 0) {
4027836SJohn.Forte@Sun.COM 			return (TRUE);	/* error, bad character */
4037836SJohn.Forte@Sun.COM 		}
4047836SJohn.Forte@Sun.COM 
4057836SJohn.Forte@Sun.COM 		if (i > 15)
4067836SJohn.Forte@Sun.COM 			i -= 6;
4077836SJohn.Forte@Sun.COM 		n2 = i;
4087836SJohn.Forte@Sun.COM 
4097836SJohn.Forte@Sun.COM 		if (dataLength < 1) {
4107836SJohn.Forte@Sun.COM 			return (TRUE);	/* error, too much data */
4117836SJohn.Forte@Sun.COM 		}
4127836SJohn.Forte@Sun.COM 
4137836SJohn.Forte@Sun.COM 		*data++ = n2;
4147836SJohn.Forte@Sun.COM 		dataLength--;
4157836SJohn.Forte@Sun.COM 	}
4167836SJohn.Forte@Sun.COM 
4177836SJohn.Forte@Sun.COM 	while (*text != '\0') {
4187836SJohn.Forte@Sun.COM 
4197836SJohn.Forte@Sun.COM 		i = iscsiAuthClientStringIndex(
4207836SJohn.Forte@Sun.COM 		    iscsiAuthClientHexString, *text++);
4217836SJohn.Forte@Sun.COM 		if (i < 0) {
4227836SJohn.Forte@Sun.COM 			return (TRUE);	/* error, bad character */
4237836SJohn.Forte@Sun.COM 		}
4247836SJohn.Forte@Sun.COM 
4257836SJohn.Forte@Sun.COM 		if (i > 15)
4267836SJohn.Forte@Sun.COM 			i -= 6;
4277836SJohn.Forte@Sun.COM 		n1 = i;
4287836SJohn.Forte@Sun.COM 
4297836SJohn.Forte@Sun.COM 		if (*text == '\0') {
4307836SJohn.Forte@Sun.COM 			return (TRUE);	/* error, odd string length */
4317836SJohn.Forte@Sun.COM 		}
4327836SJohn.Forte@Sun.COM 
4337836SJohn.Forte@Sun.COM 		i = iscsiAuthClientStringIndex(
4347836SJohn.Forte@Sun.COM 		    iscsiAuthClientHexString, *text++);
4357836SJohn.Forte@Sun.COM 		if (i < 0) {
4367836SJohn.Forte@Sun.COM 			return (TRUE);	/* error, bad character */
4377836SJohn.Forte@Sun.COM 		}
4387836SJohn.Forte@Sun.COM 
4397836SJohn.Forte@Sun.COM 		if (i > 15)
4407836SJohn.Forte@Sun.COM 			i -= 6;
4417836SJohn.Forte@Sun.COM 		n2 = i;
4427836SJohn.Forte@Sun.COM 
4437836SJohn.Forte@Sun.COM 		if (dataLength < 1) {
4447836SJohn.Forte@Sun.COM 			return (TRUE);	/* error, too much data */
4457836SJohn.Forte@Sun.COM 		}
4467836SJohn.Forte@Sun.COM 
4477836SJohn.Forte@Sun.COM 		*data++ = (n1 << 4) | n2;
4487836SJohn.Forte@Sun.COM 		dataLength--;
4497836SJohn.Forte@Sun.COM 	}
4507836SJohn.Forte@Sun.COM 
4517836SJohn.Forte@Sun.COM 	if (dataLength >= *pDataLength) {
4527836SJohn.Forte@Sun.COM 		return (TRUE);	/* error, no data */
4537836SJohn.Forte@Sun.COM 	}
4547836SJohn.Forte@Sun.COM 
4557836SJohn.Forte@Sun.COM 	*pDataLength = *pDataLength - dataLength;
4567836SJohn.Forte@Sun.COM 
4577836SJohn.Forte@Sun.COM 	return (FALSE);		/* no error */
4587836SJohn.Forte@Sun.COM }
4597836SJohn.Forte@Sun.COM 
4607836SJohn.Forte@Sun.COM 
4617836SJohn.Forte@Sun.COM static int
iscsiAuthClientBase64ToData(const char * text,unsigned int textLength,unsigned char * data,unsigned int * pDataLength)4627836SJohn.Forte@Sun.COM iscsiAuthClientBase64ToData(const char *text, unsigned int textLength,
4637836SJohn.Forte@Sun.COM     unsigned char *data, unsigned int *pDataLength)
4647836SJohn.Forte@Sun.COM {
4657836SJohn.Forte@Sun.COM 	int i;
4667836SJohn.Forte@Sun.COM 	unsigned int n;
4677836SJohn.Forte@Sun.COM 	unsigned int count;
4687836SJohn.Forte@Sun.COM 	unsigned int dataLength = *pDataLength;
4697836SJohn.Forte@Sun.COM 
4707836SJohn.Forte@Sun.COM 	textLength = textLength;	/* not used */
4717836SJohn.Forte@Sun.COM 
4727836SJohn.Forte@Sun.COM 	n = 0;
4737836SJohn.Forte@Sun.COM 	count = 0;
4747836SJohn.Forte@Sun.COM 
4757836SJohn.Forte@Sun.COM 	while (*text != '\0' && *text != '=') {
4767836SJohn.Forte@Sun.COM 
4777836SJohn.Forte@Sun.COM 		i = iscsiAuthClientStringIndex(
4787836SJohn.Forte@Sun.COM 		    iscsiAuthClientBase64String, *text++);
4797836SJohn.Forte@Sun.COM 		if (i < 0) {
4807836SJohn.Forte@Sun.COM 			return (TRUE);	/* error, bad character */
4817836SJohn.Forte@Sun.COM 		}
4827836SJohn.Forte@Sun.COM 
4837836SJohn.Forte@Sun.COM 		n = (n << 6 | (unsigned int)i);
4847836SJohn.Forte@Sun.COM 		count++;
4857836SJohn.Forte@Sun.COM 
4867836SJohn.Forte@Sun.COM 		if (count >= 4) {
4877836SJohn.Forte@Sun.COM 			if (dataLength < 3) {
4887836SJohn.Forte@Sun.COM 				return (TRUE);	/* error, too much data */
4897836SJohn.Forte@Sun.COM 			}
4907836SJohn.Forte@Sun.COM 			*data++ = n >> 16;
4917836SJohn.Forte@Sun.COM 			*data++ = n >> 8;
4927836SJohn.Forte@Sun.COM 			*data++ = n;
4937836SJohn.Forte@Sun.COM 			dataLength -= 3;
4947836SJohn.Forte@Sun.COM 			n = 0;
4957836SJohn.Forte@Sun.COM 			count = 0;
4967836SJohn.Forte@Sun.COM 		}
4977836SJohn.Forte@Sun.COM 	}
4987836SJohn.Forte@Sun.COM 
4997836SJohn.Forte@Sun.COM 	while (*text != '\0') {
5007836SJohn.Forte@Sun.COM 		if (*text++ != '=') {
5017836SJohn.Forte@Sun.COM 			return (TRUE);	/* error, bad pad */
5027836SJohn.Forte@Sun.COM 		}
5037836SJohn.Forte@Sun.COM 	}
5047836SJohn.Forte@Sun.COM 
5057836SJohn.Forte@Sun.COM 	if (count == 0) {
5067836SJohn.Forte@Sun.COM 		/*
5077836SJohn.Forte@Sun.COM 		 * do nothing
5087836SJohn.Forte@Sun.COM 		 */
5097836SJohn.Forte@Sun.COM 		/* EMPTY */
5107836SJohn.Forte@Sun.COM 	} else if (count == 2) {
5117836SJohn.Forte@Sun.COM 		if (dataLength < 1) {
5127836SJohn.Forte@Sun.COM 			return (TRUE);	/* error, too much data */
5137836SJohn.Forte@Sun.COM 		}
5147836SJohn.Forte@Sun.COM 		n = n >> 4;
5157836SJohn.Forte@Sun.COM 		*data++ = n;
5167836SJohn.Forte@Sun.COM 		dataLength--;
5177836SJohn.Forte@Sun.COM 	} else if (count == 3) {
5187836SJohn.Forte@Sun.COM 		if (dataLength < 2) {
5197836SJohn.Forte@Sun.COM 			return (TRUE);	/* error, too much data */
5207836SJohn.Forte@Sun.COM 		}
5217836SJohn.Forte@Sun.COM 		n = n >> 2;
5227836SJohn.Forte@Sun.COM 		*data++ = n >> 8;
5237836SJohn.Forte@Sun.COM 		*data++ = n;
5247836SJohn.Forte@Sun.COM 		dataLength -= 2;
5257836SJohn.Forte@Sun.COM 	} else {
5267836SJohn.Forte@Sun.COM 		return (TRUE);	/* bad encoding */
5277836SJohn.Forte@Sun.COM 	}
5287836SJohn.Forte@Sun.COM 
5297836SJohn.Forte@Sun.COM 	if (dataLength >= *pDataLength) {
5307836SJohn.Forte@Sun.COM 		return (TRUE);	/* error, no data */
5317836SJohn.Forte@Sun.COM 	}
5327836SJohn.Forte@Sun.COM 
5337836SJohn.Forte@Sun.COM 	*pDataLength = *pDataLength - dataLength;
5347836SJohn.Forte@Sun.COM 
5357836SJohn.Forte@Sun.COM 	return (FALSE);		/* no error */
5367836SJohn.Forte@Sun.COM }
5377836SJohn.Forte@Sun.COM 
5387836SJohn.Forte@Sun.COM 
5397836SJohn.Forte@Sun.COM static int
iscsiAuthClientTextToData(const char * text,unsigned char * data,unsigned int * dataLength)5407836SJohn.Forte@Sun.COM iscsiAuthClientTextToData(const char *text, unsigned char *data,
5417836SJohn.Forte@Sun.COM     unsigned int *dataLength)
5427836SJohn.Forte@Sun.COM {
5437836SJohn.Forte@Sun.COM 	int status;
5447836SJohn.Forte@Sun.COM 	unsigned int textLength;
5457836SJohn.Forte@Sun.COM 
5467836SJohn.Forte@Sun.COM 	status = iscsiAuthClientCheckString(text,
5477836SJohn.Forte@Sun.COM 	    2 + 2 * iscsiAuthLargeBinaryMaxLength + 1, &textLength);
5487836SJohn.Forte@Sun.COM 
5497836SJohn.Forte@Sun.COM 	if (status) {
5507836SJohn.Forte@Sun.COM 		return (status);
5517836SJohn.Forte@Sun.COM 	}
5527836SJohn.Forte@Sun.COM 
5537836SJohn.Forte@Sun.COM 	if (text[0] == '0' && (text[1] == 'x' || text[1] == 'X')) {
5547836SJohn.Forte@Sun.COM 		/*
5557836SJohn.Forte@Sun.COM 		 * skip prefix
5567836SJohn.Forte@Sun.COM 		 */
5577836SJohn.Forte@Sun.COM 		text += 2;
5587836SJohn.Forte@Sun.COM 		textLength -= 2;
5597836SJohn.Forte@Sun.COM 		status = iscsiAuthClientHexToData(text,
5607836SJohn.Forte@Sun.COM 		    textLength, data, dataLength);
5617836SJohn.Forte@Sun.COM 	} else if (text[0] == '0' && (text[1] == 'b' || text[1] == 'B')) {
5627836SJohn.Forte@Sun.COM 		/*
5637836SJohn.Forte@Sun.COM 		 * skip prefix
5647836SJohn.Forte@Sun.COM 		 */
5657836SJohn.Forte@Sun.COM 		text += 2;
5667836SJohn.Forte@Sun.COM 		textLength -= 2;
5677836SJohn.Forte@Sun.COM 		status = iscsiAuthClientBase64ToData(text,
5687836SJohn.Forte@Sun.COM 		    textLength, data, dataLength);
5697836SJohn.Forte@Sun.COM 	} else {
5707836SJohn.Forte@Sun.COM 		status = TRUE;	/* prefix not recognized. */
5717836SJohn.Forte@Sun.COM 	}
5727836SJohn.Forte@Sun.COM 
5737836SJohn.Forte@Sun.COM 	return (status);
5747836SJohn.Forte@Sun.COM }
5757836SJohn.Forte@Sun.COM 
5767836SJohn.Forte@Sun.COM 
5777836SJohn.Forte@Sun.COM static IscsiAuthDebugStatus
iscsiAuthClientChapComputeResponse(IscsiAuthClient * client,int remoteAuthentication,unsigned int id,unsigned char * challengeData,unsigned int challengeLength,unsigned char * responseData)5787836SJohn.Forte@Sun.COM iscsiAuthClientChapComputeResponse(IscsiAuthClient * client,
5797836SJohn.Forte@Sun.COM     int remoteAuthentication, unsigned int id,
5807836SJohn.Forte@Sun.COM     unsigned char *challengeData, unsigned int challengeLength,
5817836SJohn.Forte@Sun.COM     unsigned char *responseData)
5827836SJohn.Forte@Sun.COM {
5837836SJohn.Forte@Sun.COM 	unsigned char idData[1];
5847836SJohn.Forte@Sun.COM 	IscsiAuthMd5Context context;
5857836SJohn.Forte@Sun.COM 	unsigned char outData[iscsiAuthStringMaxLength];
5867836SJohn.Forte@Sun.COM 	unsigned int outLength = iscsiAuthStringMaxLength;
5877836SJohn.Forte@Sun.COM 
5887836SJohn.Forte@Sun.COM 	if (!client->passwordPresent) {
5897836SJohn.Forte@Sun.COM 		return (iscsiAuthDebugStatusLocalPasswordNotSet);
5907836SJohn.Forte@Sun.COM 	}
5917836SJohn.Forte@Sun.COM 
5927836SJohn.Forte@Sun.COM 	iscsiAuthMd5Init(&context);
5937836SJohn.Forte@Sun.COM 
5947836SJohn.Forte@Sun.COM 	/*
5957836SJohn.Forte@Sun.COM 	 * id byte
5967836SJohn.Forte@Sun.COM 	 */
5977836SJohn.Forte@Sun.COM 	idData[0] = id;
5987836SJohn.Forte@Sun.COM 	iscsiAuthMd5Update(&context, idData, 1);
5997836SJohn.Forte@Sun.COM 
6007836SJohn.Forte@Sun.COM 	/*
6017836SJohn.Forte@Sun.COM 	 * decrypt password
6027836SJohn.Forte@Sun.COM 	 */
6037836SJohn.Forte@Sun.COM 	if (iscsiAuthClientData(outData, &outLength,
6047836SJohn.Forte@Sun.COM 	    client->passwordData, client->passwordLength)) {
6057836SJohn.Forte@Sun.COM 
6067836SJohn.Forte@Sun.COM 		return (iscsiAuthDebugStatusPasswordDecryptFailed);
6077836SJohn.Forte@Sun.COM 	}
6087836SJohn.Forte@Sun.COM 
6097836SJohn.Forte@Sun.COM 	if (!remoteAuthentication && !client->ipSec && outLength < 12) {
6107836SJohn.Forte@Sun.COM 		return (iscsiAuthDebugStatusPasswordTooShortWithNoIpSec);
6117836SJohn.Forte@Sun.COM 	}
6127836SJohn.Forte@Sun.COM 
6137836SJohn.Forte@Sun.COM 	/*
6147836SJohn.Forte@Sun.COM 	 * shared secret
6157836SJohn.Forte@Sun.COM 	 */
6167836SJohn.Forte@Sun.COM 	iscsiAuthMd5Update(&context, outData, outLength);
6177836SJohn.Forte@Sun.COM 
6187836SJohn.Forte@Sun.COM 	/*
6197836SJohn.Forte@Sun.COM 	 * clear decrypted password
6207836SJohn.Forte@Sun.COM 	 */
6217836SJohn.Forte@Sun.COM 	bzero(outData, iscsiAuthStringMaxLength);
6227836SJohn.Forte@Sun.COM 
6237836SJohn.Forte@Sun.COM 	/*
6247836SJohn.Forte@Sun.COM 	 * challenge value
6257836SJohn.Forte@Sun.COM 	 */
6267836SJohn.Forte@Sun.COM 	iscsiAuthMd5Update(&context, challengeData, challengeLength);
6277836SJohn.Forte@Sun.COM 
6287836SJohn.Forte@Sun.COM 	iscsiAuthMd5Final(responseData, &context);
6297836SJohn.Forte@Sun.COM 
6307836SJohn.Forte@Sun.COM 	return (iscsiAuthDebugStatusNotSet);	/* no error */
6317836SJohn.Forte@Sun.COM }
6327836SJohn.Forte@Sun.COM 
6337836SJohn.Forte@Sun.COM 
6347836SJohn.Forte@Sun.COM static void
iscsiAuthClientInitKeyBlock(IscsiAuthKeyBlock * keyBlock)6357836SJohn.Forte@Sun.COM iscsiAuthClientInitKeyBlock(IscsiAuthKeyBlock * keyBlock)
6367836SJohn.Forte@Sun.COM {
6377836SJohn.Forte@Sun.COM 	char *stringBlock = keyBlock->stringBlock;
6387836SJohn.Forte@Sun.COM 
6397836SJohn.Forte@Sun.COM 	bzero(keyBlock, sizeof (*keyBlock));
6407836SJohn.Forte@Sun.COM 	keyBlock->stringBlock = stringBlock;
6417836SJohn.Forte@Sun.COM }
6427836SJohn.Forte@Sun.COM 
6437836SJohn.Forte@Sun.COM 
6447836SJohn.Forte@Sun.COM static void
iscsiAuthClientSetKeyValue(IscsiAuthKeyBlock * keyBlock,int keyType,const char * keyValue)6457836SJohn.Forte@Sun.COM iscsiAuthClientSetKeyValue(IscsiAuthKeyBlock * keyBlock,
6467836SJohn.Forte@Sun.COM     int keyType, const char *keyValue)
6477836SJohn.Forte@Sun.COM {
6487836SJohn.Forte@Sun.COM 	unsigned int length;
6497836SJohn.Forte@Sun.COM 	char *string;
6507836SJohn.Forte@Sun.COM 
6517836SJohn.Forte@Sun.COM 	if (keyBlock->key[keyType].valueSet) {
6527836SJohn.Forte@Sun.COM 		keyBlock->duplicateSet = TRUE;
6537836SJohn.Forte@Sun.COM 		return;
6547836SJohn.Forte@Sun.COM 	}
6557836SJohn.Forte@Sun.COM 
6567836SJohn.Forte@Sun.COM 	keyBlock->key[keyType].valueSet = TRUE;
6577836SJohn.Forte@Sun.COM 
6587836SJohn.Forte@Sun.COM 	if (!keyValue) {
6597836SJohn.Forte@Sun.COM 		return;
6607836SJohn.Forte@Sun.COM 	}
6617836SJohn.Forte@Sun.COM 
6627836SJohn.Forte@Sun.COM 	if (iscsiAuthClientCheckString(keyValue,
6637836SJohn.Forte@Sun.COM 	    iscsiAuthStringMaxLength, &length)) {
6647836SJohn.Forte@Sun.COM 		keyBlock->stringTooLong = TRUE;
6657836SJohn.Forte@Sun.COM 		return;
6667836SJohn.Forte@Sun.COM 	}
6677836SJohn.Forte@Sun.COM 
6687836SJohn.Forte@Sun.COM 	length += 1;
6697836SJohn.Forte@Sun.COM 
6707836SJohn.Forte@Sun.COM 	if ((keyBlock->blockLength + length) > iscsiAuthStringBlockMaxLength) {
6717836SJohn.Forte@Sun.COM 		keyBlock->tooMuchData = TRUE;
6727836SJohn.Forte@Sun.COM 		return;
6737836SJohn.Forte@Sun.COM 	}
6747836SJohn.Forte@Sun.COM 
6757836SJohn.Forte@Sun.COM 	string = &keyBlock->stringBlock[keyBlock->blockLength];
6767836SJohn.Forte@Sun.COM 
6777836SJohn.Forte@Sun.COM 	if (iscsiAuthClientStringCopy(string, keyValue, length)) {
6787836SJohn.Forte@Sun.COM 		keyBlock->tooMuchData = TRUE;
6797836SJohn.Forte@Sun.COM 		return;
6807836SJohn.Forte@Sun.COM 	}
6817836SJohn.Forte@Sun.COM 	keyBlock->blockLength += length;
6827836SJohn.Forte@Sun.COM 
6837836SJohn.Forte@Sun.COM 	keyBlock->key[keyType].string = string;
6847836SJohn.Forte@Sun.COM 	keyBlock->key[keyType].present = TRUE;
6857836SJohn.Forte@Sun.COM }
6867836SJohn.Forte@Sun.COM 
6877836SJohn.Forte@Sun.COM 
6887836SJohn.Forte@Sun.COM static const char *
iscsiAuthClientGetKeyValue(IscsiAuthKeyBlock * keyBlock,int keyType)6897836SJohn.Forte@Sun.COM iscsiAuthClientGetKeyValue(IscsiAuthKeyBlock * keyBlock, int keyType)
6907836SJohn.Forte@Sun.COM {
6917836SJohn.Forte@Sun.COM 	keyBlock->key[keyType].processed = TRUE;
6927836SJohn.Forte@Sun.COM 
6937836SJohn.Forte@Sun.COM 	if (!keyBlock->key[keyType].present) {
6947836SJohn.Forte@Sun.COM 		return (0);
6957836SJohn.Forte@Sun.COM 	}
6967836SJohn.Forte@Sun.COM 
6977836SJohn.Forte@Sun.COM 	return (keyBlock->key[keyType].string);
6987836SJohn.Forte@Sun.COM }
6997836SJohn.Forte@Sun.COM 
7007836SJohn.Forte@Sun.COM 
7017836SJohn.Forte@Sun.COM static void
iscsiAuthClientCheckKey(IscsiAuthClient * client,int keyType,int * negotiatedOption,unsigned int optionCount,int * optionList,const char * (* valueToText)(IscsiAuthClient *,int))7027836SJohn.Forte@Sun.COM iscsiAuthClientCheckKey(IscsiAuthClient * client,
7037836SJohn.Forte@Sun.COM     int keyType,
7047836SJohn.Forte@Sun.COM     int *negotiatedOption,
7057836SJohn.Forte@Sun.COM     unsigned int optionCount,
7067836SJohn.Forte@Sun.COM     int *optionList, const char *(*valueToText) (IscsiAuthClient *, int))
7077836SJohn.Forte@Sun.COM {
7087836SJohn.Forte@Sun.COM 	const char *keyValue;
7097836SJohn.Forte@Sun.COM 	int length;
7107836SJohn.Forte@Sun.COM 	unsigned int i;
7117836SJohn.Forte@Sun.COM 
7127836SJohn.Forte@Sun.COM 	keyValue = iscsiAuthClientGetKeyValue(&client->recvKeyBlock, keyType);
7137836SJohn.Forte@Sun.COM 	if (!keyValue) {
7147836SJohn.Forte@Sun.COM 		*negotiatedOption = iscsiAuthOptionNotPresent;
7157836SJohn.Forte@Sun.COM 		return;
7167836SJohn.Forte@Sun.COM 	}
7177836SJohn.Forte@Sun.COM 
7187836SJohn.Forte@Sun.COM 	while (*keyValue != '\0') {
7197836SJohn.Forte@Sun.COM 
7207836SJohn.Forte@Sun.COM 		length = 0;
7217836SJohn.Forte@Sun.COM 
7227836SJohn.Forte@Sun.COM 		while (*keyValue != '\0' && *keyValue != ',') {
7237836SJohn.Forte@Sun.COM 			client->scratchKeyValue[length++] = *keyValue++;
7247836SJohn.Forte@Sun.COM 		}
7257836SJohn.Forte@Sun.COM 
7267836SJohn.Forte@Sun.COM 		if (*keyValue == ',')
7277836SJohn.Forte@Sun.COM 			keyValue++;
7287836SJohn.Forte@Sun.COM 		client->scratchKeyValue[length++] = '\0';
7297836SJohn.Forte@Sun.COM 
7307836SJohn.Forte@Sun.COM 		for (i = 0; i < optionCount; i++) {
7317836SJohn.Forte@Sun.COM 			const char *s = (*valueToText) (client, optionList[i]);
7327836SJohn.Forte@Sun.COM 
7337836SJohn.Forte@Sun.COM 			if (!s)
7347836SJohn.Forte@Sun.COM 				continue;
7357836SJohn.Forte@Sun.COM 
7367836SJohn.Forte@Sun.COM 			if (strcmp(client->scratchKeyValue, s) == 0) {
7377836SJohn.Forte@Sun.COM 				*negotiatedOption = optionList[i];
7387836SJohn.Forte@Sun.COM 				return;
7397836SJohn.Forte@Sun.COM 			}
7407836SJohn.Forte@Sun.COM 		}
7417836SJohn.Forte@Sun.COM 	}
7427836SJohn.Forte@Sun.COM 
7437836SJohn.Forte@Sun.COM 	*negotiatedOption = iscsiAuthOptionReject;
7447836SJohn.Forte@Sun.COM }
7457836SJohn.Forte@Sun.COM 
7467836SJohn.Forte@Sun.COM 
7477836SJohn.Forte@Sun.COM static void
iscsiAuthClientSetKey(IscsiAuthClient * client,int keyType,unsigned int optionCount,int * optionList,const char * (* valueToText)(IscsiAuthClient *,int))7487836SJohn.Forte@Sun.COM iscsiAuthClientSetKey(IscsiAuthClient * client,
7497836SJohn.Forte@Sun.COM     int keyType,
7507836SJohn.Forte@Sun.COM     unsigned int optionCount,
7517836SJohn.Forte@Sun.COM     int *optionList, const char *(*valueToText) (IscsiAuthClient *, int))
7527836SJohn.Forte@Sun.COM {
7537836SJohn.Forte@Sun.COM 	unsigned int i;
7547836SJohn.Forte@Sun.COM 
7557836SJohn.Forte@Sun.COM 	if (optionCount == 0) {
7567836SJohn.Forte@Sun.COM 		/*
7577836SJohn.Forte@Sun.COM 		 * No valid options to send, but we always want to
7587836SJohn.Forte@Sun.COM 		 * send something.
7597836SJohn.Forte@Sun.COM 		 */
7607836SJohn.Forte@Sun.COM 		iscsiAuthClientSetKeyValue(&client->sendKeyBlock, keyType,
7617836SJohn.Forte@Sun.COM 		    client->noneOptionName);
7627836SJohn.Forte@Sun.COM 		return;
7637836SJohn.Forte@Sun.COM 	}
7647836SJohn.Forte@Sun.COM 
7657836SJohn.Forte@Sun.COM 	if (optionCount == 1 && optionList[0] == iscsiAuthOptionNotPresent) {
7667836SJohn.Forte@Sun.COM 		iscsiAuthClientSetKeyValue(&client->sendKeyBlock, keyType, 0);
7677836SJohn.Forte@Sun.COM 		return;
7687836SJohn.Forte@Sun.COM 	}
7697836SJohn.Forte@Sun.COM 
7707836SJohn.Forte@Sun.COM 	for (i = 0; i < optionCount; i++) {
7717836SJohn.Forte@Sun.COM 		const char *s = (*valueToText) (client, optionList[i]);
7727836SJohn.Forte@Sun.COM 
7737836SJohn.Forte@Sun.COM 		if (!s)
7747836SJohn.Forte@Sun.COM 			continue;
7757836SJohn.Forte@Sun.COM 
7767836SJohn.Forte@Sun.COM 		if (i == 0) {
7777836SJohn.Forte@Sun.COM 			(void) iscsiAuthClientStringCopy(
7787836SJohn.Forte@Sun.COM 			    client->scratchKeyValue,
7797836SJohn.Forte@Sun.COM 			    s, iscsiAuthStringMaxLength);
7807836SJohn.Forte@Sun.COM 		} else {
7817836SJohn.Forte@Sun.COM 			(void) iscsiAuthClientStringAppend(
7827836SJohn.Forte@Sun.COM 			    client->scratchKeyValue,
7837836SJohn.Forte@Sun.COM 			    ",", iscsiAuthStringMaxLength);
7847836SJohn.Forte@Sun.COM 			(void) iscsiAuthClientStringAppend(
7857836SJohn.Forte@Sun.COM 			    client->scratchKeyValue,
7867836SJohn.Forte@Sun.COM 			    s, iscsiAuthStringMaxLength);
7877836SJohn.Forte@Sun.COM 		}
7887836SJohn.Forte@Sun.COM 	}
7897836SJohn.Forte@Sun.COM 
7907836SJohn.Forte@Sun.COM 	iscsiAuthClientSetKeyValue(&client->sendKeyBlock,
7917836SJohn.Forte@Sun.COM 	    keyType, client->scratchKeyValue);
7927836SJohn.Forte@Sun.COM }
7937836SJohn.Forte@Sun.COM 
7947836SJohn.Forte@Sun.COM 
7957836SJohn.Forte@Sun.COM static void
iscsiAuthClientCheckAuthMethodKey(IscsiAuthClient * client)7967836SJohn.Forte@Sun.COM iscsiAuthClientCheckAuthMethodKey(IscsiAuthClient * client)
7977836SJohn.Forte@Sun.COM {
7987836SJohn.Forte@Sun.COM 	iscsiAuthClientCheckKey(client,
7997836SJohn.Forte@Sun.COM 	    iscsiAuthKeyTypeAuthMethod,
8007836SJohn.Forte@Sun.COM 	    &client->negotiatedAuthMethod,
8017836SJohn.Forte@Sun.COM 	    client->authMethodValidCount,
8027836SJohn.Forte@Sun.COM 	    client->authMethodValidList, iscsiAuthClientAuthMethodOptionToText);
8037836SJohn.Forte@Sun.COM }
8047836SJohn.Forte@Sun.COM 
8057836SJohn.Forte@Sun.COM 
8067836SJohn.Forte@Sun.COM static void
iscsiAuthClientSetAuthMethodKey(IscsiAuthClient * client,unsigned int authMethodCount,int * authMethodList)8077836SJohn.Forte@Sun.COM iscsiAuthClientSetAuthMethodKey(IscsiAuthClient * client,
8087836SJohn.Forte@Sun.COM     unsigned int authMethodCount, int *authMethodList)
8097836SJohn.Forte@Sun.COM {
8107836SJohn.Forte@Sun.COM 	iscsiAuthClientSetKey(client, iscsiAuthKeyTypeAuthMethod,
8117836SJohn.Forte@Sun.COM 	    authMethodCount, authMethodList,
8127836SJohn.Forte@Sun.COM 	    iscsiAuthClientAuthMethodOptionToText);
8137836SJohn.Forte@Sun.COM }
8147836SJohn.Forte@Sun.COM 
8157836SJohn.Forte@Sun.COM 
8167836SJohn.Forte@Sun.COM static void
iscsiAuthClientCheckChapAlgorithmKey(IscsiAuthClient * client)8177836SJohn.Forte@Sun.COM iscsiAuthClientCheckChapAlgorithmKey(IscsiAuthClient * client)
8187836SJohn.Forte@Sun.COM {
8197836SJohn.Forte@Sun.COM 	const char *keyValue;
8207836SJohn.Forte@Sun.COM 	int length;
8217836SJohn.Forte@Sun.COM 	unsigned long number;
8227836SJohn.Forte@Sun.COM 	unsigned int i;
8237836SJohn.Forte@Sun.COM 
8247836SJohn.Forte@Sun.COM 	keyValue = iscsiAuthClientGetKeyValue(&client->recvKeyBlock,
8257836SJohn.Forte@Sun.COM 	    iscsiAuthKeyTypeChapAlgorithm);
8267836SJohn.Forte@Sun.COM 	if (!keyValue) {
8277836SJohn.Forte@Sun.COM 		client->negotiatedChapAlgorithm = iscsiAuthOptionNotPresent;
8287836SJohn.Forte@Sun.COM 		return;
8297836SJohn.Forte@Sun.COM 	}
8307836SJohn.Forte@Sun.COM 
8317836SJohn.Forte@Sun.COM 	while (*keyValue != '\0') {
8327836SJohn.Forte@Sun.COM 		length = 0;
8337836SJohn.Forte@Sun.COM 
8347836SJohn.Forte@Sun.COM 		while (*keyValue != '\0' && *keyValue != ',') {
8357836SJohn.Forte@Sun.COM 			client->scratchKeyValue[length++] = *keyValue++;
8367836SJohn.Forte@Sun.COM 		}
8377836SJohn.Forte@Sun.COM 
8387836SJohn.Forte@Sun.COM 		if (*keyValue == ',')
8397836SJohn.Forte@Sun.COM 			keyValue++;
8407836SJohn.Forte@Sun.COM 		client->scratchKeyValue[length++] = '\0';
8417836SJohn.Forte@Sun.COM 
8427836SJohn.Forte@Sun.COM 		if (iscsiAuthClientTextToNumber(client->scratchKeyValue,
8437836SJohn.Forte@Sun.COM 		    &number)) {
8447836SJohn.Forte@Sun.COM 			continue;
8457836SJohn.Forte@Sun.COM 		}
8467836SJohn.Forte@Sun.COM 
8477836SJohn.Forte@Sun.COM 		for (i = 0; i < client->chapAlgorithmCount; i++) {
8487836SJohn.Forte@Sun.COM 
8497836SJohn.Forte@Sun.COM 			if (number == (unsigned long)client->
8507836SJohn.Forte@Sun.COM 			    chapAlgorithmList[i]) {
8517836SJohn.Forte@Sun.COM 				client->negotiatedChapAlgorithm = number;
8527836SJohn.Forte@Sun.COM 				return;
8537836SJohn.Forte@Sun.COM 			}
8547836SJohn.Forte@Sun.COM 		}
8557836SJohn.Forte@Sun.COM 	}
8567836SJohn.Forte@Sun.COM 
8577836SJohn.Forte@Sun.COM 	client->negotiatedChapAlgorithm = iscsiAuthOptionReject;
8587836SJohn.Forte@Sun.COM }
8597836SJohn.Forte@Sun.COM 
8607836SJohn.Forte@Sun.COM 
8617836SJohn.Forte@Sun.COM static void
iscsiAuthClientSetChapAlgorithmKey(IscsiAuthClient * client,unsigned int chapAlgorithmCount,int * chapAlgorithmList)8627836SJohn.Forte@Sun.COM iscsiAuthClientSetChapAlgorithmKey(IscsiAuthClient * client,
8637836SJohn.Forte@Sun.COM     unsigned int chapAlgorithmCount, int *chapAlgorithmList)
8647836SJohn.Forte@Sun.COM {
8657836SJohn.Forte@Sun.COM 	unsigned int i;
8667836SJohn.Forte@Sun.COM 
8677836SJohn.Forte@Sun.COM 	if (chapAlgorithmCount == 0) {
8687836SJohn.Forte@Sun.COM 		iscsiAuthClientSetKeyValue(&client->sendKeyBlock,
8697836SJohn.Forte@Sun.COM 		    iscsiAuthKeyTypeChapAlgorithm, 0);
8707836SJohn.Forte@Sun.COM 		return;
8717836SJohn.Forte@Sun.COM 	}
8727836SJohn.Forte@Sun.COM 
8737836SJohn.Forte@Sun.COM 	if (chapAlgorithmCount == 1 &&
8747836SJohn.Forte@Sun.COM 	    chapAlgorithmList[0] == iscsiAuthOptionNotPresent) {
8757836SJohn.Forte@Sun.COM 		iscsiAuthClientSetKeyValue(&client->sendKeyBlock,
8767836SJohn.Forte@Sun.COM 		    iscsiAuthKeyTypeChapAlgorithm, 0);
8777836SJohn.Forte@Sun.COM 		return;
8787836SJohn.Forte@Sun.COM 	}
8797836SJohn.Forte@Sun.COM 
8807836SJohn.Forte@Sun.COM 	if (chapAlgorithmCount == 1 &&
8817836SJohn.Forte@Sun.COM 	    chapAlgorithmList[0] == iscsiAuthOptionReject) {
8827836SJohn.Forte@Sun.COM 		iscsiAuthClientSetKeyValue(&client->sendKeyBlock,
8837836SJohn.Forte@Sun.COM 		    iscsiAuthKeyTypeChapAlgorithm, client->rejectOptionName);
8847836SJohn.Forte@Sun.COM 		return;
8857836SJohn.Forte@Sun.COM 	}
8867836SJohn.Forte@Sun.COM 
8877836SJohn.Forte@Sun.COM 	for (i = 0; i < chapAlgorithmCount; i++) {
8887836SJohn.Forte@Sun.COM 		char s[20];
8897836SJohn.Forte@Sun.COM 
8907836SJohn.Forte@Sun.COM 		iscsiAuthClientNumberToText(chapAlgorithmList[i],
8917836SJohn.Forte@Sun.COM 		    s, sizeof (s));
8927836SJohn.Forte@Sun.COM 
8937836SJohn.Forte@Sun.COM 		if (i == 0) {
8947836SJohn.Forte@Sun.COM 			(void) iscsiAuthClientStringCopy(
8957836SJohn.Forte@Sun.COM 			    client->scratchKeyValue, s,
8967836SJohn.Forte@Sun.COM 			    iscsiAuthStringMaxLength);
8977836SJohn.Forte@Sun.COM 		} else {
8987836SJohn.Forte@Sun.COM 			(void) iscsiAuthClientStringAppend(
8997836SJohn.Forte@Sun.COM 			    client->scratchKeyValue,
9007836SJohn.Forte@Sun.COM 			    ",", iscsiAuthStringMaxLength);
9017836SJohn.Forte@Sun.COM 			(void) iscsiAuthClientStringAppend(
9027836SJohn.Forte@Sun.COM 			    client->scratchKeyValue,
9037836SJohn.Forte@Sun.COM 			    s, iscsiAuthStringMaxLength);
9047836SJohn.Forte@Sun.COM 		}
9057836SJohn.Forte@Sun.COM 	}
9067836SJohn.Forte@Sun.COM 
9077836SJohn.Forte@Sun.COM 	iscsiAuthClientSetKeyValue(&client->sendKeyBlock,
9087836SJohn.Forte@Sun.COM 	    iscsiAuthKeyTypeChapAlgorithm, client->scratchKeyValue);
9097836SJohn.Forte@Sun.COM }
9107836SJohn.Forte@Sun.COM 
9117836SJohn.Forte@Sun.COM 
9127836SJohn.Forte@Sun.COM static void
iscsiAuthClientNextPhase(IscsiAuthClient * client)9137836SJohn.Forte@Sun.COM iscsiAuthClientNextPhase(IscsiAuthClient * client)
9147836SJohn.Forte@Sun.COM {
9157836SJohn.Forte@Sun.COM 	switch (client->phase) {
9167836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseConfigure:
9177836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseNegotiate;
9187836SJohn.Forte@Sun.COM 		break;
9197836SJohn.Forte@Sun.COM 
9207836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseNegotiate:
9217836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseAuthenticate;
9227836SJohn.Forte@Sun.COM 
9237836SJohn.Forte@Sun.COM 		if (client->negotiatedAuthMethod ==
9247836SJohn.Forte@Sun.COM 		    iscsiAuthOptionReject ||
9257836SJohn.Forte@Sun.COM 		    client->negotiatedAuthMethod ==
9267836SJohn.Forte@Sun.COM 		    iscsiAuthOptionNotPresent ||
9277836SJohn.Forte@Sun.COM 		    client->negotiatedAuthMethod == iscsiAuthOptionNone) {
9287836SJohn.Forte@Sun.COM 
9297836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateDone;
9307836SJohn.Forte@Sun.COM 			client->remoteState = iscsiAuthRemoteStateDone;
9317836SJohn.Forte@Sun.COM 
9327836SJohn.Forte@Sun.COM 			if (client->authRemote) {
9337836SJohn.Forte@Sun.COM 				client->remoteAuthStatus = iscsiAuthStatusFail;
9347836SJohn.Forte@Sun.COM 				client->phase = iscsiAuthPhaseDone;
9357836SJohn.Forte@Sun.COM 			} else {
9367836SJohn.Forte@Sun.COM 				client->remoteAuthStatus = iscsiAuthStatusPass;
9377836SJohn.Forte@Sun.COM 			}
9387836SJohn.Forte@Sun.COM 
9397836SJohn.Forte@Sun.COM 			switch (client->negotiatedAuthMethod) {
9407836SJohn.Forte@Sun.COM 			case iscsiAuthOptionReject:
9417836SJohn.Forte@Sun.COM 				client->debugStatus =
9427836SJohn.Forte@Sun.COM 				    iscsiAuthDebugStatusAuthMethodReject;
9437836SJohn.Forte@Sun.COM 				break;
9447836SJohn.Forte@Sun.COM 
9457836SJohn.Forte@Sun.COM 			case iscsiAuthOptionNotPresent:
9467836SJohn.Forte@Sun.COM 				client->debugStatus =
9477836SJohn.Forte@Sun.COM 				    iscsiAuthDebugStatusAuthMethodNotPresent;
9487836SJohn.Forte@Sun.COM 				break;
9497836SJohn.Forte@Sun.COM 
9507836SJohn.Forte@Sun.COM 			case iscsiAuthOptionNone:
9517836SJohn.Forte@Sun.COM 				client->debugStatus =
9527836SJohn.Forte@Sun.COM 				    iscsiAuthDebugStatusAuthMethodNone;
9537836SJohn.Forte@Sun.COM 			}
9547836SJohn.Forte@Sun.COM 
9557836SJohn.Forte@Sun.COM 		} else if (client->negotiatedAuthMethod ==
9567836SJohn.Forte@Sun.COM 		    iscsiAuthMethodChap) {
9577836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateSendAlgorithm;
9587836SJohn.Forte@Sun.COM 			client->remoteState = iscsiAuthRemoteStateSendAlgorithm;
9597836SJohn.Forte@Sun.COM 		} else {
9607836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateDone;
9617836SJohn.Forte@Sun.COM 			client->remoteState = iscsiAuthRemoteStateDone;
9627836SJohn.Forte@Sun.COM 			client->remoteAuthStatus = iscsiAuthStatusFail;
9637836SJohn.Forte@Sun.COM 			client->debugStatus = iscsiAuthDebugStatusAuthMethodBad;
9647836SJohn.Forte@Sun.COM 		}
9657836SJohn.Forte@Sun.COM 
9667836SJohn.Forte@Sun.COM 		break;
9677836SJohn.Forte@Sun.COM 
9687836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseAuthenticate:
9697836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseDone;
9707836SJohn.Forte@Sun.COM 		break;
9717836SJohn.Forte@Sun.COM 
9727836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseDone:
9737836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseError:
9747836SJohn.Forte@Sun.COM 	default:
9757836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
9767836SJohn.Forte@Sun.COM 	}
9777836SJohn.Forte@Sun.COM }
9787836SJohn.Forte@Sun.COM 
9797836SJohn.Forte@Sun.COM 
9807836SJohn.Forte@Sun.COM static void
iscsiAuthClientLocalAuthentication(IscsiAuthClient * client)9817836SJohn.Forte@Sun.COM iscsiAuthClientLocalAuthentication(IscsiAuthClient * client)
9827836SJohn.Forte@Sun.COM {
9837836SJohn.Forte@Sun.COM 	unsigned int chapIdentifier;
9847836SJohn.Forte@Sun.COM 	unsigned char responseData[iscsiAuthChapResponseLength];
9857836SJohn.Forte@Sun.COM 	unsigned long number;
9867836SJohn.Forte@Sun.COM 	int status;
9877836SJohn.Forte@Sun.COM 	IscsiAuthDebugStatus debugStatus;
9887836SJohn.Forte@Sun.COM 	const char *chapIdentifierKeyValue;
9897836SJohn.Forte@Sun.COM 	const char *chapChallengeKeyValue;
9907836SJohn.Forte@Sun.COM 
9917836SJohn.Forte@Sun.COM 	switch (client->localState) {
9927836SJohn.Forte@Sun.COM 	case iscsiAuthLocalStateSendAlgorithm:
9937836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeInitiator) {
9947836SJohn.Forte@Sun.COM 			iscsiAuthClientSetChapAlgorithmKey(
9957836SJohn.Forte@Sun.COM 			    client, client->chapAlgorithmCount,
9967836SJohn.Forte@Sun.COM 			    client->chapAlgorithmList);
9977836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateRecvAlgorithm;
9987836SJohn.Forte@Sun.COM 			break;
9997836SJohn.Forte@Sun.COM 		}
10007836SJohn.Forte@Sun.COM 
10017836SJohn.Forte@Sun.COM 		/* FALLTHRU */
10027836SJohn.Forte@Sun.COM 
10037836SJohn.Forte@Sun.COM 	case iscsiAuthLocalStateRecvAlgorithm:
10047836SJohn.Forte@Sun.COM 		iscsiAuthClientCheckChapAlgorithmKey(client);
10057836SJohn.Forte@Sun.COM 
10067836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeTarget) {
10077836SJohn.Forte@Sun.COM 
10087836SJohn.Forte@Sun.COM 			iscsiAuthClientSetChapAlgorithmKey(client, 1,
10097836SJohn.Forte@Sun.COM 			    &client->negotiatedChapAlgorithm);
10107836SJohn.Forte@Sun.COM 		}
10117836SJohn.Forte@Sun.COM 
10127836SJohn.Forte@Sun.COM 		/*
10137836SJohn.Forte@Sun.COM 		 * Make sure only supported CHAP algorithm is used.
10147836SJohn.Forte@Sun.COM 		 */
10157836SJohn.Forte@Sun.COM 		if (client->negotiatedChapAlgorithm ==
10167836SJohn.Forte@Sun.COM 		    iscsiAuthOptionNotPresent) {
10177836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateError;
10187836SJohn.Forte@Sun.COM 			client->debugStatus =
10197836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapAlgorithmExpected;
10207836SJohn.Forte@Sun.COM 			break;
10217836SJohn.Forte@Sun.COM 
10227836SJohn.Forte@Sun.COM 		} else if (client->negotiatedChapAlgorithm ==
10237836SJohn.Forte@Sun.COM 		    iscsiAuthOptionReject) {
10247836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateError;
10257836SJohn.Forte@Sun.COM 			client->debugStatus =
10267836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapAlgorithmReject;
10277836SJohn.Forte@Sun.COM 			break;
10287836SJohn.Forte@Sun.COM 
10297836SJohn.Forte@Sun.COM 		} else if (client->negotiatedChapAlgorithm !=
10307836SJohn.Forte@Sun.COM 		    iscsiAuthChapAlgorithmMd5) {
10317836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateError;
10327836SJohn.Forte@Sun.COM 			client->debugStatus =
10337836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapAlgorithmBad;
10347836SJohn.Forte@Sun.COM 			break;
10357836SJohn.Forte@Sun.COM 		}
10367836SJohn.Forte@Sun.COM 
10377836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeTarget) {
10387836SJohn.Forte@Sun.COM 
10397836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateRecvChallenge;
10407836SJohn.Forte@Sun.COM 			break;
10417836SJohn.Forte@Sun.COM 		}
10427836SJohn.Forte@Sun.COM 
10437836SJohn.Forte@Sun.COM 		/* FALLTHRU */
10447836SJohn.Forte@Sun.COM 
10457836SJohn.Forte@Sun.COM 	case iscsiAuthLocalStateRecvChallenge:
10467836SJohn.Forte@Sun.COM 		chapIdentifierKeyValue = iscsiAuthClientGetKeyValue(
10477836SJohn.Forte@Sun.COM 		    &client->recvKeyBlock, iscsiAuthKeyTypeChapIdentifier);
10487836SJohn.Forte@Sun.COM 		chapChallengeKeyValue = iscsiAuthClientGetKeyValue(
10497836SJohn.Forte@Sun.COM 		    &client->recvKeyBlock, iscsiAuthKeyTypeChapChallenge);
10507836SJohn.Forte@Sun.COM 
10517836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeTarget) {
10527836SJohn.Forte@Sun.COM 			if (!chapIdentifierKeyValue && !chapChallengeKeyValue) {
10537836SJohn.Forte@Sun.COM 				client->localState = iscsiAuthLocalStateDone;
10547836SJohn.Forte@Sun.COM 				break;
10557836SJohn.Forte@Sun.COM 			}
10567836SJohn.Forte@Sun.COM 		}
10577836SJohn.Forte@Sun.COM 
10587836SJohn.Forte@Sun.COM 		if (!chapIdentifierKeyValue) {
10597836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateError;
10607836SJohn.Forte@Sun.COM 			client->debugStatus =
10617836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapIdentifierExpected;
10627836SJohn.Forte@Sun.COM 			break;
10637836SJohn.Forte@Sun.COM 		}
10647836SJohn.Forte@Sun.COM 
10657836SJohn.Forte@Sun.COM 		if (!chapChallengeKeyValue) {
10667836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateError;
10677836SJohn.Forte@Sun.COM 			client->debugStatus =
10687836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapChallengeExpected;
10697836SJohn.Forte@Sun.COM 			break;
10707836SJohn.Forte@Sun.COM 		}
10717836SJohn.Forte@Sun.COM 
10727836SJohn.Forte@Sun.COM 		status = iscsiAuthClientTextToNumber(
10737836SJohn.Forte@Sun.COM 		    chapIdentifierKeyValue, &number);
10747836SJohn.Forte@Sun.COM 
10757836SJohn.Forte@Sun.COM 		if (status || (255 < number)) {
10767836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateError;
10777836SJohn.Forte@Sun.COM 			client->debugStatus =
10787836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapIdentifierBad;
10797836SJohn.Forte@Sun.COM 			break;
10807836SJohn.Forte@Sun.COM 		}
10817836SJohn.Forte@Sun.COM 		chapIdentifier = number;
10827836SJohn.Forte@Sun.COM 
10837836SJohn.Forte@Sun.COM 		if (client->recvChapChallengeStatus) {
10847836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateError;
10857836SJohn.Forte@Sun.COM 			client->debugStatus =
10867836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapChallengeBad;
10877836SJohn.Forte@Sun.COM 			break;
10887836SJohn.Forte@Sun.COM 		}
10897836SJohn.Forte@Sun.COM 
10907836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeTarget &&
10917836SJohn.Forte@Sun.COM 		    client->recvChapChallenge.length ==
10927836SJohn.Forte@Sun.COM 		    client->sendChapChallenge.length &&
10937836SJohn.Forte@Sun.COM 		    bcmp(client->recvChapChallenge.largeBinary,
10947836SJohn.Forte@Sun.COM 		    client->sendChapChallenge.largeBinary,
10957836SJohn.Forte@Sun.COM 		    client->sendChapChallenge.length) == 0) {
10967836SJohn.Forte@Sun.COM 
10977836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateError;
10987836SJohn.Forte@Sun.COM 			client->debugStatus =
10997836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapChallengeReflected;
11007836SJohn.Forte@Sun.COM 			break;
11017836SJohn.Forte@Sun.COM 		}
11027836SJohn.Forte@Sun.COM 
11037836SJohn.Forte@Sun.COM 		debugStatus = iscsiAuthClientChapComputeResponse(client,
11047836SJohn.Forte@Sun.COM 		    FALSE,
11057836SJohn.Forte@Sun.COM 		    chapIdentifier,
11067836SJohn.Forte@Sun.COM 		    client->recvChapChallenge.largeBinary,
11077836SJohn.Forte@Sun.COM 		    client->recvChapChallenge.length, responseData);
11087836SJohn.Forte@Sun.COM 
11097836SJohn.Forte@Sun.COM 		if (debugStatus != iscsiAuthDebugStatusNotSet) {
11107836SJohn.Forte@Sun.COM 			client->localState = iscsiAuthLocalStateError;
11117836SJohn.Forte@Sun.COM 			client->debugStatus = debugStatus;
11127836SJohn.Forte@Sun.COM 			break;
11137836SJohn.Forte@Sun.COM 		}
11147836SJohn.Forte@Sun.COM 
11157836SJohn.Forte@Sun.COM 		(void) iscsiAuthClientDataToText(client->base64,
11167836SJohn.Forte@Sun.COM 		    responseData, iscsiAuthChapResponseLength,
11177836SJohn.Forte@Sun.COM 		    client->scratchKeyValue, iscsiAuthStringMaxLength);
11187836SJohn.Forte@Sun.COM 		iscsiAuthClientSetKeyValue(&client->sendKeyBlock,
11197836SJohn.Forte@Sun.COM 		    iscsiAuthKeyTypeChapResponse, client->scratchKeyValue);
11207836SJohn.Forte@Sun.COM 
11217836SJohn.Forte@Sun.COM 		iscsiAuthClientSetKeyValue(&client->sendKeyBlock,
11227836SJohn.Forte@Sun.COM 		    iscsiAuthKeyTypeChapUsername, client->username);
11237836SJohn.Forte@Sun.COM 
11247836SJohn.Forte@Sun.COM 		client->localState = iscsiAuthLocalStateDone;
11257836SJohn.Forte@Sun.COM 		break;
11267836SJohn.Forte@Sun.COM 
11277836SJohn.Forte@Sun.COM 	case iscsiAuthLocalStateDone:
11287836SJohn.Forte@Sun.COM 		break;
11297836SJohn.Forte@Sun.COM 
11307836SJohn.Forte@Sun.COM 	case iscsiAuthLocalStateError:
11317836SJohn.Forte@Sun.COM 	default:
11327836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
11337836SJohn.Forte@Sun.COM 	}
11347836SJohn.Forte@Sun.COM }
11357836SJohn.Forte@Sun.COM 
11367836SJohn.Forte@Sun.COM 
11377836SJohn.Forte@Sun.COM static void
iscsiAuthClientRemoteAuthentication(IscsiAuthClient * client)11387836SJohn.Forte@Sun.COM iscsiAuthClientRemoteAuthentication(IscsiAuthClient * client)
11397836SJohn.Forte@Sun.COM {
11407836SJohn.Forte@Sun.COM 	unsigned char idData[1];
11417836SJohn.Forte@Sun.COM 	unsigned char responseData[iscsiAuthStringMaxLength];
11427836SJohn.Forte@Sun.COM 	unsigned int responseLength = iscsiAuthStringMaxLength;
11437836SJohn.Forte@Sun.COM 	unsigned char myResponseData[iscsiAuthChapResponseLength];
11447836SJohn.Forte@Sun.COM 	int status;
11457836SJohn.Forte@Sun.COM 	IscsiAuthDebugStatus debugStatus;
11467836SJohn.Forte@Sun.COM 	const char *chapResponseKeyValue;
11477836SJohn.Forte@Sun.COM 	const char *chapUsernameKeyValue;
11487836SJohn.Forte@Sun.COM 
11497836SJohn.Forte@Sun.COM 	switch (client->remoteState) {
11507836SJohn.Forte@Sun.COM 	case iscsiAuthRemoteStateSendAlgorithm:
11517836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeInitiator) {
11527836SJohn.Forte@Sun.COM 			client->remoteState = iscsiAuthRemoteStateSendChallenge;
11537836SJohn.Forte@Sun.COM 			break;
11547836SJohn.Forte@Sun.COM 		}
11557836SJohn.Forte@Sun.COM 
11567836SJohn.Forte@Sun.COM 		/* FALLTHRU */
11577836SJohn.Forte@Sun.COM 
11587836SJohn.Forte@Sun.COM 	case iscsiAuthRemoteStateSendChallenge:
11597836SJohn.Forte@Sun.COM 		if (!client->authRemote) {
11607836SJohn.Forte@Sun.COM 			client->remoteAuthStatus = iscsiAuthStatusPass;
11617836SJohn.Forte@Sun.COM 			client->debugStatus =
11627836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusAuthRemoteFalse;
11637836SJohn.Forte@Sun.COM 			client->remoteState = iscsiAuthRemoteStateDone;
11647836SJohn.Forte@Sun.COM 			break;
11657836SJohn.Forte@Sun.COM 		}
11667836SJohn.Forte@Sun.COM 
11677836SJohn.Forte@Sun.COM 		iscsiAuthRandomSetData(idData, 1);
11687836SJohn.Forte@Sun.COM 		client->sendChapIdentifier = idData[0];
11697836SJohn.Forte@Sun.COM 
11707836SJohn.Forte@Sun.COM 		iscsiAuthClientNumberToText(client->sendChapIdentifier,
11717836SJohn.Forte@Sun.COM 		    client->scratchKeyValue, iscsiAuthStringMaxLength);
11727836SJohn.Forte@Sun.COM 		iscsiAuthClientSetKeyValue(&client->sendKeyBlock,
11737836SJohn.Forte@Sun.COM 		    iscsiAuthKeyTypeChapIdentifier, client->scratchKeyValue);
11747836SJohn.Forte@Sun.COM 
11757836SJohn.Forte@Sun.COM 		client->sendChapChallenge.length = client->chapChallengeLength;
11767836SJohn.Forte@Sun.COM 		iscsiAuthRandomSetData(client->sendChapChallenge.largeBinary,
11777836SJohn.Forte@Sun.COM 		    client->sendChapChallenge.length);
11787836SJohn.Forte@Sun.COM 
11797836SJohn.Forte@Sun.COM 		iscsiAuthClientSetKeyValue(&client->sendKeyBlock,
11807836SJohn.Forte@Sun.COM 		    iscsiAuthKeyTypeChapChallenge, "");
11817836SJohn.Forte@Sun.COM 
11827836SJohn.Forte@Sun.COM 		client->remoteState = iscsiAuthRemoteStateRecvResponse;
11837836SJohn.Forte@Sun.COM 		break;
11847836SJohn.Forte@Sun.COM 
11857836SJohn.Forte@Sun.COM 	case iscsiAuthRemoteStateRecvResponse:
11867836SJohn.Forte@Sun.COM 		chapResponseKeyValue = iscsiAuthClientGetKeyValue(
11877836SJohn.Forte@Sun.COM 		    &client->recvKeyBlock, iscsiAuthKeyTypeChapResponse);
11887836SJohn.Forte@Sun.COM 
11897836SJohn.Forte@Sun.COM 		chapUsernameKeyValue = iscsiAuthClientGetKeyValue(
11907836SJohn.Forte@Sun.COM 		    &client->recvKeyBlock, iscsiAuthKeyTypeChapUsername);
11917836SJohn.Forte@Sun.COM 
11927836SJohn.Forte@Sun.COM 		if (!chapResponseKeyValue) {
11937836SJohn.Forte@Sun.COM 			client->remoteState = iscsiAuthRemoteStateError;
11947836SJohn.Forte@Sun.COM 			client->debugStatus =
11957836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapResponseExpected;
11967836SJohn.Forte@Sun.COM 			break;
11977836SJohn.Forte@Sun.COM 		}
11987836SJohn.Forte@Sun.COM 
11997836SJohn.Forte@Sun.COM 		if (!chapUsernameKeyValue) {
12007836SJohn.Forte@Sun.COM 			client->remoteState = iscsiAuthRemoteStateError;
12017836SJohn.Forte@Sun.COM 			client->debugStatus =
12027836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapUsernameExpected;
12037836SJohn.Forte@Sun.COM 			break;
12047836SJohn.Forte@Sun.COM 		}
12057836SJohn.Forte@Sun.COM 
12067836SJohn.Forte@Sun.COM 		status = iscsiAuthClientTextToData(chapResponseKeyValue,
12077836SJohn.Forte@Sun.COM 		    responseData, &responseLength);
12087836SJohn.Forte@Sun.COM 
12097836SJohn.Forte@Sun.COM 		if (status) {
12107836SJohn.Forte@Sun.COM 			client->remoteState = iscsiAuthRemoteStateError;
12117836SJohn.Forte@Sun.COM 			client->debugStatus =
12127836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusChapResponseBad;
12137836SJohn.Forte@Sun.COM 			break;
12147836SJohn.Forte@Sun.COM 		}
12157836SJohn.Forte@Sun.COM 
12167836SJohn.Forte@Sun.COM 		if (responseLength == iscsiAuthChapResponseLength) {
12177836SJohn.Forte@Sun.COM 			debugStatus = iscsiAuthClientChapComputeResponse(
12187836SJohn.Forte@Sun.COM 			    client, TRUE, client->sendChapIdentifier,
12197836SJohn.Forte@Sun.COM 			    client->sendChapChallenge.largeBinary,
12207836SJohn.Forte@Sun.COM 			    client->sendChapChallenge.length, myResponseData);
12217836SJohn.Forte@Sun.COM 
12227836SJohn.Forte@Sun.COM 			/*
12237836SJohn.Forte@Sun.COM 			 * Check if the same CHAP secret is being used for
12247836SJohn.Forte@Sun.COM 			 * authentication in both directions.
12257836SJohn.Forte@Sun.COM 			 */
12267836SJohn.Forte@Sun.COM 			if (debugStatus == iscsiAuthDebugStatusNotSet &&
12277836SJohn.Forte@Sun.COM 			    bcmp(myResponseData, responseData,
12287836SJohn.Forte@Sun.COM 			    iscsiAuthChapResponseLength) == 0) {
12297836SJohn.Forte@Sun.COM 
12307836SJohn.Forte@Sun.COM 				client->remoteState =
12317836SJohn.Forte@Sun.COM 				    iscsiAuthRemoteStateError;
12327836SJohn.Forte@Sun.COM 				client->debugStatus =
12337836SJohn.Forte@Sun.COM 				    iscsiAuthDebugStatusPasswordIdentical;
12347836SJohn.Forte@Sun.COM 				break;
12357836SJohn.Forte@Sun.COM 			}
12367836SJohn.Forte@Sun.COM 		}
12377836SJohn.Forte@Sun.COM 
12387836SJohn.Forte@Sun.COM 		(void) iscsiAuthClientStringCopy(client->chapUsername,
12397836SJohn.Forte@Sun.COM 		    chapUsernameKeyValue, iscsiAuthStringMaxLength);
12407836SJohn.Forte@Sun.COM 
12417836SJohn.Forte@Sun.COM 		/* To verify the target's response. */
12427836SJohn.Forte@Sun.COM 		status = iscsiAuthClientChapAuthRequest(
12437836SJohn.Forte@Sun.COM 		    client, client->chapUsername, client->sendChapIdentifier,
12447836SJohn.Forte@Sun.COM 		    client->sendChapChallenge.largeBinary,
12457836SJohn.Forte@Sun.COM 		    client->sendChapChallenge.length, responseData,
12467836SJohn.Forte@Sun.COM 		    responseLength);
12477836SJohn.Forte@Sun.COM 
12487836SJohn.Forte@Sun.COM 		if (status == iscsiAuthStatusInProgress) {
12497836SJohn.Forte@Sun.COM 			iscsiAuthClientGlobalStats.requestSent++;
12507836SJohn.Forte@Sun.COM 			client->remoteState = iscsiAuthRemoteStateAuthRequest;
12517836SJohn.Forte@Sun.COM 			break;
12527836SJohn.Forte@Sun.COM 		}
12537836SJohn.Forte@Sun.COM 
12547836SJohn.Forte@Sun.COM 		client->remoteAuthStatus = (IscsiAuthStatus) status;
12557836SJohn.Forte@Sun.COM 		client->authResponseFlag = TRUE;
12567836SJohn.Forte@Sun.COM 
12577836SJohn.Forte@Sun.COM 		/* FALLTHRU */
12587836SJohn.Forte@Sun.COM 
12597836SJohn.Forte@Sun.COM 	case iscsiAuthRemoteStateAuthRequest:
12607836SJohn.Forte@Sun.COM 		/*
12617836SJohn.Forte@Sun.COM 		 * client->remoteAuthStatus already set
12627836SJohn.Forte@Sun.COM 		 */
12637836SJohn.Forte@Sun.COM 		if (client->authServerErrorFlag) {
12647836SJohn.Forte@Sun.COM 			client->remoteAuthStatus = iscsiAuthStatusFail;
12657836SJohn.Forte@Sun.COM 			client->debugStatus =
12667836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusAuthServerError;
12677836SJohn.Forte@Sun.COM 		} else if (client->remoteAuthStatus == iscsiAuthStatusPass) {
12687836SJohn.Forte@Sun.COM 			client->debugStatus = iscsiAuthDebugStatusAuthPass;
12697836SJohn.Forte@Sun.COM 		} else if (client->remoteAuthStatus == iscsiAuthStatusFail) {
12707836SJohn.Forte@Sun.COM 			client->debugStatus = iscsiAuthDebugStatusAuthFail;
12717836SJohn.Forte@Sun.COM 		} else {
12727836SJohn.Forte@Sun.COM 			client->remoteAuthStatus = iscsiAuthStatusFail;
12737836SJohn.Forte@Sun.COM 			client->debugStatus = iscsiAuthDebugStatusAuthStatusBad;
12747836SJohn.Forte@Sun.COM 		}
12757836SJohn.Forte@Sun.COM 		client->remoteState = iscsiAuthRemoteStateDone;
12767836SJohn.Forte@Sun.COM 
12777836SJohn.Forte@Sun.COM 		/* FALLTHRU */
12787836SJohn.Forte@Sun.COM 
12797836SJohn.Forte@Sun.COM 	case iscsiAuthRemoteStateDone:
12807836SJohn.Forte@Sun.COM 		break;
12817836SJohn.Forte@Sun.COM 
12827836SJohn.Forte@Sun.COM 	case iscsiAuthRemoteStateError:
12837836SJohn.Forte@Sun.COM 	default:
12847836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
12857836SJohn.Forte@Sun.COM 	}
12867836SJohn.Forte@Sun.COM }
12877836SJohn.Forte@Sun.COM 
12887836SJohn.Forte@Sun.COM 
12897836SJohn.Forte@Sun.COM static void
iscsiAuthClientHandshake(IscsiAuthClient * client)12907836SJohn.Forte@Sun.COM iscsiAuthClientHandshake(IscsiAuthClient * client)
12917836SJohn.Forte@Sun.COM {
12927836SJohn.Forte@Sun.COM 	if (client->phase == iscsiAuthPhaseDone) {
12937836SJohn.Forte@Sun.COM 		/*
12947836SJohn.Forte@Sun.COM 		 * Should only happen if authentication
12957836SJohn.Forte@Sun.COM 		 * protocol error occured.
12967836SJohn.Forte@Sun.COM 		 */
12977836SJohn.Forte@Sun.COM 		return;
12987836SJohn.Forte@Sun.COM 	}
12997836SJohn.Forte@Sun.COM 
13007836SJohn.Forte@Sun.COM 	if (client->remoteState == iscsiAuthRemoteStateAuthRequest) {
13017836SJohn.Forte@Sun.COM 		/*
13027836SJohn.Forte@Sun.COM 		 * Defer until authentication response received
13037836SJohn.Forte@Sun.COM 		 * from internal authentication service.
13047836SJohn.Forte@Sun.COM 		 */
13057836SJohn.Forte@Sun.COM 		return;
13067836SJohn.Forte@Sun.COM 	}
13077836SJohn.Forte@Sun.COM 
13087836SJohn.Forte@Sun.COM 	if (client->nodeType == iscsiAuthNodeTypeInitiator) {
13097836SJohn.Forte@Sun.COM 
13107836SJohn.Forte@Sun.COM 		/*
13117836SJohn.Forte@Sun.COM 		 * Target should only have set T bit on response if
13127836SJohn.Forte@Sun.COM 		 * initiator set it on previous message.
13137836SJohn.Forte@Sun.COM 		 */
13147836SJohn.Forte@Sun.COM 		if (client->recvKeyBlock.transitBit &&
13157836SJohn.Forte@Sun.COM 		    client->transitBitSentFlag == 0) {
13167836SJohn.Forte@Sun.COM 			client->remoteAuthStatus = iscsiAuthStatusFail;
13177836SJohn.Forte@Sun.COM 			client->phase = iscsiAuthPhaseDone;
13187836SJohn.Forte@Sun.COM 			client->debugStatus =
13197836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusTbitSetIllegal;
13207836SJohn.Forte@Sun.COM 			return;
13217836SJohn.Forte@Sun.COM 		}
13227836SJohn.Forte@Sun.COM 	}
13237836SJohn.Forte@Sun.COM 
13247836SJohn.Forte@Sun.COM 	if (client->phase == iscsiAuthPhaseNegotiate) {
13257836SJohn.Forte@Sun.COM 		/*
13267836SJohn.Forte@Sun.COM 		 * Should only happen if waiting for peer
13277836SJohn.Forte@Sun.COM 		 * to send AuthMethod key or set Transit Bit.
13287836SJohn.Forte@Sun.COM 		 */
13297836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeInitiator) {
13307836SJohn.Forte@Sun.COM 			client->sendKeyBlock.transitBit = TRUE;
13317836SJohn.Forte@Sun.COM 		}
13327836SJohn.Forte@Sun.COM 		return;
13337836SJohn.Forte@Sun.COM 	}
13347836SJohn.Forte@Sun.COM 
13357836SJohn.Forte@Sun.COM 	if (client->remoteState == iscsiAuthRemoteStateRecvResponse ||
13367836SJohn.Forte@Sun.COM 	    client->remoteState == iscsiAuthRemoteStateDone) {
13377836SJohn.Forte@Sun.COM 
13387836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeInitiator) {
13397836SJohn.Forte@Sun.COM 			if (client->recvKeyBlock.transitBit) {
13407836SJohn.Forte@Sun.COM 				if (client->remoteState !=
13417836SJohn.Forte@Sun.COM 				    iscsiAuthRemoteStateDone) {
13427836SJohn.Forte@Sun.COM 					goto recvTransitBitError;
13437836SJohn.Forte@Sun.COM 				}
13447836SJohn.Forte@Sun.COM 				iscsiAuthClientNextPhase(client);
13457836SJohn.Forte@Sun.COM 			} else {
13467836SJohn.Forte@Sun.COM 				client->sendKeyBlock.transitBit = TRUE;
13477836SJohn.Forte@Sun.COM 			}
13487836SJohn.Forte@Sun.COM 		} else {
13497836SJohn.Forte@Sun.COM 			if (client->remoteState == iscsiAuthRemoteStateDone &&
13507836SJohn.Forte@Sun.COM 			    client->remoteAuthStatus != iscsiAuthStatusPass) {
13517836SJohn.Forte@Sun.COM 
13527836SJohn.Forte@Sun.COM 				/*
13537836SJohn.Forte@Sun.COM 				 * Authentication failed, don't
13547836SJohn.Forte@Sun.COM 				 * do T bit handshake.
13557836SJohn.Forte@Sun.COM 				 */
13567836SJohn.Forte@Sun.COM 				iscsiAuthClientNextPhase(client);
13577836SJohn.Forte@Sun.COM 			} else {
13587836SJohn.Forte@Sun.COM 
13597836SJohn.Forte@Sun.COM 				/*
13607836SJohn.Forte@Sun.COM 				 * Target can only set T bit on response if
13617836SJohn.Forte@Sun.COM 				 * initiator set it on current message.
13627836SJohn.Forte@Sun.COM 				 */
13637836SJohn.Forte@Sun.COM 				if (client->recvKeyBlock.transitBit) {
13647836SJohn.Forte@Sun.COM 					client->sendKeyBlock.transitBit = TRUE;
13657836SJohn.Forte@Sun.COM 					iscsiAuthClientNextPhase(client);
13667836SJohn.Forte@Sun.COM 				}
13677836SJohn.Forte@Sun.COM 			}
13687836SJohn.Forte@Sun.COM 		}
13697836SJohn.Forte@Sun.COM 	} else {
13707836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeInitiator) {
13717836SJohn.Forte@Sun.COM 			if (client->recvKeyBlock.transitBit) {
13727836SJohn.Forte@Sun.COM 				goto recvTransitBitError;
13737836SJohn.Forte@Sun.COM 			}
13747836SJohn.Forte@Sun.COM 		}
13757836SJohn.Forte@Sun.COM 	}
13767836SJohn.Forte@Sun.COM 
13777836SJohn.Forte@Sun.COM 	return;
13787836SJohn.Forte@Sun.COM 
13797836SJohn.Forte@Sun.COM recvTransitBitError:
13807836SJohn.Forte@Sun.COM 	/*
13817836SJohn.Forte@Sun.COM 	 * Target set T bit on response but
13827836SJohn.Forte@Sun.COM 	 * initiator was not done with authentication.
13837836SJohn.Forte@Sun.COM 	 */
13847836SJohn.Forte@Sun.COM 	client->remoteAuthStatus = iscsiAuthStatusFail;
13857836SJohn.Forte@Sun.COM 	client->phase = iscsiAuthPhaseDone;
13867836SJohn.Forte@Sun.COM 	client->debugStatus = iscsiAuthDebugStatusTbitSetPremature;
13877836SJohn.Forte@Sun.COM }
13887836SJohn.Forte@Sun.COM 
13897836SJohn.Forte@Sun.COM 
13907836SJohn.Forte@Sun.COM static int
iscsiAuthClientRecvEndStatus(IscsiAuthClient * client)13917836SJohn.Forte@Sun.COM iscsiAuthClientRecvEndStatus(IscsiAuthClient * client)
13927836SJohn.Forte@Sun.COM {
13937836SJohn.Forte@Sun.COM 	int authStatus;
13947836SJohn.Forte@Sun.COM 	int keyType;
13957836SJohn.Forte@Sun.COM 
13967836SJohn.Forte@Sun.COM 	if (client->phase == iscsiAuthPhaseError) {
13977836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
13987836SJohn.Forte@Sun.COM 	}
13997836SJohn.Forte@Sun.COM 
14007836SJohn.Forte@Sun.COM 	if (client->phase == iscsiAuthPhaseDone) {
14017836SJohn.Forte@Sun.COM 
14027836SJohn.Forte@Sun.COM 		/*
14037836SJohn.Forte@Sun.COM 		 * Perform sanity check against configured parameters.
14047836SJohn.Forte@Sun.COM 		 */
14057836SJohn.Forte@Sun.COM 
14067836SJohn.Forte@Sun.COM 		if (client->authRemote && !client->authResponseFlag &&
14077836SJohn.Forte@Sun.COM 		    client->remoteAuthStatus == iscsiAuthStatusPass) {
14087836SJohn.Forte@Sun.COM 
14097836SJohn.Forte@Sun.COM 			client->remoteAuthStatus = iscsiAuthStatusFail;
14107836SJohn.Forte@Sun.COM 			client->debugStatus =
14117836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusAuthPassNotValid;
14127836SJohn.Forte@Sun.COM 		}
14137836SJohn.Forte@Sun.COM 
14147836SJohn.Forte@Sun.COM 		authStatus = client->remoteAuthStatus;
14157836SJohn.Forte@Sun.COM 	} else if (client->remoteState == iscsiAuthRemoteStateAuthRequest) {
14167836SJohn.Forte@Sun.COM 		authStatus = iscsiAuthStatusInProgress;
14177836SJohn.Forte@Sun.COM 	} else {
14187836SJohn.Forte@Sun.COM 		authStatus = iscsiAuthStatusContinue;
14197836SJohn.Forte@Sun.COM 	}
14207836SJohn.Forte@Sun.COM 
14217836SJohn.Forte@Sun.COM 	if (authStatus != iscsiAuthStatusInProgress) {
14227836SJohn.Forte@Sun.COM 		client->recvInProgressFlag = FALSE;
14237836SJohn.Forte@Sun.COM 	}
14247836SJohn.Forte@Sun.COM 
14257836SJohn.Forte@Sun.COM 	if (authStatus == iscsiAuthStatusContinue ||
14267836SJohn.Forte@Sun.COM 	    authStatus == iscsiAuthStatusPass) {
14277836SJohn.Forte@Sun.COM 		if (client->sendKeyBlock.duplicateSet) {
14287836SJohn.Forte@Sun.COM 			client->remoteAuthStatus = iscsiAuthStatusFail;
14297836SJohn.Forte@Sun.COM 			client->phase = iscsiAuthPhaseDone;
14307836SJohn.Forte@Sun.COM 			client->debugStatus =
14317836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusSendDuplicateSetKeyValue;
14327836SJohn.Forte@Sun.COM 			authStatus = iscsiAuthStatusFail;
14337836SJohn.Forte@Sun.COM 		} else if (client->sendKeyBlock.stringTooLong) {
14347836SJohn.Forte@Sun.COM 			client->remoteAuthStatus = iscsiAuthStatusFail;
14357836SJohn.Forte@Sun.COM 			client->phase = iscsiAuthPhaseDone;
14367836SJohn.Forte@Sun.COM 			client->debugStatus =
14377836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusSendStringTooLong;
14387836SJohn.Forte@Sun.COM 			authStatus = iscsiAuthStatusFail;
14397836SJohn.Forte@Sun.COM 		} else if (client->sendKeyBlock.tooMuchData) {
14407836SJohn.Forte@Sun.COM 			client->remoteAuthStatus = iscsiAuthStatusFail;
14417836SJohn.Forte@Sun.COM 			client->phase = iscsiAuthPhaseDone;
14427836SJohn.Forte@Sun.COM 			client->debugStatus =
14437836SJohn.Forte@Sun.COM 			    iscsiAuthDebugStatusSendTooMuchData;
14447836SJohn.Forte@Sun.COM 			authStatus = iscsiAuthStatusFail;
14457836SJohn.Forte@Sun.COM 		} else {
14467836SJohn.Forte@Sun.COM 			/*
14477836SJohn.Forte@Sun.COM 			 * Check that all incoming keys have been processed.
14487836SJohn.Forte@Sun.COM 			 */
14497836SJohn.Forte@Sun.COM 			for (keyType = iscsiAuthKeyTypeFirst;
14507836SJohn.Forte@Sun.COM 			    keyType < iscsiAuthKeyTypeMaxCount; keyType++) {
14517836SJohn.Forte@Sun.COM 				if (client->recvKeyBlock.key[keyType].present &&
14527836SJohn.Forte@Sun.COM 				    client->recvKeyBlock.key[keyType].
14537836SJohn.Forte@Sun.COM 				    processed == 0) {
14547836SJohn.Forte@Sun.COM 					break;
14557836SJohn.Forte@Sun.COM 				}
14567836SJohn.Forte@Sun.COM 			}
14577836SJohn.Forte@Sun.COM 
14587836SJohn.Forte@Sun.COM 			if (keyType < iscsiAuthKeyTypeMaxCount) {
14597836SJohn.Forte@Sun.COM 				client->remoteAuthStatus = iscsiAuthStatusFail;
14607836SJohn.Forte@Sun.COM 				client->phase = iscsiAuthPhaseDone;
14617836SJohn.Forte@Sun.COM 				client->debugStatus =
14627836SJohn.Forte@Sun.COM 				    iscsiAuthDebugStatusUnexpectedKeyPresent;
14637836SJohn.Forte@Sun.COM 				authStatus = iscsiAuthStatusFail;
14647836SJohn.Forte@Sun.COM 			}
14657836SJohn.Forte@Sun.COM 		}
14667836SJohn.Forte@Sun.COM 	}
14677836SJohn.Forte@Sun.COM 
14687836SJohn.Forte@Sun.COM 	if (authStatus != iscsiAuthStatusPass &&
14697836SJohn.Forte@Sun.COM 	    authStatus != iscsiAuthStatusContinue &&
14707836SJohn.Forte@Sun.COM 	    authStatus != iscsiAuthStatusInProgress) {
14717836SJohn.Forte@Sun.COM 		int authMethodKeyPresent = FALSE;
14727836SJohn.Forte@Sun.COM 		int chapAlgorithmKeyPresent = FALSE;
14737836SJohn.Forte@Sun.COM 
14747836SJohn.Forte@Sun.COM 		/*
14757836SJohn.Forte@Sun.COM 		 * Suppress send keys on error, except
14767836SJohn.Forte@Sun.COM 		 * for AuthMethod and CHAP_A.
14777836SJohn.Forte@Sun.COM 		 */
14787836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeTarget) {
14797836SJohn.Forte@Sun.COM 			if (iscsiAuthClientGetKeyValue(&client->sendKeyBlock,
14807836SJohn.Forte@Sun.COM 			    iscsiAuthKeyTypeAuthMethod)) {
14817836SJohn.Forte@Sun.COM 				authMethodKeyPresent = TRUE;
14827836SJohn.Forte@Sun.COM 			} else if (iscsiAuthClientGetKeyValue(
14837836SJohn.Forte@Sun.COM 			    &client->sendKeyBlock,
14847836SJohn.Forte@Sun.COM 			    iscsiAuthKeyTypeChapAlgorithm)) {
14857836SJohn.Forte@Sun.COM 				chapAlgorithmKeyPresent = TRUE;
14867836SJohn.Forte@Sun.COM 			}
14877836SJohn.Forte@Sun.COM 		}
14887836SJohn.Forte@Sun.COM 
14897836SJohn.Forte@Sun.COM 		iscsiAuthClientInitKeyBlock(&client->sendKeyBlock);
14907836SJohn.Forte@Sun.COM 
14917836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeTarget) {
14927836SJohn.Forte@Sun.COM 			if (authMethodKeyPresent &&
14937836SJohn.Forte@Sun.COM 			    client->negotiatedAuthMethod ==
14947836SJohn.Forte@Sun.COM 			    iscsiAuthOptionReject) {
14957836SJohn.Forte@Sun.COM 				iscsiAuthClientSetKeyValue(
14967836SJohn.Forte@Sun.COM 				    &client->sendKeyBlock,
14977836SJohn.Forte@Sun.COM 				    iscsiAuthKeyTypeAuthMethod,
14987836SJohn.Forte@Sun.COM 				    client->rejectOptionName);
14997836SJohn.Forte@Sun.COM 			} else if (chapAlgorithmKeyPresent &&
15007836SJohn.Forte@Sun.COM 			    client->negotiatedChapAlgorithm ==
15017836SJohn.Forte@Sun.COM 			    iscsiAuthOptionReject) {
15027836SJohn.Forte@Sun.COM 				iscsiAuthClientSetKeyValue(
15037836SJohn.Forte@Sun.COM 				    &client->sendKeyBlock,
15047836SJohn.Forte@Sun.COM 				    iscsiAuthKeyTypeChapAlgorithm,
15057836SJohn.Forte@Sun.COM 				    client->rejectOptionName);
15067836SJohn.Forte@Sun.COM 			}
15077836SJohn.Forte@Sun.COM 		}
15087836SJohn.Forte@Sun.COM 	}
15097836SJohn.Forte@Sun.COM 
15107836SJohn.Forte@Sun.COM 	return (authStatus);
15117836SJohn.Forte@Sun.COM }
15127836SJohn.Forte@Sun.COM 
15137836SJohn.Forte@Sun.COM 
15147836SJohn.Forte@Sun.COM int
iscsiAuthClientRecvBegin(IscsiAuthClient * client)15157836SJohn.Forte@Sun.COM iscsiAuthClientRecvBegin(IscsiAuthClient * client)
15167836SJohn.Forte@Sun.COM {
15177836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
15187836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
15197836SJohn.Forte@Sun.COM 	}
15207836SJohn.Forte@Sun.COM 
15217836SJohn.Forte@Sun.COM 	if (client->phase == iscsiAuthPhaseError) {
15227836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
15237836SJohn.Forte@Sun.COM 	}
15247836SJohn.Forte@Sun.COM 
15257836SJohn.Forte@Sun.COM 	if (client->phase == iscsiAuthPhaseDone) {
15267836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
15277836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
15287836SJohn.Forte@Sun.COM 	}
15297836SJohn.Forte@Sun.COM 
15307836SJohn.Forte@Sun.COM 	if (client->recvInProgressFlag) {
15317836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
15327836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
15337836SJohn.Forte@Sun.COM 	}
15347836SJohn.Forte@Sun.COM 
15357836SJohn.Forte@Sun.COM 	client->recvInProgressFlag = TRUE;
15367836SJohn.Forte@Sun.COM 
15377836SJohn.Forte@Sun.COM 	if (client->phase == iscsiAuthPhaseConfigure) {
15387836SJohn.Forte@Sun.COM 		iscsiAuthClientNextPhase(client);
15397836SJohn.Forte@Sun.COM 	}
15407836SJohn.Forte@Sun.COM 
15417836SJohn.Forte@Sun.COM 	client->transitBitSentFlag = client->sendKeyBlock.transitBit;
15427836SJohn.Forte@Sun.COM 
15437836SJohn.Forte@Sun.COM 	iscsiAuthClientInitKeyBlock(&client->recvKeyBlock);
15447836SJohn.Forte@Sun.COM 	iscsiAuthClientInitKeyBlock(&client->sendKeyBlock);
15457836SJohn.Forte@Sun.COM 
15467836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
15477836SJohn.Forte@Sun.COM }
15487836SJohn.Forte@Sun.COM 
15497836SJohn.Forte@Sun.COM 
15507836SJohn.Forte@Sun.COM int
iscsiAuthClientRecvEnd(IscsiAuthClient * client,IscsiAuthClientCallback * callback,void * userHandle,void * messageHandle)15517836SJohn.Forte@Sun.COM iscsiAuthClientRecvEnd(IscsiAuthClient * client,
15527836SJohn.Forte@Sun.COM     IscsiAuthClientCallback * callback, void *userHandle, void *messageHandle)
15537836SJohn.Forte@Sun.COM {
15547836SJohn.Forte@Sun.COM 	int nextPhaseFlag = FALSE;
15557836SJohn.Forte@Sun.COM 
15567836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
15577836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
15587836SJohn.Forte@Sun.COM 	}
15597836SJohn.Forte@Sun.COM 
15607836SJohn.Forte@Sun.COM 	if (client->phase == iscsiAuthPhaseError) {
15617836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
15627836SJohn.Forte@Sun.COM 	}
15637836SJohn.Forte@Sun.COM 
15647836SJohn.Forte@Sun.COM 	if (!callback || !client->recvInProgressFlag) {
15657836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
15667836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
15677836SJohn.Forte@Sun.COM 	}
15687836SJohn.Forte@Sun.COM 
15697836SJohn.Forte@Sun.COM 	if (client->recvEndCount > iscsiAuthRecvEndMaxCount) {
15707836SJohn.Forte@Sun.COM 		client->remoteAuthStatus = iscsiAuthStatusFail;
15717836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseDone;
15727836SJohn.Forte@Sun.COM 		client->debugStatus =
15737836SJohn.Forte@Sun.COM 		    iscsiAuthDebugStatusRecvMessageCountLimit;
15747836SJohn.Forte@Sun.COM 	} else if (client->recvKeyBlock.duplicateSet) {
15757836SJohn.Forte@Sun.COM 		client->remoteAuthStatus = iscsiAuthStatusFail;
15767836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseDone;
15777836SJohn.Forte@Sun.COM 		client->debugStatus =
15787836SJohn.Forte@Sun.COM 		    iscsiAuthDebugStatusRecvDuplicateSetKeyValue;
15797836SJohn.Forte@Sun.COM 	} else if (client->recvKeyBlock.stringTooLong) {
15807836SJohn.Forte@Sun.COM 		client->remoteAuthStatus = iscsiAuthStatusFail;
15817836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseDone;
15827836SJohn.Forte@Sun.COM 		client->debugStatus = iscsiAuthDebugStatusRecvStringTooLong;
15837836SJohn.Forte@Sun.COM 	} else if (client->recvKeyBlock.tooMuchData) {
15847836SJohn.Forte@Sun.COM 		client->remoteAuthStatus = iscsiAuthStatusFail;
15857836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseDone;
15867836SJohn.Forte@Sun.COM 		client->debugStatus = iscsiAuthDebugStatusRecvTooMuchData;
15877836SJohn.Forte@Sun.COM 	}
15887836SJohn.Forte@Sun.COM 
15897836SJohn.Forte@Sun.COM 	client->recvEndCount++;
15907836SJohn.Forte@Sun.COM 
15917836SJohn.Forte@Sun.COM 	client->callback = callback;
15927836SJohn.Forte@Sun.COM 	client->userHandle = userHandle;
15937836SJohn.Forte@Sun.COM 	client->messageHandle = messageHandle;
15947836SJohn.Forte@Sun.COM 
15957836SJohn.Forte@Sun.COM 	switch (client->phase) {
15967836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseNegotiate:
15977836SJohn.Forte@Sun.COM 		iscsiAuthClientCheckAuthMethodKey(client);
15987836SJohn.Forte@Sun.COM 
15997836SJohn.Forte@Sun.COM 		if (client->authMethodValidNegRole ==
16007836SJohn.Forte@Sun.COM 		    iscsiAuthNegRoleResponder) {
16017836SJohn.Forte@Sun.COM 			if (client->negotiatedAuthMethod ==
16027836SJohn.Forte@Sun.COM 			    iscsiAuthOptionNotPresent) {
16037836SJohn.Forte@Sun.COM 				if (client->authRemote ||
16047836SJohn.Forte@Sun.COM 				    client->recvKeyBlock.transitBit == 0) {
16057836SJohn.Forte@Sun.COM 					/*
16067836SJohn.Forte@Sun.COM 					 * No AuthMethod key from peer
16077836SJohn.Forte@Sun.COM 					 * on first message, try moving
16087836SJohn.Forte@Sun.COM 					 * the process along by sending
16097836SJohn.Forte@Sun.COM 					 * the AuthMethod key.
16107836SJohn.Forte@Sun.COM 					 */
16117836SJohn.Forte@Sun.COM 
16127836SJohn.Forte@Sun.COM 					client->authMethodValidNegRole =
16137836SJohn.Forte@Sun.COM 					    iscsiAuthNegRoleOriginator;
16147836SJohn.Forte@Sun.COM 
16157836SJohn.Forte@Sun.COM 					iscsiAuthClientSetAuthMethodKey(client,
16167836SJohn.Forte@Sun.COM 					    client->authMethodValidCount,
16177836SJohn.Forte@Sun.COM 					    client->authMethodValidList);
16187836SJohn.Forte@Sun.COM 					break;
16197836SJohn.Forte@Sun.COM 				}
16207836SJohn.Forte@Sun.COM 
16217836SJohn.Forte@Sun.COM 				/*
16227836SJohn.Forte@Sun.COM 				 * Special case if peer sent no
16237836SJohn.Forte@Sun.COM 				 * AuthMethod key, but did set Transit
16247836SJohn.Forte@Sun.COM 				 * Bit, allowing this side to do a
16257836SJohn.Forte@Sun.COM 				 * null authentication, and compelete
16267836SJohn.Forte@Sun.COM 				 * the iSCSI security phase without
16277836SJohn.Forte@Sun.COM 				 * either side sending the AuthMethod
16287836SJohn.Forte@Sun.COM 				 * key.
16297836SJohn.Forte@Sun.COM 				 */
16307836SJohn.Forte@Sun.COM 			} else {
16317836SJohn.Forte@Sun.COM 				/*
16327836SJohn.Forte@Sun.COM 				 * Send response to AuthMethod key.
16337836SJohn.Forte@Sun.COM 				 */
16347836SJohn.Forte@Sun.COM 
16357836SJohn.Forte@Sun.COM 				iscsiAuthClientSetAuthMethodKey(client, 1,
16367836SJohn.Forte@Sun.COM 				    &client->negotiatedAuthMethod);
16377836SJohn.Forte@Sun.COM 			}
16387836SJohn.Forte@Sun.COM 
16397836SJohn.Forte@Sun.COM 			if (client->nodeType == iscsiAuthNodeTypeInitiator) {
16407836SJohn.Forte@Sun.COM 				iscsiAuthClientNextPhase(client);
16417836SJohn.Forte@Sun.COM 			} else {
16427836SJohn.Forte@Sun.COM 				nextPhaseFlag = TRUE;
16437836SJohn.Forte@Sun.COM 			}
16447836SJohn.Forte@Sun.COM 
16457836SJohn.Forte@Sun.COM 		} else {
16467836SJohn.Forte@Sun.COM 			if (client->negotiatedAuthMethod ==
16477836SJohn.Forte@Sun.COM 			    iscsiAuthOptionNotPresent) {
16487836SJohn.Forte@Sun.COM 				client->remoteAuthStatus = iscsiAuthStatusFail;
16497836SJohn.Forte@Sun.COM 				client->phase = iscsiAuthPhaseDone;
16507836SJohn.Forte@Sun.COM 				client->debugStatus =
16517836SJohn.Forte@Sun.COM 				    iscsiAuthDebugStatusAuthMethodExpected;
16527836SJohn.Forte@Sun.COM 				break;
16537836SJohn.Forte@Sun.COM 			}
16547836SJohn.Forte@Sun.COM 
16557836SJohn.Forte@Sun.COM 			iscsiAuthClientNextPhase(client);
16567836SJohn.Forte@Sun.COM 		}
16577836SJohn.Forte@Sun.COM 		break;
16587836SJohn.Forte@Sun.COM 
16597836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseAuthenticate:
16607836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseDone:
16617836SJohn.Forte@Sun.COM 		break;
16627836SJohn.Forte@Sun.COM 
16637836SJohn.Forte@Sun.COM 	default:
16647836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
16657836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
16667836SJohn.Forte@Sun.COM 	}
16677836SJohn.Forte@Sun.COM 
16687836SJohn.Forte@Sun.COM 	switch (client->phase) {
16697836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseNegotiate:
16707836SJohn.Forte@Sun.COM 		if (nextPhaseFlag) {
16717836SJohn.Forte@Sun.COM 			iscsiAuthClientNextPhase(client);
16727836SJohn.Forte@Sun.COM 		}
16737836SJohn.Forte@Sun.COM 		break;
16747836SJohn.Forte@Sun.COM 
16757836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseAuthenticate:
16767836SJohn.Forte@Sun.COM 		/*
16777836SJohn.Forte@Sun.COM 		 * Must call iscsiAuthClientLocalAuthentication()
16787836SJohn.Forte@Sun.COM 		 * before iscsiAuthClientRemoteAuthentication()
16797836SJohn.Forte@Sun.COM 		 * to insure processing of the CHAP algorithm key,
16807836SJohn.Forte@Sun.COM 		 * and to avoid leaving an in progress request to the
16817836SJohn.Forte@Sun.COM 		 * authentication service.
16827836SJohn.Forte@Sun.COM 		 */
16837836SJohn.Forte@Sun.COM 		iscsiAuthClientLocalAuthentication(client);
16847836SJohn.Forte@Sun.COM 
16857836SJohn.Forte@Sun.COM 		if (client->localState != iscsiAuthLocalStateError) {
16867836SJohn.Forte@Sun.COM 			iscsiAuthClientRemoteAuthentication(client);
16877836SJohn.Forte@Sun.COM 		}
16887836SJohn.Forte@Sun.COM 
16897836SJohn.Forte@Sun.COM 		if (client->localState == iscsiAuthLocalStateError ||
16907836SJohn.Forte@Sun.COM 		    client->remoteState == iscsiAuthRemoteStateError) {
16917836SJohn.Forte@Sun.COM 
16927836SJohn.Forte@Sun.COM 			client->remoteAuthStatus = iscsiAuthStatusFail;
16937836SJohn.Forte@Sun.COM 			client->phase = iscsiAuthPhaseDone;
16947836SJohn.Forte@Sun.COM 			/*
16957836SJohn.Forte@Sun.COM 			 * client->debugStatus should already be set.
16967836SJohn.Forte@Sun.COM 			 */
16977836SJohn.Forte@Sun.COM 		}
16987836SJohn.Forte@Sun.COM 		break;
16997836SJohn.Forte@Sun.COM 
17007836SJohn.Forte@Sun.COM 	case iscsiAuthPhaseDone:
17017836SJohn.Forte@Sun.COM 		break;
17027836SJohn.Forte@Sun.COM 
17037836SJohn.Forte@Sun.COM 	default:
17047836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
17057836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
17067836SJohn.Forte@Sun.COM 	}
17077836SJohn.Forte@Sun.COM 
17087836SJohn.Forte@Sun.COM 	iscsiAuthClientHandshake(client);
17097836SJohn.Forte@Sun.COM 
17107836SJohn.Forte@Sun.COM 	return (iscsiAuthClientRecvEndStatus(client));
17117836SJohn.Forte@Sun.COM }
17127836SJohn.Forte@Sun.COM 
17137836SJohn.Forte@Sun.COM 
17147836SJohn.Forte@Sun.COM void
iscsiAuthClientAuthResponse(IscsiAuthClient * client,int authStatus)17157836SJohn.Forte@Sun.COM iscsiAuthClientAuthResponse(IscsiAuthClient * client, int authStatus)
17167836SJohn.Forte@Sun.COM {
17177836SJohn.Forte@Sun.COM 	iscsiAuthClientGlobalStats.responseReceived++;
17187836SJohn.Forte@Sun.COM 
17197836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
17207836SJohn.Forte@Sun.COM 		return;
17217836SJohn.Forte@Sun.COM 	}
17227836SJohn.Forte@Sun.COM 
17237836SJohn.Forte@Sun.COM 	if (!client->recvInProgressFlag ||
17247836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseAuthenticate ||
17257836SJohn.Forte@Sun.COM 	    client->remoteState != iscsiAuthRemoteStateAuthRequest) {
17267836SJohn.Forte@Sun.COM 
17277836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
17287836SJohn.Forte@Sun.COM 		return;
17297836SJohn.Forte@Sun.COM 	}
17307836SJohn.Forte@Sun.COM 
17317836SJohn.Forte@Sun.COM 	client->remoteAuthStatus = (IscsiAuthStatus) authStatus;
17327836SJohn.Forte@Sun.COM 	client->authResponseFlag = TRUE;
17337836SJohn.Forte@Sun.COM 
17347836SJohn.Forte@Sun.COM 	iscsiAuthClientRemoteAuthentication(client);
17357836SJohn.Forte@Sun.COM 
17367836SJohn.Forte@Sun.COM 	iscsiAuthClientHandshake(client);
17377836SJohn.Forte@Sun.COM 
17387836SJohn.Forte@Sun.COM 	authStatus = iscsiAuthClientRecvEndStatus(client);
17397836SJohn.Forte@Sun.COM 
17407836SJohn.Forte@Sun.COM 	client->callback(client->userHandle, client->messageHandle, authStatus);
17417836SJohn.Forte@Sun.COM }
17427836SJohn.Forte@Sun.COM 
17437836SJohn.Forte@Sun.COM 
17447836SJohn.Forte@Sun.COM const char *
iscsiAuthClientGetKeyName(int keyType)17457836SJohn.Forte@Sun.COM iscsiAuthClientGetKeyName(int keyType)
17467836SJohn.Forte@Sun.COM {
17477836SJohn.Forte@Sun.COM 	if (keyType < iscsiAuthKeyTypeFirst || keyType > iscsiAuthKeyTypeLast) {
17487836SJohn.Forte@Sun.COM 		return (0);
17497836SJohn.Forte@Sun.COM 	}
17507836SJohn.Forte@Sun.COM 	return (iscsiAuthClientKeyInfo[keyType].name);
17517836SJohn.Forte@Sun.COM }
17527836SJohn.Forte@Sun.COM 
17537836SJohn.Forte@Sun.COM 
17547836SJohn.Forte@Sun.COM int
iscsiAuthClientGetNextKeyType(int * pKeyType)17557836SJohn.Forte@Sun.COM iscsiAuthClientGetNextKeyType(int *pKeyType)
17567836SJohn.Forte@Sun.COM {
17577836SJohn.Forte@Sun.COM 	int keyType = *pKeyType;
17587836SJohn.Forte@Sun.COM 
17597836SJohn.Forte@Sun.COM 	if (keyType >= iscsiAuthKeyTypeLast) {
17607836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
17617836SJohn.Forte@Sun.COM 	}
17627836SJohn.Forte@Sun.COM 
17637836SJohn.Forte@Sun.COM 	if (keyType < iscsiAuthKeyTypeFirst) {
17647836SJohn.Forte@Sun.COM 		keyType = iscsiAuthKeyTypeFirst;
17657836SJohn.Forte@Sun.COM 	} else {
17667836SJohn.Forte@Sun.COM 		keyType++;
17677836SJohn.Forte@Sun.COM 	}
17687836SJohn.Forte@Sun.COM 
17697836SJohn.Forte@Sun.COM 	*pKeyType = keyType;
17707836SJohn.Forte@Sun.COM 
17717836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
17727836SJohn.Forte@Sun.COM }
17737836SJohn.Forte@Sun.COM 
17747836SJohn.Forte@Sun.COM 
17757836SJohn.Forte@Sun.COM int
iscsiAuthClientKeyNameToKeyType(const char * keyName)17767836SJohn.Forte@Sun.COM iscsiAuthClientKeyNameToKeyType(const char *keyName)
17777836SJohn.Forte@Sun.COM {
17787836SJohn.Forte@Sun.COM 	int keyType = iscsiAuthKeyTypeNone;
17797836SJohn.Forte@Sun.COM 
17807836SJohn.Forte@Sun.COM 	while (iscsiAuthClientGetNextKeyType(&keyType) ==
17817836SJohn.Forte@Sun.COM 	    iscsiAuthStatusNoError) {
17827836SJohn.Forte@Sun.COM 		const char *keyName2 = iscsiAuthClientGetKeyName(keyType);
17837836SJohn.Forte@Sun.COM 
17847836SJohn.Forte@Sun.COM 		if (!keyName2) {
17857836SJohn.Forte@Sun.COM 			return (iscsiAuthKeyTypeNone);
17867836SJohn.Forte@Sun.COM 		}
17877836SJohn.Forte@Sun.COM 
17887836SJohn.Forte@Sun.COM 		if (strcmp(keyName, keyName2) == 0) {
17897836SJohn.Forte@Sun.COM 			return (keyType);
17907836SJohn.Forte@Sun.COM 		}
17917836SJohn.Forte@Sun.COM 	}
17927836SJohn.Forte@Sun.COM 
17937836SJohn.Forte@Sun.COM 	return (iscsiAuthKeyTypeNone);
17947836SJohn.Forte@Sun.COM }
17957836SJohn.Forte@Sun.COM 
17967836SJohn.Forte@Sun.COM 
17977836SJohn.Forte@Sun.COM int
iscsiAuthClientRecvKeyValue(IscsiAuthClient * client,int keyType,const char * userKeyValue)17987836SJohn.Forte@Sun.COM iscsiAuthClientRecvKeyValue(IscsiAuthClient * client, int keyType,
17997836SJohn.Forte@Sun.COM     const char *userKeyValue)
18007836SJohn.Forte@Sun.COM {
18017836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
18027836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
18037836SJohn.Forte@Sun.COM 	}
18047836SJohn.Forte@Sun.COM 
18057836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseNegotiate &&
18067836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseAuthenticate) {
18077836SJohn.Forte@Sun.COM 
18087836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
18097836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
18107836SJohn.Forte@Sun.COM 	}
18117836SJohn.Forte@Sun.COM 
18127836SJohn.Forte@Sun.COM 	if (keyType < iscsiAuthKeyTypeFirst || keyType > iscsiAuthKeyTypeLast) {
18137836SJohn.Forte@Sun.COM 
18147836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
18157836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
18167836SJohn.Forte@Sun.COM 	}
18177836SJohn.Forte@Sun.COM 
18187836SJohn.Forte@Sun.COM 	if (keyType == iscsiAuthKeyTypeChapChallenge) {
18197836SJohn.Forte@Sun.COM 		client->recvChapChallenge.length =
18207836SJohn.Forte@Sun.COM 		    iscsiAuthLargeBinaryMaxLength;
18217836SJohn.Forte@Sun.COM 		client->recvChapChallengeStatus =
18227836SJohn.Forte@Sun.COM 		    iscsiAuthClientTextToData(userKeyValue,
18237836SJohn.Forte@Sun.COM 		    client->recvChapChallenge.largeBinary,
18247836SJohn.Forte@Sun.COM 		    &client->recvChapChallenge.length);
18257836SJohn.Forte@Sun.COM 		userKeyValue = "";
18267836SJohn.Forte@Sun.COM 	}
18277836SJohn.Forte@Sun.COM 
18287836SJohn.Forte@Sun.COM 	iscsiAuthClientSetKeyValue(&client->recvKeyBlock,
18297836SJohn.Forte@Sun.COM 	    keyType, userKeyValue);
18307836SJohn.Forte@Sun.COM 
18317836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
18327836SJohn.Forte@Sun.COM }
18337836SJohn.Forte@Sun.COM 
18347836SJohn.Forte@Sun.COM 
18357836SJohn.Forte@Sun.COM int
iscsiAuthClientSendKeyValue(IscsiAuthClient * client,int keyType,int * keyPresent,char * userKeyValue,unsigned int maxLength)18367836SJohn.Forte@Sun.COM iscsiAuthClientSendKeyValue(IscsiAuthClient * client, int keyType,
18377836SJohn.Forte@Sun.COM     int *keyPresent, char *userKeyValue, unsigned int maxLength)
18387836SJohn.Forte@Sun.COM {
18397836SJohn.Forte@Sun.COM 	const char *keyValue;
18407836SJohn.Forte@Sun.COM 
18417836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
18427836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
18437836SJohn.Forte@Sun.COM 	}
18447836SJohn.Forte@Sun.COM 
18457836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure &&
18467836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseNegotiate &&
18477836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseAuthenticate &&
18487836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseDone) {
18497836SJohn.Forte@Sun.COM 
18507836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
18517836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
18527836SJohn.Forte@Sun.COM 	}
18537836SJohn.Forte@Sun.COM 
18547836SJohn.Forte@Sun.COM 	if (keyType < iscsiAuthKeyTypeFirst || keyType > iscsiAuthKeyTypeLast) {
18557836SJohn.Forte@Sun.COM 
18567836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
18577836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
18587836SJohn.Forte@Sun.COM 	}
18597836SJohn.Forte@Sun.COM 
18607836SJohn.Forte@Sun.COM 	keyValue = iscsiAuthClientGetKeyValue(&client->sendKeyBlock, keyType);
18617836SJohn.Forte@Sun.COM 	if (keyValue) {
18627836SJohn.Forte@Sun.COM 		if (keyType == iscsiAuthKeyTypeChapChallenge) {
18637836SJohn.Forte@Sun.COM 			if (iscsiAuthClientDataToText(client->base64,
18647836SJohn.Forte@Sun.COM 			    client->sendChapChallenge.largeBinary,
18657836SJohn.Forte@Sun.COM 			    client->sendChapChallenge.length,
18667836SJohn.Forte@Sun.COM 			    userKeyValue, maxLength)) {
18677836SJohn.Forte@Sun.COM 				client->phase = iscsiAuthPhaseError;
18687836SJohn.Forte@Sun.COM 				return (iscsiAuthStatusError);
18697836SJohn.Forte@Sun.COM 			}
18707836SJohn.Forte@Sun.COM 		} else {
18717836SJohn.Forte@Sun.COM 			if (iscsiAuthClientStringCopy(userKeyValue,
18727836SJohn.Forte@Sun.COM 			    keyValue, maxLength)) {
18737836SJohn.Forte@Sun.COM 				client->phase = iscsiAuthPhaseError;
18747836SJohn.Forte@Sun.COM 				return (iscsiAuthStatusError);
18757836SJohn.Forte@Sun.COM 			}
18767836SJohn.Forte@Sun.COM 		}
18777836SJohn.Forte@Sun.COM 		*keyPresent = TRUE;
18787836SJohn.Forte@Sun.COM 	} else {
18797836SJohn.Forte@Sun.COM 		*keyPresent = FALSE;
18807836SJohn.Forte@Sun.COM 	}
18817836SJohn.Forte@Sun.COM 
18827836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
18837836SJohn.Forte@Sun.COM }
18847836SJohn.Forte@Sun.COM 
18857836SJohn.Forte@Sun.COM 
18867836SJohn.Forte@Sun.COM int
iscsiAuthClientRecvTransitBit(IscsiAuthClient * client,int value)18877836SJohn.Forte@Sun.COM iscsiAuthClientRecvTransitBit(IscsiAuthClient * client, int value)
18887836SJohn.Forte@Sun.COM {
18897836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
18907836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
18917836SJohn.Forte@Sun.COM 	}
18927836SJohn.Forte@Sun.COM 
18937836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseNegotiate &&
18947836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseAuthenticate) {
18957836SJohn.Forte@Sun.COM 
18967836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
18977836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
18987836SJohn.Forte@Sun.COM 	}
18997836SJohn.Forte@Sun.COM 
19007836SJohn.Forte@Sun.COM 	if (value) {
19017836SJohn.Forte@Sun.COM 		client->recvKeyBlock.transitBit = TRUE;
19027836SJohn.Forte@Sun.COM 	} else {
19037836SJohn.Forte@Sun.COM 		client->recvKeyBlock.transitBit = FALSE;
19047836SJohn.Forte@Sun.COM 	}
19057836SJohn.Forte@Sun.COM 
19067836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
19077836SJohn.Forte@Sun.COM }
19087836SJohn.Forte@Sun.COM 
19097836SJohn.Forte@Sun.COM 
19107836SJohn.Forte@Sun.COM int
iscsiAuthClientSendTransitBit(IscsiAuthClient * client,int * value)19117836SJohn.Forte@Sun.COM iscsiAuthClientSendTransitBit(IscsiAuthClient * client, int *value)
19127836SJohn.Forte@Sun.COM {
19137836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
19147836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
19157836SJohn.Forte@Sun.COM 	}
19167836SJohn.Forte@Sun.COM 
19177836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure &&
19187836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseNegotiate &&
19197836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseAuthenticate &&
19207836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseDone) {
19217836SJohn.Forte@Sun.COM 
19227836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
19237836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
19247836SJohn.Forte@Sun.COM 	}
19257836SJohn.Forte@Sun.COM 
19267836SJohn.Forte@Sun.COM 	*value = client->sendKeyBlock.transitBit;
19277836SJohn.Forte@Sun.COM 
19287836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
19297836SJohn.Forte@Sun.COM }
19307836SJohn.Forte@Sun.COM 
19317836SJohn.Forte@Sun.COM 
19327836SJohn.Forte@Sun.COM int
iscsiAuthClientInit(int nodeType,int bufferDescCount,IscsiAuthBufferDesc * bufferDesc)19337836SJohn.Forte@Sun.COM iscsiAuthClientInit(int nodeType, int bufferDescCount,
19347836SJohn.Forte@Sun.COM     IscsiAuthBufferDesc * bufferDesc)
19357836SJohn.Forte@Sun.COM {
19367836SJohn.Forte@Sun.COM 	IscsiAuthClient *client;
19377836SJohn.Forte@Sun.COM 	IscsiAuthStringBlock *recvStringBlock;
19387836SJohn.Forte@Sun.COM 	IscsiAuthStringBlock *sendStringBlock;
19397836SJohn.Forte@Sun.COM 	IscsiAuthLargeBinary *recvChapChallenge;
19407836SJohn.Forte@Sun.COM 	IscsiAuthLargeBinary *sendChapChallenge;
19417836SJohn.Forte@Sun.COM 	int valueList[2];
19427836SJohn.Forte@Sun.COM 
19437836SJohn.Forte@Sun.COM 	if (bufferDescCount != 5 ||
19447836SJohn.Forte@Sun.COM 	    bufferDesc == 0) {
19457836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
19467836SJohn.Forte@Sun.COM 	}
19477836SJohn.Forte@Sun.COM 
19487836SJohn.Forte@Sun.COM 	if (!bufferDesc[0].address ||
19497836SJohn.Forte@Sun.COM 	    bufferDesc[0].length != sizeof (*client)) {
19507836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
19517836SJohn.Forte@Sun.COM 	}
19527836SJohn.Forte@Sun.COM 	client = (IscsiAuthClient *) bufferDesc[0].address;
19537836SJohn.Forte@Sun.COM 
19547836SJohn.Forte@Sun.COM 	if (bufferDesc[1].address == 0 ||
19557836SJohn.Forte@Sun.COM 	    bufferDesc[1].length != sizeof (*recvStringBlock)) {
19567836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
19577836SJohn.Forte@Sun.COM 	}
19587836SJohn.Forte@Sun.COM 	recvStringBlock = (IscsiAuthStringBlock *) bufferDesc[1].address;
19597836SJohn.Forte@Sun.COM 
19607836SJohn.Forte@Sun.COM 	if (bufferDesc[2].address == 0 ||
19617836SJohn.Forte@Sun.COM 	    bufferDesc[2].length != sizeof (*sendStringBlock)) {
19627836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
19637836SJohn.Forte@Sun.COM 	}
19647836SJohn.Forte@Sun.COM 	sendStringBlock = (IscsiAuthStringBlock *) bufferDesc[2].address;
19657836SJohn.Forte@Sun.COM 
19667836SJohn.Forte@Sun.COM 	if (bufferDesc[3].address == 0 ||
19677836SJohn.Forte@Sun.COM 	    bufferDesc[3].length != sizeof (*recvChapChallenge)) {
19687836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
19697836SJohn.Forte@Sun.COM 	}
19707836SJohn.Forte@Sun.COM 	recvChapChallenge = (IscsiAuthLargeBinary *) bufferDesc[3].address;
19717836SJohn.Forte@Sun.COM 
19727836SJohn.Forte@Sun.COM 	if (bufferDesc[4].address == 0 ||
19737836SJohn.Forte@Sun.COM 	    bufferDesc[4].length != sizeof (*sendChapChallenge)) {
19747836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
19757836SJohn.Forte@Sun.COM 	}
19767836SJohn.Forte@Sun.COM 	sendChapChallenge = (IscsiAuthLargeBinary *) bufferDesc[4].address;
19777836SJohn.Forte@Sun.COM 
19787836SJohn.Forte@Sun.COM 	bzero(client, sizeof (*client));
19797836SJohn.Forte@Sun.COM 	bzero(recvStringBlock, sizeof (*recvStringBlock));
19807836SJohn.Forte@Sun.COM 	bzero(sendStringBlock, sizeof (*sendStringBlock));
19817836SJohn.Forte@Sun.COM 	bzero(recvChapChallenge, sizeof (*recvChapChallenge));
19827836SJohn.Forte@Sun.COM 	bzero(sendChapChallenge, sizeof (*sendChapChallenge));
19837836SJohn.Forte@Sun.COM 
19847836SJohn.Forte@Sun.COM 	client->recvKeyBlock.stringBlock = recvStringBlock->stringBlock;
19857836SJohn.Forte@Sun.COM 	client->sendKeyBlock.stringBlock = sendStringBlock->stringBlock;
19867836SJohn.Forte@Sun.COM 	client->recvChapChallenge.largeBinary = recvChapChallenge->largeBinary;
19877836SJohn.Forte@Sun.COM 	client->sendChapChallenge.largeBinary = sendChapChallenge->largeBinary;
19887836SJohn.Forte@Sun.COM 
19897836SJohn.Forte@Sun.COM 	if (iscsiAuthClientCheckNodeType(nodeType)) {
19907836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
19917836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
19927836SJohn.Forte@Sun.COM 	}
19937836SJohn.Forte@Sun.COM 
19947836SJohn.Forte@Sun.COM 	client->signature = iscsiAuthClientSignature;
19957836SJohn.Forte@Sun.COM 	client->nodeType = (IscsiAuthNodeType) nodeType;
19967836SJohn.Forte@Sun.COM 	/* Assume bi-directional authentication enabled. */
19977836SJohn.Forte@Sun.COM 	client->authRemote = TRUE;
19987836SJohn.Forte@Sun.COM 	client->passwordPresent = FALSE;
19997836SJohn.Forte@Sun.COM 	client->version = iscsiAuthVersionRfc;
20007836SJohn.Forte@Sun.COM 	client->chapChallengeLength = iscsiAuthChapResponseLength;
20017836SJohn.Forte@Sun.COM 	client->ipSec = TRUE;
20027836SJohn.Forte@Sun.COM 	client->base64 = FALSE;
20037836SJohn.Forte@Sun.COM 
20047836SJohn.Forte@Sun.COM 	client->phase = iscsiAuthPhaseConfigure;
20057836SJohn.Forte@Sun.COM 	client->negotiatedAuthMethod = iscsiAuthOptionNotPresent;
20067836SJohn.Forte@Sun.COM 	client->negotiatedChapAlgorithm = iscsiAuthOptionNotPresent;
20077836SJohn.Forte@Sun.COM 
20087836SJohn.Forte@Sun.COM 	if (client->nodeType == iscsiAuthNodeTypeInitiator) {
20097836SJohn.Forte@Sun.COM 		client->authMethodNegRole = iscsiAuthNegRoleOriginator;
20107836SJohn.Forte@Sun.COM 	} else {
20117836SJohn.Forte@Sun.COM 		/*
20127836SJohn.Forte@Sun.COM 		 * Initial value ignored for Target.
20137836SJohn.Forte@Sun.COM 		 */
20147836SJohn.Forte@Sun.COM 		client->authMethodNegRole = iscsiAuthNegRoleResponder;
20157836SJohn.Forte@Sun.COM 	}
20167836SJohn.Forte@Sun.COM 
20177836SJohn.Forte@Sun.COM 	/* All supported authentication methods */
20187836SJohn.Forte@Sun.COM 	valueList[0] = iscsiAuthMethodChap;
20197836SJohn.Forte@Sun.COM 	valueList[1] = iscsiAuthOptionNone;
20207836SJohn.Forte@Sun.COM 
20217836SJohn.Forte@Sun.COM 	/*
20227836SJohn.Forte@Sun.COM 	 * Must call after setting authRemote, password,
20237836SJohn.Forte@Sun.COM 	 * version and authMethodNegRole
20247836SJohn.Forte@Sun.COM 	 */
20257836SJohn.Forte@Sun.COM 	if (iscsiAuthClientSetAuthMethodList(client, 2, valueList) !=
20267836SJohn.Forte@Sun.COM 	    iscsiAuthStatusNoError) {
20277836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
20287836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
20297836SJohn.Forte@Sun.COM 	}
20307836SJohn.Forte@Sun.COM 
20317836SJohn.Forte@Sun.COM 	valueList[0] = iscsiAuthChapAlgorithmMd5;
20327836SJohn.Forte@Sun.COM 
20337836SJohn.Forte@Sun.COM 	if (iscsiAuthClientSetChapAlgorithmList(client, 1, valueList) !=
20347836SJohn.Forte@Sun.COM 	    iscsiAuthStatusNoError) {
20357836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
20367836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
20377836SJohn.Forte@Sun.COM 	}
20387836SJohn.Forte@Sun.COM 
20397836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
20407836SJohn.Forte@Sun.COM }
20417836SJohn.Forte@Sun.COM 
20427836SJohn.Forte@Sun.COM 
20437836SJohn.Forte@Sun.COM int
iscsiAuthClientFinish(IscsiAuthClient * client)20447836SJohn.Forte@Sun.COM iscsiAuthClientFinish(IscsiAuthClient * client)
20457836SJohn.Forte@Sun.COM {
20467836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
20477836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
20487836SJohn.Forte@Sun.COM 	}
20497836SJohn.Forte@Sun.COM 
20507836SJohn.Forte@Sun.COM 	iscsiAuthClientChapAuthCancel(client);
20517836SJohn.Forte@Sun.COM 
20527836SJohn.Forte@Sun.COM 	bzero(client, sizeof (*client));
20537836SJohn.Forte@Sun.COM 
20547836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
20557836SJohn.Forte@Sun.COM }
20567836SJohn.Forte@Sun.COM 
20577836SJohn.Forte@Sun.COM 
20587836SJohn.Forte@Sun.COM static int
iscsiAuthClientSetOptionList(IscsiAuthClient * client,unsigned int optionCount,const int * optionList,unsigned int * clientOptionCount,int * clientOptionList,unsigned int optionMaxCount,int (* checkOption)(int),int (* checkList)(unsigned int optionCount,const int * optionList))20597836SJohn.Forte@Sun.COM iscsiAuthClientSetOptionList(IscsiAuthClient * client,
20607836SJohn.Forte@Sun.COM     unsigned int optionCount,
20617836SJohn.Forte@Sun.COM     const int *optionList,
20627836SJohn.Forte@Sun.COM     unsigned int *clientOptionCount,
20637836SJohn.Forte@Sun.COM     int *clientOptionList,
20647836SJohn.Forte@Sun.COM     unsigned int optionMaxCount,
20657836SJohn.Forte@Sun.COM     int (*checkOption) (int),
20667836SJohn.Forte@Sun.COM     int (*checkList) (unsigned int optionCount, const int *optionList))
20677836SJohn.Forte@Sun.COM {
20687836SJohn.Forte@Sun.COM 	unsigned int i;
20697836SJohn.Forte@Sun.COM 	unsigned int j;
20707836SJohn.Forte@Sun.COM 
20717836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
20727836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
20737836SJohn.Forte@Sun.COM 	}
20747836SJohn.Forte@Sun.COM 
20757836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure ||
20767836SJohn.Forte@Sun.COM 	    optionCount > optionMaxCount) {
20777836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
20787836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
20797836SJohn.Forte@Sun.COM 	}
20807836SJohn.Forte@Sun.COM 
20817836SJohn.Forte@Sun.COM 	for (i = 0; i < optionCount; i++) {
20827836SJohn.Forte@Sun.COM 		if ((*checkOption) (optionList[i])) {
20837836SJohn.Forte@Sun.COM 			client->phase = iscsiAuthPhaseError;
20847836SJohn.Forte@Sun.COM 			return (iscsiAuthStatusError);
20857836SJohn.Forte@Sun.COM 		}
20867836SJohn.Forte@Sun.COM 	}
20877836SJohn.Forte@Sun.COM 
20887836SJohn.Forte@Sun.COM 	/*
20897836SJohn.Forte@Sun.COM 	 * Check for duplicate entries.
20907836SJohn.Forte@Sun.COM 	 */
20917836SJohn.Forte@Sun.COM 	for (i = 0; i < optionCount; i++) {
20927836SJohn.Forte@Sun.COM 		for (j = 0; j < optionCount; j++) {
20937836SJohn.Forte@Sun.COM 			if (j == i)
20947836SJohn.Forte@Sun.COM 				continue;
20957836SJohn.Forte@Sun.COM 			if (optionList[i] == optionList[j]) {
20967836SJohn.Forte@Sun.COM 				client->phase = iscsiAuthPhaseError;
20977836SJohn.Forte@Sun.COM 				return (iscsiAuthStatusError);
20987836SJohn.Forte@Sun.COM 			}
20997836SJohn.Forte@Sun.COM 		}
21007836SJohn.Forte@Sun.COM 	}
21017836SJohn.Forte@Sun.COM 
21027836SJohn.Forte@Sun.COM 	/*
21037836SJohn.Forte@Sun.COM 	 * Check for key specific constraints.
21047836SJohn.Forte@Sun.COM 	 */
21057836SJohn.Forte@Sun.COM 	if (checkList) {
21067836SJohn.Forte@Sun.COM 		if ((*checkList) (optionCount, optionList)) {
21077836SJohn.Forte@Sun.COM 			client->phase = iscsiAuthPhaseError;
21087836SJohn.Forte@Sun.COM 			return (iscsiAuthStatusError);
21097836SJohn.Forte@Sun.COM 		}
21107836SJohn.Forte@Sun.COM 	}
21117836SJohn.Forte@Sun.COM 
21127836SJohn.Forte@Sun.COM 	for (i = 0; i < optionCount; i++) {
21137836SJohn.Forte@Sun.COM 		clientOptionList[i] = optionList[i];
21147836SJohn.Forte@Sun.COM 	}
21157836SJohn.Forte@Sun.COM 
21167836SJohn.Forte@Sun.COM 	*clientOptionCount = optionCount;
21177836SJohn.Forte@Sun.COM 
21187836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
21197836SJohn.Forte@Sun.COM }
21207836SJohn.Forte@Sun.COM 
21217836SJohn.Forte@Sun.COM 
21227836SJohn.Forte@Sun.COM static void
iscsiAuthClientSetAuthMethodValid(IscsiAuthClient * client)21237836SJohn.Forte@Sun.COM iscsiAuthClientSetAuthMethodValid(IscsiAuthClient * client)
21247836SJohn.Forte@Sun.COM {
21257836SJohn.Forte@Sun.COM 	static const char rejectOptionNameDraft8[] = "reject";
21267836SJohn.Forte@Sun.COM 	static const char rejectOptionNameRfc[] = "Reject";
21277836SJohn.Forte@Sun.COM 	static const char noneOptionNameDraft8[] = "none";
21287836SJohn.Forte@Sun.COM 	static const char noneOptionNameRfc[] = "None";
21297836SJohn.Forte@Sun.COM 	unsigned int i;
21307836SJohn.Forte@Sun.COM 	unsigned int j = 0;
21317836SJohn.Forte@Sun.COM 	int option = 0;
21327836SJohn.Forte@Sun.COM 
21337836SJohn.Forte@Sun.COM 	if (client->version == iscsiAuthVersionDraft8) {
21347836SJohn.Forte@Sun.COM 		client->rejectOptionName = rejectOptionNameDraft8;
21357836SJohn.Forte@Sun.COM 		client->noneOptionName = noneOptionNameDraft8;
21367836SJohn.Forte@Sun.COM 	} else {
21377836SJohn.Forte@Sun.COM 		client->rejectOptionName = rejectOptionNameRfc;
21387836SJohn.Forte@Sun.COM 		client->noneOptionName = noneOptionNameRfc;
21397836SJohn.Forte@Sun.COM 	}
21407836SJohn.Forte@Sun.COM 
21417836SJohn.Forte@Sun.COM 	/*
21427836SJohn.Forte@Sun.COM 	 * Following checks may need to be revised if
21437836SJohn.Forte@Sun.COM 	 * authentication options other than CHAP and none
21447836SJohn.Forte@Sun.COM 	 * are supported.
21457836SJohn.Forte@Sun.COM 	 */
21467836SJohn.Forte@Sun.COM 
21477836SJohn.Forte@Sun.COM 	if (client->nodeType == iscsiAuthNodeTypeInitiator) {
21487836SJohn.Forte@Sun.COM 
21497836SJohn.Forte@Sun.COM 		if (client->authRemote) {
21507836SJohn.Forte@Sun.COM 			/*
21517836SJohn.Forte@Sun.COM 			 * If initiator doing authentication,
21527836SJohn.Forte@Sun.COM 			 * don't offer authentication option none.
21537836SJohn.Forte@Sun.COM 			 */
21547836SJohn.Forte@Sun.COM 			option = 1;
21557836SJohn.Forte@Sun.COM 		} else if (!client->passwordPresent) {
21567836SJohn.Forte@Sun.COM 			/*
21577836SJohn.Forte@Sun.COM 			 * If initiator password not set,
21587836SJohn.Forte@Sun.COM 			 * only offer authentication option none.
21597836SJohn.Forte@Sun.COM 			 */
21607836SJohn.Forte@Sun.COM 			option = 2;
21617836SJohn.Forte@Sun.COM 		}
21627836SJohn.Forte@Sun.COM 	}
21637836SJohn.Forte@Sun.COM 
21647836SJohn.Forte@Sun.COM 	if (client->nodeType == iscsiAuthNodeTypeTarget) {
21657836SJohn.Forte@Sun.COM 
21667836SJohn.Forte@Sun.COM 		if (client->authRemote) {
21677836SJohn.Forte@Sun.COM 			/*
21687836SJohn.Forte@Sun.COM 			 * If target doing authentication,
21697836SJohn.Forte@Sun.COM 			 * don't accept authentication option none.
21707836SJohn.Forte@Sun.COM 			 */
21717836SJohn.Forte@Sun.COM 			option = 1;
21727836SJohn.Forte@Sun.COM 		} else {
21737836SJohn.Forte@Sun.COM 			/*
21747836SJohn.Forte@Sun.COM 			 * If target not doing authentication,
21757836SJohn.Forte@Sun.COM 			 * only accept authentication option none.
21767836SJohn.Forte@Sun.COM 			 */
21777836SJohn.Forte@Sun.COM 			option = 2;
21787836SJohn.Forte@Sun.COM 		}
21797836SJohn.Forte@Sun.COM 	}
21807836SJohn.Forte@Sun.COM 
21817836SJohn.Forte@Sun.COM 	for (i = 0; i < client->authMethodCount; i++) {
21827836SJohn.Forte@Sun.COM 
21837836SJohn.Forte@Sun.COM 		if (option == 1) {
21847836SJohn.Forte@Sun.COM 			if (client->authMethodList[i] == iscsiAuthOptionNone) {
21857836SJohn.Forte@Sun.COM 				continue;
21867836SJohn.Forte@Sun.COM 			}
21877836SJohn.Forte@Sun.COM 		} else if (option == 2) {
21887836SJohn.Forte@Sun.COM 			if (client->authMethodList[i] != iscsiAuthOptionNone) {
21897836SJohn.Forte@Sun.COM 				continue;
21907836SJohn.Forte@Sun.COM 			}
21917836SJohn.Forte@Sun.COM 		}
21927836SJohn.Forte@Sun.COM 
21937836SJohn.Forte@Sun.COM 		client->authMethodValidList[j++] = client->authMethodList[i];
21947836SJohn.Forte@Sun.COM 	}
21957836SJohn.Forte@Sun.COM 
21967836SJohn.Forte@Sun.COM 	client->authMethodValidCount = j;
21977836SJohn.Forte@Sun.COM 
21987836SJohn.Forte@Sun.COM 	iscsiAuthClientInitKeyBlock(&client->sendKeyBlock);
21997836SJohn.Forte@Sun.COM 
22007836SJohn.Forte@Sun.COM 	if (client->nodeType == iscsiAuthNodeTypeInitiator) {
22017836SJohn.Forte@Sun.COM 		if (client->authRemote) {
22027836SJohn.Forte@Sun.COM 			/*
22037836SJohn.Forte@Sun.COM 			 * Initiator wants to authenticate target,
22047836SJohn.Forte@Sun.COM 			 * always send AuthMethod key.
22057836SJohn.Forte@Sun.COM 			 */
22067836SJohn.Forte@Sun.COM 			client->sendKeyBlock.transitBit = FALSE;
22077836SJohn.Forte@Sun.COM 			client->authMethodValidNegRole =
22087836SJohn.Forte@Sun.COM 			    iscsiAuthNegRoleOriginator;
22097836SJohn.Forte@Sun.COM 		} else {
22107836SJohn.Forte@Sun.COM 			client->sendKeyBlock.transitBit = TRUE;
22117836SJohn.Forte@Sun.COM 			client->authMethodValidNegRole =
22127836SJohn.Forte@Sun.COM 			    client->authMethodNegRole;
22137836SJohn.Forte@Sun.COM 		}
22147836SJohn.Forte@Sun.COM 	} else {
22157836SJohn.Forte@Sun.COM 		client->sendKeyBlock.transitBit = FALSE;
22167836SJohn.Forte@Sun.COM 		client->authMethodValidNegRole = iscsiAuthNegRoleResponder;
22177836SJohn.Forte@Sun.COM 	}
22187836SJohn.Forte@Sun.COM 
22197836SJohn.Forte@Sun.COM 	if (client->authMethodValidNegRole == iscsiAuthNegRoleOriginator) {
22207836SJohn.Forte@Sun.COM 		iscsiAuthClientSetAuthMethodKey(client,
22217836SJohn.Forte@Sun.COM 		    client->authMethodValidCount,
22227836SJohn.Forte@Sun.COM 		    client->authMethodValidList);
22237836SJohn.Forte@Sun.COM 	} else {
22247836SJohn.Forte@Sun.COM 		int value = iscsiAuthOptionNotPresent;
22257836SJohn.Forte@Sun.COM 		iscsiAuthClientSetAuthMethodKey(client, 1, &value);
22267836SJohn.Forte@Sun.COM 	}
22277836SJohn.Forte@Sun.COM }
22287836SJohn.Forte@Sun.COM 
22297836SJohn.Forte@Sun.COM 
22307836SJohn.Forte@Sun.COM static int
iscsiAuthClientCheckAuthMethodList(unsigned int optionCount,const int * optionList)22317836SJohn.Forte@Sun.COM iscsiAuthClientCheckAuthMethodList(unsigned int optionCount,
22327836SJohn.Forte@Sun.COM     const int *optionList)
22337836SJohn.Forte@Sun.COM {
22347836SJohn.Forte@Sun.COM 	unsigned int i;
22357836SJohn.Forte@Sun.COM 
22367836SJohn.Forte@Sun.COM 	if (!optionList || optionCount < 2) {
22377836SJohn.Forte@Sun.COM 		return (TRUE);
22387836SJohn.Forte@Sun.COM 	}
22397836SJohn.Forte@Sun.COM 
22407836SJohn.Forte@Sun.COM 	if (optionList[optionCount - 1] != iscsiAuthOptionNone) {
22417836SJohn.Forte@Sun.COM 		return (TRUE);
22427836SJohn.Forte@Sun.COM 	}
22437836SJohn.Forte@Sun.COM 
22447836SJohn.Forte@Sun.COM 	for (i = 0; i < (optionCount - 1); i++) {
22457836SJohn.Forte@Sun.COM 		if (optionList[i] != iscsiAuthOptionNone) {
22467836SJohn.Forte@Sun.COM 			return (FALSE);
22477836SJohn.Forte@Sun.COM 		}
22487836SJohn.Forte@Sun.COM 	}
22497836SJohn.Forte@Sun.COM 
22507836SJohn.Forte@Sun.COM 	return (FALSE);
22517836SJohn.Forte@Sun.COM }
22527836SJohn.Forte@Sun.COM 
22537836SJohn.Forte@Sun.COM 
22547836SJohn.Forte@Sun.COM int
iscsiAuthClientSetAuthMethodList(IscsiAuthClient * client,unsigned int optionCount,const int * optionList)22557836SJohn.Forte@Sun.COM iscsiAuthClientSetAuthMethodList(IscsiAuthClient * client,
22567836SJohn.Forte@Sun.COM     unsigned int optionCount, const int *optionList)
22577836SJohn.Forte@Sun.COM {
22587836SJohn.Forte@Sun.COM 	int status;
22597836SJohn.Forte@Sun.COM 
22607836SJohn.Forte@Sun.COM 	status = iscsiAuthClientSetOptionList(
22617836SJohn.Forte@Sun.COM 	    client, optionCount, optionList, &client->authMethodCount,
22627836SJohn.Forte@Sun.COM 	    client->authMethodList, iscsiAuthMethodMaxCount,
22637836SJohn.Forte@Sun.COM 	    iscsiAuthClientCheckAuthMethodOption,
22647836SJohn.Forte@Sun.COM 	    iscsiAuthClientCheckAuthMethodList);
22657836SJohn.Forte@Sun.COM 
22667836SJohn.Forte@Sun.COM 	if (status != iscsiAuthStatusNoError) {
22677836SJohn.Forte@Sun.COM 		return (status);
22687836SJohn.Forte@Sun.COM 	}
22697836SJohn.Forte@Sun.COM 
22707836SJohn.Forte@Sun.COM 	/*
22717836SJohn.Forte@Sun.COM 	 * Setting authMethod affects authMethodValid.
22727836SJohn.Forte@Sun.COM 	 */
22737836SJohn.Forte@Sun.COM 	iscsiAuthClientSetAuthMethodValid(client);
22747836SJohn.Forte@Sun.COM 
22757836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
22767836SJohn.Forte@Sun.COM }
22777836SJohn.Forte@Sun.COM 
22787836SJohn.Forte@Sun.COM 
22797836SJohn.Forte@Sun.COM int
iscsiAuthClientSetAuthMethodNegRole(IscsiAuthClient * client,int negRole)22807836SJohn.Forte@Sun.COM iscsiAuthClientSetAuthMethodNegRole(IscsiAuthClient * client, int negRole)
22817836SJohn.Forte@Sun.COM {
22827836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
22837836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
22847836SJohn.Forte@Sun.COM 	}
22857836SJohn.Forte@Sun.COM 
22867836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure ||
22877836SJohn.Forte@Sun.COM 	    iscsiAuthClientCheckNegRole(negRole) ||
22887836SJohn.Forte@Sun.COM 	    client->nodeType != iscsiAuthNodeTypeInitiator) {
22897836SJohn.Forte@Sun.COM 
22907836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
22917836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
22927836SJohn.Forte@Sun.COM 	}
22937836SJohn.Forte@Sun.COM 
22947836SJohn.Forte@Sun.COM 	client->authMethodNegRole = (IscsiAuthNegRole) negRole;
22957836SJohn.Forte@Sun.COM 
22967836SJohn.Forte@Sun.COM 	/*
22977836SJohn.Forte@Sun.COM 	 * Setting negRole affects authMethodValid.
22987836SJohn.Forte@Sun.COM 	 */
22997836SJohn.Forte@Sun.COM 	iscsiAuthClientSetAuthMethodValid(client);
23007836SJohn.Forte@Sun.COM 
23017836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
23027836SJohn.Forte@Sun.COM }
23037836SJohn.Forte@Sun.COM 
23047836SJohn.Forte@Sun.COM 
23057836SJohn.Forte@Sun.COM static int
iscsiAuthClientCheckChapAlgorithmList(unsigned int optionCount,const int * optionList)23067836SJohn.Forte@Sun.COM iscsiAuthClientCheckChapAlgorithmList(unsigned int optionCount,
23077836SJohn.Forte@Sun.COM     const int *optionList)
23087836SJohn.Forte@Sun.COM {
23097836SJohn.Forte@Sun.COM 	if (!optionList || optionCount < 1) {
23107836SJohn.Forte@Sun.COM 		return (TRUE);
23117836SJohn.Forte@Sun.COM 	}
23127836SJohn.Forte@Sun.COM 
23137836SJohn.Forte@Sun.COM 	return (FALSE);
23147836SJohn.Forte@Sun.COM }
23157836SJohn.Forte@Sun.COM 
23167836SJohn.Forte@Sun.COM 
23177836SJohn.Forte@Sun.COM int
iscsiAuthClientSetChapAlgorithmList(IscsiAuthClient * client,unsigned int optionCount,const int * optionList)23187836SJohn.Forte@Sun.COM iscsiAuthClientSetChapAlgorithmList(IscsiAuthClient * client,
23197836SJohn.Forte@Sun.COM     unsigned int optionCount, const int *optionList)
23207836SJohn.Forte@Sun.COM {
23217836SJohn.Forte@Sun.COM 	return (iscsiAuthClientSetOptionList(client,
23227836SJohn.Forte@Sun.COM 	    optionCount,
23237836SJohn.Forte@Sun.COM 	    optionList,
23247836SJohn.Forte@Sun.COM 	    &client->chapAlgorithmCount,
23257836SJohn.Forte@Sun.COM 	    client->chapAlgorithmList,
23267836SJohn.Forte@Sun.COM 	    iscsiAuthChapAlgorithmMaxCount,
23277836SJohn.Forte@Sun.COM 	    iscsiAuthClientCheckChapAlgorithmOption,
23287836SJohn.Forte@Sun.COM 	    iscsiAuthClientCheckChapAlgorithmList));
23297836SJohn.Forte@Sun.COM }
23307836SJohn.Forte@Sun.COM 
23317836SJohn.Forte@Sun.COM 
23327836SJohn.Forte@Sun.COM int
iscsiAuthClientSetUsername(IscsiAuthClient * client,const char * username)23337836SJohn.Forte@Sun.COM iscsiAuthClientSetUsername(IscsiAuthClient * client, const char *username)
23347836SJohn.Forte@Sun.COM {
23357836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
23367836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
23377836SJohn.Forte@Sun.COM 	}
23387836SJohn.Forte@Sun.COM 
23397836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure ||
23407836SJohn.Forte@Sun.COM 	    iscsiAuthClientCheckString(username, iscsiAuthStringMaxLength, 0)) {
23417836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
23427836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
23437836SJohn.Forte@Sun.COM 	}
23447836SJohn.Forte@Sun.COM 
23457836SJohn.Forte@Sun.COM 	if (iscsiAuthClientStringCopy(client->username, username,
23467836SJohn.Forte@Sun.COM 	    iscsiAuthStringMaxLength)) {
23477836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
23487836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
23497836SJohn.Forte@Sun.COM 	}
23507836SJohn.Forte@Sun.COM 
23517836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
23527836SJohn.Forte@Sun.COM }
23537836SJohn.Forte@Sun.COM 
23547836SJohn.Forte@Sun.COM 
23557836SJohn.Forte@Sun.COM int
iscsiAuthClientSetPassword(IscsiAuthClient * client,const unsigned char * passwordData,unsigned int passwordLength)23567836SJohn.Forte@Sun.COM iscsiAuthClientSetPassword(IscsiAuthClient * client,
23577836SJohn.Forte@Sun.COM     const unsigned char *passwordData, unsigned int passwordLength)
23587836SJohn.Forte@Sun.COM {
23597836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
23607836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
23617836SJohn.Forte@Sun.COM 	}
23627836SJohn.Forte@Sun.COM 
23637836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure ||
23647836SJohn.Forte@Sun.COM 	    passwordLength > iscsiAuthStringMaxLength) {
23657836SJohn.Forte@Sun.COM 
23667836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
23677836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
23687836SJohn.Forte@Sun.COM 	}
23697836SJohn.Forte@Sun.COM 
23707836SJohn.Forte@Sun.COM 	bcopy(passwordData, client->passwordData, passwordLength);
23717836SJohn.Forte@Sun.COM 	client->passwordLength = passwordLength;
23727836SJohn.Forte@Sun.COM 	if (client->passwordLength > 0) {
23737836SJohn.Forte@Sun.COM 		client->passwordPresent = TRUE;
23747836SJohn.Forte@Sun.COM 	} else {
23757836SJohn.Forte@Sun.COM 		client->passwordPresent = FALSE;
23767836SJohn.Forte@Sun.COM 	}
23777836SJohn.Forte@Sun.COM 
23787836SJohn.Forte@Sun.COM 	/*
23797836SJohn.Forte@Sun.COM 	 * Setting password may affect authMethodValid.
23807836SJohn.Forte@Sun.COM 	 */
23817836SJohn.Forte@Sun.COM 	iscsiAuthClientSetAuthMethodValid(client);
23827836SJohn.Forte@Sun.COM 
23837836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
23847836SJohn.Forte@Sun.COM }
23857836SJohn.Forte@Sun.COM 
23867836SJohn.Forte@Sun.COM 
23877836SJohn.Forte@Sun.COM int
iscsiAuthClientSetAuthRemote(IscsiAuthClient * client,int authRemote)23887836SJohn.Forte@Sun.COM iscsiAuthClientSetAuthRemote(IscsiAuthClient * client, int authRemote)
23897836SJohn.Forte@Sun.COM {
23907836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
23917836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
23927836SJohn.Forte@Sun.COM 	}
23937836SJohn.Forte@Sun.COM 
23947836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure) {
23957836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
23967836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
23977836SJohn.Forte@Sun.COM 	}
23987836SJohn.Forte@Sun.COM 
23997836SJohn.Forte@Sun.COM 	client->authRemote = authRemote;
24007836SJohn.Forte@Sun.COM 
24017836SJohn.Forte@Sun.COM 	/*
24027836SJohn.Forte@Sun.COM 	 * Setting authRemote may affect authMethodValid.
24037836SJohn.Forte@Sun.COM 	 */
24047836SJohn.Forte@Sun.COM 	iscsiAuthClientSetAuthMethodValid(client);
24057836SJohn.Forte@Sun.COM 
24067836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
24077836SJohn.Forte@Sun.COM }
24087836SJohn.Forte@Sun.COM 
24097836SJohn.Forte@Sun.COM 
24107836SJohn.Forte@Sun.COM int
iscsiAuthClientSetGlueHandle(IscsiAuthClient * client,void * glueHandle)24117836SJohn.Forte@Sun.COM iscsiAuthClientSetGlueHandle(IscsiAuthClient * client, void *glueHandle)
24127836SJohn.Forte@Sun.COM {
24137836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
24147836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
24157836SJohn.Forte@Sun.COM 	}
24167836SJohn.Forte@Sun.COM 
24177836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure &&
24187836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseNegotiate &&
24197836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseAuthenticate) {
24207836SJohn.Forte@Sun.COM 
24217836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
24227836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
24237836SJohn.Forte@Sun.COM 	}
24247836SJohn.Forte@Sun.COM 
24257836SJohn.Forte@Sun.COM 	client->glueHandle = glueHandle;
24267836SJohn.Forte@Sun.COM 
24277836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
24287836SJohn.Forte@Sun.COM }
24297836SJohn.Forte@Sun.COM 
24307836SJohn.Forte@Sun.COM 
24317836SJohn.Forte@Sun.COM int
iscsiAuthClientSetMethodListName(IscsiAuthClient * client,const char * methodListName)24327836SJohn.Forte@Sun.COM iscsiAuthClientSetMethodListName(IscsiAuthClient *client,
24337836SJohn.Forte@Sun.COM     const char *methodListName)
24347836SJohn.Forte@Sun.COM {
24357836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
24367836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
24377836SJohn.Forte@Sun.COM 	}
24387836SJohn.Forte@Sun.COM 
24397836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure ||
24407836SJohn.Forte@Sun.COM 	    iscsiAuthClientCheckString(methodListName,
24417836SJohn.Forte@Sun.COM 	    iscsiAuthStringMaxLength, 0)) {
24427836SJohn.Forte@Sun.COM 
24437836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
24447836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
24457836SJohn.Forte@Sun.COM 	}
24467836SJohn.Forte@Sun.COM 
24477836SJohn.Forte@Sun.COM 	if (iscsiAuthClientStringCopy(client->methodListName, methodListName,
24487836SJohn.Forte@Sun.COM 	    iscsiAuthStringMaxLength)) {
24497836SJohn.Forte@Sun.COM 
24507836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
24517836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
24527836SJohn.Forte@Sun.COM 	}
24537836SJohn.Forte@Sun.COM 
24547836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
24557836SJohn.Forte@Sun.COM }
24567836SJohn.Forte@Sun.COM 
24577836SJohn.Forte@Sun.COM 
24587836SJohn.Forte@Sun.COM int
iscsiAuthClientSetVersion(IscsiAuthClient * client,int version)24597836SJohn.Forte@Sun.COM iscsiAuthClientSetVersion(IscsiAuthClient * client, int version)
24607836SJohn.Forte@Sun.COM {
24617836SJohn.Forte@Sun.COM 	if (client == 0 ||
24627836SJohn.Forte@Sun.COM 	    client->signature != iscsiAuthClientSignature) {
24637836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
24647836SJohn.Forte@Sun.COM 	}
24657836SJohn.Forte@Sun.COM 
24667836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure ||
24677836SJohn.Forte@Sun.COM 	    iscsiAuthClientCheckVersion(version)) {
24687836SJohn.Forte@Sun.COM 
24697836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
24707836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
24717836SJohn.Forte@Sun.COM 	}
24727836SJohn.Forte@Sun.COM 
24737836SJohn.Forte@Sun.COM 	client->version = (IscsiAuthVersion) version;
24747836SJohn.Forte@Sun.COM 
24757836SJohn.Forte@Sun.COM 	iscsiAuthClientSetAuthMethodValid(client);
24767836SJohn.Forte@Sun.COM 
24777836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
24787836SJohn.Forte@Sun.COM }
24797836SJohn.Forte@Sun.COM 
24807836SJohn.Forte@Sun.COM 
24817836SJohn.Forte@Sun.COM int
iscsiAuthClientSetIpSec(IscsiAuthClient * client,int ipSec)24827836SJohn.Forte@Sun.COM iscsiAuthClientSetIpSec(IscsiAuthClient * client, int ipSec)
24837836SJohn.Forte@Sun.COM {
24847836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
24857836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
24867836SJohn.Forte@Sun.COM 	}
24877836SJohn.Forte@Sun.COM 
24887836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure) {
24897836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
24907836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
24917836SJohn.Forte@Sun.COM 	}
24927836SJohn.Forte@Sun.COM 
24937836SJohn.Forte@Sun.COM 	client->ipSec = ipSec;
24947836SJohn.Forte@Sun.COM 
24957836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
24967836SJohn.Forte@Sun.COM }
24977836SJohn.Forte@Sun.COM 
24987836SJohn.Forte@Sun.COM 
24997836SJohn.Forte@Sun.COM int
iscsiAuthClientSetBase64(IscsiAuthClient * client,int base64)25007836SJohn.Forte@Sun.COM iscsiAuthClientSetBase64(IscsiAuthClient * client, int base64)
25017836SJohn.Forte@Sun.COM {
25027836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
25037836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
25047836SJohn.Forte@Sun.COM 	}
25057836SJohn.Forte@Sun.COM 
25067836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure) {
25077836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
25087836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
25097836SJohn.Forte@Sun.COM 	}
25107836SJohn.Forte@Sun.COM 
25117836SJohn.Forte@Sun.COM 	client->base64 = base64;
25127836SJohn.Forte@Sun.COM 
25137836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
25147836SJohn.Forte@Sun.COM }
25157836SJohn.Forte@Sun.COM 
25167836SJohn.Forte@Sun.COM 
25177836SJohn.Forte@Sun.COM int
iscsiAuthClientSetChapChallengeLength(IscsiAuthClient * client,unsigned int chapChallengeLength)25187836SJohn.Forte@Sun.COM iscsiAuthClientSetChapChallengeLength(IscsiAuthClient * client,
25197836SJohn.Forte@Sun.COM     unsigned int chapChallengeLength)
25207836SJohn.Forte@Sun.COM {
25217836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
25227836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
25237836SJohn.Forte@Sun.COM 	}
25247836SJohn.Forte@Sun.COM 
25257836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure ||
25267836SJohn.Forte@Sun.COM 	    chapChallengeLength < iscsiAuthChapResponseLength ||
25277836SJohn.Forte@Sun.COM 	    chapChallengeLength > iscsiAuthLargeBinaryMaxLength) {
25287836SJohn.Forte@Sun.COM 
25297836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
25307836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
25317836SJohn.Forte@Sun.COM 	}
25327836SJohn.Forte@Sun.COM 
25337836SJohn.Forte@Sun.COM 	client->chapChallengeLength = chapChallengeLength;
25347836SJohn.Forte@Sun.COM 
25357836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
25367836SJohn.Forte@Sun.COM }
25377836SJohn.Forte@Sun.COM 
25387836SJohn.Forte@Sun.COM 
25397836SJohn.Forte@Sun.COM int
iscsiAuthClientCheckPasswordNeeded(IscsiAuthClient * client,int * passwordNeeded)25407836SJohn.Forte@Sun.COM iscsiAuthClientCheckPasswordNeeded(IscsiAuthClient *client, int *passwordNeeded)
25417836SJohn.Forte@Sun.COM {
25427836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
25437836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
25447836SJohn.Forte@Sun.COM 	}
25457836SJohn.Forte@Sun.COM 
25467836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure) {
25477836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
25487836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
25497836SJohn.Forte@Sun.COM 	}
25507836SJohn.Forte@Sun.COM 
25517836SJohn.Forte@Sun.COM 	if (client->nodeType == iscsiAuthNodeTypeInitiator) {
25527836SJohn.Forte@Sun.COM 		if (client->authRemote && !client->passwordPresent) {
25537836SJohn.Forte@Sun.COM 			*passwordNeeded = TRUE;
25547836SJohn.Forte@Sun.COM 		} else {
25557836SJohn.Forte@Sun.COM 			*passwordNeeded = FALSE;
25567836SJohn.Forte@Sun.COM 		}
25577836SJohn.Forte@Sun.COM 	} else {
25587836SJohn.Forte@Sun.COM 		*passwordNeeded = FALSE;
25597836SJohn.Forte@Sun.COM 	}
25607836SJohn.Forte@Sun.COM 
25617836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
25627836SJohn.Forte@Sun.COM }
25637836SJohn.Forte@Sun.COM 
25647836SJohn.Forte@Sun.COM 
25657836SJohn.Forte@Sun.COM int
iscsiAuthClientGetAuthPhase(IscsiAuthClient * client,int * value)25667836SJohn.Forte@Sun.COM iscsiAuthClientGetAuthPhase(IscsiAuthClient * client, int *value)
25677836SJohn.Forte@Sun.COM {
25687836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
25697836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
25707836SJohn.Forte@Sun.COM 	}
25717836SJohn.Forte@Sun.COM 
25727836SJohn.Forte@Sun.COM 	*value = client->phase;
25737836SJohn.Forte@Sun.COM 
25747836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
25757836SJohn.Forte@Sun.COM }
25767836SJohn.Forte@Sun.COM 
25777836SJohn.Forte@Sun.COM 
25787836SJohn.Forte@Sun.COM int
iscsiAuthClientGetAuthStatus(IscsiAuthClient * client,int * value)25797836SJohn.Forte@Sun.COM iscsiAuthClientGetAuthStatus(IscsiAuthClient * client, int *value)
25807836SJohn.Forte@Sun.COM {
25817836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
25827836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
25837836SJohn.Forte@Sun.COM 	}
25847836SJohn.Forte@Sun.COM 
25857836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseDone) {
25867836SJohn.Forte@Sun.COM 
25877836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
25887836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
25897836SJohn.Forte@Sun.COM 	}
25907836SJohn.Forte@Sun.COM 
25917836SJohn.Forte@Sun.COM 	*value = client->remoteAuthStatus;
25927836SJohn.Forte@Sun.COM 
25937836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
25947836SJohn.Forte@Sun.COM }
25957836SJohn.Forte@Sun.COM 
25967836SJohn.Forte@Sun.COM 
25977836SJohn.Forte@Sun.COM int
iscsiAuthClientAuthStatusPass(int authStatus)25987836SJohn.Forte@Sun.COM iscsiAuthClientAuthStatusPass(int authStatus)
25997836SJohn.Forte@Sun.COM {
26007836SJohn.Forte@Sun.COM 	if (authStatus == iscsiAuthStatusPass) {
26017836SJohn.Forte@Sun.COM 		return (TRUE);
26027836SJohn.Forte@Sun.COM 	}
26037836SJohn.Forte@Sun.COM 
26047836SJohn.Forte@Sun.COM 	return (FALSE);
26057836SJohn.Forte@Sun.COM }
26067836SJohn.Forte@Sun.COM 
26077836SJohn.Forte@Sun.COM 
26087836SJohn.Forte@Sun.COM int
iscsiAuthClientGetAuthMethod(IscsiAuthClient * client,int * value)26097836SJohn.Forte@Sun.COM iscsiAuthClientGetAuthMethod(IscsiAuthClient * client, int *value)
26107836SJohn.Forte@Sun.COM {
26117836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
26127836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
26137836SJohn.Forte@Sun.COM 	}
26147836SJohn.Forte@Sun.COM 
26157836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseDone &&
26167836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseAuthenticate) {
26177836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
26187836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
26197836SJohn.Forte@Sun.COM 	}
26207836SJohn.Forte@Sun.COM 
26217836SJohn.Forte@Sun.COM 	*value = client->negotiatedAuthMethod;
26227836SJohn.Forte@Sun.COM 
26237836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
26247836SJohn.Forte@Sun.COM }
26257836SJohn.Forte@Sun.COM 
26267836SJohn.Forte@Sun.COM 
26277836SJohn.Forte@Sun.COM int
iscsiAuthClientGetChapAlgorithm(IscsiAuthClient * client,int * value)26287836SJohn.Forte@Sun.COM iscsiAuthClientGetChapAlgorithm(IscsiAuthClient * client, int *value)
26297836SJohn.Forte@Sun.COM {
26307836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
26317836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
26327836SJohn.Forte@Sun.COM 	}
26337836SJohn.Forte@Sun.COM 
26347836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseDone) {
26357836SJohn.Forte@Sun.COM 
26367836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
26377836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
26387836SJohn.Forte@Sun.COM 	}
26397836SJohn.Forte@Sun.COM 
26407836SJohn.Forte@Sun.COM 	*value = client->negotiatedChapAlgorithm;
26417836SJohn.Forte@Sun.COM 
26427836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
26437836SJohn.Forte@Sun.COM }
26447836SJohn.Forte@Sun.COM 
26457836SJohn.Forte@Sun.COM 
26467836SJohn.Forte@Sun.COM int
iscsiAuthClientGetChapUsername(IscsiAuthClient * client,char * value,unsigned int maxLength)26477836SJohn.Forte@Sun.COM iscsiAuthClientGetChapUsername(IscsiAuthClient * client,
26487836SJohn.Forte@Sun.COM     char *value, unsigned int maxLength)
26497836SJohn.Forte@Sun.COM {
26507836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
26517836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
26527836SJohn.Forte@Sun.COM 	}
26537836SJohn.Forte@Sun.COM 
26547836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseDone) {
26557836SJohn.Forte@Sun.COM 
26567836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
26577836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
26587836SJohn.Forte@Sun.COM 	}
26597836SJohn.Forte@Sun.COM 
26607836SJohn.Forte@Sun.COM 	if (iscsiAuthClientStringCopy(value, client->chapUsername, maxLength)) {
26617836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
26627836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
26637836SJohn.Forte@Sun.COM 	}
26647836SJohn.Forte@Sun.COM 
26657836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
26667836SJohn.Forte@Sun.COM }
26677836SJohn.Forte@Sun.COM 
26687836SJohn.Forte@Sun.COM 
26697836SJohn.Forte@Sun.COM int
iscsiAuthClientSendStatusCode(IscsiAuthClient * client,int * statusCode)26707836SJohn.Forte@Sun.COM iscsiAuthClientSendStatusCode(IscsiAuthClient * client, int *statusCode)
26717836SJohn.Forte@Sun.COM {
26727836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
26737836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
26747836SJohn.Forte@Sun.COM 	}
26757836SJohn.Forte@Sun.COM 
26767836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseConfigure &&
26777836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseNegotiate &&
26787836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseAuthenticate &&
26797836SJohn.Forte@Sun.COM 	    client->phase != iscsiAuthPhaseDone) {
26807836SJohn.Forte@Sun.COM 
26817836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
26827836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
26837836SJohn.Forte@Sun.COM 	}
26847836SJohn.Forte@Sun.COM 
26857836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseDone) {
26867836SJohn.Forte@Sun.COM 		*statusCode = 0x0000;
26877836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusNoError);
26887836SJohn.Forte@Sun.COM 	}
26897836SJohn.Forte@Sun.COM 
26907836SJohn.Forte@Sun.COM 	switch (client->remoteAuthStatus) {
26917836SJohn.Forte@Sun.COM 	case iscsiAuthStatusPass:
26927836SJohn.Forte@Sun.COM 		*statusCode = 0x0000;	/* no error */
26937836SJohn.Forte@Sun.COM 		break;
26947836SJohn.Forte@Sun.COM 
26957836SJohn.Forte@Sun.COM 	case iscsiAuthStatusFail:
26967836SJohn.Forte@Sun.COM 		switch (client->debugStatus) {
26977836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthFail:
26987836SJohn.Forte@Sun.COM 			/*
26997836SJohn.Forte@Sun.COM 			 * Authentication error with peer.
27007836SJohn.Forte@Sun.COM 			 */
27017836SJohn.Forte@Sun.COM 			if (client->nodeType == iscsiAuthNodeTypeInitiator) {
27027836SJohn.Forte@Sun.COM 				*statusCode = 0x0300;
27037836SJohn.Forte@Sun.COM 				/*
27047836SJohn.Forte@Sun.COM 				 * iSCSI Target error
27057836SJohn.Forte@Sun.COM 				 */
27067836SJohn.Forte@Sun.COM 			} else {
27077836SJohn.Forte@Sun.COM 				*statusCode = 0x0201;
27087836SJohn.Forte@Sun.COM 				/*
27097836SJohn.Forte@Sun.COM 				 * iSCSI Initiator error
27107836SJohn.Forte@Sun.COM 				 */
27117836SJohn.Forte@Sun.COM 			}
27127836SJohn.Forte@Sun.COM 			break;
27137836SJohn.Forte@Sun.COM 
27147836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthMethodExpected:
27157836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapAlgorithmExpected:
27167836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapIdentifierExpected:
27177836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapChallengeExpected:
27187836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapResponseExpected:
27197836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapUsernameExpected:
27207836SJohn.Forte@Sun.COM 			/*
27217836SJohn.Forte@Sun.COM 			 * Missing parameter with peer.
27227836SJohn.Forte@Sun.COM 			 */
27237836SJohn.Forte@Sun.COM 			if (client->nodeType == iscsiAuthNodeTypeInitiator) {
27247836SJohn.Forte@Sun.COM 				*statusCode = 0x0300;
27257836SJohn.Forte@Sun.COM 				/*
27267836SJohn.Forte@Sun.COM 				 * iSCSI Target error
27277836SJohn.Forte@Sun.COM 				 */
27287836SJohn.Forte@Sun.COM 			} else {
27297836SJohn.Forte@Sun.COM 				*statusCode = 0x0207;
27307836SJohn.Forte@Sun.COM 				/*
27317836SJohn.Forte@Sun.COM 				 * iSCSI Initiator error
27327836SJohn.Forte@Sun.COM 				 */
27337836SJohn.Forte@Sun.COM 			}
27347836SJohn.Forte@Sun.COM 			break;
27357836SJohn.Forte@Sun.COM 
27367836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthMethodNotPresent:
27377836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthMethodReject:
27387836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthMethodNone:
27397836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapAlgorithmReject:
27407836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapChallengeReflected:
27417836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusPasswordIdentical:
27427836SJohn.Forte@Sun.COM 			/*
27437836SJohn.Forte@Sun.COM 			 * Could not authenticate with peer.
27447836SJohn.Forte@Sun.COM 			 */
27457836SJohn.Forte@Sun.COM 			if (client->nodeType == iscsiAuthNodeTypeInitiator) {
27467836SJohn.Forte@Sun.COM 				*statusCode = 0x0300;
27477836SJohn.Forte@Sun.COM 				/*
27487836SJohn.Forte@Sun.COM 				 * iSCSI Target error
27497836SJohn.Forte@Sun.COM 				 */
27507836SJohn.Forte@Sun.COM 			} else {
27517836SJohn.Forte@Sun.COM 				*statusCode = 0x0201;
27527836SJohn.Forte@Sun.COM 				/*
27537836SJohn.Forte@Sun.COM 				 * iSCSI Initiator error
27547836SJohn.Forte@Sun.COM 				 */
27557836SJohn.Forte@Sun.COM 			}
27567836SJohn.Forte@Sun.COM 			break;
27577836SJohn.Forte@Sun.COM 
27587836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusLocalPasswordNotSet:
27597836SJohn.Forte@Sun.COM 			/*
27607836SJohn.Forte@Sun.COM 			 * Local password not set.
27617836SJohn.Forte@Sun.COM 			 */
27627836SJohn.Forte@Sun.COM 			if (client->nodeType == iscsiAuthNodeTypeInitiator) {
27637836SJohn.Forte@Sun.COM 				*statusCode = 0x0200;
27647836SJohn.Forte@Sun.COM 				/*
27657836SJohn.Forte@Sun.COM 				 * iSCSI Initiator error
27667836SJohn.Forte@Sun.COM 				 */
27677836SJohn.Forte@Sun.COM 			} else {
27687836SJohn.Forte@Sun.COM 				*statusCode = 0x0201;
27697836SJohn.Forte@Sun.COM 				/*
27707836SJohn.Forte@Sun.COM 				 * iSCSI Target error
27717836SJohn.Forte@Sun.COM 				 */
27727836SJohn.Forte@Sun.COM 			}
27737836SJohn.Forte@Sun.COM 			break;
27747836SJohn.Forte@Sun.COM 
27757836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapIdentifierBad:
27767836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapChallengeBad:
27777836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapResponseBad:
27787836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusUnexpectedKeyPresent:
27797836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusTbitSetIllegal:
27807836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusTbitSetPremature:
27817836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusRecvMessageCountLimit:
27827836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusRecvDuplicateSetKeyValue:
27837836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusRecvStringTooLong:
27847836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusRecvTooMuchData:
27857836SJohn.Forte@Sun.COM 			/*
27867836SJohn.Forte@Sun.COM 			 * Other error with peer.
27877836SJohn.Forte@Sun.COM 			 */
27887836SJohn.Forte@Sun.COM 			if (client->nodeType == iscsiAuthNodeTypeInitiator) {
27897836SJohn.Forte@Sun.COM 				*statusCode = 0x0300;
27907836SJohn.Forte@Sun.COM 				/*
27917836SJohn.Forte@Sun.COM 				 * iSCSI Target error
27927836SJohn.Forte@Sun.COM 				 */
27937836SJohn.Forte@Sun.COM 			} else {
27947836SJohn.Forte@Sun.COM 				*statusCode = 0x0200;
27957836SJohn.Forte@Sun.COM 				/*
27967836SJohn.Forte@Sun.COM 				 * iSCSI Initiator error
27977836SJohn.Forte@Sun.COM 				 */
27987836SJohn.Forte@Sun.COM 			}
27997836SJohn.Forte@Sun.COM 			break;
28007836SJohn.Forte@Sun.COM 
28017836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusNotSet:
28027836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthPass:
28037836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthRemoteFalse:
28047836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthMethodBad:
28057836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusChapAlgorithmBad:
28067836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusPasswordDecryptFailed:
28077836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusPasswordTooShortWithNoIpSec:
28087836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthServerError:
28097836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthStatusBad:
28107836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusAuthPassNotValid:
28117836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusSendDuplicateSetKeyValue:
28127836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusSendStringTooLong:
28137836SJohn.Forte@Sun.COM 		case iscsiAuthDebugStatusSendTooMuchData:
28147836SJohn.Forte@Sun.COM 		default:
28157836SJohn.Forte@Sun.COM 			/*
28167836SJohn.Forte@Sun.COM 			 * Error on this side.
28177836SJohn.Forte@Sun.COM 			 */
28187836SJohn.Forte@Sun.COM 			if (client->nodeType == iscsiAuthNodeTypeInitiator) {
28197836SJohn.Forte@Sun.COM 				*statusCode = 0x0200;
28207836SJohn.Forte@Sun.COM 				/*
28217836SJohn.Forte@Sun.COM 				 * iSCSI Initiator error
28227836SJohn.Forte@Sun.COM 				 */
28237836SJohn.Forte@Sun.COM 			} else {
28247836SJohn.Forte@Sun.COM 				*statusCode = 0x0300;
28257836SJohn.Forte@Sun.COM 				/*
28267836SJohn.Forte@Sun.COM 				 * iSCSI Target error
28277836SJohn.Forte@Sun.COM 				 */
28287836SJohn.Forte@Sun.COM 			}
28297836SJohn.Forte@Sun.COM 
28307836SJohn.Forte@Sun.COM 		}
28317836SJohn.Forte@Sun.COM 		break;
28327836SJohn.Forte@Sun.COM 
28337836SJohn.Forte@Sun.COM 	case iscsiAuthStatusNoError:
28347836SJohn.Forte@Sun.COM 	case iscsiAuthStatusError:
28357836SJohn.Forte@Sun.COM 	case iscsiAuthStatusContinue:
28367836SJohn.Forte@Sun.COM 	case iscsiAuthStatusInProgress:
28377836SJohn.Forte@Sun.COM 	default:
28387836SJohn.Forte@Sun.COM 		/*
28397836SJohn.Forte@Sun.COM 		 * Bad authStatus
28407836SJohn.Forte@Sun.COM 		 */
28417836SJohn.Forte@Sun.COM 		if (client->nodeType == iscsiAuthNodeTypeInitiator) {
28427836SJohn.Forte@Sun.COM 			*statusCode = 0x0200;
28437836SJohn.Forte@Sun.COM 			/*
28447836SJohn.Forte@Sun.COM 			 * iSCSI Initiator error
28457836SJohn.Forte@Sun.COM 			 */
28467836SJohn.Forte@Sun.COM 		} else {
28477836SJohn.Forte@Sun.COM 			*statusCode = 0x0300;
28487836SJohn.Forte@Sun.COM 			/*
28497836SJohn.Forte@Sun.COM 			 * iSCSI Target error
28507836SJohn.Forte@Sun.COM 			 */
28517836SJohn.Forte@Sun.COM 		}
28527836SJohn.Forte@Sun.COM 	}
28537836SJohn.Forte@Sun.COM 
28547836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
28557836SJohn.Forte@Sun.COM }
28567836SJohn.Forte@Sun.COM 
28577836SJohn.Forte@Sun.COM 
28587836SJohn.Forte@Sun.COM int
iscsiAuthClientGetDebugStatus(IscsiAuthClient * client,int * value)28597836SJohn.Forte@Sun.COM iscsiAuthClientGetDebugStatus(IscsiAuthClient * client, int *value)
28607836SJohn.Forte@Sun.COM {
28617836SJohn.Forte@Sun.COM 	if (!client || client->signature != iscsiAuthClientSignature) {
28627836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
28637836SJohn.Forte@Sun.COM 	}
28647836SJohn.Forte@Sun.COM 
28657836SJohn.Forte@Sun.COM 	if (client->phase != iscsiAuthPhaseDone) {
28667836SJohn.Forte@Sun.COM 
28677836SJohn.Forte@Sun.COM 		client->phase = iscsiAuthPhaseError;
28687836SJohn.Forte@Sun.COM 		return (iscsiAuthStatusError);
28697836SJohn.Forte@Sun.COM 	}
28707836SJohn.Forte@Sun.COM 
28717836SJohn.Forte@Sun.COM 	*value = client->debugStatus;
28727836SJohn.Forte@Sun.COM 
28737836SJohn.Forte@Sun.COM 	return (iscsiAuthStatusNoError);
28747836SJohn.Forte@Sun.COM }
28757836SJohn.Forte@Sun.COM 
28767836SJohn.Forte@Sun.COM 
28777836SJohn.Forte@Sun.COM const char *
iscsiAuthClientDebugStatusToText(int debugStatus)28787836SJohn.Forte@Sun.COM iscsiAuthClientDebugStatusToText(int debugStatus)
28797836SJohn.Forte@Sun.COM {
28807836SJohn.Forte@Sun.COM 	const char *s;
28817836SJohn.Forte@Sun.COM 
28827836SJohn.Forte@Sun.COM 	switch (debugStatus) {
28837836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusNotSet:
28847836SJohn.Forte@Sun.COM 		s = "Debug status not set";
28857836SJohn.Forte@Sun.COM 		break;
28867836SJohn.Forte@Sun.COM 
28877836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthPass:
28887836SJohn.Forte@Sun.COM 		s = "Authentication request passed";
28897836SJohn.Forte@Sun.COM 		break;
28907836SJohn.Forte@Sun.COM 
28917836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthRemoteFalse:
28927836SJohn.Forte@Sun.COM 		s = "Authentication not enabled";
28937836SJohn.Forte@Sun.COM 		break;
28947836SJohn.Forte@Sun.COM 
28957836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthFail:
28967836SJohn.Forte@Sun.COM 		s = "Authentication request failed";
28977836SJohn.Forte@Sun.COM 		break;
28987836SJohn.Forte@Sun.COM 
28997836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthMethodBad:
29007836SJohn.Forte@Sun.COM 		s = "AuthMethod bad";
29017836SJohn.Forte@Sun.COM 		break;
29027836SJohn.Forte@Sun.COM 
29037836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapAlgorithmBad:
29047836SJohn.Forte@Sun.COM 		s = "CHAP algorithm bad";
29057836SJohn.Forte@Sun.COM 		break;
29067836SJohn.Forte@Sun.COM 
29077836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusPasswordDecryptFailed:
29087836SJohn.Forte@Sun.COM 		s = "Decrypt password failed";
29097836SJohn.Forte@Sun.COM 		break;
29107836SJohn.Forte@Sun.COM 
29117836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusPasswordTooShortWithNoIpSec:
29127836SJohn.Forte@Sun.COM 		s = "Local password too short with no IPSec";
29137836SJohn.Forte@Sun.COM 		break;
29147836SJohn.Forte@Sun.COM 
29157836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthServerError:
29167836SJohn.Forte@Sun.COM 		s = "Unexpected error from authentication server";
29177836SJohn.Forte@Sun.COM 		break;
29187836SJohn.Forte@Sun.COM 
29197836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthStatusBad:
29207836SJohn.Forte@Sun.COM 		s = "Authentication request status bad";
29217836SJohn.Forte@Sun.COM 		break;
29227836SJohn.Forte@Sun.COM 
29237836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthPassNotValid:
29247836SJohn.Forte@Sun.COM 		s = "Authentication pass status not valid";
29257836SJohn.Forte@Sun.COM 		break;
29267836SJohn.Forte@Sun.COM 
29277836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusSendDuplicateSetKeyValue:
29287836SJohn.Forte@Sun.COM 		s = "Same key set more than once on send";
29297836SJohn.Forte@Sun.COM 		break;
29307836SJohn.Forte@Sun.COM 
29317836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusSendStringTooLong:
29327836SJohn.Forte@Sun.COM 		s = "Key value too long on send";
29337836SJohn.Forte@Sun.COM 		break;
29347836SJohn.Forte@Sun.COM 
29357836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusSendTooMuchData:
29367836SJohn.Forte@Sun.COM 		s = "Too much data on send";
29377836SJohn.Forte@Sun.COM 		break;
29387836SJohn.Forte@Sun.COM 
29397836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthMethodExpected:
29407836SJohn.Forte@Sun.COM 		s = "AuthMethod key expected";
29417836SJohn.Forte@Sun.COM 		break;
29427836SJohn.Forte@Sun.COM 
29437836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapAlgorithmExpected:
29447836SJohn.Forte@Sun.COM 		s = "CHAP algorithm key expected";
29457836SJohn.Forte@Sun.COM 		break;
29467836SJohn.Forte@Sun.COM 
29477836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapIdentifierExpected:
29487836SJohn.Forte@Sun.COM 		s = "CHAP identifier expected";
29497836SJohn.Forte@Sun.COM 		break;
29507836SJohn.Forte@Sun.COM 
29517836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapChallengeExpected:
29527836SJohn.Forte@Sun.COM 		s = "CHAP challenge expected";
29537836SJohn.Forte@Sun.COM 		break;
29547836SJohn.Forte@Sun.COM 
29557836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapResponseExpected:
29567836SJohn.Forte@Sun.COM 		s = "CHAP response expected";
29577836SJohn.Forte@Sun.COM 		break;
29587836SJohn.Forte@Sun.COM 
29597836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapUsernameExpected:
29607836SJohn.Forte@Sun.COM 		s = "CHAP username expected";
29617836SJohn.Forte@Sun.COM 		break;
29627836SJohn.Forte@Sun.COM 
29637836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthMethodNotPresent:
29647836SJohn.Forte@Sun.COM 		s = "AuthMethod key not present";
29657836SJohn.Forte@Sun.COM 		break;
29667836SJohn.Forte@Sun.COM 
29677836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthMethodReject:
29687836SJohn.Forte@Sun.COM 		s = "AuthMethod negotiation failed";
29697836SJohn.Forte@Sun.COM 		break;
29707836SJohn.Forte@Sun.COM 
29717836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusAuthMethodNone:
29727836SJohn.Forte@Sun.COM 		s = "AuthMethod negotiated to none";
29737836SJohn.Forte@Sun.COM 		break;
29747836SJohn.Forte@Sun.COM 
29757836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapAlgorithmReject:
29767836SJohn.Forte@Sun.COM 		s = "CHAP algorithm negotiation failed";
29777836SJohn.Forte@Sun.COM 		break;
29787836SJohn.Forte@Sun.COM 
29797836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapChallengeReflected:
29807836SJohn.Forte@Sun.COM 		s = "CHAP challange reflected";
29817836SJohn.Forte@Sun.COM 		break;
29827836SJohn.Forte@Sun.COM 
29837836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusPasswordIdentical:
29847836SJohn.Forte@Sun.COM 		s = "Local password same as remote";
29857836SJohn.Forte@Sun.COM 		break;
29867836SJohn.Forte@Sun.COM 
29877836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusLocalPasswordNotSet:
29887836SJohn.Forte@Sun.COM 		s = "Local password not set";
29897836SJohn.Forte@Sun.COM 		break;
29907836SJohn.Forte@Sun.COM 
29917836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapIdentifierBad:
29927836SJohn.Forte@Sun.COM 		s = "CHAP identifier bad";
29937836SJohn.Forte@Sun.COM 		break;
29947836SJohn.Forte@Sun.COM 
29957836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapChallengeBad:
29967836SJohn.Forte@Sun.COM 		s = "CHAP challenge bad";
29977836SJohn.Forte@Sun.COM 		break;
29987836SJohn.Forte@Sun.COM 
29997836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusChapResponseBad:
30007836SJohn.Forte@Sun.COM 		s = "CHAP response bad";
30017836SJohn.Forte@Sun.COM 		break;
30027836SJohn.Forte@Sun.COM 
30037836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusUnexpectedKeyPresent:
30047836SJohn.Forte@Sun.COM 		s = "Unexpected key present";
30057836SJohn.Forte@Sun.COM 		break;
30067836SJohn.Forte@Sun.COM 
30077836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusTbitSetIllegal:
30087836SJohn.Forte@Sun.COM 		s = "T bit set on response, but not on previous message";
30097836SJohn.Forte@Sun.COM 		break;
30107836SJohn.Forte@Sun.COM 
30117836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusTbitSetPremature:
30127836SJohn.Forte@Sun.COM 		s = "T bit set on response, but authenticaton not complete";
30137836SJohn.Forte@Sun.COM 		break;
30147836SJohn.Forte@Sun.COM 
30157836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusRecvMessageCountLimit:
30167836SJohn.Forte@Sun.COM 		s = "Message count limit reached on receive";
30177836SJohn.Forte@Sun.COM 		break;
30187836SJohn.Forte@Sun.COM 
30197836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusRecvDuplicateSetKeyValue:
30207836SJohn.Forte@Sun.COM 		s = "Same key set more than once on receive";
30217836SJohn.Forte@Sun.COM 		break;
30227836SJohn.Forte@Sun.COM 
30237836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusRecvStringTooLong:
30247836SJohn.Forte@Sun.COM 		s = "Key value too long on receive";
30257836SJohn.Forte@Sun.COM 		break;
30267836SJohn.Forte@Sun.COM 
30277836SJohn.Forte@Sun.COM 	case iscsiAuthDebugStatusRecvTooMuchData:
30287836SJohn.Forte@Sun.COM 		s = "Too much data on receive";
30297836SJohn.Forte@Sun.COM 		break;
30307836SJohn.Forte@Sun.COM 
30317836SJohn.Forte@Sun.COM 	default:
30327836SJohn.Forte@Sun.COM 		s = "Unknown error";
30337836SJohn.Forte@Sun.COM 	}
30347836SJohn.Forte@Sun.COM 
30357836SJohn.Forte@Sun.COM 	return (s);
30367836SJohn.Forte@Sun.COM }
3037