From 6a46dfca267f8bdb4ffc6539e168a39702bbb7c2 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 8 Oct 2015 13:32:36 +0200 Subject: [PATCH] ifcfg-rh: add support for NMSettingWireless:mac-address-randomization Old init-scripts that did not yet understand this key will have mac-address-randomization explicitly disabled. This is to ensure that old connections don't change behavior. Thus, the writer must always write the value explicitly. Downside is, if somebody creates a quick ifcfg-file, the feature is disabled by default. --- libnm-core/nm-setting-wireless.c | 9 ++ src/settings/plugins/ifcfg-rh/reader.c | 22 +++ .../tests/network-scripts/Makefile.am | 4 + .../ifcfg-test-wifi-mac-random-always | 7 + .../ifcfg-test-wifi-mac-random-default | 6 + .../ifcfg-test-wifi-mac-random-missing | 6 + .../ifcfg-test-wifi-mac-random-never | 6 + .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 146 ++++++++++++++++++ src/settings/plugins/ifcfg-rh/writer.c | 16 +- 9 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-always create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-default create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-missing create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-never diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index 9931521825..2a14829314 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -1398,6 +1398,15 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) * * Since: 1.2 **/ + /* ---ifcfg-rh--- + * property: mac-address-randomization + * variable: MAC_ADDRESS_RANDOMIZATION(+) + * values: 0 (default), (1) never, (2) always + * default: 1 + * description: Enables or disables Wi-Fi MAC address randomization. + * example: MAC_ADDRESS_RANDOMIZATION=2 + * ---end--- + */ g_object_class_install_property (object_class, PROP_MAC_ADDRESS_RANDOMIZATION, g_param_spec_uint (NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, "", "", diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 6ca9b92b09..5dee64d146 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -3314,6 +3314,7 @@ make_wireless_setting (shvarFile *ifcfg, NMSettingWireless *s_wireless; char *value = NULL; gint64 chan = 0; + NMSettingMacRandomization mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER; s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); @@ -3496,6 +3497,27 @@ make_wireless_setting (shvarFile *ifcfg, svGetValueBoolean (ifcfg, "POWERSAVE", FALSE) ? 1 : 0, NULL); + value = svGetValueFull (ifcfg, "MAC_ADDRESS_RANDOMIZATION", FALSE); + if (value) { + if (strcmp (value, "default") == 0) + mac_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; + else if (strcmp (value, "never") == 0) + mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER; + else if (strcmp (value, "always") == 0) + mac_randomization = NM_SETTING_MAC_RANDOMIZATION_ALWAYS; + else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid MAC_ADDRESS_RANDOMIZATION value '%s'", value); + goto error; + } + } else + mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER; + + g_object_set (s_wireless, + NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, + mac_randomization, + NULL); + return NM_SETTING (s_wireless); error: diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am index 6d1d21b444..a1b414fd6c 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am @@ -67,6 +67,10 @@ EXTRA_DIST = \ ifcfg-test-wifi-band-a \ ifcfg-test-wifi-band-a-channel-mismatch \ ifcfg-test-wifi-band-bg-channel-mismatch \ + ifcfg-test-wifi-mac-random-always \ + ifcfg-test-wifi-mac-random-never \ + ifcfg-test-wifi-mac-random-default \ + ifcfg-test-wifi-mac-random-missing \ test_ca_cert.pem \ test1_key_and_cert.pem \ ifcfg-test-ibft \ diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-always b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-always new file mode 100644 index 0000000000..9dcb5bf851 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-always @@ -0,0 +1,7 @@ +TYPE=Wireless +DEVICE=eth2 +BOOTPROTO=dhcp +ESSID=blahblah +ONBOOT=yes +MAC_ADDRESS_RANDOMIZATION=always + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-default b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-default new file mode 100644 index 0000000000..3709c493c4 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-default @@ -0,0 +1,6 @@ +TYPE=Wireless +DEVICE=eth2 +BOOTPROTO=dhcp +ESSID=blahblah +ONBOOT=yes +MAC_ADDRESS_RANDOMIZATION=default diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-missing b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-missing new file mode 100644 index 0000000000..f896eb0f99 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-missing @@ -0,0 +1,6 @@ +TYPE=Wireless +DEVICE=eth2 +BOOTPROTO=dhcp +ESSID=blahblah +ONBOOT=yes + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-never b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-never new file mode 100644 index 0000000000..aa12d74938 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-mac-random-never @@ -0,0 +1,6 @@ +TYPE=Wireless +DEVICE=eth2 +BOOTPROTO=dhcp +ESSID=blahblah +ONBOOT=yes +MAC_ADDRESS_RANDOMIZATION=never diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 2b317e8ee2..b7a887d095 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -58,6 +58,12 @@ #include "nm-test-utils.h" +typedef struct { + const char *name; + const NMSettingMacRandomization value; + const char *write_expected; +} WifiMacRandomData; + #if 0 static void connection_diff (NMConnection *a, NMConnection *b) @@ -5465,6 +5471,117 @@ test_write_wifi_hidden (void) g_object_unref (reread); } +static void +test_read_wifi_mac_random (gconstpointer user_data) +{ + const WifiMacRandomData *test_data = user_data; + NMConnection *connection; + NMSettingWireless *s_wifi; + gboolean success; + GError *error = NULL; + char *path; + + path = g_strdup_printf (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-mac-random-%s", test_data->name); + connection = connection_from_file_test (path, NULL, TYPE_WIRELESS, NULL, &error); + g_free (path); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + s_wifi = nm_connection_get_setting_wireless (connection); + g_assert (s_wifi); + g_assert_cmpint (nm_setting_wireless_get_mac_address_randomization (s_wifi), ==, test_data->value); + + g_object_unref (connection); +} + +static void +test_write_wifi_mac_random (gconstpointer user_data) +{ + const WifiMacRandomData *test_data = user_data; + NMConnection *connection, *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + char *uuid, *testfile = NULL, *val; + gboolean success; + GError *error = NULL; + shvarFile *f; + GBytes *ssid; + const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; + + connection = nm_simple_connection_new (); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + val = g_strdup_printf ("Test Write WiFi MAC %s", test_data->name); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, val, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + g_free (val); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, test_data->value, + NULL); + g_bytes_unref (ssid); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + g_assert_no_error (error); + g_assert (success); + + f = svOpenFile (testfile, &error); + g_assert_no_error (error); + g_assert (f); + + /* re-read the file to check that what key was written. */ + val = svGetValue (f, "MAC_ADDRESS_RANDOMIZATION", FALSE); + g_assert_cmpstr (val, ==, test_data->write_expected); + g_free (val); + svCloseFile (f); + + /* reread will be normalized, so we must normalize connection too. */ + nm_connection_normalize (connection, NULL, NULL, NULL); + + /* re-read the connection for comparison */ + reread = connection_from_file_test (testfile, NULL, TYPE_WIRELESS, NULL, &error); + unlink (testfile); + g_assert_no_error (error); + g_assert (reread); + + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + g_assert (success); + + g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + static void test_write_wired_wake_on_lan (void) { @@ -13061,6 +13178,35 @@ int main (int argc, char **argv) g_test_add_func (TPATH "wifi/read-band-a-channel-mismatch", test_read_wifi_band_a_channel_mismatch); g_test_add_func (TPATH "wifi/read-band-bg-channel-mismatch", test_read_wifi_band_bg_channel_mismatch); g_test_add_func (TPATH "wifi/read-hidden", test_read_wifi_hidden); + + { + static const WifiMacRandomData test_wifi_mac_random[] = { + { "always", NM_SETTING_MAC_RANDOMIZATION_ALWAYS, "always" }, + { "never", NM_SETTING_MAC_RANDOMIZATION_NEVER, "never" }, + { "default", NM_SETTING_MAC_RANDOMIZATION_DEFAULT, "default" }, + { "missing", NM_SETTING_MAC_RANDOMIZATION_NEVER, "never" }, + }; + int i; + + for (i = 0; i < G_N_ELEMENTS (test_wifi_mac_random); i++) { + char *tpath; + + tpath = g_strdup_printf (TPATH "wifi/read-mac-random-%s", test_wifi_mac_random[i].name); + g_test_add_data_func_full (tpath, + g_memdup (&test_wifi_mac_random[i], sizeof (test_wifi_mac_random[i])), + test_read_wifi_mac_random, + g_free); + g_free (tpath); + + tpath = g_strdup_printf (TPATH "wifi/write-mac-random-%s", test_wifi_mac_random[i].name); + g_test_add_data_func_full (tpath, + g_memdup (&test_wifi_mac_random[i], sizeof (test_wifi_mac_random[i])), + test_write_wifi_mac_random, + g_free); + g_free (tpath); + } + } + test_read_wired_qeth_static (); test_read_wired_ctc_static (); test_read_wifi_wep_no_keys (); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index aaf0ebe906..1ea932ee23 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -967,7 +967,7 @@ write_wireless_setting (NMConnection *connection, tmp = g_strdup_printf ("KEY_PASSPHRASE%d", i + 1); set_secret (ifcfg, tmp, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE); g_free (tmp); - + tmp = g_strdup_printf ("KEY%d", i + 1); set_secret (ifcfg, tmp, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE); g_free (tmp); @@ -989,6 +989,20 @@ write_wireless_setting (NMConnection *connection, svSetValue (ifcfg, "SSID_HIDDEN", nm_setting_wireless_get_hidden (s_wireless) ? "yes" : NULL, TRUE); svSetValue (ifcfg, "POWERSAVE", nm_setting_wireless_get_powersave (s_wireless) ? "yes" : NULL, TRUE); + svSetValue (ifcfg, "MAC_ADDRESS_RANDOMIZATION", NULL, TRUE); + switch (nm_setting_wireless_get_mac_address_randomization (s_wireless)) { + case NM_SETTING_MAC_RANDOMIZATION_DEFAULT: + svSetValue (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "default", TRUE); + break; + case NM_SETTING_MAC_RANDOMIZATION_ALWAYS: + svSetValue (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "always", TRUE); + break; + default: + case NM_SETTING_MAC_RANDOMIZATION_NEVER: + svSetValue (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "never", TRUE); + break; + } + svSetValue (ifcfg, "TYPE", TYPE_WIRELESS, FALSE); return TRUE;