WNM: Remove PMKSA cache entry on ESS disassoc imminent notification
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 5 Apr 2013 15:55:32 +0000 (18:55 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 23 May 2013 13:50:06 +0000 (16:50 +0300)
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>

hostapd/ctrl_iface.c
src/ap/pmksa_cache_auth.c
src/ap/pmksa_cache_auth.h
src/ap/wpa_auth.c
src/ap/wpa_auth.h

index 7fc520c..b0ca6cc 100644 (file)
@@ -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 "
index d27fd30..40972e9 100644 (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,
-                                  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;
 
index d473f3f..aa90024 100644 (file)
@@ -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 */
index 18ae86c..83cc857 100644 (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 *
 wpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id)
 {
index 9126b90..ebfe86f 100644 (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,
                               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);