/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2000 by Cisco Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* This file implements the iSCSI CHAP authentication method based.
* The code in this file is meant to be platform independent, and
* makes use of only limited library functions, presently only string.h.
* Platform dependent routines are defined in iscsiAuthClient.h, but
* implemented in another file.
*
* This code in this files assumes a single thread of execution
* for each IscsiAuthClient structure, and does no locking.
*/
#include "iscsi.h"
#include "iscsiAuthClient.h"
struct iscsiAuthKeyInfo_t {
const char *name;
};
/*
* Note: The ordering of this table must match the order
* defined by IscsiAuthKeyType in iscsiAuthClient.h.
*/
{"AuthMethod"},
{"CHAP_A"},
{"CHAP_N"},
{"CHAP_R"},
{"CHAP_I"},
{"CHAP_C"}
};
static const char iscsiAuthClientBase64String[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static int
iscsiAuthClientCheckString(const char *s,
unsigned int maxLength, unsigned int *pOutLength)
{
unsigned int length;
if (!s) {
return (TRUE);
}
if (*s++ == '\0') {
if (pOutLength) {
*pOutLength = length;
}
return (FALSE);
}
}
return (TRUE);
}
static int
unsigned int length)
{
return (TRUE);
}
if (--length == 0) {
stringOut--;
*stringOut = '\0';
return (TRUE);
}
}
return (FALSE);
}
static int
unsigned int length)
{
return (TRUE);
}
while (*stringOut++ != '\0') {
if (--length == 0) {
stringOut--;
*stringOut = '\0';
return (TRUE);
}
}
stringOut--;
if (--length == 0) {
stringOut--;
*stringOut = '\0';
return (TRUE);
}
}
return (FALSE);
}
static int
iscsiAuthClientStringIndex(const char *s, int c)
{
int n = 0;
while (*s != '\0') {
if (*s++ == c) {
return (n);
}
n++;
}
return (-1);
}
static int
{
if (nodeType == iscsiAuthNodeTypeInitiator ||
return (FALSE);
}
return (TRUE);
}
static int
{
return (FALSE);
}
return (TRUE);
}
static int
{
if (value == iscsiAuthNegRoleOriginator ||
return (FALSE);
}
return (TRUE);
}
static int
{
return (FALSE);
}
return (TRUE);
}
static const char *
{
const char *s;
switch (value) {
case iscsiAuthOptionReject:
s = client->rejectOptionName;
break;
case iscsiAuthOptionNone:
s = client->noneOptionName;
break;
case iscsiAuthMethodChap:
break;
default:
s = 0;
}
return (s);
}
static int
{
if (chapAlgorithm == iscsiAuthOptionNone ||
return (FALSE);
}
return (TRUE);
}
static int
char *text, unsigned int textLength)
{
unsigned long n;
if (!text || textLength == 0) {
return (TRUE);
}
if (!data || dataLength == 0) {
*text = '\0';
return (TRUE);
}
if (textLength < 3) {
*text = '\0';
return (TRUE);
}
*text++ = '0';
*text++ = 'x';
textLength -= 2;
while (dataLength > 0) {
if (textLength < 3) {
*text = '\0';
return (TRUE);
}
n = *data++;
dataLength--;
textLength -= 2;
}
*text = '\0';
return (FALSE);
}
static int
char *text, unsigned int textLength)
{
unsigned long n;
if (!text || textLength == 0) {
return (TRUE);
}
if (!data || dataLength == 0) {
*text = '\0';
return (TRUE);
}
if (textLength < 3) {
*text = '\0';
return (TRUE);
}
*text++ = '0';
*text++ = 'b';
textLength -= 2;
while (dataLength >= 3) {
if (textLength < 5) {
*text = '\0';
return (TRUE);
}
n = *data++;
n = (n << 8) | *data++;
n = (n << 8) | *data++;
dataLength -= 3;
textLength -= 4;
}
if (dataLength == 1) {
if (textLength < 5) {
*text = '\0';
return (TRUE);
}
n = *data++;
n = n << 4;
*text++ = '=';
*text++ = '=';
} else if (dataLength == 2) {
if (textLength < 5) {
return (TRUE);
}
n = *data++;
n = (n << 8) | *data++;
n = n << 2;
*text++ = '=';
}
*text = '\0';
return (FALSE);
}
static int
{
int status;
if (base64) {
} else {
}
return (status);
}
static int
unsigned char *data, unsigned int *pDataLength)
{
int i;
unsigned int n1;
unsigned int n2;
*text++);
if (i < 0) {
return (TRUE); /* error, bad character */
}
if (i > 15)
i -= 6;
n2 = i;
if (dataLength < 1) {
return (TRUE); /* error, too much data */
}
dataLength--;
}
while (*text != '\0') {
iscsiAuthClientHexString, *text++);
if (i < 0) {
return (TRUE); /* error, bad character */
}
if (i > 15)
i -= 6;
n1 = i;
if (*text == '\0') {
return (TRUE); /* error, odd string length */
}
iscsiAuthClientHexString, *text++);
if (i < 0) {
return (TRUE); /* error, bad character */
}
if (i > 15)
i -= 6;
n2 = i;
if (dataLength < 1) {
return (TRUE); /* error, too much data */
}
dataLength--;
}
if (dataLength >= *pDataLength) {
return (TRUE); /* error, no data */
}
return (FALSE); /* no error */
}
static int
unsigned char *data, unsigned int *pDataLength)
{
int i;
unsigned int n;
unsigned int count;
n = 0;
count = 0;
if (i < 0) {
return (TRUE); /* error, bad character */
}
n = (n << 6 | (unsigned int)i);
count++;
if (count >= 4) {
if (dataLength < 3) {
return (TRUE); /* error, too much data */
}
*data++ = n >> 16;
*data++ = n >> 8;
*data++ = n;
dataLength -= 3;
n = 0;
count = 0;
}
}
while (*text != '\0') {
if (*text++ != '=') {
return (TRUE); /* error, bad pad */
}
}
if (count == 0) {
/*
* do nothing
*/
/* EMPTY */
} else if (count == 2) {
if (dataLength < 1) {
return (TRUE); /* error, too much data */
}
n = n >> 4;
*data++ = n;
dataLength--;
} else if (count == 3) {
if (dataLength < 2) {
return (TRUE); /* error, too much data */
}
n = n >> 2;
*data++ = n >> 8;
*data++ = n;
dataLength -= 2;
} else {
return (TRUE); /* bad encoding */
}
if (dataLength >= *pDataLength) {
return (TRUE); /* error, no data */
}
return (FALSE); /* no error */
}
static int
unsigned int *dataLength)
{
int status;
unsigned int textLength;
if (status) {
return (status);
}
/*
* skip prefix
*/
text += 2;
textLength -= 2;
/*
* skip prefix
*/
text += 2;
textLength -= 2;
} else {
}
return (status);
}
static IscsiAuthDebugStatus
int remoteAuthentication, unsigned int id,
unsigned char *challengeData, unsigned int challengeLength,
unsigned char *responseData)
{
if (!client->passwordPresent) {
return (iscsiAuthDebugStatusLocalPasswordNotSet);
}
/*
* id byte
*/
/*
* decrypt password
*/
}
}
/*
* shared secret
*/
/*
* clear decrypted password
*/
/*
* challenge value
*/
return (iscsiAuthDebugStatusNotSet); /* no error */
}
static void
{
}
static void
{
unsigned int length;
char *string;
return;
}
if (!keyValue) {
return;
}
return;
}
length += 1;
return;
}
return;
}
}
static const char *
{
return (0);
}
}
static void
int keyType,
int *negotiatedOption,
unsigned int optionCount,
{
const char *keyValue;
int length;
unsigned int i;
if (!keyValue) {
return;
}
while (*keyValue != '\0') {
length = 0;
}
if (*keyValue == ',')
keyValue++;
for (i = 0; i < optionCount; i++) {
if (!s)
continue;
*negotiatedOption = optionList[i];
return;
}
}
}
}
static void
int keyType,
unsigned int optionCount,
{
unsigned int i;
if (optionCount == 0) {
/*
* No valid options to send, but we always want to
* send something.
*/
return;
}
return;
}
for (i = 0; i < optionCount; i++) {
if (!s)
continue;
if (i == 0) {
(void) iscsiAuthClientStringCopy(
} else {
(void) iscsiAuthClientStringAppend(
",", iscsiAuthStringMaxLength);
(void) iscsiAuthClientStringAppend(
}
}
}
static void
{
}
static void
unsigned int authMethodCount, int *authMethodList)
{
}
static void
{
const char *keyValue;
int length;
unsigned long number;
unsigned int i;
if (!keyValue) {
return;
}
while (*keyValue != '\0') {
length = 0;
}
if (*keyValue == ',')
keyValue++;
&number)) {
continue;
}
for (i = 0; i < client->chapAlgorithmCount; i++) {
chapAlgorithmList[i]) {
return;
}
}
}
}
static void
unsigned int chapAlgorithmCount, int *chapAlgorithmList)
{
unsigned int i;
if (chapAlgorithmCount == 0) {
return;
}
if (chapAlgorithmCount == 1 &&
return;
}
if (chapAlgorithmCount == 1 &&
chapAlgorithmList[0] == iscsiAuthOptionReject) {
return;
}
for (i = 0; i < chapAlgorithmCount; i++) {
char s[20];
s, sizeof (s));
if (i == 0) {
(void) iscsiAuthClientStringCopy(
client->scratchKeyValue, s,
} else {
(void) iscsiAuthClientStringAppend(
",", iscsiAuthStringMaxLength);
(void) iscsiAuthClientStringAppend(
}
}
}
static void
{
case iscsiAuthPhaseConfigure:
break;
case iscsiAuthPhaseNegotiate:
if (client->negotiatedAuthMethod ==
if (client->authRemote) {
} else {
}
switch (client->negotiatedAuthMethod) {
case iscsiAuthOptionReject:
break;
break;
case iscsiAuthOptionNone:
}
} else if (client->negotiatedAuthMethod ==
} else {
}
break;
break;
case iscsiAuthPhaseDone:
case iscsiAuthPhaseError:
default:
}
}
static void
{
unsigned int chapIdentifier;
unsigned long number;
int status;
const char *chapIdentifierKeyValue;
const char *chapChallengeKeyValue;
switch (client->localState) {
break;
}
/* FALLTHRU */
}
/*
* Make sure only supported CHAP algorithm is used.
*/
if (client->negotiatedChapAlgorithm ==
break;
} else if (client->negotiatedChapAlgorithm ==
break;
} else if (client->negotiatedChapAlgorithm !=
break;
}
break;
}
/* FALLTHRU */
if (!chapIdentifierKeyValue && !chapChallengeKeyValue) {
break;
}
}
if (!chapIdentifierKeyValue) {
break;
}
if (!chapChallengeKeyValue) {
break;
}
break;
}
if (client->recvChapChallengeStatus) {
break;
}
break;
}
if (debugStatus != iscsiAuthDebugStatusNotSet) {
break;
}
break;
case iscsiAuthLocalStateDone:
break;
case iscsiAuthLocalStateError:
default:
}
}
static void
{
int status;
const char *chapResponseKeyValue;
const char *chapUsernameKeyValue;
switch (client->remoteState) {
break;
}
/* FALLTHRU */
if (!client->authRemote) {
break;
}
break;
if (!chapResponseKeyValue) {
break;
}
if (!chapUsernameKeyValue) {
break;
}
if (status) {
break;
}
if (responseLength == iscsiAuthChapResponseLength) {
/*
* Check if the same CHAP secret is being used for
* authentication in both directions.
*/
if (debugStatus == iscsiAuthDebugStatusNotSet &&
iscsiAuthChapResponseLength) == 0) {
break;
}
}
/* To verify the target's response. */
if (status == iscsiAuthStatusInProgress) {
break;
}
/* FALLTHRU */
/*
* client->remoteAuthStatus already set
*/
if (client->authServerErrorFlag) {
} else {
}
/* FALLTHRU */
case iscsiAuthRemoteStateDone:
break;
default:
}
}
static void
{
/*
* Should only happen if authentication
* protocol error occured.
*/
return;
}
/*
* Defer until authentication response received
* from internal authentication service.
*/
return;
}
/*
* Target should only have set T bit on response if
* initiator set it on previous message.
*/
client->transitBitSentFlag == 0) {
return;
}
}
/*
* Should only happen if waiting for peer
* to send AuthMethod key or set Transit Bit.
*/
}
return;
}
if (client->remoteState !=
goto recvTransitBitError;
}
} else {
}
} else {
/*
* Authentication failed, don't
* do T bit handshake.
*/
} else {
/*
* Target can only set T bit on response if
* initiator set it on current message.
*/
}
}
}
} else {
goto recvTransitBitError;
}
}
}
return;
/*
* Target set T bit on response but
* initiator was not done with authentication.
*/
}
static int
{
int authStatus;
int keyType;
return (iscsiAuthStatusError);
}
/*
* Perform sanity check against configured parameters.
*/
}
} else {
}
if (authStatus != iscsiAuthStatusInProgress) {
}
if (authStatus == iscsiAuthStatusContinue ||
} else {
/*
* Check that all incoming keys have been processed.
*/
for (keyType = iscsiAuthKeyTypeFirst;
processed == 0) {
break;
}
}
if (keyType < iscsiAuthKeyTypeMaxCount) {
}
}
}
if (authStatus != iscsiAuthStatusPass &&
/*
* Suppress send keys on error, except
* for AuthMethod and CHAP_A.
*/
} else if (iscsiAuthClientGetKeyValue(
}
}
if (authMethodKeyPresent &&
} else if (chapAlgorithmKeyPresent &&
}
}
}
return (authStatus);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
if (client->recvInProgressFlag) {
return (iscsiAuthStatusError);
}
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
}
client->recvEndCount++;
case iscsiAuthPhaseNegotiate:
if (client->authMethodValidNegRole ==
if (client->negotiatedAuthMethod ==
if (client->authRemote ||
/*
* No AuthMethod key from peer
* on first message, try moving
* the process along by sending
* the AuthMethod key.
*/
break;
}
/*
* Special case if peer sent no
* AuthMethod key, but did set Transit
* Bit, allowing this side to do a
* null authentication, and compelete
* the iSCSI security phase without
* either side sending the AuthMethod
* key.
*/
} else {
/*
* Send response to AuthMethod key.
*/
}
} else {
}
} else {
if (client->negotiatedAuthMethod ==
break;
}
}
break;
case iscsiAuthPhaseDone:
break;
default:
return (iscsiAuthStatusError);
}
case iscsiAuthPhaseNegotiate:
if (nextPhaseFlag) {
}
break;
/*
* Must call iscsiAuthClientLocalAuthentication()
* before iscsiAuthClientRemoteAuthentication()
* to insure processing of the CHAP algorithm key,
* and to avoid leaving an in progress request to the
* authentication service.
*/
}
/*
* client->debugStatus should already be set.
*/
}
break;
case iscsiAuthPhaseDone:
break;
default:
return (iscsiAuthStatusError);
}
return (iscsiAuthClientRecvEndStatus(client));
}
void
{
return;
}
if (!client->recvInProgressFlag ||
return;
}
}
const char *
{
return (0);
}
}
int
{
if (keyType >= iscsiAuthKeyTypeLast) {
return (iscsiAuthStatusError);
}
if (keyType < iscsiAuthKeyTypeFirst) {
} else {
keyType++;
}
return (iscsiAuthStatusNoError);
}
int
{
while (iscsiAuthClientGetNextKeyType(&keyType) ==
if (!keyName2) {
return (iscsiAuthKeyTypeNone);
}
return (keyType);
}
}
return (iscsiAuthKeyTypeNone);
}
int
const char *userKeyValue)
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
if (keyType == iscsiAuthKeyTypeChapChallenge) {
userKeyValue = "";
}
return (iscsiAuthStatusNoError);
}
int
{
const char *keyValue;
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
if (keyValue) {
if (keyType == iscsiAuthKeyTypeChapChallenge) {
userKeyValue, maxLength)) {
return (iscsiAuthStatusError);
}
} else {
return (iscsiAuthStatusError);
}
}
*keyPresent = TRUE;
} else {
*keyPresent = FALSE;
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
if (value) {
} else {
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
if (bufferDescCount != 5 ||
bufferDesc == 0) {
return (iscsiAuthStatusError);
}
if (!bufferDesc[0].address ||
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
if (iscsiAuthClientCheckNodeType(nodeType)) {
return (iscsiAuthStatusError);
}
/* Assume bi-directional authentication enabled. */
} else {
/*
* Initial value ignored for Target.
*/
}
/* All supported authentication methods */
valueList[0] = iscsiAuthMethodChap;
/*
* Must call after setting authRemote, password,
* version and authMethodNegRole
*/
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
static int
unsigned int optionCount,
const int *optionList,
unsigned int *clientOptionCount,
int *clientOptionList,
unsigned int optionMaxCount,
int (*checkOption) (int),
{
unsigned int i;
unsigned int j;
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
for (i = 0; i < optionCount; i++) {
if ((*checkOption) (optionList[i])) {
return (iscsiAuthStatusError);
}
}
/*
* Check for duplicate entries.
*/
for (i = 0; i < optionCount; i++) {
for (j = 0; j < optionCount; j++) {
if (j == i)
continue;
if (optionList[i] == optionList[j]) {
return (iscsiAuthStatusError);
}
}
}
/*
* Check for key specific constraints.
*/
if (checkList) {
return (iscsiAuthStatusError);
}
}
for (i = 0; i < optionCount; i++) {
clientOptionList[i] = optionList[i];
}
return (iscsiAuthStatusNoError);
}
static void
{
unsigned int i;
unsigned int j = 0;
int option = 0;
} else {
}
/*
* Following checks may need to be revised if
* authentication options other than CHAP and none
* are supported.
*/
if (client->authRemote) {
/*
* If initiator doing authentication,
* don't offer authentication option none.
*/
option = 1;
} else if (!client->passwordPresent) {
/*
* If initiator password not set,
* only offer authentication option none.
*/
option = 2;
}
}
if (client->authRemote) {
/*
* If target doing authentication,
* don't accept authentication option none.
*/
option = 1;
} else {
/*
* If target not doing authentication,
* only accept authentication option none.
*/
option = 2;
}
}
for (i = 0; i < client->authMethodCount; i++) {
if (option == 1) {
continue;
}
} else if (option == 2) {
continue;
}
}
}
client->authMethodValidCount = j;
if (client->authRemote) {
/*
* Initiator wants to authenticate target,
* always send AuthMethod key.
*/
} else {
}
} else {
}
} else {
}
}
static int
const int *optionList)
{
unsigned int i;
return (TRUE);
}
return (TRUE);
}
for (i = 0; i < (optionCount - 1); i++) {
if (optionList[i] != iscsiAuthOptionNone) {
return (FALSE);
}
}
return (FALSE);
}
int
unsigned int optionCount, const int *optionList)
{
int status;
if (status != iscsiAuthStatusNoError) {
return (status);
}
/*
* Setting authMethod affects authMethodValid.
*/
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
/*
* Setting negRole affects authMethodValid.
*/
return (iscsiAuthStatusNoError);
}
static int
const int *optionList)
{
return (TRUE);
}
return (FALSE);
}
int
unsigned int optionCount, const int *optionList)
{
return (iscsiAuthClientSetOptionList(client,
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
const unsigned char *passwordData, unsigned int passwordLength)
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
if (client->passwordLength > 0) {
} else {
}
/*
* Setting password may affect authMethodValid.
*/
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
/*
* Setting authRemote may affect authMethodValid.
*/
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
const char *methodListName)
{
return (iscsiAuthStatusError);
}
iscsiAuthStringMaxLength, 0)) {
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
if (client == 0 ||
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
unsigned int chapChallengeLength)
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
*passwordNeeded = TRUE;
} else {
*passwordNeeded = FALSE;
}
} else {
*passwordNeeded = FALSE;
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
if (authStatus == iscsiAuthStatusPass) {
return (TRUE);
}
return (FALSE);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
*statusCode = 0x0000;
return (iscsiAuthStatusNoError);
}
switch (client->remoteAuthStatus) {
case iscsiAuthStatusPass:
break;
case iscsiAuthStatusFail:
switch (client->debugStatus) {
/*
* Authentication error with peer.
*/
*statusCode = 0x0300;
/*
* iSCSI Target error
*/
} else {
*statusCode = 0x0201;
/*
* iSCSI Initiator error
*/
}
break;
/*
* Missing parameter with peer.
*/
*statusCode = 0x0300;
/*
* iSCSI Target error
*/
} else {
*statusCode = 0x0207;
/*
* iSCSI Initiator error
*/
}
break;
/*
* Could not authenticate with peer.
*/
*statusCode = 0x0300;
/*
* iSCSI Target error
*/
} else {
*statusCode = 0x0201;
/*
* iSCSI Initiator error
*/
}
break;
/*
* Local password not set.
*/
*statusCode = 0x0200;
/*
* iSCSI Initiator error
*/
} else {
*statusCode = 0x0201;
/*
* iSCSI Target error
*/
}
break;
/*
* Other error with peer.
*/
*statusCode = 0x0300;
/*
* iSCSI Target error
*/
} else {
*statusCode = 0x0200;
/*
* iSCSI Initiator error
*/
}
break;
default:
/*
* Error on this side.
*/
*statusCode = 0x0200;
/*
* iSCSI Initiator error
*/
} else {
*statusCode = 0x0300;
/*
* iSCSI Target error
*/
}
}
break;
case iscsiAuthStatusNoError:
case iscsiAuthStatusError:
case iscsiAuthStatusContinue:
default:
/*
* Bad authStatus
*/
*statusCode = 0x0200;
/*
* iSCSI Initiator error
*/
} else {
*statusCode = 0x0300;
/*
* iSCSI Target error
*/
}
}
return (iscsiAuthStatusNoError);
}
int
{
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusError);
}
return (iscsiAuthStatusNoError);
}
const char *
{
const char *s;
switch (debugStatus) {
s = "Debug status not set";
break;
s = "Authentication request passed";
break;
s = "Authentication not enabled";
break;
s = "Authentication request failed";
break;
s = "AuthMethod bad";
break;
s = "CHAP algorithm bad";
break;
s = "Decrypt password failed";
break;
s = "Local password too short with no IPSec";
break;
s = "Unexpected error from authentication server";
break;
s = "Authentication request status bad";
break;
s = "Authentication pass status not valid";
break;
s = "Same key set more than once on send";
break;
s = "Key value too long on send";
break;
s = "Too much data on send";
break;
s = "AuthMethod key expected";
break;
s = "CHAP algorithm key expected";
break;
s = "CHAP identifier expected";
break;
s = "CHAP challenge expected";
break;
s = "CHAP response expected";
break;
s = "CHAP username expected";
break;
s = "AuthMethod key not present";
break;
s = "AuthMethod negotiation failed";
break;
s = "AuthMethod negotiated to none";
break;
s = "CHAP algorithm negotiation failed";
break;
s = "CHAP challange reflected";
break;
s = "Local password same as remote";
break;
s = "Local password not set";
break;
s = "CHAP identifier bad";
break;
s = "CHAP challenge bad";
break;
s = "CHAP response bad";
break;
s = "Unexpected key present";
break;
s = "T bit set on response, but not on previous message";
break;
s = "T bit set on response, but authenticaton not complete";
break;
s = "Message count limit reached on receive";
break;
s = "Same key set more than once on receive";
break;
s = "Key value too long on receive";
break;
s = "Too much data on receive";
break;
default:
s = "Unknown error";
}
return (s);
}