]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
A unified way to verify the zone fetch
authorMatthijs Mekking <matthijs@isc.org>
Fri, 31 Oct 2025 08:04:13 +0000 (09:04 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Thu, 6 Nov 2025 09:54:55 +0000 (10:54 +0100)
There is a lot of similarity when checking the completed fetch is legit.
Create a new function to verify the fetch and to reduce code
duplication.

lib/dns/include/dns/zonefetch.h
lib/dns/zone.c
lib/dns/zonefetch.c

index 41dcb52b1076160f32e97bcebc9d5a5910586572..01f189b81d114a909b5a62c20bb4cf6705d72c31 100644 (file)
@@ -105,3 +105,21 @@ dns_zonefetch_done(void *arg);
  *     Complete a zone fetch. This may trigger follow-up actions that depend on
  *     the fetch type.
  */
+
+isc_result_t
+dns_zonefetch_verify(dns_zonefetch_t *fetch, isc_result_t eresult,
+                    dns_trust_t trust);
+/*%<
+ *      Check a completed zone fetch. This checks the response result,
+ *     if there are records and signatures available, and the  level of trust.
+ *
+ *     Requires:
+ *             'fetch' is not NULL.
+ *
+ *     Returns:
+ *             ISC_R_SUCCESS    - if the completed zone fetch is verified.
+ *             ISC_R_NOTFOUND   - if no records are found.
+ *             DNS_R_NOVALIDSIG - if no signatures are available, or the trust
+ *                                level is below 'trust'.
+ *             eresult          - error code in case the fetch failed.
+ */
index 4b8b893e8d441afbe9f5ff991d2889d262629eb4..cf7b2bed6842d1a6d1a5dc0908e944b5bd6127c1 100644 (file)
@@ -10758,20 +10758,8 @@ keyfetch_done(dns_zonefetch_t *fetch, isc_result_t eresult) {
                   "Returned from key fetch in keyfetch_done() for '%s': %s",
                   namebuf, isc_result_totext(eresult));
 
-       /* Fetch failed */
-       if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(dnskeys)) {
-               dnssec_log(zone, ISC_LOG_WARNING,
-                          "Unable to fetch DNSKEY set '%s': %s", namebuf,
-                          isc_result_totext(eresult));
-               CHECK(minimal_update(fetch, ver, &diff));
-               goto done;
-       }
-
-       /* No RRSIGs found */
-       if (!dns_rdataset_isassociated(dnskeysigs)) {
-               dnssec_log(zone, ISC_LOG_WARNING,
-                          "No DNSKEY RRSIGs found for '%s': %s", namebuf,
-                          isc_result_totext(eresult));
+       result = dns_zonefetch_verify(fetch, eresult, dns_trust_none);
+       if (result != ISC_R_SUCCESS) {
                CHECK(minimal_update(fetch, ver, &diff));
                goto done;
        }
@@ -21171,7 +21159,6 @@ nsfetch_done(dns_zonefetch_t *fetch, isc_result_t eresult) {
        dns_name_t *pname = NULL;
        char pnamebuf[DNS_NAME_FORMATSIZE];
        dns_rdataset_t *nsrrset = NULL;
-       dns_rdataset_t *nssigset = NULL;
 
        REQUIRE(fetch != NULL);
        REQUIRE(fetch->fetchtype == ZONEFETCHTYPE_NS);
@@ -21192,37 +21179,10 @@ nsfetch_done(dns_zonefetch_t *fetch, isc_result_t eresult) {
                dnssec_log(zone, ISC_LOG_DEBUG(3),
                           "NODATA response for NS '%s', level up", pnamebuf);
                return DNS_R_CONTINUE;
-
-       } else if (eresult != ISC_R_SUCCESS) {
-               dnssec_log(zone, ISC_LOG_WARNING,
-                          "Unable to fetch NS set '%s': %s", pnamebuf,
-                          isc_result_totext(eresult));
-               result = eresult;
-               goto done;
        }
 
-       /* No NS records found */
-       if (!dns_rdataset_isassociated(nsrrset)) {
-               dnssec_log(zone, ISC_LOG_WARNING,
-                          "No NS records found for '%s'", pnamebuf);
-               result = ISC_R_NOTFOUND;
-               goto done;
-       }
-
-       /* No RRSIGs found */
-       if (!dns_rdataset_isassociated(nssigset)) {
-               dnssec_log(zone, ISC_LOG_WARNING, "No NS RRSIGs found for '%s'",
-                          pnamebuf);
-               result = DNS_R_NOVALIDSIG;
-               goto done;
-       }
-
-       /* Check trust level */
-       if (nsrrset->trust < dns_trust_secure) {
-               dnssec_log(zone, ISC_LOG_WARNING,
-                          "Invalid NS RRset for '%s' trust level %u", pnamebuf,
-                          nsrrset->trust);
-               result = DNS_R_NOVALIDSIG;
+       result = dns_zonefetch_verify(fetch, eresult, dns_trust_secure);
+       if (result != ISC_R_SUCCESS) {
                goto done;
        }
 
index 988f4a6bfada348df0ef2022efc6dd855fe9606e..ea3fa3099ce9a41c799f069367660cbf59bdbea2 100644 (file)
@@ -187,3 +187,53 @@ cleanup:
                }
        }
 }
+
+isc_result_t
+dns_zonefetch_verify(dns_zonefetch_t *fetch, isc_result_t eresult,
+                    dns_trust_t trust) {
+       char namebuf[DNS_NAME_FORMATSIZE];
+       char typebuf[DNS_RDATATYPE_FORMATSIZE];
+       dns_rdataset_t *rrset = NULL;
+       dns_rdataset_t *sigset = NULL;
+
+       REQUIRE(fetch != NULL);
+
+       rrset = &fetch->rrset;
+       sigset = &fetch->sigset;
+       dns_name_format(fetch->qname, namebuf, sizeof(namebuf));
+       dns_rdatatype_format(fetch->qtype, typebuf, sizeof(typebuf));
+
+       if (eresult != ISC_R_SUCCESS) {
+               dns_zone_logc(fetch->zone, DNS_LOGCATEGORY_DNSSEC,
+                             ISC_LOG_WARNING, "Unable to fetch %s/%s: %s",
+                             namebuf, typebuf, isc_result_totext(eresult));
+               return eresult;
+       }
+
+       /* No records found */
+       if (!dns_rdataset_isassociated(rrset)) {
+               dns_zone_logc(fetch->zone, DNS_LOGCATEGORY_DNSSEC,
+                             ISC_LOG_WARNING, "No %s records found for '%s'",
+                             typebuf, namebuf);
+               return ISC_R_NOTFOUND;
+       }
+
+       /* No RRSIGs found */
+       if (!dns_rdataset_isassociated(sigset)) {
+               dns_zone_logc(fetch->zone, DNS_LOGCATEGORY_DNSSEC,
+                             ISC_LOG_WARNING, "No %s RRSIGs found for '%s'",
+                             typebuf, namebuf);
+               return DNS_R_NOVALIDSIG;
+       }
+
+       /* Check trust level */
+       if (rrset->trust < trust) {
+               dns_zone_logc(fetch->zone, DNS_LOGCATEGORY_DNSSEC,
+                             ISC_LOG_WARNING,
+                             "Invalid %s RRset for '%s' trust level %u",
+                             typebuf, namebuf, rrset->trust);
+               return DNS_R_NOVALIDSIG;
+       }
+
+       return ISC_R_SUCCESS;
+}