diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index 2131d90ca..44937eedc 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -516,12 +516,12 @@ nm_modem_get_secrets (NMModem *self, const char *hint) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION; cancel_get_secrets (self); if (request_new) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_request, setting_name, flags, @@ -554,7 +554,7 @@ nm_modem_act_stage1_prepare (NMModem *self, NMActStageReturn ret; GPtrArray *hints = NULL; const char *setting_name = NULL; - guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION; if (priv->act_request) g_object_unref (priv->act_request); @@ -567,7 +567,7 @@ nm_modem_act_stage1_prepare (NMModem *self, reason); if ((ret == NM_ACT_STAGE_RETURN_POSTPONE) && setting_name) { if (priv->secrets_tries++) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (req, setting_name, diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index a25e46e2e..6a36975a8 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -36,6 +36,7 @@ #include "nm-active-connection.h" #include "nm-dbus-glib-types.h" #include "nm-active-connection-glue.h" +#include "nm-settings-connection.h" G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT) @@ -60,7 +61,6 @@ typedef struct { NMConnection *connection; - NMAgentManager *agent_mgr; GSList *secrets_calls; char *specific_object; @@ -94,66 +94,28 @@ enum { /*******************************************************************/ +typedef struct { + NMActRequest *self; + guint32 call_id; + NMActRequestSecretsFunc callback; + gpointer callback_data; +} GetSecretsInfo; + static void -get_secrets_cb (NMAgentManager *manager, +get_secrets_cb (NMSettingsConnection *connection, guint32 call_id, - NMConnection *connection, const char *setting_name, GError *error, - gpointer user_data, - gpointer user_data2, - gpointer user_data3) + gpointer user_data) { - NMActRequest *self = NM_ACT_REQUEST (user_data); - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); - NMActRequestSecretsFunc callback = user_data2; + GetSecretsInfo *info = user_data; + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (info->self); - priv->secrets_calls = g_slist_remove (priv->secrets_calls, GUINT_TO_POINTER (call_id)); + g_return_if_fail (info->call_id == call_id); + priv->secrets_calls = g_slist_remove (priv->secrets_calls, info); - callback (self, call_id, connection, error, user_data3); -} - -static guint32 -_internal_get_secrets (NMActRequest *self, - NMConnection *connection, - gboolean filter_by_uid, - gulong uid, - const char *setting_name, - guint32 flags, - const char *hint, - NMActRequestSecretsFunc callback, - gpointer callback_data) -{ - NMActRequestPrivate *priv; - guint32 call_id; - - g_return_val_if_fail (self, 0); - g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0); - - priv = NM_ACT_REQUEST_GET_PRIVATE (self); - - /* If given a connection (ie, called from an NMVpnConnection) then - * use that, otherwise use the private connection. - * - * FIXME: this is icky, and should go away when NMVPNConnection finally - * uses NMActRequest for activation tracking instead of impersonating one - * itself. - */ - call_id = nm_agent_manager_get_secrets (priv->agent_mgr, - connection, - filter_by_uid, - uid, - setting_name, - flags, - hint, - get_secrets_cb, - self, - callback, - callback_data); - if (call_id > 0) - priv->secrets_calls = g_slist_append (priv->secrets_calls, GUINT_TO_POINTER (call_id)); - - return call_id; + info->callback (info->self, call_id, NM_CONNECTION (connection), error, info->callback_data); + g_free (info); } guint32 @@ -164,41 +126,43 @@ nm_act_request_get_secrets (NMActRequest *self, NMActRequestSecretsFunc callback, gpointer callback_data) { - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); + NMActRequestPrivate *priv; + GetSecretsInfo *info; + guint32 call_id; - /* non-VPN requests use the activation request's internal connection, and - * also the user-requested status and user_uid if the activation was - * requested by a user. - */ - return _internal_get_secrets (self, priv->connection, priv->user_requested, - priv->user_uid, setting_name, flags, hint, - callback, callback_data); -} + g_return_val_if_fail (self, 0); + g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0); -guint32 -nm_act_request_get_secrets_vpn (NMActRequest *self, - NMConnection *connection, - gboolean user_requested, - gulong user_uid, - const char *setting_name, - guint32 flags, - const char *hint, - NMActRequestSecretsFunc callback, - gpointer callback_data) -{ - g_return_val_if_fail (connection != NULL, 0); + priv = NM_ACT_REQUEST_GET_PRIVATE (self); - /* VPN requests use the VPN's connection, and also the VPN's user-requested - * status and user_uid if the activation was requested by a user. - */ - return _internal_get_secrets (self, connection, user_requested, user_uid, - setting_name, flags, hint, callback, callback_data); + info = g_malloc0 (sizeof (GetSecretsInfo)); + info->self = self; + info->callback = callback; + info->callback_data = callback_data; + + call_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection), + priv->user_requested, + priv->user_uid, + setting_name, + flags, + hint, + get_secrets_cb, + info, + NULL); + if (call_id > 0) { + info->call_id = call_id; + priv->secrets_calls = g_slist_append (priv->secrets_calls, info); + } else + g_free (info); + + return call_id; } void nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id) { NMActRequestPrivate *priv; + GSList *iter; g_return_if_fail (self); g_return_if_fail (NM_IS_ACT_REQUEST (self)); @@ -206,9 +170,18 @@ nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id) priv = NM_ACT_REQUEST_GET_PRIVATE (self); - if (g_slist_find (priv->secrets_calls, GUINT_TO_POINTER (call_id))) { - priv->secrets_calls = g_slist_remove (priv->secrets_calls, GUINT_TO_POINTER (call_id)); - nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id); + for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { + GetSecretsInfo *info = iter->data; + + /* Remove the matching info */ + if (info->call_id == call_id) { + priv->secrets_calls = g_slist_remove_link (priv->secrets_calls, iter); + g_slist_free (iter); + + nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), call_id); + g_free (info); + break; + } } } @@ -490,7 +463,6 @@ device_state_changed (NMDevice *device, NMActRequest * nm_act_request_new (NMConnection *connection, const char *specific_object, - NMAgentManager *agent_mgr, gboolean user_requested, gulong user_uid, gboolean assumed, @@ -500,7 +472,6 @@ nm_act_request_new (NMConnection *connection, NMActRequestPrivate *priv; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (NM_IS_AGENT_MANAGER (agent_mgr), NULL); g_return_val_if_fail (NM_DEVICE (device), NULL); object = g_object_new (NM_TYPE_ACT_REQUEST, NULL); @@ -513,8 +484,6 @@ nm_act_request_new (NMConnection *connection, if (specific_object) priv->specific_object = g_strdup (specific_object); - priv->agent_mgr = g_object_ref (agent_mgr); - priv->device = NM_DEVICE (device); g_signal_connect (device, "state-changed", G_CALLBACK (device_state_changed), @@ -595,8 +564,6 @@ dispose (GObject *object) } priv->disposed = TRUE; - g_assert (priv->connection); - g_signal_handlers_disconnect_by_func (G_OBJECT (priv->device), G_CALLBACK (device_state_changed), NM_ACT_REQUEST (object)); @@ -604,14 +571,17 @@ dispose (GObject *object) /* Clear any share rules */ nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE); - g_object_unref (priv->connection); - + /* Kill any in-progress secrets requests */ + g_assert (priv->connection); for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { - nm_agent_manager_cancel_secrets (priv->agent_mgr, - GPOINTER_TO_UINT (iter->data)); + GetSecretsInfo *info = iter->data; + + nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), info->call_id); + g_free (info); } g_slist_free (priv->secrets_calls); - g_object_unref (priv->agent_mgr); + + g_object_unref (priv->connection); G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); } diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index f91eb1c72..61456cc65 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -25,7 +25,6 @@ #include #include "nm-connection.h" #include "nm-active-connection.h" -#include "nm-agent-manager.h" #define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ()) #define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest)) @@ -49,7 +48,6 @@ GType nm_act_request_get_type (void); NMActRequest *nm_act_request_new (NMConnection *connection, const char *specific_object, - NMAgentManager *agent_mgr, gboolean user_requested, gulong user_uid, gboolean assumed, @@ -93,22 +91,21 @@ typedef void (*NMActRequestSecretsFunc) (NMActRequest *req, GError *error, gpointer user_data); -guint32 nm_act_request_get_secrets (NMActRequest *req, - const char *setting_name, - guint32 flags, - const char *hint, - NMActRequestSecretsFunc callback, - gpointer callback_data); +/* NOTE: these values should match the NM_SECRET_AGENT_GET_SECRETS_FLAGS in + * the nm-secret-agent.xml introspection file. + */ +enum { + NM_ACT_REQUEST_GET_SECRETS_FLAG_NONE = 0x0, + NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1, + NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW = 0x2 +}; -guint32 nm_act_request_get_secrets_vpn (NMActRequest *req, - NMConnection *connection, - gboolean user_requested, - gulong user_uid, - const char *setting_name, - guint32 flags, - const char *hint, - NMActRequestSecretsFunc callback, - gpointer callback_data); +guint32 nm_act_request_get_secrets (NMActRequest *req, + const char *setting_name, + guint32 flags, + const char *hint, + NMActRequestSecretsFunc callback, + gpointer callback_data); void nm_act_request_cancel_secrets (NMActRequest *req, guint32 call_id); diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index d5f8ef472..11f824408 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -31,7 +31,6 @@ #include "nm-agent-manager.h" #include "nm-secret-agent.h" #include "nm-manager-auth.h" -#include "nm-settings-connection.h" #include "nm-dbus-glib-types.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -353,7 +352,7 @@ struct _Request { guint32 idle_id; - GHashTable *settings_secrets; + GHashTable *existing_secrets; NMAgentSecretsResultFunc callback; gpointer callback_data; @@ -368,6 +367,7 @@ static Request * request_new (NMConnection *connection, gboolean filter_by_uid, gulong uid_filter, + GHashTable *existing_secrets, const char *setting_name, guint32 flags, const char *hint, @@ -386,6 +386,7 @@ request_new (NMConnection *connection, req->connection = g_object_ref (connection); req->filter_by_uid = filter_by_uid; req->uid_filter = uid_filter; + req->existing_secrets = g_hash_table_ref (existing_secrets); req->setting_name = g_strdup (setting_name); req->flags = flags; req->hint = g_strdup (hint); @@ -413,60 +414,14 @@ request_free (Request *req) g_object_unref (req->connection); g_free (req->setting_name); g_free (req->hint); - if (req->settings_secrets) - g_hash_table_unref (req->settings_secrets); + if (req->existing_secrets) + g_hash_table_unref (req->existing_secrets); memset (req, 0, sizeof (Request)); g_free (req); } static void request_next (Request *req); -static void -destroy_gvalue (gpointer data) -{ - GValue *value = (GValue *) data; - - g_value_unset (value); - g_slice_free (GValue, value); -} - -static void -merge_secrets (GHashTable *src, GHashTable *dest) -{ - GHashTableIter iter; - gpointer key, data; - - g_hash_table_iter_init (&iter, src); - while (g_hash_table_iter_next (&iter, &key, &data)) { - const char *setting_name = key; - GHashTable *dstsetting; - GHashTableIter subiter; - gpointer subkey, subval; - - /* Find the corresponding setting in the merged secrets hash, or create - * it if it doesn't exist. - */ - dstsetting = g_hash_table_lookup (dest, setting_name); - if (!dstsetting) { - dstsetting = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) destroy_gvalue); - g_hash_table_insert (dest, (gpointer) setting_name, dstsetting); - } - - /* And copy in each secret from src */ - g_hash_table_iter_init (&subiter, (GHashTable *) data); - while (g_hash_table_iter_next (&subiter, &subkey, &subval)) { - const char *keyname = subkey; - GValue *srcval = subval, *dstval; - - dstval = g_slice_new0 (GValue); - g_value_init (dstval, G_VALUE_TYPE (srcval)); - g_value_copy (srcval, dstval); - - g_hash_table_insert (dstsetting, (gpointer) keyname, dstval); - } - } -} - static void request_secrets_done_cb (NMSecretAgent *agent, gconstpointer call_id, @@ -475,7 +430,7 @@ request_secrets_done_cb (NMSecretAgent *agent, gpointer user_data) { Request *req = user_data; - GHashTable *setting_secrets, *merged; + GHashTable *setting_secrets; g_return_if_fail (call_id == req->current_call_id); @@ -510,20 +465,7 @@ request_secrets_done_cb (NMSecretAgent *agent, nm_secret_agent_get_description (agent), req, req->setting_name); - /* Success! If we got some secrets from the settings service, merge those - * with the ones from the secret agent. - */ - if (req->settings_secrets) { - merged = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_unref); - - /* Copy agent secrets first, then overwrite with settings secrets */ - merge_secrets (secrets, merged); - merge_secrets (req->settings_secrets, merged); - - req->complete_callback (req, merged, NULL, req->complete_callback_data); - g_hash_table_destroy (merged); - } else - req->complete_callback (req, secrets, NULL, req->complete_callback_data); + req->complete_callback (req, secrets, NULL, req->complete_callback_data); } static void @@ -568,23 +510,17 @@ static gboolean request_start_secrets (gpointer user_data) { Request *req = user_data; - GHashTable *secrets, *setting_secrets = NULL; - GError *error = NULL; + GHashTable *setting_secrets = NULL; req->idle_id = 0; - nm_log_dbg (LOGD_AGENTS, "(%p/%s) getting secrets from system settings", - req, req->setting_name); - - /* Grab any secrets from persistent storage */ - secrets = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (req->connection), - req->setting_name, - &error); - if (secrets) - setting_secrets = g_hash_table_lookup (secrets, req->setting_name); + /* Check if there are any existing secrets */ + if (req->existing_secrets) + setting_secrets = g_hash_table_lookup (req->existing_secrets, req->setting_name); if (setting_secrets && g_hash_table_size (setting_secrets)) { NMConnection *tmp; + GError *error = NULL; /* The connection already had secrets; check if any more are required. * If no more are required, we're done. If secrets are still needed, @@ -594,7 +530,7 @@ request_start_secrets (gpointer user_data) tmp = nm_connection_duplicate (req->connection); g_assert (tmp); - if (!nm_connection_update_secrets (tmp, req->setting_name, secrets, &error)) { + if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) { req->complete_callback (req, NULL, error, req->complete_callback_data); g_clear_error (&error); } else { @@ -605,26 +541,16 @@ request_start_secrets (gpointer user_data) req, req->setting_name); /* Got everything, we're done */ - req->complete_callback (req, secrets, NULL, req->complete_callback_data); + req->complete_callback (req, req->existing_secrets, NULL, req->complete_callback_data); } else { nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets insufficient, asking agents", req, req->setting_name); /* We don't, so ask some agents for additional secrets */ - req->settings_secrets = g_hash_table_ref (secrets); request_next (req); } } g_object_unref (tmp); - } else if (error) { - nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings returned error: (%d) %s", - req, req->setting_name, error->code, error->message); - - /* Errors from the system settings are hard errors; we don't go on - * to ask agents for secrets if the settings service failed. - */ - req->complete_callback (req, NULL, error, req->complete_callback_data); - g_error_free (error); } else { /* Couldn't get secrets from system settings, so now we ask the * agents for secrets. Let the Agent Manager handle which agents @@ -633,9 +559,6 @@ request_start_secrets (gpointer user_data) request_next (req); } - if (secrets) - g_hash_table_unref (secrets); - return FALSE; } @@ -759,38 +682,18 @@ mgr_req_complete_cb (Request *req, { NMAgentManager *self = NM_AGENT_MANAGER (user_data); NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - GError *local = NULL; - if (error) - local = g_error_copy (error); - else { - /* Save the secrets into the connection */ - nm_connection_update_secrets (req->connection, - req->setting_name, - secrets, - &local); - } - - if (local) { - nm_log_warn (LOGD_SETTINGS, - "Failed to %s connection secrets: (%d) %s", - error ? "get" : "update", - local->code, - local->message ? local->message : "(none)"); - } - - /* Call the activation requests' secrets callback */ + /* Send secrets back to the requesting object */ req->callback (self, req->reqid, - req->connection, req->setting_name, - local, + error ? NULL : secrets, + error, req->callback_data, req->other_data2, req->other_data3); g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid)); - g_clear_error (&local); } guint32 @@ -798,6 +701,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, NMConnection *connection, gboolean filter_by_uid, gulong uid_filter, + GHashTable *existing_secrets, const char *setting_name, guint32 flags, const char *hint, @@ -813,7 +717,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, g_return_val_if_fail (self != NULL, 0); g_return_val_if_fail (connection != NULL, 0); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), 0); + g_return_val_if_fail (NM_IS_CONNECTION (connection), 0); g_return_val_if_fail (callback != NULL, 0); nm_log_dbg (LOGD_SETTINGS, @@ -824,6 +728,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, req = request_new (connection, filter_by_uid, uid_filter, + existing_secrets, setting_name, flags, hint, @@ -875,30 +780,33 @@ name_owner_changed_cb (NMDBusManager *dbus_mgr, /*************************************************************/ NMAgentManager * -nm_agent_manager_new (NMDBusManager *dbus_mgr) +nm_agent_manager_get (void) { - NMAgentManager *self; + static NMAgentManager *singleton = NULL; NMAgentManagerPrivate *priv; DBusGConnection *connection; - g_return_val_if_fail (dbus_mgr != NULL, NULL); + if (singleton) + return g_object_ref (singleton); - self = (NMAgentManager *) g_object_new (NM_TYPE_AGENT_MANAGER, NULL); - if (self) { - priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + singleton = (NMAgentManager *) g_object_new (NM_TYPE_AGENT_MANAGER, NULL); + g_assert (singleton); - priv->session_monitor = nm_session_monitor_get (); - priv->dbus_mgr = g_object_ref (dbus_mgr); - connection = nm_dbus_manager_get_connection (dbus_mgr); - dbus_g_connection_register_g_object (connection, NM_DBUS_PATH_AGENT_MANAGER, G_OBJECT (self)); + priv = NM_AGENT_MANAGER_GET_PRIVATE (singleton); + priv->session_monitor = nm_session_monitor_get (); + priv->dbus_mgr = nm_dbus_manager_get (); - g_signal_connect (priv->dbus_mgr, - NM_DBUS_MANAGER_NAME_OWNER_CHANGED, - G_CALLBACK (name_owner_changed_cb), - self); - } + connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + dbus_g_connection_register_g_object (connection, + NM_DBUS_PATH_AGENT_MANAGER, + G_OBJECT (singleton)); - return self; + g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, + G_CALLBACK (name_owner_changed_cb), + singleton); + + return singleton; } static void diff --git a/src/nm-agent-manager.h b/src/nm-agent-manager.h index 17d918d5d..582680741 100644 --- a/src/nm-agent-manager.h +++ b/src/nm-agent-manager.h @@ -23,12 +23,8 @@ #include #include - #include -#include "nm-dbus-manager.h" -#include "nm-secret-agent.h" - #define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ()) #define NM_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManager)) #define NM_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) @@ -46,21 +42,22 @@ typedef struct { GType nm_agent_manager_get_type (void); -NMAgentManager *nm_agent_manager_new (NMDBusManager *dbus_mgr); +NMAgentManager *nm_agent_manager_get (void); typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, guint32 call_id, - NMConnection *connection, const char *setting_name, + GHashTable *secrets, GError *error, gpointer user_data, - gpointer user_data2, - gpointer user_data3); + gpointer other_data2, + gpointer other_data3); guint32 nm_agent_manager_get_secrets (NMAgentManager *manager, NMConnection *connection, gboolean filter_by_uid, gulong uid, + GHashTable *existing_secrets, const char *setting_name, guint32 flags, const char *hint, diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index f18d5b9a9..079d9cf1f 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -1056,7 +1056,7 @@ link_timeout_cb (gpointer user_data) nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, + NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW, NULL, wired_secrets_cb, self); @@ -1237,13 +1237,13 @@ handle_auth_or_fail (NMDeviceEthernet *self, nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION; /* If the caller doesn't necessarily want completely new secrets, * only ask for new secrets after the first failure. */ if (new_secrets || tries) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW; nm_act_request_get_secrets (req, setting_name, flags, NULL, wired_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 8dfc81b9e..da1068e8d 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -2496,7 +2496,7 @@ link_timeout_cb (gpointer user_data) nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, + NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW, NULL, wifi_secrets_cb, self); @@ -2734,13 +2734,13 @@ handle_auth_or_fail (NMDeviceWifi *self, nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION; /* If the caller doesn't necessarily want completely new secrets, * only ask for new secrets after the first failure. */ if (new_secrets || tries) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW; nm_act_request_get_secrets (req, setting_name, flags, NULL, wifi_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); diff --git a/src/nm-manager.c b/src/nm-manager.c index 3bd1482e5..a7adb13ad 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -59,7 +59,6 @@ #include "nm-settings.h" #include "nm-settings-connection.h" #include "nm-manager-auth.h" -#include "nm-agent-manager.h" #include "NetworkManagerUtils.h" #define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" @@ -213,7 +212,6 @@ typedef struct { NMSettings *settings; char *hostname; - NMAgentManager *agent_mgr; RadioState radio_states[RFKILL_TYPE_MAX]; gboolean sleeping; @@ -925,86 +923,6 @@ connections_changed (NMSettings *settings, bluez_manager_resync_devices (manager); } -static void -secrets_result_cb (NMAgentManager *manager, - guint32 call_id, - NMConnection *connection, - const char *setting_name, - GError *error, - gpointer user_data, - gpointer user_data2, - gpointer user_data3) -{ - NMSettingsConnectionSecretsUpdatedFunc callback = user_data2; - gpointer callback_data = user_data3; - - callback (NM_SETTINGS_CONNECTION (connection), setting_name, call_id, error, callback_data); -} - -static guint32 -system_connection_get_secrets_cb (NMSettingsConnection *connection, - const char *sender, - const char *setting_name, - NMSettingsConnectionSecretsUpdatedFunc callback, - gpointer callback_data, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - gboolean call_id = 0; - DBusError error; - gulong sender_uid; - - /* Get the unix user of the requestor */ - dbus_error_init (&error); - sender_uid = dbus_bus_get_unix_user (nm_dbus_manager_get_dbus_connection (priv->dbus_mgr), - sender, - &error); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - else { - call_id = nm_agent_manager_get_secrets (priv->agent_mgr, - NM_CONNECTION (connection), - TRUE, - sender_uid, - setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE, - NULL, - secrets_result_cb, - self, - callback, - callback_data); - } - - return call_id; -} - -static void -system_connection_cancel_secrets_cb (NMSettingsConnection *connection, - guint32 call_id, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - - nm_agent_manager_cancel_secrets (NM_MANAGER_GET_PRIVATE (self)->agent_mgr, call_id); -} - -static void -connection_added (NMSettings *settings, - NMSettingsConnection *connection, - NMManager *manager) -{ - /* Hook up secrets request listeners */ - g_signal_connect (connection, NM_SETTINGS_CONNECTION_GET_SECRETS, - G_CALLBACK (system_connection_get_secrets_cb), - manager); - g_signal_connect (connection, NM_SETTINGS_CONNECTION_CANCEL_SECRETS, - G_CALLBACK (system_connection_cancel_secrets_cb), - manager); - - connections_changed (settings, connection, manager); -} - static void system_unmanaged_devices_changed_cb (NMSettings *settings, GParamSpec *pspec, @@ -1953,7 +1871,6 @@ internal_activate_device (NMManager *manager, req = nm_act_request_new (connection, specific_object, - NM_MANAGER_GET_PRIVATE (manager)->agent_mgr, user_requested, sender_uid, assumed, @@ -3190,8 +3107,6 @@ nm_manager_get (NMSettings *settings, priv->settings = g_object_ref (settings); - priv->agent_mgr = nm_agent_manager_new (priv->dbus_mgr); - priv->config_file = g_strdup (config_file); priv->state_file = g_strdup (state_file); @@ -3206,7 +3121,7 @@ nm_manager_get (NMSettings *settings, g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME, G_CALLBACK (system_hostname_changed_cb), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, - G_CALLBACK (connection_added), singleton); + G_CALLBACK (connections_changed), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (connections_changed), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, @@ -3275,8 +3190,6 @@ dispose (GObject *object) g_object_unref (priv->settings); - g_object_unref (priv->agent_mgr); - if (priv->vpn_manager_id) { g_source_remove (priv->vpn_manager_id); priv->vpn_manager_id = 0; diff --git a/src/nm-secret-agent.h b/src/nm-secret-agent.h index bb86835e3..f1e8bb322 100644 --- a/src/nm-secret-agent.h +++ b/src/nm-secret-agent.h @@ -29,15 +29,6 @@ #include #include "nm-dbus-manager.h" -/* NOTE: these values should match the NM_SECRET_AGENT_GET_SECRETS_FLAGS in - * the nm-secret-agent.xml introspection file. - */ -enum { - NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE = 0x0, - NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1, - NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW = 0x2 -}; - #define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) #define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) #define NM_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index bf0f020d5..62faaad72 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -442,7 +442,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, guint32 tries; GPtrArray *hints = NULL; GError *error = NULL; - guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION; connection = nm_act_request_get_connection (priv->act_req); @@ -468,7 +468,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, */ tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES)); if (tries > 1) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_req, setting_name, diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 01be34601..f532442c2 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -35,6 +35,7 @@ #include "nm-logging.h" #include "nm-manager-auth.h" #include "nm-marshal.h" +#include "nm-agent-manager.h" static void impl_settings_connection_get_settings (NMSettingsConnection *connection, DBusGMethodInvocation *context); @@ -66,8 +67,6 @@ enum { enum { UPDATED, REMOVED, - GET_SECRETS, - CANCEL_SECRETS, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -75,6 +74,9 @@ static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { gboolean disposed; + NMDBusManager *dbus_mgr; + NMAgentManager *agent_mgr; + PolkitAuthority *authority; GSList *pending_auths; /* List of pending authentication requests */ NMConnection *secrets; @@ -340,25 +342,77 @@ supports_secrets (NMSettingsConnection *connection, const char *setting_name) return TRUE; } +static void +agent_secrets_done_cb (NMAgentManager *manager, + guint32 call_id, + const char *setting_name, + GHashTable *secrets, + GError *error, + gpointer user_data, + gpointer other_data2, + gpointer other_data3) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionSecretsFunc callback = other_data2; + gpointer callback_data = other_data3; + GError *local = NULL; + GHashTable *hash; + + if (error) { + callback (self, call_id, setting_name, error, callback_data); + return; + } + + /* Update the connection with the agent's secrets */ + nm_connection_clear_secrets (NM_CONNECTION (self)); + if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) { + /* FIXME: if the agent's owner has "modify" permission, then agent + * supplied secrets should overwrite existing secrets, and those agent + * supplied secrets should get written back out to persistent storage. + */ + + hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local); + g_hash_table_destroy (hash); + } + + callback (self, call_id, setting_name, local, callback_data); + g_clear_error (&local); +} + /** * nm_settings_connection_get_secrets: * @connection: the #NMSettingsConnection + * @filter_by_uid: if TRUE, only request secrets from agents registered by the + * same UID as @uid. + * @uid: when @filter_by_uid is TRUE, only request secrets from agents belonging + * to this UID * @setting_name: the setting to return secrets for - * @error: an error on return, if an error occured + * @flags: flags to modify the secrets request + * @hint: the name of a key in @setting_name for which a secret may be required + * @callback: the function to call with returned secrets + * @callback_data: user data to pass to @callback * - * Return secrets in persistent storage, if any. Does not query any Secret - * Agents for secrets. + * Retrieves secrets from persistent storage and queries any secret agents for + * additional secrets. * - * Returns: a hash mapping setting names to hash tables, each inner hash - * containing string:value mappings of secrets + * Returns: a call ID which may be used to cancel the ongoing secrets request **/ -GHashTable * -nm_settings_connection_get_secrets (NMSettingsConnection *connection, +guint32 +nm_settings_connection_get_secrets (NMSettingsConnection *self, + gboolean filter_by_uid, + gulong uid, const char *setting_name, + guint32 flags, + const char *hint, + NMSettingsConnectionSecretsFunc callback, + gpointer callback_data, GError **error) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); - NMSetting *setting; + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + GHashTable *existing_secrets; + guint32 call_id = 0; /* Use priv->secrets to work around the fact that nm_connection_clear_secrets() * will clear secrets on this object's settings. priv->secrets should be @@ -369,20 +423,44 @@ nm_settings_connection_get_secrets (NMSettingsConnection *connection, g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "%s.%d - Internal error; secrets cache invalid.", __FILE__, __LINE__); - return NULL; + return 0; } /* FIXME: if setting_name is empty, return all secrets */ - setting = nm_connection_get_setting_by_name (priv->secrets, setting_name); - if (!setting) { + if (!nm_connection_get_setting_by_name (priv->secrets, setting_name)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING, "%s.%d - Connection didn't have requested setting '%s'.", __FILE__, __LINE__, setting_name); - return NULL; + return 0; } - return nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + existing_secrets = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + call_id = nm_agent_manager_get_secrets (priv->agent_mgr, + NM_CONNECTION (self), + filter_by_uid, + uid, + existing_secrets, + setting_name, + flags, + hint, + agent_secrets_done_cb, + self, + callback, + callback_data); + g_hash_table_unref (existing_secrets); + + return call_id; +} + +void +nm_settings_connection_cancel_secrets (NMSettingsConnection *self, + guint32 call_id) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); + nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id); } /**** User authorization **************************************/ @@ -660,25 +738,10 @@ impl_settings_connection_delete (NMSettingsConnection *self, /**************************************************************/ -static gboolean -get_secrets_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer data) -{ - guint handler_call_id = g_value_get_uint (handler_return); - - if (handler_call_id > 0) - g_value_set_uint (return_accu, handler_call_id); - - /* Abort signal emission if a valid call ID got returned */ - return handler_call_id ? FALSE : TRUE; -} - static void dbus_get_agent_secrets_cb (NMSettingsConnection *self, - const char *setting_name, guint32 call_id, + const char *setting_name, GError *error, gpointer user_data) { @@ -712,36 +775,59 @@ dbus_secrets_auth_cb (NMSettingsConnection *self, { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); char *sender, *setting_name = user_data; + DBusError dbus_error; + gulong sender_uid; guint32 call_id = 0; GError *local = NULL; + if (error) { + local = g_error_copy (error); + goto done; + } + sender = dbus_g_method_get_sender (context); if (!sender) { local = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, "Unable to get request D-Bus sender"); - } else if (!error) { - g_signal_emit (self, signals[GET_SECRETS], 0, - sender, - setting_name, - dbus_get_agent_secrets_cb, - context, - &call_id); - if (call_id > 0) { - /* track the request and wait for the callback */ - priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id)); - } else { - local = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, - "No secrets were available"); - } + goto done; } - if (error || local) + /* Get the unix user of the requestor */ + dbus_error_init (&dbus_error); + sender_uid = dbus_bus_get_unix_user (nm_dbus_manager_get_dbus_connection (priv->dbus_mgr), + sender, + &dbus_error); + g_free (sender); + + if (dbus_error_is_set (&dbus_error)) { + local = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + "Unable to get sender UID: %s", + dbus_error.message); + dbus_error_free (&dbus_error); + goto done; + } + + call_id = nm_settings_connection_get_secrets (self, + TRUE, + sender_uid, + setting_name, + 0, /* GET_SECRETS_FLAG_NONE */ + NULL, + dbus_get_agent_secrets_cb, + context, + &local); + if (call_id > 0) { + /* track the request and wait for the callback */ + priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id)); + } + +done: + if (local) dbus_g_method_return_error (context, error ? error : local); g_free (setting_name); - g_free (sender); g_clear_error (&local); } @@ -763,6 +849,8 @@ nm_settings_connection_init (NMSettingsConnection *self) char *dbus_path; GError *error = NULL; + priv->dbus_mgr = nm_dbus_manager_get (); + priv->authority = polkit_authority_get_sync (NULL, NULL); if (!priv->authority) { nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", @@ -781,6 +869,8 @@ nm_settings_connection_init (NMSettingsConnection *self) NM_SESSION_MONITOR_CHANGED, G_CALLBACK (session_changed_cb), self); + + priv->agent_mgr = nm_agent_manager_get (); } static void @@ -805,12 +895,14 @@ dispose (GObject *object) /* Cancel in-progress secrets requests */ for (iter = priv->reqs; iter; iter = g_slist_next (iter)) - g_signal_emit (self, signals[CANCEL_SECRETS], 0, GPOINTER_TO_UINT (iter->data)); + nm_agent_manager_cancel_secrets (priv->agent_mgr, GPOINTER_TO_UINT (iter->data)); g_slist_free (priv->reqs); set_visible (self, FALSE); g_object_unref (priv->session_monitor); + g_object_unref (priv->agent_mgr); + g_object_unref (priv->dbus_mgr); out: G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); @@ -881,24 +973,6 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - /* not exported over D-Bus */ - signals[GET_SECRETS] = - g_signal_new (NM_SETTINGS_CONNECTION_GET_SECRETS, - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSettingsConnectionClass, get_secrets), - get_secrets_accumulator, NULL, - _nm_marshal_UINT__STRING_STRING_POINTER_POINTER, - G_TYPE_UINT, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); - - signals[CANCEL_SECRETS] = - g_signal_new (NM_SETTINGS_CONNECTION_CANCEL_SECRETS, - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 0); - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), &dbus_glib_nm_settings_connection_object_info); } diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index b192346fc..643b1756e 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -23,7 +23,6 @@ #define NM_SETTINGS_CONNECTION_H #include -#include G_BEGIN_DECLS @@ -53,12 +52,6 @@ typedef void (*NMSettingsConnectionDeleteFunc) (NMSettingsConnection *connection GError *error, gpointer user_data); -typedef void (*NMSettingsConnectionSecretsUpdatedFunc) (NMSettingsConnection *connection, - const char *setting_name, - guint32 call_id, - GError *error, - gpointer user_data); - struct _NMSettingsConnection { NMConnection parent; }; @@ -77,15 +70,6 @@ struct _NMSettingsConnectionClass { gboolean (*supports_secrets) (NMSettingsConnection *connection, const char *setting_name); - - /* signals */ - guint32 (*get_secrets) (NMSettingsConnection *connection, - const char *sender, /* dbus bus name of requestor */ - const char *setting_name, - NMSettingsConnectionSecretsUpdatedFunc callback, - gpointer callback_data); - - void (*cancel_secrets) (NMSettingsConnection *connection, guint32 call_id); }; GType nm_settings_connection_get_type (void); @@ -107,9 +91,24 @@ void nm_settings_connection_delete (NMSettingsConnection *connection, NMSettingsConnectionDeleteFunc callback, gpointer user_data); -GHashTable *nm_settings_connection_get_secrets (NMSettingsConnection *connection, - const char *setting_name, - GError **error); +typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *connection, + guint32 call_id, + const char *setting_name, + GError *error, + gpointer user_data); + +guint32 nm_settings_connection_get_secrets (NMSettingsConnection *connection, + gboolean filter_by_uid, + gulong uid, + const char *setting_name, + guint32 flags, + const char *hint, + NMSettingsConnectionSecretsFunc callback, + gpointer callback_data, + GError **error); + +void nm_settings_connection_cancel_secrets (NMSettingsConnection *connection, + guint32 call_id); gboolean nm_settings_connection_is_visible (NMSettingsConnection *self); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 542c398a6..e47b89fb4 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -63,6 +63,7 @@ #include "nm-manager-auth.h" #include "nm-session-monitor.h" #include "system-settings/plugins/keyfile/plugin.h" +#include "nm-agent-manager.h" #define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" @@ -104,6 +105,8 @@ typedef struct { NMDBusManager *dbus_mgr; DBusGConnection *bus; + NMAgentManager *agent_mgr; + PolkitAuthority *authority; guint auth_changed_id; char *config_file; @@ -1383,6 +1386,13 @@ nm_settings_init (NMSettings *self) } priv->session_monitor = nm_session_monitor_get (); + + /* Hold a reference to the agent manager so it stays alive; the only + * other holders are NMSettingsConnection objects which are often + * transient, and we don't want the agent manager to get destroyed and + * recreated often. + */ + priv->agent_mgr = nm_agent_manager_get (); } static void @@ -1404,6 +1414,7 @@ dispose (GObject *object) g_object_unref (priv->dbus_mgr); g_object_unref (priv->session_monitor); + g_object_unref (priv->agent_mgr); G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object); } diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 30790f03f..7081f227a 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -47,6 +47,7 @@ #include "nm-dns-manager.h" #include "nm-netlink-monitor.h" #include "nm-glib-compat.h" +#include "settings/nm-settings-connection.h" #include "nm-vpn-connection-glue.h" @@ -768,22 +769,22 @@ cancel_get_secrets (NMVPNConnection *self) NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); if (priv->secrets_id) { - nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id); + nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), priv->secrets_id); priv->secrets_id = 0; } } static void -vpn_secrets_cb (NMActRequest *req, +vpn_secrets_cb (NMSettingsConnection *connection, guint32 call_id, - NMConnection *connection, + const char *setting_name, GError *error, gpointer user_data) { NMVPNConnection *self = NM_VPN_CONNECTION (user_data); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - g_return_if_fail (req == priv->act_request); + g_return_if_fail (NM_CONNECTION (connection) == priv->connection); g_return_if_fail (call_id == priv->secrets_id); priv->secrets_id = 0; @@ -802,6 +803,7 @@ connection_need_secrets_cb (DBusGProxy *proxy, { NMVPNConnection *self = NM_VPN_CONNECTION (user_data); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + GError *local = NULL; if (error) { nm_log_err (LOGD_VPN, "NeedSecrets failed: %s %s", @@ -817,17 +819,21 @@ connection_need_secrets_cb (DBusGProxy *proxy, return; } - priv->secrets_id = nm_act_request_get_secrets_vpn (priv->act_request, - priv->connection, - priv->user_requested, - priv->user_uid, - setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION, - NULL, - vpn_secrets_cb, - self); - if (!priv->secrets_id) + priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection), + priv->user_requested, + priv->user_uid, + setting_name, + NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION, + NULL, + vpn_secrets_cb, + self, + &local); + if (!priv->secrets_id) { + if (local) + nm_log_err (LOGD_VPN, "failed to get secrets: (%d) %s", local->code, local->message); nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); + g_clear_error (&local); + } } static void