Add TEST_ASSOC_IE for WPA/RSN IE testing on AP side
authorJouni Malinen <j@w1.fi>
Sun, 6 Dec 2015 17:30:59 +0000 (19:30 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 6 Dec 2015 17:33:16 +0000 (19:33 +0200)
The new wpa_supplicant control interface command "TEST_ASSOC_IE
<hexdump>" can now be used to override the WPA/RSN IE for Association
Request frame and following 4-way handshake to allow protocol testing of
AP side processing of WPA/RSN IE.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_i.h
wpa_supplicant/ctrl_iface.c

index 0b5fe51..7a70823 100644 (file)
@@ -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 */
index 1d27453..f9c89b3 100644 (file)
@@ -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 */
index dba6b62..f653ba6 100644 (file)
@@ -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 */
 };
 
 
index 1f4630f..a3b587f 100644 (file)
@@ -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)