summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2011-01-19 16:59:01 -0600
committerDan Williams <dcbw@redhat.com>2011-01-19 16:59:01 -0600
commit7ddf9c5e724527c49435f5242cb603301521b746 (patch)
tree14bcc4e461a8ff4cc5b96c45283b8a7f5ecd48fe
parent85409427beac38ac0c8586dc37d422c3b3a8d7b6 (diff)
libnm-glib: implement NMSecretAgent autoregistration
Handles registering with NM and re-registering if NM restarts.
-rw-r--r--libnm-glib/libnm-glib.ver1
-rw-r--r--libnm-glib/nm-secret-agent.c86
-rw-r--r--libnm-glib/nm-secret-agent.h3
3 files changed, 84 insertions, 6 deletions
diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver
index c31dc798d..e64569596 100644
--- a/libnm-glib/libnm-glib.ver
+++ b/libnm-glib/libnm-glib.ver
@@ -151,7 +151,6 @@ global:
nm_secret_agent_error_quark;
nm_secret_agent_get_secrets;
nm_secret_agent_get_type;
- nm_secret_agent_new;
nm_secret_agent_register;
nm_secret_agent_save_secrets;
nm_secret_agent_unregister;
diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c
index cfe13dae8..72431e2da 100644
--- a/libnm-glib/nm-secret-agent.c
+++ b/libnm-glib/nm-secret-agent.c
@@ -53,12 +53,14 @@ static void impl_secret_agent_delete_secrets (NMSecretAgent *self,
#include "nm-secret-agent-glue.h"
-G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT)
+G_DEFINE_ABSTRACT_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT)
#define NM_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SECRET_AGENT, \
NMSecretAgentPrivate))
+static gboolean auto_register_cb (gpointer user_data);
+
typedef struct {
gboolean registered;
@@ -70,6 +72,9 @@ typedef struct {
char *nm_owner;
char *identifier;
+ gboolean auto_register;
+ gboolean suppress_auto;
+ gboolean auto_register_id;
gboolean disposed;
} NMSecretAgentPrivate;
@@ -77,6 +82,7 @@ typedef struct {
enum {
PROP_0,
PROP_IDENTIFIER,
+ PROP_AUTO_REGISTER,
LAST_PROP
};
@@ -156,6 +162,17 @@ get_nm_owner (NMSecretAgent *self)
}
static void
+_internal_unregister (NMSecretAgent *self)
+{
+ NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
+
+ if (priv->registered) {
+ dbus_g_connection_unregister_g_object (priv->bus, G_OBJECT (self));
+ priv->registered = FALSE;
+ }
+}
+
+static void
name_owner_changed (DBusGProxy *proxy,
const char *name,
const char *old_owner,
@@ -164,10 +181,24 @@ name_owner_changed (DBusGProxy *proxy,
{
NMSecretAgent *self = NM_SECRET_AGENT (user_data);
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
+ gboolean old_owner_good = (old_owner && strlen (old_owner));
+ gboolean new_owner_good = (new_owner && strlen (new_owner));
if (strcmp (name, NM_DBUS_SERVICE) == 0) {
g_free (priv->nm_owner);
priv->nm_owner = g_strdup (new_owner);
+
+ if (!old_owner_good && new_owner_good) {
+ /* NM appeared */
+ auto_register_cb (self);
+ } else if (old_owner_good && !new_owner_good) {
+ /* NM disappeared */
+ _internal_unregister (self);
+ } else if (old_owner_good && new_owner_good && strcmp (old_owner, new_owner)) {
+ /* Hmm, NM magically restarted */
+ _internal_unregister (self);
+ auto_register_cb (self);
+ }
}
}
@@ -430,7 +461,7 @@ reg_request_cb (DBusGProxy *proxy,
priv->registered = TRUE;
else {
/* If registration failed we shouldn't expose ourselves on the bus */
- dbus_g_connection_unregister_g_object (priv->bus, G_OBJECT (self));
+ _internal_unregister (self);
}
g_signal_emit (self, signals[REGISTRATION_RESULT], 0, error);
@@ -472,6 +503,8 @@ nm_secret_agent_register (NMSecretAgent *self)
g_return_val_if_fail (class->save_secrets != NULL, FALSE);
g_return_val_if_fail (class->delete_secrets != NULL, FALSE);
+ priv->suppress_auto = FALSE;
+
/* Export our secret agent interface before registering with the manager */
dbus_g_connection_register_g_object (priv->bus,
NM_DBUS_PATH_SECRET_AGENT,
@@ -482,7 +515,7 @@ nm_secret_agent_register (NMSecretAgent *self)
reg_request_cb,
self,
NULL,
- G_USEC_PER_SEC * 5,
+ 5000,
G_TYPE_STRING, priv->identifier,
G_TYPE_INVALID);
@@ -514,9 +547,26 @@ nm_secret_agent_unregister (NMSecretAgent *self)
dbus_g_proxy_call_no_reply (priv->manager_proxy, "Unregister", G_TYPE_INVALID);
+ _internal_unregister (self);
+ priv->suppress_auto = TRUE;
+
return TRUE;
}
+static gboolean
+auto_register_cb (gpointer user_data)
+{
+ NMSecretAgent *self = NM_SECRET_AGENT (user_data);
+ NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
+
+ priv->auto_register_id = 0;
+ if (priv->auto_register && !priv->suppress_auto && (priv->reg_call == NULL))
+ nm_secret_agent_register (self);
+ return FALSE;
+}
+
+/**************************************************************/
+
void
nm_secret_agent_get_secrets (NMSecretAgent *self,
NMConnection *connection,
@@ -653,6 +703,8 @@ nm_secret_agent_init (NMSecretAgent *self)
g_warning ("Couldn't create NM agent manager proxy.");
return;
}
+
+ priv->auto_register_id = g_idle_add (auto_register_cb, self);
}
static void
@@ -667,6 +719,9 @@ get_property (GObject *object,
case PROP_IDENTIFIER:
g_value_set_string (value, priv->identifier);
break;
+ case PROP_AUTO_REGISTER:
+ g_value_set_boolean (value, priv->auto_register);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -691,6 +746,9 @@ set_property (GObject *object,
g_free (priv->identifier);
priv->identifier = g_strdup (identifier);
break;
+ case PROP_AUTO_REGISTER:
+ priv->auto_register = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -709,6 +767,9 @@ dispose (GObject *object)
if (priv->registered)
nm_secret_agent_unregister (self);
+ if (priv->auto_register_id)
+ g_source_remove (priv->auto_register_id);
+
g_free (priv->identifier);
g_free (priv->nm_owner);
@@ -757,6 +818,25 @@ nm_secret_agent_class_init (NMSecretAgentClass *class)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/**
+ * NMSecretAgent:auto-register:
+ *
+ * If TRUE, the agent will attempt to automatically register itself after
+ * it is created (via an idle handler) and to re-register itself if
+ * NetworkManager restarts. If FALSE, the agent does not automatically
+ * register with NetworkManager, and nm_secret_agent_register() must be
+ * called. If 'auto-register' is TRUE, calling nm_secret_agent_unregister()
+ * will suppress auto-registration until nm_secret_agent_register() is
+ * called, which re-enables auto-registration.
+ **/
+ g_object_class_install_property
+ (object_class, PROP_AUTO_REGISTER,
+ g_param_spec_boolean (NM_SECRET_AGENT_AUTO_REGISTER,
+ "Auto Register",
+ "Auto Register",
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ /**
* NMSecretAgent::registration-result:
* @agent: the agent that received the signal
* @error: the error, if any, that occured while registering
diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h
index 6fb470577..60354d563 100644
--- a/libnm-glib/nm-secret-agent.h
+++ b/libnm-glib/nm-secret-agent.h
@@ -54,6 +54,7 @@ enum {
#define NM_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass))
#define NM_SECRET_AGENT_IDENTIFIER "identifier"
+#define NM_SECRET_AGENT_AUTO_REGISTER "auto-register"
#define NM_SECRET_AGENT_REGISTRATION_RESULT "registration-result"
@@ -143,8 +144,6 @@ typedef struct {
GType nm_secret_agent_get_type (void);
-NMSecretAgent *nm_secret_agent_new (const char *identifier);
-
gboolean nm_secret_agent_register (NMSecretAgent *self);
gboolean nm_secret_agent_unregister (NMSecretAgent *self);