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))
|
NMAgentManagerPrivate))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMDBusManager *dbus_mgr;
|
|
||||||
NMAuthManager *auth_mgr;
|
NMAuthManager *auth_mgr;
|
||||||
|
|
||||||
/* Auth chains for checking agent permissions */
|
/* Auth chains for checking agent permissions */
|
||||||
@@ -263,6 +262,14 @@ find_agent_by_identifier_and_uid (NMAgentManager *self,
|
|||||||
return NULL;
|
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
|
static void
|
||||||
impl_agent_manager_register_with_capabilities (NMAgentManager *self,
|
impl_agent_manager_register_with_capabilities (NMAgentManager *self,
|
||||||
const char *identifier,
|
const char *identifier,
|
||||||
@@ -305,6 +312,8 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self,
|
|||||||
"Failed to initialize the agent");
|
"Failed to initialize the agent");
|
||||||
goto done;
|
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_log_dbg (LOGD_AGENTS, "(%s) requesting permissions",
|
||||||
nm_secret_agent_get_description (agent));
|
nm_secret_agent_get_description (agent));
|
||||||
@@ -343,11 +352,10 @@ static void
|
|||||||
impl_agent_manager_unregister (NMAgentManager *self,
|
impl_agent_manager_unregister (NMAgentManager *self,
|
||||||
DBusGMethodInvocation *context)
|
DBusGMethodInvocation *context)
|
||||||
{
|
{
|
||||||
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
char *sender = 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,
|
context,
|
||||||
&sender,
|
&sender,
|
||||||
NULL,
|
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
|
static void
|
||||||
agent_permissions_changed_done (NMAuthChain *chain,
|
agent_permissions_changed_done (NMAuthChain *chain,
|
||||||
GError *error,
|
GError *error,
|
||||||
@@ -1550,16 +1545,10 @@ constructed (GObject *object)
|
|||||||
|
|
||||||
G_OBJECT_CLASS (nm_agent_manager_parent_class)->constructed (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 ());
|
priv->auth_mgr = g_object_ref (nm_auth_manager_get ());
|
||||||
|
|
||||||
nm_exported_object_export (NM_EXPORTED_OBJECT (object));
|
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,
|
g_signal_connect (priv->auth_mgr,
|
||||||
NM_AUTH_MANAGER_SIGNAL_CHANGED,
|
NM_AUTH_MANAGER_SIGNAL_CHANGED,
|
||||||
G_CALLBACK (authority_changed_cb),
|
G_CALLBACK (authority_changed_cb),
|
||||||
@@ -1589,13 +1578,8 @@ dispose (GObject *object)
|
|||||||
object);
|
object);
|
||||||
g_clear_object (&priv->auth_mgr);
|
g_clear_object (&priv->auth_mgr);
|
||||||
}
|
}
|
||||||
if (priv->dbus_mgr) {
|
|
||||||
g_signal_handlers_disconnect_by_func (priv->dbus_mgr,
|
nm_exported_object_unexport (NM_EXPORTED_OBJECT (object));
|
||||||
G_CALLBACK (name_owner_changed_cb),
|
|
||||||
object);
|
|
||||||
nm_exported_object_unexport (NM_EXPORTED_OBJECT (object));
|
|
||||||
g_clear_object (&priv->dbus_mgr);
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object);
|
G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
@@ -47,17 +47,24 @@ typedef struct {
|
|||||||
NMAuthSubject *subject;
|
NMAuthSubject *subject;
|
||||||
char *identifier;
|
char *identifier;
|
||||||
char *owner_username;
|
char *owner_username;
|
||||||
|
char *dbus_owner;
|
||||||
NMSecretAgentCapabilities capabilities;
|
NMSecretAgentCapabilities capabilities;
|
||||||
guint32 hash;
|
guint32 hash;
|
||||||
|
|
||||||
GSList *permissions;
|
GSList *permissions;
|
||||||
|
|
||||||
DBusGProxy *proxy;
|
DBusGProxy *proxy;
|
||||||
guint proxy_destroy_id;
|
|
||||||
|
|
||||||
GHashTable *requests;
|
GHashTable *requests;
|
||||||
} NMSecretAgentPrivate;
|
} NMSecretAgentPrivate;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DISCONNECTED,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -107,7 +114,7 @@ nm_secret_agent_get_description (NMSecretAgent *agent)
|
|||||||
priv = NM_SECRET_AGENT_GET_PRIVATE (agent);
|
priv = NM_SECRET_AGENT_GET_PRIVATE (agent);
|
||||||
if (!priv->description) {
|
if (!priv->description) {
|
||||||
priv->description = g_strdup_printf ("%s/%s/%lu",
|
priv->description = g_strdup_printf ("%s/%s/%lu",
|
||||||
nm_auth_subject_get_unix_process_dbus_sender (priv->subject),
|
priv->dbus_owner,
|
||||||
priv->identifier,
|
priv->identifier,
|
||||||
nm_auth_subject_get_unix_process_uid (priv->subject));
|
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);
|
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 *
|
const char *
|
||||||
@@ -450,15 +457,35 @@ nm_secret_agent_delete_secrets (NMSecretAgent *self,
|
|||||||
callback_data);
|
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
|
static void
|
||||||
proxy_cleanup (NMSecretAgent *self)
|
proxy_cleanup (NMSecretAgent *self)
|
||||||
{
|
{
|
||||||
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
|
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
|
||||||
|
|
||||||
if (priv->proxy) {
|
if (priv->proxy) {
|
||||||
g_signal_handler_disconnect (priv->proxy, priv->proxy_destroy_id);
|
g_signal_handlers_disconnect_by_func (priv->proxy, proxy_cleanup, self);
|
||||||
priv->proxy_destroy_id = 0;
|
|
||||||
g_clear_object (&priv->proxy);
|
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;
|
NMSecretAgent *self;
|
||||||
NMSecretAgentPrivate *priv;
|
NMSecretAgentPrivate *priv;
|
||||||
char *hash_str, *username;
|
char *hash_str;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
|
||||||
g_return_val_if_fail (context != NULL, NULL);
|
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));
|
pw = getpwuid (nm_auth_subject_get_unix_process_uid (subject));
|
||||||
g_return_val_if_fail (pw != NULL, NULL);
|
g_return_val_if_fail (pw != NULL, NULL);
|
||||||
g_return_val_if_fail (pw->pw_name[0] != '\0', 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);
|
self = (NMSecretAgent *) g_object_new (NM_TYPE_SECRET_AGENT, NULL);
|
||||||
priv = NM_SECRET_AGENT_GET_PRIVATE (self);
|
priv = NM_SECRET_AGENT_GET_PRIVATE (self);
|
||||||
|
|
||||||
priv->identifier = g_strdup (identifier);
|
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->capabilities = capabilities;
|
||||||
priv->subject = g_object_ref (subject);
|
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 (),
|
priv->proxy = nm_dbus_manager_new_proxy (nm_dbus_manager_get (),
|
||||||
context,
|
context,
|
||||||
nm_auth_subject_get_unix_process_dbus_sender (subject),
|
priv->dbus_owner,
|
||||||
NM_DBUS_PATH_SECRET_AGENT,
|
NM_DBUS_PATH_SECRET_AGENT,
|
||||||
NM_DBUS_INTERFACE_SECRET_AGENT);
|
NM_DBUS_INTERFACE_SECRET_AGENT);
|
||||||
g_assert (priv->proxy);
|
g_assert (priv->proxy);
|
||||||
priv->proxy_destroy_id = g_signal_connect_swapped (priv->proxy, "destroy",
|
g_signal_connect_swapped (priv->proxy, "destroy",
|
||||||
G_CALLBACK (proxy_cleanup), self);
|
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;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,5 +585,15 @@ nm_secret_agent_class_init (NMSecretAgentClass *config_class)
|
|||||||
/* virtual methods */
|
/* virtual methods */
|
||||||
object_class->dispose = dispose;
|
object_class->dispose = dispose;
|
||||||
object_class->finalize = finalize;
|
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_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_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass))
|
||||||
|
|
||||||
|
#define NM_SECRET_AGENT_DISCONNECTED "disconnected"
|
||||||
|
|
||||||
struct _NMSecretAgent {
|
struct _NMSecretAgent {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GObjectClass parent;
|
GObjectClass parent;
|
||||||
|
|
||||||
|
void (*disconnected) (NMSecretAgent *self);
|
||||||
} NMSecretAgentClass;
|
} NMSecretAgentClass;
|
||||||
|
|
||||||
GType nm_secret_agent_get_type (void);
|
GType nm_secret_agent_get_type (void);
|
||||||
|
Reference in New Issue
Block a user