]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-transaction.c
resolved: also collect statistics about negative DNSSEC proofs
[thirdparty/systemd.git] / src / resolve / resolved-dns-transaction.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <sd-messages.h>
23
24 #include "af-list.h"
25 #include "alloc-util.h"
26 #include "dns-domain.h"
27 #include "fd-util.h"
28 #include "random-util.h"
29 #include "resolved-dns-cache.h"
30 #include "resolved-dns-transaction.h"
31 #include "resolved-llmnr.h"
32 #include "string-table.h"
33
34 #define TRANSACTIONS_MAX 4096
35
36 static void dns_transaction_reset_answer(DnsTransaction *t) {
37 assert(t);
38
39 t->received = dns_packet_unref(t->received);
40 t->answer = dns_answer_unref(t->answer);
41 t->answer_rcode = 0;
42 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
43 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
44 t->answer_authenticated = false;
45 t->answer_nsec_ttl = (uint32_t) -1;
46 }
47
48 static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) {
49 DnsTransaction *z;
50
51 assert(t);
52
53 while ((z = set_steal_first(t->dnssec_transactions))) {
54 set_remove(z->notify_transactions, t);
55 dns_transaction_gc(z);
56 }
57 }
58
59 static void dns_transaction_close_connection(DnsTransaction *t) {
60 assert(t);
61
62 t->stream = dns_stream_free(t->stream);
63 t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source);
64 t->dns_udp_fd = safe_close(t->dns_udp_fd);
65 }
66
67 static void dns_transaction_stop_timeout(DnsTransaction *t) {
68 assert(t);
69
70 t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
71 }
72
73 DnsTransaction* dns_transaction_free(DnsTransaction *t) {
74 DnsQueryCandidate *c;
75 DnsZoneItem *i;
76 DnsTransaction *z;
77
78 if (!t)
79 return NULL;
80
81 log_debug("Freeing transaction %" PRIu16 ".", t->id);
82
83 dns_transaction_close_connection(t);
84 dns_transaction_stop_timeout(t);
85
86 dns_packet_unref(t->sent);
87 dns_transaction_reset_answer(t);
88
89 dns_server_unref(t->server);
90
91 if (t->scope) {
92 hashmap_remove_value(t->scope->transactions_by_key, t->key, t);
93 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
94
95 if (t->id != 0)
96 hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
97 }
98
99 while ((c = set_steal_first(t->notify_query_candidates)))
100 set_remove(c->transactions, t);
101 set_free(t->notify_query_candidates);
102
103 while ((i = set_steal_first(t->notify_zone_items)))
104 i->probe_transaction = NULL;
105 set_free(t->notify_zone_items);
106
107 while ((z = set_steal_first(t->notify_transactions)))
108 set_remove(z->dnssec_transactions, t);
109 set_free(t->notify_transactions);
110
111 dns_transaction_flush_dnssec_transactions(t);
112 set_free(t->dnssec_transactions);
113
114 dns_answer_unref(t->validated_keys);
115 dns_resource_key_unref(t->key);
116 free(t->key_string);
117
118 free(t);
119 return NULL;
120 }
121
122 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
123
124 bool dns_transaction_gc(DnsTransaction *t) {
125 assert(t);
126
127 if (t->block_gc > 0)
128 return true;
129
130 if (set_isempty(t->notify_query_candidates) &&
131 set_isempty(t->notify_zone_items) &&
132 set_isempty(t->notify_transactions)) {
133 dns_transaction_free(t);
134 return false;
135 }
136
137 return true;
138 }
139
140 static uint16_t pick_new_id(Manager *m) {
141 uint16_t new_id;
142
143 /* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the number of
144 * transactions, and it's much lower than the space of IDs. */
145
146 assert_cc(TRANSACTIONS_MAX < 0xFFFF);
147
148 do
149 random_bytes(&new_id, sizeof(new_id));
150 while (new_id == 0 ||
151 hashmap_get(m->dns_transactions, UINT_TO_PTR(new_id)));
152
153 return new_id;
154 }
155
156 int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) {
157 _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
158 int r;
159
160 assert(ret);
161 assert(s);
162 assert(key);
163
164 /* Don't allow looking up invalid or pseudo RRs */
165 if (!dns_type_is_valid_query(key->type))
166 return -EINVAL;
167 if (dns_type_is_obsolete(key->type))
168 return -EOPNOTSUPP;
169
170 /* We only support the IN class */
171 if (key->class != DNS_CLASS_IN && key->class != DNS_CLASS_ANY)
172 return -EOPNOTSUPP;
173
174 if (hashmap_size(s->manager->dns_transactions) >= TRANSACTIONS_MAX)
175 return -EBUSY;
176
177 r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
178 if (r < 0)
179 return r;
180
181 r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
182 if (r < 0)
183 return r;
184
185 t = new0(DnsTransaction, 1);
186 if (!t)
187 return -ENOMEM;
188
189 t->dns_udp_fd = -1;
190 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
191 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
192 t->answer_nsec_ttl = (uint32_t) -1;
193 t->key = dns_resource_key_ref(key);
194 t->current_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
195
196 t->id = pick_new_id(s->manager);
197
198 r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
199 if (r < 0) {
200 t->id = 0;
201 return r;
202 }
203
204 r = hashmap_replace(s->transactions_by_key, t->key, t);
205 if (r < 0) {
206 hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
207 return r;
208 }
209
210 LIST_PREPEND(transactions_by_scope, s->transactions, t);
211 t->scope = s;
212
213 s->manager->n_transactions_total ++;
214
215 if (ret)
216 *ret = t;
217
218 t = NULL;
219
220 return 0;
221 }
222
223 static void dns_transaction_shuffle_id(DnsTransaction *t) {
224 uint16_t new_id;
225 assert(t);
226
227 /* Pick a new ID for this transaction. */
228
229 new_id = pick_new_id(t->scope->manager);
230 assert_se(hashmap_remove_and_put(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id), UINT_TO_PTR(new_id), t) >= 0);
231
232 log_debug("Transaction %" PRIu16 " is now %" PRIu16 ".", t->id, new_id);
233 t->id = new_id;
234
235 /* Make sure we generate a new packet with the new ID */
236 t->sent = dns_packet_unref(t->sent);
237 }
238
239 static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
240 _cleanup_free_ char *pretty = NULL;
241 DnsZoneItem *z;
242
243 assert(t);
244 assert(p);
245
246 if (manager_our_packet(t->scope->manager, p) != 0)
247 return;
248
249 in_addr_to_string(p->family, &p->sender, &pretty);
250
251 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s got tentative packet from %s.",
252 t->id,
253 dns_transaction_key_string(t),
254 dns_protocol_to_string(t->scope->protocol),
255 t->scope->link ? t->scope->link->name : "*",
256 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
257 pretty);
258
259 /* RFC 4795, Section 4.1 says that the peer with the
260 * lexicographically smaller IP address loses */
261 if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
262 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
263 return;
264 }
265
266 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
267
268 t->block_gc++;
269 while ((z = set_first(t->notify_zone_items))) {
270 /* First, make sure the zone item drops the reference
271 * to us */
272 dns_zone_item_probe_stop(z);
273
274 /* Secondly, report this as conflict, so that we might
275 * look for a different hostname */
276 dns_zone_item_conflict(z);
277 }
278 t->block_gc--;
279
280 dns_transaction_gc(t);
281 }
282
283 void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
284 DnsQueryCandidate *c;
285 DnsZoneItem *z;
286 DnsTransaction *d;
287 Iterator i;
288
289 assert(t);
290 assert(!DNS_TRANSACTION_IS_LIVE(state));
291
292 if (state == DNS_TRANSACTION_DNSSEC_FAILED)
293 log_struct(LOG_NOTICE,
294 LOG_MESSAGE_ID(SD_MESSAGE_DNSSEC_FAILURE),
295 LOG_MESSAGE("DNSSEC validation failed for question %s: %s", dns_transaction_key_string(t), dnssec_result_to_string(t->answer_dnssec_result)),
296 "DNS_TRANSACTION=%" PRIu16, t->id,
297 "DNS_QUESTION=%s", dns_transaction_key_string(t),
298 "DNSSEC_RESULT=%s", dnssec_result_to_string(t->answer_dnssec_result),
299 NULL);
300
301 /* Note that this call might invalidate the query. Callers
302 * should hence not attempt to access the query or transaction
303 * after calling this function. */
304
305 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).",
306 t->id,
307 dns_transaction_key_string(t),
308 dns_protocol_to_string(t->scope->protocol),
309 t->scope->link ? t->scope->link->name : "*",
310 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
311 dns_transaction_state_to_string(state),
312 t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
313 t->answer_authenticated ? "authenticated" : "unsigned");
314
315 t->state = state;
316
317 dns_transaction_close_connection(t);
318 dns_transaction_stop_timeout(t);
319
320 /* Notify all queries that are interested, but make sure the
321 * transaction isn't freed while we are still looking at it */
322 t->block_gc++;
323
324 SET_FOREACH(c, t->notify_query_candidates, i)
325 dns_query_candidate_notify(c);
326 SET_FOREACH(z, t->notify_zone_items, i)
327 dns_zone_item_notify(z);
328
329 if (!set_isempty(t->notify_transactions)) {
330 DnsTransaction **nt;
331 unsigned j, n = 0;
332
333 /* We need to be careful when notifying other
334 * transactions, as that might destroy other
335 * transactions in our list. Hence, in order to be
336 * able to safely iterate through the list of
337 * transactions, take a GC lock on all of them
338 * first. Then, in a second loop, notify them, but
339 * first unlock that specific transaction. */
340
341 nt = newa(DnsTransaction*, set_size(t->notify_transactions));
342 SET_FOREACH(d, t->notify_transactions, i) {
343 nt[n++] = d;
344 d->block_gc++;
345 }
346
347 assert(n == set_size(t->notify_transactions));
348
349 for (j = 0; j < n; j++) {
350 if (set_contains(t->notify_transactions, nt[j]))
351 dns_transaction_notify(nt[j], t);
352
353 nt[j]->block_gc--;
354 dns_transaction_gc(nt[j]);
355 }
356 }
357
358 t->block_gc--;
359 dns_transaction_gc(t);
360 }
361
362 static int dns_transaction_pick_server(DnsTransaction *t) {
363 DnsServer *server;
364
365 assert(t);
366 assert(t->scope->protocol == DNS_PROTOCOL_DNS);
367
368 server = dns_scope_get_dns_server(t->scope);
369 if (!server)
370 return -ESRCH;
371
372 t->current_feature_level = dns_server_possible_feature_level(server);
373
374 if (server == t->server)
375 return 0;
376
377 dns_server_unref(t->server);
378 t->server = dns_server_ref(server);
379
380 return 1;
381 }
382
383 static void dns_transaction_retry(DnsTransaction *t) {
384 int r;
385
386 assert(t);
387
388 log_debug("Retrying transaction %" PRIu16 ".", t->id);
389
390 /* Before we try again, switch to a new server. */
391 dns_scope_next_dns_server(t->scope);
392
393 r = dns_transaction_go(t);
394 if (r < 0)
395 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
396 }
397
398 static int dns_transaction_maybe_restart(DnsTransaction *t) {
399 assert(t);
400
401 if (!t->server)
402 return 0;
403
404 if (t->current_feature_level <= dns_server_possible_feature_level(t->server))
405 return 0;
406
407 /* The server's current feature level is lower than when we sent the original query. We learnt something from
408 the response or possibly an auxiliary DNSSEC response that we didn't know before. We take that as reason to
409 restart the whole transaction. This is a good idea to deal with servers that respond rubbish if we include
410 OPT RR or DO bit. One of these cases is documented here, for example:
411 https://open.nlnetlabs.nl/pipermail/dnssec-trigger/2014-November/000376.html */
412
413 log_debug("Server feature level is now lower than when we began our transaction. Restarting with new ID.");
414 dns_transaction_shuffle_id(t);
415 return dns_transaction_go(t);
416 }
417
418 static int on_stream_complete(DnsStream *s, int error) {
419 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
420 DnsTransaction *t;
421
422 assert(s);
423 assert(s->transaction);
424
425 /* Copy the data we care about out of the stream before we
426 * destroy it. */
427 t = s->transaction;
428 p = dns_packet_ref(s->read_packet);
429
430 t->stream = dns_stream_free(t->stream);
431
432 if (ERRNO_IS_DISCONNECT(error)) {
433 usec_t usec;
434
435 log_debug_errno(error, "Connection failure for DNS TCP stream: %m");
436 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
437 dns_server_packet_lost(t->server, IPPROTO_TCP, t->current_feature_level, usec - t->start_usec);
438
439 dns_transaction_retry(t);
440 return 0;
441 }
442 if (error != 0) {
443 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
444 return 0;
445 }
446
447 if (dns_packet_validate_reply(p) <= 0) {
448 log_debug("Invalid TCP reply packet.");
449 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
450 return 0;
451 }
452
453 dns_scope_check_conflicts(t->scope, p);
454
455 t->block_gc++;
456 dns_transaction_process_reply(t, p);
457 t->block_gc--;
458
459 /* If the response wasn't useful, then complete the transition
460 * now. After all, we are the worst feature set now with TCP
461 * sockets, and there's really no point in retrying. */
462 if (t->state == DNS_TRANSACTION_PENDING)
463 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
464 else
465 dns_transaction_gc(t);
466
467 return 0;
468 }
469
470 static int dns_transaction_open_tcp(DnsTransaction *t) {
471 _cleanup_close_ int fd = -1;
472 int r;
473
474 assert(t);
475
476 dns_transaction_close_connection(t);
477
478 switch (t->scope->protocol) {
479
480 case DNS_PROTOCOL_DNS:
481 r = dns_transaction_pick_server(t);
482 if (r < 0)
483 return r;
484
485 if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
486 return -EOPNOTSUPP;
487
488 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
489 if (r < 0)
490 return r;
491
492 fd = dns_scope_socket_tcp(t->scope, AF_UNSPEC, NULL, t->server, 53);
493 break;
494
495 case DNS_PROTOCOL_LLMNR:
496 /* When we already received a reply to this (but it was truncated), send to its sender address */
497 if (t->received)
498 fd = dns_scope_socket_tcp(t->scope, t->received->family, &t->received->sender, NULL, t->received->sender_port);
499 else {
500 union in_addr_union address;
501 int family = AF_UNSPEC;
502
503 /* Otherwise, try to talk to the owner of a
504 * the IP address, in case this is a reverse
505 * PTR lookup */
506
507 r = dns_name_address(DNS_RESOURCE_KEY_NAME(t->key), &family, &address);
508 if (r < 0)
509 return r;
510 if (r == 0)
511 return -EINVAL;
512 if (family != t->scope->family)
513 return -ESRCH;
514
515 fd = dns_scope_socket_tcp(t->scope, family, &address, NULL, LLMNR_PORT);
516 }
517
518 break;
519
520 default:
521 return -EAFNOSUPPORT;
522 }
523
524 if (fd < 0)
525 return fd;
526
527 r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
528 if (r < 0)
529 return r;
530 fd = -1;
531
532 r = dns_stream_write_packet(t->stream, t->sent);
533 if (r < 0) {
534 t->stream = dns_stream_free(t->stream);
535 return r;
536 }
537
538 t->stream->complete = on_stream_complete;
539 t->stream->transaction = t;
540
541 /* The interface index is difficult to determine if we are
542 * connecting to the local host, hence fill this in right away
543 * instead of determining it from the socket */
544 if (t->scope->link)
545 t->stream->ifindex = t->scope->link->ifindex;
546
547 dns_transaction_reset_answer(t);
548
549 t->tried_stream = true;
550
551 return 0;
552 }
553
554 static void dns_transaction_cache_answer(DnsTransaction *t) {
555 assert(t);
556
557 /* For mDNS we cache whenever we get the packet, rather than
558 * in each transaction. */
559 if (!IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR))
560 return;
561
562 /* We never cache if this packet is from the local host, under
563 * the assumption that a locally running DNS server would
564 * cache this anyway, and probably knows better when to flush
565 * the cache then we could. */
566 if (!DNS_PACKET_SHALL_CACHE(t->received))
567 return;
568
569 dns_cache_put(&t->scope->cache,
570 t->key,
571 t->answer_rcode,
572 t->answer,
573 t->answer_authenticated,
574 t->answer_nsec_ttl,
575 0,
576 t->received->family,
577 &t->received->sender);
578 }
579
580 static bool dns_transaction_dnssec_is_live(DnsTransaction *t) {
581 DnsTransaction *dt;
582 Iterator i;
583
584 assert(t);
585
586 SET_FOREACH(dt, t->dnssec_transactions, i)
587 if (DNS_TRANSACTION_IS_LIVE(dt->state))
588 return true;
589
590 return false;
591 }
592
593 static int dns_transaction_dnssec_ready(DnsTransaction *t) {
594 DnsTransaction *dt;
595 Iterator i;
596
597 assert(t);
598
599 /* Checks whether the auxiliary DNSSEC transactions of our transaction have completed, or are still
600 * ongoing. Returns 0, if we aren't ready for the DNSSEC validation, positive if we are. */
601
602 SET_FOREACH(dt, t->dnssec_transactions, i) {
603
604 switch (dt->state) {
605
606 case DNS_TRANSACTION_NULL:
607 case DNS_TRANSACTION_PENDING:
608 case DNS_TRANSACTION_VALIDATING:
609 /* Still ongoing */
610 return 0;
611
612 case DNS_TRANSACTION_RCODE_FAILURE:
613 if (dt->answer_rcode != DNS_RCODE_NXDOMAIN) {
614 log_debug("Auxiliary DNSSEC RR query failed with rcode=%s.", dns_rcode_to_string(dt->answer_rcode));
615 goto fail;
616 }
617
618 /* Fall-through: NXDOMAIN is good enough for us. This is because some DNS servers erronously
619 * return NXDOMAIN for empty non-terminals (Akamai...), and we need to handle that nicely, when
620 * asking for parent SOA or similar RRs to make unsigned proofs. */
621
622 case DNS_TRANSACTION_SUCCESS:
623 /* All good. */
624 break;
625
626 case DNS_TRANSACTION_DNSSEC_FAILED:
627 /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
628 * validationr result */
629
630 log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result));
631 t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */
632 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
633 return 0;
634
635
636 default:
637 log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(dt->state));
638 goto fail;
639 }
640 }
641
642 /* All is ready, we can go and validate */
643 return 1;
644
645 fail:
646 t->answer_dnssec_result = DNSSEC_FAILED_AUXILIARY;
647 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
648 return 0;
649 }
650
651 static void dns_transaction_process_dnssec(DnsTransaction *t) {
652 int r;
653
654 assert(t);
655
656 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
657 r = dns_transaction_dnssec_ready(t);
658 if (r < 0) {
659 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
660 return;
661 }
662 if (r == 0) /* We aren't ready yet (or one of our auxiliary transactions failed, and we shouldn't validate now */
663 return;
664
665 /* See if we learnt things from the additional DNSSEC transactions, that we didn't know before, and better
666 * restart the lookup immediately. */
667 r = dns_transaction_maybe_restart(t);
668 if (r < 0) {
669 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
670 return;
671 }
672 if (r > 0) /* Transaction got restarted... */
673 return;
674
675 /* All our auxiliary DNSSEC transactions are complete now. Try
676 * to validate our RRset now. */
677 r = dns_transaction_validate_dnssec(t);
678 if (r < 0) {
679 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
680 return;
681 }
682
683 if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER &&
684 t->scope->dnssec_mode == DNSSEC_YES) {
685 /* We are not in automatic downgrade mode, and the
686 * server is bad, refuse operation. */
687 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
688 return;
689 }
690
691 if (!IN_SET(t->answer_dnssec_result,
692 _DNSSEC_RESULT_INVALID, /* No DNSSEC validation enabled */
693 DNSSEC_VALIDATED, /* Answer is signed and validated successfully */
694 DNSSEC_UNSIGNED, /* Answer is right-fully unsigned */
695 DNSSEC_INCOMPATIBLE_SERVER)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
696 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
697 return;
698 }
699
700 dns_transaction_cache_answer(t);
701
702 if (t->answer_rcode == DNS_RCODE_SUCCESS)
703 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
704 else
705 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
706 }
707
708 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
709 usec_t ts;
710 int r;
711
712 assert(t);
713 assert(p);
714 assert(t->scope);
715 assert(t->scope->manager);
716
717 if (t->state != DNS_TRANSACTION_PENDING)
718 return;
719
720 /* Note that this call might invalidate the query. Callers
721 * should hence not attempt to access the query or transaction
722 * after calling this function. */
723
724 log_debug("Processing incoming packet on transaction %" PRIu16".", t->id);
725
726 switch (t->scope->protocol) {
727
728 case DNS_PROTOCOL_LLMNR:
729 assert(t->scope->link);
730
731 /* For LLMNR we will not accept any packets from other
732 * interfaces */
733
734 if (p->ifindex != t->scope->link->ifindex)
735 return;
736
737 if (p->family != t->scope->family)
738 return;
739
740 /* Tentative packets are not full responses but still
741 * useful for identifying uniqueness conflicts during
742 * probing. */
743 if (DNS_PACKET_LLMNR_T(p)) {
744 dns_transaction_tentative(t, p);
745 return;
746 }
747
748 break;
749
750 case DNS_PROTOCOL_MDNS:
751 assert(t->scope->link);
752
753 /* For mDNS we will not accept any packets from other interfaces */
754 if (p->ifindex != t->scope->link->ifindex)
755 return;
756
757 if (p->family != t->scope->family)
758 return;
759
760 break;
761
762 case DNS_PROTOCOL_DNS:
763 /* Note that we do not need to verify the
764 * addresses/port numbers of incoming traffic, as we
765 * invoked connect() on our UDP socket in which case
766 * the kernel already does the needed verification for
767 * us. */
768 break;
769
770 default:
771 assert_not_reached("Invalid DNS protocol.");
772 }
773
774 if (t->received != p) {
775 dns_packet_unref(t->received);
776 t->received = dns_packet_ref(p);
777 }
778
779 t->answer_source = DNS_TRANSACTION_NETWORK;
780
781 if (p->ipproto == IPPROTO_TCP) {
782 if (DNS_PACKET_TC(p)) {
783 /* Truncated via TCP? Somebody must be fucking with us */
784 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
785 return;
786 }
787
788 if (DNS_PACKET_ID(p) != t->id) {
789 /* Not the reply to our query? Somebody must be fucking with us */
790 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
791 return;
792 }
793 }
794
795 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
796
797 switch (t->scope->protocol) {
798
799 case DNS_PROTOCOL_DNS:
800 assert(t->server);
801
802 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
803
804 /* Request failed, immediately try again with reduced features */
805 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
806
807 dns_server_packet_failed(t->server, t->current_feature_level);
808 dns_transaction_retry(t);
809 return;
810 } else if (DNS_PACKET_TC(p))
811 dns_server_packet_truncated(t->server, t->current_feature_level);
812
813 break;
814
815 case DNS_PROTOCOL_LLMNR:
816 case DNS_PROTOCOL_MDNS:
817 dns_scope_packet_received(t->scope, ts - t->start_usec);
818 break;
819
820 default:
821 assert_not_reached("Invalid DNS protocol.");
822 }
823
824 if (DNS_PACKET_TC(p)) {
825
826 /* Truncated packets for mDNS are not allowed. Give up immediately. */
827 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
828 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
829 return;
830 }
831
832 log_debug("Reply truncated, retrying via TCP.");
833
834 /* Response was truncated, let's try again with good old TCP */
835 r = dns_transaction_open_tcp(t);
836 if (r == -ESRCH) {
837 /* No servers found? Damn! */
838 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
839 return;
840 }
841 if (r == -EOPNOTSUPP) {
842 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
843 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
844 return;
845 }
846 if (r < 0) {
847 /* On LLMNR, if we cannot connect to the host,
848 * we immediately give up */
849 if (t->scope->protocol != DNS_PROTOCOL_DNS) {
850 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
851 return;
852 }
853
854 /* On DNS, couldn't send? Try immediately again, with a new server */
855 dns_transaction_retry(t);
856 }
857
858 return;
859 }
860
861 /* After the superficial checks, actually parse the message. */
862 r = dns_packet_extract(p);
863 if (r < 0) {
864 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
865 return;
866 }
867
868 /* Report that the OPT RR was missing */
869 if (t->server) {
870 if (!p->opt)
871 dns_server_packet_bad_opt(t->server, t->current_feature_level);
872
873 dns_server_packet_received(t->server, p->ipproto, t->current_feature_level, ts - t->start_usec, p->size);
874 }
875
876 /* See if we know things we didn't know before that indicate we better restart the lookup immediately. */
877 r = dns_transaction_maybe_restart(t);
878 if (r < 0) {
879 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
880 return;
881 }
882 if (r > 0) /* Transaction got restarted... */
883 return;
884
885 if (IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR)) {
886
887 /* Only consider responses with equivalent query section to the request */
888 r = dns_packet_is_reply_for(p, t->key);
889 if (r < 0) {
890 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
891 return;
892 }
893 if (r == 0) {
894 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
895 return;
896 }
897
898 /* Install the answer as answer to the transaction */
899 dns_answer_unref(t->answer);
900 t->answer = dns_answer_ref(p->answer);
901 t->answer_rcode = DNS_PACKET_RCODE(p);
902 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
903 t->answer_authenticated = false;
904
905 /* Block GC while starting requests for additional DNSSEC RRs */
906 t->block_gc++;
907 r = dns_transaction_request_dnssec_keys(t);
908 t->block_gc--;
909
910 /* Maybe the transaction is ready for GC'ing now? If so, free it and return. */
911 if (!dns_transaction_gc(t))
912 return;
913
914 /* Requesting additional keys might have resulted in
915 * this transaction to fail, since the auxiliary
916 * request failed for some reason. If so, we are not
917 * in pending state anymore, and we should exit
918 * quickly. */
919 if (t->state != DNS_TRANSACTION_PENDING)
920 return;
921 if (r < 0) {
922 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
923 return;
924 }
925 if (r > 0) {
926 /* There are DNSSEC transactions pending now. Update the state accordingly. */
927 t->state = DNS_TRANSACTION_VALIDATING;
928 dns_transaction_close_connection(t);
929 dns_transaction_stop_timeout(t);
930 return;
931 }
932 }
933
934 dns_transaction_process_dnssec(t);
935 }
936
937 static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
938 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
939 DnsTransaction *t = userdata;
940 int r;
941
942 assert(t);
943 assert(t->scope);
944
945 r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
946 if (ERRNO_IS_DISCONNECT(-r)) {
947 usec_t usec;
948
949 /* UDP connection failure get reported via ICMP and then are possible delivered to us on the next
950 * recvmsg(). Treat this like a lost packet. */
951
952 log_debug_errno(r, "Connection failure for DNS UDP packet: %m");
953 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
954 dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level, usec - t->start_usec);
955
956 dns_transaction_retry(t);
957 return 0;
958 }
959 if (r < 0) {
960 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
961 return 0;
962 }
963
964 r = dns_packet_validate_reply(p);
965 if (r < 0) {
966 log_debug_errno(r, "Received invalid DNS packet as response, ignoring: %m");
967 return 0;
968 }
969 if (r == 0) {
970 log_debug("Received inappropriate DNS packet as response, ignoring.");
971 return 0;
972 }
973
974 if (DNS_PACKET_ID(p) != t->id) {
975 log_debug("Received packet with incorrect transaction ID, ignoring.");
976 return 0;
977 }
978
979 dns_transaction_process_reply(t, p);
980 return 0;
981 }
982
983 static int dns_transaction_emit_udp(DnsTransaction *t) {
984 int r;
985
986 assert(t);
987
988 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
989
990 r = dns_transaction_pick_server(t);
991 if (r < 0)
992 return r;
993
994 if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_UDP)
995 return -EAGAIN;
996
997 if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
998 return -EOPNOTSUPP;
999
1000 if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */
1001 int fd;
1002
1003 dns_transaction_close_connection(t);
1004
1005 fd = dns_scope_socket_udp(t->scope, t->server, 53);
1006 if (fd < 0)
1007 return fd;
1008
1009 r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
1010 if (r < 0) {
1011 safe_close(fd);
1012 return r;
1013 }
1014
1015 (void) sd_event_source_set_description(t->dns_udp_event_source, "dns-transaction-udp");
1016 t->dns_udp_fd = fd;
1017 }
1018
1019 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
1020 if (r < 0)
1021 return r;
1022 } else
1023 dns_transaction_close_connection(t);
1024
1025 r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->sent);
1026 if (r < 0)
1027 return r;
1028
1029 dns_transaction_reset_answer(t);
1030
1031 return 0;
1032 }
1033
1034 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
1035 DnsTransaction *t = userdata;
1036
1037 assert(s);
1038 assert(t);
1039
1040 if (!t->initial_jitter_scheduled || t->initial_jitter_elapsed) {
1041 /* Timeout reached? Increase the timeout for the server used */
1042 switch (t->scope->protocol) {
1043
1044 case DNS_PROTOCOL_DNS:
1045 assert(t->server);
1046 dns_server_packet_lost(t->server, t->stream ? IPPROTO_TCP : IPPROTO_UDP, t->current_feature_level, usec - t->start_usec);
1047 break;
1048
1049 case DNS_PROTOCOL_LLMNR:
1050 case DNS_PROTOCOL_MDNS:
1051 dns_scope_packet_lost(t->scope, usec - t->start_usec);
1052 break;
1053
1054 default:
1055 assert_not_reached("Invalid DNS protocol.");
1056 }
1057
1058 if (t->initial_jitter_scheduled)
1059 t->initial_jitter_elapsed = true;
1060 }
1061
1062 log_debug("Timeout reached on transaction %" PRIu16 ".", t->id);
1063
1064 dns_transaction_retry(t);
1065 return 0;
1066 }
1067
1068 static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
1069 assert(t);
1070 assert(t->scope);
1071
1072 switch (t->scope->protocol) {
1073
1074 case DNS_PROTOCOL_DNS:
1075 assert(t->server);
1076 return t->server->resend_timeout;
1077
1078 case DNS_PROTOCOL_MDNS:
1079 assert(t->n_attempts > 0);
1080 return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
1081
1082 case DNS_PROTOCOL_LLMNR:
1083 return t->scope->resend_timeout;
1084
1085 default:
1086 assert_not_reached("Invalid DNS protocol.");
1087 }
1088 }
1089
1090 static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
1091 int r;
1092
1093 assert(t);
1094
1095 dns_transaction_stop_timeout(t);
1096
1097 r = dns_scope_network_good(t->scope);
1098 if (r < 0)
1099 return r;
1100 if (r == 0) {
1101 dns_transaction_complete(t, DNS_TRANSACTION_NETWORK_DOWN);
1102 return 0;
1103 }
1104
1105 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
1106 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1107 return 0;
1108 }
1109
1110 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && t->tried_stream) {
1111 /* If we already tried via a stream, then we don't
1112 * retry on LLMNR. See RFC 4795, Section 2.7. */
1113 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1114 return 0;
1115 }
1116
1117 t->n_attempts++;
1118 t->start_usec = ts;
1119
1120 dns_transaction_reset_answer(t);
1121 dns_transaction_flush_dnssec_transactions(t);
1122
1123 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
1124 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
1125 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, t->key, &t->answer);
1126 if (r < 0)
1127 return r;
1128 if (r > 0) {
1129 t->answer_rcode = DNS_RCODE_SUCCESS;
1130 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
1131 t->answer_authenticated = true;
1132 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1133 return 0;
1134 }
1135
1136 if (dns_name_is_root(DNS_RESOURCE_KEY_NAME(t->key)) &&
1137 t->key->type == DNS_TYPE_DS) {
1138
1139 /* Hmm, this is a request for the root DS? A
1140 * DS RR doesn't exist in the root zone, and
1141 * if our trust anchor didn't know it either,
1142 * this means we cannot do any DNSSEC logic
1143 * anymore. */
1144
1145 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
1146 /* We are in downgrade mode. In this
1147 * case, synthesize an unsigned empty
1148 * response, so that the any lookup
1149 * depending on this one can continue
1150 * assuming there was no DS, and hence
1151 * the root zone was unsigned. */
1152
1153 t->answer_rcode = DNS_RCODE_SUCCESS;
1154 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
1155 t->answer_authenticated = false;
1156 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1157 } else
1158 /* If we are not in downgrade mode,
1159 * then fail the lookup, because we
1160 * cannot reasonably answer it. There
1161 * might be DS RRs, but we don't know
1162 * them, and the DNS server won't tell
1163 * them to us (and even if it would,
1164 * we couldn't validate it and trust
1165 * it). */
1166 dns_transaction_complete(t, DNS_TRANSACTION_NO_TRUST_ANCHOR);
1167
1168 return 0;
1169 }
1170 }
1171
1172 /* Check the zone, but only if this transaction is not used
1173 * for probing or verifying a zone item. */
1174 if (set_isempty(t->notify_zone_items)) {
1175
1176 r = dns_zone_lookup(&t->scope->zone, t->key, &t->answer, NULL, NULL);
1177 if (r < 0)
1178 return r;
1179 if (r > 0) {
1180 t->answer_rcode = DNS_RCODE_SUCCESS;
1181 t->answer_source = DNS_TRANSACTION_ZONE;
1182 t->answer_authenticated = true;
1183 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1184 return 0;
1185 }
1186 }
1187
1188 /* Check the cache, but only if this transaction is not used
1189 * for probing or verifying a zone item. */
1190 if (set_isempty(t->notify_zone_items)) {
1191
1192 /* Before trying the cache, let's make sure we figured out a
1193 * server to use. Should this cause a change of server this
1194 * might flush the cache. */
1195 dns_scope_get_dns_server(t->scope);
1196
1197 /* Let's then prune all outdated entries */
1198 dns_cache_prune(&t->scope->cache);
1199
1200 r = dns_cache_lookup(&t->scope->cache, t->key, &t->answer_rcode, &t->answer, &t->answer_authenticated);
1201 if (r < 0)
1202 return r;
1203 if (r > 0) {
1204 t->answer_source = DNS_TRANSACTION_CACHE;
1205 if (t->answer_rcode == DNS_RCODE_SUCCESS)
1206 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1207 else
1208 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
1209 return 0;
1210 }
1211 }
1212
1213 return 1;
1214 }
1215
1216 static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
1217
1218 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1219 bool add_known_answers = false;
1220 DnsTransaction *other;
1221 unsigned qdcount;
1222 usec_t ts;
1223 int r;
1224
1225 assert(t);
1226 assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
1227
1228 /* Discard any previously prepared packet, so we can start over and coalesce again */
1229 t->sent = dns_packet_unref(t->sent);
1230
1231 r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
1232 if (r < 0)
1233 return r;
1234
1235 r = dns_packet_append_key(p, t->key, NULL);
1236 if (r < 0)
1237 return r;
1238
1239 qdcount = 1;
1240
1241 if (dns_key_is_shared(t->key))
1242 add_known_answers = true;
1243
1244 /*
1245 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
1246 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
1247 * in our current scope, and see whether their timing contraints allow them to be sent.
1248 */
1249
1250 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
1251
1252 LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
1253
1254 /* Skip ourselves */
1255 if (other == t)
1256 continue;
1257
1258 if (other->state != DNS_TRANSACTION_PENDING)
1259 continue;
1260
1261 if (other->next_attempt_after > ts)
1262 continue;
1263
1264 if (qdcount >= UINT16_MAX)
1265 break;
1266
1267 r = dns_packet_append_key(p, other->key, NULL);
1268
1269 /*
1270 * If we can't stuff more questions into the packet, just give up.
1271 * One of the 'other' transactions will fire later and take care of the rest.
1272 */
1273 if (r == -EMSGSIZE)
1274 break;
1275
1276 if (r < 0)
1277 return r;
1278
1279 r = dns_transaction_prepare(other, ts);
1280 if (r <= 0)
1281 continue;
1282
1283 ts += transaction_get_resend_timeout(other);
1284
1285 r = sd_event_add_time(
1286 other->scope->manager->event,
1287 &other->timeout_event_source,
1288 clock_boottime_or_monotonic(),
1289 ts, 0,
1290 on_transaction_timeout, other);
1291 if (r < 0)
1292 return r;
1293
1294 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1295
1296 other->state = DNS_TRANSACTION_PENDING;
1297 other->next_attempt_after = ts;
1298
1299 qdcount ++;
1300
1301 if (dns_key_is_shared(other->key))
1302 add_known_answers = true;
1303 }
1304
1305 DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
1306
1307 /* Append known answer section if we're asking for any shared record */
1308 if (add_known_answers) {
1309 r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
1310 if (r < 0)
1311 return r;
1312 }
1313
1314 t->sent = p;
1315 p = NULL;
1316
1317 return 0;
1318 }
1319
1320 static int dns_transaction_make_packet(DnsTransaction *t) {
1321 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1322 int r;
1323
1324 assert(t);
1325
1326 if (t->scope->protocol == DNS_PROTOCOL_MDNS)
1327 return dns_transaction_make_packet_mdns(t);
1328
1329 if (t->sent)
1330 return 0;
1331
1332 r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode != DNSSEC_NO);
1333 if (r < 0)
1334 return r;
1335
1336 r = dns_scope_good_key(t->scope, t->key);
1337 if (r < 0)
1338 return r;
1339 if (r == 0)
1340 return -EDOM;
1341
1342 r = dns_packet_append_key(p, t->key, NULL);
1343 if (r < 0)
1344 return r;
1345
1346 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
1347 DNS_PACKET_HEADER(p)->id = t->id;
1348
1349 t->sent = p;
1350 p = NULL;
1351
1352 return 0;
1353 }
1354
1355 int dns_transaction_go(DnsTransaction *t) {
1356 usec_t ts;
1357 int r;
1358
1359 assert(t);
1360
1361 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
1362
1363 r = dns_transaction_prepare(t, ts);
1364 if (r <= 0)
1365 return r;
1366
1367 log_debug("Excercising transaction %" PRIu16 " for <%s> on scope %s on %s/%s.",
1368 t->id,
1369 dns_transaction_key_string(t),
1370 dns_protocol_to_string(t->scope->protocol),
1371 t->scope->link ? t->scope->link->name : "*",
1372 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
1373
1374 if (!t->initial_jitter_scheduled &&
1375 (t->scope->protocol == DNS_PROTOCOL_LLMNR ||
1376 t->scope->protocol == DNS_PROTOCOL_MDNS)) {
1377 usec_t jitter, accuracy;
1378
1379 /* RFC 4795 Section 2.7 suggests all queries should be
1380 * delayed by a random time from 0 to JITTER_INTERVAL. */
1381
1382 t->initial_jitter_scheduled = true;
1383
1384 random_bytes(&jitter, sizeof(jitter));
1385
1386 switch (t->scope->protocol) {
1387
1388 case DNS_PROTOCOL_LLMNR:
1389 jitter %= LLMNR_JITTER_INTERVAL_USEC;
1390 accuracy = LLMNR_JITTER_INTERVAL_USEC;
1391 break;
1392
1393 case DNS_PROTOCOL_MDNS:
1394 jitter %= MDNS_JITTER_RANGE_USEC;
1395 jitter += MDNS_JITTER_MIN_USEC;
1396 accuracy = MDNS_JITTER_RANGE_USEC;
1397 break;
1398 default:
1399 assert_not_reached("bad protocol");
1400 }
1401
1402 r = sd_event_add_time(
1403 t->scope->manager->event,
1404 &t->timeout_event_source,
1405 clock_boottime_or_monotonic(),
1406 ts + jitter, accuracy,
1407 on_transaction_timeout, t);
1408 if (r < 0)
1409 return r;
1410
1411 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1412
1413 t->n_attempts = 0;
1414 t->next_attempt_after = ts;
1415 t->state = DNS_TRANSACTION_PENDING;
1416
1417 log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
1418 return 0;
1419 }
1420
1421 /* Otherwise, we need to ask the network */
1422 r = dns_transaction_make_packet(t);
1423 if (r == -EDOM) {
1424 /* Not the right request to make on this network?
1425 * (i.e. an A request made on IPv6 or an AAAA request
1426 * made on IPv4, on LLMNR or mDNS.) */
1427 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1428 return 0;
1429 }
1430 if (r < 0)
1431 return r;
1432
1433 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
1434 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "in-addr.arpa") > 0 ||
1435 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "ip6.arpa") > 0)) {
1436
1437 /* RFC 4795, Section 2.4. says reverse lookups shall
1438 * always be made via TCP on LLMNR */
1439 r = dns_transaction_open_tcp(t);
1440 } else {
1441 /* Try via UDP, and if that fails due to large size or lack of
1442 * support try via TCP */
1443 r = dns_transaction_emit_udp(t);
1444 if (r == -EMSGSIZE)
1445 log_debug("Sending query via TCP since it is too large.");
1446 if (r == -EAGAIN)
1447 log_debug("Sending query via TCP since server doesn't support UDP.");
1448 if (r == -EMSGSIZE || r == -EAGAIN)
1449 r = dns_transaction_open_tcp(t);
1450 }
1451
1452 if (r == -ESRCH) {
1453 /* No servers to send this to? */
1454 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1455 return 0;
1456 }
1457 if (r == -EOPNOTSUPP) {
1458 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
1459 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
1460 return 0;
1461 }
1462 if (r < 0) {
1463 if (t->scope->protocol != DNS_PROTOCOL_DNS) {
1464 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
1465 return 0;
1466 }
1467
1468 /* Couldn't send? Try immediately again, with a new server */
1469 dns_scope_next_dns_server(t->scope);
1470
1471 return dns_transaction_go(t);
1472 }
1473
1474 ts += transaction_get_resend_timeout(t);
1475
1476 r = sd_event_add_time(
1477 t->scope->manager->event,
1478 &t->timeout_event_source,
1479 clock_boottime_or_monotonic(),
1480 ts, 0,
1481 on_transaction_timeout, t);
1482 if (r < 0)
1483 return r;
1484
1485 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1486
1487 t->state = DNS_TRANSACTION_PENDING;
1488 t->next_attempt_after = ts;
1489
1490 return 1;
1491 }
1492
1493 static int dns_transaction_find_cyclic(DnsTransaction *t, DnsTransaction *aux) {
1494 DnsTransaction *n;
1495 Iterator i;
1496 int r;
1497
1498 assert(t);
1499 assert(aux);
1500
1501 /* Try to find cyclic dependencies between transaction objects */
1502
1503 if (t == aux)
1504 return 1;
1505
1506 SET_FOREACH(n, aux->dnssec_transactions, i) {
1507 r = dns_transaction_find_cyclic(t, n);
1508 if (r != 0)
1509 return r;
1510 }
1511
1512 return 0;
1513 }
1514
1515 static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
1516 DnsTransaction *aux;
1517 int r;
1518
1519 assert(t);
1520 assert(ret);
1521 assert(key);
1522
1523 aux = dns_scope_find_transaction(t->scope, key, true);
1524 if (!aux) {
1525 r = dns_transaction_new(&aux, t->scope, key);
1526 if (r < 0)
1527 return r;
1528 } else {
1529 if (set_contains(t->dnssec_transactions, aux)) {
1530 *ret = aux;
1531 return 0;
1532 }
1533
1534 r = dns_transaction_find_cyclic(t, aux);
1535 if (r < 0)
1536 return r;
1537 if (r > 0) {
1538 log_debug("Detected potential cyclic dependency, refusing to add transaction %" PRIu16 " (%s) as dependency for %" PRIu16 " (%s).",
1539 aux->id,
1540 strna(dns_transaction_key_string(aux)),
1541 t->id,
1542 strna(dns_transaction_key_string(t)));
1543 return -ELOOP;
1544 }
1545 }
1546
1547 r = set_ensure_allocated(&t->dnssec_transactions, NULL);
1548 if (r < 0)
1549 goto gc;
1550
1551 r = set_ensure_allocated(&aux->notify_transactions, NULL);
1552 if (r < 0)
1553 goto gc;
1554
1555 r = set_put(t->dnssec_transactions, aux);
1556 if (r < 0)
1557 goto gc;
1558
1559 r = set_put(aux->notify_transactions, t);
1560 if (r < 0) {
1561 (void) set_remove(t->dnssec_transactions, aux);
1562 goto gc;
1563 }
1564
1565 *ret = aux;
1566 return 1;
1567
1568 gc:
1569 dns_transaction_gc(aux);
1570 return r;
1571 }
1572
1573 static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
1574 _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL;
1575 DnsTransaction *aux;
1576 int r;
1577
1578 assert(t);
1579 assert(key);
1580
1581 /* Try to get the data from the trust anchor */
1582 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, key, &a);
1583 if (r < 0)
1584 return r;
1585 if (r > 0) {
1586 r = dns_answer_extend(&t->validated_keys, a);
1587 if (r < 0)
1588 return r;
1589
1590 return 0;
1591 }
1592
1593 /* This didn't work, ask for it via the network/cache then. */
1594 r = dns_transaction_add_dnssec_transaction(t, key, &aux);
1595 if (r == -ELOOP) /* This would result in a cyclic dependency */
1596 return 0;
1597 if (r < 0)
1598 return r;
1599
1600 if (aux->state == DNS_TRANSACTION_NULL) {
1601 r = dns_transaction_go(aux);
1602 if (r < 0)
1603 return r;
1604 }
1605
1606 return 1;
1607 }
1608
1609 static int dns_transaction_has_positive_answer(DnsTransaction *t, DnsAnswerFlags *flags) {
1610 int r;
1611
1612 assert(t);
1613
1614 /* Checks whether the answer is positive, i.e. either a direct
1615 * answer to the question, or a CNAME/DNAME for it */
1616
1617 r = dns_answer_match_key(t->answer, t->key, flags);
1618 if (r != 0)
1619 return r;
1620
1621 r = dns_answer_find_cname_or_dname(t->answer, t->key, NULL, flags);
1622 if (r != 0)
1623 return r;
1624
1625 return false;
1626 }
1627
1628 static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const char *name) {
1629 int r;
1630
1631 assert(t);
1632
1633 /* Check whether the specified name is in the the NTA
1634 * database, either in the global one, or the link-local
1635 * one. */
1636
1637 r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, name);
1638 if (r != 0)
1639 return r;
1640
1641 if (!t->scope->link)
1642 return 0;
1643
1644 return set_contains(t->scope->link->dnssec_negative_trust_anchors, name);
1645 }
1646
1647 static int dns_transaction_has_unsigned_negative_answer(DnsTransaction *t) {
1648 int r;
1649
1650 assert(t);
1651
1652 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
1653 * RRs to prove it */
1654
1655 r = dns_transaction_has_positive_answer(t, NULL);
1656 if (r < 0)
1657 return r;
1658 if (r > 0)
1659 return false;
1660
1661 /* Is this key explicitly listed as a negative trust anchor?
1662 * If so, it's nothing we need to care about */
1663 r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(t->key));
1664 if (r < 0)
1665 return r;
1666 if (r > 0)
1667 return false;
1668
1669 /* The answer does not contain any RRs that match to the
1670 * question. If so, let's see if there are any NSEC/NSEC3 RRs
1671 * included. If not, the answer is unsigned. */
1672
1673 r = dns_answer_contains_nsec_or_nsec3(t->answer);
1674 if (r < 0)
1675 return r;
1676 if (r > 0)
1677 return false;
1678
1679 return true;
1680 }
1681
1682 static int dns_transaction_is_primary_response(DnsTransaction *t, DnsResourceRecord *rr) {
1683 int r;
1684
1685 assert(t);
1686 assert(rr);
1687
1688 /* Check if the specified RR is the "primary" response,
1689 * i.e. either matches the question precisely or is a
1690 * CNAME/DNAME for it, or is any kind of NSEC/NSEC3 RR */
1691
1692 r = dns_resource_key_match_rr(t->key, rr, NULL);
1693 if (r != 0)
1694 return r;
1695
1696 r = dns_resource_key_match_cname_or_dname(t->key, rr->key, NULL);
1697 if (r != 0)
1698 return r;
1699
1700 if (rr->key->type == DNS_TYPE_NSEC3) {
1701 const char *p;
1702
1703 p = DNS_RESOURCE_KEY_NAME(rr->key);
1704 r = dns_name_parent(&p);
1705 if (r < 0)
1706 return r;
1707 if (r > 0) {
1708 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), p);
1709 if (r < 0)
1710 return r;
1711 if (r > 0)
1712 return true;
1713 }
1714 }
1715
1716 return rr->key->type == DNS_TYPE_NSEC;
1717 }
1718
1719 static bool dns_transaction_dnssec_supported(DnsTransaction *t) {
1720 assert(t);
1721
1722 /* Checks whether our transaction's DNS server is assumed to be compatible with DNSSEC. Returns false as soon
1723 * as we changed our mind about a server, and now believe it is incompatible with DNSSEC. */
1724
1725 if (t->scope->protocol != DNS_PROTOCOL_DNS)
1726 return false;
1727
1728 /* If we have picked no server, then we are working from the cache or some other source, and DNSSEC might well
1729 * be supported, hence return true. */
1730 if (!t->server)
1731 return true;
1732
1733 if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_DO)
1734 return false;
1735
1736 return dns_server_dnssec_supported(t->server);
1737 }
1738
1739 static bool dns_transaction_dnssec_supported_full(DnsTransaction *t) {
1740 DnsTransaction *dt;
1741 Iterator i;
1742
1743 assert(t);
1744
1745 /* Checks whether our transaction our any of the auxiliary transactions couldn't do DNSSEC. */
1746
1747 if (!dns_transaction_dnssec_supported(t))
1748 return false;
1749
1750 SET_FOREACH(dt, t->dnssec_transactions, i)
1751 if (!dns_transaction_dnssec_supported(dt))
1752 return false;
1753
1754 return true;
1755 }
1756
1757 int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
1758 DnsResourceRecord *rr;
1759
1760 int r;
1761
1762 assert(t);
1763
1764 /*
1765 * Retrieve all auxiliary RRs for the answer we got, so that
1766 * we can verify signatures or prove that RRs are rightfully
1767 * unsigned. Specifically:
1768 *
1769 * - For RRSIG we get the matching DNSKEY
1770 * - For DNSKEY we get the matching DS
1771 * - For unsigned SOA/NS we get the matching DS
1772 * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
1773 * - For other unsigned RRs we get the matching SOA RR
1774 * - For SOA/NS/DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
1775 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
1776 */
1777
1778 if (t->scope->dnssec_mode == DNSSEC_NO)
1779 return 0;
1780 if (t->answer_source != DNS_TRANSACTION_NETWORK)
1781 return 0; /* We only need to validate stuff from the network */
1782 if (!dns_transaction_dnssec_supported(t))
1783 return 0; /* If we can't do DNSSEC anyway there's no point in geting the auxiliary RRs */
1784
1785 DNS_ANSWER_FOREACH(rr, t->answer) {
1786
1787 if (dns_type_is_pseudo(rr->key->type))
1788 continue;
1789
1790 /* If this RR is in the negative trust anchor, we don't need to validate it. */
1791 r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key));
1792 if (r < 0)
1793 return r;
1794 if (r > 0)
1795 continue;
1796
1797 switch (rr->key->type) {
1798
1799 case DNS_TYPE_RRSIG: {
1800 /* For each RRSIG we request the matching DNSKEY */
1801 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
1802
1803 /* If this RRSIG is about a DNSKEY RR and the
1804 * signer is the same as the owner, then we
1805 * already have the DNSKEY, and we don't have
1806 * to look for more. */
1807 if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
1808 r = dns_name_equal(rr->rrsig.signer, DNS_RESOURCE_KEY_NAME(rr->key));
1809 if (r < 0)
1810 return r;
1811 if (r > 0)
1812 continue;
1813 }
1814
1815 /* If the signer is not a parent of our
1816 * original query, then this is about an
1817 * auxiliary RRset, but not anything we asked
1818 * for. In this case we aren't interested,
1819 * because we don't want to request additional
1820 * RRs for stuff we didn't really ask for, and
1821 * also to avoid request loops, where
1822 * additional RRs from one transaction result
1823 * in another transaction whose additonal RRs
1824 * point back to the original transaction, and
1825 * we deadlock. */
1826 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), rr->rrsig.signer);
1827 if (r < 0)
1828 return r;
1829 if (r == 0)
1830 continue;
1831
1832 dnskey = dns_resource_key_new(rr->key->class, DNS_TYPE_DNSKEY, rr->rrsig.signer);
1833 if (!dnskey)
1834 return -ENOMEM;
1835
1836 log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").", t->id, DNS_RESOURCE_KEY_NAME(rr->key), rr->rrsig.key_tag);
1837 r = dns_transaction_request_dnssec_rr(t, dnskey);
1838 if (r < 0)
1839 return r;
1840 break;
1841 }
1842
1843 case DNS_TYPE_DNSKEY: {
1844 /* For each DNSKEY we request the matching DS */
1845 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1846
1847 /* If the DNSKEY we are looking at is not for
1848 * zone we are interested in, nor any of its
1849 * parents, we aren't interested, and don't
1850 * request it. After all, we don't want to end
1851 * up in request loops, and want to keep
1852 * additional traffic down. */
1853
1854 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), DNS_RESOURCE_KEY_NAME(rr->key));
1855 if (r < 0)
1856 return r;
1857 if (r == 0)
1858 continue;
1859
1860 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(rr->key));
1861 if (!ds)
1862 return -ENOMEM;
1863
1864 log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").", t->id, DNS_RESOURCE_KEY_NAME(rr->key), dnssec_keytag(rr, false));
1865 r = dns_transaction_request_dnssec_rr(t, ds);
1866 if (r < 0)
1867 return r;
1868
1869 break;
1870 }
1871
1872 case DNS_TYPE_SOA:
1873 case DNS_TYPE_NS: {
1874 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1875
1876 /* For an unsigned SOA or NS, try to acquire
1877 * the matching DS RR, as we are at a zone cut
1878 * then, and whether a DS exists tells us
1879 * whether the zone is signed. Do so only if
1880 * this RR matches our original question,
1881 * however. */
1882
1883 r = dns_resource_key_match_rr(t->key, rr, NULL);
1884 if (r < 0)
1885 return r;
1886 if (r == 0)
1887 continue;
1888
1889 r = dnssec_has_rrsig(t->answer, rr->key);
1890 if (r < 0)
1891 return r;
1892 if (r > 0)
1893 continue;
1894
1895 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(rr->key));
1896 if (!ds)
1897 return -ENOMEM;
1898
1899 log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
1900 r = dns_transaction_request_dnssec_rr(t, ds);
1901 if (r < 0)
1902 return r;
1903
1904 break;
1905 }
1906
1907 case DNS_TYPE_DS:
1908 case DNS_TYPE_CNAME:
1909 case DNS_TYPE_DNAME: {
1910 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1911 const char *name;
1912
1913 /* CNAMEs and DNAMEs cannot be located at a
1914 * zone apex, hence ask for the parent SOA for
1915 * unsigned CNAME/DNAME RRs, maybe that's the
1916 * apex. But do all that only if this is
1917 * actually a response to our original
1918 * question.
1919 *
1920 * Similar for DS RRs, which are signed when
1921 * the parent SOA is signed. */
1922
1923 r = dns_transaction_is_primary_response(t, rr);
1924 if (r < 0)
1925 return r;
1926 if (r == 0)
1927 continue;
1928
1929 r = dnssec_has_rrsig(t->answer, rr->key);
1930 if (r < 0)
1931 return r;
1932 if (r > 0)
1933 continue;
1934
1935 r = dns_answer_has_dname_for_cname(t->answer, rr);
1936 if (r < 0)
1937 return r;
1938 if (r > 0)
1939 continue;
1940
1941 name = DNS_RESOURCE_KEY_NAME(rr->key);
1942 r = dns_name_parent(&name);
1943 if (r < 0)
1944 return r;
1945 if (r == 0)
1946 continue;
1947
1948 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
1949 if (!soa)
1950 return -ENOMEM;
1951
1952 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
1953 r = dns_transaction_request_dnssec_rr(t, soa);
1954 if (r < 0)
1955 return r;
1956
1957 break;
1958 }
1959
1960 default: {
1961 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1962
1963 /* For other unsigned RRsets (including
1964 * NSEC/NSEC3!), look for proof the zone is
1965 * unsigned, by requesting the SOA RR of the
1966 * zone. However, do so only if they are
1967 * directly relevant to our original
1968 * question. */
1969
1970 r = dns_transaction_is_primary_response(t, rr);
1971 if (r < 0)
1972 return r;
1973 if (r == 0)
1974 continue;
1975
1976 r = dnssec_has_rrsig(t->answer, rr->key);
1977 if (r < 0)
1978 return r;
1979 if (r > 0)
1980 continue;
1981
1982 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, DNS_RESOURCE_KEY_NAME(rr->key));
1983 if (!soa)
1984 return -ENOMEM;
1985
1986 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).", t->id, DNS_RESOURCE_KEY_NAME(rr->key), dns_resource_record_to_string(rr));
1987 r = dns_transaction_request_dnssec_rr(t, soa);
1988 if (r < 0)
1989 return r;
1990 break;
1991 }}
1992 }
1993
1994 /* Above, we requested everything necessary to validate what
1995 * we got. Now, let's request what we need to validate what we
1996 * didn't get... */
1997
1998 r = dns_transaction_has_unsigned_negative_answer(t);
1999 if (r < 0)
2000 return r;
2001 if (r > 0) {
2002 const char *name;
2003
2004 name = DNS_RESOURCE_KEY_NAME(t->key);
2005
2006 /* If this was a SOA or NS request, then this
2007 * indicates that we are not at a zone apex, hence ask
2008 * the parent name instead. If this was a DS request,
2009 * then it's signed when the parent zone is signed,
2010 * hence ask the parent in that case, too. */
2011
2012 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
2013 r = dns_name_parent(&name);
2014 if (r < 0)
2015 return r;
2016 if (r > 0)
2017 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned empty SOA/NS/DS response).", t->id, DNS_RESOURCE_KEY_NAME(t->key));
2018 else
2019 name = NULL;
2020 } else
2021 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned empty non-SOA/NS/DS response).", t->id, DNS_RESOURCE_KEY_NAME(t->key));
2022
2023 if (name) {
2024 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2025
2026 soa = dns_resource_key_new(t->key->class, DNS_TYPE_SOA, name);
2027 if (!soa)
2028 return -ENOMEM;
2029
2030 r = dns_transaction_request_dnssec_rr(t, soa);
2031 if (r < 0)
2032 return r;
2033 }
2034 }
2035
2036 return dns_transaction_dnssec_is_live(t);
2037 }
2038
2039 void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source) {
2040 assert(t);
2041 assert(source);
2042
2043 /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
2044 we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
2045 the state is VALIDATING however, we should check if we are complete now. */
2046
2047 if (t->state == DNS_TRANSACTION_VALIDATING)
2048 dns_transaction_process_dnssec(t);
2049 }
2050
2051 static int dns_transaction_validate_dnskey_by_ds(DnsTransaction *t) {
2052 DnsResourceRecord *rr;
2053 int ifindex, r;
2054
2055 assert(t);
2056
2057 /* Add all DNSKEY RRs from the answer that are validated by DS
2058 * RRs from the list of validated keys to the list of
2059 * validated keys. */
2060
2061 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, t->answer) {
2062
2063 r = dnssec_verify_dnskey_by_ds_search(rr, t->validated_keys);
2064 if (r < 0)
2065 return r;
2066 if (r == 0)
2067 continue;
2068
2069 /* If so, the DNSKEY is validated too. */
2070 r = dns_answer_add_extend(&t->validated_keys, rr, ifindex, DNS_ANSWER_AUTHENTICATED);
2071 if (r < 0)
2072 return r;
2073 }
2074
2075 return 0;
2076 }
2077
2078 static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *rr) {
2079 int r;
2080
2081 assert(t);
2082 assert(rr);
2083
2084 /* Checks if the RR we are looking for must be signed with an
2085 * RRSIG. This is used for positive responses. */
2086
2087 if (t->scope->dnssec_mode == DNSSEC_NO)
2088 return false;
2089
2090 if (dns_type_is_pseudo(rr->key->type))
2091 return -EINVAL;
2092
2093 r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key));
2094 if (r < 0)
2095 return r;
2096 if (r > 0)
2097 return false;
2098
2099 switch (rr->key->type) {
2100
2101 case DNS_TYPE_RRSIG:
2102 /* RRSIGs are the signatures themselves, they need no signing. */
2103 return false;
2104
2105 case DNS_TYPE_SOA:
2106 case DNS_TYPE_NS: {
2107 DnsTransaction *dt;
2108 Iterator i;
2109
2110 /* For SOA or NS RRs we look for a matching DS transaction */
2111
2112 SET_FOREACH(dt, t->dnssec_transactions, i) {
2113
2114 if (dt->key->class != rr->key->class)
2115 continue;
2116 if (dt->key->type != DNS_TYPE_DS)
2117 continue;
2118
2119 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), DNS_RESOURCE_KEY_NAME(rr->key));
2120 if (r < 0)
2121 return r;
2122 if (r == 0)
2123 continue;
2124
2125 /* We found a DS transactions for the SOA/NS
2126 * RRs we are looking at. If it discovered signed DS
2127 * RRs, then we need to be signed, too. */
2128
2129 if (!dt->answer_authenticated)
2130 return false;
2131
2132 return dns_answer_match_key(dt->answer, dt->key, NULL);
2133 }
2134
2135 /* We found nothing that proves this is safe to leave
2136 * this unauthenticated, hence ask inist on
2137 * authentication. */
2138 return true;
2139 }
2140
2141 case DNS_TYPE_DS:
2142 case DNS_TYPE_CNAME:
2143 case DNS_TYPE_DNAME: {
2144 const char *parent = NULL;
2145 DnsTransaction *dt;
2146 Iterator i;
2147
2148 /*
2149 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
2150 *
2151 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
2152 */
2153
2154 SET_FOREACH(dt, t->dnssec_transactions, i) {
2155
2156 if (dt->key->class != rr->key->class)
2157 continue;
2158 if (dt->key->type != DNS_TYPE_SOA)
2159 continue;
2160
2161 if (!parent) {
2162 parent = DNS_RESOURCE_KEY_NAME(rr->key);
2163 r = dns_name_parent(&parent);
2164 if (r < 0)
2165 return r;
2166 if (r == 0) {
2167 if (rr->key->type == DNS_TYPE_DS)
2168 return true;
2169
2170 /* A CNAME/DNAME without a parent? That's sooo weird. */
2171 log_debug("Transaction %" PRIu16 " claims CNAME/DNAME at root. Refusing.", t->id);
2172 return -EBADMSG;
2173 }
2174 }
2175
2176 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), parent);
2177 if (r < 0)
2178 return r;
2179 if (r == 0)
2180 continue;
2181
2182 return t->answer_authenticated;
2183 }
2184
2185 return true;
2186 }
2187
2188 default: {
2189 DnsTransaction *dt;
2190 Iterator i;
2191
2192 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
2193
2194 SET_FOREACH(dt, t->dnssec_transactions, i) {
2195
2196 if (dt->key->class != rr->key->class)
2197 continue;
2198 if (dt->key->type != DNS_TYPE_SOA)
2199 continue;
2200
2201 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), DNS_RESOURCE_KEY_NAME(rr->key));
2202 if (r < 0)
2203 return r;
2204 if (r == 0)
2205 continue;
2206
2207 /* We found the transaction that was supposed to find
2208 * the SOA RR for us. It was successful, but found no
2209 * RR for us. This means we are not at a zone cut. In
2210 * this case, we require authentication if the SOA
2211 * lookup was authenticated too. */
2212 return t->answer_authenticated;
2213 }
2214
2215 return true;
2216 }}
2217 }
2218
2219 static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKey *key) {
2220 DnsTransaction *dt;
2221 const char *tld;
2222 Iterator i;
2223 int r;
2224
2225 /* If DNSSEC downgrade mode is on, checks whether the
2226 * specified RR is one level below a TLD we have proven not to
2227 * exist. In such a case we assume that this is a private
2228 * domain, and permit it.
2229 *
2230 * This detects cases like the Fritz!Box router networks. Each
2231 * Fritz!Box router serves a private "fritz.box" zone, in the
2232 * non-existing TLD "box". Requests for the "fritz.box" domain
2233 * are served by the router itself, while requests for the
2234 * "box" domain will result in NXDOMAIN.
2235 *
2236 * Note that this logic is unable to detect cases where a
2237 * router serves a private DNS zone directly under
2238 * non-existing TLD. In such a case we cannot detect whether
2239 * the TLD is supposed to exist or not, as all requests we
2240 * make for it will be answered by the router's zone, and not
2241 * by the root zone. */
2242
2243 assert(t);
2244
2245 if (t->scope->dnssec_mode != DNSSEC_ALLOW_DOWNGRADE)
2246 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
2247
2248 tld = DNS_RESOURCE_KEY_NAME(key);
2249 r = dns_name_parent(&tld);
2250 if (r < 0)
2251 return r;
2252 if (r == 0)
2253 return false; /* Already the root domain */
2254
2255 if (!dns_name_is_single_label(tld))
2256 return false;
2257
2258 SET_FOREACH(dt, t->dnssec_transactions, i) {
2259
2260 if (dt->key->class != key->class)
2261 continue;
2262
2263 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), tld);
2264 if (r < 0)
2265 return r;
2266 if (r == 0)
2267 continue;
2268
2269 /* We found an auxiliary lookup we did for the TLD. If
2270 * that returned with NXDOMAIN, we know the TLD didn't
2271 * exist, and hence this might be a private zone. */
2272
2273 return dt->answer_rcode == DNS_RCODE_NXDOMAIN;
2274 }
2275
2276 return false;
2277 }
2278
2279 static int dns_transaction_requires_nsec(DnsTransaction *t) {
2280 DnsTransaction *dt;
2281 const char *name;
2282 Iterator i;
2283 int r;
2284
2285 assert(t);
2286
2287 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
2288 * this negative reply */
2289
2290 if (t->scope->dnssec_mode == DNSSEC_NO)
2291 return false;
2292
2293 if (dns_type_is_pseudo(t->key->type))
2294 return -EINVAL;
2295
2296 r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(t->key));
2297 if (r < 0)
2298 return r;
2299 if (r > 0)
2300 return false;
2301
2302 r = dns_transaction_in_private_tld(t, t->key);
2303 if (r < 0)
2304 return r;
2305 if (r > 0) {
2306 /* The lookup is from a TLD that is proven not to
2307 * exist, and we are in downgrade mode, hence ignore
2308 * that fact that we didn't get any NSEC RRs.*/
2309
2310 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.", dns_transaction_key_string(t));
2311 return false;
2312 }
2313
2314 name = DNS_RESOURCE_KEY_NAME(t->key);
2315
2316 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
2317
2318 /* We got a negative reply for this SOA/NS lookup? If
2319 * so, then we are not at a zone apex, and thus should
2320 * look at the result of the parent SOA lookup.
2321 *
2322 * We got a negative reply for this DS lookup? DS RRs
2323 * are signed when their parent zone is signed, hence
2324 * also check the parent SOA in this case. */
2325
2326 r = dns_name_parent(&name);
2327 if (r < 0)
2328 return r;
2329 if (r == 0)
2330 return true;
2331 }
2332
2333 /* For all other RRs we check the SOA on the same level to see
2334 * if it's signed. */
2335
2336 SET_FOREACH(dt, t->dnssec_transactions, i) {
2337
2338 if (dt->key->class != t->key->class)
2339 continue;
2340 if (dt->key->type != DNS_TYPE_SOA)
2341 continue;
2342
2343 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), name);
2344 if (r < 0)
2345 return r;
2346 if (r == 0)
2347 continue;
2348
2349 return dt->answer_authenticated;
2350 }
2351
2352 /* If in doubt, require NSEC/NSEC3 */
2353 return true;
2354 }
2355
2356 static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRecord *rr) {
2357 DnsResourceRecord *rrsig;
2358 bool found = false;
2359 int r;
2360
2361 /* Checks whether any of the DNSKEYs used for the RRSIGs for
2362 * the specified RRset is authenticated (i.e. has a matching
2363 * DS RR). */
2364
2365 r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key));
2366 if (r < 0)
2367 return r;
2368 if (r > 0)
2369 return false;
2370
2371 DNS_ANSWER_FOREACH(rrsig, t->answer) {
2372 DnsTransaction *dt;
2373 Iterator i;
2374
2375 r = dnssec_key_match_rrsig(rr->key, rrsig);
2376 if (r < 0)
2377 return r;
2378 if (r == 0)
2379 continue;
2380
2381 SET_FOREACH(dt, t->dnssec_transactions, i) {
2382
2383 if (dt->key->class != rr->key->class)
2384 continue;
2385
2386 if (dt->key->type == DNS_TYPE_DNSKEY) {
2387
2388 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), rrsig->rrsig.signer);
2389 if (r < 0)
2390 return r;
2391 if (r == 0)
2392 continue;
2393
2394 /* OK, we found an auxiliary DNSKEY
2395 * lookup. If that lookup is
2396 * authenticated, report this. */
2397
2398 if (dt->answer_authenticated)
2399 return true;
2400
2401 found = true;
2402
2403 } else if (dt->key->type == DNS_TYPE_DS) {
2404
2405 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), rrsig->rrsig.signer);
2406 if (r < 0)
2407 return r;
2408 if (r == 0)
2409 continue;
2410
2411 /* OK, we found an auxiliary DS
2412 * lookup. If that lookup is
2413 * authenticated and non-zero, we
2414 * won! */
2415
2416 if (!dt->answer_authenticated)
2417 return false;
2418
2419 return dns_answer_match_key(dt->answer, dt->key, NULL);
2420 }
2421 }
2422 }
2423
2424 return found ? false : -ENXIO;
2425 }
2426
2427 static int dns_transaction_known_signed(DnsTransaction *t, DnsResourceRecord *rr) {
2428 assert(t);
2429 assert(rr);
2430
2431 /* We know that the root domain is signed, hence if it appears
2432 * not to be signed, there's a problem with the DNS server */
2433
2434 return rr->key->class == DNS_CLASS_IN &&
2435 dns_name_is_root(DNS_RESOURCE_KEY_NAME(rr->key));
2436 }
2437
2438 static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
2439 DnsResourceRecord *rr;
2440 int r;
2441
2442 assert(t);
2443
2444 /* Maybe warn the user that we encountered a revoked DNSKEY
2445 * for a key from our trust anchor. Note that we don't care
2446 * whether the DNSKEY can be authenticated or not. It's
2447 * sufficient if it is self-signed. */
2448
2449 DNS_ANSWER_FOREACH(rr, t->answer) {
2450 r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, rr, t->answer);
2451 if (r < 0)
2452 return r;
2453 }
2454
2455 return 0;
2456 }
2457
2458 static int dns_transaction_invalidate_revoked_keys(DnsTransaction *t) {
2459 bool changed;
2460 int r;
2461
2462 assert(t);
2463
2464 /* Removes all DNSKEY/DS objects from t->validated_keys that
2465 * our trust anchors database considers revoked. */
2466
2467 do {
2468 DnsResourceRecord *rr;
2469
2470 changed = false;
2471
2472 DNS_ANSWER_FOREACH(rr, t->validated_keys) {
2473 r = dns_trust_anchor_is_revoked(&t->scope->manager->trust_anchor, rr);
2474 if (r < 0)
2475 return r;
2476 if (r > 0) {
2477 r = dns_answer_remove_by_rr(&t->validated_keys, rr);
2478 if (r < 0)
2479 return r;
2480
2481 assert(r > 0);
2482 changed = true;
2483 break;
2484 }
2485 }
2486 } while (changed);
2487
2488 return 0;
2489 }
2490
2491 static int dns_transaction_copy_validated(DnsTransaction *t) {
2492 DnsTransaction *dt;
2493 Iterator i;
2494 int r;
2495
2496 assert(t);
2497
2498 /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
2499
2500 SET_FOREACH(dt, t->dnssec_transactions, i) {
2501
2502 if (DNS_TRANSACTION_IS_LIVE(dt->state))
2503 continue;
2504
2505 if (!dt->answer_authenticated)
2506 continue;
2507
2508 r = dns_answer_extend(&t->validated_keys, dt->answer);
2509 if (r < 0)
2510 return r;
2511 }
2512
2513 return 0;
2514 }
2515
2516 int dns_transaction_validate_dnssec(DnsTransaction *t) {
2517 _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
2518 enum {
2519 PHASE_DNSKEY, /* Phase #1, only validate DNSKEYs */
2520 PHASE_NSEC, /* Phase #2, only validate NSEC+NSEC3 */
2521 PHASE_ALL, /* Phase #3, validate everything else */
2522 } phase;
2523 DnsResourceRecord *rr;
2524 DnsAnswerFlags flags;
2525 int r;
2526
2527 assert(t);
2528
2529 /* We have now collected all DS and DNSKEY RRs in
2530 * t->validated_keys, let's see which RRs we can now
2531 * authenticate with that. */
2532
2533 if (t->scope->dnssec_mode == DNSSEC_NO)
2534 return 0;
2535
2536 /* Already validated */
2537 if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
2538 return 0;
2539
2540 /* Our own stuff needs no validation */
2541 if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
2542 t->answer_dnssec_result = DNSSEC_VALIDATED;
2543 t->answer_authenticated = true;
2544 return 0;
2545 }
2546
2547 /* Cached stuff is not affected by validation. */
2548 if (t->answer_source != DNS_TRANSACTION_NETWORK)
2549 return 0;
2550
2551 if (!dns_transaction_dnssec_supported_full(t)) {
2552 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
2553 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2554 log_debug("Not validating response, server lacks DNSSEC support.");
2555 return 0;
2556 }
2557
2558 log_debug("Validating response from transaction %" PRIu16 " (%s).", t->id, dns_transaction_key_string(t));
2559
2560 /* First, see if this response contains any revoked trust
2561 * anchors we care about */
2562 r = dns_transaction_check_revoked_trust_anchors(t);
2563 if (r < 0)
2564 return r;
2565
2566 /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
2567 r = dns_transaction_copy_validated(t);
2568 if (r < 0)
2569 return r;
2570
2571 /* Second, see if there are DNSKEYs we already know a
2572 * validated DS for. */
2573 r = dns_transaction_validate_dnskey_by_ds(t);
2574 if (r < 0)
2575 return r;
2576
2577 /* Fourth, remove all DNSKEY and DS RRs again that our trust
2578 * anchor says are revoked. After all we might have marked
2579 * some keys revoked above, but they might still be lingering
2580 * in our validated_keys list. */
2581 r = dns_transaction_invalidate_revoked_keys(t);
2582 if (r < 0)
2583 return r;
2584
2585 phase = PHASE_DNSKEY;
2586 for (;;) {
2587 bool changed = false, have_nsec = false;
2588
2589 DNS_ANSWER_FOREACH(rr, t->answer) {
2590 DnsResourceRecord *rrsig = NULL;
2591 DnssecResult result;
2592
2593 switch (rr->key->type) {
2594
2595 case DNS_TYPE_RRSIG:
2596 continue;
2597
2598 case DNS_TYPE_DNSKEY:
2599 /* We validate DNSKEYs only in the DNSKEY and ALL phases */
2600 if (phase == PHASE_NSEC)
2601 continue;
2602 break;
2603
2604 case DNS_TYPE_NSEC:
2605 case DNS_TYPE_NSEC3:
2606 have_nsec = true;
2607
2608 /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
2609 if (phase == PHASE_DNSKEY)
2610 continue;
2611
2612 break;
2613
2614 default:
2615 /* We validate all other RRs only in the ALL phases */
2616 if (phase != PHASE_ALL)
2617 continue;
2618
2619 break;
2620 }
2621
2622 r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result, &rrsig);
2623 if (r < 0)
2624 return r;
2625
2626 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
2627
2628 if (result == DNSSEC_VALIDATED) {
2629
2630 if (rr->key->type == DNS_TYPE_DNSKEY) {
2631 /* If we just validated a
2632 * DNSKEY RRset, then let's
2633 * add these keys to the set
2634 * of validated keys for this
2635 * transaction. */
2636
2637 r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
2638 if (r < 0)
2639 return r;
2640
2641 /* some of the DNSKEYs we just
2642 * added might already have
2643 * been revoked, remove them
2644 * again in that case. */
2645 r = dns_transaction_invalidate_revoked_keys(t);
2646 if (r < 0)
2647 return r;
2648 }
2649
2650 /* Add the validated RRset to the new
2651 * list of validated RRsets, and
2652 * remove it from the unvalidated
2653 * RRsets. We mark the RRset as
2654 * authenticated and cacheable. */
2655 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE);
2656 if (r < 0)
2657 return r;
2658
2659 t->scope->manager->n_dnssec_secure++;
2660
2661 /* Exit the loop, we dropped something from the answer, start from the beginning */
2662 changed = true;
2663 break;
2664 }
2665
2666 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
2667 * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet, we
2668 * cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
2669 if (phase != PHASE_ALL)
2670 continue;
2671
2672 if (result == DNSSEC_VALIDATED_WILDCARD) {
2673 bool authenticated = false;
2674 const char *source;
2675
2676 /* This RRset validated, but as a wildcard. This means we need to prove via NSEC/NSEC3
2677 * that no matching non-wildcard RR exists.*/
2678
2679 /* First step, determine the source of synthesis */
2680 r = dns_resource_record_source(rrsig, &source);
2681 if (r < 0)
2682 return r;
2683
2684 r = dnssec_test_positive_wildcard(
2685 validated,
2686 DNS_RESOURCE_KEY_NAME(rr->key),
2687 source,
2688 rrsig->rrsig.signer,
2689 &authenticated);
2690
2691 /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
2692 if (r == 0)
2693 result = DNSSEC_INVALID;
2694 else {
2695 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, authenticated ? (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE) : 0);
2696 if (r < 0)
2697 return r;
2698
2699 if (authenticated)
2700 t->scope->manager->n_dnssec_secure++;
2701 else
2702 t->scope->manager->n_dnssec_insecure++;
2703
2704 /* Exit the loop, we dropped something from the answer, start from the beginning */
2705 changed = true;
2706 break;
2707 }
2708 }
2709
2710 if (result == DNSSEC_NO_SIGNATURE) {
2711 r = dns_transaction_requires_rrsig(t, rr);
2712 if (r < 0)
2713 return r;
2714 if (r == 0) {
2715 /* Data does not require signing. In that case, just copy it over,
2716 * but remember that this is by no means authenticated.*/
2717 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2718 if (r < 0)
2719 return r;
2720
2721 t->scope->manager->n_dnssec_insecure++;
2722 changed = true;
2723 break;
2724 }
2725
2726 r = dns_transaction_known_signed(t, rr);
2727 if (r < 0)
2728 return r;
2729 if (r > 0) {
2730 /* This is an RR we know has to be signed. If it isn't this means
2731 * the server is not attaching RRSIGs, hence complain. */
2732
2733 dns_server_packet_rrsig_missing(t->server, t->current_feature_level);
2734
2735 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
2736
2737 /* Downgrading is OK? If so, just consider the information unsigned */
2738
2739 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2740 if (r < 0)
2741 return r;
2742
2743 t->scope->manager->n_dnssec_insecure++;
2744 changed = true;
2745 break;
2746 }
2747
2748 /* Otherwise, fail */
2749 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2750 return 0;
2751 }
2752
2753 r = dns_transaction_in_private_tld(t, rr->key);
2754 if (r < 0)
2755 return r;
2756 if (r > 0) {
2757 _cleanup_free_ char *s = NULL;
2758
2759 /* The data is from a TLD that is proven not to exist, and we are in downgrade
2760 * mode, hence ignore the fact that this was not signed. */
2761
2762 (void) dns_resource_key_to_string(rr->key, &s);
2763 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.", strna(s ? strstrip(s) : NULL));
2764
2765 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2766 if (r < 0)
2767 return r;
2768
2769 t->scope->manager->n_dnssec_insecure++;
2770 changed = true;
2771 break;
2772 }
2773 }
2774
2775 if (IN_SET(result,
2776 DNSSEC_MISSING_KEY,
2777 DNSSEC_SIGNATURE_EXPIRED,
2778 DNSSEC_UNSUPPORTED_ALGORITHM)) {
2779
2780 r = dns_transaction_dnskey_authenticated(t, rr);
2781 if (r < 0 && r != -ENXIO)
2782 return r;
2783 if (r == 0) {
2784 /* The DNSKEY transaction was not authenticated, this means there's
2785 * no DS for this, which means it's OK if no keys are found for this signature. */
2786
2787 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2788 if (r < 0)
2789 return r;
2790
2791 t->scope->manager->n_dnssec_insecure++;
2792 changed = true;
2793 break;
2794 }
2795 }
2796
2797 if (IN_SET(result,
2798 DNSSEC_INVALID,
2799 DNSSEC_SIGNATURE_EXPIRED,
2800 DNSSEC_NO_SIGNATURE))
2801 t->scope->manager->n_dnssec_bogus++;
2802 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
2803 t->scope->manager->n_dnssec_indeterminate++;
2804
2805 r = dns_transaction_is_primary_response(t, rr);
2806 if (r < 0)
2807 return r;
2808 if (r > 0) {
2809
2810 /* Look for a matching DNAME for this CNAME */
2811 r = dns_answer_has_dname_for_cname(t->answer, rr);
2812 if (r < 0)
2813 return r;
2814 if (r == 0) {
2815 /* Also look among the stuff we already validated */
2816 r = dns_answer_has_dname_for_cname(validated, rr);
2817 if (r < 0)
2818 return r;
2819 }
2820
2821 if (r == 0) {
2822 /* This is a primary response to our question, and it failed validation. That's
2823 * fatal. */
2824 t->answer_dnssec_result = result;
2825 return 0;
2826 }
2827
2828 /* This is a primary response, but we do have a DNAME RR in the RR that can replay this
2829 * CNAME, hence rely on that, and we can remove the CNAME in favour of it. */
2830 }
2831
2832 /* This is just some auxiliary data. Just remove the RRset and continue. */
2833 r = dns_answer_remove_by_key(&t->answer, rr->key);
2834 if (r < 0)
2835 return r;
2836
2837 /* Exit the loop, we dropped something from the answer, start from the beginning */
2838 changed = true;
2839 break;
2840 }
2841
2842 /* Restart the inner loop as long as we managed to achieve something */
2843 if (changed)
2844 continue;
2845
2846 if (phase == PHASE_DNSKEY && have_nsec) {
2847 /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
2848 phase = PHASE_NSEC;
2849 continue;
2850 }
2851
2852 if (phase != PHASE_ALL) {
2853 /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now. Note that in this
2854 * third phase we start to remove RRs we couldn't validate. */
2855 phase = PHASE_ALL;
2856 continue;
2857 }
2858
2859 /* We're done */
2860 break;
2861 }
2862
2863 dns_answer_unref(t->answer);
2864 t->answer = validated;
2865 validated = NULL;
2866
2867 /* At this point the answer only contains validated
2868 * RRsets. Now, let's see if it actually answers the question
2869 * we asked. If so, great! If it doesn't, then see if
2870 * NSEC/NSEC3 can prove this. */
2871 r = dns_transaction_has_positive_answer(t, &flags);
2872 if (r > 0) {
2873 /* Yes, it answers the question! */
2874
2875 if (flags & DNS_ANSWER_AUTHENTICATED) {
2876 /* The answer is fully authenticated, yay. */
2877 t->answer_dnssec_result = DNSSEC_VALIDATED;
2878 t->answer_rcode = DNS_RCODE_SUCCESS;
2879 t->answer_authenticated = true;
2880 } else {
2881 /* The answer is not fully authenticated. */
2882 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2883 t->answer_authenticated = false;
2884 }
2885
2886 } else if (r == 0) {
2887 DnssecNsecResult nr;
2888 bool authenticated = false;
2889
2890 /* Bummer! Let's check NSEC/NSEC3 */
2891 r = dnssec_nsec_test(t->answer, t->key, &nr, &authenticated, &t->answer_nsec_ttl);
2892 if (r < 0)
2893 return r;
2894
2895 switch (nr) {
2896
2897 case DNSSEC_NSEC_NXDOMAIN:
2898 /* NSEC proves the domain doesn't exist. Very good. */
2899 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
2900 t->answer_dnssec_result = DNSSEC_VALIDATED;
2901 t->answer_rcode = DNS_RCODE_NXDOMAIN;
2902 t->answer_authenticated = authenticated;
2903
2904 if (authenticated)
2905 t->scope->manager->n_dnssec_secure++;
2906 else
2907 t->scope->manager->n_dnssec_insecure++;
2908
2909 break;
2910
2911 case DNSSEC_NSEC_NODATA:
2912 /* NSEC proves that there's no data here, very good. */
2913 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
2914 t->answer_dnssec_result = DNSSEC_VALIDATED;
2915 t->answer_rcode = DNS_RCODE_SUCCESS;
2916 t->answer_authenticated = authenticated;
2917
2918 if (authenticated)
2919 t->scope->manager->n_dnssec_secure++;
2920 else
2921 t->scope->manager->n_dnssec_insecure++;
2922
2923 break;
2924
2925 case DNSSEC_NSEC_OPTOUT:
2926 /* NSEC3 says the data might not be signed */
2927 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
2928 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2929 t->answer_authenticated = false;
2930
2931 t->scope->manager->n_dnssec_insecure++;
2932 break;
2933
2934 case DNSSEC_NSEC_NO_RR:
2935 /* No NSEC data? Bummer! */
2936
2937 r = dns_transaction_requires_nsec(t);
2938 if (r < 0)
2939 return r;
2940 if (r > 0) {
2941 t->answer_dnssec_result = DNSSEC_NO_SIGNATURE;
2942 t->scope->manager->n_dnssec_indeterminate++;
2943 } else {
2944 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2945 t->answer_authenticated = false;
2946 t->scope->manager->n_dnssec_insecure++;
2947 }
2948
2949 break;
2950
2951 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM:
2952 /* We don't know the NSEC3 algorithm used? */
2953 t->answer_dnssec_result = DNSSEC_UNSUPPORTED_ALGORITHM;
2954 t->scope->manager->n_dnssec_indeterminate++;
2955 break;
2956
2957 case DNSSEC_NSEC_FOUND:
2958 case DNSSEC_NSEC_CNAME:
2959 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
2960 t->answer_dnssec_result = DNSSEC_NSEC_MISMATCH;
2961 t->scope->manager->n_dnssec_bogus++;
2962 break;
2963
2964 default:
2965 assert_not_reached("Unexpected NSEC result.");
2966 }
2967 }
2968
2969 return 1;
2970 }
2971
2972 const char *dns_transaction_key_string(DnsTransaction *t) {
2973 assert(t);
2974
2975 if (!t->key_string) {
2976 if (dns_resource_key_to_string(t->key, &t->key_string) < 0)
2977 return "n/a";
2978 }
2979
2980 return strstrip(t->key_string);
2981 }
2982
2983 static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
2984 [DNS_TRANSACTION_NULL] = "null",
2985 [DNS_TRANSACTION_PENDING] = "pending",
2986 [DNS_TRANSACTION_VALIDATING] = "validating",
2987 [DNS_TRANSACTION_RCODE_FAILURE] = "rcode-failure",
2988 [DNS_TRANSACTION_SUCCESS] = "success",
2989 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
2990 [DNS_TRANSACTION_TIMEOUT] = "timeout",
2991 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
2992 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
2993 [DNS_TRANSACTION_RESOURCES] = "resources",
2994 [DNS_TRANSACTION_ABORTED] = "aborted",
2995 [DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
2996 [DNS_TRANSACTION_NO_TRUST_ANCHOR] = "no-trust-anchor",
2997 [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED] = "rr-type-unsupported",
2998 [DNS_TRANSACTION_NETWORK_DOWN] = "network-down",
2999 };
3000 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
3001
3002 static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
3003 [DNS_TRANSACTION_NETWORK] = "network",
3004 [DNS_TRANSACTION_CACHE] = "cache",
3005 [DNS_TRANSACTION_ZONE] = "zone",
3006 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
3007 };
3008 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);