Group :: Security/Networking
RPM: ipsec-tools
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: ipsec-tools-0.6.5-mls.patch
Download
Download
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;
+}