Move the RADIUS cached attributes into a struct

This makes it easier to pass these around and to add new attributes.

Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
This commit is contained in:
Michael Braun 2019-04-28 13:14:57 +02:00 committed by Jouni Malinen
parent 3cd4db231a
commit 29024efd18
5 changed files with 114 additions and 165 deletions

View file

@ -755,11 +755,7 @@ void handle_probe_req(struct hostapd_data *hapd,
int ret; int ret;
u16 csa_offs[2]; u16 csa_offs[2];
size_t csa_offs_len; size_t csa_offs_len;
u32 session_timeout, acct_interim_interval; struct radius_sta rad_info;
struct vlan_description vlan_id;
struct hostapd_sta_wpa_psk_short *psk = NULL;
char *identity = NULL;
char *radius_cui = NULL;
if (len < IEEE80211_HDRLEN) if (len < IEEE80211_HDRLEN)
return; return;
@ -769,9 +765,7 @@ void handle_probe_req(struct hostapd_data *hapd,
ie_len = len - IEEE80211_HDRLEN; ie_len = len - IEEE80211_HDRLEN;
ret = ieee802_11_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len, ret = ieee802_11_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
&session_timeout, &rad_info, 1);
&acct_interim_interval, &vlan_id,
&psk, &identity, &radius_cui, 1);
if (ret == HOSTAPD_ACL_REJECT) { if (ret == HOSTAPD_ACL_REJECT) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG, wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Ignore Probe Request frame from " MACSTR "Ignore Probe Request frame from " MACSTR

View file

@ -2050,21 +2050,13 @@ void ieee802_11_finish_fils_auth(struct hostapd_data *hapd,
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
int int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr, const u8 *msg, size_t len,
const u8 *msg, size_t len, u32 *session_timeout, struct radius_sta *info, int is_probe_req)
u32 *acct_interim_interval,
struct vlan_description *vlan_id,
struct hostapd_sta_wpa_psk_short **psk,
char **identity, char **radius_cui, int is_probe_req)
{ {
int res; int res;
os_memset(vlan_id, 0, sizeof(*vlan_id)); res = hostapd_allowed_address(hapd, addr, msg, len, info, is_probe_req);
res = hostapd_allowed_address(hapd, addr, msg, len,
session_timeout, acct_interim_interval,
vlan_id, psk, identity, radius_cui,
is_probe_req);
if (res == HOSTAPD_ACL_REJECT) { if (res == HOSTAPD_ACL_REJECT) {
if (!is_probe_req) if (!is_probe_req)
@ -2091,12 +2083,12 @@ ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
static int static int
ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta, ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
int res, u32 session_timeout, int res, struct radius_sta *info)
u32 acct_interim_interval,
struct vlan_description *vlan_id,
struct hostapd_sta_wpa_psk_short **psk,
char **identity, char **radius_cui)
{ {
u32 session_timeout = info->session_timeout;
u32 acct_interim_interval = info->acct_interim_interval;
struct vlan_description *vlan_id = &info->vlan_id;
if (vlan_id->notempty && if (vlan_id->notempty &&
!hostapd_vlan_valid(hapd->conf->vlan, vlan_id)) { !hostapd_vlan_valid(hapd->conf->vlan, vlan_id)) {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
@ -2114,19 +2106,19 @@ ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
hostapd_free_psk_list(sta->psk); hostapd_free_psk_list(sta->psk);
if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) { if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
sta->psk = *psk; sta->psk = info->psk;
*psk = NULL; info->psk = NULL;
} else { } else {
sta->psk = NULL; sta->psk = NULL;
} }
os_free(sta->identity); os_free(sta->identity);
sta->identity = *identity; sta->identity = info->identity;
*identity = NULL; info->identity = NULL;
os_free(sta->radius_cui); os_free(sta->radius_cui);
sta->radius_cui = *radius_cui; sta->radius_cui = info->radius_cui;
*radius_cui = NULL; info->radius_cui = NULL;
if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval) if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
sta->acct_interim_interval = acct_interim_interval; sta->acct_interim_interval = acct_interim_interval;
@ -2154,14 +2146,12 @@ static void handle_auth(struct hostapd_data *hapd,
int res, reply_res; int res, reply_res;
u16 fc; u16 fc;
const u8 *challenge = NULL; const u8 *challenge = NULL;
u32 session_timeout, acct_interim_interval;
struct vlan_description vlan_id;
struct hostapd_sta_wpa_psk_short *psk = NULL;
u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
size_t resp_ies_len = 0; size_t resp_ies_len = 0;
char *identity = NULL;
char *radius_cui = NULL;
u16 seq_ctrl; u16 seq_ctrl;
struct radius_sta rad_info;
os_memset(&rad_info, 0, sizeof(rad_info));
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
@ -2313,9 +2303,7 @@ static void handle_auth(struct hostapd_data *hapd,
} }
res = ieee802_11_allowed_address( res = ieee802_11_allowed_address(
hapd, mgmt->sa, (const u8 *) mgmt, len, &session_timeout, hapd, mgmt->sa, (const u8 *) mgmt, len, &rad_info, 0);
&acct_interim_interval, &vlan_id, &psk, &identity, &radius_cui,
0);
if (res == HOSTAPD_ACL_REJECT) { if (res == HOSTAPD_ACL_REJECT) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG, wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Ignore Authentication frame from " MACSTR "Ignore Authentication frame from " MACSTR
@ -2398,9 +2386,7 @@ static void handle_auth(struct hostapd_data *hapd,
sta->auth_rssi = rssi; sta->auth_rssi = rssi;
#endif /* CONFIG_MBO */ #endif /* CONFIG_MBO */
res = ieee802_11_set_radius_info( res = ieee802_11_set_radius_info(hapd, sta, res, &rad_info);
hapd, sta, res, session_timeout, acct_interim_interval,
&vlan_id, &psk, &identity, &radius_cui);
if (res) { if (res) {
wpa_printf(MSG_DEBUG, "ieee802_11_set_radius_info() failed"); wpa_printf(MSG_DEBUG, "ieee802_11_set_radius_info() failed");
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
@ -2542,9 +2528,9 @@ static void handle_auth(struct hostapd_data *hapd,
} }
fail: fail:
os_free(identity); os_free(rad_info.identity);
os_free(radius_cui); os_free(rad_info.radius_cui);
hostapd_free_psk_list(psk); hostapd_free_psk_list(rad_info.psk);
reply_res = send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg, reply_res = send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
auth_transaction + 1, resp, resp_ies, auth_transaction + 1, resp, resp_ies,
@ -3997,13 +3983,13 @@ static void handle_assoc(struct hostapd_data *hapd,
int left, i; int left, i;
struct sta_info *sta; struct sta_info *sta;
u8 *tmp = NULL; u8 *tmp = NULL;
struct hostapd_sta_wpa_psk_short *psk = NULL; struct radius_sta info;
char *identity = NULL;
char *radius_cui = NULL;
#ifdef CONFIG_FILS #ifdef CONFIG_FILS
int delay_assoc = 0; int delay_assoc = 0;
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
os_memset(&info, 0, sizeof(info));
if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
sizeof(mgmt->u.assoc_req))) { sizeof(mgmt->u.assoc_req))) {
wpa_printf(MSG_INFO, "handle_assoc(reassoc=%d) - too short payload (len=%lu)", wpa_printf(MSG_INFO, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
@ -4079,13 +4065,10 @@ static void handle_assoc(struct hostapd_data *hapd,
hapd->iface->current_mode->mode == hapd->iface->current_mode->mode ==
HOSTAPD_MODE_IEEE80211AD) { HOSTAPD_MODE_IEEE80211AD) {
int acl_res; int acl_res;
u32 session_timeout, acct_interim_interval;
struct vlan_description vlan_id;
acl_res = ieee802_11_allowed_address( acl_res = ieee802_11_allowed_address(hapd, mgmt->sa,
hapd, mgmt->sa, (const u8 *) mgmt, len, (const u8 *) mgmt,
&session_timeout, &acct_interim_interval, len, &info, 0);
&vlan_id, &psk, &identity, &radius_cui, 0);
if (acl_res == HOSTAPD_ACL_REJECT) { if (acl_res == HOSTAPD_ACL_REJECT) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG, wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Ignore Association Request frame from " "Ignore Association Request frame from "
@ -4110,9 +4093,7 @@ static void handle_assoc(struct hostapd_data *hapd,
} }
acl_res = ieee802_11_set_radius_info( acl_res = ieee802_11_set_radius_info(
hapd, sta, acl_res, session_timeout, hapd, sta, acl_res, &info);
acct_interim_interval, &vlan_id, &psk,
&identity, &radius_cui);
if (acl_res) { if (acl_res) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail; goto fail;
@ -4313,9 +4294,9 @@ static void handle_assoc(struct hostapd_data *hapd,
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
fail: fail:
os_free(identity); os_free(info.identity);
os_free(radius_cui); os_free(info.radius_cui);
hostapd_free_psk_list(psk); hostapd_free_psk_list(info.psk);
/* /*
* In case of a successful response, add the station to the driver. * In case of a successful response, add the station to the driver.

View file

@ -16,8 +16,7 @@ struct hostapd_frame_info;
struct ieee80211_ht_capabilities; struct ieee80211_ht_capabilities;
struct ieee80211_vht_capabilities; struct ieee80211_vht_capabilities;
struct ieee80211_mgmt; struct ieee80211_mgmt;
struct vlan_description; struct radius_sta;
struct hostapd_sta_wpa_psk_short;
enum ieee80211_op_mode; enum ieee80211_op_mode;
int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len, int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
@ -181,12 +180,8 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
size_t hostapd_eid_owe_trans_len(struct hostapd_data *hapd); size_t hostapd_eid_owe_trans_len(struct hostapd_data *hapd);
u8 * hostapd_eid_owe_trans(struct hostapd_data *hapd, u8 *eid, size_t len); u8 * hostapd_eid_owe_trans(struct hostapd_data *hapd, u8 *eid, size_t len);
int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr, int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
const u8 *msg, size_t len, u32 *session_timeout, const u8 *msg, size_t len,
u32 *acct_interim_interval, struct radius_sta *info, int is_probe_req);
struct vlan_description *vlan_id,
struct hostapd_sta_wpa_psk_short **psk,
char **identity, char **radius_cui,
int is_probe_req);
int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth, int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth,
int ap_seg1_idx, int *bandwidth, int *seg1_idx); int ap_seg1_idx, int *bandwidth, int *seg1_idx);

View file

@ -32,12 +32,7 @@ struct hostapd_cached_radius_acl {
macaddr addr; macaddr addr;
int accepted; /* HOSTAPD_ACL_* */ int accepted; /* HOSTAPD_ACL_* */
struct hostapd_cached_radius_acl *next; struct hostapd_cached_radius_acl *next;
u32 session_timeout; struct radius_sta info;
u32 acct_interim_interval;
struct vlan_description vlan_id;
struct hostapd_sta_wpa_psk_short *psk;
char *identity;
char *radius_cui;
}; };
@ -54,9 +49,9 @@ struct hostapd_acl_query_data {
#ifndef CONFIG_NO_RADIUS #ifndef CONFIG_NO_RADIUS
static void hostapd_acl_cache_free_entry(struct hostapd_cached_radius_acl *e) static void hostapd_acl_cache_free_entry(struct hostapd_cached_radius_acl *e)
{ {
os_free(e->identity); os_free(e->info.identity);
os_free(e->radius_cui); os_free(e->info.radius_cui);
hostapd_free_psk_list(e->psk); hostapd_free_psk_list(e->info.psk);
os_free(e); os_free(e);
} }
@ -87,11 +82,7 @@ static void copy_psk_list(struct hostapd_sta_wpa_psk_short **psk,
static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr, static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
u32 *session_timeout, struct radius_sta *out)
u32 *acct_interim_interval,
struct vlan_description *vlan_id,
struct hostapd_sta_wpa_psk_short **psk,
char **identity, char **radius_cui)
{ {
struct hostapd_cached_radius_acl *entry; struct hostapd_cached_radius_acl *entry;
struct os_reltime now; struct os_reltime now;
@ -105,26 +96,23 @@ static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
if (os_reltime_expired(&now, &entry->timestamp, if (os_reltime_expired(&now, &entry->timestamp,
RADIUS_ACL_TIMEOUT)) RADIUS_ACL_TIMEOUT))
return -1; /* entry has expired */ return -1; /* entry has expired */
if (entry->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT) if (out) {
if (session_timeout) if (entry->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT)
*session_timeout = entry->session_timeout; out->session_timeout =
if (acct_interim_interval) entry->info.session_timeout;
*acct_interim_interval = out->acct_interim_interval =
entry->acct_interim_interval; entry->info.acct_interim_interval;
if (vlan_id) out->vlan_id = entry->info.vlan_id;
*vlan_id = entry->vlan_id; copy_psk_list(&out->psk, entry->info.psk);
copy_psk_list(psk, entry->psk); if (entry->info.identity)
if (identity) { out->identity = os_strdup(entry->info.identity);
if (entry->identity)
*identity = os_strdup(entry->identity);
else else
*identity = NULL; out->identity = NULL;
} if (entry->info.radius_cui)
if (radius_cui) { out->radius_cui =
if (entry->radius_cui) os_strdup(entry->info.radius_cui);
*radius_cui = os_strdup(entry->radius_cui);
else else
*radius_cui = NULL; out->radius_cui = NULL;
} }
return entry->accepted; return entry->accepted;
} }
@ -238,42 +226,28 @@ int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr,
* @addr: MAC address of the STA * @addr: MAC address of the STA
* @msg: Authentication message * @msg: Authentication message
* @len: Length of msg in octets * @len: Length of msg in octets
* @session_timeout: Buffer for returning session timeout (from RADIUS) * @out.session_timeout: Buffer for returning session timeout (from RADIUS)
* @acct_interim_interval: Buffer for returning account interval (from RADIUS) * @out.acct_interim_interval: Buffer for returning account interval (from
* @vlan_id: Buffer for returning VLAN ID * RADIUS)
* @psk: Linked list buffer for returning WPA PSK * @out.vlan_id: Buffer for returning VLAN ID
* @identity: Buffer for returning identity (from RADIUS) * @out.psk: Linked list buffer for returning WPA PSK
* @radius_cui: Buffer for returning CUI (from RADIUS) * @out.identity: Buffer for returning identity (from RADIUS)
* @out.radius_cui: Buffer for returning CUI (from RADIUS)
* @is_probe_req: Whether this query for a Probe Request frame * @is_probe_req: Whether this query for a Probe Request frame
* Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING * Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING
* *
* The caller is responsible for freeing the returned *identity and *radius_cui * The caller is responsible for freeing the returned out.identity and
* values with os_free(). * out.radius_cui values with os_free().
*/ */
int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
const u8 *msg, size_t len, u32 *session_timeout, const u8 *msg, size_t len, struct radius_sta *out,
u32 *acct_interim_interval,
struct vlan_description *vlan_id,
struct hostapd_sta_wpa_psk_short **psk,
char **identity, char **radius_cui,
int is_probe_req) int is_probe_req)
{ {
int res; int res;
if (session_timeout) os_memset(out, 0, sizeof(*out));
*session_timeout = 0;
if (acct_interim_interval)
*acct_interim_interval = 0;
if (vlan_id)
os_memset(vlan_id, 0, sizeof(*vlan_id));
if (psk)
*psk = NULL;
if (identity)
*identity = NULL;
if (radius_cui)
*radius_cui = NULL;
res = hostapd_check_acl(hapd, addr, vlan_id); res = hostapd_check_acl(hapd, addr, &out->vlan_id);
if (res != HOSTAPD_ACL_PENDING) if (res != HOSTAPD_ACL_PENDING)
return res; return res;
@ -290,12 +264,10 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
}; };
if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_DISABLED) if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_DISABLED)
vlan_id = NULL; os_memset(&out->vlan_id, 0, sizeof(out->vlan_id));
/* Check whether ACL cache has an entry for this station */ /* Check whether ACL cache has an entry for this station */
res = hostapd_acl_cache_get(hapd, addr, session_timeout, res = hostapd_acl_cache_get(hapd, addr, out);
acct_interim_interval, vlan_id, psk,
identity, radius_cui);
if (res == HOSTAPD_ACL_ACCEPT || if (res == HOSTAPD_ACL_ACCEPT ||
res == HOSTAPD_ACL_ACCEPT_TIMEOUT) res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
return res; return res;
@ -307,13 +279,13 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
if (os_memcmp(query->addr, addr, ETH_ALEN) == 0) { if (os_memcmp(query->addr, addr, ETH_ALEN) == 0) {
/* pending query in RADIUS retransmit queue; /* pending query in RADIUS retransmit queue;
* do not generate a new one */ * do not generate a new one */
if (identity) { if (out && out->identity) {
os_free(*identity); os_free(out->identity);
*identity = NULL; out->identity = NULL;
} }
if (radius_cui) { if (out && out->radius_cui) {
os_free(*radius_cui); os_free(out->radius_cui);
*radius_cui = NULL; out->radius_cui = NULL;
} }
return HOSTAPD_ACL_PENDING; return HOSTAPD_ACL_PENDING;
} }
@ -488,8 +460,8 @@ static void decode_tunnel_passwords(struct hostapd_data *hapd,
passphraselen); passphraselen);
psk->is_passphrase = 1; psk->is_passphrase = 1;
} }
psk->next = cache->psk; psk->next = cache->info.psk;
cache->psk = psk; cache->info.psk = psk;
psk = NULL; psk = NULL;
} }
skip: skip:
@ -518,6 +490,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
struct hostapd_data *hapd = data; struct hostapd_data *hapd = data;
struct hostapd_acl_query_data *query, *prev; struct hostapd_acl_query_data *query, *prev;
struct hostapd_cached_radius_acl *cache; struct hostapd_cached_radius_acl *cache;
struct radius_sta *info;
struct radius_hdr *hdr = radius_msg_get_hdr(msg); struct radius_hdr *hdr = radius_msg_get_hdr(msg);
query = hapd->acl_queries; query = hapd->acl_queries;
@ -555,65 +528,66 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
} }
os_get_reltime(&cache->timestamp); os_get_reltime(&cache->timestamp);
os_memcpy(cache->addr, query->addr, sizeof(cache->addr)); os_memcpy(cache->addr, query->addr, sizeof(cache->addr));
info = &cache->info;
if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) { if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) {
u8 *buf; u8 *buf;
size_t len; size_t len;
if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT, if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT,
&cache->session_timeout) == 0) &info->session_timeout) == 0)
cache->accepted = HOSTAPD_ACL_ACCEPT_TIMEOUT; cache->accepted = HOSTAPD_ACL_ACCEPT_TIMEOUT;
else else
cache->accepted = HOSTAPD_ACL_ACCEPT; cache->accepted = HOSTAPD_ACL_ACCEPT;
if (radius_msg_get_attr_int32( if (radius_msg_get_attr_int32(
msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL, msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
&cache->acct_interim_interval) == 0 && &info->acct_interim_interval) == 0 &&
cache->acct_interim_interval < 60) { info->acct_interim_interval < 60) {
wpa_printf(MSG_DEBUG, "Ignored too small " wpa_printf(MSG_DEBUG, "Ignored too small "
"Acct-Interim-Interval %d for STA " MACSTR, "Acct-Interim-Interval %d for STA " MACSTR,
cache->acct_interim_interval, info->acct_interim_interval,
MAC2STR(query->addr)); MAC2STR(query->addr));
cache->acct_interim_interval = 0; info->acct_interim_interval = 0;
} }
if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED) if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED)
cache->vlan_id.notempty = !!radius_msg_get_vlanid( info->vlan_id.notempty = !!radius_msg_get_vlanid(
msg, &cache->vlan_id.untagged, msg, &info->vlan_id.untagged,
MAX_NUM_TAGGED_VLAN, cache->vlan_id.tagged); MAX_NUM_TAGGED_VLAN, info->vlan_id.tagged);
decode_tunnel_passwords(hapd, shared_secret, shared_secret_len, decode_tunnel_passwords(hapd, shared_secret, shared_secret_len,
msg, req, cache); msg, req, cache);
if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME,
&buf, &len, NULL) == 0) { &buf, &len, NULL) == 0) {
cache->identity = os_zalloc(len + 1); info->identity = os_zalloc(len + 1);
if (cache->identity) if (info->identity)
os_memcpy(cache->identity, buf, len); os_memcpy(info->identity, buf, len);
} }
if (radius_msg_get_attr_ptr( if (radius_msg_get_attr_ptr(
msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
&buf, &len, NULL) == 0) { &buf, &len, NULL) == 0) {
cache->radius_cui = os_zalloc(len + 1); info->radius_cui = os_zalloc(len + 1);
if (cache->radius_cui) if (info->radius_cui)
os_memcpy(cache->radius_cui, buf, len); os_memcpy(info->radius_cui, buf, len);
} }
if (hapd->conf->wpa_psk_radius == PSK_RADIUS_REQUIRED && if (hapd->conf->wpa_psk_radius == PSK_RADIUS_REQUIRED &&
!cache->psk) !info->psk)
cache->accepted = HOSTAPD_ACL_REJECT; cache->accepted = HOSTAPD_ACL_REJECT;
if (cache->vlan_id.notempty && if (info->vlan_id.notempty &&
!hostapd_vlan_valid(hapd->conf->vlan, &cache->vlan_id)) { !hostapd_vlan_valid(hapd->conf->vlan, &info->vlan_id)) {
hostapd_logger(hapd, query->addr, hostapd_logger(hapd, query->addr,
HOSTAPD_MODULE_RADIUS, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO, HOSTAPD_LEVEL_INFO,
"Invalid VLAN %d%s received from RADIUS server", "Invalid VLAN %d%s received from RADIUS server",
cache->vlan_id.untagged, info->vlan_id.untagged,
cache->vlan_id.tagged[0] ? "+" : ""); info->vlan_id.tagged[0] ? "+" : "");
os_memset(&cache->vlan_id, 0, sizeof(cache->vlan_id)); os_memset(&info->vlan_id, 0, sizeof(info->vlan_id));
} }
if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_REQUIRED && if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_REQUIRED &&
!cache->vlan_id.notempty) !info->vlan_id.notempty)
cache->accepted = HOSTAPD_ACL_REJECT; cache->accepted = HOSTAPD_ACL_REJECT;
} else } else
cache->accepted = HOSTAPD_ACL_REJECT; cache->accepted = HOSTAPD_ACL_REJECT;
@ -622,7 +596,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
#ifdef CONFIG_DRIVER_RADIUS_ACL #ifdef CONFIG_DRIVER_RADIUS_ACL
hostapd_drv_set_radius_acl_auth(hapd, query->addr, cache->accepted, hostapd_drv_set_radius_acl_auth(hapd, query->addr, cache->accepted,
cache->session_timeout); info->session_timeout);
#else /* CONFIG_DRIVER_RADIUS_ACL */ #else /* CONFIG_DRIVER_RADIUS_ACL */
#ifdef NEED_AP_MLME #ifdef NEED_AP_MLME
/* Re-send original authentication frame for 802.11 processing */ /* Re-send original authentication frame for 802.11 processing */

View file

@ -16,14 +16,19 @@ enum {
HOSTAPD_ACL_ACCEPT_TIMEOUT = 3 HOSTAPD_ACL_ACCEPT_TIMEOUT = 3
}; };
struct radius_sta {
u32 session_timeout;
u32 acct_interim_interval;
struct vlan_description vlan_id;
struct hostapd_sta_wpa_psk_short *psk;
char *identity;
char *radius_cui;
};
int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr, int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr,
struct vlan_description *vlan_id); struct vlan_description *vlan_id);
int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
const u8 *msg, size_t len, u32 *session_timeout, const u8 *msg, size_t len, struct radius_sta *out,
u32 *acct_interim_interval,
struct vlan_description *vlan_id,
struct hostapd_sta_wpa_psk_short **psk,
char **identity, char **radius_cui,
int is_probe_req); int is_probe_req);
int hostapd_acl_init(struct hostapd_data *hapd); int hostapd_acl_init(struct hostapd_data *hapd);
void hostapd_acl_deinit(struct hostapd_data *hapd); void hostapd_acl_deinit(struct hostapd_data *hapd);