Add a drop_sa command to allow 802.11w testing
authorJouni Malinen <jouni.malinen@atheros.com>
Mon, 29 Mar 2010 22:42:04 +0000 (15:42 -0700)
committerJouni Malinen <j@w1.fi>
Mon, 29 Mar 2010 22:42:04 +0000 (15:42 -0700)
This drops PTK and PMK without notifying the AP.

src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/wpa_cli.c

index 495e54c..a50dfd5 100644 (file)
@@ -2379,3 +2379,14 @@ int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len)
        return -1;
 #endif /* CONFIG_NO_WPA2 */
 }
+
+
+void wpa_sm_drop_sa(struct wpa_sm *sm)
+{
+       wpa_printf(MSG_DEBUG, "WPA: Clear old PMK and PTK");
+       sm->ptk_set = 0;
+       sm->tptk_set = 0;
+       os_memset(sm->pmk, 0, sizeof(sm->pmk));
+       os_memset(&sm->ptk, 0, sizeof(sm->ptk));
+       os_memset(&sm->tptk, 0, sizeof(sm->tptk));
+}
index 8db5fda..5ff6906 100644 (file)
@@ -123,6 +123,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
                    const u8 *buf, size_t len);
 int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data);
 int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len);
+void wpa_sm_drop_sa(struct wpa_sm *sm);
 
 #else /* CONFIG_NO_WPA */
 
@@ -260,6 +261,10 @@ static inline int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf,
        return -1;
 }
 
+static inline void wpa_sm_drop_sa(struct wpa_sm *sm)
+{
+}
+
 #endif /* CONFIG_NO_WPA */
 
 #ifdef CONFIG_PEERKEY
index 438bc27..c7d3427 100644 (file)
@@ -1615,6 +1615,31 @@ static int wpa_supplicant_ctrl_iface_ap_scan(
 }
 
 
+static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
+{
+       u8 *bcast = (u8 *) "\xff\xff\xff\xff\xff\xff";
+
+       wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
+       /* MLME-DELETEKEYS.request */
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 0, 0, NULL, 0, NULL, 0);
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 1, 0, NULL, 0, NULL, 0);
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 2, 0, NULL, 0, NULL, 0);
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 3, 0, NULL, 0, NULL, 0);
+#ifdef CONFIG_IEEE80211W
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 4, 0, NULL, 0, NULL, 0);
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 5, 0, NULL, 0, NULL, 0);
+#endif /* CONFIG_IEEE80211W */
+
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
+                       0);
+       /* MLME-SETPROTECTION.request(None) */
+       wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
+                                  MLME_SETPROTECTION_PROTECT_TYPE_NONE,
+                                  MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
+       wpa_sm_drop_sa(wpa_s->wpa);
+}
+
+
 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                                         char *buf, size_t *resp_len)
 {
@@ -1818,6 +1843,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                wpas_notify_suspend(wpa_s->global);
        } else if (os_strcmp(buf, "RESUME") == 0) {
                wpas_notify_resume(wpa_s->global);
+       } else if (os_strcmp(buf, "DROP_SA") == 0) {
+               wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
        } else {
                os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
                reply_len = 16;
index 75582d8..8e17b96 100644 (file)
@@ -1434,6 +1434,12 @@ static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
 }
 
 
+static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+       return wpa_ctrl_command(ctrl, "DROP_SA");
+}
+
+
 enum wpa_cli_cmd_flags {
        cli_cmd_flag_none               = 0x00,
        cli_cmd_flag_sensitive          = 0x01
@@ -1632,6 +1638,8 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
          "= notification of suspend/hibernate" },
        { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
          "= notification of resume/thaw" },
+       { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
+         "= drop SA without deauth/disassoc (test command)" },
        { NULL, NULL, cli_cmd_flag_none, NULL }
 };