mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-24 00:29:58 -05:00
autotrust event_update routine.
git-svn-id: file:///svn/unbound/trunk@1766 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
a8dccbdd40
commit
701b4ccdd6
4 changed files with 488 additions and 8 deletions
|
|
@ -1,3 +1,6 @@
|
||||||
|
17 August 2009: Wouter
|
||||||
|
- autotrust: process events.
|
||||||
|
|
||||||
17 August 2009: Wouter
|
17 August 2009: Wouter
|
||||||
- Fix so that servers are only blacklisted if they fail to reply
|
- Fix so that servers are only blacklisted if they fail to reply
|
||||||
to 16 queries in a row and the timeout gets above 2 minutes.
|
to 16 queries in a row and the timeout gets above 2 minutes.
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/alloc.h"
|
#include "util/alloc.h"
|
||||||
#include "util/regional.h"
|
#include "util/regional.h"
|
||||||
|
#include "util/net_help.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
ub_packed_rrset_parsedelete(struct ub_packed_rrset_key* pkey,
|
ub_packed_rrset_parsedelete(struct ub_packed_rrset_key* pkey,
|
||||||
|
|
@ -303,3 +304,149 @@ packed_rrset_copy_region(struct ub_packed_rrset_key* key,
|
||||||
return ck;
|
return ck;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ub_packed_rrset_key*
|
||||||
|
ub_packed_rrset_heap_key(ldns_rr_list* rrset)
|
||||||
|
{
|
||||||
|
struct ub_packed_rrset_key* k;
|
||||||
|
ldns_rr* rr;
|
||||||
|
if(!rrset)
|
||||||
|
return NULL;
|
||||||
|
rr = ldns_rr_list_rr(rrset, 0);
|
||||||
|
if(!rr)
|
||||||
|
return NULL;
|
||||||
|
k = (struct ub_packed_rrset_key*)calloc(1, sizeof(*k));
|
||||||
|
if(!k)
|
||||||
|
return NULL;
|
||||||
|
k->rk.type = htons(ldns_rr_get_type(rr));
|
||||||
|
k->rk.rrset_class = htons(ldns_rr_get_class(rr));
|
||||||
|
k->rk.dname_len = ldns_rdf_size(ldns_rr_owner(rr));
|
||||||
|
k->rk.dname = memdup(ldns_rdf_data(ldns_rr_owner(rr)),
|
||||||
|
ldns_rdf_size(ldns_rr_owner(rr)));
|
||||||
|
if(!k->rk.dname) {
|
||||||
|
free(k);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct packed_rrset_data*
|
||||||
|
packed_rrset_heap_data(ldns_rr_list* rrset)
|
||||||
|
{
|
||||||
|
struct packed_rrset_data* data;
|
||||||
|
size_t count=0, rrsig_count=0, len=0, i, j, total;
|
||||||
|
uint8_t* nextrdata;
|
||||||
|
if(!rrset || ldns_rr_list_rr_count(rrset)==0)
|
||||||
|
return NULL;
|
||||||
|
/* count sizes */
|
||||||
|
for(i=0; i<ldns_rr_list_rr_count(rrset); i++) {
|
||||||
|
ldns_rr* rr = ldns_rr_list_rr(rrset, i);
|
||||||
|
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG)
|
||||||
|
rrsig_count++;
|
||||||
|
else count++;
|
||||||
|
for(j=0; j<ldns_rr_rd_count(rr); j++)
|
||||||
|
len += ldns_rdf_size(ldns_rr_rdf(rr, j));
|
||||||
|
len += 2; /* sizeof the rdlength */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate */
|
||||||
|
total = count + rrsig_count;
|
||||||
|
len += sizeof(*data) + total*(sizeof(size_t) + sizeof(uint32_t) +
|
||||||
|
sizeof(uint8_t*));
|
||||||
|
data = (struct packed_rrset_data*)calloc(1, len);
|
||||||
|
if(!data)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* fill it */
|
||||||
|
data->ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
|
||||||
|
data->count = count;
|
||||||
|
data->rrsig_count = rrsig_count;
|
||||||
|
data->rr_len = (size_t*)((uint8_t*)data +
|
||||||
|
sizeof(struct packed_rrset_data));
|
||||||
|
data->rr_data = (uint8_t**)&(data->rr_len[total]);
|
||||||
|
data->rr_ttl = (uint32_t*)&(data->rr_data[total]);
|
||||||
|
nextrdata = (uint8_t*)&(data->rr_ttl[total]);
|
||||||
|
|
||||||
|
/* fill out len, ttl, fields */
|
||||||
|
for(i=0; i<total; i++) {
|
||||||
|
ldns_rr* rr = ldns_rr_list_rr(rrset, i);
|
||||||
|
data->rr_ttl[i] = ldns_rr_ttl(rr);
|
||||||
|
if(data->rr_ttl[i] < data->ttl)
|
||||||
|
data->ttl = data->rr_ttl[i];
|
||||||
|
data->rr_len[i] = 0;
|
||||||
|
for(j=0; j<ldns_rr_rd_count(rr); j++)
|
||||||
|
data->rr_len[i] += ldns_rdf_size(ldns_rr_rdf(rr, j));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fixup rest of ptrs */
|
||||||
|
for(i=0; i<total; i++) {
|
||||||
|
data->rr_data[i] = nextrdata;
|
||||||
|
nextrdata += data->rr_len[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy data in there */
|
||||||
|
for(i=0; i<total; i++) {
|
||||||
|
ldns_rr* rr = ldns_rr_list_rr(rrset, i);
|
||||||
|
uint16_t rdlen = htons(data->rr_len[i]);
|
||||||
|
size_t p = sizeof(rdlen);
|
||||||
|
memmove(data->rr_data[i], &rdlen, p);
|
||||||
|
for(j=0; j<ldns_rr_rd_count(rr); j++) {
|
||||||
|
ldns_rdf* rd = ldns_rr_rdf(rr, j);
|
||||||
|
memmove(data->rr_data[i]+p, ldns_rdf_data(rd),
|
||||||
|
ldns_rdf_size(rd));
|
||||||
|
p += ldns_rdf_size(rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data->rrsig_count && data->count == 0) {
|
||||||
|
data->count = data->rrsig_count; /* rrset type is RRSIG */
|
||||||
|
data->rrsig_count = 0;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** convert i'th rr to ldns_rr */
|
||||||
|
static ldns_rr*
|
||||||
|
torr(struct ub_packed_rrset_key* k, ldns_buffer* buf, size_t i)
|
||||||
|
{
|
||||||
|
struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
|
||||||
|
ldns_rr* rr = NULL;
|
||||||
|
size_t pos = 0;
|
||||||
|
ldns_status s;
|
||||||
|
ldns_buffer_clear(buf);
|
||||||
|
ldns_buffer_write(buf, k->rk.dname, k->rk.dname_len);
|
||||||
|
if(i < d->count)
|
||||||
|
ldns_buffer_write(buf, &k->rk.type, sizeof(uint16_t));
|
||||||
|
else ldns_buffer_write_u16(buf, LDNS_RR_TYPE_RRSIG);
|
||||||
|
ldns_buffer_write(buf, &k->rk.rrset_class, sizeof(uint16_t));
|
||||||
|
ldns_buffer_write_u32(buf, d->rr_ttl[i]);
|
||||||
|
ldns_buffer_write(buf, d->rr_data[i], d->rr_len[i]);
|
||||||
|
ldns_buffer_flip(buf);
|
||||||
|
s = ldns_wire2rr(&rr, ldns_buffer_begin(buf), ldns_buffer_limit(buf),
|
||||||
|
&pos, LDNS_SECTION_ANSWER);
|
||||||
|
if(s == LDNS_STATUS_OK)
|
||||||
|
return rr;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ldns_rr_list*
|
||||||
|
packed_rrset_to_rr_list(struct ub_packed_rrset_key* k, ldns_buffer* buf)
|
||||||
|
{
|
||||||
|
struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
|
||||||
|
ldns_rr_list* r = ldns_rr_list_new();
|
||||||
|
size_t i;
|
||||||
|
if(!r)
|
||||||
|
return NULL;
|
||||||
|
for(i=0; i<d->count+d->rrsig_count; i++) {
|
||||||
|
ldns_rr* rr = torr(k, buf, i);
|
||||||
|
if(!rr) {
|
||||||
|
ldns_rr_list_deep_free(r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!ldns_rr_list_push_rr(r, rr)) {
|
||||||
|
ldns_rr_free(rr);
|
||||||
|
ldns_rr_list_deep_free(r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -376,4 +376,30 @@ struct ub_packed_rrset_key* packed_rrset_copy_region(
|
||||||
struct ub_packed_rrset_key* key, struct regional* region,
|
struct ub_packed_rrset_key* key, struct regional* region,
|
||||||
uint32_t now);
|
uint32_t now);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a ub_packed_rrset_key allocated on the heap.
|
||||||
|
* It therefore does not have the correct ID value, and cannot be used
|
||||||
|
* inside the cache. It can be used in storage outside of the cache.
|
||||||
|
* Keys for the cache have to be obtained from alloc.h .
|
||||||
|
* @param rrset: the ldns rr set.
|
||||||
|
* @return key allocated or NULL on failure.
|
||||||
|
*/
|
||||||
|
struct ub_packed_rrset_key* ub_packed_rrset_heap_key(ldns_rr_list* rrset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create packed_rrset data on the heap.
|
||||||
|
* @param rrset: the ldns rr set with the data to copy.
|
||||||
|
* @return data allocated or NULL on failure.
|
||||||
|
*/
|
||||||
|
struct packed_rrset_data* packed_rrset_heap_data(ldns_rr_list* rrset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert packed rrset to ldns rr list.
|
||||||
|
* @param rrset: packed rrset.
|
||||||
|
* @param buf: scratch buffer.
|
||||||
|
* @return rr list or NULL on failure.
|
||||||
|
*/
|
||||||
|
ldns_rr_list* packed_rrset_to_rr_list(struct ub_packed_rrset_key* rrset,
|
||||||
|
ldns_buffer* buf);
|
||||||
|
|
||||||
#endif /* UTIL_DATA_PACKED_RRSET_H */
|
#endif /* UTIL_DATA_PACKED_RRSET_H */
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,13 @@ rr_is_dnskey_sep(ldns_rr* rr)
|
||||||
return (dnskey_flags(rr)&DNSKEY_BIT_SEP);
|
return (dnskey_flags(rr)&DNSKEY_BIT_SEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check if REVOKED DNSKEY */
|
||||||
|
static int
|
||||||
|
rr_is_dnskey_revoked(ldns_rr* rr)
|
||||||
|
{
|
||||||
|
return (dnskey_flags(rr)&LDNS_KEY_REVOKE_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
/** create ta */
|
/** create ta */
|
||||||
static struct autr_ta*
|
static struct autr_ta*
|
||||||
autr_ta_create(ldns_rr* rr)
|
autr_ta_create(ldns_rr* rr)
|
||||||
|
|
@ -446,6 +453,7 @@ autr_assemble(struct trust_anchor* tp)
|
||||||
{
|
{
|
||||||
ldns_rr_list* ds, *dnskey;
|
ldns_rr_list* ds, *dnskey;
|
||||||
struct autr_ta* ta;
|
struct autr_ta* ta;
|
||||||
|
struct ub_packed_rrset_key* ubds=NULL, *ubdnskey=NULL;
|
||||||
|
|
||||||
ds = ldns_rr_list_new();
|
ds = ldns_rr_list_new();
|
||||||
dnskey = ldns_rr_list_new();
|
dnskey = ldns_rr_list_new();
|
||||||
|
|
@ -472,15 +480,44 @@ autr_assemble(struct trust_anchor* tp)
|
||||||
|
|
||||||
/* make packed rrset keys - malloced with no ID number, they
|
/* make packed rrset keys - malloced with no ID number, they
|
||||||
* are not in the cache */
|
* are not in the cache */
|
||||||
|
/* make packed rrset data (if there is a key) */
|
||||||
/* make packed rrset data */
|
if(ds) {
|
||||||
|
ubds = ub_packed_rrset_heap_key(ds);
|
||||||
/* assign the data to replace the old */
|
if(!ubds)
|
||||||
|
goto error_cleanup;
|
||||||
|
ubds->entry.data = packed_rrset_heap_data(ds);
|
||||||
|
if(!ubds->entry.data)
|
||||||
|
goto error_cleanup;
|
||||||
|
}
|
||||||
|
if(dnskey) {
|
||||||
|
ubdnskey = ub_packed_rrset_heap_key(dnskey);
|
||||||
|
if(!ubdnskey)
|
||||||
|
goto error_cleanup;
|
||||||
|
ubdnskey->entry.data = packed_rrset_heap_data(dnskey);
|
||||||
|
if(!ubdnskey->entry.data) {
|
||||||
|
error_cleanup:
|
||||||
|
if(ubds) {
|
||||||
|
free(ubds->rk.dname);
|
||||||
|
free(ubds->entry.data);
|
||||||
|
free(ubds);
|
||||||
|
}
|
||||||
|
if(ubdnskey) {
|
||||||
|
free(ubdnskey->rk.dname);
|
||||||
|
free(ubdnskey->entry.data);
|
||||||
|
free(ubdnskey);
|
||||||
|
}
|
||||||
|
ldns_rr_list_free(ds);
|
||||||
|
ldns_rr_list_free(dnskey);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* free the old data */
|
/* free the old data */
|
||||||
autr_rrset_delete(tp);
|
autr_rrset_delete(tp);
|
||||||
tp->ds_rrset = NULL;
|
|
||||||
tp->dnskey_rrset = NULL;
|
/* assign the data to replace the old */
|
||||||
|
tp->ds_rrset = ubds;
|
||||||
|
tp->dnskey_rrset = ubdnskey;
|
||||||
|
|
||||||
ldns_rr_list_free(ds);
|
ldns_rr_list_free(ds);
|
||||||
ldns_rr_list_free(dnskey);
|
ldns_rr_list_free(dnskey);
|
||||||
|
|
@ -579,13 +616,279 @@ verify_dnskey(struct module_env* env, struct val_env* ve,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Find minimum expiration interval from signatures */
|
||||||
|
static uint32_t
|
||||||
|
rrsig_min_exp_time(struct module_env* env, ldns_rr_list* rrset)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
uint32_t t, r = 15 * 24 * 3600; /* 15 days max */
|
||||||
|
for(i=0; i<ldns_rr_list_rr_count(rrset); i++) {
|
||||||
|
ldns_rr* rr = ldns_rr_list_rr(rrset, i);
|
||||||
|
if(ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG)
|
||||||
|
continue;
|
||||||
|
t = ldns_rdf2native_int32(ldns_rr_rrsig_expiration(rr));
|
||||||
|
if(t > *env->now) {
|
||||||
|
t = t - *env->now;
|
||||||
|
if(t < r)
|
||||||
|
r = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Is rr self-signed revoked key */
|
||||||
|
static int
|
||||||
|
rr_is_selfsigned_revoked(struct module_env* env, struct val_env* ve,
|
||||||
|
struct ub_packed_rrset_key* dnskey_rrset, size_t i)
|
||||||
|
{
|
||||||
|
enum sec_status sec;
|
||||||
|
sec = dnskey_verify_rrset(env, ve, dnskey_rrset, dnskey_rrset, i);
|
||||||
|
return (sec == sec_status_secure);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set fetched value */
|
||||||
|
static void
|
||||||
|
seen_trustanchor(struct autr_ta* ta, uint8_t seen)
|
||||||
|
{
|
||||||
|
ta->fetched = seen;
|
||||||
|
ta->pending_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** set revoked value */
|
||||||
|
static void
|
||||||
|
seen_revoked_trustanchor(struct autr_ta* ta, uint8_t revoked)
|
||||||
|
{
|
||||||
|
ta->revoked = revoked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare two RR buffers, skipping the REVOKED bit */
|
||||||
|
static int
|
||||||
|
ldns_rr_compare_wire_skip_revbit(ldns_buffer* rr1_buf, ldns_buffer* rr2_buf)
|
||||||
|
{
|
||||||
|
size_t rr1_len, rr2_len, min_len, i, offset;
|
||||||
|
rr1_len = ldns_buffer_capacity(rr1_buf);
|
||||||
|
rr2_len = ldns_buffer_capacity(rr2_buf);
|
||||||
|
/* jump past dname (checked in earlier part) and especially past TTL */
|
||||||
|
offset = 0;
|
||||||
|
while (offset < rr1_len && *ldns_buffer_at(rr1_buf, offset) != 0)
|
||||||
|
offset += *ldns_buffer_at(rr1_buf, offset) + 1;
|
||||||
|
/* jump to rdata section (PAST the rdata length field */
|
||||||
|
offset += 11;
|
||||||
|
min_len = (rr1_len < rr2_len) ? rr1_len : rr2_len;
|
||||||
|
/* compare RRs RDATA byte for byte. */
|
||||||
|
for(i = offset; i < min_len; i++)
|
||||||
|
{
|
||||||
|
uint8_t *rdf1, *rdf2;
|
||||||
|
rdf1 = ldns_buffer_at(rr1_buf, i);
|
||||||
|
rdf2 = ldns_buffer_at(rr2_buf, i);
|
||||||
|
if (i==(offset+1))
|
||||||
|
{
|
||||||
|
/* this is the second part of the flags field */
|
||||||
|
*rdf1 = *rdf1 | LDNS_KEY_REVOKE_KEY;
|
||||||
|
*rdf2 = *rdf2 | LDNS_KEY_REVOKE_KEY;
|
||||||
|
}
|
||||||
|
if (*rdf1 < *rdf2) return -1;
|
||||||
|
else if (*rdf1 > *rdf2) return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compare two RRs skipping the REVOKED bit */
|
||||||
|
static int
|
||||||
|
ldns_rr_compare_skip_revbit(const ldns_rr* rr1, const ldns_rr* rr2)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
size_t rr1_len, rr2_len;
|
||||||
|
ldns_buffer* rr1_buf;
|
||||||
|
ldns_buffer* rr2_buf;
|
||||||
|
|
||||||
|
result = ldns_rr_compare_no_rdata(rr1, rr2);
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
rr1_len = ldns_rr_uncompressed_size(rr1);
|
||||||
|
rr2_len = ldns_rr_uncompressed_size(rr2);
|
||||||
|
rr1_buf = ldns_buffer_new(rr1_len);
|
||||||
|
rr2_buf = ldns_buffer_new(rr2_len);
|
||||||
|
if(!rr1_buf || !rr2_buf) {
|
||||||
|
ldns_buffer_free(rr1_buf);
|
||||||
|
ldns_buffer_free(rr2_buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ldns_rr2buffer_wire_canonical(rr1_buf, rr1,
|
||||||
|
LDNS_SECTION_ANY) != LDNS_STATUS_OK)
|
||||||
|
{
|
||||||
|
ldns_buffer_free(rr1_buf);
|
||||||
|
ldns_buffer_free(rr2_buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ldns_rr2buffer_wire_canonical(rr2_buf, rr2,
|
||||||
|
LDNS_SECTION_ANY) != LDNS_STATUS_OK) {
|
||||||
|
ldns_buffer_free(rr1_buf);
|
||||||
|
ldns_buffer_free(rr2_buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
result = ldns_rr_compare_wire_skip_revbit(rr1_buf, rr2_buf);
|
||||||
|
ldns_buffer_free(rr1_buf);
|
||||||
|
ldns_buffer_free(rr2_buf);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** compare two trust anchors */
|
||||||
|
static int
|
||||||
|
ta_compare(ldns_rr* a, ldns_rr* b)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
if (!a && !b) result = 0;
|
||||||
|
else if (!a) result = -1;
|
||||||
|
else if (!b) result = 1;
|
||||||
|
else if (ldns_rr_get_type(a) != ldns_rr_get_type(b))
|
||||||
|
result = (int)ldns_rr_get_type(a) - (int)ldns_rr_get_type(b);
|
||||||
|
else if (ldns_rr_get_type(a) == LDNS_RR_TYPE_DNSKEY)
|
||||||
|
result = ldns_rr_compare_skip_revbit(a, b);
|
||||||
|
else if (ldns_rr_get_type(a) == LDNS_RR_TYPE_DS)
|
||||||
|
result = ldns_rr_compare(a, b);
|
||||||
|
else result = -1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** find key */
|
||||||
|
static struct autr_ta*
|
||||||
|
find_key(struct trust_anchor* tp, ldns_rr* rr)
|
||||||
|
{
|
||||||
|
struct autr_ta* ta;
|
||||||
|
if(!tp || !rr)
|
||||||
|
return NULL;
|
||||||
|
for(ta=tp->autr->keys; ta; ta=ta->next) {
|
||||||
|
if(ta_compare(ta->rr, rr) == 0)
|
||||||
|
return ta;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** add key and clone RR and tp already locked */
|
||||||
|
static struct autr_ta*
|
||||||
|
add_key(struct trust_anchor* tp, ldns_rr* rr)
|
||||||
|
{
|
||||||
|
ldns_rr* c;
|
||||||
|
struct autr_ta* ta;
|
||||||
|
c = ldns_rr_clone(rr);
|
||||||
|
if(!c) return NULL;
|
||||||
|
ta = autr_ta_create(c);
|
||||||
|
if(!ta) {
|
||||||
|
ldns_rr_free(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* link in, tp already locked */
|
||||||
|
ta->next = tp->autr->keys;
|
||||||
|
tp->autr->keys = ta;
|
||||||
|
return ta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** update the time values for the trustpoint */
|
||||||
|
static void
|
||||||
|
set_tp_times(struct trust_anchor* tp, uint32_t rrsig_exp_interval,
|
||||||
|
struct ub_packed_rrset_key* k)
|
||||||
|
{
|
||||||
|
struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
|
||||||
|
uint32_t origttl = d->ttl;
|
||||||
|
uint32_t x;
|
||||||
|
|
||||||
|
verbose(VERB_ALGO, "orig_ttl is %d", (int)origttl);
|
||||||
|
verbose(VERB_ALGO, "rrsig_exp_interval is %d", (int)rrsig_exp_interval);
|
||||||
|
|
||||||
|
/* x = MIN(15days, ttl/2, expire/2) */
|
||||||
|
x = 15 * 24 * 3600;
|
||||||
|
if(origttl/2 < x)
|
||||||
|
x = origttl/2;
|
||||||
|
if(rrsig_exp_interval/2 < x)
|
||||||
|
x = rrsig_exp_interval/2;
|
||||||
|
/* MAX(1hr, x) */
|
||||||
|
if(x < 3600)
|
||||||
|
tp->autr->query_interval = 3600;
|
||||||
|
else tp->autr->query_interval = x;
|
||||||
|
|
||||||
|
/* x= MIN(1day, ttl/10, expire/10) */
|
||||||
|
x = 24 * 3600;
|
||||||
|
if(origttl/10 < x)
|
||||||
|
x = origttl/10;
|
||||||
|
if(rrsig_exp_interval/10 < x)
|
||||||
|
x = rrsig_exp_interval/10;
|
||||||
|
/* MAX(1hr, x) */
|
||||||
|
if(x < 3600)
|
||||||
|
tp->autr->retry_time = 3600;
|
||||||
|
else tp->autr->retry_time = x;
|
||||||
|
|
||||||
|
verbose(VERB_ALGO, "query_interval: %d, retry_time: %d",
|
||||||
|
(int)tp->autr->query_interval, (int)tp->autr->retry_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** init events to zero */
|
||||||
|
static void
|
||||||
|
init_events(struct trust_anchor* tp)
|
||||||
|
{
|
||||||
|
struct autr_ta* ta;
|
||||||
|
for(ta=tp->autr->keys; ta; ta=ta->next) {
|
||||||
|
ta->fetched = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set update events */
|
||||||
|
static int
|
||||||
|
update_events(struct module_env* env, struct val_env* ve,
|
||||||
|
struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset)
|
||||||
|
{
|
||||||
|
ldns_rr_list* r = packed_rrset_to_rr_list(dnskey_rrset,
|
||||||
|
env->scratch_buffer);
|
||||||
|
size_t i;
|
||||||
|
if(!r)
|
||||||
|
return 0;
|
||||||
|
init_events(tp);
|
||||||
|
for(i=0; i<ldns_rr_list_rr_count(r); i++) {
|
||||||
|
ldns_rr* rr = ldns_rr_list_rr(r, i);
|
||||||
|
struct autr_ta* ta = NULL;
|
||||||
|
if(ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY)
|
||||||
|
continue;
|
||||||
|
if(!rr_is_dnskey_sep(rr))
|
||||||
|
continue;
|
||||||
|
/* is it new? if revocation bit set, find the unrevoked key */
|
||||||
|
ta = find_key(tp, rr);
|
||||||
|
if(!ta)
|
||||||
|
ta = add_key(tp, rr);
|
||||||
|
if(!ta) {
|
||||||
|
ldns_rr_list_deep_free(r);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(rr_is_dnskey_revoked(rr) &&
|
||||||
|
rr_is_selfsigned_revoked(env, ve, dnskey_rrset, i)) {
|
||||||
|
/* checked if there is an rrsig signed by this key. */
|
||||||
|
log_assert(dnskey_calc_keytag(dnskey_rrset, i) ==
|
||||||
|
ldns_calc_keytag(rr));
|
||||||
|
if(verbosity >= VERB_ALGO)
|
||||||
|
verbose(VERB_ALGO, "DNSKEY id=%d is "
|
||||||
|
"self-signed revoked", (int)
|
||||||
|
dnskey_calc_keytag(dnskey_rrset, i));
|
||||||
|
seen_revoked_trustanchor(ta, 1);
|
||||||
|
} else {
|
||||||
|
seen_trustanchor(ta, 1);
|
||||||
|
if(verbosity >= VERB_ALGO)
|
||||||
|
verbose(VERB_ALGO, "DNSKEY id=%d in DNS "
|
||||||
|
"response", (int)ldns_calc_keytag(rr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_tp_times(tp, rrsig_min_exp_time(env, r), dnskey_rrset);
|
||||||
|
ldns_rr_list_deep_free(r);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int autr_process_prime(struct module_env* env, struct val_env* ve,
|
int autr_process_prime(struct module_env* env, struct val_env* ve,
|
||||||
struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset)
|
struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset)
|
||||||
{
|
{
|
||||||
struct val_anchors* anchors = env->anchors;
|
struct val_anchors* anchors = env->anchors;
|
||||||
log_assert(tp->autr);
|
log_assert(tp->autr);
|
||||||
/* autotrust update trust anchors */
|
/* autotrust update trust anchors */
|
||||||
/* note: tp is locked */
|
/* the tp is locked, and stays locked unless it is deleted */
|
||||||
|
|
||||||
/* query_dnskeys(): */
|
/* query_dnskeys(): */
|
||||||
tp->autr->last_queried = *env->now;
|
tp->autr->last_queried = *env->now;
|
||||||
|
|
@ -613,7 +916,8 @@ int autr_process_prime(struct module_env* env, struct val_env* ve,
|
||||||
* - note revoked (selfsigned) anchors.
|
* - note revoked (selfsigned) anchors.
|
||||||
* Set trustpoint query_interval and retry_time.
|
* Set trustpoint query_interval and retry_time.
|
||||||
*/
|
*/
|
||||||
/* update_events(env, ve, tp, dnskey_rrset); */
|
if(!update_events(env, ve, tp, dnskey_rrset))
|
||||||
|
return 1; /* trust point unchanged, so exists */
|
||||||
|
|
||||||
/* do_statetable():
|
/* do_statetable():
|
||||||
* - for every SEP key do the 5011 statetable.
|
* - for every SEP key do the 5011 statetable.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue