Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.1:Update
NetworkManager-gnome
nma-brc546793.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File nma-brc546793.patch of Package NetworkManager-gnome
commit 4020594dfbf566f1852f0acb36ad631a9e73a82b Author: Dan Williams <dcbw@redhat.com> Date: Fri Dec 11 15:44:03 2009 -0800 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). Index: nm-applet-0.7.0/src/applet-device-wifi.c =================================================================== --- nm-applet-0.7.0.orig/src/applet-device-wifi.c +++ nm-applet-0.7.0/src/applet-device-wifi.c @@ -1455,6 +1455,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); @@ -1462,7 +1463,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); Index: nm-applet-0.7.0/src/applet-device-wired.c =================================================================== --- nm-applet-0.7.0.orig/src/applet-device-wired.c +++ nm-applet-0.7.0/src/applet-device-wired.c @@ -651,7 +651,18 @@ get_8021x_secrets_cb (GtkDialog *dialog, goto done; } + 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 (connection); + if (!secrets) { g_set_error (&err, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INTERNAL_ERROR, "%s.%d (%s): failed to hash setting '%s'.", @@ -659,9 +670,6 @@ get_8021x_secrets_cb (GtkDialog *dialog, goto done; } - utils_fill_connection_certs (connection); - utils_clear_filled_connection_certs (connection); - /* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that * will contain all the individual settings hashes. */ Index: nm-applet-0.7.0/src/connection-editor/nm-connection-list.c =================================================================== --- nm-applet-0.7.0.orig/src/connection-editor/nm-connection-list.c +++ nm-applet-0.7.0/src/connection-editor/nm-connection-list.c @@ -490,14 +490,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; @@ -669,16 +670,18 @@ update_connection (NMConnectionList *lis gboolean success; gboolean pending_auth = FALSE; - utils_fill_connection_certs (modified); - new_settings = nm_connection_to_hash (modified); + success = utils_fill_connection_certs (modified, &error); + if (success) { + new_settings = nm_connection_to_hash (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); + /* 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); + } if (!success) { if (is_permission_denied_error (error)) @@ -1018,19 +1021,28 @@ edit_done_cb (NMConnectionEditor *editor connection = nm_connection_editor_get_connection (editor); - utils_fill_connection_certs (connection); - success = nm_connection_verify (connection, &error); - utils_clear_filled_connection_certs (connection); - - if (success) { - update_connection (info->list, editor, info->original_connection, - connection, connection_updated_cb, info); + success = utils_fill_connection_certs (connection, &error); + if (!success) { + g_warning ("%s: error completing connection edit: (%d) %s", + __func__, + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); } else { - g_warning ("%s: invalid connection after update: bug in the " - "'%s' / '%s' invalid: %d", - __func__, - g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), - error->message, error->code); + success = nm_connection_verify (connection, &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 (error->domain)), + error->message, error->code); + } + } + + if (!success) { g_error_free (error); connection_updated_cb (info->list, FALSE, user_data); } Index: nm-applet-0.7.0/src/gconf-helpers/gconf-helpers.c =================================================================== --- nm-applet-0.7.0.orig/src/gconf-helpers/gconf-helpers.c +++ nm-applet-0.7.0/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> @@ -975,6 +976,7 @@ typedef struct ReadFromGConfInfo { GConfClient *client; const char *dir; guint32 dir_len; + GError *error; } ReadFromGConfInfo; static void @@ -1120,57 +1122,82 @@ read_one_setting_value_from_gconf (NMSet } } -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); + } + return TRUE; - g_object_set_data_full (G_OBJECT (info->connection), - key, value, - (GDestroyNotify) g_free); } 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; + 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 (!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); + } - 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 - */ - 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 @@ -1197,24 +1224,17 @@ read_one_setting (gpointer data, gpointe 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); + list = gconf_client_all_dirs (client, dir, error); + if (!list) return NULL; - } - - if (!list) { - g_warning ("Invalid connection (empty)"); - return NULL; - } + memset (&info, 0, sizeof (info)); info.connection = nm_connection_new (); info.client = client; info.dir = dir; @@ -1223,6 +1243,21 @@ nm_gconf_read_connection (GConfClient *c 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; } Index: nm-applet-0.7.0/src/gconf-helpers/gconf-helpers.h =================================================================== --- nm-applet-0.7.0.orig/src/gconf-helpers/gconf-helpers.h +++ nm-applet-0.7.0/src/gconf-helpers/gconf-helpers.h @@ -204,7 +204,8 @@ nm_gconf_get_all_connections (GConfClien NMConnection * nm_gconf_read_connection (GConfClient *client, - const char *dir); + const char *dir, + GError **error); void nm_gconf_write_connection (NMConnection *connection, Index: nm-applet-0.7.0/src/gconf-helpers/nma-gconf-connection.c =================================================================== --- nm-applet-0.7.0.orig/src/gconf-helpers/nma-gconf-connection.c +++ nm-applet-0.7.0/src/gconf-helpers/nma-gconf-connection.c @@ -45,19 +45,23 @@ NMAGConfConnection * nma_gconf_connection_new (GConfClient *client, const char *conf_dir) { NMConnection *connection; - NMAGConfConnection *gconf_connection; + NMAGConfConnection *gconf_connection = NULL; + GError *error = NULL; 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; @@ -136,13 +140,23 @@ nma_gconf_connection_changed (NMAGConfCo 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", @@ -157,7 +171,14 @@ nma_gconf_connection_changed (NMAGConfCo if (nm_connection_compare (wrapped_connection, gconf_connection, NM_SETTING_COMPARE_FLAG_EXACT)) return TRUE; - utils_fill_connection_certs (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); @@ -194,12 +215,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); @@ -494,7 +526,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", Index: nm-applet-0.7.0/src/utils/utils.c =================================================================== --- nm-applet-0.7.0.orig/src/utils/utils.c +++ nm-applet-0.7.0/src/utils/utils.c @@ -24,6 +24,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> @@ -271,25 +272,28 @@ fill_one_private_key (NMConnection *conn 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 */ @@ -300,17 +304,23 @@ utils_fill_connection_certs (NMConnectio 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 */ @@ -321,11 +331,16 @@ utils_fill_connection_certs (NMConnectio 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 Index: nm-applet-0.7.0/src/utils/utils.h =================================================================== --- nm-applet-0.7.0.orig/src/utils/utils.h +++ nm-applet-0.7.0/src/utils/utils.h @@ -32,7 +32,7 @@ char * utils_bin2hexstr (const char *byt 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);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor