From aba8dc82fcdc6a88fc37adb339d7017f1f974632 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 17 Aug 2019 16:11:20 +0300 Subject: [PATCH] EAP-PEAP server: Support vendor EAP types in Phase 2 This was already allowed with EAP-PEAP, but EAP-TEAP was hardcoded to use only the non-expanded EAP types. Extend that to allow vendor EAP types to be used. Signed-off-by: Jouni Malinen --- src/eap_server/eap_server_teap.c | 41 ++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/eap_server/eap_server_teap.c b/src/eap_server/eap_server_teap.c index 346b44b9f..34a0d4c2e 100644 --- a/src/eap_server/eap_server_teap.c +++ b/src/eap_server/eap_server_teap.c @@ -938,15 +938,14 @@ static Boolean eap_teap_check(struct eap_sm *sm, void *priv, static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data, - enum eap_type eap_type) + int vendor, enum eap_type eap_type) { if (data->phase2_priv && data->phase2_method) { data->phase2_method->reset(sm, data->phase2_priv); data->phase2_method = NULL; data->phase2_priv = NULL; } - data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF, - eap_type); + data->phase2_method = eap_server_get_eap_method(vendor, eap_type); if (!data->phase2_method) return -1; @@ -962,7 +961,8 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, struct eap_teap_data *data, u8 *in_data, size_t in_len) { - u8 next_type = EAP_TYPE_NONE; + int next_vendor = EAP_VENDOR_IETF; + enum eap_type next_type = EAP_TYPE_NONE; struct eap_hdr *hdr; u8 *pos; size_t left; @@ -990,8 +990,9 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, m->method == EAP_TYPE_TNC) { wpa_printf(MSG_DEBUG, "EAP-TEAP: Peer Nak'ed required TNC negotiation"); + next_vendor = EAP_VENDOR_IETF; next_type = eap_teap_req_failure(data, 0); - eap_teap_phase2_init(sm, data, next_type); + eap_teap_phase2_init(sm, data, next_vendor, next_type); return; } #endif /* EAP_SERVER_TNC */ @@ -999,14 +1000,17 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && 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-TEAP: try EAP type %d", - next_type); + wpa_printf(MSG_DEBUG, "EAP-TEAP: try EAP type %u:%u", + next_vendor, next_type); } else { + next_vendor = EAP_VENDOR_IETF; next_type = eap_teap_req_failure(data, 0); } - eap_teap_phase2_init(sm, data, next_type); + eap_teap_phase2_init(sm, data, next_vendor, next_type); return; } @@ -1026,8 +1030,9 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, if (!m->isSuccess(sm, priv)) { wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 method failed"); + next_vendor = EAP_VENDOR_IETF; next_type = eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD); - eap_teap_phase2_init(sm, data, next_type); + eap_teap_phase2_init(sm, data, next_vendor, next_type); return; } @@ -1037,6 +1042,7 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: Phase 2 Identity not found in the user database", sm->identity, sm->identity_len); + next_vendor = EAP_VENDOR_IETF; next_type = eap_teap_req_failure( data, TEAP_ERROR_INNER_METHOD); break; @@ -1047,23 +1053,28 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, /* TODO: Allow any inner EAP method that provides * mutual authentication and EMSK derivation (i.e., * EAP-pwd or EAP-EKE). */ + next_vendor = EAP_VENDOR_IETF; next_type = EAP_TYPE_PWD; sm->user_eap_method_index = 0; } else { + 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-TEAP: Try EAP type %d", next_type); + wpa_printf(MSG_DEBUG, "EAP-TEAP: Try EAP type %u:%u", + next_vendor, next_type); break; case PHASE2_METHOD: case CRYPTO_BINDING: eap_teap_update_icmk(sm, data); eap_teap_state(data, CRYPTO_BINDING); data->eap_seq++; + next_vendor = EAP_VENDOR_IETF; next_type = EAP_TYPE_NONE; #ifdef EAP_SERVER_TNC if (sm->tnc && !data->tnc_started) { wpa_printf(MSG_DEBUG, "EAP-TEAP: Initialize TNC"); + next_vendor = EAP_VENDOR_IETF; next_type = EAP_TYPE_TNC; data->tnc_started = 1; } @@ -1077,7 +1088,7 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, break; } - eap_teap_phase2_init(sm, data, next_type); + eap_teap_phase2_init(sm, data, next_vendor, next_type); } @@ -1640,7 +1651,8 @@ static int eap_teap_process_phase1(struct eap_sm *sm, static int eap_teap_process_phase2_start(struct eap_sm *sm, struct eap_teap_data *data) { - u8 next_type; + int next_vendor; + enum eap_type next_type; if (data->identity) { /* Used PAC and identity is from PAC-Opaque */ @@ -1653,6 +1665,7 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm, wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: Phase 2 Identity not found in the user database", sm->identity, sm->identity_len); + next_vendor = EAP_VENDOR_IETF; next_type = EAP_TYPE_NONE; eap_teap_state(data, PHASE2_METHOD); } else if (sm->eap_teap_pac_no_inner) { @@ -1672,6 +1685,7 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm, } else { wpa_printf(MSG_DEBUG, "EAP-TEAP: Identity already known - skip Phase 2 Identity Request"); + next_vendor = sm->user->methods[0].vendor; next_type = sm->user->methods[0].method; sm->user_eap_method_index = 1; eap_teap_state(data, PHASE2_METHOD); @@ -1682,10 +1696,11 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm, return 0; } else { eap_teap_state(data, PHASE2_ID); + next_vendor = EAP_VENDOR_IETF; next_type = EAP_TYPE_IDENTITY; } - return eap_teap_phase2_init(sm, data, next_type); + return eap_teap_phase2_init(sm, data, next_vendor, next_type); }