[network-manager-applet/cert-paths: 8/8] core: update to work with certificate paths
- From: Dan Williams <dcbw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [network-manager-applet/cert-paths: 8/8] core: update to work with certificate paths
- Date: Wed, 16 Sep 2009 21:36:08 +0000 (UTC)
commit b16d8acaeaf3771c953439022300cca41865aaae
Author: Dan Williams <dcbw redhat com>
Date: Wed Sep 16 14:30:02 2009 -0700
core: update to work with certificate paths
Don't store the certificate/key paths in lookaside variables, just use
the normal key/value pairs in the 802.1x setting.
Since (for backwards compat) NM treats the private key as a secret, we
need to do a few odd things like retrieving the private key paths from
GConf when getting secrets from the keyring.
Also, since the private keys and certificate properties are byte arrays,
it's a slight bit more complicated to load/store them to GConf, requiring
a bit of indirection in read_one_setting_value_from_gconf() and
copy_one_setting_value_to_gconf(). Especially for
copy_one_setting_value_to_gconf() since the incoming certificate may
just be a byte array of the cert/key data from some older plugin or
settings service, and thus we need to copy that cert data to a file
on-disk and possibly re-encrypt a decrypted private key too.
src/applet-device-wifi.c | 3 -
src/applet-device-wired.c | 21 -
src/applet.c | 3 +
src/connection-editor/nm-connection-list.c | 15 +-
src/connection-editor/page-dsl.c | 16 -
src/connection-editor/page-mobile.c | 50 --
src/connection-editor/page-wired-security.c | 2 -
src/connection-editor/page-wireless-security.c | 1 -
src/gconf-helpers/gconf-helpers.c | 950 ++++++++++++------------
src/gconf-helpers/gconf-helpers.h | 36 +-
src/gconf-helpers/gconf-upgrade.c | 159 ++++
src/gconf-helpers/gconf-upgrade.h | 4 +
src/gconf-helpers/nma-gconf-connection.c | 233 ++++++-
src/gconf-helpers/nma-gconf-settings.c | 2 +
src/utils/utils.c | 136 ----
src/utils/utils.h | 4 -
src/wireless-dialog.c | 10 +-
src/wireless-security/eap-method-peap.c | 39 +-
src/wireless-security/eap-method-tls.c | 176 +++---
src/wireless-security/eap-method-ttls.c | 39 +-
src/wireless-security/eap-method.c | 31 +-
src/wireless-security/eap-method.h | 5 +-
22 files changed, 1038 insertions(+), 897 deletions(-)
---
diff --git a/src/applet-device-wifi.c b/src/applet-device-wifi.c
index 180337f..e6e105a 100644
--- a/src/applet-device-wifi.c
+++ b/src/applet-device-wifi.c
@@ -1485,10 +1485,7 @@ 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);
secrets = nm_setting_to_hash (setting);
- utils_clear_filled_connection_certs (connection);
-
if (secrets) {
g_hash_table_insert (settings, g_strdup (nm_setting_get_name (setting)), secrets);
} else {
diff --git a/src/applet-device-wired.c b/src/applet-device-wired.c
index dc24051..e6212ab 100644
--- a/src/applet-device-wired.c
+++ b/src/applet-device-wired.c
@@ -389,24 +389,6 @@ pppoe_update_ui (NMConnection *connection, NMPppoeInfo *info)
s = nm_setting_pppoe_get_password (s_pppoe);
if (s)
gtk_entry_set_text (info->password_entry, s);
- else {
- GHashTable *secrets;
- GError *error = NULL;
- GValue *value;
-
- /* Grab password from keyring if possible */
- secrets = nm_gconf_get_keyring_items (connection,
- nm_setting_get_name (NM_SETTING (s_pppoe)),
- FALSE,
- &error);
- if (secrets) {
- value = g_hash_table_lookup (secrets, NM_SETTING_PPPOE_PASSWORD);
- if (value)
- gtk_entry_set_text (info->password_entry, g_value_get_string (value));
- g_hash_table_destroy (secrets);
- } else if (error)
- g_error_free (error);
- }
}
static NMPppoeInfo *
@@ -672,10 +654,7 @@ get_8021x_secrets_cb (GtkDialog *dialog,
goto done;
}
- utils_fill_connection_certs (NM_CONNECTION (connection));
secrets = nm_setting_to_hash (setting);
- utils_clear_filled_connection_certs (NM_CONNECTION (connection));
-
if (!secrets) {
g_set_error (&error,
NM_SETTINGS_INTERFACE_ERROR,
diff --git a/src/applet.c b/src/applet.c
index b354c68..f44e684 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -2192,6 +2192,9 @@ applet_settings_new_secrets_requested_cb (NMAGConfSettings *settings,
goto error;
}
+ // FIXME: get secrets locally and populate connection with previous secrets
+ // before asking user for other secrets
+
/* Let the device class handle secrets */
if (dclass->get_secrets (device, NM_SETTINGS_CONNECTION_INTERFACE (connection),
active_connection, setting_name, hints, callback,
diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
index 62d6bdf..ba2ff4b 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -332,9 +332,6 @@ delete_cb (NMSettingsConnectionInterface *connection_iface,
NMVpnPluginUiInterface *plugin;
GError *vpn_error = NULL;
- /* Clean up keyring keys */
- nm_gconf_clear_keyring_items (connection);
-
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
@@ -440,9 +437,7 @@ add_connection (NMConnectionList *self,
else
g_assert_not_reached ();
- utils_fill_connection_certs (connection);
nm_settings_interface_add_connection (settings, connection, add_cb, info);
- utils_clear_filled_connection_certs (connection);
}
/**********************************************/
@@ -543,10 +538,7 @@ update_connection (NMConnectionList *list,
* and private keys don't go through D-Bus; they are private of course!
*/
if (new_scope == NM_CONNECTION_SCOPE_SYSTEM) {
- utils_fill_connection_certs (NM_CONNECTION (connection));
new_settings = nm_connection_to_hash (NM_CONNECTION (connection));
- utils_clear_filled_connection_certs (NM_CONNECTION (connection));
-
if (!nm_connection_replace_settings (NM_CONNECTION (connection),
new_settings,
&error)) {
@@ -713,7 +705,6 @@ edit_done_cb (NMConnectionEditor *editor, gint response, GError *error, gpointer
const char *message = _("An unknown error ocurred.");
NMConnection *connection;
GError *edit_error = NULL;
- gboolean success;
connection = nm_connection_editor_get_connection (editor);
g_assert (connection);
@@ -721,11 +712,7 @@ edit_done_cb (NMConnectionEditor *editor, gint response, GError *error, gpointer
switch (response) {
case GTK_RESPONSE_OK:
/* Make sure the connection is valid */
- utils_fill_connection_certs (connection);
- success = nm_connection_verify (connection, &edit_error);
- utils_clear_filled_connection_certs (connection);
-
- if (success) {
+ if (nm_connection_verify (connection, &edit_error)) {
/* Save the connection to backing storage */
update_connection (info->list,
editor,
diff --git a/src/connection-editor/page-dsl.c b/src/connection-editor/page-dsl.c
index 0de10c6..92a49b9 100644
--- a/src/connection-editor/page-dsl.c
+++ b/src/connection-editor/page-dsl.c
@@ -75,22 +75,6 @@ populate_ui (CEPageDsl *self, NMConnection *connection)
/* Grab password from keyring if possible */
str = nm_setting_pppoe_get_password (setting);
- if (!str) {
- GError *error = NULL;
- GValue *value;
-
- secrets = nm_gconf_get_keyring_items (connection,
- nm_setting_get_name (NM_SETTING (setting)),
- FALSE,
- &error);
- if (secrets) {
- value = g_hash_table_lookup (secrets, NM_SETTING_PPPOE_PASSWORD);
- if (value)
- str = g_value_get_string (value);
- } else if (error)
- g_error_free (error);
- }
-
if (str)
gtk_entry_set_text (priv->password, str);
diff --git a/src/connection-editor/page-mobile.c b/src/connection-editor/page-mobile.c
index 1789765..43ec4d1 100644
--- a/src/connection-editor/page-mobile.c
+++ b/src/connection-editor/page-mobile.c
@@ -93,30 +93,12 @@ mobile_private_init (CEPageMobile *self)
priv->window_group = gtk_window_group_new ();
}
-static GHashTable *
-get_secrets (NMConnection *connection, const char *setting_name)
-{
- GError *error = NULL;
- GHashTable *secrets;
-
- secrets = nm_gconf_get_keyring_items (connection,
- setting_name,
- FALSE,
- &error);
- if (!secrets && error)
- g_error_free (error);
-
- return secrets;
-}
-
static void
populate_gsm_ui (CEPageMobile *self, NMConnection *connection)
{
CEPageMobilePrivate *priv = CE_PAGE_MOBILE_GET_PRIVATE (self);
NMSettingGsm *setting = NM_SETTING_GSM (priv->setting);
int type_idx;
- GHashTable *secrets;
- GValue *value;
GtkWidget *widget;
const char *s;
@@ -167,37 +149,17 @@ populate_gsm_ui (CEPageMobile *self, NMConnection *connection)
widget = glade_xml_get_widget (CE_PAGE (self)->xml, "band_label");
gtk_widget_hide (widget);
- secrets = get_secrets (connection, nm_setting_get_name (priv->setting));
-
s = nm_setting_gsm_get_password (setting);
if (s)
gtk_entry_set_text (priv->password, s);
- else if (secrets) {
- value = g_hash_table_lookup (secrets, NM_SETTING_GSM_PASSWORD);
- if (value)
- gtk_entry_set_text (priv->password, g_value_get_string (value));
- }
s = nm_setting_gsm_get_pin (setting);
if (s)
gtk_entry_set_text (priv->pin, s);
- else if (secrets) {
- value = g_hash_table_lookup (secrets, NM_SETTING_GSM_PIN);
- if (value)
- gtk_entry_set_text (priv->pin, g_value_get_string (value));
- }
s = nm_setting_gsm_get_puk (setting);
if (s)
gtk_entry_set_text (priv->pin, s);
- else if (secrets) {
- value = g_hash_table_lookup (secrets, NM_SETTING_GSM_PUK);
- if (value)
- gtk_entry_set_text (priv->puk, g_value_get_string (value));
- }
-
- if (secrets)
- g_hash_table_destroy (secrets);
}
static void
@@ -205,8 +167,6 @@ populate_cdma_ui (CEPageMobile *self, NMConnection *connection)
{
CEPageMobilePrivate *priv = CE_PAGE_MOBILE_GET_PRIVATE (self);
NMSettingCdma *setting = NM_SETTING_CDMA (priv->setting);
- GHashTable *secrets;
- GValue *value;
const char *s;
s = nm_setting_cdma_get_number (setting);
@@ -217,19 +177,9 @@ populate_cdma_ui (CEPageMobile *self, NMConnection *connection)
if (s)
gtk_entry_set_text (priv->username, s);
- secrets = get_secrets (connection, nm_setting_get_name (priv->setting));
-
s = nm_setting_cdma_get_password (setting);
if (s)
gtk_entry_set_text (priv->password, s);
- else if (secrets) {
- value = g_hash_table_lookup (secrets, NM_SETTING_CDMA_PASSWORD);
- if (value)
- gtk_entry_set_text (priv->password, g_value_get_string (value));
- }
-
- if (secrets)
- g_hash_table_destroy (secrets);
/* Hide GSM specific widgets */
gtk_widget_hide (glade_xml_get_widget (CE_PAGE (self)->xml, "mobile_basic_label"));
diff --git a/src/connection-editor/page-wired-security.c b/src/connection-editor/page-wired-security.c
index a1db027..492fbe7 100644
--- a/src/connection-editor/page-wired-security.c
+++ b/src/connection-editor/page-wired-security.c
@@ -150,14 +150,12 @@ validate (CEPage *page, NMConnection *connection, GError **error)
s_8021x = nm_connection_get_setting (tmp_connection, NM_TYPE_SETTING_802_1X);
nm_connection_add_setting (connection, NM_SETTING (g_object_ref (s_8021x)));
- nm_gconf_copy_private_connection_values (connection, tmp_connection);
g_object_unref (tmp_connection);
} else
g_set_error (error, 0, 0, "Invalid 802.1x security");
} else {
nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X);
- nm_gconf_clear_private_connection_values (connection);
valid = TRUE;
}
diff --git a/src/connection-editor/page-wireless-security.c b/src/connection-editor/page-wireless-security.c
index 36aaa84..51a1a72 100644
--- a/src/connection-editor/page-wireless-security.c
+++ b/src/connection-editor/page-wireless-security.c
@@ -468,7 +468,6 @@ validate (CEPage *page, NMConnection *connection, GError **error)
g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NULL, NULL);
nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X);
- nm_gconf_clear_private_connection_values (connection);
valid = TRUE;
}
diff --git a/src/gconf-helpers/gconf-helpers.c b/src/gconf-helpers/gconf-helpers.c
index 3a8c2c1..a299ccc 100644
--- a/src/gconf-helpers/gconf-helpers.c
+++ b/src/gconf-helpers/gconf-helpers.c
@@ -17,7 +17,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * (C) Copyright 2005 - 2008 Red Hat, Inc.
+ * (C) Copyright 2005 - 2009 Red Hat, Inc.
*/
#include <string.h>
@@ -27,11 +27,15 @@
#include <netinet/ether.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
#include <gconf/gconf.h>
#include <gconf/gconf-client.h>
#include <glib.h>
#include <gnome-keyring.h>
#include <dbus/dbus-glib.h>
+
#include <nm-setting-bluetooth.h>
#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
@@ -46,6 +50,7 @@
#include "gconf-helpers.h"
#include "gconf-upgrade.h"
#include "utils.h"
+#include "applet.h"
#define DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH))
#define DBUS_TYPE_G_ARRAY_OF_STRING (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING))
@@ -61,7 +66,7 @@
#define DBUS_TYPE_G_IP6_ROUTE (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
#define DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_IP6_ROUTE))
-const char *applet_8021x_ignore_keys[] = {
+const char *applet_8021x_cert_keys[] = {
"ca-cert",
"client-cert",
"private-key",
@@ -87,7 +92,7 @@ nm_gconf_set_pre_keyring_callback (PreKeyringCallback func, gpointer user_data)
pre_keyring_user_data = user_data;
}
-static void
+void
pre_keyring_callback (void)
{
GnomeKeyringInfo *info = NULL;
@@ -1516,6 +1521,9 @@ nm_gconf_get_all_connections (GConfClient *client)
nm_gconf_migrate_0_7_autoconnect_default (client);
}
+ nm_gconf_migrate_0_7_ca_cert_ignore (client);
+ nm_gconf_migrate_0_7_certs (client);
+
connections = gconf_client_all_dirs (client, GCONF_PATH_CONNECTIONS, NULL);
if (!connections) {
nm_gconf_migrate_0_6_connections (client);
@@ -1566,6 +1574,8 @@ typedef struct ReadFromGConfInfo {
guint32 dir_len;
} ReadFromGConfInfo;
+#define FILE_TAG "file://"
+
static void
read_one_setting_value_from_gconf (NMSetting *setting,
const char *key,
@@ -1584,7 +1594,8 @@ read_one_setting_value_from_gconf (NMSetting *setting,
return;
/* Secrets don't get stored in GConf */
- if (flags & NM_SETTING_PARAM_SECRET)
+ if ( (flags & NM_SETTING_PARAM_SECRET)
+ && !(NM_IS_SETTING_802_1X (setting) && string_in_list (key, applet_8021x_cert_keys)))
return;
/* Don't read the NMSettingConnection object's 'read-only' property */
@@ -1597,15 +1608,32 @@ read_one_setting_value_from_gconf (NMSetting *setting,
/* Some keys (like certs) aren't read directly from GConf but are handled
* separately.
*/
- if (NM_IS_SETTING_802_1X (setting)) {
- if (string_in_list (key, applet_8021x_ignore_keys))
- return;
- } else if (NM_IS_SETTING_VPN (setting)) {
+ /* Some VPN keys are ignored */
+ if (NM_IS_SETTING_VPN (setting)) {
if (string_in_list (key, vpn_ignore_keys))
return;
}
- if (type == G_TYPE_STRING) {
+ if ( NM_IS_SETTING_802_1X (setting)
+ && string_in_list (key, applet_8021x_cert_keys)
+ && (type == DBUS_TYPE_G_UCHAR_ARRAY)) {
+ char *str_val = NULL;
+
+ /* Certificate/key paths are stored as paths in GConf, but we need to
+ * take that path and use the special functions to set them on the
+ * setting.
+ */
+ if (nm_gconf_get_string_helper (info->client, info->dir, key, setting_name, &str_val)) {
+ GByteArray *ba_val;
+
+ ba_val = g_byte_array_sized_new (strlen (FILE_TAG) + strlen (str_val) + 1);
+ g_byte_array_append (ba_val, (const guint8 *) FILE_TAG, strlen (FILE_TAG));
+ g_byte_array_append (ba_val, (const guint8 *) str_val, strlen (str_val) + 1); /* +1 for the trailing NULL */
+ g_object_set (setting, key, ba_val, NULL);
+ g_byte_array_free (ba_val, TRUE);
+ g_free (str_val);
+ }
+ } else if (type == G_TYPE_STRING) {
char *str_val = NULL;
if (nm_gconf_get_string_helper (info->client, info->dir, key, setting_name, &str_val)) {
@@ -1739,59 +1767,6 @@ read_one_setting_value_from_gconf (NMSetting *setting,
}
static void
-read_one_cert (ReadFromGConfInfo *info,
- const char *setting_name,
- const char *key)
-{
- char *value = NULL;
-
- if (!nm_gconf_get_string_helper (info->client, info->dir, key, setting_name, &value))
- return;
-
- 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;
-
- 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);
- }
-}
-
-static void
read_one_setting (gpointer data, gpointer user_data)
{
char *name;
@@ -1806,7 +1781,6 @@ read_one_setting (gpointer data, gpointer user_data)
nm_setting_enumerate_values (setting,
read_one_setting_value_from_gconf,
info);
- read_applet_private_values_from_gconf (setting, info);
nm_connection_add_setting (info->connection, setting);
}
@@ -1912,7 +1886,9 @@ write_one_secret_to_keyring (NMSetting *setting,
const char *secret;
const char *setting_name;
- if (!(flags & NM_SETTING_PARAM_SECRET))
+ /* non-secrets and private key paths don't get stored in the keyring */
+ if ( !(flags & NM_SETTING_PARAM_SECRET)
+ || (NM_IS_SETTING_802_1X (setting) && string_in_list (key, applet_8021x_cert_keys)))
return;
setting_name = nm_setting_get_name (setting);
@@ -1939,6 +1915,391 @@ write_one_secret_to_keyring (NMSetting *setting,
}
}
+static gboolean
+write_secret_file (const char *path,
+ const char *data,
+ gsize len,
+ GError **error)
+{
+ char *tmppath;
+ int fd = -1, written;
+ gboolean success = FALSE;
+
+ tmppath = g_malloc0 (strlen (path) + 10);
+ if (!tmppath) {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR, 0,
+ "Could not allocate memory for temporary file for '%s'",
+ path);
+ return FALSE;
+ }
+
+ memcpy (tmppath, path, strlen (path));
+ strcat (tmppath, ".XXXXXX");
+
+ errno = 0;
+ fd = mkstemp (tmppath);
+ if (fd < 0) {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR, 0,
+ "Could not create temporary file for '%s': %d",
+ path, errno);
+ goto out;
+ }
+
+ /* Only readable by root */
+ errno = 0;
+ if (fchmod (fd, S_IRUSR | S_IWUSR)) {
+ close (fd);
+ unlink (tmppath);
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR, 0,
+ "Could not set permissions for temporary file '%s': %d",
+ path, errno);
+ goto out;
+ }
+
+ errno = 0;
+ written = write (fd, data, len);
+ if (written != len) {
+ close (fd);
+ unlink (tmppath);
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR, 0,
+ "Could not write temporary file for '%s': %d",
+ path, errno);
+ goto out;
+ }
+ close (fd);
+
+ /* Try to rename */
+ errno = 0;
+ if (rename (tmppath, path)) {
+ unlink (tmppath);
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR, 0,
+ "Could not rename temporary file to '%s': %d",
+ path, errno);
+ goto out;
+ }
+ success = TRUE;
+
+out:
+ return success;
+}
+
+typedef NMSetting8021xCKScheme (*SchemeFunc) (NMSetting8021x *setting);
+typedef const char * (*PathFunc) (NMSetting8021x *setting);
+typedef const GByteArray * (*BlobFunc) (NMSetting8021x *setting);
+typedef NMSetting8021xCKFormat (*FormatFunc) (NMSetting8021x *setting);
+typedef const char * (*PasswordFunc)(NMSetting8021x *setting);
+
+typedef struct ObjectType {
+ const char *setting_key;
+ gboolean p12_type;
+ SchemeFunc scheme_func;
+ PathFunc path_func;
+ BlobFunc blob_func;
+ FormatFunc format_func;
+ PasswordFunc password_func;
+ const char *privkey_password_key;
+ const char *suffix;
+} ObjectType;
+
+static const ObjectType ca_type = {
+ NM_SETTING_802_1X_CA_CERT,
+ FALSE,
+ nm_setting_802_1x_get_ca_cert_scheme,
+ nm_setting_802_1x_get_ca_cert_path,
+ nm_setting_802_1x_get_ca_cert_blob,
+ NULL,
+ NULL,
+ NULL,
+ "ca-cert.der"
+};
+
+static const ObjectType phase2_ca_type = {
+ NM_SETTING_802_1X_PHASE2_CA_CERT,
+ FALSE,
+ nm_setting_802_1x_get_phase2_ca_cert_scheme,
+ nm_setting_802_1x_get_phase2_ca_cert_path,
+ nm_setting_802_1x_get_phase2_ca_cert_blob,
+ NULL,
+ NULL,
+ NULL,
+ "inner-ca-cert.der"
+};
+
+static const ObjectType client_type = {
+ NM_SETTING_802_1X_CLIENT_CERT,
+ FALSE,
+ nm_setting_802_1x_get_client_cert_scheme,
+ nm_setting_802_1x_get_client_cert_path,
+ nm_setting_802_1x_get_client_cert_blob,
+ NULL,
+ NULL,
+ NULL,
+ "client-cert.der"
+};
+
+static const ObjectType phase2_client_type = {
+ NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
+ FALSE,
+ nm_setting_802_1x_get_phase2_client_cert_scheme,
+ nm_setting_802_1x_get_phase2_client_cert_path,
+ nm_setting_802_1x_get_phase2_client_cert_blob,
+ NULL,
+ NULL,
+ NULL,
+ "inner-client-cert.der"
+};
+
+static const ObjectType pk_type = {
+ NM_SETTING_802_1X_PRIVATE_KEY,
+ FALSE,
+ nm_setting_802_1x_get_private_key_scheme,
+ nm_setting_802_1x_get_private_key_path,
+ nm_setting_802_1x_get_private_key_blob,
+ nm_setting_802_1x_get_private_key_format,
+ nm_setting_802_1x_get_private_key_password,
+ NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD,
+ "private-key.pem"
+};
+
+static const ObjectType phase2_pk_type = {
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ FALSE,
+ nm_setting_802_1x_get_phase2_private_key_scheme,
+ nm_setting_802_1x_get_phase2_private_key_path,
+ nm_setting_802_1x_get_phase2_private_key_blob,
+ nm_setting_802_1x_get_phase2_private_key_format,
+ nm_setting_802_1x_get_phase2_private_key_password,
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD,
+ "inner-private-key.pem"
+};
+
+static const ObjectType p12_type = {
+ NM_SETTING_802_1X_PRIVATE_KEY,
+ TRUE,
+ nm_setting_802_1x_get_private_key_scheme,
+ nm_setting_802_1x_get_private_key_path,
+ nm_setting_802_1x_get_private_key_blob,
+ nm_setting_802_1x_get_private_key_format,
+ nm_setting_802_1x_get_private_key_password,
+ NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD,
+ "private-key.p12"
+};
+
+static const ObjectType phase2_p12_type = {
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ TRUE,
+ nm_setting_802_1x_get_phase2_private_key_scheme,
+ nm_setting_802_1x_get_phase2_private_key_path,
+ nm_setting_802_1x_get_phase2_private_key_blob,
+ nm_setting_802_1x_get_phase2_private_key_format,
+ nm_setting_802_1x_get_phase2_private_key_password,
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD,
+ "inner-private-key.p12"
+};
+
+static char *
+generate_cert_path (const char *id, const char *suffix)
+{
+ return g_strdup_printf ("%s/.ssh/%s-%s", g_get_home_dir (), id, suffix);
+}
+
+static gboolean
+write_object (GConfClient *client,
+ const char *dir,
+ const char *id,
+ NMSetting8021x *s_8021x,
+ const GByteArray *override_data,
+ const ObjectType *objtype,
+ GError **error)
+{
+ NMSetting8021xCKScheme scheme;
+ const char *path = NULL;
+ const GByteArray *blob = NULL;
+ const char *setting_name = nm_setting_get_name (NM_SETTING (s_8021x));
+
+ g_return_val_if_fail (objtype != NULL, FALSE);
+
+ if (override_data) {
+ /* if given explicit data to save, always use that instead of asking
+ * the setting what to do.
+ */
+ blob = override_data;
+ } else {
+ scheme = (*(objtype->scheme_func))(s_8021x);
+ switch (scheme) {
+ case NM_SETTING_802_1X_CK_SCHEME_BLOB:
+ blob = (*(objtype->blob_func))(s_8021x);
+ break;
+ case NM_SETTING_802_1X_CK_SCHEME_PATH:
+ path = (*(objtype->path_func))(s_8021x);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* If certificate/private key wasn't sent, the connection may no longer be
+ * 802.1x and thus we clear out the paths and certs.
+ */
+ if (!path && !blob) {
+ char *standard_file;
+ int ignored;
+
+ /* Since no cert/private key is now being used, delete any standard file
+ * that was created for this connection, but leave other files alone.
+ * Thus, for example, ~/.ssh/My Company Network-ca-cert.der will be
+ * deleted, but /etc/pki/tls/cert.pem would not.
+ */
+ standard_file = generate_cert_path (id, objtype->suffix);
+ if (g_file_test (standard_file, G_FILE_TEST_EXISTS))
+ ignored = unlink (standard_file);
+ g_free (standard_file);
+
+ /* Delete the key from GConf */
+ nm_gconf_set_string_helper (client, dir, objtype->setting_key, setting_name, NULL);
+ return TRUE;
+ }
+
+ /* If the object path was specified, prefer that over any raw cert data that
+ * may have been sent.
+ */
+ if (path) {
+ nm_gconf_set_string_helper (client, dir, objtype->setting_key, setting_name, path);
+ return TRUE;
+ }
+
+ /* If it's raw certificate data, write the cert data out to the standard file */
+ if (blob) {
+ gboolean success;
+ char *new_file;
+ GError *write_error = NULL;
+
+ new_file = generate_cert_path (id, objtype->suffix);
+ if (!new_file) {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR, 0,
+ "Could not create file path for %s / %s",
+ setting_name, objtype->setting_key);
+ return FALSE;
+ }
+
+ /* Write the raw certificate data out to the standard file so that we
+ * can use paths from now on instead of pushing around the certificate
+ * data itself.
+ */
+ success = write_secret_file (new_file, (const char *) blob->data, blob->len, &write_error);
+ if (success) {
+ nm_gconf_set_string_helper (client, dir, objtype->setting_key, setting_name, new_file);
+ return TRUE;
+ } else {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR, 0,
+ "Could not write certificate/key for %s / %s: %s",
+ setting_name, objtype->setting_key,
+ (write_error && write_error->message) ? write_error->message : "(unknown)");
+ g_clear_error (&write_error);
+ }
+ g_free (new_file);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+write_one_certificate (GConfClient *client,
+ const char *dir,
+ const char *key,
+ NMSetting8021x *s_8021x,
+ NMConnection *connection,
+ GError **error)
+{
+ const char *id;
+ NMSettingConnection *s_con;
+ const ObjectType *cert_objects[] = {
+ &ca_type,
+ &phase2_ca_type,
+ &client_type,
+ &phase2_client_type,
+ &pk_type,
+ &phase2_pk_type,
+ &p12_type,
+ &phase2_p12_type,
+ NULL
+ };
+ const ObjectType **obj = &cert_objects[0];
+ gboolean handled = FALSE, success = FALSE;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+ id = nm_setting_connection_get_id (s_con);
+ g_assert (id);
+
+ while (*obj && !handled) {
+ const GByteArray *blob = NULL;
+ GByteArray *enc_key = NULL;
+
+ if (strcmp (key, (*obj)->setting_key)) {
+ obj++;
+ continue;
+ }
+
+ /* Check for pkcs#12 format private keys; if the current ObjectType
+ * structure isn't for a pkcs#12 key but the key actually is
+ * pkcs#12, keep going to get the right pkcs#12 ObjectType.
+ */
+ if ( (*obj)->format_func
+ && ((*obj)->format_func (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
+ && !(*obj)->p12_type) {
+ obj++;
+ continue;
+ }
+
+ if ((*obj)->scheme_func (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_BLOB)
+ blob = (*obj)->blob_func (s_8021x);
+
+ /* Only do the private key re-encrypt dance if we got the raw key data, which
+ * by definition will be unencrypted. If we're given a direct path to the
+ * private key file, it'll be encrypted, so we don't need to re-encrypt.
+ */
+ if (blob && !(*obj)->p12_type) {
+ const char *password;
+ char *generated_pw;
+
+ /* If the private key is an unencrypted blob, re-encrypt it with a
+ * random password since we don't store unencrypted private keys on disk.
+ */
+ password = (*obj)->password_func (s_8021x);
+
+ /* Encrypt the unencrypted private key */
+ enc_key = nm_utils_rsa_key_encrypt (blob, password, &generated_pw, error);
+ if (!enc_key)
+ goto out;
+
+ /* Save any generated private key back into the 802.1x setting so
+ * it'll get stored when secrets are written to the keyring.
+ */
+ if (generated_pw) {
+ g_object_set (G_OBJECT (s_8021x), (*obj)->privkey_password_key, generated_pw, NULL);
+ memset (generated_pw, 0, strlen (generated_pw));
+ g_free (generated_pw);
+ }
+ }
+
+ success = write_object (client, dir, id, s_8021x, enc_key ? enc_key : blob, *obj, error);
+ if (enc_key)
+ g_byte_array_free (enc_key, TRUE);
+
+ handled = TRUE;
+ }
+
+ if (!handled) {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR, 0,
+ "Unhandled certificate/private-key item '%s'",
+ key);
+ }
+
+out:
+ return success;
+}
+
static void
copy_one_setting_value_to_gconf (NMSetting *setting,
const char *key,
@@ -1951,19 +2312,19 @@ copy_one_setting_value_to_gconf (NMSetting *setting,
GType type = G_VALUE_TYPE (value);
GParamSpec *pspec;
- /* Some keys (like certs) aren't written directly to GConf but are handled
- * separately.
- */
- if (NM_IS_SETTING_802_1X (setting)) {
- if (string_in_list (key, applet_8021x_ignore_keys))
- return;
- } else if (NM_IS_SETTING_VPN (setting)) {
+ /* Some VPN keys are ignored */
+ if (NM_IS_SETTING_VPN (setting)) {
if (string_in_list (key, vpn_ignore_keys))
return;
}
- /* Secrets don't get stored in GConf */
- if (flags & NM_SETTING_PARAM_SECRET)
+ /* Secrets don't get stored in GConf; but the 802.1x private keys,
+ * which are marked secret for backwards compat, do get stored in
+ * GConf because as of NM 0.8, they are just paths and not the decrypted
+ * private key blobs.
+ */
+ if ( (flags & NM_SETTING_PARAM_SECRET)
+ && !(NM_IS_SETTING_802_1X (setting) && string_in_list (key, applet_8021x_cert_keys)))
return;
/* Don't write the NMSettingConnection object's 'read-only' property */
@@ -1987,7 +2348,24 @@ copy_one_setting_value_to_gconf (NMSetting *setting,
}
}
- if (type == G_TYPE_STRING) {
+ if ( NM_IS_SETTING_802_1X (setting)
+ && string_in_list (key, applet_8021x_cert_keys)
+ && (type == DBUS_TYPE_G_UCHAR_ARRAY)) {
+ GError *error = NULL;
+
+ if (!write_one_certificate (info->client,
+ info->dir,
+ key,
+ NM_SETTING_802_1X (setting),
+ info->connection,
+ &error)) {
+ g_warning ("%s: error saving certificate/private key '%s': (%d) %s",
+ __func__,
+ key,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ }
+ } else if (type == G_TYPE_STRING) {
nm_gconf_set_string_helper (info->client, info->dir, key, setting_name, g_value_get_string (value));
} else if (type == G_TYPE_UINT) {
nm_gconf_set_int_helper (info->client, info->dir,
@@ -2065,95 +2443,6 @@ copy_one_setting_value_to_gconf (NMSetting *setting,
}
static void
-write_ignore_ca_cert_helper (CopyOneSettingValueInfo *info,
- const char *tag,
- const GByteArray *cert)
-{
- g_return_if_fail (info != NULL);
- g_return_if_fail (tag != NULL);
-
- if (cert) {
- char *key;
-
- key = g_strdup_printf ("%s/%s/%s", info->dir, NM_SETTING_802_1X_SETTING_NAME, tag);
- gconf_client_unset (info->client, key, NULL);
- g_free (key);
- } else {
- if (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (info->connection), tag)))
- nm_gconf_set_bool_helper (info->client, info->dir, tag, NM_SETTING_802_1X_SETTING_NAME, TRUE);
- }
-}
-
-static void
-write_one_private_string_value (CopyOneSettingValueInfo *info, const char *tag)
-{
- const char *value;
-
- g_return_if_fail (info != NULL);
- g_return_if_fail (tag != NULL);
-
- value = g_object_get_data (G_OBJECT (info->connection), tag);
- nm_gconf_set_string_helper (info->client, info->dir, tag,
- NM_SETTING_802_1X_SETTING_NAME,
- value);
-}
-
-static void
-write_one_password (CopyOneSettingValueInfo *info, const char *tag)
-{
- const char *value;
-
- g_return_if_fail (info != NULL);
- g_return_if_fail (tag != NULL);
-
- value = g_object_get_data (G_OBJECT (info->connection), tag);
- if (value) {
- nm_gconf_add_keyring_item (info->connection_uuid,
- info->connection_name,
- NM_SETTING_802_1X_SETTING_NAME,
- tag,
- value);
-
- /* Try not to leave the password lying around in memory */
- g_object_set_data (G_OBJECT (info->connection), tag, NULL);
- }
-}
-
-static void
-write_applet_private_values_to_gconf (CopyOneSettingValueInfo *info)
-{
- NMSetting8021x *s_8021x;
-
- g_return_if_fail (info != NULL);
-
- /* Handle values private to the applet that are not supposed to
- * be sent to NetworkManager.
- */
- s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (info->connection, NM_TYPE_SETTING_802_1X));
- if (s_8021x) {
- write_ignore_ca_cert_helper (info, NMA_CA_CERT_IGNORE_TAG,
- nm_setting_802_1x_get_ca_cert (s_8021x));
- write_ignore_ca_cert_helper (info, NMA_PHASE2_CA_CERT_IGNORE_TAG,
- nm_setting_802_1x_get_phase2_ca_cert (s_8021x));
-
- /* 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
- */
- write_one_private_string_value (info, NMA_PATH_CA_CERT_TAG);
- write_one_private_string_value (info, NMA_PATH_CLIENT_CERT_TAG);
- write_one_private_string_value (info, NMA_PATH_PRIVATE_KEY_TAG);
- write_one_private_string_value (info, NMA_PATH_PHASE2_CA_CERT_TAG);
- write_one_private_string_value (info, NMA_PATH_PHASE2_CLIENT_CERT_TAG);
- write_one_private_string_value (info, NMA_PATH_PHASE2_PRIVATE_KEY_TAG);
-
- write_one_password (info, NMA_PRIVATE_KEY_PASSWORD_TAG);
- write_one_password (info, NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG);
- }
-}
-
-static void
remove_leftovers (CopyOneSettingValueInfo *info)
{
GSList *dirs;
@@ -2184,6 +2473,7 @@ nm_gconf_write_connection (NMConnection *connection,
{
NMSettingConnection *s_con;
CopyOneSettingValueInfo info;
+ gboolean ignore;
g_return_if_fail (NM_IS_CONNECTION (connection));
g_return_if_fail (client != NULL);
@@ -2208,326 +2498,58 @@ nm_gconf_write_connection (NMConnection *connection,
write_one_secret_to_keyring,
&info);
- write_applet_private_values_to_gconf (&info);
-}
-
-static GValue *
-string_to_gvalue (const char *str)
-{
- GValue *val;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_STRING);
- g_value_set_string (val, str);
-
- return val;
-}
-
-static GValue *
-byte_array_to_gvalue (const GByteArray *array)
-{
- GValue *val;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY);
- g_value_set_boxed (val, array);
-
- return val;
-}
-
-static void
-destroy_gvalue (gpointer data)
-{
- GValue *value = (GValue *) data;
+ /* Update ignore CA cert status */
+ ignore = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), IGNORE_CA_CERT_TAG));
+ nm_gconf_set_ignore_ca_cert (info.connection_uuid, FALSE, ignore);
- g_value_unset (value);
- g_slice_free (GValue, value);
+ ignore = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), IGNORE_PHASE2_CA_CERT_TAG));
+ nm_gconf_set_ignore_ca_cert (info.connection_uuid, TRUE, ignore);
}
-static gboolean
-get_one_private_key (NMConnection *connection,
- const char *setting_name,
- const char *tag,
- const char *password,
- gboolean include_password,
- GHashTable *secrets,
- GError **error)
+static char *
+get_ignore_path (const char *uuid, gboolean phase2)
{
- NMSettingConnection *s_con;
- GByteArray *array = NULL;
- const char *filename = NULL;
- const char *secret_name;
- const char *real_password_secret_name = NULL;
- gboolean success = FALSE;
- gboolean add_password = FALSE;
-
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (tag != NULL, FALSE);
- g_return_val_if_fail (password != NULL, FALSE);
- g_return_val_if_fail (error != NULL, FALSE);
- g_return_val_if_fail (*error == NULL, FALSE);
-
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
-
- if (!strcmp (tag, NMA_PRIVATE_KEY_PASSWORD_TAG)) {
- filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_PRIVATE_KEY_TAG);
- secret_name = NM_SETTING_802_1X_PRIVATE_KEY;
- real_password_secret_name = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD;
- } else if (!strcmp (tag, NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG)) {
- filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_PHASE2_PRIVATE_KEY_TAG);
- secret_name = NM_SETTING_802_1X_PHASE2_PRIVATE_KEY;
- real_password_secret_name = NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD;
- } else {
- g_set_error (error,
- NM_SETTINGS_INTERFACE_ERROR,
- NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE,
- "%s.%d - %s/%s Unknown private key password type '%s'.",
- __FILE__, __LINE__, nm_setting_connection_get_id (s_con), setting_name, tag);
- return FALSE;
- }
-
- if (filename) {
- NMSetting8021x *setting;
- const GByteArray *tmp = NULL;
- NMSetting8021xCKType ck_type = NM_SETTING_802_1X_CK_TYPE_UNKNOWN;
-
- setting = (NMSetting8021x *) nm_setting_802_1x_new ();
- if (nm_setting_802_1x_set_private_key_from_file (setting, filename, password, &ck_type, error)) {
- /* For PKCS#12 files, which don't get decrypted, add the private key
- * password to the secrets hash.
- */
- if (ck_type == NM_SETTING_802_1X_CK_TYPE_PKCS12)
- add_password = TRUE;
-
- /* Steal the private key */
- tmp = nm_setting_802_1x_get_private_key (setting);
- g_assert (tmp);
- array = g_byte_array_sized_new (tmp->len);
- g_byte_array_append (array, tmp->data, tmp->len);
- }
- g_object_unref (setting);
- }
-
- if (*error) {
- goto out;
- } else if (!array || !array->len) {
- g_set_error (error,
- NM_SETTINGS_INTERFACE_ERROR,
- NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE,
- "%s.%d - %s/%s couldn't read private key.",
- __FILE__, __LINE__, nm_setting_connection_get_id (s_con), setting_name);
- goto out;
- }
-
- g_hash_table_insert (secrets, g_strdup (secret_name), byte_array_to_gvalue (array));
-
- if (include_password || add_password)
- g_hash_table_insert (secrets, g_strdup (real_password_secret_name), string_to_gvalue (password));
-
- success = TRUE;
-
-out:
- if (array) {
- /* Try not to leave the decrypted private key around in memory */
- memset (array->data, 0, array->len);
- g_byte_array_free (array, TRUE);
- }
- return success;
+ return g_strdup_printf (APPLET_PREFS_PATH "/%s/%s",
+ phase2 ? "ignore-phase2-ca-cert" : "ignore-ca-cert",
+ uuid);
}
-GHashTable *
-nm_gconf_get_keyring_items (NMConnection *connection,
- const char *setting_name,
- gboolean include_private_passwords,
- GError **error)
+gboolean
+nm_gconf_get_ignore_ca_cert (const char *uuid, gboolean phase2)
{
- NMSettingConnection *s_con;
- GHashTable *secrets;
- GList *found_list = NULL;
- GnomeKeyringResult ret;
- GList *iter;
- const char *connection_name;
-
- g_return_val_if_fail (connection != NULL, NULL);
- g_return_val_if_fail (setting_name != NULL, NULL);
- g_return_val_if_fail (error != NULL, NULL);
- g_return_val_if_fail (*error == NULL, NULL);
-
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
- g_assert (s_con);
-
- connection_name = nm_setting_connection_get_id (s_con);
- g_assert (connection_name);
-
- pre_keyring_callback ();
-
- ret = gnome_keyring_find_itemsv_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
- &found_list,
- KEYRING_UUID_TAG,
- GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
- nm_setting_connection_get_uuid (s_con),
- KEYRING_SN_TAG,
- GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
- setting_name,
- NULL);
- if ((ret != GNOME_KEYRING_RESULT_OK) || (g_list_length (found_list) == 0))
- return NULL;
-
- secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue);
-
- for (iter = found_list; iter != NULL; iter = g_list_next (iter)) {
- GnomeKeyringFound *found = (GnomeKeyringFound *) iter->data;
- int i;
- const char * key_name = NULL;
-
- for (i = 0; i < found->attributes->len; i++) {
- GnomeKeyringAttribute *attr;
-
- attr = &(gnome_keyring_attribute_list_index (found->attributes, i));
- if ( (strcmp (attr->name, "setting-key") == 0)
- && (attr->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING)) {
- key_name = attr->value.string;
- break;
- }
- }
-
- if (key_name == NULL) {
- g_set_error (error,
- NM_SETTINGS_INTERFACE_ERROR,
- NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE,
- "%s.%d - Internal error; keyring item '%s/%s' didn't "
- "have a 'setting-key' attribute.",
- __FILE__, __LINE__, connection_name, setting_name);
- break;
- }
+ GConfClient *client;
+ char *key = NULL;
+ gboolean ignore = FALSE;
- if ( !strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME)
- && ( !strcmp (key_name, NMA_PRIVATE_KEY_PASSWORD_TAG)
- || !strcmp (key_name, NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG))) {
- /* Private key passwords aren't passed to NM for "traditional"
- * OpenSSL private keys, but are passed to NM for PKCS#12 keys.
- */
- if (!get_one_private_key (connection, setting_name, key_name,
- found->secret, include_private_passwords, secrets, error)) {
- if (!*error) {
- g_set_error (error,
- NM_SETTINGS_INTERFACE_ERROR,
- NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE,
- "%s.%d - %s/%s unknown error from get_one_private_key().",
- __FILE__, __LINE__, connection_name, setting_name);
- }
- break;
- }
- } else {
- /* Ignore older obsolete keyring keys that we don't want to leak
- * through to NM.
- */
- if ( strcmp (key_name, "private-key-passwd")
- && strcmp (key_name, "phase2-private-key-passwd")) {
- g_hash_table_insert (secrets,
- g_strdup (key_name),
- string_to_gvalue (found->secret));
- }
- }
- }
+ g_return_val_if_fail (uuid != NULL, FALSE);
- if (*error) {
- nm_warning ("%s: error reading secrets: (%d) %s", __func__,
- (*error)->code, (*error)->message);
- g_hash_table_destroy (secrets);
- secrets = NULL;
- }
+ client = gconf_client_get_default ();
- gnome_keyring_found_list_free (found_list);
- return secrets;
-}
+ key = get_ignore_path (uuid, phase2);
+ ignore = gconf_client_get_bool (client, key, NULL);
+ g_free (key);
-static void
-delete_done (GnomeKeyringResult result, gpointer user_data)
-{
+ g_object_unref (client);
+ return ignore;
}
void
-nm_gconf_clear_keyring_items (NMConnection *connection)
+nm_gconf_set_ignore_ca_cert (const char *uuid, gboolean phase2, gboolean ignore)
{
- NMSettingConnection *s_con;
- const char *uuid;
- GList *found_list = NULL;
- GnomeKeyringResult ret;
- GList *iter;
-
- g_return_if_fail (connection != NULL);
-
- s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
- g_return_if_fail (s_con != NULL);
+ GConfClient *client;
+ char *key = NULL;
- uuid = nm_setting_connection_get_uuid (s_con);
g_return_if_fail (uuid != NULL);
- pre_keyring_callback ();
-
- ret = gnome_keyring_find_itemsv_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
- &found_list,
- KEYRING_UUID_TAG,
- GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
- nm_setting_connection_get_uuid (s_con),
- NULL);
- if (ret == GNOME_KEYRING_RESULT_OK) {
- for (iter = found_list; iter != NULL; iter = g_list_next (iter)) {
- GnomeKeyringFound *found = (GnomeKeyringFound *) iter->data;
-
- gnome_keyring_item_delete (found->keyring,
- found->item_id,
- delete_done,
- NULL,
- NULL);
- }
- gnome_keyring_found_list_free (found_list);
- }
-}
-
-static inline void
-copy_str_item (NMConnection *dst, NMConnection *src, const char *tag)
-{
- g_object_set_data_full (G_OBJECT (dst), tag, g_strdup (g_object_get_data (G_OBJECT (src), tag)), g_free);
-}
+ client = gconf_client_get_default ();
-void
-nm_gconf_copy_private_connection_values (NMConnection *dst, NMConnection *src)
-{
- g_return_if_fail (NM_IS_CONNECTION (dst));
- g_return_if_fail (NM_IS_CONNECTION (src));
-
- g_object_set_data (G_OBJECT (dst), NMA_CA_CERT_IGNORE_TAG,
- g_object_get_data (G_OBJECT (src), NMA_CA_CERT_IGNORE_TAG));
- g_object_set_data (G_OBJECT (dst), NMA_PHASE2_CA_CERT_IGNORE_TAG,
- g_object_get_data (G_OBJECT (src), NMA_PHASE2_CA_CERT_IGNORE_TAG));
-
- copy_str_item (dst, src, NMA_PATH_CLIENT_CERT_TAG);
- copy_str_item (dst, src, NMA_PATH_PHASE2_CLIENT_CERT_TAG);
- copy_str_item (dst, src, NMA_PATH_CA_CERT_TAG);
- copy_str_item (dst, src, NMA_PATH_PHASE2_CA_CERT_TAG);
- copy_str_item (dst, src, NMA_PATH_PRIVATE_KEY_TAG);
- copy_str_item (dst, src, NMA_PRIVATE_KEY_PASSWORD_TAG);
- copy_str_item (dst, src, NMA_PATH_PHASE2_PRIVATE_KEY_TAG);
- copy_str_item (dst, src, NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG);
-}
-
-void
-nm_gconf_clear_private_connection_values (NMConnection *connection)
-{
- g_return_if_fail (NM_IS_CONNECTION (connection));
+ key = get_ignore_path (uuid, phase2);
+ if (ignore)
+ gconf_client_set_bool (client, key, ignore, NULL);
+ else
+ gconf_client_unset (client, key, NULL);
+ g_free (key);
- g_object_set_data (G_OBJECT (connection), NMA_CA_CERT_IGNORE_TAG, NULL);
- g_object_set_data (G_OBJECT (connection), NMA_PHASE2_CA_CERT_IGNORE_TAG, NULL);
-
- g_object_set_data (G_OBJECT (connection), NMA_PATH_CLIENT_CERT_TAG, NULL);
- g_object_set_data (G_OBJECT (connection), NMA_PATH_PHASE2_CLIENT_CERT_TAG, NULL);
- g_object_set_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG, NULL);
- g_object_set_data (G_OBJECT (connection), NMA_PATH_PHASE2_CA_CERT_TAG, NULL);
- g_object_set_data (G_OBJECT (connection), NMA_PATH_PRIVATE_KEY_TAG, NULL);
- g_object_set_data (G_OBJECT (connection), NMA_PRIVATE_KEY_PASSWORD_TAG, NULL);
- g_object_set_data (G_OBJECT (connection), NMA_PATH_PHASE2_PRIVATE_KEY_TAG, NULL);
- g_object_set_data (G_OBJECT (connection), NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG, NULL);
+ g_object_unref (client);
}
diff --git a/src/gconf-helpers/gconf-helpers.h b/src/gconf-helpers/gconf-helpers.h
index 727115d..17d1ce8 100644
--- a/src/gconf-helpers/gconf-helpers.h
+++ b/src/gconf-helpers/gconf-helpers.h
@@ -27,6 +27,8 @@
#include <glib.h>
#include <nm-connection.h>
+#include "nma-gconf-connection.h"
+
#define GCONF_PATH_CONNECTIONS "/system/networking/connections"
/* The stamp is a mechanism for determining which applet version last
@@ -35,25 +37,8 @@
#define APPLET_CURRENT_STAMP 1
#define APPLET_PREFS_STAMP "/apps/nm-applet/stamp"
-
-/*
- * ATTENTION: Make sure to update nm_gconf_copy_private_connection_values()
- * and nm_gconf_clear_private_connection_values() when new tag is added!
- * Otherwise duplicating connection will not work correctly.
- */
-#define NMA_CA_CERT_IGNORE_TAG "nma-ca-cert-ignore"
-#define NMA_PHASE2_CA_CERT_IGNORE_TAG "nma-phase2-ca-cert-ignore"
-#define NMA_PATH_CLIENT_CERT_TAG "nma-path-client-cert"
-#define NMA_PATH_PHASE2_CLIENT_CERT_TAG "nma-path-phase2-client-cert"
-#define NMA_PATH_CA_CERT_TAG "nma-path-ca-cert"
-#define NMA_PATH_PHASE2_CA_CERT_TAG "nma-path-phase2-ca-cert"
-#define NMA_PATH_PRIVATE_KEY_TAG "nma-path-private-key"
-#define NMA_PRIVATE_KEY_PASSWORD_TAG "nma-private-key-password"
-#define NMA_PATH_PHASE2_PRIVATE_KEY_TAG "nma-path-phase2-private-key"
-#define NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG "nma-phase2-private-key-password"
-
-void nm_gconf_copy_private_connection_values (NMConnection *dst, NMConnection *src);
-void nm_gconf_clear_private_connection_values (NMConnection *connection);
+#define IGNORE_CA_CERT_TAG "ignore-ca-cert"
+#define IGNORE_PHASE2_CA_CERT_TAG "ignore-phase2-ca-cert"
#define KEYRING_UUID_TAG "connection-uuid"
#define KEYRING_SN_TAG "setting-name"
@@ -265,17 +250,12 @@ nm_gconf_add_keyring_item (const char *connection_uuid,
const char *setting_key,
const char *secret);
-GHashTable *
-nm_gconf_get_keyring_items (NMConnection *connection,
- const char *setting_name,
- gboolean include_private_passwords,
- GError **error);
-
-void
-nm_gconf_clear_keyring_items (NMConnection *connection);
-
typedef void (*PreKeyringCallback) (gpointer user_data);
void nm_gconf_set_pre_keyring_callback (PreKeyringCallback func, gpointer user_data);
+void pre_keyring_callback (void);
+
+gboolean nm_gconf_get_ignore_ca_cert (const char *uuid, gboolean phase2);
+void nm_gconf_set_ignore_ca_cert (const char *uuid, gboolean phase2, gboolean ignore);
#endif /* GCONF_HELPERS_H */
diff --git a/src/gconf-helpers/gconf-upgrade.c b/src/gconf-helpers/gconf-upgrade.c
index 9c87fbd..30f28af 100644
--- a/src/gconf-helpers/gconf-upgrade.c
+++ b/src/gconf-helpers/gconf-upgrade.c
@@ -70,6 +70,18 @@
#define NM_PHASE2_AUTH_MSCHAPV2 0x00030000
#define NM_PHASE2_AUTH_GTC 0x00040000
+#define NMA_CA_CERT_IGNORE_TAG "nma-ca-cert-ignore"
+#define NMA_PHASE2_CA_CERT_IGNORE_TAG "nma-phase2-ca-cert-ignore"
+#define NMA_PRIVATE_KEY_PASSWORD_TAG "nma-private-key-password"
+#define NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG "nma-phase2-private-key-password"
+#define NMA_PATH_CA_CERT_TAG "nma-path-ca-cert"
+#define NMA_PATH_PHASE2_CA_CERT_TAG "nma-path-phase2-ca-cert"
+#define NMA_PATH_CLIENT_CERT_TAG "nma-path-client-cert"
+#define NMA_PATH_PHASE2_CLIENT_CERT_TAG "nma-path-phase2-client-cert"
+#define NMA_PATH_PRIVATE_KEY_TAG "nma-path-private-key"
+#define NMA_PATH_PHASE2_PRIVATE_KEY_TAG "nma-path-phase2-private-key"
+
+
struct flagnames {
const char * const name;
guint value;
@@ -1820,3 +1832,150 @@ nm_gconf_migrate_0_7_autoconnect_default (GConfClient *client)
gconf_client_suggest_sync (client, NULL);
}
+void
+nm_gconf_migrate_0_7_ca_cert_ignore (GConfClient *client)
+{
+ GSList *connections, *iter;
+
+ /* With 0.8, the applet stores the key that suppresses the nag dialog
+ * when the user elects to ignore CA certificates in a different place than
+ * the connection itself. Move the old location to the new location.
+ */
+
+ connections = gconf_client_all_dirs (client, GCONF_PATH_CONNECTIONS, NULL);
+ for (iter = connections; iter; iter = iter->next) {
+ const char *dir = iter->data;
+ char *uuid = NULL;
+ gboolean ignore_ca_cert = FALSE;
+ gboolean ignore_phase2_ca_cert = FALSE;
+
+ if (!nm_gconf_get_string_helper (client, dir,
+ NM_SETTING_CONNECTION_UUID,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ &uuid))
+ continue;
+
+ nm_gconf_get_bool_helper (client, dir,
+ NMA_CA_CERT_IGNORE_TAG,
+ NM_SETTING_802_1X_SETTING_NAME,
+ &ignore_ca_cert);
+ if (ignore_ca_cert)
+ nm_gconf_set_ignore_ca_cert (uuid, FALSE, TRUE);
+ /* delete old key */
+ unset_one_setting_property (client, dir,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NMA_CA_CERT_IGNORE_TAG);
+
+ nm_gconf_get_bool_helper (client, dir,
+ NMA_PHASE2_CA_CERT_IGNORE_TAG,
+ NM_SETTING_802_1X_SETTING_NAME,
+ &ignore_phase2_ca_cert);
+ if (ignore_phase2_ca_cert)
+ nm_gconf_set_ignore_ca_cert (uuid, TRUE, TRUE);
+ unset_one_setting_property (client, dir,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NMA_PHASE2_CA_CERT_IGNORE_TAG);
+ }
+
+ nm_utils_slist_free (connections, g_free);
+ gconf_client_suggest_sync (client, NULL);
+}
+
+static void
+copy_one_cert_value (GConfClient *client,
+ const char *dir,
+ const char *tag,
+ const char *key)
+{
+ char *path = NULL;
+
+ if (nm_gconf_get_string_helper (client, dir,
+ tag,
+ NM_SETTING_802_1X_SETTING_NAME,
+ &path)) {
+ nm_gconf_set_string_helper (client, dir, key, NM_SETTING_802_1X_SETTING_NAME, path);
+ g_free (path);
+ }
+}
+
+static void
+copy_one_private_key_password (const char *uuid,
+ const char *id,
+ const char *old_key,
+ const char *new_key)
+{
+ GnomeKeyringResult ret;
+ GList *found_list = NULL;
+
+ /* Find the secret */
+ ret = gnome_keyring_find_itemsv_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ &found_list,
+ KEYRING_UUID_TAG,
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+ uuid,
+ KEYRING_SN_TAG,
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+ NM_SETTING_802_1X_SETTING_NAME,
+ KEYRING_SK_TAG,
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+ old_key,
+ NULL);
+ if ((ret == GNOME_KEYRING_RESULT_OK) && g_list_length (found_list)) {
+ GnomeKeyringFound *found = found_list->data;
+
+ nm_gconf_add_keyring_item (uuid,
+ id,
+ NM_SETTING_802_1X_SETTING_NAME,
+ new_key,
+ found->secret);
+ gnome_keyring_item_delete_sync (found->keyring, found->item_id);
+ gnome_keyring_found_list_free (found_list);
+ }
+}
+
+void
+nm_gconf_migrate_0_7_certs (GConfClient *client)
+{
+ GSList *connections, *iter;
+
+ /* With 0.8, the certificate/key path is stored in the value itself, not
+ * in the lookaside "nma" value.
+ */
+
+ connections = gconf_client_all_dirs (client, GCONF_PATH_CONNECTIONS, NULL);
+ for (iter = connections; iter; iter = iter->next) {
+ const char *dir = iter->data;
+ char *uuid = NULL, *id = NULL;
+
+ if (!nm_gconf_get_string_helper (client, dir,
+ NM_SETTING_CONNECTION_UUID,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ &uuid))
+ continue;
+
+ if (!nm_gconf_get_string_helper (client, dir,
+ NM_SETTING_CONNECTION_ID,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ &id)) {
+ g_free (uuid);
+ continue;
+ }
+
+ copy_one_cert_value (client, dir, NMA_PATH_CA_CERT_TAG, NM_SETTING_802_1X_CA_CERT);
+ copy_one_cert_value (client, dir, NMA_PATH_PHASE2_CA_CERT_TAG, NM_SETTING_802_1X_PHASE2_CA_CERT);
+ copy_one_cert_value (client, dir, NMA_PATH_CLIENT_CERT_TAG, NM_SETTING_802_1X_CLIENT_CERT);
+ copy_one_cert_value (client, dir, NMA_PATH_PHASE2_CLIENT_CERT_TAG, NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
+ copy_one_cert_value (client, dir, NMA_PATH_PRIVATE_KEY_TAG, NM_SETTING_802_1X_PRIVATE_KEY);
+ copy_one_cert_value (client, dir, NMA_PATH_PHASE2_PRIVATE_KEY_TAG, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
+
+ copy_one_private_key_password (uuid, id, NMA_PRIVATE_KEY_PASSWORD_TAG, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
+ copy_one_private_key_password (uuid, id, NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD);
+
+ g_free (uuid);
+ g_free (id);
+ }
+
+ nm_utils_slist_free (connections, g_free);
+ gconf_client_suggest_sync (client, NULL);
+}
+
diff --git a/src/gconf-helpers/gconf-upgrade.h b/src/gconf-helpers/gconf-upgrade.h
index 68c1ce2..868601c 100644
--- a/src/gconf-helpers/gconf-upgrade.h
+++ b/src/gconf-helpers/gconf-upgrade.h
@@ -48,5 +48,9 @@ void nm_gconf_migrate_0_7_vpn_never_default (GConfClient *client);
void nm_gconf_migrate_0_7_autoconnect_default (GConfClient *client);
+void nm_gconf_migrate_0_7_ca_cert_ignore (GConfClient *client);
+
+void nm_gconf_migrate_0_7_certs (GConfClient *client);
+
#endif /* GCONF_UPGRADE_H */
diff --git a/src/gconf-helpers/nma-gconf-connection.c b/src/gconf-helpers/nma-gconf-connection.c
index 2515c11..99bb2c9 100644
--- a/src/gconf-helpers/nma-gconf-connection.c
+++ b/src/gconf-helpers/nma-gconf-connection.c
@@ -25,8 +25,12 @@
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
+#include <gnome-keyring.h>
+
#include <nm-setting-connection.h>
#include <nm-setting-vpn.h>
+#include <nm-setting-8021x.h>
+
#include "nma-gconf-connection.h"
#include "gconf-helpers.h"
#include "nm-utils.h"
@@ -121,9 +125,7 @@ nma_gconf_connection_new_from_connection (GConfClient *client,
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
/* Ensure the connection is valid first */
- utils_fill_connection_certs (connection);
success = nm_connection_verify (connection, &error);
- utils_clear_filled_connection_certs (connection);
if (!success) {
g_warning ("Invalid connection %s: '%s' / '%s' invalid: %d",
conf_dir,
@@ -145,19 +147,10 @@ nma_gconf_connection_new_from_connection (GConfClient *client,
self = NMA_GCONF_CONNECTION (object);
/* Fill certs so that the nm_connection_replace_settings verification works */
- utils_fill_connection_certs (connection);
settings = nm_connection_to_hash (connection);
- utils_clear_filled_connection_certs (connection);
-
success = nm_connection_replace_settings (NM_CONNECTION (self), settings, NULL);
g_hash_table_destroy (settings);
- /* Then clear the filled certs on the replaced settings, and copy over
- * applet private values like file locations and such.
- */
- utils_clear_filled_connection_certs (NM_CONNECTION (self));
- nm_gconf_copy_private_connection_values (NM_CONNECTION (self), connection);
-
/* Already verified the settings above, they had better be OK */
g_assert (success);
@@ -189,9 +182,7 @@ nma_gconf_connection_gconf_changed (NMAGConfConnection *self)
goto invalid;
}
- utils_fill_connection_certs (new);
success = nm_connection_verify (new, &error);
- utils_clear_filled_connection_certs (new);
if (!success) {
g_warning ("%s: Invalid connection %s: '%s' / '%s' invalid: %d",
__func__, priv->dir,
@@ -207,14 +198,10 @@ nma_gconf_connection_gconf_changed (NMAGConfConnection *self)
return TRUE;
}
- utils_fill_connection_certs (new);
new_settings = nm_connection_to_hash (new);
- utils_clear_filled_connection_certs (new);
- g_object_unref (new);
-
success = nm_connection_replace_settings (NM_CONNECTION (self), new_settings, &error);
- utils_clear_filled_connection_certs (NM_CONNECTION (self));
g_hash_table_destroy (new_settings);
+ g_object_unref (new);
if (!success) {
g_warning ("%s: '%s' / '%s' invalid: %d",
@@ -238,6 +225,209 @@ invalid:
/******************************************************/
+static GValue *
+string_to_gvalue (const char *str)
+{
+ GValue *val;
+
+ val = g_slice_new0 (GValue);
+ g_value_init (val, G_TYPE_STRING);
+ g_value_set_string (val, str);
+
+ return val;
+}
+
+#define FILE_TAG "file://"
+
+static GValue *
+path_to_gvalue (const char *path)
+{
+ GValue *val;
+ GByteArray *array;
+
+ array = g_byte_array_sized_new (strlen (FILE_TAG) + strlen (path) + 1);
+ g_byte_array_append (array, (guint8 *) FILE_TAG, strlen (FILE_TAG));
+ g_byte_array_append (array, (guint8 *) path, strlen (path) + 1); /* +1 for the trailing NULL */
+
+ val = g_slice_new0 (GValue);
+ g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY);
+ g_value_take_boxed (val, array);
+
+ return val;
+}
+
+static void
+destroy_gvalue (gpointer data)
+{
+ GValue *value = (GValue *) data;
+
+ g_value_unset (value);
+ g_slice_free (GValue, value);
+}
+
+static GHashTable *
+nma_gconf_connection_get_keyring_items (NMAGConfConnection *self,
+ const char *setting_name,
+ GError **error)
+{
+ NMAGConfConnectionPrivate *priv;
+ NMSettingConnection *s_con;
+ GHashTable *secrets;
+ GList *found_list = NULL;
+ GnomeKeyringResult ret;
+ GList *iter;
+ const char *connection_name;
+ char *path = NULL;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (setting_name != NULL, NULL);
+ g_return_val_if_fail (error != NULL, NULL);
+ g_return_val_if_fail (*error == NULL, NULL);
+
+ priv = NMA_GCONF_CONNECTION_GET_PRIVATE (self);
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION));
+ g_assert (s_con);
+
+ connection_name = nm_setting_connection_get_id (s_con);
+ g_assert (connection_name);
+
+ pre_keyring_callback ();
+
+ ret = gnome_keyring_find_itemsv_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ &found_list,
+ KEYRING_UUID_TAG,
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+ nm_setting_connection_get_uuid (s_con),
+ KEYRING_SN_TAG,
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+ setting_name,
+ NULL);
+ if ((ret != GNOME_KEYRING_RESULT_OK) || (g_list_length (found_list) == 0))
+ return NULL;
+
+ secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue);
+
+ for (iter = found_list; iter != NULL; iter = g_list_next (iter)) {
+ GnomeKeyringFound *found = (GnomeKeyringFound *) iter->data;
+ int i;
+ const char *key_name = NULL;
+
+ for (i = 0; i < found->attributes->len; i++) {
+ GnomeKeyringAttribute *attr;
+
+ attr = &(gnome_keyring_attribute_list_index (found->attributes, i));
+ if ( (strcmp (attr->name, KEYRING_SK_TAG) == 0)
+ && (attr->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING)) {
+ key_name = attr->value.string;
+ break;
+ }
+ }
+
+ if (key_name == NULL) {
+ g_set_error (error,
+ NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE,
+ "%s.%d - Internal error; keyring item '%s/%s' didn't "
+ "have a 'setting-key' attribute.",
+ __FILE__, __LINE__, connection_name, setting_name);
+ break;
+ }
+
+ g_hash_table_insert (secrets,
+ g_strdup (key_name),
+ string_to_gvalue (found->secret));
+ }
+
+ /* The phase1 and phase2 private key are still marked as 'secret' for
+ * backwards compat, but since they don't get stored in the keyring since
+ * they aren't really secret (because we now use paths everywhere and not
+ * the decrypted private key like 0.7.x). So we need to grab them out of
+ * GConf and add them to the returned secret hash.
+ */
+ /* Private key path */
+ path = NULL;
+ if (nm_gconf_get_string_helper (priv->client,
+ priv->dir,
+ NM_SETTING_802_1X_PRIVATE_KEY,
+ NM_SETTING_802_1X_SETTING_NAME,
+ &path)) {
+ g_hash_table_insert (secrets,
+ g_strdup (NM_SETTING_802_1X_PRIVATE_KEY),
+ path_to_gvalue (path));
+ g_free (path);
+ }
+
+ /* Phase2 private key path */
+ path = NULL;
+ if (nm_gconf_get_string_helper (priv->client,
+ priv->dir,
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ NM_SETTING_802_1X_SETTING_NAME,
+ &path)) {
+ g_hash_table_insert (secrets,
+ g_strdup (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY),
+ path_to_gvalue (path));
+ g_free (path);
+ }
+
+ if (*error) {
+ nm_warning ("%s: error reading secrets: (%d) %s", __func__,
+ (*error)->code, (*error)->message);
+ g_hash_table_destroy (secrets);
+ secrets = NULL;
+ }
+
+ gnome_keyring_found_list_free (found_list);
+ return secrets;
+}
+
+static void
+delete_done (GnomeKeyringResult result, gpointer user_data)
+{
+}
+
+static void
+clear_keyring_items (NMAGConfConnection *self)
+{
+ NMSettingConnection *s_con;
+ const char *uuid;
+ GList *found_list = NULL;
+ GnomeKeyringResult ret;
+ GList *iter;
+
+ g_return_if_fail (self != NULL);
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION);
+ g_return_if_fail (s_con != NULL);
+
+ uuid = nm_setting_connection_get_uuid (s_con);
+ g_return_if_fail (uuid != NULL);
+
+ pre_keyring_callback ();
+
+ ret = gnome_keyring_find_itemsv_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ &found_list,
+ KEYRING_UUID_TAG,
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+ uuid,
+ NULL);
+ if (ret == GNOME_KEYRING_RESULT_OK) {
+ for (iter = found_list; iter != NULL; iter = g_list_next (iter)) {
+ GnomeKeyringFound *found = (GnomeKeyringFound *) iter->data;
+
+ gnome_keyring_item_delete (found->keyring,
+ found->item_id,
+ delete_done,
+ NULL,
+ NULL);
+ }
+ gnome_keyring_found_list_free (found_list);
+ }
+}
+
+/******************************************************/
+
static gboolean
update (NMSettingsConnectionInterface *connection,
NMSettingsConnectionInterfaceUpdateFunc callback,
@@ -263,6 +453,9 @@ do_delete (NMSettingsConnectionInterface *connection,
gboolean success;
GError *error = NULL;
+ /* Clean up keyring keys */
+ clear_keyring_items (NMA_GCONF_CONNECTION (connection));
+
success = gconf_client_recursive_unset (priv->client, priv->dir, 0, &error);
if (!success) {
callback (connection, error, user_data);
@@ -320,7 +513,7 @@ internal_get_secrets (NMSettingsConnectionInterface *connection,
/* Only try to get new secrets for D-Bus requests */
if (local) {
- secrets = nm_gconf_get_keyring_items (NM_CONNECTION (self), setting_name, local, error);
+ secrets = nma_gconf_connection_get_keyring_items (self, setting_name, error);
if (!secrets && error && *error)
return FALSE;
} else {
@@ -335,7 +528,7 @@ internal_get_secrets (NMSettingsConnectionInterface *connection,
goto get_secrets;
}
- secrets = nm_gconf_get_keyring_items (NM_CONNECTION (self), setting_name, local, error);
+ secrets = nma_gconf_connection_get_keyring_items (self, setting_name, error);
if (!secrets) {
if (error && *error)
return FALSE;
diff --git a/src/gconf-helpers/nma-gconf-settings.c b/src/gconf-helpers/nma-gconf-settings.c
index 8fca201..986d947 100644
--- a/src/gconf-helpers/nma-gconf-settings.c
+++ b/src/gconf-helpers/nma-gconf-settings.c
@@ -99,6 +99,7 @@ internal_add_connection (NMAGConfSettings *self, NMAGConfConnection *connection)
DBusGConnection *bus = NULL;
g_return_if_fail (connection != NULL);
+ g_return_if_fail (NMA_IS_GCONF_CONNECTION (connection));
priv->connections = g_slist_prepend (priv->connections, connection);
g_signal_connect (connection, "new-secrets-requested",
@@ -115,6 +116,7 @@ internal_add_connection (NMAGConfSettings *self, NMAGConfConnection *connection)
}
g_signal_emit_by_name (self, NM_SETTINGS_INTERFACE_NEW_CONNECTION, NM_CONNECTION (connection));
+ g_return_if_fail (NMA_IS_GCONF_CONNECTION (priv->connections->data));
}
static void
diff --git a/src/utils/utils.c b/src/utils/utils.c
index 61f1a7a..6405865 100644
--- a/src/utils/utils.c
+++ b/src/utils/utils.c
@@ -189,142 +189,6 @@ utils_get_device_description (NMDevice *device)
return description;
}
-static GByteArray *
-file_to_g_byte_array (const char *filename)
-{
- char *contents = NULL;
- GByteArray *array = NULL;
- gsize length = 0;
-
- if (!g_file_get_contents (filename, &contents, &length, NULL))
- return NULL;
-
- array = g_byte_array_sized_new (length);
- if (!array) {
- g_free (contents);
- return NULL;
- }
-
- g_byte_array_append (array, (unsigned char *) contents, length);
- return array;
-}
-
-static gboolean
-fill_one_private_key (NMConnection *connection,
- const char *pk_tag,
- const char *pk_prop,
- const char *cc_prop)
-{
- const char *filename;
- NMSetting8021x *tmp;
- NMSetting8021xCKType pk_type = NM_SETTING_802_1X_CK_TYPE_UNKNOWN;
- gboolean need_client_cert = TRUE;
-
- /* If the private key is PKCS#12, don't set the client cert */
- filename = g_object_get_data (G_OBJECT (connection), pk_tag);
- if (!filename)
- return TRUE;
-
- tmp = NM_SETTING_802_1X (nm_setting_802_1x_new ());
- nm_setting_802_1x_set_private_key_from_file (tmp, filename, NULL, &pk_type, NULL);
- if (pk_type == NM_SETTING_802_1X_CK_TYPE_PKCS12) {
- GByteArray *array;
-
- array = file_to_g_byte_array (filename);
- if (array) {
- NMSetting *s_8021x = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
-
- g_object_set (s_8021x,
- pk_prop, array,
- cc_prop, array,
- NULL);
- g_byte_array_free (array, TRUE);
- need_client_cert = FALSE;
- }
- }
- g_object_unref (tmp);
- return need_client_cert;
-}
-
-void
-utils_fill_connection_certs (NMConnection *connection)
-{
- NMSetting8021x *s_8021x;
- const char *filename;
- GError *error = NULL;
- gboolean need_client_cert = TRUE;
-
- g_return_if_fail (connection != NULL);
-
- s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
- if (!s_8021x)
- return;
-
- 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 the private key is PKCS#12, don't set the client cert */
- need_client_cert = fill_one_private_key (connection,
- NMA_PATH_PRIVATE_KEY_TAG,
- NM_SETTING_802_1X_PRIVATE_KEY,
- NM_SETTING_802_1X_CLIENT_CERT);
- 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);
- }
- }
-
- 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 the private key is PKCS#12, don't set the client cert */
- need_client_cert = fill_one_private_key (connection,
- NMA_PATH_PHASE2_PRIVATE_KEY_TAG,
- NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
- NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
- 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);
- }
- }
-}
-
-void
-utils_clear_filled_connection_certs (NMConnection *connection)
-{
- NMSetting8021x *s_8021x;
-
- g_return_if_fail (connection != NULL);
-
- s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
- if (!s_8021x)
- return;
-
- g_object_set (s_8021x,
- NM_SETTING_802_1X_CA_CERT, NULL,
- NM_SETTING_802_1X_CLIENT_CERT, NULL,
- NM_SETTING_802_1X_PRIVATE_KEY, NULL,
- NM_SETTING_802_1X_PHASE2_CA_CERT, NULL,
- NM_SETTING_802_1X_PHASE2_CLIENT_CERT, NULL,
- NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, NULL,
- NULL);
-}
-
-
struct cf_pair {
guint32 chan;
guint32 freq;
diff --git a/src/utils/utils.h b/src/utils/utils.h
index 9e26442..11acb66 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -30,10 +30,6 @@
const char *utils_get_device_description (NMDevice *device);
-void utils_fill_connection_certs (NMConnection *connection);
-
-void utils_clear_filled_connection_certs (NMConnection *connection);
-
guint32 utils_freq_to_channel (guint32 freq);
guint32 utils_channel_to_freq (guint32 channel, char *band);
guint32 utils_find_next_channel (guint32 channel, int direction, char *band);
diff --git a/src/wireless-dialog.c b/src/wireless-dialog.c
index c973be1..6c761b7 100644
--- a/src/wireless-dialog.c
+++ b/src/wireless-dialog.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw redhat com>
@@ -125,14 +126,15 @@ model_free (GtkTreeModel *model, guint col)
static void
size_group_clear (GtkSizeGroup *group)
{
- GSList *children;
GSList *iter;
g_return_if_fail (group != NULL);
- children = gtk_size_group_get_widgets (group);
- for (iter = children; iter; iter = g_slist_next (iter))
+ iter = gtk_size_group_get_widgets (group);
+ while (iter) {
gtk_size_group_remove_widget (group, GTK_WIDGET (iter->data));
+ iter = gtk_size_group_get_widgets (group);
+ }
}
static void
@@ -200,7 +202,7 @@ security_combo_changed (GtkWidget *combo,
/* Set focus to the security method's default widget, but only if the
* network name entry should not be focused.
*/
- if (!priv->network_name_focus) {
+ if (!priv->network_name_focus && sec->default_field) {
def_widget = glade_xml_get_widget (sec->xml, sec->default_field);
if (def_widget)
gtk_widget_grab_focus (def_widget);
diff --git a/src/wireless-security/eap-method-peap.c b/src/wireless-security/eap-method-peap.c
index e8e5f6e..4905c40 100644
--- a/src/wireless-security/eap-method-peap.c
+++ b/src/wireless-security/eap-method-peap.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw redhat com>
@@ -23,6 +24,8 @@
#include <glade/glade.h>
#include <ctype.h>
#include <string.h>
+
+#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
@@ -109,7 +112,9 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
static void
fill_connection (EAPMethod *parent, NMConnection *connection)
{
+ NMSettingConnection *s_con;
NMSetting8021x *s_8021x;
+ NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
GtkWidget *widget;
const char *text;
char *filename;
@@ -117,6 +122,10 @@ fill_connection (EAPMethod *parent, NMConnection *connection)
GtkTreeModel *model;
GtkTreeIter iter;
int peapver_active = 0;
+ GError *error = NULL;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ g_assert (s_con);
s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
g_assert (s_8021x);
@@ -132,19 +141,14 @@ fill_connection (EAPMethod *parent, NMConnection *connection)
widget = glade_xml_get_widget (parent->xml, "eap_peap_ca_cert_button");
g_assert (widget);
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
- if (filename) {
- g_object_set_data_full (G_OBJECT (connection),
- NMA_PATH_CA_CERT_TAG, g_strdup (filename),
- (GDestroyNotify) g_free);
- g_free (filename);
- } else {
- g_object_set_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG, NULL);
+ if (!nm_setting_802_1x_set_ca_cert (s_8021x, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+ g_warning ("Couldn't read CA certificate '%s': %s", filename, error ? error->message : "(unknown)");
+ g_clear_error (&error);
}
- if (eap_method_get_ignore_ca_cert (parent))
- g_object_set_data (G_OBJECT (connection), NMA_CA_CERT_IGNORE_TAG, GUINT_TO_POINTER (TRUE));
- else
- g_object_set_data (G_OBJECT (connection), NMA_CA_CERT_IGNORE_TAG, NULL);
+ nm_gconf_set_ignore_ca_cert (nm_setting_connection_get_uuid (s_con),
+ FALSE,
+ eap_method_get_ignore_ca_cert (parent));
widget = glade_xml_get_widget (parent->xml, "eap_peap_version_combo");
peapver_active = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
@@ -332,7 +336,8 @@ eap_method_peap_new (const char *glade_file,
eap_method_nag_init (EAP_METHOD (method),
glade_file,
"eap_peap_ca_cert_button",
- connection);
+ connection,
+ FALSE);
method->sec_parent = parent;
@@ -349,10 +354,12 @@ eap_method_peap_new (const char *glade_file,
parent);
filter = eap_method_default_file_chooser_filter_new (FALSE);
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter);
- if (connection) {
- filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG);
- if (filename)
- gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+ if (connection && s_8021x) {
+ if (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+ filename = nm_setting_802_1x_get_ca_cert_path (s_8021x);
+ if (filename)
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+ }
}
widget = inner_auth_combo_init (method, glade_file, connection, s_8021x);
diff --git a/src/wireless-security/eap-method-tls.c b/src/wireless-security/eap-method-tls.c
index db0d7c4..28f26aa 100644
--- a/src/wireless-security/eap-method-tls.c
+++ b/src/wireless-security/eap-method-tls.c
@@ -1,5 +1,4 @@
-/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
-
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw redhat com>
@@ -25,6 +24,8 @@
#include <glib/gi18n.h>
#include <ctype.h>
#include <string.h>
+
+#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "gconf-helpers.h"
@@ -57,7 +58,7 @@ destroy (EAPMethod *parent)
static gboolean
validate (EAPMethod *parent)
{
- NMSetting8021xCKType ck_type = NM_SETTING_802_1X_CK_TYPE_UNKNOWN;
+ NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
GtkWidget *widget;
const char *password, *identity;
@@ -80,10 +81,10 @@ validate (EAPMethod *parent)
"eap_tls_private_key_button",
TYPE_PRIVATE_KEY,
password,
- &ck_type))
+ &format))
return FALSE;
- if (ck_type != NM_SETTING_802_1X_CK_TYPE_PKCS12) {
+ if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
if (!eap_method_validate_filepicker (parent->xml, "eap_tls_user_cert_button", TYPE_CLIENT_CERT, NULL, NULL))
return FALSE;
}
@@ -118,26 +119,20 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
}
static void
-free_password (gpointer data)
-{
- g_return_if_fail (data != NULL);
-
- /* Try not to leave passwords around in memory */
- memset (data, 0, strlen (data));
- g_free (data);
-}
-
-static void
fill_connection (EAPMethod *parent, NMConnection *connection)
{
EAPMethodTLS *method = (EAPMethodTLS *) parent;
- NMSetting8021xCKType key_type = NM_SETTING_802_1X_CK_TYPE_UNKNOWN;
+ NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
NMSetting8021x *s_8021x;
+ NMSettingConnection *s_con;
GtkWidget *widget;
- char *filename, *pk_filename, *cc_filename;
- char *password = NULL;
+ char *ca_filename, *pk_filename, *cc_filename;
+ const char *password = NULL;
GError *error = NULL;
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ g_assert (s_con);
+
s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
g_assert (s_8021x);
@@ -150,92 +145,83 @@ fill_connection (EAPMethod *parent, NMConnection *connection)
g_assert (widget);
g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
+ /* TLS private key */
widget = glade_xml_get_widget (parent->xml, "eap_tls_private_key_password_entry");
g_assert (widget);
- password = g_strdup (gtk_entry_get_text (GTK_ENTRY (widget)));
- if (method->phase2) {
- g_object_set_data_full (G_OBJECT (connection),
- NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG,
- password,
- (GDestroyNotify) free_password);
- } else {
- g_object_set_data_full (G_OBJECT (connection),
- NMA_PRIVATE_KEY_PASSWORD_TAG,
- password,
- (GDestroyNotify) free_password);
- }
+ password = gtk_entry_get_text (GTK_ENTRY (widget));
+ g_assert (password);
- /* TLS private key */
widget = glade_xml_get_widget (parent->xml, "eap_tls_private_key_button");
g_assert (widget);
pk_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
g_assert (pk_filename);
- g_object_set_data_full (G_OBJECT (connection),
- method->phase2 ? NMA_PATH_PHASE2_PRIVATE_KEY_TAG : NMA_PATH_PRIVATE_KEY_TAG,
- g_strdup (pk_filename),
- (GDestroyNotify) g_free);
+
if (method->phase2) {
- if (!nm_setting_802_1x_set_phase2_private_key_from_file (s_8021x, pk_filename, password, &key_type, &error)) {
+ if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, pk_filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
g_warning ("Couldn't read phase2 private key '%s': %s", pk_filename, error ? error->message : "(unknown)");
g_clear_error (&error);
}
} else {
- if (!nm_setting_802_1x_set_private_key_from_file (s_8021x, pk_filename, password, &key_type, &error)) {
+ if (!nm_setting_802_1x_set_private_key (s_8021x, pk_filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
g_warning ("Couldn't read private key '%s': %s", pk_filename, error ? error->message : "(unknown)");
g_clear_error (&error);
}
}
+ g_free (pk_filename);
/* TLS client certificate */
- if (key_type == NM_SETTING_802_1X_CK_TYPE_PKCS12) {
- /* if the key is pkcs#12, the cert is filled with the same data */
- cc_filename = g_strdup (pk_filename);
- } else {
+ if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
+ /* If the key is pkcs#12 nm_setting_802_1x_set_private_key() already
+ * set the client certificate for us.
+ */
widget = glade_xml_get_widget (parent->xml, "eap_tls_user_cert_button");
g_assert (widget);
cc_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+ g_assert (cc_filename);
+
+ format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+ if (method->phase2) {
+ if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, cc_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+ g_warning ("Couldn't read phase2 client certificate '%s': %s", cc_filename, error ? error->message : "(unknown)");
+ g_clear_error (&error);
+ }
+ } else {
+ if (!nm_setting_802_1x_set_client_cert (s_8021x, cc_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+ g_warning ("Couldn't read client certificate '%s': %s", cc_filename, error ? error->message : "(unknown)");
+ g_clear_error (&error);
+ }
+ }
+ g_free (cc_filename);
}
- g_assert (cc_filename);
- g_object_set_data_full (G_OBJECT (connection),
- method->phase2 ? NMA_PATH_PHASE2_CLIENT_CERT_TAG : NMA_PATH_CLIENT_CERT_TAG,
- g_strdup (cc_filename),
- (GDestroyNotify) g_free);
- g_free (cc_filename);
- g_free (pk_filename);
-
/* TLS CA certificate */
widget = glade_xml_get_widget (parent->xml, "eap_tls_ca_cert_button");
g_assert (widget);
- filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
- if (filename) {
- g_object_set_data_full (G_OBJECT (connection),
- method->phase2 ? NMA_PATH_PHASE2_CA_CERT_TAG : NMA_PATH_CA_CERT_TAG,
- g_strdup (filename),
- (GDestroyNotify) g_free);
- g_free (filename);
- } else {
- g_object_set_data (G_OBJECT (connection),
- method->phase2 ? NMA_PATH_PHASE2_CA_CERT_TAG : NMA_PATH_CA_CERT_TAG,
- NULL);
- }
+ ca_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
- if (eap_method_get_ignore_ca_cert (parent)) {
- g_object_set_data (G_OBJECT (connection),
- method->phase2 ? NMA_PHASE2_CA_CERT_IGNORE_TAG : NMA_CA_CERT_IGNORE_TAG,
- GUINT_TO_POINTER (TRUE));
+ format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+ if (method->phase2) {
+ if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, ca_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+ g_warning ("Couldn't read phase2 CA certificate '%s': %s", ca_filename, error ? error->message : "(unknown)");
+ g_clear_error (&error);
+ }
} else {
- g_object_set_data (G_OBJECT (connection),
- method->phase2 ? NMA_PHASE2_CA_CERT_IGNORE_TAG : NMA_CA_CERT_IGNORE_TAG,
- NULL);
+ if (!nm_setting_802_1x_set_ca_cert (s_8021x, ca_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+ g_warning ("Couldn't read CA certificate '%s': %s", ca_filename, error ? error->message : "(unknown)");
+ g_clear_error (&error);
+ }
}
+
+ nm_gconf_set_ignore_ca_cert (nm_setting_connection_get_uuid (s_con),
+ method->phase2,
+ eap_method_get_ignore_ca_cert (parent));
}
static void
private_key_picker_helper (EAPMethod *parent, const char *filename, gboolean changed)
{
NMSetting8021x *setting;
- NMSetting8021xCKType cert_type = NM_SETTING_802_1X_CK_TYPE_UNKNOWN;
+ NMSetting8021xCKFormat cert_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
const char *password;
GtkWidget *widget;
@@ -244,12 +230,12 @@ private_key_picker_helper (EAPMethod *parent, const char *filename, gboolean cha
password = gtk_entry_get_text (GTK_ENTRY (widget));
setting = (NMSetting8021x *) nm_setting_802_1x_new ();
- nm_setting_802_1x_set_private_key_from_file (setting, filename, password, &cert_type, NULL);
+ nm_setting_802_1x_set_private_key (setting, filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &cert_format, NULL);
g_object_unref (setting);
/* With PKCS#12, the client cert must be the same as the private key */
widget = glade_xml_get_widget (parent->xml, "eap_tls_user_cert_button");
- if (cert_type == NM_SETTING_802_1X_CK_TYPE_PKCS12) {
+ if (cert_format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (widget));
gtk_widget_set_sensitive (widget, FALSE);
} else if (changed)
@@ -277,34 +263,36 @@ static void reset_filter (GtkWidget *widget, GParamSpec *spec, gpointer user_dat
}
}
+typedef const char * (*PathFunc) (NMSetting8021x *setting);
+typedef NMSetting8021xCKScheme (*SchemeFunc) (NMSetting8021x *setting);
+
static void
setup_filepicker (GladeXML *xml,
const char *name,
const char *title,
WirelessSecurity *parent,
EAPMethodTLS *method,
- NMConnection *connection,
- const char *tag)
+ NMSetting8021x *s_8021x,
+ SchemeFunc scheme_func,
+ PathFunc path_func,
+ gboolean privkey,
+ gboolean client_cert)
{
GtkWidget *widget;
GtkFileFilter *filter;
const char *filename = NULL;
- gboolean privkey = FALSE, client_cert = FALSE;
-
- if (!strcmp (tag, NMA_PATH_PHASE2_PRIVATE_KEY_TAG) || !strcmp (tag, NMA_PATH_PRIVATE_KEY_TAG))
- privkey = TRUE;
- if (!strcmp (tag, NMA_PATH_PHASE2_CLIENT_CERT_TAG) || !strcmp (tag, NMA_PATH_CLIENT_CERT_TAG))
- client_cert = TRUE;
widget = glade_xml_get_widget (xml, name);
g_assert (widget);
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), title);
- if (connection && tag) {
- filename = g_object_get_data (G_OBJECT (connection), tag);
- if (filename)
- gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+ if (s_8021x && path_func && scheme_func) {
+ if (scheme_func (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+ filename = path_func (s_8021x);
+ if (filename)
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+ }
}
/* Connect a special handler for private keys to intercept PKCS#12 key types
@@ -376,7 +364,8 @@ eap_method_tls_new (const char *glade_file,
eap_method_nag_init (EAP_METHOD (method),
glade_file,
"eap_tls_ca_cert_button",
- connection);
+ connection,
+ phase2);
method->phase2 = phase2;
@@ -410,19 +399,26 @@ eap_method_tls_new (const char *glade_file,
(GCallback) wireless_security_changed_cb,
parent);
+nm_connection_dump (connection);
setup_filepicker (xml, "eap_tls_user_cert_button",
_("Choose your personal certificate..."),
- parent, method, connection,
- phase2 ? NMA_PATH_PHASE2_CLIENT_CERT_TAG : NMA_PATH_CLIENT_CERT_TAG);
+ parent, method, s_8021x,
+ phase2 ? nm_setting_802_1x_get_phase2_client_cert_scheme : nm_setting_802_1x_get_client_cert_scheme,
+ phase2 ? nm_setting_802_1x_get_phase2_client_cert_path : nm_setting_802_1x_get_client_cert_path,
+ FALSE, TRUE);
setup_filepicker (xml, "eap_tls_ca_cert_button",
_("Choose a Certificate Authority certificate..."),
- parent, method, connection,
- phase2 ? NMA_PATH_PHASE2_CA_CERT_TAG : NMA_PATH_CA_CERT_TAG);
+ parent, method, s_8021x,
+ phase2 ? nm_setting_802_1x_get_phase2_ca_cert_scheme : nm_setting_802_1x_get_ca_cert_scheme,
+ phase2 ? nm_setting_802_1x_get_phase2_ca_cert_path : nm_setting_802_1x_get_ca_cert_path,
+ FALSE, FALSE);
setup_filepicker (xml,
"eap_tls_private_key_button",
_("Choose your private key..."),
- parent, method, connection,
- phase2 ? NMA_PATH_PHASE2_PRIVATE_KEY_TAG : NMA_PATH_PRIVATE_KEY_TAG);
+ parent, method, s_8021x,
+ phase2 ? nm_setting_802_1x_get_phase2_private_key_scheme : nm_setting_802_1x_get_private_key_scheme,
+ phase2 ? nm_setting_802_1x_get_phase2_private_key_path : nm_setting_802_1x_get_private_key_path,
+ TRUE, FALSE);
widget = glade_xml_get_widget (xml, "show_checkbutton");
g_assert (widget);
diff --git a/src/wireless-security/eap-method-ttls.c b/src/wireless-security/eap-method-ttls.c
index 6117592..9ccb1f8 100644
--- a/src/wireless-security/eap-method-ttls.c
+++ b/src/wireless-security/eap-method-ttls.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw redhat com>
@@ -23,6 +24,8 @@
#include <glade/glade.h>
#include <ctype.h>
#include <string.h>
+
+#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
@@ -105,13 +108,19 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
static void
fill_connection (EAPMethod *parent, NMConnection *connection)
{
+ NMSettingConnection *s_con;
NMSetting8021x *s_8021x;
+ NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
GtkWidget *widget;
const char *text;
char *filename;
EAPMethod *eap = NULL;
GtkTreeModel *model;
GtkTreeIter iter;
+ GError *error = NULL;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ g_assert (s_con);
s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
g_assert (s_8021x);
@@ -127,19 +136,14 @@ fill_connection (EAPMethod *parent, NMConnection *connection)
widget = glade_xml_get_widget (parent->xml, "eap_ttls_ca_cert_button");
g_assert (widget);
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
- if (filename) {
- g_object_set_data_full (G_OBJECT (connection),
- NMA_PATH_CA_CERT_TAG, g_strdup (filename),
- (GDestroyNotify) g_free);
- g_free (filename);
- } else {
- g_object_set_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG, NULL);
+ if (!nm_setting_802_1x_set_ca_cert (s_8021x, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+ g_warning ("Couldn't read CA certificate '%s': %s", filename, error ? error->message : "(unknown)");
+ g_clear_error (&error);
}
- if (eap_method_get_ignore_ca_cert (parent))
- g_object_set_data (G_OBJECT (connection), NMA_CA_CERT_IGNORE_TAG, GUINT_TO_POINTER (TRUE));
- else
- g_object_set_data (G_OBJECT (connection), NMA_CA_CERT_IGNORE_TAG, NULL);
+ nm_gconf_set_ignore_ca_cert (nm_setting_connection_get_uuid (s_con),
+ FALSE,
+ eap_method_get_ignore_ca_cert (parent));
widget = glade_xml_get_widget (parent->xml, "eap_ttls_inner_auth_combo");
model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
@@ -330,7 +334,8 @@ eap_method_ttls_new (const char *glade_file,
eap_method_nag_init (EAP_METHOD (method),
glade_file,
"eap_ttls_ca_cert_button",
- connection);
+ connection,
+ FALSE);
method->sec_parent = parent;
@@ -347,10 +352,12 @@ eap_method_ttls_new (const char *glade_file,
parent);
filter = eap_method_default_file_chooser_filter_new (FALSE);
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter);
- if (connection) {
- filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG);
- if (filename)
- gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+ if (connection && s_8021x) {
+ if (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+ filename = nm_setting_802_1x_get_ca_cert_path (s_8021x);
+ if (filename)
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+ }
}
widget = glade_xml_get_widget (xml, "eap_ttls_anon_identity_entry");
diff --git a/src/wireless-security/eap-method.c b/src/wireless-security/eap-method.c
index f382bf7..7ab7bbd 100644
--- a/src/wireless-security/eap-method.c
+++ b/src/wireless-security/eap-method.c
@@ -31,6 +31,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
#include "gconf-helpers.h"
@@ -139,7 +140,8 @@ gboolean
eap_method_nag_init (EAPMethod *method,
const char *glade_file,
const char *ca_cert_chooser,
- NMConnection *connection)
+ NMConnection *connection,
+ gboolean phase2)
{
GtkWidget *dialog, *widget;
char *text;
@@ -155,8 +157,17 @@ eap_method_nag_init (EAPMethod *method,
}
method->ca_cert_chooser = g_strdup (ca_cert_chooser);
- if (connection)
- method->ignore_ca_cert = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), NMA_CA_CERT_IGNORE_TAG));
+ if (connection) {
+ NMSettingConnection *s_con;
+ const char *uuid;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ g_assert (s_con);
+ uuid = nm_setting_connection_get_uuid (s_con);
+ g_assert (uuid);
+
+ method->ignore_ca_cert = nm_gconf_get_ignore_ca_cert (uuid, phase2);
+ }
dialog = glade_xml_get_widget (method->nag_dialog_xml, "nag_user_dialog");
g_assert (dialog);
@@ -250,7 +261,7 @@ eap_method_validate_filepicker (GladeXML *xml,
const char *name,
guint32 item_type,
const char *password,
- NMSetting8021xCKType *out_ck_type)
+ NMSetting8021xCKFormat *out_format)
{
GtkWidget *widget;
char *filename;
@@ -259,15 +270,15 @@ eap_method_validate_filepicker (GladeXML *xml,
GError *error = NULL;
if (item_type == TYPE_PRIVATE_KEY) {
- g_return_val_if_fail (password != NULL, NM_SETTING_802_1X_CK_TYPE_UNKNOWN);
- g_return_val_if_fail (strlen (password), NM_SETTING_802_1X_CK_TYPE_UNKNOWN);
+ g_return_val_if_fail (password != NULL, FALSE);
+ g_return_val_if_fail (strlen (password), FALSE);
}
widget = glade_xml_get_widget (xml, name);
g_assert (widget);
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
if (!filename)
- return (item_type == TYPE_CA_CERT) ? NM_SETTING_802_1X_CK_TYPE_X509 : NM_SETTING_802_1X_CK_TYPE_UNKNOWN;
+ return (item_type == TYPE_CA_CERT) ? TRUE : FALSE;
if (!g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
goto out;
@@ -275,21 +286,21 @@ eap_method_validate_filepicker (GladeXML *xml,
setting = (NMSetting8021x *) nm_setting_802_1x_new ();
if (item_type == TYPE_PRIVATE_KEY) {
- if (!nm_setting_802_1x_set_private_key_from_file (setting, filename, password, out_ck_type, &error)) {
+ if (!nm_setting_802_1x_set_private_key (setting, filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, &error)) {
g_warning ("Error: couldn't verify private key: %d %s",
error ? error->code : -1, error ? error->message : "(none)");
g_clear_error (&error);
} else
success = TRUE;
} else if (item_type == TYPE_CLIENT_CERT) {
- if (!nm_setting_802_1x_set_client_cert_from_file (setting, filename, out_ck_type, &error)) {
+ if (!nm_setting_802_1x_set_client_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, &error)) {
g_warning ("Error: couldn't verify client certificate: %d %s",
error ? error->code : -1, error ? error->message : "(none)");
g_clear_error (&error);
} else
success = TRUE;
} else if (item_type == TYPE_CA_CERT) {
- if (!nm_setting_802_1x_set_ca_cert_from_file (setting, filename, out_ck_type, &error)) {
+ if (!nm_setting_802_1x_set_ca_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, &error)) {
g_warning ("Error: couldn't verify CA certificate: %d %s",
error ? error->code : -1, error ? error->message : "(none)");
g_clear_error (&error);
diff --git a/src/wireless-security/eap-method.h b/src/wireless-security/eap-method.h
index 2d517b0..dd4a345 100644
--- a/src/wireless-security/eap-method.h
+++ b/src/wireless-security/eap-method.h
@@ -100,12 +100,13 @@ gboolean eap_method_validate_filepicker (GladeXML *xml,
const char *name,
guint32 item_type,
const char *password,
- NMSetting8021xCKType *out_ck_type);
+ NMSetting8021xCKFormat *out_format);
gboolean eap_method_nag_init (EAPMethod *method,
const char *glade_file,
const char *ca_cert_chooser,
- NMConnection *connection);
+ NMConnection *connection,
+ gboolean phase2);
gboolean eap_method_get_ignore_ca_cert (EAPMethod *method);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]