rpms/ipsec-tools/devel ipsec-tools-0.6.5-mls.patch, NONE, 1.1 ipsec-tools.spec, 1.23, 1.24

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Tue Apr 18 20:15:45 UTC 2006


Author: dwalsh

Update of /cvs/dist/rpms/ipsec-tools/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv31628

Modified Files:
	ipsec-tools.spec 
Added Files:
	ipsec-tools-0.6.5-mls.patch 
Log Message:
* Tue Apr 18 2006 Dan Walsh <dwalsh at redhat.com> - 0.6.4-2
- Add MLS Patch to allow use of labeled networks
- Patch provided by Joy Latten <latten at austin.ibm.com>


ipsec-tools-0.6.5-mls.patch:
 ipsec-tools-0.6.5.p1/configure.ac              |   35 +++++
 ipsec-tools-0.6.5.p1/src/libipsec/pfkey.c      |    3 
 ipsec-tools-0.6.5.p1/src/libipsec/pfkey_dump.c |   37 ++++++
 ipsec-tools-0.6.5.p1/src/setkey/parse.y        |   77 +++++++++++-
 ipsec-tools-0.6.5.p1/src/setkey/setkey.8       |   45 +++++++
 ipsec-tools-0.6.5.p1/src/setkey/token.l        |    1 
 ipsec-tools-0.6.5.p2/src/libipsec/libpfkey.h   |   12 +
 ipsec-tools-0.6.5.p2/src/libipsec/pfkey.c      |   96 ++++++++++++++-
 ipsec-tools-0.6.5.p2/src/racoon/Makefile.am    |    8 -
 ipsec-tools-0.6.5.p2/src/racoon/backupsa.c     |    3 
 ipsec-tools-0.6.5.p2/src/racoon/cftoken.l      |    1 
 ipsec-tools-0.6.5.p2/src/racoon/ipsec_doi.c    |   38 ++++++
 ipsec-tools-0.6.5.p2/src/racoon/ipsec_doi.h    |    4 
 ipsec-tools-0.6.5.p2/src/racoon/isakmp.c       |    2 
 ipsec-tools-0.6.5.p2/src/racoon/isakmp_quick.c |   13 ++
 ipsec-tools-0.6.5.p2/src/racoon/pfkey.c        |  146 +++++++++++++++++++++++-
 ipsec-tools-0.6.5.p2/src/racoon/policy.c       |   29 ++++
 ipsec-tools-0.6.5.p2/src/racoon/policy.h       |   16 ++
 ipsec-tools-0.6.5.p2/src/racoon/proposal.c     |   77 ++++++++++++
 ipsec-tools-0.6.5.p2/src/racoon/proposal.h     |    4 
 ipsec-tools-0.6.5.p2/src/racoon/remoteconf.c   |    1 
 ipsec-tools-0.6.5.p2/src/racoon/security.c     |  152 +++++++++++++++++++++++++
 22 files changed, 765 insertions(+), 35 deletions(-)

--- NEW FILE ipsec-tools-0.6.5-mls.patch ---
diff -urpN ipsec-tools-0.6.5.orig/configure.ac ipsec-tools-0.6.5.p1/configure.ac
--- ipsec-tools-0.6.5.orig/configure.ac	2006-03-02 12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/configure.ac	2006-03-02 14:43:59.000000000 -0600
@@ -588,6 +588,41 @@ AC_CHECK_TYPE([ipsec_policy_t], 
 	      	#include <netinet6/ipsec.h>
 	      ])
 
+# Check if kernel support is available for Security Context, defaults to no.
+kernel_secctx="no"
+
+AC_MSG_CHECKING(kernel Security Context support)
+case $host_os in
+linux*)
+# Linux kernel Security Context check
+AC_EGREP_CPP(yes,
+[#include <linux/pfkeyv2.h>
+#ifdef SADB_X_EXT_SEC_CTX
+yes
+#endif
+], [kernel_secctx="yes"])
+	;;
+esac
+AC_MSG_RESULT($kernel_secctx)
+
+AC_MSG_CHECKING(whether to support Security Context)
+AC_ARG_ENABLE(security-context,
+	[  --enable-security-context    enable Security Context(yes/no/kernel)],
+	[if test "$enable_security-context" = "kernel"; then
+		enable_security_context=$kernel_secctx; fi],
+	[enable_security_context=$kernel_secctx])
+AC_MSG_RESULT($enable_security_context)
+
+if test "$enable_security_context" = "yes"; then
+	if test "$kernel_secctx" = "no" ; then
+		AC_MSG_ERROR([Security Context requested, but no kernel support! Aborting.])
+	else
+		AC_DEFINE([HAVE_SECCTX], [], [Enable Security Context])
+		SECCTX_OBJS="security.o"
+		AC_SUBST(SECCTX_OBJS)
+	fi
+fi
+
 CFLAGS="$CFLAGS $CFLAGS_ADD"
 CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD"
 
diff -urpN ipsec-tools-0.6.5.orig/src/libipsec/pfkey.c ipsec-tools-0.6.5.p1/src/libipsec/pfkey.c
--- ipsec-tools-0.6.5.orig/src/libipsec/pfkey.c	2006-03-02 12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/src/libipsec/pfkey.c	2006-03-02 15:03:10.000000000 -0600
@@ -1969,6 +1969,9 @@ pfkey_align(msg, mhp)
 #ifdef SADB_X_EXT_PACKET
 		case SADB_X_EXT_PACKET:
 #endif
+#ifdef SADB_X_EXT_SEC_CTX
+		case SADB_X_EXT_SEC_CTX:
+#endif
 
 			mhp[ext->sadb_ext_type] = (void *)ext;
 			break;
diff -urpN ipsec-tools-0.6.5.orig/src/libipsec/pfkey_dump.c ipsec-tools-0.6.5.p1/src/libipsec/pfkey_dump.c
--- ipsec-tools-0.6.5.orig/src/libipsec/pfkey_dump.c	2006-03-02 12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/src/libipsec/pfkey_dump.c	2006-03-02 14:45:44.000000000 -0600
@@ -243,6 +243,9 @@ pfkey_sadump1(m, withports)
 	struct sadb_ident *m_sid, *m_did;
 	struct sadb_sens *m_sens;
 #endif
+#ifdef SADB_X_EXT_SEC_CTX
+	struct sadb_x_sec_ctx *m_sec_ctx;
+#endif
 #ifdef SADB_X_EXT_NAT_T_TYPE
 	struct sadb_x_nat_t_type *natt_type;
 	struct sadb_x_nat_t_port *natt_sport, *natt_dport;
@@ -279,6 +282,9 @@ pfkey_sadump1(m, withports)
 	m_did = (void *)mhp[SADB_EXT_IDENTITY_DST];
 	m_sens = (void *)mhp[SADB_EXT_SENSITIVITY];
 #endif
+#ifdef SADB_X_EXT_SEC_CTX
+	m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+#endif
 #ifdef SADB_X_EXT_NAT_T_TYPE
 	natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE];
 	natt_sport = (void *)mhp[SADB_X_EXT_NAT_T_SPORT];
@@ -433,6 +439,19 @@ pfkey_sadump1(m, withports)
 			0 : m_lfts->sadb_lifetime_allocations));
 	}
 
+#ifdef SADB_X_EXT_SEC_CTX
+	if (m_sec_ctx != NULL) {
+		printf("\tsecurity context doi: %u\n",
+					m_sec_ctx->sadb_x_ctx_doi);
+		printf("\tsecurity context algorithm: %u\n",
+					m_sec_ctx->sadb_x_ctx_alg);
+		printf("\tsecurity context length: %u\n",
+					m_sec_ctx->sadb_x_ctx_len);
+		printf("\tsecurity context: %s\n",
+			(char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx));
+	}
+#endif
+
 	printf("\tsadb_seq=%lu pid=%lu ",
 		(u_long)m->sadb_msg_seq,
 		(u_long)m->sadb_msg_pid);
@@ -470,6 +489,9 @@ pfkey_spdump1(m, withports)
 #endif
 	struct sadb_x_policy *m_xpl;
 	struct sadb_lifetime *m_lftc = NULL, *m_lfth = NULL;
