]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OCV: Disconnect STAs that do not use SA Query after CSA
authorJouni Malinen <jouni@codeaurora.org>
Mon, 25 May 2020 18:55:49 +0000 (21:55 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 25 May 2020 18:57:04 +0000 (21:57 +0300)
Verify that all associated STAs that claim support for OCV initiate an
SA Query after CSA. If no SA Query is seen within 15 seconds,
deauthenticate the STA.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/drv_callbacks.c
src/ap/hostapd.c
src/ap/hostapd.h
src/ap/ieee802_11_shared.c
src/ap/sta_info.h

index 524a15132b8ad9a10a530f48b9c6403dd0788ccf..173549e7bb41bcc69b2c00e5955456ac16d8b658 100644 (file)
@@ -844,8 +844,6 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
                             int offset, int width, int cf1, int cf2,
                             int finished)
 {
-       /* TODO: If OCV is enabled deauth STAs that don't perform a SA Query */
-
 #ifdef NEED_AP_MLME
        int channel, chwidth, is_dfs;
        u8 seg0_idx = 0, seg1_idx = 0;
@@ -958,6 +956,29 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
 
        for (i = 0; i < hapd->iface->num_bss; i++)
                hostapd_neighbor_set_own_report(hapd->iface->bss[i]);
+
+#ifdef CONFIG_OCV
+       if (hapd->conf->ocv) {
+               struct sta_info *sta;
+               bool check_sa_query = false;
+
+               for (sta = hapd->sta_list; sta; sta = sta->next) {
+                       if (wpa_auth_uses_ocv(sta->wpa_sm) &&
+                           !(sta->flags & WLAN_STA_WNM_SLEEP_MODE)) {
+                               sta->post_csa_sa_query = 1;
+                               check_sa_query = true;
+                       }
+               }
+
+               if (check_sa_query) {
+                       wpa_printf(MSG_DEBUG,
+                                  "OCV: Check post-CSA SA Query initiation in 15 seconds");
+                       eloop_register_timeout(15, 0,
+                                              hostapd_ocv_check_csa_sa_query,
+                                              hapd, NULL);
+               }
+       }
+#endif /* CONFIG_OCV */
 #endif /* NEED_AP_MLME */
 }
 
index f9af038bec9ac7f7e2e8ae89cbb29d4def383c7a..f0af4b87c77d515c0fb95aafe44456f15ff1c937 100644 (file)
@@ -439,6 +439,10 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd)
        hostapd_clean_rrm(hapd);
        fils_hlp_deinit(hapd);
 
+#ifdef CONFIG_OCV
+       eloop_cancel_timeout(hostapd_ocv_check_csa_sa_query, hapd, NULL);
+#endif /* CONFIG_OCV */
+
 #ifdef CONFIG_SAE
        {
                struct hostapd_sae_commit_queue *q;
@@ -3151,6 +3155,7 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
 
        hostapd_prune_associations(hapd, sta->addr);
        ap_sta_clear_disconnect_timeouts(hapd, sta);
+       sta->post_csa_sa_query = 0;
 
 #ifdef CONFIG_P2P
        if (sta->p2p_ie == NULL && !sta->no_p2p_set) {
@@ -3662,3 +3667,25 @@ void hostapd_periodic_iface(struct hostapd_iface *iface)
 #endif /* CONFIG_NO_RADIUS */
        }
 }
+
+
+#ifdef CONFIG_OCV
+void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx)
+{
+       struct hostapd_data *hapd = eloop_ctx;
+       struct sta_info *sta;
+
+       wpa_printf(MSG_DEBUG, "OCV: Post-CSA SA Query initiation check");
+
+       for (sta = hapd->sta_list; sta; sta = sta->next) {
+               if (!sta->post_csa_sa_query)
+                       continue;
+
+               wpa_printf(MSG_DEBUG, "OCV: OCVC STA " MACSTR
+                          " did not start SA Query after CSA - disconnect",
+                          MAC2STR(sta->addr));
+               ap_sta_disconnect(hapd, sta, sta->addr,
+                                 WLAN_REASON_PREV_AUTH_NOT_VALID);
+       }
+}
+#endif /* CONFIG_OCV */
index 609c84b22bad35495ac7fa48c09a64803c6a4aea..b70d13fbab47c38d0c791007d62bb7f224c8bc10 100644 (file)
@@ -632,6 +632,7 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
 void hostapd_cleanup_cs_params(struct hostapd_data *hapd);
 void hostapd_periodic_iface(struct hostapd_iface *iface);
 int hostapd_owe_trans_get_info(struct hostapd_data *hapd);
+void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx);
 
 /* utils.c */
 int hostapd_register_probereq_cb(struct hostapd_data *hapd,
index ba8f2cf98498feb088568602ff4574675afdd74b..45a07085f77e9664d19fc3b68e9b33dc1c91a11c 100644 (file)
@@ -267,6 +267,8 @@ void ieee802_11_sa_query_action(struct hostapd_data *hapd,
 #endif /* CONFIG_OCV */
 
        if (action_type == WLAN_SA_QUERY_REQUEST) {
+               if (sta)
+                       sta->post_csa_sa_query = 0;
                ieee802_11_send_sa_query_resp(hapd, sa, trans_id);
                return;
        }
index 940d3159082f04d41587609e988f996aa2384618..ef485618a337740d18ec543613d65339dc8548ad 100644 (file)
@@ -122,6 +122,7 @@ struct sta_info {
        unsigned int hs20_t_c_filtering:1;
        unsigned int ft_over_ds:1;
        unsigned int external_dh_updated:1;
+       unsigned int post_csa_sa_query:1;
 
        u16 auth_alg;