Keep and use list of PSKs per station for RADIUS-based PSK
authorMichael Braun <michael-dev@fami-braun.de>
Sun, 25 Nov 2012 15:49:25 +0000 (17:49 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 25 Nov 2012 15:57:16 +0000 (17:57 +0200)
This adds support for multiple PSKs per station when using a RADIUS
authentication server to fetch the PSKs during MAC address
authentication step. This can be useful if multiple users share a
device but each user has his or her own private passphrase.

Signed-hostap: Michael Braun <michael-dev@fami-braun.de>

src/ap/ieee802_11.c
src/ap/sta_info.c
src/ap/sta_info.h
src/ap/wpa_auth_glue.c

index 3bc7059..9e87b80 100644 (file)
@@ -570,13 +570,15 @@ static void handle_auth(struct hostapd_data *hapd,
                               HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
        }
 
-       if (psk && hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
-               os_free(sta->psk);
-               sta->psk = os_malloc(PMK_LEN);
-               if (sta->psk)
-                       os_memcpy(sta->psk, psk->psk, PMK_LEN);
+       while (sta->psk) {
+               struct hostapd_sta_wpa_psk_short *prev = sta->psk;
+               sta->psk = sta->psk->next;
+               os_free(prev);
+       }
+       if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
+               sta->psk = psk;
+               psk = NULL;
        } else {
-               os_free(sta->psk);
                sta->psk = NULL;
        }
 
index 4f57af5..ef1aab8 100644 (file)
@@ -235,7 +235,11 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
        wpabuf_free(sta->hs20_ie);
 
        os_free(sta->ht_capabilities);
-       os_free(sta->psk);
+       while (sta->psk) {
+               struct hostapd_sta_wpa_psk_short *prev = sta->psk;
+               sta->psk = sta->psk->next;
+               os_free(prev);
+       }
        os_free(sta->identity);
        os_free(sta->radius_cui);
 
index 132830f..d5e92fa 100644 (file)
@@ -95,7 +95,8 @@ struct sta_info {
        struct hostapd_ssid *ssid_probe; /* SSID selection based on ProbeReq */
 
        int vlan_id;
-       u8 *psk; /* PSK from RADIUS authentication server */
+        /* PSKs from RADIUS authentication server */
+       struct hostapd_sta_wpa_psk_short *psk;
 
        char *identity; /* User-Name from RADIUS */
        char *radius_cui; /* Chargeable-User-Identity from RADIUS */
index 68fe596..76c61ea 100644 (file)
@@ -188,10 +188,18 @@ static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
        /*
         * This is about to iterate over all psks, prev_psk gives the last
         * returned psk which should not be returned again.
-        * logic list (all hostapd_get_psk; sta->psk)
+        * logic list (all hostapd_get_psk; all sta->psk)
         */
-       if (sta && sta->psk && !psk && sta->psk != prev_psk)
-               psk = sta->psk;
+       if (sta && sta->psk && !psk) {
+               struct hostapd_sta_wpa_psk_short *pos;
+               psk = sta->psk->psk;
+               for (pos = sta->psk; pos; pos = pos->next) {
+                       if (pos->psk == prev_psk) {
+                               psk = pos->next ? pos->next->psk : NULL;
+                               break;
+                       }
+               }
+       }
        return psk;
 }