From: Wouter Wijngaards Date: Thu, 30 Aug 2007 15:36:23 +0000 (+0000) Subject: bind config trusted keys read work. X-Git-Tag: release-0.5~73 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fceea2bcd573666d465d3acb41d522bce9bbc707;p=thirdparty%2Funbound.git bind config trusted keys read work. git-svn-id: file:///svn/unbound/trunk@568 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/example.conf b/doc/example.conf index 7aad2b2a8..387b93bd4 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -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. diff --git a/doc/unbound.conf.5 b/doc/unbound.conf.5 index 25b5890bd..9062c1b24 100644 --- a/doc/unbound.conf.5 +++ b/doc/unbound.conf.5 @@ -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 +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 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 diff --git a/util/config_file.c b/util/config_file.c index 0756d3670..041526571 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -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; diff --git a/util/config_file.h b/util/config_file.h index 6226d9f0c..69f41c27b 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -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; diff --git a/util/configlexer.lex b/util/configlexer.lex index 6a4e5a697..e7cdd8370 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -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;} diff --git a/util/configparser.y b/util/configparser.y index 4a16e08cc..ac9fb58dd 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -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)); diff --git a/validator/val_anchor.c b/validator/val_anchor.c index f6b8e3d3d..fab8e0cab 100644 --- a/validator/val_anchor.c +++ b/validator/val_anchor.c @@ -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;