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.
This commit is contained in:
Dan Williams
2011-07-01 14:34:08 -05:00
parent 85708fa5d7
commit ded905ceb1

View File

@@ -49,6 +49,9 @@ typedef struct {
NMDBusManager *dbus_mgr; NMDBusManager *dbus_mgr;
NMSessionMonitor *session_monitor; NMSessionMonitor *session_monitor;
/* Auth chains for checking agent permissions */
GSList *chains;
/* Hashed by owner name, not identifier, since two agents in different /* Hashed by owner name, not identifier, since two agents in different
* sessions can use the same identifier. * sessions can use the same identifier.
*/ */
@@ -225,6 +228,59 @@ validate_identifier (const char *identifier, GError **error)
return TRUE; 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 static void
impl_agent_manager_register (NMAgentManager *self, impl_agent_manager_register (NMAgentManager *self,
const char *identifier, const char *identifier,
@@ -235,8 +291,7 @@ impl_agent_manager_register (NMAgentManager *self,
gulong sender_uid = G_MAXULONG; gulong sender_uid = G_MAXULONG;
GError *error = NULL, *local = NULL; GError *error = NULL, *local = NULL;
NMSecretAgent *agent; NMSecretAgent *agent;
GHashTableIter iter; NMAuthChain *chain;
gpointer data;
if (!nm_auth_get_caller_uid (context, if (!nm_auth_get_caller_uid (context,
priv->dbus_mgr, priv->dbus_mgr,
@@ -280,18 +335,16 @@ impl_agent_manager_register (NMAgentManager *self,
goto done; goto done;
} }
g_hash_table_insert (priv->agents, g_strdup (sender), agent); nm_log_dbg (LOGD_AGENTS, "(%s) requesting permissions",
nm_log_dbg (LOGD_AGENTS, "(%s) agent registered",
nm_secret_agent_get_description (agent)); nm_secret_agent_get_description (agent));
dbus_g_method_return (context);
/* Signal an agent was registered */ /* Kick off permissions requests for this agent */
g_signal_emit (self, signals[AGENT_REGISTERED], 0, 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 */ priv->chains = g_slist_append (priv->chains, chain);
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);
done: done:
if (error) 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 * NMAgentManager *
@@ -1331,6 +1451,8 @@ nm_agent_manager_get (void)
G_CALLBACK (name_owner_changed_cb), G_CALLBACK (name_owner_changed_cb),
singleton); singleton);
nm_auth_changed_func_register (authority_changed_cb, singleton);
return singleton; return singleton;
} }
@@ -1354,6 +1476,10 @@ dispose (GObject *object)
if (!priv->disposed) { if (!priv->disposed) {
priv->disposed = TRUE; 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->agents);
g_hash_table_destroy (priv->requests); g_hash_table_destroy (priv->requests);