]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
zonemd, unit test for dnssec verify, implement test.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 15 Oct 2020 10:27:22 +0000 (12:27 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 15 Oct 2020 10:27:22 +0000 (12:27 +0200)
services/authzone.c
services/authzone.h
testcode/unitmain.c

index 7c75441d5a33d57944954317e27b9ac365825803..7ba86c23cec8d01cb5adf54db9814545db6dd78e 100644 (file)
@@ -7702,16 +7702,22 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
  * @param z: auth zone that fails.
  * @param env: environment with config, to ignore failure or not.
  * @param reason: failure string description.
+ * @param result: strdup result in here if not NULL.
  */
 static void auth_zone_zonemd_fail(struct auth_zone* z, struct module_env* env,
-       char* reason)
+       char* reason, char** result)
 {
        char zstr[255+1];
        /* if fail: log reason, and depending on config also take action
         * and drop the zone, eg. it is gone from memory, set zone_expired */
        dname_str(z->name, zstr);
        if(!reason) reason = "verification failed";
-       log_warn("auth zone %s: ZONEMD verification failed: %s", zstr, reason);
+       if(result) {
+               *result = strdup(reason);
+               if(!*result) log_err("out of memory");
+       } else {
+               log_warn("auth zone %s: ZONEMD verification failed: %s", zstr, reason);
+       }
 
        /* expired means the zone gives servfail and is not used by
         * lookup if fallback_enabled*/
@@ -7727,10 +7733,11 @@ static void auth_zone_zonemd_fail(struct auth_zone* z, struct module_env* env,
  * @param is_insecure: if true, the dnskey is not used, the zone is insecure.
  *     And dnssec is not used.  It is DNSSEC secure insecure or not under
  *     a trust anchor.
+ * @param result: if not NULL result reason copied here.
  */
 static void
 auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
-       struct ub_packed_rrset_key* dnskey, int is_insecure)
+       struct ub_packed_rrset_key* dnskey, int is_insecure, char** result)
 {
        char* reason = NULL;
        struct auth_data* apex = NULL;
@@ -7760,28 +7767,32 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
                /* fetch, DNSSEC verify, and check NSEC/NSEC3 */
                if(!zonemd_check_dnssec_absence(z, env, dnskey, apex,
                        &reason)) {
-                       auth_zone_zonemd_fail(z, env, reason);
+                       auth_zone_zonemd_fail(z, env, reason, result);
                        return;
                }
        } else if(zonemd_rrset && dnskey) {
                /* check DNSSEC verify of SOA and ZONEMD */
                if(!zonemd_check_dnssec_soazonemd(z, env, dnskey, apex,
                        zonemd_rrset, &reason)) {
-                       auth_zone_zonemd_fail(z, env, reason);
+                       auth_zone_zonemd_fail(z, env, reason, result);
                        return;
                }
        }
 
        /* check ZONEMD checksum and report or else fail. */
        if(!auth_zone_zonemd_check_hash(z, env, &reason)) {
-               auth_zone_zonemd_fail(z, env, reason);
+               auth_zone_zonemd_fail(z, env, reason, result);
                return;
        }
 
        if(zonemd_absent)
-               auth_zone_zonemd_fail(z, env, "ZONEMD absent and that is not allowed by config");
+               auth_zone_zonemd_fail(z, env, "ZONEMD absent and that is not allowed by config", result);
        /* success! log the success */
        auth_zone_log(z->name, VERB_ALGO, "ZONEMD verification successful");
+       if(result) {
+               *result = strdup("ZONEMD verification successful");
+               if(!*result) log_err("out of memory");
+       }
 }
 
 /**
@@ -7925,12 +7936,12 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
        }
 
        if(reason) {
-               auth_zone_zonemd_fail(z, env, reason);
+               auth_zone_zonemd_fail(z, env, reason, NULL);
                lock_rw_unlock(&z->lock);
                return;
        }
 
-       auth_zone_verify_zonemd_with_key(z, env, dnskey, is_insecure);
+       auth_zone_verify_zonemd_with_key(z, env, dnskey, is_insecure, NULL);
        regional_free_all(env->scratch);
        lock_rw_unlock(&z->lock);
 }
@@ -7993,7 +8004,8 @@ zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env)
        return 1;
 }
 
-void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env)
+void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
+       char** result)
 {
        char* reason = NULL;
        struct trust_anchor* anchor = NULL;
@@ -8033,10 +8045,10 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env)
        }
 
        if(reason) {
-               auth_zone_zonemd_fail(z, env, reason);
+               auth_zone_zonemd_fail(z, env, reason, result);
                return;
        }
 
-       auth_zone_verify_zonemd_with_key(z, env, dnskey, is_insecure);
+       auth_zone_verify_zonemd_with_key(z, env, dnskey, is_insecure, result);
        regional_free_all(env->scratch);
 }
index 69ec7ed9930285b2c0233dbbef934bb1b46d8aa2..c00598ad119e644aca1923b025b248351886046a 100644 (file)
@@ -743,8 +743,10 @@ int auth_zone_generate_zonemd_check(struct auth_zone* z, int scheme,
  * This includes DNSSEC verification if applicable.
  * @param z: auth zone to check.  Caller holds lock. wrlock.
  * @param env: with temp region, buffer and config.
+ * @param result: if not NULL, result string strdupped in here.
  */
-void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env);
+void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
+       char** result);
 
 /** mesh callback for zonemd on lookup of dnskey */
 void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode,
index b5aa8fe4292550947a013889673bd8f50d37c862..519653064cdb375840ff312b695c7000dffa1fbf 100644 (file)
@@ -1033,6 +1033,8 @@ static void zonemd_verify_test(void)
        char* zname = "example.org";
        char* zfile = "testdata/zonemd.example1.zone";
        char* date_override = "20180302005009";
+       char* result = NULL;
+       char* result_wanted = "have trust anchor, but zone has no DNSKEY";
        struct auth_zone* z;
        unit_show_func("services/authzone.c", "auth_zone_verify_zonemd");
 
@@ -1073,8 +1075,26 @@ static void zonemd_verify_test(void)
 
        /* test */
        lock_rw_wrlock(&z->lock);
-       auth_zone_verify_zonemd(z, &env);
+       auth_zone_verify_zonemd(z, &env, &result);
        lock_rw_unlock(&z->lock);
+       if(1) {
+               printf("auth zone %s: ZONEMD verification %s: %s\n", zname,
+                       (strcmp(result, "ZONEMD verification successful")==0?"successful":"failed"),
+                       result);
+       }
+       if(!result)
+               fatal_exit("out of memory");
+       unit_assert(strcmp(result, result_wanted) == 0);
+       free(result);
+       if(strcmp(result, "ZONEMD verification successful") == 0) {
+               lock_rw_rdlock(&z->lock);
+               unit_assert(!z->zone_expired);
+               lock_rw_unlock(&z->lock);
+       } else {
+               lock_rw_rdlock(&z->lock);
+               unit_assert(z->zone_expired);
+               lock_rw_unlock(&z->lock);
+       }
 
        /* desetup test harness */
        mesh_delete(env.mesh);