]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
autotrust work
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 20 Aug 2009 11:49:33 +0000 (11:49 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 20 Aug 2009 11:49:33 +0000 (11:49 +0000)
git-svn-id: file:///svn/unbound/trunk@1769 be551aaa-1e26-0410-a405-d3ace91eadb9

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

index d8b35ffbab64a476d4e24d511eb8560311065c8a..17cd4d1b392605f82187d3a711a186a29ecd9b94 100644 (file)
@@ -1,3 +1,6 @@
+20 August 2009: Wouter
+       - autotrust: save and read trustpoint variables.
+
 19 August 2009: Wouter
        - autotrust: state table updates.
        - iana portlist updated.
index 55ca68e3bf1d9f7a387a456360aa5ede565a2628..d9d7f2bd9d6e3f99d6a5cb80fd6a9e6ec391ebdd 100644 (file)
@@ -303,9 +303,8 @@ autr_ta_create(ldns_rr* rr)
 
 /** create tp */
 static struct trust_anchor*
-autr_tp_create(struct val_anchors* anchors, ldns_rr* rr)
+autr_tp_create(struct val_anchors* anchors, ldns_rdf* own, uint16_t dc)
 {
-       ldns_rdf* own = ldns_rr_owner(rr);
        struct trust_anchor* tp = (struct trust_anchor*)calloc(1, sizeof(*tp));
        if(!tp) return NULL;
        tp->name = memdup(ldns_rdf_data(own), ldns_rdf_size(own));
@@ -316,7 +315,7 @@ autr_tp_create(struct val_anchors* anchors, ldns_rr* rr)
        tp->namelen = ldns_rdf_size(own);
        tp->namelabs = dname_count_labels(tp->name);
        tp->node.key = tp;
-       tp->dclass = ldns_rr_get_class(rr);
+       tp->dclass = dc;
        tp->autr = (struct autr_point_data*)calloc(1, sizeof(*tp->autr));
        if(!tp->autr) {
                free(tp->name);
@@ -326,7 +325,14 @@ autr_tp_create(struct val_anchors* anchors, ldns_rr* rr)
        tp->autr->pnode.key = tp;
 
        lock_basic_lock(&anchors->lock);
-       (void)rbtree_insert(anchors->tree, &tp->node);
+       if(!rbtree_insert(anchors->tree, &tp->node)) {
+               lock_basic_unlock(&anchors->lock);
+               log_err("trust anchor presented twice");
+               free(tp->name);
+               free(tp->autr);
+               free(tp);
+               return NULL;
+       }
        lock_basic_unlock(&anchors->lock);
        lock_basic_init(&tp->lock);
        lock_protect(&tp->lock, tp, sizeof(*tp));
@@ -385,7 +391,7 @@ find_add_tp(struct val_anchors* anchors, ldns_rr* rr)
                }
                return tp;
        }
-       tp = autr_tp_create(anchors, rr);
+       tp = autr_tp_create(anchors, ldns_rr_owner(rr), ldns_rr_get_class(rr));
        lock_basic_lock(&tp->lock);
        return tp;
 }
@@ -543,6 +549,102 @@ autr_assemble(struct trust_anchor* tp)
        return 1;
 }
 
+/** parse integer */
+static unsigned int
+parse_int(char* line, int* ret)
+{
+       char *e;
+       unsigned int x = (unsigned int)strtol(line, &e, 10);
+       if(line == e) {
+               *ret = -1; /* parse error */
+               return 0; 
+       }
+       *ret = 1; /* matched */
+       return x;
+}
+
+/** parse id sequence for anchor */
+static struct trust_anchor*
+parse_id(struct val_anchors* anchors, char* line)
+{
+       struct trust_anchor *tp;
+       size_t len;
+       int labs, r;
+       ldns_rdf* rdf;
+       uint16_t dclass;
+       /* read the owner name */
+       char* next = strchr(line, ' ');
+       if(!next) return NULL;
+       next[0] = 0;
+       rdf = ldns_dname_new_frm_str(line);
+       if(!rdf) return NULL;
+       labs = dname_count_size_labels(ldns_rdf_data(rdf), &len);
+       log_assert(len == ldns_rdf_size(rdf));
+
+       /* read the class */
+       dclass = parse_int(next+1, &r);
+       if(r == -1) {
+               ldns_rdf_deep_free(rdf);
+               return NULL;
+       }
+
+       /* find the trust point */
+       tp = autr_tp_create(anchors, rdf, dclass);
+       ldns_rdf_deep_free(rdf);
+       return tp;
+}
+
+/** parse variable from trustanchor header 
+ * @param line: to parse
+ * @param anchors: the anchor is added to this, if "id:" is seen.
+ * @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.
+ */
+static int
+parse_var_line(char* line, struct val_anchors* anchors, 
+       struct trust_anchor** anchor)
+{
+       struct trust_anchor* tp = *anchor;
+       int r = 0;
+       if(strncmp(line, ";;id: ", 5) == 0) {
+               *anchor = parse_id(anchors, line+6);
+               if(!*anchor) return -1;
+               else return 1;
+       } else if(strncmp(line, ";;last_queried: ", 15) == 0) {
+               if(!tp) return -1;
+               lock_basic_lock(&tp->lock);
+               tp->autr->last_queried = (time_t)parse_int(line+16, &r);
+               lock_basic_unlock(&tp->lock);
+       } else if(strncmp(line, ";;last_success: ", 15) == 0) {
+               if(!tp) return -1;
+               lock_basic_lock(&tp->lock);
+               tp->autr->last_success = (time_t)parse_int(line+16, &r);
+               lock_basic_unlock(&tp->lock);
+       } else if(strncmp(line, ";;next_probe_time: ", 18) == 0) {
+               if(!tp) return -1;
+               lock_basic_lock(&tp->lock);
+               tp->autr->next_probe_time = (time_t)parse_int(line+16, &r);
+               lock_basic_unlock(&tp->lock);
+       } else if(strncmp(line, ";;query_failed: ", 15) == 0) {
+               if(!tp) return -1;
+               lock_basic_lock(&tp->lock);
+               tp->autr->query_failed = (uint8_t)parse_int(line+16, &r);
+               lock_basic_unlock(&tp->lock);
+       } else if(strncmp(line, ";;query_interval: ", 17) == 0) {
+               if(!tp) return -1;
+               lock_basic_lock(&tp->lock);
+               tp->autr->query_interval = (uint32_t)parse_int(line+16, &r);
+               lock_basic_unlock(&tp->lock);
+       } else if(strncmp(line, ";;retry_time: ", 13) == 0) {
+               if(!tp) return -1;
+               lock_basic_lock(&tp->lock);
+               tp->autr->retry_time = (uint32_t)parse_int(line+16, &r);
+               lock_basic_unlock(&tp->lock);
+       }
+       return r;
+}
+
 int autr_read_file(struct val_anchors* anchors, const char* nm)
 {
         /* the file descriptor */
@@ -553,6 +655,7 @@ int autr_read_file(struct val_anchors* anchors, const char* nm)
         char line[10240];
        /* trust point being read */
        struct trust_anchor *tp = NULL, *tp2;
+       int r;
 
         if (!(fd = fopen(nm, "r"))) {
                 log_err("unable to open %s for reading: %s", 
@@ -564,6 +667,13 @@ int autr_read_file(struct val_anchors* anchors, const char* nm)
        /* TODO: read next probe time (if in file, otherwise now+0-100s) */
         while (fgets(line, (int)sizeof(line), fd) != NULL) {
                 line_nr++;
+               if((r = parse_var_line(line, anchors, &tp)) == -1) {
+                       log_err("could not parse auto-trust-anchor-file "
+                               "%s line %d", nm, line_nr);
+                       return 0;
+               } else if(r == 1) {
+                       continue;
+               }
                if (!str_contains_data(line, ';'))
                        continue; /* empty lines allowed */
                 if (!(tp2=load_trustanchor(anchors, line, nm))) {
@@ -596,7 +706,30 @@ int autr_read_file(struct val_anchors* anchors, const char* nm)
        return 1;
 }
 
-void autr_write_file(struct trust_anchor* tp)
+/** print ID to file */
+static void
+print_id(FILE* out, struct module_env* env, 
+       uint8_t* nm, size_t nmlen, uint16_t dclass)
+{
+       ldns_rdf rdf;
+       ldns_status s;
+
+       memset(&rdf, 0, sizeof(rdf));
+       ldns_rdf_set_data(&rdf, nm);
+       ldns_rdf_set_size(&rdf, nmlen);
+       ldns_rdf_set_type(&rdf, LDNS_RDF_TYPE_DNAME);
+
+       ldns_buffer_clear(env->scratch_buffer);
+       s = ldns_rdf2buffer_str_dname(env->scratch_buffer, &rdf);
+       log_assert(s == LDNS_STATUS_OK);
+       ldns_buffer_write_u8(env->scratch_buffer, 0);
+       ldns_buffer_flip(env->scratch_buffer);
+       fprintf(out, ";;id: %s %d\n", 
+               (char*)ldns_buffer_begin(env->scratch_buffer),
+               (int)dclass);
+}
+
+void autr_write_file(struct module_env* env, struct trust_anchor* tp)
 {
        char tmi[32];
        FILE* out;
@@ -610,9 +743,21 @@ void autr_write_file(struct trust_anchor* tp)
        }
        /* write pretty header */
        fprintf(out, "; autotrust trust anchor file\n");
+       print_id(out, env, tp->name, tp->namelen, tp->dclass);
+       ctime_r(&(tp->autr->last_queried), tmi);
+       fprintf(out, ";;last_queried: %u ;;%s\n", 
+               (unsigned int)tp->autr->last_queried, tmi);
+       ctime_r(&(tp->autr->last_success), tmi);
+       fprintf(out, ";;last_success: %u ;;%s\n", 
+               (unsigned int)tp->autr->last_success, tmi);
+       ctime_r(&(tp->autr->next_probe_time), tmi);
+       fprintf(out, ";;next_probe_time: %u ;;%s\n", 
+               (unsigned int)tp->autr->next_probe_time, tmi);
+       fprintf(out, ";;query_failed: %d\n", (int)tp->autr->query_failed);
+       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 */
-       /* write next probe time */
        /* TODO */
 
        /* write anchors */
@@ -1300,7 +1445,7 @@ int autr_process_prime(struct module_env* env, struct val_env* ve,
        if(changed) {
                verbose(VERB_ALGO, "autotrust: point changed, write to disk");
                autr_cleanup_keys(tp);
-               autr_write_file(tp);
+               autr_write_file(env, tp);
                if(!autr_assemble(tp)) {
                        log_err("malloc failure assembling autotrust keys");
                        return 1; /* unchanged */
index fcef0387745e779db5f3dd29bee1318c4df0f62e..56c97fd822cd0484da70f67fc0a1f0c65e258a70 100644 (file)
@@ -66,10 +66,10 @@ struct autr_ta {
        struct autr_ta* next;
        /** the RR */
        ldns_rr* rr;
-       /** 5011 state */
-       autr_state_t s;
        /** last update of key */
        time_t last_change;
+       /** 5011 state */
+       autr_state_t s;
        /** pending count */
        uint8_t pending_count;
        /** fresh TA was seen */
@@ -84,24 +84,26 @@ struct autr_ta {
 struct autr_point_data {
        /** file to store the trust point in. chrootdir already applied. */
        const char* file;
-       /** next probe time */
-       uint32_t next_probe_time;
        /** rbtree node for probe sort, key is struct trust_anchor */
        rbnode_t pnode;
 
+       /** the keys */
+       struct autr_ta* keys;
+
        /** last queried DNSKEY set */
        time_t last_queried;
        /** last successful DNSKEY set */
        time_t last_success;
-       /** how many times did it fail */
-       uint8_t query_failed;
+       /** next probe time */
+       time_t next_probe_time;
+
        /** when to query if !failed */
        uint32_t query_interval;
        /** when to retry if failed */
        uint32_t retry_time;
 
-       /** the keys */
-       struct autr_ta* keys;
+       /** how many times did it fail */
+       uint8_t query_failed;
 };
 
 /** 
@@ -137,9 +139,10 @@ int autr_read_file(struct val_anchors* anchors, const char* nm);
 
 /**
  * Write autotrust file.
+ * @param env: environment with scratch space.
  * @param tp: trust point to write.
  */
-void autr_write_file(struct trust_anchor* tp);
+void autr_write_file(struct module_env* env, struct trust_anchor* tp);
 
 /**
  * Delete autr anchor, deletes the autr data but does not do