NetworkManager r3838 - in trunk/vpn-daemons/pptp: . auth-dialog auth-dialog-general po properties src src/external



Author: dcbw
Date: Sun Jul 20 22:45:51 2008
New Revision: 3838
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=3838&view=rev

Log:
2008-07-20  Dan Williams  <dcbw redhat com>

	Port to NM 0.7 VPN plugin API



Added:
   trunk/vpn-daemons/pptp/nm-pptp-service.conf
      - copied, changed from r3830, /trunk/vpn-daemons/pptp/nm-ppp-starter.conf
   trunk/vpn-daemons/pptp/nm-pptp-service.name.in
      - copied, changed from r3830, /trunk/vpn-daemons/pptp/nm-ppp-starter.name.in
   trunk/vpn-daemons/pptp/nm-pptp.desktop.in
      - copied, changed from r3830, /trunk/vpn-daemons/pptp/nm-ppp.desktop.in
   trunk/vpn-daemons/pptp/properties/advanced-dialog.c
   trunk/vpn-daemons/pptp/properties/advanced-dialog.h
   trunk/vpn-daemons/pptp/properties/import-export.c
   trunk/vpn-daemons/pptp/properties/import-export.h
   trunk/vpn-daemons/pptp/properties/nm-pptp-dialog.glade
   trunk/vpn-daemons/pptp/properties/nm-pptp.c
   trunk/vpn-daemons/pptp/properties/nm-pptp.h
   trunk/vpn-daemons/pptp/src/nm-ppp-status.h
   trunk/vpn-daemons/pptp/src/nm-pptp-pppd-plugin.c
      - copied, changed from r3830, /trunk/vpn-daemons/pptp/src/nm-pppd-plugin.c
   trunk/vpn-daemons/pptp/src/nm-pptp-pppd-service.xml
   trunk/vpn-daemons/pptp/src/nm-pptp-service.c
   trunk/vpn-daemons/pptp/src/nm-pptp-service.h
Removed:
   trunk/vpn-daemons/pptp/auth-dialog-general/
   trunk/vpn-daemons/pptp/nm-ppp-starter.conf
   trunk/vpn-daemons/pptp/nm-ppp-starter.name.in
   trunk/vpn-daemons/pptp/nm-ppp.desktop.in
   trunk/vpn-daemons/pptp/properties/nm-ppp-dialog.glade
   trunk/vpn-daemons/pptp/properties/nm-ppp-properties.c
   trunk/vpn-daemons/pptp/properties/nm-ppp-properties.h
   trunk/vpn-daemons/pptp/properties/util_lists.c
   trunk/vpn-daemons/pptp/properties/util_lists.h
   trunk/vpn-daemons/pptp/properties/vpnui_expand.c
   trunk/vpn-daemons/pptp/properties/vpnui_expand.h
   trunk/vpn-daemons/pptp/properties/vpnui_impl.c
   trunk/vpn-daemons/pptp/properties/vpnui_impl.h
   trunk/vpn-daemons/pptp/properties/vpnui_opt.c
   trunk/vpn-daemons/pptp/properties/vpnui_opt.h
   trunk/vpn-daemons/pptp/properties/vpnui_validate.c
   trunk/vpn-daemons/pptp/properties/vpnui_validate.h
   trunk/vpn-daemons/pptp/properties/vpnui_variant.c
   trunk/vpn-daemons/pptp/properties/vpnui_variant.h
   trunk/vpn-daemons/pptp/src/external/
   trunk/vpn-daemons/pptp/src/nm-ppp-starter.c
   trunk/vpn-daemons/pptp/src/nm-ppp-starter.h
   trunk/vpn-daemons/pptp/src/nm-pppd-plugin.c
   trunk/vpn-daemons/pptp/src/nm-pppd-plugin.h
   trunk/vpn-daemons/pptp/src/nm-utils.c
   trunk/vpn-daemons/pptp/src/nm-utils.h
Modified:
   trunk/vpn-daemons/pptp/ChangeLog
   trunk/vpn-daemons/pptp/Makefile.am
   trunk/vpn-daemons/pptp/README
   trunk/vpn-daemons/pptp/auth-dialog/Makefile.am
   trunk/vpn-daemons/pptp/auth-dialog/gnome-two-password-dialog.c
   trunk/vpn-daemons/pptp/auth-dialog/main.c
   trunk/vpn-daemons/pptp/configure.in
   trunk/vpn-daemons/pptp/po/POTFILES.in
   trunk/vpn-daemons/pptp/properties/Makefile.am
   trunk/vpn-daemons/pptp/src/Makefile.am

Modified: trunk/vpn-daemons/pptp/Makefile.am
==============================================================================
--- trunk/vpn-daemons/pptp/Makefile.am	(original)
+++ trunk/vpn-daemons/pptp/Makefile.am	Sun Jul 20 22:45:51 2008
@@ -1,24 +1,20 @@
+AUTOMAKE_OPTIONS = foreign
+
 if WITH_GNOME
-SUBDIRS = src auth-dialog auth-dialog-general properties po
+SUBDIRS = src auth-dialog properties po
 else
 SUBDIRS = src
 endif
 
 dbusservicedir = $(sysconfdir)/dbus-1/system.d
-dbusservice_DATA = nm-ppp-starter.conf
+dbusservice_DATA = nm-pptp-service.conf
 
-nmvpnservice_in_files = nm-ppp-starter.name.in
 nmvpnservicedir = $(sysconfdir)/NetworkManager/VPN
-nmvpnservice_DATA = $(nmvpnservice_in_files:.name.in=.name)
-
-%.name: %.name.in Makefile
-	@sed -e "s|%bindir%|$(bindir)|g" \
-	     -e "s|%libdir%|$(libdir)|g" \
-	     -e "s|%libexecdir%|$(libexecdir)|g" $< > $@
+nmvpnservice_DATA = nm-pptp-service.name
 
 if WITH_GNOME
 desktopdir = $(datadir)/applications
-desktop_in_files = nm-ppp.desktop.in
+desktop_in_files = nm-pptp.desktop.in
 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
 @INTLTOOL_DESKTOP_RULE@
 
@@ -26,14 +22,18 @@
 icon_DATA = gnome-mime-application-x-pptp-settings.png
 endif
 
-EXTRA_DIST =\
-	$(nmvpnservice_in_files)	\
-	$(dbusservice_DATA)		\
-	$(desktop_in_files)		\
-	$(icon_DATA)			\
-	intltool-extract.in		\
-	intltool-merge.in		\
-	intltool-update.in
+nm-pptp-service.name: $(srcdir)/nm-pptp-service.name.in Makefile
+	sed	-e 's|[ ]BINDIR[@]|$(bindir)|g' \
+		< $(srcdir)/nm-pptp-service.name.in \
+		> nm-pptp-service.name
+
+EXTRA_DIST = nm-pptp-service.name.in \
+             $(dbusservice_DATA)  \
+             $(desktop_in_files)  \
+             $(icon_DATA)         \
+             intltool-extract.in  \
+             intltool-merge.in    \
+             intltool-update.in
 
-CLEANFILES = $(desktop_DATA) $(nmvpnservice_DATA) *~
+CLEANFILES = $(nmvpnservice_DATA) $(desktop_DATA) *~
 DISTCLEANFILES = intltool-extract intltool-merge intltool-update

Modified: trunk/vpn-daemons/pptp/README
==============================================================================
--- trunk/vpn-daemons/pptp/README	(original)
+++ trunk/vpn-daemons/pptp/README	Sun Jul 20 22:45:51 2008
@@ -1,15 +1,17 @@
 PPTP support for NetworkManager
 
-Added by Antony Mee http://www.students.ncl.ac.uk/a.j.mee
-Based entirely on OpenVPN support by Tim Niemueller http://www.niemueller.de
-
 This requires the Linux PPTP client installed 
 http://pptpclient.sourceforge.net/
 
-TODO: Support for passwords stored outside of /etc/ppp/chap-secrets
+0.7.x version:
+(C) 2008 Dan Williams <dcbw redhat com>, and Tambet Ingo <tambet gmail com>
+
+0.6.x version:
+(C) 2005 - 2007 Antony Mee   http://www.students.ncl.ac.uk/a.j.mee
+Based entirely on OpenVPN support by Tim Niemueller http://www.niemueller.de
+
 
-Code released under the GPL. See COPYING file in the NetworkManager
-directory.
+Theory of operation
+------------------------------
 
-Aachen, 2005/11/12
 

Modified: trunk/vpn-daemons/pptp/auth-dialog/Makefile.am
==============================================================================
--- trunk/vpn-daemons/pptp/auth-dialog/Makefile.am	(original)
+++ trunk/vpn-daemons/pptp/auth-dialog/Makefile.am	Sun Jul 20 22:45:51 2008
@@ -1,8 +1,9 @@
-INCLUDES = -I${top_srcdir} -I${top_srcdir}/utils
+INCLUDES = -I${top_srcdir}
 
-libexec_PROGRAMS = nm-ppp-auth-dialog
+libexec_PROGRAMS = nm-pptp-auth-dialog
 
-nm_ppp_auth_dialog_CPPFLAGS =			\
+nm_pptp_auth_dialog_CPPFLAGS =			\
+	$(NM_UTILS_CFLAGS)			\
 	$(GTHREAD_CFLAGS)			\
 	$(GTK_CFLAGS)				\
 	$(LIBGNOMEUI_CFLAGS)			\
@@ -18,13 +19,13 @@
 	-DVERSION=\"$(VERSION)\"			\
 	$(NULL)
 
-nm_ppp_auth_dialog_SOURCES =			\
+nm_pptp_auth_dialog_SOURCES =			\
 	main.c					\
 	gnome-two-password-dialog.c		\
 	gnome-two-password-dialog.h		\
 	$(NULL)
 
-nm_ppp_auth_dialog_LDADD =			\
+nm_pptp_auth_dialog_LDADD =			\
 	$(GTK_LIBS)				\
 	$(LIBGNOMEUI_LIBS)			\
 	$(GNOMEKEYRING_LIBS)			\

Modified: trunk/vpn-daemons/pptp/auth-dialog/gnome-two-password-dialog.c
==============================================================================
--- trunk/vpn-daemons/pptp/auth-dialog/gnome-two-password-dialog.c	(original)
+++ trunk/vpn-daemons/pptp/auth-dialog/gnome-two-password-dialog.c	Sun Jul 20 22:45:51 2008
@@ -159,7 +159,6 @@
 
 	g_free (password_dialog->details->remember_label_text);
 	g_free (password_dialog->details->secondary_password_label);
-
 	g_free (password_dialog->details);
 
 	if (G_OBJECT_CLASS (parent_class)->finalize != NULL)
@@ -463,16 +462,15 @@
 	gtk_widget_show_all (GTK_DIALOG (password_dialog)->vbox);
 
 	password_dialog->details->remember_session_button =
-		gtk_check_button_new_with_mnemonic (_("_Remember password for this session"));
+		gtk_check_button_new_with_mnemonic (_("_Remember passwords for this session"));
 	password_dialog->details->remember_forever_button =
-		gtk_check_button_new_with_mnemonic (_("_Save password in keyring"));
+		gtk_check_button_new_with_mnemonic (_("_Save passwords in keyring"));
 
 	gtk_box_pack_start (GTK_BOX (vbox), password_dialog->details->remember_session_button, 
 			    FALSE, FALSE, 0);
 	gtk_box_pack_start (GTK_BOX (vbox), password_dialog->details->remember_forever_button, 
 			    FALSE, FALSE, 0);
-	
-	
+
 	gnome_two_password_dialog_set_username (password_dialog, username);
 	gnome_two_password_dialog_set_password (password_dialog, password);
 	gnome_two_password_dialog_set_readonly_domain (password_dialog, readonly_username);

Modified: trunk/vpn-daemons/pptp/auth-dialog/main.c
==============================================================================
--- trunk/vpn-daemons/pptp/auth-dialog/main.c	(original)
+++ trunk/vpn-daemons/pptp/auth-dialog/main.c	Sun Jul 20 22:45:51 2008
@@ -16,7 +16,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2004 Red Hat, Inc.
+ * (C) Copyright 2008 Red Hat, Inc.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -29,87 +29,118 @@
 #include <libgnomeui/libgnomeui.h>
 #include <gnome-keyring.h>
 
-#include "gnome-two-password-dialog.h"
+#include <nm-setting-vpn.h>
+#include <nm-setting-vpn-properties.h>
 
-#define VPN_SERVICE "org.freedesktop.NetworkManager.ppp_starter"
+#include "../src/nm-pptp-service.h"
+#include "gnome-two-password-dialog.h"
 
-static GSList *
-lookup_pass (const char *vpn_name, const char *vpn_service, char *auth_type, gboolean *is_session)
+#define KEYRING_CID_TAG "connection-id"
+#define KEYRING_SN_TAG "setting-name"
+#define KEYRING_SK_TAG "setting-key"
+
+static char *
+find_one_password (const char *vpn_id,
+                   const char *vpn_name,
+                   const char *vpn_service,
+                   const char *secret_name,
+                   gboolean *is_session)
 {
-	GSList *passwords;
-	GList *keyring_result;
+	GList *found_list = NULL;
+	GnomeKeyringResult ret;
+	GnomeKeyringFound *found;
+	char *secret;
+
+	ret = gnome_keyring_find_itemsv_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+	                                      &found_list,
+	                                      KEYRING_CID_TAG,
+	                                      GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+	                                      vpn_id,
+	                                      KEYRING_SN_TAG,
+	                                      GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+	                                      NM_SETTING_VPN_PROPERTIES_SETTING_NAME,
+	                                      KEYRING_SK_TAG,
+	                                      GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+	                                      secret_name,
+	                                      NULL);
+	if ((ret != GNOME_KEYRING_RESULT_OK) || (g_list_length (found_list) == 0))
+		return NULL;
+
+	found = (GnomeKeyringFound *) found_list->data;
+
+	if (strcmp (found->keyring, "session") == 0)
+		*is_session = TRUE;
+	else
+		*is_session = FALSE;
 
-	passwords = NULL;
+	secret = found->secret ? g_strdup (found->secret) : NULL;
+	gnome_keyring_found_list_free (found_list);
 
-	if (gnome_keyring_find_network_password_sync (NULL,  /* user */
-						      NULL,                   /* domain */
-						      vpn_name,               /* server */
-						      NULL,                   /* object */
-						      vpn_service,            /* protocol */
-						      auth_type,              /* authtype */
-						      0,                      /* port */
-						      &keyring_result) != GNOME_KEYRING_RESULT_OK)
-		return FALSE;
-
-	if (keyring_result != NULL && g_list_length (keyring_result) == 1) {
-		GnomeKeyringNetworkPasswordData *data = 
-             (GnomeKeyringNetworkPasswordData *)keyring_result->data;
-		char *username = NULL;
-		char *password = NULL;
-		char *auth_type = NULL;
-
-        username = data->user;
-        password = data->password;
-        auth_type = data->authtype;
-
-		if (password != NULL && username != NULL && auth_type != NULL) {
-// Statically set the authentication type for now.
-		    passwords = g_slist_append (passwords, g_strdup(auth_type));
-			passwords = g_slist_append (passwords, g_strdup (username));
-			passwords = g_slist_append (passwords, g_strdup (password));
-			if (strcmp (data->keyring, "session") == 0)
-				*is_session = TRUE;
-			else
-				*is_session = FALSE;
-		}
+	return secret;
+}
 
-		gnome_keyring_network_password_list_free (keyring_result);
-	}
+static GSList *
+lookup_pass (const char *vpn_id, const char *vpn_name, const char *vpn_service, gboolean *is_session)
+{
+	GSList *passwords = NULL;
+	char *password;
+
+	password = find_one_password (vpn_id, vpn_name, vpn_service, "password", is_session);
+	if (password)
+		passwords = g_slist_append (passwords, password);
 
 	return passwords;
 }
 
-static void save_vpn_password (const char *vpn_name, const char *vpn_service, const char *keyring, 
-			       const char *auth_type, const char *username, const char *password)
+static void
+save_vpn_password (const char *vpn_id,
+                   const char *vpn_name,
+                   const char *vpn_service,
+                   const char *keyring,
+                   const char *secret_name,
+                   const char *secret)
 {
-	guint32 item_id;
-	GnomeKeyringResult keyring_result;
-
-	keyring_result = gnome_keyring_set_network_password_sync (keyring,
-								  username,
-								  NULL,
-								  vpn_name,
-								  NULL,
-								  vpn_service,
-								  auth_type,
-								  0,
-								  password,
-								  &item_id);
-	if (keyring_result != GNOME_KEYRING_RESULT_OK)
-	{
-		g_warning ("Couldn't store authentication information in keyring, code %d", (int) keyring_result);
-	}
-
+	char *display_name;
+	GnomeKeyringResult ret;
+	GnomeKeyringAttributeList *attrs = NULL;
+	guint32 id = 0;
+
+	display_name = g_strdup_printf ("VPN %s secret for %s/%s/" NM_SETTING_VPN_PROPERTIES_SETTING_NAME,
+	                                secret_name,
+	                                vpn_name,
+	                                vpn_service);
+
+	attrs = gnome_keyring_attribute_list_new ();
+	gnome_keyring_attribute_list_append_string (attrs,
+	                                            KEYRING_CID_TAG,
+	                                            vpn_id);
+	gnome_keyring_attribute_list_append_string (attrs,
+	                                            KEYRING_SN_TAG,
+	                                            NM_SETTING_VPN_PROPERTIES_SETTING_NAME);
+	gnome_keyring_attribute_list_append_string (attrs,
+	                                            KEYRING_SK_TAG,
+	                                            secret_name);
+
+	ret = gnome_keyring_item_create_sync (keyring,
+	                                      GNOME_KEYRING_ITEM_GENERIC_SECRET,
+	                                      display_name,
+	                                      attrs,
+	                                      secret,
+	                                      TRUE,
+	                                      &id);
+	gnome_keyring_attribute_list_free (attrs);
+	g_free (display_name);
 }
 
 static GSList *
-get_passwords (const char *vpn_name, const char *vpn_service, gboolean retry)
+get_passwords (const char *vpn_id,
+               const char *vpn_name,
+               const char *vpn_service,
+               gboolean retry)
 {
 	GSList          *result;
 	char            *prompt;
-	GtkWidget	    *dialog;
-	char            *keyring_authtype;
-	char            *keyring_username;
+	GtkWidget	*dialog;
 	char            *keyring_password;
 	gboolean         keyring_is_session;
 	GSList          *keyring_result;
@@ -117,36 +148,34 @@
 
 	result = NULL;
 	keyring_password = NULL;
-	keyring_username = NULL;
 	keyring_result = NULL;
 
+	g_return_val_if_fail (vpn_id != NULL, NULL);
 	g_return_val_if_fail (vpn_name != NULL, NULL);
 
 	/* Use the system user name, since the VPN might have a different user name */
 	if (!retry) {
-		if ((result = lookup_pass (vpn_name, vpn_service, "CHAP", &keyring_is_session)) != NULL) {
+		if ((result = lookup_pass (vpn_id, vpn_name, vpn_service, &keyring_is_session)) != NULL) {
 			return result;
 		}
 	} else {
-		if ((keyring_result = lookup_pass (vpn_name, vpn_service, "CHAP", &keyring_is_session)) != NULL) {
-			keyring_authtype = g_strdup ((char *) keyring_result->data);
-			keyring_username = g_strdup ((char *) (g_slist_next (keyring_result))->data);
-			keyring_password = g_strdup ((char *) (g_slist_next (g_slist_next (keyring_result)))->data);
-		}
+		if ((keyring_result = lookup_pass (vpn_id, vpn_name, vpn_service, &keyring_is_session)) != NULL)
+			keyring_password = g_strdup ((char *) (g_slist_next (keyring_result))->data);
+
 		g_slist_foreach (keyring_result, (GFunc)g_free, NULL);
 		g_slist_free (keyring_result);
 	}
 
-	prompt = g_strdup_printf (_("You need to authenticate to access '%s'."), vpn_name);
-	dialog = gnome_two_password_dialog_new (_("Authenticate Connection"), prompt, NULL, NULL, FALSE);
+	prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network '%s'."), vpn_name);
+	dialog = gnome_two_password_dialog_new (_("Authenticate VPN"), prompt, NULL, NULL, FALSE);
 	g_free (prompt);
 
+	gnome_two_password_dialog_set_show_username (GNOME_TWO_PASSWORD_DIALOG (dialog), FALSE);
 	gnome_two_password_dialog_set_show_userpass_buttons (GNOME_TWO_PASSWORD_DIALOG (dialog), FALSE);
-	gnome_two_password_dialog_set_show_username (GNOME_TWO_PASSWORD_DIALOG (dialog), TRUE);
 	gnome_two_password_dialog_set_show_domain (GNOME_TWO_PASSWORD_DIALOG (dialog), FALSE);
 	gnome_two_password_dialog_set_show_remember (GNOME_TWO_PASSWORD_DIALOG (dialog), TRUE);
 	gnome_two_password_dialog_set_show_password_secondary (GNOME_TWO_PASSWORD_DIALOG (dialog), FALSE);
-	//gnome_two_password_dialog_set_password_secondary_label (GNOME_TWO_PASSWORD_DIALOG (dialog), _("_Group Password:"));
+
 	/* use the same keyring storage options as from the items we put in the entry boxes */
 	remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_NOTHING;
 	if (keyring_result != NULL) {
@@ -158,9 +187,6 @@
 	gnome_two_password_dialog_set_remember (GNOME_TWO_PASSWORD_DIALOG (dialog), remember);
 
 	/* if retrying, put in the passwords from the keyring */
-	if (keyring_username != NULL) {
-		gnome_two_password_dialog_set_username (GNOME_TWO_PASSWORD_DIALOG (dialog), keyring_username);
-	}
 	if (keyring_password != NULL) {
 		gnome_two_password_dialog_set_password (GNOME_TWO_PASSWORD_DIALOG (dialog), keyring_password);
 	}
@@ -169,25 +195,18 @@
 
 	if (gnome_two_password_dialog_run_and_block (GNOME_TWO_PASSWORD_DIALOG (dialog)))
 	{
-		char *username;
 		char *password;
-		char *auth_type;
 
-		username = gnome_two_password_dialog_get_username (GNOME_TWO_PASSWORD_DIALOG (dialog));
 		password = gnome_two_password_dialog_get_password (GNOME_TWO_PASSWORD_DIALOG (dialog));
-// Statically set the authentication type for now.
-        auth_type = g_strdup("CHAP");
-		result = g_slist_append (result, auth_type);
-		result = g_slist_append (result, g_strdup(username));
-		result = g_slist_append (result, g_strdup(password));
+		result = g_slist_append (result, password);
 
 		switch (gnome_two_password_dialog_get_remember (GNOME_TWO_PASSWORD_DIALOG (dialog)))
 		{
 			case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION:
-				save_vpn_password (vpn_name, vpn_service, "session", auth_type, username, password);
+				save_vpn_password (vpn_id, vpn_name, vpn_service, "session", "password", password);
 				break;
 			case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER:
-				save_vpn_password (vpn_name, vpn_service, NULL, auth_type, username, password);
+				save_vpn_password (vpn_id, vpn_name, vpn_service, NULL, "password", password);
 				break;
 			default:
 				break;
@@ -195,10 +214,8 @@
 
 	}
 
-	if (keyring_username!=NULL) g_free (keyring_username);
-	if (keyring_password!=NULL) g_free (keyring_password);
+	g_free (keyring_password);
 
-	gtk_widget_hide (dialog);
 	gtk_widget_destroy (dialog);
 
 	return result;
@@ -207,22 +224,23 @@
 int 
 main (int argc, char *argv[])
 {
-	GSList *i;
 	GSList *passwords;
 	static gboolean retry = FALSE;
 	static gchar *vpn_name = NULL;
+	static gchar *vpn_id = NULL;
 	static gchar *vpn_service = NULL;
-	GError *error = NULL;
+	char buf[1];
+	int ret;
 	GOptionContext *context;
 	GnomeProgram *program;
 	GOptionEntry entries[] =
 		{
 			{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
+			{ "id", 'i', 0, G_OPTION_ARG_STRING, &vpn_id, "ID of VPN connection", NULL},
 			{ "name", 'n', 0, G_OPTION_ARG_STRING, &vpn_name, "Name of VPN connection", NULL},
 			{ "service", 's', 0, G_OPTION_ARG_STRING, &vpn_service, "VPN service type", NULL},
 			{ NULL }
 		};
-	char buf[1];
 
 	bindtextdomain (GETTEXT_PACKAGE, NULL);
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
@@ -230,35 +248,35 @@
 
 	passwords = NULL;
 	
-	context = g_option_context_new ("- ppp auth dialog");
+	context = g_option_context_new ("- pptp auth dialog");
 	g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
-
-	program = gnome_program_init ("nm-ppp-auth-dialog", VERSION,
+	
+	program = gnome_program_init ("nm-pptp-auth-dialog", VERSION,
 				      LIBGNOMEUI_MODULE,
 				      argc, argv,
 				      GNOME_PARAM_GOPTION_CONTEXT, context,
 				      GNOME_PARAM_NONE);
 	  
-	if (vpn_name == NULL || vpn_service == NULL) {
-		fprintf (stderr, "Have to supply both name and service\n");
+
+	if (vpn_id == NULL || vpn_name == NULL || vpn_service == NULL) {
+		fprintf (stderr, "Have to supply ID, name, and service\n");
 		goto out;
 	}
 
-	if (strcmp (vpn_service, VPN_SERVICE) != 0) {
-		fprintf (stderr, "This dialog only works with the '%s' service\n", VPN_SERVICE);
+	if (strcmp (vpn_service, NM_DBUS_SERVICE_PPTP) != 0) {
+		fprintf (stderr, "This dialog only works with the '%s' service\n", NM_DBUS_SERVICE_PPTP);
 		goto out;		
 	}
 
-	passwords = get_passwords (vpn_name, vpn_service, retry);
+	passwords = get_passwords (vpn_id, vpn_name, vpn_service, retry);
 	if (passwords == NULL)
 		goto out;
 
 	/* dump the passwords to stdout */
-	for (i = passwords; i != NULL; i = g_slist_next (i)) {
-		char *password = (char *) i->data;
-		printf ("%s\n", password);
-	}
+
+	printf ("%s\n%s\n", NM_PPTP_KEY_PASSWORD, (char *) passwords->data);
 	printf ("\n\n");
+
 	/* for good measure, flush stdout since Kansas is going Bye-Bye */
 	fflush (stdout);
 
@@ -266,7 +284,7 @@
 	g_slist_free (passwords);
 
 	/* wait for data on stdin  */
-	fread (buf, sizeof (char), sizeof (buf), stdin);
+	ret = fread (buf, sizeof (char), sizeof (buf), stdin);
 
 out:
 	g_object_unref (program);

Modified: trunk/vpn-daemons/pptp/configure.in
==============================================================================
--- trunk/vpn-daemons/pptp/configure.in	(original)
+++ trunk/vpn-daemons/pptp/configure.in	Sun Jul 20 22:45:51 2008
@@ -1,10 +1,11 @@
 AC_PREREQ(2.59)
 
-AC_INIT(NetworkManager-ppp_vpn, 0.7.0-beta, eemynotna gmail com, NetworkManager-ppp_vpn)
-
+AC_INIT(NetworkManager-pptp, 0.7.0, dcbw redhat com, NetworkManager-pptp)
+AC_CONFIG_AUX_DIR(.)
 AM_INIT_AUTOMAKE([1.9 foreign no-dist-gzip dist-bzip2 subdir-objects])
+AM_MAINTAINER_MODE
 
-AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_HEADER(config.h)
 
 dnl
 dnl Require programs
@@ -14,66 +15,23 @@
 AC_PROG_INSTALL
 AC_PROG_LIBTOOL
 
-
 dnl
 dnl Required headers
 dnl
 AC_HEADER_STDC
 AC_CHECK_HEADERS(fcntl.h paths.h sys/ioctl.h sys/time.h syslog.h unistd.h)
 
-AC_ARG_WITH(pppd, AC_HELP_STRING([--with-pppd=DISTRO], [Specify path to pppd.h (and patchlevel.h)]))
-AC_ARG_WITH(pppd-version, AC_HELP_STRING([--with-pppd-version=DISTRO], [Version of pppd.h]))
-if test "z$with_pppd" != "z"; then
-  AC_MSG_CHECKING([for $with_pppd/pppd.h])
-  if test -f "$with_pppd/pppd.h"; then
-    PPPD_CFLAGS="-I $with_pppd"
-    PPPD_VERSION=`grep VERSION $with_pppd/patchlevel.h | awk '{print $3}' | sed -e 's/\s*"\s*//g'`
-    found_pppd_headers=yes
-    AC_MSG_RESULT(found version $PPPD_VERSION)
-  else
-    AC_MSG_ERROR(not found in $with_pppd)
-  fi 
-fi
-
-if test "z$found_pppd_headers" = "z"; then
-  AC_MSG_CHECKING([for pppd.h under $prefix/include])
-  find_pppd_h=`find $prefix/include -name pppd.h | xargs | awk '{print $1}'`
-  if echo $find_pppd_h | grep pppd.h; then
-    with_pppd=`dirname $find_pppd_h`
-    PPPD_CFLAGS="-I $with_pppd"
-    PPPD_VERSION=`grep VERSION $with_pppd/patchlevel.h | awk '{print $3}' | sed -e 's/\s*"\s*//g'`
-    found_pppd_headers=yes
-    AC_MSG_RESULT(found version $PPPD_VERSION)
-  else
-    AC_MSG_RESULT(not found)
-  fi
-fi
+AC_CHECK_HEADERS(pppd/pppd.h,,
+  AC_MSG_ERROR(couldn't find pppd.h. pppd development headers are required.))
 
-if test "z$found_pppd_headers" = "z"; then
-  if test "z$PPPD_VERSION" = "z"; then
-    AC_MSG_RESULT(Couldn't find pppd.h trying to determine pppd version to use in tree headers)
-    ##### Find PPPD executable
-    AC_CHECK_PROG(PPPD,pppd,pppd)
-    if test "z$PPPD" = "z"; then
-        AC_MSG_ERROR(Cannot compile without pppd)
-    fi
-    AC_MSG_RESULT(pppd version not found attempting to run 'pppd --version')
-    PPPD_VERSION=`$PPPD --version 2>&1 | awk '{print $3}'`
-    if test "z$PPPD_VERSION" = "z"; then
-        AC_MSG_ERROR(Couldn't determine the version of your pppd package.)
-    fi
-  fi
-
-  if ! test -d "src/external/$PPPD_VERSION"; then
-    AC_MSG_ERROR(pppd headers could not be found)
-  fi
+AC_ARG_WITH([pppd-plugin-dir], AS_HELP_STRING([--with-pppd-plugin-dir=DIR], [path to the pppd plugins directory]))
 
-  AC_MSG_RESULT(Found in source headers for pppd version $PPPD_VERSION)
-  PPPD_CFLAGS="-I ./external/$PPPD_VERSION"
+if test -n "$with_pppd_plugin_dir" ; then
+	PPPD_PLUGIN_DIR="$with_pppd_plugin_dir"
+else
+	PPPD_PLUGIN_DIR="${libdir}/pppd/2.4.4"
 fi
-
-AC_SUBST([PPPD_VERSION])
-AC_SUBST(PPPD_CFLAGS)
+AC_SUBST(PPPD_PLUGIN_DIR)
 
 dnl
 dnl Checks for typedefs, structures, and compiler characteristics.
@@ -95,7 +53,7 @@
 AC_ARG_WITH(gnome, AC_HELP_STRING([--without-gnome], [Build NetworkManager-pptp without GNOME support, e.g. vpn service only]))
 AM_CONDITIONAL(WITH_GNOME, test x"$with_gnome" != xno)
 
-GETTEXT_PACKAGE=NetworkManager-ppp_vpn
+GETTEXT_PACKAGE=NetworkManager-pptp
 AC_SUBST(GETTEXT_PACKAGE)
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package])
 
@@ -106,13 +64,13 @@
 AC_SUBST(GTHREAD_CFLAGS)
 AC_SUBST(GTHREAD_LIBS)
 
-PKG_CHECK_MODULES(DBUS, dbus-glib-1 >= 0.30)
-AC_SUBST(DBUS_CFLAGS)
-AC_SUBST(DBUS_LIBS)
-
-PKG_CHECK_MODULES(NETWORK_MANAGER, NetworkManager >= 0.4.1 libnm-util >= 0.7.0)
-AC_SUBST(NETWORK_MANAGER_CFLAGS)
-AC_SUBST(NETWORK_MANAGER_LIBS)
+PKG_CHECK_MODULES(DBUS, dbus-glib-1 >= 0.74)
+AC_SUBST(DBUS_GLIB_CFLAGS)
+AC_SUBST(DBUS_GLIB_LIBS)
+
+PKG_CHECK_MODULES(NM_UTILS, NetworkManager >= 0.7.0 libnm-util libnm_glib libnm_glib_vpn)
+AC_SUBST(NM_UTILS_CFLAGS)
+AC_SUBST(NM_UTILS_LIBS)
 
 if test x"$with_gnome" != xno; then
 	PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.6)
@@ -140,19 +98,6 @@
 	AC_SUBST(GNOMEKEYRING_LIBS)
 fi
 
-AC_ARG_ENABLE(nm-vpn-dbus-old,
-AC_HELP_STRING([ --enable-nm-vpn-dbus-old], [Build Plugin to use old non-'DBUS Dict' NetworkManager VPN interface [default=no]]), 
-enable_nm_vpn_dbus_old="$enableval", enable_nm_vpn_dbus_old=no)
-NM_VPN_CFLAGS=
-if test "x$enable_nm_vpn_dbus_old" = "xyes" ; then
-    NM_VPN_CFLAGS="-DNM_VPN_USE_OLD_DBUS_INTERFACE"
-fi
-AC_SUBST(NM_VPN_CFLAGS)
-
-AC_ARG_ENABLE(bluetooth, [  --enable-bluetooth  Build Bluetooth bits [default=no]], enable_bluetooth="$enableval", enable_bluetooth=no)
-if test "x$enable_bluetooth" = "xyes" ; then
-    BUILD_BLUETOOTH="yes"
-fi
 AC_ARG_ENABLE(more-warnings,
 AC_HELP_STRING([--enable-more-warnings], [Maximum compiler warnings]),
 set_more_warnings="$enableval",[
@@ -186,13 +131,11 @@
 	AC_MSG_RESULT(no)
 fi
 
-AC_CONFIG_FILES([
+AC_OUTPUT([
 Makefile
 src/Makefile
 auth-dialog/Makefile
-auth-dialog-general/Makefile
 properties/Makefile
 po/Makefile.in
 ])
 
-AC_OUTPUT

Copied: trunk/vpn-daemons/pptp/nm-pptp-service.conf (from r3830, /trunk/vpn-daemons/pptp/nm-ppp-starter.conf)
==============================================================================
--- /trunk/vpn-daemons/pptp/nm-ppp-starter.conf	(original)
+++ trunk/vpn-daemons/pptp/nm-pptp-service.conf	Sun Jul 20 22:45:51 2008
@@ -3,14 +3,22 @@
  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd";>
 <busconfig>
 	<policy user="root">
-		<allow own="org.freedesktop.NetworkManager.ppp_starter"/>
-		<allow send_destination="org.freedesktop.NetworkManager.ppp_starter"/>
-		<allow send_interface="org.freedesktop.NetworkManager.ppp_starter"/>
+		<allow own="org.freedesktop.NetworkManager.pptp"/>
+		<allow send_destination="org.freedesktop.NetworkManager.pptp"/>
+		<allow send_interface="org.freedesktop.NetworkManager.pptp"/>
+
+		<allow own="org.freedesktop.NetworkManager.pptp-ppp"/>
+		<allow send_destination="org.freedesktop.NetworkManager.pptp-ppp"/>
+		<allow send_interface="org.freedesktop.NetworkManager.pptp-ppp"/>
 	</policy>
 	<policy context="default">
-		<deny own="org.freedesktop.NetworkManager.ppp_starter"/>
-		<deny send_destination="org.freedesktop.NetworkManager.ppp_starter"/>
-		<deny send_interface="org.freedesktop.NetworkManager.ppp_starter"/>
+		<deny own="org.freedesktop.NetworkManager.pptp"/>
+		<deny send_destination="org.freedesktop.NetworkManager.pptp"/>
+		<deny send_interface="org.freedesktop.NetworkManager.pptp"/>
+
+		<deny own="org.freedesktop.NetworkManager.pptp-ppp"/>
+		<deny send_destination="org.freedesktop.NetworkManager.pptp-ppp"/>
+		<deny send_interface="org.freedesktop.NetworkManager.pptp-ppp"/>
 	</policy>
 </busconfig>
 

Copied: trunk/vpn-daemons/pptp/nm-pptp-service.name.in (from r3830, /trunk/vpn-daemons/pptp/nm-ppp-starter.name.in)
==============================================================================
--- /trunk/vpn-daemons/pptp/nm-ppp-starter.name.in	(original)
+++ trunk/vpn-daemons/pptp/nm-pptp-service.name.in	Sun Jul 20 22:45:51 2008
@@ -1,8 +1,8 @@
 [VPN Connection]
-name=ppp
-service=org.freedesktop.NetworkManager.ppp_starter
-program= BINDIR@/nm-ppp-starter
+name=pptp
+service=org.freedesktop.NetworkManager.pptp
+program= BINDIR@/nm-pptp-service
 
 [GNOME]
-auth-dialog= LIBEXECDIR@/nm-ppp-auth-dialog
-properties= PREFIX@/${LIB}/libnm-ppp-properties
+auth-dialog=nm-pptp-auth-dialog
+properties=libnm-pptp-properties

Copied: trunk/vpn-daemons/pptp/nm-pptp.desktop.in (from r3830, /trunk/vpn-daemons/pptp/nm-ppp.desktop.in)
==============================================================================
--- /trunk/vpn-daemons/pptp/nm-ppp.desktop.in	(original)
+++ trunk/vpn-daemons/pptp/nm-pptp.desktop.in	Sun Jul 20 22:45:51 2008
@@ -1,9 +1,9 @@
 [Desktop Entry]
 Encoding=UTF-8
-_Name=VPN Connection Manager (PPP generic)
-_GenericName=VPN Connection Manager (PPP generic)
-_Comment=Add, Remove, and Edit VPN Connections
-Exec=nm-vpn-properties --import-service org.freedesktop.NetworkManager.ppp_starter --import-file %f
+_Name=PPTP VPN Connection Manager
+_GenericName=PPTP VPN Connection Manager
+_Comment=Add, Remove, and Edit PPTP VPN Connections
+Exec=nm-vpn-properties --import-service org.freedesktop.NetworkManager.pptp --import-file %f
 Icon=gnome-mime-application-x-ppp-settings
 Terminal=false
 Type=Application

Modified: trunk/vpn-daemons/pptp/po/POTFILES.in
==============================================================================
--- trunk/vpn-daemons/pptp/po/POTFILES.in	(original)
+++ trunk/vpn-daemons/pptp/po/POTFILES.in	Sun Jul 20 22:45:51 2008
@@ -1,12 +1,9 @@
 # List of source files containing translatable strings.
 # Please keep this file sorted alphabetically.
-auth-dialog-general/gnome-generic-auth-dialog.c
-auth-dialog-general/main.c
-auth-dialog-general/nm-ppp-auth.glade
 auth-dialog/gnome-two-password-dialog.c
 auth-dialog/main.c
-nm-ppp.desktop.in
-properties/nm-ppp-dialog.glade
-properties/nm-ppp-properties.c
-properties/vpnui_impl.c
-src/nm-ppp-starter.c
+nm-pptp.desktop.in
+properties/advanced-dialog.c
+properties/nm-pptp-dialog.glade
+properties/nm-pptp.c
+src/nm-pptp-service.c

Modified: trunk/vpn-daemons/pptp/properties/Makefile.am
==============================================================================
--- trunk/vpn-daemons/pptp/properties/Makefile.am	(original)
+++ trunk/vpn-daemons/pptp/properties/Makefile.am	Sun Jul 20 22:45:51 2008
@@ -1,32 +1,22 @@
+lib_LTLIBRARIES = libnm-pptp-properties.la
 
+libnm_pptp_properties_la_SOURCES = \
+	nm-pptp.c \
+	nm-pptp.h \
+	advanced-dialog.c \
+	advanced-dialog.h \
+	import-export.c \
+	import-export.h
 
-lib_LTLIBRARIES = libnm-ppp-properties.la
+gladedir = $(datadir)/gnome-vpn-properties/pptp
+glade_DATA = nm-pptp-dialog.glade
 
-libnm_ppp_properties_la_SOURCES = 			\
-				nm-ppp-properties.c \
-                vpnui_impl.c \
-                vpnui_expand.c \
-                vpnui_opt.c \
-                vpnui_validate.c \
-                vpnui_variant.c  \
-                util_lists.c \
-                vpnui_impl.h \
-                vpnui_opt.h  \
-                vpnui_expand.h \
-                vpnui_validate.h \
-                vpnui_variant.h  \
-                util_lists.h \
-                vpnui_impl.h 
-
-gladedir = $(datadir)/gnome-vpn-properties/ppp
-glade_DATA = nm-ppp-dialog.glade
-
-libnm_ppp_properties_la_CFLAGS =                        \
+libnm_pptp_properties_la_CFLAGS =                    \
         $(GLADE_CFLAGS)                                 \
         $(GTK_CFLAGS)                                   \
         $(GCONF_CFLAGS)                                 \
         $(LIBGNOMEUI_CFLAGS)                            \
-        $(NETWORK_MANAGER_CFLAGS)                       \
+        $(NM_UTILS_CFLAGS)                       \
         -DICONDIR=\""$(datadir)/pixmaps"\"              \
         -DGLADEDIR=\""$(gladedir)"\"                    \
         -DG_DISABLE_DEPRECATED                          \
@@ -35,14 +25,14 @@
         -DGNOMELOCALEDIR=\"$(datadir)/locale\"          \
         -DVERSION=\"$(VERSION)\"
 
-libnm_ppp_properties_la_LIBADD =        \
+libnm_pptp_properties_la_LIBADD =    \
         $(GLADE_LIBS)                   \
         $(GTK_LIBS)                     \
         $(GCONF_LIBS)                   \
         $(LIBGNOMEUI_LIBS)              \
-        $(NETWORK_MANAGER_LIBS)
+        $(NM_UTILS_LIBS)
 
-libnm_ppp_properties_la_LDFLAGS =       \
+libnm_pptp_properties_la_LDFLAGS =   \
         -avoid-version
 
 CLEANFILES = *.bak *.gladep *~

Added: trunk/vpn-daemons/pptp/properties/advanced-dialog.c
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/properties/advanced-dialog.c	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,478 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/***************************************************************************
+ *
+ * Copyright (C) 2008 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <glade/glade.h>
+
+#include <nm-connection.h>
+#include <nm-setting-vpn.h>
+#include <nm-setting-vpn-properties.h>
+
+#include "advanced-dialog.h"
+#include "nm-pptp.h"
+#include "../src/nm-pptp-service.h"
+
+#define COL_NAME  0
+#define COL_VALUE 1
+#define COL_TAG 2
+
+#define TAG_PAP 0
+#define TAG_CHAP 1
+#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,
+	NM_PPTP_KEY_REFUSE_CHAP,
+	NM_PPTP_KEY_REFUSE_MSCHAP,
+	NM_PPTP_KEY_REFUSE_MSCHAPV2,
+	NM_PPTP_KEY_REQUIRE_MPPE,
+	NM_PPTP_KEY_REQUIRE_MPPE_40,
+	NM_PPTP_KEY_REQUIRE_MPPE_128,
+	NM_PPTP_KEY_MPPE_STATEFUL,
+	NM_PPTP_KEY_NOBSDCOMP,
+	NM_PPTP_KEY_NODEFLATE,
+	NM_PPTP_KEY_NO_VJ_COMP,
+	NM_PPTP_KEY_LCP_ECHO_FAILURE,
+	NM_PPTP_KEY_LCP_ECHO_INTERVAL,
+	NULL
+};
+
+static void
+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)));
+		}
+	}
+}
+
+GHashTable *
+advanced_dialog_new_hash_from_connection (NMConnection *connection,
+                                          GError **error)
+{
+	GHashTable *hash;
+	NMSettingVPNProperties *s_vpn_props;
+
+	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
+
+	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);
+
+	return hash;
+}
+
+static void
+mppe_toggled_cb (GtkWidget *check, gpointer user_data)
+{
+	GladeXML *xml = (GladeXML *) user_data;
+	GtkWidget *widget;
+	gboolean use_mppe;
+
+	use_mppe = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check));
+
+	widget = glade_xml_get_widget (xml, "ppp_mppe_security_label");
+	gtk_widget_set_sensitive (widget, use_mppe);
+
+	widget = glade_xml_get_widget (xml, "ppp_mppe_security_combo");
+	if (!use_mppe)
+		gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); /* default */
+	gtk_widget_set_sensitive (widget, use_mppe);
+
+	widget = glade_xml_get_widget (xml, "ppp_allow_stateful_mppe");
+	if (!use_mppe)
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+	gtk_widget_set_sensitive (widget, use_mppe);
+}
+
+#define SEC_INDEX_DEFAULT   0
+#define SEC_INDEX_MPPE_128  1
+#define SEC_INDEX_MPPE_40   2
+
+static void
+setup_security_combo (GladeXML *xml, GHashTable *hash)
+{
+	GtkWidget *widget;
+	GtkListStore *store;
+	GtkTreeIter iter;
+	int active = -1;
+	GValue *value;
+
+	g_return_if_fail (xml != NULL);
+	g_return_if_fail (hash != NULL);
+
+	widget = glade_xml_get_widget (xml, "ppp_mppe_security_combo");
+
+	store = gtk_list_store_new (1, G_TYPE_STRING);
+
+	/* Default */
+	gtk_list_store_append (store, &iter);
+	gtk_list_store_set (store, &iter, 0, _("All Available (Default)"), -1);
+
+	/* MPPE-128 */
+	gtk_list_store_append (store, &iter);
+	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))
+			active = SEC_INDEX_MPPE_128;
+	}
+
+	/* MPPE-40 */
+	gtk_list_store_append (store, &iter);
+	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))
+			active = SEC_INDEX_MPPE_40;
+	}
+
+	gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
+	g_object_unref (store);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active < 0 ? SEC_INDEX_DEFAULT : active);
+}
+
+static void
+check_toggled_cb (GtkCellRendererToggle *cell, gchar *path_str, gpointer user_data)
+{
+	GladeXML *xml = GLADE_XML (user_data);
+	GtkWidget *widget;
+	GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean toggle_item;
+
+	widget = glade_xml_get_widget (xml, "ppp_auth_methods");
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+
+	gtk_tree_model_get_iter (model, &iter, path);
+	gtk_tree_model_get (model, &iter, COL_VALUE, &toggle_item, -1);
+
+	toggle_item ^= 1;
+
+	/* set new value */
+	gtk_list_store_set (GTK_LIST_STORE (model), &iter, COL_VALUE, toggle_item, -1);
+
+	gtk_tree_path_free (path);
+}
+
+static void
+auth_methods_setup (GladeXML *xml, GHashTable *hash)
+{
+	GtkWidget *widget;
+	GtkListStore *store;
+	GtkTreeIter iter;
+	GValue *value;
+	gboolean allowed;
+	gboolean use_mppe = FALSE;
+	GtkCellRendererToggle *check_renderer;
+	GtkCellRenderer *text_renderer;
+	GtkTreeViewColumn *column;
+	gint offset;
+
+	store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT);
+
+	/* 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))
+		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))
+		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))
+		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;
+	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;
+	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;
+	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;
+	gtk_list_store_append (store, &iter);
+	gtk_list_store_set (store, &iter, COL_NAME, _("MSCHAPv2"), COL_VALUE, allowed, COL_TAG, TAG_MSCHAPV2, -1);
+
+	/* Set up the tree view */
+	widget = glade_xml_get_widget (xml, "ppp_auth_methods");
+	gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL (store));
+
+	check_renderer = GTK_CELL_RENDERER_TOGGLE (gtk_cell_renderer_toggle_new ());
+	g_signal_connect (check_renderer, "toggled", G_CALLBACK (check_toggled_cb), xml);
+
+	offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget),
+	                                                      -1, "", GTK_CELL_RENDERER (check_renderer),
+	                                                      "active", COL_VALUE,
+	                                                      NULL);
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), offset - 1);
+	gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), GTK_TREE_VIEW_COLUMN_FIXED);
+	gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 30);
+	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
+
+	text_renderer = gtk_cell_renderer_text_new ();
+	offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget),
+	                                                      -1, "", text_renderer,
+	                                                      "text", COL_NAME,
+	                                                      NULL);
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), offset - 1);
+	gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
+}
+
+GtkWidget *
+advanced_dialog_new (GHashTable *hash)
+{
+	GladeXML *xml;
+	GtkWidget *dialog = NULL;
+	char *glade_file = NULL;
+	GtkWidget *widget;
+	GValue *value;
+
+	g_return_val_if_fail (hash != NULL, NULL);
+
+	glade_file = g_strdup_printf ("%s/%s", GLADEDIR, "nm-pptp-dialog.glade");
+	xml = glade_xml_new (glade_file, "pptp-advanced-dialog", GETTEXT_PACKAGE);
+	if (xml == NULL)
+		goto out;
+
+	dialog = glade_xml_get_widget (xml, "pptp-advanced-dialog");
+	if (!dialog) {
+		g_object_unref (G_OBJECT (xml));
+		goto out;
+	}
+	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+	g_object_set_data_full (G_OBJECT (dialog), "glade-xml",
+	                        xml, (GDestroyNotify) g_object_unref);
+
+
+	setup_security_combo (xml, hash);
+
+	widget = glade_xml_get_widget (xml, "ppp_use_mppe");
+	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);
+	}
+	mppe_toggled_cb (widget, xml);
+
+	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);
+	}
+
+	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);
+	}
+
+	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);
+	}
+
+	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);
+	}
+
+	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))
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+	}
+
+	auth_methods_setup (xml, hash);
+
+out:
+	g_free (glade_file);
+	return dialog;
+}
+
+GHashTable *
+advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error)
+{
+	GHashTable *hash;
+	GtkWidget *widget;
+	GladeXML *xml;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean valid;
+
+	g_return_val_if_fail (dialog != NULL, NULL);
+	if (error)
+		g_return_val_if_fail (*error == NULL, NULL);
+
+	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);
+
+	widget = glade_xml_get_widget (xml, "ppp_use_mppe");
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
+
+		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));
+			break;
+		case SEC_INDEX_MPPE_40:
+			g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REQUIRE_MPPE_40), bool_to_gvalue (TRUE));
+			break;
+		default:
+			g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REQUIRE_MPPE), bool_to_gvalue (TRUE));
+			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));
+	}
+
+	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));
+
+	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));
+
+	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));
+
+	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));
+	}
+
+	widget = glade_xml_get_widget (xml, "ppp_auth_methods");
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+	valid = gtk_tree_model_get_iter_first (model, &iter);
+	while (valid) {
+		gboolean allowed;
+		guint32 tag;
+
+		gtk_tree_model_get (model, &iter, COL_VALUE, &allowed, COL_TAG, &tag, -1);
+		switch (tag) {
+		case TAG_PAP:
+			if (!allowed)
+				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_PAP), bool_to_gvalue (TRUE));
+			break;
+		case TAG_CHAP:
+			if (!allowed)
+				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_CHAP), bool_to_gvalue (TRUE));
+			break;
+		case TAG_MSCHAP:
+			if (!allowed)
+				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_MSCHAP), bool_to_gvalue (TRUE));
+			break;
+		case TAG_MSCHAPV2:
+			if (!allowed)
+				g_hash_table_insert (hash, g_strdup (NM_PPTP_KEY_REFUSE_MSCHAPV2), bool_to_gvalue (TRUE));
+			break;
+		default:
+			break;
+		}
+
+		valid = gtk_tree_model_iter_next (model, &iter);
+	}
+
+	return hash;
+}
+

