]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add EAPOL_TX command to extend ext_eapol_frame_io possibilities
authorJouni Malinen <jouni@codeaurora.org>
Mon, 1 Feb 2021 14:57:14 +0000 (16:57 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 11 May 2021 18:13:56 +0000 (21:13 +0300)
This makes it convenient for an external test script to use
ext_eapol_frame_io=1 to delay and/or modify transmission of EAPOL-Key
msg 1/4 without having to use separate frame injection mechanisms.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
hostapd/ctrl_iface.c
src/ap/wpa_auth.h
src/ap/wpa_auth_glue.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/wpas_glue.c
wpa_supplicant/wpas_glue.h

index 911098066ad6d21ab9248e63ad77c5674085f3d7..4a2d60627070fd76b8a0ab0543dcfd8bb8e6d658 100644 (file)
@@ -1946,6 +1946,52 @@ static int hostapd_ctrl_iface_eapol_rx(struct hostapd_data *hapd, char *cmd)
 }
 
 
+static int hostapd_ctrl_iface_eapol_tx(struct hostapd_data *hapd, char *cmd)
+{
+       char *pos, *pos2;
+       u8 dst[ETH_ALEN], *buf;
+       int used, ret;
+       size_t len;
+       unsigned int prev;
+       int encrypt = 0;
+
+       wpa_printf(MSG_DEBUG, "External EAPOL TX: %s", cmd);
+
+       pos = cmd;
+       used = hwaddr_aton2(pos, dst);
+       if (used < 0)
+               return -1;
+       pos += used;
+       while (*pos == ' ')
+               pos++;
+
+       pos2 = os_strchr(pos, ' ');
+       if (pos2) {
+               len = pos2 - pos;
+               encrypt = os_strstr(pos2, "encrypt=1") != NULL;
+       } else {
+               len = os_strlen(pos);
+       }
+       if (len & 1)
+               return -1;
+       len /= 2;
+
+       buf = os_malloc(len);
+       if (!buf || hexstr2bin(pos, buf, len) < 0) {
+               os_free(buf);
+               return -1;
+       }
+
+       prev = hapd->ext_eapol_frame_io;
+       hapd->ext_eapol_frame_io = 0;
+       ret = hostapd_wpa_auth_send_eapol(hapd, dst, buf, len, encrypt);
+       hapd->ext_eapol_frame_io = prev;
+       os_free(buf);
+
+       return ret;
+}
+
+
 static u16 ipv4_hdr_checksum(const void *buf, size_t len)
 {
        size_t i;
@@ -3651,6 +3697,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
        } else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
                if (hostapd_ctrl_iface_eapol_rx(hapd, buf + 9) < 0)
                        reply_len = -1;
+       } else if (os_strncmp(buf, "EAPOL_TX ", 9) == 0) {
+               if (hostapd_ctrl_iface_eapol_tx(hapd, buf + 9) < 0)
+                       reply_len = -1;
        } else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
                if (hostapd_ctrl_iface_data_test_config(hapd, buf + 17) < 0)
                        reply_len = -1;
index ec3e0b5d75b67a1aaef5d5a9813d9d48236d8a9a..fe47723b9e6bb8b81161fe744d2aed8a8ae6c93e 100644 (file)
@@ -556,6 +556,9 @@ int wpa_auth_resend_group_m1(struct wpa_state_machine *sm,
 int wpa_auth_rekey_ptk(struct wpa_authenticator *wpa_auth,
                       struct wpa_state_machine *sm);
 int wpa_auth_rekey_gtk(struct wpa_authenticator *wpa_auth);
+int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
+                               const u8 *data, size_t data_len,
+                               int encrypt);
 void wpa_auth_set_ptk_rekey_timer(struct wpa_state_machine *sm);
 void wpa_auth_set_ft_rsnxe_used(struct wpa_authenticator *wpa_auth, int val);
 
