summaryrefslogtreecommitdiff
path: root/net/djbdns/files
diff options
context:
space:
mode:
authorschmonz <schmonz>2009-04-22 04:48:13 +0000
committerschmonz <schmonz>2009-04-22 04:48:13 +0000
commite0a6abbdb983849f73da5047849a7ae7f3005c48 (patch)
tree4204321e99b3cc6253ab947f366d62190a44cc4d /net/djbdns/files
parentb8dc62d3de80db34eed4c480d64eca161d64dadd (diff)
downloadpkgsrc-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/files')
-rw-r--r--net/djbdns/files/patch-qmerge2254
1 files changed, 254 insertions, 0 deletions
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);