diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index 5991c2465..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... */ @@ -428,6 +435,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); } } 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 9c9f7d6a0..48edf61b3 100644 --- a/src/frontends/gnome/auth-dialog/Makefile.am +++ b/src/frontends/gnome/auth-dialog/Makefile.am @@ -2,10 +2,9 @@ nm_libexec_PROGRAMS = nm-strongswan-auth-dialog nm_strongswan_auth_dialog_CPPFLAGS = \ $(GTK_CFLAGS) \ - $(LIBGNOMEUI_CFLAGS) \ $(LIBSECRET_CFLAGS) \ - $(NETWORK_MANAGER_CFLAGS) \ - $(NM_UTILS_CFLAGS) \ + $(LIBNM_CFLAGS) \ + $(LIBNMA_CFLAGS) \ -DG_DISABLE_DEPRECATED \ -DGNOME_DISABLE_DEPRECATED \ -DGNOMELOCALEDIR=\"$(datadir)/locale\" \ @@ -16,6 +15,6 @@ nm_strongswan_auth_dialog_SOURCES = \ nm_strongswan_auth_dialog_LDADD = \ $(GTK_LIBS) \ - $(LIBGNOMEUI_LIBS) \ $(LIBSECRET_LIBS) \ - $(NM_UTILS_LIBS) + $(LIBNM_LIBS) \ + $(LIBNMA_LIBS) diff --git a/src/frontends/gnome/auth-dialog/main.c b/src/frontends/gnome/auth-dialog/main.c index 3d5d84390..b4432aae0 100644 --- a/src/frontends/gnome/auth-dialog/main.c +++ b/src/frontends/gnome/auth-dialog/main.c @@ -1,6 +1,10 @@ /* + * Copyright (C) 2015 Lubomir Rintel + * + * Copyright (C) 2013-2016 Tobias Brunner * Copyright (C) 2008-2011 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR Hochschule fuer Technik Rapperswil + * * Copyright (C) 2004 Dan Williams * Red Hat, Inc. * @@ -19,21 +23,202 @@ #include #endif +#include +#include #include #include #include #include -#include -#include -#include -#include -#include + +#include +#include +#include #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; @@ -58,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_plugin_utils_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, *keyring = 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 } }; @@ -124,118 +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 = 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); - } - 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); - } - 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); - 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); - } - gnome_password_dialog_set_show_username(GNOME_PASSWORD_DIALOG(dialog), FALSE); - if (pass) - { - gnome_password_dialog_set_password(GNOME_PASSWORD_DIALOG(dialog), pass); - } - -too_short_retry: - if (!gnome_password_dialog_run_and_block(GNOME_PASSWORD_DIALOG(dialog))) - { - return 1; - } - - pass = gnome_password_dialog_get_password(GNOME_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; - } + 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/configure.ac b/src/frontends/gnome/configure.ac index a2e3beef3..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 @@ -43,13 +43,16 @@ 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(LIBGNOMEUI, libgnomeui-2.0) +PKG_CHECK_MODULES(GTK, gtk+-3.0 >= 3.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 >= 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" +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..ec3b1c374 100644 --- a/src/frontends/gnome/debian/control +++ b/src/frontends/gnome/debian/control @@ -4,19 +4,19 @@ Priority: extra Maintainer: Martin Willi Build-Depends: cdbs, debhelper (>= 7), - network-manager-dev (>= 0.9), - libnm-util-dev (>= 0.9), - libnm-glib-dev (>= 0.9), - libnm-glib-vpn-dev (>= 0.9), - libgnomeui-dev, + 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), 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 (>= 0.9) +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 diff --git a/src/frontends/gnome/nm-strongswan-service.name.in b/src/frontends/gnome/nm-strongswan-service.name.in index eb64a22ff..f52eec26d 100644 --- a/src/frontends/gnome/nm-strongswan-service.name.in +++ b/src/frontends/gnome/nm-strongswan-service.name.in @@ -3,6 +3,10 @@ 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 +supports-external-ui-mode=true diff --git a/src/frontends/gnome/properties/Makefile.am b/src/frontends/gnome/properties/Makefile.am index 66f2d5124..1f138db2f 100644 --- a/src/frontends/gnome/properties/Makefile.am +++ b/src/frontends/gnome/properties/Makefile.am @@ -1,25 +1,47 @@ -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 = \ + $(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) \ - $(NM_UTILS_LIBS) + $(LIBNMA_LIBS) \ + $(LIBNM_LIBS) -libnm_strongswan_properties_la_LDFLAGS = \ +libnm_strongswan_properties_la_LIBADD = \ + $(GTK_LIBS) \ + $(LIBNM_GTK_LIBS) \ + $(LIBNM_GLIB_LIBS) + +libnm_vpn_plugin_strongswan_la_LDFLAGS = \ -avoid-version +libnm_strongswan_properties_la_LDFLAGS = \ + $(libnm_vpn_plugin_strongswan_la_LDFLAGS) + EXTRA_DIST = $(ui_DATA) 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 4cf6864de..b79106826 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,16 @@ #include #include -#define NM_VPN_API_SUBJECT_TO_CHANGE - +#ifdef NM_STRONGSWAN_OLD +#define NM_VPN_LIBNM_COMPAT #include #include #include +#include +#else +#include +#include +#endif #include "nm-strongswan.h" @@ -41,18 +47,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)) @@ -114,10 +127,26 @@ 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; } -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))) { @@ -125,37 +154,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_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, "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, "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_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; } @@ -169,16 +210,70 @@ 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"); } +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) { StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self); - NMSettingVPN *settings; + NMSettingVpn *settings; GtkWidget *widget; const char *value; @@ -195,15 +290,21 @@ 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")); + 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) + 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")); @@ -232,22 +333,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); @@ -281,7 +376,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); @@ -289,14 +384,45 @@ get_widget (NMVpnPluginUiWidgetInterface *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 (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; @@ -354,6 +480,7 @@ update_connection (NMVpnPluginUiWidgetInterface *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: @@ -362,6 +489,7 @@ update_connection (NMVpnPluginUiWidgetInterface *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; } @@ -379,24 +507,21 @@ update_connection (NMVpnPluginUiWidgetInterface *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; } -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; @@ -441,6 +566,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); @@ -467,7 +596,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 +604,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 +620,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 +643,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 +661,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); }