diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 07cc514d9..f914875fe 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -3221,13 +3221,45 @@ static int ocv_oci_add(struct wpa_state_machine *sm, u8 **argpos) } +#ifdef CONFIG_TESTING_OPTIONS +static u8 * replace_ie(const char *name, const u8 *old_buf, size_t *len, u8 eid, + const u8 *ie, size_t ie_len) +{ + const u8 *elem; + u8 *buf; + + wpa_printf(MSG_DEBUG, "TESTING: %s EAPOL override", name); + wpa_hexdump(MSG_DEBUG, "TESTING: wpa_ie before override", + old_buf, *len); + buf = os_malloc(*len + ie_len); + if (!buf) + return NULL; + os_memcpy(buf, old_buf, *len); + elem = get_ie(buf, *len, eid); + if (elem) { + u8 elem_len = 2 + elem[1]; + + os_memmove((void *) elem, elem + elem_len, + *len - (elem - buf) - elem_len); + *len -= elem_len; + } + os_memcpy(buf + *len, ie, ie_len); + *len += ie_len; + wpa_hexdump(MSG_DEBUG, "TESTING: wpa_ie after EAPOL override", + buf, *len); + + return buf; +} +#endif /* CONFIG_TESTING_OPTIONS */ + + SM_STATE(WPA_PTK, PTKINITNEGOTIATING) { u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde = NULL, *pos, dummy_gtk[32]; - size_t gtk_len, kde_len; + size_t gtk_len, kde_len, wpa_ie_len; struct wpa_group *gsm = sm->group; u8 *wpa_ie; - int wpa_ie_len, secure, gtkidx, encr = 0; + int secure, gtkidx, encr = 0; u8 *wpa_ie_buf = NULL; SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk); @@ -3255,7 +3287,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) wpa_ie_len = sm->wpa_auth->wpa_ie_len; if (sm->wpa == WPA_VERSION_WPA && (sm->wpa_auth->conf.wpa & WPA_PROTO_RSN) && - wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) { + wpa_ie_len > wpa_ie[1] + 2U && wpa_ie[0] == WLAN_EID_RSN) { /* WPA-only STA, remove RSN IE and possible MDIE */ wpa_ie = wpa_ie + wpa_ie[1] + 2; if (wpa_ie[0] == WLAN_EID_MOBILITY_DOMAIN) @@ -3263,32 +3295,14 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) wpa_ie_len = wpa_ie[1] + 2; } #ifdef CONFIG_TESTING_OPTIONS - if (sm->wpa_auth->conf.rsnxe_override_eapol_len) { - u8 *obuf = sm->wpa_auth->conf.rsnxe_override_eapol; - size_t olen = sm->wpa_auth->conf.rsnxe_override_eapol_len; - const u8 *rsnxe; - - wpa_hexdump(MSG_DEBUG, - "TESTING: wpa_ie before RSNXE EAPOL override", - wpa_ie, wpa_ie_len); - wpa_ie_buf = os_malloc(wpa_ie_len + olen); + if (sm->wpa_auth->conf.rsnxe_override_eapol_set) { + wpa_ie_buf = replace_ie( + "RSNXE", wpa_ie, &wpa_ie_len, WLAN_EID_RSNX, + sm->wpa_auth->conf.rsnxe_override_eapol, + sm->wpa_auth->conf.rsnxe_override_eapol_len); if (!wpa_ie_buf) - return; - os_memcpy(wpa_ie_buf, wpa_ie, wpa_ie_len); + goto done; wpa_ie = wpa_ie_buf; - rsnxe = get_ie(wpa_ie, wpa_ie_len, WLAN_EID_RSNX); - if (rsnxe) { - u8 rsnxe_len = 2 + rsnxe[1]; - - os_memmove((void *) rsnxe, rsnxe + rsnxe_len, - wpa_ie_len - (rsnxe - wpa_ie) - rsnxe_len); - wpa_ie_len -= rsnxe_len; - } - os_memcpy(wpa_ie + wpa_ie_len, obuf, olen); - wpa_ie_len += olen; - wpa_hexdump(MSG_DEBUG, - "TESTING: wpa_ie after RSNXE EAPOL override", - wpa_ie, wpa_ie_len); } #endif /* CONFIG_TESTING_OPTIONS */ wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 1f7ba4899..93d7f74f2 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -225,6 +225,7 @@ struct wpa_auth_config { size_t rsnxe_override_eapol_len; u8 gtk_rsc_override[WPA_KEY_RSC_LEN]; u8 igtk_rsc_override[WPA_KEY_RSC_LEN]; + unsigned int rsnxe_override_eapol_set:1; unsigned int gtk_rsc_override_set:1; unsigned int igtk_rsc_override_set:1; #endif /* CONFIG_TESTING_OPTIONS */ diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 82e82a7d2..4a303b039 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -123,6 +123,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, } if (conf->rsnxe_override_eapol && wpabuf_len(conf->rsnxe_override_eapol) <= MAX_OWN_IE_OVERRIDE) { + wconf->rsnxe_override_eapol_set = 1; wconf->rsnxe_override_eapol_len = wpabuf_len(conf->rsnxe_override_eapol); os_memcpy(wconf->rsnxe_override_eapol,