From 30c7308e9d9f6db72023ecc6ccb8ea964fb563d9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 18 Jan 2011 13:20:34 -0600 Subject: [PATCH] libnm-glib: implement agent secrets request cancelation --- libnm-glib/nm-secret-agent.c | 73 ++++++++++++++++++++++++------------ libnm-glib/nm-secret-agent.h | 13 ++++++- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index 5308759d0b..d1c8b44988 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -36,6 +36,11 @@ static void impl_secret_agent_get_secrets (NMSecretAgent *self, gboolean request_new, DBusGMethodInvocation *context); +static void impl_secret_agent_cancel_get_secrets (NMSecretAgent *self, + const char *connection_path, + const char *setting_name, + DBusGMethodInvocation *context); + static void impl_secret_agent_save_secrets (NMSecretAgent *self, GHashTable *connection_hash, const char *connection_path, @@ -166,10 +171,12 @@ name_owner_changed (DBusGProxy *proxy, } } -static NMConnection * +static gboolean verify_request (NMSecretAgent *self, DBusGMethodInvocation *context, GHashTable *connection_hash, + const char *connection_path, + NMConnection **out_connection, GError **error) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); @@ -181,8 +188,7 @@ verify_request (NMSecretAgent *self, uid_t sender_uid = G_MAXUINT; GError *local = NULL; - g_return_val_if_fail (context != NULL, NULL); - g_return_val_if_fail (connection_hash != NULL, NULL); + g_return_val_if_fail (context != NULL, FALSE); /* Verify the sender's UID is 0, and that the sender is the same as * NetworkManager's bus name owner. @@ -245,21 +251,27 @@ verify_request (NMSecretAgent *self, } /* And make sure the connection is actually valid */ - connection = nm_connection_new_from_hash (connection_hash, &local); - if (!connection) { - g_set_error (error, - NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, - "Invalid connection: (%d) %s", - local ? local->code : -1, - (local && local->message) ? local->message : "(unknown)"); - g_clear_error (&local); + if (connection_hash) { + connection = nm_connection_new_from_hash (connection_hash, &local); + if (connection && connection_path) { + nm_connection_set_path (connection, connection_path); + } else { + g_set_error (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "Invalid connection: (%d) %s", + local ? local->code : -1, + (local && local->message) ? local->message : "(unknown)"); + g_clear_error (&local); + } } - out: + if (out_connection) + *out_connection = connection; g_free (sender); - return connection; + + return !!connection; } static void @@ -287,11 +299,10 @@ impl_secret_agent_get_secrets (NMSecretAgent *self, DBusGMethodInvocation *context) { GError *error = NULL; - NMConnection *connection; + NMConnection *connection = NULL; /* Make sure the request comes from NetworkManager and is valid */ - connection = verify_request (self, context, connection_hash, &error); - if (!connection) { + if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) { dbus_g_method_return_error (context, error); g_clear_error (&error); return; @@ -308,6 +319,24 @@ impl_secret_agent_get_secrets (NMSecretAgent *self, g_object_unref (connection); } +static void +impl_secret_agent_cancel_get_secrets (NMSecretAgent *self, + const char *connection_path, + const char *setting_name, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + + /* Make sure the request comes from NetworkManager and is valid */ + if (!verify_request (self, context, NULL, NULL, NULL, &error)) { + dbus_g_method_return_error (context, error); + g_clear_error (&error); + } else { + NM_SECRET_AGENT_GET_CLASS (self)->cancel_get_secrets (self, connection_path, setting_name); + dbus_g_method_return (context); + } +} + static void save_secrets_cb (NMSecretAgent *self, NMConnection *connection, @@ -329,11 +358,10 @@ impl_secret_agent_save_secrets (NMSecretAgent *self, DBusGMethodInvocation *context) { GError *error = NULL; - NMConnection *connection; + NMConnection *connection = NULL; /* Make sure the request comes from NetworkManager and is valid */ - connection = verify_request (self, context, connection_hash, &error); - if (!connection) { + if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) { dbus_g_method_return_error (context, error); g_clear_error (&error); return; @@ -368,11 +396,10 @@ impl_secret_agent_delete_secrets (NMSecretAgent *self, DBusGMethodInvocation *context) { GError *error = NULL; - NMConnection *connection; + NMConnection *connection = NULL; /* Make sure the request comes from NetworkManager and is valid */ - connection = verify_request (self, context, connection_hash, &error); - if (!connection) { + if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) { dbus_g_method_return_error (context, error); g_clear_error (&error); return; diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h index 98c90114d0..f62ebacd00 100644 --- a/libnm-glib/nm-secret-agent.h +++ b/libnm-glib/nm-secret-agent.h @@ -15,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2010 Red Hat, Inc. + * (C) Copyright 2010 - 2011 Red Hat, Inc. */ #ifndef NM_SECRET_AGENT_H @@ -80,7 +80,9 @@ typedef struct { /* Called when the subclass should retrieve and return secrets. Subclass * must copy or reference any arguments it may require after returning from * this method, as the arguments will freed (except for 'agent', 'callback', - * and 'callback_data' of course). + * and 'callback_data' of course). If the request is canceled, the callback + * should still be called, but with the NM_SECRET_AGENT_ERROR_AGENT_CANCELED + * error. */ void (*get_secrets) (NMSecretAgent *agent, NMConnection *connection, @@ -91,6 +93,13 @@ typedef struct { NMSecretAgentGetSecretsFunc callback, gpointer callback_data); + /* Called when the subclass should cancel an outstanding request to + * get secrets for a given connection. + */ + void (*cancel_get_secrets) (NMSecretAgent *agent, + const char *connection_path, + const char *setting_name); + /* Called when the subclass should save the secrets contained in the * connection to backing storage. Subclass must copy or reference any * arguments it may require after returning from this method, as the