📄 eap.c
字号:
{ SM_ENTRY(EAP, RETRANSMIT2); sm->retransCount++; if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) { if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0) sm->eap_if.eapReq = TRUE; }}SM_STATE(EAP, RECEIVED2){ SM_ENTRY(EAP, RECEIVED2); /* parse rxResp, respId, respMethod */ eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);}SM_STATE(EAP, DISCARD2){ SM_ENTRY(EAP, DISCARD2); sm->eap_if.eapResp = FALSE; sm->eap_if.eapNoReq = TRUE;}SM_STATE(EAP, SEND_REQUEST2){ SM_ENTRY(EAP, SEND_REQUEST2); sm->retransCount = 0; if (sm->eap_if.eapReqData) { if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0) { sm->eap_if.eapResp = FALSE; sm->eap_if.eapReq = TRUE; } else { sm->eap_if.eapResp = FALSE; sm->eap_if.eapReq = FALSE; } } else { wpa_printf(MSG_INFO, "EAP: SEND_REQUEST2 - no eapReqData"); sm->eap_if.eapResp = FALSE; sm->eap_if.eapReq = FALSE; sm->eap_if.eapNoReq = TRUE; }}SM_STATE(EAP, AAA_REQUEST){ SM_ENTRY(EAP, AAA_REQUEST); if (sm->eap_if.eapRespData == NULL) { wpa_printf(MSG_INFO, "EAP: AAA_REQUEST - no eapRespData"); return; } /* * if (respMethod == IDENTITY) * aaaIdentity = eapRespData * This is already taken care of by the EAP-Identity method which * stores the identity into sm->identity. */ eap_copy_buf(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData);}SM_STATE(EAP, AAA_RESPONSE){ SM_ENTRY(EAP, AAA_RESPONSE); eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); sm->currentId = eap_sm_getId(sm->eap_if.eapReqData); sm->methodTimeout = sm->eap_if.aaaMethodTimeout;}SM_STATE(EAP, AAA_IDLE){ SM_ENTRY(EAP, AAA_IDLE); sm->eap_if.aaaFail = FALSE; sm->eap_if.aaaSuccess = FALSE; sm->eap_if.aaaEapReq = FALSE; sm->eap_if.aaaEapNoReq = FALSE; sm->eap_if.aaaEapResp = TRUE;}SM_STATE(EAP, TIMEOUT_FAILURE2){ SM_ENTRY(EAP, TIMEOUT_FAILURE2); sm->eap_if.eapTimeout = TRUE;}SM_STATE(EAP, FAILURE2){ SM_ENTRY(EAP, FAILURE2); eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); sm->eap_if.eapFail = TRUE;}SM_STATE(EAP, SUCCESS2){ SM_ENTRY(EAP, SUCCESS2); eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); sm->eap_if.eapKeyAvailable = sm->eap_if.aaaEapKeyAvailable; if (sm->eap_if.aaaEapKeyAvailable) { EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData); } else { os_free(sm->eap_if.eapKeyData); sm->eap_if.eapKeyData = NULL; sm->eap_if.eapKeyDataLen = 0; } sm->eap_if.eapSuccess = TRUE; /* * Start reauthentication with identity request even though we know the * previously used identity. This is needed to get reauthentication * started properly. */ sm->start_reauth = TRUE;}SM_STEP(EAP){ if (sm->eap_if.eapRestart && sm->eap_if.portEnabled) SM_ENTER_GLOBAL(EAP, INITIALIZE); else if (!sm->eap_if.portEnabled) SM_ENTER_GLOBAL(EAP, DISABLED); else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { wpa_printf(MSG_DEBUG, "EAP: more than %d " "authentication rounds - abort", EAP_MAX_AUTH_ROUNDS); sm->num_rounds++; SM_ENTER_GLOBAL(EAP, FAILURE); } } else switch (sm->EAP_state) { case EAP_INITIALIZE: if (sm->backend_auth) { if (!sm->rxResp) SM_ENTER(EAP, SELECT_ACTION); else if (sm->rxResp && (sm->respMethod == EAP_TYPE_NAK || (sm->respMethod == EAP_TYPE_EXPANDED && sm->respVendor == EAP_VENDOR_IETF && sm->respVendorMethod == EAP_TYPE_NAK))) SM_ENTER(EAP, NAK); else SM_ENTER(EAP, PICK_UP_METHOD); } else { SM_ENTER(EAP, SELECT_ACTION); } break; case EAP_PICK_UP_METHOD: if (sm->currentMethod == EAP_TYPE_NONE) { SM_ENTER(EAP, SELECT_ACTION); } else { SM_ENTER(EAP, METHOD_RESPONSE); } break; case EAP_DISABLED: if (sm->eap_if.portEnabled) SM_ENTER(EAP, INITIALIZE); break; case EAP_IDLE: if (sm->eap_if.retransWhile == 0) SM_ENTER(EAP, RETRANSMIT); else if (sm->eap_if.eapResp) SM_ENTER(EAP, RECEIVED); break; case EAP_RETRANSMIT: if (sm->retransCount > sm->MaxRetrans) SM_ENTER(EAP, TIMEOUT_FAILURE); else SM_ENTER(EAP, IDLE); break; case EAP_RECEIVED: if (sm->rxResp && (sm->respId == sm->currentId) && (sm->respMethod == EAP_TYPE_NAK || (sm->respMethod == EAP_TYPE_EXPANDED && sm->respVendor == EAP_VENDOR_IETF && sm->respVendorMethod == EAP_TYPE_NAK)) && (sm->methodState == METHOD_PROPOSED)) SM_ENTER(EAP, NAK); else if (sm->rxResp && (sm->respId == sm->currentId) && ((sm->respMethod == sm->currentMethod) || (sm->respMethod == EAP_TYPE_EXPANDED && sm->respVendor == EAP_VENDOR_IETF && sm->respVendorMethod == sm->currentMethod))) SM_ENTER(EAP, INTEGRITY_CHECK); else { wpa_printf(MSG_DEBUG, "EAP: RECEIVED->DISCARD: " "rxResp=%d respId=%d currentId=%d " "respMethod=%d currentMethod=%d", sm->rxResp, sm->respId, sm->currentId, sm->respMethod, sm->currentMethod); SM_ENTER(EAP, DISCARD); } break; case EAP_DISCARD: SM_ENTER(EAP, IDLE); break; case EAP_SEND_REQUEST: SM_ENTER(EAP, IDLE); break; case EAP_INTEGRITY_CHECK: if (sm->ignore) SM_ENTER(EAP, DISCARD); else SM_ENTER(EAP, METHOD_RESPONSE); break; case EAP_METHOD_REQUEST: SM_ENTER(EAP, SEND_REQUEST); break; case EAP_METHOD_RESPONSE: /* * Note: Mechanism to allow EAP methods to wait while going * through pending processing is an extension to RFC 4137 * which only defines the transits to SELECT_ACTION and * METHOD_REQUEST from this METHOD_RESPONSE state. */ if (sm->methodState == METHOD_END) SM_ENTER(EAP, SELECT_ACTION); else if (sm->method_pending == METHOD_PENDING_WAIT) { wpa_printf(MSG_DEBUG, "EAP: Method has pending " "processing - wait before proceeding to " "METHOD_REQUEST state"); } else if (sm->method_pending == METHOD_PENDING_CONT) { wpa_printf(MSG_DEBUG, "EAP: Method has completed " "pending processing - reprocess pending " "EAP message"); sm->method_pending = METHOD_PENDING_NONE; SM_ENTER(EAP, METHOD_RESPONSE); } else SM_ENTER(EAP, METHOD_REQUEST); break; case EAP_PROPOSE_METHOD: /* * Note: Mechanism to allow EAP methods to wait while going * through pending processing is an extension to RFC 4137 * which only defines the transit to METHOD_REQUEST from this * PROPOSE_METHOD state. */ if (sm->method_pending == METHOD_PENDING_WAIT) { wpa_printf(MSG_DEBUG, "EAP: Method has pending " "processing - wait before proceeding to " "METHOD_REQUEST state"); if (sm->user_eap_method_index > 0) sm->user_eap_method_index--; } else if (sm->method_pending == METHOD_PENDING_CONT) { wpa_printf(MSG_DEBUG, "EAP: Method has completed " "pending processing - reprocess pending " "EAP message"); sm->method_pending = METHOD_PENDING_NONE; SM_ENTER(EAP, PROPOSE_METHOD); } else SM_ENTER(EAP, METHOD_REQUEST); break; case EAP_NAK: SM_ENTER(EAP, SELECT_ACTION); break; case EAP_SELECT_ACTION: if (sm->decision == DECISION_FAILURE) SM_ENTER(EAP, FAILURE); else if (sm->decision == DECISION_SUCCESS) SM_ENTER(EAP, SUCCESS); else if (sm->decision == DECISION_PASSTHROUGH) SM_ENTER(EAP, INITIALIZE_PASSTHROUGH); else SM_ENTER(EAP, PROPOSE_METHOD); break; case EAP_TIMEOUT_FAILURE: break; case EAP_FAILURE: break; case EAP_SUCCESS: break; case EAP_INITIALIZE_PASSTHROUGH: if (sm->currentId == -1) SM_ENTER(EAP, AAA_IDLE); else SM_ENTER(EAP, AAA_REQUEST); break; case EAP_IDLE2: if (sm->eap_if.eapResp) SM_ENTER(EAP, RECEIVED2); else if (sm->eap_if.retransWhile == 0) SM_ENTER(EAP, RETRANSMIT2); break; case EAP_RETRANSMIT2: if (sm->retransCount > sm->MaxRetrans) SM_ENTER(EAP, TIMEOUT_FAILURE2); else SM_ENTER(EAP, IDLE2); break; case EAP_RECEIVED2: if (sm->rxResp && (sm->respId == sm->currentId)) SM_ENTER(EAP, AAA_REQUEST); else SM_ENTER(EAP, DISCARD2); break; case EAP_DISCARD2: SM_ENTER(EAP, IDLE2); break; case EAP_SEND_REQUEST2: SM_ENTER(EAP, IDLE2); break; case EAP_AAA_REQUEST: SM_ENTER(EAP, AAA_IDLE); break; case EAP_AAA_RESPONSE: SM_ENTER(EAP, SEND_REQUEST2); break; case EAP_AAA_IDLE: if (sm->eap_if.aaaFail) SM_ENTER(EAP, FAILURE2); else if (sm->eap_if.aaaSuccess) SM_ENTER(EAP, SUCCESS2); else if (sm->eap_if.aaaEapReq) SM_ENTER(EAP, AAA_RESPONSE); else if (sm->eap_if.aaaTimeout) SM_ENTER(EAP, TIMEOUT_FAILURE2); break; case EAP_TIMEOUT_FAILURE2: break; case EAP_FAILURE2: break; case EAP_SUCCESS2: break; }}static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount, int eapSRTT, int eapRTTVAR, int methodTimeout){ int rto, i; if (methodTimeout) { /* * EAP method (either internal or through AAA server, provided * timeout hint. Use that as-is as a timeout for retransmitting * the EAP request if no response is received. */ wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds " "(from EAP method hint)", methodTimeout); return methodTimeout; } /* * RFC 3748 recommends algorithms described in RFC 2988 for estimation * of the retransmission timeout. This should be implemented once * round-trip time measurements are available. For nowm a simple * backoff mechanism is used instead if there are no EAP method * specific hints. * * SRTT = smoothed round-trip time * RTTVAR = round-trip time variation * RTO = retransmission timeout */ /* * RFC 2988, 2.1: before RTT measurement, set RTO to 3 seconds for * initial retransmission and then double the RTO to provide back off * per 5.5. Limit the maximum RTO to 20 seconds per RFC 3748, 4.3 * modified RTOmax. */ rto = 3; for (i = 0; i < retransCount; i++) { rto *= 2; if (rto >= 20) { rto = 20; break; } } wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds " "(from dynamic back off; retransCount=%d)", rto, retransCount); return rto;}static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp){ const struct eap_hdr *hdr; size_t plen; /* parse rxResp, respId, respMethod */ sm->rxResp = FALSE; sm->respId = -1; sm->respMethod = EAP_TYPE_NONE; sm->respVendor = EAP_VENDOR_IETF; sm->respVendorMethod = EAP_TYPE_NONE; if (resp == NULL || wpabuf_len(resp) < sizeof(*hdr)) { wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p " "len=%lu", resp, resp ? (unsigned long) wpabuf_len(resp) : 0); return; } hdr = wpabuf_head(resp); plen = be_to_host16(hdr->length); if (plen > wpabuf_len(resp)) { wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet " "(len=%lu plen=%lu)", (unsigned long) wpabuf_len(resp), (unsigned long) plen); return; } sm->respId = hdr->identifier; if (hdr->code == EAP_CODE_RESPONSE) sm->rxResp = TRUE; if (plen > sizeof(*hdr)) { u8 *pos = (u8 *) (hdr + 1); sm->respMethod = *pos++; if (sm->respMethod == EAP_TYPE_EXPANDED) { if (plen < sizeof(*hdr) + 8) { wpa_printf(MSG_DEBUG, "EAP: Ignored truncated " "expanded EAP-Packet (plen=%lu)", (unsigned long) plen); return; } sm->respVendor = WPA_GET_BE24(pos); pos += 3; sm->respVendorMethod = WPA_GET_BE32(pos); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -