From owner-p4-projects@FreeBSD.ORG Mon Mar 10 18:35:02 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id CA9D71065672; Mon, 10 Mar 2008 18:35:01 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 87D8F1065681 for ; Mon, 10 Mar 2008 18:35:01 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 72FA88FC2C for ; Mon, 10 Mar 2008 18:35:01 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m2AIZ1sK030335 for ; Mon, 10 Mar 2008 18:35:01 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m2AIZ1i6030333 for perforce@freebsd.org; Mon, 10 Mar 2008 18:35:01 GMT (envelope-from sam@freebsd.org) Date: Mon, 10 Mar 2008 18:35:01 GMT Message-Id: <200803101835.m2AIZ1i6030333@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 137336 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Mar 2008 18:35:02 -0000 http://perforce.freebsd.org/chv.cgi?CH=137336 Change 137336 by sam@sam_ebb on 2008/03/10 18:34:35 radius acl support (sent upstream to Jouni for inclusion) Submitted by: Chris Zimmerman Affected files ... .. //depot/projects/vap/contrib/hostapd/Makefile#3 edit .. //depot/projects/vap/contrib/hostapd/defconfig#3 edit .. //depot/projects/vap/contrib/hostapd/driver.h#3 edit .. //depot/projects/vap/contrib/hostapd/ieee802_11_auth.c#3 edit .. //depot/projects/vap/usr.sbin/wpa/hostapd/driver_freebsd.c#4 edit Differences ... ==== //depot/projects/vap/contrib/hostapd/Makefile#3 (text+ko) ==== @@ -313,6 +313,10 @@ 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. ==== //depot/projects/vap/contrib/hostapd/defconfig#3 (text+ko) ==== @@ -102,3 +102,7 @@ # 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 ==== //depot/projects/vap/contrib/hostapd/driver.h#3 (text+ko) ==== @@ -141,6 +141,10 @@ * 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 @@ 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 */ ==== //depot/projects/vap/contrib/hostapd/ieee802_11_auth.c#3 (text+ko) ==== @@ -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 @@ 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 @@ 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 @@ 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 @@ 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) ==== //depot/projects/vap/usr.sbin/wpa/hostapd/driver_freebsd.c#4 (text+ko) ==== @@ -30,6 +30,7 @@ #include "hostapd.h" #include "driver.h" #include "ieee802_1x.h" +#include "ieee802_11_auth.h" #include "eloop.h" #include "sta_info.h" #include "l2_packet.h" @@ -544,6 +545,9 @@ struct ieee80211_michael_event *mic; struct ieee80211_join_event *join; struct ieee80211_leave_event *leave; +#ifdef CONFIG_DRIVER_RADIUS_ACL + struct ieee80211_auth_event *auth; +#endif int n; n = read(sock, buf, sizeof(buf)); @@ -596,6 +600,32 @@ MAC2STR(mic->iev_src)); ieee80211_michael_mic_failure(hapd, mic->iev_src, 1); break; +#ifdef CONFIG_DRIVER_RADIUS_ACL + case RTM_IEEE80211_AUTH: + auth = (struct ieee80211_auth_event *) &ifan[1]; + wpa_printf(MSG_DEBUG, "802.11 AUTH, STA = " MACSTR, + MAC2STR(auth->iev_addr)); + n = hostapd_allowed_address(hapd, auth->iev_addr, + NULL, 0, NULL, NULL, NULL); + switch (n) { + case HOSTAPD_ACL_ACCEPT: + case HOSTAPD_ACL_REJECT: + hostapd_set_radius_acl_auth(hapd, + auth->iev_addr, n, 0); + wpa_printf(MSG_DEBUG, + "802.11 AUTH, STA = " MACSTR " hostapd says: %s", + MAC2STR(auth->iev_addr), + (n == HOSTAPD_ACL_ACCEPT ? + "ACCEPT" : "REJECT" )); + break; + case HOSTAPD_ACL_PENDING: + wpa_printf(MSG_DEBUG, + "802.11 AUTH, STA = " MACSTR " pending", + MAC2STR(auth->iev_addr)); + break; + } + break; +#endif /* CONFIG_DRIVER_RADIUS_ACL */ } break; } @@ -728,7 +758,68 @@ return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled); } +#ifdef CONFIG_DRIVER_RADIUS_ACL +static int +bsd_set_radius_acl_auth(void *priv, const u8 *mac, int accepted, + u32 session_timeout) +{ + struct bsd_driver_data *drv = priv; + struct hostapd_data *hapd = drv->hapd; + struct ieee80211req_mlme mlme; + + switch (accepted) { + case HOSTAPD_ACL_ACCEPT_TIMEOUT: + wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR + " has been accepted by RADIUS ACL with timeout " + "of %d.\n", hapd->conf->iface, MAC2STR(mac), + session_timeout); + mlme.im_reason = IEEE80211_STATUS_SUCCESS; + break; + case HOSTAPD_ACL_ACCEPT: + wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR + " has been accepted by RADIUS ACL.\n", + hapd->conf->iface, MAC2STR(mac)); + mlme.im_reason = IEEE80211_STATUS_SUCCESS; + break; + case HOSTAPD_ACL_REJECT: + wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR + " has been rejected by RADIUS ACL.\n", + hapd->conf->iface, MAC2STR(mac)); + mlme.im_reason = IEEE80211_STATUS_UNSPECIFIED; + break; + default: + wpa_printf(MSG_ERROR, "[%s] STA " MACSTR + " has unknown status (%d) by RADIUS ACL. " + "Nothing to do...\n", hapd->conf->iface, + MAC2STR(mac), accepted); + return 0; + } + memset(&mlme, 0, sizeof(mlme)); + mlme.im_op = IEEE80211_MLME_AUTH; + memcpy(mlme.im_macaddr, mac, IEEE80211_ADDR_LEN); + return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); +} + static int +bsd_set_radius_acl_expire(void *priv, const u8 *mac) +{ + struct bsd_driver_data *drv = priv; + struct hostapd_data *hapd = drv->hapd; + + /* + * The expiry of the MAC address from RADIUS ACL cache doesn't mean + * that we should kick off the client. Our current approach doesn't + * require adding/removing entries from an allow/deny list; so this + * function is likely unecessary + */ + wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR " radius acl cache " + "expired; nothing to do...", hapd->conf->iface, + MAC2STR(mac)); + return 0; +} +#endif /* CONFIG_DRIVER_RADIUS_ACL */ + +static int bsd_init(struct hostapd_data *hapd) { struct bsd_driver_data *drv; @@ -820,6 +911,10 @@ .get_ssid = bsd_get_ssid, .set_countermeasures = bsd_set_countermeasures, .sta_clear_stats = bsd_sta_clear_stats, +#ifdef CONFIG_DRIVER_RADIUS_ACL + .set_radius_acl_auth = bsd_set_radius_acl_auth, + .set_radius_acl_expire = bsd_set_radius_acl_expire, +#endif }; void bsd_driver_register(void)