bind config trusted keys read work.

git-svn-id: file:///svn/unbound/trunk@568 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-08-30 15:36:23 +00:00
parent 45297772c9
commit fceea2bcd5
7 changed files with 193 additions and 3 deletions

View 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.

View 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

View 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;

View 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;

View 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;}

View 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));

View 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;