From 53fe8b12458bf166fdf35ab8b527a75daf78209d Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 29 Mar 2016 20:07:04 +0200 Subject: nm: Add a widget for setting a password It was only possible to set the password from the authentication dialog, which is not ideal; as it requires a connection attempt. This adds an input entry along with a primary icon from libnma/libnm-gtk which allows selecting the backend and flags for the password (system, session agent, always ask or empty). --- src/frontends/gnome/configure.ac | 2 + src/frontends/gnome/properties/Makefile.am | 4 + .../gnome/properties/nm-strongswan-dialog.ui | 107 +++++++++++++----- src/frontends/gnome/properties/nm-strongswan.c | 121 ++++++++++++++++++++- 4 files changed, 206 insertions(+), 28 deletions(-) diff --git a/src/frontends/gnome/configure.ac b/src/frontends/gnome/configure.ac index 2a426e7b2..13fb7a646 100644 --- a/src/frontends/gnome/configure.ac +++ b/src/frontends/gnome/configure.ac @@ -48,6 +48,8 @@ PKG_CHECK_MODULES(LIBGNOMEUI, libgnomeui-2.0) PKG_CHECK_MODULES(LIBSECRET, libsecret-1) PKG_CHECK_MODULES(LIBNM_GLIB, NetworkManager >= 1.1.0 libnm-util libnm-glib libnm-glib-vpn) +PKG_CHECK_MODULES(LIBNM_GTK, libnm-gtk >= 1.1.0) +PKG_CHECK_MODULES(LIBNMA, libnma >= 1.1.0) PKG_CHECK_MODULES(LIBNM, libnm >= 1.1.0) LIBNM_CFLAGS="$LIBNM_CFLAGS -DNM_VERSION_MIN_REQUIRED=NM_VERSION_1_2" diff --git a/src/frontends/gnome/properties/Makefile.am b/src/frontends/gnome/properties/Makefile.am index 82eae497b..1f138db2f 100644 --- a/src/frontends/gnome/properties/Makefile.am +++ b/src/frontends/gnome/properties/Makefile.am @@ -19,19 +19,23 @@ common_CFLAGS = \ libnm_vpn_plugin_strongswan_la_CFLAGS = \ $(LIBNM_CFLAGS) \ + $(LIBNMA_CFLAGS) \ $(common_CFLAGS) libnm_strongswan_properties_la_CFLAGS = \ -DNM_STRONGSWAN_OLD \ + $(LIBNM_GTK_CFLAGS) \ $(LIBNM_GLIB_CFLAGS) \ $(common_CFLAGS) libnm_vpn_plugin_strongswan_la_LIBADD = \ $(GTK_LIBS) \ + $(LIBNMA_LIBS) \ $(LIBNM_LIBS) libnm_strongswan_properties_la_LIBADD = \ $(GTK_LIBS) \ + $(LIBNM_GTK_LIBS) \ $(LIBNM_GLIB_LIBS) libnm_vpn_plugin_strongswan_la_LDFLAGS = \ diff --git a/src/frontends/gnome/properties/nm-strongswan-dialog.ui b/src/frontends/gnome/properties/nm-strongswan-dialog.ui index 6aea549fb..278fd006b 100644 --- a/src/frontends/gnome/properties/nm-strongswan-dialog.ui +++ b/src/frontends/gnome/properties/nm-strongswan-dialog.ui @@ -1,10 +1,10 @@ + True False - start 12 16 @@ -50,7 +50,7 @@ GTK_FILL - + @@ -59,11 +59,15 @@ True True An IP address or hostname the Gateway can be contacted. + False + False + True + True 1 2 - + @@ -79,7 +83,7 @@ 1 2 GTK_FILL - + @@ -139,7 +143,7 @@ True False - 4 + 6 2 6 6 @@ -152,8 +156,8 @@ 1 2 - 3 - 4 + 2 + 3 @@ -166,10 +170,10 @@ userkey-button - 3 - 4 + 2 + 3 GTK_FILL - + @@ -182,7 +186,7 @@ GTK_FILL - + @@ -195,10 +199,10 @@ user-entry - 1 - 2 + 3 + 4 GTK_FILL - + @@ -207,13 +211,17 @@ True True The username (identity) to use for authentication against the gateway. + False + False + True + True 1 2 - 1 - 2 - + 3 + 4 + @@ -226,10 +234,10 @@ usercert-button - 2 - 3 + 1 + 2 GTK_FILL - + @@ -241,8 +249,8 @@ 1 2 - 2 - 3 + 1 + 2 @@ -255,6 +263,58 @@ 2 + + + True + False + 0 + _Password: + True + user-entry + + + 4 + 5 + GTK_FILL + + + + + + True + True + True + The password to use for authentication against the gateway (min. 20 characters for PSKs). + False + + + 1 + 2 + 4 + 5 + + + + + + _Show password + True + True + False + True + True + + + 1 + 2 + 5 + 6 + + + + + + @@ -307,7 +367,6 @@ False True The Gateway may provide addresses from a pool to use for communication in the Gateways network. Check to request such an address. - False True True @@ -325,7 +384,6 @@ False True Some firewalls block ESP traffic. Enforcing UDP capsulation even if no NAT situation is detected might help in such cases. - False True True @@ -343,7 +401,6 @@ False True IPComp compresses raw IP packets before they get encrypted. This saves some bandwidth, but uses more processing power. - False True True diff --git a/src/frontends/gnome/properties/nm-strongswan.c b/src/frontends/gnome/properties/nm-strongswan.c index 6c59fa7d6..71f874713 100644 --- a/src/frontends/gnome/properties/nm-strongswan.c +++ b/src/frontends/gnome/properties/nm-strongswan.c @@ -32,8 +32,10 @@ #include #include #include +#include #else #include +#include #endif #include "nm-strongswan.h" @@ -142,12 +144,18 @@ static void update_layout (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *p gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"))); + gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show"))); + gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label"))); + gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"))); break; case 1: gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label"))); gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"))); + gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show"))); + gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label"))); + gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button"))); break; @@ -156,6 +164,9 @@ static void update_layout (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *p gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"))); + gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show"))); + gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label"))); + gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button"))); break; @@ -163,6 +174,9 @@ static void update_layout (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *p case 4: gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label"))); gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"))); + gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show"))); + gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label"))); + gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label"))); @@ -185,6 +199,60 @@ settings_changed_cb (GtkWidget *widget, gpointer user_data) g_signal_emit_by_name (STRONGSWAN_PLUGIN_UI_WIDGET (user_data), "changed"); } +static void +show_toggled_cb (GtkCheckButton *button, StrongswanPluginUiWidget *self) +{ + StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self); + GtkWidget *widget; + gboolean visible; + + visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")); + gtk_entry_set_visibility (GTK_ENTRY (widget), visible); +} + +static void +password_storage_changed_cb (GObject *entry, GParamSpec *pspec, gpointer user_data) +{ + settings_changed_cb (NULL, STRONGSWAN_PLUGIN_UI_WIDGET (user_data)); +} + +static void +init_password_icon (StrongswanPluginUiWidget *self, NMSettingVpn *settings, + const char *secret_key, const char *entry_name) +{ + StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self); + GtkWidget *entry; + const char *value = NULL; + NMSettingSecretFlags pw_flags = NM_SETTING_SECRET_FLAG_NONE; + + /* If there's already a password and the password type can't be found in + * the VPN settings, default to saving it. Otherwise, always ask for it. + */ + entry = GTK_WIDGET (gtk_builder_get_object (priv->builder, entry_name)); + + 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". + */ + if (settings) + { + nm_setting_get_secret_flags (NM_SETTING (settings), secret_key, &pw_flags, NULL); + } + + value = gtk_entry_get_text (GTK_ENTRY (entry)); + if ((!value || !*value) && (pw_flags == NM_SETTING_SECRET_FLAG_NONE)) + { + nma_utils_update_password_storage (entry, NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING (settings), secret_key); + } + + g_signal_connect (entry, "notify::secondary-icon-name", + G_CALLBACK (password_storage_changed_cb), self); +} + static gboolean init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError **error) { @@ -215,6 +283,19 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError gtk_entry_set_text (GTK_ENTRY (widget), value); g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self); + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")); + gtk_widget_set_no_show_all (widget, TRUE); + g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (show_toggled_cb), self); + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")); + gtk_widget_set_no_show_all (widget, TRUE); + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")); + gtk_widget_set_no_show_all (widget, TRUE); + value = nm_setting_vpn_get_secret (settings, "password"); + if (value) + gtk_entry_set_text (GTK_ENTRY (widget), value); + g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self); + init_password_icon (self, settings, "password", "passwd-entry"); + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo")); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate/private key")); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate/ssh-agent")); @@ -300,6 +381,37 @@ get_widget (NMVpnEditor *iface) return G_OBJECT (priv->widget); } +static void +save_password_and_flags (NMSettingVpn *settings, GtkBuilder *builder, + const char *entry_name, const char *secret_key) +{ + NMSettingSecretFlags flags; + const char *password; + GtkWidget *entry; + + /* Get secret flags */ + entry = GTK_WIDGET (gtk_builder_get_object (builder, entry_name)); + flags = nma_utils_menu_to_secret_flags (entry); + + /* Save password and convert flags to legacy data items */ + switch (flags) { + case NM_SETTING_SECRET_FLAG_NONE: + /* FALL */ + case NM_SETTING_SECRET_FLAG_AGENT_OWNED: + password = gtk_entry_get_text (GTK_ENTRY (entry)); + if (password && strlen (password)) + { + nm_setting_vpn_add_secret (settings, secret_key, password); + } + break; + default: + break; + } + + /* Set new secret flags */ + nm_setting_set_secret_flags (NM_SETTING (settings), secret_key, flags, NULL); +} + static gboolean update_connection (NMVpnEditor *iface, NMConnection *connection, @@ -365,6 +477,7 @@ update_connection (NMVpnEditor *iface, if (str && strlen (str)) { nm_setting_vpn_add_data_item (settings, "user", str); } + save_password_and_flags (settings, priv->builder, "passwd-entry", "password"); str = "eap"; break; case 4: @@ -373,6 +486,7 @@ update_connection (NMVpnEditor *iface, if (str && strlen (str)) { nm_setting_vpn_add_data_item (settings, "user", str); } + save_password_and_flags (settings, priv->builder, "passwd-entry", "password"); str = "psk"; break; } @@ -390,9 +504,6 @@ update_connection (NMVpnEditor *iface, active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); nm_setting_vpn_add_data_item (settings, "ipcomp", active ? "yes" : "no"); - nm_setting_set_secret_flags (NM_SETTING (settings), "password", - NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL); - nm_connection_add_setting (connection, NM_SETTING (settings)); return TRUE; } @@ -452,6 +563,10 @@ dispose (GObject *object) { StrongswanPluginUiWidget *plugin = STRONGSWAN_PLUGIN_UI_WIDGET (object); StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (plugin); + GtkWidget *widget; + + 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); if (priv->widget) g_object_unref (priv->widget); -- cgit v1.2.3