Commit d64176ce90 for strongswan.org
commit d64176ce90a6c077de5d5405cccefce6b2ae88b7
Author: Jarno Mäkelä <jarno.makela@iki.fi>
Date: Mon Oct 12 15:38:19 2026 +0300
nm: Add cert-eap method to GNOME editor and auth dialog
The editor gains a fifth method entry. It uses the existing certificate-
and EAP-related fields. Every certificate source (file, ssh-agent,
smartcard) can be selected. The key password row does not fall back
to the EAP password for this method.
The auth dialog treats "cert-eap" as a certificate method so the
certificate source is resolved (agent socket, or pin / userkey-password
secret). It then calls get_secrets() with the EAP password as the main
entry and the certificate secret as a secondary entry, so both are
requested in a single dialog or keyfile exchange. The no-dialog
shortcut is skipped when a secondary secret is still needed. In
non-external mode both secrets are printed before the single
wait_for_quit().
Signed-off-by: Jarno Mäkelä <jarno.makela@iki.fi>
diff --git a/src/frontends/gnome/auth-dialog/main.c b/src/frontends/gnome/auth-dialog/main.c
index 39e0e1e3a0..e78c2fac19 100644
--- a/src/frontends/gnome/auth-dialog/main.c
+++ b/src/frontends/gnome/auth-dialog/main.c
@@ -106,13 +106,14 @@ static void keyfile_print_stdout (GKeyFile *keyfile)
}
static gboolean get_secrets(const char *type, const char *cert_source, const char *uuid, const char *name,
- const char *secret_name,
+ const char *secret_name, const char *secondary_name,
gboolean retry, gboolean allow_interaction, gboolean external_ui_mode,
- const char *in_pw, char **out_pw, NMSettingSecretFlags flags)
+ const char *in_pw, char **out_pw, const char *in_pw2, char **out_pw2,
+ NMSettingSecretFlags flags)
{
NMAVpnPasswordDialog *dialog;
char *prompt, *pw = NULL;
- const char *new_pw = NULL;
+ const char *new_pw = NULL, *secondary_prompt = NULL;
guint32 minlen = 0;
if (!(flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) &&
@@ -132,7 +133,8 @@ static gboolean get_secrets(const char *type, const char *cert_source, const cha
g_free (pw);
return TRUE;
}
- if (!strcmp(type, "eap"))
+ if (!strcmp(type, "eap") ||
+ !strcmp(type, "cert-eap"))
{
prompt = g_strdup_printf (_("EAP password required to establish VPN connection '%s'."),
name);
@@ -156,39 +158,60 @@ static gboolean get_secrets(const char *type, const char *cert_source, const cha
name);
}
}
+ if (secondary_name)
+ {
+ secondary_prompt = !strcmp(cert_source, "smartcard") ? _("PIN:")
+ : _("Private key password:");
+ }
if (external_ui_mode)
{
GKeyFile *keyfile;
keyfile = g_key_file_new ();
- g_key_file_set_integer (keyfile, UI_KEYFILE_GROUP, "Version", 2);
- g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Description", prompt);
- g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Title", _("Authenticate VPN"));
+ if (strcmp(type, "cert-eap") || strcmp(cert_source, "agent"))
+ {
+ g_key_file_set_integer (keyfile, UI_KEYFILE_GROUP, "Version", 2);
+ g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Description", prompt);
+ g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Title", _("Authenticate VPN"));
+ }
keyfile_add_entry_info (keyfile, secret_name, pw ?: "", _("Password:"), TRUE, allow_interaction);
-
+ if (secondary_name)
+ {
+ keyfile_add_entry_info (keyfile, secondary_name, in_pw2 ?: "",
+ secondary_prompt, TRUE, allow_interaction);
+ }
keyfile_print_stdout (keyfile);
g_key_file_unref (keyfile);
goto out;
}
else if (!allow_interaction ||
- (!retry && pw && !(flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)))
+ (!retry && pw && !(flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) &&
+ (!secondary_name || in_pw2)))
{
/* If we can't prompt the user, just return the existing password. Do the same
* if we don't nee a new password (!retry) and have an existing saved one */
*out_pw = pw;
+ if (secondary_name)
+ *out_pw2 = g_strdup (in_pw2);
g_free (prompt);
return TRUE;
}
dialog = (NMAVpnPasswordDialog*)nma_vpn_password_dialog_new(_("Authenticate VPN"), prompt, NULL);
- nma_vpn_password_dialog_set_show_password_secondary(dialog, FALSE);
+ nma_vpn_password_dialog_set_show_password_secondary(dialog, secondary_name != NULL);
if (pw && !(flags & NM_SETTING_SECRET_FLAG_NOT_SAVED))
{
nma_vpn_password_dialog_set_password(dialog, pw);
}
+ if (secondary_name)
+ {
+ nma_vpn_password_dialog_set_password_secondary_label(dialog, secondary_prompt);
+ if (in_pw2)
+ nma_vpn_password_dialog_set_password_secondary(dialog, in_pw2);
+ }
gtk_widget_show (GTK_WIDGET (dialog));
too_short_retry:
@@ -203,6 +226,8 @@ too_short_retry:
{
*out_pw = g_strdup (new_pw);
}
+ if (secondary_name)
+ *out_pw2 = g_strdup (nma_vpn_password_dialog_get_password_secondary (dialog));
}
gtk_widget_hide (GTK_WIDGET (dialog));
gtk_widget_destroy (GTK_WIDGET (dialog));
@@ -213,13 +238,11 @@ out:
static void print_secret (const char *secret_name, gchar *secret)
{
- if (secret)
+ if (secret && *secret)
{
printf("%s\n%s\n", secret_name, secret);
- g_free(secret);
}
- printf("\n\n");
- fflush(stdout);
+ g_free(secret);
}
static void wait_for_quit (void)
@@ -229,6 +252,9 @@ static void wait_for_quit (void)
ssize_t n;
time_t start;
+ printf("\n\n");
+ fflush(stdout);
+
str = g_string_sized_new (10);
start = time (NULL);
do {
@@ -250,12 +276,13 @@ int main (int argc, char *argv[])
{
gboolean retry = FALSE, allow_interaction = FALSE, external_ui_mode = FALSE;
gboolean need_secret = FALSE;
- gchar *name = NULL, *uuid = NULL, *service = NULL, *pass = NULL;
+ gchar *name = NULL, *uuid = NULL, *service = NULL, *pass = NULL, *pass2 = NULL;
GHashTable *data = NULL, *secrets = NULL;
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+ NMSettingSecretFlags flags2 = NM_SETTING_SECRET_FLAG_NONE;
GOptionContext *context;
char *agent, *type, *cert_source;
- const char *secret_name = "password";
+ const char *secret_name = "password", *secondary_name = NULL;
int status = 0;
GOptionEntry entries[] = {
{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
@@ -311,7 +338,8 @@ int main (int argc, char *argv[])
!strcmp(type, "eap-tls") ||
!strcmp(type, "key") ||
!strcmp(type, "agent") ||
- !strcmp(type, "smartcard"))
+ !strcmp(type, "smartcard") ||
+ !strcmp(type, "cert-eap"))
{
if (!strcmp(cert_source, "agent"))
{
@@ -321,12 +349,20 @@ int main (int argc, char *argv[])
if (external_ui_mode)
{
GKeyFile *keyfile;
+ char *prompt;
keyfile = g_key_file_new ();
+ if (!strcmp(type, "cert-eap"))
+ prompt = g_strdup_printf (_("EAP password required to establish VPN connection '%s'."),
+ name);
+ else
+ prompt = g_strdup ("SSH agent");
+
g_key_file_set_integer (keyfile, UI_KEYFILE_GROUP, "Version", 2);
- g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Description", "SSH agent");
+ g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Description", prompt);
g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Title", _("Authenticate VPN"));
+ g_free (prompt);
keyfile_add_entry_info (keyfile, "agent", agent, "SSH agent socket", TRUE, FALSE);
@@ -336,18 +372,23 @@ int main (int argc, char *argv[])
else
{
print_secret("agent", g_strdup (agent));
- wait_for_quit ();
+ if (strcmp(type, "cert-eap") != 0)
+ wait_for_quit ();
}
}
- else if (allow_interaction)
+ else
{
- GtkWidget *dialog;
- dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- _("Configuration uses ssh-agent for authentication, "
- "but ssh-agent is not running!"));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
+ if (allow_interaction)
+ {
+ GtkWidget *dialog;
+ dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("Configuration uses ssh-agent for authentication, "
+ "but ssh-agent is not running!"));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+ goto out;
}
}
else
@@ -355,30 +396,49 @@ int main (int argc, char *argv[])
NMSettingSecretFlags new_flags = NM_SETTING_SECRET_FLAG_NONE;
need_secret = TRUE;
- secret_name = !strcmp(cert_source, "smartcard") ? "pin" : "userkey-password";
- /* fallback to the legacy field for connections that were saved
- * before the rename, otherwise stored passwords/flags won't be used
- * and the returned flagless password is stored in the connection */
- if (!nm_vpn_service_plugin_get_secret_flags (data, secret_name, &new_flags))
+ if (!strcmp(type, "cert-eap"))
{
- secret_name = "password";
+ secondary_name = !strcmp(cert_source, "smartcard") ? "pin" : "userkey-password";
+ }
+ else
+ {
+ secret_name = !strcmp(cert_source, "smartcard") ? "pin" : "userkey-password";
+ /* fallback to the legacy field for connections that were saved
+ * before the rename, otherwise stored passwords/flags won't be used
+ * and the returned flagless password is stored in the connection */
+ if (!nm_vpn_service_plugin_get_secret_flags (data, secret_name, &new_flags))
+ {
+ secret_name = "password";
+ }
}
}
}
if (need_secret ||
!strcmp(type, "eap") ||
- !strcmp(type, "psk"))
+ !strcmp(type, "psk") ||
+ !strcmp(type, "cert-eap"))
{
nm_vpn_service_plugin_get_secret_flags (data, secret_name, &flags);
- if (!get_secrets(type, cert_source, uuid, name, secret_name, retry, allow_interaction,
- external_ui_mode, g_hash_table_lookup (secrets, secret_name), &pass, flags))
+ if (secondary_name &&
+ nm_vpn_service_plugin_get_secret_flags (data, secondary_name, &flags2) &&
+ (flags2 & NM_SETTING_SECRET_FLAG_NOT_REQUIRED))
+ {
+ secondary_name = NULL;
+ }
+ if (!get_secrets(type, cert_source, uuid, name, secret_name, secondary_name,
+ retry, allow_interaction, external_ui_mode,
+ g_hash_table_lookup (secrets, secret_name), &pass,
+ secondary_name ? g_hash_table_lookup (secrets, secondary_name) : NULL,
+ secondary_name ? &pass2 : NULL, flags))
{
status = 1;
}
else if (!external_ui_mode)
{
print_secret(secret_name, pass);
+ if (secondary_name)
+ print_secret(secondary_name, pass2);
wait_for_quit ();
}
}
diff --git a/src/frontends/gnome/properties/nm-strongswan.c b/src/frontends/gnome/properties/nm-strongswan.c
index f74eb9be96..415ccaed00 100644
--- a/src/frontends/gnome/properties/nm-strongswan.c
+++ b/src/frontends/gnome/properties/nm-strongswan.c
@@ -212,6 +212,11 @@ static void update_sensitive (StrongswanPluginUiWidgetPrivate *priv)
update_pass_field (priv, TRUE);
update_cert_fields (priv, FALSE);
break;
+ case 4:
+ update_user_field (priv, TRUE);
+ update_pass_field (priv, TRUE);
+ update_cert_fields (priv, TRUE);
+ break;
}
}
@@ -438,7 +443,8 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
(nm_setting_vpn_get_secret (settings, "password") ||
(nm_setting_get_secret_flags (NM_SETTING (settings), "password",
&flags, NULL) && flags)) &&
- method && g_strcmp0 (method, "eap") != 0 && g_strcmp0 (method, "psk") != 0)
+ method && g_strcmp0 (method, "eap") != 0 && g_strcmp0 (method, "psk") != 0 &&
+ g_strcmp0 (method, "cert-eap") != 0)
{
secret = "password";
}
@@ -455,8 +461,11 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"));
value = nm_setting_vpn_get_secret (settings, "password");
/* ignore legacy password for certificate configs */
- if (value && method && (g_strcmp0 (method, "eap") == 0 || g_strcmp0 (method, "psk") == 0))
+ if (value && method && (g_strcmp0 (method, "eap") == 0 ||
+ g_strcmp0 (method, "psk") == 0 || g_strcmp0 (method, "cert-eap") == 0))
+ {
gtk_editable_set_text (GTK_EDITABLE (widget), value);
+ }
g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
init_password_icon (self, settings, "password", "passwd-entry",
NM_SETTING_SECRET_FLAG_NOT_SAVED);
@@ -466,6 +475,7 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate"));
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("EAP-TLS"));
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Pre-shared key"));
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate + EAP (Username/Password)"));
if (method) {
if (g_strcmp0 (method, "eap") == 0) {
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
@@ -483,6 +493,9 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
if (g_strcmp0 (method, "psk") == 0) {
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 3);
}
+ if (g_strcmp0 (method, "cert-eap") == 0) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 4);
+ }
}
if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
{
@@ -744,6 +757,12 @@ update_connection (NMVpnEditor *iface,
save_password_and_flags (settings, priv->builder, "passwd-entry", "password");
str = "psk";
break;
+ case 4:
+ save_entry (settings, priv->builder, "user-entry", "user");
+ save_password_and_flags (settings, priv->builder, "passwd-entry", "password");
+ save_cert (settings, priv->builder);
+ str = "cert-eap";
+ break;
}
nm_setting_vpn_add_data_item (settings, "method", str);