Copy User-Name/CUI from RADIUS ACL to STA entry
authorMichael Braun <michael-dev@fami-braun.de>
Sun, 19 Aug 2012 11:20:10 +0000 (14:20 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 19 Aug 2012 11:20:10 +0000 (14:20 +0300)
Signed-hostap: Michael Braun <michael-dev@fami-braun.de>

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

index 537b555..4d8b3e6 100644 (file)
@@ -311,6 +311,8 @@ static void handle_auth(struct hostapd_data *hapd,
        int has_psk = 0;
        u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
        size_t resp_ies_len = 0;
+       char *identity = NULL;
+       char *radius_cui = NULL;
 
        if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
                printf("handle_auth - too short payload (len=%lu)\n",
@@ -372,7 +374,7 @@ static void handle_auth(struct hostapd_data *hapd,
        res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
                                      &session_timeout,
                                      &acct_interim_interval, &vlan_id,
-                                     psk, &has_psk);
+                                     psk, &has_psk, &identity, &radius_cui);
 
        if (res == HOSTAPD_ACL_REJECT) {
                printf("Station " MACSTR " not allowed to authenticate.\n",
@@ -421,6 +423,11 @@ static void handle_auth(struct hostapd_data *hapd,
                sta->psk = NULL;
        }
 
+       sta->identity = identity;
+       identity = NULL;
+       sta->radius_cui = radius_cui;
+       radius_cui = NULL;
+
        sta->flags &= ~WLAN_STA_PREAUTH;
        ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
 
@@ -482,6 +489,9 @@ static void handle_auth(struct hostapd_data *hapd,
        }
 
  fail:
+       os_free(identity);
+       os_free(radius_cui);
+
        send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
                        auth_transaction + 1, resp, resp_ies, resp_ies_len);
 }
index 6f8f372..63ae345 100644 (file)
@@ -77,7 +77,8 @@ static void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache)
 static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
                                 u32 *session_timeout,
                                 u32 *acct_interim_interval, int *vlan_id,
-                                u8 *psk, int *has_psk)
+                                u8 *psk, int *has_psk, char **identity,
+                                char **radius_cui)
 {
        struct hostapd_cached_radius_acl *entry;
        struct os_time now;
@@ -102,6 +103,18 @@ static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
                        os_memcpy(psk, entry->psk, PMK_LEN);
                if (has_psk)
                        *has_psk = entry->has_psk;
+               if (identity) {
+                       if (entry->identity)
+                               *identity = os_strdup(entry->identity);
+                       else
+                               *identity = NULL;
+               }
+               if (radius_cui) {
+                       if (entry->radius_cui)
+                               *radius_cui = os_strdup(entry->radius_cui);
+                       else
+                               *radius_cui = NULL;
+               }
                return entry->accepted;
        }
 
@@ -189,12 +202,18 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
  * @vlan_id: Buffer for returning VLAN ID
  * @psk: Buffer for returning WPA PSK
  * @has_psk: Buffer for indicating whether psk was filled
+ * @identity: Buffer for returning identity (from RADIUS)
+ * @radius_cui: Buffer for returning CUI (from RADIUS)
  * Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING
+ *
+ * The caller is responsible for freeing the returned *identity and *radius_cui
+ * values with os_free().
  */
 int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
                            const u8 *msg, size_t len, u32 *session_timeout,
                            u32 *acct_interim_interval, int *vlan_id,
-                           u8 *psk, int *has_psk)
+                           u8 *psk, int *has_psk, char **identity,
+                           char **radius_cui)
 {
        if (session_timeout)
                *session_timeout = 0;
@@ -206,6 +225,10 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
                *has_psk = 0;
        if (psk)
                os_memset(psk, 0, PMK_LEN);
+       if (identity)
+               *identity = NULL;
+       if (radius_cui)
+               *radius_cui = NULL;
 
        if (hostapd_maclist_found(hapd->conf->accept_mac,
                                  hapd->conf->num_accept_mac, addr, vlan_id))
@@ -230,7 +253,8 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
                /* Check whether ACL cache has an entry for this station */
                int res = hostapd_acl_cache_get(hapd, addr, session_timeout,
                                                acct_interim_interval,
-                                               vlan_id, psk, has_psk);
+                                               vlan_id, psk, has_psk,
+                                               identity, radius_cui);
                if (res == HOSTAPD_ACL_ACCEPT ||
                    res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
                        return res;
@@ -242,6 +266,14 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
                        if (os_memcmp(query->addr, addr, ETH_ALEN) == 0) {
                                /* pending query in RADIUS retransmit queue;
                                 * do not generate a new one */
+                               if (identity) {
+                                       os_free(*identity);
+                                       *identity = NULL;
+                               }
+                               if (radius_cui) {
+                                       os_free(*radius_cui);
+                                       *radius_cui = NULL;
+                               }
                                return HOSTAPD_ACL_PENDING;
                        }
                        query = query->next;
index b8a4c13..0e8d1cb 100644 (file)
@@ -19,7 +19,8 @@ enum {
 int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
                            const u8 *msg, size_t len, u32 *session_timeout,
                            u32 *acct_interim_interval, int *vlan_id,
-                           u8 *psk, int *has_psk);
+                           u8 *psk, int *has_psk, char **identity,
+                           char **radius_cui);
 int hostapd_acl_init(struct hostapd_data *hapd);
 void hostapd_acl_deinit(struct hostapd_data *hapd);
 
index ce43270..d61177f 100644 (file)
@@ -235,6 +235,8 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 
        os_free(sta->ht_capabilities);
        os_free(sta->psk);
+       os_free(sta->identity);
+       os_free(sta->radius_cui);
 
        os_free(sta);
 }
index b5d0f11..b3c57b4 100644 (file)
@@ -97,6 +97,9 @@ struct sta_info {
        int vlan_id;
        u8 *psk; /* PSK from RADIUS authentication server */
 
+       char *identity; /* User-Name from RADIUS */
+       char *radius_cui; /* Chargeable-User-Identity from RADIUS */
+
        struct ieee80211_ht_capabilities *ht_capabilities;
        struct ieee80211_vht_capabilities *vht_capabilities;