]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
layer/validate: additional check when validating CNAME chain
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Mon, 16 Jan 2017 15:22:06 +0000 (16:22 +0100)
committerGrigorii Demidov <grigorii.demidov@nic.cz>
Mon, 16 Jan 2017 15:26:11 +0000 (16:26 +0100)
daemon/lua/kres-gen.lua
lib/layer/validate.c
lib/utils.c
lib/utils.h

index d341c37e41ada977db596ad682f2b916a5e06d0e..a77bcf40057c1c39643762574917f64b8268ef8c 100644 (file)
@@ -65,6 +65,7 @@ typedef struct {
 struct ranked_rr_array_entry {
     uint32_t qry_uid;
     uint8_t rank;
+    uint8_t revalidation_cnt;
     _Bool cached;
     _Bool yielded;
     _Bool to_wire;
index cfe352b3e6fa2d2a9a1b266e5ee1056a1fa9a6f3..29a4c03959be068f376fca31097de492a3a09785 100644 (file)
@@ -37,6 +37,8 @@
 
 #define VERBOSE_MSG(qry, fmt...) QRVERBOSE(qry, "vldr", fmt)
 
+#define MAX_REVALIDATION_CNT 2
+
 /**
  * Search in section for given type.
  * @param sec  Packet section.
@@ -267,7 +269,8 @@ static void mark_insecure_parents(const struct kr_query *qry)
        while (parent && ((parent->flags & cut_flags) == 0)) {
                parent->flags &= ~QUERY_DNSSEC_WANT;
                parent->flags |= QUERY_DNSSEC_INSECURE;
-               if (parent->stype != KNOT_RRTYPE_DS) {
+               if (parent->stype != KNOT_RRTYPE_DS &&
+                   parent->stype != KNOT_RRTYPE_RRSIG) {
                        break;
                }
                parent = parent->parent;
@@ -406,13 +409,6 @@ static int rrsig_not_found(kr_layer_t *ctx, const knot_rrset_t *rr)
        struct kr_request *req = ctx->req;
        struct kr_query *qry = req->current_query;
 
-       if (knot_dname_is_equal(rr->owner, qry->zone_cut.name) ||
-                               ctx->state == KR_STATE_YIELD) {
-               /* Already yielded for revalidation. */
-               VERBOSE_MSG(qry, "<= couldn't validate RRSIGs\n");
-               qry->flags |= QUERY_DNSSEC_BOGUS;
-               return KR_STATE_FAIL;
-       }
        VERBOSE_MSG(qry, ">< no RRSIGs found\n");
        struct kr_zonecut *cut = &qry->zone_cut;
        const knot_dname_t *cut_name_start = qry->zone_cut.name;
@@ -455,7 +451,7 @@ static int check_validation_result(kr_layer_t *ctx, ranked_rr_array_t *arr)
        int ret = KR_STATE_DONE;
        struct kr_request *req = ctx->req;
        struct kr_query *qry = req->current_query;
-       const ranked_rr_array_entry_t *invalid_entry = NULL;
+       ranked_rr_array_entry_t *invalid_entry = NULL;
        for (size_t i = 0; i < arr->len; ++i) {
                ranked_rr_array_entry_t *entry = arr->at[i];
                if (entry->yielded) {
@@ -477,6 +473,13 @@ static int check_validation_result(kr_layer_t *ctx, ranked_rr_array_t *arr)
                return ret;
        }
 
+       if ((invalid_entry->rank != KR_VLDRANK_SECURE) &&
+           (++(invalid_entry->revalidation_cnt) > MAX_REVALIDATION_CNT)) {
+               VERBOSE_MSG(qry, "<= continuous revalidation, fails\n");
+               qry->flags |= QUERY_DNSSEC_BOGUS;
+               return KR_STATE_FAIL;
+       }
+
        const knot_rrset_t *rr = invalid_entry->rr;
        if (invalid_entry->rank == KR_VLDRANK_MISMATCH) {
                const knot_dname_t *signer_name = knot_rrsig_signer_name(&rr->rrs, 0);
@@ -657,7 +660,10 @@ static int validate(kr_layer_t *ctx, knot_pkt_t *pkt)
                                        VERBOSE_MSG(qry, "<= can't prove NODATA due to optout, going insecure\n");
                                        qry->flags &= ~QUERY_DNSSEC_WANT;
                                        qry->flags |= QUERY_DNSSEC_INSECURE;
-                                       /* Could not return here, we must to update parent query */
+                                       /* Could not return from here,
+                                        * we must continue and
+                                        * call update_parent_keys() to mark
+                                        * parent queries as insecured */
                                } else {
                                        VERBOSE_MSG(qry, "<= bad NODATA proof\n");
                                        qry->flags |= QUERY_DNSSEC_BOGUS;
index 2588ba159510bc71d83892ba2503bb98b321c3f4..4c196a067976dbe45719046ead21b6b17599309f 100644 (file)
@@ -457,6 +457,7 @@ int kr_ranked_rrarray_add(ranked_rr_array_t *array, const knot_rrset_t *rr,
        entry->qry_uid = qry_uid;
        entry->rr = copy;
        entry->rank = rank;
+       entry->revalidation_cnt = 0;
        entry->cached = false;
        entry->yielded = false;
        entry->to_wire = to_wire;
index bdefbf7a240b3bb24d2ecb34a674fb458b7448e4..a552e85f21562ebeade5428e398ad2864b1b4a3e 100644 (file)
@@ -94,6 +94,7 @@ typedef array_t(knot_rrset_t *) rr_array_t;
 struct ranked_rr_array_entry {
        uint32_t qry_uid;
        uint8_t rank;
+       uint8_t revalidation_cnt;
        bool cached;
        bool yielded;
        bool to_wire;