[network-manager-netbook/MplPanelClient: 27/44] First-pass at NM 0.8 port (bgo #596755)
- From: Tambet Ingo <tambeti src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [network-manager-netbook/MplPanelClient: 27/44] First-pass at NM 0.8 port (bgo #596755)
- Date: Tue, 10 Nov 2009 14:11:59 +0000 (UTC)
commit 4f77d49a98c01f34399ad6fbc121a845dfbacff0
Author: Bastien Nocera <hadess hadess net>
Date: Tue Sep 29 17:08:49 2009 -0700
First-pass at NM 0.8 port (bgo #596755)
configure.in | 4 +-
src/gconf-helpers/Makefile.am | 7 +-
src/gconf-helpers/gconf-helpers.c | 1592 +++++++++++++++++++++---------
src/gconf-helpers/gconf-helpers.h | 82 ++-
src/gconf-helpers/nma-gconf-connection.c | 908 +++++++++++++-----
src/gconf-helpers/nma-gconf-connection.h | 42 +-
src/gconf-helpers/nma-gconf-settings.c | 222 +++--
src/gconf-helpers/nma-gconf-settings.h | 52 +-
src/gconf-helpers/utils.c | 856 ----------------
src/gconf-helpers/utils.h | 56 --
src/marshallers/nma-marshal.list | 7 +-
src/nmn-applet.h | 4 +
src/nmn-device-handler.c | 35 +-
src/nmn-device-handler.h | 2 +-
src/nmn-ethernet-handler.c | 3 +-
src/nmn-ethernet-item.c | 39 +-
src/nmn-network-item.c | 41 +-
src/nmn-network-item.h | 2 +-
src/nmn-networks.c | 3 +-
src/nmn-nm-data.c | 14 +-
src/nmn-nm-data.h | 8 +-
src/nmn-serial-handler.c | 3 +-
src/nmn-wifi-handler.c | 5 +-
src/nmn-wifi-item.c | 42 +-
src/nmn-wifi-list.c | 4 +-
src/utils.c | 246 ++---
src/utils.h | 8 +-
src/wireless-dialog.c | 1 -
src/wireless-security/Makefile.am | 1 +
src/wireless-security/eap-method-peap.c | 36 +-
src/wireless-security/eap-method-tls.c | 127 ++--
src/wireless-security/eap-method-ttls.c | 36 +-
src/wireless-security/eap-method.c | 17 +-
src/wireless-security/eap-method.h | 3 +-
34 files changed, 2428 insertions(+), 2080 deletions(-)
---
diff --git a/configure.in b/configure.in
index 4987201..fe14a1c 100644
--- a/configure.in
+++ b/configure.in
@@ -22,7 +22,9 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package])
IT_PROG_INTLTOOL([0.35.0])
AM_GLIB_GNU_GETTEXT
-PKG_CHECK_MODULES(NMN, dbus-glib-1 >= 0.75 gtk+-2.0 gconf-2.0 gnome-keyring-1 libnm-util libnm_glib mobile-broadband-provider-info moblin-panel-gtk nbtk-gtk-1.0)
+NM_REQUIRED=0.7.996
+
+PKG_CHECK_MODULES(NMN, dbus-glib-1 >= 0.75 gtk+-2.0 gconf-2.0 gnome-keyring-1 libnm-util >= $NM_REQUIRED libnm-glib >= $NM_REQUIRED mobile-broadband-provider-info moblin-panel nbtk-gtk-1.2)
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
AC_SUBST(GLIB_GENMARSHAL)
diff --git a/src/gconf-helpers/Makefile.am b/src/gconf-helpers/Makefile.am
index a840abf..0344b34 100644
--- a/src/gconf-helpers/Makefile.am
+++ b/src/gconf-helpers/Makefile.am
@@ -3,15 +3,16 @@ noinst_LTLIBRARIES = libgconf-helpers.la
libgconf_helpers_la_SOURCES = \
gconf-helpers.h \
gconf-helpers.c \
+ gconf-upgrade.h \
+ gconf-upgrade.c \
nma-gconf-connection.h \
nma-gconf-connection.c \
nma-gconf-settings.h \
- nma-gconf-settings.c \
- utils.h \
- utils.c
+ nma-gconf-settings.c
libgconf_helpers_la_CPPFLAGS = \
$(NMN_CFLAGS) \
+ -I${top_builddir}/src/ \
-I${top_builddir}/src/marshallers
libgconf_helpers_la_LIBADD = \
diff --git a/src/gconf-helpers/gconf-helpers.c b/src/gconf-helpers/gconf-helpers.c
index 0449c1b..06b2a55 100644
--- a/src/gconf-helpers/gconf-helpers.c
+++ b/src/gconf-helpers/gconf-helpers.c
@@ -17,25 +17,40 @@
* 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>
+#include <stdlib.h>
#include <errno.h>
+#include <net/ethernet.h>
+#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>
+#include <nm-setting-wireless.h>
#include <nm-setting-wireless-security.h>
#include <nm-setting-8021x.h>
#include <nm-setting-vpn.h>
#include <nm-setting-ip4-config.h>
#include <nm-utils.h>
-#include <nm-settings.h>
+#include <nm-settings-interface.h>
#include "gconf-helpers.h"
+#include "gconf-upgrade.h"
+#include "utils.h"
+#include "nmn-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))
@@ -46,8 +61,12 @@
#define DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT))
#define DBUS_TYPE_G_MAP_OF_STRING (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING))
#define DBUS_TYPE_G_LIST_OF_STRING (dbus_g_type_get_collection ("GSList", G_TYPE_STRING))
+#define DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
+#define DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_IP6_ADDRESS))
+#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",
@@ -73,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;
@@ -265,6 +284,70 @@ out:
return success;
}
+typedef struct {
+ const char *setting_name;
+ const char *key_name;
+} MacAddressKey;
+
+static MacAddressKey mac_keys[] = {
+ { NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR },
+ { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS },
+ { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS },
+ { NULL, NULL }
+};
+
+static gboolean
+nm_gconf_get_mac_address_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GByteArray **value)
+{
+ char *gc_key;
+ GConfValue *gc_value;
+ gboolean success = FALSE;
+ MacAddressKey *tmp = &mac_keys[0];
+ gboolean found = FALSE;
+
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (setting != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ /* Match against know setting/key combos that can be MAC addresses */
+ while (tmp->setting_name) {
+ if (!strcmp (tmp->setting_name, setting) && !strcmp (tmp->key_name, key)) {
+ found = TRUE;
+ break;
+ }
+ tmp++;
+ }
+ if (!found)
+ return FALSE;
+
+ gc_key = g_strdup_printf ("%s/%s/%s", path, setting, key);
+ if (!(gc_value = gconf_client_get (client, gc_key, NULL)))
+ goto out;
+
+ if (gc_value && (gc_value->type == GCONF_VALUE_STRING)) {
+ const char *str;
+ struct ether_addr *addr;
+
+ str = gconf_value_get_string (gc_value);
+ addr = ether_aton (str);
+ if (addr) {
+ *value = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (*value, (const guint8 *) addr->ether_addr_octet, ETH_ALEN);
+ success = TRUE;
+ }
+ }
+
+out:
+ if (gc_value)
+ gconf_value_free (gc_value);
+ g_free (gc_key);
+ return success;
+}
+
gboolean
nm_gconf_get_bytearray_helper (GConfClient *client,
const char *path,
@@ -436,7 +519,7 @@ nm_gconf_get_valuehash_helper (GConfClient *client,
gc_key += prefix_len + 1; /* get rid of the full path */
add_property (*value, gc_key, gconf_entry_get_value (entry));
- gconf_entry_free (entry);
+ gconf_entry_unref (entry);
}
g_slist_free (gconf_entries);
@@ -491,7 +574,7 @@ nm_gconf_get_stringhash_helper (GConfClient *client,
g_hash_table_insert (*value, gconf_unescape_key (gc_key, -1), g_strdup (gc_str));
}
}
- gconf_entry_free (entry);
+ gconf_entry_unref (entry);
}
g_slist_free (gconf_entries);
@@ -560,6 +643,254 @@ out:
}
gboolean
+nm_gconf_get_ip6dns_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray **value)
+{
+ char *gc_key;
+ GConfValue *gc_value = NULL;
+ GPtrArray *array;
+ gboolean success = FALSE;
+ GSList *values, *iter;
+
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (setting != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ gc_key = g_strdup_printf ("%s/%s/%s", path, setting, key);
+ if (!(gc_value = gconf_client_get (client, gc_key, NULL)))
+ goto out;
+
+ if ( (gc_value->type != GCONF_VALUE_LIST)
+ || (gconf_value_get_list_type (gc_value) != GCONF_VALUE_STRING))
+ goto out;
+
+ values = gconf_value_get_list (gc_value);
+ array = g_ptr_array_sized_new (1);
+ for (iter = values; iter; iter = g_slist_next (iter)) {
+ const char *straddr = gconf_value_get_string ((GConfValue *) iter->data);
+ struct in6_addr rawaddr;
+ GByteArray *ba;
+
+ if (inet_pton (AF_INET6, straddr, &rawaddr) <= 0) {
+ g_warning ("%s: %s contained bad address: %s",
+ __func__, gc_key, straddr);
+ continue;
+ }
+
+ ba = g_byte_array_new ();
+ g_byte_array_append (ba, (guchar *)&rawaddr, sizeof (rawaddr));
+
+ g_ptr_array_add (array, ba);
+ }
+
+ *value = array;
+ success = TRUE;
+
+out:
+ if (gc_value)
+ gconf_value_free (gc_value);
+ g_free (gc_key);
+ return success;
+}
+
+gboolean
+nm_gconf_get_ip6addr_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray **value)
+{
+ char *gc_key;
+ GConfValue *gc_value = NULL;
+ GPtrArray *array;
+ gboolean success = FALSE;
+ GSList *values, *iter;
+
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (setting != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ gc_key = g_strdup_printf ("%s/%s/%s", path, setting, key);
+ if (!(gc_value = gconf_client_get (client, gc_key, NULL)))
+ goto out;
+
+ if ( (gc_value->type != GCONF_VALUE_LIST)
+ || (gconf_value_get_list_type (gc_value) != GCONF_VALUE_STRING))
+ goto out;
+
+ values = gconf_value_get_list (gc_value);
+ array = g_ptr_array_sized_new (1);
+ for (iter = values; iter; iter = g_slist_next (iter)) {
+ const char *addr_prefix = gconf_value_get_string ((GConfValue *) iter->data);
+ char *addr, *p;
+ guint prefix;
+ struct in6_addr rawaddr;
+ GValueArray *valarr;
+ GValue element = {0, };
+ GByteArray *ba;
+
+ addr = g_strdup (addr_prefix);
+ p = strchr (addr, '/');
+ if (!p) {
+ g_warning ("%s: %s contained bad address/prefix: %s",
+ __func__, gc_key, addr_prefix);
+ g_free (addr);
+ continue;
+ }
+ *p++ = '\0';
+ prefix = strtoul (p, NULL, 10);
+
+ if (inet_pton (AF_INET6, addr, &rawaddr) <= 0 && prefix > 128) {
+ g_warning ("%s: %s contained bad address: %s",
+ __func__, gc_key, addr_prefix);
+ g_free (addr);
+ continue;
+ }
+ g_free (addr);
+
+ valarr = g_value_array_new (2);
+
+ g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
+ ba = g_byte_array_new ();
+ g_byte_array_append (ba, (guint8 *) &rawaddr, 16);
+ g_value_take_boxed (&element, ba);
+ g_value_array_append (valarr, &element);
+ g_value_unset (&element);
+
+ g_value_init (&element, G_TYPE_UINT);
+ g_value_set_uint (&element, prefix);
+ g_value_array_append (valarr, &element);
+ g_value_unset (&element);
+
+ g_ptr_array_add (array, valarr);
+ }
+
+ *value = array;
+ success = TRUE;
+
+out:
+ if (gc_value)
+ gconf_value_free (gc_value);
+ g_free (gc_key);
+ return success;
+}
+
+gboolean
+nm_gconf_get_ip6route_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray **value)
+{
+ char *gc_key;
+ GConfValue *gc_value = NULL;
+ GPtrArray *array;
+ gboolean success = FALSE;
+ GSList *values, *iter;
+
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (setting != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ gc_key = g_strdup_printf ("%s/%s/%s", path, setting, key);
+ if (!(gc_value = gconf_client_get (client, gc_key, NULL)))
+ goto out;
+
+ if ( (gc_value->type != GCONF_VALUE_LIST)
+ || (gconf_value_get_list_type (gc_value) != GCONF_VALUE_STRING))
+ goto out;
+
+ values = gconf_value_get_list (gc_value);
+ array = g_ptr_array_sized_new (1);
+ for (iter = values; iter; iter = g_slist_next (iter)) {
+ const char *route_str = gconf_value_get_string ((GConfValue *) iter->data);
+ char **parts, *addr, *p;
+ guint prefix, metric;
+ struct in6_addr rawaddr;
+ GValueArray *valarr;
+ GValue element = {0, };
+ GByteArray *dest, *next_hop;
+
+ parts = g_strsplit (route_str, ",", -1);
+ if (g_strv_length (parts) != 3) {
+ g_warning ("%s: %s contained bad route: %s",
+ __func__, gc_key, route_str);
+ g_strfreev (parts);
+ continue;
+ }
+
+ addr = parts[0];
+ p = strchr (addr, '/');
+ if (!p) {
+ g_warning ("%s: %s contained bad address/prefix: %s",
+ __func__, gc_key, addr);
+ g_strfreev (parts);
+ continue;
+ }
+ *p++ = '\0';
+ prefix = strtoul (p, NULL, 10);
+
+ if (inet_pton (AF_INET6, addr, &rawaddr) <= 0 && prefix > 128) {
+ g_warning ("%s: %s contained bad address: %s",
+ __func__, gc_key, addr);
+ g_strfreev (parts);
+ continue;
+ }
+ dest = g_byte_array_new ();
+ g_byte_array_append (dest, (guint8 *) &rawaddr, 16);
+
+ if (inet_pton (AF_INET6, parts[1], &rawaddr) <= 0 && prefix > 128) {
+ g_warning ("%s: %s contained bad address: %s",
+ __func__, gc_key, addr);
+ g_byte_array_free (dest, TRUE);
+ g_strfreev (parts);
+ continue;
+ }
+ next_hop = g_byte_array_new ();
+ g_byte_array_append (next_hop, (guint8 *) &rawaddr, 16);
+
+ metric = strtoul (parts[2], NULL, 10);
+
+ valarr = g_value_array_new (4);
+
+ g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
+ g_value_take_boxed (&element, dest);
+ g_value_array_append (valarr, &element);
+ g_value_unset (&element);
+
+ g_value_init (&element, G_TYPE_UINT);
+ g_value_set_uint (&element, prefix);
+ g_value_array_append (valarr, &element);
+ g_value_unset (&element);
+
+ g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
+ g_value_take_boxed (&element, next_hop);
+ g_value_array_append (valarr, &element);
+ g_value_unset (&element);
+
+ g_value_init (&element, G_TYPE_UINT);
+ g_value_set_uint (&element, metric);
+ g_value_array_append (valarr, &element);
+ g_value_unset (&element);
+
+ g_ptr_array_add (array, valarr);
+ g_strfreev (parts);
+ }
+
+ *value = array;
+ success = TRUE;
+
+out:
+ if (gc_value)
+ gconf_value_free (gc_value);
+ g_free (gc_key);
+ return success;
+}
+
+gboolean
nm_gconf_set_int_helper (GConfClient *client,
const char *path,
const char *key,
@@ -675,6 +1006,51 @@ nm_gconf_set_stringlist_helper (GConfClient *client,
return TRUE;
}
+static gboolean
+nm_gconf_set_mac_address_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GByteArray *value)
+{
+ char *gc_key;
+ MacAddressKey *tmp = &mac_keys[0];
+ gboolean found = FALSE;
+ char *str;
+
+ g_return_val_if_fail (path != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (setting != NULL, FALSE);
+
+ /* Match against know setting/key combos that can be MAC addresses */
+ while (tmp->setting_name) {
+ if (!strcmp (tmp->setting_name, setting) && !strcmp (tmp->key_name, key)) {
+ found = TRUE;
+ break;
+ }
+ tmp++;
+ }
+ if (!found || !value)
+ return FALSE;
+
+ g_return_val_if_fail (value->len == ETH_ALEN, FALSE);
+
+ gc_key = g_strdup_printf ("%s/%s/%s", path, setting, key);
+ if (!gc_key) {
+ g_warning ("Not enough memory to create gconf path");
+ return FALSE;
+ }
+
+ str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ value->data[0], value->data[1], value->data[2],
+ value->data[3], value->data[4], value->data[5]);
+ gconf_client_set_string (client, gc_key, str, NULL);
+ g_free (str);
+
+ g_free (gc_key);
+ return TRUE;
+}
+
gboolean
nm_gconf_set_bytearray_helper (GConfClient *client,
const char *path,
@@ -864,7 +1240,7 @@ nm_gconf_set_stringhash_helper (GConfClient *client,
&& strcmp ((char *) basename, NM_SETTING_VPN_SERVICE_TYPE)
&& strcmp ((char *) basename, NM_SETTING_VPN_USER_NAME))
gconf_client_unset (client, entry->key, NULL);
- gconf_entry_free (entry);
+ gconf_entry_unref (entry);
g_free (basename);
}
g_slist_free (existing);
@@ -926,10 +1302,239 @@ out:
return success;
}
+gboolean
+nm_gconf_set_ip6dns_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray *value)
+{
+ char *gc_key;
+ int i;
+ GSList *list = NULL, *l;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (setting != NULL, FALSE);
+
+ if (!value)
+ return TRUE;
+
+ gc_key = g_strdup_printf ("%s/%s/%s", path, setting, key);
+ if (!gc_key) {
+ g_warning ("Not enough memory to create gconf path");
+ return FALSE;
+ }
+
+ for (i = 0; i < value->len; i++) {
+ GByteArray *ba = g_ptr_array_index (value, i);
+ char addr[INET6_ADDRSTRLEN];
+
+ if (!inet_ntop (AF_INET6, ba->data, addr, sizeof (addr))) {
+ g_warning ("%s: invalid IPv6 DNS server address!", __func__);
+ goto out;
+ }
+
+ list = g_slist_append (list, g_strdup (addr));
+ }
+
+ gconf_client_set_list (client, gc_key, GCONF_VALUE_STRING, list, NULL);
+ success = TRUE;
+
+out:
+ for (l = list; l; l = l->next)
+ g_free (l->data);
+ g_slist_free (list);
+ g_free (gc_key);
+ return success;
+}
+
+gboolean
+nm_gconf_set_ip6addr_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray *value)
+{
+ char *gc_key;
+ int i;
+ GSList *list = NULL, *l;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (setting != NULL, FALSE);
+
+ if (!value)
+ return TRUE;
+
+ gc_key = g_strdup_printf ("%s/%s/%s", path, setting, key);
+ if (!gc_key) {
+ g_warning ("Not enough memory to create gconf path");
+ return FALSE;
+ }
+
+ for (i = 0; i < value->len; i++) {
+ GValueArray *elements = (GValueArray *) g_ptr_array_index (value, i);
+ GValue *tmp;
+ GByteArray *ba;
+ guint prefix;
+ char addr[INET6_ADDRSTRLEN];
+
+ if ( (elements->n_values != 2)
+ || (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY)
+ || (G_VALUE_TYPE (g_value_array_get_nth (elements, 1)) != G_TYPE_UINT)) {
+ g_warning ("%s: invalid IPv6 address!", __func__);
+ goto out;
+ }
+
+ tmp = g_value_array_get_nth (elements, 0);
+ ba = g_value_get_boxed (tmp);
+ tmp = g_value_array_get_nth (elements, 1);
+ prefix = g_value_get_uint (tmp);
+ if (prefix > 128) {
+ g_warning ("%s: invalid IPv6 address prefix %u", __func__, prefix);
+ goto out;
+ }
+
+ if (!inet_ntop (AF_INET6, ba->data, addr, sizeof (addr))) {
+ g_warning ("%s: invalid IPv6 address!", __func__);
+ goto out;
+ }
+
+ list = g_slist_append (list, g_strdup_printf ("%s/%u", addr, prefix));
+ }
+
+ gconf_client_set_list (client, gc_key, GCONF_VALUE_STRING, list, NULL);
+ success = TRUE;
+
+out:
+ for (l = list; l; l = l->next)
+ g_free (l->data);
+ g_slist_free (list);
+ g_free (gc_key);
+ return success;
+}
+
+gboolean
+nm_gconf_set_ip6route_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray *value)
+{
+ char *gc_key;
+ int i;
+ GSList *list = NULL, *l;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (setting != NULL, FALSE);
+
+ if (!value)
+ return TRUE;
+
+ gc_key = g_strdup_printf ("%s/%s/%s", path, setting, key);
+ if (!gc_key) {
+ g_warning ("Not enough memory to create gconf path");
+ return FALSE;
+ }
+
+ for (i = 0; i < value->len; i++) {
+ GValueArray *elements = (GValueArray *) g_ptr_array_index (value, i);
+ GValue *tmp;
+ GByteArray *ba;
+ guint prefix, metric;
+ char dest[INET6_ADDRSTRLEN], next_hop[INET6_ADDRSTRLEN];
+
+ if ( (elements->n_values != 4)
+ || (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY)
+ || (G_VALUE_TYPE (g_value_array_get_nth (elements, 1)) != G_TYPE_UINT)
+ || (G_VALUE_TYPE (g_value_array_get_nth (elements, 2)) != DBUS_TYPE_G_UCHAR_ARRAY)
+ || (G_VALUE_TYPE (g_value_array_get_nth (elements, 3)) != G_TYPE_UINT))
+ {
+ g_warning ("%s: invalid IPv6 route!", __func__);
+ goto out;
+ }
+
+ tmp = g_value_array_get_nth (elements, 0);
+ ba = g_value_get_boxed (tmp);
+ if (!inet_ntop (AF_INET6, ba->data, dest, sizeof (dest))) {
+ g_warning ("%s: invalid IPv6 dest address!", __func__);
+ goto out;
+ }
+ tmp = g_value_array_get_nth (elements, 1);
+ prefix = g_value_get_uint (tmp);
+ if (prefix > 128) {
+ g_warning ("%s: invalid IPv6 dest prefix %u", __func__, prefix);
+ goto out;
+ }
+ tmp = g_value_array_get_nth (elements, 2);
+ ba = g_value_get_boxed (tmp);
+ if (!inet_ntop (AF_INET6, ba->data, next_hop, sizeof (next_hop))) {
+ g_warning ("%s: invalid IPv6 next_hop address!", __func__);
+ goto out;
+ }
+ tmp = g_value_array_get_nth (elements, 3);
+ metric = g_value_get_uint (tmp);
+
+ list = g_slist_append (list,
+ g_strdup_printf ("%s/%u,%s,%u", dest, prefix,
+ next_hop, metric));
+ }
+
+ gconf_client_set_list (client, gc_key, GCONF_VALUE_STRING, list, NULL);
+ success = TRUE;
+
+out:
+ for (l = list; l; l = l->next)
+ g_free (l->data);
+ g_slist_free (list);
+ g_free (gc_key);
+ return success;
+}
+
GSList *
nm_gconf_get_all_connections (GConfClient *client)
{
- return gconf_client_all_dirs (client, GCONF_PATH_CONNECTIONS, NULL);
+ GSList *connections;
+ guint32 stamp = 0;
+ GError *error = NULL;
+
+ stamp = (guint32) gconf_client_get_int (client, APPLET_PREFS_STAMP, &error);
+ if (error) {
+ g_error_free (error);
+ stamp = 0;
+ }
+
+ nm_gconf_migrate_0_7_connection_uuid (client);
+ nm_gconf_migrate_0_7_keyring_items (client);
+ nm_gconf_migrate_0_7_wireless_security (client);
+ nm_gconf_migrate_0_7_netmask_to_prefix (client);
+ nm_gconf_migrate_0_7_ip4_method (client);
+ nm_gconf_migrate_0_7_ignore_dhcp_dns (client);
+ nm_gconf_migrate_0_7_vpn_routes (client);
+ nm_gconf_migrate_0_7_vpn_properties (client);
+ nm_gconf_migrate_0_7_openvpn_properties (client);
+
+ if (stamp < 1) {
+ nm_gconf_migrate_0_7_vpn_never_default (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);
+ connections = gconf_client_all_dirs (client, GCONF_PATH_CONNECTIONS, NULL);
+ }
+
+ /* Update the applet GConf stamp */
+ if (stamp != APPLET_CURRENT_STAMP)
+ gconf_client_set_int (client, APPLET_PREFS_STAMP, APPLET_CURRENT_STAMP, NULL);
+
+ return connections;
}
static gboolean
@@ -950,6 +1555,18 @@ free_one_addr (gpointer data)
g_array_free ((GArray *) data, TRUE);
}
+static void
+free_one_bytearray (gpointer data)
+{
+ g_byte_array_free (data, TRUE);
+}
+
+static void
+free_one_struct (gpointer data)
+{
+ g_value_array_free (data);
+}
+
typedef struct ReadFromGConfInfo {
NMConnection *connection;
GConfClient *client;
@@ -957,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,
@@ -975,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 */
@@ -988,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)) {
@@ -1044,8 +1681,13 @@ read_one_setting_value_from_gconf (NMSetting *setting,
}
} else if (type == DBUS_TYPE_G_UCHAR_ARRAY) {
GByteArray *ba_val = NULL;
+ gboolean success = FALSE;
+
+ success = nm_gconf_get_mac_address_helper (info->client, info->dir, key, setting_name, &ba_val);
+ if (!success)
+ success = nm_gconf_get_bytearray_helper (info->client, info->dir, key, setting_name, &ba_val);
- if (nm_gconf_get_bytearray_helper (info->client, info->dir, key, setting_name, &ba_val)) {
+ if (success) {
g_object_set (setting, key, ba_val, NULL);
g_byte_array_free (ba_val, TRUE);
}
@@ -1094,62 +1736,33 @@ read_one_setting_value_from_gconf (NMSetting *setting,
g_ptr_array_foreach (pa_val, (GFunc) free_one_addr, NULL);
g_ptr_array_free (pa_val, TRUE);
}
- } else {
- g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'",
- setting_name, key, G_VALUE_TYPE_NAME (value));
- }
-}
-
-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);
-}
+ } else if (type == DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR) {
+ GPtrArray *pa_val = NULL;
-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_ip6dns_array_helper (info->client, info->dir, key, setting_name, &pa_val)) {
+ g_object_set (setting, key, pa_val, NULL);
+ g_ptr_array_foreach (pa_val, (GFunc) free_one_bytearray, NULL);
+ g_ptr_array_free (pa_val, TRUE);
}
+ } else if (type == DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS) {
+ GPtrArray *pa_val = NULL;
- if (nm_gconf_get_bool_helper (info->client, info->dir,
- NMA_PHASE2_CA_CERT_IGNORE_TAG,
- setting_name, &value)) {
- g_object_set_data (G_OBJECT (info->connection),
- NMA_PHASE2_CA_CERT_IGNORE_TAG,
- GUINT_TO_POINTER (value));
+ if (nm_gconf_get_ip6addr_array_helper (info->client, info->dir, key, setting_name, &pa_val)) {
+ g_object_set (setting, key, pa_val, NULL);
+ g_ptr_array_foreach (pa_val, (GFunc) free_one_struct, NULL);
+ g_ptr_array_free (pa_val, TRUE);
}
+ } else if (type == DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE) {
+ GPtrArray *pa_val = NULL;
- /* Binary certificate and key data doesn't get stored in GConf. Instead,
- * the path to the certificate gets stored in a special key and the
- * certificate is read and stuffed into the setting right before
- * the connection is sent to NM
- */
- read_one_cert (info, setting_name, NMA_PATH_CA_CERT_TAG);
- read_one_cert (info, setting_name, NMA_PATH_CLIENT_CERT_TAG);
- read_one_cert (info, setting_name, NMA_PATH_PRIVATE_KEY_TAG);
- read_one_cert (info, setting_name, NMA_PATH_PHASE2_CA_CERT_TAG);
- read_one_cert (info, setting_name, NMA_PATH_PHASE2_CLIENT_CERT_TAG);
- read_one_cert (info, setting_name, NMA_PATH_PHASE2_PRIVATE_KEY_TAG);
+ if (nm_gconf_get_ip6route_array_helper (info->client, info->dir, key, setting_name, &pa_val)) {
+ g_object_set (setting, key, pa_val, NULL);
+ g_ptr_array_foreach (pa_val, (GFunc) free_one_struct, NULL);
+ g_ptr_array_free (pa_val, TRUE);
+ }
+ } else {
+ g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'",
+ setting_name, key, G_VALUE_TYPE_NAME (value));
}
}
@@ -1168,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);
}
@@ -1274,23 +1886,25 @@ 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);
- if (type != G_TYPE_STRING) {
- g_warning ("Unhandled setting secret type (write) '%s/%s' : '%s'",
- setting_name, key, g_type_name (type));
- return;
- }
-
/* VPN secrets are handled by the VPN plugins */
if ( (type == DBUS_TYPE_G_MAP_OF_STRING)
&& NM_IS_SETTING_VPN (setting)
&& !strcmp (key, NM_SETTING_VPN_SECRETS))
return;
+ if (type != G_TYPE_STRING) {
+ g_warning ("Unhandled setting secret type (write) '%s/%s' : '%s'",
+ setting_name, key, g_type_name (type));
+ return;
+ }
+
secret = g_value_get_string (value);
if (secret && strlen (secret)) {
nm_gconf_add_keyring_item (info->connection_uuid,
@@ -1301,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,
@@ -1313,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 */
@@ -1349,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,
@@ -1376,9 +2392,10 @@ copy_one_setting_value_to_gconf (NMSetting *setting,
key, setting_name,
g_value_get_char (value));
} else if (type == DBUS_TYPE_G_UCHAR_ARRAY) {
- nm_gconf_set_bytearray_helper (info->client, info->dir,
- key, setting_name,
- (GByteArray *) g_value_get_boxed (value));
+ GByteArray *ba_val = (GByteArray *) g_value_get_boxed (value);
+
+ if (!nm_gconf_set_mac_address_helper (info->client, info->dir, key, setting_name, ba_val))
+ nm_gconf_set_bytearray_helper (info->client, info->dir, key, setting_name, ba_val);
} else if (type == DBUS_TYPE_G_LIST_OF_STRING) {
nm_gconf_set_stringlist_helper (info->client, info->dir,
key, setting_name,
@@ -1408,101 +2425,24 @@ copy_one_setting_value_to_gconf (NMSetting *setting,
nm_gconf_set_ip4_helper (info->client, info->dir,
key, setting_name, tuple_len,
(GPtrArray *) g_value_get_boxed (value));
+ } else if (type == DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR) {
+ nm_gconf_set_ip6dns_array_helper (info->client, info->dir,
+ key, setting_name,
+ (GPtrArray *) g_value_get_boxed (value));
+ } else if (type == DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS) {
+ nm_gconf_set_ip6addr_array_helper (info->client, info->dir,
+ key, setting_name,
+ (GPtrArray *) g_value_get_boxed (value));
+ } else if (type == DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE) {
+ nm_gconf_set_ip6route_array_helper (info->client, info->dir,
+ key, setting_name,
+ (GPtrArray *) g_value_get_boxed (value));
} else
g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'",
setting_name, key, g_type_name (type));
}
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;
@@ -1533,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);
@@ -1557,289 +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_ERROR, NM_SETTINGS_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_ERROR, NM_SETTINGS_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_ERROR, NM_SETTINGS_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;
- }
-
- 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_ERROR, NM_SETTINGS_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));
- }
- }
- }
+ GConfClient *client;
+ char *key = NULL;
+ gboolean ignore = FALSE;
- if (*error) {
- nm_warning ("%s: error reading secrets: (%d) %s", __func__,
- (*error)->code, (*error)->message);
- g_hash_table_destroy (secrets);
- secrets = NULL;
- }
+ g_return_val_if_fail (uuid != NULL, FALSE);
- gnome_keyring_found_list_free (found_list);
- return secrets;
-}
+ client = gconf_client_get_default ();
-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);
-}
+ key = get_ignore_path (uuid, phase2);
+ ignore = gconf_client_get_bool (client, key, NULL);
+ g_free (key);
-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);
+ g_object_unref (client);
+ return ignore;
}
void
-nm_gconf_clear_private_connection_values (NMConnection *connection)
+nm_gconf_set_ignore_ca_cert (const char *uuid, gboolean phase2, gboolean ignore)
{
- g_return_if_fail (NM_IS_CONNECTION (connection));
-
- 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);
-}
-
-NMConnection *
-nm_gconf_connection_duplicate (NMConnection *connection)
-{
- NMConnection *dup;
+ GConfClient *client;
+ char *key = NULL;
- g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
+ g_return_if_fail (uuid != NULL);
- dup = nm_connection_duplicate (connection);
- g_return_val_if_fail (NM_IS_CONNECTION (dup), NULL);
+ client = gconf_client_get_default ();
- nm_gconf_copy_private_connection_values (dup, 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);
- return dup;
+ g_object_unref (client);
}
diff --git a/src/gconf-helpers/gconf-helpers.h b/src/gconf-helpers/gconf-helpers.h
index df814f6..17d1ce8 100644
--- a/src/gconf-helpers/gconf-helpers.h
+++ b/src/gconf-helpers/gconf-helpers.h
@@ -27,28 +27,18 @@
#include <glib.h>
#include <nm-connection.h>
+#include "nma-gconf-connection.h"
+
#define GCONF_PATH_CONNECTIONS "/system/networking/connections"
-/*
- ATTENTION: Make sure to update nm_gconf_connection_duplicate()
- when new connection 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"
-
-NMConnection *nm_gconf_connection_duplicate (NMConnection *connection);
-
-void nm_gconf_copy_private_connection_values (NMConnection *dst, NMConnection *src);
-void nm_gconf_clear_private_connection_values (NMConnection *connection);
+/* The stamp is a mechanism for determining which applet version last
+ * updated GConf for various GConf update tasks in newer applet versions.
+ */
+#define APPLET_CURRENT_STAMP 1
+#define APPLET_PREFS_STAMP "/apps/nm-applet/stamp"
+
+#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"
@@ -126,6 +116,27 @@ nm_gconf_get_ip4_helper (GConfClient *client,
guint32 tuple_len,
GPtrArray **value);
+gboolean
+nm_gconf_get_ip6dns_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray **value);
+
+gboolean
+nm_gconf_get_ip6addr_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray **value);
+
+gboolean
+nm_gconf_get_ip6route_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray **value);
+
/* Setters */
gboolean
@@ -199,6 +210,27 @@ nm_gconf_set_ip4_helper (GConfClient *client,
guint32 tuple_len,
GPtrArray *value);
+gboolean
+nm_gconf_set_ip6dns_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray *value);
+
+gboolean
+nm_gconf_set_ip6addr_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray *value);
+
+gboolean
+nm_gconf_set_ip6route_array_helper (GConfClient *client,
+ const char *path,
+ const char *key,
+ const char *setting,
+ GPtrArray *value);
+
GSList *
nm_gconf_get_all_connections (GConfClient *client);
@@ -218,14 +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);
-
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/nma-gconf-connection.c b/src/gconf-helpers/nma-gconf-connection.c
index 4297d7c..51fe667 100644
--- a/src/gconf-helpers/nma-gconf-connection.c
+++ b/src/gconf-helpers/nma-gconf-connection.c
@@ -1,15 +1,50 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Novell, Inc.
+ * (C) Copyright 2008 - 2009 Red Hat, Inc.
+ */
#include <string.h>
+#include <unistd.h>
+
+#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 <nm-utils.h>
-#include "nma-marshal.h"
#include "gconf-helpers.h"
+#include "nm-utils.h"
#include "utils.h"
+#include "nma-marshal.h"
+#include "nm-settings-interface.h"
-G_DEFINE_TYPE (NMAGConfConnection, nma_gconf_connection, NM_TYPE_EXPORTED_CONNECTION)
+static NMSettingsConnectionInterface *parent_settings_connection_iface;
+
+static void settings_connection_interface_init (NMSettingsConnectionInterface *class);
+
+G_DEFINE_TYPE_EXTENDED (NMAGConfConnection, nma_gconf_connection, NM_TYPE_EXPORTED_CONNECTION, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE,
+ settings_connection_interface_init))
#define NMA_GCONF_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMA_TYPE_GCONF_CONNECTION, NMAGConfConnectionPrivate))
@@ -60,106 +95,97 @@ nma_gconf_connection_new (GConfClient *client, const char *conf_dir)
NMAGConfConnection *
nma_gconf_connection_new_from_connection (GConfClient *client,
- const char *conf_dir,
- NMConnection *connection)
+ const char *conf_dir,
+ NMConnection *connection)
{
+ GObject *object;
+ NMAGConfConnection *self;
+ GError *error = NULL;
+ gboolean success;
+ GHashTable *settings;
+
g_return_val_if_fail (GCONF_IS_CLIENT (client), NULL);
g_return_val_if_fail (conf_dir != NULL, NULL);
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
- return (NMAGConfConnection *) g_object_new (NMA_TYPE_GCONF_CONNECTION,
- NMA_GCONF_CONNECTION_CLIENT, client,
- NMA_GCONF_CONNECTION_DIR, conf_dir,
- NM_EXPORTED_CONNECTION_CONNECTION, connection,
- NULL);
-}
-
-const char *
-nma_gconf_connection_get_path (NMAGConfConnection *self)
-{
- g_return_val_if_fail (NMA_IS_GCONF_CONNECTION (self), NULL);
+ /* Ensure the connection is valid first */
+ success = nm_connection_verify (connection, &error);
+ if (!success) {
+ g_warning ("Invalid connection %s: '%s' / '%s' invalid: %d",
+ conf_dir,
+ g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
+ (error && error->message) ? error->message : "(unknown)",
+ error ? error->code : -1);
+ g_clear_error (&error);
+ return NULL;
+ }
- return NMA_GCONF_CONNECTION_GET_PRIVATE (self)->dir;
-}
+ object = g_object_new (NMA_TYPE_GCONF_CONNECTION,
+ NMA_GCONF_CONNECTION_CLIENT, client,
+ NMA_GCONF_CONNECTION_DIR, conf_dir,
+ NM_CONNECTION_SCOPE, NM_CONNECTION_SCOPE_USER,
+ NULL);
+ if (!object)
+ return NULL;
-/* FIXME: Remove and replace the callers with nm_exported_connection_update() */
-void
-nma_gconf_connection_save (NMAGConfConnection *self)
-{
- NMAGConfConnectionPrivate *priv;
- NMConnection *connection;
+ self = NMA_GCONF_CONNECTION (object);
- g_return_if_fail (NMA_IS_GCONF_CONNECTION (self));
+ /* Fill certs so that the nm_connection_replace_settings verification works */
+ settings = nm_connection_to_hash (connection);
+ success = nm_connection_replace_settings (NM_CONNECTION (self), settings, NULL);
+ g_hash_table_destroy (settings);
- priv = NMA_GCONF_CONNECTION_GET_PRIVATE (self);
+ /* Already verified the settings above, they had better be OK */
+ g_assert (success);
- connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (self));
- nm_gconf_write_connection (connection,
- priv->client,
- priv->dir);
- gconf_client_notify (priv->client, priv->dir);
- gconf_client_suggest_sync (priv->client, NULL);
+ return self;
}
-static void
-fill_vpn_user_name (NMConnection *connection)
+const char *
+nma_gconf_connection_get_gconf_path (NMAGConfConnection *self)
{
- const char *user_name;
- NMSettingVPN *s_vpn;
-
- s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN));
- if (!s_vpn)
- return;
+ g_return_val_if_fail (NMA_IS_GCONF_CONNECTION (self), NULL);
- user_name = g_get_user_name ();
- g_assert (g_utf8_validate (user_name, -1, NULL));
- g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, user_name, NULL);
+ return NMA_GCONF_CONNECTION_GET_PRIVATE (self)->dir;
}
gboolean
-nma_gconf_connection_changed (NMAGConfConnection *self)
+nma_gconf_connection_gconf_changed (NMAGConfConnection *self)
{
- NMAGConfConnectionPrivate *priv;
- GHashTable *settings;
- NMConnection *wrapped_connection;
- NMConnection *gconf_connection;
+ NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (self);
+ NMConnection *new;
GHashTable *new_settings;
GError *error = NULL;
+ gboolean success;
- g_return_val_if_fail (NMA_IS_GCONF_CONNECTION (self), FALSE);
-
- priv = NMA_GCONF_CONNECTION_GET_PRIVATE (self);
- wrapped_connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (self));
-
- gconf_connection = nm_gconf_read_connection (priv->client, priv->dir);
- if (!gconf_connection) {
+ new = nm_gconf_read_connection (priv->client, priv->dir);
+ if (!new) {
g_warning ("No connection read from GConf at %s.", priv->dir);
goto invalid;
}
- utils_fill_connection_certs (gconf_connection);
- if (!nm_connection_verify (gconf_connection, &error)) {
- utils_clear_filled_connection_certs (gconf_connection);
+ success = nm_connection_verify (new, &error);
+ if (!success) {
g_warning ("%s: Invalid connection %s: '%s' / '%s' invalid: %d",
__func__, priv->dir,
g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
error->message, error->code);
+ g_object_unref (new);
goto invalid;
}
- utils_clear_filled_connection_certs (gconf_connection);
/* Ignore the GConf update if nothing changed */
- if (nm_connection_compare (wrapped_connection, gconf_connection, NM_SETTING_COMPARE_FLAG_EXACT))
+ if (nm_connection_compare (NM_CONNECTION (self), new, NM_SETTING_COMPARE_FLAG_EXACT)) {
+ g_object_unref (new);
return TRUE;
+ }
- utils_fill_connection_certs (gconf_connection);
- new_settings = nm_connection_to_hash (gconf_connection);
- utils_clear_filled_connection_certs (gconf_connection);
-
- if (!nm_connection_replace_settings (wrapped_connection, new_settings, &error)) {
- utils_clear_filled_connection_certs (wrapped_connection);
- g_hash_table_destroy (new_settings);
+ new_settings = nm_connection_to_hash (new);
+ success = nm_connection_replace_settings (NM_CONNECTION (self), new_settings, &error);
+ g_hash_table_destroy (new_settings);
+ g_object_unref (new);
+ if (!success) {
g_warning ("%s: '%s' / '%s' invalid: %d",
__func__,
error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)",
@@ -167,74 +193,271 @@ nma_gconf_connection_changed (NMAGConfConnection *self)
error ? error->code : -1);
goto invalid;
}
- g_object_unref (gconf_connection);
- g_hash_table_destroy (new_settings);
- fill_vpn_user_name (wrapped_connection);
-
- settings = nm_connection_to_hash (wrapped_connection);
- utils_clear_filled_connection_certs (wrapped_connection);
-
- nm_exported_connection_signal_updated (NM_EXPORTED_CONNECTION (self), settings);
- g_hash_table_destroy (settings);
+ nm_settings_connection_interface_emit_updated (NM_SETTINGS_CONNECTION_INTERFACE (self));
return TRUE;
invalid:
g_clear_error (&error);
- nm_exported_connection_signal_removed (NM_EXPORTED_CONNECTION (self));
+ g_signal_emit_by_name (self, NM_SETTINGS_CONNECTION_INTERFACE_REMOVED);
return FALSE;
}
+/******************************************************/
-static GHashTable *
-get_settings (NMExportedConnection *exported)
+static GValue *
+string_to_gvalue (const char *str)
{
- NMConnection *connection;
- GHashTable *settings;
+ GValue *val;
- connection = nm_exported_connection_get_connection (exported);
+ val = g_slice_new0 (GValue);
+ g_value_init (val, G_TYPE_STRING);
+ g_value_set_string (val, str);
- utils_fill_connection_certs (connection);
- settings = nm_connection_to_hash (connection);
- utils_clear_filled_connection_certs (connection);
+ return val;
+}
- return settings;
+#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
-secrets_return_error (DBusGMethodInvocation *context, GError *error)
+destroy_gvalue (gpointer data)
{
- nm_warning ("Error getting secrets: %s", error->message);
- dbus_g_method_return_error (context, error);
- g_error_free (error);
+ GValue *value = (GValue *) data;
+
+ g_value_unset (value);
+ g_slice_free (GValue, value);
}
-typedef struct {
- gboolean found;
- const char **hints;
-} FindHintsInfo;
+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
-find_hints_in_secrets (gpointer key, gpointer data, gpointer user_data)
+delete_done (GnomeKeyringResult result, gpointer user_data)
{
- FindHintsInfo *info = (FindHintsInfo *) user_data;
- const char **iter;
+}
- for (iter = info->hints; !info->found && *iter; iter++) {
- if (!strcmp (*iter, (const char *) key) && data && G_IS_VALUE (data))
- info->found = TRUE;
+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 void
-service_get_secrets (NMExportedConnection *exported,
- const gchar *setting_name,
- const gchar **hints,
- gboolean request_new,
- DBusGMethodInvocation *context)
+/******************************************************/
+
+static gboolean
+update (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceUpdateFunc callback,
+ gpointer user_data)
{
- NMConnection *connection;
+ NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (connection);
+
+ nm_gconf_write_connection (NM_CONNECTION (connection),
+ priv->client,
+ priv->dir);
+ gconf_client_notify (priv->client, priv->dir);
+ gconf_client_suggest_sync (priv->client, NULL);
+
+ return parent_settings_connection_iface->update (connection, callback, user_data);
+}
+
+static gboolean
+do_delete (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceDeleteFunc callback,
+ gpointer user_data)
+{
+ NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (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);
+ g_error_free (error);
+ return FALSE;
+ }
+ gconf_client_suggest_sync (priv->client, NULL);
+
+ return parent_settings_connection_iface->delete (connection, callback, user_data);
+}
+
+static gboolean
+internal_get_secrets (NMSettingsConnectionInterface *connection,
+ const char *setting_name,
+ const char **hints,
+ gboolean request_new,
+ gboolean local,
+ NMANewSecretsRequestedFunc callback,
+ gpointer callback_data,
+ GError **error)
+{
+ NMAGConfConnection *self = NMA_GCONF_CONNECTION (connection);
GHashTable *settings = NULL;
GHashTable *secrets = NULL;
NMSettingConnection *s_con;
@@ -242,71 +465,92 @@ service_get_secrets (NMExportedConnection *exported,
const char *connection_id;
const char *connection_type;
- connection = nm_exported_connection_get_connection (exported);
-
- setting = nm_connection_get_setting_by_name (connection, setting_name);
+ setting = nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name);
if (!setting) {
- g_set_error (&error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ g_set_error (error,
+ NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
"%s.%d - Connection didn't have requested setting '%s'.",
__FILE__, __LINE__, setting_name);
- secrets_return_error (context, error);
- return;
+ return FALSE;
}
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
- connection_id = s_con ? nm_setting_connection_get_id (s_con) : NULL;
- connection_type = s_con ? nm_setting_connection_get_connection_type (s_con) : NULL;
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+ connection_id = nm_setting_connection_get_id (s_con);
+ connection_type = nm_setting_connection_get_connection_type (s_con);
if (!s_con || !connection_id || !strlen (connection_id) || !connection_type) {
- g_set_error (&error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ g_set_error (error,
+ NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
"%s.%d - Connection didn't have required '"
NM_SETTING_CONNECTION_SETTING_NAME
"' setting , or the connection name was invalid.",
__FILE__, __LINE__);
- secrets_return_error (context, error);
- return;
+ return FALSE;
}
- /* VPN passwords are handled by the VPN plugin's auth dialog */
- if (!strcmp (connection_type, NM_SETTING_VPN_SETTING_NAME))
- goto get_secrets;
-
- if (request_new) {
- nm_info ("New secrets for %s/%s requested; ask the user",
- connection_id, setting_name);
- nm_connection_clear_secrets (connection);
- goto get_secrets;
- }
+ /* Only try to get new secrets for D-Bus requests */
+ if (local) {
+ secrets = nma_gconf_connection_get_keyring_items (self, setting_name, error);
+ if (!secrets && error && *error)
+ return FALSE;
+ } else {
+ /* VPN passwords are handled by the VPN plugin's auth dialog */
+ if (!strcmp (connection_type, NM_SETTING_VPN_SETTING_NAME))
+ goto get_secrets;
- secrets = nm_gconf_get_keyring_items (connection, setting_name, FALSE, &error);
- if (!secrets) {
- if (error) {
- secrets_return_error (context, error);
- return;
+ if (request_new) {
+ nm_info ("New secrets for %s/%s requested; ask the user",
+ connection_id, setting_name);
+ nm_connection_clear_secrets (NM_CONNECTION (self));
+ goto get_secrets;
}
- nm_info ("No keyring secrets found for %s/%s; asking user.",
- connection_id, setting_name);
- goto get_secrets;
- }
- if (g_hash_table_size (secrets) == 0) {
- g_hash_table_destroy (secrets);
- nm_warning ("%s.%d - Secrets were found for setting '%s' but none"
- " were valid.", __FILE__, __LINE__, setting_name);
- goto get_secrets;
- }
+ secrets = nma_gconf_connection_get_keyring_items (self, setting_name, error);
+ if (!secrets) {
+ if (error && *error)
+ return FALSE;
- /* If there were hints, and none of the hints were returned by the keyring,
- * get some new secrets.
- */
- if (hints && g_strv_length ((char **) hints)) {
- FindHintsInfo info = { .found = FALSE, .hints = hints };
+ nm_info ("No keyring secrets found for %s/%s; asking user.",
+ connection_id, setting_name);
+ goto get_secrets;
+ }
- g_hash_table_foreach (secrets, find_hints_in_secrets, &info);
- if (info.found == FALSE) {
+ if (g_hash_table_size (secrets) == 0) {
g_hash_table_destroy (secrets);
+ nm_warning ("%s.%d - Secrets were found for setting '%s' but none"
+ " were valid.", __FILE__, __LINE__, setting_name);
goto get_secrets;
}
+
+ /* If there were hints, and none of the hints were returned by the keyring,
+ * get some new secrets.
+ */
+ if (hints && g_strv_length ((char **) hints)) {
+ GHashTableIter iter;
+ gpointer key, value;
+ gboolean found = FALSE;
+
+ g_hash_table_iter_init (&iter, secrets);
+ while (g_hash_table_iter_next (&iter, &key, &value) && !found) {
+ const char **hint = hints;
+
+ while (!found && *hint) {
+ if (!strcmp (*hint, (const char *) key) && value && G_IS_VALUE (value)) {
+ found = TRUE;
+ break;
+ }
+ hint++;
+ }
+ }
+
+ if (!found) {
+ g_hash_table_destroy (secrets);
+ goto get_secrets;
+ }
+ }
}
/* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that
@@ -315,65 +559,298 @@ service_get_secrets (NMExportedConnection *exported,
settings = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free,
(GDestroyNotify) g_hash_table_destroy);
- g_hash_table_insert (settings, g_strdup (setting_name), secrets);
- dbus_g_method_return (context, settings);
+ if (secrets)
+ g_hash_table_insert (settings, g_strdup (setting_name), secrets);
+ callback (NM_SETTINGS_CONNECTION_INTERFACE (self), settings, NULL, callback_data);
g_hash_table_destroy (settings);
- return;
+ return TRUE;
get_secrets:
- g_signal_emit (exported,
+ g_signal_emit (self,
signals[NEW_SECRETS_REQUESTED],
0,
setting_name,
hints,
request_new,
- context);
+ callback,
+ callback_data);
+ return TRUE;
+}
+
+typedef struct {
+ NMSettingsConnectionInterfaceGetSecretsFunc callback;
+ gpointer callback_data;
+} GetSecretsInfo;
+
+static void
+get_secrets_cb (NMSettingsConnectionInterface *connection,
+ GHashTable *settings,
+ GError *error,
+ gpointer user_data)
+{
+ GetSecretsInfo *info = user_data;
+
+ info->callback (NM_SETTINGS_CONNECTION_INTERFACE (connection), settings, error, info->callback_data);
+ g_free (info);
}
static gboolean
-update (NMExportedConnection *exported, GHashTable *new_settings, GError **error)
+get_secrets (NMSettingsConnectionInterface *connection,
+ const char *setting_name,
+ const char **hints,
+ gboolean request_new,
+ NMSettingsConnectionInterfaceGetSecretsFunc callback,
+ gpointer user_data)
{
- NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (exported);
- NMConnection *tmp;
- GError *local_error = NULL;
+ GetSecretsInfo *info;
+ GError *error = NULL;
+
+ info = g_malloc0 (sizeof (GetSecretsInfo));
+ info->callback = callback;
+ info->callback_data = user_data;
+
+ if (!internal_get_secrets (connection,
+ setting_name,
+ hints,
+ request_new,
+ TRUE,
+ get_secrets_cb,
+ info,
+ &error)) {
+ callback (NM_SETTINGS_CONNECTION_INTERFACE (connection), NULL, error, user_data);
+ g_error_free (error);
+ g_free (info);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/******************************************************/
+
+static gboolean
+is_dbus_request_authorized (DBusGMethodInvocation *context,
+ gboolean allow_user,
+ GError **error)
+{
+ DBusGConnection *bus = NULL;
+ DBusConnection *connection = NULL;
+ char *sender = NULL;
+ gulong sender_uid = G_MAXULONG;
+ DBusError dbus_error;
gboolean success = FALSE;
- tmp = nm_connection_new_from_hash (new_settings, &local_error);
- if (!tmp) {
- nm_warning ("%s: Invalid connection: '%s' / '%s' invalid: %d",
- __func__,
- g_type_name (nm_connection_lookup_setting_type_by_quark (local_error->domain)),
- local_error->message, local_error->code);
+ sender = dbus_g_method_get_sender (context);
+ if (!sender) {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ "%s", "Could not determine D-Bus requestor");
+ goto out;
+ }
- g_propagate_error (error, local_error);
- } else {
- /* Copy private values to the connection that actually gets saved */
- nm_gconf_copy_private_connection_values (tmp, nm_exported_connection_get_connection (exported));
+ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+ if (!bus) {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ "%s", "Could not get the system bus");
+ goto out;
+ }
+ connection = dbus_g_connection_get_connection (bus);
+ if (!connection) {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ "%s", "Could not get the D-Bus system bus");
+ goto out;
+ }
- nm_gconf_write_connection (tmp, priv->client, priv->dir);
- g_object_unref (tmp);
+ dbus_error_init (&dbus_error);
+ sender_uid = dbus_bus_get_unix_user (connection, sender, &dbus_error);
+ if (dbus_error_is_set (&dbus_error)) {
+ dbus_error_free (&dbus_error);
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_PERMISSION_DENIED,
+ "%s", "Could not determine the Unix user ID of the requestor");
+ goto out;
+ }
- gconf_client_notify (priv->client, priv->dir);
- gconf_client_suggest_sync (priv->client, NULL);
+ /* And finally, the actual UID check */
+ if ( (allow_user && (sender_uid == geteuid()))
+ || (sender_uid == 0))
success = TRUE;
+ else {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_PERMISSION_DENIED,
+ "%s", "Requestor UID does not match the UID of the user settings service");
}
+out:
+ if (bus)
+ dbus_g_connection_unref (bus);
+ g_free (sender);
return success;
}
-static gboolean
-do_delete (NMExportedConnection *exported, GError **err)
+static void
+con_update_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data)
{
- NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (exported);
- gboolean success;
+ DBusGMethodInvocation *context = user_data;
- success = gconf_client_recursive_unset (priv->client, priv->dir, 0, err);
- gconf_client_suggest_sync (priv->client, NULL);
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context);
+}
- return success;
+static void
+dbus_update (NMExportedConnection *exported,
+ GHashTable *new_settings,
+ DBusGMethodInvocation *context)
+{
+ NMAGConfConnection *self = NMA_GCONF_CONNECTION (exported);
+ NMConnection *new;
+ gboolean success = FALSE;
+ GError *error = NULL;
+
+ /* Restrict Update to execution by the current user and root for DBus invocation */
+ if (!is_dbus_request_authorized (context, TRUE, &error)) {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ new = nm_connection_new_from_hash (new_settings, &error);
+ if (!new) {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+ g_object_unref (new);
+
+ success = nm_connection_replace_settings (NM_CONNECTION (self), new_settings, NULL);
+ /* Settings better be valid; we verified them above */
+ g_assert (success);
+
+ nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (self),
+ con_update_cb,
+ context);
}
-/* GObject */
+static void
+con_delete_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data)
+{
+ DBusGMethodInvocation *context = user_data;
+
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context);
+}
+
+static void
+dbus_delete (NMExportedConnection *exported,
+ DBusGMethodInvocation *context)
+{
+ NMAGConfConnection *self = NMA_GCONF_CONNECTION (exported);
+ GError *error = NULL;
+
+ /* Restrict Update to execution by the current user and root for DBus invocation */
+ if (!is_dbus_request_authorized (context, TRUE, &error)) {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ nm_settings_connection_interface_delete (NM_SETTINGS_CONNECTION_INTERFACE (self),
+ con_delete_cb,
+ context);
+}
+
+static void
+dbus_get_secrets_cb (NMSettingsConnectionInterface *connection,
+ GHashTable *settings,
+ GError *error,
+ gpointer user_data)
+{
+ DBusGMethodInvocation *context = user_data;
+
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context, settings);
+}
+
+static void
+dbus_get_secrets (NMExportedConnection *connection,
+ const gchar *setting_name,
+ const gchar **hints,
+ gboolean request_new,
+ DBusGMethodInvocation *context)
+{
+ GError *error = NULL;
+
+ /* Restrict GetSecrets to execution by root for DBus invocation */
+ if (!is_dbus_request_authorized (context, FALSE, &error)) {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ if (!internal_get_secrets (NM_SETTINGS_CONNECTION_INTERFACE (connection),
+ setting_name,
+ hints,
+ request_new,
+ FALSE,
+ dbus_get_secrets_cb,
+ context,
+ &error)) {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
+}
+
+static GHashTable *
+dbus_get_settings (NMExportedConnection *connection, GError **error)
+{
+ GHashTable *settings;
+ const char *user_name;
+ NMSettingVPN *s_vpn;
+ gboolean added = FALSE;
+
+ /* Insert the default VPN username when NM gets the connection; it doesn't
+ * get stored in GConf since it's always available and could change at any
+ * time, so it's inserted on-the-fly.
+ */
+ s_vpn = NM_SETTING_VPN (nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_VPN));
+ if (s_vpn) {
+ user_name = g_get_user_name ();
+ g_assert (g_utf8_validate (user_name, -1, NULL));
+ g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, user_name, NULL);
+ added = TRUE;
+ }
+
+ settings = NM_EXPORTED_CONNECTION_CLASS (nma_gconf_connection_parent_class)->get_settings (connection, error);
+
+ if (added)
+ g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, NULL, NULL);
+
+ return settings;
+}
+
+/************************************************************/
+
+static void
+settings_connection_interface_init (NMSettingsConnectionInterface *iface)
+{
+ parent_settings_connection_iface = g_type_interface_peek_parent (iface);
+
+ iface->update = update;
+ iface->delete = do_delete;
+ iface->get_secrets = get_secrets;
+}
static void
nma_gconf_connection_init (NMAGConfConnection *connection)
@@ -382,14 +859,11 @@ nma_gconf_connection_init (NMAGConfConnection *connection)
static GObject *
constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
{
GObject *object;
NMAGConfConnectionPrivate *priv;
- NMConnection *connection;
- DBusGConnection *bus;
- GError *error = NULL;
object = G_OBJECT_CLASS (nma_gconf_connection_parent_class)->constructor (type, n_construct_params, construct_params);
@@ -400,47 +874,17 @@ constructor (GType type,
if (!priv->client) {
nm_warning ("GConfClient not provided.");
- goto err;
+ g_object_unref (object);
+ return NULL;
}
if (!priv->dir) {
nm_warning ("GConf directory not provided.");
- goto err;
- }
-
- connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (object));
-
- utils_fill_connection_certs (connection);
- if (!nm_connection_verify (connection, &error)) {
- utils_clear_filled_connection_certs (connection);
- g_warning ("Invalid connection: '%s' / '%s' invalid: %d",
- g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
- error->message, error->code);
- g_error_free (error);
- goto err;
- }
- utils_clear_filled_connection_certs (connection);
-
- fill_vpn_user_name (connection);
-
- bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
- if (!bus) {
- nm_warning ("Could not get the system bus: %s", error->message);
- g_error_free (error);
- goto err;
+ g_object_unref (object);
+ return NULL;
}
- nm_exported_connection_register_object (NM_EXPORTED_CONNECTION (object),
- NM_CONNECTION_SCOPE_USER,
- bus);
- dbus_g_connection_unref (bus);
-
return object;
-
- err:
- g_object_unref (object);
-
- return NULL;
}
static void
@@ -508,12 +952,12 @@ get_property (GObject *object, guint prop_id,
}
static void
-nma_gconf_connection_class_init (NMAGConfConnectionClass *gconf_connection_class)
+nma_gconf_connection_class_init (NMAGConfConnectionClass *class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (gconf_connection_class);
- NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (gconf_connection_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ NMExportedConnectionClass *ec_class = NM_EXPORTED_CONNECTION_CLASS (class);
- g_type_class_add_private (gconf_connection_class, sizeof (NMAGConfConnectionPrivate));
+ g_type_class_add_private (class, sizeof (NMAGConfConnectionPrivate));
/* Virtual methods */
object_class->constructor = constructor;
@@ -522,10 +966,10 @@ nma_gconf_connection_class_init (NMAGConfConnectionClass *gconf_connection_class
object_class->dispose = dispose;
object_class->finalize = finalize;
- connection_class->get_settings = get_settings;
- connection_class->service_get_secrets = service_get_secrets;
- connection_class->update = update;
- connection_class->do_delete = do_delete;
+ ec_class->update = dbus_update;
+ ec_class->delete = dbus_delete;
+ ec_class->get_secrets = dbus_get_secrets;
+ ec_class->get_settings = dbus_get_settings;
/* Properties */
g_object_class_install_property
@@ -551,7 +995,7 @@ nma_gconf_connection_class_init (NMAGConfConnectionClass *gconf_connection_class
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMAGConfConnectionClass, new_secrets_requested),
NULL, NULL,
- nma_marshal_VOID__STRING_POINTER_BOOLEAN_POINTER,
- G_TYPE_NONE, 4,
- G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_POINTER);
+ nma_marshal_VOID__STRING_POINTER_BOOLEAN_POINTER_POINTER,
+ G_TYPE_NONE, 5,
+ G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_POINTER);
}
diff --git a/src/gconf-helpers/nma-gconf-connection.h b/src/gconf-helpers/nma-gconf-connection.h
index da23244..296ca58 100644
--- a/src/gconf-helpers/nma-gconf-connection.h
+++ b/src/gconf-helpers/nma-gconf-connection.h
@@ -1,11 +1,32 @@
-/* -*- 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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Novell, Inc.
+ * (C) Copyright 2008 Red Hat, Inc.
+ */
#ifndef NMA_GCONF_CONNECTION_H
#define NMA_GCONF_CONNECTION_H
#include <gconf/gconf-client.h>
#include <dbus/dbus-glib.h>
-#include <nm-settings.h>
+#include <nm-connection.h>
+#include <nm-exported-connection.h>
+#include <nm-settings-connection-interface.h>
G_BEGIN_DECLS
@@ -23,6 +44,11 @@ typedef struct {
NMExportedConnection parent;
} NMAGConfConnection;
+typedef void (*NMANewSecretsRequestedFunc) (NMSettingsConnectionInterface *connection,
+ GHashTable *settings,
+ GError *error,
+ gpointer user_data);
+
typedef struct {
NMExportedConnectionClass parent;
@@ -37,17 +63,15 @@ typedef struct {
GType nma_gconf_connection_get_type (void);
NMAGConfConnection *nma_gconf_connection_new (GConfClient *client,
- const char *conf_dir);
+ const char *conf_dir);
NMAGConfConnection *nma_gconf_connection_new_from_connection (GConfClient *client,
- const char *conf_dir,
- NMConnection *connection);
-
-const char *nma_gconf_connection_get_path (NMAGConfConnection *self);
+ const char *conf_dir,
+ NMConnection *connection);
-void nma_gconf_connection_save (NMAGConfConnection *self);
+gboolean nma_gconf_connection_gconf_changed (NMAGConfConnection *self);
-gboolean nma_gconf_connection_changed (NMAGConfConnection *self);
+const char *nma_gconf_connection_get_gconf_path (NMAGConfConnection *self);
G_END_DECLS
diff --git a/src/gconf-helpers/nma-gconf-settings.c b/src/gconf-helpers/nma-gconf-settings.c
index cbe4c17..986d947 100644
--- a/src/gconf-helpers/nma-gconf-settings.c
+++ b/src/gconf-helpers/nma-gconf-settings.c
@@ -1,13 +1,32 @@
-/* -*- 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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Novell, Inc.
+ */
#include <string.h>
#include <stdio.h>
-#include <nm-utils.h>
+
#include "nma-gconf-settings.h"
#include "gconf-helpers.h"
#include "nma-marshal.h"
+#include "nm-utils.h"
-G_DEFINE_TYPE (NMAGConfSettings, nma_gconf_settings, NM_TYPE_SETTINGS)
+G_DEFINE_TYPE (NMAGConfSettings, nma_gconf_settings, NM_TYPE_SETTINGS_SERVICE)
#define NMA_GCONF_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMA_TYPE_GCONF_SETTINGS, NMAGConfSettingsPrivate))
@@ -31,9 +50,12 @@ static guint signals[LAST_SIGNAL] = { 0 };
NMAGConfSettings *
-nma_gconf_settings_new (void)
+nma_gconf_settings_new (DBusGConnection *bus)
{
- return (NMAGConfSettings *) g_object_new (NMA_TYPE_GCONF_SETTINGS, NULL);
+ return (NMAGConfSettings *) g_object_new (NMA_TYPE_GCONF_SETTINGS,
+ NM_SETTINGS_SERVICE_SCOPE, NM_CONNECTION_SCOPE_USER,
+ NM_SETTINGS_SERVICE_BUS, bus,
+ NULL);
}
static void
@@ -41,7 +63,8 @@ connection_new_secrets_requested_cb (NMAGConfConnection *connection,
const char *setting_name,
const char **hints,
gboolean ask_user,
- DBusGMethodInvocation *context,
+ NMANewSecretsRequestedFunc callback,
+ gpointer callback_data,
gpointer user_data)
{
NMAGConfSettings *self = NMA_GCONF_SETTINGS (user_data);
@@ -56,33 +79,57 @@ connection_new_secrets_requested_cb (NMAGConfConnection *connection,
setting_name,
hints,
ask_user,
- context);
+ callback,
+ callback_data);
}
static void
-connection_removed (NMAGConfConnection *connection,
- gpointer user_data)
+connection_removed (NMExportedConnection *connection, gpointer user_data)
{
NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (user_data);
priv->connections = g_slist_remove (priv->connections, connection);
+ g_object_unref (connection);
}
static void
-add_connection_real (NMAGConfSettings *self, NMAGConfConnection *connection)
+internal_add_connection (NMAGConfSettings *self, NMAGConfConnection *connection)
{
NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (self);
+ 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",
+ G_CALLBACK (connection_new_secrets_requested_cb),
+ self);
+
+ g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), self);
- if (connection) {
- priv->connections = g_slist_prepend (priv->connections, connection);
- g_signal_connect (connection, "new-secrets-requested",
- G_CALLBACK (connection_new_secrets_requested_cb),
- self);
+ g_object_get (G_OBJECT (self), NM_SETTINGS_SERVICE_BUS, &bus, NULL);
+ if (bus) {
+ nm_settings_service_export_connection (NM_SETTINGS_SERVICE (self),
+ NM_SETTINGS_CONNECTION_INTERFACE (connection));
+ dbus_g_connection_unref (bus);
+ }
- g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), self);
+ 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));
+}
- nm_settings_signal_new_connection (NM_SETTINGS (self),
- NM_EXPORTED_CONNECTION (connection));
+static void
+update_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data)
+{
+ if (error) {
+ g_warning ("%s: %s:%d error updating connection %s: (%d) %s",
+ __func__, __FILE__, __LINE__,
+ nma_gconf_connection_get_gconf_path (NMA_GCONF_CONNECTION (connection)),
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "(unknown)");
}
}
@@ -117,44 +164,45 @@ nma_gconf_settings_add_connection (NMAGConfSettings *self, NMConnection *connect
exported = nma_gconf_connection_new_from_connection (priv->client, path, connection);
g_free (path);
- if (!exported)
- return NULL;
-
- add_connection_real (self, exported);
+ if (exported) {
+ internal_add_connection (self, exported);
- /* Must save connection to GConf _after_ adding it to the connections
- * list to avoid races with GConf notifications.
- */
- nma_gconf_connection_save (exported);
+ /* Must save connection to GConf _after_ adding it to the connections
+ * list to avoid races with GConf notifications.
+ */
+ nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (exported), update_cb, NULL);
+ }
return exported;
}
-NMAGConfConnection *
-nma_gconf_settings_get_by_path (NMAGConfSettings *self, const char *path)
+static void
+add_connection (NMSettingsService *settings,
+ NMConnection *connection,
+ DBusGMethodInvocation *context, /* Only present for D-Bus calls */
+ NMSettingsAddConnectionFunc callback,
+ gpointer user_data)
{
- NMAGConfSettingsPrivate *priv;
- GSList *iter;
-
- g_return_val_if_fail (NMA_IS_GCONF_SETTINGS (self), NULL);
- g_return_val_if_fail (path != NULL, NULL);
+ NMAGConfSettings *self = NMA_GCONF_SETTINGS (settings);
- priv = NMA_GCONF_SETTINGS_GET_PRIVATE (self);
- for (iter = priv->connections; iter; iter = iter->next) {
- NMAGConfConnection *connection = NMA_GCONF_CONNECTION (iter->data);
- const char *gconf_path;
+ /* For now, we don't support additions via D-Bus until we figure out
+ * the security implications.
+ */
+ if (context) {
+ GError *error;
- gconf_path = nma_gconf_connection_get_path (connection);
- if (gconf_path && !strcmp (gconf_path, path))
- return connection;
+ error = g_error_new (0, 0, "%s: adding connections via D-Bus is not (yet) supported", __func__);
+ callback (NM_SETTINGS_INTERFACE (settings), error, user_data);
+ g_error_free (error);
+ return;
}
- return NULL;
+ nma_gconf_settings_add_connection (self, connection);
+ callback (NM_SETTINGS_INTERFACE (settings), NULL, user_data);
}
-NMAGConfConnection *
-nma_gconf_settings_get_by_dbus_path (NMAGConfSettings *self,
- const char *path)
+static NMAGConfConnection *
+get_connection_by_gconf_path (NMAGConfSettings *self, const char *path)
{
NMAGConfSettingsPrivate *priv;
GSList *iter;
@@ -165,42 +213,16 @@ nma_gconf_settings_get_by_dbus_path (NMAGConfSettings *self,
priv = NMA_GCONF_SETTINGS_GET_PRIVATE (self);
for (iter = priv->connections; iter; iter = iter->next) {
NMAGConfConnection *connection = NMA_GCONF_CONNECTION (iter->data);
- NMConnection *wrapped;
- const char *sc_path;
-
- wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection));
- sc_path = nm_connection_get_path (wrapped);
+ const char *gconf_path;
- if (sc_path && !strcmp (sc_path, path))
+ gconf_path = nma_gconf_connection_get_gconf_path (connection);
+ if (gconf_path && !strcmp (gconf_path, path))
return connection;
}
return NULL;
}
-NMAGConfConnection *
-nma_gconf_settings_get_by_connection (NMAGConfSettings *self,
- NMConnection *connection)
-{
- NMAGConfSettingsPrivate *priv;
- GSList *iter;
-
- g_return_val_if_fail (NMA_IS_GCONF_SETTINGS (self), NULL);
- g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
-
- priv = NMA_GCONF_SETTINGS_GET_PRIVATE (self);
-
- for (iter = priv->connections; iter; iter = iter->next) {
- NMConnection *wrapped;
-
- wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (iter->data));
- if (connection == wrapped)
- return NMA_GCONF_CONNECTION (iter->data);
- }
-
- return NULL;
-}
-
static void
read_connections (NMAGConfSettings *settings)
{
@@ -214,8 +236,11 @@ read_connections (NMAGConfSettings *settings)
for (iter = dir_list; iter; iter = iter->next) {
char *dir = (char *) iter->data;
+ NMAGConfConnection *connection;
- add_connection_real (settings, nma_gconf_connection_new (priv->client, dir));
+ connection = nma_gconf_connection_new (priv->client, dir);
+ if (connection)
+ internal_add_connection (settings, connection);
g_free (dir);
}
@@ -233,7 +258,7 @@ read_connections_cb (gpointer data)
}
static GSList *
-list_connections (NMSettings *settings)
+list_connections (NMSettingsService *settings)
{
NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (settings);
@@ -268,15 +293,16 @@ connection_changes_done (gpointer data)
NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (info->settings);
NMAGConfConnection *connection;
- connection = nma_gconf_settings_get_by_path (info->settings, info->path);
+ connection = get_connection_by_gconf_path (info->settings, info->path);
if (!connection) {
/* New connection */
connection = nma_gconf_connection_new (priv->client, info->path);
- add_connection_real (info->settings, connection);
+ if (connection)
+ internal_add_connection (info->settings, connection);
} else {
if (gconf_client_dir_exists (priv->client, info->path, NULL)) {
/* Updated connection */
- if (!nma_gconf_connection_changed (connection))
+ if (!nma_gconf_connection_gconf_changed (connection))
priv->connections = g_slist_remove (priv->connections, connection);
}
}
@@ -336,12 +362,12 @@ remove_pending_change (gpointer data)
g_source_remove (GPOINTER_TO_UINT (data));
}
-/* GObject */
+/************************************************************/
static void
-nma_gconf_settings_init (NMAGConfSettings *settings)
+nma_gconf_settings_init (NMAGConfSettings *self)
{
- NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (settings);
+ NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (self);
priv->client = gconf_client_get_default ();
priv->pending_changes = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, remove_pending_change);
@@ -352,10 +378,10 @@ nma_gconf_settings_init (NMAGConfSettings *settings)
NULL);
priv->conf_notify_id = gconf_client_notify_add (priv->client,
- GCONF_PATH_CONNECTIONS,
- (GConfClientNotifyFunc) connections_changed_cb,
- settings,
- NULL, NULL);
+ GCONF_PATH_CONNECTIONS,
+ (GConfClientNotifyFunc) connections_changed_cb,
+ self,
+ NULL, NULL);
}
static GObject *
@@ -364,17 +390,10 @@ constructor (GType type,
GObjectConstructParam *construct_params)
{
GObject *object;
- NMAGConfSettingsPrivate *priv;
object = G_OBJECT_CLASS (nma_gconf_settings_parent_class)->constructor (type, n_construct_params, construct_params);
-
- if (!object)
- return NULL;
-
- priv = NMA_GCONF_SETTINGS_GET_PRIVATE (object);
-
- priv->read_connections_id = g_idle_add (read_connections_cb, object);
-
+ if (object)
+ NMA_GCONF_SETTINGS_GET_PRIVATE (object)->read_connections_id = g_idle_add (read_connections_cb, object);
return object;
}
@@ -407,18 +426,19 @@ dispose (GObject *object)
}
static void
-nma_gconf_settings_class_init (NMAGConfSettingsClass *gconf_settings_class)
+nma_gconf_settings_class_init (NMAGConfSettingsClass *class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (gconf_settings_class);
- NMSettingsClass *settings_class = NM_SETTINGS_CLASS (gconf_settings_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ NMSettingsServiceClass *settings_class = NM_SETTINGS_SERVICE_CLASS (class);
- g_type_class_add_private (gconf_settings_class, sizeof (NMAGConfSettingsPrivate));
+ g_type_class_add_private (class, sizeof (NMAGConfSettingsPrivate));
/* Virtual methods */
object_class->constructor = constructor;
object_class->dispose = dispose;
settings_class->list_connections = list_connections;
+ settings_class->add_connection = add_connection;
/* Signals */
signals[NEW_SECRETS_REQUESTED] =
@@ -427,7 +447,7 @@ nma_gconf_settings_class_init (NMAGConfSettingsClass *gconf_settings_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMAGConfSettingsClass, new_secrets_requested),
NULL, NULL,
- nma_marshal_VOID__OBJECT_STRING_POINTER_BOOLEAN_POINTER,
- G_TYPE_NONE, 5,
- G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_POINTER);
+ nma_marshal_VOID__OBJECT_STRING_POINTER_BOOLEAN_POINTER_POINTER,
+ G_TYPE_NONE, 6,
+ G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_POINTER);
}
diff --git a/src/gconf-helpers/nma-gconf-settings.h b/src/gconf-helpers/nma-gconf-settings.h
index 2011081..d197a35 100644
--- a/src/gconf-helpers/nma-gconf-settings.h
+++ b/src/gconf-helpers/nma-gconf-settings.h
@@ -1,11 +1,29 @@
-/* -*- 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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Novell, Inc.
+ */
#ifndef NMA_GCONF_SETTINGS_H
#define NMA_GCONF_SETTINGS_H
-#include <dbus/dbus-glib.h>
#include <nm-connection.h>
-#include <nm-settings.h>
+#include <nm-settings-service.h>
+
#include "nma-gconf-connection.h"
G_BEGIN_DECLS
@@ -18,36 +36,28 @@ G_BEGIN_DECLS
#define NMA_GCONF_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMA_TYPE_GCONF_SETTINGS, NMAGConfSettingsClass))
typedef struct {
- NMSettings parent;
+ NMSettingsService parent;
} NMAGConfSettings;
typedef struct {
- NMSettingsClass parent;
+ NMSettingsServiceClass parent;
/* Signals */
void (*new_secrets_requested) (NMAGConfSettings *self,
- NMAGConfConnection *exported,
- const char *setting_name,
- const char **hints,
- gboolean ask_user,
- DBusGMethodInvocation *context);
+ NMAGConfConnection *exported,
+ const char *setting_name,
+ const char **hints,
+ gboolean ask_user,
+ NMANewSecretsRequestedFunc callback,
+ gpointer callback_data);
} NMAGConfSettingsClass;
GType nma_gconf_settings_get_type (void);
-NMAGConfSettings *nma_gconf_settings_new (void);
+NMAGConfSettings *nma_gconf_settings_new (DBusGConnection *bus);
NMAGConfConnection *nma_gconf_settings_add_connection (NMAGConfSettings *self,
- NMConnection *connection);
-
-NMAGConfConnection *nma_gconf_settings_get_by_path (NMAGConfSettings *self,
- const char *path);
-
-NMAGConfConnection *nma_gconf_settings_get_by_dbus_path (NMAGConfSettings *self,
- const char *path);
-
-NMAGConfConnection *nma_gconf_settings_get_by_connection (NMAGConfSettings *self,
- NMConnection *connection);
+ NMConnection *connection);
G_END_DECLS
diff --git a/src/marshallers/nma-marshal.list b/src/marshallers/nma-marshal.list
index 8cb2830..4cf3524 100644
--- a/src/marshallers/nma-marshal.list
+++ b/src/marshallers/nma-marshal.list
@@ -1,4 +1,7 @@
VOID:POINTER
VOID:STRING,STRING,STRING
-VOID:STRING,POINTER,BOOLEAN,POINTER
-VOID:OBJECT,STRING,POINTER,BOOLEAN,POINTER
+VOID:STRING,POINTER,BOOLEAN,POINTER,POINTER
+VOID:OBJECT,STRING,POINTER,BOOLEAN,POINTER,POINTER
+VOID:POINTER,POINTER
+VOID:INT,POINTER
+
diff --git a/src/nmn-applet.h b/src/nmn-applet.h
index 314ffa7..48a3c65 100644
--- a/src/nmn-applet.h
+++ b/src/nmn-applet.h
@@ -26,6 +26,10 @@
G_BEGIN_DECLS
+#define APPLET_PREFS_PATH "/apps/nm-applet"
+#define PREF_DISABLE_CONNECTED_NOTIFICATIONS APPLET_PREFS_PATH "/disable-connected-notifications"
+#define PREF_DISABLE_DISCONNECTED_NOTIFICATIONS APPLET_PREFS_PATH "/disable-disconnected-notifications"
+
#define NMN_TYPE_APPLET (nmn_applet_get_type ())
#define NMN_APPLET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMN_TYPE_APPLET, NmnApplet))
#define NMN_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMN_TYPE_APPLET, NmnAppletClass))
diff --git a/src/nmn-device-handler.c b/src/nmn-device-handler.c
index 75fd5c2..d48f78a 100644
--- a/src/nmn-device-handler.c
+++ b/src/nmn-device-handler.c
@@ -17,6 +17,8 @@
* (C) Copyright 2009 Novell, Inc.
*/
+#include <nm-settings-interface.h>
+#include <nm-setting-connection.h>
#include "nmn-device-handler.h"
G_DEFINE_TYPE (NmnDeviceHandler, nmn_device_handler, G_TYPE_OBJECT)
@@ -44,14 +46,13 @@ typedef struct {
GSList *items;
gboolean started;
gulong device_state_changed_id;
- gulong user_connection_added_id;
- gulong system_connection_added_id;
+ gulong connection_added_id;
gboolean disposed;
} NmnDeviceHandlerPrivate;
static void
-connection_added (NMSettings *settings,
+connection_added (NMSettingConnection *settings,
NMExportedConnection *exported,
gpointer user_data)
{
@@ -101,7 +102,7 @@ device_state_changed (NMDevice *device,
void
nmn_device_handler_start (NmnDeviceHandler *self)
{
- NMSettings *settings;
+ NMSettingsInterface *settings;
NmnDeviceHandlerPrivate *priv;
g_return_if_fail (NMN_IS_DEVICE_HANDLER (self));
@@ -117,13 +118,8 @@ nmn_device_handler_start (NmnDeviceHandler *self)
settings = nmn_nm_data_get_user_settings (priv->nm_data);
if (settings)
- priv->user_connection_added_id = g_signal_connect (settings, "new-connection",
- G_CALLBACK (connection_added), self);
-
- settings = nmn_nm_data_get_system_settings (priv->nm_data);
- if (settings)
- priv->system_connection_added_id = g_signal_connect (settings, "new-connection",
- G_CALLBACK (connection_added), self);
+ priv->connection_added_id = g_signal_connect (settings, "new-connection",
+ G_CALLBACK (connection_added), self);
nmn_device_handler_add_items (self);
}
@@ -180,7 +176,7 @@ GSList *
nmn_device_handler_get_connections (NmnDeviceHandler *self)
{
NmnDeviceHandlerPrivate *priv;
- NMSettings *settings;
+ NMSettingsInterface *settings;
GSList *list = NULL;
g_return_val_if_fail (NMN_IS_DEVICE_HANDLER (self), NULL);
@@ -189,11 +185,7 @@ nmn_device_handler_get_connections (NmnDeviceHandler *self)
settings = nmn_nm_data_get_user_settings (priv->nm_data);
if (settings)
- list = nm_settings_list_connections (settings);
-
- settings = nmn_nm_data_get_system_settings (priv->nm_data);
- if (settings)
- list = g_slist_concat (list, nm_settings_list_connections (settings));
+ list = nm_settings_interface_list_connections (settings);
return list;
}
@@ -210,7 +202,7 @@ nmn_device_handler_get_item_for_connection (NmnDeviceHandler *self,
list = GET_PRIVATE (self)->items;
for (iter = list; iter; iter = iter->next) {
- if (nmn_network_item_get_connection (NMN_NETWORK_ITEM (iter->data)) == connection)
+ if (nmn_network_item_get_connection (NMN_NETWORK_ITEM (iter->data)) == NM_EXPORTED_CONNECTION (connection))
return NMN_NETWORK_ITEM (iter->data);
}
@@ -310,7 +302,7 @@ static void
dispose (GObject *object)
{
NmnDeviceHandlerPrivate *priv = GET_PRIVATE (object);
- NMSettings *settings;
+ NMSettingsInterface *settings;
if (priv->disposed)
return;
@@ -318,10 +310,7 @@ dispose (GObject *object)
g_signal_handler_disconnect (priv->device, priv->device_state_changed_id);
settings = nmn_nm_data_get_user_settings (priv->nm_data);
- g_signal_handler_disconnect (settings, priv->user_connection_added_id);
-
- settings = nmn_nm_data_get_system_settings (priv->nm_data);
- g_signal_handler_disconnect (settings, priv->system_connection_added_id);
+ g_signal_handler_disconnect (settings, priv->connection_added_id);
g_slist_foreach (priv->items, (GFunc) g_object_unref, NULL);
g_slist_free (priv->items);
diff --git a/src/nmn-device-handler.h b/src/nmn-device-handler.h
index 7ffa0f5..15d4b9b 100644
--- a/src/nmn-device-handler.h
+++ b/src/nmn-device-handler.h
@@ -22,7 +22,7 @@
#include <glib-object.h>
#include <nm-device.h>
-#include <nm-settings.h>
+#include <nm-exported-connection.h>
#include "nmn-nm-data.h"
#include "nmn-network-item.h"
diff --git a/src/nmn-ethernet-handler.c b/src/nmn-ethernet-handler.c
index d8430c7..aca4de6 100644
--- a/src/nmn-ethernet-handler.c
+++ b/src/nmn-ethernet-handler.c
@@ -18,7 +18,6 @@
*/
#include <string.h>
-#include <nm-settings.h>
#include "nmn-ethernet-handler.h"
#include "nmn-ethernet-item.h"
#include "utils.h"
@@ -75,7 +74,7 @@ connection_added (NmnDeviceHandler *handler,
if (!nm_device_ethernet_get_carrier (device))
return;
- wrapped = nm_exported_connection_get_connection (exported);
+ wrapped = NM_CONNECTION (exported);
if (utils_connection_valid_for_device (wrapped, NM_DEVICE (device), NULL) &&
!have_item_for_connection (handler, exported)) {
item = nmn_ethernet_item_new (nmn_device_handler_get_nm_data (handler), device);
diff --git a/src/nmn-ethernet-item.c b/src/nmn-ethernet-item.c
index 692ac11..c1d4edf 100644
--- a/src/nmn-ethernet-item.c
+++ b/src/nmn-ethernet-item.c
@@ -65,34 +65,45 @@ nmn_ethernet_item_new (NmnNMData *nm_data,
NULL));
}
+static void
+update_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer data)
+{
+ NMSettingConnection *s_con;
+ NmnNetworkItem *item = data;
+
+ if (error != NULL) {
+ g_warning ("Updating auto-connect for ethernet failed: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ s_con = NM_SETTING_CONNECTION (connection);
+ if (nm_setting_connection_get_autoconnect (s_con) == TRUE) {
+ NMN_NETWORK_ITEM_CLASS (nmn_ethernet_item_parent_class)->connect (item);
+ } else {
+ NMN_NETWORK_ITEM_CLASS (nmn_ethernet_item_parent_class)->disconnect (item);
+ }
+}
+
static gboolean
update_autoconnect (NmnNetworkItem *item, gboolean connect_automatically)
{
NMExportedConnection *exported;
NMConnection *wrapped;
NMSettingConnection *s_con;
- GHashTable *new_settings;
GError *error = NULL;
exported = nmn_network_item_get_connection (item);
- wrapped = nm_exported_connection_get_connection (exported);
+ wrapped = NM_CONNECTION (exported);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
if (nm_setting_connection_get_autoconnect (s_con) == connect_automatically)
return FALSE;
g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, connect_automatically, NULL);
- new_settings = nm_connection_to_hash (wrapped);
-
- if (!nm_exported_connection_update (exported, new_settings, &error)) {
- if (error) {
- g_warning ("Couldn't update ethernet connection: %s", error->message);
- g_error_free (error);
- } else
- g_warning ("Couldn't update ethernet connection: no details");
- }
-
- g_hash_table_unref (new_settings);
+ nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (s_con),
+ update_cb, item);
return TRUE;
}
@@ -101,7 +112,6 @@ static void
connect (NmnNetworkItem *item)
{
update_autoconnect (NMN_NETWORK_ITEM (item), TRUE);
- NMN_NETWORK_ITEM_CLASS (nmn_ethernet_item_parent_class)->connect (item);
}
static void
@@ -109,7 +119,6 @@ disconnect (NmnNetworkItem *item)
{
/* Turn off autoconnect, otherwise it would reconnect right back. */
update_autoconnect (item, FALSE);
- NMN_NETWORK_ITEM_CLASS (nmn_ethernet_item_parent_class)->disconnect (item);
}
static guint
diff --git a/src/nmn-network-item.c b/src/nmn-network-item.c
index 55dd055..63410ee 100644
--- a/src/nmn-network-item.c
+++ b/src/nmn-network-item.c
@@ -119,7 +119,7 @@ update_details (NmnNetworkItem *self)
if (!priv->details || !priv->connection)
return;
- connection = nm_exported_connection_get_connection (priv->connection);
+ connection = NM_CONNECTION (priv->connection);
setting = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
if (nm_device_get_state (priv->device) == NM_DEVICE_STATE_ACTIVATED)
@@ -195,7 +195,7 @@ update_item (NmnNetworkItem *self)
g_assert (priv->connection);
- wrapped = nm_exported_connection_get_connection (priv->connection);
+ wrapped = NM_CONNECTION (priv->connection);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
nmn_item_set_name (item, nm_setting_connection_get_id (s_con));
@@ -319,7 +319,7 @@ connection_secrets_requested_cb (NMExportedConnection *connection,
else {
GError *error = NULL;
- g_set_error_literal (&error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE,
+ g_set_error_literal (&error, NM_SETTINGS_INTERFACE_ERROR, NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE,
G_STRLOC "no secrets found");
g_warning ("%s", error->message);
@@ -336,8 +336,10 @@ connect_cb (gpointer user_data,
/* FIXME: Report the error somewhere */
}
-static gboolean
-delayed_connect (gpointer data)
+static void
+update_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer data)
{
NmnItem *item = NMN_ITEM (data);
NmnNetworkItemPrivate *priv = GET_PRIVATE (item);
@@ -347,7 +349,13 @@ delayed_connect (gpointer data)
const char *specific_object;
NMConnectionScope scope;
- wrapped = nm_exported_connection_get_connection (priv->connection);
+ if (error != NULL) {
+ g_warning ("Updating settings failed: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ wrapped = NM_CONNECTION (priv->connection);
path = nm_connection_get_path (wrapped);
scope = nm_connection_get_scope (wrapped);
@@ -366,8 +374,13 @@ delayed_connect (gpointer data)
specific_object,
connect_cb,
NULL);
+}
- return FALSE;
+static gboolean
+delayed_connect (gpointer data)
+{
+ update_cb (NULL, NULL, data);
+ return FALSE;
}
static void
@@ -386,21 +399,16 @@ connect (NmnNetworkItem *item)
NMSetting *current_config;
NMSetting *new_config;
- wrapped = nm_exported_connection_get_connection (priv->connection);
+ wrapped = NM_CONNECTION (priv->connection);
current_config = nm_connection_get_setting (wrapped, NM_TYPE_SETTING_IP4_CONFIG);
new_config = NM_SETTING (nmn_connection_details_get_data (NMN_CONNECTION_DETAILS (details)));
g_assert (new_config);
if (current_config == NULL || nm_setting_compare (current_config, new_config, 0) == FALSE) {
- GHashTable *new_settings;
-
nm_connection_add_setting (wrapped, new_config);
- new_settings = nm_connection_to_hash (wrapped);
- nm_exported_connection_update (priv->connection, new_settings, NULL);
- g_hash_table_unref (new_settings);
+ nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (new_config),
+ update_cb, item);
- /* Ugh... Give NM a bit of time to get the new values */
- g_timeout_add_seconds (1, delayed_connect, item);
return;
}
}
@@ -539,7 +547,8 @@ item_delete (NmnNetworkItem *item)
NMExportedConnection *exported = nmn_network_item_get_connection (item);
if (exported)
- nm_exported_connection_delete (exported, NULL);
+ nm_settings_connection_interface_delete (NM_SETTINGS_CONNECTION_INTERFACE (exported),
+ NULL, NULL);
}
static guint
diff --git a/src/nmn-network-item.h b/src/nmn-network-item.h
index 497376e..726baaf 100644
--- a/src/nmn-network-item.h
+++ b/src/nmn-network-item.h
@@ -22,7 +22,7 @@
#include <gtk/gtk.h>
#include <dbus/dbus-glib.h>
-#include <nm-settings.h>
+#include <nm-exported-connection.h>
#include "nmn-item.h"
#include "nmn-connection-details.h"
#include "nmn-nm-data.h"
diff --git a/src/nmn-networks.c b/src/nmn-networks.c
index 7ae135e..fc26945 100644
--- a/src/nmn-networks.c
+++ b/src/nmn-networks.c
@@ -20,7 +20,6 @@
#include <string.h>
#include <glib/gi18n.h>
#include <NetworkManager.h>
-#include <nm-settings.h>
#include <nm-device-ethernet.h>
#include <nm-device-wifi.h>
#include "nmn-networks.h"
@@ -172,7 +171,7 @@ find_ac_for_item (NmnNetworks *self, NmnNetworkItem *item)
int i;
acs = nm_client_get_active_connections (NM_CLIENT (priv->nm_data));
- connection = nm_exported_connection_get_connection (nmn_network_item_get_connection (item));
+ connection = NM_CONNECTION (nmn_network_item_get_connection (item));
path = nm_connection_get_path (connection);
scope = nm_connection_get_scope (connection);
diff --git a/src/nmn-nm-data.c b/src/nmn-nm-data.c
index f095888..ac02135 100644
--- a/src/nmn-nm-data.c
+++ b/src/nmn-nm-data.c
@@ -17,7 +17,7 @@
* (C) Copyright 2009 Novell, Inc.
*/
-#include <nm-dbus-settings-system.h>
+#include <nm-remote-settings.h>
#include "nmn-nm-data.h"
#include "nma-gconf-settings.h"
@@ -37,8 +37,8 @@ static guint signals[LAST_SIGNAL];
#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_NM_DATA, NmnNMDataPrivate))
typedef struct {
- NMSettings *user_settings;
- NMSettings *system_settings;
+ NMSettingsInterface *user_settings;
+ NMSettingsInterface *system_settings;
gboolean ethernet_active;
gboolean wifi_active;
@@ -57,7 +57,7 @@ nmn_nm_data_new (DBusGConnection *bus)
NULL));
}
-NMSettings *
+NMSettingsInterface *
nmn_nm_data_get_user_settings (NmnNMData *self)
{
g_return_val_if_fail (NMN_IS_NM_DATA (self), NULL);
@@ -65,7 +65,7 @@ nmn_nm_data_get_user_settings (NmnNMData *self)
return GET_PRIVATE (self)->user_settings;
}
-NMSettings *
+NMSettingsInterface *
nmn_nm_data_get_system_settings (NmnNMData *self)
{
g_return_val_if_fail (NMN_IS_NM_DATA (self), NULL);
@@ -235,8 +235,8 @@ constructor (GType type,
priv = GET_PRIVATE (object);
bus = nm_object_get_connection (NM_OBJECT (object));
- priv->user_settings = NM_SETTINGS (nma_gconf_settings_new ());
- priv->system_settings = NM_SETTINGS (nm_dbus_settings_system_new (bus));
+ priv->user_settings = NM_SETTINGS_INTERFACE (nma_gconf_settings_new (bus));
+ priv->system_settings = NM_SETTINGS_INTERFACE (nm_remote_settings_new (bus, NM_CONNECTION_SCOPE_SYSTEM));
g_signal_connect (object,
"notify::" NM_CLIENT_STATE,
diff --git a/src/nmn-nm-data.h b/src/nmn-nm-data.h
index 894da91..c099661 100644
--- a/src/nmn-nm-data.h
+++ b/src/nmn-nm-data.h
@@ -22,7 +22,7 @@
#include <dbus/dbus-glib.h>
#include <nm-client.h>
-#include <nm-settings.h>
+#include <nm-settings-interface.h>
#define NMN_TYPE_NM_DATA (nmn_nm_data_get_type ())
#define NMN_NM_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMN_TYPE_NM_DATA, NmnNMData))
@@ -55,9 +55,9 @@ typedef struct {
GType nmn_nm_data_get_type (void);
-NmnNMData *nmn_nm_data_new (DBusGConnection *bus);
-NMSettings *nmn_nm_data_get_user_settings (NmnNMData *data);
-NMSettings *nmn_nm_data_get_system_settings (NmnNMData *data);
+NmnNMData *nmn_nm_data_new (DBusGConnection *bus);
+NMSettingsInterface *nmn_nm_data_get_user_settings (NmnNMData *data);
+NMSettingsInterface *nmn_nm_data_get_system_settings (NmnNMData *data);
gboolean nmn_nm_data_ethernet_get_active (NmnNMData *self);
void nmn_nm_data_ethernet_toggled (NmnNMData *self,
diff --git a/src/nmn-serial-handler.c b/src/nmn-serial-handler.c
index 0fe7fd4..53d2b12 100644
--- a/src/nmn-serial-handler.c
+++ b/src/nmn-serial-handler.c
@@ -17,7 +17,6 @@
* (C) Copyright 2009 Novell, Inc.
*/
-#include <nm-settings.h>
#include "nmn-serial-handler.h"
#include "nmn-serial-item.h"
#include "utils.h"
@@ -53,7 +52,7 @@ connection_added (NmnDeviceHandler *handler,
NMDevice *device;
GtkWidget *item;
- wrapped = nm_exported_connection_get_connection (exported);
+ wrapped = NM_CONNECTION (exported);
device = nmn_device_handler_get_device (handler);
if (!utils_connection_valid_for_device (wrapped, device, NULL))
diff --git a/src/nmn-wifi-handler.c b/src/nmn-wifi-handler.c
index 27c8bfc..1ba8098 100644
--- a/src/nmn-wifi-handler.c
+++ b/src/nmn-wifi-handler.c
@@ -18,7 +18,6 @@
*/
#include <string.h>
-#include <nm-settings.h>
#include <nm-setting-connection.h>
#include <nm-setting-wireless.h>
#include "nmn-wifi-handler.h"
@@ -101,7 +100,7 @@ find_best_ap_for_connection (NMDeviceWifi *device,
NMAccessPoint *best_ap = NULL;
int i;
- wrapped = nm_exported_connection_get_connection (connection);
+ wrapped = NM_CONNECTION (connection);
aps = nm_device_wifi_get_access_points (device);
for (i = 0; aps && i < aps->len; i++) {
NMAccessPoint *ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i));
@@ -189,7 +188,7 @@ connection_added (NmnDeviceHandler *handler,
NMAccessPoint *ap;
GtkWidget *item;
- wrapped = nm_exported_connection_get_connection (exported);
+ wrapped = NM_CONNECTION (exported);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
connection_type = nm_setting_connection_get_connection_type (s_con);
diff --git a/src/nmn-wifi-item.c b/src/nmn-wifi-item.c
index 0ee9d2c..a1c9713 100644
--- a/src/nmn-wifi-item.c
+++ b/src/nmn-wifi-item.c
@@ -428,6 +428,27 @@ wireless_dialog_response_cb (NMAWirelessDialog *dialog,
gtk_widget_destroy (GTK_WIDGET (dialog));
}
+static void
+update_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer data)
+{
+ NMSettingConnection *s_con;
+ NmnNetworkItem *item = data;
+
+ if (error != NULL) {
+ g_warning ("Updating auto-connect for wifi failed: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ s_con = NM_SETTING_CONNECTION (connection);
+ if (nm_setting_connection_get_autoconnect (s_con) == TRUE) {
+ NMN_NETWORK_ITEM_CLASS (nmn_wifi_item_parent_class)->connect (item);
+ } else {
+ NMN_NETWORK_ITEM_CLASS (nmn_wifi_item_parent_class)->disconnect (item);
+ }
+}
+
static gboolean
update_autoconnect (NmnNetworkItem *item, gboolean connect_automatically)
{
@@ -437,17 +458,16 @@ update_autoconnect (NmnNetworkItem *item, gboolean connect_automatically)
GHashTable *new_settings;
exported = nmn_network_item_get_connection (item);
- wrapped = nm_exported_connection_get_connection (exported);
+ wrapped = NM_CONNECTION (exported);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
if (nm_setting_connection_get_autoconnect (s_con) == connect_automatically)
return FALSE;
g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, connect_automatically, NULL);
- new_settings = nm_connection_to_hash (wrapped);
- nm_exported_connection_update (exported, new_settings, NULL);
- g_hash_table_unref (new_settings);
+ nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (s_con),
+ update_cb, item);
return TRUE;
}
@@ -517,14 +537,12 @@ add_one_setting (GHashTable *settings,
{
GHashTable *secrets;
- 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 {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INTERNAL_ERROR,
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR, NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
G_STRLOC ": failed to hash setting '%s'.",
nm_setting_get_name (setting));
}
@@ -550,17 +568,17 @@ secrets_requested_response_cb (NMAWirelessDialog *dialog,
GError *error = NULL;
if (response != GTK_RESPONSE_OK) {
- g_set_error_literal (&error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED,
+ g_set_error_literal (&error, NM_SETTINGS_INTERFACE_ERROR, NM_SETTINGS_INTERFACE_ERROR_SECRETS_REQUEST_CANCELED,
G_STRLOC ": canceled");
goto done;
}
- wrapped = nm_exported_connection_get_connection (info->exported);
+ wrapped = NM_CONNECTION (info->exported);
/* Second-guess which setting NM wants secrets for. */
s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_WIRELESS_SECURITY));
if (!s_wireless_sec) {
- g_set_error_literal (&error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ g_set_error_literal (&error, NM_SETTINGS_INTERFACE_ERROR, NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
G_STRLOC ": requested setting '802-11-wireless-security'"
" didn't exist in the connection.");
goto done; /* Unencrypted */
@@ -589,7 +607,7 @@ secrets_requested_response_cb (NMAWirelessDialog *dialog,
s_8021x = (NMSetting8021x *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_802_1X);
if (!s_8021x) {
- g_set_error_literal (&error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ g_set_error_literal (&error, NM_SETTINGS_INTERFACE_ERROR, NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
G_STRLOC ": requested setting '802-1x' didn't"
" exist in the connection.");
goto done;
@@ -643,7 +661,7 @@ secrets_requested (NmnNetworkItem *network_item,
exported = nmn_network_item_get_connection (network_item);
dialog = nma_wireless_dialog_new (NM_CLIENT (nmn_network_item_get_nm_data (network_item)),
- nm_exported_connection_get_connection (exported),
+ NM_CONNECTION (exported),
nmn_network_item_get_device (network_item),
nmn_wifi_item_get_ap (NMN_WIFI_ITEM (network_item)));
diff --git a/src/nmn-wifi-list.c b/src/nmn-wifi-list.c
index 3cdbf5c..662b34e 100644
--- a/src/nmn-wifi-list.c
+++ b/src/nmn-wifi-list.c
@@ -74,9 +74,9 @@ matching_connection_exists (NmnWifiList *list, NMDevice *device, NMAccessPoint *
GSList *iter;
gboolean exists = FALSE;
- connections = nm_settings_list_connections (nmn_nm_data_get_user_settings (priv->nm_data));
+ connections = nm_settings_interface_list_connections (nmn_nm_data_get_user_settings (priv->nm_data));
for (iter = connections; iter; iter = iter->next) {
- NMConnection *connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (iter->data));
+ NMConnection *connection = NM_CONNECTION (NM_EXPORTED_CONNECTION (iter->data));
if (utils_connection_valid_for_device (connection, device, ap)) {
exists = TRUE;
diff --git a/src/utils.c b/src/utils.c
index 0486678..575f94b 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -27,6 +27,7 @@
#include <moblin-panel/mpl-panel-client.h>
#include <nm-device-ethernet.h>
#include <nm-device-wifi.h>
+#include <nm-device-bt.h>
#include <nm-gsm-device.h>
#include <nm-cdma-device.h>
#include <nm-access-point.h>
@@ -38,6 +39,7 @@
#include <nm-setting-gsm.h>
#include <nm-setting-cdma.h>
#include <nm-setting-pppoe.h>
+#include <nm-setting-bluetooth.h>
#include <nm-utils.h>
#include "utils.h"
@@ -81,6 +83,7 @@ static char *ignored_words[] = {
"Components",
"Corporation",
"Communications",
+ "Company",
"Corp.",
"Corp",
"Co.",
@@ -93,6 +96,7 @@ static char *ignored_words[] = {
"adapter",
"[hex]",
"NDIS",
+ "Module",
NULL
};
@@ -114,6 +118,7 @@ static char *ignored_phrases[] = {
"Communication S.p.A.",
"Business Mobile Networks BV",
"Mobile Broadband Minicard Composite Device",
+ "Mobile Communications AB",
NULL
};
@@ -133,12 +138,11 @@ fixup_desc_string (const char *desc)
/* Attempt to shorten ID by ignoring certain phrases */
for (item = ignored_phrases; *item; item++) {
- guint32 temp_len = strlen (temp);
guint32 ignored_len = strlen (*item);
p = strstr (temp, *item);
if (p)
- memmove (p, p + ignored_len, temp_len - (p - temp));
+ memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */
}
/* Attmept to shorten ID by ignoring certain individual words */
@@ -218,142 +222,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;
@@ -773,6 +641,66 @@ connection_valid_for_cdma (NMConnection *connection,
return TRUE;
}
+static guint32
+get_connection_bt_type (NMConnection *connection)
+{
+ NMSettingBluetooth *s_bt;
+ const char *bt_type;
+
+ s_bt = (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
+ if (!s_bt)
+ return NM_BT_CAPABILITY_NONE;
+
+ bt_type = nm_setting_bluetooth_get_connection_type (s_bt);
+ g_assert (bt_type);
+
+ if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN))
+ return NM_BT_CAPABILITY_DUN;
+ else if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU))
+ return NM_BT_CAPABILITY_NAP;
+
+ return NM_BT_CAPABILITY_NONE;
+}
+
+static gboolean
+connection_valid_for_bt (NMConnection *connection,
+ NMSettingConnection *s_con,
+ NMDevice *device,
+ gpointer specific_object)
+{
+ NMSettingBluetooth *s_bt;
+ const GByteArray *array;
+ char *str;
+ const char *hw_addr;
+ int addr_match = FALSE;
+ guint32 bt_type;
+
+ if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME))
+ return FALSE;
+
+ s_bt = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
+ if (!s_bt)
+ return FALSE;
+
+ array = nm_setting_bluetooth_get_bdaddr (s_bt);
+ if (!array || (array->len != ETH_ALEN))
+ return FALSE;
+
+ bt_type = get_connection_bt_type (connection);
+ if (!(bt_type & nm_device_bt_get_capabilities (NM_DEVICE_BT (device))))
+ return FALSE;
+
+ str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ array->data[0], array->data[1], array->data[2],
+ array->data[3], array->data[4], array->data[5]);
+ hw_addr = nm_device_bt_get_hw_address (NM_DEVICE_BT (device));
+ if (hw_addr)
+ addr_match = !g_ascii_strcasecmp (hw_addr, str);
+ g_free (str);
+
+ return addr_match;
+}
+
gboolean
utils_connection_valid_for_device (NMConnection *connection,
NMDevice *device,
@@ -795,6 +723,8 @@ utils_connection_valid_for_device (NMConnection *connection,
return connection_valid_for_gsm (connection, s_con, device, specific_object);
else if (NM_IS_CDMA_DEVICE (device))
return connection_valid_for_cdma (connection, s_con, device, specific_object);
+ else if (NM_IS_DEVICE_BT (device))
+ return connection_valid_for_bt (connection, s_con, device, specific_object);
else
g_warning ("Unknown device type '%s'", g_type_name (G_OBJECT_TYPE(device)));
@@ -858,6 +788,46 @@ utils_ether_ntop (const struct ether_addr *mac)
mac->ether_addr_octet[4], mac->ether_addr_octet[5]);
}
+char *
+utils_next_available_name (GSList *connections, const char *format)
+{
+ GSList *names = NULL, *iter;
+ char *cname = NULL;
+ int i = 0;
+
+ for (iter = connections; iter; iter = g_slist_next (iter)) {
+ NMConnection *candidate = NM_CONNECTION (iter->data);
+ NMSettingConnection *s_con;
+ const char *id;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION));
+ id = nm_setting_connection_get_id (s_con);
+ g_assert (id);
+ names = g_slist_append (names, (gpointer) id);
+ }
+
+ /* Find the next available unique connection name */
+ while (!cname && (i++ < 10000)) {
+ char *temp;
+ gboolean found = FALSE;
+
+ temp = g_strdup_printf (format, i);
+ for (iter = names; iter; iter = g_slist_next (iter)) {
+ if (!strcmp (iter->data, temp)) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ cname = temp;
+ else
+ g_free (temp);
+ }
+
+ g_slist_free (names);
+ return cname;
+}
+
static MplPanelClient *main_widget = NULL;
static void
diff --git a/src/utils.h b/src/utils.h
index 396b2b1..d4dd553 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -31,11 +31,7 @@
char * utils_bin2hexstr (const char *bytes, int len, int final_len);
-const char * utils_get_device_description (NMDevice *device);
-
-void utils_fill_connection_certs (NMConnection *connection);
-
-void utils_clear_filled_connection_certs (NMConnection *connection);
+const char *utils_get_device_description (NMDevice *device);
guint32 utils_freq_to_channel (guint32 freq);
guint32 utils_channel_to_freq (guint32 channel, char *band);
@@ -53,6 +49,8 @@ char *utils_ether_ntop (const struct ether_addr *mac);
gboolean utils_mac_valid (const struct ether_addr *addr);
+char *utils_next_available_name (GSList *connections, const char *format);
+
/* Ugh, please avert your eyes... */
void utils_set_main_widget (GObject *panel_client);
void utils_hide_main_widget (void);
diff --git a/src/wireless-dialog.c b/src/wireless-dialog.c
index 6b5788e..aa860ac 100644
--- a/src/wireless-dialog.c
+++ b/src/wireless-dialog.c
@@ -37,7 +37,6 @@
#include <nm-setting-connection.h>
#include <nm-setting-wireless.h>
#include <nm-setting-ip4-config.h>
-#include <nm-settings.h>
#include "wireless-dialog.h"
#include "wireless-security.h"
diff --git a/src/wireless-security/Makefile.am b/src/wireless-security/Makefile.am
index 4e6aea1..ad019d7 100644
--- a/src/wireless-security/Makefile.am
+++ b/src/wireless-security/Makefile.am
@@ -33,6 +33,7 @@ libwireless_security_la_SOURCES = \
libwireless_security_la_CPPFLAGS = \
$(NMN_CFLAGS) \
-I${top_srcdir}/src/gconf-helpers \
+ -I${top_srcdir}/src/ \
-DUIDIR=\""$(uidir)"\"
libwireless_security_la_LIBADD = \
diff --git a/src/wireless-security/eap-method-peap.c b/src/wireless-security/eap-method-peap.c
index 7d3b1e9..893c1c8 100644
--- a/src/wireless-security/eap-method-peap.c
+++ b/src/wireless-security/eap-method-peap.c
@@ -22,6 +22,7 @@
#include <glib/gi18n.h>
#include <ctype.h>
#include <string.h>
+#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
@@ -108,7 +109,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;
@@ -116,6 +119,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);
@@ -131,19 +138,14 @@ fill_connection (EAPMethod *parent, NMConnection *connection)
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "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 = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_combo"));
peapver_active = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
@@ -275,7 +277,7 @@ eap_method_peap_new (WirelessSecurity *parent,
builder = EAP_METHOD (method)->builder;
- eap_method_nag_init (EAP_METHOD (method), "ca-nag-dialog.ui", "eap_peap_ca_cert_button", connection);
+ eap_method_nag_init (EAP_METHOD (method), "ca-nag-dialog.ui", "eap_peap_ca_cert_button", connection, FALSE);
method->sec_parent = parent;
@@ -292,10 +294,12 @@ eap_method_peap_new (WirelessSecurity *parent,
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, connection);
diff --git a/src/wireless-security/eap-method-tls.c b/src/wireless-security/eap-method-tls.c
index 62448c9..707d43e 100644
--- a/src/wireless-security/eap-method-tls.c
+++ b/src/wireless-security/eap-method-tls.c
@@ -24,6 +24,7 @@
#include <glib/gi18n.h>
#include <ctype.h>
#include <string.h>
+#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "gconf-helpers.h"
@@ -131,12 +132,17 @@ 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;
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);
@@ -149,37 +155,24 @@ 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 = GTK_WIDGET (gtk_builder_get_object (parent->builder, "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);
- }
- /* TLS private key */
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "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);
}
@@ -196,10 +189,17 @@ fill_connection (EAPMethod *parent, NMConnection *connection)
}
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);
+ 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_free (pk_filename);
@@ -207,27 +207,23 @@ fill_connection (EAPMethod *parent, NMConnection *connection)
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "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);
- }
- 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, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+ g_warning ("Couldn't read phase2 CA certificate '%s': %s", 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, 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);
+ }
}
+
+ nm_gconf_set_ignore_ca_cert (nm_setting_connection_get_uuid (s_con),
+ method->phase2,
+ eap_method_get_ignore_ca_cert (parent));
}
static void
@@ -276,48 +272,50 @@ 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 (GtkBuilder *builder,
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 = GTK_WIDGET (gtk_builder_get_object (builder, 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
* and desensitize the user cert button.
*/
if (privkey) {
- g_signal_connect (G_OBJECT (widget), "file-set",
+ g_signal_connect (G_OBJECT (widget), "selection-changed",
(GCallback) private_key_picker_file_set_cb,
method);
if (filename)
private_key_picker_helper ((EAPMethod *) method, filename, FALSE);
}
- g_signal_connect (G_OBJECT (widget), "file-set",
+ g_signal_connect (G_OBJECT (widget), "selection-changed",
(GCallback) wireless_security_changed_cb,
parent);
@@ -352,7 +350,7 @@ eap_method_tls_new (WirelessSecurity *parent,
builder = EAP_METHOD (method)->builder;
- eap_method_nag_init (EAP_METHOD (method), "ca-nag-dialog.ui", "eap_tls_ca_cert_button", connection);
+ eap_method_nag_init (EAP_METHOD (method), "ca-nag-dialog.ui", "eap_tls_ca_cert_button", connection, phase2);
method->phase2 = phase2;
@@ -385,20 +383,25 @@ eap_method_tls_new (WirelessSecurity *parent,
g_signal_connect (G_OBJECT (widget), "changed",
(GCallback) wireless_security_changed_cb,
parent);
-
setup_filepicker (builder, "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 (builder, "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 (builder,
"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 = GTK_WIDGET (gtk_builder_get_object (builder, "eap_tls_show_checkbutton"));
g_assert (widget);
diff --git a/src/wireless-security/eap-method-ttls.c b/src/wireless-security/eap-method-ttls.c
index 1852fe9..d53f61e 100644
--- a/src/wireless-security/eap-method-ttls.c
+++ b/src/wireless-security/eap-method-ttls.c
@@ -22,6 +22,7 @@
#include <glib/gi18n.h>
#include <ctype.h>
#include <string.h>
+#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
@@ -104,13 +105,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);
@@ -126,19 +133,14 @@ fill_connection (EAPMethod *parent, NMConnection *connection)
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "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 = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo"));
model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
@@ -305,7 +307,7 @@ eap_method_ttls_new (WirelessSecurity *parent,
builder = EAP_METHOD (method)->builder;
- eap_method_nag_init (EAP_METHOD (method), "ca-nag-dialog.ui", "eap_ttls_ca_cert_button", connection);
+ eap_method_nag_init (EAP_METHOD (method), "ca-nag-dialog.ui", "eap_ttls_ca_cert_button", connection, FALSE);
method->sec_parent = parent;
@@ -322,10 +324,12 @@ eap_method_ttls_new (WirelessSecurity *parent,
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 = GTK_WIDGET (gtk_builder_get_object (builder, "eap_ttls_anon_identity_entry"));
diff --git a/src/wireless-security/eap-method.c b/src/wireless-security/eap-method.c
index 6339f59..edf4eaa 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 *ui_file,
const char *ca_cert_chooser,
- NMConnection *connection)
+ NMConnection *connection,
+ gboolean phase2)
{
GtkWidget *dialog;
char *path;
@@ -165,8 +167,17 @@ eap_method_nag_init (EAPMethod *method,
g_free (path);
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 = GTK_WIDGET (gtk_builder_get_object (method->builder, "nag_user_dialog"));
g_assert (dialog);
diff --git a/src/wireless-security/eap-method.h b/src/wireless-security/eap-method.h
index 3ebb5ac..0263cc1 100644
--- a/src/wireless-security/eap-method.h
+++ b/src/wireless-security/eap-method.h
@@ -101,7 +101,8 @@ gboolean eap_method_validate_filepicker (GtkBuilder *builder,
gboolean eap_method_nag_init (EAPMethod *method,
const char *ui_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]