Added: trunk/vpn-daemons/pptp/properties/advanced-dialog.h
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/properties/advanced-dialog.h	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,37 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/***************************************************************************
+ *
+ * Copyright (C) 2008 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ **************************************************************************/
+
+#ifndef _AUTH_HELPERS_H_
+#define _AUTH_HELPERS_H_
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkwidget.h>
+
+#include <nm-connection.h>
+
+GtkWidget *advanced_dialog_new (GHashTable *hash);
+
+GHashTable *advanced_dialog_new_hash_from_connection (NMConnection *connection, GError **error);
+
+GHashTable *advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error);
+
+#endif

Added: trunk/vpn-daemons/pptp/properties/import-export.c
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/properties/import-export.c	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/***************************************************************************
+ *
+ * Copyright (C) 2008 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <ctype.h>
+
+#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>
+
+#include "import-export.h"
+#include "nm-pptp.h"
+#include "../src/nm-pptp-service.h"
+
+NMConnection *
+do_import (const char *path, char **lines, GError **error)
+{
+	NMConnection *connection = NULL;
+	NMSettingConnection *s_con;
+	NMSettingVPN *s_vpn;
+	NMSettingVPNProperties *s_vpn_props;
+	char *last_dot;
+
+	connection = nm_connection_new ();
+	s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+	nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+	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 ());
+	nm_connection_add_setting (connection, NM_SETTING (s_vpn_props));
+
+	s_con->id = g_path_get_basename (path);
+	last_dot = strrchr (s_con->id, '.');
+	if (last_dot)
+		*last_dot = '\0';
+
+	return connection;
+}
+
+gboolean
+do_export (const char *path, NMConnection *connection, GError **error)
+{
+	return FALSE;
+}
+
+
+

Added: trunk/vpn-daemons/pptp/properties/import-export.h
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/properties/import-export.h	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/***************************************************************************
+ *
+ * Copyright (C) 2008 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ **************************************************************************/
+
+#ifndef _IMPORT_EXPORT_H_
+#define _IMPORT_EXPORT_H_
+
+#include <glib.h>
+#include <nm-connection.h>
+
+NMConnection *do_import (const char *path, char **lines, GError **error);
+
+gboolean do_export (const char *path, NMConnection *connection, GError **error);
+
+#endif

Added: trunk/vpn-daemons/pptp/properties/nm-pptp-dialog.glade
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/properties/nm-pptp-dialog.glade	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,538 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
+<glade-interface>
+  <widget class="GtkWindow" id="pptp-widget">
+    <property name="title" translatable="yes">window1</property>
+    <child>
+      <widget class="GtkVBox" id="pptp-vbox">
+        <property name="visible">True</property>
+        <property name="border_width">12</property>
+        <property name="spacing">16</property>
+        <child>
+          <widget class="GtkVBox" id="vbox8">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkLabel" id="label22">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;General&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkAlignment" id="alignment8">
+                <property name="visible">True</property>
+                <property name="left_padding">12</property>
+                <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="row_spacing">6</property>
+                    <child>
+                      <widget class="GtkLabel" id="label23">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">_Gateway:</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">gateway_entry</property>
+                      </widget>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkEntry" id="gateway_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="y_options"></property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkVBox" id="vbox11">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkLabel" id="label25">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Optional&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkAlignment" id="alignment9">
+                <property name="visible">True</property>
+                <property name="left_padding">12</property>
+                <child>
+                  <widget class="GtkTable" id="table3">
+                    <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="row_spacing">6</property>
+                    <child>
+                      <widget class="GtkLabel" id="label26">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">User name:</property>
+                      </widget>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <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="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label27">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Domain:</property>
+                      </widget>
+                      <packing>
+                        <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">
+                        <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>
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkAlignment" id="alignment1">
+            <property name="visible">True</property>
+            <property name="xalign">1</property>
+            <property name="xscale">0</property>
+            <child>
+              <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">
+                    <property name="visible">True</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <widget class="GtkImage" id="image1">
+                        <property name="visible">True</property>
+                        <property name="stock">gtk-preferences</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label1">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Ad_vanced...</property>
+                        <property name="use_markup">True</property>
+                        <property name="use_underline">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+  <widget class="GtkDialog" id="pptp-advanced-dialog">
+    <property name="border_width">5</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="icon_name">stock-preferences</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="skip_pager_hint">True</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox3">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="PppPage">
+            <property name="visible">True</property>
+            <property name="border_width">12</property>
+            <property name="spacing">16</property>
+            <child>
+              <widget class="GtkVBox" id="vbox2">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label28">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Authentication&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkAlignment" id="alignment2">
+                    <property name="visible">True</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <widget class="GtkVBox" id="vbox4">
+                        <property name="visible">True</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <widget class="GtkLabel" id="auth_methods_label">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Allow the following authentication methods:</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkScrolledWindow" id="scrolledwindow1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+                            <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                            <property name="shadow_type">GTK_SHADOW_IN</property>
+                            <child>
+                              <widget class="GtkTreeView" id="ppp_auth_methods">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="headers_visible">False</property>
+                              </widget>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </widget>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox5">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label29">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Security and Compression&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkAlignment" id="alignment3">
+                    <property name="visible">True</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <widget class="GtkVBox" id="vbox6">
+                        <property name="visible">True</property>
+                        <child>
+                          <widget class="GtkVBox" id="vbox7">
+                            <property name="visible">True</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="use_underline">True</property>
+                                <property name="response_id">0</property>
+                                <property name="draw_indicator">True</property>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkAlignment" id="alignment4">
+                                <property name="visible">True</property>
+                                <property name="left_padding">12</property>
+                                <child>
+                                  <widget class="GtkVBox" id="vbox1">
+                                    <property name="visible">True</property>
+                                    <child>
+                                      <widget class="GtkHBox" id="hbox1">
+                                        <property name="visible">True</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>
+                                          </widget>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="padding">6</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <widget class="GtkComboBox" id="ppp_mppe_security_combo">
+                                            <property name="visible">True</property>
+                                            <property name="items" translatable="yes">Default</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </widget>
+                                    </child>
+                                    <child>
+                                      <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="use_underline">True</property>
+                                        <property name="response_id">0</property>
+                                        <property name="draw_indicator">True</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">False</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </widget>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <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="use_underline">True</property>
+                            <property name="response_id">0</property>
+                            <property name="draw_indicator">True</property>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <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="use_underline">True</property>
+                            <property name="response_id">0</property>
+                            <property name="draw_indicator">True</property>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <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="use_underline">True</property>
+                            <property name="response_id">0</property>
+                            <property name="draw_indicator">True</property>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">3</property>
+                          </packing>
+                        </child>
+                      </widget>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox9">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label31">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Echo&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkAlignment" id="alignment5">
+                    <property name="visible">True</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <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="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                      </widget>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area3">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <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="use_stock">True</property>
+                <property name="response_id">-6</property>
+              </widget>
+            </child>
+            <child>
+              <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="use_stock">True</property>
+                <property name="response_id">-5</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

