From eaaa5b4f9301ae2e5a29dd77616d8e29fd3b2c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henryk=20Pl=C3=B6tz?= Date: Fri, 3 Oct 2014 20:19:52 +0200 Subject: Add tinydnssec-1.05-1.3.tar.bz2 Source was http://www.tinydnssec.org/download/tinydnssec-1.05-1.3.tar.bz2, SHA1 b33d5c3e0de67f6427aad8c00a99580b59804075 --- djbdns-1.05-dnssec.patch | 1749 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1749 insertions(+) create mode 100644 djbdns-1.05-dnssec.patch (limited to 'djbdns-1.05-dnssec.patch') diff --git a/djbdns-1.05-dnssec.patch b/djbdns-1.05-dnssec.patch new file mode 100644 index 0000000..d2b2323 --- /dev/null +++ b/djbdns-1.05-dnssec.patch @@ -0,0 +1,1749 @@ +(C) 2012 Peter Conrad + +This patch is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License version 3 as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +diff -rNU3 djbdns-1.05.tds-base/axfrdns.c djbdns-1.05.tinydnssec/axfrdns.c +--- djbdns-1.05.tds-base/axfrdns.c 2012-12-06 22:45:38.000000000 +0100 ++++ djbdns-1.05.tinydnssec/axfrdns.c 2012-12-06 22:39:13.000000000 +0100 +@@ -23,6 +23,7 @@ + #include "response.h" + #include "ip6.h" + #include "clientloc.h" ++#include "edns0.h" + + extern int respond(char *,char *,char *); + +@@ -346,6 +347,9 @@ + if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY)) + strerr_die2x(111,FATAL,"bogus query: bad class"); + ++ pos = check_edns0(header, buf, len, pos); ++ if (!pos) die_truncated(); ++ + qlog(ip,port,header,zone,qtype," "); + + if (byte_equal(qtype,2,DNS_T_AXFR)) { +diff -rNU3 djbdns-1.05.tds-base/base32hex.c djbdns-1.05.tinydnssec/base32hex.c +--- djbdns-1.05.tds-base/base32hex.c 1970-01-01 01:00:00.000000000 +0100 ++++ djbdns-1.05.tinydnssec/base32hex.c 2012-12-06 22:39:13.000000000 +0100 +@@ -0,0 +1,79 @@ ++/* (C) 2012 Peter Conrad ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include "base32hex.h" ++ ++#define to_32hex(c) ((c) < 10 ? (c) + '0' : (c) + 'a' - 10) ++ ++/* out must point to a buffer of at least (len * 8 / 5) + 1 bytes. ++ * Encoded string is *not* padded. ++ * See RFC-4648. This implementation produces lowercase hex characters. ++ * Returns length of encoded string. ++ */ ++unsigned int base32hex(char *out, uint8_t *in, unsigned int len) { ++int buf = 0, bits = 0; ++char *x = out; ++ ++ while (len-- > 0) { ++ buf <<= 8; ++ buf |= *in++; ++ bits += 8; ++ while (bits >= 5) { ++ char c = (buf >> (bits - 5)) & 0x1f; ++ *x++ = to_32hex(c); ++ bits -= 5; ++ } ++ } ++ if (bits > 0) { ++ char c = (buf << (5 - bits)) & 0x1f; ++ *x++ = to_32hex(c); ++ } ++ return x - out; ++} ++ ++#ifdef TEST ++#include ++#include ++#include ++ ++static void test(char *in, char *expected, int explen) { ++char buf[255]; ++int r; ++ ++ if ((r = base32hex(buf, in, strlen(in))) != explen) { ++ printf("Failed: b32h('%s') yields %d chars (expected %d)\n", ++ in, r, explen); ++ exit(1); ++ } ++ if (strncmp(buf, expected, r)) { ++ buf[r] = 0; ++ printf("Failed: b32h('%s') = '%s' (expected %s)\n", ++ in, buf, expected); ++ exit(1); ++ } ++} ++ ++int main(int argc, char **argv) { ++ test("", "", 0); ++ test("f", "co", 2); ++ test("fo", "cpng", 4); ++ test("foo", "cpnmu", 5); ++ test("foob", "cpnmuog", 7); ++ test("fooba", "cpnmuoj1", 8); ++ test("foobar", "cpnmuoj1e8", 10); ++ printf("Success!\n"); ++} ++ ++#endif +diff -rNU3 djbdns-1.05.tds-base/base32hex.h djbdns-1.05.tinydnssec/base32hex.h +--- djbdns-1.05.tds-base/base32hex.h 1970-01-01 01:00:00.000000000 +0100 ++++ djbdns-1.05.tinydnssec/base32hex.h 2012-12-06 22:39:13.000000000 +0100 +@@ -0,0 +1,23 @@ ++/* (C) 2012 Peter Conrad ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#ifndef _BASE32_HEX_H ++#define _BASE32_HEX_H ++ ++#include ++ ++extern unsigned int base32hex(char *out, uint8_t *in, unsigned int len); ++ ++#endif +diff -rNU3 djbdns-1.05.tds-base/dns.h djbdns-1.05.tinydnssec/dns.h +--- djbdns-1.05.tds-base/dns.h 2012-12-06 22:45:38.000000000 +0100 ++++ djbdns-1.05.tinydnssec/dns.h 2012-12-06 22:39:13.000000000 +0100 +@@ -20,8 +20,17 @@ + #define DNS_T_SIG "\0\30" + #define DNS_T_KEY "\0\31" + #define DNS_T_AAAA "\0\34" ++#define DNS_T_OPT "\0\51" ++#define DNS_T_DS "\0\53" ++#define DNS_T_RRSIG "\0\56" ++#define DNS_T_DNSKEY "\0\60" ++#define DNS_T_NSEC3 "\0\62" ++#define DNS_T_NSEC3PARAM "\0\63" + #define DNS_T_AXFR "\0\374" + #define DNS_T_ANY "\0\377" ++/* Pseudo-RRs for DNSSEC */ ++#define DNS_T_HASHREF "\377\1" ++#define DNS_T_HASHLIST "\377\2" + + struct dns_transmit { + char *query; /* 0, or dynamically allocated */ +diff -rNU3 djbdns-1.05.tds-base/edns0.c djbdns-1.05.tinydnssec/edns0.c +--- djbdns-1.05.tds-base/edns0.c 1970-01-01 01:00:00.000000000 +0100 ++++ djbdns-1.05.tinydnssec/edns0.c 2012-12-06 22:39:13.000000000 +0100 +@@ -0,0 +1,45 @@ ++/* (C) 2012 Peter Conrad ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include "dns.h" ++#include "edns0.h" ++#include "response.h" ++#include "uint16.h" ++ ++unsigned int check_edns0(const char header[12], const char *buf, const int len, unsigned int pos) ++{ ++char opt_class[2]; ++char opt_ttl[4]; ++ ++ max_response_len = 512; ++ do_dnssec = 0; ++ if (!header[6] && !header[7] && !header[8] && !header[9] ++ && !header[10] && header[11] == 1) { ++ char nametype[3]; ++ uint16 size, min_len; ++ pos = dns_packet_copy(buf,len,pos,nametype,3); if (!pos) return pos; ++ if (nametype[0] || nametype[1] || nametype[2] != DNS_T_OPT[1]) return pos; ++ pos = dns_packet_copy(buf,len,pos,opt_class,2); if (!pos) return pos; ++ pos = dns_packet_copy(buf,len,pos,opt_ttl,4); if (!pos) return pos; ++ if (opt_ttl[0]) return pos; // unsupported RCODE in query ++ if (opt_ttl[1]) return pos; // unsupported version ++ do_dnssec = opt_ttl[2] & 0x80; ++ uint16_unpack_big(opt_class, &size); ++ min_len = do_dnssec ? 1220 : 512; ++ max_response_len = size > 4000 ? 4000 : size; ++ if (max_response_len < min_len) { max_response_len = min_len; } ++ } ++ return pos; ++} +diff -rNU3 djbdns-1.05.tds-base/edns0.h djbdns-1.05.tinydnssec/edns0.h +--- djbdns-1.05.tds-base/edns0.h 1970-01-01 01:00:00.000000000 +0100 ++++ djbdns-1.05.tinydnssec/edns0.h 2012-12-06 22:39:13.000000000 +0100 +@@ -0,0 +1,22 @@ ++/* (C) 2012 Peter Conrad ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#ifndef _EDNS0_H ++ ++#define _EDNS0_H ++ ++extern unsigned int check_edns0(const char *, const char *, const int, unsigned int); ++ ++#endif +diff -rNU3 djbdns-1.05.tds-base/Makefile djbdns-1.05.tinydnssec/Makefile +--- djbdns-1.05.tds-base/Makefile 2012-12-06 22:45:45.000000000 +0100 ++++ djbdns-1.05.tinydnssec/Makefile 2012-12-07 11:07:23.000000000 +0100 +@@ -53,10 +53,10 @@ + axfrdns: \ + load axfrdns.o iopause.o droproot.o tdlookup.o response.o qlog.o \ + prot.o timeoutread.o timeoutwrite.o clientloc.o dns.a libtai.a alloc.a env.a \ +-cdb.a buffer.a unix.a byte.a ++cdb.a buffer.a unix.a byte.a sha1.o base32hex.o edns0.o + ./load axfrdns iopause.o droproot.o tdlookup.o response.o \ + qlog.o prot.o timeoutread.o timeoutwrite.o clientloc.o dns.a libtai.a \ +- alloc.a env.a cdb.a buffer.a unix.a byte.a ++ alloc.a env.a cdb.a buffer.a unix.a byte.a sha1.o base32hex.o edns0.o + + axfrdns-conf: \ + load axfrdns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a +@@ -76,6 +76,10 @@ + response.h uint32.h clientloc.h + ./compile axfrdns.c + ++base32hex.o: \ ++compile base32hex.c base32hex.h ++ ./compile base32hex.c ++ + buffer.a: \ + makelib buffer.o buffer_1.o buffer_2.o buffer_copy.o buffer_get.o \ + buffer_put.o strerr_die.o strerr_sys.o +@@ -454,10 +458,11 @@ + + dnsq: \ + load dnsq.o iopause.o printrecord.o printpacket.o parsetype.o dns.a \ +-env.a libtai.a buffer.a alloc.a unix.a byte.a socket.lib ++env.a libtai.a buffer.a alloc.a unix.a byte.a socket.lib printtype.o \ ++base32hex.o + ./load dnsq iopause.o printrecord.o printpacket.o \ + parsetype.o dns.a env.a libtai.a buffer.a alloc.a unix.a \ +- byte.a `cat socket.lib` ++ byte.a `cat socket.lib` printtype.o base32hex.o + + dnsq.o: \ + compile dnsq.c uint16.h strerr.h buffer.h scan.h str.h byte.h error.h \ +@@ -467,10 +472,11 @@ + + dnsqr: \ + load dnsqr.o iopause.o printrecord.o printpacket.o parsetype.o dns.a \ +-env.a libtai.a buffer.a alloc.a unix.a byte.a socket.lib ++env.a libtai.a buffer.a alloc.a unix.a byte.a socket.lib printtype.o \ ++base32hex.o + ./load dnsqr iopause.o printrecord.o printpacket.o \ + parsetype.o dns.a env.a libtai.a buffer.a alloc.a unix.a \ +- byte.a `cat socket.lib` ++ byte.a `cat socket.lib` printtype.o base32hex.o + + dnsqr.o: \ + compile dnsqr.c uint16.h strerr.h buffer.h scan.h str.h byte.h \ +@@ -480,10 +486,10 @@ + + dnstrace: \ + load dnstrace.o dd.o iopause.o printrecord.o parsetype.o dns.a env.a \ +-libtai.a alloc.a buffer.a unix.a byte.a socket.lib ++libtai.a alloc.a buffer.a unix.a byte.a socket.lib printtype.o base32hex.o + ./load dnstrace dd.o iopause.o printrecord.o parsetype.o \ + dns.a env.a libtai.a alloc.a buffer.a unix.a byte.a `cat \ +- socket.lib` ++ socket.lib` printtype.o base32hex.o + + dnstrace.o: \ + compile dnstrace.c uint16.h uint32.h fmt.h str.h byte.h ip4.h \ +@@ -514,6 +520,10 @@ + compile droproot.c env.h scan.h prot.h strerr.h + ./compile droproot.c + ++edns0.o: \ ++compile edns0.c edns0.h uint16.h dns.h response.h iopause.h taia.h uint64.h ++ ./compile edns0.c ++ + env.a: \ + makelib env.o + ./makelib env.a env.o +@@ -689,10 +699,10 @@ + + pickdns: \ + load pickdns.o server.o iopause.o response.o droproot.o qlog.o prot.o dns.a \ +-env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib ++env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib edns0.o + ./load pickdns server.o iopause.o response.o droproot.o qlog.o \ + prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ +- byte.a `cat socket.lib` ++ byte.a `cat socket.lib` edns0.o + + pickdns-conf: \ + load pickdns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a +@@ -725,15 +735,19 @@ + printpacket.o: \ + compile printpacket.c uint16.h uint32.h error.h byte.h dns.h \ + stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h \ +-printrecord.h stralloc.h printpacket.h stralloc.h ++printrecord.h stralloc.h printpacket.h stralloc.h printtype.h + ./compile printpacket.c + + printrecord.o: \ + compile printrecord.c uint16.h uint32.h error.h byte.h dns.h \ + stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h \ +-printrecord.h stralloc.h ++printrecord.h stralloc.h printtype.h + ./compile printrecord.c + ++printtype.o: \ ++compile printtype.c printtype.h dns.h stralloc.h byte.h uint16.h iopause.h taia.h uint64.h ++ ./compile printtype.c ++ + prog: \ + dnscache-conf dnscache walldns-conf walldns rbldns-conf rbldns \ + rbldns-data pickdns-conf pickdns pickdns-data tinydns-conf tinydns \ +@@ -767,10 +781,10 @@ + + rbldns: \ + load rbldns.o server.o iopause.o response.o dd.o droproot.o qlog.o prot.o dns.a \ +-env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib ++env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib edns0.o + ./load rbldns server.o iopause.o response.o dd.o droproot.o qlog.o \ + prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ +- byte.a `cat socket.lib` ++ byte.a `cat socket.lib` edns0.o + + rbldns-conf: \ + load rbldns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a +@@ -840,7 +854,7 @@ + compile server.c byte.h case.h env.h buffer.h strerr.h ip4.h uint16.h \ + ndelay.h socket.h uint16.h droproot.h qlog.h uint16.h response.h \ + uint32.h dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h \ +-taia.h iopause.h alloc.h str.h ++taia.h iopause.h alloc.h str.h edns0.h + ./compile server.c + + setup: \ +@@ -931,6 +945,10 @@ + cp /dev/null haven2i.h + ./choose cL tryn2i haven2i.h1 haven2i.h2 socket > haven2i.h + ++sha1.o: \ ++compile sha1.c sha1.h ++ ./compile sha1.c ++ + str_chr.o: \ + compile str_chr.c str.h + ./compile str_chr.c +@@ -1072,7 +1090,7 @@ + tdlookup.o: \ + compile tdlookup.c uint16.h open.h tai.h uint64.h cdb.h uint32.h \ + byte.h case.h dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h \ +-taia.h seek.h response.h uint32.h ip6.h clientloc.h ++taia.h seek.h response.h uint32.h ip6.h clientloc.h sha1.h base32hex.h + ./compile tdlookup.c + + timeoutread.o: \ +@@ -1088,10 +1106,10 @@ + tinydns: \ + load tinydns.o server.o iopause.o droproot.o tdlookup.o response.o qlog.o \ + prot.o clientloc.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a byte.a \ +-socket.lib ++socket.lib sha1.o base32hex.o edns0.o + ./load tinydns server.o iopause.o droproot.o tdlookup.o response.o \ + qlog.o prot.o clientloc.o dns.a libtai.a env.a cdb.a alloc.a buffer.a \ +- unix.a byte.a `cat socket.lib` ++ unix.a byte.a `cat socket.lib` sha1.o base32hex.o edns0.o + + tinydns-conf: \ + load tinydns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a +@@ -1126,11 +1144,12 @@ + ./compile tinydns-edit.c + + tinydns-get: \ +-load tinydns-get.o tdlookup.o response.o printpacket.o printrecord.o \ +-parsetype.o clientloc.o dns.a libtai.a cdb.a buffer.a alloc.a unix.a byte.a ++load tinydns-get.o tdlookup.o sha1.o response.o printpacket.o printrecord.o \ ++parsetype.o clientloc.o dns.a libtai.a cdb.a buffer.a alloc.a unix.a byte.a \ ++base32hex.o printtype.o + ./load tinydns-get tdlookup.o response.o printpacket.o \ + printrecord.o parsetype.o clientloc.o dns.a libtai.a cdb.a buffer.a \ +- alloc.a unix.a byte.a ++ alloc.a unix.a byte.a sha1.o base32hex.o printtype.o + + tinydns-get.o: \ + compile tinydns-get.c str.h byte.h scan.h exit.h stralloc.h \ +@@ -1198,10 +1217,10 @@ + + walldns: \ + load walldns.o server.o iopause.o response.o droproot.o qlog.o prot.o dd.o \ +-dns.a env.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib ++dns.a env.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib edns0.o + ./load walldns server.o iopause.o response.o droproot.o qlog.o \ + prot.o dd.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a \ +- byte.a `cat socket.lib` ++ byte.a `cat socket.lib` edns0.o + + walldns-conf: \ + load walldns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a +@@ -1227,4 +1246,4 @@ + ./choose c trysa6 sockaddr_in6.h1 sockaddr_in6.h2 > sockaddr_in6.h + + clean: +- rm -f `cat TARGETS` ++ rm -f `cat TARGETS` data data.cdb test/[ot]* +diff -rNU3 djbdns-1.05.tds-base/parsetype.c djbdns-1.05.tinydnssec/parsetype.c +--- djbdns-1.05.tds-base/parsetype.c 2001-02-11 22:11:45.000000000 +0100 ++++ djbdns-1.05.tinydnssec/parsetype.c 2012-12-06 22:39:13.000000000 +0100 +@@ -24,6 +24,8 @@ + else if (case_equals(s,"key")) byte_copy(type,2,DNS_T_KEY); + else if (case_equals(s,"aaaa")) byte_copy(type,2,DNS_T_AAAA); + else if (case_equals(s,"axfr")) byte_copy(type,2,DNS_T_AXFR); ++ else if (case_equals(s,"dnskey")) byte_copy(type,2,DNS_T_DNSKEY); ++ else if (case_equals(s,"ds")) byte_copy(type,2,DNS_T_DS); + else + return 0; + +diff -rNU3 djbdns-1.05.tds-base/printpacket.c djbdns-1.05.tinydnssec/printpacket.c +--- djbdns-1.05.tds-base/printpacket.c 2001-02-11 22:11:45.000000000 +0100 ++++ djbdns-1.05.tinydnssec/printpacket.c 2012-12-06 22:39:13.000000000 +0100 +@@ -5,6 +5,7 @@ + #include "dns.h" + #include "printrecord.h" + #include "printpacket.h" ++#include "printtype.h" + + static char *d; + +@@ -67,8 +68,7 @@ + X("weird class") + } + else { +- uint16_unpack_big(data,&type); +- NUM(type) ++ if (!printtype(out,data)) return 0; + X(" ") + if (!dns_domain_todot_cat(out,d)) return 0; + } +diff -rNU3 djbdns-1.05.tds-base/printrecord.c djbdns-1.05.tinydnssec/printrecord.c +--- djbdns-1.05.tds-base/printrecord.c 2012-12-06 22:45:38.000000000 +0100 ++++ djbdns-1.05.tinydnssec/printrecord.c 2012-12-06 22:39:13.000000000 +0100 +@@ -5,9 +5,25 @@ + #include "dns.h" + #include "printrecord.h" + #include "ip6.h" ++#include "base32hex.h" ++#include "printtype.h" + + static char *d; + ++static const char *HEX = "0123456789ABCDEF"; ++ ++static int hexout(stralloc *out,const char *buf,unsigned int len,unsigned int pos,unsigned int n) { ++ unsigned char c; ++ int i; ++ ++ for (i = 0; i < n; i++) { ++ pos = dns_packet_copy(buf,len,pos,&c,1); if (!pos) return 0; ++ if (!stralloc_catb(out,&HEX[(c>>4)&0xf],1)) return 0; ++ if (!stralloc_catb(out,&HEX[c&0xf],1)) return 0; ++ } ++ return pos; ++} ++ + unsigned int printrecord_cat(stralloc *out,const char *buf,unsigned int len,unsigned int pos,const char *q,const char qtype[2]) + { + const char *x; +@@ -18,6 +34,7 @@ + unsigned int newpos; + int i; + unsigned char ch; ++ int rawlen; + + pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; + pos = dns_packet_copy(buf,len,pos,misc,10); if (!pos) return 0; +@@ -33,15 +50,20 @@ + + if (!dns_domain_todot_cat(out,d)) return 0; + if (!stralloc_cats(out," ")) return 0; +- uint32_unpack_big(misc + 4,&u32); +- if (!stralloc_catulong0(out,u32,0)) return 0; ++ if (byte_diff(misc,2,DNS_T_OPT)) { ++ uint32_unpack_big(misc + 4,&u32); ++ if (!stralloc_catulong0(out,u32,0)) return 0; + +- if (byte_diff(misc + 2,2,DNS_C_IN)) { +- if (!stralloc_cats(out," weird class\n")) return 0; +- return newpos; ++ if (byte_diff(misc + 2,2,DNS_C_IN)) { ++ if (!stralloc_cats(out," weird class\n")) return 0; ++ return newpos; ++ } ++ } else { ++ if (!stralloc_cats(out,"0")) return 0; + } + + x = 0; ++ rawlen = 0; + if (byte_equal(misc,2,DNS_T_NS)) x = " NS "; + if (byte_equal(misc,2,DNS_T_PTR)) x = " PTR "; + if (byte_equal(misc,2,DNS_T_CNAME)) x = " CNAME "; +@@ -92,12 +114,111 @@ + stringlen=ip6_fmt(ip6str,misc); + if (!stralloc_catb(out,ip6str,stringlen)) return 0; + } ++ else if (byte_equal(misc,2,DNS_T_DNSKEY)) { ++ pos = dns_packet_copy(buf,len,pos,misc,4); if (!pos) return 0; ++ if (!stralloc_cats(out," DNSKEY ")) return 0; ++ uint16_unpack_big(misc,&u16); ++ if (!stralloc_catulong0(out,u16,0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!stralloc_catulong0(out,misc[2],0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!stralloc_catulong0(out,misc[3],0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ rawlen = datalen - 4; ++ } ++ else if (byte_equal(misc,2,DNS_T_DS)) { ++ pos = dns_packet_copy(buf,len,pos,misc,4); if (!pos) return 0; ++ if (!stralloc_cats(out," DS ")) return 0; ++ uint16_unpack_big(misc,&u16); ++ if (!stralloc_catulong0(out,u16,0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!stralloc_catulong0(out,misc[2],0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!stralloc_catulong0(out,misc[3],0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ pos = hexout(out,buf,len,pos,datalen - 4); if (!pos) return 0; ++ } ++ else if (byte_equal(misc,2,DNS_T_RRSIG)) { ++ pos = dns_packet_copy(buf,len,pos,misc,18); if (!pos) return 0; ++ if (!stralloc_cats(out," RRSIG ")) return 0; ++ if (!printtype(out,misc)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!stralloc_catulong0(out,misc[2],0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!stralloc_catulong0(out,misc[3],0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ uint32_unpack_big(misc + 4,&u32); ++ if (!stralloc_catulong0(out,u32,0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ uint32_unpack_big(misc + 8,&u32); ++ if (!stralloc_catulong0(out,u32,0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ uint32_unpack_big(misc + 12,&u32); ++ if (!stralloc_catulong0(out,u32,0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ uint16_unpack_big(misc + 16,&u16); ++ if (!stralloc_catulong0(out,u16,0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ rawlen = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; ++ rawlen = datalen - 18 - (rawlen - pos); ++ pos += datalen - 18 - rawlen; ++ if (!dns_domain_todot_cat(out,d)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ } ++ else if (byte_equal(misc,2,DNS_T_NSEC3)) { ++ char nextHash[255]; ++ char nextOwner[255*8/5]; ++ int j; ++ pos = dns_packet_copy(buf,len,pos,misc,5); if (!pos) return 0; ++ if (!stralloc_cats(out," NSEC3 ")) return 0; ++ if (!stralloc_catulong0(out,misc[0],0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!stralloc_catulong0(out,misc[1],0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ uint16_unpack_big(misc+2,&u16); ++ if (!stralloc_catulong0(out,u16,0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!misc[4]) ++ if (!stralloc_cats(out,"-")) return 0; ++ pos = hexout(out,buf,len,pos,misc[4]); if (!pos) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ pos = dns_packet_copy(buf,len,pos,misc,1); if (!pos) return 0; ++ pos = dns_packet_copy(buf,len,pos,nextHash,misc[0]); if (!pos) return 0; ++ i = base32hex(nextOwner, nextHash, misc[0]); ++ if (!stralloc_catb(out,nextOwner,i)) return 0; ++ while (pos < newpos) { ++ pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0; ++ pos = dns_packet_copy(buf,len,pos,nextHash,misc[1]); if (!pos) return 0; ++ j = 8 * misc[1]; ++ for (i = 0; i < j; i++) { ++ if (nextHash[i/8] & (1 << (7 - (i%8)))) { ++ misc[1] = i; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!printtype(out,misc)) return 0; ++ } ++ } ++ } ++ } ++ else if (byte_equal(misc,2,DNS_T_OPT)) { ++ if (!stralloc_cats(out," OPT ")) return 0; ++ uint16_unpack_big(misc+2, &u16); ++ if (!stralloc_catulong0(out,u16,0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!stralloc_catulong0(out,misc[4],0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!stralloc_catulong0(out,misc[5],0)) return 0; ++ if (!stralloc_cats(out," ")) return 0; ++ if (!hexout(out,misc,8,6,2)) return 0; ++ rawlen = datalen; ++ } + else { + if (!stralloc_cats(out," ")) return 0; + uint16_unpack_big(misc,&u16); + if (!stralloc_catulong0(out,u16,0)) return 0; + if (!stralloc_cats(out," ")) return 0; +- while (datalen--) { ++ rawlen = datalen; ++ } ++ while (rawlen--) { + pos = dns_packet_copy(buf,len,pos,misc,1); if (!pos) return 0; + if ((misc[0] >= 33) && (misc[0] <= 126) && (misc[0] != '\\')) { + if (!stralloc_catb(out,misc,1)) return 0; +@@ -111,7 +232,6 @@ + if (!stralloc_catb(out,misc,4)) return 0; + } + } +- } + + if (!stralloc_cats(out,"\n")) return 0; + if (pos != newpos) { errno = error_proto; return 0; } +diff -rNU3 djbdns-1.05.tds-base/printtype.c djbdns-1.05.tinydnssec/printtype.c +--- djbdns-1.05.tds-base/printtype.c 1970-01-01 01:00:00.000000000 +0100 ++++ djbdns-1.05.tinydnssec/printtype.c 2012-12-06 22:39:13.000000000 +0100 +@@ -0,0 +1,47 @@ ++/* (C) 2012 Peter Conrad ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include "byte.h" ++#include "dns.h" ++#include "uint16.h" ++#include "printtype.h" ++ ++int printtype(stralloc *out, const char type[2]) { ++uint16 u16; ++ ++ if (byte_equal(type,2,DNS_T_A)) return stralloc_cats(out,"A"); ++ if (byte_equal(type,2,DNS_T_NS)) return stralloc_cats(out,"NS"); ++ if (byte_equal(type,2,DNS_T_CNAME)) return stralloc_cats(out,"CNAME"); ++ if (byte_equal(type,2,DNS_T_SOA)) return stralloc_cats(out,"SOA"); ++ if (byte_equal(type,2,DNS_T_PTR)) return stralloc_cats(out,"PTR"); ++ if (byte_equal(type,2,DNS_T_HINFO)) return stralloc_cats(out,"HINFO"); ++ if (byte_equal(type,2,DNS_T_MX)) return stralloc_cats(out,"MX"); ++ if (byte_equal(type,2,DNS_T_TXT)) return stralloc_cats(out,"TXT"); ++ if (byte_equal(type,2,DNS_T_RP)) return stralloc_cats(out,"RP"); ++ if (byte_equal(type,2,DNS_T_SIG)) return stralloc_cats(out,"SIG"); ++ if (byte_equal(type,2,DNS_T_KEY)) return stralloc_cats(out,"KEY"); ++ if (byte_equal(type,2,DNS_T_AAAA)) return stralloc_cats(out,"AAAA"); ++ if (byte_equal(type,2,DNS_T_OPT)) return stralloc_cats(out,"OPT"); ++ if (byte_equal(type,2,DNS_T_DS)) return stralloc_cats(out,"DS"); ++ if (byte_equal(type,2,DNS_T_RRSIG)) return stralloc_cats(out,"RRSIG"); ++ if (byte_equal(type,2,DNS_T_DNSKEY)) return stralloc_cats(out,"DNSKEY"); ++ if (byte_equal(type,2,DNS_T_NSEC3)) return stralloc_cats(out,"NSEC3"); ++ if (byte_equal(type,2,DNS_T_NSEC3PARAM)) return stralloc_cats(out,"NSEC3PARAM"); ++ if (byte_equal(type,2,DNS_T_AXFR)) return stralloc_cats(out,"AXFR"); ++ if (byte_equal(type,2,DNS_T_ANY)) return stralloc_cats(out,"*"); ++ ++ uint16_unpack_big(type,&u16); ++ return stralloc_catulong0(out,u16,0); ++} +diff -rNU3 djbdns-1.05.tds-base/printtype.h djbdns-1.05.tinydnssec/printtype.h +--- djbdns-1.05.tds-base/printtype.h 1970-01-01 01:00:00.000000000 +0100 ++++ djbdns-1.05.tinydnssec/printtype.h 2012-12-06 22:39:13.000000000 +0100 +@@ -0,0 +1,23 @@ ++/* (C) 2012 Peter Conrad ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#ifndef _PRINTTYPE_H ++#define _PRINTTYPE_H ++ ++#include "stralloc.h" ++ ++extern int printtype(stralloc *, const char *); ++ ++#endif +diff -rNU3 djbdns-1.05.tds-base/response.c djbdns-1.05.tinydnssec/response.c +--- djbdns-1.05.tds-base/response.c 2001-02-11 22:11:45.000000000 +0100 ++++ djbdns-1.05.tinydnssec/response.c 2012-12-06 22:39:13.000000000 +0100 +@@ -5,6 +5,8 @@ + + char response[65535]; + unsigned int response_len = 0; /* <= 65535 */ ++unsigned int max_response_len = 0; /* <= 65535 */ ++unsigned int do_dnssec = 0; + static unsigned int tctarget; + + #define NAMES 100 +diff -rNU3 djbdns-1.05.tds-base/response.h djbdns-1.05.tinydnssec/response.h +--- djbdns-1.05.tds-base/response.h 2001-02-11 22:11:45.000000000 +0100 ++++ djbdns-1.05.tinydnssec/response.h 2012-12-06 22:39:13.000000000 +0100 +@@ -5,6 +5,8 @@ + + extern char response[]; + extern unsigned int response_len; ++extern unsigned int max_response_len; ++extern unsigned int do_dnssec; + + extern int response_query(const char *,const char *,const char *); + extern void response_nxdomain(void); +diff -rNU3 djbdns-1.05.tds-base/server.c djbdns-1.05.tinydnssec/server.c +--- djbdns-1.05.tds-base/server.c 2012-12-06 22:45:38.000000000 +0100 ++++ djbdns-1.05.tinydnssec/server.c 2012-12-06 22:39:13.000000000 +0100 +@@ -1,3 +1,4 @@ ++#include "edns0.h" + #include "byte.h" + #include "case.h" + #include "env.h" +@@ -63,6 +64,9 @@ + if (header[2] & 126) goto NOTIMP; + if (byte_equal(qtype,2,DNS_T_AXFR)) goto NOTIMP; + ++ pos = check_edns0(header, buf, len, pos); ++ if (!pos) goto NOQ; ++ + case_lowerb(q,dns_domain_length(q)); + if (!respond(q,qtype,ip)) { + qlog(ip,port,header,q,qtype," - "); +@@ -168,7 +172,7 @@ + len = socket_recv6(udp53[i],buf,sizeof buf,ip,&port,&ifid); + if (len < 0) continue; + if (!doit()) continue; +- if (response_len > 512) response_tc(); ++ if (response_len > max_response_len) response_tc(); + socket_send6(udp53[i],response,response_len,ip,port,ifid); + /* may block for buffer space; if it fails, too bad */ + } +diff -rNU3 djbdns-1.05.tds-base/sha1.c djbdns-1.05.tinydnssec/sha1.c +--- djbdns-1.05.tds-base/sha1.c 1970-01-01 01:00:00.000000000 +0100 ++++ djbdns-1.05.tinydnssec/sha1.c 2012-12-06 22:39:13.000000000 +0100 +@@ -0,0 +1,385 @@ ++/* ++SHA-1 in C ++By Steve Reid ++100% Public Domain ++ ++----------------- ++Modified 7/98 ++By James H. Brown ++Still 100% Public Domain ++ ++Corrected a problem which generated improper hash values on 16 bit machines ++Routine SHA1Update changed from ++ void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int ++len) ++to ++ void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned ++long len) ++ ++The 'len' parameter was declared an int which works fine on 32 bit machines. ++However, on 16 bit machines an int is too small for the shifts being done ++against ++it. This caused the hash function to generate incorrect values if len was ++greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). ++ ++Since the file IO in main() reads 16K at a time, any file 8K or larger would ++be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million ++"a"s). ++ ++I also changed the declaration of variables i & j in SHA1Update to ++unsigned long from unsigned int for the same reason. ++ ++These changes should make no difference to any 32 bit implementations since ++an ++int and a long are the same size in those environments. ++ ++-- ++I also corrected a few compiler warnings generated by Borland C. ++1. Added #include for exit() prototype ++2. Removed unused variable 'j' in SHA1Final ++3. Changed exit(0) to return(0) at end of main. ++ ++ALL changes I made can be located by searching for comments containing 'JHB' ++----------------- ++Modified 8/98 ++By Steve Reid ++Still 100% public domain ++ ++1- Removed #include and used return() instead of exit() ++2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) ++3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net ++ ++----------------- ++Modified 4/01 ++By Saul Kravitz ++Still 100% PD ++Modified to run on Compaq Alpha hardware. ++ ++----------------- ++Modified 07/2002 ++By Ralph Giles ++Still 100% public domain ++modified for use with stdint types, autoconf ++code cleanup, removed attribution comments ++switched SHA1Final() argument order for consistency ++use SHA1_ prefix for public api ++move public api to sha1.h ++ ++----------------- ++Modified 08/2012 ++By Peter Conrad ++Still 100% public domain ++ ++Taken from http://svn.ghostscript.com/jbig2dec/trunk/ for inclusion in tinydns ++Added/removed some includes ++Replaced WORDS_BIGENDIAN with BYTE_ORDER == BIG_ENDIAN check ++Test succeeds on x86_64 ++*/ ++ ++/* ++Test Vectors (from FIPS PUB 180-1) ++"abc" ++ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D ++"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ++ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 ++A million repetitions of "a" ++ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F ++*/ ++ ++/* #define SHA1HANDSOFF */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++ ++#include "sha1.h" ++ ++void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]); ++ ++#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) ++ ++/* blk0() and blk() perform the initial expand. */ ++/* I got the idea of expanding during the round function from SSLeay */ ++/* FIXME: can we do this in an endian-proof way? */ ++#if BYTE_ORDER == BIG_ENDIAN ++#define blk0(i) block->l[i] ++#else ++#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ ++ |(rol(block->l[i],8)&0x00FF00FF)) ++#endif ++#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ ++ ^block->l[(i+2)&15]^block->l[i&15],1)) ++ ++/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ ++#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); ++#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); ++#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); ++#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); ++#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); ++ ++ ++#ifdef VERBOSE /* SAK */ ++void SHAPrintContext(SHA1_CTX *context, char *msg){ ++ printf("%s (%d,%d) %x %x %x %x %x\n", ++ msg, ++ context->count[0], context->count[1], ++ context->state[0], ++ context->state[1], ++ context->state[2], ++ context->state[3], ++ context->state[4]); ++} ++#endif /* VERBOSE */ ++ ++/* Hash a single 512-bit block. This is the core of the algorithm. */ ++void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]) ++{ ++ uint32_t a, b, c, d, e; ++ typedef union { ++ uint8_t c[64]; ++ uint32_t l[16]; ++ } CHAR64LONG16; ++ CHAR64LONG16* block; ++ ++#ifdef SHA1HANDSOFF ++ static uint8_t workspace[64]; ++ block = (CHAR64LONG16*)workspace; ++ memcpy(block, buffer, 64); ++#else ++ block = (CHAR64LONG16*)buffer; ++#endif ++ ++ /* Copy context->state[] to working vars */ ++ a = state[0]; ++ b = state[1]; ++ c = state[2]; ++ d = state[3]; ++ e = state[4]; ++ ++ /* 4 rounds of 20 operations each. Loop unrolled. */ ++ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); ++ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); ++ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); ++ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); ++ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); ++ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); ++ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); ++ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); ++ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); ++ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); ++ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); ++ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); ++ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); ++ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); ++ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); ++ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); ++ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); ++ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); ++ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); ++ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); ++ ++ /* Add the working vars back into context.state[] */ ++ state[0] += a; ++ state[1] += b; ++ state[2] += c; ++ state[3] += d; ++ state[4] += e; ++ ++ /* Wipe variables */ ++ a = b = c = d = e = 0; ++} ++ ++ ++/* SHA1Init - Initialize new context */ ++void SHA1_Init(SHA1_CTX* context) ++{ ++ /* SHA1 initialization constants */ ++ context->state[0] = 0x67452301; ++ context->state[1] = 0xEFCDAB89; ++ context->state[2] = 0x98BADCFE; ++ context->state[3] = 0x10325476; ++ context->state[4] = 0xC3D2E1F0; ++ context->count[0] = context->count[1] = 0; ++} ++ ++ ++/* Run your data through this. */ ++void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len) ++{ ++ size_t i, j; ++ ++#ifdef VERBOSE ++ SHAPrintContext(context, "before"); ++#endif ++ ++ j = (context->count[0] >> 3) & 63; ++ if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; ++ context->count[1] += (len >> 29); ++ if ((j + len) > 63) { ++ memcpy(&context->buffer[j], data, (i = 64-j)); ++ SHA1_Transform(context->state, context->buffer); ++ for ( ; i + 63 < len; i += 64) { ++ SHA1_Transform(context->state, data + i); ++ } ++ j = 0; ++ } ++ else i = 0; ++ memcpy(&context->buffer[j], &data[i], len - i); ++ ++#ifdef VERBOSE ++ SHAPrintContext(context, "after "); ++#endif ++} ++ ++ ++/* Add padding and return the message digest. */ ++void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) ++{ ++ uint32_t i; ++ uint8_t finalcount[8]; ++ ++ for (i = 0; i < 8; i++) { ++ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] ++ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ ++ } ++ SHA1_Update(context, (uint8_t *)"\200", 1); ++ while ((context->count[0] & 504) != 448) { ++ SHA1_Update(context, (uint8_t *)"\0", 1); ++ } ++ SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */ ++ for (i = 0; i < SHA1_DIGEST_SIZE; i++) { ++ digest[i] = (uint8_t) ++ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); ++ } ++ ++ /* Wipe variables */ ++ i = 0; ++ memset(context->buffer, 0, 64); ++ memset(context->state, 0, 20); ++ memset(context->count, 0, 8); ++ memset(finalcount, 0, 8); /* SWR */ ++ ++#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */ ++ SHA1_Transform(context->state, context->buffer); ++#endif ++} ++ ++/*************************************************************/ ++ ++#if 0 ++int main(int argc, char** argv) ++{ ++int i, j; ++SHA1_CTX context; ++unsigned char digest[SHA1_DIGEST_SIZE], buffer[16384]; ++FILE* file; ++ ++ if (argc > 2) { ++ puts("Public domain SHA-1 implementation - by Steve Reid "); ++ puts("Modified for 16 bit environments 7/98 - by James H. Brown "); /* JHB */ ++ puts("Produces the SHA-1 hash of a file, or stdin if no file is specified."); ++ return(0); ++ } ++ if (argc < 2) { ++ file = stdin; ++ } ++ else { ++ if (!(file = fopen(argv[1], "rb"))) { ++ fputs("Unable to open file.", stderr); ++ return(-1); ++ } ++ } ++ SHA1_Init(&context); ++ while (!feof(file)) { /* note: what if ferror(file) */ ++ i = fread(buffer, 1, 16384, file); ++ SHA1_Update(&context, buffer, i); ++ } ++ SHA1_Final(&context, digest); ++ fclose(file); ++ for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) { ++ for (j = 0; j < 4; j++) { ++ printf("%02X", digest[i*4+j]); ++ } ++ putchar(' '); ++ } ++ putchar('\n'); ++ return(0); /* JHB */ ++} ++#endif ++ ++/* self test */ ++ ++#ifdef TEST ++ ++static char *test_data[] = { ++ "abc", ++ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", ++ "A million repetitions of 'a'"}; ++static char *test_results[] = { ++ "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D", ++ "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1", ++ "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"}; ++ ++ ++void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output) ++{ ++ int i,j; ++ char *c = output; ++ ++ for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) { ++ for (j = 0; j < 4; j++) { ++ sprintf(c,"%02X", digest[i*4+j]); ++ c += 2; ++ } ++ sprintf(c, " "); ++ c += 1; ++ } ++ *(c - 1) = '\0'; ++} ++ ++int main(int argc, char** argv) ++{ ++ int k; ++ SHA1_CTX context; ++ uint8_t digest[20]; ++ char output[80]; ++ ++ fprintf(stdout, "verifying SHA-1 implementation... "); ++ ++ for (k = 0; k < 2; k++){ ++ SHA1_Init(&context); ++ SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k])); ++ SHA1_Final(&context, digest); ++ digest_to_hex(digest, output); ++ ++ if (strcmp(output, test_results[k])) { ++ fprintf(stdout, "FAIL\n"); ++ fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[k]); ++ fprintf(stderr,"\t%s returned\n", output); ++ fprintf(stderr,"\t%s is correct\n", test_results[k]); ++ return (1); ++ } ++ } ++ /* million 'a' vector we feed separately */ ++ SHA1_Init(&context); ++ for (k = 0; k < 1000000; k++) ++ SHA1_Update(&context, (uint8_t*)"a", 1); ++ SHA1_Final(&context, digest); ++ digest_to_hex(digest, output); ++ if (strcmp(output, test_results[2])) { ++ fprintf(stdout, "FAIL\n"); ++ fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]); ++ fprintf(stderr,"\t%s returned\n", output); ++ fprintf(stderr,"\t%s is correct\n", test_results[2]); ++ return (1); ++ } ++ ++ /* success */ ++ fprintf(stdout, "ok\n"); ++ return(0); ++} ++#endif /* TEST */ +diff -rNU3 djbdns-1.05.tds-base/sha1.h djbdns-1.05.tinydnssec/sha1.h +--- djbdns-1.05.tds-base/sha1.h 1970-01-01 01:00:00.000000000 +0100 ++++ djbdns-1.05.tinydnssec/sha1.h 2012-12-06 22:39:13.000000000 +0100 +@@ -0,0 +1,29 @@ ++/* public api for steve reid's public domain SHA-1 implementation */ ++/* this file is in the public domain */ ++ ++#ifndef __SHA1_H ++#define __SHA1_H ++ ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef struct { ++ uint32_t state[5]; ++ uint32_t count[2]; ++ uint8_t buffer[64]; ++} SHA1_CTX; ++ ++#define SHA1_DIGEST_SIZE 20 ++ ++void SHA1_Init(SHA1_CTX* context); ++void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len); ++void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* __SHA1_H */ +diff -rNU3 djbdns-1.05.tds-base/TARGETS djbdns-1.05.tinydnssec/TARGETS +--- djbdns-1.05.tds-base/TARGETS 2012-12-06 22:45:38.000000000 +0100 ++++ djbdns-1.05.tinydnssec/TARGETS 2012-12-06 22:39:13.000000000 +0100 +@@ -240,3 +240,8 @@ + socket_accept6.o + socket_connect6.o + socket_tcp6.o ++base32hex.o ++sha1.o ++base32hex.o ++printtype.o ++edns0.o +diff -rNU3 djbdns-1.05.tds-base/tdlookup.c djbdns-1.05.tinydnssec/tdlookup.c +--- djbdns-1.05.tds-base/tdlookup.c 2012-12-06 22:45:38.000000000 +0100 ++++ djbdns-1.05.tinydnssec/tdlookup.c 2012-12-07 11:01:39.000000000 +0100 +@@ -10,6 +10,9 @@ + #include "response.h" + #include "ip6.h" + #include "clientloc.h" ++#include "alloc.h" ++#include "sha1.h" ++#include "base32hex.h" + + static int want(const char *owner,const char type[2]) + { +@@ -34,7 +37,7 @@ + } + + static char *d1; +- ++static char *wantAddr; + static char clientloc[2]; + static struct tai now; + static struct cdb c; +@@ -44,10 +47,18 @@ + static unsigned int dpos; + static char type[2]; + static uint32 ttl; ++static char *nsec3; ++static char *cname = 0; + ++/* returns -1 on failure, ++ * returns 0 on not found ++ * returns 1 when found ++ * returns 2 when flagwild is true and no wildcard match has been found but ++ * a direct match exists. This is for RFC-1034 section 4.3.3 compatibility. ++ */ + static int find(char *d,int flagwild) + { +- int r; ++ int r, direct=0; + char ch; + struct tai cutoff; + char ttd[8]; +@@ -57,7 +68,9 @@ + + for (;;) { + r = cdb_findnext(&c,d,dns_domain_length(d)); +- if (r <= 0) return r; ++ if (r < 0) return r; /* -1 */ ++ if (r == 0) { return flagwild ? direct ? 2 : 0 ++ : 0; } + dlen = cdb_datalen(&c); + if (dlen > sizeof data) return -1; + if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return -1; +@@ -68,6 +81,7 @@ + dpos = dns_packet_copy(data,dlen,dpos,recordloc,2); if (!dpos) return -1; + if (byte_diff(recordloc,2,clientloc)) continue; + } ++ direct = direct || (ch != '*'); + if (flagwild != (ch == '*')) continue; + dpos = dns_packet_copy(data,dlen,dpos,ttlstr,4); if (!dpos) return -1; + uint32_unpack_big(ttlstr,&ttl); +@@ -105,6 +119,123 @@ + return response_addname(d1); + } + ++static int addNSEC3(char *hashName) ++{ ++int r; ++ ++ cdb_findstart(&c); ++ while (r = find(hashName,0)) { ++ if (r == -1) return 0; ++ if (byte_equal(type,2,DNS_T_NSEC3)) { ++ if (!response_rstart(hashName,DNS_T_NSEC3,ttl)) return 0; ++ if (!response_addbytes(data + dpos,dlen - dpos)) return 0; ++ response_rfinish(RESPONSE_AUTHORITY); ++ } ++ else if (do_dnssec && byte_equal(type,2,DNS_T_RRSIG) && dlen > dpos+18 ++ && byte_equal(data+dpos,2,DNS_T_NSEC3)) { ++ if (!response_rstart(hashName,DNS_T_RRSIG,ttl)) return 0; ++ if (!dobytes(18)) return 0; ++ if (!doname()) return 0; ++ if (!response_addbytes(data + dpos,dlen - dpos)) return 0; ++ response_rfinish(RESPONSE_AUTHORITY); ++ } ++ } ++ return 1; ++} ++ ++static int addNSEC3Cover(char *name, char *control, int wild) ++{ ++SHA1_CTX ctx; ++int algo = 0, flags = 0, saltlen = 0, r; ++uint16 iterations = 0; ++char salt[255]; ++uint8_t digest[SHA1_DIGEST_SIZE]; ++ ++ /* Search NSEC3PARAM to find hash parameters */ ++ cdb_findstart(&c); ++ while (r = find(control,0)) { ++ if (r == -1) return 0; ++ if (byte_equal(type,2,DNS_T_NSEC3PARAM) && dlen - dpos > 5) { ++ algo = data[dpos]; ++ flags = data[dpos+1]; ++ uint16_unpack_big(data + dpos + 2, &iterations); ++ saltlen = data[dpos+4]; ++ if (algo != 1 || flags || dlen - dpos - 5 < saltlen) { ++ algo = 0; ++ } else { ++ byte_copy(salt,saltlen, data + dpos + 5); ++ break; ++ } ++ } ++ } ++ if (algo != 1) return 0; /* not found or unsupported algorithm / flags */ ++ ++ /* Compute hash value */ ++ case_lowerb(name,dns_domain_length(name)); ++ SHA1_Init(&ctx); ++ if (wild) SHA1_Update(&ctx, "\1*", 2); ++ SHA1_Update(&ctx, name, dns_domain_length(name)); ++ SHA1_Update(&ctx, salt, saltlen); ++ SHA1_Final(&ctx, digest); ++ while (iterations-- > 0) { ++ SHA1_Init(&ctx); ++ SHA1_Update(&ctx, digest, SHA1_DIGEST_SIZE); ++ SHA1_Update(&ctx, salt, saltlen); ++ SHA1_Final(&ctx, digest); ++ } ++ ++ /* Find covering hash */ ++ char nibble = ((digest[0] >> 4) & 0xf) + '0'; ++ if (nibble > '9') { nibble += 'a' - '9' - 1; } ++ salt[0] = 1; ++ salt[1] = nibble; ++ byte_copy(salt+2, dns_domain_length(control), control); ++ cdb_findstart(&c); ++ while (r = find(salt,0)) { ++ if (r == -1) return 0; ++ if (byte_equal(type,2,DNS_T_HASHLIST) && dlen - dpos >= SHA1_DIGEST_SIZE) { ++ int hpos = dpos + SHA1_DIGEST_SIZE; ++ while (byte_diff(digest,SHA1_DIGEST_SIZE,data+hpos) > 0 && hpos < dlen) hpos += SHA1_DIGEST_SIZE; ++ hpos -= SHA1_DIGEST_SIZE; ++ *salt = base32hex(salt+1,data+hpos,SHA1_DIGEST_SIZE); ++ byte_copy(salt + *salt + 1, dns_domain_length(control), control); ++ break; ++ } ++ } ++ if (*salt == 1) return 0; /* not found */ ++ return addNSEC3(salt); ++} ++ ++static int addClosestEncloserProof(char *name, char *control, int includeWild) ++{ ++char *q = name; ++char *hashName = 0; ++int r; ++ ++ while (*q) { ++ cdb_findstart(&c); ++ while (r = find(q,0)) { ++ if (r == -1) return 0; ++ if (byte_equal(type,2,DNS_T_HASHREF) && dlen > dpos) { ++ if (!dns_packet_getname(data,dlen,dpos,&hashName)) return 0; ++ break; ++ } ++ } ++ if (hashName) { ++ int rc = addNSEC3(hashName); ++ alloc_free(hashName); ++ if (!rc) return 0; ++ hashName = 0; ++ break; ++ } ++ name = q; ++ q += *q + 1; ++ } ++ if (!*q) return 0; ++ if (includeWild && !addNSEC3Cover(q, control, 1)) return 0; ++ return addNSEC3Cover(name, control, 0); ++} ++ + static int doit(char *q,char qtype[2]) + { + unsigned int bpos; +@@ -118,6 +249,8 @@ + int r; + int flagns; + int flagauthoritative; ++ int flagsigned; ++ char *flagcname; + char x[20]; + uint16 u16; + char addr[8][4]; +@@ -132,18 +265,28 @@ + for (;;) { + flagns = 0; + flagauthoritative = 0; ++ flagsigned = 0; + cdb_findstart(&c); + while (r = find(control,0)) { + if (r == -1) return 0; + if (byte_equal(type,2,DNS_T_SOA)) flagauthoritative = 1; +- if (byte_equal(type,2,DNS_T_NS)) flagns = 1; ++ else if (byte_equal(type,2,DNS_T_NS)) flagns = 1; ++ else if (byte_equal(type,2,DNS_T_DNSKEY)) flagsigned |= 1; ++ else if (byte_equal(type,2,DNS_T_RRSIG)) flagsigned |= 2; ++ else if (byte_equal(type,2,DNS_T_NSEC3PARAM)) flagsigned |= 4; + } ++ flagsigned = (flagsigned == 7); + if (flagns) break; +- if (!*control) return 0; /* q is not within our bailiwick */ ++ if (!*control) { ++ if (!cname) return 0; /* q is not within our bailiwick */ ++ response[2] &= ~4; /* CNAME chain ends in external reference */ ++ return 1; ++ } + control += *control; + control += 1; + } + ++ wild = q; + if (!flagauthoritative) { + response[2] &= ~4; + goto AUTHORITY; /* q is in a child zone */ +@@ -152,7 +295,11 @@ + + flaggavesoa = 0; + flagfound = 0; +- wild = q; ++ flagcname = 0; ++ if (nsec3) { ++ alloc_free(nsec3); ++ nsec3 = 0; ++ } + + for (;;) { + addrnum = addr6num = 0; +@@ -160,10 +307,29 @@ + cdb_findstart(&c); + while (r = find(wild,wild != q)) { + if (r == -1) return 0; ++ if (r == 2) break; + flagfound = 1; + if (flaggavesoa && byte_equal(type,2,DNS_T_SOA)) continue; +- if (byte_diff(type,2,qtype) && byte_diff(qtype,2,DNS_T_ANY) && byte_diff(type,2,DNS_T_CNAME)) continue; +- if (byte_equal(type,2,DNS_T_A) && (dlen - dpos == 4)) { ++ if (do_dnssec && byte_equal(type,2,DNS_T_HASHREF) && dlen > dpos) { ++ if (!dns_packet_getname(data,dlen,dpos,&nsec3)) return 0; ++ } ++ if (byte_diff(type,2,qtype) && byte_diff(qtype,2,DNS_T_ANY) && byte_diff(type,2,DNS_T_CNAME) ++ && (!do_dnssec || byte_diff(type,2,DNS_T_RRSIG))) continue; ++ if (byte_equal(type,2,DNS_T_HASHREF) || byte_equal(type,2,DNS_T_HASHLIST)) continue; ++ if (do_dnssec && byte_equal(type,2,DNS_T_RRSIG) && dlen - dpos > 18) { ++ char sigtype[2]; ++ struct tai valid; ++ uint32 validFrom, validUntil; ++ byte_copy(sigtype,2,data + dpos); ++ if (byte_diff(sigtype,2,qtype) && byte_diff(qtype,2,DNS_T_ANY) && byte_diff(sigtype,2,DNS_T_CNAME)) continue; ++ uint32_unpack_big(data + dpos + 12, &validFrom); ++ tai_unix(&valid, validFrom); ++ if (tai_less(&now, &valid)) continue; ++ uint32_unpack_big(data + dpos + 8, &validUntil); ++ tai_unix(&valid, validUntil); ++ if (tai_less(&valid, &now)) continue; ++ } ++ if (byte_equal(type,2,DNS_T_A) && (dlen - dpos == 4) && (!do_dnssec || addrnum < 8)) { + addrttl = ttl; + i = dns_random(addrnum + 1); + if (i < 8) { +@@ -174,7 +340,7 @@ + if (addrnum < 1000000) ++addrnum; + continue; + } +- if (byte_equal(type,2,DNS_T_AAAA) && (dlen - dpos == 16)) { ++ if (byte_equal(type,2,DNS_T_AAAA) && (dlen - dpos == 16) && (!do_dnssec || addr6num < 8)) { + addr6ttl = ttl; + i = dns_random(addr6num + 1); + if (i < 8) { +@@ -188,6 +354,9 @@ + if (!response_rstart(q,type,ttl)) return 0; + if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) { + if (!doname()) return 0; ++ if (byte_equal(type,2,DNS_T_CNAME) && byte_diff(qtype,2,DNS_T_CNAME)) { ++ if (!dns_domain_copy(&flagcname,d1)) return 0; ++ } + } + else if (byte_equal(type,2,DNS_T_MX)) { + if (!dobytes(2)) return 0; +@@ -199,10 +368,18 @@ + if (!dobytes(20)) return 0; + flaggavesoa = 1; + } ++ else if (byte_equal(type,2,DNS_T_RRSIG) && dlen - dpos > 18) { ++ char sigtype[2]; ++ byte_copy(sigtype,2,data + dpos); ++ if (!dobytes(18)) return 0; ++ if (!doname()) return 0; ++ if (!response_addbytes(data + dpos,dlen - dpos)) return 0; ++ } + else + if (!response_addbytes(data + dpos,dlen - dpos)) return 0; + response_rfinish(RESPONSE_ANSWER); + } ++ if (r == 2) break; + for (i = 0;i < addrnum;++i) + if (i < 8) { + if (!response_rstart(q,DNS_T_A,addrttl)) return 0; +@@ -223,6 +400,16 @@ + wild += 1; + } + ++ if (flagcname) { ++ if (response[RESPONSE_ANSWER+1] >= 100) { ++ dns_domain_free(&flagcname); /* most likely a loop */ ++ return 0; ++ } ++ if (cname) dns_domain_free(&cname); ++ cname = flagcname; ++ return doit(cname, qtype); ++ } ++ + if (!flagfound) + response_nxdomain(); + +@@ -230,22 +417,49 @@ + AUTHORITY: + aupos = response_len; + +- if (flagauthoritative && (aupos == anpos)) { +- cdb_findstart(&c); +- while (r = find(control,0)) { +- if (r == -1) return 0; +- if (byte_equal(type,2,DNS_T_SOA)) { +- if (!response_rstart(control,DNS_T_SOA,ttl)) return 0; +- if (!doname()) return 0; +- if (!doname()) return 0; +- if (!dobytes(20)) return 0; +- response_rfinish(RESPONSE_AUTHORITY); +- break; ++ if (flagauthoritative && (aupos == anpos)) { /* NODATA or NXDOMAIN */ ++ if (!flaggavesoa) { ++ cdb_findstart(&c); ++ while (r = find(control,0)) { ++ if (r == -1) return 0; ++ if (!flaggavesoa && byte_equal(type,2,DNS_T_SOA)) { ++ if (!response_rstart(control,DNS_T_SOA,ttl)) return 0; ++ if (!doname()) return 0; ++ if (!doname()) return 0; ++ if (!dobytes(20)) return 0; ++ response_rfinish(RESPONSE_AUTHORITY); ++ flaggavesoa = 1; ++ } ++ else if (do_dnssec && byte_equal(type,2,DNS_T_RRSIG) && dlen > dpos+18 ++ && byte_equal(data+dpos,2,DNS_T_SOA)) { ++ if (!response_rstart(control,DNS_T_RRSIG,ttl)) return 0; ++ if (!dobytes(18)) return 0; ++ if (!doname()) return 0; ++ if (!response_addbytes(data + dpos,dlen - dpos)) return 0; ++ response_rfinish(RESPONSE_AUTHORITY); ++ } ++ } ++ } ++ if (do_dnssec && flagsigned) { ++ if (flagfound && nsec3) { /* NODATA */ ++ if (!addNSEC3(nsec3)) return 0; ++ if (wild != q) { /* Wildcard NODATA */ ++ if (!addClosestEncloserProof(q, control, 0)) return 0; ++ } ++ } ++ else { /* NXDOMAIN, or query for NSEC3 owner name */ ++ if (!addClosestEncloserProof(q, control, 1)) return 0; + } + } + } +- else ++ else { ++ if (do_dnssec && wild != q && flagsigned) { /* Wildcard answer */ ++ char *nextCloser = q; ++ while (nextCloser + *nextCloser + 1 < wild) { nextCloser += *nextCloser + 1; } ++ if (!addNSEC3Cover(nextCloser, control, 0)) return 0; ++ } + if (want(control,DNS_T_NS)) { ++ int have_ds = 0; + cdb_findstart(&c); + while (r = find(control,0)) { + if (r == -1) return 0; +@@ -254,10 +468,33 @@ + if (!doname()) return 0; + response_rfinish(RESPONSE_AUTHORITY); + } ++ else if (do_dnssec && byte_equal(type,2,DNS_T_DS)) { ++ if (!response_rstart(control,DNS_T_DS,ttl)) return 0; ++ if (!response_addbytes(data + dpos,dlen - dpos)) return 0; ++ response_rfinish(RESPONSE_AUTHORITY); ++ have_ds = 1; ++ } ++ else if (do_dnssec && byte_equal(type,2,DNS_T_RRSIG) && dlen > dpos+18 ++ && (byte_equal(data+dpos,2,DNS_T_NS) ++ || byte_equal(data+dpos,2,DNS_T_DS))) { ++ if (!response_rstart(control,DNS_T_RRSIG,ttl)) return 0; ++ if (!dobytes(18)) return 0; ++ if (!doname()) return 0; ++ if (!response_addbytes(data + dpos,dlen - dpos)) return 0; ++ response_rfinish(RESPONSE_AUTHORITY); ++ } + } ++ if (do_dnssec && !flagauthoritative && !have_ds) { addNSEC3(control); } + } ++ } + + arpos = response_len; ++ if (do_dnssec) { ++ /* Add EDNS0 OPT RR */ ++ if (!response_rstart("",DNS_T_OPT,1 << 15)) return 0; ++ uint16_pack_big(response+arpos+3, 512); ++ response_rfinish(RESPONSE_ADDITIONAL); ++ } + + bpos = anpos; + while (bpos < arpos) { +@@ -265,25 +502,33 @@ + bpos = dns_packet_copy(response,arpos,bpos,x,10); if (!bpos) return 0; + if (byte_equal(x,2,DNS_T_NS) || byte_equal(x,2,DNS_T_MX)) { + if (byte_equal(x,2,DNS_T_NS)) { +- if (!dns_packet_getname(response,arpos,bpos,&d1)) return 0; ++ if (!dns_packet_getname(response,arpos,bpos,&wantAddr)) return 0; + } + else +- if (!dns_packet_getname(response,arpos,bpos + 2,&d1)) return 0; +- case_lowerb(d1,dns_domain_length(d1)); +- if (want(d1,DNS_T_A)) { ++ if (!dns_packet_getname(response,arpos,bpos + 2,&wantAddr)) return 0; ++ case_lowerb(wantAddr,dns_domain_length(wantAddr)); ++ if (want(wantAddr,DNS_T_A)) { + cdb_findstart(&c); +- while (r = find(d1,0)) { ++ while (r = find(wantAddr,0)) { + if (r == -1) return 0; + if (byte_equal(type,2,DNS_T_A)) { +- if (!response_rstart(d1,DNS_T_A,ttl)) return 0; ++ if (!response_rstart(wantAddr,DNS_T_A,ttl)) return 0; + if (!dobytes(4)) return 0; + response_rfinish(RESPONSE_ADDITIONAL); + } + else if (byte_equal(type,2,DNS_T_AAAA)) { +- if (!response_rstart(d1,DNS_T_AAAA,ttl)) return 0; ++ if (!response_rstart(wantAddr,DNS_T_AAAA,ttl)) return 0; + if (!dobytes(16)) return 0; + response_rfinish(RESPONSE_ADDITIONAL); + } ++ else if (do_dnssec && byte_equal(type,2,DNS_T_RRSIG) && dlen > dpos+18 ++ && (byte_equal(data+dpos,2,DNS_T_A) || byte_equal(data+dpos,2,DNS_T_AAAA))) { ++ if (!response_rstart(wantAddr,DNS_T_RRSIG,ttl)) return 0; ++ if (!dobytes(18)) return 0; ++ if (!doname()) return 0; ++ if (!response_addbytes(data + dpos,dlen - dpos)) return 0; ++ response_rfinish(RESPONSE_ADDITIONAL); ++ } + } + } + } +@@ -291,10 +536,10 @@ + bpos += u16; + } + +- if (flagauthoritative && (response_len > 512)) { ++ if (flagauthoritative && (response_len > max_response_len)) { + byte_zero(response + RESPONSE_ADDITIONAL,2); + response_len = arpos; +- if (response_len > 512) { ++ if (!do_dnssec && response_len > max_response_len) { + byte_zero(response + RESPONSE_AUTHORITY,2); + response_len = aupos; + } +@@ -316,6 +561,9 @@ + cdb_init(&c,fd); + + r = doit(q,qtype); ++ if (cname) { ++ dns_domain_free(&cname); ++ } + + cdb_free(&c); + close(fd); +diff -rNU3 djbdns-1.05.tds-base/tinydns-data.c djbdns-1.05.tinydnssec/tinydns-data.c +--- djbdns-1.05.tds-base/tinydns-data.c 2012-12-06 22:45:38.000000000 +0100 ++++ djbdns-1.05.tinydnssec/tinydns-data.c 2012-12-06 22:39:13.000000000 +0100 +@@ -436,7 +436,7 @@ + i = 0; + while (i < f[1].len) { + k = f[1].len - i; +- if (k > 127) k = 127; ++ if (k > 255) k = 255; + ch = k; + rr_add(&ch,1); + rr_add(f[1].s + i,k); +diff -rNU3 djbdns-1.05.tds-base/tinydns-get.c djbdns-1.05.tinydnssec/tinydns-get.c +--- djbdns-1.05.tds-base/tinydns-get.c 2001-02-11 22:11:45.000000000 +0100 ++++ djbdns-1.05.tinydnssec/tinydns-get.c 2012-12-06 22:39:13.000000000 +0100 +@@ -19,7 +19,7 @@ + + void usage(void) + { +- strerr_die1x(100,"tinydns-get: usage: tinydns-get type name [ip]"); ++ strerr_die1x(100,"tinydns-get: usage: tinydns-get [-s | -S] type name [ip]"); + } + void oops(void) + { +@@ -39,6 +39,14 @@ + if (!*argv) usage(); + + if (!*++argv) usage(); ++ ++ max_response_len = 512; ++ if ((*argv)[0] == '-') { ++ if ((*argv)[1] != 's' && (*argv)[1] != 'S' || (*argv)[2]) usage(); ++ do_dnssec = 1; ++ max_response_len = (*argv)[1] == 's' ? 1220 : 4000; ++ if (!*++argv) usage(); ++ } + if (!parsetype(*argv,type)) usage(); + + if (!*++argv) usage(); -- cgit v1.2.3