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 <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-10-18 10:20:24 +03:00
parent aff039fada
commit fcc306e3cc
5 changed files with 44 additions and 0 deletions

View file

@ -10,6 +10,8 @@
#include "utils/common.h" #include "utils/common.h"
#include "utils/eloop.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.h"
#include "radius/radius_client.h" #include "radius/radius_client.h"
#include "hostapd.h" #include "hostapd.h"
@ -49,6 +51,21 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
if (sta) { if (sta) {
radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*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 { } else {
radius_msg_make_authenticator(msg, (u8 *) hapd, sizeof(*hapd)); radius_msg_make_authenticator(msg, (u8 *) hapd, sizeof(*hapd));
} }

View 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->eap_type_authsrv = eapol->eap_type_authsrv;
entry->vlan_id = ((struct sta_info *) eapol->sta)->vlan_id; 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; eapol->eap_type_authsrv = entry->eap_type_authsrv;
((struct sta_info *) eapol->sta)->vlan_id = entry->vlan_id; ((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;
} }

View file

@ -30,6 +30,9 @@ struct rsn_pmksa_cache_entry {
u8 eap_type_authsrv; u8 eap_type_authsrv;
int vlan_id; int vlan_id;
int opportunistic; int opportunistic;
u32 acct_multi_session_id_hi;
u32 acct_multi_session_id_lo;
}; };
struct rsn_pmksa_cache; struct rsn_pmksa_cache;

View file

@ -851,6 +851,11 @@ eapol_auth_alloc(struct eapol_authenticator *eapol, const u8 *addr,
sm->radius_cui = wpabuf_alloc_copy(radius_cui, sm->radius_cui = wpabuf_alloc_copy(radius_cui,
os_strlen(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; return sm;
} }
@ -1127,6 +1132,7 @@ struct eapol_authenticator * eapol_auth_init(struct eapol_auth_config *conf,
struct eapol_auth_cb *cb) struct eapol_auth_cb *cb)
{ {
struct eapol_authenticator *eapol; struct eapol_authenticator *eapol;
struct os_time now;
eapol = os_zalloc(sizeof(*eapol)); eapol = os_zalloc(sizeof(*eapol));
if (eapol == NULL) 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.tx_key = cb->tx_key;
eapol->cb.eapol_event = cb->eapol_event; 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; return eapol;
} }

View file

@ -30,6 +30,9 @@ struct eapol_authenticator {
u8 *default_wep_key; u8 *default_wep_key;
u8 default_wep_key_idx; 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 */ void *sta; /* station context pointer to use in callbacks */
int remediation; int remediation;
u32 acct_multi_session_id_hi;
u32 acct_multi_session_id_lo;
}; };
#endif /* EAPOL_AUTH_SM_I_H */ #endif /* EAPOL_AUTH_SM_I_H */