Added: trunk/vpn-daemons/pptp/properties/nm-pptp.c
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/properties/nm-pptp.c	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,654 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/***************************************************************************
+ * nm-pptp.c : GNOME UI dialogs for configuring PPTP VPN connections
+ *
+ * Copyright (C) 2008 Dan Williams, <dcbw redhat com>
+ * Based on work by 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+#define NM_VPN_API_SUBJECT_TO_CHANGE
+
+#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>
+
+#include "../src/nm-pptp-service.h"
+#include "nm-pptp.h"
+#include "import-export.h"
+#include "advanced-dialog.h"
+
+#define PPTP_PLUGIN_NAME    _("Point-to-Point Tunneling Protocol (PPTP)")
+#define PPTP_PLUGIN_DESC    _("Compatible with Microsoft and other PPTP VPN servers.")
+#define PPTP_PLUGIN_SERVICE NM_DBUS_SERVICE_PPTP
+
+
+/************** plugin class **************/
+
+static void pptp_plugin_ui_interface_init (NMVpnPluginUiInterface *iface_class);
+
+G_DEFINE_TYPE_EXTENDED (PptpPluginUi, pptp_plugin_ui, G_TYPE_OBJECT, 0,
+						G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_PLUGIN_UI_INTERFACE,
+											   pptp_plugin_ui_interface_init))
+
+/************** UI widget class **************/
+
+static void pptp_plugin_ui_widget_interface_init (NMVpnPluginUiWidgetInterface *iface_class);
+
+G_DEFINE_TYPE_EXTENDED (PptpPluginUiWidget, pptp_plugin_ui_widget, G_TYPE_OBJECT, 0,
+						G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_PLUGIN_UI_WIDGET_INTERFACE,
+											   pptp_plugin_ui_widget_interface_init))
+
+#define PPTP_PLUGIN_UI_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PPTP_TYPE_PLUGIN_UI_WIDGET, PptpPluginUiWidgetPrivate))
+
+typedef struct {
+	GladeXML *xml;
+	GtkWidget *widget;
+	GtkSizeGroup *group;
+	GtkWindowGroup *window_group;
+	gboolean window_added;
+	GHashTable *advanced;
+} PptpPluginUiWidgetPrivate;
+
+
+GQuark
+pptp_plugin_ui_error_quark (void)
+{
+	static GQuark error_quark = 0;
+
+	if (G_UNLIKELY (error_quark == 0))
+		error_quark = g_quark_from_static_string ("pptp-plugin-ui-error-quark");
+
+	return error_quark;
+}
+
+/* This should really be standard. */
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+GType
+pptp_plugin_ui_error_get_type (void)
+{
+	static GType etype = 0;
+
+	if (etype == 0) {
+		static const GEnumValue values[] = {
+			/* Unknown error. */
+			ENUM_ENTRY (PPTP_PLUGIN_UI_ERROR_UNKNOWN, "UnknownError"),
+			/* The specified property was invalid. */
+			ENUM_ENTRY (PPTP_PLUGIN_UI_ERROR_INVALID_PROPERTY, "InvalidProperty"),
+			/* The specified property was missing and is required. */
+			ENUM_ENTRY (PPTP_PLUGIN_UI_ERROR_MISSING_PROPERTY, "MissingProperty"),
+			/* The file to import could not be read. */
+			ENUM_ENTRY (PPTP_PLUGIN_UI_ERROR_FILE_NOT_READABLE, "FileNotReadable"),
+			/* The file to import could was not an PPTP client file. */
+			ENUM_ENTRY (PPTP_PLUGIN_UI_ERROR_FILE_NOT_PPTP, "FileNotPPTP"),
+			{ 0, 0, 0 }
+		};
+		etype = g_enum_register_static ("PptpPluginUiError", values);
+	}
+	return etype;
+}
+
+static gboolean
+check_validity (PptpPluginUiWidget *self, GError **error)
+{
+	PptpPluginUiWidgetPrivate *priv = PPTP_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
+	GtkWidget *widget;
+	const char *str;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	widget = glade_xml_get_widget (priv->xml, "gateway_entry");
+	str = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (!str || !strlen (str)) {
+		g_set_error (error,
+		             PPTP_PLUGIN_UI_ERROR,
+		             PPTP_PLUGIN_UI_ERROR_INVALID_PROPERTY,
+		             NM_PPTP_KEY_GATEWAY);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void
+stuff_changed_cb (GtkWidget *widget, gpointer user_data)
+{
+	g_signal_emit_by_name (PPTP_PLUGIN_UI_WIDGET (user_data), "changed");
+}
+
+static void
+advanced_dialog_close_cb (GtkWidget *dialog, gpointer user_data)
+{
+	PptpPluginUiWidget *self = PPTP_PLUGIN_UI_WIDGET (user_data);
+
+	gtk_widget_hide (dialog);
+	/* gtk_widget_destroy() will remove the window from the window group */
+	gtk_widget_destroy (dialog);
+}
+
+static void
+advanced_dialog_response_cb (GtkWidget *dialog, gint response, gpointer user_data)
+{
+	PptpPluginUiWidget *self = PPTP_PLUGIN_UI_WIDGET (user_data);
+	PptpPluginUiWidgetPrivate *priv = PPTP_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
+	GError *error = NULL;
+
+	if (response != GTK_RESPONSE_OK) {
+		advanced_dialog_close_cb (dialog, self);
+		return;
+	}
+
+	if (priv->advanced)
+		g_hash_table_destroy (priv->advanced);
+	priv->advanced = advanced_dialog_new_hash_from_dialog (dialog, &error);
+	if (!priv->advanced) {
+		g_message ("%s: error reading advanced settings: %s", __func__, error->message);
+		g_error_free (error);
+	}
+	advanced_dialog_close_cb (dialog, self);
+
+	stuff_changed_cb (NULL, self);
+}
+
+static void
+advanced_button_clicked_cb (GtkWidget *button, gpointer user_data)
+{
+	PptpPluginUiWidget *self = PPTP_PLUGIN_UI_WIDGET (user_data);
+	PptpPluginUiWidgetPrivate *priv = PPTP_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
+	GtkWidget *dialog, *toplevel, *widget;
+
+	toplevel = gtk_widget_get_toplevel (priv->widget);
+	g_return_if_fail (GTK_WIDGET_TOPLEVEL (toplevel));
+
+	dialog = advanced_dialog_new (priv->advanced);
+	if (!dialog) {
+		g_warning ("%s: failed to create the Advanced dialog!", __func__);
+		return;
+	}
+
+	gtk_window_group_add_window (priv->window_group, GTK_WINDOW (dialog));
+	if (!priv->window_added) {
+		gtk_window_group_add_window (priv->window_group, GTK_WINDOW (toplevel));
+		priv->window_added = TRUE;
+	}
+
+	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel));
+	g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (advanced_dialog_response_cb), self);
+	g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (advanced_dialog_close_cb), self);
+
+	gtk_widget_show_all (dialog);
+}
+
+static gboolean
+init_plugin_ui (PptpPluginUiWidget *self, NMConnection *connection, GError **error)
+{
+	PptpPluginUiWidgetPrivate *priv = PPTP_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
+	NMSettingVPNProperties *s_vpn_props;
+	GtkWidget *widget;
+	GtkListStore *store;
+	GtkTreeIter iter;
+	int active = -1;
+	GValue *value;
+
+	s_vpn_props = (NMSettingVPNProperties *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES);
+
+	priv->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+	widget = glade_xml_get_widget (priv->xml, "gateway_entry");
+	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));
+	}
+	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
+
+	widget = glade_xml_get_widget (priv->xml, "user_entry");
+	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));
+	}
+	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
+
+	widget = glade_xml_get_widget (priv->xml, "domain_entry");
+	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));
+	}
+	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
+
+	widget = glade_xml_get_widget (priv->xml, "advanced_button");
+	g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (advanced_button_clicked_cb), self);
+
+	return TRUE;
+}
+
+static GObject *
+get_widget (NMVpnPluginUiWidgetInterface *iface)
+{
+	PptpPluginUiWidget *self = PPTP_PLUGIN_UI_WIDGET (iface);
+	PptpPluginUiWidgetPrivate *priv = PPTP_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
+
+	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));
+	}
+}
+
+static gboolean
+update_connection (NMVpnPluginUiWidgetInterface *iface,
+                   NMConnection *connection,
+                   GError **error)
+{
+	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;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean valid = FALSE;
+
+	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_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));
+	}
+
+	/* 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));
+	}
+
+	/* 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));
+	}
+
+	if (priv->advanced)
+		g_hash_table_foreach (priv->advanced, hash_copy_advanced, s_vpn_props->data);
+
+	nm_connection_add_setting (connection, NM_SETTING (s_vpn_props));
+	valid = TRUE;
+
+done:
+	return valid;
+}
+
+static NMVpnPluginUiWidgetInterface *
+nm_vpn_plugin_ui_widget_interface_new (NMConnection *connection, GError **error)
+{
+	NMVpnPluginUiWidgetInterface *object;
+	PptpPluginUiWidgetPrivate *priv;
+	char *glade_file;
+
+	if (error)
+		g_return_val_if_fail (*error == NULL, NULL);
+
+	object = NM_VPN_PLUGIN_UI_WIDGET_INTERFACE (g_object_new (PPTP_TYPE_PLUGIN_UI_WIDGET, NULL));
+	if (!object) {
+		g_set_error (error, PPTP_PLUGIN_UI_ERROR, 0, "could not create pptp object");
+		return NULL;
+	}
+
+	priv = PPTP_PLUGIN_UI_WIDGET_GET_PRIVATE (object);
+
+	glade_file = g_strdup_printf ("%s/%s", GLADEDIR, "nm-pptp-dialog.glade");
+	priv->xml = glade_xml_new (glade_file, "pptp-vbox", GETTEXT_PACKAGE);
+	if (priv->xml == NULL) {
+		g_set_error (error, PPTP_PLUGIN_UI_ERROR, 0,
+		             "could not load required resources at %s", glade_file);
+		g_free (glade_file);
+		g_object_unref (object);
+		return NULL;
+	}
+	g_free (glade_file);
+
+	priv->widget = glade_xml_get_widget (priv->xml, "pptp-vbox");
+	if (!priv->widget) {
+		g_set_error (error, PPTP_PLUGIN_UI_ERROR, 0, "could not load UI widget");
+		g_object_unref (object);
+		return NULL;
+	}
+	g_object_ref_sink (priv->widget);
+
+	priv->window_group = gtk_window_group_new ();
+
+	if (!init_plugin_ui (PPTP_PLUGIN_UI_WIDGET (object), connection, error)) {
+		g_object_unref (object);
+		return NULL;
+	}
+
+	priv->advanced = advanced_dialog_new_hash_from_connection (connection, error);
+	if (!priv->advanced) {
+		g_object_unref (object);
+		return NULL;
+	}
+
+	return object;
+}
+
+static void
+dispose (GObject *object)
+{
+	PptpPluginUiWidget *plugin = PPTP_PLUGIN_UI_WIDGET (object);
+	PptpPluginUiWidgetPrivate *priv = PPTP_PLUGIN_UI_WIDGET_GET_PRIVATE (plugin);
+
+	if (priv->group)
+		g_object_unref (priv->group);
+
+	if (priv->window_group)
+		g_object_unref (priv->window_group);
+
+	if (priv->widget)
+		g_object_unref (priv->widget);
+
+	if (priv->xml)
+		g_object_unref (priv->xml);
+
+	if (priv->advanced)
+		g_hash_table_destroy (priv->advanced);
+
+	G_OBJECT_CLASS (pptp_plugin_ui_widget_parent_class)->dispose (object);
+}
+
+static void
+pptp_plugin_ui_widget_class_init (PptpPluginUiWidgetClass *req_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+
+	g_type_class_add_private (req_class, sizeof (PptpPluginUiWidgetPrivate));
+
+	object_class->dispose = dispose;
+}
+
+static void
+pptp_plugin_ui_widget_init (PptpPluginUiWidget *plugin)
+{
+}
+
+static void
+pptp_plugin_ui_widget_interface_init (NMVpnPluginUiWidgetInterface *iface_class)
+{
+	/* interface implementation */
+	iface_class->get_widget = get_widget;
+	iface_class->update_connection = update_connection;
+}
+
+static NMConnection *
+import (NMVpnPluginUiInterface *iface, const char *path, GError **error)
+{
+	NMConnection *connection = NULL;
+	char *contents = NULL;
+	char **lines = NULL;
+	char *ext;
+
+	ext = strrchr (path, '.');
+	if (!ext) {
+		g_set_error (error,
+		             PPTP_PLUGIN_UI_ERROR,
+		             PPTP_PLUGIN_UI_ERROR_FILE_NOT_PPTP,
+		             "unknown PPTP file extension");
+		goto out;
+	}
+
+	if (strcmp (ext, ".conf") && strcmp (ext, ".cnf")) {
+		g_set_error (error,
+		             PPTP_PLUGIN_UI_ERROR,
+		             PPTP_PLUGIN_UI_ERROR_FILE_NOT_PPTP,
+		             "unknown PPTP file extension");
+		goto out;
+	}
+
+	if (!g_file_get_contents (path, &contents, NULL, error))
+		return NULL;
+
+	lines = g_strsplit_set (contents, "\r\n", 0);
+	if (g_strv_length (lines) <= 1) {
+		g_set_error (error,
+		             PPTP_PLUGIN_UI_ERROR,
+		             PPTP_PLUGIN_UI_ERROR_FILE_NOT_READABLE,
+		             "not a valid PPTP configuration file");
+		goto out;
+	}
+
+	connection = do_import (path, lines, error);
+
+out:
+	if (lines)
+		g_strfreev (lines);
+	g_free (contents);
+	return connection;
+}
+
+static gboolean
+export (NMVpnPluginUiInterface *iface,
+        const char *path,
+        NMConnection *connection,
+        GError **error)
+{
+	return do_export (path, connection, error);
+}
+
+static char *
+get_suggested_name (NMVpnPluginUiInterface *iface, NMConnection *connection)
+{
+	NMSettingConnection *s_con;
+
+	g_return_val_if_fail (connection != NULL, NULL);
+
+	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	g_return_val_if_fail (s_con != NULL, NULL);
+	g_return_val_if_fail (s_con->id != NULL, NULL);
+
+	return g_strdup_printf ("%s (pptp).conf", s_con->id);
+}
+
+static guint32
+get_capabilities (NMVpnPluginUiInterface *iface)
+{
+	return (NM_VPN_PLUGIN_UI_CAPABILITY_IMPORT | NM_VPN_PLUGIN_UI_CAPABILITY_EXPORT);
+}
+
+static NMVpnPluginUiWidgetInterface *
+ui_factory (NMVpnPluginUiInterface *iface, NMConnection *connection, GError **error)
+{
+	return nm_vpn_plugin_ui_widget_interface_new (connection, error);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+			  GValue *value, GParamSpec *pspec)
+{
+	switch (prop_id) {
+	case NM_VPN_PLUGIN_UI_INTERFACE_PROP_NAME:
+		g_value_set_string (value, PPTP_PLUGIN_NAME);
+		break;
+	case NM_VPN_PLUGIN_UI_INTERFACE_PROP_DESC:
+		g_value_set_string (value, PPTP_PLUGIN_DESC);
+		break;
+	case NM_VPN_PLUGIN_UI_INTERFACE_PROP_SERVICE:
+		g_value_set_string (value, PPTP_PLUGIN_SERVICE);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+pptp_plugin_ui_class_init (PptpPluginUiClass *req_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+
+	object_class->get_property = get_property;
+
+	g_object_class_override_property (object_class,
+									  NM_VPN_PLUGIN_UI_INTERFACE_PROP_NAME,
+									  NM_VPN_PLUGIN_UI_INTERFACE_NAME);
+
+	g_object_class_override_property (object_class,
+									  NM_VPN_PLUGIN_UI_INTERFACE_PROP_DESC,
+									  NM_VPN_PLUGIN_UI_INTERFACE_DESC);
+
+	g_object_class_override_property (object_class,
+									  NM_VPN_PLUGIN_UI_INTERFACE_PROP_SERVICE,
+									  NM_VPN_PLUGIN_UI_INTERFACE_SERVICE);
+}
+
+static void
+pptp_plugin_ui_init (PptpPluginUi *plugin)
+{
+}
+
+static void
+pptp_plugin_ui_interface_init (NMVpnPluginUiInterface *iface_class)
+{
+	/* interface implementation */
+	iface_class->ui_factory = ui_factory;
+	iface_class->get_capabilities = get_capabilities;
+	iface_class->import = import;
+	iface_class->export = export;
+	iface_class->get_suggested_name = get_suggested_name;
+}
+
+
+G_MODULE_EXPORT NMVpnPluginUiInterface *
+nm_vpn_plugin_ui_factory (GError **error)
+{
+	if (error)
+		g_return_val_if_fail (*error == NULL, NULL);
+
+	return NM_VPN_PLUGIN_UI_INTERFACE (g_object_new (PPTP_TYPE_PLUGIN_UI, NULL));
+}
+

Added: trunk/vpn-daemons/pptp/properties/nm-pptp.h
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/properties/nm-pptp.h	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,94 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/***************************************************************************
+ * nm-pptp.h : GNOME UI dialogs for configuring pptp VPN connections
+ *
+ * Copyright (C) 2008 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ **************************************************************************/
+
+#ifndef _NM_PPTP_H_
+#define _NM_PPTP_H_
+
+#include <glib-object.h>
+
+typedef enum
+{
+	PPTP_PLUGIN_UI_ERROR_UNKNOWN = 0,
+	PPTP_PLUGIN_UI_ERROR_INVALID_PROPERTY,
+	PPTP_PLUGIN_UI_ERROR_MISSING_PROPERTY,
+	PPTP_PLUGIN_UI_ERROR_FILE_NOT_READABLE,
+	PPTP_PLUGIN_UI_ERROR_FILE_NOT_PPTP
+} PptpPluginUiError;
+
+#define PPTP_TYPE_PLUGIN_UI_ERROR (pptp_plugin_ui_error_get_type ()) 
+GType pptp_plugin_ui_error_get_type (void);
+
+#define PPTP_PLUGIN_UI_ERROR (pptp_plugin_ui_error_quark ())
+GQuark pptp_plugin_ui_error_quark (void);
+
+
+#define PPTP_TYPE_PLUGIN_UI            (pptp_plugin_ui_get_type ())
+#define PPTP_PLUGIN_UI(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PPTP_TYPE_PLUGIN_UI, PptpPluginUi))
+#define PPTP_PLUGIN_UI_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PPTP_TYPE_PLUGIN_UI, PptpPluginUiClass))
+#define PPTP_IS_PLUGIN_UI(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PPTP_TYPE_PLUGIN_UI))
+#define PPTP_IS_PLUGIN_UI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), PPTP_TYPE_PLUGIN_UI))
+#define PPTP_PLUGIN_UI_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), PPTP_TYPE_PLUGIN_UI, PptpPluginUiClass))
+
+typedef struct _PptpPluginUi PptpPluginUi;
+typedef struct _PptpPluginUiClass PptpPluginUiClass;
+
+struct _PptpPluginUi {
+	GObject parent;
+};
+
+struct _PptpPluginUiClass {
+	GObjectClass parent;
+};
+
+GType pptp_plugin_ui_get_type (void);
+
+
+#define PPTP_TYPE_PLUGIN_UI_WIDGET            (pptp_plugin_ui_widget_get_type ())
+#define PPTP_PLUGIN_UI_WIDGET(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PPTP_TYPE_PLUGIN_UI_WIDGET, PptpPluginUiWidget))
+#define PPTP_PLUGIN_UI_WIDGET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PPTP_TYPE_PLUGIN_UI_WIDGET, PptpPluginUiWidgetClass))
+#define PPTP_IS_PLUGIN_UI_WIDGET(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PPTP_TYPE_PLUGIN_UI_WIDGET))
+#define PPTP_IS_PLUGIN_UI_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), PPTP_TYPE_PLUGIN_UI_WIDGET))
+#define PPTP_PLUGIN_UI_WIDGET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), PPTP_TYPE_PLUGIN_UI_WIDGET, PptpPluginUiWidgetClass))
+
+typedef struct _PptpPluginUiWidget PptpPluginUiWidget;
+typedef struct _PptpPluginUiWidgetClass PptpPluginUiWidgetClass;
+
+struct _PptpPluginUiWidget {
+	GObject parent;
+};
+
+struct _PptpPluginUiWidgetClass {
+	GObjectClass parent;
+};
+
+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: trunk/vpn-daemons/pptp/src/Makefile.am
==============================================================================
--- trunk/vpn-daemons/pptp/src/Makefile.am	(original)
+++ trunk/vpn-daemons/pptp/src/Makefile.am	Sun Jul 20 22:45:51 2008
@@ -1,13 +1,9 @@
-INCLUDES = -I${top_srcdir}                  \
-           -I${top_srcdir}/utils            \
-           -I${top_srcdir}/vpn-daemons/pptp
+INCLUDES = -I${top_srcdir}
 
 AM_CPPFLAGS =							\
-	$(DBUS_CFLAGS)						\
+	$(DBUS_GLIB_CFLAGS)						\
 	$(GTHREAD_CFLAGS)					\
-	$(NETWORK_MANAGER_CFLAGS)				\
-	$(PPPD_CFLAGS)						\
-	$(NM_VPN_CFLAGS)					\
+	$(NM_UTILS_CFLAGS)				\
 	-Wall							\
 	-DDBUS_API_SUBJECT_TO_CHANGE				\
 	-DG_DISABLE_DEPRECATED					\
@@ -19,45 +15,42 @@
 	-DLIBEXECDIR=\""$(libexecdir)"\"			\
 	-DLOCALSTATEDIR=\""$(localstatedir)"\"		 	\
 	-DDATADIR=\"$(datadir)\"				\
+	-DPLUGINDIR=\"$(PPPD_PLUGIN_DIR)\" \
 	-fPIC
 
-bin_PROGRAMS = nm-ppp-starter
+bin_PROGRAMS = nm-pptp-service
 
-pppdplugindir = $(libexecdir)/pppd/$(PPPD_VERSION)
-pppdplugin_LTLIBRARIES = nm-pppd-plugin.la
+nm_pptp_service_SOURCES = \
+				nm-pptp-service.c \
+				nm-pptp-service.h
 
-nm_ppp_starter_SOURCES =			\
-				nm-ppp-starter.c	\
-				nm-ppp-starter.h	\
-				nm-utils.c			\
-				nm-utils.h			\
-				external/2.4.3/pppd/patchlevel.h \
-				external/2.4.3/pppd/ipcp.h \
-				external/2.4.3/pppd/pppd.h \
-				external/2.4.3/pppd/fsm.h \
-				external/2.4.4/pppd/patchlevel.h \
-				external/2.4.4/pppd/ipcp.h \
-				external/2.4.4/pppd/pppd.h \
-				external/2.4.4/pppd/fsm.h \
-				external/2.4.4b1/pppd/patchlevel.h \
-				external/2.4.4b1/pppd/ipcp.h \
-				external/2.4.4b1/pppd/pppd.h \
-				external/2.4.4b1/pppd/fsm.h
+nm-pptp-pppd-service-glue.h: $(top_srcdir)/src/nm-pptp-pppd-service.xml
+	dbus-binding-tool --prefix=nm_pptp_pppd_service --mode=glib-server --output=$@ $<
 
-nm_ppp_starter_LDADD = 				\
-				$(DBUS_LIBS)		\
+nm_pptp_service_LDADD = 				\
+				$(DBUS_GLIB_LIBS)		\
 				$(GTHREAD_LIBS)		\
-				$(NETWORK_MANAGER_LIBS)
+				$(NM_UTILS_LIBS)
 
-nm_pppd_plugin_la_SOURCES = 		\
-				nm-pppd-plugin.c 	\
-				nm-pppd-plugin.h  	\
-				nm-ppp-starter.h
+pppd_plugindir = $(PPPD_PLUGIN_DIR)
+pppd_plugin_LTLIBRARIES = nm-pptp-pppd-plugin.la
 
-nm_pppd_plugin_la_LDFLAGS = -module
+nm_pptp_pppd_plugin_la_SOURCES = \
+	nm-pptp-pppd-plugin.c \
+	nm-ppp-status.h
 
-nm_pppd_plugin_la_LIBADD = 		\
-				$(DBUS_LIBS)	\
-				$(GTHREAD_LIBS)
+nm_pptp_pppd_plugin_la_CPPFLAGS = \
+	$(DBUS_GLIB_CFLAGS) \
+	$(GLIB_CFLAGS) \
+	$(NM_UTILS_CFLAGS)
 
-CLEANFILES = *~
+nm_pptp_pppd_plugin_la_LDFLAGS = -module -avoid-version
+
+nm_pptp_pppd_plugin_la_LIBADD = \
+	$(DBUS_GLIB_LIBS) \
+	$(GLIB_LIBS) \
+	$(NM_UTILS_LIBS)
+
+BUILT_SOURCES = nm-pptp-pppd-service-glue.h
+
+CLEANFILES = $(BUILT_SOURCES)

Added: trunk/vpn-daemons/pptp/src/nm-ppp-status.h
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/src/nm-ppp-status.h	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,22 @@
+#ifndef NM_PPP_STATUS_H
+#define NM_PPP_STATUS_H
+
+typedef enum {
+	NM_PPP_STATUS_UNKNOWN,
+
+	NM_PPP_STATUS_DEAD,
+	NM_PPP_STATUS_INITIALIZE,
+	NM_PPP_STATUS_SERIALCONN,
+	NM_PPP_STATUS_DORMANT,
+	NM_PPP_STATUS_ESTABLISH,
+	NM_PPP_STATUS_AUTHENTICATE,
+	NM_PPP_STATUS_CALLBACK,
+	NM_PPP_STATUS_NETWORK,
+	NM_PPP_STATUS_RUNNING,
+	NM_PPP_STATUS_TERMINATE,
+	NM_PPP_STATUS_DISCONNECT,
+	NM_PPP_STATUS_HOLDOFF,
+	NM_PPP_STATUS_MASTER
+} NMPPPStatus;
+
+#endif /* NM_PPP_STATUS_H */

Copied: trunk/vpn-daemons/pptp/src/nm-pptp-pppd-plugin.c (from r3830, /trunk/vpn-daemons/pptp/src/nm-pppd-plugin.c)
==============================================================================
--- /trunk/vpn-daemons/pptp/src/nm-pppd-plugin.c	(original)
+++ trunk/vpn-daemons/pptp/src/nm-pptp-pppd-plugin.c	Sun Jul 20 22:45:51 2008
@@ -1,6 +1,8 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /* nm-pptp-service - pptp (and other pppd) integration with NetworkManager
  *
- * Antony J Mee <eemynotna at gmail dot com>
+ * (C) 2007 - 2008 Novell, Inc.
+ * (C) 2008 Red Hat, Inc.
  *
  * 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
@@ -16,492 +18,307 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ * 
  */
 
-#include "pppd/pppd.h"
-
-#include "pppd/fsm.h"
-#include "pppd/ipcp.h"
-#ifndef PPPD_VERSION
-  #ifdef VERSION
-    #define PPPD_VERSION VERSION
-  #endif
-#endif
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <glib.h>
-#include <stdlib.h>
-#include <stdio.h>
 #include <string.h>
-#include <regex.h>
+#include <pppd/pppd.h>
+#include <pppd/fsm.h>
+#include <pppd/ipcp.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
+#include <glib/gtypes.h>
+#include <glib-object.h>
 #include <dbus/dbus-glib.h>
-#include <NetworkManager.h>
 
-#include "nm-ppp-starter.h"
-#include "nm-pppd-plugin.h"
-#include "nm-utils.h"
+#include "nm-pptp-service.h"
+#include "nm-ppp-status.h"
 
-typedef struct NmPPPData
-{
-  DBusConnection	*con;
-  gboolean          got_auth_info;
-  char              *auth_type;
-  char              *username;
-  char              *password;
-  int               pppd_pid;
-} NmPPPData;
-
-char pppd_version[] = PPPD_VERSION;
-
-NmPPPData plugin_data;
-
-int plugin_init();
-
-void nm_ip_up(void *opaque, int arg);
-void nm_ip_down(void *opaque, int arg);
-void nm_exit_notify(void *opaque, int arg);
-
-int nm_chap_passwd_hook(char *user, char *passwd);
-int nm_chap_check_hook(void);
-
-void nm_notify_pid (NmPPPData *data);
-void send_config_error (DBusConnection *con, const char *item);
-gboolean nm_get_auth_items (NmPPPData *data);
-gboolean nm_store_auth_info (NmPPPData *data, char **auth_items, int num_auth_items);
-gboolean nm_dbus_prepare_connection(NmPPPData *data);
-void nm_dbus_kill_connection(NmPPPData *data);
+#include <nm-utils.h>
 
-gboolean nm_dbus_prepare_connection(NmPPPData *data)
-{
-//    DBusMessage *	message = NULL;
-    DBusError		error;
-//    DBusObjectPathVTable	 vtable = { NULL, 
-//                                        &nm_dbus_message_handler, 
-//                                        NULL, NULL, NULL, NULL };
-
-    g_return_val_if_fail (data != NULL, FALSE);
-    if (data->con != NULL) return TRUE;
-
-
-    dbus_error_init (&error);
-    data->con = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-    if ((data->con == NULL) || dbus_error_is_set (&error))
-      {
-        info("Could not get the system bus.  Make sure the message bus daemon is running?");
-        goto out;
-      }
-    dbus_connection_set_exit_on_disconnect (data->con, FALSE);
-
-//    dbus_error_init (&error);
-//    dbus_bus_request_name (data->con, NM_DBUS_SERVICE_PPP, 0, &error);
-//    if (dbus_error_is_set (&error))
-//      {
-//        nm_warning ("Could not acquire the dbus service.  dbus_bus_request_name() says: '%s'", error.message);
-//        goto out;
-//      }
-    
-//    if (!dbus_connection_register_object_path (data->con, NM_DBUS_PATH_PPP, &vtable, data))
-//      {
-//        nm_warning ("Could not register a dbus handler for nm-ppp-service.  Not enough memory?");
-//        dbus_connection_unref(data->con);
-//        data->con = NULL;
-//      }
-out:
-    if (dbus_error_is_set (&error))
-      {
-        dbus_error_free (&error);
-        data->con = NULL;
-      }
-    if (data->con == NULL) return FALSE;
-    return TRUE;
-}
+int plugin_init (void);
 
-void nm_dbus_kill_connection(NmPPPData *data)
-{
-    g_return_if_fail (data != NULL);
+char pppd_version[] = VERSION;
 
-    if (data->con != NULL)
-      dbus_connection_unref(data->con);
-    if (data->username!=NULL) g_free(data->username);
-    if (data->password!=NULL) g_free(data->password);
-}
+static DBusGProxy *proxy = NULL;
+
+static void
+nm_phasechange (void *data, int arg)
+{
+	NMPPPStatus ppp_status = NM_PPP_STATUS_UNKNOWN;
+	char *ppp_phase;
+
+	g_return_if_fail (DBUS_IS_G_PROXY (proxy));
+
+	switch (arg) {
+	case PHASE_DEAD:
+		ppp_status = NM_PPP_STATUS_DEAD;
+		ppp_phase = "dead";
+		break;
+	case PHASE_INITIALIZE:
+		ppp_status = NM_PPP_STATUS_INITIALIZE;
+		ppp_phase = "initialize";
+		break;
+	case PHASE_SERIALCONN:
+		ppp_status = NM_PPP_STATUS_SERIALCONN;
+		ppp_phase = "serial connection";
+		break;
+	case PHASE_DORMANT:
+		ppp_status = NM_PPP_STATUS_DORMANT;
+		ppp_phase = "dormant";
+		break;
+	case PHASE_ESTABLISH:
+		ppp_status = NM_PPP_STATUS_ESTABLISH;
+		ppp_phase = "establish";
+		break;
+	case PHASE_AUTHENTICATE:
+		ppp_status = NM_PPP_STATUS_AUTHENTICATE;
+		ppp_phase = "authenticate";
+		break;
+	case PHASE_CALLBACK:
+		ppp_status = NM_PPP_STATUS_CALLBACK;
+		ppp_phase = "callback";
+		break;
+	case PHASE_NETWORK:
+		ppp_status = NM_PPP_STATUS_NETWORK;
+		ppp_phase = "network";
+		break;
+	case PHASE_RUNNING:
+		ppp_status = NM_PPP_STATUS_RUNNING;
+		ppp_phase = "running";
+		break;
+	case PHASE_TERMINATE:
+		ppp_status = NM_PPP_STATUS_TERMINATE;
+		ppp_phase = "terminate";
+		break;
+	case PHASE_DISCONNECT:
+		ppp_status = NM_PPP_STATUS_DISCONNECT;
+		ppp_phase = "disconnect";
+		break;
+	case PHASE_HOLDOFF:
+		ppp_status = NM_PPP_STATUS_HOLDOFF;
+		ppp_phase = "holdoff";
+		break;
+	case PHASE_MASTER:
+		ppp_status = NM_PPP_STATUS_MASTER;
+		ppp_phase = "master";
+		break;
+
+	default:
+		ppp_phase = "unknown";
+		break;
+	}
+
+	if (ppp_status != NM_PPP_STATUS_UNKNOWN) {
+		dbus_g_proxy_call_no_reply (proxy, "SetState",
+							   G_TYPE_UINT, ppp_status,
+							   G_TYPE_INVALID,
+							   G_TYPE_INVALID);
+	}
+}
+
+static GValue *
+str_to_gvalue (const char *str)
+{
+	GValue *val;
+
+	val = g_slice_new0 (GValue);
+	g_value_init (val, G_TYPE_STRING);
+	g_value_set_string (val, str);
+
+	return val;
+}
+
+static GValue *
+uint_to_gvalue (guint32 i)
+{
+	GValue *val;
+
+	val = g_slice_new0 (GValue);
+	g_value_init (val, G_TYPE_UINT);
+	g_value_set_uint (val, i);
+
+	return val;
+}
+
+static void
+value_destroy (gpointer data)
+{
+	GValue *val = (GValue *) data;
+
+	g_value_unset (val);
+	g_slice_free (GValue, val);
+}
+
+static void
+nm_ip_up (void *data, int arg)
+{
+	ipcp_options opts = ipcp_gotoptions[ifunit];
+	ipcp_options peer_opts = ipcp_hisoptions[ifunit];
+	GHashTable *hash;
+	GArray *array;
+	GValue *val;
+
+	g_return_if_fail (DBUS_IS_G_PROXY (proxy));
+
+	if (!opts.ouraddr) {
+		g_warning ("Didn't receive an internal IP from pppd");
+		return;
+	}
+
+	hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+							NULL, value_destroy);
+
+	g_hash_table_insert (hash, NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, 
+					 str_to_gvalue (ifname));
+
+	g_hash_table_insert (hash, NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, 
+					 uint_to_gvalue (opts.ouraddr));
+
+	g_hash_table_insert (hash, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, uint_to_gvalue (32));
+
+	if (opts.dnsaddr[0] || opts.dnsaddr[1]) {
+		array = g_array_new (FALSE, FALSE, sizeof (guint32));
+
+		if (opts.dnsaddr[0])
+			g_array_append_val (array, opts.dnsaddr[0]);
+		if (opts.dnsaddr[1])
+			g_array_append_val (array, opts.dnsaddr[1]);
+
+		val = g_slice_new0 (GValue);
+		g_value_init (val, DBUS_TYPE_G_UINT_ARRAY);
+		g_value_set_boxed (val, array);
 
-int nm_chap_check_hook(void)
-{
-    plugin_data.pppd_pid=getpid();
-    nm_notify_pid (&plugin_data);
+		g_hash_table_insert (hash, NM_VPN_PLUGIN_IP4_CONFIG_DNS, val);
+	}
 
-    if (! nm_get_auth_items (&plugin_data))
-      {
-        return 0;
-      }
-
-    if (strcmp("CHAP",plugin_data.auth_type)!=0)
-      {
-        info("nm-pppd-plugin: No CHAP authentication available!");
-        return 0;
-      }
-    
+/*
+	if (opts.winsaddr[0] || opts.winsaddr[1]) {
+		array = g_array_new (FALSE, FALSE, sizeof (guint32));
 
-    info("nm-pppd-plugin: CHAP check hook.");
-    return 1;
-}
+		if (opts.winsaddr[0])
+			g_array_append_val (array, opts.winsaddr[0]);
+		if (opts.winsaddr[1])
+			g_array_append_val (array, opts.winsaddr[1]);
+
+		val = g_slice_new0 (GValue);
+		g_value_init (val, DBUS_TYPE_G_UINT_ARRAY);
+		g_value_set_boxed (val, array);
 
-int nm_chap_passwd_hook(char *user, char *passwd)
-{
-    info("nm-pppd-plugin: CHAP credentials requested.");
+		g_hash_table_insert (hash, NM_VPN_PLUGIN_IP4_CONFIG_WINS, val);
+	}
+*/
 
-    if (user == NULL)
-      {
-        info("nm-pppd-plugin: pppd didn't provide username buffer");
-        return -1;
-      }
-
-    if (passwd == NULL)
-      {
-        info("nm-pppd-plugin: pppd didn't provide password buffer");
-        return -1;
-      }
-
-    if (plugin_data.username == NULL)
-      {
-        info("nm-pppd-plugin: CHAP username not set");
-        return -1;
-      }
-
-    if (plugin_data.password == NULL)
-      {
-        info("nm-pppd-plugin: CHAP password not set");
-        return -1;
-      }
-
-    if (strlen(plugin_data.username) >= MAXNAMELEN)
-      {
-        info("nm-pppd-plugin: CHAP username too long!");
-        return -1;
-      }
-
-    if (strlen(plugin_data.password) >= MAXSECRETLEN)
-      {
-        info("nm-pppd-plugin: CHAP password too long!");
-        return -1;
-      }
-
-    strcpy(user, plugin_data.username);
-    user[MAXNAMELEN-1]='\0';
-    strcpy(passwd, plugin_data.password);
-    passwd[MAXSECRETLEN-1]='\0';
-//    info("nm-pppd-plugin: CHAP authenticating as '%s' with '%s'",user,passwd);
-//
-// Forget the username and password?
-//
-//    if (plugin_data.username!=NULL) g_free(plugin_data.username);
-//    if (plugin_data.password!=NULL) g_free(plugin_data.password);
+	dbus_g_proxy_call_no_reply (proxy, "SetIp4Config",
+						   DBUS_TYPE_G_MAP_OF_VARIANT, hash, G_TYPE_INVALID,
+						   G_TYPE_INVALID);
 
-    return 0;
+	g_hash_table_destroy (hash);
 }
 
-void nm_exit_notify(void *opaque, int arg)
+static int
+get_chap_check()
 {
-  NmPPPData *data = (NmPPPData *)opaque;
-
-  nm_dbus_kill_connection(data);
+	return 1;
 }
 
-void nm_ip_down(void *opaque, int arg)
-{   
-//  DBusConnection *con = (DBusConnection *)opaque;
-
-  return;
+static int
+get_pap_check()
+{
+	return 1;
 }
 
-void nm_ip_up(void *opaque, int arg)
+static int
+get_credentials (char *username, char *password)
 {
-  NmPPPData *data = (NmPPPData *)opaque;
-  DBusConnection *con = data->con;
-  DBusMessage		*message;
-
-  char *		str_ifname        = NULL;
-//  guint32 *		uint_ip4_dns   = NULL;
-  guint32 		uint_ip4_dns1     = 0;
-  guint32 		uint_ip4_dns2     = 0;
-  guint32		uint_ip4_dns_len  = 0;
-//  guint32 *		uint_ip4_wins  = NULL;
-  guint32 		uint_ip4_wins1    = 0;
-  guint32 		uint_ip4_wins2    = 0;
-  guint32		uint_ip4_wins_len = 0;
-  guint32		uint_ip4_address  = 0;
-  guint32		uint_ip4_ptp_address  = 0;
-  guint32		uint_ip4_netmask  = 0xFFFFFFFF; /* Default mask of 255.255.255.255 */
-//  guint32 i=0;
-
- 
-  g_return_if_fail (con != NULL);
-  if (ipcp_gotoptions[ifunit].ouraddr==0) {
-    info ("nm-pppd-plugin: didn't receive an Internal IP4 Address from ppp.");
-    send_config_error (con, "IP4 Address");
-    return;
-  }
-  uint_ip4_address=ipcp_gotoptions[ifunit].ouraddr;
-  
-  if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE_PPP_STARTER, NM_DBUS_PATH_PPP_STARTER, NM_DBUS_INTERFACE_PPP_STARTER, "signalIP4Config")))
-    {
-      nm_warning ("send_config_error(): Couldn't allocate the dbus message");
-      return;
-    }
-
-  if (ipcp_gotoptions[ifunit].dnsaddr) {
-    if (ipcp_gotoptions[ifunit].dnsaddr[0]!=0) {
-      uint_ip4_dns_len++; 
-      uint_ip4_dns1=ipcp_gotoptions[ifunit].dnsaddr[0];
-      if (ipcp_gotoptions[ifunit].dnsaddr[1]!=0) {
-        uint_ip4_dns_len++;
-        uint_ip4_dns2=ipcp_gotoptions[ifunit].dnsaddr[1];
-      }  
-    }
-  }
-
-  if (ipcp_gotoptions[ifunit].winsaddr) {
-    if (ipcp_gotoptions[ifunit].winsaddr[0]!=0) {
-      uint_ip4_wins_len++; 
-      uint_ip4_wins1=ipcp_gotoptions[ifunit].winsaddr[0];
-      if (ipcp_gotoptions[ifunit].winsaddr[1]!=0) {
-        uint_ip4_wins_len++;
-        uint_ip4_wins2=ipcp_gotoptions[ifunit].winsaddr[1];
-      }
-    }
-  }
- 
-  if (ifname==NULL) {
-    info ("nm-pppd-plugin: didn't receive a tunnel device name.");
-    send_config_error (con, "IP4 Address");
-  }
-  str_ifname = g_strdup(ifname);
-
-  dbus_message_append_args (message, 
-			    DBUS_TYPE_STRING, &str_ifname,
-			    DBUS_TYPE_UINT32, &uint_ip4_address,
-			    DBUS_TYPE_UINT32, &uint_ip4_ptp_address,
-			    DBUS_TYPE_UINT32, &uint_ip4_netmask,
-// Array workaround
-                DBUS_TYPE_UINT32, &uint_ip4_dns1,
-			    DBUS_TYPE_UINT32, &uint_ip4_dns2,
-			    DBUS_TYPE_UINT32, &uint_ip4_dns_len,
-			    DBUS_TYPE_UINT32, &uint_ip4_wins1,
-			    DBUS_TYPE_UINT32, &uint_ip4_wins2,
-			    DBUS_TYPE_UINT32, &uint_ip4_wins_len, 
-			    DBUS_TYPE_INVALID);
-
-  if (!dbus_connection_send (con, message, NULL)) {
-    info ("nm_ip_up(): could not send dbus message");
-    dbus_message_unref (message);
-    g_free(str_ifname);
-    return;
-  }
-  
-  g_free(str_ifname);
-  dbus_message_unref (message);
-  return;
-}
+	char *my_username;
+	char *my_password;
+	size_t len;
+	GError *err = NULL;
 
