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 <quic_jouni@quicinc.com>
"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);
}
struct hostapd_data *hapd = ctx;
ptksa_cache_add(hapd->ptksa, hapd->own_addr, addr, cipher, life_time,
- ptk);
+ ptk, NULL, NULL);
}
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);
* @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.
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;
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);
u32 cipher;
u8 addr[ETH_ALEN];
u8 own_addr[ETH_ALEN];
+ void (*cb)(struct ptksa_cache_entry *e);
+ void *ctx;
};
#ifdef CONFIG_PTKSA_CACHE
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 */
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;
}
}
+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)
{
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));
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 */