From bdc431a06bbc06b243d6960a3cff50fc953dd420 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Mon, 24 Mar 2008 21:20:35 +0000 Subject: [PATCH] add support for driver-based RADIUS ACL's (committed on vendor branch as it's been sent upstream) Submitted by: Chris Zimmermann --- contrib/hostapd/Makefile | 4 ++++ contrib/hostapd/defconfig | 4 ++++ contrib/hostapd/driver.h | 22 ++++++++++++++++++++++ contrib/hostapd/ieee802_11_auth.c | 22 +++++++++++++++++----- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/contrib/hostapd/Makefile b/contrib/hostapd/Makefile index c98922b31aaf..4fadede02057 100644 --- a/contrib/hostapd/Makefile +++ b/contrib/hostapd/Makefile @@ -313,6 +313,10 @@ ifdef CONFIG_IPV6 CFLAGS += -DCONFIG_IPV6 endif +ifdef CONFIG_DRIVER_RADIUS_ACL +CFLAGS += -DCONFIG_DRIVER_RADIUS_ACL +endif + ifdef CONFIG_FULL_DYNAMIC_VLAN # define CONFIG_FULL_DYNAMIC_VLAN to have hostapd manipulate bridges # and vlan interfaces for the vlan feature. diff --git a/contrib/hostapd/defconfig b/contrib/hostapd/defconfig index 8fe4bf9f5bfa..634f7f5fce8d 100644 --- a/contrib/hostapd/defconfig +++ b/contrib/hostapd/defconfig @@ -102,3 +102,7 @@ CONFIG_PKCS12=y # Build IPv6 support for RADIUS operations CONFIG_IPV6=y + +# Use the hostapd's IEEE 802.11 authentication (ACL), but without +# the IEEE 802.11 Management capability +CONFIG_DRIVER_RADIUS_ACL=y diff --git a/contrib/hostapd/driver.h b/contrib/hostapd/driver.h index 4fd262c1ff14..aeefbea1c45d 100644 --- a/contrib/hostapd/driver.h +++ b/contrib/hostapd/driver.h @@ -141,6 +141,10 @@ struct driver_ops { * this handler will be called after initial setup has been completed. */ int (*commit)(void *priv); + + int (*set_radius_acl_auth)(void *priv, const u8 *mac, int accepted, + u32 session_timeout); + int (*set_radius_acl_expire)(void *priv, const u8 *mac); }; static inline int @@ -653,4 +657,22 @@ hostapd_driver_commit(struct hostapd_data *hapd) return hapd->driver->commit(hapd->driver); } +static inline int +hostapd_set_radius_acl_auth(struct hostapd_data *hapd, const u8 *mac, int accepted, + u32 session_timeout) +{ + if (hapd->driver == NULL || hapd->driver->set_radius_acl_auth == NULL) + return 0; + return hapd->driver->set_radius_acl_auth(hapd->driver, mac, accepted, + session_timeout); +} + +static inline int +hostapd_set_radius_acl_expire(struct hostapd_data *hapd, const u8 *mac) +{ + if (hapd->driver == NULL || hapd->driver->set_radius_acl_expire == NULL) + return 0; + return hapd->driver->set_radius_acl_expire(hapd->driver, mac); +} + #endif /* DRIVER_H */ diff --git a/contrib/hostapd/ieee802_11_auth.c b/contrib/hostapd/ieee802_11_auth.c index 16a85171027e..75d0494e3c0c 100644 --- a/contrib/hostapd/ieee802_11_auth.c +++ b/contrib/hostapd/ieee802_11_auth.c @@ -22,6 +22,7 @@ #include "radius.h" #include "radius_client.h" #include "eloop.h" +#include "driver.h" #define RADIUS_ACL_TIMEOUT 30 @@ -74,8 +75,10 @@ static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr, if (now - entry->timestamp > RADIUS_ACL_TIMEOUT) return -1; /* entry has expired */ if (entry->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT) - *session_timeout = entry->session_timeout; - *acct_interim_interval = entry->acct_interim_interval; + if (session_timeout) + *session_timeout = entry->session_timeout; + if (acct_interim_interval) + *acct_interim_interval = entry->acct_interim_interval; if (vlan_id) *vlan_id = entry->vlan_id; return entry->accepted; @@ -192,8 +195,10 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, const u8 *msg, size_t len, u32 *session_timeout, u32 *acct_interim_interval, int *vlan_id) { - *session_timeout = 0; - *acct_interim_interval = 0; + if (session_timeout) + *session_timeout = 0; + if (acct_interim_interval) + *acct_interim_interval = 0; if (vlan_id) *vlan_id = 0; @@ -287,7 +292,9 @@ static void hostapd_acl_expire_cache(struct hostapd_data *hapd, time_t now) prev->next = entry->next; else hapd->acl_cache = entry->next; - +#ifdef CONFIG_DRIVER_RADIUS_ACL + hostapd_set_radius_acl_expire(hapd, entry->addr); +#endif tmp = entry; entry = entry->next; free(tmp); @@ -413,11 +420,16 @@ 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_set_radius_acl_auth(hapd, query->addr, cache->accepted, + cache->session_timeout); +#else /* Re-send original authentication frame for 802.11 processing */ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Re-sending authentication frame " "after successful RADIUS ACL query\n"); ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, WLAN_FC_STYPE_AUTH, NULL); +#endif done: if (prev == NULL)