]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
nm: Pass back the username auth-dialog runs as to access ssh-agent socket
authorTobias Brunner <tobias@strongswan.org>
Thu, 4 Dec 2025 12:56:31 +0000 (13:56 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 10 Dec 2025 17:34:19 +0000 (18:34 +0100)
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.

src/charon-nm/nm/nm_service.c
src/frontends/gnome/auth-dialog/main.c

index 50a65e9457ce028ddac763c6b2ed5fd9ceee7a9b..1651b76f8686487d9779072a8a1b38abf7f5b2a9 100644 (file)
@@ -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;
 }
 
index fe42875c154c4b529cfbb7a9fe11cb49dc46c00a..803f708011826c902402fdf817beb5dcd8ce74e7 100644 (file)
@@ -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 ();
                }
        }