[network-manager-openvpn/NETWORKMANAGER_0_7] export: implement export and fix a few import/export bugs (bgo #573986)



commit f886bfdf9573ec74ba2326d860c8222af5bb9d01
Author: Dan Williams <dcbw redhat com>
Date:   Fri Oct 30 13:48:57 2009 -0700

    export: implement export and fix a few import/export bugs (bgo #573986)
    
    do_export() by Huzaifa S. Sidhpurwala <huzaifas redhat com> with
    cleanups by me.  Testcases and import/export bugfixes by me.

 Makefile.am                           |    3 +-
 configure.ac                          |   16 ++
 nm-test-helpers.h                     |   51 ++++
 properties/Makefile.am                |    4 +-
 properties/import-export.c            |  148 +++++++++++-
 properties/nm-openvpn.c               |   21 ++-
 properties/tests/Makefile.am          |   35 +++
 properties/tests/conf/Makefile.am     |    6 +
 properties/tests/conf/iso885915.ovpn  |   14 +
 properties/tests/conf/password.conf   |   29 +++
 properties/tests/conf/tls.ovpn        |   19 ++
 properties/tests/test-import-export.c |  431 +++++++++++++++++++++++++++++++++
 12 files changed, 764 insertions(+), 13 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 522ae18..e86d11f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,7 +31,8 @@ EXTRA_DIST = nm-openvpn-service.name.in \
              $(icon_DATA)         \
              intltool-extract.in  \
              intltool-merge.in    \
-             intltool-update.in
+             intltool-update.in \
+             nm-test-helpers.h
 
 CLEANFILES = $(nmvpnservice_DATA) $(desktop_DATA) *~
 DISTCLEANFILES = intltool-extract intltool-merge intltool-update
diff --git a/configure.ac b/configure.ac
index 76ce4aa..3ce0753 100644
--- a/configure.ac
+++ b/configure.ac
@@ -101,12 +101,28 @@ fi
 
 NM_COMPILER_WARNINGS
 
+dnl
+dnl Tests
+dnl
+AC_ARG_WITH(tests, AS_HELP_STRING([--with-tests], [Build NetworkManager tests]))
+AM_CONDITIONAL(WITH_TESTS, test "x$with_tests" = "xyes")
+case $with_tests in
+    yes)
+        with_tests=yes
+        ;;
+    *)
+        with_tests=no
+        ;;
+esac
+
 AC_CONFIG_FILES([
 Makefile
 src/Makefile
 common-gnome/Makefile
 auth-dialog/Makefile
 properties/Makefile
+properties/tests/Makefile
+properties/tests/conf/Makefile
 po/Makefile.in
 ])
 AC_OUTPUT