+#ifdef SADB_X_EXT_SEC_CTX
+	struct sadb_x_sec_ctx *m_sec_ctx;
+#endif
 	struct sockaddr *sa;
 	u_int16_t sport = 0, dport = 0;
 
@@ -492,6 +514,9 @@ pfkey_spdump1(m, withports)
 	m_lftc = (void *)mhp[SADB_EXT_LIFETIME_CURRENT];
 	m_lfth = (void *)mhp[SADB_EXT_LIFETIME_HARD];
 
+#ifdef SADB_X_EXT_SEC_CTX
+	m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+#endif
 #ifdef __linux__
 	/* *bsd indicates per-socket policies by omiting src and dst 
 	 * extensions. Linux always includes them, but we can catch it
@@ -596,6 +621,18 @@ pfkey_spdump1(m, withports)
 			(u_long)m_lfth->sadb_lifetime_usetime);
 	}
 
+#ifdef SADB_X_EXT_SEC_CTX
+	if (m_sec_ctx != NULL) {
+		printf("\tsecurity context doi: %u\n",
+					m_sec_ctx->sadb_x_ctx_doi);
+		printf("\tsecurity context algorithm: %u\n",
+					m_sec_ctx->sadb_x_ctx_alg);
+		printf("\tsecurity context length: %u\n",
+					m_sec_ctx->sadb_x_ctx_len);
+		printf("\tsecurity context: %s\n",
+			(char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx));
+	}
+#endif
 
 	printf("\tspid=%ld seq=%ld pid=%ld\n",
 		(u_long)m_xpl->sadb_x_policy_id,
diff -urpN ipsec-tools-0.6.5.orig/src/setkey/parse.y ipsec-tools-0.6.5.p1/src/setkey/parse.y
--- ipsec-tools-0.6.5.orig/src/setkey/parse.y	2006-03-02 12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/src/setkey/parse.y	2006-03-02 14:47:06.000000000 -0600
@@ -78,6 +78,15 @@ const char *p_key_auth;
 time_t p_lt_hard, p_lt_soft;
 size_t p_lb_hard, p_lb_soft;
 
+struct security_ctx {
+        __u8 doi;
+        __u8 alg;
+        __u16 len;
+        char *buf;
+};
+
+struct security_ctx sec_ctx;
+
 static u_int p_natt_type;
 static struct addrinfo * p_natt_oa = NULL;
 
@@ -124,6 +133,7 @@ static int setkeymsg_add __P((unsigned i
 %token F_POLICY PL_REQUESTS
 %token F_AIFLAGS
 %token TAGGED
+%token SECURITY_CTX
 
 %type <num> prefix protocol_spec upper_spec
 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
@@ -533,12 +543,18 @@ extension
 	|	F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
 	|	F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; }
 	|	F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; }
+	|       SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
+		sec_ctx.doi = $2;
+		sec_ctx.alg = $3;
+		sec_ctx.len = $4.len+1;
+		sec_ctx.buf = $4.buf;
+	}
 	;
 
 	/* definition about command for SPD management */
 	/* spdadd */
 spdadd_command
-	:	SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
+	:	SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
 		{
 			int status;
 			struct addrinfo *src, *dst;
@@ -570,7 +586,7 @@ spdadd_command
 				return -1;
 			}
 
-			status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
+			status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$12,
 			    src, $4, dst, $7);
 			freeaddrinfo(src);
 			freeaddrinfo(dst);
@@ -589,7 +605,7 @@ spdadd_command
 	;
 
 spddelete_command
-	:	SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
+	:	SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
 		{
 			int status;
 			struct addrinfo *src, *dst;
@@ -617,7 +633,7 @@ spddelete_command
 				return -1;
 			}
 
-			status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
+			status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$12,
 			    src, $4, dst, $7);
 			freeaddrinfo(src);
 			freeaddrinfo(dst);
@@ -792,6 +808,16 @@ upper_misc_spec
 		}
 	;
 
+context_spec
+	:	/* NOTHING */
+	|	SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
+			sec_ctx.doi = $2;
+			sec_ctx.alg = $3;
+			sec_ctx.len = $4.len+1;
+			sec_ctx.buf = $4.buf;
+		}
+	;
+
 policy_spec
 	:	F_POLICY policy_requests
 		{
@@ -939,7 +965,27 @@ setkeymsg_spdaddr(type, upper, policy, s
 
 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
 			    sizeof(m_addr), sa, salen);
-
+#ifdef SADB_X_EXT_SEC_CTX
+			/* Add security context label */
+			if (sec_ctx.doi) {
+				struct sadb_x_sec_ctx m_sec_ctx;
+				u_int slen = sizeof(struct sadb_x_sec_ctx);
+
+				memset(&m_sec_ctx, 0, slen);
+
+				m_sec_ctx.sadb_x_sec_len =
+				PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len));
+
+				m_sec_ctx.sadb_x_sec_exttype = 
+					SADB_X_EXT_SEC_CTX;
+				m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/
+				m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
+				m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
+				setvarbuf(buf, &l, 
+					  (struct sadb_ext *)&m_sec_ctx, slen, 
+					  (caddr_t)sec_ctx.buf, sec_ctx.len);
+			}
+#endif
 			msg->sadb_msg_len = PFKEY_UNIT64(l);
 
 			sendkeymsg(buf, l);
@@ -1268,6 +1314,25 @@ setkeymsg_add(type, satype, srcs, dsts)
 		l += slen;
 	}
 
+#ifdef SADB_X_EXT_SEC_CTX
+	/* Add security context label */
+	if (sec_ctx.doi) {
+		struct sadb_x_sec_ctx m_sec_ctx;
+		u_int slen = sizeof(struct sadb_x_sec_ctx);
+
+		memset(&m_sec_ctx, 0, slen);
+
+		m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen +
+					PFKEY_ALIGN8(sec_ctx.len));
+		m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
+		m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */
+		m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
+		m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
+		setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen,
+			  (caddr_t)sec_ctx.buf, sec_ctx.len); 
+	}
+#endif
+
 	len = sizeof(struct sadb_sa);
 	m_sa.sadb_sa_len = PFKEY_UNIT64(len);
 	m_sa.sadb_sa_exttype = SADB_EXT_SA;
@@ -1513,6 +1578,8 @@ parse_init()
 	p_lt_hard = p_lt_soft = 0;
 	p_lb_hard = p_lb_soft = 0;
 
+	memset(&sec_ctx, 0, sizeof(struct security_ctx));
+
 	p_aiflags = 0;
 	p_aifamily = PF_UNSPEC;
 
diff -urpN ipsec-tools-0.6.5.orig/src/setkey/setkey.8 ipsec-tools-0.6.5.p1/src/setkey/setkey.8
--- ipsec-tools-0.6.5.orig/src/setkey/setkey.8	2006-03-02 12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/src/setkey/setkey.8	2006-03-02 14:46:18.000000000 -0600
@@ -218,7 +218,7 @@ on the command line achieves the same fu
 .It Xo
 .Li spdadd
 .Op Fl 46n
-.Ar src_range Ar dst_range Ar upperspec Ar policy
+.Ar src_range Ar dst_range Ar upperspec Ar label Ar policy
 .Li ;
 .Xc
 Add an SPD entry.
@@ -368,6 +368,20 @@ Specify hard/soft life time duration of 
 .It Fl bh Ar bytes
 .It Fl bs Ar bytes
 Specify hard/soft life time duration of the SA measured in bytes transported.
+.\"
+.It Fl ctx Ar doi Ar algorithm Ar context-name
+Specify an access control label. The access control label is interpreted 
+by the LSM (e.g., SELinux). Ultimately, it enables MAC on network 
+communications. 
+.Bl -tag -width Fl -compact
+.It Ar doi
+The domain of interpretation, which is used by the
+IKE daemon to identify the domain in which negotiation takes place. 
+.It Ar algorithm
+Indicates the LSM for which the label is generated (e.g., SELinux).
+.It Ar context-name 
+The string representation of the label that is interpreted by the LSM.
+.El
 .El
 .\"
 .Pp
@@ -488,6 +502,27 @@ to use with IPsec.
 You have to consider carefully what to use.
 .\"
 .Pp
+.It Ar label
+.Ar label 
+is the access control label for the policy. This label is interpreted
+by the LSM (e.g., SELinux). Ultimately, it enables MAC on network
+communications. When a policy contains an access control label, SAs
+negotiated with this policy will contain the label. It's format:
+.Bl -tag -width Fl -compact
+.\"
+.It Fl ctx Ar doi Ar algorithm Ar context-name
+.Bl -tag -width Fl -compact
+.It Ar doi
+The domain of interpretation, which is used by the
+IKE daemon to identify the domain in which negotiation takes place.
+.It Ar algorithm
+Indicates the LSM for which the label is generated (e.g., SELinux).
+.It Ar context-name
+The string representation of the label that is interpreted by the LSM.
+.El
+.El
+.\"
+.Pp
 .It Ar policy
 .Ar policy
 is in one of the following three formats:
@@ -796,6 +831,14 @@ spdadd 10.0.11.41/32[21] 10.0.11.33/32[a
 	-P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require ;
 
 add 10.1.10.34 10.1.10.36 tcp 0x1000 -A tcp-md5 "TCP-MD5 BGP secret" ;
+
+add 10.0.11.41 10.0.11.33 esp 0x10001
+	-ctx 1 1 "system_u:system_r:unconfined_t:SystemLow-SystemHigh"
+	-E des-cbc 0x3ffe05014819ffff;
+
+spdadd 10.0.11.41 10.0.11.33 any
+	-ctx 1 1 "system_u:system_r:unconfined_t:SystemLow-SystemHigh"
+	-P out ipsec esp/transport//require ;
 .Ed
 .\"
 .Sh SEE ALSO
diff -urpN ipsec-tools-0.6.5.orig/src/setkey/token.l ipsec-tools-0.6.5.p1/src/setkey/token.l
--- ipsec-tools-0.6.5.orig/src/setkey/token.l	2006-03-02 12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/src/setkey/token.l	2006-03-02 14:46:53.000000000 -0600
@@ -236,6 +236,7 @@ nocyclic-seq	{ return(NOCYCLICSEQ); }
 {hyphen}ls	{ return(F_LIFETIME_SOFT); }
 {hyphen}bh	{ return(F_LIFEBYTE_HARD); }
 {hyphen}bs	{ return(F_LIFEBYTE_SOFT); }
+{hyphen}ctx	{ return(SECURITY_CTX); }
 
 	/* ... */
 any		{ return(ANY); }
diff -urpN ipsec-tools-0.6.5.p1/src/libipsec/libpfkey.h ipsec-tools-0.6.5.p2/src/libipsec/libpfkey.h
--- ipsec-tools-0.6.5.p1/src/libipsec/libpfkey.h	2006-03-02 14:43:32.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/libipsec/libpfkey.h	2006-03-02 14:51:51.000000000 -0600
@@ -88,21 +88,25 @@ int pfkey_send_getspi __P((int, u_int, u
 int pfkey_send_update __P((int, u_int, u_int, struct sockaddr *,
 	struct sockaddr *, u_int32_t, u_int32_t, u_int,
 	caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t,
-	u_int64_t, u_int64_t, u_int32_t));
+	u_int64_t, u_int64_t, u_int32_t,
+	u_int8_t, u_int8_t, caddr_t, u_int16_t));
 int pfkey_send_update_nat __P((int, u_int, u_int, struct sockaddr *,
 	struct sockaddr *, u_int32_t, u_int32_t, u_int,
 	caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t,
 	u_int64_t, u_int64_t, u_int32_t,
-	u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t));
+	u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t,
+	u_int8_t, u_int8_t, caddr_t, u_int16_t));
 int pfkey_send_add __P((int, u_int, u_int, struct sockaddr *,
 	struct sockaddr *, u_int32_t, u_int32_t, u_int,
 	caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t,
-	u_int64_t, u_int64_t, u_int32_t));
+	u_int64_t, u_int64_t, u_int32_t,
+	u_int8_t, u_int8_t, caddr_t, u_int16_t));
 int pfkey_send_add_nat __P((int, u_int, u_int, struct sockaddr *,
 	struct sockaddr *, u_int32_t, u_int32_t, u_int,
 	caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t,
 	u_int64_t, u_int64_t, u_int32_t,
-	u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t));
+	u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t,
+	u_int8_t, u_int8_t, caddr_t, u_int16_t));
 int pfkey_send_delete __P((int, u_int, u_int,
 	struct sockaddr *, struct sockaddr *, u_int32_t));
 int pfkey_send_delete_all __P((int, u_int, u_int,
diff -urpN ipsec-tools-0.6.5.p1/src/libipsec/pfkey.c ipsec-tools-0.6.5.p2/src/libipsec/pfkey.c
--- ipsec-tools-0.6.5.p1/src/libipsec/pfkey.c	2006-03-02 15:03:10.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/libipsec/pfkey.c	2006-03-02 15:00:45.000000000 -0600
@@ -62,7 +62,8 @@ static int pfkey_send_x1 __P((int, u_int
 	struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t,
 	u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t,
 	u_int32_t, u_int32_t, u_int32_t,
-	u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t));
+	u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t,
+	u_int8_t, u_int8_t, caddr_t, u_int16_t));
 static int pfkey_send_x2 __P((int, u_int, u_int, u_int,
 	struct sockaddr *, struct sockaddr *, u_int32_t));
 static int pfkey_send_x3 __P((int, u_int, u_int));
@@ -81,6 +82,10 @@ static caddr_t pfkey_setsadbkey __P((cad
 static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t,
 	u_int32_t, u_int32_t, u_int32_t));
 static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t));
+#ifdef SADB_X_EXT_SEC_CTX
+static caddr_t pfkey_setsecctx __P((caddr_t, caddr_t, u_int, u_int8_t, 
+	u_int8_t, caddr_t, u_int16_t));
+#endif
 
 #ifdef SADB_X_EXT_NAT_T_TYPE
 static caddr_t pfkey_set_natt_type __P((caddr_t, caddr_t, u_int, u_int8_t));
@@ -494,7 +499,9 @@ pfkey_send_getspi(so, satype, mode, src,
 int
 pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize,
 		keymat, e_type, e_keylen, a_type, a_keylen, flags,
-		l_alloc, l_bytes, l_addtime, l_usetime, seq)
+		l_alloc, l_bytes, l_addtime, l_usetime, seq, 
+		ctxdoi, ctxalg, ctxstr, ctxstrlen)
+		
 	int so;
 	u_int satype, mode, wsize;
 	struct sockaddr *src, *dst;
@@ -504,13 +511,17 @@ pfkey_send_update(so, satype, mode, src,
 	u_int32_t l_alloc;
 	u_int64_t l_bytes, l_addtime, l_usetime;
 	u_int32_t seq;
+	u_int8_t ctxdoi, ctxalg;
+	caddr_t ctxstr;
+	u_int16_t ctxstrlen;
 {
 	int len;
 	if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi,
 			reqid, wsize,
 			keymat, e_type, e_keylen, a_type, a_keylen, flags,
 			l_alloc, (u_int)l_bytes, (u_int)l_addtime, 
-			(u_int)l_usetime, seq, 0, 0, 0, NULL, 0)) < 0)
+			(u_int)l_usetime, seq, 0, 0, 0, NULL, 0,
+			ctxdoi, ctxalg, ctxstr, ctxstrlen)) < 0)
 		return -1;
 
 	return len;
@@ -522,7 +533,7 @@ pfkey_send_update_nat(so, satype, mode, 
 		      keymat, e_type, e_keylen, a_type, a_keylen, flags,
 		      l_alloc, l_bytes, l_addtime, l_usetime, seq,
 		      l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa,
-		      l_natt_frag)
+		      l_natt_frag, ctxdoi, ctxalg, ctxstr, ctxstrlen)
 	int so;
 	u_int satype, mode, wsize;
 	struct sockaddr *src, *dst;
@@ -536,6 +547,9 @@ pfkey_send_update_nat(so, satype, mode, 
 	u_int16_t l_natt_sport, l_natt_dport;
 	struct sockaddr *l_natt_oa;
 	u_int16_t l_natt_frag;
+	u_int8_t ctxdoi, ctxalg;
+	caddr_t ctxstr;
+	u_int16_t ctxstrlen;
 {
 	int len;
 	if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi,
@@ -543,7 +557,8 @@ pfkey_send_update_nat(so, satype, mode, 
 			keymat, e_type, e_keylen, a_type, a_keylen, flags,
 			l_alloc, (u_int)l_bytes, (u_int)l_addtime, 
 			(u_int)l_usetime, seq, l_natt_type, l_natt_sport, 
-			l_natt_dport, l_natt_oa, l_natt_frag)) < 0)
+			l_natt_dport, l_natt_oa, l_natt_frag,
+			ctxdoi, ctxalg, ctxstr, ctxstrlen)) < 0)
 		return -1;
 
 	return len;
@@ -560,7 +575,9 @@ pfkey_send_update_nat(so, satype, mode, 
 int
 pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize,
 		keymat, e_type, e_keylen, a_type, a_keylen, flags,
-		l_alloc, l_bytes, l_addtime, l_usetime, seq)
+		l_alloc, l_bytes, l_addtime, l_usetime, seq,
+		ctxdoi, ctxalg, ctxstr, ctxstrlen)
+
 	int so;
 	u_int satype, mode, wsize;
 	struct sockaddr *src, *dst;
@@ -570,13 +587,17 @@ pfkey_send_add(so, satype, mode, src, ds
 	u_int32_t l_alloc;
 	u_int64_t l_bytes, l_addtime, l_usetime;
 	u_int32_t seq;
+	u_int8_t ctxdoi, ctxalg;
+	caddr_t ctxstr;
+	u_int16_t ctxstrlen;
 {
 	int len;
 	if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
 			reqid, wsize,
 			keymat, e_type, e_keylen, a_type, a_keylen, flags,
 			l_alloc, (u_int)l_bytes, (u_int)l_addtime, 
-			(u_int)l_usetime, seq, 0, 0, 0, NULL, 0)) < 0)
+			(u_int)l_usetime, seq, 0, 0, 0, NULL, 0,
+			ctxdoi, ctxalg, ctxstr, ctxstrlen)) < 0)
 		return -1;
 
 	return len;
@@ -588,7 +609,7 @@ pfkey_send_add_nat(so, satype, mode, src
 		   keymat, e_type, e_keylen, a_type, a_keylen, flags,
 		   l_alloc, l_bytes, l_addtime, l_usetime, seq,
 		   l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa,
-		   l_natt_frag)
+		   l_natt_frag, ctxdoi, ctxalg, ctxstr, ctxstrlen)
 	int so;
 	u_int satype, mode, wsize;
 	struct sockaddr *src, *dst;
@@ -602,6 +623,9 @@ pfkey_send_add_nat(so, satype, mode, src
 	u_int16_t l_natt_sport, l_natt_dport;
 	struct sockaddr *l_natt_oa;
 	u_int16_t l_natt_frag;
+	u_int8_t ctxdoi, ctxalg;
+	caddr_t ctxstr;
+	u_int16_t ctxstrlen;
 {
 	int len;
 	if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
@@ -609,7 +633,8 @@ pfkey_send_add_nat(so, satype, mode, src
 			keymat, e_type, e_keylen, a_type, a_keylen, flags,
 			l_alloc, (u_int)l_bytes, (u_int)l_addtime, 
 			(u_int)l_usetime, seq, l_natt_type, l_natt_sport, 
-			l_natt_dport, l_natt_oa, l_natt_frag)) < 0)
+			l_natt_dport, l_natt_oa, l_natt_frag,
+			ctxdoi, ctxalg, ctxstr, ctxstrlen)) < 0)
 		return -1;
 
 	return len;
@@ -1202,7 +1227,7 @@ pfkey_send_x1(so, type, satype, mode, sr
 		keymat, e_type, e_keylen, a_type, a_keylen, flags,
 		l_alloc, l_bytes, l_addtime, l_usetime, seq,
 	        l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa, 
-		l_natt_frag)
+		l_natt_frag, ctxdoi, ctxalg, ctxstr, ctxstrlen)
 	int so;
 	u_int type, satype, mode;
 	struct sockaddr *src, *dst, *l_natt_oa;
@@ -1214,6 +1239,9 @@ pfkey_send_x1(so, type, satype, mode, sr
 	u_int16_t l_natt_sport, l_natt_dport;
 	u_int8_t l_natt_type;
 	u_int16_t l_natt_frag;
+	u_int8_t ctxdoi, ctxalg;
+	caddr_t ctxstr;
+	u_int16_t ctxstrlen;
 {
 	struct sadb_msg *newmsg;
 	int len;
@@ -1302,6 +1330,12 @@ pfkey_send_x1(so, type, satype, mode, sr
 	if (a_type != SADB_AALG_NONE)
 		len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen));
 
+#ifdef SADB_X_EXT_SEC_CTX 
+	if (ctxstr != NULL)
+		len += (sizeof(struct sadb_x_sec_ctx)
+		    + PFKEY_ALIGN8(ctxstrlen));
+#endif
+
 #ifdef SADB_X_EXT_NAT_T_TYPE
 	/* add nat-t packets */
 	if (l_natt_type) {
@@ -1392,6 +1426,16 @@ pfkey_send_x1(so, type, satype, mode, sr
 		free(newmsg);
 		return -1;
 	}
+#ifdef SADB_X_EXT_SEC_CTX 
+	if (ctxstr != NULL) {
+		p = pfkey_setsecctx(p, ep, SADB_X_EXT_SEC_CTX, ctxdoi, 
+				ctxalg, ctxstr, ctxstrlen);
+		if (!p) {
+			free(newmsg);
+			return -1;
+		}
+	}
+#endif
 
 #ifdef SADB_X_EXT_NAT_T_TYPE
 	/* Add nat-t messages */
@@ -2408,3 +2452,35 @@ pfkey_set_natt_frag(buf, lim, type, l_na
 	return(buf + len);
 }
 #endif
+
+#ifdef SADB_X_EXT_SEC_CTX 
+static caddr_t
+pfkey_setsecctx(buf, lim, type, ctx_doi, ctx_alg, sec_ctx, sec_ctxlen)
+	caddr_t buf;
+	caddr_t lim;
+	u_int type;
+	u_int8_t ctx_doi, ctx_alg;
+	caddr_t sec_ctx;
+	u_int16_t sec_ctxlen;
+{
+	struct sadb_x_sec_ctx *p;
+	u_int len;
+
+	p = (struct sadb_x_sec_ctx *)buf;
+	len = sizeof(struct sadb_x_sec_ctx) + PFKEY_ALIGN8(sec_ctxlen);
+	
+	if (buf + len > lim)
+		return NULL;
+	
+	memset(p, 0, len);
+	p->sadb_x_sec_len = PFKEY_UNIT64(len);
+	p->sadb_x_sec_exttype = type;
+	p->sadb_x_ctx_len = sec_ctxlen;
+	p->sadb_x_ctx_doi = ctx_doi;
+	p->sadb_x_ctx_alg = ctx_alg;
+		
+	memcpy(p + 1, sec_ctx, sec_ctxlen);
+
+	return buf + len;
+}
+#endif 
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/backupsa.c ipsec-tools-0.6.5.p2/src/racoon/backupsa.c
--- ipsec-tools-0.6.5.p1/src/racoon/backupsa.c	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/backupsa.c	2006-03-02 14:52:47.000000000 -0600
@@ -331,7 +331,8 @@ do { \
 				wsize,
 				keymat,
 				e_type, e_keylen, a_type, a_keylen, flags,
-				0, l_bytes, l_addtime, 0, seq) < 0) {
+				0, l_bytes, l_addtime, 0, seq,
+				0, 0, NULL, 0) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"restore SA filed line#%d in %s: %s\n",
 				line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], ipsec_strerror());
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/cftoken.l ipsec-tools-0.6.5.p2/src/racoon/cftoken.l
--- ipsec-tools-0.6.5.p1/src/racoon/cftoken.l	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/cftoken.l	2006-03-02 14:52:58.000000000 -0600
@@ -70,6 +70,7 @@
 #include "isakmp_var.h"
 #include "isakmp.h"
 #include "ipsec_doi.h"
+#include "policy.h"
 #include "proposal.h"
 #include "nattraversal.h"
 #ifdef GC
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/ipsec_doi.c ipsec-tools-0.6.5.p2/src/racoon/ipsec_doi.c
--- ipsec-tools-0.6.5.p1/src/racoon/ipsec_doi.c	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/ipsec_doi.c	2006-03-02 14:53:08.000000000 -0600
@@ -2379,6 +2379,15 @@ ahmismatch:
 			}
 			break;
 
+#ifdef HAVE_SECCTX
+		case IPSECDOI_ATTR_SECCTX:
+			if (flag) {
+				plog(LLV_ERROR, LOCATION, NULL,
+					"SECCTX must be in TLV.\n");
+				return -1;
+			}
+		break;
+#endif
 		case IPSECDOI_ATTR_KEY_ROUNDS:
 		case IPSECDOI_ATTR_COMP_DICT_SIZE:
 		case IPSECDOI_ATTR_COMP_PRIVALG:
@@ -2882,6 +2891,10 @@ setph2proposal0(iph2, pp, pr)
 	caddr_t x0, x;
 	u_int8_t *np_t; /* pointer next trns type in previous header */
 	const u_int8_t *spi;
+#ifdef HAVE_SECCTX
+	int truectxlen = 0;
+#endif
+
 
 	p = vmalloc(sizeof(*prop) + sizeof(pr->spi));
 	if (p == NULL)
@@ -2983,6 +2996,16 @@ setph2proposal0(iph2, pp, pr)
 
 		if (alg_oakley_dhdef_ok(iph2->sainfo->pfs_group))
 			attrlen += sizeof(struct isakmp_data);
+#ifdef HAVE_SECCTX
+		/* ctx_str is defined as char ctx_str[MAX_CTXSTR_SIZ].
+		 * The string may be smaller than MAX_CTXSTR_SIZ.
+		 */
+		if (*pp->sctx.ctx_str) {
+			truectxlen = sizeof(struct security_ctx) -
+				     (MAX_CTXSTR_SIZE - pp->sctx.ctx_strlen);
+			attrlen += sizeof(struct isakmp_data) + truectxlen;
+		}
+#endif /* HAVE_SECCTX */
 
 		p = vrealloc(p, p->l + sizeof(*trns) + attrlen);
 		if (p == NULL)
@@ -3038,6 +3061,13 @@ setph2proposal0(iph2, pp, pr)
 			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_GRP_DESC,
 				iph2->sainfo->pfs_group);
 
+#ifdef HAVE_SECCTX
+		if (*pp->sctx.ctx_str) {
+			x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SECCTX,
+					      (caddr_t)&pp->sctx, truectxlen);
+		}
+#endif
+
 		/* update length of this transform. */
 		trns = (struct isakmp_pl_t *)(p->v + trnsoff);
 		trns->h.len = htons(sizeof(*trns) + attrlen);
@@ -4154,6 +4184,14 @@ ipsecdoi_t2satrns(t, pp, pr, tr)
 			tr->encklen = ntohs(d->lorv);
 			break;
 
+#ifdef HAVE_SECCTX
+		case IPSECDOI_ATTR_SECCTX:
+		{
+			int len = ntohs(d->lorv);
+			memcpy(&pp->sctx, d + 1, len);
+			break;
+		}
+#endif
 		case IPSECDOI_ATTR_KEY_ROUNDS:
 		case IPSECDOI_ATTR_COMP_DICT_SIZE:
 		case IPSECDOI_ATTR_COMP_PRIVALG:
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/ipsec_doi.h ipsec-tools-0.6.5.p2/src/racoon/ipsec_doi.h
--- ipsec-tools-0.6.5.p1/src/racoon/ipsec_doi.h	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/ipsec_doi.h	2006-03-02 14:53:13.000000000 -0600
@@ -133,6 +133,10 @@
 #define IPSECDOI_ATTR_COMP_DICT_SIZE          8 /* B */
 #define IPSECDOI_ATTR_COMP_PRIVALG            9 /* V */
 
+#ifdef HAVE_SECCTX
+#define IPSECDOI_ATTR_SECCTX	     	     10 /* V */
+#endif
+
 /* 4.6.1 Security Association Payload */
 struct ipsecdoi_pl_sa {
 	struct isakmp_gen h;
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/isakmp.c ipsec-tools-0.6.5.p2/src/racoon/isakmp.c
--- ipsec-tools-0.6.5.p1/src/racoon/isakmp.c	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/isakmp.c	2006-03-02 14:53:23.000000000 -0600
@@ -84,11 +84,11 @@
 #include "oakley.h"
 #include "evt.h"
 #include "handler.h"
+#include "policy.h"
 #include "proposal.h"
 #include "ipsec_doi.h"
 #include "pfkey.h"
 #include "crypto_openssl.h"
-#include "policy.h"
 #include "isakmp_ident.h"
 #include "isakmp_agg.h"
 #include "isakmp_base.h"
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/isakmp_quick.c ipsec-tools-0.6.5.p2/src/racoon/isakmp_quick.c
--- ipsec-tools-0.6.5.p1/src/racoon/isakmp_quick.c	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/isakmp_quick.c	2006-03-02 14:53:30.000000000 -0600
@@ -2037,6 +2037,19 @@ get_proposal_r(iph2)
 	if (spidx.ul_proto == 0)
 		spidx.ul_proto = IPSEC_ULPROTO_ANY;
 
+#ifdef HAVE_SECCTX
+	/*
+	 * Need to use security context in spidx to ensure the correct
+	 * policy is selected. The only way to get the security context
+	 * is to look into the proposal sent by peer ahead of time.
+	 */
+	if (get_security_context(iph2->sa, &spidx)) {
+		plog(LLV_ERROR, LOCATION, NULL, 
+			"error occurred trying to get security context.\n");
+		return ISAKMP_INTERNAL_ERROR;
+	}
+#endif /* HAVE_SECCTX */
+
 	/* get inbound policy */
 	sp_in = getsp_r(&spidx);
 	if (sp_in == NULL) {
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/Makefile.am ipsec-tools-0.6.5.p2/src/racoon/Makefile.am
--- ipsec-tools-0.6.5.p1/src/racoon/Makefile.am	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/Makefile.am	2006-03-02 14:53:42.000000000 -0600
@@ -31,12 +31,12 @@ racoon_SOURCES = \
 	safefile.c backupsa.c genlist.c rsalist.c \
 	cftoken.l cfparse.y prsa_tok.l prsa_par.y 
 EXTRA_racoon_SOURCES = isakmp_xauth.c isakmp_cfg.c isakmp_unity.c throttle.c \
-	isakmp_frag.c nattraversal.c $(MISSING_ALGOS)
+	isakmp_frag.c nattraversal.c security.c $(MISSING_ALGOS)
 racoon_LDFLAGS = ../libipsec/libipsec.la
-racoon_LDADD = $(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) $(LEXLIB) \
-	vmbuf.o sockmisc.o misc.o
+racoon_LDADD = $(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) \
+	$(SECCTX_OBJS) $(LEXLIB) vmbuf.o sockmisc.o misc.o
 racoon_DEPENDENCIES = ../libipsec/libipsec.la \
-	$(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) \
+	$(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) $(SECCTX_OBJS) \
 	vmbuf.o sockmisc.o misc.o
 
 racoonctl_SOURCES = racoonctl.c str2val.c 
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/pfkey.c ipsec-tools-0.6.5.p2/src/racoon/pfkey.c
--- ipsec-tools-0.6.5.p1/src/racoon/pfkey.c	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/pfkey.c	2006-03-02 14:53:56.000000000 -0600
@@ -1009,6 +1009,10 @@ pk_sendupdate(iph2)
 	u_int wsize = 4;  /* XXX static size of window */ 
 	int proxy = 0;
 	struct ph2natt natt;
+	u_int8_t ctxdoi = 0, ctxalg = 0;
+	u_int16_t ctxstrlen = 0;
+	caddr_t ctxstr = NULL;
+	
 
 	/* sanity check */
 	if (iph2->approval == NULL) {
@@ -1070,6 +1074,15 @@ pk_sendupdate(iph2)
 		lifebyte = 0;
 #endif
 
+#ifdef HAVE_SECCTX
+		if (*iph2->approval->sctx.ctx_str) {
+			ctxdoi = iph2->approval->sctx.ctx_doi;
+			ctxalg = iph2->approval->sctx.ctx_alg;
+			ctxstrlen = iph2->approval->sctx.ctx_strlen;
+			ctxstr = iph2->approval->sctx.ctx_str;
+		}
+#endif /* HAVE_SECCTX */
+
 #ifdef ENABLE_NATT
 		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_update_nat\n");
 		if (pr->udp_encap) {
@@ -1097,7 +1110,8 @@ pk_sendupdate(iph2)
 				0, lifebyte, iph2->approval->lifetime, 0,
 				iph2->seq,
 				natt.type, natt.sport, natt.dport, natt.oa,
-				natt.frag) < 0) {
+				natt.frag,
+				ctxdoi, ctxalg, ctxstr, ctxstrlen) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"libipsec failed send update_nat (%s)\n",
 				ipsec_strerror());
@@ -1117,7 +1131,8 @@ pk_sendupdate(iph2)
 				pr->keymat->v,
 				e_type, e_keylen, a_type, a_keylen, flags,
 				0, lifebyte, iph2->approval->lifetime, 0,
-				iph2->seq) < 0) {
+				iph2->seq,
+				ctxdoi, ctxalg, ctxstr, ctxstrlen) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"libipsec failed send update (%s)\n",
 				ipsec_strerror());
@@ -1301,6 +1316,9 @@ pk_sendadd(iph2)
 	u_int wsize = 4; /* XXX static size of window */ 
 	int proxy = 0;
 	struct ph2natt natt;
+	u_int8_t ctxdoi = 0, ctxalg = 0;
+	u_int16_t ctxstrlen = 0;
+	caddr_t ctxstr = NULL;
 
 	/* sanity check */
 	if (iph2->approval == NULL) {
@@ -1362,6 +1380,15 @@ pk_sendadd(iph2)
 		lifebyte = 0;
 #endif
 
+#ifdef HAVE_SECCTX
+		if (*iph2->approval->sctx.ctx_str) {
+			ctxdoi = iph2->approval->sctx.ctx_doi;
+			ctxalg = iph2->approval->sctx.ctx_alg;
+			ctxstrlen = iph2->approval->sctx.ctx_strlen;
+			ctxstr = iph2->approval->sctx.ctx_str;
+		}
+#endif /* HAVE_SECCTX */
+
 #ifdef ENABLE_NATT
 		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add_nat\n");
 
@@ -1394,7 +1421,8 @@ pk_sendadd(iph2)
 				0, lifebyte, iph2->approval->lifetime, 0,
 				iph2->seq,
 				natt.type, natt.sport, natt.dport, natt.oa,
-				natt.frag) < 0) {
+				natt.frag,
+				ctxdoi, ctxalg, ctxstr, ctxstrlen) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"libipsec failed send add_nat (%s)\n",
 				ipsec_strerror());
@@ -1419,7 +1447,8 @@ pk_sendadd(iph2)
 				pr->keymat_p->v,
 				e_type, e_keylen, a_type, a_keylen, flags,
 				0, lifebyte, iph2->approval->lifetime, 0,
-				iph2->seq) < 0) {
+				iph2->seq,
+				ctxdoi, ctxalg, ctxstr, ctxstrlen) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"libipsec failed send add (%s)\n",
 				ipsec_strerror());
@@ -1757,6 +1786,11 @@ pk_recvacquire(mhp)
 	spidx.prefs = sp_out->spidx.prefd;
 	spidx.prefd = sp_out->spidx.prefs;
 	spidx.ul_proto = sp_out->spidx.ul_proto;
+#ifdef HAVE_SECCTX
+	if (*sp_out->spidx.sec_ctx.ctx_str)
+		memcpy(&spidx.sec_ctx, &sp_out->spidx.sec_ctx, 
+			sizeof(spidx.sec_ctx));
+#endif
 
 	sp_in = getsp(&spidx);
 	if (sp_in) {
@@ -1970,6 +2004,10 @@ getsadbpolicy(policy0, policylen0, type,
 	int policylen;
 	int xisrlen;
 	u_int satype, mode;
+	int len = 0;
+#ifdef HAVE_SECCTX
+	int ctxlen = 0;
+#endif
 
 	/* get policy buffer size */
 	policylen = sizeof(struct sadb_x_policy);
@@ -1984,6 +2022,13 @@ getsadbpolicy(policy0, policylen0, type,
 			policylen += PFKEY_ALIGN8(xisrlen);
 		}
 	}
+#ifdef HAVE_SECCTX
+	if (*spidx->sec_ctx.ctx_str) {
+		ctxlen = sizeof(struct sadb_x_sec_ctx)
+			   + PFKEY_ALIGN8(spidx->sec_ctx.ctx_strlen);
+		policylen += ctxlen;
+	}
+#endif
 
 	/* make policy structure */
 	policy = racoon_malloc(policylen);
@@ -2002,12 +2047,31 @@ getsadbpolicy(policy0, policylen0, type,
 #ifdef HAVE_PFKEY_POLICY_PRIORITY
 	xpl->sadb_x_policy_priority = PRIORITY_DEFAULT;
 #endif
+	len++;
 
+#ifdef HAVE_SECCTX
+	if (*spidx->sec_ctx.ctx_str) {
+		struct sadb_x_sec_ctx *p;
+
+		p = (struct sadb_x_sec_ctx *)(xpl + len);
+		memset(p, 0, ctxlen);
+		p->sadb_x_sec_len = PFKEY_UNIT64(ctxlen);
+		p->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
+		p->sadb_x_ctx_len = spidx->sec_ctx.ctx_strlen;
+		p->sadb_x_ctx_doi = spidx->sec_ctx.ctx_doi;
+		p->sadb_x_ctx_alg = spidx->sec_ctx.ctx_alg;
+                                                                                
+		memcpy(p + 1,spidx->sec_ctx.ctx_str,spidx->sec_ctx.ctx_strlen);
+		len += ctxlen;
+	}
+#endif /* HAVE_SECCTX */
+	
 	/* no need to append policy information any more if type is SPDDELETE */
 	if (type == SADB_X_SPDDELETE)
 		goto end;
 
-	xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
+
+	xisr = (struct sadb_x_ipsecrequest *)(xpl + len);
 
 	for (pr = iph2->approval->head; pr; pr = pr->next) {
 
@@ -2148,6 +2212,18 @@ pk_recvspdupdate(mhp)
 			&spidx);
 #endif
 
+#ifdef HAVE_SECCTX
+	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
+		struct sadb_x_sec_ctx *ctx;
+
+		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
+		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
+		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
+		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
+	}
+#endif /* HAVE SEC_CTX */
+		
 	sp = getsp(&spidx);
 	if (sp == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -2249,6 +2325,18 @@ pk_recvspdadd(mhp)
 			&spidx);
 #endif
 
+#ifdef HAVE_SECCTX
+	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
+		struct sadb_x_sec_ctx *ctx;
+
+		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
+		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
+		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
+		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
+	}
+#endif /* HAVE_SECCTX */
+
 	sp = getsp(&spidx);
 	if (sp != NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -2345,6 +2433,18 @@ pk_recvspddelete(mhp)
 			&spidx);
 #endif
 
+#ifdef HAVE_SECCTX
+	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
+		struct sadb_x_sec_ctx *ctx;
+
+		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
+		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
+		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
+		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
+	}
+#endif /* HAVE_SECCTX */
+
 	sp = getsp(&spidx);
 	if (sp == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -2400,6 +2500,18 @@ pk_recvspdexpire(mhp)
 			&spidx);
 #endif
 
+#ifdef HAVE_SECCTX
+	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
+		struct sadb_x_sec_ctx *ctx;
+
+		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
+		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
+		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
+		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
+	}
+#endif /* HAVE_SECCTX */
+
 	sp = getsp(&spidx);
 	if (sp == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -2475,6 +2587,18 @@ pk_recvspddump(mhp)
 			&spidx);
 #endif
 
+#ifdef HAVE_SECCTX
+	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
+		struct sadb_x_sec_ctx *ctx;
+
+		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
+		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
+		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
+		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
+	}
+#endif /* HAVE_SECCTX */
+
 	sp = getsp(&spidx);
 	if (sp != NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -2832,6 +2956,18 @@ addnewsp(mhp)
 			&new->spidx);
 #endif
 
