[redhat-lspp] improved racoon patch and instructions

Joy Latten latten at austin.ibm.com
Tue Sep 19 03:17:21 UTC 2006


I have found and fixed the bug that prevented racoon from 
establishing SAs that were not labeled. 

I have included additional instructions on how to configure
ipsec and racoon.

I consider this patch and its instructions an improvement
from that which I sent earlier this evening. Please use this
patch and these instructions. 

I will run a stress test with ipsec & racoon without labels tonight.
So far, test efforts have been to ensure regular ipsec behaviour has not
regressed.  I am running with mls policy in permissive on rawhide
kernel from last week, I believe. Tomorrow I will test with labels.

If you have any problems with this patch, please let me know.

Basic steps to use:

1. This patch is against ipsec-tools-0.6.5.3-1 source in latest rawhide.

2. To patch source:
	
install ipsec-tools-0.6.5.3-1.src.rpm
cd to /usr/src/redhat
rpmbuild -bp SPECS/ipsec-tools.spec
cd BUILD/ipsec-tools-0.6.5
patch -p1 < <patch.source>

3. To build ipsec-tools
./bootstrap
./configure
make

4. install new binary into /usr/local/sbin/racoon
cp src/racoon /usr/local/sbin/racoon

5.  See next step if you would like info on configuring racoon.
    You must configure before running.
    To run new racoon, you must also specify location of config
    file since we did not build with redhat default of /etc/racoon.
	/usr/local/sbin/racoon -f /etc/racoon/racoon.conf

6. Some config info:
   You must first add policies to the policy database in order for racoon
   to know to establish SAs for a particular traffic stream.
   For example:
	in the file /tmp/setkey.nolabel I have the following info
	to create policies without labels.

	spdadd 10.1.0.55 10.1.0.206 any  -P in ipsec
        esp/transport//require;

	spdadd 10.1.0.206 10.1.0.55 any -P out ipsec
        esp/transport//require;


OR	in the file /tmp/setkey.label I have the following info
	to create policy with labels.

	spdadd 10.1.0.55 10.1.0.206 any 
	-ctx 1 1 "system_u:object_r:unlabeled_t:s0:c0"
	-P in ipsec
        esp/transport//require;

	spdadd 9.3.192.206 9.3.189.55 any
	-ctx 1 1 "system_u:object_r:unlabeled_t:s0:c0"
	-P out ipsec
        esp/transport//require;

  
NEXT
   run "setkey -f /tmp/setkey.nolabel" to add policy without labels
	OR
   run "setkey -f /tmp/setkey.label" to add  policy with a label.


NEXT
   Now you need to configure racoon. For a simple config,
   I use pre-shared keys with a very basic racoon configuration.
   The two files i will use are psk.txt for preshared keys and
   racoon's basic config file, racoon.conf.
   For example:
	I first add the following to /etc/racoon/psk.txt,
	(please add whatever text you want for your shared
	secret key. In this example, I used "flibbertigibbet".)

	10.1.0.55    flibbertigibbet
	10.1.0.206   flibbertigibbet

   In /etc/racoon/racoon.conf, I pretty much use the defaults.
   I have the following in my /etc/racoon/racoon.conf:

	path include "/etc/racoon";
	path pre_shared_key "/etc/racoon/psk.txt";
	path certificate "/etc/racoon/certs";

	remote anonymous
	{
        	exchange_mode main,aggressive;
        	doi ipsec_doi;

        	nonce_size 16;
        	lifetime time 24 hour;

        	proposal_check obey;
        	proposal {
                	encryption_algorithm 3des;
                	hash_algorithm sha1;
                	authentication_method pre_shared_key;
                	dh_group 2;
        	}
	}

	sainfo anonymous
	{
        	pfs_group 2;
        	lifetime time 6 hour ;
        	encryption_algorithm 3des, aes ;
        	authentication_algorithm hmac_sha1, hmac_md5 ;
        	compression_algorithm deflate ;
	}


NEXT
	You can now start racoon daemon. On command line issue,
		/usr/local/sbin/racoon -f /etc/racoon/racoon.conf


NOTE: To stop racoon daemon, do "kill <racoon's pid>.
This will remove the SAs from the kernel. 
"setkey -FP" will remove the policy from the kernel.


This should do it. Let me know if you have any problems.

Regards,
Joy Latten

---------------------------------------------------------------------------


