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