]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
PASN: Add support for deauthentication flow in station
authorIlan Peer <ilan.peer@intel.com>
Mon, 15 Mar 2021 12:57:12 +0000 (14:57 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 16 Mar 2021 20:49:28 +0000 (22:49 +0200)
The new wpa_supplicant control interface command "PASN_DEAUTH
bssid=<BSSID>" can now be used to flush the local PTKSA cache for the
specified BSS and to notify the AP to request it to drop its PTKSA as
well.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
wpa_supplicant/ctrl_iface.c
wpa_supplicant/pasn_supplicant.c
wpa_supplicant/wpa_cli.c
wpa_supplicant/wpa_supplicant_i.h

index c05175822c39899230aacee0254e8a587945188c..b54d7d4968d87cb8e7fb983e05fce24cc04098fe 100644 (file)
@@ -10655,6 +10655,22 @@ static int wpas_ctrl_iface_pasn_start(struct wpa_supplicant *wpa_s, char *cmd)
 
        return wpas_pasn_auth_start(wpa_s, bssid, akmp, cipher, group, id);
 }
+
+
+static int wpas_ctrl_iface_pasn_deauthenticate(struct wpa_supplicant *wpa_s,
+                                              const char *cmd)
+{
+       u8 bssid[ETH_ALEN];
+
+       if (os_strncmp(cmd, "bssid=", 6) != 0 || hwaddr_aton(cmd + 6, bssid)) {
+               wpa_printf(MSG_DEBUG,
+                          "CTRL: PASN_DEAUTH without valid BSSID");
+               return -1;
+       }
+
+       return wpas_pasn_deauthenticate(wpa_s, bssid);
+}
+
 #endif /* CONFIG_PASN */
 
 
@@ -11576,6 +11592,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                wpas_pasn_auth_stop(wpa_s);
        } else if (os_strcmp(buf, "PTKSA_CACHE_LIST") == 0) {
                reply_len = ptksa_cache_list(wpa_s->ptksa, reply, reply_size);
+       } else if (os_strncmp(buf, "PASN_DEAUTH ", 12) == 0) {
+               if (wpas_ctrl_iface_pasn_deauthenticate(wpa_s, buf + 12) < 0)
+                       reply_len = -1;
 #endif /* CONFIG_PASN */
        } else {
                os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
index f7c61542fb63b1c9758abbe6a64c271e879e25ed..e6adf73f3e421934bd1307618856d477ccbdfd5e 100644 (file)
@@ -1526,3 +1526,59 @@ int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
 
        return 0;
 }
+
+
+int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *bssid)
+{
+       struct wpa_bss *bss;
+       struct wpabuf *buf;
+       struct ieee80211_mgmt *deauth;
+       int ret;
+
+       if (os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) == 0) {
+               wpa_printf(MSG_DEBUG,
+                          "PASN: Cannot deauthenticate from current BSS");
+               return -1;
+       }
+
+       wpa_printf(MSG_DEBUG, "PASN: deauth: Flushing all PTKSA entries for "
+                  MACSTR, MAC2STR(bssid));
+       ptksa_cache_flush(wpa_s->ptksa, bssid, WPA_CIPHER_NONE);
+
+       bss = wpa_bss_get_bssid(wpa_s, bssid);
+       if (!bss) {
+               wpa_printf(MSG_DEBUG, "PASN: deauth: BSS not found");
+               return -1;
+       }
+
+       buf = wpabuf_alloc(64);
+       if (!buf) {
+               wpa_printf(MSG_DEBUG, "PASN: deauth: Failed wpabuf allocate");
+               return -1;
+       }
+
+       deauth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
+                                         u.deauth.variable));
+
+       deauth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
+                                            (WLAN_FC_STYPE_DEAUTH << 4));
+
+       os_memcpy(deauth->da, bssid, ETH_ALEN);
+       os_memcpy(deauth->sa, wpa_s->own_addr, ETH_ALEN);
+       os_memcpy(deauth->bssid, bssid, ETH_ALEN);
+       deauth->u.deauth.reason_code =
+               host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
+
+       /*
+        * Since we do not expect any response from the AP, implement the
+        * Deauthentication frame transmission using direct call to the driver
+        * without a radio work.
+        */
+       ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1,
+                               bss->freq, 0);
+
+       wpabuf_free(buf);
+       wpa_printf(MSG_DEBUG, "PASN: deauth: send_mlme ret=%d", ret);
+
+       return ret;
+}
index 95608971faca6d32b95c3304c82ad0c2849b0037..fea7b85e081d31b7775708c495acbf1da2dcf896 100644 (file)
@@ -3210,6 +3210,13 @@ static int wpa_cli_cmd_ptksa_cache_list(struct wpa_ctrl *ctrl, int argc,
        return wpa_cli_cmd(ctrl, "PTKSA_CACHE_LIST", 0, argc, argv);
 }
 
+
+static int wpa_cli_cmd_pasn_deauth(struct wpa_ctrl *ctrl, int argc,
+                                  char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "PASN_DEAUTH", 1, argc, argv);
+}
+
 #endif /* CONFIG_PASN */
 
 
@@ -3913,6 +3920,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
        { "ptksa_cache_list", wpa_cli_cmd_ptksa_cache_list, NULL,
          cli_cmd_flag_none,
          "= Get the PTKSA Cache" },
+       { "pasn_deauth", wpa_cli_cmd_pasn_deauth, NULL,
+         cli_cmd_flag_none,
+         "bssid=<BSSID> = Remove PASN PTKSA state" },
 #endif /* CONFIG_PASN */
        { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
 };
index 68d78c11fdf4fbc1109d14337eaafa315b301ceb..7ed8c0ee4d92048771dfdf81ca8c14af113b8348 100644 (file)
@@ -1737,4 +1737,6 @@ int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
 int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
                      const struct ieee80211_mgmt *mgmt, size_t len);
 
+int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *bssid);
+
 #endif /* WPA_SUPPLICANT_I_H */