(racoon 742) [PATCH] setkey support for sadb_sens

Serge Hallyn <[email protected]> Wed, 15 Sep 2004 08:51:48 -0500
Newsgroups gmane.network.ipv6.kame.racoon
Message-ID <[email protected]>
Hi,

Attached please find a patch which implements support in setkey for the
PF_KEY sensitivity extension.  We have been using this with several
(patched) versions of linux.  If there are no fundamental objections to
adding this support, then we will of course also need to patch racoon.

An example setkey input is:

add 9.53.94.132 9.53.94.14 esp 0x123456
-sens dpd=1 senscat=59 senslvl=3 intcat=58 intlvl=4
-E null;
spdadd 9.53.94.132 9.53.94.14 any -P out ipsec
         esp/transport//require;

thanks,
-serge
-- 
=======================================================
Serge Hallyn
Security Software Engineer, IBM Linux Technology Center
[email protected]
kame-sens.diff (text/x-patch, 5.2 KB)
diff -Nru -p1 kame/kame/kame/libipsec/pfkey_dump.c kame-sens/kame/kame/libipsec/pfkey_dump.c
--- kame/kame/kame/libipsec/pfkey_dump.c	2003-09-08 05:14:56.000000000 -0500
+++ kame-sens/kame/kame/libipsec/pfkey_dump.c	2004-09-14 15:27:33.858371192 -0500
@@ -195,2 +195,22 @@ static struct val2str str_alg_comp[] = {
 
+/* print a 64-bit bitmap out as a binary number.
+ * str must be pre-allocced to 65 characters.
+ */
+void
+print_cats(unsigned long long bitmap, char *str)
+{
+	int i;
+	unsigned long long mask;
+
+	memset(str, 0, 65);
+	for (i=0; i<64; i++) {
+		mask = (unsigned long long)1 << i;
+		if (mask & bitmap)
+			*(str+i) = '1';
+		else
+			*(str+i) = '0';
+	}
+}
+
+
 /*
@@ -476,2 +496,18 @@ pfkey_spdump(m)
 
+	if (m_sens != NULL) {
+		char categories[65];
+		unsigned long long *sens_cat = (unsigned long long *)
+			((char *)m_sens+sizeof(struct sadb_sens));
+		unsigned long long *integ_cat = (unsigned long long *)
+			((char *)m_sens+sizeof(struct sadb_sens) +
+			 sizeof(unsigned long long));
+		printf("\tprotection domain: %u\n", m_sens->sadb_sens_dpd);
+		print_cats(*sens_cat, categories);
+		printf("\tsens categories:(%Lu)\n\t%s\n", *sens_cat, categories);
+		printf("\t\tsens level: %u\n", m_sens->sadb_sens_sens_level);
+		print_cats(*integ_cat, categories);
+		printf("\tintegrity categories:(%Lu)\n\t%s\n", *integ_cat, categories);
+		printf("\t\tinteg_level: %u\n", m_sens->sadb_sens_integ_level);
+		printf("\tsens reserved: %lu\n", m_sens->sadb_sens_reserved);
+	}
 
diff -Nru -p1 kame/kame/kame/setkey/parse.y kame-sens/kame/kame/setkey/parse.y
--- kame/kame/kame/setkey/parse.y	2004-06-18 12:38:24.000000000 -0500
+++ kame-sens/kame/kame/setkey/parse.y	2004-09-14 15:40:29.120513432 -0500
@@ -62,2 +62,10 @@ caddr_t p_key_enc, p_key_auth;
 time_t p_lt_hard, p_lt_soft;
+struct sens_struct {
+	uint32_t dpd;
+	uint64_t senscat;
+	uint8_t senslvl;
+	uint64_t intcat;
+	uint8_t intlvl;
+};
+struct sens_struct sens;
 
@@ -106,3 +114,3 @@ extern void yyerror __P((const char *));
 %token F_LIFETIME_HARD F_LIFETIME_SOFT
-%token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
+%token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY EQSTRING
 	/* SPD management */
@@ -112,2 +120,3 @@ extern void yyerror __P((const char *));
 %token TAGGED
+%token SENS
 
@@ -122,3 +131,4 @@ extern void yyerror __P((const char *));
 %type <val> policy_requests
-%type <val> QUOTEDSTRING HEXSTRING STRING
+%type <val> QUOTEDSTRING HEXSTRING STRING EQSTRING
+
 %type <val> F_AIFLAGS
@@ -488,2 +498,45 @@ extension
 	|	F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
+	|       SENS EQSTRING EQSTRING EQSTRING EQSTRING EQSTRING {
+		char *tok;
+
+		tok = strchr($2.buf, '=');
+		if (!tok || strncmp($2.buf, "dpd", 3)) {
+			yyerror("bad value for sensitivity dpd.\n");
+			return -1;
+		}
+		sens.dpd = strtoul(tok+1, NULL, 10);
+
+		tok = strchr($3.buf, '=');
+		if (!tok || strncmp($3.buf, "senscat", 7)) {
+			yyerror("bad value for sensitivity categories.\n");
+			return -1;
+		}
+		sens.senscat = strtoull(tok+1, NULL, 10);
+		printf("senscat is %s: %lu\n", tok+1, sens.senscat);
+
+		tok = strchr($4.buf, '=');
+		printf("senslvl buf is %s\n", $4.buf);
+		if (!tok || strncmp($4.buf, "senslvl", 7)) {
+			yyerror("bad value for sensitivity level.\n");
+			return -1;
+		}
+		sens.senslvl = strtoul(tok+1, NULL, 10);
+		printf("senslvl is %s: %lu\n", tok+1, sens.senslvl);
+
+		tok = strchr($5.buf, '=');
+		if (!tok || strncmp($5.buf, "intcat", 6)) {
+			yyerror("bad value for integrity categories.\n");
+			return -1;
+		}
+		sens.intcat = strtoull(tok+1, NULL, 10);
+		printf("intcat is %s: %lu\n", tok+1, sens.intcat);
+
+		tok = strchr($6.buf, '=');
+		if (!tok || strncmp($6.buf, "intlvl", 6)) {
+			yyerror("bad value for integrity level.\n");
+			return -1;
+		}
+		sens.intlvl = strtoul(tok+1, NULL, 10);
+	}
+
 	;
@@ -1117,2 +1170,25 @@ setkeymsg_add(type, satype, srcs, dsts)
 
+	/* Add sensitivity label */
+	{
+		struct sadb_sens m_sens;
+		u_int slen = sizeof(struct sadb_sens);
+
+		memset(&m_sens, 0, sizeof(struct sadb_sens));
+
+		m_sens.sadb_sens_len = PFKEY_UNIT64(slen + PFKEY_ALIGN8(2*sizeof(__u64)));
+		m_sens.sadb_sens_exttype = SADB_EXT_SENSITIVITY;
+
+		m_sens.sadb_sens_sens_level = sens.senslvl;
+		m_sens.sadb_sens_integ_level = sens.intlvl;
+		m_sens.sadb_sens_dpd = sens.dpd;
+		m_sens.sadb_sens_sens_len = 1;
+		m_sens.sadb_sens_integ_len = 1;
+
+		memcpy(buf+l, &m_sens, slen);
+		memcpy(buf+l+slen, &(sens.senscat), sizeof(__u64));
+		memcpy(buf+l+slen+sizeof(__u64), &(sens.intcat), sizeof(__u64));
+
+		l += PFKEY_ALIGN8(slen + 2*sizeof(__u64));
+	}
+
 	len = sizeof(struct sadb_sa);
@@ -1297,2 +1373,4 @@ parse_init()
 
+	memset(&sens, 0, sizeof(struct sens_struct));
+
 	p_aiflags = 0;
diff -Nru -p1 kame/kame/kame/setkey/token.l kame-sens/kame/kame/setkey/token.l
--- kame/kame/kame/setkey/token.l	2004-01-08 00:01:03.000000000 -0600
+++ kame-sens/kame/kame/setkey/token.l	2004-09-14 15:42:14.076557688 -0500
@@ -215,2 +215,3 @@ nocyclic-seq	{ return(NOCYCLICSEQ); }
 {hyphen}ls	{ return(F_LIFETIME_SOFT); }
+{hyphen}sens	{ return(SENS); }
 
@@ -228,2 +229,11 @@ any		{ return(ANY); }
 
++[a-z]+=[0-9]+	{
+			yylval.val.len = yyleng;
+			yylval.val.buf = strdup(yytext);
+			if (!yylval.val.buf)
+				yyfatal("insufficient memory");
+			return (EQSTRING);
+		}
+
+
 	/* parameter */