mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- Made new validator error string available from libunbound for
applications. It is in result->why_bogus, a zero-terminated string. unbound-host prints it by default if a result is bogus. Also the errinf is public in module_qstate (for other modules). Binary API different. bumped library ABI version. git-svn-id: file:///svn/unbound/trunk@1874 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
d7868e4077
commit
f42d27e1a2
23 changed files with 329 additions and 272 deletions
31
configure
vendored
31
configure
vendored
|
|
@ -2108,7 +2108,8 @@ LIBUNBOUND_AGE=0
|
|||
# 1.3.2 had 1:2:0
|
||||
# 1.3.3 had 1:3:0
|
||||
# 1.3.4 had 1:4:0
|
||||
# 1.4.0 had 1:5:0
|
||||
# 1.4.0-snapshots had 1:5:0
|
||||
# 1.4.0 had 2:0:0 # ub_result.why_bogus
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
|
|
@ -7279,13 +7280,13 @@ if test "${lt_cv_nm_interface+set}" = set; then
|
|||
else
|
||||
lt_cv_nm_interface="BSD nm"
|
||||
echo "int some_variable = 0;" > conftest.$ac_ext
|
||||
(eval echo "\"\$as_me:7282: $ac_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7283: $ac_compile\"" >&5)
|
||||
(eval "$ac_compile" 2>conftest.err)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:7285: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval echo "\"\$as_me:7286: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:7288: output\"" >&5)
|
||||
(eval echo "\"\$as_me:7289: output\"" >&5)
|
||||
cat conftest.out >&5
|
||||
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
|
||||
lt_cv_nm_interface="MS dumpbin"
|
||||
|
|
@ -8490,7 +8491,7 @@ ia64-*-hpux*)
|
|||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 8493 "configure"' > conftest.$ac_ext
|
||||
echo '#line 8494 "configure"' > conftest.$ac_ext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
|
|
@ -9857,11 +9858,11 @@ else
|
|||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:9860: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:9861: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:9864: \$? = $ac_status" >&5
|
||||
echo "$as_me:9865: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
|
|
@ -10196,11 +10197,11 @@ else
|
|||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:10199: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:10200: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:10203: \$? = $ac_status" >&5
|
||||
echo "$as_me:10204: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
|
|
@ -10301,11 +10302,11 @@ else
|
|||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:10304: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:10305: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:10308: \$? = $ac_status" >&5
|
||||
echo "$as_me:10309: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
|
|
@ -10356,11 +10357,11 @@ else
|
|||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:10359: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:10360: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:10363: \$? = $ac_status" >&5
|
||||
echo "$as_me:10364: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
|
|
@ -13159,7 +13160,7 @@ else
|
|||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 13162 "configure"
|
||||
#line 13163 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
|
|
@ -13255,7 +13256,7 @@ else
|
|||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 13258 "configure"
|
||||
#line 13259 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ LIBUNBOUND_AGE=0
|
|||
# 1.3.2 had 1:2:0
|
||||
# 1.3.3 had 1:3:0
|
||||
# 1.3.4 had 1:4:0
|
||||
# 1.4.0 had 1:5:0
|
||||
# 1.4.0-snapshots had 1:5:0
|
||||
# 1.4.0 had 2:0:0 # ub_result.why_bogus
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
|
|
|
|||
|
|
@ -1281,13 +1281,15 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
|
|||
}
|
||||
|
||||
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s))
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s))
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@
|
|||
- more detail to errors from insecure delegation checks.
|
||||
- Fix double time subtraction in negative cache reported by
|
||||
Amanda Constant and Hugh Mahon.
|
||||
- Made new validator error string available from libunbound for
|
||||
applications. It is in result->why_bogus, a zero-terminated string.
|
||||
unbound-host prints it by default if a result is bogus.
|
||||
Also the errinf is public in module_qstate (for other modules).
|
||||
|
||||
7 October 2009: Wouter
|
||||
- retry for validation failure in DS and prime results. Less mem use.
|
||||
|
|
|
|||
|
|
@ -351,6 +351,7 @@ The result of the DNS resolution and validation is returned as
|
|||
int nxdomain; /* true if nodata because name does not exist */
|
||||
int secure; /* true if result is secure */
|
||||
int bogus; /* true if a security failure happened */
|
||||
char* why_bogus; /* string with error if bogus */
|
||||
};
|
||||
.fi
|
||||
.P
|
||||
|
|
|
|||
|
|
@ -288,20 +288,27 @@ context_serialize_answer(struct ctx_query* q, int err, ldns_buffer* pkt,
|
|||
* o uint32 id
|
||||
* o uint32 error_code
|
||||
* o uint32 msg_security
|
||||
* o uint32 length of why_bogus string (+1 for eos); 0 absent.
|
||||
* o why_bogus_string
|
||||
* o the remainder is the answer msg from resolver lookup.
|
||||
* remainder can be length 0.
|
||||
*/
|
||||
size_t pkt_len = pkt?ldns_buffer_remaining(pkt):0;
|
||||
size_t wlen = (pkt&&q->res->why_bogus)?strlen(q->res->why_bogus)+1:0;
|
||||
uint8_t* p;
|
||||
*len = sizeof(uint32_t)*4 + pkt_len;
|
||||
*len = sizeof(uint32_t)*5 + pkt_len + wlen;
|
||||
p = (uint8_t*)malloc(*len);
|
||||
if(!p) return NULL;
|
||||
ldns_write_uint32(p, UB_LIBCMD_ANSWER);
|
||||
ldns_write_uint32(p+sizeof(uint32_t), (uint32_t)q->querynum);
|
||||
ldns_write_uint32(p+2*sizeof(uint32_t), (uint32_t)err);
|
||||
ldns_write_uint32(p+3*sizeof(uint32_t), (uint32_t)q->msg_security);
|
||||
ldns_write_uint32(p+4*sizeof(uint32_t), (uint32_t)wlen);
|
||||
if(wlen > 0)
|
||||
memmove(p+5*sizeof(uint32_t), q->res->why_bogus, wlen);
|
||||
if(pkt_len > 0)
|
||||
memmove(p+4*sizeof(uint32_t), ldns_buffer_begin(pkt), pkt_len);
|
||||
memmove(p+5*sizeof(uint32_t)+wlen,
|
||||
ldns_buffer_begin(pkt), pkt_len);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
@ -311,16 +318,31 @@ context_deserialize_answer(struct ub_ctx* ctx,
|
|||
{
|
||||
struct ctx_query* q = NULL ;
|
||||
int id;
|
||||
if(len < 4*sizeof(uint32_t)) return NULL;
|
||||
size_t wlen;
|
||||
if(len < 5*sizeof(uint32_t)) return NULL;
|
||||
log_assert( ldns_read_uint32(p) == UB_LIBCMD_ANSWER);
|
||||
id = (int)ldns_read_uint32(p+sizeof(uint32_t));
|
||||
q = (struct ctx_query*)rbtree_search(&ctx->queries, &id);
|
||||
if(!q) return NULL;
|
||||
*err = (int)ldns_read_uint32(p+2*sizeof(uint32_t));
|
||||
q->msg_security = ldns_read_uint32(p+3*sizeof(uint32_t));
|
||||
if(len > 4*sizeof(uint32_t)) {
|
||||
q->msg_len = len - 4*sizeof(uint32_t);
|
||||
q->msg = (uint8_t*)memdup(p+4*sizeof(uint32_t), q->msg_len);
|
||||
wlen = (size_t)ldns_read_uint32(p+4*sizeof(uint32_t));
|
||||
if(len > 5*sizeof(uint32_t) && wlen > 0) {
|
||||
if(len >= 5*sizeof(uint32_t)+wlen)
|
||||
q->res->why_bogus = (char*)memdup(
|
||||
p+5*sizeof(uint32_t), wlen);
|
||||
if(!q->res->why_bogus) {
|
||||
/* pass malloc failure to the user callback */
|
||||
q->msg_len = 0;
|
||||
*err = UB_NOMEM;
|
||||
return q;
|
||||
}
|
||||
q->res->why_bogus[wlen-1] = 0; /* zero terminated for sure */
|
||||
}
|
||||
if(len > 5*sizeof(uint32_t)+wlen) {
|
||||
q->msg_len = len - 5*sizeof(uint32_t) - wlen;
|
||||
q->msg = (uint8_t*)memdup(p+5*sizeof(uint32_t)+wlen,
|
||||
q->msg_len);
|
||||
if(!q->msg) {
|
||||
/* pass malloc failure to the user callback */
|
||||
q->msg_len = 0;
|
||||
|
|
|
|||
|
|
@ -691,6 +691,7 @@ ub_resolve_free(struct ub_result* result)
|
|||
free(result->data);
|
||||
free(result->len);
|
||||
free(result->answer_packet);
|
||||
free(result->why_bogus);
|
||||
free(result);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -438,8 +438,10 @@ libworker_enter_result(struct ub_result* res, ldns_buffer* buf,
|
|||
/** fillup fg results */
|
||||
static void
|
||||
libworker_fillup_fg(struct ctx_query* q, int rcode, ldns_buffer* buf,
|
||||
enum sec_status s)
|
||||
enum sec_status s, char* why_bogus)
|
||||
{
|
||||
if(why_bogus)
|
||||
q->res->why_bogus = strdup(why_bogus);
|
||||
if(rcode != 0) {
|
||||
q->res->rcode = rcode;
|
||||
q->msg_security = s;
|
||||
|
|
@ -460,13 +462,14 @@ libworker_fillup_fg(struct ctx_query* q, int rcode, ldns_buffer* buf,
|
|||
}
|
||||
|
||||
void
|
||||
libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s)
|
||||
libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s,
|
||||
char* why_bogus)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
/* fg query is done; exit comm base */
|
||||
comm_base_exit(q->w->base);
|
||||
|
||||
libworker_fillup_fg(q, rcode, buf, s);
|
||||
libworker_fillup_fg(q, rcode, buf, s, why_bogus);
|
||||
}
|
||||
|
||||
/** setup qinfo and edns */
|
||||
|
|
@ -517,7 +520,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
|||
w->back->udp_buff, w->env->scratch)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure);
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
libworker_delete(w);
|
||||
free(qinfo.qname);
|
||||
return UB_NOERROR;
|
||||
|
|
@ -540,7 +543,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
|||
/** add result to the bg worker result queue */
|
||||
static void
|
||||
add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt,
|
||||
int err)
|
||||
int err, char* reason)
|
||||
{
|
||||
uint8_t* msg = NULL;
|
||||
uint32_t len = 0;
|
||||
|
|
@ -548,6 +551,8 @@ add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt,
|
|||
/* serialize and delete unneeded q */
|
||||
if(w->is_bg_thread) {
|
||||
lock_basic_lock(&w->ctx->cfglock);
|
||||
if(reason)
|
||||
q->res->why_bogus = strdup(reason);
|
||||
if(pkt) {
|
||||
q->msg_len = ldns_buffer_remaining(pkt);
|
||||
q->msg = memdup(ldns_buffer_begin(pkt), q->msg_len);
|
||||
|
|
@ -559,6 +564,8 @@ add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt,
|
|||
} else msg = context_serialize_answer(q, err, NULL, &len);
|
||||
lock_basic_unlock(&w->ctx->cfglock);
|
||||
} else {
|
||||
if(reason)
|
||||
q->res->why_bogus = strdup(reason);
|
||||
msg = context_serialize_answer(q, err, pkt, &len);
|
||||
(void)rbtree_delete(&w->ctx->queries, q->node.key);
|
||||
w->ctx->num_async--;
|
||||
|
|
@ -576,7 +583,8 @@ add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt,
|
|||
}
|
||||
|
||||
void
|
||||
libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s)
|
||||
libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s,
|
||||
char* why_bogus)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
|
||||
|
|
@ -597,7 +605,7 @@ libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s)
|
|||
if(rcode != 0) {
|
||||
error_encode(buf, rcode, NULL, 0, BIT_RD, NULL);
|
||||
}
|
||||
add_bg_result(q->w, q, buf, UB_NOERROR);
|
||||
add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -622,7 +630,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
|||
return;
|
||||
}
|
||||
if(!setup_qinfo_edns(w, q, &qinfo, &edns)) {
|
||||
add_bg_result(w, q, NULL, UB_SYNTAX);
|
||||
add_bg_result(w, q, NULL, UB_SYNTAX, NULL);
|
||||
return;
|
||||
}
|
||||
qid = 0;
|
||||
|
|
@ -634,7 +642,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
|||
w->back->udp_buff, w->env->scratch)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
q->msg_security = sec_status_insecure;
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR);
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
||||
free(qinfo.qname);
|
||||
return;
|
||||
}
|
||||
|
|
@ -642,7 +650,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
|||
/* process new query */
|
||||
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
|
||||
w->back->udp_buff, qid, libworker_bg_done_cb, q)) {
|
||||
add_bg_result(w, q, NULL, UB_NOMEM);
|
||||
add_bg_result(w, q, NULL, UB_NOMEM, NULL);
|
||||
}
|
||||
free(qinfo.qname);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,11 +158,11 @@ void libworker_handle_result_write(struct tube* tube, uint8_t* msg, size_t len,
|
|||
|
||||
/** mesh callback with fg results */
|
||||
void libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf,
|
||||
enum sec_status s);
|
||||
enum sec_status s, char* why_bogus);
|
||||
|
||||
/** mesh callback with bg results */
|
||||
void libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf,
|
||||
enum sec_status s);
|
||||
enum sec_status s, char* why_bogus);
|
||||
|
||||
/**
|
||||
* fill result from parsed message, on error fills servfail
|
||||
|
|
|
|||
|
|
@ -181,6 +181,14 @@ struct ub_result {
|
|||
* This means the data is from a domain where data is not signed.
|
||||
*/
|
||||
int bogus;
|
||||
|
||||
/**
|
||||
* If the result is bogus this contains a string (zero terminated)
|
||||
* that describes the failure. There may be other errors as well
|
||||
* as the one described, the description may not be perfectly accurate.
|
||||
* Is NULL if the result is not bogus.
|
||||
*/
|
||||
char* why_bogus;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
|||
for(cb=mstate->cb_list; cb; cb=cb->next) {
|
||||
fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
|
||||
(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
|
||||
sec_status_unchecked);
|
||||
sec_status_unchecked, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -615,6 +615,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
struct mesh_cb* r)
|
||||
{
|
||||
int secure;
|
||||
char* reason = NULL;
|
||||
/* bogus messages are not made into servfail, sec_status passed
|
||||
* to the callback function */
|
||||
if(rep && rep->security == sec_status_secure)
|
||||
|
|
@ -622,10 +623,14 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
else secure = 0;
|
||||
if(!rep && rcode == LDNS_RCODE_NOERROR)
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(!rcode && rep->security == sec_status_bogus) {
|
||||
if(!(reason = errinf_to_str(&m->s)))
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
/* send the reply */
|
||||
if(rcode) {
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked);
|
||||
(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL);
|
||||
} else {
|
||||
size_t udp_size = r->edns.udp_size;
|
||||
ldns_buffer_clear(r->buf);
|
||||
|
|
@ -640,13 +645,14 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
{
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, LDNS_RCODE_SERVFAIL, r->buf,
|
||||
sec_status_unchecked);
|
||||
sec_status_unchecked, NULL);
|
||||
} else {
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, LDNS_RCODE_NOERROR, r->buf,
|
||||
rep->security);
|
||||
rep->security, reason);
|
||||
}
|
||||
}
|
||||
free(reason);
|
||||
m->s.env->mesh->num_reply_addrs--;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -206,9 +206,10 @@ struct mesh_reply {
|
|||
|
||||
/**
|
||||
* Mesh result callback func.
|
||||
* called as func(cb_arg, rcode, buffer_with_reply, security);
|
||||
* */
|
||||
typedef void (*mesh_cb_func_t)(void*, int, ldns_buffer*, enum sec_status);
|
||||
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus);
|
||||
*/
|
||||
typedef void (*mesh_cb_func_t)(void*, int, ldns_buffer*, enum sec_status,
|
||||
char*);
|
||||
|
||||
/**
|
||||
* Callback to result routine
|
||||
|
|
|
|||
|
|
@ -304,6 +304,8 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname)
|
|||
if(verb > 0)
|
||||
printf(" %s", secstatus);
|
||||
printf("\n");
|
||||
if(result->bogus && result->why_bogus)
|
||||
printf("%s\n", result->why_bogus);
|
||||
return;
|
||||
}
|
||||
if(docname && result->canonname &&
|
||||
|
|
@ -335,6 +337,8 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname)
|
|||
printf(" %s\n", secstatus);
|
||||
}
|
||||
/* else: emptiness to indicate no data */
|
||||
if(result->bogus && result->why_bogus)
|
||||
printf("%s\n", result->why_bogus);
|
||||
return;
|
||||
}
|
||||
i=0;
|
||||
|
|
@ -346,6 +350,8 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname)
|
|||
(size_t)result->len[i]);
|
||||
i++;
|
||||
}
|
||||
if(result->bogus && result->why_bogus)
|
||||
printf("%s\n", result->why_bogus);
|
||||
}
|
||||
|
||||
/** perform a lookup and printout return if domain existed */
|
||||
|
|
|
|||
|
|
@ -182,13 +182,15 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
|
|||
}
|
||||
|
||||
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s))
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s))
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@
|
|||
#include "util/configparser.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/module.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/data/dname.h"
|
||||
/** global config during parsing */
|
||||
struct config_parser_state* cfg_parser = 0;
|
||||
/** lex in file */
|
||||
|
|
@ -156,6 +159,7 @@ config_create()
|
|||
cfg->val_sig_skew_max = 86400; /* at most timezone settings trouble */
|
||||
cfg->val_clean_additional = 1;
|
||||
cfg->val_log_level = 0;
|
||||
cfg->val_log_squelch = 0;
|
||||
cfg->val_permissive_mode = 0;
|
||||
cfg->add_holddown = 30*24*3600;
|
||||
cfg->del_holddown = 30*24*3600;
|
||||
|
|
@ -210,6 +214,8 @@ struct config_file* config_create_forlib()
|
|||
cfg->neg_cache_size = 100 * 1024;
|
||||
cfg->donotquery_localhost = 0; /* allow, so that you can ask a
|
||||
forward nameserver running on localhost */
|
||||
cfg->val_log_level = 2; /* to fill why_bogus with */
|
||||
cfg->val_log_squelch = 1;
|
||||
return cfg;
|
||||
}
|
||||
|
||||
|
|
@ -387,6 +393,9 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
|||
} else if(strcmp(opt, "val-log-level:") == 0) {
|
||||
IS_NUMBER_OR_ZERO;
|
||||
cfg->val_log_level = atoi(val);
|
||||
} else if(strcmp(opt, "val-log-squelch:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->val_log_squelch = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "val-permissive-mode:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->val_permissive_mode = (strcmp(val, "yes") == 0);
|
||||
|
|
@ -1095,3 +1104,113 @@ char* cfg_ptr_reverse(char* str)
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void errinf(struct module_qstate* qstate, const char* str)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
if(qstate->env->cfg->val_log_level < 2 || !str)
|
||||
return;
|
||||
p = (struct config_strlist*)regional_alloc(qstate->region, sizeof(*p));
|
||||
if(!p) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
p->next = NULL;
|
||||
p->str = regional_strdup(qstate->region, str);
|
||||
if(!p->str) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
/* add at end */
|
||||
if(qstate->errinf) {
|
||||
struct config_strlist* q = qstate->errinf;
|
||||
while(q->next)
|
||||
q = q->next;
|
||||
q->next = p;
|
||||
} else qstate->errinf = p;
|
||||
}
|
||||
|
||||
void errinf_origin(struct module_qstate* qstate, struct sock_list *origin)
|
||||
{
|
||||
struct sock_list* p;
|
||||
if(qstate->env->cfg->val_log_level < 2)
|
||||
return;
|
||||
for(p=origin; p; p=p->next) {
|
||||
char buf[256];
|
||||
if(p == origin)
|
||||
snprintf(buf, sizeof(buf), "from ");
|
||||
else snprintf(buf, sizeof(buf), "and from ");
|
||||
if(p->len == 0)
|
||||
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf),
|
||||
"cache");
|
||||
else
|
||||
addr_to_str(&p->addr, p->len, buf+strlen(buf),
|
||||
sizeof(buf)-strlen(buf));
|
||||
errinf(qstate, buf);
|
||||
}
|
||||
}
|
||||
|
||||
char* errinf_to_str(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct config_strlist* s;
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char* t = ldns_rr_type2str(qstate->qinfo.qtype);
|
||||
char* c = ldns_rr_class2str(qstate->qinfo.qclass);
|
||||
if(!t || !c) {
|
||||
free(t);
|
||||
free(c);
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return NULL;
|
||||
}
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c);
|
||||
free(t);
|
||||
free(c);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
if(!qstate->errinf)
|
||||
snprintf(p, left, " misc failure");
|
||||
else for(s=qstate->errinf; s; s=s->next) {
|
||||
snprintf(p, left, " %s", s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr)
|
||||
{
|
||||
char buf[1024];
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char *t, *c;
|
||||
if(qstate->env->cfg->val_log_level < 2 || !rr)
|
||||
return;
|
||||
t = ldns_rr_type2str(ntohs(rr->rk.type));
|
||||
c = ldns_rr_class2str(ntohs(rr->rk.rrset_class));
|
||||
if(!t || !c) {
|
||||
free(t);
|
||||
free(c);
|
||||
log_err("malloc failure in errinf_rrset");
|
||||
return;
|
||||
}
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c);
|
||||
free(t);
|
||||
free(c);
|
||||
errinf(qstate, buf);
|
||||
}
|
||||
|
||||
void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname)
|
||||
{
|
||||
char b[1024];
|
||||
char buf[LDNS_MAX_DOMAINLEN+1];
|
||||
if(qstate->env->cfg->val_log_level < 2 || !str || !dname)
|
||||
return;
|
||||
dname_str(dname, buf);
|
||||
snprintf(b, sizeof(b), "%s %s", str, buf);
|
||||
errinf(qstate, b);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@
|
|||
struct config_stub;
|
||||
struct config_strlist;
|
||||
struct config_str2list;
|
||||
struct module_qstate;
|
||||
struct sock_list;
|
||||
struct ub_packed_rrset_key;
|
||||
|
||||
/**
|
||||
* The configuration options.
|
||||
|
|
@ -219,6 +222,8 @@ struct config_file {
|
|||
int val_clean_additional;
|
||||
/** log bogus messages by the validator */
|
||||
int val_log_level;
|
||||
/** squelch val_log_level to log - this is library goes to callback */
|
||||
int val_log_squelch;
|
||||
/** should validator allow bogus messages to go through */
|
||||
int val_permissive_mode;
|
||||
/** nsec3 maximum iterations per key size, string */
|
||||
|
|
@ -469,6 +474,48 @@ char* fname_after_chroot(const char* fname, struct config_file* cfg,
|
|||
*/
|
||||
char* cfg_ptr_reverse(char* str);
|
||||
|
||||
/**
|
||||
* Append text to the error info for validation.
|
||||
* @param qstate: query state.
|
||||
* @param str: copied into query region and appended.
|
||||
* Failures to allocate are logged.
|
||||
*/
|
||||
void errinf(struct module_qstate* qstate, const char* str);
|
||||
|
||||
/**
|
||||
* Append text to error info: from 1.2.3.4
|
||||
* @param qstate: query state.
|
||||
* @param origin: sock list with origin of trouble.
|
||||
* Every element added.
|
||||
* If NULL: nothing is added.
|
||||
* if 0len element: 'from cache' is added.
|
||||
*/
|
||||
void errinf_origin(struct module_qstate* qstate, struct sock_list *origin);
|
||||
|
||||
/**
|
||||
* Append text to error info: for RRset name type class
|
||||
* @param qstate: query state.
|
||||
* @param rr: rrset_key.
|
||||
*/
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr);
|
||||
|
||||
/**
|
||||
* Append text to error info: str dname
|
||||
* @param qstate: query state.
|
||||
* @param str: explanation string
|
||||
* @param dname: the dname.
|
||||
*/
|
||||
void errinf_dname(struct module_qstate* qstate, const char* str,
|
||||
uint8_t* dname);
|
||||
|
||||
/**
|
||||
* Create error info in string
|
||||
* @param qstate: query state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Used during options parsing
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -299,6 +299,8 @@ struct module_qstate {
|
|||
struct sock_list* blacklist;
|
||||
/** region for this query. Cleared when query process finishes. */
|
||||
struct regional* region;
|
||||
/** failure reason information if val-log-level is high */
|
||||
struct config_strlist* errinf;
|
||||
|
||||
/** which module is executing */
|
||||
int curmod;
|
||||
|
|
|
|||
|
|
@ -1925,7 +1925,8 @@ autr_debug_print(struct val_anchors* anchors)
|
|||
}
|
||||
|
||||
void probe_answer_cb(void* arg, int ATTR_UNUSED(rcode),
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(sec))
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(sec),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
{
|
||||
/* retry was set before the query was done,
|
||||
* re-querytime is set when query succeeded, but that may not
|
||||
|
|
|
|||
|
|
@ -199,6 +199,6 @@ void autr_debug_print(struct val_anchors* anchors);
|
|||
|
||||
/** callback for query answer to 5011 probe */
|
||||
void probe_answer_cb(void* arg, int rcode, ldns_buffer* buf,
|
||||
enum sec_status sec);
|
||||
enum sec_status sec, char* errinf);
|
||||
|
||||
#endif /* VALIDATOR_AUTOTRUST_H */
|
||||
|
|
|
|||
|
|
@ -850,120 +850,6 @@ void val_blacklist(struct sock_list** blacklist, struct regional* region,
|
|||
else sock_list_merge(blacklist, region, origin);
|
||||
}
|
||||
|
||||
void val_errinf(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
const char* str)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
if(qstate->env->cfg->val_log_level < 2 || !str)
|
||||
return;
|
||||
p = (struct config_strlist*)regional_alloc(qstate->region, sizeof(*p));
|
||||
if(!p) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
p->next = NULL;
|
||||
p->str = regional_strdup(qstate->region, str);
|
||||
if(!p->str) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
/* add at end */
|
||||
if(vq->errinf) {
|
||||
struct config_strlist* q = vq->errinf;
|
||||
while(q->next)
|
||||
q = q->next;
|
||||
q->next = p;
|
||||
} else vq->errinf = p;
|
||||
}
|
||||
|
||||
void val_errinf_origin(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
struct sock_list *origin)
|
||||
{
|
||||
struct sock_list* p;
|
||||
if(qstate->env->cfg->val_log_level < 2)
|
||||
return;
|
||||
for(p=origin; p; p=p->next) {
|
||||
char buf[256];
|
||||
if(p == origin)
|
||||
snprintf(buf, sizeof(buf), "from ");
|
||||
else snprintf(buf, sizeof(buf), "and from ");
|
||||
if(p->len == 0)
|
||||
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf),
|
||||
"cache");
|
||||
else
|
||||
addr_to_str(&p->addr, p->len, buf+strlen(buf),
|
||||
sizeof(buf)-strlen(buf));
|
||||
val_errinf(qstate, vq, buf);
|
||||
}
|
||||
}
|
||||
|
||||
char* val_errinf_to_str(struct module_qstate* qstate, struct val_qstate* vq)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct config_strlist* s;
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char* t = ldns_rr_type2str(qstate->qinfo.qtype);
|
||||
char* c = ldns_rr_class2str(qstate->qinfo.qclass);
|
||||
if(!t || !c) {
|
||||
free(t);
|
||||
free(c);
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return NULL;
|
||||
}
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c);
|
||||
free(t);
|
||||
free(c);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
if(!vq->errinf)
|
||||
snprintf(p, left, " misc failure");
|
||||
else for(s=vq->errinf; s; s=s->next) {
|
||||
snprintf(p, left, " %s", s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
void val_errinf_rrset(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
struct ub_packed_rrset_key *rr)
|
||||
{
|
||||
char buf[1024];
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char *t, *c;
|
||||
if(qstate->env->cfg->val_log_level < 2 || !rr)
|
||||
return;
|
||||
t = ldns_rr_type2str(ntohs(rr->rk.type));
|
||||
c = ldns_rr_class2str(ntohs(rr->rk.rrset_class));
|
||||
if(!t || !c) {
|
||||
free(t);
|
||||
free(c);
|
||||
log_err("malloc failure in errinf_rrset");
|
||||
return;
|
||||
}
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c);
|
||||
free(t);
|
||||
free(c);
|
||||
val_errinf(qstate, vq, buf);
|
||||
}
|
||||
|
||||
void val_errinf_dname(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
const char* str, uint8_t* dname)
|
||||
{
|
||||
char b[1024];
|
||||
char buf[LDNS_MAX_DOMAINLEN+1];
|
||||
if(qstate->env->cfg->val_log_level < 2 || !str || !dname)
|
||||
return;
|
||||
dname_str(dname, buf);
|
||||
snprintf(b, sizeof(b), "%s %s", str, buf);
|
||||
val_errinf(qstate, vq, b);
|
||||
}
|
||||
|
||||
int val_has_signed_nsecs(struct reply_info* rep, char** reason)
|
||||
{
|
||||
size_t i, num_nsec = 0, num_nsec3 = 0;
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@ struct regional;
|
|||
struct val_anchors;
|
||||
struct rrset_cache;
|
||||
struct sock_list;
|
||||
struct module_qstate;
|
||||
struct val_qstate;
|
||||
|
||||
/**
|
||||
* Response classifications for the validator. The different types of proofs.
|
||||
|
|
@ -308,56 +306,6 @@ const char* val_classification_to_string(enum val_classification subtype);
|
|||
void val_blacklist(struct sock_list** blacklist, struct regional* region,
|
||||
struct sock_list* origin, int cross);
|
||||
|
||||
/**
|
||||
* Append text to the error info for validation.
|
||||
* @param qstate: query state.
|
||||
* @param vq: validator state.
|
||||
* @param str: copied into query region and appended.
|
||||
* Failures to allocate are logged.
|
||||
*/
|
||||
void val_errinf(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
const char* str);
|
||||
|
||||
/**
|
||||
* Append text to error info: from 1.2.3.4
|
||||
* @param qstate: query state.
|
||||
* @param vq: validator state.
|
||||
* @param origin: sock list with origin of trouble.
|
||||
* Every element added.
|
||||
* If NULL: nothing is added.
|
||||
* if 0len element: 'from cache' is added.
|
||||
*/
|
||||
void val_errinf_origin(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
struct sock_list *origin);
|
||||
|
||||
/**
|
||||
* Append text to error info: for RRset name type class
|
||||
* @param qstate: query state.
|
||||
* @param vq: validator state.
|
||||
* @param rr: rrset_key.
|
||||
*/
|
||||
void val_errinf_rrset(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
struct ub_packed_rrset_key *rr);
|
||||
|
||||
/**
|
||||
* Append text to error info: str dname
|
||||
* @param qstate: query state.
|
||||
* @param vq: validator state.
|
||||
* @param str: explanation string
|
||||
* @param dname: the dname.
|
||||
*/
|
||||
void val_errinf_dname(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
const char* str, uint8_t* dname);
|
||||
|
||||
/**
|
||||
* Create error info in string
|
||||
* @param qstate: query state. (for query name)
|
||||
* @param vq: validator state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* val_errinf_to_str(struct module_qstate* qstate, struct val_qstate* vq);
|
||||
|
||||
/**
|
||||
* check if has dnssec info, and if it has signed nsecs. gives error reason.
|
||||
* @param rep: reply to check.
|
||||
|
|
|
|||
|
|
@ -410,7 +410,6 @@ prime_trust_anchor(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
* completed.
|
||||
*
|
||||
* @param qstate: query state.
|
||||
* @param vq: validator query state.
|
||||
* @param env: module env for verify.
|
||||
* @param ve: validator env for verify.
|
||||
* @param qchase: query that was made.
|
||||
|
|
@ -421,8 +420,8 @@ prime_trust_anchor(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
* fail to verify. The message is then set to bogus.
|
||||
*/
|
||||
static int
|
||||
validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
struct module_env* env, struct val_env* ve, struct query_info* qchase,
|
||||
validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
struct val_env* ve, struct query_info* qchase,
|
||||
struct reply_info* chase_reply, struct key_entry_key* key_entry)
|
||||
{
|
||||
uint8_t* sname;
|
||||
|
|
@ -458,12 +457,12 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
log_nametypeclass(VERB_QUERY, "validator: response "
|
||||
"has failed ANSWER rrset:", s->rk.dname,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
|
||||
val_errinf(qstate, vq, reason);
|
||||
errinf(qstate, reason);
|
||||
if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME)
|
||||
val_errinf(qstate, vq, "for CNAME");
|
||||
errinf(qstate, "for CNAME");
|
||||
else if(ntohs(s->rk.type) == LDNS_RR_TYPE_DNAME)
|
||||
val_errinf(qstate, vq, "for DNAME");
|
||||
val_errinf_origin(qstate, vq, qstate->reply_origin);
|
||||
errinf(qstate, "for DNAME");
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
chase_reply->security = sec_status_bogus;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -487,9 +486,9 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
log_nametypeclass(VERB_QUERY, "validator: response "
|
||||
"has failed AUTHORITY rrset:", s->rk.dname,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
|
||||
val_errinf(qstate, vq, reason);
|
||||
val_errinf_rrset(qstate, vq, s);
|
||||
val_errinf_origin(qstate, vq, qstate->reply_origin);
|
||||
errinf(qstate, reason);
|
||||
errinf_rrset(qstate, s);
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
chase_reply->security = sec_status_bogus;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1511,7 +1510,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
"of trust to keys for", vq->key_entry->name,
|
||||
LDNS_RR_TYPE_DNSKEY, vq->key_entry->key_class);
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
val_errinf(qstate, vq, "while building chain of trust");
|
||||
errinf(qstate, "while building chain of trust");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -1522,8 +1521,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
"signer name", &vq->qchase);
|
||||
verbose(VERB_DETAIL, "Could not establish validation of "
|
||||
"INSECURE status of unsigned response.");
|
||||
val_errinf(qstate, vq, "no signatures");
|
||||
val_errinf_origin(qstate, vq, qstate->reply_origin);
|
||||
errinf(qstate, "no signatures");
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1532,7 +1531,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
|
||||
/* check signatures in the message;
|
||||
* answer and authority must be valid, additional is only checked. */
|
||||
if(!validate_msg_signatures(qstate, vq, qstate->env, ve, &vq->qchase,
|
||||
if(!validate_msg_signatures(qstate, qstate->env, ve, &vq->qchase,
|
||||
vq->chase_reply, vq->key_entry)) {
|
||||
/* workaround bad recursor out there that truncates (even
|
||||
* with EDNS4k) to 512 by removing RRSIG from auth section
|
||||
|
|
@ -1549,7 +1548,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
vq->chase_reply->ar_numrrsets = 0;
|
||||
vq->chase_reply->rrset_count =
|
||||
vq->chase_reply->an_numrrsets;
|
||||
vq->errinf = NULL;
|
||||
qstate->errinf = NULL;
|
||||
}
|
||||
else {
|
||||
verbose(VERB_DETAIL, "Validate: message contains "
|
||||
|
|
@ -1629,11 +1628,10 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
}
|
||||
if(vq->chase_reply->security == sec_status_bogus) {
|
||||
if(subtype == VAL_CLASS_POSITIVE)
|
||||
val_errinf(qstate, vq, "wildcard");
|
||||
else val_errinf(qstate, vq,
|
||||
val_classification_to_string(subtype));
|
||||
val_errinf(qstate, vq, "proof failed");
|
||||
val_errinf_origin(qstate, vq, qstate->reply_origin);
|
||||
errinf(qstate, "wildcard");
|
||||
else errinf(qstate, val_classification_to_string(subtype));
|
||||
errinf(qstate, "proof failed");
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
@ -1884,12 +1882,13 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
}
|
||||
|
||||
vq->orig_msg->rep->ttl = ve->bogus_ttl;
|
||||
if(qstate->env->cfg->val_log_level >= 1) {
|
||||
if(qstate->env->cfg->val_log_level >= 1 &&
|
||||
!qstate->env->cfg->val_log_squelch) {
|
||||
if(qstate->env->cfg->val_log_level < 2)
|
||||
log_query_info(0, "validation failure",
|
||||
&qstate->qinfo);
|
||||
else {
|
||||
char* err = val_errinf_to_str(qstate, vq);
|
||||
char* err = errinf_to_str(qstate);
|
||||
if(err) log_info(err);
|
||||
free(err);
|
||||
}
|
||||
|
|
@ -2157,9 +2156,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
|||
"could not fetch DNSKEY rrset",
|
||||
ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
|
||||
if(qstate->env->cfg->harden_dnssec_stripped) {
|
||||
struct val_qstate* vq = (struct val_qstate*)
|
||||
qstate->minfo[id];
|
||||
val_errinf(qstate, vq, "no DNSKEY rrset");
|
||||
errinf(qstate, "no DNSKEY rrset");
|
||||
kkey = key_entry_create_bad(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass);
|
||||
} else kkey = key_entry_create_null(qstate->region, ta->name,
|
||||
|
|
@ -2209,9 +2206,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
|||
/* NOTE: in this case, we should probably reject the trust
|
||||
* anchor for longer, perhaps forever. */
|
||||
if(qstate->env->cfg->harden_dnssec_stripped) {
|
||||
struct val_qstate* vq = (struct val_qstate*)
|
||||
qstate->minfo[id];
|
||||
val_errinf(qstate, vq, reason);
|
||||
errinf(qstate, reason);
|
||||
kkey = key_entry_create_bad(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass);
|
||||
} else kkey = key_entry_create_null(qstate->region, ta->name,
|
||||
|
|
@ -2258,8 +2253,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
char* rc = ldns_pkt_rcode2str(rcode);
|
||||
/* errors here pretty much break validation */
|
||||
verbose(VERB_DETAIL, "DS response was error, thus bogus");
|
||||
val_errinf(qstate, vq, rc);
|
||||
val_errinf(qstate, vq, "no DS");
|
||||
errinf(qstate, rc);
|
||||
errinf(qstate, "no DS");
|
||||
free(rc);
|
||||
goto return_bogus;
|
||||
}
|
||||
|
|
@ -2274,7 +2269,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
if(!ds) {
|
||||
log_warn("internal error: POSITIVE DS response was "
|
||||
"missing DS.");
|
||||
val_errinf(qstate, vq, "no DS record");
|
||||
errinf(qstate, "no DS record");
|
||||
goto return_bogus;
|
||||
}
|
||||
/* Verify only returns BOGUS or SECURE. If the rrset is
|
||||
|
|
@ -2284,7 +2279,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
if(sec != sec_status_secure) {
|
||||
verbose(VERB_DETAIL, "DS rrset in DS response did "
|
||||
"not verify");
|
||||
val_errinf(qstate, vq, reason);
|
||||
errinf(qstate, reason);
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
|
|
@ -2315,7 +2310,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
/* make sure there are NSECs or NSEC3s with signatures */
|
||||
if(!val_has_signed_nsecs(msg->rep, &reason)) {
|
||||
verbose(VERB_ALGO, "no NSECs: %s", reason);
|
||||
val_errinf(qstate, vq, reason);
|
||||
errinf(qstate, reason);
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
|
|
@ -2345,7 +2340,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
case sec_status_bogus:
|
||||
verbose(VERB_DETAIL, "NSEC RRset for the "
|
||||
"referral did not prove no DS.");
|
||||
val_errinf(qstate, vq, reason);
|
||||
errinf(qstate, reason);
|
||||
goto return_bogus;
|
||||
case sec_status_unchecked:
|
||||
default:
|
||||
|
|
@ -2373,7 +2368,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
case sec_status_bogus:
|
||||
verbose(VERB_DETAIL, "NSEC3s for the "
|
||||
"referral did not prove no DS.");
|
||||
val_errinf(qstate, vq, reason);
|
||||
errinf(qstate, reason);
|
||||
goto return_bogus;
|
||||
case sec_status_insecure:
|
||||
case sec_status_unchecked:
|
||||
|
|
@ -2386,20 +2381,19 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
* this is BOGUS. */
|
||||
verbose(VERB_DETAIL, "DS %s ran out of options, so return "
|
||||
"bogus", val_classification_to_string(subtype));
|
||||
val_errinf(qstate, vq, "no DS but also no proof of that");
|
||||
errinf(qstate, "no DS but also no proof of that");
|
||||
goto return_bogus;
|
||||
} else {
|
||||
verbose(VERB_QUERY, "Encountered an unhandled type of "
|
||||
"DS response, thus bogus.");
|
||||
val_errinf(qstate, vq, "no DS and ");
|
||||
errinf(qstate, "no DS and ");
|
||||
if(FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR) {
|
||||
char* rc = ldns_pkt_rcode2str(
|
||||
FLAGS_GET_RCODE(msg->rep->flags));
|
||||
val_errinf(qstate, vq, rc);
|
||||
errinf(qstate, rc);
|
||||
free(rc);
|
||||
} else val_errinf(qstate, vq,
|
||||
val_classification_to_string(subtype));
|
||||
val_errinf(qstate, vq, "message fails to prove that");
|
||||
} else errinf(qstate, val_classification_to_string(subtype));
|
||||
errinf(qstate, "message fails to prove that");
|
||||
goto return_bogus;
|
||||
}
|
||||
return_bogus:
|
||||
|
|
@ -2464,12 +2458,12 @@ process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
&& vq->restart_count < VAL_MAX_RESTART_COUNT) {
|
||||
vq->empty_DS_name = olds;
|
||||
val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1);
|
||||
vq->errinf = NULL;
|
||||
qstate->errinf = NULL;
|
||||
vq->restart_count++;
|
||||
} else {
|
||||
if(key_entry_isbad(dske)) {
|
||||
val_errinf_origin(qstate, vq, origin);
|
||||
val_errinf_dname(qstate, vq, "for DS", qinfo->qname);
|
||||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for DS", qinfo->qname);
|
||||
}
|
||||
/* NOTE: the reason for the DS to be not good (that is,
|
||||
* either bad or null) should have been logged by
|
||||
|
|
@ -2516,7 +2510,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
if(vq->restart_count < VAL_MAX_RESTART_COUNT) {
|
||||
val_blacklist(&vq->chain_blacklist, qstate->region,
|
||||
origin, 1);
|
||||
vq->errinf = NULL;
|
||||
qstate->errinf = NULL;
|
||||
vq->restart_count++;
|
||||
return;
|
||||
}
|
||||
|
|
@ -2526,9 +2520,9 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
log_err("alloc failure in missing dnskey response");
|
||||
/* key_entry is NULL for failure in Validate */
|
||||
}
|
||||
val_errinf(qstate, vq, "No DNSKEY record");
|
||||
val_errinf_origin(qstate, vq, origin);
|
||||
val_errinf_dname(qstate, vq, "for key", qinfo->qname);
|
||||
errinf(qstate, "No DNSKEY record");
|
||||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for key", qinfo->qname);
|
||||
vq->state = VAL_VALIDATE_STATE;
|
||||
return;
|
||||
}
|
||||
|
|
@ -2553,23 +2547,23 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
if(vq->restart_count < VAL_MAX_RESTART_COUNT) {
|
||||
val_blacklist(&vq->chain_blacklist,
|
||||
qstate->region, origin, 1);
|
||||
vq->errinf = NULL;
|
||||
qstate->errinf = NULL;
|
||||
vq->restart_count++;
|
||||
vq->key_entry = old;
|
||||
return;
|
||||
}
|
||||
verbose(VERB_DETAIL, "Did not match a DS to a DNSKEY, "
|
||||
"thus bogus.");
|
||||
val_errinf(qstate, vq, reason);
|
||||
val_errinf_origin(qstate, vq, origin);
|
||||
val_errinf_dname(qstate, vq, "for key", qinfo->qname);
|
||||
errinf(qstate, reason);
|
||||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for key", qinfo->qname);
|
||||
}
|
||||
vq->chain_blacklist = NULL;
|
||||
vq->state = VAL_VALIDATE_STATE;
|
||||
return;
|
||||
}
|
||||
vq->chain_blacklist = NULL;
|
||||
vq->errinf = NULL;
|
||||
qstate->errinf = NULL;
|
||||
|
||||
/* The DNSKEY validated, so cache it as a trusted key rrset. */
|
||||
key_cache_insert(ve->kcache, vq->key_entry);
|
||||
|
|
@ -2628,15 +2622,15 @@ process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
&& vq->restart_count < VAL_MAX_RESTART_COUNT) {
|
||||
val_blacklist(&vq->chain_blacklist, qstate->region,
|
||||
origin, 1);
|
||||
vq->errinf = NULL;
|
||||
qstate->errinf = NULL;
|
||||
vq->restart_count++;
|
||||
vq->key_entry = NULL;
|
||||
vq->state = VAL_INIT_STATE;
|
||||
return;
|
||||
}
|
||||
vq->chain_blacklist = NULL;
|
||||
val_errinf_origin(qstate, vq, origin);
|
||||
val_errinf_dname(qstate, vq, "for trust anchor", ta->name);
|
||||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for trust anchor", ta->name);
|
||||
/* store the freshly primed entry in the cache */
|
||||
key_cache_insert(ve->kcache, vq->key_entry);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,9 +237,6 @@ struct val_qstate {
|
|||
dlv_ask_higher, /* ask again */
|
||||
dlv_there_is_no_dlv /* got no DLV, sure of it */
|
||||
} dlv_status;
|
||||
|
||||
/** failure reason information if val-log-level is high */
|
||||
struct config_strlist* errinf;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue