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