mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-15 19:22:55 -05:00
autotrust work
git-svn-id: file:///svn/unbound/trunk@1769 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
1e2111f593
commit
ca94ca57b4
3 changed files with 168 additions and 17 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue