[Openswan dev] [PATCH] Openswan and OS X with NAT-T

Peter Van der Beken peterv at propagandism.org
Mon Sep 26 16:11:53 CEST 2005


Hi,

Please find included a patch to Openswan 2.3.1 to make it interoperate 
with OS X using NAT-T. As you probably know, Apple implemented a draft 
version of the NAT-T RFC, only implemented it partially and with an 
incorrect Vendor ID. With this patch I was able to connect to Openswan 
2.3.1 from behind a NAT, YMMV.
Note that I'm not advocating to integrate this into the official 
distribution (the fact that Apple uses values that conflict with another 
RFC makes it quite ugly IMHO). I just want to throw it out there, it 
might be useful for other people. If there's interest I could look into 
porting it to 2.4.x.

Thanks,

Peter
-------------- next part --------------
diff -ru openswan-2.3.1.orig/include/ietf_constants.h openswan-2.3.1/include/ietf_constants.h
--- openswan-2.3.1.orig/include/ietf_constants.h	2005-03-21 04:54:42.000000000 +0100
+++ openswan-2.3.1/include/ietf_constants.h	2005-09-26 13:59:16.000000000 +0200
@@ -270,6 +270,8 @@
 #define ISAKMP_NEXT_D          12	/* Delete */
 #define ISAKMP_NEXT_VID        13	/* Vendor ID */
 #define ISAKMP_NEXT_ATTR       14       /* Mode config Attribute */
+#define ISAKMP_NEXT_NATD_BADDRAFTS   15 /* NAT-Traversal: NAT-D (bad drafts) */
+                                        /* !!! Conflicts with RFC 3547 */
 #define ISAKMP_NEXT_NATD_RFC   20       /* NAT-Traversal: NAT-D (rfc) */
 #define ISAKMP_NEXT_NATOA_RFC  21       /* NAT-Traversal: NAT-OA (rfc) */
 #define ISAKMP_NEXT_ROOF       22	/* roof on payload types */
diff -ru openswan-2.3.1.orig/lib/libopenswan/constants.c openswan-2.3.1/lib/libopenswan/constants.c
--- openswan-2.3.1.orig/lib/libopenswan/constants.c	2005-01-23 19:53:35.000000000 +0100
+++ openswan-2.3.1/lib/libopenswan/constants.c	2005-09-26 14:00:35.000000000 +0200
@@ -123,7 +123,7 @@
 	"ISAKMP_NEXT_D",
 	"ISAKMP_NEXT_VID",
 	"ISAKMP_NEXT_MODECFG",  /* 14 */
-	"ISAKMP_NEXT_15",
+	"ISAKMP_NEXT_NAT-D",
 	"ISAKMP_NEXT_16",
 	"ISAKMP_NEXT_17",
 	"ISAKMP_NEXT_18",
