Flush PMKSA cache entries and invalidate EAP state on network changes
If a network configuration block is removed or modified, flush all PMKSA cache entries that were created using that network configuration. Similarly, invalidate EAP state (fast re-auth). The special case for OKC on wpa_supplicant reconfiguration (network_ctx pointer change) is now addressed as part of the PMKSA cache flushing, so it does not need a separate mechanism for clearing the network_ctx values in the PMKSA cache.
This commit is contained in:
parent
f3857c2e6a
commit
d8a790b922
7 changed files with 69 additions and 29 deletions
|
@ -229,6 +229,40 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pmksa_cache_flush - Flush PMKSA cache entries for a specific network
|
||||||
|
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
|
||||||
|
* @network_ctx: Network configuration context or %NULL to flush all entries
|
||||||
|
*/
|
||||||
|
void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx)
|
||||||
|
{
|
||||||
|
struct rsn_pmksa_cache_entry *entry, *prev = NULL, *tmp;
|
||||||
|
int removed = 0;
|
||||||
|
|
||||||
|
entry = pmksa->pmksa;
|
||||||
|
while (entry) {
|
||||||
|
if (entry->network_ctx == network_ctx || network_ctx == NULL) {
|
||||||
|
wpa_printf(MSG_DEBUG, "RSN: Flush PMKSA cache entry "
|
||||||
|
"for " MACSTR, MAC2STR(entry->aa));
|
||||||
|
if (prev)
|
||||||
|
prev->next = entry->next;
|
||||||
|
else
|
||||||
|
pmksa->pmksa = entry->next;
|
||||||
|
tmp = entry;
|
||||||
|
entry = entry->next;
|
||||||
|
wpa_sm_remove_pmkid(pmksa->sm, tmp->aa, tmp->pmkid);
|
||||||
|
pmksa_cache_free_entry(pmksa, tmp, 0);
|
||||||
|
removed++;
|
||||||
|
} else {
|
||||||
|
prev = entry;
|
||||||
|
entry = entry->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (removed)
|
||||||
|
pmksa_cache_set_expiration(pmksa);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pmksa_cache_deinit - Free all entries in PMKSA cache
|
* pmksa_cache_deinit - Free all entries in PMKSA cache
|
||||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
|
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
|
||||||
|
@ -274,22 +308,6 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pmksa_cache_notify_reconfig - Reconfiguration notification for PMKSA cache
|
|
||||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
|
|
||||||
*
|
|
||||||
* Clear references to old data structures when wpa_supplicant is reconfigured.
|
|
||||||
*/
|
|
||||||
void pmksa_cache_notify_reconfig(struct rsn_pmksa_cache *pmksa)
|
|
||||||
{
|
|
||||||
struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
|
|
||||||
while (entry) {
|
|
||||||
entry->network_ctx = NULL;
|
|
||||||
entry = entry->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct rsn_pmksa_cache_entry *
|
static struct rsn_pmksa_cache_entry *
|
||||||
pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa,
|
pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa,
|
||||||
const struct rsn_pmksa_cache_entry *old_entry,
|
const struct rsn_pmksa_cache_entry *old_entry,
|
||||||
|
|
|
@ -57,7 +57,6 @@ int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len);
|
||||||
struct rsn_pmksa_cache_entry *
|
struct rsn_pmksa_cache_entry *
|
||||||
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||||
const u8 *aa, const u8 *spa, void *network_ctx, int akmp);
|
const u8 *aa, const u8 *spa, void *network_ctx, int akmp);
|
||||||
void pmksa_cache_notify_reconfig(struct rsn_pmksa_cache *pmksa);
|
|
||||||
struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm);
|
struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm);
|
||||||
void pmksa_cache_clear_current(struct wpa_sm *sm);
|
void pmksa_cache_clear_current(struct wpa_sm *sm);
|
||||||
int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid,
|
int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid,
|
||||||
|
@ -66,6 +65,7 @@ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid,
|
||||||
struct rsn_pmksa_cache_entry *
|
struct rsn_pmksa_cache_entry *
|
||||||
pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa,
|
pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa,
|
||||||
void *network_ctx, const u8 *aa);
|
void *network_ctx, const u8 *aa);
|
||||||
|
void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx);
|
||||||
|
|
||||||
#else /* IEEE8021X_EAPOL and !CONFIG_NO_WPA2 */
|
#else /* IEEE8021X_EAPOL and !CONFIG_NO_WPA2 */
|
||||||
|
|
||||||
|
@ -106,10 +106,6 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pmksa_cache_notify_reconfig(struct rsn_pmksa_cache *pmksa)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void pmksa_cache_clear_current(struct wpa_sm *sm)
|
static inline void pmksa_cache_clear_current(struct wpa_sm *sm)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -122,6 +118,11 @@ static inline int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa,
|
||||||
|
void *network_ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* IEEE8021X_EAPOL and !CONFIG_NO_WPA2 */
|
#endif /* IEEE8021X_EAPOL and !CONFIG_NO_WPA2 */
|
||||||
|
|
||||||
#endif /* PMKSA_CACHE_H */
|
#endif /* PMKSA_CACHE_H */
|
||||||
|
|
|
@ -2269,8 +2269,6 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
|
||||||
sm->ssid_len = 0;
|
sm->ssid_len = 0;
|
||||||
sm->wpa_ptk_rekey = 0;
|
sm->wpa_ptk_rekey = 0;
|
||||||
}
|
}
|
||||||
if (config == NULL || config->network_ctx != sm->network_ctx)
|
|
||||||
pmksa_cache_notify_reconfig(sm->pmksa);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2654,3 +2652,11 @@ void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
|
||||||
{
|
{
|
||||||
os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
|
os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_NO_WPA2
|
||||||
|
pmksa_cache_flush(sm->pmksa, network_ctx);
|
||||||
|
#endif /* CONFIG_NO_WPA2 */
|
||||||
|
}
|
||||||
|
|
|
@ -136,6 +136,8 @@ int wpa_sm_has_ptk(struct wpa_sm *sm);
|
||||||
|
|
||||||
void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr);
|
void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr);
|
||||||
|
|
||||||
|
void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx);
|
||||||
|
|
||||||
#else /* CONFIG_NO_WPA */
|
#else /* CONFIG_NO_WPA */
|
||||||
|
|
||||||
static inline struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
|
static inline struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
|
||||||
|
@ -286,6 +288,11 @@ static inline void wpa_sm_update_replay_ctr(struct wpa_sm *sm,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm,
|
||||||
|
void *network_ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NO_WPA */
|
#endif /* CONFIG_NO_WPA */
|
||||||
|
|
||||||
#ifdef CONFIG_PEERKEY
|
#ifdef CONFIG_PEERKEY
|
||||||
|
|
|
@ -1395,8 +1395,8 @@ static int wpa_supplicant_ctrl_iface_remove_network(
|
||||||
wpas_notify_network_removed(wpa_s, remove_ssid);
|
wpas_notify_network_removed(wpa_s, remove_ssid);
|
||||||
wpa_config_remove_network(wpa_s->conf, id);
|
wpa_config_remove_network(wpa_s->conf, id);
|
||||||
}
|
}
|
||||||
if (wpa_s->current_ssid) {
|
|
||||||
eapol_sm_invalidate_cached_session(wpa_s->eapol);
|
eapol_sm_invalidate_cached_session(wpa_s->eapol);
|
||||||
|
if (wpa_s->current_ssid) {
|
||||||
wpa_sm_set_config(wpa_s->wpa, NULL);
|
wpa_sm_set_config(wpa_s->wpa, NULL);
|
||||||
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
|
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
|
||||||
wpa_supplicant_disassociate(wpa_s,
|
wpa_supplicant_disassociate(wpa_s,
|
||||||
|
@ -1418,12 +1418,15 @@ static int wpa_supplicant_ctrl_iface_remove_network(
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ssid == wpa_s->current_ssid) {
|
if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) {
|
||||||
/*
|
/*
|
||||||
* Invalidate the EAP session cache if the current network is
|
* Invalidate the EAP session cache if the current or
|
||||||
* removed.
|
* previously used network is removed.
|
||||||
*/
|
*/
|
||||||
eapol_sm_invalidate_cached_session(wpa_s->eapol);
|
eapol_sm_invalidate_cached_session(wpa_s->eapol);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssid == wpa_s->current_ssid) {
|
||||||
wpa_sm_set_config(wpa_s->wpa, NULL);
|
wpa_sm_set_config(wpa_s->wpa, NULL);
|
||||||
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
|
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
|
||||||
|
|
||||||
|
@ -1471,10 +1474,12 @@ static int wpa_supplicant_ctrl_iface_set_network(
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wpa_s->current_ssid == ssid) {
|
wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
|
||||||
|
|
||||||
|
if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) {
|
||||||
/*
|
/*
|
||||||
* Invalidate the EAP session cache if anything in the current
|
* Invalidate the EAP session cache if anything in the current
|
||||||
* configuration changes.
|
* or previously used configuration changes.
|
||||||
*/
|
*/
|
||||||
eapol_sm_invalidate_cached_session(wpa_s->eapol);
|
eapol_sm_invalidate_cached_session(wpa_s->eapol);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "dbus/dbus_common.h"
|
#include "dbus/dbus_common.h"
|
||||||
#include "dbus/dbus_old.h"
|
#include "dbus/dbus_old.h"
|
||||||
#include "dbus/dbus_new.h"
|
#include "dbus/dbus_new.h"
|
||||||
|
#include "rsn_supp/wpa.h"
|
||||||
#include "driver_i.h"
|
#include "driver_i.h"
|
||||||
#include "scan.h"
|
#include "scan.h"
|
||||||
#include "p2p_supplicant.h"
|
#include "p2p_supplicant.h"
|
||||||
|
@ -238,6 +239,7 @@ void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s,
|
||||||
void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
|
void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *ssid)
|
struct wpa_ssid *ssid)
|
||||||
{
|
{
|
||||||
|
wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
|
||||||
if (wpa_s->global->p2p_group_formation != wpa_s)
|
if (wpa_s->global->p2p_group_formation != wpa_s)
|
||||||
wpas_dbus_unregister_network(wpa_s, ssid->id);
|
wpas_dbus_unregister_network(wpa_s, ssid->id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -726,6 +726,7 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
|
||||||
}
|
}
|
||||||
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
|
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
|
||||||
wpa_sm_set_config(wpa_s->wpa, NULL);
|
wpa_sm_set_config(wpa_s->wpa, NULL);
|
||||||
|
wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
|
||||||
wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
|
wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
|
||||||
rsn_preauth_deinit(wpa_s->wpa);
|
rsn_preauth_deinit(wpa_s->wpa);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue