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