[network-manager-applet/rm-userset] applet: track keyring requests for possible cancelation
- From: Dan Williams <dcbw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-applet/rm-userset] applet: track keyring requests for possible cancelation
- Date: Thu, 20 Jan 2011 06:17:57 +0000 (UTC)
commit ab2515d53c4fe24984dbed28a0caa574bcb1ca76
Author: Dan Williams <dcbw redhat com>
Date: Wed Jan 19 18:01:27 2011 -0600
applet: track keyring requests for possible cancelation
Since the keyring doesn't pass the request ID to the callback of
the request, we have to track it via a small allocated structure.
Yay for the keyring.
Previously the SaveSecrets handler would overwrite the keyring id
of a previous operation if multiple secrets were to be saved. This
fixes that issue.
src/applet-agent.c | 126 ++++++++++++++++++++++++++++++++++++---------------
1 files changed, 89 insertions(+), 37 deletions(-)
---
diff --git a/src/applet-agent.c b/src/applet-agent.c
index a473603..4cb908c 100644
--- a/src/applet-agent.c
+++ b/src/applet-agent.c
@@ -96,7 +96,7 @@ typedef struct {
NMSecretAgentDeleteSecretsFunc delete_callback;
gpointer callback_data;
- gpointer keyring_id;
+ GSList *keyring_ids;
guint32 op_count;
gboolean canceled;
} Request;
@@ -139,6 +139,7 @@ request_free (Request *r)
g_hash_table_remove (APPLET_AGENT_GET_PRIVATE (r->agent)->requests, GUINT_TO_POINTER (r->id));
g_object_unref (r->connection);
+ g_slist_free (r->keyring_ids);
g_free (r->path);
g_free (r->setting_name);
g_strfreev (r->hints);
@@ -146,6 +147,38 @@ request_free (Request *r)
g_slice_free (Request, r);
}
+
+/*************************************************************/
+
+/* The keyring doesn't pass the call ID to the callback for the
+ * operation which the call ID represents, so we have to track
+ * it with a small structure. Ugh.
+ */
+
+typedef struct {
+ Request *r;
+ gpointer keyring_id;
+} KeyringCall;
+
+static inline KeyringCall *
+keyring_call_new (Request *r)
+{
+ KeyringCall *call;
+
+ call = g_malloc0 (sizeof (KeyringCall));
+ call->r = r;
+ return call;
+}
+
+static inline void
+keyring_call_free (gpointer data)
+{
+ KeyringCall *call = data;
+
+ memset (call, 0, sizeof (*call));
+ g_free (call);
+}
+
/*******************************************************/
static void
@@ -240,7 +273,8 @@ keyring_find_secrets_cb (GnomeKeyringResult result,
GList *list,
gpointer user_data)
{
- Request *r = user_data;
+ KeyringCall *call = user_data;
+ Request *r = call->r;
GError *error = NULL;
NMSettingConnection *s_con;
const char *connection_id = NULL;
@@ -248,6 +282,8 @@ keyring_find_secrets_cb (GnomeKeyringResult result,
GList *iter;
gboolean hint_found = FALSE;
+ r->keyring_ids = g_slist_remove (r->keyring_ids, call->keyring_id);
+
if (r->canceled) {
/* Callback already called by cancelation handler */
request_free (r);
@@ -347,6 +383,7 @@ get_secrets (NMSecretAgent *agent,
const char *id;
const char *ctype;
gboolean ask = FALSE;
+ KeyringCall *call;
setting = nm_connection_get_setting_by_name (connection, setting_name);
if (!setting) {
@@ -395,17 +432,18 @@ get_secrets (NMSecretAgent *agent,
if (ask)
ask_for_secrets (r);
else {
- r->keyring_id = gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET,
- keyring_find_secrets_cb,
- r,
- NULL,
- 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);
+ 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);
}
}
@@ -434,11 +472,15 @@ cancel_get_secrets (NMSecretAgent *agent,
/* Cancel any matching GetSecrets call */
if (!g_strcmp0 (r->path, connection_path) && !g_strcmp0 (r->setting_name, setting_name)) {
+ GSList *kiter;
+
+ /* cancel outstanding keyring operations */
+ for (kiter = r->keyring_ids; kiter; kiter = g_slist_next (kiter))
+ gnome_keyring_cancel_request (kiter->data);
+ g_slist_free (r->keyring_ids);
+ r->keyring_ids = NULL;
+
r->canceled = TRUE;
- if (r->keyring_id) {
- gnome_keyring_cancel_request (r->keyring_id);
- r->keyring_id = NULL;
- }
r->get_callback (NM_SECRET_AGENT (r->agent), r->connection, NULL, error, r->callback_data);
g_hash_table_remove (priv->requests, GUINT_TO_POINTER (r->id));
g_signal_emit (r->agent, signals[CANCEL_SECRETS], 0, GUINT_TO_POINTER (r->id));
@@ -453,7 +495,10 @@ cancel_get_secrets (NMSecretAgent *agent,
static void
save_secret_cb (GnomeKeyringResult result, guint val, gpointer user_data)
{
- Request *r = user_data;
+ KeyringCall *call = user_data;
+ Request *r = call->r;
+
+ r->keyring_ids = g_slist_remove (r->keyring_ids, call->keyring_id);
/* Only call the SaveSecrets callback and free the request when all the
* secrets have been saved to the keyring.
@@ -478,6 +523,7 @@ write_one_secret_to_keyring (NMSetting *setting,
const char *setting_name;
GnomeKeyringAttributeList *attrs;
char *display_name = NULL;
+ KeyringCall *call;
/* non-secrets and private key paths don't get stored in the keyring */
if ( !(flags & NM_SETTING_PARAM_SECRET)
@@ -506,15 +552,16 @@ write_one_secret_to_keyring (NMSetting *setting,
key,
&display_name);
g_assert (attrs);
- r->keyring_id = gnome_keyring_item_create (NULL,
- GNOME_KEYRING_ITEM_GENERIC_SECRET,
- display_name,
- attrs,
- secret,
- TRUE,
- save_secret_cb,
- r,
- NULL);
+ call = keyring_call_new (r);
+ call->keyring_id = gnome_keyring_item_create (NULL,
+ GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ display_name,
+ attrs,
+ secret,
+ TRUE,
+ save_secret_cb,
+ call,
+ keyring_call_free);
r->op_count++;
gnome_keyring_attribute_list_free (attrs);
g_free (display_name);
@@ -552,12 +599,15 @@ save_secrets (NMSecretAgent *agent,
/*******************************************************/
static void
-delete_find_items_cb (GnomeKeyringResult result, GList *list, gpointer data)
+delete_find_items_cb (GnomeKeyringResult result, GList *list, gpointer user_data)
{
- Request *r = data;
+ KeyringCall *call = user_data;
+ Request *r = call->r;
GList *iter;
GError *error = NULL;
+ r->keyring_ids = g_slist_remove (r->keyring_ids, call->keyring_id);
+
if ((result == GNOME_KEYRING_RESULT_OK) || (result == GNOME_KEYRING_RESULT_NO_MATCH)) {
for (iter = list; iter != NULL; iter = g_list_next (iter)) {
GnomeKeyringFound *found = (GnomeKeyringFound *) iter->data;
@@ -586,6 +636,7 @@ delete_secrets (NMSecretAgent *agent,
Request *r;
NMSettingConnection *s_con;
const char *uuid;
+ KeyringCall *call;
r = request_new (agent, connection, connection_path, NULL, NULL, FALSE, NULL, NULL, callback, callback_data);
g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r);
@@ -595,14 +646,15 @@ delete_secrets (NMSecretAgent *agent,
uuid = nm_setting_connection_get_uuid (s_con);
g_assert (uuid);
- r->keyring_id = gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET,
- delete_find_items_cb,
- r,
- NULL,
- KEYRING_UUID_TAG,
- GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
- uuid,
- NULL);
+ call = keyring_call_new (r);
+ call->keyring_id = gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ delete_find_items_cb,
+ call,
+ keyring_call_free,
+ KEYRING_UUID_TAG,
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+ uuid,
+ NULL);
}
/*******************************************************/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]