summaryrefslogtreecommitdiff
path: root/sbin/isakmpd
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>2000-10-16 23:26:21 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>2000-10-16 23:26:21 +0000
commit4d613ead133566d1737cd5762c80b4a3e82f8259 (patch)
treec82b6fb2596e263d7e4dd9cbb1091a1dbafb09c1 /sbin/isakmpd
parent1a2e8187b2eb660c984a2258104199be2beab5c1 (diff)
Merge with EOM 1.59
author: provos better referencing. okay niklas@ author: niklas Name collissions introduced by me, DOH! author: niklas Allow new and old style configuration simultaneously author: niklas Backward compatibility with old style configuration author: niklas remove redundant ifdefs author: niklas facistoid style and naming pedantery author: angelos Construct the ISAKMP-peer section such that it actually contains the src/dst Phase 1 IDs (so we don't have to worry about configuration conflicts). I should update the manpage.... author: angelos Use local-address, not listen-address. author: angelos First cut of ACQUIRE handling, fully functional but not entirely dynamic (it depends on the pre-defined Transforms and Suites). Nonetheless, it is possible to use isakmpd without a configuration file when using certificates for authentication. author: angelos Add RIPEMD negotiation/configuration.
Diffstat (limited to 'sbin/isakmpd')
-rw-r--r--sbin/isakmpd/pf_key_v2.c795
1 files changed, 670 insertions, 125 deletions
diff --git a/sbin/isakmpd/pf_key_v2.c b/sbin/isakmpd/pf_key_v2.c
index fee9dd06a9b..523d33220be 100644
--- a/sbin/isakmpd/pf_key_v2.c
+++ b/sbin/isakmpd/pf_key_v2.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pf_key_v2.c,v 1.32 2000/10/10 13:34:58 niklas Exp $ */
-/* $EOM: pf_key_v2.c,v 1.49 2000/10/10 13:30:26 niklas Exp $ */
+/* $OpenBSD: pf_key_v2.c,v 1.33 2000/10/16 23:26:20 niklas Exp $ */
+/* $EOM: pf_key_v2.c,v 1.59 2000/10/16 18:16:59 provos Exp $ */
/*
* Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved.
@@ -65,6 +65,14 @@
#include "timer.h"
#include "transport.h"
+#define IN6_IS_ADDR_FULL(a) \
+ ((*(u_int32_t *)(void *)(&(a)->s6_addr[0]) == 0xffff) \
+ && (*(u_int32_t *)(void *)(&(a)->s6_addr[4]) == 0xffff) \
+ && (*(u_int32_t *)(void *)(&(a)->s6_addr[8]) == 0xffff) \
+ && (*(u_int32_t *)(void *)(&(a)->s6_addr[12]) == 0xffff))
+
+#define ADDRESS_MAX sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"
+
/*
* PF_KEY v2 always work with 64-bit entities and aligns on 64-bit boundaries.
*/
@@ -89,6 +97,9 @@ TAILQ_HEAD (pf_key_v2_msg, pf_key_v2_node);
#define PF_KEY_V2_NODE_MALLOCED 1
#define PF_KEY_V2_NODE_MARK 2
+/* Used to derive "unique" connection identifiers */
+int connection_seq = 0;
+
#ifdef KAME
/*
* KAME requires the sadb_msg_seq of an UPDATE be the same of that of the
@@ -582,6 +593,7 @@ pf_key_v2_get_spi (size_t *sz, u_int8_t proto, struct sockaddr *src,
struct sadb_address *addr = 0;
struct sadb_spirange spirange;
struct pf_key_v2_msg *getspi = 0, *ret = 0;
+ struct pf_key_v2_node *ext;
u_int8_t *spi = 0;
int len, err;
#ifdef KAME
@@ -602,7 +614,7 @@ pf_key_v2_get_spi (size_t *sz, u_int8_t proto, struct sockaddr *src,
goto cleanup;
}
/*
- * XXX When we have acquires working, the sequence number have to be set
+ * XXX When we have acquires working, the sequence number has to be set
* from the acquire message.
*/
msg.sadb_msg_seq = 0;
@@ -611,9 +623,9 @@ pf_key_v2_get_spi (size_t *sz, u_int8_t proto, struct sockaddr *src,
goto cleanup;
#ifdef KAME
- memset(&ssa2, 0, sizeof(ssa2));
+ memset(&ssa2, 0, sizeof ssa2);
ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- ssa2.sadb_x_sa2_len = sizeof(ssa2) / PF_KEY_V2_CHUNK;
+ ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
ssa2.sadb_x_sa2_mode = 0;
if (pf_key_v2_msg_add (getspi, (struct sadb_ext *)&ssa2, 0) == -1)
goto cleanup;
@@ -681,12 +693,13 @@ pf_key_v2_get_spi (size_t *sz, u_int8_t proto, struct sockaddr *src,
goto cleanup;
}
- sa = (struct sadb_sa *)pf_key_v2_find_ext (ret, SADB_EXT_SA)->seg;
- if (!sa)
+ ext = pf_key_v2_find_ext (ret, SADB_EXT_SA);
+ if (!ext)
{
log_print ("pf_key_v2_get_spi: no SA extension found");
goto cleanup;
}
+ sa = ext->seg;
*sz = sizeof sa->sadb_sa_spi;
spi = malloc (*sz);
@@ -778,7 +791,7 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming)
#endif
default:
- /* XXX Log? */
+ LOG_DBG ((LOG_SYSDEP, 50, "pf_key_v2_set_spi: unknown encryption algorithm %d", proto->id));
return -1;
}
@@ -800,9 +813,16 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming)
#endif
break;
+#ifndef KAME
+ case IPSEC_AUTH_HMAC_RIPEMD:
+ ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC96;
+ break;
+#endif
+
case IPSEC_AUTH_DES_MAC:
case IPSEC_AUTH_KPDK:
- /* XXX Log? */
+ /* XXX We should be supporting KPDK */
+ LOG_DBG ((LOG_SYSDEP, 50, "pf_key_v2_set_spi: unknown authentication algorithm %d", iproto->auth));
return -1;
default:
@@ -834,8 +854,14 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming)
#endif
break;
+#ifndef KAME
+ case IPSEC_AH_RIPEMD:
+ ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC96;
+ break;
+#endif
+
default:
- /* XXX Log? */
+ LOG_DBG ((LOG_SYSDEP, 50, "pf_key_v2_set_spi: unknown authentication algorithm %d", proto->id));
goto cleanup;
}
break;
@@ -862,9 +888,9 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming)
goto cleanup;
#ifdef KAME
- memset(&ssa2, 0, sizeof(ssa2));
+ memset(&ssa2, 0, sizeof ssa2);
ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- ssa2.sadb_x_sa2_len = sizeof(ssa2) / PF_KEY_V2_CHUNK;
+ ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
ssa2.sadb_x_sa2_mode = 0;
if (pf_key_v2_msg_add (update, (struct sadb_ext *)&ssa2, 0) == -1)
goto cleanup;
@@ -898,7 +924,7 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming)
life->sadb_lifetime_bytes = sa->kilobytes * 1024;
/*
* XXX I am not sure which one is best in security respect. Maybe the
- * RFCs actually mandate what a lifetime reaaly is.
+ * RFCs actually mandate what a lifetime really is.
*/
#if 0
life->sadb_lifetime_addtime = 0;
@@ -943,7 +969,7 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming)
/*
* Setup the ADDRESS extensions.
*
- * XXX Addresses has to be thought through. Assumes IPv4.
+ * XXX Addresses have to be thought through. Assumes IPv4.
*/
if (incoming)
sa->transport->vtbl->get_dst (sa->transport, &src, &srclen);
@@ -1111,9 +1137,6 @@ pf_key_v2_mask_to_bits (u_int32_t mask)
return (33 - ffs (~mask + 1)) % 33;
}
-#undef OPENBSD_IPSEC_API_VERSION
-
-#ifndef OPENBSD_IPSEC_API_VERSION
/*
* Enable/disable a flow.
* XXX Assumes OpenBSD {ADD,DEL}FLOW extensions.
@@ -1126,17 +1149,15 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
{
#if defined (SADB_X_ADDFLOW) && defined (SADB_X_DELFLOW)
struct sadb_msg msg;
- struct sadb_sa ssa;
#ifdef SADB_X_EXT_FLOW_TYPE
struct sadb_protocol flowtype;
+#else
+ struct sadb_sa ssa;
#endif
struct sadb_address *addr = 0;
struct pf_key_v2_msg *flow = 0, *ret = 0;
size_t len;
int err;
-#ifdef KAME
- struct sadb_x_sa2 ssa2;
-#endif
#if !defined (SADB_X_SAFLAGS_INGRESS_FLOW) && !defined(SADB_X_EXT_FLOW_TYPE)
if (ingress)
@@ -1161,15 +1182,17 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
if (!flow)
goto cleanup;
-#ifdef KAME
- memset(&ssa2, 0, sizeof(ssa2));
- ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- ssa2.sadb_x_sa2_len = sizeof(ssa2) / PF_KEY_V2_CHUNK;
- ssa2.sadb_x_sa2_mode = 0;
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)&ssa2, 0) == -1)
- goto cleanup;
-#endif
+#ifdef SADB_X_EXT_FLOW_TYPE
+ /* Setup the flow type extension. */
+ flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE;
+ flowtype.sadb_protocol_len = sizeof flowtype / PF_KEY_V2_CHUNK;
+ flowtype.sadb_protocol_direction
+ = ingress ? IPSP_DIRECTION_IN : IPSP_DIRECTION_OUT;
+ flowtype.sadb_protocol_proto = FLOW_X_TYPE_REQUIRE;
+ if (pf_key_v2_msg_add (flow, (struct sadb_ext *)&flowtype, 0) == -1)
+ goto cleanup;
+#else /* SADB_X_EXT_FLOW_TYPE */
/* Setup the SA extension. */
ssa.sadb_sa_exttype = SADB_EXT_SA;
ssa.sadb_sa_len = sizeof ssa / PF_KEY_V2_CHUNK;
@@ -1190,23 +1213,12 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)&ssa, 0) == -1)
goto cleanup;
-
-#ifdef SADB_X_EXT_FLOW_TYPE
- /* Setup the flow type extension. */
- flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE;
- flowtype.sadb_protocol_len = sizeof flowtype / PF_KEY_V2_CHUNK;
- flowtype.sadb_protocol_direction
- = ingress ? IPSP_DIRECTION_IN : IPSP_DIRECTION_OUT;
- flowtype.sadb_protocol_proto = FLOW_X_TYPE_REQUIRE;
-
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)&flowtype, 0) == -1)
- goto cleanup;
-#endif
+#endif /* SADB_X_EXT_FLOW_TYPE */
/*
* Setup the ADDRESS extensions.
*
- * XXX Addresses has to be thought through. Assumes IPv4.
+ * XXX Addresses have to be thought through. Assumes IPv4.
*/
len = sizeof *addr + PF_KEY_V2_ROUND (sizeof (struct sockaddr_in));
if (!delete || ingress)
@@ -1216,10 +1228,6 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
-#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
-#endif
addr->sadb_address_reserved = 0;
memset (addr + 1, '\0', sizeof (struct sockaddr_in));
((struct sockaddr_in *)(addr + 1))->sin_len
@@ -1243,10 +1251,6 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
goto cleanup;
addr->sadb_address_exttype = SADB_X_EXT_SRC_FLOW;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
-#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
-#endif
addr->sadb_address_reserved = 0;
memset (addr + 1, '\0', sizeof (struct sockaddr_in));
((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
@@ -1263,10 +1267,6 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
goto cleanup;
addr->sadb_address_exttype = SADB_X_EXT_SRC_MASK;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
-#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
-#endif
addr->sadb_address_reserved = 0;
memset (addr + 1, '\0', sizeof (struct sockaddr_in));
((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
@@ -1283,10 +1283,6 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
goto cleanup;
addr->sadb_address_exttype = SADB_X_EXT_DST_FLOW;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
-#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
-#endif
addr->sadb_address_reserved = 0;
memset (addr + 1, '\0', sizeof (struct sockaddr_in));
((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
@@ -1303,10 +1299,6 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
goto cleanup;
addr->sadb_address_exttype = SADB_X_EXT_DST_MASK;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
-#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
-#endif
addr->sadb_address_reserved = 0;
memset (addr + 1, '\0', sizeof (struct sockaddr_in));
((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
@@ -1329,12 +1321,10 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
err = ((struct sadb_msg *)TAILQ_FIRST (ret)->seg)->sadb_msg_errno;
if (err)
{
-#ifdef __OpenBSD__
if (err == ESRCH) /* These are common and usually harmless. */
LOG_DBG ((LOG_SYSDEP, 10, "pf_key_v2_flow: %sFLOW: %s",
delete ? "DEL" : "ADD", strerror (err)));
else
-#endif
log_print ("pf_key_v2_flow: %sFLOW: %s", delete ? "DEL" : "ADD",
strerror (err));
goto cleanup;
@@ -1358,6 +1348,7 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
struct sadb_msg msg;
struct sadb_x_policy *policy = 0;
struct sadb_x_ipsecrequest *ipsecrequest;
+ struct sadb_x_sa2 ssa2;
struct sadb_address *addr = 0;
struct sockaddr_in *saddr;
u_int8_t
@@ -1365,9 +1356,6 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
struct pf_key_v2_msg *flow = 0, *ret = 0;
size_t len;
int err;
-#ifdef KAME
- struct sadb_x_sa2 ssa2;
-#endif
msg.sadb_msg_type = delete ? SADB_X_SPDDELETE : SADB_X_SPDADD;
msg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
@@ -1376,19 +1364,17 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
if (!flow)
goto cleanup;
-#ifdef KAME
- memset(&ssa2, 0, sizeof(ssa2));
+ memset(&ssa2, 0, sizeof ssa2);
ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- ssa2.sadb_x_sa2_len = sizeof(ssa2) / PF_KEY_V2_CHUNK;
+ ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
ssa2.sadb_x_sa2_mode = 0;
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)&ssa2, 0) == -1)
goto cleanup;
-#endif
/*
* Setup the ADDRESS extensions.
*
- * XXX Addresses has to be thought through. Assumes IPv4.
+ * XXX Addresses have to be thought through. Assumes IPv4.
*/
len = sizeof *addr + PF_KEY_V2_ROUND (sizeof (struct sockaddr_in));
addr = malloc (len);
@@ -1396,10 +1382,8 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
-#ifndef __OpenBSD__
addr->sadb_address_proto = IPSEC_ULPROTO_ANY;
addr->sadb_address_prefixlen = pf_key_v2_mask_to_bits (ntohl (lmask));
-#endif
addr->sadb_address_reserved = 0;
memset (addr + 1, '\0', sizeof (struct sockaddr_in));
((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
@@ -1416,10 +1400,8 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
-#ifndef __OpenBSD__
addr->sadb_address_proto = IPSEC_ULPROTO_ANY;
addr->sadb_address_prefixlen = pf_key_v2_mask_to_bits (ntohl (rmask));
-#endif
addr->sadb_address_reserved = 0;
memset (addr + 1, '\0', sizeof (struct sockaddr_in));
((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
@@ -1514,16 +1496,11 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
return -1;
#endif
}
-#endif
/* Enable a flow given a SA. */
int
pf_key_v2_enable_sa (struct sa *sa)
{
-#if OPENBSD_IPSEC_API_VERSION == 1
- /* We don't mess with flows */
- return 0;
-#else
struct ipsec_sa *isa = sa->data;
struct sockaddr *dst, *src;
int dstlen, srclen, error;
@@ -1580,10 +1557,8 @@ pf_key_v2_enable_sa (struct sa *sa)
isa->src_mask, proto->spi[1], proto->proto,
((struct sockaddr_in *)src)->sin_addr.s_addr,
((struct sockaddr_in *)dst)->sin_addr.s_addr, 0, 1);
-#endif
}
-#ifndef OPENBSD_IPSEC_API_VERSION
/* Disable a flow given a SA. */
static int
pf_key_v2_disable_sa (struct sa *sa, int incoming)
@@ -1646,7 +1621,6 @@ pf_key_v2_disable_sa (struct sa *sa, int incoming)
1, 1);
}
}
-#endif
/*
* Delete the IPSec SA represented by the INCOMING direction in protocol PROTO
@@ -1655,9 +1629,6 @@ pf_key_v2_disable_sa (struct sa *sa, int incoming)
int
pf_key_v2_delete_spi (struct sa *sa, struct proto *proto, int incoming)
{
-#if OPENBSD_IPSEC_API_VERSION == 1
- return 0;
-#else
struct sadb_msg msg;
struct sadb_sa ssa;
struct sadb_address *addr = 0;
@@ -1672,8 +1643,10 @@ pf_key_v2_delete_spi (struct sa *sa, struct proto *proto, int incoming)
* If the SA was outbound and it has not yet been replaced, or it's
* incoming, remove the flow associated with it.
* We ignore any errors from the disabling of the flow, it does not matter.
+ * Only remove flows if it was not an SA acquired by the kernel.
*/
- if ((!incoming && !(sa->flags & SA_FLAG_REPLACED)) || incoming)
+ if (((!incoming && !(sa->flags & SA_FLAG_REPLACED)) || incoming)
+ && !(sa->flags & SA_FLAG_ONDEMAND))
pf_key_v2_disable_sa (sa, incoming);
msg.sadb_msg_type = SADB_DELETE;
@@ -1707,9 +1680,9 @@ pf_key_v2_delete_spi (struct sa *sa, struct proto *proto, int incoming)
goto cleanup;
#ifdef KAME
- memset(&ssa2, 0, sizeof(ssa2));
+ memset(&ssa2, 0, sizeof ssa2);
ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- ssa2.sadb_x_sa2_len = sizeof(ssa2) / PF_KEY_V2_CHUNK;
+ ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
ssa2.sadb_x_sa2_mode = 0;
if (pf_key_v2_msg_add (delete, (struct sadb_ext *)&ssa2, 0) == -1)
goto cleanup;
@@ -1718,7 +1691,7 @@ pf_key_v2_delete_spi (struct sa *sa, struct proto *proto, int incoming)
/*
* Setup the ADDRESS extensions.
*
- * XXX Addresses has to be thought through. Assumes IPv4.
+ * XXX Addresses have to be thought through. Assumes IPv4.
*/
if (incoming)
sa->transport->vtbl->get_dst (sa->transport, &saddr, &saddrlen);
@@ -1790,7 +1763,6 @@ pf_key_v2_delete_spi (struct sa *sa, struct proto *proto, int incoming)
if (ret)
pf_key_v2_msg_free (ret);
return -1;
-#endif
}
static void
@@ -1830,20 +1802,36 @@ pf_key_v2_expire (struct pf_key_v2_msg *pmsg)
struct sockaddr *dstaddr;
struct sadb_lifetime *life;
struct sa *sa;
- struct pf_key_v2_node *lifenode;
+ struct pf_key_v2_node *lifenode, *ext;
msg = (struct sadb_msg *)TAILQ_FIRST (pmsg)->seg;
- ssa = pf_key_v2_find_ext (pmsg, SADB_EXT_SA)->seg;
- dst = pf_key_v2_find_ext (pmsg, SADB_EXT_ADDRESS_DST)->seg;
+ ext = pf_key_v2_find_ext (pmsg, SADB_EXT_SA);
+ if (!ext)
+ {
+ log_print ("pf_key_v2_expire: no SA extension found");
+ return;
+ }
+ ssa = ext->seg;
+ ext = pf_key_v2_find_ext (pmsg, SADB_EXT_ADDRESS_DST);
+ if (!ext)
+ {
+ log_print ("pf_key_v2_expire: no destination address extension found");
+ return;
+ }
+ dst = ext->seg;
dstaddr = (struct sockaddr *)(dst + 1);
lifenode = pf_key_v2_find_ext (pmsg, SADB_EXT_LIFETIME_HARD);
if (!lifenode)
lifenode = pf_key_v2_find_ext (pmsg, SADB_EXT_LIFETIME_SOFT);
+ if (!lifenode)
+ {
+ log_print ("pf_key_v2_expire: no lifetime extension found");
+ return;
+ }
life = lifenode->seg;
/* XXX IPv4 specific. */
- LOG_DBG ((LOG_SYSDEP, 20,
- "pf_key_v2_expire: %s dst %s SPI %x sproto %d",
+ LOG_DBG ((LOG_SYSDEP, 20, "pf_key_v2_expire: %s dst %s SPI %x sproto %d",
life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_SOFT ? "SOFT"
: "HARD",
inet_ntoa (((struct sockaddr_in *)dstaddr)->sin_addr),
@@ -1881,12 +1869,12 @@ pf_key_v2_expire (struct pf_key_v2_msg *pmsg)
if (life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_HARD)
{
- /*
- * XXX We need to reestablish the on-demand route here. This we need
- * even if we have started a new negotiation, considering it might
- * fail.
+ /* This SA is still referenced by the software timeout.
+ * However, sa_free will clean up all timeouts and
+ * decrement reference counters. We need to reference it
+ * so that sa_release() works.
*/
-
+ sa_reference (sa);
/* Remove the old SA, it isn't useful anymore. */
sa_free (sa);
}
@@ -1896,40 +1884,597 @@ pf_key_v2_expire (struct pf_key_v2_msg *pmsg)
static void
pf_key_v2_acquire (struct pf_key_v2_msg *pmsg)
{
- struct sadb_msg *msg;
- struct sadb_address *dst, *src;
- struct sockaddr *dstaddr, *srcaddr;
- struct sadb_comb *scmb;
- struct sadb_prop *sprp;
- char adbuf[40];
+#if !defined (SADB_X_ASKPOLICY)
+ return;
+#else
+ struct sadb_msg *msg, askpolicy_msg;
+ struct pf_key_v2_msg *askpolicy = 0, *ret = 0;
+ struct sadb_policy policy;
+ struct sadb_address *dst = 0, *src = 0;
+ struct sockaddr *dstaddr, *srcaddr = 0;
+ struct sadb_comb *scmb = 0;
+ struct sadb_prop *sprp = 0;
+ struct sadb_ident *srcident = 0, *dstident = 0;
+ char dstbuf[ADDRESS_MAX], srcbuf[ADDRESS_MAX], *peer = 0, conn[22];
+ char confname[120];
+ char *srcid = 0, *dstid = 0, *prefstring = 0;
+ int slen, af;
+ struct sockaddr *smask, *sflow, *dmask, *dflow;
+ struct sadb_protocol *sproto;
+ char ssflow[ADDRESS_MAX], sdflow[ADDRESS_MAX];
+ char sdmask[ADDRESS_MAX], ssmask[ADDRESS_MAX];
+ char lname[90], dname[90], configname[30];
+ int shostflag = 0, dhostflag = 0;
+ struct pf_key_v2_node *ext;
msg = (struct sadb_msg *)TAILQ_FIRST (pmsg)->seg;
- dst = pf_key_v2_find_ext (pmsg, SADB_EXT_ADDRESS_DST)->seg;
- src = pf_key_v2_find_ext (pmsg, SADB_EXT_ADDRESS_SRC)->seg;
- sprp = pf_key_v2_find_ext (pmsg, SADB_EXT_PROPOSAL)->seg;
- scmb = (struct sadb_comb *)(sprp + 1);
+
+ ext = pf_key_v2_find_ext (pmsg, SADB_EXT_ADDRESS_DST);
+ if (!ext)
+ {
+ log_print ("pf_key_v2_acquire: no destination address specified");
+ return;
+ }
+ dst = ext->seg;
+
+ ext = pf_key_v2_find_ext (pmsg, SADB_EXT_ADDRESS_SRC);
+ if (ext)
+ src = ext->seg;
+
+ ext = pf_key_v2_find_ext (pmsg, SADB_EXT_PROPOSAL);
+ if (ext)
+ {
+ sprp = ext->seg;
+ scmb = (struct sadb_comb *)(sprp + 1);
+ }
+
+ ext = pf_key_v2_find_ext (pmsg, SADB_EXT_IDENTITY_SRC);
+ if (ext)
+ srcident = ext->seg;
+
+ ext = pf_key_v2_find_ext (pmsg, SADB_EXT_IDENTITY_DST);
+ if (ext)
+ dstident = ext->seg;
+
+ /* Ask the kernel for the matching policy */
+ bzero (&askpolicy_msg, sizeof askpolicy_msg);
+ askpolicy_msg.sadb_msg_type = SADB_X_ASKPOLICY;
+ askpolicy = pf_key_v2_msg_new (&askpolicy_msg, 0);
+ if (!askpolicy)
+ goto fail;
+
+ policy.sadb_policy_exttype = SADB_X_EXT_POLICY;
+ policy.sadb_policy_len = sizeof policy / PF_KEY_V2_CHUNK;
+ policy.sadb_policy_seq = msg->sadb_msg_seq;
+ if (pf_key_v2_msg_add (askpolicy, (struct sadb_ext *)&policy, 0) == -1)
+ goto fail;
+
+ ret = pf_key_v2_call (askpolicy);
+ if (!ret)
+ goto fail;
+
+ /* Now we have all the information needed */
+
+ ext = pf_key_v2_find_ext (ret, SADB_X_EXT_SRC_FLOW);
+ if (!ext)
+ {
+ log_print ("pf_key_v2_acquire: no source flow extension found");
+ goto fail;
+ }
+ sflow = (struct sockaddr *) (((struct sadb_address *)ext->seg) + 1);
+
+ ext = pf_key_v2_find_ext (ret, SADB_X_EXT_DST_FLOW);
+ if (!ext)
+ {
+ log_print ("pf_key_v2_acquire: no destination flow extension found");
+ goto fail;
+ }
+ dflow = (struct sockaddr *)(((struct sadb_address *)ext->seg) + 1);
+
+ ext = pf_key_v2_find_ext (ret, SADB_X_EXT_SRC_MASK);
+ if (!ext)
+ {
+ log_print ("pf_key_v2_acquire: no source mask extension found");
+ goto fail;
+ }
+ smask = (struct sockaddr *)(((struct sadb_address *)ext->seg) + 1);
+
+ ext = pf_key_v2_find_ext (ret, SADB_X_EXT_DST_MASK);
+ if (!ext)
+ {
+ log_print ("pf_key_v2_acquire: no destination mask extension found");
+ goto fail;
+ }
+ dmask = (struct sockaddr *)(((struct sadb_address *)ext->seg) + 1);
+
+ ext = pf_key_v2_find_ext (pmsg, SADB_X_EXT_FLOW_TYPE);
+ if (!ext)
+ {
+ log_print ("pf_key_v2_acquire: no flow type extension found");
+ goto fail;
+ }
+ sproto = ext->seg;
+
+ bzero (ssflow, sizeof ssflow);
+ bzero (sdflow, sizeof sdflow);
+ bzero (ssmask, sizeof ssmask);
+ bzero (sdmask, sizeof sdmask);
+
+ switch (sflow->sa_family)
+ {
+ case AF_INET:
+ if (inet_ntop (AF_INET, &((struct sockaddr_in *)sflow)->sin_addr, ssflow,
+ ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ if (inet_ntop (AF_INET, &((struct sockaddr_in *)dflow)->sin_addr, sdflow,
+ ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ if (inet_ntop (AF_INET, &((struct sockaddr_in *)smask)->sin_addr, ssmask,
+ ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ if (inet_ntop (AF_INET, &((struct sockaddr_in *)dmask)->sin_addr, sdmask,
+ ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ if (((struct sockaddr_in *)smask)->sin_addr.s_addr == INADDR_BROADCAST)
+ shostflag = 1;
+ if (((struct sockaddr_in *)dmask)->sin_addr.s_addr == INADDR_BROADCAST)
+ dhostflag = 1;
+ break;
+
+ case AF_INET6:
+ if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)sflow)->sin6_addr,
+ ssflow, ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)dflow)->sin6_addr,
+ sdflow, ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)smask)->sin6_addr,
+ ssmask, ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)dmask)->sin6_addr,
+ sdmask, ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ if (IN6_IS_ADDR_FULL (&((struct sockaddr_in6 *)smask)->sin6_addr))
+ shostflag = 1;
+ if (IN6_IS_ADDR_FULL (&((struct sockaddr_in6 *)dmask)->sin6_addr))
+ dhostflag = 1;
+ break;
+ }
dstaddr = (struct sockaddr *)(dst + 1);
- srcaddr = (struct sockaddr *)(src + 1);
+ bzero (dstbuf, sizeof dstbuf);
switch (dstaddr->sa_family)
{
case AF_INET:
- LOG_DBG ((LOG_SYSDEP, 20, "pf_key_v2_acquire: dst=%s sproto %d",
- inet_ntop(AF_INET, &((struct sockaddr_in *)dstaddr)->sin_addr,
- adbuf, 16), msg->sadb_msg_satype));
+ if (inet_ntop (AF_INET, &((struct sockaddr_in *)dstaddr)->sin_addr,
+ dstbuf, ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ LOG_DBG ((LOG_SYSDEP, 20, "pf_key_v2_acquire: dst=%s sproto %d", dstbuf,
+ msg->sadb_msg_satype));
break;
case AF_INET6:
- LOG_DBG ((LOG_SYSDEP, 20, "pf_key_v2_acquire: dst=%s sproto %d",
- inet_ntop(AF_INET6
- , &((struct sockaddr_in6 *)dstaddr)->sin6_addr,
- adbuf, 16), msg->sadb_msg_satype));
+ if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)dstaddr)->sin6_addr,
+ dstbuf, ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ LOG_DBG ((LOG_SYSDEP, 20, "pf_key_v2_acquire: dst=%s sproto %d", dstbuf,
+ msg->sadb_msg_satype));
break;
}
- /* XXX Only support one proposal for now */
- /* XXX Finish it */
+ if (src)
+ {
+ srcaddr = (struct sockaddr *)(src + 1);
+ bzero (srcbuf, sizeof srcbuf);
+
+ switch (srcaddr->sa_family)
+ {
+ case AF_INET:
+ if (inet_ntop (AF_INET, &((struct sockaddr_in *)srcaddr)->sin_addr,
+ srcbuf, ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ break;
+
+ case AF_INET6:
+ if (inet_ntop (AF_INET6,
+ &((struct sockaddr_in6 *)srcaddr)->sin6_addr, srcbuf,
+ ADDRESS_MAX) == NULL)
+ {
+ log_error ("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ break;
+ }
+ }
+
+ /* Insert source ID */
+ if (srcident)
+ {
+ /* Check for valid type */
+ switch (srcident->sadb_ident_type)
+ {
+ case SADB_IDENTTYPE_PREFIX:
+ /* XXX Process the address */
+ break;
+
+ case SADB_IDENTTYPE_FQDN:
+ prefstring = "FQDN";
+ /* Fall through */
+
+ case SADB_IDENTTYPE_MBOX:
+ slen = (srcident->sadb_ident_len * sizeof (u_int64_t))
+ - sizeof (struct sadb_ident);
+ if (!prefstring)
+ prefstring = "USER_FQDN";
+
+ srcid = malloc (slen + strlen (prefstring) + 1 + strlen ("ID:/"));
+ if (!srcid)
+ {
+ log_error ("pf_key_v2_acquire: malloc (%d) failed",
+ slen + strlen (prefstring) + 1 + strlen ("ID:/"));
+ goto fail;
+ }
+
+ sprintf (srcid, "ID:%s/", prefstring);
+ strlcat (srcid + strlen ("ID:/") + strlen (prefstring),
+ (char *)(srcident + 1),
+ slen + strlen (prefstring) + 1 + strlen ("ID:/"));
+
+ /* Set the section if it doesn't already exist */
+ if (!conf_get_str (srcid, "ID-type"))
+ {
+ af = conf_begin ();
+ if (conf_set (af, srcid, "ID-type", prefstring, 0, 0)
+ || conf_set (af, srcid, "Name",
+ srcid + strlen ("ID:/") + strlen (prefstring),
+ 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ conf_end (af, 1);
+ }
+
+ break;
+
+ default:
+ LOG_DBG ((LOG_SYSDEP, 20,
+ "pf_key_v2_acquire: invalid source ID type %d",
+ srcident->sadb_ident_type));
+ goto fail;
+ }
+
+ LOG_DBG ((LOG_SYSDEP, 50,
+ "pf_key_v2_acquire: constructed source ID \"%s\"", srcid));
+ prefstring = 0;
+ }
+
+ /* Insert destination ID */
+ if (dstident)
+ {
+ /* Check for valid type */
+ switch (dstident->sadb_ident_type)
+ {
+ case SADB_IDENTTYPE_PREFIX:
+ /* XXX Process the address */
+ break;
+
+ case SADB_IDENTTYPE_FQDN:
+ prefstring = "FQDN";
+ /* Fall through */
+
+ case SADB_IDENTTYPE_MBOX:
+ slen = (dstident->sadb_ident_len * sizeof (u_int64_t))
+ - sizeof (struct sadb_ident);
+ if (!prefstring)
+ prefstring = "USER_FQDN";
+
+ dstid = malloc (slen + strlen (prefstring) + 1 + strlen ("ID:/"));
+ if (!dstid)
+ {
+ log_error ("pf_key_v2_acquire: malloc (%d) failed",
+ slen + strlen (prefstring) + 1 + strlen ("ID:/"));
+ goto fail;
+ }
+
+ sprintf (dstid, "ID:%s/", prefstring);
+ strlcat (dstid + strlen ("ID:/") + strlen (prefstring),
+ (char *) (dstident + 1),
+ slen + strlen (prefstring) + 1 + strlen ("ID:/"));
+
+ /* Set the section if it doesn't already exist */
+ if (!conf_get_str (dstid, "ID-type"))
+ {
+ af = conf_begin ();
+ if (conf_set (af, dstid, "ID-type", prefstring, 0, 0)
+ || conf_set (af, dstid, "Name",
+ dstid + strlen ("ID:/") + strlen (prefstring),
+ 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ conf_end (af, 1);
+ }
+
+ break;
+
+ default:
+ LOG_DBG ((LOG_SYSDEP, 20,
+ "pf_key_v2_acquire: invalid destination ID type %d",
+ dstident->sadb_ident_type));
+ goto fail;
+ }
+
+ LOG_DBG ((LOG_SYSDEP, 50,
+ "pf_key_v2_acquire: constructed destination ID \"%s\"",
+ dstid));
+ }
+
+ /* Now we've placed the necessary IDs in the configuration space */
+
+ /* Get a new connection sequence number */
+ for (;; connection_seq++)
+ {
+ sprintf (conn, "Connection-%d", connection_seq);
+ sprintf (configname, "Config-Phase2-%d", connection_seq);
+
+ /* Does it exist ? */
+ if (!conf_get_str (conn, "Phase")
+ && !conf_get_str (configname, "Suites"))
+ break;
+ }
+
+ /*
+ * Set the IPsec connection entry. In particular, the following fields:
+ * - Phase
+ * - ISAKMPD-peer
+ * - Local-ID/Remote-ID (if provided)
+ *
+ * Also set the following section:
+ * [Peer-dstaddr(/srcaddr)(-srcid)(/dstid)]
+ * with these fields:
+ * - Phase
+ * - ID (if provided)
+ * - Remote-ID (if provided)
+ * - Listen-address (if provided)
+ * - Address
+ * - Configuration (if an entry "ISAKMP-configuration-dstaddr(/srcaddr)"
+ * exists -- otherwise use the defaults)
+ */
+
+ peer = malloc (strlen (dstbuf) + strlen (srcbuf) + srcid ? strlen (srcid) : 0
+ + dstid ? strlen (dstid) : 0 + strlen ("Peer-/-/") + 1);
+ if (!peer)
+ goto fail;
+
+ /*
+ * The various cases:
+ * - Peer-dstaddr
+ * - Peer-dstaddr/srcaddr
+ * - Peer-dstaddr/srcaddr-srcid
+ * - Peer-dstaddr/srcaddr-srcid/dstid
+ * - Peer-dstaddr/srcaddr-/dstid
+ * - Peer-dstaddr-srcid/dstid
+ * - Peer-dstaddr-/dstid
+ * - Peer-dstaddr-srcid
+ */
+ sprintf (peer, "Peer-%s%s%s%s%s%s%s", dstbuf, srcaddr ? "/" : "",
+ srcaddr ? srcbuf : "", srcid ? "-" : "", srcid ? srcid : "",
+ dstid ? (srcid ? "/" : "-/") : "", dstid ? dstid : "");
+
+ /* Set the IPsec connection section */
+ af = conf_begin ();
+ if (conf_set (af, conn, "Phase", "2", 0, 0)
+ || conf_set (af, conn, "Flags", "__ondemand", 0 ,0)
+ || conf_set (af, conn, "ISAKMP-peer", peer, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ /* Set Phase 2 IDs -- this is the Local-ID section */
+ sprintf (lname, "Phase2-ID:%s/%s", ssflow, ssmask);
+ if (conf_set (af, conn, "Local-ID", lname, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ if (!conf_get_str (lname, "ID-type"))
+ {
+ if (shostflag)
+ {
+ if (conf_set (af, lname, "ID-type", "IPV4_ADDR", 0, 0)
+ || conf_set (af, lname, "Address", ssflow, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+ }
+ else
+ {
+ if (conf_set (af, lname, "ID-type", "IPV4_SUBNET", 0, 0)
+ || conf_set (af, lname, "Network", ssflow, 0, 0)
+ || conf_set (af, lname, "Netmask", ssmask, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+ }
+ }
+
+ /* Set Remote-ID section */
+ sprintf (dname, "Phase2-ID:%s/%s", sdflow, sdmask);
+ if (conf_set (af, conn, "Remote-ID", dname, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ if (!conf_get_str (dname, "ID-type"))
+ {
+ if (dhostflag)
+ {
+ if (conf_set (af, dname, "ID-type", "IPV4_ADDR", 0, 0)
+ || conf_set (af, dname, "Address", sdflow, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+ }
+ else
+ {
+ if (conf_set (af, dname, "ID-type", "IPV4_SUBNET", 0, 0)
+ || conf_set (af, dname, "Network", sdflow, 0, 0)
+ || conf_set (af, dname, "Netmask", sdmask, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+ }
+ }
+
+ /*
+ * XXX
+ * We should be using information from the proposal to set this up.
+ * At least, we should make this selectable.
+ */
+
+ /* Phase 2 configuration */
+ if (conf_set (af, conn, "Configuration", configname, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ if (conf_set (af, configname, "Exchange_type", "Quick_mode", 0, 0)
+ || conf_set (af, configname, "DOI", "IPSEC", 0, 0)
+ || conf_set (af, configname, "Suites",
+ "QM-ESP-3DES-SHA-PFS-SUITE", 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ /* Set the ISAKMP-peer section */
+ if (!conf_get_str (peer, "Phase"))
+ {
+ if (conf_set (af, peer, "Phase", "1", 0, 0)
+ || conf_set (af, peer, "Address", dstbuf, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ if (srcaddr && conf_set (af, peer, "Local-address", srcbuf, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ sprintf (confname, "ISAKMP-Configuration-%s", peer);
+ if (conf_set (af, peer, "Configuration", confname, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ /* XXX Default transform set should be settable */
+ /* Phase 1 configuration */
+ if (!conf_get_str (confname, "exchange_type"))
+ {
+ if (conf_set (af, confname, "exchange_type", "ID_PROT", 0, 0)
+ || conf_set (af, confname, "DOI", "IPSEC", 0, 0)
+ || conf_set (af, confname, "Transforms", "3DES-SHA-RSA_SIG", 0,
+ 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+ }
+
+ /* The ID we should use in Phase 1 */
+ if (srcid && conf_set (af, peer, "ID", srcid, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+
+ /* The ID the other side should use in Phase 1 */
+ if (dstid && conf_set (af, peer, "Remote-ID", dstid, 0, 0))
+ {
+ conf_end (af, 0);
+ goto fail;
+ }
+ }
+ else
+ {
+ /* Phase 1 tag exists, there's nothing more we need to do */
+ }
+
+ /* All done */
+ conf_end (af, 1);
+
+ /* Let's rock */
+ pf_key_v2_connection_check (conn);
+
+ /*
+ * XXX Need to implement cleanup of sections after SAs expire. In
+ * particular, we need to expire the IPsec connection section; we
+ * could keep the ISAKMP-peer, Local-ID/Remote-ID sections.
+ */
+
+ /* Fall-through to cleanup */
+ fail:
+ if (ret)
+ pf_key_v2_msg_free (ret);
+ if (askpolicy)
+ pf_key_v2_msg_free (askpolicy);
+ if (srcid)
+ free (srcid);
+ if (dstid)
+ free (dstid);
+ if (peer)
+ free (peer);
+ return;
+#endif
}
static void
@@ -2041,9 +2586,9 @@ pf_key_v2_group_spis (struct sa *sa, struct proto *proto1,
if (pf_key_v2_msg_add (grpspis, (struct sadb_ext *)&sa2, 0) == -1)
goto cleanup;
#else
- memset(&kamesa2, 0, sizeof(kamesa2));
+ memset(&kamesa2, 0, sizeof kamesa2);
kamesa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- kamesa2.sadb_x_sa2_len = sizeof(kamesa2) / PF_KEY_V2_CHUNK;
+ kamesa2.sadb_x_sa2_len = sizeof kamesa2 / PF_KEY_V2_CHUNK;
kamesa2.sadb_x_sa2_mode = 0;
if (pf_key_v2_msg_add (grpspis, (struct sadb_ext *)&kamesa2, 0) == -1)
goto cleanup;
@@ -2052,7 +2597,7 @@ pf_key_v2_group_spis (struct sa *sa, struct proto *proto1,
/*
* Setup the ADDRESS extensions.
*
- * XXX Addresses has to be thought through. Assumes IPv4.
+ * XXX Addresses have to be thought through. Assumes IPv4.
*/
if (incoming)
sa->transport->vtbl->get_src (sa->transport, &saddr, &saddrlen);