mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-21 07:10:43 -05:00
revoke point handling
git-svn-id: file:///svn/unbound/trunk@1777 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
7d90b75ce8
commit
b8a2dfb2c9
6 changed files with 86 additions and 13 deletions
|
|
@ -176,7 +176,7 @@ daemon_init()
|
||||||
#endif
|
#endif
|
||||||
OpenSSL_add_all_algorithms();
|
OpenSSL_add_all_algorithms();
|
||||||
/* grab the COMP method ptr because openssl leaks it */
|
/* grab the COMP method ptr because openssl leaks it */
|
||||||
comp_meth = SSL_COMP_get_compression_methods();
|
comp_meth = (void*)SSL_COMP_get_compression_methods();
|
||||||
(void)SSL_library_init();
|
(void)SSL_library_init();
|
||||||
#ifdef HAVE_TZSET
|
#ifdef HAVE_TZSET
|
||||||
/* init timezone info while we are not chrooted yet */
|
/* init timezone info while we are not chrooted yet */
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
- fixup memleak in trust anchor unsupported algorithm check.
|
- fixup memleak in trust anchor unsupported algorithm check.
|
||||||
- iana portlist updated.
|
- iana portlist updated.
|
||||||
- autotrust options: add-holddown, del-holddown, keep-missing.
|
- autotrust options: add-holddown, del-holddown, keep-missing.
|
||||||
|
- autotrust store revoked status of trust points.
|
||||||
|
|
||||||
24 August 2009: Wouter
|
24 August 2009: Wouter
|
||||||
- cleaner memory allocation on exit. autotrust test routines.
|
- cleaner memory allocation on exit. autotrust test routines.
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
#include "util/module.h"
|
#include "util/module.h"
|
||||||
#include "util/net_help.h"
|
#include "util/net_help.h"
|
||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
|
#include "util/regional.h"
|
||||||
|
|
||||||
/** number of times a key must be seen before it can become valid */
|
/** number of times a key must be seen before it can become valid */
|
||||||
#define MIN_PENDINGCOUNT 2
|
#define MIN_PENDINGCOUNT 2
|
||||||
|
|
@ -599,6 +600,7 @@ parse_id(struct val_anchors* anchors, char* line)
|
||||||
* @param anchor: the anchor as result value or previously returned anchor
|
* @param anchor: the anchor as result value or previously returned anchor
|
||||||
* value to read the variable lines into.
|
* value to read the variable lines into.
|
||||||
* @return: 0 no match, -1 failed syntax error, +1 success line read.
|
* @return: 0 no match, -1 failed syntax error, +1 success line read.
|
||||||
|
* +2 revoked trust anchor file.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
parse_var_line(char* line, struct val_anchors* anchors,
|
parse_var_line(char* line, struct val_anchors* anchors,
|
||||||
|
|
@ -610,6 +612,12 @@ parse_var_line(char* line, struct val_anchors* anchors,
|
||||||
*anchor = parse_id(anchors, line+6);
|
*anchor = parse_id(anchors, line+6);
|
||||||
if(!*anchor) return -1;
|
if(!*anchor) return -1;
|
||||||
else return 1;
|
else return 1;
|
||||||
|
} else if(strncmp(line, ";;REVOKED", 9) == 0) {
|
||||||
|
if(tp) {
|
||||||
|
log_err("REVOKED statement must be at start of file");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
} else if(strncmp(line, ";;last_queried: ", 16) == 0) {
|
} else if(strncmp(line, ";;last_queried: ", 16) == 0) {
|
||||||
if(!tp) return -1;
|
if(!tp) return -1;
|
||||||
lock_basic_lock(&tp->lock);
|
lock_basic_lock(&tp->lock);
|
||||||
|
|
@ -663,7 +671,6 @@ int autr_read_file(struct val_anchors* anchors, const char* nm)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
verbose(VERB_ALGO, "reading autotrust anchor file %s", nm);
|
verbose(VERB_ALGO, "reading autotrust anchor file %s", nm);
|
||||||
/* TODO: read line to see if special marker for revoked tp */
|
|
||||||
while (fgets(line, (int)sizeof(line), fd) != NULL) {
|
while (fgets(line, (int)sizeof(line), fd) != NULL) {
|
||||||
line_nr++;
|
line_nr++;
|
||||||
if((r = parse_var_line(line, anchors, &tp)) == -1) {
|
if((r = parse_var_line(line, anchors, &tp)) == -1) {
|
||||||
|
|
@ -672,6 +679,10 @@ int autr_read_file(struct val_anchors* anchors, const char* nm)
|
||||||
return 0;
|
return 0;
|
||||||
} else if(r == 1) {
|
} else if(r == 1) {
|
||||||
continue;
|
continue;
|
||||||
|
} else if(r == 2) {
|
||||||
|
log_warn("trust anchor %s has been revoked", nm);
|
||||||
|
fclose(fd);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
if (!str_contains_data(line, ';'))
|
if (!str_contains_data(line, ';'))
|
||||||
continue; /* empty lines allowed */
|
continue; /* empty lines allowed */
|
||||||
|
|
@ -757,6 +768,14 @@ void autr_write_file(struct module_env* env, struct trust_anchor* tp)
|
||||||
}
|
}
|
||||||
/* write pretty header */
|
/* write pretty header */
|
||||||
fprintf(out, "; autotrust trust anchor file\n");
|
fprintf(out, "; autotrust trust anchor file\n");
|
||||||
|
if(tp->autr->revoked) {
|
||||||
|
fprintf(out, ";;REVOKED\n");
|
||||||
|
fprintf(out, "; The zone has all keys revoked, and is\n"
|
||||||
|
"; considered as if it has no trust anchors.\n"
|
||||||
|
"; the remainder of the file is the last probe.\n"
|
||||||
|
"; to restart the trust anchor, overwrite this file.\n"
|
||||||
|
"; with one containing valid DNSKEYs or DSes.\n");
|
||||||
|
}
|
||||||
print_id(out, env, tp->name, tp->namelen, tp->dclass);
|
print_id(out, env, tp->name, tp->namelen, tp->dclass);
|
||||||
fprintf(out, ";;last_queried: %u ;;%s",
|
fprintf(out, ";;last_queried: %u ;;%s",
|
||||||
(unsigned int)tp->autr->last_queried,
|
(unsigned int)tp->autr->last_queried,
|
||||||
|
|
@ -771,9 +790,6 @@ void autr_write_file(struct module_env* env, struct trust_anchor* tp)
|
||||||
fprintf(out, ";;query_interval: %d\n", (int)tp->autr->query_interval);
|
fprintf(out, ";;query_interval: %d\n", (int)tp->autr->query_interval);
|
||||||
fprintf(out, ";;retry_time: %d\n", (int)tp->autr->retry_time);
|
fprintf(out, ";;retry_time: %d\n", (int)tp->autr->retry_time);
|
||||||
|
|
||||||
/* write revoked tp special marker */
|
|
||||||
/* TODO */
|
|
||||||
|
|
||||||
/* write anchors */
|
/* write anchors */
|
||||||
for(ta=tp->autr->keys; ta; ta=ta->next) {
|
for(ta=tp->autr->keys; ta; ta=ta->next) {
|
||||||
char* str;
|
char* str;
|
||||||
|
|
@ -1399,6 +1415,36 @@ autr_cleanup_keys(struct trust_anchor* tp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Delete trust point that was revoked */
|
||||||
|
static void
|
||||||
|
autr_tp_remove(struct module_env* env, struct trust_anchor* tp)
|
||||||
|
{
|
||||||
|
struct trust_anchor key;
|
||||||
|
/* save name */
|
||||||
|
memset(&key, 0, sizeof(key));
|
||||||
|
key.node.key = &key;
|
||||||
|
key.name = regional_alloc_init(env->scratch, tp->name, tp->namelen);
|
||||||
|
if(!key.name) {
|
||||||
|
log_err("out of scratch memory in trust point delete");
|
||||||
|
/* the revoked=1 flag on it saves the day, but wastes memory */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
key.namelen = tp->namelen;
|
||||||
|
key.namelabs = tp->namelabs;
|
||||||
|
key.dclass = tp->dclass;
|
||||||
|
|
||||||
|
/* unlock */
|
||||||
|
lock_basic_unlock(&tp->lock);
|
||||||
|
|
||||||
|
/* take from tree. It could be deleted by someone else. */
|
||||||
|
lock_basic_lock(&env->anchors->lock);
|
||||||
|
(void)rbtree_delete(env->anchors->tree, &key);
|
||||||
|
anchors_init_parents_locked(env->anchors);
|
||||||
|
lock_basic_unlock(&env->anchors->lock);
|
||||||
|
/* delete */
|
||||||
|
autr_point_delete(tp);
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
@ -1407,7 +1453,15 @@ int autr_process_prime(struct module_env* env, struct val_env* ve,
|
||||||
/* autotrust update trust anchors */
|
/* autotrust update trust anchors */
|
||||||
/* the tp is locked, and stays locked unless it is deleted */
|
/* the tp is locked, and stays locked unless it is deleted */
|
||||||
|
|
||||||
/* TODO: check if marked as revoked, if so, unlock and return */
|
/* we could just catch the anchor here while another thread
|
||||||
|
* is busy deleting it. Just unlock and let the other do its job */
|
||||||
|
if(tp->autr->revoked) {
|
||||||
|
log_nametypeclass(VERB_ALGO, "autotrust not processed, "
|
||||||
|
"trust point revoked", tp->name,
|
||||||
|
LDNS_RR_TYPE_DNSKEY, tp->dclass);
|
||||||
|
lock_basic_unlock(&tp->lock);
|
||||||
|
return 0; /* it is revoked */
|
||||||
|
}
|
||||||
|
|
||||||
/* query_dnskeys(): */
|
/* query_dnskeys(): */
|
||||||
tp->autr->last_queried = *env->now;
|
tp->autr->last_queried = *env->now;
|
||||||
|
|
@ -1460,9 +1514,8 @@ int autr_process_prime(struct module_env* env, struct val_env* ve,
|
||||||
}
|
}
|
||||||
if(!tp->ds_rrset && !tp->dnskey_rrset) {
|
if(!tp->ds_rrset && !tp->dnskey_rrset) {
|
||||||
/* no more keys, all are revoked */
|
/* no more keys, all are revoked */
|
||||||
/* TODO: delete trust point:
|
tp->autr->revoked = 1;
|
||||||
* mark as revoked trust point.
|
autr_tp_remove(env, tp);
|
||||||
* save name, unlock, take from tree, delete. */
|
|
||||||
return 0; /* trust point removed */
|
return 0; /* trust point removed */
|
||||||
}
|
}
|
||||||
} else verbose(VERB_ALGO, "autotrust: no changes");
|
} else verbose(VERB_ALGO, "autotrust: no changes");
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ struct autr_ta {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Autotrust metadata for a trust point.
|
* Autotrust metadata for a trust point.
|
||||||
|
* This is part of the struct trust_anchor data.
|
||||||
*/
|
*/
|
||||||
struct autr_point_data {
|
struct autr_point_data {
|
||||||
/** file to store the trust point in. chrootdir already applied. */
|
/** file to store the trust point in. chrootdir already applied. */
|
||||||
|
|
@ -104,6 +105,8 @@ struct autr_point_data {
|
||||||
|
|
||||||
/** how many times did it fail */
|
/** how many times did it fail */
|
||||||
uint8_t query_failed;
|
uint8_t query_failed;
|
||||||
|
/** true if the trust point has been revoked */
|
||||||
|
uint8_t revoked;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -120,15 +120,13 @@ anchors_delete(struct val_anchors* anchors)
|
||||||
free(anchors);
|
free(anchors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** initialise parent pointers in the tree */
|
void
|
||||||
static void
|
anchors_init_parents_locked(struct val_anchors* anchors)
|
||||||
init_parents(struct val_anchors* anchors)
|
|
||||||
{
|
{
|
||||||
struct trust_anchor* node, *prev = NULL, *p;
|
struct trust_anchor* node, *prev = NULL, *p;
|
||||||
int m;
|
int m;
|
||||||
/* nobody else can grab locks because we hold the main lock.
|
/* nobody else can grab locks because we hold the main lock.
|
||||||
* Thus the previous items, after unlocked, are not deleted */
|
* Thus the previous items, after unlocked, are not deleted */
|
||||||
lock_basic_lock(&anchors->lock);
|
|
||||||
RBTREE_FOR(node, struct trust_anchor*, anchors->tree) {
|
RBTREE_FOR(node, struct trust_anchor*, anchors->tree) {
|
||||||
lock_basic_lock(&node->lock);
|
lock_basic_lock(&node->lock);
|
||||||
node->parent = NULL;
|
node->parent = NULL;
|
||||||
|
|
@ -153,6 +151,14 @@ init_parents(struct val_anchors* anchors)
|
||||||
lock_basic_unlock(&node->lock);
|
lock_basic_unlock(&node->lock);
|
||||||
prev = node;
|
prev = node;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** initialise parent pointers in the tree */
|
||||||
|
static void
|
||||||
|
init_parents(struct val_anchors* anchors)
|
||||||
|
{
|
||||||
|
lock_basic_lock(&anchors->lock);
|
||||||
|
anchors_init_parents_locked(anchors);
|
||||||
lock_basic_unlock(&anchors->lock);
|
lock_basic_unlock(&anchors->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,16 @@ void anchors_delete(struct val_anchors* anchors);
|
||||||
*/
|
*/
|
||||||
int anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg);
|
int anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recalculate parent pointers. The caller must hold the lock on the
|
||||||
|
* anchors structure (say after removing an item from the rbtree).
|
||||||
|
* Caller must not hold any locks on trust anchors.
|
||||||
|
* After the call is complete the parent pointers are updated and an item
|
||||||
|
* just removed is no longer referenced in parent pointers.
|
||||||
|
* @param anchors: the structure to update.
|
||||||
|
*/
|
||||||
|
void anchors_init_parents_locked(struct val_anchors* anchors);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a qname/qclass combination, find the trust anchor closest above it.
|
* Given a qname/qclass combination, find the trust anchor closest above it.
|
||||||
* Or return NULL if none exists.
|
* Or return NULL if none exists.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue