[network-manager-vpnc/NETWORKMANAGER_0_7] import/export: handle NAT Traversal modes better



commit 19c9334aa71c99f6263643e7115af8522ead0a14
Author: Dan Williams <dcbw redhat com>
Date:   Wed Jan 13 12:22:37 2010 -0800

    import/export: handle NAT Traversal modes better
    
    Unfortunately PCF files don't have a way of specifying whether
    to use Cisco-UDP or the newer and more standardized NAT-T.  So
    we'll use a custom NM key for that.  We default to Cisco-UDP
    for compatibility with older versions of nm-vpnc but this allows
    sysadmins to get the right behavior if they are installing
    newer concentrators that use NAT-T.

 properties/nm-vpnc.c                  |   41 +++++++---
 properties/tests/pcf/nat-cisco.pcf    |   38 +++++++++
 properties/tests/pcf/natt.pcf         |   39 +++++++++
 properties/tests/test-import-export.c |  142 ++++++++++++++++++++++++++++++++-
 4 files changed, 246 insertions(+), 14 deletions(-)
---
diff --git a/properties/nm-vpnc.c b/properties/nm-vpnc.c
index 0d084e5..5050ad9 100644
--- a/properties/nm-vpnc.c
+++ b/properties/nm-vpnc.c
@@ -1060,22 +1060,31 @@ import (NMVpnPluginUiInterface *iface, const char *path, GError **error)
 			nm_setting_vpn_add_data_item (s_vpn, NM_VPNC_KEY_SINGLE_DES, "yes");
 	}
 