+#ifdef HAVE_SECCTX
+	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
+		struct sadb_x_sec_ctx *ctx;
+
+		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+		new->spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
+		new->spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
+		new->spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
+		memcpy(new->spidx.sec_ctx.ctx_str,ctx + 1,ctx->sadb_x_ctx_len);
+	}
+#endif /* HAVE_SECCTX */
+
 	inssp(new);
 
 	return 0;
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/policy.c ipsec-tools-0.6.5.p2/src/racoon/policy.c
--- ipsec-tools-0.6.5.p1/src/racoon/policy.c	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/policy.c	2006-03-02 14:54:04.000000000 -0600
@@ -203,6 +203,14 @@ cmpspidxstrict(a, b)
 			   (struct sockaddr *)&b->dst))
 		return 1;
 
+#ifdef HAVE_SECCTX
+	if (a->sec_ctx.ctx_alg != b->sec_ctx.ctx_alg 
+	 || a->sec_ctx.ctx_doi != b->sec_ctx.ctx_doi
+	 || a->sec_ctx.ctx_strlen != b->sec_ctx.ctx_strlen
+	 || (memcmp(a->sec_ctx.ctx_str, b->sec_ctx.ctx_str, 
+	     a->sec_ctx.ctx_strlen) != 0))
+		return 1;
+#endif
 	return 0;
 }
 
@@ -273,6 +281,15 @@ cmpspidxwild(a, b)
 	if (cmpsaddrwild((struct sockaddr *)&sa1, (struct sockaddr *)&sa2))
 		return 1;
 
+#ifdef HAVE_SECCTX
+	if (a->sec_ctx.ctx_alg != b->sec_ctx.ctx_alg 
+	 || a->sec_ctx.ctx_doi != b->sec_ctx.ctx_doi
+	 || a->sec_ctx.ctx_strlen != b->sec_ctx.ctx_strlen
+	 || (memcmp(a->sec_ctx.ctx_str, b->sec_ctx.ctx_str, 
+	     a->sec_ctx.ctx_strlen) != 0))
+		return 1;
+#endif
+
 	return 0;
 }
 
@@ -462,8 +479,18 @@ spidx2str(spidx)
 	p += i;
 	blen -= i;
 
-	snprintf(p, blen, "proto=%s dir=%s",
+	i = snprintf(p, blen, "proto=%s dir=%s",
 		s_proto(spidx->ul_proto), s_direction(spidx->dir));
+	
+#ifdef HAVE_SECCTX
+	if (spidx->sec_ctx.ctx_strlen) {
+		p += i;
+		blen -= i;
+		snprintf(p, blen, " sec_ctx:doi=%d,alg=%d,len=%d,str=%s", 
+	  		spidx->sec_ctx.ctx_doi, spidx->sec_ctx.ctx_alg,
+			spidx->sec_ctx.ctx_strlen, spidx->sec_ctx.ctx_str);
+	}
+#endif
 
 	return buf;
 }
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/policy.h ipsec-tools-0.6.5.p2/src/racoon/policy.h
--- ipsec-tools-0.6.5.p1/src/racoon/policy.h	2006-03-02 14:43:32.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/policy.h	2006-03-02 14:54:09.000000000 -0600
@@ -34,6 +34,18 @@
 
 #include <sys/queue.h>
 
+#ifdef HAVE_SECCTX
+#define MAX_CTXSTR_SIZE 50
+struct security_ctx {
+	u_int8_t ctx_doi;	/* Security Context DOI */
+	u_int8_t ctx_alg;	/* Security Context Algorithm */
+	u_int16_t ctx_strlen;	/* Security Context stringlength
+				 * (includes terminating NULL)
+				 */
+	char ctx_str[MAX_CTXSTR_SIZE];	/* Security Context string */
+};
+#endif
+
 /* refs. ipsec.h */
 /*
  * Security Policy Index
@@ -50,6 +62,9 @@ struct policyindex {
 	u_int8_t prefd;			/* prefix length in bits for dst */
 	u_int16_t ul_proto;		/* upper layer Protocol */
 	u_int32_t priority;		/* priority for the policy */
+#ifdef HAVE_SECCTX
+	struct security_ctx sec_ctx;	/* Security Context */
+#endif
 };
 
 /* Security Policy Data Base */
@@ -131,5 +146,6 @@ extern void initsp __P((void));
 extern struct ipsecrequest *newipsecreq __P((void));
 
 extern const char *spidx2str __P((const struct policyindex *));
+extern int get_security_context __P((vchar_t *, struct policyindex *));
 
 #endif /* _POLICY_H */
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/proposal.c ipsec-tools-0.6.5.p2/src/racoon/proposal.c
--- ipsec-tools-0.6.5.p1/src/racoon/proposal.c	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/proposal.c	2006-03-02 14:54:22.000000000 -0600
@@ -311,6 +311,60 @@ cmpsaprop_alloc(ph1, pp1, pp2, side)
 		goto err;
 	}
 
+#ifdef HAVE_SECCTX
+	/* check the security_context properties.
+	 * It is possible for one side to have a security context
+	 * and the other side doesn't. If so, this is an error.
+	 */
+	
+	if (*pp1->sctx.ctx_str && !(*pp2->sctx.ctx_str)) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"My proposal missing security context\n");
+		goto err;
+	}
+	if (!(*pp1->sctx.ctx_str) && *pp2->sctx.ctx_str) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"Peer is missing security context\n");
+		goto err;
+	}
+		
+	if (*pp1->sctx.ctx_str && *pp2->sctx.ctx_str) {
+		if (pp1->sctx.ctx_doi == pp2->sctx.ctx_doi)
+			newpp->sctx.ctx_doi = pp1->sctx.ctx_doi;
+		else {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"sec doi mismatched: "
+				"my:%d peer:%d\n",
+				pp2->sctx.ctx_doi, pp1->sctx.ctx_doi);
+			goto err;
+		}
+		
+		if (pp1->sctx.ctx_alg == pp2->sctx.ctx_alg)
+			newpp->sctx.ctx_alg = pp1->sctx.ctx_alg;
+		else {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"sec alg mismatched: "
+				"my:%d peer:%d\n",
+				pp2->sctx.ctx_alg, pp1->sctx.ctx_alg);
+			goto err;
+		}
+	
+		if ((pp1->sctx.ctx_strlen != pp2->sctx.ctx_strlen) || 
+		memcmp(pp1->sctx.ctx_str, pp2->sctx.ctx_str, 
+		       pp1->sctx.ctx_strlen) != 0) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"security-context string mismatched: "
+				"my: %s peer: %s\n",
+				pp2->sctx.ctx_str, pp1->sctx.ctx_str);
+			goto err;
+		} else {
+			newpp->sctx.ctx_strlen = pp1->sctx.ctx_strlen;
+			memcpy(newpp->sctx.ctx_str, pp1->sctx.ctx_str, 
+			       pp1->sctx.ctx_strlen);
+		}
+	}	
+#endif /* HAVE_SECCTX */
+
 	npr1 = npr2 = 0;
 	for (pr1 = pp1->head; pr1; pr1 = pr1->next)
 		npr1++;
