SM_STATE(EAP, INITIALIZE) { SM_ENTRY(EAP, INITIALIZE); if (sm->fast_reauth && sm->m && sm->m->has_reauth_data && sm->m->has_reauth_data(sm, sm->eap_method_priv)) { wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for " "fast reauthentication"); sm->m->deinit_for_reauth(sm, sm->eap_method_priv); } else { eap_deinit_prev_method(sm, "INITIALIZE"); } sm->selectedMethod = EAP_TYPE_NONE; sm->methodState = METHOD_NONE; sm->allowNotifications = TRUE; sm->decision = DECISION_FAIL; eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); eapol_set_bool(sm, EAPOL_eapFail, FALSE); free(sm->eapKeyData); sm->eapKeyData = NULL; sm->eapKeyAvailable = FALSE; eapol_set_bool(sm, EAPOL_eapRestart, FALSE); sm->lastId = -1; /* new session - make sure this does not match with * the first EAP-Packet */ /* draft-ietf-eap-statemachine-02.pdf does not reset eapResp and * eapNoResp here. However, this seemed to be able to trigger cases * where both were set and if EAPOL state machine uses eapNoResp first, * it may end up not sending a real reply correctly. This occurred * when the workaround in FAIL state set eapNoResp = TRUE.. Maybe that * workaround needs to be fixed to do something else(?) */ eapol_set_bool(sm, EAPOL_eapResp, FALSE); eapol_set_bool(sm, EAPOL_eapNoResp, FALSE); sm->num_rounds = 0; }
SM_STATE(EAP, INITIALIZE) { SM_ENTRY(EAP, INITIALIZE); sm->currentId = -1; eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); eapol_set_bool(sm, EAPOL_eapFail, FALSE); eapol_set_bool(sm, EAPOL_eapTimeout, FALSE); free(sm->eapKeyData); sm->eapKeyData = NULL; sm->eapKeyDataLen = 0; /* eapKeyAvailable = FALSE */ eapol_set_bool(sm, EAPOL_eapRestart, FALSE); /* This is not defined in draft-ietf-eap-statemachine-05.txt, but * method state needs to be reseted here so that it does not remain in * success state when re-authentication starts. */ if (sm->m && sm->eap_method_priv) { sm->m->reset(sm, sm->eap_method_priv); sm->eap_method_priv = NULL; } sm->m = NULL; sm->user_eap_method_index = 0; if (sm->backend_auth) { sm->currentMethod = EAP_TYPE_NONE; /* parse rxResp, respId, respMethod */ eap_sm_parseEapResp(sm, sm->eapRespData, sm->eapRespDataLen); if (sm->rxResp) { sm->currentId = sm->respId; } } }
SM_STATE(EAP, RETRANSMIT) { SM_ENTRY(EAP, RETRANSMIT); #if 0 /* original */ /* TODO: Is this needed since EAPOL state machines take care of * retransmit? */ #else /* Hmmm... EAPOL s.m. isn't retransmitting. Do it here. * Hope this is the right place to do it. * Maybe it really should be done in eapol. */ if (++sm->retransCount > sm->MaxRetrans) { } else if (sm->lastReqData) { eapol_set_eapReqData(sm, sm->lastReqData, sm->lastReqDataLen); eapol_set_bool(sm, EAPOL_eapResp, FALSE); eapol_set_bool(sm, EAPOL_eapReq, TRUE); } else { wpa_printf(MSG_INFO, "EAP: RETRANSMIT - no lastReqData"); eapol_set_bool(sm, EAPOL_eapResp, FALSE); eapol_set_bool(sm, EAPOL_eapReq, FALSE); eapol_set_bool(sm, EAPOL_eapNoReq, TRUE); } #endif }
SM_STATE(EAP, FAILURE) { SM_ENTRY(EAP, FAILURE); eapol_set_bool(sm, EAPOL_eapFail, TRUE); /* draft-ietf-eap-statemachine-02.pdf does not clear eapReq here, but * this seems to be required to avoid processing the same request * twice when state machine is initialized. */ eapol_set_bool(sm, EAPOL_eapReq, FALSE); /* draft-ietf-eap-statemachine-02.pdf does not set eapNoResp here. * However, either eapResp or eapNoResp is required to be set after * processing the received EAP frame. */ eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); }
SM_STATE(EAP, SUCCESS) { SM_ENTRY(EAP, SUCCESS); if (sm->eapKeyData != NULL) sm->eapKeyAvailable = TRUE; eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); /* draft-ietf-eap-statemachine-02.pdf does not clear eapReq here, but * this seems to be required to avoid processing the same request * twice when state machine is initialized. */ eapol_set_bool(sm, EAPOL_eapReq, FALSE); /* draft-ietf-eap-statemachine-02.pdf does not set eapNoResp here, but * this seems to be required to get EAPOL Supplicant backend state * machine into SUCCESS state. In addition, either eapResp or eapNoResp * is required to be set after processing the received EAP frame. */ eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); }
SM_STATE(EAP, SEND_RESPONSE) { SM_ENTRY(EAP, SEND_RESPONSE); free(sm->lastRespData); if (sm->eapRespData) { if (sm->workaround) memcpy(sm->last_md5, sm->req_md5, 16); sm->lastId = sm->reqId; sm->lastRespData = malloc(sm->eapRespDataLen); if (sm->lastRespData) { memcpy(sm->lastRespData, sm->eapRespData, sm->eapRespDataLen); sm->lastRespDataLen = sm->eapRespDataLen; } eapol_set_bool(sm, EAPOL_eapResp, TRUE); } else sm->lastRespData = NULL; eapol_set_bool(sm, EAPOL_eapReq, FALSE); eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); }
SM_STATE(EAP, SEND_REQUEST) { SM_ENTRY(EAP, SEND_REQUEST); sm->retransCount = 0; if (sm->eapReqData) { eapol_set_eapReqData(sm, sm->eapReqData, sm->eapReqDataLen); free(sm->lastReqData); sm->lastReqData = sm->eapReqData; sm->lastReqDataLen = sm->eapReqDataLen; sm->eapReqData = NULL; sm->eapReqDataLen = 0; eapol_set_bool(sm, EAPOL_eapResp, FALSE); eapol_set_bool(sm, EAPOL_eapReq, TRUE); } else { wpa_printf(MSG_INFO, "EAP: SEND_REQUEST - no eapReqData"); eapol_set_bool(sm, EAPOL_eapResp, FALSE); eapol_set_bool(sm, EAPOL_eapReq, FALSE); eapol_set_bool(sm, EAPOL_eapNoReq, TRUE); } }
SM_STATE(EAP, INITIALIZE) { SM_ENTRY(EAP, INITIALIZE); sm->currentId = -1; eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); eapol_set_bool(sm, EAPOL_eapFail, FALSE); eapol_set_bool(sm, EAPOL_eapTimeout, FALSE); free(sm->eapKeyData); sm->eapKeyData = NULL; sm->eapKeyDataLen = 0; /* eapKeyAvailable = FALSE */ eapol_set_bool(sm, EAPOL_eapRestart, FALSE); /* * This is not defined in RFC 4137, but method state needs to be * reseted here so that it does not remain in success state when * re-authentication starts. */ if (sm->m && sm->eap_method_priv) { sm->m->reset(sm, sm->eap_method_priv); sm->eap_method_priv = NULL; } sm->m = NULL; sm->user_eap_method_index = 0; if (sm->backend_auth) { sm->currentMethod = EAP_TYPE_NONE; /* parse rxResp, respId, respMethod */ eap_sm_parseEapResp(sm, sm->eapRespData, sm->eapRespDataLen); if (sm->rxResp) { sm->currentId = sm->respId; wpa_printf(MSG_DEBUG, "SM_STATE EAP INITIALIZE new currentId %d", sm->currentId); } } sm->num_rounds = 0; sm->method_pending = METHOD_PENDING_NONE; }
SM_STATE(EAP, FAILURE) { SM_ENTRY(EAP, FAILURE); free(sm->eapReqData); sm->eapReqData = eap_sm_buildFailure(sm, sm->currentId, &sm->eapReqDataLen); if (sm->eapReqData) { eapol_set_eapReqData(sm, sm->eapReqData, sm->eapReqDataLen); free(sm->eapReqData); sm->eapReqData = NULL; sm->eapReqDataLen = 0; } free(sm->lastReqData); sm->lastReqData = NULL; sm->lastReqDataLen = 0; eapol_set_bool(sm, EAPOL_eapFail, TRUE); }
SM_STATE(EAP, SUCCESS) { SM_ENTRY(EAP, SUCCESS); free(sm->eapReqData); sm->eapReqData = eap_sm_buildSuccess(sm, sm->currentId, &sm->eapReqDataLen); if (sm->eapReqData) { eapol_set_eapReqData(sm, sm->eapReqData, sm->eapReqDataLen); free(sm->eapReqData); sm->eapReqData = NULL; sm->eapReqDataLen = 0; } free(sm->lastReqData); sm->lastReqData = NULL; sm->lastReqDataLen = 0; if (sm->eapKeyData) { eapol_set_eapKeyData(sm, sm->eapKeyData, sm->eapKeyDataLen); } eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); }
SM_STATE(EAP, DISCARD) { SM_ENTRY(EAP, DISCARD); eapol_set_bool(sm, EAPOL_eapReq, FALSE); eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); }
SM_STATE(EAP, TIMEOUT_FAILURE) { SM_ENTRY(EAP, TIMEOUT_FAILURE); eapol_set_bool(sm, EAPOL_eapTimeout, TRUE); }