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