[network-manager-vpnc/rm-userset: 3/4] auth-dialog: port to new applet IPC protocol



commit 5b55b7bfc0999664acc4fad9f12fd2b93fc1e227
Author: Dan Williams <dcbw redhat com>
Date:   Wed Feb 9 01:03:49 2011 -0600

    auth-dialog: port to new applet IPC protocol
    
    As a bonus, we don't need to hit up GConf anymore.

 auth-dialog/Makefile.am |    2 -
 auth-dialog/main.c      |  324 ++++++++++++++++++++++++-----------------------
 2 files changed, 168 insertions(+), 158 deletions(-)
---
diff --git a/auth-dialog/Makefile.am b/auth-dialog/Makefile.am
index 4d9b6ba..3100987 100644
--- a/auth-dialog/Makefile.am
+++ b/auth-dialog/Makefile.am
@@ -6,7 +6,6 @@ nm_vpnc_auth_dialog_CPPFLAGS = \
 	$(NETWORKMANAGER_CFLAGS) \
 	$(GTHREAD_CFLAGS) \
 	$(GTK_CFLAGS) \
-	$(GCONF_CFLAGS) \
 	$(GNOMEKEYRING_CFLAGS) \
 	-DICONDIR=\""$(datadir)/pixmaps"\" \
 	-DBINDIR=\""$(bindir)"\" \
@@ -23,7 +22,6 @@ nm_vpnc_auth_dialog_SOURCES = \
 
 nm_vpnc_auth_dialog_LDADD = \
 	$(GTK_LIBS) \
-	$(GCONF_LIBS) \
 	$(top_builddir)/common-gnome/libnm-vpnc-common-gnome.la
 
 CLEANFILES = *~
diff --git a/auth-dialog/main.c b/auth-dialog/main.c
index 75ed7b7..116110e 100644
--- a/auth-dialog/main.c
+++ b/auth-dialog/main.c
@@ -17,19 +17,18 @@
  * 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 - 2008 Red Hat, Inc.
+ * (C) Copyright 2004 - 2011 Red Hat, Inc.
  */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+#include <errno.h>
 #include <string.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <gnome-keyring.h>
 #include <gnome-keyring-memory.h>
-#include <gconf/gconf-client.h>
 
 #include <nm-setting-vpn.h>
 #include <nm-setting-connection.h>
@@ -38,75 +37,15 @@
 #include "src/nm-vpnc-service.h"
 #include "gnome-two-password-dialog.h"
 
