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 --- INSTALL.tinydnssec | 45 ++ README.tinydnssec | 132 ++++ TODO.tinydnssec | 13 + djbdns-1.05-dnssec.patch | 1749 ++++++++++++++++++++++++++++++++++++++++++++++ gpl-3.0.txt | 674 ++++++++++++++++++ run-tests.sh | 104 +++ test/a-01 | 16 + test/a-02 | 9 + test/a-03 | 11 + test/a-04 | 7 + test/a-05 | 7 + test/a-06 | 9 + test/a-07 | 18 + test/a-08 | 11 + test/a-09 | 7 + test/a-10 | 9 + test/a-11 | 6 + test/a-12 | 3 + test/a-13 | 3 + test/a-14 | 3 + test/a-15 | 9 + test/a-16 | 3 + test/a-17 | 3 + test/a-18 | 3 + test/a-19 | 4 + test/a-20 | 4 + test/a-21 | 7 + test/a-22 | 7 + test/a-23 | 4 + test/a-24 | 6 + test/a-25 | 9 + test/a-26 | 9 + test/a-27 | 12 + test/a-28 | 7 + test/a-29 | 12 + test/a-30 | 3 + test/a-31 | 4 + test/a-32 | 3 + test/a-33 | 4 + test/a-34 | 9 + test/a-35 | 10 + test/a-36 | 3 + test/a-37 | 3 + test/a-38 | 4 + test/a-39 | 5 + test/data | 65 ++ test/example.ksk | 53 ++ test/example.zsk | 17 + test/q-01 | 2 + test/q-02 | 2 + test/q-03 | 2 + test/q-04 | 2 + test/q-05 | 2 + test/q-06 | 2 + test/q-07 | 2 + test/q-08 | 2 + test/q-09 | 2 + test/q-10 | 1 + test/q-11 | 1 + test/q-12 | 1 + test/q-13 | 1 + test/q-14 | 1 + test/q-15 | 1 + test/q-16 | 1 + test/q-17 | 1 + test/q-18 | 1 + test/q-19 | 1 + test/q-20 | 1 + test/q-21 | 1 + test/q-22 | 1 + test/q-23 | 1 + test/q-24 | 1 + test/q-25 | 1 + test/q-26 | 1 + test/q-27 | 1 + test/q-28 | 1 + test/q-29 | 1 + test/q-30 | 1 + test/q-31 | 1 + test/q-32 | 1 + test/q-33 | 1 + test/q-34 | 1 + test/q-35 | 1 + test/q-36 | 1 + test/q-37 | 1 + test/q-38 | 1 + test/q-39 | 1 + tinydns-sign.pl | 1025 +++++++++++++++++++++++++++ 88 files changed, 4191 insertions(+) create mode 100644 INSTALL.tinydnssec create mode 100644 README.tinydnssec create mode 100644 TODO.tinydnssec create mode 100644 djbdns-1.05-dnssec.patch create mode 100644 gpl-3.0.txt create mode 100755 run-tests.sh create mode 100644 test/a-01 create mode 100644 test/a-02 create mode 100644 test/a-03 create mode 100644 test/a-04 create mode 100644 test/a-05 create mode 100644 test/a-06 create mode 100644 test/a-07 create mode 100644 test/a-08 create mode 100644 test/a-09 create mode 100644 test/a-10 create mode 100644 test/a-11 create mode 100644 test/a-12 create mode 100644 test/a-13 create mode 100644 test/a-14 create mode 100644 test/a-15 create mode 100644 test/a-16 create mode 100644 test/a-17 create mode 100644 test/a-18 create mode 100644 test/a-19 create mode 100644 test/a-20 create mode 100644 test/a-21 create mode 100644 test/a-22 create mode 100644 test/a-23 create mode 100644 test/a-24 create mode 100644 test/a-25 create mode 100644 test/a-26 create mode 100644 test/a-27 create mode 100644 test/a-28 create mode 100644 test/a-29 create mode 100644 test/a-30 create mode 100644 test/a-31 create mode 100644 test/a-32 create mode 100644 test/a-33 create mode 100644 test/a-34 create mode 100644 test/a-35 create mode 100644 test/a-36 create mode 100644 test/a-37 create mode 100644 test/a-38 create mode 100644 test/a-39 create mode 100644 test/data create mode 100644 test/example.ksk create mode 100644 test/example.zsk create mode 100644 test/q-01 create mode 100644 test/q-02 create mode 100644 test/q-03 create mode 100644 test/q-04 create mode 100644 test/q-05 create mode 100644 test/q-06 create mode 100644 test/q-07 create mode 100644 test/q-08 create mode 100644 test/q-09 create mode 100644 test/q-10 create mode 100644 test/q-11 create mode 100644 test/q-12 create mode 100644 test/q-13 create mode 100644 test/q-14 create mode 100644 test/q-15 create mode 100644 test/q-16 create mode 100644 test/q-17 create mode 100644 test/q-18 create mode 100644 test/q-19 create mode 100644 test/q-20 create mode 100644 test/q-21 create mode 100644 test/q-22 create mode 100644 test/q-23 create mode 100644 test/q-24 create mode 100644 test/q-25 create mode 100644 test/q-26 create mode 100644 test/q-27 create mode 100644 test/q-28 create mode 100644 test/q-29 create mode 100644 test/q-30 create mode 100644 test/q-31 create mode 100644 test/q-32 create mode 100644 test/q-33 create mode 100644 test/q-34 create mode 100644 test/q-35 create mode 100644 test/q-36 create mode 100644 test/q-37 create mode 100644 test/q-38 create mode 100644 test/q-39 create mode 100755 tinydns-sign.pl diff --git a/INSTALL.tinydnssec b/INSTALL.tinydnssec new file mode 100644 index 0000000..677d774 --- /dev/null +++ b/INSTALL.tinydnssec @@ -0,0 +1,45 @@ +Installation of the tinydnssec patch +==================================== + +Requirements +------------ + +This patch is *not* against stock djbdns. Here's the minimal set of patches +to install before the tinydnssec patch applies: + +1. http://www.fefe.de/dns/djbdns-1.05-test25.diff.bz2 + Unfortunately, fefe refuses to name a license for this patch, which means + that I cannot redistribute it. + +2. My own fixes to the Makefile (IPv6-related): djbdns-ipv6-make.patch + +Build +----- + +1. Download and unpack the original djbdns sources from + http://cr.yp.to/djbdns/install.html . +2. Download and apply the patches listed above. +3. Download and unpack http://tinydnssec.org/tinydnssec-1.05-1.tar.gz in + the top-level source directory. +4. Apply djbdns-1.05-dnssec.patch. +5. Install as per usual instructions (see http://cr.yp.to/djbdns/install.html ). +6. Optional: run tests (see below). +7. Install djbdns as per original instructions, or whatever your preferred + method is. +8. Install tinydns-sign.pl in your preferred location for system + executables, like e. g. /usr/sbin . +9. Optional: create a manpage for tinydns-sign using e. g. + pod2man -s 8 -c '' "tinydns-sign.pl" >tinydns-sign.8 + then install it in your preferred location for system manpages. + + +Test +---- + +run-tests.sh will sign test/data using keys from test/example*, then issue +some queries using tinydns-get, i. e. without any networking involved. + +As root, start tinydns / axfrdns on a local address (127.0.0.3), then execute +SERVER=127.0.0.3 run-tests.sh -t -u +to test the same queries via tcp and udp. + diff --git a/README.tinydnssec b/README.tinydnssec new file mode 100644 index 0000000..bf15c76 --- /dev/null +++ b/README.tinydnssec @@ -0,0 +1,132 @@ +DNSSEC for tinydns +================== + +This project adds DNSSEC support to D. J. Bernstein's tinydns (see +http://cr.yp.to/djbdns.html ). + +It consists of two parts (mostly): + +- tinydns-sign, a perl script for augmenting a tinydns-data file with + DNSSEC-related RRs, and + +- a patch to tinydns / axfrdns to make them produce DNSSEC-authenticated + answers. + +The patch tries to preserve the behaviour of tinydns/axfrdns wrt non-DNSSEC +queries, with these noteworthy exceptions: + +- The interpretation of wildcard records now matches the description in + RFC-1034 section 4.3.3. Specifically, if there's a wildcard *.x and a + record for a.x, then a query for y.a.x will *not* be answered using the + wildcard (for a label 'a' and series of labels 'x' and 'y'). + This change is required for signed domains, because authentication of + negative responses requires a common understanding between client and + server about the meaning of wildcards. + +- EDNS0 in queries will be honoured also for non-DNSSEC queries, i. e. + tinydns may produce answers exceeding 512 bytes. (There is a hard + limit of 4000 bytes, though.) + This *can* lead to problems on IPv6 networks. + +- TXT records are split into character-strings of 255 bytes, not 127. + This is not really a DNSSEC-related change, but this is kind of a FAQ [5] and + tinydns-data and tinydns-sign must agree on how this is handled or the + generated RRSIG won't match. + +- The patch includes a fix for the broken CNAME handling in tinydns. See [6] + for a description of the problem. The patch referenced by that description + conflicts with fefe's IPv6 patch and requires further modifications for + DNSSEC, so I decided to roll my own solution. + +Be careful with publishing signed zones as a secondary nameserver: the +modified tinydns/axfrdns require certain helper RRs in the database to +simplify locating NSEC3 records. Without these helpers, tinydns cannot +generate valid negative response nor valid wildcard responses. + +Axfrdns *will* publish these helper RRs, other primaries will most +likely *not*. + + +HOWTO +----- + +0. Install tinydns-sign and patched tinydns/axfrdns. + +1. Generate key(s). See the tinydns-sign manpage for details. + + It is common practice to have a "Key signing key" (KSK, with flags=257) + and a "Zone signing key" (ZSK, with flags=256). The KSK is used only for + signing the DNSKEY RRs, the ZSK is used for signing the rest. The KSK is + more difficult to change because it is used in the delegating domain's + referral, therefore it usually has more bits. The ZSK is used for signing + all the other records, and is therefore usually shorter and changed more + frequently. + + You should keep the keys in a safe place (outside the tinydns ROOT), e. g. + in a directory "keys" located above the ROOT. + +2. Add the K pseudo records from the key files to your tinydns-data file. + Also, add a P pseudo record for each signed zone. + +3. Adapt the Makefile to pipe your data file through tinydns-sign before + before running tinydns-data, e. g. + +data.cdb: data update + tinydns-sign ../keys/* data.tmp + mv data.tmp data + tinydns-data + rm -f update + +update: + touch update + +4. Run make. + +5. Set up a cronjob to periodically re-sign your data file before the + signatures expire. + +6. TEST! For example: + + * Use dig axfr @ and validate the result with a dnssec zone + validator, like yazvs [1]. + + * Use an online DNS or DNSSEC test tool. See [2] for a list. + +7. Read RFC-4641 [3] to get a feeling for what is explicitly not called + "Best Current Practices". :-) + + In particular, think about key lifetime and how to do a key rollover. + +8. Sacrifice a few small animals to a deity of your choice. Get yourself a + drink for really tough guys, like prune juice [4]. + +9. If you feel brave, contact your upstream delegator to publish DS records + for your zone. + + Note that this is a really good way to cut yourself off from the rest of the + internet. You've been warned, so don't blame me. + +LICENSE +------- + +(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 . + + +[1] http://yazvs.verisignlabs.com/ . +[2] http://www.bortzmeyer.org/tests-dns.html +[3] http://tools.ietf.org/html/rfc4641 +[4] http://en.memory-alpha.org/wiki/Prune_juice +[5] http://marc.info/?l=djbdns&m=120848817816960&w=2 +[6] http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/djbdns-problems.html#tinydns-alias-chain-truncation diff --git a/TODO.tinydnssec b/TODO.tinydnssec new file mode 100644 index 0000000..70fe34e --- /dev/null +++ b/TODO.tinydnssec @@ -0,0 +1,13 @@ + +* Make hardcoded limit for EDNS0 response size configurable (environment). + +* Add support for locations + timestamps to tinydns-sign (basically, treat + them as separate zones, with timestamp-dependend SOA serials). + +* Add support for ((semi-)automatic) ZSK rollover using pre-publish method. + +* Refactor tinydns-sign: + - separate generation of helper records + - put some functionality into modules + - make (better) use of existing Net::DNS modules + 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(); diff --git a/gpl-3.0.txt b/gpl-3.0.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/gpl-3.0.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/run-tests.sh b/run-tests.sh new file mode 100755 index 0000000..14d2c88 --- /dev/null +++ b/run-tests.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +# (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 . + +./tinydns-sign.pl test/example.?sk data +./tinydns-data + +for i in test/q-*; do + id="${i#test/q}" + echo -n "$i ... " + read sec type name <"$i" + ./tinydns-get "$sec" "$type" $name | tail +2 >test/"o$id" + sed -s 's/\b[0-9]\{10\}\b/