aboutsummaryrefslogtreecommitdiff
path: root/validator/val_anchor.c
diff options
context:
space:
mode:
Diffstat (limited to 'validator/val_anchor.c')
-rw-r--r--validator/val_anchor.c237
1 files changed, 113 insertions, 124 deletions
diff --git a/validator/val_anchor.c b/validator/val_anchor.c
index e710f2f24083..a4adfe2d9dde 100644
--- a/validator/val_anchor.c
+++ b/validator/val_anchor.c
@@ -21,16 +21,16 @@
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
@@ -40,8 +40,6 @@
*/
#include "config.h"
#include <ctype.h>
-#include <ldns/dname.h>
-#include <ldns/host2wire.h>
#include "validator/val_anchor.h"
#include "validator/val_sigcrypt.h"
#include "validator/autotrust.h"
@@ -50,6 +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"
#ifdef HAVE_GLOB_H
#include <glob.h>
#endif
@@ -346,36 +347,26 @@ anchor_store_new_key(struct val_anchors* anchors, uint8_t* name, uint16_t type,
/**
* Add new RR. It converts ldns RR to wire format.
* @param anchors: anchor storage.
- * @param buffer: parsing buffer.
- * @param rr: the rr (allocated by caller).
+ * @param rr: the wirerr.
+ * @param rl: length of rr.
+ * @param dl: length of dname.
* @return NULL on error, else the trust anchor.
*/
static struct trust_anchor*
-anchor_store_new_rr(struct val_anchors* anchors, ldns_buffer* buffer,
- ldns_rr* rr)
+anchor_store_new_rr(struct val_anchors* anchors, uint8_t* rr, size_t rl,
+ size_t dl)
{
struct trust_anchor* ta;
- ldns_rdf* owner = ldns_rr_owner(rr);
- ldns_status status;
- ldns_buffer_clear(buffer);
- ldns_buffer_skip(buffer, 2); /* skip rdatalen */
- status = ldns_rr_rdata2buffer_wire(buffer, rr);
- if(status != LDNS_STATUS_OK) {
- log_err("error converting trustanchor to wireformat: %s",
- ldns_get_errorstr_by_id(status));
- return NULL;
- }
- ldns_buffer_flip(buffer);
- ldns_buffer_write_u16_at(buffer, 0, ldns_buffer_limit(buffer) - 2);
-
- if(!(ta=anchor_store_new_key(anchors, ldns_rdf_data(owner),
- ldns_rr_get_type(rr), ldns_rr_get_class(rr),
- ldns_buffer_begin(buffer), ldns_buffer_limit(buffer)))) {
+ if(!(ta=anchor_store_new_key(anchors, rr,
+ sldns_wirerr_get_type(rr, rl, dl),
+ sldns_wirerr_get_class(rr, rl, dl),
+ sldns_wirerr_get_rdatawl(rr, rl, dl),
+ sldns_wirerr_get_rdatalen(rr, rl, dl)+2))) {
return NULL;
}
log_nametypeclass(VERB_QUERY, "adding trusted key",
- ldns_rdf_data(owner),
- ldns_rr_get_type(rr), ldns_rr_get_class(rr));
+ rr, sldns_wirerr_get_type(rr, rl, dl),
+ sldns_wirerr_get_class(rr, rl, dl));
return ta;
}
@@ -389,36 +380,37 @@ static struct trust_anchor*
anchor_insert_insecure(struct val_anchors* anchors, const char* str)
{
struct trust_anchor* ta;
- ldns_rdf* nm = ldns_dname_new_frm_str(str);
+ size_t dname_len = 0;
+ uint8_t* nm = sldns_str2wire_dname(str, &dname_len);
if(!nm) {
log_err("parse error in domain name '%s'", str);
return NULL;
}
- ta = anchor_store_new_key(anchors, ldns_rdf_data(nm), LDNS_RR_TYPE_DS,
+ ta = anchor_store_new_key(anchors, nm, LDNS_RR_TYPE_DS,
LDNS_RR_CLASS_IN, NULL, 0);
- ldns_rdf_deep_free(nm);
+ free(nm);
return ta;
}
struct trust_anchor*
-anchor_store_str(struct val_anchors* anchors, ldns_buffer* buffer,
+anchor_store_str(struct val_anchors* anchors, sldns_buffer* buffer,
const char* str)
{
struct trust_anchor* ta;
- ldns_rr* rr = NULL;
- ldns_status status = ldns_rr_new_frm_str(&rr, str, 0, NULL, NULL);
- if(status != LDNS_STATUS_OK) {
- log_err("error parsing trust anchor: %s",
- ldns_get_errorstr_by_id(status));
- ldns_rr_free(rr);
+ uint8_t* rr = sldns_buffer_begin(buffer);
+ size_t len = sldns_buffer_capacity(buffer), dname_len = 0;
+ int status = sldns_str2wire_rr_buf(str, rr, &len, &dname_len,
+ 0, NULL, 0, NULL, 0);
+ if(status != 0) {
+ log_err("error parsing trust anchor %s: at %d: %s",
+ str, LDNS_WIREPARSE_OFFSET(status),
+ sldns_get_errorstr_parse(status));
return NULL;
}
- if(!(ta=anchor_store_new_rr(anchors, buffer, rr))) {
+ if(!(ta=anchor_store_new_rr(anchors, rr, len, dname_len))) {
log_err("out of memory");
- ldns_rr_free(rr);
return NULL;
}
- ldns_rr_free(rr);
return ta;
}
@@ -431,44 +423,43 @@ anchor_store_str(struct val_anchors* anchors, ldns_buffer* buffer,
* @return NULL on error. Else last trust-anchor point.
*/
static struct trust_anchor*
-anchor_read_file(struct val_anchors* anchors, ldns_buffer* buffer,
+anchor_read_file(struct val_anchors* anchors, sldns_buffer* buffer,
const char* fname, int onlyone)
{
struct trust_anchor* ta = NULL, *tanew;
- uint32_t default_ttl = 3600;
- ldns_rdf* origin = NULL, *prev = NULL;
- int line_nr = 1;
- ldns_status status;
- ldns_rr* rr;
+ struct sldns_file_parse_state pst;
+ int status;
+ size_t len, dname_len;
+ uint8_t* rr = sldns_buffer_begin(buffer);
int ok = 1;
FILE* in = fopen(fname, "r");
if(!in) {
log_err("error opening file %s: %s", fname, strerror(errno));
return 0;
}
+ memset(&pst, 0, sizeof(pst));
+ pst.default_ttl = 3600;
+ pst.lineno = 1;
while(!feof(in)) {
- rr = NULL;
- status = ldns_rr_new_frm_fp_l(&rr, in, &default_ttl, &origin,
- &prev, &line_nr);
- if(status == LDNS_STATUS_SYNTAX_EMPTY /* empty line */
- || status == LDNS_STATUS_SYNTAX_TTL /* $TTL */
- || status == LDNS_STATUS_SYNTAX_ORIGIN /* $ORIGIN */)
+ len = sldns_buffer_capacity(buffer);
+ dname_len = 0;
+ status = sldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst);
+ if(len == 0) /* empty, $TTL, $ORIGIN */
continue;
- if(status != LDNS_STATUS_OK) {
- log_err("parse error in %s:%d : %s", fname, line_nr,
- ldns_get_errorstr_by_id(status));
- ldns_rr_free(rr);
+ if(status != 0) {
+ log_err("parse error in %s:%d:%d : %s", fname,
+ pst.lineno, LDNS_WIREPARSE_OFFSET(status),
+ sldns_get_errorstr_parse(status));
ok = 0;
break;
}
- if(ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS &&
- ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY) {
- ldns_rr_free(rr);
+ if(sldns_wirerr_get_type(rr, len, dname_len) !=
+ LDNS_RR_TYPE_DS && sldns_wirerr_get_type(rr, len,
+ dname_len) != LDNS_RR_TYPE_DNSKEY) {
continue;
}
- if(!(tanew=anchor_store_new_rr(anchors, buffer, rr))) {
- log_err("error at %s line %d", fname, line_nr);
- ldns_rr_free(rr);
+ if(!(tanew=anchor_store_new_rr(anchors, rr, len, dname_len))) {
+ log_err("mem error at %s line %d", fname, pst.lineno);
ok = 0;
break;
}
@@ -476,16 +467,12 @@ anchor_read_file(struct val_anchors* anchors, ldns_buffer* buffer,
log_err("error at %s line %d: no multiple anchor "
"domains allowed (you can have multiple "
"keys, but they must have the same name).",
- fname, line_nr);
- ldns_rr_free(rr);
+ fname, pst.lineno);
ok = 0;
break;
}
ta = tanew;
- ldns_rr_free(rr);
}
- ldns_rdf_deep_free(origin);
- ldns_rdf_deep_free(prev);
fclose(in);
if(!ok) return NULL;
/* empty file is OK when multiple anchors are allowed */
@@ -540,7 +527,7 @@ is_bind_special(int c)
* 0 on end of file.
*/
static int
-readkeyword_bindfile(FILE* in, ldns_buffer* buf, int* line, int comments)
+readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments)
{
int c;
int numdone = 0;
@@ -550,17 +537,17 @@ readkeyword_bindfile(FILE* in, ldns_buffer* buf, int* line, int comments)
(*line)++;
continue;
} else if(comments && c=='/' && numdone>0 && /* /_/ bla*/
- ldns_buffer_read_u8_at(buf,
- ldns_buffer_position(buf)-1) == '/') {
- ldns_buffer_skip(buf, -1);
+ sldns_buffer_read_u8_at(buf,
+ sldns_buffer_position(buf)-1) == '/') {
+ sldns_buffer_skip(buf, -1);
numdone--;
skip_to_eol(in);
(*line)++;
continue;
} else if(comments && c=='*' && numdone>0 && /* /_* bla *_/ */
- ldns_buffer_read_u8_at(buf,
- ldns_buffer_position(buf)-1) == '/') {
- ldns_buffer_skip(buf, -1);
+ sldns_buffer_read_u8_at(buf,
+ sldns_buffer_position(buf)-1) == '/') {
+ sldns_buffer_skip(buf, -1);
numdone--;
/* skip to end of comment */
while(c != EOF && (c=getc(in)) != EOF ) {
@@ -590,10 +577,10 @@ readkeyword_bindfile(FILE* in, ldns_buffer* buf, int* line, int comments)
(*line)++;
}
/* space for 1 char + 0 string terminator */
- if(ldns_buffer_remaining(buf) < 2) {
+ if(sldns_buffer_remaining(buf) < 2) {
fatal_exit("trusted-keys, %d, string too long", *line);
}
- ldns_buffer_write_u8(buf, (uint8_t)c);
+ sldns_buffer_write_u8(buf, (uint8_t)c);
numdone++;
if(isspace(c)) {
/* collate whitespace into ' ' */
@@ -615,17 +602,17 @@ readkeyword_bindfile(FILE* in, ldns_buffer* buf, int* line, int comments)
/** skip through file to { or ; */
static int
-skip_to_special(FILE* in, ldns_buffer* buf, int* line, int spec)
+skip_to_special(FILE* in, sldns_buffer* buf, int* line, int spec)
{
int rdlen;
- ldns_buffer_clear(buf);
+ sldns_buffer_clear(buf);
while((rdlen=readkeyword_bindfile(in, buf, line, 1))) {
- if(rdlen == 1 && isspace((int)*ldns_buffer_begin(buf))) {
- ldns_buffer_clear(buf);
+ if(rdlen == 1 && isspace((int)*sldns_buffer_begin(buf))) {
+ sldns_buffer_clear(buf);
continue;
}
- if(rdlen != 1 || *ldns_buffer_begin(buf) != (uint8_t)spec) {
- ldns_buffer_write_u8(buf, 0);
+ if(rdlen != 1 || *sldns_buffer_begin(buf) != (uint8_t)spec) {
+ sldns_buffer_write_u8(buf, 0);
log_err("trusted-keys, line %d, expected %c",
*line, spec);
return 0;
@@ -645,7 +632,7 @@ skip_to_special(FILE* in, ldns_buffer* buf, int* line, int spec)
* @return 0 on error.
*/
static int
-process_bind_contents(struct val_anchors* anchors, ldns_buffer* buf,
+process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf,
int* line, FILE* in)
{
/* loop over contents, collate strings before ; */
@@ -658,41 +645,41 @@ process_bind_contents(struct val_anchors* anchors, ldns_buffer* buf,
int comments = 1;
int rdlen;
char* str = 0;
- ldns_buffer_clear(buf);
+ sldns_buffer_clear(buf);
while((rdlen=readkeyword_bindfile(in, buf, line, comments))) {
- if(rdlen == 1 && ldns_buffer_position(buf) == 1
- && isspace((int)*ldns_buffer_begin(buf))) {
+ if(rdlen == 1 && sldns_buffer_position(buf) == 1
+ && isspace((int)*sldns_buffer_begin(buf))) {
/* starting whitespace is removed */
- ldns_buffer_clear(buf);
+ sldns_buffer_clear(buf);
continue;
- } else if(rdlen == 1 && ldns_buffer_current(buf)[-1] == '"') {
+ } else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == '"') {
/* remove " from the string */
if(contnum == 0) {
quoted = 1;
comments = 0;
}
- ldns_buffer_skip(buf, -1);
+ sldns_buffer_skip(buf, -1);
if(contnum > 0 && quoted) {
- if(ldns_buffer_remaining(buf) < 8+1) {
+ if(sldns_buffer_remaining(buf) < 8+1) {
log_err("line %d, too long", *line);
return 0;
}
- ldns_buffer_write(buf, " DNSKEY ", 8);
+ sldns_buffer_write(buf, " DNSKEY ", 8);
quoted = 0;
comments = 1;
} else if(contnum > 0)
comments = !comments;
continue;
- } else if(rdlen == 1 && ldns_buffer_current(buf)[-1] == ';') {
+ } else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == ';') {
if(contnum < 5) {
- ldns_buffer_write_u8(buf, 0);
+ sldns_buffer_write_u8(buf, 0);
log_err("line %d, bad key", *line);
return 0;
}
- ldns_buffer_skip(buf, -1);
- ldns_buffer_write_u8(buf, 0);
- str = strdup((char*)ldns_buffer_begin(buf));
+ sldns_buffer_skip(buf, -1);
+ sldns_buffer_write_u8(buf, 0);
+ str = strdup((char*)sldns_buffer_begin(buf));
if(!str) {
log_err("line %d, allocation failure", *line);
return 0;
@@ -703,30 +690,30 @@ process_bind_contents(struct val_anchors* anchors, ldns_buffer* buf,
return 0;
}
free(str);
- ldns_buffer_clear(buf);
+ sldns_buffer_clear(buf);
contnum = 0;
quoted = 0;
comments = 1;
continue;
- } else if(rdlen == 1 && ldns_buffer_current(buf)[-1] == '}') {
+ } else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == '}') {
if(contnum > 0) {
- ldns_buffer_write_u8(buf, 0);
+ sldns_buffer_write_u8(buf, 0);
log_err("line %d, bad key before }", *line);
return 0;
}
return 1;
} else if(rdlen == 1 &&
- isspace((int)ldns_buffer_current(buf)[-1])) {
+ isspace((int)sldns_buffer_current(buf)[-1])) {
/* leave whitespace here */
} else {
/* not space or whatnot, so actual content */
contnum ++;
if(contnum == 1 && !quoted) {
- if(ldns_buffer_remaining(buf) < 8+1) {
+ if(sldns_buffer_remaining(buf) < 8+1) {
log_err("line %d, too long", *line);
return 0;
}
- ldns_buffer_write(buf, " DNSKEY ", 8);
+ sldns_buffer_write(buf, " DNSKEY ", 8);
}
}
}
@@ -743,7 +730,7 @@ process_bind_contents(struct val_anchors* anchors, ldns_buffer* buf,
* @return false on error.
*/
static int
-anchor_read_bind_file(struct val_anchors* anchors, ldns_buffer* buffer,
+anchor_read_bind_file(struct val_anchors* anchors, sldns_buffer* buffer,
const char* fname)
{
int line_nr = 1;
@@ -755,11 +742,11 @@ anchor_read_bind_file(struct val_anchors* anchors, ldns_buffer* buffer,
}
verbose(VERB_QUERY, "reading in bind-compat-mode: '%s'", fname);
/* scan for trusted-keys keyword, ignore everything else */
- ldns_buffer_clear(buffer);
+ sldns_buffer_clear(buffer);
while((rdlen=readkeyword_bindfile(in, buffer, &line_nr, 1)) != 0) {
- if(rdlen != 12 || strncmp((char*)ldns_buffer_begin(buffer),
+ if(rdlen != 12 || strncmp((char*)sldns_buffer_begin(buffer),
"trusted-keys", 12) != 0) {
- ldns_buffer_clear(buffer);
+ sldns_buffer_clear(buffer);
/* ignore everything but trusted-keys */
continue;
}
@@ -779,7 +766,7 @@ anchor_read_bind_file(struct val_anchors* anchors, ldns_buffer* buffer,
fclose(in);
return 0;
}
- ldns_buffer_clear(buffer);
+ sldns_buffer_clear(buffer);
}
fclose(in);
return 1;
@@ -794,7 +781,7 @@ anchor_read_bind_file(struct val_anchors* anchors, ldns_buffer* buffer,
* @return false on error.
*/
static int
-anchor_read_bind_file_wild(struct val_anchors* anchors, ldns_buffer* buffer,
+anchor_read_bind_file_wild(struct val_anchors* anchors, sldns_buffer* buffer,
const char* pat)
{
#ifdef HAVE_GLOB
@@ -1052,13 +1039,13 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
{
struct config_strlist* f;
char* nm;
- ldns_buffer* parsebuf = ldns_buffer_new(65535);
+ sldns_buffer* parsebuf = sldns_buffer_new(65535);
for(f = cfg->domain_insecure; f; f = f->next) {
if(!f->str || f->str[0] == 0) /* empty "" */
continue;
if(!anchor_insert_insecure(anchors, f->str)) {
log_err("error in domain-insecure: %s", f->str);
- ldns_buffer_free(parsebuf);
+ sldns_buffer_free(parsebuf);
return 0;
}
}
@@ -1071,7 +1058,7 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
nm += strlen(cfg->chrootdir);
if(!anchor_read_file(anchors, parsebuf, nm, 0)) {
log_err("error reading trust-anchor-file: %s", f->str);
- ldns_buffer_free(parsebuf);
+ sldns_buffer_free(parsebuf);
return 0;
}
}
@@ -1084,7 +1071,7 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
nm += strlen(cfg->chrootdir);
if(!anchor_read_bind_file_wild(anchors, parsebuf, nm)) {
log_err("error reading trusted-keys-file: %s", f->str);
- ldns_buffer_free(parsebuf);
+ sldns_buffer_free(parsebuf);
return 0;
}
}
@@ -1093,7 +1080,7 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
continue;
if(!anchor_store_str(anchors, parsebuf, f->str)) {
log_err("error in trust-anchor: \"%s\"", f->str);
- ldns_buffer_free(parsebuf);
+ sldns_buffer_free(parsebuf);
return 0;
}
}
@@ -1107,7 +1094,7 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
nm, 1))) {
log_err("error reading dlv-anchor-file: %s",
cfg->dlv_anchor_file);
- ldns_buffer_free(parsebuf);
+ sldns_buffer_free(parsebuf);
return 0;
}
lock_basic_lock(&anchors->lock);
@@ -1121,7 +1108,7 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
if(!(dlva = anchor_store_str(
anchors, parsebuf, f->str))) {
log_err("error in dlv-anchor: \"%s\"", f->str);
- ldns_buffer_free(parsebuf);
+ sldns_buffer_free(parsebuf);
return 0;
}
lock_basic_lock(&anchors->lock);
@@ -1140,14 +1127,14 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
if(!autr_read_file(anchors, nm)) {
log_err("error reading auto-trust-anchor-file: %s",
f->str);
- ldns_buffer_free(parsebuf);
+ sldns_buffer_free(parsebuf);
return 0;
}
}
/* first assemble, since it may delete useless anchors */
anchors_assemble_rrsets(anchors);
init_parents(anchors);
- ldns_buffer_free(parsebuf);
+ sldns_buffer_free(parsebuf);
if(verbosity >= VERB_ALGO) autr_debug_print(anchors);
return 1;
}
@@ -1197,6 +1184,8 @@ anchors_get_mem(struct val_anchors* anchors)
{
struct trust_anchor *ta;
size_t s = sizeof(*anchors);
+ if(!anchors)
+ return 0;
RBTREE_FOR(ta, struct trust_anchor*, anchors->tree) {
s += sizeof(*ta) + ta->namelen;
/* keys and so on */