From d3447cf20a26072d294cd74a8b3e5c676a7421e7 Mon Sep 17 00:00:00 2001
From: Nishant Pandey <nishpand@codeaurora.org>
Date: Tue, 22 Sep 2020 14:19:41 +0530
Subject: [PATCH] mesh: Add ACL logic support to mesh configuration

Extend AP-STA accept and deny acl list support to
mesh peer connection as well. Here mesh node uses
macaddr_acl value either ACCEPT_UNLESS_DENIED or
DENY_UNLESS_ACCEPTED.

Signed-off-by: Nishant Pandey <nishpand@codeaurora.org>
---
 wpa_supplicant/config.c            | 21 ++++++++++++++++++++-
 wpa_supplicant/config_file.c       |  6 ++++++
 wpa_supplicant/config_ssid.h       |  5 +++++
 wpa_supplicant/mesh.c              | 22 ++++++++++++++++++++++
 wpa_supplicant/mesh_mpm.c          | 15 +++++++++++++++
 wpa_supplicant/wpa_supplicant.conf | 14 ++++++++++++++
 6 files changed, 82 insertions(+), 1 deletion(-)

Index: hostapd-2021-02-08/wpa_supplicant/config.c
===================================================================
--- hostapd-2021-02-08.orig/wpa_supplicant/config.c
+++ hostapd-2021-02-08/wpa_supplicant/config.c
@@ -20,7 +20,9 @@
 #include "drivers/nl80211_copy.h"
 #include "fst/fst.h"
 #include "config.h"
-
+#ifdef CONFIG_MESH
+#include "ap/ap_config.h"
+#endif
 
 #if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE)
 #define NO_CONFIG_WRITE
@@ -2710,6 +2712,9 @@ static const struct parse_data ssid_fiel
 	{ INT(dot11MeshRetryTimeout) },
 	{ INT(dot11MeshConfirmTimeout) },
 	{ INT(dot11MeshHoldingTimeout) },
+	{ STR(accept_mac_file) },
+	{ STR(deny_mac_file) },
+	{ INT(macaddr_acl) },
 #endif /* CONFIG_MESH */
 	{ INT(wpa_ptk_rekey) },
 	{ INT_RANGE(wpa_deny_ptk0_rekey, 0, 2) },
@@ -2980,6 +2985,8 @@ void wpa_config_free_ssid(struct wpa_ssi
 	os_free(ssid->p2p_client_list);
 	os_free(ssid->bssid_ignore);
 	os_free(ssid->bssid_accept);
+	os_free(ssid->accept_mac_file);
+	os_free(ssid->deny_mac_file);
 #ifdef CONFIG_HT_OVERRIDES
 	os_free(ssid->ht_mcs);
 #endif /* CONFIG_HT_OVERRIDES */
@@ -3344,6 +3351,18 @@ int wpa_config_set(struct wpa_ssid *ssid
 			}
 			ret = -1;
 		}
