]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
validator, trust anchors.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 2 Aug 2007 15:45:32 +0000 (15:45 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 2 Aug 2007 15:45:32 +0000 (15:45 +0000)
git-svn-id: file:///svn/unbound/trunk@482 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/example.conf
doc/unbound.conf.5
util/config_file.c
util/config_file.h
util/configlexer.lex
util/configparser.y
validator/val_anchor.c [new file with mode: 0644]
validator/val_anchor.h [new file with mode: 0644]
validator/validator.c
validator/validator.h

index 49c636cc0b6702b447e4bc8ff16446f2ac8a15e8..4d1b04afe8aef3d2d49366f918c60fbd18105cd1 100644 (file)
@@ -151,6 +151,10 @@ server:
        # module configuration of the server. A string with identifiers
        # separated by spaces. "iterator" or "validator iterator"
        # module-config: "validator iterator"
+       
+       # File with trusted keys for validation.
+       # Zone file format, with DS and DNSKEY entries.
+       # trust-anchor-file: ""
 
 # Stub zones.
 # Create entries like below, to make all queries for 'example.com' and 
index 3811b36879dd28ec520b23d255e22a07f627bdfb..b2166ecce6c1ab88a09dbfa3dda7773e880d0e8d 100644 (file)
@@ -188,6 +188,10 @@ Module configuration, a list of module names separated by spaces, surround
 the string with quotes (""). The modules can be validator, iterator.
 Setting this to "iterator" will result in a non-validating server.
 Setting this to "validator iterator" will turn on validation.
+.It \fBtrust-anchor-file:\fR <filename>
+File with trusted keys for validation. Both DS and DNSKEY entries can appear
+in the file. The format of the file is the standard DNS Zone file format.
+Default is "", or no trust anchor file.
 .El
 
 .Ss Stub Zone Options
index c803cebf26a3b8e99b9be4f5939b3a35bd6325cb..94175f0740d1903291afef344caa986bb891d3e2 100644 (file)
@@ -111,6 +111,7 @@ config_create()
        cfg->hide_version = 0;
        cfg->identity = NULL;
        cfg->version = NULL;
+       cfg->trust_anchor_file = NULL;
        if(!(cfg->module_conf = strdup("iterator"))) goto error_exit;
        return cfg;
 error_exit:
@@ -205,6 +206,7 @@ config_delete(struct config_file* cfg)
        free(cfg->identity);
        free(cfg->version);
        free(cfg->module_conf);
+       free(cfg->trust_anchor_file);
        free(cfg);
 }
 
index 0a66e25e428d93cbb4022d3835855db825cdc19e..71d5ead0e8d0255ef1d1952fdc628ec7d2099d5b 100644 (file)
@@ -139,6 +139,9 @@ struct config_file {
        /** the module configuration string */
        char* module_conf;
        
+       /** file with trusted DS and DNSKEYs in zonefile format */
+       char* trust_anchor_file;
+
        /** daemonize, i.e. fork into the background. */
        int do_daemonize;
 };
index 365b887b592317f09ce97829389d3d5cbf0067a0..d902f988a85cb8ff153d140588d481457a923df1 100644 (file)
@@ -142,6 +142,7 @@ hide-version{COLON}     { YDOUT; return VAR_HIDE_VERSION;}
 identity{COLON}                { YDOUT; return VAR_IDENTITY;}
 version{COLON}         { YDOUT; return VAR_VERSION;}
 module-conf{COLON}             { YDOUT; return VAR_MODULE_CONF;}
+trust-anchor-file{COLON}       { YDOUT; return VAR_TRUST_ANCHOR_FILE;}
 {NEWLINE}              { LEXOUT(("NL\n")); cfg_parser->line++;}
 
        /* Quoted strings. Strip leading and ending quotes */
index 6e2e688752a433419b2d6535d491444e03443824..b086f8cbe643a0073c0156ebac343992cdd1f471 100644 (file)
@@ -80,6 +80,7 @@ extern struct config_parser_state* cfg_parser;
 %token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR
 %token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION
 %token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE VAR_MODULE_CONF
+%token VAR_TRUST_ANCHOR_FILE
 
 %%
 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -112,7 +113,7 @@ content_server: server_num_threads | server_verbosity | server_port |
        server_harden_short_bufsize | server_harden_large_queries |
        server_do_not_query_address | server_hide_identity |
        server_hide_version | server_identity | server_version |
-       server_harden_glue | server_module_conf
+       server_harden_glue | server_module_conf | server_trust_anchor_file
        ;
 stubstart: VAR_STUB_ZONE
        {
@@ -284,6 +285,13 @@ server_pidfile: VAR_PIDFILE STRING
                cfg_parser->cfg->pidfile = $2;
        }
        ;
