]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add Acct-Multi-Session-Id into RADIUS Accounting messages
authorJouni Malinen <j@w1.fi>
Sat, 18 Oct 2014 07:20:24 +0000 (10:20 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 18 Oct 2014 07:38:17 +0000 (10:38 +0300)
This allows multiple sessions using the same PMKSA cache entry to be
combined more easily at the server side. Acct-Session-Id is still a
unique identifier for each association, while Acct-Multi-Session-Id will
maintain its value for all associations that use the same PMKSA.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/ap/accounting.c
src/ap/pmksa_cache_auth.c
src/ap/pmksa_cache_auth.h
src/eapol_auth/eapol_auth_sm.c
src/eapol_auth/eapol_auth_sm_i.h

index 1fb1e92af76efe02079ad5dba9a38c07f4ca985e..7c55146b2c5c2780d2e1e2d4f0b23c5d72bd258c 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "utils/common.h"
 #include "utils/eloop.h"
+#include "eapol_auth/eapol_auth_sm.h"
+#include "eapol_auth/eapol_auth_sm_i.h"
 #include "radius/radius.h"
 #include "radius/radius_client.h"
 #include "hostapd.h"
@@ -49,6 +51,21 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
 
        if (sta) {
                radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
+
+               if ((hapd->conf->wpa & 2) &&
+                   !hapd->conf->disable_pmksa_caching &&
+                   sta->eapol_sm && sta->eapol_sm->acct_multi_session_id_hi) {
+                       os_snprintf(buf, sizeof(buf), "%08X+%08X",
+                                   sta->eapol_sm->acct_multi_session_id_hi,
+                                   sta->eapol_sm->acct_multi_session_id_lo);
+                       if (!radius_msg_add_attr(
+                                   msg, RADIUS_ATTR_ACCT_MULTI_SESSION_ID,
+                                   (u8 *) buf, os_strlen(buf))) {
+                               wpa_printf(MSG_INFO,
+                                          "Could not add Acct-Multi-Session-Id");
+                               goto fail;
+                       }
+               }
        } else {
                radius_msg_make_authenticator(msg, (u8 *) hapd, sizeof(*hapd));
        }
index 9de4cffebf65c1d4e7ff8a47b08e9e286a1d9afe..44c4a0d9a45d8e9f6ada1c64349241f172261da3 100644 (file)
@@ -146,6 +146,9 @@ static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache_entry *entry,
 
        entry->eap_type_authsrv = eapol->eap_type_authsrv;
        entry->vlan_id = ((struct sta_info *) eapol->sta)->vlan_id;
+
+       entry->acct_multi_session_id_hi = eapol->acct_multi_session_id_hi;
+       entry->acct_multi_session_id_lo = eapol->acct_multi_session_id_lo;
 }
 
 
@@ -183,6 +186,9 @@ void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry,
 
        eapol->eap_type_authsrv = entry->eap_type_authsrv;
        ((struct sta_info *) eapol->sta)->vlan_id = entry->vlan_id;
+
+       eapol->acct_multi_session_id_hi = entry->acct_multi_session_id_hi;
+       eapol->acct_multi_session_id_lo = entry->acct_multi_session_id_lo;
 }
 
 
index aa90024d7df8d4d0fbc1fcbb65c15536c7b23a95..b2d4e9d817143b63cd139d723ac27e8a08a48b11 100644 (file)
@@ -30,6 +30,9 @@ struct rsn_pmksa_cache_entry {
        u8 eap_type_authsrv;
        int vlan_id;
        int opportunistic;
+
+       u32 acct_multi_session_id_hi;
+       u32 acct_multi_session_id_lo;
 };
 
 struct rsn_pmksa_cache;
index a76fa13b2e408249f7254b39f6c019fe903c1231..8584cf0b4d0e6027809367f73299e76b95e00bed 100644 (file)
@@ -851,6 +851,11 @@ eapol_auth_alloc(struct eapol_authenticator *eapol, const u8 *addr,
                sm->radius_cui = wpabuf_alloc_copy(radius_cui,
                                                   os_strlen(radius_cui));
 
+       sm->acct_multi_session_id_lo = eapol->acct_multi_session_id_lo++;
+       if (eapol->acct_multi_session_id_lo == 0)
+               eapol->acct_multi_session_id_hi++;
+       sm->acct_multi_session_id_hi = eapol->acct_multi_session_id_hi;
+
        return sm;
 }
 
@@ -1127,6 +1132,7 @@ struct eapol_authenticator * eapol_auth_init(struct eapol_auth_config *conf,
                                             struct eapol_auth_cb *cb)
 {
        struct eapol_authenticator *eapol;
+       struct os_time now;
 
        eapol = os_zalloc(sizeof(*eapol));
        if (eapol == NULL)
@@ -1153,6 +1159,12 @@ struct eapol_authenticator * eapol_auth_init(struct eapol_auth_config *conf,
        eapol->cb.tx_key = cb->tx_key;
        eapol->cb.eapol_event = cb->eapol_event;
 
+       /* Acct-Multi-Session-Id should be unique over reboots. If reliable
+        * clock is not available, this could be replaced with reboot counter,
+        * etc. */
+       os_get_time(&now);
+       eapol->acct_multi_session_id_hi = now.sec;
+
        return eapol;
 }
 
index 25baddbab43159e25ddc1e92ec8e65952b1e5dfb..a29b49c90c72f5d99dd6163dbbcf80b4101ef03d 100644 (file)
@@ -30,6 +30,9 @@ struct eapol_authenticator {
 
        u8 *default_wep_key;
        u8 default_wep_key_idx;
+
+       u32 acct_multi_session_id_hi;
+       u32 acct_multi_session_id_lo;
 };
 
 
@@ -175,6 +178,9 @@ struct eapol_state_machine {
        void *sta; /* station context pointer to use in callbacks */
 
        int remediation;
+
+       u32 acct_multi_session_id_hi;
+       u32 acct_multi_session_id_lo;
 };
 
 #endif /* EAPOL_AUTH_SM_I_H */