From 65d38939e28153106f09ce5fced8455ee6305e63 Mon Sep 17 00:00:00 2001 From: Alessandro Astone Date: Wed, 19 Feb 2025 12:26:44 +0100 Subject: [PATCH] shell/network-agent: Do not query keyring in greeter mode When trying to connect to a network from gdm, it doesn't make sense to query secrets from the gdm user since it's a system user. Furthermore, gdm runs an isolated dbus-session per gnome-shell instance (for multi-seat setups). Instead, gnome-keyring-daemon is started by systemd and so it registers on the _main_ dbus session of the gdm user session. Then, gnome-shell tries to dbus-activate another gnome-keyring-daemon on its isolated bus, but gnome-keyring-daemon refuses to start as it sees another instance already running, exposed at $XDG_RUNTIME_DIR/keyring/control. After a 25s timeout, gnome-shell aborts the request without ever prompting for a new password. Because it is both problematic and pointless to query secrets in this case, let's avoid it altogether and just prompt the user for the network password. Part-of: --- js/ui/components/networkAgent.js | 2 + src/shell-network-agent.c | 63 +++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/js/ui/components/networkAgent.js b/js/ui/components/networkAgent.js index d9a1aeb96..5e9c741d1 100644 --- a/js/ui/components/networkAgent.js +++ b/js/ui/components/networkAgent.js @@ -10,6 +10,7 @@ import St from 'gi://St'; import * as Signals from '../../misc/signals.js'; import * as Dialog from '../dialog.js'; +import * as Main from '../main.js'; import * as MessageTray from '../messageTray.js'; import * as ModalDialog from '../modalDialog.js'; import * as ShellEntry from '../shellEntry.js'; @@ -676,6 +677,7 @@ class NetworkAgent { identifier: 'org.gnome.Shell.NetworkAgent', capabilities: NM.SecretAgentCapabilities.VPN_HINTS, auto_register: false, + force_always_ask: Main.sessionMode.isGreeter, }); this._dialogs = { }; diff --git a/src/shell-network-agent.c b/src/shell-network-agent.c index cd1ee015a..d44593bc6 100644 --- a/src/shell-network-agent.c +++ b/src/shell-network-agent.c @@ -27,6 +27,17 @@ #include "shell-network-agent.h" +enum +{ + PROP_0, + + PROP_FORCE_ALWAYS_ASK, + + N_PROPS +}; + +static GParamSpec *props[N_PROPS] = { NULL, }; + enum { SIGNAL_NEW_REQUEST, SIGNAL_CANCEL_REQUEST, @@ -57,6 +68,7 @@ typedef struct _ShellNetworkAgent /* */ GHashTable *requests; + gboolean force_always_ask; } ShellNetworkAgent; G_DEFINE_FINAL_TYPE (ShellNetworkAgent, shell_network_agent, NM_TYPE_SECRET_AGENT_OLD) @@ -377,7 +389,7 @@ shell_network_agent_get_secrets (NMSecretAgentOld *agent, if ((flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW) || ((flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION) - && is_connection_always_ask (request->connection))) + && (self->force_always_ask || is_connection_always_ask (request->connection)))) { request->entries = g_variant_dict_new (NULL); request_secrets_from_ui (request); @@ -849,12 +861,54 @@ shell_network_agent_delete_secrets (NMSecretAgentOld *agent, NULL); } +static void +shell_network_agent_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ShellNetworkAgent *self = SHELL_NETWORK_AGENT (object); + + switch (prop_id) + { + case PROP_FORCE_ALWAYS_ASK: + self->force_always_ask = g_value_get_boolean (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +shell_network_agent_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ShellNetworkAgent *self = SHELL_NETWORK_AGENT (object); + + switch (prop_id) + { + case PROP_FORCE_ALWAYS_ASK: + g_value_set_boolean (value, self->force_always_ask); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + void shell_network_agent_class_init (ShellNetworkAgentClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); NMSecretAgentOldClass *agent_class = NM_SECRET_AGENT_OLD_CLASS (klass); + gobject_class->set_property = shell_network_agent_set_property; + gobject_class->get_property = shell_network_agent_get_property; gobject_class->finalize = shell_network_agent_finalize; agent_class->get_secrets = shell_network_agent_get_secrets; @@ -862,6 +916,13 @@ shell_network_agent_class_init (ShellNetworkAgentClass *klass) agent_class->save_secrets = shell_network_agent_save_secrets; agent_class->delete_secrets = shell_network_agent_delete_secrets; + props[PROP_FORCE_ALWAYS_ASK] = + g_param_spec_boolean ("force-always-ask", NULL, NULL, + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (gobject_class, N_PROPS, props); + signals[SIGNAL_NEW_REQUEST] = g_signal_new ("new-request", G_TYPE_FROM_CLASS (klass), 0, /* flags */