diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 668fbacac..76be48afe 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -233,6 +233,7 @@ global: nm_remote_settings_new_finish; nm_remote_settings_reload_connections; nm_remote_settings_save_hostname; + nm_secret_agent_capabilities_get_type; nm_secret_agent_delete_secrets; nm_secret_agent_error_get_type; nm_secret_agent_error_quark; diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index 2205f7e7b..f58f95fe0 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -63,6 +63,7 @@ static gboolean auto_register_cb (gpointer user_data); typedef struct { gboolean registered; + NMSecretAgentCapabilities capabilities; DBusGConnection *bus; gboolean private_bus; @@ -86,6 +87,7 @@ enum { PROP_IDENTIFIER, PROP_AUTO_REGISTER, PROP_REGISTERED, + PROP_CAPABILITIES, LAST_PROP }; @@ -530,6 +532,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, @@ -541,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); } /** @@ -599,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; } @@ -868,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; @@ -895,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; @@ -997,6 +1042,20 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) FALSE, 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 diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h index eabe98669..4457df3bf 100644 --- a/libnm-glib/nm-secret-agent.h +++ b/libnm-glib/nm-secret-agent.h @@ -55,6 +55,24 @@ typedef enum { NM_SECRET_AGENT_ERROR_NO_SECRETS, /*< nick=NoSecrets >*/ } NMSecretAgentError; +/** + * NMSecretAgentCapabilities: + * @NM_SECRET_AGENT_CAPABILITY_NONE: the agent supports no special capabilities + * @NM_SECRET_AGENT_CAPABILITY_VPN_HINTS: the agent supports sending hints given + * by the NMSecretAgentClass::get_secrets() class method to VPN plugin + * authentication dialogs. + * @NM_SECRET_AGENT_CAPABILITY_LAST: bounds checking value; should not be used. + * + * #NMSecretAgentCapabilities indicate various capabilities of the agent. + */ +typedef enum /*< flags >*/ { + NM_SECRET_AGENT_CAPABILITY_NONE = 0x0, + NM_SECRET_AGENT_CAPABILITY_VPN_HINTS = 0x1, + + /* boundary value */ + NM_SECRET_AGENT_CAPABILITY_LAST = NM_SECRET_AGENT_CAPABILITY_VPN_HINTS +} NMSecretAgentCapabilities; + /** * NMSecretAgentGetSecretsFlags: * @NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE: no special behavior; by default no @@ -91,6 +109,7 @@ typedef enum /*< flags >*/ { #define NM_SECRET_AGENT_IDENTIFIER "identifier" #define NM_SECRET_AGENT_AUTO_REGISTER "auto-register" #define NM_SECRET_AGENT_REGISTERED "registered" +#define NM_SECRET_AGENT_CAPABILITIES "capabilities" #define NM_SECRET_AGENT_REGISTRATION_RESULT "registration-result"