aboutsummaryrefslogtreecommitdiffstats
path: root/hostapd/pmksa_cache.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2005-12-11 02:35:23 (GMT)
committerJouni Malinen <j@w1.fi>2005-12-11 02:35:23 (GMT)
commitb77d9b3b932045730494fb839550c65589197039 (patch)
tree002873da2134595a9dd65c994c57e8293827d767 /hostapd/pmksa_cache.c
parentce08a9dfe5634b244032a279653e2ce702708b3f (diff)
downloadhostap-history-b77d9b3b932045730494fb839550c65589197039.zip
hostap-history-b77d9b3b932045730494fb839550c65589197039.tar.gz
hostap-history-b77d9b3b932045730494fb839550c65589197039.tar.bz2
Removed struct hostapd_data references from pmksa_cache.c by making it
a separate module that uses a private data structure to store the PMKSA cache variables. Eventual goal here is to be able to share the same PMKSA cache implementation for both hostapd and wpa_supplicant.
Diffstat (limited to 'hostapd/pmksa_cache.c')
-rw-r--r--hostapd/pmksa_cache.c161
1 files changed, 93 insertions, 68 deletions
diff --git a/hostapd/pmksa_cache.c b/hostapd/pmksa_cache.c
index 384ebfd..506898a 100644
--- a/hostapd/pmksa_cache.c
+++ b/hostapd/pmksa_cache.c
@@ -26,6 +26,19 @@
static const int pmksa_cache_max_entries = 1024;
static const int dot11RSNAConfigPMKLifetime = 43200;
+struct rsn_pmksa_cache {
+#define PMKID_HASH_SIZE 128
+#define PMKID_HASH(pmkid) (unsigned int) ((pmkid)[0] & 0x7f)
+ struct rsn_pmksa_cache_entry *pmkid[PMKID_HASH_SIZE];
+ struct rsn_pmksa_cache_entry *pmksa;
+ int pmksa_count;
+
+ void (*free_cb)(struct rsn_pmksa_cache_entry *entry, void *ctx);
+ void *ctx;
+
+ u8 own_addr[ETH_ALEN];
+};
+
static void rsn_pmkid(const u8 *pmk, const u8 *aa, const u8 *spa, u8 *pmkid)
{
@@ -43,10 +56,10 @@ static void rsn_pmkid(const u8 *pmk, const u8 *aa, const u8 *spa, u8 *pmkid)
}
-static void pmksa_cache_set_expiration(struct hostapd_data *hapd);
+static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa);
-void _pmksa_cache_free_entry(struct rsn_pmksa_cache *entry)
+void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry)
{
if (entry == NULL)
return;
@@ -56,24 +69,21 @@ void _pmksa_cache_free_entry(struct rsn_pmksa_cache *entry)
}
-static void pmksa_cache_free_entry(struct hostapd_data *hapd,
- struct rsn_pmksa_cache *entry)
+static void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa,
+ struct rsn_pmksa_cache_entry *entry)
{
- struct sta_info *sta;
- struct rsn_pmksa_cache *pos, *prev;
- hapd->pmksa_count--;
- for (sta = hapd->sta_list; sta != NULL; sta = sta->next) {
- if (sta->pmksa == entry)
- sta->pmksa = NULL;
- }
- pos = hapd->pmkid[PMKID_HASH(entry->pmkid)];
+ struct rsn_pmksa_cache_entry *pos, *prev;
+
+ pmksa->pmksa_count--;
+ pmksa->free_cb(entry, pmksa->ctx);
+ pos = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
prev = NULL;
while (pos) {
if (pos == entry) {
if (prev != NULL) {
prev->hnext = pos->hnext;
} else {
- hapd->pmkid[PMKID_HASH(entry->pmkid)] =
+ pmksa->pmkid[PMKID_HASH(entry->pmkid)] =
pos->hnext;
}
break;
@@ -82,14 +92,14 @@ static void pmksa_cache_free_entry(struct hostapd_data *hapd,
pos = pos->hnext;
}
- pos = hapd->pmksa;
+ pos = pmksa->pmksa;
prev = NULL;
while (pos) {
if (pos == entry) {
if (prev != NULL)
prev->next = pos->next;
else
- hapd->pmksa = pos->next;
+ pmksa->pmksa = pos->next;
break;
}
prev = pos;
@@ -101,37 +111,36 @@ static void pmksa_cache_free_entry(struct hostapd_data *hapd,
static void pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
{
- struct hostapd_data *hapd = eloop_ctx;
+ struct rsn_pmksa_cache *pmksa = eloop_ctx;
time_t now;
time(&now);
- while (hapd->pmksa && hapd->pmksa->expiration <= now) {
- struct rsn_pmksa_cache *entry = hapd->pmksa;
- hapd->pmksa = entry->next;
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
- "RSN: expired PMKSA cache entry for "
- MACSTR, MAC2STR(entry->spa));
- pmksa_cache_free_entry(hapd, entry);
+ while (pmksa->pmksa && pmksa->pmksa->expiration <= now) {
+ struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
+ pmksa->pmksa = entry->next;
+ wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for "
+ MACSTR, MAC2STR(entry->spa));
+ pmksa_cache_free_entry(pmksa, entry);
}
- pmksa_cache_set_expiration(hapd);
+ pmksa_cache_set_expiration(pmksa);
}
-static void pmksa_cache_set_expiration(struct hostapd_data *hapd)
+static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
{
int sec;
- eloop_cancel_timeout(pmksa_cache_expire, hapd, NULL);
- if (hapd->pmksa == NULL)
+ eloop_cancel_timeout(pmksa_cache_expire, pmksa, NULL);
+ if (pmksa->pmksa == NULL)
return;
- sec = hapd->pmksa->expiration - time(NULL);
+ sec = pmksa->pmksa->expiration - time(NULL);
if (sec < 0)
sec = 0;
- eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, hapd, NULL);
+ eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL);
}
-static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache *entry,
+static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache_entry *entry,
struct eapol_state_machine *eapol)
{
if (eapol == NULL)
@@ -151,7 +160,7 @@ static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache *entry,
}
-void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache *entry,
+void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry,
struct eapol_state_machine *eapol)
{
if (entry == NULL || eapol == NULL)
@@ -179,20 +188,20 @@ void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache *entry,
}
-void pmksa_cache_add(struct hostapd_data *hapd, struct sta_info *sta, u8 *pmk,
- int session_timeout)
+int pmksa_cache_add(struct rsn_pmksa_cache *pmksa, struct sta_info *sta,
+ const u8 *pmk, int session_timeout)
{
- struct rsn_pmksa_cache *entry, *pos, *prev;
+ struct rsn_pmksa_cache_entry *entry, *pos, *prev;
if (sta->wpa != WPA_VERSION_WPA2)
- return;
+ return -1;
entry = malloc(sizeof(*entry));
if (entry == NULL)
- return;
+ return -1;
memset(entry, 0, sizeof(*entry));
memcpy(entry->pmk, pmk, PMK_LEN);
- rsn_pmkid(pmk, hapd->own_addr, sta->addr, entry->pmkid);
+ rsn_pmkid(pmk, pmksa->own_addr, sta->addr, entry->pmkid);
time(&entry->expiration);
if (session_timeout > 0)
entry->expiration += session_timeout;
@@ -204,21 +213,20 @@ void pmksa_cache_add(struct hostapd_data *hapd, struct sta_info *sta, u8 *pmk,
/* Replace an old entry for the same STA (if found) with the new entry
*/
- pos = pmksa_cache_get(hapd, sta->addr, NULL);
+ pos = pmksa_cache_get(pmksa, sta->addr, NULL);
if (pos)
- pmksa_cache_free_entry(hapd, pos);
+ pmksa_cache_free_entry(pmksa, pos);
- if (hapd->pmksa_count >= pmksa_cache_max_entries && hapd->pmksa) {
+ if (pmksa->pmksa_count >= pmksa_cache_max_entries && pmksa->pmksa) {
/* Remove the oldest entry to make room for the new entry */
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
- "RSN: removed the oldest PMKSA cache entry (for "
- MACSTR ") to make room for new one",
- MAC2STR(hapd->pmksa->spa));
- pmksa_cache_free_entry(hapd, hapd->pmksa);
+ wpa_printf(MSG_DEBUG, "RSN: removed the oldest PMKSA cache "
+ "entry (for " MACSTR ") to make room for new one",
+ MAC2STR(pmksa->pmksa->spa));
+ pmksa_cache_free_entry(pmksa, pmksa->pmksa);
}
/* Add the new entry; order by expiration time */
- pos = hapd->pmksa;
+ pos = pmksa->pmksa;
prev = NULL;
while (pos) {
if (pos->expiration > entry->expiration)
@@ -227,53 +235,51 @@ void pmksa_cache_add(struct hostapd_data *hapd, struct sta_info *sta, u8 *pmk,
pos = pos->next;
}
if (prev == NULL) {
- entry->next = hapd->pmksa;
- hapd->pmksa = entry;
+ entry->next = pmksa->pmksa;
+ pmksa->pmksa = entry;
} else {
entry->next = prev->next;
prev->next = entry;
}
- entry->hnext = hapd->pmkid[PMKID_HASH(entry->pmkid)];
- hapd->pmkid[PMKID_HASH(entry->pmkid)] = entry;
+ entry->hnext = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
+ pmksa->pmkid[PMKID_HASH(entry->pmkid)] = entry;
- hapd->pmksa_count++;
- hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
- HOSTAPD_LEVEL_DEBUG,
- "added PMKSA cache entry");
+ pmksa->pmksa_count++;
wpa_hexdump(MSG_DEBUG, "RSN: added PMKID", entry->pmkid, PMKID_LEN);
+
+ return 0;
}
-void pmksa_cache_free(struct hostapd_data *hapd)
+void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa)
{
- struct rsn_pmksa_cache *entry, *prev;
+ struct rsn_pmksa_cache_entry *entry, *prev;
int i;
- struct sta_info *sta;
- entry = hapd->pmksa;
- hapd->pmksa = NULL;
+ if (pmksa == NULL)
+ return;
+
+ entry = pmksa->pmksa;
while (entry) {
prev = entry;
entry = entry->next;
_pmksa_cache_free_entry(prev);
}
- eloop_cancel_timeout(pmksa_cache_expire, hapd, NULL);
+ eloop_cancel_timeout(pmksa_cache_expire, pmksa, NULL);
for (i = 0; i < PMKID_HASH_SIZE; i++)
- hapd->pmkid[i] = NULL;
- for (sta = hapd->sta_list; sta; sta = sta->next)
- sta->pmksa = NULL;
+ pmksa->pmkid[i] = NULL;
}
-struct rsn_pmksa_cache * pmksa_cache_get(struct hostapd_data *hapd,
- const u8 *spa, const u8 *pmkid)
+struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
+ const u8 *spa, const u8 *pmkid)
{
- struct rsn_pmksa_cache *entry;
+ struct rsn_pmksa_cache_entry *entry;
if (pmkid)
- entry = hapd->pmkid[PMKID_HASH(pmkid)];
+ entry = pmksa->pmkid[PMKID_HASH(pmkid)];
else
- entry = hapd->pmksa;
+ entry = pmksa->pmksa;
while (entry) {
if ((spa == NULL || memcmp(entry->spa, spa, ETH_ALEN) == 0) &&
(pmkid == NULL ||
@@ -283,3 +289,22 @@ struct rsn_pmksa_cache * pmksa_cache_get(struct hostapd_data *hapd,
}
return NULL;
}
+
+
+struct rsn_pmksa_cache *
+pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
+ void *ctx),
+ void *ctx, const u8 *own_addr)
+{
+ struct rsn_pmksa_cache *pmksa;
+
+ pmksa = malloc(sizeof(*pmksa));
+ if (pmksa) {
+ memset(pmksa, 0, sizeof(*pmksa));
+ pmksa->free_cb = free_cb;
+ pmksa->ctx = ctx;
+ memcpy(pmksa->own_addr, own_addr, ETH_ALEN);
+ }
+
+ return pmksa;
+}