[Pkg-utopia-commits] r3435 - in /packages/unstable/network-manager-applet/debian: changelog patches/03-CVE-2009-4144_fix_ca_cert_handling_after_cert_file_deletion.patch patches/series

biebl at users.alioth.debian.org biebl at users.alioth.debian.org
Sat Jan 23 01:32:35 UTC 2010


Author: biebl
Date: Sat Jan 23 01:32:35 2010
New Revision: 3435

URL: http://svn.debian.org/wsvn/pkg-utopia/?sc=1&rev=3435
Log:
* debian/patches/03-CVE-2009-4144_fix_ca_cert_handling_after_cert_file_deletion.patch
  - Fix possible connections to spoofed WPA Enterprise networks when
    certification file is deleted. (Closes: #560067)
    Patch backported from upstream Git.
    Fixes: CVE-2009-4144

Added:
    packages/unstable/network-manager-applet/debian/patches/03-CVE-2009-4144_fix_ca_cert_handling_after_cert_file_deletion.patch
Modified:
    packages/unstable/network-manager-applet/debian/changelog
    packages/unstable/network-manager-applet/debian/patches/series

Modified: packages/unstable/network-manager-applet/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-utopia/packages/unstable/network-manager-applet/debian/changelog?rev=3435&op=diff
==============================================================================
--- packages/unstable/network-manager-applet/debian/changelog (original)
+++ packages/unstable/network-manager-applet/debian/changelog Sat Jan 23 01:32:35 2010
@@ -7,6 +7,11 @@
     - Fix potential leakage of secrets onto the system bus. (Closes: #563371)
       Patch backported from upstream Git.
       Fixes: CVE-2009-4145
+  * debian/patches/03-CVE-2009-4144_fix_ca_cert_handling_after_cert_file_deletion.patch
+    - Fix possible connections to spoofed WPA Enterprise networks when
+      certification file is deleted. (Closes: #560067)
+      Patch backported from upstream Git.
+      Fixes: CVE-2009-4144
 
  -- Michael Biebl <biebl at debian.org>  Fri, 22 Jan 2010 23:33:06 +0100
 

Added: packages/unstable/network-manager-applet/debian/patches/03-CVE-2009-4144_fix_ca_cert_handling_after_cert_file_deletion.patch
URL: http://svn.debian.org/wsvn/pkg-utopia/packages/unstable/network-manager-applet/debian/patches/03-CVE-2009-4144_fix_ca_cert_handling_after_cert_file_deletion.patch?rev=3435&op=file
==============================================================================
--- packages/unstable/network-manager-applet/debian/patches/03-CVE-2009-4144_fix_ca_cert_handling_after_cert_file_deletion.patch (added)
+++ packages/unstable/network-manager-applet/debian/patches/03-CVE-2009-4144_fix_ca_cert_handling_after_cert_file_deletion.patch Sat Jan 23 01:32:35 2010
@@ -1,0 +1,698 @@
+From 2ad9d26b1a6020dd178b75fb7dc133c23daa37bc Mon Sep 17 00:00:00 2001
+From: Dan Williams <dcbw at redhat.com>
+Date: Wed, 9 Dec 2009 14:44:17 -0800
+Subject: [PATCH 2/2] gconf: ensure changes to certificate and key paths get remembered
+
+Because the GConf update-event code was not checking the new connections'
+private values (which store cert and key paths) if the user only updated
+certificate or key paths in the connection editor, the change would be
+reverted the next time the applet connected to that AP since the applet
+writes the connection back out to GConf when updating the timestamp when
+the connection is active.  Unless the user logged out or rebooted before
+connecting to that AP.
+
+core: fix CA cert mishandling after cert file deletion (deb #560067) (rh #546793)
+
+If a connection was created with a CA certificate, but the user later
+moved or deleted that CA certificate, the applet would simply provide the
+connection to NetworkManager without any CA certificate.  This could cause
+NM to connect to the original network (or a network spoofing the original
+network) without verifying the identity of the network as the user
+expects.
+
+In the future we can/should do better here by (1) alerting the user that
+some connection is now no longer complete by flagging it in the connection
+editor or notifying the user somehow, and (2) by using a freaking' cert
+store already (not that Linux has one yet).
+---
+ src/applet-device-wifi.c                   |   11 ++-
+ src/applet-device-wired.c                  |   10 ++-
+ src/connection-editor/nm-connection-list.c |   65 ++++++----
+ src/gconf-helpers/gconf-helpers.c          |  184 +++++++++++++++++++++-------
+ src/gconf-helpers/gconf-helpers.h          |    4 +-
+ src/gconf-helpers/nma-gconf-connection.c   |   66 ++++++++--
+ src/utils/utils.c                          |   49 +++++---
+ src/utils/utils.h                          |    2 +-
+ 8 files changed, 286 insertions(+), 105 deletions(-)
+
+diff --git a/src/applet-device-wifi.c b/src/applet-device-wifi.c
+index ca2b087..31fee5e 100644
+--- a/src/applet-device-wifi.c
++++ b/src/applet-device-wifi.c
+@@ -1478,6 +1478,7 @@ add_one_setting (GHashTable *settings,
+                  GError **error)
+ {
+ 	GHashTable *secrets;
++	GError *tmp_error = NULL;
+ 
+ 	g_return_val_if_fail (settings != NULL, FALSE);
+ 	g_return_val_if_fail (connection != NULL, FALSE);
+@@ -1485,7 +1486,15 @@ add_one_setting (GHashTable *settings,
+ 	g_return_val_if_fail (error != NULL, FALSE);
+ 	g_return_val_if_fail (*error == NULL, FALSE);
+ 
+-	utils_fill_connection_certs (connection);
++	if (!utils_fill_connection_certs (NM_CONNECTION (connection), &tmp_error)) {
++		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INTERNAL_ERROR,
++					 "%s.%d (%s): failed to read connection certificates: (%d) %s.",
++					 __FILE__, __LINE__, __func__,
++					 tmp_error ? tmp_error->code : -1,
++					 tmp_error && tmp_error->message ? tmp_error->message : "(unknown)");
++		return FALSE;
++	}
++
+ 	secrets = nm_setting_to_hash (setting);
+ 	utils_clear_filled_connection_certs (connection);
+ 
+diff --git a/src/applet-device-wired.c b/src/applet-device-wired.c
+index 3e63a76..76c3c2f 100644
+--- a/src/applet-device-wired.c
++++ b/src/applet-device-wired.c
+@@ -650,7 +650,15 @@ get_8021x_secrets_cb (GtkDialog *dialog,
+ 		goto done;
+ 	}
+ 
+-	utils_fill_connection_certs (NM_CONNECTION (connection));
++	if (!utils_fill_connection_certs (NM_CONNECTION (connection), &err)) {
++		g_set_error (&err, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INTERNAL_ERROR,
++					 "%s.%d (%s): failed to read connection certificates: (%d) %s.",
++					 __FILE__, __LINE__, __func__,
++					 err ? err->code : -1,
++					 err && err->message ? err->message : "(unknown)");
++		goto done;
++	}
++
+ 	secrets = nm_setting_to_hash (setting);
+ 	utils_clear_filled_connection_certs (NM_CONNECTION (connection));
+ 
+diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
+index cd4b375..6e3a410 100644
+--- a/src/connection-editor/nm-connection-list.c
++++ b/src/connection-editor/nm-connection-list.c
+@@ -503,14 +503,15 @@ add_connection (NMConnectionList *self,
+ 	NMExportedConnection *exported = NULL;
+ 	NMConnectionScope scope;
+ 	gboolean success = FALSE;
++	GError *error = NULL;
+ 
+ 	scope = nm_connection_get_scope (connection);
+ 	if (scope == NM_CONNECTION_SCOPE_SYSTEM) {
+-		GError *error = NULL;
+-
+-		utils_fill_connection_certs (connection);
+-		success = nm_dbus_settings_system_add_connection (self->system_settings, connection, &error);
+-		utils_clear_filled_connection_certs (connection);
++		success = utils_fill_connection_certs (connection, &error);
++		if (success) {
++			success = nm_dbus_settings_system_add_connection (self->system_settings, connection, &error);
++			utils_clear_filled_connection_certs (connection);
++		}
+ 
+ 		if (!success) {
+ 			gboolean pending_auth = FALSE;
+@@ -705,18 +706,21 @@ update_connection (NMConnectionList *list,
+ 		gboolean pending_auth = FALSE;
+ 		GtkWindow *parent;
+ 
+-		utils_fill_connection_certs (modified);
+-		new_settings = nm_connection_to_hash (modified);
++		parent = nm_connection_editor_get_window (editor);
+ 
+-		/* Hack; make sure that gconf private values are copied */
+-		nm_gconf_copy_private_connection_values (nm_exported_connection_get_connection (original),
+-		                                         modified);
++		success = utils_fill_connection_certs (modified, &error);
++		if (success) {
++			new_settings = nm_connection_to_hash (modified);
+ 
+-		success = nm_exported_connection_update (original, new_settings, &error);
+-		g_hash_table_destroy (new_settings);
+-		utils_clear_filled_connection_certs (modified);
++			/* Hack; make sure that gconf private values are copied */
++			nm_gconf_copy_private_connection_values (nm_exported_connection_get_connection (original),
++			                                         modified);
++
++			success = nm_exported_connection_update (original, new_settings, &error);
++			g_hash_table_destroy (new_settings);
++			utils_clear_filled_connection_certs (modified);
++		}
+ 
+-		parent = nm_connection_editor_get_window (editor);
+ 		if (!success) {
+ 			if (pk_helper_is_permission_denied_error (error)) {
+ 				GError *auth_error = NULL;
+@@ -902,19 +906,28 @@ edit_done_cb (NMConnectionEditor *editor, gint response, GError *error, gpointer
+ 
+ 		connection = nm_connection_editor_get_connection (editor);
+ 
+-		utils_fill_connection_certs (connection);
+-		success = nm_connection_verify (connection, &edit_error);
+-		utils_clear_filled_connection_certs (connection);
+-
+-		if (success) {
+-			update_connection (info->list, editor, info->original_connection,
+-			                   connection, connection_updated_cb, info);
+-		} else {
+-			g_warning ("%s: invalid connection after update: bug in the "
+-			           "'%s' / '%s' invalid: %d",
++		success = utils_fill_connection_certs (connection, &edit_error);
++		if (!success) {
++			g_warning ("%s: error completing connection edit: (%d) %s",
+ 			           __func__,
+-			           g_type_name (nm_connection_lookup_setting_type_by_quark (edit_error->domain)),
+-			           edit_error->message, edit_error->code);
++			           edit_error ? edit_error->code : -1,
++			           edit_error && edit_error->message ? edit_error->message : "(unknown)");
++		} else {
++			success = nm_connection_verify (connection, &edit_error);
++			utils_clear_filled_connection_certs (connection);
++			if (success) {
++				update_connection (info->list, editor, info->original_connection,
++				                   connection, connection_updated_cb, info);
++			} else {
++				g_warning ("%s: invalid connection after update: property "
++				           "'%s' / '%s' invalid: %d",
++				           __func__,
++				           g_type_name (nm_connection_lookup_setting_type_by_quark (edit_error->domain)),
++				           edit_error->message, edit_error->code);
++			}
++		}
++
++		if (!success) {
+ 			g_error_free (edit_error);
+ 			connection_updated_cb (info->list, FALSE, user_data);
+ 		}
+diff --git a/src/gconf-helpers/gconf-helpers.c b/src/gconf-helpers/gconf-helpers.c
+index 8ebb9ae..17aee90 100644
+--- a/src/gconf-helpers/gconf-helpers.c
++++ b/src/gconf-helpers/gconf-helpers.c
+@@ -25,6 +25,7 @@
+ #include <gconf/gconf.h>
+ #include <gconf/gconf-client.h>
+ #include <glib.h>
++#include <glib/gi18n.h>
+ #include <gnome-keyring.h>
+ #include <dbus/dbus-glib.h>
+ #include <nm-setting-connection.h>
+@@ -992,6 +993,7 @@ typedef struct ReadFromGConfInfo {
+ 	GConfClient *client;
+ 	const char *dir;
+ 	guint32 dir_len;
++	GError *error;
+ } ReadFromGConfInfo;
+ 
+ static void
+@@ -1137,57 +1139,81 @@ read_one_setting_value_from_gconf (NMSetting *setting,
+ 	}
+ }
+ 
+-static void
++static gboolean
+ read_one_cert (ReadFromGConfInfo *info,
+                const char *setting_name,
+-               const char *key)
++               const char *key,
++               gboolean fail_if_missing,
++               GError **error)
+ {
+ 	char *value = NULL;
+ 
+-	if (!nm_gconf_get_string_helper (info->client, info->dir, key, setting_name, &value))
+-		return;
++	if (nm_gconf_get_string_helper (info->client, info->dir, key, setting_name, &value)) {
++		if (fail_if_missing && !g_file_test (value, G_FILE_TEST_EXISTS)) {
++			g_set_error (error, 0, 0, _("Certificate %s not found or not accessible."), value);
++			return FALSE;
++		}
+ 
+-	g_object_set_data_full (G_OBJECT (info->connection),
+-	                        key, value,
+-	                        (GDestroyNotify) g_free);
++		g_object_set_data_full (G_OBJECT (info->connection), key, value, (GDestroyNotify) g_free);
++	}
++	return TRUE;
+ }
+ 
+ static void
+ read_applet_private_values_from_gconf (NMSetting *setting,
+                                        ReadFromGConfInfo *info)
+ {
+-	if (NM_IS_SETTING_802_1X (setting)) {
+-		const char *setting_name = nm_setting_get_name (setting);
+-		gboolean value;
+-
+-		if (nm_gconf_get_bool_helper (info->client, info->dir,
+-		                              NMA_CA_CERT_IGNORE_TAG,
+-		                              setting_name, &value)) {
+-			g_object_set_data (G_OBJECT (info->connection),
+-			                   NMA_CA_CERT_IGNORE_TAG,
+-			                   GUINT_TO_POINTER (value));
+-		}
++	const char *setting_name = nm_setting_get_name (setting);
++	gboolean value;
++	GError *error = NULL;
++
++	if (!NM_IS_SETTING_802_1X (setting))
++		return;
++
++	if (nm_gconf_get_bool_helper (info->client, info->dir,
++	                              NMA_CA_CERT_IGNORE_TAG,
++	                              setting_name, &value)) {
++		g_object_set_data (G_OBJECT (info->connection),
++		                   NMA_CA_CERT_IGNORE_TAG,
++		                   GUINT_TO_POINTER (value));
++	}
++
++	if (nm_gconf_get_bool_helper (info->client, info->dir,
++	                              NMA_PHASE2_CA_CERT_IGNORE_TAG,
++	                              setting_name, &value)) {
++		g_object_set_data (G_OBJECT (info->connection),
++		                   NMA_PHASE2_CA_CERT_IGNORE_TAG,
++		                   GUINT_TO_POINTER (value));
++	}
++
++	/* Binary certificate and key data doesn't get stored in GConf.  Instead,
++	 * the path to the certificate gets stored in a special key and the
++	 * certificate is read and stuffed into the setting right before
++	 * the connection is sent to NM
++	 */
+ 
+-		if (nm_gconf_get_bool_helper (info->client, info->dir,
+-		                              NMA_PHASE2_CA_CERT_IGNORE_TAG,
+-		                              setting_name, &value)) {
+-			g_object_set_data (G_OBJECT (info->connection),
+-			                   NMA_PHASE2_CA_CERT_IGNORE_TAG,
+-			                   GUINT_TO_POINTER (value));
++	if (!read_one_cert (info, setting_name, NMA_PATH_CA_CERT_TAG, TRUE, &error)) {
++		/* Save the first error reading a certificate */
++		if (!info->error) {
++			info->error = error;
++			error = NULL;
+ 		}
++		g_clear_error (&error);
++	}
+ 
+-		/* Binary certificate and key data doesn't get stored in GConf.  Instead,
+-		 * the path to the certificate gets stored in a special key and the
+-		 * certificate is read and stuffed into the setting right before
+-		 * the connection is sent to NM
+-		 */
+-		read_one_cert (info, setting_name, NMA_PATH_CA_CERT_TAG);
+-		read_one_cert (info, setting_name, NMA_PATH_CLIENT_CERT_TAG);
+-		read_one_cert (info, setting_name, NMA_PATH_PRIVATE_KEY_TAG);
+-		read_one_cert (info, setting_name, NMA_PATH_PHASE2_CA_CERT_TAG);
+-		read_one_cert (info, setting_name, NMA_PATH_PHASE2_CLIENT_CERT_TAG);
+-		read_one_cert (info, setting_name, NMA_PATH_PHASE2_PRIVATE_KEY_TAG);
++	if (!read_one_cert (info, setting_name, NMA_PATH_PHASE2_CA_CERT_TAG, TRUE, &error)) {
++		/* Save the first error reading a certificate */
++		if (!info->error) {
++			info->error = error;
++			error = NULL;
++		}
++		g_clear_error (&error);
+ 	}
++
++	read_one_cert (info, setting_name, NMA_PATH_CLIENT_CERT_TAG, FALSE, NULL);
++	read_one_cert (info, setting_name, NMA_PATH_PRIVATE_KEY_TAG, FALSE, NULL);
++	read_one_cert (info, setting_name, NMA_PATH_PHASE2_CLIENT_CERT_TAG, FALSE, NULL);
++	read_one_cert (info, setting_name, NMA_PATH_PHASE2_PRIVATE_KEY_TAG, FALSE, NULL);
+ }
+ 
+ static void
+@@ -1214,24 +1240,17 @@ read_one_setting (gpointer data, gpointer user_data)
+ 
+ NMConnection *
+ nm_gconf_read_connection (GConfClient *client,
+-                          const char *dir)
++                          const char *dir,
++                          GError **error)
+ {
+ 	ReadFromGConfInfo info;
+ 	GSList *list;
+-	GError *err = NULL;
+-
+-	list = gconf_client_all_dirs (client, dir, &err);
+-	if (err) {
+-		g_warning ("Error while reading connection: %s", err->message);
+-		g_error_free (err);
+-		return NULL;
+-	}
+ 
+-	if (!list) {
+-		g_warning ("Invalid connection (empty)");
++	list = gconf_client_all_dirs (client, dir, error);
++	if (!list)
+ 		return NULL;
+-	}
+ 
++	memset (&info, 0, sizeof (info));
+ 	info.connection = nm_connection_new ();
+ 	info.client = client;
+ 	info.dir = dir;
+@@ -1240,6 +1259,21 @@ nm_gconf_read_connection (GConfClient *client,
+ 	g_slist_foreach (list, read_one_setting, &info);
+ 	g_slist_free (list);
+ 
++	if (info.error) {
++		if (error)
++			*error = info.error;
++		else {
++			g_warning ("%s: (%s) error reading connection: (%d) %s",
++			           __func__, info.dir, info.error->code, info.error->message);
++			g_clear_error (&info.error);
++		}
++
++		if (info.connection) {
++			g_object_unref (info.connection);
++			info.connection = NULL;
++		}
++	}
++
+ 	return info.connection;
+ }
+ 
+@@ -1909,6 +1943,62 @@ nm_gconf_clear_private_connection_values (NMConnection *connection)
+ 	g_object_set_data (G_OBJECT (connection), NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG, NULL);
+ }
+ 
++static gboolean
++string_compare (NMConnection *dst, NMConnection *src, const char *tag)
++{
++	const char *s1, *s2;
++
++	s1 = (const char *) g_object_get_data (G_OBJECT (src), tag);
++	s2 = (const char *) g_object_get_data (G_OBJECT (dst), tag);
++
++	if (s1 && !s2)
++		return FALSE;
++	if (!s1 && s2)
++		return FALSE;
++	if (!s1 && !s2)
++		return TRUE;
++	g_assert (s1 && s2);
++	return !strcmp (s1, s2);
++}
++
++gboolean
++nm_gconf_compare_private_connection_values (NMConnection *dst, NMConnection *src)
++{
++	gboolean val1, val2;
++
++	g_return_val_if_fail (NM_IS_CONNECTION (dst), FALSE);
++	g_return_val_if_fail (NM_IS_CONNECTION (src), FALSE);
++
++	val1 = !!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (src), NMA_CA_CERT_IGNORE_TAG));
++	val2 = !!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (dst), NMA_CA_CERT_IGNORE_TAG));
++	if (val1 != val2)
++		return FALSE;
++
++	val1 = !!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (src), NMA_PHASE2_CA_CERT_IGNORE_TAG));
++	val2 = !!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (dst), NMA_PHASE2_CA_CERT_IGNORE_TAG));
++	if (val1 != val2)
++		return FALSE;
++
++	if (!string_compare (src, dst, NMA_PATH_CLIENT_CERT_TAG))
++		return FALSE;
++	if (!string_compare (src, dst, NMA_PATH_PHASE2_CLIENT_CERT_TAG))
++		return FALSE;
++	if (!string_compare (src, dst, NMA_PATH_CA_CERT_TAG))
++		return FALSE;
++	if (!string_compare (src, dst, NMA_PATH_PHASE2_CA_CERT_TAG))
++		return FALSE;
++	if (!string_compare (src, dst, NMA_PATH_PRIVATE_KEY_TAG))
++		return FALSE;
++	if (!string_compare (src, dst, NMA_PRIVATE_KEY_PASSWORD_TAG))
++		return FALSE;
++	if (!string_compare (src, dst, NMA_PATH_PHASE2_PRIVATE_KEY_TAG))
++		return FALSE;
++	if (!string_compare (src, dst, NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG))
++		return FALSE;
++
++	return TRUE;
++}
++
+ NMConnection *
+ nm_gconf_connection_duplicate (NMConnection *connection)
+ {
+diff --git a/src/gconf-helpers/gconf-helpers.h b/src/gconf-helpers/gconf-helpers.h
+index 3653c39..99ce1ee 100644
+--- a/src/gconf-helpers/gconf-helpers.h
++++ b/src/gconf-helpers/gconf-helpers.h
+@@ -56,6 +56,7 @@ NMConnection *nm_gconf_connection_duplicate (NMConnection *connection);
+ 
+ void nm_gconf_copy_private_connection_values (NMConnection *dst, NMConnection *src);
+ void nm_gconf_clear_private_connection_values (NMConnection *connection);
++gboolean nm_gconf_compare_private_connection_values (NMConnection *dst, NMConnection *src);
+ 
+ #define KEYRING_UUID_TAG "connection-uuid"
+ #define KEYRING_SN_TAG "setting-name"
+@@ -211,7 +212,8 @@ nm_gconf_get_all_connections (GConfClient *client);
+ 
+ NMConnection *
+ nm_gconf_read_connection (GConfClient *client,
+-                          const char *dir);
++                          const char *dir,
++                          GError **error);
+ 
+ void
+ nm_gconf_write_connection (NMConnection *connection,
+diff --git a/src/gconf-helpers/nma-gconf-connection.c b/src/gconf-helpers/nma-gconf-connection.c
+index a5b65c2..648ac17 100644
+--- a/src/gconf-helpers/nma-gconf-connection.c
++++ b/src/gconf-helpers/nma-gconf-connection.c
+@@ -64,19 +64,23 @@ NMAGConfConnection *
+ nma_gconf_connection_new (GConfClient *client, const char *conf_dir)
+ {
+ 	NMConnection *connection;
+-	NMAGConfConnection *gconf_connection;
++	NMAGConfConnection *gconf_connection = NULL;
++	GError *error;
+ 
+ 	g_return_val_if_fail (GCONF_IS_CLIENT (client), NULL);
+ 	g_return_val_if_fail (conf_dir != NULL, NULL);
+ 
+ 	/* retrieve GConf data */
+-	connection = nm_gconf_read_connection (client, conf_dir);
++	connection = nm_gconf_read_connection (client, conf_dir, &error);
+ 	if (connection) {
+ 		gconf_connection = nma_gconf_connection_new_from_connection (client, conf_dir, connection);
+ 		g_object_unref (connection);
+ 	} else {
+-		nm_warning ("No connection read from GConf at %s.", conf_dir);
+-		gconf_connection = NULL;
++		g_warning ("%s: (%s) error reading connection: (%d) %s",
++		           __func__, conf_dir,
++		           error ? error->code : -1,
++		           error && error->message ? error->message : "(unknown)");
++		g_clear_error (&error);
+ 	}
+ 	
+ 	return gconf_connection;
+@@ -160,13 +164,23 @@ nma_gconf_connection_changed (NMAGConfConnection *self)
+ 	priv = NMA_GCONF_CONNECTION_GET_PRIVATE (self);
+ 	wrapped_connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (self));
+ 
+-	gconf_connection = nm_gconf_read_connection (priv->client, priv->dir);
++	gconf_connection = nm_gconf_read_connection (priv->client, priv->dir, &error);
+ 	if (!gconf_connection) {
+-		g_warning ("No connection read from GConf at %s.", priv->dir);
++		g_warning ("%s: (%s) error reading connection: (%d) %s",
++		           __func__, priv->dir,
++		           error ? error->code : -1,
++		           error && error->message ? error->message : "(unknown)");
++		goto invalid;
++	}
++
++	if (!utils_fill_connection_certs (gconf_connection, &error)) {
++		g_warning ("%s: Invalid connection %s: failed to load connection certificates: (%d) %s",
++		           __func__, priv->dir,
++		           error ? error->code : -1,
++		           error && error->message ? error->message : "(unknown)");
+ 		goto invalid;
+ 	}
+ 
+-	utils_fill_connection_certs (gconf_connection);
+ 	if (!nm_connection_verify (gconf_connection, &error)) {
+ 		utils_clear_filled_connection_certs (gconf_connection);
+ 		g_warning ("%s: Invalid connection %s: '%s' / '%s' invalid: %d",
+@@ -178,10 +192,21 @@ nma_gconf_connection_changed (NMAGConfConnection *self)
+ 	utils_clear_filled_connection_certs (gconf_connection);
+ 
+ 	/* Ignore the GConf update if nothing changed */
+-	if (nm_connection_compare (wrapped_connection, gconf_connection, NM_SETTING_COMPARE_FLAG_EXACT))
++	if (   nm_connection_compare (wrapped_connection, gconf_connection, NM_SETTING_COMPARE_FLAG_EXACT)
++	    && nm_gconf_compare_private_connection_values (wrapped_connection, gconf_connection))
+ 		return TRUE;
+ 
+-	utils_fill_connection_certs (gconf_connection);
++	/* Update private values to catch any certificate path changes */
++	nm_gconf_copy_private_connection_values (wrapped_connection, gconf_connection);
++
++	if (!utils_fill_connection_certs (gconf_connection, &error)) {
++		g_warning ("%s: Invalid connection %s: failed to load connection certificates: (%d) %s",
++		           __func__, priv->dir,
++		           error ? error->code : -1,
++		           error && error->message ? error->message : "(unknown)");
++		goto invalid;
++	}
++
+ 	new_settings = nm_connection_to_hash (gconf_connection);
+ 	utils_clear_filled_connection_certs (gconf_connection);
+ 
+@@ -218,12 +243,23 @@ invalid:
+ static GHashTable *
+ get_settings (NMExportedConnection *exported)
+ {
++	NMAGConfConnection *self = NMA_GCONF_CONNECTION (exported);
++	NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (self);
+ 	NMConnection *connection;
+ 	GHashTable *settings;
++	GError *error = NULL;
+ 
+ 	connection = nm_exported_connection_get_connection (exported);
+ 
+-	utils_fill_connection_certs (connection);
++	if (!utils_fill_connection_certs (connection, &error)) {
++		g_warning ("%s: Invalid connection %s: failed to load connection certificates: (%d) %s",
++		           __func__, priv->dir,
++		           error ? error->code : -1,
++		           error && error->message ? error->message : "(unknown)");
++		g_clear_error (&error);
++		return NULL;
++	}
++
+ 	settings = nm_connection_to_hash (connection);
+ 	utils_clear_filled_connection_certs (connection);
+ 
+@@ -516,7 +552,15 @@ constructor (GType type,
+ 
+ 	connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (object));
+ 
+-	utils_fill_connection_certs (connection);
++	if (!utils_fill_connection_certs (connection, &error)) {
++		g_warning ("%s: Invalid connection %s: failed to load connection certificates: (%d) %s",
++		           __func__, priv->dir,
++		           error ? error->code : -1,
++		           error && error->message ? error->message : "(unknown)");
++		g_clear_error (&error);
++		goto err;
++	}
++
+ 	if (!nm_connection_verify (connection, &error)) {
+ 		utils_clear_filled_connection_certs (connection);
+ 		g_warning ("Invalid connection: '%s' / '%s' invalid: %d",
+diff --git a/src/utils/utils.c b/src/utils/utils.c
+index c68c2cd..a74111d 100644
+--- a/src/utils/utils.c
++++ b/src/utils/utils.c
+@@ -23,6 +23,7 @@
+ #include <string.h>
+ #include <netinet/ether.h>
+ #include <glib.h>
++#include <glib/gi18n.h>
+ 
+ #include <nm-device-ethernet.h>
+ #include <nm-device-wifi.h>
+@@ -244,25 +245,28 @@ fill_one_private_key (NMConnection *connection,
+ 	return need_client_cert;
+ }
+ 
+-void
+-utils_fill_connection_certs (NMConnection *connection)
++gboolean
++utils_fill_connection_certs (NMConnection *connection, GError **error)
+ {
+ 	NMSetting8021x *s_8021x;
+ 	const char *filename;
+-	GError *error = NULL;
++	GError *tmp_error = NULL;
+ 	gboolean need_client_cert = TRUE;
+ 
+-	g_return_if_fail (connection != NULL);
++	g_return_val_if_fail (connection != NULL, FALSE);
+ 
+ 	s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
+ 	if (!s_8021x)
+-		return;
++		return TRUE;
+ 
+ 	filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG);
+ 	if (filename) {
+-		if (!nm_setting_802_1x_set_ca_cert_from_file (s_8021x, filename, NULL, &error))
+-			g_warning ("%s: couldn't read CA certificate: %d %s", __func__, error->code, error->message);
+-		g_clear_error (&error);
++		if (!nm_setting_802_1x_set_ca_cert_from_file (s_8021x, filename, NULL, &tmp_error)) {
++			g_set_error (error, tmp_error->domain, tmp_error->code,
++			             _("Could not read CA certificate: %s"), tmp_error->message);
++			g_clear_error (&tmp_error);
++			return FALSE;
++		}
+ 	}
+ 
+ 	/* If the private key is PKCS#12, don't set the client cert */
+@@ -273,17 +277,23 @@ utils_fill_connection_certs (NMConnection *connection)
+ 	if (need_client_cert) {
+ 		filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_CLIENT_CERT_TAG);
+ 		if (filename) {
+-			if (!nm_setting_802_1x_set_client_cert_from_file (s_8021x, filename, NULL, &error))
+-				g_warning ("%s: couldn't read client certificate: %d %s", __func__, error->code, error->message);
+-			g_clear_error (&error);
++			if (!nm_setting_802_1x_set_client_cert_from_file (s_8021x, filename, NULL, &tmp_error)) {
++				g_set_error (error, tmp_error->domain, tmp_error->code,
++				             _("Could not read client certificate: %s"), tmp_error->message);
++				g_clear_error (&tmp_error);
++				return FALSE;
++			}
+ 		}
+ 	}
+ 
+ 	filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_PHASE2_CA_CERT_TAG);
+ 	if (filename) {
+-		if (!nm_setting_802_1x_set_phase2_ca_cert_from_file (s_8021x, filename, NULL, &error))
+-			g_warning ("%s: couldn't read phase2 CA certificate: %d %s", __func__, error->code, error->message);
+-		g_clear_error (&error);
++		if (!nm_setting_802_1x_set_phase2_ca_cert_from_file (s_8021x, filename, NULL, &tmp_error)) {
++			g_set_error (error, tmp_error->domain, tmp_error->code,
++			             _("Could not read inner CA certificate: %s"), tmp_error->message);
++			g_clear_error (&tmp_error);
++			return FALSE;
++		}
+ 	}
+ 
+ 	/* If the private key is PKCS#12, don't set the client cert */
+@@ -294,11 +304,16 @@ utils_fill_connection_certs (NMConnection *connection)
+ 	if (need_client_cert) {
+ 		filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_PHASE2_CLIENT_CERT_TAG);
+ 		if (filename) {
+-			if (!nm_setting_802_1x_set_phase2_client_cert_from_file (s_8021x, filename, NULL, &error))
+-				g_warning ("%s: couldn't read phase2 client certificate: %d %s", __func__, error->code, error->message);
+-			g_clear_error (&error);
++			if (!nm_setting_802_1x_set_phase2_client_cert_from_file (s_8021x, filename, NULL, &tmp_error)) {
++				g_set_error (error, tmp_error->domain, tmp_error->code,
++				             _("Could not read inner client certificate: %s"), tmp_error->message);
++				g_clear_error (&tmp_error);
++				return FALSE;
++			}
+ 		}
+ 	}
++
++	return TRUE;
+ }
+ 
+ void
+diff --git a/src/utils/utils.h b/src/utils/utils.h
+index 9e26442..a3bf2ce 100644
+--- a/src/utils/utils.h
++++ b/src/utils/utils.h
+@@ -30,7 +30,7 @@
+ 
+ const char *utils_get_device_description (NMDevice *device);
+ 
+-void utils_fill_connection_certs (NMConnection *connection);
++gboolean utils_fill_connection_certs (NMConnection *connection, GError **error);
+ 
+ void utils_clear_filled_connection_certs (NMConnection *connection);
+ 
+-- 
+1.6.6
+

Modified: packages/unstable/network-manager-applet/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-utopia/packages/unstable/network-manager-applet/debian/patches/series?rev=3435&op=diff
==============================================================================
--- packages/unstable/network-manager-applet/debian/patches/series (original)
+++ packages/unstable/network-manager-applet/debian/patches/series Sat Jan 23 01:32:35 2010
@@ -1,3 +1,4 @@
 01-dbus_access_nm_applet.patch
 02-CVE-2009-4145_fix_leakage_of_secrets_on_system_bus.patch
+03-CVE-2009-4144_fix_ca_cert_handling_after_cert_file_deletion.patch
 04-autostart.patch




More information about the Pkg-utopia-commits mailing list