diff -urpN ipsec-tools-0.6.5.orig/configure.ac ipsec-tools-0.6.5.0918/configure.ac
--- ipsec-tools-0.6.5.orig/configure.ac	2006-08-22 00:49:52.000000000 -0500
+++ ipsec-tools-0.6.5.0918/configure.ac	2006-09-18 03:29:40.000000000 -0500
@@ -620,6 +620,7 @@ if test "$enable_security_context" = "ye
 		AC_DEFINE([HAVE_SECCTX], [], [Enable Security Context])
 		SECCTX_OBJS="security.o"
 		AC_SUBST(SECCTX_OBJS)
+		LIBS="$LIBS -lselinux"
 	fi
 fi
 
diff -urpN ipsec-tools-0.6.5.orig/src/racoon/cftoken.c ipsec-tools-0.6.5.0918/src/racoon/cftoken.c
--- ipsec-tools-0.6.5.orig/src/racoon/cftoken.c	2006-08-22 00:49:52.000000000 -0500
+++ ipsec-tools-0.6.5.0918/src/racoon/cftoken.c	2006-09-18 02:57:23.000000000 -0500
@@ -1363,6 +1363,7 @@ char *yytext;
 #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.orig/src/racoon/isakmp_quick.c ipsec-tools-0.6.5.0918/src/racoon/isakmp_quick.c
--- ipsec-tools-0.6.5.orig/src/racoon/isakmp_quick.c	2006-08-22 00:49:53.000000000 -0500
+++ ipsec-tools-0.6.5.0918/src/racoon/isakmp_quick.c	2006-09-18 02:47:16.000000000 -0500
@@ -2128,5 +2128,11 @@ get_proposal_r(iph2)
 		return ISAKMP_INTERNAL_ERROR;
 	}
 
+#ifdef HAVE_SECCTX
+	if (spidx.sec_ctx.ctx_str) {
+		set_secctx_in_proposal(iph2, spidx);
+	}
+#endif /* HAVE_SECCTX */
+
 	return 0;
 }
diff -urpN ipsec-tools-0.6.5.orig/src/racoon/pfkey.c ipsec-tools-0.6.5.0918/src/racoon/pfkey.c
--- ipsec-tools-0.6.5.orig/src/racoon/pfkey.c	2006-08-22 00:49:53.000000000 -0500
+++ ipsec-tools-0.6.5.0918/src/racoon/pfkey.c	2006-09-18 03:04:00.000000000 -0500
@@ -1672,6 +1672,10 @@ pk_recvacquire(mhp)
 	struct ph2handle *iph2[MAXNESTEDSA];
 	struct sockaddr *src, *dst;
 	int n;	/* # of phase 2 handler */
+#ifdef HAVE_SECCTX
+	struct sadb_x_sec_ctx *m_sec_ctx;
+#endif /* HAVE_SECCTX */
+	struct policyindex spidx;
 
 	/* ignore this message because of local test mode. */
 	if (f_local)
@@ -1691,6 +1695,24 @@ pk_recvacquire(mhp)
 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
+#ifdef HAVE_SECCTX 
+	m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+
+	if (m_sec_ctx != NULL) {
+		plog(LLV_INFO, LOCATION, NULL, 
+			"security context doi: %u\n",
+			m_sec_ctx->sadb_x_ctx_doi);
+		plog(LLV_INFO, LOCATION, NULL, 
+			"security context algorithm: %u\n",
+			m_sec_ctx->sadb_x_ctx_alg);
+		plog(LLV_INFO, LOCATION, NULL, 
+			"security context length: %u\n",
+			m_sec_ctx->sadb_x_ctx_len);
+		plog(LLV_INFO, LOCATION, NULL, "security context: %s\n",
+			((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)));
+	}
+#endif /* HAVE_SECCTX */
+
 	/* ignore if type is not IPSEC_POLICY_IPSEC */
 	if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
 		plog(LLV_DEBUG, LOCATION, NULL,
@@ -1778,7 +1800,6 @@ pk_recvacquire(mhp)
 
 	/* get inbound policy */
     {
-	struct policyindex spidx;
 
 	spidx.dir = IPSEC_DIR_INBOUND;
 	memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src));
@@ -1786,10 +1807,16 @@ 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));
+	if (m_sec_ctx) {
+		spidx.sec_ctx.ctx_doi = m_sec_ctx->sadb_x_ctx_doi;
+		spidx.sec_ctx.ctx_alg = m_sec_ctx->sadb_x_ctx_alg;
+		spidx.sec_ctx.ctx_strlen = m_sec_ctx->sadb_x_ctx_len;
+		memcpy(spidx.sec_ctx.ctx_str,
+  			((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)),
+			spidx.sec_ctx.ctx_strlen);
+	}
 #endif
 
 	sp_in = getsp(&spidx);
