diff options
Diffstat (limited to 'libnm-glib/nm-secret-agent.c')
-rw-r--r-- | libnm-glib/nm-secret-agent.c | 167 |
1 files changed, 114 insertions, 53 deletions
diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index e7dcbbb53..f58f95fe0 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -23,13 +23,10 @@ #include <dbus/dbus-glib-lowlevel.h> #include "nm-glib-compat.h" - -#include <NetworkManager.h> - +#include "NetworkManager.h" #include "nm-secret-agent.h" #include "nm-glib-enum-types.h" -#include "nm-glib-marshal.h" -#include "NetworkManager.h" +#include "nm-dbus-helpers-private.h" static void impl_secret_agent_get_secrets (NMSecretAgent *self, GHashTable *connection_hash, @@ -66,8 +63,10 @@ static gboolean auto_register_cb (gpointer user_data); typedef struct { gboolean registered; + NMSecretAgentCapabilities capabilities; DBusGConnection *bus; + gboolean private_bus; DBusGProxy *dbus_proxy; DBusGProxy *manager_proxy; DBusGProxyCall *reg_call; @@ -88,6 +87,7 @@ enum { PROP_IDENTIFIER, PROP_AUTO_REGISTER, PROP_REGISTERED, + PROP_CAPABILITIES, LAST_PROP }; @@ -228,6 +228,12 @@ verify_sender (NMSecretAgent *self, g_return_val_if_fail (context != NULL, FALSE); + /* Private bus connection is always to NetworkManager, which is always + * UID 0. + */ + if (priv->private_bus) + return TRUE; + /* Verify the sender's UID is 0, and that the sender is the same as * NetworkManager's bus name owner. */ @@ -527,6 +533,22 @@ impl_secret_agent_delete_secrets (NMSecretAgent *self, /**************************************************************/ static void +reg_result (NMSecretAgent *self, GError *error) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + if (error) { + /* If registration failed we shouldn't expose ourselves on the bus */ + _internal_unregister (self); + } else { + priv->registered = TRUE; + g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_REGISTERED); + } + + g_signal_emit (self, signals[REGISTRATION_RESULT], 0, error); +} + +static void reg_request_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) @@ -537,16 +559,37 @@ reg_request_cb (DBusGProxy *proxy, priv->reg_call = NULL; - if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) { - priv->registered = TRUE; - g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_REGISTERED); - } else { - /* If registration failed we shouldn't expose ourselves on the bus */ - _internal_unregister (self); + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + reg_result (self, error); + g_clear_error (&error); +} + +static void +reg_with_caps_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + NMSecretAgent *self = NM_SECRET_AGENT (user_data); + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + priv->reg_call = NULL; + + if (dbus_g_proxy_end_call (proxy, call, NULL, G_TYPE_INVALID)) { + reg_result (self, NULL); + return; } - g_signal_emit (self, signals[REGISTRATION_RESULT], 0, error); - g_clear_error (&error); + /* Might be an old NetworkManager that doesn't support capabilities; + * fall back to old Register() method instead. + */ + priv->reg_call = dbus_g_proxy_begin_call_with_timeout (priv->manager_proxy, + "Register", + reg_request_cb, + self, + NULL, + 5000, + G_TYPE_STRING, priv->identifier, + G_TYPE_INVALID); } /** @@ -569,7 +612,6 @@ nm_secret_agent_register (NMSecretAgent *self) NMSecretAgentPrivate *priv; NMSecretAgentClass *class; - g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE); priv = NM_SECRET_AGENT_GET_PRIVATE (self); @@ -585,6 +627,9 @@ 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); + if (!priv->nm_owner && !priv->private_bus) + return FALSE; + priv->suppress_auto = FALSE; /* Export our secret agent interface before registering with the manager */ @@ -593,14 +638,14 @@ nm_secret_agent_register (NMSecretAgent *self) G_OBJECT (self)); priv->reg_call = dbus_g_proxy_begin_call_with_timeout (priv->manager_proxy, - "Register", - reg_request_cb, + "RegisterWithCapabilities", + reg_with_caps_cb, self, NULL, 5000, G_TYPE_STRING, priv->identifier, + G_TYPE_UINT, priv->capabilities, G_TYPE_INVALID); - return TRUE; } @@ -619,7 +664,6 @@ nm_secret_agent_unregister (NMSecretAgent *self) { NMSecretAgentPrivate *priv; - g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE); priv = NM_SECRET_AGENT_GET_PRIVATE (self); @@ -628,6 +672,9 @@ nm_secret_agent_unregister (NMSecretAgent *self) g_return_val_if_fail (priv->bus != NULL, FALSE); g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); + if (!priv->nm_owner && !priv->private_bus) + return FALSE; + dbus_g_proxy_call_no_reply (priv->manager_proxy, "Unregister", G_TYPE_INVALID); _internal_unregister (self); @@ -645,7 +692,6 @@ nm_secret_agent_unregister (NMSecretAgent *self) gboolean nm_secret_agent_get_registered (NMSecretAgent *self) { - g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE); return NM_SECRET_AGENT_GET_PRIVATE (self)->registered; @@ -692,9 +738,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, NMSecretAgentGetSecretsFunc callback, gpointer user_data) { - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SECRET_AGENT (self)); - g_return_if_fail (connection != NULL); g_return_if_fail (NM_IS_CONNECTION (connection)); g_return_if_fail (nm_connection_get_path (connection)); g_return_if_fail (setting_name != NULL); @@ -729,9 +773,7 @@ nm_secret_agent_save_secrets (NMSecretAgent *self, NMSecretAgentSaveSecretsFunc callback, gpointer user_data) { - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SECRET_AGENT (self)); - g_return_if_fail (connection != NULL); g_return_if_fail (NM_IS_CONNECTION (connection)); g_return_if_fail (nm_connection_get_path (connection)); @@ -760,9 +802,7 @@ nm_secret_agent_delete_secrets (NMSecretAgent *self, NMSecretAgentDeleteSecretsFunc callback, gpointer user_data) { - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SECRET_AGENT (self)); - g_return_if_fail (connection != NULL); g_return_if_fail (NM_IS_CONNECTION (connection)); g_return_if_fail (nm_connection_get_path (connection)); @@ -807,44 +847,46 @@ nm_secret_agent_init (NMSecretAgent *self) NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); GError *error = NULL; - priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + priv->bus = _nm_dbus_new_connection (&error); if (!priv->bus) { g_warning ("Couldn't connect to system bus: %s", error->message); g_error_free (error); return; } - - priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - if (!priv->dbus_proxy) { - g_warning ("Couldn't create messagebus proxy."); - return; + priv->private_bus = _nm_dbus_is_connection_private (priv->bus); + + if (priv->private_bus == FALSE) { + priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + g_assert (priv->dbus_proxy); + + dbus_g_object_register_marshaller (g_cclosure_marshal_generic, + G_TYPE_NONE, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->dbus_proxy, + "NameOwnerChanged", + G_CALLBACK (name_owner_changed), + self, NULL); + + get_nm_owner (self); } - dbus_g_object_register_marshaller (_nm_glib_marshal_VOID__STRING_STRING_STRING, - G_TYPE_NONE, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->dbus_proxy, - "NameOwnerChanged", - G_CALLBACK (name_owner_changed), - self, NULL); - - priv->manager_proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE, - NM_DBUS_PATH_AGENT_MANAGER, - NM_DBUS_INTERFACE_AGENT_MANAGER); + priv->manager_proxy = _nm_dbus_new_proxy_for_connection (priv->bus, + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER); if (!priv->manager_proxy) { g_warning ("Couldn't create NM agent manager proxy."); return; } - priv->auto_register_id = g_idle_add (auto_register_cb, self); + if (priv->nm_owner || priv->private_bus) + priv->auto_register_id = g_idle_add (auto_register_cb, self); } static void @@ -865,6 +907,9 @@ get_property (GObject *object, case PROP_REGISTERED: g_value_set_boolean (value, priv->registered); break; + case PROP_CAPABILITIES: + g_value_set_flags (value, priv->capabilities); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -892,6 +937,9 @@ set_property (GObject *object, case PROP_AUTO_REGISTER: priv->auto_register = g_value_get_boolean (value); break; + case PROP_CAPABILITIES: + priv->capabilities = g_value_get_flags (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -995,6 +1043,20 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) G_PARAM_READABLE)); /** + * NMSecretAgent:capabilities: + * + * A bitfield of %NMSecretAgentCapabilities. + **/ + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_flags (NM_SECRET_AGENT_CAPABILITIES, + "Capabilities", + "Capabilities", + NM_TYPE_SECRET_AGENT_CAPABILITIES, + NM_SECRET_AGENT_CAPABILITY_NONE, + 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 @@ -1006,8 +1068,7 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) g_signal_new (NM_SECRET_AGENT_REGISTRATION_RESULT, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_POINTER); dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), |