From 8ee0bc622a715366344e6669bc19c9bd40891aeb Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 25 May 2020 21:55:49 +0300 Subject: [PATCH] OCV: Disconnect STAs that do not use SA Query after CSA 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 --- src/ap/drv_callbacks.c | 25 +++++++++++++++++++++++-- src/ap/hostapd.c | 27 +++++++++++++++++++++++++++ src/ap/hostapd.h | 1 + src/ap/ieee802_11_shared.c | 2 ++ src/ap/sta_info.h | 1 + 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index 524a15132..173549e7b 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -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 */ } diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index f9af038be..f0af4b87c 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -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 */ diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 609c84b22..b70d13fba 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -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, diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c index ba8f2cf98..45a07085f 100644 --- a/src/ap/ieee802_11_shared.c +++ b/src/ap/ieee802_11_shared.c @@ -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; } diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h index 940d31590..ef485618a 100644 --- a/src/ap/sta_info.h +++ b/src/ap/sta_info.h @@ -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;