EAP server: Handle EAP method initialization failures more cleanly

Allow another EAP method to be tried if one of the enabled methods
fails. If all the remaining methods fail, reject connection by adding a
new METHOD_REQUEST -> FAILURE transition. Previously, this case resulted
in the state machine trying to send a message when none was available
and then waiting for a following event until timeout.

Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2013-11-24 18:26:05 +02:00
parent 59d343858d
commit d9c753b4f5

View file

@ -343,6 +343,7 @@ SM_STATE(EAP, PROPOSE_METHOD)
SM_ENTRY(EAP, PROPOSE_METHOD); SM_ENTRY(EAP, PROPOSE_METHOD);
try_another_method:
type = eap_sm_Policy_getNextMethod(sm, &vendor); type = eap_sm_Policy_getNextMethod(sm, &vendor);
if (vendor == EAP_VENDOR_IETF) if (vendor == EAP_VENDOR_IETF)
sm->currentMethod = type; sm->currentMethod = type;
@ -360,8 +361,14 @@ SM_STATE(EAP, PROPOSE_METHOD)
"method %d", sm->currentMethod); "method %d", sm->currentMethod);
sm->m = NULL; sm->m = NULL;
sm->currentMethod = EAP_TYPE_NONE; sm->currentMethod = EAP_TYPE_NONE;
goto try_another_method;
} }
} }
if (sm->m == NULL) {
wpa_printf(MSG_DEBUG, "EAP: Could not find suitable EAP method");
sm->decision = DECISION_FAILURE;
return;
}
if (sm->currentMethod == EAP_TYPE_IDENTITY || if (sm->currentMethod == EAP_TYPE_IDENTITY ||
sm->currentMethod == EAP_TYPE_NOTIFICATION) sm->currentMethod == EAP_TYPE_NOTIFICATION)
sm->methodState = METHOD_CONTINUE; sm->methodState = METHOD_CONTINUE;
@ -702,6 +709,15 @@ SM_STEP(EAP)
SM_ENTER(EAP, METHOD_RESPONSE); SM_ENTER(EAP, METHOD_RESPONSE);
break; break;
case EAP_METHOD_REQUEST: case EAP_METHOD_REQUEST:
if (sm->m == NULL) {
/*
* This transition is not mentioned in RFC 4137, but it
* is needed to handle cleanly a case where EAP method
* initialization fails.
*/
SM_ENTER(EAP, FAILURE);
break;
}
SM_ENTER(EAP, SEND_REQUEST); SM_ENTER(EAP, SEND_REQUEST);
break; break;
case EAP_METHOD_RESPONSE: case EAP_METHOD_RESPONSE: