]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-PEAP server: Support vendor EAP types in Phase 2
authorJouni Malinen <j@w1.fi>
Sat, 17 Aug 2019 13:11:20 +0000 (16:11 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 17 Aug 2019 13:17:42 +0000 (16:17 +0300)
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 <j@w1.fi>
src/eap_server/eap_server_teap.c

index 346b44b9ffd46da0fde349a3be443791bb0f3d1f..34a0d4c2ef9a7afd17dd068014c794e16bea26f4 100644 (file)
@@ -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);
 }