@@ -960,7 +1014,7 @@ set_proposal_from_policy(iph2, sp_main, 
 	struct saprop *newpp;
 	struct ipsecrequest *req;
 	int encmodesv = IPSEC_MODE_TRANSPORT; /* use only when complex_bundle */
-
+	
 	newpp = newsaprop();
 	if (newpp == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -971,6 +1025,15 @@ set_proposal_from_policy(iph2, sp_main, 
 	newpp->lifetime = iph2->sainfo->lifetime;
 	newpp->lifebyte = iph2->sainfo->lifebyte;
 	newpp->pfs_group = iph2->sainfo->pfs_group;
+#ifdef HAVE_SECCTX
+	if (*sp_main->spidx.sec_ctx.ctx_str) {
+		newpp->sctx.ctx_doi = sp_main->spidx.sec_ctx.ctx_doi;
+		newpp->sctx.ctx_alg = sp_main->spidx.sec_ctx.ctx_alg;
+		newpp->sctx.ctx_strlen = sp_main->spidx.sec_ctx.ctx_strlen;
+		memcpy(newpp->sctx.ctx_str, sp_main->spidx.sec_ctx.ctx_str, 
+			sp_main->spidx.sec_ctx.ctx_strlen);
+	}
+#endif /* HAVE_SECCTX */
 
 	if (lcconf->complex_bundle)
 		goto skip1;
@@ -1125,7 +1188,17 @@ set_proposal_from_proposal(iph2)
 		pp0->lifetime = iph2->sainfo->lifetime;
 		pp0->lifebyte = iph2->sainfo->lifebyte;
 		pp0->pfs_group = iph2->sainfo->pfs_group;
-
+		
+#ifdef HAVE_SECCTX
+		if (*pp_peer->sctx.ctx_str) {
+			pp0->sctx.ctx_doi = pp_peer->sctx.ctx_doi;
+			pp0->sctx.ctx_alg = pp_peer->sctx.ctx_alg;
+			pp0->sctx.ctx_strlen = pp_peer->sctx.ctx_strlen;
+			memcpy(pp0->sctx.ctx_str, pp_peer->sctx.ctx_str,
+				pp_peer->sctx.ctx_strlen);
+		}
+#endif /* HAVE_SECCTX */
+		
 		if (pp_peer->next != NULL) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"pp_peer is inconsistency, ignore it.\n");
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/proposal.h ipsec-tools-0.6.5.p2/src/racoon/proposal.h
--- ipsec-tools-0.6.5.p1/src/racoon/proposal.h	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/proposal.h	2006-03-02 14:54:28.000000000 -0600
@@ -60,7 +60,9 @@ struct saprop {
 	int pfs_group;			/* pfs group */
 	int claim;			/* flag to send RESPONDER-LIFETIME. */
 					/* XXX assumed DOI values are 1 or 2. */
-
+#ifdef HAVE_SECCTX
+	struct security_ctx sctx;	/* security context structure */
+#endif
 	struct saproto *head;
 	struct saprop *next;
 };
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/remoteconf.c ipsec-tools-0.6.5.p2/src/racoon/remoteconf.c
--- ipsec-tools-0.6.5.p1/src/racoon/remoteconf.c	2006-03-02 14:43:31.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/remoteconf.c	2006-03-02 14:54:41.000000000 -0600
@@ -66,6 +66,7 @@
 #include "remoteconf.h"
 #include "localconf.h"
 #include "grabmyaddr.h"
+#include "policy.h"
 #include "proposal.h"
 #include "vendorid.h"
 #include "gcmalloc.h"
diff -urpN ipsec-tools-0.6.5.p1/src/racoon/security.c ipsec-tools-0.6.5.p2/src/racoon/security.c
--- ipsec-tools-0.6.5.p1/src/racoon/security.c	1969-12-31 18:00:00.000000000 -0600
+++ ipsec-tools-0.6.5.p2/src/racoon/security.c	2006-03-02 14:54:47.000000000 -0600
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2005 International Business Machines Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "var.h"
+#include "vmbuf.h"
+#include "misc.h"
+#include "plog.h"
+
+#include "isakmp_var.h"
+#include "isakmp.h"
+#include "ipsec_doi.h"
+#include "policy.h"
+#include "strnames.h"
+#include "handler.h"
+
+/* 
+ * Get the security context information from SA.
+ */
+int
+get_security_context(sa, p)
+	vchar_t *sa;
+	struct policyindex *p;
+{
+	int len = 0;
+	int flag, type = 0;
+	u_int16_t lorv;
+	caddr_t bp;
+	vchar_t *pbuf = NULL;
+	vchar_t *tbuf = NULL;
+	struct isakmp_parse_t *pa;
+	struct isakmp_parse_t *ta;
+	struct isakmp_pl_p *prop;
+	struct isakmp_pl_t *trns;
+	struct isakmp_data *d;
+	struct ipsecdoi_sa_b *sab = (struct ipsecdoi_sa_b *)sa->v;
+	
+	/* check SA payload size */
+	if (sa->l < sizeof(*sab)) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"Invalid SA length = %zu.\n", sa->l);
+		return -1;
+	}
+
+	bp = (caddr_t)(sab + 1); /* here bp points to first proposal payload */
+	len = sa->l - sizeof(*sab);
+
+	pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, len);
+	if (pbuf == NULL)
+		return -1;
+
+	pa = (struct isakmp_parse_t *)pbuf->v; 
+        /* check the value of next payload */
+	if (pa->type != ISAKMP_NPTYPE_P) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"Invalid payload type=%u\n", pa->type);
+		vfree(pbuf);
+		return -1;
+	}
+
+	if (pa->len == 0) {
+		plog(LLV_ERROR, LOCATION, NULL,
+		"invalid proposal with length %d\n", pa->len);
+		vfree(pbuf);
+		return -1;
+	}
+
+	/* our first proposal */
+	prop = (struct isakmp_pl_p *)pa->ptr;
+
+	/* now get transform */
+	bp = (caddr_t)prop + sizeof(struct isakmp_pl_p) + prop->spi_size;
+	len = ntohs(prop->h.len) - 
+		(sizeof(struct isakmp_pl_p) + prop->spi_size);
+	tbuf = isakmp_parsewoh(ISAKMP_NPTYPE_T, (struct isakmp_gen *)bp, len);
+	if (tbuf == NULL)
+		return -1;
+
+	ta = (struct isakmp_parse_t *)tbuf->v;
+	if (ta->type != ISAKMP_NPTYPE_T) {
+		plog(LLV_ERROR, LOCATION, NULL,
+		     "Invalid payload type=%u\n", ta->type);
+		return -1;
+	}
+	
+	trns = (struct isakmp_pl_t *)ta->ptr;
+
+	len = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
+	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));
+
+	while (len > 0) {
+		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
+		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
+		lorv = ntohs(d->lorv);
+
+		if (type != IPSECDOI_ATTR_SECCTX) {
+			if (flag) {
+				len -= sizeof(*d);
+				d = (struct isakmp_data *)((char *)d 
+				     + sizeof(*d));
+			} else {
+				len -= (sizeof(*d) + lorv);
+				d = (struct isakmp_data *)((caddr_t)d
+				     + sizeof(*d) + lorv);
+			}
+		} else {
+			flag = ntohs(d->type & ISAKMP_GEN_MASK);
+			if (flag) {
+				plog(LLV_ERROR, LOCATION, NULL,
+				     "SECCTX must be in TLV.\n");
+				return -1;
+			}
+			memcpy(&p->sec_ctx, d + 1, lorv);
+			return 0;
+		}
+	}
+	return 0;
+}


Index: ipsec-tools.spec
===================================================================
RCS file: /cvs/dist/rpms/ipsec-tools/devel/ipsec-tools.spec,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- ipsec-tools.spec	11 Feb 2006 03:37:37 -0000	1.23
+++ ipsec-tools.spec	18 Apr 2006 20:15:42 -0000	1.24
@@ -1,6 +1,6 @@
 Name: ipsec-tools
 Version: 0.6.4
-Release: 1.1
+Release: 2
 Summary: Tools for configuring and using IPSEC
 License: BSD
 Group: System Environment/Base
@@ -16,10 +16,11 @@
 Patch2: isakmp.c.diff
 Patch5: ipsec-tools-0.5-64bit.patch
 #Patch6: ipsec-tools-0.6.1-openssl-098.patch
+Patch7: ipsec-tools-0.6.5-mls.patch
 BuildPrereq: openssl-devel, krb5-devel, bison, flex
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 Requires: initscripts >= 7.31.11.EL-1
-
+	
 %description
 This is the IPsec-Tools package.  You need this package in order to
 really use the IPsec functionality in the linux-2.5+ kernels.  This
@@ -34,6 +35,7 @@
 %patch2 -p1
 %patch5 -p1 -b .64bit
 #%patch6 -p1 -b .openssl-098
+%patch7 -p1 -b .mls
 
 mkdir -p kernel-headers/linux
 cp %{SOURCE1} %{SOURCE2} %{SOURCE5} %{SOURCE6} kernel-headers/linux
@@ -90,6 +92,10 @@
 %config(noreplace) /etc/racoon/racoon.conf
 
 %changelog
+* Tue Apr 18 2006 Dan Walsh <dwalsh at redhat.com> - 0.6.4-2
+- Add MLS Patch to allow use of labeled networks
+- Patch provided by Joy Latten <latten at austin.ibm.com>
+
 * Fri Feb 10 2006 Jesse Keating <jkeating at redhat.com> - 0.6.4-1.1
 - bump again for double-long bug on ppc(64)
 




More information about the fedora-cvs-commits mailing list