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:
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user