[patch] nm-vpn-properties



Hey,

Attached you should find a patch against HEAD implementing a UI for
editing VPN connections. In nm-applet, an item "Configure VPN..." is
inserted into the "VPN Connections" menu and if this is pressed the
binary nm-vpn-properties is launched. 

This (simplistic) program will allow to add/edit/delete VPN connections
which simply translates into manipulating gconf entries
under /system/networking/vpn_connections. We also support greying out
Delete and Edit if the user is not capable of editing the connection,
ie. if the sysadmin installed it as mandatory gconf settings (think
lockdown). I've also included a simple script that I envision sysadmins
can use to mass-deploy site-specific VPN configuration settings.

Also, nm-vpn-properties is built with extension points in mind so in a
not too far future we'll be able to have NetworkManager-vpnc tarballs /
packages that provide both the backend (org.freedesktop.vpnc service)
and the frontend. Right now this isn't the case though: the vpnc widget
code is in this patch. 

However, Dan and I have been talking about making this split soon as it
will make it easier to make other VPN types work with NetworkManager.
The basic interface is in nm-vpn-ui-interface.h but this needs a little
bit of work (GModule and GInterface perhaps).

Also, nm-vpn-properties supports validation per VPN widget to fit in
with the GNOME desktop.

The patch should apply and work out of the box after a autogen / make /
make install cycle. There's still a few TODO's that makes it not so
useful:

 - right now nm-applet requires the user_name key to be present. I
   think I've argued this is VPN-connection-specific (think
   certificates) so it should really go to vpn_data (and note that
   the vpnc widget allows you to set this; it sets Xauth username)

 - perhaps ditto for the routes though I admit I'm not sure about
   this. I have no problem extending the nm-vpn-ui-interface.h file
   to let the UI editing code give this vector, however my main
   grief is that we need the UI editing code to be VPN connection
   specific so it doesn't "stand out" on a separate page.

 - there are some sensitivity issues (as in grey outed / not greyed out)
   left in the code; should be easy to fix

 - validation for vpnc in the UI can be greatly improved. This is pretty
   much low-hanging fruit. 

   Here's an UI question: should each VPN editing widget provide "hints"
   we can show in the UI much like e.g. Firefox says it has blocked a
   popup window?

 - the nm-vpn-ui-interface.h needs serious doc love. At some point we
   need to lock down the interface (I guess this is also true for the
   backend, right Dan? :-))

 - nm-vpn-properties needs to have a place to load all the VPN editing
   widgets from. Perhaps just $libdir/gnome/nm-vpn-widgets or something?
   Or should we just a key to files in /etc/NetworkManager/VPN/<file>?
   (hmm, there may be multilib issues with this?)

 - there are some obvious TODO's left in the code

I plan to go through these TODO's once I've got some feedback.

Anyway, let me know what you think.

Cheers,
David

? nm-vpn-properties.patch
? gnome/vpn-properties
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/NetworkManager/ChangeLog,v
retrieving revision 1.371
diff -u -p -r1.371 ChangeLog
--- ChangeLog	21 May 2005 04:33:06 -0000	1.371
+++ ChangeLog	23 May 2005 18:44:02 -0000
@@ -1,3 +1,31 @@
+2005-05-23  David Zeuthen  <davidz redhat com>
+
+	* configure.in (AC_OUTPUT): Generate gnome/vpn-properties/Makefile
+
+	* gnome/applet/applet.c (nmwa_menu_configure_vpn_item_activate): New
+	function; launches nm-vpn-properties
+	(nmwa_menu_disconnect_vpn_item_activate): Fix function header comment
+	(nmwa_menu_add_vpn_menu): Add "Configure VPN..." menu item to menu
+
+	* gnome/applet/Makefile.am (nm_applet_CPPFLAGS): Export BINDIR as
+	preprocessor symbol
+
+	* gnome/vpn-properties: New directory
+
+	* gnome/vpn-properties/nm-vpn-dummy.c: New file
+
+	* gnome/vpn-properties/nm-vpn-properties.glade: New file
+
+	* gnome/vpn-properties/nm-vpnc-dialog.glade: New file
+
+	* gnome/vpn-properties/nm-vpn-ui-interface.h: New file
+
+	* gnome/vpn-properties/nm-vpn-properties.c: New file
+
+	* gnome/vpn-properties/Makefile.am: New file
+
+	* gnome/vpn-properties/example-vpnc-system-wide-connection.sh: New file
+
 2005-05-20  Dan Williams <dcbw redhat com>
 
 	* NetworkManager.h
Index: configure.in
===================================================================
RCS file: /cvs/gnome/NetworkManager/configure.in,v
retrieving revision 1.78
diff -u -p -r1.78 configure.in
--- configure.in	16 May 2005 17:24:55 -0000	1.78
+++ configure.in	23 May 2005 18:44:02 -0000
@@ -277,6 +277,7 @@ gnome/applet/Makefile
 gnome/applet/icons/Makefile
 gnome/libnm_glib/libnm_glib.pc
 gnome/libnm_glib/Makefile
+gnome/vpn-properties/Makefile
 test/Makefile
 initscript/Makefile
 initscript/RedHat/Makefile
Index: gnome/applet/Makefile.am
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/Makefile.am,v
retrieving revision 1.3
diff -u -p -r1.3 Makefile.am
--- gnome/applet/Makefile.am	16 May 2005 18:35:20 -0000	1.3
+++ gnome/applet/Makefile.am	23 May 2005 18:44:02 -0000
@@ -19,6 +19,7 @@ nm_applet_CPPFLAGS =				\
 	$(GNOMEKEYRING_CFLAGS)			\
 	-DICONDIR=\""$(datadir)/pixmaps"\"	\
 	-DGLADEDIR=\""$(gladedir)"\"		\
+	-DBINDIR=\""$(bindir)"\"		\
 	-DDBUS_API_SUBJECT_TO_CHANGE		\
 	-DG_DISABLE_DEPRECATED			\
 	-DGDK_DISABLE_DEPRECATED			\
Index: gnome/applet/applet.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/applet.c,v
retrieving revision 1.10
diff -u -p -r1.10 applet.c
--- gnome/applet/applet.c	21 May 2005 04:33:08 -0000	1.10
+++ gnome/applet/applet.c	23 May 2005 18:44:04 -0000
@@ -1121,9 +1121,26 @@ static void nmwa_menu_vpn_item_activate 
 
 
 /*
+ * nmwa_menu_configure_vpn_item_activate
+ *
+ * Signal function called when user clicks "Configure VPN..."
+ *
+ */
+static void nmwa_menu_configure_vpn_item_activate (GtkMenuItem *item, gpointer user_data)
+{
+	NMWirelessApplet	*applet = (NMWirelessApplet *)user_data;
+	char *argv[2] = {BINDIR "/nm-vpn-properties", NULL};
+
+	g_return_if_fail (item != NULL);
+	g_return_if_fail (applet != NULL);
+
+	g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, NULL);
+}
+
+/*
  * nmwa_menu_disconnect_vpn_item_activate
  *
- * Signal function called when user clicks on a VPN menu item
+ * Signal function called when user clicks "Disconnect VPN..."
  *
  */
 static void nmwa_menu_disconnect_vpn_item_activate (GtkMenuItem *item, gpointer user_data)