+	if (username && !password) {
+		/* pppd is checking pap support; return 1 for supported */
+		return 1;
+	}
 
-/*
- * send_config_error
- *
- * Notify nm-ppp-starter of a config error from pppd.
- *
-*/
-void send_config_error (DBusConnection *con, const char *item)
-{
-  DBusMessage		*message;
+	g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), -1);
 
-  g_return_if_fail (con != NULL);
-  g_return_if_fail (item != NULL);
+	my_username = my_password = NULL;
+	dbus_g_proxy_call (proxy, "NeedSecrets", &err,
+				    G_TYPE_INVALID,
+				    G_TYPE_STRING, &my_username,
+				    G_TYPE_STRING, &my_password,
+				    G_TYPE_INVALID);
 
-  if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE_PPP_STARTER, NM_DBUS_PATH_PPP_STARTER, NM_DBUS_INTERFACE_PPP_STARTER, "signalConfigError")))
-    {
-      nm_warning ("send_config_error(): Couldn't allocate the dbus message");
-      return;
-    }
-
-  dbus_message_append_args (message, DBUS_TYPE_STRING, &item, DBUS_TYPE_INVALID);
-  if (!dbus_connection_send (con, message, NULL))
-    nm_warning ("send_config_error(): could not send dbus message");
-  
-  dbus_message_unref (message);
-}
+	if (err) {
+		g_warning ("Could not get secrets: %s", err->message);
+		g_error_free (err);
+		return -1;
+	}
 
+	if (my_username) {
+		len = strlen (my_username) + 1;
+		len = len < MAXNAMELEN ? len : MAXNAMELEN;
 
-/*
- * nm_notify_pid
- *
- * Let the pppd starter service know our PID
- * so that pppd may be killed later.
- *
- */
-void nm_notify_pid (NmPPPData *data)
-{
-  DBusConnection *con;
-  DBusMessage *message = NULL;
+		strncpy (username, my_username, len);
+		username[len - 1] = '\0';
 
-  if (!nm_dbus_prepare_connection(data)) 
-      return;
-   
-  con = data->con;
-  if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE_PPP_STARTER, NM_DBUS_PATH_PPP_STARTER, NM_DBUS_INTERFACE_PPP_STARTER, "notifyPID")))
-  {
-    nm_warning ("nm-pppd-plugin: Couldn't allocate the notifyPID dbus message");
-    return;
-  }
-
-  dbus_message_append_args (message, 
-        DBUS_TYPE_UINT32, &(data->pppd_pid),
-        DBUS_TYPE_INVALID);
-
-  if (!dbus_connection_send (con, message, NULL)) {
-    info ("nm_ip_up(): could not send dbus message");
-    dbus_message_unref (message);
-    return;
-  }
- 
-//  nm_warning("Sent notify message: %d",data->pppd_pid);
-  dbus_message_unref (message);
-}
-/*
- * nm_get_auth_items
- *
- * Request credentials from PPP_STARTER service.
- *
- */
-gboolean nm_get_auth_items (NmPPPData *data)
-{
-  DBusConnection *con;
-  int num_auth_items = -1;
-  char *auth_items[3] = { NULL, NULL, NULL };
-//  char **auth_items = NULL;
-  DBusMessage *message = NULL;
-  DBusMessage *reply = NULL;
-
-  if (!nm_dbus_prepare_connection(data)) 
-      return FALSE;
-   
-  con = data->con;
-
-  g_return_val_if_fail (con != NULL,FALSE);
-  if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE_PPP_STARTER, NM_DBUS_PATH_PPP_STARTER, NM_DBUS_INTERFACE_PPP_STARTER, "getAuthInfo")))
-  {
-    nm_warning("nm-pppd-plugin: failed to create getAuthInfo message.");
-    return FALSE;
-  }
-
-  reply = dbus_connection_send_with_reply_and_block (con, message, -1, NULL);
-  dbus_message_unref (message);
-  if (!reply)
-    {
-      info("nm-pppd-plugin: no reply to getAuthInfo message.");
-      return FALSE;
-    }
-
-  if (!(dbus_message_get_args (reply, NULL, 
-              DBUS_TYPE_STRING, &(auth_items[0]),
-              DBUS_TYPE_STRING, &(auth_items[1]),
-              DBUS_TYPE_STRING, &(auth_items[2]),
-//              DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &auth_items, &num_auth_items, 
-              DBUS_TYPE_INVALID)))
-  {
-    dbus_message_unref (reply);
-    return FALSE;
-  }
-  num_auth_items=3;
-
-  if (!nm_store_auth_info (data, auth_items, num_auth_items))
-  {
-    //dbus_free_string_array (auth_items);
-    dbus_message_unref (reply);
-    return FALSE;
-  }
-
-  //dbus_free_string_array (auth_items);
-  dbus_message_unref (reply);
-  return TRUE;
+		g_free (my_username);
+	}
+
+	if (my_password) {
+		len = strlen (my_password) + 1;
+		len = len < MAXSECRETLEN ? len : MAXSECRETLEN;
+
+		strncpy (password, my_password, len);
+		password[len - 1] = '\0';
+
+		g_free (my_password);
+	}
+
+	return 1;
 }
 
