summaryrefslogtreecommitdiffstats
path: root/lib/libipsec
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2001-06-11 12:39:29 +0000
committerume <ume@FreeBSD.org>2001-06-11 12:39:29 +0000
commit832f8d224926758a9ae0b23a6b45353e44fbc87a (patch)
treea79fc7ad2b97862c4a404f352f0211ad93a7b5f1 /lib/libipsec
parent2693854b01a52b0395a91322aa3edf926bddff38 (diff)
downloadFreeBSD-src-832f8d224926758a9ae0b23a6b45353e44fbc87a.zip
FreeBSD-src-832f8d224926758a9ae0b23a6b45353e44fbc87a.tar.gz
Sync with recent KAME.
This work was based on kame-20010528-freebsd43-snap.tgz and some critical problem after the snap was out were fixed. There are many many changes since last KAME merge. TODO: - The definitions of SADB_* in sys/net/pfkeyv2.h are still different from RFC2407/IANA assignment because of binary compatibility issue. It should be fixed under 5-CURRENT. - ip6po_m member of struct ip6_pktopts is no longer used. But, it is still there because of binary compatibility issue. It should be removed under 5-CURRENT. Reviewed by: itojun Obtained from: KAME MFC after: 3 weeks
Diffstat (limited to 'lib/libipsec')
-rw-r--r--lib/libipsec/ipsec_set_policy.337
-rw-r--r--lib/libipsec/ipsec_strerror.327
-rw-r--r--lib/libipsec/ipsec_strerror.c8
-rw-r--r--lib/libipsec/ipsec_strerror.h4
-rw-r--r--lib/libipsec/libpfkey.h15
-rw-r--r--lib/libipsec/pfkey.c767
-rw-r--r--lib/libipsec/pfkey_dump.c134
-rw-r--r--lib/libipsec/policy_token.l4
-rw-r--r--lib/libipsec/test-policy.c27
9 files changed, 827 insertions, 196 deletions
diff --git a/lib/libipsec/ipsec_set_policy.3 b/lib/libipsec/ipsec_set_policy.3
index 7b71c53..bb27a5b 100644
--- a/lib/libipsec/ipsec_set_policy.3
+++ b/lib/libipsec/ipsec_set_policy.3
@@ -1,7 +1,7 @@
-.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+.\" $KAME: ipsec_set_policy.3,v 1.14 2001/04/06 07:00:46 itojun Exp $
.\" $FreeBSD$
-.\" $KAME: ipsec_set_policy.3,v 1.10 2000/05/07 05:25:03 itojun Exp $
.\"
+.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -92,7 +92,7 @@ It is caller's responsibility to reclaim the region, by using
.Fa policy
is formatted as either of the following:
.Bl -tag -width "discard"
-.It Ar direction Li entrust
+.It Ar direction Li discard
.Ar direction
must be
.Li in
@@ -100,6 +100,10 @@ or
.Li out .
.Ar direction
specifies which direction the policy needs to be applied.
+With
+.Li discard
+policy, packets will be dropped if they match the policy.
+.It Ar direction Li entrust
.Li entrust
means to consult to SPD defined by
.Xr setkey 8 .
@@ -164,6 +168,15 @@ and
.Ar src
is the other node
.Pq peer .
+If
+.Ar mode
+is
+.Li transport ,
+Both
+.Ar src
+and
+.Ar dst
+can be omited.
.Pp
.Ar level
must be set to one of the following:
@@ -222,7 +235,8 @@ Note that there is a bit difference of specification from
.Xr setkey 8 .
In specification by
.Xr setkey 8 ,
-both entrust and bypass are not used. Refer to
+both entrust and bypass are not used.
+Refer to
.Xr setkey 8
for detail.
.Pp
@@ -230,12 +244,11 @@ Here are several examples
.Pq long lines are wrapped for readability :
.Bd -literal -offset indent
in discard
-out ipsec esp/transport/10.1.1.1-10.1.1.2/require
-in ipsec ah/transport/10.1.1.2-10.1.1.1/require
-out ipsec esp/transport/10.1.1.2-10.1.1.1/use
- ah/tunnel/10.1.1.2-10.1.1.1/unique:1000
-in ipsec ipcomp/transport/10.1.1.2-10.1.1.1/use
- esp/transport/10.1.1.2-10.1.1.1/use
+out ipsec esp/transport//require
+in ipsec ah/transport//require
+out ipsec esp/tunnel/10.1.1.2-10.1.1.1/use
+in ipsec ipcomp/transport//use
+ esp/transport//use
.Ed
.Sh RETURN VALUES
.Fn ipsec_set_policy
@@ -255,3 +268,7 @@ on errors.
.Xr setkey 8
.Sh HISTORY
The functions first appeared in WIDE/KAME IPv6 protocol stack kit.
+.Pp
+IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
+was initially integrated into
+.Fx 4.0
diff --git a/lib/libipsec/ipsec_strerror.3 b/lib/libipsec/ipsec_strerror.3
index 66ae950..82fa99c 100644
--- a/lib/libipsec/ipsec_strerror.3
+++ b/lib/libipsec/ipsec_strerror.3
@@ -1,7 +1,7 @@
-.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+.\" $KAME: ipsec_strerror.3,v 1.8 2000/11/20 00:35:14 sakane Exp $
.\" $FreeBSD$
-.\" $KAME: ipsec_strerror.3,v 1.6 2000/05/07 05:25:03 itojun Exp $
.\"
+.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -34,24 +34,23 @@
.\"
.Sh NAME
.Nm ipsec_strerror
-.Nd error code for IPsec policy manipulation library
+.Nd error message for IPsec policy manipulation library
.\"
.Sh SYNOPSIS
.Fd #include <netinet6/ipsec.h>
-.Ft "char *"
+.Ft "const char *"
.Fn ipsec_strerror
.\"
.Sh DESCRIPTION
.Pa netinet6/ipsec.h
declares
-.Bd -ragged -offset indent
-.Vt extern int ipsec_errcode ;
-.Ed
.Pp
-which is used to pass error code from IPsec policy manipulation library
-to user program.
+.Dl extern int ipsec_errcode;
+.Pp
+which is used to pass an error code from IPsec policy manipulation library
+to an user program.
.Fn ipsec_strerror
-can be used to obtain error message string for the error code.
+can be used to obtain the error message string for the error code.
.Pp
The array pointed to is not to be modified by the program.
Since
@@ -75,7 +74,9 @@ The C string must not be overwritten by user programs.
.Xr ipsec_set_policy 3
.\"
.Sh HISTORY
-The functions first appeared in WIDE/KAME IPv6 protocol stack kit.
+.Fn ipsec_strerror
+first appeared in WIDE/KAME IPv6 protocol stack kit.
.\"
-.\" .Sh BUGS
-.\" (to be written)
+.Sh BUGS
+.Fn ipsec_strerror
+will return its result which may be overwritten by subsequent calls.
diff --git a/lib/libipsec/ipsec_strerror.c b/lib/libipsec/ipsec_strerror.c
index 1cf4e4c..d53a9e3 100644
--- a/lib/libipsec/ipsec_strerror.c
+++ b/lib/libipsec/ipsec_strerror.c
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $KAME: ipsec_strerror.c,v 1.6 2000/05/07 05:25:03 itojun Exp $ */
+/* $KAME: ipsec_strerror.c,v 1.7 2000/07/30 00:45:12 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@@ -40,7 +40,7 @@
int __ipsec_errcode;
-static char *ipsec_errlist[] = {
+static const char *ipsec_errlist[] = {
"Success", /*EIPSEC_NO_ERROR*/
"Not supported", /*EIPSEC_NOT_SUPPORTED*/
"Invalid argument", /*EIPSEC_INVAL_ARGUMENT*/
@@ -71,7 +71,7 @@ NULL, /*EIPSEC_SYSTEM_ERROR*/
"Unknown error", /*EIPSEC_MAX*/
};
-char *ipsec_strerror(void)
+const char *ipsec_strerror(void)
{
if (__ipsec_errcode < 0 || __ipsec_errcode > EIPSEC_MAX)
__ipsec_errcode = EIPSEC_MAX;
@@ -79,7 +79,7 @@ char *ipsec_strerror(void)
return ipsec_errlist[__ipsec_errcode];
}
-void __ipsec_set_strerror(char *str)
+void __ipsec_set_strerror(const char *str)
{
__ipsec_errcode = EIPSEC_SYSTEM_ERROR;
ipsec_errlist[EIPSEC_SYSTEM_ERROR] = str;
diff --git a/lib/libipsec/ipsec_strerror.h b/lib/libipsec/ipsec_strerror.h
index 02448cd..24d4199 100644
--- a/lib/libipsec/ipsec_strerror.h
+++ b/lib/libipsec/ipsec_strerror.h
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $KAME: ipsec_strerror.h,v 1.7 2000/05/07 05:25:03 itojun Exp $ */
+/* $KAME: ipsec_strerror.h,v 1.8 2000/07/30 00:45:12 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@@ -31,7 +31,7 @@
*/
extern int __ipsec_errcode;
-extern void __ipsec_set_strerror __P((char *));
+extern void __ipsec_set_strerror __P((const char *));
#define EIPSEC_NO_ERROR 0 /*success*/
#define EIPSEC_NOT_SUPPORTED 1 /*not supported*/
diff --git a/lib/libipsec/libpfkey.h b/lib/libipsec/libpfkey.h
index ad87700..1f25a30 100644
--- a/lib/libipsec/libpfkey.h
+++ b/lib/libipsec/libpfkey.h
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $KAME: libpfkey.h,v 1.1 2000/06/08 21:28:32 itojun Exp $ */
+/* $KAME: libpfkey.h,v 1.6 2001/03/05 18:22:17 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -30,11 +30,15 @@
* SUCH DAMAGE.
*/
+struct sadb_msg;
extern void pfkey_sadump __P((struct sadb_msg *));
extern void pfkey_spdump __P((struct sadb_msg *));
struct sockaddr;
+struct sadb_alg;
int ipsec_check_keylen __P((u_int, u_int, u_int));
+int ipsec_check_keylen2 __P((u_int, u_int, u_int));
+int ipsec_get_keylen __P((u_int, u_int, struct sadb_alg *));
u_int pfkey_set_softrate __P((u_int, u_int));
u_int pfkey_get_softrate __P((u_int));
int pfkey_send_getspi __P((int, u_int, u_int, struct sockaddr *,
@@ -49,17 +53,26 @@ int pfkey_send_add __P((int, u_int, u_int, struct sockaddr *,
u_int64_t, u_int64_t, u_int32_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,
+ struct sockaddr *, struct sockaddr *));
int pfkey_send_get __P((int, u_int, u_int,
struct sockaddr *, struct sockaddr *, u_int32_t));
int pfkey_send_register __P((int, u_int));
int pfkey_recv_register __P((int));
+int pfkey_set_supported __P((struct sadb_msg *, int));
int pfkey_send_flush __P((int, u_int));
int pfkey_send_dump __P((int, u_int));
int pfkey_send_promisc_toggle __P((int, int));
int pfkey_send_spdadd __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
+int pfkey_send_spdadd2 __P((int, struct sockaddr *, u_int,
+ struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
+ caddr_t, int, u_int32_t));
int pfkey_send_spdupdate __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
+int pfkey_send_spdupdate2 __P((int, struct sockaddr *, u_int,
+ struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
+ caddr_t, int, u_int32_t));
int pfkey_send_spddelete __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
int pfkey_send_spddelete2 __P((int, u_int32_t));
diff --git a/lib/libipsec/pfkey.c b/lib/libipsec/pfkey.c
index 11b6722..6cdea34 100644
--- a/lib/libipsec/pfkey.c
+++ b/lib/libipsec/pfkey.c
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $KAME: pfkey.c,v 1.31 2000/06/10 14:17:43 sakane Exp $ */
+/* $KAME: pfkey.c,v 1.39 2001/03/05 18:22:17 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@@ -42,12 +42,16 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
+#include <stdio.h>
#include "ipsec_strerror.h"
#include "libpfkey.h"
#define CALLOC(size, cast) (cast)calloc(1, (size))
+static int findsupportedmap __P((int));
+static int setsupportedmap __P((struct sadb_supported *));
+static struct sadb_alg *findsupportedalg __P((u_int, u_int));
static int pfkey_send_x1 __P((int, u_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_int32_t,
@@ -56,94 +60,215 @@ 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));
static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int,
- struct sockaddr *, u_int, u_int, char *, int, u_int32_t));
+ struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
+ char *, int, u_int32_t));
static int pfkey_send_x5 __P((int, u_int, u_int32_t));
-static caddr_t pfkey_setsadbmsg __P((caddr_t, u_int, u_int,
+static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int,
u_int, u_int32_t, pid_t));
-static caddr_t pfkey_setsadbsa __P((caddr_t, u_int32_t, u_int,
+static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int,
u_int, u_int, u_int32_t));
-static caddr_t pfkey_setsadbaddr __P((caddr_t, u_int,
+static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int,
struct sockaddr *, u_int, u_int));
-static caddr_t pfkey_setsadbkey __P((caddr_t, u_int, caddr_t, u_int));
-static caddr_t pfkey_setsadblifetime __P((caddr_t, u_int, u_int32_t, u_int32_t,
- u_int32_t, u_int32_t));
-static caddr_t pfkey_setsadbxsa2 __P((caddr_t, u_int32_t, u_int32_t));
+static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int));
+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));
+
+/*
+ * make and search supported algorithm structure.
+ */
+static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, };
+
+static int supported_map[] = {
+ SADB_SATYPE_AH,
+ SADB_SATYPE_ESP,
+ SADB_X_SATYPE_IPCOMP,
+};
+
+static int
+findsupportedmap(satype)
+ int satype;
+{
+ int i;
+
+ for (i = 0; i < sizeof(supported_map)/sizeof(supported_map[0]); i++)
+ if (supported_map[i] == satype)
+ return i;
+ return -1;
+}
+
+static struct sadb_alg *
+findsupportedalg(satype, alg_id)
+ u_int satype, alg_id;
+{
+ int algno;
+ int tlen;
+ caddr_t p;
+
+ /* validity check */
+ algno = findsupportedmap(satype);
+ if (algno == -1) {
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ return NULL;
+ }
+ if (ipsec_supported[algno] == NULL) {
+ __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST;
+ return NULL;
+ }
+
+ tlen = ipsec_supported[algno]->sadb_supported_len
+ - sizeof(struct sadb_supported);
+ p = (caddr_t)(ipsec_supported[algno] + 1);
+ while (tlen > 0) {
+ if (tlen < sizeof(struct sadb_alg)) {
+ /* invalid format */
+ break;
+ }
+ if (((struct sadb_alg *)p)->sadb_alg_id == alg_id)
+ return (struct sadb_alg *)p;
+
+ tlen -= sizeof(struct sadb_alg);
+ p += sizeof(struct sadb_alg);
+ }
+
+ __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
+ return NULL;
+}
+
+static int
+setsupportedmap(sup)
+ struct sadb_supported *sup;
+{
+ struct sadb_supported **ipsup;
+
+ switch (sup->sadb_supported_exttype) {
+ case SADB_EXT_SUPPORTED_AUTH:
+ ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_AH)];
+ break;
+ case SADB_EXT_SUPPORTED_ENCRYPT:
+ ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_ESP)];
+ break;
+ default:
+ __ipsec_errcode = EIPSEC_INVAL_SATYPE;
+ return -1;
+ }
+
+ if (*ipsup)
+ free(*ipsup);
+
+ *ipsup = malloc(sup->sadb_supported_len);
+ if (!*ipsup) {
+ __ipsec_set_strerror(strerror(errno));
+ return -1;
+ }
+ memcpy(*ipsup, sup, sup->sadb_supported_len);
+
+ return 0;
+}
/*
* check key length against algorithm specified.
- * supported is either SADB_EXT_SUPPORTED_ENCRYPT or SADB_EXT_SUPPORTED_AUTH.
- * Refer to keyv2.h to get more info.
+ * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the
+ * augument, and only calls to ipsec_check_keylen2();
* keylen is the unit of bit.
* OUT:
* -1: invalid.
* 0: valid.
*/
-struct sadb_msg *ipsec_supported = NULL;
-
int
ipsec_check_keylen(supported, alg_id, keylen)
u_int supported;
u_int alg_id;
u_int keylen;
{
- u_int tlen;
- caddr_t p;
- struct sadb_supported *sup;
- struct sadb_alg *alg;
+ int satype;
/* validity check */
- if (ipsec_supported == NULL) {
- __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST;
- return -1;
- }
switch (supported) {
case SADB_EXT_SUPPORTED_AUTH:
+ satype = SADB_SATYPE_AH;
+ break;
case SADB_EXT_SUPPORTED_ENCRYPT:
+ satype = SADB_SATYPE_ESP;
break;
default:
__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
- tlen = ipsec_supported->sadb_msg_len - sizeof(struct sadb_msg);
- p = (caddr_t)ipsec_supported + sizeof(struct sadb_msg);
+ return ipsec_check_keylen2(satype, alg_id, keylen);
+}
- for (;
- tlen > 0;
- tlen -= sup->sadb_supported_len, p += sup->sadb_supported_len) {
+/*
+ * check key length against algorithm specified.
+ * satype is one of satype defined at pfkeyv2.h.
+ * keylen is the unit of bit.
+ * OUT:
+ * -1: invalid.
+ * 0: valid.
+ */
+int
+ipsec_check_keylen2(satype, alg_id, keylen)
+ u_int satype;
+ u_int alg_id;
+ u_int keylen;
+{
+ struct sadb_alg *alg;
- sup = (struct sadb_supported *)p;
+ alg = findsupportedalg(satype, alg_id);
+ if (!alg)
+ return -1;
- if (sup->sadb_supported_exttype != supported)
- continue;
+ if (keylen < alg->sadb_alg_minbits || keylen > alg->sadb_alg_maxbits) {
+ __ipsec_errcode = EIPSEC_INVAL_KEYLEN;
+ return -1;
+ }
- {
- u_int ttlen = sup->sadb_supported_len;
- caddr_t pp = p + sizeof(*sup);
+ __ipsec_errcode = EIPSEC_NO_ERROR;
+ return 0;
+}
- for (;
- ttlen > 0;
- ttlen -= sizeof(*alg), pp += sizeof(*alg)) {
- alg = (struct sadb_alg *)pp;
+/*
+ * get max/min key length against algorithm specified.
+ * satype is one of satype defined at pfkeyv2.h.
+ * keylen is the unit of bit.
+ * OUT:
+ * -1: invalid.
+ * 0: valid.
+ */
+int
+ipsec_get_keylen(supported, alg_id, alg0)
+ u_int supported, alg_id;
+ struct sadb_alg *alg0;
+{
+ struct sadb_alg *alg;
+ u_int satype;
- if (alg->sadb_alg_id == alg_id)
- goto found;
- }
- }
+ /* validity check */
+ if (!alg0) {
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ return -1;
}
- __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
- return -1;
- /* NOTREACHED */
-
- found:
- if (keylen < alg->sadb_alg_minbits
- || keylen > alg->sadb_alg_maxbits) {
- __ipsec_errcode = EIPSEC_INVAL_KEYLEN;
+ switch (supported) {
+ case SADB_EXT_SUPPORTED_AUTH:
+ satype = SADB_SATYPE_AH;
+ break;
+ case SADB_EXT_SUPPORTED_ENCRYPT:
+ satype = SADB_SATYPE_ESP;
+ break;
+ default:
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
+ alg = findsupportedalg(satype, alg_id);
+ if (!alg)
+ return -1;
+
+ memcpy(alg0, alg, sizeof(*alg0));
+
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
@@ -221,6 +346,7 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
u_int32_t min, max, reqid, seq;
{
struct sadb_msg *newmsg;
+ caddr_t ep;
int len;
int need_spirange = 0;
caddr_t p;
@@ -268,31 +394,59 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
__ipsec_set_strerror(strerror(errno));
return -1;
}
+ ep = ((caddr_t)newmsg) + len;
- p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_GETSPI,
- len, satype, seq, getpid());
+ p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_GETSPI,
+ len, satype, seq, getpid());
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
- p = pfkey_setsadbxsa2(p, mode, reqid);
+ p = pfkey_setsadbxsa2(p, ep, mode, reqid);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
/* set sadb_address for source */
- p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen,
+ p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
IPSEC_ULPROTO_ANY);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
/* set sadb_address for destination */
- p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen,
+ p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
IPSEC_ULPROTO_ANY);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
/* proccessing spi range */
if (need_spirange) {
- int _len = sizeof(struct sadb_spirange);
+ struct sadb_spirange spirange;
-#define _SADB_SPIRANGE(p) ((struct sadb_spirange *)(p))
- _SADB_SPIRANGE(p)->sadb_spirange_len = PFKEY_UNIT64(_len);
- _SADB_SPIRANGE(p)->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
- _SADB_SPIRANGE(p)->sadb_spirange_min = min;
- _SADB_SPIRANGE(p)->sadb_spirange_max = max;
-#undef _SADB_SPIRANGE(p)
- p += _len;
+ if (p + sizeof(spirange) > ep) {
+ free(newmsg);
+ return -1;
+ }
+
+ memset(&spirange, 0, sizeof(spirange));
+ spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(spirange));
+ spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
+ spirange.sadb_spirange_min = min;
+ spirange.sadb_spirange_max = max;
+
+ memcpy(p, &spirange, sizeof(spirange));
+
+ p += sizeof(spirange);
+ }
+ if (p != ep) {
+ free(newmsg);
+ return -1;
}
/* send message */
@@ -389,6 +543,91 @@ pfkey_send_delete(so, satype, mode, src, dst, spi)
}
/*
+ * sending SADB_DELETE without spi to the kernel. This is
+ * the "delete all" request (an extension also present in
+ * Solaris).
+ *
+ * OUT:
+ * positive: success and return length sent
+ * -1 : error occured, and set errno
+ */
+int
+pfkey_send_delete_all(so, satype, mode, src, dst)
+ int so;
+ u_int satype, mode;
+ struct sockaddr *src, *dst;
+{
+ struct sadb_msg *newmsg;
+ int len;
+ caddr_t p;
+ int plen;
+ caddr_t ep;
+
+ /* validity check */
+ if (src == NULL || dst == NULL) {
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ return -1;
+ }
+ if (src->sa_family != dst->sa_family) {
+ __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
+ return -1;
+ }
+ switch (src->sa_family) {
+ case AF_INET:
+ plen = sizeof(struct in_addr) << 3;
+ break;
+ case AF_INET6:
+ plen = sizeof(struct in6_addr) << 3;
+ break;
+ default:
+ __ipsec_errcode = EIPSEC_INVAL_FAMILY;
+ return -1;
+ }
+
+ /* create new sadb_msg to reply. */
+ len = sizeof(struct sadb_msg)
+ + sizeof(struct sadb_address)
+ + PFKEY_ALIGN8(src->sa_len)
+ + sizeof(struct sadb_address)
+ + PFKEY_ALIGN8(dst->sa_len);
+
+ if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
+ __ipsec_set_strerror(strerror(errno));
+ return -1;
+ }
+ ep = ((caddr_t)newmsg) + len;
+
+ p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_DELETE, len, satype, 0,
+ getpid());
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
+ IPSEC_ULPROTO_ANY);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
+ IPSEC_ULPROTO_ANY);
+ if (!p || p != ep) {
+ free(newmsg);
+ return -1;
+ }
+
+ /* send message */
+ len = pfkey_send(so, newmsg, len);
+ free(newmsg);
+
+ if (len < 0)
+ return -1;
+
+ __ipsec_errcode = EIPSEC_NO_ERROR;
+ return len;
+}
+
+/*
* sending SADB_GET message to the kernel.
* OUT:
* positive: success and return length sent.
@@ -419,7 +658,29 @@ pfkey_send_register(so, satype)
int so;
u_int satype;
{
- int len;
+ int len, algno;
+
+ if (satype == PF_UNSPEC) {
+ for (algno = 0;
+ algno < sizeof(supported_map)/sizeof(supported_map[0]);
+ algno++) {
+ if (ipsec_supported[algno]) {
+ free(ipsec_supported[algno]);
+ ipsec_supported[algno] = NULL;
+ }
+ }
+ } else {
+ algno = findsupportedmap(satype);
+ if (algno == -1) {
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ return -1;
+ }
+
+ if (ipsec_supported[algno]) {
+ free(ipsec_supported[algno]);
+ ipsec_supported[algno] = NULL;
+ }
+ }
if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0)
return -1;
@@ -440,51 +701,92 @@ pfkey_recv_register(so)
{
pid_t pid = getpid();
struct sadb_msg *newmsg;
- struct sadb_supported *sup;
- caddr_t p;
- int tlen;
+ int error = -1;
/* receive message */
do {
if ((newmsg = pfkey_recv(so)) == NULL)
return -1;
-
} while (newmsg->sadb_msg_type != SADB_REGISTER
|| newmsg->sadb_msg_pid != pid);
/* check and fix */
newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len);
- tlen = newmsg->sadb_msg_len - sizeof(struct sadb_msg);
- p = (caddr_t)newmsg + sizeof(struct sadb_msg);
- while (tlen > 0) {
+ error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len);
+ free(newmsg);
+
+ if (error == 0)
+ __ipsec_errcode = EIPSEC_NO_ERROR;
+
+ return error;
+}
+
+/*
+ * receiving SADB_REGISTER message from the kernel, and copy buffer for
+ * sadb_supported returned into ipsec_supported.
+ * NOTE: sadb_msg_len must be host order.
+ * IN:
+ * tlen: msg length, it's to makeing sure.
+ * OUT:
+ * 0: success and return length sent.
+ * -1: error occured, and set errno.
+ */
+int
+pfkey_set_supported(msg, tlen)
+ struct sadb_msg *msg;
+ int tlen;
+{
+ struct sadb_supported *sup;
+ caddr_t p;
+ caddr_t ep;
+
+ /* validity */
+ if (msg->sadb_msg_len != tlen) {
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ return -1;
+ }
+
+ p = (caddr_t)msg;
+ ep = p + tlen;
+
+ p += sizeof(struct sadb_msg);
+
+ while (p < ep) {
sup = (struct sadb_supported *)p;
+ if (ep < p + sizeof(*sup) ||
+ PFKEY_EXTLEN(sup) < sizeof(*sup) ||
+ ep < p + sup->sadb_supported_len) {
+ /* invalid format */
+ break;
+ }
+
switch (sup->sadb_supported_exttype) {
case SADB_EXT_SUPPORTED_AUTH:
case SADB_EXT_SUPPORTED_ENCRYPT:
- sup->sadb_supported_len = PFKEY_EXTLEN(sup);
break;
default:
__ipsec_errcode = EIPSEC_INVAL_SATYPE;
- free(newmsg);
return -1;
}
- tlen -= sup->sadb_supported_len;
+ /* fixed length */
+ sup->sadb_supported_len = PFKEY_EXTLEN(sup);
+
+ /* set supported map */
+ if (setsupportedmap(sup) != 0)
+ return -1;
+
p += sup->sadb_supported_len;
}
- if (tlen < 0) {
+ if (p != ep) {
__ipsec_errcode = EIPSEC_INVAL_SATYPE;
return -1;
}
- if (ipsec_supported != NULL)
- free(ipsec_supported);
-
- ipsec_supported = newmsg;
-
__ipsec_errcode = EIPSEC_NO_ERROR;
+
return 0;
}
@@ -570,6 +872,35 @@ pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
src, prefs, dst, prefd, proto,
+ 0, 0,
+ policy, policylen, seq)) < 0)
+ return -1;
+
+ return len;
+}
+
+/*
+ * sending SADB_X_SPDADD message to the kernel.
+ * OUT:
+ * positive: success and return length sent.
+ * -1 : error occured, and set errno.
+ */
+int
+pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime,
+ policy, policylen, seq)
+ int so;
+ struct sockaddr *src, *dst;
+ u_int prefs, prefd, proto;
+ u_int64_t ltime, vtime;
+ caddr_t policy;
+ int policylen;
+ u_int32_t seq;
+{
+ int len;
+
+ if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
+ src, prefs, dst, prefd, proto,
+ ltime, vtime,
policy, policylen, seq)) < 0)
return -1;
@@ -595,6 +926,35 @@ pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
src, prefs, dst, prefd, proto,
+ 0, 0,
+ policy, policylen, seq)) < 0)
+ return -1;
+
+ return len;
+}
+
+/*
+ * sending SADB_X_SPDUPDATE message to the kernel.
+ * OUT:
+ * positive: success and return length sent.
+ * -1 : error occured, and set errno.
+ */
+int
+pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime,
+ policy, policylen, seq)
+ int so;
+ struct sockaddr *src, *dst;
+ u_int prefs, prefd, proto;
+ u_int64_t ltime, vtime;
+ caddr_t policy;
+ int policylen;
+ u_int32_t seq;
+{
+ int len;
+
+ if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
+ src, prefs, dst, prefd, proto,
+ ltime, vtime,
policy, policylen, seq)) < 0)
return -1;
@@ -625,6 +985,7 @@ pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE,
src, prefs, dst, prefd, proto,
+ 0, 0,
policy, policylen, seq)) < 0)
return -1;
@@ -693,6 +1054,7 @@ pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX,
src, prefs, dst, prefd, proto,
+ 0, 0,
policy, policylen, seq)) < 0)
return -1;
@@ -753,6 +1115,7 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
int len;
caddr_t p;
int plen;
+ caddr_t ep;
/* validity check */
if (src == NULL || dst == NULL) {
@@ -793,6 +1156,14 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
}
break;
case SADB_X_SATYPE_IPCOMP:
+ if (e_type == SADB_X_CALG_NONE) {
+ __ipsec_errcode = EIPSEC_INVAL_ALGS;
+ return -1;
+ }
+ if (a_type != SADB_AALG_NONE) {
+ __ipsec_errcode = EIPSEC_NO_ALGS;
+ return -1;
+ }
break;
default:
__ipsec_errcode = EIPSEC_INVAL_SATYPE;
@@ -819,28 +1190,67 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
__ipsec_set_strerror(strerror(errno));
return -1;
}
+ ep = ((caddr_t)newmsg) + len;
- p = pfkey_setsadbmsg((caddr_t)newmsg, type, len,
+ p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
satype, seq, getpid());
- p = pfkey_setsadbsa(p, spi, wsize, a_type, e_type, flags);
- p = pfkey_setsadbxsa2(p, mode, reqid);
- p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen,
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbxsa2(p, ep, mode, reqid);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
IPSEC_ULPROTO_ANY);
- p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen,
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
IPSEC_ULPROTO_ANY);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
- if (e_type != SADB_EALG_NONE)
- p = pfkey_setsadbkey(p, SADB_EXT_KEY_ENCRYPT,
+ if (e_type != SADB_EALG_NONE) {
+ p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT,
keymat, e_keylen);
- if (a_type != SADB_AALG_NONE)
- p = pfkey_setsadbkey(p, SADB_EXT_KEY_AUTH,
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ }
+ if (a_type != SADB_AALG_NONE) {
+ p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH,
keymat + e_keylen, a_keylen);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ }
/* set sadb_lifetime for destination */
- p = pfkey_setsadblifetime(p, SADB_EXT_LIFETIME_HARD,
+ p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
l_alloc, l_bytes, l_addtime, l_usetime);
- p = pfkey_setsadblifetime(p, SADB_EXT_LIFETIME_SOFT,
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT,
l_alloc, l_bytes, l_addtime, l_usetime);
+ if (!p || p != ep) {
+ free(newmsg);
+ return -1;
+ }
/* send message */
len = pfkey_send(so, newmsg, len);
@@ -865,6 +1275,7 @@ pfkey_send_x2(so, type, satype, mode, src, dst, spi)
int len;
caddr_t p;
int plen;
+ caddr_t ep;
/* validity check */
if (src == NULL || dst == NULL) {
@@ -899,13 +1310,31 @@ pfkey_send_x2(so, type, satype, mode, src, dst, spi)
__ipsec_set_strerror(strerror(errno));
return -1;
}
+ ep = ((caddr_t)newmsg) + len;
- p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, getpid());
- p = pfkey_setsadbsa(p, spi, 0, 0, 0, 0);
- p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen,
+ p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0,
+ getpid());
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
IPSEC_ULPROTO_ANY);
- p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen,
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
IPSEC_ULPROTO_ANY);
+ if (!p || p != ep) {
+ free(newmsg);
+ return -1;
+ }
/* send message */
len = pfkey_send(so, newmsg, len);
@@ -929,6 +1358,8 @@ pfkey_send_x3(so, type, satype)
{
struct sadb_msg *newmsg;
int len;
+ caddr_t p;
+ caddr_t ep;
/* validity check */
switch (type) {
@@ -958,8 +1389,14 @@ pfkey_send_x3(so, type, satype)
__ipsec_set_strerror(strerror(errno));
return -1;
}
+ ep = ((caddr_t)newmsg) + len;
- (void)pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, getpid());
+ p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0,
+ getpid());
+ if (!p || p != ep) {
+ free(newmsg);
+ return -1;
+ }
/* send message */
len = pfkey_send(so, newmsg, len);
@@ -974,10 +1411,12 @@ pfkey_send_x3(so, type, satype)
/* sending SADB_X_SPDADD message to the kernel */
static int
-pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, policy, policylen, seq)
+pfkey_send_x4(so, type, src, prefs, dst, prefd, proto,
+ ltime, vtime, policy, policylen, seq)
int so;
struct sockaddr *src, *dst;
u_int type, prefs, prefd, proto;
+ u_int64_t ltime, vtime;
char *policy;
int policylen;
u_int32_t seq;
@@ -986,6 +1425,7 @@ pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, policy, policylen, seq)
int len;
caddr_t p;
int plen;
+ caddr_t ep;
/* validity check */
if (src == NULL || dst == NULL) {
@@ -1019,25 +1459,37 @@ pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, policy, policylen, seq)
+ PFKEY_ALIGN8(src->sa_len)
+ sizeof(struct sadb_address)
+ PFKEY_ALIGN8(src->sa_len)
+ + sizeof(struct sadb_lifetime)
+ policylen;
if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
__ipsec_set_strerror(strerror(errno));
return -1;
}
+ ep = ((caddr_t)newmsg) + len;
- p = pfkey_setsadbmsg((caddr_t)newmsg, type, len,
- SADB_SATYPE_UNSPEC, seq, getpid());
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_SRC,
- src,
- prefs,
- proto);
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_DST,
- dst,
- prefd,
- proto);
+ p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
+ SADB_SATYPE_UNSPEC, seq, getpid());
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
+ 0, 0, ltime, vtime);
+ if (!p || p + policylen != ep) {
+ free(newmsg);
+ return -1;
+ }
memcpy(p, policy, policylen);
/* send message */
@@ -1062,6 +1514,7 @@ pfkey_send_x5(so, type, spid)
struct sadb_x_policy xpl;
int len;
caddr_t p;
+ caddr_t ep;
/* create new sadb_msg to reply. */
len = sizeof(struct sadb_msg)
@@ -1071,15 +1524,23 @@ pfkey_send_x5(so, type, spid)
__ipsec_set_strerror(strerror(errno));
return -1;
}
+ ep = ((caddr_t)newmsg) + len;
- p = pfkey_setsadbmsg((caddr_t)newmsg, type, len,
- SADB_SATYPE_UNSPEC, 0, getpid());
+ p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
+ SADB_SATYPE_UNSPEC, 0, getpid());
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ if (p + sizeof(xpl) != ep) {
+ free(newmsg);
+ return -1;
+ }
memset(&xpl, 0, sizeof(xpl));
xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl));
xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
xpl.sadb_x_policy_id = spid;
-
memcpy(p, &xpl, sizeof(xpl));
/* send message */
@@ -1143,6 +1604,8 @@ pfkey_close(so)
* OUT:
* NULL : error occured.
* others : a pointer to sadb_msg structure.
+ *
+ * XXX should be rewritten to pass length explicitly
*/
struct sadb_msg *
pfkey_recv(so)
@@ -1152,7 +1615,8 @@ pfkey_recv(so)
int len, reallen;
while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) {
- if (errno == EINTR) continue;
+ if (errno == EINTR)
+ continue;
__ipsec_set_strerror(strerror(errno));
return NULL;
}
@@ -1171,7 +1635,8 @@ pfkey_recv(so)
}
while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
- if (errno == EINTR) continue;
+ if (errno == EINTR)
+ continue;
__ipsec_set_strerror(strerror(errno));
free(newmsg);
return NULL;
@@ -1183,6 +1648,13 @@ pfkey_recv(so)
return NULL;
}
+ /* don't trust what the kernel says, validate! */
+ if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) {
+ __ipsec_errcode = EIPSEC_SYSTEM_ERROR;
+ free(newmsg);
+ return NULL;
+ }
+
__ipsec_errcode = EIPSEC_NO_ERROR;
return newmsg;
}
@@ -1219,6 +1691,8 @@ pfkey_send(so, msg, len)
* caddr_t mhp[SADB_EXT_MAX + 1];
* OUT: -1: invalid.
* 0: valid.
+ *
+ * XXX should be rewritten to obtain length explicitly
*/
int
pfkey_align(msg, mhp)
@@ -1226,8 +1700,9 @@ pfkey_align(msg, mhp)
caddr_t *mhp;
{
struct sadb_ext *ext;
- int tlen, extlen;
int i;
+ caddr_t p;
+ caddr_t ep; /* XXX should be passed from upper layer */
/* validity check */
if (msg == NULL || mhp == NULL) {
@@ -1241,10 +1716,21 @@ pfkey_align(msg, mhp)
mhp[0] = (caddr_t)msg;
- tlen = PFKEY_UNUNIT64(msg->sadb_msg_len) - sizeof(struct sadb_msg);
- ext = (struct sadb_ext *)((caddr_t)msg + sizeof(struct sadb_msg));
+ /* initialize */
+ p = (caddr_t) msg;
+ ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len);
+
+ /* skip base header */
+ p += sizeof(struct sadb_msg);
+
+ while (p < ep) {
+ ext = (struct sadb_ext *)p;
+ if (ep < p + sizeof(*ext) || PFKEY_EXTLEN(ext) < sizeof(*ext) ||
+ ep < p + PFKEY_EXTLEN(ext)) {
+ /* invalid format */
+ break;
+ }
- while (tlen > 0) {
/* duplicate check */
/* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
if (mhp[ext->sadb_ext_type] != NULL) {
@@ -1281,9 +1767,12 @@ pfkey_align(msg, mhp)
return -1;
}
- extlen = PFKEY_EXTLEN(ext);
- tlen -= extlen;
- ext = (struct sadb_ext *)((caddr_t)ext + extlen);
+ p += PFKEY_EXTLEN(ext);
+ }
+
+ if (p != ep) {
+ __ipsec_errcode = EIPSEC_INVAL_SADBMSG;
+ return -1;
}
__ipsec_errcode = EIPSEC_NO_ERROR;
@@ -1413,8 +1902,9 @@ pfkey_check(mhp)
* `buf' must has been allocated sufficiently.
*/
static caddr_t
-pfkey_setsadbmsg(buf, type, tlen, satype, seq, pid)
+pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid)
caddr_t buf;
+ caddr_t lim;
u_int type, satype;
u_int tlen;
u_int32_t seq;
@@ -1426,6 +1916,9 @@ pfkey_setsadbmsg(buf, type, tlen, satype, seq, pid)
p = (struct sadb_msg *)buf;
len = sizeof(struct sadb_msg);
+ if (buf + len > lim)
+ return NULL;
+
memset(p, 0, len);
p->sadb_msg_version = PF_KEY_V2;
p->sadb_msg_type = type;
@@ -1444,8 +1937,9 @@ pfkey_setsadbmsg(buf, type, tlen, satype, seq, pid)
* `buf' must has been allocated sufficiently.
*/
static caddr_t
-pfkey_setsadbsa(buf, spi, wsize, auth, enc, flags)
+pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
caddr_t buf;
+ caddr_t lim;
u_int32_t spi, flags;
u_int wsize, auth, enc;
{
@@ -1455,6 +1949,9 @@ pfkey_setsadbsa(buf, spi, wsize, auth, enc, flags)
p = (struct sadb_sa *)buf;
len = sizeof(struct sadb_sa);
+ if (buf + len > lim)
+ return NULL;
+
memset(p, 0, len);
p->sadb_sa_len = PFKEY_UNIT64(len);
p->sadb_sa_exttype = SADB_EXT_SA;
@@ -1474,8 +1971,9 @@ pfkey_setsadbsa(buf, spi, wsize, auth, enc, flags)
* prefixlen is in bits.
*/
static caddr_t
-pfkey_setsadbaddr(buf, exttype, saddr, prefixlen, ul_proto)
+pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto)
caddr_t buf;
+ caddr_t lim;
u_int exttype;
struct sockaddr *saddr;
u_int prefixlen;
@@ -1487,6 +1985,9 @@ pfkey_setsadbaddr(buf, exttype, saddr, prefixlen, ul_proto)
p = (struct sadb_address *)buf;
len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len);
+ if (buf + len > lim)
+ return NULL;
+
memset(p, 0, len);
p->sadb_address_len = PFKEY_UNIT64(len);
p->sadb_address_exttype = exttype & 0xffff;
@@ -1504,8 +2005,10 @@ pfkey_setsadbaddr(buf, exttype, saddr, prefixlen, ul_proto)
* OUT: the pointer of buf + len.
*/
static caddr_t
-pfkey_setsadbkey(buf, type, key, keylen)
- caddr_t buf, key;
+pfkey_setsadbkey(buf, lim, type, key, keylen)
+ caddr_t buf;
+ caddr_t lim;
+ caddr_t key;
u_int type, keylen;
{
struct sadb_key *p;
@@ -1514,6 +2017,9 @@ pfkey_setsadbkey(buf, type, key, keylen)
p = (struct sadb_key *)buf;
len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
+ if (buf + len > lim)
+ return NULL;
+
memset(p, 0, len);
p->sadb_key_len = PFKEY_UNIT64(len);
p->sadb_key_exttype = type;
@@ -1530,8 +2036,9 @@ pfkey_setsadbkey(buf, type, key, keylen)
* OUT: the pointer of buf + len.
*/
static caddr_t
-pfkey_setsadblifetime(buf, type, l_alloc, l_bytes, l_addtime, l_usetime)
+pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime)
caddr_t buf;
+ caddr_t lim;
u_int type;
u_int32_t l_alloc, l_bytes, l_addtime, l_usetime;
{
@@ -1541,6 +2048,9 @@ pfkey_setsadblifetime(buf, type, l_alloc, l_bytes, l_addtime, l_usetime)
p = (struct sadb_lifetime *)buf;
len = sizeof(struct sadb_lifetime);
+ if (buf + len > lim)
+ return NULL;
+
memset(p, 0, len);
p->sadb_lifetime_len = PFKEY_UNIT64(len);
p->sadb_lifetime_exttype = type;
@@ -1572,8 +2082,9 @@ pfkey_setsadblifetime(buf, type, l_alloc, l_bytes, l_addtime, l_usetime)
* `buf' must has been allocated sufficiently.
*/
static caddr_t
-pfkey_setsadbxsa2(buf, mode0, reqid)
+pfkey_setsadbxsa2(buf, lim, mode0, reqid)
caddr_t buf;
+ caddr_t lim;
u_int32_t mode0;
u_int32_t reqid;
{
@@ -1584,6 +2095,9 @@ pfkey_setsadbxsa2(buf, mode0, reqid)
p = (struct sadb_x_sa2 *)buf;
len = sizeof(struct sadb_x_sa2);
+ if (buf + len > lim)
+ return NULL;
+
memset(p, 0, len);
p->sadb_x_sa2_len = PFKEY_UNIT64(len);
p->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
@@ -1592,4 +2106,3 @@ pfkey_setsadbxsa2(buf, mode0, reqid)
return(buf + len);
}
-
diff --git a/lib/libipsec/pfkey_dump.c b/lib/libipsec/pfkey_dump.c
index 6408651..6c74bcd 100644
--- a/lib/libipsec/pfkey_dump.c
+++ b/lib/libipsec/pfkey_dump.c
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $KAME: pfkey_dump.c,v 1.19 2000/06/10 06:47:11 sakane Exp $ */
+/* $KAME: pfkey_dump.c,v 1.27 2001/03/12 09:03:38 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@@ -52,6 +52,29 @@
#include "ipsec_strerror.h"
#include "libpfkey.h"
+/* cope with old kame headers - ugly */
+#ifndef SADB_X_AALG_MD5
+#define SADB_X_AALG_MD5 SADB_AALG_MD5
+#endif
+#ifndef SADB_X_AALG_SHA
+#define SADB_X_AALG_SHA SADB_AALG_SHA
+#endif
+#ifndef SADB_X_AALG_NULL
+#define SADB_X_AALG_NULL SADB_AALG_NULL
+#endif
+
+#ifndef SADB_X_EALG_BLOWFISHCBC
+#define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
+#endif
+#ifndef SADB_X_EALG_CAST128CBC
+#define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
+#endif
+#ifndef SADB_X_EALG_RC5CBC
+#ifdef SADB_EALG_RC5CBC
+#define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
+#endif
+#endif
+
#define GETMSGSTR(str, num) \
do { \
if (sizeof((str)[0]) == 0 \
@@ -63,15 +86,33 @@ do { \
printf("%s ", (str)[(num)]); \
} while (0)
+#define GETMSGV2S(v2s, num) \
+do { \
+ struct val2str *p; \
+ for (p = (v2s); p && p->str; p++) { \
+ if (p->val == (num)) \
+ break; \
+ } \
+ if (p && p->str) \
+ printf("%s ", p->str); \
+ else \
+ printf("%d ", (num)); \
+} while (0)
+
static char *str_ipaddr __P((struct sockaddr *));
static char *str_prefport __P((u_int, u_int, u_int));
static char *str_time __P((time_t));
static void str_lifetime_byte __P((struct sadb_lifetime *, char *));
+struct val2str {
+ int val;
+ const char *str;
+};
+
/*
* Must to be re-written about following strings.
*/
-static char *_str_satype[] = {
+static char *str_satype[] = {
"unspec",
"unknown",
"ah",
@@ -84,13 +125,13 @@ static char *_str_satype[] = {
"ipcomp",
};
-static char *_str_mode[] = {
+static char *str_mode[] = {
"any",
"transport",
"tunnel",
};
-static char *_str_upper[] = {
+static char *str_upper[] = {
/*0*/ "ip", "icmp", "igmp", "ggp", "ip4",
"", "tcp", "", "egp", "",
/*10*/ "", "", "", "", "",
@@ -106,37 +147,57 @@ static char *_str_upper[] = {
/*60*/ "dst6",
};
-static char *_str_state[] = {
+static char *str_state[] = {
"larval",
"mature",
"dying",
"dead",
};
-static char *_str_alg_auth[] = {
- "none",
- "hmac-md5",
- "hmac-sha1",
- "md5",
- "sha",
- "null",
+static struct val2str str_alg_auth[] = {
+ { SADB_AALG_NONE, "none", },
+ { SADB_AALG_MD5HMAC, "hmac-md5", },
+ { SADB_AALG_SHA1HMAC, "hmac-sha1", },
+ { SADB_X_AALG_MD5, "md5", },
+ { SADB_X_AALG_SHA, "sha", },
+ { SADB_X_AALG_NULL, "null", },
+#ifdef SADB_X_AALG_SHA2_256
+ { SADB_X_AALG_SHA2_256, "hmac-sha2-256", },
+#endif
+#ifdef SADB_X_AALG_SHA2_384
+ { SADB_X_AALG_SHA2_384, "hmac-sha2-384", },
+#endif
+#ifdef SADB_X_AALG_SHA2_512
+ { SADB_X_AALG_SHA2_512, "hmac-sha2-512", },
+#endif
+ { -1, NULL, },
};
-static char *_str_alg_enc[] = {
- "none",
- "des-cbc",
- "3des-cbc",
- "null",
- "blowfish-cbc",
- "cast128-cbc",
- "rc5-cbc",
+static struct val2str str_alg_enc[] = {
+ { SADB_EALG_NONE, "none", },
+ { SADB_EALG_DESCBC, "des-cbc", },
+ { SADB_EALG_3DESCBC, "3des-cbc", },
+ { SADB_EALG_NULL, "null", },
+#ifdef SADB_X_EALG_RC5CBC
+ { SADB_X_EALG_RC5CBC, "rc5-cbc", },
+#endif
+ { SADB_X_EALG_CAST128CBC, "cast128-cbc", },
+ { SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", },
+#ifdef SADB_X_EALG_RIJNDAELCBC
+ { SADB_X_EALG_RIJNDAELCBC, "rijndael-cbc", },
+#endif
+#ifdef SADB_X_EALG_TWOFISHCBC
+ { SADB_X_EALG_TWOFISHCBC, "twofish-cbc", },
+#endif
+ { -1, NULL, },
};
-static char *_str_alg_comp[] = {
- "none",
- "oui",
- "deflate",
- "lzs",
+static struct val2str str_alg_comp[] = {
+ { SADB_X_CALG_NONE, "none", },
+ { SADB_X_CALG_OUI, "oui", },
+ { SADB_X_CALG_DEFLATE, "deflate", },
+ { SADB_X_CALG_LZS, "lzs", },
+ { -1, NULL, },
};
/*
@@ -204,10 +265,10 @@ pfkey_sadump(m)
}
printf("\n\t");
- GETMSGSTR(_str_satype, m->sadb_msg_satype);
+ GETMSGSTR(str_satype, m->sadb_msg_satype);
printf("mode=");
- GETMSGSTR(_str_mode, m_sa2->sadb_x_sa2_mode);
+ GETMSGSTR(str_mode, m_sa2->sadb_x_sa2_mode);
printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n",
(u_int32_t)ntohl(m_sa->sadb_sa_spi),
@@ -218,11 +279,11 @@ pfkey_sadump(m)
/* encryption key */
if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
printf("\tC: ");
- GETMSGSTR(_str_alg_comp, m_sa->sadb_sa_encrypt);
+ GETMSGV2S(str_alg_comp, m_sa->sadb_sa_encrypt);
} else if (m->sadb_msg_satype == SADB_SATYPE_ESP) {
if (m_enc != NULL) {
printf("\tE: ");
- GETMSGSTR(_str_alg_enc, m_sa->sadb_sa_encrypt);
+ GETMSGV2S(str_alg_enc, m_sa->sadb_sa_encrypt);
ipsec_hexdump((caddr_t)m_enc + sizeof(*m_enc),
m_enc->sadb_key_bits / 8);
printf("\n");
@@ -232,7 +293,7 @@ pfkey_sadump(m)
/* authentication key */
if (m_auth != NULL) {
printf("\tA: ");
- GETMSGSTR(_str_alg_auth, m_sa->sadb_sa_auth);
+ GETMSGV2S(str_alg_auth, m_sa->sadb_sa_auth);
ipsec_hexdump((caddr_t)m_auth + sizeof(*m_auth),
m_auth->sadb_key_bits / 8);
printf("\n");
@@ -245,7 +306,7 @@ pfkey_sadump(m)
/* state */
printf("state=");
- GETMSGSTR(_str_state, m_sa->sadb_sa_state);
+ GETMSGSTR(str_state, m_sa->sadb_sa_state);
printf("seq=%lu pid=%lu\n",
(u_long)m->sadb_msg_seq,
@@ -307,6 +368,7 @@ pfkey_spdump(m)
caddr_t mhp[SADB_EXT_MAX + 1];
struct sadb_address *m_saddr, *m_daddr;
struct sadb_x_policy *m_xpl;
+ struct sadb_lifetime *m_lft = NULL;
struct sockaddr *sa;
u_int16_t port;
@@ -323,6 +385,7 @@ pfkey_spdump(m)
m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
m_xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
+ m_lft = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
/* source address */
if (m_saddr == NULL) {
@@ -378,7 +441,7 @@ pfkey_spdump(m)
if (m_saddr->sadb_address_proto == IPSEC_ULPROTO_ANY)
printf("any");
else
- GETMSGSTR(_str_upper, m_saddr->sadb_address_proto);
+ GETMSGSTR(str_upper, m_saddr->sadb_address_proto);
/* policy */
{
@@ -395,6 +458,13 @@ pfkey_spdump(m)
free(d_xpl);
}
+ /* lifetime */
+ if (m_lft) {
+ printf("\tlifetime:%lu validtime:%lu\n",
+ (u_long)m_lft->sadb_lifetime_addtime,
+ (u_long)m_lft->sadb_lifetime_usetime);
+ }
+
printf("\tspid=%ld seq=%ld pid=%ld\n",
(u_long)m_xpl->sadb_x_policy_id,
(u_long)m->sadb_msg_seq,
diff --git a/lib/libipsec/policy_token.l b/lib/libipsec/policy_token.l
index 81d632b..91c89dc 100644
--- a/lib/libipsec/policy_token.l
+++ b/lib/libipsec/policy_token.l
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $KAME: policy_token.l,v 1.9 2000/05/07 05:25:03 itojun Exp $ */
+/* $KAME: policy_token.l,v 1.11 2000/12/01 10:08:29 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@@ -37,7 +37,6 @@
#include <net/route.h>
#include <net/pfkeyv2.h>
#include <netkey/keydb.h>
-#include <netkey/key_debug.h>
#include <netinet/in.h>
#include <netinet6/ipsec.h>
@@ -58,6 +57,7 @@ int yylex __P((void));
%}
%option noyywrap
+%option nounput
/* common section */
nl \n
diff --git a/lib/libipsec/test-policy.c b/lib/libipsec/test-policy.c
index 5a4faf5..960de20 100644
--- a/lib/libipsec/test-policy.c
+++ b/lib/libipsec/test-policy.c
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $KAME: test-policy.c,v 1.13 2000/05/07 05:25:03 itojun Exp $ */
+/* $KAME: test-policy.c,v 1.14 2000/12/27 11:38:11 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@@ -46,6 +46,8 @@
#include <errno.h>
#include <err.h>
+#include "libpfkey.h"
+
struct req_t {
int result; /* expected result; 0:ok 1:ng */
char *str;
@@ -111,9 +113,9 @@ test1()
result = test1sub1(&reqs[i]);
if (result == 0 && reqs[i].result == 1) {
- errx(1, "ERROR: expecting failure.\n");
+ warnx("ERROR: expecting failure.\n");
} else if (result == 1 && reqs[i].result == 0) {
- errx(1, "ERROR: expecting success.\n");
+ warnx("ERROR: expecting success.\n");
}
}
@@ -245,7 +247,8 @@ test2()
errx(1, "ERROR: %s\n", ipsec_strerror());
m = pfkey_recv(so);
free(m);
-
+
+#if 0
printf("spdsetidx()\n");
if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
@@ -262,6 +265,8 @@ test2()
m = pfkey_recv(so);
free(m);
+ sleep(4);
+
printf("spddelete()\n");
if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
@@ -283,19 +288,31 @@ test2()
m = pfkey_recv(so);
free(m);
+ sleep(4);
+
printf("spddelete2()\n");
if (pfkey_send_spddelete2(so, spid) < 0)
errx(1, "ERROR: %s\n", ipsec_strerror());
m = pfkey_recv(so);
free(m);
+#endif
+ printf("spdadd() with lifetime's 10(s)\n");
+ if (pfkey_send_spdadd2(so, (struct sockaddr *)addr, 128,
+ (struct sockaddr *)addr, 128,
+ 255, 0, 10, sp2, splen2, 0) < 0)
+ errx(1, "ERROR: %s\n", ipsec_strerror());
+ spid = test2sub(so);
+
+#if 0
/* expecting failure */
printf("spdupdate()\n");
if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
255, sp2, splen2, 0) == 0) {
- errx(1, "ERROR: expecting failure.\n");
+ warnx("ERROR: expecting failure.\n");
}
+#endif
return 0;
}
OpenPOWER on IntegriCloud