]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-PEAP peer: Support vendor EAP method in Phase 2
authorJouni Malinen <j@w1.fi>
Sat, 17 Aug 2019 12:40:59 +0000 (15:40 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 17 Aug 2019 13:15:02 +0000 (16:15 +0300)
The implementation was previously hardcoded to allow only the Microsoft
SoH expanded EAP method in Phase 2 in addition to non-expanded EAP
methods. Extend that to allow any vendor EAP method with an expanded
header to be used.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/eap_peer/eap_peap.c

index 6453afe2fc57fabab7d51f4ae3e79bc3fd1a3c15..5ca61459d274b198808519b9909eae2fc381af5c 100644 (file)
@@ -603,6 +603,8 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
        u8 *pos;
        struct eap_method_ret iret;
        struct eap_peer_config *config = eap_get_config(sm);
+       int vendor;
+       enum eap_type method;
 
        if (len <= sizeof(struct eap_hdr)) {
                wpa_printf(MSG_INFO, "EAP-PEAP: too short "
@@ -666,13 +668,26 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
 #endif /* EAP_TNC */
                /* fall through */
        default:
+               vendor = EAP_VENDOR_IETF;
+               method = *pos;
+
+               if (method == EAP_TYPE_EXPANDED) {
+                       if (len < sizeof(struct eap_hdr) + 8) {
+                               wpa_printf(MSG_INFO,
+                                          "EAP-PEAP: Too short Phase 2 request (expanded header) (len=%lu)",
+                                          (unsigned long) len);
+                               return -1;
+                       }
+                       vendor = WPA_GET_BE24(pos + 1);
+                       method = WPA_GET_BE32(pos + 4);
+               }
+
                if (data->phase2_type.vendor == EAP_VENDOR_IETF &&
                    data->phase2_type.method == EAP_TYPE_NONE) {
                        size_t i;
                        for (i = 0; i < data->num_phase2_types; i++) {
-                               if (data->phase2_types[i].vendor !=
-                                   EAP_VENDOR_IETF ||
-                                   data->phase2_types[i].method != *pos)
+                               if (data->phase2_types[i].vendor != vendor ||
+                                   data->phase2_types[i].method != method)
                                        continue;
 
                                data->phase2_type.vendor =
@@ -686,8 +701,9 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
                                break;
                        }
                }
-               if (*pos != data->phase2_type.method ||
-                   *pos == EAP_TYPE_NONE) {
+               if (vendor != data->phase2_type.vendor ||
+                   method != data->phase2_type.method ||
+                   (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_NONE)) {
                        if (eap_peer_tls_phase2_nak(data->phase2_types,
                                                    data->num_phase2_types,
                                                    hdr, resp))