diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 7fc520c48..b0ca6cc11 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -29,6 +29,7 @@ #include "ap/wps_hostapd.h" #include "ap/ctrl_iface_ap.h" #include "ap/ap_drv_ops.h" +#include "ap/wpa_auth.h" #include "wps/wps_defs.h" #include "wps/wps.h" #include "config_file.h" @@ -595,6 +596,13 @@ static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd, if (disassoc_timer) { struct sta_info *sta; + /* + * Prevent STA from reconnecting using cached PMKSA to force + * full authentication with the authentication server (which may + * decide to reject the connection), + */ + wpa_auth_pmksa_remove(hapd->wpa_auth, addr); + sta = ap_get_sta(hapd, addr); if (sta == NULL) { wpa_printf(MSG_DEBUG, "Station " MACSTR " not found " diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c index d27fd302b..40972e9a0 100644 --- a/src/ap/pmksa_cache_auth.c +++ b/src/ap/pmksa_cache_auth.c @@ -48,8 +48,8 @@ static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry) } -static void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa, - struct rsn_pmksa_cache_entry *entry) +void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa, + struct rsn_pmksa_cache_entry *entry) { struct rsn_pmksa_cache_entry *pos, *prev; diff --git a/src/ap/pmksa_cache_auth.h b/src/ap/pmksa_cache_auth.h index d473f3fdc..aa90024d7 100644 --- a/src/ap/pmksa_cache_auth.h +++ b/src/ap/pmksa_cache_auth.h @@ -55,5 +55,7 @@ pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa, const u8 *aa, const u8 *pmkid); void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry, struct eapol_state_machine *eapol); +void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa, + struct rsn_pmksa_cache_entry *entry); #endif /* PMKSA_CACHE_H */ diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 18ae86c8b..83cc85782 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -2944,6 +2944,22 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, } +void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, + const u8 *sta_addr) +{ + struct rsn_pmksa_cache_entry *pmksa; + + if (wpa_auth == NULL || wpa_auth->pmksa == NULL) + return; + pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sta_addr, NULL); + if (pmksa) { + wpa_printf(MSG_DEBUG, "WPA: Remove PMKSA cache entry for " + MACSTR " based on request", MAC2STR(sta_addr)); + pmksa_cache_free_entry(wpa_auth->pmksa, pmksa); + } +} + + static struct wpa_group * wpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id) { diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 9126b90dc..ebfe86f0e 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -263,6 +263,8 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, const u8 *pmk, size_t len, const u8 *sta_addr, int session_timeout, struct eapol_state_machine *eapol); +void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, + const u8 *sta_addr); int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id); void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *sm, int ack);