diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index 50a65e945..1651b76f8 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 fe42875c1..803f70801 100644 --- a/src/frontends/gnome/auth-dialog/main.c +++ b/src/frontends/gnome/auth-dialog/main.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -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 (); } }