val_anchor.c revision 356345
1/*
2 * validator/val_anchor.c - validator trust anchor storage.
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36/**
37 * \file
38 *
39 * This file contains storage for the trust anchors for the validator.
40 */
41#include "config.h"
42#include <ctype.h>
43#include "validator/val_anchor.h"
44#include "validator/val_sigcrypt.h"
45#include "validator/autotrust.h"
46#include "util/data/packed_rrset.h"
47#include "util/data/dname.h"
48#include "util/log.h"
49#include "util/net_help.h"
50#include "util/config_file.h"
51#include "util/as112.h"
52#include "sldns/sbuffer.h"
53#include "sldns/rrdef.h"
54#include "sldns/str2wire.h"
55#ifdef HAVE_GLOB_H
56#include <glob.h>
57#endif
58
59int
60anchor_cmp(const void* k1, const void* k2)
61{
62	int m;
63	struct trust_anchor* n1 = (struct trust_anchor*)k1;
64	struct trust_anchor* n2 = (struct trust_anchor*)k2;
65	/* no need to ntohs(class) because sort order is irrelevant */
66	if(n1->dclass != n2->dclass) {
67		if(n1->dclass < n2->dclass)
68			return -1;
69		return 1;
70	}
71	return dname_lab_cmp(n1->name, n1->namelabs, n2->name, n2->namelabs,
72		&m);
73}
74
75struct val_anchors*
76anchors_create(void)
77{
78	struct val_anchors* a = (struct val_anchors*)calloc(1, sizeof(*a));
79	if(!a)
80		return NULL;
81	a->tree = rbtree_create(anchor_cmp);
82	if(!a->tree) {
83		anchors_delete(a);
84		return NULL;
85	}
86	a->autr = autr_global_create();
87	if(!a->autr) {
88		anchors_delete(a);
89		return NULL;
90	}
91	lock_basic_init(&a->lock);
92	lock_protect(&a->lock, a, sizeof(*a));
93	lock_protect(&a->lock, a->autr, sizeof(*a->autr));
94	return a;
95}
96
97/** delete assembled rrset */
98static void
99assembled_rrset_delete(struct ub_packed_rrset_key* pkey)
100{
101	if(!pkey) return;
102	if(pkey->entry.data) {
103		struct packed_rrset_data* pd = (struct packed_rrset_data*)
104			pkey->entry.data;
105		free(pd->rr_data);
106		free(pd->rr_ttl);
107		free(pd->rr_len);
108		free(pd);
109	}
110	free(pkey->rk.dname);
111	free(pkey);
112}
113
114/** destroy locks in tree and delete autotrust anchors */
115static void
116anchors_delfunc(rbnode_type* elem, void* ATTR_UNUSED(arg))
117{
118	struct trust_anchor* ta = (struct trust_anchor*)elem;
119	if(!ta) return;
120	if(ta->autr) {
121		autr_point_delete(ta);
122	} else {
123		struct ta_key* p, *np;
124		lock_basic_destroy(&ta->lock);
125		free(ta->name);
126		p = ta->keylist;
127		while(p) {
128			np = p->next;
129			free(p->data);
130			free(p);
131			p = np;
132		}
133		assembled_rrset_delete(ta->ds_rrset);
134		assembled_rrset_delete(ta->dnskey_rrset);
135		free(ta);
136	}
137}
138
139void
140anchors_delete(struct val_anchors* anchors)
141{
142	if(!anchors)
143		return;
144	lock_unprotect(&anchors->lock, anchors->autr);
145	lock_unprotect(&anchors->lock, anchors);
146	lock_basic_destroy(&anchors->lock);
147	if(anchors->tree)
148		traverse_postorder(anchors->tree, anchors_delfunc, NULL);
149	free(anchors->tree);
150	autr_global_delete(anchors->autr);
151	free(anchors);
152}
153
154void
155anchors_init_parents_locked(struct val_anchors* anchors)
156{
157	struct trust_anchor* node, *prev = NULL, *p;
158	int m;
159	/* nobody else can grab locks because we hold the main lock.
160	 * Thus the previous items, after unlocked, are not deleted */
161	RBTREE_FOR(node, struct trust_anchor*, anchors->tree) {
162		lock_basic_lock(&node->lock);
163		node->parent = NULL;
164		if(!prev || prev->dclass != node->dclass) {
165			prev = node;
166			lock_basic_unlock(&node->lock);
167			continue;
168		}
169		(void)dname_lab_cmp(prev->name, prev->namelabs, node->name,
170			node->namelabs, &m); /* we know prev is smaller */
171		/* sort order like: . com. bla.com. zwb.com. net. */
172		/* find the previous, or parent-parent-parent */
173		for(p = prev; p; p = p->parent)
174			/* looking for name with few labels, a parent */
175			if(p->namelabs <= m) {
176				/* ==: since prev matched m, this is closest*/
177				/* <: prev matches more, but is not a parent,
178			 	* this one is a (grand)parent */
179				node->parent = p;
180				break;
181			}
182		lock_basic_unlock(&node->lock);
183		prev = node;
184	}
185}
186
187/** initialise parent pointers in the tree */
188static void
189init_parents(struct val_anchors* anchors)
190{
191	lock_basic_lock(&anchors->lock);
192	anchors_init_parents_locked(anchors);
193	lock_basic_unlock(&anchors->lock);
194}
195
196struct trust_anchor*
197anchor_find(struct val_anchors* anchors, uint8_t* name, int namelabs,
198	size_t namelen, uint16_t dclass)
199{
200	struct trust_anchor key;
201	rbnode_type* n;
202	if(!name) return NULL;
203	key.node.key = &key;
204	key.name = name;
205	key.namelabs = namelabs;
206	key.namelen = namelen;
207	key.dclass = dclass;
208	lock_basic_lock(&anchors->lock);
209	n = rbtree_search(anchors->tree, &key);
210	if(n) {
211		lock_basic_lock(&((struct trust_anchor*)n->key)->lock);
212	}
213	lock_basic_unlock(&anchors->lock);
214	if(!n)
215		return NULL;
216	return (struct trust_anchor*)n->key;
217}
218
219/** create new trust anchor object */
220static struct trust_anchor*
221anchor_new_ta(struct val_anchors* anchors, uint8_t* name, int namelabs,
222	size_t namelen, uint16_t dclass, int lockit)
223{
224#ifdef UNBOUND_DEBUG
225	rbnode_type* r;
226#endif
227	struct trust_anchor* ta = (struct trust_anchor*)malloc(
228		sizeof(struct trust_anchor));
229	if(!ta)
230		return NULL;
231	memset(ta, 0, sizeof(*ta));
232	ta->node.key = ta;
233	ta->name = memdup(name, namelen);
234	if(!ta->name) {
235		free(ta);
236		return NULL;
237	}
238	ta->namelabs = namelabs;
239	ta->namelen = namelen;
240	ta->dclass = dclass;
241	lock_basic_init(&ta->lock);
242	if(lockit) {
243		lock_basic_lock(&anchors->lock);
244	}
245#ifdef UNBOUND_DEBUG
246	r =
247#else
248	(void)
249#endif
250	rbtree_insert(anchors->tree, &ta->node);
251	if(lockit) {
252		lock_basic_unlock(&anchors->lock);
253	}
254	log_assert(r != NULL);
255	return ta;
256}
257
258/** find trustanchor key by exact data match */
259static struct ta_key*
260anchor_find_key(struct trust_anchor* ta, uint8_t* rdata, size_t rdata_len,
261	uint16_t type)
262{
263	struct ta_key* k;
264	for(k = ta->keylist; k; k = k->next) {
265		if(k->type == type && k->len == rdata_len &&
266			memcmp(k->data, rdata, rdata_len) == 0)
267			return k;
268	}
269	return NULL;
270}
271
272/** create new trustanchor key */
273static struct ta_key*
274anchor_new_ta_key(uint8_t* rdata, size_t rdata_len, uint16_t type)
275{
276	struct ta_key* k = (struct ta_key*)malloc(sizeof(*k));
277	if(!k)
278		return NULL;
279	memset(k, 0, sizeof(*k));
280	k->data = memdup(rdata, rdata_len);
281	if(!k->data) {
282		free(k);
283		return NULL;
284	}
285	k->len = rdata_len;
286	k->type = type;
287	return k;
288}
289
290/**
291 * This routine adds a new RR to a trust anchor. The trust anchor may not
292 * exist yet, and is created if not. The RR can be DS or DNSKEY.
293 * This routine will also remove duplicates; storing them only once.
294 * @param anchors: anchor storage.
295 * @param name: name of trust anchor (wireformat)
296 * @param type: type or RR
297 * @param dclass: class of RR
298 * @param rdata: rdata wireformat, starting with rdlength.
299 *	If NULL, nothing is stored, but an entry is created.
300 * @param rdata_len: length of rdata including rdlength.
301 * @return: NULL on error, else the trust anchor.
302 */
303static struct trust_anchor*
304anchor_store_new_key(struct val_anchors* anchors, uint8_t* name, uint16_t type,
305	uint16_t dclass, uint8_t* rdata, size_t rdata_len)
306{
307	struct ta_key* k;
308	struct trust_anchor* ta;
309	int namelabs;
310	size_t namelen;
311	namelabs = dname_count_size_labels(name, &namelen);
312	if(type != LDNS_RR_TYPE_DS && type != LDNS_RR_TYPE_DNSKEY) {
313		log_err("Bad type for trust anchor");
314		return 0;
315	}
316	/* lookup or create trustanchor */
317	ta = anchor_find(anchors, name, namelabs, namelen, dclass);
318	if(!ta) {
319		ta = anchor_new_ta(anchors, name, namelabs, namelen, dclass, 1);
320		if(!ta)
321			return NULL;
322		lock_basic_lock(&ta->lock);
323	}
324	if(!rdata) {
325		lock_basic_unlock(&ta->lock);
326		return ta;
327	}
328	/* look for duplicates */
329	if(anchor_find_key(ta, rdata, rdata_len, type)) {
330		lock_basic_unlock(&ta->lock);
331		return ta;
332	}
333	k = anchor_new_ta_key(rdata, rdata_len, type);
334	if(!k) {
335		lock_basic_unlock(&ta->lock);
336		return NULL;
337	}
338	/* add new key */
339	if(type == LDNS_RR_TYPE_DS)
340		ta->numDS++;
341	else	ta->numDNSKEY++;
342	k->next = ta->keylist;
343	ta->keylist = k;
344	lock_basic_unlock(&ta->lock);
345	return ta;
346}
347
348/**
349 * Add new RR. It converts ldns RR to wire format.
350 * @param anchors: anchor storage.
351 * @param rr: the wirerr.
352 * @param rl: length of rr.
353 * @param dl: length of dname.
354 * @return NULL on error, else the trust anchor.
355 */
356static struct trust_anchor*
357anchor_store_new_rr(struct val_anchors* anchors, uint8_t* rr, size_t rl,
358	size_t dl)
359{
360	struct trust_anchor* ta;
361	if(!(ta=anchor_store_new_key(anchors, rr,
362		sldns_wirerr_get_type(rr, rl, dl),
363		sldns_wirerr_get_class(rr, rl, dl),
364		sldns_wirerr_get_rdatawl(rr, rl, dl),
365		sldns_wirerr_get_rdatalen(rr, rl, dl)+2))) {
366		return NULL;
367	}
368	log_nametypeclass(VERB_QUERY, "adding trusted key",
369		rr, sldns_wirerr_get_type(rr, rl, dl),
370		sldns_wirerr_get_class(rr, rl, dl));
371	return ta;
372}
373
374/**
375 * Insert insecure anchor
376 * @param anchors: anchor storage.
377 * @param str: the domain name.
378 * @return NULL on error, Else last trust anchor point
379 */
380static struct trust_anchor*
381anchor_insert_insecure(struct val_anchors* anchors, const char* str)
382{
383	struct trust_anchor* ta;
384	size_t dname_len = 0;
385	uint8_t* nm = sldns_str2wire_dname(str, &dname_len);
386	if(!nm) {
387		log_err("parse error in domain name '%s'", str);
388		return NULL;
389	}
390	ta = anchor_store_new_key(anchors, nm, LDNS_RR_TYPE_DS,
391		LDNS_RR_CLASS_IN, NULL, 0);
392	free(nm);
393	return ta;
394}
395
396struct trust_anchor*
397anchor_store_str(struct val_anchors* anchors, sldns_buffer* buffer,
398	const char* str)
399{
400	struct trust_anchor* ta;
401	uint8_t* rr = sldns_buffer_begin(buffer);
402	size_t len = sldns_buffer_capacity(buffer), dname_len = 0;
403	int status = sldns_str2wire_rr_buf(str, rr, &len, &dname_len,
404		0, NULL, 0, NULL, 0);
405	if(status != 0) {
406		log_err("error parsing trust anchor %s: at %d: %s",
407			str, LDNS_WIREPARSE_OFFSET(status),
408			sldns_get_errorstr_parse(status));
409		return NULL;
410	}
411	if(!(ta=anchor_store_new_rr(anchors, rr, len, dname_len))) {
412		log_err("out of memory");
413		return NULL;
414	}
415	return ta;
416}
417
418/**
419 * Read a file with trust anchors
420 * @param anchors: anchor storage.
421 * @param buffer: parsing buffer.
422 * @param fname: string.
423 * @param onlyone: only one trust anchor allowed in file.
424 * @return NULL on error. Else last trust-anchor point.
425 */
426static struct trust_anchor*
427anchor_read_file(struct val_anchors* anchors, sldns_buffer* buffer,
428	const char* fname, int onlyone)
429{
430	struct trust_anchor* ta = NULL, *tanew;
431	struct sldns_file_parse_state pst;
432	int status;
433	size_t len, dname_len;
434	uint8_t* rr = sldns_buffer_begin(buffer);
435	int ok = 1;
436	FILE* in = fopen(fname, "r");
437	if(!in) {
438		log_err("error opening file %s: %s", fname, strerror(errno));
439		return 0;
440	}
441	memset(&pst, 0, sizeof(pst));
442	pst.default_ttl = 3600;
443	pst.lineno = 1;
444	while(!feof(in)) {
445		len = sldns_buffer_capacity(buffer);
446		dname_len = 0;
447		status = sldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst);
448		if(len == 0) /* empty, $TTL, $ORIGIN */
449			continue;
450		if(status != 0) {
451			log_err("parse error in %s:%d:%d : %s", fname,
452				pst.lineno, LDNS_WIREPARSE_OFFSET(status),
453				sldns_get_errorstr_parse(status));
454			ok = 0;
455			break;
456		}
457		if(sldns_wirerr_get_type(rr, len, dname_len) !=
458			LDNS_RR_TYPE_DS && sldns_wirerr_get_type(rr, len,
459			dname_len) != LDNS_RR_TYPE_DNSKEY) {
460			continue;
461		}
462		if(!(tanew=anchor_store_new_rr(anchors, rr, len, dname_len))) {
463			log_err("mem error at %s line %d", fname, pst.lineno);
464			ok = 0;
465			break;
466		}
467		if(onlyone && ta && ta != tanew) {
468			log_err("error at %s line %d: no multiple anchor "
469				"domains allowed (you can have multiple "
470				"keys, but they must have the same name).",
471				fname, pst.lineno);
472			ok = 0;
473			break;
474		}
475		ta = tanew;
476	}
477	fclose(in);
478	if(!ok) return NULL;
479	/* empty file is OK when multiple anchors are allowed */
480	if(!onlyone && !ta) return (struct trust_anchor*)1;
481	return ta;
482}
483
484/** skip file to end of line */
485static void
486skip_to_eol(FILE* in)
487{
488	int c;
489	while((c = getc(in)) != EOF ) {
490		if(c == '\n')
491			return;
492	}
493}
494
495/** true for special characters in bind configs */
496static int
497is_bind_special(int c)
498{
499	switch(c) {
500		case '{':
501		case '}':
502		case '"':
503		case ';':
504			return 1;
505	}
506	return 0;
507}
508
509/**
510 * Read a keyword skipping bind comments; spaces, specials, restkeywords.
511 * The file is split into the following tokens:
512 *	* special characters, on their own, rdlen=1, { } doublequote ;
513 *	* whitespace becomes a single ' ' or tab. Newlines become spaces.
514 *	* other words ('keywords')
515 *	* comments are skipped if desired
516 *		/ / C++ style comment to end of line
517 *		# to end of line
518 *		/ * C style comment * /
519 * @param in: file to read from.
520 * @param buf: buffer, what is read is stored after current buffer position.
521 *	Space is left in the buffer to write a terminating 0.
522 * @param line: line number is increased per line, for error reports.
523 * @param comments: if 0, comments are not possible and become text.
524 *	if 1, comments are skipped entirely.
525 *	In BIND files, this is when reading quoted strings, for example
526 *	" base 64 text with / / in there "
527 * @return the number of character written to the buffer.
528 *	0 on end of file.
529 */
530static int
531readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments)
532{
533	int c;
534	int numdone = 0;
535	while((c = getc(in)) != EOF ) {
536		if(comments && c == '#') {	/*   # blabla   */
537			skip_to_eol(in);
538			(*line)++;
539			continue;
540		} else if(comments && c=='/' && numdone>0 && /* /_/ bla*/
541			sldns_buffer_read_u8_at(buf,
542			sldns_buffer_position(buf)-1) == '/') {
543			sldns_buffer_skip(buf, -1);
544			numdone--;
545			skip_to_eol(in);
546			(*line)++;
547			continue;
548		} else if(comments && c=='*' && numdone>0 && /* /_* bla *_/ */
549			sldns_buffer_read_u8_at(buf,
550			sldns_buffer_position(buf)-1) == '/') {
551			sldns_buffer_skip(buf, -1);
552			numdone--;
553			/* skip to end of comment */
554			while(c != EOF && (c=getc(in)) != EOF ) {
555				if(c == '*') {
556					if((c=getc(in)) == '/')
557						break;
558				}
559				if(c == '\n')
560					(*line)++;
561			}
562			continue;
563		}
564		/* not a comment, complete the keyword */
565		if(numdone > 0) {
566			/* check same type */
567			if(isspace((unsigned char)c)) {
568				ungetc(c, in);
569				return numdone;
570			}
571			if(is_bind_special(c)) {
572				ungetc(c, in);
573				return numdone;
574			}
575		}
576		if(c == '\n') {
577			c = ' ';
578			(*line)++;
579		}
580		/* space for 1 char + 0 string terminator */
581		if(sldns_buffer_remaining(buf) < 2) {
582			fatal_exit("trusted-keys, %d, string too long", *line);
583		}
584		sldns_buffer_write_u8(buf, (uint8_t)c);
585		numdone++;
586		if(isspace((unsigned char)c)) {
587			/* collate whitespace into ' ' */
588			while((c = getc(in)) != EOF ) {
589				if(c == '\n')
590					(*line)++;
591				if(!isspace((unsigned char)c)) {
592					ungetc(c, in);
593					break;
594				}
595			}
596			return numdone;
597		}
598		if(is_bind_special(c))
599			return numdone;
600	}
601	return numdone;
602}
603
604/** skip through file to { or ; */
605static int
606skip_to_special(FILE* in, sldns_buffer* buf, int* line, int spec)
607{
608	int rdlen;
609	sldns_buffer_clear(buf);
610	while((rdlen=readkeyword_bindfile(in, buf, line, 1))) {
611		if(rdlen == 1 && isspace((unsigned char)*sldns_buffer_begin(buf))) {
612			sldns_buffer_clear(buf);
613			continue;
614		}
615		if(rdlen != 1 || *sldns_buffer_begin(buf) != (uint8_t)spec) {
616			sldns_buffer_write_u8(buf, 0);
617			log_err("trusted-keys, line %d, expected %c",
618				*line, spec);
619			return 0;
620		}
621		return 1;
622	}
623	log_err("trusted-keys, line %d, expected %c got EOF", *line, spec);
624	return 0;
625}
626
627/**
628 * read contents of trusted-keys{ ... ; clauses and insert keys into storage.
629 * @param anchors: where to store keys
630 * @param buf: buffer to use
631 * @param line: line number in file
632 * @param in: file to read from.
633 * @return 0 on error.
634 */
635static int
636process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf,
637	int* line, FILE* in)
638{
639	/* loop over contents, collate strings before ; */
640	/* contents is (numbered): 0   1    2  3 4   5  6 7 8    */
641	/*                           name. 257 3 5 base64 base64 */
642	/* quoted value:           0 "111"  0  0 0   0  0 0 0    */
643	/* comments value:         1 "000"  1  1  1 "0  0 0 0"  1 */
644	int contnum = 0;
645	int quoted = 0;
646	int comments = 1;
647	int rdlen;
648	char* str = 0;
649	sldns_buffer_clear(buf);
650	while((rdlen=readkeyword_bindfile(in, buf, line, comments))) {
651		if(rdlen == 1 && sldns_buffer_position(buf) == 1
652			&& isspace((unsigned char)*sldns_buffer_begin(buf))) {
653			/* starting whitespace is removed */
654			sldns_buffer_clear(buf);
655			continue;
656		} else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == '"') {
657			/* remove " from the string */
658			if(contnum == 0) {
659				quoted = 1;
660				comments = 0;
661			}
662			sldns_buffer_skip(buf, -1);
663			if(contnum > 0 && quoted) {
664				if(sldns_buffer_remaining(buf) < 8+1) {
665					log_err("line %d, too long", *line);
666					return 0;
667				}
668				sldns_buffer_write(buf, " DNSKEY ", 8);
669				quoted = 0;
670				comments = 1;
671			} else if(contnum > 0)
672				comments = !comments;
673			continue;
674		} else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == ';') {
675
676			if(contnum < 5) {
677				sldns_buffer_write_u8(buf, 0);
678				log_err("line %d, bad key", *line);
679				return 0;
680			}
681			sldns_buffer_skip(buf, -1);
682			sldns_buffer_write_u8(buf, 0);
683			str = strdup((char*)sldns_buffer_begin(buf));
684			if(!str) {
685				log_err("line %d, allocation failure", *line);
686				return 0;
687			}
688			if(!anchor_store_str(anchors, buf, str)) {
689				log_err("line %d, bad key", *line);
690				free(str);
691				return 0;
692			}
693			free(str);
694			sldns_buffer_clear(buf);
695			contnum = 0;
696			quoted = 0;
697			comments = 1;
698			continue;
699		} else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == '}') {
700			if(contnum > 0) {
701				sldns_buffer_write_u8(buf, 0);
702				log_err("line %d, bad key before }", *line);
703				return 0;
704			}
705			return 1;
706		} else if(rdlen == 1 &&
707			isspace((unsigned char)sldns_buffer_current(buf)[-1])) {
708			/* leave whitespace here */
709		} else {
710			/* not space or whatnot, so actual content */
711			contnum ++;
712			if(contnum == 1 && !quoted) {
713				if(sldns_buffer_remaining(buf) < 8+1) {
714					log_err("line %d, too long", *line);
715					return 0;
716				}
717				sldns_buffer_write(buf, " DNSKEY ", 8);
718			}
719		}
720	}
721
722	log_err("line %d, EOF before }", *line);
723	return 0;
724}
725
726/**
727 * Read a BIND9 like file with trust anchors in named.conf format.
728 * @param anchors: anchor storage.
729 * @param buffer: parsing buffer.
730 * @param fname: string.
731 * @return false on error.
732 */
733static int
734anchor_read_bind_file(struct val_anchors* anchors, sldns_buffer* buffer,
735	const char* fname)
736{
737	int line_nr = 1;
738	FILE* in = fopen(fname, "r");
739	int rdlen = 0;
740	if(!in) {
741		log_err("error opening file %s: %s", fname, strerror(errno));
742		return 0;
743	}
744	verbose(VERB_QUERY, "reading in bind-compat-mode: '%s'", fname);
745	/* scan for  trusted-keys  keyword, ignore everything else */
746	sldns_buffer_clear(buffer);
747	while((rdlen=readkeyword_bindfile(in, buffer, &line_nr, 1)) != 0) {
748		if(rdlen != 12 || strncmp((char*)sldns_buffer_begin(buffer),
749			"trusted-keys", 12) != 0) {
750			sldns_buffer_clear(buffer);
751			/* ignore everything but trusted-keys */
752			continue;
753		}
754		if(!skip_to_special(in, buffer, &line_nr, '{')) {
755			log_err("error in trusted key: \"%s\"", fname);
756			fclose(in);
757			return 0;
758		}
759		/* process contents */
760		if(!process_bind_contents(anchors, buffer, &line_nr, in)) {
761			log_err("error in trusted key: \"%s\"", fname);
762			fclose(in);
763			return 0;
764		}
765		if(!skip_to_special(in, buffer, &line_nr, ';')) {
766			log_err("error in trusted key: \"%s\"", fname);
767			fclose(in);
768			return 0;
769		}
770		sldns_buffer_clear(buffer);
771	}
772	fclose(in);
773	return 1;
774}
775
776/**
777 * Read a BIND9 like files with trust anchors in named.conf format.
778 * Performs wildcard processing of name.
779 * @param anchors: anchor storage.
780 * @param buffer: parsing buffer.
781 * @param pat: pattern string. (can be wildcarded)
782 * @return false on error.
783 */
784static int
785anchor_read_bind_file_wild(struct val_anchors* anchors, sldns_buffer* buffer,
786	const char* pat)
787{
788#ifdef HAVE_GLOB
789	glob_t g;
790	size_t i;
791	int r, flags;
792	if(!strchr(pat, '*') && !strchr(pat, '?') && !strchr(pat, '[') &&
793		!strchr(pat, '{') && !strchr(pat, '~')) {
794		return anchor_read_bind_file(anchors, buffer, pat);
795	}
796	verbose(VERB_QUERY, "wildcard found, processing %s", pat);
797	flags = 0
798#ifdef GLOB_ERR
799		| GLOB_ERR
800#endif
801#ifdef GLOB_NOSORT
802		| GLOB_NOSORT
803#endif
804#ifdef GLOB_BRACE
805		| GLOB_BRACE
806#endif
807#ifdef GLOB_TILDE
808		| GLOB_TILDE
809#endif
810	;
811	memset(&g, 0, sizeof(g));
812	r = glob(pat, flags, NULL, &g);
813	if(r) {
814		/* some error */
815		if(r == GLOB_NOMATCH) {
816			verbose(VERB_QUERY, "trusted-keys-file: "
817				"no matches for %s", pat);
818			return 1;
819		} else if(r == GLOB_NOSPACE) {
820			log_err("wildcard trusted-keys-file %s: "
821				"pattern out of memory", pat);
822		} else if(r == GLOB_ABORTED) {
823			log_err("wildcard trusted-keys-file %s: expansion "
824				"aborted (%s)", pat, strerror(errno));
825		} else {
826			log_err("wildcard trusted-keys-file %s: expansion "
827				"failed (%s)", pat, strerror(errno));
828		}
829		/* ignore globs that yield no files */
830		return 1;
831	}
832	/* process files found, if any */
833	for(i=0; i<(size_t)g.gl_pathc; i++) {
834		if(!anchor_read_bind_file(anchors, buffer, g.gl_pathv[i])) {
835			log_err("error reading wildcard "
836				"trusted-keys-file: %s", g.gl_pathv[i]);
837			globfree(&g);
838			return 0;
839		}
840	}
841	globfree(&g);
842	return 1;
843#else /* not HAVE_GLOB */
844	return anchor_read_bind_file(anchors, buffer, pat);
845#endif /* HAVE_GLOB */
846}
847
848/**
849 * Assemble an rrset structure for the type
850 * @param ta: trust anchor.
851 * @param num: number of items to fetch from list.
852 * @param type: fetch only items of this type.
853 * @return rrset or NULL on error.
854 */
855static struct ub_packed_rrset_key*
856assemble_it(struct trust_anchor* ta, size_t num, uint16_t type)
857{
858	struct ub_packed_rrset_key* pkey = (struct ub_packed_rrset_key*)
859		malloc(sizeof(*pkey));
860	struct packed_rrset_data* pd;
861	struct ta_key* tk;
862	size_t i;
863	if(!pkey)
864		return NULL;
865	memset(pkey, 0, sizeof(*pkey));
866	pkey->rk.dname = memdup(ta->name, ta->namelen);
867	if(!pkey->rk.dname) {
868		free(pkey);
869		return NULL;
870	}
871
872	pkey->rk.dname_len = ta->namelen;
873	pkey->rk.type = htons(type);
874	pkey->rk.rrset_class = htons(ta->dclass);
875	/* The rrset is build in an uncompressed way. This means it
876	 * cannot be copied in the normal way. */
877	pd = (struct packed_rrset_data*)malloc(sizeof(*pd));
878	if(!pd) {
879		free(pkey->rk.dname);
880		free(pkey);
881		return NULL;
882	}
883	memset(pd, 0, sizeof(*pd));
884	pd->count = num;
885	pd->trust = rrset_trust_ultimate;
886	pd->rr_len = (size_t*)reallocarray(NULL, num, sizeof(size_t));
887	if(!pd->rr_len) {
888		free(pd);
889		free(pkey->rk.dname);
890		free(pkey);
891		return NULL;
892	}
893	pd->rr_ttl = (time_t*)reallocarray(NULL, num, sizeof(time_t));
894	if(!pd->rr_ttl) {
895		free(pd->rr_len);
896		free(pd);
897		free(pkey->rk.dname);
898		free(pkey);
899		return NULL;
900	}
901	pd->rr_data = (uint8_t**)reallocarray(NULL, num, sizeof(uint8_t*));
902	if(!pd->rr_data) {
903		free(pd->rr_ttl);
904		free(pd->rr_len);
905		free(pd);
906		free(pkey->rk.dname);
907		free(pkey);
908		return NULL;
909	}
910	/* fill in rrs */
911	i=0;
912	for(tk = ta->keylist; tk; tk = tk->next) {
913		if(tk->type != type)
914			continue;
915		pd->rr_len[i] = tk->len;
916		/* reuse data ptr to allocation in talist */
917		pd->rr_data[i] = tk->data;
918		pd->rr_ttl[i] = 0;
919		i++;
920	}
921	pkey->entry.data = (void*)pd;
922	return pkey;
923}
924
925/**
926 * Assemble structures for the trust DS and DNSKEY rrsets.
927 * @param ta: trust anchor
928 * @return: false on error.
929 */
930static int
931anchors_assemble(struct trust_anchor* ta)
932{
933	if(ta->numDS > 0) {
934		ta->ds_rrset = assemble_it(ta, ta->numDS, LDNS_RR_TYPE_DS);
935		if(!ta->ds_rrset)
936			return 0;
937	}
938	if(ta->numDNSKEY > 0) {
939		ta->dnskey_rrset = assemble_it(ta, ta->numDNSKEY,
940			LDNS_RR_TYPE_DNSKEY);
941		if(!ta->dnskey_rrset)
942			return 0;
943	}
944	return 1;
945}
946
947/**
948 * Check DS algos for support, warn if not.
949 * @param ta: trust anchor
950 * @return number of DS anchors with unsupported algorithms.
951 */
952static size_t
953anchors_ds_unsupported(struct trust_anchor* ta)
954{
955	size_t i, num = 0;
956	for(i=0; i<ta->numDS; i++) {
957		if(!ds_digest_algo_is_supported(ta->ds_rrset, i) ||
958			!ds_key_algo_is_supported(ta->ds_rrset, i))
959			num++;
960	}
961	return num;
962}
963
964/**
965 * Check DNSKEY algos for support, warn if not.
966 * @param ta: trust anchor
967 * @return number of DNSKEY anchors with unsupported algorithms.
968 */
969static size_t
970anchors_dnskey_unsupported(struct trust_anchor* ta)
971{
972	size_t i, num = 0;
973	for(i=0; i<ta->numDNSKEY; i++) {
974		if(!dnskey_algo_is_supported(ta->dnskey_rrset, i))
975			num++;
976	}
977	return num;
978}
979
980/**
981 * Assemble the rrsets in the anchors, ready for use by validator.
982 * @param anchors: trust anchor storage.
983 * @return: false on error.
984 */
985static int
986anchors_assemble_rrsets(struct val_anchors* anchors)
987{
988	struct trust_anchor* ta;
989	struct trust_anchor* next;
990	size_t nods, nokey;
991	lock_basic_lock(&anchors->lock);
992	ta=(struct trust_anchor*)rbtree_first(anchors->tree);
993	while((rbnode_type*)ta != RBTREE_NULL) {
994		next = (struct trust_anchor*)rbtree_next(&ta->node);
995		lock_basic_lock(&ta->lock);
996		if(ta->autr || (ta->numDS == 0 && ta->numDNSKEY == 0)) {
997			lock_basic_unlock(&ta->lock);
998			ta = next; /* skip */
999			continue;
1000		}
1001		if(!anchors_assemble(ta)) {
1002			log_err("out of memory");
1003			lock_basic_unlock(&ta->lock);
1004			lock_basic_unlock(&anchors->lock);
1005			return 0;
1006		}
1007		nods = anchors_ds_unsupported(ta);
1008		nokey = anchors_dnskey_unsupported(ta);
1009		if(nods) {
1010			log_nametypeclass(NO_VERBOSE, "warning: unsupported "
1011				"algorithm for trust anchor",
1012				ta->name, LDNS_RR_TYPE_DS, ta->dclass);
1013		}
1014		if(nokey) {
1015			log_nametypeclass(NO_VERBOSE, "warning: unsupported "
1016				"algorithm for trust anchor",
1017				ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
1018		}
1019		if(nods == ta->numDS && nokey == ta->numDNSKEY) {
1020			char b[257];
1021			dname_str(ta->name, b);
1022			log_warn("trust anchor %s has no supported algorithms,"
1023				" the anchor is ignored (check if you need to"
1024				" upgrade unbound and "
1025#ifdef HAVE_LIBRESSL
1026				"libressl"
1027#else
1028				"openssl"
1029#endif
1030				")", b);
1031			(void)rbtree_delete(anchors->tree, &ta->node);
1032			lock_basic_unlock(&ta->lock);
1033			if(anchors->dlv_anchor == ta)
1034				anchors->dlv_anchor = NULL;
1035			anchors_delfunc(&ta->node, NULL);
1036			ta = next;
1037			continue;
1038		}
1039		lock_basic_unlock(&ta->lock);
1040		ta = next;
1041	}
1042	lock_basic_unlock(&anchors->lock);
1043	return 1;
1044}
1045
1046int
1047anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
1048{
1049	struct config_strlist* f;
1050	const char** zstr;
1051	char* nm;
1052	sldns_buffer* parsebuf = sldns_buffer_new(65535);
1053	if(cfg->insecure_lan_zones) {
1054		for(zstr = as112_zones; *zstr; zstr++) {
1055			if(!anchor_insert_insecure(anchors, *zstr)) {
1056				log_err("error in insecure-lan-zones: %s", *zstr);
1057				sldns_buffer_free(parsebuf);
1058				return 0;
1059			}
1060		}
1061	}
1062	for(f = cfg->domain_insecure; f; f = f->next) {
1063		if(!f->str || f->str[0] == 0) /* empty "" */
1064			continue;
1065		if(!anchor_insert_insecure(anchors, f->str)) {
1066			log_err("error in domain-insecure: %s", f->str);
1067			sldns_buffer_free(parsebuf);
1068			return 0;
1069		}
1070	}
1071	for(f = cfg->trust_anchor_file_list; f; f = f->next) {
1072		if(!f->str || f->str[0] == 0) /* empty "" */
1073			continue;
1074		nm = f->str;
1075		if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
1076			cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
1077			nm += strlen(cfg->chrootdir);
1078		if(!anchor_read_file(anchors, parsebuf, nm, 0)) {
1079			log_err("error reading trust-anchor-file: %s", f->str);
1080			sldns_buffer_free(parsebuf);
1081			return 0;
1082		}
1083	}
1084	for(f = cfg->trusted_keys_file_list; f; f = f->next) {
1085		if(!f->str || f->str[0] == 0) /* empty "" */
1086			continue;
1087		nm = f->str;
1088		if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
1089			cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
1090			nm += strlen(cfg->chrootdir);
1091		if(!anchor_read_bind_file_wild(anchors, parsebuf, nm)) {
1092			log_err("error reading trusted-keys-file: %s", f->str);
1093			sldns_buffer_free(parsebuf);
1094			return 0;
1095		}
1096	}
1097	for(f = cfg->trust_anchor_list; f; f = f->next) {
1098		if(!f->str || f->str[0] == 0) /* empty "" */
1099			continue;
1100		if(!anchor_store_str(anchors, parsebuf, f->str)) {
1101			log_err("error in trust-anchor: \"%s\"", f->str);
1102			sldns_buffer_free(parsebuf);
1103			return 0;
1104		}
1105	}
1106	if(cfg->dlv_anchor_file && cfg->dlv_anchor_file[0] != 0) {
1107		struct trust_anchor* dlva;
1108		nm = cfg->dlv_anchor_file;
1109		if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
1110			cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
1111			nm += strlen(cfg->chrootdir);
1112		if(!(dlva = anchor_read_file(anchors, parsebuf,
1113			nm, 1))) {
1114			log_err("error reading dlv-anchor-file: %s",
1115				cfg->dlv_anchor_file);
1116			sldns_buffer_free(parsebuf);
1117			return 0;
1118		}
1119		lock_basic_lock(&anchors->lock);
1120		anchors->dlv_anchor = dlva;
1121		lock_basic_unlock(&anchors->lock);
1122	}
1123	for(f = cfg->dlv_anchor_list; f; f = f->next) {
1124		struct trust_anchor* dlva;
1125		if(!f->str || f->str[0] == 0) /* empty "" */
1126			continue;
1127		if(!(dlva = anchor_store_str(
1128			anchors, parsebuf, f->str))) {
1129			log_err("error in dlv-anchor: \"%s\"", f->str);
1130			sldns_buffer_free(parsebuf);
1131			return 0;
1132		}
1133		lock_basic_lock(&anchors->lock);
1134		anchors->dlv_anchor = dlva;
1135		lock_basic_unlock(&anchors->lock);
1136	}
1137	/* do autr last, so that it sees what anchors are filled by other
1138	 * means can can print errors about double config for the name */
1139	for(f = cfg->auto_trust_anchor_file_list; f; f = f->next) {
1140		if(!f->str || f->str[0] == 0) /* empty "" */
1141			continue;
1142		nm = f->str;
1143		if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
1144			cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
1145			nm += strlen(cfg->chrootdir);
1146		if(!autr_read_file(anchors, nm)) {
1147			log_err("error reading auto-trust-anchor-file: %s",
1148				f->str);
1149			sldns_buffer_free(parsebuf);
1150			return 0;
1151		}
1152	}
1153	/* first assemble, since it may delete useless anchors */
1154	anchors_assemble_rrsets(anchors);
1155	init_parents(anchors);
1156	sldns_buffer_free(parsebuf);
1157	if(verbosity >= VERB_ALGO) autr_debug_print(anchors);
1158	return 1;
1159}
1160
1161struct trust_anchor*
1162anchors_lookup(struct val_anchors* anchors,
1163        uint8_t* qname, size_t qname_len, uint16_t qclass)
1164{
1165	struct trust_anchor key;
1166	struct trust_anchor* result;
1167	rbnode_type* res = NULL;
1168	key.node.key = &key;
1169	key.name = qname;
1170	key.namelabs = dname_count_labels(qname);
1171	key.namelen = qname_len;
1172	key.dclass = qclass;
1173	lock_basic_lock(&anchors->lock);
1174	if(rbtree_find_less_equal(anchors->tree, &key, &res)) {
1175		/* exact */
1176		result = (struct trust_anchor*)res;
1177	} else {
1178		/* smaller element (or no element) */
1179		int m;
1180		result = (struct trust_anchor*)res;
1181		if(!result || result->dclass != qclass) {
1182			lock_basic_unlock(&anchors->lock);
1183			return NULL;
1184		}
1185		/* count number of labels matched */
1186		(void)dname_lab_cmp(result->name, result->namelabs, key.name,
1187			key.namelabs, &m);
1188		while(result) { /* go up until qname is subdomain of stub */
1189			if(result->namelabs <= m)
1190				break;
1191			result = result->parent;
1192		}
1193	}
1194	if(result) {
1195		lock_basic_lock(&result->lock);
1196	}
1197	lock_basic_unlock(&anchors->lock);
1198	return result;
1199}
1200
1201size_t
1202anchors_get_mem(struct val_anchors* anchors)
1203{
1204	struct trust_anchor *ta;
1205	size_t s = sizeof(*anchors);
1206	if(!anchors)
1207		return 0;
1208	RBTREE_FOR(ta, struct trust_anchor*, anchors->tree) {
1209		s += sizeof(*ta) + ta->namelen;
1210		/* keys and so on */
1211	}
1212	return s;
1213}
1214
1215int
1216anchors_add_insecure(struct val_anchors* anchors, uint16_t c, uint8_t* nm)
1217{
1218	struct trust_anchor key;
1219	key.node.key = &key;
1220	key.name = nm;
1221	key.namelabs = dname_count_size_labels(nm, &key.namelen);
1222	key.dclass = c;
1223	lock_basic_lock(&anchors->lock);
1224	if(rbtree_search(anchors->tree, &key)) {
1225		lock_basic_unlock(&anchors->lock);
1226		/* nothing to do, already an anchor or insecure point */
1227		return 1;
1228	}
1229	if(!anchor_new_ta(anchors, nm, key.namelabs, key.namelen, c, 0)) {
1230		log_err("out of memory");
1231		lock_basic_unlock(&anchors->lock);
1232		return 0;
1233	}
1234	/* no other contents in new ta, because it is insecure point */
1235	anchors_init_parents_locked(anchors);
1236	lock_basic_unlock(&anchors->lock);
1237	return 1;
1238}
1239
1240void
1241anchors_delete_insecure(struct val_anchors* anchors, uint16_t c,
1242        uint8_t* nm)
1243{
1244	struct trust_anchor key;
1245	struct trust_anchor* ta;
1246	key.node.key = &key;
1247	key.name = nm;
1248	key.namelabs = dname_count_size_labels(nm, &key.namelen);
1249	key.dclass = c;
1250	lock_basic_lock(&anchors->lock);
1251	if(!(ta=(struct trust_anchor*)rbtree_search(anchors->tree, &key))) {
1252		lock_basic_unlock(&anchors->lock);
1253		/* nothing there */
1254		return;
1255	}
1256	/* lock it to drive away other threads that use it */
1257	lock_basic_lock(&ta->lock);
1258	/* see if its really an insecure point */
1259	if(ta->keylist || ta->autr || ta->numDS || ta->numDNSKEY) {
1260		lock_basic_unlock(&anchors->lock);
1261		lock_basic_unlock(&ta->lock);
1262		/* its not an insecure point, do not remove it */
1263		return;
1264	}
1265
1266	/* remove from tree */
1267	(void)rbtree_delete(anchors->tree, &ta->node);
1268	anchors_init_parents_locked(anchors);
1269	lock_basic_unlock(&anchors->lock);
1270
1271	/* actual free of data */
1272	lock_basic_unlock(&ta->lock);
1273	anchors_delfunc(&ta->node, NULL);
1274}
1275
1276/** compare two keytags, return -1, 0 or 1 */
1277static int
1278keytag_compare(const void* x, const void* y)
1279{
1280	if(*(uint16_t*)x == *(uint16_t*)y)
1281		return 0;
1282	if(*(uint16_t*)x > *(uint16_t*)y)
1283		return 1;
1284	return -1;
1285}
1286
1287size_t
1288anchor_list_keytags(struct trust_anchor* ta, uint16_t* list, size_t num)
1289{
1290	size_t i, ret = 0;
1291	if(ta->numDS == 0 && ta->numDNSKEY == 0)
1292		return 0; /* insecure point */
1293	if(ta->numDS != 0 && ta->ds_rrset) {
1294		struct packed_rrset_data* d=(struct packed_rrset_data*)
1295			ta->ds_rrset->entry.data;
1296		for(i=0; i<d->count; i++) {
1297			if(ret == num) continue;
1298			list[ret++] = ds_get_keytag(ta->ds_rrset, i);
1299		}
1300	}
1301	if(ta->numDNSKEY != 0 && ta->dnskey_rrset) {
1302		struct packed_rrset_data* d=(struct packed_rrset_data*)
1303			ta->dnskey_rrset->entry.data;
1304		for(i=0; i<d->count; i++) {
1305			if(ret == num) continue;
1306			list[ret++] = dnskey_calc_keytag(ta->dnskey_rrset, i);
1307		}
1308	}
1309	qsort(list, ret, sizeof(*list), keytag_compare);
1310	return ret;
1311}
1312
1313int
1314anchor_has_keytag(struct val_anchors* anchors, uint8_t* name, int namelabs,
1315	size_t namelen, uint16_t dclass, uint16_t keytag)
1316{
1317	uint16_t* taglist;
1318	uint16_t* tl;
1319	size_t numtag, i;
1320	struct trust_anchor* anchor = anchor_find(anchors,
1321		name, namelabs, namelen, dclass);
1322	if(!anchor)
1323		return 0;
1324	if(!anchor->numDS && !anchor->numDNSKEY) {
1325		lock_basic_unlock(&anchor->lock);
1326		return 0;
1327	}
1328
1329	taglist = calloc(anchor->numDS + anchor->numDNSKEY, sizeof(*taglist));
1330	if(!taglist) {
1331		lock_basic_unlock(&anchor->lock);
1332		return 0;
1333	}
1334
1335	numtag = anchor_list_keytags(anchor, taglist,
1336		anchor->numDS+anchor->numDNSKEY);
1337	lock_basic_unlock(&anchor->lock);
1338	if(!numtag) {
1339		free(taglist);
1340		return 0;
1341	}
1342	tl = taglist;
1343	for(i=0; i<numtag; i++) {
1344		if(*tl == keytag) {
1345			free(taglist);
1346			return 1;
1347		}
1348		tl++;
1349	}
1350	free(taglist);
1351	return 0;
1352}
1353