diff options
Diffstat (limited to 'testcode')
-rwxr-xr-x | testcode/do-tests.sh | 2 | ||||
-rw-r--r-- | testcode/fake_event.c | 7 | ||||
-rw-r--r-- | testcode/testbound.c | 22 | ||||
-rw-r--r-- | testcode/testpkts.c | 306 | ||||
-rw-r--r-- | testcode/testpkts.h | 22 | ||||
-rw-r--r-- | testcode/unitecs.c | 284 | ||||
-rw-r--r-- | testcode/unitmain.c | 267 | ||||
-rw-r--r-- | testcode/unitmain.h | 4 | ||||
-rw-r--r-- | testcode/unitverify.c | 12 |
9 files changed, 905 insertions, 21 deletions
diff --git a/testcode/do-tests.sh b/testcode/do-tests.sh index 6ea12cd2f3367..e356d4fc312ca 100755 --- a/testcode/do-tests.sh +++ b/testcode/do-tests.sh @@ -9,6 +9,7 @@ NEED_CURL='06-ianaports.tpkg root_anchor.tpkg' NEED_WHOAMI='07-confroot.tpkg' NEED_IPV6='fwd_ancil.tpkg fwd_tcp_tc6.tpkg stub_udp6.tpkg edns_cache.tpkg' NEED_NOMINGW='tcp_sigpipe.tpkg 07-confroot.tpkg 08-host-lib.tpkg fwd_ancil.tpkg' +NEED_DNSCRYPT_PROXY='dnscrypt_queries.tpkg' # test if dig and ldns-testns are available. test_tool_avail "dig" @@ -39,6 +40,7 @@ for test in `ls *.tpkg`; do skip_if_in_list $test "$NEED_XXD" "xxd" skip_if_in_list $test "$NEED_NC" "nc" skip_if_in_list $test "$NEED_WHOAMI" "whoami" + skip_if_in_list $test "$NEED_DNSCRYPT_PROXY" "dnscrypt-proxy" if echo $NEED_IPV6 | grep $test >/dev/null; then if test "$HAVE_IPV6" = no; then diff --git a/testcode/fake_event.c b/testcode/fake_event.c index 2072089381f7f..154013a8c8e3c 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -1070,8 +1070,13 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, sldns_buffer_write_u16(pend->buffer, qinfo->qclass); sldns_buffer_flip(pend->buffer); if(1) { - /* add edns */ struct edns_data edns; + if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen, + zone, zonelen, qstate, qstate->region)) { + free(pend); + return NULL; + } + /* add edns */ edns.edns_present = 1; edns.ext_rcode = 0; edns.edns_version = EDNS_ADVERTISED_VERSION; diff --git a/testcode/testbound.c b/testcode/testbound.c index 00502eea88497..180b2c256a49f 100644 --- a/testcode/testbound.c +++ b/testcode/testbound.c @@ -73,9 +73,11 @@ testbound_usage(void) printf("\ttest the unbound daemon.\n"); printf("-h this help\n"); printf("-p file playback text file\n"); + printf("-1 detect SHA1 support (exit code 0 or 1)\n"); printf("-2 detect SHA256 support (exit code 0 or 1)\n"); printf("-g detect GOST support (exit code 0 or 1)\n"); printf("-e detect ECDSA support (exit code 0 or 1)\n"); + printf("-c detect CLIENT_SUBNET support (exit code 0 or 1)\n"); printf("-s testbound self-test - unit test of testbound parts.\n"); printf("-o str unbound commandline options separated by spaces.\n"); printf("Version %s\n", PACKAGE_VERSION); @@ -279,12 +281,21 @@ main(int argc, char* argv[]) pass_argc = 1; pass_argv[0] = "unbound"; add_opts("-d", &pass_argc, pass_argv); - while( (c=getopt(argc, argv, "2egho:p:s")) != -1) { + while( (c=getopt(argc, argv, "12egho:p:s")) != -1) { switch(c) { case 's': free(pass_argv[1]); testbound_selftest(); exit(0); + case '1': +#ifdef USE_SHA1 + printf("SHA1 supported\n"); + exit(0); +#else + printf("SHA1 not supported\n"); + exit(1); +#endif + break; case '2': #if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2) printf("SHA256 supported\n"); @@ -317,6 +328,15 @@ main(int argc, char* argv[]) exit(1); #endif break; + case 'c': +#ifdef CLIENT_SUBNET + printf("CLIENT_SUBNET supported\n"); + exit(0); +#else + printf("CLIENT_SUBNET not supported\n"); + exit(1); +#endif + break; case 'p': playback_file = optarg; break; diff --git a/testcode/testpkts.c b/testcode/testpkts.c index c9ad9d069b568..e1a7768abed0a 100644 --- a/testcode/testpkts.c +++ b/testcode/testpkts.c @@ -98,6 +98,7 @@ entry_add_reply(struct entry* entry) pkt->packet_sleep = 0; pkt->reply_pkt = NULL; pkt->reply_from_hex = NULL; + pkt->raw_ednsdata = NULL; /* link at end */ while(*p) p = &((*p)->next); @@ -118,6 +119,12 @@ static void matchline(char* line, struct entry* e) e->match_qtype = 1; } else if(str_keyword(&parse, "qname")) { e->match_qname = 1; + } else if(str_keyword(&parse, "rcode")) { + e->match_rcode = 1; + } else if(str_keyword(&parse, "question")) { + e->match_question = 1; + } else if(str_keyword(&parse, "answer")) { + e->match_answer = 1; } else if(str_keyword(&parse, "subdomain")) { e->match_subdomain = 1; } else if(str_keyword(&parse, "all")) { @@ -128,6 +135,8 @@ static void matchline(char* line, struct entry* e) e->match_do = 1; } else if(str_keyword(&parse, "noedns")) { e->match_noedns = 1; + } else if(str_keyword(&parse, "ednsdata")) { + e->match_ednsdata_raw = 1; } else if(str_keyword(&parse, "UDP")) { e->match_transport = transport_udp; } else if(str_keyword(&parse, "TCP")) { @@ -224,6 +233,8 @@ static void adjustline(char* line, struct entry* e, e->copy_id = 1; } else if(str_keyword(&parse, "copy_query")) { e->copy_query = 1; + } else if(str_keyword(&parse, "copy_ednsdata_assume_clientsubnet")) { + e->copy_ednsdata_assume_clientsubnet = 1; } else if(str_keyword(&parse, "sleep=")) { e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10); while(isspace((unsigned char)*parse)) @@ -247,6 +258,9 @@ static struct entry* new_entry(void) e->match_opcode = 0; e->match_qtype = 0; e->match_qname = 0; + e->match_rcode = 0; + e->match_question = 0; + e->match_answer = 0; e->match_subdomain = 0; e->match_all = 0; e->match_ttl = 0; @@ -258,6 +272,7 @@ static struct entry* new_entry(void) e->reply_list = NULL; e->copy_id = 0; e->copy_query = 0; + e->copy_ednsdata_assume_clientsubnet = 0; e->sleeptime = 0; e->next = NULL; return e; @@ -475,25 +490,28 @@ static void add_rr(char* rrstr, uint8_t* pktbuf, size_t pktsize, else error("internal error bad section %d", (int)add_section); } -/* add EDNS 4096 DO opt record */ +/* add EDNS 4096 opt record */ static void -add_do_flag(uint8_t* pktbuf, size_t pktsize, size_t* pktlen) +add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, uint8_t *ednsdata, + uint16_t ednslen, size_t* pktlen) { uint8_t edns[] = {0x00, /* root label */ 0x00, LDNS_RR_TYPE_OPT, /* type */ 0x10, 0x00, /* class is UDPSIZE 4096 */ 0x00, /* TTL[0] is ext rcode */ 0x00, /* TTL[1] is edns version */ - 0x80, 0x00, /* TTL[2-3] is edns flags, DO */ - 0x00, 0x00 /* rdatalength (0 options) */ + (uint8_t)(do_flag?0x80:0x00), 0x00, /* TTL[2-3] is edns flags, DO */ + (uint8_t)((ednslen >> 8) & 0xff), + (uint8_t)(ednslen & 0xff), /* rdatalength */ }; if(*pktlen < LDNS_HEADER_SIZE) return; - if(*pktlen + sizeof(edns) > pktsize) + if(*pktlen + sizeof(edns) + ednslen > pktsize) error("not enough space for EDNS OPT record"); memmove(pktbuf+*pktlen, edns, sizeof(edns)); + memmove(pktbuf+*pktlen+sizeof(edns), ednsdata, ednslen); sldns_write_uint16(pktbuf+10, LDNS_ARCOUNT(pktbuf)+1); - *pktlen += sizeof(edns); + *pktlen += (sizeof(edns) + ednslen); } /* Reads one entry from file. Returns entry or NULL on error. */ @@ -507,7 +525,9 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate, sldns_pkt_section add_section = LDNS_SECTION_QUESTION; struct reply_packet *cur_reply = NULL; int reading_hex = 0; + int reading_hex_ednsdata = 0; sldns_buffer* hex_data_buffer = NULL; + sldns_buffer* hex_ednsdata_buffer = NULL; uint8_t pktbuf[MAX_PACKETLEN]; size_t pktlen = LDNS_HEADER_SIZE; int do_flag = 0; /* DO flag in EDNS */ @@ -574,21 +594,45 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate, cur_reply->reply_from_hex = hex_buffer2wire(hex_data_buffer); sldns_buffer_free(hex_data_buffer); hex_data_buffer = NULL; + } else if(reading_hex) { + sldns_buffer_printf(hex_data_buffer, "%s", line); + } else if(str_keyword(&parse, "HEX_EDNSDATA_BEGIN")) { + hex_ednsdata_buffer = sldns_buffer_new(MAX_PACKETLEN); + reading_hex_ednsdata = 1; + } else if(str_keyword(&parse, "HEX_EDNSDATA_END")) { + if (!reading_hex_ednsdata) { + error("%s line %d: HEX_EDNSDATA_END read but no" + "HEX_EDNSDATA_BEGIN keyword seen", name, pstate->lineno); + } + reading_hex_ednsdata = 0; + cur_reply->raw_ednsdata = hex_buffer2wire(hex_ednsdata_buffer); + sldns_buffer_free(hex_ednsdata_buffer); + hex_ednsdata_buffer = NULL; + } else if(reading_hex_ednsdata) { + sldns_buffer_printf(hex_ednsdata_buffer, "%s", line); } else if(str_keyword(&parse, "ENTRY_END")) { if(hex_data_buffer) sldns_buffer_free(hex_data_buffer); + if(hex_ednsdata_buffer) + sldns_buffer_free(hex_ednsdata_buffer); if(pktlen != 0) { - if(do_flag) - add_do_flag(pktbuf, sizeof(pktbuf), - &pktlen); + if(do_flag || cur_reply->raw_ednsdata) { + if(cur_reply->raw_ednsdata && + sldns_buffer_limit(cur_reply->raw_ednsdata)) + add_edns(pktbuf, sizeof(pktbuf), do_flag, + sldns_buffer_begin(cur_reply->raw_ednsdata), + (uint16_t)sldns_buffer_limit(cur_reply->raw_ednsdata), + &pktlen); + else + add_edns(pktbuf, sizeof(pktbuf), do_flag, + NULL, 0, &pktlen); + } cur_reply->reply_pkt = memdup(pktbuf, pktlen); cur_reply->reply_len = pktlen; if(!cur_reply->reply_pkt) error("out of memory"); } return current; - } else if(reading_hex) { - sldns_buffer_printf(hex_data_buffer, "%s", line); } else { add_rr(skip_whitespace?parse:line, pktbuf, sizeof(pktbuf), &pktlen, pstate, add_section, @@ -596,10 +640,14 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate, } } - if (reading_hex) { + if(reading_hex) { error("%s: End of file reached while still reading hex, " "missing HEX_ANSWER_END\n", name); } + if(reading_hex_ednsdata) { + error("%s: End of file reached while still reading edns data, " + "missing HEX_EDNSDATA_END\n", name); + } if(current) { error("%s: End of file reached while reading entry. " "missing ENTRY_END\n", name); @@ -691,6 +739,14 @@ static int get_opcode(uint8_t* pkt, size_t pktlen) return (int)LDNS_OPCODE_WIRE(pkt); } +/** returns rcode from packet */ +static int get_rcode(uint8_t* pkt, size_t pktlen) +{ + if(pktlen < LDNS_HEADER_SIZE) + return 0; + return (int)LDNS_RCODE_WIRE(pkt); +} + /** get authority section SOA serial value */ static uint32_t get_serial(uint8_t* p, size_t plen) { @@ -761,16 +817,16 @@ pkt_find_edns_opt(uint8_t** p, size_t* plen) wlen -= LDNS_HEADER_SIZE; /* skip other records with wire2str_scan */ - for(i=0; i < LDNS_QDCOUNT(p); i++) + for(i=0; i < LDNS_QDCOUNT(*p); i++) (void)sldns_wire2str_rrquestion_scan(&w, &wlen, &snull, &sl, *p, *plen); - for(i=0; i < LDNS_ANCOUNT(p); i++) + for(i=0; i < LDNS_ANCOUNT(*p); i++) (void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen); - for(i=0; i < LDNS_NSCOUNT(p); i++) + for(i=0; i < LDNS_NSCOUNT(*p); i++) (void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen); /* walk through additional section */ - for(i=0; i < LDNS_ARCOUNT(p); i++) { + for(i=0; i < LDNS_ARCOUNT(*p); i++) { /* if this is OPT then done */ uint8_t* dstart = w; size_t dlen = wlen; @@ -802,8 +858,8 @@ get_do_flag(uint8_t* pkt, size_t len) uint16_t edns_bits; uint8_t* walk = pkt; size_t walk_len = len; - if(pkt_find_edns_opt(&walk, &walk_len)) { - return 1; + if(!pkt_find_edns_opt(&walk, &walk_len)) { + return 0; } if(walk_len < 6) return 0; /* malformed */ @@ -1086,6 +1142,138 @@ static void lowercase_pkt(uint8_t* pkt, size_t pktlen) } } +/** match question section of packet */ +static int +match_question(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl) +{ + char* qstr, *pstr, *s, *qcmpstr, *pcmpstr; + uint8_t* qb = q, *pb = p; + int r; + /* zero TTLs */ + qb = memdup(q, qlen); + pb = memdup(p, plen); + if(!qb || !pb) error("out of memory"); + if(!mttl) { + zerottls(qb, qlen); + zerottls(pb, plen); + } + lowercase_pkt(qb, qlen); + lowercase_pkt(pb, plen); + qstr = sldns_wire2str_pkt(qb, qlen); + pstr = sldns_wire2str_pkt(pb, plen); + if(!qstr || !pstr) error("cannot pkt2string"); + + /* remove before ;; QUESTION */ + s = strstr(qstr, ";; QUESTION SECTION"); + qcmpstr = s; + s = strstr(pstr, ";; QUESTION SECTION"); + pcmpstr = s; + if(!qcmpstr && !pcmpstr) { + free(qstr); + free(pstr); + free(qb); + free(pb); + return 1; + } + if(!qcmpstr || !pcmpstr) { + free(qstr); + free(pstr); + free(qb); + free(pb); + return 0; + } + + /* remove after answer section, (;; AUTH, ;; ADD, ;; MSG size ..) */ + s = strstr(qcmpstr, ";; ANSWER SECTION"); + if(!s) s = strstr(qcmpstr, ";; AUTHORITY SECTION"); + if(!s) s = strstr(qcmpstr, ";; ADDITIONAL SECTION"); + if(!s) s = strstr(qcmpstr, ";; MSG SIZE"); + if(s) *s = 0; + s = strstr(pcmpstr, ";; ANSWER SECTION"); + if(!s) s = strstr(pcmpstr, ";; AUTHORITY SECTION"); + if(!s) s = strstr(pcmpstr, ";; ADDITIONAL SECTION"); + if(!s) s = strstr(pcmpstr, ";; MSG SIZE"); + if(s) *s = 0; + + r = (strcmp(qcmpstr, pcmpstr) == 0); + + if(!r) { + verbose(3, "mismatch question section '%s' and '%s'", + qcmpstr, pcmpstr); + } + + free(qstr); + free(pstr); + free(qb); + free(pb); + return r; +} + +/** match answer section of packet */ +static int +match_answer(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl) +{ + char* qstr, *pstr, *s, *qcmpstr, *pcmpstr; + uint8_t* qb = q, *pb = p; + int r; + /* zero TTLs */ + qb = memdup(q, qlen); + pb = memdup(p, plen); + if(!qb || !pb) error("out of memory"); + if(!mttl) { + zerottls(qb, qlen); + zerottls(pb, plen); + } + lowercase_pkt(qb, qlen); + lowercase_pkt(pb, plen); + qstr = sldns_wire2str_pkt(qb, qlen); + pstr = sldns_wire2str_pkt(pb, plen); + if(!qstr || !pstr) error("cannot pkt2string"); + + /* remove before ;; ANSWER */ + s = strstr(qstr, ";; ANSWER SECTION"); + qcmpstr = s; + s = strstr(pstr, ";; ANSWER SECTION"); + pcmpstr = s; + if(!qcmpstr && !pcmpstr) { + free(qstr); + free(pstr); + free(qb); + free(pb); + return 1; + } + if(!qcmpstr || !pcmpstr) { + free(qstr); + free(pstr); + free(qb); + free(pb); + return 0; + } + + /* remove after answer section, (;; AUTH, ;; ADD, ;; MSG size ..) */ + s = strstr(qcmpstr, ";; AUTHORITY SECTION"); + if(!s) s = strstr(qcmpstr, ";; ADDITIONAL SECTION"); + if(!s) s = strstr(qcmpstr, ";; MSG SIZE"); + if(s) *s = 0; + s = strstr(pcmpstr, ";; AUTHORITY SECTION"); + if(!s) s = strstr(pcmpstr, ";; ADDITIONAL SECTION"); + if(!s) s = strstr(pcmpstr, ";; MSG SIZE"); + if(s) *s = 0; + + r = (strcmp(qcmpstr, pcmpstr) == 0); + + if(!r) { + verbose(3, "mismatch answer section '%s' and '%s'", + qcmpstr, pcmpstr); + } + + free(qstr); + free(pstr); + free(qb); + free(pb); + return r; +} + /** match all of the packet */ int match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl, @@ -1128,6 +1316,9 @@ match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl, /* check for reordered sections */ r = match_noloc(qstr, pstr, q, qlen, p, plen); } + if(!r) { + verbose(3, "mismatch pkt '%s' and '%s'", qstr, pstr); + } free(qstr); free(pstr); free(qb); @@ -1186,6 +1377,31 @@ static int subdomain_dname(uint8_t* q, size_t qlen, uint8_t* p, size_t plen) return 0; } +/** Match OPT RDATA (not the EDNS payload size or flags) */ +static int +match_ednsdata(uint8_t* q, size_t qlen, uint8_t* p, size_t plen) +{ + uint8_t* walk_q = q; + size_t walk_qlen = qlen; + uint8_t* walk_p = p; + size_t walk_plen = plen; + + if(!pkt_find_edns_opt(&walk_q, &walk_qlen)) + walk_qlen = 0; + if(!pkt_find_edns_opt(&walk_p, &walk_plen)) + walk_plen = 0; + + /* class + ttl + rdlen = 8 */ + if(walk_qlen <= 8 && walk_plen <= 8) { + verbose(3, "NO edns opt, move on"); + return 1; + } + if(walk_qlen != walk_plen) + return 0; + + return (memcmp(walk_p+8, walk_q+8, walk_qlen-8) == 0); +} + /* finds entry in list, or returns NULL */ struct entry* find_match(struct entry* entries, uint8_t* query_pkt, size_t len, @@ -1214,6 +1430,31 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len, continue; } } + if(p->match_rcode) { + if(get_rcode(query_pkt, len) != get_rcode(reply, rlen)) { + char *r1 = sldns_wire2str_rcode(get_rcode(query_pkt, len)); + char *r2 = sldns_wire2str_rcode(get_rcode(reply, rlen)); + verbose(3, "bad rcode %s instead of %s\n", + r1, r2); + free(r1); + free(r2); + continue; + } + } + if(p->match_question) { + if(!match_question(query_pkt, len, reply, rlen, + (int)p->match_ttl)) { + verbose(3, "bad question section\n"); + continue; + } + } + if(p->match_answer) { + if(!match_answer(query_pkt, len, reply, rlen, + (int)p->match_ttl)) { + verbose(3, "bad answer section\n"); + continue; + } + } if(p->match_subdomain) { if(!subdomain_dname(query_pkt, len, reply, rlen)) { verbose(3, "bad subdomain\n"); @@ -1232,6 +1473,11 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len, verbose(3, "bad; EDNS OPT present\n"); continue; } + if(p->match_ednsdata_raw && + !match_ednsdata(query_pkt, len, reply, rlen)) { + verbose(3, "bad EDNS data match.\n"); + continue; + } if(p->match_transport != transport_any && p->match_transport != transport) { verbose(3, "bad transport\n"); continue; @@ -1317,6 +1563,29 @@ adjust_packet(struct entry* match, uint8_t** answer_pkt, size_t *answer_len, if(match->copy_id && reslen >= 1) res[0] = orig[0]; + if(match->copy_ednsdata_assume_clientsubnet) { + /** Assume there is only one EDNS option, which is ECS. + * Copy source mask from query to scope mask in reply. Assume + * rest of ECS data in response (eg address) matches the query. + */ + uint8_t* walk_q = orig; + size_t walk_qlen = origlen; + uint8_t* walk_p = res; + size_t walk_plen = reslen; + + if(!pkt_find_edns_opt(&walk_q, &walk_qlen)) { + walk_qlen = 0; + } + if(!pkt_find_edns_opt(&walk_p, &walk_plen)) { + walk_plen = 0; + } + /* class + ttl + rdlen + optcode + optlen + ecs fam + ecs source + * + ecs scope = index 15 */ + if(walk_qlen >= 15 && walk_plen >= 15) { + walk_p[15] = walk_q[14]; + } + } + if(match->sleeptime > 0) { verbose(3, "sleeping for %d seconds\n", match->sleeptime); #ifdef HAVE_SLEEP @@ -1410,6 +1679,7 @@ void delete_replylist(struct reply_packet* replist) np = p->next; free(p->reply_pkt); sldns_buffer_free(p->reply_from_hex); + sldns_buffer_free(p->raw_ednsdata); free(p); p=np; } diff --git a/testcode/testpkts.h b/testcode/testpkts.h index 5c000546fed67..b175cab066ab9 100644 --- a/testcode/testpkts.h +++ b/testcode/testpkts.h @@ -50,6 +50,10 @@ struct sldns_file_parse_state; ; 'ttl' used with all, rrs in packet must also have matching TTLs. ; 'DO' will match only queries with DO bit set. ; 'noedns' matches queries without EDNS OPT records. + ; 'rcode' makes the query match the rcode from the reply + ; 'question' makes the query match the question section + ; 'answer' makes the query match the answer section + ; 'ednsdata' matches queries to HEX_EDNS section. MATCH [opcode] [qtype] [qname] [serial=<value>] [all] [ttl] MATCH [UDP|TCP] DO MATCH ... @@ -84,6 +88,11 @@ struct sldns_file_parse_state; ; be parsed, ADJUST rules for the answer packet ; are ignored. Only copy_id is done. HEX_ANSWER_END + HEX_EDNS_BEGIN ; follow with hex data. + ; Raw EDNS data to match against. It must be an + ; exact match (all options are matched) and will be + ; evaluated only when 'MATCH ednsdata' given. + HEX_EDNS_END ENTRY_END @@ -144,6 +153,8 @@ struct reply_packet { uint8_t* reply_pkt; /** length of reply pkt */ size_t reply_len; + /** Additional EDNS data for matching queries. */ + struct sldns_buffer* raw_ednsdata; /** or reply pkt in hex if not parsable */ struct sldns_buffer* reply_from_hex; /** seconds to sleep before giving packet */ @@ -161,6 +172,12 @@ struct entry { uint8_t match_qtype; /** match qname with answer qname */ uint8_t match_qname; + /** match rcode with answer rcode */ + uint8_t match_rcode; + /** match question section */ + uint8_t match_question; + /** match answer section */ + uint8_t match_answer; /** match qname as subdomain of answer qname */ uint8_t match_subdomain; /** match SOA serial number, from auth section */ @@ -173,6 +190,8 @@ struct entry { uint8_t match_do; /** match absence of EDNS OPT record in query */ uint8_t match_noedns; + /** match edns data field given in hex */ + uint8_t match_ednsdata_raw; /** match query serial with this value. */ uint32_t ixfr_soa_serial; /** match on UDP/TCP */ @@ -186,6 +205,9 @@ struct entry { uint8_t copy_id; /** copy the query nametypeclass from query into the answer */ uint8_t copy_query; + /** copy ednsdata to reply, assume it is clientsubnet and + * adjust scopemask to match sourcemask */ + uint8_t copy_ednsdata_assume_clientsubnet; /** in seconds */ unsigned int sleeptime; diff --git a/testcode/unitecs.c b/testcode/unitecs.c new file mode 100644 index 0000000000000..3584b0f983b6f --- /dev/null +++ b/testcode/unitecs.c @@ -0,0 +1,284 @@ +/* + * testcode/unitecs.c - unit test for ecs routines. + * + * Copyright (c) 2013, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * \file + * Calls ecs related unit tests. Exits with code 1 on a failure. + */ + +#include "config.h" + +#ifdef CLIENT_SUBNET + +#include "util/log.h" +#include "util/module.h" +#include "testcode/unitmain.h" +#include "edns-subnet/addrtree.h" +#include "edns-subnet/subnetmod.h" + +/* + void printkey(addrkey_t *k, addrlen_t bits) + { + int byte; + int bytes = bits/8 + ((bits%8)>0); + char msk = 0xFF; + for (byte = 0; byte < bytes; byte++) { + //~ if (byte+1 == bytes) + //~ msk = 0xFF<<(8-bits%8); + printf("%02x ", k[byte]&msk); + } + } + + void print_tree(struct addrnode* node, int indent, int maxdepth) + { + struct addredge* edge; + int i, s, byte; + if (indent == 0) printf("-----Tree-----\n"); + if (indent > maxdepth) { + printf("\n"); + return; + } + printf("[node elem:%d] (%d)\n", node->elem != NULL, node); + for (i = 0; i<2; i++) { + if (node->edge[i]) { + for (s = 0; s < indent; s++) printf(" "); + printkey(node->edge[i]->str, node->edge[i]->len); + printf("(len %d bits, %d bytes) ", node->edge[i]->len, + node->edge[i]->len/8 + ((node->edge[i]->len%8)>0)); + print_tree(node->edge[i]->node, indent+1, maxdepth); + } + } + if (indent == 0) printf("-----Tree-----"); + } +*/ + +/* what should we check? + * X - is it balanced? (a node with 1 child shoudl not have + * a node with 1 child MUST have elem + * child must be sub of parent + * edge must be longer than parent edge + * */ +static int addrtree_inconsistent_subtree(struct addrtree* tree, + struct addredge* parent_edge, addrlen_t depth) +{ + struct addredge* edge; + struct addrnode* node = parent_edge->node; + int childcount, i, r; + if (depth > tree->max_depth) return 15; + childcount = (node->edge[0] != NULL) + (node->edge[1] != NULL); + /* Only nodes with 2 children should possibly have no element. */ + if (childcount < 2 && !node->elem) return 10; + for (i = 0; i<2; i++) { + edge = node->edge[i]; + if (!edge) continue; + if (!edge->node) return 11; + if (!edge->str) return 12; + if (edge->len <= parent_edge->len) return 13; + if (!unittest_wrapper_addrtree_issub(parent_edge->str, + parent_edge->len, edge->str, edge->len, 0)) + return 14; + if ((r = addrtree_inconsistent_subtree(tree, edge, depth+1)) != 0) + return 100+r; + } + return 0; +} + +static int addrtree_inconsistent(struct addrtree* tree) +{ + struct addredge* edge; + int i, r; + + if (!tree) return 0; + if (!tree->root) return 1; + + for (i = 0; i<2; i++) { + edge = tree->root->edge[i]; + if (!edge) continue; + if (!edge->node) return 3; + if (!edge->str) return 4; + if ((r = addrtree_inconsistent_subtree(tree, edge, 1)) != 0) + return r; + } + return 0; +} + +static addrlen_t randomkey(addrkey_t **k, int maxlen) +{ + int byte; + int bits = rand() % maxlen; + int bytes = bits/8 + (bits%8>0); /*ceil*/ + *k = (addrkey_t *) malloc(bytes * sizeof(addrkey_t)); + for (byte = 0; byte < bytes; byte++) { + (*k)[byte] = (addrkey_t)(rand() & 0xFF); + } + return (addrlen_t)bits; +} + +static void elemfree(void *envptr, void *elemptr) +{ + struct reply_info *elem = (struct reply_info *)elemptr; + (void)envptr; + free(elem); +} + +static void consistency_test(void) +{ + addrlen_t l; + time_t i; + unsigned int count; + addrkey_t *k; + struct addrtree* t; + struct module_env env; + struct reply_info *elem; + time_t timenow = 0; + unit_show_func("edns-subnet/addrtree.h", "Tree consistency check"); + srand(9195); /* just some value for reproducibility */ + + t = addrtree_create(100, &elemfree, &unittest_wrapper_subnetmod_sizefunc, &env, 0); + count = t->node_count; + unit_assert(count == 0); + for (i = 0; i < 1000; i++) { + l = randomkey(&k, 128); + elem = (struct reply_info *) calloc(1, sizeof(struct reply_info)); + addrtree_insert(t, k, l, 64, elem, timenow + 10, timenow); + /* This should always hold because no items ever expire. They + * could be overwritten, though. */ + unit_assert( count <= t->node_count ); + count = t->node_count; + free(k); + unit_assert( !addrtree_inconsistent(t) ); + } + addrtree_delete(t); + + unit_show_func("edns-subnet/addrtree.h", "Tree consistency with purge"); + t = addrtree_create(8, &elemfree, &unittest_wrapper_subnetmod_sizefunc, &env, 0); + unit_assert(t->node_count == 0); + for (i = 0; i < 1000; i++) { + l = randomkey(&k, 128); + elem = (struct reply_info *) calloc(1, sizeof(struct reply_info)); + addrtree_insert(t, k, l, 64, elem, i + 10, i); + free(k); + unit_assert( !addrtree_inconsistent(t) ); + } + addrtree_delete(t); + + unit_show_func("edns-subnet/addrtree.h", "Tree consistency with limit"); + t = addrtree_create(8, &elemfree, &unittest_wrapper_subnetmod_sizefunc, &env, 27); + unit_assert(t->node_count == 0); + for (i = 0; i < 1000; i++) { + l = randomkey(&k, 128); + elem = (struct reply_info *) calloc(1, sizeof(struct reply_info)); + addrtree_insert(t, k, l, 64, elem, i + 10, i); + unit_assert( t->node_count <= 27); + free(k); + unit_assert( !addrtree_inconsistent(t) ); + } + addrtree_delete(t); +} + +static void issub_test(void) +{ + addrkey_t k1[] = {0x55, 0x55, 0x5A}; + addrkey_t k2[] = {0x55, 0x5D, 0x5A}; + unit_show_func("edns-subnet/addrtree.h", "issub"); + unit_assert( !unittest_wrapper_addrtree_issub(k1, 24, k2, 24, 0) ); + unit_assert( unittest_wrapper_addrtree_issub(k1, 8, k2, 16, 0) ); + unit_assert( unittest_wrapper_addrtree_issub(k2, 12, k1, 13, 0) ); + unit_assert( !unittest_wrapper_addrtree_issub(k1, 16, k2, 12, 0) ); + unit_assert( unittest_wrapper_addrtree_issub(k1, 12, k2, 12, 0) ); + unit_assert( !unittest_wrapper_addrtree_issub(k1, 13, k2, 13, 0) ); + unit_assert( unittest_wrapper_addrtree_issub(k1, 24, k2, 24, 13) ); + unit_assert( !unittest_wrapper_addrtree_issub(k1, 24, k2, 20, 13) ); + unit_assert( unittest_wrapper_addrtree_issub(k1, 20, k2, 24, 13) ); +} + +static void getbit_test(void) +{ + addrkey_t k1[] = {0x55, 0x55, 0x5A}; + int i; + unit_show_func("edns-subnet/addrtree.h", "getbit"); + for(i = 0; i<20; i++) { + unit_assert( unittest_wrapper_addrtree_getbit(k1, 20, (addrlen_t)i) == (i&1) ); + } +} + +static void bits_common_test(void) +{ + addrkey_t k1[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + addrkey_t k2[] = {0,0,0,0,0,0,0,0}; + addrlen_t i; + + unit_show_func("edns-subnet/addrtree.h", "bits_common"); + for(i = 0; i<64; i++) { + unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k1, 64, i) == 64 ); + } + for(i = 0; i<8; i++) { + k2[i] = k1[i]^(1<<i); + } + unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 0) == 0*8+7 ); + unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 8) == 1*8+6 ); + unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 16) == 2*8+5 ); + unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 24) == 3*8+4 ); + unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 32) == 4*8+3 ); + unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 40) == 5*8+2 ); + unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 48) == 6*8+1 ); + unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 56) == 7*8+0 ); +} + +static void cmpbit_test(void) +{ + addrkey_t k1[] = {0xA5, 0x0F}; + addrkey_t k2[] = {0x5A, 0xF0}; + addrlen_t i; + + unit_show_func("edns-subnet/addrtree.h", "cmpbit"); + for(i = 0; i<16; i++) { + unit_assert( !unittest_wrapper_addrtree_cmpbit(k1,k1,i) ); + unit_assert( unittest_wrapper_addrtree_cmpbit(k1,k2,i) ); + } +} + +void ecs_test(void) +{ + unit_show_feature("ecs"); + cmpbit_test(); + bits_common_test(); + getbit_test(); + issub_test(); + consistency_test(); +} +#endif /* CLIENT_SUBNET */ + diff --git a/testcode/unitmain.c b/testcode/unitmain.c index e3d7a59b4c4ca..fd56e64d3f5d8 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -558,6 +558,269 @@ rnd_test(void) ub_randfree(r); } +#include "respip/respip.h" +#include "services/localzone.h" +#include "util/data/packed_rrset.h" +typedef struct addr_action {char* ip; char* sact; enum respip_action act;} + addr_action_t; + +/** Utility function that verifies that the respip set has actions as expected */ +static void +verify_respip_set_actions(struct respip_set* set, addr_action_t actions[], + int actions_len) +{ + int i = 0; + struct rbtree_type* tree = respip_set_get_tree(set); + for (i=0; i<actions_len; i++) { + struct sockaddr_storage addr; + int net; + socklen_t addrlen; + struct resp_addr* node; + netblockstrtoaddr(actions[i].ip, UNBOUND_DNS_PORT, &addr, + &addrlen, &net); + node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net); + + /** we have the node and the node has the correct action + * and has no data */ + unit_assert(node); + unit_assert(actions[i].act == + resp_addr_get_action(node)); + unit_assert(resp_addr_get_rrset(node) == NULL); + } + unit_assert(actions_len && i == actions_len); + unit_assert(actions_len == (int)tree->count); +} + +/** Global respip actions test; apply raw config data and verify that + * all the nodes in the respip set, looked up by address, have expected + * actions */ +static void +respip_conf_actions_test(void) +{ + addr_action_t config_response_ip[] = { + {"192.0.1.0/24", "deny", respip_deny}, + {"192.0.2.0/24", "redirect", respip_redirect}, + {"192.0.3.0/26", "inform", respip_inform}, + {"192.0.4.0/27", "inform_deny", respip_inform_deny}, + {"2001:db8:1::/48", "always_transparent", respip_always_transparent}, + {"2001:db8:2::/49", "always_refuse", respip_always_refuse}, + {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain}, + }; + int i; + struct respip_set* set = respip_set_create(); + struct config_file cfg; + int clen = (int)(sizeof(config_response_ip) / sizeof(addr_action_t)); + + unit_assert(set); + unit_show_feature("global respip config actions apply"); + memset(&cfg, 0, sizeof(cfg)); + for(i=0; i<clen; i++) { + char* ip = strdup(config_response_ip[i].ip); + char* sact = strdup(config_response_ip[i].sact); + unit_assert(ip && sact); + if(!cfg_str2list_insert(&cfg.respip_actions, ip, sact)) + unit_assert(0); + } + unit_assert(respip_global_apply_cfg(set, &cfg)); + verify_respip_set_actions(set, config_response_ip, clen); +} + +/** Per-view respip actions test; apply raw configuration with two views + * and verify that actions are as expected in respip sets of both views */ +static void +respip_view_conf_actions_test(void) +{ + addr_action_t config_response_ip_view1[] = { + {"192.0.1.0/24", "deny", respip_deny}, + {"192.0.2.0/24", "redirect", respip_redirect}, + {"192.0.3.0/26", "inform", respip_inform}, + {"192.0.4.0/27", "inform_deny", respip_inform_deny}, + }; + addr_action_t config_response_ip_view2[] = { + {"2001:db8:1::/48", "always_transparent", respip_always_transparent}, + {"2001:db8:2::/49", "always_refuse", respip_always_refuse}, + {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain}, + }; + int i; + struct config_file cfg; + int clen1 = (int)(sizeof(config_response_ip_view1) / sizeof(addr_action_t)); + int clen2 = (int)(sizeof(config_response_ip_view2) / sizeof(addr_action_t)); + struct config_view* cv1; + struct config_view* cv2; + int have_respip_cfg = 0; + struct views* views = NULL; + struct view* v = NULL; + + unit_show_feature("per-view respip config actions apply"); + memset(&cfg, 0, sizeof(cfg)); + cv1 = (struct config_view*)calloc(1, sizeof(struct config_view)); + cv2 = (struct config_view*)calloc(1, sizeof(struct config_view)); + unit_assert(cv1 && cv2); + cv1->name = strdup("view1"); + cv2->name = strdup("view2"); + unit_assert(cv1->name && cv2->name); + cv1->next = cv2; + cfg.views = cv1; + + for(i=0; i<clen1; i++) { + char* ip = strdup(config_response_ip_view1[i].ip); + char* sact = strdup(config_response_ip_view1[i].sact); + unit_assert(ip && sact); + if(!cfg_str2list_insert(&cv1->respip_actions, ip, sact)) + unit_assert(0); + } + for(i=0; i<clen2; i++) { + char* ip = strdup(config_response_ip_view2[i].ip); + char* sact = strdup(config_response_ip_view2[i].sact); + unit_assert(ip && sact); + if(!cfg_str2list_insert(&cv2->respip_actions, ip, sact)) + unit_assert(0); + } + views = views_create(); + unit_assert(views); + unit_assert(views_apply_cfg(views, &cfg)); + unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg)); + + /* now verify the respip sets in each view */ + v = views_find_view(views, "view1", 0); + unit_assert(v); + verify_respip_set_actions(v->respip_set, config_response_ip_view1, clen1); + lock_rw_unlock(&v->lock); + v = views_find_view(views, "view2", 0); + unit_assert(v); + verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2); + lock_rw_unlock(&v->lock); +} + +typedef struct addr_data {char* ip; char* data;} addr_data_t; + +/** find the respip address node in the specified tree (by address lookup) + * and verify type and address of the specified rdata (by index) in this + * node's rrset */ +static void +verify_rrset(struct respip_set* set, const char* ipstr, + const char* rdatastr, size_t rdi, uint16_t type) +{ + struct sockaddr_storage addr; + int net; + char buf[65536]; + socklen_t addrlen; + struct rbtree_type* tree; + struct resp_addr* node; + const struct ub_packed_rrset_key* rrs; + + netblockstrtoaddr(ipstr, UNBOUND_DNS_PORT, &addr, &addrlen, &net); + tree = respip_set_get_tree(set); + node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net); + unit_assert(node); + unit_assert((rrs = resp_addr_get_rrset(node))); + unit_assert(ntohs(rrs->rk.type) == type); + packed_rr_to_string((struct ub_packed_rrset_key*)rrs, + rdi, 0, buf, sizeof(buf)); + unit_assert(strstr(buf, rdatastr)); +} + +/** Dataset used to test redirect rrset initialization for both + * global and per-view respip redirect configuration */ +static addr_data_t config_response_ip_data[] = { + {"192.0.1.0/24", "A 1.2.3.4"}, + {"192.0.1.0/24", "A 11.12.13.14"}, + {"192.0.2.0/24", "CNAME www.example.com."}, + {"2001:db8:1::/48", "AAAA 2001:db8:1::2:1"}, +}; + +/** Populate raw respip redirect config data, used for both global and + * view-based respip redirect test case */ +static void +cfg_insert_respip_data(struct config_str2list** respip_actions, + struct config_str2list** respip_data) +{ + int clen = (int)(sizeof(config_response_ip_data) / sizeof(addr_data_t)); + int i = 0; + + /* insert actions (duplicate netblocks don't matter) */ + for(i=0; i<clen; i++) { + char* ip = strdup(config_response_ip_data[i].ip); + char* sact = strdup("redirect"); + unit_assert(ip && sact); + if(!cfg_str2list_insert(respip_actions, ip, sact)) + unit_assert(0); + } + /* insert data */ + for(i=0; i<clen; i++) { + char* ip = strdup(config_response_ip_data[i].ip); + char* data = strdup(config_response_ip_data[i].data); + unit_assert(ip && data); + if(!cfg_str2list_insert(respip_data, ip, data)) + unit_assert(0); + } +} + +/** Test global respip redirect w/ data directives */ +static void +respip_conf_data_test(void) +{ + struct respip_set* set = respip_set_create(); + struct config_file cfg; + + unit_show_feature("global respip config data apply"); + memset(&cfg, 0, sizeof(cfg)); + + cfg_insert_respip_data(&cfg.respip_actions, &cfg.respip_data); + + /* apply configuration and verify rrsets */ + unit_assert(respip_global_apply_cfg(set, &cfg)); + verify_rrset(set, "192.0.1.0/24", "1.2.3.4", 0, LDNS_RR_TYPE_A); + verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A); + verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME); + verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA); +} + +/** Test per-view respip redirect w/ data directives */ +static void +respip_view_conf_data_test(void) +{ + struct config_file cfg; + struct config_view* cv; + int have_respip_cfg = 0; + struct views* views = NULL; + struct view* v = NULL; + + unit_show_feature("per-view respip config data apply"); + memset(&cfg, 0, sizeof(cfg)); + cv = (struct config_view*)calloc(1, sizeof(struct config_view)); + unit_assert(cv); + cv->name = strdup("view1"); + unit_assert(cv->name); + cfg.views = cv; + cfg_insert_respip_data(&cv->respip_actions, &cv->respip_data); + views = views_create(); + unit_assert(views); + unit_assert(views_apply_cfg(views, &cfg)); + + /* apply configuration and verify rrsets */ + unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg)); + v = views_find_view(views, "view1", 0); + unit_assert(v); + verify_rrset(v->respip_set, "192.0.1.0/24", "1.2.3.4", + 0, LDNS_RR_TYPE_A); + verify_rrset(v->respip_set, "192.0.1.0/24", "11.12.13.14", + 1, LDNS_RR_TYPE_A); + verify_rrset(v->respip_set, "192.0.2.0/24", "www.example.com", + 0, LDNS_RR_TYPE_CNAME); + verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1", + 0, LDNS_RR_TYPE_AAAA); +} + +/** respip unit tests */ +static void respip_test(void) +{ + respip_view_conf_data_test(); + respip_conf_data_test(); + respip_view_conf_actions_test(); + respip_conf_actions_test(); +} + void unit_show_func(const char* file, const char* func) { printf("test %s:%s\n", file, func); @@ -604,6 +867,7 @@ main(int argc, char* argv[]) checklock_start(); neg_test(); rnd_test(); + respip_test(); verify_test(); net_test(); config_memsize_test(); @@ -618,6 +882,9 @@ main(int argc, char* argv[]) infra_test(); ldns_test(); msgparse_test(); +#ifdef CLIENT_SUBNET + ecs_test(); +#endif /* CLIENT_SUBNET */ checklock_stop(); printf("%d checks ok.\n", testcount); #ifdef HAVE_SSL diff --git a/testcode/unitmain.h b/testcode/unitmain.h index c27bd1437053f..d81b603b2f6b8 100644 --- a/testcode/unitmain.h +++ b/testcode/unitmain.h @@ -72,6 +72,10 @@ void verify_test(void); void neg_test(void); /** unit test for regional allocator functions */ void regional_test(void); +#ifdef CLIENT_SUBNET +/** Unit test for ECS functions */ +void ecs_test(void); +#endif /* CLIENT_SUBNET */ /** unit test for ldns functions */ void ldns_test(void); diff --git a/testcode/unitverify.c b/testcode/unitverify.c index b74ea5131b90a..37994a377c28e 100644 --- a/testcode/unitverify.c +++ b/testcode/unitverify.c @@ -496,8 +496,10 @@ void verify_test(void) { unit_show_feature("signature verify"); +#ifdef USE_SHA1 verifytest_file("testdata/test_signatures.1", "20070818005004"); -#ifdef USE_DSA +#endif +#if defined(USE_DSA) && defined(USE_SHA1) verifytest_file("testdata/test_signatures.2", "20080414005004"); verifytest_file("testdata/test_signatures.3", "20080416005004"); verifytest_file("testdata/test_signatures.4", "20080416005004"); @@ -505,17 +507,23 @@ verify_test(void) verifytest_file("testdata/test_signatures.6", "20080416005004"); verifytest_file("testdata/test_signatures.7", "20070829144150"); #endif /* USE_DSA */ +#ifdef USE_SHA1 verifytest_file("testdata/test_signatures.8", "20070829144150"); +#endif #if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2) verifytest_file("testdata/test_sigs.rsasha256", "20070829144150"); +# ifdef USE_SHA1 verifytest_file("testdata/test_sigs.sha1_and_256", "20070829144150"); +# endif verifytest_file("testdata/test_sigs.rsasha256_draft", "20090101000000"); #endif #if (defined(HAVE_EVP_SHA512) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2) verifytest_file("testdata/test_sigs.rsasha512_draft", "20070829144150"); #endif +#ifdef USE_SHA1 verifytest_file("testdata/test_sigs.hinfo", "20090107100022"); verifytest_file("testdata/test_sigs.revoked", "20080414005004"); +#endif #ifdef USE_GOST if(sldns_key_EVP_load_gost_id()) verifytest_file("testdata/test_sigs.gost", "20090807060504"); @@ -529,7 +537,9 @@ verify_test(void) } dstest_file("testdata/test_ds.sha384"); #endif +#ifdef USE_SHA1 dstest_file("testdata/test_ds.sha1"); +#endif nsectest(); nsec3_hash_test("testdata/test_nsec3_hash.1"); } |