[network-manager-applet/rm-userset] agent: grab local secrets before asking user for more



commit 6419198be75a585d5b80e6174b4d7f55e7403c4d
Author: Dan Williams <dcbw redhat com>
Date:   Wed Feb 2 16:22:32 2011 -0600

    agent: grab local secrets before asking user for more
    
    So we can populate any UI with them before asking the user.  Users
    expect to see the passphrase or password that was there before, plus
    this helps UI dialog validation be simpler.

 src/applet-agent.c |  222 ++++++++++++++++++++++++++++------------------------
 1 files changed, 119 insertions(+), 103 deletions(-)
---
diff --git a/src/applet-agent.c b/src/applet-agent.c
index 1e8fbbb..d0e3b4a 100644
--- a/src/applet-agent.c
+++ b/src/applet-agent.c
@@ -193,6 +193,75 @@ ask_for_secrets (Request *r)
 	               r);
 }
 
+static void
+check_always_ask_cb (NMSetting *setting,
+                     const char *key,
+                     const GValue *value,
+                     GParamFlags flags,
+                     gpointer user_data)
+{
+	gboolean *always_ask = user_data;
+	NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED;
+
+	if (flags & NM_SETTING_PARAM_SECRET) {
+		if (nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) {
+			if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)
+				*always_ask = TRUE;
+		}
+	}
+}
+
+static gboolean
+has_always_ask (NMSetting *setting)
+{
+	gboolean always_ask = FALSE;
+
+	nm_setting_enumerate_values (setting, check_always_ask_cb, &always_ask);
+	return always_ask;
+}
+
+static gboolean
+is_connection_always_ask (NMConnection *connection)
+{
+	NMSettingConnection *s_con;
+	const char *ctype;
+	NMSetting *setting;
+
+	/* For the given connection type, check if the secrets for that connection
+	 * are always-ask or not.
+	 */
+	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	g_assert (s_con);
+	ctype = nm_setting_connection_get_connection_type (s_con);
+
+	setting = nm_connection_get_setting_by_name (connection, ctype);
+	g_return_val_if_fail (setting != NULL, FALSE);
+
+	if (has_always_ask (setting))
+		return TRUE;
+
+	/* Try type-specific settings too; be a bit paranoid and only consider
+	 * secrets from settings relevant to the connection type.
+	 */
+	if (NM_IS_SETTING_WIRELESS (setting)) {
+		setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+		if (setting && has_always_ask (setting))
+			return TRUE;
+		setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+		if (setting && has_always_ask (setting))
+			return TRUE;
+	} else if (NM_IS_SETTING_WIRED (setting)) {
+		setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
+		if (setting && has_always_ask (setting))
+			return TRUE;
+		setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+		if (setting && has_always_ask (setting))
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
 static GValue *
 string_to_gvalue (const char *str)
 {
@@ -223,7 +292,7 @@ keyring_find_secrets_cb (GnomeKeyringResult result,
 	const char *connection_id = NULL;
 	GHashTable *secrets = NULL, *settings = NULL;
 	GList *iter;
-	gboolean hint_found = FALSE;
+	gboolean hint_found = FALSE, ask = FALSE;
 
 	r->keyring_ids = g_slist_remove (r->keyring_ids, call->keyring_id);
 
@@ -288,10 +357,15 @@ keyring_find_secrets_cb (GnomeKeyringResult result,
 	/* If there were hints, and none of the hints were returned by the keyring,
 	 * get some new secrets.
 	 */
-	if (r->flags && r->hints && r->hints[0] && !hint_found) {
-		g_hash_table_destroy (secrets);
-		ask_for_secrets (r);
-		return;
+	if (r->flags) {
+		if (r->hints && r->hints[0] && !hint_found)
+			ask = TRUE;
+		else if (r->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW) {
+			g_message ("New secrets for %s/%s requested; ask the user", connection_id, r->setting_name);
+			ask = TRUE;
+		} else if (   (r->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION)
+			       && is_connection_always_ask (r->connection))
+			ask = TRUE;
 	}
 
 	/* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that
@@ -301,81 +375,32 @@ keyring_find_secrets_cb (GnomeKeyringResult result,
 	g_hash_table_insert (settings, g_strdup (r->setting_name), secrets);
 
 done:
-	r->get_callback (NM_SECRET_AGENT (r->agent), r->connection, error ? NULL : settings, error, r->callback_data);
-	request_free (r);
-
-	if (settings)
-		g_hash_table_destroy (settings);
-	g_clear_error (&error);
-}
-
-static void
-check_always_ask_cb (NMSetting *setting,
-                     const char *key,
-                     const GValue *value,
-                     GParamFlags flags,
-                     gpointer user_data)
-{
-	gboolean *always_ask = user_data;
-	NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED;
-
-	if (flags & NM_SETTING_PARAM_SECRET) {
-		if (nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) {
-			if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)
-				*always_ask = TRUE;
+	if (ask) {
+		GHashTableIter hash_iter;
+		const char *setting_name;
+		GHashTable *setting_hash;
+
+		/* Stuff all the found secrets into the connection for the UI to use */
+		g_hash_table_iter_init (&hash_iter, settings);
+		while (g_hash_table_iter_next (&hash_iter,
+		                               (gpointer *) &setting_name,
+		                               (gpointer *) &setting_hash)) {
+			nm_connection_update_secrets (r->connection,
+				                          setting_name,
+				                          setting_hash,
+				                          NULL);
 		}
-	}
-}
-
-static gboolean
-has_always_ask (NMSetting *setting)
-{
-	gboolean always_ask = FALSE;
-
-	nm_setting_enumerate_values (setting, check_always_ask_cb, &always_ask);
-	return always_ask;
-}
-
-static gboolean
-is_connection_always_ask (NMConnection *connection)
-{
-	NMSettingConnection *s_con;
-	const char *ctype;
-	NMSetting *setting;
-
-	/* For the given connection type, check if the secrets for that connection
-	 * are always-ask or not.
-	 */
-	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
-	g_assert (s_con);
-	ctype = nm_setting_connection_get_connection_type (s_con);
-
-	setting = nm_connection_get_setting_by_name (connection, ctype);
-	g_return_val_if_fail (setting != NULL, FALSE);
 
-	if (has_always_ask (setting))
-		return TRUE;
-
-	/* Try type-specific settings too; be a bit paranoid and only consider
-	 * secrets from settings relevant to the connection type.
-	 */
-	if (NM_IS_SETTING_WIRELESS (setting)) {
-		setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
-		if (setting && has_always_ask (setting))
-			return TRUE;
-		setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
-		if (setting && has_always_ask (setting))
-			return TRUE;
-	} else if (NM_IS_SETTING_WIRED (setting)) {
-		setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
-		if (setting && has_always_ask (setting))
-			return TRUE;
-		setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
-		if (setting && has_always_ask (setting))
-			return TRUE;
+		ask_for_secrets (r);
+	} else {
+		/* Otherwise send the secrets back to NetworkManager */
+		r->get_callback (NM_SECRET_AGENT (r->agent), r->connection, error ? NULL : settings, error, r->callback_data);
+		request_free (r);
 	}
 
-	return FALSE;
+	if (settings)
+		g_hash_table_destroy (settings);
+	g_clear_error (&error);
 }
 
 static void
@@ -395,7 +420,6 @@ get_secrets (NMSecretAgent *agent,
 	NMSetting *setting;
 	const char *id;
 	const char *ctype;
-	gboolean ask = FALSE;
 	KeyringCall *call;
 
 	setting = nm_connection_get_setting_by_name (connection, setting_name);
@@ -431,34 +455,26 @@ get_secrets (NMSecretAgent *agent,
 	g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r);
 
 	/* VPN passwords are handled by the VPN plugin's auth dialog */
-	if (!strcmp (ctype, NM_SETTING_VPN_SETTING_NAME))
-		ask = TRUE;
-	else if (flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW) {
-		ask = TRUE;
-		g_message ("New secrets for %s/%s requested; ask the user", id, setting_name);
-	} else if (   (flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION)
-	           && is_connection_always_ask (connection))
-		ask = TRUE;
-
-	/* VPN passwords are handled by the VPN plugin's auth dialog; and we always
-	 * get secrets for OTP connections marked as 'always ask'.
-	 */
-	if (ask)
+	if (!strcmp (ctype, NM_SETTING_VPN_SETTING_NAME)) {
 		ask_for_secrets (r);
-	else {
-		call = keyring_call_new (r);
-		call->keyring_id = gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET,
-		                                              keyring_find_secrets_cb,
-		                                              call,
-		                                              keyring_call_free,
-		                                              KEYRING_UUID_TAG,
-		                                              GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
-		                                              nm_setting_connection_get_uuid (s_con),
-		                                              KEYRING_SN_TAG,
-		                                              GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
-		                                              setting_name,
-		                                              NULL);
+		return;
 	}
+
+	/* For everything else we scrape the keyring for secrets first, and ask
+	 * later if required.
+	 */
+	call = keyring_call_new (r);
+	call->keyring_id = gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+	                                              keyring_find_secrets_cb,
+	                                              call,
+	                                              keyring_call_free,
+	                                              KEYRING_UUID_TAG,
+	                                              GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+	                                              nm_setting_connection_get_uuid (s_con),
+	                                              KEYRING_SN_TAG,
+	                                              GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+	                                              setting_name,
+	                                              NULL);
 }
 
 /*******************************************************/



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