Coverage Report

Created: 2025-07-18 07:00

/src/unbound/validator/autotrust.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * validator/autotrust.c - RFC5011 trust anchor management for unbound.
3
 *
4
 * Copyright (c) 2009, 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
 * Contains autotrust implementation. The implementation was taken from 
40
 * the autotrust daemon (BSD licensed), written by Matthijs Mekking.
41
 * It was modified to fit into unbound. The state table process is the same.
42
 */
43
#include "config.h"
44
#include "validator/autotrust.h"
45
#include "validator/val_anchor.h"
46
#include "validator/val_utils.h"
47
#include "validator/val_sigcrypt.h"
48
#include "util/data/dname.h"
49
#include "util/data/packed_rrset.h"
50
#include "util/log.h"
51
#include "util/module.h"
52
#include "util/net_help.h"
53
#include "util/config_file.h"
54
#include "util/regional.h"
55
#include "util/random.h"
56
#include "util/data/msgparse.h"
57
#include "services/mesh.h"
58
#include "services/cache/rrset.h"
59
#include "validator/val_kcache.h"
60
#include "sldns/sbuffer.h"
61
#include "sldns/wire2str.h"
62
#include "sldns/str2wire.h"
63
#include "sldns/keyraw.h"
64
#include "sldns/rrdef.h"
65
#include <stdarg.h>
66
#include <ctype.h>
67
68
/** number of times a key must be seen before it can become valid */
69
0
#define MIN_PENDINGCOUNT 2
70
71
/** Event: Revoked */
72
static void do_revoked(struct module_env* env, struct autr_ta* anchor, int* c);
73
74
struct autr_global_data* autr_global_create(void)
75
0
{
76
0
  struct autr_global_data* global;
77
0
  global = (struct autr_global_data*)malloc(sizeof(*global));
78
0
  if(!global) 
79
0
    return NULL;
80
0
  rbtree_init(&global->probe, &probetree_cmp);
81
0
  return global;
82
0
}
83
84
void autr_global_delete(struct autr_global_data* global)
85
0
{
86
0
  if(!global)
87
0
    return;
88
  /* elements deleted by parent */
89
0
  free(global);
90
0
}
91
92
int probetree_cmp(const void* x, const void* y)
93
0
{
94
0
  struct trust_anchor* a = (struct trust_anchor*)x;
95
0
  struct trust_anchor* b = (struct trust_anchor*)y;
96
0
  log_assert(a->autr && b->autr);
97
0
  if(a->autr->next_probe_time < b->autr->next_probe_time)
98
0
    return -1;
99
0
  if(a->autr->next_probe_time > b->autr->next_probe_time)
100
0
    return 1;
101
  /* time is equal, sort on trust point identity */
102
0
  return anchor_cmp(x, y);
103
0
}
104
105
size_t 
106
autr_get_num_anchors(struct val_anchors* anchors)
107
0
{
108
0
  size_t res = 0;
109
0
  if(!anchors)
110
0
    return 0;
111
0
  lock_basic_lock(&anchors->lock);
112
0
  if(anchors->autr)
113
0
    res = anchors->autr->probe.count;
114
0
  lock_basic_unlock(&anchors->lock);
115
0
  return res;
116
0
}
117
118
/** Position in string */
119
static int
120
position_in_string(char *str, const char* sub)
121
0
{
122
0
  char* pos = strstr(str, sub);
123
0
  if(pos)
124
0
    return (int)(pos-str)+(int)strlen(sub);
125
0
  return -1;
126
0
}
127
128
/** Debug routine to print pretty key information */
129
static void
130
verbose_key(struct autr_ta* ta, enum verbosity_value level, 
131
  const char* format, ...) ATTR_FORMAT(printf, 3, 4);
132
133
/** 
134
 * Implementation of debug pretty key print 
135
 * @param ta: trust anchor key with DNSKEY data.
136
 * @param level: verbosity level to print at.
137
 * @param format: printf style format string.
138
 */
139
static void
140
verbose_key(struct autr_ta* ta, enum verbosity_value level, 
141
  const char* format, ...) 
142
0
{
143
0
  va_list args;
144
0
  va_start(args, format);
145
0
  if(verbosity >= level) {
146
0
    char* str = sldns_wire2str_dname(ta->rr, ta->dname_len);
147
0
    int keytag = (int)sldns_calc_keytag_raw(sldns_wirerr_get_rdata(
148
0
      ta->rr, ta->rr_len, ta->dname_len),
149
0
      sldns_wirerr_get_rdatalen(ta->rr, ta->rr_len,
150
0
      ta->dname_len));
151
0
    char msg[MAXSYSLOGMSGLEN];
152
0
    vsnprintf(msg, sizeof(msg), format, args);
153
0
    verbose(level, "%s key %d %s", str?str:"??", keytag, msg);
154
0
    free(str);
155
0
  }
156
0
  va_end(args);
157
0
}
158
159
/** 
160
 * Parse comments 
161
 * @param str: to parse
162
 * @param ta: trust key autotrust metadata
163
 * @return false on failure.
164
 */
165
static int
166
parse_comments(char* str, struct autr_ta* ta)
167
0
{
168
0
        int len = (int)strlen(str), pos = 0, timestamp = 0;
169
0
        char* comment = (char*) malloc(sizeof(char)*len+1);
170
0
        char* comments = comment;
171
0
  if(!comment) {
172
0
    log_err("malloc failure in parse");
173
0
                return 0;
174
0
  }
175
  /* skip over whitespace and data at start of line */
176
0
        while (*str != '\0' && *str != ';')
177
0
                str++;
178
0
        if (*str == ';')
179
0
                str++;
180
        /* copy comments */
181
0
        while (*str != '\0')
182
0
        {
183
0
                *comments = *str;
184
0
                comments++;
185
0
                str++;
186
0
        }
187
0
        *comments = '\0';
188
189
0
        comments = comment;
190
191
        /* read state */
192
0
        pos = position_in_string(comments, "state=");
193
0
        if (pos >= (int) strlen(comments))
194
0
        {
195
0
    log_err("parse error");
196
0
                free(comment);
197
0
                return 0;
198
0
        }
199
0
        if (pos <= 0)
200
0
                ta->s = AUTR_STATE_VALID;
201
0
        else
202
0
        {
203
0
                int s = (int) comments[pos] - '0';
204
0
                switch(s)
205
0
                {
206
0
                        case AUTR_STATE_START:
207
0
                        case AUTR_STATE_ADDPEND:
208
0
                        case AUTR_STATE_VALID:
209
0
                        case AUTR_STATE_MISSING:
210
0
                        case AUTR_STATE_REVOKED:
211
0
                        case AUTR_STATE_REMOVED:
212
0
                                ta->s = s;
213
0
                                break;
214
0
                        default:
215
0
        verbose_key(ta, VERB_OPS, "has undefined "
216
0
          "state, considered NewKey");
217
0
                                ta->s = AUTR_STATE_START;
218
0
                                break;
219
0
                }
220
0
        }
221
        /* read pending count */
222
0
        pos = position_in_string(comments, "count=");
223
0
        if (pos >= (int) strlen(comments))
224
0
        {
225
0
    log_err("parse error");
226
0
                free(comment);
227
0
                return 0;
228
0
        }
229
0
        if (pos <= 0)
230
0
                ta->pending_count = 0;
231
0
        else
232
0
        {
233
0
                comments += pos;
234
0
                ta->pending_count = (uint8_t)atoi(comments);
235
0
        }
236
237
        /* read last change */
238
0
        pos = position_in_string(comments, "lastchange=");
239
0
        if (pos >= (int) strlen(comments))
240
0
        {
241
0
    log_err("parse error");
242
0
                free(comment);
243
0
                return 0;
244
0
        }
245
0
        if (pos >= 0)
246
0
        {
247
0
                comments += pos;
248
0
                timestamp = atoi(comments);
249
0
        }
250
0
        if (pos < 0 || !timestamp)
251
0
    ta->last_change = 0;
252
0
        else
253
0
                ta->last_change = (time_t)timestamp;
254
255
0
        free(comment);
256
0
        return 1;
257
0
}
258
259
/** Check if a line contains data (besides comments) */
260
static int
261
str_contains_data(char* str, char comment)
262
0
{
263
0
        while (*str != '\0') {
264
0
                if (*str == comment || *str == '\n')
265
0
                        return 0;
266
0
                if (*str != ' ' && *str != '\t')
267
0
                        return 1;
268
0
                str++;
269
0
        }
270
0
        return 0;
271
0
}
272
273
/** Get DNSKEY flags
274
 * rdata without rdatalen in front of it. */
275
static int
276
dnskey_flags(uint16_t t, uint8_t* rdata, size_t len)
277
0
{
278
0
  uint16_t f;
279
0
  if(t != LDNS_RR_TYPE_DNSKEY)
280
0
    return 0;
281
0
  if(len < 2)
282
0
    return 0;
283
0
  memmove(&f, rdata, 2);
284
0
  f = ntohs(f);
285
0
  return (int)f;
286
0
}
287
288
/** Check if KSK DNSKEY.
289
 * pass rdata without rdatalen in front of it */
290
static int
291
rr_is_dnskey_sep(uint16_t t, uint8_t* rdata, size_t len)
292
0
{
293
0
  return (dnskey_flags(t, rdata, len)&DNSKEY_BIT_SEP);
294
0
}
295
296
/** Check if TA is KSK DNSKEY */
297
static int
298
ta_is_dnskey_sep(struct autr_ta* ta)
299
0
{
300
0
  return (dnskey_flags(
301
0
    sldns_wirerr_get_type(ta->rr, ta->rr_len, ta->dname_len),
302
0
    sldns_wirerr_get_rdata(ta->rr, ta->rr_len, ta->dname_len),
303
0
    sldns_wirerr_get_rdatalen(ta->rr, ta->rr_len, ta->dname_len)
304
0
    ) & DNSKEY_BIT_SEP);
305
0
}
306
307
/** Check if REVOKED DNSKEY
308
 * pass rdata without rdatalen in front of it */
309
static int
310
rr_is_dnskey_revoked(uint16_t t, uint8_t* rdata, size_t len)
311
0
{
312
0
  return (dnskey_flags(t, rdata, len)&LDNS_KEY_REVOKE_KEY);
313
0
}
314
315
/** create ta */
316
static struct autr_ta*
317
autr_ta_create(uint8_t* rr, size_t rr_len, size_t dname_len)
318
0
{
319
0
  struct autr_ta* ta = (struct autr_ta*)calloc(1, sizeof(*ta));
320
0
  if(!ta) {
321
0
    free(rr);
322
0
    return NULL;
323
0
  }
324
0
  ta->rr = rr;
325
0
  ta->rr_len = rr_len;
326
0
  ta->dname_len = dname_len;
327
0
  return ta;
328
0
}
329
330
/** create tp */
331
static struct trust_anchor*
332
autr_tp_create(struct val_anchors* anchors, uint8_t* own, size_t own_len,
333
  uint16_t dc)
334
0
{
335
0
  struct trust_anchor* tp = (struct trust_anchor*)calloc(1, sizeof(*tp));
336
0
  if(!tp) return NULL;
337
0
  tp->name = memdup(own, own_len);
338
0
  if(!tp->name) {
339
0
    free(tp);
340
0
    return NULL;
341
0
  }
342
0
  tp->namelen = own_len;
343
0
  tp->namelabs = dname_count_labels(tp->name);
344
0
  tp->node.key = tp;
345
0
  tp->dclass = dc;
346
0
  tp->autr = (struct autr_point_data*)calloc(1, sizeof(*tp->autr));
347
0
  if(!tp->autr) {
348
0
    free(tp->name);
349
0
    free(tp);
350
0
    return NULL;
351
0
  }
352
0
  tp->autr->pnode.key = tp;
353
354
0
  lock_basic_lock(&anchors->lock);
355
0
  if(!rbtree_insert(anchors->tree, &tp->node)) {
356
0
    char buf[LDNS_MAX_DOMAINLEN];
357
0
    lock_basic_unlock(&anchors->lock);
358
0
    dname_str(tp->name, buf);
359
0
    log_err("trust anchor for '%s' presented twice", buf);
360
0
    free(tp->name);
361
0
    free(tp->autr);
362
0
    free(tp);
363
0
    return NULL;
364
0
  }
365
0
  if(!rbtree_insert(&anchors->autr->probe, &tp->autr->pnode)) {
366
0
    char buf[LDNS_MAX_DOMAINLEN];
367
0
    (void)rbtree_delete(anchors->tree, tp);
368
0
    lock_basic_unlock(&anchors->lock);
369
0
    dname_str(tp->name, buf);
370
0
    log_err("trust anchor for '%s' in probetree twice", buf);
371
0
    free(tp->name);
372
0
    free(tp->autr);
373
0
    free(tp);
374
0
    return NULL;
375
0
  }
376
0
  lock_basic_init(&tp->lock);
377
0
  lock_protect(&tp->lock, tp, sizeof(*tp));
378
0
  lock_protect(&tp->lock, tp->autr, sizeof(*tp->autr));
379
0
  lock_basic_unlock(&anchors->lock);
380
0
  return tp;
381
0
}
382
383
/** delete assembled rrsets */
384
static void
385
autr_rrset_delete(struct ub_packed_rrset_key* r)
386
0
{
387
0
  if(r) {
388
0
    free(r->rk.dname);
389
0
    free(r->entry.data);
390
0
    free(r);
391
0
  }
392
0
}
393
394
void autr_point_delete(struct trust_anchor* tp)
395
0
{
396
0
  if(!tp)
397
0
    return;
398
0
  lock_unprotect(&tp->lock, tp);
399
0
  lock_unprotect(&tp->lock, tp->autr);
400
0
  lock_basic_destroy(&tp->lock);
401
0
  autr_rrset_delete(tp->ds_rrset);
402
0
  autr_rrset_delete(tp->dnskey_rrset);
403
0
  if(tp->autr) {
404
0
    struct autr_ta* p = tp->autr->keys, *np;
405
0
    while(p) {
406
0
      np = p->next;
407
0
      free(p->rr);
408
0
      free(p);
409
0
      p = np;
410
0
    }
411
0
    free(tp->autr->file);
412
0
    free(tp->autr);
413
0
  }
414
0
  free(tp->name);
415
0
  free(tp);
416
0
}
417
418
/** find or add a new trust point for autotrust */
419
static struct trust_anchor*
420
find_add_tp(struct val_anchors* anchors, uint8_t* rr, size_t rr_len,
421
  size_t dname_len)
422
0
{
423
0
  struct trust_anchor* tp;
424
0
  tp = anchor_find(anchors, rr, dname_count_labels(rr), dname_len,
425
0
    sldns_wirerr_get_class(rr, rr_len, dname_len));
426
0
  if(tp) {
427
0
    if(!tp->autr) {
428
0
      log_err("anchor cannot be with and without autotrust");
429
0
      lock_basic_unlock(&tp->lock);
430
0
      return NULL;
431
0
    }
432
0
    return tp;
433
0
  }
434
0
  tp = autr_tp_create(anchors, rr, dname_len, sldns_wirerr_get_class(rr,
435
0
    rr_len, dname_len));
436
0
  if(!tp) 
437
0
    return NULL;
438
0
  lock_basic_lock(&tp->lock);
439
0
  return tp;
440
0
}
441
442
/** Add trust anchor from RR */
443
static struct autr_ta*
444
add_trustanchor_frm_rr(struct val_anchors* anchors, uint8_t* rr, size_t rr_len,
445
        size_t dname_len, struct trust_anchor** tp)
446
0
{
447
0
  struct autr_ta* ta = autr_ta_create(rr, rr_len, dname_len);
448
0
  if(!ta) 
449
0
    return NULL;
450
0
  *tp = find_add_tp(anchors, rr, rr_len, dname_len);
451
0
  if(!*tp) {
452
0
    free(ta->rr);
453
0
    free(ta);
454
0
    return NULL;
455
0
  }
456
  /* add ta to tp */
457
0
  ta->next = (*tp)->autr->keys;
458
0
  (*tp)->autr->keys = ta;
459
0
  lock_basic_unlock(&(*tp)->lock);
460
0
  return ta;
461
0
}
462
463
/**
464
 * Add new trust anchor from a string in file.
465
 * @param anchors: all anchors
466
 * @param str: string with anchor and comments, if any comments.
467
 * @param tp: trust point returned.
468
 * @param origin: what to use for @
469
 * @param origin_len: length of origin
470
 * @param prev: previous rr name
471
 * @param prev_len: length of prev
472
 * @param skip: if true, the result is NULL, but not an error, skip it.
473
 * @return new key in trust point.
474
 */
475
static struct autr_ta*
476
add_trustanchor_frm_str(struct val_anchors* anchors, char* str, 
477
  struct trust_anchor** tp, uint8_t* origin, size_t origin_len,
478
  uint8_t** prev, size_t* prev_len, int* skip)
479
0
{
480
0
  uint8_t rr[LDNS_RR_BUF_SIZE];
481
0
  size_t rr_len = sizeof(rr), dname_len;
482
0
  uint8_t* drr;
483
0
  int lstatus;
484
0
        if (!str_contains_data(str, ';')) {
485
0
    *skip = 1;
486
0
                return NULL; /* empty line */
487
0
  }
488
0
  if(0 != (lstatus = sldns_str2wire_rr_buf(str, rr, &rr_len, &dname_len,
489
0
    0, origin, origin_len, *prev, *prev_len)))
490
0
  {
491
0
    log_err("ldns error while converting string to RR at%d: %s: %s",
492
0
      LDNS_WIREPARSE_OFFSET(lstatus),
493
0
      sldns_get_errorstr_parse(lstatus), str);
494
0
    return NULL;
495
0
  }
496
0
  free(*prev);
497
0
  *prev = memdup(rr, dname_len);
498
0
  *prev_len = dname_len;
499
0
  if(!*prev) {
500
0
    log_err("malloc failure in add_trustanchor");
501
0
    return NULL;
502
0
  }
503
0
  if(sldns_wirerr_get_type(rr, rr_len, dname_len)!=LDNS_RR_TYPE_DNSKEY &&
504
0
    sldns_wirerr_get_type(rr, rr_len, dname_len)!=LDNS_RR_TYPE_DS) {
505
0
    *skip = 1;
506
0
    return NULL; /* only DS and DNSKEY allowed */
507
0
  }
508
0
  drr = memdup(rr, rr_len);
509
0
  if(!drr) {
510
0
    log_err("malloc failure in add trustanchor");
511
0
    return NULL;
512
0
  }
513
0
  return add_trustanchor_frm_rr(anchors, drr, rr_len, dname_len, tp);
514
0
}
515
516
/** 
517
 * Load single anchor 
518
 * @param anchors: all points.
519
 * @param str: comments line
520
 * @param fname: filename
521
 * @param origin: the $ORIGIN.
522
 * @param origin_len: length of origin
523
 * @param prev: passed to ldns.
524
 * @param prev_len: length of prev
525
 * @param skip: if true, the result is NULL, but not an error, skip it.
526
 * @return false on failure, otherwise the tp read.
527
 */
528
static struct trust_anchor*
529
load_trustanchor(struct val_anchors* anchors, char* str, const char* fname,
530
  uint8_t* origin, size_t origin_len, uint8_t** prev, size_t* prev_len,
531
  int* skip)
532
0
{
533
0
  struct autr_ta* ta = NULL;
534
0
  struct trust_anchor* tp = NULL;
535
536
0
  ta = add_trustanchor_frm_str(anchors, str, &tp, origin, origin_len,
537
0
    prev, prev_len, skip);
538
0
  if(!ta)
539
0
    return NULL;
540
0
  lock_basic_lock(&tp->lock);
541
0
  if(!parse_comments(str, ta)) {
542
0
    lock_basic_unlock(&tp->lock);
543
0
    return NULL;
544
0
  }
545
0
  if(!tp->autr->file) {
546
0
    tp->autr->file = strdup(fname);
547
0
    if(!tp->autr->file) {
548
0
      lock_basic_unlock(&tp->lock);
549
0
      log_err("malloc failure");
550
0
      return NULL;
551
0
    }
552
0
  }
553
0
  lock_basic_unlock(&tp->lock);
554
0
        return tp;
555
0
}
556
557
/** iterator for DSes from keylist. return true if a next element exists */
558
static int
559
assemble_iterate_ds(struct autr_ta** list, uint8_t** rr, size_t* rr_len,
560
  size_t* dname_len)
561
0
{
562
0
  while(*list) {
563
0
    if(sldns_wirerr_get_type((*list)->rr, (*list)->rr_len,
564
0
      (*list)->dname_len) == LDNS_RR_TYPE_DS) {
565
0
      *rr = (*list)->rr;
566
0
      *rr_len = (*list)->rr_len;
567
0
      *dname_len = (*list)->dname_len;
568
0
      *list = (*list)->next;
569
0
      return 1;
570
0
    }
571
0
    *list = (*list)->next;
572
0
  }
573
0
  return 0;
574
0
}
575
576
/** iterator for DNSKEYs from keylist. return true if a next element exists */
577
static int
578
assemble_iterate_dnskey(struct autr_ta** list, uint8_t** rr, size_t* rr_len,
579
  size_t* dname_len)
580
0
{
581
0
  while(*list) {
582
0
    if(sldns_wirerr_get_type((*list)->rr, (*list)->rr_len,
583
0
       (*list)->dname_len) != LDNS_RR_TYPE_DS &&
584
0
      ((*list)->s == AUTR_STATE_VALID || 
585
0
       (*list)->s == AUTR_STATE_MISSING)) {
586
0
      *rr = (*list)->rr;
587
0
      *rr_len = (*list)->rr_len;
588
0
      *dname_len = (*list)->dname_len;
589
0
      *list = (*list)->next;
590
0
      return 1;
591
0
    }
592
0
    *list = (*list)->next;
593
0
  }
594
0
  return 0;
595
0
}
596
597
/** see if iterator-list has any elements in it, or it is empty */
598
static int
599
assemble_iterate_hasfirst(int iter(struct autr_ta**, uint8_t**, size_t*,
600
  size_t*), struct autr_ta* list)
601
0
{
602
0
  uint8_t* rr = NULL;
603
0
  size_t rr_len = 0, dname_len = 0;
604
0
  return iter(&list, &rr, &rr_len, &dname_len);
605
0
}
606
607
/** number of elements in iterator list */
608
static size_t
609
assemble_iterate_count(int iter(struct autr_ta**, uint8_t**, size_t*,
610
  size_t*), struct autr_ta* list)
611
0
{
612
0
  uint8_t* rr = NULL;
613
0
  size_t i = 0, rr_len = 0, dname_len = 0;
614
0
  while(iter(&list, &rr, &rr_len, &dname_len)) {
615
0
    i++;
616
0
  }
617
0
  return i;
618
0
}
619
620
/**
621
 * Create a ub_packed_rrset_key allocated on the heap.
622
 * It therefore does not have the correct ID value, and cannot be used
623
 * inside the cache.  It can be used in storage outside of the cache.
624
 * Keys for the cache have to be obtained from alloc.h .
625
 * @param iter: iterator over the elements in the list.  It filters elements.
626
 * @param list: the list.
627
 * @return key allocated or NULL on failure.
628
 */
629
static struct ub_packed_rrset_key* 
630
ub_packed_rrset_heap_key(int iter(struct autr_ta**, uint8_t**, size_t*,
631
  size_t*), struct autr_ta* list)
632
0
{
633
0
  uint8_t* rr = NULL;
634
0
  size_t rr_len = 0, dname_len = 0;
635
0
  struct ub_packed_rrset_key* k;
636
0
  if(!iter(&list, &rr, &rr_len, &dname_len))
637
0
    return NULL;
638
0
  k = (struct ub_packed_rrset_key*)calloc(1, sizeof(*k));
639
0
  if(!k)
640
0
    return NULL;
641
0
  k->rk.type = htons(sldns_wirerr_get_type(rr, rr_len, dname_len));
642
0
  k->rk.rrset_class = htons(sldns_wirerr_get_class(rr, rr_len, dname_len));
643
0
  k->rk.dname_len = dname_len;
644
0
  k->rk.dname = memdup(rr, dname_len);
645
0
  if(!k->rk.dname) {
646
0
    free(k);
647
0
    return NULL;
648
0
  }
649
0
  return k;
650
0
}
651
652
/**
653
 * Create packed_rrset data on the heap.
654
 * @param iter: iterator over the elements in the list.  It filters elements.
655
 * @param list: the list.
656
 * @return data allocated or NULL on failure.
657
 */
658
static struct packed_rrset_data* 
659
packed_rrset_heap_data(int iter(struct autr_ta**, uint8_t**, size_t*,
660
  size_t*), struct autr_ta* list)
661
0
{
662
0
  uint8_t* rr = NULL;
663
0
  size_t rr_len = 0, dname_len = 0;
664
0
  struct packed_rrset_data* data;
665
0
  size_t count=0, rrsig_count=0, len=0, i, total;
666
0
  uint8_t* nextrdata;
667
0
  struct autr_ta* list_i;
668
0
  time_t ttl = 0;
669
670
0
  list_i = list;
671
0
  while(iter(&list_i, &rr, &rr_len, &dname_len)) {
672
0
    if(sldns_wirerr_get_type(rr, rr_len, dname_len) ==
673
0
      LDNS_RR_TYPE_RRSIG)
674
0
      rrsig_count++;
675
0
    else  count++;
676
    /* sizeof the rdlength + rdatalen */
677
0
    len += 2 + sldns_wirerr_get_rdatalen(rr, rr_len, dname_len);
678
0
    ttl = (time_t)sldns_wirerr_get_ttl(rr, rr_len, dname_len);
679
0
  }
680
0
  if(count == 0 && rrsig_count == 0)
681
0
    return NULL;
682
683
  /* allocate */
684
0
  total = count + rrsig_count;
685
0
  len += sizeof(*data) + total*(sizeof(size_t) + sizeof(time_t) + 
686
0
    sizeof(uint8_t*));
687
0
  data = (struct packed_rrset_data*)calloc(1, len);
688
0
  if(!data)
689
0
    return NULL;
690
691
  /* fill it */
692
0
  data->ttl = ttl;
693
0
  data->count = count;
694
0
  data->rrsig_count = rrsig_count;
695
0
  data->rr_len = (size_t*)((uint8_t*)data +
696
0
    sizeof(struct packed_rrset_data));
697
0
  data->rr_data = (uint8_t**)&(data->rr_len[total]);
698
0
  data->rr_ttl = (time_t*)&(data->rr_data[total]);
699
0
  nextrdata = (uint8_t*)&(data->rr_ttl[total]);
700
701
  /* fill out len, ttl, fields */
702
0
  list_i = list;
703
0
  i = 0;
704
0
  while(iter(&list_i, &rr, &rr_len, &dname_len)) {
705
0
    data->rr_ttl[i] = (time_t)sldns_wirerr_get_ttl(rr, rr_len,
706
0
      dname_len);
707
0
    if(data->rr_ttl[i] < data->ttl)
708
0
      data->ttl = data->rr_ttl[i];
709
0
    data->rr_len[i] = 2 /* the rdlength */ +
710
0
      sldns_wirerr_get_rdatalen(rr, rr_len, dname_len);
711
0
    i++;
712
0
  }
713
714
  /* fixup rest of ptrs */
715
0
  for(i=0; i<total; i++) {
716
0
    data->rr_data[i] = nextrdata;
717
0
    nextrdata += data->rr_len[i];
718
0
  }
719
720
  /* copy data in there */
721
0
  list_i = list;
722
0
  i = 0;
723
0
  while(iter(&list_i, &rr, &rr_len, &dname_len)) {
724
0
    log_assert(data->rr_data[i]);
725
0
    memmove(data->rr_data[i],
726
0
      sldns_wirerr_get_rdatawl(rr, rr_len, dname_len),
727
0
      data->rr_len[i]);
728
0
    i++;
729
0
  }
730
731
0
  if(data->rrsig_count && data->count == 0) {
732
0
    data->count = data->rrsig_count; /* rrset type is RRSIG */
733
0
    data->rrsig_count = 0;
734
0
  }
735
0
  return data;
736
0
}
737
738
/**
739
 * Assemble the trust anchors into DS and DNSKEY packed rrsets.
740
 * Uses only VALID and MISSING DNSKEYs.
741
 * Read the sldns_rrs and builds packed rrsets
742
 * @param tp: the trust point. Must be locked.
743
 * @return false on malloc failure.
744
 */
745
static int 
746
autr_assemble(struct trust_anchor* tp)
747
0
{
748
0
  struct ub_packed_rrset_key* ubds=NULL, *ubdnskey=NULL;
749
750
  /* make packed rrset keys - malloced with no ID number, they
751
   * are not in the cache */
752
  /* make packed rrset data (if there is a key) */
753
0
  if(assemble_iterate_hasfirst(assemble_iterate_ds, tp->autr->keys)) {
754
0
    ubds = ub_packed_rrset_heap_key(
755
0
      assemble_iterate_ds, tp->autr->keys);
756
0
    if(!ubds)
757
0
      goto error_cleanup;
758
0
    ubds->entry.data = packed_rrset_heap_data(
759
0
      assemble_iterate_ds, tp->autr->keys);
760
0
    if(!ubds->entry.data)
761
0
      goto error_cleanup;
762
0
  }
763
764
  /* make packed DNSKEY data */
765
0
  if(assemble_iterate_hasfirst(assemble_iterate_dnskey, tp->autr->keys)) {
766
0
    ubdnskey = ub_packed_rrset_heap_key(
767
0
      assemble_iterate_dnskey, tp->autr->keys);
768
0
    if(!ubdnskey)
769
0
      goto error_cleanup;
770
0
    ubdnskey->entry.data = packed_rrset_heap_data(
771
0
      assemble_iterate_dnskey, tp->autr->keys);
772
0
    if(!ubdnskey->entry.data) {
773
0
    error_cleanup:
774
0
      autr_rrset_delete(ubds);
775
0
      autr_rrset_delete(ubdnskey);
776
0
      return 0;
777
0
    }
778
0
  }
779
780
  /* we have prepared the new keys so nothing can go wrong any more.
781
   * And we are sure we cannot be left without trustanchor after
782
   * any errors. Put in the new keys and remove old ones. */
783
784
  /* free the old data */
785
0
  autr_rrset_delete(tp->ds_rrset);
786
0
  autr_rrset_delete(tp->dnskey_rrset);
787
788
  /* assign the data to replace the old */
789
0
  tp->ds_rrset = ubds;
790
0
  tp->dnskey_rrset = ubdnskey;
791
0
  tp->numDS = assemble_iterate_count(assemble_iterate_ds,
792
0
    tp->autr->keys);
793
0
  tp->numDNSKEY = assemble_iterate_count(assemble_iterate_dnskey,
794
0
    tp->autr->keys);
795
0
  return 1;
796
0
}
797
798
/** parse integer */
799
static unsigned int
800
parse_int(char* line, int* ret)
801
0
{
802
0
  char *e;
803
0
  unsigned int x = (unsigned int)strtol(line, &e, 10);
804
0
  if(line == e) {
805
0
    *ret = -1; /* parse error */
806
0
    return 0; 
807
0
  }
808
0
  *ret = 1; /* matched */
809
0
  return x;
810
0
}
811
812
/** parse id sequence for anchor */
813
static struct trust_anchor*
814
parse_id(struct val_anchors* anchors, char* line)
815
0
{
816
0
  struct trust_anchor *tp;
817
0
  int r;
818
0
  uint16_t dclass;
819
0
  uint8_t* dname;
820
0
  size_t dname_len;
821
  /* read the owner name */
822
0
  char* next = strchr(line, ' ');
823
0
  if(!next)
824
0
    return NULL;
825
0
  next[0] = 0;
826
0
  dname = sldns_str2wire_dname(line, &dname_len);
827
0
  if(!dname)
828
0
    return NULL;
829
830
  /* read the class */
831
0
  dclass = parse_int(next+1, &r);
832
0
  if(r == -1) {
833
0
    free(dname);
834
0
    return NULL;
835
0
  }
836
837
  /* find the trust point */
838
0
  tp = autr_tp_create(anchors, dname, dname_len, dclass);
839
0
  free(dname);
840
0
  return tp;
841
0
}
842
843
/** 
844
 * Parse variable from trustanchor header 
845
 * @param line: to parse
846
 * @param anchors: the anchor is added to this, if "id:" is seen.
847
 * @param anchor: the anchor as result value or previously returned anchor
848
 *  value to read the variable lines into.
849
 * @return: 0 no match, -1 failed syntax error, +1 success line read.
850
 *  +2 revoked trust anchor file.
851
 */
852
static int
853
parse_var_line(char* line, struct val_anchors* anchors, 
854
  struct trust_anchor** anchor)
855
0
{
856
0
  struct trust_anchor* tp = *anchor;
857
0
  int r = 0;
858
0
  if(strncmp(line, ";;id: ", 6) == 0) {
859
0
    *anchor = parse_id(anchors, line+6);
860
0
    if(!*anchor) return -1;
861
0
    else return 1;
862
0
  } else if(strncmp(line, ";;REVOKED", 9) == 0) {
863
0
    if(tp) {
864
0
      log_err("REVOKED statement must be at start of file");
865
0
      return -1;
866
0
    }
867
0
    return 2;
868
0
  } else if(strncmp(line, ";;last_queried: ", 16) == 0) {
869
0
    if(!tp) return -1;
870
0
    lock_basic_lock(&tp->lock);
871
0
    tp->autr->last_queried = (time_t)parse_int(line+16, &r);
872
0
    lock_basic_unlock(&tp->lock);
873
0
  } else if(strncmp(line, ";;last_success: ", 16) == 0) {
874
0
    if(!tp) return -1;
875
0
    lock_basic_lock(&tp->lock);
876
0
    tp->autr->last_success = (time_t)parse_int(line+16, &r);
877
0
    lock_basic_unlock(&tp->lock);
878
0
  } else if(strncmp(line, ";;next_probe_time: ", 19) == 0) {
879
0
    if(!tp) return -1;
880
0
    lock_basic_lock(&anchors->lock);
881
0
    lock_basic_lock(&tp->lock);
882
0
    (void)rbtree_delete(&anchors->autr->probe, tp);
883
0
    tp->autr->next_probe_time = (time_t)parse_int(line+19, &r);
884
0
    (void)rbtree_insert(&anchors->autr->probe, &tp->autr->pnode);
885
0
    lock_basic_unlock(&tp->lock);
886
0
    lock_basic_unlock(&anchors->lock);
887
0
  } else if(strncmp(line, ";;query_failed: ", 16) == 0) {
888
0
    if(!tp) return -1;
889
0
    lock_basic_lock(&tp->lock);
890
0
    tp->autr->query_failed = (uint8_t)parse_int(line+16, &r);
891
0
    lock_basic_unlock(&tp->lock);
892
0
  } else if(strncmp(line, ";;query_interval: ", 18) == 0) {
893
0
    if(!tp) return -1;
894
0
    lock_basic_lock(&tp->lock);
895
0
    tp->autr->query_interval = (time_t)parse_int(line+18, &r);
896
0
    lock_basic_unlock(&tp->lock);
897
0
  } else if(strncmp(line, ";;retry_time: ", 14) == 0) {
898
0
    if(!tp) return -1;
899
0
    lock_basic_lock(&tp->lock);
900
0
    tp->autr->retry_time = (time_t)parse_int(line+14, &r);
901
0
    lock_basic_unlock(&tp->lock);
902
0
  }
903
0
  return r;
904
0
}
905
906
/** handle origin lines */
907
static int
908
handle_origin(char* line, uint8_t** origin, size_t* origin_len)
909
0
{
910
0
  size_t len = 0;
911
0
  while(isspace((unsigned char)*line))
912
0
    line++;
913
0
  if(strncmp(line, "$ORIGIN", 7) != 0)
914
0
    return 0;
915
0
  free(*origin);
916
0
  line += 7;
917
0
  while(isspace((unsigned char)*line))
918
0
    line++;
919
0
  *origin = sldns_str2wire_dname(line, &len);
920
0
  *origin_len = len;
921
0
  if(!*origin)
922
0
    log_warn("malloc failure or parse error in $ORIGIN");
923
0
  return 1;
924
0
}
925
926
/** Read one line and put multiline RRs onto one line string */
927
static int
928
read_multiline(char* buf, size_t len, FILE* in, int* linenr)
929
0
{
930
0
  char* pos = buf;
931
0
  size_t left = len;
932
0
  int depth = 0;
933
0
  buf[len-1] = 0;
934
0
  while(left > 0 && fgets(pos, (int)left, in) != NULL) {
935
0
    size_t i, poslen = strlen(pos);
936
0
    (*linenr)++;
937
938
    /* check what the new depth is after the line */
939
    /* this routine cannot handle braces inside quotes,
940
       say for TXT records, but this routine only has to read keys */
941
0
    for(i=0; i<poslen; i++) {
942
0
      if(pos[i] == '(') {
943
0
        depth++;
944
0
      } else if(pos[i] == ')') {
945
0
        if(depth == 0) {
946
0
          log_err("mismatch: too many ')'");
947
0
          return -1;
948
0
        }
949
0
        depth--;
950
0
      } else if(pos[i] == ';') {
951
0
        break;
952
0
      }
953
0
    }
954
955
    /* normal oneline or last line: keeps newline and comments */
956
0
    if(depth == 0) {
957
0
      return 1;
958
0
    }
959
960
    /* more lines expected, snip off comments and newline */
961
0
    if(poslen>0) 
962
0
      pos[poslen-1] = 0; /* strip newline */
963
0
    if(strchr(pos, ';')) 
964
0
      strchr(pos, ';')[0] = 0; /* strip comments */
965
966
    /* move to paste other lines behind this one */
967
0
    poslen = strlen(pos);
968
0
    pos += poslen;
969
0
    left -= poslen;
970
    /* the newline is changed into a space */
971
0
    if(left <= 2 /* space and eos */) {
972
0
      log_err("line too long");
973
0
      return -1;
974
0
    }
975
0
    pos[0] = ' ';
976
0
    pos[1] = 0;
977
0
    pos += 1;
978
0
    left -= 1;
979
0
  }
980
0
  if(depth != 0) {
981
0
    log_err("mismatch: too many '('");
982
0
    return -1;
983
0
  }
984
0
  if(pos != buf)
985
0
    return 1;
986
0
  return 0;
987
0
}
988
989
int autr_read_file(struct val_anchors* anchors, const char* nm)
990
0
{
991
        /* the file descriptor */
992
0
        FILE* fd;
993
        /* keep track of line numbers */
994
0
        int line_nr = 0;
995
        /* single line */
996
0
        char line[10240];
997
  /* trust point being read */
998
0
  struct trust_anchor *tp = NULL, *tp2;
999
0
  int r;
1000
  /* for $ORIGIN parsing */
1001
0
  uint8_t *origin=NULL, *prev=NULL;
1002
0
  size_t origin_len=0, prev_len=0;
1003
1004
0
        if (!(fd = fopen(nm, "r"))) {
1005
0
                log_err("unable to open %s for reading: %s", 
1006
0
      nm, strerror(errno));
1007
0
                return 0;
1008
0
        }
1009
0
        verbose(VERB_ALGO, "reading autotrust anchor file %s", nm);
1010
0
        while ( (r=read_multiline(line, sizeof(line), fd, &line_nr)) != 0) {
1011
0
    if(r == -1 || (r = parse_var_line(line, anchors, &tp)) == -1) {
1012
0
      log_err("could not parse auto-trust-anchor-file "
1013
0
        "%s line %d", nm, line_nr);
1014
0
      fclose(fd);
1015
0
      free(origin);
1016
0
      free(prev);
1017
0
      return 0;
1018
0
    } else if(r == 1) {
1019
0
      continue;
1020
0
    } else if(r == 2) {
1021
0
      log_warn("trust anchor %s has been revoked", nm);
1022
0
      fclose(fd);
1023
0
      free(origin);
1024
0
      free(prev);
1025
0
      return 1;
1026
0
    }
1027
0
          if (!str_contains_data(line, ';'))
1028
0
                  continue; /* empty lines allowed */
1029
0
    if(handle_origin(line, &origin, &origin_len))
1030
0
      continue;
1031
0
    r = 0;
1032
0
                if(!(tp2=load_trustanchor(anchors, line, nm, origin,
1033
0
      origin_len, &prev, &prev_len, &r))) {
1034
0
      if(!r) log_err("failed to load trust anchor from %s "
1035
0
        "at line %i, skipping", nm, line_nr);
1036
                        /* try to do the rest */
1037
0
      continue;
1038
0
                }
1039
0
    if(tp && tp != tp2) {
1040
0
      log_err("file %s has mismatching data inside: "
1041
0
        "the file may only contain keys for one name, "
1042
0
        "remove keys for other domain names", nm);
1043
0
            fclose(fd);
1044
0
      free(origin);
1045
0
      free(prev);
1046
0
      return 0;
1047
0
    }
1048
0
    tp = tp2;
1049
0
        }
1050
0
        fclose(fd);
1051
0
  free(origin);
1052
0
  free(prev);
1053
0
  if(!tp) {
1054
0
    log_err("failed to read %s", nm);
1055
0
    return 0;
1056
0
  }
1057
1058
  /* now assemble the data into DNSKEY and DS packed rrsets */
1059
0
  lock_basic_lock(&tp->lock);
1060
0
  if(!autr_assemble(tp)) {
1061
0
    lock_basic_unlock(&tp->lock);
1062
0
    log_err("malloc failure assembling %s", nm);
1063
0
    return 0;
1064
0
  }
1065
0
  lock_basic_unlock(&tp->lock);
1066
0
  return 1;
1067
0
}
1068
1069
/** string for a trustanchor state */
1070
static const char*
1071
trustanchor_state2str(autr_state_type s)
1072
0
{
1073
0
        switch (s) {
1074
0
                case AUTR_STATE_START:       return "  START  ";
1075
0
                case AUTR_STATE_ADDPEND:     return " ADDPEND ";
1076
0
                case AUTR_STATE_VALID:       return "  VALID  ";
1077
0
                case AUTR_STATE_MISSING:     return " MISSING ";
1078
0
                case AUTR_STATE_REVOKED:     return " REVOKED ";
1079
0
                case AUTR_STATE_REMOVED:     return " REMOVED ";
1080
0
        }
1081
0
        return " UNKNOWN ";
1082
0
}
1083
1084
/** ctime r for autotrust */
1085
static char* autr_ctime_r(time_t* t, char* s)
1086
0
{
1087
0
  ctime_r(t, s);
1088
#ifdef USE_WINSOCK
1089
  if(strlen(s) > 10 && s[7]==' ' && s[8]=='0')
1090
    s[8]=' '; /* fix error in windows ctime */
1091
#endif
1092
0
  return s;
1093
0
}
1094
1095
/** print ID to file */
1096
static int
1097
print_id(FILE* out, char* fname, uint8_t* nm, size_t nmlen, uint16_t dclass)
1098
0
{
1099
0
  char* s = sldns_wire2str_dname(nm, nmlen);
1100
0
  if(!s) {
1101
0
    log_err("malloc failure in write to %s", fname);
1102
0
    return 0;
1103
0
  }
1104
0
  if(fprintf(out, ";;id: %s %d\n", s, (int)dclass) < 0) {
1105
0
    log_err("could not write to %s: %s", fname, strerror(errno));
1106
0
    free(s);
1107
0
    return 0;
1108
0
  }
1109
0
  free(s);
1110
0
  return 1;
1111
0
}
1112
1113
static int
1114
autr_write_contents(FILE* out, char* fn, struct trust_anchor* tp)
1115
0
{
1116
0
  char tmi[32];
1117
0
  struct autr_ta* ta;
1118
0
  char* str;
1119
1120
  /* write pretty header */
1121
0
  if(fprintf(out, "; autotrust trust anchor file\n") < 0) {
1122
0
    log_err("could not write to %s: %s", fn, strerror(errno));
1123
0
    return 0;
1124
0
  }
1125
0
  if(tp->autr->revoked) {
1126
0
    if(fprintf(out, ";;REVOKED\n") < 0 ||
1127
0
       fprintf(out, "; The zone has all keys revoked, and is\n"
1128
0
      "; considered as if it has no trust anchors.\n"
1129
0
      "; the remainder of the file is the last probe.\n"
1130
0
      "; to restart the trust anchor, overwrite this file.\n"
1131
0
      "; with one containing valid DNSKEYs or DSes.\n") < 0) {
1132
0
       log_err("could not write to %s: %s", fn, strerror(errno));
1133
0
       return 0;
1134
0
    }
1135
0
  }
1136
0
  if(!print_id(out, fn, tp->name, tp->namelen, tp->dclass)) {
1137
0
    return 0;
1138
0
  }
1139
0
  if(fprintf(out, ";;last_queried: %u ;;%s", 
1140
0
    (unsigned int)tp->autr->last_queried, 
1141
0
    autr_ctime_r(&(tp->autr->last_queried), tmi)) < 0 ||
1142
0
     fprintf(out, ";;last_success: %u ;;%s", 
1143
0
    (unsigned int)tp->autr->last_success,
1144
0
    autr_ctime_r(&(tp->autr->last_success), tmi)) < 0 ||
1145
0
     fprintf(out, ";;next_probe_time: %u ;;%s", 
1146
0
    (unsigned int)tp->autr->next_probe_time,
1147
0
    autr_ctime_r(&(tp->autr->next_probe_time), tmi)) < 0 ||
1148
0
     fprintf(out, ";;query_failed: %d\n", (int)tp->autr->query_failed)<0
1149
0
     || fprintf(out, ";;query_interval: %d\n", 
1150
0
     (int)tp->autr->query_interval) < 0 ||
1151
0
     fprintf(out, ";;retry_time: %d\n", (int)tp->autr->retry_time) < 0) {
1152
0
    log_err("could not write to %s: %s", fn, strerror(errno));
1153
0
    return 0;
1154
0
  }
1155
1156
  /* write anchors */
1157
0
  for(ta=tp->autr->keys; ta; ta=ta->next) {
1158
    /* by default do not store START and REMOVED keys */
1159
0
    if(ta->s == AUTR_STATE_START)
1160
0
      continue;
1161
0
    if(ta->s == AUTR_STATE_REMOVED)
1162
0
      continue;
1163
    /* only store keys */
1164
0
    if(sldns_wirerr_get_type(ta->rr, ta->rr_len, ta->dname_len)
1165
0
      != LDNS_RR_TYPE_DNSKEY)
1166
0
      continue;
1167
0
    str = sldns_wire2str_rr(ta->rr, ta->rr_len);
1168
0
    if(!str || !str[0]) {
1169
0
      free(str);
1170
0
      log_err("malloc failure writing %s", fn);
1171
0
      return 0;
1172
0
    }
1173
0
    str[strlen(str)-1] = 0; /* remove newline */
1174
0
    if(fprintf(out, "%s ;;state=%d [%s] ;;count=%d "
1175
0
      ";;lastchange=%u ;;%s", str, (int)ta->s, 
1176
0
      trustanchor_state2str(ta->s), (int)ta->pending_count,
1177
0
      (unsigned int)ta->last_change, 
1178
0
      autr_ctime_r(&(ta->last_change), tmi)) < 0) {
1179
0
       log_err("could not write to %s: %s", fn, strerror(errno));
1180
0
       free(str);
1181
0
       return 0;
1182
0
    }
1183
0
    free(str);
1184
0
  }
1185
0
  return 1;
1186
0
}
1187
1188
void autr_write_file(struct module_env* env, struct trust_anchor* tp)
1189
0
{
1190
0
  FILE* out;
1191
0
  char* fname = tp->autr->file;
1192
0
#ifndef S_SPLINT_S
1193
0
  long long llvalue;
1194
0
#endif
1195
0
  char tempf[2048];
1196
0
  log_assert(tp->autr);
1197
0
  if(!env) {
1198
0
    log_err("autr_write_file: Module environment is NULL.");
1199
0
    return;
1200
0
  }
1201
  /* unique name with pid number, thread number, and struct pointer
1202
   * (the pointer uniquifies for multiple libunbound contexts) */
1203
0
#ifndef S_SPLINT_S
1204
#if defined(SIZE_MAX) && defined(UINT32_MAX) && (UINT32_MAX == SIZE_MAX || INT32_MAX == SIZE_MAX)
1205
  /* avoid warning about upcast on 32bit systems */
1206
  llvalue = (unsigned long)tp;
1207
#else
1208
0
  llvalue = (unsigned long long)tp;
1209
0
#endif
1210
0
  snprintf(tempf, sizeof(tempf), "%s.%d-%d-" ARG_LL "x", fname, (int)getpid(),
1211
0
    env->worker?*(int*)env->worker:0, llvalue);
1212
0
#endif /* S_SPLINT_S */
1213
0
  verbose(VERB_ALGO, "autotrust: write to disk: %s", tempf);
1214
0
  out = fopen(tempf, "w");
1215
0
  if(!out) {
1216
0
    fatal_exit("could not open autotrust file for writing, %s: %s",
1217
0
      tempf, strerror(errno));
1218
0
    return;
1219
0
  }
1220
0
  if(!autr_write_contents(out, tempf, tp)) {
1221
    /* failed to write contents (completely) */
1222
0
    fclose(out);
1223
0
    unlink(tempf);
1224
0
    fatal_exit("could not completely write: %s", fname);
1225
0
    return;
1226
0
  }
1227
0
  if(fflush(out) != 0)
1228
0
    log_err("could not fflush(%s): %s", fname, strerror(errno));
1229
0
#ifdef HAVE_FSYNC
1230
0
  if(fsync(fileno(out)) != 0)
1231
0
    log_err("could not fsync(%s): %s", fname, strerror(errno));
1232
#else
1233
  FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(out)));
1234
#endif
1235
0
  if(fclose(out) != 0) {
1236
0
    fatal_exit("could not complete write: %s: %s",
1237
0
      fname, strerror(errno));
1238
0
    unlink(tempf);
1239
0
    return;
1240
0
  }
1241
  /* success; overwrite actual file */
1242
0
  verbose(VERB_ALGO, "autotrust: replaced %s", fname);
1243
#ifdef UB_ON_WINDOWS
1244
  (void)unlink(fname); /* windows does not replace file with rename() */
1245
#endif
1246
0
  if(rename(tempf, fname) < 0) {
1247
0
    fatal_exit("rename(%s to %s): %s", tempf, fname, strerror(errno));
1248
0
  }
1249
0
}
1250
1251
/** 
1252
 * Verify if dnskey works for trust point 
1253
 * @param env: environment (with time) for verification
1254
 * @param ve: validator environment (with options) for verification.
1255
 * @param tp: trust point to verify with
1256
 * @param rrset: DNSKEY rrset to verify.
1257
 * @param qstate: qstate with region.
1258
 * @return false on failure, true if verification successful.
1259
 */
1260
static int
1261
verify_dnskey(struct module_env* env, struct val_env* ve,
1262
        struct trust_anchor* tp, struct ub_packed_rrset_key* rrset,
1263
  struct module_qstate* qstate)
1264
0
{
1265
0
  char reasonbuf[256];
1266
0
  char* reason = NULL;
1267
0
  uint8_t sigalg[ALGO_NEEDS_MAX+1];
1268
0
  int downprot = env->cfg->harden_algo_downgrade;
1269
0
  enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, rrset,
1270
0
    tp->ds_rrset, tp->dnskey_rrset, downprot?sigalg:NULL, &reason,
1271
0
    NULL, qstate, reasonbuf, sizeof(reasonbuf));
1272
  /* sigalg is ignored, it returns algorithms signalled to exist, but
1273
   * in 5011 there are no other rrsets to check.  if downprot is
1274
   * enabled, then it checks that the DNSKEY is signed with all
1275
   * algorithms available in the trust store. */
1276
0
  verbose(VERB_ALGO, "autotrust: validate DNSKEY with anchor: %s",
1277
0
    sec_status_to_string(sec));
1278
0
  return sec == sec_status_secure;
1279
0
}
1280
1281
static int32_t
1282
rrsig_get_expiry(uint8_t* d, size_t len)
1283
0
{
1284
  /* rrsig: 2(rdlen), 2(type) 1(alg) 1(v) 4(origttl), then 4(expi), (4)incep) */
1285
0
  if(len < 2+8+4)
1286
0
    return 0;
1287
0
  return sldns_read_uint32(d+2+8);
1288
0
}
1289
1290
/** Find minimum expiration interval from signatures */
1291
static time_t
1292
min_expiry(struct module_env* env, struct packed_rrset_data* dd)
1293
0
{
1294
0
  size_t i;
1295
0
  int32_t t, r = 15 * 24 * 3600; /* 15 days max */
1296
0
  for(i=dd->count; i<dd->count+dd->rrsig_count; i++) {
1297
0
    t = rrsig_get_expiry(dd->rr_data[i], dd->rr_len[i]);
1298
0
    if((int32_t)t - (int32_t)*env->now > 0) {
1299
0
      t -= (int32_t)*env->now;
1300
0
      if(t < r)
1301
0
        r = t;
1302
0
    }
1303
0
  }
1304
0
  return (time_t)r;
1305
0
}
1306
1307
/** Is rr self-signed revoked key */
1308
static int
1309
rr_is_selfsigned_revoked(struct module_env* env, struct val_env* ve,
1310
  struct ub_packed_rrset_key* dnskey_rrset, size_t i,
1311
  struct module_qstate* qstate)
