diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h index 095e20e927..74a77c4c4a 100644 --- a/src/settings/plugins/ifcfg-rh/common.h +++ b/src/settings/plugins/ifcfg-rh/common.h @@ -45,6 +45,10 @@ #define TYPE_WIRELESS "Wireless" #define TYPE_BRIDGE "Bridge" +#define SECRET_FLAG_AGENT "user" +#define SECRET_FLAG_NOT_SAVED "ask" +#define SECRET_FLAG_NOT_REQUIRED "unused" + #define IFCFG_PLUGIN_ERROR (ifcfg_plugin_error_quark ()) GQuark ifcfg_plugin_error_quark (void); diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 2821460d6c..03d2f0ec1c 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -1705,6 +1705,30 @@ read_wep_keys (shvarFile *ifcfg, return TRUE; } +static NMSettingSecretFlags +read_secret_flags (shvarFile *ifcfg, const char *flags_key) +{ + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + char *val; + + g_return_val_if_fail (flags_key != NULL, NM_SETTING_SECRET_FLAG_NONE); + g_return_val_if_fail (flags_key[0] != '\0', NM_SETTING_SECRET_FLAG_NONE); + g_return_val_if_fail (g_str_has_suffix (flags_key, "_FLAGS"), NM_SETTING_SECRET_FLAG_NONE); + + val = svGetValue (ifcfg, flags_key, FALSE); + if (val) { + if (strstr (val, SECRET_FLAG_AGENT)) + flags |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; + if (strstr (val, SECRET_FLAG_NOT_SAVED)) + flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED; + if (strstr (val, SECRET_FLAG_NOT_REQUIRED)) + flags |= NM_SETTING_SECRET_FLAG_NOT_REQUIRED; + + g_free (val); + } + return flags; +} + static NMSetting * make_wep_setting (shvarFile *ifcfg, const char *file, @@ -1715,6 +1739,7 @@ make_wep_setting (shvarFile *ifcfg, shvarFile *keys_ifcfg = NULL; int default_key_idx = 0; gboolean has_default_key = FALSE, success; + NMSettingSecretFlags key_flags; s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL); @@ -1735,19 +1760,25 @@ make_wep_setting (shvarFile *ifcfg, g_free (value); } - /* Read keys in the ifcfg file */ - if (!read_wep_keys (ifcfg, default_key_idx, s_wsec, error)) - goto error; + /* Read WEP key flags */ + key_flags = read_secret_flags (ifcfg, "WEP_KEY_FLAGS"); + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, key_flags, NULL); - /* Try to get keys from the "shadow" key file */ - keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); - if (keys_ifcfg) { - if (!read_wep_keys (keys_ifcfg, default_key_idx, s_wsec, error)) { - svCloseFile (keys_ifcfg); + /* Read keys in the ifcfg file if they are system-owned */ + if (key_flags == NM_SETTING_SECRET_FLAG_NONE) { + if (!read_wep_keys (ifcfg, default_key_idx, s_wsec, error)) goto error; + + /* Try to get keys from the "shadow" key file */ + keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); + if (keys_ifcfg) { + if (!read_wep_keys (keys_ifcfg, default_key_idx, s_wsec, error)) { + svCloseFile (keys_ifcfg); + goto error; + } + svCloseFile (keys_ifcfg); + g_assert (error == NULL || *error == NULL); } - svCloseFile (keys_ifcfg); - g_assert (error == NULL || *error == NULL); } value = svGetValue (ifcfg, "SECURITYMODE", FALSE); @@ -1771,11 +1802,15 @@ make_wep_setting (shvarFile *ifcfg, g_free (lcase); } + /* If no WEP keys were given, and the keys are not agent-owned, and no + * default WEP key index was given, then the connection is unencrypted. + */ if ( !nm_setting_wireless_security_get_wep_key (s_wsec, 0) && !nm_setting_wireless_security_get_wep_key (s_wsec, 1) && !nm_setting_wireless_security_get_wep_key (s_wsec, 2) && !nm_setting_wireless_security_get_wep_key (s_wsec, 3) - && (has_default_key == FALSE)) { + && (has_default_key == FALSE) + && (key_flags == NM_SETTING_SECRET_FLAG_NONE)) { const char *auth_alg; auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); @@ -1954,6 +1989,7 @@ eap_simple_reader (const char *eap_method, gboolean phase2, GError **error) { + NMSettingSecretFlags flags; char *value; value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE); @@ -1966,21 +2002,27 @@ eap_simple_reader (const char *eap_method, g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); g_free (value); - value = svGetValue (ifcfg, "IEEE_8021X_PASSWORD", FALSE); - if (!value && keys) { - /* Try the lookaside keys file */ - value = svGetValue (keys, "IEEE_8021X_PASSWORD", FALSE); - } + flags = read_secret_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS"); + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_FLAGS, flags, NULL); - if (!value) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Missing IEEE_8021X_PASSWORD for EAP method '%s'.", - eap_method); - return FALSE; - } + /* Only read the password if it's system-owned */ + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + value = svGetValue (ifcfg, "IEEE_8021X_PASSWORD", FALSE); + if (!value && keys) { + /* Try the lookaside keys file */ + value = svGetValue (keys, "IEEE_8021X_PASSWORD", FALSE); + } - g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL); - g_free (value); + if (!value) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IEEE_8021X_PASSWORD for EAP method '%s'.", + eap_method); + return FALSE; + } + + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL); + g_free (value); + } return TRUE; } @@ -2027,6 +2069,8 @@ eap_tls_reader (const char *eap_method, const char *pk_pw_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD": "IEEE_8021X_PRIVATE_KEY_PASSWORD"; const char *pk_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY"; const char *cli_cert_key = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT"; + const char *pk_pw_flags_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS": "IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS"; + NMSettingSecretFlags flags; value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE); if (!value) { @@ -2056,6 +2100,8 @@ eap_tls_reader (const char *eap_method, error)) goto done; } + g_free (real_path); + real_path = NULL; } else { PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: missing %s for EAP" " method '%s'; this is insecure!", @@ -2063,19 +2109,29 @@ eap_tls_reader (const char *eap_method, eap_method); } - /* Private key password */ - privkey_password = svGetValue (ifcfg, pk_pw_key, FALSE); - if (!privkey_password && keys) { - /* Try the lookaside keys file */ - privkey_password = svGetValue (keys, pk_pw_key, FALSE); - } + /* Read and set private key password flags */ + flags = read_secret_flags (ifcfg, pk_pw_flags_key); + g_object_set (s_8021x, + phase2 ? NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS : NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, + flags, + NULL); - if (!privkey_password) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Missing %s for EAP method '%s'.", - pk_pw_key, - eap_method); - goto done; + /* Read the private key password if it's system-owned */ + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + /* Private key password */ + privkey_password = svGetValue (ifcfg, pk_pw_key, FALSE); + if (!privkey_password && keys) { + /* Try the lookaside keys file */ + privkey_password = svGetValue (keys, pk_pw_key, FALSE); + } + + if (!privkey_password) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing %s for EAP method '%s'.", + pk_pw_key, + eap_method); + goto done; + } } /* The private key itself */ @@ -2088,13 +2144,12 @@ eap_tls_reader (const char *eap_method, goto done; } - g_free (real_path); real_path = get_cert_file (ifcfg->fileName, privkey); if (phase2) { if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, real_path, privkey_password, - NM_SETTING_802_1X_CK_SCHEME_PATH, + NM_SETTING_802_1X_CK_SCHEME_PATH, &privkey_format, error)) goto done; @@ -2102,11 +2157,13 @@ eap_tls_reader (const char *eap_method, if (!nm_setting_802_1x_set_private_key (s_8021x, real_path, privkey_password, - NM_SETTING_802_1X_CK_SCHEME_PATH, + NM_SETTING_802_1X_CK_SCHEME_PATH, &privkey_format, error)) goto done; } + g_free (real_path); + real_path = NULL; /* Only set the client certificate if the private key is not PKCS#12 format, * as NM (due to supplicant restrictions) requires. If the key was PKCS#12, @@ -2124,7 +2181,6 @@ eap_tls_reader (const char *eap_method, goto done; } - g_free (real_path); real_path = get_cert_file (ifcfg->fileName, client_cert); if (phase2) { if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, @@ -2141,6 +2197,8 @@ eap_tls_reader (const char *eap_method, error)) goto done; } + g_free (real_path); + real_path = NULL; } success = TRUE; @@ -2504,10 +2562,18 @@ make_wpa_setting (shvarFile *ifcfg, } if (!strcmp (value, "WPA-PSK")) { - psk = parse_wpa_psk (ifcfg, file, ssid, error); - if (psk) { - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL); - g_free (psk); + NMSettingSecretFlags psk_flags; + + psk_flags = read_secret_flags (ifcfg, "WPA_PSK_FLAGS"); + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, psk_flags, NULL); + + /* Read PSK if it's system-owned */ + if (psk_flags == NM_SETTING_SECRET_FLAG_NONE) { + psk = parse_wpa_psk (ifcfg, file, ssid, error); + if (psk) { + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL); + g_free (psk); + } } if (adhoc) @@ -2553,6 +2619,7 @@ make_leap_setting (shvarFile *ifcfg, NMSettingWirelessSecurity *wsec; shvarFile *keys_ifcfg; char *value; + NMSettingSecretFlags flags; wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); @@ -2567,18 +2634,24 @@ make_leap_setting (shvarFile *ifcfg, g_free (value); - value = svGetValue (ifcfg, "IEEE_8021X_PASSWORD", FALSE); - if (!value) { - /* Try to get keys from the "shadow" key file */ - keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); - if (keys_ifcfg) { - value = svGetValue (keys_ifcfg, "IEEE_8021X_PASSWORD", FALSE); - svCloseFile (keys_ifcfg); + flags = read_secret_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS"); + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags, NULL); + + /* Read LEAP password if it's system-owned */ + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + value = svGetValue (ifcfg, "IEEE_8021X_PASSWORD", FALSE); + if (!value) { + /* Try to get keys from the "shadow" key file */ + keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); + if (keys_ifcfg) { + value = svGetValue (keys_ifcfg, "IEEE_8021X_PASSWORD", FALSE); + svCloseFile (keys_ifcfg); + } } + if (value && strlen (value)) + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, value, NULL); + g_free (value); } - if (value && strlen (value)) - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, value, NULL); - g_free (value); value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE); if (!value || !strlen (value)) { 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 a2caf8793e..63866d9f2a 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am @@ -30,6 +30,8 @@ EXTRA_DIST = \ keys-test-wifi-wep-eap-ttls-chap \ ifcfg-test-wifi-leap \ keys-test-wifi-leap \ + ifcfg-test-wifi-leap-agent \ + ifcfg-test-wifi-leap-always-ask \ ifcfg-test-wifi-wpa-psk \ keys-test-wifi-wpa-psk \ ifcfg-test-wifi-wpa-psk-unquoted \ @@ -71,7 +73,8 @@ EXTRA_DIST = \ ifcfg-test-bridge-component \ ifcfg-test-vlan-interface \ ifcfg-test-wifi-wep-no-keys \ - ifcfg-test-permissions + ifcfg-test-permissions \ + ifcfg-test-wifi-wep-agent-keys check-local: @for f in $(EXTRA_DIST); do \ diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-agent b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-agent new file mode 100644 index 0000000000..991ba67aa9 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-agent @@ -0,0 +1,17 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +KEY_MGMT=IEEE8021X +SECURITYMODE=LEAP +IEEE_8021X_IDENTITY="Bill Smith" +IEEE_8021X_PASSWORD_FLAGS=user diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-always-ask b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-always-ask new file mode 100644 index 0000000000..5bb02b5cea --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-always-ask @@ -0,0 +1,17 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +KEY_MGMT=IEEE8021X +SECURITYMODE=LEAP +IEEE_8021X_IDENTITY="Bill Smith" +IEEE_8021X_PASSWORD_FLAGS="user ask" diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-agent-keys b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-agent-keys new file mode 100644 index 0000000000..2bc16b6e5a --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-agent-keys @@ -0,0 +1,18 @@ +ESSID="foobar" +MODE=Managed +TYPE=Wireless +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=yes +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +UUID=9c4637bd-7600-40cc-9c24-13819c5bf5dd +ONBOOT=yes +HWADDR=00:16:BB:AA:CC:DD +WEP_KEY_FLAGS=user +PEERDNS=yes +PEERROUTES=yes +IPV6_PEERDNS=yes +IPV6_PEERROUTES=yes 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 49a07c2338..2b4cb09f70 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -50,6 +50,27 @@ #include "reader.h" #include "writer.h" +#if 0 +static void +connection_diff (NMConnection *a, NMConnection *b) +{ + GHashTable *hash; + GHashTableIter iter, siter; + const char *setting_name, *key; + GHashTable *setting_hash = NULL; + + if (!nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &hash)) { + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) { + g_hash_table_iter_init (&siter, setting_hash); + while (g_hash_table_iter_next (&siter, (gpointer) &key, NULL)) + g_message (":: %s :: %s", setting_name,key); + } + g_hash_table_destroy (hash); + } +} +#endif + typedef enum { CK_CA_CERT = 0, CK_CLIENT_CERT = 1, @@ -4185,6 +4206,61 @@ test_read_wifi_leap (void) g_object_unref (connection); } +#define TEST_IFCFG_WIFI_LEAP_AGENT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-leap-agent" +#define TEST_IFCFG_WIFI_LEAP_ALWAYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-leap-always-ask" + +static void +test_read_wifi_leap_secret_flags (const char *file, NMSettingSecretFlags expected_flags) +{ + NMConnection *connection; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *expected_identity = "Bill Smith"; + gboolean success; + + connection = connection_from_file (file, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* ===== WIRELESS SETTING ===== */ + s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + g_assert (s_wifi); + + g_assert (g_strcmp0 (nm_setting_wireless_get_security (s_wifi), NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0); + + /* ===== WIRELESS SECURITY SETTING ===== */ + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + g_assert (s_wsec); + + g_assert (g_strcmp0 (nm_setting_wireless_security_get_key_mgmt (s_wsec), "ieee8021x") == 0); + g_assert (g_strcmp0 (nm_setting_wireless_security_get_auth_alg (s_wsec), "leap") == 0); + g_assert (g_strcmp0 (nm_setting_wireless_security_get_leap_username (s_wsec), expected_identity) == 0); + /* password blank as it's not system-owned */ + g_assert (nm_setting_wireless_security_get_leap_password_flags (s_wsec) == expected_flags); + g_assert (nm_setting_wireless_security_get_leap_password (s_wsec) == NULL); + + g_object_unref (connection); +} + #define TEST_IFCFG_WIFI_WPA_PSK TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk" static void @@ -5814,6 +5890,70 @@ test_read_permissions (void) g_object_unref (connection); } +#define TEST_IFCFG_WIFI_WEP_AGENT_KEYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-agent-keys" + +static void +test_read_wifi_wep_agent_keys (void) +{ + NMConnection *connection; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + NMWepKeyType key_type; + gboolean success; + NMSettingSecretFlags flags; + + connection = connection_from_file (TEST_IFCFG_WIFI_WEP_AGENT_KEYS, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert (connection != NULL); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Ensure the connection is still marked for wifi security even though + * we don't have any WEP keys because they are agent owned. + */ + + /* ===== WIRELESS SETTING ===== */ + s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + g_assert (s_wifi); + tmp = nm_setting_wireless_get_security (s_wifi); + g_assert (g_strcmp0 (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0); + + /* ===== WIRELESS SECURITY SETTING ===== */ + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + g_assert (s_wsec); + + g_assert (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0); + g_assert (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0); + + key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); + g_assert (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); + + /* We don't expect WEP key0 to be filled */ + g_assert (nm_setting_wireless_security_get_wep_key (s_wsec, 0) == NULL); + + flags = nm_setting_wireless_security_get_wep_key_flags (s_wsec); + g_assert (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED); + + g_object_unref (connection); +} + static void test_write_wired_static (void) { @@ -6772,6 +6912,203 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void) g_object_unref (reread); } +#if 0 +static GByteArray * +file_to_byte_array (const char *filename) +{ + char *contents; + GByteArray *array = NULL; + gsize length = 0; + + if (g_file_get_contents (filename, &contents, &length, NULL)) { + array = g_byte_array_sized_new (length); + if (array) { + g_byte_array_append (array, (guint8 *) contents, length); + g_assert (array->len == length); + } + g_free (contents); + } + return array; +} +#endif + +#define TEST_IFCFG_WIRED_TLS_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem" +#define TEST_IFCFG_WIRED_TLS_CLIENT_CERT TEST_IFCFG_DIR"/network-scripts/test1_key_and_cert.pem" +#define TEST_IFCFG_WIRED_TLS_PRIVATE_KEY TEST_IFCFG_DIR"/network-scripts/test1_key_and_cert.pem" + +static void +test_write_wired_8021x_tls_blobs (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + NMSetting8021x *s_8021x; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + const char *pw; + + connection = nm_connection_new (); + g_assert (connection != NULL); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired 802.1x TLS Blobs", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + g_assert (s_wired); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + /* 802.1x setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + g_assert (s_8021x); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + nm_setting_802_1x_add_eap_method (s_8021x, "tls"); + + /* CA cert */ + success = nm_setting_802_1x_set_ca_cert (s_8021x, + TEST_IFCFG_WIRED_TLS_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + if (!success) { + g_assert (error); + g_warning ("Failed to set CA certificate '%s': %s", + TEST_IFCFG_WIRED_TLS_CA_CERT, + error->message); + } + g_assert (success == TRUE); + g_assert (format == NM_SETTING_802_1X_CK_FORMAT_X509); + + /* Client cert */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_client_cert (s_8021x, + TEST_IFCFG_WIRED_TLS_CLIENT_CERT, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + if (!success) { + g_assert (error); + g_warning ("Failed to set client certificate '%s': %s", + TEST_IFCFG_WIRED_TLS_CLIENT_CERT, + error->message); + } + g_assert (success == TRUE); + g_assert (format == NM_SETTING_802_1X_CK_FORMAT_X509); + + /* Private key */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_private_key (s_8021x, + TEST_IFCFG_WIRED_TLS_PRIVATE_KEY, + "test1", + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + if (!success) { + g_assert (error); + g_warning ("Failed to set private key '%s': %s", + TEST_IFCFG_WIRED_TLS_PRIVATE_KEY, + error->message); + } + g_assert (success == TRUE); + g_assert (format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY); + + /* Verify finished connection */ + success = nm_connection_verify (connection, &error); + if (!success) { + g_assert (error); + g_warning ("Failed to verify connection: %s", error->message); + } + g_assert (success); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + if (!success) { + g_assert (error); + g_warning ("Failed to write connection: %s", error->message); + } + g_assert (success); + g_assert (testfile != NULL); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + g_assert (keyfile != NULL); + unlink (keyfile); + + g_assert (reread != NULL); + + success = nm_connection_verify (reread, &error); + if (!success) { + g_assert (error); + g_warning ("Failed to verify %s: %s", testfile, error->message); + } + g_assert (success); + + /* Ensure the reread connection's certificates and private key are paths */ + s_8021x = (NMSetting8021x *) nm_connection_get_setting (reread, NM_TYPE_SETTING_802_1X); + g_assert (s_8021x); + g_assert (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert (nm_setting_802_1x_get_client_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert (nm_setting_802_1x_get_private_key_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + + /* Ensure the private key password is still set */ + pw = nm_setting_802_1x_get_private_key_password (s_8021x); + g_assert (pw != NULL); + g_assert (g_strcmp0 (pw, "test1") == 0); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + static void test_write_wifi_open (void) { @@ -6903,7 +7240,6 @@ test_write_wifi_open (void) ASSERT (tmp != NULL, "wifi-open-write-reread", "failed to read ESSID key from %s", testfile); - g_message ("%s", tmp); ASSERT (strncmp (tmp, "\"\"", 2) != 0, "wifi-open-write-reread", "unexpected ESSID double-quote in %s", testfile); @@ -7953,6 +8289,132 @@ test_write_wifi_leap (void) g_object_unref (reread); } +static void +test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = "blahblah"; + + connection = nm_connection_new (); + g_assert (connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi LEAP Secret Flags", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + g_assert (s_wifi); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_assert (s_wsec); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "foobar22", + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + 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); + g_assert (testfile); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + g_assert_no_error (error); + + /* No key should be written out since the secret is not system owned */ + g_assert (keyfile); + g_assert (g_file_test (keyfile, G_FILE_TEST_EXISTS) == FALSE); + + g_assert (reread); + + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + g_assert (success); + + /* Remove the LEAP password from the original connection since it wont' be + * in the reread connection, as the password is not system owned. + */ + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, NULL, NULL); + 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_wifi_wpa_psk (const char *name, const char *test_name, @@ -9438,6 +9900,136 @@ test_write_permissions (void) g_object_unref (reread); } +static void +test_write_wifi_wep_agent_keys (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + const char *str_ssid = "foobarbaz"; + GByteArray *ssid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + g_assert (connection != NULL); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP Agent Owned", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + g_assert (s_wifi); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (strlen (str_ssid)); + g_byte_array_append (ssid, (guint8 *) str_ssid, strlen (str_ssid)); + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NULL); + g_byte_array_free (ssid, TRUE); + + /* Wifi security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_assert (s_wsec); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NULL); + nm_setting_wireless_security_set_wep_key (s_wsec, 0, "asdfdjaslfjasd;flasjdfl;aksdf"); + + /* Verify */ + 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); + g_assert (testfile != NULL); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_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); + + /* Remove the WEP key from the original, because it should not have been + * written out to disk as it was agent-owned. The new connection should + * not have any WEP keys set. + */ + nm_setting_wireless_security_set_wep_key (s_wsec, 0, NULL); + + /* Compare original and reread */ + success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success); + + if (route6file) + unlink (route6file); + + g_free (testfile); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + static void test_write_wired_pppoe (void) { @@ -9843,6 +10435,9 @@ int main (int argc, char **argv) test_read_wifi_wep_40_ascii (); test_read_wifi_wep_104_ascii (); test_read_wifi_leap (); + test_read_wifi_leap_secret_flags (TEST_IFCFG_WIFI_LEAP_AGENT, NM_SETTING_SECRET_FLAG_AGENT_OWNED); + test_read_wifi_leap_secret_flags (TEST_IFCFG_WIFI_LEAP_ALWAYS, + NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED); test_read_wifi_wpa_psk (); test_read_wifi_wpa_psk_unquoted (); test_read_wifi_wpa_psk_unquoted2 (); @@ -9854,6 +10449,7 @@ int main (int argc, char **argv) test_read_wired_qeth_static (); test_read_wifi_wep_no_keys (); test_read_permissions (); + test_read_wifi_wep_agent_keys (); test_write_wired_static (); test_write_wired_static_ip6_only (); @@ -9861,6 +10457,7 @@ int main (int argc, char **argv) test_read_write_static_routes_legacy (); test_write_wired_dhcp (); test_write_wired_dhcp_8021x_peap_mschapv2 (); + test_write_wired_8021x_tls_blobs (); test_write_wifi_open (); test_write_wifi_open_hex_ssid (); test_write_wifi_wep (); @@ -9869,6 +10466,9 @@ int main (int argc, char **argv) test_write_wifi_wep_40_ascii (); test_write_wifi_wep_104_ascii (); test_write_wifi_leap (); + test_write_wifi_leap_secret_flags (NM_SETTING_SECRET_FLAG_AGENT_OWNED); + test_write_wifi_leap_secret_flags (NM_SETTING_SECRET_FLAG_NOT_SAVED); + test_write_wifi_leap_secret_flags (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED); test_write_wifi_wpa_psk ("Test Write Wifi WPA PSK", "wifi-wpa-psk-write", FALSE, @@ -9905,6 +10505,7 @@ int main (int argc, char **argv) test_write_wifi_wpa_eap_ttls_mschapv2 (); test_write_wired_qeth_dhcp (); test_write_permissions (); + test_write_wifi_wep_agent_keys (); /* iSCSI / ibft */ test_read_ibft_dhcp (); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 3638459919..e135b20167 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -48,15 +48,58 @@ #define PLUGIN_WARN(pname, fmt, args...) \ { g_warning (" " pname ": " fmt, ##args); } +static void +save_secret_flags (shvarFile *ifcfg, + const char *key, + NMSettingSecretFlags flags) +{ + GString *str; + + g_return_if_fail (ifcfg != NULL); + g_return_if_fail (key != NULL); + + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + svSetValue (ifcfg, key, NULL, FALSE); + return; + } + + /* Convert flags bitfield into string representation */ + str = g_string_sized_new (20); + if (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED) + g_string_append (str, SECRET_FLAG_AGENT); + + if (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) { + if (str->len) + g_string_append_c (str, ' '); + g_string_append (str, SECRET_FLAG_NOT_SAVED); + } + + if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) { + if (str->len) + g_string_append_c (str, ' '); + g_string_append (str, SECRET_FLAG_NOT_REQUIRED); + } + + svSetValue (ifcfg, key, str->len ? str->str : NULL, FALSE); + g_string_free (str, TRUE); +} + static void set_secret (shvarFile *ifcfg, const char *key, const char *value, + const char *flags_key, NMSettingSecretFlags flags, gboolean verbatim) { shvarFile *keyfile; + /* Clear the secret from the ifcfg and the associated "keys" file */ + svSetValue (ifcfg, key, NULL, FALSE); + + /* Save secret flags */ + save_secret_flags (ifcfg, flags_key, flags); + keyfile = utils_get_keys_ifcfg (ifcfg->fileName, TRUE); if (!keyfile) { PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: could not create key file for '%s'", @@ -64,8 +107,7 @@ set_secret (shvarFile *ifcfg, goto error; } - /* Clear the secret from the ifcfg and the associated "keys" file */ - svSetValue (ifcfg, key, NULL, FALSE); + /* Clear the secret from the associated "keys" file */ svSetValue (keyfile, key, NULL, FALSE); /* Only write the secret if it's system owned and supposed to be saved */ @@ -155,15 +197,11 @@ out: return success; } -typedef NMSetting8021xCKScheme (*SchemeFunc)(NMSetting8021x *setting); -typedef const char * (*PathFunc) (NMSetting8021x *setting); -typedef const GByteArray * (*BlobFunc) (NMSetting8021x *setting); - typedef struct ObjectType { const char *setting_key; - SchemeFunc scheme_func; - PathFunc path_func; - BlobFunc blob_func; + NMSetting8021xCKScheme (*scheme_func)(NMSetting8021x *setting); + const char * (*path_func) (NMSetting8021x *setting); + const GByteArray * (*blob_func) (NMSetting8021x *setting); const char *ifcfg_key; const char *suffix; } ObjectType; @@ -243,7 +281,6 @@ static const ObjectType phase2_p12_type = { static gboolean write_object (NMSetting8021x *s_8021x, shvarFile *ifcfg, - const GByteArray *override_data, const ObjectType *objtype, GError **error) { @@ -254,23 +291,16 @@ write_object (NMSetting8021x *s_8021x, g_return_val_if_fail (ifcfg != NULL, FALSE); g_return_val_if_fail (objtype != NULL, FALSE); - if (override_data) { - /* if given explicit data to save, always use that instead of asking - * the setting what to do. - */ - blob = override_data; - } else { - scheme = (*(objtype->scheme_func))(s_8021x); - switch (scheme) { - case NM_SETTING_802_1X_CK_SCHEME_BLOB: - blob = (*(objtype->blob_func))(s_8021x); - break; - case NM_SETTING_802_1X_CK_SCHEME_PATH: - path = (*(objtype->path_func))(s_8021x); - break; - default: - break; - } + scheme = (*(objtype->scheme_func))(s_8021x); + switch (scheme) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + blob = (*(objtype->blob_func))(s_8021x); + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = (*(objtype->path_func))(s_8021x); + break; + default: + break; } /* If certificate/private key wasn't sent, the connection may no longer be @@ -303,7 +333,7 @@ write_object (NMSetting8021x *s_8021x, return TRUE; } - /* If it's raw certificate data, write the cert data out to the standard file */ + /* If it's raw certificate data, write the data out to the standard file */ if (blob) { gboolean success; char *new_file; @@ -344,101 +374,72 @@ write_8021x_certs (NMSetting8021x *s_8021x, shvarFile *ifcfg, GError **error) { - GByteArray *enc_key = NULL; const char *password = NULL; - char *generated_pw = NULL; gboolean success = FALSE, is_pkcs12 = FALSE; const ObjectType *otype = NULL; - const GByteArray *blob = NULL; NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; /* CA certificate */ - if (phase2) - otype = &phase2_ca_type; - else - otype = &ca_type; - - if (!write_object (s_8021x, ifcfg, NULL, otype, error)) + if (!write_object (s_8021x, ifcfg, phase2 ? &phase2_ca_type : &ca_type, error)) return FALSE; /* Private key */ if (phase2) { - if (nm_setting_802_1x_get_phase2_private_key_scheme (s_8021x) != NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { - if (nm_setting_802_1x_get_phase2_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) - is_pkcs12 = TRUE; + otype = &phase2_pk_type; + if (nm_setting_802_1x_get_phase2_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + otype = &phase2_p12_type; + is_pkcs12 = TRUE; } password = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); flags = nm_setting_802_1x_get_phase2_private_key_password_flags (s_8021x); } else { - if (nm_setting_802_1x_get_private_key_scheme (s_8021x) != NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { - if (nm_setting_802_1x_get_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) - is_pkcs12 = TRUE; + otype = &pk_type; + if (nm_setting_802_1x_get_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + otype = &p12_type; + is_pkcs12 = TRUE; } password = nm_setting_802_1x_get_private_key_password (s_8021x); flags = nm_setting_802_1x_get_private_key_password_flags (s_8021x); } - if (is_pkcs12) - otype = phase2 ? &phase2_p12_type : &p12_type; - else - otype = phase2 ? &phase2_pk_type : &pk_type; - - if ((*(otype->scheme_func))(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_BLOB) - blob = (*(otype->blob_func))(s_8021x); - - /* Only do the private key re-encrypt dance if we got the raw key data, which - * by definition will be unencrypted. If we're given a direct path to the - * private key file, it'll be encrypted, so we don't need to re-encrypt. - */ - if (blob && !is_pkcs12) { - /* Encrypt the unencrypted private key with the fake password */ - enc_key = nm_utils_rsa_key_encrypt (blob, password, &generated_pw, error); - if (!enc_key) - goto out; - - if (generated_pw) { - password = generated_pw; - flags = NM_SETTING_SECRET_FLAG_NONE; - } - } - /* Save the private key */ - if (!write_object (s_8021x, ifcfg, enc_key ? enc_key : blob, otype, error)) + if (!write_object (s_8021x, ifcfg, otype, error)) goto out; /* Private key password */ - if (phase2) - set_secret (ifcfg, "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD", password, flags, FALSE); - else - set_secret (ifcfg, "IEEE_8021X_PRIVATE_KEY_PASSWORD", password, flags, FALSE); + if (phase2) { + set_secret (ifcfg, + "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD", + password, + "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS", + flags, + FALSE); + } else { + set_secret (ifcfg, + "IEEE_8021X_PRIVATE_KEY_PASSWORD", + password, + "IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS", + flags, + FALSE); + } /* Client certificate */ if (is_pkcs12) { + /* Don't need a client certificate with PKCS#12 since the file is both + * the client certificate and the private key in one file. + */ svSetValue (ifcfg, phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT", NULL, FALSE); } else { - if (phase2) - otype = &phase2_client_type; - else - otype = &client_type; - /* Save the client certificate */ - if (!write_object (s_8021x, ifcfg, NULL, otype, error)) + if (!write_object (s_8021x, ifcfg, phase2 ? &phase2_client_type : &client_type, error)) goto out; } success = TRUE; out: - if (generated_pw) { - memset (generated_pw, 0, strlen (generated_pw)); - g_free (generated_pw); - } - if (enc_key) { - memset (enc_key->data, 0, enc_key->len); - g_byte_array_free (enc_key, TRUE); - } return success; } @@ -486,6 +487,7 @@ write_8021x_setting (NMConnection *connection, set_secret (ifcfg, "IEEE_8021X_PASSWORD", nm_setting_802_1x_get_password (s_8021x), + "IEEE_8021X_PASSWORD_FLAGS", nm_setting_802_1x_get_password_flags (s_8021x), FALSE); @@ -590,8 +592,10 @@ write_wireless_security_setting (NMConnection *connection, svSetValue (ifcfg, "IEEE_8021X_IDENTITY", nm_setting_wireless_security_get_leap_username (s_wsec), FALSE); - set_secret (ifcfg, "IEEE_8021X_PASSWORD", + set_secret (ifcfg, + "IEEE_8021X_PASSWORD", nm_setting_wireless_security_get_leap_password (s_wsec), + "IEEE_8021X_PASSWORD_FLAGS", nm_setting_wireless_security_get_leap_password_flags (s_wsec), FALSE); *no_8021x = TRUE; @@ -601,16 +605,16 @@ write_wireless_security_setting (NMConnection *connection, /* WEP keys */ /* Clear any default key */ - set_secret (ifcfg, "KEY", NULL, NM_SETTING_SECRET_FLAG_NONE, FALSE); + set_secret (ifcfg, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE); /* Clear existing keys */ for (i = 0; i < 4; i++) { tmp = g_strdup_printf ("KEY_PASSPHRASE%d", i + 1); - set_secret (ifcfg, tmp, NULL, NM_SETTING_SECRET_FLAG_NONE, FALSE); + 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, NM_SETTING_SECRET_FLAG_NONE, FALSE); + set_secret (ifcfg, tmp, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE); g_free (tmp); } @@ -645,7 +649,12 @@ write_wireless_security_setting (NMConnection *connection, } } - set_secret (ifcfg, tmp, key, nm_setting_wireless_security_get_wep_key_flags (s_wsec), FALSE); + set_secret (ifcfg, + tmp, + key, + "WEP_KEY_FLAGS", + nm_setting_wireless_security_get_wep_key_flags (s_wsec), + FALSE); g_free (tmp); g_free (ascii_key); } @@ -711,12 +720,19 @@ write_wireless_security_setting (NMConnection *connection, set_secret (ifcfg, "WPA_PSK", quoted ? quoted->str : psk, + "WPA_PSK_FLAGS", nm_setting_wireless_security_get_psk_flags (s_wsec), TRUE); if (quoted) g_string_free (quoted, TRUE); - } else - set_secret (ifcfg, "WPA_PSK", NULL, NM_SETTING_SECRET_FLAG_NONE, FALSE); + } else { + set_secret (ifcfg, + "WPA_PSK", + NULL, + "WPA_PSK_FLAGS", + NM_SETTING_SECRET_FLAG_NONE, + FALSE); + } return TRUE; }