|
|
--- isakmpd-20041012.orig/dpd.c
|
|
|
+++ isakmpd-20041012/dpd.c
|
|
|
@@ -26,6 +26,7 @@
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
#include <stdlib.h>
|
|
|
+#include <memory.h>
|
|
|
|
|
|
#include "sysdep.h"
|
|
|
|
|
|
@@ -174,6 +175,7 @@
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
+ ;
|
|
|
}
|
|
|
|
|
|
/* Mark handled. */
|
|
|
@@ -223,6 +225,7 @@
|
|
|
dpd_check_event, sa, &tv);
|
|
|
break;
|
|
|
default:
|
|
|
+ ;
|
|
|
}
|
|
|
if (!sa->dpd_event)
|
|
|
log_print("dpd_timer_reset: timer_add_event failed");
|
|
|
--- isakmpd-20041012.orig/ipsec.c
|
|
|
+++ isakmpd-20041012/ipsec.c
|
|
|
@@ -1020,6 +1020,52 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * deal with a NOTIFY of INVALID_SPI
|
|
|
+ */
|
|
|
+static void
|
|
|
+ipsec_invalid_spi (struct message *msg, struct payload *p)
|
|
|
+{
|
|
|
+ struct sockaddr *dst;
|
|
|
+ int invspisz, off;
|
|
|
+ u_int32_t spi;
|
|
|
+ u_int16_t totsiz;
|
|
|
+ u_int8_t spisz;
|
|
|
+
|
|
|
+ /* Any notification that make us do something should be protected */
|
|
|
+ if(!TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]))
|
|
|
+ {
|
|
|
+ LOG_DBG ((LOG_SA, 40,
|
|
|
+ "ipsec_invalid_spi: missing HASH payload in INVALID_SPI"
|
|
|
+ " notification"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * get the invalid spi out of the variable sized notification data
|
|
|
+ * field, which is after the variable sized SPI field [which specifies
|
|
|
+ * the receiving entity's phase-1 SPI, not the invalid spi]
|
|
|
+ */
|
|
|
+ totsiz = GET_ISAKMP_GEN_LENGTH (p->p);
|
|
|
+ spisz = GET_ISAKMP_NOTIFY_SPI_SZ (p->p);
|
|
|
+ off = ISAKMP_NOTIFY_SPI_OFF + spisz;
|
|
|
+ invspisz = totsiz - off;
|
|
|
+
|
|
|
+ if (invspisz != sizeof spi)
|
|
|
+ {
|
|
|
+ LOG_DBG ((LOG_SA, 40,
|
|
|
+ "ipsec_invalid_spi: SPI size %d in INVALID_SPI "
|
|
|
+ "payload unsupported", spisz));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ memcpy (&spi, p->p + off, sizeof spi);
|
|
|
+
|
|
|
+ msg->transport->vtbl->get_dst (msg->transport, &dst);
|
|
|
+
|
|
|
+ /* delete matching SPI's from this peer */
|
|
|
+ ipsec_delete_spi_list (dst, 0, (u_int8_t *)&spi, 1, "INVALID_SPI");
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
ipsec_responder(struct message *msg)
|
|
|
{
|
|
|
@@ -1205,7 +1251,9 @@
|
|
|
return dv != IPSEC_ENCAP_TUNNEL
|
|
|
&& dv != IPSEC_ENCAP_TRANSPORT
|
|
|
&& dv != IPSEC_ENCAP_UDP_ENCAP_TUNNEL
|
|
|
- && dv != IPSEC_ENCAP_UDP_ENCAP_TRANSPORT;
|
|
|
+ && dv != IPSEC_ENCAP_UDP_ENCAP_TRANSPORT
|
|
|
+ && dv != IPSEC_ENCAP_UDP_ENCAP_TUNNEL_DRAFT
|
|
|
+ && dv != IPSEC_ENCAP_UDP_ENCAP_TRANSPORT_DRAFT;
|
|
|
#else
|
|
|
return dv < IPSEC_ENCAP_TUNNEL
|
|
|
|| dv > IPSEC_ENCAP_TRANSPORT;
|
|
|
@@ -1837,7 +1885,7 @@
|
|
|
ipsec_get_id(char *section, int *id, struct sockaddr **addr,
|
|
|
struct sockaddr **mask, u_int8_t *tproto, u_int16_t *port)
|
|
|
{
|
|
|
- char *type, *address, *netmask;
|
|
|
+ char *type, *address, *netmask;
|
|
|
|
|
|
type = conf_get_str(section, "ID-type");
|
|
|
if (!type) {
|
|
|
--- isakmpd-20041012.orig/GNUmakefile
|
|
|
+++ isakmpd-20041012/GNUmakefile
|
|
|
@@ -40,12 +40,12 @@
|
|
|
# integrated, freebsd/netbsd means FreeBSD/NetBSD with KAME IPsec.
|
|
|
# darwin means MacOS X 10.2 and later with KAME IPsec. linux means Linux-2.5
|
|
|
# and later with native IPSec support.
|
|
|
-OS= openbsd
|
|
|
+#OS= openbsd
|
|
|
#OS= netbsd
|
|
|
#OS= freebsd
|
|
|
#OS= freeswan
|
|
|
#OS= darwin
|
|
|
-#OS= linux
|
|
|
+OS= linux
|
|
|
|
|
|
.CURDIR:= $(shell pwd)
|
|
|
VPATH= ${.CURDIR}/sysdep/${OS}
|
|
|
@@ -55,9 +55,10 @@
|
|
|
ifndef BINDIR
|
|
|
BINDIR= /sbin
|
|
|
endif
|
|
|
-ifndef LDSTATIC
|
|
|
-LDSTATIC= -static
|
|
|
-endif
|
|
|
+
|
|
|
+#ifndef LDSTATIC
|
|
|
+#LDSTATIC= -static
|
|
|
+#endif
|
|
|
|
|
|
SRCS= app.c attribute.c cert.c connection.c \
|
|
|
constants.c conf.c cookie.c crypto.c dh.c doi.c exchange.c \
|
|
|
@@ -131,11 +132,14 @@
|
|
|
ifneq ($(findstring install,$(MAKECMDGOALS)),install)
|
|
|
# Skip 'regress' until the regress/ structure has gmake makefiles for it.
|
|
|
#SUBDIR:= regress
|
|
|
-SUBDIR:=
|
|
|
+#SUBDIR:= apps/certpatch
|
|
|
mksubdirs:
|
|
|
$(foreach DIR, ${SUBDIR}, \
|
|
|
- cd ${DIR}; ${MAKE} ${MAKEFLAGS} CFLAGS="${CFLAGS}" \
|
|
|
- MKDEP="${MKDEP}" ${MAKECMDGOALS})
|
|
|
+ cd ${.CURDIR}/${DIR}; ${MAKE} ${MAKECMDGOALS};)
|
|
|
+
|
|
|
+# $(foreach DIR, ${SUBDIR}, \
|
|
|
+# cd ${DIR}; ${MAKE} CFLAGS="${CFLAGS}" \
|
|
|
+# MKDEP="${MKDEP}" ${MAKECMDGOALS})
|
|
|
else
|
|
|
mksubdirs:
|
|
|
endif
|
|
|
@@ -173,7 +177,7 @@
|
|
|
endif
|
|
|
|
|
|
SRCS+= ${IPSEC_SRCS} ${X509} ${POLICY} ${EC} ${AGGRESSIVE} ${DNSSEC} \
|
|
|
- $(ISAKMP_CFG)
|
|
|
+ $(ISAKMP_CFG) ${DPD} ${NAT_TRAVERSAL}
|
|
|
CFLAGS+= ${IPSEC_CFLAGS}
|
|
|
LDADD+= ${DESLIB}
|
|
|
DPADD+= ${DESLIBDEP}
|
|
|
--- isakmpd-20041012.orig/exchange.h
|
|
|
+++ isakmpd-20041012/exchange.h
|
|
|
@@ -221,6 +221,8 @@
|
|
|
#define EXCHANGE_FLAG_NAT_T_ENABLE 0x10 /* We are doing NAT-T. */
|
|
|
#define EXCHANGE_FLAG_NAT_T_KEEPALIVE 0x20 /* We are the NAT:ed peer. */
|
|
|
#define EXCHANGE_FLAG_DPD_CAP_PEER 0x40 /* Peer is DPD capable. */
|
|
|
+#define EXCHANGE_FLAG_NAT_T_RFC 0x0080 /* Peer does RFC NAT-T. */
|
|
|
+#define EXCHANGE_FLAG_NAT_T_DRAFT 0x0100 /* Peer does draft NAT-T.*/
|
|
|
|
|
|
extern int exchange_add_certs(struct message *);
|
|
|
extern void exchange_finalize(struct message *);
|
|
|
--- isakmpd-20041012.orig/log.c
|
|
|
+++ isakmpd-20041012/log.c
|
|
|
@@ -79,7 +79,6 @@
|
|
|
|
|
|
struct packhdr {
|
|
|
struct pcap_pkthdr pcap;/* pcap file packet header */
|
|
|
- u_int32_t sa_family; /* address family */
|
|
|
union {
|
|
|
struct ip ip4; /* IPv4 header (w/o options) */
|
|
|
struct ip6_hdr ip6; /* IPv6 header */
|
|
|
@@ -97,7 +96,7 @@
|
|
|
static u_int8_t *packet_buf = NULL;
|
|
|
|
|
|
static int udp_cksum(struct packhdr *, const struct udphdr *,
|
|
|
- u_int16_t *);
|
|
|
+ u_int16_t *, int);
|
|
|
static u_int16_t in_cksum(const u_int16_t *, int);
|
|
|
#endif /* USE_DEBUG */
|
|
|
|
|
|
@@ -539,11 +538,9 @@
|
|
|
udp.uh_ulen = htons(datalen);
|
|
|
|
|
|
/* ip */
|
|
|
- hdr.sa_family = htonl(src->sa_family);
|
|
|
switch (src->sa_family) {
|
|
|
default:
|
|
|
/* Assume IPv4. XXX Can 'default' ever happen here? */
|
|
|
- hdr.sa_family = htonl(AF_INET);
|
|
|
hdr.ip.ip4.ip_src.s_addr = 0x02020202;
|
|
|
hdr.ip.ip4.ip_dst.s_addr = 0x01010101;
|
|
|
/* The rest of the setup is common to AF_INET. */
|
|
|
@@ -584,9 +581,7 @@
|
|
|
}
|
|
|
|
|
|
/* Calculate UDP checksum. */
|
|
|
- udp.uh_sum = udp_cksum(&hdr, &udp, (u_int16_t *) packet_buf);
|
|
|
- hdrlen += sizeof hdr.sa_family;
|
|
|
-
|
|
|
+ udp.uh_sum = udp_cksum(&hdr, &udp, (u_int16_t *) packet_buf, src->sa_family);
|
|
|
/* pcap file packet header */
|
|
|
gettimeofday(&tv, 0);
|
|
|
hdr.pcap.ts.tv_sec = tv.tv_sec;
|
|
|
@@ -610,7 +605,7 @@
|
|
|
|
|
|
/* Copied from tcpdump/print-udp.c, mostly rewritten. */
|
|
|
static int
|
|
|
-udp_cksum(struct packhdr *hdr, const struct udphdr *u, u_int16_t *d)
|
|
|
+udp_cksum(struct packhdr *hdr, const struct udphdr *u, u_int16_t *d, int af)
|
|
|
{
|
|
|
struct ip *ip4;
|
|
|
struct ip6_hdr *ip6;
|
|
|
@@ -639,7 +634,7 @@
|
|
|
|
|
|
/* Setup pseudoheader. */
|
|
|
memset(phu.pa, 0, sizeof phu);
|
|
|
- switch (ntohl(hdr->sa_family)) {
|
|
|
+ switch (af) {
|
|
|
case AF_INET:
|
|
|
ip4 = &hdr->ip.ip4;
|
|
|
memcpy(&phu.ip4p.src, &ip4->ip_src, sizeof(struct in_addr));
|
|
|
@@ -664,7 +659,7 @@
|
|
|
|
|
|
/* IPv6 wants a 0xFFFF checksum "on error", not 0x0. */
|
|
|
if (tlen < 0)
|
|
|
- return (ntohl(hdr->sa_family) == AF_INET ? 0 : 0xFFFF);
|
|
|
+ return (af == AF_INET ? 0 : 0xFFFF);
|
|
|
|
|
|
sum = 0;
|
|
|
for (i = 0; i < hdrlen; i += 2)
|
|
|
--- isakmpd-20041012.orig/nat_traversal.c
|
|
|
+++ isakmpd-20041012/nat_traversal.c
|
|
|
@@ -1,4 +1,4 @@
|
|
|
-/* $OpenBSD: nat_traversal.c,v 1.7 2004/08/08 19:11:06 deraadt Exp $ */
|
|
|
+/* $OpenBSD: nat_traversal.c,v 1.17 2006/06/14 14:03:33 hshoexer Exp $ */
|
|
|
|
|
|
/*
|
|
|
* Copyright (c) 2004 H<EFBFBD>kan Olsson. All rights reserved.
|
|
|
@@ -48,40 +48,40 @@
|
|
|
#include "util.h"
|
|
|
#include "virtual.h"
|
|
|
|
|
|
+int disable_nat_t = 0;
|
|
|
+
|
|
|
/*
|
|
|
- * XXX According to draft-ietf-ipsec-nat-t-ike-07.txt, the NAT-T
|
|
|
- * capability of the other peer is determined by a particular vendor ID
|
|
|
- * sent as the first message. This vendor ID string is supposed to be a
|
|
|
- * MD5 hash of "RFC XXXX", where XXXX is the future RFC number.
|
|
|
+ * NAT-T capability of the other peer is determined by a particular vendor
|
|
|
+ * ID sent in the first message. This vendor ID string is supposed to be a
|
|
|
+ * MD5 hash of "RFC 3947".
|
|
|
*
|
|
|
* These seem to be the "well" known variants of this string in use by
|
|
|
* products today.
|
|
|
*/
|
|
|
-static const char *isakmp_nat_t_cap_text[] = {
|
|
|
- "draft-ietf-ipsec-nat-t-ike-00", /* V1 (XXX: may be obsolete) */
|
|
|
- "draft-ietf-ipsec-nat-t-ike-02\n", /* V2 */
|
|
|
- "draft-ietf-ipsec-nat-t-ike-03", /* V3 */
|
|
|
-#ifdef notyet
|
|
|
- "RFC XXXX",
|
|
|
-#endif
|
|
|
+
|
|
|
+static struct nat_t_cap isakmp_nat_t_cap[] = {
|
|
|
+ { VID_DRAFT_V2_N, EXCHANGE_FLAG_NAT_T_DRAFT,
|
|
|
+ "draft-ietf-ipsec-nat-t-ike-02\n", NULL, 0 },
|
|
|
+ { VID_DRAFT_V3, EXCHANGE_FLAG_NAT_T_DRAFT,
|
|
|
+ "draft-ietf-ipsec-nat-t-ike-03", NULL, 0 },
|
|
|
+ { VID_RFC3947, EXCHANGE_FLAG_NAT_T_RFC,
|
|
|
+ "RFC 3947", NULL, 0 },
|
|
|
};
|
|
|
|
|
|
+#define NUMNATTCAP (sizeof isakmp_nat_t_cap / sizeof isakmp_nat_t_cap[0])
|
|
|
+
|
|
|
/* In seconds. Recommended in draft-ietf-ipsec-udp-encaps-09. */
|
|
|
#define NAT_T_KEEPALIVE_INTERVAL 20
|
|
|
|
|
|
-/* The MD5 hashes of the above strings is put in this array. */
|
|
|
-static char **nat_t_hashes;
|
|
|
-static size_t nat_t_hashsize;
|
|
|
-
|
|
|
static int nat_t_setup_hashes(void);
|
|
|
-static int nat_t_add_vendor_payload(struct message *, char *);
|
|
|
+static int nat_t_add_vendor_payload(struct message *, struct nat_t_cap *);
|
|
|
static int nat_t_add_nat_d(struct message *, struct sockaddr *);
|
|
|
static int nat_t_match_nat_d_payload(struct message *, struct sockaddr *);
|
|
|
|
|
|
void
|
|
|
nat_t_init(void)
|
|
|
{
|
|
|
- nat_t_hashes = (char **)NULL;
|
|
|
+ nat_t_setup_hashes();
|
|
|
}
|
|
|
|
|
|
/* Generate the NAT-T capability marker hashes. Executed only once. */
|
|
|
@@ -89,7 +89,7 @@
|
|
|
nat_t_setup_hashes(void)
|
|
|
{
|
|
|
struct hash *hash;
|
|
|
- int n = sizeof isakmp_nat_t_cap_text / sizeof isakmp_nat_t_cap_text[0];
|
|
|
+ int n = NUMNATTCAP;
|
|
|
int i;
|
|
|
|
|
|
/* The draft says to use MD5. */
|
|
|
@@ -100,56 +100,49 @@
|
|
|
"could not find MD5 hash structure!");
|
|
|
return -1;
|
|
|
}
|
|
|
- nat_t_hashsize = hash->hashsize;
|
|
|
|
|
|
- /* Allocate one more than is necessary, i.e NULL terminated. */
|
|
|
- nat_t_hashes = (char **)calloc((size_t)(n + 1), sizeof(char *));
|
|
|
- if (!nat_t_hashes) {
|
|
|
- log_error("nat_t_setup_hashes: calloc (%lu,%lu) failed",
|
|
|
- (unsigned long)n, (unsigned long)sizeof(char *));
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- /* Populate with hashes. */
|
|
|
+ /* Populate isakmp_nat_t_cap with hashes. */
|
|
|
for (i = 0; i < n; i++) {
|
|
|
- nat_t_hashes[i] = (char *)malloc(nat_t_hashsize);
|
|
|
- if (!nat_t_hashes[i]) {
|
|
|
+ isakmp_nat_t_cap[i].hashsize = hash->hashsize;
|
|
|
+ isakmp_nat_t_cap[i].hash = (char *)malloc(hash->hashsize);
|
|
|
+ if (!isakmp_nat_t_cap[i].hash) {
|
|
|
log_error("nat_t_setup_hashes: malloc (%lu) failed",
|
|
|
- (unsigned long)nat_t_hashsize);
|
|
|
+ (unsigned long)hash->hashsize);
|
|
|
goto errout;
|
|
|
}
|
|
|
|
|
|
hash->Init(hash->ctx);
|
|
|
hash->Update(hash->ctx,
|
|
|
- (unsigned char *)isakmp_nat_t_cap_text[i],
|
|
|
- strlen(isakmp_nat_t_cap_text[i]));
|
|
|
- hash->Final(nat_t_hashes[i], hash->ctx);
|
|
|
+ (unsigned char *)isakmp_nat_t_cap[i].text,
|
|
|
+ strlen(isakmp_nat_t_cap[i].text));
|
|
|
+ hash->Final(isakmp_nat_t_cap[i].hash, hash->ctx);
|
|
|
|
|
|
LOG_DBG((LOG_EXCHANGE, 50, "nat_t_setup_hashes: "
|
|
|
- "MD5(\"%s\") (%lu bytes)", isakmp_nat_t_cap_text[i],
|
|
|
- (unsigned long)nat_t_hashsize));
|
|
|
+ "MD5(\"%s\") (%lu bytes)", isakmp_nat_t_cap[i].text,
|
|
|
+ (unsigned long)hash->hashsize));
|
|
|
LOG_DBG_BUF((LOG_EXCHANGE, 50, "nat_t_setup_hashes",
|
|
|
- nat_t_hashes[i], nat_t_hashsize));
|
|
|
+ isakmp_nat_t_cap[i].hash, hash->hashsize));
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
- errout:
|
|
|
+errout:
|
|
|
for (i = 0; i < n; i++)
|
|
|
- if (nat_t_hashes[i])
|
|
|
- free(nat_t_hashes[i]);
|
|
|
- free(nat_t_hashes);
|
|
|
- nat_t_hashes = NULL;
|
|
|
+ if (isakmp_nat_t_cap[i].hash)
|
|
|
+ free(isakmp_nat_t_cap[i].hash);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
/* Add one NAT-T VENDOR payload. */
|
|
|
static int
|
|
|
-nat_t_add_vendor_payload(struct message *msg, char *hash)
|
|
|
+nat_t_add_vendor_payload(struct message *msg, struct nat_t_cap *cap)
|
|
|
{
|
|
|
- size_t buflen = nat_t_hashsize + ISAKMP_GEN_SZ;
|
|
|
+ size_t buflen = cap->hashsize + ISAKMP_GEN_SZ;
|
|
|
u_int8_t *buf;
|
|
|
|
|
|
+ if (disable_nat_t)
|
|
|
+ return 0;
|
|
|
+
|
|
|
buf = malloc(buflen);
|
|
|
if (!buf) {
|
|
|
log_error("nat_t_add_vendor_payload: malloc (%lu) failed",
|
|
|
@@ -158,12 +151,11 @@
|
|
|
}
|
|
|
|
|
|
SET_ISAKMP_GEN_LENGTH(buf, buflen);
|
|
|
- memcpy(buf + ISAKMP_VENDOR_ID_OFF, hash, nat_t_hashsize);
|
|
|
+ memcpy(buf + ISAKMP_VENDOR_ID_OFF, cap->hash, cap->hashsize);
|
|
|
if (message_add_payload(msg, ISAKMP_PAYLOAD_VENDOR, buf, buflen, 1)) {
|
|
|
free(buf);
|
|
|
return -1;
|
|
|
}
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
@@ -171,16 +163,14 @@
|
|
|
int
|
|
|
nat_t_add_vendor_payloads(struct message *msg)
|
|
|
{
|
|
|
- int i = 0;
|
|
|
+ int i;
|
|
|
|
|
|
- if (!nat_t_hashes)
|
|
|
- if (nat_t_setup_hashes())
|
|
|
- return 0; /* XXX should this be an error? */
|
|
|
+ if (disable_nat_t)
|
|
|
+ return 0;
|
|
|
|
|
|
- while (nat_t_hashes[i])
|
|
|
- if (nat_t_add_vendor_payload(msg, nat_t_hashes[i++]))
|
|
|
+ for (i = 0; i < NUMNATTCAP; i++)
|
|
|
+ if (nat_t_add_vendor_payload(msg, &isakmp_nat_t_cap[i]))
|
|
|
return -1;
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
@@ -192,36 +182,31 @@
|
|
|
{
|
|
|
u_int8_t *pbuf = p->p;
|
|
|
size_t vlen;
|
|
|
- int i = 0;
|
|
|
+ int i;
|
|
|
|
|
|
- /* Already checked? */
|
|
|
- if (p->flags & PL_MARK ||
|
|
|
- msg->exchange->flags & EXCHANGE_FLAG_NAT_T_CAP_PEER)
|
|
|
+ if (disable_nat_t)
|
|
|
return;
|
|
|
|
|
|
- if (!nat_t_hashes)
|
|
|
- if (nat_t_setup_hashes())
|
|
|
- return;
|
|
|
-
|
|
|
vlen = GET_ISAKMP_GEN_LENGTH(pbuf) - ISAKMP_GEN_SZ;
|
|
|
- if (vlen != nat_t_hashsize) {
|
|
|
- LOG_DBG((LOG_EXCHANGE, 50, "nat_t_check_vendor_payload: "
|
|
|
- "bad size %lu != %lu", (unsigned long)vlen,
|
|
|
- (unsigned long)nat_t_hashsize));
|
|
|
- return;
|
|
|
- }
|
|
|
|
|
|
- while (nat_t_hashes[i])
|
|
|
- if (memcmp(nat_t_hashes[i++], pbuf + ISAKMP_GEN_SZ,
|
|
|
+ for (i = 0; i < NUMNATTCAP; i++) {
|
|
|
+ if (vlen != isakmp_nat_t_cap[i].hashsize) {
|
|
|
+ LOG_DBG((LOG_EXCHANGE, 50, "nat_t_check_vendor_payload: "
|
|
|
+ "bad size %lu != %lu", (unsigned long)vlen,
|
|
|
+ (unsigned long)isakmp_nat_t_cap[i].hashsize));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (memcmp(isakmp_nat_t_cap[i].hash, pbuf + ISAKMP_GEN_SZ,
|
|
|
vlen) == 0) {
|
|
|
/* This peer is NAT-T capable. */
|
|
|
msg->exchange->flags |= EXCHANGE_FLAG_NAT_T_CAP_PEER;
|
|
|
+ msg->exchange->flags |= isakmp_nat_t_cap[i].flags;
|
|
|
LOG_DBG((LOG_EXCHANGE, 10,
|
|
|
"nat_t_check_vendor_payload: "
|
|
|
"NAT-T capable peer detected"));
|
|
|
p->flags |= PL_MARK;
|
|
|
- return;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
@@ -233,10 +218,8 @@
|
|
|
{
|
|
|
struct ipsec_exch *ie = (struct ipsec_exch *)msg->exchange->data;
|
|
|
struct hash *hash;
|
|
|
- struct prf *prf;
|
|
|
u_int8_t *res;
|
|
|
in_port_t port;
|
|
|
- int prf_type = PRF_HMAC; /* XXX */
|
|
|
|
|
|
hash = hash_get(ie->hash->type);
|
|
|
if (hash == NULL) {
|
|
|
@@ -244,31 +227,25 @@
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- prf = prf_alloc(prf_type, hash->type, msg->exchange->cookies,
|
|
|
- ISAKMP_HDR_COOKIES_LEN);
|
|
|
- if(!prf) {
|
|
|
- log_print("nat_t_generate_nat_d_hash: prf_alloc failed");
|
|
|
- return NULL;
|
|
|
- }
|
|
|
+ *hashlen = hash->hashsize;
|
|
|
|
|
|
- *hashlen = prf->blocksize;
|
|
|
res = (u_int8_t *)malloc((unsigned long)*hashlen);
|
|
|
if (!res) {
|
|
|
log_print("nat_t_generate_nat_d_hash: malloc (%lu) failed",
|
|
|
(unsigned long)*hashlen);
|
|
|
- prf_free(prf);
|
|
|
*hashlen = 0;
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
port = sockaddr_port(sa);
|
|
|
- memset(res, 0, *hashlen);
|
|
|
-
|
|
|
- prf->Update(prf->prfctx, sockaddr_addrdata(sa), sockaddr_addrlen(sa));
|
|
|
- prf->Update(prf->prfctx, (unsigned char *)&port, sizeof port);
|
|
|
- prf->Final(res, prf->prfctx);
|
|
|
- prf_free (prf);
|
|
|
+ bzero(res, *hashlen);
|
|
|
|
|
|
+ hash->Init(hash->ctx);
|
|
|
+ hash->Update(hash->ctx, msg->exchange->cookies,
|
|
|
+ sizeof msg->exchange->cookies);
|
|
|
+ hash->Update(hash->ctx, sockaddr_addrdata(sa), sockaddr_addrlen(sa));
|
|
|
+ hash->Update(hash->ctx, (unsigned char *)&port, sizeof port);
|
|
|
+ hash->Final(res, hash->ctx);
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
@@ -276,6 +253,7 @@
|
|
|
static int
|
|
|
nat_t_add_nat_d(struct message *msg, struct sockaddr *sa)
|
|
|
{
|
|
|
+ int ret;
|
|
|
u_int8_t *hbuf, *buf;
|
|
|
size_t hbuflen, buflen;
|
|
|
|
|
|
@@ -298,11 +276,19 @@
|
|
|
memcpy(buf + ISAKMP_NAT_D_DATA_OFF, hbuf, hbuflen);
|
|
|
free(hbuf);
|
|
|
|
|
|
- if (message_add_payload(msg, ISAKMP_PAYLOAD_NAT_D, buf, buflen, 1)) {
|
|
|
+ if (msg->exchange->flags & EXCHANGE_FLAG_NAT_T_RFC)
|
|
|
+ ret = message_add_payload(msg, ISAKMP_PAYLOAD_NAT_D, buf,
|
|
|
+ buflen, 1);
|
|
|
+ else if (msg->exchange->flags & EXCHANGE_FLAG_NAT_T_DRAFT)
|
|
|
+ ret = message_add_payload(msg, ISAKMP_PAYLOAD_NAT_D_DRAFT,
|
|
|
+ buf, buflen, 1);
|
|
|
+ else
|
|
|
+ ret = -1;
|
|
|
+
|
|
|
+ if (ret) {
|
|
|
free(buf);
|
|
|
return -1;
|
|
|
}
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
@@ -312,14 +298,14 @@
|
|
|
{
|
|
|
struct sockaddr *sa;
|
|
|
|
|
|
- msg->transport->vtbl->get_src(msg->transport, &sa);
|
|
|
+ /* Remote address first. */
|
|
|
+ msg->transport->vtbl->get_dst(msg->transport, &sa);
|
|
|
if (nat_t_add_nat_d(msg, sa))
|
|
|
return -1;
|
|
|
|
|
|
- msg->transport->vtbl->get_dst(msg->transport, &sa);
|
|
|
+ msg->transport->vtbl->get_src(msg->transport, &sa);
|
|
|
if (nat_t_add_nat_d(msg, sa))
|
|
|
return -1;
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
@@ -336,8 +322,8 @@
|
|
|
* If there are no NAT-D payloads in the message, return "found"
|
|
|
* as this will avoid NAT-T (see nat_t_exchange_check_nat_d()).
|
|
|
*/
|
|
|
- p = payload_first(msg, ISAKMP_PAYLOAD_NAT_D);
|
|
|
- if (!p)
|
|
|
+ if ((p = payload_first(msg, ISAKMP_PAYLOAD_NAT_D_DRAFT)) == NULL &&
|
|
|
+ (p = payload_first(msg, ISAKMP_PAYLOAD_NAT_D)) == NULL)
|
|
|
return 1;
|
|
|
|
|
|
hbuf = nat_t_generate_nat_d_hash(msg, sa, &hbuflen);
|
|
|
--- isakmpd-20041012.orig/udp_encap.c
|
|
|
+++ isakmpd-20041012/udp_encap.c
|
|
|
@@ -61,6 +61,11 @@
|
|
|
|
|
|
#define UDP_SIZE 65536
|
|
|
|
|
|
+#if defined(USE_NAT_TRAVERSAL) && defined (LINUX_IPSEC)
|
|
|
+#include <linux/socket.h>
|
|
|
+#include <linux/udp.h>
|
|
|
+#endif
|
|
|
+
|
|
|
/* If a system doesn't have SO_REUSEPORT, SO_REUSEADDR will have to do. */
|
|
|
#ifndef SO_REUSEPORT
|
|
|
#define SO_REUSEPORT SO_REUSEADDR
|
|
|
@@ -134,6 +139,18 @@
|
|
|
if (sysdep_cleartext(s, laddr->sa_family) == -1)
|
|
|
goto err;
|
|
|
|
|
|
+#if defined(USE_NAT_TRAVERSAL) && defined (LINUX_IPSEC)
|
|
|
+ {
|
|
|
+#ifndef SOL_UDP
|
|
|
+#define SOL_UDP 17
|
|
|
+#endif
|
|
|
+ int option = UDP_ENCAP_ESPINUDP;
|
|
|
+ if(setsockopt(s, SOL_UDP, UDP_ENCAP, &option,
|
|
|
+ sizeof (option)) < 0)
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
/* Wildcard address ? */
|
|
|
switch (laddr->sa_family) {
|
|
|
case AF_INET:
|
|
|
--- isakmpd-20041012.orig/apps/Makefile
|
|
|
+++ isakmpd-20041012/apps/Makefile
|
|
|
@@ -31,4 +31,4 @@
|
|
|
|
|
|
SUBDIR= certpatch
|
|
|
|
|
|
-.include <bsd.subdir.mk>
|
|
|
+#.include <bsd.subdir.mk>
|
|
|
--- isakmpd-20041012.orig/apps/certpatch/GNUmakefile
|
|
|
+++ isakmpd-20041012/apps/certpatch/GNUmakefile
|
|
|
@@ -0,0 +1,55 @@
|
|
|
+# $OpenBSD: Makefile,v 1.7 2003/06/03 14:35:00 ho Exp $
|
|
|
+# $EOM: Makefile,v 1.6 2000/03/28 21:22:06 ho Exp $
|
|
|
+
|
|
|
+#
|
|
|
+# Copyright (c) 1999 Niels Provos. All rights reserved.
|
|
|
+# Copyright (c) 2001 Niklas Hallqvist. 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.
|
|
|
+#
|
|
|
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
|
|
+#
|
|
|
+
|
|
|
+#
|
|
|
+# This code was written under funding by Ericsson Radio Systems.
|
|
|
+#
|
|
|
+
|
|
|
+PROG= certpatch
|
|
|
+SRCS= certpatch.c
|
|
|
+BINDIR?= /usr/sbin
|
|
|
+TOPSRC= ${.CURDIR}../..
|
|
|
+TOPOBJ!= cd ${TOPSRC}; printf "all:\n\t@pwd\n" |${MAKE} -f-
|
|
|
+OS= linux
|
|
|
+FEATURES!= awk '/^FEATURES=/ { print $$0 }' ${.CURDIR}/../../Makefile | sed 's/FEATURES=.//'
|
|
|
+.PATH: ${TOPSRC} ${TOPSRC}/sysdep/${OS} ${TOPOBJ}
|
|
|
+CFLAGS+= -I${TOPSRC} -I${TOPSRC}/sysdep/${OS} -I${TOPOBJ} -Wall
|
|
|
+LDFLAGS+= -lcrypto -lssl -lgmp
|
|
|
+MAN= certpatch.8
|
|
|
+
|
|
|
+CFLAGS+= -DMP_FLAVOUR=MP_FLAVOUR_GMP
|
|
|
+LDADD+= -lgmp
|
|
|
+DPADD+= ${LIBGMP}
|
|
|
+
|
|
|
+# Override LIBSYSDEPDIR definition from Makefile.sysdep
|
|
|
+LIBSYSDEPDIR= ${TOPSRC}/sysdep/common/libsysdep
|
|
|
+
|
|
|
+all: ${PROG}
|
|
|
+
|
|
|
+clean:
|
|
|
+ rm -f ${PROG}
|
|
|
--- isakmpd-20041012.orig/pf_key_v2.c
|
|
|
+++ isakmpd-20041012/pf_key_v2.c
|
|
|
@@ -1055,6 +1055,10 @@
|
|
|
#endif
|
|
|
#if defined (USE_NAT_TRAVERSAL) && defined (SADB_X_EXT_UDPENCAP)
|
|
|
struct sadb_x_udpencap udpencap;
|
|
|
+#elif defined (USE_NAT_TRAVERSAL) && defined (SADB_X_EXT_NAT_T_TYPE)
|
|
|
+ struct sadb_x_nat_t_type nat_t_type;
|
|
|
+ struct sadb_x_nat_t_port nat_t_sport;
|
|
|
+ struct sadb_x_nat_t_port nat_t_dport;
|
|
|
#endif
|
|
|
#ifdef USE_DEBUG
|
|
|
char *addr_str;
|
|
|
@@ -1273,10 +1277,15 @@
|
|
|
log_print("pf_key_v2_set_spi: invalid proto %d", proto->proto);
|
|
|
goto cleanup;
|
|
|
}
|
|
|
- if (incoming)
|
|
|
+ if (incoming) {
|
|
|
sa->transport->vtbl->get_src(sa->transport, &dst);
|
|
|
- else
|
|
|
+ sa->transport->vtbl->get_dst(sa->transport, &src);
|
|
|
+ }
|
|
|
+ else {
|
|
|
sa->transport->vtbl->get_dst(sa->transport, &dst);
|
|
|
+ sa->transport->vtbl->get_src(sa->transport, &src);
|
|
|
+ }
|
|
|
+
|
|
|
#ifdef KAME
|
|
|
msg.sadb_msg_seq = (incoming ?
|
|
|
pf_key_v2_seq_by_sa(proto->spi[incoming], sizeof ssa.sadb_sa_spi,
|
|
|
@@ -1319,12 +1328,13 @@
|
|
|
ssa.sadb_sa_flags = 0;
|
|
|
#ifdef SADB_X_SAFLAGS_TUNNEL
|
|
|
if (iproto->encap_mode == IPSEC_ENCAP_TUNNEL ||
|
|
|
- iproto->encap_mode == IPSEC_ENCAP_UDP_ENCAP_TUNNEL)
|
|
|
+ iproto->encap_mode == IPSEC_ENCAP_UDP_ENCAP_TUNNEL ||
|
|
|
+ iproto->encap_mode == IPSEC_ENCAP_UDP_ENCAP_TUNNEL_DRAFT)
|
|
|
ssa.sadb_sa_flags = SADB_X_SAFLAGS_TUNNEL;
|
|
|
#endif
|
|
|
|
|
|
-#if defined (USE_NAT_TRAVERSAL) && defined (SADB_X_EXT_UDPENCAP)
|
|
|
if (isakmp_sa->flags & SA_FLAG_NAT_T_ENABLE) {
|
|
|
+#if defined (USE_NAT_TRAVERSAL) && defined (SADB_X_EXT_UDPENCAP)
|
|
|
memset(&udpencap, 0, sizeof udpencap);
|
|
|
ssa.sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP;
|
|
|
udpencap.sadb_x_udpencap_exttype = SADB_X_EXT_UDPENCAP;
|
|
|
@@ -1334,8 +1344,40 @@
|
|
|
if (pf_key_v2_msg_add(update, (struct sadb_ext *)&udpencap, 0)
|
|
|
== -1)
|
|
|
goto cleanup;
|
|
|
- }
|
|
|
+#elif defined (USE_NAT_TRAVERSAL) && defined (SADB_X_EXT_NAT_T_TYPE)
|
|
|
+#ifndef UDP_ENCAP_ESPINUDP
|
|
|
+#define UDP_ENCAP_ESPINUDP 2
|
|
|
+#endif
|
|
|
+ memset(&nat_t_type, 0, sizeof nat_t_type);
|
|
|
+ memset(&nat_t_sport, 0, sizeof nat_t_sport);
|
|
|
+ memset(&nat_t_dport, 0, sizeof nat_t_dport);
|
|
|
+
|
|
|
+ /* type = draft-udp-encap-06 */
|
|
|
+ nat_t_type.sadb_x_nat_t_type_len = sizeof nat_t_type / PF_KEY_V2_CHUNK;
|
|
|
+ nat_t_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
|
|
|
+ nat_t_type.sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP;
|
|
|
+ if(pf_key_v2_msg_add(update, (struct sadb_ext *)&nat_t_type, 0) == -1)
|
|
|
+ goto cleanup;
|
|
|
+
|
|
|
+ /* source port */
|
|
|
+ nat_t_sport.sadb_x_nat_t_port_len = sizeof nat_t_sport /
|
|
|
+ PF_KEY_V2_CHUNK;
|
|
|
+ nat_t_sport.sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
|
|
|
+ nat_t_sport.sadb_x_nat_t_port_port = sockaddr_port(src);
|
|
|
+ if(pf_key_v2_msg_add(update, (struct sadb_ext *)&nat_t_sport, 0) == -1)
|
|
|
+ goto cleanup;
|
|
|
+
|
|
|
+ /* destination port */
|
|
|
+ nat_t_dport.sadb_x_nat_t_port_len = sizeof nat_t_dport /
|
|
|
+ PF_KEY_V2_CHUNK;
|
|
|
+ nat_t_dport.sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
|
|
|
+ nat_t_dport.sadb_x_nat_t_port_port = sockaddr_port(dst);
|
|
|
+ if(pf_key_v2_msg_add(update, (struct sadb_ext *)&nat_t_dport, 0) == -1)
|
|
|
+ goto cleanup;
|
|
|
+
|
|
|
+ /* original address (transport mode checksum missing info) goes here */
|
|
|
#endif
|
|
|
+ }
|
|
|
|
|
|
if (pf_key_v2_msg_add(update, (struct sadb_ext *)&ssa, 0) == -1)
|
|
|
goto cleanup;
|
|
|
@@ -1395,10 +1437,6 @@
|
|
|
/*
|
|
|
* Setup the ADDRESS extensions.
|
|
|
*/
|
|
|
- if (incoming)
|
|
|
- sa->transport->vtbl->get_dst(sa->transport, &src);
|
|
|
- else
|
|
|
- sa->transport->vtbl->get_src(sa->transport, &src);
|
|
|
len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(src));
|
|
|
addr = calloc(1, len);
|
|
|
if (!addr)
|
|
|
@@ -2167,7 +2205,7 @@
|
|
|
pf_key_v2_msg_free(ret);
|
|
|
return -1;
|
|
|
|
|
|
-#elif defined (SADB_X_SPDADD) && defined (SADB_X_SPDDELETE)
|
|
|
+#elif defined (SADB_X_SPDUPDATE) && defined (SADB_X_SPDDELETE)
|
|
|
struct sadb_msg msg;
|
|
|
struct sadb_x_policy *policy = 0;
|
|
|
struct sadb_x_ipsecrequest *ipsecrequest;
|
|
|
@@ -2181,7 +2219,7 @@
|
|
|
struct sockaddr_in *ip4_sa;
|
|
|
struct sockaddr_in6 *ip6_sa;
|
|
|
|
|
|
- msg.sadb_msg_type = delete ? SADB_X_SPDDELETE : SADB_X_SPDADD;
|
|
|
+ msg.sadb_msg_type = delete ? SADB_X_SPDDELETE : SADB_X_SPDUPDATE;
|
|
|
msg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
|
|
|
msg.sadb_msg_seq = 0;
|
|
|
flow = pf_key_v2_msg_new(&msg, 0);
|
|
|
--- isakmpd-20041012.orig/isakmp_num.cst
|
|
|
+++ isakmpd-20041012/isakmp_num.cst
|
|
|
@@ -57,15 +57,18 @@
|
|
|
KD 17 # RFC 3547, Key Download
|
|
|
SEQ 18 # RFC 3547, Sequence Number
|
|
|
POP 19 # RFC 3547, Proof of possession
|
|
|
- RESERVED_MIN 20
|
|
|
+ NAT_D 20 # RFC 3947, NAT Discovery payload
|
|
|
+ NAT_OA 21 # RFC 3947, NAT Original Address payload
|
|
|
+ RESERVED_MIN 22
|
|
|
RESERVED_MAX 127
|
|
|
PRIVATE_MIN 128
|
|
|
# XXX values from draft-ietf-ipsec-nat-t-ike-01,02,03. Later drafts specify
|
|
|
# XXX NAT_D as payload 15 and NAT_OA as 16, but these are allocated by RFC
|
|
|
# XXX 3547 as seen above.
|
|
|
- NAT_D 130 # NAT Discovery payload
|
|
|
- NAT_OA 131 # NAT Original Address payload
|
|
|
+ NAT_D_DRAFT 130 # NAT Discovery payload
|
|
|
+ NAT_OA_DRAFT 131 # NAT Original Address payload
|
|
|
PRIVATE_MAX 255
|
|
|
+ MAX 255
|
|
|
.
|
|
|
|
|
|
# ISAKMP exchange types.
|
|
|
--- isakmpd-20041012.orig/ipsec_num.cst
|
|
|
+++ isakmpd-20041012/ipsec_num.cst
|
|
|
@@ -62,10 +62,10 @@
|
|
|
IPSEC_ENCAP
|
|
|
TUNNEL 1
|
|
|
TRANSPORT 2
|
|
|
- FUTURE_UDP_ENCAP_TUNNEL 3 # XXX Not yet assigned
|
|
|
- FUTURE_UDP_ENCAP_TRANSPORT 4 # XXX Not yet assigned
|
|
|
- UDP_ENCAP_TUNNEL 61443 # draft-ietf-ipsec-nat-t-ike
|
|
|
- UDP_ENCAP_TRANSPORT 61443 # draft-ietf-ipsec-nat-t-ike
|
|
|
+ UDP_ENCAP_TUNNEL 3
|
|
|
+ UDP_ENCAP_TRANSPORT 4
|
|
|
+ UDP_ENCAP_TUNNEL_DRAFT 61443 # draft-ietf-ipsec-nat-t-ike
|
|
|
+ UDP_ENCAP_TRANSPORT_DRAFT 61443 # draft-ietf-ipsec-nat-t-ike
|
|
|
.
|
|
|
|
|
|
# IPSEC authentication algorithm.
|
|
|
--- isakmpd-20041012.orig/nat_traversal.h
|
|
|
+++ isakmpd-20041012/nat_traversal.h
|
|
|
@@ -1,4 +1,4 @@
|
|
|
-/* $OpenBSD: nat_traversal.h,v 1.2 2004/06/21 23:27:10 ho Exp $ */
|
|
|
+/* $OpenBSD: nat_traversal.h,v 1.4 2005/07/25 15:03:47 hshoexer Exp $ */
|
|
|
|
|
|
/*
|
|
|
* Copyright (c) 2004 H<EFBFBD>kan Olsson. All rights reserved.
|
|
|
@@ -27,6 +27,24 @@
|
|
|
#ifndef _NAT_TRAVERSAL_H_
|
|
|
#define _NAT_TRAVERSAL_H_
|
|
|
|
|
|
+#define VID_DRAFT_V2 0
|
|
|
+#define VID_DRAFT_V2_N 1
|
|
|
+#define VID_DRAFT_V3 2
|
|
|
+#define VID_RFC3947 3
|
|
|
+
|
|
|
+struct nat_t_cap {
|
|
|
+ int id;
|
|
|
+ u_int32_t flags;
|
|
|
+ const char *text;
|
|
|
+ char *hash;
|
|
|
+ size_t hashsize;
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * Set if -T is given on the command line to disable NAT-T support.
|
|
|
+ */
|
|
|
+extern int disable_nat_t;
|
|
|
+
|
|
|
void nat_t_init(void);
|
|
|
int nat_t_add_vendor_payloads(struct message *);
|
|
|
void nat_t_check_vendor_payload(struct message *, struct payload *);
|
|
|
--- isakmpd-20041012.orig/message.c
|
|
|
+++ isakmpd-20041012/message.c
|
|
|
@@ -112,6 +112,7 @@
|
|
|
message_validate_hash, message_validate_sig, message_validate_nonce,
|
|
|
message_validate_notify, message_validate_delete,
|
|
|
message_validate_vendor, message_validate_attribute,
|
|
|
+ message_validate_nat_d, message_validate_nat_oa,
|
|
|
message_validate_nat_d, message_validate_nat_oa
|
|
|
};
|
|
|
|
|
|
@@ -120,7 +121,7 @@
|
|
|
isakmp_id_fld, isakmp_cert_fld, isakmp_certreq_fld, isakmp_hash_fld,
|
|
|
isakmp_sig_fld, isakmp_nonce_fld, isakmp_notify_fld, isakmp_delete_fld,
|
|
|
isakmp_vendor_fld, isakmp_attribute_fld, isakmp_nat_d_fld,
|
|
|
- isakmp_nat_oa_fld
|
|
|
+ isakmp_nat_oa_fld, isakmp_nat_d_fld, isakmp_nat_oa_fld
|
|
|
};
|
|
|
|
|
|
/*
|
|
|
@@ -138,7 +139,8 @@
|
|
|
ISAKMP_PAYLOAD_SAK, ISAKMP_PAYLOAD_SAT, ISAKMP_PAYLOAD_KD,
|
|
|
ISAKMP_PAYLOAD_SEQ, ISAKMP_PAYLOAD_POP
|
|
|
#endif
|
|
|
- ISAKMP_PAYLOAD_NAT_D, ISAKMP_PAYLOAD_NAT_OA
|
|
|
+ ISAKMP_PAYLOAD_NAT_D, ISAKMP_PAYLOAD_NAT_OA,
|
|
|
+ ISAKMP_PAYLOAD_NAT_D_DRAFT, ISAKMP_PAYLOAD_NAT_OA_DRAFT
|
|
|
};
|
|
|
|
|
|
static u_int8_t payload_map[256];
|
|
|
@@ -347,8 +349,8 @@
|
|
|
}
|
|
|
/* Ignore most private payloads. */
|
|
|
if (next >= ISAKMP_PAYLOAD_PRIVATE_MIN &&
|
|
|
- next != ISAKMP_PAYLOAD_NAT_D &&
|
|
|
- next != ISAKMP_PAYLOAD_NAT_OA) {
|
|
|
+ next != ISAKMP_PAYLOAD_NAT_D_DRAFT &&
|
|
|
+ next != ISAKMP_PAYLOAD_NAT_OA_DRAFT) {
|
|
|
LOG_DBG((LOG_MESSAGE, 30, "message_parse_payloads: "
|
|
|
"private next payload type %s in payload of "
|
|
|
"type %d ignored",
|
|
|
@@ -460,8 +462,10 @@
|
|
|
return ISAKMP_ATTRIBUTE_SZ;
|
|
|
#if defined (USE_NAT_TRAVERSAL)
|
|
|
case ISAKMP_PAYLOAD_NAT_D:
|
|
|
+ case ISAKMP_PAYLOAD_NAT_D_DRAFT:
|
|
|
return ISAKMP_NAT_D_SZ;
|
|
|
case ISAKMP_PAYLOAD_NAT_OA:
|
|
|
+ case ISAKMP_PAYLOAD_NAT_OA_DRAFT:
|
|
|
return ISAKMP_NAT_OA_SZ;
|
|
|
#endif
|
|
|
/* Not yet supported and any other unknown payloads. */
|
|
|
--- isakmpd-20041012.orig/policy.c
|
|
|
+++ isakmpd-20041012/policy.c
|
|
|
@@ -511,7 +511,10 @@
|
|
|
break;
|
|
|
}
|
|
|
#if defined (USE_NAT_TRAVERSAL)
|
|
|
- else if (decode_16(value) == IPSEC_ENCAP_UDP_ENCAP_TUNNEL)
|
|
|
+ else if (decode_16(value) ==
|
|
|
+ IPSEC_ENCAP_UDP_ENCAP_TUNNEL ||
|
|
|
+ decode_16(value) ==
|
|
|
+ IPSEC_ENCAP_UDP_ENCAP_TUNNEL_DRAFT)
|
|
|
switch (proto->proto) {
|
|
|
case IPSEC_PROTO_IPSEC_AH:
|
|
|
ah_encapsulation = "udp-encap-tunnel";
|
|
|
@@ -1932,7 +1935,7 @@
|
|
|
void
|
|
|
policy_init(void)
|
|
|
{
|
|
|
- char *ptr, *policy_file;
|
|
|
+ char *ptr, *policy_file, *use_keynote;
|
|
|
char **asserts;
|
|
|
size_t sz, len;
|
|
|
int fd, i;
|
|
|
@@ -1940,10 +1943,11 @@
|
|
|
LOG_DBG((LOG_POLICY, 30, "policy_init: initializing"));
|
|
|
|
|
|
/* Do we want to use the policy modules? */
|
|
|
- if (ignore_policy ||
|
|
|
- strncmp("yes", conf_get_str("General", "Use-Keynote"), 3))
|
|
|
- return;
|
|
|
-
|
|
|
+ use_keynote = conf_get_str("General", "Use-Keynote");
|
|
|
+ if (ignore_policy ||
|
|
|
+ (use_keynote && strncmp("yes", use_keynote, 3)))
|
|
|
+ return;
|
|
|
+
|
|
|
/* Get policy file from configuration. */
|
|
|
policy_file = conf_get_str("General", "Policy-file");
|
|
|
if (!policy_file)
|
|
|
--- isakmpd-20041012.orig/ike_phase_1.c
|
|
|
+++ isakmpd-20041012/ike_phase_1.c
|
|
|
@@ -1040,9 +1040,9 @@
|
|
|
|
|
|
/* Compare expected/desired and received remote ID */
|
|
|
if (bcmp(rid, payload->p + ISAKMP_ID_DATA_OFF, sz)) {
|
|
|
- free(rid);
|
|
|
log_print("ike_phase_1_recv_ID: "
|
|
|
- "received remote ID other than expected %s", p);
|
|
|
+ "received remote ID other than expected %s - %s", p, payload->p);
|
|
|
+ free(rid);
|
|
|
return -1;
|
|
|
}
|
|
|
free(rid);
|
|
|
--- isakmpd-20041012.orig/x509.c
|
|
|
+++ isakmpd-20041012/x509.c
|
|
|
@@ -910,7 +910,11 @@
|
|
|
X509_STORE_CTX_init(&csc, x509_cas, cert, NULL);
|
|
|
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
|
|
|
/* XXX See comment in x509_read_crls_from_dir. */
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
|
|
+ if (x509_cas->param->flags & X509_V_FLAG_CRL_CHECK) {
|
|
|
+#else
|
|
|
if (x509_cas->flags & X509_V_FLAG_CRL_CHECK) {
|
|
|
+#endif
|
|
|
X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK);
|
|
|
X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK_ALL);
|
|
|
}
|
|
|
--- isakmpd-20041012.orig/sysdep/linux/sysdep.c
|
|
|
+++ isakmpd-20041012/sysdep/linux/sysdep.c
|
|
|
@@ -169,22 +169,22 @@
|
|
|
return 0;
|
|
|
|
|
|
if (!(af == AF_INET || af == AF_INET6))
|
|
|
- {
|
|
|
+ {
|
|
|
log_print ("sysdep_cleartext: unsupported protocol family %d", af);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
if (setsockopt (fd, af == AF_INET ? IPPROTO_IP : IPPROTO_IPV6,
|
|
|
- af == AF_INET ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY,
|
|
|
- &pol_in, sizeof pol_in) < 0 ||
|
|
|
+ af == AF_INET ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY,
|
|
|
+ &pol_in, sizeof pol_in) < 0 ||
|
|
|
setsockopt (fd, af == AF_INET ? IPPROTO_IP : IPPROTO_IPV6,
|
|
|
- af == AF_INET ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY,
|
|
|
- &pol_out, sizeof pol_out) < 0)
|
|
|
- {
|
|
|
+ af == AF_INET ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY,
|
|
|
+ &pol_out, sizeof pol_out) < 0)
|
|
|
+ {
|
|
|
log_error ("sysdep_cleartext: "
|
|
|
- "setsockopt (%d, IPPROTO_IP%s, IP%s_IPSEC_POLICY, ...) "
|
|
|
- "failed", fd, af == AF_INET ? "" : "V6",
|
|
|
- af == AF_INET ? "" : "V6");
|
|
|
+ "setsockopt (%d, IPPROTO_IP%s, IP%s_IPSEC_POLICY, ...) "
|
|
|
+ "failed", fd, af == AF_INET ? "" : "V6",
|
|
|
+ af == AF_INET ? "" : "V6");
|
|
|
return -1;
|
|
|
}
|
|
|
return 0;
|
|
|
--- isakmpd-20041012.orig/sysdep/linux/GNUmakefile.sysdep
|
|
|
+++ isakmpd-20041012/sysdep/linux/GNUmakefile.sysdep
|
|
|
@@ -33,13 +33,13 @@
|
|
|
LDADD+= -lgmp ${LIBSYSDEP} ${LIBCRYPTO}
|
|
|
DPADD+= ${LIBGMP} ${LIBSYSDEP}
|
|
|
|
|
|
-CFLAGS+= -DUSE_OLD_SOCKADDR -DHAVE_PCAP \
|
|
|
- -DNEED_SYSDEP_APP -DMP_FLAVOUR=MP_FLAVOUR_GMP \
|
|
|
- -I/usr/src/linux/include -I${.CURDIR}/sysdep/common \
|
|
|
+CFLAGS+= -DHAVE_GETNAMEINFO -DUSE_OLD_SOCKADDR -DHAVE_PCAP \
|
|
|
+ -DNEED_SYSDEP_APP -DMP_FLAVOUR=MP_FLAVOUR_GMP -DUSE_AES \
|
|
|
+ -I${.CURDIR}/sysdep/linux/include -I${.CURDIR}/sysdep/common \
|
|
|
-I/usr/include/openssl
|
|
|
|
|
|
FEATURES= debug tripledes blowfish cast ec aggressive x509 policy
|
|
|
-FEATURES+= des aes
|
|
|
+FEATURES+= dpd nat_traversal isakmp_cfg des aes
|
|
|
|
|
|
IPSEC_SRCS= pf_key_v2.c
|
|
|
IPSEC_CFLAGS= -DUSE_PF_KEY_V2
|
|
|
@@ -51,7 +51,7 @@
|
|
|
# hack libsysdep.a dependenc
|
|
|
${LIBSYSDEPDIR}/.depend ${LIBSYSDEP}:
|
|
|
cd ${LIBSYSDEPDIR} && \
|
|
|
- ${MAKE} --no-print-directory ${MAKEFLAGS} \
|
|
|
+ ${MAKE} --no-print-directory \
|
|
|
CFLAGS="${CFLAGS}" MKDEP="${MKDEP}" ${MAKECMDGOALS}
|
|
|
|
|
|
ifeq ($(findstring clean,$(MAKECMDGOALS)),clean)
|
|
|
--- isakmpd-20041012.orig/sysdep/linux/include/bitstring.h
|
|
|
+++ isakmpd-20041012/sysdep/linux/include/bitstring.h
|
|
|
@@ -0,0 +1,132 @@
|
|
|
+/* $OpenBSD: bitstring.h,v 1.4 2002/06/19 02:50:10 millert Exp $ */
|
|
|
+/* $NetBSD: bitstring.h,v 1.5 1997/05/14 15:49:55 pk Exp $ */
|
|
|
+
|
|
|
+/*
|
|
|
+ * Copyright (c) 1989, 1993
|
|
|
+ * The Regents of the University of California. All rights reserved.
|
|
|
+ *
|
|
|
+ * This code is derived from software contributed to Berkeley by
|
|
|
+ * Paul Vixie.
|
|
|
+ *
|
|
|
+ * 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. All advertising materials mentioning features or use of this software
|
|
|
+ * must display the following acknowledgement:
|
|
|
+ * This product includes software developed by the University of
|
|
|
+ * California, Berkeley and its contributors.
|
|
|
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
|
|
|
+ *
|
|
|
+ * @(#)bitstring.h 8.1 (Berkeley) 7/19/93
|
|
|
+ */
|
|
|
+
|
|
|
+#ifndef _BITSTRING_H_
|
|
|
+#define _BITSTRING_H_
|
|
|
+
|
|
|
+/* modified for SV/AT and bitstring bugfix by M.R.Murphy, 11oct91
|
|
|
+ * bitstr_size changed gratuitously, but shorter
|
|
|
+ * bit_alloc spelling error fixed
|
|
|
+ * the following were efficient, but didn't work, they've been made to
|
|
|
+ * work, but are no longer as efficient :-)
|
|
|
+ * bit_nclear, bit_nset, bit_ffc, bit_ffs
|
|
|
+ */
|
|
|
+typedef unsigned char bitstr_t;
|
|
|
+
|
|
|
+/* internal macros */
|
|
|
+ /* byte of the bitstring bit is in */
|
|
|
+#define _bit_byte(bit) \
|
|
|
+ ((bit) >> 3)
|
|
|
+
|
|
|
+ /* mask for the bit within its byte */
|
|
|
+#define _bit_mask(bit) \
|
|
|
+ (1 << ((bit)&0x7))
|
|
|
+
|
|
|
+/* external macros */
|
|
|
+ /* bytes in a bitstring of nbits bits */
|
|
|
+#define bitstr_size(nbits) \
|
|
|
+ (((nbits) + 7) >> 3)
|
|
|
+
|
|
|
+ /* allocate a bitstring */
|
|
|
+#define bit_alloc(nbits) \
|
|
|
+ (bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t))
|
|
|
+
|
|
|
+ /* allocate a bitstring on the stack */
|
|
|
+#define bit_decl(name, nbits) \
|
|
|
+ ((name)[bitstr_size(nbits)])
|
|
|
+
|
|
|
+ /* is bit N of bitstring name set? */
|
|
|
+#define bit_test(name, bit) \
|
|
|
+ ((name)[_bit_byte(bit)] & _bit_mask(bit))
|
|
|
+
|
|
|
+ /* set bit N of bitstring name */
|
|
|
+#define bit_set(name, bit) \
|
|
|
+ ((name)[_bit_byte(bit)] |= _bit_mask(bit))
|
|
|
+
|
|
|
+ /* clear bit N of bitstring name */
|
|
|
+#define bit_clear(name, bit) \
|
|
|
+ ((name)[_bit_byte(bit)] &= ~_bit_mask(bit))
|
|
|
+
|
|
|
+ /* clear bits start ... stop in bitstring */
|
|
|
+#define bit_nclear(name, start, stop) do { \
|
|
|
+ register bitstr_t *_name = name; \
|
|
|
+ register int _start = start, _stop = stop; \
|
|
|
+ while (_start <= _stop) { \
|
|
|
+ bit_clear(_name, _start); \
|
|
|
+ _start++; \
|
|
|
+ } \
|
|
|
+} while(0)
|
|
|
+
|
|
|
+ /* set bits start ... stop in bitstring */
|
|
|
+#define bit_nset(name, start, stop) do { \
|
|
|
+ register bitstr_t *_name = name; \
|
|
|
+ register int _start = start, _stop = stop; \
|
|
|
+ while (_start <= _stop) { \
|
|
|
+ bit_set(_name, _start); \
|
|
|
+ _start++; \
|
|
|
+ } \
|
|
|
+} while(0)
|
|
|
+
|
|
|
+ /* find first bit clear in name */
|
|
|
+#define bit_ffc(name, nbits, value) do { \
|
|
|
+ register bitstr_t *_name = name; \
|
|
|
+ register int _bit, _nbits = nbits, _value = -1; \
|
|
|
+ for (_bit = 0; _bit < _nbits; ++_bit) \
|
|
|
+ if (!bit_test(_name, _bit)) { \
|
|
|
+ _value = _bit; \
|
|
|
+ break; \
|
|
|
+ } \
|
|
|
+ *(value) = _value; \
|
|
|
+} while(0)
|
|
|
+
|
|
|
+ /* find first bit set in name */
|
|
|
+#define bit_ffs(name, nbits, value) do { \
|
|
|
+ register bitstr_t *_name = name; \
|
|
|
+ register int _bit, _nbits = nbits, _value = -1; \
|
|
|
+ for (_bit = 0; _bit < _nbits; ++_bit) \
|
|
|
+ if (bit_test(_name, _bit)) { \
|
|
|
+ _value = _bit; \
|
|
|
+ break; \
|
|
|
+ } \
|
|
|
+ *(value) = _value; \
|
|
|
+} while(0)
|
|
|
+
|
|
|
+#endif /* !_BITSTRING_H_ */
|
|
|
--- isakmpd-20041012.orig/sysdep/linux/include/sys/queue.h
|
|
|
+++ isakmpd-20041012/sysdep/linux/include/sys/queue.h
|
|
|
@@ -0,0 +1,453 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) 1991, 1993
|
|
|
+ * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
|
|
|
+ * must display the following acknowledgement:
|
|
|
+ * This product includes software developed by the University of
|
|
|
+ * California, Berkeley and its contributors.
|
|
|
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
|
|
|
+ *
|
|
|
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
|
|
|
+ * $FreeBSD: src/sys/sys/queue.h,v 1.45 2001/12/11 11:49:58 sheldonh Exp $
|
|
|
+ */
|
|
|
+
|
|
|
+#ifndef _SYS_QUEUE_H_
|
|
|
+#define _SYS_QUEUE_H_
|
|
|
+
|
|
|
+//#include <machine/ansi.h> /* for __offsetof */
|
|
|
+
|
|
|
+/*
|
|
|
+ * This file defines four types of data structures: singly-linked lists,
|
|
|
+ * singly-linked tail queues, lists and tail queues.
|
|
|
+ *
|
|
|
+ * A singly-linked list is headed by a single forward pointer. The elements
|
|
|
+ * are singly linked for minimum space and pointer manipulation overhead at
|
|
|
+ * the expense of O(n) removal for arbitrary elements. New elements can be
|
|
|
+ * added to the list after an existing element or at the head of the list.
|
|
|
+ * Elements being removed from the head of the list should use the explicit
|
|
|
+ * macro for this purpose for optimum efficiency. A singly-linked list may
|
|
|
+ * only be traversed in the forward direction. Singly-linked lists are ideal
|
|
|
+ * for applications with large datasets and few or no removals or for
|
|
|
+ * implementing a LIFO queue.
|
|
|
+ *
|
|
|
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
|
|
|
+ * head of the list and the other to the tail of the list. The elements are
|
|
|
+ * singly linked for minimum space and pointer manipulation overhead at the
|
|
|
+ * expense of O(n) removal for arbitrary elements. New elements can be added
|
|
|
+ * to the list after an existing element, at the head of the list, or at the
|
|
|
+ * end of the list. Elements being removed from the head of the tail queue
|
|
|
+ * should use the explicit macro for this purpose for optimum efficiency.
|
|
|
+ * A singly-linked tail queue may only be traversed in the forward direction.
|
|
|
+ * Singly-linked tail queues are ideal for applications with large datasets
|
|
|
+ * and few or no removals or for implementing a FIFO queue.
|
|
|
+ *
|
|
|
+ * A list is headed by a single forward pointer (or an array of forward
|
|
|
+ * pointers for a hash table header). The elements are doubly linked
|
|
|
+ * so that an arbitrary element can be removed without a need to
|
|
|
+ * traverse the list. New elements can be added to the list before
|
|
|
+ * or after an existing element or at the head of the list. A list
|
|
|
+ * may only be traversed in the forward direction.
|
|
|
+ *
|
|
|
+ * A tail queue is headed by a pair of pointers, one to the head of the
|
|
|
+ * list and the other to the tail of the list. The elements are doubly
|
|
|
+ * linked so that an arbitrary element can be removed without a need to
|
|
|
+ * traverse the list. New elements can be added to the list before or
|
|
|
+ * after an existing element, at the head of the list, or at the end of
|
|
|
+ * the list. A tail queue may be traversed in either direction.
|
|
|
+ *
|
|
|
+ * For details on the use of these macros, see the queue(3) manual page.
|
|
|
+ *
|
|
|
+ *
|
|
|
+ * SLIST LIST STAILQ TAILQ
|
|
|
+ * _HEAD + + + +
|
|
|
+ * _HEAD_INITIALIZER + + + +
|
|
|
+ * _ENTRY + + + +
|
|
|
+ * _INIT + + + +
|
|
|
+ * _EMPTY + + + +
|
|
|
+ * _FIRST + + + +
|
|
|
+ * _NEXT + + + +
|
|
|
+ * _PREV - - - +
|
|
|
+ * _LAST - - + +
|
|
|
+ * _FOREACH + + + +
|
|
|
+ * _FOREACH_REVERSE - - - +
|
|
|
+ * _INSERT_HEAD + + + +
|
|
|
+ * _INSERT_BEFORE - + - +
|
|
|
+ * _INSERT_AFTER + + + +
|
|
|
+ * _INSERT_TAIL - - + +
|
|
|
+ * _REMOVE_HEAD + - + -
|
|
|
+ * _REMOVE + + + +
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+/*
|
|
|
+ * Singly-linked List declarations.
|
|
|
+ */
|
|
|
+#define SLIST_HEAD(name, type) \
|
|
|
+struct name { \
|
|
|
+ struct type *slh_first; /* first element */ \
|
|
|
+}
|
|
|
+
|
|
|
+#define SLIST_HEAD_INITIALIZER(head) \
|
|
|
+ { NULL }
|
|
|
+
|
|
|
+#define SLIST_ENTRY(type) \
|
|
|
+struct { \
|
|
|
+ struct type *sle_next; /* next element */ \
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Singly-linked List functions.
|
|
|
+ */
|
|
|
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
|
|
+
|
|
|
+#define SLIST_FIRST(head) ((head)->slh_first)
|
|
|
+
|
|
|
+#define SLIST_FOREACH(var, head, field) \
|
|
|
+ for ((var) = SLIST_FIRST((head)); \
|
|
|
+ (var); \
|
|
|
+ (var) = SLIST_NEXT((var), field))
|
|
|
+
|
|
|
+#define SLIST_INIT(head) do { \
|
|
|
+ SLIST_FIRST((head)) = NULL; \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
|
|
+ SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
|
|
+ SLIST_NEXT((slistelm), field) = (elm); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
|
|
+ SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
|
|
+ SLIST_FIRST((head)) = (elm); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
|
|
+
|
|
|
+#define SLIST_REMOVE(head, elm, type, field) do { \
|
|
|
+ if (SLIST_FIRST((head)) == (elm)) { \
|
|
|
+ SLIST_REMOVE_HEAD((head), field); \
|
|
|
+ } \
|
|
|
+ else { \
|
|
|
+ struct type *curelm = SLIST_FIRST((head)); \
|
|
|
+ while (SLIST_NEXT(curelm, field) != (elm)) \
|
|
|
+ curelm = SLIST_NEXT(curelm, field); \
|
|
|
+ SLIST_NEXT(curelm, field) = \
|
|
|
+ SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
|
|
|
+ } \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define SLIST_REMOVE_HEAD(head, field) do { \
|
|
|
+ SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Singly-linked Tail queue declarations.
|
|
|
+ */
|
|
|
+#define STAILQ_HEAD(name, type) \
|
|
|
+struct name { \
|
|
|
+ struct type *stqh_first;/* first element */ \
|
|
|
+ struct type **stqh_last;/* addr of last next element */ \
|
|
|
+}
|
|
|
+
|
|
|
+#define STAILQ_HEAD_INITIALIZER(head) \
|
|
|
+ { NULL, &(head).stqh_first }
|
|
|
+
|
|
|
+#define STAILQ_ENTRY(type) \
|
|
|
+struct { \
|
|
|
+ struct type *stqe_next; /* next element */ \
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Singly-linked Tail queue functions.
|
|
|
+ */
|
|
|
+#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
|
|
+
|
|
|
+#define STAILQ_FIRST(head) ((head)->stqh_first)
|
|
|
+
|
|
|
+#define STAILQ_FOREACH(var, head, field) \
|
|
|
+ for((var) = STAILQ_FIRST((head)); \
|
|
|
+ (var); \
|
|
|
+ (var) = STAILQ_NEXT((var), field))
|
|
|
+
|
|
|
+#define STAILQ_INIT(head) do { \
|
|
|
+ STAILQ_FIRST((head)) = NULL; \
|
|
|
+ (head)->stqh_last = &STAILQ_FIRST((head)); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
|
|
+ if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
|
|
|
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
|
|
+ STAILQ_NEXT((tqelm), field) = (elm); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
|
|
+ if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
|
|
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
|
|
+ STAILQ_FIRST((head)) = (elm); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
|
|
+ STAILQ_NEXT((elm), field) = NULL; \
|
|
|
+ *(head)->stqh_last = (elm); \
|
|
|
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define STAILQ_LAST(head, type, field) \
|
|
|
+ (STAILQ_EMPTY(head) ? \
|
|
|
+ NULL : \
|
|
|
+ ((struct type *) \
|
|
|
+ ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
|
|
|
+
|
|
|
+#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
|
|
+
|
|
|
+#define STAILQ_REMOVE(head, elm, type, field) do { \
|
|
|
+ if (STAILQ_FIRST((head)) == (elm)) { \
|
|
|
+ STAILQ_REMOVE_HEAD(head, field); \
|
|
|
+ } \
|
|
|
+ else { \
|
|
|
+ struct type *curelm = STAILQ_FIRST((head)); \
|
|
|
+ while (STAILQ_NEXT(curelm, field) != (elm)) \
|
|
|
+ curelm = STAILQ_NEXT(curelm, field); \
|
|
|
+ if ((STAILQ_NEXT(curelm, field) = \
|
|
|
+ STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
|
|
|
+ (head)->stqh_last = &STAILQ_NEXT((curelm), field);\
|
|
|
+ } \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define STAILQ_REMOVE_HEAD(head, field) do { \
|
|
|
+ if ((STAILQ_FIRST((head)) = \
|
|
|
+ STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
|
|
+ (head)->stqh_last = &STAILQ_FIRST((head)); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
|
|
|
+ if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
|
|
|
+ (head)->stqh_last = &STAILQ_FIRST((head)); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+/*
|
|
|
+ * List declarations.
|
|
|
+ */
|
|
|
+#define LIST_HEAD(name, type) \
|
|
|
+struct name { \
|
|
|
+ struct type *lh_first; /* first element */ \
|
|
|
+}
|
|
|
+
|
|
|
+#define LIST_HEAD_INITIALIZER(head) \
|
|
|
+ { NULL }
|
|
|
+
|
|
|
+#define LIST_ENTRY(type) \
|
|
|
+struct { \
|
|
|
+ struct type *le_next; /* next element */ \
|
|
|
+ struct type **le_prev; /* address of previous next element */ \
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * List functions.
|
|
|
+ */
|
|
|
+
|
|
|
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
|
|
+
|
|
|
+#define LIST_FIRST(head) ((head)->lh_first)
|
|
|
+
|
|
|
+#define LIST_FOREACH(var, head, field) \
|
|
|
+ for ((var) = LIST_FIRST((head)); \
|
|
|
+ (var); \
|
|
|
+ (var) = LIST_NEXT((var), field))
|
|
|
+
|
|
|
+#define LIST_INIT(head) do { \
|
|
|
+ LIST_FIRST((head)) = NULL; \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
|
|
+ if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
|
|
|
+ LIST_NEXT((listelm), field)->field.le_prev = \
|
|
|
+ &LIST_NEXT((elm), field); \
|
|
|
+ LIST_NEXT((listelm), field) = (elm); \
|
|
|
+ (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
|
|
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
|
|
|
+ LIST_NEXT((elm), field) = (listelm); \
|
|
|
+ *(listelm)->field.le_prev = (elm); \
|
|
|
+ (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define LIST_INSERT_HEAD(head, elm, field) do { \
|
|
|
+ if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
|
|
+ LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
|
|
|
+ LIST_FIRST((head)) = (elm); \
|
|
|
+ (elm)->field.le_prev = &LIST_FIRST((head)); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
|
|
+
|
|
|
+#define LIST_REMOVE(elm, field) do { \
|
|
|
+ if (LIST_NEXT((elm), field) != NULL) \
|
|
|
+ LIST_NEXT((elm), field)->field.le_prev = \
|
|
|
+ (elm)->field.le_prev; \
|
|
|
+ *(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Tail queue declarations.
|
|
|
+ */
|
|
|
+#define TAILQ_HEAD(name, type) \
|
|
|
+struct name { \
|
|
|
+ struct type *tqh_first; /* first element */ \
|
|
|
+ struct type **tqh_last; /* addr of last next element */ \
|
|
|
+}
|
|
|
+
|
|
|
+#define TAILQ_HEAD_INITIALIZER(head) \
|
|
|
+ { NULL, &(head).tqh_first }
|
|
|
+
|
|
|
+#define TAILQ_ENTRY(type) \
|
|
|
+struct { \
|
|
|
+ struct type *tqe_next; /* next element */ \
|
|
|
+ struct type **tqe_prev; /* address of previous next element */ \
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Tail queue functions.
|
|
|
+ */
|
|
|
+#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
|
|
+
|
|
|
+#define TAILQ_FIRST(head) ((head)->tqh_first)
|
|
|
+
|
|
|
+#define TAILQ_FOREACH(var, head, field) \
|
|
|
+ for ((var) = TAILQ_FIRST((head)); \
|
|
|
+ (var); \
|
|
|
+ (var) = TAILQ_NEXT((var), field))
|
|
|
+
|
|
|
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
|
|
+ for ((var) = TAILQ_LAST((head), headname); \
|
|
|
+ (var); \
|
|
|
+ (var) = TAILQ_PREV((var), headname, field))
|
|
|
+
|
|
|
+#define TAILQ_INIT(head) do { \
|
|
|
+ TAILQ_FIRST((head)) = NULL; \
|
|
|
+ (head)->tqh_last = &TAILQ_FIRST((head)); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
|
|
+ if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
|
|
|
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
|
|
+ &TAILQ_NEXT((elm), field); \
|
|
|
+ else \
|
|
|
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
|
|
+ TAILQ_NEXT((listelm), field) = (elm); \
|
|
|
+ (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
|
|
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
|
|
+ TAILQ_NEXT((elm), field) = (listelm); \
|
|
|
+ *(listelm)->field.tqe_prev = (elm); \
|
|
|
+ (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
|
|
+ if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
|
|
+ TAILQ_FIRST((head))->field.tqe_prev = \
|
|
|
+ &TAILQ_NEXT((elm), field); \
|
|
|
+ else \
|
|
|
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
|
|
+ TAILQ_FIRST((head)) = (elm); \
|
|
|
+ (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
|
|
+ TAILQ_NEXT((elm), field) = NULL; \
|
|
|
+ (elm)->field.tqe_prev = (head)->tqh_last; \
|
|
|
+ *(head)->tqh_last = (elm); \
|
|
|
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define TAILQ_LAST(head, headname) \
|
|
|
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
|
|
|
+
|
|
|
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
|
|
+
|
|
|
+#define TAILQ_PREV(elm, headname, field) \
|
|
|
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
|
|
+
|
|
|
+#define TAILQ_REMOVE(head, elm, field) do { \
|
|
|
+ if ((TAILQ_NEXT((elm), field)) != NULL) \
|
|
|
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
|
|
+ (elm)->field.tqe_prev; \
|
|
|
+ else \
|
|
|
+ (head)->tqh_last = (elm)->field.tqe_prev; \
|
|
|
+ *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+
|
|
|
+#ifdef _KERNEL
|
|
|
+
|
|
|
+/*
|
|
|
+ * XXX insque() and remque() are an old way of handling certain queues.
|
|
|
+ * They bogusly assumes that all queue heads look alike.
|
|
|
+ */
|
|
|
+
|
|
|
+struct quehead {
|
|
|
+ struct quehead *qh_link;
|
|
|
+ struct quehead *qh_rlink;
|
|
|
+};
|
|
|
+
|
|
|
+#ifdef __GNUC__
|
|
|
+
|
|
|
+static __inline void
|
|
|
+insque(void *a, void *b)
|
|
|
+{
|
|
|
+ struct quehead *element = (struct quehead *)a,
|
|
|
+ *head = (struct quehead *)b;
|
|
|
+
|
|
|
+ element->qh_link = head->qh_link;
|
|
|
+ element->qh_rlink = head;
|
|
|
+ head->qh_link = element;
|
|
|
+ element->qh_link->qh_rlink = element;
|
|
|
+}
|
|
|
+
|
|
|
+static __inline void
|
|
|
+remque(void *a)
|
|
|
+{
|
|
|
+ struct quehead *element = (struct quehead *)a;
|
|
|
+
|
|
|
+ element->qh_link->qh_rlink = element->qh_rlink;
|
|
|
+ element->qh_rlink->qh_link = element->qh_link;
|
|
|
+ element->qh_rlink = 0;
|
|
|
+}
|
|
|
+
|
|
|
+#else /* !__GNUC__ */
|
|
|
+
|
|
|
+void insque __P((void *a, void *b));
|
|
|
+void remque __P((void *a));
|
|
|
+
|
|
|
+#endif /* __GNUC__ */
|
|
|
+
|
|
|
+#endif /* _KERNEL */
|
|
|
+
|
|
|
+#endif /* !_SYS_QUEUE_H_ */
|
|
|
--- isakmpd-20041012.orig/sysdep/common/pcap.h
|
|
|
+++ isakmpd-20041012/sysdep/common/pcap.h
|
|
|
@@ -55,8 +55,13 @@
|
|
|
u_int32_t linktype; /* data link type (DLT_*) */
|
|
|
};
|
|
|
|
|
|
+struct pcap_timeval {
|
|
|
+ int32_t tv_sec; /* seconds */
|
|
|
+ int32_t tv_usec; /* microseconds */
|
|
|
+};
|
|
|
+
|
|
|
struct pcap_pkthdr {
|
|
|
- struct timeval ts; /* time stamp */
|
|
|
+ struct pcap_timeval ts; /* time stamp */
|
|
|
u_int32_t caplen; /* length of portion present */
|
|
|
u_int32_t len; /* length this packet (off wire) */
|
|
|
};
|
|
|
--- isakmpd-20041012.orig/sysdep/common/libsysdep/arc4random.c
|
|
|
+++ isakmpd-20041012/sysdep/common/libsysdep/arc4random.c
|
|
|
@@ -78,7 +78,7 @@
|
|
|
static void
|
|
|
arc4_stir(struct arc4_stream *as)
|
|
|
{
|
|
|
- int fd;
|
|
|
+ int fd, i;
|
|
|
struct {
|
|
|
struct timeval tv;
|
|
|
u_int8_t rnd[128 - sizeof(struct timeval)];
|
|
|
--- isakmpd-20041012.orig/x509v3.cnf
|
|
|
+++ isakmpd-20041012/x509v3.cnf
|
|
|
@@ -0,0 +1,26 @@
|
|
|
+# default settings
|
|
|
+CERTPATHLEN = 1
|
|
|
+CERTUSAGE = digitalSignature,keyCertSign
|
|
|
+CERTIP = 0.0.0.0
|
|
|
+CERTFQDN = nohost.nodomain
|
|
|
+
|
|
|
+# This section should be referenced when building an x509v3 CA
|
|
|
+# Certificate.
|
|
|
+# The default path length and the key usage can be overriden
|
|
|
+# modified by setting the CERTPATHLEN and CERTUSAGE environment
|
|
|
+# variables.
|
|
|
+[x509v3_CA]
|
|
|
+basicConstraints=critical,CA:true,pathlen:$ENV::CERTPATHLEN
|
|
|
+keyUsage=$ENV::CERTUSAGE
|
|
|
+
|
|
|
+# This section should be referenced to add an IP Address
|
|
|
+# as an alternate subject name, needed by isakmpd
|
|
|
+# The address must be provided in the CERTIP environment variable
|
|
|
+[x509v3_IPAddr]
|
|
|
+subjectAltName=IP:$ENV::CERTIP
|
|
|
+
|
|
|
+# This section should be referenced to add a FQDN hostname
|
|
|
+# as an alternate subject name, needed by isakmpd
|
|
|
+# The address must be provided in the CERTFQDN environment variable
|
|
|
+[x509v3_FQDN]
|
|
|
+subjectAltName=DNS:$ENV::CERTFQDN
|
|
|
|
|
|
|