1312
0
{
1313
0
  enum sec_status sec;
1314
0
  char* reason = NULL;
1315
0
  verbose(VERB_ALGO, "seen REVOKE flag, check self-signed, rr %d",
1316
0
    (int)i);
1317
  /* no algorithm downgrade protection necessary, if it is selfsigned
1318
   * revoked it can be removed. */
1319
0
  sec = dnskey_verify_rrset(env, ve, dnskey_rrset, dnskey_rrset, i, 
1320
0
    &reason, NULL, LDNS_SECTION_ANSWER, qstate);
1321
0
  return (sec == sec_status_secure);
1322
0
}
1323
1324
/** Set fetched value */
1325
static void
1326
seen_trustanchor(struct autr_ta* ta, uint8_t seen)
1327
0
{
1328
0
  ta->fetched = seen;
1329
0
  if(ta->pending_count < 250) /* no numerical overflow, please */
1330
0
    ta->pending_count++;
1331
0
}
1332
1333
/** set revoked value */
1334
static void
1335
seen_revoked_trustanchor(struct autr_ta* ta, uint8_t revoked)
1336
0
{
1337
0
  ta->revoked = revoked;
1338
0
}
1339
1340
/** revoke a trust anchor */
1341
static void
1342
revoke_dnskey(struct autr_ta* ta, int off)
1343
0
{
1344
0
  uint16_t flags;
1345
0
  uint8_t* data;
1346
0
  if(sldns_wirerr_get_type(ta->rr, ta->rr_len, ta->dname_len) !=
1347
0
    LDNS_RR_TYPE_DNSKEY)
1348
0
    return;
1349
0
  if(sldns_wirerr_get_rdatalen(ta->rr, ta->rr_len, ta->dname_len) < 2)
1350
0
    return;
1351
0
  data = sldns_wirerr_get_rdata(ta->rr, ta->rr_len, ta->dname_len);
1352
0
  flags = sldns_read_uint16(data);
1353
0
  if (off && (flags&LDNS_KEY_REVOKE_KEY))
1354
0
    flags ^= LDNS_KEY_REVOKE_KEY; /* flip */
1355
0
  else
1356
0
    flags |= LDNS_KEY_REVOKE_KEY;
1357
0
  sldns_write_uint16(data, flags);
1358
0
}
1359
1360
/** Compare two RRs skipping the REVOKED bit. Pass rdata(no len) */
1361
static int
1362
dnskey_compare_skip_revbit(uint8_t* a, size_t a_len, uint8_t* b, size_t b_len)
1363
0
{
1364
0
  size_t i;
1365
0
  if(a_len != b_len)
1366
0
    return -1;
1367
  /* compare RRs RDATA byte for byte. */
1368
0
  for(i = 0; i < a_len; i++)
1369
0
  {
1370
0
    uint8_t rdf1, rdf2;
1371
0
    rdf1 = a[i];
1372
0
    rdf2 = b[i];
1373
0
    if(i==1) {
1374
      /* this is the second part of the flags field */
1375
0
      rdf1 |= LDNS_KEY_REVOKE_KEY;
1376
0
      rdf2 |= LDNS_KEY_REVOKE_KEY;
1377
0
    }
1378
0
    if (rdf1 < rdf2) return -1;
1379
0
    else if (rdf1 > rdf2) return 1;
1380
0
        }
1381
0
  return 0;
1382
0
}
1383
1384
1385
/** compare trust anchor with rdata, 0 if equal. Pass rdata(no len) */
1386
static int
1387
ta_compare(struct autr_ta* a, uint16_t t, uint8_t* b, size_t b_len)
1388
0
{
1389
0
  if(!a) return -1;
1390
0
  else if(!b) return -1;
1391
0
  else if(sldns_wirerr_get_type(a->rr, a->rr_len, a->dname_len) != t)
1392
0
    return (int)sldns_wirerr_get_type(a->rr, a->rr_len,
1393
0
      a->dname_len) - (int)t;
1394
0
  else if(t == LDNS_RR_TYPE_DNSKEY) {
1395
0
    return dnskey_compare_skip_revbit(
1396
0
      sldns_wirerr_get_rdata(a->rr, a->rr_len, a->dname_len),
1397
0
      sldns_wirerr_get_rdatalen(a->rr, a->rr_len,
1398
0
      a->dname_len), b, b_len);
1399
0
  }
1400
0
  else if(t == LDNS_RR_TYPE_DS) {
1401
0
    if(sldns_wirerr_get_rdatalen(a->rr, a->rr_len, a->dname_len) !=
1402
0
      b_len)
1403
0
      return -1;
1404
0
    return memcmp(sldns_wirerr_get_rdata(a->rr,
1405
0
      a->rr_len, a->dname_len), b, b_len);
1406
0
  }
1407
0
  return -1;
1408
0
}
1409
1410
/** 
1411
 * Find key
1412
 * @param tp: to search in
1413
 * @param t: rr type of the rdata.
1414
 * @param rdata: to look for  (no rdatalen in it)
1415
 * @param rdata_len: length of rdata
1416
 * @param result: returns NULL or the ta key looked for.
1417
 * @return false on malloc failure during search. if true examine result.
1418
 */
1419
static int
1420
find_key(struct trust_anchor* tp, uint16_t t, uint8_t* rdata, size_t rdata_len,
1421
  struct autr_ta** result)
1422
0
{
1423
0
  struct autr_ta* ta;
1424
0
  if(!tp || !rdata) {
1425
0
    *result = NULL;
1426
0
    return 0;
1427
0
  }
1428
0
  for(ta=tp->autr->keys; ta; ta=ta->next) {
1429
0
    if(ta_compare(ta, t, rdata, rdata_len) == 0) {
1430
0
      *result = ta;
1431
0
      return 1;
1432
0
    }
1433
0
  }
1434
0
  *result = NULL;
1435
0
  return 1;
1436
0
}
1437
1438
/** add key and clone RR and tp already locked. rdata without rdlen. */
1439
static struct autr_ta*
1440
add_key(struct trust_anchor* tp, uint32_t ttl, uint8_t* rdata, size_t rdata_len)
1441
0
{
1442
0
  struct autr_ta* ta;
1443
0
  uint8_t* rr;
1444
0
  size_t rr_len, dname_len;
1445
0
  uint16_t rrtype = htons(LDNS_RR_TYPE_DNSKEY);
1446
0
  uint16_t rrclass = htons(LDNS_RR_CLASS_IN);
1447
0
  uint16_t rdlen = htons(rdata_len);
1448
0
  dname_len = tp->namelen;
1449
0
  ttl = htonl(ttl);
1450
0
  rr_len = dname_len + 10 /* type,class,ttl,rdatalen */ + rdata_len;
1451
0
  rr = (uint8_t*)malloc(rr_len);
1452
0
  if(!rr) return NULL;
1453
0
  memmove(rr, tp->name, tp->namelen);
1454
0
  memmove(rr+dname_len, &rrtype, 2);
1455
0
  memmove(rr+dname_len+2, &rrclass, 2);
1456
0
  memmove(rr+dname_len+4, &ttl, 4);
1457
0
  memmove(rr+dname_len+8, &rdlen, 2);
1458
0
  memmove(rr+dname_len+10, rdata, rdata_len);
1459
0
  ta = autr_ta_create(rr, rr_len, dname_len);
1460
0
  if(!ta) {
1461
    /* rr freed in autr_ta_create */
1462
0
    return NULL;
1463
0
  }
1464
  /* link in, tp already locked */
1465
0
  ta->next = tp->autr->keys;
1466
0
  tp->autr->keys = ta;
1467
0
  return ta;
1468
0
}
1469
1470
/** get TTL from DNSKEY rrset */
1471
static time_t
1472
key_ttl(struct ub_packed_rrset_key* k)
1473
0
{
1474
0
  struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
1475
0
  return d->ttl;
1476
0
}
1477
1478
/** update the time values for the trustpoint */
1479
static void
1480
set_tp_times(struct trust_anchor* tp, time_t rrsig_exp_interval, 
1481
  time_t origttl, int* changed)
1482
0
{
1483
0
  time_t x, qi = tp->autr->query_interval, rt = tp->autr->retry_time;
1484
  
1485
  /* x = MIN(15days, ttl/2, expire/2) */
1486
0
  x = 15 * 24 * 3600;
1487
0
  if(origttl/2 < x)
1488
0
    x = origttl/2;
1489
0
  if(rrsig_exp_interval/2 < x)
1490
0
    x = rrsig_exp_interval/2;
1491
  /* MAX(1hr, x) */
1492
0
  if(!autr_permit_small_holddown) {
1493
0
    if(x < 3600)
1494
0
      tp->autr->query_interval = 3600;
1495
0
    else  tp->autr->query_interval = x;
1496
0
  } else    tp->autr->query_interval = x;
1497
1498
  /* x= MIN(1day, ttl/10, expire/10) */
1499
0
  x = 24 * 3600;
1500
0
  if(origttl/10 < x)
1501
0
    x = origttl/10;
1502
0
  if(rrsig_exp_interval/10 < x)
1503
0
    x = rrsig_exp_interval/10;
1504
  /* MAX(1hr, x) */
1505
0
  if(!autr_permit_small_holddown) {
1506
0
    if(x < 3600)
1507
0
      tp->autr->retry_time = 3600;
1508
0
    else  tp->autr->retry_time = x;
1509
0
  } else    tp->autr->retry_time = x;
1510
1511
0
  if(qi != tp->autr->query_interval || rt != tp->autr->retry_time) {
1512
0
    *changed = 1;
1513
0
    verbose(VERB_ALGO, "orig_ttl is %d", (int)origttl);
1514
0
    verbose(VERB_ALGO, "rrsig_exp_interval is %d", 
1515
0
      (int)rrsig_exp_interval);
1516
0
    verbose(VERB_ALGO, "query_interval: %d, retry_time: %d",
1517
0
      (int)tp->autr->query_interval, 
1518
0
      (int)tp->autr->retry_time);
1519
0
  }
1520
0
}
1521
1522
/** init events to zero */
1523
static void
1524
init_events(struct trust_anchor* tp)
1525
0
{
1526
0
  struct autr_ta* ta;
1527
0
  for(ta=tp->autr->keys; ta; ta=ta->next) {
1528
0
    ta->fetched = 0;
1529
0
  }
1530
0
}
1531
1532
/** check for revoked keys without trusting any other information */
1533
static void
1534
check_contains_revoked(struct module_env* env, struct val_env* ve,
1535
  struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset,
1536
  int* changed, struct module_qstate* qstate)
1537
0
{
1538
0
  struct packed_rrset_data* dd = (struct packed_rrset_data*)
1539
0
    dnskey_rrset->entry.data;
1540
0
  size_t i;
1541
0
  log_assert(ntohs(dnskey_rrset->rk.type) == LDNS_RR_TYPE_DNSKEY);
1542
0
  for(i=0; i<dd->count; i++) {
1543
0
    struct autr_ta* ta = NULL;
1544
0
    if(!rr_is_dnskey_sep(ntohs(dnskey_rrset->rk.type),
1545
0
      dd->rr_data[i]+2, dd->rr_len[i]-2) ||
1546
0
      !rr_is_dnskey_revoked(ntohs(dnskey_rrset->rk.type),
1547
0
      dd->rr_data[i]+2, dd->rr_len[i]-2))
1548
0
      continue; /* not a revoked KSK */
1549
0
    if(!find_key(tp, ntohs(dnskey_rrset->rk.type),
1550
0
      dd->rr_data[i]+2, dd->rr_len[i]-2, &ta)) {
1551
0
      log_err("malloc failure");
1552
0
      continue; /* malloc fail in compare*/
1553
0
    }
1554
0
    if(!ta)
1555
0
      continue; /* key not found */
1556
0
    if(rr_is_selfsigned_revoked(env, ve, dnskey_rrset, i, qstate)) {
1557
      /* checked if there is an rrsig signed by this key. */
1558
      /* same keytag, but stored can be revoked already, so 
1559
       * compare keytags, with +0 or +128(REVOKE flag) */
1560
0
      log_assert(dnskey_calc_keytag(dnskey_rrset, i)-128 ==
1561
0
        sldns_calc_keytag_raw(sldns_wirerr_get_rdata(
1562
0
        ta->rr, ta->rr_len, ta->dname_len),
1563
0
        sldns_wirerr_get_rdatalen(ta->rr, ta->rr_len,
1564
0
        ta->dname_len)) ||
1565
0
        dnskey_calc_keytag(dnskey_rrset, i) ==
1566
0
        sldns_calc_keytag_raw(sldns_wirerr_get_rdata(
1567
0
        ta->rr, ta->rr_len, ta->dname_len),
1568
0
        sldns_wirerr_get_rdatalen(ta->rr, ta->rr_len,
1569
0
        ta->dname_len))); /* checks conversion*/
1570
0
      verbose_key(ta, VERB_ALGO, "is self-signed revoked");
1571
0
      if(!ta->revoked) 
1572
0
        *changed = 1;
1573
0
      seen_revoked_trustanchor(ta, 1);
1574
0
      do_revoked(env, ta, changed);
1575
0
    }
1576
0
  }
1577
0
}
1578
1579
/** See if a DNSKEY is verified by one of the DSes */
1580
static int
1581
key_matches_a_ds(struct module_env* env, struct val_env* ve,
1582
  struct ub_packed_rrset_key* dnskey_rrset, size_t key_idx,
1583
  struct ub_packed_rrset_key* ds_rrset)
1584
0
{
1585
0
  struct packed_rrset_data* dd = (struct packed_rrset_data*)
1586
0
                  ds_rrset->entry.data;
1587
0
  size_t ds_idx, num = dd->count;
1588
0
  int d = val_favorite_ds_algo(ds_rrset);
1589
0
  char* reason = "";
1590
0
  for(ds_idx=0; ds_idx<num; ds_idx++) {
1591
0
    if(!ds_digest_algo_is_supported(ds_rrset, ds_idx) ||
1592
0
      !ds_key_algo_is_supported(ds_rrset, ds_idx) ||
1593
0
      !dnskey_size_is_supported(dnskey_rrset, key_idx) ||
1594
0
      ds_get_digest_algo(ds_rrset, ds_idx) != d)
1595
0
      continue;
1596
0
    if(ds_get_key_algo(ds_rrset, ds_idx)
1597
0
       != dnskey_get_algo(dnskey_rrset, key_idx)
1598
0
       || dnskey_calc_keytag(dnskey_rrset, key_idx)
1599
0
       != ds_get_keytag(ds_rrset, ds_idx)) {
1600
0
      continue;
1601
0
    }
1602
0
    if(!ds_digest_match_dnskey(env, dnskey_rrset, key_idx,
1603
0
      ds_rrset, ds_idx)) {
1604
0
      verbose(VERB_ALGO, "DS match attempt failed");
1605
0
      continue;
1606
0
    }
1607
    /* match of hash is sufficient for bootstrap of trust point */
1608
0
    (void)reason;
1609
0
    (void)ve;
1610
0
    return 1;
1611
    /* no need to check RRSIG, DS hash already matched with source
1612
    if(dnskey_verify_rrset(env, ve, dnskey_rrset, 
1613
      dnskey_rrset, key_idx, &reason) == sec_status_secure) {
1614
      return 1;
1615
    } else {
1616
      verbose(VERB_ALGO, "DS match failed because the key "
1617
        "does not verify the keyset: %s", reason);
1618
    }
1619
    */
1620
0
  }
1621
0
  return 0;
1622
0
}
1623
1624
/** Set update events */
1625
static int
1626
update_events(struct module_env* env, struct val_env* ve, 
1627
  struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset, 
1628
  int* changed)
1629
0
{
1630
0
  struct packed_rrset_data* dd = (struct packed_rrset_data*)
1631
0
    dnskey_rrset->entry.data;
1632
0
  size_t i;
1633
0
  log_assert(ntohs(dnskey_rrset->rk.type) == LDNS_RR_TYPE_DNSKEY);
1634
0
  init_events(tp);
1635
0
  for(i=0; i<dd->count; i++) {
1636
0
    struct autr_ta* ta = NULL;
1637
0
    if(!rr_is_dnskey_sep(ntohs(dnskey_rrset->rk.type),
1638
0
      dd->rr_data[i]+2, dd->rr_len[i]-2))
1639
0
      continue;
1640
0
    if(rr_is_dnskey_revoked(ntohs(dnskey_rrset->rk.type),
1641
0
      dd->rr_data[i]+2, dd->rr_len[i]-2)) {
1642
      /* self-signed revoked keys already detected before,
1643
       * other revoked keys are not 'added' again */
1644
0
      continue;
1645
0
    }
1646
    /* is a key of this type supported?. Note rr_list and
1647
     * packed_rrset are in the same order. */
1648
0
    if(!dnskey_algo_is_supported(dnskey_rrset, i) ||
1649
0
      !dnskey_size_is_supported(dnskey_rrset, i)) {
1650
      /* skip unknown algorithm key, it is useless to us */
1651
0
      log_nametypeclass(VERB_DETAIL, "trust point has "
1652
0
        "unsupported algorithm at", 
1653
0
        tp->name, LDNS_RR_TYPE_DNSKEY, tp->dclass);
1654
0
      continue;
1655
0
    }
1656
1657
    /* is it new? if revocation bit set, find the unrevoked key */
1658
0
    if(!find_key(tp, ntohs(dnskey_rrset->rk.type),
1659
0
      dd->rr_data[i]+2, dd->rr_len[i]-2, &ta)) {
1660
0
      return 0;
1661
0
    }
1662
0
    if(!ta) {
1663
0
      ta = add_key(tp, (uint32_t)dd->rr_ttl[i],
1664
0
        dd->rr_data[i]+2, dd->rr_len[i]-2);
1665
0
      *changed = 1;
1666
      /* first time seen, do we have DSes? if match: VALID */
1667
0
      if(ta && tp->ds_rrset && key_matches_a_ds(env, ve,
1668
0
        dnskey_rrset, i, tp->ds_rrset)) {
1669
0
        verbose_key(ta, VERB_ALGO, "verified by DS");
1670
0
        ta->s = AUTR_STATE_VALID;
1671
0
      }
1672
0
    }
1673
0
    if(!ta) {
1674
0
      return 0;
1675
0
    }
1676
0
    seen_trustanchor(ta, 1);
1677
0
    verbose_key(ta, VERB_ALGO, "in DNS response");
1678
0
  }
1679
0
  set_tp_times(tp, min_expiry(env, dd), key_ttl(dnskey_rrset), changed);
1680
0
  return 1;
1681
0
}
1682
1683
/**
1684
 * Check if the holddown time has already exceeded
1685
 * setting: add-holddown: add holddown timer
1686
 * setting: del-holddown: del holddown timer
1687
 * @param env: environment with current time
1688
 * @param ta: trust anchor to check for.
1689
 * @param holddown: the timer value
1690
 * @return number of seconds the holddown has passed.
1691
 */
1692
static time_t
1693
check_holddown(struct module_env* env, struct autr_ta* ta,
1694
  unsigned int holddown)
1695
0
{
1696
0
        time_t elapsed;
1697
0
  if(*env->now < ta->last_change) {
1698
0
    log_warn("time goes backwards. delaying key holddown");
1699
0
    return 0;
1700
0
  }
1701
0
  elapsed = *env->now - ta->last_change;
1702
0
        if (elapsed > (time_t)holddown) {
1703
0
                return elapsed-(time_t)holddown;
1704
0
        }
1705
0
  verbose_key(ta, VERB_ALGO, "holddown time " ARG_LL "d seconds to go",
1706
0
    (long long) ((time_t)holddown-elapsed));
1707
0
        return 0;
1708
0
}
1709
1710
1711
/** Set last_change to now */
1712
static void
1713
reset_holddown(struct module_env* env, struct autr_ta* ta, int* changed)
1714
0
{
1715
0
  ta->last_change = *env->now;
1716
0
  *changed = 1;
1717
0
}
1718
1719
/** Set the state for this trust anchor */
1720
static void
1721
set_trustanchor_state(struct module_env* env, struct autr_ta* ta, int* changed,
1722
  autr_state_type s)
1723
0
{
1724
0
  verbose_key(ta, VERB_ALGO, "update: %s to %s",
1725
0
    trustanchor_state2str(ta->s), trustanchor_state2str(s));
1726
0
  ta->s = s;
1727
0
  reset_holddown(env, ta, changed);
1728
0
}
1729
1730
1731
/** Event: NewKey */
1732
static void
1733
do_newkey(struct module_env* env, struct autr_ta* anchor, int* c)
1734
0
{
1735
0
  if (anchor->s == AUTR_STATE_START)
1736
0
    set_trustanchor_state(env, anchor, c, AUTR_STATE_ADDPEND);
1737
0
}
1738
1739
/** Event: AddTime */
1740
static void
1741
do_addtime(struct module_env* env, struct autr_ta* anchor, int* c)
1742
0
{
1743
  /* This not according to RFC, this is 30 days, but the RFC demands 
1744
   * MAX(30days, TTL expire time of first DNSKEY set with this key),
1745
   * The value may be too small if a very large TTL was used. */
1746
0
  time_t exceeded = check_holddown(env, anchor, env->cfg->add_holddown);
1747
0
  if (exceeded && anchor->s == AUTR_STATE_ADDPEND) {
1748
0
    verbose_key(anchor, VERB_ALGO, "add-holddown time exceeded "
1749
0
      ARG_LL "d seconds ago, and pending-count %d",
1750
0
      (long long)exceeded, anchor->pending_count);
1751
0
    if(anchor->pending_count >= MIN_PENDINGCOUNT) {
1752
0
      set_trustanchor_state(env, anchor, c, AUTR_STATE_VALID);
1753
0
      anchor->pending_count = 0;
1754
0
      return;
1755
0
    }
1756
0
    verbose_key(anchor, VERB_ALGO, "add-holddown time sanity check "
1757
0
      "failed (pending count: %d)", anchor->pending_count);
1758
0
  }
1759
0
}
1760
1761
/** Event: RemTime */
1762
static void
1763
do_remtime(struct module_env* env, struct autr_ta* anchor, int* c)
1764
0
{
1765
0
  time_t exceeded = check_holddown(env, anchor, env->cfg->del_holddown);
1766
0
  if(exceeded && anchor->s == AUTR_STATE_REVOKED) {
1767
0
    verbose_key(anchor, VERB_ALGO, "del-holddown time exceeded "
1768
0
      ARG_LL "d seconds ago", (long long)exceeded);
1769
0
    set_trustanchor_state(env, anchor, c, AUTR_STATE_REMOVED);
1770
0
  }
1771
0
}
1772
1773
/** Event: KeyRem */
1774
static void
1775
do_keyrem(struct module_env* env, struct autr_ta* anchor, int* c)
1776
0
{
1777
0
  if(anchor->s == AUTR_STATE_ADDPEND) {
1778
0
    set_trustanchor_state(env, anchor, c, AUTR_STATE_START);
1779
0
    anchor->pending_count = 0;
1780
0
  } else if(anchor->s == AUTR_STATE_VALID)
1781
0
    set_trustanchor_state(env, anchor, c, AUTR_STATE_MISSING);
1782
0
}
1783
1784
/** Event: KeyPres */
1785
static void
1786
do_keypres(struct module_env* env, struct autr_ta* anchor, int* c)
1787
0
{
1788
0
  if(anchor->s == AUTR_STATE_MISSING)
1789
0
    set_trustanchor_state(env, anchor, c, AUTR_STATE_VALID);
1790
0
}
1791
1792
/* Event: Revoked */
1793
static void
1794
do_revoked(struct module_env* env, struct autr_ta* anchor, int* c)
1795
0
{
1796
0
  if(anchor->s == AUTR_STATE_VALID || anchor->s == AUTR_STATE_MISSING) {
1797
0
                set_trustanchor_state(env, anchor, c, AUTR_STATE_REVOKED);
1798
0
    verbose_key(anchor, VERB_ALGO, "old id, prior to revocation");
1799
0
                revoke_dnskey(anchor, 0);
1800
0
    verbose_key(anchor, VERB_ALGO, "new id, after revocation");
1801
0
  }
1802
0
}
1803
1804
/** Do statestable transition matrix for anchor */
1805
static void
1806
anchor_state_update(struct module_env* env, struct autr_ta* anchor, int* c)
1807
0
{
1808
0
  log_assert(anchor);
1809
0
  switch(anchor->s) {
1810
  /* START */
1811
0
  case AUTR_STATE_START:
1812
    /* NewKey: ADDPEND */
1813
0
    if (anchor->fetched)
1814
0
      do_newkey(env, anchor, c);
1815
0
    break;
1816
  /* ADDPEND */
1817
0
  case AUTR_STATE_ADDPEND:
1818
    /* KeyRem: START */
1819
0
    if (!anchor->fetched)
1820
0
      do_keyrem(env, anchor, c);
1821
    /* AddTime: VALID */
1822
0
    else  do_addtime(env, anchor, c);
1823
0
    break;
1824
  /* VALID */
1825
0
  case AUTR_STATE_VALID:
1826
    /* RevBit: REVOKED */
1827
0
    if (anchor->revoked)
1828
0
      do_revoked(env, anchor, c);
1829
    /* KeyRem: MISSING */
1830
0
    else if (!anchor->fetched)
1831
0
      do_keyrem(env, anchor, c);
1832
0
    else if(!anchor->last_change) {
1833
0
      verbose_key(anchor, VERB_ALGO, "first seen");
1834
0
      reset_holddown(env, anchor, c);
1835
0
    }
1836
0
    break;
1837
  /* MISSING */
1838
0
  case AUTR_STATE_MISSING:
1839
    /* RevBit: REVOKED */
1840
0
    if (anchor->revoked)
1841
0
      do_revoked(env, anchor, c);
1842
    /* KeyPres */
1843
0
    else if (anchor->fetched)
1844
0
      do_keypres(env, anchor, c);
1845
0
    break;
1846
  /* REVOKED */
1847
0
  case AUTR_STATE_REVOKED:
1848
0
    if (anchor->fetched)
1849
0
      reset_holddown(env, anchor, c);
1850
    /* RemTime: REMOVED */
1851
0
    else  do_remtime(env, anchor, c);
1852
0
    break;
1853
  /* REMOVED */
1854
0
  case AUTR_STATE_REMOVED:
1855
0
  default:
1856
0
    break;
1857
0
  }
1858
0
}
1859
1860
/** if ZSK init then trust KSKs */
1861
static int
1862
init_zsk_to_ksk(struct module_env* env, struct trust_anchor* tp, int* changed)
1863
0
{
1864
  /* search for VALID ZSKs */
1865
0
  struct autr_ta* anchor;
1866
0
  int validzsk = 0;
1867
0
  int validksk = 0;
1868
0
  for(anchor = tp->autr->keys; anchor; anchor = anchor->next) {
1869
    /* last_change test makes sure it was manually configured */
1870
0
    if(sldns_wirerr_get_type(anchor->rr, anchor->rr_len,
1871
0
      anchor->dname_len) == LDNS_RR_TYPE_DNSKEY &&
1872
0
      anchor->last_change == 0 && 
1873
0
      !ta_is_dnskey_sep(anchor) &&
1874
0
      anchor->s == AUTR_STATE_VALID)
1875
0
                        validzsk++;
1876
0
  }
1877
0
  if(validzsk == 0)
1878
0
    return 0;
1879
0
  for(anchor = tp->autr->keys; anchor; anchor = anchor->next) {
1880
0
                if (ta_is_dnskey_sep(anchor) && 
1881
0
      anchor->s == AUTR_STATE_ADDPEND) {
1882
0
      verbose_key(anchor, VERB_ALGO, "trust KSK from "
1883
0
        "ZSK(config)");
1884
0
      set_trustanchor_state(env, anchor, changed, 
1885
0
        AUTR_STATE_VALID);
1886
0
      validksk++;
1887
0
    }
1888
0
  }
1889
0
  return validksk;
1890
0
}
1891
1892
/** Remove missing trustanchors so the list does not grow forever */
1893
static void
1894
remove_missing_trustanchors(struct module_env* env, struct trust_anchor* tp,
1895
  int* changed)
