static void eap_sm_Policy_update(struct eap_sm *sm, u8 *nak_list, size_t len) { if (nak_list == NULL || sm == NULL || sm->user == NULL) return; if (sm->user->phase2) { wpa_printf(MSG_DEBUG, "EAP: EAP-Nak received after Phase2 user" " info was selected - reject"); sm->decision = DECISION_FAILURE; return; } eap_sm_process_nak(sm, nak_list, len); }
static void eap_fast_process_phase2_response(struct eap_sm *sm, struct eap_fast_data *data, u8 *in_data, size_t in_len) { u8 next_type = EAP_TYPE_NONE; struct eap_hdr *hdr; u8 *pos; size_t left; struct wpabuf buf; const struct eap_method *m = data->phase2_method; void *priv = data->phase2_priv; if (priv == NULL) { wpa_printf(MSG_DEBUG, "EAP-FAST: %s - Phase2 not " "initialized?!", __func__); return; } hdr = (struct eap_hdr *) in_data; pos = (u8 *) (hdr + 1); if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) { left = in_len - sizeof(*hdr); wpa_hexdump(MSG_DEBUG, "EAP-FAST: Phase2 type Nak'ed; " "allowed types", pos + 1, left - 1); #ifdef EAP_SERVER_TNC if (m && m->vendor == EAP_VENDOR_IETF && m->method == EAP_TYPE_TNC) { wpa_printf(MSG_DEBUG, "EAP-FAST: Peer Nak'ed required " "TNC negotiation"); next_type = eap_fast_req_failure(sm, data); eap_fast_phase2_init(sm, data, next_type); return; } #endif /* EAP_SERVER_TNC */ eap_sm_process_nak(sm, pos + 1, left - 1); if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && sm->user->methods[sm->user_eap_method_index].method != EAP_TYPE_NONE) { next_type = sm->user->methods[ sm->user_eap_method_index++].method; wpa_printf(MSG_DEBUG, "EAP-FAST: try EAP type %d", next_type); } else { next_type = eap_fast_req_failure(sm, data); } eap_fast_phase2_init(sm, data, next_type); return; } wpabuf_set(&buf, in_data, in_len); if (m->check(sm, priv, &buf)) { wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 check() asked to " "ignore the packet"); eap_fast_req_failure(sm, data); return; } m->process(sm, priv, &buf); if (!m->isDone(sm, priv)) return; if (!m->isSuccess(sm, priv)) { wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 method failed"); next_type = eap_fast_req_failure(sm, data); eap_fast_phase2_init(sm, data, next_type); return; } switch (data->state) { case PHASE2_ID: if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: Phase2 " "Identity not found in the user " "database", sm->identity, sm->identity_len); next_type = eap_fast_req_failure(sm, data); break; } eap_fast_state(data, PHASE2_METHOD); if (data->anon_provisioning) { /* * Only EAP-MSCHAPv2 is allowed for anonymous * provisioning. */ next_type = EAP_TYPE_MSCHAPV2; sm->user_eap_method_index = 0; } else { next_type = sm->user->methods[0].method; sm->user_eap_method_index = 1; } wpa_printf(MSG_DEBUG, "EAP-FAST: try EAP type %d", next_type); break; case PHASE2_METHOD: case CRYPTO_BINDING: eap_fast_update_icmk(sm, data); eap_fast_state(data, CRYPTO_BINDING); data->eap_seq++; next_type = EAP_TYPE_NONE; #ifdef EAP_SERVER_TNC if (sm->tnc && !data->tnc_started) { wpa_printf(MSG_DEBUG, "EAP-FAST: Initialize TNC"); next_type = EAP_TYPE_TNC; data->tnc_started = 1; } #endif /* EAP_SERVER_TNC */ break; case FAILURE: break; default: wpa_printf(MSG_DEBUG, "EAP-FAST: %s - unexpected state %d", __func__, data->state); break; } eap_fast_phase2_init(sm, data, next_type); }
static void eap_peap_process_phase2_response(struct eap_sm *sm, struct eap_peap_data *data, struct wpabuf *in_data) { int next_vendor = EAP_VENDOR_IETF; u32 next_type = EAP_TYPE_NONE; const struct eap_hdr *hdr; const u8 *pos; size_t left; if (data->state == PHASE2_TLV) { eap_peap_process_phase2_tlv(sm, data, in_data); return; } #ifdef EAP_SERVER_TNC if (data->state == PHASE2_SOH) { eap_peap_process_phase2_soh(sm, data, in_data); return; } #endif /* EAP_SERVER_TNC */ if (data->phase2_priv == NULL) { wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - Phase2 not " "initialized?!", __func__); return; } hdr = wpabuf_head(in_data); pos = (const u8 *) (hdr + 1); if (wpabuf_len(in_data) > sizeof(*hdr) && *pos == EAP_TYPE_NAK) { left = wpabuf_len(in_data) - sizeof(*hdr); wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Phase2 type Nak'ed; " "allowed types", pos + 1, left - 1); eap_sm_process_nak(sm, pos + 1, left - 1); if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && (sm->user->methods[sm->user_eap_method_index].vendor != EAP_VENDOR_IETF || sm->user->methods[sm->user_eap_method_index].method != EAP_TYPE_NONE)) { next_vendor = sm->user->methods[ sm->user_eap_method_index].vendor; next_type = sm->user->methods[ sm->user_eap_method_index++].method; wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP vendor %d type 0x%x", next_vendor, next_type); } else { eap_peap_req_failure(sm, data); next_vendor = EAP_VENDOR_IETF; next_type = EAP_TYPE_NONE; } eap_peap_phase2_init(sm, data, next_vendor, next_type); return; } if (data->phase2_method->check(sm, data->phase2_priv, in_data)) { wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 check() asked to " "ignore the packet"); return; } data->phase2_method->process(sm, data->phase2_priv, in_data); if (sm->method_pending == METHOD_PENDING_WAIT) { wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method is in " "pending wait state - save decrypted response"); wpabuf_free(data->pending_phase2_resp); data->pending_phase2_resp = wpabuf_dup(in_data); } if (!data->phase2_method->isDone(sm, data->phase2_priv)) return; if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) { wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method failed"); eap_peap_req_failure(sm, data); next_vendor = EAP_VENDOR_IETF; next_type = EAP_TYPE_NONE; eap_peap_phase2_init(sm, data, next_vendor, next_type); return; } os_free(data->phase2_key); if (data->phase2_method->getKey) { data->phase2_key = data->phase2_method->getKey( sm, data->phase2_priv, &data->phase2_key_len); if (data->phase2_key == NULL) { wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 getKey " "failed"); eap_peap_req_failure(sm, data); eap_peap_phase2_init(sm, data, EAP_VENDOR_IETF, EAP_TYPE_NONE); return; } } switch (data->state) { case PHASE1_ID2: case PHASE2_ID: case PHASE2_SOH: if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { wpa_hexdump_ascii(MSG_DEBUG, "EAP_PEAP: Phase2 " "Identity not found in the user " "database", sm->identity, sm->identity_len); eap_peap_req_failure(sm, data); next_vendor = EAP_VENDOR_IETF; next_type = EAP_TYPE_NONE; break; } #ifdef EAP_SERVER_TNC if (data->state != PHASE2_SOH && sm->tnc && data->peap_version == 0) { eap_peap_state(data, PHASE2_SOH); wpa_printf(MSG_DEBUG, "EAP-PEAP: Try to initialize " "TNC (NAP SOH)"); next_vendor = EAP_VENDOR_IETF; next_type = EAP_TYPE_NONE; break; } #endif /* EAP_SERVER_TNC */ eap_peap_state(data, PHASE2_METHOD); next_vendor = sm->user->methods[0].vendor; next_type = sm->user->methods[0].method; sm->user_eap_method_index = 1; wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP vendor %d type 0x%x", next_vendor, next_type); break; case PHASE2_METHOD: eap_peap_req_success(sm, data); next_vendor = EAP_VENDOR_IETF; next_type = EAP_TYPE_NONE; break; case FAILURE: break; default: wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d", __func__, data->state); break; } eap_peap_phase2_init(sm, data, next_vendor, next_type); }
static void eap_peap_process_phase2_response(struct eap_sm *sm, struct eap_peap_data *data, u8 *in_data, size_t in_len) { u8 next_type = EAP_TYPE_NONE; struct eap_hdr *hdr; u8 *pos; size_t left; if (data->phase2_priv == NULL) { wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - Phase2 not " "initialized?!", __func__); return; } hdr = (struct eap_hdr *) in_data; pos = (u8 *) (hdr + 1); left = in_len - sizeof(*hdr); if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) { wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Phase2 type Nak'ed; " "allowed types", pos + 1, left - 1); eap_sm_process_nak(sm, pos + 1, left - 1); if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && sm->user->methods[sm->user_eap_method_index] != EAP_TYPE_NONE) { next_type = sm->user->methods[sm->user_eap_method_index++]; wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d", next_type); } else { next_type = eap_peap_req_failure(sm, data); } eap_peap_phase2_init(sm, data, next_type); return; } if (data->phase2_method->check(sm, data->phase2_priv, in_data, in_len)) { wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 check() asked to " "ignore the packet"); return; } data->phase2_method->process(sm, data->phase2_priv, in_data, in_len); if (!data->phase2_method->isDone(sm, data->phase2_priv)) return; if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) { wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method failed"); next_type = eap_peap_req_failure(sm, data); eap_peap_phase2_init(sm, data, next_type); return; } switch (data->state) { case PHASE2_ID: if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { wpa_hexdump_ascii(MSG_DEBUG, "EAP_PEAP: Phase2 " "Identity not found in the user " "database", sm->identity, sm->identity_len); next_type = eap_peap_req_failure(sm, data); break; } eap_peap_state(data, PHASE2_METHOD); next_type = sm->user->methods[0]; sm->user_eap_method_index = 1; wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d", next_type); break; case PHASE2_METHOD: next_type = eap_peap_req_success(sm, data); break; case PHASE2_TLV: if (sm->tlv_request == TLV_REQ_SUCCESS || data->state == SUCCESS_REQ) { eap_peap_state(data, SUCCESS); } else { eap_peap_state(data, FAILURE); } break; case FAILURE: break; default: wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d", __func__, data->state); break; } eap_peap_phase2_init(sm, data, next_type); }