+server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING
+       {
+               OUTYY(("P(server_trust_anchor_file:%s)\n", $2));
+               free(cfg_parser->cfg->trust_anchor_file);
+               cfg_parser->cfg->trust_anchor_file = $2;
+       }
+       ;
 server_hide_identity: VAR_HIDE_IDENTITY STRING
        {
                OUTYY(("P(server_hide_identity:%s)\n", $2));
diff --git a/validator/val_anchor.c b/validator/val_anchor.c
new file mode 100644 (file)
index 0000000..af0fef7
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * validator/val_anchor.c - validator trust anchor storage.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains storage for the trust anchors for the validator.
+ */
+#include "config.h"
+#include "validator/val_anchor.h"
+#include "util/data/packed_rrset.h"
+#include "util/data/dname.h"
+#include "util/log.h"
+#include "util/region-allocator.h"
+#include "util/config_file.h"
+
+/** compare two trust anchors */
+static int
+anchor_cmp(const void* k1, const void* k2)
+{
+       int m;
+       struct trust_anchor* n1 = (struct trust_anchor*)k1;
+       struct trust_anchor* n2 = (struct trust_anchor*)k2;
+       /* no need to ntohs(class) because sort order is irrelevant */
+       if(n1->dclass != n2->dclass) {
+               if(n1->dclass < n2->dclass)
+                       return -1;
+               return 1;
+       }
+       return dname_lab_cmp(n1->name, n1->namelabs, n2->name, n2->namelabs, 
+               &m);
+}
+
+struct val_anchors* 
+anchors_create()
+{
+       struct val_anchors* a = (struct val_anchors*)calloc(1, sizeof(*a));
+       if(!a)
+               return NULL;
+       a->region = region_create(malloc, free);
+       if(!a->region) {
+               free(a);
+               return NULL;
+       }
+       a->tree = rbtree_create(anchor_cmp);
+       if(!a->tree) {
+               anchors_delete(a);
+               return NULL;
+       }
+       return a;
+}
+
+void 
+anchors_delete(struct val_anchors* anchors)
+{
+       if(!anchors)
+               return;
+       free(anchors->tree);
+       region_destroy(anchors->region);
+       free(anchors);
+}
+
+/** initialise parent pointers in the tree */
+static void
+init_parents(struct val_anchors* anchors)
+{
+       struct trust_anchor* node, *prev = NULL, *p;
+       int m; 
+       RBTREE_FOR(node, struct trust_anchor*, anchors->tree) {
+               node->parent = NULL;
+               if(!prev || prev->dclass != node->dclass) {
+                       prev = node;
+                       continue;
+               }
+               (void)dname_lab_cmp(prev->name, prev->namelabs, node->name, 
+                       node->namelabs, &m); /* we know prev is smaller */
+               /* sort order like: . com. bla.com. zwb.com. net. */
+               /* find the previous, or parent-parent-parent */
+               for(p = prev; p; p = p->parent)
+                       /* looking for name with few labels, a parent */
+                       if(p->namelabs <= m) {
+                               /* ==: since prev matched m, this is closest*/
+                               /* <: prev matches more, but is not a parent,
+                               * this one is a (grand)parent */
+                               node->parent = p;
+                               break;
+                       }
+               prev = node;
+       }
+}
+
+int 
+anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
+{
+       if(cfg->trust_anchor_file && cfg->trust_anchor_file[0]) {
+               /* read trust anchor file */
+       }
+       init_parents(anchors);
+       return 1;
+}
+
+struct trust_anchor* 
+anchors_lookup(struct val_anchors* anchors,
+        uint8_t* qname, size_t qname_len, uint16_t qclass)
+{
+       return NULL;
+}
diff --git a/validator/val_anchor.h b/validator/val_anchor.h
new file mode 100644 (file)
index 0000000..f0de67e
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * validator/val_anchor.h - validator trust anchor storage.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains storage for the trust anchors for the validator.
+ */
+
+#ifndef VALIDATOR_VAL_ANCHOR_H
+#define VALIDATOR_VAL_ANCHOR_H
+#include "util/rbtree.h"
+struct region;
+struct trust_anchor;
+struct config_file;
+
+/**
+ * Trust anchor store.
+ */
+struct val_anchors {
+       /** region where trust anchors are allocated */
+       struct region* region;
+       /**
+        * Anchors are store in this tree. Sort order is chosen, so that
+        * dnames are in nsec-like order. A lookup on class, name will return
+        * an exact match of the closest match, with the ancestor needed.
+        * contents of type trust_anchor.
+        */
+       rbtree_t* tree;
+};
+
+/**
+ * Trust anchor key
+ */
+struct ta_key {
+       /** next in list */
+       struct ta_key* next;
+       /** rdata, in wireformat of the key RR. */
+       uint8_t* data;
+       /** length of the rdata */
+       size_t len;
+       /** DNS type (host format) of the key, DS or DNSKEY */
+       uint16_t type;
+};
+
+/**
+ * A trust anchor in the trust anchor store.
+ * Unique by name, class.
+ */
+struct trust_anchor {
+       /** rbtree node, key is this structure */
+       rbnode_t node;
+       /** name of this trust anchor */
+       uint8_t* name;
+       /** number of labels in name of rrset */
+       int namelabs;
+       /** the ancestor in the trustanchor tree */
+       struct trust_anchor* parent;
+       /** 
+        * List of DS or DNSKEY rrs that form the trust anchor.
+        * It is allocated in the region.
+        */
+       struct ta_key* keylist;
+       /** number of DSs in the keylist */
+       size_t numDS;
+       /** number of DNSKEYs in the keylist */
+       size_t numDNSKEY;
+       /** class of the trust anchor */
+       uint16_t dclass;
+};
+
+/**
+ * Create trust anchor storage
+ * @return new storage or NULL on error.
+ */
+struct val_anchors* anchors_create();
+
+/**
+ * Delete trust anchor storage.
+ * @param anchors: to delete.
+ */
+void anchors_delete(struct val_anchors* anchors);
+
+/**
+ * Process trust anchor config.
+ * @param anchors: struct anchor storage
+ * @param cfg: config options.
+ * @return 0 on error.
+ */
+int anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg);
+
+/**
+ * Given a qname/qclass combination, find the trust anchor closest above it.
+ * Or return NULL if none exists.
+ *
+ * @param anchors: struct anchor storage
+ * @param qname: query name, uncompressed wireformat.
+ * @param qname_len: length of qname.
+ * @param qclass: class to query for.
+ * @return the trust anchor or NULL if none is found.
+ */
+struct trust_anchor* anchors_lookup(struct val_anchors* anchors,
+       uint8_t* qname, size_t qname_len, uint16_t qclass);
+
+#endif /* VALIDATOR_VAL_ANCHOR_H */
index 90aa0e3f87c3c719065065b716128cac17ed6519..d03808b1bfec943d01f924466a746f5d403e293b 100644 (file)
  */
 #include "config.h"
 #include "validator/validator.h"