@@ -1877,6 +1904,12 @@ pk_recvacquire(mhp)
 		delph2(iph2[n]);
 		return -1;
 	}
+#ifdef HAVE_SECCTX
+	if (m_sec_ctx) {
+		set_secctx_in_proposal(iph2[n], spidx);
+	}
+#endif /* HAVE_SECCTX */
+
 	insph2(iph2[n]);
 
 	/* start isakmp initiation by using ident exchange */
diff -urpN ipsec-tools-0.6.5.orig/src/racoon/policy.c ipsec-tools-0.6.5.0918/src/racoon/policy.c
--- ipsec-tools-0.6.5.orig/src/racoon/policy.c	2006-08-22 00:49:53.000000000 -0500
+++ ipsec-tools-0.6.5.0918/src/racoon/policy.c	2006-09-18 02:47:16.000000000 -0500
@@ -206,9 +206,13 @@ cmpspidxstrict(a, b)
 #ifdef HAVE_SECCTX
 	if (a->sec_ctx.ctx_alg != b->sec_ctx.ctx_alg 
 	 || a->sec_ctx.ctx_doi != b->sec_ctx.ctx_doi
+#if 1
+	 || !within_range(a->sec_ctx.ctx_str, b->sec_ctx.ctx_str))
+#else
 	 || 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))
+#endif
 		return 1;
 #endif
 	return 0;
@@ -284,9 +288,13 @@ cmpspidxwild(a, b)
 #ifdef HAVE_SECCTX
 	if (a->sec_ctx.ctx_alg != b->sec_ctx.ctx_alg 
 	 || a->sec_ctx.ctx_doi != b->sec_ctx.ctx_doi
+#if 1
+	 || !within_range(a->sec_ctx.ctx_str, b->sec_ctx.ctx_str))
+#else
 	 || 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))
+#endif
 		return 1;
 #endif
 
diff -urpN ipsec-tools-0.6.5.orig/src/racoon/policy.h ipsec-tools-0.6.5.0918/src/racoon/policy.h
--- ipsec-tools-0.6.5.orig/src/racoon/policy.h	2006-08-22 00:49:53.000000000 -0500
+++ ipsec-tools-0.6.5.0918/src/racoon/policy.h	2006-09-18 03:05:08.000000000 -0500
@@ -35,6 +35,7 @@
 #include <sys/queue.h>
 
 #ifdef HAVE_SECCTX
+
 #define MAX_CTXSTR_SIZE 50
 struct security_ctx {
 	u_int8_t ctx_doi;	/* Security Context DOI */
@@ -146,6 +147,11 @@ extern void initsp __P((void));
 extern struct ipsecrequest *newipsecreq __P((void));
 
 extern const char *spidx2str __P((const struct policyindex *));
+#ifdef HAVE_SECCTX
+#include <selinux/selinux.h>
 extern int get_security_context __P((vchar_t *, struct policyindex *));
+extern int within_range __P((security_context_t, security_context_t));
+extern void set_secctx_in_proposal __P((struct ph2handle *, struct policyindex));
+#endif
 
 #endif /* _POLICY_H */
diff -urpN ipsec-tools-0.6.5.orig/src/racoon/proposal.c ipsec-tools-0.6.5.0918/src/racoon/proposal.c
--- ipsec-tools-0.6.5.orig/src/racoon/proposal.c	2006-08-22 00:49:53.000000000 -0500
+++ ipsec-tools-0.6.5.0918/src/racoon/proposal.c	2006-09-18 02:47:16.000000000 -0500
@@ -1025,15 +1025,6 @@ 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;
@@ -1196,7 +1187,11 @@ set_proposal_from_proposal(iph2)
 			pp0->sctx.ctx_strlen = pp_peer->sctx.ctx_strlen;
 			memcpy(pp0->sctx.ctx_str, pp_peer->sctx.ctx_str,
 				pp_peer->sctx.ctx_strlen);
+
+			plog(LLV_INFO, LOCATION, NULL,
+        		     "RESPONDING with (%s).\n", pp_peer->sctx.ctx_str);
 		}
