diff options
author | Thomas Haller <thaller@redhat.com> | 2019-02-05 08:42:40 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-02-05 08:42:40 +0100 |
commit | d3d8611066a533ce245be6449cba10c6f4b7bb79 (patch) | |
tree | d46de9284e706cac8af556b3812a63043d9d4224 | |
parent | 9f558e4d15352526e40837b8887b804c6979a92d (diff) | |
parent | 472f89da6b5dbd88ffd0815966dfaeb98dd8e024 (diff) | |
download | NetworkManager-d3d8611066a533ce245be6449cba10c6f4b7bb79.tar.gz |
secret-agent: merge branch 'th/secret-agent-cleanup'
https://github.com/NetworkManager/NetworkManager/pull/288
-rw-r--r-- | clients/cli/agent.c | 2 | ||||
-rw-r--r-- | clients/cli/common.c | 2 | ||||
-rw-r--r-- | clients/cli/connections.c | 5 | ||||
-rw-r--r-- | clients/cli/devices.c | 2 | ||||
-rw-r--r-- | clients/cli/nmcli.c | 12 | ||||
-rw-r--r-- | clients/cli/nmcli.h | 4 | ||||
-rw-r--r-- | clients/common/nm-secret-agent-simple.c | 735 | ||||
-rw-r--r-- | clients/common/nm-secret-agent-simple.h | 36 | ||||
-rw-r--r-- | clients/tui/nmtui-connect.c | 8 | ||||
-rw-r--r-- | libnm/nm-secret-agent-old.c | 522 | ||||
-rw-r--r-- | shared/nm-utils/nm-macros-internal.h | 22 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-iwd.c | 4 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem.c | 10 | ||||
-rw-r--r-- | src/nm-act-request.c | 3 | ||||
-rw-r--r-- | src/nm-act-request.h | 2 | ||||
-rw-r--r-- | src/ppp/nm-ppp-manager.c | 10 |
16 files changed, 711 insertions, 668 deletions
diff --git a/clients/cli/agent.c b/clients/cli/agent.c index 05cc5dca5a..55a5ba6b85 100644 --- a/clients/cli/agent.c +++ b/clients/cli/agent.c @@ -149,7 +149,7 @@ do_agent_secret (NmCli *nmc, int argc, char **argv) /* We keep running */ nmc->should_wait++; - nm_secret_agent_simple_enable (NM_SECRET_AGENT_SIMPLE (nmc->secret_agent), NULL); + nm_secret_agent_simple_enable (nmc->secret_agent, NULL); g_signal_connect (nmc->secret_agent, NM_SECRET_AGENT_SIMPLE_REQUEST_SECRETS, G_CALLBACK (secrets_requested), diff --git a/clients/cli/common.c b/clients/cli/common.c index 85b5005e44..56e5062f52 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -778,7 +778,7 @@ nmc_secrets_requested (NMSecretAgentSimple *agent, /* Unregister our secret agent on failure, so that another agent * may be tried */ if (nmc->secret_agent) { - nm_secret_agent_old_unregister (nmc->secret_agent, NULL, NULL); + nm_secret_agent_old_unregister (NM_SECRET_AGENT_OLD (nmc->secret_agent), NULL, NULL); g_clear_object (&nmc->secret_agent); } } diff --git a/clients/cli/connections.c b/clients/cli/connections.c index e2c23cb8c1..b8fac54e5c 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -2474,7 +2474,7 @@ check_activated (ActivateConnectionInfo *info) if (nmc->secret_agent) { NMRemoteConnection *connection = nm_active_connection_get_connection (info->active); - nm_secret_agent_simple_enable (NM_SECRET_AGENT_SIMPLE (nmc->secret_agent), + nm_secret_agent_simple_enable (nmc->secret_agent, nm_connection_get_path (NM_CONNECTION (connection))); } break; @@ -2776,7 +2776,6 @@ nmc_activate_connection (NmCli *nmc, g_hash_table_destroy (nmc->pwds_hash); nmc->pwds_hash = pwds_hash; - /* Create secret agent */ nmc->secret_agent = nm_secret_agent_simple_new ("nmcli-connect"); if (nmc->secret_agent) { g_signal_connect (nmc->secret_agent, @@ -6728,7 +6727,7 @@ progress_activation_editor_cb (gpointer user_data) NMRemoteConnection *connection; connection = nm_active_connection_get_connection (ac); - nm_secret_agent_simple_enable (NM_SECRET_AGENT_SIMPLE (info->nmc->secret_agent), + nm_secret_agent_simple_enable (info->nmc->secret_agent, nm_object_get_path (NM_OBJECT (connection))); } diff --git a/clients/cli/devices.c b/clients/cli/devices.c index 44573fb649..d17cf79980 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -1961,7 +1961,7 @@ connect_device_cb (GObject *client, GAsyncResult *result, gpointer user_data) if (nmc->secret_agent) { NMRemoteConnection *connection = nm_active_connection_get_connection (active); - nm_secret_agent_simple_enable (NM_SECRET_AGENT_SIMPLE (nmc->secret_agent), + nm_secret_agent_simple_enable (nmc->secret_agent, nm_connection_get_path (NM_CONNECTION (connection))); } diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index 6217477cc2..6d38a58857 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -1013,15 +1013,15 @@ nmc_cleanup (NmCli *nmc) g_clear_object (&nmc->client); - g_string_free (nmc->return_text, TRUE); + if (nmc->return_text) + g_string_free (g_steal_pointer (&nmc->return_text), TRUE); if (nmc->secret_agent) { - /* Destroy secret agent if we have one. */ - nm_secret_agent_old_unregister (nmc->secret_agent, NULL, NULL); - g_object_unref (nmc->secret_agent); + nm_secret_agent_old_unregister (NM_SECRET_AGENT_OLD (nmc->secret_agent), NULL, NULL); + g_clear_object (&nmc->secret_agent); } - if (nmc->pwds_hash) - g_hash_table_destroy (nmc->pwds_hash); + + nm_clear_pointer (&nmc->pwds_hash, g_hash_table_destroy); nm_clear_g_free (&nmc->required_fields); diff --git a/clients/cli/nmcli.h b/clients/cli/nmcli.h index 0ccf1653d8..cd50333a99 100644 --- a/clients/cli/nmcli.h +++ b/clients/cli/nmcli.h @@ -20,7 +20,7 @@ #ifndef NMC_NMCLI_H #define NMC_NMCLI_H -#include "nm-secret-agent-old.h" +#include "nm-secret-agent-simple.h" #include "nm-meta-setting-desc.h" struct _NMPolkitListener; @@ -129,7 +129,7 @@ typedef struct _NmCli { int timeout; /* Operation timeout */ - NMSecretAgentOld *secret_agent; /* Secret agent */ + NMSecretAgentSimple *secret_agent; /* Secret agent */ GHashTable *pwds_hash; /* Hash table with passwords in passwd-file */ struct _NMPolkitListener *pk_listener; /* polkit agent listener */ diff --git a/clients/common/nm-secret-agent-simple.c b/clients/common/nm-secret-agent-simple.c index 9fcf4200cd..f649316fe3 100644 --- a/clients/common/nm-secret-agent-simple.c +++ b/clients/common/nm-secret-agent-simple.c @@ -31,124 +31,97 @@ #include "nm-default.h" +#include "nm-secret-agent-simple.h" + #include <gio/gunixoutputstream.h> #include <gio/gunixinputstream.h> #include <string.h> #include "nm-vpn-service-plugin.h" - #include "nm-vpn-helpers.h" -#include "nm-secret-agent-simple.h" - -G_DEFINE_TYPE (NMSecretAgentSimple, nm_secret_agent_simple, NM_TYPE_SECRET_AGENT_OLD) -#define NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimplePrivate)) - -enum { - REQUEST_SECRETS, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; +/*****************************************************************************/ typedef struct { + char *request_id; + NMSecretAgentSimple *self; - char *request_id; NMConnection *connection; char **hints; NMSecretAgentOldGetSecretsFunc callback; gpointer callback_data; GCancellable *cancellable; NMSecretAgentGetSecretsFlags flags; -} NMSecretAgentSimpleRequest; +} RequestData; + +enum { + REQUEST_SECRETS, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { - /* <char *request_id, NMSecretAgentSimpleRequest *request> */ GHashTable *requests; char *path; gboolean enabled; } NMSecretAgentSimplePrivate; -static void -nm_secret_agent_simple_request_free (gpointer data) -{ - NMSecretAgentSimpleRequest *request = data; +struct _NMSecretAgentSimple { + NMSecretAgentOld parent; + NMSecretAgentSimplePrivate _priv; +}; - g_clear_object (&request->cancellable); - g_object_unref (request->self); - g_object_unref (request->connection); - g_strfreev (request->hints); +struct _NMSecretAgentSimpleClass { + NMSecretAgentOldClass parent; +}; - g_slice_free (NMSecretAgentSimpleRequest, request); -} +G_DEFINE_TYPE (NMSecretAgentSimple, nm_secret_agent_simple, NM_TYPE_SECRET_AGENT_OLD) -static void -nm_secret_agent_simple_request_cancel (NMSecretAgentSimpleRequest *request, - GError *error) -{ - NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (request->self); +#define NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSecretAgentSimple, NM_IS_SECRET_AGENT_SIMPLE, NMSecretAgentOld) - request->callback (NM_SECRET_AGENT_OLD (request->self), request->connection, - NULL, error, request->callback_data); - g_hash_table_remove (priv->requests, request->request_id); -} +/*****************************************************************************/ static void -nm_secret_agent_simple_init (NMSecretAgentSimple *agent) +_request_data_free (gpointer data) { - NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (agent); + RequestData *request = data; - priv->requests = g_hash_table_new_full (nm_str_hash, g_str_equal, - g_free, nm_secret_agent_simple_request_free); + g_free (request->request_id); + nm_clear_g_cancellable (&request->cancellable); + g_object_unref (request->connection); + g_strfreev (request->hints); + + g_slice_free (RequestData, request); } static void -nm_secret_agent_simple_finalize (GObject *object) +_request_data_complete (RequestData *request, + GVariant *secrets, + GError *error, + GHashTableIter *iter_to_remove) { - NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (object); - GError *error; - GHashTableIter iter; - gpointer key; - gpointer value; - - error = g_error_new (NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_AGENT_CANCELED, - "The secret agent is going away"); - - g_hash_table_iter_init (&iter, priv->requests); - while (g_hash_table_iter_next (&iter, &key, &value)) { - NMSecretAgentSimpleRequest *request = value; - - request->callback (NM_SECRET_AGENT_OLD (object), - request->connection, - NULL, error, - request->callback_data); - } + NMSecretAgentSimple *self = request->self; + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (self); - g_hash_table_destroy (priv->requests); - g_error_free (error); + nm_assert ((secrets != NULL) != (error != NULL)); - g_free (priv->path); + request->callback (NM_SECRET_AGENT_OLD (request->self), + request->connection, + secrets, + error, + request->callback_data); - G_OBJECT_CLASS (nm_secret_agent_simple_parent_class)->finalize (object); + if (iter_to_remove) + g_hash_table_iter_remove (iter_to_remove); + else + g_hash_table_remove (priv->requests, request); } -static gboolean -strv_has (char **haystack, - char *needle) -{ - char **iter; - - for (iter = haystack; iter && *iter; iter++) { - if (g_strcmp0 (*iter, needle) == 0) - return TRUE; - } - - return FALSE; -} +/*****************************************************************************/ /** * NMSecretAgentSimpleSecret: @@ -164,12 +137,12 @@ typedef struct { NMSecretAgentSimpleSecret base; NMSetting *setting; char *property; -} NMSecretAgentSimpleSecretReal; +} SecretReal; static void -nm_secret_agent_simple_secret_free (NMSecretAgentSimpleSecret *secret) +_secret_real_free (NMSecretAgentSimpleSecret *secret) { - NMSecretAgentSimpleSecretReal *real = (NMSecretAgentSimpleSecretReal *)secret; + SecretReal *real = (SecretReal *)secret; g_free ((char *) secret->pretty_name); g_free ((char *) secret->entry_id); @@ -178,24 +151,24 @@ nm_secret_agent_simple_secret_free (NMSecretAgentSimpleSecret *secret) g_free (real->property); g_clear_object (&real->setting); - g_slice_free (NMSecretAgentSimpleSecretReal, real); + g_slice_free (SecretReal, real); } static NMSecretAgentSimpleSecret * -nm_secret_agent_simple_secret_new (NMSecretAgentSecretType secret_type, - const char *pretty_name, - NMSetting *setting, - const char *property, - const char *vpn_type) +_secret_real_new (NMSecretAgentSecretType secret_type, + const char *pretty_name, + NMSetting *setting, + const char *property, + const char *vpn_type) { - NMSecretAgentSimpleSecretReal *real; + SecretReal *real; const char *vpn_prefix; const char *value; nm_assert (property); nm_assert (NM_IS_SETTING (setting)); - real = g_slice_new0 (NMSecretAgentSimpleSecretReal); + real = g_slice_new0 (SecretReal); *((NMSecretAgentSecretType *) &real->base.secret_type) = secret_type; real->setting = g_object_ref (setting); real->base.pretty_name = g_strdup (pretty_name); @@ -225,9 +198,11 @@ nm_secret_agent_simple_secret_new (NMSecretAgentSecretType secret_type, return &real->base; } +/*****************************************************************************/ + static gboolean -add_8021x_secrets (NMSecretAgentSimpleRequest *request, - GPtrArray *secrets) +add_8021x_secrets (RequestData *request, + GPtrArray *secrets) { NMSetting8021x *s_8021x = nm_connection_get_setting_802_1x (request->connection); const char *eap_method; @@ -238,11 +213,11 @@ add_8021x_secrets (NMSecretAgentSimpleRequest *request, char **iter; for (iter = request->hints; *iter; iter++) { - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _(*iter), - NM_SETTING (s_8021x), - *iter, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _(*iter), + NM_SETTING (s_8021x), + *iter, + NULL); g_ptr_array_add (secrets, secret); } @@ -253,41 +228,41 @@ add_8021x_secrets (NMSecretAgentSimpleRequest *request, if (!eap_method) return FALSE; - if ( !strcmp (eap_method, "md5") - || !strcmp (eap_method, "leap") - || !strcmp (eap_method, "ttls") - || !strcmp (eap_method, "peap")) { + if (NM_IN_STRSET (eap_method, "md5", + "leap", + "ttls", + "peap")) { /* TTLS and PEAP are actually much more complicated, but this complication * is not visible here since we only care about phase2 authentication * (and don't even care of which one) */ - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, - _("Username"), - NM_SETTING (s_8021x), - NM_SETTING_802_1X_IDENTITY, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + _("Username"), + NM_SETTING (s_8021x), + NM_SETTING_802_1X_IDENTITY, + NULL); g_ptr_array_add (secrets, secret); - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _("Password"), - NM_SETTING (s_8021x), - NM_SETTING_802_1X_PASSWORD, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING (s_8021x), + NM_SETTING_802_1X_PASSWORD, + NULL); g_ptr_array_add (secrets, secret); return TRUE; } - if (!strcmp (eap_method, "tls")) { - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, - _("Identity"), - NM_SETTING (s_8021x), - NM_SETTING_802_1X_IDENTITY, - NULL); + if (nm_streq (eap_method, "tls")) { + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + _("Identity"), + NM_SETTING (s_8021x), + NM_SETTING_802_1X_IDENTITY, + NULL); g_ptr_array_add (secrets, secret); - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _("Private key password"), - NM_SETTING (s_8021x), - NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Private key password"), + NM_SETTING (s_8021x), + NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, + NULL); g_ptr_array_add (secrets, secret); return TRUE; } @@ -296,7 +271,7 @@ add_8021x_secrets (NMSecretAgentSimpleRequest *request, } static gboolean -add_wireless_secrets (NMSecretAgentSimpleRequest *request, +add_wireless_secrets (RequestData *request, GPtrArray *secrets) { NMSettingWirelessSecurity *s_wsec = nm_connection_get_setting_wireless_security (request->connection); @@ -306,76 +281,74 @@ add_wireless_secrets (NMSecretAgentSimpleRequest *request, if (!key_mgmt) return FALSE; - if (!strcmp (key_mgmt, "wpa-none") || !strcmp (key_mgmt, "wpa-psk")) { - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _("Password"), - NM_SETTING (s_wsec), - NM_SETTING_WIRELESS_SECURITY_PSK, - NULL); + if (NM_IN_STRSET (key_mgmt, "wpa-none", + "wpa-psk")) { + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING (s_wsec), + NM_SETTING_WIRELESS_SECURITY_PSK, + NULL); g_ptr_array_add (secrets, secret); return TRUE; } - if (!strcmp (key_mgmt, "none")) { - int index; - char *key; + if (nm_streq (key_mgmt, "none")) { + guint32 index; + char key[100]; index = nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec); - key = g_strdup_printf ("wep-key%d", index); - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _("Key"), - NM_SETTING (s_wsec), - key, - NULL); - g_free (key); - + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Key"), + NM_SETTING (s_wsec), + nm_sprintf_buf (key, "wep-key%u", (guint) index), + NULL); g_ptr_array_add (secrets, secret); return TRUE; } - if (!strcmp (key_mgmt, "iee8021x")) { - if (!g_strcmp0 (nm_setting_wireless_security_get_auth_alg (s_wsec), "leap")) { - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _("Password"), - NM_SETTING (s_wsec), - NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, - NULL); + if (nm_streq (key_mgmt, "iee8021x")) { + if (nm_streq0 (nm_setting_wireless_security_get_auth_alg (s_wsec), "leap")) { + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING (s_wsec), + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + NULL); g_ptr_array_add (secrets, secret); return TRUE; } else return add_8021x_secrets (request, secrets); } - if (!strcmp (key_mgmt, "wpa-eap")) + if (nm_streq (key_mgmt, "wpa-eap")) return add_8021x_secrets (request, secrets); return FALSE; } static gboolean -add_pppoe_secrets (NMSecretAgentSimpleRequest *request, +add_pppoe_secrets (RequestData *request, GPtrArray *secrets) { NMSettingPppoe *s_pppoe = nm_connection_get_setting_pppoe (request->connection); NMSecretAgentSimpleSecret *secret; - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, - _("Username"), - NM_SETTING (s_pppoe), - NM_SETTING_PPPOE_USERNAME, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + _("Username"), + NM_SETTING (s_pppoe), + NM_SETTING_PPPOE_USERNAME, + NULL); g_ptr_array_add (secrets, secret); - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, - _("Service"), - NM_SETTING (s_pppoe), - NM_SETTING_PPPOE_SERVICE, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + _("Service"), + NM_SETTING (s_pppoe), + NM_SETTING_PPPOE_SERVICE, + NULL); g_ptr_array_add (secrets, secret); - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _("Password"), - NM_SETTING (s_pppoe), - NM_SETTING_PPPOE_PASSWORD, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING (s_pppoe), + NM_SETTING_PPPOE_PASSWORD, + NULL); g_ptr_array_add (secrets, secret); return TRUE; } @@ -403,11 +376,11 @@ add_vpn_secret_helper (GPtrArray *secrets, NMSettingVpn *s_vpn, const char *name flags = get_vpn_secret_flags (s_vpn, name); if ( flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED || flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) { - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_VPN_SECRET, - ui_name, - NM_SETTING (s_vpn), - name, - nm_setting_vpn_get_service_type (s_vpn)); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_VPN_SECRET, + ui_name, + NM_SETTING (s_vpn), + name, + nm_setting_vpn_get_service_type (s_vpn)); /* Check for duplicates */ for (i = 0; i < secrets->len; i++) { @@ -416,7 +389,7 @@ add_vpn_secret_helper (GPtrArray *secrets, NMSettingVpn *s_vpn, const char *name if ( s->secret_type == secret->secret_type && nm_streq0 (s->vpn_type, secret->vpn_type) && nm_streq0 (s->entry_id, secret->entry_id)) { - nm_secret_agent_simple_secret_free (secret); + _secret_real_free (secret); return; } } @@ -428,7 +401,7 @@ add_vpn_secret_helper (GPtrArray *secrets, NMSettingVpn *s_vpn, const char *name #define VPN_MSG_TAG "x-vpn-message:" static gboolean -add_vpn_secrets (NMSecretAgentSimpleRequest *request, +add_vpn_secrets (RequestData *request, GPtrArray *secrets, char **msg) { @@ -461,17 +434,21 @@ add_vpn_secrets (NMSecretAgentSimpleRequest *request, typedef struct { GPid auth_dialog_pid; - char read_buf[5]; GString *auth_dialog_response; - NMSecretAgentSimpleRequest *request; + RequestData *request; GPtrArray *secrets; - guint child_watch_id; + GCancellable *cancellable; gulong cancellable_id; + guint child_watch_id; + char read_buf[5]; } AuthDialogData; static void _auth_dialog_data_free (AuthDialogData *data) { + nm_clear_g_signal_handler (data->cancellable, &data->cancellable_id); + g_clear_object (&data->cancellable); + nm_clear_g_source (&data->child_watch_id); g_ptr_array_unref (data->secrets); g_spawn_close_pid (data->auth_dialog_pid); g_string_free (data->auth_dialog_response, TRUE); @@ -482,17 +459,19 @@ static void _auth_dialog_exited (GPid pid, int status, gpointer user_data) { AuthDialogData *data = user_data; - NMSecretAgentSimpleRequest *request = data->request; + RequestData *request = data->request; GPtrArray *secrets = data->secrets; NMSettingVpn *s_vpn = nm_connection_get_setting_vpn (request->connection); - GKeyFile *keyfile = NULL; + gs_unref_keyfile GKeyFile *keyfile = NULL; gs_strfreev char **groups = NULL; gs_free char *title = NULL; gs_free char *message = NULL; int i; gs_free_error GError *error = NULL; - g_cancellable_disconnect (request->cancellable, data->cancellable_id); + data->child_watch_id = 0; + + nm_clear_g_cancellable_disconnect (data->cancellable, &data->cancellable_id); if (status != 0) { g_set_error (&error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED, @@ -509,7 +488,7 @@ _auth_dialog_exited (GPid pid, int status, gpointer user_data) } groups = g_key_file_get_groups (keyfile, NULL); - if (g_strcmp0 (groups[0], "VPN Plugin UI") != 0) { + if (!nm_streq0 (groups[0], "VPN Plugin UI")) { g_set_error (&error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED, "Expected [VPN Plugin UI] in auth dialog response"); goto out; @@ -529,13 +508,11 @@ _auth_dialog_exited (GPid pid, int status, gpointer user_data) if (!g_key_file_get_boolean (keyfile, groups[i], "ShouldAsk", NULL)) continue; - g_ptr_array_add (secrets, - nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_VPN_SECRET, - g_key_file_get_string (keyfile, groups[i], "Label", NULL), - NM_SETTING (s_vpn), - groups[i], - nm_setting_vpn_get_service_type (s_vpn))); - + g_ptr_array_add (secrets, _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_VPN_SECRET, + g_key_file_get_string (keyfile, groups[i], "Label", NULL), + NM_SETTING (s_vpn), + groups[i], + nm_setting_vpn_get_service_type (s_vpn))); } out: @@ -550,24 +527,20 @@ out: } } - if (error) { - nm_secret_agent_simple_request_cancel (request, error); - } else { + if (error) + _request_data_complete (request, NULL, error, NULL); + else { g_signal_emit (request->self, signals[REQUEST_SECRETS], 0, request->request_id, title, message, secrets); } - g_clear_pointer (&keyfile, g_key_file_unref); _auth_dialog_data_free (data); } static void _request_cancelled (GObject *object, gpointer user_data) { - AuthDialogData *data = user_data; - - g_source_remove (data->child_watch_id); - _auth_dialog_data_free (data); + _auth_dialog_data_free (user_data); } static void @@ -584,14 +557,15 @@ _auth_dialog_read_done (GObject *source_object, switch (read_size) { case -1: if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - nm_secret_agent_simple_request_cancel (data->request, error); + _request_data_complete (data->request, NULL, error, NULL); _auth_dialog_data_free (data); break; case 0: /* Done reading. Let's wait for the auth dialog to exit so that we're able to collect the status. * Remember we can be cancelled in between. */ data->child_watch_id = g_child_watch_add (data->auth_dialog_pid, _auth_dialog_exited, data); - data->cancellable_id = g_cancellable_connect (data->request->cancellable, + data->cancellable = g_object_ref (data->request->cancellable); + data->cancellable_id = g_cancellable_connect (data->cancellable, G_CALLBACK (_request_cancelled), data, NULL); break; default: @@ -615,12 +589,11 @@ _auth_dialog_write_done (GObject *source_object, gpointer user_data) { GOutputStream *auth_dialog_out = G_OUTPUT_STREAM (source_object); - GString *auth_dialog_request = user_data; + _nm_unused gs_free char *auth_dialog_request_free = user_data; /* We don't care about write errors. If there are any problems, the * reader shall notice. */ g_output_stream_write_finish (auth_dialog_out, res, NULL); - g_string_free (auth_dialog_request, TRUE); g_output_stream_close (auth_dialog_out, NULL, NULL); } @@ -661,7 +634,7 @@ _add_secret_to_string (const char *key, const char *value, gpointer user_data) } static gboolean -try_spawn_vpn_auth_helper (NMSecretAgentSimpleRequest *request, +try_spawn_vpn_auth_helper (RequestData *request, GPtrArray *secrets) { NMSettingVpn *s_vpn = nm_connection_get_setting_vpn (request->connection); @@ -683,6 +656,8 @@ try_spawn_vpn_auth_helper (NMSecretAgentSimpleRequest *request, GInputStream *auth_dialog_out; GError *error = NULL; GString *auth_dialog_request; + char *auth_dialog_request_str; + gsize auth_dialog_request_len; AuthDialogData *data; plugin_info = nm_vpn_plugin_info_list_find_by_service (nm_vpn_get_plugin_infos (), @@ -720,20 +695,24 @@ try_spawn_vpn_auth_helper (NMSecretAgentSimpleRequest *request, nm_setting_vpn_foreach_data_item (s_vpn, _add_data_item_to_string, auth_dialog_request); nm_setting_vpn_foreach_secret (s_vpn, _add_secret_to_string, auth_dialog_request); g_string_append (auth_dialog_request, "DONE\nQUIT\n"); + auth_dialog_request_len = auth_dialog_request->len; + auth_dialog_request_str = g_string_free (auth_dialog_request, FALSE); - data = g_slice_alloc0 (sizeof (AuthDialogData)); - data->auth_dialog_response = g_string_new_len (NULL, sizeof (data->read_buf)); - data->auth_dialog_pid = auth_dialog_pid; - data->request = request; - data->secrets = secrets; + data = g_slice_new (AuthDialogData); + *data = (AuthDialogData) { + .auth_dialog_response = g_string_new_len (NULL, sizeof (data->read_buf)), + .auth_dialog_pid = auth_dialog_pid, + .request = request, + .secrets = secrets, + }; g_output_stream_write_async (auth_dialog_in, - auth_dialog_request->str, - auth_dialog_request->len, + auth_dialog_request_str, + auth_dialog_request_len, G_PRIORITY_DEFAULT, request->cancellable, _auth_dialog_write_done, - auth_dialog_request); + auth_dialog_request_str); g_input_stream_read_async (auth_dialog_out, data->read_buf, @@ -747,30 +726,27 @@ try_spawn_vpn_auth_helper (NMSecretAgentSimpleRequest *request, } static void -request_secrets_from_ui (NMSecretAgentSimpleRequest *request) +request_secrets_from_ui (RequestData *request) { - GPtrArray *secrets; + gs_unref_ptrarray GPtrArray *secrets = NULL; + gs_free_error GError *error = NULL; NMSecretAgentSimplePrivate *priv; NMSecretAgentSimpleSecret *secret; const char *title; - char *msg; - gboolean ok = TRUE; + gs_free char *msg = NULL; priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (request->self); g_return_if_fail (priv->enabled); /* We only handle requests for connection with @path if set. */ if (priv->path && !g_str_has_prefix (request->request_id, priv->path)) { - gs_free_error GError *error = NULL; - - error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED, - "Request for %s secrets doesn't match path %s", - request->request_id, priv->path); - nm_secret_agent_simple_request_cancel (request, error); - return; + g_set_error (&error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED, + "Request for %s secrets doesn't match path %s", + request->request_id, priv->path); + goto out_fail_error; } - secrets = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_secret_agent_simple_secret_free); + secrets = g_ptr_array_new_with_free_func ((GDestroyNotify) _secret_real_free); if (nm_connection_is_type (request->connection, NM_SETTING_WIRELESS_SETTING_NAME)) { NMSettingWireless *s_wireless; @@ -785,42 +761,45 @@ request_secrets_from_ui (NMSecretAgentSimpleRequest *request) title = _("Authentication required by wireless network"); msg = g_strdup_printf (_("Passwords or encryption keys are required to access the wireless network '%s'."), ssid_utf8); - ok = add_wireless_secrets (request, secrets); + if (!add_wireless_secrets (request, secrets)) + goto out_fail; } else if (nm_connection_is_type (request->connection, NM_SETTING_WIRED_SETTING_NAME)) { title = _("Wired 802.1X authentication"); msg = g_strdup_printf (_("Secrets are required to access the wired network '%s'"), nm_connection_get_id (request->connection)); - ok = add_8021x_secrets (request, secrets); + if (!add_8021x_secrets (request, secrets)) + goto out_fail; } else if (nm_connection_is_type (request->connection, NM_SETTING_PPPOE_SETTING_NAME)) { title = _("DSL authentication"); msg = g_strdup_printf (_("Secrets are required for the DSL connection '%s'"), nm_connection_get_id (request->connection)); - ok = add_pppoe_secrets (request, secrets); + if (!add_pppoe_secrets (request, secrets)) + goto out_fail; } else if (nm_connection_is_type (request->connection, NM_SETTING_GSM_SETTING_NAME)) { NMSettingGsm *s_gsm = nm_connection_get_setting_gsm (request->connection); - if (strv_has (request->hints, "pin")) { + if (g_strv_contains (NM_CAST_STRV_CC (request->hints), NM_SETTING_GSM_PIN)) { title = _("PIN code required"); msg = g_strdup (_("PIN code is needed for the mobile broadband device")); - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, - _("PIN"), - NM_SETTING (s_gsm), - NM_SETTING_GSM_PIN, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + _("PIN"), + NM_SETTING (s_gsm), + NM_SETTING_GSM_PIN, + NULL); g_ptr_array_add (secrets, secret); } else { title = _("Mobile broadband network password"); msg = g_strdup_printf (_("A password is required to connect to '%s'."), nm_connection_get_id (request->connection)); - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _("Password"), - NM_SETTING (s_gsm), - NM_SETTING_GSM_PASSWORD, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING (s_gsm), + NM_SETTING_GSM_PASSWORD, + NULL); g_ptr_array_add (secrets, secret); } } else if (nm_connection_is_type (request->connection, NM_SETTING_MACSEC_SETTING_NAME)) { @@ -831,15 +810,16 @@ request_secrets_from_ui (NMSecretAgentSimpleRequest *request) if (nm_setting_macsec_get_mode (s_macsec) == NM_SETTING_MACSEC_MODE_PSK) { title = _("MACsec PSK authentication"); - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _("MKA CAK"), - NM_SETTING (s_macsec), - NM_SETTING_MACSEC_MKA_CAK, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("MKA CAK"), + NM_SETTING (s_macsec), + NM_SETTING_MACSEC_MKA_CAK, + NULL); g_ptr_array_add (secrets, secret); } else { title = _("MACsec EAP authentication"); - ok = add_8021x_secrets (request, secrets); + if (!add_8021x_secrets (request, secrets)) + goto out_fail; } } else if (nm_connection_is_type (request->connection, NM_SETTING_CDMA_SETTING_NAME)) { NMSettingCdma *s_cdma = nm_connection_get_setting_cdma (request->connection); @@ -848,11 +828,11 @@ request_secrets_from_ui (NMSecretAgentSimpleRequest *request) msg = g_strdup_printf (_("A password is required to connect to '%s'."), nm_connection_get_id (request->connection)); - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _("Password"), - NM_SETTING (s_cdma), - NM_SETTING_CDMA_PASSWORD, - NULL); + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING (s_cdma), + NM_SETTING_CDMA_PASSWORD, + NULL); g_ptr_array_add (secrets, secret); } else if (nm_connection_is_type (request->connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) { NMSetting *setting = NULL; @@ -865,76 +845,73 @@ request_secrets_from_ui (NMSecretAgentSimpleRequest *request) setting = nm_connection_get_setting_by_name (request->connection, NM_SETTING_CDMA_SETTING_NAME); } - if (setting) { - title = _("Mobile broadband network password"); - msg = g_strdup_printf (_("A password is required to connect to '%s'."), - nm_connection_get_id (request->connection)); + if (!setting) + goto out_fail; - secret = nm_secret_agent_simple_secret_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, - _("Password"), - setting, - "password", - NULL); - g_ptr_array_add (secrets, secret); - } else - ok = FALSE; + title = _("Mobile broadband network password"); + msg = g_strdup_printf (_("A password is required to connect to '%s'."), + nm_connection_get_id (request->connection)); + + secret = _secret_real_new (NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + setting, + "password", + NULL); + g_ptr_array_add (secrets, secret); } else if (nm_connection_is_type (request->connection, NM_SETTING_VPN_SETTING_NAME)) { title = _("VPN password required"); - msg = NULL; if (try_spawn_vpn_auth_helper (request, secrets)) { /* This will emit REQUEST_SECRETS when ready */ return; } - ok = add_vpn_secrets (request, secrets, &msg); - if (!msg) + if (!add_vpn_secrets (request, secrets, &msg)) + goto out_fail; + if (!msg) { msg = g_strdup_printf (_("A password is required to connect to '%s'."), nm_connection_get_id (request->connection)); + } } else - ok = FALSE; - - if (!ok) { - gs_free_error GError *error = NULL; - - error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED, - "Cannot service a secrets request %s for a %s connection", - request->request_id, - nm_connection_get_connection_type (request->connection)); - nm_secret_agent_simple_request_cancel (request, error); - g_ptr_array_unref (secrets); - return; - } + goto out_fail; g_signal_emit (request->self, signals[REQUEST_SECRETS], 0, request->request_id, title, msg, secrets); + return; + +out_fail: + g_set_error (&error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED, + "Cannot service a secrets request %s for a %s connection", + request->request_id, + nm_connection_get_connection_type (request->connection)); +out_fail_error: + _request_data_complete (request, NULL, error, NULL); + } static void -nm_secret_agent_simple_get_secrets (NMSecretAgentOld *agent, - NMConnection *connection, - const char *connection_path, - const char *setting_name, - const char **hints, - NMSecretAgentGetSecretsFlags flags, - NMSecretAgentOldGetSecretsFunc callback, - gpointer callback_data) +get_secrets (NMSecretAgentOld *agent, + NMConnection *connection, + const char *connection_path, + const char *setting_name, + const char **hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer callback_data) { NMSecretAgentSimple *self = NM_SECRET_AGENT_SIMPLE (agent); NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (self); - NMSecretAgentSimpleRequest *request; - char *request_id; - GError *error; + RequestData *request; + gs_free_error GError *error = NULL; + gs_free char *request_id = NULL; request_id = g_strdup_printf ("%s/%s", connection_path, setting_name); - if (g_hash_table_lookup (priv->requests, request_id) != NULL) { + + if (g_hash_table_contains (priv->requests, &request_id)) { /* We already have a request pending for this (connection, setting) */ error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED, "Request for %s secrets already pending", request_id); - nope: callback (agent, connection, NULL, error, callback_data); - g_error_free (error); - g_free (request_id); return; } @@ -942,19 +919,22 @@ nm_secret_agent_simple_get_secrets (NMSecretAgentOld *agent, /* We don't do stored passwords */ error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_NO_SECRETS, "Stored passwords not supported"); - goto nope; + callback (agent, connection, NULL, error, callback_data); + return; } - request = g_slice_new (NMSecretAgentSimpleRequest); - request->self = g_object_ref (self); - request->connection = g_object_ref (connection); - request->hints = g_strdupv ((char **)hints); - request->callback = callback; - request->callback_data = callback_data; - request->request_id = request_id; - request->flags = flags; - request->cancellable = g_cancellable_new (); - g_hash_table_replace (priv->requests, request->request_id, request); + request = g_slice_new (RequestData); + *request = (RequestData) { + .self = self, + .connection = g_object_ref (connection), + .hints = g_strdupv ((char **) hints), + .callback = callback, + .callback_data = callback_data, + .request_id = g_steal_pointer (&request_id), + .flags = flags, + .cancellable = g_cancellable_new (), + }; + g_hash_table_add (priv->requests, request); if (priv->enabled) request_secrets_from_ui (request); @@ -980,15 +960,15 @@ nm_secret_agent_simple_response (NMSecretAgentSimple *self, GPtrArray *secrets) { NMSecretAgentSimplePrivate *priv; - NMSecretAgentSimpleRequest *request; - GVariant *dict = NULL; - GError *error = NULL; + RequestData *request; + gs_unref_variant GVariant *secrets_dict = NULL; + gs_free_error GError *error = NULL; int i; g_return_if_fail (NM_IS_SECRET_AGENT_SIMPLE (self)); priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (self); - request = g_hash_table_lookup (priv->requests, request_id); + request = g_hash_table_lookup (priv->requests, &request_id); g_return_if_fail (request != NULL); if (secrets) { @@ -1001,7 +981,7 @@ nm_secret_agent_simple_response (NMSecretAgentSimple *self, settings = g_hash_table_new (nm_str_hash, g_str_equal); for (i = 0; i < secrets->len; i++) { - NMSecretAgentSimpleSecretReal *secret = secrets->pdata[i]; + SecretReal *secret = secrets->pdata[i]; setting_builder = g_hash_table_lookup (settings, nm_setting_get_name (secret->setting)); if (!setting_builder) { @@ -1038,49 +1018,59 @@ nm_secret_agent_simple_response (NMSecretAgentSimple *self, g_hash_table_iter_init (&iter, settings); while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &setting_builder)) g_variant_builder_add (&conn_builder, "{sa{sv}}", name, setting_builder); - dict = g_variant_builder_end (&conn_builder); + secrets_dict = g_variant_ref_sink (g_variant_builder_end (&conn_builder)); g_hash_table_destroy (settings); } else { error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_USER_CANCELED, "User cancelled"); } - request->callback (NM_SECRET_AGENT_OLD (self), request->connection, dict, error, request->callback_data); - - g_clear_error (&error); - g_hash_table_remove (priv->requests, request_id); + _request_data_complete (request, secrets_dict, error, NULL); } static void -nm_secret_agent_simple_cancel_get_secrets (NMSecretAgentOld *agent, - const char *connection_path, - const char *setting_name) +cancel_get_secrets (NMSecretAgentOld *agent, + const char *connection_path, + const char *setting_name) { NMSecretAgentSimple *self = NM_SECRET_AGENT_SIMPLE (agent); NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (self); + gs_free_error GError *error = NULL; gs_free char *request_id = NULL; + RequestData *request; request_id = g_strdup_printf ("%s/%s", connection_path, setting_name); - g_hash_table_remove (priv->requests, request_id); + request = g_hash_table_lookup (priv->requests, &request_id); + if (!request) { + /* this is really a bug of the caller (or us?). We cannot invoke a callback, + * hence the caller cannot cleanup the request. */ + g_return_if_reached (); + } + + g_set_error (&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_AGENT_CANCELED, + "The secret agent is going away"); + _request_data_complete (request, NULL, error, NULL); } static void -nm_secret_agent_simple_save_secrets (NMSecretAgentOld *agent, - NMConnection *connection, - const char *connection_path, - NMSecretAgentOldSaveSecretsFunc callback, - gpointer callback_data) +save_secrets (NMSecretAgentOld *agent, + NMConnection *connection, + const char *connection_path, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer callback_data) { /* We don't support secret storage */ callback (agent, connection, NULL, callback_data); } static void -nm_secret_agent_simple_delete_secrets (NMSecretAgentOld *agent, - NMConnection *connection, - const char *connection_path, - NMSecretAgentOldDeleteSecretsFunc callback, - gpointer callback_data) +delete_secrets (NMSecretAgentOld *agent, + NMConnection *connection, + const char *connection_path, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer callback_data) { /* We don't support secret storage, so there's nothing to delete. */ callback (agent, connection, NULL, callback_data); @@ -1100,7 +1090,8 @@ void nm_secret_agent_simple_enable (NMSecretAgentSimple *self, const char *path) { NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (self); - GList *requests, *iter; + gs_free RequestData **requests = NULL; + gsize i; gs_free char *path_full = NULL; /* The path is only used to match a request_id with the current @@ -1109,10 +1100,9 @@ nm_secret_agent_simple_enable (NMSecretAgentSimple *self, const char *path) */ path_full = path ? g_strdup_printf ("%s/", path) : NULL; - if (g_strcmp0 (path_full, priv->path) != 0) { + if (!nm_streq0 (path_full, priv->path)) { g_free (priv->path); - priv->path = path_full; - path_full = NULL; + priv->path = g_steal_pointer (&path_full); } if (priv->enabled) @@ -1120,27 +1110,85 @@ nm_secret_agent_simple_enable (NMSecretAgentSimple *self, const char *path) priv->enabled = TRUE; /* Service pending secret requests. */ - requests = g_hash_table_get_values (priv->requests); - for (iter = requests; iter; iter = g_list_next (iter)) - request_secrets_from_ui (iter->data); + requests = (RequestData **) g_hash_table_get_keys_as_array (priv->requests, NULL); + for (i = 0; requests[i]; i++) + request_secrets_from_ui (requests[i]); +} + +/*****************************************************************************/ + +static void +nm_secret_agent_simple_init (NMSecretAgentSimple *agent) +{ + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (agent); + + G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (RequestData, request_id) == 0); + priv->requests = g_hash_table_new_full (nm_pstr_hash, nm_pstr_equal, + NULL, _request_data_free); +} + +/** + * nm_secret_agent_simple_new: + * @name: the identifier of secret agent + * + * Creates a new #NMSecretAgentSimple. It does not serve any requests until + * nm_secret_agent_simple_enable() is called. + * + * Returns: a new #NMSecretAgentSimple if the agent creation is successful + * or %NULL in case of a failure. + */ +NMSecretAgentSimple * +nm_secret_agent_simple_new (const char *name) +{ + return g_initable_new (NM_TYPE_SECRET_AGENT_SIMPLE, NULL, NULL, + NM_SECRET_AGENT_OLD_IDENTIFIER, name, + NM_SECRET_AGENT_OLD_CAPABILITIES, NM_SECRET_AGENT_CAPABILITY_VPN_HINTS, + NULL); +} + +static void +dispose (GObject *object) +{ + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (object); + gs_free_error GError *error = NULL; + GHashTableIter iter; + RequestData *request; + + g_hash_table_iter_init (&iter, priv->requests); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &request)) { + if (!error) + nm_utils_error_set_cancelled (&error, TRUE, "NMSecretAgentSimple"); + _request_data_complete (request, NULL, error, &iter); + } + + G_OBJECT_CLASS (nm_secret_agent_simple_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (object); + + g_hash_table_destroy (priv->requests); - g_list_free (requests); + g_free (priv->path); + + G_OBJECT_CLASS (nm_secret_agent_simple_parent_class)->finalize (object); } void nm_secret_agent_simple_class_init (NMSecretAgentSimpleClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); NMSecretAgentOldClass *agent_class = NM_SECRET_AGENT_OLD_CLASS (klass); - g_type_class_add_private (klass, sizeof (NMSecretAgentSimplePrivate)); + object_class->dispose = dispose; + object_class->finalize = finalize; - gobject_class->finalize = nm_secret_agent_simple_finalize; - - agent_class->get_secrets = nm_secret_agent_simple_get_secrets; - agent_class->cancel_get_secrets = nm_secret_agent_simple_cancel_get_secrets; - agent_class->save_secrets = nm_secret_agent_simple_save_secrets; - agent_class->delete_secrets = nm_secret_agent_simple_delete_secrets; + agent_class->get_secrets = get_secrets; + agent_class->cancel_get_secrets = cancel_get_secrets; + agent_class->save_secrets = save_secrets; + agent_class->delete_secrets = delete_secrets; /** * NMSecretAgentSimple::request-secrets: @@ -1174,22 +1222,3 @@ nm_secret_agent_simple_class_init (NMSecretAgentSimpleClass *klass) G_TYPE_STRING, /* prompt */ G_TYPE_PTR_ARRAY); } - -/** - * nm_secret_agent_simple_new: - * @name: the identifier of secret agent - * - * Creates a new #NMSecretAgentSimple. It does not serve any requests until - * nm_secret_agent_simple_enable() is called. - * - * Returns: a new #NMSecretAgentSimple if the agent creation is successful - * or %NULL in case of a failure. - */ -NMSecretAgentOld * -nm_secret_agent_simple_new (const char *name) -{ - return g_initable_new (NM_TYPE_SECRET_AGENT_SIMPLE, NULL, NULL, - NM_SECRET_AGENT_OLD_IDENTIFIER, name, - NM_SECRET_AGENT_OLD_CAPABILITIES, NM_SECRET_AGENT_CAPABILITY_VPN_HINTS, - NULL); -} diff --git a/clients/common/nm-secret-agent-simple.h b/clients/common/nm-secret-agent-simple.h index 529aaeaca9..8cae17a8c2 100644 --- a/clients/common/nm-secret-agent-simple.h +++ b/clients/common/nm-secret-agent-simple.h @@ -21,26 +21,6 @@ #include "nm-secret-agent-old.h" -#define NM_TYPE_SECRET_AGENT_SIMPLE (nm_secret_agent_simple_get_type ()) -#define NM_SECRET_AGENT_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimple)) -#define NM_SECRET_AGENT_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimpleClass)) -#define NM_IS_SECRET_AGENT_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRET_AGENT_SIMPLE)) -#define NM_IS_SECRET_AGENT_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SECRET_AGENT_SIMPLE)) -#define NM_SECRET_AGENT_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimpleClass)) - -/* Signals */ -#define NM_SECRET_AGENT_SIMPLE_REQUEST_SECRETS "request-secrets" - -typedef struct { - NMSecretAgentOld parent; - -} NMSecretAgentSimple; - -typedef struct { - NMSecretAgentOldClass parent; - -} NMSecretAgentSimpleClass; - typedef enum { NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, NM_SECRET_AGENT_SECRET_TYPE_SECRET, @@ -60,9 +40,23 @@ typedef struct { #define NM_SECRET_AGENT_VPN_TYPE_OPENCONNECT NM_DBUS_INTERFACE".openconnect" +/*****************************************************************************/ + +#define NM_TYPE_SECRET_AGENT_SIMPLE (nm_secret_agent_simple_get_type ()) +#define NM_SECRET_AGENT_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimple)) +#define NM_SECRET_AGENT_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimpleClass)) +#define NM_IS_SECRET_AGENT_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRET_AGENT_SIMPLE)) +#define NM_IS_SECRET_AGENT_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SECRET_AGENT_SIMPLE)) +#define NM_SECRET_AGENT_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimpleClass)) + +#define NM_SECRET_AGENT_SIMPLE_REQUEST_SECRETS "request-secrets" + +typedef struct _NMSecretAgentSimple NMSecretAgentSimple; +typedef struct _NMSecretAgentSimpleClass NMSecretAgentSimpleClass; + GType nm_secret_agent_simple_get_type (void); -NMSecretAgentOld *nm_secret_agent_simple_new (const char *name); +NMSecretAgentSimple *nm_secret_agent_simple_new (const char *name); void nm_secret_agent_simple_response (NMSecretAgentSimple *self, const char *request_id, diff --git a/clients/tui/nmtui-connect.c b/clients/tui/nmtui-connect.c index 6f29e13e9e..e43c22e4fd 100644 --- a/clients/tui/nmtui-connect.c +++ b/clients/tui/nmtui-connect.c @@ -240,7 +240,7 @@ activate_connection (NMConnection *connection, NMObject *specific_object) { NmtNewtForm *form; - gs_unref_object NMSecretAgentOld *agent = NULL; + gs_unref_object NMSecretAgentSimple *agent = NULL; NmtNewtWidget *label; NmtSyncOp op; const char *specific_object_path; @@ -257,7 +257,7 @@ activate_connection (NMConnection *connection, agent = nm_secret_agent_simple_new ("nmtui"); if (agent) { if (connection) { - nm_secret_agent_simple_enable (NM_SECRET_AGENT_SIMPLE (agent), + nm_secret_agent_simple_enable (agent, nm_object_get_path (NM_OBJECT (connection))); } g_signal_connect (agent, @@ -303,7 +303,7 @@ activate_connection (NMConnection *connection, if (agent && !connection) { connection = NM_CONNECTION (nm_active_connection_get_connection (ac)); if (connection) { - nm_secret_agent_simple_enable (NM_SECRET_AGENT_SIMPLE (agent), + nm_secret_agent_simple_enable (agent, nm_object_get_path (NM_OBJECT (connection))); } } @@ -341,7 +341,7 @@ activate_connection (NMConnection *connection, g_object_unref (form); if (agent) - nm_secret_agent_old_unregister (agent, NULL, NULL); + nm_secret_agent_old_unregister (NM_SECRET_AGENT_OLD (agent), NULL, NULL); } static void diff --git a/libnm/nm-secret-agent-old.c b/libnm/nm-secret-agent-old.c index 1b9e8915bb..2f2482d99d 100644 --- a/libnm/nm-secret-agent-old.c +++ b/libnm/nm-secret-agent-old.c @@ -20,55 +20,65 @@ #include "nm-default.h" +#include "nm-secret-agent-old.h" + #include <string.h> #include "nm-dbus-interface.h" -#include "nm-secret-agent-old.h" #include "nm-enum-types.h" #include "nm-dbus-helpers.h" #include "nm-simple-connection.h" #include "nm-core-internal.h" +#include "c-list/src/c-list.h" #include "introspection/org.freedesktop.NetworkManager.SecretAgent.h" #include "introspection/org.freedesktop.NetworkManager.AgentManager.h" -static void nm_secret_agent_old_initable_iface_init (GInitableIface *iface); -static void nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface); -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMSecretAgentOld, nm_secret_agent_old, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_secret_agent_old_initable_iface_init); - G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_secret_agent_old_async_initable_iface_init); - ) - -#define NM_SECRET_AGENT_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldPrivate)) +/*****************************************************************************/ typedef struct { - gboolean registered; - gboolean registering; - NMSecretAgentCapabilities capabilities; + char *path; + char *setting_name; + GDBusMethodInvocation *context; + CList gsi_lst; +} GetSecretsInfo; +NM_GOBJECT_PROPERTIES_DEFINE (NMSecretAgentOld, + PROP_IDENTIFIER, + PROP_AUTO_REGISTER, + PROP_REGISTERED, + PROP_CAPABILITIES, +); + +typedef struct { GDBusConnection *bus; - gboolean private_bus; - gboolean session_bus; NMDBusAgentManager *manager_proxy; NMDBusSecretAgent *dbus_secret_agent; /* GetSecretsInfo structs of in-flight GetSecrets requests */ - GSList *pending_gets; + CList gsi_lst_head; char *identifier; - gboolean auto_register; - gboolean suppress_auto; + + NMSecretAgentCapabilities capabilities; + + bool registered:1; + bool registering:1; + bool private_bus:1; + bool session_bus:1; + bool auto_register:1; + bool suppress_auto:1; } NMSecretAgentOldPrivate; -enum { - PROP_0, - PROP_IDENTIFIER, - PROP_AUTO_REGISTER, - PROP_REGISTERED, - PROP_CAPABILITIES, +static void nm_secret_agent_old_initable_iface_init (GInitableIface *iface); +static void nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface); - LAST_PROP -}; +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMSecretAgentOld, nm_secret_agent_old, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_secret_agent_old_initable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_secret_agent_old_async_initable_iface_init); + ) + +#define NM_SECRET_AGENT_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldPrivate)) /*****************************************************************************/ @@ -81,29 +91,20 @@ _internal_unregister (NMSecretAgentOld *self) g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent)); priv->registered = FALSE; priv->registering = FALSE; - g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED); + _notify (self, PROP_REGISTERED); } } -typedef struct { - char *path; - char *setting_name; - GDBusMethodInvocation *context; -} GetSecretsInfo; - static void -get_secrets_info_finalize (NMSecretAgentOld *self, GetSecretsInfo *info) +get_secrets_info_free (GetSecretsInfo *info) { - NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - - g_return_if_fail (info != NULL); + nm_assert (info); - priv->pending_gets = g_slist_remove (priv->pending_gets, info); + c_list_unlink_stale (&info->gsi_lst); g_free (info->path); g_free (info->setting_name); - memset (info, 0, sizeof (*info)); - g_free (info); + g_slice_free (GetSecretsInfo, info); } static inline gboolean @@ -124,25 +125,20 @@ name_owner_changed (GObject *proxy, { NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (user_data); NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - GSList *iter; - char *owner; + gs_free char *owner = NULL; + GetSecretsInfo *info; owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy)); - if (owner != NULL) { + if (owner) { if (should_auto_register (self)) nm_secret_agent_old_register_async (self, NULL, NULL, NULL); - g_free (owner); } else { - /* Cancel any pending secrets requests */ - for (iter = priv->pending_gets; iter; iter = g_slist_next (iter)) { - GetSecretsInfo *info = iter->data; - + while ((info = c_list_first_entry (&priv->gsi_lst_head, GetSecretsInfo, gsi_lst))) { + c_list_unlink (&info->gsi_lst); NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self, - info->path, - info->setting_name); + info->path, + info->setting_name); } - g_slist_free (priv->pending_gets); - priv->pending_gets = NULL; _internal_unregister (self); } @@ -154,11 +150,11 @@ verify_sender (NMSecretAgentOld *self, GError **error) { NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - char *nm_owner; + gs_free char *owner = NULL; const char *sender; guint32 sender_uid; - GVariant *ret; - GError *local = NULL; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *local = NULL; g_return_val_if_fail (context != NULL, FALSE); @@ -170,8 +166,8 @@ verify_sender (NMSecretAgentOld *self, /* Verify that the sender is the same as NetworkManager's bus name owner. */ - nm_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy)); - if (!nm_owner) { + owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy)); + if (!owner) { g_set_error_literal (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, @@ -185,20 +181,16 @@ verify_sender (NMSecretAgentOld *self, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, "Failed to get request sender."); - g_free (nm_owner); return FALSE; } - /* Check that the sender matches the current NM bus name owner */ - if (strcmp (sender, nm_owner) != 0) { + if (!nm_streq (sender, owner)) { g_set_error_literal (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, "Request sender does not match NetworkManager bus name owner."); - g_free (nm_owner); return FALSE; } - g_free (nm_owner); /* If we're connected to the session bus, then this must be a test program, * so skip the UID check. @@ -217,8 +209,9 @@ verify_sender (NMSecretAgentOld *self, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &local); if (!ret) { - char *remote_error = g_dbus_error_get_remote_error (local); + gs_free char *remote_error = NULL; + remote_error = g_dbus_error_get_remote_error (local); g_dbus_error_strip_remote_error (local); g_set_error (error, NM_SECRET_AGENT_ERROR, @@ -226,15 +219,12 @@ verify_sender (NMSecretAgentOld *self, "Failed to request unix user: (%s) %s.", remote_error ?: "", local->message); - g_free (remote_error); - g_error_free (local); return FALSE; } g_variant_get (ret, "(u)", &sender_uid); - g_variant_unref (ret); /* We only accept requests from NM, which always runs as root */ - if (0 != sender_uid) { + if (sender_uid != 0) { g_set_error_literal (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, @@ -253,8 +243,8 @@ verify_request (NMSecretAgentOld *self, NMConnection **out_connection, GError **error) { - NMConnection *connection = NULL; - GError *local = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_free_error GError *local = NULL; if (!verify_sender (self, context, error)) return FALSE; @@ -273,20 +263,18 @@ verify_request (NMSecretAgentOld *self, } /* Make sure the given connection is valid */ - g_assert (out_connection); connection = _nm_simple_connection_new_from_dbus (connection_dict, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &local); - if (connection) { - nm_connection_set_path (connection, connection_path); - *out_connection = connection; - } else { + if (!connection) { g_set_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, "Invalid connection: %s", local->message); - g_clear_error (&local); + return FALSE; } - return !!connection; + nm_connection_set_path (connection, connection_path); + NM_SET_OUT (out_connection, g_steal_pointer (&connection)); + return TRUE; } static void @@ -306,8 +294,7 @@ get_secrets_cb (NMSecretAgentOld *self, g_variant_new ("(@a{sa{sv}})", secrets)); } - /* Remove the request from internal tracking */ - get_secrets_info_finalize (self, info); + get_secrets_info_free (info); } static void @@ -322,7 +309,7 @@ impl_secret_agent_old_get_secrets (NMSecretAgentOld *self, { NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); GError *error = NULL; - NMConnection *connection = NULL; + gs_unref_object NMConnection *connection = NULL; GetSecretsInfo *info; /* Make sure the request comes from NetworkManager and is valid */ @@ -331,34 +318,35 @@ impl_secret_agent_old_get_secrets (NMSecretAgentOld *self, return; } - info = g_malloc0 (sizeof (GetSecretsInfo)); - info->path = g_strdup (connection_path); - info->setting_name = g_strdup (setting_name); - info->context = context; - priv->pending_gets = g_slist_append (priv->pending_gets, info); + info = g_slice_new (GetSecretsInfo); + *info = (GetSecretsInfo) { + .path = g_strdup (connection_path), + .setting_name = g_strdup (setting_name), + .context = context, + }; + c_list_link_tail (&priv->gsi_lst_head, &info->gsi_lst); NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self, - connection, - connection_path, - setting_name, - (const char **) hints, - flags, - get_secrets_cb, - info); - g_object_unref (connection); + connection, + connection_path, + setting_name, + (const char **) hints, + flags, + get_secrets_cb, + info); } static GetSecretsInfo * -find_get_secrets_info (GSList *list, const char *path, const char *setting_name) +find_get_secrets_info (NMSecretAgentOldPrivate *priv, + const char *path, + const char *setting_name) { - GSList *iter; - - for (iter = list; iter; iter = g_slist_next (iter)) { - GetSecretsInfo *candidate = iter->data; + GetSecretsInfo *info; - if ( g_strcmp0 (path, candidate->path) == 0 - && g_strcmp0 (setting_name, candidate->setting_name) == 0) - return candidate; + c_list_for_each_entry (info, &priv->gsi_lst_head, gsi_lst) { + if ( nm_streq0 (path, info->path) + && nm_streq0 (setting_name, info->setting_name)) + return info; } return NULL; } @@ -380,7 +368,7 @@ impl_secret_agent_old_cancel_get_secrets (NMSecretAgentOld *self, return; } - info = find_get_secrets_info (priv->pending_gets, connection_path, setting_name); + info = find_get_secrets_info (priv, connection_path, setting_name); if (!info) { g_dbus_method_invocation_return_error (context, NM_SECRET_AGENT_ERROR, @@ -389,10 +377,12 @@ impl_secret_agent_old_cancel_get_secrets (NMSecretAgentOld *self, return; } - /* Send the cancel request up to the subclass and finalize it */ + c_list_unlink (&info->gsi_lst); + NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self, - info->path, - info->setting_name); + info->path, + info->setting_name); + g_dbus_method_invocation_return_value (context, NULL); } @@ -417,8 +407,8 @@ impl_secret_agent_old_save_secrets (NMSecretAgentOld *self, const char *connection_path, gpointer user_data) { + gs_unref_object NMConnection *connection = NULL; GError *error = NULL; - NMConnection *connection = NULL; /* Make sure the request comes from NetworkManager and is valid */ if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { @@ -427,11 +417,10 @@ impl_secret_agent_old_save_secrets (NMSecretAgentOld *self, } NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self, - connection, - connection_path, - save_secrets_cb, - context); - g_object_unref (connection); + connection, + connection_path, + save_secrets_cb, + context); } static void @@ -455,8 +444,8 @@ impl_secret_agent_old_delete_secrets (NMSecretAgentOld *self, const char *connection_path, gpointer user_data) { + gs_unref_object NMConnection *connection = NULL; GError *error = NULL; - NMConnection *connection = NULL; /* Make sure the request comes from NetworkManager and is valid */ if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { @@ -465,11 +454,10 @@ impl_secret_agent_old_delete_secrets (NMSecretAgentOld *self, } NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self, - connection, - connection_path, - delete_secrets_cb, - context); - g_object_unref (connection); + connection, + connection_path, + delete_secrets_cb, + context); } /*****************************************************************************/ @@ -478,15 +466,13 @@ static gboolean check_nm_running (NMSecretAgentOld *self, GError **error) { NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - char *owner; + gs_free char *owner = NULL; if (priv->private_bus) return TRUE; owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy)); - if (owner) { - g_free (owner); + if (owner) return TRUE; - } g_set_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED, "NetworkManager is not running"); @@ -568,7 +554,7 @@ nm_secret_agent_old_register (NMSecretAgentOld *self, success: priv->registering = FALSE; priv->registered = TRUE; - g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED); + _notify (self, PROP_REGISTERED); return TRUE; } @@ -576,6 +562,7 @@ static void reg_result (NMSecretAgentOld *self, GSimpleAsyncResult *simple, GError *error) { NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + _nm_unused gs_unref_object GSimpleAsyncResult *simple_free = simple; priv->registering = FALSE; @@ -587,13 +574,11 @@ reg_result (NMSecretAgentOld *self, GSimpleAsyncResult *simple, GError *error) _internal_unregister (self); } else { priv->registered = TRUE; - g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED); + _notify (self, PROP_REGISTERED); g_simple_async_result_set_op_res_gboolean (simple, TRUE); g_simple_async_result_complete (simple); } - - g_object_unref (simple); } static void @@ -624,6 +609,7 @@ reg_with_caps_cb (GObject *proxy, self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); g_object_unref (self); /* drop extra ref added by get_source_object() */ + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); if (nmdbus_agent_manager_call_register_with_capabilities_finish (NMDBUS_AGENT_MANAGER (proxy), result, NULL)) { @@ -661,7 +647,7 @@ nm_secret_agent_old_register_async (NMSecretAgentOld *self, { NMSecretAgentOldPrivate *priv; NMSecretAgentOldClass *class; - GSimpleAsyncResult *simple; + gs_unref_object GSimpleAsyncResult *simple = NULL; GError *error = NULL; g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); @@ -687,7 +673,6 @@ nm_secret_agent_old_register_async (NMSecretAgentOld *self, if (!check_nm_running (self, &error)) { g_simple_async_result_take_error (simple, error); g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); return; } @@ -698,7 +683,6 @@ nm_secret_agent_old_register_async (NMSecretAgentOld *self, &error)) { g_simple_async_result_take_error (simple, error); g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); return; } @@ -709,7 +693,8 @@ nm_secret_agent_old_register_async (NMSecretAgentOld *self, priv->identifier, priv->capabilities, NULL, - reg_with_caps_cb, simple); + reg_with_caps_cb, + g_steal_pointer (&simple)); } /** @@ -775,7 +760,7 @@ nm_secret_agent_old_unregister (NMSecretAgentOld *self, static void unregister_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { - GSimpleAsyncResult *simple = user_data; + gs_unref_object GSimpleAsyncResult *simple = user_data; NMSecretAgentOld *self; GError *error = NULL; @@ -793,7 +778,6 @@ unregister_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) } g_simple_async_result_complete (simple); - g_object_unref (simple); } /** @@ -814,7 +798,7 @@ nm_secret_agent_old_unregister_async (NMSecretAgentOld *self, gpointer user_data) { NMSecretAgentOldPrivate *priv; - GSimpleAsyncResult *simple; + gs_unref_object GSimpleAsyncResult *simple = NULL; GError *error = NULL; g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); @@ -832,14 +816,15 @@ nm_secret_agent_old_unregister_async (NMSecretAgentOld *self, if (!check_nm_running (self, &error)) { g_simple_async_result_take_error (simple, error); g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); return; } priv->suppress_auto = TRUE; - nmdbus_agent_manager_call_unregister (priv->manager_proxy, cancellable, - unregister_cb, simple); + nmdbus_agent_manager_call_unregister (priv->manager_proxy, + cancellable, + unregister_cb, + g_steal_pointer (&simple)); } /** @@ -916,13 +901,13 @@ nm_secret_agent_old_get_secrets (NMSecretAgentOld *self, g_return_if_fail (callback != NULL); NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self, - connection, - nm_connection_get_path (connection), - setting_name, - hints, - flags, - callback, - user_data); + connection, + nm_connection_get_path (connection), + setting_name, + hints, + flags, + callback, + user_data); } /** @@ -946,10 +931,10 @@ nm_secret_agent_old_save_secrets (NMSecretAgentOld *self, g_return_if_fail (nm_connection_get_path (connection)); NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self, - connection, - nm_connection_get_path (connection), - callback, - user_data); + connection, + nm_connection_get_path (connection), + callback, + user_data); } /** @@ -973,10 +958,10 @@ nm_secret_agent_old_delete_secrets (NMSecretAgentOld *self, g_return_if_fail (nm_connection_get_path (connection)); NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self, - connection, - nm_connection_get_path (connection), - callback, - user_data); + connection, + nm_connection_get_path (connection), + callback, + user_data); } /*****************************************************************************/ @@ -1007,20 +992,7 @@ validate_identifier (const char *identifier) return TRUE; } -static void -nm_secret_agent_old_init (NMSecretAgentOld *self) -{ - NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - - priv->dbus_secret_agent = nmdbus_secret_agent_skeleton_new (); - _nm_dbus_bind_properties (self, priv->dbus_secret_agent); - _nm_dbus_bind_methods (self, priv->dbus_secret_agent, - "GetSecrets", impl_secret_agent_old_get_secrets, - "CancelGetSecrets", impl_secret_agent_old_cancel_get_secrets, - "DeleteSecrets", impl_secret_agent_old_delete_secrets, - "SaveSecrets", impl_secret_agent_old_save_secrets, - NULL); -} +/*****************************************************************************/ static void init_common (NMSecretAgentOld *self) @@ -1037,42 +1009,14 @@ init_common (NMSecretAgentOld *self) } } -static gboolean -init_sync (GInitable *initable, GCancellable *cancellable, GError **error) -{ - NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable); - NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - - priv->bus = _nm_dbus_new_connection (cancellable, error); - if (!priv->bus) - return FALSE; - - priv->manager_proxy = nmdbus_agent_manager_proxy_new_sync (priv->bus, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES - | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NM_DBUS_SERVICE, - NM_DBUS_PATH_AGENT_MANAGER, - cancellable, - error); - if (!priv->manager_proxy) - return FALSE; - - init_common (self); - - if (priv->auto_register) - return nm_secret_agent_old_register (self, cancellable, error); - else - return TRUE; -} - typedef struct { NMSecretAgentOld *self; GCancellable *cancellable; GSimpleAsyncResult *simple; -} NMSecretAgentOldInitData; +} InitData; static void -init_async_complete (NMSecretAgentOldInitData *init_data, GError *error) +init_async_complete (InitData *init_data, GError *error) { if (!error) g_simple_async_result_set_op_res_gboolean (init_data->simple, TRUE); @@ -1083,14 +1027,14 @@ init_async_complete (NMSecretAgentOldInitData *init_data, GError *error) g_object_unref (init_data->simple); g_clear_object (&init_data->cancellable); - g_slice_free (NMSecretAgentOldInitData, init_data); + g_slice_free (InitData, init_data); } static void init_async_registered (GObject *object, GAsyncResult *result, gpointer user_data) { NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object); - NMSecretAgentOldInitData *init_data = user_data; + InitData *init_data = user_data; GError *error = NULL; nm_secret_agent_old_register_finish (self, result, &error); @@ -1100,7 +1044,7 @@ init_async_registered (GObject *object, GAsyncResult *result, gpointer user_data static void init_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data) { - NMSecretAgentOldInitData *init_data = user_data; + InitData *init_data = user_data; NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self); GError *error = NULL; @@ -1122,7 +1066,7 @@ init_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data) static void init_async_got_bus (GObject *initable, GAsyncResult *result, gpointer user_data) { - NMSecretAgentOldInitData *init_data = user_data; + InitData *init_data = user_data; NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self); GError *error = NULL; @@ -1141,36 +1085,7 @@ init_async_got_bus (GObject *initable, GAsyncResult *result, gpointer user_data) init_async_got_proxy, init_data); } -static void -init_async (GAsyncInitable *initable, int io_priority, - GCancellable *cancellable, GAsyncReadyCallback callback, - gpointer user_data) -{ - NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable); - NMSecretAgentOldInitData *init_data; - - init_data = g_slice_new (NMSecretAgentOldInitData); - init_data->self = self; - init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - - init_data->simple = g_simple_async_result_new (G_OBJECT (initable), callback, - user_data, init_async); - if (cancellable) - g_simple_async_result_set_check_cancellable (init_data->simple, cancellable); - - _nm_dbus_new_connection_async (cancellable, init_async_got_bus, init_data); -} - -static gboolean -init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error) -{ - GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); - - if (g_simple_async_result_propagate_error (simple, error)) - return FALSE; - else - return TRUE; -} +/*****************************************************************************/ static void get_property (GObject *object, @@ -1229,23 +1144,109 @@ set_property (GObject *object, } } +/*****************************************************************************/ + +static void +nm_secret_agent_old_init (NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + c_list_init (&priv->gsi_lst_head); + priv->dbus_secret_agent = nmdbus_secret_agent_skeleton_new (); + _nm_dbus_bind_properties (self, priv->dbus_secret_agent); + _nm_dbus_bind_methods (self, priv->dbus_secret_agent, + "GetSecrets", impl_secret_agent_old_get_secrets, + "CancelGetSecrets", impl_secret_agent_old_cancel_get_secrets, + "DeleteSecrets", impl_secret_agent_old_delete_secrets, + "SaveSecrets", impl_secret_agent_old_save_secrets, + NULL); +} + +static gboolean +init_sync (GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable); + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + priv->bus = _nm_dbus_new_connection (cancellable, error); + if (!priv->bus) + return FALSE; + + priv->manager_proxy = nmdbus_agent_manager_proxy_new_sync (priv->bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NM_DBUS_SERVICE, + NM_DBUS_PATH_AGENT_MANAGER, + cancellable, + error); + if (!priv->manager_proxy) + return FALSE; + + init_common (self); + + if (priv->auto_register) + return nm_secret_agent_old_register (self, cancellable, error); + else + return TRUE; +} + +static void +init_async (GAsyncInitable *initable, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) +{ + NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable); + InitData *init_data; + + init_data = g_slice_new (InitData); + *init_data = (InitData) { + .self = self, + .cancellable = nm_g_object_ref (cancellable), + .simple = g_simple_async_result_new (G_OBJECT (initable), + callback, + user_data, + init_async), + }; + + if (cancellable) + g_simple_async_result_set_check_cancellable (init_data->simple, cancellable); + + _nm_dbus_new_connection_async (cancellable, init_async_got_bus, init_data); +} + +static gboolean +init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return TRUE; +} + static void dispose (GObject *object) { NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object); NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + GetSecretsInfo *info; - if (priv->registered) + if (priv->registered) { + priv->registered = FALSE; nm_secret_agent_old_unregister_async (self, NULL, NULL, NULL); + } - g_clear_pointer (&priv->identifier, g_free); + nm_clear_g_free (&priv->identifier); - while (priv->pending_gets) - get_secrets_info_finalize (self, priv->pending_gets->data); + while ((info = c_list_first_entry (&priv->gsi_lst_head, GetSecretsInfo, gsi_lst))) + get_secrets_info_free (info); - g_signal_handlers_disconnect_matched (priv->dbus_secret_agent, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, self); - g_object_unref (priv->dbus_secret_agent); + if (priv->dbus_secret_agent) { + g_signal_handlers_disconnect_matched (priv->dbus_secret_agent, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, self); + g_clear_object (&priv->dbus_secret_agent); + } g_clear_object (&priv->manager_proxy); g_clear_object (&priv->bus); @@ -1260,7 +1261,6 @@ nm_secret_agent_old_class_init (NMSecretAgentOldClass *class) g_type_class_add_private (class, sizeof (NMSecretAgentOldPrivate)); - /* Virtual methods */ object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; @@ -1276,13 +1276,12 @@ nm_secret_agent_old_class_init (NMSecretAgentOldClass *class) * of 3 characters. An example valid identifier is 'org.gnome.nm-applet' * (without quotes). **/ - g_object_class_install_property - (object_class, PROP_IDENTIFIER, - g_param_spec_string (NM_SECRET_AGENT_OLD_IDENTIFIER, "", "", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); + obj_properties[PROP_IDENTIFIER] = + g_param_spec_string (NM_SECRET_AGENT_OLD_IDENTIFIER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); /** * NMSecretAgentOld:auto-register: @@ -1305,39 +1304,38 @@ nm_secret_agent_old_class_init (NMSecretAgentOldClass *class) * auto-registration. This ensures that the agent remains un-registered when * you expect it to be unregistered. **/ - g_object_class_install_property - (object_class, PROP_AUTO_REGISTER, - g_param_spec_boolean (NM_SECRET_AGENT_OLD_AUTO_REGISTER, "", "", - TRUE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); + obj_properties[PROP_AUTO_REGISTER] = + g_param_spec_boolean (NM_SECRET_AGENT_OLD_AUTO_REGISTER, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); /** * NMSecretAgentOld:registered: * * %TRUE if the agent is registered with NetworkManager, %FALSE if not. **/ - g_object_class_install_property - (object_class, PROP_REGISTERED, - g_param_spec_boolean (NM_SECRET_AGENT_OLD_REGISTERED, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + obj_properties[PROP_REGISTERED] = + g_param_spec_boolean (NM_SECRET_AGENT_OLD_REGISTERED, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); /** * NMSecretAgentOld:capabilities: * * A bitfield of %NMSecretAgentCapabilities. **/ - g_object_class_install_property - (object_class, PROP_CAPABILITIES, - g_param_spec_flags (NM_SECRET_AGENT_OLD_CAPABILITIES, "", "", - NM_TYPE_SECRET_AGENT_CAPABILITIES, - NM_SECRET_AGENT_CAPABILITY_NONE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); + obj_properties[PROP_CAPABILITIES] = + g_param_spec_flags (NM_SECRET_AGENT_OLD_CAPABILITIES, "", "", + NM_TYPE_SECRET_AGENT_CAPABILITIES, + NM_SECRET_AGENT_CAPABILITY_NONE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); } static void diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index 5a4975b539..3537b37d50 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -1149,6 +1149,28 @@ nm_clear_g_cancellable (GCancellable **cancellable) return FALSE; } +/* If @cancellable_id is not 0, clear it and call g_cancellable_disconnect(). + * @cancellable may be %NULL, if there is nothing to disconnect. + * + * It's like nm_clear_g_signal_handler(), except that it uses g_cancellable_disconnect() + * instead of g_signal_handler_disconnect(). + * + * Note the warning in glib documentation about dead-lock and what g_cancellable_disconnect() + * actually does. */ +static inline gboolean +nm_clear_g_cancellable_disconnect (GCancellable *cancellable, gulong *cancellable_id) +{ + gulong id; + + if ( cancellable_id + && (id = *cancellable_id) != 0) { + *cancellable_id = 0; + g_cancellable_disconnect (cancellable, id); + return TRUE; + } + return FALSE; +} + /*****************************************************************************/ static inline GVariant * diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index 71b8d15153..5fcf6dff23 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -1380,7 +1380,7 @@ wifi_secrets_get_one (NMDeviceIwd *self, TRUE, setting_name, flags, - setting_key, + NM_MAKE_STRV (setting_key), wifi_secrets_cb, nm_utils_user_data_pack (self, invocation)); } @@ -1894,7 +1894,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) TRUE, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION, - "psk", + NM_MAKE_STRV (NM_SETTING_WIRELESS_SECURITY_PSK), act_psk_cb, self); nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index 11ada549da..1ad12b9d8e 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -948,7 +948,7 @@ nm_modem_get_secrets (NMModem *self, FALSE, setting_name, flags, - hint, + NM_MAKE_STRV (hint), modem_secrets_cb, self); g_return_if_fail (priv->secrets_id); @@ -986,8 +986,7 @@ nm_modem_act_stage1_prepare (NMModem *self, setting_name = nm_connection_need_secrets (connection, &hints); if (!setting_name) { - /* Ready to connect */ - g_assert (!hints); + nm_assert (!hints); return NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self, connection, out_failure_reason); } @@ -995,11 +994,14 @@ nm_modem_act_stage1_prepare (NMModem *self, if (priv->secrets_tries++) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + if (hints) + g_ptr_array_add (hints, NULL); + priv->secrets_id = nm_act_request_get_secrets (req, FALSE, setting_name, flags, - hints ? g_ptr_array_index (hints, 0) : NULL, + hints ? (const char *const*) hints->pdata : NULL, modem_secrets_cb, self); g_return_val_if_fail (priv->secrets_id, NM_ACT_STAGE_RETURN_FAILURE); diff --git a/src/nm-act-request.c b/src/nm-act-request.c index cd81696490..584eceab12 100644 --- a/src/nm-act-request.c +++ b/src/nm-act-request.c @@ -166,7 +166,7 @@ nm_act_request_get_secrets (NMActRequest *self, gboolean ref_self, const char *setting_name, NMSecretAgentGetSecretsFlags flags, - const char *hint, + const char *const*hints, NMActRequestSecretsFunc callback, gpointer callback_data) { @@ -175,7 +175,6 @@ nm_act_request_get_secrets (NMActRequest *self, NMSettingsConnectionCallId *call_id_s; NMSettingsConnection *settings_connection; NMConnection *applied_connection; - const char *hints[2] = { hint, NULL }; g_return_val_if_fail (NM_IS_ACT_REQUEST (self), NULL); diff --git a/src/nm-act-request.h b/src/nm-act-request.h index af2b749055..e16e1ecfdc 100644 --- a/src/nm-act-request.h +++ b/src/nm-act-request.h @@ -69,7 +69,7 @@ NMActRequestGetSecretsCallId *nm_act_request_get_secrets (NMActRequest *req, gboolean take_ref, const char *setting_name, NMSecretAgentGetSecretsFlags flags, - const char *hint, + const char *const*hints, NMActRequestSecretsFunc callback, gpointer callback_data); diff --git a/src/ppp/nm-ppp-manager.c b/src/ppp/nm-ppp-manager.c index 122901fcd8..548f46606f 100644 --- a/src/ppp/nm-ppp-manager.c +++ b/src/ppp/nm-ppp-manager.c @@ -363,7 +363,7 @@ impl_ppp_manager_need_secrets (NMDBusObject *obj, const char *username = NULL; const char *password = NULL; guint32 tries; - GPtrArray *hints = NULL; + gs_unref_ptrarray GPtrArray *hints = NULL; GError *error = NULL; NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; @@ -393,18 +393,18 @@ impl_ppp_manager_need_secrets (NMDBusObject *obj, if (tries > 1) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + if (hints) + g_ptr_array_add (hints, NULL); + priv->secrets_id = nm_act_request_get_secrets (priv->act_req, FALSE, priv->secrets_setting_name, flags, - hints ? g_ptr_array_index (hints, 0) : NULL, + hints ? (const char *const*) hints->pdata : NULL, ppp_secrets_cb, self); g_object_set_qdata (G_OBJECT (applied_connection), ppp_manager_secret_tries_quark (), GUINT_TO_POINTER (++tries)); priv->pending_secrets_context = invocation; - - if (hints) - g_ptr_array_free (hints, TRUE); } static void |