diff options
author | Dan Williams <dcbw@redhat.com> | 2011-01-19 16:59:01 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2011-01-19 16:59:01 -0600 |
commit | 7ddf9c5e724527c49435f5242cb603301521b746 (patch) | |
tree | 14bcc4e461a8ff4cc5b96c45283b8a7f5ecd48fe | |
parent | 85409427beac38ac0c8586dc37d422c3b3a8d7b6 (diff) |
libnm-glib: implement NMSecretAgent autoregistration
Handles registering with NM and re-registering if NM restarts.
-rw-r--r-- | libnm-glib/libnm-glib.ver | 1 | ||||
-rw-r--r-- | libnm-glib/nm-secret-agent.c | 86 | ||||
-rw-r--r-- | libnm-glib/nm-secret-agent.h | 3 |
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); |