1896
0
{
1897
0
  struct autr_ta* anchor;
1898
0
  time_t exceeded;
1899
0
  int valid = 0;
1900
  /* see if we have anchors that are valid */
1901
0
  for(anchor = tp->autr->keys; anchor; anchor = anchor->next) {
1902
    /* Only do KSKs */
1903
0
                if (!ta_is_dnskey_sep(anchor))
1904
0
                        continue;
1905
0
                if (anchor->s == AUTR_STATE_VALID)
1906
0
                        valid++;
1907
0
  }
1908
  /* if there are no SEP Valid anchors, see if we started out with
1909
   * a ZSK (last-change=0) anchor, which is VALID and there are KSKs
1910
   * now that can be made valid.  Do this immediately because there
1911
   * is no guarantee that the ZSKs get announced long enough.  Usually
1912
   * this is immediately after init with a ZSK trusted, unless the domain
1913
   * was not advertising any KSKs at all.  In which case we perfectly
1914
   * track the zero number of KSKs. */
1915
0
  if(valid == 0) {
1916
0
    valid = init_zsk_to_ksk(env, tp, changed);
1917
0
    if(valid == 0)
1918
0
      return;
1919
0
  }
1920
  
1921
0
  for(anchor = tp->autr->keys; anchor; anchor = anchor->next) {
1922
    /* ignore ZSKs if newly added */
1923
0
    if(anchor->s == AUTR_STATE_START)
1924
0
      continue;
1925
    /* remove ZSKs if a KSK is present */
1926
0
                if (!ta_is_dnskey_sep(anchor)) {
1927
0
      if(valid > 0) {
1928
0
        verbose_key(anchor, VERB_ALGO, "remove ZSK "
1929
0
          "[%d key(s) VALID]", valid);
1930
0
        set_trustanchor_state(env, anchor, changed, 
1931
0
          AUTR_STATE_REMOVED);
1932
0
      }
1933
0
                        continue;
1934
0
    }
1935
                /* Only do MISSING keys */
1936
0
                if (anchor->s != AUTR_STATE_MISSING)
1937
0
                        continue;
1938
0
    if(env->cfg->keep_missing == 0)
1939
0
      continue; /* keep forever */
1940
1941
0
    exceeded = check_holddown(env, anchor, env->cfg->keep_missing);
1942
    /* If keep_missing has exceeded and we still have more than 
1943
     * one valid KSK: remove missing trust anchor */
1944
0
                if (exceeded && valid > 0) {
1945
0
      verbose_key(anchor, VERB_ALGO, "keep-missing time "
1946
0
        "exceeded " ARG_LL "d seconds ago, [%d key(s) VALID]",
1947
0
        (long long)exceeded, valid);
1948
0
      set_trustanchor_state(env, anchor, changed, 
1949
0
        AUTR_STATE_REMOVED);
1950
0
    }
1951
0
  }
1952
0
}
1953
1954
/** Do the statetable from RFC5011 transition matrix */
1955
static int
1956
do_statetable(struct module_env* env, struct trust_anchor* tp, int* changed)
1957
0
{
1958
0
  struct autr_ta* anchor;
1959
0
  for(anchor = tp->autr->keys; anchor; anchor = anchor->next) {
1960
    /* Only do KSKs */
1961
0
    if(!ta_is_dnskey_sep(anchor))
1962
0
      continue;
1963
0
    anchor_state_update(env, anchor, changed);
1964
0
  }
1965
0
  remove_missing_trustanchors(env, tp, changed);
1966
0
  return 1;
1967
0
}
1968
1969
/** See if time alone makes ADDPEND to VALID transition */
1970
static void
1971
autr_holddown_exceed(struct module_env* env, struct trust_anchor* tp, int* c)
1972
0
{
1973
0
  struct autr_ta* anchor;
1974
0
  for(anchor = tp->autr->keys; anchor; anchor = anchor->next) {
1975
0
    if(ta_is_dnskey_sep(anchor) && 
1976
0
      anchor->s == AUTR_STATE_ADDPEND)
1977
0
      do_addtime(env, anchor, c);
1978
0
  }
1979
0
}
1980
1981
/** cleanup key list */
1982
static void
1983
autr_cleanup_keys(struct trust_anchor* tp)
1984
0
{
1985
0
  struct autr_ta* p, **prevp;
1986
0
  prevp = &tp->autr->keys;
1987
0
  p = tp->autr->keys;
1988
0
  while(p) {
1989
    /* do we want to remove this key? */
1990
0
    if(p->s == AUTR_STATE_START || p->s == AUTR_STATE_REMOVED ||
1991
0
      sldns_wirerr_get_type(p->rr, p->rr_len, p->dname_len)
1992
0
      != LDNS_RR_TYPE_DNSKEY) {
1993
0
      struct autr_ta* np = p->next;
1994
      /* remove */
1995
0
      free(p->rr);
1996
0
      free(p);
1997
      /* snip and go to next item */
1998
0
      *prevp = np;
1999
0
      p = np;
2000
0
      continue;
2001
0
    }
2002
    /* remove pending counts if no longer pending */
2003
0
    if(p->s != AUTR_STATE_ADDPEND)
2004
0
      p->pending_count = 0;
2005
0
    prevp = &p->next;
2006
0
    p = p->next;
2007
0
  }
2008
0
}
2009
2010
/** calculate next probe time */
2011
static time_t
2012
calc_next_probe(struct module_env* env, time_t wait)
2013
0
{
2014
  /* make it random, 90-100% */
2015
0
  time_t rnd, rest;
2016
0
  if(!autr_permit_small_holddown) {
2017
0
    if(wait < 3600)
2018
0
      wait = 3600;
2019
0
  } else {
2020
0
    if(wait == 0) wait = 1;
2021
0
  }
2022
0
  rnd = wait/10;
2023
0
  rest = wait-rnd;
2024
0
  rnd = (time_t)ub_random_max(env->rnd, (long int)rnd);
2025
0
  return (time_t)(*env->now + rest + rnd);
2026
0
}
2027
2028
/** what is first probe time (anchors must be locked) */
2029
static time_t
2030
wait_probe_time(struct val_anchors* anchors)
2031
0
{
2032
0
  rbnode_type* t = rbtree_first(&anchors->autr->probe);
2033
0
  if(t != RBTREE_NULL) 
2034
0
    return ((struct trust_anchor*)t->key)->autr->next_probe_time;
2035
0
  return 0;
2036
0
}
2037
2038
/** reset worker timer, at the time from wait_probe_time. */
2039
static void
2040
reset_worker_timer_at(struct module_env* env, time_t next)
2041
0
{
2042
0
  struct timeval tv;
2043
0
#ifndef S_SPLINT_S
2044
  /* in case this is libunbound, no timer */
2045
0
  if(!env->probe_timer)
2046
0
    return;
2047
0
  if(next > *env->now)
2048
0
    tv.tv_sec = (time_t)(next - *env->now);
2049
0
  else  tv.tv_sec = 0;
2050
#else
2051
  (void)next;
2052
#endif
2053
0
  tv.tv_usec = 0;
2054
0
  comm_timer_set(env->probe_timer, &tv);
2055
0
  verbose(VERB_ALGO, "scheduled next probe in " ARG_LL "d sec", (long long)tv.tv_sec);
2056
0
}
2057
2058
/** reset worker timer. This routine manages the locks on acquiring the
2059
 * next time for the timer. */
2060
static void
2061
reset_worker_timer(struct module_env* env)
2062
0
{
2063
0
  time_t next;
2064
0
  if(!env->anchors)
2065
0
    return;
2066
0
  lock_basic_lock(&env->anchors->lock);
2067
0
  next = wait_probe_time(env->anchors);
2068
0
  lock_basic_unlock(&env->anchors->lock);
2069
0
  reset_worker_timer_at(env, next);
2070
0
}
2071
2072
/** set next probe for trust anchor */
2073
static int
2074
set_next_probe(struct module_env* env, struct trust_anchor* tp,
2075
  struct ub_packed_rrset_key* dnskey_rrset)
2076
0
{
2077
0
  struct trust_anchor key, *tp2;
2078
0
  time_t mold, mnew;
2079
  /* use memory allocated in rrset for temporary name storage */
2080
0
  key.node.key = &key;
2081
0
  key.name = dnskey_rrset->rk.dname;
2082
0
  key.namelen = dnskey_rrset->rk.dname_len;
2083
0
  key.namelabs = dname_count_labels(key.name);
2084
0
  key.dclass = tp->dclass;
2085
0
  lock_basic_unlock(&tp->lock);
2086
2087
  /* fetch tp again and lock anchors, so that we can modify the trees */
2088
0
  lock_basic_lock(&env->anchors->lock);
2089
0
  tp2 = (struct trust_anchor*)rbtree_search(env->anchors->tree, &key);
2090
0
  if(!tp2) {
2091
0
    verbose(VERB_ALGO, "trustpoint was deleted in set_next_probe");
2092
0
    lock_basic_unlock(&env->anchors->lock);
2093
0
    return 0;
2094
0
  }
2095
0
  log_assert(tp == tp2);
2096
0
  lock_basic_lock(&tp->lock);
2097
2098
  /* schedule */
2099
0
  mold = wait_probe_time(env->anchors);
2100
0
  (void)rbtree_delete(&env->anchors->autr->probe, tp);
2101
0
  tp->autr->next_probe_time = calc_next_probe(env, 
2102
0
    tp->autr->query_interval);
2103
0
  (void)rbtree_insert(&env->anchors->autr->probe, &tp->autr->pnode);
2104
0
  mnew = wait_probe_time(env->anchors);
2105
2106
0
  lock_basic_unlock(&env->anchors->lock);
2107
0
  verbose(VERB_ALGO, "next probe set in %d seconds", 
2108
0
    (int)tp->autr->next_probe_time - (int)*env->now);
2109
0
  if(mold != mnew) {
2110
0
    reset_worker_timer_at(env, mnew);
2111
0
  }
2112
0
  return 1;
2113
0
}
2114
2115
/** Revoke and Delete a trust point */
2116
static void
2117
autr_tp_remove(struct module_env* env, struct trust_anchor* tp,
2118
  struct ub_packed_rrset_key* dnskey_rrset)
2119
0
{
2120
0
  struct trust_anchor* del_tp;
2121
0
  struct trust_anchor key;
2122
0
  struct autr_point_data pd;
2123
0
  time_t mold, mnew;
2124
2125
0
  log_nametypeclass(VERB_OPS, "trust point was revoked",
2126
0
    tp->name, LDNS_RR_TYPE_DNSKEY, tp->dclass);
2127
0
  tp->autr->revoked = 1;
2128
2129
  /* use space allocated for dnskey_rrset to save name of anchor */
2130
0
  memset(&key, 0, sizeof(key));
2131
0
  memset(&pd, 0, sizeof(pd));
2132
0
  key.autr = &pd;
2133
0
  key.node.key = &key;
2134
0
  pd.pnode.key = &key;
2135
0
  pd.next_probe_time = tp->autr->next_probe_time;
2136
0
  key.name = dnskey_rrset->rk.dname;
2137
0
  key.namelen = tp->namelen;
2138
0
  key.namelabs = tp->namelabs;
2139
0
  key.dclass = tp->dclass;
2140
2141
  /* unlock */
2142
0
  lock_basic_unlock(&tp->lock);
2143
2144
  /* take from tree. It could be deleted by someone else,hence (void). */
2145
0
  lock_basic_lock(&env->anchors->lock);
2146
0
  del_tp = (struct trust_anchor*)rbtree_delete(env->anchors->tree, &key);
2147
0
  mold = wait_probe_time(env->anchors);
2148
0
  (void)rbtree_delete(&env->anchors->autr->probe, &key);
2149
0
  mnew = wait_probe_time(env->anchors);
2150
0
  anchors_init_parents_locked(env->anchors);
2151
0
  lock_basic_unlock(&env->anchors->lock);
2152
2153
  /* if !del_tp then the trust point is no longer present in the tree,
2154
   * it was deleted by someone else, who will write the zonefile and
2155
   * clean up the structure */
2156
0
  if(del_tp) {
2157
    /* save on disk */
2158
0
    del_tp->autr->next_probe_time = 0; /* no more probing for it */
2159
0
    autr_write_file(env, del_tp);
2160
2161
    /* delete */
2162
0
    autr_point_delete(del_tp);
2163
0
  }
2164
0
  if(mold != mnew) {
2165
0
    reset_worker_timer_at(env, mnew);
2166
0
  }
2167
0
}
2168
2169
int autr_process_prime(struct module_env* env, struct val_env* ve,
2170
  struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset,
2171
  struct module_qstate* qstate)
