From ded905ceb17860d9cb1527de5a81ab91b022995d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 1 Jul 2011 14:34:08 -0500 Subject: [PATCH] agents: track agent wifi permissions When an agent registers, request wifi sharing permissions for that agent's user and only register the agent when the permissions are known. --- src/settings/nm-agent-manager.c | 148 +++++++++++++++++++++++++++++--- 1 file changed, 137 insertions(+), 11 deletions(-) diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 1693ae25b..7d3960abd 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -49,6 +49,9 @@ typedef struct { NMDBusManager *dbus_mgr; NMSessionMonitor *session_monitor; + /* Auth chains for checking agent permissions */ + GSList *chains; + /* Hashed by owner name, not identifier, since two agents in different * sessions can use the same identifier. */ @@ -225,6 +228,59 @@ validate_identifier (const char *identifier, GError **error) return TRUE; } +static void +agent_register_permissions_done (NMAuthChain *chain, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + NMAgentManager *self = NM_AGENT_MANAGER (user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + NMSecretAgent *agent; + const char *sender; + GError *local = NULL; + NMAuthCallResult result; + GHashTableIter iter; + Request *req; + + priv->chains = g_slist_remove (priv->chains, chain); + + if (error) { + local = g_error_new (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, + "Failed to request agent permissions: (%d) %s", + error->code, error->message); + dbus_g_method_return_error (context, local); + g_error_free (local); + } else { + agent = nm_auth_chain_steal_data (chain, "agent"); + + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED); + if (result == NM_AUTH_CALL_RESULT_YES) + nm_secret_agent_add_permission (agent, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, TRUE); + + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN); + if (result == NM_AUTH_CALL_RESULT_YES) + nm_secret_agent_add_permission (agent, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, TRUE); + + sender = nm_secret_agent_get_dbus_owner (agent); + g_hash_table_insert (priv->agents, g_strdup (sender), agent); + nm_log_dbg (LOGD_AGENTS, "(%s) agent registered", + nm_secret_agent_get_description (agent)); + dbus_g_method_return (context); + + /* Signal an agent was registered */ + g_signal_emit (self, signals[AGENT_REGISTERED], 0, agent); + + /* Add this agent to any in-progress secrets requests */ + g_hash_table_iter_init (&iter, priv->requests); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &req)) + request_add_agent (req, agent, priv->session_monitor); + } + + nm_auth_chain_unref (chain); +} + static void impl_agent_manager_register (NMAgentManager *self, const char *identifier, @@ -235,8 +291,7 @@ impl_agent_manager_register (NMAgentManager *self, gulong sender_uid = G_MAXULONG; GError *error = NULL, *local = NULL; NMSecretAgent *agent; - GHashTableIter iter; - gpointer data; + NMAuthChain *chain; if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, @@ -280,18 +335,16 @@ impl_agent_manager_register (NMAgentManager *self, goto done; } - g_hash_table_insert (priv->agents, g_strdup (sender), agent); - nm_log_dbg (LOGD_AGENTS, "(%s) agent registered", + nm_log_dbg (LOGD_AGENTS, "(%s) requesting permissions", nm_secret_agent_get_description (agent)); - dbus_g_method_return (context); - /* Signal an agent was registered */ - g_signal_emit (self, signals[AGENT_REGISTERED], 0, agent); + /* Kick off permissions requests for this agent */ + chain = nm_auth_chain_new (context, NULL, agent_register_permissions_done, self); + nm_auth_chain_set_data (chain, "agent", agent, g_object_unref); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE); - /* Add this agent to any in-progress secrets requests */ - g_hash_table_iter_init (&iter, priv->requests); - while (g_hash_table_iter_next (&iter, NULL, &data)) - request_add_agent ((Request *) data, agent, priv->session_monitor); + priv->chains = g_slist_append (priv->chains, chain); done: if (error) @@ -1302,6 +1355,73 @@ name_owner_changed_cb (NMDBusManager *dbus_mgr, } } +static void +agent_permissions_changed_done (NMAuthChain *chain, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + NMAgentManager *self = NM_AGENT_MANAGER (user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + NMSecretAgent *agent; + NMAuthCallResult result; + + priv->chains = g_slist_remove (priv->chains, chain); + + agent = nm_auth_chain_get_data (chain, "agent"); + + if (error) { + nm_log_dbg (LOGD_AGENTS, "(%s) failed to request updated agent permissions", + nm_secret_agent_get_description (agent)); + nm_secret_agent_add_permission (agent, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE); + nm_secret_agent_add_permission (agent, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE); + } else { + nm_log_dbg (LOGD_AGENTS, "(%s) updated agent permissions", + nm_secret_agent_get_description (agent)); + + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED); + nm_secret_agent_add_permission (agent, + NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, + (result == NM_AUTH_CALL_RESULT_YES)); + + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN); + nm_secret_agent_add_permission (agent, + NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, + (result == NM_AUTH_CALL_RESULT_YES)); + } + + nm_auth_chain_unref (chain); +} + +static void +authority_changed_cb (gpointer user_data) +{ + NMAgentManager *self = NM_AGENT_MANAGER (user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + GHashTableIter iter; + NMSecretAgent *agent; + + /* Recheck the permissions of all secret agents */ + g_hash_table_iter_init (&iter, priv->agents); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &agent)) { + NMAuthChain *chain; + const char *sender; + + /* Kick off permissions requests for this agent */ + sender = nm_secret_agent_get_dbus_owner (agent); + chain = nm_auth_chain_new_dbus_sender (sender, agent_permissions_changed_done, self); + + /* Make sure if the agent quits while the permissions call is in progress + * that the object sticks around until our callback. + */ + nm_auth_chain_set_data (chain, "agent", g_object_ref (agent), g_object_unref); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE); + + priv->chains = g_slist_append (priv->chains, chain); + } +} + /*************************************************************/ NMAgentManager * @@ -1331,6 +1451,8 @@ nm_agent_manager_get (void) G_CALLBACK (name_owner_changed_cb), singleton); + nm_auth_changed_func_register (authority_changed_cb, singleton); + return singleton; } @@ -1354,6 +1476,10 @@ dispose (GObject *object) if (!priv->disposed) { priv->disposed = TRUE; + nm_auth_changed_func_unregister (authority_changed_cb, NM_AGENT_MANAGER (object)); + + g_slist_foreach (priv->chains, (GFunc) nm_auth_chain_unref, NULL); + g_hash_table_destroy (priv->agents); g_hash_table_destroy (priv->requests);