-/*
- * nm_store_auth_info
- *
- * Decode and temporarily store the authentication info provided.
- *
- */
-gboolean nm_store_auth_info (NmPPPData *data, char **auth_items, int num_auth_items)
+static void
+nm_exit_notify (void *data, int arg)
 {
-//  int i=0;
-  g_return_val_if_fail (auth_items != NULL, FALSE);
-  g_return_val_if_fail (num_auth_items >= 1, FALSE);
-
-  nm_warning ("PPPD will authenticate using '%s'.", auth_items[0]);
-  
-  if (strcmp ("CHAP", auth_items[0]) == 0) {
-    g_return_val_if_fail (num_auth_items >= 3, FALSE);
-    if (data->auth_type!=NULL) g_free(data->auth_type);
-    if (data->username!=NULL) g_free(data->username);
-    if (data->password!=NULL) g_free(data->password);
-    data->auth_type=g_strdup(auth_items[0]);
-    data->username=g_strdup(auth_items[1]);
-    data->password=g_strdup(auth_items[2]);
-  } else if (strcmp ("NONE", auth_items[0]) == 0) {
-    if (data->auth_type!=NULL) g_free(data->auth_type);
-    if (data->username!=NULL) g_free(data->username);
-    if (data->password!=NULL) g_free(data->password);
-    data->auth_type=g_strdup(auth_items[0]);
-  } else {
-	  nm_warning ("PPPD authentication type '%s' is not allowed.", auth_items[0]);
-      return FALSE;
-  }
+	g_return_if_fail (DBUS_IS_G_PROXY (proxy));
 
-  data->got_auth_info=TRUE;
-  return TRUE;
+	g_object_unref (proxy);
+	proxy = NULL;
 }
 
-int plugin_init()
+int
+plugin_init (void)
 {
-//    DBusConnection *	con = NULL;
-//    DBusMessage *	message = NULL;
-//    DBusError		error;
-
-//    g_type_init ();
-//    if (!g_thread_supported ())
-//      g_thread_init (NULL);
-    
-//    dbus_error_init (&error);
-//    con = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-//    if ((con == NULL) || dbus_error_is_set (&error))
-//      {
-//        dbus_error_free (&error);
-//        info("Could not get the system bus.  Make sure the message bus daemon is running?");
-//        return -1;
-//      }
-//    dbus_connection_set_exit_on_disconnect (con, FALSE);
-//
-//
-//    dbus_error_free (&error);
-
-//    add_options(ppp_options);
-
-    chap_check_hook = nm_chap_check_hook;
-    chap_passwd_hook = nm_chap_passwd_hook;
-
-    add_notifier(&ip_down_notifier, nm_ip_down, (void *) &plugin_data);
-    add_notifier(&ip_up_notifier, nm_ip_up, (void *) &plugin_data);
-    add_notifier(&exitnotify, nm_exit_notify, (void *) &plugin_data);
+	DBusGConnection *bus;
+	GError *err = NULL;
 
-    info("nm-pppd-plugin: plugin initialized.");
-    return 0;
-}
+	g_type_init ();
 
+	bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+	if (!bus) {
+		g_warning ("Couldn't connect to system bus: %s", err->message);
+		g_error_free (err);
+		return -1;
+	}
 
+	proxy = dbus_g_proxy_new_for_name (bus,
+								NM_DBUS_SERVICE_PPTP_PPP,
+								NM_DBUS_PATH_PPTP_PPP,
+								NM_DBUS_INTERFACE_PPTP_PPP);
+
+	dbus_g_connection_unref (bus);
+
+	chap_passwd_hook = get_credentials;
+	chap_check_hook = get_chap_check;
+	pap_passwd_hook = get_credentials;
+	pap_check_hook = get_pap_check;
+
+	add_notifier (&phasechange, nm_phasechange, NULL);
+	add_notifier (&ip_up_notifier, nm_ip_up, NULL);
+	add_notifier (&exitnotify, nm_exit_notify, proxy);
+
+	return 0;
+}

Added: trunk/vpn-daemons/pptp/src/nm-pptp-pppd-service.xml
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/src/nm-pptp-pppd-service.xml	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+  <interface name="org.freedesktop.NetworkManager.pptp.ppp">
+    <method name="NeedSecrets">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_pptp_service_need_secrets"/>
+      <arg name="username" type="s" direction="out"/>
+      <arg name="password" type="s" direction="out"/>
+    </method>
+
+    <method name="SetIp4Config">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_pptp_service_set_ip4_config"/>
+      <arg name="config" type="a{sv}" direction="in"/>
+    </method>
+
+    <method name="SetState">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_pptp_service_set_state"/>
+      <arg name="state" type="u" direction="in"/>
+    </method>
+  </interface>
+</node>

