You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openwrt/package/isakmpd/patches/010-debian_3.patch

1707 lines
53 KiB
Diff

--- 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<>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<>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