update unbound from upstream

This commit is contained in:
Riccardo Spagni
2015-04-02 11:16:18 +02:00
parent b0151de601
commit 1f49833d4f
155 changed files with 5482 additions and 3440 deletions

View File

@@ -57,11 +57,11 @@
#include "services/mesh.h"
#include "services/cache/rrset.h"
#include "validator/val_kcache.h"
#include "ldns/sbuffer.h"
#include "ldns/wire2str.h"
#include "ldns/str2wire.h"
#include "ldns/keyraw.h"
#include "ldns/rrdef.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "sldns/str2wire.h"
#include "sldns/keyraw.h"
#include "sldns/rrdef.h"
#include <stdarg.h>
#include <ctype.h>

View File

@@ -48,9 +48,9 @@
#include "util/log.h"
#include "util/net_help.h"
#include "util/config_file.h"
#include "ldns/sbuffer.h"
#include "ldns/rrdef.h"
#include "ldns/str2wire.h"
#include "sldns/sbuffer.h"
#include "sldns/rrdef.h"
#include "sldns/str2wire.h"
#ifdef HAVE_GLOB_H
#include <glob.h>
#endif
@@ -882,14 +882,14 @@ assemble_it(struct trust_anchor* ta, size_t num, uint16_t type)
memset(pd, 0, sizeof(*pd));
pd->count = num;
pd->trust = rrset_trust_ultimate;
pd->rr_len = (size_t*)malloc(num*sizeof(size_t));
pd->rr_len = (size_t*)reallocarray(NULL, num, sizeof(size_t));
if(!pd->rr_len) {
free(pd);
free(pkey->rk.dname);
free(pkey);
return NULL;
}
pd->rr_ttl = (time_t*)malloc(num*sizeof(time_t));
pd->rr_ttl = (time_t*)reallocarray(NULL, num, sizeof(time_t));
if(!pd->rr_ttl) {
free(pd->rr_len);
free(pd);
@@ -897,7 +897,7 @@ assemble_it(struct trust_anchor* ta, size_t num, uint16_t type)
free(pkey);
return NULL;
}
pd->rr_data = (uint8_t**)malloc(num*sizeof(uint8_t*));
pd->rr_data = (uint8_t**)reallocarray(NULL, num, sizeof(uint8_t*));
if(!pd->rr_data) {
free(pd->rr_ttl);
free(pd->rr_len);
@@ -1020,7 +1020,13 @@ anchors_assemble_rrsets(struct val_anchors* anchors)
dname_str(ta->name, b);
log_warn("trust anchor %s has no supported algorithms,"
" the anchor is ignored (check if you need to"
" upgrade unbound and openssl)", b);
" upgrade unbound and "
#ifdef HAVE_LIBRESSL
"libressl"
#else
"openssl"
#endif
")", b);
(void)rbtree_delete(anchors->tree, &ta->node);
lock_basic_unlock(&ta->lock);
anchors_delfunc(&ta->node, NULL);

View File

@@ -45,8 +45,8 @@
#include "util/storage/lookup3.h"
#include "util/regional.h"
#include "util/net_help.h"
#include "ldns/rrdef.h"
#include "ldns/keyraw.h"
#include "sldns/rrdef.h"
#include "sldns/keyraw.h"
size_t
key_entry_sizefunc(void* key, void* data)

View File

@@ -59,8 +59,8 @@
#include "util/config_file.h"
#include "services/cache/rrset.h"
#include "services/cache/dns.h"
#include "ldns/rrdef.h"
#include "ldns/sbuffer.h"
#include "sldns/rrdef.h"
#include "sldns/sbuffer.h"
int val_neg_data_compare(const void* a, const void* b)
{

View File

@@ -62,7 +62,7 @@
#include "util/data/msgreply.h"
/* we include nsec.h for the bitmap_has_type function */
#include "validator/val_nsec.h"
#include "ldns/sbuffer.h"
#include "sldns/sbuffer.h"
/**
* This function we get from ldns-compat or from base system

View File

@@ -41,12 +41,13 @@
* and do the library calls (for the crypto library in use).
*/
#include "config.h"
#include "validator/val_secalgo.h"
/* packed_rrset on top to define enum types (forced by c99 standard) */
#include "util/data/packed_rrset.h"
#include "validator/val_secalgo.h"
#include "util/log.h"
#include "ldns/rrdef.h"
#include "ldns/keyraw.h"
#include "ldns/sbuffer.h"
#include "sldns/rrdef.h"
#include "sldns/keyraw.h"
#include "sldns/sbuffer.h"
#if !defined(HAVE_SSL) && !defined(HAVE_NSS)
#error "Need crypto library to do digital signature cryptography"

View File

@@ -51,10 +51,10 @@
#include "util/module.h"
#include "util/net_help.h"
#include "util/regional.h"
#include "ldns/keyraw.h"
#include "ldns/sbuffer.h"
#include "ldns/parseutil.h"
#include "ldns/wire2str.h"
#include "sldns/keyraw.h"
#include "sldns/sbuffer.h"
#include "sldns/parseutil.h"
#include "sldns/wire2str.h"
#include <ctype.h>
#if !defined(HAVE_SSL) && !defined(HAVE_NSS)
@@ -1079,6 +1079,8 @@ int rrset_canonical_equal(struct regional* region,
fd.rr_data = fdata;
rbtree_init(&sortree1, &canonical_tree_compare);
rbtree_init(&sortree2, &canonical_tree_compare);
if(d1->count > RR_COUNT_MAX || d2->count > RR_COUNT_MAX)
return 1; /* protection against integer overflow */
rrs1 = regional_alloc(region, sizeof(struct canon_rr)*d1->count);
rrs2 = regional_alloc(region, sizeof(struct canon_rr)*d2->count);
if(!rrs1 || !rrs2) return 1; /* alloc failure */
@@ -1135,6 +1137,8 @@ rrset_canonical(struct regional* region, sldns_buffer* buf,
sizeof(rbtree_t));
if(!*sortree)
return 0;
if(d->count > RR_COUNT_MAX)
return 0; /* integer overflow protection */
rrs = regional_alloc(region, sizeof(struct canon_rr)*d->count);
if(!rrs) {
*sortree = NULL;

View File

@@ -846,6 +846,18 @@ val_fill_reply(struct reply_info* chase, struct reply_info* orig,
chase->ar_numrrsets;
}
void val_reply_remove_auth(struct reply_info* rep, size_t index)
{
log_assert(index < rep->rrset_count);
log_assert(index >= rep->an_numrrsets);
log_assert(index < rep->an_numrrsets+rep->ns_numrrsets);
memmove(rep->rrsets+index, rep->rrsets+index+1,
sizeof(struct ub_packed_rrset_key*)*
(rep->rrset_count - index - 1));
rep->ns_numrrsets--;
rep->rrset_count--;
}
void
val_check_nonsecure(struct val_env* ve, struct reply_info* rep)
{

View File

@@ -294,6 +294,13 @@ int val_chase_cname(struct query_info* qchase, struct reply_info* rep,
void val_fill_reply(struct reply_info* chase, struct reply_info* orig,
size_t cname_skip, uint8_t* name, size_t len, uint8_t* signer);
/**
* Remove rrset with index from reply, from the authority section.
* @param rep: reply to remove it from.
* @param index: rrset to remove, must be in the authority section.
*/
void val_reply_remove_auth(struct reply_info* rep, size_t index);
/**
* Remove all unsigned or non-secure status rrsets from NS and AR sections.
* So that unsigned data does not get let through to clients, when we have

View File

@@ -58,8 +58,8 @@
#include "util/regional.h"
#include "util/config_file.h"
#include "util/fptr_wlist.h"
#include "ldns/rrdef.h"
#include "ldns/wire2str.h"
#include "sldns/rrdef.h"
#include "sldns/wire2str.h"
/* forward decl for cache response and normal super inform calls of a DS */
static void process_ds_response(struct module_qstate* qstate,
@@ -226,6 +226,8 @@ val_new_getmsg(struct module_qstate* qstate, struct val_qstate* vq)
sizeof(struct reply_info) - sizeof(struct rrset_ref));
if(!vq->chase_reply)
return NULL;
if(vq->orig_msg->rep->rrset_count > RR_COUNT_MAX)
return NULL; /* protect against integer overflow */
vq->chase_reply->rrsets = regional_alloc_init(qstate->region,
vq->orig_msg->rep->rrsets, sizeof(struct ub_packed_rrset_key*)
* vq->orig_msg->rep->rrset_count);
@@ -574,6 +576,61 @@ detect_wrongly_truncated(struct reply_info* rep)
return 1;
}
/**
* For messages that are not referrals, if the chase reply contains an
* unsigned NS record in the authority section it could have been
* inserted by a (BIND) forwarder that thinks the zone is insecure, and
* that has an NS record without signatures in cache. Remove the NS
* record since the reply does not hinge on that record (in the authority
* section), but do not remove it if it removes the last record from the
* answer+authority sections.
* @param chase_reply: the chased reply, we have a key for this contents,
* so we should have signatures for these rrsets and not having
* signatures means it will be bogus.
* @param orig_reply: original reply, remove NS from there as well because
* we cannot mark the NS record as DNSSEC valid because it is not
* validated by signatures.
*/
static void
remove_spurious_authority(struct reply_info* chase_reply,
struct reply_info* orig_reply)
{
size_t i, found = 0;
int remove = 0;
/* if no answer and only 1 auth RRset, do not remove that one */
if(chase_reply->an_numrrsets == 0 && chase_reply->ns_numrrsets == 1)
return;
/* search authority section for unsigned NS records */
for(i = chase_reply->an_numrrsets;
i < chase_reply->an_numrrsets+chase_reply->ns_numrrsets; i++) {
struct packed_rrset_data* d = (struct packed_rrset_data*)
chase_reply->rrsets[i]->entry.data;
if(ntohs(chase_reply->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS
&& d->rrsig_count == 0) {
found = i;
remove = 1;
break;
}
}
/* see if we found the entry */
if(!remove) return;
log_rrset_key(VERB_ALGO, "Removing spurious unsigned NS record "
"(likely inserted by forwarder)", chase_reply->rrsets[found]);
/* find rrset in orig_reply */
for(i = orig_reply->an_numrrsets;
i < orig_reply->an_numrrsets+orig_reply->ns_numrrsets; i++) {
if(ntohs(orig_reply->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS
&& query_dname_compare(orig_reply->rrsets[i]->rk.dname,
chase_reply->rrsets[found]->rk.dname) == 0) {
/* remove from orig_msg */
val_reply_remove_auth(orig_reply, i);
break;
}
}
/* remove rrset from chase_reply */
val_reply_remove_auth(chase_reply, found);
}
/**
* Given a "positive" response -- a response that contains an answer to the
@@ -1642,6 +1699,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
}
subtype = val_classify_response(qstate->query_flags, &qstate->qinfo,
&vq->qchase, vq->orig_msg->rep, vq->rrset_skip);
if(subtype != VAL_CLASS_REFERRAL)
remove_spurious_authority(vq->chase_reply, vq->orig_msg->rep);
/* check signatures in the message;
* answer and authority must be valid, additional is only checked. */
@@ -2295,7 +2354,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
struct key_entry_key* kkey = NULL;
enum sec_status sec = sec_status_unchecked;
char* reason = NULL;
int downprot = 1;
int downprot = qstate->env->cfg->harden_algo_downgrade;
if(!dnskey_rrset) {
log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- "