2172
0
{
2173
0
  int changed = 0;
2174
0
  log_assert(tp && tp->autr);
2175
  /* autotrust update trust anchors */
2176
  /* the tp is locked, and stays locked unless it is deleted */
2177
2178
  /* we could just catch the anchor here while another thread
2179
   * is busy deleting it. Just unlock and let the other do its job */
2180
0
  if(tp->autr->revoked) {
2181
0
    log_nametypeclass(VERB_ALGO, "autotrust not processed, "
2182
0
      "trust point revoked", tp->name, 
2183
0
      LDNS_RR_TYPE_DNSKEY, tp->dclass);
2184
0
    lock_basic_unlock(&tp->lock);
2185
0
    return 0; /* it is revoked */
2186
0
  }
2187
2188
  /* query_dnskeys(): */
2189
0
  tp->autr->last_queried = *env->now;
2190
2191
0
  log_nametypeclass(VERB_ALGO, "autotrust process for",
2192
0
    tp->name, LDNS_RR_TYPE_DNSKEY, tp->dclass);
2193
  /* see if time alone makes some keys valid */
2194
0
  autr_holddown_exceed(env, tp, &changed);
2195
0
  if(changed) {
2196
0
    verbose(VERB_ALGO, "autotrust: morekeys, reassemble");
2197
0
    if(!autr_assemble(tp)) {
2198
0
      log_err("malloc failure assembling autotrust keys");
2199
0
      return 1; /* unchanged */
2200
0
    }
2201
0
  }
2202
  /* did we get any data? */
2203
0
  if(!dnskey_rrset) {
2204
0
    verbose(VERB_ALGO, "autotrust: no dnskey rrset");
2205
    /* no update of query_failed, because then we would have
2206
     * to write to disk. But we cannot because we maybe are
2207
     * still 'initializing' with DS records, that we cannot write
2208
     * in the full format (which only contains KSKs). */
2209
0
    return 1; /* trust point exists */
2210
0
  }
2211
  /* check for revoked keys to remove immediately */
2212
0
  check_contains_revoked(env, ve, tp, dnskey_rrset, &changed, qstate);
2213
0
  if(changed) {
2214
0
    verbose(VERB_ALGO, "autotrust: revokedkeys, reassemble");
2215
0
    if(!autr_assemble(tp)) {
2216
0
      log_err("malloc failure assembling autotrust keys");
2217
0
      return 1; /* unchanged */
2218
0
    }
2219
0
    if(!tp->ds_rrset && !tp->dnskey_rrset) {
2220
      /* no more keys, all are revoked */
2221
      /* this is a success for this probe attempt */
2222
0
      tp->autr->last_success = *env->now;
2223
0
      autr_tp_remove(env, tp, dnskey_rrset);
2224
0
      return 0; /* trust point removed */
2225
0
    }
2226
0
  }
2227
  /* verify the dnskey rrset and see if it is valid. */
2228
0
  if(!verify_dnskey(env, ve, tp, dnskey_rrset, qstate)) {
2229
0
    verbose(VERB_ALGO, "autotrust: dnskey did not verify.");
2230
    /* only increase failure count if this is not the first prime,
2231
     * this means there was a previous successful probe */
2232
0
    if(tp->autr->last_success) {
2233
0
      tp->autr->query_failed += 1;
2234
0
      autr_write_file(env, tp);
2235
0
    }
2236
0
    return 1; /* trust point exists */
2237
0
  }
2238
2239
0
  tp->autr->last_success = *env->now;
2240
0
  tp->autr->query_failed = 0;
2241
2242
  /* Add new trust anchors to the data structure
2243
   * - note which trust anchors are seen this probe.
2244
   * Set trustpoint query_interval and retry_time.
2245
   * - find minimum rrsig expiration interval
2246
   */
2247
0
  if(!update_events(env, ve, tp, dnskey_rrset, &changed)) {
2248
0
    log_err("malloc failure in autotrust update_events. "
2249
0
      "trust point unchanged.");
2250
0
    return 1; /* trust point unchanged, so exists */
2251
0
  }
2252
2253
  /* - for every SEP key do the 5011 statetable.
2254
   * - remove missing trustanchors (if veryold and we have new anchors).
2255
   */
2256
0
  if(!do_statetable(env, tp, &changed)) {
2257
0
    log_err("malloc failure in autotrust do_statetable. "
2258
0
      "trust point unchanged.");
2259
0
    return 1; /* trust point unchanged, so exists */
2260
0
  }
2261
2262
0
  autr_cleanup_keys(tp);
2263
0
  if(!set_next_probe(env, tp, dnskey_rrset))
2264
0
    return 0; /* trust point does not exist */
2265
0
  autr_write_file(env, tp);
2266
0
  if(changed) {
2267
0
    verbose(VERB_ALGO, "autotrust: changed, reassemble");
2268
0
    if(!autr_assemble(tp)) {
2269
0
      log_err("malloc failure assembling autotrust keys");
2270
0
      return 1; /* unchanged */
2271
0
    }
2272
0
    if(!tp->ds_rrset && !tp->dnskey_rrset) {
2273
      /* no more keys, all are revoked */
2274
0
      autr_tp_remove(env, tp, dnskey_rrset);
2275
0
      return 0; /* trust point removed */
2276
0
    }
2277
0
  } else verbose(VERB_ALGO, "autotrust: no changes");
2278
  
2279
0
  return 1; /* trust point exists */
2280
0
}
2281
2282
/** debug print a trust anchor key */
2283
static void 
2284
autr_debug_print_ta(struct autr_ta* ta)
2285
0
{
2286
0
  char buf[32];
2287
0
  char* str = sldns_wire2str_rr(ta->rr, ta->rr_len);
2288
0
  if(!str) {
2289
0
    log_info("out of memory in debug_print_ta");
2290
0
    return;
2291
0
  }
2292
0
  if(str[0]) str[strlen(str)-1]=0; /* remove newline */
2293
0
  (void)autr_ctime_r(&ta->last_change, buf);
2294
0
  if(buf[0]) buf[strlen(buf)-1]=0; /* remove newline */
2295
0
  log_info("[%s] %s ;;state:%d ;;pending_count:%d%s%s last:%s",
2296
0
    trustanchor_state2str(ta->s), str, ta->s, ta->pending_count,
2297
0
    ta->fetched?" fetched":"", ta->revoked?" revoked":"", buf);
2298
0
  free(str);
2299
0
}
2300
2301
/** debug print a trust point */
2302
static void 
2303
autr_debug_print_tp(struct trust_anchor* tp)
2304
0
{
2305
0
  struct autr_ta* ta;
2306
  /* Note: buf is also used for autr_ctime_r but that only needs a size
2307
   *       of 26, so LDNS_MAX_DOMAINLEN is enough. */
2308
0
  char buf[LDNS_MAX_DOMAINLEN];
2309
0
  if(!tp->autr)
2310
0
    return;
2311
0
  dname_str(tp->name, buf);
2312
0
  log_info("trust point %s : %d", buf, (int)tp->dclass);
2313
0
  log_info("assembled %d DS and %d DNSKEYs", 
2314
0
    (int)tp->numDS, (int)tp->numDNSKEY);
2315
0
  if(tp->ds_rrset) {
2316
0
    log_packed_rrset(NO_VERBOSE, "DS:", tp->ds_rrset);
2317
0
  }
2318
0
  if(tp->dnskey_rrset) {
2319
0
    log_packed_rrset(NO_VERBOSE, "DNSKEY:", tp->dnskey_rrset);
2320
0
  }
2321
0
  log_info("file %s", tp->autr->file);
2322
0
  (void)autr_ctime_r(&tp->autr->last_queried, buf);
2323
0
  if(buf[0]) buf[strlen(buf)-1]=0; /* remove newline */
2324
0
  log_info("last_queried: %u %s", (unsigned)tp->autr->last_queried, buf);
2325
0
  (void)autr_ctime_r(&tp->autr->last_success, buf);
2326
0
  if(buf[0]) buf[strlen(buf)-1]=0; /* remove newline */
2327
0
  log_info("last_success: %u %s", (unsigned)tp->autr->last_success, buf);
2328
0
  (void)autr_ctime_r(&tp->autr->next_probe_time, buf);
2329
0
  if(buf[0]) buf[strlen(buf)-1]=0; /* remove newline */
2330
0
  log_info("next_probe_time: %u %s", (unsigned)tp->autr->next_probe_time,
2331
0
    buf);
2332
0
  log_info("query_interval: %u", (unsigned)tp->autr->query_interval);
2333
0
  log_info("retry_time: %u", (unsigned)tp->autr->retry_time);
2334
0
  log_info("query_failed: %u", (unsigned)tp->autr->query_failed);
2335
    
2336
0
  for(ta=tp->autr->keys; ta; ta=ta->next) {
2337
0
    autr_debug_print_ta(ta);
2338
0
  }
2339
0
}
2340
2341
void 
2342
autr_debug_print(struct val_anchors* anchors)
2343
0
{
2344
0
  struct trust_anchor* tp;
2345
0
  lock_basic_lock(&anchors->lock);
2346
0
  RBTREE_FOR(tp, struct trust_anchor*, anchors->tree) {
2347
0
    lock_basic_lock(&tp->lock);
2348
0
    autr_debug_print_tp(tp);
2349
0
    lock_basic_unlock(&tp->lock);
2350
0
  }
2351
0
  lock_basic_unlock(&anchors->lock);
2352
0
}
2353
2354
void probe_answer_cb(void* arg, int ATTR_UNUSED(rcode), 
2355
  sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(sec),
2356
  char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
2357
0
{
2358
  /* retry was set before the query was done,
2359
   * re-querytime is set when query succeeded, but that may not
2360
   * have reset this timer because the query could have been
2361
   * handled by another thread. In that case, this callback would
2362
   * get called after the original timeout is done. 
2363
   * By not resetting the timer, it may probe more often, but not
2364
   * less often.
2365
   * Unless the new lookup resulted in smaller TTLs and thus smaller
2366
   * timeout values. In that case one old TTL could be mistakenly done.
2367
   */
2368
0
  struct module_env* env = (struct module_env*)arg;
2369
0
  verbose(VERB_ALGO, "autotrust probe answer cb");
2370
0
  reset_worker_timer(env);
2371
0
}
2372
2373
/** probe a trust anchor DNSKEY and unlocks tp */
2374
static void
2375
probe_anchor(struct module_env* env, struct trust_anchor* tp)
2376
0
{
2377
0
  struct query_info qinfo;
2378
0
  uint16_t qflags = BIT_RD;
2379
0
  struct edns_data edns;
2380
0
  sldns_buffer* buf = env->scratch_buffer;
2381
0
  qinfo.qname = regional_alloc_init(env->scratch, tp->name, tp->namelen);
2382
0
  if(!qinfo.qname) {
2383
0
    log_err("out of memory making 5011 probe");
2384
0
    return;
2385
0
  }
2386
0
  qinfo.qname_len = tp->namelen;
2387
0
  qinfo.qtype = LDNS_RR_TYPE_DNSKEY;
2388
0
  qinfo.qclass = tp->dclass;
2389
0
  qinfo.local_alias = NULL;
2390
0
  log_query_info(VERB_ALGO, "autotrust probe", &qinfo);
2391
0
  verbose(VERB_ALGO, "retry probe set in %d seconds", 
2392
0
    (int)tp->autr->next_probe_time - (int)*env->now);
2393
0
  edns.edns_present = 1;
2394
0
  edns.ext_rcode = 0;
2395
0
  edns.edns_version = 0;
2396
0
  edns.bits = EDNS_DO;
2397
0
  edns.opt_list_in = NULL;
2398
0
  edns.opt_list_out = NULL;
2399
0
  edns.opt_list_inplace_cb_out = NULL;
2400
0
  edns.padding_block_size = 0;
2401
0
  edns.cookie_present = 0;
2402
0
  edns.cookie_valid = 0;
2403
0
  if(sldns_buffer_capacity(buf) < 65535)
2404
0
    edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
2405
0
  else  edns.udp_size = 65535;
2406
2407
  /* can't hold the lock while mesh_run is processing */
2408
0
  lock_basic_unlock(&tp->lock);
2409
2410
  /* delete the DNSKEY from rrset and key cache so an active probe
2411
   * is done. First the rrset so another thread does not use it
2412
   * to recreate the key entry in a race condition. */
2413
0
  rrset_cache_remove(env->rrset_cache, qinfo.qname, qinfo.qname_len,
2414
0
    qinfo.qtype, qinfo.qclass, 0);
2415
0
  key_cache_remove(env->key_cache, qinfo.qname, qinfo.qname_len, 
2416
0
    qinfo.qclass);
2417
2418
0
  if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0, 
2419
0
    &probe_answer_cb, env, 0)) {
2420
0
    log_err("out of memory making 5011 probe");
2421
0
  }
2422
0
}
2423
2424
/** fetch first to-probe trust-anchor and lock it and set retrytime */
2425
static struct trust_anchor*
2426
todo_probe(struct module_env* env, time_t* next)
2427
0
{
2428
0
  struct trust_anchor* tp;
2429
0
  rbnode_type* el;
2430
  /* get first one */
2431
0
  lock_basic_lock(&env->anchors->lock);
2432
0
  if( (el=rbtree_first(&env->anchors->autr->probe)) == RBTREE_NULL) {
2433
    /* in case of revoked anchors */
2434
0
    lock_basic_unlock(&env->anchors->lock);
2435
    /* signal that there are no anchors to probe */
2436
0
    *next = 0;
2437
0
    return NULL;
2438
0
  }
2439
0
  tp = (struct trust_anchor*)el->key;
2440
0
  lock_basic_lock(&tp->lock);
2441
2442
  /* is it eligible? */
2443
0
  if((time_t)tp->autr->next_probe_time > *env->now) {
2444
    /* no more to probe */
2445
0
    *next = (time_t)tp->autr->next_probe_time - *env->now;
2446
0
    lock_basic_unlock(&tp->lock);
2447
0
    lock_basic_unlock(&env->anchors->lock);
2448
0
    return NULL;
2449
0
  }
2450
2451
  /* reset its next probe time */
2452
0
  (void)rbtree_delete(&env->anchors->autr->probe, tp);
2453
0
  tp->autr->next_probe_time = calc_next_probe(env, tp->autr->retry_time);
2454
0
  (void)rbtree_insert(&env->anchors->autr->probe, &tp->autr->pnode);
2455
0
  lock_basic_unlock(&env->anchors->lock);
2456
2457
0
  return tp;
2458
0
}
2459
2460
time_t 
2461
autr_probe_timer(struct module_env* env)
2462
0
{
2463
0
  struct trust_anchor* tp;
2464
0
  time_t next_probe = 3600;
2465
0
  int num = 0;
2466
0
  if(autr_permit_small_holddown) next_probe = 1;
2467
0
  verbose(VERB_ALGO, "autotrust probe timer callback");
2468
  /* while there are still anchors to probe */
2469
0
  while( (tp = todo_probe(env, &next_probe)) ) {
2470
    /* make a probe for this anchor */
2471
0
    probe_anchor(env, tp);
2472
0
    num++;
2473
0
  }
2474
0
  regional_free_all(env->scratch);
2475
0
  if(next_probe == 0)
2476
0
    return 0; /* no trust points to probe */
2477
0
  verbose(VERB_ALGO, "autotrust probe timer %d callbacks done", num);
2478
0
  return next_probe;
2479
0
}