From 05cac184852d8b5df8f1c5d290d3de73c4c9d921 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 21 Oct 2015 10:36:54 +0200 Subject: [PATCH 01/12] nm: Build two plugin binaries from the single source They're both the same now. We'll port the new one to libnm in follow-up commits. NetworkManager 1.2 (which is currently versioned as 1.1.0) is going to bring some new ABI while still supporting the old one. There's new VPN service and UI plugin APIs in libnm. There's one difficulty though -- the connection editor 1.2 will be linked against libnm and a new libnma library it will provide (as opposed to libnm-glib and libnm-gtk), thus will be incapable of loading of property plugins that are linked with the old libraries (due to glib type system limitations). However, we must not break support for other connection editors (GNOME control center, older versions of nm-connection-editor, etc.) therefore we need to build two versions of the property plugin. NetworkManager 1.2's libnm will provide a shim that makes it easy. --- src/frontends/gnome/properties/Makefile.am | 34 +++++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/frontends/gnome/properties/Makefile.am b/src/frontends/gnome/properties/Makefile.am index 66f2d5124..f98ce73b8 100644 --- a/src/frontends/gnome/properties/Makefile.am +++ b/src/frontends/gnome/properties/Makefile.am @@ -1,25 +1,43 @@ -nm_plugin_LTLIBRARIES = libnm-strongswan-properties.la +nm_plugin_LTLIBRARIES = libnm-vpn-plugin-strongswan.la +nm_plugin_LTLIBRARIES += libnm-strongswan-properties.la -libnm_strongswan_properties_la_SOURCES = \ +libnm_vpn_plugin_strongswan_la_SOURCES = \ nm-strongswan.c \ nm-strongswan.h +libnm_strongswan_properties_la_SOURCES = \ + $(libnm_vpn_plugin_strongswan_la_SOURCES) + uidir = $(datadir)/gnome-vpn-properties/strongswan ui_DATA = nm-strongswan-dialog.ui -libnm_strongswan_properties_la_CFLAGS = \ +common_CFLAGS = \ $(GTK_CFLAGS) \ - $(NM_UTILS_CFLAGS) \ -DUIDIR=\""$(uidir)"\" \ -DG_DISABLE_DEPRECATED \ - -DGDK_DISABLE_DEPRECATED \ - -DVERSION=\"$(VERSION)\" + -DGDK_DISABLE_DEPRECATED -libnm_strongswan_properties_la_LIBADD = \ +libnm_vpn_plugin_strongswan_la_CFLAGS = \ + $(NM_UTILS_CFLAGS) \ + $(common_CFLAGS) + +libnm_strongswan_properties_la_CFLAGS = \ + -DNM_STRONGSWAN_OLD \ + $(NM_UTILS_CFLAGS) \ + $(common_CFLAGS) + +libnm_vpn_plugin_strongswan_la_LIBADD = \ $(GTK_LIBS) \ $(NM_UTILS_LIBS) -libnm_strongswan_properties_la_LDFLAGS = \ +libnm_strongswan_properties_la_LIBADD = \ + $(GTK_LIBS) \ + $(NM_UTILS_LIBS) + +libnm_vpn_plugin_strongswan_la_LDFLAGS = \ -avoid-version +libnm_strongswan_properties_la_LDFLAGS = \ + $(libnm_vpn_plugin_strongswan_la_LDFLAGS) + EXTRA_DIST = $(ui_DATA) From 0fa986336307de3d8e21739ad849d3fd675763a7 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 21 Oct 2015 10:56:23 +0200 Subject: [PATCH 02/12] nm: Check for libnm libnm replaces libnm-glib. This will make sense with port to libnm and is done to reduce line noise in that commit. --- src/frontends/gnome/auth-dialog/Makefile.am | 5 ++--- src/frontends/gnome/configure.ac | 10 ++++++---- src/frontends/gnome/debian/control | 1 + src/frontends/gnome/properties/Makefile.am | 8 ++++---- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/frontends/gnome/auth-dialog/Makefile.am b/src/frontends/gnome/auth-dialog/Makefile.am index 9c9f7d6a0..ddfd7eebc 100644 --- a/src/frontends/gnome/auth-dialog/Makefile.am +++ b/src/frontends/gnome/auth-dialog/Makefile.am @@ -4,8 +4,7 @@ nm_strongswan_auth_dialog_CPPFLAGS = \ $(GTK_CFLAGS) \ $(LIBGNOMEUI_CFLAGS) \ $(LIBSECRET_CFLAGS) \ - $(NETWORK_MANAGER_CFLAGS) \ - $(NM_UTILS_CFLAGS) \ + $(LIBNM_GLIB_CFLAGS) \ -DG_DISABLE_DEPRECATED \ -DGNOME_DISABLE_DEPRECATED \ -DGNOMELOCALEDIR=\"$(datadir)/locale\" \ @@ -18,4 +17,4 @@ nm_strongswan_auth_dialog_LDADD = \ $(GTK_LIBS) \ $(LIBGNOMEUI_LIBS) \ $(LIBSECRET_LIBS) \ - $(NM_UTILS_LIBS) + $(LIBNM_GLIB_LIBS) diff --git a/src/frontends/gnome/configure.ac b/src/frontends/gnome/configure.ac index a2e3beef3..41cd56069 100644 --- a/src/frontends/gnome/configure.ac +++ b/src/frontends/gnome/configure.ac @@ -46,10 +46,12 @@ AM_GLIB_GNU_GETTEXT PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.6) PKG_CHECK_MODULES(LIBGNOMEUI, libgnomeui-2.0) PKG_CHECK_MODULES(LIBSECRET, libsecret-1) -PKG_CHECK_EXISTS([libnm-glib], - [PKG_CHECK_MODULES(NM_UTILS, NetworkManager >= 0.9.0 libnm-util libnm-glib libnm-glib-vpn)], - [PKG_CHECK_MODULES(NM_UTILS, NetworkManager >= 0.9.0 libnm-util libnm_glib libnm_glib_vpn)] -) + +PKG_CHECK_MODULES(LIBNM_GLIB, NetworkManager >= 0.9.0 libnm-util libnm-glib libnm-glib-vpn) + +PKG_CHECK_MODULES(LIBNM, libnm >= 1.1.0) +LIBNM_CFLAGS="$LIBNM_CFLAGS -DNM_VERSION_MIN_REQUIRED=NM_VERSION_1_2" +LIBNM_CFLAGS="$LIBNM_CFLAGS -DNM_VERSION_MAX_ALLOWED=NM_VERSION_1_2" AC_ARG_WITH( [charon], diff --git a/src/frontends/gnome/debian/control b/src/frontends/gnome/debian/control index be60bcf14..c35bdf683 100644 --- a/src/frontends/gnome/debian/control +++ b/src/frontends/gnome/debian/control @@ -4,6 +4,7 @@ Priority: extra Maintainer: Martin Willi Build-Depends: cdbs, debhelper (>= 7), + libnm (>= 1.1.0), network-manager-dev (>= 0.9), libnm-util-dev (>= 0.9), libnm-glib-dev (>= 0.9), diff --git a/src/frontends/gnome/properties/Makefile.am b/src/frontends/gnome/properties/Makefile.am index f98ce73b8..fe62f9e00 100644 --- a/src/frontends/gnome/properties/Makefile.am +++ b/src/frontends/gnome/properties/Makefile.am @@ -18,21 +18,21 @@ common_CFLAGS = \ -DGDK_DISABLE_DEPRECATED libnm_vpn_plugin_strongswan_la_CFLAGS = \ - $(NM_UTILS_CFLAGS) \ + $(LIBNM_GLIB_CFLAGS) \ $(common_CFLAGS) libnm_strongswan_properties_la_CFLAGS = \ -DNM_STRONGSWAN_OLD \ - $(NM_UTILS_CFLAGS) \ + $(LIBNM_GLIB_CFLAGS) \ $(common_CFLAGS) libnm_vpn_plugin_strongswan_la_LIBADD = \ $(GTK_LIBS) \ - $(NM_UTILS_LIBS) + $(LIBNM_GLIB_LIBS) libnm_strongswan_properties_la_LIBADD = \ $(GTK_LIBS) \ - $(NM_UTILS_LIBS) + $(LIBNM_GLIB_LIBS) libnm_vpn_plugin_strongswan_la_LDFLAGS = \ -avoid-version From ae8082daa8c796c78537bb018d9abc5f49e84f49 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 21 Oct 2015 11:23:57 +0200 Subject: [PATCH 03/12] nm: Port to libnm --- src/frontends/gnome/Makefile.am | 4 +- src/frontends/gnome/auth-dialog/Makefile.am | 4 +- src/frontends/gnome/auth-dialog/main.c | 9 +-- src/frontends/gnome/configure.ac | 2 +- src/frontends/gnome/debian/control | 10 +-- .../gnome/nm-strongswan-service.name.in | 5 +- src/frontends/gnome/properties/Makefile.am | 4 +- .../gnome/properties/nm-strongswan.c | 73 +++++++++++-------- 8 files changed, 63 insertions(+), 48 deletions(-) diff --git a/src/frontends/gnome/Makefile.am b/src/frontends/gnome/Makefile.am index 12fa6cfb2..43f31e726 100644 --- a/src/frontends/gnome/Makefile.am +++ b/src/frontends/gnome/Makefile.am @@ -19,6 +19,7 @@ install-data-hook: sed -e "1s|^|# This file is obsoleted by a file in $(NM_VPN_SERVICE_DIR)\n\n|" \ -e 's|[@]NM_LIBEXECDIR[@]|$(nm_libexecdir)|g' \ -e 's|[@]NM_PLUGINDIR[@]|$(nm_plugindir)|g' \ + -e 's|[@]NM_PLUGINDIR_ABS[@]|$(nm_plugindir)|g' \ -e 's|[@]CHARON[@]|$(charon)|' \ <$(srcdir)/nm-strongswan-service.name.in \ >$(DESTDIR)$(sysconfdir)/NetworkManager/VPN/nm-strongswan-service.name @@ -29,7 +30,8 @@ uninstall-hook: nm-strongswan-service.name: $(srcdir)/nm-strongswan-service.name.in $(AM_V_GEN) \ sed -e 's|[@]NM_LIBEXECDIR[@]|$(nm_libexecdir)|' \ - -e 's|[@]NM_PLUGINDIR[@]/|$(nm_plugindir_abs)|g' \ + -e 's|[@]NM_PLUGINDIR[@]|$(nm_plugindir)|g' \ + -e 's|[@]NM_PLUGINDIR_ABS[@]/|$(nm_plugindir_abs)|g' \ -e 's|[@]CHARON[@]|$(charon)|' $< >$@ EXTRA_DIST = \ diff --git a/src/frontends/gnome/auth-dialog/Makefile.am b/src/frontends/gnome/auth-dialog/Makefile.am index ddfd7eebc..63c6cede3 100644 --- a/src/frontends/gnome/auth-dialog/Makefile.am +++ b/src/frontends/gnome/auth-dialog/Makefile.am @@ -4,7 +4,7 @@ nm_strongswan_auth_dialog_CPPFLAGS = \ $(GTK_CFLAGS) \ $(LIBGNOMEUI_CFLAGS) \ $(LIBSECRET_CFLAGS) \ - $(LIBNM_GLIB_CFLAGS) \ + $(LIBNM_CFLAGS) \ -DG_DISABLE_DEPRECATED \ -DGNOME_DISABLE_DEPRECATED \ -DGNOMELOCALEDIR=\"$(datadir)/locale\" \ @@ -17,4 +17,4 @@ nm_strongswan_auth_dialog_LDADD = \ $(GTK_LIBS) \ $(LIBGNOMEUI_LIBS) \ $(LIBSECRET_LIBS) \ - $(LIBNM_GLIB_LIBS) + $(LIBNM_LIBS) diff --git a/src/frontends/gnome/auth-dialog/main.c b/src/frontends/gnome/auth-dialog/main.c index 3d5d84390..2b264652a 100644 --- a/src/frontends/gnome/auth-dialog/main.c +++ b/src/frontends/gnome/auth-dialog/main.c @@ -24,10 +24,9 @@ #include #include #include -#include -#include -#include -#include + +#include +#include #define NM_DBUS_SERVICE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan" @@ -66,7 +65,7 @@ static char* get_connection_type(char *uuid) GHashTable *data = NULL, *secrets = NULL; char *method; - if (!nm_vpn_plugin_utils_read_vpn_details (0, &data, &secrets)) { + if (!nm_vpn_service_plugin_read_vpn_details (0, &data, &secrets)) { fprintf (stderr, "Failed to read data and secrets from stdin.\n"); return NULL; } diff --git a/src/frontends/gnome/configure.ac b/src/frontends/gnome/configure.ac index 41cd56069..2a426e7b2 100644 --- a/src/frontends/gnome/configure.ac +++ b/src/frontends/gnome/configure.ac @@ -47,7 +47,7 @@ PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.6) PKG_CHECK_MODULES(LIBGNOMEUI, libgnomeui-2.0) PKG_CHECK_MODULES(LIBSECRET, libsecret-1) -PKG_CHECK_MODULES(LIBNM_GLIB, NetworkManager >= 0.9.0 libnm-util libnm-glib libnm-glib-vpn) +PKG_CHECK_MODULES(LIBNM_GLIB, NetworkManager >= 1.1.0 libnm-util libnm-glib libnm-glib-vpn) 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/debian/control b/src/frontends/gnome/debian/control index c35bdf683..9c33e84ff 100644 --- a/src/frontends/gnome/debian/control +++ b/src/frontends/gnome/debian/control @@ -5,10 +5,10 @@ Maintainer: Martin Willi Build-Depends: cdbs, debhelper (>= 7), libnm (>= 1.1.0), - network-manager-dev (>= 0.9), - libnm-util-dev (>= 0.9), - libnm-glib-dev (>= 0.9), - libnm-glib-vpn-dev (>= 0.9), + network-manager-dev (>= 1.1.0), + libnm-util-dev (>= 1.1.0), + libnm-glib-dev (>= 1.1.0), + libnm-glib-vpn-dev (>= 1.1.0), libgnomeui-dev, libsecret-1-dev, automake, @@ -17,7 +17,7 @@ Standards-Version: 3.8.3 Package: network-manager-strongswan Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, strongswan-nm, network-manager (>= 0.9) +Depends: ${shlibs:Depends}, ${misc:Depends}, strongswan-nm, network-manager (>= 1.1.0) Description: network management framework (strongSwan plugin) NetworkManager attempts to keep an active network connection available at all times. It is intended primarily for laptops where it allows easy diff --git a/src/frontends/gnome/nm-strongswan-service.name.in b/src/frontends/gnome/nm-strongswan-service.name.in index eb64a22ff..d16e90651 100644 --- a/src/frontends/gnome/nm-strongswan-service.name.in +++ b/src/frontends/gnome/nm-strongswan-service.name.in @@ -3,6 +3,9 @@ name=strongswan service=org.freedesktop.NetworkManager.strongswan program=@CHARON@ +[libnm] +plugin=@NM_PLUGINDIR@/libnm-vpn-plugin-strongswan.so + [GNOME] auth-dialog=@NM_LIBEXECDIR@/nm-strongswan-auth-dialog -properties=@NM_PLUGINDIR@/libnm-strongswan-properties +properties=@NM_PLUGINDIR_ABS@/libnm-strongswan-properties diff --git a/src/frontends/gnome/properties/Makefile.am b/src/frontends/gnome/properties/Makefile.am index fe62f9e00..82eae497b 100644 --- a/src/frontends/gnome/properties/Makefile.am +++ b/src/frontends/gnome/properties/Makefile.am @@ -18,7 +18,7 @@ common_CFLAGS = \ -DGDK_DISABLE_DEPRECATED libnm_vpn_plugin_strongswan_la_CFLAGS = \ - $(LIBNM_GLIB_CFLAGS) \ + $(LIBNM_CFLAGS) \ $(common_CFLAGS) libnm_strongswan_properties_la_CFLAGS = \ @@ -28,7 +28,7 @@ libnm_strongswan_properties_la_CFLAGS = \ libnm_vpn_plugin_strongswan_la_LIBADD = \ $(GTK_LIBS) \ - $(LIBNM_GLIB_LIBS) + $(LIBNM_LIBS) libnm_strongswan_properties_la_LIBADD = \ $(GTK_LIBS) \ diff --git a/src/frontends/gnome/properties/nm-strongswan.c b/src/frontends/gnome/properties/nm-strongswan.c index 4cf6864de..6c59fa7d6 100644 --- a/src/frontends/gnome/properties/nm-strongswan.c +++ b/src/frontends/gnome/properties/nm-strongswan.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015 Lubomir Rintel * Copyright (C) 2013 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil @@ -26,11 +27,14 @@ #include #include -#define NM_VPN_API_SUBJECT_TO_CHANGE - +#ifdef NM_STRONGSWAN_OLD +#define NM_VPN_LIBNM_COMPAT #include #include #include +#else +#include +#endif #include "nm-strongswan.h" @@ -41,18 +45,25 @@ /************** plugin class **************/ -static void strongswan_plugin_ui_interface_init (NMVpnPluginUiInterface *iface_class); +enum { + PROP_0, + PROP_NAME, + PROP_DESC, + PROP_SERVICE +}; + +static void strongswan_plugin_ui_interface_init (NMVpnEditorPluginInterface *iface_class); G_DEFINE_TYPE_EXTENDED (StrongswanPluginUi, strongswan_plugin_ui, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_PLUGIN_UI_INTERFACE, + G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_EDITOR_PLUGIN, strongswan_plugin_ui_interface_init)) /************** UI widget class **************/ -static void strongswan_plugin_ui_widget_interface_init (NMVpnPluginUiWidgetInterface *iface_class); +static void strongswan_plugin_ui_widget_interface_init (NMVpnEditorInterface *iface_class); G_DEFINE_TYPE_EXTENDED (StrongswanPluginUiWidget, strongswan_plugin_ui_widget, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_PLUGIN_UI_WIDGET_INTERFACE, + G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_EDITOR, strongswan_plugin_ui_widget_interface_init)) #define STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, StrongswanPluginUiWidgetPrivate)) @@ -178,7 +189,7 @@ static gboolean init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError **error) { StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self); - NMSettingVPN *settings; + NMSettingVpn *settings; GtkWidget *widget; const char *value; @@ -281,7 +292,7 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError } static GObject * -get_widget (NMVpnPluginUiWidgetInterface *iface) +get_widget (NMVpnEditor *iface) { StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (iface); StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self); @@ -290,13 +301,13 @@ get_widget (NMVpnPluginUiWidgetInterface *iface) } static gboolean -update_connection (NMVpnPluginUiWidgetInterface *iface, +update_connection (NMVpnEditor *iface, NMConnection *connection, GError **error) { StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (iface); StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self); - NMSettingVPN *settings; + NMSettingVpn *settings; GtkWidget *widget; gboolean active; char *str; @@ -386,17 +397,17 @@ update_connection (NMVpnPluginUiWidgetInterface *iface, return TRUE; } -static NMVpnPluginUiWidgetInterface * +static NMVpnEditor * nm_vpn_plugin_ui_widget_interface_new (NMConnection *connection, GError **error) { - NMVpnPluginUiWidgetInterface *object; + NMVpnEditor *object; StrongswanPluginUiWidgetPrivate *priv; char *ui_file; if (error) g_return_val_if_fail (*error == NULL, NULL); - object = NM_VPN_PLUGIN_UI_WIDGET_INTERFACE (g_object_new (STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, NULL)); + object = g_object_new (STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, NULL); if (!object) { g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not create strongswan object"); return NULL; @@ -467,7 +478,7 @@ strongswan_plugin_ui_widget_init (StrongswanPluginUiWidget *plugin) } static void -strongswan_plugin_ui_widget_interface_init (NMVpnPluginUiWidgetInterface *iface_class) +strongswan_plugin_ui_widget_interface_init (NMVpnEditorInterface *iface_class) { /* interface implementation */ iface_class->get_widget = get_widget; @@ -475,13 +486,13 @@ strongswan_plugin_ui_widget_interface_init (NMVpnPluginUiWidgetInterface *iface_ } static guint32 -get_capabilities (NMVpnPluginUiInterface *iface) +get_capabilities (NMVpnEditorPlugin *iface) { return 0; } -static NMVpnPluginUiWidgetInterface * -ui_factory (NMVpnPluginUiInterface *iface, NMConnection *connection, GError **error) +static NMVpnEditor * +get_editor (NMVpnEditorPlugin *iface, NMConnection *connection, GError **error) { return nm_vpn_plugin_ui_widget_interface_new (connection, error); } @@ -491,13 +502,13 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { switch (prop_id) { - case NM_VPN_PLUGIN_UI_INTERFACE_PROP_NAME: + case PROP_NAME: g_value_set_string (value, STRONGSWAN_PLUGIN_NAME); break; - case NM_VPN_PLUGIN_UI_INTERFACE_PROP_DESC: + case PROP_DESC: g_value_set_string (value, STRONGSWAN_PLUGIN_DESC); break; - case NM_VPN_PLUGIN_UI_INTERFACE_PROP_SERVICE: + case PROP_SERVICE: g_value_set_string (value, STRONGSWAN_PLUGIN_SERVICE); break; default: @@ -514,16 +525,16 @@ strongswan_plugin_ui_class_init (StrongswanPluginUiClass *req_class) object_class->get_property = get_property; g_object_class_override_property (object_class, - NM_VPN_PLUGIN_UI_INTERFACE_PROP_NAME, - NM_VPN_PLUGIN_UI_INTERFACE_NAME); + PROP_NAME, + NM_VPN_EDITOR_PLUGIN_NAME); g_object_class_override_property (object_class, - NM_VPN_PLUGIN_UI_INTERFACE_PROP_DESC, - NM_VPN_PLUGIN_UI_INTERFACE_DESC); + PROP_DESC, + NM_VPN_EDITOR_PLUGIN_DESCRIPTION); g_object_class_override_property (object_class, - NM_VPN_PLUGIN_UI_INTERFACE_PROP_SERVICE, - NM_VPN_PLUGIN_UI_INTERFACE_SERVICE); + PROP_SERVICE, + NM_VPN_EDITOR_PLUGIN_SERVICE); } static void @@ -532,20 +543,20 @@ strongswan_plugin_ui_init (StrongswanPluginUi *plugin) } static void -strongswan_plugin_ui_interface_init (NMVpnPluginUiInterface *iface_class) +strongswan_plugin_ui_interface_init (NMVpnEditorPluginInterface *iface_class) { /* interface implementation */ - iface_class->ui_factory = ui_factory; + iface_class->get_editor = get_editor; iface_class->get_capabilities = get_capabilities; /* TODO: implement delete_connection to purge associated secrets */ } -G_MODULE_EXPORT NMVpnPluginUiInterface * -nm_vpn_plugin_ui_factory (GError **error) +G_MODULE_EXPORT NMVpnEditorPlugin * +nm_vpn_editor_plugin_factory (GError **error) { if (error) g_return_val_if_fail (*error == NULL, NULL); - return NM_VPN_PLUGIN_UI_INTERFACE (g_object_new (STRONGSWAN_TYPE_PLUGIN_UI, NULL)); + return g_object_new (STRONGSWAN_TYPE_PLUGIN_UI, NULL); } From 53fe8b12458bf166fdf35ab8b527a75daf78209d Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 29 Mar 2016 20:07:04 +0200 Subject: [PATCH 04/12] 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 ++++++++++++---- .../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); From 456044189c3bde3df5b60e572b8aaf7715600672 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 29 Mar 2016 22:33:30 +0200 Subject: [PATCH 05/12] nm: Grey out the unneeded authentication options Hiding and showing the items is not ideal, since it leaves the spacing in place and the layout gets really messy. --- .../gnome/properties/nm-strongswan.c | 91 ++++++++----------- 1 file changed, 39 insertions(+), 52 deletions(-) diff --git a/src/frontends/gnome/properties/nm-strongswan.c b/src/frontends/gnome/properties/nm-strongswan.c index 71f874713..223dfb32c 100644 --- a/src/frontends/gnome/properties/nm-strongswan.c +++ b/src/frontends/gnome/properties/nm-strongswan.c @@ -130,7 +130,7 @@ check_validity (StrongswanPluginUiWidget *self, GError **error) return TRUE; } -static void update_layout (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *priv) +static void update_sensitive (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *priv) { switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget))) { @@ -138,49 +138,49 @@ static void update_layout (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *p gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); /* FALL */ case 0: - 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_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label"))); - 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"))); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), FALSE); 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"))); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), FALSE); break; case 2: - 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, "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"))); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), FALSE); break; case 3: 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"))); - gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button"))); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), FALSE); break; } @@ -194,7 +194,7 @@ settings_changed_cb (GtkWidget *widget, gpointer user_data) if (widget == GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"))) { - update_layout(GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo")), priv); + update_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo")), priv); } g_signal_emit_by_name (STRONGSWAN_PLUGIN_UI_WIDGET (user_data), "changed"); } @@ -274,22 +274,15 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value); g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self); - widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")); - gtk_widget_set_no_show_all (widget, TRUE); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")); - gtk_widget_set_no_show_all (widget, TRUE); value = nm_setting_vpn_get_data_item (settings, "user"); if (value) 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); @@ -324,22 +317,16 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError { gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); } - update_layout (widget, priv); + update_sensitive (widget, priv); g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self); - widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")); - gtk_widget_set_no_show_all (widget, TRUE); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")); - gtk_widget_set_no_show_all (widget, TRUE); value = nm_setting_vpn_get_data_item (settings, "usercert"); if (value) gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value); g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self); - widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")); - gtk_widget_set_no_show_all (widget, TRUE); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")); - gtk_widget_set_no_show_all (widget, TRUE); value = nm_setting_vpn_get_data_item (settings, "userkey"); if (value) gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value); From 47bd094e5399ba33d28982f2b53b81bedc7377d6 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 21 Oct 2015 11:29:25 +0200 Subject: [PATCH 06/12] nm: Replace libgnomeui with libnma for password dialog libgnomeui is long deprecated. There's one functional difference: the choice to save the passwords is gone. The password flags and saved password should be set in the preferences dialog, but this commit does not fix that. --- src/frontends/gnome/auth-dialog/Makefile.am | 6 +- src/frontends/gnome/auth-dialog/main.c | 67 ++++++++------------- src/frontends/gnome/configure.ac | 1 - src/frontends/gnome/debian/control | 5 +- 4 files changed, 30 insertions(+), 49 deletions(-) diff --git a/src/frontends/gnome/auth-dialog/Makefile.am b/src/frontends/gnome/auth-dialog/Makefile.am index 63c6cede3..48edf61b3 100644 --- a/src/frontends/gnome/auth-dialog/Makefile.am +++ b/src/frontends/gnome/auth-dialog/Makefile.am @@ -2,9 +2,9 @@ nm_libexec_PROGRAMS = nm-strongswan-auth-dialog nm_strongswan_auth_dialog_CPPFLAGS = \ $(GTK_CFLAGS) \ - $(LIBGNOMEUI_CFLAGS) \ $(LIBSECRET_CFLAGS) \ $(LIBNM_CFLAGS) \ + $(LIBNMA_CFLAGS) \ -DG_DISABLE_DEPRECATED \ -DGNOME_DISABLE_DEPRECATED \ -DGNOMELOCALEDIR=\"$(datadir)/locale\" \ @@ -15,6 +15,6 @@ nm_strongswan_auth_dialog_SOURCES = \ nm_strongswan_auth_dialog_LDADD = \ $(GTK_LIBS) \ - $(LIBGNOMEUI_LIBS) \ $(LIBSECRET_LIBS) \ - $(LIBNM_LIBS) + $(LIBNM_LIBS) \ + $(LIBNMA_LIBS) diff --git a/src/frontends/gnome/auth-dialog/main.c b/src/frontends/gnome/auth-dialog/main.c index 2b264652a..ee794a614 100644 --- a/src/frontends/gnome/auth-dialog/main.c +++ b/src/frontends/gnome/auth-dialog/main.c @@ -1,6 +1,9 @@ /* + * Copyright (C) 2015 Lubomir Rintel + * * Copyright (C) 2008-2011 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR Hochschule fuer Technik Rapperswil + * * Copyright (C) 2004 Dan Williams * Red Hat, Inc. * @@ -19,14 +22,16 @@ #include #endif +#include +#include #include #include #include #include -#include #include #include +#include #define NM_DBUS_SERVICE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan" @@ -85,7 +90,7 @@ static char* get_connection_type(char *uuid) int main (int argc, char *argv[]) { gboolean retry = FALSE, allow_interaction = FALSE; - gchar *name = NULL, *uuid = NULL, *service = NULL, *keyring = NULL, *pass; + gchar *name = NULL, *uuid = NULL, *service = NULL, *pass; GOptionContext *context; char *agent, *type; guint32 minlen = 0; @@ -142,69 +147,47 @@ int main (int argc, char *argv[]) { if (!strcmp(type, "eap")) { - dialog = gnome_password_dialog_new(_("VPN password required"), - _("EAP password required to establish VPN connection:"), - NULL, NULL, TRUE); - gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE); + dialog = nma_vpn_password_dialog_new(_("VPN password required"), + _("EAP password required to establish VPN connection:"), + NULL); } else if (!strcmp(type, "key")) { - dialog = gnome_password_dialog_new(_("VPN password required"), - _("Private key decryption password required to establish VPN connection:"), - NULL, NULL, TRUE); - gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE); + dialog = nma_vpn_password_dialog_new(_("VPN password required"), + _("Private key decryption password required to establish VPN connection:"), + NULL); } else if (!strcmp(type, "psk")) { - dialog = gnome_password_dialog_new(_("VPN password required"), - _("Pre-shared key required to establish VPN connection (min. 20 characters):"), - NULL, NULL, TRUE); - gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE); + dialog = nma_vpn_password_dialog_new(_("VPN password required"), + _("Pre-shared key required to establish VPN connection (min. 20 characters):"), + NULL); minlen = 20; } else /* smartcard */ { - dialog = gnome_password_dialog_new(_("VPN password required"), - _("Smartcard PIN required to establish VPN connection:"), - NULL, NULL, TRUE); - gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), FALSE); + dialog = nma_vpn_password_dialog_new(_("VPN password required"), + _("Smartcard PIN required to establish VPN connection:"), + NULL); } - gnome_password_dialog_set_show_username(GNOME_PASSWORD_DIALOG(dialog), FALSE); if (pass) { - gnome_password_dialog_set_password(GNOME_PASSWORD_DIALOG(dialog), pass); + nma_vpn_password_dialog_set_password(NMA_VPN_PASSWORD_DIALOG(dialog), pass); } + nma_vpn_password_dialog_set_show_password_secondary(NMA_VPN_PASSWORD_DIALOG(dialog), FALSE); + gtk_widget_show(dialog); too_short_retry: - if (!gnome_password_dialog_run_and_block(GNOME_PASSWORD_DIALOG(dialog))) + if (!nma_vpn_password_dialog_run_and_block(NMA_VPN_PASSWORD_DIALOG(dialog))) { return 1; } - pass = gnome_password_dialog_get_password(GNOME_PASSWORD_DIALOG(dialog)); + pass = g_strdup(nma_vpn_password_dialog_get_password(NMA_VPN_PASSWORD_DIALOG(dialog))); if (minlen && strlen(pass) < minlen) { goto too_short_retry; } - switch (gnome_password_dialog_get_remember(GNOME_PASSWORD_DIALOG(dialog))) - { - case GNOME_PASSWORD_DIALOG_REMEMBER_NOTHING: - break; - case GNOME_PASSWORD_DIALOG_REMEMBER_SESSION: - keyring = SECRET_COLLECTION_SESSION; - /* FALL */ - case GNOME_PASSWORD_DIALOG_REMEMBER_FOREVER: - if (!secret_password_store_sync(SECRET_SCHEMA_COMPAT_NETWORK, - keyring, "", pass, NULL, NULL, - "user", g_get_user_name(), - "server", name, - "protocol", service, - NULL)) - { - g_warning ("storing password in keyring failed"); - } - break; - } } if (pass) { diff --git a/src/frontends/gnome/configure.ac b/src/frontends/gnome/configure.ac index 13fb7a646..1f726aaa4 100644 --- a/src/frontends/gnome/configure.ac +++ b/src/frontends/gnome/configure.ac @@ -44,7 +44,6 @@ IT_PROG_INTLTOOL([0.35]) AM_GLIB_GNU_GETTEXT PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.6) -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) diff --git a/src/frontends/gnome/debian/control b/src/frontends/gnome/debian/control index 9c33e84ff..ec3b1c374 100644 --- a/src/frontends/gnome/debian/control +++ b/src/frontends/gnome/debian/control @@ -5,19 +5,18 @@ Maintainer: Martin Willi Build-Depends: cdbs, debhelper (>= 7), libnm (>= 1.1.0), + libnma-dev (>= 1.1.0), network-manager-dev (>= 1.1.0), libnm-util-dev (>= 1.1.0), libnm-glib-dev (>= 1.1.0), libnm-glib-vpn-dev (>= 1.1.0), - libgnomeui-dev, libsecret-1-dev, automake, - gnome-common, Standards-Version: 3.8.3 Package: network-manager-strongswan Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, strongswan-nm, network-manager (>= 1.1.0) +Depends: ${shlibs:Depends}, ${misc:Depends}, strongswan-nm, network-manager (>= 1.1.0), libnma (>= 1.11.0) Description: network management framework (strongSwan plugin) NetworkManager attempts to keep an active network connection available at all times. It is intended primarily for laptops where it allows easy From 7714c631d8b981aa8bb14a88d73948fd80204cf2 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 21 Oct 2015 13:04:14 +0200 Subject: [PATCH 07/12] nm: Bump to GTK+ 3.0 It's been released years ago; we depend on newer stuff than that now. --- src/frontends/gnome/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontends/gnome/configure.ac b/src/frontends/gnome/configure.ac index 1f726aaa4..313bfc835 100644 --- a/src/frontends/gnome/configure.ac +++ b/src/frontends/gnome/configure.ac @@ -43,7 +43,7 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package]) IT_PROG_INTLTOOL([0.35]) AM_GLIB_GNU_GETTEXT -PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.6) +PKG_CHECK_MODULES(GTK, gtk+-3.0 >= 3.0) PKG_CHECK_MODULES(LIBSECRET, libsecret-1) PKG_CHECK_MODULES(LIBNM_GLIB, NetworkManager >= 1.1.0 libnm-util libnm-glib libnm-glib-vpn) From a238f534e886a8e6e34b691e244ee6836daaa7e4 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 21 Oct 2015 13:06:42 +0200 Subject: [PATCH 08/12] nm: Bump minor version to 1.4.0 This is probably a good idea to do to signal there's significant changes in dependencies to the distro package maintainers with libnm port and associated changes. --- src/frontends/gnome/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontends/gnome/configure.ac b/src/frontends/gnome/configure.ac index 313bfc835..4d27615de 100644 --- a/src/frontends/gnome/configure.ac +++ b/src/frontends/gnome/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ(2.52) -AC_INIT(NetworkManager-strongswan, 1.3.2, martin@strongswan.org, NetworkManager-strongswan) +AC_INIT(NetworkManager-strongswan, 1.4.0, martin@strongswan.org, NetworkManager-strongswan) AM_INIT_AUTOMAKE([subdir-objects]) AM_MAINTAINER_MODE From 2b63883dba7ff015ee6a013cf5583ac464509e2c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 21 Apr 2016 17:46:02 +0200 Subject: [PATCH 09/12] nm: Add minimum length constraint for PSK passwords in connection editor We already have this restriction in the auth-dialog. --- src/frontends/gnome/properties/nm-strongswan.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/frontends/gnome/properties/nm-strongswan.c b/src/frontends/gnome/properties/nm-strongswan.c index 223dfb32c..b79106826 100644 --- a/src/frontends/gnome/properties/nm-strongswan.c +++ b/src/frontends/gnome/properties/nm-strongswan.c @@ -127,6 +127,22 @@ check_validity (StrongswanPluginUiWidget *self, GError **error) "address"); return FALSE; } + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo")); + switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget))) + { + case 4: + { + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")); + str = (char *) gtk_entry_get_text (GTK_ENTRY (widget)); + if (str && strlen (str) < 20) { + g_set_error (error, + STRONGSWAN_PLUGIN_UI_ERROR, + STRONGSWAN_PLUGIN_UI_ERROR_INVALID_PROPERTY, + "password is too short"); + return FALSE; + } + } + } return TRUE; } From 9e74a0952e27e3ac0055b0831919aaddfef1e1b5 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 5 Sep 2016 10:54:07 +0200 Subject: [PATCH 10/12] nm: Enforce min. length for PSKs in backend --- src/charon-nm/nm/nm_service.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index 5991c2465..c0c78eff4 100644 --- a/src/charon-nm/nm/nm_service.c +++ b/src/charon-nm/nm/nm_service.c @@ -428,6 +428,16 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, { user = identification_create_from_string((char*)str); str = nm_setting_vpn_get_secret(vpn, "password"); + if (auth_class == AUTH_CLASS_PSK && + strlen(str) < 20) + { + g_set_error(err, NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "pre-shared key is too short."); + gateway->destroy(gateway); + user->destroy(user); + return FALSE; + } priv->creds->set_username_password(priv->creds, user, (char*)str); } } From be1061c92080510b7d440588a4386cb66ce60441 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 5 Sep 2016 10:58:16 +0200 Subject: [PATCH 11/12] nm: Update auth-dialog This updates the auth dialog so that passwords are properly retrieved (e.g. for the nm-applet). It also adds support for external UI mode and properly handles secret flags. --- src/frontends/gnome/auth-dialog/main.c | 356 ++++++++++++------ .../gnome/nm-strongswan-service.name.in | 1 + 2 files changed, 251 insertions(+), 106 deletions(-) diff --git a/src/frontends/gnome/auth-dialog/main.c b/src/frontends/gnome/auth-dialog/main.c index ee794a614..b4432aae0 100644 --- a/src/frontends/gnome/auth-dialog/main.c +++ b/src/frontends/gnome/auth-dialog/main.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2015 Lubomir Rintel * + * Copyright (C) 2013-2016 Tobias Brunner * Copyright (C) 2008-2011 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -35,9 +36,189 @@ #define NM_DBUS_SERVICE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan" -/** - * Wait for quit input - */ +#define KEYRING_UUID_TAG "connection-uuid" +#define KEYRING_SN_TAG "setting-name" +#define KEYRING_SK_TAG "setting-key" + +static const SecretSchema network_manager_secret_schema = { + "org.freedesktop.NetworkManager.Connection", + SECRET_SCHEMA_DONT_MATCH_NAME, + { + { KEYRING_UUID_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING }, + { KEYRING_SN_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING }, + { KEYRING_SK_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING }, + { NULL, 0 }, + } +}; + +#define UI_KEYFILE_GROUP "VPN Plugin UI" + +static char *keyring_lookup_secret(const char *uuid, const char *secret_name) +{ + GHashTable *attrs; + GList *list; + char *secret = NULL; + + attrs = secret_attributes_build(&network_manager_secret_schema, + KEYRING_UUID_TAG, uuid, + KEYRING_SN_TAG, NM_SETTING_VPN_SETTING_NAME, + KEYRING_SK_TAG, secret_name, + NULL); + + list = secret_service_search_sync (NULL, &network_manager_secret_schema, attrs, + SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS, + NULL, NULL); + if (list && list->data) + { + SecretItem *item = list->data; + SecretValue *value = secret_item_get_secret (item); + + if (value) + { + secret = g_strdup (secret_value_get (value, NULL)); + secret_value_unref (value); + } + } + + g_list_free_full (list, g_object_unref); + g_hash_table_unref (attrs); + return secret; +} + +static void keyfile_add_entry_info(GKeyFile *keyfile, const gchar *key, const gchar *value, + const gchar *label, gboolean is_secret, gboolean should_ask) +{ + g_key_file_set_string (keyfile, key, "Value", value); + g_key_file_set_string (keyfile, key, "Label", label); + g_key_file_set_boolean (keyfile, key, "IsSecret", is_secret); + g_key_file_set_boolean (keyfile, key, "ShouldAsk", should_ask); +} + +static void keyfile_print_stdout (GKeyFile *keyfile) +{ + gchar *data; + gsize length; + + data = g_key_file_to_data (keyfile, &length, NULL); + + fputs (data, stdout); + + g_free (data); +} + +static gboolean get_secrets(const char *type, const char *uuid, const char *name, gboolean retry, + gboolean allow_interaction, gboolean external_ui_mode, + const char *in_pw, char **out_pw, NMSettingSecretFlags flags) +{ + NMAVpnPasswordDialog *dialog; + char *prompt, *pw = NULL; + const char *new_pw = NULL; + guint32 minlen = 0; + + if (!(flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) && + !(flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) + { + if (in_pw) + { + pw = g_strdup (in_pw); + } + else + { + pw = keyring_lookup_secret (uuid, "password"); + } + } + if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) + { + g_free (pw); + return TRUE; + } + if (!strcmp(type, "eap")) + { + prompt = g_strdup_printf (_("EAP password required to establish VPN connection '%s'."), + name); + } + else if (!strcmp(type, "key")) + { + prompt = g_strdup_printf (_("Private key decryption password required to establish VPN connection '%s'."), + name); + } + else if (!strcmp(type, "psk")) + { + prompt = g_strdup_printf (_("Pre-shared key required to establish VPN connection '%s' (min. 20 characters)."), + name); + minlen = 20; + } + else /* smartcard */ + { + prompt = g_strdup_printf (_("Smartcard PIN required to establish VPN connection '%s'."), + name); + } + 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")); + + keyfile_add_entry_info (keyfile, "password", pw ?: "", _("Password:"), 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))) + { + /* 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; + 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); + + if (pw && !(flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) + { + nma_vpn_password_dialog_set_password(dialog, pw); + } + gtk_widget_show (GTK_WIDGET (dialog)); + +too_short_retry: + if (nma_vpn_password_dialog_run_and_block (dialog)) + { + new_pw = nma_vpn_password_dialog_get_password(dialog); + if (new_pw && minlen && strlen(new_pw) < minlen) + { + goto too_short_retry; + } + else if (new_pw) + { + *out_pw = g_strdup (new_pw); + } + } + gtk_widget_hide (GTK_WIDGET (dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); +out: + g_free (prompt); + return TRUE; +} + +static void print_secret (const char *secret_name, gchar *secret) +{ + if (secret) + { + printf("%s\n%s\n", secret_name, secret); + g_free(secret); + } + printf("\n\n"); + fflush(stdout); +} + static void wait_for_quit (void) { GString *str; @@ -62,45 +243,22 @@ static void wait_for_quit (void) g_string_free (str, TRUE); } -/** - * get the connection type - */ -static char* get_connection_type(char *uuid) -{ - GHashTable *data = NULL, *secrets = NULL; - char *method; - - if (!nm_vpn_service_plugin_read_vpn_details (0, &data, &secrets)) { - fprintf (stderr, "Failed to read data and secrets from stdin.\n"); - return NULL; - } - - method = g_hash_table_lookup (data, "method"); - if (method) - method = g_strdup(method); - - if (data) - g_hash_table_unref (data); - if (secrets) - g_hash_table_unref (secrets); - - return method; -} - int main (int argc, char *argv[]) { - gboolean retry = FALSE, allow_interaction = FALSE; - gchar *name = NULL, *uuid = NULL, *service = NULL, *pass; + gboolean retry = FALSE, allow_interaction = FALSE, external_ui_mode = FALSE; + gchar *name = NULL, *uuid = NULL, *service = NULL, *pass = NULL; + GHashTable *data = NULL, *secrets = NULL; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; GOptionContext *context; char *agent, *type; - guint32 minlen = 0; - GtkWidget *dialog; + int status = 0; GOptionEntry entries[] = { { "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL}, { "uuid", 'u', 0, G_OPTION_ARG_STRING, &uuid, "UUID of VPN connection", NULL}, { "name", 'n', 0, G_OPTION_ARG_STRING, &name, "Name of VPN connection", NULL}, { "service", 's', 0, G_OPTION_ARG_STRING, &service, "VPN service type", NULL}, { "allow-interaction", 'i', 0, G_OPTION_ARG_NONE, &allow_interaction, "Allow user interaction", NULL}, + { "external-ui-mode", 0, 0, G_OPTION_ARG_NONE, &external_ui_mode, "External UI mode", NULL}, { NULL } }; @@ -128,96 +286,82 @@ int main (int argc, char *argv[]) return 1; } - type = get_connection_type(uuid); + if (!nm_vpn_service_plugin_read_vpn_details (0, &data, &secrets)) + { + fprintf(stderr, "Failed to read '%s' (%s) data and secrets from stdin.\n", + name, uuid); + return 1; + } + + type = g_hash_table_lookup (data, "method"); if (!type) { fprintf(stderr, "Connection lookup failed\n"); - return 1; + status = 1; + goto out; } - if (!strcmp(type, "eap") || !strcmp(type, "key") || !strcmp(type, "psk") || - !strcmp(type, "smartcard")) + + if (!strcmp(type, "eap") || !strcmp(type, "key") || + !strcmp(type, "psk") || !strcmp(type, "smartcard")) { - pass = secret_password_lookup_sync(SECRET_SCHEMA_COMPAT_NETWORK, NULL, NULL, - "user", g_get_user_name(), - "server", name, - "protocol", service, - NULL); - - if ((!pass || retry) && allow_interaction) + nm_vpn_service_plugin_get_secret_flags (secrets, "password", &flags); + if (!get_secrets(type, uuid, name, retry, allow_interaction, external_ui_mode, + g_hash_table_lookup (secrets, "password"), &pass, flags)) { - if (!strcmp(type, "eap")) - { - dialog = nma_vpn_password_dialog_new(_("VPN password required"), - _("EAP password required to establish VPN connection:"), - NULL); - } - else if (!strcmp(type, "key")) - { - dialog = nma_vpn_password_dialog_new(_("VPN password required"), - _("Private key decryption password required to establish VPN connection:"), - NULL); - } - else if (!strcmp(type, "psk")) - { - dialog = nma_vpn_password_dialog_new(_("VPN password required"), - _("Pre-shared key required to establish VPN connection (min. 20 characters):"), - NULL); - minlen = 20; - } - else /* smartcard */ - { - dialog = nma_vpn_password_dialog_new(_("VPN password required"), - _("Smartcard PIN required to establish VPN connection:"), - NULL); - } - if (pass) - { - nma_vpn_password_dialog_set_password(NMA_VPN_PASSWORD_DIALOG(dialog), pass); - } - - nma_vpn_password_dialog_set_show_password_secondary(NMA_VPN_PASSWORD_DIALOG(dialog), FALSE); - gtk_widget_show(dialog); -too_short_retry: - if (!nma_vpn_password_dialog_run_and_block(NMA_VPN_PASSWORD_DIALOG(dialog))) - { - return 1; - } - - pass = g_strdup(nma_vpn_password_dialog_get_password(NMA_VPN_PASSWORD_DIALOG(dialog))); - if (minlen && strlen(pass) < minlen) - { - goto too_short_retry; - } + status = 1; } - if (pass) + else if (!external_ui_mode) { - printf("password\n%s\n", pass); - g_free(pass); + print_secret("password", pass); + wait_for_quit (); } } - else + else if (!strcmp(type, "agent")) { agent = getenv("SSH_AUTH_SOCK"); if (agent) { - printf("agent\n%s\n", agent); - } - else - { - if (allow_interaction) + if (external_ui_mode) { - 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); + 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", "SSH agent"); + g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Title", _("Authenticate VPN")); + + keyfile_add_entry_info (keyfile, "agent", agent, "SSH agent socket", TRUE, FALSE); + + keyfile_print_stdout (keyfile); + g_key_file_unref (keyfile); + } + else + { + print_secret("agent", g_strdup (agent)); + wait_for_quit (); } } + else 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); + } } - printf("\n\n"); - /* flush output, wait for input */ - fflush(stdout); - wait_for_quit (); - return 0; + +out: + if (data) + { + g_hash_table_unref (data); + } + if (secrets) + { + g_hash_table_unref(secrets); + } + return status; } diff --git a/src/frontends/gnome/nm-strongswan-service.name.in b/src/frontends/gnome/nm-strongswan-service.name.in index d16e90651..f52eec26d 100644 --- a/src/frontends/gnome/nm-strongswan-service.name.in +++ b/src/frontends/gnome/nm-strongswan-service.name.in @@ -9,3 +9,4 @@ plugin=@NM_PLUGINDIR@/libnm-vpn-plugin-strongswan.so [GNOME] auth-dialog=@NM_LIBEXECDIR@/nm-strongswan-auth-dialog properties=@NM_PLUGINDIR_ABS@/libnm-strongswan-properties +supports-external-ui-mode=true From f201d86debb12731b634625a0278e289e3e05e10 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 5 Sep 2016 14:34:07 +0200 Subject: [PATCH 12/12] nm: Pass external gateway to NM This seems to be required by newer versions. --- src/charon-nm/nm/nm_service.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index c0c78eff4..0fe10e00f 100644 --- a/src/charon-nm/nm/nm_service.c +++ b/src/charon-nm/nm/nm_service.c @@ -88,12 +88,19 @@ static void signal_ipv4_config(NMVPNPlugin *plugin, GValue *val; GHashTable *config; enumerator_t *enumerator; - host_t *me; + host_t *me, *other; nm_handler_t *handler; config = g_hash_table_new(g_str_hash, g_str_equal); handler = priv->handler; + /* NM apparently requires to know the gateway */ + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + other = ike_sa->get_other_host(ike_sa); + g_value_set_uint (val, *(uint32_t*)other->get_address(other).ptr); + g_hash_table_insert (config, NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, val); + /* NM requires a tundev, but netkey does not use one. Passing the physical * interface does not work, as NM fiddles around with it. So we pass a dummy * TUN device along for NM to play with... */