diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c index 4fb135916b..f966207c5c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c @@ -452,6 +452,15 @@ int eap_sm_process_request(struct eap_sm *sm, struct wpabuf *reqData) if (m == NULL) { goto build_nak; } + + if (!eap_sm_allowMethod(sm, reqVendor, reqVendorMethod)) { + wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed", + reqVendor, reqVendorMethod); + wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD + "vendor=%u method=%u -> NAK", + reqVendor, reqVendorMethod); + goto build_nak; + } if (sm->m) { eap_deinit_prev_method(sm, "GET_METHOD"); } diff --git a/components/wpa_supplicant/src/eap_peer/eap.c b/components/wpa_supplicant/src/eap_peer/eap.c index f3caa93a8f..7cc829d0c3 100644 --- a/components/wpa_supplicant/src/eap_peer/eap.c +++ b/components/wpa_supplicant/src/eap_peer/eap.c @@ -49,6 +49,7 @@ void eap_deinit_prev_method(struct eap_sm *sm, const char *txt); #ifdef EAP_PEER_METHOD static struct eap_method *eap_methods = NULL; +static struct eap_method_type *config_methods; const struct eap_method * eap_peer_get_eap_method(int vendor, EapType method) { @@ -72,6 +73,33 @@ const struct eap_method * eap_peer_get_methods(size_t *count) return eap_methods; } +/** + * eap_config_allowed_method - Check whether EAP method is allowed + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @config: EAP configuration + * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types + * @method: EAP type + * Returns: 1 = allowed EAP method, 0 = not allowed + */ +static int eap_config_allowed_method(struct eap_sm *sm, + struct eap_peer_config *config, + int vendor, u32 method) +{ + int i; + struct eap_method_type *m; + + if (config == NULL || config->eap_methods == NULL) + return 1; + + m = config->eap_methods; + for (i = 0; m[i].vendor != EAP_VENDOR_IETF || + m[i].method != EAP_TYPE_NONE; i++) { + if (m[i].vendor == vendor && m[i].method == method) + return 1; + } + return 0; +} + EapType eap_peer_get_type(const char *name, int *vendor) { struct eap_method *m; @@ -85,6 +113,21 @@ EapType eap_peer_get_type(const char *name, int *vendor) return EAP_TYPE_NONE; } + +/** + * eap_allowed_method - Check whether EAP method is allowed + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types + * @method: EAP type + * Returns: 1 = allowed EAP method, 0 = not allowed + */ +int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method) +{ + return eap_config_allowed_method(sm, eap_get_config(sm), vendor, + method); +} + + static int eap_allowed_phase2_type(int vendor, int type) { @@ -194,6 +237,21 @@ void eap_peer_unregister_methods(void) +bool eap_sm_allowMethod(struct eap_sm *sm, int vendor, + EapType method) +{ + if (!eap_allowed_method(sm, vendor, method)) { + wpa_printf(MSG_DEBUG, "EAP: configuration does not allow: " + "vendor %u method %u", vendor, method); + return FALSE; + } + if (eap_peer_get_eap_method(vendor, method)) + return TRUE; + wpa_printf(MSG_DEBUG, "EAP: not included in build: " + "vendor %u method %u", vendor, method); + return FALSE; +} + int eap_peer_register_methods(void) { int ret = 0; @@ -499,6 +557,52 @@ int eap_peer_config_init( if (g_wpa_phase1_options) { sm->config.phase1 = g_wpa_phase1_options; } + + /* Allow methods with correct configuration only */ + size_t mcount; + int allowed_method_count = 0; + const struct eap_method *methods; + + if (!config_methods) { + methods = eap_peer_get_methods(&mcount); + if (methods == NULL) { + wpa_printf(MSG_ERROR, "EAP: Set config init: EAP methods not registered."); + return -1; + } + + // Allocate a buffer large enough to accomodate all the registered methods. + config_methods = os_malloc(mcount * sizeof(struct eap_method_type)); + if (config_methods == NULL) { + wpa_printf(MSG_ERROR, "EAP: Set config init: Out of memory, set configured methods failed"); + return -1; + } + + if (g_wpa_username) { + //set EAP-PEAP + config_methods[allowed_method_count].vendor = EAP_VENDOR_IETF; + config_methods[allowed_method_count++].method = EAP_TYPE_PEAP; + //set EAP-TTLS + config_methods[allowed_method_count].vendor = EAP_VENDOR_IETF; + config_methods[allowed_method_count++].method = EAP_TYPE_TTLS; + } + if (g_wpa_private_key) { + //set EAP-TLS + config_methods[allowed_method_count].vendor = EAP_VENDOR_IETF; + config_methods[allowed_method_count++].method = EAP_TYPE_TLS; + } +#ifndef USE_MBEDTLS_CRYPTO + if (g_wpa_pac_file) { + //set EAP-FAST + config_methods[allowed_method_count].vendor = EAP_VENDOR_IETF; + config_methods[allowed_method_count++].method = EAP_TYPE_FAST; + } +#endif + // Terminate the allowed method list + config_methods[allowed_method_count].vendor = EAP_VENDOR_IETF; + config_methods[allowed_method_count++].method = EAP_TYPE_NONE; + // Set the allowed methods to config + sm->config.eap_methods = config_methods; + } return 0; } @@ -512,6 +616,7 @@ void eap_peer_config_deinit(struct eap_sm *sm) os_free(sm->config.identity); os_free(sm->config.password); os_free(sm->config.new_password); + os_free(sm->config.eap_methods); os_bzero(&sm->config, sizeof(struct eap_peer_config)); } diff --git a/components/wpa_supplicant/src/eap_peer/eap.h b/components/wpa_supplicant/src/eap_peer/eap.h index f787e35daf..3db3c9907a 100644 --- a/components/wpa_supplicant/src/eap_peer/eap.h +++ b/components/wpa_supplicant/src/eap_peer/eap.h @@ -62,5 +62,6 @@ int eap_peer_register_methods(void); void eap_sm_request_identity(struct eap_sm *sm); void eap_sm_request_password(struct eap_sm *sm); void eap_sm_request_new_password(struct eap_sm *sm); +bool eap_sm_allowMethod(struct eap_sm *sm, int vendor, EapType method); #endif /* EAP_H */ diff --git a/components/wpa_supplicant/src/eap_peer/eap_i.h b/components/wpa_supplicant/src/eap_peer/eap_i.h index e60fc2385f..8d71b4983d 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_i.h +++ b/components/wpa_supplicant/src/eap_peer/eap_i.h @@ -329,6 +329,7 @@ int eap_get_config_fragment_size(struct eap_sm *sm); struct eap_peer_config * eap_get_config(struct eap_sm *sm); void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob); const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm, const char *name); +int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method); bool wifi_sta_get_enterprise_disable_time_check(void); struct wpabuf * eap_sm_build_identity_resp(struct eap_sm *sm, u8 id, int encrypted);