+#ifdef CONFIG_MESH
+		if (os_strcmp(var, "macaddr_acl") == 0) {
+			if (ssid->macaddr_acl != ACCEPT_UNLESS_DENIED &&
+			    ssid->macaddr_acl != DENY_UNLESS_ACCEPTED) {
+				wpa_printf(MSG_ERROR,
+					   "Line %d: unknown macaddr_acl %d",
+					   line, ssid->macaddr_acl);
+				ret = -1;
+			}
+		}
+#endif
+
 #ifdef CONFIG_SAE
 		if (os_strcmp(var, "ssid") == 0 ||
 		    os_strcmp(var, "psk") == 0 ||
Index: hostapd-2021-02-08/wpa_supplicant/config_file.c
===================================================================
--- hostapd-2021-02-08.orig/wpa_supplicant/config_file.c
+++ hostapd-2021-02-08/wpa_supplicant/config_file.c
@@ -18,6 +18,9 @@
 #include "common.h"
 #include "config.h"
 #include "base64.h"
+#ifdef CONFIG_MESH
+#include "ap/ap_config.h"
+#endif
 #include "uuid.h"
 #include "common/ieee802_1x_defs.h"
 #include "p2p/p2p.h"
@@ -914,6 +917,9 @@ static void wpa_config_write_network(FIL
 	write_int(f, "mac_addr", ssid->mac_addr, -1);
 #ifdef CONFIG_MESH
 	STR(mesh_basic_rates);
+	STR(accept_mac_file);
+	STR(deny_mac_file);
+	INT_DEF(macaddr_acl, ACCEPT_UNLESS_DENIED);
 	INT_DEF(dot11MeshMaxRetries, DEFAULT_MESH_MAX_RETRIES);
 	INT_DEF(dot11MeshRetryTimeout, DEFAULT_MESH_RETRY_TIMEOUT);
 	INT_DEF(dot11MeshConfirmTimeout, DEFAULT_MESH_CONFIRM_TIMEOUT);
Index: hostapd-2021-02-08/wpa_supplicant/config_ssid.h
===================================================================
--- hostapd-2021-02-08.orig/wpa_supplicant/config_ssid.h
+++ hostapd-2021-02-08/wpa_supplicant/config_ssid.h
@@ -546,6 +546,11 @@ struct wpa_ssid {
 	int dot11MeshConfirmTimeout; /* msec */
 	int dot11MeshHoldingTimeout; /* msec */
 
+	char *accept_mac_file;
+	char *deny_mac_file;
+	int macaddr_acl;
+
+
 	int ht;
 	int ht40;
 
Index: hostapd-2021-02-08/wpa_supplicant/mesh.c
===================================================================
--- hostapd-2021-02-08.orig/wpa_supplicant/mesh.c
+++ hostapd-2021-02-08/wpa_supplicant/mesh.c
@@ -16,6 +16,7 @@
 #include "common/hw_features_common.h"
 #include "ap/sta_info.h"
 #include "ap/hostapd.h"
+#include "ap/ieee802_11_auth.h"
 #include "ap/ieee802_11.h"
 #include "config_ssid.h"
 #include "config.h"
@@ -459,6 +460,17 @@ static int wpa_supplicant_mesh_init(stru
 	ifmsh->bss[0]->dot11RSNASAERetransPeriod =
 		wpa_s->conf->dot11RSNASAERetransPeriod;
 	os_strlcpy(bss->conf->iface, wpa_s->ifname, sizeof(bss->conf->iface));
+	bss->conf->macaddr_acl = ssid->macaddr_acl;
+
+	if (ssid->accept_mac_file)
+		hostapd_config_read_maclist(ssid->accept_mac_file,
+					    &bss->conf->accept_mac,
+					    &bss->conf->num_accept_mac);
+
+	if (ssid->deny_mac_file)
+		hostapd_config_read_maclist(ssid->deny_mac_file,
+					    &bss->conf->deny_mac,
+					    &bss->conf->num_deny_mac);
 
 	mconf = mesh_config_create(wpa_s, ssid);
 	if (!mconf)
@@ -555,6 +567,16 @@ void wpa_mesh_notify_peer(struct wpa_sup
 			  const u8 *ies, size_t ie_len)
 {
 	struct ieee802_11_elems elems;
+	int acl_res;
+	struct hostapd_data *data = wpa_s->ifmsh->bss[0];
+	struct radius_sta rad_info;
+
+	acl_res = hostapd_allowed_address(data, addr, NULL, 0, &rad_info, 0);
+	if (acl_res == HOSTAPD_ACL_REJECT) {
+		wpa_printf(MSG_ERROR, "Ignore new peer notification\n");
+		return;
+
+	}
 
 	wpa_msg(wpa_s, MSG_INFO,
 		"new peer notification for " MACSTR, MAC2STR(addr));
Index: hostapd-2021-02-08/wpa_supplicant/mesh_mpm.c
===================================================================
--- hostapd-2021-02-08.orig/wpa_supplicant/mesh_mpm.c
+++ hostapd-2021-02-08/wpa_supplicant/mesh_mpm.c
@@ -16,6 +16,7 @@
 #include "ap/hostapd.h"
 #include "ap/sta_info.h"
 #include "ap/ieee802_11.h"
+#include "ap/ieee802_11_auth.h"
 #include "ap/wpa_auth.h"
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
@@ -1128,10 +1129,12 @@ void mesh_mpm_action_rx(struct wpa_suppl
 	enum plink_event event;
 	struct ieee802_11_elems elems;
 	struct mesh_peer_mgmt_ie peer_mgmt_ie;
+	struct radius_sta rad_info;
 	const u8 *ies;
 	size_t ie_len;
 	int ret;
 	u16 reason = 0;
+	int acl_res;
 
 	if (mgmt->u.action.category != WLAN_ACTION_SELF_PROTECTED)
 		return;
@@ -1179,6 +1182,18 @@ void mesh_mpm_action_rx(struct wpa_suppl
 		return;
 	}
 	if (action_field != PLINK_CLOSE) {
+	if (action_field != PLINK_CLOSE) {
+		acl_res = hostapd_allowed_address(hapd, mgmt->sa,
+						  (const u8 *) mgmt,
+						  len, &rad_info, 0);
+		if (acl_res == HOSTAPD_ACL_REJECT) {
+			wpa_printf(MSG_DEBUG,
+				   "MPM: Ignore action frame\n");
+			return;
+
+		}
+	}
+
 		if (!elems.mesh_id || !elems.mesh_config) {
 			wpa_printf(MSG_DEBUG,
 				   "MPM: No Mesh ID or Mesh Configuration element");
Index: hostapd-2021-02-08/wpa_supplicant/wpa_supplicant.conf
===================================================================
--- hostapd-2021-02-08.orig/wpa_supplicant/wpa_supplicant.conf
+++ hostapd-2021-02-08/wpa_supplicant/wpa_supplicant.conf
@@ -150,6 +150,20 @@ ap_scan=1
 # This timeout value is used in mesh STA to clean up inactive stations.
 #mesh_max_inactivity=300
 
+# Mesh node address -based authentication
+# Please note that this kind of access control requires a driver that uses
+# wpa_supplicant to take care of management frame and mesh PLINK connection
+# processing and as such.
+# 0 = accept unless in deny list
+# 1 = deny unless in accept list
+macaddr_acl=0
+
+# Accept/deny lists are read from separate files (containing list of
+# MAC addresses, one per line). Use absolute path name to make sure that the
+# files can be read on SIGHUP configuration reloads.
+#accept_mac_file=/etc/hostapd.accept
+#deny_mac_file=/etc/hostapd.deny
+
 # cert_in_cb - Whether to include a peer certificate dump in events
 # This controls whether peer certificates for authentication server and
 # its certificate chain are included in EAP peer certificate events. This is
