From fcc306e3cc714ca54a02176db1da366786b01147 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 18 Oct 2014 10:20:24 +0300 Subject: [PATCH] Add Acct-Multi-Session-Id into RADIUS Accounting messages 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 --- src/ap/accounting.c | 17 +++++++++++++++++ src/ap/pmksa_cache_auth.c | 6 ++++++ src/ap/pmksa_cache_auth.h | 3 +++ src/eapol_auth/eapol_auth_sm.c | 12 ++++++++++++ src/eapol_auth/eapol_auth_sm_i.h | 6 ++++++ 5 files changed, 44 insertions(+) diff --git a/src/ap/accounting.c b/src/ap/accounting.c index 1fb1e92af..7c55146b2 100644 --- a/src/ap/accounting.c +++ b/src/ap/accounting.c @@ -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)); } diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c index 9de4cffeb..44c4a0d9a 100644 --- a/src/ap/pmksa_cache_auth.c +++ b/src/ap/pmksa_cache_auth.c @@ -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; } diff --git a/src/ap/pmksa_cache_auth.h b/src/ap/pmksa_cache_auth.h index aa90024d7..b2d4e9d81 100644 --- a/src/ap/pmksa_cache_auth.h +++ b/src/ap/pmksa_cache_auth.h @@ -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; diff --git a/src/eapol_auth/eapol_auth_sm.c b/src/eapol_auth/eapol_auth_sm.c index a76fa13b2..8584cf0b4 100644 --- a/src/eapol_auth/eapol_auth_sm.c +++ b/src/eapol_auth/eapol_auth_sm.c @@ -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; } diff --git a/src/eapol_auth/eapol_auth_sm_i.h b/src/eapol_auth/eapol_auth_sm_i.h index 25baddbab..a29b49c90 100644 --- a/src/eapol_auth/eapol_auth_sm_i.h +++ b/src/eapol_auth/eapol_auth_sm_i.h @@ -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 */