[PATCH] settings: add support for mac-blacklists for wifi and ethernet



Hi,

i created a patch to support MAC address blacklists for Ethernet/Wifi
connections. With this patch it's possible to disable a connection for a
given list of mac-addresses. 

I created this patch for the NM 0.8 branch and i have not tested this
for 0.9 and i don't know if it's difficult to port this patch to NM 0.9.

Cheers,

Tom
From b4e118440aa3b840ff10ff005276f6d1b2de76c4 Mon Sep 17 00:00:00 2001
From: Thomas Bechtold <thomasbechtold jpberlin de>
Date: Thu, 16 Jun 2011 23:07:40 +0200
Subject: [PATCH] settings: add support for mac-blacklists for wifi and
 ethernet

wifi and ethernet settings have a new parameter called
"mac-address-blacklist". Devices with MAC addresses listed in
"mac-address-blacklist" will never use this connection.
---
 libnm-util/libnm-util.ver        |    2 +
 libnm-util/nm-setting-wired.c    |   50 ++++++++++++++++++++++++++++++++++++++
 libnm-util/nm-setting-wired.h    |    2 +
 libnm-util/nm-setting-wireless.c |   48 ++++++++++++++++++++++++++++++++++-
 libnm-util/nm-setting-wireless.h |    2 +
 src/nm-device-ethernet.c         |   20 +++++++++++++++
 src/nm-device-wifi.c             |   19 ++++++++++++++
 7 files changed, 141 insertions(+), 2 deletions(-)

diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver
index b348fd6..f58076f 100644
--- a/libnm-util/libnm-util.ver
+++ b/libnm-util/libnm-util.ver
@@ -319,6 +319,7 @@ global:
 	nm_setting_wired_get_cloned_mac_address;
 	nm_setting_wired_get_duplex;
 	nm_setting_wired_get_mac_address;
+	nm_setting_wired_get_mac_address_blacklist;
 	nm_setting_wired_get_mtu;
 	nm_setting_wired_get_num_s390_options;
 	nm_setting_wired_get_port;
@@ -339,6 +340,7 @@ global:
 	nm_setting_wireless_get_channel;
 	nm_setting_wireless_get_cloned_mac_address;
 	nm_setting_wireless_get_mac_address;
+	nm_setting_wireless_get_mac_address_blacklist;
 	nm_setting_wireless_get_mode;
 	nm_setting_wireless_get_mtu;
 	nm_setting_wireless_get_num_seen_bssids;
diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c
index 8691aee..d148578 100644
--- a/libnm-util/nm-setting-wired.c
+++ b/libnm-util/nm-setting-wired.c
@@ -27,6 +27,7 @@
 #include <ctype.h>
 #include <net/ethernet.h>
 #include <dbus/dbus-glib.h>
+#include <netinet/ether.h>
 
 #include "nm-setting-wired.h"
 #include "nm-param-spec-specialized.h"
@@ -79,6 +80,7 @@ typedef struct {
 	gboolean auto_negotiate;
 	GByteArray *device_mac_address;
 	GByteArray *cloned_mac_address;
+	GSList *mac_address_blacklist;
 	guint32 mtu;
 	GPtrArray *s390_subchannels;
 	char *s390_nettype;
@@ -93,6 +95,7 @@ enum {
 	PROP_AUTO_NEGOTIATE,
 	PROP_MAC_ADDRESS,
 	PROP_CLONED_MAC_ADDRESS,
+	PROP_MAC_ADDRESS_BLACKLIST,
 	PROP_MTU,
 	PROP_S390_SUBCHANNELS,
 	PROP_S390_NETTYPE,
@@ -165,6 +168,14 @@ nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting)
 	return NM_SETTING_WIRED_GET_PRIVATE (setting)->cloned_mac_address;
 }
 
