upgrade isakmpd, add security fix
authorFelix Fietkau <nbd@openwrt.org>
Thu, 7 Sep 2006 12:40:03 +0000 (12:40 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Thu, 7 Sep 2006 12:40:03 +0000 (12:40 +0000)
SVN-Revision: 4768

openwrt/package/isakmpd/Makefile
openwrt/package/isakmpd/patches/01-standardize.patch [deleted file]
openwrt/package/isakmpd/patches/010-debian_3.patch [new file with mode: 0644]
openwrt/package/isakmpd/patches/02-openssl_hashes.patch [deleted file]
openwrt/package/isakmpd/patches/020-standardize.patch [new file with mode: 0644]
openwrt/package/isakmpd/patches/030-openssl_hashes.patch [new file with mode: 0644]
openwrt/package/isakmpd/patches/040-security_fix.patch [new file with mode: 0644]

index 5e268e52a0e39225f5f60d0c8af4a3dfcfbfaa0a..98cb36f2c2a24ce77f71f41720cd994c05ce9172 100644 (file)
@@ -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/openwrt/package/isakmpd/patches/01-standardize.patch b/openwrt/package/isakmpd/patches/01-standardize.patch
deleted file mode 100644 (file)
index f97c776..0000000
+++ /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/openwrt/package/isakmpd/patches/010-debian_3.patch b/openwrt/package/isakmpd/patches/010-debian_3.patch
new file mode 100644 (file)
index 0000000..551ae1f
--- /dev/null
@@ -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/openwrt/package/isakmpd/patches/02-openssl_hashes.patch b/openwrt/package/isakmpd/patches/02-openssl_hashes.patch
deleted file mode 100644 (file)
index 680db86..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-diff -urN isakmpd/GNUmakefile isakmpd.new/GNUmakefile
---- isakmpd/GNUmakefile        2006-09-01 19:29:05.000000000 +0200
-+++ isakmpd.new/GNUmakefile    2006-09-01 19:29:28.000000000 +0200
-@@ -75,13 +75,14 @@
-               isakmp_fld.c isakmp_fld.h
- MAN=          isakmpd.8 isakmpd.conf.5 isakmpd.policy.5
--CFLAGS+=      -O2 ${DEBUG} -Wall -DNEED_SYSDEP_APP \
-+CFLAGS+=      ${DEBUG} -Wall -DNEED_SYSDEP_APP \
-               -I${.CURDIR} -I${.CURDIR}/sysdep/${OS} -I. \
- # Different debugging & profiling suggestions
- # Include symbolic debugging info
- DEBUG=                -g
-+CFLAGS+=      -g
- # Do execution time profiles
- #CFLAGS+=     -pg
-@@ -172,6 +173,14 @@
- CFLAGS+=        -DUSE_RAWKEY
- endif
-+ifdef USE_OPENSSL_MD5
-+CFLAGS+=      -DUSE_OPENSSL_MD5
-+endif
-+
-+ifdef USE_OPENSSL_SHA1
-+CFLAGS+=      -DUSE_OPENSSL_SHA1
-+endif
-+
- SRCS+=                ${IPSEC_SRCS} ${X509} ${POLICY} ${EC} ${AGGRESSIVE} ${DNSSEC} \
-               $(ISAKMP_CFG)
- CFLAGS+=      ${IPSEC_CFLAGS}
-diff -urN isakmpd/sysdep/common/libsysdep/GNUmakefile isakmpd.new/sysdep/common/libsysdep/GNUmakefile
---- isakmpd/sysdep/common/libsysdep/GNUmakefile        2003-06-03 16:52:06.000000000 +0200
-+++ isakmpd.new/sysdep/common/libsysdep/GNUmakefile    2006-09-01 19:29:28.000000000 +0200
-@@ -31,10 +31,18 @@
- .CURDIR:=     $(shell pwd)
- LIB=          sysdep
--SRCS=         arc4random.c blowfish.c cast.c md5.c sha1.c strlcat.c strlcpy.c
-+SRCS=         arc4random.c blowfish.c cast.c strlcat.c strlcpy.c
- NOMAN=
- CFLAGS+=      -I${.CURDIR}/.. -I/usr/include/machine
-+ifeq (,$(findstring USE_OPENSSL_MD5,$(CFLAGS)))
-+SRCS+=md5.c
-+endif
-+
-+ifeq (,$(findstring USE_OPENSSL_SHA1,$(CFLAGS)))
-+SRCS+=sha1.c
-+endif
-+
- lib${LIB}.a: ${SRCS:%.c=%.o}
-       ar cq $@ ${SRCS:%.c=%.o}
-diff -urN isakmpd/sysdep/common/libsysdep/md5.c isakmpd.new/sysdep/common/libsysdep/md5.c
---- isakmpd/sysdep/common/libsysdep/md5.c      2002-06-14 23:34:58.000000000 +0200
-+++ isakmpd.new/sysdep/common/libsysdep/md5.c  2006-09-01 19:29:28.000000000 +0200
-@@ -5,6 +5,8 @@
-  * changes to accommodate it in the kernel by ji.
-  */
-+#ifndef USE_OPENSSL_MD5
-+
- /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
-  */
-@@ -390,3 +392,4 @@
- #endif
- #endif
-+#endif /* USE_OPENSSL_MD5 */
-diff -urN isakmpd/sysdep/common/libsysdep/sha1.c isakmpd.new/sysdep/common/libsysdep/sha1.c
---- isakmpd/sysdep/common/libsysdep/sha1.c     2001-01-28 23:38:48.000000000 +0100
-+++ isakmpd.new/sysdep/common/libsysdep/sha1.c 2006-09-01 19:29:28.000000000 +0200
-@@ -1,5 +1,7 @@
- /*    $OpenBSD: sha1.c,v 1.2 2001/01/28 22:38:48 niklas Exp $ */
-+#ifndef USE_OPENSSL_SHA1
-+
- /*
- SHA-1 in C
- By Steve Reid <steve@edmweb.com>
-@@ -171,3 +173,5 @@
-     SHA1Transform(context->state, context->buffer);
- #endif
- }
-+
-+#endif /* USE_OPENSSL_SHA1 */
-diff -urN isakmpd/sysdep/common/md5.h isakmpd.new/sysdep/common/md5.h
---- isakmpd/sysdep/common/md5.h        2001-01-28 23:38:47.000000000 +0100
-+++ isakmpd.new/sysdep/common/md5.h    2006-09-01 19:29:28.000000000 +0200
-@@ -1,5 +1,15 @@
- /*    $OpenBSD: md5.h,v 1.2 2001/01/28 22:38:47 niklas Exp $  */
-+#ifdef USE_OPENSSL_MD5
-+
-+#include <openssl/md5.h>
-+
-+#define MD5Init               MD5_Init
-+#define       MD5Update       MD5_Update
-+#define       MD5Final        MD5_Final
-+
-+#else /* USE_OPENSSL_MD5 */
-+
- /* GLOBAL.H - RSAREF types and constants
-  */
-@@ -71,3 +81,5 @@
- void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
- #define _MD5_H_
-+
-+#endif        /* USE_OPENSSL_MD5 */
-diff -urN isakmpd/sysdep/common/sha1.h isakmpd.new/sysdep/common/sha1.h
---- isakmpd/sysdep/common/sha1.h       2001-01-28 23:38:47.000000000 +0100
-+++ isakmpd.new/sysdep/common/sha1.h   2006-09-01 19:29:28.000000000 +0200
-@@ -1,5 +1,16 @@
- /*    $OpenBSD: sha1.h,v 1.2 2001/01/28 22:38:47 niklas Exp $ */
-+#ifdef USE_OPENSSL_SHA1
-+
-+#include <openssl/sha.h>
-+
-+typedef SHA_CTX SHA1_CTX;
-+#define       SHA1Init        SHA1_Init
-+#define       SHA1Update      SHA1_Update
-+#define       SHA1Final       SHA1_Final
-+
-+#else /* USE_OPENSSL_SHA1 */
-+
- /*
- SHA-1 in C
- By Steve Reid <steve@edmweb.com>
-@@ -16,3 +27,5 @@
- void SHA1Init(SHA1_CTX* context);
- void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
- void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
-+
-+#endif        /* USE_OPENSSL_SHA1 */
-diff -urN isakmpd/sysdep/linux/GNUmakefile.sysdep isakmpd.new/sysdep/linux/GNUmakefile.sysdep
---- isakmpd/sysdep/linux/GNUmakefile.sysdep    2006-09-01 19:29:05.000000000 +0200
-+++ isakmpd.new/sysdep/linux/GNUmakefile.sysdep        2006-09-01 19:29:29.000000000 +0200
-@@ -48,6 +48,8 @@
- USE_LIBCRYPO= defined
- HAVE_DLOPEN=  defined
- USE_KEYNOTE=  defined
-+USE_OPENSSL_MD5=      defined
-+USE_OPENSSL_SHA1=     defined
- # hack libsysdep.a dependenc
- ${LIBSYSDEPDIR}/.depend ${LIBSYSDEP}:
diff --git a/openwrt/package/isakmpd/patches/020-standardize.patch b/openwrt/package/isakmpd/patches/020-standardize.patch
new file mode 100644 (file)
index 0000000..d3dfabf
--- /dev/null
@@ -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/openwrt/package/isakmpd/patches/030-openssl_hashes.patch b/openwrt/package/isakmpd/patches/030-openssl_hashes.patch
new file mode 100644 (file)
index 0000000..680db86
--- /dev/null
@@ -0,0 +1,154 @@
+diff -urN isakmpd/GNUmakefile isakmpd.new/GNUmakefile
+--- isakmpd/GNUmakefile        2006-09-01 19:29:05.000000000 +0200
++++ isakmpd.new/GNUmakefile    2006-09-01 19:29:28.000000000 +0200
+@@ -75,13 +75,14 @@
+               isakmp_fld.c isakmp_fld.h
+ MAN=          isakmpd.8 isakmpd.conf.5 isakmpd.policy.5
+-CFLAGS+=      -O2 ${DEBUG} -Wall -DNEED_SYSDEP_APP \
++CFLAGS+=      ${DEBUG} -Wall -DNEED_SYSDEP_APP \
+               -I${.CURDIR} -I${.CURDIR}/sysdep/${OS} -I. \
+ # Different debugging & profiling suggestions
+ # Include symbolic debugging info
+ DEBUG=                -g
++CFLAGS+=      -g
+ # Do execution time profiles
+ #CFLAGS+=     -pg
+@@ -172,6 +173,14 @@
+ CFLAGS+=        -DUSE_RAWKEY
+ endif
++ifdef USE_OPENSSL_MD5
++CFLAGS+=      -DUSE_OPENSSL_MD5
++endif
++
++ifdef USE_OPENSSL_SHA1
++CFLAGS+=      -DUSE_OPENSSL_SHA1
++endif
++
+ SRCS+=                ${IPSEC_SRCS} ${X509} ${POLICY} ${EC} ${AGGRESSIVE} ${DNSSEC} \
+               $(ISAKMP_CFG)
+ CFLAGS+=      ${IPSEC_CFLAGS}
+diff -urN isakmpd/sysdep/common/libsysdep/GNUmakefile isakmpd.new/sysdep/common/libsysdep/GNUmakefile
+--- isakmpd/sysdep/common/libsysdep/GNUmakefile        2003-06-03 16:52:06.000000000 +0200
++++ isakmpd.new/sysdep/common/libsysdep/GNUmakefile    2006-09-01 19:29:28.000000000 +0200
+@@ -31,10 +31,18 @@
+ .CURDIR:=     $(shell pwd)
+ LIB=          sysdep
+-SRCS=         arc4random.c blowfish.c cast.c md5.c sha1.c strlcat.c strlcpy.c
++SRCS=         arc4random.c blowfish.c cast.c strlcat.c strlcpy.c
+ NOMAN=
+ CFLAGS+=      -I${.CURDIR}/.. -I/usr/include/machine
++ifeq (,$(findstring USE_OPENSSL_MD5,$(CFLAGS)))
++SRCS+=md5.c
++endif
++
++ifeq (,$(findstring USE_OPENSSL_SHA1,$(CFLAGS)))
++SRCS+=sha1.c
++endif
++
+ lib${LIB}.a: ${SRCS:%.c=%.o}
+       ar cq $@ ${SRCS:%.c=%.o}
+diff -urN isakmpd/sysdep/common/libsysdep/md5.c isakmpd.new/sysdep/common/libsysdep/md5.c
+--- isakmpd/sysdep/common/libsysdep/md5.c      2002-06-14 23:34:58.000000000 +0200
++++ isakmpd.new/sysdep/common/libsysdep/md5.c  2006-09-01 19:29:28.000000000 +0200
+@@ -5,6 +5,8 @@
+  * changes to accommodate it in the kernel by ji.
+  */
++#ifndef USE_OPENSSL_MD5
++
+ /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+  */
+@@ -390,3 +392,4 @@
+ #endif
+ #endif
++#endif /* USE_OPENSSL_MD5 */
+diff -urN isakmpd/sysdep/common/libsysdep/sha1.c isakmpd.new/sysdep/common/libsysdep/sha1.c
+--- isakmpd/sysdep/common/libsysdep/sha1.c     2001-01-28 23:38:48.000000000 +0100
++++ isakmpd.new/sysdep/common/libsysdep/sha1.c 2006-09-01 19:29:28.000000000 +0200
+@@ -1,5 +1,7 @@
+ /*    $OpenBSD: sha1.c,v 1.2 2001/01/28 22:38:48 niklas Exp $ */
++#ifndef USE_OPENSSL_SHA1
++
+ /*
+ SHA-1 in C
+ By Steve Reid <steve@edmweb.com>
+@@ -171,3 +173,5 @@
+     SHA1Transform(context->state, context->buffer);
+ #endif
+ }
++
++#endif /* USE_OPENSSL_SHA1 */
+diff -urN isakmpd/sysdep/common/md5.h isakmpd.new/sysdep/common/md5.h
+--- isakmpd/sysdep/common/md5.h        2001-01-28 23:38:47.000000000 +0100
++++ isakmpd.new/sysdep/common/md5.h    2006-09-01 19:29:28.000000000 +0200
+@@ -1,5 +1,15 @@
+ /*    $OpenBSD: md5.h,v 1.2 2001/01/28 22:38:47 niklas Exp $  */
++#ifdef USE_OPENSSL_MD5
++
++#include <openssl/md5.h>
++
++#define MD5Init               MD5_Init
++#define       MD5Update       MD5_Update
++#define       MD5Final        MD5_Final
++
++#else /* USE_OPENSSL_MD5 */
++
+ /* GLOBAL.H - RSAREF types and constants
+  */
+@@ -71,3 +81,5 @@
+ void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+ #define _MD5_H_
++
++#endif        /* USE_OPENSSL_MD5 */
+diff -urN isakmpd/sysdep/common/sha1.h isakmpd.new/sysdep/common/sha1.h
+--- isakmpd/sysdep/common/sha1.h       2001-01-28 23:38:47.000000000 +0100
++++ isakmpd.new/sysdep/common/sha1.h   2006-09-01 19:29:28.000000000 +0200
+@@ -1,5 +1,16 @@
+ /*    $OpenBSD: sha1.h,v 1.2 2001/01/28 22:38:47 niklas Exp $ */
++#ifdef USE_OPENSSL_SHA1
++
++#include <openssl/sha.h>
++
++typedef SHA_CTX SHA1_CTX;
++#define       SHA1Init        SHA1_Init
++#define       SHA1Update      SHA1_Update
++#define       SHA1Final       SHA1_Final
++
++#else /* USE_OPENSSL_SHA1 */
++
+ /*
+ SHA-1 in C
+ By Steve Reid <steve@edmweb.com>
+@@ -16,3 +27,5 @@
+ void SHA1Init(SHA1_CTX* context);
+ void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
+ void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
++
++#endif        /* USE_OPENSSL_SHA1 */
+diff -urN isakmpd/sysdep/linux/GNUmakefile.sysdep isakmpd.new/sysdep/linux/GNUmakefile.sysdep
+--- isakmpd/sysdep/linux/GNUmakefile.sysdep    2006-09-01 19:29:05.000000000 +0200
++++ isakmpd.new/sysdep/linux/GNUmakefile.sysdep        2006-09-01 19:29:29.000000000 +0200
+@@ -48,6 +48,8 @@
+ USE_LIBCRYPO= defined
+ HAVE_DLOPEN=  defined
+ USE_KEYNOTE=  defined
++USE_OPENSSL_MD5=      defined
++USE_OPENSSL_SHA1=     defined
+ # hack libsysdep.a dependenc
+ ${LIBSYSDEPDIR}/.depend ${LIBSYSDEP}:
diff --git a/openwrt/package/isakmpd/patches/040-security_fix.patch b/openwrt/package/isakmpd/patches/040-security_fix.patch
new file mode 100644 (file)
index 0000000..9128880
--- /dev/null
@@ -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;
+ }
+ /*