]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Extend hostapd rsnxe_override_eapol to allow IE removal
authorJouni Malinen <j@w1.fi>
Sat, 7 Mar 2020 14:39:36 +0000 (16:39 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 7 Mar 2020 14:39:36 +0000 (16:39 +0200)
Previous implementation was determining whether the override value was
set based on its length being larger than zero. Replace this with an
explicit indication of whether the parameter is set to allow zero length
replacement, i.e., remove of RSNXE from EAPOL-Key msg 3/4.

In addition, move IE replacement into a more generic helper function to
allow this to be used with other IEs as well.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_glue.c

index 07cc514d9ed5f1d1052b89804013df02e7c66898..f914875fe2d282b6b0f4bc9ce546702de4478d79 100644 (file)
@@ -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,
index 1f7ba4899dd37128edf08ea47ea458b34be7eefa..93d7f74f26c1c6c015bd92f88c58614b8e86bdfb 100644 (file)
@@ -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 */
index 82e82a7d2ca99885ee618da761fae44a1fcd4ebd..4a303b039dfe939762dcaf57f2b03b2d43fdfcd6 100644 (file)
@@ -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,