diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2006-09-07 12:40:03 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2006-09-07 12:40:03 +0000 |
commit | 7ef4836b71fc990c63fbf8027499339c16ba5f90 (patch) | |
tree | 2a0f4d0cacbd184306a8a56929a3bfdf736f81e5 /package | |
parent | 57127d8916fee08e09cc95256eaf5f53d4b1ba2b (diff) |
upgrade isakmpd, add security fix
git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@4768 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package')
-rw-r--r-- | package/isakmpd/Makefile | 16 | ||||
-rw-r--r-- | package/isakmpd/patches/01-standardize.patch | 133 | ||||
-rw-r--r-- | package/isakmpd/patches/010-debian_3.patch | 1706 | ||||
-rw-r--r-- | package/isakmpd/patches/020-standardize.patch | 59 | ||||
-rw-r--r-- | package/isakmpd/patches/030-openssl_hashes.patch (renamed from package/isakmpd/patches/02-openssl_hashes.patch) | 0 | ||||
-rw-r--r-- | package/isakmpd/patches/040-security_fix.patch | 22 |
6 files changed, 1796 insertions, 140 deletions
diff --git a/package/isakmpd/Makefile b/package/isakmpd/Makefile index 5e268e52a0..98cb36f2c2 100644 --- a/package/isakmpd/Makefile +++ b/package/isakmpd/Makefile @@ -9,14 +9,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=isakmpd -PKG_VERSION:=20040115cvs +PKG_VERSION:=20041012 PKG_RELEASE:=1 -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_SOURCE_URL:=http://downloads.openwrt.org/sources/ -PKG_MD5SUM:=9f59b10d57cfed5e95743255f1c1620d -PKG_CAT:=bzcat +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION).orig +PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).orig.tar.gz +PKG_SOURCE_URL:=http://ftp.debian.org/debian/pool/main/i/isakmpd/ +PKG_MD5SUM:=e6d25a9e232fb186e1a48dc06453bd57 +PKG_CAT:=zcat PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install @@ -35,8 +35,10 @@ endef define Build/Compile $(call Build/Compile/Default,LINUX_DIR="$(LINUX_DIR)" \ STAGING_DIR="$(STAGING_DIR)" \ - DESTDIR="$(PKG_INSTALL_DIR)") + DESTDIR="$(PKG_INSTALL_DIR)" \ + ) $(MAKE) -C $(PKG_BUILD_DIR) \ + STAGING_DIR="$(STAGING_DIR)" \ DESTDIR="$(PKG_INSTALL_DIR)" \ INSTALL="install -c" \ install-bin diff --git a/package/isakmpd/patches/01-standardize.patch b/package/isakmpd/patches/01-standardize.patch deleted file mode 100644 index f97c77630e..0000000000 --- a/package/isakmpd/patches/01-standardize.patch +++ /dev/null @@ -1,133 +0,0 @@ -diff -urN isakmpd/GNUmakefile isakmpd.new/GNUmakefile ---- isakmpd/GNUmakefile 2004-01-16 13:36:32.000000000 +0100 -+++ isakmpd.new/GNUmakefile 2006-09-03 17:33:03.000000000 +0200 -@@ -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} -@@ -53,11 +53,11 @@ - PROG= isakmpd - - ifndef BINDIR --BINDIR= /sbin --endif --ifndef LDSTATIC --LDSTATIC= -static -+BINDIR= /usr/sbin - 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 \ -@@ -154,7 +154,7 @@ - - ifdef USE_KEYNOTE - USE_LIBCRYPTO= yes --LDADD+= -lkeynote -lm -+LDADD+= -L${LIBKEYNOTEDIR} -lkeynote -lm - DPADD+= ${LIBKEYNOTE} ${LIBM} - POLICY= policy.c - CFLAGS+= -DUSE_KEYNOTE -@@ -238,3 +238,16 @@ - - realcleandepend: - rm -f .depend tags -+ -+# Install rules -+install: install-bin install-man -+ -+install-bin: isakmpd -+ -mkdir -p $(DESTDIR)$(BINDIR) -+ $(INSTALL) $(INSTALL_OPTS) -m 755 isakmpd $(DESTDIR)$(BINDIR) -+ -+install-man: -+ -mkdir -p $(DESTDIR)$(MANDIR)/man8 -+ $(INSTALL) $(INSTALL_OPTS) -m 444 isakmpd.8 $(DESTDIR)$(MANDIR)/man8 -+ -mkdir -p $(DESTDIR)$(MANDIR)/man5 -+ $(INSTALL) $(INSTALL_OPTS) -m 444 isakmpd.conf.5 isakmpd.policy.5 $(DESTDIR)$(MANDIR)/man5 -diff -urN isakmpd/samples/Makefile isakmpd.new/samples/Makefile ---- isakmpd/samples/Makefile 2003-06-03 16:39:50.000000000 +0200 -+++ isakmpd.new/samples/Makefile 2006-09-03 17:07:24.000000000 +0200 -@@ -26,7 +26,7 @@ - # - - FILES= VPN-* policy singlehost-* --TARGETDIR= /usr/share/ipsec/isakmpd -+TARGETDIR= /usr/share/isakmpd/samples - - # The mkdir below is for installation on OpenBSD pre 2.7 - install: -diff -urN isakmpd/sysdep/linux/GNUmakefile.sysdep isakmpd.new/sysdep/linux/GNUmakefile.sysdep ---- isakmpd/sysdep/linux/GNUmakefile.sysdep 2004-01-16 13:36:42.000000000 +0100 -+++ isakmpd.new/sysdep/linux/GNUmakefile.sysdep 2006-09-03 17:16:48.000000000 +0200 -@@ -25,18 +25,20 @@ - # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - # - --LIBGMP:= /usr/lib/libgmp.a --LIBCRYPTO:= /usr/lib/libcrypto.a -+LIBGMP:= -lgmp -+LIBCRYPTO:= -lcrypto - LIBSYSDEPDIR:= ${.CURDIR}/sysdep/common/libsysdep - LIBSYSDEP:= ${LIBSYSDEPDIR}/libsysdep.a - --LDADD+= -lgmp ${LIBSYSDEP} ${LIBCRYPTO} -+LIBKEYNOTEDIR:= $(STAGING_DIR)/usr/include -+ -+LDADD+= -L$(STAGING_DIR)/usr/lib ${LIBGMP} ${LIBSYSDEP} ${LIBCRYPTO} --DPADD+= ${LIBGMP} ${LIBSYSDEP} -+DPADD+= ${LIBSYSDEP} - - CFLAGS+= -DHAVE_GETNAMEINFO -DUSE_OLD_SOCKADDR -DHAVE_PCAP \ - -DNEED_SYSDEP_APP -DMP_FLAVOUR=MP_FLAVOUR_GMP \ -- -I/usr/src/linux/include -I${.CURDIR}/sysdep/common \ -- -I/usr/include/openssl -+ -I$(LINUX_DIR)/include -I${.CURDIR}/sysdep/common \ -+ -I$(STAGING_DIR)/usr/include/openssl -I${LIBKEYNOTEDIR} - - FEATURES= debug tripledes blowfish cast ec aggressive x509 policy - -@@ -50,7 +52,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) -diff -urN isakmpd/x509.c isakmpd.new/x509.c ---- isakmpd/x509.c 2004-01-06 01:09:19.000000000 +0100 -+++ isakmpd.new/x509.c 2006-09-03 17:07:24.000000000 +0200 -@@ -969,14 +969,14 @@ - * trust. - */ - X509_STORE_CTX_init (&csc, x509_cas, cert, NULL); --#if OPENSSL_VERSION_NUMBER >= 0x00907000L -- /* XXX See comment in x509_read_crls_from_dir. */ -- if (x509_cas->flags & X509_V_FLAG_CRL_CHECK) -+//#if OPENSSL_VERSION_NUMBER >= 0x00907000L -+ /* XXX See comment in x509_read_crls_from_dir. */ -+ /*if (x509_cas->flags & X509_V_FLAG_CRL_CHECK) - { - X509_STORE_CTX_set_flags (&csc, X509_V_FLAG_CRL_CHECK); - X509_STORE_CTX_set_flags (&csc, X509_V_FLAG_CRL_CHECK_ALL); - } --#endif -+#endif */ - res = X509_verify_cert (&csc); - err = csc.error; - X509_STORE_CTX_cleanup (&csc); diff --git a/package/isakmpd/patches/010-debian_3.patch b/package/isakmpd/patches/010-debian_3.patch new file mode 100644 index 0000000000..551ae1ffcd --- /dev/null +++ b/package/isakmpd/patches/010-debian_3.patch @@ -0,0 +1,1706 @@ +--- 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 + diff --git a/package/isakmpd/patches/020-standardize.patch b/package/isakmpd/patches/020-standardize.patch new file mode 100644 index 0000000000..d3dfabf349 --- /dev/null +++ b/package/isakmpd/patches/020-standardize.patch @@ -0,0 +1,59 @@ +diff -urN isakmpd/GNUmakefile isakmpd.new/GNUmakefile +--- isakmpd/GNUmakefile 2004-01-16 13:36:32.000000000 +0100 ++++ isakmpd.new/GNUmakefile 2006-09-03 17:33:03.000000000 +0200 +@@ -238,3 +238,16 @@ + + realcleandepend: + rm -f .depend tags ++ ++# Install rules ++install: install-bin install-man ++ ++install-bin: isakmpd ++ -mkdir -p $(DESTDIR)$(BINDIR) ++ $(INSTALL) $(INSTALL_OPTS) -m 755 isakmpd $(DESTDIR)$(BINDIR) ++ ++install-man: ++ -mkdir -p $(DESTDIR)$(MANDIR)/man8 ++ $(INSTALL) $(INSTALL_OPTS) -m 444 isakmpd.8 $(DESTDIR)$(MANDIR)/man8 ++ -mkdir -p $(DESTDIR)$(MANDIR)/man5 ++ $(INSTALL) $(INSTALL_OPTS) -m 444 isakmpd.conf.5 isakmpd.policy.5 $(DESTDIR)$(MANDIR)/man5 +diff -urN isakmpd/samples/Makefile isakmpd.new/samples/Makefile +--- isakmpd/samples/Makefile 2003-06-03 16:39:50.000000000 +0200 ++++ isakmpd.new/samples/Makefile 2006-09-03 17:07:24.000000000 +0200 +@@ -26,7 +26,7 @@ + # + + FILES= VPN-* policy singlehost-* +-TARGETDIR= /usr/share/ipsec/isakmpd ++TARGETDIR= /usr/share/isakmpd/samples + + # The mkdir below is for installation on OpenBSD pre 2.7 + install: + +diff -urN isakmp.old/sysdep/linux/GNUmakefile.sysdep isakmp.dev/sysdep/linux/GNUmakefile.sysdep +--- isakmp.old/sysdep/linux/GNUmakefile.sysdep 2006-09-07 13:49:20.000000000 +0200 ++++ isakmp.dev/sysdep/linux/GNUmakefile.sysdep 2006-09-07 13:51:41.000000000 +0200 +@@ -25,18 +25,18 @@ + # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # + +-LIBGMP:= /usr/lib/libgmp.a +-LIBCRYPTO:= /usr/lib/libcrypto.a ++LIBGMP:= ++LIBCRYPTO:= -lcrypto + LIBSYSDEPDIR:= ${.CURDIR}/sysdep/common/libsysdep + LIBSYSDEP:= ${LIBSYSDEPDIR}/libsysdep.a + +-LDADD+= -lgmp ${LIBSYSDEP} ${LIBCRYPTO} ++LDADD+= -L$(STAGING_DIR)/usr/lib -lgmp ${LIBSYSDEP} ${LIBCRYPTO} + DPADD+= ${LIBGMP} ${LIBSYSDEP} + + 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 ++ -I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/usr/include/openssl -I$(LINUX_DIR)/include + + FEATURES= debug tripledes blowfish cast ec aggressive x509 policy + FEATURES+= dpd nat_traversal isakmp_cfg des aes diff --git a/package/isakmpd/patches/02-openssl_hashes.patch b/package/isakmpd/patches/030-openssl_hashes.patch index 680db86a31..680db86a31 100644 --- a/package/isakmpd/patches/02-openssl_hashes.patch +++ b/package/isakmpd/patches/030-openssl_hashes.patch diff --git a/package/isakmpd/patches/040-security_fix.patch b/package/isakmpd/patches/040-security_fix.patch new file mode 100644 index 0000000000..9128880107 --- /dev/null +++ b/package/isakmpd/patches/040-security_fix.patch @@ -0,0 +1,22 @@ +Index: sbin/isakmpd/ipsec.c +=================================================================== +RCS file: /cvs/src/sbin/isakmpd/ipsec.c,v +retrieving revision 1.122 +retrieving revision 1.122.2.1 +diff -u -p -r1.122 -r1.122.2.1 +--- isakmpd/ipsec.c 23 Sep 2005 14:44:03 -0000 1.122 ++++ isakmpd/ipsec.c 19 Aug 2006 20:23:28 -0000 1.122.2.1 +@@ -2076,9 +2076,10 @@ ipsec_proto_init(struct proto *proto, ch + { + struct ipsec_proto *iproto = proto->data; + +- if (proto->sa->phase == 2 && section) +- iproto->replay_window = conf_get_num(section, "ReplayWindow", +- DEFAULT_REPLAY_WINDOW); ++ if (proto->sa->phase == 2) ++ iproto->replay_window = section ? conf_get_num(section, ++ "ReplayWindow", DEFAULT_REPLAY_WINDOW) : ++ DEFAULT_REPLAY_WINDOW; + } + + /* |