diff options
author | Internet Software Consortium, Inc <@isc.org> | 2012-10-29 07:27:43 -0600 |
---|---|---|
committer | Internet Software Consortium, Inc <@isc.org> | 2012-10-29 07:27:43 -0600 |
commit | 56b61b7cd52fdce3fd477a28c8dd55db76eba042 (patch) | |
tree | 5619c48ff3e920b87bc1c1a2de09ba68426c38bf /lib | |
parent | c450e7bf1c721a84ef09d825e79cf998159decc0 (diff) | |
download | bind9-56b61b7cd52fdce3fd477a28c8dd55db76eba042.tar.gz |
9.9.2
Diffstat (limited to 'lib')
166 files changed, 2426 insertions, 670 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in index e46aef26..e3f0bdb8 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001, 2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/bind9/Makefile.in b/lib/bind9/Makefile.in index 35c40223..73285e1e 100644 --- a/lib/bind9/Makefile.in +++ b/lib/bind9/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/bind9/api b/lib/bind9/api index 6ed2ee97..787f54fc 100644 --- a/lib/bind9/api +++ b/lib/bind9/api @@ -4,5 +4,5 @@ # 9.8: 80-89 # 9.9: 90-109 LIBINTERFACE = 90 -LIBREVISION = 3 +LIBREVISION = 5 LIBAGE = 0 diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 08d393ec..9cbcf24f 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -287,10 +287,6 @@ disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) { tresult = dns_secalg_fromtext(&alg, &r); if (tresult != ISC_R_SUCCESS) { - isc_uint8_t ui; - result = isc_parse_uint8(&ui, r.base, 10); - } - if (tresult != ISC_R_SUCCESS) { cfg_obj_log(cfg_listelt_value(element), logctx, ISC_LOG_ERROR, "invalid algorithm '%s'", r.base); @@ -737,6 +733,20 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, } obj = NULL; + cfg_map_get(options, "max-rsa-exponent-size", &obj); + if (obj != NULL) { + isc_uint32_t val; + + val = cfg_obj_asuint32(obj); + if (val != 0 && (val < 35 || val > 4096)) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "max-rsa-exponent-size '%u' is out of " + "range (35..4096)", val); + result = ISC_R_RANGE; + } + } + + obj = NULL; cfg_map_get(options, "sig-validity-interval", &obj); if (obj != NULL) { isc_uint32_t validity, resign = 0; @@ -1261,6 +1271,29 @@ typedef struct { } optionstable; static isc_result_t +check_nonzero(const cfg_obj_t *options, isc_log_t *logctx) { + isc_result_t result = ISC_R_SUCCESS; + const cfg_obj_t *obj = NULL; + unsigned int i; + + static const char *nonzero[] = { "max-retry-time", "min-retry-time", + "max-refresh-time", "min-refresh-time" }; + /* + * Check if value is zero. + */ + for (i = 0; i < sizeof(nonzero) / sizeof(nonzero[0]); i++) { + obj = NULL; + if (cfg_map_get(options, nonzero[i], &obj) == ISC_R_SUCCESS && + cfg_obj_asuint32(obj) == 0) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "'%s' must not be zero", nonzero[i]); + result = ISC_R_FAILURE; + } + } + return (result); +} + +static isc_result_t check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, const cfg_obj_t *config, isc_symtab_t *symtab, dns_rdataclass_t defclass, cfg_aclconfctx_t *actx, @@ -1269,7 +1302,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, const char *znamestr; const char *typestr; unsigned int ztype; - const cfg_obj_t *zoptions; + const cfg_obj_t *zoptions, *goptions = NULL; const cfg_obj_t *obj = NULL; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; @@ -1290,8 +1323,10 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, { "also-notify", MASTERZONE | SLAVEZONE }, { "dialup", MASTERZONE | SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "delegation-only", HINTZONE | STUBZONE | DELEGATIONZONE }, - { "forward", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE }, - { "forwarders", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE }, + { "forward", MASTERZONE | SLAVEZONE | STUBZONE | + STATICSTUBZONE | FORWARDZONE }, + { "forwarders", MASTERZONE | SLAVEZONE | STUBZONE | + STATICSTUBZONE | FORWARDZONE }, { "maintain-ixfr-base", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, { "max-ixfr-log-size", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, { "notify-source", MASTERZONE | SLAVEZONE }, @@ -1350,10 +1385,14 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, { "passive", SLAVEZONE | STUBZONE | STREDIRECTZONE }, }; + znamestr = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); zoptions = cfg_tuple_get(zconfig, "options"); + if (config != NULL) + cfg_map_get(config, "options", &goptions); + obj = NULL; (void)cfg_map_get(zoptions, "type", &obj); if (obj == NULL) { @@ -1443,6 +1482,12 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, } /* + * Check if value is zero. + */ + if (check_nonzero(zoptions, logctx) != ISC_R_SUCCESS) + result = ISC_R_FAILURE; + + /* * Look for inappropriate options for the given zone type. * Check that ACLs expand correctly. */ @@ -2190,6 +2235,14 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, } /* + * Check non-zero options at the global and view levels. + */ + if (options != NULL && check_nonzero(options, logctx) != ISC_R_SUCCESS) + result = ISC_R_FAILURE; + if (voptions != NULL &&check_nonzero(voptions, logctx) != ISC_R_SUCCESS) + result = ISC_R_FAILURE; + + /* * Check that dual-stack-servers is reasonable. */ if (voptions == NULL) { @@ -2216,15 +2269,15 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, tresult = isc_symtab_create(mctx, 1000, freekey, mctx, ISC_FALSE, &symtab); if (tresult != ISC_R_SUCCESS) - return (ISC_R_NOMEMORY); + goto cleanup; (void)cfg_map_get(config, "key", &keys); tresult = check_keylist(keys, symtab, mctx, logctx); if (tresult == ISC_R_EXISTS) result = ISC_R_FAILURE; else if (tresult != ISC_R_SUCCESS) { - isc_symtab_destroy(&symtab); - return (tresult); + result = tresult; + goto cleanup; } if (voptions != NULL) { @@ -2234,8 +2287,8 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, if (tresult == ISC_R_EXISTS) result = ISC_R_FAILURE; else if (tresult != ISC_R_SUCCESS) { - isc_symtab_destroy(&symtab); - return (tresult); + result = tresult; + goto cleanup; } } @@ -2356,7 +2409,11 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, if (tresult != ISC_R_SUCCESS) result = tresult; - cfg_aclconfctx_detach(&actx); + cleanup: + if (symtab != NULL) + isc_symtab_destroy(&symtab); + if (actx != NULL) + cfg_aclconfctx_detach(&actx); return (result); } diff --git a/lib/bind9/include/Makefile.in b/lib/bind9/include/Makefile.in index 65eecb05..0a7436c0 100644 --- a/lib/bind9/include/Makefile.in +++ b/lib/bind9/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/bind9/include/bind9/Makefile.in b/lib/bind9/include/bind9/Makefile.in index 8abfaf65..11ae5862 100644 --- a/lib/bind9/include/bind9/Makefile.in +++ b/lib/bind9/include/bind9/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in index b68a1b0b..a0063388 100644 --- a/lib/dns/Makefile.in +++ b/lib/dns/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any @@ -47,7 +47,8 @@ LIBS = @LIBS@ # Alphabetically OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ - opensslgost_link.@O@ opensslrsa_link.@O@ + opensslecdsa_link.@O@ opensslgost_link.@O@ \ + opensslrsa_link.@O@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \ dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \ @@ -76,7 +77,7 @@ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} # Alphabetically OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ - opensslgost_link.c opensslrsa_link.c + opensslecdsa_link.c opensslgost_link.c opensslrsa_link.c DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \ dst_api.c dst_lib.c dst_parse.c \ diff --git a/lib/dns/adb.c b/lib/dns/adb.c index 8d17d829..5db442cf 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -111,6 +111,7 @@ struct dns_adb { isc_taskmgr_t *taskmgr; isc_task_t *task; + isc_task_t *excl; isc_interval_t tick_interval; int next_cleanbucket; @@ -1627,10 +1628,12 @@ new_adbname(dns_adb_t *adb, dns_name_t *dnsname) { LOCK(&adb->namescntlock); adb->namescnt++; - if (!adb->grownames_sent && adb->namescnt > (adb->nnames * 8)) { + if (!adb->grownames_sent && adb->excl != NULL && + adb->namescnt > (adb->nnames * 8)) + { isc_event_t *event = &adb->grownames; inc_adb_irefcnt(adb); - isc_task_send(adb->task, &event); + isc_task_send(adb->excl, &event); adb->grownames_sent = ISC_TRUE; } UNLOCK(&adb->namescntlock); @@ -1751,8 +1754,9 @@ new_adbentry(dns_adb_t *adb) { ISC_LINK_INIT(e, plink); LOCK(&adb->entriescntlock); adb->entriescnt++; - if (!adb->growentries_sent && - adb->entriescnt > (adb->nentries * 8)) { + if (!adb->growentries_sent && adb->growentries_sent && + adb->entriescnt > (adb->nentries * 8)) + { isc_event_t *event = &adb->growentries; inc_adb_irefcnt(adb); isc_task_send(adb->task, &event); @@ -2327,6 +2331,7 @@ destroy(dns_adb_t *adb) { adb->magic = 0; isc_task_detach(&adb->task); + isc_task_detach(&adb->excl); isc_mempool_destroy(&adb->nmp); isc_mempool_destroy(&adb->nhmp); @@ -2410,6 +2415,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, adb->aimp = NULL; adb->afmp = NULL; adb->task = NULL; + adb->excl = NULL; adb->mctx = NULL; adb->view = view; adb->taskmgr = taskmgr; @@ -2445,6 +2451,16 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, adb, NULL, NULL); adb->grownames_sent = ISC_FALSE; + result = isc_taskmgr_excltask(adb->taskmgr, &adb->excl); + if (result != ISC_R_SUCCESS) { + DP(ISC_LOG_INFO, "adb: task-exclusive mode unavailable, " + "intializing table sizes to %u\n", + nbuckets[11]); + adb->nentries = nbuckets[11]; + adb->nnames= nbuckets[11]; + + } + isc_mem_attach(mem, &adb->mctx); result = isc_mutex_init(&adb->lock); @@ -2557,6 +2573,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, result = isc_task_create(adb->taskmgr, 0, &adb->task); if (result != ISC_R_SUCCESS) goto fail3; + isc_task_setname(adb->task, "ADB", adb); /* @@ -3904,8 +3921,10 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, addr->entry->srtt = new_srtt; addr->srtt = new_srtt; - isc_stdtime_get(&now); - addr->entry->expires = now + ADB_ENTRY_WINDOW; + if (addr->entry->expires == 0) { + isc_stdtime_get(&now); + addr->entry->expires = now + ADB_ENTRY_WINDOW; + } UNLOCK(&adb->entrylocks[bucket]); } @@ -3915,6 +3934,7 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits, unsigned int mask) { int bucket; + isc_stdtime_t now; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); @@ -3923,6 +3943,11 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, LOCK(&adb->entrylocks[bucket]); addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask); + if (addr->entry->expires == 0) { + isc_stdtime_get(&now); + addr->entry->expires = now + ADB_ENTRY_WINDOW; + } + /* * Note that we do not update the other bits in addr->flags with * the most recent values from addr->entry->flags. @@ -4001,15 +4026,16 @@ dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) { entry = addr->entry; REQUIRE(DNS_ADBENTRY_VALID(entry)); - isc_stdtime_get(&now); - *addrp = NULL; overmem = isc_mem_isovermem(adb->mctx); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); - entry->expires = now + ADB_ENTRY_WINDOW; + if (entry->expires == 0) { + isc_stdtime_get(&now); + entry->expires = now + ADB_ENTRY_WINDOW; + } want_check_exit = dec_entry_refcnt(adb, overmem, entry, ISC_FALSE); diff --git a/lib/dns/api b/lib/dns/api index 9d37a0b8..5eded2c1 100644 --- a/lib/dns/api +++ b/lib/dns/api @@ -3,6 +3,6 @@ # 9.7: 60-79 # 9.8: 80-89 # 9.9: 90-109 -LIBINTERFACE = 94 +LIBINTERFACE = 96 LIBREVISION = 1 LIBAGE = 1 diff --git a/lib/dns/db.c b/lib/dns/db.c index e7e4bf15..77547268 100644 --- a/lib/dns/db.c +++ b/lib/dns/db.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.c,v 1.99 2011/10/13 01:32:33 vjs Exp $ */ +/* $Id: db.c,v 1.99.4.1 2011/10/23 20:12:07 vjs Exp $ */ /*! \file */ @@ -1014,14 +1014,13 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) (db->methods->rpz_enabled)(db, st); } -isc_result_t +void dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_rdataset_t *ardataset, dns_rpz_st_t *st, dns_name_t *query_qname) { - if (db->methods->rpz_findips == NULL) - return (ISC_R_NOTIMPLEMENTED); - return ((db->methods->rpz_findips)(rpz, rpz_type, zone, db, version, - ardataset, st, query_qname)); + if (db->methods->rpz_findips != NULL) + (db->methods->rpz_findips)(rpz, rpz_type, zone, db, version, + ardataset, st, query_qname); } diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index ed945254..2995fdde 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -44,10 +44,13 @@ #include <dns/rdataset.h> #include <dns/rdatastruct.h> #include <dns/result.h> +#include <dns/stats.h> #include <dns/tsig.h> /* for DNS_TSIG_FUDGE */ #include <dst/result.h> +LIBDNS_EXTERNAL_DATA isc_stats_t *dns_dnssec_stats; + #define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR) #define RETERR(x) do { \ @@ -77,6 +80,12 @@ digest_callback(void *arg, isc_region_t *data) { return (dst_context_adddata(ctx, data)); } +static inline void +inc_stat(isc_statscounter_t counter) { + if (dns_dnssec_stats != NULL) + isc_stats_increment(dns_dnssec_stats, counter); +} + /* * Make qsort happy. */ @@ -153,7 +162,9 @@ dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx, } static isc_result_t -digest_sig(dst_context_t *ctx, dns_rdata_t *sigrdata, dns_rdata_rrsig_t *sig) { +digest_sig(dst_context_t *ctx, isc_boolean_t downcase, dns_rdata_t *sigrdata, + dns_rdata_rrsig_t *rrsig) +{ isc_region_t r; isc_result_t ret; dns_fixedname_t fname; @@ -165,11 +176,16 @@ digest_sig(dst_context_t *ctx, dns_rdata_t *sigrdata, dns_rdata_rrsig_t *sig) { ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) return (ret); - dns_fixedname_init(&fname); - RUNTIME_CHECK(dns_name_downcase(&sig->signer, - dns_fixedname_name(&fname), NULL) - == ISC_R_SUCCESS); - dns_name_toregion(dns_fixedname_name(&fname), &r); + if (downcase) { + dns_fixedname_init(&fname); + + RUNTIME_CHECK(dns_name_downcase(&rrsig->signer, + dns_fixedname_name(&fname), + NULL) == ISC_R_SUCCESS); + dns_name_toregion(dns_fixedname_name(&fname), &r); + } else + dns_name_toregion(&rrsig->signer, &r); + return (dst_context_adddata(ctx, &r)); } @@ -191,6 +207,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_uint32_t flags; unsigned int sigsize; dns_fixedname_t fnewname; + dns_fixedname_t fsigner; REQUIRE(name != NULL); REQUIRE(dns_name_countlabels(name) <= 255); @@ -218,8 +235,14 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, sig.common.rdtype = dns_rdatatype_rrsig; ISC_LINK_INIT(&sig.common, link); + /* + * Downcase signer. + */ dns_name_init(&sig.signer, NULL); - dns_name_clone(dst_key_name(key), &sig.signer); + dns_fixedname_init(&fsigner); + RUNTIME_CHECK(dns_name_downcase(dst_key_name(key), + dns_fixedname_name(&fsigner), NULL) == ISC_R_SUCCESS); + dns_name_clone(dns_fixedname_name(&fsigner), &sig.signer); sig.covered = set->type; sig.algorithm = dst_key_alg(key); @@ -259,7 +282,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, /* * Digest the SIG rdata. */ - ret = digest_sig(ctx, &tmpsigrdata, &sig); + ret = digest_sig(ctx, ISC_FALSE, &tmpsigrdata, &sig); if (ret != ISC_R_SUCCESS) goto cleanup_context; @@ -332,7 +355,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, memcpy(sig.signature, r.base, sig.siglen); ret = dns_rdata_fromstruct(sigrdata, sig.common.rdclass, - sig.common.rdtype, &sig, buffer); + sig.common.rdtype, &sig, buffer); cleanup_array: isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t)); @@ -351,6 +374,15 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild) { + return (dns_dnssec_verify3(name, set, key, ignoretime, 0, mctx, + sigrdata, wild)); +} + +isc_result_t +dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, + isc_boolean_t ignoretime, unsigned int maxbits, + isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild) +{ dns_rdata_rrsig_t sig; dns_fixedname_t fnewname; isc_region_t r; @@ -363,6 +395,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, dst_context_t *ctx = NULL; int labels = 0; isc_uint32_t flags; + isc_boolean_t downcase = ISC_FALSE; REQUIRE(name != NULL); REQUIRE(set != NULL); @@ -377,8 +410,10 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, if (set->type != sig.covered) return (DNS_R_SIGINVALID); - if (isc_serial_lt(sig.timeexpire, sig.timesigned)) + if (isc_serial_lt(sig.timeexpire, sig.timesigned)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); + } if (!ignoretime) { isc_stdtime_get(&now); @@ -386,10 +421,13 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, /* * Is SIG temporally valid? */ - if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) + if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGFUTURE); - else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) + } else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGEXPIRED); + } } /* @@ -400,16 +438,22 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, case dns_rdatatype_ns: case dns_rdatatype_soa: case dns_rdatatype_dnskey: - if (!dns_name_equal(name, &sig.signer)) + if (!dns_name_equal(name, &sig.signer)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); + } break; case dns_rdatatype_ds: - if (dns_name_equal(name, &sig.signer)) + if (dns_name_equal(name, &sig.signer)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); + } /* FALLTHROUGH */ default: - if (!dns_name_issubdomain(name, &sig.signer)) + if (!dns_name_issubdomain(name, &sig.signer)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); + } break; } @@ -417,11 +461,16 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, * Is the key allowed to sign data? */ flags = dst_key_flags(key); - if (flags & DNS_KEYTYPE_NOAUTH) + if (flags & DNS_KEYTYPE_NOAUTH) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_KEYUNAUTHORIZED); - if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) + } + if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_KEYUNAUTHORIZED); + } + again: ret = dst_context_create(key, mctx, &ctx); if (ret != ISC_R_SUCCESS) goto cleanup_struct; @@ -429,7 +478,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, /* * Digest the SIG rdata (not including the signature). */ - ret = digest_sig(ctx, sigrdata, &sig); + ret = digest_sig(ctx, downcase, sigrdata, &sig); if (ret != ISC_R_SUCCESS) goto cleanup_context; @@ -507,22 +556,41 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, r.base = sig.signature; r.length = sig.siglen; - ret = dst_context_verify(ctx, &r); - if (ret == DST_R_VERIFYFAILURE) - ret = DNS_R_SIGINVALID; + ret = dst_context_verify2(ctx, maxbits, &r); + if (ret == ISC_R_SUCCESS && downcase) { + char namebuf[DNS_NAME_FORMATSIZE]; + dns_name_format(&sig.signer, namebuf, sizeof(namebuf)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "sucessfully validated after lower casing " + "signer '%s'", namebuf); + inc_stat(dns_dnssecstats_downcase); + } else if (ret == ISC_R_SUCCESS) + inc_stat(dns_dnssecstats_asis); cleanup_array: isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t)); cleanup_context: dst_context_destroy(&ctx); + if (ret == DST_R_VERIFYFAILURE && !downcase) { + downcase = ISC_TRUE; + goto again; + } cleanup_struct: dns_rdata_freestruct(&sig); + if (ret == DST_R_VERIFYFAILURE) + ret = DNS_R_SIGINVALID; + + if (ret != ISC_R_SUCCESS) + inc_stat(dns_dnssecstats_fail); + if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) { if (wild != NULL) RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, dns_fixedname_name(&fnewname), wild, NULL) == ISC_R_SUCCESS); + inc_stat(dns_dnssecstats_wildcard); ret = DNS_R_FROMWILDCARD; } return (ret); @@ -1333,11 +1401,12 @@ dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory, * the keys in the keyset, regardless of whether they have * metadata indicating they should be deactivated or removed. */ -static void +static isc_result_t addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey, isc_boolean_t savekeys, isc_mem_t *mctx) { dns_dnsseckey_t *key; + isc_result_t result; /* Skip duplicates */ for (key = ISC_LIST_HEAD(*keylist); @@ -1365,10 +1434,12 @@ addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey, } key->source = dns_keysource_zoneapex; - return; + return (ISC_R_SUCCESS); } - dns_dnsseckey_create(mctx, newkey, &key); + result = dns_dnsseckey_create(mctx, newkey, &key); + if (result != ISC_R_SUCCESS) + return (result); if (key->legacy || savekeys) { key->force_publish = ISC_TRUE; key->force_sign = dst_key_isprivate(key->key); @@ -1376,6 +1447,7 @@ addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey, key->source = dns_keysource_zoneapex; ISC_LIST_APPEND(*keylist, key, link); *newkey = NULL; + return (ISC_R_SUCCESS); } @@ -1466,7 +1538,7 @@ dns_dnssec_keylistfromrdataset(dns_name_t *origin, goto skip; if (public) { - addkey(keylist, &pubkey, savekeys, mctx); + RETERR(addkey(keylist, &pubkey, savekeys, mctx)); goto skip; } @@ -1519,7 +1591,7 @@ dns_dnssec_keylistfromrdataset(dns_name_t *origin, } if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) { - addkey(keylist, &pubkey, savekeys, mctx); + RETERR(addkey(keylist, &pubkey, savekeys, mctx)); goto skip; } RETERR(result); @@ -1534,7 +1606,7 @@ dns_dnssec_keylistfromrdataset(dns_name_t *origin, */ dst_key_setttl(privkey, dst_key_getttl(pubkey)); - addkey(keylist, &privkey, savekeys, mctx); + RETERR(addkey(keylist, &privkey, savekeys, mctx)); skip: if (pubkey != NULL) dst_key_free(&pubkey); diff --git a/lib/dns/ds.c b/lib/dns/ds.c index 3c74d1da..e72ecbb6 100644 --- a/lib/dns/ds.c +++ b/lib/dns/ds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -52,12 +52,13 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, { dns_fixedname_t fname; dns_name_t *name; - unsigned char digest[ISC_SHA256_DIGESTLENGTH]; + unsigned char digest[ISC_SHA384_DIGESTLENGTH]; isc_region_t r; isc_buffer_t b; dns_rdata_ds_t ds; isc_sha1_t sha1; isc_sha256_t sha256; + isc_sha384_t sha384; #ifdef HAVE_OPENSSL_GOST EVP_MD_CTX ctx; const EVP_MD *md; @@ -86,17 +87,18 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, isc_sha1_update(&sha1, r.base, r.length); isc_sha1_final(&sha1, digest); break; + #ifdef HAVE_OPENSSL_GOST #define CHECK(x) \ if ((x) != 1) { \ EVP_MD_CTX_cleanup(&ctx); \ - return (DST_R_OPENSSLFAILURE); \ + return (DST_R_CRYPTOFAILURE); \ } case DNS_DSDIGEST_GOST: md = EVP_gost(); if (md == NULL) - return (DST_R_OPENSSLFAILURE); + return (DST_R_CRYPTOFAILURE); EVP_MD_CTX_init(&ctx); CHECK(EVP_DigestInit(&ctx, md)); dns_name_toregion(name, &r); @@ -111,6 +113,18 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, CHECK(EVP_DigestFinal(&ctx, digest, NULL)); break; #endif + + case DNS_DSDIGEST_SHA384: + isc_sha384_init(&sha384); + dns_name_toregion(name, &r); + isc_sha384_update(&sha384, r.base, r.length); + dns_rdata_toregion(key, &r); + INSIST(r.length >= 4); + isc_sha384_update(&sha384, r.base, r.length); + isc_sha384_final(digest, &sha384); + break; + + case DNS_DSDIGEST_SHA256: default: isc_sha256_init(&sha256); dns_name_toregion(name, &r); @@ -132,11 +146,18 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, case DNS_DSDIGEST_SHA1: ds.length = ISC_SHA1_DIGESTLENGTH; break; + #ifdef HAVE_OPENSSL_GOST case DNS_DSDIGEST_GOST: ds.length = ISC_GOST_DIGESTLENGTH; break; #endif + + case DNS_DSDIGEST_SHA384: + ds.length = ISC_SHA384_DIGESTLENGTH; + break; + + case DNS_DSDIGEST_SHA256: default: ds.length = ISC_SHA256_DIGESTLENGTH; break; @@ -152,9 +173,11 @@ dns_ds_digest_supported(unsigned int digest_type) { #ifdef HAVE_OPENSSL_GOST return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 || digest_type == DNS_DSDIGEST_SHA256 || - digest_type == DNS_DSDIGEST_GOST)); + digest_type == DNS_DSDIGEST_GOST || + digest_type == DNS_DSDIGEST_SHA384)); #else return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 || - digest_type == DNS_DSDIGEST_SHA256)); + digest_type == DNS_DSDIGEST_SHA256 || + digest_type == DNS_DSDIGEST_SHA384)); #endif } diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index a94abff0..12822bed 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -56,6 +56,9 @@ #include <isc/string.h> #include <isc/time.h> #include <isc/util.h> +#include <isc/file.h> + +#define DST_KEY_INTERNAL #include <dns/fixedname.h> #include <dns/keyvalues.h> @@ -227,6 +230,10 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, #ifdef HAVE_OPENSSL_GOST RETERR(dst__opensslgost_init(&dst_t_func[DST_ALG_ECCGOST])); #endif +#ifdef HAVE_OPENSSL_ECDSA + RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA256])); + RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); +#endif #endif /* OPENSSL */ #ifdef GSSAPI RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI])); @@ -359,6 +366,25 @@ dst_context_verify(dst_context_t *dctx, isc_region_t *sig) { } isc_result_t +dst_context_verify2(dst_context_t *dctx, unsigned int maxbits, + isc_region_t *sig) +{ + REQUIRE(VALID_CTX(dctx)); + REQUIRE(sig != NULL); + + CHECKALG(dctx->key->key_alg); + if (dctx->key->keydata.generic == NULL) + return (DST_R_NULLKEY); + if (dctx->key->func->verify == NULL && + dctx->key->func->verify2 == NULL) + return (DST_R_NOTPUBLICKEY); + + return (dctx->key->func->verify2 != NULL ? + dctx->key->func->verify2(dctx, maxbits, sig) : + dctx->key->func->verify(dctx, sig)); +} + +isc_result_t dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret) { @@ -736,6 +762,40 @@ out: } isc_result_t +dst_key_buildinternal(dns_name_t *name, unsigned int alg, + unsigned int bits, unsigned int flags, + unsigned int protocol, dns_rdataclass_t rdclass, + void *data, isc_mem_t *mctx, dst_key_t **keyp) +{ + dst_key_t *key; + isc_result_t result; + + REQUIRE(dst_initialized == ISC_TRUE); + REQUIRE(dns_name_isabsolute(name)); + REQUIRE(mctx != NULL); + REQUIRE(keyp != NULL && *keyp == NULL); + REQUIRE(data != NULL); + + CHECKALG(alg); + + key = get_key_struct(name, alg, flags, protocol, bits, rdclass, + 0, mctx); + if (key == NULL) + return (ISC_R_NOMEMORY); + + key->keydata.generic = data; + + result = computeid(key); + if (result != ISC_R_SUCCESS) { + dst_key_free(&key); + return (result); + } + + *keyp = key; + return (ISC_R_SUCCESS); +} + +isc_result_t dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, const char *engine, const char *label, const char *pin, @@ -1112,6 +1172,12 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) { case DST_ALG_ECCGOST: *n = DNS_SIG_GOSTSIGSIZE; break; + case DST_ALG_ECDSA256: + *n = DNS_SIG_ECDSA256SIZE; + break; + case DST_ALG_ECDSA384: + *n = DNS_SIG_ECDSA384SIZE; + break; case DST_ALG_HMACMD5: *n = 16; break; @@ -1420,6 +1486,8 @@ issymmetric(const dst_key_t *key) { case DST_ALG_NSEC3DSA: case DST_ALG_DH: case DST_ALG_ECCGOST: + case DST_ALG_ECDSA256: + case DST_ALG_ECDSA384: return (ISC_FALSE); case DST_ALG_HMACMD5: case DST_ALG_GSSAPI: @@ -1698,7 +1766,8 @@ algorithm_status(unsigned int alg) { alg == DST_ALG_HMACMD5 || alg == DST_ALG_NSEC3DSA || alg == DST_ALG_NSEC3RSASHA1 || alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512 || - alg == DST_ALG_ECCGOST) + alg == DST_ALG_ECCGOST || + alg == DST_ALG_ECDSA256 || alg == DST_ALG_ECDSA384) return (DST_R_NOCRYPTO); #endif return (DST_R_UNSUPPORTEDALG); diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h index f2906d75..d9d75672 100644 --- a/lib/dns/dst_internal.h +++ b/lib/dns/dst_internal.h @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -170,6 +170,8 @@ struct dst_func { */ isc_result_t (*sign)(dst_context_t *dctx, isc_buffer_t *sig); isc_result_t (*verify)(dst_context_t *dctx, const isc_region_t *sig); + isc_result_t (*verify2)(dst_context_t *dctx, int maxbits, + const isc_region_t *sig); isc_result_t (*computesecret)(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret); @@ -218,6 +220,9 @@ isc_result_t dst__gssapi_init(struct dst_func **funcp); #ifdef HAVE_OPENSSL_GOST isc_result_t dst__opensslgost_init(struct dst_func **funcp); #endif +#ifdef HAVE_OPENSSL_ECDSA +isc_result_t dst__opensslecdsa_init(struct dst_func **funcp); +#endif /*% * Destructors diff --git a/lib/dns/dst_openssl.h b/lib/dns/dst_openssl.h index cc9929fc..22071c08 100644 --- a/lib/dns/dst_openssl.h +++ b/lib/dns/dst_openssl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -39,6 +39,9 @@ ISC_LANG_BEGINDECLS isc_result_t dst__openssl_toresult(isc_result_t fallback); +isc_result_t +dst__openssl_toresult2(const char *funcname, isc_result_t fallback); + #ifdef USE_ENGINE ENGINE * dst__openssl_getengine(const char *engine); diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c index ee513d55..ca43cb3d 100644 --- a/lib/dns/dst_parse.c +++ b/lib/dns/dst_parse.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -44,8 +44,10 @@ #include <isc/stdtime.h> #include <isc/string.h> #include <isc/util.h> +#include <isc/file.h> #include <dns/time.h> +#include <dns/log.h> #include "dst_internal.h" #include "dst_parse.h" @@ -106,6 +108,8 @@ static struct parse_map map[] = { {TAG_GOST_PRIVASN1, "GostAsn1:"}, + {TAG_ECDSA_PRIVATEKEY, "PrivateKey:"}, + {TAG_HMACMD5_KEY, "Key:"}, {TAG_HMACMD5_BITS, "Bits:"}, @@ -251,6 +255,15 @@ check_gost(const dst_private_t *priv) { } static int +check_ecdsa(const dst_private_t *priv) { + if (priv->nelements != ECDSA_NTAGS) + return (-1); + if (priv->elements[0].tag != TAG(DST_ALG_ECDSA256, 0)) + return (-1); + return (0); +} + +static int check_hmac_md5(const dst_private_t *priv, isc_boolean_t old) { int i, j; @@ -302,13 +315,20 @@ check_data(const dst_private_t *priv, const unsigned int alg, switch (alg) { case DST_ALG_RSAMD5: case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + case DST_ALG_RSASHA256: + case DST_ALG_RSASHA512: return (check_rsa(priv)); case DST_ALG_DH: return (check_dh(priv)); case DST_ALG_DSA: + case DST_ALG_NSEC3DSA: return (check_dsa(priv)); case DST_ALG_ECCGOST: return (check_gost(priv)); + case DST_ALG_ECDSA256: + case DST_ALG_ECDSA384: + return (check_ecdsa(priv)); case DST_ALG_HMACMD5: return (check_hmac_md5(priv, old)); case DST_ALG_HMACSHA1: @@ -345,7 +365,7 @@ isc_result_t dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, isc_mem_t *mctx, dst_private_t *priv) { - int n = 0, major, minor; + int n = 0, major, minor, check; isc_buffer_t b; isc_token_t token; unsigned char *data = NULL; @@ -515,8 +535,14 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, data = NULL; } done: - if (check_data(priv, alg, ISC_TRUE) < 0) + check = check_data(priv, alg, ISC_TRUE); + if (check < 0) { + ret = DST_R_INVALIDPRIVATEKEY; + goto fail; + } else if (check != ISC_R_SUCCESS) { + ret = check; goto fail; + } return (ISC_R_SUCCESS); @@ -533,7 +559,6 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, const char *directory) { FILE *fp; - int ret, i; isc_result_t result; char filename[ISC_DIR_NAMEMAX]; char buffer[MAXFIELDSIZE * 2]; @@ -543,16 +568,32 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, isc_buffer_t b; isc_region_t r; int major, minor; + mode_t mode; + int i, ret; REQUIRE(priv != NULL); - if (check_data(priv, dst_key_alg(key), ISC_FALSE) < 0) + ret = check_data(priv, dst_key_alg(key), ISC_FALSE); + if (ret < 0) return (DST_R_INVALIDPRIVATEKEY); + else if (ret != ISC_R_SUCCESS) + return (ret); isc_buffer_init(&b, filename, sizeof(filename)); - ret = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b); - if (ret != ISC_R_SUCCESS) - return (ret); + result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b); + if (result != ISC_R_SUCCESS) + return (result); + + result = isc_file_mode(filename, &mode); + if (result == ISC_R_SUCCESS && mode != 0600) { + /* File exists; warn that we are changing its permissions */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, + "Permissions on the file %s " + "have changed from 0%o to 0600 as " + "a result of this operation.", + filename, (unsigned int)mode); + } if ((fp = fopen(filename, "w")) == NULL) return (DST_R_WRITEERROR); @@ -603,6 +644,12 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, case DST_ALG_ECCGOST: fprintf(fp, "(ECC-GOST)\n"); break; + case DST_ALG_ECDSA256: + fprintf(fp, "(ECDSAP256SHA256)\n"); + break; + case DST_ALG_ECDSA384: + fprintf(fp, "(ECDSAP384SHA384)\n"); + break; case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break; diff --git a/lib/dns/dst_parse.h b/lib/dns/dst_parse.h index 91b072fb..f048bf0c 100644 --- a/lib/dns/dst_parse.h +++ b/lib/dns/dst_parse.h @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -81,6 +81,9 @@ #define GOST_NTAGS 1 #define TAG_GOST_PRIVASN1 ((DST_ALG_ECCGOST << TAG_SHIFT) + 0) +#define ECDSA_NTAGS 1 +#define TAG_ECDSA_PRIVATEKEY ((DST_ALG_ECDSA256 << TAG_SHIFT) + 0) + #define OLD_HMACMD5_NTAGS 1 #define HMACMD5_NTAGS 2 #define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0) diff --git a/lib/dns/dst_result.c b/lib/dns/dst_result.c index 429dbb2f..297e809c 100644 --- a/lib/dns/dst_result.c +++ b/lib/dns/dst_result.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -30,7 +30,7 @@ static const char *text[DST_R_NRESULTS] = { "algorithm is unsupported", /*%< 0 */ - "openssl failure", /*%< 1 */ + "crypto failure", /*%< 1 */ "built with no crypto support", /*%< 2 */ "illegal operation for a null key", /*%< 3 */ "public key is invalid", /*%< 4 */ diff --git a/lib/dns/gssapi_link.c b/lib/dns/gssapi_link.c index 381ba102..5ad81cd8 100644 --- a/lib/dns/gssapi_link.c +++ b/lib/dns/gssapi_link.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -362,6 +362,7 @@ static dst_func_t gssapi_functions = { gssapi_adddata, gssapi_sign, gssapi_verify, + NULL, /*%< verify2 */ NULL, /*%< computesecret */ gssapi_compare, NULL, /*%< paramcompare */ diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c index bc0e9a04..256abb6e 100644 --- a/lib/dns/hmac_link.c +++ b/lib/dns/hmac_link.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -313,6 +313,7 @@ static dst_func_t hmacmd5_functions = { hmacmd5_adddata, hmacmd5_sign, hmacmd5_verify, + NULL, /*%< verify2 */ NULL, /*%< computesecret */ hmacmd5_compare, NULL, /*%< paramcompare */ @@ -589,6 +590,7 @@ static dst_func_t hmacsha1_functions = { hmacsha1_adddata, hmacsha1_sign, hmacsha1_verify, + NULL, /* verify2 */ NULL, /* computesecret */ hmacsha1_compare, NULL, /* paramcompare */ @@ -867,6 +869,7 @@ static dst_func_t hmacsha224_functions = { hmacsha224_adddata, hmacsha224_sign, hmacsha224_verify, + NULL, /* verify2 */ NULL, /* computesecret */ hmacsha224_compare, NULL, /* paramcompare */ @@ -1145,6 +1148,7 @@ static dst_func_t hmacsha256_functions = { hmacsha256_adddata, hmacsha256_sign, hmacsha256_verify, + NULL, /* verify2 */ NULL, /* computesecret */ hmacsha256_compare, NULL, /* paramcompare */ @@ -1423,6 +1427,7 @@ static dst_func_t hmacsha384_functions = { hmacsha384_adddata, hmacsha384_sign, hmacsha384_verify, + NULL, /* verify2 */ NULL, /* computesecret */ hmacsha384_compare, NULL, /* paramcompare */ @@ -1701,6 +1706,7 @@ static dst_func_t hmacsha512_functions = { hmacsha512_adddata, hmacsha512_sign, hmacsha512_verify, + NULL, /* verify2 */ NULL, /* computesecret */ hmacsha512_compare, NULL, /* paramcompare */ diff --git a/lib/dns/include/Makefile.in b/lib/dns/include/Makefile.in index b52cb980..10d798d9 100644 --- a/lib/dns/include/Makefile.in +++ b/lib/dns/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/dns/include/dns/Makefile.in b/lib/dns/include/dns/Makefile.in index 5b2e78d0..1a69f2c8 100644 --- a/lib/dns/include/dns/Makefile.in +++ b/lib/dns/include/dns/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007-2009, 2011 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index 48b5a26e..a5edbce2 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.h,v 1.107 2011/10/13 01:32:34 vjs Exp $ */ +/* $Id: db.h,v 1.107.4.1 2011/10/23 20:12:08 vjs Exp $ */ #ifndef DNS_DB_H #define DNS_DB_H 1 @@ -173,7 +173,7 @@ typedef struct dns_dbmethods { isc_boolean_t (*isdnssec)(dns_db_t *db); dns_stats_t *(*getrrsetstats)(dns_db_t *db); void (*rpz_enabled)(dns_db_t *db, dns_rpz_st_t *st); - isc_result_t (*rpz_findips)(dns_rpz_zone_t *rpz, + void (*rpz_findips)(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, @@ -770,6 +770,10 @@ dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * that it is correct. This only affects answers returned from the * cache. * + * \li In the #DNS_DBFIND_FORCENSEC3 option is set, then we are looking + * in the NSEC3 tree and not the main tree. Without this option being + * set NSEC3 records will not be found. + * * \li To respond to a query for SIG records, the caller should create a * rdataset iterator and extract the signatures from each rdataset. * @@ -1545,7 +1549,7 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st); * DNS_RPZ_TYPE_NSDNAME records. */ -isc_result_t +void dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_rdataset_t *ardataset, dns_rpz_st_t *st, @@ -1562,10 +1566,6 @@ dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, * \li 'ardataset' is an A or AAAA rdataset of addresses to check * \li 'found' specifies the previous best match if any or * or NULL, an empty name, 0, DNS_RPZ_POLICY_MISS, and 0 - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_UNEXPECTED */ ISC_LANG_ENDDECLS diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h index 68df540a..e443f91b 100644 --- a/lib/dns/include/dns/dnssec.h +++ b/lib/dns/include/dns/dnssec.h @@ -24,6 +24,7 @@ #include <isc/lang.h> #include <isc/stdtime.h> +#include <isc/stats.h> #include <dns/diff.h> #include <dns/types.h> @@ -32,6 +33,8 @@ ISC_LANG_BEGINDECLS +LIBDNS_EXTERNAL_DATA extern isc_stats_t *dns_dnssec_stats; + /*%< Maximum number of keys supported in a zone. */ #define DNS_MAXZONEKEYS 32 @@ -96,8 +99,8 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_stdtime_t *inception, isc_stdtime_t *expire, isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata); /*%< - * Generates a SIG record covering this rdataset. This has no effect - * on existing SIG records. + * Generates a RRSIG record covering this rdataset. This has no effect + * on existing RRSIG records. * * Requires: *\li 'name' (the owner name of the record) is a valid name @@ -129,12 +132,19 @@ isc_result_t dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild); + +isc_result_t +dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, + isc_boolean_t ignoretime, unsigned int maxbits, + isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild); /*%< - * Verifies the SIG record covering this rdataset signed by a specific - * key. This does not determine if the key's owner is authorized to - * sign this record, as this requires a resolver or database. + * Verifies the RRSIG record covering this rdataset signed by a specific + * key. This does not determine if the key's owner is authorized to sign + * this record, as this requires a resolver or database. * If 'ignoretime' is ISC_TRUE, temporal validity will not be checked. * + * 'maxbits' specifies the maximum number of rsa exponent bits accepted. + * * Requires: *\li 'name' (the owner name of the record) is a valid name *\li 'set' is a valid rdataset diff --git a/lib/dns/include/dns/ds.h b/lib/dns/include/dns/ds.h index b20b4086..03ab0ed0 100644 --- a/lib/dns/include/dns/ds.h +++ b/lib/dns/include/dns/ds.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -27,15 +27,16 @@ #define DNS_DSDIGEST_SHA1 (1) #define DNS_DSDIGEST_SHA256 (2) #define DNS_DSDIGEST_GOST (3) +#define DNS_DSDIGEST_SHA384 (4) /* should not be here... */ #define ISC_GOST_DIGESTLENGTH 32U /* - * Assuming SHA-256 digest type. + * Assuming SHA-384 digest type. */ -#define DNS_DS_BUFFERSIZE (36) +#define DNS_DS_BUFFERSIZE (52) ISC_LANG_BEGINDECLS diff --git a/lib/dns/include/dns/iptable.h b/lib/dns/include/dns/iptable.h index d7eb140d..2ce8e181 100644 --- a/lib/dns/include/dns/iptable.h +++ b/lib/dns/include/dns/iptable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,6 +23,8 @@ #include <isc/magic.h> #include <isc/radix.h> +#include <dns/types.h> + struct dns_iptable { unsigned int magic; isc_mem_t *mctx; diff --git a/lib/dns/include/dns/keyvalues.h b/lib/dns/include/dns/keyvalues.h index 55c0b8fc..0c392ca1 100644 --- a/lib/dns/include/dns/keyvalues.h +++ b/lib/dns/include/dns/keyvalues.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -71,6 +71,8 @@ #define DNS_KEYALG_RSASHA256 8 #define DNS_KEYALG_RSASHA512 10 #define DNS_KEYALG_ECCGOST 12 +#define DNS_KEYALG_ECDSA256 13 +#define DNS_KEYALG_ECDSA384 14 #define DNS_KEYALG_INDIRECT 252 #define DNS_KEYALG_PRIVATEDNS 253 #define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */ @@ -101,4 +103,10 @@ #define DNS_SIG_GOSTSIGSIZE 64 +#define DNS_SIG_ECDSA256SIZE 64 +#define DNS_SIG_ECDSA384SIZE 96 + +#define DNS_KEY_ECDSA256SIZE 64 +#define DNS_KEY_ECDSA384SIZE 96 + #endif /* DNS_KEYVALUES_H */ diff --git a/lib/dns/include/dns/log.h b/lib/dns/include/dns/log.h index 2060a33c..3c4df8a4 100644 --- a/lib/dns/include/dns/log.h +++ b/lib/dns/include/dns/log.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -75,6 +75,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[]; #define DNS_LOGMODULE_ACACHE (&dns_modules[25]) #define DNS_LOGMODULE_DLZ (&dns_modules[26]) #define DNS_LOGMODULE_DNSSEC (&dns_modules[27]) +#define DNS_LOGMODULE_CRYPTO (&dns_modules[28]) ISC_LANG_BEGINDECLS diff --git a/lib/dns/include/dns/nsec.h b/lib/dns/include/dns/nsec.h index fca843a1..bdcd2eec 100644 --- a/lib/dns/include/dns/nsec.h +++ b/lib/dns/include/dns/nsec.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -76,6 +76,28 @@ dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version, * 'answer' to be non NULL. */ +unsigned int +dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw, + unsigned int max_type); +/*%< + * Convert a raw bitmap into a compressed windowed bit map. 'map' and 'raw' + * may overlap. + * + * Returns the length of the compressed windowed bit map. + */ + +void +dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit); +/*%< + * Set type bit in raw 'array' to 'bit'. + */ + +isc_boolean_t +dns_nsec_isset(const unsigned char *array, unsigned int type); +/*%< + * Test if the corresponding 'type' bit is set in 'array'. + */ + ISC_LANG_ENDDECLS #endif /* DNS_NSEC_H */ diff --git a/lib/dns/include/dns/private.h b/lib/dns/include/dns/private.h index 91fff5f7..c4a2ae64 100644 --- a/lib/dns/include/dns/private.h +++ b/lib/dns/include/dns/private.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -51,15 +51,15 @@ dns_private_chains(dns_db_t *db, dns_dbversion_t *ver, */ isc_result_t -dns_private_totext(dns_rdata_t *private, isc_buffer_t *buffer); +dns_private_totext(dns_rdata_t *privaterdata, isc_buffer_t *buffer); /*%< - * Convert a private-type RR 'private' to human-readable form, + * Convert a private-type RR 'privaterdata' to human-readable form, * and place the result in 'buffer'. The text should indicate * which action the private-type record specifies and whether the * action has been completed. * * Requires: - * \li 'private' is a valid rdata containing at least five bytes + * \li 'privaterdata' is a valid rdata containing at least five bytes * \li 'buffer' is a valid buffer * * Returns: diff --git a/lib/dns/include/dns/rdata.h b/lib/dns/include/dns/rdata.h index a82b03b1..2c7b2730 100644 --- a/lib/dns/include/dns/rdata.h +++ b/lib/dns/include/dns/rdata.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h index f6a55e3b..31bcd15f 100644 --- a/lib/dns/include/dns/rdataset.h +++ b/lib/dns/include/dns/rdataset.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -56,6 +56,7 @@ #include <isc/stdtime.h> #include <dns/types.h> +#include <dns/rdatastruct.h> ISC_LANG_BEGINDECLS @@ -651,6 +652,25 @@ dns_rdataset_expire(dns_rdataset_t *rdataset); * Mark the rdataset to be expired in the backing database. */ +void +dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, + dns_rdata_rrsig_t *rrsig, isc_stdtime_t now, + isc_boolean_t acceptexpired); +/*%< + * Trim the ttl of 'rdataset' and 'sigrdataset' so that they will expire + * at or before 'rrsig->expiretime'. If 'acceptexpired' is true and the + * signature has expired or will expire in the next 120 seconds, limit + * the ttl to be no more than 120 seconds. + * + * The ttl is further limited by the original ttl as stored in 'rrsig' + * and the original ttl values of 'rdataset' and 'sigrdataset'. + * + * Requires: + * \li 'rdataset' is a valid rdataset. + * \li 'sigrdataset' is a valid rdataset. + * \li 'rrsig' is non NULL. + */ + const char * dns_trust_totext(dns_trust_t trust); /* diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h index accec2ab..03db8d33 100644 --- a/lib/dns/include/dns/rpz.h +++ b/lib/dns/include/dns/rpz.h @@ -30,6 +30,7 @@ ISC_LANG_BEGINDECLS #define DNS_RPZ_IP_ZONE "rpz-ip" #define DNS_RPZ_NSIP_ZONE "rpz-nsip" #define DNS_RPZ_NSDNAME_ZONE "rpz-nsdname" +#define DNS_RPZ_PASSTHRU_ZONE "rpz-passthru" typedef isc_uint8_t dns_rpz_cidr_bits_t; @@ -66,11 +67,14 @@ typedef struct dns_rpz_zone dns_rpz_zone_t; struct dns_rpz_zone { ISC_LINK(dns_rpz_zone_t) link; - int num; + int num; /* ordinal in list of policy zones */ dns_name_t origin; /* Policy zone name */ dns_name_t nsdname; /* DNS_RPZ_NSDNAME_ZONE.origin */ - dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */ + dns_name_t passthru;/* DNS_RPZ_PASSTHRU_ZONE. */ dns_name_t cname; /* override value for ..._CNAME */ + dns_ttl_t max_policy_ttl; + dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */ + isc_boolean_t recursive_only; }; /* @@ -143,6 +147,7 @@ typedef struct { } dns_rpz_st_t; #define DNS_RPZ_TTL_DEFAULT 5 +#define DNS_RPZ_MAX_TTL_DEFAULT DNS_RPZ_TTL_DEFAULT /* * So various response policy zone messages can be turned up or down. @@ -152,6 +157,7 @@ typedef struct { #define DNS_RPZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1) #define DNS_RPZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2) #define DNS_RPZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3) +#define DNS_RPZ_DEBUG_QUIET (DNS_RPZ_DEBUG_LEVEL3+1) const char * dns_rpz_type2str(dns_rpz_type_t type); @@ -192,7 +198,8 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr, dns_name_t *search_name, dns_rpz_cidr_bits_t *prefix); dns_rpz_policy_t -dns_rpz_decode_cname(dns_rdataset_t *, dns_name_t *selfname); +dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset, + dns_name_t *selfname); ISC_LANG_ENDDECLS diff --git a/lib/dns/include/dns/stats.h b/lib/dns/include/dns/stats.h index bc77d1e9..53642672 100644 --- a/lib/dns/include/dns/stats.h +++ b/lib/dns/include/dns/stats.h @@ -64,6 +64,16 @@ enum { dns_resstatscounter_max = 30, + /* + * DNSSEC stats. + */ + dns_dnssecstats_asis = 0, + dns_dnssecstats_downcase = 1, + dns_dnssecstats_wildcard = 2, + dns_dnssecstats_fail = 3, + + dns_dnssecstats_max = 4, + /*% * Zone statistics counters. */ diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 3d652436..16f8d7a1 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -157,11 +157,14 @@ struct dns_view { dns_name_t * dlv; dns_fixedname_t dlv_fixed; isc_uint16_t maxudp; + unsigned int maxbits; dns_v4_aaaa_t v4_aaaa; dns_acl_t * v4_aaaa_acl; dns_dns64list_t dns64; unsigned int dns64cnt; ISC_LIST(dns_rpz_zone_t) rpz_zones; + isc_boolean_t rpz_recursive_only; + isc_boolean_t rpz_break_dnssec; /* * Configurable data for server use only, diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index e7c754f2..8f32bae4 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -1861,7 +1861,7 @@ dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures); isc_result_t dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, - isc_uint16_t keyid, isc_boolean_t delete); + isc_uint16_t keyid, isc_boolean_t deleteit); /*%< * Initiate/resume signing of the entire zone with the zone DNSKEY(s) * that match the given algorithm and keyid. diff --git a/lib/dns/include/dst/Makefile.in b/lib/dns/include/dst/Makefile.in index 4ed4ec04..cece67dd 100644 --- a/lib/dns/include/dst/Makefile.in +++ b/lib/dns/include/dst/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h index 7a1d938d..66501df4 100644 --- a/lib/dns/include/dst/dst.h +++ b/lib/dns/include/dst/dst.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -59,6 +59,8 @@ typedef struct dst_context dst_context_t; #define DST_ALG_RSASHA256 8 #define DST_ALG_RSASHA512 10 #define DST_ALG_ECCGOST 12 +#define DST_ALG_ECDSA256 13 +#define DST_ALG_ECDSA384 14 #define DST_ALG_HMACMD5 157 #define DST_ALG_GSSAPI 160 #define DST_ALG_HMACSHA1 161 /* XXXMPA */ @@ -231,9 +233,16 @@ dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig); isc_result_t dst_context_verify(dst_context_t *dctx, isc_region_t *sig); + +isc_result_t +dst_context_verify2(dst_context_t *dctx, unsigned int maxbits, + isc_region_t *sig); /*%< * Verifies the signature using the data and key stored in the context. * + * 'maxbits' specifies the maximum number of bits permitted in the RSA + * exponent. + * * Requires: * \li "dctx" is a valid context. * \li "sig" is a valid region. @@ -490,6 +499,14 @@ dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx, * the context id. */ +#ifdef DST_KEY_INTERNAL +isc_result_t +dst_key_buildinternal(dns_name_t *name, unsigned int alg, + unsigned int bits, unsigned int flags, + unsigned int protocol, dns_rdataclass_t rdclass, + void *data, isc_mem_t *mctx, dst_key_t **keyp); +#endif + isc_result_t dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, @@ -510,6 +527,7 @@ dst_key_generate2(dns_name_t *name, unsigned int alg, dns_rdataclass_t rdclass, isc_mem_t *mctx, dst_key_t **keyp, void (*callback)(int)); + /*%< * Generate a DST key (or keypair) with the supplied parameters. The * interpretation of the "param" field depends on the algorithm: diff --git a/lib/dns/include/dst/result.h b/lib/dns/include/dst/result.h index d77b72e7..00640a1b 100644 --- a/lib/dns/include/dst/result.h +++ b/lib/dns/include/dst/result.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -34,7 +34,9 @@ #include <isc/result.h> /* Contractual promise. */ #define DST_R_UNSUPPORTEDALG (ISC_RESULTCLASS_DST + 0) -#define DST_R_OPENSSLFAILURE (ISC_RESULTCLASS_DST + 1) +#define DST_R_CRYPTOFAILURE (ISC_RESULTCLASS_DST + 1) +/* compat */ +#define DST_R_OPENSSLFAILURE DST_R_CRYPTOFAILURE #define DST_R_NOCRYPTO (ISC_RESULTCLASS_DST + 2) #define DST_R_NULLKEY (ISC_RESULTCLASS_DST + 3) #define DST_R_INVALIDPUBLICKEY (ISC_RESULTCLASS_DST + 4) diff --git a/lib/dns/log.c b/lib/dns/log.c index e6fbb53a..c4d644e3 100644 --- a/lib/dns/log.c +++ b/lib/dns/log.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -81,6 +81,7 @@ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = { { "dns/acache", 0 }, { "dns/dlz", 0 }, { "dns/dnssec", 0 }, + { "dns/crypto", 0 }, { NULL, 0 } }; diff --git a/lib/dns/master.c b/lib/dns/master.c index 7b1ccdf8..a8a456d7 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -2078,20 +2078,22 @@ load_raw(dns_loadctx_t *lctx) { unsigned int loop_cnt = 0; dns_rdatacallbacks_t *callbacks; unsigned char namebuf[DNS_NAME_MAXWIRE]; - isc_region_t r; - dns_name_t name; + dns_fixedname_t fixed; + dns_name_t *name; rdatalist_head_t head, dummy; dns_rdatalist_t rdatalist; isc_mem_t *mctx = lctx->mctx; dns_rdata_t *rdata = NULL; unsigned int rdata_size = 0; int target_size = TSIZ; - isc_buffer_t target; + isc_buffer_t target, buf; unsigned char *target_mem = NULL; dns_masterrawheader_t header; + dns_decompress_t dctx; REQUIRE(DNS_LCTX_VALID(lctx)); callbacks = lctx->callbacks; + dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); dns_master_initrawheader(&header); @@ -2171,6 +2173,9 @@ load_raw(dns_loadctx_t *lctx) { } isc_buffer_init(&target, target_mem, target_size); + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + /* * In the following loop, we regard any error fatal regardless of * whether "MANYERRORS" is set in the context option. This is because @@ -2182,7 +2187,7 @@ load_raw(dns_loadctx_t *lctx) { for (loop_cnt = 0; (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt); loop_cnt++) { - unsigned int i, rdcount, consumed_name; + unsigned int i, rdcount; isc_uint16_t namelen; isc_uint32_t totallen; size_t minlen, readlen; @@ -2272,12 +2277,11 @@ load_raw(dns_loadctx_t *lctx) { lctx->f); if (result != ISC_R_SUCCESS) goto cleanup; + isc_buffer_setactive(&target, (unsigned int)namelen); - isc_buffer_activeregion(&target, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - isc_buffer_forward(&target, (unsigned int)namelen); - consumed_name = isc_buffer_consumedlength(&target); + result = dns_name_fromwire(name, &target, &dctx, 0, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; /* Rdata contents. */ if (rdcount > rdata_size) { @@ -2308,7 +2312,7 @@ load_raw(dns_loadctx_t *lctx) { /* Partial Commit. */ ISC_LIST_APPEND(head, &rdatalist, link); - result = commit(callbacks, lctx, &head, &name, + result = commit(callbacks, lctx, &head, name, NULL, 0); for (j = 0; j < i; j++) { ISC_LIST_UNLINK(rdatalist.rdata, @@ -2320,8 +2324,6 @@ load_raw(dns_loadctx_t *lctx) { /* Rewind the buffer and continue */ isc_buffer_clear(&target); - isc_buffer_add(&target, consumed_name); - isc_buffer_forward(&target, consumed_name); rdcount -= i; @@ -2341,11 +2343,20 @@ load_raw(dns_loadctx_t *lctx) { if (result != ISC_R_SUCCESS) goto cleanup; isc_buffer_setactive(&target, (unsigned int)rdlen); - isc_buffer_activeregion(&target, &r); - isc_buffer_forward(&target, (unsigned int)rdlen); - dns_rdata_fromregion(&rdata[i], rdatalist.rdclass, - rdatalist.type, &r); - + /* + * It is safe to have the source active region and + * the target available region be the same if + * decompression is disabled (see dctx above) and we + * are not downcasing names (options == 0). + */ + isc_buffer_init(&buf, isc_buffer_current(&target), + (unsigned int)rdlen); + result = dns_rdata_fromwire(&rdata[i], + rdatalist.rdclass, + rdatalist.type, &target, + &dctx, 0, &buf); + if (result != ISC_R_SUCCESS) + goto cleanup; ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link); } @@ -2362,7 +2373,7 @@ load_raw(dns_loadctx_t *lctx) { ISC_LIST_APPEND(head, &rdatalist, link); /* Commit this RRset. rdatalist will be unlinked. */ - result = commit(callbacks, lctx, &head, &name, NULL, 0); + result = commit(callbacks, lctx, &head, name, NULL, 0); for (i = 0; i < rdcount; i++) { ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link); diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c index e800715e..2717658e 100644 --- a/lib/dns/masterdump.c +++ b/lib/dns/masterdump.c @@ -1614,7 +1614,8 @@ dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db, } static isc_result_t -opentmp(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) { +opentmp(isc_mem_t *mctx, dns_masterformat_t format, const char *file, + char **tempp, FILE **fp) { FILE *f = NULL; isc_result_t result; char *tempname = NULL; @@ -1629,7 +1630,10 @@ opentmp(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) { if (result != ISC_R_SUCCESS) goto cleanup; - result = isc_file_openunique(tempname, &f); + if (format == dns_masterformat_text) + result = isc_file_openunique(tempname, &f); + else + result = isc_file_bopenunique(tempname, &f); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, @@ -1684,7 +1688,7 @@ dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, if (file == NULL) return (ISC_R_NOMEMORY); - result = opentmp(mctx, filename, &tempname, &f); + result = opentmp(mctx, format, filename, &tempname, &f); if (result != ISC_R_SUCCESS) goto cleanup; @@ -1748,7 +1752,7 @@ dns_master_dump3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, char *tempname; dns_dumpctx_t *dctx = NULL; - result = opentmp(mctx, filename, &tempname, &f); + result = opentmp(mctx, format, filename, &tempname, &f); if (result != ISC_R_SUCCESS) return (result); diff --git a/lib/dns/nsec.c b/lib/dns/nsec.c index 6e3a69ab..69207d09 100644 --- a/lib/dns/nsec.c +++ b/lib/dns/nsec.c @@ -41,28 +41,61 @@ goto failure; \ } while (0) -static void -set_bit(unsigned char *array, unsigned int index, unsigned int bit) { +void +dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit) { unsigned int shift, mask; - shift = 7 - (index % 8); + shift = 7 - (type % 8); mask = 1 << shift; if (bit != 0) - array[index / 8] |= mask; + array[type / 8] |= mask; else - array[index / 8] &= (~mask & 0xFF); + array[type / 8] &= (~mask & 0xFF); } -static unsigned int -bit_isset(unsigned char *array, unsigned int index) { +isc_boolean_t +dns_nsec_isset(const unsigned char *array, unsigned int type) { unsigned int byte, shift, mask; - byte = array[index / 8]; - shift = 7 - (index % 8); + byte = array[type / 8]; + shift = 7 - (type % 8); mask = 1 << shift; - return ((byte & mask) != 0); + return (ISC_TF(byte & mask)); +} + +unsigned int +dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw, + unsigned int max_type) +{ + unsigned char *start = map; + unsigned int window; + int octet; + + if (raw == NULL) + return (0); + + for (window = 0; window < 256; window++) { + if (window * 256 > max_type) + break; + for (octet = 31; octet >= 0; octet--) + if (*(raw + octet) != 0) + break; + if (octet < 0) { + raw += 32; + continue; + } + *map++ = window; + *map++ = octet + 1; + /* + * Note: potential overlapping move. + */ + memmove(map, raw, octet + 1); + map += octet + 1; + raw += 32; + } + return (map - start); } isc_result_t @@ -73,8 +106,7 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, isc_result_t result; dns_rdataset_t rdataset; isc_region_t r; - unsigned int i, window; - int octet; + unsigned int i; unsigned char *nsec_bits, *bm; unsigned int max_type; @@ -90,8 +122,8 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, */ bm = r.base + r.length + 512; nsec_bits = r.base + r.length; - set_bit(bm, dns_rdatatype_rrsig, 1); - set_bit(bm, dns_rdatatype_nsec, 1); + dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1); + dns_nsec_setbit(bm, dns_rdatatype_nsec, 1); max_type = dns_rdatatype_nsec; dns_rdataset_init(&rdataset); rdsiter = NULL; @@ -108,7 +140,7 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, rdataset.type != dns_rdatatype_rrsig) { if (rdataset.type > max_type) max_type = rdataset.type; - set_bit(bm, rdataset.type, 1); + dns_nsec_setbit(bm, rdataset.type, 1); } dns_rdataset_disassociate(&rdataset); } @@ -116,12 +148,12 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, /* * At zone cuts, deny the existence of glue in the parent zone. */ - if (bit_isset(bm, dns_rdatatype_ns) && - ! bit_isset(bm, dns_rdatatype_soa)) { + if (dns_nsec_isset(bm, dns_rdatatype_ns) && + ! dns_nsec_isset(bm, dns_rdatatype_soa)) { for (i = 0; i <= max_type; i++) { - if (bit_isset(bm, i) && + if (dns_nsec_isset(bm, i) && ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i)) - set_bit(bm, i, 0); + dns_nsec_setbit(bm, i, 0); } } @@ -129,22 +161,8 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, if (result != ISC_R_NOMORE) return (result); - for (window = 0; window < 256; window++) { - if (window * 256 > max_type) - break; - for (octet = 31; octet >= 0; octet--) - if (bm[window * 32 + octet] != 0) - break; - if (octet < 0) - continue; - nsec_bits[0] = window; - nsec_bits[1] = octet + 1; - /* - * Note: potential overlapping move. - */ - memmove(&nsec_bits[2], &bm[window * 32], octet + 1); - nsec_bits += 3 + octet; - } + nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type); + r.length = nsec_bits - r.base; INSIST(r.length <= DNS_NSEC_BUFFERSIZE); dns_rdata_fromregion(rdata, @@ -155,7 +173,6 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, return (ISC_R_SUCCESS); } - isc_result_t dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *target, dns_ttl_t ttl) @@ -216,8 +233,8 @@ dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type) { if ((window + 1) * 256 <= type) continue; if (type < (window * 256) + len * 8) - present = ISC_TF(bit_isset(&nsecstruct.typebits[i], - type % 256)); + present = ISC_TF(dns_nsec_isset(&nsecstruct.typebits[i], + type % 256)); break; } dns_rdata_freestruct(&nsecstruct); diff --git a/lib/dns/nsec3.c b/lib/dns/nsec3.c index 44cc6527..4975bf31 100644 --- a/lib/dns/nsec3.c +++ b/lib/dns/nsec3.c @@ -33,6 +33,7 @@ #include <dns/dbiterator.h> #include <dns/diff.h> #include <dns/fixedname.h> +#include <dns/nsec.h> #include <dns/nsec3.h> #include <dns/rdata.h> #include <dns/rdatalist.h> @@ -52,30 +53,6 @@ #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0) #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) -static void -set_bit(unsigned char *array, unsigned int index, unsigned int bit) { - unsigned int shift, mask; - - shift = 7 - (index % 8); - mask = 1 << shift; - - if (bit != 0) - array[index / 8] |= mask; - else - array[index / 8] &= (~mask & 0xFF); -} - -static unsigned int -bit_isset(unsigned char *array, unsigned int index) { - unsigned int byte, shift, mask; - - byte = array[index / 8]; - shift = 7 - (index % 8); - mask = 1 << shift; - - return ((byte & mask) != 0); -} - isc_result_t dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, unsigned int hashalg, @@ -87,8 +64,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, isc_result_t result; dns_rdataset_t rdataset; isc_region_t r; - unsigned int i, window; - int octet; + unsigned int i; isc_boolean_t found; isc_boolean_t found_ns; isc_boolean_t need_rrsig; @@ -156,7 +132,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, rdataset.type != dns_rdatatype_rrsig) { if (rdataset.type > max_type) max_type = rdataset.type; - set_bit(bm, rdataset.type, 1); + dns_nsec_setbit(bm, rdataset.type, 1); /* * Work out if we need to set the RRSIG bit for * this node. We set the RRSIG bit if either of @@ -179,18 +155,18 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, if ((found && !found_ns) || need_rrsig) { if (dns_rdatatype_rrsig > max_type) max_type = dns_rdatatype_rrsig; - set_bit(bm, dns_rdatatype_rrsig, 1); + dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1); } /* * At zone cuts, deny the existence of glue in the parent zone. */ - if (bit_isset(bm, dns_rdatatype_ns) && - ! bit_isset(bm, dns_rdatatype_soa)) { + if (dns_nsec_isset(bm, dns_rdatatype_ns) && + ! dns_nsec_isset(bm, dns_rdatatype_soa)) { for (i = 0; i <= max_type; i++) { - if (bit_isset(bm, i) && + if (dns_nsec_isset(bm, i) && ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i)) - set_bit(bm, i, 0); + dns_nsec_setbit(bm, i, 0); } } @@ -199,22 +175,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, return (result); collapse_bitmap: - for (window = 0; window < 256; window++) { - if (window * 256 > max_type) - break; - for (octet = 31; octet >= 0; octet--) - if (bm[window * 32 + octet] != 0) - break; - if (octet < 0) - continue; - nsec_bits[0] = window; - nsec_bits[1] = octet + 1; - /* - * Note: potentially overlapping move. - */ - memmove(&nsec_bits[2], &bm[window * 32], octet + 1); - nsec_bits += 3 + octet; - } + nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type); r.length = nsec_bits - r.base; INSIST(r.length <= DNS_NSEC3_BUFFERSIZE); dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r); @@ -249,8 +210,8 @@ dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) { if ((window + 1) * 256 <= type) continue; if (type < (window * 256) + len * 8) - present = ISC_TF(bit_isset(&nsec3.typebits[i], - type % 256)); + present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i], + type % 256)); break; } dns_rdata_freestruct(&nsec3); diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c index 59626f20..d186761c 100644 --- a/lib/dns/openssl_link.c +++ b/lib/dns/openssl_link.c @@ -45,6 +45,8 @@ #include <isc/thread.h> #include <isc/util.h> +#include <dns/log.h> + #include <dst/result.h> #include "dst_internal.h" @@ -172,6 +174,8 @@ dst__openssl_init(const char *engine) { CRYPTO_set_locking_callback(lock_callback); CRYPTO_set_id_callback(id_callback); + ERR_load_crypto_strings(); + rm = mem_alloc(sizeof(RAND_METHOD)); if (rm == NULL) { result = ISC_R_NOMEMORY; @@ -285,7 +289,7 @@ dst__openssl_destroy() { isc_result_t dst__openssl_toresult(isc_result_t fallback) { isc_result_t result = fallback; - int err = ERR_get_error(); + unsigned long err = ERR_get_error(); switch (ERR_GET_REASON(err)) { case ERR_R_MALLOC_FAILURE: @@ -298,6 +302,40 @@ dst__openssl_toresult(isc_result_t fallback) { return (result); } +isc_result_t +dst__openssl_toresult2(const char *funcname, isc_result_t fallback) { + isc_result_t result = fallback; + unsigned long err = ERR_peek_error(); + const char *file, *data; + int line, flags; + char buf[256]; + + switch (ERR_GET_REASON(err)) { + case ERR_R_MALLOC_FAILURE: + result = ISC_R_NOMEMORY; + goto done; + default: + break; + } + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING, + "%s failed", funcname); + for (;;) { + err = ERR_get_error_line_data(&file, &line, &data, &flags); + if (err == 0U) + goto done; + ERR_error_string_n(err, buf, sizeof(buf)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_CRYPTO, ISC_LOG_INFO, + "%s:%s:%d:%s", buf, file, line, + (flags & ERR_TXT_STRING) ? data : ""); + } + + done: + ERR_clear_error(); + return (result); +} + #if defined(USE_ENGINE) ENGINE * dst__openssl_getengine(const char *engine) { diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c index 71b4b122..36b8a412 100644 --- a/lib/dns/openssldh_link.c +++ b/lib/dns/openssldh_link.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -94,7 +94,8 @@ openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv, return (ISC_R_NOSPACE); ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv); if (ret == 0) - return (dst__openssl_toresult(DST_R_COMPUTESECRETFAILURE)); + return (dst__openssl_toresult2("DH_compute_key", + DST_R_COMPUTESECRETFAILURE)); isc_buffer_add(secret, len); return (ISC_R_SUCCESS); } @@ -204,7 +205,7 @@ openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { #if OPENSSL_VERSION_NUMBER > 0x00908000L dh = DH_new(); if (dh == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult(ISC_R_NOMEMORY)); if (callback == NULL) { BN_GENCB_set_old(&cb, NULL, NULL); @@ -216,7 +217,9 @@ openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { if (!DH_generate_parameters_ex(dh, key->key_size, generator, &cb)) { DH_free(dh); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2( + "DH_generate_parameters_ex", + DST_R_OPENSSLFAILURE)); } #else dh = DH_generate_parameters(key->key_size, generator, @@ -225,11 +228,13 @@ openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { } if (dh == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("DH_generate_parameters", + DST_R_OPENSSLFAILURE)); if (DH_generate_key(dh) == 0) { DH_free(dh); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("DH_generate_key", + DST_R_OPENSSLFAILURE)); } dh->flags &= ~DH_FLAG_CACHE_MONT_P; @@ -460,6 +465,7 @@ openssldh_tofile(const dst_key_t *key, const char *directory) { dh = key->keydata.dh; + memset(bufs, 0, sizeof(bufs)); for (i = 0; i < 4; i++) { bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(dh->p)); if (bufs[i] == NULL) { @@ -628,6 +634,7 @@ static dst_func_t openssldh_functions = { NULL, /*%< adddata */ NULL, /*%< openssldh_sign */ NULL, /*%< openssldh_verify */ + NULL, /*%< openssldh_verify2 */ openssldh_computesecret, openssldh_compare, openssldh_paramcompare, diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c index 39c06159..715fa73a 100644 --- a/lib/dns/openssldsa_link.c +++ b/lib/dns/openssldsa_link.c @@ -168,7 +168,8 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) { EVP_PKEY_free(pkey); free(sigbuf); - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_SignFinal", + ISC_R_FAILURE)); } INSIST(EVP_PKEY_size(pkey) >= (int) siglen); EVP_PKEY_free(pkey); @@ -181,23 +182,26 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { sb = sigbuf; if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) { free(sigbuf); - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("d2i_DSA_SIG", ISC_R_FAILURE)); } free(sigbuf); #elif 0 /* Only use EVP for the Digest */ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_DigestFinal_ex", + ISC_R_FAILURE)); } dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) - return (dst__openssl_toresult(DST_R_SIGNFAILURE)); + return (dst__openssl_toresult2("DSA_do_sign", + DST_R_SIGNFAILURE)); #else isc_sha1_final(sha1ctx, digest); dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) - return (dst__openssl_toresult(DST_R_SIGNFAILURE)); + return (dst__openssl_toresult2("DSA_do_sign", + DST_R_SIGNFAILURE)); #endif *r.base++ = (key->key_size - 512)/64; BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH); @@ -276,10 +280,15 @@ openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa); #endif DSA_SIG_free(dsasig); - if (status != 1) + switch (status) { + case 1: + return (ISC_R_SUCCESS); + case 0: return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); - - return (ISC_R_SUCCESS); + default: + return (dst__openssl_toresult2("DSA_do_verify", + DST_R_VERIFYFAILURE)); + } } static isc_boolean_t @@ -370,19 +379,22 @@ openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { &cb)) { DSA_free(dsa); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("DSA_generate_parameters_ex", + DST_R_OPENSSLFAILURE)); } #else dsa = DSA_generate_parameters(key->key_size, rand_array, ISC_SHA1_DIGESTLENGTH, NULL, NULL, NULL, NULL); if (dsa == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("DSA_generate_parameters", + DST_R_OPENSSLFAILURE)); #endif if (DSA_generate_key(dsa) == 0) { DSA_free(dsa); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("DSA_generate_key", + DST_R_OPENSSLFAILURE)); } dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; @@ -605,6 +617,7 @@ static dst_func_t openssldsa_functions = { openssldsa_adddata, openssldsa_sign, openssldsa_verify, + NULL, /*%< verify2 */ NULL, /*%< computesecret */ openssldsa_compare, NULL, /*%< paramcompare */ diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c new file mode 100644 index 00000000..ad628650 --- /dev/null +++ b/lib/dns/opensslecdsa_link.c @@ -0,0 +1,597 @@ +/* + * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id$ */ + +#include <config.h> + +#ifdef HAVE_OPENSSL_ECDSA + +#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384) +#error "ECDSA without EVP for SHA2?" +#endif + +#include <isc/entropy.h> +#include <isc/mem.h> +#include <isc/sha2.h> +#include <isc/string.h> +#include <isc/util.h> + +#include <dns/keyvalues.h> +#include <dst/result.h> + +#include "dst_internal.h" +#include "dst_openssl.h" +#include "dst_parse.h" + +#include <openssl/err.h> +#include <openssl/objects.h> +#include <openssl/ecdsa.h> +#include <openssl/bn.h> + +#ifndef NID_X9_62_prime256v1 +#error "P-256 group is not known (NID_X9_62_prime256v1)" +#endif +#ifndef NID_secp384r1 +#error "P-384 group is not known (NID_secp384r1)" +#endif + +#define DST_RET(a) {ret = a; goto err;} + +static isc_result_t opensslecdsa_todns(const dst_key_t *key, + isc_buffer_t *data); + +static isc_result_t +opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { + EVP_MD_CTX *evp_md_ctx; + const EVP_MD *type = NULL; + + UNUSED(key); + REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || + dctx->key->key_alg == DST_ALG_ECDSA384); + + evp_md_ctx = EVP_MD_CTX_create(); + if (evp_md_ctx == NULL) + return (ISC_R_NOMEMORY); + if (dctx->key->key_alg == DST_ALG_ECDSA256) + type = EVP_sha256(); + else + type = EVP_sha384(); + + if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { + EVP_MD_CTX_destroy(evp_md_ctx); + return (dst__openssl_toresult2("EVP_DigestInit_ex", + ISC_R_FAILURE)); + } + + dctx->ctxdata.evp_md_ctx = evp_md_ctx; + + return (ISC_R_SUCCESS); +} + +static void +opensslecdsa_destroyctx(dst_context_t *dctx) { + EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; + + REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || + dctx->key->key_alg == DST_ALG_ECDSA384); + + if (evp_md_ctx != NULL) { + EVP_MD_CTX_destroy(evp_md_ctx); + dctx->ctxdata.evp_md_ctx = NULL; + } +} + +static isc_result_t +opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) { + EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; + + REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || + dctx->key->key_alg == DST_ALG_ECDSA384); + + if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) + return (dst__openssl_toresult2("EVP_DigestUpdate", + ISC_R_FAILURE)); + + return (ISC_R_SUCCESS); +} + +static int +BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) { + int bytes = size - BN_num_bytes(bn); + + while (bytes-- > 0) + *buf++ = 0; + BN_bn2bin(bn, buf); + return (size); +} + +static isc_result_t +opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { + isc_result_t ret; + dst_key_t *key = dctx->key; + isc_region_t r; + ECDSA_SIG *ecdsasig; + EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; + EVP_PKEY *pkey = key->keydata.pkey; + EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey); + unsigned int dgstlen, siglen; + unsigned char digest[EVP_MAX_MD_SIZE]; + + REQUIRE(key->key_alg == DST_ALG_ECDSA256 || + key->key_alg == DST_ALG_ECDSA384); + + if (eckey == NULL) + return (ISC_R_FAILURE); + + if (key->key_alg == DST_ALG_ECDSA256) + siglen = DNS_SIG_ECDSA256SIZE; + else + siglen = DNS_SIG_ECDSA384SIZE; + + isc_buffer_availableregion(sig, &r); + if (r.length < siglen) + DST_RET(ISC_R_NOSPACE); + + if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen)) + DST_RET(dst__openssl_toresult2("EVP_DigestFinal", + ISC_R_FAILURE)); + + ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey); + if (ecdsasig == NULL) + DST_RET(dst__openssl_toresult2("ECDSA_do_sign", + DST_R_SIGNFAILURE)); + BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2); + r.base += siglen / 2; + BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2); + r.base += siglen / 2; + ECDSA_SIG_free(ecdsasig); + isc_buffer_add(sig, siglen); + ret = ISC_R_SUCCESS; + + err: + if (eckey != NULL) + EC_KEY_free(eckey); + return (ret); +} + +static isc_result_t +opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { + isc_result_t ret; + dst_key_t *key = dctx->key; + int status; + unsigned char *cp = sig->base; + ECDSA_SIG *ecdsasig = NULL; + EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; + EVP_PKEY *pkey = key->keydata.pkey; + EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey); + unsigned int dgstlen, siglen; + unsigned char digest[EVP_MAX_MD_SIZE]; + + REQUIRE(key->key_alg == DST_ALG_ECDSA256 || + key->key_alg == DST_ALG_ECDSA384); + + if (eckey == NULL) + return (ISC_R_FAILURE); + + if (key->key_alg == DST_ALG_ECDSA256) + siglen = DNS_SIG_ECDSA256SIZE; + else + siglen = DNS_SIG_ECDSA384SIZE; + + if (sig->length != siglen) + return (DST_R_VERIFYFAILURE); + + if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen)) + DST_RET (dst__openssl_toresult2("EVP_DigestFinal_ex", + ISC_R_FAILURE)); + + ecdsasig = ECDSA_SIG_new(); + if (ecdsasig == NULL) + DST_RET (ISC_R_NOMEMORY); + ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL); + cp += siglen / 2; + ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL); + /* cp += siglen / 2; */ + + status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey); + switch (status) { + case 1: + ret = ISC_R_SUCCESS; + break; + case 0: + ret = dst__openssl_toresult(DST_R_VERIFYFAILURE); + break; + default: + ret = dst__openssl_toresult2("ECDSA_do_verify", + DST_R_VERIFYFAILURE); + break; + } + + err: + if (ecdsasig != NULL) + ECDSA_SIG_free(ecdsasig); + if (eckey != NULL) + EC_KEY_free(eckey); + return (ret); +} + +static isc_boolean_t +opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) { + isc_boolean_t ret; + int status; + EVP_PKEY *pkey1 = key1->keydata.pkey; + EVP_PKEY *pkey2 = key2->keydata.pkey; + EC_KEY *eckey1 = NULL; + EC_KEY *eckey2 = NULL; + const BIGNUM *priv1, *priv2; + + if (pkey1 == NULL && pkey2 == NULL) + return (ISC_TRUE); + else if (pkey1 == NULL || pkey2 == NULL) + return (ISC_FALSE); + + eckey1 = EVP_PKEY_get1_EC_KEY(pkey1); + eckey2 = EVP_PKEY_get1_EC_KEY(pkey2); + if (eckey1 == NULL && eckey2 == NULL) { + DST_RET (ISC_TRUE); + } else if (eckey1 == NULL || eckey2 == NULL) + DST_RET (ISC_FALSE); + + status = EVP_PKEY_cmp(pkey1, pkey2); + if (status != 1) + DST_RET (ISC_FALSE); + + priv1 = EC_KEY_get0_private_key(eckey1); + priv2 = EC_KEY_get0_private_key(eckey2); + if (priv1 != NULL || priv2 != NULL) { + if (priv1 == NULL || priv2 == NULL) + DST_RET (ISC_FALSE); + if (BN_cmp(priv1, priv2) != 0) + DST_RET (ISC_FALSE); + } + ret = ISC_TRUE; + + err: + if (eckey1 != NULL) + EC_KEY_free(eckey1); + if (eckey2 != NULL) + EC_KEY_free(eckey2); + return (ret); +} + +static isc_result_t +opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { + isc_result_t ret; + EVP_PKEY *pkey; + EC_KEY *eckey = NULL; + int group_nid; + + REQUIRE(key->key_alg == DST_ALG_ECDSA256 || + key->key_alg == DST_ALG_ECDSA384); + UNUSED(unused); + UNUSED(callback); + + if (key->key_alg == DST_ALG_ECDSA256) + group_nid = NID_X9_62_prime256v1; + else + group_nid = NID_secp384r1; + + eckey = EC_KEY_new_by_curve_name(group_nid); + if (eckey == NULL) + return (dst__openssl_toresult2("EC_KEY_new_by_curve_name", + DST_R_OPENSSLFAILURE)); + + if (EC_KEY_generate_key(eckey) != 1) + DST_RET (dst__openssl_toresult2("EC_KEY_generate_key", + DST_R_OPENSSLFAILURE)); + + pkey = EVP_PKEY_new(); + if (pkey == NULL) + DST_RET (ISC_R_NOMEMORY); + if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { + EVP_PKEY_free(pkey); + DST_RET (ISC_R_FAILURE); + } + key->keydata.pkey = pkey; + ret = ISC_R_SUCCESS; + + err: + if (eckey != NULL) + EC_KEY_free(eckey); + return (ret); +} + +static isc_boolean_t +opensslecdsa_isprivate(const dst_key_t *key) { + isc_boolean_t ret; + EVP_PKEY *pkey = key->keydata.pkey; + EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey); + + ret = ISC_TF(eckey != NULL && EC_KEY_get0_private_key(eckey) != NULL); + if (eckey != NULL) + EC_KEY_free(eckey); + return (ret); +} + +static void +opensslecdsa_destroy(dst_key_t *key) { + EVP_PKEY *pkey = key->keydata.pkey; + + EVP_PKEY_free(pkey); + key->keydata.pkey = NULL; +} + +static isc_result_t +opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { + isc_result_t ret; + EVP_PKEY *pkey; + EC_KEY *eckey = NULL; + isc_region_t r; + int len; + unsigned char *cp; + unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; + + REQUIRE(key->keydata.pkey != NULL); + + pkey = key->keydata.pkey; + eckey = EVP_PKEY_get1_EC_KEY(pkey); + if (eckey == NULL) + return (dst__openssl_toresult(ISC_R_FAILURE)); + len = i2o_ECPublicKey(eckey, NULL); + /* skip form */ + len--; + + isc_buffer_availableregion(data, &r); + if (r.length < (unsigned int) len) + DST_RET (ISC_R_NOSPACE); + cp = buf; + if (!i2o_ECPublicKey(eckey, &cp)) + DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); + memcpy(r.base, buf + 1, len); + isc_buffer_add(data, len); + ret = ISC_R_SUCCESS; + + err: + if (eckey != NULL) + EC_KEY_free(eckey); + return (ret); +} + +static isc_result_t +opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { + isc_result_t ret; + EVP_PKEY *pkey; + EC_KEY *eckey = NULL; + isc_region_t r; + int group_nid; + unsigned int len; + const unsigned char *cp; + unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; + + REQUIRE(key->key_alg == DST_ALG_ECDSA256 || + key->key_alg == DST_ALG_ECDSA384); + + if (key->key_alg == DST_ALG_ECDSA256) { + len = DNS_KEY_ECDSA256SIZE; + group_nid = NID_X9_62_prime256v1; + } else { + len = DNS_KEY_ECDSA384SIZE; + group_nid = NID_secp384r1; + } + + isc_buffer_remainingregion(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + if (r.length < len) + return (DST_R_INVALIDPUBLICKEY); + + eckey = EC_KEY_new_by_curve_name(group_nid); + if (eckey == NULL) + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + + buf[0] = POINT_CONVERSION_UNCOMPRESSED; + memcpy(buf + 1, r.base, len); + cp = buf; + if (o2i_ECPublicKey(&eckey, + (const unsigned char **) &cp, + (long) len + 1) == NULL) + DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); + if (EC_KEY_check_key(eckey) != 1) + DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); + + pkey = EVP_PKEY_new(); + if (pkey == NULL) + DST_RET (ISC_R_NOMEMORY); + if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { + EVP_PKEY_free(pkey); + DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); + } + + isc_buffer_forward(data, len); + key->keydata.pkey = pkey; + ret = ISC_R_SUCCESS; + + err: + if (eckey != NULL) + EC_KEY_free(eckey); + return (ret); +} + +static isc_result_t +opensslecdsa_tofile(const dst_key_t *key, const char *directory) { + isc_result_t ret; + EVP_PKEY *pkey; + EC_KEY *eckey = NULL; + const BIGNUM *privkey; + dst_private_t priv; + unsigned char *buf = NULL; + + if (key->keydata.pkey == NULL) + return (DST_R_NULLKEY); + + pkey = key->keydata.pkey; + eckey = EVP_PKEY_get1_EC_KEY(pkey); + if (eckey == NULL) + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + privkey = EC_KEY_get0_private_key(eckey); + if (privkey == NULL) + DST_RET (ISC_R_FAILURE); + + buf = isc_mem_get(key->mctx, BN_num_bytes(privkey)); + if (buf == NULL) + DST_RET (ISC_R_NOMEMORY); + + priv.elements[0].tag = TAG_ECDSA_PRIVATEKEY; + priv.elements[0].length = BN_num_bytes(privkey); + BN_bn2bin(privkey, buf); + priv.elements[0].data = buf; + priv.nelements = ECDSA_NTAGS; + ret = dst__privstruct_writefile(key, &priv, directory); + + err: + if (eckey != NULL) + EC_KEY_free(eckey); + if (buf != NULL) + isc_mem_put(key->mctx, buf, BN_num_bytes(privkey)); + return (ret); +} + +static isc_result_t +ecdsa_check(EC_KEY *eckey, dst_key_t *pub) +{ + isc_result_t ret = ISC_R_FAILURE; + EVP_PKEY *pkey; + EC_KEY *pubeckey = NULL; + const EC_POINT *pubkey; + + if (pub == NULL) + return (ISC_R_SUCCESS); + pkey = pub->keydata.pkey; + if (pkey == NULL) + return (ISC_R_SUCCESS); + pubeckey = EVP_PKEY_get1_EC_KEY(pkey); + if (pubeckey == NULL) + return (ISC_R_SUCCESS); + pubkey = EC_KEY_get0_public_key(pubeckey); + if (pubkey == NULL) + DST_RET (ISC_R_SUCCESS); + if (EC_KEY_set_public_key(eckey, pubkey) != 1) + DST_RET (ISC_R_SUCCESS); + if (EC_KEY_check_key(eckey) == 1) + DST_RET (ISC_R_SUCCESS); + + err: + if (pubeckey != NULL) + EC_KEY_free(pubeckey); + return (ret); +} + +static isc_result_t +opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { + dst_private_t priv; + isc_result_t ret; + EVP_PKEY *pkey; + EC_KEY *eckey = NULL; + BIGNUM *privkey; + int group_nid; + isc_mem_t *mctx = key->mctx; + + REQUIRE(key->key_alg == DST_ALG_ECDSA256 || + key->key_alg == DST_ALG_ECDSA384); + + if (key->key_alg == DST_ALG_ECDSA256) + group_nid = NID_X9_62_prime256v1; + else + group_nid = NID_secp384r1; + + eckey = EC_KEY_new_by_curve_name(group_nid); + if (eckey == NULL) + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + + /* read private key file */ + ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); + if (ret != ISC_R_SUCCESS) + goto err; + + privkey = BN_bin2bn(priv.elements[0].data, + priv.elements[0].length, NULL); + if (privkey == NULL) + DST_RET(ISC_R_NOMEMORY); + if (!EC_KEY_set_private_key(eckey, privkey)) + DST_RET(ISC_R_NOMEMORY); + if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS) + DST_RET(DST_R_INVALIDPRIVATEKEY); + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + + pkey = EVP_PKEY_new(); + if (pkey == NULL) + DST_RET (ISC_R_NOMEMORY); + if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { + EVP_PKEY_free(pkey); + DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + } + key->keydata.pkey = pkey; + ret = ISC_R_SUCCESS; + + err: + if (eckey != NULL) + EC_KEY_free(eckey); + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ret); +} + +static dst_func_t opensslecdsa_functions = { + opensslecdsa_createctx, + opensslecdsa_destroyctx, + opensslecdsa_adddata, + opensslecdsa_sign, + opensslecdsa_verify, + NULL, /*%< verify2 */ + NULL, /*%< computesecret */ + opensslecdsa_compare, + NULL, /*%< paramcompare */ + opensslecdsa_generate, + opensslecdsa_isprivate, + opensslecdsa_destroy, + opensslecdsa_todns, + opensslecdsa_fromdns, + opensslecdsa_tofile, + opensslecdsa_parse, + NULL, /*%< cleanup */ + NULL, /*%< fromlabel */ + NULL, /*%< dump */ + NULL, /*%< restore */ +}; + +isc_result_t +dst__opensslecdsa_init(dst_func_t **funcp) { + REQUIRE(funcp != NULL); + if (*funcp == NULL) + *funcp = &opensslecdsa_functions; + return (ISC_R_SUCCESS); +} + +#else /* HAVE_OPENSSL_ECDSA */ + +#include <isc/util.h> + +EMPTY_TRANSLATION_UNIT + +#endif /* HAVE_OPENSSL_ECDSA */ +/*! \file */ diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c index e92d50f9..1ca89808 100644 --- a/lib/dns/opensslgost_link.c +++ b/lib/dns/opensslgost_link.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -121,10 +121,15 @@ opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) { EVP_PKEY *pkey = key->keydata.pkey; status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); - if (status != 1) + switch (status) { + case 1: + return (ISC_R_SUCCESS); + case 0: return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); - - return (ISC_R_SUCCESS); + default: + return (dst__openssl_toresult2("EVP_VerifyFinal", + DST_R_VERIFYFAILURE)); + } } static isc_boolean_t @@ -168,22 +173,27 @@ opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) { void (*fptr)(int); } u; EVP_PKEY *pkey = NULL; + isc_result_t ret; UNUSED(unused); ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL); if (ctx == NULL) - goto err; + DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_id", + DST_R_OPENSSLFAILURE)); if (callback != NULL) { u.fptr = callback; EVP_PKEY_CTX_set_app_data(ctx, u.dptr); EVP_PKEY_CTX_set_cb(ctx, &progress_cb); } if (EVP_PKEY_keygen_init(ctx) <= 0) - goto err; + DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init", + DST_R_OPENSSLFAILURE)); if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) - goto err; + DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_ctrl_str", + DST_R_OPENSSLFAILURE)); if (EVP_PKEY_keygen(ctx, &pkey) <= 0) - goto err; + DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen", + DST_R_OPENSSLFAILURE)); key->keydata.pkey = pkey; EVP_PKEY_CTX_free(ctx); return (ISC_R_SUCCESS); @@ -193,7 +203,7 @@ err: EVP_PKEY_free(pkey); if (ctx != NULL) EVP_PKEY_CTX_free(ctx); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (ret); } static isc_boolean_t @@ -267,7 +277,8 @@ opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) { p = der; if (d2i_PUBKEY(&pkey, &p, (long) sizeof(der)) == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("d2i_PUBKEY", + DST_R_OPENSSLFAILURE)); key->keydata.pkey = pkey; return (ISC_R_SUCCESS); @@ -293,7 +304,8 @@ opensslgost_tofile(const dst_key_t *key, const char *directory) { p = der; if (i2d_PrivateKey(pkey, &p) != len) { - result = dst__openssl_toresult(DST_R_OPENSSLFAILURE); + result = dst__openssl_toresult2("i2d_PrivateKey", + DST_R_OPENSSLFAILURE); goto fail; } @@ -328,7 +340,8 @@ opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { p = priv.elements[0].data; if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) priv.elements[0].length) == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); + DST_RET(dst__openssl_toresult2("d2i_PrivateKey", + DST_R_INVALIDPRIVATEKEY)); key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); dst__privstruct_free(&priv, mctx); @@ -359,6 +372,7 @@ static dst_func_t opensslgost_functions = { opensslgost_adddata, opensslgost_sign, opensslgost_verify, + NULL, /*%< verify2 */ NULL, /*%< computesecret */ opensslgost_compare, NULL, /*%< paramcompare */ @@ -377,35 +391,47 @@ static dst_func_t opensslgost_functions = { isc_result_t dst__opensslgost_init(dst_func_t **funcp) { + isc_result_t ret; + REQUIRE(funcp != NULL); /* check if the gost engine works properly */ e = ENGINE_by_id("gost"); if (e == NULL) - return (DST_R_OPENSSLFAILURE); + return (dst__openssl_toresult2("ENGINE_by_id", + DST_R_OPENSSLFAILURE)); if (ENGINE_init(e) <= 0) { ENGINE_free(e); e = NULL; - return (DST_R_OPENSSLFAILURE); + return (dst__openssl_toresult2("ENGINE_init", + DST_R_OPENSSLFAILURE)); } /* better than to rely on digest_gost symbol */ opensslgost_digest = ENGINE_get_digest(e, NID_id_GostR3411_94); + if (opensslgost_digest == NULL) + DST_RET(dst__openssl_toresult2("ENGINE_get_digest", + DST_R_OPENSSLFAILURE)); /* from openssl.cnf */ - if ((opensslgost_digest == NULL) || - (ENGINE_register_pkey_asn1_meths(e) <= 0) || - (ENGINE_ctrl_cmd_string(e, - "CRYPT_PARAMS", - "id-Gost28147-89-CryptoPro-A-ParamSet", - 0) <= 0)) { - ENGINE_finish(e); - ENGINE_free(e); - e = NULL; - return (DST_R_OPENSSLFAILURE); - } + if (ENGINE_register_pkey_asn1_meths(e) <= 0) + DST_RET(dst__openssl_toresult2( + "ENGINE_register_pkey_asn1_meths", + DST_R_OPENSSLFAILURE)); + if (ENGINE_ctrl_cmd_string(e, + "CRYPT_PARAMS", + "id-Gost28147-89-CryptoPro-A-ParamSet", + 0) <= 0) + DST_RET(dst__openssl_toresult2("ENGINE_ctrl_cmd_string", + DST_R_OPENSSLFAILURE)); if (*funcp == NULL) *funcp = &opensslgost_functions; return (ISC_R_SUCCESS); + + err: + ENGINE_finish(e); + ENGINE_free(e); + e = NULL; + return (ret); } #else /* HAVE_OPENSSL_GOST */ diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c index a2456188..a6db4545 100644 --- a/lib/dns/opensslrsa_link.c +++ b/lib/dns/opensslrsa_link.c @@ -56,6 +56,13 @@ #endif /* + * Limit the size of public exponents. + */ +#ifndef RSA_MAX_PUBEXP_BITS +#define RSA_MAX_PUBEXP_BITS 35 +#endif + +/* * We don't use configure for windows so enforce the OpenSSL version * here. Unlike with configure we don't support overriding this test. */ @@ -156,7 +163,8 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) { if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_DigestInit_ex", + ISC_R_FAILURE)); } dctx->ctxdata.evp_md_ctx = evp_md_ctx; #else @@ -304,7 +312,8 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) { #if USE_EVP if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_DigestUpdate", + ISC_R_FAILURE)); } #else switch (dctx->key->key_alg) { @@ -374,10 +383,6 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { int status; int type = 0; unsigned int digestlen = 0; - char *message; - unsigned long err; - const char* file; - int line; #if OPENSSL_VERSION_NUMBER < 0x00908000L unsigned int prefixlen = 0; const unsigned char *prefix = NULL; @@ -397,7 +402,8 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { return (ISC_R_NOSPACE); if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) { - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_SignFinal", + ISC_R_FAILURE)); } #else if (r.length < (unsigned int) RSA_size(rsa)) @@ -489,13 +495,9 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { INSIST(type != 0); status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); #endif - if (status == 0) { - err = ERR_peek_error_line(&file, &line); - if (err != 0U) { - message = ERR_error_string(err, NULL); - } - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - } + if (status == 0) + return (dst__openssl_toresult2("RSA_sign", + DST_R_OPENSSLFAILURE)); #endif isc_buffer_add(sig, siglen); @@ -504,12 +506,14 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { } static isc_result_t -opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { +opensslrsa_verify2(dst_context_t *dctx, int maxbits, const isc_region_t *sig) { dst_key_t *key = dctx->key; int status = 0; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; + RSA *rsa; + int bits; #else /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */ unsigned char digest[ISC_SHA512_DIGESTLENGTH]; @@ -529,8 +533,19 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP + rsa = EVP_PKEY_get1_RSA(pkey); + if (rsa == NULL) + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + bits = BN_num_bits(rsa->e); + RSA_free(rsa); + if (bits > maxbits && maxbits != 0) + return (DST_R_VERIFYFAILURE); + status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); #else + if (BN_num_bits(rsa->e) > maxbits && maxbits != 0) + return (DST_R_VERIFYFAILURE); + switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { @@ -615,7 +630,9 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { original, rsa, RSA_PKCS1_PADDING); if (status <= 0) - return (DST_R_VERIFYFAILURE); + return (dst__openssl_toresult2( + "RSA_public_decrypt", + DST_R_VERIFYFAILURE)); if (status != (int)(prefixlen + digestlen)) return (DST_R_VERIFYFAILURE); if (memcmp(original, prefix, prefixlen)) @@ -636,11 +653,17 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { #endif #endif if (status != 1) - return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); + return (dst__openssl_toresult2("RSA_verify", + DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); } +static isc_result_t +opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { + return (opensslrsa_verify2(dctx, 0, sig)); +} + static isc_boolean_t opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) { int status; @@ -727,6 +750,7 @@ progress_cb(int p, int n, BN_GENCB *cb) static isc_result_t opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { #if OPENSSL_VERSION_NUMBER > 0x00908000L + isc_result_t ret = DST_R_OPENSSLFAILURE; BN_GENCB cb; union { void *dptr; @@ -752,7 +776,7 @@ opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { BN_set_bit(e, 0); BN_set_bit(e, 16); } else { - /* F5 0x100000001 */ + /* (phased-out) F5 0x100000001 */ BN_set_bit(e, 0); BN_set_bit(e, 32); } @@ -776,6 +800,8 @@ opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { #endif return (ISC_R_SUCCESS); } + ret = dst__openssl_toresult2("RSA_generate_key_ex", + DST_R_OPENSSLFAILURE); err: #if USE_EVP @@ -786,7 +812,7 @@ err: BN_free(e); if (rsa != NULL) RSA_free(rsa); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult(ret)); #else RSA *rsa; unsigned long e; @@ -810,7 +836,8 @@ err: #if USE_EVP EVP_PKEY_free(pkey); #endif - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("RSA_generate_key", + DST_R_OPENSSLFAILURE)); } SET_FLAGS(rsa); #if USE_EVP @@ -1009,6 +1036,7 @@ opensslrsa_tofile(const dst_key_t *key, const char *directory) { rsa = key->keydata.rsa; #endif + memset(bufs, 0, sizeof(bufs)); for (i = 0; i < 8; i++) { bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n)); if (bufs[i] == NULL) { @@ -1162,7 +1190,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) - return (ret); + goto err; for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { @@ -1188,10 +1216,10 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (e == NULL) DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_private_key(e, label, NULL, NULL); - if (pkey == NULL) { - /* ERR_print_errors_fp(stderr); */ - DST_RET(ISC_R_NOTFOUND); - } + if (pkey == NULL) + DST_RET(dst__openssl_toresult2( + "ENGINE_load_private_key", + ISC_R_NOTFOUND)); key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); @@ -1203,6 +1231,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); + if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) + DST_RET(ISC_R_RANGE); if (pubrsa != NULL) RSA_free(pubrsa); key->key_size = EVP_PKEY_bits(pkey); @@ -1285,6 +1315,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); + if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) + DST_RET(ISC_R_RANGE); key->key_size = BN_num_bits(rsa->n); if (pubrsa != NULL) RSA_free(pubrsa); @@ -1303,7 +1335,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { RSA_free(rsa); if (pubrsa != NULL) RSA_free(pubrsa); - opensslrsa_destroy(key); + key->keydata.generic = NULL; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); @@ -1336,7 +1368,8 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label, } pkey = ENGINE_load_private_key(e, label, NULL, NULL); if (pkey == NULL) - DST_RET(ISC_R_NOTFOUND); + DST_RET(dst__openssl_toresult2("ENGINE_load_private_key", + ISC_R_NOTFOUND)); if (engine != NULL) { key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) @@ -1357,6 +1390,8 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label, DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); + if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) + DST_RET(ISC_R_RANGE); if (pubrsa != NULL) RSA_free(pubrsa); key->key_size = EVP_PKEY_bits(pkey); @@ -1392,6 +1427,7 @@ static dst_func_t opensslrsa_functions = { opensslrsa_adddata, opensslrsa_sign, opensslrsa_verify, + opensslrsa_verify2, NULL, /*%< computesecret */ opensslrsa_compare, NULL, /*%< paramcompare */ diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 5bae6c48..b80a0c7e 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -113,6 +113,8 @@ typedef isc_uint32_t rbtdb_rdatatype_t; RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_cname) #define RBTDB_RDATATYPE_SIGDNAME \ RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_dname) +#define RBTDB_RDATATYPE_SIGDDS \ + RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds) #define RBTDB_RDATATYPE_NCACHEANY \ RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any) @@ -4572,7 +4574,7 @@ get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) * configured earlier than this policy zone and does not have a higher * precedence type. */ -static isc_result_t +static void rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_rdataset_t *ardataset, dns_rpz_st_t *st, @@ -4597,7 +4599,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, if (rbtdb->rpz_cidr == NULL) { RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - return (ISC_R_UNEXPECTED); + return; } dns_fixedname_init(&selfnamef); @@ -4659,7 +4661,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, dns_name_format(qname, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "rpz_findips findnode(%s): %s", + "rpz_findips findnode(%s) failed: %s", namebuf, isc_result_totext(result)); continue; } @@ -4680,7 +4682,8 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, if (zrdataset.type != dns_rdatatype_cname) { rpz_policy = DNS_RPZ_POLICY_RECORD; } else { - rpz_policy = dns_rpz_decode_cname(&zrdataset, + rpz_policy = dns_rpz_decode_cname(rpz, + &zrdataset, selfname); if (rpz_policy == DNS_RPZ_POLICY_RECORD || rpz_policy == DNS_RPZ_POLICY_WILDCNAME) @@ -4738,7 +4741,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, st->m.type = rpz_type; st->m.prefix = prefix; st->m.policy = rpz_policy; - st->m.ttl = ttl; + st->m.ttl = ISC_MIN(ttl, rpz->max_policy_ttl); st->m.result = result; dns_name_copy(qname, st->qname, NULL); if ((rpz_policy == DNS_RPZ_POLICY_RECORD || @@ -4755,7 +4758,6 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, } RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - return (ISC_R_SUCCESS); } #endif @@ -5914,13 +5916,12 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, negtype = 0; if (rbtversion == NULL && !newheader_nx) { rdtype = RBTDB_RDATATYPE_BASE(newheader->type); + covers = RBTDB_RDATATYPE_EXT(newheader->type); + sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, covers); if (NEGATIVE(newheader)) { /* * We're adding a negative cache entry. */ - covers = RBTDB_RDATATYPE_EXT(newheader->type); - sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, - covers); for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { @@ -5953,14 +5954,20 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, * We're adding something that isn't a * negative cache entry. Look for an extant * non-stale NXDOMAIN/NODATA(QTYPE=ANY) negative - * cache entry. + * cache entry. If we're adding an RRSIG, also + * check for an extant non-stale NODATA ncache + * entry which covers the same type as the RRSIG. */ for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { - if (topheader->type == - RBTDB_RDATATYPE_NCACHEANY) - break; + if ((topheader->type == + RBTDB_RDATATYPE_NCACHEANY) || + (newheader->type == sigtype && + topheader->type == + RBTDB_RDATATYPE_VALUE(0, covers))) { + break; + } } if (topheader != NULL && EXISTS(topheader) && topheader->rdh_ttl > now) { @@ -5983,7 +5990,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, } /* * The new rdataset is better. Expire the - * NXDOMAIN/NODATA(QTYPE=ANY). + * ncache entry. */ set_ttl(rbtdb, topheader, 0); topheader->attributes |= RDATASET_ATTR_STALE; @@ -6145,7 +6152,9 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, } if (IS_CACHE(rbtdb) && header->rdh_ttl > now && (header->type == dns_rdatatype_a || - header->type == dns_rdatatype_aaaa) && + header->type == dns_rdatatype_aaaa || + header->type == dns_rdatatype_ds || + header->type == RBTDB_RDATATYPE_SIGDDS) && !header_nx && !newheader_nx && header->trust >= newheader->trust && dns_rdataslab_equal((unsigned char *)header, diff --git a/lib/dns/rcode.c b/lib/dns/rcode.c index 09f6d83d..0b7fe8c2 100644 --- a/lib/dns/rcode.c +++ b/lib/dns/rcode.c @@ -108,6 +108,8 @@ { DNS_KEYALG_RSASHA256, "RSASHA256", 0 }, \ { DNS_KEYALG_RSASHA512, "RSASHA512", 0 }, \ { DNS_KEYALG_ECCGOST, "ECCGOST", 0 }, \ + { DNS_KEYALG_ECDSA256, "ECDSAP256SHA256", 0 }, \ + { DNS_KEYALG_ECDSA384, "ECDSAP384SHA384", 0 }, \ { DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \ { DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \ { DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \ diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 683130ac..b6e715ef 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -445,6 +445,8 @@ dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, REQUIRE(DNS_RDATA_INITIALIZED(rdata)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); } + REQUIRE(source != NULL); + REQUIRE(target != NULL); if (type == 0) return (DNS_R_FORMERR); @@ -545,13 +547,11 @@ rdata_validate(isc_buffer_t *src, isc_buffer_t *dest, dns_rdataclass_t rdclass, dns_rdatatype_t type) { dns_decompress_t dctx; - dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); isc_buffer_setactive(src, isc_buffer_usedlength(src)); - result = dns_rdata_fromwire(&rdata, rdclass, type, src, - &dctx, 0, dest); + result = dns_rdata_fromwire(NULL, rdclass, type, src, &dctx, 0, dest); dns_decompress_invalidate(&dctx); return (result); @@ -1182,7 +1182,8 @@ txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { if (n > tregion.length) return (ISC_R_NOSPACE); - memcpy(tregion.base, sregion.base, n); + if (tregion.base != sregion.base) + memcpy(tregion.base, sregion.base, n); isc_buffer_forward(source, n); isc_buffer_add(target, n); return (ISC_R_SUCCESS); @@ -1331,7 +1332,8 @@ multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { if (n > tregion.length) return (ISC_R_NOSPACE); - memcpy(tregion.base, sregion.base, n); + if (tregion.base != sregion.base) + memcpy(tregion.base, sregion.base, n); isc_buffer_forward(source, n); isc_buffer_add(target, n); isc_buffer_activeregion(source, &sregion); @@ -1507,7 +1509,8 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { isc_buffer_availableregion(target, &tr); if (length > tr.length) return (ISC_R_NOSPACE); - memcpy(tr.base, base, length); + if (tr.base != base) + memcpy(tr.base, base, length); isc_buffer_add(target, length); return (ISC_R_SUCCESS); } diff --git a/lib/dns/rdata/generic/dlv_32769.c b/lib/dns/rdata/generic/dlv_32769.c index 51ed11d1..474e9cb3 100644 --- a/lib/dns/rdata/generic/dlv_32769.c +++ b/lib/dns/rdata/generic/dlv_32769.c @@ -84,6 +84,9 @@ fromtext_dlv(ARGS_FROMTEXT) { case DNS_DSDIGEST_GOST: length = ISC_GOST_DIGESTLENGTH; break; + case DNS_DSDIGEST_SHA384: + length = ISC_SHA384_DIGESTLENGTH; + break; default: length = -1; break; @@ -166,7 +169,9 @@ fromwire_dlv(ARGS_FROMWIRE) { (sr.base[3] == DNS_DSDIGEST_SHA256 && sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || (sr.base[3] == DNS_DSDIGEST_GOST && - sr.length < 4 + ISC_GOST_DIGESTLENGTH)) + sr.length < 4 + ISC_GOST_DIGESTLENGTH) || + (sr.base[3] == DNS_DSDIGEST_SHA384 && + sr.length < 4 + ISC_SHA384_DIGESTLENGTH)) return (ISC_R_UNEXPECTEDEND); /* @@ -180,6 +185,8 @@ fromwire_dlv(ARGS_FROMWIRE) { sr.length = 4 + ISC_SHA256_DIGESTLENGTH; else if (sr.base[3] == DNS_DSDIGEST_GOST) sr.length = 4 + ISC_GOST_DIGESTLENGTH; + else if (sr.base[3] == DNS_DSDIGEST_SHA384) + sr.length = 4 + ISC_SHA384_DIGESTLENGTH; isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); @@ -232,6 +239,9 @@ fromstruct_dlv(ARGS_FROMSTRUCT) { case DNS_DSDIGEST_GOST: REQUIRE(dlv->length == ISC_GOST_DIGESTLENGTH); break; + case DNS_DSDIGEST_SHA384: + REQUIRE(dlv->length == ISC_SHA384_DIGESTLENGTH); + break; } UNUSED(type); diff --git a/lib/dns/rdata/generic/ds_43.c b/lib/dns/rdata/generic/ds_43.c index fc35b72e..dd47c8d5 100644 --- a/lib/dns/rdata/generic/ds_43.c +++ b/lib/dns/rdata/generic/ds_43.c @@ -84,6 +84,9 @@ fromtext_ds(ARGS_FROMTEXT) { case DNS_DSDIGEST_GOST: length = ISC_GOST_DIGESTLENGTH; break; + case DNS_DSDIGEST_SHA384: + length = ISC_SHA384_DIGESTLENGTH; + break; default: length = -1; break; @@ -166,7 +169,9 @@ fromwire_ds(ARGS_FROMWIRE) { (sr.base[3] == DNS_DSDIGEST_SHA256 && sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || (sr.base[3] == DNS_DSDIGEST_GOST && - sr.length < 4 + ISC_GOST_DIGESTLENGTH)) + sr.length < 4 + ISC_GOST_DIGESTLENGTH) || + (sr.base[3] == DNS_DSDIGEST_SHA384 && + sr.length < 4 + ISC_SHA384_DIGESTLENGTH)) return (ISC_R_UNEXPECTEDEND); /* @@ -180,6 +185,8 @@ fromwire_ds(ARGS_FROMWIRE) { sr.length = 4 + ISC_SHA256_DIGESTLENGTH; else if (sr.base[3] == DNS_DSDIGEST_GOST) sr.length = 4 + ISC_GOST_DIGESTLENGTH; + else if (sr.base[3] == DNS_DSDIGEST_SHA384) + sr.length = 4 + ISC_SHA384_DIGESTLENGTH; isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); @@ -232,6 +239,9 @@ fromstruct_ds(ARGS_FROMSTRUCT) { case DNS_DSDIGEST_GOST: REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH); break; + case DNS_DSDIGEST_SHA384: + REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH); + break; } UNUSED(type); diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c index 8c865498..026d7712 100644 --- a/lib/dns/rdataset.c +++ b/lib/dns/rdataset.c @@ -26,6 +26,7 @@ #include <isc/buffer.h> #include <isc/mem.h> #include <isc/random.h> +#include <isc/serial.h> #include <isc/util.h> #include <dns/name.h> @@ -772,3 +773,30 @@ dns_rdataset_expire(dns_rdataset_t *rdataset) { if (rdataset->methods->expire != NULL) (rdataset->methods->expire)(rdataset); } + +void +dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, + dns_rdata_rrsig_t *rrsig, isc_stdtime_t now, + isc_boolean_t acceptexpired) +{ + isc_uint32_t ttl = 0; + + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(DNS_RDATASET_VALID(sigrdataset)); + REQUIRE(rrsig != NULL); + + /* + * If we accept expired RRsets keep them for no more than 120 seconds. + */ + if (acceptexpired && + (isc_serial_le(rrsig->timeexpire, ((now + 120) & 0xffffffff)) || + isc_serial_le(rrsig->timeexpire, now))) + ttl = 120; + else if (isc_serial_ge(rrsig->timeexpire, now)) + ttl = rrsig->timeexpire - now; + + ttl = ISC_MIN(ISC_MIN(rdataset->ttl, sigrdataset->ttl), + ISC_MIN(rrsig->originalttl, ttl)); + rdataset->ttl = ttl; + sigrdataset->ttl = ttl; +} diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 20b8de47..503f1d23 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -105,8 +105,21 @@ #define QTRACE(m) #endif +#define US_PER_SEC 1000000U +/* + * The maximum time we will wait for a single query. + */ +#define MAX_SINGLE_QUERY_TIMEOUT 9U +#define MAX_SINGLE_QUERY_TIMEOUT_US (MAX_SINGLE_QUERY_TIMEOUT*US_PER_SEC) + +/* + * We need to allow a individual query time to complete / timeout. + */ +#define MINIMUM_QUERY_TIMEOUT (MAX_SINGLE_QUERY_TIMEOUT + 1U) + +/* The default time in seconds for the whole query to live. */ #ifndef DEFAULT_QUERY_TIMEOUT -#define DEFAULT_QUERY_TIMEOUT 10 /* The default time in seconds for the whole query to live. */ +#define DEFAULT_QUERY_TIMEOUT MINIMUM_QUERY_TIMEOUT #endif #ifndef MAXIMUM_QUERY_TIMEOUT @@ -821,8 +834,8 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp, */ INSIST(no_response); rtt = query->addrinfo->srtt + 200000; - if (rtt > 10000000) - rtt = 10000000; + if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US) + rtt = MAX_SINGLE_QUERY_TIMEOUT_US; /* * Replace the current RTT with our value. */ @@ -1336,12 +1349,18 @@ fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) { us = (800000 << (fctx->restarts - 2)); /* - * Double the round-trip time. + * Add a fudge factor to the expected rtt based on the current + * estimate. */ - rtt *= 2; + if (rtt < 50000) + rtt += 50000; + else if (rtt < 100000) + rtt += 100000; + else + rtt += 200000; /* - * Always wait for at least the doubled round-trip time. + * Always wait for at least the expected rtt. */ if (us < rtt) us = rtt; @@ -1349,11 +1368,11 @@ fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) { /* * But don't ever wait for more than 10 seconds. */ - if (us > 10000000) - us = 10000000; + if (us > MAX_SINGLE_QUERY_TIMEOUT_US) + us = MAX_SINGLE_QUERY_TIMEOUT_US; - seconds = us / 1000000; - us -= seconds * 1000000; + seconds = us / US_PER_SEC; + us -= seconds * US_PER_SEC; isc_interval_set(&fctx->interval, seconds, us * 1000); } @@ -1375,6 +1394,11 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, task = res->buckets[fctx->bucketnum].task; srtt = addrinfo->srtt; + + /* + * A forwarder needs to make multiple queries. Give it at least + * a second to do these in. + */ if (ISFORWARDER(addrinfo) && srtt < 1000000) srtt = 1000000; @@ -8211,8 +8235,8 @@ dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx, "timeout:%u,lame:%u,neterr:%u,badresp:%u," "adberr:%u,findfail:%u,valfail:%u]", __FILE__, fctx->exitline, fctx->info, - fctx->duration / 1000000, - fctx->duration % 1000000, + fctx->duration / US_PER_SEC, + fctx->duration % US_PER_SEC, isc_result_totext(fctx->result), isc_result_totext(fctx->vresult), domainbuf, fctx->referrals, fctx->restarts, @@ -8818,6 +8842,8 @@ dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int seconds) { seconds = DEFAULT_QUERY_TIMEOUT; if (seconds > MAXIMUM_QUERY_TIMEOUT) seconds = MAXIMUM_QUERY_TIMEOUT; + if (seconds < MINIMUM_QUERY_TIMEOUT) + seconds = MINIMUM_QUERY_TIMEOUT; resolver->query_timeout = seconds; } diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c index e3f49897..78658590 100644 --- a/lib/dns/rpz.c +++ b/lib/dns/rpz.c @@ -118,9 +118,9 @@ struct dns_rpz_cidr { isc_mem_t *mctx; isc_boolean_t have_nsdname; /* zone has NSDNAME record */ dns_rpz_cidr_node_t *root; - dns_name_t ip_name; /* RPZ_IP_ZONE.LOCALHOST. */ - dns_name_t nsip_name; /* RPZ_NSIP_ZONE.LOCALHOST. */ - dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.LOCALHOST */ + dns_name_t ip_name; /* RPZ_IP_ZONE.origin. */ + dns_name_t nsip_name; /* RPZ_NSIP_ZONE.origin. */ + dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.origin */ }; static isc_boolean_t have_rpz_zones = ISC_FALSE; @@ -183,7 +183,7 @@ dns_rpz_policy2str(dns_rpz_policy_t policy) { str = "NODATA"; break; case DNS_RPZ_POLICY_RECORD: - str = "records"; + str = "Local-Data"; break; case DNS_RPZ_POLICY_CNAME: case DNS_RPZ_POLICY_WILDCNAME: @@ -255,6 +255,8 @@ dns_rpz_view_destroy(dns_view_t *view) { ISC_LIST_UNLINK(view->rpz_zones, zone, link); if (dns_name_dynamic(&zone->origin)) dns_name_free(&zone->origin, view->mctx); + if (dns_name_dynamic(&zone->passthru)) + dns_name_free(&zone->passthru, view->mctx); if (dns_name_dynamic(&zone->nsdname)) dns_name_free(&zone->nsdname, view->mctx); if (dns_name_dynamic(&zone->cname)) @@ -427,14 +429,16 @@ new_node(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *ip, } static void -badname(int level, dns_name_t *name, const char *comment) { +badname(int level, dns_name_t *name, const char *str1, const char *str2) { char printname[DNS_NAME_FORMATSIZE]; - if (isc_log_wouldlog(dns_lctx, level)) { + if (level < DNS_RPZ_DEBUG_QUIET + && isc_log_wouldlog(dns_lctx, level)) { dns_name_format(name, printname, sizeof(printname)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, level, - "invalid rpz \"%s\"%s", printname, comment); + "invalid rpz IP address \"%s\"%s%s", + printname, str1, str2); } } @@ -566,11 +570,11 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, dns_rpz_type_t type, dns_rpz_cidr_key_t *tgt_ip, dns_rpz_cidr_bits_t *tgt_prefix) { - isc_buffer_t buffer; - unsigned char data[DNS_NAME_MAXWIRE+1]; + isc_result_t result; dns_fixedname_t fname; - dns_name_t *name; - const char *cp, *end; + dns_name_t *ipname; + char ipstr[DNS_NAME_FORMATSIZE]; + const char *prefix_str, *cp, *end; char *cp2; int ip_labels; dns_rpz_cidr_bits_t bits; @@ -585,37 +589,43 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, ip_labels -= dns_name_countlabels(&cidr->ip_name); ip_labels--; if (ip_labels < 1) { - badname(level, src_name, ", too short"); + badname(level, src_name, "; too short", ""); return (ISC_R_FAILURE); } /* - * Get text for the IP address without RPZ_x_ZONE.rpz.LOCALHOST. + * Get text for the IP address */ dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); + ipname = dns_fixedname_name(&fname); dns_name_split(src_name, dns_name_countlabels(&cidr->ip_name), - name, NULL); - isc_buffer_init(&buffer, data, sizeof(data)); - dns_name_totext(name, ISC_TRUE, &buffer); - isc_buffer_putuint8(&buffer, '\0'); - cp = isc_buffer_base(&buffer); - - prefix = strtoul(cp, &cp2, 10); - if (prefix < 1U || prefix > 128U || *cp2 != '.') { - badname(level, src_name, ", bad prefix length"); + ipname, NULL); + dns_name_format(ipname, ipstr, sizeof(ipstr)); + end = &ipstr[strlen(ipstr)+1]; + prefix_str = ipstr; + + prefix = strtoul(prefix_str, &cp2, 10); + if (*cp2 != '.') { + badname(level, src_name, + "; invalid leading prefix length", ""); + return (ISC_R_FAILURE); + } + *cp2 = '\0'; + if (prefix < 1U || prefix > 128U) { + badname(level, src_name, + "; invalid prefix length of ", prefix_str); return (ISC_R_FAILURE); } cp = cp2+1; - end = isc_buffer_used(&buffer); if (ip_labels == 4 && !strchr(cp, 'z')) { /* * Convert an IPv4 address * from the form "prefix.w.z.y.x" */ if (prefix > 32U) { - badname(level, src_name, "; bad IPv4 prefix length"); + badname(level, src_name, + "; invalid IPv4 prefix length of ", prefix_str); return (ISC_R_FAILURE); } prefix += 96; @@ -627,7 +637,10 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, for (i = 0; i < 32; i += 8) { l = strtoul(cp, &cp2, 10); if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) { - badname(level, src_name, "; bad IPv4 address"); + if (*cp2 == '.') + *cp2 = '\0'; + badname(level, src_name, + "; invalid IPv4 octet ", cp); return (ISC_R_FAILURE); } tgt_ip->w[3] |= l << i; @@ -654,7 +667,10 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, l = strtoul(cp, &cp2, 16); if (l > 0xffffu || (*cp2 != '.' && *cp2 != '\0')) { - badname(level, src_name, ""); + if (*cp2 == '.') + *cp2 = '\0'; + badname(level, src_name, + "; invalid IPv6 word ", cp); return (ISC_R_FAILURE); } if ((i & 1) == 0) @@ -667,7 +683,7 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, } } if (cp != end) { - badname(level, src_name, ""); + badname(level, src_name, "", ""); return (ISC_R_FAILURE); } @@ -681,7 +697,8 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, i = bits % DNS_RPZ_CIDR_WORD_BITS; aword = tgt_ip->w[bits / DNS_RPZ_CIDR_WORD_BITS]; if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) { - badname(level, src_name, "; wrong prefix length"); + badname(level, src_name, + "; too small prefix length of ", prefix_str); return (ISC_R_FAILURE); } bits -= i; @@ -689,13 +706,13 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, } /* - * Convert the IPv6 address back to a canonical policy domain name + * Convert the address back to a canonical policy domain name * to ensure that it is in canonical form. */ - if (ISC_R_SUCCESS != ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t)prefix, - type, NULL, name) || - !dns_name_equal(src_name, name)) { - badname(level, src_name, "; not canonical"); + result = ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t) prefix, + type, NULL, ipname); + if (result != ISC_R_SUCCESS || !dns_name_equal(src_name, ipname)) { + badname(level, src_name, "; not canonical", ""); return (ISC_R_FAILURE); } @@ -934,6 +951,7 @@ search(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip, */ void dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { + isc_result_t result; dns_rpz_cidr_key_t tgt_ip; dns_rpz_cidr_bits_t tgt_prefix; dns_rpz_type_t type; @@ -956,19 +974,22 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { case DNS_RPZ_TYPE_BAD: return; } - if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name, - type, &tgt_ip, &tgt_prefix)) + result = name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name, + type, &tgt_ip, &tgt_prefix); + if (result != ISC_R_SUCCESS) return; - if (ISC_R_EXISTS == search(cidr, &tgt_ip, tgt_prefix, type, - ISC_TRUE, NULL) && - isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) { + result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_TRUE, NULL); + if (result == ISC_R_EXISTS && + isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) + { char printname[DNS_NAME_FORMATSIZE]; dns_name_format(name, printname, sizeof(printname)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "duplicate rpz name \"%s\"", printname); + "rpz add failed; \"%s\" is a duplicate name", + printname); } } @@ -978,6 +999,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { */ void dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) { + isc_result_t result; dns_rpz_cidr_key_t tgt_ip; dns_rpz_cidr_bits_t tgt_prefix; dns_rpz_type_t type; @@ -1010,19 +1032,14 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) { /* * Do not get excited about the deletion of interior rbt nodes. */ - if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_DEBUG_LEVEL3, name, - type, &tgt_ip, &tgt_prefix)) + result = name2ipkey(cidr, DNS_RPZ_DEBUG_QUIET, name, + type, &tgt_ip, &tgt_prefix); + if (result != ISC_R_SUCCESS) return; - if (ISC_R_SUCCESS != search(cidr, &tgt_ip, tgt_prefix, type, - ISC_FALSE, &tgt)) { - if (isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) { - char printname[DNS_NAME_FORMATSIZE]; - - dns_name_format(name, printname, sizeof(printname)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "missing rpz node \"%s\"", printname); - } + + result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_FALSE, &tgt); + if (result != ISC_R_SUCCESS) { + badname(DNS_RPZ_ERROR_LEVEL, name, "; missing rpz node", ""); return; } @@ -1135,7 +1152,9 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr, * Translate CNAME rdata to a QNAME response policy action. */ dns_rpz_policy_t -dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) { +dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset, + dns_name_t *selfname) +{ dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_cname_t cname; isc_result_t result; @@ -1171,7 +1190,13 @@ dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) { } /* - * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. means "do not rewrite" + * CNAME PASSTHRU.origin means "do not rewrite. + */ + if (dns_name_equal(&cname.cname, &rpz->passthru)) + return (DNS_RPZ_POLICY_PASSTHRU); + + /* + * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU */ if (selfname != NULL && dns_name_equal(&cname.cname, selfname)) return (DNS_RPZ_POLICY_PASSTHRU); diff --git a/lib/dns/spnego_asn1.pl b/lib/dns/spnego_asn1.pl index 93dd6767..0aaa57fa 100644 --- a/lib/dns/spnego_asn1.pl +++ b/lib/dns/spnego_asn1.pl @@ -1,6 +1,6 @@ #!/bin/bin/perl -w # -# Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2006, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/dns/tests/Makefile.in b/lib/dns/tests/Makefile.in index 5f68af0a..409ee8dc 100644 --- a/lib/dns/tests/Makefile.in +++ b/lib/dns/tests/Makefile.in @@ -39,13 +39,13 @@ LIBS = @LIBS@ @ATFLIBS@ OBJS = dnstest.@O@ SRCS = dnstest.c master_test.c dbiterator_test.c time_test.c \ private_test.c update_test.c zonemgr_test.c zt_test.c \ - dbdiff_test.c nsec3_test.c rdata_test.c + dbdiff_test.c nsec3_test.c rdataset_test.c rdata_test.c SUBDIRS = TARGETS = master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \ private_test@EXEEXT@ update_test@EXEEXT@ zonemgr_test@EXEEXT@ \ zt_test@EXEEXT@ dbversion_test@EXEEXT@ dbdiff_test@EXEEXT@ \ - nsec3_test@EXEEXT@ rdata_test@EXEEXT@ + nsec3_test@EXEEXT@ rdataset_test@EXEEXT@ rdata_test@EXEEXT@ @BIND9_MAKE_RULES@ @@ -104,6 +104,11 @@ nsec3_test@EXEEXT@: nsec3_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ nsec3_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} + +rdataset_test@EXEEXT@: rdataset_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + rdataset_test.@O@ dnstest.@O@ ${DNSLIBS} \ + ${ISCLIBS} ${LIBS} rdata_test@EXEEXT@: rdata_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ diff --git a/lib/dns/tests/rdataset_test.c b/lib/dns/tests/rdataset_test.c new file mode 100644 index 00000000..7cbaa195 --- /dev/null +++ b/lib/dns/tests/rdataset_test.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id$ */ + +/*! \file */ + +#include <config.h> + +#include <atf-c.h> + +#include <unistd.h> + +#include <dns/rdataset.h> +#include <dns/rdatastruct.h> + +#include "dnstest.h" + + +/* + * Individual unit tests + */ + +/* Successful load test */ +ATF_TC(trimttl); +ATF_TC_HEAD(trimttl, tc) { + atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() loads a " + "valid master file and returns success"); +} +ATF_TC_BODY(trimttl, tc) { + isc_result_t result; + dns_rdataset_t rdataset, sigrdataset; + dns_rdata_rrsig_t rrsig; + isc_stdtime_t ttltimenow, ttltimeexpire; + + ttltimenow = 10000000; + ttltimeexpire = ttltimenow + 800; + + UNUSED(tc); + + dns_rdataset_init(&rdataset); + dns_rdataset_init(&sigrdataset); + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + rdataset.ttl = 900; + sigrdataset.ttl = 1000; + rrsig.timeexpire = ttltimeexpire; + rrsig.originalttl = 1000; + + dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, + ISC_TRUE); + ATF_REQUIRE_EQ(rdataset.ttl, 800); + ATF_REQUIRE_EQ(sigrdataset.ttl, 800); + + rdataset.ttl = 900; + sigrdataset.ttl = 1000; + rrsig.timeexpire = ttltimenow - 200; + rrsig.originalttl = 1000; + + dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, + ISC_TRUE); + ATF_REQUIRE_EQ(rdataset.ttl, 120); + ATF_REQUIRE_EQ(sigrdataset.ttl, 120); + + rdataset.ttl = 900; + sigrdataset.ttl = 1000; + rrsig.timeexpire = ttltimenow - 200; + rrsig.originalttl = 1000; + + dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, + ISC_FALSE); + ATF_REQUIRE_EQ(rdataset.ttl, 0); + ATF_REQUIRE_EQ(sigrdataset.ttl, 0); + + sigrdataset.ttl = 900; + rdataset.ttl = 1000; + rrsig.timeexpire = ttltimeexpire; + rrsig.originalttl = 1000; + + dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, + ISC_TRUE); + ATF_REQUIRE_EQ(rdataset.ttl, 800); + ATF_REQUIRE_EQ(sigrdataset.ttl, 800); + + sigrdataset.ttl = 900; + rdataset.ttl = 1000; + rrsig.timeexpire = ttltimenow - 200; + rrsig.originalttl = 1000; + + dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, + ISC_TRUE); + ATF_REQUIRE_EQ(rdataset.ttl, 120); + ATF_REQUIRE_EQ(sigrdataset.ttl, 120); + + sigrdataset.ttl = 900; + rdataset.ttl = 1000; + rrsig.timeexpire = ttltimenow - 200; + rrsig.originalttl = 1000; + + dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, + ISC_FALSE); + ATF_REQUIRE_EQ(rdataset.ttl, 0); + ATF_REQUIRE_EQ(sigrdataset.ttl, 0); + + dns_test_end(); +} + +/* + * Main + */ +ATF_TP_ADD_TCS(tp) { + ATF_TP_ADD_TC(tp, trimttl); + + return (atf_no_error()); +} + diff --git a/lib/dns/tests/zt_test.c b/lib/dns/tests/zt_test.c index 80d11cd6..176d4779 100644 --- a/lib/dns/tests/zt_test.c +++ b/lib/dns/tests/zt_test.c @@ -37,6 +37,11 @@ #include "dnstest.h" +struct args { + void *arg1; + void *arg2; +}; + /* * Helper functions */ @@ -72,6 +77,27 @@ all_done(void *arg) { return (ISC_R_SUCCESS); } +static void +start_zt_asyncload(isc_task_t *task, isc_event_t *event) { + struct args *args = (struct args *)(event->ev_arg); + + UNUSED(task); + + dns_zt_asyncload(args->arg1, all_done, args->arg2); + + isc_event_free(&event); +} + +static void +start_zone_asyncload(isc_task_t *task, isc_event_t *event) { + struct args *args = (struct args *)(event->ev_arg); + + UNUSED(task); + + dns_zone_asyncload(args->arg1, load_done, args->arg2); + isc_event_free(&event); +} + /* * Individual unit tests */ @@ -127,6 +153,7 @@ ATF_TC_BODY(asyncload_zone, tc) { dns_db_t *db = NULL; isc_boolean_t done = ISC_FALSE; int i = 0; + struct args args; UNUSED(tc); @@ -147,8 +174,10 @@ ATF_TC_BODY(asyncload_zone, tc) { ATF_CHECK(!dns__zone_loadpending(zone)); ATF_CHECK(!done); dns_zone_setfile(zone, "testdata/zt/zone1.db"); - dns_zone_asyncload(zone, load_done, (void *) &done); - ATF_CHECK(dns__zone_loadpending(zone)); + + args.arg1 = zone; + args.arg2 = &done; + isc_app_onrun(mctx, maintask, start_zone_asyncload, &args); isc_app_run(); while (dns__zone_loadpending(zone) && i++ < 5000) @@ -183,6 +212,7 @@ ATF_TC_BODY(asyncload_zt, tc) { dns_db_t *db = NULL; isc_boolean_t done = ISC_FALSE; int i = 0; + struct args args; UNUSED(tc); @@ -218,7 +248,10 @@ ATF_TC_BODY(asyncload_zt, tc) { ATF_CHECK(!dns__zone_loadpending(zone1)); ATF_CHECK(!dns__zone_loadpending(zone2)); ATF_CHECK(!done); - dns_zt_asyncload(zt, all_done, (void *) &done); + + args.arg1 = zt; + args.arg2 = &done; + isc_app_onrun(mctx, maintask, start_zt_asyncload, &args); isc_app_run(); while (!done && i++ < 5000) diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 3f9aae7f..56639241 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -1890,8 +1890,10 @@ isselfsigned(dns_validator_t *val) { if (result != ISC_R_SUCCESS) continue; - result = dns_dnssec_verify2(name, rdataset, dstkey, - ISC_TRUE, mctx, &sigrdata, + result = dns_dnssec_verify3(name, rdataset, dstkey, + ISC_TRUE, + val->view->maxbits, + mctx, &sigrdata, dns_fixedname_name(&fixed)); dst_key_free(&dstkey); if (result != ISC_R_SUCCESS) @@ -1928,8 +1930,9 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata, dns_fixedname_init(&fixed); wild = dns_fixedname_name(&fixed); again: - result = dns_dnssec_verify2(val->event->name, val->event->rdataset, - key, ignore, val->view->mctx, rdata, wild); + result = dns_dnssec_verify3(val->event->name, val->event->rdataset, + key, ignore, val->view->maxbits, + val->view->mctx, rdata, wild); if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) && val->view->acceptexpired) { @@ -2075,15 +2078,13 @@ validate(dns_validator_t *val, isc_boolean_t resume) { validator_log(val, ISC_LOG_DEBUG(3), "failed to verify rdataset"); else { - isc_uint32_t ttl; isc_stdtime_t now; isc_stdtime_get(&now); - ttl = ISC_MIN(event->rdataset->ttl, - ISC_MIN(val->siginfo->originalttl, - val->siginfo->timeexpire - now)); - event->rdataset->ttl = ttl; - event->sigrdataset->ttl = ttl; + dns_rdataset_trimttl(event->rdataset, + event->sigrdataset, + val->siginfo, now, + val->view->acceptexpired); } if (val->keynode != NULL) diff --git a/lib/dns/view.c b/lib/dns/view.c index 0f82b1ae..0a9727c2 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -189,9 +189,12 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->flush = ISC_FALSE; view->dlv = NULL; view->maxudp = 0; + view->maxbits = 0; view->v4_aaaa = dns_v4_aaaa_ok; view->v4_aaaa_acl = NULL; ISC_LIST_INIT(view->rpz_zones); + view->rpz_recursive_only = ISC_TRUE; + view->rpz_break_dnssec = ISC_FALSE; dns_fixedname_init(&view->dlv_fixed); view->managed_keys = NULL; view->redirect = NULL; diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def index e91ce4d4..878318fa 100644 --- a/lib/dns/win32/libdns.def +++ b/lib/dns/win32/libdns.def @@ -219,6 +219,7 @@ dns_dnssec_signs dns_dnssec_updatekeys dns_dnssec_verify dns_dnssec_verify2 +dns_dnssec_verify3 dns_dnssec_verifymessage dns_dnsseckey_create dns_dnsseckey_destroy @@ -431,7 +432,10 @@ dns_nsec3param_fromprivate dns_nsec3param_toprivate dns_nsec_build dns_nsec_buildrdata +dns_nsec_compressbitmap +dns_nsec_isset dns_nsec_nseconly +dns_nsec_setbit dns_nsec_typepresent dns_opcode_totext dns_opcodestats_create @@ -550,6 +554,7 @@ dns_rdataset_settrust dns_rdataset_totext dns_rdataset_towire dns_rdataset_towiresorted +dns_rdataset_trimttl dns_rdatasetiter_current dns_rdatasetiter_destroy dns_rdatasetiter_first diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 99b540be..5dd0b76a 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -3346,7 +3346,7 @@ zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial, &journal); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "%s:dns_journal_open -> %s\n", + "%s:dns_journal_open -> %s", caller, dns_result_totext(result)); return (result); } @@ -3357,7 +3357,7 @@ zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial, result = dns_journal_write_transaction(journal, diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "%s:dns_journal_write_transaction -> %s\n", + "%s:dns_journal_write_transaction -> %s", caller, dns_result_totext(result)); } dns_journal_destroy(&journal); @@ -3383,7 +3383,7 @@ add_soa(dns_zone_t *zone, dns_db_t *db) { result = dns_db_newversion(db, &ver); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "add_soa:dns_db_newversion -> %s\n", + "add_soa:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } @@ -3393,7 +3393,7 @@ add_soa(dns_zone_t *zone, dns_db_t *db) { 0, 0, 0, 0, 0, buf, &rdata); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "add_soa:dns_soa_buildrdata -> %s\n", + "add_soa:dns_soa_buildrdata -> %s", dns_result_totext(result)); goto failure; } @@ -3445,7 +3445,7 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) { result = dns_db_newversion(db, &ver); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "sync_keyzone:dns_db_newversion -> %s\n", + "sync_keyzone:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } @@ -5411,7 +5411,7 @@ zone_resigninc(dns_zone_t *zone) { result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:dns_db_newversion -> %s\n", + "zone_resigninc:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } @@ -5420,7 +5420,7 @@ zone_resigninc(dns_zone_t *zone) { zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:find_zone_keys -> %s\n", + "zone_resigninc:find_zone_keys -> %s", dns_result_totext(result)); goto failure; } @@ -5444,7 +5444,7 @@ zone_resigninc(dns_zone_t *zone) { result = dns_db_getsigningtime(db, &rdataset, name); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:dns_db_getsigningtime -> %s\n", + "zone_resigninc:dns_db_getsigningtime -> %s", dns_result_totext(result)); } @@ -5468,7 +5468,7 @@ zone_resigninc(dns_zone_t *zone) { zone_keys, nkeys, now, ISC_TRUE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:del_sigs -> %s\n", + "zone_resigninc:del_sigs -> %s", dns_result_totext(result)); break; } @@ -5478,7 +5478,7 @@ zone_resigninc(dns_zone_t *zone) { expire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:add_sigs -> %s\n", + "zone_resigninc:add_sigs -> %s", dns_result_totext(result)); break; } @@ -5490,7 +5490,7 @@ zone_resigninc(dns_zone_t *zone) { } if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:dns_db_getsigningtime -> %s\n", + "zone_resigninc:dns_db_getsigningtime -> %s", dns_result_totext(result)); } @@ -5501,7 +5501,7 @@ zone_resigninc(dns_zone_t *zone) { &sig_diff, zone_keys, nkeys, now, ISC_TRUE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:del_sigs -> %s\n", + "zone_resigninc:del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5517,7 +5517,7 @@ zone_resigninc(dns_zone_t *zone) { zone->updatemethod); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:update_soa_serial -> %s\n", + "zone_resigninc:update_soa_serial -> %s", dns_result_totext(result)); goto failure; } @@ -5531,7 +5531,7 @@ zone_resigninc(dns_zone_t *zone) { soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:add_sigs -> %s\n", + "zone_resigninc:add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -6233,7 +6233,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "update_sigs:del_sigs -> %s\n", + "update_sigs:del_sigs -> %s", dns_result_totext(result)); return (result); } @@ -6243,7 +6243,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, expire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "update_sigs:add_sigs -> %s\n", + "update_sigs:add_sigs -> %s", dns_result_totext(result)); return (result); } @@ -6328,7 +6328,7 @@ zone_nsec3chain(dns_zone_t *zone) { result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_nsec3chain:dns_db_newversion -> %s\n", + "zone_nsec3chain:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } @@ -6337,7 +6337,7 @@ zone_nsec3chain(dns_zone_t *zone) { DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_nsec3chain:find_zone_keys -> %s\n", + "zone_nsec3chain:find_zone_keys -> %s", dns_result_totext(result)); goto failure; } @@ -6483,7 +6483,7 @@ zone_nsec3chain(dns_zone_t *zone) { &nsec3_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "dns_nsec3_addnsec3 -> %s\n", + "dns_nsec3_addnsec3 -> %s", dns_result_totext(result)); goto failure; } @@ -6541,7 +6541,7 @@ zone_nsec3chain(dns_zone_t *zone) { } else if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "dns_dbiterator_next -> %s\n", + "dns_dbiterator_next -> %s", dns_result_totext(result)); goto failure; } else if (delegation) { @@ -6600,7 +6600,7 @@ zone_nsec3chain(dns_zone_t *zone) { if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "need_nsec_chain -> %s\n", + "need_nsec_chain -> %s", dns_result_totext(result)); goto failure; } @@ -6625,7 +6625,7 @@ zone_nsec3chain(dns_zone_t *zone) { if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "fixup_nsec3param -> %s\n", + "fixup_nsec3param -> %s", dns_result_totext(result)); goto failure; } @@ -6640,7 +6640,7 @@ zone_nsec3chain(dns_zone_t *zone) { if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "deletematchingnsec3 -> %s\n", + "deletematchingnsec3 -> %s", dns_result_totext(result)); goto failure; } @@ -6741,7 +6741,7 @@ zone_nsec3chain(dns_zone_t *zone) { if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "fixup_nsec3param -> %s\n", + "fixup_nsec3param -> %s", dns_result_totext(result)); goto failure; } @@ -6749,7 +6749,7 @@ zone_nsec3chain(dns_zone_t *zone) { } else if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "dns_dbiterator_next -> %s\n", + "dns_dbiterator_next -> %s", dns_result_totext(result)); goto failure; } else if (delegation) { @@ -6786,7 +6786,7 @@ zone_nsec3chain(dns_zone_t *zone) { result = dns_db_allrdatasets(db, node, version, 0, &iterator); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "dns_db_allrdatasets -> %s\n", + "dns_db_allrdatasets -> %s", dns_result_totext(result)); goto failure; } @@ -6812,7 +6812,7 @@ zone_nsec3chain(dns_zone_t *zone) { if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "updatesecure -> %s\n", + "updatesecure -> %s", dns_result_totext(result)); goto failure; } @@ -6825,7 +6825,7 @@ zone_nsec3chain(dns_zone_t *zone) { if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "dns_nsec3_addnsec3s -> %s\n", + "dns_nsec3_addnsec3s -> %s", dns_result_totext(result)); goto failure; } @@ -6840,7 +6840,7 @@ zone_nsec3chain(dns_zone_t *zone) { check_ksk, keyset_kskonly, &sig_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "update_sigs -> %s\n", dns_result_totext(result)); + "update_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -6853,7 +6853,7 @@ zone_nsec3chain(dns_zone_t *zone) { check_ksk, keyset_kskonly, &sig_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "update_sigs -> %s\n", dns_result_totext(result)); + "update_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -6864,7 +6864,7 @@ zone_nsec3chain(dns_zone_t *zone) { zone->minimum, ISC_FALSE, &nsec_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "updatesecure -> %s\n", + "updatesecure -> %s", dns_result_totext(result)); goto failure; } @@ -6875,7 +6875,7 @@ zone_nsec3chain(dns_zone_t *zone) { check_ksk, keyset_kskonly, &sig_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "update_sigs -> %s\n", dns_result_totext(result)); + "update_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -6890,7 +6890,7 @@ zone_nsec3chain(dns_zone_t *zone) { &sig_diff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "del_sigs -> %s\n", dns_result_totext(result)); + "del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -6898,7 +6898,7 @@ zone_nsec3chain(dns_zone_t *zone) { zone->updatemethod); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "update_soa_serial -> %s\n", + "update_soa_serial -> %s", dns_result_totext(result)); goto failure; } @@ -6908,7 +6908,7 @@ zone_nsec3chain(dns_zone_t *zone) { soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "add_sigs -> %s\n", dns_result_totext(result)); + "add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -6952,7 +6952,7 @@ zone_nsec3chain(dns_zone_t *zone) { failure: if (result != ISC_R_SUCCESS) - dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s\n", + dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s", dns_result_totext(result)); /* * On error roll back the current nsec3chain. @@ -7155,7 +7155,7 @@ zone_sign(dns_zone_t *zone) { result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:dns_db_newversion -> %s\n", + "zone_sign:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } @@ -7164,7 +7164,7 @@ zone_sign(dns_zone_t *zone) { DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:find_zone_keys -> %s\n", + "zone_sign:find_zone_keys -> %s", dns_result_totext(result)); goto failure; } @@ -7385,7 +7385,7 @@ zone_sign(dns_zone_t *zone) { if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "updatesecure -> %s\n", + "updatesecure -> %s", dns_result_totext(result)); goto failure; } @@ -7397,8 +7397,7 @@ zone_sign(dns_zone_t *zone) { &post_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "updatesignwithkey " - "-> %s\n", + "updatesignwithkey -> %s", dns_result_totext(result)); goto failure; } @@ -7406,7 +7405,7 @@ zone_sign(dns_zone_t *zone) { goto next_signing; } else if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:dns_dbiterator_next -> %s\n", + "zone_sign:dns_dbiterator_next -> %s", dns_result_totext(result)); goto failure; } else if (delegation) { @@ -7432,7 +7431,7 @@ zone_sign(dns_zone_t *zone) { check_ksk, keyset_kskonly, &sig_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:" - "update_sigs -> %s\n", + "update_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -7452,7 +7451,7 @@ zone_sign(dns_zone_t *zone) { &sig_diff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:del_sigs -> %s\n", + "zone_sign:del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -7461,7 +7460,7 @@ zone_sign(dns_zone_t *zone) { zone->updatemethod); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:update_soa_serial -> %s\n", + "zone_sign:update_soa_serial -> %s", dns_result_totext(result)); goto failure; } @@ -7475,7 +7474,7 @@ zone_sign(dns_zone_t *zone) { soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:add_sigs -> %s\n", + "zone_sign:add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -8532,7 +8531,7 @@ zone_maintenance(dns_zone_t *zone) { DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) { dumping = was_dumping(zone); - } else + } else dumping = ISC_TRUE; UNLOCK_ZONE(zone); if (!dumping) { @@ -15190,7 +15189,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "sign_apex:find_zone_keys -> %s\n", + "sign_apex:find_zone_keys -> %s", dns_result_totext(result)); return (result); } @@ -15221,7 +15220,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "sign_apex:del_sigs -> %s\n", + "sign_apex:del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -15231,7 +15230,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "sign_apex:add_sigs -> %s\n", + "sign_apex:add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -15243,7 +15242,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "sign_apex:update_sigs -> %s\n", + "sign_apex:update_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -15943,7 +15942,7 @@ keydone(isc_task_t *task, isc_event_t *event) { result = dns_db_newversion(db, &newver); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "keydone:dns_db_newversion -> %s\n", + "keydone:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } @@ -16063,7 +16062,7 @@ dns_zone_keydone(dns_zone_t *zone, const char *keystr) { kd->all = ISC_FALSE; n = sscanf(keystr, "%hd/", &keyid); - if (n == 0) + if (n == 0U) CHECK(ISC_R_FAILURE); algstr = strchr(keystr, '/'); @@ -16073,7 +16072,7 @@ dns_zone_keydone(dns_zone_t *zone, const char *keystr) { CHECK(ISC_R_FAILURE); n = sscanf(algstr, "%hhd", &alg); - if (n == 0) { + if (n == 0U) { DE_CONST(algstr, r.base); r.length = strlen(algstr); CHECK(dns_secalg_fromtext(&alg, &r)); @@ -16141,7 +16140,7 @@ setnsec3param(isc_task_t *task, isc_event_t *event) { result = dns_db_newversion(db, &newver); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "setnsec3param:dns_db_newversion -> %s\n", + "setnsec3param:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } diff --git a/lib/dns/zt.c b/lib/dns/zt.c index 5bb4cb8b..eb1e4247 100644 --- a/lib/dns/zt.c +++ b/lib/dns/zt.c @@ -46,6 +46,7 @@ struct dns_zt { dns_zt_allloaded_t loaddone; void * loaddone_arg; /* Locked by lock. */ + isc_boolean_t flush; isc_uint32_t references; unsigned int loads_pending; dns_rbt_t *table; @@ -93,8 +94,10 @@ dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) if (result != ISC_R_SUCCESS) goto cleanup_rbt; - zt->mctx = mctx; + zt->mctx = NULL; + isc_mem_attach(mctx, &zt->mctx); zt->references = 1; + zt->flush = ISC_FALSE; zt->rdclass = rdclass; zt->magic = ZTMAGIC; zt->loaddone = NULL; @@ -201,6 +204,16 @@ flush(dns_zone_t *zone, void *uap) { } static void +zt_destroy(dns_zt_t *zt) { + if (zt->flush) + (void)dns_zt_apply(zt, ISC_FALSE, flush, NULL); + dns_rbt_destroy(&zt->table); + isc_rwlock_destroy(&zt->rwlock); + zt->magic = 0; + isc_mem_putanddetach(&zt->mctx, zt, sizeof(*zt)); +} + +static void zt_flushanddetach(dns_zt_t **ztp, isc_boolean_t need_flush) { isc_boolean_t destroy = ISC_FALSE; dns_zt_t *zt; @@ -215,17 +228,13 @@ zt_flushanddetach(dns_zt_t **ztp, isc_boolean_t need_flush) { zt->references--; if (zt->references == 0) destroy = ISC_TRUE; + if (need_flush) + zt->flush = ISC_TRUE; RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); - if (destroy) { - if (need_flush) - (void)dns_zt_apply(zt, ISC_FALSE, flush, NULL); - dns_rbt_destroy(&zt->table); - isc_rwlock_destroy(&zt->rwlock); - zt->magic = 0; - isc_mem_put(zt->mctx, zt, sizeof(*zt)); - } + if (destroy) + zt_destroy(zt); *ztp = NULL; } @@ -272,10 +281,9 @@ dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) { REQUIRE(VALID_ZT(zt)); - RWLOCK(&zt->rwlock, isc_rwlocktype_read); + RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->loads_pending == 0); - result = dns_zt_apply2(zt, ISC_FALSE, NULL, asyncload, &dl); pending = zt->loads_pending; @@ -284,7 +292,7 @@ dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) { zt->loaddone_arg = arg; } - RWUNLOCK(&zt->rwlock, isc_rwlocktype_read); + RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); if (pending == 0) alldone(arg); @@ -305,10 +313,15 @@ asyncload(dns_zone_t *zone, void *callback) { REQUIRE(zone != NULL); zt = dns_zone_getview(zone)->zonetable; + INSIST(VALID_ZT(zt)); result = dns_zone_asyncload(zone, *loaded, zt); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { + INSIST(zt->references > 0); + zt->references++; + INSIST(zt->references != 0); zt->loads_pending++; + } return (ISC_R_SUCCESS); } @@ -479,6 +492,7 @@ dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub, */ static isc_result_t doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) { + isc_boolean_t destroy = ISC_FALSE; dns_zt_allloaded_t alldone = NULL; void *arg = NULL; @@ -489,6 +503,10 @@ doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) { RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->loads_pending != 0); + INSIST(zt->references != 0); + zt->references--; + if (zt->references == 0) + destroy = ISC_TRUE; zt->loads_pending--; if (zt->loads_pending == 0) { alldone = zt->loaddone; @@ -501,6 +519,9 @@ doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) { if (alldone != NULL) alldone(arg); + if (destroy) + zt_destroy(zt); + return (ISC_R_SUCCESS); } diff --git a/lib/export/Makefile.in b/lib/export/Makefile.in index fc9d4ad4..1fd72168 100644 --- a/lib/export/Makefile.in +++ b/lib/export/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/dns/Makefile.in b/lib/export/dns/Makefile.in index cd72988d..6df36fe8 100644 --- a/lib/export/dns/Makefile.in +++ b/lib/export/dns/Makefile.in @@ -44,7 +44,7 @@ LIBS = @LIBS@ # Alphabetically OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ - opensslgost_link.@O@ opensslrsa_link.@O@ + opensslecdsa_link.@O@ opensslgost_link.@O@ opensslrsa_link.@O@ DSTOBJS = @OPENSSLLINKOBJS@ \ dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \ @@ -72,7 +72,7 @@ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} ${PORTDNSOBJS} # Alphabetically OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ - opensslgost_link.c opensslrsa_link.c + opensslecdsa_link.c opensslgost_link.c opensslrsa_link.c DSTSRCS = @OPENSSLLINKSRCS@ \ dst_api.c dst_lib.c dst_parse.c \ diff --git a/lib/export/dns/include/Makefile.in b/lib/export/dns/include/Makefile.in index 9fc0b66b..6bf12053 100644 --- a/lib/export/dns/include/Makefile.in +++ b/lib/export/dns/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/dns/include/dns/Makefile.in b/lib/export/dns/include/dns/Makefile.in index 2d7f2c78..b7f51b4a 100644 --- a/lib/export/dns/include/dns/Makefile.in +++ b/lib/export/dns/include/dns/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/dns/include/dst/Makefile.in b/lib/export/dns/include/dst/Makefile.in index 259e62ed..f6f540a2 100644 --- a/lib/export/dns/include/dst/Makefile.in +++ b/lib/export/dns/include/dst/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/irs/include/irs/Makefile.in b/lib/export/irs/include/irs/Makefile.in index c8507571..530e67c8 100644 --- a/lib/export/irs/include/irs/Makefile.in +++ b/lib/export/irs/include/irs/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/isc/Makefile.in b/lib/export/isc/Makefile.in index a55a1f44..86726ab3 100644 --- a/lib/export/isc/Makefile.in +++ b/lib/export/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/isc/include/isc/Makefile.in b/lib/export/isc/include/isc/Makefile.in index 24991853..91f538c4 100644 --- a/lib/export/isc/include/isc/Makefile.in +++ b/lib/export/isc/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/isc/nls/Makefile.in b/lib/export/isc/nls/Makefile.in index a9e779f9..25156854 100644 --- a/lib/export/isc/nls/Makefile.in +++ b/lib/export/isc/nls/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/isc/nothreads/Makefile.in b/lib/export/isc/nothreads/Makefile.in index 93b21093..994da636 100644 --- a/lib/export/isc/nothreads/Makefile.in +++ b/lib/export/isc/nothreads/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/isc/nothreads/include/isc/Makefile.in b/lib/export/isc/nothreads/include/isc/Makefile.in index eb25c885..9bda987d 100644 --- a/lib/export/isc/nothreads/include/isc/Makefile.in +++ b/lib/export/isc/nothreads/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/isc/pthreads/Makefile.in b/lib/export/isc/pthreads/Makefile.in index 92788ec1..f08e5c63 100644 --- a/lib/export/isc/pthreads/Makefile.in +++ b/lib/export/isc/pthreads/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/isc/pthreads/include/isc/Makefile.in b/lib/export/isc/pthreads/include/isc/Makefile.in index 77d5c077..43197685 100644 --- a/lib/export/isc/pthreads/include/isc/Makefile.in +++ b/lib/export/isc/pthreads/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/isc/unix/Makefile.in b/lib/export/isc/unix/Makefile.in index 5a8eed88..f5cf7e86 100644 --- a/lib/export/isc/unix/Makefile.in +++ b/lib/export/isc/unix/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/isc/unix/include/isc/Makefile.in b/lib/export/isc/unix/include/isc/Makefile.in index f19b8c65..7159c768 100644 --- a/lib/export/isc/unix/include/isc/Makefile.in +++ b/lib/export/isc/unix/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/isccfg/include/isccfg/Makefile.in b/lib/export/isccfg/include/isccfg/Makefile.in index 5e9ea78d..57a344cc 100644 --- a/lib/export/isccfg/include/isccfg/Makefile.in +++ b/lib/export/isccfg/include/isccfg/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/samples/Makefile-postinstall.in b/lib/export/samples/Makefile-postinstall.in index 174aed60..5b1aafba 100644 --- a/lib/export/samples/Makefile-postinstall.in +++ b/lib/export/samples/Makefile-postinstall.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/export/samples/Makefile.in b/lib/export/samples/Makefile.in index c60baac5..cdc66b16 100644 --- a/lib/export/samples/Makefile.in +++ b/lib/export/samples/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/irs/Makefile.in b/lib/irs/Makefile.in index ed869679..d3c47b01 100644 --- a/lib/irs/Makefile.in +++ b/lib/irs/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/irs/include/Makefile.in b/lib/irs/include/Makefile.in index eca19452..91099f1e 100644 --- a/lib/irs/include/Makefile.in +++ b/lib/irs/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/irs/include/irs/Makefile.in b/lib/irs/include/irs/Makefile.in index 3c3b6127..63e7fd6b 100644 --- a/lib/irs/include/irs/Makefile.in +++ b/lib/irs/include/irs/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/alpha/Makefile.in b/lib/isc/alpha/Makefile.in index 324db070..9c24cdf9 100644 --- a/lib/isc/alpha/Makefile.in +++ b/lib/isc/alpha/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/alpha/include/Makefile.in b/lib/isc/alpha/include/Makefile.in index f1d8bdd3..e3995599 100644 --- a/lib/isc/alpha/include/Makefile.in +++ b/lib/isc/alpha/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/alpha/include/isc/Makefile.in b/lib/isc/alpha/include/isc/Makefile.in index 5f116cac..4927e210 100644 --- a/lib/isc/alpha/include/isc/Makefile.in +++ b/lib/isc/alpha/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/api b/lib/isc/api index ed4b69f8..178430ae 100644 --- a/lib/isc/api +++ b/lib/isc/api @@ -3,6 +3,6 @@ # 9.7: 60-79 # 9.8: 80-89 # 9.9: 90-109 -LIBINTERFACE = 91 -LIBREVISION = 1 +LIBINTERFACE = 93 +LIBREVISION = 0 LIBAGE = 1 diff --git a/lib/isc/ia64/Makefile.in b/lib/isc/ia64/Makefile.in index 324db070..9c24cdf9 100644 --- a/lib/isc/ia64/Makefile.in +++ b/lib/isc/ia64/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/ia64/include/Makefile.in b/lib/isc/ia64/include/Makefile.in index f1d8bdd3..e3995599 100644 --- a/lib/isc/ia64/include/Makefile.in +++ b/lib/isc/ia64/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/ia64/include/isc/Makefile.in b/lib/isc/ia64/include/isc/Makefile.in index 5f116cac..4927e210 100644 --- a/lib/isc/ia64/include/isc/Makefile.in +++ b/lib/isc/ia64/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/ia64/include/isc/atomic.h b/lib/isc/ia64/include/isc/atomic.h index 6c22f2a5..557941d0 100644 --- a/lib/isc/ia64/include/isc/atomic.h +++ b/lib/isc/ia64/include/isc/atomic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2006, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -41,7 +41,7 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) { swapped = prev + val; __asm__ volatile( - "mov ar.ccv=%2;" + "mov ar.ccv=%2;;" "cmpxchg4.acq %0=%4,%3,ar.ccv" : "=r" (swapped), "=m" (*p) : "r" (prev), "r" (swapped), "m" (*p) @@ -84,7 +84,7 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) isc_int32_t ret; __asm__ volatile( - "mov ar.ccv=%2;" + "mov ar.ccv=%2;;" "cmpxchg4.acq %0=%4,%3,ar.ccv" : "=r" (ret), "=m" (*p) : "r" (cmpval), "r" (val), "m" (*p) diff --git a/lib/isc/include/Makefile.in b/lib/isc/include/Makefile.in index 04778d78..70c165ef 100644 --- a/lib/isc/include/Makefile.in +++ b/lib/isc/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h index 8794065b..38f78b74 100644 --- a/lib/isc/include/isc/file.h +++ b/lib/isc/include/isc/file.h @@ -25,6 +25,7 @@ #include <stdio.h> #include <isc/lang.h> +#include <isc/stat.h> #include <isc/types.h> ISC_LANG_BEGINDECLS @@ -33,6 +34,9 @@ isc_result_t isc_file_settime(const char *file, isc_time_t *time); isc_result_t +isc_file_mode(const char *file, mode_t *modep); + +isc_result_t isc_file_getmodtime(const char *file, isc_time_t *time); /*!< * \brief Get the time of last modification of a file. @@ -97,15 +101,22 @@ isc_file_mktemplate(const char *path, char *buf, size_t buflen); * of the path with the internal template string. */ - isc_result_t isc_file_openunique(char *templet, FILE **fp); isc_result_t isc_file_openuniqueprivate(char *templet, FILE **fp); isc_result_t isc_file_openuniquemode(char *templet, int mode, FILE **fp); +isc_result_t +isc_file_bopenunique(char *templet, FILE **fp); +isc_result_t +isc_file_bopenuniqueprivate(char *templet, FILE **fp); +isc_result_t +isc_file_bopenuniquemode(char *templet, int mode, FILE **fp); /*!< * \brief Create and open a file with a unique name based on 'templet'. + * isc_file_bopen*() open the file in binary mode in Windows. + * isc_file_open*() open the file in text mode in Windows. * * Notes: *\li 'template' is a reserved work in C++. If you want to complain diff --git a/lib/isc/include/isc/heap.h b/lib/isc/include/isc/heap.h index 77bf07c3..0b3a53b0 100644 --- a/lib/isc/include/isc/heap.h +++ b/lib/isc/include/isc/heap.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -60,6 +60,8 @@ isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare, * storage method. When the heap elements are deleted space is not freed * but will be reused when new elements are inserted. * + * Heap elements are indexed from 1. + * * Requires: *\li "mctx" is valid. *\li "compare" is a function which takes two void * arguments and diff --git a/lib/isc/include/isc/namespace.h b/lib/isc/include/isc/namespace.h index cd4ec9ad..05b7daa7 100644 --- a/lib/isc/include/isc/namespace.h +++ b/lib/isc/include/isc/namespace.h @@ -151,6 +151,8 @@ #define isc_taskmgr_setmode isc__taskmgr_setmode #define isc_taskmgr_mode isc__taskmgr_mode #define isc_taskmgr_destroy isc__taskmgr_destroy +#define isc_taskmgr_setexcltask isc__taskmgr_setexcltask +#define isc_taskmgr_excltask isc__taskmgr_excltask #define isc_task_beginexclusive isc__task_beginexclusive #define isc_task_endexclusive isc__task_endexclusive #define isc_task_setprivilege isc__task_setprivilege diff --git a/lib/isc/include/isc/queue.h b/lib/isc/include/isc/queue.h index 1bc9d5b4..22e2a01e 100644 --- a/lib/isc/include/isc/queue.h +++ b/lib/isc/include/isc/queue.h @@ -35,7 +35,7 @@ #define ISC_QLINK_INSIST(x) (void)0 #endif -#define ISC_QLINK(type) struct { void *prev, *next; } +#define ISC_QLINK(type) struct { type *prev, *next; } #define ISC_QLINK_INIT(elt, link) \ do { \ @@ -142,4 +142,22 @@ (ret)->link.next = (ret)->link.prev = (void *)(-1); \ } while(0) +#define ISC_QUEUE_UNLINK(queue, elt, link) \ + do { \ + ISC_QLINK_INSIST(ISC_QLINK_LINKED(elt, link)); \ + LOCK(&(queue).headlock); \ + LOCK(&(queue).taillock); \ + if ((elt)->link.prev == NULL) \ + (queue).head = (elt)->link.next; \ + else \ + (elt)->link.prev->link.next = (elt)->link.next; \ + if ((elt)->link.next == NULL) \ + (queue).tail = (elt)->link.prev; \ + else \ + (elt)->link.next->link.prev = (elt)->link.prev; \ + UNLOCK(&(queue).taillock); \ + UNLOCK(&(queue).headlock); \ + (elt)->link.next = (elt)->link.prev = (void *)(-1); \ + } while(0) + #endif /* ISC_QUEUE_H */ diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h index 594d80f3..c63c3e66 100644 --- a/lib/isc/include/isc/task.h +++ b/lib/isc/include/isc/task.h @@ -115,6 +115,8 @@ typedef struct isc_taskmgrmethods { isc_result_t (*taskcreate)(isc_taskmgr_t *manager, unsigned int quantum, isc_task_t **taskp); + void (*setexcltask)(isc_taskmgr_t *mgr, isc_task_t *task); + isc_result_t (*excltask)(isc_taskmgr_t *mgr, isc_task_t **taskp); } isc_taskmgrmethods_t; typedef struct isc_taskmethods { @@ -759,6 +761,31 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp); * have been freed. */ +void +isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task); +/*%< + * Set a task which will be used for all task-exclusive operations. + * + * Requires: + *\li 'manager' is a valid task manager. + * + *\li 'task' is a valid task. + */ + +isc_result_t +isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp); +/*%< + * Attach '*taskp' to the task set by isc_taskmgr_getexcltask(). + * This task should be used whenever running in task-exclusive mode, + * so as to prevent deadlock between two exclusive tasks. + * + * Requires: + *\li 'manager' is a valid task manager. + + *\li taskp != NULL && *taskp == NULL + */ + + #ifdef HAVE_LIBXML2 void diff --git a/lib/isc/mem.c b/lib/isc/mem.c index 5b4b16c5..1964b7a0 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -1191,7 +1191,7 @@ isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) { oldsize -= ALIGNMENT_SIZE; INSIST(oldsize == size); } - isc_mem_free((isc_mem_t *)ctx, ptr); + isc__mem_free((isc_mem_t *)ctx, ptr FLARG_PASS); MCTXLOCK(ctx, &ctx->lock); ctx->references--; @@ -1327,7 +1327,7 @@ isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) { oldsize -= ALIGNMENT_SIZE; INSIST(oldsize == size); } - isc_mem_free((isc_mem_t *)ctx, ptr); + isc__mem_free((isc_mem_t *)ctx, ptr FLARG_PASS); return; } @@ -1592,7 +1592,11 @@ isc___mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) { oldsize = (((size_info *)ptr)[-1]).u.size; INSIST(oldsize >= ALIGNMENT_SIZE); oldsize -= ALIGNMENT_SIZE; - copysize = oldsize > size ? size : oldsize; + if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) { + INSIST(oldsize >= ALIGNMENT_SIZE); + oldsize -= ALIGNMENT_SIZE; + } + copysize = (oldsize > size) ? size : oldsize; memcpy(new_ptr, ptr, copysize); isc__mem_free(ctx0, ptr FLARG_PASS); } diff --git a/lib/isc/mips/Makefile.in b/lib/isc/mips/Makefile.in index 324db070..9c24cdf9 100644 --- a/lib/isc/mips/Makefile.in +++ b/lib/isc/mips/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/mips/include/Makefile.in b/lib/isc/mips/include/Makefile.in index f1d8bdd3..e3995599 100644 --- a/lib/isc/mips/include/Makefile.in +++ b/lib/isc/mips/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/mips/include/isc/Makefile.in b/lib/isc/mips/include/isc/Makefile.in index 5f116cac..4927e210 100644 --- a/lib/isc/mips/include/isc/Makefile.in +++ b/lib/isc/mips/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/nls/Makefile.in b/lib/isc/nls/Makefile.in index aca4a273..7bacf1c8 100644 --- a/lib/isc/nls/Makefile.in +++ b/lib/isc/nls/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/noatomic/Makefile.in b/lib/isc/noatomic/Makefile.in index 324db070..9c24cdf9 100644 --- a/lib/isc/noatomic/Makefile.in +++ b/lib/isc/noatomic/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/noatomic/include/Makefile.in b/lib/isc/noatomic/include/Makefile.in index f1d8bdd3..e3995599 100644 --- a/lib/isc/noatomic/include/Makefile.in +++ b/lib/isc/noatomic/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/noatomic/include/isc/Makefile.in b/lib/isc/noatomic/include/isc/Makefile.in index 5f116cac..4927e210 100644 --- a/lib/isc/noatomic/include/isc/Makefile.in +++ b/lib/isc/noatomic/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/nothreads/Makefile.in b/lib/isc/nothreads/Makefile.in index 7e7abd6b..540b2434 100644 --- a/lib/isc/nothreads/Makefile.in +++ b/lib/isc/nothreads/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/nothreads/include/Makefile.in b/lib/isc/nothreads/include/Makefile.in index a52310a6..662a72df 100644 --- a/lib/isc/nothreads/include/Makefile.in +++ b/lib/isc/nothreads/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/nothreads/include/isc/Makefile.in b/lib/isc/nothreads/include/isc/Makefile.in index 3c9eab0e..a2c347ea 100644 --- a/lib/isc/nothreads/include/isc/Makefile.in +++ b/lib/isc/nothreads/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/powerpc/Makefile.in b/lib/isc/powerpc/Makefile.in index 324db070..9c24cdf9 100644 --- a/lib/isc/powerpc/Makefile.in +++ b/lib/isc/powerpc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/powerpc/include/Makefile.in b/lib/isc/powerpc/include/Makefile.in index f1d8bdd3..e3995599 100644 --- a/lib/isc/powerpc/include/Makefile.in +++ b/lib/isc/powerpc/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/powerpc/include/isc/Makefile.in b/lib/isc/powerpc/include/isc/Makefile.in index 5f116cac..4927e210 100644 --- a/lib/isc/powerpc/include/isc/Makefile.in +++ b/lib/isc/powerpc/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/pthreads/Makefile.in b/lib/isc/pthreads/Makefile.in index d6e7c760..9f66ef33 100644 --- a/lib/isc/pthreads/Makefile.in +++ b/lib/isc/pthreads/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/pthreads/condition.c b/lib/isc/pthreads/condition.c index 50281a2b..9053cf0f 100644 --- a/lib/isc/pthreads/condition.c +++ b/lib/isc/pthreads/condition.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -43,7 +43,14 @@ isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) { * POSIX defines a timespec's tv_sec as time_t. */ result = isc_time_secondsastimet(t, &ts.tv_sec); - if (result != ISC_R_SUCCESS) + + /* + * If we have a range error ts.tv_sec is most probably a signed + * 32 bit value. Set ts.tv_sec to INT_MAX. This is a kludge. + */ + if (result == ISC_R_RANGE) + ts.tv_sec = INT_MAX; + else if (result != ISC_R_SUCCESS) return (result); /*! diff --git a/lib/isc/pthreads/include/Makefile.in b/lib/isc/pthreads/include/Makefile.in index 0303ab13..46c243e1 100644 --- a/lib/isc/pthreads/include/Makefile.in +++ b/lib/isc/pthreads/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/pthreads/include/isc/Makefile.in b/lib/isc/pthreads/include/isc/Makefile.in index 11675ec2..7cadcf4b 100644 --- a/lib/isc/pthreads/include/isc/Makefile.in +++ b/lib/isc/pthreads/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/sparc64/Makefile.in b/lib/isc/sparc64/Makefile.in index 324db070..9c24cdf9 100644 --- a/lib/isc/sparc64/Makefile.in +++ b/lib/isc/sparc64/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/sparc64/include/Makefile.in b/lib/isc/sparc64/include/Makefile.in index f1d8bdd3..e3995599 100644 --- a/lib/isc/sparc64/include/Makefile.in +++ b/lib/isc/sparc64/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/sparc64/include/isc/Makefile.in b/lib/isc/sparc64/include/isc/Makefile.in index 5f116cac..4927e210 100644 --- a/lib/isc/sparc64/include/isc/Makefile.in +++ b/lib/isc/sparc64/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/task.c b/lib/isc/task.c index 227b2959..9c8badd4 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -156,6 +156,7 @@ struct isc__taskmgr { isc_boolean_t pause_requested; isc_boolean_t exclusive_requested; isc_boolean_t exiting; + isc__task_t *excl; #ifdef USE_SHARED_MANAGER unsigned int refs; #endif /* ISC_PLATFORM_USETHREADS */ @@ -225,6 +226,10 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers, unsigned int default_quantum, isc_taskmgr_t **managerp); ISC_TASKFUNC_SCOPE void isc__taskmgr_destroy(isc_taskmgr_t **managerp); +ISC_TASKFUNC_SCOPE void +isc__taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0); +ISC_TASKFUNC_SCOPE isc_result_t +isc__taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp); ISC_TASKFUNC_SCOPE isc_result_t isc__task_beginexclusive(isc_task_t *task); ISC_TASKFUNC_SCOPE void @@ -286,7 +291,9 @@ static isc_taskmgrmethods_t taskmgrmethods = { isc__taskmgr_destroy, isc__taskmgr_setmode, isc__taskmgr_mode, - isc__task_create + isc__task_create, + isc__taskmgr_setexcltask, + isc__taskmgr_excltask }; /*** @@ -1396,6 +1403,7 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers, manager->exclusive_requested = ISC_FALSE; manager->pause_requested = ISC_FALSE; manager->exiting = ISC_FALSE; + manager->excl = NULL; isc_mem_attach(mctx, &manager->mctx); @@ -1480,6 +1488,12 @@ isc__taskmgr_destroy(isc_taskmgr_t **managerp) { */ /* + * Detach the exclusive task before acquiring the manager lock + */ + if (manager->excl != NULL) + isc__task_detach((isc_task_t **) &manager->excl); + + /* * Unlike elsewhere, we're going to hold this lock a long time. * We need to do so, because otherwise the list of tasks could * change while we were traversing it. @@ -1629,12 +1643,41 @@ isc__taskmgr_resume(isc_taskmgr_t *manager0) { } #endif /* USE_WORKER_THREADS */ +ISC_TASKFUNC_SCOPE void +isc__taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0) { + isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0; + isc__task_t *task = (isc__task_t *) task0; + + REQUIRE(VALID_MANAGER(mgr)); + REQUIRE(VALID_TASK(task)); + if (mgr->excl != NULL) + isc__task_detach((isc_task_t **) &mgr->excl); + isc__task_attach(task0, (isc_task_t **) &mgr->excl); +} + +ISC_TASKFUNC_SCOPE isc_result_t +isc__taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp) { + isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0; + + REQUIRE(VALID_MANAGER(mgr)); + REQUIRE(taskp != NULL && *taskp == NULL); + + if (mgr->excl == NULL) + return (ISC_R_NOTFOUND); + + isc__task_attach((isc_task_t *) mgr->excl, taskp); + return (ISC_R_SUCCESS); +} + ISC_TASKFUNC_SCOPE isc_result_t isc__task_beginexclusive(isc_task_t *task0) { #ifdef USE_WORKER_THREADS isc__task_t *task = (isc__task_t *)task0; isc__taskmgr_t *manager = task->manager; + REQUIRE(task->state == task_state_running); + /* XXX: Require task == manager->excl? */ + LOCK(&manager->lock); if (manager->exclusive_requested) { UNLOCK(&manager->lock); diff --git a/lib/isc/task_api.c b/lib/isc/task_api.c index 34510ff6..f49ab321 100644 --- a/lib/isc/task_api.c +++ b/lib/isc/task_api.c @@ -201,6 +201,17 @@ isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag) return (task->methods->purgeevents(task, sender, type, tag)); } +void +isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task) { + REQUIRE(ISCAPI_TASK_VALID(task)); + return (mgr->methods->setexcltask(mgr, task)); +} + +isc_result_t +isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp) { + return (mgr->methods->excltask(mgr, taskp)); +} + isc_result_t isc_task_beginexclusive(isc_task_t *task) { REQUIRE(ISCAPI_TASK_VALID(task)); diff --git a/lib/isc/tests/isctest.c b/lib/isc/tests/isctest.c index e118bbf2..41b09fce 100644 --- a/lib/isc/tests/isctest.c +++ b/lib/isc/tests/isctest.c @@ -42,6 +42,7 @@ isc_log_t *lctx = NULL; isc_taskmgr_t *taskmgr = NULL; isc_timermgr_t *timermgr = NULL; isc_socketmgr_t *socketmgr = NULL; +isc_task_t *maintask = NULL; int ncpus; static isc_boolean_t hash_active = ISC_FALSE; @@ -63,6 +64,8 @@ static isc_logcategory_t categories[] = { static void cleanup_managers() { + if (maintask != NULL) + isc_task_destroy(&maintask); if (socketmgr != NULL) isc_socketmgr_destroy(&socketmgr); if (taskmgr != NULL) @@ -81,6 +84,9 @@ create_managers() { #endif CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr)); + CHECK(isc_task_create(taskmgr, 0, &maintask)); + isc_taskmgr_setexcltask(taskmgr, maintask); + CHECK(isc_timermgr_create(mctx, &timermgr)); CHECK(isc_socketmgr_create(mctx, &socketmgr)); return (ISC_R_SUCCESS); @@ -138,6 +144,8 @@ isc_test_begin(FILE *logfile, isc_boolean_t start_managers) { void isc_test_end() { + if (maintask != NULL) + isc_task_detach(&maintask); if (taskmgr != NULL) isc_taskmgr_destroy(&taskmgr); if (lctx != NULL) diff --git a/lib/isc/tests/queue_test.c b/lib/isc/tests/queue_test.c index 74620fef..c4a80c4c 100644 --- a/lib/isc/tests/queue_test.c +++ b/lib/isc/tests/queue_test.c @@ -29,10 +29,11 @@ #include "isctest.h" -typedef struct item { +typedef struct item item_t; +struct item { int value; ISC_QLINK(item_t) qlink; -} item_t; +}; typedef ISC_QUEUE(item_t) item_queue_t; @@ -107,6 +108,9 @@ ATF_TC_BODY(queue_valid, tc) { ISC_QUEUE_PUSH(queue, &five, qlink); ATF_CHECK(ISC_QLINK_LINKED(&five, qlink)); + /* Test unlink by removing one item from the middle */ + ISC_QUEUE_UNLINK(queue, &three, qlink); + ISC_QUEUE_POP(queue, qlink, p); ATF_REQUIRE(p != NULL); ATF_CHECK_EQ(p->value, 1); @@ -117,10 +121,6 @@ ATF_TC_BODY(queue_valid, tc) { ISC_QUEUE_POP(queue, qlink, p); ATF_REQUIRE(p != NULL); - ATF_CHECK_EQ(p->value, 3); - - ISC_QUEUE_POP(queue, qlink, p); - ATF_REQUIRE(p != NULL); ATF_CHECK_EQ(p->value, 4); ISC_QUEUE_POP(queue, qlink, p); diff --git a/lib/isc/unix/Makefile.in b/lib/isc/unix/Makefile.in index 9884ca90..c1411cb3 100644 --- a/lib/isc/unix/Makefile.in +++ b/lib/isc/unix/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/unix/file.c b/lib/isc/unix/file.c index 0538761a..99c02ec7 100644 --- a/lib/isc/unix/file.c +++ b/lib/isc/unix/file.c @@ -98,6 +98,20 @@ file_stats(const char *file, struct stat *stats) { } isc_result_t +isc_file_mode(const char *file, mode_t *modep) { + isc_result_t result; + struct stat stats; + + REQUIRE(modep != NULL); + + result = file_stats(file, &stats); + if (result == ISC_R_SUCCESS) + *modep = (stats.st_mode & 07777); + + return (result); +} + +isc_result_t isc_file_getmodtime(const char *file, isc_time_t *time) { isc_result_t result; struct stat stats; @@ -313,6 +327,23 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) { } isc_result_t +isc_file_bopenunique(char *templet, FILE **fp) { + int mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; + return (isc_file_openuniquemode(templet, mode, fp)); +} + +isc_result_t +isc_file_bopenuniqueprivate(char *templet, FILE **fp) { + int mode = S_IWUSR|S_IRUSR; + return (isc_file_openuniquemode(templet, mode, fp)); +} + +isc_result_t +isc_file_bopenuniquemode(char *templet, int mode, FILE **fp) { + return (isc_file_openuniquemode(templet, mode, fp)); +} + +isc_result_t isc_file_remove(const char *filename) { int r; diff --git a/lib/isc/unix/include/Makefile.in b/lib/isc/unix/include/Makefile.in index 0303ab13..46c243e1 100644 --- a/lib/isc/unix/include/Makefile.in +++ b/lib/isc/unix/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/unix/include/isc/Makefile.in b/lib/isc/unix/include/isc/Makefile.in index 2f4d2164..d3b50842 100644 --- a/lib/isc/unix/include/isc/Makefile.in +++ b/lib/isc/unix/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/win32/Makefile.in b/lib/isc/win32/Makefile.in index 3396db1e..c129e31c 100644 --- a/lib/isc/win32/Makefile.in +++ b/lib/isc/win32/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/win32/file.c b/lib/isc/win32/file.c index c6b9e4f5..146fd35e 100644 --- a/lib/isc/win32/file.c +++ b/lib/isc/win32/file.c @@ -45,10 +45,14 @@ * */ static int -gettemp(char *path, int *doopen) { +gettemp(char *path, isc_boolean_t binary, int *doopen) { char *start, *trv; struct stat sbuf; int pid; + int flags = O_CREAT|O_EXCL|O_RDWR; + + if (binary) + flags |= _O_BINARY; trv = strrchr(path, 'X'); trv++; @@ -81,8 +85,7 @@ gettemp(char *path, int *doopen) { for (;;) { if (doopen) { if ((*doopen = - open(path, O_CREAT|O_EXCL|O_RDWR, - _S_IREAD | _S_IWRITE)) >= 0) + open(path, flags, _S_IREAD | _S_IWRITE)) >= 0) return (1); if (errno != EEXIST) return (0); @@ -108,10 +111,10 @@ gettemp(char *path, int *doopen) { } static int -mkstemp(char *path) { +mkstemp(char *path, isc_boolean_t binary) { int fd; - return (gettemp(path, &fd) ? fd : -1); + return (gettemp(path, binary, &fd) ? fd : -1); } /* @@ -165,7 +168,7 @@ isc_file_safemovefile(const char *oldname, const char *newname) { exists = TRUE; strcpy(buf, newname); strcat(buf, ".XXXXX"); - tmpfd = mkstemp(buf); + tmpfd = mkstemp(buf, ISC_TRUE); if (tmpfd > 0) _close(tmpfd); DeleteFile(buf); @@ -300,7 +303,7 @@ isc_file_renameunique(const char *file, char *templet) { REQUIRE(file != NULL); REQUIRE(templet != NULL); - fd = mkstemp(templet); + fd = mkstemp(templet, ISC_TRUE); if (fd == -1) result = isc__errno2result(errno); else @@ -316,20 +319,8 @@ isc_file_renameunique(const char *file, char *templet) { return (result); } -isc_result_t -isc_file_openuniqueprivate(char *templet, FILE **fp) { - int mode = _S_IREAD | _S_IWRITE; - return (isc_file_openuniquemode(templet, mode, fp)); -} - -isc_result_t -isc_file_openunique(char *templet, FILE **fp) { - int mode = _S_IREAD | _S_IWRITE; - return (isc_file_openuniquemode(templet, mode, fp)); -} - -isc_result_t -isc_file_openuniquemode(char *templet, int mode, FILE **fp) { +static isc_result_t +openuniquemode(char *templet, int mode, isc_boolean_t binary, FILE **fp) { int fd; FILE *f; isc_result_t result = ISC_R_SUCCESS; @@ -340,7 +331,7 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) { /* * Win32 does not have mkstemp. Using emulation above. */ - fd = mkstemp(templet); + fd = mkstemp(templet, binary); if (fd == -1) result = isc__errno2result(errno); @@ -350,7 +341,7 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) { #else (void)fchmod(fd, mode); #endif - f = fdopen(fd, "w+"); + f = fdopen(fd, binary ? "wb+" : "w+"); if (f == NULL) { result = isc__errno2result(errno); (void)remove(templet); @@ -363,6 +354,40 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) { } isc_result_t +isc_file_openuniqueprivate(char *templet, FILE **fp) { + int mode = _S_IREAD | _S_IWRITE; + return (openuniquemode(templet, mode, ISC_FALSE, fp)); +} + +isc_result_t +isc_file_openunique(char *templet, FILE **fp) { + int mode = _S_IREAD | _S_IWRITE; + return (openuniquemode(templet, mode, ISC_FALSE, fp)); +} + +isc_result_t +isc_file_openuniquemode(char *templet, int mode, FILE **fp) { + return (openuniquemode(templet, mode, ISC_FALSE, fp)); +} + +isc_result_t +isc_file_bopenuniqueprivate(char *templet, FILE **fp) { + int mode = _S_IREAD | _S_IWRITE; + return (openuniquemode(templet, mode, ISC_TRUE, fp)); +} + +isc_result_t +isc_file_bopenunique(char *templet, FILE **fp) { + int mode = _S_IREAD | _S_IWRITE; + return (openuniquemode(templet, mode, ISC_TRUE, fp)); +} + +isc_result_t +isc_file_bopenuniquemode(char *templet, int mode, FILE **fp) { + return (openuniquemode(templet, mode, ISC_TRUE, fp)); +} + +isc_result_t isc_file_remove(const char *filename) { int r; @@ -617,3 +642,16 @@ isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename) return (ISC_R_SUCCESS); } + +isc_result_t +isc_file_mode(const char *file, mode_t *modep) { + isc_result_t result; + struct stat stats; + + REQUIRE(modep != NULL); + + result = file_stats(file, &stats); + if (result == ISC_R_SUCCESS) + *modep = (stats.st_mode & 07777); + return (result); +} diff --git a/lib/isc/win32/include/Makefile.in b/lib/isc/win32/include/Makefile.in index c74b52d2..60435f9e 100644 --- a/lib/isc/win32/include/Makefile.in +++ b/lib/isc/win32/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/win32/include/isc/Makefile.in b/lib/isc/win32/include/isc/Makefile.in index dcd85190..6b5bcea2 100644 --- a/lib/isc/win32/include/isc/Makefile.in +++ b/lib/isc/win32/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/win32/include/isc/stat.h b/lib/isc/win32/include/isc/stat.h index 2c822b9e..6703e329 100644 --- a/lib/isc/win32/include/isc/stat.h +++ b/lib/isc/win32/include/isc/stat.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -22,6 +22,11 @@ #include <sys/stat.h> +/* + * Windows doesn't typedef this. + */ +typedef unsigned short mode_t; + /* open() under unix allows setting of read/write permissions * at the owner, group and other levels. These don't exist in NT * We'll just map them all to the NT equivalent diff --git a/lib/isc/win32/libisc.def b/lib/isc/win32/libisc.def index fb084103..fe3f739b 100644 --- a/lib/isc/win32/libisc.def +++ b/lib/isc/win32/libisc.def @@ -140,7 +140,9 @@ isc__task_unsend isc__task_unsendrange isc__taskmgr_create isc__taskmgr_destroy +isc__taskmgr_excltask isc__taskmgr_mode +isc__taskmgr_setexcltask isc__taskmgr_setmode isc__timer_attach isc__timer_create @@ -218,6 +220,9 @@ isc_event_allocate isc_event_free isc_file_absolutepath isc_file_basename +isc_file_bopenunique +isc_file_bopenuniquemode +isc_file_bopenuniqueprivate isc_file_exists isc_file_getmodtime isc_file_isabsolute @@ -225,6 +230,7 @@ isc_file_ischdiridempotent isc_file_iscurrentdir isc_file_isplainfile isc_file_mktemplate +isc_file_mode isc_file_openunique isc_file_openuniquemode isc_file_openuniqueprivate diff --git a/lib/isc/x86_32/Makefile.in b/lib/isc/x86_32/Makefile.in index 324db070..9c24cdf9 100644 --- a/lib/isc/x86_32/Makefile.in +++ b/lib/isc/x86_32/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/x86_32/include/Makefile.in b/lib/isc/x86_32/include/Makefile.in index f1d8bdd3..e3995599 100644 --- a/lib/isc/x86_32/include/Makefile.in +++ b/lib/isc/x86_32/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/x86_32/include/isc/Makefile.in b/lib/isc/x86_32/include/isc/Makefile.in index 5f116cac..4927e210 100644 --- a/lib/isc/x86_32/include/isc/Makefile.in +++ b/lib/isc/x86_32/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/x86_64/Makefile.in b/lib/isc/x86_64/Makefile.in index 324db070..9c24cdf9 100644 --- a/lib/isc/x86_64/Makefile.in +++ b/lib/isc/x86_64/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/x86_64/include/Makefile.in b/lib/isc/x86_64/include/Makefile.in index f1d8bdd3..e3995599 100644 --- a/lib/isc/x86_64/include/Makefile.in +++ b/lib/isc/x86_64/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isc/x86_64/include/isc/Makefile.in b/lib/isc/x86_64/include/isc/Makefile.in index f33ae994..9a988bb7 100644 --- a/lib/isc/x86_64/include/isc/Makefile.in +++ b/lib/isc/x86_64/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/isccc/api b/lib/isccc/api index 59e4f66c..e34aa945 100644 --- a/lib/isccc/api +++ b/lib/isccc/api @@ -4,5 +4,5 @@ # 9.8: 80-89 # 9.9: 90-109 LIBINTERFACE = 90 -LIBREVISION = 1 +LIBREVISION = 2 LIBAGE = 0 diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c index b549d6cb..1ab94798 100644 --- a/lib/isccc/cc.c +++ b/lib/isccc/cc.c @@ -399,8 +399,6 @@ table_fromwire(isccc_region_t *source, isccc_region_t *secret, first_tag = ISC_FALSE; } - *alistp = alist; - if (secret != NULL) { if (checksum_rstart != NULL) result = verify(alist, checksum_rstart, @@ -412,7 +410,9 @@ table_fromwire(isccc_region_t *source, isccc_region_t *secret, result = ISC_R_SUCCESS; bad: - if (result != ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) + *alistp = alist; + else isccc_sexpr_free(&alist); return (result); diff --git a/lib/isccc/include/Makefile.in b/lib/isccc/include/Makefile.in index 9f727c30..6b222a52 100644 --- a/lib/isccc/include/Makefile.in +++ b/lib/isccc/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isccc/include/isccc/Makefile.in b/lib/isccc/include/isccc/Makefile.in index ae5bec75..c4af19a7 100644 --- a/lib/isccc/include/isccc/Makefile.in +++ b/lib/isccc/include/isccc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isccfg/api b/lib/isccfg/api index 59e4f66c..e34aa945 100644 --- a/lib/isccfg/api +++ b/lib/isccfg/api @@ -4,5 +4,5 @@ # 9.8: 80-89 # 9.9: 90-109 LIBINTERFACE = 90 -LIBREVISION = 1 +LIBREVISION = 2 LIBAGE = 0 diff --git a/lib/isccfg/include/Makefile.in b/lib/isccfg/include/Makefile.in index 1f240030..5c6976a8 100644 --- a/lib/isccfg/include/Makefile.in +++ b/lib/isccfg/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isccfg/include/isccfg/Makefile.in b/lib/isccfg/include/isccfg/Makefile.in index a6fd4125..211583a5 100644 --- a/lib/isccfg/include/isccfg/Makefile.in +++ b/lib/isccfg/include/isccfg/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001, 2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 58b5ca4c..541f078b 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -917,6 +917,7 @@ options_clauses[] = { { "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI }, { "managed-keys-directory", &cfg_type_qstring, 0 }, { "match-mapped-addresses", &cfg_type_boolean, 0 }, + { "max-rsa-exponent-size", &cfg_type_uint32, 0 }, { "memstatistics-file", &cfg_type_qstring, 0 }, { "memstatistics", &cfg_type_boolean, 0 }, { "multiple-cnames", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, @@ -1025,66 +1026,60 @@ static cfg_type_t cfg_type_masterformat = { -/* +/*% * response-policy { * zone <string> [ policy (given|disabled|passthru| - * nxdomain|nodata|cname <domain> ) ]; - * }; - * - * this is a chimera of doc_optional_keyvalue() and cfg_doc_enum() + * nxdomain|nodata|cname <domain> ) ] + * [ recursive-only yes|no ] + * [ max-policy-ttl number ] ; + * } [ recursive-only yes|no ] [ break-dnssec yes|no ] + * [ max-policy-ttl number ] ; */ + static void -doc_rpz_policies(cfg_printer_t *pctx, const cfg_type_t *type) { - const keyword_type_t *kw; +doc_rpz_policy(cfg_printer_t *pctx, const cfg_type_t *type) { const char * const *p; - - kw = type->of; - cfg_print_chars(pctx, "[ ", 2); - cfg_print_cstr(pctx, kw->name); - cfg_print_chars(pctx, " ", 1); - + /* + * This is cfg_doc_enum() without the trailing " )". + */ cfg_print_chars(pctx, "( ", 2); - for (p = kw->type->of; *p != NULL; p++) { + for (p = type->of; *p != NULL; p++) { cfg_print_cstr(pctx, *p); if (p[1] != NULL) cfg_print_chars(pctx, " | ", 3); } } -/* - * print_qstring() from parser.c - */ -static void -print_rpz_cname(cfg_printer_t *pctx, const cfg_obj_t *obj) -{ - cfg_print_chars(pctx, "\"", 1); - cfg_print_ustring(pctx, obj); - cfg_print_chars(pctx, "\"", 1); -} - static void doc_rpz_cname(cfg_printer_t *pctx, const cfg_type_t *type) { cfg_doc_terminal(pctx, type); - cfg_print_chars(pctx, " ) ]", 4); + cfg_print_chars(pctx, " )", 2); } +/* + * Parse + * given|disabled|passthru|nxdomain|nodata|cname <domain> + */ static isc_result_t -parse_rpz(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { +cfg_parse_rpz_policy(cfg_parser_t *pctx, const cfg_type_t *type, + cfg_obj_t **ret) +{ isc_result_t result; - cfg_obj_t *obj = NULL; - const cfg_tuplefielddef_t *fields = type->of; + cfg_obj_t *obj; + const cfg_tuplefielddef_t *fields; CHECK(cfg_create_tuple(pctx, type, &obj)); + + fields = type->of; CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0])); - CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1])); /* * parse cname domain only after "policy cname" */ - if (cfg_obj_isvoid(obj->value.tuple[1]) || - strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[1]))) { - CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2])); + if (strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[0])) != 0) { + CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1])); } else { - CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2])); + CHECK(cfg_parse_obj(pctx, fields[1].type, + &obj->value.tuple[1])); } *ret = obj; @@ -1095,50 +1090,160 @@ cleanup: return (result); } +/* + * Parse a tuple consisting of any kind of required field followed + * by 2 or more optional keyvalues that can be in any order. + */ +static isc_result_t +cfg_parse_kv_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { + const cfg_tuplefielddef_t *fields, *f; + cfg_obj_t *obj; + int fn; + isc_result_t result; + + obj = NULL; + CHECK(cfg_create_tuple(pctx, type, &obj)); + + /* + * The zone first field is required and always first. + */ + fields = type->of; + CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0])); + + for (;;) { + CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); + if (pctx->token.type != isc_tokentype_string) + break; + + for (fn = 1, f = &fields[1]; ; ++fn, ++f) { + if (f->name == NULL) { + cfg_parser_error(pctx, 0, "unexpected '%s'", + TOKEN_STRING(pctx)); + result = ISC_R_UNEXPECTEDTOKEN; + goto cleanup; + } + if (obj->value.tuple[fn] == NULL && + strcasecmp(f->name, TOKEN_STRING(pctx)) == 0) + break; + } + + CHECK(cfg_gettoken(pctx, 0)); + CHECK(cfg_parse_obj(pctx, f->type, &obj->value.tuple[fn])); + } + + for (fn = 1, f = &fields[1]; f->name != NULL; ++fn, ++f) { + if (obj->value.tuple[fn] == NULL) + CHECK(cfg_parse_void(pctx, NULL, + &obj->value.tuple[fn])); + } + + *ret = obj; + return (ISC_R_SUCCESS); + +cleanup: + CLEANUP_OBJ(obj); + return (result); +} + +static void +cfg_print_kv_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj) { + unsigned int i; + const cfg_tuplefielddef_t *fields, *f; + const cfg_obj_t *fieldobj; + + fields = obj->type->of; + for (f = fields, i = 0; f->name != NULL; f++, i++) { + fieldobj = obj->value.tuple[i]; + if (fieldobj->type->print == cfg_print_void) + continue; + if (i != 0) { + cfg_print_chars(pctx, " ", 1); + cfg_print_cstr(pctx, f->name); + cfg_print_chars(pctx, " ", 1); + } + cfg_print_obj(pctx, fieldobj); + } +} + +static void +cfg_doc_kv_tuple(cfg_printer_t *pctx, const cfg_type_t *type) { + const cfg_tuplefielddef_t *fields, *f; + + fields = type->of; + for (f = fields; f->name != NULL; f++) { + if (f != fields) { + cfg_print_chars(pctx, " [ ", 3); + cfg_print_cstr(pctx, f->name); + if (f->type->doc != cfg_doc_void) + cfg_print_chars(pctx, " ", 1); + } + cfg_doc_obj(pctx, f->type); + if (f != fields) + cfg_print_chars(pctx, " ]", 2); + } +} + +static keyword_type_t zone_kw = {"zone", &cfg_type_qstring}; +static cfg_type_t cfg_type_rpz_zone = { + "zone", parse_keyvalue, print_keyvalue, + doc_keyvalue, &cfg_rep_string, + &zone_kw +}; static const char *rpz_policies[] = { "given", "disabled", "passthru", "no-op", "nxdomain", "nodata", "cname", NULL }; -static cfg_type_t cfg_type_rpz_policylist = { - "policies", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, - &cfg_rep_string, &rpz_policies +static cfg_type_t cfg_type_rpz_policy_name = { + "policy name", cfg_parse_enum, cfg_print_ustring, + doc_rpz_policy, &cfg_rep_string, + &rpz_policies }; -static keyword_type_t rpz_policies_kw = { - "policy", &cfg_type_rpz_policylist +static cfg_type_t cfg_type_rpz_cname = { + "quoted_string", cfg_parse_astring, NULL, + doc_rpz_cname, &cfg_rep_string, + NULL }; -static cfg_type_t cfg_type_rpz_policy = { - "optional_policy", parse_optional_keyvalue, print_keyvalue, - doc_rpz_policies, &cfg_rep_string, &rpz_policies_kw +static cfg_tuplefielddef_t rpz_policy_fields[] = { + { "policy name", &cfg_type_rpz_policy_name, 0 }, + { "cname", &cfg_type_rpz_cname, 0 }, + { NULL, NULL, 0 } }; -static cfg_type_t cfg_type_cname = { - "domain", cfg_parse_astring, print_rpz_cname, doc_rpz_cname, - &cfg_rep_string, NULL +static cfg_type_t cfg_type_rpz_policy = { + "policy tuple", cfg_parse_rpz_policy, + cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, + rpz_policy_fields }; -static cfg_tuplefielddef_t rpzone_fields[] = { - { "name", &cfg_type_astring, 0 }, +static cfg_tuplefielddef_t rpz_zone_fields[] = { + { "zone name", &cfg_type_rpz_zone, 0 }, { "policy", &cfg_type_rpz_policy, 0 }, - { "cname", &cfg_type_cname, 0 }, + { "recursive-only", &cfg_type_boolean, 0 }, + { "max-policy-ttl", &cfg_type_uint32, 0 }, { NULL, NULL, 0 } }; -static cfg_type_t cfg_type_rpzone = { - "rpzone", parse_rpz, cfg_print_tuple, cfg_doc_tuple, - &cfg_rep_tuple, rpzone_fields +static cfg_type_t cfg_type_rpz_tuple = { + "rpz tuple", cfg_parse_kv_tuple, + cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple, + rpz_zone_fields }; -static cfg_clausedef_t rpz_clauses[] = { - { "zone", &cfg_type_rpzone, CFG_CLAUSEFLAG_MULTI }, - { NULL, NULL, 0 } +static cfg_type_t cfg_type_rpz_list = { + "zone list", cfg_parse_bracketed_list, cfg_print_bracketed_list, + cfg_doc_bracketed_list, &cfg_rep_list, + &cfg_type_rpz_tuple }; -static cfg_clausedef_t *rpz_clausesets[] = { - rpz_clauses, - NULL +static cfg_tuplefielddef_t rpz_fields[] = { + { "zone list", &cfg_type_rpz_list, 0 }, + { "recursive-only", &cfg_type_boolean, 0 }, + { "break-dnssec", &cfg_type_boolean, 0 }, + { "max-policy-ttl", &cfg_type_uint32, 0 }, + { NULL, NULL, 0 } }; static cfg_type_t cfg_type_rpz = { - "rpz", cfg_parse_map, cfg_print_map, cfg_doc_map, - &cfg_rep_map, rpz_clausesets + "rpz", cfg_parse_kv_tuple, + cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple, + rpz_fields }; - /*% * dnssec-lookaside */ diff --git a/lib/lwres/Makefile.in b/lib/lwres/Makefile.in index 858b325d..0cf873b5 100644 --- a/lib/lwres/Makefile.in +++ b/lib/lwres/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/lwres/api b/lib/lwres/api index a45a6bff..59e4f66c 100644 --- a/lib/lwres/api +++ b/lib/lwres/api @@ -4,5 +4,5 @@ # 9.8: 80-89 # 9.9: 90-109 LIBINTERFACE = 90 -LIBREVISION = 0 +LIBREVISION = 1 LIBAGE = 0 diff --git a/lib/lwres/getaddrinfo.c b/lib/lwres/getaddrinfo.c index 8e916f34..811a2fee 100644 --- a/lib/lwres/getaddrinfo.c +++ b/lib/lwres/getaddrinfo.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * This code is derived from software contributed to ISC by @@ -398,7 +398,7 @@ lwres_getaddrinfo(const char *hostname, const char *servname, goto inet6_addr; } addrsize = sizeof(struct in_addr); - addroff = (char *)(&SIN(0)->sin_addr) - (char *)0; + addroff = offsetof(struct sockaddr_in, sin_addr); family = AF_INET; goto common; #ifdef LWRES_HAVE_SIN6_SCOPE_ID @@ -408,7 +408,7 @@ lwres_getaddrinfo(const char *hostname, const char *servname, if (family && family != AF_INET6) return (EAI_NONAME); addrsize = sizeof(struct in6_addr); - addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0; + addroff = offsetof(struct sockaddr_in6, sin6_addr); family = AF_INET6; goto common; #endif @@ -417,7 +417,7 @@ lwres_getaddrinfo(const char *hostname, const char *servname, return (EAI_NONAME); inet6_addr: addrsize = sizeof(struct in6_addr); - addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0; + addroff = offsetof(struct sockaddr_in6, sin6_addr); family = AF_INET6; common: diff --git a/lib/lwres/include/Makefile.in b/lib/lwres/include/Makefile.in index 4750a5e9..6c3d07fd 100644 --- a/lib/lwres/include/Makefile.in +++ b/lib/lwres/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/lwres/include/lwres/Makefile.in b/lib/lwres/include/lwres/Makefile.in index fc3126f8..36b8b03d 100644 --- a/lib/lwres/include/lwres/Makefile.in +++ b/lib/lwres/include/lwres/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/lwres/man/Makefile.in b/lib/lwres/man/Makefile.in index cb723c27..80db9f2f 100644 --- a/lib/lwres/man/Makefile.in +++ b/lib/lwres/man/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/lwres/unix/Makefile.in b/lib/lwres/unix/Makefile.in index 5d77208a..26ca4fb8 100644 --- a/lib/lwres/unix/Makefile.in +++ b/lib/lwres/unix/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/lwres/unix/include/Makefile.in b/lib/lwres/unix/include/Makefile.in index 61906330..5372543c 100644 --- a/lib/lwres/unix/include/Makefile.in +++ b/lib/lwres/unix/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/lwres/unix/include/lwres/Makefile.in b/lib/lwres/unix/include/lwres/Makefile.in index c943e015..4f60ce82 100644 --- a/lib/lwres/unix/include/lwres/Makefile.in +++ b/lib/lwres/unix/include/lwres/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/lwres/win32/Makefile.in b/lib/lwres/win32/Makefile.in index 5d77208a..26ca4fb8 100644 --- a/lib/lwres/win32/Makefile.in +++ b/lib/lwres/win32/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/lwres/win32/include/Makefile.in b/lib/lwres/win32/include/Makefile.in index 61906330..5372543c 100644 --- a/lib/lwres/win32/include/Makefile.in +++ b/lib/lwres/win32/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/lwres/win32/include/lwres/Makefile.in b/lib/lwres/win32/include/lwres/Makefile.in index c943e015..4f60ce82 100644 --- a/lib/lwres/win32/include/lwres/Makefile.in +++ b/lib/lwres/win32/include/lwres/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/tests/Makefile.in b/lib/tests/Makefile.in index 105d567d..02802656 100644 --- a/lib/tests/Makefile.in +++ b/lib/tests/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001, 2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/tests/include/Makefile.in b/lib/tests/include/Makefile.in index 10eedede..b529c75d 100644 --- a/lib/tests/include/Makefile.in +++ b/lib/tests/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/tests/include/tests/Makefile.in b/lib/tests/include/tests/Makefile.in index 5d6ad0f6..cfadac78 100644 --- a/lib/tests/include/tests/Makefile.in +++ b/lib/tests/include/tests/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any |