diff --git a/CONTRIBUTING b/CONTRIBUTING
index baf6d25905..47f93700d0 100644
--- a/CONTRIBUTING
+++ b/CONTRIBUTING
@@ -17,3 +17,25 @@ with #ifdef MY_DEFINE / #endif in the code.
...
}
+* Keep a space between the function name and the opening '('.
+ GOOD: g_strdup (x)
+ BAD: g_strdup(x)
+
+* C-style comments, except for FIXMEs.
+ GOOD: f(x); /* comment */
+ BAD: f(x); // comment
+
+ GOOD: // FIXME: juice the gooblygok
+ BAD: /* FIXME: juice the gooblygok */
+
+* Keep assignments in the variable declaration area pretty short.
+ GOOD: MyObject *object;
+ BAD: MyObject *object = complex_and_long_init_function(arg1, arg2, arg3);
+
+* 80-cols is a guideline, don't make the code uncomfortable in order to fit in
+ less than 80 cols.
+
+* Constants are CAPS_WITH_UNDERSCORES and use the preprocessor.
+ GOOD: #define MY_CONSTANT 42
+ BAD: static const unsigned myConstant = 42;
+
diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml
index a93ee5897b..02e8bcf51a 100644
--- a/introspection/nm-manager.xml
+++ b/introspection/nm-manager.xml
@@ -39,12 +39,19 @@
- The device to be activated.
+ The object path of device to be activated for physical connections. This parameter is ignored for VPN connections, because the specific_object (if provided) specifies the device to use.
- The path of a device-type-specific object this activation should use, for example a WiFi access point.
+ The path of a connection-type-specific object this activation should use.
+ This parameter is currently ignored for wired and mobile broadband connections,
+ and the value of "/" should be used (ie, no specific object). For WiFi
+ connections, pass the object path of a specific AP from the card's scan
+ list, or "/" to pick and AP automatically. For VPN connections, pass
+ the object path of an ActiveConnection object that should serve as the
+ "base" connection (to which the VPN connections lifetime will be tied),
+ or pass "/" and NM will automatically use the current default device.
diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c
index 7e9bc2fa0b..94bda26e56 100644
--- a/libnm-glib/nm-object.c
+++ b/libnm-glib/nm-object.c
@@ -83,7 +83,7 @@ constructor (GType type,
priv = NM_OBJECT_GET_PRIVATE (object);
if (priv->connection == NULL || priv->path == NULL) {
- g_warning ("Connection or path not received.");
+ g_warning ("%s: bus connection and path required.", __func__);
g_object_unref (object);
return NULL;
}
@@ -331,7 +331,10 @@ handle_property_changed (gpointer key, gpointer data, gpointer user_data)
prop_name = wincaps_to_dash ((char *) key);
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (self)), prop_name);
if (!pspec) {
- g_warning ("Property '%s' change detected but couldn't be found on the object.", prop_name);
+ g_warning ("%s: property '%s' changed but wasn't defined by object type %s.",
+ __func__,
+ prop_name,
+ G_OBJECT_TYPE_NAME (self));
goto out;
}
@@ -350,8 +353,12 @@ handle_property_changed (gpointer key, gpointer data, gpointer user_data)
#if DEBUG
g_warning ("Property '%s' unhandled.", prop_name);
#endif
- } else if (!success)
- g_warning ("Property '%s' could not be set due to errors.", prop_name);
+ } else if (!success) {
+ g_warning ("%s: failed to update property '%s' of object type %s.",
+ __func__,
+ prop_name,
+ G_OBJECT_TYPE_NAME (self));
+ }
out:
g_free (prop_name);
@@ -486,11 +493,17 @@ _nm_object_get_property (NMObject *object,
G_TYPE_INVALID,
G_TYPE_VALUE, value,
G_TYPE_INVALID)) {
- g_warning ("%s: Error getting '%s' for %s: %s\n",
- __func__,
- prop_name,
- nm_object_get_path (object),
- err->message);
+ /* Don't warn about D-Bus no reply/timeout errors; it's mostly noise and
+ * happens for example when NM quits and the applet is still running.
+ */
+ if (!(err->domain == DBUS_GERROR && err->code == DBUS_GERROR_NO_REPLY)) {
+ g_warning ("%s: Error getting '%s' for %s: (%d) %s\n",
+ __func__,
+ prop_name,
+ nm_object_get_path (object),
+ err->code,
+ err->message);
+ }
g_error_free (err);
return FALSE;
}
diff --git a/libnm-glib/nm-remote-settings-system.c b/libnm-glib/nm-remote-settings-system.c
index 02aaff4cde..4e30fda800 100644
--- a/libnm-glib/nm-remote-settings-system.c
+++ b/libnm-glib/nm-remote-settings-system.c
@@ -90,10 +90,15 @@ get_all_cb (DBusGProxy *proxy,
if (!dbus_g_proxy_end_call (proxy, call, &error,
DBUS_TYPE_G_MAP_OF_VARIANT, &props,
G_TYPE_INVALID)) {
- g_warning ("%s: couldn't retrieve system settings properties: (%d) %s.",
- __func__,
- error ? error->code : -1,
- (error && error->message) ? error->message : "(unknown)");
+ /* Don't warn when the call times out because the settings service can't
+ * be activated or whatever.
+ */
+ if (!(error->domain == DBUS_GERROR && error->code == DBUS_GERROR_NO_REPLY)) {
+ g_warning ("%s: couldn't retrieve system settings properties: (%d) %s.",
+ __func__,
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "(unknown)");
+ }
g_clear_error (&error);
return;
}
diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c
index d7be8fbb04..55ae0f3a14 100644
--- a/libnm-glib/nm-remote-settings.c
+++ b/libnm-glib/nm-remote-settings.c
@@ -268,10 +268,20 @@ remove_connections (gpointer user_data)
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
GHashTableIter iter;
gpointer value;
+ GSList *list = NULL, *list_iter;
+ /* Build up the list of connections; we can't emit "removed" during hash
+ * table iteration because emission of the "removed" signal may trigger code
+ * that explicitly removes the the connection from the hash table somewhere
+ * else.
+ */
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, &value))
- g_signal_emit_by_name (NM_REMOTE_CONNECTION (value), "removed");
+ list = g_slist_prepend (list, NM_REMOTE_CONNECTION (value));
+
+ for (list_iter = list; list_iter; list_iter = g_slist_next (list_iter))
+ g_signal_emit_by_name (NM_REMOTE_CONNECTION (list_iter->data), "removed");
+ g_slist_free (list);
g_hash_table_remove_all (priv->connections);
return FALSE;
diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c
index d52bd1e3e2..a137e8704a 100644
--- a/libnm-util/nm-setting-8021x.c
+++ b/libnm-util/nm-setting-8021x.c
@@ -2173,27 +2173,39 @@ need_secrets_sim (NMSetting8021x *self,
}
static gboolean
-need_private_key_password (GByteArray *key, const char *password)
+need_private_key_password (const GByteArray *blob,
+ const char *path,
+ const char *password)
{
- GError *error = NULL;
- gboolean needed = TRUE;
-
- /* See if a private key password is needed, which basically is whether
- * or not the private key is a PKCS#12 file or not, since PKCS#1 files
- * are decrypted by the settings service.
+ /* Private key password is only un-needed if the private key scheme is BLOB,
+ * because BLOB keys are decrypted by the settings service. A private key
+ * password is required if the private key is PKCS#12 format, or if the
+ * private key scheme is PATH.
*/
- if (!crypto_is_pkcs12_data (key))
- return FALSE;
+ if (path) {
+ GByteArray *tmp;
+ NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN;
+ NMCryptoFileFormat key_format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
- if (crypto_verify_pkcs12 (key, password, &error))
- return FALSE; /* pkcs#12 validation successful */
+ /* check the password */
+ tmp = crypto_get_private_key (path, password, &key_type, &key_format, NULL);
+ if (tmp) {
+ /* Decrypt/verify successful; password must be OK */
+ g_byte_array_free (tmp, TRUE);
+ return FALSE;
+ }
+ } else if (blob) {
+ /* Non-PKCS#12 blob-scheme keys are already decrypted by their settings
+ * service, thus if the private key is not PKCS#12 format, a new password
+ * is not required. If the PKCS#12 key can be decrypted with the given
+ * password, then we don't need a new password either.
+ */
+ if (!crypto_is_pkcs12_data (blob) || crypto_verify_pkcs12 (blob, password, NULL))
+ return FALSE;
+ } else
+ g_warning ("%s: unknown private key password scheme", __func__);
- /* If the error was a decryption error then a password is needed */
- if (!error || g_error_matches (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED))
- needed = TRUE;
-
- g_clear_error (&error);
- return needed;
+ return TRUE;
}
static void
@@ -2202,16 +2214,47 @@ need_secrets_tls (NMSetting8021x *self,
gboolean phase2)
{
NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
+ NMSetting8021xCKScheme scheme;
+ const GByteArray *blob = NULL;
+ const char *path = NULL;
if (phase2) {
- if (!priv->phase2_private_key || !priv->phase2_private_key->len)
+ if (!priv->phase2_private_key || !priv->phase2_private_key->len) {
g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
- else if (need_private_key_password (priv->phase2_private_key, priv->phase2_private_key_password))
+ return;
+ }
+
+ scheme = nm_setting_802_1x_get_phase2_private_key_scheme (self);
+ if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
+ path = nm_setting_802_1x_get_phase2_private_key_path (self);
+ else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
+ blob = nm_setting_802_1x_get_phase2_private_key_blob (self);
+ else {
+ g_warning ("%s: unknown phase2 private key scheme %d", __func__, scheme);
+ g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
+ return;
+ }
+
+ if (need_private_key_password (blob, path, priv->phase2_private_key_password))
g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD);
} else {
- if (!priv->private_key || !priv->private_key->len)
+ if (!priv->private_key || !priv->private_key->len) {
g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY);
- else if (need_private_key_password (priv->private_key, priv->private_key_password))
+ return;
+ }
+
+ scheme = nm_setting_802_1x_get_private_key_scheme (self);
+ if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
+ path = nm_setting_802_1x_get_private_key_path (self);
+ else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
+ blob = nm_setting_802_1x_get_private_key_blob (self);
+ else {
+ g_warning ("%s: unknown private key scheme %d", __func__, scheme);
+ g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY);
+ return;
+ }
+
+ if (need_private_key_password (blob, path, priv->private_key_password))
g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
}
}
@@ -2439,7 +2482,7 @@ need_secrets_phase2 (NMSetting8021x *self,
for (i = 0; eap_methods_table[i].method; i++) {
if (eap_methods_table[i].ns_func == NULL)
continue;
- if (strcmp (eap_methods_table[i].method, method)) {
+ if (!strcmp (eap_methods_table[i].method, method)) {
(*eap_methods_table[i].ns_func) (self, secrets, TRUE);
break;
}
diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c
index 309c097933..f13ac872d9 100644
--- a/libnm-util/nm-setting-gsm.c
+++ b/libnm-util/nm-setting-gsm.c
@@ -395,9 +395,11 @@ get_property (GObject *object, guint prop_id,
break;
case PROP_PUK:
/* deprecated */
+ g_value_set_string (value, NULL);
break;
case PROP_BAND:
/* deprecated */
+ g_value_set_int (value, -1);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
diff --git a/libnm-util/tests/Makefile.am b/libnm-util/tests/Makefile.am
index 78e94c2593..d0e3477df3 100644
--- a/libnm-util/tests/Makefile.am
+++ b/libnm-util/tests/Makefile.am
@@ -4,7 +4,7 @@ INCLUDES = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-util
-noinst_PROGRAMS = test-settings-defaults test-crypto
+noinst_PROGRAMS = test-settings-defaults test-crypto test-need-secrets
test_settings_defaults_SOURCES = \
test-settings-defaults.c
@@ -29,11 +29,24 @@ test_crypto_LDADD = \
$(top_builddir)/libnm-util/libnm-util.la \
$(GLIB_LIBS)
+test_need_secrets_SOURCES = \
+ test-need-secrets.c
+
+test_need_secrets_CPPFLAGS = \
+ -DTEST_CERT_DIR=\"$(top_srcdir)/libnm-util/tests/certs/\" \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS)
+
+test_need_secrets_LDADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(GLIB_LIBS) \
+ $(DBUS_LIBS)
if WITH_TESTS
-check-local: test-settings-defaults test-crypto
+check-local: test-settings-defaults test-crypto test-need-secrets
$(abs_builddir)/test-settings-defaults
+ $(abs_builddir)/test-need-secrets
# Cert with 8 bytes of tail padding
$(abs_builddir)/test-crypto \
diff --git a/libnm-util/tests/test-need-secrets.c b/libnm-util/tests/test-need-secrets.c
new file mode 100644
index 0000000000..517e2e01d7
--- /dev/null
+++ b/libnm-util/tests/test-need-secrets.c
@@ -0,0 +1,566 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 - 2009 Red Hat, Inc.
+ *
+ */
+
+#include
+#include
+#include
+
+#include "nm-test-helpers.h"
+#include
+
+#include "nm-setting-connection.h"
+#include "nm-setting-wired.h"
+#include "nm-setting-8021x.h"
+#include "nm-setting-ip4-config.h"
+#include "nm-setting-wireless-security.h"
+#include "nm-setting-cdma.h"
+#include "nm-setting-gsm.h"
+#include "nm-setting-ppp.h"
+#include "nm-setting-pppoe.h"
+#include "nm-setting-vpn.h"
+
+
+#define TEST_NEED_SECRETS_EAP_TLS_CA_CERT TEST_CERT_DIR "/test_ca_cert.pem"
+#define TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT TEST_CERT_DIR "/test_key_and_cert.pem"
+#define TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY TEST_CERT_DIR "/test_key_and_cert.pem"
+
+static gboolean
+find_hints_item (GPtrArray *hints, const char *item)
+{
+ int i;
+
+ for (i = 0; i < hints->len; i++) {
+ if (!strcmp (item, (const char *) g_ptr_array_index (hints, i)))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static NMConnection *
+make_tls_connection (const char *detail, NMSetting8021xCKScheme scheme)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSetting8021x *s_8021x;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ detail, "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ detail, "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Need TLS Secrets",
+ 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 ();
+ ASSERT (s_wired != NULL,
+ detail, "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ /* Wireless security setting */
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ ASSERT (s_8021x != NULL,
+ detail, "failed to allocate new %s setting",
+ NM_SETTING_802_1X_SETTING_NAME);
+ 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");
+
+ success = nm_setting_802_1x_set_ca_cert (s_8021x,
+ TEST_NEED_SECRETS_EAP_TLS_CA_CERT,
+ scheme,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ detail, "failed to set CA certificate '%s': %s",
+ TEST_NEED_SECRETS_EAP_TLS_CA_CERT, error->message);
+
+ success = nm_setting_802_1x_set_client_cert (s_8021x,
+ TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT,
+ scheme,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ detail, "failed to set client certificate '%s': %s",
+ TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, error->message);
+
+ success = nm_setting_802_1x_set_private_key (s_8021x,
+ TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY,
+ "test",
+ scheme,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ detail, "failed to set private key '%s': %s",
+ TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, error->message);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ detail, "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ 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);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ detail, "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ return connection;
+}
+
+static void
+test_need_tls_secrets_path (void)
+{
+ NMConnection *connection;
+ const char *setting_name;
+ GPtrArray *hints = NULL;
+ NMSetting8021x *s_8021x;
+
+ connection = make_tls_connection ("need-tls-secrets-path-key", NM_SETTING_802_1X_CK_SCHEME_PATH);
+ ASSERT (connection != NULL,
+ "need-tls-secrets-path-key",
+ "error creating test connection");
+
+ /* Ensure we don't need any secrets since we just set up the connection */
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name == NULL,
+ "need-tls-secrets-path-key",
+ "secrets are unexpectedly required");
+ ASSERT (hints == NULL,
+ "need-tls-secrets-path-key",
+ "hints should be NULL since no secrets were required");
+
+ /* Connection is good; clear secrets and ensure private key is then required */
+ nm_connection_clear_secrets (connection);
+
+ hints = NULL;
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name != NULL,
+ "need-tls-secrets-path-key",
+ "unexpected secrets success");
+ ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0,
+ "need-tls-secrets-path-key",
+ "unexpected setting secrets required");
+
+ ASSERT (hints != NULL,
+ "need-tls-secrets-path-key",
+ "expected returned secrets hints");
+ ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY),
+ "need-tls-secrets-path-key",
+ "expected to require private key, but it wasn't");
+
+ g_object_unref (connection);
+
+ /*** Just clear the private key this time ***/
+
+ connection = make_tls_connection ("need-tls-secrets-path-key-password", NM_SETTING_802_1X_CK_SCHEME_PATH);
+ ASSERT (connection != NULL,
+ "need-tls-secrets-path-key-password",
+ "error creating test connection");
+
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ ASSERT (s_8021x != NULL,
+ "need-tls-secrets-path-key-password",
+ "error getting test 802.1x setting");
+
+ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL);
+
+ hints = NULL;
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name != NULL,
+ "need-tls-secrets-path-key-password",
+ "unexpected secrets success");
+ ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0,
+ "need-tls-secrets-path-key-password",
+ "unexpected setting secrets required");
+
+ ASSERT (hints != NULL,
+ "need-tls-secrets-path-key-password",
+ "expected returned secrets hints");
+ ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD),
+ "need-tls-secrets-path-key-password",
+ "expected to require private key password, but it wasn't");
+
+ g_object_unref (connection);
+}
+
+static void
+test_need_tls_secrets_blob (void)
+{
+ NMConnection *connection;
+ const char *setting_name;
+ GPtrArray *hints = NULL;
+ NMSetting8021x *s_8021x;
+
+ connection = make_tls_connection ("need-tls-secrets-blob-key", NM_SETTING_802_1X_CK_SCHEME_BLOB);
+ ASSERT (connection != NULL,
+ "need-tls-secrets-blob-key",
+ "error creating test connection");
+
+ /* Ensure we don't need any secrets since we just set up the connection */
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name == NULL,
+ "need-tls-secrets-blob-key",
+ "secrets are unexpectedly required");
+ ASSERT (hints == NULL,
+ "need-tls-secrets-blob-key",
+ "hints should be NULL since no secrets were required");
+
+ /* Connection is good; clear secrets and ensure private key is then required */
+ nm_connection_clear_secrets (connection);
+
+ hints = NULL;
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name != NULL,
+ "need-tls-secrets-blob-key",
+ "unexpected secrets success");
+ ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0,
+ "need-tls-secrets-blob-key",
+ "unexpected setting secrets required");
+
+ ASSERT (hints != NULL,
+ "need-tls-secrets-blob-key",
+ "expected returned secrets hints");
+ ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY),
+ "need-tls-secrets-blob-key",
+ "expected to require private key, but it wasn't");
+
+ g_object_unref (connection);
+
+ /*** Just clear the private key this time ***/
+
+ connection = make_tls_connection ("need-tls-secrets-blob-key-password", NM_SETTING_802_1X_CK_SCHEME_BLOB);
+ ASSERT (connection != NULL,
+ "need-tls-secrets-blob-key-password",
+ "error creating test connection");
+
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ ASSERT (s_8021x != NULL,
+ "need-tls-secrets-blob-key-password",
+ "error getting test 802.1x setting");
+
+ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL);
+
+ /* Blobs are already decrypted and don't need a password */
+ hints = NULL;
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name == NULL,
+ "need-tls-secrets-blob-key-password",
+ "unexpected secrets failure");
+ ASSERT (hints == NULL,
+ "need-tls-secrets-blob-key-password",
+ "hints should be NULL since no secrets were required");
+
+ g_object_unref (connection);
+}
+
+static NMConnection *
+make_tls_phase2_connection (const char *detail, NMSetting8021xCKScheme scheme)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSetting8021x *s_8021x;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ detail, "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ detail, "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Need TLS Secrets",
+ 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 ();
+ ASSERT (s_wired != NULL,
+ detail, "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ /* Wireless security setting */
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ ASSERT (s_8021x != NULL,
+ detail, "failed to allocate new %s setting",
+ NM_SETTING_802_1X_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "blahblah", NULL);
+ g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL);
+
+ nm_setting_802_1x_add_eap_method (s_8021x, "ttls");
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL);
+
+ success = nm_setting_802_1x_set_phase2_ca_cert (s_8021x,
+ TEST_NEED_SECRETS_EAP_TLS_CA_CERT,
+ scheme,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ detail, "failed to set phase2 CA certificate '%s': %s",
+ TEST_NEED_SECRETS_EAP_TLS_CA_CERT, error->message);
+
+ success = nm_setting_802_1x_set_phase2_client_cert (s_8021x,
+ TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT,
+ scheme,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ detail, "failed to set phase2 client certificate '%s': %s",
+ TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, error->message);
+
+ success = nm_setting_802_1x_set_phase2_private_key (s_8021x,
+ TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY,
+ "test",
+ scheme,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ detail, "failed to set phase2 private key '%s': %s",
+ TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, error->message);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ detail, "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ 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);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ detail, "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ return connection;
+}
+
+static void
+test_need_tls_phase2_secrets_path (void)
+{
+ NMConnection *connection;
+ const char *setting_name;
+ GPtrArray *hints = NULL;
+ NMSetting8021x *s_8021x;
+
+ connection = make_tls_phase2_connection ("need-tls-phase2-secrets-path-key",
+ NM_SETTING_802_1X_CK_SCHEME_PATH);
+ ASSERT (connection != NULL,
+ "need-tls-phase2-secrets-path-key",
+ "error creating test connection");
+
+ /* Ensure we don't need any secrets since we just set up the connection */
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name == NULL,
+ "need-tls-phase2-secrets-path-key",
+ "secrets are unexpectedly required");
+ ASSERT (hints == NULL,
+ "need-tls-phase2-secrets-path-key",
+ "hints should be NULL since no secrets were required");
+
+ /* Connection is good; clear secrets and ensure private key is then required */
+ nm_connection_clear_secrets (connection);
+
+ hints = NULL;
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name != NULL,
+ "need-tls-phase2-secrets-path-key",
+ "unexpected secrets success");
+ ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0,
+ "need-tls-phase2-secrets-path-key",
+ "unexpected setting secrets required");
+
+ ASSERT (hints != NULL,
+ "need-tls-phase2-secrets-path-key",
+ "expected returned secrets hints");
+ ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY),
+ "need-tls-phase2-secrets-path-key",
+ "expected to require private key, but it wasn't");
+
+ g_object_unref (connection);
+
+ /*** Just clear the private key this time ***/
+
+ connection = make_tls_phase2_connection ("need-tls-phase2-secrets-path-key-password",
+ NM_SETTING_802_1X_CK_SCHEME_PATH);
+ ASSERT (connection != NULL,
+ "need-tls-phase2-secrets-path-key-password",
+ "error creating test connection");
+
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ ASSERT (s_8021x != NULL,
+ "need-tls-phase2-secrets-path-key-password",
+ "error getting test 802.1x setting");
+
+ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, NULL, NULL);
+
+ hints = NULL;
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name != NULL,
+ "need-tls-phase2-secrets-path-key-password",
+ "unexpected secrets success");
+ ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0,
+ "need-tls-phase2-secrets-path-key-password",
+ "unexpected setting secrets required");
+
+ ASSERT (hints != NULL,
+ "need-tls-phase2-secrets-path-key-password",
+ "expected returned secrets hints");
+ ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD),
+ "need-tls-phase2-secrets-path-key-password",
+ "expected to require private key password, but it wasn't");
+
+ g_object_unref (connection);
+}
+
+static void
+test_need_tls_phase2_secrets_blob (void)
+{
+ NMConnection *connection;
+ const char *setting_name;
+ GPtrArray *hints = NULL;
+ NMSetting8021x *s_8021x;
+
+ connection = make_tls_phase2_connection ("need-tls-phase2-secrets-blob-key",
+ NM_SETTING_802_1X_CK_SCHEME_BLOB);
+ ASSERT (connection != NULL,
+ "need-tls-phase2-secrets-blob-key",
+ "error creating test connection");
+
+ /* Ensure we don't need any secrets since we just set up the connection */
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name == NULL,
+ "need-tls-phase2-secrets-blob-key",
+ "secrets are unexpectedly required");
+ ASSERT (hints == NULL,
+ "need-tls-phase2-secrets-blob-key",
+ "hints should be NULL since no secrets were required");
+
+ /* Connection is good; clear secrets and ensure private key is then required */
+ nm_connection_clear_secrets (connection);
+
+ hints = NULL;
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name != NULL,
+ "need-tls-phase2-secrets-blob-key",
+ "unexpected secrets success");
+ ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0,
+ "need-tls-phase2-secrets-blob-key",
+ "unexpected setting secrets required");
+
+ ASSERT (hints != NULL,
+ "need-tls-phase2-secrets-blob-key",
+ "expected returned secrets hints");
+ ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY),
+ "need-tls-phase2-secrets-blob-key",
+ "expected to require private key, but it wasn't");
+
+ g_object_unref (connection);
+
+ /*** Just clear the private key this time ***/
+
+ connection = make_tls_phase2_connection ("need-tls-phase2-secrets-blob-key-password",
+ NM_SETTING_802_1X_CK_SCHEME_BLOB);
+ ASSERT (connection != NULL,
+ "need-tls-phase2-secrets-blob-key-password",
+ "error creating test connection");
+
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ ASSERT (s_8021x != NULL,
+ "need-tls-phase2-secrets-blob-key-password",
+ "error getting test 802.1x setting");
+
+ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, NULL, NULL);
+
+ /* Blobs are already decrypted and don't need a password */
+ hints = NULL;
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ ASSERT (setting_name == NULL,
+ "need-tls-phase2-secrets-blob-key-password",
+ "unexpected secrets failure");
+ ASSERT (hints == NULL,
+ "need-tls-phase2-secrets-blob-key-password",
+ "hints should be NULL since no secrets were required");
+
+ g_object_unref (connection);
+}
+
+int main (int argc, char **argv)
+{
+ GError *error = NULL;
+ DBusGConnection *bus;
+ char *base;
+
+ g_type_init ();
+ bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+
+ if (!nm_utils_init (&error))
+ FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
+
+ /* The tests */
+ test_need_tls_secrets_path ();
+ test_need_tls_secrets_blob ();
+ test_need_tls_phase2_secrets_path ();
+ test_need_tls_phase2_secrets_blob ();
+
+ base = g_path_get_basename (argv[0]);
+ fprintf (stdout, "%s: SUCCESS\n", base);
+ g_free (base);
+ return 0;
+}
+
diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c
index 7f280cec1a..f41169cb15 100644
--- a/src/ip6-manager/nm-ip6-manager.c
+++ b/src/ip6-manager/nm-ip6-manager.c
@@ -18,6 +18,7 @@
* Copyright (C) 2009 Red Hat, Inc.
*/
+#include
#include
#include
@@ -68,12 +69,16 @@ typedef struct {
char *iface;
int index;
+ char *accept_ra_path;
+ gboolean accept_ra_save_valid;
+ guint32 accept_ra_save;
+
guint finish_addrconf_id;
guint config_changed_id;
NMIP6DeviceState state;
NMIP6DeviceState target_state;
- gboolean want_signal;
+ gboolean addrconf_complete;
GArray *rdnss_servers;
guint rdnss_timeout_id;
@@ -179,6 +184,14 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class)
static void
nm_ip6_device_destroy (NMIP6Device *device)
{
+ g_return_if_fail (device != NULL);
+
+ /* reset the saved RA value */
+ if (device->accept_ra_save_valid) {
+ nm_utils_do_sysctl (device->accept_ra_path,
+ device->accept_ra_save ? "1\n" : "0\n");
+ }
+
if (device->finish_addrconf_id)
g_source_remove (device->finish_addrconf_id);
if (device->config_changed_id)
@@ -189,6 +202,7 @@ nm_ip6_device_destroy (NMIP6Device *device)
if (device->rdnss_timeout_id)
g_source_remove (device->rdnss_timeout_id);
+ g_free (device->accept_ra_path);
g_slice_free (NMIP6Device, device);
}
@@ -227,7 +241,7 @@ finish_addrconf (gpointer user_data)
char *iface_copy;
device->finish_addrconf_id = 0;
- device->want_signal = FALSE;
+ device->addrconf_complete = TRUE;
if (device->state >= device->target_state) {
g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0,
@@ -354,7 +368,7 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed)
// if (flags & (IF_RA_MANAGED | IF_RA_OTHERCONF))
// device->need_dhcp = TRUE;
- if (device->want_signal) {
+ if (!device->addrconf_complete) {
if (device->state >= device->target_state ||
device->state == NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT) {
/* device->finish_addrconf_id may currently be a timeout
@@ -452,7 +466,7 @@ process_prefix (NMIP6Manager *manager, struct nl_msg *msg)
pmsg = (struct prefixmsg *) NLMSG_DATA (nlmsg_hdr (msg));
device = nm_ip6_manager_get_device (manager, pmsg->prefix_ifindex);
- if (!device || !device->want_signal)
+ if (!device || device->addrconf_complete)
return NULL;
return device;
@@ -600,6 +614,8 @@ nm_ip6_device_new (NMIP6Manager *manager, const char *iface)
{
NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
NMIP6Device *device;
+ GError *error = NULL;
+ char *contents = NULL;
device = g_slice_new0 (NMIP6Device);
if (!device) {
@@ -616,6 +632,14 @@ nm_ip6_device_new (NMIP6Manager *manager, const char *iface)
}
device->index = nm_netlink_iface_to_index (iface);
+ device->accept_ra_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/accept_ra", iface);
+ if (!device->accept_ra_path) {
+ nm_warning ("%s: Out of memory creating IP6 addrconf object "
+ "property 'accept_ra_path'.",
+ iface);
+ goto error;
+ }
+
device->manager = manager;
device->rdnss_servers = g_array_new (FALSE, FALSE, sizeof (NMIP6RDNSS));
@@ -623,6 +647,27 @@ nm_ip6_device_new (NMIP6Manager *manager, const char *iface)
g_hash_table_replace (priv->devices_by_iface, device->iface, device);
g_hash_table_replace (priv->devices_by_index, GINT_TO_POINTER (device->index), device);
+ /* Grab the original value of "accept_ra" so we can restore it when the
+ * device is taken down.
+ */
+ if (!g_file_get_contents (device->accept_ra_path, &contents, NULL, &error)) {
+ nm_warning ("%s: error reading %s: (%d) %s",
+ iface, device->accept_ra_path,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ } else {
+ long int tmp;
+
+ errno = 0;
+ tmp = strtol (contents, NULL, 10);
+ if ((errno == 0) && (tmp == 0 || tmp == 1)) {
+ device->accept_ra_save = (guint32) tmp;
+ device->accept_ra_save_valid = TRUE;
+ }
+ g_free (contents);
+ }
+
return device;
error:
@@ -638,7 +683,6 @@ nm_ip6_manager_prepare_interface (NMIP6Manager *manager,
NMIP6ManagerPrivate *priv;
NMIP6Device *device;
const char *method = NULL;
- char *sysctl_path;
g_return_if_fail (NM_IS_IP6_MANAGER (manager));
g_return_if_fail (iface != NULL);
@@ -662,10 +706,9 @@ nm_ip6_manager_prepare_interface (NMIP6Manager *manager,
strcmp (iface, "all") != 0 &&
strcmp (iface, "default") != 0);
- sysctl_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/accept_ra", iface);
- nm_utils_do_sysctl (sysctl_path,
- device->target_state >= NM_IP6_DEVICE_GOT_ADDRESS ? "1\n" : "0\n");
- g_free (sysctl_path);
+ /* Turn router advertisement acceptance on or off... */
+ nm_utils_do_sysctl (device->accept_ra_path,
+ device->target_state >= NM_IP6_DEVICE_GOT_ADDRESS ? "1\n" : "0\n");
}
void
@@ -685,6 +728,8 @@ nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
nm_info ("Activation (%s) Beginning IP6 addrconf.", iface);
+ device->addrconf_complete = FALSE;
+
/* Set up a timeout on the transaction to kill it after the timeout */
device->finish_addrconf_id = g_timeout_add_seconds (NM_IP6_TIMEOUT,
finish_addrconf,
diff --git a/src/ip6-manager/nm-ip6-manager.h b/src/ip6-manager/nm-ip6-manager.h
index 2c79a454a1..33b2b9893a 100644
--- a/src/ip6-manager/nm-ip6-manager.h
+++ b/src/ip6-manager/nm-ip6-manager.h
@@ -43,8 +43,16 @@ typedef struct {
GObjectClass parent;
/* Signals */
+
+ /* addrconf_complete is emitted only during initial configuration to indicate
+ * that the initial configuration is complete.
+ */
void (*addrconf_complete) (NMIP6Manager *manager, char *iface, gboolean success);
+ /* config_changed gets emitted only *after* initial configuration is
+ * complete; it's like DHCP renew and indicates that the existing config
+ * of the interface has changed.
+ */
void (*config_changed) (NMIP6Manager *manager, char *iface);
} NMIP6ManagerClass;
diff --git a/src/nm-device.c b/src/nm-device.c
index 0d3481cb37..6c0f99ca47 100644
--- a/src/nm-device.c
+++ b/src/nm-device.c
@@ -532,7 +532,7 @@ ip6_addrconf_complete (NMIP6Manager *ip6_manager,
NMDevice *self = NM_DEVICE (user_data);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- if (strcmp (nm_device_get_iface (self), iface) != 0)
+ if (strcmp (nm_device_get_ip_iface (self), iface) != 0)
return;
if (!nm_device_get_act_request (self))
return;
@@ -553,7 +553,7 @@ ip6_config_changed (NMIP6Manager *ip6_manager,
{
NMDevice *self = NM_DEVICE (user_data);
- if (strcmp (nm_device_get_iface (self), iface) != 0)
+ if (strcmp (nm_device_get_ip_iface (self), iface) != 0)
return;
if (!nm_device_get_act_request (self))
return;
@@ -567,7 +567,7 @@ nm_device_setup_ip6 (NMDevice *self)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActRequest *req;
NMConnection *connection;
- const char *iface, *method = NULL;
+ const char *ip_iface, *method = NULL;
NMSettingIP6Config *s_ip6;
req = nm_device_get_act_request (self);
@@ -598,8 +598,8 @@ nm_device_setup_ip6 (NMDevice *self)
priv->ip6_waiting_for_config = FALSE;
- iface = nm_device_get_iface (self);
- nm_ip6_manager_prepare_interface (priv->ip6_manager, iface, s_ip6);
+ ip_iface = nm_device_get_ip_iface (self);
+ nm_ip6_manager_prepare_interface (priv->ip6_manager, ip_iface, s_ip6);
}
static void
@@ -607,21 +607,22 @@ nm_device_cleanup_ip6 (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- if (priv->ip6_manager) {
- if (priv->ip6_addrconf_sigid) {
- g_signal_handler_disconnect (priv->ip6_manager,
- priv->ip6_addrconf_sigid);
- priv->ip6_addrconf_sigid = 0;
- }
- if (priv->ip6_config_changed_sigid) {
- g_signal_handler_disconnect (priv->ip6_manager,
- priv->ip6_config_changed_sigid);
- priv->ip6_config_changed_sigid = 0;
- }
+ if (!priv->ip6_manager)
+ return;
- g_object_unref (priv->ip6_manager);
- priv->ip6_manager = NULL;
+ if (priv->ip6_addrconf_sigid) {
+ g_signal_handler_disconnect (priv->ip6_manager,
+ priv->ip6_addrconf_sigid);
+ priv->ip6_addrconf_sigid = 0;
}
+ if (priv->ip6_config_changed_sigid) {
+ g_signal_handler_disconnect (priv->ip6_manager,
+ priv->ip6_config_changed_sigid);
+ priv->ip6_config_changed_sigid = 0;
+ }
+
+ g_object_unref (priv->ip6_manager);
+ priv->ip6_manager = NULL;
}
/*
@@ -1139,7 +1140,7 @@ static NMActStageReturn
real_act_stage3_ip6_config_start (NMDevice *self, NMDeviceStateReason *reason)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- const char *iface = nm_device_get_iface (self);
+ const char *ip_iface = nm_device_get_ip_iface (self);
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
@@ -1150,7 +1151,7 @@ real_act_stage3_ip6_config_start (NMDevice *self, NMDeviceStateReason *reason)
return NM_ACT_STAGE_RETURN_SUCCESS;
priv->ip6_waiting_for_config = TRUE;
- nm_ip6_manager_begin_addrconf (priv->ip6_manager, iface);
+ nm_ip6_manager_begin_addrconf (priv->ip6_manager, ip_iface);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
diff --git a/src/nm-manager.c b/src/nm-manager.c
index f1ac17162e..44e4b56e2a 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1999,6 +1999,7 @@ nm_manager_activate_connection (NMManager *manager,
gboolean user_requested,
GError **error)
{
+ NMManagerPrivate *priv;
NMDevice *device = NULL;
NMSettingConnection *s_con;
NMVPNConnection *vpn_connection;
@@ -2009,26 +2010,47 @@ nm_manager_activate_connection (NMManager *manager,
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail (*error == NULL, NULL);
+ priv = NM_MANAGER_GET_PRIVATE (manager);
+
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
if (!strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_VPN_SETTING_NAME)) {
- NMActRequest *req;
+ NMActRequest *req = NULL;
NMVPNManager *vpn_manager;
/* VPN connection */
- req = nm_manager_get_act_request_by_path (manager, specific_object, &device);
- if (!req) {
- g_set_error (error,
- NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
- "%s", "Base connection for VPN connection not active.");
- return NULL;
+
+ if (specific_object) {
+ /* Find the specifc connection the client requested we use */
+ req = nm_manager_get_act_request_by_path (manager, specific_object, &device);
+ if (!req) {
+ g_set_error (error,
+ NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
+ "%s", "Base connection for VPN connection not active.");
+ return NULL;
+ }
+ } else {
+ GSList *iter;
+
+ /* Just find the current default connection */
+ for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
+ NMDevice *candidate = NM_DEVICE (iter->data);
+ NMActRequest *candidate_req;
+
+ candidate_req = nm_device_get_act_request (candidate);
+ if (candidate_req && nm_act_request_get_default (candidate_req)) {
+ device = candidate;
+ req = candidate_req;
+ break;
+ }
+ }
}
- if (!device) {
+ if (!device || !req) {
g_set_error (error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
- "%s", "Source connection had no active device.");
+ "%s", "Could not find source connection, or the source connection had no active device.");
return NULL;
}
diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c
index 32895be169..9bba219e10 100644
--- a/src/system-settings/nm-sysconfig-settings.c
+++ b/src/system-settings/nm-sysconfig-settings.c
@@ -594,8 +594,10 @@ add_new_connection (NMSysconfigSettings *self,
connection,
&tmp_error);
g_clear_error (&last_error);
- if (!success)
+ if (!success) {
last_error = tmp_error;
+ tmp_error = NULL;
+ }
}
if (!success)
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index a89c7101f7..f8360dc669 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -912,6 +912,12 @@ vpn_cleanup (NMVPNConnection *connection)
g_free (priv->tundev);
priv->tundev = NULL;
}
+
+ /* Clear out connection secrets to ensure that the settings service
+ * gets asked for them next time the connection is activated.
+ */
+ if (priv->connection)
+ nm_connection_clear_secrets (priv->connection);
}
static void
diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c
index 3fee59d72a..d26145930a 100644
--- a/system-settings/plugins/ifcfg-rh/reader.c
+++ b/system-settings/plugins/ifcfg-rh/reader.c
@@ -668,7 +668,7 @@ make_ip4_setting (shvarFile *ifcfg,
NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
NULL);
return NM_SETTING (s_ip4);
- } else if (!g_ascii_strcasecmp (value, "none")) {
+ } else if (!g_ascii_strcasecmp (value, "none") || !g_ascii_strcasecmp (value, "static")) {
/* Static IP */
} else if (strlen (value)) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
diff --git a/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
index 206b206e15..9a2d899a14 100644
--- a/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
+++ b/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
@@ -2,6 +2,7 @@ EXTRA_DIST = \
ifcfg-test-minimal \
ifcfg-test-nm-controlled \
ifcfg-test-wired-static \
+ ifcfg-test-wired-static-bootproto \
ifcfg-test-wired-dhcp \
ifcfg-test-wired-global-gateway \
network-test-wired-global-gateway \
diff --git a/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-bootproto b/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-bootproto
new file mode 100644
index 0000000000..ee821503e2
--- /dev/null
+++ b/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-bootproto
@@ -0,0 +1,15 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=static
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+MTU=1492
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=192.168.1.5
+NETMASK=255.255.255.0
+GATEWAY=192.168.1.1
diff --git a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
index 4d83145982..cfbe0d6872 100644
--- a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -413,10 +413,8 @@ test_read_unmanaged (void)
g_object_unref (connection);
}
-#define TEST_IFCFG_WIRED_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static"
-
static void
-test_read_wired_static (void)
+test_read_wired_static (const char *file, const char *expected_id)
{
NMConnection *connection;
NMSettingConnection *s_con;
@@ -429,7 +427,6 @@ test_read_wired_static (void)
const GByteArray *array;
char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee };
const char *tmp;
- const char *expected_id = "System test-wired-static";
const char *expected_dns1 = "4.2.2.1";
const char *expected_dns2 = "4.2.2.2";
struct in_addr addr;
@@ -437,7 +434,7 @@ test_read_wired_static (void)
const char *expected_address1_gw = "192.168.1.1";
NMIP4Address *ip4_addr;
- connection = connection_from_file (TEST_IFCFG_WIRED_STATIC,
+ connection = connection_from_file (file,
NULL,
TYPE_ETHERNET,
NULL,
@@ -446,46 +443,46 @@ test_read_wired_static (void)
&error,
&ignore_error);
ASSERT (connection != NULL,
- "wired-static-read", "failed to read %s: %s", TEST_IFCFG_WIRED_STATIC, error->message);
+ "wired-static-read", "failed to read %s: %s", file, error->message);
ASSERT (nm_connection_verify (connection, &error),
- "wired-static-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_STATIC, error->message);
+ "wired-static-verify", "failed to verify %s: %s", file, error->message);
ASSERT (unmanaged == FALSE,
- "wired-static-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_STATIC);
+ "wired-static-verify", "failed to verify %s: unexpected unmanaged value", file);
/* ===== CONNECTION SETTING ===== */
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
ASSERT (s_con != NULL,
"wired-static-verify-connection", "failed to verify %s: missing %s setting",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_CONNECTION_SETTING_NAME);
/* ID */
tmp = nm_setting_connection_get_id (s_con);
ASSERT (tmp != NULL,
"wired-static-verify-connection", "failed to verify %s: missing %s / %s key",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_ID);
ASSERT (strcmp (tmp, expected_id) == 0,
"wired-static-verify-connection", "failed to verify %s: unexpected %s / %s key value",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_ID);
/* Timestamp */
ASSERT (nm_setting_connection_get_timestamp (s_con) == 0,
"wired-static-verify-connection", "failed to verify %s: unexpected %s /%s key value",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_TIMESTAMP);
/* Autoconnect */
ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
"wired-static-verify-connection", "failed to verify %s: unexpected %s /%s key value",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_AUTOCONNECT);
@@ -494,30 +491,30 @@ test_read_wired_static (void)
s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
ASSERT (s_wired != NULL,
"wired-static-verify-wired", "failed to verify %s: missing %s setting",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_WIRED_SETTING_NAME);
/* MAC address */
array = nm_setting_wired_get_mac_address (s_wired);
ASSERT (array != NULL,
"wired-static-verify-wired", "failed to verify %s: missing %s / %s key",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_WIRED_MAC_ADDRESS);
ASSERT (array->len == ETH_ALEN,
"wired-static-verify-wired", "failed to verify %s: unexpected %s / %s key value length",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_WIRED_MAC_ADDRESS);
ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
"wired-static-verify-wired", "failed to verify %s: unexpected %s / %s key value",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_WIRED_MAC_ADDRESS);
ASSERT (nm_setting_wired_get_mtu (s_wired) == 1492,
"wired-static-verify-wired", "failed to verify %s: unexpected %s / %s key value",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_WIRED_MTU);
@@ -526,49 +523,49 @@ test_read_wired_static (void)
s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
ASSERT (s_ip4 != NULL,
"wired-static-verify-ip4", "failed to verify %s: missing %s setting",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME);
/* Method */
tmp = nm_setting_ip4_config_get_method (s_ip4);
ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
"wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_METHOD);
/* DNS Addresses */
ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2,
"wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_DNS);
ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0,
"wired-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_DNS);
ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr,
"wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_DNS);
ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0,
"wired-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_DNS);
ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr,
"wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_DNS);
ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1,
"wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_DNS);
@@ -576,35 +573,35 @@ test_read_wired_static (void)
ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
ASSERT (ip4_addr,
"wired-static-verify-ip4", "failed to verify %s: missing IP4 address #1",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_ADDRESSES);
ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 24,
"wired-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_ADDRESSES);
ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0,
"wired-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_DNS);
ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
"wired-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_ADDRESSES);
ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0,
"wired-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1 gateway",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_ADDRESSES);
ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr,
"wired-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 gateway",
- TEST_IFCFG_WIRED_STATIC,
+ file,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_ADDRESSES);
@@ -4210,6 +4207,140 @@ test_write_wifi_wep_adhoc (void)
g_object_unref (reread);
}
+static void
+test_write_wifi_leap (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = "blahblah";
+ struct stat statbuf;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-leap-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-leap-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ 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",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-leap-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ 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 ();
+ ASSERT (s_wsec != NULL,
+ "wifi-leap-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ 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",
+ NULL);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-leap-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ 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);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-leap-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-leap-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-leap-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (keyfile != NULL,
+ "wifi-leap-write-reread", "expected keyfile for '%s'", testfile);
+
+ ASSERT (stat (keyfile, &statbuf) == 0,
+ "wifi-leap-write-reread", "couldn't stat() '%s'", keyfile);
+ ASSERT (S_ISREG (statbuf.st_mode),
+ "wifi-leap-write-reread", "keyfile '%s' wasn't a normal file", keyfile);
+ ASSERT ((statbuf.st_mode & 0077) == 0,
+ "wifi-leap-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile);
+
+ unlink (keyfile);
+
+ ASSERT (reread != NULL,
+ "wifi-leap-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-leap-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-leap-write", "written and re-read connection weren't the same.");
+
+ 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,
@@ -5624,6 +5755,9 @@ test_write_mobile_broadband (gboolean gsm)
#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-long-hex"
+#define TEST_IFCFG_WIRED_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static"
+#define TEST_IFCFG_WIRED_STATIC_BOOTPROTO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-bootproto"
+
#define DEFAULT_HEX_PSK "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0"
int main (int argc, char **argv)
@@ -5641,7 +5775,8 @@ int main (int argc, char **argv)
/* The tests */
test_read_unmanaged ();
test_read_minimal ();
- test_read_wired_static ();
+ test_read_wired_static (TEST_IFCFG_WIRED_STATIC, "System test-wired-static");
+ test_read_wired_static (TEST_IFCFG_WIRED_STATIC_BOOTPROTO, "System test-wired-static-bootproto");
test_read_wired_dhcp ();
test_read_wired_global_gateway ();
test_read_wired_never_default ();
@@ -5670,6 +5805,7 @@ int main (int argc, char **argv)
test_write_wifi_open_hex_ssid ();
test_write_wifi_wep ();
test_write_wifi_wep_adhoc ();
+ test_write_wifi_leap ();
test_write_wifi_wpa_psk ("Test Write Wifi WPA PSK",
"wifi-wpa-psk-write",
FALSE,
diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c
index 11ab2d182d..1ba9455837 100644
--- a/system-settings/plugins/ifcfg-rh/writer.c
+++ b/system-settings/plugins/ifcfg-rh/writer.c
@@ -575,7 +575,7 @@ write_wireless_security_setting (NMConnection *connection,
svSetValue (ifcfg, "SECURITYMODE", "open", FALSE);
else if (!strcmp (auth_alg, "leap")) {
svSetValue (ifcfg, "SECURITYMODE", "leap", FALSE);
- svSetValue (ifcfg, "IEEE_8021X_USERNAME",
+ svSetValue (ifcfg, "IEEE_8021X_IDENTITY",
nm_setting_wireless_security_get_leap_username (s_wsec),
FALSE);
set_secret (ifcfg, "IEEE_8021X_PASSWORD",