]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
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 7fc520c4880cb4b3c3d03475c4d8c86a9a6f2867..b0ca6cc11ac94e5b8415618d5bd60db9e6dcce29 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 d27fd302ba9699c8cbb7e68f3621d32443c6bddc..40972e9a01932f6c4730a1d5ebdbe594f677f55f 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 d473f3fdced3a4c7bf7476b2666e82df02ad4ce0..aa90024d7df8d4d0fbc1fcbb65c15536c7b23a95 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 18ae86c8bdc3bdf2bab22259327eb99ad416beeb..83cc857823a574e3ac5cce2af38aef18d33a0f51 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 9126b90dc7711388050d37e33eec9b507b129b80..ebfe86f0e3bc8ca27958c88223d401ae4d80e652 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);