diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 0b5fe51ee..7a708234b 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -2291,6 +2291,9 @@ void wpa_sm_deinit(struct wpa_sm *sm) #ifdef CONFIG_IEEE80211R os_free(sm->assoc_resp_ies); #endif /* CONFIG_IEEE80211R */ +#ifdef CONFIG_TESTING_OPTIONS + wpabuf_free(sm->test_assoc_ie); +#endif /* CONFIG_TESTING_OPTIONS */ os_free(sm); } @@ -2692,6 +2695,17 @@ int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie, if (sm == NULL) return -1; +#ifdef CONFIG_TESTING_OPTIONS + if (sm->test_assoc_ie) { + wpa_printf(MSG_DEBUG, + "TESTING: Replace association WPA/RSN IE"); + if (*wpa_ie_len < wpabuf_len(sm->test_assoc_ie)) + return -1; + os_memcpy(wpa_ie, wpabuf_head(sm->test_assoc_ie), + wpabuf_len(sm->test_assoc_ie)); + res = wpabuf_len(sm->test_assoc_ie); + } else +#endif /* CONFIG_TESTING_OPTIONS */ res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len); if (res < 0) return -1; @@ -3031,3 +3045,12 @@ void wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm, } sm->ptk_set = 1; } + + +#ifdef CONFIG_TESTING_OPTIONS +void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf) +{ + wpabuf_free(sm->test_assoc_ie); + sm->test_assoc_ie = buf; +} +#endif /* CONFIG_TESTING_OPTIONS */ diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 1d274534b..f9c89b367 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -419,5 +419,6 @@ int wpa_tdls_enable_chan_switch(struct wpa_sm *sm, const u8 *addr, int wpa_tdls_disable_chan_switch(struct wpa_sm *sm, const u8 *addr); int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf); +void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf); #endif /* WPA_H */ diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index dba6b624f..f653ba6e0 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -134,6 +134,10 @@ struct wpa_sm { #ifdef CONFIG_P2P u8 p2p_ip_addr[3 * 4]; #endif /* CONFIG_P2P */ + +#ifdef CONFIG_TESTING_OPTIONS + struct wpabuf *test_assoc_ie; +#endif /* CONFIG_TESTING_OPTIONS */ }; diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 1f4630f3d..a3b587fe8 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -6952,6 +6952,7 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) wpa_s->extra_roc_dur = 0; wpa_s->test_failure = WPAS_TEST_FAILURE_NONE; wpa_s->p2p_go_csa_on_inv = 0; + wpa_sm_set_test_assoc_ie(wpa_s->wpa, NULL); #endif /* CONFIG_TESTING_OPTIONS */ wpa_s->disconnected = 0; @@ -7841,6 +7842,35 @@ static int wpas_ctrl_event_test(struct wpa_supplicant *wpa_s, const char *cmd) (void *) (intptr_t) count); } + +static int wpas_ctrl_test_assoc_ie(struct wpa_supplicant *wpa_s, + const char *cmd) +{ + struct wpabuf *buf; + size_t len; + + len = os_strlen(cmd); + if (len & 1) + return -1; + len /= 2; + + if (len == 0) { + buf = NULL; + } else { + buf = wpabuf_alloc(len); + if (buf == NULL) + return -1; + + if (hexstr2bin(cmd, wpabuf_put(buf, len), len) < 0) { + wpabuf_free(buf); + return -1; + } + } + + wpa_sm_set_test_assoc_ie(wpa_s->wpa, buf); + return 0; +} + #endif /* CONFIG_TESTING_OPTIONS */ @@ -8805,6 +8835,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "EVENT_TEST ", 11) == 0) { if (wpas_ctrl_event_test(wpa_s, buf + 11) < 0) reply_len = -1; + } else if (os_strncmp(buf, "TEST_ASSOC_IE ", 14) == 0) { + if (wpas_ctrl_test_assoc_ie(wpa_s, buf + 14) < 0) + reply_len = -1; #endif /* CONFIG_TESTING_OPTIONS */ } else if (os_strncmp(buf, "VENDOR_ELEM_ADD ", 16) == 0) { if (wpas_ctrl_vendor_elem_add(wpa_s, buf + 16) < 0)