diff --git a/Makefile.am b/Makefile.am index 55fd588fbb..cda851a094 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2169,6 +2169,7 @@ EXTRA_DIST += \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted2 \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-802-1X-subj-matches \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-802-1x-ttls-eapgtc \ + src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-802-1x-password-raw \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2 \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-agent \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-always \ diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index 31a72fe17f..82dc41dd55 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -4527,8 +4527,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ /* ---ifcfg-rh--- * property: password-raw - * variable: (none) - * description: The property is not handled by ifcfg-rh plugin. + * variable: IEEE_8021X_PASSWORD_RAW(+) + * description: password used for EAP, encoded as a hexadecimal string. It + * can also go to "key-" lookaside file. + * example: IEEE_8021X_PASSWORD_RAW=041c8320083aa4bf * ---end--- */ g_object_class_install_property diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 87d97173dc..be7226533e 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -2684,6 +2684,23 @@ parse_wpa_psk (shvarFile *ifcfg, return g_steal_pointer (&psk); } +static void +read_8021x_password (shvarFile *ifcfg, shvarFile *keys_ifcfg, const char *name, + char **value, NMSettingSecretFlags *flags) +{ + gs_free char *flags_key = NULL; + + *value = NULL; + flags_key = g_strdup_printf ("%s_FLAGS", name); + *flags = read_secret_flags (ifcfg, flags_key); + + if (*flags == NM_SETTING_SECRET_FLAG_NONE) { + *value = svGetValueStr_cp (ifcfg, name); + if (!*value && keys_ifcfg) + *value = svGetValueStr_cp (keys_ifcfg, name); + } +} + static gboolean eap_simple_reader (const char *eap_method, shvarFile *ifcfg, @@ -2693,6 +2710,7 @@ eap_simple_reader (const char *eap_method, GError **error) { NMSettingSecretFlags flags; + GBytes *bytes; char *value; value = svGetValueStr_cp (ifcfg, "IEEE_8021X_IDENTITY"); @@ -2703,22 +2721,29 @@ eap_simple_reader (const char *eap_method, return FALSE; } g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); - g_free (value); + nm_clear_g_free (&value); - flags = read_secret_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS"); + read_8021x_password (ifcfg, keys, "IEEE_8021X_PASSWORD", &value, &flags); g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_FLAGS, flags, NULL); + if (value) { + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL); + nm_clear_g_free (&value); + } - /* Only read the password if it's system-owned */ - if (flags == NM_SETTING_SECRET_FLAG_NONE) { - value = svGetValueStr_cp (ifcfg, "IEEE_8021X_PASSWORD"); - if (!value && keys) { - /* Try the lookaside keys file */ - value = svGetValueStr_cp (keys, "IEEE_8021X_PASSWORD"); + read_8021x_password (ifcfg, keys, "IEEE_8021X_PASSWORD_RAW", &value, &flags); + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_RAW_FLAGS, flags, NULL); + if (value) { + bytes = nm_utils_hexstr2bin (value); + if (!bytes) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid hex string '%s' in IEEE_8021X_PASSWORD_RAW.", + value); + g_free (value); + return FALSE; } - - if (value) - g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL); - g_free (value); + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_RAW, bytes, NULL); + g_bytes_unref (bytes); + nm_clear_g_free (&value); } return TRUE; diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index 9d852d7ca3..61a04b6696 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -403,11 +403,14 @@ write_8021x_setting (NMConnection *connection, NMSetting8021x *s_8021x; NMSetting8021xAuthFlags auth_flags; const char *value, *match; + gconstpointer ptr; + GBytes* bytes; char *tmp = NULL; GString *phase2_auth; GString *str; guint32 i, num; gint timeout; + gsize size; s_8021x = nm_connection_get_setting_802_1x (connection); if (!s_8021x) { @@ -443,6 +446,20 @@ write_8021x_setting (NMConnection *connection, "IEEE_8021X_PASSWORD_FLAGS", nm_setting_802_1x_get_password_flags (s_8021x)); + tmp = NULL; + bytes = nm_setting_802_1x_get_password_raw (s_8021x); + if (bytes) { + ptr = g_bytes_get_data (bytes, &size); + tmp = nm_utils_bin2hexstr (ptr, size, -1); + } + set_secret (ifcfg, + secrets, + "IEEE_8021X_PASSWORD_RAW", + tmp, + "IEEE_8021X_PASSWORD_RAW_FLAGS", + nm_setting_802_1x_get_password_raw_flags (s_8021x)); + g_free (tmp); + /* PEAP version */ value = nm_setting_802_1x_get_phase1_peapver (s_8021x); svUnsetValue (ifcfg, "IEEE_8021X_PEAP_VERSION"); diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-802-1x-password-raw b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-802-1x-password-raw new file mode 100644 index 0000000000..181ffbef81 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-802-1x-password-raw @@ -0,0 +1,13 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +NM_CONTROLLED=yes +KEY_MGMT=IEEE8021X +IEEE_8021X_EAP_METHODS=TTLS +IEEE_8021X_IDENTITY="Bill Smith" +IEEE_8021X_CA_CERT=test_ca_cert.pem +IEEE_8021X_INNER_AUTH_METHODS=EAP-GTC +IEEE_8021X_PASSWORD_RAW=0408151623420001 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 2178201af8..99b5dc9152 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -1962,6 +1962,46 @@ test_read_802_1x_ttls_eapgtc (void) g_object_unref (connection); } +static void +test_read_write_802_1x_password_raw (void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + gs_free char *keyfile = NULL; + NMSetting8021x *s_8021x; + GBytes *bytes; + gconstpointer data; + gsize size; + + /* Test that the 802-1x.password-raw is correctly read and written. */ + + connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1x-password-raw", + NULL, TYPE_ETHERNET, NULL); + + /* ===== 802.1x SETTING ===== */ + s_8021x = nm_connection_get_setting_802_1x (connection); + g_assert (s_8021x); + + bytes = nm_setting_802_1x_get_password_raw (s_8021x); + g_assert (bytes); + data = g_bytes_get_data (bytes, &size); + g_assert_cmpmem (data, size, "\x04\x08\x15\x16\x23\x42\x00\x01", 8); + + g_assert_cmpint (nm_setting_802_1x_get_password_raw_flags (s_8021x), + ==, + NM_SETTING_SECRET_FLAG_NONE); + + _writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile); + reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + keyfile = utils_get_keys_path (testfile); + g_assert (g_file_test (keyfile, G_FILE_TEST_EXISTS)); + + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); +} + static void test_read_wired_aliases_good (gconstpointer test_data) { @@ -9605,6 +9645,7 @@ int main (int argc, char **argv) g_test_add_func (TPATH "802-1x/subj-matches", test_read_write_802_1X_subj_matches); g_test_add_func (TPATH "802-1x/ttls-eapgtc", test_read_802_1x_ttls_eapgtc); + g_test_add_func (TPATH "802-1x/password_raw", test_read_write_802_1x_password_raw); g_test_add_data_func (TPATH "wired/read/aliases/good/0", GINT_TO_POINTER (0), test_read_wired_aliases_good); g_test_add_data_func (TPATH "wired/read/aliases/good/3", GINT_TO_POINTER (3), test_read_wired_aliases_good); g_test_add_func (TPATH "wired/read/aliases/bad1", test_read_wired_aliases_bad_1);