📄 iscsiauthclient.c
字号:
length = 0; while (*keyValue != '\0' && *keyValue != ',') { client->scratchKeyValue[length++] = *keyValue++; } if (*keyValue == ',') keyValue++; client->scratchKeyValue[length++] = '\0'; if (iscsiAuthClientTextToNumber(client->scratchKeyValue, &number)) { continue; } for (i = 0; i < client->chapAlgorithmCount; i++) { if (number == (unsigned long)client->chapAlgorithmList[i]) { client->negotiatedChapAlgorithm = number; return; } } } client->negotiatedChapAlgorithm = iscsiAuthOptionReject;}static voidiscsiAuthClientSetChapAlgorithmKey( IscsiAuthClient *client, unsigned int chapAlgorithmCount, int *chapAlgorithmList){ unsigned int i; if (chapAlgorithmCount == 0) { iscsiAuthClientSetKeyValue( &client->sendKeyBlock, iscsiAuthKeyTypeChapAlgorithm, NULL); return; } if (chapAlgorithmCount == 1 && ((chapAlgorithmList[0] == iscsiAuthOptionNotPresent) || (chapAlgorithmList[0] == iscsiAuthOptionReject))) { iscsiAuthClientSetKeyValue( &client->sendKeyBlock, iscsiAuthKeyTypeChapAlgorithm, NULL); return; } for (i = 0; i < chapAlgorithmCount; i++) { char s[20]; iscsiAuthClientNumberToText(chapAlgorithmList[i], s, sizeof(s)); if (i == 0) { strcpy(client->scratchKeyValue, s); } else { strcat(client->scratchKeyValue, ","); strcat(client->scratchKeyValue, s); } } iscsiAuthClientSetKeyValue( &client->sendKeyBlock, iscsiAuthKeyTypeChapAlgorithm, client->scratchKeyValue);}static voidiscsiAuthClientNextPhase(IscsiAuthClient *client){ switch (client->phase) { case iscsiAuthPhaseConfigure: client->phase = iscsiAuthPhaseNegotiate; break; case iscsiAuthPhaseNegotiate: client->phase = iscsiAuthPhaseAuthenticate; if (client->negotiatedAuthMethod == iscsiAuthOptionReject || client->negotiatedAuthMethod == iscsiAuthOptionNotPresent || client->negotiatedAuthMethod == iscsiAuthOptionNone) { client->localState = iscsiAuthLocalStateDone; client->remoteState = iscsiAuthRemoteStateDone; if (client->authRemote) { client->remoteAuthStatus = iscsiAuthStatusFail; client->phase = iscsiAuthPhaseDone; } else { client->remoteAuthStatus = iscsiAuthStatusPass; } switch (client->negotiatedAuthMethod) { case iscsiAuthOptionReject: client->debugStatus = iscsiAuthDebugStatusAuthMethodReject; break; case iscsiAuthOptionNotPresent: client->debugStatus = iscsiAuthDebugStatusAuthMethodNotPresent; break; case iscsiAuthOptionNone: client->debugStatus = iscsiAuthDebugStatusAuthMethodNone; } } else if (client->negotiatedAuthMethod == iscsiAuthMethodChap) { client->localState = iscsiAuthLocalStateSendAlgorithm; client->remoteState = iscsiAuthRemoteStateSendAlgorithm; } else { client->localState = iscsiAuthLocalStateDone; client->remoteState = iscsiAuthRemoteStateDone; client->remoteAuthStatus = iscsiAuthStatusFail; client->debugStatus = iscsiAuthDebugStatusAuthMethodBad; } break; case iscsiAuthPhaseAuthenticate: client->phase = iscsiAuthPhaseDone; break; case iscsiAuthPhaseDone: case iscsiAuthPhaseError: default: client->phase = iscsiAuthPhaseError; }}static voidiscsiAuthClientLocalAuthentication(IscsiAuthClient *client){ unsigned int identifier; unsigned char challengeData[iscsiAuthStringMaxLength]; unsigned int challengeLength = sizeof(challengeData); unsigned char responseData[iscsiAuthChapResponseLength]; unsigned long number; int status; IscsiAuthDebugStatus debugStatus; const char *chapIdentifierKeyValue; const char *chapChallengeKeyValue; switch (client->localState) { case iscsiAuthLocalStateSendAlgorithm: if (client->nodeType == iscsiAuthNodeTypeInitiator) { iscsiAuthClientSetChapAlgorithmKey( client, client->chapAlgorithmCount, client->chapAlgorithmList); client->localState = iscsiAuthLocalStateRecvAlgorithm; break; } /* Fall through */ case iscsiAuthLocalStateRecvAlgorithm: iscsiAuthClientCheckChapAlgorithmKey(client); if (client->nodeType == iscsiAuthNodeTypeTarget) { iscsiAuthClientSetChapAlgorithmKey( client, 1, &client->negotiatedChapAlgorithm); } /* Make sure only supported CHAP algorithm is used. */ if (client->negotiatedChapAlgorithm == iscsiAuthOptionNotPresent) { client->localState = iscsiAuthLocalStateError; client->debugStatus = iscsiAuthDebugStatusChapAlgorithmExpected; break; } else if (client->negotiatedChapAlgorithm == iscsiAuthOptionReject) { client->localState = iscsiAuthLocalStateError; client->debugStatus = iscsiAuthDebugStatusChapAlgorithmReject; break; } else if (client->negotiatedChapAlgorithm != iscsiAuthChapAlgorithmMd5) { client->localState = iscsiAuthLocalStateError; client->debugStatus = iscsiAuthDebugStatusChapAlgorithmBad; break; } if (client->nodeType == iscsiAuthNodeTypeTarget) { client->localState = iscsiAuthLocalStateRecvChallenge; break; } /* Fall through */ case iscsiAuthLocalStateRecvChallenge: chapIdentifierKeyValue = iscsiAuthClientGetKeyValue( &client->recvKeyBlock, iscsiAuthKeyTypeChapIdentifier); chapChallengeKeyValue = iscsiAuthClientGetKeyValue( &client->recvKeyBlock, iscsiAuthKeyTypeChapChallenge); if (client->nodeType == iscsiAuthNodeTypeTarget) { if (!chapIdentifierKeyValue && !chapChallengeKeyValue) { client->localState = iscsiAuthLocalStateDone; break; } } if (!chapIdentifierKeyValue) { client->localState = iscsiAuthLocalStateError; client->debugStatus = iscsiAuthDebugStatusChapIdentifierExpected; break; } if (!chapChallengeKeyValue) { client->localState = iscsiAuthLocalStateError; client->debugStatus = iscsiAuthDebugStatusChapChallengeExpected; break; } status = iscsiAuthClientTextToNumber(chapIdentifierKeyValue, &number); if (status || (255 < number)) { client->localState = iscsiAuthLocalStateError; client->debugStatus = iscsiAuthDebugStatusChapIdentifierBad; break; } identifier = number; status = iscsiAuthClientTextToData( chapChallengeKeyValue, challengeData, &challengeLength); if (status) { client->localState = iscsiAuthLocalStateError; client->debugStatus = iscsiAuthDebugStatusChapChallengeBad; break; } if (client->nodeType == iscsiAuthNodeTypeTarget && challengeLength == iscsiAuthChapChallengeLength && memcmp(challengeData, client->chapChallengeData, iscsiAuthChapChallengeLength) == 0) { client->localState = iscsiAuthLocalStateError; client->debugStatus = iscsiAuthDebugStatusChapChallengeReflected; break; } debugStatus = iscsiAuthClientChapComputeResponse( client, client->passwordData, client->passwordLength, identifier, challengeData, challengeLength, responseData); if (debugStatus != iscsiAuthDebugStatusNotSet) { client->localState = iscsiAuthLocalStateError; client->debugStatus = debugStatus; break; } iscsiAuthClientDataToText( client->base64, responseData, iscsiAuthChapResponseLength, client->scratchKeyValue); iscsiAuthClientSetKeyValue( &client->sendKeyBlock, iscsiAuthKeyTypeChapResponse, client->scratchKeyValue); iscsiAuthClientSetKeyValue( &client->sendKeyBlock, iscsiAuthKeyTypeChapUsername, client->username); client->localState = iscsiAuthLocalStateDone; break; case iscsiAuthLocalStateDone: break; case iscsiAuthLocalStateError: default: client->phase = iscsiAuthPhaseError; }}static voidiscsiAuthClientRemoteAuthentication(IscsiAuthClient *client){ unsigned char idData[1]; unsigned char responseData[iscsiAuthStringMaxLength]; unsigned int responseLength = sizeof(responseData); int authStatus; int status; const char *chapResponseKeyValue; const char *chapUsernameKeyValue; switch (client->remoteState) { case iscsiAuthRemoteStateSendAlgorithm: if (client->nodeType == iscsiAuthNodeTypeInitiator) { client->remoteState = iscsiAuthRemoteStateSendChallenge; break; } /* Fall through */ case iscsiAuthRemoteStateSendChallenge: if (!client->authRemote) { client->remoteAuthStatus = iscsiAuthStatusPass; client->debugStatus = iscsiAuthDebugStatusAuthRemoteFalse; client->remoteState = iscsiAuthRemoteStateDone; break; } iscsiAuthRandomSetData(idData, 1); client->chapIdentifier = idData[0]; iscsiAuthClientNumberToText( client->chapIdentifier, client->scratchKeyValue, sizeof(client->scratchKeyValue)); iscsiAuthClientSetKeyValue( &client->sendKeyBlock, iscsiAuthKeyTypeChapIdentifier, client->scratchKeyValue); iscsiAuthRandomSetData( client->chapChallengeData, iscsiAuthChapChallengeLength); iscsiAuthClientDataToText( client->base64, client->chapChallengeData, iscsiAuthChapChallengeLength, client->scratchKeyValue); iscsiAuthClientSetKeyValue( &client->sendKeyBlock, iscsiAuthKeyTypeChapChallenge, client->scratchKeyValue); client->remoteState = iscsiAuthRemoteStateRecvResponse; break; case iscsiAuthRemoteStateRecvResponse: chapResponseKeyValue = iscsiAuthClientGetKeyValue( &client->recvKeyBlock, iscsiAuthKeyTypeChapResponse); chapUsernameKeyValue = iscsiAuthClientGetKeyValue( &client->recvKeyBlock, iscsiAuthKeyTypeChapUsername); if (!chapResponseKeyValue) { client->remoteState = iscsiAuthRemoteStateError; client->debugStatus = iscsiAuthDebugStatusChapResponseExpected; break; } if (!chapUsernameKeyValue) { client->remoteState = iscsiAuthRemoteStateError; client->debugStatus = iscsiAuthDebugStatusChapUsernameExpected; break; } status = iscsiAuthClientTextToData( chapResponseKeyValue, responseData, &responseLength); if (status) { client->remoteState = iscsiAuthRemoteStateError; client->debugStatus = iscsiAuthDebugStatusChapResponseBad; break; } strcpy(client->chapUsername, chapUsernameKeyValue); authStatus = iscsiAuthClientChapAuthRequest( client, client->chapUsername, client->chapIdentifier, client->chapChallengeData, iscsiAuthChapChallengeLength, responseData, responseLength); if (authStatus == iscsiAuthStatusInProgress) { iscsiAuthClientGlobalStats.requestSent++; client->remoteState = iscsiAuthRemoteStateAuthRequest; break; } client->remoteAuthStatus = (IscsiAuthStatus)authStatus; client->authResponseFlag = TRUE; /* Fall through */ case iscsiAuthRemoteStateAuthRequest: /* client->remoteAuthStatus already set */ if (client->remoteAuthStatus == iscsiAuthStatusPass) { client->debugStatus = iscsiAuthDebugStatusAuthPass; } else if (client->remoteAuthStatus == iscsiAuthStatusFail) { client->debugStatus = iscsiAuthDebugStatusAuthFail; } else { client->remoteAuthStatus = iscsiAuthStatusFail; client->debugStatus = iscsiAuthDebugStatusAuthStatusBad; } client->remoteState = iscsiAuthRemoteStateDone; /* Fall through */ case iscsiAuthRemoteStateDone: break; case iscsiAuthRemoteStateError: default: client->phase = iscsiAuthPhaseError; }}static voidiscsiAuthClientHandshake(IscsiAuthClient *client){ if (client->phase == iscsiAuthPhaseDone) { /* * Should only happen if authentication * protocol error occured. */ return; } if (client->remoteState == iscsiAuthRemoteStateAuthRequest) { /* * Defer until authentication response received * from internal authentication service. */ return; } if (client->nodeType == iscsiAuthNodeTypeInitiator) { /* * Target should only have set T bit on response if * initiator set it on previous command. */ if (client->recvKeyBlock.transitBit && !client->transitBitSentFlag) { client->remoteAuthStatus = iscsiAuthStatusFail; client->phase = iscsiAuthPhaseDone; client->debugStatus = iscsiAuthDebugStatusTbitSetIllegal; return; } } if (client->phase == iscsiAuthPhaseNegotiate) { /* * Should only happen if waiting for peer * to send AuthMethod key or set Transit Bit. */ if (client->nodeType == iscsiAuthNodeTypeInitiator) { client->sendKeyBlock.transitBit = TRUE; } return; } if (client->remoteState == iscsiAuthRemoteStateRecvResponse || client->remoteState == iscsiAuthRemoteStateDone) { if (client->nodeType == iscsiAuthNodeTypeInitiator) { if (client->recvKeyBlock.transitBit) { if (client->remoteState != iscsiAuthRemoteStateDone) { goto recvTransitBitError; } iscsiAuthClientNextPhase(client); } else { client->sendKeyBlock.transitBit = TRUE; } } else { if (client->remoteState == iscsiAuthRemoteStateDone && client->remoteAuthStatus != iscsiAuthStatusPass) { /* * Authentication failed, don't do T bit handshake. */ iscsiAuthClientNextPhase(client); } else { /* * Target can only set T bit on response if * initiator set it on current command. */ if (client->recvKeyBlock.transitBit) { client->sendKeyBlock.transitBit = TRUE; iscsiAuthClientNextPhase(client); } } } } else { if (client->nodeType == iscsiAuthNodeTypeInitiator) { if (client->recvKeyBlock.transitBit) { goto recvTransitBitError; } } } return;recvTransitBitError: /* * Target set T bit on response but * initiator was not done with authentication. */ client->remoteAuthStatus = iscsiAuthStatusFail; client->phase = iscsiAuthPhaseDone; client->debugStatus = iscsiAuthDebugStatusTbitSetPremature;}static intiscsiAuthClientRecvEndStatus(IscsiAuthClient *client){ int authStatus; int keyType; if (client->phase == iscsiAuthPhaseError) { return iscsiAuthStatusError; } if (client->phase == iscsiAuthPhaseDone) { /* Perform sanity check against configured parameters. */ if (client->authRemote && !client->authResponseFlag && client->remoteAuthStatus == iscsiAuthStatusPass) { client->remoteAuthStatus = iscsiAuthStatusFail; client->debugStatus = iscsiAuthDebugStatusAuthPassNotValid; } authStatus = client->remoteAuthStatus; } else if (client->remoteState == iscsiAuthRemoteStateAuthRequest) { authStatus = iscsiAuthStatusInProgress; } else { authStatus = iscsiAuthStatusContinue; } if (authStatus != iscsiAuthStatusInProgress) { client->recvInProgressFlag = FALSE; } if (authStatus == iscsiAuthStatusContinue || authStatus == iscsiAuthStatusPass) { if (client->sendKeyBlock.duplicateSet) { client->remoteAuthStatus = iscsiAuthStatusFail; client->phase = iscsiAuthPhaseDone; client->debugStatus = iscsiAuthDebugStatusSendDuplicateSetKeyValue; authStatus = iscsiAuthStatusFail; } else if (client->sendKeyBlock.stringTooLong) { client->remoteAuthStatus = iscsiAuthStatusFail; client->phase = iscsiAuthPhaseDone; client->debugStatus = iscsiAuthDebugStatusSendStringTooLong; authStatus = iscsiAuthStatusFail; } else if (client->sendKeyBlock.tooMuchData) { client->remoteAuthStatus = iscsiAuthStatusFail; client->phase = iscsiAuthPhaseDone; client->debugStatus = iscsiAuthDebugStatusSendTooMuchData; authStatus = iscsiAuthStatusFail; } else { /* Check that all incoming keys have been processed. */ for (keyType = iscsiAuthKeyTypeFirst; keyType < iscsiAuthKeyTypeMaxCount; keyType++) { if (client->recvKeyBlock.key[keyType].present && !client->recvKeyBlock.key[keyType].processed) { break; } } if (keyType < iscsiAuthKeyTypeMaxCount) { client->remoteAuthStatus = iscsiAuthStatusFail; client->phase = iscsiAuthPhaseDone; client->debugStatus = iscsiAuthDebugStatusUnexpectedKeyPresent; authStatus = iscsiAuthStatusFail; } } } if (authStatus != iscsiAuthStatusPass && authStatus != iscsiAuthStatusContinue && authStatus != iscsiAuthStatusInProgress) { /* Suppress send keys on error. */ iscsiAuthClientInitKeyBlock(&client->sendKeyBlock); } return authStatus;}intiscsiAuthClientRecvBegin(IscsiAuthClient *client){ if (!client || client->signature != iscsiAuthClientSignature) { return iscsiAuthStatusError; } if (client->phase == iscsiAuthPhaseError) { return iscsiAuthStatusError; } if (client->phase == iscsiAuthPhaseDone) { client->phase = iscsiAuthPhaseError; return iscsiAuthStatusError; } if (client->recvInProgressFlag) { client->phase = iscsiAuthPhaseError; return iscsiAuthStatusError; } client->recvInProgressFlag = TRUE; if (client->phase == iscsiAuthPhaseConfigure) { iscsiAuthClientNextPhase(client);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -