summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/NetworkManager.conf.xml.in4
-rw-r--r--src/devices/wifi/nm-device-wifi.c17
-rw-r--r--src/supplicant-manager/nm-supplicant-config.c53
-rw-r--r--src/supplicant-manager/nm-supplicant-config.h7
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.c105
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.h6
-rw-r--r--src/supplicant-manager/nm-supplicant-types.h6
-rw-r--r--src/supplicant-manager/tests/test-supplicant-config.c24
8 files changed, 190 insertions, 32 deletions
diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in
index 3fd1b12b19..b7e228aa3e 100644
--- a/man/NetworkManager.conf.xml.in
+++ b/man/NetworkManager.conf.xml.in
@@ -610,6 +610,10 @@ ipv6.ip6-privacy=1
<term><varname>vpn.timeout</varname></term>
<listitem><para>If left unspecified, default value of 60 seconds is used.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>wifi.mac-address-randomization</varname></term>
+ <listitem><para>If left unspecified, MAC address randomization is disabled.</para></listitem>
+ </varlistentry>
</para>
</refsect1>
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 3ba532dd6d..6327cba0df 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -49,6 +49,7 @@
#include "nm-enum-types.h"
#include "nm-connection-provider.h"
#include "nm-core-internal.h"
+#include "nm-config.h"
#include "nmdbus-device-wifi.h"
@@ -2201,6 +2202,9 @@ build_supplicant_config (NMDeviceWifi *self,
NMSupplicantConfig *config = NULL;
NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wireless_sec;
+ NMSupplicantFeature mac_randomization_support;
+ NMSettingMacRandomization mac_randomization_fallback;
+ gs_free char *svalue = NULL;
g_return_val_if_fail (self != NULL, NULL);
@@ -2217,9 +2221,20 @@ build_supplicant_config (NMDeviceWifi *self,
_LOGW (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out.");
}
+ mac_randomization_support = nm_supplicant_interface_get_mac_randomization_support (priv->sup_iface);
+ svalue = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
+ "wifi." NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION,
+ NM_DEVICE (self));
+ mac_randomization_fallback = _nm_utils_ascii_str_to_int64 (svalue, 10,
+ NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
+ NM_SETTING_MAC_RANDOMIZATION_ALWAYS,
+ NM_SETTING_MAC_RANDOMIZATION_DEFAULT);
+
if (!nm_supplicant_config_add_setting_wireless (config,
s_wireless,
- fixed_freq)) {
+ fixed_freq,
+ mac_randomization_support,
+ mac_randomization_fallback)) {
_LOGE (LOGD_WIFI, "Couldn't add 802-11-wireless setting to supplicant config.");
goto error;
}
diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c
index 65d6e2df44..28047b62e8 100644
--- a/src/supplicant-manager/nm-supplicant-config.c
+++ b/src/supplicant-manager/nm-supplicant-config.c
@@ -39,7 +39,7 @@ G_DEFINE_TYPE (NMSupplicantConfig, nm_supplicant_config, G_TYPE_OBJECT)
typedef struct {
char *value;
- guint32 len;
+ guint32 len;
OptType type;
} ConfigOption;
@@ -48,6 +48,7 @@ typedef struct
GHashTable *config;
GHashTable *blobs;
guint32 ap_scan;
+ NMSettingMacRandomization mac_randomization;
gboolean fast_required;
gboolean dispose_has_run;
} NMSupplicantConfigPrivate;
@@ -85,6 +86,7 @@ nm_supplicant_config_init (NMSupplicantConfig * self)
(GDestroyNotify) blob_free);
priv->ap_scan = 1;
+ priv->mac_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT;
priv->dispose_has_run = FALSE;
}
@@ -240,14 +242,30 @@ nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self)
return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan;
}
-void
-nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self,
- guint32 ap_scan)
+const char *
+nm_supplicant_config_get_mac_randomization (NMSupplicantConfig *self)
{
- g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self));
- g_return_if_fail (ap_scan <= 2);
+ g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), 0);
+
+ /**
+ * mac_addr - MAC address policy default
+ *
+ * 0 = use permanent MAC address
+ * 1 = use random MAC address for each ESS connection
+ * 2 = like 1, but maintain OUI (with local admin bit set)
+ *
+ * By default, permanent MAC address is used unless policy is changed by
+ * the per-network mac_addr parameter.
+ */
- NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan = ap_scan;
+ switch (NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->mac_randomization) {
+ case NM_SETTING_MAC_RANDOMIZATION_ALWAYS:
+ return "1";
+ case NM_SETTING_MAC_RANDOMIZATION_NEVER:
+ case NM_SETTING_MAC_RANDOMIZATION_DEFAULT:
+ default:
+ return "0";
+ }
}
gboolean
@@ -336,7 +354,9 @@ wifi_freqs_to_string (gboolean bg_band)
gboolean
nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
NMSettingWireless * setting,
- guint32 fixed_freq)
+ guint32 fixed_freq,
+ NMSupplicantFeature mac_randomization_support,
+ NMSettingMacRandomization mac_randomization_fallback)
{
NMSupplicantConfigPrivate *priv;
gboolean is_adhoc, is_ap;
@@ -441,6 +461,21 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
}
}
+ priv->mac_randomization = nm_setting_wireless_get_mac_address_randomization (setting);
+ if (priv->mac_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) {
+ priv->mac_randomization = mac_randomization_fallback;
+ if (priv->mac_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) {
+ /* the value is unconfigured. For now, that means we don't use randomization.*/
+ priv->mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER;
+ }
+ }
+
+ if ( priv->mac_randomization != NM_SETTING_MAC_RANDOMIZATION_NEVER
+ && mac_randomization_support != NM_SUPPLICANT_FEATURE_YES) {
+ nm_log_warn (LOGD_SUPPLICANT, "MAC address randomization is not supported");
+ return FALSE;
+ }
+
return TRUE;
}
@@ -805,7 +840,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
/* Wired 802.1x must always use eapol_flags=0 */
if (!add_string_val (self, "0", "eapol_flags", FALSE, FALSE))
return FALSE;
- nm_supplicant_config_set_ap_scan (self, 0);
+ priv->ap_scan = 0;
}
ADD_STRING_LIST_VAL (setting, 802_1x, eap_method, eap_methods, "eap", ' ', TRUE, FALSE);
diff --git a/src/supplicant-manager/nm-supplicant-config.h b/src/supplicant-manager/nm-supplicant-config.h
index 0cd3243ebf..b87edb43b0 100644
--- a/src/supplicant-manager/nm-supplicant-config.h
+++ b/src/supplicant-manager/nm-supplicant-config.h
@@ -54,8 +54,7 @@ NMSupplicantConfig *nm_supplicant_config_new (void);
guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig *self);
-void nm_supplicant_config_set_ap_scan (NMSupplicantConfig *self,
- guint32 ap_scan);
+const char *nm_supplicant_config_get_mac_randomization (NMSupplicantConfig *self);
gboolean nm_supplicant_config_fast_required (NMSupplicantConfig *self);
@@ -65,7 +64,9 @@ GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig *self);
gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig *self,
NMSettingWireless *setting,
- guint32 fixed_freq);
+ guint32 fixed_freq,
+ NMSupplicantFeature mac_randomization_support,
+ NMSettingMacRandomization mac_randomization_fallback);
gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
NMSettingWirelessSecurity *setting,
diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c
index 64a06b62fa..8267fb98af 100644
--- a/src/supplicant-manager/nm-supplicant-interface.c
+++ b/src/supplicant-manager/nm-supplicant-interface.c
@@ -488,6 +488,23 @@ nm_supplicant_interface_get_mac_randomization_support (NMSupplicantInterface *se
}
static void
+set_preassoc_scan_mac_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
+{
+ gs_unref_variant GVariant *variant = NULL;
+ gs_free_error GError *error = NULL;
+
+ variant = _nm_dbus_proxy_call_finish (proxy, result,
+ G_VARIANT_TYPE ("()"),
+ &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+ if (error)
+ nm_log_warn (LOGD_SUPPLICANT, "Failed to enable scan MAC address randomization");
+
+ iface_check_ready (NM_SUPPLICANT_INTERFACE (user_data));
+}
+
+static void
iface_introspect_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
NMSupplicantInterface *self;
@@ -512,8 +529,23 @@ iface_introspect_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data
if (strstr (data, "ProbeRequest"))
priv->ap_support = NM_SUPPLICANT_FEATURE_YES;
- if (strstr (data, "PreassocMacAddr"))
+ if (strstr (data, "PreassocMacAddr")) {
priv->mac_randomization_support = NM_SUPPLICANT_FEATURE_YES;
+
+ /* Turn on MAC randomization during scans by default */
+ priv->ready_count++;
+ g_dbus_proxy_call (priv->iface_proxy,
+ DBUS_INTERFACE_PROPERTIES ".Set",
+ g_variant_new ("(ssv)",
+ WPAS_DBUS_IFACE_INTERFACE,
+ "PreassocMacAddr",
+ g_variant_new_string ("1")),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->init_cancellable,
+ (GAsyncReadyCallback) set_preassoc_scan_mac_cb,
+ self);
+ }
}
iface_check_ready (self);
@@ -1126,6 +1158,51 @@ add_network_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
}
static void
+add_network (NMSupplicantInterface *self)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ g_dbus_proxy_call (priv->iface_proxy,
+ "AddNetwork",
+ g_variant_new ("(@a{sv})", nm_supplicant_config_to_variant (priv->cfg)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->assoc_cancellable,
+ (GAsyncReadyCallback) add_network_cb,
+ self);
+}
+
+static void
+set_mac_randomization_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
+{
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ gs_unref_variant GVariant *reply = NULL;
+ gs_free_error GError *error = NULL;
+
+ reply = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ if (!reply) {
+ g_dbus_error_strip_remote_error (error);
+ nm_log_warn (LOGD_SUPPLICANT, "Couldn't send MAC randomization mode to "
+ "the supplicant interface: %s.",
+ error->message);
+ emit_error_helper (self, error);
+ return;
+ }
+
+ nm_log_info (LOGD_SUPPLICANT, "Config: set MAC randomization to %s",
+ nm_supplicant_config_get_mac_randomization (priv->cfg));
+
+ add_network (self);
+}
+
+static void
set_ap_scan_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
NMSupplicantInterface *self;
@@ -1151,14 +1228,24 @@ set_ap_scan_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
nm_log_info (LOGD_SUPPLICANT, "Config: set interface ap_scan to %d",
nm_supplicant_config_get_ap_scan (priv->cfg));
- g_dbus_proxy_call (priv->iface_proxy,
- "AddNetwork",
- g_variant_new ("(@a{sv})", nm_supplicant_config_to_variant (priv->cfg)),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- priv->assoc_cancellable,
- (GAsyncReadyCallback) add_network_cb,
- self);
+ if (priv->mac_randomization_support == NM_SUPPLICANT_FEATURE_YES) {
+ const char *mac_randomization = nm_supplicant_config_get_mac_randomization (priv->cfg);
+
+ /* Enable/disable association MAC address randomization */
+ g_dbus_proxy_call (priv->iface_proxy,
+ DBUS_INTERFACE_PROPERTIES ".Set",
+ g_variant_new ("(ssv)",
+ WPAS_DBUS_IFACE_INTERFACE,
+ "MacAddr",
+ g_variant_new_string (mac_randomization)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->assoc_cancellable,
+ (GAsyncReadyCallback) set_mac_randomization_cb,
+ self);
+ } else {
+ add_network (self);
+ }
}
gboolean
diff --git a/src/supplicant-manager/nm-supplicant-interface.h b/src/supplicant-manager/nm-supplicant-interface.h
index 4cfdf5fdd8..77371789fe 100644
--- a/src/supplicant-manager/nm-supplicant-interface.h
+++ b/src/supplicant-manager/nm-supplicant-interface.h
@@ -67,12 +67,6 @@ enum {
#define NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR "connection-error"
#define NM_SUPPLICANT_INTERFACE_CREDENTIALS_REQUEST "credentials-request"
-typedef enum {
- NM_SUPPLICANT_FEATURE_UNKNOWN = 0, /* Can't detect whether supported or not */
- NM_SUPPLICANT_FEATURE_NO = 1, /* Feature definitely not supported */
- NM_SUPPLICANT_FEATURE_YES = 2, /* Feature definitely supported */
-} NMSupplicantFeature;
-
struct _NMSupplicantInterface {
GObject parent;
};
diff --git a/src/supplicant-manager/nm-supplicant-types.h b/src/supplicant-manager/nm-supplicant-types.h
index 1c16e49433..02682f566c 100644
--- a/src/supplicant-manager/nm-supplicant-types.h
+++ b/src/supplicant-manager/nm-supplicant-types.h
@@ -29,4 +29,10 @@ typedef struct _NMSupplicantManager NMSupplicantManager;
typedef struct _NMSupplicantInterface NMSupplicantInterface;
typedef struct _NMSupplicantConfig NMSupplicantConfig;
+typedef enum {
+ NM_SUPPLICANT_FEATURE_UNKNOWN = 0, /* Can't detect whether supported or not */
+ NM_SUPPLICANT_FEATURE_NO = 1, /* Feature definitely not supported */
+ NM_SUPPLICANT_FEATURE_YES = 2, /* Feature definitely supported */
+} NMSupplicantFeature;
+
#endif /* NM_SUPPLICANT_TYPES_H */
diff --git a/src/supplicant-manager/tests/test-supplicant-config.c b/src/supplicant-manager/tests/test-supplicant-config.c
index 11b027a3ed..01f5535a2b 100644
--- a/src/supplicant-manager/tests/test-supplicant-config.c
+++ b/src/supplicant-manager/tests/test-supplicant-config.c
@@ -158,7 +158,11 @@ test_wifi_open (void)
"*added 'bssid' value '11:22:33:44:55:66'*");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*added 'freq_list' value *");
- g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0));
+ g_assert (nm_supplicant_config_add_setting_wireless (config,
+ s_wifi,
+ 0,
+ NM_SUPPLICANT_FEATURE_UNKNOWN,
+ NM_SETTING_MAC_RANDOMIZATION_DEFAULT));
g_test_assert_expected_messages ();
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
@@ -256,7 +260,11 @@ test_wifi_wep_key (const char *detail,
"*added 'bssid' value '11:22:33:44:55:66'*");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*added 'freq_list' value *");
- g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0));
+ g_assert (nm_supplicant_config_add_setting_wireless (config,
+ s_wifi,
+ 0,
+ NM_SUPPLICANT_FEATURE_UNKNOWN,
+ NM_SETTING_MAC_RANDOMIZATION_DEFAULT));
g_test_assert_expected_messages ();
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
@@ -393,7 +401,11 @@ test_wifi_wpa_psk (const char *detail,
"*added 'bssid' value '11:22:33:44:55:66'*");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*added 'freq_list' value *");
- g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0));
+ g_assert (nm_supplicant_config_add_setting_wireless (config,
+ s_wifi,
+ 0,
+ NM_SUPPLICANT_FEATURE_UNKNOWN,
+ NM_SETTING_MAC_RANDOMIZATION_DEFAULT));
g_test_assert_expected_messages ();
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
@@ -532,7 +544,11 @@ test_wifi_eap (void)
"*added 'bssid' value '11:22:33:44:55:66'*");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*added 'freq_list' value *");
- g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0));
+ g_assert (nm_supplicant_config_add_setting_wireless (config,
+ s_wifi,
+ 0,
+ NM_SUPPLICANT_FEATURE_UNKNOWN,
+ NM_SETTING_MAC_RANDOMIZATION_DEFAULT));
g_test_assert_expected_messages ();
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,