+#include "validator/val_anchor.h"
 #include "services/cache/dns.h"
 #include "util/module.h"
 #include "util/log.h"
 #include "util/net_help.h"
 #include "util/region-allocator.h"
 
+/** apply config settings to validator */
+static int
+val_apply_cfg(struct val_env* val_env, struct config_file* cfg)
+{
+       if(!val_env->anchors)
+               val_env->anchors = anchors_create();
+       if(!val_env->anchors) {
+               log_err("out of memory");
+               return 0;
+       }
+       if(!anchors_apply_cfg(val_env->anchors, cfg)) {
+               log_err("validator: error in trustanchors config");
+               return 0;
+       }
+       return 1;
+}
+
 /** validator init */
 static int
 val_init(struct module_env* env, int id)
@@ -58,10 +76,10 @@ val_init(struct module_env* env, int id)
                return 0;
        }
        env->modinfo[id] = (void*)val_env;
-       /*if(!val_apply_cfg(val_env, env->cfg)) {
+       if(!val_apply_cfg(val_env, env->cfg)) {
                log_err("validator: could not apply configuration settings.");
                return 0;
-       }*/
+       }
        return 1;
 }
 
@@ -73,6 +91,7 @@ val_deinit(struct module_env* env, int id)
        if(!env || !env->modinfo || !env->modinfo[id])
                return;
        val_env = (struct val_env*)env->modinfo[id];
+       anchors_delete(val_env->anchors);
        free(val_env);
 }
 
index 03d2d2c176faa179cc03f5dfe804e45c121a8e8c..a664c65264567ae9e2a2bd76c2dc2bfebe29d31d 100644 (file)
 #define VALIDATOR_VALIDATOR_H
 struct module_func_block;
 #include "util/data/msgreply.h"
+struct val_anchors;
 
 /**
  * Global state for the validator. 
  */
 struct val_env {
-       /** global state placeholder */
-       int option;
-
        /** trusted key storage */
+       struct val_anchors* anchors;
 
        /** key cache */
 };