]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
bind config trusted keys read work.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 30 Aug 2007 15:36:23 +0000 (15:36 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 30 Aug 2007 15:36:23 +0000 (15:36 +0000)
git-svn-id: file:///svn/unbound/trunk@568 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

index 7aad2b2a8a3c3436faa2176024477b5b823d8aa6..387b93bd49a4c9121b293d2cd057026cd320a697 100644 (file)
@@ -169,7 +169,13 @@ server:
        # (These examples are from August 2007 and may not be valid anymore).
        # trust-anchor: "nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ=="
        # trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A"
-       
+
+       # File with trusted keys for validation. Specify more than one file
+       # with several entries, one file per entry. Like trust-anchor-file
+       # but has a different file format. Format is BIND-9 style format, 
+       # the trusted-keys { name flag proto algo "key"; }; clauses are read.
+       # trusted-keys-file: ""
+
        # Override the date for validation with a specific fixed date.
        # Do not set this unless you are debugging signature inception
        # and expiration. "" or "0" turns the feature off. 
index 25b5890bd0c90b4aadbb62aec6496c644009f95a..9062c1b246035432d7ee1b92de35f223fad4a8c1 100644 (file)
@@ -209,6 +209,11 @@ The resource record is entered in the same format as 'dig' or 'drill' prints
 them, the same format as in the zone file. Has to be on a single line, with
 "" around it. A TTL can be specified for ease of cut and paste, but is ignored. 
 A class can be specified, but class IN is default.
+.It \fBtrusted-keys-file:\fR <filename>
+File with trusted keys for validation. Specify more than one file
+with several entries, one file per entry. Like \fBtrust-anchor-file\fR
+but has a different file format. Format is BIND-9 style format, 
+the trusted-keys { name flag proto algo "key"; }; clauses are read.
 .It \fBval-override-date:\fR <rrsig-style date spec>
 Default is "" or "0", which disables this debugging feature. If enabled by
 giving a RRSIG style date, that date is used for verifying RRSIG inception
index 0756d36701f01849c74289b8f4e62c7360d84d14..041526571d55427255eb6e25094566c1dbfd9e8c 100644 (file)
@@ -116,6 +116,7 @@ config_create()
        cfg->version = NULL;
        cfg->trust_anchor_file_list = NULL;
        cfg->trust_anchor_list = NULL;
+       cfg->trusted_keys_file_list = NULL;
        cfg->val_date_override = 0;
        cfg->val_clean_additional = 1;
        cfg->val_permissive_mode = 0;
index 6226d9f0cf8e29fb70fcb2b61953fc291a3c5067..69f41c27b3a1601ef061e420570f5aa4e2247401 100644 (file)
@@ -147,6 +147,8 @@ struct config_file {
        struct config_strlist* trust_anchor_file_list;
        /** list of trustanchor keys, linked list */
        struct config_strlist* trust_anchor_list;
+       /** files with trusted DNSKEYs in named.conf format, list */
+       struct config_strlist* trusted_keys_file_list;
 
        /** if not 0, this value is the validation date for RRSIGs */
        int32_t val_date_override;
index 6a4e5a697d59b5b7931e0292e22be2f851dac364..e7cdd83701c5f2ef7db2f6a647548c4834158682 100644 (file)
@@ -145,6 +145,7 @@ 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;}
+trusted-keys-file{COLON}       { YDOUT; return VAR_TRUSTED_KEYS_FILE;}
 trust-anchor{COLON}    { YDOUT; return VAR_TRUST_ANCHOR;}
 val-override-date{COLON}       { YDOUT; return VAR_VAL_OVERRIDE_DATE;}
 val-bogus-ttl{COLON}   { YDOUT; return VAR_BOGUS_TTL;}
index 4a16e08ccd4c7c7c4c8f8103b25fa66838ae267c..ac9fb58dda6e1a3fcc11587559a15714bcbfd6b0 100644 (file)
@@ -83,7 +83,7 @@ extern struct config_parser_state* cfg_parser;
 %token VAR_TRUST_ANCHOR_FILE VAR_TRUST_ANCHOR VAR_VAL_OVERRIDE_DATE
 %token VAR_BOGUS_TTL VAR_VAL_CLEAN_ADDITIONAL VAR_VAL_PERMISSIVE_MODE
 %token VAR_INCOMING_NUM_TCP VAR_MSG_BUFFER_SIZE VAR_KEY_CACHE_SIZE
-%token VAR_KEY_CACHE_SLABS
+%token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE
 
 %%
 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -120,7 +120,8 @@ content_server: server_num_threads | server_verbosity | server_port |
        server_trust_anchor | server_val_override_date | server_bogus_ttl |
        server_val_clean_additional | server_val_permissive_mode |
        server_incoming_num_tcp | server_msg_buffer_size | 
-       server_key_cache_size | server_key_cache_slabs
+       server_key_cache_size | server_key_cache_slabs | 
+       server_trusted_keys_file
        ;
 stubstart: VAR_STUB_ZONE
        {
@@ -309,6 +310,14 @@ server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING
                        yyerror("out of memory");
        }
        ;
+server_trusted_keys_file: VAR_TRUSTED_KEYS_FILE STRING
+       {
+               OUTYY(("P(server_trusted_keys_file:%s)\n", $2));
+               if(!cfg_strlist_insert(&cfg_parser->cfg->
+                       trusted_keys_file_list, $2))
+                       yyerror("out of memory");
+       }
+       ;
 server_trust_anchor: VAR_TRUST_ANCHOR STRING
        {
                OUTYY(("P(server_trust_anchor:%s)\n", $2));
index f6b8e3d3dcfdbdbf958de22c6d4cceffb589c793..fab8e0cabe31db728f9ace22a7d3fccb7124afd6 100644 (file)
@@ -363,6 +363,163 @@ anchor_read_file(struct val_anchors* anchors, ldns_buffer* buffer,
        return ok;
 }
 
+/** skip file to end of line */
+static void
+skip_to_eol(FILE* in)
+{
+       int c;
+       while((c = getc(in)) != EOF ) {
+               if(c == '\n')
+                       return;
+       }
+}
+
+/** true for special characters in bind configs */
+static int
+is_bind_special(int c)
+{
+       switch(c) {
+               case '{':
+               case '}':
+               case '"':
+               case ';':
+                       return 1;
+       }
+       return 0;
+}
+
+/** Read a keyword skipping bind comments; spaces, specials, restkeywords. */
+static int
+readkeyword_bindfile(FILE* in, ldns_buffer* buf, int* line)
+{
+       int c;
+       int numdone = 0;
+       while((c = getc(in)) != EOF ) {
+               if(c == '#') {  /*   # blabla   */
+                       skip_to_eol(in);
+                       (*line)++;
+                       continue;
+               } else if(c=='/' && numdone>0 &&        /* /_/ blabla */
+                       ldns_buffer_read_u8_at(buf, 
+                       ldns_buffer_position(buf)-1) == '/') {
+                       ldns_buffer_skip(buf, -1);
+                       numdone--;
+                       skip_to_eol(in);
+                       (*line)++;
+                       continue;
+               } else if(c=='*' && numdone>0 &&        /* /_* blabla *_/ */
+                       ldns_buffer_read_u8_at(buf, 
+                       ldns_buffer_position(buf)-1) == '/') {
+                       ldns_buffer_skip(buf, -1);
+                       /* skip to end of comment */
+                       while(c != EOF && (c=getc(in)) != EOF ) {
+                               if(c == '*') {
+                                       if((c=getc(in)) == '/')
+                                               break;
+                               }
+                               if(c == '\n')
+                                       (*line)++;
+                       }
+                       continue;
+               }
+               /* not a comment, complete the keyword */
+               if(numdone > 0) {
+                       /* check same type */
+                       if(isspace(c)) {
+                               ungetc(c, in);
+                               return numdone;
+                       }
+                       if(is_bind_special(c)) {
+                               ungetc(c, in);
+                               return numdone;
+                       }
+               }
+               if(c == '\n')
+                       (*line)++;
+               if(ldns_buffer_remaining(buf) < 1) {
+                       fatal_exit("trusted-keys, %d, string too long", *line);
+               }
+               ldns_buffer_write_u8(buf, c);
+               numdone++;
+               if(isspace(c))
+                       return numdone;
+               if(is_bind_special(c))
+                       return numdone;
+       }
+       return numdone;
+}
+
+/** skip through file to { */
+static int 
+skip_to_brace_open(FILE* in, int* line) 
+{
+       int c;
+       while((c = getc(in)) != EOF ) {
+               if(c == '\n')
+                       (*line)++;
+               if(isspace(c))
+                       continue;
+               if(c != '{') {
+                       log_err("trusted-keys, line %d, expected {", *line);
+                       return 0;
+               }
+               return 1;
+       }
+       log_err("trusted-keys, line %d, expected {", *line);
+       return 0;
+}
+
+static int
+process_bind_contents(struct val_anchors* anchors, ldns_buffer* buffer,
+       int* line)
+{
+       char* str = 0;
+       if(!anchor_store_str(anchors, buffer, str)) {
+       }
+}
+
+/**
+ * Read a BIND9 like file with trust anchors in named.conf format.
+ * @param anchors: anchor storage.
+ * @param buffer: parsing buffer.
+ * @param fname: string.
+ * @return false on error.
+ */
+static int
+anchor_read_bind_file(struct val_anchors* anchors, ldns_buffer* buffer,
+       const char* fname)
+{
+       int line_nr = 1;
+       FILE* in = fopen(fname, "r");
+       int rdlen = 0;
+       if(!in) {
+               log_err("error opening file %s: %s", fname, strerror(errno));
+               return 0;
+       }
+       fclose(in);
+       /* scan for  trusted-keys  keyword, ignore everything else */
+       ldns_buffer_clear(buffer);
+       while((rdlen=readkeyword_bindfile(in, buffer, &line_nr)) != 0) {
+               if(rdlen != 12 || strncmp((char*)ldns_buffer_begin(buffer),
+                       "trusted-keys", 12) != 0) {
+                       ldns_buffer_clear(buffer);
+                       /* ignore everything but trusted-keys */
+                       continue;
+               }
+               if(!skip_to_brace_open(in, &line_nr)) {
+                       log_err("error in trusted key: \"%s\"", fname);
+                       return 0;
+               }
+               /* process contents */
+               if(!process_bind_contents(anchors, buffer, &line_nr)) {
+                       log_err("error in trusted key: \"%s\"", fname);
+                       return 0;
+               }
+               ldns_buffer_clear(buffer);
+       }
+       return 1;
+}
+
 /** 
  * Assemble an rrset structure for the type 
  * @param region: allocated in this region.
@@ -478,6 +635,15 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
                        return 0;
                }
        }
+       for(f = cfg->trusted_keys_file_list; f; f = f->next) {
+               if(!f->str || f->str[0] == 0) /* empty "" */
+                       continue;
+               if(!anchor_read_bind_file(anchors, parsebuf, f->str)) {
+                       log_err("error reading trusted-keys-file: %s", f->str);
+                       ldns_buffer_free(parsebuf);
+                       return 0;
+               }
+       }
        for(f = cfg->trust_anchor_list; f; f = f->next) {
                if(!f->str || f->str[0] == 0) /* empty "" */
                        continue;