-	/* Default is enabled, only disabled if explicit EnableNat=0 exists */
+	/* Disable all NAT Traversal if explicit EnableNat=0 exists, otherwise
+	 * default to NAT-T which is newer and standardized.  If EnableNat=1, then
+	 * use Cisco-UDP like always; but if the key "X-NM-Use-NAT-T" is set, then
+	 * use NAT-T.
+	 */
+	nm_setting_vpn_add_data_item (s_vpn,
+	                              NM_VPNC_KEY_NAT_TRAVERSAL_MODE,
+	                              NM_VPNC_NATT_MODE_CISCO);
+
 	if (pcf_file_lookup_bool (pcf, "main", "EnableNat", &bool_value)) {
-		if (!bool_value) {
+		if (bool_value) {
+			bool_value = FALSE;
+			if (   pcf_file_lookup_bool (pcf, "main", "X-NM-Use-NAT-T", &bool_value)
+			    && bool_value) {
+				nm_setting_vpn_add_data_item (s_vpn,
+				                              NM_VPNC_KEY_NAT_TRAVERSAL_MODE,
+				                              NM_VPNC_NATT_MODE_NATT);
+			}
+		} else {
 			nm_setting_vpn_add_data_item (s_vpn,
 			                              NM_VPNC_KEY_NAT_TRAVERSAL_MODE,
 			                              NM_VPNC_NATT_MODE_NONE);
 		}
 	}
 
-	/* Default to Cisco UDP */
-	if (!nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_NAT_TRAVERSAL_MODE)) {
-		nm_setting_vpn_add_data_item (s_vpn,
-		                              NM_VPNC_KEY_NAT_TRAVERSAL_MODE,
-		                              NM_VPNC_NATT_MODE_CISCO);
-	}
-
 	if (pcf_file_lookup_int (pcf, "main", "PeerTimeout", &val)) {
 		if ((val == 0) || ((val >= 10) && (val <= 86400))) {
 			char *tmp = g_strdup_printf ("%d", (gint) val);
@@ -1144,6 +1153,7 @@ export (NMVpnPluginUiInterface *iface,
 	gboolean success = FALSE;
 	guint32 routes_count = 0;
 	gboolean save_password = FALSE;
+	gboolean use_natt = FALSE;
 
 	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
 	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
@@ -1185,8 +1195,15 @@ export (NMVpnPluginUiInterface *iface,
 		singledes = TRUE;
 
 	value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
-	if (value && strlen (value) && strcmp (value, NM_VPNC_NATT_MODE_NONE))
-		enablenat = TRUE;
+	if (value && strlen (value)) {
+		if (!strcmp (value, NM_VPNC_NATT_MODE_CISCO)) {
+			enablenat = TRUE;
+			use_natt = FALSE;
+		} else if (!strcmp (value, NM_VPNC_NATT_MODE_NATT)) {
+			enablenat = TRUE;
+			use_natt = TRUE;
+		}
+	}
 
 	value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_DPD_IDLE_TIMEOUT);
 	if (value && strlen (value))
@@ -1264,6 +1281,7 @@ export (NMVpnPluginUiInterface *iface,
 		 "EnableSplitDNS=1\n"
 		 "SingleDES=%s\n"
 		 "SPPhonebook=\n"
+		 "X-NM-Use-NAT-T=%s\n"
 		 "%s\n",
 		 /* Description */   nm_setting_connection_get_id (s_con),
 		 /* Host */          gateway,
@@ -1275,6 +1293,7 @@ export (NMVpnPluginUiInterface *iface,
 		 /* NTDomain */      domain != NULL ? domain : "",
 		 /* PeerTimeout */   peertimeout != NULL ? peertimeout : "0",
 		 /* SingleDES */     singledes ? "1" : "0",
+		 /* X-NM-Use-NAT-T */ use_natt ? "1" : "0",
 		 /* X-NM-Routes */   (routes && routes->str) ? routes->str : "");
 
 	success = TRUE;
diff --git a/properties/tests/pcf/nat-cisco.pcf b/properties/tests/pcf/nat-cisco.pcf
new file mode 100644
index 0000000..d875a6e
--- /dev/null
+++ b/properties/tests/pcf/nat-cisco.pcf
@@ -0,0 +1,38 @@
+[main]
+Description=NAT-Cisco
+!Host=10.20.30.40
+!AuthType=1
+!GroupName=blahblah
+!GroupPwd=my-group-password
+!enc_GroupPwd=
+EnableISPConnect=0
+ISPConnectType=0
+ISPConnect=
+ISPCommand=
+Username=bsmith
+SaveUserPassword=1
+UserPassword=my-user-password
+enc_UserPassword=
+!NTDomain=COMPANY
+!EnableBackup=0
+!BackupServer=
+!EnableMSLogon=1
+!MSLogonType=0
+EnableNat=1
+!TunnelingMode=0
+!TcpTunnelingPort=10000
+CertStore=0
+CertName=
+CertPath=
+CertSubjectName=
+CertSerialHash=00000000000000000000000000000000
+SendCertChain=0
+VerifyCertDN=
+DHGroup=2
+ForceKeepAlives=1
+PeerTimeout=90
+!EnableLocalLAN=1
+!EnableSplitDNS=1
+ISPPhonebook=
+X-NM-Routes=10.0.0.0/8 172.16.0.0/16
+
diff --git a/properties/tests/pcf/natt.pcf b/properties/tests/pcf/natt.pcf
new file mode 100644
index 0000000..40b6196
--- /dev/null
+++ b/properties/tests/pcf/natt.pcf
@@ -0,0 +1,39 @@
+[main]
+Description=NAT-T
+!Host=10.20.30.40
+!AuthType=1
+!GroupName=blahblah
+!GroupPwd=my-group-password
+!enc_GroupPwd=
+EnableISPConnect=0
+ISPConnectType=0
+ISPConnect=
+ISPCommand=
+Username=bsmith
+SaveUserPassword=1
+UserPassword=my-user-password
+enc_UserPassword=
+!NTDomain=COMPANY
+!EnableBackup=0
+!BackupServer=
+!EnableMSLogon=1
+!MSLogonType=0
+EnableNat=1
+!TunnelingMode=0
+!TcpTunnelingPort=10000
+CertStore=0
+CertName=
+CertPath=
+CertSubjectName=
+CertSerialHash=00000000000000000000000000000000
+SendCertChain=0
+VerifyCertDN=
+DHGroup=2
+ForceKeepAlives=1
+PeerTimeout=90
+!EnableLocalLAN=1
+!EnableSplitDNS=1
+ISPPhonebook=
+X-NM-Routes=10.0.0.0/8 172.16.0.0/16
+X-NM-Use-NAT-T=1
+
diff --git a/properties/tests/test-import-export.c b/properties/tests/test-import-export.c
index fc39f6d..ef2ce5a 100644
--- a/properties/tests/test-import-export.c
+++ b/properties/tests/test-import-export.c
@@ -260,7 +260,7 @@ remove_secrets (NMConnection *connection)
 	g_slist_free (keys);
 }
 
-#define EXPORTED_NAME "basic-export-test.pcf"
+#define BASIC_EXPORTED_NAME "basic-export-test.pcf"
 static void
 test_basic_export (NMVpnPluginUiInterface *plugin, const char *dir)
 {
@@ -274,7 +274,7 @@ test_basic_export (NMVpnPluginUiInterface *plugin, const char *dir)
 	connection = get_basic_connection ("basic-export", plugin, dir, "basic.pcf");
 	ASSERT (connection != NULL, "basic-export", "failed to import connection");
 
-	path = g_build_path ("/", dir, EXPORTED_NAME, NULL);
+	path = g_build_path ("/", dir, BASIC_EXPORTED_NAME, NULL);
 	success = nm_vpn_plugin_ui_interface_export (plugin, path, connection, &error);
 	if (!success) {
 		if (!error)
@@ -284,7 +284,7 @@ test_basic_export (NMVpnPluginUiInterface *plugin, const char *dir)
 	}
 
 	/* Now re-import it and compare the connections to ensure they are the same */
-	reimported = get_basic_connection ("basic-export", plugin, dir, EXPORTED_NAME);
+	reimported = get_basic_connection ("basic-export", plugin, dir, BASIC_EXPORTED_NAME);
 	ret = unlink (path);
 	ASSERT (connection != NULL, "basic-export", "failed to re-import connection");
 
@@ -301,6 +301,52 @@ test_basic_export (NMVpnPluginUiInterface *plugin, const char *dir)
 	g_free (path);
 }
 
+#define NAT_EXPORTED_NAME "nat-export-test.pcf"
+static void
+test_nat_export (NMVpnPluginUiInterface *plugin, const char *dir, const char *nat_mode)
+{
+	NMConnection *connection;
+	NMSettingVPN *s_vpn;
+	NMConnection *reimported;
+	char *path;
+	gboolean success;
+	GError *error = NULL;
+	int ret;
+
+	connection = get_basic_connection ("nat-export", plugin, dir, "basic.pcf");
+	ASSERT (connection != NULL, "nat-export", "failed to import connection");
+
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	ASSERT (s_vpn != NULL, "nat-export", "imported connection had no VPN setting");
+
+	nm_setting_vpn_add_data_item (s_vpn, NM_VPNC_KEY_NAT_TRAVERSAL_MODE, nat_mode);
+
+	path = g_build_path ("/", dir, NAT_EXPORTED_NAME, NULL);
+	success = nm_vpn_plugin_ui_interface_export (plugin, path, connection, &error);
+	if (!success) {
+		if (!error)
+			FAIL ("nat-export", "export failed with missing error");
+		else
+			FAIL ("nat-export", "export failed: %s", error->message);
+	}
+
+	/* Now re-import it and compare the connections to ensure they are the same */
+	reimported = get_basic_connection ("nat-export", plugin, dir, NAT_EXPORTED_NAME);
+	ret = unlink (path);
+	ASSERT (connection != NULL, "nat-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,
+	        "nat-export", "original and reimported connection differ");
+
+	g_object_unref (reimported);
+	g_object_unref (connection);
+	g_free (path);
+}
 
 static void
 test_everything_via_vpn (NMVpnPluginUiInterface *plugin, const char *dir)
@@ -388,6 +434,92 @@ test_no_natt (NMVpnPluginUiInterface *plugin, const char *dir)
 }
 
 static void
+test_nat_cisco (NMVpnPluginUiInterface *plugin, const char *dir)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingVPN *s_vpn;
+	GError *error = NULL;
+	char *pcf;
+	const char *expected_id = "NAT-Cisco";
+	const char *value;
+
+	pcf = g_build_path ("/", dir, "nat-cisco.pcf", NULL);
+	ASSERT (pcf != NULL,
+	        "nat-cisco", "failed to create pcf path");
+
+	connection = nm_vpn_plugin_ui_interface_import (plugin, pcf, &error);
+	if (error)
+		FAIL ("nat-cisco", "error importing %s: %s", pcf, error->message);
+	ASSERT (connection != NULL,
+	        "nat-cisco", "error importing %s: (unknown)", pcf);
+
+	/* Connection setting */
+	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	ASSERT (s_con != NULL,
+	        "nat-cisco", "missing 'connection' setting");
+
+	ASSERT (strcmp (nm_setting_connection_get_id (s_con), expected_id) == 0,
+	        "nat-cisco", "unexpected connection ID");
+
+	/* VPN setting */
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	ASSERT (s_vpn != NULL,
+	        "nat-cisco", "missing 'vpn' setting");
+
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
+	ASSERT (value != NULL,
+	        "nat-cisco", "unexpected missing value for item %s", NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
+	ASSERT (strcmp (value, NM_VPNC_NATT_MODE_CISCO) == 0,
+	        "nat-cisco", "unexpected value for item %s", NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
+
+	g_free (pcf);
+}
+
+static void
+test_nat_natt (NMVpnPluginUiInterface *plugin, const char *dir)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingVPN *s_vpn;
+	GError *error = NULL;
+	char *pcf;
+	const char *expected_id = "NAT-T";
+	const char *value;
+
+	pcf = g_build_path ("/", dir, "natt.pcf", NULL);
+	ASSERT (pcf != NULL,
+	        "natt", "failed to create pcf path");
+
+	connection = nm_vpn_plugin_ui_interface_import (plugin, pcf, &error);
+	if (error)
+		FAIL ("natt", "error importing %s: %s", pcf, error->message);
+	ASSERT (connection != NULL,
+	        "natt", "error importing %s: (unknown)", pcf);
+
+	/* Connection setting */
+	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	ASSERT (s_con != NULL,
+	        "natt", "missing 'connection' setting");
+
+	ASSERT (strcmp (nm_setting_connection_get_id (s_con), expected_id) == 0,
+	        "natt", "unexpected connection ID");
+
+	/* VPN setting */
+	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	ASSERT (s_vpn != NULL,
+	        "natt", "missing 'vpn' setting");
+
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
+	ASSERT (value != NULL,
+	        "natt", "unexpected missing value for item %s", NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
+	ASSERT (strcmp (value, NM_VPNC_NATT_MODE_NATT) == 0,
+	        "natt", "unexpected value for item %s", NM_VPNC_KEY_NAT_TRAVERSAL_MODE);
+
+	g_free (pcf);
+}
+
+static void
 test_always_ask (NMVpnPluginUiInterface *plugin, const char *dir)
 {
 	NMConnection *connection;
@@ -490,10 +622,14 @@ int main (int argc, char **argv)
 	test_basic_import (plugin, argv[1]);
 	test_everything_via_vpn (plugin, argv[1]);
 	test_no_natt (plugin, argv[1]);
+	test_nat_cisco (plugin, argv[1]);
+	test_nat_natt (plugin, argv[1]);
 	test_always_ask (plugin, argv[1]);
 	test_non_utf8_import (plugin, argv[1]);
 
 	test_basic_export (plugin, argv[1]);
+	test_nat_export (plugin, argv[1], NM_VPNC_NATT_MODE_CISCO);
+	test_nat_export (plugin, argv[1], NM_VPNC_NATT_MODE_NATT);
 
 	g_object_unref (plugin);
 



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