WNM: Remove PMKSA cache entry on ESS disassoc imminent notification

This is needed to avoid allowing the STA to reconnect using a cached
PMKSA. ESS disassoc imminent notification is normally used to indicate
that the STA session will be terminated and as such, requiring full
authentication through the authentication server after this is needed.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2013-04-05 18:55:32 +03:00 committed by Jouni Malinen
parent dad153d16b
commit 901d1fe1e5
5 changed files with 30 additions and 2 deletions

View file

@ -29,6 +29,7 @@
#include "ap/wps_hostapd.h" #include "ap/wps_hostapd.h"
#include "ap/ctrl_iface_ap.h" #include "ap/ctrl_iface_ap.h"
#include "ap/ap_drv_ops.h" #include "ap/ap_drv_ops.h"
#include "ap/wpa_auth.h"
#include "wps/wps_defs.h" #include "wps/wps_defs.h"
#include "wps/wps.h" #include "wps/wps.h"
#include "config_file.h" #include "config_file.h"
@ -595,6 +596,13 @@ static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd,
if (disassoc_timer) { if (disassoc_timer) {
struct sta_info *sta; 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); sta = ap_get_sta(hapd, addr);
if (sta == NULL) { if (sta == NULL) {
wpa_printf(MSG_DEBUG, "Station " MACSTR " not found " wpa_printf(MSG_DEBUG, "Station " MACSTR " not found "

View file

@ -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, void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa,
struct rsn_pmksa_cache_entry *entry) struct rsn_pmksa_cache_entry *entry)
{ {
struct rsn_pmksa_cache_entry *pos, *prev; struct rsn_pmksa_cache_entry *pos, *prev;

View file

@ -55,5 +55,7 @@ pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
const u8 *aa, const u8 *pmkid); const u8 *aa, const u8 *pmkid);
void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry, void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry,
struct eapol_state_machine *eapol); 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 */ #endif /* PMKSA_CACHE_H */

View file

@ -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 * static struct wpa_group *
wpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id) wpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id)
{ {

View file

@ -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, const u8 *pmk, size_t len, const u8 *sta_addr,
int session_timeout, int session_timeout,
struct eapol_state_machine *eapol); 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); 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, void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm, int ack); struct wpa_state_machine *sm, int ack);