Added: trunk/vpn-daemons/pptp/src/nm-pptp-service.c
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/src/nm-pptp-service.c	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,1031 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* nm-pptp-service - PPTP VPN integration with NetworkManager
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Red Hat, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <ctype.h>
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <asm/types.h>
+#include <net/if.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+
+#include <linux/ppp_defs.h>
+#ifndef aligned_u64
+#define aligned_u64 unsigned long long __attribute__((aligned(8)))
+#endif
+#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"
+#include "nm-ppp-status.h"
+
+/********************************************************/
+/* ppp plugin <-> pptp-service object                   */
+/********************************************************/
+
+/* Have to have a separate objec to handle ppp plugin requests since
+ * dbus-glib doesn't allow multiple interfaces registed on one GObject.
+ */
+
+#define NM_TYPE_PPTP_PPP_SERVICE            (nm_pptp_ppp_service_get_type ())
+#define NM_PPTP_PPP_SERVICE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PPTP_PPP_SERVICE, NMPptpPppService))
+#define NM_PPTP_PPP_SERVICE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_PPTP_PPP_SERVICE, NMPptpPppServiceClass))
+#define NM_IS_PPTP_PPP_SERVICE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_PPTP_PPP_SERVICE))
+#define NM_IS_PPTP_PPP_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_PPTP_PPP_SERVICE))
+#define NM_PPTP_PPP_SERVICE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_PPTP_PPP_SERVICE, NMPptpPppServiceClass))
+
+typedef struct {
+	GObject parent;
+} NMPptpPppService;
+
+typedef struct {
+	GObjectClass parent;
+
+	/* Signals */
+	void (*plugin_alive) (NMPptpPppService *self);
+	void (*ppp_state) (NMPptpPppService *self, guint32 state);
+	void (*ip4_config) (NMPptpPppService *self, GHashTable *config_hash);
+} NMPptpPppServiceClass;
+
+GType nm_pptp_ppp_service_get_type (void);
+
+G_DEFINE_TYPE (NMPptpPppService, nm_pptp_ppp_service, G_TYPE_OBJECT)
+
+static gboolean impl_pptp_service_need_secrets (NMPptpPppService *self,
+                                                char **out_username,
+                                                char **out_password,
+                                                GError **err);
+
+static gboolean impl_pptp_service_set_state (NMPptpPppService *self,
+                                             guint32 state,
+                                             GError **err);
+
+static gboolean impl_pptp_service_set_ip4_config (NMPptpPppService *self,
+                                                  GHashTable *config,
+                                                  GError **err);
+
+#include "nm-pptp-pppd-service-glue.h"
+
+
+#define NM_PPTP_PPP_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_PPTP_PPP_SERVICE, NMPptpPppServicePrivate))
+
+typedef struct {
+	char username[100];
+	char password[100];
+} NMPptpPppServicePrivate;
+
+enum {
+	PLUGIN_ALIVE,
+	PPP_STATE,
+	IP4_CONFIG,
+
+	LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = { 0 };
+
+NMPptpPppService *
+nm_pptp_ppp_service_new (void)
+{
+	DBusGConnection *connection;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	gboolean success = FALSE;
+	guint request_name_result;
+	GObject *object;
+
+	object = g_object_new (NM_TYPE_PPTP_PPP_SERVICE, NULL);
+
+	dbus_connection_set_change_sigpipe (TRUE);
+
+	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (!connection) {
+		nm_warning ("Could not get the system bus.  Make sure "
+		            "the message bus daemon is running!  Message: %s",
+		            error->message);
+		g_error_free (error);
+		g_object_unref (object);
+		return NULL;
+	}
+
+	proxy = dbus_g_proxy_new_for_name (connection,
+								"org.freedesktop.DBus",
+								"/org/freedesktop/DBus",
+								"org.freedesktop.DBus");
+
+	if (dbus_g_proxy_call (proxy, "RequestName", &error,
+					   G_TYPE_STRING, NM_DBUS_SERVICE_PPTP_PPP,
+					   G_TYPE_UINT, 0,
+					   G_TYPE_INVALID,
+					   G_TYPE_UINT, &request_name_result,
+					   G_TYPE_INVALID)) {
+		dbus_g_connection_register_g_object (connection, NM_DBUS_PATH_PPTP_PPP, object);
+		success = TRUE;
+	} else {
+		nm_warning ("Could not register D-Bus service name.  Message: %s", error->message);
+		g_error_free (error);
+		g_object_unref (object);
+		object = NULL;
+	}
+
+	g_object_unref (proxy);
+	return (NMPptpPppService *) object;
+}
+
+static void
+nm_pptp_ppp_service_init (NMPptpPppService *self)
+{
+}
+
+static void
+finalize (GObject *object)
+{
+	NMPptpPppServicePrivate *priv = NM_PPTP_PPP_SERVICE_GET_PRIVATE (object);
+
+	/* Get rid of the cached username and password */
+	memset (priv->username, 0, sizeof (priv->username));
+	memset (priv->password, 0, sizeof (priv->password));
+}
+
+static void
+nm_pptp_ppp_service_class_init (NMPptpPppServiceClass *service_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (service_class);
+
+	g_type_class_add_private (service_class, sizeof (NMPptpPppServicePrivate));
+
+	/* virtual methods */
+	object_class->finalize = finalize;
+
+	/* Signals */
+	signals[PLUGIN_ALIVE] = 
+		g_signal_new ("plugin-alive", 
+		              G_OBJECT_CLASS_TYPE (object_class),
+		              G_SIGNAL_RUN_FIRST,
+		              G_STRUCT_OFFSET (NMPptpPppServiceClass, plugin_alive),
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__VOID,
+		              G_TYPE_NONE, 0);
+
+	signals[PPP_STATE] = 
+		g_signal_new ("ppp-state", 
+		              G_OBJECT_CLASS_TYPE (object_class),
+		              G_SIGNAL_RUN_FIRST,
+		              G_STRUCT_OFFSET (NMPptpPppServiceClass, ppp_state),
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__UINT,
+		              G_TYPE_NONE, 1, G_TYPE_UINT);
+
+	signals[IP4_CONFIG] = 
+		g_signal_new ("ip4-config", 
+		              G_OBJECT_CLASS_TYPE (object_class),
+		              G_SIGNAL_RUN_FIRST,
+		              G_STRUCT_OFFSET (NMPptpPppServiceClass, ip4_config),
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__POINTER,
+		              G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+	dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (service_class),
+									 &dbus_glib_nm_pptp_pppd_service_object_info);
+}
+
+static gboolean
+nm_pptp_ppp_service_cache_credentials (NMPptpPppService *self,
+                                       NMConnection *connection,
+                                       GError **error)
+{
+	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);
+	g_return_val_if_fail (connection != NULL, FALSE);
+
+	memset (priv->username, 0, sizeof (priv->username));
+	memset (priv->password, 0, sizeof (priv->password));
+
+	s_vpn = (NMSettingVPN *) 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,
+		             "%s",
+		             "Could not find secrets (connection invalid, no vpn setting).");
+		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);
+		if (!username || !strlen (username)) {
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
+			             "%s",
+			             "Invalid VPN username.");
+			return FALSE;
+		}
+	} else {
+		username = s_vpn->user_name;
+		if (!username || !strlen (username)) {
+			g_set_error (error,
+			             NM_VPN_PLUGIN_ERROR,
+			             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
+			             "%s",
+			             "Missing VPN username.");
+			return FALSE;
+		}
+	}
+
+	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);
+	if (!password || !strlen (password)) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
+		             "%s",
+		             "Invalid VPN password.");
+		return FALSE;
+	}
+
+	memcpy (priv->username, username, strlen (username));
+	memcpy (priv->password, password, strlen (password));
+	return TRUE;
+}
+
+static gboolean
+impl_pptp_service_need_secrets (NMPptpPppService *self,
+                                char **out_username,
+                                char **out_password,
+                                GError **error)
+{
+	NMPptpPppServicePrivate *priv = NM_PPTP_PPP_SERVICE_GET_PRIVATE (self);
+
+	g_signal_emit (G_OBJECT (self), signals[PLUGIN_ALIVE], 0);
+
+	if (!strlen (priv->username) || !strlen (priv->password)) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
+		             "%s",
+		             "No cached credentials.");
+		goto error;
+	}
+
+	/* Success */
+	*out_username = g_strdup (priv->username);
+	*out_password = g_strdup (priv->password);
+	return TRUE;
+
+error:
+	return FALSE;
+}
+
+static gboolean
+impl_pptp_service_set_state (NMPptpPppService *self,
+                             guint32 pppd_state,
+                             GError **err)
+{
+	g_signal_emit (G_OBJECT (self), signals[PLUGIN_ALIVE], 0);
+	g_signal_emit (G_OBJECT (self), signals[PPP_STATE], 0, pppd_state);
+	return TRUE;
+}
+
+static gboolean
+impl_pptp_service_set_ip4_config (NMPptpPppService *self,
+                                  GHashTable *config_hash,
+                                  GError **err)
+{
+	nm_info ("PPTP service (IP Config Get) reply received.");
+	g_signal_emit (G_OBJECT (self), signals[PLUGIN_ALIVE], 0);
+
+	/* Just forward the pppd plugin config up to our superclass; no need to modify it */
+	g_signal_emit (G_OBJECT (self), signals[IP4_CONFIG], 0, config_hash);
+
+	return TRUE;
+}
+
+
+/********************************************************/
+/* The VPN plugin service                               */
+/********************************************************/
+
+G_DEFINE_TYPE (NMPptpPlugin, nm_pptp_plugin, NM_TYPE_VPN_PLUGIN)
+
+typedef struct {
+	GPid pid;
+	guint32 ppp_timeout_handler;
+	NMPptpPppService *service;
+} NMPptpPluginPrivate;
+
+#define NM_PPTP_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_PPTP_PLUGIN, NMPptpPluginPrivate))
+
+#define NM_PPTP_PPPD_PLUGIN PLUGINDIR "/nm-pptp-pppd-plugin.so"
+#define NM_PPTP_WAIT_PPPD 10000 /* 10 seconds */
+#define PPTP_SERVICE_SECRET_TRIES "pptp-service-secret-tries"
+
+typedef struct {
+	const char *name;
+	GType type;
+	gboolean required;
+} ValidProperty;
+
+static ValidProperty valid_properties[] = {
+	{ NM_PPTP_KEY_GATEWAY,           G_TYPE_STRING, TRUE },
+	{ NM_PPTP_KEY_USER,              G_TYPE_STRING, FALSE },
+	{ NM_PPTP_KEY_PASSWORD,          G_TYPE_STRING, FALSE },
+	{ NM_PPTP_KEY_DOMAIN,            G_TYPE_STRING, FALSE },
+	{ NM_PPTP_KEY_REFUSE_EAP,        G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_REFUSE_PAP,        G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_REFUSE_CHAP,       G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_REFUSE_MSCHAP,     G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_REFUSE_MSCHAPV2,   G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_REQUIRE_MPPE,      G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_REQUIRE_MPPE_40,   G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_REQUIRE_MPPE_128,  G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_MPPE_STATEFUL,     G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_NOBSDCOMP,         G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_NODEFLATE,         G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_NO_VJ_COMP,        G_TYPE_BOOLEAN, FALSE },
+	{ NM_PPTP_KEY_LCP_ECHO_FAILURE,  G_TYPE_UINT, FALSE },
+	{ NM_PPTP_KEY_LCP_ECHO_INTERVAL, G_TYPE_UINT, FALSE },
+	{ NULL,                          G_TYPE_NONE,   FALSE }
+};
+
+static gboolean
+validate_gateway (GValue *value)
+{
+	const char *gateway = g_value_get_string (value);
+	const char *p = gateway;
+
+	if (!gateway || !strlen (gateway))
+		return FALSE;
+
+	/* Ensure it's a valid DNS name or IP address */
+	p = gateway;
+	while (*p) {
+		if (!isalnum (*p) && (*p != '-') && (*p != '.'))
+			return FALSE;
+		p++;
+	}
+	return TRUE;
+}
+
+static void
+validate_one_property (gpointer key, gpointer val, gpointer user_data)
+{
+	gboolean *failed = (gboolean *) user_data;
+	int i;
+
+	if (*failed)
+		return;
+
+	/* 'name' is the setting name; always allowed but unused */
+	if (!strcmp ((char *) key, NM_SETTING_NAME))
+		return;
+
+	for (i = 0; valid_properties[i].name; i++) {
+		ValidProperty prop = valid_properties[i];
+
+		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;
+			}
+			/* Property is ok */
+			return;
+		}
+	}
+
+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;
+}
+
+static gboolean
+nm_pptp_properties_validate (GHashTable *properties)
+{
+	gboolean failed = FALSE;
+	int i;
+
+	if (g_hash_table_size (properties) < 1)
+		return failed;
+
+	g_hash_table_foreach (properties, validate_one_property, &failed);
+	if (failed)
+		return FALSE;
+
+	/* Ensure required properties exist */
+	for (i = 0; valid_properties[i].name; i++) {
+		ValidProperty prop = valid_properties[i];
+		GValue *value;
+
+		if (!prop.required)
+			continue;
+
+		value = g_hash_table_lookup (properties, prop.name);
+		if (!value || (G_VALUE_TYPE (value) != prop.type))
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void
+pppd_watch_cb (GPid pid, gint status, gpointer user_data)
+{
+	NMPptpPlugin *plugin = NM_PPTP_PLUGIN (user_data);
+	NMPptpPluginPrivate *priv = NM_PPTP_PLUGIN_GET_PRIVATE (plugin);
+	guint error = 0;
+
+	if (WIFEXITED (status)) {
+		error = WEXITSTATUS (status);
+		if (error != 0)
+			nm_warning ("pppd exited with error code %d", error);
+	}
+	else if (WIFSTOPPED (status))
+		nm_warning ("pppd stopped unexpectedly with signal %d", WSTOPSIG (status));
+	else if (WIFSIGNALED (status))
+		nm_warning ("pppd died with signal %d", WTERMSIG (status));
+	else
+		nm_warning ("pppd died from an unknown cause");
+
+	/* Reap child if needed. */
+	waitpid (priv->pid, NULL, WNOHANG);
+	priv->pid = 0;
+
+	/* Must be after data->state is set since signals use data->state */
+	switch (error) {
+	case 16:
+		/* hangup */
+		// FIXME: better failure reason
+		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
+		break;
+	case 2:
+		/* Couldn't log in due to bad user/pass */
+		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED);
+		break;
+	case 1:
+		/* Other error (couldn't bind to address, etc) */
+		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
+		break;
+	default:
+		break;
+	}
+
+	nm_vpn_plugin_set_state (NM_VPN_PLUGIN (plugin), NM_VPN_SERVICE_STATE_STOPPED);
+}
+
+static inline const char *
+nm_find_pppd (void)
+{
+	static const char *pppd_binary_paths[] =
+		{
+			"/sbin/pppd",
+			"/usr/sbin/pppd",
+			"/usr/local/sbin/pppd",
+			NULL
+		};
+
+	const char  **pppd_binary = pppd_binary_paths;
+
+	while (*pppd_binary != NULL) {
+		if (g_file_test (*pppd_binary, G_FILE_TEST_EXISTS))
+			break;
+		pppd_binary++;
+	}
+
+	return *pppd_binary;
+}
+
+static inline const char *
+nm_find_pptp (void)
+{
+	static const char *pptp_binary_paths[] =
+		{
+			"/sbin/pptp",
+			"/usr/sbin/pptp",
+			"/usr/local/sbin/pptp",
+			NULL
+		};
+
+	const char  **pptp_binary = pptp_binary_paths;
+
+	while (*pptp_binary != NULL) {
+		if (g_file_test (*pptp_binary, G_FILE_TEST_EXISTS))
+			break;
+		pptp_binary++;
+	}
+
+	return *pptp_binary;
+}
+
+static gboolean
+pppd_timed_out (gpointer user_data)
+{
+	NMPptpPlugin *plugin = NM_PPTP_PLUGIN (user_data);
+
+	nm_warning ("Looks like pppd didn't initialize our dbus module");
+	nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT);
+
+	return FALSE;
+}
+
+static void
+free_pppd_args (GPtrArray *args)
+{
+	int i;
+
+	if (!args)
+		return;
+
+	for (i = 0; i < args->len; i++)
+		g_free (g_ptr_array_index (args, i));
+	g_ptr_array_free (args, TRUE);
+}
+
+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;
+	char *ipparam, *tmp;
+
+	pptp_binary = nm_find_pptp ();
+	if (!pptp_binary) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
+		             "%s",
+		             "Could not find pptp client binary.");
+		return FALSE;
+	}
+
+	args = g_ptr_array_new ();
+	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)) {
+		g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
+		             "%s",
+		             "Missing VPN gateway.");
+		goto error;
+	}
+
+	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);
+	g_ptr_array_add (args, (gpointer) tmp);
+
+	/* PPP options */
+	g_ptr_array_add (args, (gpointer) g_strdup ("ipparam"));
+	g_ptr_array_add (args, (gpointer) ipparam);
+
+	g_ptr_array_add (args, (gpointer) g_strdup ("nodetach"));
+	g_ptr_array_add (args, (gpointer) g_strdup ("lock"));
+	g_ptr_array_add (args, (gpointer) g_strdup ("usepeerdns"));
+
+	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))
+		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))
+		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))
+		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))
+		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))
+		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))
+		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))
+		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))
+		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))
+		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))
+		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))
+		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))
+		g_ptr_array_add (args, (gpointer) g_strdup ("novjcomp"));
+
+	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_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);
+	}
+
+	g_ptr_array_add (args, (gpointer) g_strdup ("plugin"));
+	g_ptr_array_add (args, (gpointer) g_strdup (NM_PPTP_PPPD_PLUGIN));
+
+	g_ptr_array_add (args, NULL);
+
+	return args;
+
+error:
+	free_pppd_args (args);
+	return FALSE;
+}
+
+static gboolean
+nm_pptp_start_pppd_binary (NMPptpPlugin *plugin,
+                           NMSettingVPN *s_vpn,
+                           NMSettingVPNProperties *s_vpn_props)
+{
+	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.");
+		return FALSE;
+	}
+
+	pppd_argv = construct_pppd_args (plugin, s_vpn, s_vpn_props, pppd_binary, &err);
+	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_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);
+
+	nm_info ("pppd started with pid %d", pid);
+
+	NM_PPTP_PLUGIN_GET_PRIVATE (plugin)->pid = pid;
+	g_child_watch_add (pid, pppd_watch_cb, plugin);
+
+	priv->ppp_timeout_handler = g_timeout_add (NM_PPTP_WAIT_PPPD, pppd_timed_out, plugin);
+
+	return TRUE;
+}
+
+static void
+remove_timeout_handler (NMPptpPlugin *plugin)
+{
+	NMPptpPluginPrivate *priv = NM_PPTP_PLUGIN_GET_PRIVATE (plugin);
+	
+	if (priv->ppp_timeout_handler) {
+		g_source_remove (priv->ppp_timeout_handler);
+		priv->ppp_timeout_handler = 0;
+	}
+}
+
+static void
+service_plugin_alive_cb (NMPptpPppService *service,
+                         NMPptpPlugin *plugin)
+{
+	remove_timeout_handler (plugin);
+}
+
+static void
+service_ppp_state_cb (NMPptpPppService *service,
+                      guint32 ppp_state,
+                      NMPptpPlugin *plugin)
+{
+	NMVPNServiceState plugin_state = nm_vpn_plugin_get_state (NM_VPN_PLUGIN (plugin));
+
+	switch (ppp_state) {
+	case NM_PPP_STATUS_DEAD:
+	case NM_PPP_STATUS_DISCONNECT:
+		if (plugin_state == NM_VPN_SERVICE_STATE_STARTED)
+			nm_vpn_plugin_disconnect (NM_VPN_PLUGIN (plugin), NULL);
+		else if (plugin_state == NM_VPN_SERVICE_STATE_STARTING)
+			nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+service_ip4_config_cb (NMPptpPppService *service,
+                       GHashTable *config_hash,
+                       NMPptpPlugin *plugin)
+{
+	nm_vpn_plugin_set_ip4_config (NM_VPN_PLUGIN (plugin), config_hash);
+}
+
+static gboolean
+real_connect (NMVPNPlugin   *plugin,
+              NMConnection  *connection,
+              GError       **err)
+{
+	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);
+
+	/* Start our pppd plugin helper service */
+	if (priv->service)
+		g_object_unref (priv->service);
+
+	priv->service = nm_pptp_ppp_service_new ();
+	if (!priv->service) {
+		g_set_error (err,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
+		             "%s",
+		             "Could not start pppd plugin helper service.");
+		return FALSE;
+	}
+	g_signal_connect (G_OBJECT (priv->service), "plugin-alive", G_CALLBACK (service_plugin_alive_cb), plugin);
+	g_signal_connect (G_OBJECT (priv->service), "ppp-state", G_CALLBACK (service_ppp_state_cb), plugin);
+	g_signal_connect (G_OBJECT (priv->service), "ip4-config", G_CALLBACK (service_ip4_config_cb), plugin);
+
+	/* 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))
+		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.");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean
+real_need_secrets (NMVPNPlugin *plugin,
+                   NMConnection *connection,
+                   char **setting_name,
+                   GError **error)
+{
+	NMSettingVPNProperties *s_vpn_props;
+
+	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) {
+        g_set_error (error,
+		             NM_VPN_PLUGIN_ERROR,
+		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
+		             "%s",
+		             "Could not process the request because the VPN connection settings were invalid.");
+		return FALSE;
+	}
+
+	if (!g_hash_table_lookup (s_vpn_props->data, NM_PPTP_KEY_PASSWORD)) {
+		*setting_name = NM_SETTING_VPN_PROPERTIES_SETTING_NAME;
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+ensure_killed (gpointer data)
+{
+	int pid = GPOINTER_TO_INT (data);
+
+	if (kill (pid, 0) == 0)
+		kill (pid, SIGKILL);
+
+	return FALSE;
+}
+
+static gboolean
+real_disconnect (NMVPNPlugin   *plugin,
+			  GError       **err)
+{
+	NMPptpPluginPrivate *priv = NM_PPTP_PLUGIN_GET_PRIVATE (plugin);
+
+	if (priv->pid) {
+		if (kill (priv->pid, SIGTERM) == 0)
+			g_timeout_add (2000, ensure_killed, GINT_TO_POINTER (priv->pid));
+		else
+			kill (priv->pid, SIGKILL);
+
+		nm_info ("Terminated ppp daemon with PID %d.", priv->pid);
+		priv->pid = 0;
+	}
+
+	if (priv->service) {
+		g_object_unref (priv->service);
+		priv->service = NULL;
+	}
+
+	return TRUE;
+}
+
+static void
+state_changed_cb (GObject *object, NMVPNServiceState state, gpointer user_data)
+{
+	NMPptpPluginPrivate *priv = NM_PPTP_PLUGIN_GET_PRIVATE (object);
+
+	switch (state) {
+	case NM_VPN_SERVICE_STATE_UNKNOWN:
+	case NM_VPN_SERVICE_STATE_INIT:
+	case NM_VPN_SERVICE_STATE_SHUTDOWN:
+	case NM_VPN_SERVICE_STATE_STARTED:
+	case NM_VPN_SERVICE_STATE_STOPPING:
+	case NM_VPN_SERVICE_STATE_STOPPED:
+		if (priv->service) {
+			g_object_unref (priv->service);
+			priv->service = NULL;
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+dispose (GObject *object)
+{
+	NMPptpPluginPrivate *priv = NM_PPTP_PLUGIN_GET_PRIVATE (object);
+
+	if (priv->service)
+		g_object_unref (priv->service);
+
+	G_OBJECT_CLASS (nm_pptp_plugin_parent_class)->dispose (object);
+}
+
+static void
+nm_pptp_plugin_init (NMPptpPlugin *plugin)
+{
+}
+
+static void
+nm_pptp_plugin_class_init (NMPptpPluginClass *pptp_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (pptp_class);
+	NMVPNPluginClass *parent_class = NM_VPN_PLUGIN_CLASS (pptp_class);
+
+	g_type_class_add_private (object_class, sizeof (NMPptpPluginPrivate));
+
+	/* virtual methods */
+	object_class->dispose = dispose;
+	parent_class->connect    = real_connect;
+	parent_class->need_secrets = real_need_secrets;
+	parent_class->disconnect = real_disconnect;
+}
+
+NMPptpPlugin *
+nm_pptp_plugin_new (void)
+{
+	NMPptpPlugin *plugin;
+
+	plugin = g_object_new (NM_TYPE_PPTP_PLUGIN,
+	                       NM_VPN_PLUGIN_DBUS_SERVICE_NAME,
+	                       NM_DBUS_SERVICE_PPTP,
+	                       NULL);
+	if (plugin)
+		g_signal_connect (G_OBJECT (plugin), "state-changed", G_CALLBACK (state_changed_cb), NULL);
+	return plugin;
+}
+
+static void
+quit_mainloop (NMPptpPlugin *plugin, gpointer user_data)
+{
+	g_main_loop_quit ((GMainLoop *) user_data);
+}
+
+int
+main (int argc, char *argv[])
+{
+	NMPptpPlugin *plugin;
+	GMainLoop *main_loop;
+
+	g_type_init ();
+
+	plugin = nm_pptp_plugin_new ();
+	if (!plugin)
+		exit (EXIT_FAILURE);
+
+	main_loop = g_main_loop_new (NULL, FALSE);
+
+	g_signal_connect (plugin, "quit",
+				   G_CALLBACK (quit_mainloop),
+				   main_loop);
+
+	g_main_loop_run (main_loop);
+
+	g_main_loop_unref (main_loop);
+	g_object_unref (plugin);
+
+	exit (EXIT_SUCCESS);
+}

Added: trunk/vpn-daemons/pptp/src/nm-pptp-service.h
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/pptp/src/nm-pptp-service.h	Sun Jul 20 22:45:51 2008
@@ -0,0 +1,82 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* nm-pptp-service - PPTP VPN integration with NetworkManager
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Red Hat, Inc.
+ */
+
+#ifndef NM_PPTP_PLUGIN_H
+#define NM_PPTP_PLUGIN_H
+
+#include <glib/gtypes.h>
+#include <glib-object.h>
+#include <nm-vpn-plugin.h>
+
+#define NM_TYPE_PPTP_PLUGIN            (nm_pptp_plugin_get_type ())
+#define NM_PPTP_PLUGIN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PPTP_PLUGIN, NMPptpPlugin))
+#define NM_PPTP_PLUGIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_PPTP_PLUGIN, NMPptpPluginClass))
+#define NM_IS_PPTP_PLUGIN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_PPTP_PLUGIN))
+#define NM_IS_PPTP_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_PPTP_PLUGIN))
+#define NM_PPTP_PLUGIN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_PPTP_PLUGIN, NMPptpPluginClass))
+
+/* For the pppd plugin <-> VPN plugin service */
+#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
+
+#define NM_DBUS_SERVICE_PPTP_PPP    "org.freedesktop.NetworkManager.pptp-ppp"
+#define NM_DBUS_PATH_PPTP_PPP       "/org/freedesktop/NetworkManager/pptp/ppp"
+#define NM_DBUS_INTERFACE_PPTP_PPP  "org.freedesktop.NetworkManager.pptp.ppp"
+
+
+/* For the NM <-> VPN plugin service */
+#define NM_DBUS_SERVICE_PPTP    "org.freedesktop.NetworkManager.pptp"
+#define NM_DBUS_INTERFACE_PPTP  "org.freedesktop.NetworkManager.pptp"
+#define NM_DBUS_PATH_PPTP       "/org/freedesktop/NetworkManager/pptp"
+
+#define NM_PPTP_KEY_GATEWAY           "gateway"
+#define NM_PPTP_KEY_USER              "user"
+#define NM_PPTP_KEY_PASSWORD          "password"
+#define NM_PPTP_KEY_DOMAIN            "domain"
+#define NM_PPTP_KEY_REFUSE_EAP        "refuse-eap"
+#define NM_PPTP_KEY_REFUSE_PAP        "refuse-pap"
+#define NM_PPTP_KEY_REFUSE_CHAP       "refuse-chap"
+#define NM_PPTP_KEY_REFUSE_MSCHAP     "refuse-mschap"
+#define NM_PPTP_KEY_REFUSE_MSCHAPV2   "refuse-mschapv2"
+#define NM_PPTP_KEY_REQUIRE_MPPE      "require-mppe"
+#define NM_PPTP_KEY_REQUIRE_MPPE_40   "require-mppe-40"
+#define NM_PPTP_KEY_REQUIRE_MPPE_128  "require-mppe-128"
+#define NM_PPTP_KEY_MPPE_STATEFUL     "mppe-stateful"
+#define NM_PPTP_KEY_NOBSDCOMP         "nobsdcomp"
+#define NM_PPTP_KEY_NODEFLATE         "nodeflate"
+#define NM_PPTP_KEY_NO_VJ_COMP        "no-vj-comp"
+#define NM_PPTP_KEY_LCP_ECHO_FAILURE  "lcp-echo-failure"
+#define NM_PPTP_KEY_LCP_ECHO_INTERVAL "lcp-echo-interval"
+
+
+typedef struct {
+	NMVPNPlugin parent;
+} NMPptpPlugin;
+
+typedef struct {
+	NMVPNPluginClass parent;
+} NMPptpPluginClass;
+
+GType nm_pptp_plugin_get_type (void);
+
+NMPptpPlugin *nm_pptp_plugin_new (void);
+
+#endif /* NM_PPTP_PLUGIN_H */



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