+const GSList *
+nm_setting_wired_get_mac_address_blacklist (NMSettingWired *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL);
+
+	return NM_SETTING_WIRED_GET_PRIVATE (setting)->mac_address_blacklist;
+}
+
 guint32
 nm_setting_wired_get_mtu (NMSettingWired *setting)
 {
@@ -363,6 +374,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 	const char *valid_duplex[] = { "half", "full", NULL };
 	const char *valid_nettype[] = { "qeth", "lcs", "ctc", NULL };
 	GHashTableIter iter;
+	GSList* mac_blacklist_iter;
 	const char *key, *value;
 
 	if (priv->port && !_nm_utils_string_in_list (priv->port, valid_ports)) {
@@ -389,6 +401,19 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 		return FALSE;
 	}
 
+	for (mac_blacklist_iter = priv->mac_address_blacklist; 
+		 mac_blacklist_iter; mac_blacklist_iter = mac_blacklist_iter->next) {
+		struct ether_addr addr;
+
+		if (!ether_aton_r (mac_blacklist_iter->data, &addr)) {
+			g_set_error (error,
+			             NM_SETTING_WIRED_ERROR,
+			             NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
+			             NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST);
+			return FALSE;
+		}
+	}
+
 	if (   priv->s390_subchannels
 	    && !(priv->s390_subchannels->len == 3 || priv->s390_subchannels->len == 2)) {
 		g_set_error (error,
@@ -456,6 +481,8 @@ finalize (GObject *object)
 	if (priv->cloned_mac_address)
 		g_byte_array_free (priv->cloned_mac_address, TRUE);
 
+	nm_utils_slist_free (priv->mac_address_blacklist, g_free);
+
 	G_OBJECT_CLASS (nm_setting_wired_parent_class)->finalize (object);
 }
 
@@ -497,6 +524,10 @@ set_property (GObject *object, guint prop_id,
 			g_byte_array_free (priv->cloned_mac_address, TRUE);
 		priv->cloned_mac_address = g_value_dup_boxed (value);
 		break;
+	case PROP_MAC_ADDRESS_BLACKLIST:
+		nm_utils_slist_free (priv->mac_address_blacklist, g_free);
+		priv->mac_address_blacklist = g_value_dup_boxed (value);
+		break;
 	case PROP_MTU:
 		priv->mtu = g_value_get_uint (value);
 		break;
@@ -550,6 +581,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_CLONED_MAC_ADDRESS:
 		g_value_set_boxed (value, nm_setting_wired_get_cloned_mac_address (setting));
 		break;
+	case PROP_MAC_ADDRESS_BLACKLIST:
+		g_value_set_boxed (value, NM_SETTING_WIRED_GET_PRIVATE (setting)->mac_address_blacklist);
+		break;
 	case PROP_MTU:
 		g_value_set_uint (value, nm_setting_wired_get_mtu (setting));
 		break;
@@ -685,6 +719,22 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
 	                                     "This is known as MAC cloning or spoofing.",
 	                                     DBUS_TYPE_G_UCHAR_ARRAY,
 	                                     G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+    
+    /**
+	 * NMSettingWireless:mac-address-backlist:
+	 *
+	 * If specified, this connection will never apply to the WiFi device
+	 * whose permanent MAC address matches.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_MAC_ADDRESS_BLACKLIST,
+		 _nm_param_spec_specialized (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST,
+									 "Device MAC Address blacklist (each MAC address "
+									 "has format '00:11:22:33:44:55').",
+									 "If specified, this connection will never apply to "
+									 "the wired device whose permanent MAC address matches.",
+									 DBUS_TYPE_G_LIST_OF_STRING,
+									 G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
 
 	/**
 	 * NMSettingWired:mtu:
diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h
index 32361b4..cc26d55 100644
--- a/libnm-util/nm-setting-wired.h
+++ b/libnm-util/nm-setting-wired.h
@@ -58,6 +58,7 @@ GQuark nm_setting_wired_error_quark (void);
 #define NM_SETTING_WIRED_AUTO_NEGOTIATE "auto-negotiate"
 #define NM_SETTING_WIRED_MAC_ADDRESS "mac-address"
 #define NM_SETTING_WIRED_CLONED_MAC_ADDRESS "cloned-mac-address"
+#define NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST "mac-address-blacklist"
 #define NM_SETTING_WIRED_MTU "mtu"
 #define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels"
 #define NM_SETTING_WIRED_S390_NETTYPE "s390-nettype"
@@ -85,6 +86,7 @@ guint32           nm_setting_wired_get_speed            (NMSettingWired *setting
 const char *      nm_setting_wired_get_duplex           (NMSettingWired *setting);
 gboolean          nm_setting_wired_get_auto_negotiate   (NMSettingWired *setting);
 const GByteArray *nm_setting_wired_get_mac_address      (NMSettingWired *setting);
+const GSList     *nm_setting_wired_get_mac_address_blacklist (NMSettingWired *setting);
 const GByteArray *nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting);
 guint32           nm_setting_wired_get_mtu              (NMSettingWired *setting);
 
diff --git a/libnm-util/nm-setting-wireless.c b/libnm-util/nm-setting-wireless.c
index ec7d53a..de92ded 100644
--- a/libnm-util/nm-setting-wireless.c
+++ b/libnm-util/nm-setting-wireless.c
@@ -89,6 +89,7 @@ typedef struct {
 	guint32 tx_power;
 	GByteArray *device_mac_address;
 	GByteArray *cloned_mac_address;
+	GSList *mac_address_blacklist;
 	guint32 mtu;
 	GSList *seen_bssids;
 	char *security;
@@ -105,6 +106,7 @@ enum {
 	PROP_TX_POWER,
 	PROP_MAC_ADDRESS,
 	PROP_CLONED_MAC_ADDRESS,
+	PROP_MAC_ADDRESS_BLACKLIST,
 	PROP_MTU,
 	PROP_SEEN_BSSIDS,
 	PROP_SEC,
@@ -367,6 +369,14 @@ nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address;
 }
 
+const GSList *
+nm_setting_wireless_get_mac_address_blacklist (NMSettingWireless *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
+
+	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address_blacklist;
+}
+
 guint32
 nm_setting_wireless_get_mtu (NMSettingWireless *setting)
 {
@@ -524,6 +534,18 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 		return FALSE;
 	}
 
+	for (iter = priv->mac_address_blacklist; iter; iter = iter->next) {
+		struct ether_addr addr;
+
+		if (!ether_aton_r (iter->data, &addr)) {
+			g_set_error (error,
+			             NM_SETTING_WIRELESS_ERROR,
+			             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
+			             NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST);
+			return FALSE;
+		}
+	}
+
 	for (iter = priv->seen_bssids; iter; iter = iter->next) {
 		struct ether_addr addr;
 
@@ -558,7 +580,6 @@ static void
 finalize (GObject *object)
 {
 	NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (object);
-
 	g_free (priv->mode);
 	g_free (priv->band);
 	g_free (priv->security);
@@ -571,7 +592,7 @@ finalize (GObject *object)
 		g_byte_array_free (priv->device_mac_address, TRUE);
 	if (priv->cloned_mac_address)
 		g_byte_array_free (priv->cloned_mac_address, TRUE);
-
+	nm_utils_slist_free (priv->mac_address_blacklist, g_free);
 	nm_utils_slist_free (priv->seen_bssids, g_free);
 
 	G_OBJECT_CLASS (nm_setting_wireless_parent_class)->finalize (object);
@@ -621,6 +642,10 @@ set_property (GObject *object, guint prop_id,
 			g_byte_array_free (priv->cloned_mac_address, TRUE);
 		priv->cloned_mac_address = g_value_dup_boxed (value);
 		break;
+	case PROP_MAC_ADDRESS_BLACKLIST:
+		nm_utils_slist_free (priv->mac_address_blacklist, g_free);
+		priv->mac_address_blacklist = g_value_dup_boxed (value);
+		break;
 	case PROP_MTU:
 		priv->mtu = g_value_get_uint (value);
 		break;
@@ -672,6 +697,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_CLONED_MAC_ADDRESS:
 		g_value_set_boxed (value, nm_setting_wireless_get_cloned_mac_address (setting));
 		break;
+	case PROP_MAC_ADDRESS_BLACKLIST:
+		g_value_set_boxed (value, NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address_blacklist);
+		break;
 	case PROP_MTU:
 		g_value_set_uint (value, nm_setting_wireless_get_mtu (setting));
 		break;
@@ -868,6 +896,22 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
 	                                     DBUS_TYPE_G_UCHAR_ARRAY,
 	                                     G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
+    /**
+	 * NMSettingWireless:mac-address-backlist:
+	 *
+	 * If specified, this connection will never apply to the WiFi device
+	 * whose permanent MAC address matches.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_MAC_ADDRESS_BLACKLIST,
+		 _nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST,
+									 "Device MAC Address blacklist (each MAC address "
+									 "has format '00:11:22:33:44:55').",
+									 "If specified, this connection will never apply to "
+									 "the WiFi device whose permanent MAC address matches.",
+									 DBUS_TYPE_G_LIST_OF_STRING,
+									 G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
+
 	/**
 	 * NMSettingWireless:seen-bssids:
 	 *
diff --git a/libnm-util/nm-setting-wireless.h b/libnm-util/nm-setting-wireless.h
index 2216a24..84cfe88 100644
--- a/libnm-util/nm-setting-wireless.h
+++ b/libnm-util/nm-setting-wireless.h
@@ -64,6 +64,7 @@ GQuark nm_setting_wireless_error_quark (void);
 #define NM_SETTING_WIRELESS_TX_POWER    "tx-power"
 #define NM_SETTING_WIRELESS_MAC_ADDRESS "mac-address"
 #define NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS "cloned-mac-address"
+#define NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST "mac-address-blacklist"
 #define NM_SETTING_WIRELESS_MTU         "mtu"
 #define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids"
 #define NM_SETTING_WIRELESS_SEC         "security"
@@ -95,6 +96,7 @@ guint32           nm_setting_wireless_get_rate               (NMSettingWireless
 guint32           nm_setting_wireless_get_tx_power           (NMSettingWireless *setting);
 const GByteArray *nm_setting_wireless_get_mac_address        (NMSettingWireless *setting);
 const GByteArray *nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting);
+const GSList      *nm_setting_wireless_get_mac_address_blacklist (NMSettingWireless *setting);
 guint32           nm_setting_wireless_get_mtu                (NMSettingWireless *setting);
 const char       *nm_setting_wireless_get_security           (NMSettingWireless *setting);
 
diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c
index c4f62f3..a9d9b9d 100644
--- a/src/nm-device-ethernet.c
+++ b/src/nm-device-ethernet.c
@@ -33,6 +33,8 @@
 #include <unistd.h>
 #include <linux/if.h>
 #include <errno.h>
+#include <netinet/ether.h>
+
 
 #define G_UDEV_API_IS_SUBJECT_TO_CHANGE
 #include <gudev/gudev.h>
@@ -894,6 +896,8 @@ real_get_best_auto_connection (NMDevice *dev,
 		NMSettingWired *s_wired;
 		const char *connection_type;
 		gboolean is_pppoe = FALSE;
+		const GSList *mac_blacklist, *mac_blacklist_iter;
+		gboolean mac_blacklist_found = FALSE;
 
 		s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
 		g_assert (s_con);
@@ -924,6 +928,22 @@ real_get_best_auto_connection (NMDevice *dev,
 				continue;
 		}
 
+        /* check for mac address blacklist */
+		mac_blacklist = nm_setting_wired_get_mac_address_blacklist(s_wired);
+		for (mac_blacklist_iter = mac_blacklist; mac_blacklist_iter;
+			 mac_blacklist_iter = g_slist_next (mac_blacklist_iter)) {
+			struct ether_addr addr;
+			if (!ether_aton_r (mac_blacklist_iter->data, &addr)) {
+				g_warn_if_reached();
+				continue;
+			}
+			if (memcmp(&addr, &priv->perm_hw_addr, ETH_ALEN) == 0)
+				mac_blacklist_found = TRUE;
+		}
+		/* found device mac address in blacklist - do not use this connection */
+		if (mac_blacklist_found)
+			continue;
+
 		return connection;
 	}
 	return NULL;
diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c
index 16a1b7b..a3199e1 100644
--- a/src/nm-device-wifi.c
+++ b/src/nm-device-wifi.c
@@ -33,6 +33,7 @@
 #include <linux/sockios.h>
 #include <linux/ethtool.h>
 #include <sys/ioctl.h>
+#include <netinet/ether.h>
 
 #include "nm-glib-compat.h"
 #include "nm-device.h"
@@ -1363,6 +1364,8 @@ real_get_best_auto_connection (NMDevice *dev,
 		NMSettingConnection *s_con;
 		NMSettingWireless *s_wireless;
 		const GByteArray *mac;
+		const GSList *mac_blacklist, *mac_blacklist_iter;
+		gboolean mac_blacklist_found = FALSE;
 		NMSettingIP4Config *s_ip4;
 		const char *method = NULL;
 
@@ -1380,7 +1383,23 @@ real_get_best_auto_connection (NMDevice *dev,
 
 		mac = nm_setting_wireless_get_mac_address (s_wireless);
 		if (mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN))
+			continue;
+
+        /* check for mac address blacklist */
+		mac_blacklist = nm_setting_wireless_get_mac_address_blacklist(s_wireless);
+		for (mac_blacklist_iter = mac_blacklist; mac_blacklist_iter;
+			 mac_blacklist_iter = g_slist_next (mac_blacklist_iter)) {
+			struct ether_addr addr;
+			if (!ether_aton_r (mac_blacklist_iter->data, &addr)) {
+				g_warn_if_reached();
 				continue;
+			}
+			if (memcmp(&addr, &priv->perm_hw_addr, ETH_ALEN) == 0)
+				mac_blacklist_found = TRUE;
+		}
+		/* found device mac address in blacklist - do not use this connection */
+		if (mac_blacklist_found)
+			continue;
 
 		/* Use the connection if it's a shared connection */
 		s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
-- 
1.7.5.4

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]