EAP peer: Improve failure reporting from METHOD with no eapRespData
One of the RFC 4137 state transitions (METHOD -> FAILURE) had been forgotten and this could result in EAP peer method processing not reporting failure immediately and instead, remain stuck waiting for the connection to time out. Fix this by adding the methodState == DONE && decision == FAIL case to allow immediate reporting of failures. The condition from RFC 4137 as-is would cause problems for number of the existing EAP method implementations since they use that in places where the final message before EAP-Failure should really be sent to the EAP server (e.g., WSC_Done in EAP-WSC). Address this by includng eapRespData == NULL as an additional constraint for entering FAILURE state directly from METHOD. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
7271ee8769
commit
5f01c3c84a
1 changed files with 18 additions and 4 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* EAP peer state machines (RFC 4137)
|
||||
* Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -388,10 +388,11 @@ SM_STATE(EAP, METHOD)
|
|||
sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret,
|
||||
eapReqData);
|
||||
wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s "
|
||||
"methodState=%s decision=%s",
|
||||
"methodState=%s decision=%s eapRespData=%p",
|
||||
ret.ignore ? "TRUE" : "FALSE",
|
||||
eap_sm_method_state_txt(ret.methodState),
|
||||
eap_sm_decision_txt(ret.decision));
|
||||
eap_sm_decision_txt(ret.decision),
|
||||
sm->eapRespData);
|
||||
|
||||
sm->ignore = ret.ignore;
|
||||
if (sm->ignore)
|
||||
|
@ -432,8 +433,10 @@ SM_STATE(EAP, SEND_RESPONSE)
|
|||
sm->lastId = sm->reqId;
|
||||
sm->lastRespData = wpabuf_dup(sm->eapRespData);
|
||||
eapol_set_bool(sm, EAPOL_eapResp, TRUE);
|
||||
} else
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "EAP: No eapRespData available");
|
||||
sm->lastRespData = NULL;
|
||||
}
|
||||
eapol_set_bool(sm, EAPOL_eapReq, FALSE);
|
||||
eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
|
||||
}
|
||||
|
@ -724,8 +727,19 @@ static void eap_peer_sm_step_local(struct eap_sm *sm)
|
|||
SM_ENTER(EAP, SEND_RESPONSE);
|
||||
break;
|
||||
case EAP_METHOD:
|
||||
/*
|
||||
* Note: RFC 4137 uses methodState == DONE && decision == FAIL
|
||||
* as the condition. eapRespData == NULL here is used to allow
|
||||
* final EAP method response to be sent without having to change
|
||||
* all methods to either use methodState MAY_CONT or leaving
|
||||
* decision to something else than FAIL in cases where the only
|
||||
* expected response is EAP-Failure.
|
||||
*/
|
||||
if (sm->ignore)
|
||||
SM_ENTER(EAP, DISCARD);
|
||||
else if (sm->methodState == METHOD_DONE &&
|
||||
sm->decision == DECISION_FAIL && !sm->eapRespData)
|
||||
SM_ENTER(EAP, FAILURE);
|
||||
else
|
||||
SM_ENTER(EAP, SEND_RESPONSE);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue