Merge branch 'bugfix/eap_method_selection' into 'master'

esp_wifi: Fix the negotiation of method with eap server.

Closes IDFGH-6088

See merge request espressif/esp-idf!16246
This commit is contained in:
Hrudaynath Dhabe 2022-01-12 08:46:32 +00:00
commit 190b31bb1b
4 changed files with 116 additions and 1 deletions

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -451,6 +451,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");
}

View File

@ -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;
@ -500,6 +558,51 @@ int eap_peer_config_init(
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;
}
@ -513,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));
}

View File

@ -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 */

View File

@ -331,6 +331,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);