@@ -916,9 +916,9 @@
 const char *const natt_type_bitnames[] = {
   "draft-ietf-ipsec-nat-t-ike-00/01",    /* 0 */
   "draft-ietf-ipsec-nat-t-ike-02/03",
+  "draft-ietf-ipsec-nat-t-ike (OS X)",
   "RFC 3947 (NAT-Traversal)",
-  "3",                                   /* 3 */
-  "4",   "5",   "6",   "7", 
+  "4",   "5",   "6",   "7",              /* 4 */ 
   "8",   "9",   "10",  "11",
   "12",  "13",  "14",  "15",
   "16",  "17",  "18",  "19", 
diff -ru openswan-2.3.1.orig/programs/pluto/demux.c openswan-2.3.1/programs/pluto/demux.c
--- openswan-2.3.1.orig/programs/pluto/demux.c	2005-03-21 05:01:52.000000000 +0100
+++ openswan-2.3.1/programs/pluto/demux.c	2005-09-26 14:15:06.000000000 +0200
@@ -2029,6 +2029,16 @@
 		    np = ISAKMP_NEXT_NATOA_RFC;  /* NAT-OA relocated */
 		    sd = payload_descs[np];
 		    break;
+		case ISAKMP_NEXT_NATD_BADDRAFTS:
+			if (st && (st->hidden_variables.st_nat_traversal & NAT_T_WITH_NATD_BADDRAFT_VALUES)) {
+			    /*
+			     * Only accept this value if we're in compatibility mode with
+			     * the bad drafts of the RFC
+			     */
+		        np = ISAKMP_NEXT_NATD_RFC;  /* NAT-D relocated */
+		        sd = payload_descs[np];
+		        break;
+		    }
 #endif
 		default:
 		    loglog(RC_LOG_SERIOUS, "%smessage ignored because it contains an unknown or"
diff -ru openswan-2.3.1.orig/programs/pluto/nat_traversal.c openswan-2.3.1/programs/pluto/nat_traversal.c
--- openswan-2.3.1.orig/programs/pluto/nat_traversal.c	2005-03-21 00:16:16.000000000 +0100
+++ openswan-2.3.1/programs/pluto/nat_traversal.c	2005-09-26 14:16:08.000000000 +0200
@@ -211,6 +211,9 @@
 		case VID_NATT_IETF_03:
 			return LELEM(NAT_TRAVERSAL_IETF_02_03);
 			break;
+		case VID_NATT_DRAFT_IETF_IPSEC_NAT_T_IKE:
+			return LELEM(NAT_TRAVERSAL_OSX);
+			break;
 		case VID_NATT_RFC:
 			return LELEM(NAT_TRAVERSAL_RFC);
 			break;
@@ -324,7 +327,9 @@
 	DBG(DBG_EMITTING, DBG_log("sending NATD payloads"));
 
 	nat_np = (st->hidden_variables.st_nat_traversal & NAT_T_WITH_RFC_VALUES
-	      ? ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS);
+	      ? ISAKMP_NEXT_NATD_RFC
+	      : (st->hidden_variables.st_nat_traversal & NAT_T_WITH_NATD_BADDRAFT_VALUES
+	      ? ISAKMP_NEXT_NATD_BADDRAFTS : ISAKMP_NEXT_NATD_DRAFTS));
 	if (!out_modify_previous_np(nat_np, outs)) {
 		return FALSE;
 	}
@@ -541,9 +546,12 @@
 	case LELEM(NAT_TRAVERSAL_IETF_02_03):
 	    mth = natt_type_bitnames[1];
 	    break;
-	case LELEM(NAT_TRAVERSAL_RFC):
+	case LELEM(NAT_TRAVERSAL_OSX):
 	    mth = natt_type_bitnames[2];
 	    break;
+	case LELEM(NAT_TRAVERSAL_RFC):
+	    mth = natt_type_bitnames[3];
+	    break;
 	}
 	switch (nt & NAT_T_DETECTED) {
 		case 0:
diff -ru openswan-2.3.1.orig/programs/pluto/nat_traversal.h openswan-2.3.1/programs/pluto/nat_traversal.h
--- openswan-2.3.1.orig/programs/pluto/nat_traversal.h	2005-01-23 20:17:25.000000000 +0100
+++ openswan-2.3.1/programs/pluto/nat_traversal.h	2005-09-26 14:12:38.000000000 +0200
@@ -21,7 +21,8 @@
 
 #define NAT_TRAVERSAL_IETF_00_01     1
 #define NAT_TRAVERSAL_IETF_02_03     2
-#define NAT_TRAVERSAL_RFC            3
+#define NAT_TRAVERSAL_OSX            3
+#define NAT_TRAVERSAL_RFC            4
 
 #define NAT_TRAVERSAL_NAT_BHND_ME    30
 #define NAT_TRAVERSAL_NAT_BHND_PEER  31
@@ -33,7 +34,7 @@
  */
 #define NAT_T_WITH_NATD \
 	( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
-	LELEM(NAT_TRAVERSAL_RFC) )
+	LELEM(NAT_TRAVERSAL_OSX) | LELEM(NAT_TRAVERSAL_RFC) )
 /**
  * NAT-Traversal methods which need NAT-OA
  */
@@ -45,12 +46,20 @@
  */
 #define NAT_T_WITH_KA \
 	( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
-	LELEM(NAT_TRAVERSAL_RFC) )
+	LELEM(NAT_TRAVERSAL_OSX) | LELEM(NAT_TRAVERSAL_RFC) )
 /**
  * NAT-Traversal methods which use floating port
  */
 #define NAT_T_WITH_PORT_FLOATING \
-	( LELEM(NAT_TRAVERSAL_IETF_02_03) | LELEM(NAT_TRAVERSAL_RFC) )
+	( LELEM(NAT_TRAVERSAL_IETF_02_03) | LELEM(NAT_TRAVERSAL_OSX) | \
+	LELEM(NAT_TRAVERSAL_RFC) )
+
+/**
+ * NAT-Traversal methods which use a value for NAT-D from draft versions of the
+ * RFC which conflict with values from RFC 3547
+ */
+#define NAT_T_WITH_NATD_BADDRAFT_VALUES \
+	( LELEM(NAT_TRAVERSAL_OSX) )
 
 /**
  * NAT-Traversal methods which use officials values (RFC)
@@ -59,6 +68,12 @@
 	( LELEM(NAT_TRAVERSAL_RFC) )
 
 /**
+ * NAT-Traversal methods which use officials values (RFC) for encapsulation
+ */
+#define NAT_T_WITH_ENCAPSULATION_RFC_VALUES \
+	( LELEM(NAT_TRAVERSAL_OSX) | LELEM(NAT_TRAVERSAL_RFC) )
+
+/**
  * NAT-Traversal detected
  */
 #define NAT_T_DETECTED \
@@ -137,11 +152,11 @@
 #define NAT_T_ENCAPSULATION_MODE(st,nat_t_policy) ( \
 	((st)->hidden_variables.st_nat_traversal & NAT_T_DETECTED) \
 		? ( ((nat_t_policy) & POLICY_TUNNEL) \
-			? ( ((st)->hidden_variables.st_nat_traversal & NAT_T_WITH_RFC_VALUES) \
+			? ( ((st)->hidden_variables.st_nat_traversal & NAT_T_WITH_ENCAPSULATION_RFC_VALUES) \
 				? (ENCAPSULATION_MODE_UDP_TUNNEL_RFC) \
 				: (ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS) \
 			  ) \
-			: ( ((st)->hidden_variables.st_nat_traversal & NAT_T_WITH_RFC_VALUES) \
+			: ( ((st)->hidden_variables.st_nat_traversal & NAT_T_WITH_ENCAPSULATION_RFC_VALUES) \
 				? (ENCAPSULATION_MODE_UDP_TRANSPORT_RFC) \
 				: (ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS) \
 			  ) \
diff -ru openswan-2.3.1.orig/programs/pluto/spdb_struct.c openswan-2.3.1/programs/pluto/spdb_struct.c
--- openswan-2.3.1.orig/programs/pluto/spdb_struct.c	2005-02-15 02:54:20.000000000 +0100
+++ openswan-2.3.1/programs/pluto/spdb_struct.c	2005-09-26 02:41:40.000000000 +0200
@@ -1458,7 +1458,7 @@
 #endif
 
 			case ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS:
-				if (st->hidden_variables.st_nat_traversal & NAT_T_WITH_RFC_VALUES) {
+				if (st->hidden_variables.st_nat_traversal & NAT_T_WITH_ENCAPSULATION_RFC_VALUES) {
 					loglog(RC_LOG_SERIOUS,
 						"%s must only be used with old IETF drafts",
 						enum_name(&enc_mode_names, val));
@@ -1487,7 +1487,7 @@
 
 			case ENCAPSULATION_MODE_UDP_TUNNEL_RFC:
 				if ((st->hidden_variables.st_nat_traversal & NAT_T_DETECTED) &&
-					(st->hidden_variables.st_nat_traversal & NAT_T_WITH_RFC_VALUES)) {
+					(st->hidden_variables.st_nat_traversal & NAT_T_WITH_ENCAPSULATION_RFC_VALUES)) {
 					attrs->encapsulation = val - ENCAPSULATION_MODE_UDP_TUNNEL_RFC + ENCAPSULATION_MODE_TUNNEL;
 				}
 				else if (st->hidden_variables.st_nat_traversal & NAT_T_DETECTED) {
diff -ru openswan-2.3.1.orig/programs/pluto/vendor.c openswan-2.3.1/programs/pluto/vendor.c
--- openswan-2.3.1.orig/programs/pluto/vendor.c	2005-09-26 01:13:27.000000000 +0200
+++ openswan-2.3.1/programs/pluto/vendor.c	2005-09-26 01:13:12.000000000 +0200
@@ -378,6 +378,7 @@
 		case VID_NATT_IETF_02:
 		case VID_NATT_IETF_02_N:
 		case VID_NATT_IETF_03:
+		case VID_NATT_DRAFT_IETF_IPSEC_NAT_T_IKE:
 		case VID_NATT_RFC:
  		        vid_usefull = 1;
 			if(!nat_traversal_support_port_floating) {


More information about the Dev mailing list