From 24929543ba4e8d9a2934ca346ffb0132f7141125 Mon Sep 17 00:00:00 2001 From: Vinay Gannevaram Date: Fri, 8 Jul 2022 11:41:01 +0530 Subject: [PATCH] PASN: Deauthenticate on PTKSA cache entry expiration Add an option for an alternative processing of PTKSA life time expiry. Register a callback in wpa_supplicant to handle the life time expiry of the keys in PTKSA cache. Send PASN deauthentication when a PTKSA cache entry expires. Signed-off-by: Jouni Malinen --- src/ap/ieee802_11.c | 2 +- src/ap/wpa_auth_glue.c | 2 +- src/common/ptksa_cache.c | 15 +++++++++++++-- src/common/ptksa_cache.h | 10 ++++++++-- wpa_supplicant/pasn_supplicant.c | 12 +++++++++++- wpa_supplicant/wpas_glue.c | 2 +- 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 53f2aab6f..c43f18b4a 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3503,7 +3503,7 @@ static void handle_auth_pasn_3(struct hostapd_data *hapd, struct sta_info *sta, "PASN: Success handling transaction == 3. Store PTK"); ptksa_cache_add(hapd->ptksa, hapd->own_addr, sta->addr, - sta->pasn->cipher, 43200, &sta->pasn->ptk); + sta->pasn->cipher, 43200, &sta->pasn->ptk, NULL, NULL); fail: ap_free_sta(hapd, sta); } diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 9c27c7a83..1b4852cea 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -935,7 +935,7 @@ static void hostapd_store_ptksa(void *ctx, const u8 *addr,int cipher, struct hostapd_data *hapd = ctx; ptksa_cache_add(hapd->ptksa, hapd->own_addr, addr, cipher, life_time, - ptk); + ptk, NULL, NULL); } diff --git a/src/common/ptksa_cache.c b/src/common/ptksa_cache.c index be7a7605e..d5f8b7805 100644 --- a/src/common/ptksa_cache.c +++ b/src/common/ptksa_cache.c @@ -51,7 +51,10 @@ static void ptksa_cache_expire(void *eloop_ctx, void *timeout_ctx) wpa_printf(MSG_DEBUG, "Expired PTKSA cache entry for " MACSTR, MAC2STR(e->addr)); - ptksa_cache_free_entry(ptksa, e); + if (e->cb && e->ctx) + e->cb(e); + else + ptksa_cache_free_entry(ptksa, e); } ptksa_cache_set_expiration(ptksa); @@ -259,6 +262,8 @@ void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher) * @cipher: The cipher used * @life_time: The PTK life time in seconds * @ptk: The PTK + * @life_time_expiry_cb: Callback for alternative expiration handling + * @ctx: Context pointer to save into e->ctx for the callback * Returns: Pointer to the added PTKSA cache entry or %NULL on error * * This function creates a PTKSA entry and adds it to the PTKSA cache. @@ -269,7 +274,10 @@ struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa, const u8 *own_addr, const u8 *addr, u32 cipher, u32 life_time, - const struct wpa_ptk *ptk) + const struct wpa_ptk *ptk, + void (*life_time_expiry_cb) + (struct ptksa_cache_entry *e), + void *ctx) { struct ptksa_cache_entry *entry, *tmp, *tmp2 = NULL; struct os_reltime now; @@ -291,6 +299,9 @@ struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa, dl_list_init(&entry->list); os_memcpy(entry->addr, addr, ETH_ALEN); entry->cipher = cipher; + entry->cb = life_time_expiry_cb; + entry->ctx = ctx; + if (own_addr) os_memcpy(entry->own_addr, own_addr, ETH_ALEN); diff --git a/src/common/ptksa_cache.h b/src/common/ptksa_cache.h index ee7675fa4..a643a268e 100644 --- a/src/common/ptksa_cache.h +++ b/src/common/ptksa_cache.h @@ -24,6 +24,8 @@ struct ptksa_cache_entry { u32 cipher; u8 addr[ETH_ALEN]; u8 own_addr[ETH_ALEN]; + void (*cb)(struct ptksa_cache_entry *e); + void *ctx; }; #ifdef CONFIG_PTKSA_CACHE @@ -39,7 +41,10 @@ struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa, const u8 *own_addr, const u8 *addr, u32 cipher, u32 life_time, - const struct wpa_ptk *ptk); + const struct wpa_ptk *ptk, + void (*cb) + (struct ptksa_cache_entry *e), + void *ctx); void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher); #else /* CONFIG_PTKSA_CACHE */ @@ -67,7 +72,8 @@ static inline int ptksa_cache_list(struct ptksa_cache *ptksa, static inline struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa, const u8 *own_addr, const u8 *addr, - u32 cipher, u32 life_time, const struct wpa_ptk *ptk) + u32 cipher, u32 life_time, const struct wpa_ptk *ptk, + void (*cb)(struct ptksa_cache_entry *e), void *ctx) { return NULL; } diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c index 38d240b00..47aa6ee6d 100644 --- a/wpa_supplicant/pasn_supplicant.c +++ b/wpa_supplicant/pasn_supplicant.c @@ -1584,6 +1584,14 @@ static int wpas_pasn_immediate_retry(struct wpa_supplicant *wpa_s, } +static void wpas_pasn_deauth_cb(struct ptksa_cache_entry *entry) +{ + struct wpa_supplicant *wpa_s = entry->ctx; + + wpas_pasn_deauthenticate(wpa_s, entry->own_addr, entry->addr); +} + + int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s, const struct ieee80211_mgmt *mgmt, size_t len) { @@ -1825,7 +1833,9 @@ int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s, wpa_printf(MSG_DEBUG, "PASN: Success sending last frame. Store PTK"); ptksa_cache_add(wpa_s->ptksa, pasn->own_addr, pasn->bssid, - pasn->cipher, dot11RSNAConfigPMKLifetime, &pasn->ptk); + pasn->cipher, dot11RSNAConfigPMKLifetime, &pasn->ptk, + wpa_s->pasn_params ? wpas_pasn_deauth_cb : NULL, + wpa_s->pasn_params ? wpa_s : NULL); forced_memzero(&pasn->ptk, sizeof(pasn->ptk)); diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 78ad5a665..35ca12308 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -1379,7 +1379,7 @@ static void wpa_supplicant_store_ptk(void *ctx, u8 *addr, int cipher, struct wpa_supplicant *wpa_s = ctx; ptksa_cache_add(wpa_s->ptksa, wpa_s->own_addr, addr, cipher, life_time, - ptk); + ptk, NULL, NULL); } #endif /* CONFIG_NO_WPA */