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