summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschmonz <schmonz@pkgsrc.org>2009-04-22 04:48:13 +0000
committerschmonz <schmonz@pkgsrc.org>2009-04-22 04:48:13 +0000
commit6325b6f67b2151c55be6d1468be29516dbb85ebf (patch)
tree4204321e99b3cc6253ab947f366d62190a44cc4d
parentd42ad0440f1b4852e2d5825745822b6f03a65a51 (diff)
downloadpkgsrc-6325b6f67b2151c55be6d1468be29516dbb85ebf.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.
-rw-r--r--net/djbdns/Makefile4
-rw-r--r--net/djbdns/distinfo12
-rw-r--r--net/djbdns/files/patch-qmerge2254
-rw-r--r--net/djbdns/options.mk30
-rw-r--r--net/djbdns/patches/patch-ac13
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;