diff options
author | Jiří Klimeš <jklimes@redhat.com> | 2011-06-30 12:54:18 +0200 |
---|---|---|
committer | Jiří Klimeš <jklimes@redhat.com> | 2011-06-30 16:46:26 +0200 |
commit | a6733c8b4fd0b289e192c8b1bbeaa82552aceb3d (patch) | |
tree | 13bb0863d8c7b3de90e62afff15bff4de0474425 | |
parent | f340c44fedc7504634bc4c6f5dac683871df4841 (diff) | |
download | NetworkManager-a6733c8b4fd0b289e192c8b1bbeaa82552aceb3d.tar.gz |
core: add MAC address blacklisting feature for WiFi and ethernet connections
"mac-address-blacklist" property is added to the ethernet and WiFi connections.
It is the MAC addresses list of devices on which the connection won't be
activated.
Original patch (NM_0_8 branch) from Thomas Bechtold <thomasbechtold@jpberlin.de>
-rw-r--r-- | libnm-util/libnm-util.ver | 2 | ||||
-rw-r--r-- | libnm-util/nm-setting-wired.c | 55 | ||||
-rw-r--r-- | libnm-util/nm-setting-wired.h | 4 | ||||
-rw-r--r-- | libnm-util/nm-setting-wireless.c | 52 | ||||
-rw-r--r-- | libnm-util/nm-setting-wireless.h | 4 | ||||
-rw-r--r-- | libnm-util/tests/test-general.c | 21 | ||||
-rw-r--r-- | src/nm-device-ethernet.c | 42 | ||||
-rw-r--r-- | src/nm-device-wifi.c | 42 | ||||
-rw-r--r-- | src/nm-manager.c | 4 |
9 files changed, 210 insertions, 16 deletions
diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 4ff0838e39..5394e56a91 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -342,6 +342,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; @@ -362,6 +363,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 8691aeee03..5992eaecf6 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -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_mac_address_blacklist (setting)); + break; case PROP_MTU: g_value_set_uint (value, nm_setting_wired_get_mtu (setting)); break; @@ -685,6 +719,25 @@ 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)); + + /** + * NMSettingWired:mac-address-blacklist: + * + * If specified, this connection will never apply to the ethernet device + * whose permanent MAC address matches an address in the list. Each + * MAC address is in the standard hex-digits-and-colons notation + * (00:11:22:33:44:55). + **/ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS_BLACKLIST, + _nm_param_spec_specialized (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, + "MAC Address Blacklist", + "If specified, this connection will never apply to " + "the ethernet device whose permanent MAC address matches " + "an address in the list. Each MAC address is in the " + "standard hex-digits-and-colons notation (00:11:22:33:44:55).", + 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 32361b4bca..c9e6872ec2 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -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" @@ -86,6 +87,7 @@ 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 GByteArray *nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting); +const GSList *nm_setting_wired_get_mac_address_blacklist (NMSettingWired *setting); guint32 nm_setting_wired_get_mtu (NMSettingWired *setting); const GPtrArray * nm_setting_wired_get_s390_subchannels (NMSettingWired *setting); diff --git a/libnm-util/nm-setting-wireless.c b/libnm-util/nm-setting-wireless.c index 1e243f0f40..391c89371d 100644 --- a/libnm-util/nm-setting-wireless.c +++ b/libnm-util/nm-setting-wireless.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -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; @@ -571,7 +593,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 +643,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 +698,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_mac_address_blacklist (setting)); + break; case PROP_MTU: g_value_set_uint (value, nm_setting_wireless_get_mtu (setting)); break; @@ -869,6 +898,25 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** + * NMSettingWireless:mac-address-blacklist: + * + * If specified, this connection will never apply to the WiFi device + * whose permanent MAC address matches an address in the list. Each + * MAC address is in the standard hex-digits-and-colons notation. + * (00:11:22:33:44:55). + **/ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS_BLACKLIST, + _nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, + "MAC Address Blacklist", + "If specified, this connection will never apply to " + "the WiFi device whose permanent MAC address matches " + "an address in the list. Each MAC address is in the " + "standard hex-digits-and-colons notation (00:11:22:33:44:55).", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE)); + + /** * NMSettingWireless:seen-bssids: * * A list of BSSIDs (each BSSID formatted as a MAC address like diff --git a/libnm-util/nm-setting-wireless.h b/libnm-util/nm-setting-wireless.h index d3e1ed41a3..6208902dce 100644 --- a/libnm-util/nm-setting-wireless.h +++ b/libnm-util/nm-setting-wireless.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -65,6 +65,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" @@ -99,6 +100,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/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index 867fcb6aa9..f2f7e8ffe6 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -852,16 +852,17 @@ test_connection_diff_a_only (void) { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN } } }, { NM_SETTING_WIRED_SETTING_NAME, { - { NM_SETTING_WIRED_PORT, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_WIRED_SPEED, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_WIRED_DUPLEX, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_WIRED_AUTO_NEGOTIATE, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_WIRED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_WIRED_CLONED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_WIRED_MTU, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_WIRED_S390_SUBCHANNELS, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_WIRED_S390_NETTYPE, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_WIRED_S390_OPTIONS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_PORT, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_SPEED, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_DUPLEX, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_AUTO_NEGOTIATE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_CLONED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_MTU, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_S390_SUBCHANNELS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_S390_NETTYPE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_S390_OPTIONS, NM_SETTING_DIFF_RESULT_IN_A }, { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, } }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, { diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index f470e090c1..35b7367050 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -34,6 +34,7 @@ #include <unistd.h> #include <linux/if.h> #include <errno.h> +#include <netinet/ether.h> #include <gudev/gudev.h> @@ -881,6 +882,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); @@ -909,6 +912,25 @@ real_get_best_auto_connection (NMDevice *dev, mac = nm_setting_wired_get_mac_address (s_wired); if (try_mac && mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) 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; + break; + } + } + /* Found device MAC address in the blacklist - do not use this connection */ + if (mac_blacklist_found) + continue; } return connection; @@ -1605,6 +1627,7 @@ real_check_connection_compatible (NMDevice *device, gboolean is_pppoe = FALSE; const GByteArray *mac; gboolean try_mac = TRUE; + const GSList *mac_blacklist, *mac_blacklist_iter; s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); g_assert (s_con); @@ -1645,6 +1668,25 @@ real_check_connection_compatible (NMDevice *device, "The connection's MAC address did not match this device."); return FALSE; } + + /* 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) { + g_set_error (error, + NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, + "The connection's MAC address (%s) is blacklisted in %s.", + (char *) mac_blacklist_iter->data, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); + return FALSE; + } + } } // FIXME: check bitrate against device capabilities diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 491b856ce2..ba31fb3a1b 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" @@ -1314,6 +1315,7 @@ real_check_connection_compatible (NMDevice *device, NMSettingConnection *s_con; NMSettingWireless *s_wireless; const GByteArray *mac; + const GSList *mac_blacklist, *mac_blacklist_iter; s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); g_assert (s_con); @@ -1341,6 +1343,25 @@ real_check_connection_compatible (NMDevice *device, return FALSE; } + /* 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) { + g_set_error (error, + NM_WIFI_ERROR, NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, + "The connection's MAC address (%s) is blacklisted in %s.", + (char *) mac_blacklist_iter->data, NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); + return FALSE; + } + } + // FIXME: check channel/freq/band against bands the hardware supports // FIXME: check encryption against device capabilities // FIXME: check bitrate against device capabilities @@ -1585,6 +1606,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; @@ -1602,7 +1625,26 @@ 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; + break; + } + } + /* Found device MAC address in the 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); diff --git a/src/nm-manager.c b/src/nm-manager.c index a15e4b7916..6e37c1780d 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2017,7 +2017,9 @@ pending_activate (NMManager *self, PendingActivation *pending) if (!path) { nm_log_warn (LOGD_CORE, "connection %s failed to activate: (%d) %s", - pending->connection_path, error->code, error->message); + pending->connection_path, + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); } else g_object_notify (G_OBJECT (pending->manager), NM_MANAGER_ACTIVE_CONNECTIONS); |