NetworkManager r3981 - in branches/mbca: . callouts docs/libnm-glib include introspection libnm-glib libnm-util po src src/backends src/dhcp-manager src/dnsmasq-manager src/named-manager src/ppp-manager src/vpn-manager system-settings/plugins/ifcfg-fedora system-settings/plugins/ifcfg-suse system-settings/plugins/keyfile system-settings/src vpn-daemons/openvpn vpn-daemons/openvpn/auth-dialog vpn-daemons/openvpn/po vpn-daemons/openvpn/properties vpn-daemons/openvpn/src vpn-daemons/pptp vpn-daemons/pptp/auth-dialog vpn-daemons/pptp/po vpn-daemons/pptp/properties vpn-daemons/pptp/src vpn-daemons/vpnc vpn-daemons/vpnc/auth-dialog vpn-daemons/vpnc/po vpn-daemons/vpnc/properties vpn-daemons/vpnc/src



Author: kaijanma
Date: Mon Aug 18 08:30:28 2008
New Revision: 3981
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=3981&view=rev

Log:
keep up with trunk

Added:
   branches/mbca/docs/libnm-glib/
      - copied from r3980, /trunk/docs/libnm-glib/
   branches/mbca/libnm-glib/nm-dhcp4-config.c
      - copied unchanged from r3980, /trunk/libnm-glib/nm-dhcp4-config.c
   branches/mbca/libnm-glib/nm-dhcp4-config.h
      - copied unchanged from r3980, /trunk/libnm-glib/nm-dhcp4-config.h
   branches/mbca/src/nm-hso-gsm-device.c
      - copied unchanged from r3980, /trunk/src/nm-hso-gsm-device.c
   branches/mbca/src/nm-hso-gsm-device.h
      - copied unchanged from r3980, /trunk/src/nm-hso-gsm-device.h
Removed:
   branches/mbca/libnm-util/nm-setting-vpn-properties.c
   branches/mbca/libnm-util/nm-setting-vpn-properties.h
   branches/mbca/src/backends/shvar.c
   branches/mbca/src/backends/shvar.h
Modified:
   branches/mbca/ChangeLog
   branches/mbca/Makefile.am
   branches/mbca/autogen.sh
   branches/mbca/callouts/Makefile.am
   branches/mbca/callouts/nm-dispatcher-action.c
   branches/mbca/configure.in
   branches/mbca/include/NetworkManager.h
   branches/mbca/introspection/nm-device.xml
   branches/mbca/introspection/nm-ip4-config.xml
   branches/mbca/introspection/nm-settings-system.xml
   branches/mbca/libnm-glib/Makefile.am
   branches/mbca/libnm-glib/libnm-glib-test.c
   branches/mbca/libnm-glib/nm-access-point.c
   branches/mbca/libnm-glib/nm-active-connection.c
   branches/mbca/libnm-glib/nm-cdma-device.c
   branches/mbca/libnm-glib/nm-client.c
   branches/mbca/libnm-glib/nm-device-ethernet.c
   branches/mbca/libnm-glib/nm-device-wifi.c
   branches/mbca/libnm-glib/nm-device.c
   branches/mbca/libnm-glib/nm-device.h
   branches/mbca/libnm-glib/nm-gsm-device.c
   branches/mbca/libnm-glib/nm-ip4-config.c
   branches/mbca/libnm-glib/nm-ip4-config.h
   branches/mbca/libnm-glib/nm-object.c
   branches/mbca/libnm-glib/nm-serial-device.c
   branches/mbca/libnm-glib/nm-settings.c
   branches/mbca/libnm-glib/nm-vpn-plugin.c
   branches/mbca/libnm-util/Makefile.am
   branches/mbca/libnm-util/nm-connection.c
   branches/mbca/libnm-util/nm-setting-vpn.c
   branches/mbca/libnm-util/nm-setting-vpn.h
   branches/mbca/libnm-util/nm-utils.c
   branches/mbca/po/ChangeLog
   branches/mbca/po/fi.po
   branches/mbca/po/fr.po
   branches/mbca/po/nb.po
   branches/mbca/src/Makefile.am
   branches/mbca/src/NetworkManager.c
   branches/mbca/src/NetworkManagerPolicy.c
   branches/mbca/src/NetworkManagerSystem.c
   branches/mbca/src/NetworkManagerSystem.h
   branches/mbca/src/NetworkManagerUtils.c
   branches/mbca/src/backends/Makefile.am
   branches/mbca/src/backends/NetworkManagerArch.c
   branches/mbca/src/backends/NetworkManagerDebian.c
   branches/mbca/src/backends/NetworkManagerFrugalware.c
   branches/mbca/src/backends/NetworkManagerGeneric.c
   branches/mbca/src/backends/NetworkManagerGeneric.h
   branches/mbca/src/backends/NetworkManagerGentoo.c
   branches/mbca/src/backends/NetworkManagerMandriva.c
   branches/mbca/src/backends/NetworkManagerPaldo.c
   branches/mbca/src/backends/NetworkManagerRedHat.c
   branches/mbca/src/backends/NetworkManagerSlackware.c
   branches/mbca/src/backends/NetworkManagerSuSE.c
   branches/mbca/src/dhcp-manager/nm-dhcp-manager.c
   branches/mbca/src/dnsmasq-manager/nm-dnsmasq-manager.c
   branches/mbca/src/named-manager/nm-named-manager.c
   branches/mbca/src/named-manager/nm-named-manager.h
   branches/mbca/src/nm-activation-request.c
   branches/mbca/src/nm-activation-request.h
   branches/mbca/src/nm-cdma-device.c
   branches/mbca/src/nm-device-ethernet.c
   branches/mbca/src/nm-device-interface.c
   branches/mbca/src/nm-device.c
   branches/mbca/src/nm-device.h
   branches/mbca/src/nm-dhcp4-config.c
   branches/mbca/src/nm-dhcp4-config.h
   branches/mbca/src/nm-gsm-device.c
   branches/mbca/src/nm-gsm-device.h
   branches/mbca/src/nm-hal-manager.c
   branches/mbca/src/nm-ip4-config.c
   branches/mbca/src/nm-ip4-config.h
   branches/mbca/src/nm-netlink-monitor.c
   branches/mbca/src/nm-netlink-monitor.h
   branches/mbca/src/nm-properties-changed-signal.c
   branches/mbca/src/nm-properties-changed-signal.h
   branches/mbca/src/ppp-manager/nm-ppp-manager.c
   branches/mbca/src/vpn-manager/nm-vpn-connection.c
   branches/mbca/system-settings/plugins/ifcfg-fedora/shvar.c
   branches/mbca/system-settings/plugins/ifcfg-fedora/shvar.h
   branches/mbca/system-settings/plugins/ifcfg-suse/parser.c
   branches/mbca/system-settings/plugins/keyfile/Makefile.am
   branches/mbca/system-settings/plugins/keyfile/nm-keyfile-connection.c
   branches/mbca/system-settings/plugins/keyfile/plugin.c
   branches/mbca/system-settings/plugins/keyfile/reader.c
   branches/mbca/system-settings/plugins/keyfile/writer.c
   branches/mbca/system-settings/plugins/keyfile/writer.h
   branches/mbca/system-settings/src/dbus-settings.c
   branches/mbca/system-settings/src/nm-system-config-interface.c
   branches/mbca/system-settings/src/nm-system-config-interface.h
   branches/mbca/vpn-daemons/openvpn/ChangeLog
   branches/mbca/vpn-daemons/openvpn/auth-dialog/main.c
   branches/mbca/vpn-daemons/openvpn/po/ChangeLog
   branches/mbca/vpn-daemons/openvpn/po/es.po
   branches/mbca/vpn-daemons/openvpn/po/fi.po
   branches/mbca/vpn-daemons/openvpn/po/fr.po
   branches/mbca/vpn-daemons/openvpn/po/ru.po
   branches/mbca/vpn-daemons/openvpn/properties/auth-helpers.c
   branches/mbca/vpn-daemons/openvpn/properties/auth-helpers.h
   branches/mbca/vpn-daemons/openvpn/properties/import-export.c
   branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn-dialog.glade
   branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn.c
   branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn.h
   branches/mbca/vpn-daemons/openvpn/src/nm-openvpn-service.c
   branches/mbca/vpn-daemons/openvpn/src/nm-openvpn-service.h
   branches/mbca/vpn-daemons/pptp/ChangeLog
   branches/mbca/vpn-daemons/pptp/auth-dialog/main.c
   branches/mbca/vpn-daemons/pptp/po/ChangeLog
   branches/mbca/vpn-daemons/pptp/po/LINGUAS
   branches/mbca/vpn-daemons/pptp/po/es.po
   branches/mbca/vpn-daemons/pptp/po/fi.po
   branches/mbca/vpn-daemons/pptp/po/fr.po
   branches/mbca/vpn-daemons/pptp/po/ru.po
   branches/mbca/vpn-daemons/pptp/properties/advanced-dialog.c
   branches/mbca/vpn-daemons/pptp/properties/import-export.c
   branches/mbca/vpn-daemons/pptp/properties/nm-pptp-dialog.glade
   branches/mbca/vpn-daemons/pptp/properties/nm-pptp.c
   branches/mbca/vpn-daemons/pptp/properties/nm-pptp.h
   branches/mbca/vpn-daemons/pptp/src/nm-pptp-pppd-plugin.c
   branches/mbca/vpn-daemons/pptp/src/nm-pptp-service.c
   branches/mbca/vpn-daemons/vpnc/ChangeLog
   branches/mbca/vpn-daemons/vpnc/auth-dialog/main.c
   branches/mbca/vpn-daemons/vpnc/po/ChangeLog
   branches/mbca/vpn-daemons/vpnc/po/fi.po
   branches/mbca/vpn-daemons/vpnc/po/fr.po
   branches/mbca/vpn-daemons/vpnc/po/ru.po
   branches/mbca/vpn-daemons/vpnc/properties/nm-vpnc.c
   branches/mbca/vpn-daemons/vpnc/src/nm-vpnc-service.c

Modified: branches/mbca/Makefile.am
==============================================================================
--- branches/mbca/Makefile.am	(original)
+++ branches/mbca/Makefile.am	Mon Aug 18 08:30:28 2008
@@ -40,7 +40,8 @@
 	   callouts \
 	   system-settings \
 	   tools \
-	   policy
+	   policy \
+	   docs/libnm-glib
 
 EXTRA_DIST =				\
 	CONTRIBUTING			\
@@ -49,6 +50,8 @@
 	intltool-merge.in		\
 	intltool-update.in		
 
+DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
+
 DISTCLEANFILES = intltool-extract intltool-merge intltool-update
 
 pkgconfigdir = $(libdir)/pkgconfig

Modified: branches/mbca/autogen.sh
==============================================================================
--- branches/mbca/autogen.sh	(original)
+++ branches/mbca/autogen.sh	Mon Aug 18 08:30:28 2008
@@ -14,6 +14,7 @@
 }
 
 (cd $srcdir;
+    gtkdocize || exit 1
     autoreconf --install --symlink &&
     intltoolize --force &&
     autoreconf &&

Modified: branches/mbca/callouts/Makefile.am
==============================================================================
--- branches/mbca/callouts/Makefile.am	(original)
+++ branches/mbca/callouts/Makefile.am	Mon Aug 18 08:30:28 2008
@@ -59,6 +59,7 @@
 nm_dispatcher_action_LDADD = \
 	$(DBUS_LIBS) \
 	$(GTHREAD_LIBS) \
+	$(top_builddir)/libnm-glib/libnm_glib.la \
 	$(top_builddir)/libnm-util/libnm-util.la
 
 nm-dispatcher-glue.h: nm-dispatcher.xml
@@ -77,6 +78,10 @@
 	-e 's|@localstatedir[ ]|$(localstatedir)|g' \
 	-e 's|@libexecdir[ ]|$(libexecdir)|g'
 
+dispatcherdir=$(sysconfdir)/NetworkManager/dispatcher.d
+install-data-hook:
+	   $(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)
+
 BUILT_SOURCES = nm-dispatcher-glue.h
 
 CLEANFILES = $(BUILT_SOURCES) $(dbusactivation_DATA)

Modified: branches/mbca/callouts/nm-dispatcher-action.c
==============================================================================
--- branches/mbca/callouts/nm-dispatcher-action.c	(original)
+++ branches/mbca/callouts/nm-dispatcher-action.c	Mon Aug 18 08:30:28 2008
@@ -29,6 +29,7 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <errno.h>
+#include <arpa/inet.h>
 
 #include <glib.h>
 #include <dbus/dbus.h>
@@ -37,12 +38,16 @@
 
 #include <NetworkManager.h>
 #include <libnm-util/nm-connection.h>
+#include <libnm-util/nm-setting-ip4-config.h>
+#include <libnm-glib/nm-dhcp4-config.h>
+#include <libnm-glib/nm-device.h>
 
 #include "nm-dispatcher-action.h"
 
 #define NMD_SCRIPT_DIR    SYSCONFDIR "/NetworkManager/dispatcher.d"
 
 static GMainLoop *loop = NULL;
+static gboolean debug = FALSE;
 
 static gboolean quit_timeout_cb (gpointer user_data);
 
@@ -214,16 +219,170 @@
         setpgid (pid, pid);
 }
 
+typedef struct {
+	char **envp;
+	guint32 i;
+} EnvAddInfo;
+
+static void
+add_one_option_to_envp (gpointer key, gpointer value, gpointer user_data)
+{
+	EnvAddInfo *info = (EnvAddInfo *) user_data;
+	char *ucased;
+
+	ucased = g_ascii_strup (key, -1);
+	info->envp[info->i++] = g_strdup_printf ("DHCP4_%s=%s", ucased, (char *) value);
+	g_free (ucased);
+}
+
+static char **
+construct_envp (NMIP4Config *ip4_config, NMDHCP4Config *dhcp4_config)
+{
+	guint32 env_size = 0;
+	char **envp;
+	guint32 envp_idx = 0;
+	GHashTable *options = NULL;
+	GSList *addresses, *routes, *iter;
+	GArray *nameservers;
+	GPtrArray *domains;
+	guint32 num, i;
+	GString *tmp;
+
+	if (!ip4_config)
+		return g_new0 (char *, 1);
+
+	addresses = (GSList *) nm_ip4_config_get_addresses (ip4_config);
+	nameservers = (GArray *) nm_ip4_config_get_nameservers (ip4_config);
+	domains = (GPtrArray *) nm_ip4_config_get_domains (ip4_config);
+	routes = (GSList *) nm_ip4_config_get_routes (ip4_config);
+
+	env_size =   g_slist_length (addresses)
+	           + 1 /* addresses length */
+	           + 1 /* nameservers */
+	           + 1 /* domains */
+	           + 1 /* hostname */
+	           + g_slist_length (routes)
+	           + 1 /* routes length */;
+
+	if (dhcp4_config) {
+		options = nm_dhcp4_config_get_options (dhcp4_config);
+		env_size += g_hash_table_size (options);
+	}
+
+	envp = g_new0 (char *, env_size + 1);
+
+	/* IP4 config stuff */
+	for (iter = addresses, num = 0; iter; iter = g_slist_next (iter)) {
+		NMSettingIP4Address *addr = (NMSettingIP4Address *) iter->data;
+		char str_addr[INET_ADDRSTRLEN + 1];
+		char str_gw[INET_ADDRSTRLEN + 1];
+		struct in_addr tmp_addr;
+
+		memset (str_addr, 0, sizeof (str_addr));
+		tmp_addr.s_addr = addr->address;
+		if (!inet_ntop (AF_INET, &tmp_addr, str_addr, sizeof (str_addr)))
+			continue;
+
+		memset (str_gw, 0, sizeof (str_gw));
+		tmp_addr.s_addr = addr->gateway;
+		inet_ntop (AF_INET, &tmp_addr, str_gw, sizeof (str_gw));
+
+		tmp = g_string_sized_new (25 + strlen (str_addr) + strlen (str_gw));
+		g_string_append_printf (tmp, "IP4_ADDRESS_%d=%s/%d %s", num++, str_addr, addr->prefix, str_gw);
+		envp[envp_idx++] = tmp->str;
+		g_string_free (tmp, FALSE);
+	}
+	if (num)
+		envp[envp_idx++] = g_strdup_printf ("IP4_NUM_ADDRESSES=%d", num);
+
+	if (nameservers && nameservers->len) {
+		gboolean first = TRUE;
+
+		tmp = g_string_new ("IP4_NAMESERVERS=");
+		for (i = 0; i < nameservers->len; i++) {
+			struct in_addr addr;
+			char buf[INET_ADDRSTRLEN + 1];
+
+			addr.s_addr = g_array_index (nameservers, guint32, i);
+			memset (buf, 0, sizeof (buf));
+			if (inet_ntop (AF_INET, &addr, buf, sizeof (buf))) {
+				if (!first)
+					g_string_append_c (tmp, ' ');
+				g_string_append (tmp, buf);
+				first = FALSE;
+			}
+		}
+		envp[envp_idx++] = tmp->str;
+		g_string_free (tmp, FALSE);
+	}
+
+	if (domains && domains->len) {
+		tmp = g_string_new ("IP4_DOMAINS=");
+		for (i = 0; i < domains->len; i++) {
+			if (i > 0)
+				g_string_append_c (tmp, ' ');
+			g_string_append (tmp, (char *) g_ptr_array_index (domains, i));
+		}
+		envp[envp_idx++] = tmp->str;
+		g_string_free (tmp, FALSE);
+	}
+
+	for (iter = routes, num = 0; iter; iter = g_slist_next (iter)) {
+		NMSettingIP4Route *route = (NMSettingIP4Route *) iter->data;
+		char str_addr[INET_ADDRSTRLEN + 1];
+		char str_nh[INET_ADDRSTRLEN + 1];
+		struct in_addr tmp_addr;
+
+		memset (str_addr, 0, sizeof (str_addr));
+		tmp_addr.s_addr = route->address;
+		if (!inet_ntop (AF_INET, &tmp_addr, str_addr, sizeof (str_addr)))
+			continue;
+
+		memset (str_nh, 0, sizeof (str_nh));
+		tmp_addr.s_addr = route->next_hop;
+		inet_ntop (AF_INET, &tmp_addr, str_nh, sizeof (str_nh));
+
+		tmp = g_string_sized_new (30 + strlen (str_addr) + strlen (str_nh));
+		g_string_append_printf (tmp, "IP4_ROUTE_%d=%s/%d %s %d", num++, str_addr, route->prefix, str_nh, route->metric);
+		envp[envp_idx++] = tmp->str;
+		g_string_free (tmp, FALSE);
+	}
+	envp[envp_idx++] = g_strdup_printf ("IP4_NUM_ROUTES=%d", num);
+
+	/* DHCP stuff */
+	if (dhcp4_config && options) {
+		EnvAddInfo info;
+
+		info.envp = envp;
+		info.i = envp_idx;
+		g_hash_table_foreach (options, add_one_option_to_envp, &info);
+	}
+
+	if (debug) {
+		char **p;
+
+		g_message ("-----------------------------------------");
+		for (p = envp; *p; p++)
+			g_message ("  %s", *p);
+		g_message ("\n");
+	}
+
+	return envp;
+}
+
 static void
 dispatch_scripts (const char *action,
                   const char *iface,
                   const char *parent_iface,
-                  NMDeviceType type)
+                  NMDeviceType type,
+                  NMIP4Config *ip4_config,
+                  NMDHCP4Config *dhcp4_config)
 {
 	GDir *dir;
 	const char *filename;
 	GSList *scripts = NULL, *iter;
 	GError *error = NULL;
+	char **envp = NULL;
 
 	if (!(dir = g_dir_open (NMD_SCRIPT_DIR, 0, &error))) {
 		g_warning ("g_dir_open() could not open '" NMD_SCRIPT_DIR "'.  '%s'",
@@ -261,9 +420,10 @@
 	}
 	g_dir_close (dir);
 
+	envp = construct_envp (ip4_config, dhcp4_config);
+
 	for (iter = scripts; iter; iter = g_slist_next (iter)) {
 		gchar *argv[4];
-		gchar *envp[1] = { NULL };
 		gint status = -1;
 
 		argv[0] = (char *) iter->data;
@@ -286,6 +446,8 @@
 		}
 	}
 
+	g_strfreev (envp);
+
 	g_slist_foreach (scripts, (GFunc) g_free, NULL);
 	g_slist_free (scripts);
 }
@@ -303,6 +465,10 @@
 	char *iface = NULL;
 	char *parent_iface = NULL;
 	NMDeviceType type = NM_DEVICE_TYPE_UNKNOWN;
+	NMDeviceState dev_state = NM_DEVICE_STATE_UNKNOWN;
+	NMDevice *device = NULL;
+	NMDHCP4Config *dhcp4_config = NULL;
+	NMIP4Config *ip4_config = NULL;
 	GValue *value;
 
 	/* Back off the quit timeout */
@@ -322,6 +488,7 @@
 		*error = NULL;
 	}
 
+	/* interface name */
 	value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_INTERFACE);
 	if (!value || !G_VALUE_HOLDS_STRING (value)) {
 		g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_INTERFACE "!");
@@ -329,6 +496,7 @@
 	}
 	iface = (char *) g_value_get_string (value);
 
+	/* IP interface name */
 	value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_IP_INTERFACE);
 	if (value) {
 		if (!G_VALUE_HOLDS_STRING (value)) {
@@ -339,6 +507,7 @@
 		iface = (char *) g_value_get_string (value);
 	}
 
+	/* Device type */
 	value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_TYPE);
 	if (!value || !G_VALUE_HOLDS_UINT (value)) {
 		g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_TYPE "!");
@@ -346,7 +515,32 @@
 	}
 	type = g_value_get_uint (value);
 
-	dispatch_scripts (action, iface, parent_iface, type);
+	/* Device state */
+	value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_STATE);
+	if (!value || !G_VALUE_HOLDS_UINT (value)) {
+		g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_STATE "!");
+		goto out;
+	}
+	dev_state = g_value_get_uint (value);
+
+	/* device itself */
+	value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_PATH);
+	if (!value || (G_VALUE_TYPE (value) != DBUS_TYPE_G_OBJECT_PATH)) {
+		g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_PATH "!");
+		goto out;
+	}
+	device = NM_DEVICE (nm_device_new (d->g_connection, (const char *) g_value_get_boxed (value)));
+
+	/* Get the DHCP4 config */
+	if (device && (dev_state == NM_DEVICE_STATE_ACTIVATED)) {
+		dhcp4_config = nm_device_get_dhcp4_config (device);
+		ip4_config = nm_device_get_ip4_config (device);
+	}
+
+	dispatch_scripts (action, iface, parent_iface, type, ip4_config, dhcp4_config);
+
+	if (device)
+		g_object_unref (device);
 
 out:
 	return TRUE;
@@ -519,7 +713,6 @@
 	Dispatcher *d = g_malloc0 (sizeof (Dispatcher));
 	GOptionContext *opt_ctx;
 	GError *error = NULL;
-	gboolean debug = FALSE;
 	gboolean persist = FALSE;
 
 	GOptionEntry entries[] = {

Modified: branches/mbca/configure.in
==============================================================================
--- branches/mbca/configure.in	(original)
+++ branches/mbca/configure.in	Mon Aug 18 08:30:28 2008
@@ -170,7 +170,7 @@
 	AC_MSG_ERROR(wireless-tools >= 28pre9 not installed or not functional)
 fi
 
-PKG_CHECK_MODULES(DBUS, dbus-glib-1 >= 0.75)
+PKG_CHECK_MODULES(DBUS, dbus-glib-1 >= 0.74)
 
 ##### Find out the version of DBUS we're using
 dbus_version=`pkg-config --modversion dbus-1`
@@ -407,6 +407,8 @@
 	AC_MSG_RESULT(no)
 fi
 
+GTK_DOC_CHECK(1.0)
+
 AC_CONFIG_FILES([
 Makefile
 include/Makefile
@@ -457,6 +459,7 @@
 man/nm-tool.1
 po/Makefile.in
 policy/Makefile
+docs/libnm-glib/Makefile
 NetworkManager.pc
 ])
 AC_OUTPUT

Modified: branches/mbca/include/NetworkManager.h
==============================================================================
--- branches/mbca/include/NetworkManager.h	(original)
+++ branches/mbca/include/NetworkManager.h	Mon Aug 18 08:30:28 2008
@@ -39,6 +39,7 @@
 #define NM_DBUS_INTERFACE_CDMA_DEVICE       NM_DBUS_INTERFACE_DEVICE ".Cdma"
 #define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active"
 #define NM_DBUS_INTERFACE_IP4_CONFIG        NM_DBUS_INTERFACE ".IP4Config"
+#define NM_DBUS_INTERFACE_DHCP4_CONFIG      NM_DBUS_INTERFACE ".DHCP4Config"
 
 
 #define NM_DBUS_SERVICE_USER_SETTINGS     "org.freedesktop.NetworkManagerUserSettings"
@@ -306,6 +307,15 @@
 	/* Failed to select the specified APN */
 	NM_DEVICE_STATE_REASON_GSM_APN_FAILED,
 
+	/* Not searching for networks */
+	NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING,
+
+	/* Network registration denied */
+	NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED,
+
+	/* Network registration timed out */
+	NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT,
+
 	/* Failed to register with the requested network */
 	NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED,
 

Modified: branches/mbca/introspection/nm-device.xml
==============================================================================
--- branches/mbca/introspection/nm-device.xml	(original)
+++ branches/mbca/introspection/nm-device.xml	Mon Aug 18 08:30:28 2008
@@ -290,12 +290,27 @@
           Failed to select the specified GSM APN.
         </tp:docstring>
       </tp:enumvalue>
-      <tp:enumvalue suffix="GSM_REGISTRATION_FAILED" value="30">
+      <tp:enumvalue suffix="GSM_REGISTRATION_NOT_SEARCHING" value="30">
+        <tp:docstring>
+          Not searching for networks.
+        </tp:docstring>
+      </tp:enumvalue>
+      <tp:enumvalue suffix="GSM_REGISTRATION_DENIED" value="31">
+        <tp:docstring>
+          Network registration was denied.
+        </tp:docstring>
+      </tp:enumvalue>
+      <tp:enumvalue suffix="GSM_REGISTRATION_TIMEOUT" value="32">
+        <tp:docstring>
+          Network registration timed out.
+        </tp:docstring>
+      </tp:enumvalue>
+      <tp:enumvalue suffix="GSM_REGISTRATION_FAILED" value="33">
         <tp:docstring>
           Failed to register with the requested GSM network.
         </tp:docstring>
       </tp:enumvalue>
-      <tp:enumvalue suffix="GSM_PIN_CHECK_FAILED" value="31">
+      <tp:enumvalue suffix="GSM_PIN_CHECK_FAILED" value="34">
         <tp:docstring>
           PIN check failed.
         </tp:docstring>

Modified: branches/mbca/introspection/nm-ip4-config.xml
==============================================================================
--- branches/mbca/introspection/nm-ip4-config.xml	(original)
+++ branches/mbca/introspection/nm-ip4-config.xml	Mon Aug 18 08:30:28 2008
@@ -14,12 +14,6 @@
     <property name="Domains" type="as" access="read">
       <tp:docstring>A list of domains this address belongs to.</tp:docstring>
     </property>
-    <property name="NisDomain" type="s" access="read">
-      <tp:docstring>The NIS domain this address belongs to.</tp:docstring>
-    </property>
-    <property name="NisServers" type="au" access="read">
-      <tp:docstring>The NIS servers associated with this address.</tp:docstring>
-    </property>
     <property name="Routes" type="aau" access="read">
       <tp:docstring>Tuples of IPv4 route/prefix/next-hop/metric.</tp:docstring>
     </property>

Modified: branches/mbca/introspection/nm-settings-system.xml
==============================================================================
--- branches/mbca/introspection/nm-settings-system.xml	(original)
+++ branches/mbca/introspection/nm-settings-system.xml	Mon Aug 18 08:30:28 2008
@@ -8,14 +8,14 @@
 
     <method name="AddConnection">
       <tp:docstring>
-	Add new connection.
+        Add new connection.
       </tp:docstring>
       <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_add_connection"/>
       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
       <arg name="connection" type="a{sa{sv}}" direction="in">
-	<tp:docstring>
-	  Connection properties.
-	</tp:docstring>
+        <tp:docstring>
+          Connection properties.
+        </tp:docstring>
       </arg>
     </method>
 

Modified: branches/mbca/libnm-glib/Makefile.am
==============================================================================
--- branches/mbca/libnm-glib/Makefile.am	(original)
+++ branches/mbca/libnm-glib/Makefile.am	Mon Aug 18 08:30:28 2008
@@ -16,7 +16,9 @@
 	nm-settings-system-bindings.h \
 	nm-vpn-connection-bindings.h \
 	nm-vpn-plugin-glue.h \
-	nm-active-connection-bindings.h
+	nm-active-connection-bindings.h \
+	nm-ip4-config-bindings.h \
+	nm-dhcp4-config-bindings.h
 
 lib_LTLIBRARIES = libnm_glib.la libnm_glib_vpn.la
 
@@ -49,7 +51,8 @@
 	nm-active-connection.h \
 	nm-dbus-connection.h \
 	nm-dbus-settings.h \
-	nm-dbus-settings-system.h
+	nm-dbus-settings-system.h \
+	nm-dhcp4-config.h
 
 libnm_glib_la_SOURCES = \
 	libnm_glib.c		\
@@ -76,7 +79,8 @@
 	nm-active-connection.c \
 	nm-dbus-connection.c \
 	nm-dbus-settings.c \
-	nm-dbus-settings-system.c
+	nm-dbus-settings-system.c \
+	nm-dhcp4-config.c
 
 libnm_glib_la_LIBADD = \
 	$(top_builddir)/libnm-util/libnm-util.la	\
@@ -138,6 +142,12 @@
 nm-active-connection-bindings.h: $(top_srcdir)/introspection/nm-active-connection.xml
 	dbus-binding-tool --prefix=nm_active_connection --mode=glib-client --output=$@ $<
 
+nm-ip4-config-bindings.h: $(top_srcdir)/introspection/nm-ip4-config.xml
+	dbus-binding-tool --prefix=nm_ip4_config --mode=glib-client --output=$@ $<
+
+nm-dhcp4-config-bindings.h: $(top_srcdir)/introspection/nm-dhcp4-config.xml
+	dbus-binding-tool --prefix=nm_dhcp4_config --mode=glib-client --output=$@ $<
+
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libnm_glib.pc libnm_glib_vpn.pc
 

Modified: branches/mbca/libnm-glib/libnm-glib-test.c
==============================================================================
--- branches/mbca/libnm-glib/libnm-glib-test.c	(original)
+++ branches/mbca/libnm-glib/libnm-glib-test.c	Mon Aug 18 08:30:28 2008
@@ -106,18 +106,30 @@
 		for (i = 0; i < ptr_array->len; i++)
 			g_print ("\t%s\n", (const char *) g_ptr_array_index (ptr_array, i));
 	}
+}
+
+static void
+print_one_dhcp4_option (gpointer key, gpointer data, gpointer user_data)
+{
+	const char *option = (const char *) key;
+	const char *value = (const char *) data;
 
-	g_print ("IP4 NIS domain: %s\n", nm_ip4_config_get_nis_domain (cfg));
+	g_print ("  %s:   %s\n", option, value);
+}
 
-	array = nm_ip4_config_get_nis_servers (cfg);
-	if (array) {
-		g_print ("IP4 NIS servers:\n");
-		for (i = 0; i < array->len; i++) {
-			tmp = ip4_address_as_string (g_array_index (array, guint32, i));
-			g_print ("\t%s\n", tmp);
-			g_free (tmp);
-		}
-	}
+static void
+dump_dhcp4_config (NMDHCP4Config *config)
+{
+	GHashTable *options = NULL;
+
+	if (!config)
+		return;
+
+	g_print ("\nDHCP4 Options:\n");
+	g_print ("-------------------------------------\n");
+
+	g_object_get (G_OBJECT (config), NM_DHCP4_CONFIG_OPTIONS, &options, NULL);
+	g_hash_table_foreach (options, print_one_dhcp4_option, NULL);
 }
 
 static void
@@ -206,6 +218,8 @@
 		dump_wired (NM_DEVICE_ETHERNET (device));
 	else if (NM_IS_DEVICE_WIFI (device))
 		dump_wireless (NM_DEVICE_WIFI (device));
+
+	dump_dhcp4_config (nm_device_get_dhcp4_config (device));
 }
 
 static gboolean
@@ -238,7 +252,7 @@
 
 	g_print ("Active connections changed:\n");
 	connections = nm_client_get_active_connections (client);
-	for (i = 0; i < connections->len; i++) {
+	for (i = 0; connections && (i < connections->len); i++) {
 		NMActiveConnection *connection;
 		const GPtrArray *devices;
 
@@ -266,7 +280,7 @@
 
 	g_print ("Active connections:\n");
 	connections = nm_client_get_active_connections (client);
-	for (i = 0; i < connections->len; i++) {
+	for (i = 0; connections && (i < connections->len); i++) {
 		const GPtrArray *devices;
 
 		g_print ("    %s\n", nm_object_get_path (g_ptr_array_index (connections, i)));

Modified: branches/mbca/libnm-glib/nm-access-point.c
==============================================================================
--- branches/mbca/libnm-glib/nm-access-point.c	(original)
+++ branches/mbca/libnm-glib/nm-access-point.c	Mon Aug 18 08:30:28 2008
@@ -53,6 +53,15 @@
 #define DBUS_PROP_MAX_BITRATE "MaxBitrate"
 #define DBUS_PROP_STRENGTH "Strength"
 
+/**
+ * nm_access_point_new:
+ * @connection: the #DBusGConnection
+ * @path: the DBusobject path of the access point
+ *
+ * Creates a new #NMAccessPoint.
+ *
+ * Returns: a new access point
+ **/
 GObject *
 nm_access_point_new (DBusGConnection *connection, const char *path)
 {
@@ -65,6 +74,14 @@
 								    NULL);
 }
 
+/**
+ * nm_access_point_get_flags:
+ * @ap: a #NMAccessPoint
+ *
+ * Gets the flags of the access point
+ *
+ * Returns: the flags
+ **/
 guint32
 nm_access_point_get_flags (NMAccessPoint *ap)
 {
@@ -82,6 +99,14 @@
 	return priv->flags;
 }
 
+/**
+ * nm_access_point_get_wpa_flags:
+ * @ap: a #NMAccessPoint
+ *
+ * Gets the WPA flags of the access point.
+ *
+ * Returns: the WPA flags
+ **/
 guint32
 nm_access_point_get_wpa_flags (NMAccessPoint *ap)
 {
@@ -99,6 +124,14 @@
 	return priv->wpa_flags;
 }
 
+/**
+ * nm_access_point_get_rsn_flags:
+ * @ap: a #NMAccessPoint
+ *
+ * Gets the RSN flags of the access point.
+ *
+ * Returns: the RSN flags
+ **/
 guint32
 nm_access_point_get_rsn_flags (NMAccessPoint *ap)
 {
@@ -116,6 +149,15 @@
 	return priv->rsn_flags;
 }
 
+/**
+ * nm_access_point_get_ssid:
+ * @ap: a #NMAccessPoint
+ *
+ * Gets the SSID of the access point.
+ *
+ * Returns: the #GByteArray containing the SSID. This is the internal copy used by the
+ * access point, and must not be modified.
+ **/
 const GByteArray *
 nm_access_point_get_ssid (NMAccessPoint *ap)
 {
@@ -133,6 +175,14 @@
 	return priv->ssid;
 }
 
+/**
+ * nm_access_point_get_frequency:
+ * @ap: a #NMAccessPoint
+ *
+ * Gets the frequency of the access point.
+ *
+ * Returns: the frequency
+ **/
 guint32
 nm_access_point_get_frequency (NMAccessPoint *ap)
 {
@@ -150,6 +200,15 @@
 	return priv->frequency;
 }
 
+/**
+ * nm_access_point_get_hw_address:
+ * @ap: a #NMAccessPoint
+ *
+ * Gets the hardware (MAC) address of the access point.
+ *
+ * Returns: the hardware address of the access point. This is the internal string used by the
+ * access point and must not be modified.
+ **/
 const char *
 nm_access_point_get_hw_address (NMAccessPoint *ap)
 {
@@ -167,6 +226,14 @@
 	return priv->hw_address;
 }
 
+/**
+ * nm_access_point_get_mode:
+ * @ap: a #NMAccessPoint
+ *
+ * Gets the mode of the access point.
+ *
+ * Returns: the mode
+ **/
 NM80211Mode
 nm_access_point_get_mode (NMAccessPoint *ap)
 {
@@ -184,6 +251,14 @@
 	return priv->mode;
 }
 
+/**
+ * nm_access_point_get_max_bitrate:
+ * @ap: a #NMAccessPoint
+ *
+ * Gets the maximum bit rate of the access point.
+ *
+ * Returns: the maximum bit rate
+ **/
 guint32
 nm_access_point_get_max_bitrate (NMAccessPoint *ap)
 {
@@ -201,6 +276,14 @@
 	return priv->max_bitrate;
 }
 
+/**
+ * nm_access_point_get_strength:
+ * @ap: 
+ *
+ * Gets the current signal strength of the access point.
+ *
+ * Returns: the signal strength
+ **/
 guint8
 nm_access_point_get_strength (NMAccessPoint *ap)
 {
@@ -371,6 +454,12 @@
 	object_class->finalize = finalize;
 
 	/* properties */
+
+	/**
+	 * NMAccessPoint:flags:
+	 *
+	 * The flags of the access point.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_FLAGS,
 		 g_param_spec_uint (NM_ACCESS_POINT_FLAGS,
@@ -381,6 +470,11 @@
 		                    NM_802_11_AP_FLAGS_NONE,
 		                    G_PARAM_READABLE));
 
+	/**
+	 * NMAccessPoint:wpa-flags:
+	 *
+	 * The WPA flags of the access point.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_WPA_FLAGS,
 		 g_param_spec_uint (NM_ACCESS_POINT_WPA_FLAGS,
@@ -389,6 +483,11 @@
 		                    0, G_MAXUINT32, 0,
 		                    G_PARAM_READABLE));
 
+	/**
+	 * NMAccessPoint:rsn-flags:
+	 *
+	 * The RSN flags of the access point.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_RSN_FLAGS,
 		 g_param_spec_uint (NM_ACCESS_POINT_RSN_FLAGS,
@@ -397,6 +496,11 @@
 		                    0, G_MAXUINT32, 0,
 		                    G_PARAM_READABLE));
 
+	/**
+	 * NMAccessPoint:ssid:
+	 *
+	 * The SSID of the access point.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_SSID,
 		 g_param_spec_boxed (NM_ACCESS_POINT_SSID,
@@ -405,6 +509,11 @@
 						 NM_TYPE_SSID,
 						 G_PARAM_READABLE));
 
+	/**
+	 * NMAccessPoint:frequency:
+	 *
+	 * The frequency of the access point.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_FREQUENCY,
 		 g_param_spec_uint (NM_ACCESS_POINT_FREQUENCY,
@@ -413,6 +522,11 @@
 						0, 10000, 0,
 						G_PARAM_READABLE));
 
+	/**
+	 * NMAccessPoint:hw-address:
+	 *
+	 * The hardware address of the access point.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_HW_ADDRESS,
 		 g_param_spec_string (NM_ACCESS_POINT_HW_ADDRESS,
@@ -421,6 +535,11 @@
 						  NULL,
 						  G_PARAM_READABLE));
 	
+	/**
+	 * NMAccessPoint:mode:
+	 *
+	 * The mode of the access point.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_MODE,
 		 g_param_spec_uint (NM_ACCESS_POINT_MODE,
@@ -429,6 +548,11 @@
 					    NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA,
 					    G_PARAM_READABLE));
 
+	/**
+	 * NMAccessPoint:max-bitrate:
+	 *
+	 * The maximum bit rate of the access point.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_MAX_BITRATE,
 		 g_param_spec_uint (NM_ACCESS_POINT_MAX_BITRATE,
@@ -437,6 +561,11 @@
 						0, G_MAXUINT32, 0,
 						G_PARAM_READABLE));
 
+	/**
+	 * NMAccessPoint:strength:
+	 *
+	 * The current signal strength of the access point.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_STRENGTH,
 		 g_param_spec_uchar (NM_ACCESS_POINT_STRENGTH,

Modified: branches/mbca/libnm-glib/nm-active-connection.c
==============================================================================
--- branches/mbca/libnm-glib/nm-active-connection.c	(original)
+++ branches/mbca/libnm-glib/nm-active-connection.c	Mon Aug 18 08:30:28 2008
@@ -50,6 +50,15 @@
 #define DBUS_PROP_STATE "State"
 #define DBUS_PROP_DEFAULT "Default"
 
+/**
+ * nm_active_connection_new:
+ * @connection: the #DBusGConnection
+ * @path: the DBus object path of the device
+ *
+ * Creates a new #NMActiveConnection.
+ *
+ * Returns: a new active connection
+ **/
 GObject *
 nm_active_connection_new (DBusGConnection *connection, const char *path)
 {
@@ -73,6 +82,15 @@
 	return NM_CONNECTION_SCOPE_UNKNOWN;
 }
 
+/**
+ * nm_active_connection_get_service_name:
+ * @connection: a #NMActiveConnection
+ *
+ * Gets the service name of the active connection.
+ *
+ * Returns: the service name. This is the internal string used by the
+ * connection, and must not be modified.
+ **/
 const char *
 nm_active_connection_get_service_name (NMActiveConnection *connection)
 {
@@ -91,6 +109,14 @@
 	return priv->service_name;
 }
 
+/**
+ * nm_active_connection_get_scope:
+ * @connection: a #NMActiveConnection
+ *
+ * Gets the scope of the active connection.
+ *
+ * Returns: the connection's scope
+ **/
 NMConnectionScope
 nm_active_connection_get_scope (NMActiveConnection *connection)
 {
@@ -101,6 +127,15 @@
 	return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->scope;
 }
 
+/**
+ * nm_active_connection_get_connection:
+ * @connection: a #NMActiveConnection
+ *
+ * Gets the #NMConnection<!-- -->'s DBus object path.
+ *
+ * Returns: the object path of the #NMConnection inside of #NMActiveConnection.
+ * This is the internal string used by the connection, and must not be modified.
+ **/
 const char *
 nm_active_connection_get_connection (NMActiveConnection *connection)
 {
@@ -118,6 +153,15 @@
 	return priv->connection;
 }
 
+/**
+ * nm_active_connection_get_specific_object:
+ * @connection: a #NMActiveConnection
+ *
+ * Gets the "specific object" used at the activation.
+ *
+ * Returns: the specific object's DBus path. This is the internal string used by the
+ * connection, and must not be modified.
+ **/
 const char *
 nm_active_connection_get_specific_object (NMActiveConnection *connection)
 {
@@ -135,6 +179,15 @@
 	return priv->specific_object;
 }
 
+/**
+ * nm_active_connection_get_devices:
+ * @connection: a #NMActiveConnection
+ *
+ * Gets the #NMDevice<!-- -->s used for the active connections.
+ *
+ * Returns: the #GPtrArray containing #NMDevice<!-- -->s.
+ * This is the internal copy used by the connection, and must not be modified.
+ **/
 const GPtrArray *
 nm_active_connection_get_devices (NMActiveConnection *connection)
 {
@@ -160,6 +213,14 @@
 	return handle_ptr_array_return (priv->devices);
 }
 
+/**
+ * nm_active_connection_get_state:
+ * @connection: a #NMActiveConnection
+ *
+ * Gets the active connection's state.
+ *
+ * Returns: the state
+ **/
 NMActiveConnectionState
 nm_active_connection_get_state (NMActiveConnection *connection)
 {
@@ -177,6 +238,15 @@
 	return priv->state;
 }
 
+/**
+ * nm_active_connection_get_default:
+ * @connection: a #NMActiveConnection
+ *
+ * Whether the active connection is the default one (that is, is used for the default route
+ * and DNS information).
+ *
+ * Returns: %TRUE if the active connection is the default one
+ **/
 gboolean
 nm_active_connection_get_default (NMActiveConnection *connection)
 {
@@ -350,6 +420,12 @@
 	object_class->finalize = finalize;
 
 	/* properties */
+
+	/**
+	 * NMActiveConnection:service-name:
+	 *
+	 * The service name of the active connection.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_SERVICE_NAME,
 		 g_param_spec_string (NM_ACTIVE_CONNECTION_SERVICE_NAME,
@@ -358,6 +434,11 @@
 						  NULL,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMActiveConnection:connection:
+	 *
+	 * The connection's path of the active connection.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_CONNECTION,
 		 g_param_spec_string (NM_ACTIVE_CONNECTION_CONNECTION,
@@ -366,6 +447,11 @@
 						      NULL,
 						      G_PARAM_READABLE));
 
+	/**
+	 * NMActiveConnection:specific-object:
+	 *
+	 * The specific object's path of the active connection.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_SPECIFIC_OBJECT,
 		 g_param_spec_string (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT,
@@ -374,6 +460,11 @@
 						      NULL,
 						      G_PARAM_READABLE));
 
+	/**
+	 * NMActiveConnection:device:
+	 *
+	 * The devices (#NMDevice) of the active connection.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_DEVICES,
 		 g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES,
@@ -382,6 +473,11 @@
 						       NM_TYPE_OBJECT_ARRAY,
 						       G_PARAM_READABLE));
 
+	/**
+	 * NMActiveConnection:state:
+	 *
+	 * The state of the active connection.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_STATE,
 		 g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE,
@@ -392,6 +488,11 @@
 							  NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
 							  G_PARAM_READABLE));
 
+	/**
+	 * NMActiveConnection:default:
+	 *
+	 * Whether the active connection is the default one.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_DEFAULT,
 		 g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT,

Modified: branches/mbca/libnm-glib/nm-cdma-device.c
==============================================================================
--- branches/mbca/libnm-glib/nm-cdma-device.c	(original)
+++ branches/mbca/libnm-glib/nm-cdma-device.c	Mon Aug 18 08:30:28 2008
@@ -87,6 +87,15 @@
 	object_class->dispose = dispose;
 }
 
+/**
+ * nm_cdma_device_new:
+ * @connection: the #DBusGConnection
+ * @path: the DBus object path of the device
+ *
+ * Creates a new #NMCdmaDevice.
+ *
+ * Returns: a new device
+ **/
 GObject *
 nm_cdma_device_new (DBusGConnection *connection, const char *path)
 {

Modified: branches/mbca/libnm-glib/nm-client.c
==============================================================================
--- branches/mbca/libnm-glib/nm-client.c	(original)
+++ branches/mbca/libnm-glib/nm-client.c	Mon Aug 18 08:30:28 2008
@@ -381,6 +381,12 @@
 	object_class->dispose = dispose;
 
 	/* properties */
+
+	/**
+	 * NMClient:state:
+	 *
+	 * The current daemon state.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_STATE,
 		 g_param_spec_uint (NM_CLIENT_STATE,
@@ -389,6 +395,11 @@
 						    NM_STATE_UNKNOWN, NM_STATE_DISCONNECTED, NM_STATE_UNKNOWN,
 						    G_PARAM_READABLE));
 
+	/**
+	 * NMClient::manager-running:
+	 *
+	 * Whether the daemon is running.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_MANAGER_RUNNING,
 		 g_param_spec_boolean (NM_CLIENT_MANAGER_RUNNING,
@@ -397,6 +408,11 @@
 						       FALSE,
 						       G_PARAM_READABLE));
 
+	/**
+	 * NMClient::wireless-enabled:
+	 *
+	 * Whether wireless is enabled.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_WIRELESS_ENABLED,
 		 g_param_spec_boolean (NM_CLIENT_WIRELESS_ENABLED,
@@ -405,6 +421,11 @@
 						   TRUE,
 						   G_PARAM_READWRITE));
 
+	/**
+	 * NMClient::wireless-hardware-enabled:
+	 *
+	 * Whether the wireless hardware is enabled.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_WIRELESS_HARDWARE_ENABLED,
 		 g_param_spec_boolean (NM_CLIENT_WIRELESS_HARDWARE_ENABLED,
@@ -413,6 +434,11 @@
 						   TRUE,
 						   G_PARAM_READABLE));
 
+	/**
+	 * NMClient::active-connections:
+	 *
+	 * The active connections.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_ACTIVE_CONNECTIONS,
 		 g_param_spec_boxed (NM_CLIENT_ACTIVE_CONNECTIONS,
@@ -422,6 +448,14 @@
 						   G_PARAM_READABLE));
 
 	/* signals */
+
+	/**
+	 * NMClient::device-added:
+	 * @client: the client that received the signal
+	 * @device: the new device
+	 *
+	 * Notifies that a #NMDevice is added.
+	 **/
 	signals[DEVICE_ADDED] =
 		g_signal_new ("device-added",
 					  G_OBJECT_CLASS_TYPE (object_class),
@@ -432,6 +466,13 @@
 					  G_TYPE_NONE, 1,
 					  G_TYPE_OBJECT);
 
+	/**
+	 * NMClient::device-removed:
+	 * @widget: the client that received the signal
+	 * @device: the removed device
+	 *
+	 * Notifies that a #NMDevice is removed.
+	 **/
 	signals[DEVICE_REMOVED] =
 		g_signal_new ("device-removed",
 					  G_OBJECT_CLASS_TYPE (object_class),
@@ -443,6 +484,13 @@
 					  G_TYPE_OBJECT);
 }
 
+/**
+ * nm_client_new:
+ *
+ * Creates a new #NMClient.
+ *
+ * Returns: a new #NMClient
+ **/
 NMClient *
 nm_client_new (void)
 {
@@ -541,6 +589,15 @@
 	}
 }
 
+/**
+ * nm_client_get_devices:
+ * @client: a #NMClient
+ *
+ * Gets all the detected devices.
+ *
+ * Returns: a #GPtrArray containing all the #NMDevice<!-- -->s.
+ * The returned array is owned by the client and should not be modified.
+ **/
 const GPtrArray *
 nm_client_get_devices (NMClient *client)
 {
@@ -571,6 +628,15 @@
 	return handle_ptr_array_return (priv->devices);
 }
 
+/**
+ * nm_client_get_device_by_path:
+ * @client: a #NMClient
+ * @object_path: the object path to search for
+ *
+ * Gets a #NMDevice from a #NMClient.
+ *
+ * Returns: the #NMDevice for the given @object_path or %NULL if none is found.
+ **/
 NMDevice *
 nm_client_get_device_by_path (NMClient *client, const char *object_path)
 {
@@ -617,6 +683,19 @@
 	g_slice_free (ActivateDeviceInfo, info);
 }
 
+/**
+ * nm_client_activate_connection:
+ * @client: a #NMClient
+ * @service_name: the connection's service name
+ * @connection_path: the connection's DBus path
+ * @device: the #NMDevice
+ * @specific_object: the device specific object (currently used only for
+ * activating wireless devices and should be the #NMAccessPoint<!-- -->'s path.
+ * @callback: the function to call when the call is done
+ * @user_data: user data to pass to the callback function
+ *
+ * Activates a connection with the given #NMDevice.
+ **/
 void
 nm_client_activate_connection (NMClient *client,
 					  const char *service_name,
@@ -653,6 +732,13 @@
 											    info);
 }
 
+/**
+ * nm_client_deactivate_connection:
+ * @client: a #NMClient
+ * @active: the #NMActiveConnection to deactivate
+ *
+ * Deactivates an active #NMActiveConnection.
+ **/
 void
 nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active)
 {
@@ -672,6 +758,15 @@
 	}
 }
 
+/**
+ * nm_client_get_active_connections:
+ * @client: a #NMClient
+ *
+ * Gets the active connections.
+ *
+ * Returns: a #GPtrArray containing all the active #NMActiveConnection<!-- -->s.
+ * The returned array is owned by the client and should not be modified.
+ **/
 const GPtrArray * 
 nm_client_get_active_connections (NMClient *client)
 {
@@ -684,6 +779,9 @@
 	if (priv->active_connections)
 		return handle_ptr_array_return (priv->active_connections);
 
+	if (!priv->manager_running)
+		return NULL;
+
 	if (!nm_object_get_property (NM_OBJECT (client),
 	                             "org.freedesktop.DBus.Properties",
 	                             "ActiveConnections",
@@ -697,6 +795,14 @@
 	return handle_ptr_array_return (priv->active_connections);
 }
 
+/**
+ * nm_client_wireless_get_enabled:
+ * @client: a #NMClient
+ *
+ * Determines whether the wireless is enabled.
+ *
+ * Returns: %TRUE if wireless is enabled
+ **/
 gboolean
 nm_client_wireless_get_enabled (NMClient *client)
 {
@@ -705,6 +811,13 @@
 	return NM_CLIENT_GET_PRIVATE (client)->wireless_enabled;
 }
 
+/**
+ * nm_client_wireless_set_enabled:
+ * @client: a #NMClient
+ * @enabled: %TRUE to enable wireless
+ *
+ * Enables or disables wireless devices.
+ **/
 void
 nm_client_wireless_set_enabled (NMClient *client, gboolean enabled)
 {
@@ -721,6 +834,14 @@
 					    &value);
 }
 
+/**
+ * nm_client_wireless_hardware_get_enabled:
+ * @client: a #NMClient
+ *
+ * Determines whether the wireless hardware is enabled.
+ *
+ * Returns: %TRUE if the wireless hardware is enabled
+ **/
 gboolean
 nm_client_wireless_hardware_get_enabled (NMClient *client)
 {
@@ -729,6 +850,14 @@
 	return NM_CLIENT_GET_PRIVATE (client)->wireless_hw_enabled;
 }
 
+/**
+ * nm_client_get_state:
+ * @client: a #NMClient
+ *
+ * Gets the current daemon state.
+ *
+ * Returns: the current %NMState
+ **/
 NMState
 nm_client_get_state (NMClient *client)
 {
@@ -747,6 +876,14 @@
 	return priv->state;
 }
 
+/**
+ * nm_client_sleep:
+ * @client: a #NMClient
+ * @sleep: %TRUE to put the daemon to sleep
+ *
+ * Enables or disables networking. When the daemon is put to sleep, it'll deactivate and disable
+ * all the active devices.
+ **/
 void
 nm_client_sleep (NMClient *client, gboolean sleep)
 {
@@ -760,6 +897,14 @@
 	}
 }
 
+/**
+ * nm_client_get_manager_running:
+ * @client: a #NMClient
+ *
+ * Determines whether the daemon is running.
+ *
+ * Returns: %TRUE if the daemon is running
+ **/
 gboolean
 nm_client_get_manager_running (NMClient *client)
 {

Modified: branches/mbca/libnm-glib/nm-device-ethernet.c
==============================================================================
--- branches/mbca/libnm-glib/nm-device-ethernet.c	(original)
+++ branches/mbca/libnm-glib/nm-device-ethernet.c	Mon Aug 18 08:30:28 2008
@@ -32,6 +32,15 @@
 #define DBUS_PROP_SPEED "Speed"
 #define DBUS_PROP_CARRIER "Carrier"
 
+/**
+ * nm_device_ethernet_new:
+ * @connection: the #DBusGConnection
+ * @path: the DBus object path of the device
+ *
+ * Creates a new #NMDeviceEthernet.
+ *
+ * Returns: a new device
+ **/
 GObject *
 nm_device_ethernet_new (DBusGConnection *connection, const char *path)
 {
@@ -44,6 +53,15 @@
 	                     NULL);
 }
 
+/**
+ * nm_device_ethernet_get_hw_address:
+ * @device: a #NMDeviceEthernet
+ *
+ * Gets the hardware (MAC) address of the #NMDeviceEthernet
+ *
+ * Returns: the hardware address. This is the internal string used by the
+ * device, and must not be modified.
+ **/
 const char *
 nm_device_ethernet_get_hw_address (NMDeviceEthernet *device)
 {
@@ -61,6 +79,14 @@
 	return priv->hw_address;
 }
 
+/**
+ * nm_device_ethernet_get_speed:
+ * @device: a #NMDeviceEthernet
+ *
+ * Gets the speed of the #NMDeviceEthernet.
+ *
+ * Returns: the speed of the device
+ **/
 guint32
 nm_device_ethernet_get_speed (NMDeviceEthernet *device)
 {
@@ -78,6 +104,14 @@
 	return priv->speed;
 }
 
+/**
+ * nm_device_ethernet_get_carrier:
+ * @device: a #NMDeviceEthernet
+ *
+ * Whether the device has carrier.
+ *
+ * Returns: %TRUE if the device has carrier
+ **/
 gboolean
 nm_device_ethernet_get_carrier (NMDeviceEthernet *device)
 {
@@ -214,6 +248,12 @@
 	object_class->get_property = get_property;
 
 	/* properties */
+
+	/**
+	 * NMDeviceEthernet:hw-address:
+	 *
+	 * The hardware (MAC) address of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_HW_ADDRESS,
 		 g_param_spec_string (NM_DEVICE_ETHERNET_HW_ADDRESS,
@@ -222,6 +262,11 @@
 						  NULL,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMDeviceEthernet:speed:
+	 *
+	 * The speed of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_SPEED,
 		 g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED,
@@ -230,6 +275,11 @@
 					    0, G_MAXUINT32, 0,
 					    G_PARAM_READABLE));
 
+	/**
+	 * NMDeviceEthernet:carrier:
+	 *
+	 * Whether the device has carrier.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_CARRIER,
 		 g_param_spec_boolean (NM_DEVICE_ETHERNET_CARRIER,

Modified: branches/mbca/libnm-glib/nm-device-wifi.c
==============================================================================
--- branches/mbca/libnm-glib/nm-device-wifi.c	(original)
+++ branches/mbca/libnm-glib/nm-device-wifi.c	Mon Aug 18 08:30:28 2008
@@ -60,6 +60,15 @@
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+/**
+ * nm_device_wifi_new:
+ * @connection: the #DBusGConnection
+ * @path: the DBus object path of the device
+ *
+ * Creates a new #NMDeviceWifi.
+ *
+ * Returns: a new device
+ **/
 GObject *
 nm_device_wifi_new (DBusGConnection *connection, const char *path)
 {
@@ -72,6 +81,15 @@
 	                     NULL);
 }
 
+/**
+ * nm_device_wifi_get_hw_address:
+ * @device: a #NMDeviceWifi
+ *
+ * Gets the hardware (MAC) address of the #NMDeviceWifi
+ *
+ * Returns: the hardware address. This is the internal string used by the
+ * device, and must not be modified.
+ **/
 const char *
 nm_device_wifi_get_hw_address (NMDeviceWifi *device)
 {
@@ -89,6 +107,14 @@
 	return priv->hw_address;
 }
 
+/**
+ * nm_device_wifi_get_mode:
+ * @device: a #NMDeviceWifi
+ *
+ * Gets the #NMDeviceWifi mode.
+ *
+ * Returns: the mode
+ **/
 NM80211Mode
 nm_device_wifi_get_mode (NMDeviceWifi *device)
 {
@@ -106,6 +132,14 @@
 	return priv->mode;
 }
 
+/**
+ * nm_device_wifi_get_bitrate:
+ * @device: a #NMDeviceWifi
+ *
+ * Gets the bit rate of the #NMDeviceWifi.
+ *
+ * Returns: the bit rate
+ **/
 guint32
 nm_device_wifi_get_bitrate (NMDeviceWifi *device)
 {
@@ -137,6 +171,14 @@
 	return priv->rate;
 }
 
+/**
+ * nm_device_wifi_get_capabilities:
+ * @device: a #NMDeviceWifi
+ *
+ * Gets the WIFI capabilities of the #NMDeviceWifi.
+ *
+ * Returns: the capabilities
+ **/
 guint32
 nm_device_wifi_get_capabilities (NMDeviceWifi *device)
 {
@@ -154,6 +196,14 @@
 	return priv->wireless_caps;
 }
 
+/**
+ * nm_device_wifi_get_active_access_point:
+ * @self: a #NMDeviceWifi
+ *
+ * Gets the active #NMAccessPoint.
+ *
+ * Returns: the access point or %NULL if none is active
+ **/
 NMAccessPoint *
 nm_device_wifi_get_active_access_point (NMDeviceWifi *self)
 {
@@ -196,6 +246,15 @@
 	return priv->active_ap;
 }
 
+/**
+ * nm_device_wifi_get_access_points:
+ * @self: a #NMDeviceWifi
+ *
+ * Gets all the scanned access points of the #NMDeviceWifi.
+ *
+ * Returns: a #GPtrArray containing all the scanned #NMAccessPoint<!-- -->s.
+ * The returned array is owned by the client and should not be modified.
+ **/
 const GPtrArray *
 nm_device_wifi_get_access_points (NMDeviceWifi *self)
 {
@@ -226,6 +285,15 @@
 	return handle_ptr_array_return (priv->aps);
 }
 
+/**
+ * nm_device_wifi_get_access_point_by_path:
+ * @self: a #NMDeviceWifi
+ * @path: the object path of the access point
+ *
+ * Gets a #NMAccessPoint by path.
+ *
+ * Returns: the access point or %NULL if none is found.
+ **/
 NMAccessPoint *
 nm_device_wifi_get_access_point_by_path (NMDeviceWifi *self,
 											        const char *path)
@@ -323,6 +391,13 @@
 	}
 }
 
+/**
+ * nm_device_wifi_set_wireless_enabled:
+ * @device: a #NMDeviceWifi
+ * @enabled: %TRUE to enable the device
+ *
+ * Enables or disables the wireless device.
+ **/
 void
 nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device,
                                                 gboolean enabled)
@@ -547,6 +622,12 @@
 	object_class->finalize = finalize;
 
 	/* properties */
+
+	/**
+	 * NMDeviceWifi:hw-address:
+	 *
+	 * The hardware (MAC) address of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_HW_ADDRESS,
 		 g_param_spec_string (NM_DEVICE_WIFI_HW_ADDRESS,
@@ -555,6 +636,11 @@
 						  NULL,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMDeviceWifi:mode:
+	 *
+	 * The mode of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_MODE,
 		 g_param_spec_uint (NM_DEVICE_WIFI_MODE,
@@ -563,6 +649,11 @@
 					    NM_802_11_MODE_UNKNOWN, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA,
 					    G_PARAM_READABLE));
 
+	/**
+	 * NMDeviceWifi:bitrate:
+	 *
+	 * The bit rate of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_BITRATE,
 		 g_param_spec_uint (NM_DEVICE_WIFI_BITRATE,
@@ -571,6 +662,11 @@
 					    0, G_MAXUINT32, 0,
 					    G_PARAM_READABLE));
 
+	/**
+	 * NMDeviceWifi:active-access-point:
+	 *
+	 * The active #NMAccessPoint of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_ACTIVE_ACCESS_POINT,
 		 g_param_spec_object (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT,
@@ -579,6 +675,11 @@
 						 NM_TYPE_ACCESS_POINT,
 						 G_PARAM_READABLE));
 
+	/**
+	 * NMDeviceWifi:wireless-capabilities:
+	 *
+	 * The wireless capabilities of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_WIRELESS_CAPABILITIES,
 		 g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES,
@@ -588,6 +689,14 @@
 		                    G_PARAM_READABLE));
 
 	/* signals */
+
+	/**
+	 * NMDeviceWifi::access-point-added:
+	 * @device: the wifi device that received the signal
+	 * @ap: the new access point
+	 *
+	 * Notifies that a #NMAccessPoint is added to the wifi device.
+	 **/
 	signals[ACCESS_POINT_ADDED] =
 		g_signal_new ("access-point-added",
 				    G_OBJECT_CLASS_TYPE (object_class),
@@ -598,6 +707,13 @@
 				    G_TYPE_NONE, 1,
 				    G_TYPE_OBJECT);
 
+	/**
+	 * NMDeviceWifi::access-point-removed:
+	 * @device: the wifi device that received the signal
+	 * @ap: the removed access point
+	 *
+	 * Notifies that a #NMAccessPoint is removed from the wifi device.
+	 **/
 	signals[ACCESS_POINT_REMOVED] =
 		g_signal_new ("access-point-removed",
 				    G_OBJECT_CLASS_TYPE (object_class),

Modified: branches/mbca/libnm-glib/nm-device.c
==============================================================================
--- branches/mbca/libnm-glib/nm-device.c	(original)
+++ branches/mbca/libnm-glib/nm-device.c	Mon Aug 18 08:30:28 2008
@@ -28,6 +28,8 @@
 	gboolean managed;
 	NMIP4Config *ip4_config;
 	gboolean null_ip4_config;
+	NMDHCP4Config *dhcp4_config;
+	gboolean null_dhcp4_config;
 	NMDeviceState state;
 	char *product;
 	char *vendor;
@@ -41,6 +43,7 @@
 	PROP_CAPABILITIES,
 	PROP_MANAGED,
 	PROP_IP4_CONFIG,
+	PROP_DHCP4_CONFIG,
 	PROP_STATE,
 	PROP_PRODUCT,
 	PROP_VENDOR,
@@ -106,6 +109,46 @@
 	return TRUE;
 }
 
+static gboolean
+demarshal_dhcp4_config (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
+{
+	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
+	const char *path;
+	NMDHCP4Config *config = NULL;
+	DBusGConnection *connection;
+
+	if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
+		return FALSE;
+
+	priv->null_dhcp4_config = FALSE;
+
+	path = g_value_get_boxed (value);
+	if (path) {
+		if (!strcmp (path, "/"))
+			priv->null_dhcp4_config = TRUE;
+		else {
+			config = NM_DHCP4_CONFIG (nm_object_cache_get (path));
+			if (config)
+				config = g_object_ref (config);
+			else {
+				connection = nm_object_get_connection (object);
+				config = NM_DHCP4_CONFIG (nm_dhcp4_config_new (connection, path));
+			}
+		}
+	}
+
+	if (priv->dhcp4_config) {
+		g_object_unref (priv->dhcp4_config);
+		priv->dhcp4_config = NULL;
+	}
+
+	if (config)
+		priv->dhcp4_config = config;
+
+	nm_object_queue_notify (object, NM_DEVICE_DHCP4_CONFIG);
+	return TRUE;
+}
+
 static void
 register_for_property_changed (NMDevice *device)
 {
@@ -117,6 +160,7 @@
 		{ NM_DEVICE_CAPABILITIES, nm_object_demarshal_generic, &priv->capabilities },
 		{ NM_DEVICE_MANAGED,      nm_object_demarshal_generic, &priv->managed },
 		{ NM_DEVICE_IP4_CONFIG,   demarshal_ip4_config,        &priv->ip4_config },
+		{ NM_DEVICE_DHCP4_CONFIG, demarshal_dhcp4_config,      &priv->dhcp4_config },
 		{ NULL },
 	};
 
@@ -198,6 +242,8 @@
 	g_object_unref (priv->proxy);
 	if (priv->ip4_config)
 		g_object_unref (priv->ip4_config);
+	if (priv->dhcp4_config)
+		g_object_unref (priv->dhcp4_config);
 
 	G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
 }
@@ -243,6 +289,9 @@
 	case PROP_IP4_CONFIG:
 		g_value_set_object (value, nm_device_get_ip4_config (device));
 		break;
+	case PROP_DHCP4_CONFIG:
+		g_value_set_object (value, nm_device_get_dhcp4_config (device));
+		break;
 	case PROP_STATE:
 		g_value_set_uint (value, nm_device_get_state (device));
 		break;
@@ -272,6 +321,12 @@
 	object_class->finalize = finalize;
 
 	/* properties */
+
+	/**
+	 * NMDevice:interface:
+	 *
+	 * The interface of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_INTERFACE,
 		 g_param_spec_string (NM_DEVICE_INTERFACE,
@@ -280,6 +335,11 @@
 						  NULL,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMDevice:udi:
+	 *
+	 * The HAL UDI of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_UDI,
 		 g_param_spec_string (NM_DEVICE_UDI,
@@ -288,6 +348,11 @@
 						  NULL,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMDevice:driver:
+	 *
+	 * The driver of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_DRIVER,
 		 g_param_spec_string (NM_DEVICE_DRIVER,
@@ -296,6 +361,11 @@
 						  NULL,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMDevice:capabilities:
+	 *
+	 * The capabilities of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_CAPABILITIES,
 		 g_param_spec_uint (NM_DEVICE_CAPABILITIES,
@@ -304,6 +374,11 @@
 						  0, G_MAXUINT32, 0,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMDevice:managed:
+	 *
+	 * Whether the device is managed by NetworkManager.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_MANAGED,
 		 g_param_spec_boolean (NM_DEVICE_MANAGED,
@@ -312,6 +387,11 @@
 						  FALSE,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMDevice:ip4-config:
+	 *
+	 * The #NMIP4Config of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_IP4_CONFIG,
 		 g_param_spec_object (NM_DEVICE_IP4_CONFIG,
@@ -320,6 +400,24 @@
 						  NM_TYPE_IP4_CONFIG,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMDevice:dhcp4-config:
+	 *
+	 * The #NMDHCP4Config of the device.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_DHCP4_CONFIG,
+		 g_param_spec_object (NM_DEVICE_DHCP4_CONFIG,
+						  "DHCP4 Config",
+						  "DHCP4 Config",
+						  NM_TYPE_DHCP4_CONFIG,
+						  G_PARAM_READABLE));
+
+	/**
+	 * NMDevice:state:
+	 *
+	 * The state of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_STATE,
 		 g_param_spec_uint (NM_DEVICE_STATE,
@@ -328,6 +426,11 @@
 						  0, G_MAXUINT32, 0,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMDevice:vendor:
+	 *
+	 * The vendor string of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_VENDOR,
 		 g_param_spec_string (NM_DEVICE_VENDOR,
@@ -336,6 +439,11 @@
 						  NULL,
 						  G_PARAM_READABLE));
 
+	/**
+	 * NMDevice:product:
+	 *
+	 * The product string of the device.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_PRODUCT,
 		 g_param_spec_string (NM_DEVICE_PRODUCT,
@@ -345,6 +453,14 @@
 						  G_PARAM_READABLE));
 
 	/* signals */
+
+	/**
+	 * NMDevice::state-changed:
+	 * @device: the client that received the signal
+	 * @state: the new state of the device
+	 *
+	 * Notifies the state change of a #NMDevice.
+	 **/
 	signals[STATE_CHANGED] =
 		g_signal_new ("state-changed",
 				    G_OBJECT_CLASS_TYPE (object_class),
@@ -356,6 +472,15 @@
 				    G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
 }
 
+/**
+ * nm_device_new:
+ * @connection: the #DBusGConnection
+ * @path: the DBus object path of the device
+ *
+ * Creates a new #NMDevice.
+ *
+ * Returns: a new device
+ **/
 GObject *
 nm_device_new (DBusGConnection *connection, const char *path)
 {
@@ -418,6 +543,15 @@
 	return G_OBJECT (device);
 }
 
+/**
+ * nm_device_get_iface:
+ * @device: a #NMDevice
+ *
+ * Gets the interface name of the #NMDevice.
+ *
+ * Returns: the interface of the device. This is the internal string used by the
+ * device, and must not be modified.
+ **/
 const char *
 nm_device_get_iface (NMDevice *device)
 {
@@ -435,6 +569,15 @@
 	return priv->iface;
 }
 
+/**
+ * nm_device_get_udi:
+ * @device: a #NMDevice
+ *
+ * Gets the HAL UDI of the #NMDevice.
+ *
+ * Returns: the HAL UDI of the device. This is the internal string used by the
+ * device, and must not be modified.
+ **/
 const char *
 nm_device_get_udi (NMDevice *device)
 {
@@ -452,6 +595,15 @@
 	return priv->udi;
 }
 
+/**
+ * nm_device_get_driver:
+ * @device: a #NMDevice
+ *
+ * Gets the driver of the #NMDevice.
+ *
+ * Returns: the driver of the device. This is the internal string used by the
+ * device, and must not be modified.
+ **/
 const char *
 nm_device_get_driver (NMDevice *device)
 {
@@ -469,6 +621,14 @@
 	return priv->driver;
 }
 
+/**
+ * nm_device_get_capabilities:
+ * @device: a #NMDevice
+ *
+ * Gets the device' capabilities.
+ *
+ * Returns: the capabilities
+ **/
 guint32
 nm_device_get_capabilities (NMDevice *device)
 {
@@ -486,6 +646,14 @@
 	return priv->capabilities;
 }
 
+/**
+ * nm_device_get_managed:
+ * @device: a #NMDevice
+ *
+ * Whether the #NMDevice is managed by NetworkManager.
+ *
+ * Returns: %TRUE if the device is managed by NetworkManager
+ **/
 gboolean
 nm_device_get_managed (NMDevice *device)
 {
@@ -503,6 +671,14 @@
 	return priv->managed;
 }
 
+/**
+ * nm_device_get_ip4_config:
+ * @device: a #NMDevice
+ *
+ * Gets the current #NMIP4Config associated with the #NMDevice.
+ *
+ * Returns: the #NMIP4Config or %NULL if the device is not activated.
+ **/
 NMIP4Config *
 nm_device_get_ip4_config (NMDevice *device)
 {
@@ -529,6 +705,49 @@
 	return priv->ip4_config;
 }
 
+/**
+ * nm_device_get_dhcp4_config:
+ * @device: a #NMDevice
+ *
+ * Gets the current #NMDHCP4Config associated with the #NMDevice.
+ *
+ * Returns: the #NMDHCPConfig or %NULL if the device is not activated or not
+ * using DHCP.
+ **/
+NMDHCP4Config *
+nm_device_get_dhcp4_config (NMDevice *device)
+{
+	NMDevicePrivate *priv;
+	char *path;
+	GValue value = { 0, };
+
+	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
+
+	priv = NM_DEVICE_GET_PRIVATE (device);
+	if (priv->dhcp4_config)
+		return priv->dhcp4_config;
+	if (priv->null_dhcp4_config)
+		return NULL;
+
+	path = nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Dhcp4Config");
+	if (path) {
+		g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
+		g_value_take_boxed (&value, path);
+		demarshal_dhcp4_config (NM_OBJECT (device), NULL, &value, &priv->dhcp4_config);
+		g_value_unset (&value);
+	}
+
+	return priv->dhcp4_config;
+}
+
+/**
+ * nm_device_get_state:
+ * @device: a #NMDevice
+ *
+ * Gets the current #NMDevice state.
+ *
+ * Returns: the current device state
+ **/
 NMDeviceState
 nm_device_get_state (NMDevice *device)
 {
@@ -724,6 +943,15 @@
 	nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_PRODUCT);
 }
 
+/**
+ * nm_device_get_product:
+ * @device: a #NMDevice
+ *
+ * Gets the product string of the #NMDevice.
+ *
+ * Returns: the product name of the device. This is the internal string used by the
+ * device, and must not be modified.
+ **/
 const char *
 nm_device_get_product (NMDevice *device)
 {
@@ -737,6 +965,15 @@
 	return priv->product;
 }
 
+/**
+ * nm_device_get_vendor:
+ * @device: a #NMDevice
+ *
+ * Gets the vendor string of the #NMDevice.
+ *
+ * Returns: the vendor name of the device. This is the internal string used by the
+ * device, and must not be modified.
+ **/
 const char *
 nm_device_get_vendor (NMDevice *device)
 {

Modified: branches/mbca/libnm-glib/nm-device.h
==============================================================================
--- branches/mbca/libnm-glib/nm-device.h	(original)
+++ branches/mbca/libnm-glib/nm-device.h	Mon Aug 18 08:30:28 2008
@@ -7,6 +7,7 @@
 #include "nm-object.h"
 #include "NetworkManager.h"
 #include "nm-ip4-config.h"
+#include "nm-dhcp4-config.h"
 #include "nm-connection.h"
 
 G_BEGIN_DECLS
@@ -24,6 +25,7 @@
 #define NM_DEVICE_CAPABILITIES "capabilities"
 #define NM_DEVICE_MANAGED "managed"
 #define NM_DEVICE_IP4_CONFIG "ip4-config"
+#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config"
 #define NM_DEVICE_STATE "state"
 #define NM_DEVICE_VENDOR "vendor"
 #define NM_DEVICE_PRODUCT "product"
@@ -46,15 +48,16 @@
 
 GObject * nm_device_new (DBusGConnection *connection, const char *path);
 
-const char *  nm_device_get_iface        (NMDevice *device);
-const char *  nm_device_get_udi          (NMDevice *device);
-const char *  nm_device_get_driver       (NMDevice *device);
-guint32       nm_device_get_capabilities (NMDevice *device);
-gboolean      nm_device_get_managed      (NMDevice *device);
-NMIP4Config * nm_device_get_ip4_config   (NMDevice *device);
-NMDeviceState nm_device_get_state        (NMDevice *device);
-const char *  nm_device_get_product      (NMDevice *device);
-const char *  nm_device_get_vendor       (NMDevice *device);
+const char *  nm_device_get_iface          (NMDevice *device);
+const char *  nm_device_get_udi            (NMDevice *device);
+const char *  nm_device_get_driver         (NMDevice *device);
+guint32       nm_device_get_capabilities   (NMDevice *device);
+gboolean      nm_device_get_managed        (NMDevice *device);
+NMIP4Config * nm_device_get_ip4_config     (NMDevice *device);
+NMDHCP4Config * nm_device_get_dhcp4_config (NMDevice *device);
+NMDeviceState nm_device_get_state          (NMDevice *device);
+const char *  nm_device_get_product        (NMDevice *device);
+const char *  nm_device_get_vendor         (NMDevice *device);
 
 G_END_DECLS
 

Modified: branches/mbca/libnm-glib/nm-gsm-device.c
==============================================================================
--- branches/mbca/libnm-glib/nm-gsm-device.c	(original)
+++ branches/mbca/libnm-glib/nm-gsm-device.c	Mon Aug 18 08:30:28 2008
@@ -87,6 +87,15 @@
 	object_class->dispose = dispose;
 }
 
+/**
+ * nm_gsm_device_new:
+ * @connection: the #DBusGConnection
+ * @path: the DBus object path of the device
+ *
+ * Creates a new #NMGsmDevice.
+ *
+ * Returns: a new device
+ **/
 NMGsmDevice *
 nm_gsm_device_new (DBusGConnection *connection, const char *path)
 {

Modified: branches/mbca/libnm-glib/nm-ip4-config.c
==============================================================================
--- branches/mbca/libnm-glib/nm-ip4-config.c	(original)
+++ branches/mbca/libnm-glib/nm-ip4-config.c	Mon Aug 18 08:30:28 2008
@@ -17,8 +17,6 @@
 	char *hostname;
 	GArray *nameservers;
 	GPtrArray *domains;
-	char *nis_domain;
-	GArray *nis_servers;
 	GSList *routes;
 } NMIP4ConfigPrivate;
 
@@ -28,8 +26,6 @@
 	PROP_HOSTNAME,
 	PROP_NAMESERVERS,
 	PROP_DOMAINS,
-	PROP_NIS_DOMAIN,
-	PROP_NIS_SERVERS,
 	PROP_ROUTES,
 
 	LAST_PROP
@@ -63,8 +59,6 @@
 
 	if (!strcmp (pspec->name, NM_IP4_CONFIG_NAMESERVERS))
 		nm_object_queue_notify (object, NM_IP4_CONFIG_NAMESERVERS);
-	else if (!strcmp (pspec->name, NM_IP4_CONFIG_NIS_SERVERS))
-		nm_object_queue_notify (object, NM_IP4_CONFIG_NAMESERVERS);
 	return TRUE;
 }
 
@@ -102,8 +96,6 @@
 		{ NM_IP4_CONFIG_HOSTNAME,    nm_object_demarshal_generic,  &priv->hostname },
 		{ NM_IP4_CONFIG_NAMESERVERS, demarshal_ip4_array,          &priv->nameservers },
 		{ NM_IP4_CONFIG_DOMAINS,     demarshal_domains,            &priv->domains },
-		{ NM_IP4_CONFIG_NIS_DOMAIN,  nm_object_demarshal_generic,  &priv->nis_domain },
-		{ NM_IP4_CONFIG_NIS_SERVERS, demarshal_ip4_array,          &priv->nis_servers },
 		{ NM_IP4_CONFIG_ROUTES,      demarshal_ip4_routes_array,   &priv->routes },
 		{ NULL },
 	};
@@ -153,11 +145,8 @@
 	g_slist_free (priv->routes);
 
 	g_free (priv->hostname);
-	g_free (priv->nis_domain);
 	if (priv->nameservers)
 		g_array_free (priv->nameservers, TRUE);
-	if (priv->nis_servers)
-		g_array_free (priv->nis_servers, TRUE);
 
 	if (priv->domains) {
 		g_ptr_array_foreach (priv->domains, (GFunc) g_free, NULL);
@@ -189,12 +178,6 @@
 	case PROP_DOMAINS:
 		g_value_set_boxed (value, nm_ip4_config_get_domains (self));
 		break;
-	case PROP_NIS_DOMAIN:
-		g_value_set_string (value, nm_ip4_config_get_nis_domain (self));
-		break;
-	case PROP_NIS_SERVERS:
-		g_value_set_boxed (value, nm_ip4_config_get_nis_servers (self));
-		break;
 	case PROP_ROUTES:
 		nm_utils_ip4_routes_to_gvalue (priv->routes, value);
 		break;
@@ -217,6 +200,12 @@
 	object_class->finalize = finalize;
 
 	/* properties */
+
+	/**
+	 * NMIP4Config:addresses:
+	 *
+	 * The #GPtrArray containing #NMSettingIP4Address<!-- -->es of the configuration.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_ADDRESSES,
 		 g_param_spec_pointer (NM_IP4_CONFIG_ADDRESSES,
@@ -224,6 +213,11 @@
 						       "Addresses",
 						       G_PARAM_READABLE));
 
+	/**
+	 * NMIP4Config:hostname:
+	 *
+	 * The host name string of the configuration.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_HOSTNAME,
 		 g_param_spec_string (NM_IP4_CONFIG_HOSTNAME,
@@ -232,6 +226,11 @@
 						    NULL,
 						    G_PARAM_READABLE));
 
+	/**
+	 * NMIP4Config:nameservers:
+	 *
+	 * The #GArray containing name servers (%guint32<!-- -->es) of the configuration.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_NAMESERVERS,
 		 g_param_spec_boxed (NM_IP4_CONFIG_NAMESERVERS,
@@ -240,6 +239,11 @@
 						    NM_TYPE_UINT_ARRAY,
 						    G_PARAM_READABLE));
 
+	/**
+	 * NMIP4Config:domains:
+	 *
+	 * The #GPtrArray containing domain strings of the configuration.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_DOMAINS,
 		 g_param_spec_boxed (NM_IP4_CONFIG_DOMAINS,
@@ -248,22 +252,11 @@
 						    NM_TYPE_STRING_ARRAY,
 						    G_PARAM_READABLE));
 
-	g_object_class_install_property
-		(object_class, PROP_NIS_DOMAIN,
-		 g_param_spec_string (NM_IP4_CONFIG_NIS_DOMAIN,
-						    "NIS domain",
-						    "NIS domain",
-						    NULL,
-						    G_PARAM_READABLE));
-
-	g_object_class_install_property
-		(object_class, PROP_NIS_SERVERS,
-		 g_param_spec_boxed (NM_IP4_CONFIG_NIS_SERVERS,
-						    "NIS servers",
-						    "NIS servers",
-						    NM_TYPE_UINT_ARRAY,
-						    G_PARAM_READABLE));
-
+	/**
+	 * NMIP4Config:routes:
+	 *
+	 * The #GPtrArray containing #NMSettingIP4Route<!-- -->s of the configuration.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_ROUTES,
 		 g_param_spec_pointer (NM_IP4_CONFIG_ROUTES,
@@ -272,6 +265,15 @@
 						       G_PARAM_READABLE));
 }
 
+/**
+ * nm_ip4_config_new:
+ * @connection: the #DBusGConnection
+ * @object_path: the DBus object path of the device
+ *
+ * Creates a new #NMIP4Config.
+ *
+ * Returns: a new IP4 configuration
+ **/
 GObject *
 nm_ip4_config_new (DBusGConnection *connection, const char *object_path)
 {
@@ -281,6 +283,15 @@
 									 NULL);
 }
 
+/**
+ * nm_ip4_config_get_addresses:
+ * @config: a #NMIP4Config
+ *
+ * Gets the IP4 addresses (containing the address, prefix, and gateway).
+ *
+ * Returns: the #GSList containing #NMSettingIP4Address<!-- -->es. This is the internal copy
+ * used by the configuration and must not be modified.
+ **/
 const GSList *
 nm_ip4_config_get_addresses (NMIP4Config *config)
 {
@@ -306,6 +317,15 @@
 	return priv->addresses;
 }
 
+/**
+ * nm_ip4_config_get_hostname:
+ * @config: a #NMIP4Config
+ *
+ * Gets the host name.
+ *
+ * Returns: the host name from the configuration. This is the internal copy used by the
+ * configuration and must not be modified.
+ **/
 const char *
 nm_ip4_config_get_hostname (NMIP4Config *config)
 {
@@ -323,6 +343,15 @@
 	return priv->hostname;
 }
 
+/**
+ * nm_ip4_config_get_nameservers:
+ * @config: a #NMIP4Config
+ *
+ * Gets the domain name servers (DNS).
+ *
+ * Returns: the #GArray containing %guint32<!-- -->s. This is the internal copy used by the
+ * configuration and must not be modified.
+ **/
 const GArray *
 nm_ip4_config_get_nameservers (NMIP4Config *config)
 {
@@ -349,7 +378,15 @@
 
 	return priv->nameservers;
 }
-
+/**
+ * nm_ip4_config_get_domains:
+ * @config: a #NMIP4Config
+ *
+ * Gets the domain names.
+ *
+ * Returns: the #GPtrArray containing domains as strings. This is the 
+ * internal copy used by the configuration, and must not be modified.
+ **/
 const GPtrArray *
 nm_ip4_config_get_domains (NMIP4Config *config)
 {
@@ -380,50 +417,15 @@
 	return handle_ptr_array_return (priv->domains);
 }
 
-const char *
-nm_ip4_config_get_nis_domain (NMIP4Config *config)
-{
-	NMIP4ConfigPrivate *priv;
-
-	g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL);
-
-	priv = NM_IP4_CONFIG_GET_PRIVATE (config);
-	if (!priv->nis_domain) {
-		priv->nis_domain = nm_object_get_string_property (NM_OBJECT (config),
-		                                                  NM_DBUS_INTERFACE_IP4_CONFIG,
-		                                                  "NisDomain");
-	}
-
-	return priv->nis_domain;
-}
-
-const GArray *
-nm_ip4_config_get_nis_servers (NMIP4Config *config)
-{
-	NMIP4ConfigPrivate *priv;
-	GArray *array = NULL;
-	GValue value = {0,};
-
-	g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL);
-
-	priv = NM_IP4_CONFIG_GET_PRIVATE (config);
-	if (!priv->nis_servers) {
-		if (nm_object_get_property (NM_OBJECT (config),
-									NM_DBUS_INTERFACE_IP4_CONFIG,
-									"NisServers",
-									&value)) {
-			array = (GArray *) g_value_get_boxed (&value);
-			if (array && array->len) {
-				priv->nis_servers = g_array_sized_new (FALSE, TRUE, sizeof (guint32), array->len);
-				g_array_append_vals (priv->nis_servers, array->data, array->len);
-			}
-			g_value_unset (&value);
-		}
-	}
-
-	return priv->nis_servers;
-}
-
+/**
+ * nm_ip4_config_get_routes:
+ * @config: a #NMIP4Config
+ *
+ * Gets the routes.
+ *
+ * Returns: the #GSList containing #NMSettingIP4Route<!-- -->s. This is the 
+ * internal copy used by the configuration, and must not be modified.
+ **/
 const GSList *
 nm_ip4_config_get_routes (NMIP4Config *config)
 {

Modified: branches/mbca/libnm-glib/nm-ip4-config.h
==============================================================================
--- branches/mbca/libnm-glib/nm-ip4-config.h	(original)
+++ branches/mbca/libnm-glib/nm-ip4-config.h	Mon Aug 18 08:30:28 2008
@@ -27,8 +27,6 @@
 #define NM_IP4_CONFIG_HOSTNAME "hostname"
 #define NM_IP4_CONFIG_NAMESERVERS "nameservers"
 #define NM_IP4_CONFIG_DOMAINS "domains"
-#define NM_IP4_CONFIG_NIS_DOMAIN "nis-domain"
-#define NM_IP4_CONFIG_NIS_SERVERS "nis-servers"
 #define NM_IP4_CONFIG_ROUTES "routes"
 
 GType nm_ip4_config_get_type (void);
@@ -39,8 +37,6 @@
 const char *     nm_ip4_config_get_hostname    (NMIP4Config *config);
 const GArray *   nm_ip4_config_get_nameservers (NMIP4Config *config);
 const GPtrArray *nm_ip4_config_get_domains     (NMIP4Config *config);
-const char *     nm_ip4_config_get_nis_domain  (NMIP4Config *config);
-const GArray *   nm_ip4_config_get_nis_servers (NMIP4Config *config);
 const GSList *   nm_ip4_config_get_routes      (NMIP4Config *config);
 
 G_END_DECLS

Modified: branches/mbca/libnm-glib/nm-object.c
==============================================================================
--- branches/mbca/libnm-glib/nm-object.c	(original)
+++ branches/mbca/libnm-glib/nm-object.c	Mon Aug 18 08:30:28 2008
@@ -168,6 +168,12 @@
 	object_class->finalize = finalize;
 
 	/* porperties */
+
+	/**
+	 * NMObject:connection:
+	 *
+	 * The #DBusGConnection of the object.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_CONNECTION,
 		 g_param_spec_boxed (NM_OBJECT_DBUS_CONNECTION,
@@ -176,6 +182,11 @@
 							 DBUS_TYPE_G_CONNECTION,
 							 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
+	/**
+	 * NMObject:path:
+	 *
+	 * The DBus object path.
+	 **/
 	g_object_class_install_property
 		(object_class, PROP_PATH,
 		 g_param_spec_string (NM_OBJECT_DBUS_PATH,
@@ -185,6 +196,14 @@
 							  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 }
 
+/**
+ * nm_object_get_connection:
+ * @object: a #NMObject
+ *
+ * Gets the #NMObject's DBusGConnection.
+ *
+ * Returns: the connection
+ **/
 DBusGConnection *
 nm_object_get_connection (NMObject *object)
 {
@@ -193,6 +212,15 @@
 	return NM_OBJECT_GET_PRIVATE (object)->connection;
 }
 
+/**
+ * nm_object_get_path:
+ * @object: a #NMObject
+ *
+ * Gets the DBus path of the #NMObject.
+ *
+ * Returns: the object's path. This is the internal string used by the
+ * device, and must not be modified.
+ **/
 const char *
 nm_object_get_path (NMObject *object)
 {

Modified: branches/mbca/libnm-glib/nm-serial-device.c
==============================================================================
--- branches/mbca/libnm-glib/nm-serial-device.c	(original)
+++ branches/mbca/libnm-glib/nm-serial-device.c	Mon Aug 18 08:30:28 2008
@@ -26,6 +26,15 @@
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+/**
+ * nm_serial_device_get_bytes_received:
+ * @self: a #NMSerialDevice
+ *
+ * Gets the amount of bytes received by the serial device.
+ * This counter is reset when the device is activated.
+ *
+ * Returns: bytes received
+ **/
 guint32
 nm_serial_device_get_bytes_received (NMSerialDevice *self)
 {
@@ -34,6 +43,15 @@
 	return NM_SERIAL_DEVICE_GET_PRIVATE (self)->in_bytes;
 }
 
+/**
+ * nm_serial_device_get_bytes_sent:
+ * @self: a #NMSerialDevice
+ *
+ * Gets the amount of bytes sent by the serial device.
+ * This counter is reset when the device is activated.
+ *
+ * Returns: bytes sent
+ **/
 guint32
 nm_serial_device_get_bytes_sent (NMSerialDevice *self)
 {
@@ -148,6 +166,15 @@
 	object_class->dispose = dispose;
 
 	/* Signals */
+
+	/**
+	 * NMSerialDevice::ppp-stats:
+	 * @device: the serial device that received the signal
+	 * @in_bytes: the amount of bytes received
+	 * @out_bytes: the amount of bytes sent
+	 *
+	 * Notifies that a #NMAccessPoint is added to the wifi device.
+	 **/
 	signals[PPP_STATS] =
 		g_signal_new ("ppp-stats",
 					  G_OBJECT_CLASS_TYPE (object_class),

Modified: branches/mbca/libnm-glib/nm-settings.c
==============================================================================
--- branches/mbca/libnm-glib/nm-settings.c	(original)
+++ branches/mbca/libnm-glib/nm-settings.c	Mon Aug 18 08:30:28 2008
@@ -7,6 +7,13 @@
 #include "nm-dbus-glib-types.h"
 
 
+/**
+ * nm_settings_error_quark:
+ *
+ * Setting error quark.
+ *
+ * Returns: the setting error quark
+ **/
 GQuark
 nm_settings_error_quark (void)
 {
@@ -80,6 +87,14 @@
 	settings_class->list_connections = NULL;
 
 	/* signals */
+
+	/**
+	 * NMSettings::new-connection:
+	 * @setting: the setting that received the signal
+	 * @connection: the new #NMExportedConnection
+	 *
+	 * Notifies that a new exported connection is added.
+	 **/
 	settings_signals[S_NEW_CONNECTION] =
 		g_signal_new ("new-connection",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -94,6 +109,14 @@
 					 &dbus_glib_nm_settings_object_info);
 }
 
+/**
+ * nm_settings_list_connections:
+ * @settings: 
+ *
+ * Lists all the available connections.
+ *
+ * Returns: the #GSList containing #NMExportedConnection<!-- -->s
+ **/
 GSList *
 nm_settings_list_connections (NMSettings *settings)
 {

Modified: branches/mbca/libnm-glib/nm-vpn-plugin.c
==============================================================================
--- branches/mbca/libnm-glib/nm-vpn-plugin.c	(original)
+++ branches/mbca/libnm-glib/nm-vpn-plugin.c	Mon Aug 18 08:30:28 2008
@@ -46,6 +46,7 @@
 	/* Temporary stuff */
 	guint connect_timer;
 	guint quit_timer;
+	guint fail_stop_id;
 } NMVPNPluginPrivate;
 
 #define NM_VPN_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_PLUGIN, NMVPNPluginPrivate))
@@ -257,10 +258,20 @@
 }
 
 static gboolean
+fail_stop (gpointer data)
+{
+	NMVPNPlugin *plugin = NM_VPN_PLUGIN (data);
+
+	nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
+	return FALSE;
+}
+
+static gboolean
 nm_vpn_plugin_connect (NMVPNPlugin *plugin,
 				   NMConnection *connection,
 				   GError **err)
 {
+	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
 	gboolean ret = FALSE;
 	NMVPNServiceState state;
 
@@ -293,8 +304,14 @@
 	case NM_VPN_SERVICE_STATE_INIT:
 		nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING);
 		ret = NM_VPN_PLUGIN_GET_CLASS (plugin)->connect (plugin, connection, err);
-		if (!ret)
-			nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
+		if (!ret) {
+			/* Stop the plugin from and idle handler so that the Connect
+			 * method return gets sent before the STOP StateChanged signal.
+			 */
+			if (priv->fail_stop_id)
+				g_source_remove (priv->fail_stop_id);
+			priv->fail_stop_id = g_idle_add (fail_stop, plugin);
+		}
 		break;
 
 	default:
@@ -584,6 +601,9 @@
 
 	priv->disposed = TRUE;
 
+	if (priv->fail_stop_id)
+		g_source_remove (priv->fail_stop_id);
+
 	state = nm_vpn_plugin_get_state (plugin);
 
 	if (state == NM_VPN_SERVICE_STATE_STARTED ||
@@ -633,6 +653,11 @@
 		if (priv->quit_timer)
 			g_source_remove (priv->quit_timer);
 
+		if (priv->fail_stop_id) {
+			g_source_remove (priv->fail_stop_id);
+			priv->fail_stop_id = 0;
+		}
+
 		/* Add a timer to make sure we do not wait indefinitely for the successful connect. */
 		priv->connect_timer = g_timeout_add_full (G_PRIORITY_DEFAULT,
 										  NM_VPN_PLUGIN_CONNECT_TIMER,
@@ -655,6 +680,10 @@
 		if (priv->quit_timer)
 			g_source_remove (priv->quit_timer);
 
+		if (priv->fail_stop_id) {
+			g_source_remove (priv->fail_stop_id);
+			priv->fail_stop_id = 0;
+		}
 		break;
 	}
 }

Modified: branches/mbca/libnm-util/Makefile.am
==============================================================================
--- branches/mbca/libnm-util/Makefile.am	(original)
+++ branches/mbca/libnm-util/Makefile.am	Mon Aug 18 08:30:28 2008
@@ -24,7 +24,6 @@
 	nm-setting-wireless.h		\
 	nm-setting-wireless-security.h	\
 	nm-setting-vpn.h		\
-	nm-setting-vpn-properties.h	\
 	nm-utils.h
 
 libnm_util_la_SOURCES=			\
@@ -47,7 +46,6 @@
 	nm-setting-wireless.c		\
 	nm-setting-wireless-security.c	\
 	nm-setting-vpn.c		\
-	nm-setting-vpn-properties.c	\
 	nm-utils.c			\
 	$(libnm_util_include_HEADERS)
 

Modified: branches/mbca/libnm-util/nm-connection.c
==============================================================================
--- branches/mbca/libnm-util/nm-connection.c	(original)
+++ branches/mbca/libnm-util/nm-connection.c	Mon Aug 18 08:30:28 2008
@@ -39,7 +39,6 @@
 #include "nm-setting-wireless.h"
 #include "nm-setting-wireless-security.h"
 #include "nm-setting-vpn.h"
-#include "nm-setting-vpn-properties.h"
 
 #include "nm-setting-serial.h"
 #include "nm-setting-gsm.h"
@@ -197,11 +196,6 @@
 	                      NM_SETTING_VPN_ERROR,
 	                      4);
 
-	register_one_setting (NM_SETTING_VPN_PROPERTIES_SETTING_NAME,
-	                      NM_TYPE_SETTING_VPN_PROPERTIES,
-	                      NM_SETTING_VPN_PROPERTIES_ERROR,
-	                      5);
-
 	register_one_setting (NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	                      NM_TYPE_SETTING_IP4_CONFIG,
 	                      NM_SETTING_IP4_CONFIG_ERROR,

Modified: branches/mbca/libnm-util/nm-setting-vpn.c
==============================================================================
--- branches/mbca/libnm-util/nm-setting-vpn.c	(original)
+++ branches/mbca/libnm-util/nm-setting-vpn.c	Mon Aug 18 08:30:28 2008
@@ -70,6 +70,7 @@
 	PROP_0,
 	PROP_SERVICE_TYPE,
 	PROP_USER_NAME,
+	PROP_DATA,
 
 	LAST_PROP
 };
@@ -114,9 +115,24 @@
 }
 
 static void
+update_one_secret (NMSetting *setting, const char *key, GValue *value)
+{
+	NMSettingVPN *self = NM_SETTING_VPN (setting);
+
+	g_return_if_fail (key != NULL);
+	g_return_if_fail (value != NULL);
+	g_return_if_fail (G_VALUE_HOLDS_STRING (value));
+
+	/* Secrets are really only known to the VPNs themselves. */
+	g_hash_table_insert (self->data, g_strdup (key), g_value_dup_string (value));
+}
+
+static void
 nm_setting_vpn_init (NMSettingVPN *setting)
 {
-	((NMSetting *) setting)->name = g_strdup (NM_SETTING_VPN_SETTING_NAME);
+	NM_SETTING (setting)->name = g_strdup (NM_SETTING_VPN_SETTING_NAME);
+
+	setting->data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 }
 
 static void
@@ -126,11 +142,18 @@
 
 	g_free (self->service_type);
 	g_free (self->user_name);
+	g_hash_table_destroy (self->data);
 
 	G_OBJECT_CLASS (nm_setting_vpn_parent_class)->finalize (object);
 }
 
 static void
+copy_hash (gpointer key, gpointer value, gpointer user_data)
+{
+	g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), g_strdup (value));
+}
+
+static void
 set_property (GObject *object, guint prop_id,
 		    const GValue *value, GParamSpec *pspec)
 {
@@ -145,6 +168,11 @@
 		g_free (setting->user_name);
 		setting->user_name = g_value_dup_string (value);
 		break;
+	case PROP_DATA:
+		/* Must make a deep copy of the hash table here... */
+		g_hash_table_remove_all (setting->data);
+		g_hash_table_foreach (g_value_get_boxed (value), copy_hash, setting->data);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -164,6 +192,9 @@
 	case PROP_USER_NAME:
 		g_value_set_string (value, setting->user_name);
 		break;
+	case PROP_DATA:
+		g_value_set_boxed (value, setting->data);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -181,6 +212,7 @@
 	object_class->get_property = get_property;
 	object_class->finalize     = finalize;
 	parent_class->verify       = verify;
+	parent_class->update_one_secret = update_one_secret;
 
 	/* Properties */
 	g_object_class_install_property
@@ -198,4 +230,12 @@
 						  "User name",
 						  NULL,
 						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_DATA,
+		 nm_param_spec_specialized (NM_SETTING_VPN_DATA,
+							   "Data",
+							   "VPN Service specific data",
+							   DBUS_TYPE_G_MAP_OF_STRING,
+							   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 }

Modified: branches/mbca/libnm-util/nm-setting-vpn.h
==============================================================================
--- branches/mbca/libnm-util/nm-setting-vpn.h	(original)
+++ branches/mbca/libnm-util/nm-setting-vpn.h	Mon Aug 18 08:30:28 2008
@@ -54,12 +54,27 @@
 
 #define NM_SETTING_VPN_SERVICE_TYPE "service-type"
 #define NM_SETTING_VPN_USER_NAME    "user-name"
+#define NM_SETTING_VPN_DATA         "data"
 
 typedef struct {
 	NMSetting parent;
 
 	char *service_type;
+
+	/* username of the user requesting this connection, thus
+	 * it's really only valid for user connections, and it also
+	 * should never be saved out to persistent config.
+	 */
 	char *user_name;
+
+	/* The hash table is created at setting object
+	 * init time and should not be replaced.  It is
+	 * a char * -> char * mapping, and both the key
+	 * and value are owned by the hash table, and should
+	 * be allocated with functions whose value can be
+	 * freed with g_free()
+	 */
+	GHashTable *data;
 } NMSettingVPN;
 
 typedef struct {

Modified: branches/mbca/libnm-util/nm-utils.c
==============================================================================
--- branches/mbca/libnm-util/nm-utils.c	(original)
+++ branches/mbca/libnm-util/nm-utils.c	Mon Aug 18 08:30:28 2008
@@ -577,7 +577,7 @@
 }
 
 static void
-convert_one_hash_entry (gpointer key, gpointer value, gpointer user_data)
+convert_one_gvalue_hash_entry (gpointer key, gpointer value, gpointer user_data)
 {
 	GString *printable = (GString *) user_data;
 	char *value_as_string;
@@ -598,7 +598,33 @@
 	hash = (GHashTable *) g_value_get_boxed (src_value);
 
 	printable = g_string_new ("[");
-	g_hash_table_foreach (hash, convert_one_hash_entry, printable);
+	g_hash_table_foreach (hash, convert_one_gvalue_hash_entry, printable);
+	g_string_append (printable, " ]");
+
+	g_value_take_string (dest_value, printable->str);
+	g_string_free (printable, FALSE);
+}
+
+static void
+convert_one_string_hash_entry (gpointer key, gpointer value, gpointer user_data)
+{
+	GString *printable = (GString *) user_data;
+
+	g_string_append_printf (printable, " { '%s': %s },", (const char *) key, (const char *) value);
+}
+
+static void
+nm_utils_convert_string_hash_to_string (const GValue *src_value, GValue *dest_value)
+{
+	GHashTable *hash;
+	GString *printable;
+
+	g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_MAP_OF_STRING));
+
+	hash = (GHashTable *) g_value_get_boxed (src_value);
+
+	printable = g_string_new ("[");
+	g_hash_table_foreach (hash, convert_one_string_hash_entry, printable);
 	g_string_append (printable, " ]");
 
 	g_value_take_string (dest_value, printable->str);
@@ -626,6 +652,9 @@
 		g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_VARIANT,
 		                                 G_TYPE_STRING, 
 		                                 nm_utils_convert_gvalue_hash_to_string);
+		g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_STRING,
+		                                 G_TYPE_STRING, 
+		                                 nm_utils_convert_string_hash_to_string);
 		registered = TRUE;
 	}
 }

Modified: branches/mbca/src/Makefile.am
==============================================================================
--- branches/mbca/src/Makefile.am	(original)
+++ branches/mbca/src/Makefile.am	Mon Aug 18 08:30:28 2008
@@ -65,6 +65,8 @@
 		nm-gsm-device.h		\
 		nm-cdma-device.c		\
 		nm-cdma-device.h		\
+		nm-hso-gsm-device.c \
+		nm-hso-gsm-device.h \
 		wpa.c				\
 		wpa.h				\
 		nm-netlink.c			\
@@ -179,10 +181,8 @@
 	$(NetworkManager_DATA)
 
 rundir=$(localstatedir)/run/NetworkManager
-dispatcherdir=$(sysconfdir)/NetworkManager/dispatcher.d
 install-data-hook:
-	   $(mkinstalldirs) -m 0700 $(DESTDIR)$(rundir)
-	   $(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)
+	$(mkinstalldirs) -m 0700 $(DESTDIR)$(rundir)
 
 CLEANFILES = $(BUILT_SOURCES)
 

Modified: branches/mbca/src/NetworkManager.c
==============================================================================
--- branches/mbca/src/NetworkManager.c	(original)
+++ branches/mbca/src/NetworkManager.c	Mon Aug 18 08:30:28 2008
@@ -287,7 +287,6 @@
 	nm_logging_setup (become_daemon);
 	nm_info ("starting...");
 
-	nm_system_init ();
 	main_loop = g_main_loop_new (NULL, FALSE);
 
 	/* Create watch functions that monitor cards for link status. */

Modified: branches/mbca/src/NetworkManagerPolicy.c
==============================================================================
--- branches/mbca/src/NetworkManagerPolicy.c	(original)
+++ branches/mbca/src/NetworkManagerPolicy.c	Mon Aug 18 08:30:28 2008
@@ -20,17 +20,7 @@
  * (C) Copyright 2005 Red Hat, Inc.
  */
 
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <sys/select.h>
 #include <string.h>
-#include <stdlib.h>
-#include <sys/wait.h>
 
 #include "NetworkManagerPolicy.h"
 #include "NetworkManagerUtils.h"
@@ -41,6 +31,7 @@
 #include "nm-device.h"
 #include "nm-device-wifi.h"
 #include "nm-device-ethernet.h"
+#include "nm-hso-gsm-device.h"
 #include "nm-gsm-device.h"
 #include "nm-cdma-device.h"
 #include "nm-dbus-manager.h"
@@ -122,7 +113,6 @@
 	NMActRequest *best_req = NULL;
 	GSList *devices, *iter;
 	NMNamedManager *named_mgr;
-	NMIP4Config *config;
 
 	devices = nm_manager_get_devices (policy->manager);
 	for (iter = devices; iter; iter = g_slist_next (iter)) {
@@ -133,7 +123,7 @@
 		NMSettingIP4Config *s_ip4;
 		guint32 prio;
 		guint i;
-		gboolean have_gateway = FALSE;
+		gboolean can_default = FALSE;
 		
 		if (nm_device_get_state (dev) != NM_DEVICE_STATE_ACTIVATED)
 			continue;
@@ -158,12 +148,13 @@
 
 			addr = nm_ip4_config_get_address (ip4_config, i);
 			if (addr->gateway) {
-				have_gateway = TRUE;
+				can_default = TRUE;
 				break;
 			}
 		}
 
-		if (!have_gateway)
+		/* 'hso' devices never get a gateway from the remote end */
+		if (!can_default && !NM_IS_HSO_GSM_DEVICE (dev))
 			continue;
 
 		prio = get_device_priority (dev);
@@ -196,15 +187,17 @@
 	}
 
 	named_mgr = nm_named_manager_get ();
-	config = nm_device_get_ip4_config (best);
-	nm_named_manager_add_ip4_config (named_mgr, config, NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE);
+	nm_named_manager_add_ip4_config (named_mgr,
+									 nm_device_get_ip_iface (best),
+									 nm_device_get_ip4_config (best),
+									 NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE);
 	g_object_unref (named_mgr);
 
 	/* Now set new default active connection _after_ updating DNS info, so that
 	 * if the connection is shared dnsmasq picks up the right stuff.
 	 */
 	if (best_req)
-			nm_act_request_set_default (best_req, TRUE);
+		nm_act_request_set_default (best_req, TRUE);
 
 	nm_info ("Policy set (%s) as default device for routing and DNS.",
 	         nm_device_get_iface (best));
@@ -342,178 +335,6 @@
 	return nm_act_request_get_connection (req);
 }
 
-static gboolean
-do_cmd (const char *fmt, ...)
-{
-	va_list args;
-	char *cmd;
-	int ret;
-
-	va_start (args, fmt);
-	cmd = g_strdup_vprintf (fmt, args);
-	va_end (args);
-
-	nm_info ("Executing: %s", cmd);
-	ret = system (cmd);
-	g_free (cmd);
-
-	if (ret == -1) {
-		nm_info ("** Error executing command.");
-		return FALSE;
-	} else if (WEXITSTATUS (ret)) {
-		nm_info ("** Command returned exit status %d.", WEXITSTATUS (ret));
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static void
-sharing_init (void)
-{
-	do_cmd ("echo \"1\" > /proc/sys/net/ipv4/ip_forward");
-	do_cmd ("echo \"1\" > /proc/sys/net/ipv4/ip_dynaddr");
-	do_cmd ("/sbin/modprobe ip_tables iptable_nat ip_nat_ftp ip_nat_irc");
-	do_cmd ("/sbin/iptables -P INPUT ACCEPT");
-	do_cmd ("/sbin/iptables -F INPUT");
-	do_cmd ("/sbin/iptables -P OUTPUT ACCEPT");
-	do_cmd ("/sbin/iptables -F OUTPUT");
-	do_cmd ("/sbin/iptables -P FORWARD DROP");
-	do_cmd ("/sbin/iptables -F FORWARD");
-	do_cmd ("/sbin/iptables -t nat -F");
-}
-
-static void
-sharing_stop (NMActRequest *req)
-{
-	do_cmd ("/sbin/iptables -F INPUT");
-	do_cmd ("/sbin/iptables -F OUTPUT");
-	do_cmd ("/sbin/iptables -P FORWARD DROP");
-	do_cmd ("/sbin/iptables -F FORWARD");
-	do_cmd ("/sbin/iptables -F -t nat");
-
-	// Delete all User-specified chains
-	do_cmd ("/sbin/iptables -X");
-
-	// Reset all IPTABLES counters
-	do_cmd ("/sbin/iptables -Z");
-
-	nm_act_request_set_shared (req, FALSE);
-}
-
-/* Given a default activation request, start NAT-ing if there are any shared
- * connections.
- */
-static void
-sharing_restart (NMPolicy *policy, NMActRequest *req)
-{
-	GSList *devices, *iter;
-	const char *extif;
-	gboolean have_shared = FALSE;
-
-	if (nm_act_request_get_shared (req))
-		sharing_stop (req);
-
-	extif = nm_device_get_ip_iface (NM_DEVICE (nm_act_request_get_device (req)));
-	g_assert (extif);
-
-	/* Start NAT-ing every 'shared' connection */
-	devices = nm_manager_get_devices (policy->manager);
-	for (iter = devices; iter; iter = g_slist_next (iter)) {
-		NMDevice *candidate = NM_DEVICE (iter->data);
-		NMSettingIP4Config *s_ip4;
-		NMConnection *connection;
-		const char *intif;
-
-		if (nm_device_get_state (candidate) != NM_DEVICE_STATE_ACTIVATED)
-			continue;
-
-		connection = get_device_connection (candidate);
-		g_assert (connection);
-
-		s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
-		if (!s_ip4 || strcmp (s_ip4->method, "shared"))
-			continue;
-
-		/* Init sharing if there's a shared connection to NAT */
-		if (!have_shared) {
-			sharing_init ();
-			have_shared = TRUE;
-		}
-
-		// FWD: Allow all connections OUT and only existing and related ones IN
-		intif = nm_device_get_ip_iface (candidate);
-		g_assert (intif);
-		do_cmd ("/sbin/iptables -A FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT", extif, intif);
-		do_cmd ("/sbin/iptables -A FORWARD -i %s -o %s -j ACCEPT", extif, intif);
-		do_cmd ("/sbin/iptables -A FORWARD -i %s -o %s -j ACCEPT", intif, extif);
-	}
-
-	if (have_shared) {
-		// Enabling SNAT (MASQUERADE) functionality on $EXTIF
-		do_cmd ("/sbin/iptables -t nat -A POSTROUTING -o %s -j MASQUERADE", extif);
-
-		nm_act_request_set_shared (req, TRUE);
-	}
-}
-
-static void
-check_sharing (NMPolicy *policy, NMDevice *device, NMConnection *connection)
-{
-	NMSettingIP4Config *s_ip4;
-	GSList *devices, *iter;
-	NMActRequest *default_req = NULL;
-
-	if (!connection)
-		return;
-
-	/* We only care about 'shared' connections going up or down */
-	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
-	if (!s_ip4 || strcmp (s_ip4->method, "shared"))
-		return;
-
-	/* Find the default connection, if any */
-	devices = nm_manager_get_devices (policy->manager);
-	for (iter = devices; iter; iter = g_slist_next (iter)) {
-		NMDevice *candidate = NM_DEVICE (iter->data);
-		NMActRequest *req = nm_device_get_act_request (candidate);
-
-		if (req && nm_act_request_get_default (req)) {
-			default_req = req;
-			break;
-		}
-	}
-
-	/* Restart sharing if there's a default active connection */
-	if (default_req)
-		sharing_restart (policy, default_req);
-}
-
-static void
-active_connection_default_changed (NMActRequest *req,
-                                   GParamSpec *pspec,
-                                   NMPolicy *policy)
-{
-	gboolean is_default = nm_act_request_get_default (req);
-
-	if (is_default) {
-		if (nm_act_request_get_shared (req)) {
-			/* Already shared, shouldn't get here */
-			nm_warning ("%s: Active connection '%s' already shared.",
-			            __func__, nm_act_request_get_active_connection_path (req));
-			return;
-		}
-
-		sharing_restart (policy, req);
-	} else {
-		if (!nm_act_request_get_shared (req))
-			return;  /* Don't care about non-shared connections */
-
-		/* Tear down all NAT-ing */
-		sharing_stop (req);
-	}
-}
-
 static void
 device_state_changed (NMDevice *device,
                       NMDeviceState new_state,
@@ -532,27 +353,19 @@
 			nm_info ("Marking connection '%s' invalid.", get_connection_id (connection));
 		}
 		schedule_activate_check (policy, device);
-		check_sharing (policy, device, connection);
 		break;
 	case NM_DEVICE_STATE_ACTIVATED:
 		/* Clear the invalid tag on the connection */
 		if (connection)
 			g_object_set_data (G_OBJECT (connection), INVALID_TAG, NULL);
 
-		g_signal_connect (G_OBJECT (nm_device_get_act_request (device)),
-		                  "notify::default",
-		                  G_CALLBACK (active_connection_default_changed),
-		                  policy);
-
 		update_routing_and_dns (policy, FALSE);
-		check_sharing (policy, device, connection);
 		break;
 	case NM_DEVICE_STATE_UNMANAGED:
 	case NM_DEVICE_STATE_UNAVAILABLE:
 	case NM_DEVICE_STATE_DISCONNECTED:
 		update_routing_and_dns (policy, FALSE);
 		schedule_activate_check (policy, device);
-		check_sharing (policy, device, connection);
 		break;
 	default:
 		break;

Modified: branches/mbca/src/NetworkManagerSystem.c
==============================================================================
--- branches/mbca/src/NetworkManagerSystem.c	(original)
+++ branches/mbca/src/NetworkManagerSystem.c	Mon Aug 18 08:30:28 2008
@@ -385,7 +385,7 @@
 
 out:
 	named_mgr = nm_named_manager_get ();
-	nm_named_manager_add_ip4_config (named_mgr, config, NM_NAMED_IP_CONFIG_TYPE_VPN);
+	nm_named_manager_add_ip4_config (named_mgr, iface, config, NM_NAMED_IP_CONFIG_TYPE_VPN);
 	g_object_unref (named_mgr);
 
 	return TRUE;
@@ -406,7 +406,7 @@
 	g_return_val_if_fail (config != NULL, FALSE);
 
 	named_mgr = nm_named_manager_get ();
-	nm_named_manager_remove_ip4_config (named_mgr, config);
+	nm_named_manager_remove_ip4_config (named_mgr, iface, config);
 	g_object_unref (named_mgr);
 
 	return TRUE;
@@ -428,10 +428,10 @@
 
 gboolean nm_system_device_set_up_down_with_iface (const char *iface, gboolean up)
 {
+	struct rtnl_link *request = NULL, *old = NULL;
+	struct nl_handle *nlh;
 	gboolean success = FALSE;
 	guint32 idx;
-	struct rtnl_link *	request = NULL;
-	struct rtnl_link *	old = NULL;
 
 	g_return_val_if_fail (iface != NULL, FALSE);
 
@@ -446,16 +446,13 @@
 	idx = nm_netlink_iface_to_index (iface);
 	old = nm_netlink_index_to_rtnl_link (idx);
 	if (old) {
-		struct nl_handle *nlh;
-
 		nlh = nm_netlink_get_default_handle ();
 		if (nlh)
-			rtnl_link_change (nlh, old, request, 0);
+			success = (rtnl_link_change (nlh, old, request, 0) == 0) ? TRUE : FALSE;
 	}
 
 	rtnl_link_put (old);
 	rtnl_link_put (request);
-	success = TRUE;
 
 out:
 	return success;
@@ -483,6 +480,7 @@
 	}
 
 	/* Get device's flags */
+	memset (&ifr, 0, sizeof (ifr));
 	strncpy (ifr.ifr_name, iface, IFNAMSIZ);
 	if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0) {
 		if (errno != ENODEV) {

Modified: branches/mbca/src/NetworkManagerSystem.h
==============================================================================
--- branches/mbca/src/NetworkManagerSystem.h	(original)
+++ branches/mbca/src/NetworkManagerSystem.h	Mon Aug 18 08:30:28 2008
@@ -32,8 +32,6 @@
  * implemented in the backend files in backends/ directory
  */
 
-void			nm_system_init (void);
-
 void			nm_system_device_flush_ip4_routes				(NMDevice *dev);
 void			nm_system_device_flush_ip4_routes_with_iface	(const char *iface);
 
@@ -45,7 +43,6 @@
 void			nm_system_device_flush_ip4_addresses_with_iface	(const char *iface);
 
 void			nm_system_enable_loopback				(void);
-void			nm_system_kill_all_dhcp_daemons			(void);
 void			nm_system_update_dns					(void);
 
 gboolean		nm_system_device_set_from_ip4_config		(const char *iface,
@@ -65,12 +62,6 @@
 gboolean        nm_system_device_is_up (NMDevice *device);
 gboolean        nm_system_device_is_up_with_iface (const char *iface);
 
-void			nm_system_set_hostname (NMIP4Config *config);
-void			nm_system_activate_nis (NMIP4Config *config);
-void			nm_system_shutdown_nis (void);
-
 gboolean		nm_system_device_set_mtu (const char *iface, guint32 mtu);
 
-gboolean		nm_system_should_modify_resolv_conf (void);
-
 #endif

Modified: branches/mbca/src/NetworkManagerUtils.c
==============================================================================
--- branches/mbca/src/NetworkManagerUtils.c	(original)
+++ branches/mbca/src/NetworkManagerUtils.c	Mon Aug 18 08:30:28 2008
@@ -113,14 +113,14 @@
 		driver = "<unknown>";
 
 	if (caps == NM_DEVICE_CAP_NONE || !(NM_DEVICE_CAP_NM_SUPPORTED)) {
-		nm_info ("%s: Driver support level for '%s' is unsupported",
+		nm_info ("%s: driver '%s' is unsupported",
 				nm_device_get_iface (dev), driver);
 		return;
 	}
 
 	if (NM_IS_DEVICE_ETHERNET (dev)) {
 		if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) {
-			nm_info ("%s: Driver '%s' does not support carrier detection.\n"
+			nm_info ("%s: driver '%s' does not support carrier detection.\n"
 					"\tYou must switch to it manually.",
 					nm_device_get_iface (dev), driver);
 			full_support = FALSE;
@@ -130,7 +130,7 @@
 	}
 
 	if (full_support) {
-		nm_info ("%s: Device is fully-supported using driver '%s'.",
+		nm_info ("%s: driver is '%s'.",
 				nm_device_get_iface (dev), driver);
 	}
 }

Modified: branches/mbca/src/backends/Makefile.am
==============================================================================
--- branches/mbca/src/backends/Makefile.am	(original)
+++ branches/mbca/src/backends/Makefile.am	Mon Aug 18 08:30:28 2008
@@ -7,54 +7,46 @@
 
 noinst_LTLIBRARIES = libnmbackend.la
 
-libnmbackend_la_SOURCES =	NetworkManagerGeneric.c	\
+libnmbackend_la_SOURCES = NetworkManagerGeneric.c	\
 				NetworkManagerGeneric.h
 
 libnmbackend_la_LIBADD =
 
 if TARGET_REDHAT
-libnmbackend_la_SOURCES +=	NetworkManagerRedHat.c	\
-						shvar.c				\
-						shvar.h
+libnmbackend_la_SOURCES += NetworkManagerRedHat.c
 endif
 
 if TARGET_SUSE
-libnmbackend_la_SOURCES +=	NetworkManagerSuSE.c				\
-						shvar.c				\
-						shvar.h
+libnmbackend_la_SOURCES += NetworkManagerSuSE.c
 endif
 
 if TARGET_GENTOO
-libnmbackend_la_SOURCES +=	NetworkManagerGentoo.c		\
-						shvar.c				\
-						shvar.h
+libnmbackend_la_SOURCES += NetworkManagerGentoo.c
 endif
 
 if TARGET_DEBIAN
-libnmbackend_la_SOURCES +=	NetworkManagerDebian.c
+libnmbackend_la_SOURCES += NetworkManagerDebian.c
 endif
 
 if TARGET_SLACKWARE
-libnmbackend_la_SOURCES +=	NetworkManagerSlackware.c
+libnmbackend_la_SOURCES += NetworkManagerSlackware.c
 endif
 
 if TARGET_ARCH
-libnmbackend_la_SOURCES +=	NetworkManagerArch.c
+libnmbackend_la_SOURCES += NetworkManagerArch.c
 endif
 
 if TARGET_PALDO
-libnmbackend_la_SOURCES +=	NetworkManagerPaldo.c
+libnmbackend_la_SOURCES += NetworkManagerPaldo.c
 endif
 
 if TARGET_FRUGALWARE
-libnmbackend_la_SOURCES +=	NetworkManagerFrugalware.c
+libnmbackend_la_SOURCES += NetworkManagerFrugalware.c
 libnmbackend_la_LIBADD += -lfwnetconfig -lfwutil
 endif
 
 if TARGET_MANDRIVA
-libnmbackend_la_SOURCES +=      NetworkManagerMandriva.c  \
-				shvar.c                         \
-				shvar.h
+libnmbackend_la_SOURCES += NetworkManagerMandriva.c
 endif
 
 libnmbackend_la_LIBADD += $(DBUS_LIBS) $(GTHREAD_LIBS)

Modified: branches/mbca/src/backends/NetworkManagerArch.c
==============================================================================
--- branches/mbca/src/backends/NetworkManagerArch.c	(original)
+++ branches/mbca/src/backends/NetworkManagerArch.c	Mon Aug 18 08:30:28 2008
@@ -36,31 +36,12 @@
 #endif
 
 #include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <arpa/inet.h>
-#include <glib/gprintf.h>
-#include <glib/gfileutils.h>
 #include <string.h>
 #include <stdlib.h>
 
 #include "NetworkManagerGeneric.h"
 #include "NetworkManagerSystem.h"
 #include "NetworkManagerUtils.h"
-#include "nm-device.h"
-#include "nm-utils.h"
-
-/*
- * nm_system_init
- *
- * Initializes the distribution-specific system backend
- *
- */
-void nm_system_init (void)
-{
-	nm_generic_init ();
-}
 
 /*
  * nm_system_enable_loopback
@@ -70,22 +51,10 @@
  */
 void nm_system_enable_loopback (void)
 {
-	nm_system_device_set_up_down_with_iface ("lo", TRUE);
+	nm_generic_enable_loopback ();
 }
 
 /*
- * nm_system_kill_all_dhcp_daemons
- *
- * Kill all DHCP daemons currently running, done at startup.
- *
- */
-void nm_system_kill_all_dhcp_daemons (void)
-{
-	nm_spawn_process ("/usr/bin/killall -q dhclient");
-}
-
-
-/*
  * nm_system_update_dns
  *
  * Make glibc/nscd aware of any changes to the resolv.conf file by
@@ -96,48 +65,6 @@
 {
 	/* Check if the daemon was already running - do not start a new instance */
 	if (g_file_test("/var/run/daemons/nscd", G_FILE_TEST_EXISTS))
-	{
 		nm_spawn_process ("/etc/rc.d/nscd restart");
-	}
-}
-
-/*
- * nm_system_activate_nis
- *
- * set up the nis domain and write a yp.conf
- *
- */
-void nm_system_activate_nis (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_should_modify_resolv_conf
- *
- * Can NM update resolv.conf, or is it locked down?
- */
-gboolean nm_system_should_modify_resolv_conf (void)
-{
-	return TRUE;
-}
-
-/*
- * nm_system_shutdown_nis
- *
- * shutdown ypbind
- *
- */
-void nm_system_shutdown_nis (void)
-{
-}
-
-/*
- * nm_system_set_hostname
- *
- * set the hostname
- *
- */
-void nm_system_set_hostname (NMIP4Config *config)
-{
 }
 

Modified: branches/mbca/src/backends/NetworkManagerDebian.c
==============================================================================
--- branches/mbca/src/backends/NetworkManagerDebian.c	(original)
+++ branches/mbca/src/backends/NetworkManagerDebian.c	Mon Aug 18 08:30:28 2008
@@ -28,28 +28,12 @@
 #endif
 
 #include <stdio.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <arpa/inet.h>
 #include <string.h>
 #include <stdlib.h>
 
 #include "NetworkManagerGeneric.h"
 #include "NetworkManagerSystem.h"
 #include "NetworkManagerUtils.h"
-#include "nm-device.h"
-#include "nm-utils.h"
-
-/*
- * nm_system_init
- *
- * Initializes the distribution-specific system backend
- *
- */
-void nm_system_init (void)
-{
-	nm_generic_init ();
-}
 
 /*
  * nm_system_enable_loopback
@@ -63,18 +47,6 @@
 }
 
 /*
- * nm_system_kill_all_dhcp_daemons
- *
- * Kill all DHCP daemons currently running, done at startup.
- *
- */
-void nm_system_kill_all_dhcp_daemons (void)
-{
-	nm_spawn_process ("/usr/bin/killall -q dhclient");
-}
-
-
-/*
  * nm_system_update_dns
  *
  * Make glibc/nscd aware of any changes to the resolv.conf file by
@@ -84,46 +56,5 @@
 void nm_system_update_dns (void)
 {
 	nm_spawn_process ("/usr/sbin/invoke-rc.d nscd restart");
-
-}
-
-/*
- * nm_system_activate_nis
- *
- * set up the nis domain and write a yp.conf
- *
- */
-void nm_system_activate_nis (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_shutdown_nis
- *
- * shutdown ypbind
- *
- */
-void nm_system_shutdown_nis (void)
-{
-}
-
-/*
- * nm_system_set_hostname
- *
- * set the hostname
- *
- */
-void nm_system_set_hostname (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_should_modify_resolv_conf
- *
- * Can NM update resolv.conf, or is it locked down?
- */
-gboolean nm_system_should_modify_resolv_conf (void)
-{
-	return TRUE;
 }
 

Modified: branches/mbca/src/backends/NetworkManagerFrugalware.c
==============================================================================
--- branches/mbca/src/backends/NetworkManagerFrugalware.c	(original)
+++ branches/mbca/src/backends/NetworkManagerFrugalware.c	Mon Aug 18 08:30:28 2008
@@ -24,29 +24,13 @@
  */
 
 #include <stdio.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <arpa/inet.h>
 #include <string.h>
 #include <stdlib.h>
 
 #include "NetworkManagerSystem.h"
-#include "NetworkManagerUtils.h"
-#include "nm-device.h"
-#include "nm-utils.h"
 
-// Provided by the frugalwareutils package on Frugalware
-#include <libfwnetconfig.h>
-
-/*
- * nm_system_init
- *
- * Initializes the distribution-specific system backend
- *
- */
-void nm_system_init (void)
-{
-}
+/* Provided by the frugalwareutils package on Frugalware */
+#include <libfwnetconfig.h> 
 
 /*
  * nm_system_enable_loopback
@@ -61,18 +45,6 @@
 
 
 /*
- * nm_system_kill_all_dhcp_daemons
- *
- * Kill all DHCP daemons currently running, done at startup.
- *
- */
-void nm_system_kill_all_dhcp_daemons (void)
-{
-	nm_spawn_process ("/usr/bin/killall -q dhclient");
-}
-
-
-/*
  * nm_system_update_dns
  *
  * Make glibc/nscd aware of any changes to the resolv.conf file by
@@ -84,43 +56,3 @@
 	/* I'm not running nscd */
 }
 
-/*
- * nm_system_activate_nis
- *
- * set up the nis domain and write a yp.conf
- *
- */
-void nm_system_activate_nis (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_shutdown_nis
- *
- * shutdown ypbind
- *
- */
-void nm_system_shutdown_nis (void)
-{
-}
-
-/*
- * nm_system_set_hostname
- *
- * set the hostname
- *
- */
-void nm_system_set_hostname (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_should_modify_resolv_conf
- *
- * Can NM update resolv.conf, or is it locked down?
- */
-gboolean nm_system_should_modify_resolv_conf (void)
-{
-	return TRUE;
-}
-

Modified: branches/mbca/src/backends/NetworkManagerGeneric.c
==============================================================================
--- branches/mbca/src/backends/NetworkManagerGeneric.c	(original)
+++ branches/mbca/src/backends/NetworkManagerGeneric.c	Mon Aug 18 08:30:28 2008
@@ -34,9 +34,8 @@
 #include "NetworkManagerGeneric.h"
 #include "NetworkManagerSystem.h"
 #include "NetworkManagerUtils.h"
-#include "nm-device.h"
-#include "nm-utils.h"
 #include "nm-netlink.h"
+#include "nm-utils.h"
 
 /* Because of a bug in libnl, rtnl.h should be included before route.h */
 #include <netlink/route/rtnl.h>
@@ -45,18 +44,6 @@
 #include <netlink/netlink.h>
 
 /*
- * nm_generic_init
- *
- * Initializes the distribution-specific system backend
- *
- */
-void nm_generic_init (void)
-{
-	/* Kill any dhclients lying around */
-	nm_system_kill_all_dhcp_daemons ();
-}
-
-/*
  * nm_generic_enable_loopback
  *
  * Bring up the loopback interface
@@ -112,17 +99,6 @@
 }
 
 /*
- * nm_generic_kill_all_dhcp_daemons
- *
- * Kill all DHCP daemons currently running, done at startup.
- *
- */
-void nm_generic_kill_all_dhcp_daemons (void)
-{
-}
-
-
-/*
  * nm_generic_update_dns
  *
  * Make glibc/nscd aware of any changes to the resolv.conf file by
@@ -133,162 +109,3 @@
 {
 }
 
-/*
- * nm_generic_set_ip4_config_from_resolv_conf
- *
- * Add nameservers and search names from a resolv.conf format file.
- *
- */
-void nm_generic_set_ip4_config_from_resolv_conf (const char *filename, NMIP4Config *ip4_config)
-{
-	char *	contents = NULL;
-	char **	split_contents = NULL;
-	int		i, len;
-
-	g_return_if_fail (filename != NULL);
-	g_return_if_fail (ip4_config != NULL);
-
-	if (!g_file_get_contents (filename, &contents, NULL, NULL) || (contents == NULL))
-		return;
-
-	if (!(split_contents = g_strsplit (contents, "\n", 0)))
-		goto out;
-	
-	len = g_strv_length (split_contents);
-	for (i = 0; i < len; i++)
-	{
-		char *line = split_contents[i];
-
-		/* Ignore comments */
-		if (!line || (line[0] == ';') || (line[0] == '#'))
-			continue;
-
-		line = g_strstrip (line);
-		if ((strncmp (line, "search", 6) == 0) && (strlen (line) > 6))
-		{
-			char *searches = g_strdup (line + 7);
-			char **split_searches = NULL;
-
-			if (!searches || !strlen (searches))
-				continue;
-
-			/* Allow space-separated search domains */
-			if ((split_searches = g_strsplit (searches, " ", 0)))
-			{
-				int m, srch_len;
-
-				srch_len = g_strv_length (split_searches);
-				for (m = 0; m < srch_len; m++)
-				{
-					if (split_searches[m])
-						nm_ip4_config_add_domain	(ip4_config, split_searches[m]);
-				}
-				g_strfreev (split_searches);
-			}
-			else
-			{
-				/* Only 1 item, add the whole line */
-				nm_ip4_config_add_domain	(ip4_config, searches);
-			}
-
-			g_free (searches);
-		}
-		else if ((strncmp (line, "nameserver", 10) == 0) && (strlen (line) > 10))
-		{
-			guint32	addr = (guint32) (inet_addr (line + 11));
-
-			if (addr != (guint32) -1)
-				nm_ip4_config_add_nameserver (ip4_config, addr);
-		}
-	}
-
-	g_strfreev (split_contents);
-
-out:
-	g_free (contents);
-}
-
-
-/*
- * nm_generic_device_get_system_config
- *
- * Retrieve any relevant configuration info for a particular device
- * from the system network configuration information.  Clear out existing
- * info before setting stuff too.
- *
- */
-void* nm_generic_device_get_system_config (NMDevice *dev)
-{
-	return NULL;
-}
-
-/*
- * nm_generic_device_free_system_config
- *
- * Free stored system config data
- *
- */
-void nm_generic_device_free_system_config (NMDevice *dev, void *system_config_data)
-{
-	return;
-}
-
-
-/*
- * nm_generic_device_get_disabled
- *
- * Return whether the distro-specific system config tells us to use
- * dhcp for this device.
- *
- */
-gboolean nm_generic_device_get_disabled (NMDevice *dev)
-{
-	return FALSE;
-}
-
-
-NMIP4Config *nm_generic_device_new_ip4_system_config (NMDevice *dev)
-{
-	return NULL;
-}
-
-/*
- * nm_generic_activate_nis
- *
- * set up the nis domain and write a yp.conf
- *
- */
-void nm_generic_activate_nis (NMIP4Config *config)
-{
-}
-
-/*
- * nm_generic_shutdown_nis
- *
- * shutdown ypbind
- *
- */
-void nm_generic_shutdown_nis (void)
-{
-}
-
-/*
- * nm_generic_set_hostname
- *
- * set the hostname
- *
- */
-void nm_generic_set_hostname (NMIP4Config *config)
-{
-}
-
-/*
- * nm_generic_should_modify_resolv_conf
- *
- * Can NM update resolv.conf, or is it locked down?
- */
-gboolean nm_generic_should_modify_resolv_conf (void)
-{
-	return TRUE;
-}
-

Modified: branches/mbca/src/backends/NetworkManagerGeneric.h
==============================================================================
--- branches/mbca/src/backends/NetworkManagerGeneric.h	(original)
+++ branches/mbca/src/backends/NetworkManagerGeneric.h	Mon Aug 18 08:30:28 2008
@@ -24,39 +24,7 @@
 #ifndef NETWORK_MANAGER_GENERIC_H
 #define NETWORK_MANAGER_GENERIC_H
 
-#include <glib.h>
-#include "nm-device.h"
-#include "nm-ip4-config.h"
-#include "nm-named-manager.h"
-
-/* Prototypes for system/distribution dependent functions,
- * implemented in the backend files in backends/ directory
- */
-
-void			nm_generic_init (void);
-
-void			nm_generic_enable_loopback				(void);
-void			nm_generic_kill_all_dhcp_daemons			(void);
-void			nm_generic_update_dns					(void);
-
-void			nm_generic_set_ip4_config_from_resolv_conf (const char *filename, NMIP4Config *ip4_config);
-void *		nm_generic_device_get_system_config			(NMDevice *dev);
-void			nm_generic_device_free_system_config		(NMDevice *dev, void *system_config_data);
-NMIP4Config *	nm_generic_device_new_ip4_system_config		(NMDevice *dev);
-
-gboolean		nm_generic_device_get_disabled				(NMDevice *dev);
-
-gboolean		nm_generic_device_set_from_ip4_config		(NMDevice *dev);
-gboolean		nm_generic_vpn_device_set_from_ip4_config	(NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config, char **routes, int num_routes);
-gboolean		nm_generic_vpn_device_unset_from_ip4_config	(NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config);
-
-gboolean		nm_generic_device_set_up_down				(NMDevice *dev, gboolean up);
-gboolean		nm_generic_device_set_up_down_with_iface		(NMDevice *dev, const char *iface, gboolean up);
-
-void			nm_generic_set_hostname (NMIP4Config *config);
-void			nm_generic_activate_nis (NMIP4Config *config);
-void			nm_generic_shutdown_nis (void);
-
-gboolean		nm_generic_should_modify_resolv_conf (void);
+void nm_generic_enable_loopback	(void);
+void nm_generic_update_dns		(void);
 
 #endif

Modified: branches/mbca/src/backends/NetworkManagerGentoo.c
==============================================================================
--- branches/mbca/src/backends/NetworkManagerGentoo.c	(original)
+++ branches/mbca/src/backends/NetworkManagerGentoo.c	Mon Aug 18 08:30:28 2008
@@ -28,29 +28,12 @@
 #endif
 
 #include <stdio.h>
-#include <sys/types.h>
-#include <signal.h>
 #include <string.h>
 #include <stdlib.h>
-#include <arpa/inet.h>
 
 #include "NetworkManagerGeneric.h"
 #include "NetworkManagerSystem.h"
 #include "NetworkManagerUtils.h"
-#include "nm-device.h"
-#include "nm-utils.h"
-#include "shvar.h"
-
-/*
- * nm_system_init
- *
- * Initializes the distribution-specific system backend
- *
- */
-void nm_system_init (void)
-{
-	nm_generic_init ();
-}
 
 /*
  * nm_system_enable_loopback
@@ -66,18 +49,6 @@
 }
 
 /*
- * nm_system_kill_all_dhcp_daemons
- *
- * Kill all DHCP daemons currently running, done at startup
- *
- */
-void nm_system_kill_all_dhcp_daemons (void)
-{
-        /* TODO */
-        /* Tell dhcdbd to kill its dhclient instance */
-}
-
-/*
  * nm_system_update_dns
  *
  * Make glibc/nscd aware of any changes to the resolv.conf file by
@@ -94,44 +65,3 @@
  #endif
 }
 
-/*
- * nm_system_activate_nis
- *
- * set up the nis domain and write a yp.conf
- *
- */
-void nm_system_activate_nis (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_shutdown_nis
- *
- * shutdown ypbind
- *
- */
-void nm_system_shutdown_nis (void)
-{
-}
-
-/*
- * nm_system_set_hostname
- *
- * set the hostname
- *
- */
-void nm_system_set_hostname (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_should_modify_resolv_conf
- *
- * Can NM update resolv.conf, or is it locked down?
- */
-gboolean nm_system_should_modify_resolv_conf (void)
-{
-	return TRUE;
-}
-
-

Modified: branches/mbca/src/backends/NetworkManagerMandriva.c
==============================================================================
--- branches/mbca/src/backends/NetworkManagerMandriva.c	(original)
+++ branches/mbca/src/backends/NetworkManagerMandriva.c	Mon Aug 18 08:30:28 2008
@@ -26,30 +26,12 @@
 #endif
 
 #include <stdio.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <arpa/inet.h>
 #include <string.h>
 #include <stdlib.h>
 
 #include "NetworkManagerGeneric.h"
 #include "NetworkManagerSystem.h"
 #include "NetworkManagerUtils.h"
-#include "nm-device.h"
-#include "nm-utils.h"
-#include "shvar.h"
-
-/*
- * nm_system_init
- *
- * Initializes the distribution-specific system backend
- *
- */
-void nm_system_init (void)
-{
-	nm_generic_init ();
-}
-
 
 /*
  * nm_system_enable_loopback
@@ -63,17 +45,6 @@
 }
 
 /*
- * nm_system_kill_all_dhcp_daemons
- *
- * Kill all DHCP daemons currently running, done at startup.
- *
- */
-void nm_system_kill_all_dhcp_daemons (void)
-{
-}
-
-
-/*
  * nm_system_update_dns
  *
  * Invalidate the nscd host cache, if it exists, since
@@ -88,44 +59,3 @@
 	}
 }
 
-/*
- * nm_system_activate_nis
- *
- * set up the nis domain and write a yp.conf
- *
- */
-void nm_system_activate_nis (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_shutdown_nis
- *
- * shutdown ypbind
- *
- */
-void nm_system_shutdown_nis (void)
-{
-}
-
-/*
- * nm_system_set_hostname
- *
- * set the hostname
- *
- */
-void nm_system_set_hostname (NMIP4Config *config)
-{
-}
-
-
-/*
- * nm_system_should_modify_resolv_conf
- *
- * Can NM update resolv.conf, or is it locked down?
- */
-gboolean nm_system_should_modify_resolv_conf (void)
-{
-	return TRUE;
-}
-

Modified: branches/mbca/src/backends/NetworkManagerPaldo.c
==============================================================================
--- branches/mbca/src/backends/NetworkManagerPaldo.c	(original)
+++ branches/mbca/src/backends/NetworkManagerPaldo.c	Mon Aug 18 08:30:28 2008
@@ -27,31 +27,15 @@
 #endif
 
 #include <stdio.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <arpa/inet.h>
-#include <glib/gkeyfile.h>
 #include <string.h>
 #include <stdlib.h>
 
 #include "NetworkManagerGeneric.h"
 #include "NetworkManagerSystem.h"
 #include "NetworkManagerUtils.h"
-#include "nm-device.h"
 #include "nm-utils.h"
 
 /*
- * nm_system_init
- *
- * Initializes the distribution-specific system backend
- *
- */
-void nm_system_init (void)
-{
-	nm_generic_init ();
-}
-
-/*
  * nm_system_enable_loopback
  *
  * Bring up the loopback interface
@@ -63,17 +47,6 @@
 }
 
 /*
- * nm_system_kill_all_dhcp_daemons
- *
- * Kill all DHCP daemons currently running, done at startup.
- *
- */
-void nm_system_kill_all_dhcp_daemons (void)
-{
-}
-
-
-/*
  * nm_system_update_dns
  *
  * Invalidate the nscd host cache, if it exists, since
@@ -86,44 +59,3 @@
 	nm_spawn_process ("/usr/sbin/nscd -i hosts");
 }
 
-/*
- * nm_system_activate_nis
- *
- * set up the nis domain and write a yp.conf
- *
- */
-void nm_system_activate_nis (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_shutdown_nis
- *
- * shutdown ypbind
- *
- */
-void nm_system_shutdown_nis (void)
-{
-}
-
-/*
- * nm_system_set_hostname
- *
- * set the hostname
- *
- */
-void nm_system_set_hostname (NMIP4Config *config)
-{
-}
-
-
-/*
- * nm_system_should_modify_resolv_conf
- *
- * Can NM update resolv.conf, or is it locked down?
- */
-gboolean nm_system_should_modify_resolv_conf (void)
-{
-	return TRUE;
-}
-

Modified: branches/mbca/src/backends/NetworkManagerRedHat.c
==============================================================================
--- branches/mbca/src/backends/NetworkManagerRedHat.c	(original)
+++ branches/mbca/src/backends/NetworkManagerRedHat.c	Mon Aug 18 08:30:28 2008
@@ -24,29 +24,12 @@
 #endif
 
 #include <stdio.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <arpa/inet.h>
 #include <string.h>
 #include <stdlib.h>
 
 #include "NetworkManagerGeneric.h"
 #include "NetworkManagerSystem.h"
 #include "NetworkManagerUtils.h"
-#include "nm-device.h"
-#include "nm-utils.h"
-#include "shvar.h"
-
-/*
- * nm_system_init
- *
- * Initializes the distribution-specific system backend
- *
- */
-void nm_system_init (void)
-{
-	nm_generic_init ();
-}
 
 /*
  * nm_system_enable_loopback
@@ -60,17 +43,6 @@
 }
 
 /*
- * nm_system_kill_all_dhcp_daemons
- *
- * Kill all DHCP daemons currently running, done at startup.
- *
- */
-void nm_system_kill_all_dhcp_daemons (void)
-{
-}
-
-
-/*
  * nm_system_update_dns
  *
  * Invalidate the nscd host cache, if it exists, since
@@ -85,44 +57,3 @@
 	}
 }
 
-/*
- * nm_system_activate_nis
- *
- * set up the nis domain and write a yp.conf
- *
- */
-void nm_system_activate_nis (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_shutdown_nis
- *
- * shutdown ypbind
- *
- */
-void nm_system_shutdown_nis (void)
-{
-}
-
-/*
- * nm_system_set_hostname
- *
- * set the hostname
- *
- */
-void nm_system_set_hostname (NMIP4Config *config)
-{
-}
-
-
-/*
- * nm_system_should_modify_resolv_conf
- *
- * Can NM update resolv.conf, or is it locked down?
- */
-gboolean nm_system_should_modify_resolv_conf (void)
-{
-	return TRUE;
-}
-

Modified: branches/mbca/src/backends/NetworkManagerSlackware.c
==============================================================================
--- branches/mbca/src/backends/NetworkManagerSlackware.c	(original)
+++ branches/mbca/src/backends/NetworkManagerSlackware.c	Mon Aug 18 08:30:28 2008
@@ -25,31 +25,11 @@
 #endif
 
 #include <stdio.h>
-#include <sys/types.h>
-#include <signal.h>
 #include <string.h>
 #include <stdlib.h>
 
 #include "NetworkManagerGeneric.h"
 #include "NetworkManagerSystem.h"
-#include "NetworkManagerUtils.h"
-#include "nm-device.h"
-#include "nm-utils.h"
-
-/*
- * Mostly a mix of the Gentoo and RedHat Backends
- */
-
-/*
- * nm_system_init
- *
- * Initializes the distribution-specific system backend
- *
- */
-void nm_system_init (void)
-{
-	nm_generic_init ();
-}
 
 /*
  * nm_system_enable_loopback
@@ -64,18 +44,6 @@
 
 
 /*
- * nm_system_kill_all_dhcp_daemons
- *
- * Kill all DHCP daemons currently running, done at startup.
- *
- */
-void nm_system_kill_all_dhcp_daemons (void)
-{
-	nm_spawn_process ("/bin/killall -q dhcpcd");
-}
-
-
-/*
  * nm_system_update_dns
  *
  * Make glibc/nscd aware of any changes to the resolv.conf file by
@@ -87,43 +55,3 @@
 	/* I'm not running nscd */
 }
 
-/*
- * nm_system_activate_nis
- *
- * set up the nis domain and write a yp.conf
- *
- */
-void nm_system_activate_nis (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_shutdown_nis
- *
- * shutdown ypbind
- *
- */
-void nm_system_shutdown_nis (void)
-{
-}
-
-/*
- * nm_system_set_hostname
- *
- * set the hostname
- *
- */
-void nm_system_set_hostname (NMIP4Config *config)
-{
-}
-
-/*
- * nm_system_should_modify_resolv_conf
- *
- * Can NM update resolv.conf, or is it locked down?
- */
-gboolean nm_system_should_modify_resolv_conf (void)
-{
-	return TRUE;
-}
-

Modified: branches/mbca/src/backends/NetworkManagerSuSE.c
==============================================================================
--- branches/mbca/src/backends/NetworkManagerSuSE.c	(original)
+++ branches/mbca/src/backends/NetworkManagerSuSE.c	Mon Aug 18 08:30:28 2008
@@ -28,34 +28,13 @@
 #endif
 
 #include <stdio.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <arpa/inet.h>
 #include <string.h>
 #include <stdlib.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <errno.h>
 
 #include "NetworkManagerGeneric.h"
 #include "NetworkManagerSystem.h"
 #include "NetworkManagerUtils.h"
-#include "nm-device.h"
-#include "NetworkManagerPolicy.h"
 #include "nm-utils.h"
-#include "shvar.h"
-
-/*
- * nm_system_init
- *
- * Initializes the distribution-specific system backend
- *
- */
-void nm_system_init (void)
-{
-	nm_generic_init ();
-}
 
 /*
  * nm_system_enable_loopback
@@ -69,17 +48,6 @@
 }
 
 /*
- * nm_system_kill_all_dhcp_daemons
- *
- * Kill all DHCP daemons currently running, done at startup.
- *
- */
-void nm_system_kill_all_dhcp_daemons (void)
-{
-}
-
-
-/*
  * nm_system_update_dns
  *
  * Invalidate the nscd host cache, if it exists, since
@@ -92,192 +60,3 @@
 	nm_spawn_process ("/usr/sbin/nscd -i hosts");
 }
 
-/*
- * nm_system_activate_nis
- *
- * set up the nis domain and write a yp.conf
- *
- */
-void nm_system_activate_nis (NMIP4Config *config)
-{
-	shvarFile *file;
-	const char *nis_domain;
-	char *name, *buf;
-	struct in_addr temp_addr;
-	int i;
-	FILE *ypconf = NULL;
-	char addr_buf[INET_ADDRSTRLEN+1];
-
-	memset (&addr_buf, '\0', sizeof (addr_buf));
-
-	g_return_if_fail (config != NULL);
-
-	nis_domain = nm_ip4_config_get_nis_domain(config);
-
-	name = g_strdup_printf (SYSCONFDIR"/sysconfig/network/dhcp");
-	file = svNewFile (name);
-	if (!file)
-		goto out_gfree;
-
-	buf = svGetValue (file, "DHCLIENT_SET_DOMAINNAME");
-	if (!buf)
-		goto out_close;
-
-	if ((!strcmp (buf, "yes")) && nis_domain && (setdomainname (nis_domain, strlen (nis_domain)) < 0))
-			nm_warning ("Could not set nis domain name.");
-	free (buf);
-
-	buf = svGetValue (file, "DHCLIENT_MODIFY_NIS_CONF");
-	if (!buf)
-		goto out_close;
-
-	if (!strcmp (buf, "yes")) {
-		int num_nis_servers;
-
-		num_nis_servers = nm_ip4_config_get_num_nis_servers(config);
-		if (num_nis_servers > 0)
-		{
-			struct stat sb;
-
-			/* write out yp.conf and restart the daemon */
-
-			ypconf = fopen ("/etc/yp.conf", "w");
-
-			if (ypconf)
-			{
-				fprintf (ypconf, "# generated by NetworkManager, do not edit!\n\n");
-				for (i = 0; i < num_nis_servers; i++) {
-					temp_addr.s_addr = nm_ip4_config_get_nis_server (config, i);
-
-					if (!inet_ntop (AF_INET, &temp_addr, addr_buf, INET_ADDRSTRLEN))
-						nm_warning ("%s: error converting IP4 address 0x%X",
-						            __func__, ntohl (temp_addr.s_addr));
-					else
-						fprintf (ypconf, "domain %s server %s\n", nis_domain, addr_buf);
-				}
-				fprintf (ypconf, "\n");
-				fclose (ypconf);
-			} else
-				nm_warning ("Could not commit NIS changes to /etc/yp.conf.");
-
-			if (stat ("/usr/sbin/rcautofs", &sb) != -1)
-			{
-				nm_info ("Restarting autofs.");
-				nm_spawn_process ("/usr/sbin/rcautofs reload");
-			}
-		}
-	}
-	free (buf);
-
-out_close:
-	svCloseFile (file);
-out_gfree:
-	g_free (name);
-}
-
-
-/*
- * nm_system_shutdown_nis
- *
- * shutdown ypbind
- *
- */
-void nm_system_shutdown_nis (void)
-{
-}
-
-
-/*
- * nm_system_set_hostname
- *
- * set the hostname
- *
- */
-void nm_system_set_hostname (NMIP4Config *config)
-{
-	char *filename, *h_name = NULL, *buf;
-	shvarFile *file;
-
-	g_return_if_fail (config != NULL);
-
-	filename = g_strdup_printf (SYSCONFDIR"/sysconfig/network/dhcp");
-	file = svNewFile (filename);
-	if (!file)
-		goto out_gfree;
-
-	buf = svGetValue (file, "DHCLIENT_SET_HOSTNAME");
-	if (!buf)
-		goto out_close;
-
-	if (!strcmp (buf, "yes")) 
-	{
-		const char *hostname;
-
-		hostname = nm_ip4_config_get_hostname (config);
-		if (!hostname)
-		{
-			struct in_addr temp_addr;
-			struct hostent *host;
-			const NMSettingIP4Address *ip_address;
-
-			/* try to get hostname via dns */
-			ip_address = nm_ip4_config_get_address (config, 0);
-			temp_addr.s_addr = ip_address->address;
-			host = gethostbyaddr ((char *) &temp_addr, sizeof (temp_addr), AF_INET);
-			if (host)
-			{
-				h_name = g_strdup (host->h_name);
-				hostname = strtok (h_name, ".");
-			}
-			else
-				nm_warning ("nm_system_set_hostname(): gethostbyaddr failed, h_errno = %d", h_errno);
-		}
-
-		if (hostname)
-		{
-			nm_info ("Setting hostname to '%s'", hostname);
-			if (sethostname (hostname, strlen (hostname)) < 0)
-				nm_warning ("Could not set hostname.");
-		}
-	}
-
-	g_free (h_name);
-	free (buf);
-out_close:
-	svCloseFile (file);
-out_gfree:
-	g_free (filename);
-}
-
-/*
- * nm_system_should_modify_resolv_conf
- *
- * Can NM update resolv.conf, or is it locked down?
- */
-gboolean nm_system_should_modify_resolv_conf (void)
-{
-	char *name, *buf;
-	shvarFile *file;
-	gboolean ret = TRUE;
-
-	name = g_strdup_printf (SYSCONFDIR"/sysconfig/network/dhcp");
-	file = svNewFile (name);
-	if (!file)
-		goto out_gfree;
-
-	buf = svGetValue (file, "DHCLIENT_MODIFY_RESOLV_CONF");
-	if (!buf)
-		goto out_close;
-
-	if (strcmp (buf, "no") == 0)
-		ret = FALSE;
-
-	free (buf);
-out_close:
-	svCloseFile (file);
-out_gfree:
-	g_free (name);
-
-	return ret;
-}
-

Modified: branches/mbca/src/dhcp-manager/nm-dhcp-manager.c
==============================================================================
--- branches/mbca/src/dhcp-manager/nm-dhcp-manager.c	(original)
+++ branches/mbca/src/dhcp-manager/nm-dhcp-manager.c	Mon Aug 18 08:30:28 2008
@@ -747,9 +747,20 @@
 	}
 
 	str = g_hash_table_lookup (device->options, "new_routers");
-	if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) {
-		addr->gateway = tmp_addr.s_addr;
-		nm_info("  gateway %s", str);
+	if (str) {
+		char **routers = g_strsplit (str, " ", 0);
+		char **s;
+
+		for (s = routers; *s; s++) {
+			/* FIXME: how to handle multiple routers? */
+			if (inet_pton (AF_INET, *s, &tmp_addr) > 0) {
+				addr->gateway = tmp_addr.s_addr;
+				nm_info ("  gateway %s", *s);
+				break;
+			} else
+				nm_warning ("Ignoring invalid gateway '%s'", *s);
+		}
+		g_strfreev (routers);
 	}
 
 	nm_ip4_config_take_address (ip4_config, addr);
@@ -800,27 +811,6 @@
 		g_strfreev (searches);
 	}
 
-	str = g_hash_table_lookup (device->options, "new_nis_domain");
-	if (str) {
-		nm_ip4_config_set_nis_domain (ip4_config, str);
-		nm_info ("  nis domain '%s'", str);
-	}
-
-	str = g_hash_table_lookup (device->options, "new_nis_servers");
-	if (str) {
-		char **searches = g_strsplit (str, " ", 0);
-		char **s;
-
-		for (s = searches; *s; s++) {
-			if (inet_pton (AF_INET, *s, &tmp_addr) > 0) {
-				nm_ip4_config_add_nis_server (ip4_config, tmp_addr.s_addr);
-				nm_info ("  nis server '%s'", *s);
-			} else
-				nm_warning ("Ignoring invalid nis server '%s'", *s);
-		}
-		g_strfreev (searches);
-	}
-
 	str = g_hash_table_lookup (device->options, "new_static_routes");
 	if (str) {
 		char **searches = g_strsplit (str, " ", 0);
@@ -894,7 +884,7 @@
 	char *tmp_key = NULL;
 	const char **p;
 	static const char *filter_options[] = {
-		"interface", "pid", "reason", NULL
+		"interface", "pid", "reason", "dhcp_message_type", NULL
 	};
 	
 	/* Filter out stuff that's not actually new DHCP options */

Modified: branches/mbca/src/dnsmasq-manager/nm-dnsmasq-manager.c
==============================================================================
--- branches/mbca/src/dnsmasq-manager/nm-dnsmasq-manager.c	(original)
+++ branches/mbca/src/dnsmasq-manager/nm-dnsmasq-manager.c	Mon Aug 18 08:30:28 2008
@@ -236,6 +236,7 @@
 	const NMSettingIP4Address *tmp;
 	struct in_addr addr;
 	char buf[INET_ADDRSTRLEN + 1];
+	char localaddr[INET_ADDRSTRLEN + 1];
 
 	dm_binary = nm_find_dnsmasq ();
 	if (!dm_binary) {
@@ -259,12 +260,12 @@
 
 	s = g_string_new ("--listen-address=");
 	addr.s_addr = tmp->address;
-	if (!inet_ntop (AF_INET, &addr, &buf[0], INET_ADDRSTRLEN)) {
+	if (!inet_ntop (AF_INET, &addr, &localaddr[0], INET_ADDRSTRLEN)) {
 		nm_warning ("%s: error converting IP4 address 0x%X",
 		            __func__, ntohl (addr.s_addr));
 		goto error;
 	}
-	g_string_append (s, buf);
+	g_string_append (s, localaddr);
 	nm_cmd_line_add_string (cmd, s->str);
 	g_string_free (s, TRUE);
 
@@ -294,7 +295,11 @@
 	nm_cmd_line_add_string (cmd, s->str);
 	g_string_free (s, TRUE);
 
-	nm_cmd_line_add_string (cmd, "--dhcp-option=option:router,0.0.0.0");
+	s = g_string_new ("--dhcp-option=option:router,");
+	g_string_append (s, localaddr);
+	nm_cmd_line_add_string (cmd, s->str);
+	g_string_free (s, TRUE);
+
 	nm_cmd_line_add_string (cmd, "--dhcp-lease-max=50");
 
 	s = g_string_new ("--pid-file=");

Modified: branches/mbca/src/named-manager/nm-named-manager.c
==============================================================================
--- branches/mbca/src/named-manager/nm-named-manager.c	(original)
+++ branches/mbca/src/named-manager/nm-named-manager.c	Mon Aug 18 08:30:28 2008
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
 /*
  *  Copyright (C) 2004 - 2008 Red Hat, Inc.
  *
@@ -26,6 +28,8 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <arpa/inet.h>
+#include <sys/types.h>
+#include <unistd.h>
 #include <glib.h>
 
 #include <glib/gi18n.h>
@@ -85,50 +89,6 @@
 	return quark;
 }
 
-static char *
-compute_nameservers (NMIP4Config *config)
-{
-	int i, num;
-	GString *str = NULL;
-
-	g_return_val_if_fail (config != NULL, NULL);
-
-	num = nm_ip4_config_get_num_nameservers (config);
-	if (num == 0)
-		return NULL;
-
-	str = g_string_new ("");
-	for (i = 0; i < num; i++) {
-		#define ADDR_BUF_LEN 50
-		struct in_addr addr;
-		char *buf;
-
-		addr.s_addr = nm_ip4_config_get_nameserver (config, i);
-		buf = g_malloc0 (ADDR_BUF_LEN);
-		if (!buf)
-			continue;
-
-		if (!inet_ntop (AF_INET, &addr, buf, ADDR_BUF_LEN))
-			nm_warning ("%s: error converting IP4 address 0x%X",
-			            __func__, ntohl (addr.s_addr));
-
-		if (i == 3) {
-			g_string_append (str, "\n# ");
-			g_string_append (str, _("NOTE: the glibc resolver does not support more than 3 nameservers."));
-			g_string_append (str, "\n# ");
-			g_string_append (str, _("The nameservers listed below may not be recognized."));
-			g_string_append_c (str, '\n');
-		}
-
-		g_string_append (str, "nameserver ");
-		g_string_append (str, buf);
-		g_string_append_c (str, '\n');
-		g_free (buf);
-	}
-
-	return g_string_free (str, FALSE);
-}
-
 static void
 merge_one_ip4_config (NMIP4Config *dst, NMIP4Config *src)
 {
@@ -155,49 +115,221 @@
 	}
 }
 
+#if defined(TARGET_SUSE)
+/**********************************/
+/* SUSE */
+
+static void
+netconfig_child_setup (gpointer user_data G_GNUC_UNUSED)
+{
+	pid_t pid = getpid ();
+	setpgid (pid, pid);
+}
+
+static gint
+run_netconfig (GError **error)
+{
+	GPtrArray *argv;
+	gint stdin_fd;
+
+	argv = g_ptr_array_new ();
+	g_ptr_array_add (argv, "/sbin/netconfig");
+	g_ptr_array_add (argv, "modify");
+	g_ptr_array_add (argv, "--service");
+	g_ptr_array_add (argv, "NetworkManager");
+	g_ptr_array_add (argv, NULL);
+
+	if (!g_spawn_async_with_pipes (NULL, (char **) argv->pdata, NULL,
+							 G_SPAWN_DO_NOT_REAP_CHILD,
+							 netconfig_child_setup,
+							 NULL, NULL, &stdin_fd,
+							 NULL, NULL, error)) {
+		stdin_fd = -1;
+	}
+
+	g_ptr_array_free (argv, TRUE);
+
+	return stdin_fd;
+}
+
+static void
+write_to_netconfig (gint fd, const char *key, const char *value)
+{
+	char *str;
+	int x;
+
+	str = g_strdup_printf ("%s='%s'\n", key, value);
+	x = write (fd, str, strlen (str));
+	g_free (str);
+}
+
 static gboolean
-rewrite_resolv_conf (NMNamedManager *mgr, GError **error)
+update_resolv_conf (const char *iface,
+				const char *domain,
+				char **searches,
+				char **nameservers,
+				GError **error)
 {
-	NMNamedManagerPrivate *priv;
-	const char *tmp_resolv_conf = RESOLV_CONF ".tmp";
-	char *searches = NULL, *domain = NULL;
-	char *nameservers = NULL;
-	guint32 num_domains, num_searches, i;
-	NMIP4Config *composite;
-	GSList *iter;
-	FILE *f;
-	GString *str;
+	gint fd;
+	char *str;
 
-	g_return_val_if_fail (error != NULL, FALSE);
-	g_return_val_if_fail (*error == NULL, FALSE);
+	fd = run_netconfig (error);
+	if (fd < 0)
+		return FALSE;
 
-	priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
+	write_to_netconfig (fd, "INTERFACE", iface);
 
-	/* If the sysadmin disabled modifying resolv.conf, exit silently */
-	if (!nm_system_should_modify_resolv_conf ()) {
-		nm_info ("DHCP returned name servers but system has disabled dynamic modification!");
-		return TRUE;
+	if (searches) {
+		str = g_strjoinv (" ", searches);
+		write_to_netconfig (fd, "DNSDOMAIN", str);
+		g_free (str);
 	}
 
+	if (nameservers) {
+		str = g_strjoinv (" ", nameservers);
+		write_to_netconfig (fd, "DNSSERVERS", str);
+		g_free (str);
+	}
+
+	close (fd);
+
+	return TRUE;
+}
+
+#else
+/**********************************/
+/* Generic */
+
+static gboolean
+update_resolv_conf (const char *iface,
+				const char *domain,
+				char **searches,
+				char **nameservers,
+				GError **error)
+{
+	const char *tmp_resolv_conf = RESOLV_CONF ".tmp";
+	char *domain_str = NULL;
+	char *searches_str = NULL;
+	char *nameservers_str = NULL;
+	FILE *f;
+
 	if ((f = fopen (tmp_resolv_conf, "w")) == NULL) {
 		g_set_error (error,
-			     NM_NAMED_MANAGER_ERROR,
-			     NM_NAMED_MANAGER_ERROR_SYSTEM,
-			     "Could not open " RESOLV_CONF ": %s\n",
-			     g_strerror (errno));
+				   NM_NAMED_MANAGER_ERROR,
+				   NM_NAMED_MANAGER_ERROR_SYSTEM,
+				   "Could not open " RESOLV_CONF ": %s\n",
+				   g_strerror (errno));
 		return FALSE;
 	}
 
 	if (fprintf (f, "%s","# generated by NetworkManager, do not edit!\n\n") < 0) {
 		g_set_error (error,
-			     NM_NAMED_MANAGER_ERROR,
-			     NM_NAMED_MANAGER_ERROR_SYSTEM,
-			     "Could not write " RESOLV_CONF ": %s\n",
-			     g_strerror (errno));
+				   NM_NAMED_MANAGER_ERROR,
+				   NM_NAMED_MANAGER_ERROR_SYSTEM,
+				   "Could not write " RESOLV_CONF ": %s\n",
+				   g_strerror (errno));
 		fclose (f);
 		return FALSE;
 	}
 
+	if (domain)
+		domain_str = g_strconcat ("domain ", domain, "\n\n", NULL);
+
+	if (searches) {
+		char *tmp_str;
+
+		tmp_str = g_strjoinv (" ", searches);
+		searches_str = g_strconcat ("search ", tmp_str, "\n\n", NULL);
+		g_free (tmp_str);
+	}
+
+	if (nameservers) {
+		GString *str;
+		int num;
+		int i;
+
+		str = g_string_new ("");
+		num = g_strv_length (nameservers);
+
+		for (i = 0; i < num; i++) {
+			if (i == 3) {
+				g_string_append (str, "\n# ");
+				g_string_append (str, _("NOTE: the glibc resolver does not support more than 3 nameservers."));
+				g_string_append (str, "\n# ");
+				g_string_append (str, _("The nameservers listed below may not be recognized."));
+				g_string_append_c (str, '\n');
+			}
+
+			g_string_append (str, "nameserver ");
+			g_string_append (str, nameservers[i]);
+			g_string_append_c (str, '\n');
+		}
+
+		nameservers_str = g_string_free (str, FALSE);
+	}
+
+	if (fprintf (f, "%s%s%s\n",
+	             domain_str ? domain_str : "",
+	             searches_str ? searches_str : "",
+	             nameservers_str ? nameservers_str : "") < 0) {
+		g_set_error (error,
+				   NM_NAMED_MANAGER_ERROR,
+				   NM_NAMED_MANAGER_ERROR_SYSTEM,
+				   "Could not write to " RESOLV_CONF ": %s\n",
+				   g_strerror (errno));
+	}
+
+	g_free (domain_str);
+	g_free (searches_str);
+	g_free (nameservers_str);
+
+	if (fclose (f) < 0) {
+		if (*error == NULL) {
+			g_set_error (error,
+					   NM_NAMED_MANAGER_ERROR,
+					   NM_NAMED_MANAGER_ERROR_SYSTEM,
+					   "Could not close " RESOLV_CONF ": %s\n",
+					   g_strerror (errno));
+		}
+	}
+
+	if (*error == NULL) {
+		if (rename (tmp_resolv_conf, RESOLV_CONF) < 0) {
+			g_set_error (error,
+					   NM_NAMED_MANAGER_ERROR,
+					   NM_NAMED_MANAGER_ERROR_SYSTEM,
+					   "Could not replace " RESOLV_CONF ": %s\n",
+					   g_strerror (errno));
+		}
+	}
+
+	return *error ? FALSE : TRUE;
+}
+#endif
+
+#define ADDR_BUF_LEN 50
+
+static gboolean
+rewrite_resolv_conf (NMNamedManager *mgr, const char *iface, GError **error)
+{
+	NMNamedManagerPrivate *priv;
+	NMIP4Config *composite;
+	GSList *iter;
+	GPtrArray *array;
+	const char *domain = NULL;
+	char **searches = NULL;
+	char **nameservers = NULL;
+	int num_domains;
+	int num_searches;
+	int num_nameservers;
+	int i;
+	gboolean success;
+
+	g_return_val_if_fail (error != NULL, FALSE);
+	g_return_val_if_fail (*error == NULL, FALSE);
+
+	priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
+
 	/* Construct the composite config from all the currently active IP4Configs */
 	composite = nm_ip4_config_new ();
 
@@ -239,79 +371,65 @@
 	num_domains = nm_ip4_config_get_num_domains (composite);
 	num_searches = nm_ip4_config_get_num_searches (composite);
 
+	/* Domain */
+	if (num_domains > 0)
+		domain = nm_ip4_config_get_domain (composite, 0);
+
+	/* Searches */
 	if ((num_searches == 0)  && (num_domains > 0)) {
-		str = g_string_new ("search");
-		for (i = 0; i < num_domains; i++) {
-			g_string_append_c (str, ' ');
-			g_string_append (str, nm_ip4_config_get_domain (composite, i));		
-		}
+		array = g_ptr_array_sized_new (num_domains + 1);
+		for (i = 0; i < num_domains; i++)
+			g_ptr_array_add (array, g_strdup (nm_ip4_config_get_domain (composite, i)));
 
-		g_string_append (str, "\n\n");
-		searches = g_string_free (str, FALSE);
+		g_ptr_array_add (array, NULL);
+		searches = (char **) g_ptr_array_free (array, FALSE);
 	} else if (num_searches > 0) {
-		str = g_string_new ("search");
-		for (i = 0; i < num_searches; i++) {
-			g_string_append_c (str, ' ');
-			g_string_append (str, nm_ip4_config_get_search (composite, i));		
+		array = g_ptr_array_sized_new (num_searches + 1);
+		for (i = 0; i < num_searches; i++)
+			g_ptr_array_add (array, g_strdup (nm_ip4_config_get_search (composite, i)));
+
+		g_ptr_array_add (array, NULL);
+		searches = (char **) g_ptr_array_free (array, FALSE);
+	}
+
+	/* Name servers */
+	num_nameservers = nm_ip4_config_get_num_nameservers (composite);
+	if (num_nameservers > 0) {
+		array = g_ptr_array_sized_new (num_nameservers + 1);
+		for (i = 0; i < num_nameservers; i++) {
+			struct in_addr addr;
+			char *buf;
+
+			addr.s_addr = nm_ip4_config_get_nameserver (composite, i);
+			buf = g_malloc0 (ADDR_BUF_LEN);
+			if (!buf)
+				continue;
+
+			if (inet_ntop (AF_INET, &addr, buf, ADDR_BUF_LEN))
+				g_ptr_array_add (array, buf);
+			else
+				nm_warning ("%s: error converting IP4 address 0x%X",
+						  __func__, ntohl (addr.s_addr));
 		}
 
-		g_string_append (str, "\n\n");
-		searches = g_string_free (str, FALSE);
-	}
-
-	/* Compute resolv.conf domain */
-	if (num_domains > 0) {
-		str = g_string_new ("domain ");
-		g_string_append (str, nm_ip4_config_get_domain (composite, 0));
-		g_string_append (str, "\n\n");
-
-		domain = g_string_free (str, FALSE);
-	}
-
-	/* Using glibc resolver */
-	nameservers = compute_nameservers (composite);
-	if (fprintf (f, "%s%s%s\n",
-	             domain ? domain : "",
-	             searches ? searches : "",
-	             nameservers ? nameservers : "") < 0) {
-		g_set_error (error,
-			     NM_NAMED_MANAGER_ERROR,
-			     NM_NAMED_MANAGER_ERROR_SYSTEM,
-			     "Could not write to " RESOLV_CONF ": %s\n",
-			     g_strerror (errno));
+		g_ptr_array_add (array, NULL);
+		nameservers = (char **) g_ptr_array_free (array, FALSE);
 	}
-	g_free (nameservers);
 
-	if (fclose (f) < 0) {
-		if (*error == NULL) {
-			g_set_error (error,
-				     NM_NAMED_MANAGER_ERROR,
-				     NM_NAMED_MANAGER_ERROR_SYSTEM,
-				     "Could not close " RESOLV_CONF ": %s\n",
-				     g_strerror (errno));
-		}
-	}
+	success = update_resolv_conf (iface, domain, searches, nameservers, error);
 
-	g_free (domain);
-	g_free (searches);
+	g_strfreev (searches);
+	g_strfreev (nameservers);
 
-	if (*error == NULL) {
-		if (rename (tmp_resolv_conf, RESOLV_CONF) < 0) {
-			g_set_error (error,
-				     NM_NAMED_MANAGER_ERROR,
-				     NM_NAMED_MANAGER_ERROR_SYSTEM,
-				     "Could not replace " RESOLV_CONF ": %s\n",
-				     g_strerror (errno));
-		} else {
-			nm_system_update_dns ();
-		}
-	}
+	if (success)
+		nm_system_update_dns ();
 
-	return *error ? FALSE : TRUE;
+	return success;
 }
 
 gboolean
 nm_named_manager_add_ip4_config (NMNamedManager *mgr,
+						   const char *iface,
                                  NMIP4Config *config,
                                  NMNamedIPConfigType cfg_type)
 {
@@ -319,6 +437,7 @@
 	GError *error = NULL;
 
 	g_return_val_if_fail (mgr != NULL, FALSE);
+	g_return_val_if_fail (iface != NULL, FALSE);
 	g_return_val_if_fail (config != NULL, FALSE);
 
 	priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
@@ -338,7 +457,7 @@
 	if (!g_slist_find (priv->configs, config))
 		priv->configs = g_slist_append (priv->configs, g_object_ref (config));
 
-	if (!rewrite_resolv_conf (mgr, &error)) {
+	if (!rewrite_resolv_conf (mgr, iface, &error)) {
 		nm_warning ("Could not commit DNS changes.  Error: '%s'", error ? error->message : "(none)");
 		g_error_free (error);
 	}
@@ -347,12 +466,15 @@
 }
 
 gboolean
-nm_named_manager_remove_ip4_config (NMNamedManager *mgr, NMIP4Config *config)
+nm_named_manager_remove_ip4_config (NMNamedManager *mgr,
+							 const char *iface,
+							 NMIP4Config *config)
 {
 	NMNamedManagerPrivate *priv;
 	GError *error = NULL;
 
 	g_return_val_if_fail (mgr != NULL, FALSE);
+	g_return_val_if_fail (iface != NULL, FALSE);
 	g_return_val_if_fail (config != NULL, FALSE);
 
 	priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
@@ -371,7 +493,7 @@
 
 	g_object_unref (config);	
 
-	if (!rewrite_resolv_conf (mgr, &error)) {
+	if (!rewrite_resolv_conf (mgr, iface, &error)) {
 		nm_warning ("Could not commit DNS changes.  Error: '%s'", error ? error->message : "(none)");
 		if (error)
 			g_error_free (error);

Modified: branches/mbca/src/named-manager/nm-named-manager.h
==============================================================================
--- branches/mbca/src/named-manager/nm-named-manager.h	(original)
+++ branches/mbca/src/named-manager/nm-named-manager.h	Mon Aug 18 08:30:28 2008
@@ -68,10 +68,13 @@
 NMNamedManager * nm_named_manager_get (void);
 
 gboolean nm_named_manager_add_ip4_config (NMNamedManager *mgr,
+					  const char *iface,
                                           NMIP4Config *config,
                                           NMNamedIPConfigType cfg_type);
 
-gboolean nm_named_manager_remove_ip4_config (NMNamedManager *mgr, NMIP4Config *config);
+gboolean nm_named_manager_remove_ip4_config (NMNamedManager *mgr,
+					     const char *iface,
+					     NMIP4Config *config);
 
 G_END_DECLS
 

Modified: branches/mbca/src/nm-activation-request.c
==============================================================================
--- branches/mbca/src/nm-activation-request.c	(original)
+++ branches/mbca/src/nm-activation-request.c	Mon Aug 18 08:30:28 2008
@@ -20,6 +20,9 @@
  */
 
 #include <string.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <unistd.h>
 #include <dbus/dbus-glib.h>
 
 #include "nm-activation-request.h"
@@ -49,6 +52,10 @@
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+typedef struct {
+	char *table;
+	char *rule;
+} ShareRule;
 
 typedef struct {
 	gboolean disposed;
@@ -63,6 +70,7 @@
 	NMActiveConnectionState state;
 	gboolean is_default;
 	gboolean shared;
+	GSList *share_rules;
 
 	char *ac_path;
 } NMActRequestPrivate;
@@ -206,12 +214,33 @@
 
 	cleanup_secrets_dbus_call (NM_ACT_REQUEST (object));
 
+	/* Clear any share rules */
+	nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE);
+
 	g_object_unref (priv->connection);
 
 	G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
 }
 
 static void
+clear_share_rules (NMActRequest *req)
+{
+	NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
+	GSList *iter;
+
+	for (iter = priv->share_rules; iter; iter = g_slist_next (iter)) {
+		ShareRule *rule = (ShareRule *) iter->data;
+
+		g_free (rule->table);
+		g_free (rule->rule);
+		g_free (rule);
+	}
+
+	g_slist_free (priv->share_rules);
+	priv->share_rules = NULL;
+}
+
+static void
 finalize (GObject *object)
 {
 	NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
@@ -219,6 +248,8 @@
 	g_free (priv->specific_object);
 	g_free (priv->ac_path);
 
+	clear_share_rules (NM_ACT_REQUEST (object));
+
 	G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object);
 }
 
@@ -646,12 +677,69 @@
 	return NM_ACT_REQUEST_GET_PRIVATE (req)->is_default;
 }
 
+static void
+share_child_setup (gpointer user_data G_GNUC_UNUSED)
+{
+	/* We are in the child process at this point */
+	pid_t pid = getpid ();
+	setpgid (pid, pid);
+}
+
 void
 nm_act_request_set_shared (NMActRequest *req, gboolean shared)
 {
+	NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
+	GSList *list, *iter;
+
 	g_return_if_fail (NM_IS_ACT_REQUEST (req));
 
 	NM_ACT_REQUEST_GET_PRIVATE (req)->shared = shared;
+
+	/* Tear the rules down in reverse order when sharing is stopped */
+	list = g_slist_copy (priv->share_rules);
+	if (!shared)
+		list = g_slist_reverse (list);
+
+	/* Send the rules to iptables */
+	for (iter = list; iter; iter = g_slist_next (iter)) {
+		ShareRule *rule = (ShareRule *) iter->data;
+		char *envp[1] = { NULL };
+		char **argv;
+		char *cmd;
+		int status;
+		GError *error = NULL;
+
+		if (shared)
+			cmd = g_strdup_printf ("/sbin/iptables --table %s --insert %s", rule->table, rule->rule);
+		else
+			cmd = g_strdup_printf ("/sbin/iptables --table %s --delete %s", rule->table, rule->rule);
+
+		argv = g_strsplit (cmd, " ", 0);
+		if (!argv || !argv[0]) {
+			continue;
+			g_free (cmd);
+		}
+
+		nm_info ("Executing: %s", cmd);
+		g_free (cmd);
+
+		if (!g_spawn_sync ("/", argv, envp, G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
+		                   share_child_setup, NULL, NULL, NULL, &status, &error)) {
+			nm_info ("Error executing command: (%d) %s",
+			         error ? error->code : 0, (error && error->message) ? error->message : "unknown");
+			if (error)
+				g_error_free (error);
+		} else if (WEXITSTATUS (status))
+			nm_info ("** Command returned exit status %d.", WEXITSTATUS (status));
+
+		g_strfreev (argv);
+	}
+
+	g_slist_free (list);
+
+	/* Clear the share rule list when sharing is stopped */
+	if (!shared)
+		clear_share_rules (req);
 }
 
 gboolean
@@ -662,6 +750,24 @@
 	return NM_ACT_REQUEST_GET_PRIVATE (req)->shared;
 }
 
+void
+nm_act_request_add_share_rule (NMActRequest *req,
+                               const char *table,
+                               const char *table_rule)
+{
+	NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
+	ShareRule *rule;
+
+	g_return_if_fail (NM_IS_ACT_REQUEST (req));
+	g_return_if_fail (table != NULL);
+	g_return_if_fail (table_rule != NULL);
+	
+	rule = g_malloc0 (sizeof (ShareRule));
+	rule->table = g_strdup (table);
+	rule->rule = g_strdup (table_rule);
+	priv->share_rules = g_slist_append (priv->share_rules, rule);
+}
+
 GObject *
 nm_act_request_get_device (NMActRequest *req)
 {

Modified: branches/mbca/src/nm-activation-request.h
==============================================================================
--- branches/mbca/src/nm-activation-request.h	(original)
+++ branches/mbca/src/nm-activation-request.h	Mon Aug 18 08:30:28 2008
@@ -44,7 +44,8 @@
 	SECRETS_CALLER_WIFI,
 	SECRETS_CALLER_GSM,
 	SECRETS_CALLER_CDMA,
-	SECRETS_CALLER_PPP
+	SECRETS_CALLER_PPP,
+	SECRETS_CALLER_HSO_GSM
 } RequestSecretsCaller;
 
 typedef struct {
@@ -94,6 +95,10 @@
 
 void          nm_act_request_set_shared (NMActRequest *req, gboolean shared);
 
+void          nm_act_request_add_share_rule (NMActRequest *req,
+                                             const char *table,
+                                             const char *rule);
+
 GObject *     nm_act_request_get_device (NMActRequest *req);
 
 #endif /* NM_ACTIVATION_REQUEST_H */

Modified: branches/mbca/src/nm-cdma-device.c
==============================================================================
--- branches/mbca/src/nm-cdma-device.c	(original)
+++ branches/mbca/src/nm-cdma-device.c	Mon Aug 18 08:30:28 2008
@@ -513,7 +513,7 @@
 						  "Monitoring interface",
 						  "Monitoring interface",
 						  NULL,
-						  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+						  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
 
 	/* Signals */
 	signals[PROPERTIES_CHANGED] = 

Modified: branches/mbca/src/nm-device-ethernet.c
==============================================================================
--- branches/mbca/src/nm-device-ethernet.c	(original)
+++ branches/mbca/src/nm-device-ethernet.c	Mon Aug 18 08:30:28 2008
@@ -291,7 +291,7 @@
 											  dev);
 
 		if (!nm_netlink_monitor_request_status (monitor, &error)) {
-			nm_warning ("couldn't request carrier state: %s", error->message);
+			nm_warning ("couldn't request carrier state: %s", error ? error->message : "unknown");
 			g_error_free (error);
 		}
 

Modified: branches/mbca/src/nm-device-interface.c
==============================================================================
--- branches/mbca/src/nm-device-interface.c	(original)
+++ branches/mbca/src/nm-device-interface.c	Mon Aug 18 08:30:28 2008
@@ -98,10 +98,10 @@
 
 	g_object_interface_install_property
 		(g_iface,
-		 g_param_spec_object (NM_DEVICE_INTERFACE_DHCP4_CONFIG,
+		 g_param_spec_boxed (NM_DEVICE_INTERFACE_DHCP4_CONFIG,
 							  "DHCP4 Config",
 							  "DHCP4 Config",
-							  G_TYPE_OBJECT,
+							  DBUS_TYPE_G_OBJECT_PATH,
 							  G_PARAM_READWRITE));
 
 	g_object_interface_install_property

Modified: branches/mbca/src/nm-device.c
==============================================================================
--- branches/mbca/src/nm-device.c	(original)
+++ branches/mbca/src/nm-device.c	Mon Aug 18 08:30:28 2008
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <arpa/inet.h>
+#include <fcntl.h>
 
 #include "nm-device-interface.h"
 #include "nm-device.h"
@@ -1199,6 +1200,140 @@
 	         nm_device_get_iface (self));
 }
 
+static void
+share_child_setup (gpointer user_data G_GNUC_UNUSED)
+{
+	/* We are in the child process at this point */
+	pid_t pid = getpid ();
+	setpgid (pid, pid);
+}
+
+static gboolean
+share_init (void)
+{
+	int fd, count, status;
+	char *modules[] = { "ip_tables", "iptable_nat", "nf_nat_ftp", "nf_nat_irc",
+	                    "nf_nat_sip", "nf_nat_tftp", "nf_nat_pptp", "nf_nat_h323",
+	                    NULL };
+	char **iter;
+
+	fd = open ("/proc/sys/net/ipv4/ip_forward", O_WRONLY | O_TRUNC);
+	if (fd) {
+		count = write (fd, "1\n", 2);
+		if (count != 2) {
+			nm_warning ("%s: Error starting IP forwarding: (%d) %s",
+			            __func__, errno, strerror (errno));
+			return FALSE;
+		}
+		close (fd);
+	}
+
+	fd = open ("/proc/sys/net/ipv4/ip_dynaddr", O_WRONLY | O_TRUNC);
+	if (fd) {
+		count = write (fd, "1\n", 2);
+		if (count != 2) {
+			nm_warning ("%s: Error starting IP forwarding: (%d) %s",
+			            __func__, errno, strerror (errno));
+		}
+		close (fd);
+	}
+
+	for (iter = modules; *iter; iter++) {
+		char *argv[3] = { "/sbin/modprobe", *iter, NULL };
+		char *envp[1] = { NULL };
+		GError *error = NULL;
+
+		if (!g_spawn_sync ("/", argv, envp, G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
+		                   share_child_setup, NULL, NULL, NULL, &status, &error)) {
+			nm_info ("%s: Error loading NAT module %s: (%d) %s",
+			         __func__, *iter, error ? error->code : 0,
+			         (error && error->message) ? error->message : "unknown");
+			if (error)
+				g_error_free (error);
+		}
+	}
+
+	return TRUE;
+}
+
+static void
+add_share_rule (NMActRequest *req, const char *table, const char *fmt, ...)
+{
+	va_list args;
+	char *cmd;
+
+	va_start (args, fmt);
+	cmd = g_strdup_vprintf (fmt, args);
+	va_end (args);
+
+	nm_act_request_add_share_rule (req, table, cmd);
+	g_free (cmd);
+}
+
+static gboolean
+start_sharing (NMDevice *self)
+{
+	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+	NMActRequest *req;
+	GError *error = NULL;
+	char str_addr[INET_ADDRSTRLEN + 1];
+	char str_mask[INET_ADDRSTRLEN + 1];
+	guint32 netmask, network;
+	NMIP4Config *ip4_config;
+	const NMSettingIP4Address *ip4_addr;
+	const char *iface;
+
+	iface = nm_device_get_ip_iface (self);
+	if (!iface)
+		iface = nm_device_get_iface (self);
+
+	ip4_config = nm_device_get_ip4_config (self);
+	if (!ip4_config)
+		return FALSE;
+
+	ip4_addr = nm_ip4_config_get_address (ip4_config, 0);
+	if (!ip4_addr || !ip4_addr->address)
+		return FALSE;
+
+	netmask = nm_utils_ip4_prefix_to_netmask (ip4_addr->prefix);
+	if (!inet_ntop (AF_INET, &netmask, str_mask, sizeof (str_mask)))
+		return FALSE;
+
+	network = ip4_addr->address & netmask;
+	if (!inet_ntop (AF_INET, &network, str_addr, sizeof (str_addr)))
+		return FALSE;
+
+	if (!share_init ())
+		return FALSE;
+
+	req = nm_device_get_act_request (self);
+	g_assert (req);
+
+	add_share_rule (req, "filter", "INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT", iface);
+	add_share_rule (req, "filter", "INPUT --in-interface %s --protocol udp --destination-port 53 --jump ACCEPT", iface);
+	add_share_rule (req, "filter", "INPUT --in-interface %s --protocol tcp --destination-port 67 --jump ACCEPT", iface);
+	add_share_rule (req, "filter", "INPUT --in-interface %s --protocol udp --destination-port 67 --jump ACCEPT", iface);
+	add_share_rule (req, "filter", "FORWARD --in-interface %s --jump REJECT", iface);
+	add_share_rule (req, "filter", "FORWARD --out-interface %s --jump REJECT", iface);
+	add_share_rule (req, "filter", "FORWARD --in-interface %s --out-interface %s --jump ACCEPT", iface, iface);
+	add_share_rule (req, "filter", "FORWARD --source %s/%s --in-interface %s --jump ACCEPT", str_addr, str_mask, iface);
+	add_share_rule (req, "filter", "FORWARD --destination %s/%s --out-interface %s --match state --state ESTABLISHED,RELATED --jump ACCEPT", str_addr, str_mask, iface);
+	add_share_rule (req, "nat", "POSTROUTING --source %s/%s --destination ! %s/%s --jump MASQUERADE", str_addr, str_mask, str_addr, str_mask);
+
+	nm_act_request_set_shared (req, TRUE);
+
+	if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, ip4_config, &error)) {
+		nm_warning ("(%s): failed to start dnsmasq: %s", iface, error->message);
+		g_error_free (error);
+		nm_act_request_set_shared (req, FALSE);
+		return FALSE;
+	}
+
+	priv->dnsmasq_state_id = g_signal_connect (priv->dnsmasq_manager, "state-changed",
+	                                           G_CALLBACK (dnsmasq_state_changed_cb),
+	                                           self);
+	return TRUE;
+}
 
 /*
  * nm_device_activate_stage5_ip_config_commit
@@ -1237,18 +1372,11 @@
 	connection = nm_act_request_get_connection (nm_device_get_act_request (self));
 	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
 	if (s_ip4 && !strcmp (s_ip4->method, "shared")) {
-		GError *error = NULL;
-
-		if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, ip4_config, &error)) {
-			nm_warning ("(%s): failed to start dnsmasq: %s", iface, error->message);
-			g_error_free (error);
+		if (!start_sharing (self)) {
+			nm_warning ("Activation (%s) Stage 5 of 5 (IP Configure Commit) start sharing failed.", iface);
 			nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
 			goto out;
 		}
-
-		priv->dnsmasq_state_id = g_signal_connect (priv->dnsmasq_manager, "state-changed",
-		                                           G_CALLBACK (dnsmasq_state_changed_cb),
-		                                           self);
 	}
 
 	nm_device_state_changed (self, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE);
@@ -1329,8 +1457,6 @@
 
 	priv = NM_DEVICE_GET_PRIVATE (self);
 
-	nm_system_shutdown_nis ();
-
 	/* Break the activation chain */
 	if (priv->act_source_id) {
 		g_source_remove (priv->act_source_id);
@@ -1363,13 +1489,13 @@
 
 	aipd_cleanup (self);
 
-	/* Tear down an existing activation request */
-	clear_act_request (self);
-
 	/* Call device type-specific deactivation */
 	if (NM_DEVICE_GET_CLASS (self)->deactivate_quickly)
 		NM_DEVICE_GET_CLASS (self)->deactivate_quickly (self);
 
+	/* Tear down an existing activation request */
+	clear_act_request (self);
+
 	return TRUE;
 }
 
@@ -1736,13 +1862,14 @@
 	g_return_val_if_fail (reason != NULL, FALSE);
 
 	priv = NM_DEVICE_GET_PRIVATE (self);
+	ip_iface = nm_device_get_ip_iface (self);
 
 	if (priv->ip4_config) {
 		NMNamedManager *named_mgr;
 
 		/* Remove any previous IP4 Config from the named manager */
 		named_mgr = nm_named_manager_get ();
-		nm_named_manager_remove_ip4_config (named_mgr, priv->ip4_config);
+		nm_named_manager_remove_ip4_config (named_mgr, ip_iface, priv->ip4_config);
 		g_object_unref (named_mgr);
 
 		g_object_unref (priv->ip4_config);
@@ -1754,14 +1881,9 @@
 
 	priv->ip4_config = g_object_ref (config);
 
-	ip_iface = nm_device_get_ip_iface (self);
-
 	success = nm_system_device_set_from_ip4_config (ip_iface, config);
-	if (success) {
+	if (success)
 		nm_device_update_ip4_address (self);
-		nm_system_set_hostname (config);
-		nm_system_activate_nis (config);
-	}
 
 	g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_IP4_CONFIG);
 
@@ -2062,9 +2184,9 @@
 	case NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG:
 		if (   ((state == NM_DEVICE_STATE_ACTIVATED) || (state == NM_DEVICE_STATE_IP_CONFIG))
 		    && nm_device_get_use_dhcp (self))
-			g_value_set_object (value, priv->dhcp4_config);
+			g_value_set_boxed (value, nm_dhcp4_config_get_dbus_path (priv->dhcp4_config));
 		else
-			g_value_set_object (value, NULL);
+			g_value_set_boxed (value, "/");
 		break;
 	case NM_DEVICE_INTERFACE_PROP_STATE:
 		g_value_set_uint (value, priv->state);

Modified: branches/mbca/src/nm-device.h
==============================================================================
--- branches/mbca/src/nm-device.h	(original)
+++ branches/mbca/src/nm-device.h	Mon Aug 18 08:30:28 2008
@@ -60,8 +60,6 @@
 	NMDevicePrivate *priv;
 };
 
-struct NMData;
-
 struct _NMDeviceClass
 {
 	GObjectClass parent;

Modified: branches/mbca/src/nm-dhcp4-config.c
==============================================================================
--- branches/mbca/src/nm-dhcp4-config.c	(original)
+++ branches/mbca/src/nm-dhcp4-config.c	Mon Aug 18 08:30:28 2008
@@ -105,6 +105,14 @@
 	return value ? g_value_get_string (value) : NULL;
 }
 
+const char *
+nm_dhcp4_config_get_dbus_path (NMDHCP4Config *self)
+{
+	g_return_val_if_fail (NM_IS_DHCP4_CONFIG (self), NULL);
+
+	return NM_DHCP4_CONFIG_GET_PRIVATE (self)->dbus_path;
+}
+
 static void
 nm_gvalue_destroy (gpointer data)
 {

Modified: branches/mbca/src/nm-dhcp4-config.h
==============================================================================
--- branches/mbca/src/nm-dhcp4-config.h	(original)
+++ branches/mbca/src/nm-dhcp4-config.h	Mon Aug 18 08:30:28 2008
@@ -51,6 +51,8 @@
 
 NMDHCP4Config *nm_dhcp4_config_new (void);
 
+const char *nm_dhcp4_config_get_dbus_path (NMDHCP4Config *config);
+
 void nm_dhcp4_config_add_option (NMDHCP4Config *config,
                                  const char *key,
                                  const char *option);

Modified: branches/mbca/src/nm-gsm-device.c
==============================================================================
--- branches/mbca/src/nm-gsm-device.c	(original)
+++ branches/mbca/src/nm-gsm-device.c	Mon Aug 18 08:30:28 2008
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 
 #include <stdio.h>
 #include <string.h>
@@ -74,13 +74,14 @@
 				  guint timeout,
 				  char **responses,
 				  char **terminators,
-				  NMSerialWaitForReplyFn callback)
+				  NMSerialWaitForReplyFn callback,
+				  gpointer user_data)
 {
 	NMSerialDevice *serial = NM_SERIAL_DEVICE (self);
 	guint id = 0;
 
 	if (nm_serial_device_send_command_string (serial, command))
-		id = nm_serial_device_wait_for_reply (serial, timeout, responses, terminators, callback, NULL);
+		id = nm_serial_device_wait_for_reply (serial, timeout, responses, terminators, callback, user_data);
 
 	if (id == 0)
 		nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
@@ -163,7 +164,7 @@
 }
 
 static void
-do_dial (NMGsmDevice *device, guint cid)
+real_do_dial (NMGsmDevice *device, guint cid)
 {
 	NMSettingGsm *setting;
 	char *command;
@@ -185,7 +186,7 @@
 	} else
 		command = g_strconcat ("ATDT", setting->number, NULL);
 
-	modem_wait_for_reply (device, command, 60, responses, responses, dial_done);
+	modem_wait_for_reply (device, command, 60, responses, responses, dial_done, NULL);
 	g_free (command);
 }
 
@@ -196,7 +197,7 @@
 {
 	switch (reply_index) {
 	case 0:
-		do_dial (NM_GSM_DEVICE (device), 1);
+		NM_GSM_DEVICE_GET_CLASS (device)->do_dial (NM_GSM_DEVICE (device), GPOINTER_TO_UINT (user_data));
 		break;
 	default:
 		nm_warning ("Setting APN failed");
@@ -216,15 +217,14 @@
 	guint cid = 1;
 
 	setting = NM_SETTING_GSM (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_GSM));
-
 	if (!setting->apn) {
 		/* APN not set, nothing to do */
-		do_dial (device, 0);
+		NM_GSM_DEVICE_GET_CLASS (device)->do_dial (NM_GSM_DEVICE (device), 0);
 		return;
 	}
 
 	command = g_strdup_printf ("AT+CGDCONT=%d, \"IP\", \"%s\"", cid, setting->apn);
-	modem_wait_for_reply (device, command, 3, responses, responses, set_apn_done);
+	modem_wait_for_reply (device, command, 3, responses, responses, set_apn_done, GUINT_TO_POINTER (cid));
 	g_free (command);
 }
 
@@ -241,7 +241,7 @@
 		nm_warning ("Manual registration timed out");
 		nm_device_state_changed (NM_DEVICE (device),
 		                         NM_DEVICE_STATE_FAILED,
-		                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED);
+		                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT);
 		break;
 	default:
 		nm_warning ("Manual registration failed");
@@ -262,7 +262,7 @@
 	setting = NM_SETTING_GSM (gsm_device_get_setting (device, NM_TYPE_SETTING_GSM));
 
 	command = g_strdup_printf ("AT+COPS=1,2,\"%s\"", setting->network_id);
-	modem_wait_for_reply (device, command, 30, responses, responses, manual_registration_done);
+	modem_wait_for_reply (device, command, 30, responses, responses, manual_registration_done, NULL);
 	g_free (command);
 }
 
@@ -304,7 +304,7 @@
 		nm_warning ("Automatic registration failed: not registered and not searching.");
 		nm_device_state_changed (NM_DEVICE (device),
 		                         NM_DEVICE_STATE_FAILED,
-		                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED);
+		                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING);
 		break;
 	case 1:
 		nm_info ("Registered on Home network");
@@ -317,7 +317,7 @@
 		nm_warning ("Automatic registration failed: registration denied.");
 		nm_device_state_changed (NM_DEVICE (device),
 		                         NM_DEVICE_STATE_FAILED,
-		                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED);
+		                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED);
 		break;
 	case 4:
 		nm_info ("Registered on Roaming network");
@@ -327,7 +327,7 @@
 		nm_warning ("Automatic registration timed out");
 		nm_device_state_changed (NM_DEVICE (device),
 		                         NM_DEVICE_STATE_FAILED,
-		                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED);
+		                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT);
 		break;
 	default:
 		nm_warning ("Automatic registration failed");
@@ -344,7 +344,7 @@
 	char *responses[] = { "+CREG: 0,0", "+CREG: 0,1", "+CREG: 0,2", "+CREG: 0,3", "+CREG: 0,5", NULL };
 	char *terminators[] = { "OK", "ERROR", "ERR", NULL };
 
-	modem_wait_for_reply (device, "AT+CREG?", 60, responses, terminators, automatic_registration_response);
+	modem_wait_for_reply (device, "AT+CREG?", 60, responses, terminators, automatic_registration_response, NULL);
 }
 
 static void
@@ -393,7 +393,7 @@
 	 * just breaks stuff since echo-ed commands are interpreted as replies.
 	 * rh #456770
 	 */
-	modem_wait_for_reply (device, "ATZ E0", 10, responses, responses, init_full_done);
+	modem_wait_for_reply (device, "ATZ E0", 10, responses, responses, init_full_done, NULL);
 }
 
 static void
@@ -473,7 +473,7 @@
 		char *responses[] = { "OK", "ERROR", "ERR", NULL };
 
 		command = g_strdup_printf ("AT+CPIN=\"%s\"", secret);
-		modem_wait_for_reply (device, command, 3, responses, responses, enter_pin_done);
+		modem_wait_for_reply (device, command, 3, responses, responses, enter_pin_done, NULL);
 		g_free (command);
 	} else {
 		nm_info ("(%s): GSM %s secret required", nm_device_get_iface (NM_DEVICE (device)), secret_name);
@@ -527,7 +527,7 @@
 	char *responses[] = { "READY", "SIM PIN", "SIM PUK", "ERROR", "ERR", NULL };
 	char *terminators[] = { "OK", "ERROR", "ERR", NULL };
 
-	modem_wait_for_reply (self, "AT+CPIN?", 3, responses, terminators, check_pin_done);
+	modem_wait_for_reply (self, "AT+CPIN?", 3, responses, terminators, check_pin_done, NULL);
 }
 
 static void
@@ -559,7 +559,7 @@
 {
 	char *responses[] = { "OK", "ERROR", "ERR", NULL };
 
-	modem_wait_for_reply (NM_GSM_DEVICE (device), "AT E0", 10, responses, responses, init_done);
+	modem_wait_for_reply (NM_GSM_DEVICE (device), "AT E0", 10, responses, responses, init_done, NULL);
 }
 
 static NMActStageReturn
@@ -911,6 +911,8 @@
 	device_class->connection_secrets_updated = real_connection_secrets_updated;
 	device_class->deactivate_quickly = real_deactivate_quickly;
 
+	klass->do_dial = real_do_dial;
+
 	/* Properties */
 	g_object_class_install_property
 		(object_class, PROP_MONITOR_IFACE,
@@ -918,7 +920,7 @@
 						  "Monitoring interface",
 						  "Monitoring interface",
 						  NULL,
-						  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+						  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
 
 	/* Signals */
 	signals[PROPERTIES_CHANGED] = 

Modified: branches/mbca/src/nm-gsm-device.h
==============================================================================
--- branches/mbca/src/nm-gsm-device.h	(original)
+++ branches/mbca/src/nm-gsm-device.h	Mon Aug 18 08:30:28 2008
@@ -23,6 +23,8 @@
 typedef struct {
 	NMSerialDeviceClass parent;
 
+	void (*do_dial) (NMGsmDevice *device, guint cid);
+
 	/* Signals */
 	void (*properties_changed) (NMGsmDevice *device, GHashTable *properties);
 } NMGsmDeviceClass;

Modified: branches/mbca/src/nm-hal-manager.c
==============================================================================
--- branches/mbca/src/nm-hal-manager.c	(original)
+++ branches/mbca/src/nm-hal-manager.c	Mon Aug 18 08:30:28 2008
@@ -14,6 +14,7 @@
 #include "nm-device-wifi.h"
 #include "nm-device-ethernet.h"
 #include "nm-gsm-device.h"
+#include "nm-hso-gsm-device.h"
 #include "nm-cdma-device.h"
 #include "probe-modem.h"
 
@@ -221,6 +222,50 @@
 	return is_modem;
 }
 
+static char *
+get_hso_netdev (LibHalContext *ctx, const char *udi)
+{
+	char *serial_parent, *netdev = NULL;
+	char **netdevs;
+	int num, i;
+
+	/* Get the serial interface's originating device UDI, used to find the
+	 * originating device's netdev.
+	 */
+	serial_parent = libhal_device_get_property_string (ctx, udi, "serial.originating_device", NULL);
+	if (!serial_parent)
+		serial_parent = libhal_device_get_property_string (ctx, udi, "info.parent", NULL);
+	if (!serial_parent)
+		return NULL;
+
+	/* Look for the originating device's netdev */
+	netdevs = libhal_find_device_by_capability (ctx, "net", &num, NULL);
+	for (i = 0; netdevs && !netdev && (i < num); i++) {
+		char *netdev_parent, *tmp;
+
+		netdev_parent = libhal_device_get_property_string (ctx, netdevs[i], "net.originating_device", NULL);
+		if (!netdev_parent)
+			netdev_parent = libhal_device_get_property_string (ctx, netdevs[i], "net.physical_device", NULL);
+		if (!netdev_parent)
+			continue;
+
+		if (!strcmp (netdev_parent, serial_parent)) {
+			/* We found it */
+			tmp = libhal_device_get_property_string (ctx, netdevs[i], "net.interface", NULL);
+			if (tmp) {
+				netdev = g_strdup (tmp);
+				libhal_free_string (tmp);
+			}
+		}
+
+		libhal_free_string (netdev_parent);
+	}
+	libhal_free_string_array (netdevs);
+	libhal_free_string (serial_parent);
+
+	return netdev;
+}
+
 static GObject *
 modem_device_creator (NMHalManager *self, const char *udi, gboolean managed)
 {
@@ -233,6 +278,7 @@
 	gboolean type_gsm = FALSE;
 	gboolean type_cdma = FALSE;
 	gboolean type_v250 = FALSE;
+	char *netdev = NULL;
 
 	serial_device = libhal_device_get_property_string (priv->hal_ctx, udi, "serial.device", NULL);
 
@@ -289,8 +335,15 @@
 		}
 	}
 
+	/* Special handling of 'hso' cards (until punted out to a modem manager) */
+	if (type_gsm && !strcmp (driver_name, "hso"))
+		netdev = get_hso_netdev (priv->hal_ctx, udi);
+
 	if (type_gsm)
-		device = (GObject *) nm_gsm_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name, managed);
+		if (netdev)
+			device = (GObject *) nm_hso_gsm_device_new (udi, serial_device + strlen ("/dev/"), NULL, netdev, driver_name, managed);
+		else
+			device = (GObject *) nm_gsm_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name, managed);
 	else if (type_cdma)
 		device = (GObject *) nm_cdma_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name, managed);
 
@@ -317,7 +370,7 @@
 
 	/* Wireless device */
 	creator = g_slice_new0 (DeviceCreator);
-	creator->device_type_name = g_strdup ("wireless (802.11)");
+	creator->device_type_name = g_strdup ("802.11 WiFi");
 	creator->capability_str = g_strdup ("net.80211");
 	creator->is_device_fn = is_wireless_device;
 	creator->creator_fn = wireless_device_creator;

Modified: branches/mbca/src/nm-ip4-config.c
==============================================================================
--- branches/mbca/src/nm-ip4-config.c	(original)
+++ branches/mbca/src/nm-ip4-config.c	Mon Aug 18 08:30:28 2008
@@ -56,8 +56,6 @@
 	GPtrArray *searches;
 
 	gchar *hostname;
-	gchar *nis_domain;
-	GArray *nis_servers;
 	GSList *routes;
 } NMIP4ConfigPrivate;
 
@@ -68,8 +66,6 @@
 	PROP_HOSTNAME,
 	PROP_NAMESERVERS,
 	PROP_DOMAINS,
-	PROP_NIS_DOMAIN,
-	PROP_NIS_SERVERS,
 	PROP_ROUTES,
 
 	LAST_PROP
@@ -95,56 +91,6 @@
 	return (NMIP4Config *) object;
 }
 
-NMIP4Config *nm_ip4_config_copy (NMIP4Config *src_config)
-{
-	NMIP4Config *dst_config;
-	NMIP4ConfigPrivate *src_priv;
-	int i;
-	int len;
-	GSList *iter;
-
-	g_return_val_if_fail (NM_IS_IP4_CONFIG (src_config), NULL);
-
-	dst_config = nm_ip4_config_new ();
-	src_priv = NM_IP4_CONFIG_GET_PRIVATE (src_config);
-
-	for (iter = src_priv->addresses; iter; iter = g_slist_next (iter)) {
-		NMSettingIP4Address *src_addr = (NMSettingIP4Address *) iter->data;
-		NMSettingIP4Address *dst_addr;
-
-		dst_addr = g_malloc0 (sizeof (NMSettingIP4Address));
-		memcpy (dst_addr, src_addr, sizeof (NMSettingIP4Address));
-		nm_ip4_config_take_address (dst_config, dst_addr);
-	}
-
-	nm_ip4_config_set_ptp_address (dst_config, nm_ip4_config_get_ptp_address (src_config));
-	nm_ip4_config_set_hostname    (dst_config, nm_ip4_config_get_hostname (src_config));
-	nm_ip4_config_set_nis_domain  (dst_config, nm_ip4_config_get_nis_domain (src_config));
-
-	len = nm_ip4_config_get_num_nameservers (src_config);
-	for (i = 0; i < len; i++)
-		nm_ip4_config_add_nameserver (dst_config, nm_ip4_config_get_nameserver (src_config, i));
-
-	len = nm_ip4_config_get_num_domains (src_config);
-	for (i = 0; i < len; i++)
-		nm_ip4_config_add_domain (dst_config, nm_ip4_config_get_domain (src_config, i));
-
-	len = nm_ip4_config_get_num_nis_servers (src_config);
-	for (i = 0; i < len; i++)
-		nm_ip4_config_add_nis_server (dst_config, nm_ip4_config_get_nis_server (src_config, i));
-
-	for (iter = src_priv->routes; iter; iter = g_slist_next (iter)) {
-		NMSettingIP4Route *src_route = (NMSettingIP4Route *) iter->data;
-		NMSettingIP4Route *dst_route;
-
-		dst_route = g_malloc0 (sizeof (NMSettingIP4Route));
-		memcpy (dst_route, src_route, sizeof (NMSettingIP4Route));
-		nm_ip4_config_take_route (dst_config, dst_route);
-	}
-
-	return dst_config;
-}
-
 void
 nm_ip4_config_take_address (NMIP4Config *config,
                             NMSettingIP4Address *address)
@@ -180,6 +126,7 @@
                                NMSettingIP4Address *new_address)
 {
 	NMIP4ConfigPrivate *priv;
+	NMSettingIP4Address *copy;
 	GSList *old;
 
 	g_return_if_fail (NM_IS_IP4_CONFIG (config));
@@ -187,9 +134,11 @@
 	priv = NM_IP4_CONFIG_GET_PRIVATE (config);
 	old = g_slist_nth (priv->addresses, i);
 	g_return_if_fail (old != NULL);
-
 	g_free (old->data);
-	old->data = new_address;
+
+	copy = g_malloc0 (sizeof (NMSettingIP4Address));
+	memcpy (copy, new_address, sizeof (NMSettingIP4Address));
+	old->data = copy;
 }
 
 const NMSettingIP4Address *nm_ip4_config_get_address (NMIP4Config *config, guint i)
@@ -253,27 +202,6 @@
 		g_array_remove_range (priv->nameservers, 0, priv->nameservers->len);
 }
 
-void nm_ip4_config_add_nis_server (NMIP4Config *config, guint32 nis_server)
-{
-	g_return_if_fail (NM_IS_IP4_CONFIG (config));
-
-	g_array_append_val (NM_IP4_CONFIG_GET_PRIVATE (config)->nis_servers, nis_server);
-}
-
-guint32 nm_ip4_config_get_nis_server (NMIP4Config *config, guint i)
-{
-	g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
-
-	return g_array_index (NM_IP4_CONFIG_GET_PRIVATE (config)->nis_servers, guint32, i);
-}
-
-guint32 nm_ip4_config_get_num_nis_servers (NMIP4Config *config)
-{
-	g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
-
-	return NM_IP4_CONFIG_GET_PRIVATE (config)->nis_servers->len;
-}
-
 void nm_ip4_config_set_hostname (NMIP4Config *config, const char *hostname)
 {
 	g_return_if_fail (NM_IS_IP4_CONFIG (config));
@@ -292,23 +220,6 @@
 	return NM_IP4_CONFIG_GET_PRIVATE (config)->hostname;
 }
 
-void nm_ip4_config_set_nis_domain (NMIP4Config *config, const char *domain) 
-{
-	g_return_if_fail (NM_IS_IP4_CONFIG (config));
-	g_return_if_fail (domain != NULL);
-	
-	if (!strlen (domain))
-		return;
-	
-	NM_IP4_CONFIG_GET_PRIVATE (config)->nis_domain = g_strdup (domain);
-}
-
-const char *nm_ip4_config_get_nis_domain (NMIP4Config *config)
-{
-	g_return_val_if_fail( NM_IS_IP4_CONFIG (config), NULL);
-	return NM_IP4_CONFIG_GET_PRIVATE (config)->nis_domain;
-}
-
 void
 nm_ip4_config_take_route (NMIP4Config *config,
 						   NMSettingIP4Route *route)
@@ -344,6 +255,7 @@
 							 NMSettingIP4Route *new_route)
 {
 	NMIP4ConfigPrivate *priv;
+	NMSettingIP4Route *copy;
 	GSList *old;
 
 	g_return_if_fail (NM_IS_IP4_CONFIG (config));
@@ -351,9 +263,11 @@
 	priv = NM_IP4_CONFIG_GET_PRIVATE (config);
 	old = g_slist_nth (priv->routes, i);
 	g_return_if_fail (old != NULL);
-
 	g_free (old->data);
-	old->data = new_route;
+
+	copy = g_malloc0 (sizeof (NMSettingIP4Route));
+	memcpy (copy, new_route, sizeof (NMSettingIP4Route));
+	old->data = copy;
 }
 
 const NMSettingIP4Route *
@@ -565,7 +479,6 @@
 	NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
 
 	priv->nameservers = g_array_new (FALSE, TRUE, sizeof (guint32));
-	priv->nis_servers = g_array_new (FALSE, TRUE, sizeof (guint32));
 	priv->domains = g_ptr_array_new ();
 	priv->searches = g_ptr_array_new ();
 }
@@ -577,44 +490,13 @@
 
 	nm_utils_slist_free (priv->addresses, g_free);
 	g_free (priv->hostname);
-	g_free (priv->nis_domain);
 	g_array_free (priv->nameservers, TRUE);
 	g_ptr_array_free (priv->domains, TRUE);
 	g_ptr_array_free (priv->searches, TRUE);
-	g_array_free (priv->nis_servers, TRUE);
 	nm_utils_slist_free (priv->routes, g_free);
 }
 
 static void
-ip4_addresses_to_gvalue (GSList *list, GValue *value)
-{
-	GPtrArray *addresses;
-	GSList *iter;
-
-	addresses = g_ptr_array_new ();
-
-	for (iter = list; iter; iter = iter->next) {
-		NMSettingIP4Address *ip4_addr = (NMSettingIP4Address *) iter->data;
-		GArray *array;
-		const guint32 empty_val = 0;
-
-		array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
-
-		g_array_append_val (array, ip4_addr->address);
-		g_array_append_val (array, ip4_addr->prefix);
-
-		if (ip4_addr->gateway)
-			g_array_append_val (array, ip4_addr->gateway);
-		else
-			g_array_append_val (array, empty_val);
-
-		g_ptr_array_add (addresses, array);
-	}
-
-	g_value_take_boxed (value, addresses);
-}
-
-static void
 get_property (GObject *object, guint prop_id,
 			  GValue *value, GParamSpec *pspec)
 {
@@ -622,7 +504,7 @@
 
 	switch (prop_id) {
 	case PROP_ADDRESSES:
-		ip4_addresses_to_gvalue (priv->addresses, value);
+		nm_utils_ip4_addresses_to_gvalue (priv->addresses, value);
 		break;
 	case PROP_HOSTNAME:
 		g_value_set_string (value, priv->hostname);
@@ -633,14 +515,8 @@
 	case PROP_DOMAINS:
 		g_value_set_boxed (value, priv->domains);
 		break;
-	case PROP_NIS_DOMAIN:
-		g_value_set_string (value, priv->nis_domain);
-		break;
-	case PROP_NIS_SERVERS:
-		g_value_set_boxed (value, priv->nis_servers);
-		break;
 	case PROP_ROUTES:
-		ip4_addresses_to_gvalue (priv->routes, value);
+		nm_utils_ip4_routes_to_gvalue (priv->routes, value);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -688,20 +564,6 @@
 							 "Domains",
 							 DBUS_TYPE_G_ARRAY_OF_STRING,
 							 G_PARAM_READABLE));
-	g_object_class_install_property
-		(object_class, PROP_NIS_DOMAIN,
-		 g_param_spec_string (NM_IP4_CONFIG_NIS_DOMAIN,
-							  "NIS domain",
-							  "NIS domain name",
-							  NULL,
-							  G_PARAM_READABLE));
-	g_object_class_install_property
-		(object_class, PROP_NIS_SERVERS,
-		 g_param_spec_boxed (NM_IP4_CONFIG_NIS_SERVERS,
-							 "NIS servers",
-							 "NIS servers",
-							 DBUS_TYPE_G_UINT_ARRAY,
-							 G_PARAM_READABLE));
 
 	g_object_class_install_property
 		(object_class, PROP_ROUTES,

Modified: branches/mbca/src/nm-ip4-config.h
==============================================================================
--- branches/mbca/src/nm-ip4-config.h	(original)
+++ branches/mbca/src/nm-ip4-config.h	Mon Aug 18 08:30:28 2008
@@ -72,10 +72,6 @@
 guint32		nm_ip4_config_get_num_nameservers	(NMIP4Config *config);
 void			nm_ip4_config_reset_nameservers		(NMIP4Config *config);
 
-void			nm_ip4_config_add_nis_server		(NMIP4Config *config, guint32 nis_server);
-guint32		nm_ip4_config_get_nis_server		(NMIP4Config *config, guint i);
-guint32		nm_ip4_config_get_num_nis_servers	(NMIP4Config *config);
-
 void			nm_ip4_config_take_route		(NMIP4Config *config, NMSettingIP4Route *route);
 void			nm_ip4_config_add_route			(NMIP4Config *config, NMSettingIP4Route *route);
 void			nm_ip4_config_replace_route		(NMIP4Config *config, guint32 i, NMSettingIP4Route *new_route);
@@ -86,9 +82,6 @@
 void			nm_ip4_config_set_hostname		(NMIP4Config *config, const char *hostname);
 const char * 	nm_ip4_config_get_hostname		(NMIP4Config *config);
 
-void			nm_ip4_config_set_nis_domain		(NMIP4Config *config, const char *domain);
-const char *	nm_ip4_config_get_nis_domain		(NMIP4Config *config);
-
 void			nm_ip4_config_add_domain			(NMIP4Config *config, const char *domain);
 const char *	nm_ip4_config_get_domain			(NMIP4Config *config, guint i);
 guint32		nm_ip4_config_get_num_domains		(NMIP4Config *config);

Modified: branches/mbca/src/nm-netlink-monitor.c
==============================================================================
--- branches/mbca/src/nm-netlink-monitor.c	(original)
+++ branches/mbca/src/nm-netlink-monitor.c	Mon Aug 18 08:30:28 2008
@@ -434,7 +434,10 @@
 
 	/* Update the link cache with latest state */
 	if (nl_cache_refill (priv->nlh, priv->nlh_link_cache)) {
-		nm_warning ("Error updating link cache: %s", nl_geterror ());
+		g_set_error (error, NM_NETLINK_MONITOR_ERROR,
+		             NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE,
+		             _("error updating link cache: %s"),
+		             nl_geterror ());
 		return FALSE;
 	}
 
@@ -487,7 +490,7 @@
 {
 	GError *socket_error;
  
-	g_return_val_if_fail (!(io_condition & ~(NM_NETLINK_MONITOR_ERROR_CONDITIONS)), FALSE);
+	g_return_val_if_fail (io_condition & NM_NETLINK_MONITOR_ERROR_CONDITIONS, FALSE);
 
 	socket_error = g_error_new (NM_NETLINK_MONITOR_ERROR,
 	                            NM_NETLINK_MONITOR_ERROR_WAITING_FOR_SOCKET_DATA,

Modified: branches/mbca/src/nm-netlink-monitor.h
==============================================================================
--- branches/mbca/src/nm-netlink-monitor.h	(original)
+++ branches/mbca/src/nm-netlink-monitor.h	Mon Aug 18 08:30:28 2008
@@ -43,6 +43,7 @@
 	NM_NETLINK_MONITOR_ERROR_PROCESSING_MESSAGE,
 	NM_NETLINK_MONITOR_ERROR_BAD_ALLOC,
 	NM_NETLINK_MONITOR_ERROR_WAITING_FOR_SOCKET_DATA,
+	NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE
 } NMNetlinkMonitorError;
 
 typedef struct {

Modified: branches/mbca/src/nm-properties-changed-signal.c
==============================================================================
--- branches/mbca/src/nm-properties-changed-signal.c	(original)
+++ branches/mbca/src/nm-properties-changed-signal.c	Mon Aug 18 08:30:28 2008
@@ -141,6 +141,10 @@
 	PropertiesChangedInfo *info;
 	GValue *value;
 
+	/* Ignore properties that shouldn't be exported */
+	if (pspec->flags & NM_PROPERTY_PARAM_NO_EXPORT)
+		return;
+
 	info = (PropertiesChangedInfo *) g_object_get_data (object, NM_DBUS_PROPERTY_CHANGED);
 	if (!info) {
 		info = properties_changed_info_new ();

Modified: branches/mbca/src/nm-properties-changed-signal.h
==============================================================================
--- branches/mbca/src/nm-properties-changed-signal.h	(original)
+++ branches/mbca/src/nm-properties-changed-signal.h	Mon Aug 18 08:30:28 2008
@@ -5,6 +5,8 @@
 
 #include <glib-object.h>
 
+#define NM_PROPERTY_PARAM_NO_EXPORT    (1 << (0 + G_PARAM_USER_SHIFT))
+
 guint nm_properties_changed_signal_new (GObjectClass *object_class,
 								guint class_offset);
 

Modified: branches/mbca/src/ppp-manager/nm-ppp-manager.c
==============================================================================
--- branches/mbca/src/ppp-manager/nm-ppp-manager.c	(original)
+++ branches/mbca/src/ppp-manager/nm-ppp-manager.c	Mon Aug 18 08:30:28 2008
@@ -384,7 +384,7 @@
 			 */
 			priv->pending_secrets_context = context;
 			nm_ppp_manager_update_secrets (manager,
-			                               NULL, /* FIXME: pass device name */
+			                               priv->parent_iface,
 			                               username ? username : "",
 			                               password ? password : "",
 			                               NULL);
@@ -690,6 +690,8 @@
 	nm_warning ("Looks like pppd didn't initialize our dbus module");
 	nm_ppp_manager_stop (manager);
 
+	g_signal_emit (manager, signals[STATE_CHANGED], 0, NM_PPP_STATUS_DEAD);
+
 	return FALSE;
 }
 

Modified: branches/mbca/src/vpn-manager/nm-vpn-connection.c
==============================================================================
--- branches/mbca/src/vpn-manager/nm-vpn-connection.c	(original)
+++ branches/mbca/src/vpn-manager/nm-vpn-connection.c	Mon Aug 18 08:30:28 2008
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 
 /* NetworkManager -- Network link manager
  *
@@ -35,7 +35,6 @@
 #include "nm-vpn-connection.h"
 #include "nm-setting-connection.h"
 #include "nm-setting-vpn.h"
-#include "nm-setting-vpn-properties.h"
 #include "nm-setting-ip4-config.h"
 #include "nm-dbus-manager.h"
 #include "nm-manager.h"
@@ -477,7 +476,7 @@
 		    nm_vpn_connection_get_name (connection));
 
 	if (err) {
-		nm_warning ("(VPN connection '%s' could not start.  dbus says: '%s'.", 
+		nm_warning ("VPN connection '%s' failed to connect: '%s'.", 
 				  nm_vpn_connection_get_name (connection), err->message);
 		nm_vpn_connection_set_vpn_state (connection,
 		                                 NM_VPN_CONNECTION_STATE_FAILED,
@@ -660,11 +659,11 @@
 {
 	NMConnection *connection = NM_CONNECTION (user_data);
 
-	if (strcmp (key, NM_SETTING_VPN_PROPERTIES_SETTING_NAME))
+	if (strcmp (key, NM_SETTING_VPN_SETTING_NAME))
 		return;
 
 	nm_connection_update_secrets (connection,
-	                              NM_SETTING_VPN_PROPERTIES_SETTING_NAME,
+	                              NM_SETTING_VPN_SETTING_NAME,
 	                              (GHashTable *) data);
 }
 
@@ -802,9 +801,9 @@
 }
 
 static void
-connection_vpn_state_changed (NMVPNConnection *connection,
-                              NMVPNConnectionState state,
-                              NMVPNConnectionStateReason reason)
+connection_state_changed (NMVPNConnection *connection,
+                          NMVPNConnectionState state,
+                          NMVPNConnectionStateReason reason)
 {
 	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
@@ -977,7 +976,7 @@
 	g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
 
 	/* virtual methods */
-	connection_class->vpn_state_changed = connection_vpn_state_changed;
+	connection_class->vpn_state_changed = connection_state_changed;
 	object_class->get_property = get_property;
 	object_class->dispose = dispose;
 	object_class->finalize = finalize;

Modified: branches/mbca/system-settings/plugins/ifcfg-fedora/shvar.c
==============================================================================
--- branches/mbca/system-settings/plugins/ifcfg-fedora/shvar.c	(original)
+++ branches/mbca/system-settings/plugins/ifcfg-fedora/shvar.c	Mon Aug 18 08:30:28 2008
@@ -121,9 +121,13 @@
     len = strlen(s);
     if ((s[0] == '"' || s[0] == '\'') && s[0] == s[len-1]) {
 	i = len - 2;
-	memmove(s, s+1, i);
-	s[i+1] = '\0';
-	len = i;
+	if (i == 0)
+	  s[0] = '\0';
+	else {
+	  memmove(s, s+1, i);
+	  s[i+1] = '\0';
+	  len = i;
+	}
     }
     for (i = 0; i < len; i++) {
 	if (s[i] == '\\') {
@@ -291,7 +295,6 @@
 	    /* change/append line to get key= */
 	    if (s->current) s->current->data = keyValue;
 	    else s->lineList = g_list_append(s->lineList, keyValue);
-	    s->freeList = g_list_append(s->freeList, keyValue);
 	    s->modified = 1;
 	} else if (val1) {
 	    /* delete line */
@@ -307,7 +310,6 @@
 	if (val2 && !strcmp(val2, newval)) goto end;
 	/* append line */
 	s->lineList = g_list_append(s->lineList, keyValue);
-	s->freeList = g_list_append(s->freeList, keyValue);
 	s->modified = 1;
 	goto end;
     }
@@ -326,7 +328,6 @@
 	/* change line */
 	if (s->current) s->current->data = keyValue;
 	else s->lineList = g_list_append(s->lineList, keyValue);
-	s->freeList = g_list_append(s->freeList, keyValue);
 	s->modified = 1;
     }
 
@@ -387,11 +388,7 @@
     if (s->fd != -1) close(s->fd);
 
     g_free(s->arena);
-    for (s->current = s->freeList; s->current; s->current = s->current->next) {
-        g_free(s->current->data);
-    }
     g_free(s->fileName);
-    g_list_free(s->freeList);
     g_list_foreach (s->lineList, (GFunc) g_free, NULL);
     g_list_free(s->lineList); /* implicitly frees s->current */
     g_free(s);

Modified: branches/mbca/system-settings/plugins/ifcfg-fedora/shvar.h
==============================================================================
--- branches/mbca/system-settings/plugins/ifcfg-fedora/shvar.h	(original)
+++ branches/mbca/system-settings/plugins/ifcfg-fedora/shvar.h	Mon Aug 18 08:30:28 2008
@@ -42,7 +42,6 @@
 	int		fd;		/* read-only */
 	char		*arena;		/* ignore */
 	GList		*lineList;	/* read-only */
-	GList		*freeList;	/* ignore */
 	GList		*current;	/* set implicitly or explicitly,
 					   points to element of lineList */
 	shvarFile	*parent;	/* set explicitly */

Modified: branches/mbca/system-settings/plugins/ifcfg-suse/parser.c
==============================================================================
--- branches/mbca/system-settings/plugins/ifcfg-suse/parser.c	(original)
+++ branches/mbca/system-settings/plugins/ifcfg-suse/parser.c	Mon Aug 18 08:30:28 2008
@@ -118,7 +118,7 @@
 	}
 
 	if (!s_ip4->method)
-		s_ip4->method = g_strdup (NM_SETTING_IP4_CONFIG_METHOD_DHCP);
+		s_ip4->method = g_strdup (NM_SETTING_IP4_CONFIG_METHOD_AUTO);
 
 	str = svGetValue (ifcfg, "IPADDR");
 	if (str) {

Modified: branches/mbca/system-settings/plugins/keyfile/Makefile.am
==============================================================================
--- branches/mbca/system-settings/plugins/keyfile/Makefile.am	(original)
+++ branches/mbca/system-settings/plugins/keyfile/Makefile.am	Mon Aug 18 08:30:28 2008
@@ -11,6 +11,8 @@
 	writer.c \
 	writer.h
 
+keyfiledir=$(sysconfdir)/NetworkManager/system-connections
+
 libnm_settings_plugin_keyfile_la_CPPFLAGS = \
 	$(GLIB_CFLAGS) \
 	$(GMODULE_CFLAGS) \
@@ -20,7 +22,7 @@
 	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/libnm-util \
 	-I${top_srcdir}/libnm-glib \
-	-DKEYFILE_DIR=\""$(sysconfdir)/NetworkManager/system-connections"\"
+	-DKEYFILE_DIR=\""$(keyfiledir)"\"
 
 libnm_settings_plugin_keyfile_la_LDFLAGS = -module -avoid-version
 libnm_settings_plugin_keyfile_la_LIBADD = \
@@ -37,3 +39,7 @@
 libnm_settings_plugin_keyfile_la_LIBADD += \
 	$(GIO_LIBS)
 endif
+
+install-data-hook:
+	$(mkinstalldirs) -m 0755 $(DESTDIR)$(keyfiledir)
+

Modified: branches/mbca/system-settings/plugins/keyfile/nm-keyfile-connection.c
==============================================================================
--- branches/mbca/system-settings/plugins/keyfile/nm-keyfile-connection.c	(original)
+++ branches/mbca/system-settings/plugins/keyfile/nm-keyfile-connection.c	Mon Aug 18 08:30:28 2008
@@ -55,14 +55,13 @@
 static gboolean
 update (NMExportedConnection *exported,
 	   GHashTable *new_settings,
-	   GError **err)
+	   GError **error)
 {
 	gboolean success;
 
-	success = NM_EXPORTED_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->update (exported, new_settings, err);
-
+	success = NM_EXPORTED_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->update (exported, new_settings, error);
 	if (success)
-		write_connection (nm_exported_connection_get_connection (exported));
+		success = write_connection (nm_exported_connection_get_connection (exported), error);
 
 	return success;
 }

Modified: branches/mbca/system-settings/plugins/keyfile/plugin.c
==============================================================================
--- branches/mbca/system-settings/plugins/keyfile/plugin.c	(original)
+++ branches/mbca/system-settings/plugins/keyfile/plugin.c	Mon Aug 18 08:30:28 2008
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 
 #include <config.h>
 #include <sys/stat.h>
@@ -182,9 +182,11 @@
 }
 
 static gboolean
-add_connection (NMSystemConfigInterface *config, NMConnection *connection)
+add_connection (NMSystemConfigInterface *config,
+                NMConnection *connection,
+                GError **error)
 {
-	return write_connection (connection);
+	return write_connection (connection, error);
 }
 
 /* GObject */

Modified: branches/mbca/system-settings/plugins/keyfile/reader.c
==============================================================================
--- branches/mbca/system-settings/plugins/keyfile/reader.c	(original)
+++ branches/mbca/system-settings/plugins/keyfile/reader.c	Mon Aug 18 08:30:28 2008
@@ -8,6 +8,7 @@
 #include <dbus/dbus-glib.h>
 #include <nm-setting.h>
 #include <nm-setting-ip4-config.h>
+#include <nm-setting-vpn.h>
 #include <arpa/inet.h>
 #include <string.h>
 
@@ -289,6 +290,32 @@
 }
 
 static void
+read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key)
+{
+	char **keys, **iter;
+	char *value;
+
+	keys = g_key_file_get_keys (file, setting->name, NULL, NULL);
+	if (!keys || !*keys)
+		return;
+
+	for (iter = keys; *iter; iter++) {
+		value = g_key_file_get_string (file, setting->name, *iter, NULL);
+		if (!value)
+			continue;
+
+		if (NM_IS_SETTING_VPN (setting)) {
+			NMSettingVPN *s_vpn = NM_SETTING_VPN (setting);
+
+			if (strcmp (*iter, NM_SETTING_VPN_SERVICE_TYPE))
+				g_hash_table_insert (s_vpn->data, g_strdup (*iter), g_strdup (value));
+		}
+		g_free (value);
+	}
+	g_strfreev (keys);
+}
+
+static void
 read_one_setting_value (NMSetting *setting,
 				    const char *key,
 				    const GValue *value,
@@ -395,9 +422,8 @@
 
 		g_slist_free (list);
 		g_strfreev (sa);
-	} else if (type == dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) {
-		/* FIXME */
-		g_warning ("Implement me");
+	} else if (type == dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)) {
+		read_hash_of_string (file, setting, key);
 	} else if (type == DBUS_TYPE_G_UINT_ARRAY) {
 		if (!read_array_of_uint (file, setting, key)) {
 			g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'",

Modified: branches/mbca/system-settings/plugins/keyfile/writer.c
==============================================================================
--- branches/mbca/system-settings/plugins/keyfile/writer.c	(original)
+++ branches/mbca/system-settings/plugins/keyfile/writer.c	Mon Aug 18 08:30:28 2008
@@ -7,6 +7,7 @@
 #include <nm-setting.h>
 #include <nm-setting-connection.h>
 #include <nm-setting-ip4-config.h>
+#include <nm-setting-vpn.h>
 #include <nm-utils.h>
 #include <string.h>
 #include <arpa/inet.h>
@@ -141,6 +142,42 @@
 	return TRUE;
 }
 
+typedef struct {
+	GKeyFile *file;
+	const char *setting_name;
+} WriteStringHashInfo;
+
+static void
+write_hash_of_string_helper (gpointer key, gpointer data, gpointer user_data)
+{
+	WriteStringHashInfo *info = (WriteStringHashInfo *) user_data;
+	const char *property = (const char *) key;
+	const char *value = (const char *) data;
+
+	if (   !strcmp (info->setting_name, NM_SETTING_VPN_SETTING_NAME)
+	    && !strcmp (property, NM_SETTING_VPN_SERVICE_TYPE))
+		return;
+
+	g_key_file_set_string (info->file,
+	                       info->setting_name,
+	                       property,
+	                       value);
+}
+
+static void
+write_hash_of_string (GKeyFile *file,
+                      NMSetting *setting,
+                      const char *key,
+                      const GValue *value)
+{
+	GHashTable *hash = g_value_get_boxed (value);
+	WriteStringHashInfo info;
+
+	info.file = file;
+	info.setting_name = setting->name;
+	g_hash_table_foreach (hash, write_hash_of_string_helper, &info);
+}
+
 static void
 write_setting_value (NMSetting *setting,
 				 const char *key,
@@ -208,9 +245,8 @@
 			g_key_file_set_string_list (file, setting->name, key, (const gchar **const) array, i);
 			g_free (array);
 		}
-	} else if (type == dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) {
-		/* FIXME */
-		g_warning ("Implement me");
+	} else if (type == dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)) {
+		write_hash_of_string (file, setting, key, value);
 	} else if (type == DBUS_TYPE_G_UINT_ARRAY) {
 		if (!write_array_of_uint (file, setting, key, value)) {
 			g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'", 
@@ -228,7 +264,7 @@
 }
 
 gboolean
-write_connection (NMConnection *connection)
+write_connection (NMConnection *connection, GError **error)
 {
 	NMSettingConnection *s_con;
 	GKeyFile *key_file;

Modified: branches/mbca/system-settings/plugins/keyfile/writer.h
==============================================================================
--- branches/mbca/system-settings/plugins/keyfile/writer.h	(original)
+++ branches/mbca/system-settings/plugins/keyfile/writer.h	Mon Aug 18 08:30:28 2008
@@ -6,6 +6,6 @@
 #include <glib.h>
 #include <nm-connection.h>
 
-gboolean write_connection (NMConnection *connection);
+gboolean write_connection (NMConnection *connection, GError **error);
 
 #endif /* _KEYFILE_PLUGIN_WRITER_H */

Modified: branches/mbca/system-settings/src/dbus-settings.c
==============================================================================
--- branches/mbca/system-settings/src/dbus-settings.c	(original)
+++ branches/mbca/system-settings/src/dbus-settings.c	Mon Aug 18 08:30:28 2008
@@ -1,8 +1,10 @@
-/* -*- 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 system settings service
  *
  * SÃren Sandmann <sandmann daimi au dk>
+ * Dan Williams <dcbw redhat com>
+ * Tambet Ingo <tambet gmail com>
  *
  * 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
@@ -18,7 +20,8 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2007 Red Hat, Inc.
+ * (C) Copyright 2007 - 2008 Red Hat, Inc.
+ * (C) Copyright 2008 Novell, Inc.
  */
 
 #include <NetworkManager.h>
@@ -263,7 +266,9 @@
 	dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (settings_class),
 	                                 &dbus_glib_nm_settings_system_object_info);
 
-	dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, NULL, NM_TYPE_SYSCONFIG_SETTINGS_ERROR);
+	dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR,
+	                              NM_DBUS_IFACE_SETTINGS_SYSTEM,
+	                              NM_TYPE_SYSCONFIG_SETTINGS_ERROR);
 }
 
 static void
@@ -453,6 +458,8 @@
 
 	connection = nm_connection_new_from_hash (hash, &cnfh_error);
 	if (connection) {
+		GError *add_error = NULL;
+
 		/* Here's how it works:
 		   1) plugin writes a connection.
 		   2) plugin notices that a new connection is available for reading.
@@ -461,9 +468,12 @@
 		*/
 
 		success = FALSE;
-		for (iter = priv->plugins; iter && success == FALSE; iter = iter->next)
+		for (iter = priv->plugins; iter && success == FALSE; iter = iter->next) {
 			success = nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data),
-													   connection);
+													   connection, &add_error);
+			if (!success && add_error)
+				g_error_free (add_error);
+		}
 
 		g_object_unref (connection);
 
@@ -491,3 +501,4 @@
 		return TRUE;
 	}
 }
+

Modified: branches/mbca/system-settings/src/nm-system-config-interface.c
==============================================================================
--- branches/mbca/system-settings/src/nm-system-config-interface.c	(original)
+++ branches/mbca/system-settings/src/nm-system-config-interface.c	Mon Aug 18 08:30:28 2008
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /* NetworkManager -- Network link manager
  *
  * Dan Williams <dcbw redhat com>
@@ -139,7 +139,8 @@
 
 gboolean
 nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
-								   NMConnection *connection)
+                                           NMConnection *connection,
+                                           GError **error)
 {
 	gboolean success = FALSE;
 
@@ -147,7 +148,7 @@
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
 
 	if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection)
-		success = NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection);
+		success = NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection, error);
 
 	return success;
 }

Modified: branches/mbca/system-settings/src/nm-system-config-interface.h
==============================================================================
--- branches/mbca/system-settings/src/nm-system-config-interface.h	(original)
+++ branches/mbca/system-settings/src/nm-system-config-interface.h	Mon Aug 18 08:30:28 2008
@@ -60,12 +60,14 @@
 
 #define NM_SYSTEM_CONFIG_INTERFACE_NAME "name"
 #define NM_SYSTEM_CONFIG_INTERFACE_INFO "info"
+#define NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME "hostname"
 
 typedef enum {
 	NM_SYSTEM_CONFIG_INTERFACE_PROP_FIRST = 0x1000,
 
 	NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME = NM_SYSTEM_CONFIG_INTERFACE_PROP_FIRST,
 	NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
+	NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
 } NMSystemConfigInterfaceProp;
 
 
@@ -92,7 +94,7 @@
 	/*
 	 * Add a new connection.
 	 */
-	gboolean (*add_connection) (NMSystemConfigInterface *config, NMConnection *connection);
+	gboolean (*add_connection) (NMSystemConfigInterface *config, NMConnection *connection, GError **error);
 
 	/* Signals */
 
@@ -115,7 +117,8 @@
 gboolean nm_system_config_interface_supports_add (NMSystemConfigInterface *config);
 
 gboolean nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
-						    NMConnection *connection);
+                                                    NMConnection *connection,
+                                                    GError **error);
 
 G_END_DECLS
 

Modified: branches/mbca/vpn-daemons/openvpn/auth-dialog/main.c
==============================================================================
--- branches/mbca/vpn-daemons/openvpn/auth-dialog/main.c	(original)
+++ branches/mbca/vpn-daemons/openvpn/auth-dialog/main.c	Mon Aug 18 08:30:28 2008
@@ -32,6 +32,8 @@
 #include <libgnomeui/libgnomeui.h>
 #include <gconf/gconf-client.h>
 #include <gnome-keyring.h>
+#include <nm-setting-vpn.h>
+#include <nm-setting-connection.h>
 
 #include "../src/nm-openvpn-service.h"
 #include "gnome-two-password-dialog.h"
@@ -129,6 +131,7 @@
 	}
 }
 
+#define PROC_TYPE_TAG "Proc-Type: 4,ENCRYPTED"
 
 /** Checks if a key is encrypted
  * The key file is read and it is checked if it contains a line reading
@@ -140,27 +143,24 @@
 static gboolean
 pem_is_encrypted (const char *filename)
 {
-
 	GIOChannel *pem_chan;
 	char       *str = NULL;
 	gboolean encrypted = FALSE;
 
 	pem_chan = g_io_channel_new_file (filename, "r", NULL);
-
-	if ( pem_chan == NULL ) {
-		// We don't know
+	if (!pem_chan)
 		return FALSE;
-	}
 
-	while ( ! encrypted && (g_io_channel_read_line (pem_chan, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) ) {
-		if ( strstr (str, "Proc-Type: 4,ENCRYPTED") == str ) {
-			// encrypted!
+	while (g_io_channel_read_line (pem_chan, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) {
+		if (strncmp (str, PROC_TYPE_TAG, strlen (PROC_TYPE_TAG)) == 0) {
 			encrypted = TRUE;
+			break;
 		}
-
 		g_free (str);
 	}
 
+	g_io_channel_shutdown (pem_chan, FALSE, NULL);
+	g_io_channel_unref (pem_chan);
 	return encrypted;
 }
 
@@ -270,7 +270,12 @@
 		return FALSE;
 
 	for (iter = conf_list; iter; iter = iter->next) {
-		key = g_strconcat ((char *) iter->data, "/connection/type", NULL);
+		const char *path = (const char *) iter->data;
+
+		key = g_strdup_printf ("%s/%s/%s", 
+		                       path,
+		                       NM_SETTING_CONNECTION_SETTING_NAME,
+		                       NM_SETTING_CONNECTION_TYPE);
 		str = gconf_client_get_string (gconf_client, key, NULL);
 		g_free (key);
 
@@ -279,7 +284,10 @@
 			continue;
 		}
 
-		key = g_strconcat ((char *) iter->data, "/connection/id", NULL);
+		key = g_strdup_printf ("%s/%s/%s", 
+		                       path,
+		                       NM_SETTING_CONNECTION_SETTING_NAME,
+		                       NM_SETTING_CONNECTION_ID);
 		str = gconf_client_get_string (gconf_client, key, NULL);
 		g_free (key);
 
@@ -289,7 +297,7 @@
 		}
 
 		/* Woo, found the connection */
-		connection_path = g_strdup ((char *) iter->data);
+		connection_path = g_strdup (path);
 		break;
 	}
 
@@ -297,37 +305,32 @@
 	g_slist_free (conf_list);
 
 	if (connection_path) {
-		int connection_type;
+		const char *connection_type;
 
-		key = g_strconcat (connection_path, "/vpn-properties/connection-type", NULL);
-		connection_type = gconf_client_get_int (gconf_client, key, NULL);
+		key = g_strdup_printf ("%s/%s/%s", connection_path, NM_SETTING_VPN_SETTING_NAME,
+		                       NM_OPENVPN_KEY_CONNECTION_TYPE);
+		connection_type = gconf_client_get_string (gconf_client, key, NULL);
 		g_free (key);
-
-		switch (connection_type) {
-		case NM_OPENVPN_CONTYPE_PASSWORD_TLS:
-			info->need_password = TRUE;
-			/* Fall through */
-		case NM_OPENVPN_CONTYPE_TLS:
+		
+		if (   !strcmp (connection_type, NM_OPENVPN_CONTYPE_TLS)
+		    || !strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
 			success = TRUE;
 
-			key = g_strconcat (connection_path, "/vpn-properties/", NM_OPENVPN_KEY_KEY, NULL);
+			if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS))
+				info->need_password = TRUE;
+
+			key = g_strdup_printf ("%s/%s/%s", connection_path, NM_SETTING_VPN_SETTING_NAME,
+			                       NM_OPENVPN_KEY_KEY);
 			str = gconf_client_get_string (gconf_client, key, NULL);
-			g_free (key);
-			if (str) {
+			if (str)
 				info->need_certpass = pem_is_encrypted (str);
-				g_free (str);
-			}
-			break;
-		case NM_OPENVPN_CONTYPE_STATIC_KEY:
+			g_free (str);
+			g_free (key);
+		} else if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_STATIC_KEY)) {
 			success = TRUE;
-			break;
-		case NM_OPENVPN_CONTYPE_PASSWORD:
+		} else if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD)) {
 			success = TRUE;
 			info->need_password = TRUE;
-			break;
-		default:
-			/* Invalid connection type */
-			break;
 		}
 
 		g_free (connection_path);

Modified: branches/mbca/vpn-daemons/openvpn/properties/auth-helpers.c
==============================================================================
--- branches/mbca/vpn-daemons/openvpn/properties/auth-helpers.c	(original)
+++ branches/mbca/vpn-daemons/openvpn/properties/auth-helpers.c	Mon Aug 18 08:30:28 2008
@@ -30,6 +30,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <glib/gi18n-lib.h>
 
@@ -40,14 +41,14 @@
 void
 tls_pw_init_auth_widget (GladeXML *xml,
                          GtkSizeGroup *group,
-                         NMSettingVPNProperties *s_vpn_props,
-                         gint contype,
+                         NMSettingVPN *s_vpn,
+                         const char *contype,
                          const char *prefix,
                          ChangedCallback changed_cb,
                          gpointer user_data)
 {
 	GtkWidget *widget;
-	GValue *value;
+	const char *value;
 	char *tmp;
 	GtkFileFilter *filter;
 
@@ -68,13 +69,13 @@
 	                                   _("Choose a Certificate Authority certificate..."));
 	g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (changed_cb), user_data);
 
-	if (s_vpn_props && s_vpn_props->data) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_CA);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), g_value_get_string (value));
+	if (s_vpn && s_vpn->data) {
+		value = g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_CA);
+		if (value && strlen (value))
+			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
 	}
 
-	if (contype == NM_OPENVPN_CONTYPE_TLS || contype == NM_OPENVPN_CONTYPE_PASSWORD_TLS) {
+	if (!strcmp (contype, NM_OPENVPN_CONTYPE_TLS) || !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
 		tmp = g_strdup_printf ("%s_user_cert_chooser", prefix);
 		widget = glade_xml_get_widget (xml, tmp);
 		g_free (tmp);
@@ -87,10 +88,10 @@
 		                                   _("Choose your personal certificate..."));
 		g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (changed_cb), user_data);
 
-		if (s_vpn_props && s_vpn_props->data) {
-			value = g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_CERT);
-			if (value && G_VALUE_HOLDS_STRING (value))
-				gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), g_value_get_string (value));
+		if (s_vpn && s_vpn->data) {
+			value = g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_CERT);
+			if (value && strlen (value))
+				gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
 		}
 
 		tmp = g_strdup_printf ("%s_private_key_chooser", prefix);
@@ -105,23 +106,23 @@
 		                                   _("Choose your private key..."));
 		g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (changed_cb), user_data);
 
-		if (s_vpn_props && s_vpn_props->data) {
-			value = g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_KEY);
-			if (value && G_VALUE_HOLDS_STRING (value))
-				gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), g_value_get_string (value));
+		if (s_vpn && s_vpn->data) {
+			value = g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_KEY);
+			if (value && strlen (value))
+				gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
 		}
 	}
 
-	if (contype == NM_OPENVPN_CONTYPE_PASSWORD || contype == NM_OPENVPN_CONTYPE_PASSWORD_TLS) {
+	if (!strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD) || !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
 		tmp = g_strdup_printf ("%s_username_entry", prefix);
 		widget = glade_xml_get_widget (xml, tmp);
 		g_free (tmp);
 
 		gtk_size_group_add_widget (group, widget);
-		if (s_vpn_props && s_vpn_props->data) {
-			value = g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_USERNAME);
-			if (value && G_VALUE_HOLDS_STRING (value))
-				gtk_entry_set_text (GTK_ENTRY (widget), g_value_get_string (value));
+		if (s_vpn && s_vpn->data) {
+			value = g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_USERNAME);
+			if (value && strlen (value))
+				gtk_entry_set_text (GTK_ENTRY (widget), value);
 		}
 		g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (changed_cb), user_data);
 	}
@@ -133,12 +134,12 @@
 void
 sk_init_auth_widget (GladeXML *xml,
                      GtkSizeGroup *group,
-                     NMSettingVPNProperties *s_vpn_props,
+                     NMSettingVPN *s_vpn,
                      ChangedCallback changed_cb,
                      gpointer user_data)
 {
 	GtkWidget *widget;
-	GValue *value = NULL;
+	const char *value = NULL;
 	GtkListStore *store;
 	GtkTreeIter iter;
 	gint active = -1;
@@ -158,18 +159,24 @@
 	                                   _("Choose an OpenVPN static key..."));
 	g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (changed_cb), user_data);
 
-	if (s_vpn_props && s_vpn_props->data) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_SHARED_KEY);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), g_value_get_string (value));
+	if (s_vpn && s_vpn->data) {
+		value = g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_STATIC_KEY);
+		if (value && strlen (value))
+			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
 	}
 
 	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
 
-	if (s_vpn_props && s_vpn_props->data) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_SHARED_KEY_DIRECTION);
-		if (value && G_VALUE_HOLDS_INT (value))
-			direction = g_value_get_int (value);
+	if (s_vpn && s_vpn->data) {
+		value = g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_STATIC_KEY_DIRECTION);
+		if (value && strlen (value)) {
+			long int tmp;
+
+			errno = 0;
+			tmp = strtol (value, NULL, 10);
+			if (errno == 0 && (tmp == 0 || tmp == 1))
+				direction = (guint32) tmp;
+		}
 	}
 
 	gtk_list_store_append (store, &iter);
@@ -177,17 +184,13 @@
 
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter, SK_DIR_COL_NAME, "0", SK_DIR_COL_NUM, 0, -1);
-	if (value && G_VALUE_HOLDS_INT (value)) {
-		if (g_value_get_int (value) == 0)
-			active = 1;
-	}
+	if (direction == 0)
+		active = 1;
 
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter, SK_DIR_COL_NAME, "1", SK_DIR_COL_NUM, 1, -1);
-	if (value && G_VALUE_HOLDS_INT (value)) {
-		if (g_value_get_int (value) == 1)
-			active = 2;
-	}
+	if (direction == 1)
+		active = 2;
 
 	widget = glade_xml_get_widget (xml, "sk_direction_combo");
 	gtk_size_group_add_widget (group, widget);
@@ -198,6 +201,15 @@
 
 	widget = glade_xml_get_widget (xml, "sk_dir_help_label");
 	gtk_size_group_add_widget (group, widget);
+
+	widget = glade_xml_get_widget (xml, "sk_local_address_entry");
+	gtk_size_group_add_widget (group, widget);
+	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (changed_cb), user_data);
+	if (s_vpn && s_vpn->data) {
+		value = g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_LOCAL_IP);
+		if (value && strlen (value))
+			gtk_entry_set_text (GTK_ENTRY (widget), value);
+	}
 }
 
 static gboolean
@@ -256,21 +268,17 @@
 }
 
 gboolean
-auth_widget_check_validity (GladeXML *xml, gint contype, GError **error)
+auth_widget_check_validity (GladeXML *xml, const char *contype, GError **error)
 {
 	GtkWidget *widget;
-	gboolean is_valid = TRUE;
 	const char *str;
 
-	switch (contype) {
-	case NM_OPENVPN_CONTYPE_TLS:
-		is_valid = validate_tls (xml, "tls", error);
-		break;
-
-	case NM_OPENVPN_CONTYPE_PASSWORD_TLS:
-		is_valid = validate_tls (xml, "pw_tls", error);
-		if (!is_valid)
-			break;
+	if (!strcmp (contype, NM_OPENVPN_CONTYPE_TLS)) {
+		if (!validate_tls (xml, "tls", error))
+			return FALSE;
+	} else if (!strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
+		if (!validate_tls (xml, "pw_tls", error))
+			return FALSE;
 
 		widget = glade_xml_get_widget (xml, "pw_tls_username_entry");
 		str = gtk_entry_get_text (GTK_ENTRY (widget));
@@ -279,18 +287,15 @@
 			             OPENVPN_PLUGIN_UI_ERROR,
 			             OPENVPN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
 			             NM_OPENVPN_KEY_USERNAME);
-			is_valid = FALSE;
+			return FALSE;
 		}
-		break;
-
-	case NM_OPENVPN_CONTYPE_PASSWORD:
+	} else if (!strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD)) {
 		if (!validate_file_chooser (xml, "pw_ca_cert_chooser")) {
 			g_set_error (error,
 			             OPENVPN_PLUGIN_UI_ERROR,
 			             OPENVPN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
 			             NM_OPENVPN_KEY_CA);
-			is_valid = FALSE;
-			break;
+			return FALSE;
 		}
 		widget = glade_xml_get_widget (xml, "pw_username_entry");
 		str = gtk_entry_get_text (GTK_ENTRY (widget));
@@ -299,26 +304,30 @@
 			             OPENVPN_PLUGIN_UI_ERROR,
 			             OPENVPN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
 			             NM_OPENVPN_KEY_USERNAME);
-			is_valid = FALSE;
+			return FALSE;
 		}
-		break;
-
-	case NM_OPENVPN_CONTYPE_STATIC_KEY:
+	} else if (!strcmp (contype, NM_OPENVPN_CONTYPE_STATIC_KEY)) {
 		if (!validate_file_chooser (xml, "sk_key_chooser")) {
 			g_set_error (error,
 			             OPENVPN_PLUGIN_UI_ERROR,
 			             OPENVPN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
-			             NM_OPENVPN_KEY_SHARED_KEY);
-			is_valid = FALSE;
-			break;
+			             NM_OPENVPN_KEY_STATIC_KEY);
+			return FALSE;
 		}
-		break;
 
-	default:
+		widget = glade_xml_get_widget (xml, "sk_local_address_entry");
+		str = gtk_entry_get_text (GTK_ENTRY (widget));
+		if (!str || !strlen (str)) {
+			g_set_error (error,
+			             OPENVPN_PLUGIN_UI_ERROR,
+			             OPENVPN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
+			             NM_OPENVPN_KEY_LOCAL_IP);
+			return FALSE;
+		}
+	} else
 		g_assert_not_reached ();
-	}
 
-	return is_valid;
+	return TRUE;
 }
 
 static void
@@ -326,7 +335,7 @@
                          const char *key,
                          const char *prefix,
                          const char *widget_name,
-                         NMSettingVPNProperties *s_vpn_props)
+                         NMSettingVPN *s_vpn)
 {
 	GtkWidget *widget;
 	char *tmp, *filename;
@@ -335,8 +344,8 @@
 	g_return_if_fail (key != NULL);
 	g_return_if_fail (prefix != NULL);
 	g_return_if_fail (widget_name != NULL);
-	g_return_if_fail (s_vpn_props != NULL);
-	g_return_if_fail (s_vpn_props->data != NULL);
+	g_return_if_fail (s_vpn != NULL);
+	g_return_if_fail (s_vpn->data != NULL);
 
 	tmp = g_strdup_printf ("%s_%s", prefix, widget_name);
 	widget = glade_xml_get_widget (xml, tmp);
@@ -347,21 +356,21 @@
 		return;
 
 	if (strlen (filename))
-		g_hash_table_insert (s_vpn_props->data, g_strdup (key), str_to_gvalue (filename));
+		g_hash_table_insert (s_vpn->data, g_strdup (key), g_strdup (filename));
 	
 	g_free (filename);
 }
 
 static void
-update_tls (GladeXML *xml, const char *prefix, NMSettingVPNProperties *s_vpn_props)
+update_tls (GladeXML *xml, const char *prefix, NMSettingVPN *s_vpn)
 {
-	update_from_filechooser (xml, NM_OPENVPN_KEY_CA, prefix, "ca_cert_chooser", s_vpn_props);
-	update_from_filechooser (xml, NM_OPENVPN_KEY_CERT, prefix, "user_cert_chooser", s_vpn_props);
-	update_from_filechooser (xml, NM_OPENVPN_KEY_KEY, prefix, "private_key_chooser", s_vpn_props);
+	update_from_filechooser (xml, NM_OPENVPN_KEY_CA, prefix, "ca_cert_chooser", s_vpn);
+	update_from_filechooser (xml, NM_OPENVPN_KEY_CERT, prefix, "user_cert_chooser", s_vpn);
+	update_from_filechooser (xml, NM_OPENVPN_KEY_KEY, prefix, "private_key_chooser", s_vpn);
 }
 
 static void
-update_username (GladeXML *xml, const char *prefix, NMSettingVPNProperties *s_vpn_props)
+update_username (GladeXML *xml, const char *prefix, NMSettingVPN *s_vpn)
 {
 	GtkWidget *widget;
 	char *tmp;
@@ -369,8 +378,8 @@
 
 	g_return_if_fail (xml != NULL);
 	g_return_if_fail (prefix != NULL);
-	g_return_if_fail (s_vpn_props != NULL);
-	g_return_if_fail (s_vpn_props->data != NULL);
+	g_return_if_fail (s_vpn != NULL);
+	g_return_if_fail (s_vpn->data != NULL);
 
 	tmp = g_strdup_printf ("%s_username_entry", prefix);
 	widget = glade_xml_get_widget (xml, tmp);
@@ -378,38 +387,31 @@
 
 	str = gtk_entry_get_text (GTK_ENTRY (widget));
 	if (str && strlen (str)) {
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_OPENVPN_KEY_USERNAME),
-		                     str_to_gvalue (str));
+		                     g_strdup (str));
 	}
 }
 
 gboolean
 auth_widget_update_connection (GladeXML *xml,
-                               gint contype,
-                               NMSettingVPNProperties *s_vpn_props)
+                               const char *contype,
+                               NMSettingVPN *s_vpn)
 {
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	GtkWidget *widget;
 
-	switch (contype) {
-	case NM_OPENVPN_CONTYPE_TLS:
-		update_tls (xml, "tls", s_vpn_props);
-		break;
-
-	case NM_OPENVPN_CONTYPE_PASSWORD:
-		update_from_filechooser (xml, NM_OPENVPN_KEY_CA, "pw", "ca_cert_chooser", s_vpn_props);
-		update_username (xml, "pw", s_vpn_props);
-		break;
-
-	case NM_OPENVPN_CONTYPE_PASSWORD_TLS:
-		update_tls (xml, "pw_tls", s_vpn_props);
-		update_username (xml, "pw_tls", s_vpn_props);
-		break;
-
-	case NM_OPENVPN_CONTYPE_STATIC_KEY:
-		update_from_filechooser (xml, NM_OPENVPN_KEY_SHARED_KEY, "sk", "key_chooser", s_vpn_props);
+	if (!strcmp (contype, NM_OPENVPN_CONTYPE_TLS)) {
+		update_tls (xml, "tls", s_vpn);
+	} else if (!strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD)) {
+		update_from_filechooser (xml, NM_OPENVPN_KEY_CA, "pw", "ca_cert_chooser", s_vpn);
+		update_username (xml, "pw", s_vpn);
+	} else if (!strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
+		update_tls (xml, "pw_tls", s_vpn);
+		update_username (xml, "pw_tls", s_vpn);
+	} else if (!strcmp (contype, NM_OPENVPN_CONTYPE_STATIC_KEY)) {
+		update_from_filechooser (xml, NM_OPENVPN_KEY_STATIC_KEY, "sk", "key_chooser", s_vpn);
 		widget = glade_xml_get_widget (xml, "sk_direction_combo");
 		g_assert (widget);
 		model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
@@ -418,16 +420,13 @@
 
 			gtk_tree_model_get (model, &iter, SK_DIR_COL_NUM, &direction, -1);
 			if (direction > -1) {
-				g_hash_table_insert (s_vpn_props->data,
-				                     g_strdup (NM_OPENVPN_KEY_SHARED_KEY_DIRECTION),
-				                     int_to_gvalue (direction));
+				g_hash_table_insert (s_vpn->data,
+				                     g_strdup (NM_OPENVPN_KEY_STATIC_KEY_DIRECTION),
+				                     g_strdup_printf ("%d", direction));
 			}
 		}
-		break;
-
-	default:
+	} else
 		g_assert_not_reached ();
-	}
 
 	return TRUE;
 }
@@ -580,15 +579,6 @@
 	return filter;
 }
 
-static void
-nm_gvalue_destroy (gpointer data)
-{
-	GValue *value = (GValue *) data;
-
-	g_value_unset (value);
-	g_slice_free (GValue, value);
-}
-
 static const char *advanced_keys[] = {
 	NM_OPENVPN_KEY_PORT,
 	NM_OPENVPN_KEY_COMP_LZO,
@@ -604,26 +594,14 @@
 copy_values (gpointer key, gpointer data, gpointer user_data)
 {
 	GHashTable *hash = (GHashTable *) user_data;
-	GValue *value = (GValue *) data;
+	const char *value = (const char *) data;
 	const char **i;
 
 	for (i = &advanced_keys[0]; *i; i++) {
 		if (strcmp ((const char *) key, *i))
 			continue;
 
-		if (G_VALUE_HOLDS_STRING (value)) {
-			g_hash_table_insert (hash,
-			                     g_strdup ((const char *) key),
-			                     str_to_gvalue (g_value_get_string (value)));
-		} else if (G_VALUE_HOLDS_INT (value)) {
-			g_hash_table_insert (hash,
-			                     g_strdup ((const char *) key),
-			                     int_to_gvalue (g_value_get_int (value)));
-		} else if (G_VALUE_HOLDS_BOOLEAN (value)) {
-			g_hash_table_insert (hash,
-			                     g_strdup ((const char *) key),
-			                     bool_to_gvalue (g_value_get_boolean (value)));
-		}
+		g_hash_table_insert (hash, g_strdup ((const char *) key), g_strdup (value));
 	}
 }
 
@@ -632,13 +610,13 @@
                                           GError **error)
 {
 	GHashTable *hash;
-	NMSettingVPNProperties *s_vpn_props;
+	NMSettingVPN *s_vpn;
 
-	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
+	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
-	s_vpn_props = (NMSettingVPNProperties *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES);
-	if (s_vpn_props && s_vpn_props->data)
-		g_hash_table_foreach (s_vpn_props->data, copy_values, hash);
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	if (s_vpn && s_vpn->data)
+		g_hash_table_foreach (s_vpn->data, copy_values, hash);
 
 	return hash;
 }
@@ -781,13 +759,13 @@
 #define TA_DIR_COL_NUM 1
 
 GtkWidget *
-advanced_dialog_new (GHashTable *hash, int contype)
+advanced_dialog_new (GHashTable *hash, const char *contype)
 {
 	GladeXML *xml;
 	GtkWidget *dialog = NULL;
 	char *glade_file = NULL;
 	GtkWidget *widget;
-	GValue *value;
+	const char *value;
 
 	g_return_val_if_fail (hash != NULL, NULL);
 
@@ -811,12 +789,18 @@
 	g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (port_toggled_cb), xml);
 
 	value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_PORT);
-	if (value && G_VALUE_HOLDS_INT (value)) {
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+	if (value && strlen (value)) {
+		long int tmp;
 
-		widget = glade_xml_get_widget (xml, "port_spinbutton");
-		gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget),
-		                           (gdouble) g_value_get_int (value));
+		errno = 0;
+		tmp = strtol (value, NULL, 10);
+		if (errno == 0 && tmp > 0 && tmp < 65536 && tmp != 1194) {
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+
+			widget = glade_xml_get_widget (xml, "port_spinbutton");
+			gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget),
+			                           (gdouble) tmp);
+		}
 		gtk_widget_set_sensitive (widget, TRUE);
 	} else {
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
@@ -827,54 +811,46 @@
 	}
 
 	value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_COMP_LZO);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+	if (value && !strcmp (value, "yes")) {
 		widget = glade_xml_get_widget (xml, "lzo_checkbutton");
-		if (g_value_get_boolean (value))
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 	}
 
 	value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_PROTO_TCP);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+	if (value && !strcmp (value, "yes")) {
 		widget = glade_xml_get_widget (xml, "tcp_checkbutton");
-		if (g_value_get_boolean (value))
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 	}
 
 	value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TAP_DEV);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+	if (value && !strcmp (value, "yes")) {
 		widget = glade_xml_get_widget (xml, "tap_checkbutton");
-		if (g_value_get_boolean (value))
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 	}
 
-	if (contype != NM_OPENVPN_CONTYPE_TLS && contype != NM_OPENVPN_CONTYPE_PASSWORD_TLS) {
+	if (strcmp (contype, NM_OPENVPN_CONTYPE_TLS) && strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
 		widget = glade_xml_get_widget (xml, "options_notebook");
 		gtk_notebook_remove_page (GTK_NOTEBOOK (widget), 1);
 	} else {
-		char *user_cipher = NULL;
 		GtkListStore *store;
 		GtkTreeIter iter;
 		int direction = -1, active = -1;
 
 		widget = glade_xml_get_widget (xml, "cipher_combo");
 		value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_CIPHER);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			user_cipher = (char *) g_value_get_string (value);
-		populate_cipher_combo (GTK_COMBO_BOX (widget), user_cipher);
+		populate_cipher_combo (GTK_COMBO_BOX (widget), value);
 
 		widget = glade_xml_get_widget (xml, "tls_auth_checkbutton");
 		value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TA);
-		if (value && G_VALUE_HOLDS_STRING (value)) {
-			if (strlen (g_value_get_string (value)))
-				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
-		}
+		if (value && strlen (value))
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 		g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (tls_auth_toggled_cb), xml);
 		tls_auth_toggled_cb (widget, xml);
 
 		widget = glade_xml_get_widget (xml, "direction_combo");
 		value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TA_DIR);
-		if (value && G_VALUE_HOLDS_STRING (value)) {
-			direction = (int) strtol (g_value_get_string (value), NULL, 10);
+		if (value && strlen (value)) {
+			direction = (int) strtol (value, NULL, 10);
 			/* If direction is not 0 or 1, use no direction */
 			if (direction != 0 && direction != 1)
 				direction = -1;
@@ -900,9 +876,9 @@
 		gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active < 0 ? 0 : active);
 
 		value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TA);
-		if (value && G_VALUE_HOLDS_STRING (value)) {
+		if (value && strlen (value)) {
 			widget = glade_xml_get_widget (xml, "tls_auth_chooser");
-			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), g_value_get_string (value));
+			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
 		}
 	}
 
@@ -917,7 +893,7 @@
 	GHashTable *hash;
 	GtkWidget *widget;
 	GladeXML *xml;
-	int contype = NM_OPENVPN_CONTYPE_INVALID;
+	const char *contype = NULL;
 
 	g_return_val_if_fail (dialog != NULL, NULL);
 	if (error)
@@ -926,7 +902,7 @@
 	xml = g_object_get_data (G_OBJECT (dialog), "glade-xml");
 	g_return_val_if_fail (xml != NULL, NULL);
 
-	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
+	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
 	widget = glade_xml_get_widget (xml, "port_checkbutton");
 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
@@ -934,23 +910,23 @@
 
 		widget = glade_xml_get_widget (xml, "port_spinbutton");
 		port = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
-		g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_PORT), int_to_gvalue (port));
+		g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_PORT), g_strdup_printf ("%d", port));
 	}
 
 	widget = glade_xml_get_widget (xml, "lzo_checkbutton");
 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
-		g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_COMP_LZO), bool_to_gvalue (TRUE));
+		g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_COMP_LZO), g_strdup ("yes"));
 
 	widget = glade_xml_get_widget (xml, "tcp_checkbutton");
 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
-		g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_PROTO_TCP), bool_to_gvalue (TRUE));
+		g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_PROTO_TCP), g_strdup ("yes"));
 
 	widget = glade_xml_get_widget (xml, "tap_checkbutton");
 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
-		g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_TAP_DEV), bool_to_gvalue (TRUE));
+		g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_TAP_DEV), g_strdup ("yes"));
 
-	contype = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), "connection-type"));
-	if (contype == NM_OPENVPN_CONTYPE_TLS || contype == NM_OPENVPN_CONTYPE_PASSWORD_TLS) {
+	contype = g_object_get_data (G_OBJECT (dialog), "connection-type");
+	if (!strcmp (contype, NM_OPENVPN_CONTYPE_TLS) || !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
 		GtkTreeModel *model;
 		GtkTreeIter iter;
 
@@ -964,8 +940,7 @@
 			                    TLS_CIPHER_COL_NAME, &cipher,
 			                    TLS_CIPHER_COL_DEFAULT, &is_default, -1);
 			if (!is_default && cipher) {
-				g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_CIPHER),
-				                     str_to_gvalue (cipher));
+				g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_CIPHER), g_strdup (cipher));
 			}
 		}
 		
@@ -976,8 +951,7 @@
 			widget = glade_xml_get_widget (xml, "tls_auth_chooser");
 			filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
 			if (filename && strlen (filename)) {
-				g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_TA),
-				                     str_to_gvalue (filename));
+				g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_TA), g_strdup (filename));
 			}
 			g_free (filename);
 
@@ -988,11 +962,8 @@
 
 				gtk_tree_model_get (model, &iter, TA_DIR_COL_NUM, &direction, -1);
 				if (direction >= 0) {
-					char str_dir[2] = { '0', '\0' };
-
-					str_dir[0] = (direction == 0) ? '0' : '1';
 					g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_TA_DIR),
-					                     str_to_gvalue (str_dir));					
+					                     g_strdup_printf ("%d", direction));					
 				}
 			}
 		}

Modified: branches/mbca/vpn-daemons/openvpn/properties/auth-helpers.h
==============================================================================
--- branches/mbca/vpn-daemons/openvpn/properties/auth-helpers.h	(original)
+++ branches/mbca/vpn-daemons/openvpn/properties/auth-helpers.h	Mon Aug 18 08:30:28 2008
@@ -28,35 +28,35 @@
 #include <glade/glade.h>
 
 #include <nm-connection.h>
-#include <nm-setting-vpn-properties.h>
+#include <nm-setting-vpn.h>
 
 typedef void (*ChangedCallback) (GtkWidget *widget, gpointer user_data);
 
 void tls_pw_init_auth_widget (GladeXML *xml,
                               GtkSizeGroup *group,
-                              NMSettingVPNProperties *s_vpn_props,
-                              gint contype,
+                              NMSettingVPN *s_vpn,
+                              const char *contype,
                               const char *prefix,
                               ChangedCallback changed_cb,
                               gpointer user_data);
 
 void sk_init_auth_widget (GladeXML *xml,
                           GtkSizeGroup *group,
-                          NMSettingVPNProperties *s_vpn_props,
+                          NMSettingVPN *s_vpn,
                           ChangedCallback changed_cb,
                           gpointer user_data);
 
-gboolean auth_widget_check_validity (GladeXML *xml, gint contype, GError **error);
+gboolean auth_widget_check_validity (GladeXML *xml, const char *contype, GError **error);
 
 gboolean auth_widget_update_connection (GladeXML *xml,
-                                        gint contype,
-                                        NMSettingVPNProperties *s_vpn_props);
+                                        const char *contype,
+                                        NMSettingVPN *s_vpn);
 
 GtkFileFilter *tls_file_chooser_filter_new (void);
 
 GtkFileFilter *sk_file_chooser_filter_new (void);
 
-GtkWidget *advanced_dialog_new (GHashTable *hash, int contype);
+GtkWidget *advanced_dialog_new (GHashTable *hash, const char *contype);
 
 GHashTable *advanced_dialog_new_hash_from_connection (NMConnection *connection, GError **error);
 

Modified: branches/mbca/vpn-daemons/openvpn/properties/import-export.c
==============================================================================
--- branches/mbca/vpn-daemons/openvpn/properties/import-export.c	(original)
+++ branches/mbca/vpn-daemons/openvpn/properties/import-export.c	Mon Aug 18 08:30:28 2008
@@ -35,7 +35,6 @@
 #include <glib/gi18n-lib.h>
 
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 #include <nm-setting-connection.h>
 #include <nm-setting-ip4-config.h>
 
@@ -104,7 +103,7 @@
 	if (leftover && *file)
 		*leftover = file + 1;
 
-	g_hash_table_insert (hash, g_strdup (key), str_to_gvalue (unquoted));
+	g_hash_table_insert (hash, g_strdup (key), g_strdup (unquoted));
 	g_free (unquoted);
 
 out:
@@ -143,9 +142,12 @@
 
 	errno = 0;
 	direction = strtol (leftover, NULL, 10);
-	if ((errno == 0) && ((direction == 0) || (direction == 1)))
-		g_hash_table_insert (hash, g_strdup (key), int_to_gvalue (direction));
-	else
+	if (errno == 0) {
+		if (direction == 0)
+			g_hash_table_insert (hash, g_strdup (key), g_strdup ("0"));
+		else if (direction == 1)
+			g_hash_table_insert (hash, g_strdup (key), g_strdup ("1"));
+	} else
 		g_warning ("%s: unknown %s direction '%s'", __func__, tag, leftover);
 }
 
@@ -155,12 +157,11 @@
 	NMConnection *connection = NULL;
 	NMSettingConnection *s_con;
 	NMSettingVPN *s_vpn;
-	NMSettingVPNProperties *s_vpn_props;
 	char *last_dot;
 	char **line;
 	gboolean have_client = FALSE, have_remote = FALSE;
 	gboolean have_pass = FALSE, have_sk = FALSE;
-	int ctype = NM_OPENVPN_CONTYPE_INVALID;
+	const char *ctype = NULL;
 
 	connection = nm_connection_new ();
 	s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
@@ -168,10 +169,6 @@
 
 	s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
 	s_vpn->service_type = g_strdup (NM_DBUS_SERVICE_OPENVPN);
-	nm_connection_add_setting (connection, NM_SETTING (s_vpn));
-
-	s_vpn_props = NM_SETTING_VPN_PROPERTIES (nm_setting_vpn_properties_new ());
-	nm_connection_add_setting (connection, NM_SETTING (s_vpn_props));
 
 	s_con->id = g_path_get_basename (path);
 	last_dot = strrchr (s_con->id, '.');
@@ -195,9 +192,9 @@
 			if (strstr (*line, "tun")) {
 				/* ignore; default is tun */
 			} else if (strstr (*line, "tap")) {
-				g_hash_table_insert (s_vpn_props->data,
+				g_hash_table_insert (s_vpn->data,
 				                     g_strdup (NM_OPENVPN_KEY_TAP_DEV),
-				                     bool_to_gvalue (TRUE));
+				                     g_strdup ("yes"));
 			} else
 				g_warning ("%s: unknown dev option '%s'", __func__, *line);
 
@@ -208,9 +205,9 @@
 			if (strstr (*line, "udp")) {
 				/* ignore; udp is default */
 			} else if (strstr (*line, "tcp")) {
-				g_hash_table_insert (s_vpn_props->data,
+				g_hash_table_insert (s_vpn->data,
 				                     g_strdup (NM_OPENVPN_KEY_PROTO_TCP),
-				                     bool_to_gvalue (TRUE));
+				                     g_strdup ("yes"));
 			} else
 				g_warning ("%s: unknown proto option '%s'", __func__, *line);
 
@@ -218,9 +215,9 @@
 		}
 
 		if (!strncmp (*line, COMP_TAG, strlen (COMP_TAG))) {
-			g_hash_table_insert (s_vpn_props->data,
+			g_hash_table_insert (s_vpn->data,
 			                     g_strdup (NM_OPENVPN_KEY_COMP_LZO),
-			                     bool_to_gvalue (TRUE));
+			                     g_strdup ("yes"));
 			continue;
 		}
 
@@ -230,9 +227,9 @@
 				continue;
 
 			if (g_strv_length (items) >= 1) {
-				g_hash_table_insert (s_vpn_props->data,
+				g_hash_table_insert (s_vpn->data,
 				                     g_strdup (NM_OPENVPN_KEY_REMOTE),
-				                     str_to_gvalue (items[0]));
+				                     g_strdup (items[0]));
 				have_remote = TRUE;
 
 				if (g_strv_length (items) >= 2) {
@@ -241,44 +238,44 @@
 					errno = 0;
 					port = strtol (items[1], NULL, 10);
 					if ((errno == 0) && (port > 0) && (port < 65536)) {
-						g_hash_table_insert (s_vpn_props->data,
+						g_hash_table_insert (s_vpn->data,
 						                     g_strdup (NM_OPENVPN_KEY_PORT),
-						                     int_to_gvalue (port));
+						                     g_strdup_printf ("%d", (guint32) port));
 					} else
 						g_warning ("%s: invalid remote port in option '%s'", __func__, *line);
 				}
 			}
 			g_strfreev (items);
 
-			if (!g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_REMOTE))
+			if (!g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_REMOTE))
 				g_warning ("%s: unknown remote option '%s'", __func__, *line);
 			continue;
 		}
 
-		if (handle_path_item (*line, CA_TAG, NM_OPENVPN_KEY_CA, s_vpn_props->data, NULL))
+		if (handle_path_item (*line, CA_TAG, NM_OPENVPN_KEY_CA, s_vpn->data, NULL))
 			continue;
 
-		if (handle_path_item (*line, CERT_TAG, NM_OPENVPN_KEY_CERT, s_vpn_props->data, NULL))
+		if (handle_path_item (*line, CERT_TAG, NM_OPENVPN_KEY_CERT, s_vpn->data, NULL))
 			continue;
 
-		if (handle_path_item (*line, KEY_TAG, NM_OPENVPN_KEY_KEY, s_vpn_props->data, NULL))
+		if (handle_path_item (*line, KEY_TAG, NM_OPENVPN_KEY_KEY, s_vpn->data, NULL))
 			continue;
 
-		if (handle_path_item (*line, SECRET_TAG, NM_OPENVPN_KEY_SHARED_KEY,
-		                      s_vpn_props->data, &leftover)) {
+		if (handle_path_item (*line, SECRET_TAG, NM_OPENVPN_KEY_STATIC_KEY,
+		                      s_vpn->data, &leftover)) {
 			handle_direction ("secret",
-			                  NM_OPENVPN_KEY_SHARED_KEY_DIRECTION,
+			                  NM_OPENVPN_KEY_STATIC_KEY_DIRECTION,
 			                  leftover,
-			                  s_vpn_props->data);
+			                  s_vpn->data);
 			continue;
 		}
 
 		if (handle_path_item (*line, TLS_AUTH_TAG, NM_OPENVPN_KEY_TA,
-		                      s_vpn_props->data, &leftover)) {
+		                      s_vpn->data, &leftover)) {
 			handle_direction ("tls-auth",
 			                  NM_OPENVPN_KEY_TA_DIR,
 			                  leftover,
-			                  s_vpn_props->data);
+			                  s_vpn->data);
 			continue;
 		}
 
@@ -288,9 +285,9 @@
 				continue;
 
 			if (g_strv_length (items)) {
-				g_hash_table_insert (s_vpn_props->data,
+				g_hash_table_insert (s_vpn->data,
 				                     g_strdup (NM_OPENVPN_KEY_CIPHER),
-				                     str_to_gvalue (items[0]));
+				                     g_strdup (items[0]));
 			}
 			g_strfreev (items);
 			continue;
@@ -302,12 +299,12 @@
 				continue;
 
 			if (g_strv_length (items) == 2) {
-				g_hash_table_insert (s_vpn_props->data,
+				g_hash_table_insert (s_vpn->data,
 				                     g_strdup (NM_OPENVPN_KEY_LOCAL_IP),
-				                     str_to_gvalue (items[0]));
-				g_hash_table_insert (s_vpn_props->data,
+				                     g_strdup (items[0]));
+				g_hash_table_insert (s_vpn->data,
 				                     g_strdup (NM_OPENVPN_KEY_REMOTE_IP),
-				                     str_to_gvalue (items[1]));
+				                     g_strdup (items[1]));
 			} else
 				g_warning ("%s: unknown ifconfig option '%s'", __func__, *line);
 			g_strfreev (items);
@@ -318,7 +315,7 @@
 			have_pass = TRUE;
 	}
 
-	if (g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_SHARED_KEY))
+	if (g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_STATIC_KEY))
 		have_sk = TRUE;
 
 	if (!have_client && !have_sk) {
@@ -338,12 +335,12 @@
 	} else {
 		gboolean have_certs = FALSE, have_ca = FALSE;
 
-		if (g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_CA))
+		if (g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_CA))
 			have_ca = TRUE;
 
 		if (   have_ca
-		    && g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_CERT)
-		    && g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_KEY))
+		    && g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_CERT)
+		    && g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_KEY))
 			have_certs = TRUE;
 
 		/* Determine connection type */
@@ -357,14 +354,15 @@
 		} else if (have_sk)
 			ctype = NM_OPENVPN_CONTYPE_STATIC_KEY;
 
-		if (ctype == NM_OPENVPN_CONTYPE_INVALID)
+		if (!ctype)
 			ctype = NM_OPENVPN_CONTYPE_TLS;
 
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_OPENVPN_KEY_CONNECTION_TYPE),
-		                     int_to_gvalue (ctype));
+		                     g_strdup (ctype));
 	}
 
+	nm_connection_add_setting (connection, NM_SETTING (s_vpn));
 	return connection;
 }
 
@@ -375,4 +373,3 @@
 }
 
 
-

Modified: branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn-dialog.glade
==============================================================================
--- branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn-dialog.glade	(original)
+++ branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn-dialog.glade	Mon Aug 18 08:30:28 2008
@@ -241,7 +241,7 @@
                         <child>
                           <widget class="GtkLabel" id="label14">
                             <property name="visible">True</property>
-                            <property name="label" translatable="yes">page 1</property>
+                            <property name="label">page 1</property>
                           </widget>
                           <packing>
                             <property name="type">tab</property>
@@ -322,7 +322,7 @@
                         <child>
                           <widget class="GtkLabel" id="label15">
                             <property name="visible">True</property>
-                            <property name="label" translatable="yes">page 2</property>
+                            <property name="label">page 2</property>
                           </widget>
                           <packing>
                             <property name="type">tab</property>
@@ -466,7 +466,7 @@
                         <child>
                           <widget class="GtkLabel" id="label16">
                             <property name="visible">True</property>
-                            <property name="label" translatable="yes">page 3</property>
+                            <property name="label">page 3</property>
                           </widget>
                           <packing>
                             <property name="type">tab</property>
@@ -477,7 +477,7 @@
                         <child>
                           <widget class="GtkTable" id="table6">
                             <property name="visible">True</property>
-                            <property name="n_rows">3</property>
+                            <property name="n_rows">4</property>
                             <property name="n_columns">2</property>
                             <property name="column_spacing">6</property>
                             <property name="row_spacing">6</property>
@@ -566,6 +566,36 @@
                                 <property name="y_options"></property>
                               </packing>
                             </child>
+                            <child>
+                              <widget class="GtkLabel" id="label20">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">Local IP Address:</property>
+                              </widget>
+                              <packing>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkAlignment" id="alignment18">
+                                <property name="visible">True</property>
+                                <property name="xalign">1</property>
+                                <property name="xscale">0</property>
+                                <child>
+                                  <widget class="GtkEntry" id="sk_local_address_entry">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                  </widget>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
                           </widget>
                           <packing>
                             <property name="position">3</property>
@@ -574,7 +604,7 @@
                         <child>
                           <widget class="GtkLabel" id="label17">
                             <property name="visible">True</property>
-                            <property name="label" translatable="yes">page 4</property>
+                            <property name="label">page 4</property>
                           </widget>
                           <packing>
                             <property name="type">tab</property>
@@ -786,6 +816,9 @@
                     <property name="column_spacing">12</property>
                     <property name="row_spacing">6</property>
                     <child>
+                      <placeholder/>
+                    </child>
+                    <child>
                       <widget class="GtkLabel" id="tls_auth_label">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
@@ -814,9 +847,6 @@
                       </packing>
                     </child>
                     <child>
-                      <placeholder/>
-                    </child>
-                    <child>
                       <widget class="GtkAlignment" id="alignment19">
                         <property name="visible">True</property>
                         <property name="xalign">1</property>
@@ -925,7 +955,7 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="label">gtk-cancel</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">-6</property>
               </widget>
@@ -935,7 +965,7 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="label">gtk-ok</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">-5</property>
               </widget>

Modified: branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn.c
==============================================================================
--- branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn.c	(original)
+++ branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn.c	Mon Aug 18 08:30:28 2008
@@ -41,7 +41,6 @@
 
 #include <nm-vpn-plugin-ui-interface.h>
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 #include <nm-setting-connection.h>
 #include <nm-setting-ip4-config.h>
 
@@ -133,7 +132,7 @@
 	const char *str;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
-	gint contype = NM_OPENVPN_CONTYPE_INVALID;
+	const char *contype = NULL;
 
 	widget = glade_xml_get_widget (priv->xml, "gateway_entry");
 	str = gtk_entry_get_text (GTK_ENTRY (widget));
@@ -226,7 +225,7 @@
 	GtkWidget *dialog, *toplevel, *widget;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
-	int contype = NM_OPENVPN_CONTYPE_INVALID;
+	const char *contype = NULL;
 
 	toplevel = gtk_widget_get_toplevel (priv->widget);
 	g_return_if_fail (GTK_WIDGET_TOPLEVEL (toplevel));
@@ -259,15 +258,15 @@
 init_plugin_ui (OpenvpnPluginUiWidget *self, NMConnection *connection, GError **error)
 {
 	OpenvpnPluginUiWidgetPrivate *priv = OPENVPN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
-	NMSettingVPNProperties *s_vpn_props;
+	NMSettingVPN *s_vpn;
 	GtkWidget *widget;
 	GtkListStore *store;
 	GtkTreeIter iter;
 	int active = -1;
-	GValue *value;
-	gint contype = NM_OPENVPN_CONTYPE_TLS;
+	const char *value;
+	const char *contype = NM_OPENVPN_CONTYPE_TLS;
 
-	s_vpn_props = (NMSettingVPNProperties *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES);
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
 
 	priv->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
@@ -275,10 +274,10 @@
 	if (!widget)
 		return FALSE;
 	gtk_size_group_add_widget (priv->group, widget);
-	if (s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_REMOTE);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			gtk_entry_set_text (GTK_ENTRY (widget), g_value_get_string (value));
+	if (s_vpn) {
+		value = g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_REMOTE);
+		if (value)
+			gtk_entry_set_text (GTK_ENTRY (widget), value);
 	}
 	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 
@@ -287,19 +286,22 @@
 		return FALSE;
 	gtk_size_group_add_widget (priv->group, widget);
 
-	store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
+	store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
 
-	if (s_vpn_props && s_vpn_props->data) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_CONNECTION_TYPE);
-		if (value && G_VALUE_HOLDS_INT (value)) {
-			contype = g_value_get_int (value);
-			if ((contype < NM_OPENVPN_CONTYPE_TLS) || (contype > NM_OPENVPN_CONTYPE_PASSWORD_TLS))
+	if (s_vpn && s_vpn->data) {
+		contype = g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_CONNECTION_TYPE);
+		if (contype) {
+			if (   strcmp (contype, NM_OPENVPN_CONTYPE_TLS)
+			    && strcmp (contype, NM_OPENVPN_CONTYPE_STATIC_KEY)
+			    && strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD)
+			    && strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS))
 				contype = NM_OPENVPN_CONTYPE_TLS;
-		}
+		} else
+			contype = NM_OPENVPN_CONTYPE_TLS;
 	}
 
 	/* TLS auth widget */
-	tls_pw_init_auth_widget (priv->xml, priv->group, s_vpn_props,
+	tls_pw_init_auth_widget (priv->xml, priv->group, s_vpn,
 	                         NM_OPENVPN_CONTYPE_TLS, "tls",
 	                         stuff_changed_cb, self);
 
@@ -311,7 +313,7 @@
 	                    -1);
 
 	/* Password auth widget */
-	tls_pw_init_auth_widget (priv->xml, priv->group, s_vpn_props,
+	tls_pw_init_auth_widget (priv->xml, priv->group, s_vpn,
 	                         NM_OPENVPN_CONTYPE_PASSWORD, "pw",
 	                         stuff_changed_cb, self);
 
@@ -321,11 +323,11 @@
 	                    COL_AUTH_PAGE, 1,
 	                    COL_AUTH_TYPE, NM_OPENVPN_CONTYPE_PASSWORD,
 	                    -1);
-	if ((active < 0) && (contype == NM_OPENVPN_CONTYPE_PASSWORD))
+	if ((active < 0) && !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD))
 		active = 1;
 
 	/* Password+TLS auth widget */
-	tls_pw_init_auth_widget (priv->xml, priv->group, s_vpn_props,
+	tls_pw_init_auth_widget (priv->xml, priv->group, s_vpn,
 	                         NM_OPENVPN_CONTYPE_PASSWORD_TLS, "pw_tls",
 	                         stuff_changed_cb, self);
 
@@ -335,11 +337,11 @@
 	                    COL_AUTH_PAGE, 2,
 	                    COL_AUTH_TYPE, NM_OPENVPN_CONTYPE_PASSWORD_TLS,
 	                    -1);
-	if ((active < 0) && (contype == NM_OPENVPN_CONTYPE_PASSWORD_TLS))
+	if ((active < 0) && !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS))
 		active = 2;
 
 	/* Static key auth widget */
-	sk_init_auth_widget (priv->xml, priv->group, s_vpn_props, stuff_changed_cb, self);
+	sk_init_auth_widget (priv->xml, priv->group, s_vpn, stuff_changed_cb, self);
 
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter,
@@ -347,7 +349,7 @@
 	                    COL_AUTH_PAGE, 3,
 	                    COL_AUTH_TYPE, NM_OPENVPN_CONTYPE_STATIC_KEY,
 	                    -1);
-	if ((active < 0) && (contype == NM_OPENVPN_CONTYPE_STATIC_KEY))
+	if ((active < 0) && !strcmp (contype, NM_OPENVPN_CONTYPE_STATIC_KEY))
 		active = 3;
 
 	gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
@@ -370,64 +372,13 @@
 	return G_OBJECT (priv->widget);
 }
 
-GValue *
-str_to_gvalue (const char *str)
-{
-	GValue *value;
-
-	value = g_slice_new0 (GValue);
-	g_value_init (value, G_TYPE_STRING);
-	g_value_set_string (value, str);
-
-	return value;
-}
-
-GValue *
-bool_to_gvalue (gboolean b)
-{
-	GValue *value;
-
-	value = g_slice_new0 (GValue);
-	g_value_init (value, G_TYPE_BOOLEAN);
-	g_value_set_boolean (value, b);
-
-	return value;
-}
-
-GValue *
-int_to_gvalue (gint i)
-{
-	GValue *value;
-
-	value = g_slice_new0 (GValue);
-	g_value_init (value, G_TYPE_INT);
-	g_value_set_int (value, i);
-
-	return value;
-}
-
 static void
 hash_copy_advanced (gpointer key, gpointer data, gpointer user_data)
 {
 	GHashTable *hash = (GHashTable *) user_data;
-	GValue *value = (GValue *) data;
+	const char *value = (const char *) data;
 
-	if (G_VALUE_HOLDS_STRING (value)) {
-		g_hash_table_insert (hash,
-		                     g_strdup ((const char *) key),
-		                     str_to_gvalue (g_value_get_string (value)));
-	} else if (G_VALUE_HOLDS_INT (value)) {
-		g_hash_table_insert (hash,
-		                     g_strdup ((const char *) key),
-		                     int_to_gvalue (g_value_get_int (value)));
-	} else if (G_VALUE_HOLDS_BOOLEAN (value)) {
-		g_hash_table_insert (hash,
-		                     g_strdup ((const char *) key),
-		                     bool_to_gvalue (g_value_get_boolean (value)));
-	} else {
-		g_warning ("%s: unhandled key '%s' of type '%s'",
-		           __func__, (const char *) key, G_VALUE_TYPE_NAME (value));
-	}
+	g_hash_table_insert (hash, g_strdup ((const char *) key), g_strdup (value));
 }
 
 static gboolean
@@ -438,55 +389,42 @@
 	OpenvpnPluginUiWidget *self = OPENVPN_PLUGIN_UI_WIDGET (iface);
 	OpenvpnPluginUiWidgetPrivate *priv = OPENVPN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
 	NMSettingVPN *s_vpn;
-	NMSettingVPNProperties *s_vpn_props;
 	GtkWidget *widget;
 	char *str;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	gboolean valid = FALSE;
-	int auth_type = NM_OPENVPN_CONTYPE_INVALID;
+	const char *auth_type = NULL;
 
 	if (!check_validity (self, error))
 		return FALSE;
 
 	s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
 	s_vpn->service_type = g_strdup (NM_DBUS_SERVICE_OPENVPN);
-	nm_connection_add_setting (connection, NM_SETTING (s_vpn));
-
-	s_vpn_props = NM_SETTING_VPN_PROPERTIES (nm_setting_vpn_properties_new ());
 
 	/* Gateway */
 	widget = glade_xml_get_widget (priv->xml, "gateway_entry");
 	str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
 	if (str && strlen (str)) {
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_OPENVPN_KEY_REMOTE),
-		                     str_to_gvalue (str));
+		                     g_strdup (str));
 	}
 
 	widget = glade_xml_get_widget (priv->xml, "auth_combo");
 	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
 	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)) {
 		gtk_tree_model_get (model, &iter, COL_AUTH_TYPE, &auth_type, -1);
-		if (   (auth_type > NM_OPENVPN_CONTYPE_INVALID)
-		    && (auth_type <= NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
-			g_hash_table_insert (s_vpn_props->data,
-			                     g_strdup (NM_OPENVPN_KEY_CONNECTION_TYPE),
-			                     int_to_gvalue (auth_type));
-			auth_widget_update_connection (priv->xml, auth_type, s_vpn_props);
-		} else {
-			g_set_error (error,
-			             OPENVPN_PLUGIN_UI_ERROR,
-			             OPENVPN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
-			             NM_OPENVPN_KEY_CONNECTION_TYPE);
-			goto done;
-		}
+		g_hash_table_insert (s_vpn->data,
+		                     g_strdup (NM_OPENVPN_KEY_CONNECTION_TYPE),
+		                     g_strdup (auth_type));
+		auth_widget_update_connection (priv->xml, auth_type, s_vpn);
 	}
 
 	if (priv->advanced)
-		g_hash_table_foreach (priv->advanced, hash_copy_advanced, s_vpn_props->data);
+		g_hash_table_foreach (priv->advanced, hash_copy_advanced, s_vpn->data);
 
-	nm_connection_add_setting (connection, NM_SETTING (s_vpn_props));
+	nm_connection_add_setting (connection, NM_SETTING (s_vpn));
 	valid = TRUE;
 
 done:

Modified: branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn.h
==============================================================================
--- branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn.h	(original)
+++ branches/mbca/vpn-daemons/openvpn/properties/nm-openvpn.h	Mon Aug 18 08:30:28 2008
@@ -82,11 +82,5 @@
 
 GType openvpn_plugin_ui_widget_get_type (void);
 
-GValue *int_to_gvalue (gint i);
-
-GValue *bool_to_gvalue (gboolean b);
-
-GValue *str_to_gvalue (const char *str);
-
 #endif	/* _NM_OPENVPN_H_ */
 

Modified: branches/mbca/vpn-daemons/openvpn/src/nm-openvpn-service.c
==============================================================================
--- branches/mbca/vpn-daemons/openvpn/src/nm-openvpn-service.c	(original)
+++ branches/mbca/vpn-daemons/openvpn/src/nm-openvpn-service.c	Mon Aug 18 08:30:28 2008
@@ -1,8 +1,8 @@
-/* -*- 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 -*- */
 /* nm-openvpn-service - openvpn integration with NetworkManager
  *
  * Tim Niemueller <tim niemueller de>
- * Based on work by Dan Williams <dcbw redhat com>
+ * Dan Williams <dcbw redhat com>
  *
  * 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
@@ -44,11 +44,11 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <ctype.h>
+#include <errno.h>
 
 #include <NetworkManager.h>
 #include <NetworkManagerVPN.h>
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 
 #include "nm-openvpn-service.h"
 #include "nm-utils.h"
@@ -63,9 +63,6 @@
 	char *username;
 	char *password;
 	char *certpass;
-	gint child_stdin_fd;
-	gint child_stdout_fd;
-	gint child_stderr_fd;
 	GIOChannel *socket_channel;
 	guint socket_channel_eventid;
 } NMOpenvpnPluginIOData;
@@ -80,39 +77,59 @@
 typedef struct {
 	const char *name;
 	GType type;
+	gint int_min;
+	gint int_max;
+	gboolean address;
 } ValidProperty;
 
 static ValidProperty valid_properties[] = {
-	{ NM_OPENVPN_KEY_CA,                   G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_CERT,                 G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_CIPHER,               G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_COMP_LZO,             G_TYPE_BOOLEAN },
-	{ NM_OPENVPN_KEY_CONNECTION_TYPE,      G_TYPE_INT },
-	{ NM_OPENVPN_KEY_TAP_DEV,              G_TYPE_BOOLEAN },
-	{ NM_OPENVPN_KEY_KEY,                  G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_LOCAL_IP,             G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_PROTO_TCP,            G_TYPE_BOOLEAN },
-	{ NM_OPENVPN_KEY_PORT,                 G_TYPE_INT },
-	{ NM_OPENVPN_KEY_REMOTE,               G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_REMOTE_IP,            G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_SHARED_KEY,           G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_SHARED_KEY_DIRECTION, G_TYPE_INT },
-	{ NM_OPENVPN_KEY_TA,                   G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_TA_DIR,               G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_USERNAME,             G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_PASSWORD,             G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_CERTPASS,             G_TYPE_STRING },
-	{ NM_OPENVPN_KEY_NOSECRET,             G_TYPE_STRING },
-	{ NULL,                                G_TYPE_NONE }
+	{ NM_OPENVPN_KEY_CA,                   G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_CERT,                 G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_CIPHER,               G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_COMP_LZO,             G_TYPE_BOOLEAN, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_CONNECTION_TYPE,      G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_TAP_DEV,              G_TYPE_BOOLEAN, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_KEY,                  G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_LOCAL_IP,             G_TYPE_STRING, 0, 0, TRUE },
+	{ NM_OPENVPN_KEY_PROTO_TCP,            G_TYPE_BOOLEAN, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_PORT,                 G_TYPE_INT, 1, 65535, FALSE },
+	{ NM_OPENVPN_KEY_REMOTE,               G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_REMOTE_IP,            G_TYPE_STRING, 0, 0, TRUE },
+	{ NM_OPENVPN_KEY_STATIC_KEY,           G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_STATIC_KEY_DIRECTION, G_TYPE_INT, 0, 1, FALSE },
+	{ NM_OPENVPN_KEY_TA,                   G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_TA_DIR,               G_TYPE_INT, 0, 1, FALSE },
+	{ NM_OPENVPN_KEY_USERNAME,             G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_PASSWORD,             G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_CERTPASS,             G_TYPE_STRING, 0, 0, FALSE },
+	{ NM_OPENVPN_KEY_NOSECRET,             G_TYPE_STRING, 0, 0, FALSE },
+	{ NULL,                                G_TYPE_NONE, FALSE }
 };
 
+static gboolean
+validate_address (const char *address)
+{
+	const char *p = address;
+
+	if (!address || !strlen (address))
+		return FALSE;
+
+	/* Ensure it's a valid DNS name or IP address */
+	while (*p) {
+		if (!isalnum (*p) && (*p != '-') && (*p != '.'))
+			return FALSE;
+		p++;
+	}
+	return TRUE;
+}
+
 static void
-validate_one_property (gpointer key, gpointer val, gpointer user_data)
+validate_one_property (gpointer key, gpointer value, gpointer user_data)
 {
-	gboolean *failed = (gboolean *) user_data;
+	GError **error = (GError **) user_data;
 	int i;
 
-	if (*failed)
+	if (*error)
 		return;
 
 	/* 'name' is the setting name; always allowed but unused */
@@ -121,27 +138,79 @@
 
 	for (i = 0; valid_properties[i].name; i++) {
 		ValidProperty prop = valid_properties[i];
+		long int tmp;
+
+		if (strcmp (prop.name, (char *) key))
+			continue;
 
-		if (!strcmp (prop.name, (char *) key) && prop.type == G_VALUE_TYPE ((GValue *) val))
-			/* Property is ok */
-			return;
+		switch (prop.type) {
+		case G_TYPE_STRING:
+			if (!prop.address || validate_address ((const char *) value))
+				return; /* valid */
+
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "invalid address '%s'",
+			             (const char *) key);
+			break;
+		case G_TYPE_INT:
+			errno = 0;
+			tmp = strtol ((char *) value, NULL, 10);
+			if (errno == 0 && tmp >= prop.int_min && tmp <= prop.int_max)
+				return; /* valid */
+
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "invalid integer property '%s' or out of range [%d -> %d]",
+			             (const char *) key, prop.int_min, prop.int_max);
+			break;
+		case G_TYPE_BOOLEAN:
+			if (!strcmp ((char *) value, "yes") || !strcmp ((char *) value, "no"))
+				return; /* valid */
+
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "invalid boolean property '%s' (not yes or no)",
+			             (const char *) key);
+			break;
+		default:
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "unhandled property '%s' type %s",
+			             (const char *) key, g_type_name (prop.type));
+			break;
+		}
 	}
 
 	/* Did not find the property from valid_properties or the type did not match */
-	*failed = TRUE;
+	if (!valid_properties[i].name) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+		             "property '%s' invalid or not supported",
+		             (const char *) key);
+	}
 }
 
 static gboolean
-nm_openvpn_properties_validate (GHashTable *properties)
+nm_openvpn_properties_validate (GHashTable *properties, GError **error)
 {
-	gboolean failed = FALSE;
-
-	if (g_hash_table_size (properties) < 1)
-		return failed;
+	if (g_hash_table_size (properties) < 1) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+		             "%s",
+		             "No VPN configuration options.");
+		return FALSE;
+	}
 
-	g_hash_table_foreach (properties, validate_one_property, &failed);
+	g_hash_table_foreach (properties, validate_one_property, error);
 
-	return !failed;
+	return *error ? FALSE : TRUE;
 }
 
 static void
@@ -166,6 +235,26 @@
 	priv->io_data = NULL;
 }
 
+static char *
+ovpn_quote_string (const char *unquoted)
+{
+	char *quoted = NULL, *q;
+	char *u = (char *) unquoted;
+
+	g_return_val_if_fail (unquoted != NULL, NULL);
+
+	/* FIXME: use unpaged memory */
+	quoted = q = g_malloc0 (strlen (unquoted) * 2);
+	while (*u) {
+		/* Escape certain characters */
+		if (*u == ' ' || *u == '\\' || *u == '"')
+			*q++ = '\\';
+		*q++ = *u++;
+	}
+
+	return quoted;
+}
+
 static gboolean
 nm_openvpn_socket_data_cb (GIOChannel *source, GIOCondition condition, gpointer user_data)
 {
@@ -189,10 +278,19 @@
 	if (sscanf (str, ">PASSWORD:Need '%a[^']'", &auth) > 0 ) {
 		if (strcmp (auth, "Auth") == 0) {
 			if (io_data->username != NULL && io_data->password != NULL) {
-				buf = g_strdup_printf ("username \"%s\" %s\n"
-								   "password \"%s\" %s\n",
-								   auth, io_data->username,
-								   auth, io_data->password);
+				char *quser, *qpass;
+
+				/* Quote strings passed back to openvpn */
+				quser = ovpn_quote_string (io_data->username);
+				qpass = ovpn_quote_string (io_data->password);
+				buf = g_strdup_printf ("username \"%s\" \"%s\"\n"
+				                       "password \"%s\" \"%s\"\n",
+				                       auth, quser,
+				                       auth, qpass);
+				memset (qpass, 0, strlen (qpass));
+				g_free (qpass);
+				g_free (quser);
+
 				/* Will always write everything in blocking channels (on success) */
 				g_io_channel_write_chars (source, buf, strlen (buf), &written, NULL);
 				g_io_channel_flush (source, NULL);
@@ -200,7 +298,14 @@
 			}
 		} else if (!strcmp (auth, "Private Key")) {
 			if (io_data->certpass) {
-				buf = g_strdup_printf ("password \"%s\" %s\n", auth, io_data->certpass);
+				char *qpass;
+
+				/* Quote strings passed back to openvpn */
+				qpass = ovpn_quote_string (io_data->certpass);
+				buf = g_strdup_printf ("password \"%s\" \"%s\"\n", auth, qpass);
+				memset (qpass, 0, strlen (qpass));
+				g_free (qpass);
+
 				/* Will always write everything in blocking channels (on success) */
 				g_io_channel_write_chars (source, buf, strlen (buf), &written, NULL);
 				g_io_channel_flush (source, NULL);
@@ -213,12 +318,16 @@
 			nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
 			nm_openvpn_disconnect_management_socket (plugin);
 		}
-
 	} else if (strstr (str, ">PASSWORD:Verification Failed: ") == str) {
 		nm_warning ("Password verification failed");
 		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED);
 		nm_openvpn_disconnect_management_socket (plugin);
 		again = FALSE;
+	} else if (strstr (str, "private key password verification failed")) {
+		nm_warning ("Private key verification failed");
+		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED);
+		nm_openvpn_disconnect_management_socket (plugin);
+		again = FALSE;
 	}
 
  out:
@@ -261,8 +370,8 @@
 			return FALSE;
 		}
 	} else {
-		GIOChannel            *openvpn_socket_channel;
-		guint                  openvpn_socket_channel_eventid;
+		GIOChannel *openvpn_socket_channel;
+		guint openvpn_socket_channel_eventid;
 
 		openvpn_socket_channel = g_io_channel_unix_new (socket_fd);
 		openvpn_socket_channel_eventid = g_io_add_watch (openvpn_socket_channel,
@@ -328,20 +437,21 @@
 	nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
 }
 
-static int
+static const char *
 get_connection_type (GHashTable *properties)
 {
-	int connection_type = NM_OPENVPN_CONTYPE_INVALID;
-	gpointer tmp;
+	const char *ctype;
 
-	tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_CONNECTION_TYPE);
-	if (tmp)
-		connection_type = g_value_get_int ((GValue *) tmp);
-
-	if (connection_type < NM_OPENVPN_CONTYPE_INVALID || connection_type > NM_OPENVPN_CONTYPE_PASSWORD_TLS)
-		connection_type = NM_OPENVPN_CONTYPE_INVALID;
+	ctype = g_hash_table_lookup (properties, NM_OPENVPN_KEY_CONNECTION_TYPE);
+	if (ctype) {
+		if (   !strcmp (ctype, NM_OPENVPN_CONTYPE_TLS)
+		    || !strcmp (ctype, NM_OPENVPN_CONTYPE_STATIC_KEY)
+		    || !strcmp (ctype, NM_OPENVPN_CONTYPE_PASSWORD)
+		    || !strcmp (ctype, NM_OPENVPN_CONTYPE_PASSWORD_TLS))
+			return ctype;
+	}
 
-	return connection_type;
+	return NULL;
 }
 
 static const char *
@@ -363,215 +473,275 @@
 	return *openvpn_binary;
 }
 
-static gint
-nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin, GHashTable *properties)
+static void
+free_openvpn_args (GPtrArray *args)
+{
+	g_ptr_array_foreach (args, (GFunc) g_free, NULL);
+	g_ptr_array_free (args, TRUE);
+}
+
+static void
+add_openvpn_arg (GPtrArray *args, const char *arg)
+{
+	g_return_if_fail (args != NULL);
+	g_return_if_fail (arg != NULL);
+
+	g_ptr_array_add (args, (gpointer) g_strdup (arg));
+}
+
+static gboolean
+add_openvpn_arg_int (GPtrArray *args, const char *arg)
+{
+	long int tmp_int;
+
+	g_return_val_if_fail (args != NULL, FALSE);
+	g_return_val_if_fail (arg != NULL, FALSE);
+
+	/* Convert -> int and back to string for security's sake since
+	 * strtol() ignores some leading and trailing characters.
+	 */
+	errno = 0;
+	tmp_int = strtol (arg, NULL, 10);
+	if (errno != 0)
+		return FALSE;
+	g_ptr_array_add (args, (gpointer) g_strdup_printf ("%d", (guint32) tmp_int));
+	return TRUE;
+}
+
+static gboolean
+nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
+                                 GHashTable *properties,
+                                 GError **error)
 {
 	NMOpenvpnPluginPrivate *priv = NM_OPENVPN_PLUGIN_GET_PRIVATE (plugin);
-	GPid	pid;
-	const char *openvpn_binary;
-	GPtrArray *openvpn_argv;
+	const char *openvpn_binary, *connection_type, *tmp;
+	GPtrArray *args;
 	GSource *openvpn_watch;
-	gpointer tmp;
-	gint	stdin_fd;
-	gint stdout_fd;
-	gint stderr_fd;
-	int connection_type;
-	GError *err = NULL;
+	GPid pid;
 
 	/* Find openvpn */
 	openvpn_binary = nm_find_openvpn ();
 	if (!openvpn_binary) {
-		nm_info ("Could not find openvpn binary.");
-		return -1;
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+		             "%s",
+		             "Could not find the openvpn binary.");
+		return FALSE;
 	}
 
 	connection_type = get_connection_type (properties);
-	if (connection_type == NM_OPENVPN_CONTYPE_INVALID)
-		return -1;
+	if (!connection_type) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+		             "%s",
+		             "Invalid connection type.");
+		return FALSE;
+	}
 
-	openvpn_argv = g_ptr_array_new ();
-	g_ptr_array_add (openvpn_argv, (gpointer) (openvpn_binary));
+	args = g_ptr_array_new ();
+	add_openvpn_arg (args, openvpn_binary);
 
 	tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_REMOTE);
-	if (tmp) {
-		g_ptr_array_add (openvpn_argv, (gpointer) "--remote");
-		g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+	if (tmp && strlen (tmp)) {
+		add_openvpn_arg (args, "--remote");
+		add_openvpn_arg (args, tmp);
 	}
 
 	tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_COMP_LZO);
-	if (tmp && g_value_get_boolean ((GValue *) tmp))
-		g_ptr_array_add (openvpn_argv, (gpointer) "--comp-lzo");
+	if (tmp && !strcmp (tmp, "yes"))
+		add_openvpn_arg (args, "--comp-lzo");
 
-	g_ptr_array_add (openvpn_argv, (gpointer) "--nobind");
+	add_openvpn_arg (args, "--nobind");
 
 	/* Device, either tun or tap */
-	g_ptr_array_add (openvpn_argv, (gpointer) "--dev");
+	add_openvpn_arg (args, "--dev");
 	tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_TAP_DEV);
-	if (tmp && g_value_get_boolean ((GValue *) tmp))
-		g_ptr_array_add (openvpn_argv, (gpointer) "tap");
+	if (tmp && !strcmp (tmp, "yes"))
+		add_openvpn_arg (args, "tap");
 	else
-		g_ptr_array_add (openvpn_argv, (gpointer) "tun");
+		add_openvpn_arg (args, "tun");
 
 	/* Protocol, either tcp or udp */
-	g_ptr_array_add (openvpn_argv, (gpointer) "--proto");
+	add_openvpn_arg (args, "--proto");
 	tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_PROTO_TCP);
-	if (tmp && g_value_get_boolean ((GValue *) tmp))
-		g_ptr_array_add (openvpn_argv, (gpointer) "tcp-client");
+	if (tmp && !strcmp (tmp, "yes"))
+		add_openvpn_arg (args, "tcp-client");
 	else
-		g_ptr_array_add (openvpn_argv, (gpointer) "udp");
+		add_openvpn_arg (args, "udp");
 
 	/* Port */
-	g_ptr_array_add (openvpn_argv, (gpointer) "--port");
+	add_openvpn_arg (args, "--port");
 	tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_PORT);
-	if (tmp)
-		/* The string here is leaked, big deal. */
-		g_ptr_array_add (openvpn_argv, g_strdup_printf ("%u", g_value_get_int ((GValue *) tmp)));
-	else
+	if (tmp && strlen (tmp)) {
+		if (!add_openvpn_arg_int (args, tmp)) {
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "Invalid port number '%s'.",
+			             tmp);
+			free_openvpn_args (args);
+			return FALSE;
+		}
+	} else {
 		/* Default to IANA assigned port 1194 */
-		g_ptr_array_add (openvpn_argv, (GValue *) "1194");
+		add_openvpn_arg (args, "1194");
+	}
 
 	/* Cipher */
 	tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_CIPHER);
-	if (tmp) {
-		g_ptr_array_add (openvpn_argv, (gpointer) "--cipher");
-		g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+	if (tmp && strlen (tmp)) {
+		add_openvpn_arg (args, "--cipher");
+		add_openvpn_arg (args, tmp);
 	}
 
 	/* TA */
 	tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_TA);
-	if (tmp) {
-		g_ptr_array_add (openvpn_argv, (gpointer) "--tls-auth");
-		g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+	if (tmp && strlen (tmp)) {
+		add_openvpn_arg (args, "--tls-auth");
+		add_openvpn_arg (args, tmp);
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_TA_DIR);
-		if (tmp && strlen (g_value_get_string (tmp)))
-			g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+		if (tmp && strlen (tmp))
+			add_openvpn_arg (args, tmp);
 	}
 
 	/* Syslog */
-	g_ptr_array_add (openvpn_argv, (gpointer) "--syslog");
-	g_ptr_array_add (openvpn_argv, (gpointer) "nm-openvpn");
+	add_openvpn_arg (args, "--syslog");
+	add_openvpn_arg (args, "nm-openvpn");
 
 	/* Up script, called when connection has been established or has been restarted */
-	g_ptr_array_add (openvpn_argv, (gpointer) "--up");
-	g_ptr_array_add (openvpn_argv, (gpointer) NM_OPENVPN_HELPER_PATH);
-	g_ptr_array_add (openvpn_argv, (gpointer) "--up-restart");
+	add_openvpn_arg (args, "--up");
+	add_openvpn_arg (args, NM_OPENVPN_HELPER_PATH);
+	add_openvpn_arg (args, "--up-restart");
 
 	/* Keep key and tun if restart is needed */
-	g_ptr_array_add (openvpn_argv, (gpointer) "--persist-key");
-	g_ptr_array_add (openvpn_argv, (gpointer) "--persist-tun");
+	add_openvpn_arg (args, "--persist-key");
+	add_openvpn_arg (args, "--persist-tun");
 
 	/* Management socket for localhost access to supply username and password */
-	g_ptr_array_add (openvpn_argv, (gpointer) "--management");
-	g_ptr_array_add (openvpn_argv, (gpointer) "127.0.0.1");
+	add_openvpn_arg (args, "--management");
+	add_openvpn_arg (args, "127.0.0.1");
 	/* with have nobind, thus 1194 should be free, it is the IANA assigned port */
-	g_ptr_array_add (openvpn_argv, (gpointer) "1194");
+	add_openvpn_arg (args, "1194");
 	/* Query on the management socket for user/pass */
-	g_ptr_array_add (openvpn_argv, (gpointer) "--management-query-passwords");
+	add_openvpn_arg (args, "--management-query-passwords");
 
 	/* do not let openvpn setup routes, NM will handle it */
-	g_ptr_array_add (openvpn_argv, (gpointer) "--route-noexec");
+	add_openvpn_arg (args, "--route-noexec");
 
 	/* Now append configuration options which are dependent on the configuration type */
-	switch (connection_type) {
-	case NM_OPENVPN_CONTYPE_TLS:
-		g_ptr_array_add (openvpn_argv, (gpointer) "--client");
+	if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_TLS)) {
+		add_openvpn_arg (args, "--client");
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_CA);
-		if (tmp) {
-			g_ptr_array_add (openvpn_argv, (gpointer) "--ca");
-			g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+		if (tmp && strlen (tmp)) {
+			add_openvpn_arg (args, "--ca");
+			add_openvpn_arg (args, tmp);
 		}
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_CERT);
-		if (tmp) {
-			g_ptr_array_add (openvpn_argv, (gpointer) "--cert");
-			g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+		if (tmp && strlen (tmp)) {
+			add_openvpn_arg (args, "--cert");
+			add_openvpn_arg (args, tmp);
 		}
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_KEY);
-		if (tmp) {
-			g_ptr_array_add (openvpn_argv, (gpointer) "--key");
-			g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
-		}
-		break;
-
-	case NM_OPENVPN_CONTYPE_STATIC_KEY:
-		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_SHARED_KEY);
-		if (tmp) {
-			g_ptr_array_add (openvpn_argv, (gpointer) "--secret");
-			g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+		if (tmp && strlen (tmp)) {
+			add_openvpn_arg (args, "--key");
+			add_openvpn_arg (args, tmp);
+		}
+	} else if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_STATIC_KEY)) {
+		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_STATIC_KEY);
+		if (tmp && strlen (tmp)) {
+			add_openvpn_arg (args, "--secret");
+			add_openvpn_arg (args, tmp);
+
+			tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_STATIC_KEY_DIRECTION);
+			if (tmp && strlen (tmp))
+				add_openvpn_arg (args, tmp);
 		}
 
-		g_ptr_array_add (openvpn_argv, (gpointer) "--ifconfig");
+		add_openvpn_arg (args, "--ifconfig");
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_LOCAL_IP);
 		if (!tmp) {
 			/* Insufficient data (FIXME: this should really be detected when validating the properties */
-			g_ptr_array_free (openvpn_argv, TRUE);
-			return -1;
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "%s",
+			             "Missing required local IP address for static key mode.");
+			free_openvpn_args (args);
+			return FALSE;
 		}
-		g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+		add_openvpn_arg (args, tmp);
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_REMOTE_IP);
 		if (!tmp) {
 			/* Insufficient data (FIXME: this should really be detected when validating the properties */
-			g_ptr_array_free (openvpn_argv, TRUE);
-			return -1;
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "%s",
+			             "Missing required remote IP address for static key mode.");
+			free_openvpn_args (args);
+			return FALSE;
 		}
-		g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
-		break;
-
-	case NM_OPENVPN_CONTYPE_PASSWORD:
+		add_openvpn_arg (args, tmp);
+	} else if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD)) {
 		/* Client mode */
-		g_ptr_array_add (openvpn_argv, (gpointer) "--client");
+		add_openvpn_arg (args, "--client");
 		/* Use user/path authentication */
-		g_ptr_array_add (openvpn_argv, (gpointer) "--auth-user-pass");
+		add_openvpn_arg (args, "--auth-user-pass");
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_CA);
-		if (tmp) {
-			g_ptr_array_add (openvpn_argv, (gpointer) "--ca");
-			g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+		if (tmp && strlen (tmp)) {
+			add_openvpn_arg (args, "--ca");
+			add_openvpn_arg (args, tmp);
 		}
-		break;
-
-	case NM_OPENVPN_CONTYPE_PASSWORD_TLS:
-		g_ptr_array_add (openvpn_argv, (gpointer) "--client");
+	} else if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
+		add_openvpn_arg (args, "--client");
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_CA);
-		if (tmp) {
-			g_ptr_array_add (openvpn_argv, (gpointer) "--ca");
-			g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+		if (tmp && strlen (tmp)) {
+			add_openvpn_arg (args, "--ca");
+			add_openvpn_arg (args, tmp);
 		}
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_CERT);
-		if (tmp) {
-			g_ptr_array_add (openvpn_argv, (gpointer) "--cert");
-			g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+		if (tmp && strlen (tmp)) {
+			add_openvpn_arg (args, "--cert");
+			add_openvpn_arg (args, tmp);
 		}
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_KEY);
-		if (tmp) {
-			g_ptr_array_add (openvpn_argv, (gpointer) "--key");
-			g_ptr_array_add (openvpn_argv, (gpointer) g_value_get_string ((GValue *) tmp));
+		if (tmp && strlen (tmp)) {
+			add_openvpn_arg (args, "--key");
+			add_openvpn_arg (args, tmp);
 		}
 
 		/* Use user/path authentication */
-		g_ptr_array_add (openvpn_argv, (gpointer) "--auth-user-pass");
-		break;
+		add_openvpn_arg (args, "--auth-user-pass");
+	} else {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+		             "Unknown connection type '%s'.",
+		             connection_type);
+		free_openvpn_args (args);
+		return FALSE;
 	}
 
-	g_ptr_array_add (openvpn_argv, NULL);
+	g_ptr_array_add (args, NULL);
 
-	if (!g_spawn_async_with_pipes (NULL, (char **) openvpn_argv->pdata, NULL,
-							 G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &stdin_fd,
-							 &stdout_fd, &stderr_fd, &err)) {
-		g_ptr_array_free (openvpn_argv, TRUE);
-		nm_warning ("openvpn failed to start.  error: '%s'", err->message);
-		g_error_free (err);
-		return -1;
+	if (!g_spawn_async (NULL, (char **) args->pdata, NULL,
+	                    G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, error)) {
+		free_openvpn_args (args);
+		return FALSE;
 	}
-	g_ptr_array_free (openvpn_argv, TRUE);
+	free_openvpn_args (args);
 
 	nm_info ("openvpn started with pid %d", pid);
 
@@ -586,72 +756,47 @@
 	   X509USERPASS: Will require username and password and maybe certificate password
 	   X509: May require certificate password
 	*/
-	if (connection_type == NM_OPENVPN_CONTYPE_PASSWORD ||
-	    connection_type == NM_OPENVPN_CONTYPE_PASSWORD_TLS ||
-	    connection_type == NM_OPENVPN_CONTYPE_TLS) {
-
-		NMOpenvpnPluginIOData  *io_data;
-
-		io_data                  = g_new0 (NMOpenvpnPluginIOData, 1);
-		io_data->child_stdin_fd  = stdin_fd;
-		io_data->child_stdout_fd = stdout_fd;
-		io_data->child_stderr_fd = stderr_fd;
+	if (   !strcmp (connection_type, NM_OPENVPN_CONTYPE_TLS)
+	    || !strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD)
+	    || !strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
+		NMOpenvpnPluginIOData *io_data;
+
+		io_data = g_new0 (NMOpenvpnPluginIOData, 1);
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_USERNAME);
-		if (tmp)
-			io_data->username = g_strdup ((char *) g_value_get_string ((GValue *) tmp));
+		io_data->username = tmp ? g_strdup (tmp) : NULL;
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_PASSWORD);
-		if (tmp)
-			io_data->password = g_strdup ((char *) g_value_get_string ((GValue *) tmp));
+		io_data->password = tmp ? g_strdup (tmp) : NULL;
 
 		tmp = g_hash_table_lookup (properties, NM_OPENVPN_KEY_CERTPASS);
-		if (tmp)
-			io_data->certpass = g_strdup ((char *) g_value_get_string ((GValue *) tmp));
+		io_data->certpass = tmp ? g_strdup (tmp) : NULL;
 
 		priv->io_data = io_data;
 
 		nm_openvpn_schedule_connect_timer (plugin);
 	}
 
-	return stdin_fd;
+	return TRUE;
 }
 
 static gboolean
 real_connect (NMVPNPlugin   *plugin,
-		    NMConnection  *connection,
-		    GError       **err)
+              NMConnection  *connection,
+              GError       **error)
 {
-	NMSettingVPNProperties *properties;
-	gint fd;
-	gboolean success = FALSE;
-
-	properties = NM_SETTING_VPN_PROPERTIES (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES));
-	if (!properties || !nm_openvpn_properties_validate (properties->data)) {
-		g_set_error (err,
-				   NM_VPN_PLUGIN_ERROR,
-				   NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
-				   "%s",
-				   "Invalid arguments.");
-		goto out;
-	}
+	NMSettingVPN *s_vpn;
 
-	if ((fd = nm_openvpn_start_openvpn_binary (NM_OPENVPN_PLUGIN (plugin), properties->data)) < 0) {
-		g_set_error (err,
-				   NM_VPN_PLUGIN_ERROR,
-				   NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
-				   "%s",
-				   "Could not start openvpn binary.");
-		goto out;
-	}
+	s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN));
+	g_assert (s_vpn);
 
-	success = TRUE;
+	if (!nm_openvpn_properties_validate (s_vpn->data, error))
+		return FALSE;
 
- out:
-	/* FIXME: It never did that but I guess it should? */
-/* 	close (fd); */
+	if (!nm_openvpn_start_openvpn_binary (NM_OPENVPN_PLUGIN (plugin), s_vpn->data, error))
+		return FALSE;
 
-	return success;
+	return TRUE;
 }
 
 static gboolean
@@ -660,15 +805,15 @@
                    char **setting_name,
                    GError **error)
 {
-	NMSettingVPNProperties *s_vpn_props;
-	int connection_type;
+	NMSettingVPN *s_vpn;
+	const char *connection_type;
 	gboolean need_secrets = FALSE;
 
 	g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
 
-	s_vpn_props = NM_SETTING_VPN_PROPERTIES (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES));
-	if (!s_vpn_props) {
+	s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN));
+	if (!s_vpn) {
 		g_set_error (error,
 		             NM_VPN_PLUGIN_ERROR,
 		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
@@ -677,30 +822,28 @@
 		return FALSE;
 	}
 
-	connection_type = get_connection_type (s_vpn_props->data);
-	switch (connection_type) {
-	case NM_OPENVPN_CONTYPE_PASSWORD_TLS:
+	connection_type = get_connection_type (s_vpn->data);
+	if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
 		/* Will require username and password and maybe certificate password */
-		if (!g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_CERTPASS))
+		if (!g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_CERTPASS))
 			need_secrets = TRUE;
-		/* Fall through */
-	case NM_OPENVPN_CONTYPE_PASSWORD:
+
+		if (!g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_USERNAME) ||
+		    !g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_PASSWORD))
+			need_secrets = TRUE;
+	} else if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD)) {
 		/* Will require username and password */
-		if (!g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_USERNAME) ||
-		    !g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_PASSWORD))
+		if (!g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_USERNAME) ||
+		    !g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_PASSWORD))
 			need_secrets = TRUE;
-		break;
-	case NM_OPENVPN_CONTYPE_TLS:
+	} else if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_TLS)) {
 		/* May require certificate password */
-		if (!g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_CERTPASS))
+		if (!g_hash_table_lookup (s_vpn->data, NM_OPENVPN_KEY_CERTPASS))
 			need_secrets = TRUE;
-		break;
-	default:
-		break;
 	}
 
 	if (need_secrets)
-		*setting_name = NM_SETTING_VPN_PROPERTIES_SETTING_NAME;
+		*setting_name = NM_SETTING_VPN_SETTING_NAME;
 
 	return need_secrets;
 }

Modified: branches/mbca/vpn-daemons/openvpn/src/nm-openvpn-service.h
==============================================================================
--- branches/mbca/vpn-daemons/openvpn/src/nm-openvpn-service.h	(original)
+++ branches/mbca/vpn-daemons/openvpn/src/nm-openvpn-service.h	Mon Aug 18 08:30:28 2008
@@ -38,29 +38,20 @@
 #define NM_DBUS_INTERFACE_OPENVPN  "org.freedesktop.NetworkManager.openvpn"
 #define NM_DBUS_PATH_OPENVPN       "/org/freedesktop/NetworkManager/openvpn"
 
-/* Do not change numbers, only add if needed!
-   See properties/nm-openvpn.c:connection_type_changed() for details
- */
-#define NM_OPENVPN_CONTYPE_INVALID      -1
-#define NM_OPENVPN_CONTYPE_TLS          0
-#define NM_OPENVPN_CONTYPE_STATIC_KEY   1
-#define NM_OPENVPN_CONTYPE_PASSWORD     2
-#define NM_OPENVPN_CONTYPE_PASSWORD_TLS 3
-
 #define NM_OPENVPN_KEY_CA "ca"
 #define NM_OPENVPN_KEY_CERT "cert"
 #define NM_OPENVPN_KEY_CIPHER "cipher"
 #define NM_OPENVPN_KEY_COMP_LZO "comp-lzo"
 #define NM_OPENVPN_KEY_CONNECTION_TYPE "connection-type"
-#define NM_OPENVPN_KEY_TAP_DEV "dev"
+#define NM_OPENVPN_KEY_TAP_DEV "tap-dev"
 #define NM_OPENVPN_KEY_KEY "key"
 #define NM_OPENVPN_KEY_LOCAL_IP "local-ip"
-#define NM_OPENVPN_KEY_PROTO_TCP "proto"
+#define NM_OPENVPN_KEY_PROTO_TCP "proto-tcp"
 #define NM_OPENVPN_KEY_PORT "port"
 #define NM_OPENVPN_KEY_REMOTE "remote"
 #define NM_OPENVPN_KEY_REMOTE_IP "remote-ip"
-#define NM_OPENVPN_KEY_SHARED_KEY "shared-key"
-#define NM_OPENVPN_KEY_SHARED_KEY_DIRECTION "shared-key-direction"
+#define NM_OPENVPN_KEY_STATIC_KEY "static-key"
+#define NM_OPENVPN_KEY_STATIC_KEY_DIRECTION "static-key-direction"
 #define NM_OPENVPN_KEY_TA "ta"
 #define NM_OPENVPN_KEY_TA_DIR "ta-dir"
 #define NM_OPENVPN_KEY_USERNAME "username"
@@ -69,6 +60,11 @@
 #define NM_OPENVPN_KEY_CERTPASS "cert-pass"
 #define NM_OPENVPN_KEY_NOSECRET "no-secret"
 
+#define NM_OPENVPN_CONTYPE_TLS          "tls"
+#define NM_OPENVPN_CONTYPE_STATIC_KEY   "static-key"
+#define NM_OPENVPN_CONTYPE_PASSWORD     "password"
+#define NM_OPENVPN_CONTYPE_PASSWORD_TLS "password-tls"
+
 typedef struct {
 	NMVPNPlugin parent;
 } NMOpenvpnPlugin;

Modified: branches/mbca/vpn-daemons/pptp/auth-dialog/main.c
==============================================================================
--- branches/mbca/vpn-daemons/pptp/auth-dialog/main.c	(original)
+++ branches/mbca/vpn-daemons/pptp/auth-dialog/main.c	Mon Aug 18 08:30:28 2008
@@ -30,7 +30,6 @@
 #include <gnome-keyring.h>
 
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 
 #include "../src/nm-pptp-service.h"
 #include "gnome-two-password-dialog.h"
@@ -58,7 +57,7 @@
 	                                      vpn_id,
 	                                      KEYRING_SN_TAG,
 	                                      GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
-	                                      NM_SETTING_VPN_PROPERTIES_SETTING_NAME,
+	                                      NM_SETTING_VPN_SETTING_NAME,
 	                                      KEYRING_SK_TAG,
 	                                      GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
 	                                      secret_name,
@@ -105,7 +104,7 @@
 	GnomeKeyringAttributeList *attrs = NULL;
 	guint32 id = 0;
 
-	display_name = g_strdup_printf ("VPN %s secret for %s/%s/" NM_SETTING_VPN_PROPERTIES_SETTING_NAME,
+	display_name = g_strdup_printf ("VPN %s secret for %s/%s/" NM_SETTING_VPN_SETTING_NAME,
 	                                secret_name,
 	                                vpn_name,
 	                                vpn_service);
@@ -116,7 +115,7 @@
 	                                            vpn_id);
 	gnome_keyring_attribute_list_append_string (attrs,
 	                                            KEYRING_SN_TAG,
-	                                            NM_SETTING_VPN_PROPERTIES_SETTING_NAME);
+	                                            NM_SETTING_VPN_SETTING_NAME);
 	gnome_keyring_attribute_list_append_string (attrs,
 	                                            KEYRING_SK_TAG,
 	                                            secret_name);

Modified: branches/mbca/vpn-daemons/pptp/po/LINGUAS
==============================================================================
--- branches/mbca/vpn-daemons/pptp/po/LINGUAS	(original)
+++ branches/mbca/vpn-daemons/pptp/po/LINGUAS	Mon Aug 18 08:30:28 2008
@@ -14,6 +14,7 @@
 et
 eu
 fi
+fr
 gl
 he
 hu

Modified: branches/mbca/vpn-daemons/pptp/properties/advanced-dialog.c
==============================================================================
--- branches/mbca/vpn-daemons/pptp/properties/advanced-dialog.c	(original)
+++ branches/mbca/vpn-daemons/pptp/properties/advanced-dialog.c	Mon Aug 18 08:30:28 2008
@@ -29,6 +29,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <glib.h>
 #include <glib/gi18n-lib.h>
@@ -36,7 +37,6 @@
 
 #include <nm-connection.h>
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 
 #include "advanced-dialog.h"
 #include "nm-pptp.h"
@@ -51,15 +51,6 @@
 #define TAG_MSCHAP 2
 #define TAG_MSCHAPV2 3
 
-static void
-nm_gvalue_destroy (gpointer data)
-{
-	GValue *value = (GValue *) data;
-
-	g_value_unset (value);
-	g_slice_free (GValue, value);
-}
-
 static const char *advanced_keys[] = {
 	NM_PPTP_KEY_REFUSE_EAP,
 	NM_PPTP_KEY_REFUSE_PAP,
@@ -82,30 +73,13 @@
 copy_values (gpointer key, gpointer data, gpointer user_data)
 {
 	GHashTable *hash = (GHashTable *) user_data;
-	GValue *value = (GValue *) data;
 	const char **i;
 
 	for (i = &advanced_keys[0]; *i; i++) {
 		if (strcmp ((const char *) key, *i))
 			continue;
 
-		if (G_VALUE_HOLDS_STRING (value)) {
-			g_hash_table_insert (hash,
-			                     g_strdup ((const char *) key),
-			                     str_to_gvalue (g_value_get_string (value)));
-		} else if (G_VALUE_HOLDS_INT (value)) {
-			g_hash_table_insert (hash,
-			                     g_strdup ((const char *) key),
-			                     int_to_gvalue (g_value_get_int (value)));
-		} else if (G_VALUE_HOLDS_UINT (value)) {
-			g_hash_table_insert (hash,
-			                     g_strdup ((const char *) key),
-			                     uint_to_gvalue (g_value_get_uint (value)));
-		} else if (G_VALUE_HOLDS_BOOLEAN (value)) {
-			g_hash_table_insert (hash,
-			                     g_strdup ((const char *) key),
-			                     bool_to_gvalue (g_value_get_boolean (value)));
-		}
+		g_hash_table_insert (hash, g_strdup ((const char *) key), g_strdup ((const char *) data));
 	}
 }
 
@@ -114,13 +88,13 @@
                                           GError **error)
 {
 	GHashTable *hash;
-	NMSettingVPNProperties *s_vpn_props;
+	NMSettingVPN *s_vpn;
 
-	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
+	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
-	s_vpn_props = (NMSettingVPNProperties *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES);
-	if (s_vpn_props && s_vpn_props->data)
-		g_hash_table_foreach (s_vpn_props->data, copy_values, hash);
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	if (s_vpn && s_vpn->data)
+		g_hash_table_foreach (s_vpn->data, copy_values, hash);
 
 	return hash;
 }
@@ -159,7 +133,7 @@
 	GtkListStore *store;
 	GtkTreeIter iter;
 	int active = -1;
-	GValue *value;
+	const char *value;
 
 	g_return_if_fail (xml != NULL);
 	g_return_if_fail (hash != NULL);
@@ -177,7 +151,7 @@
 	gtk_list_store_set (store, &iter, 0, _("128-bit (most secure)"), -1);
 	if (active < 0) {
 		value = g_hash_table_lookup (hash, NM_PPTP_KEY_REQUIRE_MPPE_128);
-		if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+		if (value && !strcmp (value, "yes"))
 			active = SEC_INDEX_MPPE_128;
 	}
 
@@ -186,7 +160,7 @@
 	gtk_list_store_set (store, &iter, 0, _("40-bit (less secure)"), -1);
 	if (active < 0) {
 		value = g_hash_table_lookup (hash, NM_PPTP_KEY_REQUIRE_MPPE_40);
-		if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+		if (value && !strcmp (value, "yes"))
 			active = SEC_INDEX_MPPE_40;
 	}
 
@@ -225,7 +199,7 @@
 	GtkWidget *widget;
 	GtkListStore *store;
 	GtkTreeIter iter;
-	GValue *value;
+	const char *value;
 	gboolean allowed;
 	gboolean use_mppe = FALSE;
 	GtkCellRendererToggle *check_renderer;
@@ -237,40 +211,40 @@
 
 	/* Check for MPPE */
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_REQUIRE_MPPE);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	if (value && !strcmp (value, "yes"))
 		use_mppe = TRUE;
 	
 	/* Or MPPE-128 */
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_REQUIRE_MPPE_128);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	if (value && !strcmp (value, "yes"))
 		use_mppe = TRUE;
 
 	/* Or MPPE-40 */
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_REQUIRE_MPPE_40);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	if (value && !strcmp (value, "yes"))
 		use_mppe = TRUE;
 
 	/* PAP */
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_REFUSE_PAP);
-	allowed = (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value)) ? FALSE : TRUE;
+	allowed = (value && !strcmp (value, "yes")) ? FALSE : TRUE;
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter, COL_NAME, _("PAP"), COL_VALUE, allowed, COL_TAG, TAG_PAP, -1);
 
 	/* CHAP */
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_REFUSE_CHAP);
-	allowed = (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value)) ? FALSE : TRUE;
+	allowed = (value && !strcmp (value, "yes")) ? FALSE : TRUE;
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter, COL_NAME, _("CHAP"), COL_VALUE, allowed, COL_TAG, TAG_CHAP, -1);
 
 	/* MSCHAP */
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_REFUSE_MSCHAP);
-	allowed = (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value)) ? FALSE : TRUE;
+	allowed = (value && !strcmp (value, "yes")) ? FALSE : TRUE;
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter, COL_NAME, _("MSCHAP"), COL_VALUE, allowed, COL_TAG, TAG_MSCHAP, -1);
 
 	/* PAP */
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_REFUSE_MSCHAPV2);
-	allowed = (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value)) ? FALSE : TRUE;
+	allowed = (value && !strcmp (value, "yes")) ? FALSE : TRUE;
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter, COL_NAME, _("MSCHAPv2"), COL_VALUE, allowed, COL_TAG, TAG_MSCHAPV2, -1);
 
@@ -306,7 +280,7 @@
 	GtkWidget *dialog = NULL;
 	char *glade_file = NULL;
 	GtkWidget *widget;
-	GValue *value;
+	const char *value;
 
 	g_return_val_if_fail (hash != NULL, NULL);
 
@@ -332,47 +306,41 @@
 	g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (mppe_toggled_cb), xml);
 
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_REQUIRE_MPPE);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
-		if (g_value_get_boolean (value))
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
-	}
+	if (value && !strcmp (value, "yes"))
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 	mppe_toggled_cb (widget, xml);
 
+	widget = glade_xml_get_widget (xml, "ppp_allow_stateful_mppe");
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_MPPE_STATEFUL);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
-		widget = glade_xml_get_widget (xml, "ppp_allow_stateful_mppe");
-		if (g_value_get_boolean (value))
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
-	}
+	if (value && !strcmp (value, "yes"))
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 
 	widget = glade_xml_get_widget (xml, "ppp_allow_bsdcomp");
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_NOBSDCOMP);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
-		if (g_value_get_boolean (value))
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
-	}
+	if (value && !strcmp (value, "yes"))
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
 
 	widget = glade_xml_get_widget (xml, "ppp_allow_deflate");
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_NODEFLATE);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
-		if (g_value_get_boolean (value))
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
-	}
+	if (value && !strcmp (value, "yes"))
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
 
 	widget = glade_xml_get_widget (xml, "ppp_usevj");
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_NO_VJ_COMP);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
-		if (g_value_get_boolean (value))
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
-	}
+	if (value && !strcmp (value, "yes"))
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
 
+	widget = glade_xml_get_widget (xml, "ppp_send_echo_packets");
 	value = g_hash_table_lookup (hash, NM_PPTP_KEY_LCP_ECHO_INTERVAL);
-	if (value && G_VALUE_HOLDS_UINT (value)) {
-		widget = glade_xml_get_widget (xml, "ppp_send_echo_packets");
-		if (g_value_get_uint (value))
+	if (value && strlen (value)) {
+		long int tmp_int;
+
+		errno = 0;
+		tmp_int = strtol (value, NULL, 10);
+		if (errno == 0 && tmp_int > 0)
 			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 	}
 
@@ -400,7 +368,7 @@
 	xml = g_object_get_data (G_OBJECT (dialog), "glade-xml");
 	g_return_val_if_fail (xml != NULL, NULL);
 
-	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
+	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
 	widget = glade_xml_get_widget (xml, "ppp_use_mppe");
 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
@@ -408,37 +376,37 @@
 		widget = glade_xml_get_widget (xml, "ppp_mppe_security_combo");
 		switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget))) {
 		case SEC_INDEX_MPPE_128:
-			g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REQUIRE_MPPE_128), bool_to_gvalue (TRUE));
+			g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REQUIRE_MPPE_128), g_strdup ("yes"));
 			break;
 		case SEC_INDEX_MPPE_40:
-			g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REQUIRE_MPPE_40), bool_to_gvalue (TRUE));
+			g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REQUIRE_MPPE_40), g_strdup ("yes"));
 			break;
 		default:
-			g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REQUIRE_MPPE), bool_to_gvalue (TRUE));
+			g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REQUIRE_MPPE), g_strdup ("yes"));
 			break;
 		}
 
 		widget = glade_xml_get_widget (xml, "ppp_allow_stateful_mppe");
 		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
-			g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_MPPE_STATEFUL), bool_to_gvalue (TRUE));
+			g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_MPPE_STATEFUL), g_strdup ("yes"));
 	}
 
 	widget = glade_xml_get_widget (xml, "ppp_allow_bsdcomp");
 	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
-		g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_NOBSDCOMP), bool_to_gvalue (TRUE));
+		g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_NOBSDCOMP), g_strdup ("yes"));
 
 	widget = glade_xml_get_widget (xml, "ppp_allow_deflate");
 	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
-		g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_NODEFLATE), bool_to_gvalue (TRUE));
+		g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_NODEFLATE), g_strdup ("yes"));
 
 	widget = glade_xml_get_widget (xml, "ppp_usevj");
 	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
-		g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_NO_VJ_COMP), bool_to_gvalue (TRUE));
+		g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_NO_VJ_COMP), g_strdup ("yes"));
 
 	widget = glade_xml_get_widget (xml, "ppp_send_echo_packets");
 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
-		g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_LCP_ECHO_FAILURE), uint_to_gvalue (5));
-		g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_LCP_ECHO_INTERVAL), uint_to_gvalue (30));
+		g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_LCP_ECHO_FAILURE), g_strdup_printf ("%d", 5));
+		g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_LCP_ECHO_INTERVAL), g_strdup_printf ("%d", 30));
 	}
 
 	widget = glade_xml_get_widget (xml, "ppp_auth_methods");
@@ -452,19 +420,19 @@
 		switch (tag) {
 		case TAG_PAP:
 			if (!allowed)
-				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_PAP), bool_to_gvalue (TRUE));
+				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_PAP), g_strdup ("yes"));
 			break;
 		case TAG_CHAP:
 			if (!allowed)
-				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_CHAP), bool_to_gvalue (TRUE));
+				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_CHAP), g_strdup ("yes"));
 			break;
 		case TAG_MSCHAP:
 			if (!allowed)
-				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_MSCHAP), bool_to_gvalue (TRUE));
+				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_MSCHAP), g_strdup ("yes"));
 			break;
 		case TAG_MSCHAPV2:
 			if (!allowed)
-				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_MSCHAPV2), bool_to_gvalue (TRUE));
+				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_MSCHAPV2), g_strdup ("yes"));
 			break;
 		default:
 			break;

Modified: branches/mbca/vpn-daemons/pptp/properties/import-export.c
==============================================================================
--- branches/mbca/vpn-daemons/pptp/properties/import-export.c	(original)
+++ branches/mbca/vpn-daemons/pptp/properties/import-export.c	Mon Aug 18 08:30:28 2008
@@ -35,7 +35,6 @@
 #include <glib/gi18n-lib.h>
 
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 #include <nm-setting-connection.h>
 #include <nm-setting-ip4-config.h>
 

Modified: branches/mbca/vpn-daemons/pptp/properties/nm-pptp-dialog.glade
==============================================================================
--- branches/mbca/vpn-daemons/pptp/properties/nm-pptp-dialog.glade	(original)
+++ branches/mbca/vpn-daemons/pptp/properties/nm-pptp-dialog.glade	Mon Aug 18 08:30:28 2008
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--*- mode: xml -*-->
+<!--Generated with glade3 3.4.4 on Tue Aug 12 07:11:36 2008 -->
 <glade-interface>
   <widget class="GtkWindow" id="pptp-widget">
     <property name="title" translatable="yes">window1</property>
@@ -32,9 +32,8 @@
                 <child>
                   <widget class="GtkTable" id="table2">
                     <property name="visible">True</property>
-                    <property name="n_rows">1</property>
                     <property name="n_columns">2</property>
-                    <property name="column_spacing">6</property>
+                    <property name="column_spacing">12</property>
                     <property name="row_spacing">6</property>
                     <child>
                       <widget class="GtkLabel" id="label23">
@@ -45,7 +44,7 @@
                         <property name="mnemonic_widget">gateway_entry</property>
                       </widget>
                       <packing>
-                        <property name="x_options">GTK_FILL</property>
+                        <property name="x_options">GTK_SHRINK | GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
@@ -97,7 +96,7 @@
                     <property name="visible">True</property>
                     <property name="n_rows">2</property>
                     <property name="n_columns">2</property>
-                    <property name="column_spacing">6</property>
+                    <property name="column_spacing">12</property>
                     <property name="row_spacing">6</property>
                     <child>
                       <widget class="GtkLabel" id="label26">
@@ -106,44 +105,44 @@
                         <property name="label" translatable="yes">User name:</property>
                       </widget>
                       <packing>
-                        <property name="x_options">GTK_FILL</property>
+                        <property name="x_options">GTK_SHRINK | GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkEntry" id="user_entry">
+                      <widget class="GtkLabel" id="label27">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Domain:</property>
                       </widget>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_SHRINK | GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label27">
+                      <widget class="GtkEntry" id="domain_entry">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Domain:</property>
+                        <property name="can_focus">True</property>
                       </widget>
                       <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
                         <property name="top_attach">1</property>
                         <property name="bottom_attach">2</property>
-                        <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkEntry" id="domain_entry">
+                      <widget class="GtkEntry" id="user_entry">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                       </widget>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
@@ -170,7 +169,6 @@
               <widget class="GtkButton" id="advanced_button">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
                 <property name="response_id">0</property>
                 <child>
                   <widget class="GtkHBox" id="hbox2">
@@ -229,8 +227,8 @@
         <child>
           <widget class="GtkVBox" id="PppPage">
             <property name="visible">True</property>
-            <property name="border_width">12</property>
-            <property name="spacing">16</property>
+            <property name="border_width">5</property>
+            <property name="spacing">18</property>
             <child>
               <widget class="GtkVBox" id="vbox2">
                 <property name="visible">True</property>
@@ -317,14 +315,16 @@
                     <child>
                       <widget class="GtkVBox" id="vbox6">
                         <property name="visible">True</property>
+                        <property name="spacing">6</property>
                         <child>
                           <widget class="GtkVBox" id="vbox7">
                             <property name="visible">True</property>
+                            <property name="spacing">6</property>
                             <child>
                               <widget class="GtkCheckButton" id="ppp_use_mppe">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
-                                <property name="label" translatable="yes">Use Point-to-Point Encryption (MPPE)</property>
+                                <property name="label" translatable="yes">Use _Point-to-Point encryption (MPPE)</property>
                                 <property name="use_underline">True</property>
                                 <property name="response_id">0</property>
                                 <property name="draw_indicator">True</property>
@@ -341,18 +341,21 @@
                                 <child>
                                   <widget class="GtkVBox" id="vbox1">
                                     <property name="visible">True</property>
+                                    <property name="spacing">6</property>
                                     <child>
                                       <widget class="GtkHBox" id="hbox1">
                                         <property name="visible">True</property>
+                                        <property name="spacing">12</property>
                                         <child>
                                           <widget class="GtkLabel" id="ppp_mppe_security_label">
                                             <property name="visible">True</property>
                                             <property name="xalign">0</property>
-                                            <property name="label" translatable="yes">Security:</property>
+                                            <property name="label" translatable="yes">_Security:</property>
+                                            <property name="use_underline">True</property>
+                                            <property name="mnemonic_widget">ppp_mppe_security_combo</property>
                                           </widget>
                                           <packing>
                                             <property name="expand">False</property>
-                                            <property name="padding">6</property>
                                           </packing>
                                         </child>
                                         <child>
@@ -361,6 +364,7 @@
                                             <property name="items" translatable="yes">Default</property>
                                           </widget>
                                           <packing>
+                                            <property name="expand">False</property>
                                             <property name="position">1</property>
                                           </packing>
                                         </child>
@@ -370,7 +374,7 @@
                                       <widget class="GtkCheckButton" id="ppp_allow_stateful_mppe">
                                         <property name="visible">True</property>
                                         <property name="can_focus">True</property>
-                                        <property name="label" translatable="yes">Allow Stateful Encryption</property>
+                                        <property name="label" translatable="yes">Allow st_ateful encryption</property>
                                         <property name="use_underline">True</property>
                                         <property name="response_id">0</property>
                                         <property name="draw_indicator">True</property>
@@ -398,7 +402,7 @@
                           <widget class="GtkCheckButton" id="ppp_allow_bsdcomp">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
-                            <property name="label" translatable="yes">Allow BSD data compression</property>
+                            <property name="label" translatable="yes">Allow _BSD data compression</property>
                             <property name="use_underline">True</property>
                             <property name="response_id">0</property>
                             <property name="draw_indicator">True</property>
@@ -413,7 +417,7 @@
                           <widget class="GtkCheckButton" id="ppp_allow_deflate">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
-                            <property name="label" translatable="yes">Allow Deflate data compression</property>
+                            <property name="label" translatable="yes">Allow _Deflate data compression</property>
                             <property name="use_underline">True</property>
                             <property name="response_id">0</property>
                             <property name="draw_indicator">True</property>
@@ -428,7 +432,7 @@
                           <widget class="GtkCheckButton" id="ppp_usevj">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
-                            <property name="label" translatable="yes">Use TCP header compression</property>
+                            <property name="label" translatable="yes">Use TCP _header compression</property>
                             <property name="use_underline">True</property>
                             <property name="response_id">0</property>
                             <property name="draw_indicator">True</property>
@@ -477,7 +481,7 @@
                       <widget class="GtkCheckButton" id="ppp_send_echo_packets">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="label" translatable="yes">Send PPP echo packets</property>
+                        <property name="label" translatable="yes">Send PPP _echo packets</property>
                         <property name="use_underline">True</property>
                         <property name="response_id">0</property>
                         <property name="draw_indicator">True</property>
@@ -507,8 +511,7 @@
               <widget class="GtkButton" id="cancel_button">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="label">gtk-cancel</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">-6</property>
               </widget>
@@ -517,8 +520,7 @@
               <widget class="GtkButton" id="ok_button">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="label">gtk-ok</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">-5</property>
               </widget>

Modified: branches/mbca/vpn-daemons/pptp/properties/nm-pptp.c
==============================================================================
--- branches/mbca/vpn-daemons/pptp/properties/nm-pptp.c	(original)
+++ branches/mbca/vpn-daemons/pptp/properties/nm-pptp.c	Mon Aug 18 08:30:28 2008
@@ -38,7 +38,6 @@
 
 #include <nm-vpn-plugin-ui-interface.h>
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 #include <nm-setting-connection.h>
 #include <nm-setting-ip4-config.h>
 
@@ -213,14 +212,14 @@
 init_plugin_ui (PptpPluginUiWidget *self, NMConnection *connection, GError **error)
 {
 	PptpPluginUiWidgetPrivate *priv = PPTP_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
-	NMSettingVPNProperties *s_vpn_props;
+	NMSettingVPN *s_vpn;
 	GtkWidget *widget;
 	GtkListStore *store;
 	GtkTreeIter iter;
 	int active = -1;
-	GValue *value;
+	const char *value;
 
-	s_vpn_props = (NMSettingVPNProperties *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES);
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
 
 	priv->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
@@ -228,10 +227,10 @@
 	if (!widget)
 		return FALSE;
 	gtk_size_group_add_widget (priv->group, widget);
-	if (s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_GATEWAY);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			gtk_entry_set_text (GTK_ENTRY (widget), g_value_get_string (value));
+	if (s_vpn) {
+		value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_GATEWAY);
+		if (value && strlen (value))
+			gtk_entry_set_text (GTK_ENTRY (widget), value);
 	}
 	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 
@@ -239,10 +238,10 @@
 	if (!widget)
 		return FALSE;
 	gtk_size_group_add_widget (priv->group, widget);
-	if (s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_USER);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			gtk_entry_set_text (GTK_ENTRY (widget), g_value_get_string (value));
+	if (s_vpn) {
+		value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_USER);
+		if (value && strlen (value))
+			gtk_entry_set_text (GTK_ENTRY (widget), value);
 	}
 	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 
@@ -250,10 +249,10 @@
 	if (!widget)
 		return FALSE;
 	gtk_size_group_add_widget (priv->group, widget);
-	if (s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_DOMAIN);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			gtk_entry_set_text (GTK_ENTRY (widget), g_value_get_string (value));
+	if (s_vpn) {
+		value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_DOMAIN);
+		if (value && strlen (value))
+			gtk_entry_set_text (GTK_ENTRY (widget), value);
 	}
 	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 
@@ -272,76 +271,12 @@
 	return G_OBJECT (priv->widget);
 }
 
-GValue *
-str_to_gvalue (const char *str)
-{
-	GValue *value;
-
-	value = g_slice_new0 (GValue);
-	g_value_init (value, G_TYPE_STRING);
-	g_value_set_string (value, str);
-
-	return value;
-}
-
-GValue *
-bool_to_gvalue (gboolean b)
-{
-	GValue *value;
-
-	value = g_slice_new0 (GValue);
-	g_value_init (value, G_TYPE_BOOLEAN);
-	g_value_set_boolean (value, b);
-
-	return value;
-}
-
-GValue *
-int_to_gvalue (gint i)
-{
-	GValue *value;
-
-	value = g_slice_new0 (GValue);
-	g_value_init (value, G_TYPE_INT);
-	g_value_set_int (value, i);
-
-	return value;
-}
-
-GValue *
-uint_to_gvalue (guint32 u)
-{
-	GValue *value;
-
-	value = g_slice_new0 (GValue);
-	g_value_init (value, G_TYPE_UINT);
-	g_value_set_uint (value, u);
-
-	return value;
-}
-
 static void
 hash_copy_advanced (gpointer key, gpointer data, gpointer user_data)
 {
 	GHashTable *hash = (GHashTable *) user_data;
-	GValue *value = (GValue *) data;
 
-	if (G_VALUE_HOLDS_STRING (value)) {
-		g_hash_table_insert (hash,
-		                     g_strdup ((const char *) key),
-		                     str_to_gvalue (g_value_get_string (value)));
-	} else if (G_VALUE_HOLDS_INT (value)) {
-		g_hash_table_insert (hash,
-		                     g_strdup ((const char *) key),
-		                     int_to_gvalue (g_value_get_int (value)));
-	} else if (G_VALUE_HOLDS_BOOLEAN (value)) {
-		g_hash_table_insert (hash,
-		                     g_strdup ((const char *) key),
-		                     bool_to_gvalue (g_value_get_boolean (value)));
-	} else {
-		g_warning ("%s: unhandled key '%s' of type '%s'",
-		           __func__, (const char *) key, G_VALUE_TYPE_NAME (value));
-	}
+	g_hash_table_insert (hash, g_strdup ((const char *) key), g_strdup ((const char *) data));
 }
 
 static gboolean
@@ -352,9 +287,8 @@
 	PptpPluginUiWidget *self = PPTP_PLUGIN_UI_WIDGET (iface);
 	PptpPluginUiWidgetPrivate *priv = PPTP_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
 	NMSettingVPN *s_vpn;
-	NMSettingVPNProperties *s_vpn_props;
 	GtkWidget *widget;
-	char *str;
+	const char *str;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	gboolean valid = FALSE;
@@ -364,41 +298,29 @@
 
 	s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
 	s_vpn->service_type = g_strdup (NM_DBUS_SERVICE_PPTP);
-	nm_connection_add_setting (connection, NM_SETTING (s_vpn));
-
-	s_vpn_props = NM_SETTING_VPN_PROPERTIES (nm_setting_vpn_properties_new ());
 
 	/* Gateway */
 	widget = glade_xml_get_widget (priv->xml, "gateway_entry");
-	str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
-	if (str && strlen (str)) {
-		g_hash_table_insert (s_vpn_props->data,
-		                     g_strdup (NM_PPTP_KEY_GATEWAY),
-		                     str_to_gvalue (str));
-	}
+	str = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (str && strlen (str))
+		g_hash_table_insert (s_vpn->data, g_strdup (NM_PPTP_KEY_GATEWAY), g_strdup (str));
 
 	/* Username */
 	widget = glade_xml_get_widget (priv->xml, "user_entry");
-	str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
-	if (str && strlen (str)) {
-		g_hash_table_insert (s_vpn_props->data,
-		                     g_strdup (NM_PPTP_KEY_USER),
-		                     str_to_gvalue (str));
-	}
+	str = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (str && strlen (str))
+		g_hash_table_insert (s_vpn->data, g_strdup (NM_PPTP_KEY_USER), g_strdup (str));
 
 	/* Domain */
 	widget = glade_xml_get_widget (priv->xml, "domain_entry");
-	str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
-	if (str && strlen (str)) {
-		g_hash_table_insert (s_vpn_props->data,
-		                     g_strdup (NM_PPTP_KEY_DOMAIN),
-		                     str_to_gvalue (str));
-	}
+	str = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (str && strlen (str))
+		g_hash_table_insert (s_vpn->data, g_strdup (NM_PPTP_KEY_DOMAIN), g_strdup (str));
 
 	if (priv->advanced)
-		g_hash_table_foreach (priv->advanced, hash_copy_advanced, s_vpn_props->data);
+		g_hash_table_foreach (priv->advanced, hash_copy_advanced, s_vpn->data);
 
-	nm_connection_add_setting (connection, NM_SETTING (s_vpn_props));
+	nm_connection_add_setting (connection, NM_SETTING (s_vpn));
 	valid = TRUE;
 
 done:

Modified: branches/mbca/vpn-daemons/pptp/properties/nm-pptp.h
==============================================================================
--- branches/mbca/vpn-daemons/pptp/properties/nm-pptp.h	(original)
+++ branches/mbca/vpn-daemons/pptp/properties/nm-pptp.h	Mon Aug 18 08:30:28 2008
@@ -82,13 +82,5 @@
 
 GType pptp_plugin_ui_widget_get_type (void);
 
-GValue *int_to_gvalue (gint i);
-
-GValue *uint_to_gvalue (guint32 u);
-
-GValue *bool_to_gvalue (gboolean b);
-
-GValue *str_to_gvalue (const char *str);
-
 #endif	/* _NM_PPTP_H_ */
 

Modified: branches/mbca/vpn-daemons/pptp/src/nm-pptp-pppd-plugin.c
==============================================================================
--- branches/mbca/vpn-daemons/pptp/src/nm-pptp-pppd-plugin.c	(original)
+++ branches/mbca/vpn-daemons/pptp/src/nm-pptp-pppd-plugin.c	Mon Aug 18 08:30:28 2008
@@ -154,8 +154,8 @@
 static void
 nm_ip_up (void *data, int arg)
 {
-	ipcp_options opts = ipcp_gotoptions[ifunit];
-	ipcp_options peer_opts = ipcp_hisoptions[ifunit];
+	ipcp_options opts = ipcp_gotoptions[0];
+	ipcp_options peer_opts = ipcp_hisoptions[0];
 	GHashTable *hash;
 	GArray *array;
 	GValue *val;

Modified: branches/mbca/vpn-daemons/pptp/src/nm-pptp-service.c
==============================================================================
--- branches/mbca/vpn-daemons/pptp/src/nm-pptp-service.c	(original)
+++ branches/mbca/vpn-daemons/pptp/src/nm-pptp-service.c	Mon Aug 18 08:30:28 2008
@@ -46,7 +46,6 @@
 #include <linux/if_ppp.h>
 
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 #include <nm-utils.h>
 
 #include "nm-pptp-service.h"
@@ -228,8 +227,6 @@
 {
 	NMPptpPppServicePrivate *priv = NM_PPTP_PPP_SERVICE_GET_PRIVATE (self);
 	NMSettingVPN *s_vpn;
-	NMSettingVPNProperties *s_vpn_props;
-	GValue *value;
 	const char *username, *password;
 
 	g_return_val_if_fail (self != NULL, FALSE);
@@ -239,7 +236,7 @@
 	memset (priv->password, 0, sizeof (priv->password));
 
 	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
-	if (!s_vpn) {
+	if (!s_vpn || !s_vpn->data) {
 		g_set_error (error,
 		             NM_VPN_PLUGIN_ERROR,
 		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
@@ -248,20 +245,9 @@
 		return FALSE;
 	}
 
-	s_vpn_props = (NMSettingVPNProperties *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES);
-	if (!s_vpn_props || !s_vpn_props->data) {
-		g_set_error (error,
-		             NM_VPN_PLUGIN_ERROR,
-		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
-		             "%s",
-		             "Could not find secrets (connection invalid, no vpn-properties setting).");
-		return FALSE;
-	}
-
 	/* Username; try PPTP specific username first, then generic username */
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_USER);
-	if (value && G_VALUE_HOLDS_STRING (value)) {
-		username = g_value_get_string (value);
+	username = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_USER);
+	if (username && strlen (username)) {
 		if (!username || !strlen (username)) {
 			g_set_error (error,
 			             NM_VPN_PLUGIN_ERROR,
@@ -282,23 +268,13 @@
 		}
 	}
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_PASSWORD);
-	if (!value || !G_VALUE_HOLDS_STRING (value)) {
-		g_set_error (error,
-		             NM_VPN_PLUGIN_ERROR,
-		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
-		             "%s",
-		             "Missing VPN password.");
-		return FALSE;
-	}
-
-	password = g_value_get_string (value);
+	password = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_PASSWORD);
 	if (!password || !strlen (password)) {
 		g_set_error (error,
 		             NM_VPN_PLUGIN_ERROR,
 		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
 		             "%s",
-		             "Invalid VPN password.");
+		             "Missing or invalid VPN password.");
 		return FALSE;
 	}
 
@@ -407,9 +383,8 @@
 };
 
 static gboolean
-validate_gateway (GValue *value)
+validate_gateway (const char *gateway)
 {
-	const char *gateway = g_value_get_string (value);
 	const char *p = gateway;
 
 	if (!gateway || !strlen (gateway))
@@ -426,12 +401,12 @@
 }
 
 static void
-validate_one_property (gpointer key, gpointer val, gpointer user_data)
+validate_one_property (gpointer key, gpointer value, gpointer user_data)
 {
-	gboolean *failed = (gboolean *) user_data;
+	GError **error = (GError **) user_data;
 	int i;
 
-	if (*failed)
+	if (*error)
 		return;
 
 	/* 'name' is the setting name; always allowed but unused */
@@ -440,47 +415,100 @@
 
 	for (i = 0; valid_properties[i].name; i++) {
 		ValidProperty prop = valid_properties[i];
+		long int tmp;
 
-		if (!strcmp (prop.name, (char *) key) && prop.type == G_VALUE_TYPE ((GValue *) val)) {
-			if (!strcmp (prop.name, NM_PPTP_KEY_GATEWAY)) {
-				if (!validate_gateway ((GValue *) val))
-					goto failed;
+		if (strcmp (prop.name, (char *) key))
+			continue;
+
+		switch (prop.type) {
+		case G_TYPE_STRING:
+			if (   !strcmp (prop.name, NM_PPTP_KEY_GATEWAY)
+			    && !validate_gateway (value)) {
+				g_set_error (error,
+				             NM_VPN_PLUGIN_ERROR,
+				             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+				             "invalid gateway '%s'",
+				             (const char *) key);
+				return;
 			}
-			/* Property is ok */
-			return;
+			return; /* valid */
+		case G_TYPE_UINT:
+			errno = 0;
+			tmp = strtol ((char *) value, NULL, 10);
+			if (errno == 0)
+				return; /* valid */
+
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "invalid integer property '%s'",
+			             (const char *) key);
+			break;
+		case G_TYPE_BOOLEAN:
+			if (!strcmp ((char *) value, "yes") || !strcmp ((char *) value, "no"))
+				return; /* valid */
+
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "invalid boolean property '%s' (not yes or no)",
+			             (const char *) key);
+			break;
+		default:
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "unhandled property '%s' type %s",
+			             (const char *) key, g_type_name (prop.type));
+			break;
 		}
 	}
 
-failed:
 	/* Did not find the property from valid_properties or the type did not match */
-	g_warning ("VPN property '%s' failed validation.", (char *) key);
-	*failed = TRUE;
+	if (!valid_properties[i].name) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+		             "property '%s' invalid or not supported",
+		             (const char *) key);
+	}
 }
 
 static gboolean
-nm_pptp_properties_validate (GHashTable *properties)
+nm_pptp_properties_validate (GHashTable *properties, GError **error)
 {
-	gboolean failed = FALSE;
 	int i;
 
-	if (g_hash_table_size (properties) < 1)
-		return failed;
+	if (g_hash_table_size (properties) < 1) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+		             "%s",
+		             "No VPN configuration options.");
+		return FALSE;
+	}
 
-	g_hash_table_foreach (properties, validate_one_property, &failed);
-	if (failed)
+	g_hash_table_foreach (properties, validate_one_property, error);
+	if (*error)
 		return FALSE;
 
 	/* Ensure required properties exist */
 	for (i = 0; valid_properties[i].name; i++) {
 		ValidProperty prop = valid_properties[i];
-		GValue *value;
+		const char *value;
 
 		if (!prop.required)
 			continue;
 
 		value = g_hash_table_lookup (properties, prop.name);
-		if (!value || (G_VALUE_TYPE (value) != prop.type))
+		if (!value || !strlen (value)) {
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "Missing required option '%s'.",
+			             prop.name);
 			return FALSE;
+		}
 	}
 
 	return TRUE;
@@ -602,13 +630,11 @@
 static GPtrArray *
 construct_pppd_args (NMPptpPlugin *plugin,
                      NMSettingVPN *s_vpn,
-                     NMSettingVPNProperties *s_vpn_props,
                      const char *pppd,
                      GError **error)
 {
 	GPtrArray *args = NULL;
-	GValue *value;
-	const char *pptp_binary;
+	const char *value, *pptp_binary;
 	char *ipparam, *tmp;
 
 	pptp_binary = nm_find_pptp ();
@@ -625,8 +651,8 @@
 	g_ptr_array_add (args, (gpointer) g_strdup (pppd));
 
 	/* PPTP options */
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_GATEWAY);
-	if (!value || !G_VALUE_HOLDS_STRING (value)) {
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_GATEWAY);
+	if (!value || !strlen (value)) {
 		g_set_error (error,
 		             NM_VPN_PLUGIN_ERROR,
 		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
@@ -638,8 +664,7 @@
 	ipparam = g_strdup_printf ("nm-pptp-service-%d", getpid ());
 
 	g_ptr_array_add (args, (gpointer) g_strdup ("pty"));
-	tmp = g_strdup_printf ("%s %s --nolaunchpppd --logstring %s",
-	                       pptp_binary, g_value_get_string (value), ipparam);
+	tmp = g_strdup_printf ("%s %s --nolaunchpppd --logstring %s", pptp_binary, value, ipparam);
 	g_ptr_array_add (args, (gpointer) tmp);
 
 	/* PPP options */
@@ -651,66 +676,82 @@
 	g_ptr_array_add (args, (gpointer) g_strdup ("usepeerdns"));
 	g_ptr_array_add (args, (gpointer) g_strdup ("noipdefault"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_REFUSE_EAP);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_REFUSE_EAP);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("refuse-eap"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_REFUSE_PAP);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_REFUSE_PAP);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("refuse-pap"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_REFUSE_CHAP);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_REFUSE_CHAP);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("refuse-chap"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_REFUSE_MSCHAP);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_REFUSE_MSCHAP);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("refuse-mschap"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_REFUSE_MSCHAPV2);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_REFUSE_MSCHAPV2);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("refuse-mschap-v2"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_REQUIRE_MPPE);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_REQUIRE_MPPE);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("require-mppe"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_REQUIRE_MPPE_40);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_REQUIRE_MPPE_40);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("require-mppe-40"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_REQUIRE_MPPE_128);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_REQUIRE_MPPE_128);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("require-mppe-128"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_MPPE_STATEFUL);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_MPPE_STATEFUL);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("mppe-stateful"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_NOBSDCOMP);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_NOBSDCOMP);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("nobsdcomp"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_NODEFLATE);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_NODEFLATE);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("nodeflate"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_NO_VJ_COMP);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_NO_VJ_COMP);
+	if (value && !strcmp (value, "yes"))
 		g_ptr_array_add (args, (gpointer) g_strdup ("novj"));
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_LCP_ECHO_FAILURE);
-	if (value && G_VALUE_HOLDS_UINT (value) && g_value_get_uint (value)) {
-		g_ptr_array_add (args, (gpointer) g_strdup ("lcp-echo-failure"));
-		tmp = g_strdup_printf ("%d", g_value_get_uint (value));
-		g_ptr_array_add (args, (gpointer) tmp);
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_LCP_ECHO_FAILURE);
+	if (value && strlen (value)) {
+		long int tmp_int;
+
+		/* Convert to integer and then back to string for security's sake
+		 * because strtol ignores some leading and trailing characters.
+		 */
+		errno = 0;
+		tmp_int = strtol (value, NULL, 10);
+		if (errno == 0) {
+			g_ptr_array_add (args, (gpointer) g_strdup ("lcp-echo-failure"));
+			g_ptr_array_add (args, (gpointer) g_strdup_printf ("%ld", tmp_int));
+		}
 	}
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_LCP_ECHO_INTERVAL);
-	if (value && G_VALUE_HOLDS_UINT (value) && g_value_get_uint (value)) {
-		g_ptr_array_add (args, (gpointer) g_strdup ("lcp-echo-interval"));
-		tmp = g_strdup_printf ("%d", g_value_get_uint (value));
-		g_ptr_array_add (args, (gpointer) tmp);
+	value = g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_LCP_ECHO_INTERVAL);
+	if (value && strlen (value)) {
+		long int tmp_int;
+
+		/* Convert to integer and then back to string for security's sake
+		 * because strtol ignores some leading and trailing characters.
+		 */
+		errno = 0;
+		tmp_int = strtol (value, NULL, 10);
+		if (errno == 0) {
+			g_ptr_array_add (args, (gpointer) g_strdup ("lcp-echo-interval"));
+			g_ptr_array_add (args, (gpointer) g_strdup_printf ("%ld", tmp_int));
+		}
 	}
 
 	g_ptr_array_add (args, (gpointer) g_strdup ("plugin"));
@@ -728,29 +769,30 @@
 static gboolean
 nm_pptp_start_pppd_binary (NMPptpPlugin *plugin,
                            NMSettingVPN *s_vpn,
-                           NMSettingVPNProperties *s_vpn_props)
+                           GError **error)
 {
 	NMPptpPluginPrivate *priv = NM_PPTP_PLUGIN_GET_PRIVATE (plugin);
 	GPid pid;
 	const char *pppd_binary;
 	GPtrArray *pppd_argv;
-	GError *err = NULL;
 
 	pppd_binary = nm_find_pppd ();
 	if (!pppd_binary) {
-		nm_info ("Could not find pppd binary.");
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
+		             "%s",
+		             "Could not find the pppd binary.");
 		return FALSE;
 	}
 
-	pppd_argv = construct_pppd_args (plugin, s_vpn, s_vpn_props, pppd_binary, &err);
+	pppd_argv = construct_pppd_args (plugin, s_vpn, pppd_binary, error);
 	if (!pppd_argv)
 		return FALSE;
 
 	if (!g_spawn_async (NULL, (char **) pppd_argv->pdata, NULL,
-	                    G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &err)) {
+	                    G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, error)) {
 		g_ptr_array_free (pppd_argv, TRUE);
-		nm_warning ("pppd failed to start.  error: '%s'", err->message);
-		g_error_free (err);
 		return FALSE;
 	}
 	free_pppd_args (pppd_argv);
@@ -814,24 +856,15 @@
 static gboolean
 real_connect (NMVPNPlugin   *plugin,
               NMConnection  *connection,
-              GError       **err)
+              GError       **error)
 {
 	NMPptpPluginPrivate *priv = NM_PPTP_PLUGIN_GET_PRIVATE (plugin);
 	NMSettingVPN *s_vpn;
-	NMSettingVPNProperties *s_vpn_props;
-
-	s_vpn_props = NM_SETTING_VPN_PROPERTIES (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES));
-	if (!s_vpn_props || !nm_pptp_properties_validate (s_vpn_props->data)) {
-		g_set_error (err,
-				   NM_VPN_PLUGIN_ERROR,
-				   NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
-				   "%s",
-				   "Invalid arguments.");
-		return FALSE;
-	}
 
 	s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN));
 	g_assert (s_vpn);
+	if (!nm_pptp_properties_validate (s_vpn->data, error))
+		return FALSE;
 
 	/* Start our pppd plugin helper service */
 	if (priv->service)
@@ -839,7 +872,7 @@
 
 	priv->service = nm_pptp_ppp_service_new ();
 	if (!priv->service) {
-		g_set_error (err,
+		g_set_error (error,
 		             NM_VPN_PLUGIN_ERROR,
 		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
 		             "%s",
@@ -853,17 +886,11 @@
 	/* Cache the username and password so we can relay the secrets to the pppd
 	 * plugin when it asks for them.
 	 */
-	if (!nm_pptp_ppp_service_cache_credentials (priv->service, connection, err))
+	if (!nm_pptp_ppp_service_cache_credentials (priv->service, connection, error))
 		return FALSE;
 
-	if (!nm_pptp_start_pppd_binary (NM_PPTP_PLUGIN (plugin), s_vpn, s_vpn_props)) {
-		g_set_error (err,
-		             NM_VPN_PLUGIN_ERROR,
-		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
-		             "%s",
-		             "Could not start pppd binary.");
+	if (!nm_pptp_start_pppd_binary (NM_PPTP_PLUGIN (plugin), s_vpn, error))
 		return FALSE;
-	}
 
 	return TRUE;
 }
@@ -874,13 +901,13 @@
                    char **setting_name,
                    GError **error)
 {
-	NMSettingVPNProperties *s_vpn_props;
+	NMSettingVPN *s_vpn;
 
 	g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
 
-	s_vpn_props = NM_SETTING_VPN_PROPERTIES (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES));
-	if (!s_vpn_props) {
+	s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN));
+	if (!s_vpn) {
         g_set_error (error,
 		             NM_VPN_PLUGIN_ERROR,
 		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
@@ -889,8 +916,8 @@
 		return FALSE;
 	}
 
-	if (!g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_PASSWORD)) {
-		*setting_name = NM_SETTING_VPN_PROPERTIES_SETTING_NAME;
+	if (!g_hash_table_lookup (s_vpn->data, NM_PPTP_KEY_PASSWORD)) {
+		*setting_name = NM_SETTING_VPN_SETTING_NAME;
 		return TRUE;
 	}
 

Modified: branches/mbca/vpn-daemons/vpnc/auth-dialog/main.c
==============================================================================
--- branches/mbca/vpn-daemons/vpnc/auth-dialog/main.c	(original)
+++ branches/mbca/vpn-daemons/vpnc/auth-dialog/main.c	Mon Aug 18 08:30:28 2008
@@ -30,7 +30,6 @@
 #include <gnome-keyring.h>
 
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 
 #include "../src/nm-vpnc-service.h"
 #include "gnome-two-password-dialog.h"
@@ -58,7 +57,7 @@
 	                                      vpn_id,
 	                                      KEYRING_SN_TAG,
 	                                      GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
-	                                      NM_SETTING_VPN_PROPERTIES_SETTING_NAME,
+	                                      NM_SETTING_VPN_SETTING_NAME,
 	                                      KEYRING_SK_TAG,
 	                                      GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
 	                                      secret_name,
@@ -115,7 +114,7 @@
 	GnomeKeyringAttributeList *attrs = NULL;
 	guint32 id = 0;
 
-	display_name = g_strdup_printf ("VPN %s secret for %s/%s/" NM_SETTING_VPN_PROPERTIES_SETTING_NAME,
+	display_name = g_strdup_printf ("VPN %s secret for %s/%s/" NM_SETTING_VPN_SETTING_NAME,
 	                                secret_name,
 	                                vpn_name,
 	                                vpn_service);
@@ -126,7 +125,7 @@
 	                                            vpn_id);
 	gnome_keyring_attribute_list_append_string (attrs,
 	                                            KEYRING_SN_TAG,
-	                                            NM_SETTING_VPN_PROPERTIES_SETTING_NAME);
+	                                            NM_SETTING_VPN_SETTING_NAME);
 	gnome_keyring_attribute_list_append_string (attrs,
 	                                            KEYRING_SK_TAG,
 	                                            secret_name);

Modified: branches/mbca/vpn-daemons/vpnc/properties/nm-vpnc.c
==============================================================================
--- branches/mbca/vpn-daemons/vpnc/properties/nm-vpnc.c	(original)
+++ branches/mbca/vpn-daemons/vpnc/properties/nm-vpnc.c	Mon Aug 18 08:30:28 2008
@@ -40,7 +40,6 @@
 
 #include <nm-vpn-plugin-ui-interface.h>
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 #include <nm-setting-connection.h>
 #include <nm-setting-ip4-config.h>
 
@@ -159,15 +158,15 @@
 init_plugin_ui (VpncPluginUiWidget *self, NMConnection *connection, GError **error)
 {
 	VpncPluginUiWidgetPrivate *priv = VPNC_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
-	NMSettingVPNProperties *s_vpn_props;
+	NMSettingVPN *s_vpn;
 	GtkWidget *widget;
 	GtkListStore *store;
 	GtkTreeIter iter;
+	char *value;
 	int active = -1;
-	GValue *value;
 	const char *natt_mode = NULL;
 
-	s_vpn_props = (NMSettingVPNProperties *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES);
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
 
 	priv->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
@@ -175,10 +174,10 @@
 	if (!widget)
 		return FALSE;
 	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
-	if (s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_GATEWAY);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			gtk_entry_set_text (GTK_ENTRY (widget), g_value_get_string (value));
+	if (s_vpn) {
+		value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_GATEWAY);
+		if (value && strlen (value))
+			gtk_entry_set_text (GTK_ENTRY (widget), value);
 	}
 	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 
@@ -186,10 +185,10 @@
 	if (!widget)
 		return FALSE;
 	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
-	if (s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_ID);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			gtk_entry_set_text (GTK_ENTRY (widget), g_value_get_string (value));
+	if (s_vpn) {
+		value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_ID);
+		if (value && strlen (value))
+			gtk_entry_set_text (GTK_ENTRY (widget), value);
 	}
 	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 
@@ -205,17 +204,17 @@
 
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter, 0, _("Weak (use with caution)"), -1);
-	if ((active < 0) && s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_SINGLE_DES);
-		if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	if (s_vpn && (active < 0)) {
+		value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_SINGLE_DES);
+		if (value && !strcmp (value, "yes"))
 			active = 1;
 	}
 
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter, 0, _("None (completely insecure)"), -1);
-	if ((active < 0) && s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_NO_ENCRYPTION);
-		if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	if (s_vpn && (active < 0)) {
+		value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_NO_ENCRYPTION);
+		if (value && !strcmp (value, "yes"))
 			active = 2;
 	}
 
@@ -228,12 +227,10 @@
 	if (!widget)
 		return FALSE;
 	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
-	if (s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_XAUTH_USER);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			gtk_entry_set_text (GTK_ENTRY (widget), g_value_get_string (value));
-		else {
-		}
+	if (s_vpn) {
+		value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_XAUTH_USER);
+		if (value && strlen (value))
+			gtk_entry_set_text (GTK_ENTRY (widget), value);
 	}
 	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 
@@ -241,20 +238,17 @@
 	if (!widget)
 		return FALSE;
 	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
-	if (s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_DOMAIN);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			gtk_entry_set_text (GTK_ENTRY (widget), g_value_get_string (value));
+	if (s_vpn) {
+		value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_DOMAIN);
+		if (value && strlen (value))
+			gtk_entry_set_text (GTK_ENTRY (widget), value);
 	}
 	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 
 	active = -1;
 	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
-	if (s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
-		if (value && G_VALUE_HOLDS_STRING (value))
-			natt_mode = g_value_get_string (value);
-	}
+	if (s_vpn)
+		natt_mode = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
 
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter, 0, _("NAT-T (default)"), 1, NM_VPNC_NATT_MODE_NATT, -1);
@@ -289,10 +283,16 @@
 	widget = glade_xml_get_widget (priv->xml, "disable_dpd_checkbutton");
 	if (!widget)
 		return FALSE;
-	if (s_vpn_props) {
-		value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_DPD_IDLE_TIMEOUT);
-		if (value && G_VALUE_HOLDS_INT (value)) {
-			priv->orig_dpd_timeout = g_value_get_int (value);
+	if (s_vpn) {
+		value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_DPD_IDLE_TIMEOUT);
+		if (value) {
+			long int tmp;
+
+			errno = 0;
+			tmp = strtol (value, NULL, 10);
+			if (tmp >= 0 && tmp <= G_MAXUINT32 && errno == 0)
+				priv->orig_dpd_timeout = (guint32) tmp;
+
 			if (priv->orig_dpd_timeout == 0)
 				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 		}
@@ -311,42 +311,6 @@
 	return G_OBJECT (priv->widget);
 }
 
-static GValue *
-str_to_gvalue (const char *str)
-{
-	GValue *value;
-
-	value = g_slice_new0 (GValue);
-	g_value_init (value, G_TYPE_STRING);
-	g_value_set_string (value, str);
-
-	return value;
-}
-
-static GValue *
-bool_to_gvalue (gboolean b)
-{
-	GValue *value;
-
-	value = g_slice_new0 (GValue);
-	g_value_init (value, G_TYPE_BOOLEAN);
-	g_value_set_boolean (value, b);
-
-	return value;
-}
-
-static GValue *
-int_to_gvalue (gint i)
-{
-	GValue *value;
-
-	value = g_slice_new0 (GValue);
-	g_value_init (value, G_TYPE_INT);
-	g_value_set_int (value, i);
-
-	return value;
-}
-
 static gboolean
 update_connection (NMVpnPluginUiWidgetInterface *iface,
                    NMConnection *connection,
@@ -355,7 +319,6 @@
 	VpncPluginUiWidget *self = VPNC_PLUGIN_UI_WIDGET (iface);
 	VpncPluginUiWidgetPrivate *priv = VPNC_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
 	NMSettingVPN *s_vpn;
-	NMSettingVPNProperties *s_vpn_props;
 	GtkWidget *widget;
 	char *str;
 	GtkTreeModel *model;
@@ -366,55 +329,52 @@
 
 	s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
 	s_vpn->service_type = g_strdup (NM_DBUS_SERVICE_VPNC);
-	nm_connection_add_setting (connection, NM_SETTING (s_vpn));
-
-	s_vpn_props = NM_SETTING_VPN_PROPERTIES (nm_setting_vpn_properties_new ());
 
 	/* Gateway */
 	widget = glade_xml_get_widget (priv->xml, "gateway_entry");
 	str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
 	if (str && strlen (str)) {
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_VPNC_KEY_GATEWAY),
-		                     str_to_gvalue (str));
+		                     g_strdup (str));
 	}
 
 	/* Group name */
 	widget = glade_xml_get_widget (priv->xml, "group_entry");
 	str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
 	if (str && strlen (str)) {
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_VPNC_KEY_ID),
-		                     str_to_gvalue (str));
+		                     g_strdup (str));
 	}
 
 	widget = glade_xml_get_widget (priv->xml, "user_entry");
 	str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
 	if (str && strlen (str)) {
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_VPNC_KEY_XAUTH_USER),
-		                     str_to_gvalue (str));
+		                     g_strdup (str));
 	}
 
 	widget = glade_xml_get_widget (priv->xml, "domain_entry");
 	str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
 	if (str && strlen (str)) {
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_VPNC_KEY_DOMAIN),
-		                     str_to_gvalue (str));
+		                     g_strdup (str));
 	}
 
 	widget = glade_xml_get_widget (priv->xml, "encryption_combo");
 	switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget))) {
 	case ENC_TYPE_WEAK:
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_VPNC_KEY_SINGLE_DES),
-		                     bool_to_gvalue (TRUE));
+		                     g_strdup ("yes"));
 		break;
 	case ENC_TYPE_NONE:
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_VPNC_KEY_NO_ENCRYPTION),
-		                     bool_to_gvalue (TRUE));
+		                     g_strdup ("yes"));
 		break;
 	case ENC_TYPE_SECURE:
 	default:
@@ -427,27 +387,27 @@
 		const char *mode;
 
 		gtk_tree_model_get (model, &iter, 1, &mode, -1);
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_VPNC_KEY_NAT_TRAVERSAL_MODE),
-		                     str_to_gvalue (mode));
+		                     g_strdup (mode));
 	} else {
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_VPNC_KEY_NAT_TRAVERSAL_MODE),
-		                     str_to_gvalue (NM_VPNC_NATT_MODE_NATT));
+		                     g_strdup (NM_VPNC_NATT_MODE_NATT));
 	}
 	
 	widget = glade_xml_get_widget (priv->xml, "disable_dpd_checkbutton");
 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_VPNC_KEY_DPD_IDLE_TIMEOUT),
-		                     int_to_gvalue (0));
+		                     g_strdup ("0"));
 	} else {
-		g_hash_table_insert (s_vpn_props->data,
+		g_hash_table_insert (s_vpn->data,
 		                     g_strdup (NM_VPNC_KEY_DPD_IDLE_TIMEOUT),
-		                     int_to_gvalue (priv->orig_dpd_timeout));
+		                     g_strdup_printf ("%d", priv->orig_dpd_timeout));
 	}
 
-	nm_connection_add_setting (connection, NM_SETTING (s_vpn_props));
+	nm_connection_add_setting (connection, NM_SETTING (s_vpn));
 	return TRUE;
 }
 
@@ -591,7 +551,6 @@
 	NMConnection *connection;
 	NMSettingConnection *s_con;
 	NMSettingVPN *s_vpn;
-	NMSettingVPNProperties *s_vpn_props;
 	GHashTable *pcf;
 	const char *buf;
 	gboolean have_value;
@@ -611,9 +570,6 @@
 	s_vpn->service_type = g_strdup (VPNC_PLUGIN_SERVICE);
 	nm_connection_add_setting (connection, NM_SETTING (s_vpn));
 
-	s_vpn_props = NM_SETTING_VPN_PROPERTIES (nm_setting_vpn_properties_new ());
-	nm_connection_add_setting (connection, NM_SETTING (s_vpn_props));
-
 	/* Connection name */
 	if ((buf = pcf_file_lookup_value (pcf, "main", "Description")))
 		s_con->id = g_strdup (buf);
@@ -626,7 +582,7 @@
 
 	/* Gateway */
 	if ((buf = pcf_file_lookup_value (pcf, "main", "Host")))
-		g_hash_table_insert (s_vpn_props->data, g_strdup (NM_VPNC_KEY_GATEWAY), str_to_gvalue (buf));
+		g_hash_table_insert (s_vpn->data, g_strdup (NM_VPNC_KEY_GATEWAY), g_strdup (buf));
 	else {
 		g_set_error (error, 0, 0, "does not look like a %s VPN connection (no Host)",
 		             VPNC_PLUGIN_NAME);
@@ -636,7 +592,7 @@
 
 	/* Group name */
 	if ((buf = pcf_file_lookup_value (pcf, "main", "GroupName")))
-		g_hash_table_insert (s_vpn_props->data, g_strdup (NM_VPNC_KEY_ID), str_to_gvalue (buf));
+		g_hash_table_insert (s_vpn->data, g_strdup (NM_VPNC_KEY_ID), g_strdup (buf));
 	else {
 		g_set_error (error, 0, 0, "does not look like a %s VPN connection (no GroupName)",
 		             VPNC_PLUGIN_NAME);
@@ -649,29 +605,34 @@
 	buf = pcf_file_lookup_value (pcf, "main", "UserName");
 	have_value = buf == NULL ? FALSE : strlen (buf) > 0;
 	if (have_value)
-		g_hash_table_insert (s_vpn_props->data, g_strdup (NM_VPNC_KEY_XAUTH_USER), str_to_gvalue (buf));
+		g_hash_table_insert (s_vpn->data, g_strdup (NM_VPNC_KEY_XAUTH_USER), g_strdup (buf));
 
 	buf = pcf_file_lookup_value (pcf, "main", "NTDomain");
 	have_value = buf == NULL ? FALSE : strlen (buf) > 0;
 	if (have_value)
-		g_hash_table_insert (s_vpn_props->data, g_strdup (NM_VPNC_KEY_DOMAIN), str_to_gvalue (buf));
+		g_hash_table_insert (s_vpn->data, g_strdup (NM_VPNC_KEY_DOMAIN), g_strdup (buf));
 
 	buf = pcf_file_lookup_value (pcf, "main", "SingleDES");
 	have_value = (buf == NULL ? FALSE : strcmp (buf, "0") != 0);
 	if (have_value)
-		g_hash_table_insert (s_vpn_props->data, g_strdup (NM_VPNC_KEY_SINGLE_DES), bool_to_gvalue (TRUE));
+		g_hash_table_insert (s_vpn->data, g_strdup (NM_VPNC_KEY_SINGLE_DES), g_strdup ("yes"));
 
 	/* Default is enabled, only disabled if explicit EnableNat=0 exists */
 	buf = pcf_file_lookup_value (pcf, "main", "EnableNat");
 	have_value = (buf ? strncmp (buf, "0", 1) == 0 : FALSE);
 	if (have_value)
-		g_hash_table_insert (s_vpn_props->data, g_strdup (NM_VPNC_KEY_NAT_TRAVERSAL_MODE), str_to_gvalue (NM_VPNC_NATT_MODE_NATT));
+		g_hash_table_insert (s_vpn->data, g_strdup (NM_VPNC_KEY_NAT_TRAVERSAL_MODE), g_strdup (NM_VPNC_NATT_MODE_NATT));
 
 	if ((buf = pcf_file_lookup_value (pcf, "main", "PeerTimeout"))) {
-		gulong val = strtol (buf, NULL, 10);
+		long int val;
 
-		if ((val == 0) || ((val > 10) && (val < 86400)))
-			g_hash_table_insert (s_vpn_props->data, g_strdup (NM_VPNC_KEY_DPD_IDLE_TIMEOUT), int_to_gvalue ((gint) val));
+		errno = 0;
+		val = strtol (buf, NULL, 10);
+		if ((errno == 0) && ((val == 0) || ((val >= 10) && (val <= 86400)))) {
+			g_hash_table_insert (s_vpn->data,
+			                     g_strdup (NM_VPNC_KEY_DPD_IDLE_TIMEOUT),
+			                     g_strdup_printf ("%d", (gint) val));
+		}
 	}
 
 	buf = pcf_file_lookup_value (pcf, "main", "X-NM-Routes");
@@ -715,25 +676,25 @@
         GError **error)
 {
 	NMSettingConnection *s_con;
-	NMSettingVPNProperties *s_vpn_props;
 	NMSettingIP4Config *s_ip4;
+	NMSettingVPN *s_vpn;
 	FILE *f;
-	GValue *value;
+	const char *value;
 	const char *gateway = NULL;
 	gboolean enablenat = TRUE;
 	gboolean singledes = FALSE;
 	const char *groupname = NULL;
 	const char *username = NULL;
 	const char *domain = NULL;
-	int peertimeout = 0;
+	const char *peertimeout = NULL;
 	GString *routes = NULL;
 	gboolean success = FALSE;
 
 	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
 	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
 
-	s_vpn_props = (NMSettingVPNProperties *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES);
-	if (!s_vpn_props || !s_vpn_props->data) {
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	if (!s_vpn || !s_vpn->data) {
 		g_set_error (error, 0, 0, "connection was incomplete");
 		return FALSE;
 	}
@@ -744,43 +705,41 @@
 		return FALSE;
 	}
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_GATEWAY);
-	if (value && G_VALUE_HOLDS_STRING (value))
-		gateway = g_value_get_string (value);
+	value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_GATEWAY);
+	if (value && strlen (value))
+		gateway = value;
 	else {
 		g_set_error (error, 0, 0, "connection was incomplete (missing gateway)");
 		goto done;
 	}
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_ID);
-	if (value && G_VALUE_HOLDS_STRING (value))
-		groupname = g_value_get_string (value);
+	value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_ID);
+	if (value && strlen (value))
+		groupname = value;
 	else {
 		g_set_error (error, 0, 0, "connection was incomplete (missing group)");
 		goto done;
 	}
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_XAUTH_USER);
-	if (value && G_VALUE_HOLDS_STRING (value))
-		username = g_value_get_string (value);
-
-	value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_DOMAIN);
-	if (value && G_VALUE_HOLDS_STRING (value))
-		domain = g_value_get_string (value);
+	value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_XAUTH_USER);
+	if (value && strlen (value))
+		username = value;
+
+	value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_DOMAIN);
+	if (value && strlen (value))
+		domain =  value;
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_SINGLE_DES);
-	if (value && G_VALUE_HOLDS_BOOLEAN (value) && g_value_get_boolean (value))
+	value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_SINGLE_DES);
+	if (value && !strcmp (value, "yes"))
 		singledes = TRUE;
 
-	value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
-	if (value && G_VALUE_HOLDS_STRING (value)) {
-		if (strlen (g_value_get_string (value)))
-			enablenat = TRUE;
-	}
-
-	value = g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_DPD_IDLE_TIMEOUT);
-	if (value && G_VALUE_HOLDS_INT (value))
-		peertimeout = g_value_get_int (value);
+	value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
+	if (value && strlen (value) && strcmp (value, NM_VPNC_NATT_MODE_NONE))
+		enablenat = TRUE;
+
+	value = g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_DPD_IDLE_TIMEOUT);
+	if (value && strlen (value))
+		peertimeout = value;
 
 	routes = g_string_new ("");
 	if (s_ip4 && s_ip4->routes) {
@@ -831,7 +790,7 @@
 		 "MSLogonType=0\n"
 		 "TunnelingMode=0\n"
 		 "TcpTunnelingPort=10000\n"
-		 "PeerTimeout=%d\n"
+		 "PeerTimeout=%s\n"
 		 "EnableLocalLAN=1\n"
 		 "SendCertChain=0\n"
 		 "VerifyCertDN=\n"
@@ -845,7 +804,7 @@
 		 /* Username */    username != NULL ? username : "",
 		 /* EnableNat */   enablenat ? "1" : "0",
 		 /* NTDomain */    domain != NULL ? domain : "",
-		 /* PeerTimeout */ peertimeout,
+		 /* PeerTimeout */ peertimeout != NULL ? peertimeout : "0",
 		 /* SingleDES */   singledes ? "1" : "0",
 		 /* X-NM-Routes */ routes->str ? routes->str : "");
 

Modified: branches/mbca/vpn-daemons/vpnc/src/nm-vpnc-service.c
==============================================================================
--- branches/mbca/vpn-daemons/vpnc/src/nm-vpnc-service.c	(original)
+++ branches/mbca/vpn-daemons/vpnc/src/nm-vpnc-service.c	Mon Aug 18 08:30:28 2008
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 
 #include <stdio.h>
 #include <string.h>
@@ -8,9 +8,9 @@
 #include <signal.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
+#include <errno.h>
 
 #include <nm-setting-vpn.h>
-#include <nm-setting-vpn-properties.h>
 #include "nm-vpnc-service.h"
 #include "nm-utils.h"
 
@@ -36,37 +36,39 @@
 typedef struct {
 	const char *name;
 	GType type;
+	gint int_min;
+	gint int_max;
 } ValidProperty;
 
 #define LEGACY_NAT_KEEPALIVE "NAT-Keepalive packet interval"
 
 static ValidProperty valid_properties[] = {
-	{ NM_VPNC_KEY_GATEWAY,               G_TYPE_STRING },
-	{ NM_VPNC_KEY_ID,                    G_TYPE_STRING },
-	{ NM_VPNC_KEY_SECRET,                G_TYPE_STRING },
-	{ NM_VPNC_KEY_XAUTH_USER,            G_TYPE_STRING },
-	{ NM_VPNC_KEY_XAUTH_PASSWORD,        G_TYPE_STRING },
-	{ NM_VPNC_KEY_DOMAIN,                G_TYPE_STRING },
-	{ NM_VPNC_KEY_DHGROUP,               G_TYPE_STRING },
-	{ NM_VPNC_KEY_PERFECT_FORWARD,       G_TYPE_STRING },
-	{ NM_VPNC_KEY_APP_VERSION,           G_TYPE_STRING },
-	{ NM_VPNC_KEY_SINGLE_DES,            G_TYPE_BOOLEAN },
-	{ NM_VPNC_KEY_NO_ENCRYPTION,         G_TYPE_BOOLEAN },
-	{ NM_VPNC_KEY_DPD_IDLE_TIMEOUT,      G_TYPE_INT },
-	{ NM_VPNC_KEY_NAT_TRAVERSAL_MODE,    G_TYPE_STRING },
-	{ NM_VPNC_KEY_CISCO_UDP_ENCAPS_PORT, G_TYPE_INT },
+	{ NM_VPNC_KEY_GATEWAY,               G_TYPE_STRING, 0, 0 },
+	{ NM_VPNC_KEY_ID,                    G_TYPE_STRING, 0, 0 },
+	{ NM_VPNC_KEY_SECRET,                G_TYPE_STRING, 0, 0 },
+	{ NM_VPNC_KEY_XAUTH_USER,            G_TYPE_STRING, 0, 0 },
+	{ NM_VPNC_KEY_XAUTH_PASSWORD,        G_TYPE_STRING, 0, 0 },
+	{ NM_VPNC_KEY_DOMAIN,                G_TYPE_STRING, 0, 0 },
+	{ NM_VPNC_KEY_DHGROUP,               G_TYPE_STRING, 0, 0 },
+	{ NM_VPNC_KEY_PERFECT_FORWARD,       G_TYPE_STRING, 0, 0 },
+	{ NM_VPNC_KEY_APP_VERSION,           G_TYPE_STRING, 0, 0 },
+	{ NM_VPNC_KEY_SINGLE_DES,            G_TYPE_BOOLEAN, 0, 0 },
+	{ NM_VPNC_KEY_NO_ENCRYPTION,         G_TYPE_BOOLEAN, 0, 0 },
+	{ NM_VPNC_KEY_DPD_IDLE_TIMEOUT,      G_TYPE_INT, 0, 86400 },
+	{ NM_VPNC_KEY_NAT_TRAVERSAL_MODE,    G_TYPE_STRING, 0, 0 },
+	{ NM_VPNC_KEY_CISCO_UDP_ENCAPS_PORT, G_TYPE_INT, 0, 65535 },
 	/* Legacy options that are ignored */
-	{ LEGACY_NAT_KEEPALIVE,              G_TYPE_STRING },
-	{ NULL,                              G_TYPE_NONE }
+	{ LEGACY_NAT_KEEPALIVE,              G_TYPE_STRING, 0, 0 },
+	{ NULL,                              G_TYPE_NONE, 0, 0 }
 };
 
 static void
-validate_one_property (gpointer key, gpointer val, gpointer user_data)
+validate_one_property (gpointer key, gpointer value, gpointer user_data)
 {
-	gboolean *failed = (gboolean *) user_data;
+	GError **error = (GError **) user_data;
 	int i;
 
-	if (*failed)
+	if (*error)
 		return;
 
 	/* 'name' is the setting name; always allowed but unused */
@@ -75,28 +77,71 @@
 
 	for (i = 0; valid_properties[i].name; i++) {
 		ValidProperty prop = valid_properties[i];
+		long int tmp;
 
-		if (!strcmp (prop.name, (char *) key) && prop.type == G_VALUE_TYPE ((GValue *) val))
-			/* Property is ok */
-			return;
+		if (strcmp (prop.name, (char *) key))
+			continue;
+
+		switch (prop.type) {
+		case G_TYPE_STRING:
+			return; /* valid */
+		case G_TYPE_INT:
+			errno = 0;
+			tmp = strtol ((char *) value, NULL, 10);
+			if (errno == 0 && tmp >= prop.int_min && tmp <= prop.int_max)
+				return; /* valid */
+
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "invalid integer property '%s' or out of range [%d -> %d]",
+			             (const char *) key, prop.int_min, prop.int_max);
+			break;
+		case G_TYPE_BOOLEAN:
+			if (!strcmp ((char *) value, "yes") || !strcmp ((char *) value, "no"))
+				return; /* valid */
+
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "invalid boolean property '%s' (not yes or no)",
+			             (const char *) key);
+			break;
+		default:
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "unhandled property '%s' type %s",
+			             (const char *) key, g_type_name (prop.type));
+			break;
+		}
 	}
 
 	/* Did not find the property from valid_properties or the type did not match */
-	g_warning ("VPN property '%s' failed validation.", (char *) key);
-	*failed = TRUE;
+	if (!valid_properties[i].name) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+		             "property '%s' invalid or not supported",
+		             (const char *) key);
+	}
 }
 
 static gboolean
-nm_vpnc_properties_validate (GHashTable *properties)
+nm_vpnc_properties_validate (GHashTable *properties, GError **error)
 {
-	gboolean failed = FALSE;
-
-	if (g_hash_table_size (properties) < 1)
-		return failed;
+	if (g_hash_table_size (properties) < 1) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+		             "%s",
+		             "No VPN configuration options.");
+		return FALSE;
+	}
 
-	g_hash_table_foreach (properties, validate_one_property, &failed);
+	g_hash_table_foreach (properties, validate_one_property, error);
 
-	return !failed;
+	return *error ? FALSE : TRUE;
 }
 
 static void
@@ -140,12 +185,11 @@
 }
 
 static gint
-nm_vpnc_start_vpnc_binary (NMVPNCPlugin *plugin)
+nm_vpnc_start_vpnc_binary (NMVPNCPlugin *plugin, GError **error)
 {
 	GPid	pid;
 	const char **vpnc_binary = NULL;
 	GPtrArray *vpnc_argv;
-	GError *err = NULL;
 	GSource *vpnc_watch;
 	gint	stdin_fd;
 
@@ -158,7 +202,11 @@
 	}
 
 	if (!*vpnc_binary) {
-		nm_info ("Could not find vpnc binary.");
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
+		             "%s",
+		             "Could not find vpnc binary.");
 		return -1;
 	}
 
@@ -171,10 +219,9 @@
 
 	if (!g_spawn_async_with_pipes (NULL, (char **) vpnc_argv->pdata, NULL,
 							 G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &stdin_fd,
-							 NULL, NULL, &err)) {
+							 NULL, NULL, error)) {
 		g_ptr_array_free (vpnc_argv, TRUE);
-		nm_warning ("vpnc failed to start.  error: '%s'", err->message);
-		g_error_free (err);
+		nm_warning ("vpnc failed to start.  error: '%s'", (*error)->message);
 		return -1;
 	}
 	g_ptr_array_free (vpnc_argv, TRUE);
@@ -204,37 +251,79 @@
 	va_end (args);
 }
 
+typedef struct {
+	int fd;
+	GError *error;
+} WriteConfigInfo;
+
 static void
-write_one_property (gpointer key, gpointer val, gpointer user_data)
+write_one_property (gpointer key, gpointer value, gpointer user_data)
 {
-	gint vpnc_fd = GPOINTER_TO_INT (user_data);
-	GValue *value = (GValue *) val;
-	GType type;
+	WriteConfigInfo *info = (WriteConfigInfo *) user_data;
+	GType type = G_TYPE_INVALID;
+	int i;
+
+	if (info->error)
+		return;
+
+	/* Find the value in the table to get its type */
+	for (i = 0; valid_properties[i].name; i++) {
+		ValidProperty prop = valid_properties[i];
+
+		if (!strcmp (prop.name, (char *) key)) {
+			/* Property is ok */
+			type = prop.type;
+			break;
+		}
+	}
+
+	if (type == G_TYPE_INVALID) {
+		g_set_error (&info->error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+		             "Config option '%s' invalid or unknown.",
+		             (const char *) key);
+	}	
 
-	type = G_VALUE_TYPE (value);
 	if (type == G_TYPE_STRING)
-		write_config_option (vpnc_fd, "%s %s\n", (char *) key, g_value_get_string (value));
-	else if (type == G_TYPE_BOOLEAN)
-		write_config_option (vpnc_fd, "%s\n", (char *) key);
-	else if (type == G_TYPE_INT)
-		write_config_option (vpnc_fd, "%s %d\n", (char *) key, g_value_get_int (value));
-	else if (type == DBUS_TYPE_G_UCHAR_ARRAY) {
-		char *tmp;
-
-		tmp = nm_utils_garray_to_string ((GArray *) g_value_get_boxed (value));
-		write_config_option (vpnc_fd, "%s %s\n", tmp);
-		g_free (tmp);
+		write_config_option (info->fd, "%s %s\n", (char *) key, (char *) value);
+	else if (type == G_TYPE_BOOLEAN) {
+		if (!strcmp (value, "yes"))
+			write_config_option (info->fd, "%s\n", (char *) key);
+	} else if (type == G_TYPE_INT) {
+		long int tmp_int;
+		char *tmp_str;
+
+		/* Convert -> int and back to string for security's sake since
+		 * strtol() ignores leading and trailing characters.
+		 */
+		errno = 0;
+		tmp_int = strtol (value, NULL, 10);
+		if (errno == 0) {
+			tmp_str = g_strdup_printf ("%ld", tmp_int);
+			write_config_option (info->fd, "%s %s\n", (char *) key, tmp_str);
+			g_free (tmp_str);
+		} else {
+			g_set_error (&info->error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+			             "Config option '%s' not an integer.",
+			             (const char *) key);
+		}
 	} else {
+		/* Just ignore unknown properties */
 		nm_warning ("Don't know how to write property '%s' with type %s",
 				  (char *) key, g_type_name (type));
 	}
 }
 
-static void
+static gboolean
 nm_vpnc_config_write (gint vpnc_fd,
                       const char *default_user_name,
-                      GHashTable *properties)
+                      GHashTable *properties,
+                      GError **error)
 {
+	WriteConfigInfo *info;
 	const char *props_user_name;
 	const char *props_natt_mode;
 
@@ -262,45 +351,42 @@
 		                     NM_VPNC_NATT_MODE_NATT);
 	}
 
-	g_hash_table_foreach (properties, write_one_property, GINT_TO_POINTER (vpnc_fd));
+	info = g_malloc0 (sizeof (WriteConfigInfo));
+	info->fd = vpnc_fd;
+	g_hash_table_foreach (properties, write_one_property, info);
+	*error = info->error;
+	g_free (info);
+
+	return *error ? FALSE : TRUE;
 }
 
 static gboolean
 real_connect (NMVPNPlugin   *plugin,
-		    NMConnection  *connection,
-		    GError       **err)
+              NMConnection  *connection,
+              GError       **error)
 {
 	NMSettingVPN *s_vpn;
-	NMSettingVPNProperties *properties;
-	gint vpnc_fd;
-
-	properties = NM_SETTING_VPN_PROPERTIES (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES));
-	if (!properties || !nm_vpnc_properties_validate (properties->data)) {
-		g_set_error (err,
-				   NM_VPN_PLUGIN_ERROR,
-				   NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
-				   "%s",
-				   "Invalid arguments.");
-		return FALSE;
-	}
+	gint vpnc_fd = -1;
+	gboolean success = FALSE;
 
 	s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN));
 	g_assert (s_vpn);
+	if (!nm_vpnc_properties_validate (s_vpn->data, error))
+		goto out;
 
-	if ((vpnc_fd = nm_vpnc_start_vpnc_binary (NM_VPNC_PLUGIN (plugin))) >= 0)
-		nm_vpnc_config_write (vpnc_fd, s_vpn->user_name, properties->data);
-	else {
-		g_set_error (err,
-				   NM_VPN_PLUGIN_ERROR,
-				   NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
-				   "%s",
-				   "Could not start vpnc binary.");
-		close (vpnc_fd);
-		return FALSE;
-	}
+	vpnc_fd = nm_vpnc_start_vpnc_binary (NM_VPNC_PLUGIN (plugin), error);
+	if (vpnc_fd < 0)
+		goto out;
 
-	close (vpnc_fd);
-	return TRUE;
+	if (!nm_vpnc_config_write (vpnc_fd, s_vpn->user_name, s_vpn->data, error))
+		goto out;
+
+	success = TRUE;
+
+out:
+	if (vpnc_fd >= 0)
+		close (vpnc_fd);
+	return success;
 }
 
 static gboolean
@@ -309,13 +395,13 @@
                    char **setting_name,
                    GError **error)
 {
-	NMSettingVPNProperties *s_vpn_props;
+	NMSettingVPN *s_vpn;
 
 	g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
 
-	s_vpn_props = NM_SETTING_VPN_PROPERTIES (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES));
-	if (!s_vpn_props) {
+	s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN));
+	if (!s_vpn) {
         g_set_error (error,
 		             NM_VPN_PLUGIN_ERROR,
 		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
@@ -326,12 +412,12 @@
 
 	// FIXME: there are some configurations where both passwords are not
 	// required.  Make sure they work somehow.
-	if (!g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_SECRET)) {
-		*setting_name = NM_SETTING_VPN_PROPERTIES_SETTING_NAME;
+	if (!g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_SECRET)) {
+		*setting_name = NM_SETTING_VPN_SETTING_NAME;
 		return TRUE;
 	}
-	if (!g_hash_table_lookup (s_vpn_props->data, NM_VPNC_KEY_XAUTH_PASSWORD)) {
-		*setting_name = NM_SETTING_VPN_PROPERTIES_SETTING_NAME;
+	if (!g_hash_table_lookup (s_vpn->data, NM_VPNC_KEY_XAUTH_PASSWORD)) {
+		*setting_name = NM_SETTING_VPN_SETTING_NAME;
 		return TRUE;
 	}
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]