diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index 3439c2dfc..98abd4ef7 100644 --- a/src/eap_peer/eap.c +++ b/src/eap_peer/eap.c @@ -1,6 +1,6 @@ /* * EAP peer state machines (RFC 4137) - * Copyright (c) 2004-2012, Jouni Malinen + * Copyright (c) 2004-2014, Jouni Malinen * * 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;