]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
rrcache, pktcache: check security only if under a TA
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 7 Apr 2017 10:42:01 +0000 (12:42 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 7 Apr 2017 10:42:01 +0000 (12:42 +0200)
Tests: iter_minmaxttl and iter_soamin get fixed, probably because
they're without a root TA but have some lower TA(s).

lib/layer/pktcache.c
lib/layer/rrcache.c

index 6725fa48b60cf49fb140ac1efc09e7ec3483a2a7..0756e2091ce9c6c726db2a93c17da25a99069298 100644 (file)
@@ -29,6 +29,7 @@
 #include <contrib/ucw/lib.h>
 #include "lib/layer/iterate.h"
 #include "lib/cache.h"
+#include "lib/dnssec/ta.h"
 #include "lib/module.h"
 #include "lib/resolve.h"
 
@@ -55,7 +56,7 @@ static void adjust_ttl(knot_rrset_t *rr, uint32_t drift)
 }
 
 /** @internal Try to find a shortcut directly to searched packet. */
-static int loot_pktcache(struct kr_cache *cache, knot_pkt_t *pkt,
+static int loot_pktcache(struct kr_context *ctx, knot_pkt_t *pkt,
                         struct kr_request *req, uint8_t *flags)
 {
        struct kr_query *qry = req->current_query;
@@ -64,16 +65,20 @@ static int loot_pktcache(struct kr_cache *cache, knot_pkt_t *pkt,
        uint16_t rrtype = qry->stype;
 
        struct kr_cache_entry *entry = NULL;
-       int ret = kr_cache_peek(cache, KR_CACHE_PKT, qname,
+       int ret = kr_cache_peek(&ctx->cache, KR_CACHE_PKT, qname,
                                rrtype, &entry, &timestamp);
        if (ret != 0) { /* Not in the cache */
                return ret;
        }
 
        uint8_t lowest_rank = KR_RANK_INITIAL | KR_RANK_AUTH;
+
+       /* Records not present under any TA don't have their security verified at all. */
+       const bool ta_covers = kr_ta_covers_qry(ctx, qry->sname, qry->stype);
+       /* ^ TODO: performance? */
+
        /* There's probably little sense for NONAUTH in pktcache. */
-       if (!knot_wire_get_cd(req->answer->wire)) {
-               // FIXME: only if we can cover the name by a TA
+       if (!knot_wire_get_cd(req->answer->wire) && ta_covers) {
                kr_rank_set(&lowest_rank, KR_RANK_INSECURE);
        }
        if (entry->rank < lowest_rank) {
@@ -142,8 +147,7 @@ static int pktcache_peek(kr_layer_t *ctx, knot_pkt_t *pkt)
 
        /* Fetch either answer to original or minimized query */
        uint8_t flags = 0;
-       struct kr_cache *cache = &req->ctx->cache;
-       int ret = loot_pktcache(cache, pkt, req, &flags);
+       int ret = loot_pktcache(req->ctx, pkt, req, &flags);
        if (ret == 0) {
                VERBOSE_MSG(qry, "=> satisfied from cache\n");
                qry->flags |= QUERY_CACHED|QUERY_NO_MINIMIZE;
index 61ba47e57e597bc11dcec2b21e988d0374a45fe1..ebc11ac3d6c92db6eb30a3d33f6d1cae88856d37 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "lib/layer/iterate.h"
 #include "lib/cache.h"
+#include "lib/dnssec/ta.h"
 #include "lib/module.h"
 #include "lib/utils.h"
 #include "lib/resolve.h"
@@ -138,14 +139,19 @@ enomem:
 }
 
 /** @internal Try to find a shortcut directly to searched record. */
-static int loot_rrcache(struct kr_cache *cache, knot_pkt_t *pkt,
+static int loot_rrcache(struct kr_context *ctx, knot_pkt_t *pkt,
                        struct kr_query *qry, uint16_t rrtype, const bool cdbit)
 {
+       /* Records not present under any TA don't have their security verified at all. */
+       const bool ta_covers = kr_ta_covers_qry(ctx, qry->sname, qry->stype);
+       /* ^ TODO: performance? */
+
        /* Lookup direct match first; only consider authoritative records.
         * TODO: move rank handling into the iterator (QUERY_DNSSEC_* flags)? */
        uint8_t rank  = 0;
        uint8_t flags = 0;
-       uint8_t lowest_rank = KR_RANK_INSECURE | KR_RANK_AUTH;
+       uint8_t lowest_rank = (ta_covers ? KR_RANK_INSECURE : KR_RANK_INITIAL)
+               | KR_RANK_AUTH;
        if (qry->flags & QUERY_NONAUTH) {
                lowest_rank = KR_RANK_INITIAL;
                /* Note: there's little sense in validation status for non-auth records.
@@ -157,6 +163,7 @@ static int loot_rrcache(struct kr_cache *cache, knot_pkt_t *pkt,
                kr_rank_set(&lowest_rank, KR_RANK_INITIAL);
        }
 
+       struct kr_cache *cache = &ctx->cache;
        int ret = loot_rr(cache, pkt, qry->sname, qry->sclass, rrtype, qry,
                          &rank, &flags, 0, lowest_rank);
        if (ret != 0 && rrtype != KNOT_RRTYPE_CNAME) {
@@ -199,16 +206,15 @@ static int rrcache_peek(kr_layer_t *ctx, knot_pkt_t *pkt)
         * it may either be a CNAME chain or direct answer.
         * Only one step of the chain is resolved at a time.
         */
-       struct kr_cache *cache = &req->ctx->cache;
        int ret = -1;
        if (qry->stype != KNOT_RRTYPE_ANY) {
-               ret = loot_rrcache(cache, pkt, qry, qry->stype, cd_is_set);
+               ret = loot_rrcache(req->ctx, pkt, qry, qry->stype, cd_is_set);
        } else {
                /* ANY query are used by either qmail or certain versions of Firefox.
                 * Probe cache for a few interesting records. */
                static uint16_t any_types[] = { KNOT_RRTYPE_A, KNOT_RRTYPE_AAAA, KNOT_RRTYPE_MX };
                for (size_t i = 0; i < sizeof(any_types)/sizeof(any_types[0]); ++i) {
-                       if (loot_rrcache(cache, pkt, qry, any_types[i], cd_is_set) == 0) {
+                       if (loot_rrcache(req->ctx, pkt, qry, any_types[i], cd_is_set) == 0) {
                                ret = 0; /* At least single record matches */
                        }
                }