diff --git a/nm-test-helpers.h b/nm-test-helpers.h
new file mode 100644
index 0000000..840e25f
--- /dev/null
+++ b/nm-test-helpers.h
@@ -0,0 +1,51 @@
+/* NetworkManager -- Network link manager
+ *
+ * Dan Williams <dcbw redhat com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Red Hat, Inc.
+ */
+
+#ifndef NM_TEST_HELPERS_H
+#define NM_TEST_HELPERS_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+static void
+FAIL(const char *test_name, const char *fmt, ...)
+{
+	va_list args;
+	char buf[500];
+
+	snprintf (buf, 500, "FAIL: (%s) %s\n", test_name, fmt);
+
+	va_start (args, fmt);
+	vfprintf (stderr, buf, args);
+	va_end (args);
+	_exit (1);
+}
+
+#define ASSERT(x, test_name, fmt, ...) \
+{ \
+	if (!(x)) { \
+		FAIL (test_name, fmt, ## __VA_ARGS__); \
+	} \
+}
+
+#endif /* NM_TEST_HELPERS_H */
+
diff --git a/properties/Makefile.am b/properties/Makefile.am
index 875d2bd..6044378 100644
--- a/properties/Makefile.am
+++ b/properties/Makefile.am
@@ -1,3 +1,5 @@
+SUBDIRS = . tests
+
 plugindir = $(libdir)/NetworkManager
 plugin_LTLIBRARIES = libnm-openvpn-properties.la
 
@@ -16,7 +18,6 @@ libnm_openvpn_properties_la_CFLAGS =                    \
         $(GLADE_CFLAGS)                                 \
         $(GTK_CFLAGS)                                   \
         $(GCONF_CFLAGS)                                 \
-        $(LIBGNOMEUI_CFLAGS)                            \
         $(NETWORK_MANAGER_CFLAGS)                       \
         $(GNOMEKEYRING_CFLAGS)                          \
         $(DISABLE_DEPRECATED)                           \
@@ -33,7 +34,6 @@ libnm_openvpn_properties_la_LIBADD =    \
         $(GLADE_LIBS)                   \
         $(GTK_LIBS)                     \
         $(GCONF_LIBS)                   \
-        $(LIBGNOMEUI_LIBS)              \
         $(NETWORK_MANAGER_LIBS)         \
         $(top_builddir)/common-gnome/libnm-openvpn-common-gnome.la
 
diff --git a/properties/import-export.c b/properties/import-export.c
index 5e17dea..c99df54 100644
--- a/properties/import-export.c
+++ b/properties/import-export.c
@@ -1,8 +1,6 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /***************************************************************************
  *
- * Copyright (C) 2008 Dan Williams, <dcbw redhat com>
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -17,6 +15,8 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ * Copyright (C) 2008 - 2009 Dan Williams <dcbw redhat com> and Red Hat, Inc.
+ *
  **************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -31,6 +31,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <ctype.h>
+#include <stdio.h>
 
 #include <glib/gi18n-lib.h>
 
@@ -44,19 +45,19 @@
 
 #define CLIENT_TAG "client"
 #define TLS_CLIENT_TAG "tls-client"
-#define DEV_TAG "dev"
-#define PROTO_TAG "proto"
-#define REMOTE_TAG "remote"
+#define DEV_TAG "dev "
+#define PROTO_TAG "proto "
+#define REMOTE_TAG "remote "
 #define CA_TAG "ca"
 #define CERT_TAG "cert"
 #define KEY_TAG "key"
 #define CIPHER_TAG "cipher"
 #define COMP_TAG "comp-lzo"
-#define IFCONFIG_TAG "ifconfig"
+#define IFCONFIG_TAG "ifconfig "
 #define SECRET_TAG "secret"
 #define AUTH_USER_PASS_TAG "auth-user-pass"
 #define TLS_AUTH_TAG "tls-auth"
-#define AUTH_TAG "auth"
+#define AUTH_TAG "auth "
 #define RENEG_SEC_TAG "reneg-sec"
 
 static gboolean
@@ -415,7 +416,136 @@ do_import (const char *path, char **lines, GError **error)
 gboolean
 do_export (const char *path, NMConnection *connection, GError **error)
 {
-	return FALSE;
-}
+	NMSettingConnection *s_con;
+	NMSettingIP4Config *s_ip4;
+	NMSettingVPN *s_vpn;
+	FILE *f;
+	const char *value;
+	const char *gateway = NULL;
+	const char *cipher = NULL;
+	const char *cacert = NULL;
+	const char *connection_type = NULL;
+	const char *user_cert = NULL;
+	const char *private_key = NULL;
+	const char *port = NULL;
+	gboolean success = FALSE;
+	gboolean device_tun = TRUE;
+	gboolean proto_udp = TRUE;
+	gboolean use_lzo = FALSE;
+	gboolean reneg_exists = FALSE;
+	guint32 reneg = 0;
+
+	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	g_assert (s_con);
+
+	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+
+	f = fopen (path, "w");
+	if (!f) {
+		g_set_error (error, 0, 0, "could not open file for writing");
+		return FALSE;
+	}
+
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_REMOTE);
+	if (value && strlen (value))
+		gateway = value;
+	else {
+		g_set_error (error, 0, 0, "connection was incomplete (missing gateway)");
+		goto done;
+	}
+
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_CONNECTION_TYPE);
+	if (value && strlen (value))
+		connection_type = value;
+
+	if (   !strcmp (connection_type, NM_OPENVPN_CONTYPE_TLS)
+	    || !strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD)
+	    || !strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
+		value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_CA);
+		if (value && strlen (value))
+			cacert = value;
+	}
+
+	if (   !strcmp (connection_type, NM_OPENVPN_CONTYPE_TLS)
+	    || !strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
+		value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_CERT);
+		if (value && strlen (value))
+			user_cert = value;
+
+		value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_KEY);
+		if (value && strlen (value))
+			private_key = value;
+	}
+
+	/* Advanced values start */
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_PORT);
+	if (value && strlen (value))
+		port = value;
 
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_RENEG_SECONDS);
+	if (value && strlen (value)) {
+		reneg_exists = TRUE;
+		reneg = strtol (value, NULL, 10);
+	}
+
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_PROTO_TCP);
+	if (value && !strcmp (value, "yes"))
+		proto_udp = FALSE;
+
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_TAP_DEV);
+	if (value && !strcmp (value, "yes"))
+		device_tun = FALSE;
+
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_COMP_LZO);
+	if (value && !strcmp (value, "yes"))
+		use_lzo = TRUE;
+
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_CIPHER);
+	if (value && strlen (value))
+		cipher = value;
+
+	/* Advanced values end */
+
+	fprintf (f, "client\n");
+	fprintf (f, "remote %s %s\n", gateway, port ? port : "");
+
+	if (cacert)
+		fprintf (f, "ca %s\n", cacert);
+	if (user_cert)
+		fprintf (f, "cert %s\n", user_cert);
+	if (private_key)
+		fprintf(f, "key %s\n", private_key);
+
+	if (   !strcmp(connection_type, NM_OPENVPN_CONTYPE_PASSWORD)
+	    || !strcmp(connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS))
+		fprintf (f, "auth-user-pass\n");
+
+	if (reneg_exists)
+		fprintf (f, "reneg-sec %d\n", reneg);
+
+	if (cipher)
+		fprintf (f, "cipher %s\n", cipher);
+
+	if (use_lzo)
+		fprintf (f, "comp-lzo yes\n");
+
+	fprintf (f, "dev %s\n", device_tun ? "tun" : "tap");
+	fprintf (f, "proto %s\n", proto_udp ? "udp" : "tcp");
+
+	/* Add hard-coded stuff */
+	fprintf (f,
+	         "nobind\n"
+	         "auth-nocache\n"
+	         "script-security 2\n"
+	         "persist-key\n"
+	         "persist-tun\n"
+	         "user openvpn\n"
+	         "group openvpn\n");
+	success = TRUE;
+
+done:
+	fclose (f);
+	return success;
+}
 
