[PATCH 14/44] 802.11 Factor out authentication code for reuse with FT-over-DS
michael-dev at fami-braun.de
michael-dev at fami-braun.de
Wed Feb 24 03:53:20 PST 2016
From: Michael Braun <michael-dev at fami-braun.de>
Signed-off-by: Michael Braun <michael-dev at fami-braun.de>
---
src/ap/ieee802_11.c | 125 ++++++++++++++++++++++++++++-------------------
src/ap/ieee802_11.h | 4 ++
src/ap/ieee802_11_auth.c | 82 ++++++++++++++++---------------
src/ap/ieee802_11_auth.h | 22 +++++++--
4 files changed, 140 insertions(+), 93 deletions(-)
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 84e6e15..d318b53 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -908,6 +908,71 @@ int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta)
#endif /* CONFIG_SAE */
+void handle_auth_restart_cb(struct hostapd_data *hapd, const u8 *buf,
+ size_t len, const u8 *mac, int accepted,
+ u32 session_timeout)
+{
+#ifdef CONFIG_DRIVER_RADIUS_ACL
+ hostapd_drv_set_radius_acl_auth(hapd, mac, accepted, session_timeout);
+#else /* CONFIG_DRIVER_RADIUS_ACL */
+#ifdef NEED_AP_MLME
+ /* Re-send original authentication frame for 802.11 processing */
+ wpa_printf(MSG_DEBUG, "Re-sending authentication frame after "
+ "successful RADIUS ACL query");
+ ieee802_11_mgmt(hapd, buf, len, NULL);
+#endif /* NEED_AP_MLME */
+#endif /* CONFIG_DRIVER_RADIUS_ACL */
+}
+
+
+int handle_auth_cfg_sta(struct hostapd_data *hapd, struct sta_info *sta,
+ int res, struct hostapd_allowed_address_info *info,
+ u16 *resp)
+{
+ if (info->vlan_id.notempty &&
+ !hostapd_vlan_valid(hapd->conf->vlan, &info->vlan_id)) {
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
+ HOSTAPD_LEVEL_INFO,
+ "Invalid VLAN %d%s received from RADIUS server",
+ info->vlan_id.untagged,
+ info->vlan_id.tagged[0] ? "+" : "");
+ *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ return -1;
+ }
+ if (ap_sta_set_vlan(hapd, sta, &info->vlan_id) < 0) {
+ *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ return -1;
+ }
+ if (sta->vlan_id)
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
+ HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
+
+ hostapd_free_psk_list(sta->psk);
+ if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
+ sta->psk = info->psk;
+ info->psk = NULL;
+ } else {
+ sta->psk = NULL;
+ }
+
+ sta->identity = info->identity;
+ info->identity = NULL;
+ sta->radius_cui = info->radius_cui;
+ info->radius_cui = NULL;
+
+ if (hapd->conf->acct_interim_interval == 0 &&
+ info->acct_interim_interval)
+ sta->acct_interim_interval = info->acct_interim_interval;
+
+ if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
+ ap_sta_session_timeout(hapd, sta, info->session_timeout);
+ else
+ ap_sta_no_session_timeout(hapd, sta);
+
+ return 0;
+}
+
+
static void handle_auth(struct hostapd_data *hapd,
const struct ieee80211_mgmt *mgmt, size_t len)
{
@@ -917,16 +982,10 @@ static void handle_auth(struct hostapd_data *hapd,
int res, reply_res;
u16 fc;
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];
size_t resp_ies_len = 0;
- char *identity = NULL;
- char *radius_cui = NULL;
u16 seq_ctrl;
-
- os_memset(&vlan_id, 0, sizeof(vlan_id));
+ struct hostapd_allowed_address_info details;
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
@@ -944,6 +1003,8 @@ static void handle_auth(struct hostapd_data *hapd,
}
#endif /* CONFIG_TESTING_OPTIONS */
+ hostapd_allowed_address_init(&details);
+
auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
status_code = le_to_host16(mgmt->u.auth.status_code);
@@ -1068,9 +1129,8 @@ 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, &identity, &radius_cui);
+ &handle_auth_restart_cb,
+ &details);
if (res == HOSTAPD_ACL_REJECT) {
wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
@@ -1085,6 +1145,7 @@ static void handle_auth(struct hostapd_data *hapd,
/* Authentication code will re-send the authentication frame
* after it has received (and cached) information from the
* external source. */
+ hostapd_allowed_address_free(&details);
return;
}
@@ -1099,6 +1160,7 @@ static void handle_auth(struct hostapd_data *hapd,
HOSTAPD_LEVEL_DEBUG,
"Drop repeated authentication frame seq_ctrl=0x%x",
seq_ctrl);
+ hostapd_allowed_address_free(&details);
return;
}
#ifdef CONFIG_MESH
@@ -1107,6 +1169,7 @@ static void handle_auth(struct hostapd_data *hapd,
wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
" is blocked - drop Authentication frame",
MAC2STR(mgmt->sa));
+ hostapd_allowed_address_free(&details);
return;
}
#endif /* CONFIG_MESH */
@@ -1125,6 +1188,7 @@ static void handle_auth(struct hostapd_data *hapd,
wpabuf_free(hapd->mesh_pending_auth);
hapd->mesh_pending_auth = wpabuf_alloc_copy(mgmt, len);
os_get_reltime(&hapd->mesh_pending_auth_time);
+ hostapd_allowed_address_free(&details);
return;
}
#endif /* CONFIG_MESH */
@@ -1138,47 +1202,12 @@ static void handle_auth(struct hostapd_data *hapd,
sta->last_seq_ctrl = seq_ctrl;
sta->last_subtype = WLAN_FC_STYPE_AUTH;
- if (vlan_id.notempty &&
- !hostapd_vlan_valid(hapd->conf->vlan, &vlan_id)) {
- hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
- HOSTAPD_LEVEL_INFO,
- "Invalid VLAN %d%s received from RADIUS server",
- vlan_id.untagged,
- vlan_id.tagged[0] ? "+" : "");
- resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ if (handle_auth_cfg_sta(hapd, sta, res, &details, &resp) < 0)
goto fail;
- }
- if (ap_sta_set_vlan(hapd, sta, &vlan_id) < 0) {
- resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
- goto fail;
- }
- if (sta->vlan_id)
- hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
- HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
-
- hostapd_free_psk_list(sta->psk);
- if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
- sta->psk = psk;
- psk = NULL;
- } else {
- 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);
- if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
- sta->acct_interim_interval = acct_interim_interval;
- if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
- ap_sta_session_timeout(hapd, sta, session_timeout);
- else
- ap_sta_no_session_timeout(hapd, sta);
-
/*
* If the driver supports full AP client state, add a station to the
* driver before sending authentication reply to make sure the driver
@@ -1288,9 +1317,7 @@ static void handle_auth(struct hostapd_data *hapd,
}
fail:
- os_free(identity);
- os_free(radius_cui);
- hostapd_free_psk_list(psk);
+ hostapd_allowed_address_free(&details);
reply_res = send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
auth_transaction + 1, resp, resp_ies,
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index 78db204..48e7e44 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -16,6 +16,7 @@ struct hostapd_frame_info;
struct ieee80211_ht_capabilities;
struct ieee80211_vht_capabilities;
struct ieee80211_mgmt;
+struct hostapd_allowed_address_info;
int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
struct hostapd_frame_info *fi);
@@ -108,6 +109,9 @@ static inline void sae_clear_retransmit_timer(struct hostapd_data *hapd,
{
}
#endif /* CONFIG_SAE */
+int handle_auth_cfg_sta(struct hostapd_data *hapd, struct sta_info *sta,
+ int res, struct hostapd_allowed_address_info *info,
+ u16 *resp);
#ifdef CONFIG_MBO
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index f280709..ebc971c 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -48,6 +48,8 @@ struct hostapd_acl_query_data {
macaddr addr;
u8 *auth_msg; /* IEEE 802.11 authentication frame from station */
size_t auth_msg_len;
+ void (*cb)(struct hostapd_data *hapd, const u8 *buf, size_t len,
+ const u8 *mac, int accepted, u32 session_timeout);
struct hostapd_acl_query_data *next;
};
@@ -216,6 +218,23 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
#endif /* CONFIG_NO_RADIUS */
+void hostapd_allowed_address_init(struct hostapd_allowed_address_info *info)
+{
+ os_memset(info, 0, sizeof(*info));
+}
+
+
+void hostapd_allowed_address_free(struct hostapd_allowed_address_info *info)
+{
+ os_free(info->identity);
+ info->identity = NULL;
+ os_free(info->radius_cui);
+ info->radius_cui = NULL;
+ hostapd_free_psk_list(info->psk);
+ info->psk = NULL;
+}
+
+
/**
* hostapd_check_acl - Check a specified STA against accept/deny ACLs
* @hapd: hostapd BSS data
@@ -261,28 +280,16 @@ int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr,
* 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,
- struct vlan_description *vlan_id,
- struct hostapd_sta_wpa_psk_short **psk,
- char **identity, char **radius_cui)
+ const u8 *msg, size_t len,
+ void (*cb)(struct hostapd_data *hapd,
+ const u8 *buf, size_t len,
+ const u8 *mac, int accepted,
+ u32 session_timeout),
+ struct hostapd_allowed_address_info *info)
{
int res;
- if (session_timeout)
- *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, &info->vlan_id);
if (res != HOSTAPD_ACL_PENDING)
return res;
@@ -293,9 +300,12 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
struct hostapd_acl_query_data *query;
/* Check whether ACL cache has an entry for this station */
- res = hostapd_acl_cache_get(hapd, addr, session_timeout,
- acct_interim_interval, vlan_id, psk,
- identity, radius_cui);
+ res = hostapd_acl_cache_get(hapd, addr,
+ &info->session_timeout,
+ &info->acct_interim_interval,
+ &info->vlan_id, &info->psk,
+ &info->identity,
+ &info->radius_cui);
if (res == HOSTAPD_ACL_ACCEPT ||
res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
return res;
@@ -307,13 +317,13 @@ 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 (info->identity) {
+ os_free(info->identity);
+ info->identity = NULL;
}
- if (radius_cui) {
- os_free(*radius_cui);
- *radius_cui = NULL;
+ if (info->radius_cui) {
+ os_free(info->radius_cui);
+ info->radius_cui = NULL;
}
return HOSTAPD_ACL_PENDING;
}
@@ -347,6 +357,7 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
}
os_memcpy(query->auth_msg, msg, len);
query->auth_msg_len = len;
+ query->cb = cb;
query->next = hapd->acl_queries;
hapd->acl_queries = query;
@@ -606,17 +617,10 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
cache->next = hapd->acl_cache;
hapd->acl_cache = cache;
-#ifdef CONFIG_DRIVER_RADIUS_ACL
- hostapd_drv_set_radius_acl_auth(hapd, query->addr, cache->accepted,
- cache->session_timeout);
-#else /* CONFIG_DRIVER_RADIUS_ACL */
-#ifdef NEED_AP_MLME
- /* Re-send original authentication frame for 802.11 processing */
- wpa_printf(MSG_DEBUG, "Re-sending authentication frame after "
- "successful RADIUS ACL query");
- ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, NULL);
-#endif /* NEED_AP_MLME */
-#endif /* CONFIG_DRIVER_RADIUS_ACL */
+ if (query->cb)
+ query->cb(hapd, query->auth_msg, query->auth_msg_len,
+ query->addr, cache->accepted,
+ cache->session_timeout);
done:
if (prev == NULL)
diff --git a/src/ap/ieee802_11_auth.h b/src/ap/ieee802_11_auth.h
index 71f53b9..fc8497f 100644
--- a/src/ap/ieee802_11_auth.h
+++ b/src/ap/ieee802_11_auth.h
@@ -16,14 +16,26 @@ enum {
HOSTAPD_ACL_ACCEPT_TIMEOUT = 3
};
+struct hostapd_allowed_address_info {
+ u32 session_timeout;
+ u32 acct_interim_interval;
+ struct vlan_description vlan_id;
+ struct hostapd_sta_wpa_psk_short *psk;
+ char *identity;
+ char *radius_cui;
+};
+
+void hostapd_allowed_address_init(struct hostapd_allowed_address_info *info);
+void hostapd_allowed_address_free(struct hostapd_allowed_address_info *info);
int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr,
struct vlan_description *vlan_id);
int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
- const u8 *msg, size_t len, u32 *session_timeout,
- u32 *acct_interim_interval,
- struct vlan_description *vlan_id,
- struct hostapd_sta_wpa_psk_short **psk,
- char **identity, char **radius_cui);
+ const u8 *msg, size_t len,
+ void (*cb)(struct hostapd_data *hapd,
+ const u8 *buf, size_t len,
+ const u8 *mac, int accepted,
+ u32 session_timeout),
+ struct hostapd_allowed_address_info *info);
int hostapd_acl_init(struct hostapd_data *hapd);
void hostapd_acl_deinit(struct hostapd_data *hapd);
void hostapd_free_psk_list(struct hostapd_sta_wpa_psk_short *psk);
--
1.9.1
More information about the Hostap
mailing list