diff options
author | schmonz <schmonz> | 2009-04-22 04:48:13 +0000 |
---|---|---|
committer | schmonz <schmonz> | 2009-04-22 04:48:13 +0000 |
commit | e0a6abbdb983849f73da5047849a7ae7f3005c48 (patch) | |
tree | 4204321e99b3cc6253ab947f366d62190a44cc4d /net/djbdns | |
parent | b8dc62d3de80db34eed4c480d64eca161d64dadd (diff) | |
download | pkgsrc-e0a6abbdb983849f73da5047849a7ae7f3005c48.tar.gz |
Add DJB's patch to fix the axfrdns bug reported by Matthew Dempsky,
described here:
http://article.gmane.org/gmane.network.djbdns/13864
Add mutually exclusive options, both by Jeff King, to address the
dnscache poisoning weaknesses described in CVE-2008-4392:
* "djbdns-qmerge1" (from http://www.your.org/dnscache/)
* "djbdns-qmerge2" (from http://article.gmane.org/gmane.network.djbdns/13965)
Both options are included because qmerge1 is better tested but has
known shortcomings, while qmerge2 is probably more correct but (as
yet) less well tested.
Bump PKGREVISION.
Diffstat (limited to 'net/djbdns')
-rw-r--r-- | net/djbdns/Makefile | 4 | ||||
-rw-r--r-- | net/djbdns/distinfo | 12 | ||||
-rw-r--r-- | net/djbdns/files/patch-qmerge2 | 254 | ||||
-rw-r--r-- | net/djbdns/options.mk | 30 | ||||
-rw-r--r-- | net/djbdns/patches/patch-ac | 13 |
5 files changed, 303 insertions, 10 deletions
diff --git a/net/djbdns/Makefile b/net/djbdns/Makefile index 4fa2fbbcf34..fe045b4c47f 100644 --- a/net/djbdns/Makefile +++ b/net/djbdns/Makefile @@ -1,7 +1,7 @@ -# $NetBSD: Makefile,v 1.56 2009/01/19 10:27:31 sketch Exp $ +# $NetBSD: Makefile,v 1.57 2009/04/22 04:48:13 schmonz Exp $ DISTNAME= djbdns-1.05 -PKGREVISION= 8 +PKGREVISION= 9 CATEGORIES= net MASTER_SITES= http://cr.yp.to/djbdns/ ftp://cr.yp.to/djbdns/ DISTFILES= ${DISTNAME}${EXTRACT_SUFX} ${MANPAGES} diff --git a/net/djbdns/distinfo b/net/djbdns/distinfo index 5816dec0619..eadd2a84cc9 100644 --- a/net/djbdns/distinfo +++ b/net/djbdns/distinfo @@ -1,4 +1,4 @@ -$NetBSD: distinfo,v 1.16 2009/01/19 10:27:31 sketch Exp $ +$NetBSD: distinfo,v 1.17 2009/04/22 04:48:13 schmonz Exp $ SHA1 (djbdns-1.05.tar.gz) = 2efdb3a039d0c548f40936aa9cb30829e0ce8c3d RMD160 (djbdns-1.05.tar.gz) = a832cbfd93e4ccec6a565492a4ee0b3c1b4b68ed @@ -15,8 +15,12 @@ Size (djbdns-1.05-ignoreip2.patch) = 3890 bytes SHA1 (djbdns-cachestats.patch) = ab0b2835140768d89159d5564534d39520d7f403 RMD160 (djbdns-cachestats.patch) = e09994d84573e781ce18b59f909f8bd013de5d8e Size (djbdns-cachestats.patch) = 2341 bytes -SHA1 (tinydns64.diff) = 5a06ba9968ddd905ef69ce036bdc9d18bb738982 -RMD160 (tinydns64.diff) = 7eb8ea387731385576fb1c933c18e0957477c3e0 -Size (tinydns64.diff) = 1537 bytes +SHA1 (0001-dnscache-merge-similar-outgoing-queries.patch) = 8dd3ce7758d3a97cafbe6a60ea83f48e916f496d +RMD160 (0001-dnscache-merge-similar-outgoing-queries.patch) = c416dd6575819cfd40ef0d306ccb14d34a5afc90 +Size (0001-dnscache-merge-similar-outgoing-queries.patch) = 9914 bytes +SHA1 (0002-dnscache-cache-soa-records.patch) = ac9b6a62c62588205cc4dc71da4e0ad6630f9635 +RMD160 (0002-dnscache-cache-soa-records.patch) = 0b58e57bc11b36113c5fef73a64c869895f83889 +Size (0002-dnscache-cache-soa-records.patch) = 2944 bytes SHA1 (patch-aa) = 8953486b88d57d003956c6fe2addea9bcd16e5aa SHA1 (patch-ab) = e14b7cba40d1dc7279c3ab04ede597277e2576d1 +SHA1 (patch-ac) = 1d5ab2c90a2c4221bc7ec08d116d3d23799bd5d6 diff --git a/net/djbdns/files/patch-qmerge2 b/net/djbdns/files/patch-qmerge2 new file mode 100644 index 00000000000..c78e2d1a126 --- /dev/null +++ b/net/djbdns/files/patch-qmerge2 @@ -0,0 +1,254 @@ +--- clients.h.orig 2009-04-21 23:43:02.000000000 -0400 ++++ clients.h +@@ -0,0 +1,7 @@ ++#ifndef CLIENTS_H ++#define CLIENTS_H ++ ++#define MAXUDP 200 ++#define MAXTCP 20 ++ ++#endif /* CLIENTS_H */ +--- dns.h.orig 2001-02-11 16:11:45.000000000 -0500 ++++ dns.h +@@ -4,6 +4,7 @@ + #include "stralloc.h" + #include "iopause.h" + #include "taia.h" ++#include "clients.h" + + #define DNS_C_IN "\0\1" + #define DNS_C_ANY "\0\377" +@@ -37,8 +38,14 @@ struct dns_transmit { + const char *servers; + char localip[4]; + char qtype[2]; ++ struct dns_transmit *master; ++ struct dns_transmit *slaves[MAXUDP]; ++ int nslaves; + } ; + ++extern void dns_enable_merge(void (*logger)(const char *, const char *, ++ const char *)); ++ + extern void dns_random_init(const char *); + extern unsigned int dns_random(unsigned int); + +--- dns_transmit.c.orig 2001-02-11 16:11:45.000000000 -0500 ++++ dns_transmit.c +@@ -7,6 +7,61 @@ + #include "byte.h" + #include "uint16.h" + #include "dns.h" ++#include "strerr.h" ++ ++static int merge_enable; ++static void (*merge_logger)(const char *, const char *, const char *); ++void dns_enable_merge(void (*f)(const char *, const char *, const char *)) ++{ ++ merge_enable = 1; ++ merge_logger = f; ++} ++ ++static int merge_equal(struct dns_transmit *a, struct dns_transmit *b) ++{ ++ const char *ip1 = a->servers + 4 * a->curserver; ++ const char *ip2 = b->servers + 4 * b->curserver; ++ return ++ byte_equal(ip1, 4, ip2) && ++ byte_equal(a->qtype, 2, b->qtype) && ++ dns_domain_equal(a->query + 14, b->query + 14); ++} ++ ++struct dns_transmit *inprogress[MAXUDP]; ++ ++static int try_merge(struct dns_transmit *d) ++{ ++ int i; ++ for (i = 0; i < MAXUDP; i++) { ++ if (!inprogress[i]) continue; ++ if (!merge_equal(d, inprogress[i])) continue; ++ d->master = inprogress[i]; ++ inprogress[i]->slaves[inprogress[i]->nslaves++] = d; ++ return 1; ++ } ++ return 0; ++} ++ ++static void register_inprogress(struct dns_transmit *d) ++{ ++ int i; ++ for (i = 0; i < MAXUDP; i++) { ++ if (!inprogress[i]) { ++ inprogress[i] = d; ++ return; ++ } ++ } ++ strerr_die1x(100, "BUG: out of inprogress slots"); ++} ++ ++static void unregister_inprogress(struct dns_transmit *d) ++{ ++ int i; ++ for (i = 0; i < MAXUDP; i++) { ++ if (inprogress[i] == d) ++ inprogress[i] = 0; ++ } ++} + + static int serverwantstcp(const char *buf,unsigned int len) + { +@@ -59,8 +114,28 @@ static void packetfree(struct dns_transm + d->packet = 0; + } + ++static void mergefree(struct dns_transmit *d) ++{ ++ int i; ++ if (merge_enable) ++ unregister_inprogress(d); ++ /* unregister us from our master */ ++ if (d->master) { ++ for (i = 0; i < d->master->nslaves; i++) ++ if (d->master->slaves[i] == d) ++ d->master->slaves[i] = 0; ++ } ++ /* and unregister all of our slaves from us */ ++ for (i = 0; i < d->nslaves; i++) { ++ if (d->slaves[i]) ++ d->slaves[i]->master = NULL; ++ } ++ d->nslaves = 0; ++} ++ + static void queryfree(struct dns_transmit *d) + { ++ mergefree(d); + if (!d->query) return; + alloc_free(d->query); + d->query = 0; +@@ -99,11 +174,18 @@ static int thisudp(struct dns_transmit * + const char *ip; + + socketfree(d); ++ mergefree(d); + + while (d->udploop < 4) { + for (;d->curserver < 16;++d->curserver) { + ip = d->servers + 4 * d->curserver; + if (byte_diff(ip,4,"\0\0\0\0")) { ++ if (merge_enable && try_merge(d)) { ++ if (merge_logger) ++ merge_logger(ip, d->qtype, d->query + 14); ++ return 0; ++ } ++ + d->query[2] = dns_random(256); + d->query[3] = dns_random(256); + +@@ -118,6 +200,8 @@ static int thisudp(struct dns_transmit * + taia_uint(&d->deadline,timeouts[d->udploop]); + taia_add(&d->deadline,&d->deadline,&now); + d->tcpstate = 0; ++ if (merge_enable) ++ register_inprogress(d); + return 0; + } + +@@ -226,8 +310,12 @@ void dns_transmit_io(struct dns_transmit + x->fd = d->s1 - 1; + + switch(d->tcpstate) { +- case 0: case 3: case 4: case 5: +- x->events = IOPAUSE_READ; ++ case 0: ++ if (d->master) return; ++ if (d->packet) { taia_now(deadline); return; } ++ /* otherwise, fall through */ ++ case 3: case 4: case 5: ++ x->events = IOPAUSE_READ; + break; + case 1: case 2: + x->events = IOPAUSE_WRITE; +@@ -244,10 +332,14 @@ int dns_transmit_get(struct dns_transmit + unsigned char ch; + int r; + int fd; ++ int i; + + errno = error_io; + fd = d->s1 - 1; + ++ if (d->tcpstate == 0 && d->master) return 0; ++ if (d->tcpstate == 0 && d->packet) return 1; ++ + if (!x->revents) { + if (taia_less(when,&d->deadline)) return 0; + errno = error_timeout; +@@ -279,6 +371,15 @@ have sent query to curserver on UDP sock + d->packet = alloc(d->packetlen); + if (!d->packet) { dns_transmit_free(d); return -1; } + byte_copy(d->packet,d->packetlen,udpbuf); ++ ++ for (i = 0; i < d->nslaves; i++) { ++ if (!d->slaves[i]) continue; ++ d->slaves[i]->packetlen = d->packetlen; ++ d->slaves[i]->packet = alloc(d->packetlen); ++ if (!d->slaves[i]->packet) { dns_transmit_free(d->slaves[i]); continue; } ++ byte_copy(d->slaves[i]->packet,d->packetlen,udpbuf); ++ } ++ + queryfree(d); + return 1; + } +--- dnscache.c.orig 2001-02-11 16:11:45.000000000 -0500 ++++ dnscache.c +@@ -54,7 +54,6 @@ uint64 numqueries = 0; + + static int udp53; + +-#define MAXUDP 200 + static struct udpclient { + struct query q; + struct taia start; +@@ -131,7 +130,6 @@ void u_new(void) + + static int tcp53; + +-#define MAXTCP 20 + struct tcpclient { + struct query q; + struct taia start; +@@ -435,6 +433,8 @@ int main() + response_hidettl(); + if (env_get("FORWARDONLY")) + query_forwardonly(); ++ if (env_get("MERGEQUERIES")) ++ dns_enable_merge(log_merge); + + if (!roots_init()) + strerr_die2sys(111,FATAL,"unable to read servers: "); +--- log.c.orig 2001-02-11 16:11:45.000000000 -0500 ++++ log.c +@@ -150,6 +150,12 @@ void log_tx(const char *q,const char qty + line(); + } + ++void log_merge(const char *addr, const char qtype[2], const char *q) ++{ ++ string("merge "); ip(addr); space(); logtype(qtype); space(); name(q); ++ line(); ++} ++ + void log_cachedanswer(const char *q,const char type[2]) + { + string("cached "); logtype(type); space(); +--- log.h.orig 2001-02-11 16:11:45.000000000 -0500 ++++ log.h +@@ -18,6 +18,7 @@ extern void log_cachednxdomain(const cha + extern void log_cachedns(const char *,const char *); + + extern void log_tx(const char *,const char *,const char *,const char *,unsigned int); ++extern void log_merge(const char *, const char *, const char *); + + extern void log_nxdomain(const char *,const char *,unsigned int); + extern void log_nodata(const char *,const char *,const char *,unsigned int); diff --git a/net/djbdns/options.mk b/net/djbdns/options.mk index 38c10164155..fd80e4f2645 100644 --- a/net/djbdns/options.mk +++ b/net/djbdns/options.mk @@ -1,7 +1,12 @@ -# $NetBSD: options.mk,v 1.11 2009/01/19 10:27:31 sketch Exp $ +# $NetBSD: options.mk,v 1.12 2009/04/22 04:48:13 schmonz Exp $ + +PKG_OPTIONS_VAR= PKG_OPTIONS.djbdns +PKG_SUPPORTED_OPTIONS+= inet6 djbdns-cachestats djbdns-ignoreip2 +PKG_SUPPORTED_OPTIONS+= djbdns-tinydns64 +PKG_OPTIONS_OPTIONAL_GROUPS= qmerge +PKG_OPTIONS_GROUP.qmerge= djbdns-qmerge1 djbdns-qmerge2 +PKG_SUGGESTED_OPTIONS= djbdns-qmerge2 -PKG_OPTIONS_VAR= PKG_OPTIONS.djbdns -PKG_SUPPORTED_OPTIONS+= inet6 djbdns-cachestats djbdns-ignoreip2 djbdns-tinydns64 .if ${MACHINE_ARCH} == "sparc64" || \ ${MACHINE_ARCH} == "alpha" || \ @@ -32,7 +37,24 @@ PATCHFILES+= ${IGNOREIP2_PATCH} SITES.${IGNOREIP2_PATCH}= http://www.tinydns.org/ .endif +.if !empty(PKG_OPTIONS:Mdjbdns-qmerge1) +DNSCACHE_MERGE_PATCH= 0001-dnscache-merge-similar-outgoing-queries.patch +DNSCACHE_SOA_PATCH= 0002-dnscache-cache-soa-records.patch +PATCHFILES+= ${DNSCACHE_MERGE_PATCH} ${DNSCACHE_SOA_PATCH} +PATCH_DIST_STRIP.${DNSCACHE_MERGE_PATCH}= -p1 +PATCH_DIST_STRIP.${DNSCACHE_SOA_PATCH}= -p1 +SITES.${DNSCACHE_MERGE_PATCH}= http://www.your.org/dnscache/ +SITES.${DNSCACHE_SOA_PATCH}= http://www.your.org/dnscache/ +.endif + +.if !empty(PKG_OPTIONS:Mdjbdns-qmerge2) +USE_TOOLS+= patch +post-patch: + cd ${WRKSRC} && ${PATCH} ${PATCH_ARGS} < ${FILESDIR}/patch-qmerge2 +.endif + .if !empty(PKG_OPTIONS:Mdjbdns-tinydns64) +USE_TOOLS+= patch post-patch: - @cd ${WRKSRC} && ${PATCH} ${PATCH_ARGS} < ${FILESDIR}/patch-tinydns64 + cd ${WRKSRC} && ${PATCH} ${PATCH_ARGS} < ${FILESDIR}/patch-tinydns64 .endif diff --git a/net/djbdns/patches/patch-ac b/net/djbdns/patches/patch-ac new file mode 100644 index 00000000000..bca0708d2ef --- /dev/null +++ b/net/djbdns/patches/patch-ac @@ -0,0 +1,13 @@ +$NetBSD: patch-ac,v 1.5 2009/04/22 04:48:13 schmonz Exp $ + +--- response.c.orig 2001-02-11 16:11:45.000000000 -0500 ++++ response.c +@@ -34,7 +34,7 @@ int response_addname(const char *d) + uint16_pack_big(buf,49152 + name_ptr[i]); + return response_addbytes(buf,2); + } +- if (dlen <= 128) ++ if ((dlen <= 128) && (response_len < 16384)) + if (name_num < NAMES) { + byte_copy(name[name_num],dlen,d); + name_ptr[name_num] = response_len; |