Index: isakmpd-20041012.orig/dpd.c =================================================================== --- isakmpd-20041012.orig.orig/dpd.c 2007-06-04 13:22:39.088912864 +0200 +++ isakmpd-20041012.orig/dpd.c 2007-06-04 13:22:39.282883376 +0200 @@ -26,6 +26,7 @@ #include #include +#include #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"); Index: isakmpd-20041012.orig/ipsec.c =================================================================== --- isakmpd-20041012.orig.orig/ipsec.c 2007-06-04 13:22:39.093912104 +0200 +++ isakmpd-20041012.orig/ipsec.c 2007-06-04 13:22:39.283883224 +0200 @@ -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) { Index: isakmpd-20041012.orig/GNUmakefile =================================================================== --- isakmpd-20041012.orig.orig/GNUmakefile 2007-06-04 13:22:39.099911192 +0200 +++ isakmpd-20041012.orig/GNUmakefile 2007-06-04 13:22:39.283883224 +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} @@ -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} Index: isakmpd-20041012.orig/exchange.h =================================================================== --- isakmpd-20041012.orig.orig/exchange.h 2007-06-04 13:22:39.104910432 +0200 +++ isakmpd-20041012.orig/exchange.h 2007-06-04 13:22:39.283883224 +0200 @@ -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 *); Index: isakmpd-20041012.orig/log.c =================================================================== --- isakmpd-20041012.orig.orig/log.c 2007-06-04 13:22:39.110909520 +0200 +++ isakmpd-20041012.orig/log.c 2007-06-04 13:22:39.284883072 +0200 @@ -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) Index: isakmpd-20041012.orig/nat_traversal.c =================================================================== --- isakmpd-20041012.orig.orig/nat_traversal.c 2007-06-04 13:22:39.115908760 +0200 +++ isakmpd-20041012.orig/nat_traversal.c 2007-06-04 13:22:39.284883072 +0200 @@ -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); Index: isakmpd-20041012.orig/udp_encap.c =================================================================== --- isakmpd-20041012.orig.orig/udp_encap.c 2007-06-04 13:22:39.121907848 +0200 +++ isakmpd-20041012.orig/udp_encap.c 2007-06-04 13:22:39.284883072 +0200 @@ -61,6 +61,11 @@ #define UDP_SIZE 65536 +#if defined(USE_NAT_TRAVERSAL) && defined (LINUX_IPSEC) +#include +#include +#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: Index: isakmpd-20041012.orig/apps/Makefile =================================================================== --- isakmpd-20041012.orig.orig/apps/Makefile 2007-06-04 13:22:39.126907088 +0200 +++ isakmpd-20041012.orig/apps/Makefile 2007-06-04 13:22:39.285882920 +0200 @@ -31,4 +31,4 @@ SUBDIR= certpatch -.include +#.include Index: isakmpd-20041012.orig/apps/certpatch/GNUmakefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ isakmpd-20041012.orig/apps/certpatch/GNUmakefile 2007-06-04 13:22:39.285882920 +0200 @@ -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} Index: isakmpd-20041012.orig/pf_key_v2.c =================================================================== --- isakmpd-20041012.orig.orig/pf_key_v2.c 2007-06-04 13:22:39.137905416 +0200 +++ isakmpd-20041012.orig/pf_key_v2.c 2007-06-04 13:22:39.287882616 +0200 @@ -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); Index: isakmpd-20041012.orig/isakmp_num.cst =================================================================== --- isakmpd-20041012.orig.orig/isakmp_num.cst 2007-06-04 13:22:39.143904504 +0200 +++ isakmpd-20041012.orig/isakmp_num.cst 2007-06-04 13:22:39.287882616 +0200 @@ -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. Index: isakmpd-20041012.orig/ipsec_num.cst =================================================================== --- isakmpd-20041012.orig.orig/ipsec_num.cst 2007-06-04 13:22:39.149903592 +0200 +++ isakmpd-20041012.orig/ipsec_num.cst 2007-06-04 13:22:39.287882616 +0200 @@ -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. Index: isakmpd-20041012.orig/nat_traversal.h =================================================================== --- isakmpd-20041012.orig.orig/nat_traversal.h 2007-06-04 13:22:39.154902832 +0200 +++ isakmpd-20041012.orig/nat_traversal.h 2007-06-04 13:22:39.287882616 +0200 @@ -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 *); Index: isakmpd-20041012.orig/message.c =================================================================== --- isakmpd-20041012.orig.orig/message.c 2007-06-04 13:22:39.160901920 +0200 +++ isakmpd-20041012.orig/message.c 2007-06-04 13:22:39.288882464 +0200 @@ -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. */ Index: isakmpd-20041012.orig/policy.c =================================================================== --- isakmpd-20041012.orig.orig/policy.c 2007-06-04 13:22:39.165901160 +0200 +++ isakmpd-20041012.orig/policy.c 2007-06-04 13:22:39.289882312 +0200 @@ -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) Index: isakmpd-20041012.orig/ike_phase_1.c =================================================================== --- isakmpd-20041012.orig.orig/ike_phase_1.c 2007-06-04 13:22:39.170900400 +0200 +++ isakmpd-20041012.orig/ike_phase_1.c 2007-06-04 13:22:39.290882160 +0200 @@ -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); Index: isakmpd-20041012.orig/x509.c =================================================================== --- isakmpd-20041012.orig.orig/x509.c 2007-06-04 13:22:39.176899488 +0200 +++ isakmpd-20041012.orig/x509.c 2007-06-04 13:22:39.290882160 +0200 @@ -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); } Index: isakmpd-20041012.orig/sysdep/linux/sysdep.c =================================================================== --- isakmpd-20041012.orig.orig/sysdep/linux/sysdep.c 2007-06-04 13:22:39.182898576 +0200 +++ isakmpd-20041012.orig/sysdep/linux/sysdep.c 2007-06-04 13:22:39.291882008 +0200 @@ -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; Index: isakmpd-20041012.orig/sysdep/linux/GNUmakefile.sysdep =================================================================== --- isakmpd-20041012.orig.orig/sysdep/linux/GNUmakefile.sysdep 2007-06-04 13:22:39.187897816 +0200 +++ isakmpd-20041012.orig/sysdep/linux/GNUmakefile.sysdep 2007-06-04 13:22:39.291882008 +0200 @@ -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) Index: isakmpd-20041012.orig/sysdep/linux/include/bitstring.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ isakmpd-20041012.orig/sysdep/linux/include/bitstring.h 2007-06-04 13:22:39.291882008 +0200 @@ -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_ */ Index: isakmpd-20041012.orig/sysdep/linux/include/sys/queue.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ isakmpd-20041012.orig/sysdep/linux/include/sys/queue.h 2007-06-04 13:22:39.292881856 +0200 @@ -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 /* 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_ */ Index: isakmpd-20041012.orig/sysdep/common/pcap.h =================================================================== --- isakmpd-20041012.orig.orig/sysdep/common/pcap.h 2007-06-04 13:22:39.203895384 +0200 +++ isakmpd-20041012.orig/sysdep/common/pcap.h 2007-06-04 13:22:39.292881856 +0200 @@ -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) */ }; Index: isakmpd-20041012.orig/sysdep/common/libsysdep/arc4random.c =================================================================== --- isakmpd-20041012.orig.orig/sysdep/common/libsysdep/arc4random.c 2007-06-04 13:22:39.211894168 +0200 +++ isakmpd-20041012.orig/sysdep/common/libsysdep/arc4random.c 2007-06-04 13:22:39.292881856 +0200 @@ -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)]; Index: isakmpd-20041012.orig/x509v3.cnf =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ isakmpd-20041012.orig/x509v3.cnf 2007-06-04 13:22:39.293881704 +0200 @@ -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