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 <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-05-25 21:55:49 +03:00 committed by Jouni Malinen
parent 01ceb88c77
commit 8ee0bc622a
5 changed files with 54 additions and 2 deletions

View 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 offset, int width, int cf1, int cf2,
int finished) int finished)
{ {
/* TODO: If OCV is enabled deauth STAs that don't perform a SA Query */
#ifdef NEED_AP_MLME #ifdef NEED_AP_MLME
int channel, chwidth, is_dfs; int channel, chwidth, is_dfs;
u8 seg0_idx = 0, seg1_idx = 0; 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++) for (i = 0; i < hapd->iface->num_bss; i++)
hostapd_neighbor_set_own_report(hapd->iface->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 */ #endif /* NEED_AP_MLME */
} }

View file

@ -439,6 +439,10 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd)
hostapd_clean_rrm(hapd); hostapd_clean_rrm(hapd);
fils_hlp_deinit(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 #ifdef CONFIG_SAE
{ {
struct hostapd_sae_commit_queue *q; 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); hostapd_prune_associations(hapd, sta->addr);
ap_sta_clear_disconnect_timeouts(hapd, sta); ap_sta_clear_disconnect_timeouts(hapd, sta);
sta->post_csa_sa_query = 0;
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
if (sta->p2p_ie == NULL && !sta->no_p2p_set) { 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 */ #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 */

View file

@ -632,6 +632,7 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
void hostapd_cleanup_cs_params(struct hostapd_data *hapd); void hostapd_cleanup_cs_params(struct hostapd_data *hapd);
void hostapd_periodic_iface(struct hostapd_iface *iface); void hostapd_periodic_iface(struct hostapd_iface *iface);
int hostapd_owe_trans_get_info(struct hostapd_data *hapd); 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 */ /* utils.c */
int hostapd_register_probereq_cb(struct hostapd_data *hapd, int hostapd_register_probereq_cb(struct hostapd_data *hapd,

View file

@ -267,6 +267,8 @@ void ieee802_11_sa_query_action(struct hostapd_data *hapd,
#endif /* CONFIG_OCV */ #endif /* CONFIG_OCV */
if (action_type == WLAN_SA_QUERY_REQUEST) { 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); ieee802_11_send_sa_query_resp(hapd, sa, trans_id);
return; return;
} }

View file

@ -122,6 +122,7 @@ struct sta_info {
unsigned int hs20_t_c_filtering:1; unsigned int hs20_t_c_filtering:1;
unsigned int ft_over_ds:1; unsigned int ft_over_ds:1;
unsigned int external_dh_updated:1; unsigned int external_dh_updated:1;
unsigned int post_csa_sa_query:1;
u16 auth_alg; u16 auth_alg;