-#define KEYRING_UUID_TAG "connection-uuid"
-#define KEYRING_SN_TAG "setting-name"
-#define KEYRING_SK_TAG "setting-key"
-
-static char *
-find_connection_path (const char *vpn_uuid)
-{
-	char *key, *str, *connection_path = NULL;
-	GConfClient *gconf_client = NULL;
-	GSList *conf_list;
-	GSList *iter;
-
-	/* FIXME: This whole thing sucks: we should not go around poking gconf
-	   directly, but there's nothing that does it for us right now */
-
-	gconf_client = gconf_client_get_default ();
-
-	conf_list = gconf_client_all_dirs (gconf_client, "/system/networking/connections", NULL);
-	if (!conf_list)
-		return NULL;
-
-	for (iter = conf_list; iter; iter = iter->next) {
-		const char *path = (const char *) iter->data;
-
-		key = g_strdup_printf ("%s/%s/%s", 
-		                       path,
-		                       NM_SETTING_CONNECTION_SETTING_NAME,
-		                       NM_SETTING_CONNECTION_TYPE);
-		str = gconf_client_get_string (gconf_client, key, NULL);
-		g_free (key);
-
-		if (!str || strcmp (str, "vpn")) {
-			g_free (str);
-			continue;
-		}
-		g_free (str);
-
-		key = g_strdup_printf ("%s/%s/%s", 
-		                       path,
-		                       NM_SETTING_CONNECTION_SETTING_NAME,
-		                       NM_SETTING_CONNECTION_UUID);
-		str = gconf_client_get_string (gconf_client, key, NULL);
-		g_free (key);
-
-		if (!str || strcmp (str, vpn_uuid)) {
-			g_free (str);
-			continue;
-		}
-		g_free (str);
-
-		/* Woo, found the connection */
-		connection_path = g_strdup (path);
-		break;
-	}
-
-	g_slist_foreach (conf_list, (GFunc) g_free, NULL);
-	g_slist_free (conf_list);
-
-	g_object_unref (gconf_client);
-	return connection_path;
-}
-
 static gboolean
 get_secrets (const char *vpn_uuid,
              const char *vpn_name,
              gboolean retry,
-             char **upw,
+             const char *in_upw,
+             char **out_upw,
              const char *upw_type,
-             char **gpw,
+             const char *in_gpw,
+             char **out_gpw,
              const char *gpw_type)
 {
 	VpnPasswordDialog *dialog;
@@ -118,43 +57,53 @@ get_secrets (const char *vpn_uuid,
 
 	g_return_val_if_fail (vpn_uuid != NULL, FALSE);
 	g_return_val_if_fail (vpn_name != NULL, FALSE);
-	g_return_val_if_fail (upw != NULL, FALSE);
-	g_return_val_if_fail (*upw == NULL, FALSE);
-	g_return_val_if_fail (gpw != NULL, FALSE);
-	g_return_val_if_fail (*gpw == NULL, FALSE);
+	g_return_val_if_fail (out_upw != NULL, FALSE);
+	g_return_val_if_fail (*out_upw == NULL, FALSE);
+	g_return_val_if_fail (out_gpw != NULL, FALSE);
+	g_return_val_if_fail (*out_gpw == NULL, FALSE);
 
 	/* If a password type wasn't present in the VPN connection details, then
 	 * default to saving the password if it was found in the keyring.  But if
 	 * it wasn't found in the keyring, default to always asking for the password.
 	 */
 
-	found_upw = keyring_helpers_get_one_secret (vpn_uuid, VPNC_USER_PASSWORD, upw, &is_session);
-	if (!upw_type)
-		upw_type = found_upw ? NM_VPNC_PW_TYPE_SAVE : NM_VPNC_PW_TYPE_ASK;
-	else if (!strcmp (upw_type, NM_VPNC_PW_TYPE_UNUSED)) {
-		gnome_keyring_memory_free (*upw);
-		*upw = NULL;
+	if (in_upw) {
+		*out_upw = gnome_keyring_memory_strdup (in_upw);
+		found_upw = TRUE;
+	} else {
+		found_upw = keyring_helpers_get_one_secret (vpn_uuid, VPNC_USER_PASSWORD, out_upw, &is_session);
+		if (!upw_type)
+			upw_type = found_upw ? NM_VPNC_PW_TYPE_SAVE : NM_VPNC_PW_TYPE_ASK;
+		else if (!strcmp (upw_type, NM_VPNC_PW_TYPE_UNUSED)) {
+			gnome_keyring_memory_free (*out_upw);
+			*out_upw = NULL;
+		}
 	}
 
-	found_gpw = keyring_helpers_get_one_secret (vpn_uuid, VPNC_GROUP_PASSWORD, gpw, &is_session);
-	if (!gpw_type)
-		gpw_type = found_gpw ? NM_VPNC_PW_TYPE_SAVE : NM_VPNC_PW_TYPE_ASK;
-	else if (!strcmp (gpw_type, NM_VPNC_PW_TYPE_UNUSED)) {
-		gnome_keyring_memory_free (*gpw);
-		*gpw = NULL;
+	if (in_gpw) {
+		*out_gpw = gnome_keyring_memory_strdup (in_gpw);
+		found_gpw = TRUE;
+	} else {
+		found_gpw = keyring_helpers_get_one_secret (vpn_uuid, VPNC_GROUP_PASSWORD, out_gpw, &is_session);
+		if (!gpw_type)
+			gpw_type = found_gpw ? NM_VPNC_PW_TYPE_SAVE : NM_VPNC_PW_TYPE_ASK;
+		else if (!strcmp (gpw_type, NM_VPNC_PW_TYPE_UNUSED)) {
+			gnome_keyring_memory_free (*out_gpw);
+			*out_gpw = NULL;
+		}
 	}
 
 	if (!retry) {
 		gboolean need_upw = TRUE, need_gpw = TRUE;
 
 		/* Don't ask if both passwords are either saved and present, or unused */
-		if (   (!strcmp (upw_type, NM_VPNC_PW_TYPE_SAVE) && found_upw && *upw)
-		    || (!upw_type && found_upw && *upw)  /* treat unknown type as "save" */
+		if (   (!strcmp (upw_type, NM_VPNC_PW_TYPE_SAVE) && found_upw && *out_upw)
+		    || (!upw_type && found_upw && *out_upw)  /* treat unknown type as "save" */
 		    || !strcmp (upw_type, NM_VPNC_PW_TYPE_UNUSED))
 			need_upw = FALSE;
 
-		if (   (!strcmp (gpw_type, NM_VPNC_PW_TYPE_SAVE) && found_gpw && *gpw)
-		    || (!gpw_type && found_gpw && *gpw)  /* treat unknown type as "save" */
+		if (   (!strcmp (gpw_type, NM_VPNC_PW_TYPE_SAVE) && found_gpw && *out_gpw)
+		    || (!gpw_type && found_gpw && *out_gpw)  /* treat unknown type as "save" */
 		    || !strcmp (gpw_type, NM_VPNC_PW_TYPE_UNUSED))
 			need_gpw = FALSE;
 
@@ -193,27 +142,27 @@ get_secrets (const char *vpn_uuid,
 	}
 
 	/* if retrying, pre-fill dialog with the password */
-	if (*upw) {
-		vpn_password_dialog_set_password (dialog, *upw);
-		gnome_keyring_memory_free (*upw);
-		*upw = NULL;
+	if (*out_upw) {
+		vpn_password_dialog_set_password (dialog, *out_upw);
+		gnome_keyring_memory_free (*out_upw);
+		*out_upw = NULL;
 	}
-	if (*gpw) {
-		vpn_password_dialog_set_password_secondary (dialog, *gpw);
-		gnome_keyring_memory_free (*gpw);
-		*gpw = NULL;
+	if (*out_gpw) {
+		vpn_password_dialog_set_password_secondary (dialog, *out_gpw);
+		gnome_keyring_memory_free (*out_gpw);
+		*out_gpw = NULL;
 	}
 
 	gtk_widget_show (GTK_WIDGET (dialog));
 
 	success = vpn_password_dialog_run_and_block (dialog);
 	if (success) {
-		*upw = gnome_keyring_memory_strdup (vpn_password_dialog_get_password (dialog));
-		*gpw = gnome_keyring_memory_strdup (vpn_password_dialog_get_password_secondary (dialog));
+		*out_upw = gnome_keyring_memory_strdup (vpn_password_dialog_get_password (dialog));
+		*out_gpw = gnome_keyring_memory_strdup (vpn_password_dialog_get_password_secondary (dialog));
 
 		if (!strcmp (upw_type, NM_VPNC_PW_TYPE_SAVE)) {
-			if (*upw)
-				keyring_helpers_save_secret (vpn_uuid, vpn_name, NULL, VPNC_USER_PASSWORD, *upw);
+			if (*out_upw)
+				keyring_helpers_save_secret (vpn_uuid, vpn_name, NULL, VPNC_USER_PASSWORD, *out_upw);
 		} else if (   !strcmp (upw_type, NM_VPNC_PW_TYPE_ASK)
 		         || !strcmp (upw_type, NM_VPNC_PW_TYPE_UNUSED)) {
 			/* Clear the password from the keyring */
@@ -221,8 +170,8 @@ get_secrets (const char *vpn_uuid,
 		}
 
 		if (!strcmp (gpw_type, NM_VPNC_PW_TYPE_SAVE)) {
-			if (*gpw)
-				keyring_helpers_save_secret (vpn_uuid, vpn_name, NULL, VPNC_GROUP_PASSWORD, *gpw);
+			if (*out_gpw)
+				keyring_helpers_save_secret (vpn_uuid, vpn_name, NULL, VPNC_GROUP_PASSWORD, *out_gpw);
 		} else if (   !strcmp (gpw_type, NM_VPNC_PW_TYPE_ASK)
 		         || !strcmp (gpw_type, NM_VPNC_PW_TYPE_UNUSED)) {
 			/* Clear the password from the keyring */
@@ -236,42 +185,104 @@ get_secrets (const char *vpn_uuid,
 	return success;
 }
 
+#define DATA_KEY_TAG "DATA_KEY="
+#define DATA_VAL_TAG "DATA_VAL="
+#define SECRET_KEY_TAG "SECRET_KEY="
+#define SECRET_VAL_TAG "SECRET_VAL="
+
 static gboolean
-get_connection_info (const char *vpn_uuid,
-                     char **out_name,
-                     char **out_upw_type,
-                     char **out_gpw_type)
+get_vpn_data_and_secrets (GHashTable **data, GHashTable **secrets)
 {
-	char *key;
-	char *connection_path = NULL;
-	GConfClient *gconf_client;
-
-	connection_path = find_connection_path (vpn_uuid);
-	if (!connection_path)
-		return FALSE;
-
-	gconf_client = gconf_client_get_default ();
-	key = g_strdup_printf ("%s/%s/%s", connection_path,
-	                       NM_SETTING_CONNECTION_SETTING_NAME,
-	                       NM_SETTING_CONNECTION_ID);
-	*out_name = gconf_client_get_string (gconf_client, key, NULL);
-	g_free (key);
-
-	key = g_strdup_printf ("%s/%s/%s", connection_path,
-	                       NM_SETTING_VPN_SETTING_NAME,
-	                       NM_VPNC_KEY_XAUTH_PASSWORD_TYPE);
-	*out_upw_type = gconf_client_get_string (gconf_client, key, NULL);
-	g_free (key);
-
-	key = g_strdup_printf ("%s/%s/%s", connection_path,
-	                       NM_SETTING_VPN_SETTING_NAME,
-	                       NM_VPNC_KEY_SECRET_TYPE);
-	*out_gpw_type = gconf_client_get_string (gconf_client, key, NULL);
-	g_free (key);
-	
-	g_free (connection_path);
-	g_object_unref (gconf_client);
-	return TRUE;
+	gboolean success = FALSE;
+	gchar c;
+	GString *line;
+	char *key = NULL, *val = NULL;
+
+	g_return_val_if_fail (data != NULL, FALSE);
+	g_return_val_if_fail (*data == NULL, FALSE);
+	g_return_val_if_fail (secrets != NULL, FALSE);
+	g_return_val_if_fail (*secrets == NULL, FALSE);
+
+	*data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+	*secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, gnome_keyring_memory_free);
+
+	line = g_string_new ("");
+
+	/* Read stdin for data and secret items until we get a DONE */
+	while (1) {
+		ssize_t nr;
+		GHashTable *hash = NULL;
+
+		errno = 0;
+		nr = read (0, &c, 1);
+		if (nr == -1) {
+			if (errno == EAGAIN) {
+				g_usleep (100);
+				continue;
+			}
+			break;
+		}
+
+		if (c != '\n') {
+			g_string_append_c (line, c);
+			continue;
+		}
+
+		/* Check for the finish marker */
+		if (strcmp (line->str, "DONE") == 0)
+			break;
+
+		/* Otherwise it's a data/secret item */
+		if (strncmp (line->str, DATA_KEY_TAG, strlen (DATA_KEY_TAG)) == 0) {
+			hash = *data;
+			key = g_strdup (line->str + strlen (DATA_KEY_TAG));
+		} else if (strncmp (line->str, DATA_VAL_TAG, strlen (DATA_VAL_TAG)) == 0) {
+			hash = *data;
+			val = g_strdup (line->str + strlen (DATA_VAL_TAG));
+		} else if (strncmp (line->str, SECRET_KEY_TAG, strlen (SECRET_KEY_TAG)) == 0) {
+			hash = *secrets;
+			key = g_strdup (line->str + strlen (SECRET_KEY_TAG));
+		} else if (strncmp (line->str, SECRET_VAL_TAG, strlen (SECRET_VAL_TAG)) == 0) {
+			hash = *secrets;
+			val = gnome_keyring_memory_strdup (line->str + strlen (SECRET_VAL_TAG));
+		}
+		g_string_truncate (line, 0);
+
+		if (key && val && hash) {
+			g_hash_table_insert (hash, key, val);
+			key = NULL;
+			val = NULL;
+			success = TRUE;  /* Got at least one value */
+		}
+	}
+
+	g_string_free (line, TRUE);
+	return success;
+}
+
+static void
+wait_for_quit (void)
+{
+	GString *str;
+	char c;
+	ssize_t n;
+	time_t start;
+
+	str = g_string_sized_new (10);
+	start = time (NULL);
+	do {
+		errno = 0;
+		n = read (0, &c, 1);
+		if (n == 0 || (n < 0 && errno == EAGAIN))
+			g_usleep (G_USEC_PER_SEC / 10);
+		else if (n == 1) {
+			g_string_append_c (str, c);
+			if (strstr (str->str, "QUIT") || (str->len > 10))
+				break;
+		} else
+			break;
+	} while (time (NULL) < start + 20);
+	g_string_free (str, TRUE);
 }
 
 int 
@@ -279,17 +290,14 @@ main (int argc, char *argv[])
 {
 	gboolean retry = FALSE;
 	char *vpn_name = NULL, *vpn_uuid = NULL, *vpn_service = NULL;
-	char *ignored;
+	GHashTable *data = NULL, *secrets = NULL;
 	char *password = NULL, *group_password = NULL;
-	char *upw_type = NULL, *gpw_type = NULL;
-	char buf[1];
-	int ret;
 	GError *error = NULL;
 	GOptionContext *context;
 	GOptionEntry entries[] = {
 			{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
 			{ "uuid", 'u', 0, G_OPTION_ARG_STRING, &vpn_uuid, "UUID of VPN connection", NULL},
-			{ "name", 'n', 0, G_OPTION_ARG_STRING, &ignored, "Name 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 }
 		};
@@ -303,15 +311,15 @@ main (int argc, char *argv[])
 	g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
 
 	if (!g_option_context_parse (context, &argc, &argv, &error)) {
-		g_warning ("Error parsing options: %s\n", error->message);
+		fprintf (stderr, "Error parsing options: %s\n", error->message);
 		g_error_free (error);
 		return 1;
 	}
 
 	g_option_context_free (context);
 
-	if (vpn_uuid == NULL || vpn_service == NULL) {
-		fprintf (stderr, "A connection UUID and VPN plugin service name are required.\n");
+	if (!vpn_uuid || !vpn_service || !vpn_name) {
+		fprintf (stderr, "A connection UUID, name, and VPN plugin service name are required.\n");
 		return 1;
 	}
 
@@ -320,21 +328,20 @@ main (int argc, char *argv[])
 		return 1;
 	}
 
-	if (!get_connection_info (vpn_uuid, &vpn_name, &upw_type, &gpw_type)) {
-		g_free (upw_type);
-		g_free (gpw_type);
-		fprintf (stderr, "This VPN connection '%s' (%s) could not be found in GConf.",
-		         vpn_name ? vpn_name : "(unknown)", vpn_uuid);
+	if (!get_vpn_data_and_secrets (&data, &secrets)) {
+		fprintf (stderr, "Failed to read '%s' (%s) data and secrets from stdin.",
+		         vpn_name, vpn_uuid);
 		return 1;
 	}
 
-	if (!get_secrets (vpn_uuid, vpn_name, retry, &password, upw_type, &group_password, gpw_type)) {
-		g_free (upw_type);
-		g_free (gpw_type);
+	if (!get_secrets (vpn_uuid, vpn_name, retry,
+	                  g_hash_table_lookup (secrets, NM_VPNC_KEY_XAUTH_PASSWORD),
+	                  &password,
+	                  g_hash_table_lookup (data, NM_VPNC_KEY_XAUTH_PASSWORD_TYPE),
+	                  g_hash_table_lookup (secrets, NM_VPNC_KEY_SECRET),
+	                  &group_password,
+	                  g_hash_table_lookup (data, NM_VPNC_KEY_SECRET_TYPE)))
 		return 1;
-	}
-	g_free (upw_type);
-	g_free (gpw_type);
 
 	/* dump the passwords to stdout */
 	if (password)
@@ -355,7 +362,12 @@ main (int argc, char *argv[])
 	/* for good measure, flush stdout since Kansas is going Bye-Bye */
 	fflush (stdout);
 
-	/* wait for data on stdin  */
-	ret = fread (buf, sizeof (char), sizeof (buf), stdin);
+	/* Wait for quit signal */
+	wait_for_quit ();
+
+	if (data)
+		g_hash_table_unref (data);
+	if (secrets)
+		g_hash_table_unref (secrets);
 	return 0;
 }



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