Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Mar 2008 18:35:01 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 137336 for review
Message-ID:  <200803101835.m2AIZ1i6030333@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803101835.m2AIZ1i6030333>