index c3b2e81e2e72dc0996c5cf117f118c8d19fdee51..7ca292530dc157c8ed3fd43670a2f1ea64104a55 100644 (file)
@@ -505,9 +505,9 @@ static int hostapd_wpa_auth_get_seqnum(void *ctx, const u8 *addr, int idx,
 }
 
 
-static int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
-                                      const u8 *data, size_t data_len,
-                                      int encrypt)
+int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
+                               const u8 *data, size_t data_len,
+                               int encrypt)
 {
        struct hostapd_data *hapd = ctx;
        struct sta_info *sta;
index bf83e41686a0b03ef6c7e0551971c6ecfc653bd2..ba91cfb11d1455f581195043622b93ff2413cf44 100644 (file)
@@ -39,6 +39,7 @@
 #include "driver_i.h"
 #include "wps_supplicant.h"
 #include "ibss_rsn.h"
+#include "wpas_glue.h"
 #include "ap.h"
 #include "p2p_supplicant.h"
 #include "p2p/p2p.h"
@@ -9519,6 +9520,45 @@ static int wpas_ctrl_iface_eapol_rx(struct wpa_supplicant *wpa_s, char *cmd)
 }
 
 
+static int wpas_ctrl_iface_eapol_tx(struct wpa_supplicant *wpa_s, char *cmd)
+{
+       char *pos;
+       u8 dst[ETH_ALEN], *buf;
+       int used, ret;
+       size_t len;
+       unsigned int prev;
+
+       wpa_printf(MSG_DEBUG, "External EAPOL TX: %s", cmd);
+
+       pos = cmd;
+       used = hwaddr_aton2(pos, dst);
+       if (used < 0)
+               return -1;
+       pos += used;
+       while (*pos == ' ')
+               pos++;
+
+       len = os_strlen(pos);
+       if (len & 1)
+               return -1;
+       len /= 2;
+
+       buf = os_malloc(len);
+       if (!buf || hexstr2bin(pos, buf, len) < 0) {
+               os_free(buf);
+               return -1;
+       }
+
+       prev = wpa_s->ext_eapol_frame_io;
+       wpa_s->ext_eapol_frame_io = 0;
+       ret = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, buf, len);
+       wpa_s->ext_eapol_frame_io = prev;
+       os_free(buf);
+
+       return ret;
+}
+
+
 static u16 ipv4_hdr_checksum(const void *buf, size_t len)
 {
        size_t i;
@@ -11514,6 +11554,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
                if (wpas_ctrl_iface_eapol_rx(wpa_s, buf + 9) < 0)
                        reply_len = -1;
+       } else if (os_strncmp(buf, "EAPOL_TX ", 9) == 0) {
+               if (wpas_ctrl_iface_eapol_tx(wpa_s, buf + 9) < 0)
+                       reply_len = -1;
        } else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
                if (wpas_ctrl_iface_data_test_config(wpa_s, buf + 17) < 0)
                        reply_len = -1;
index 240e3d2d9ba961e3f9d47528198ac9fec2726d14..96818697882fa2b934f4c1a7e8373a919e33e65c 100644 (file)
@@ -95,8 +95,8 @@ static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
  * @len: Frame payload length
  * Returns: >=0 on success, <0 on failure
  */
-static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
-                         u16 proto, const u8 *buf, size_t len)
+int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
+                  u16 proto, const u8 *buf, size_t len)
 {
 #ifdef CONFIG_TESTING_OPTIONS
        if (wpa_s->ext_eapol_frame_io && proto == ETH_P_EAPOL) {
index 5585e5615a652b3ba442a5343167b77f6d4f404a..338af4e650a758a22d8245e20b06c46ee23b7698 100644 (file)
@@ -15,6 +15,8 @@ int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s);
 int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
                                        struct wpa_ssid *ssid);
+int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
+                  u16 proto, const u8 *buf, size_t len);
 
 const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
                                               const char *default_txt,