Commit 28a04fcb54 for strongswan.org
commit 28a04fcb54ea2ebc13cac77517aa7bddf72d29a8
Author: Jarno Mäkelä <jarno.makela@iki.fi>
Date: Mon Oct 12 14:50:29 2026 +0300
nm: Add private key password field to editor and auth dialog
The editor now has a dedicated row for the private key passphrase,
saved as the "userkey-password" secret. An empty private key password
defaults to "not required" so that unencrypted keys do not prompt for
a passphrase. The password row no longer serves the key for certificate
methods with a key file; it remains the EAP and PSK password. A
smartcard PIN is stored as "pin" and is never saved in the connection,
only supplied by the auth dialog. A key passphrase that was saved as
"password" before this change is carried over to "userkey-password" when
the connection is edited and ignored for the password field.
For new connections, the auth dialog returns the secret whose name
depends on the method: "password" for eap and psk, "pin" for a smartcard
certificate source, and "userkey-password" otherwise. For legacy
connections it defaults to "password" based on the flags. The dialog
now also reads the password flags from the correct hash table.
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 fe42875c15..39e0e1e3a0 100644
--- a/src/frontends/gnome/auth-dialog/main.c
+++ b/src/frontends/gnome/auth-dialog/main.c
@@ -106,6 +106,7 @@ 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,
gboolean retry, gboolean allow_interaction, gboolean external_ui_mode,
const char *in_pw, char **out_pw, NMSettingSecretFlags flags)
{
@@ -123,7 +124,7 @@ static gboolean get_secrets(const char *type, const char *cert_source, const cha
}
else
{
- pw = keyring_lookup_secret (uuid, "password");
+ pw = keyring_lookup_secret (uuid, secret_name);
}
}
if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)
@@ -165,7 +166,7 @@ static gboolean get_secrets(const char *type, const char *cert_source, const cha
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, "password", pw ?: "", _("Password:"), TRUE, allow_interaction);
+ keyfile_add_entry_info (keyfile, secret_name, pw ?: "", _("Password:"), TRUE, allow_interaction);
keyfile_print_stdout (keyfile);
g_key_file_unref (keyfile);
@@ -254,6 +255,7 @@ int main (int argc, char *argv[])
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
GOptionContext *context;
char *agent, *type, *cert_source;
+ const char *secret_name = "password";
int status = 0;
GOptionEntry entries[] = {
{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
@@ -350,7 +352,17 @@ int main (int argc, char *argv[])
}
else
{
+ 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))
+ {
+ secret_name = "password";
+ }
}
}
@@ -358,15 +370,15 @@ int main (int argc, char *argv[])
!strcmp(type, "eap") ||
!strcmp(type, "psk"))
{
- nm_vpn_service_plugin_get_secret_flags (secrets, "password", &flags);
- if (!get_secrets(type, cert_source, uuid, name, retry, allow_interaction,
- external_ui_mode, g_hash_table_lookup (secrets, "password"), &pass, flags))
+ 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))
{
status = 1;
}
else if (!external_ui_mode)
{
- print_secret("password", pass);
+ print_secret(secret_name, pass);
wait_for_quit ();
}
}
diff --git a/src/frontends/gnome/properties/nm-strongswan-dialog.ui b/src/frontends/gnome/properties/nm-strongswan-dialog.ui
index f90c2c7262..a0aaeb979c 100644
--- a/src/frontends/gnome/properties/nm-strongswan-dialog.ui
+++ b/src/frontends/gnome/properties/nm-strongswan-dialog.ui
@@ -397,6 +397,33 @@
<property name="top-attach">3</property>
</packing>
</child>
+ <child>
+ <object class="GtkLabel" id="userkey-password-label">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">Private key pass_word:</property>
+ <property name="use-underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="userkey-password-entry">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="tooltip-text" translatable="yes">The password to decrypt the private key, if it is encrypted.</property>
+ <property name="hexpand">True</property>
+ <property name="visibility">False</property>
+ <property name="placeholder-text" translatable="yes">(Use icon to change password storage policy)</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
<child>
<object class="GtkLabel" id="user-label">
<property name="visible">True</property>
@@ -407,7 +434,7 @@
</object>
<packing>
<property name="left-attach">0</property>
- <property name="top-attach">5</property>
+ <property name="top-attach">6</property>
</packing>
</child>
<child>
@@ -419,7 +446,7 @@
</object>
<packing>
<property name="left-attach">1</property>
- <property name="top-attach">5</property>
+ <property name="top-attach">6</property>
</packing>
</child>
<child>
@@ -432,7 +459,7 @@
</object>
<packing>
<property name="left-attach">0</property>
- <property name="top-attach">6</property>
+ <property name="top-attach">7</property>
</packing>
</child>
<child>
@@ -446,7 +473,7 @@
</object>
<packing>
<property name="left-attach">1</property>
- <property name="top-attach">6</property>
+ <property name="top-attach">7</property>
</packing>
</child>
<child>
@@ -461,7 +488,7 @@
</object>
<packing>
<property name="left-attach">1</property>
- <property name="top-attach">7</property>
+ <property name="top-attach">8</property>
</packing>
</child>
<child>
@@ -474,7 +501,7 @@
</object>
<packing>
<property name="left-attach">0</property>
- <property name="top-attach">4</property>
+ <property name="top-attach">5</property>
</packing>
</child>
<child>
@@ -487,7 +514,7 @@
</object>
<packing>
<property name="left-attach">1</property>
- <property name="top-attach">4</property>
+ <property name="top-attach">5</property>
</packing>
</child>
<child>
diff --git a/src/frontends/gnome/properties/nm-strongswan.c b/src/frontends/gnome/properties/nm-strongswan.c
index 4b518c79c8..f74eb9be96 100644
--- a/src/frontends/gnome/properties/nm-strongswan.c
+++ b/src/frontends/gnome/properties/nm-strongswan.c
@@ -168,7 +168,6 @@ static void update_cert_fields (StrongswanPluginUiWidgetPrivate *priv, gboolean
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
/* FALL */
case 0:
- update_pass_field (priv, TRUE);
cert = key = TRUE;
break;
case 1:
@@ -184,6 +183,8 @@ static void update_cert_fields (StrongswanPluginUiWidgetPrivate *priv, gboolean
gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), enabled && cert);
gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), enabled && key);
gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), enabled && key);
+ gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-password-label")), enabled && key);
+ gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-password-entry")), enabled && key);
}
static void update_sensitive (StrongswanPluginUiWidgetPrivate *priv)
@@ -316,7 +317,8 @@ password_storage_changed_cb (GObject *entry, GParamSpec *pspec, gpointer user_da
static void
init_password_icon (StrongswanPluginUiWidget *self, NMSettingVpn *settings,
- const char *secret_key, const char *entry_name)
+ const char *secret_key, const char *entry_name,
+ NMSettingSecretFlags empty_flags)
{
StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
GtkWidget *entry;
@@ -331,7 +333,7 @@ init_password_icon (StrongswanPluginUiWidget *self, NMSettingVpn *settings,
nma_utils_setup_password_storage (entry, 0, NM_SETTING (settings), secret_key, TRUE, FALSE);
/* If there's no password and no flags in the setting,
- * initialize flags as "always-ask".
+ * initialize flags as given by the caller.
*/
if (settings)
{
@@ -341,7 +343,7 @@ init_password_icon (StrongswanPluginUiWidget *self, NMSettingVpn *settings,
value = gtk_editable_get_text (GTK_EDITABLE (entry));
if ((!value || !*value) && (pw_flags == NM_SETTING_SECRET_FLAG_NONE))
{
- nma_utils_update_password_storage (entry, NM_SETTING_SECRET_FLAG_NOT_SAVED,
+ nma_utils_update_password_storage (entry, empty_flags,
NM_SETTING (settings), secret_key);
}
@@ -382,8 +384,9 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
{
StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
NMSettingVpn *settings;
+ NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
GtkWidget *widget;
- const char *value, *method;
+ const char *value, *method, *secret;
settings = NM_SETTING_VPN(nm_connection_get_setting(connection, NM_TYPE_SETTING_VPN));
@@ -426,14 +429,37 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
gtk_editable_set_text (GTK_EDITABLE (widget), value);
g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
+ /* fallback to the password for old certificate configs, before the password
+ * field below stores default flags for it */
+ secret = "userkey-password";
+ if (!nm_setting_vpn_get_secret (settings, "userkey-password") &&
+ !(nm_setting_get_secret_flags (NM_SETTING (settings), "userkey-password",
+ &flags, NULL) && flags) &&
+ (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)
+ {
+ secret = "password";
+ }
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-password-entry"));
+ value = nm_setting_vpn_get_secret (settings, secret);
+ if (value)
+ 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, secret, "userkey-password-entry",
+ NM_SETTING_SECRET_FLAG_NOT_REQUIRED);
+
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show"));
g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (show_toggled_cb), self);
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"));
value = nm_setting_vpn_get_secret (settings, "password");
- if (value)
+ /* ignore legacy password for certificate configs */
+ if (value && method && (g_strcmp0 (method, "eap") == 0 || g_strcmp0 (method, "psk") == 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");
+ init_password_icon (self, settings, "password", "passwd-entry",
+ NM_SETTING_SECRET_FLAG_NOT_SAVED);
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"));
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("EAP (Username/Password)"));
@@ -646,8 +672,8 @@ save_cert (NMSettingVpn *settings, GtkBuilder *builder)
{
default:
case 0:
- save_password_and_flags (settings, builder, "passwd-entry",
- "password");
+ save_password_and_flags (settings, builder, "userkey-password-entry",
+ "userkey-password");
cert = key = TRUE;
str = "file";
break;
@@ -656,7 +682,7 @@ save_cert (NMSettingVpn *settings, GtkBuilder *builder)
str = "agent";
break;
case 2:
- nm_setting_set_secret_flags (NM_SETTING (settings), "password",
+ nm_setting_set_secret_flags (NM_SETTING (settings), "pin",
NM_SETTING_SECRET_FLAG_NOT_SAVED, NULL);
str = "smartcard";
break;
@@ -769,6 +795,8 @@ dispose (GObject *object)
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"));
g_signal_handlers_disconnect_by_func (G_OBJECT (widget), G_CALLBACK (password_storage_changed_cb), plugin);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-password-entry"));
+ g_signal_handlers_disconnect_by_func (G_OBJECT (widget), G_CALLBACK (password_storage_changed_cb), plugin);
if (priv->widget)
g_object_unref (priv->widget);