@@ -1391,6 +1408,10 @@ static void nmwa_menu_add_vpn_menu (GtkW
 		gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (vpn_item));
 	}
 	other_item = GTK_MENU_ITEM (gtk_separator_menu_item_new ());
+	gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (other_item));
+
+	other_item = GTK_MENU_ITEM (gtk_menu_item_new_with_label (_("Configure VPN...")));
+	g_signal_connect (G_OBJECT (other_item), "activate", G_CALLBACK (nmwa_menu_configure_vpn_item_activate), applet);
 	gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (other_item));
 
 	other_item = GTK_MENU_ITEM (gtk_menu_item_new_with_label (_("Disconnect VPN...")));
--- /dev/null	2005-05-23 10:03:46.347167944 -0400
+++ gnome/vpn-properties/Makefile.am	2005-05-23 13:37:40.000000000 -0400
@@ -0,0 +1,41 @@
+
+bin_PROGRAMS = nm-vpn-properties
+
+nm_vpn_properties_SOURCES = 					\
+					nm-vpn-properties.c	\
+	nm-vpn-ui-interface.h					\
+					nm-vpnc.c		\
+					nm-vpn-dummy.c
+
+gladedir = $(datadir)/gnome-vpn-properties
+glade_DATA = nm-vpn-properties.glade nm-vpnc-dialog.glade
+
+nm_vpn_properties_CFLAGS =                              \
+        $(GLADE_CFLAGS)                                 \
+        $(GTK_CFLAGS)                                   \
+        $(GCONF_CFLAGS)                                 \
+        $(LIBGNOMEUI_CFLAGS)                            \
+        -DICONDIR=\""$(datadir)/pixmaps"\"              \
+        -DGLADEDIR=\""$(gladedir)"\"                    \
+        -DG_DISABLE_DEPRECATED                          \
+        -DGDK_DISABLE_DEPRECATED                        \
+        -DGNOME_DISABLE_DEPRECATED                      \
+        -DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"  \
+        -DVERSION=\"$(VERSION)\" \
+        $(NULL)
+
+nm_vpn_properties_LDADD =               \
+        $(GLADE_LIBS)                   \
+        $(GTK_LIBS)                     \
+        $(GCONF_LIBS)                   \
+        $(LIBGNOMEUI_LIBS)              \
+        $(NULL)
+
+CLEANFILES = $(server_DATA) *.bak *.gladep
+
+EXTRA_DIST =                            \
+        $(glade_DATA)                   \
+        $(NULL)
+
+
+
--- /dev/null	2005-05-23 10:03:46.347167944 -0400
+++ gnome/vpn-properties/nm-vpn-dummy.c	2005-05-18 14:24:58.000000000 -0400
@@ -0,0 +1,93 @@
+
+#include "nm-vpn-ui-interface.h"
+
+typedef struct _NetworkManagerVpnUIImpl NetworkManagerVpnUIImpl;
+
+struct _NetworkManagerVpnUIImpl {
+	NetworkManagerVpnUI parent;
+
+	GtkWidget *widget;
+};
+
+
+static const char *
+impl_get_display_name (NetworkManagerVpnUI *self)
+{
+	return "Dummy VPN UI";
+}
+
+
+static const char *
+impl_get_service_name (NetworkManagerVpnUI *self)
+{
+	return "org.freedesktop.dummy";
+}
+
+static char *
+impl_get_connection_name (NetworkManagerVpnUI *self)
+{
+	return g_strdup ("dummy-conn-name");
+}
+
+static GtkWidget *
+impl_get_widget (NetworkManagerVpnUI *self, GSList *properties, const char *connection_name)
+{
+	return NULL;
+}
+
+static GSList *
+impl_get_properties (NetworkManagerVpnUI *self)
+{
+	return NULL;
+}
+
+static void 
+impl_set_validity_changed_callback (NetworkManagerVpnUI *self, 
+				    NetworkManagerVpnUIDialogValidityCallback callback,
+				    gpointer user_data)
+{
+	NetworkManagerVpnUIImpl *impl = (NetworkManagerVpnUIImpl *) self->data;
+
+	/*impl->callback = callback;*/
+	/*impl->callback_user_data = user_data;*/
+}
+
+static gboolean
+impl_is_valid (NetworkManagerVpnUI *self)
+{
+	return TRUE;
+}
+
+static const char *
+impl_get_confirmation_details (NetworkManagerVpnUI *self)
+{
+	NetworkManagerVpnUIImpl *impl = (NetworkManagerVpnUIImpl *) self->data;
+
+	return "none";
+}
+
+static NetworkManagerVpnUI* 
+impl_get_object (void)
+{
+	NetworkManagerVpnUIImpl *impl;
+
+	impl = g_new0 (NetworkManagerVpnUIImpl, 1);
+
+	impl->parent.get_display_name              = impl_get_display_name;
+	impl->parent.get_service_name              = impl_get_service_name;
+	impl->parent.get_widget                    = impl_get_widget;
+	impl->parent.get_connection_name           = impl_get_connection_name;
+	impl->parent.get_properties                = impl_get_properties;
+	impl->parent.set_validity_changed_callback = impl_set_validity_changed_callback;
+	impl->parent.is_valid                      = impl_is_valid;
+	impl->parent.get_confirmation_details      = impl_get_confirmation_details;
+	impl->parent.data = impl;
+	
+	return &(impl->parent);
+}
+
+NetworkManagerVpnUI* 
+vpn_ui_factory_dummy (void)
+{
+	return impl_get_object ();
+}
--- /dev/null	2005-05-23 10:03:46.347167944 -0400
+++ gnome/vpn-properties/nm-vpn-properties.glade	2005-05-23 11:23:59.000000000 -0400
@@ -0,0 +1,336 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+<requires lib="gnome"/>
+
+<widget class="GtkWindow" id="vpn-ui-properties">
+  <property name="border_width">5</property>
+  <property name="width_request">400</property>
+  <property name="height_request">300</property>
+  <property name="title" translatable="yes">VPN Connections</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+
+  <child>
+    <widget class="GtkVBox" id="vbox23">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child>
+	<widget class="GtkLabel" id="label29">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Manage Virtual Private Network connections</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0</property>
+	  <property name="yalign">0</property>
+	  <property name="xpad">6</property>
+	  <property name="ypad">11</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox70">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="scrolledwindow1">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="shadow_type">GTK_SHADOW_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<widget class="GtkTreeView" id="vpnlist">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="headers_visible">False</property>
+		  <property name="rules_hint">False</property>
+		  <property name="reorderable">False</property>
+		  <property name="enable_search">False</property>
+		  <property name="fixed_height_mode">False</property>
+		  <property name="hover_selection">False</property>
+		  <property name="hover_expand">False</property>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVButtonBox" id="vbuttonbox1">
+	      <property name="border_width">6</property>
+	      <property name="visible">True</property>
+	      <property name="layout_style">GTK_BUTTONBOX_START</property>
+	      <property name="spacing">12</property>
+
+	      <child>
+		<widget class="GtkButton" id="add">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label">gtk-add</property>
+		  <property name="use_stock">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="edit">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label">gtk-edit</property>
+		  <property name="use_stock">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="delete">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label">gtk-delete</property>
+		  <property name="use_stock">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHButtonBox" id="hbuttonbox1">
+	  <property name="border_width">6</property>
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkButton" id="close">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-close</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkWindow" id="vpn-create-connection">
+  <property name="title" translatable="yes">Create VPN Connection</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+
+  <child>
+    <widget class="GnomeDruid" id="vpn-create-connection-druid">
+      <property name="border_width">4</property>
+      <property name="visible">True</property>
+      <property name="show_help">False</property>
+
+      <child>
+	<widget class="GnomeDruidPageEdge" id="vpn-druid-vpn-start">
+	  <property name="visible">True</property>
+	  <property name="position">GNOME_EDGE_START</property>
+	  <property name="title" translatable="yes">Create VPN Connection</property>
+	  <property name="text" translatable="yes">This assistant will guide you through the creation of a new VPN connection to a private network.
+
+It will require some information, such as IP addresses and secrets, that will probably be provided by your system administrator as appropriate.</property>
+	</widget>
+      </child>
+
+      <child>
+	<widget class="GnomeDruidPageStandard" id="vpn-druid-vpn-type-page">
+	  <property name="visible">True</property>
+	  <property name="title" translatable="yes">Create VPN Connection - 1 of 2</property>
+
+	  <child internal-child="vbox">
+	    <widget class="GtkVBox" id="druid-vbox4">
+	      <property name="border_width">16</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkVBox" id="vbox24">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label31">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Dependent on the private network you want to connect to, you need to select what type of connection you want to create.</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">True</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">12</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">12</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkHBox" id="vpn-create-connection-druid-hbox1">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkLabel" id="label32">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Connect to:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">12</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<placeholder/>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+      </child>
+
+      <child>
+	<widget class="GnomeDruidPageStandard" id="vpn-druid-vpn-details-page">
+	  <property name="visible">True</property>
+	  <property name="title" translatable="yes">Create VPN Connection - 2 of 2</property>
+
+	  <child internal-child="vbox">
+	    <widget class="GtkVBox" id="vpn-connection-druid-details-box">
+	      <property name="border_width">16</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<placeholder/>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+      </child>
+
+      <child>
+	<widget class="GnomeDruidPageEdge" id="vpn-druid-vpn-confirm-page">
+	  <property name="visible">True</property>
+	  <property name="position">GNOME_EDGE_FINISH</property>
+	  <property name="title" translatable="yes">Finish create VPN Connection</property>
+	  <property name="text" translatable="yes"></property>
+	</widget>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
--- /dev/null	2005-05-23 10:03:46.347167944 -0400
+++ gnome/vpn-properties/nm-vpnc-dialog.glade	2005-05-23 11:24:05.000000000 -0400
@@ -0,0 +1,607 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+<requires lib="gnome"/>
+
+
+<widget class="GtkWindow" id="vpn-connection-vpnc">
+  <property name="title" translatable="yes">window2</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+
+  <child>
+    <widget class="GtkVBox" id="nm-vpnc-widget">
+      <property name="border_width">12</property>
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">12</property>
+
+      <child>
+	<widget class="GtkLabel" id="label56">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Please enter the information provided by your system administrator below. Do not enter your password here as you will be prompted when connecting.</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">True</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox81">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label57">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes"></property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">12</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox31">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">12</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label58">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Connection Name&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkVBox" id="vbox32">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">6</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label59">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Name used to identify the connection to the private network, e.g. &quot;Campus VPN&quot; or &quot;Corporate Network&quot;</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">True</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox82">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkLabel" id="label60">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes"></property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">12</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkEntry" id="vpnc-connection-name">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes"></property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char">*</property>
+			  <property name="activates_default">False</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label61">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Required Information&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox83">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">12</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label62">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes"></property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkTable" id="table3">
+		      <property name="visible">True</property>
+		      <property name="n_rows">3</property>
+		      <property name="n_columns">2</property>
+		      <property name="homogeneous">False</property>
+		      <property name="row_spacing">6</property>
+		      <property name="column_spacing">12</property>
+
+		      <child>
+			<widget class="GtkLabel" id="label63">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Gateway:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label64">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Group Name:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label65">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Secret:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">2</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkEntry" id="vpnc-gateway">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes"></property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char">*</property>
+			  <property name="activates_default">False</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkEntry" id="vpnc-group-name">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes"></property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char">*</property>
+			  <property name="activates_default">False</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>
+
+		      <child>
+			<widget class="GtkEntry" id="vpnc-secret">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes"></property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char">*</property>
+			  <property name="activates_default">False</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">2</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label66">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Optional Information&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox84">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label67">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes"></property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">6</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkVBox" id="vbox33">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">6</property>
+
+		      <child>
+			<widget class="GtkCheckButton" id="vpnc-use-alternate-username">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">Use another username</property>
+			  <property name="use_underline">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</property>
+			  <property name="active">False</property>
+			  <property name="inconsistent">False</property>
+			  <property name="draw_indicator">True</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox85">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">0</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label68">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes"></property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">12</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="vpnc-username">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char">*</property>
+			      <property name="activates_default">False</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+
+</glade-interface>
--- /dev/null	2005-05-23 10:03:46.347167944 -0400
+++ gnome/vpn-properties/nm-vpn-ui-interface.h	2005-05-23 12:29:56.000000000 -0400
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * nm-vpn-ui-interface.h : Public interface for VPN UI editing widgets
+ *
+ * Copyright (C) 2005 David Zeuthen, <davidz 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ **************************************************************************/
+
+#ifndef NM_VPN_UI_INTERFACE_H
+#define NM_VPN_UI_INTERFACE_H
+
+#include <gtk/gtk.h>
+
+struct _NetworkManagerVpnUI;
+typedef struct _NetworkManagerVpnUI NetworkManagerVpnUI;
+
+typedef void (*NetworkManagerVpnUIDialogValidityCallback) (NetworkManagerVpnUI *self,
+							   gboolean is_valid, 
+							   gpointer user_data);
+
+
+struct _NetworkManagerVpnUI {
+	const char *(*get_display_name) (NetworkManagerVpnUI *self);
+
+	const char *(*get_service_name) (NetworkManagerVpnUI *self);
+
+	GtkWidget *(*get_widget) (NetworkManagerVpnUI *self, GSList *properties, const char *connection_name);
+
+	void (*set_validity_changed_callback) (NetworkManagerVpnUI *self, 
+					       NetworkManagerVpnUIDialogValidityCallback cb,
+					       gpointer user_data);
+
+	gboolean (*is_valid) (NetworkManagerVpnUI *self);
+
+	const char *(*get_confirmation_details)(NetworkManagerVpnUI *self);
+
+
+	char *(*get_connection_name) (NetworkManagerVpnUI *self);
+
+	GSList *(*get_properties) (NetworkManagerVpnUI *self);
+
+
+	gpointer data;
+};
+
+#endif /* NM_VPN_UI_INTERFACE_H */
+
--- /dev/null	2005-05-23 10:03:46.347167944 -0400
+++ gnome/vpn-properties/nm-vpn-properties.c	2005-05-23 14:41:44.000000000 -0400
@@ -0,0 +1,810 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * nm-vpn-properties.c : GNOME UI dialogs for manipulating VPN connections
+ *
+ * Copyright (C) 2005 David Zeuthen, <davidz 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ **************************************************************************/
+
+#include <string.h>
+#include <gnome.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtkwindow.h>
+#include <glade/glade.h>
+#include <gconf/gconf-client.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "nm-vpn-ui-interface.h"
+
+#ifdef ENABLE_NLS
+#  include <libintl.h>
+#  define _(String) gettext (String)
+#  ifdef gettext_noop
+#    define N_(String) gettext_noop (String)
+#  else
+#    define N_(String) (String)
+#  endif
+#else
+#  define _(String)
+#  define N_(String) (String)
+#endif
+
+
+#define NM_GCONF_VPN_CONNECTIONS_PATH "/system/networking/vpn_connections"
+
+static GladeXML *xml;
+static GConfClient *gconf_client;
+
+static GtkWidget *dialog;
+static GtkWindow *druid_window;
+static GtkTreeView *vpn_conn_view;
+static GtkListStore *vpn_conn_list;
+static GtkWidget *vpn_edit;
+static GtkWidget *vpn_delete;
+static GnomeDruid *druid;
+static GnomeDruidPageEdge *druid_confirm_page;
+static GtkComboBox *vpn_type_combo_box;
+static GtkVBox *vpn_type_details;
+static GtkDialog *edit_dialog;
+
+static GSList *vpn_types;
+
+enum {
+	VPNCONN_NAME_COLUMN,
+	VPNCONN_GCONF_COLUMN,
+	VPNCONN_USER_CAN_EDIT_COLUMN,
+	VPNCONN_N_COLUMNS
+};
+
+static void
+update_edit_del_sensitivity (void)
+{
+	GtkTreeIter iter;
+	GtkTreeSelection *selection;
+	gboolean is_editable;	
+
+	if ((selection = gtk_tree_view_get_selection (vpn_conn_view)) == NULL)
+		goto out;
+
+	if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
+		goto out;
+
+	gtk_tree_model_get (GTK_TREE_MODEL (vpn_conn_list), &iter, VPNCONN_USER_CAN_EDIT_COLUMN, &is_editable, -1);
+
+	gtk_widget_set_sensitive (vpn_edit, is_editable);
+	gtk_widget_set_sensitive (vpn_delete, is_editable);
+
+out:
+	;
+}
+
+static gboolean
+add_vpn_connection (const char *conn_name, const char *service_name, GSList *conn_data)
+{
+	int i;
+	char *gconf_key;
+	GtkTreeIter iter;
+	char conn_gconf_path[PATH_MAX];
+	char *escaped_conn_name;
+	gboolean ret;
+	gboolean conn_user_can_edit = TRUE;
+
+	ret = FALSE;
+
+	escaped_conn_name = gconf_escape_key (conn_name, strlen (conn_name));
+
+	g_snprintf (conn_gconf_path, 
+		    sizeof (conn_gconf_path), 
+		    NM_GCONF_VPN_CONNECTIONS_PATH "/%s",
+		    escaped_conn_name);
+
+	if (gconf_client_dir_exists (gconf_client, conn_gconf_path, NULL))
+		goto out;
+	       
+	/* User-visible name of connection */
+	gconf_key = g_strdup_printf ("%s/name", conn_gconf_path);
+	gconf_client_set_string (gconf_client, gconf_key, conn_name, NULL);
+
+	/* Service name of connection */
+	gconf_key = g_strdup_printf ("%s/service_name", conn_gconf_path);
+	gconf_client_set_string (gconf_client, gconf_key, service_name, NULL);
+
+	/* vpn-daemon specific data */
+	gconf_key = g_strdup_printf ("%s/vpn_data", conn_gconf_path);
+	{
+		gconf_client_set_list (gconf_client, gconf_key, GCONF_VALUE_STRING, conn_data, NULL);
+	}
+
+	/* TODO: remove user_name */
+	gconf_key = g_strdup_printf ("%s/user_name", conn_gconf_path);
+	gconf_client_set_string (gconf_client, gconf_key, "davidz", NULL);
+
+	/* TODO: remove routes */
+	gconf_key = g_strdup_printf ("%s/routes", conn_gconf_path);
+	{
+		GSList *i;
+
+		i = NULL;
+		/*i = g_slist_append (i, "172.16.0.0/16");*/
+		gconf_client_set_list (gconf_client, gconf_key, GCONF_VALUE_STRING, i, NULL);
+		g_slist_free (i);
+	}
+
+	gconf_client_suggest_sync (gconf_client, NULL);
+
+	conn_user_can_edit = TRUE;
+
+	gtk_list_store_append (vpn_conn_list, &iter);
+	gtk_list_store_set (vpn_conn_list, &iter,
+			    VPNCONN_NAME_COLUMN, conn_name,
+			    VPNCONN_GCONF_COLUMN, conn_gconf_path,
+			    VPNCONN_USER_CAN_EDIT_COLUMN, &conn_user_can_edit,
+			    -1);
+
+	ret = TRUE;
+
+out:
+	g_free (escaped_conn_name);
+	return ret;
+}
+
+static void 
+vpn_druid_vpn_validity_changed (NetworkManagerVpnUI *vpn_ui,
+				gboolean is_valid, 
+				gpointer user_data)
+{
+	char *conn_name;
+	GtkTreeIter iter;
+
+	/*printf ("vpn_druid_vpn_validity_changed %d!\n", is_valid);*/
+
+	conn_name = vpn_ui->get_connection_name (vpn_ui);
+
+	/* get list of existing connection names */
+	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (vpn_conn_list), &iter)) {
+		do {
+			char *name;
+
+			gtk_tree_model_get (GTK_TREE_MODEL (vpn_conn_list),
+					    &iter,
+					    VPNCONN_NAME_COLUMN,
+					    &name,
+					    -1);
+			
+			if (strcmp (name, conn_name) == 0) {
+				/*printf ("name '%s' is already in use\n", conn_name);*/
+				is_valid = FALSE;
+				break;
+			}
+
+		} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (vpn_conn_list), &iter));
+	}
+
+	g_free (conn_name);
+
+	gnome_druid_set_buttons_sensitive (druid, 
+					   TRUE,
+					   is_valid,
+					   TRUE,
+					   FALSE);
+}
+
+
+static gboolean vpn_druid_vpn_type_page_next (GnomeDruidPage *druidpage,
+					      GtkWidget *widget,
+					      gpointer user_data)
+{
+	GtkWidget *w;
+	GtkWidget *vbox;
+	NetworkManagerVpnUI *vpn_ui;
+
+	/*printf ("vpn_type_next!\n");*/
+
+	/* first hide existing child */
+	w = g_list_nth_data (gtk_container_children (GTK_CONTAINER (vpn_type_details)), 0);
+	if (w != NULL) {
+		gtk_widget_hide (w);
+	}
+
+	/* show appropriate child */
+	vpn_ui = (NetworkManagerVpnUI *) g_slist_nth_data (vpn_types, gtk_combo_box_get_active (vpn_type_combo_box));
+	if (vpn_ui != NULL) {
+		w = vpn_ui->get_widget (vpn_ui, NULL, NULL);
+		if (w != NULL) {	
+			gtk_widget_reparent (w, GTK_WIDGET (vpn_type_details));
+			gtk_widget_show_all (w);
+		}
+
+		vpn_ui->set_validity_changed_callback (vpn_ui, vpn_druid_vpn_validity_changed, NULL);
+	}
+
+	return FALSE;
+}
+
+static void vpn_druid_vpn_details_page_prepare (GnomeDruidPage *druidpage,
+						GtkWidget *widget,
+						gpointer user_data)
+{
+	/*printf ("vpn_details_prepare!\n");*/
+
+	gnome_druid_set_buttons_sensitive (druid, 
+					   TRUE,
+					   FALSE,
+					   TRUE,
+					   FALSE);	
+
+}
+
+static gboolean vpn_druid_vpn_details_page_next (GnomeDruidPage *druidpage,
+						 GtkWidget *widget,
+						 gpointer user_data)
+{
+	gboolean is_valid;
+	NetworkManagerVpnUI *vpn_ui;
+
+	is_valid = FALSE;
+
+	/*printf ("vpn_details_next!\n");*/
+
+	/* validate input */
+	vpn_ui = (NetworkManagerVpnUI *) g_slist_nth_data (vpn_types, gtk_combo_box_get_active (vpn_type_combo_box));
+	if (vpn_ui != NULL) {
+		is_valid = vpn_ui->is_valid (vpn_ui);
+	}
+
+out:
+	return !is_valid;
+}
+
+static void vpn_druid_vpn_confirm_page_prepare (GnomeDruidPage *druidpage,
+						GtkWidget *widget,
+						gpointer user_data)
+{
+	NetworkManagerVpnUI *vpn_ui;
+
+	/*printf ("vpn_confirm_prepare!\n");*/
+
+	vpn_ui = (NetworkManagerVpnUI *) g_slist_nth_data (vpn_types, gtk_combo_box_get_active (vpn_type_combo_box));
+	if (vpn_ui != NULL) {
+		const char *confirm_text;
+
+		confirm_text = vpn_ui->get_confirmation_details (vpn_ui);
+		
+		gnome_druid_page_edge_set_text (druid_confirm_page,
+						confirm_text);
+	}
+}
+
+static gboolean vpn_druid_vpn_confirm_page_finish (GnomeDruidPage *druidpage,
+						   GtkWidget *widget,
+						   gpointer user_data)
+{
+	static int vpncon = 0;
+	GSList *conn_data;
+	char *conn_name;
+	NetworkManagerVpnUI *vpn_ui;
+
+	/*printf ("vpn_confirm_finish!\n");*/
+
+	vpn_ui = (NetworkManagerVpnUI *) g_slist_nth_data (vpn_types, gtk_combo_box_get_active (vpn_type_combo_box));
+	conn_name = vpn_ui->get_connection_name (vpn_ui);
+	conn_data = vpn_ui->get_properties (vpn_ui);
+
+	add_vpn_connection (conn_name, vpn_ui->get_service_name (vpn_ui), conn_data);
+
+	gtk_widget_hide_all (GTK_WIDGET (druid_window));
+out:
+	return FALSE;
+}
+
+static gboolean vpn_druid_cancel (GnomeDruid *druid,
+				  gpointer user_data)
+{
+	/*printf ("vpn_druid_cancel!\n");*/
+
+	gtk_widget_hide_all (GTK_WIDGET (druid_window));
+	return FALSE;
+}
+
+
+
+static void
+add_cb (GtkButton *button, gpointer user_data)
+{
+	GtkWidget *w;
+
+	/*printf ("add_cb\n");*/
+
+	w = glade_xml_get_widget (xml, "vpn-druid-vpn-start");
+	gnome_druid_set_page (druid, GNOME_DRUID_PAGE (w));
+	gtk_widget_show_all (GTK_WIDGET (druid_window));
+}
+
+
+static void 
+vpn_edit_vpn_validity_changed (NetworkManagerVpnUI *vpn_ui,
+				gboolean is_valid, 
+				gpointer user_data)
+{
+	const char *orig_conn_name;
+	char *conn_name;
+	GtkTreeIter iter;
+
+	orig_conn_name = (const char *) user_data;
+
+	/*printf ("vpn_edit_vpn_validity_changed %d!\n", is_valid);*/
+
+	conn_name = vpn_ui->get_connection_name (vpn_ui);
+
+	/* get list of existing connection names */
+	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (vpn_conn_list), &iter)) {
+		do {
+			char *name;
+
+			gtk_tree_model_get (GTK_TREE_MODEL (vpn_conn_list),
+					    &iter,
+					    VPNCONN_NAME_COLUMN,
+					    &name,
+					    -1);
+
+			/* Can override the original name (stored in user_data, see edit_cb()) */
+			if (strcmp (name, orig_conn_name) != 0) {			
+				if (strcmp (name, conn_name) == 0) {
+					printf ("name '%s' is already in use\n", conn_name);
+					is_valid = FALSE;
+					break;
+				}
+			}
+
+		} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (vpn_conn_list), &iter));
+	}
+
+	g_free (conn_name);
+
+	gtk_dialog_set_response_sensitive (edit_dialog, GTK_RESPONSE_ACCEPT, is_valid);
+
+}
+
+static NetworkManagerVpnUI *
+find_vpn_ui_by_service_name (const char *service_name)
+{
+	GSList *i;
+
+	for (i = vpn_types; i != NULL; i = g_slist_next (i)) {
+		NetworkManagerVpnUI *vpn_ui;
+
+		vpn_ui = i->data;
+		if (strcmp (vpn_ui->get_service_name (vpn_ui), service_name) == 0)
+			return vpn_ui;
+	}
+
+	return NULL;
+}
+
+static void
+edit_cb (GtkButton *button, gpointer user_data)
+{
+	GtkWidget *vpn_edit_widget;
+	NetworkManagerVpnUI *vpn_ui;
+	gint result;
+	char *conn_gconf_path;
+	const char *conn_name;
+	const char *conn_service_name;
+	GSList *conn_vpn_data_gconfvalue;
+	GSList *conn_vpn_data;
+	GSList *i;
+	char key[PATH_MAX];
+	GtkTreeSelection *selection;
+	GtkTreeIter iter;
+	GConfValue *value;
+
+	/*printf ("edit\n");*/
+
+	if ((selection = gtk_tree_view_get_selection (vpn_conn_view)) == NULL)
+		goto out;
+
+	if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
+		goto out;
+
+	gtk_tree_model_get (GTK_TREE_MODEL (vpn_conn_list), 
+			    &iter, 
+			    VPNCONN_GCONF_COLUMN, 
+			    &conn_gconf_path, 
+			    -1);
+
+	g_snprintf (key, sizeof (key), "%s/name", conn_gconf_path);
+	if ((value = gconf_client_get (gconf_client, key, NULL)) == NULL ||
+	    (conn_name = gconf_value_get_string (value)) == NULL)
+		goto out;
+
+	g_snprintf (key, sizeof (key), "%s/service_name", conn_gconf_path);
+	if ((value = gconf_client_get (gconf_client, key, NULL)) == NULL ||
+	    (conn_service_name = gconf_value_get_string (value)) == NULL)
+		goto out;
+
+	vpn_ui = find_vpn_ui_by_service_name (conn_service_name);
+	if (vpn_ui == NULL) {
+		GtkWidget *dialog;
+
+		dialog = gtk_message_dialog_new (NULL,
+						 GTK_DIALOG_DESTROY_WITH_PARENT,
+						 GTK_MESSAGE_ERROR,
+						 GTK_BUTTONS_CLOSE,
+						 _("Cannot edit VPN connection '%s'"),
+						 conn_name);
+		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+  _("Could not find the UI files for VPN connection type '%s'. Please contact your system administrator."),
+							  conn_service_name);
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+		goto out;
+	}
+
+	g_snprintf (key, sizeof (key), "%s/vpn_data", conn_gconf_path);
+	if ((value = gconf_client_get (gconf_client, key, NULL)) == NULL ||
+	    gconf_value_get_list_type (value) != GCONF_VALUE_STRING ||
+	    (conn_vpn_data_gconfvalue = gconf_value_get_list (value)) == NULL)
+		goto out;
+
+	conn_vpn_data = NULL;
+	for (i = conn_vpn_data_gconfvalue; i != NULL; i = g_slist_next (i)) {
+		const char *value;
+		value = gconf_value_get_string ((GConfValue *) i->data);
+		conn_vpn_data = g_slist_append (conn_vpn_data, (gpointer) value);
+	}
+
+	vpn_edit_widget = vpn_ui->get_widget (vpn_ui, conn_vpn_data, conn_name);
+
+	g_slist_free (conn_vpn_data);
+
+	vpn_ui->set_validity_changed_callback (vpn_ui, vpn_edit_vpn_validity_changed, (gpointer) conn_name);
+
+	gtk_widget_reparent (vpn_edit_widget, GTK_WIDGET (edit_dialog->vbox));
+	gtk_widget_show_all (vpn_edit_widget);
+
+	result = gtk_dialog_run (GTK_DIALOG (edit_dialog));
+
+	if (result == GTK_RESPONSE_ACCEPT) {
+		char *new_conn_name;
+		GSList *new_conn_data;
+
+		new_conn_name = vpn_ui->get_connection_name (vpn_ui);
+		new_conn_data = vpn_ui->get_properties (vpn_ui);
+
+		if (strcmp (new_conn_name, conn_name) == 0) {
+
+			/* same name, just update properties */
+			g_snprintf (key, sizeof (key), "%s/vpn_data", conn_gconf_path);
+			gconf_client_set_list (gconf_client, key, GCONF_VALUE_STRING, new_conn_data, NULL);
+
+			gconf_client_suggest_sync (gconf_client, NULL);
+		} else {
+
+			/* remove old entry */
+			g_snprintf (key, sizeof (key), "%s/name", conn_gconf_path);
+			gconf_client_unset (gconf_client, key, NULL);
+			g_snprintf (key, sizeof (key), "%s/service_name", conn_gconf_path);
+			gconf_client_unset (gconf_client, key, NULL);
+			g_snprintf (key, sizeof (key), "%s/vpn_data", conn_gconf_path);
+			gconf_client_unset (gconf_client, key, NULL);
+			/* TODO: at some point remove routes and user_name */
+			g_snprintf (key, sizeof (key), "%s/routes", conn_gconf_path);
+			gconf_client_unset (gconf_client, key, NULL);
+			g_snprintf (key, sizeof (key), "%s/user_name", conn_gconf_path);
+			gconf_client_unset (gconf_client, key, NULL);
+			gconf_client_unset (gconf_client, conn_gconf_path, NULL);
+			gconf_client_suggest_sync (gconf_client, NULL);
+			gtk_list_store_remove (vpn_conn_list, &iter);
+
+			/* add new entry */
+			add_vpn_connection (new_conn_name, vpn_ui->get_service_name (vpn_ui), new_conn_data);
+		}
+
+	}
+
+	gtk_widget_hide (GTK_WIDGET (edit_dialog));
+
+out:
+	;
+}
+
+static void
+delete_cb (GtkButton *button, gpointer user_data)
+{
+	GtkTreeIter iter;
+	GtkTreeSelection *selection;
+	gchar *conn_gconf_path;
+
+	/*printf ("delete\n");*/
+
+	if ((selection = gtk_tree_view_get_selection (vpn_conn_view)) == NULL)
+		goto out;
+
+	if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
+		goto out;
+
+	gtk_tree_model_get (GTK_TREE_MODEL (vpn_conn_list), &iter, VPNCONN_GCONF_COLUMN, &conn_gconf_path, -1);
+
+	if (conn_gconf_path != NULL) {
+		char key[PATH_MAX];
+		
+		g_snprintf (key, sizeof (key), "%s/name", conn_gconf_path);
+		gconf_client_unset (gconf_client, key, NULL);
+		g_snprintf (key, sizeof (key), "%s/service_name", conn_gconf_path);
+		gconf_client_unset (gconf_client, key, NULL);
+		g_snprintf (key, sizeof (key), "%s/vpn_data", conn_gconf_path);
+		gconf_client_unset (gconf_client, key, NULL);
+		g_snprintf (key, sizeof (key), "%s/routes", conn_gconf_path);
+		gconf_client_unset (gconf_client, key, NULL);
+		/* TODO: remove user_name */
+		g_snprintf (key, sizeof (key), "%s/user_name", conn_gconf_path);
+		gconf_client_unset (gconf_client, key, NULL);
+		gconf_client_unset (gconf_client, conn_gconf_path, NULL);
+
+		gconf_client_suggest_sync (gconf_client, NULL);
+
+		if (gtk_list_store_remove (vpn_conn_list, &iter))
+			gtk_tree_selection_select_iter (selection, &iter);
+	}
+
+	update_edit_del_sensitivity ();
+
+out:
+	;
+}
+
+static void
+close_cb (void)
+{
+	gtk_widget_destroy (dialog);
+	gtk_main_quit ();
+}
+
+static void get_all_vpn_connections (void)
+{
+	GtkTreeIter iter;
+	GSList *vpn_conn = NULL;
+
+	for (vpn_conn = gconf_client_all_dirs (gconf_client, NM_GCONF_VPN_CONNECTIONS_PATH, NULL);
+	     vpn_conn != NULL;
+	     vpn_conn = g_slist_next (vpn_conn)) {
+		char key[PATH_MAX];
+		GConfValue *value;
+		const char *conn_gconf_path;
+		const char *conn_name;
+		const char *conn_service_name;
+		GSList *conn_vpn_data;
+		GSList *i;
+		gboolean conn_user_can_edit = TRUE;
+
+		conn_gconf_path = (const char *) (vpn_conn->data);
+
+		g_snprintf (key, sizeof (key), "%s/name", conn_gconf_path);
+		conn_user_can_edit = gconf_client_key_is_writable (gconf_client, key, NULL);
+		if ((value = gconf_client_get (gconf_client, key, NULL)) == NULL ||
+		    (conn_name = gconf_value_get_string (value)) == NULL)
+			goto error;
+
+		g_snprintf (key, sizeof (key), "%s/service_name", conn_gconf_path);
+		if ((value = gconf_client_get (gconf_client, key, NULL)) == NULL ||
+		    (conn_service_name = gconf_value_get_string (value)) == NULL)
+			goto error;
+
+		g_snprintf (key, sizeof (key), "%s/vpn_data", conn_gconf_path);
+		if ((value = gconf_client_get (gconf_client, key, NULL)) == NULL ||
+		    gconf_value_get_list_type (value) != GCONF_VALUE_STRING ||
+		    (conn_vpn_data = gconf_value_get_list (value)) == NULL)
+			goto error;
+		
+		//conn_user_can_edit = (strcmp (conn_name, "RH VPN Boston") != 0);
+
+		gtk_list_store_append (vpn_conn_list, &iter);
+		gtk_list_store_set (vpn_conn_list, &iter,
+				    VPNCONN_NAME_COLUMN, conn_name,
+				    VPNCONN_GCONF_COLUMN, conn_gconf_path,
+				    VPNCONN_USER_CAN_EDIT_COLUMN, conn_user_can_edit,
+				    -1);
+
+		/*
+		printf ("conn_name = '%s'\n", conn_name);
+		printf ("conn_service_name = '%s'\n", conn_service_name);
+		printf ("conn_vpn_data = {");
+		{
+			GSList *i;
+			for (i = conn_vpn_data; i != NULL; i = g_slist_next (i)) {
+				printf ("'%s'", gconf_value_get_string ((GConfValue *) i->data));
+				if (g_slist_next (i) != NULL)
+					printf (", ");
+			}
+			printf ("}\n");
+		}
+		*/
+
+error:
+		g_free (vpn_conn->data);
+	}
+
+out:
+	;
+}
+
+static void 
+vpn_list_cursor_changed_cb (GtkTreeView *treeview,
+			    gpointer user_data)
+{
+	/*printf ("*** vpn_list_cursor_changed_cb\n");*/
+
+	update_edit_del_sensitivity ();
+}
+
+/* TODO: remove these once we get the GModule thing going */
+extern NetworkManagerVpnUI* vpn_ui_factory_vpnc (void);
+extern NetworkManagerVpnUI* vpn_ui_factory_dummy (void);
+
+static void
+init_app (void)
+{
+	GtkWidget *w;
+	gchar *glade_file;
+	char *file;
+	GtkTreeIter iter;
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *renderer;
+	GSList *i;
+	NetworkManagerVpnUI *vpn_ui_interface;
+	GtkHBox *vpn_type_hbox1;
+
+	/* TODO: ensure only one copy of this program is running at any time */
+
+	gconf_client = gconf_client_get_default ();
+	gconf_client_add_dir (gconf_client, NM_GCONF_VPN_CONNECTIONS_PATH,
+			      GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+
+	glade_file = g_strdup_printf ("%s/%s", GLADEDIR, "nm-vpn-properties.glade");
+	//glade_file = g_strdup ("nm-vpn-properties.glade");
+	xml = glade_xml_new (glade_file, NULL, NULL);
+	g_free (glade_file);
+
+	/* Load all VPN UI modules (TODO: load dynamically) */
+	vpn_types = NULL;
+	vpn_ui_interface = vpn_ui_factory_vpnc ();
+	if (vpn_ui_interface != NULL)
+		vpn_types = g_slist_append (vpn_types, vpn_ui_interface);
+	vpn_ui_interface = vpn_ui_factory_dummy ();
+	if (vpn_ui_interface != NULL)
+		vpn_types = g_slist_append (vpn_types, vpn_ui_interface);
+
+
+	dialog = glade_xml_get_widget (xml, "vpn-ui-properties");
+
+	vpn_type_details = GTK_VBOX (glade_xml_get_widget (xml, "vpn-connection-druid-details-box"));
+
+	w = glade_xml_get_widget (xml, "add");
+	gtk_signal_connect (GTK_OBJECT (w), "clicked", GTK_SIGNAL_FUNC (add_cb), NULL);
+	vpn_edit = glade_xml_get_widget (xml, "edit");
+	gtk_signal_connect (GTK_OBJECT (vpn_edit), "clicked", GTK_SIGNAL_FUNC (edit_cb), NULL);
+	vpn_delete = glade_xml_get_widget (xml, "delete");
+	gtk_signal_connect (GTK_OBJECT (vpn_delete), "clicked", GTK_SIGNAL_FUNC (delete_cb), NULL);
+	w = glade_xml_get_widget (xml, "close");
+	gtk_signal_connect (GTK_OBJECT (w), "clicked",
+			    GTK_SIGNAL_FUNC (close_cb), NULL);
+	gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
+			    GTK_SIGNAL_FUNC (close_cb), NULL);
+
+
+	vpn_conn_view = GTK_TREE_VIEW (glade_xml_get_widget (xml, "vpnlist"));
+	vpn_conn_list = gtk_list_store_new (VPNCONN_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
+
+	gtk_signal_connect_after (GTK_OBJECT (vpn_conn_view), "cursor-changed",
+				  GTK_SIGNAL_FUNC (vpn_list_cursor_changed_cb), NULL);
+
+
+	get_all_vpn_connections ();
+
+	
+
+	column = gtk_tree_view_column_new ();
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (column, renderer, TRUE);
+	gtk_tree_view_column_set_attributes (column, renderer,
+					     "text", VPNCONN_NAME_COLUMN,
+					     NULL);
+	gtk_tree_view_append_column (vpn_conn_view, column);
+
+	gtk_tree_view_set_model (vpn_conn_view, GTK_TREE_MODEL (vpn_conn_list));
+	gtk_tree_view_expand_all (vpn_conn_view);
+
+       
+	gtk_widget_show_all (dialog);
+
+	/* fill in possibly choices in the druid when adding a connection */
+	vpn_type_hbox1 = GTK_HBOX (glade_xml_get_widget (xml, "vpn-create-connection-druid-hbox1"));
+	vpn_type_combo_box = GTK_COMBO_BOX (gtk_combo_box_new_text ());
+	for (i = vpn_types; i != NULL; i = g_slist_next (i)) {
+		NetworkManagerVpnUI *vpn_ui = i->data;
+		gtk_combo_box_append_text (vpn_type_combo_box, vpn_ui->get_display_name (vpn_ui));
+
+	}
+	gtk_combo_box_set_active (vpn_type_combo_box, 0);
+	gtk_box_pack_end (GTK_BOX (vpn_type_hbox1), GTK_WIDGET (vpn_type_combo_box), TRUE, TRUE, 0);
+
+
+	/* Druid */
+	druid = GNOME_DRUID (glade_xml_get_widget (xml, "vpn-create-connection-druid"));
+	gtk_signal_connect (GTK_OBJECT (druid), "cancel", GTK_SIGNAL_FUNC (vpn_druid_cancel), NULL);
+	druid_confirm_page = GNOME_DRUID_PAGE_EDGE (glade_xml_get_widget (xml, "vpn-druid-vpn-confirm-page"));
+	/* use connect_after, otherwise gnome_druid_set_buttons_sensitive() won't work in prepare handlers */
+	w = glade_xml_get_widget (xml, "vpn-druid-vpn-type-page");
+	gtk_signal_connect_after (GTK_OBJECT (w), "next", GTK_SIGNAL_FUNC (vpn_druid_vpn_type_page_next), NULL);
+	w = glade_xml_get_widget (xml, "vpn-druid-vpn-details-page");
+	gtk_signal_connect_after (GTK_OBJECT (w), "prepare", GTK_SIGNAL_FUNC (vpn_druid_vpn_details_page_prepare), NULL);
+	gtk_signal_connect_after (GTK_OBJECT (w), "next", GTK_SIGNAL_FUNC (vpn_druid_vpn_details_page_next), NULL);
+	w = glade_xml_get_widget (xml, "vpn-druid-vpn-confirm-page");
+	gtk_signal_connect_after (GTK_OBJECT (w), "prepare", GTK_SIGNAL_FUNC (vpn_druid_vpn_confirm_page_prepare), NULL);
+	gtk_signal_connect_after (GTK_OBJECT (w), "finish", GTK_SIGNAL_FUNC (vpn_druid_vpn_confirm_page_finish), NULL);
+
+	druid_window = GTK_WINDOW (glade_xml_get_widget (xml, "vpn-create-connection"));
+	/* reuse the widget */
+	gtk_signal_connect (GTK_OBJECT (druid_window), "delete-event", 
+			    GTK_SIGNAL_FUNC (gtk_widget_hide_on_delete), NULL);
+	/* make the druid window modal wrt. our main window */
+	gtk_window_set_modal (druid_window, TRUE);
+	gtk_window_set_transient_for (druid_window, GTK_WINDOW (dialog));
+
+
+	/* Edit dialog */
+	edit_dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (_("Edit VPN Connection"),
+							       NULL,
+							       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+							       GTK_STOCK_CANCEL,
+							       GTK_RESPONSE_REJECT,
+							       GTK_STOCK_APPLY,
+							       GTK_RESPONSE_ACCEPT,
+							       NULL));
+	/* reuse the widget */
+	gtk_signal_connect (GTK_OBJECT (edit_dialog), "delete-event", 
+			    GTK_SIGNAL_FUNC (gtk_widget_hide_on_delete), NULL);
+
+
+	/* update "Edit" and "Delete" for current selection */
+	update_edit_del_sensitivity ();
+}
+
+
+int
+main (int argc, char *argv[])
+{
+
+	gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE, argc, argv,
+			    GNOME_PARAM_NONE);
+
+	glade_gnome_init ();
+
+	bindtextdomain(PACKAGE, GNOMELOCALEDIR);
+	bind_textdomain_codeset(PACKAGE, "UTF-8");
+	textdomain(PACKAGE);
+
+	init_app ();
+
+	gtk_main ();
+
+	return 0;
+}
--- /dev/null	2005-05-23 10:03:46.347167944 -0400
+++ gnome/vpn-properties/example-vpnc-system-wide-connection.sh	2005-05-23 13:55:04.000000000 -0400
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+NAME="RH VPN Boston"
+ESCAPED_NAME="RH 32@VPN 32@Boston"
+IPSEC_GATEWAY="1.2.3.4"
+IPSEC_ID="myGroupName"
+IPSEC_SECRET="mySecret"
+IPSEC_USERNAME="davidz"
+IPSEC_ROUTES="[\"172.16.0.0/16\",\"192.168.4.0/24\"]"
+
+# TODO: remove user_name, routes
+
+GCONF_PATH="/system/networking/vpn_connections/$ESCAPED_NAME"
+
+GCONFTOOL2_OPTS="--direct --config-source xml:readwrite:/etc/gconf/gconf.xml.mandatory"
+
+gconftool-2 $GCONFTOOL2_OPTS --type string --set $GCONF_PATH/name "$NAME"
+gconftool-2 $GCONFTOOL2_OPTS --type string --set $GCONF_PATH/service_name "org.freedesktop.vpnc"
+gconftool-2 $GCONFTOOL2_OPTS --type string --set $GCONF_PATH/user_name $IPSEC_USERNAME
+gconftool-2 $GCONFTOOL2_OPTS --type list --list-type=string --set $GCONF_PATH/vpn_data ["IPSec gateway","$IPSEC_GATEWAY","IPSec ID","$IPSEC_ID","IPSec secret","$IPSEC_SECRET"]
+gconftool-2 $GCONFTOOL2_OPTS --type list --list-type=string --set $GCONF_PATH/routes $IPSEC_ROUTES
+


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