Commit d7608ca192 for strongswan.org

commit d7608ca1922152c07d5e3d4597c267cb84f0d7c0
Author: Tobias Brunner <tobias@strongswan.org>
Date:   Thu Dec 4 13:56:31 2025 +0100

    nm: Pass back the username auth-dialog runs as to access ssh-agent socket

    This ensures we access the socket as user who NM ran the auth-dialog for,
    especially for system-wide connections where the connection does not
    mention a user.

    We also make sure we don't use the cached socket and user of a previous
    connection attempt, because system-wide connections might be used by
    different users.

diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c
index 50a65e9457..1651b76f86 100644
--- a/src/charon-nm/nm/nm_service.c
+++ b/src/charon-nm/nm/nm_service.c
@@ -57,6 +57,8 @@ typedef struct {
 	char *name;
 	/* temporary files for safe access */
 	GPtrArray *safe_files;
+	/* already requested the ssh-agent socket for the current connection */
+	bool agent_requested;
 } NMStrongswanPluginPrivate;

 G_DEFINE_TYPE_WITH_PRIVATE(NMStrongswanPlugin, nm_strongswan_plugin, NM_TYPE_VPN_SERVICE_PLUGIN)
@@ -581,7 +583,7 @@ static bool add_auth_cfg_cert(NMStrongswanPluginPrivate *priv,
 	identification_t *id = NULL;
 	certificate_t *cert = NULL;
 	auth_cfg_t *auth;
-	const char *str, *method, *cert_source;
+	const char *str, *method, *cert_source, *agent_user;
 	chunk_t safe_file;

 	method = nm_setting_vpn_get_data_item(vpn, "method");
@@ -631,13 +633,15 @@ static bool add_auth_cfg_cert(NMStrongswanPluginPrivate *priv,
 		str = nm_setting_vpn_get_secret(vpn, "agent");
 		if (agent && str)
 		{
+			agent_user = nm_setting_vpn_get_secret(vpn, "agent-user");
+
 			public = cert->get_public_key(cert);
 			if (public)
 			{
 				private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
 											 public->get_type(public),
 											 BUILD_AGENT_SOCKET, str,
-											 BUILD_AGENT_USER, user,
+											 BUILD_AGENT_USER, agent_user ?: user,
 											 BUILD_PUBLIC_KEY, public,
 											 BUILD_END);
 				public->destroy(public);
@@ -1197,7 +1201,14 @@ static gboolean need_secrets(NMVpnServicePlugin *plugin, NMConnection *connectio
 			}
 			if (streq(cert_source, "agent"))
 			{
-				need_secret = !nm_setting_vpn_get_secret(settings, "agent");
+				/* always request the socket/username from the current user */
+				need_secret = !priv->agent_requested;
+				if (!priv->agent_requested)
+				{
+					nm_setting_vpn_remove_secret(settings, "agent");
+					nm_setting_vpn_remove_secret(settings, "agent-user");
+					priv->agent_requested = TRUE;
+				}
 			}
 			else if (streq(cert_source, "smartcard"))
 			{
@@ -1284,6 +1295,8 @@ static gboolean do_disconnect(gpointer plugin)

 	/* delete any allocated interface */
 	delete_interface(priv);
+
+	priv->agent_requested = FALSE;
 	return FALSE;
 }

diff --git a/src/frontends/gnome/auth-dialog/main.c b/src/frontends/gnome/auth-dialog/main.c
index fe42875c15..803f708011 100644
--- a/src/frontends/gnome/auth-dialog/main.c
+++ b/src/frontends/gnome/auth-dialog/main.c
@@ -28,6 +28,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <libsecret/secret.h>
+#include <pwd.h>

 #include <NetworkManager.h>
 #include <nm-vpn-service-plugin.h>
@@ -217,6 +218,11 @@ static void print_secret (const char *secret_name, gchar *secret)
 		printf("%s\n%s\n", secret_name, secret);
 		g_free(secret);
 	}
+}
+
+static void print_last_secret (const char *secret_name, gchar *secret)
+{
+	print_secret(secret_name, secret);
 	printf("\n\n");
 	fflush(stdout);
 }
@@ -316,6 +322,17 @@ int main (int argc, char *argv[])
 			agent = getenv("SSH_AUTH_SOCK");
 			if (agent)
 			{
+				int uid = getuid();
+				struct passwd *pw = getpwuid(uid);
+
+				if (!pw)
+				{
+					fprintf(stderr, "Unable to determine username for "
+							"authentication via ssh-agent\n");
+					status = 1;
+					goto out;
+				}
+
 				if (external_ui_mode)
 				{
 					GKeyFile *keyfile;
@@ -326,6 +343,7 @@ int main (int argc, char *argv[])
 					g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Description", "SSH agent");
 					g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Title", _("Authenticate VPN"));

+					keyfile_add_entry_info (keyfile, "agent-user", pw->pw_name, "SSH agent user", TRUE, FALSE);
 					keyfile_add_entry_info (keyfile, "agent", agent, "SSH agent socket", TRUE, FALSE);

 					keyfile_print_stdout (keyfile);
@@ -333,7 +351,8 @@ int main (int argc, char *argv[])
 				}
 				else
 				{
-					print_secret("agent", g_strdup (agent));
+					print_secret("agent-user", g_strdup (pw->pw_name));
+					print_last_secret("agent", g_strdup (agent));
 					wait_for_quit ();
 				}
 			}
@@ -366,7 +385,7 @@ int main (int argc, char *argv[])
 		}
 		else if (!external_ui_mode)
 		{
-			print_secret("password", pass);
+			print_last_secret("password", pass);
 			wait_for_quit ();
 		}
 	}