settings: rework NMSecretAgent disconnection detection

Have NMSecretAgent emit "disconnected" when it detects that it has
been disconnected, rather than having both the agent and the agent
manager monitor it separately.
This commit is contained in:
Dan Winship
2015-04-27 14:54:32 -04:00
parent 1bcf42f37b
commit 2a2fd1216b
3 changed files with 69 additions and 41 deletions

View File

@@ -50,7 +50,6 @@ G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, NM_TYPE_EXPORTED_OBJECT)
NMAgentManagerPrivate))
typedef struct {
NMDBusManager *dbus_mgr;
NMAuthManager *auth_mgr;
/* Auth chains for checking agent permissions */
@@ -263,6 +262,14 @@ find_agent_by_identifier_and_uid (NMAgentManager *self,
return NULL;
}
static void
agent_disconnected_cb (NMSecretAgent *agent, gpointer user_data)
{
/* The agent quit, so remove it and let interested clients know */
remove_agent (NM_AGENT_MANAGER (user_data),
nm_secret_agent_get_dbus_owner (agent));
}
static void
impl_agent_manager_register_with_capabilities (NMAgentManager *self,
const char *identifier,
@@ -305,6 +312,8 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self,
"Failed to initialize the agent");
goto done;
}
g_signal_connect (agent, NM_SECRET_AGENT_DISCONNECTED,
G_CALLBACK (agent_disconnected_cb), self);
nm_log_dbg (LOGD_AGENTS, "(%s) requesting permissions",
nm_secret_agent_get_description (agent));
@@ -343,11 +352,10 @@ static void
impl_agent_manager_unregister (NMAgentManager *self,
DBusGMethodInvocation *context)
{
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
GError *error = NULL;
char *sender = NULL;
if (!nm_dbus_manager_get_caller_info (priv->dbus_mgr,
if (!nm_dbus_manager_get_caller_info (nm_dbus_manager_get (),
context,
&sender,
NULL,
@@ -1450,19 +1458,6 @@ nm_agent_manager_all_agents_have_capability (NMAgentManager *manager,
/*************************************************************/
static void
name_owner_changed_cb (NMDBusManager *dbus_mgr,
const char *name,
const char *old_owner,
const char *new_owner,
gpointer user_data)
{
if (old_owner) {
/* The agent quit, so remove it and let interested clients know */
remove_agent (NM_AGENT_MANAGER (user_data), old_owner);
}
}
static void
agent_permissions_changed_done (NMAuthChain *chain,
GError *error,
@@ -1550,16 +1545,10 @@ constructed (GObject *object)
G_OBJECT_CLASS (nm_agent_manager_parent_class)->constructed (object);
priv->dbus_mgr = g_object_ref (nm_dbus_manager_get ());
priv->auth_mgr = g_object_ref (nm_auth_manager_get ());
nm_exported_object_export (NM_EXPORTED_OBJECT (object));
g_signal_connect (priv->dbus_mgr,
NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
G_CALLBACK (name_owner_changed_cb),
object);
g_signal_connect (priv->auth_mgr,
NM_AUTH_MANAGER_SIGNAL_CHANGED,
G_CALLBACK (authority_changed_cb),
@@ -1589,13 +1578,8 @@ dispose (GObject *object)
object);
g_clear_object (&priv->auth_mgr);
}
if (priv->dbus_mgr) {
g_signal_handlers_disconnect_by_func (priv->dbus_mgr,
G_CALLBACK (name_owner_changed_cb),
object);
nm_exported_object_unexport (NM_EXPORTED_OBJECT (object));
g_clear_object (&priv->dbus_mgr);
}
nm_exported_object_unexport (NM_EXPORTED_OBJECT (object));
G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object);
}

View File

@@ -47,17 +47,24 @@ typedef struct {
NMAuthSubject *subject;
char *identifier;
char *owner_username;
char *dbus_owner;
NMSecretAgentCapabilities capabilities;
guint32 hash;
GSList *permissions;
DBusGProxy *proxy;
guint proxy_destroy_id;
GHashTable *requests;
} NMSecretAgentPrivate;
enum {
DISCONNECTED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
/*************************************************************/
typedef struct {
@@ -107,7 +114,7 @@ nm_secret_agent_get_description (NMSecretAgent *agent)
priv = NM_SECRET_AGENT_GET_PRIVATE (agent);
if (!priv->description) {
priv->description = g_strdup_printf ("%s/%s/%lu",
nm_auth_subject_get_unix_process_dbus_sender (priv->subject),
priv->dbus_owner,
priv->identifier,
nm_auth_subject_get_unix_process_uid (priv->subject));
}
@@ -120,7 +127,7 @@ nm_secret_agent_get_dbus_owner (NMSecretAgent *agent)
{
g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL);
return nm_auth_subject_get_unix_process_dbus_sender (NM_SECRET_AGENT_GET_PRIVATE (agent)->subject);
return NM_SECRET_AGENT_GET_PRIVATE (agent)->dbus_owner;
}
const char *
@@ -450,15 +457,35 @@ nm_secret_agent_delete_secrets (NMSecretAgent *self,
callback_data);
}
static void proxy_cleanup (NMSecretAgent *self);
static void
name_owner_changed_cb (NMDBusManager *dbus_mgr,
const char *name,
const char *old_owner,
const char *new_owner,
gpointer user_data)
{
NMSecretAgent *self = NM_SECRET_AGENT (user_data);
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
if (!new_owner && !g_strcmp0 (old_owner, priv->dbus_owner))
proxy_cleanup (self);
}
static void
proxy_cleanup (NMSecretAgent *self)
{
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
if (priv->proxy) {
g_signal_handler_disconnect (priv->proxy, priv->proxy_destroy_id);
priv->proxy_destroy_id = 0;
g_signal_handlers_disconnect_by_func (priv->proxy, proxy_cleanup, self);
g_clear_object (&priv->proxy);
g_signal_handlers_disconnect_by_func (nm_dbus_manager_get (), name_owner_changed_cb, self);
g_clear_pointer (&priv->dbus_owner, g_free);
g_signal_emit (self, signals[DISCONNECTED], 0);
}
}
@@ -472,7 +499,7 @@ nm_secret_agent_new (DBusGMethodInvocation *context,
{
NMSecretAgent *self;
NMSecretAgentPrivate *priv;
char *hash_str, *username;
char *hash_str;
struct passwd *pw;
g_return_val_if_fail (context != NULL, NULL);
@@ -483,13 +510,13 @@ nm_secret_agent_new (DBusGMethodInvocation *context,
pw = getpwuid (nm_auth_subject_get_unix_process_uid (subject));
g_return_val_if_fail (pw != NULL, NULL);
g_return_val_if_fail (pw->pw_name[0] != '\0', NULL);
username = g_strdup (pw->pw_name);
self = (NMSecretAgent *) g_object_new (NM_TYPE_SECRET_AGENT, NULL);
priv = NM_SECRET_AGENT_GET_PRIVATE (self);
priv->identifier = g_strdup (identifier);
priv->owner_username = g_strdup (username);
priv->owner_username = g_strdup (pw->pw_name);
priv->dbus_owner = g_strdup (nm_auth_subject_get_unix_process_dbus_sender (subject));
priv->capabilities = capabilities;
priv->subject = g_object_ref (subject);
@@ -499,14 +526,17 @@ nm_secret_agent_new (DBusGMethodInvocation *context,
priv->proxy = nm_dbus_manager_new_proxy (nm_dbus_manager_get (),
context,
nm_auth_subject_get_unix_process_dbus_sender (subject),
priv->dbus_owner,
NM_DBUS_PATH_SECRET_AGENT,
NM_DBUS_INTERFACE_SECRET_AGENT);
g_assert (priv->proxy);
priv->proxy_destroy_id = g_signal_connect_swapped (priv->proxy, "destroy",
G_CALLBACK (proxy_cleanup), self);
g_signal_connect_swapped (priv->proxy, "destroy",
G_CALLBACK (proxy_cleanup), self);
g_signal_connect (nm_dbus_manager_get (),
NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
G_CALLBACK (name_owner_changed_cb),
self);
g_free (username);
return self;
}
@@ -555,5 +585,15 @@ nm_secret_agent_class_init (NMSecretAgentClass *config_class)
/* virtual methods */
object_class->dispose = dispose;
object_class->finalize = finalize;
/* signals */
signals[DISCONNECTED] =
g_signal_new (NM_SECRET_AGENT_DISCONNECTED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSecretAgentClass, disconnected),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}

View File

@@ -33,12 +33,16 @@
#define NM_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SECRET_AGENT))
#define NM_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass))
#define NM_SECRET_AGENT_DISCONNECTED "disconnected"
struct _NMSecretAgent {
GObject parent;
};
typedef struct {
GObjectClass parent;
void (*disconnected) (NMSecretAgent *self);
} NMSecretAgentClass;
GType nm_secret_agent_get_type (void);