summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-11-14 13:07:50 +0100
committerThomas Haller <thaller@redhat.com>2023-11-16 13:07:54 +0100
commitd210923c0f4b53d2da28a3718ac9283980a1ff61 (patch)
treea0fb52a0a5ccd59aba156443886b2eae7bf7b69a
parent587f5afb5a57ca19913deffdbe0862eea1beb973 (diff)
wifi: add "wifi.cloned-mac-address=stable-ssid"
Add a new "stable-ssid" mode that generates the MAC address based on the Wi-Fi's SSID. Note that this gives the same MAC address as setting connection.stable-id="${NETWORK_SSID}" wifi.cloned-mac-address="stable" The difference is that changing the stable ID of a profile also affects "ipv6.addr-gen-mode=stable-privacy" and other settings.
-rw-r--r--NEWS2
-rw-r--r--src/core/devices/nm-device.c27
-rw-r--r--src/core/nm-core-utils.c6
-rw-r--r--src/core/nm-core-utils.h3
-rw-r--r--src/core/tests/test-core.c12
-rw-r--r--src/libnm-core-aux-intern/nm-common-macros.h14
-rw-r--r--src/libnm-core-impl/nm-setting-wireless.c4
-rw-r--r--src/libnmc-setting/settings-docs.h.in2
-rw-r--r--src/nmcli/gen-metadata-nm-settings-nmcli.c2
-rw-r--r--src/nmcli/gen-metadata-nm-settings-nmcli.xml.in4
10 files changed, 66 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index 336e276168..5759157b42 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ Overview of changes since NetworkManager-1.44
* Support dynamic value "${NETWORK_SSID}" for connection.stable-id to generate
the stable ID based on the Wi-Fi's SSID.
+* Support new value "wifi.cloned-mac-address=stable-ssid" for randomizing the
+ MAC address based on the Wi-Fi network.
* Change internal ABI of NMSetting types and NMSimpleConnection. The layout of
these structs was already hidden from public headers since 1.34 and this change
should not be noticeable.
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 317a44a4f6..b7e855bcde 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -17433,9 +17433,12 @@ _hw_addr_get_cloned(NMDevice *self,
addr_out = g_steal_pointer(&hw_addr_generated);
type_out = HW_ADDR_TYPE_GENERATED;
- } else if (NM_IN_STRSET(addr, NM_CLONED_MAC_STABLE)) {
+ } else if (nm_streq(addr, NM_CLONED_MAC_STABLE)
+ || (is_wifi && nm_streq(addr, NM_CLONED_MAC_STABLE_SSID))) {
+ gs_free char *stable_id_free = NULL;
NMUtilsStableType stable_type;
const char *stable_id;
+ GBytes *ssid = NULL;
if (priv->hw_addr_type == HW_ADDR_TYPE_GENERATED) {
/* hm, we already use a generate MAC address. Most certainly, that is from the same
@@ -17443,7 +17446,27 @@ _hw_addr_get_cloned(NMDevice *self,
goto out_no_action;
}
- stable_id = _prop_get_connection_stable_id(self, connection, &stable_type);
+ if (!nm_streq(addr, NM_CLONED_MAC_STABLE)) {
+ NMSettingWireless *s_wifi;
+
+ s_wifi = nm_connection_get_setting_wireless(connection);
+ if (s_wifi)
+ ssid = nm_setting_wireless_get_ssid(s_wifi);
+ }
+
+ if (G_UNLIKELY(ssid)) {
+ stable_type = nm_utils_stable_id_parse_network_ssid(ssid,
+ nm_connection_get_uuid(connection),
+ &stable_id_free);
+ stable_id = stable_id_free;
+ } else {
+ /* If @addr is NM_CLONED_MAC_STABLE_SSID, and this is not a Wi-Fi
+ * profile, the behavior is the same as NM_CLONED_MAC_STABLE. Note
+ * that this really shouldn't happen, because we have a Wi-Fi
+ * profile at hand, and an SSID should be set. */
+ stable_id = _prop_get_connection_stable_id(self, connection, &stable_type);
+ }
+
hw_addr_generated = nm_utils_hw_addr_gen_stable_eth(
stable_type,
stable_id,
diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c
index 06b93f17ba..66549605ec 100644
--- a/src/core/nm-core-utils.c
+++ b/src/core/nm-core-utils.c
@@ -3546,6 +3546,12 @@ nm_utils_stable_id_parse(const char *stable_id,
return NM_UTILS_STABLE_TYPE_GENERATED;
}
+NMUtilsStableType
+nm_utils_stable_id_parse_network_ssid(GBytes *ssid, const char *uuid, char **out_stable_id)
+{
+ return nm_utils_stable_id_parse("${NETWORK_SSID}", NULL, NULL, NULL, uuid, ssid, out_stable_id);
+}
+
/*****************************************************************************/
static gboolean
diff --git a/src/core/nm-core-utils.h b/src/core/nm-core-utils.h
index ec72690b07..22ee8686af 100644
--- a/src/core/nm-core-utils.h
+++ b/src/core/nm-core-utils.h
@@ -316,6 +316,9 @@ NMUtilsStableType nm_utils_stable_id_parse(const char *stable_id,
GBytes *ssid,
char **out_generated);
+NMUtilsStableType
+nm_utils_stable_id_parse_network_ssid(GBytes *ssid, const char *uuid, char **out_stable_id);
+
char *nm_utils_stable_id_random(void);
char *nm_utils_stable_id_generated_complete(const char *msg);
diff --git a/src/core/tests/test-core.c b/src/core/tests/test-core.c
index 01d2782012..faf51f4706 100644
--- a/src/core/tests/test-core.c
+++ b/src/core/tests/test-core.c
@@ -2191,6 +2191,18 @@ test_stable_id_parse(void)
_parse_random("${RANDOM}");
_parse_random(" ${RANDOM}");
_parse_random("${BOOT}${RANDOM}");
+
+ {
+ gs_free char *str = NULL;
+ char ssid_bin[] = "foo\n";
+ gs_unref_bytes GBytes *ssid = g_bytes_new_static(ssid_bin, sizeof(ssid_bin) - 1);
+ NMUtilsStableType stable_type;
+
+ stable_type = nm_utils_stable_id_parse_network_ssid(ssid, "uuid", &str);
+
+ g_assert_cmpstr(str, ==, "${NETWORK_SSID}=9{s:foo\\012}");
+ g_assert_cmpint(stable_type, ==, NM_UTILS_STABLE_TYPE_GENERATED);
+ }
}
/*****************************************************************************/
diff --git a/src/libnm-core-aux-intern/nm-common-macros.h b/src/libnm-core-aux-intern/nm-common-macros.h
index 155c585aef..3e6eabaead 100644
--- a/src/libnm-core-aux-intern/nm-common-macros.h
+++ b/src/libnm-core-aux-intern/nm-common-macros.h
@@ -34,10 +34,11 @@
"org.freedesktop.NetworkManager.enable-disable-connectivity-check"
#define NM_AUTH_PERMISSION_WIFI_SCAN "org.freedesktop.NetworkManager.wifi.scan"
-#define NM_CLONED_MAC_PRESERVE "preserve"
-#define NM_CLONED_MAC_PERMANENT "permanent"
-#define NM_CLONED_MAC_RANDOM "random"
-#define NM_CLONED_MAC_STABLE "stable"
+#define NM_CLONED_MAC_PRESERVE "preserve"
+#define NM_CLONED_MAC_PERMANENT "permanent"
+#define NM_CLONED_MAC_RANDOM "random"
+#define NM_CLONED_MAC_STABLE "stable"
+#define NM_CLONED_MAC_STABLE_SSID "stable-ssid"
static inline gboolean
NM_CLONED_MAC_IS_SPECIAL(const char *str, gboolean is_wifi)
@@ -49,6 +50,11 @@ NM_CLONED_MAC_IS_SPECIAL(const char *str, gboolean is_wifi)
NM_CLONED_MAC_STABLE))
return TRUE;
+ if (is_wifi) {
+ if (NM_IN_STRSET(str, NM_CLONED_MAC_STABLE_SSID))
+ return TRUE;
+ }
+
return FALSE;
}
diff --git a/src/libnm-core-impl/nm-setting-wireless.c b/src/libnm-core-impl/nm-setting-wireless.c
index cdf77ad7aa..06450f5227 100644
--- a/src/libnm-core-impl/nm-setting-wireless.c
+++ b/src/libnm-core-impl/nm-setting-wireless.c
@@ -1542,12 +1542,14 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass)
* This is known as MAC cloning or spoofing.
*
* Beside explicitly specifying a MAC address, the special values "preserve", "permanent",
- * "random" and "stable" are supported.
+ * "random", "stable" and "stable-ssid" are supported.
* "preserve" means not to touch the MAC address on activation.
* "permanent" means to use the permanent hardware address of the device.
* "random" creates a random MAC address on each connect.
* "stable" creates a hashed MAC address based on connection.stable-id and a
* machine dependent key.
+ * "stable-ssid" creates a hashed MAC address based on the SSID, the same as setting the
+ * stable-id to "${NETWORK_SSID}".
*
* If unspecified, the value can be overwritten via global defaults, see manual
* of NetworkManager.conf. If still unspecified, it defaults to "preserve"
diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in
index 634bdf600e..b9c06e55eb 100644
--- a/src/libnmc-setting/settings-docs.h.in
+++ b/src/libnmc-setting/settings-docs.h.in
@@ -400,7 +400,7 @@
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_BAND N_("802.11 frequency band of the network. One of \"a\" for 5GHz 802.11a or \"bg\" for 2.4GHz 802.11. This will lock associations to the Wi-Fi network to the specific band, i.e. if \"a\" is specified, the device will not associate with the same network in the 2.4GHz band even if the network's settings are compatible. This setting depends on specific driver capability and may not work with all drivers.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_BSSID N_("If specified, directs the device to only associate with the given access point. This capability is highly driver dependent and not supported by all devices. Note: this property does not control the BSSID used when creating an Ad-Hoc network and is unlikely to in the future. Locking a client profile to a certain BSSID will prevent roaming and also disable background scanning. That can be useful, if there is only one access point for the SSID.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_CHANNEL N_("Wireless channel to use for the Wi-Fi connection. The device will only join (or create for Ad-Hoc networks) a Wi-Fi network on the specified channel. Because channel numbers overlap between bands, this property also requires the \"band\" property to be set.")
-#define DESCRIBE_DOC_NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS N_("If specified, request that the device use this MAC address instead. This is known as MAC cloning or spoofing. Beside explicitly specifying a MAC address, the special values \"preserve\", \"permanent\", \"random\" and \"stable\" are supported. \"preserve\" means not to touch the MAC address on activation. \"permanent\" means to use the permanent hardware address of the device. \"random\" creates a random MAC address on each connect. \"stable\" creates a hashed MAC address based on connection.stable-id and a machine dependent key. If unspecified, the value can be overwritten via global defaults, see manual of NetworkManager.conf. If still unspecified, it defaults to \"preserve\" (older versions of NetworkManager may use a different default value). On D-Bus, this field is expressed as \"assigned-mac-address\" or the deprecated \"cloned-mac-address\".")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS N_("If specified, request that the device use this MAC address instead. This is known as MAC cloning or spoofing. Beside explicitly specifying a MAC address, the special values \"preserve\", \"permanent\", \"random\", \"stable\" and \"stable-ssid\" are supported. \"preserve\" means not to touch the MAC address on activation. \"permanent\" means to use the permanent hardware address of the device. \"random\" creates a random MAC address on each connect. \"stable\" creates a hashed MAC address based on connection.stable-id and a machine dependent key. \"stable-ssid\" creates a hashed MAC address based on the SSID, the same as setting the stable-id to \"${NETWORK_SSID}\". If unspecified, the value can be overwritten via global defaults, see manual of NetworkManager.conf. If still unspecified, it defaults to \"preserve\" (older versions of NetworkManager may use a different default value). On D-Bus, this field is expressed as \"assigned-mac-address\" or the deprecated \"cloned-mac-address\".")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK N_("With \"cloned-mac-address\" setting \"random\" or \"stable\", by default all bits of the MAC address are scrambled and a locally-administered, unicast MAC address is created. This property allows to specify that certain bits are fixed. Note that the least significant bit of the first MAC address will always be unset to create a unicast MAC address. If the property is NULL, it is eligible to be overwritten by a default connection setting. If the value is still NULL or an empty string, the default is to create a locally-administered, unicast MAC address. If the value contains one MAC address, this address is used as mask. The set bits of the mask are to be filled with the current MAC address of the device, while the unset bits are subject to randomization. Setting \"FE:FF:FF:00:00:00\" means to preserve the OUI of the current MAC address and only randomize the lower 3 bytes using the \"random\" or \"stable\" algorithm. If the value contains one additional MAC address after the mask, this address is used instead of the current MAC address to fill the bits that shall not be randomized. For example, a value of \"FE:FF:FF:00:00:00 68:F7:28:00:00:00\" will set the OUI of the MAC address to 68:F7:28, while the lower bits are randomized. A value of \"02:00:00:00:00:00 00:00:00:00:00:00\" will create a fully scrambled globally-administered, burned-in MAC address. If the value contains more than one additional MAC addresses, one of them is chosen randomly. For example, \"02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00\" will create a fully scrambled MAC address, randomly locally or globally administered.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_HIDDEN N_("If TRUE, indicates that the network is a non-broadcasting network that hides its SSID. This works both in infrastructure and AP mode. In infrastructure mode, various workarounds are used for a more reliable discovery of hidden networks, such as probe-scanning the SSID. However, these workarounds expose inherent insecurities with hidden SSID networks, and thus hidden SSID networks should be used with caution. In AP mode, the created network does not broadcast its SSID. Note that marking the network as hidden may be a privacy issue for you (in infrastructure mode) or client stations (in AP mode), as the explicit probe-scans are distinctly recognizable on the air.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_MAC_ADDRESS N_("If specified, this connection will only apply to the Wi-Fi device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).")
diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.c b/src/nmcli/gen-metadata-nm-settings-nmcli.c
index c52e6b3d74..babf1f064b 100644
--- a/src/nmcli/gen-metadata-nm-settings-nmcli.c
+++ b/src/nmcli/gen-metadata-nm-settings-nmcli.c
@@ -482,6 +482,8 @@ get_property_special_values(const NMMetaPropertyInfo *prop_info)
NM_CLONED_MAC_PERMANENT,
NM_CLONED_MAC_RANDOM,
NM_CLONED_MAC_STABLE);
+ if (prop_typ_data->subtype.mac.mode == NM_META_PROPERTY_TYPE_MAC_MODE_CLONED_WIFI)
+ append_vals(special_values, NM_CLONED_MAC_STABLE_SSID);
break;
default:
break;
diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
index 2b9bd14837..bea062b0f2 100644
--- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
+++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
@@ -49,9 +49,9 @@
format="MAC address" />
<property name="cloned-mac-address"
alias="cloned-mac"
- nmcli-description="If specified, request that the device use this MAC address instead. This is known as MAC cloning or spoofing. Beside explicitly specifying a MAC address, the special values &quot;preserve&quot;, &quot;permanent&quot;, &quot;random&quot; and &quot;stable&quot; are supported. &quot;preserve&quot; means not to touch the MAC address on activation. &quot;permanent&quot; means to use the permanent hardware address of the device. &quot;random&quot; creates a random MAC address on each connect. &quot;stable&quot; creates a hashed MAC address based on connection.stable-id and a machine dependent key. If unspecified, the value can be overwritten via global defaults, see manual of NetworkManager.conf. If still unspecified, it defaults to &quot;preserve&quot; (older versions of NetworkManager may use a different default value). On D-Bus, this field is expressed as &quot;assigned-mac-address&quot; or the deprecated &quot;cloned-mac-address&quot;."
+ nmcli-description="If specified, request that the device use this MAC address instead. This is known as MAC cloning or spoofing. Beside explicitly specifying a MAC address, the special values &quot;preserve&quot;, &quot;permanent&quot;, &quot;random&quot;, &quot;stable&quot; and &quot;stable-ssid&quot; are supported. &quot;preserve&quot; means not to touch the MAC address on activation. &quot;permanent&quot; means to use the permanent hardware address of the device. &quot;random&quot; creates a random MAC address on each connect. &quot;stable&quot; creates a hashed MAC address based on connection.stable-id and a machine dependent key. &quot;stable-ssid&quot; creates a hashed MAC address based on the SSID, the same as setting the stable-id to &quot;${NETWORK_SSID}&quot;. If unspecified, the value can be overwritten via global defaults, see manual of NetworkManager.conf. If still unspecified, it defaults to &quot;preserve&quot; (older versions of NetworkManager may use a different default value). On D-Bus, this field is expressed as &quot;assigned-mac-address&quot; or the deprecated &quot;cloned-mac-address&quot;."
format="MAC address"
- special-values="preserve, permanent, random, stable" />
+ special-values="preserve, permanent, random, stable, stable-ssid" />
<property name="generate-mac-address-mask"
nmcli-description="With &quot;cloned-mac-address&quot; setting &quot;random&quot; or &quot;stable&quot;, by default all bits of the MAC address are scrambled and a locally-administered, unicast MAC address is created. This property allows to specify that certain bits are fixed. Note that the least significant bit of the first MAC address will always be unset to create a unicast MAC address. If the property is NULL, it is eligible to be overwritten by a default connection setting. If the value is still NULL or an empty string, the default is to create a locally-administered, unicast MAC address. If the value contains one MAC address, this address is used as mask. The set bits of the mask are to be filled with the current MAC address of the device, while the unset bits are subject to randomization. Setting &quot;FE:FF:FF:00:00:00&quot; means to preserve the OUI of the current MAC address and only randomize the lower 3 bytes using the &quot;random&quot; or &quot;stable&quot; algorithm. If the value contains one additional MAC address after the mask, this address is used instead of the current MAC address to fill the bits that shall not be randomized. For example, a value of &quot;FE:FF:FF:00:00:00 68:F7:28:00:00:00&quot; will set the OUI of the MAC address to 68:F7:28, while the lower bits are randomized. A value of &quot;02:00:00:00:00:00 00:00:00:00:00:00&quot; will create a fully scrambled globally-administered, burned-in MAC address. If the value contains more than one additional MAC addresses, one of them is chosen randomly. For example, &quot;02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00&quot; will create a fully scrambled MAC address, randomly locally or globally administered."
format="string" />