]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
revoke point handling
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 25 Aug 2009 10:02:17 +0000 (10:02 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 25 Aug 2009 10:02:17 +0000 (10:02 +0000)
git-svn-id: file:///svn/unbound/trunk@1777 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/daemon.c
doc/Changelog
validator/autotrust.c
validator/autotrust.h
validator/val_anchor.c
validator/val_anchor.h

index 4ebebe07e0240844905ff607acf515bd6d74541c..16be3534e020267f3f38887bac6d03c82ff34614 100644 (file)
@@ -176,7 +176,7 @@ daemon_init()
 #endif
        OpenSSL_add_all_algorithms();
        /* grab the COMP method ptr because openssl leaks it */
-       comp_meth = SSL_COMP_get_compression_methods();
+       comp_meth = (void*)SSL_COMP_get_compression_methods();
        (void)SSL_library_init();
 #ifdef HAVE_TZSET
        /* init timezone info while we are not chrooted yet */
index 4817fb4f730df410e1217fde37acb5161a520086..612f53c3105e98f63ec8a5ce84750626cf91432e 100644 (file)
@@ -2,6 +2,7 @@
        - fixup memleak in trust anchor unsupported algorithm check.
        - iana portlist updated.
        - autotrust options: add-holddown, del-holddown, keep-missing.
+       - autotrust store revoked status of trust points.
 
 24 August 2009: Wouter
        - cleaner memory allocation on exit. autotrust test routines.
index 7efbe49be2577fbee5e8c3e38e84ea96d63a571d..61cea54c4174132eba03e110630a936bc7ea2811 100644 (file)
@@ -50,6 +50,7 @@
 #include "util/module.h"
 #include "util/net_help.h"
 #include "util/config_file.h"
+#include "util/regional.h"
 
 /** number of times a key must be seen before it can become valid */
 #define MIN_PENDINGCOUNT 2
@@ -599,6 +600,7 @@ parse_id(struct val_anchors* anchors, char* line)
  * @param anchor: the anchor as result value or previously returned anchor
  *     value to read the variable lines into.
  * @return: 0 no match, -1 failed syntax error, +1 success line read.
+ *     +2 revoked trust anchor file.
  */
 static int
 parse_var_line(char* line, struct val_anchors* anchors, 
@@ -610,6 +612,12 @@ parse_var_line(char* line, struct val_anchors* anchors,
                *anchor = parse_id(anchors, line+6);
                if(!*anchor) return -1;
                else return 1;
+       } else if(strncmp(line, ";;REVOKED", 9) == 0) {
+               if(tp) {
+                       log_err("REVOKED statement must be at start of file");
+                       return -1;
+               }
+               return 2;
        } else if(strncmp(line, ";;last_queried: ", 16) == 0) {
                if(!tp) return -1;
                lock_basic_lock(&tp->lock);
@@ -663,7 +671,6 @@ int autr_read_file(struct val_anchors* anchors, const char* nm)
                 return 0;
         }
         verbose(VERB_ALGO, "reading autotrust anchor file %s", nm);
-       /* TODO: read line to see if special marker for revoked tp */
         while (fgets(line, (int)sizeof(line), fd) != NULL) {
                 line_nr++;
                if((r = parse_var_line(line, anchors, &tp)) == -1) {
@@ -672,6 +679,10 @@ int autr_read_file(struct val_anchors* anchors, const char* nm)
                        return 0;
                } else if(r == 1) {
                        continue;
+               } else if(r == 2) {
+                       log_warn("trust anchor %s has been revoked", nm);
+                       fclose(fd);
+                       return 1;
                }
                if (!str_contains_data(line, ';'))
                        continue; /* empty lines allowed */
@@ -757,6 +768,14 @@ void autr_write_file(struct module_env* env, struct trust_anchor* tp)
        }
        /* write pretty header */
        fprintf(out, "; autotrust trust anchor file\n");
+       if(tp->autr->revoked) {
+               fprintf(out, ";;REVOKED\n");
+               fprintf(out, "; The zone has all keys revoked, and is\n"
+                       "; considered as if it has no trust anchors.\n"
+                       "; the remainder of the file is the last probe.\n"
+                       "; to restart the trust anchor, overwrite this file.\n"
+                       "; with one containing valid DNSKEYs or DSes.\n");
+       }
        print_id(out, env, tp->name, tp->namelen, tp->dclass);
        fprintf(out, ";;last_queried: %u ;;%s", 
                (unsigned int)tp->autr->last_queried, 
@@ -771,9 +790,6 @@ void autr_write_file(struct module_env* env, struct trust_anchor* tp)
        fprintf(out, ";;query_interval: %d\n", (int)tp->autr->query_interval);
        fprintf(out, ";;retry_time: %d\n", (int)tp->autr->retry_time);
 
-       /* write revoked tp special marker */
-       /* TODO */
-
        /* write anchors */
        for(ta=tp->autr->keys; ta; ta=ta->next) {
                char* str;
@@ -1399,6 +1415,36 @@ autr_cleanup_keys(struct trust_anchor* tp)
        }
 }
 
+/** Delete trust point that was revoked */
+static void
+autr_tp_remove(struct module_env* env, struct trust_anchor* tp)
+{
+       struct trust_anchor key;
+       /* save name */
+       memset(&key, 0, sizeof(key));
+       key.node.key = &key;
+       key.name = regional_alloc_init(env->scratch, tp->name, tp->namelen);
+       if(!key.name) {
+               log_err("out of scratch memory in trust point delete");
+               /* the revoked=1 flag on it saves the day, but wastes memory */
+               return;
+       }
+       key.namelen = tp->namelen;
+       key.namelabs = tp->namelabs;
+       key.dclass = tp->dclass;
+
+       /* unlock */
+       lock_basic_unlock(&tp->lock);
+
+       /* take from tree. It could be deleted by someone else. */
+       lock_basic_lock(&env->anchors->lock);
+       (void)rbtree_delete(env->anchors->tree, &key);
+       anchors_init_parents_locked(env->anchors);
+       lock_basic_unlock(&env->anchors->lock);
+       /* delete */
+       autr_point_delete(tp);
+}
+
 int autr_process_prime(struct module_env* env, struct val_env* ve,
        struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset)
 {
@@ -1407,7 +1453,15 @@ int autr_process_prime(struct module_env* env, struct val_env* ve,
        /* autotrust update trust anchors */
        /* the tp is locked, and stays locked unless it is deleted */
 
-       /* TODO: check if marked as revoked, if so, unlock and return */
+       /* we could just catch the anchor here while another thread
+        * is busy deleting it. Just unlock and let the other do its job */
+       if(tp->autr->revoked) {
+               log_nametypeclass(VERB_ALGO, "autotrust not processed, "
+                       "trust point revoked", tp->name, 
+                       LDNS_RR_TYPE_DNSKEY, tp->dclass);
+               lock_basic_unlock(&tp->lock);
+               return 0; /* it is revoked */
+       }
 
        /* query_dnskeys(): */
        tp->autr->last_queried = *env->now;
@@ -1460,9 +1514,8 @@ int autr_process_prime(struct module_env* env, struct val_env* ve,
                }
                if(!tp->ds_rrset && !tp->dnskey_rrset) {
                        /* no more keys, all are revoked */
-                       /* TODO: delete trust point:
-                        *      mark as revoked trust point.
-                        *      save name, unlock, take from tree, delete. */
+                       tp->autr->revoked = 1;
+                       autr_tp_remove(env, tp);
                        return 0; /* trust point removed */
                }
        } else verbose(VERB_ALGO, "autotrust: no changes");
index 4b12a3644876bf605645076579636feb73e119d8..ff336ce63d0da60aedbf2e6c0eb5e43c967462ea 100644 (file)
@@ -80,6 +80,7 @@ struct autr_ta {
 
 /** 
  * Autotrust metadata for a trust point.
+ * This is part of the struct trust_anchor data.
  */
 struct autr_point_data {
        /** file to store the trust point in. chrootdir already applied. */
@@ -104,6 +105,8 @@ struct autr_point_data {
 
        /** how many times did it fail */
        uint8_t query_failed;
+       /** true if the trust point has been revoked */
+       uint8_t revoked;
 };
 
 /** 
index e7517f8fe09f2db20e3fe5c5c78f23de01c6a6c7..fa49fbb97596089a82af507f08504eb366fba35a 100644 (file)
@@ -120,15 +120,13 @@ anchors_delete(struct val_anchors* anchors)
        free(anchors);
 }
 
-/** initialise parent pointers in the tree */
-static void
-init_parents(struct val_anchors* anchors)
+void
+anchors_init_parents_locked(struct val_anchors* anchors)
 {
        struct trust_anchor* node, *prev = NULL, *p;
        int m; 
        /* nobody else can grab locks because we hold the main lock.
         * Thus the previous items, after unlocked, are not deleted */
-       lock_basic_lock(&anchors->lock);
        RBTREE_FOR(node, struct trust_anchor*, anchors->tree) {
                lock_basic_lock(&node->lock);
                node->parent = NULL;
@@ -153,6 +151,14 @@ init_parents(struct val_anchors* anchors)
                lock_basic_unlock(&node->lock);
                prev = node;
        }
+}
+
+/** initialise parent pointers in the tree */
+static void
+init_parents(struct val_anchors* anchors)
+{
+       lock_basic_lock(&anchors->lock);
+       anchors_init_parents_locked(anchors);
        lock_basic_unlock(&anchors->lock);
 }
 
index af530ba2e28f7999d0bf9cbb7359961cbf7da581..bc39efb07d31ac93d33f9ba3ea850e29b7d3fbce 100644 (file)
@@ -141,6 +141,16 @@ void anchors_delete(struct val_anchors* anchors);
  */
 int anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg);
 
+/**
+ * Recalculate parent pointers.  The caller must hold the lock on the
+ * anchors structure (say after removing an item from the rbtree).
+ * Caller must not hold any locks on trust anchors.
+ * After the call is complete the parent pointers are updated and an item
+ * just removed is no longer referenced in parent pointers.
+ * @param anchors: the structure to update.
+ */
+void anchors_init_parents_locked(struct val_anchors* anchors);
+
 /**
  * Given a qname/qclass combination, find the trust anchor closest above it.
  * Or return NULL if none exists.