+		
 #endif /* HAVE_SECCTX */
 		
 		if (pp_peer->next != NULL) {
diff -urpN ipsec-tools-0.6.5.orig/src/racoon/security.c ipsec-tools-0.6.5.0918/src/racoon/security.c
--- ipsec-tools-0.6.5.orig/src/racoon/security.c	2006-08-22 00:49:53.000000000 -0500
+++ ipsec-tools-0.6.5.0918/src/racoon/security.c	2006-09-18 10:58:37.000000000 -0500
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2005 International Business Machines Corporation
+ * Copyright (c) 2005 by Trusted Computer Solutions, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,6 +37,12 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <selinux/selinux.h>
+#include <selinux/flask.h>
+#include <selinux/av_permissions.h>
+#include <selinux/avc.h>
+#include <selinux/context.h>
+
 #include "var.h"
 #include "vmbuf.h"
 #include "misc.h"
@@ -45,6 +52,7 @@
 #include "isakmp.h"
 #include "ipsec_doi.h"
 #include "policy.h"
+#include "proposal.h"
 #include "strnames.h"
 #include "handler.h"
 
@@ -150,3 +158,112 @@ get_security_context(sa, p)
 	}
 	return 0;
 }
+
+void
+set_secctx_in_proposal(iph2, spidx)
+	struct ph2handle *iph2;
+	struct policyindex spidx;
+{
+	iph2->proposal->sctx.ctx_doi = spidx.sec_ctx.ctx_doi;
+	iph2->proposal->sctx.ctx_alg = spidx.sec_ctx.ctx_alg;
+	iph2->proposal->sctx.ctx_strlen = spidx.sec_ctx.ctx_strlen;
+		memcpy(iph2->proposal->sctx.ctx_str, spidx.sec_ctx.ctx_str,
+			spidx.sec_ctx.ctx_strlen);
+}
+
+
+/*
+ * function: 	init_avc
+ * description:	function performs the steps necessary to initialize the
+ *		userspace avc.
+ * input:	void
+ * return:	0	if avc was successfully initialized
+ * 		1	if the avc could not be initialized
+ */
+
+static int
+init_avc(void)
+{
+	int rtn = 0;
+
+	if (!is_selinux_mls_enabled()) {
+		plog(LLV_ERROR, LOCATION, NULL, "racoon: MLS support is not"
+				" enabled.\n");
+		return 1;
+	}
+
+	rtn = avc_init("racoon", NULL, NULL, NULL, NULL);
+	if (rtn != 0) {
+		plog(LLV_ERROR, LOCATION, NULL, "racoon: could not initialize avc.\n");
+		rtn = 1;
+	}
+	return rtn;
+}
+
+/*
+ * function: 	within_range
+ * description:	function determines if the specified sl is within the
+ * 		configured range for a policy rule.
+ * input:	security_context *sl		SL
+ * 		char *range		Range
+ * return:	1	if the sl is within the range
+ * 		0	if the sl is not within the range or an error
+ * 			occurred which prevented the determination
+ */
+
+int
+within_range(security_context_t sl, security_context_t range)
+{
+	int rtn = 1;
+	security_id_t slsid;
+	security_id_t rangesid;
+	struct av_decision avd;
+	security_class_t tclass;
+	access_vector_t av;
+
+	if (!*range)	/* This policy doesn't have security context */
+		return 1;
+
+	rtn = init_avc();
+	if (rtn != 0) {
+		plog(LLV_ERROR, LOCATION, NULL, 
+			"within_range: couldn't initialize the AVC\n");
+		return 0;
+	}
+
+	/*
+	 * Get the sids for the sl and range contexts
+	 */
+	rtn = avc_context_to_sid(sl, &slsid);
+	if (rtn != 0) {
+		plog(LLV_ERROR, LOCATION, NULL, 
+				"within_range: Unable to retrieve "
+				"sid for sl context (%s).\n", sl);
+		return 0;
+	}
+	rtn = avc_context_to_sid(range, &rangesid);
+	if (rtn != 0) {
+		plog(LLV_ERROR, LOCATION, NULL, 
+				"within_range: Unable to retrieve "
+				"sid for range context (%s).\n", range);
+		sidput(slsid);
+		return 0;
+	}
+
+	/* 
+	 * Straight up test between sl and range
+	 */
+	tclass = SECCLASS_ASSOCIATION;
+	av = ASSOCIATION__POLMATCH;
+	rtn = avc_has_perm(slsid, rangesid, tclass, av, NULL, &avd);
+	if (rtn != 0) {
+		plog(LLV_INFO, LOCATION, NULL, 
+			"within_range: The sl is not within range\n");
+		sidput(slsid);
+		sidput(rangesid);
+		return 0;
+	}
+	plog(LLV_DEBUG, LOCATION, NULL, 
+		"within_range: The sl (%s) is within range (%s)\n", sl, range);
+		return 1;
+}




More information about the redhat-lspp mailing list