diff --git a/properties/nm-openvpn.c b/properties/nm-openvpn.c
index be81baf..a33a315 100644
--- a/properties/nm-openvpn.c
+++ b/properties/nm-openvpn.c
@@ -605,7 +605,10 @@ import (NMVpnPluginUiInterface *iface, const char *path, GError **error)
 		goto out;
 	}
 
-	if (strcmp (ext, ".ovpn") && strcmp (ext, ".conf") && strcmp (ext, ".cnf")) {
+	if (   strcmp (ext, ".ovpn")
+	    && strcmp (ext, ".conf")
+	    && strcmp (ext, ".cnf")
+	    && strcmp (ext, ".ovpntest")) {   /* Special extension for testcases */
 		g_set_error (error,
 		             OPENVPN_PLUGIN_UI_ERROR,
 		             OPENVPN_PLUGIN_UI_ERROR_FILE_NOT_OPENVPN,
@@ -616,6 +619,22 @@ import (NMVpnPluginUiInterface *iface, const char *path, GError **error)
 	if (!g_file_get_contents (path, &contents, NULL, error))
 		return NULL;
 
+	if (!g_utf8_validate (contents, -1, NULL)) {
+		char *tmp;
+		GError *conv_error = NULL;
+
+		tmp = g_locale_to_utf8 (contents, -1, NULL, NULL, &conv_error);
+		if (conv_error) {
+			/* ignore the error, we tried at least. */
+			g_error_free (conv_error);
+			g_free (tmp);
+		} else {
+			g_assert (tmp);
+			g_free (contents);
+			contents = tmp;  /* update contents with the UTF-8 safe text */
+		}
+	}
+
 	lines = g_strsplit_set (contents, "\r\n", 0);
 	if (g_strv_length (lines) <= 1) {
 		g_set_error (error,
diff --git a/properties/tests/Makefile.am b/properties/tests/Makefile.am
new file mode 100644
index 0000000..6fb6ab7
--- /dev/null
+++ b/properties/tests/Makefile.am
@@ -0,0 +1,35 @@
+SUBDIRS = conf
+
+INCLUDES = -I${top_srcdir}
+
+noinst_PROGRAMS = test-import-export
+
+test_import_export_SOURCES = \
+	test-import-export.c
+
+test_import_export_CPPFLAGS = \
+	$(GLIB_CFLAGS) \
+	$(GLADE_CFLAGS) \
+	$(GTK_CFLAGS) \
+	$(GCONF_CFLAGS) \
+	$(GNOMEKEYRING_CFLAGS) \
+        $(NETWORK_MANAGER_CFLAGS) \
+	$(DBUS_CFLAGS)
+
+test_import_export_LDADD = \
+	$(GTHREAD_LIBS) \
+	$(GLADE_LIBS) \
+	$(GTK_LIBS) \
+	$(GCONF_LIBS) \
+	$(GNOMEKEYRING_LIBS) \
+	$(DBUS_LIBS) \
+	$(NETWORK_MANAGER_LIBS) \
+	$(top_builddir)/properties/libnm-openvpn-properties.la
+
+if WITH_TESTS
+
+check-local: test-import-export
+	$(abs_builddir)/test-import-export $(abs_srcdir)/conf
+
+endif
+
diff --git a/properties/tests/conf/Makefile.am b/properties/tests/conf/Makefile.am
new file mode 100644
index 0000000..6a0dd98
--- /dev/null
+++ b/properties/tests/conf/Makefile.am
@@ -0,0 +1,6 @@
+EXTRA_DIST = \
+	password.conf \
+	tls.ovpn \
+	iso885915.ovpn
+
+
diff --git a/properties/tests/conf/iso885915.ovpn b/properties/tests/conf/iso885915.ovpn
new file mode 100644
index 0000000..1c27dbd
--- /dev/null
+++ b/properties/tests/conf/iso885915.ovpn
@@ -0,0 +1,14 @@
+# something non utf8: Att äta en ko
+
+client
+dev tun
+proto udp
+topology subnet
+remote test.server.com 443
+nobind
+ca Attätaenko.pem
+auth-user-pass
+auth-nocache
+script-security 2
+
+
diff --git a/properties/tests/conf/password.conf b/properties/tests/conf/password.conf
new file mode 100644
index 0000000..bcf4946
--- /dev/null
+++ b/properties/tests/conf/password.conf
@@ -0,0 +1,29 @@
+client
+dev tun
+
+proto udp
+topology subnet
+
+remote test.server.com 443
+nobind
+persist-key
+persist-tun
+user openvpn
+group openvpn
+
+
+ca cacert.pem
+cipher AES-256-CBC
+reneg-sec 0
+
+auth-user-pass
+auth-nocache
+
+ping 30
+ping-exit 120
+
+# random comment
+
+script-security 2
+
+
diff --git a/properties/tests/conf/tls.ovpn b/properties/tests/conf/tls.ovpn
new file mode 100644
index 0000000..5b33dad
--- /dev/null
+++ b/properties/tests/conf/tls.ovpn
@@ -0,0 +1,19 @@
+remote 173.8.149.245 1194
+resolv-retry infinite
+
+dev tun
+persist-key
+persist-tun
+link-mtu 1400
+proto udp
+nobind
+pull
+tls-client
+
+ca keys/mg8.ca
+cert keys/clee.crt
+key keys/clee.key
+
+comp-lzo
+verb 3
+
diff --git a/properties/tests/test-import-export.c b/properties/tests/test-import-export.c
new file mode 100644
index 0000000..455f08e
--- /dev/null
+++ b/properties/tests/test-import-export.c
@@ -0,0 +1,431 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2009 Dan Williams, <dcbw redhat com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <string.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <locale.h>
+
+#include <nm-utils.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-vpn.h>
+
+#define NM_VPN_API_SUBJECT_TO_CHANGE
+#include <nm-vpn-plugin-ui-interface.h>
+
+#include "nm-test-helpers.h"
+#include "properties/nm-openvpn.h"
+#include "src/nm-openvpn-service.h"
+
+static NMConnection *
+get_basic_connection (const char *detail,
+                      NMVpnPluginUiInterface *plugin,
+                      const char *dir,
+                      const char *filename)
+{
+	NMConnection *connection;
+	GError *error = NULL;
+	char *pcf;
+
+	pcf = g_build_path ("/", dir, filename, NULL);
+	ASSERT (pcf != NULL,
+	        "basic", "failed to create pcf path");
+
+	connection = nm_vpn_plugin_ui_interface_import (plugin, pcf, &error);
+	if (error)
+		FAIL ("basic", "error importing %s: %s", pcf, error->message);
+	ASSERT (connection != NULL,
+	        "basic", "error importing %s: (unknown)", pcf);
+
+	g_free (pcf);
+	return connection;
+}
+
+static void
+test_item (const char *test,
+           NMSettingVPN *s_vpn,
+           const char *item,
+           const char *expected)
+{
+	const char *value;
+
+	ASSERT (s_vpn != NULL, test, "missing 'vpn' setting");
+
+	value = nm_setting_vpn_get_data_item (s_vpn, item);
+	if (expected == NULL) {
+		ASSERT (value == NULL, test, "unexpected '%s' item value (found '%s', expected NULL",
+		        item, value);
+		return;
+	}
+
+	ASSERT (value != NULL, test, "missing '%s' item value", item);
+	ASSERT (strcmp (value, expected) == 0, test,
+	        "unexpected '%s' secret value (found '%s', expected '%s')",
+	        item, value, expected);
+}
+
+static void
+test_secret (const char *test,
+             NMSettingVPN *s_vpn,
+             const char *item,
+             const char *expected)
+{
+	const char *value;
+
+	ASSERT (s_vpn != NULL, test, "missing 'vpn' setting");
+
+	value = nm_setting_vpn_get_secret (s_vpn, item);
+	if (expected == NULL) {
+		ASSERT (value == NULL, test, "unexpected '%s' secret value (found '%s', expected NULL",
+		        item, value);
+		return;
+	}
+
+	ASSERT (value != NULL, test, "missing '%s' secret value", item);
+	ASSERT (strcmp (value, expected) == 0, test,
+	        "unexpected '%s' secret value (found '%s', expected '%s')",
+	        item, value, expected);
+}
+
+static void
+test_password_import (NMVpnPluginUiInterface *plugin, const char *dir)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingIP4Config *s_ip4;
+	NMSettingVPN *s_vpn;
+	const char *expected_id = "password";
+	char *expected_cacert;
+
+	connection = get_basic_connection ("password-import", plugin, dir, "password.conf");
+	ASSERT (connection != NULL, "password-import", "failed to import connection");
+
+	/* Connection setting */
+	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	ASSERT (s_con != NULL,
+	        "password-import", "missing 'connection' setting");
+
+	ASSERT (strcmp (nm_setting_connection_get_id (s_con), expected_id) == 0,
+	        "password-import", "unexpected connection ID");
+
+	ASSERT (nm_setting_connection_get_uuid (s_con) == NULL,
+	        "password-import", "unexpected valid UUID");
+
+	/* IP4 setting */
+	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+	ASSERT (s_ip4 == NULL,
+	        "password-import", "unexpected 'ip4-config' setting");
+
+	/* VPN setting */
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	ASSERT (s_vpn != NULL,
+	        "password-import", "missing 'vpn' setting");
+
+	/* Data items */
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_CONNECTION_TYPE, NM_OPENVPN_CONTYPE_PASSWORD);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_TAP_DEV, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_PROTO_TCP, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_COMP_LZO, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_RENEG_SECONDS, "0");
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_REMOTE, "test.server.com");
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_PORT, "443");
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_CERT, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_KEY, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_STATIC_KEY, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_STATIC_KEY_DIRECTION, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_TA, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_TA_DIR, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_CIPHER, "AES-256-CBC");
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_LOCAL_IP, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_REMOTE_IP, NULL);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_AUTH, NULL);
+
+	expected_cacert = g_strdup_printf ("%s/cacert.pem", dir);
+	test_item ("password-import-data", s_vpn, NM_OPENVPN_KEY_CA, expected_cacert);
+	g_free (expected_cacert);
+
+	/* Secrets */
+	test_secret ("password-import-secrets", s_vpn, NM_OPENVPN_KEY_PASSWORD, NULL);
+	test_secret ("password-import-secrets", s_vpn, NM_OPENVPN_KEY_CERTPASS, NULL);
+
+	g_object_unref (connection);
+}
+
+static void
+save_one_key (const char *key, const char *value, gpointer user_data)
+{
+	GSList **list = user_data;
+
+	*list = g_slist_append (*list, g_strdup (key));
+}
+
+static void
+remove_secrets (NMConnection *connection)
+{
+	NMSettingVPN *s_vpn;
+	GSList *keys = NULL, *iter;
+
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	if (!s_vpn)
+		return;
+
+	nm_setting_vpn_foreach_secret (s_vpn, save_one_key, &keys);
+	for (iter = keys; iter; iter = g_slist_next (iter))
+		nm_setting_vpn_remove_secret (s_vpn, (const char *) iter->data);
+
+	g_slist_foreach (keys, (GFunc) g_free, NULL);
+	g_slist_free (keys);
+}
+
+#define PASSWORD_EXPORTED_NAME "password.ovpntest"
+static void
+test_password_export (NMVpnPluginUiInterface *plugin, const char *dir)
+{
+	NMConnection *connection;
+	NMConnection *reimported;
+	char *path;
+	gboolean success;
+	GError *error = NULL;
+	int ret;
+
+	connection = get_basic_connection ("password-export", plugin, dir, "password.conf");
+	ASSERT (connection != NULL, "password-export", "failed to import connection");
+
+	path = g_build_path ("/", dir, PASSWORD_EXPORTED_NAME, NULL);
+	success = nm_vpn_plugin_ui_interface_export (plugin, path, connection, &error);
+	if (!success) {
+		if (!error)
+			FAIL ("password-export", "export failed with missing error");
+		else
+			FAIL ("password-export", "export failed: %s", error->message);
+	}
+
+	/* Now re-import it and compare the connections to ensure they are the same */
+	reimported = get_basic_connection ("password-export", plugin, dir, PASSWORD_EXPORTED_NAME);
+	ret = unlink (path);
+	ASSERT (connection != NULL, "password-export", "failed to re-import connection");
+
+	/* Clear secrets first, since they don't get exported, and thus would
+	 * make the connection comparison below fail.
+	 */
+	remove_secrets (connection);
+
+	ASSERT (nm_connection_compare (connection, reimported, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+	        "password-export", "original and reimported connection differ");
+
+	g_object_unref (reimported);
+	g_object_unref (connection);
+	g_free (path);
+}
+
+static void
+test_tls_import (NMVpnPluginUiInterface *plugin, const char *dir)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingIP4Config *s_ip4;
+	NMSettingVPN *s_vpn;
+	const char *expected_id = "tls";
+	char *expected_path;
+
+	connection = get_basic_connection ("tls-import", plugin, dir, "tls.ovpn");
+	ASSERT (connection != NULL, "tls-import", "failed to import connection");
+
+	/* Connection setting */
+	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	ASSERT (s_con != NULL,
+	        "tls-import", "missing 'connection' setting");
+
+	ASSERT (strcmp (nm_setting_connection_get_id (s_con), expected_id) == 0,
+	        "tls-import", "unexpected connection ID");
+
+	ASSERT (nm_setting_connection_get_uuid (s_con) == NULL,
+	        "tls-import", "unexpected valid UUID");
+
+	/* IP4 setting */
+	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+	ASSERT (s_ip4 == NULL,
+	        "tls-import", "unexpected 'ip4-config' setting");
+
+	/* VPN setting */
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	ASSERT (s_vpn != NULL,
+	        "tls-import", "missing 'vpn' setting");
+
+	/* Data items */
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_CONNECTION_TYPE, NM_OPENVPN_CONTYPE_TLS);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_TAP_DEV, NULL);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_PROTO_TCP, NULL);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_COMP_LZO, "yes");
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_RENEG_SECONDS, NULL);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_REMOTE, "173.8.149.245");
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_PORT, "1194");
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_STATIC_KEY, NULL);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_STATIC_KEY_DIRECTION, NULL);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_TA, NULL);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_TA_DIR, NULL);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_CIPHER, NULL);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_LOCAL_IP, NULL);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_REMOTE_IP, NULL);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_AUTH, NULL);
+
+	expected_path = g_strdup_printf ("%s/keys/mg8.ca", dir);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_CA, expected_path);
+	g_free (expected_path);
+
+	expected_path = g_strdup_printf ("%s/keys/clee.crt", dir);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_CERT, expected_path);
+	g_free (expected_path);
+
+	expected_path = g_strdup_printf ("%s/keys/clee.key", dir);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_KEY, expected_path);
+	g_free (expected_path);
+
+	/* Secrets */
+	test_secret ("tls-import-secrets", s_vpn, NM_OPENVPN_KEY_PASSWORD, NULL);
+	test_secret ("tls-import-secrets", s_vpn, NM_OPENVPN_KEY_CERTPASS, NULL);
+
+	g_object_unref (connection);
+}
+
+#define TLS_EXPORTED_NAME "tls.ovpntest"
+static void
+test_tls_export (NMVpnPluginUiInterface *plugin, const char *dir)
+{
+	NMConnection *connection;
+	NMConnection *reimported;
+	char *path;
+	gboolean success;
+	GError *error = NULL;
+	int ret;
+
+	connection = get_basic_connection ("tls-export", plugin, dir, "tls.ovpn");
+	ASSERT (connection != NULL, "tls-export", "failed to import connection");
+
+	path = g_build_path ("/", dir, TLS_EXPORTED_NAME, NULL);
+	success = nm_vpn_plugin_ui_interface_export (plugin, path, connection, &error);
+	if (!success) {
+		if (!error)
+			FAIL ("tls-export", "export failed with missing error");
+		else
+			FAIL ("tls-export", "export failed: %s", error->message);
+	}
+
+	/* Now re-import it and compare the connections to ensure they are the same */
+	reimported = get_basic_connection ("tls-export", plugin, dir, TLS_EXPORTED_NAME);
+	ret = unlink (path);
+	ASSERT (connection != NULL, "tls-export", "failed to re-import connection");
+
+	/* Clear secrets first, since they don't get exported, and thus would
+	 * make the connection comparison below fail.
+	 */
+	remove_secrets (connection);
+
+	ASSERT (nm_connection_compare (connection, reimported, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+	        "tls-export", "original and reimported connection differ");
+
+	g_object_unref (reimported);
+	g_object_unref (connection);
+	g_free (path);
+}
+
+static void
+test_non_utf8_import (NMVpnPluginUiInterface *plugin, const char *dir)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingVPN *s_vpn;
+	const char *expected_cacert = "Attätaenko.pem";
+	char *expected_path;
+	const char *charset = NULL;
+
+	/* Change charset to ISO-8859-15 to match iso885915.ovpn */
+	g_get_charset (&charset);
+	setlocale (LC_ALL, "de_DE euro");
+	connection = get_basic_connection ("non-utf8-import", plugin, dir, "iso885915.ovpn");
+	setlocale (LC_ALL, charset);
+
+	ASSERT (connection != NULL, "non-utf8-import", "failed to import connection");
+
+	/* Connection setting */
+	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	ASSERT (s_con != NULL,
+	        "non-utf8-import", "missing 'connection' setting");
+
+	ASSERT (strcmp (nm_setting_connection_get_id (s_con), "iso885915") == 0,
+	        "non-utf8-import", "unexpected connection ID");
+
+	ASSERT (nm_setting_connection_get_uuid (s_con) == NULL,
+	        "non-utf8-import", "unexpected valid UUID");
+
+	/* VPN setting */
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	ASSERT (s_vpn != NULL,
+	        "non-utf8-import", "missing 'vpn' setting");
+
+	expected_path = g_strdup_printf ("%s/%s", dir, expected_cacert);
+	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_CA, expected_path);
+	g_free (expected_path);
+
+	g_object_unref (connection);
+}
+
+int main (int argc, char **argv)
+{
+	GError *error = NULL;
+	DBusGConnection *bus;
+	char *basename;
+	NMVpnPluginUiInterface *plugin = NULL;
+
+	if (argc != 2)
+		FAIL ("args", "usage: %s <conf path>", argv[0]);
+
+	g_type_init ();
+	bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+
+	if (!nm_utils_init (&error))
+		FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
+
+	plugin = nm_vpn_plugin_ui_factory (&error);
+	if (error)
+		FAIL ("plugin-init", "failed to initialize UI plugin: %s", error->message);
+	ASSERT (plugin != NULL,
+	        "plugin-init", "failed to initialize UI plugin");
+
+	/* The tests */
+	test_password_import (plugin, argv[1]);
+	test_password_export (plugin, argv[1]);
+
+	test_tls_import (plugin, argv[1]);
+	test_tls_export (plugin, argv[1]);
+
+	test_non_utf8_import (plugin, argv[1]);
+
+	g_object_unref (plugin);
+
+	basename = g_path_get_basename (argv[0]);
+	fprintf (stdout, "%s: SUCCESS\n", basename);
+	g_free (basename);
+	return 0;
+}
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]