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