From: Michał Kępień Date: Thu, 28 Jun 2018 11:38:39 +0000 (+0200) Subject: Add dns_zone_verifydb() X-Git-Tag: v9.13.2~7^2~19 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eaf1c0f6ebce22f748b0efa3dd25bc81821cab29;p=thirdparty%2Fbind9.git Add dns_zone_verifydb() Add a function for determining whether the supplied version of a mirror zone passes DNSSEC validation and is signed using a trusted key. Define a new libdns result signifying a zone verification failure. --- diff --git a/lib/dns/include/dns/result.h b/lib/dns/include/dns/result.h index 92fa5e12909..2063cb790e3 100644 --- a/lib/dns/include/dns/result.h +++ b/lib/dns/include/dns/result.h @@ -153,8 +153,9 @@ #define DNS_R_BADTSIG (ISC_RESULTCLASS_DNS + 115) #define DNS_R_BADSIG0 (ISC_RESULTCLASS_DNS + 116) #define DNS_R_TOOMANYRECORDS (ISC_RESULTCLASS_DNS + 117) +#define DNS_R_VERIFYFAILURE (ISC_RESULTCLASS_DNS + 118) -#define DNS_R_NRESULTS 118 /*%< Number of results */ +#define DNS_R_NRESULTS 119 /*%< Number of results */ /* * DNS wire format rcodes. diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 553776f5709..c724951d9e3 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -2486,4 +2486,24 @@ dns_zone_ismirror(const dns_zone_t *zone); * Return ISC_TRUE if 'zone' is a mirror zone, return ISC_FALSE otherwise. */ +isc_result_t +dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver); +/*%< + * If 'zone' is a mirror zone, perform DNSSEC validation of version 'ver' of + * its database, 'db'. Ensure that the DNSKEY RRset at zone apex is signed by + * at least one trust anchor specified for the view that 'zone' is assigned to. + * If 'ver' is NULL, use the current version of 'db'. + * + * If 'zone' is not a mirror zone, return ISC_R_SUCCESS immediately. + * + * Returns: + * + * \li #ISC_R_SUCCESS either 'zone' is not a mirror zone or 'zone' is + * a mirror zone and all DNSSEC checks succeeded + * and the DNSKEY RRset at zone apex is signed by + * a trusted key + * + * \li #DNS_R_VERIFYFAILURE any other case + */ + #endif /* DNS_ZONE_H */ diff --git a/lib/dns/result.c b/lib/dns/result.c index e7507c53ff1..0d992920614 100644 --- a/lib/dns/result.c +++ b/lib/dns/result.c @@ -165,6 +165,7 @@ static const char *text[DNS_R_NRESULTS] = { "TSIG in wrong location", /*%< 115 DNS_R_BADTSIG */ "SIG(0) in wrong location", /*%< 116 DNS_R_BADSIG0 */ "too many records", /*%< 117 DNS_R_TOOMANYRECORDS */ + "verify failure", /*%< 118 DNS_R_VERIFYFAILURE */ }; static const char *ids[DNS_R_NRESULTS] = { diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index 796dccb9e29..11f5c09b6ce 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -1307,6 +1307,7 @@ dns_zone_setzeronosoattl dns_zone_signwithkey dns_zone_synckeyzone dns_zone_unload +dns_zone_verifydb dns_zonekey_iszonekey dns_zonemgr_attach dns_zonemgr_create diff --git a/lib/dns/zone.c b/lib/dns/zone.c index d0460a9b565..2f4f15464e1 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include @@ -19330,3 +19331,56 @@ dns_zone_ismirror(const dns_zone_t *zone) { return (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MIRROR)); } + +isc_result_t +dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) { + dns_dbversion_t *version = NULL; + dns_keytable_t *secroots = NULL; + isc_result_t result; + dns_name_t *origin; + + const char me[] = "dns_zone_verifydb"; + ENTER; + + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(db != NULL); + + if (!dns_zone_ismirror(zone)) { + return (ISC_R_SUCCESS); + } + + if (ver == NULL) { + dns_db_currentversion(db, &version); + } else { + version = ver; + } + + if (zone->view != NULL) { + result = dns_view_getsecroots(zone->view, &secroots); + if (result != ISC_R_SUCCESS) { + goto done; + } + } + + origin = dns_db_origin(db); + result = dns_zoneverify_dnssec(zone, db, version, origin, secroots, + zone->mctx, ISC_FALSE, ISC_FALSE); + + done: + if (secroots != NULL) { + dns_keytable_detach(&secroots); + } + + if (ver == NULL) { + dns_db_closeversion(db, &version, ISC_FALSE); + } + + if (result != ISC_R_SUCCESS) { + dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, + "zone verification failed: %s", + isc_result_totext(result)); + result = DNS_R_VERIFYFAILURE; + } + + return (result); +}