]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-transaction.c
resolved: handle oom properly
[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/DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
1808 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
1809 */
1810
1811 if (t->scope->dnssec_mode == DNSSEC_NO)
1812 return 0;
1813 if (t->answer_source != DNS_TRANSACTION_NETWORK)
1814 return 0; /* We only need to validate stuff from the network */
1815 if (!dns_transaction_dnssec_supported(t))
1816 return 0; /* If we can't do DNSSEC anyway there's no point in geting the auxiliary RRs */
1817
1818 DNS_ANSWER_FOREACH(rr, t->answer) {
1819
1820 if (dns_type_is_pseudo(rr->key->type))
1821 continue;
1822
1823 /* If this RR is in the negative trust anchor, we don't need to validate it. */
1824 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
1825 if (r < 0)
1826 return r;
1827 if (r > 0)
1828 continue;
1829
1830 switch (rr->key->type) {
1831
1832 case DNS_TYPE_RRSIG: {
1833 /* For each RRSIG we request the matching DNSKEY */
1834 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
1835
1836 /* If this RRSIG is about a DNSKEY RR and the
1837 * signer is the same as the owner, then we
1838 * already have the DNSKEY, and we don't have
1839 * to look for more. */
1840 if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
1841 r = dns_name_equal(rr->rrsig.signer, dns_resource_key_name(rr->key));
1842 if (r < 0)
1843 return r;
1844 if (r > 0)
1845 continue;
1846 }
1847
1848 /* If the signer is not a parent of our
1849 * original query, then this is about an
1850 * auxiliary RRset, but not anything we asked
1851 * for. In this case we aren't interested,
1852 * because we don't want to request additional
1853 * RRs for stuff we didn't really ask for, and
1854 * also to avoid request loops, where
1855 * additional RRs from one transaction result
1856 * in another transaction whose additonal RRs
1857 * point back to the original transaction, and
1858 * we deadlock. */
1859 r = dns_name_endswith(dns_resource_key_name(t->key), rr->rrsig.signer);
1860 if (r < 0)
1861 return r;
1862 if (r == 0)
1863 continue;
1864
1865 dnskey = dns_resource_key_new(rr->key->class, DNS_TYPE_DNSKEY, rr->rrsig.signer);
1866 if (!dnskey)
1867 return -ENOMEM;
1868
1869 log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").",
1870 t->id, dns_resource_key_name(rr->key), rr->rrsig.key_tag);
1871 r = dns_transaction_request_dnssec_rr(t, dnskey);
1872 if (r < 0)
1873 return r;
1874 break;
1875 }
1876
1877 case DNS_TYPE_DNSKEY: {
1878 /* For each DNSKEY we request the matching DS */
1879 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1880
1881 /* If the DNSKEY we are looking at is not for
1882 * zone we are interested in, nor any of its
1883 * parents, we aren't interested, and don't
1884 * request it. After all, we don't want to end
1885 * up in request loops, and want to keep
1886 * additional traffic down. */
1887
1888 r = dns_name_endswith(dns_resource_key_name(t->key), dns_resource_key_name(rr->key));
1889 if (r < 0)
1890 return r;
1891 if (r == 0)
1892 continue;
1893
1894 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
1895 if (!ds)
1896 return -ENOMEM;
1897
1898 log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").",
1899 t->id, dns_resource_key_name(rr->key), dnssec_keytag(rr, false));
1900 r = dns_transaction_request_dnssec_rr(t, ds);
1901 if (r < 0)
1902 return r;
1903
1904 break;
1905 }
1906
1907 case DNS_TYPE_SOA:
1908 case DNS_TYPE_NS: {
1909 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1910
1911 /* For an unsigned SOA or NS, try to acquire
1912 * the matching DS RR, as we are at a zone cut
1913 * then, and whether a DS exists tells us
1914 * whether the zone is signed. Do so only if
1915 * this RR matches our original question,
1916 * however. */
1917
1918 r = dns_resource_key_match_rr(t->key, rr, NULL);
1919 if (r < 0)
1920 return r;
1921 if (r == 0)
1922 continue;
1923
1924 r = dnssec_has_rrsig(t->answer, rr->key);
1925 if (r < 0)
1926 return r;
1927 if (r > 0)
1928 continue;
1929
1930 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
1931 if (!ds)
1932 return -ENOMEM;
1933
1934 log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).",
1935 t->id, dns_resource_key_name(rr->key));
1936 r = dns_transaction_request_dnssec_rr(t, ds);
1937 if (r < 0)
1938 return r;
1939
1940 break;
1941 }
1942
1943 case DNS_TYPE_DS:
1944 case DNS_TYPE_CNAME:
1945 case DNS_TYPE_DNAME: {
1946 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1947 const char *name;
1948
1949 /* CNAMEs and DNAMEs cannot be located at a
1950 * zone apex, hence ask for the parent SOA for
1951 * unsigned CNAME/DNAME RRs, maybe that's the
1952 * apex. But do all that only if this is
1953 * actually a response to our original
1954 * question.
1955 *
1956 * Similar for DS RRs, which are signed when
1957 * the parent SOA is signed. */
1958
1959 r = dns_transaction_is_primary_response(t, rr);
1960 if (r < 0)
1961 return r;
1962 if (r == 0)
1963 continue;
1964
1965 r = dnssec_has_rrsig(t->answer, rr->key);
1966 if (r < 0)
1967 return r;
1968 if (r > 0)
1969 continue;
1970
1971 r = dns_answer_has_dname_for_cname(t->answer, rr);
1972 if (r < 0)
1973 return r;
1974 if (r > 0)
1975 continue;
1976
1977 name = dns_resource_key_name(rr->key);
1978 r = dns_name_parent(&name);
1979 if (r < 0)
1980 return r;
1981 if (r == 0)
1982 continue;
1983
1984 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
1985 if (!soa)
1986 return -ENOMEM;
1987
1988 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).",
1989 t->id, dns_resource_key_name(rr->key));
1990 r = dns_transaction_request_dnssec_rr(t, soa);
1991 if (r < 0)
1992 return r;
1993
1994 break;
1995 }
1996
1997 default: {
1998 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1999
2000 /* For other unsigned RRsets (including
2001 * NSEC/NSEC3!), look for proof the zone is
2002 * unsigned, by requesting the SOA RR of the
2003 * zone. However, do so only if they are
2004 * directly relevant to our original
2005 * question. */
2006
2007 r = dns_transaction_is_primary_response(t, rr);
2008 if (r < 0)
2009 return r;
2010 if (r == 0)
2011 continue;
2012
2013 r = dnssec_has_rrsig(t->answer, rr->key);
2014 if (r < 0)
2015 return r;
2016 if (r > 0)
2017 continue;
2018
2019 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, dns_resource_key_name(rr->key));
2020 if (!soa)
2021 return -ENOMEM;
2022
2023 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).",
2024 t->id, dns_resource_key_name(rr->key), dns_resource_record_to_string(rr));
2025 r = dns_transaction_request_dnssec_rr(t, soa);
2026 if (r < 0)
2027 return r;
2028 break;
2029 }}
2030 }
2031
2032 /* Above, we requested everything necessary to validate what
2033 * we got. Now, let's request what we need to validate what we
2034 * didn't get... */
2035
2036 r = dns_transaction_has_unsigned_negative_answer(t);
2037 if (r < 0)
2038 return r;
2039 if (r > 0) {
2040 const char *name;
2041
2042 name = dns_resource_key_name(t->key);
2043
2044 /* If this was a SOA or NS request, then this
2045 * indicates that we are not at a zone apex, hence ask
2046 * the parent name instead. If this was a DS request,
2047 * then it's signed when the parent zone is signed,
2048 * hence ask the parent in that case, too. */
2049
2050 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
2051 r = dns_name_parent(&name);
2052 if (r < 0)
2053 return r;
2054 if (r > 0)
2055 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned empty SOA/NS/DS response).",
2056 t->id, dns_resource_key_name(t->key));
2057 else
2058 name = NULL;
2059 } else
2060 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned empty non-SOA/NS/DS response).",
2061 t->id, dns_resource_key_name(t->key));
2062
2063 if (name) {
2064 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2065
2066 soa = dns_resource_key_new(t->key->class, DNS_TYPE_SOA, name);
2067 if (!soa)
2068 return -ENOMEM;
2069
2070 r = dns_transaction_request_dnssec_rr(t, soa);
2071 if (r < 0)
2072 return r;
2073 }
2074 }
2075
2076 return dns_transaction_dnssec_is_live(t);
2077 }
2078
2079 void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source) {
2080 assert(t);
2081 assert(source);
2082
2083 /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
2084 we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
2085 the state is VALIDATING however, we should check if we are complete now. */
2086
2087 if (t->state == DNS_TRANSACTION_VALIDATING)
2088 dns_transaction_process_dnssec(t);
2089 }
2090
2091 static int dns_transaction_validate_dnskey_by_ds(DnsTransaction *t) {
2092 DnsResourceRecord *rr;
2093 int ifindex, r;
2094
2095 assert(t);
2096
2097 /* Add all DNSKEY RRs from the answer that are validated by DS
2098 * RRs from the list of validated keys to the list of
2099 * validated keys. */
2100
2101 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, t->answer) {
2102
2103 r = dnssec_verify_dnskey_by_ds_search(rr, t->validated_keys);
2104 if (r < 0)
2105 return r;
2106 if (r == 0)
2107 continue;
2108
2109 /* If so, the DNSKEY is validated too. */
2110 r = dns_answer_add_extend(&t->validated_keys, rr, ifindex, DNS_ANSWER_AUTHENTICATED);
2111 if (r < 0)
2112 return r;
2113 }
2114
2115 return 0;
2116 }
2117
2118 static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *rr) {
2119 int r;
2120
2121 assert(t);
2122 assert(rr);
2123
2124 /* Checks if the RR we are looking for must be signed with an
2125 * RRSIG. This is used for positive responses. */
2126
2127 if (t->scope->dnssec_mode == DNSSEC_NO)
2128 return false;
2129
2130 if (dns_type_is_pseudo(rr->key->type))
2131 return -EINVAL;
2132
2133 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
2134 if (r < 0)
2135 return r;
2136 if (r > 0)
2137 return false;
2138
2139 switch (rr->key->type) {
2140
2141 case DNS_TYPE_RRSIG:
2142 /* RRSIGs are the signatures themselves, they need no signing. */
2143 return false;
2144
2145 case DNS_TYPE_SOA:
2146 case DNS_TYPE_NS: {
2147 DnsTransaction *dt;
2148 Iterator i;
2149
2150 /* For SOA or NS RRs we look for a matching DS transaction */
2151
2152 SET_FOREACH(dt, t->dnssec_transactions, i) {
2153
2154 if (dt->key->class != rr->key->class)
2155 continue;
2156 if (dt->key->type != DNS_TYPE_DS)
2157 continue;
2158
2159 r = dns_name_equal(dns_resource_key_name(dt->key), dns_resource_key_name(rr->key));
2160 if (r < 0)
2161 return r;
2162 if (r == 0)
2163 continue;
2164
2165 /* We found a DS transactions for the SOA/NS
2166 * RRs we are looking at. If it discovered signed DS
2167 * RRs, then we need to be signed, too. */
2168
2169 if (!dt->answer_authenticated)
2170 return false;
2171
2172 return dns_answer_match_key(dt->answer, dt->key, NULL);
2173 }
2174
2175 /* We found nothing that proves this is safe to leave
2176 * this unauthenticated, hence ask inist on
2177 * authentication. */
2178 return true;
2179 }
2180
2181 case DNS_TYPE_DS:
2182 case DNS_TYPE_CNAME:
2183 case DNS_TYPE_DNAME: {
2184 const char *parent = NULL;
2185 DnsTransaction *dt;
2186 Iterator i;
2187
2188 /*
2189 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
2190 *
2191 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
2192 */
2193
2194 SET_FOREACH(dt, t->dnssec_transactions, i) {
2195
2196 if (dt->key->class != rr->key->class)
2197 continue;
2198 if (dt->key->type != DNS_TYPE_SOA)
2199 continue;
2200
2201 if (!parent) {
2202 parent = dns_resource_key_name(rr->key);
2203 r = dns_name_parent(&parent);
2204 if (r < 0)
2205 return r;
2206 if (r == 0) {
2207 if (rr->key->type == DNS_TYPE_DS)
2208 return true;
2209
2210 /* A CNAME/DNAME without a parent? That's sooo weird. */
2211 log_debug("Transaction %" PRIu16 " claims CNAME/DNAME at root. Refusing.", t->id);
2212 return -EBADMSG;
2213 }
2214 }
2215
2216 r = dns_name_equal(dns_resource_key_name(dt->key), parent);
2217 if (r < 0)
2218 return r;
2219 if (r == 0)
2220 continue;
2221
2222 return t->answer_authenticated;
2223 }
2224
2225 return true;
2226 }
2227
2228 default: {
2229 DnsTransaction *dt;
2230 Iterator i;
2231
2232 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
2233
2234 SET_FOREACH(dt, t->dnssec_transactions, i) {
2235
2236 if (dt->key->class != rr->key->class)
2237 continue;
2238 if (dt->key->type != DNS_TYPE_SOA)
2239 continue;
2240
2241 r = dns_name_equal(dns_resource_key_name(dt->key), dns_resource_key_name(rr->key));
2242 if (r < 0)
2243 return r;
2244 if (r == 0)
2245 continue;
2246
2247 /* We found the transaction that was supposed to find
2248 * the SOA RR for us. It was successful, but found no
2249 * RR for us. This means we are not at a zone cut. In
2250 * this case, we require authentication if the SOA
2251 * lookup was authenticated too. */
2252 return t->answer_authenticated;
2253 }
2254
2255 return true;
2256 }}
2257 }
2258
2259 static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKey *key) {
2260 DnsTransaction *dt;
2261 const char *tld;
2262 Iterator i;
2263 int r;
2264
2265 /* If DNSSEC downgrade mode is on, checks whether the
2266 * specified RR is one level below a TLD we have proven not to
2267 * exist. In such a case we assume that this is a private
2268 * domain, and permit it.
2269 *
2270 * This detects cases like the Fritz!Box router networks. Each
2271 * Fritz!Box router serves a private "fritz.box" zone, in the
2272 * non-existing TLD "box". Requests for the "fritz.box" domain
2273 * are served by the router itself, while requests for the
2274 * "box" domain will result in NXDOMAIN.
2275 *
2276 * Note that this logic is unable to detect cases where a
2277 * router serves a private DNS zone directly under
2278 * non-existing TLD. In such a case we cannot detect whether
2279 * the TLD is supposed to exist or not, as all requests we
2280 * make for it will be answered by the router's zone, and not
2281 * by the root zone. */
2282
2283 assert(t);
2284
2285 if (t->scope->dnssec_mode != DNSSEC_ALLOW_DOWNGRADE)
2286 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
2287
2288 tld = dns_resource_key_name(key);
2289 r = dns_name_parent(&tld);
2290 if (r < 0)
2291 return r;
2292 if (r == 0)
2293 return false; /* Already the root domain */
2294
2295 if (!dns_name_is_single_label(tld))
2296 return false;
2297
2298 SET_FOREACH(dt, t->dnssec_transactions, i) {
2299
2300 if (dt->key->class != key->class)
2301 continue;
2302
2303 r = dns_name_equal(dns_resource_key_name(dt->key), tld);
2304 if (r < 0)
2305 return r;
2306 if (r == 0)
2307 continue;
2308
2309 /* We found an auxiliary lookup we did for the TLD. If
2310 * that returned with NXDOMAIN, we know the TLD didn't
2311 * exist, and hence this might be a private zone. */
2312
2313 return dt->answer_rcode == DNS_RCODE_NXDOMAIN;
2314 }
2315
2316 return false;
2317 }
2318
2319 static int dns_transaction_requires_nsec(DnsTransaction *t) {
2320 DnsTransaction *dt;
2321 const char *name;
2322 Iterator i;
2323 int r;
2324 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
2325
2326 assert(t);
2327
2328 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
2329 * this negative reply */
2330
2331 if (t->scope->dnssec_mode == DNSSEC_NO)
2332 return false;
2333
2334 if (dns_type_is_pseudo(t->key->type))
2335 return -EINVAL;
2336
2337 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(t->key));
2338 if (r < 0)
2339 return r;
2340 if (r > 0)
2341 return false;
2342
2343 r = dns_transaction_in_private_tld(t, t->key);
2344 if (r < 0)
2345 return r;
2346 if (r > 0) {
2347 /* The lookup is from a TLD that is proven not to
2348 * exist, and we are in downgrade mode, hence ignore
2349 * that fact that we didn't get any NSEC RRs.*/
2350
2351 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
2352 dns_resource_key_to_string(t->key, key_str, sizeof key_str));
2353 return false;
2354 }
2355
2356 name = dns_resource_key_name(t->key);
2357
2358 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
2359
2360 /* We got a negative reply for this SOA/NS lookup? If
2361 * so, then we are not at a zone apex, and thus should
2362 * look at the result of the parent SOA lookup.
2363 *
2364 * We got a negative reply for this DS lookup? DS RRs
2365 * are signed when their parent zone is signed, hence
2366 * also check the parent SOA in this case. */
2367
2368 r = dns_name_parent(&name);
2369 if (r < 0)
2370 return r;
2371 if (r == 0)
2372 return true;
2373 }
2374
2375 /* For all other RRs we check the SOA on the same level to see
2376 * if it's signed. */
2377
2378 SET_FOREACH(dt, t->dnssec_transactions, i) {
2379
2380 if (dt->key->class != t->key->class)
2381 continue;
2382 if (dt->key->type != DNS_TYPE_SOA)
2383 continue;
2384
2385 r = dns_name_equal(dns_resource_key_name(dt->key), name);
2386 if (r < 0)
2387 return r;
2388 if (r == 0)
2389 continue;
2390
2391 return dt->answer_authenticated;
2392 }
2393
2394 /* If in doubt, require NSEC/NSEC3 */
2395 return true;
2396 }
2397
2398 static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRecord *rr) {
2399 DnsResourceRecord *rrsig;
2400 bool found = false;
2401 int r;
2402
2403 /* Checks whether any of the DNSKEYs used for the RRSIGs for
2404 * the specified RRset is authenticated (i.e. has a matching
2405 * DS RR). */
2406
2407 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
2408 if (r < 0)
2409 return r;
2410 if (r > 0)
2411 return false;
2412
2413 DNS_ANSWER_FOREACH(rrsig, t->answer) {
2414 DnsTransaction *dt;
2415 Iterator i;
2416
2417 r = dnssec_key_match_rrsig(rr->key, rrsig);
2418 if (r < 0)
2419 return r;
2420 if (r == 0)
2421 continue;
2422
2423 SET_FOREACH(dt, t->dnssec_transactions, i) {
2424
2425 if (dt->key->class != rr->key->class)
2426 continue;
2427
2428 if (dt->key->type == DNS_TYPE_DNSKEY) {
2429
2430 r = dns_name_equal(dns_resource_key_name(dt->key), rrsig->rrsig.signer);
2431 if (r < 0)
2432 return r;
2433 if (r == 0)
2434 continue;
2435
2436 /* OK, we found an auxiliary DNSKEY
2437 * lookup. If that lookup is
2438 * authenticated, report this. */
2439
2440 if (dt->answer_authenticated)
2441 return true;
2442
2443 found = true;
2444
2445 } else if (dt->key->type == DNS_TYPE_DS) {
2446
2447 r = dns_name_equal(dns_resource_key_name(dt->key), rrsig->rrsig.signer);
2448 if (r < 0)
2449 return r;
2450 if (r == 0)
2451 continue;
2452
2453 /* OK, we found an auxiliary DS
2454 * lookup. If that lookup is
2455 * authenticated and non-zero, we
2456 * won! */
2457
2458 if (!dt->answer_authenticated)
2459 return false;
2460
2461 return dns_answer_match_key(dt->answer, dt->key, NULL);
2462 }
2463 }
2464 }
2465
2466 return found ? false : -ENXIO;
2467 }
2468
2469 static int dns_transaction_known_signed(DnsTransaction *t, DnsResourceRecord *rr) {
2470 assert(t);
2471 assert(rr);
2472
2473 /* We know that the root domain is signed, hence if it appears
2474 * not to be signed, there's a problem with the DNS server */
2475
2476 return rr->key->class == DNS_CLASS_IN &&
2477 dns_name_is_root(dns_resource_key_name(rr->key));
2478 }
2479
2480 static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
2481 DnsResourceRecord *rr;
2482 int r;
2483
2484 assert(t);
2485
2486 /* Maybe warn the user that we encountered a revoked DNSKEY
2487 * for a key from our trust anchor. Note that we don't care
2488 * whether the DNSKEY can be authenticated or not. It's
2489 * sufficient if it is self-signed. */
2490
2491 DNS_ANSWER_FOREACH(rr, t->answer) {
2492 r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, rr, t->answer);
2493 if (r < 0)
2494 return r;
2495 }
2496
2497 return 0;
2498 }
2499
2500 static int dns_transaction_invalidate_revoked_keys(DnsTransaction *t) {
2501 bool changed;
2502 int r;
2503
2504 assert(t);
2505
2506 /* Removes all DNSKEY/DS objects from t->validated_keys that
2507 * our trust anchors database considers revoked. */
2508
2509 do {
2510 DnsResourceRecord *rr;
2511
2512 changed = false;
2513
2514 DNS_ANSWER_FOREACH(rr, t->validated_keys) {
2515 r = dns_trust_anchor_is_revoked(&t->scope->manager->trust_anchor, rr);
2516 if (r < 0)
2517 return r;
2518 if (r > 0) {
2519 r = dns_answer_remove_by_rr(&t->validated_keys, rr);
2520 if (r < 0)
2521 return r;
2522
2523 assert(r > 0);
2524 changed = true;
2525 break;
2526 }
2527 }
2528 } while (changed);
2529
2530 return 0;
2531 }
2532
2533 static int dns_transaction_copy_validated(DnsTransaction *t) {
2534 DnsTransaction *dt;
2535 Iterator i;
2536 int r;
2537
2538 assert(t);
2539
2540 /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
2541
2542 SET_FOREACH(dt, t->dnssec_transactions, i) {
2543
2544 if (DNS_TRANSACTION_IS_LIVE(dt->state))
2545 continue;
2546
2547 if (!dt->answer_authenticated)
2548 continue;
2549
2550 r = dns_answer_extend(&t->validated_keys, dt->answer);
2551 if (r < 0)
2552 return r;
2553 }
2554
2555 return 0;
2556 }
2557
2558 typedef enum {
2559 DNSSEC_PHASE_DNSKEY, /* Phase #1, only validate DNSKEYs */
2560 DNSSEC_PHASE_NSEC, /* Phase #2, only validate NSEC+NSEC3 */
2561 DNSSEC_PHASE_ALL, /* Phase #3, validate everything else */
2562 } Phase;
2563
2564 static int dnssec_validate_records(
2565 DnsTransaction *t,
2566 Phase phase,
2567 bool *have_nsec,
2568 DnsAnswer **validated) {
2569
2570 DnsResourceRecord *rr;
2571 int r;
2572
2573 /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
2574
2575 DNS_ANSWER_FOREACH(rr, t->answer) {
2576 DnsResourceRecord *rrsig = NULL;
2577 DnssecResult result;
2578
2579 switch (rr->key->type) {
2580 case DNS_TYPE_RRSIG:
2581 continue;
2582
2583 case DNS_TYPE_DNSKEY:
2584 /* We validate DNSKEYs only in the DNSKEY and ALL phases */
2585 if (phase == DNSSEC_PHASE_NSEC)
2586 continue;
2587 break;
2588
2589 case DNS_TYPE_NSEC:
2590 case DNS_TYPE_NSEC3:
2591 *have_nsec = true;
2592
2593 /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
2594 if (phase == DNSSEC_PHASE_DNSKEY)
2595 continue;
2596 break;
2597
2598 default:
2599 /* We validate all other RRs only in the ALL phases */
2600 if (phase != DNSSEC_PHASE_ALL)
2601 continue;
2602 }
2603
2604 r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result, &rrsig);
2605 if (r < 0)
2606 return r;
2607
2608 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
2609
2610 if (result == DNSSEC_VALIDATED) {
2611
2612 if (rr->key->type == DNS_TYPE_DNSKEY) {
2613 /* If we just validated a DNSKEY RRset, then let's add these keys to
2614 * the set of validated keys for this transaction. */
2615
2616 r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
2617 if (r < 0)
2618 return r;
2619
2620 /* Some of the DNSKEYs we just added might already have been revoked,
2621 * remove them again in that case. */
2622 r = dns_transaction_invalidate_revoked_keys(t);
2623 if (r < 0)
2624 return r;
2625 }
2626
2627 /* Add the validated RRset to the new list of validated
2628 * RRsets, and remove it from the unvalidated RRsets.
2629 * We mark the RRset as authenticated and cacheable. */
2630 r = dns_answer_move_by_key(validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE);
2631 if (r < 0)
2632 return r;
2633
2634 manager_dnssec_verdict(t->scope->manager, DNSSEC_SECURE, rr->key);
2635
2636 /* Exit the loop, we dropped something from the answer, start from the beginning */
2637 return 1;
2638 }
2639
2640 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
2641 * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet,
2642 * we cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
2643 if (phase != DNSSEC_PHASE_ALL)
2644 continue;
2645
2646 if (result == DNSSEC_VALIDATED_WILDCARD) {
2647 bool authenticated = false;
2648 const char *source;
2649
2650 /* This RRset validated, but as a wildcard. This means we need
2651 * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists.*/
2652
2653 /* First step, determine the source of synthesis */
2654 r = dns_resource_record_source(rrsig, &source);
2655 if (r < 0)
2656 return r;
2657
2658 r = dnssec_test_positive_wildcard(*validated,
2659 dns_resource_key_name(rr->key),
2660 source,
2661 rrsig->rrsig.signer,
2662 &authenticated);
2663
2664 /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
2665 if (r == 0)
2666 result = DNSSEC_INVALID;
2667 else {
2668 r = dns_answer_move_by_key(validated, &t->answer, rr->key,
2669 authenticated ? (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE) : 0);
2670 if (r < 0)
2671 return r;
2672
2673 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, rr->key);
2674
2675 /* Exit the loop, we dropped something from the answer, start from the beginning */
2676 return 1;
2677 }
2678 }
2679
2680 if (result == DNSSEC_NO_SIGNATURE) {
2681 r = dns_transaction_requires_rrsig(t, rr);
2682 if (r < 0)
2683 return r;
2684 if (r == 0) {
2685 /* Data does not require signing. In that case, just copy it over,
2686 * but remember that this is by no means authenticated.*/
2687 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
2688 if (r < 0)
2689 return r;
2690
2691 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
2692 return 1;
2693 }
2694
2695 r = dns_transaction_known_signed(t, rr);
2696 if (r < 0)
2697 return r;
2698 if (r > 0) {
2699 /* This is an RR we know has to be signed. If it isn't this means
2700 * the server is not attaching RRSIGs, hence complain. */
2701
2702 dns_server_packet_rrsig_missing(t->server, t->current_feature_level);
2703
2704 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
2705
2706 /* Downgrading is OK? If so, just consider the information unsigned */
2707
2708 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
2709 if (r < 0)
2710 return r;
2711
2712 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
2713 return 1;
2714 }
2715
2716 /* Otherwise, fail */
2717 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2718 return 0;
2719 }
2720
2721 r = dns_transaction_in_private_tld(t, rr->key);
2722 if (r < 0)
2723 return r;
2724 if (r > 0) {
2725 char s[DNS_RESOURCE_KEY_STRING_MAX];
2726
2727 /* The data is from a TLD that is proven not to exist, and we are in downgrade
2728 * mode, hence ignore the fact that this was not signed. */
2729
2730 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.",
2731 dns_resource_key_to_string(rr->key, s, sizeof s));
2732
2733 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
2734 if (r < 0)
2735 return r;
2736
2737 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
2738 return 1;
2739 }
2740 }
2741
2742 if (IN_SET(result,
2743 DNSSEC_MISSING_KEY,
2744 DNSSEC_SIGNATURE_EXPIRED,
2745 DNSSEC_UNSUPPORTED_ALGORITHM)) {
2746
2747 r = dns_transaction_dnskey_authenticated(t, rr);
2748 if (r < 0 && r != -ENXIO)
2749 return r;
2750 if (r == 0) {
2751 /* The DNSKEY transaction was not authenticated, this means there's
2752 * no DS for this, which means it's OK if no keys are found for this signature. */
2753
2754 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
2755 if (r < 0)
2756 return r;
2757
2758 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
2759 return 1;
2760 }
2761 }
2762
2763 r = dns_transaction_is_primary_response(t, rr);
2764 if (r < 0)
2765 return r;
2766 if (r > 0) {
2767 /* Look for a matching DNAME for this CNAME */
2768 r = dns_answer_has_dname_for_cname(t->answer, rr);
2769 if (r < 0)
2770 return r;
2771 if (r == 0) {
2772 /* Also look among the stuff we already validated */
2773 r = dns_answer_has_dname_for_cname(*validated, rr);
2774 if (r < 0)
2775 return r;
2776 }
2777
2778 if (r == 0) {
2779 if (IN_SET(result,
2780 DNSSEC_INVALID,
2781 DNSSEC_SIGNATURE_EXPIRED,
2782 DNSSEC_NO_SIGNATURE))
2783 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key);
2784 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
2785 manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key);
2786
2787 /* This is a primary response to our question, and it failed validation.
2788 * That's fatal. */
2789 t->answer_dnssec_result = result;
2790 return 0;
2791 }
2792
2793 /* This is a primary response, but we do have a DNAME RR
2794 * in the RR that can replay this CNAME, hence rely on
2795 * that, and we can remove the CNAME in favour of it. */
2796 }
2797
2798 /* This is just some auxiliary data. Just remove the RRset and continue. */
2799 r = dns_answer_remove_by_key(&t->answer, rr->key);
2800 if (r < 0)
2801 return r;
2802
2803 /* We dropped something from the answer, start from the beginning. */
2804 return 1;
2805 }
2806
2807 return 2; /* Finito. */
2808 }
2809
2810 int dns_transaction_validate_dnssec(DnsTransaction *t) {
2811 _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
2812 Phase phase;
2813 DnsAnswerFlags flags;
2814 int r;
2815 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
2816
2817 assert(t);
2818
2819 /* We have now collected all DS and DNSKEY RRs in
2820 * t->validated_keys, let's see which RRs we can now
2821 * authenticate with that. */
2822
2823 if (t->scope->dnssec_mode == DNSSEC_NO)
2824 return 0;
2825
2826 /* Already validated */
2827 if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
2828 return 0;
2829
2830 /* Our own stuff needs no validation */
2831 if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
2832 t->answer_dnssec_result = DNSSEC_VALIDATED;
2833 t->answer_authenticated = true;
2834 return 0;
2835 }
2836
2837 /* Cached stuff is not affected by validation. */
2838 if (t->answer_source != DNS_TRANSACTION_NETWORK)
2839 return 0;
2840
2841 if (!dns_transaction_dnssec_supported_full(t)) {
2842 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
2843 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2844 log_debug("Not validating response for %" PRIu16 ", server lacks DNSSEC support.", t->id);
2845 return 0;
2846 }
2847
2848 log_debug("Validating response from transaction %" PRIu16 " (%s).",
2849 t->id,
2850 dns_resource_key_to_string(t->key, key_str, sizeof key_str));
2851
2852 /* First, see if this response contains any revoked trust
2853 * anchors we care about */
2854 r = dns_transaction_check_revoked_trust_anchors(t);
2855 if (r < 0)
2856 return r;
2857
2858 /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
2859 r = dns_transaction_copy_validated(t);
2860 if (r < 0)
2861 return r;
2862
2863 /* Second, see if there are DNSKEYs we already know a
2864 * validated DS for. */
2865 r = dns_transaction_validate_dnskey_by_ds(t);
2866 if (r < 0)
2867 return r;
2868
2869 /* Fourth, remove all DNSKEY and DS RRs again that our trust
2870 * anchor says are revoked. After all we might have marked
2871 * some keys revoked above, but they might still be lingering
2872 * in our validated_keys list. */
2873 r = dns_transaction_invalidate_revoked_keys(t);
2874 if (r < 0)
2875 return r;
2876
2877 phase = DNSSEC_PHASE_DNSKEY;
2878 for (;;) {
2879 bool have_nsec = false;
2880
2881 r = dnssec_validate_records(t, phase, &have_nsec, &validated);
2882 if (r <= 0)
2883 return r;
2884
2885 /* Try again as long as we managed to achieve something */
2886 if (r == 1)
2887 continue;
2888
2889 if (phase == DNSSEC_PHASE_DNSKEY && have_nsec) {
2890 /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
2891 phase = DNSSEC_PHASE_NSEC;
2892 continue;
2893 }
2894
2895 if (phase != DNSSEC_PHASE_ALL) {
2896 /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now.
2897 * Note that in this third phase we start to remove RRs we couldn't validate. */
2898 phase = DNSSEC_PHASE_ALL;
2899 continue;
2900 }
2901
2902 /* We're done */
2903 break;
2904 }
2905
2906 dns_answer_unref(t->answer);
2907 t->answer = validated;
2908 validated = NULL;
2909
2910 /* At this point the answer only contains validated
2911 * RRsets. Now, let's see if it actually answers the question
2912 * we asked. If so, great! If it doesn't, then see if
2913 * NSEC/NSEC3 can prove this. */
2914 r = dns_transaction_has_positive_answer(t, &flags);
2915 if (r > 0) {
2916 /* Yes, it answers the question! */
2917
2918 if (flags & DNS_ANSWER_AUTHENTICATED) {
2919 /* The answer is fully authenticated, yay. */
2920 t->answer_dnssec_result = DNSSEC_VALIDATED;
2921 t->answer_rcode = DNS_RCODE_SUCCESS;
2922 t->answer_authenticated = true;
2923 } else {
2924 /* The answer is not fully authenticated. */
2925 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2926 t->answer_authenticated = false;
2927 }
2928
2929 } else if (r == 0) {
2930 DnssecNsecResult nr;
2931 bool authenticated = false;
2932
2933 /* Bummer! Let's check NSEC/NSEC3 */
2934 r = dnssec_nsec_test(t->answer, t->key, &nr, &authenticated, &t->answer_nsec_ttl);
2935 if (r < 0)
2936 return r;
2937
2938 switch (nr) {
2939
2940 case DNSSEC_NSEC_NXDOMAIN:
2941 /* NSEC proves the domain doesn't exist. Very good. */
2942 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
2943 t->answer_dnssec_result = DNSSEC_VALIDATED;
2944 t->answer_rcode = DNS_RCODE_NXDOMAIN;
2945 t->answer_authenticated = authenticated;
2946
2947 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, t->key);
2948 break;
2949
2950 case DNSSEC_NSEC_NODATA:
2951 /* NSEC proves that there's no data here, very good. */
2952 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
2953 t->answer_dnssec_result = DNSSEC_VALIDATED;
2954 t->answer_rcode = DNS_RCODE_SUCCESS;
2955 t->answer_authenticated = authenticated;
2956
2957 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, t->key);
2958 break;
2959
2960 case DNSSEC_NSEC_OPTOUT:
2961 /* NSEC3 says the data might not be signed */
2962 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
2963 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2964 t->answer_authenticated = false;
2965
2966 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, t->key);
2967 break;
2968
2969 case DNSSEC_NSEC_NO_RR:
2970 /* No NSEC data? Bummer! */
2971
2972 r = dns_transaction_requires_nsec(t);
2973 if (r < 0)
2974 return r;
2975 if (r > 0) {
2976 t->answer_dnssec_result = DNSSEC_NO_SIGNATURE;
2977 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, t->key);
2978 } else {
2979 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2980 t->answer_authenticated = false;
2981 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, t->key);
2982 }
2983
2984 break;
2985
2986 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM:
2987 /* We don't know the NSEC3 algorithm used? */
2988 t->answer_dnssec_result = DNSSEC_UNSUPPORTED_ALGORITHM;
2989 manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, t->key);
2990 break;
2991
2992 case DNSSEC_NSEC_FOUND:
2993 case DNSSEC_NSEC_CNAME:
2994 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
2995 t->answer_dnssec_result = DNSSEC_NSEC_MISMATCH;
2996 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, t->key);
2997 break;
2998
2999 default:
3000 assert_not_reached("Unexpected NSEC result.");
3001 }
3002 }
3003
3004 return 1;
3005 }
3006
3007 static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
3008 [DNS_TRANSACTION_NULL] = "null",
3009 [DNS_TRANSACTION_PENDING] = "pending",
3010 [DNS_TRANSACTION_VALIDATING] = "validating",
3011 [DNS_TRANSACTION_RCODE_FAILURE] = "rcode-failure",
3012 [DNS_TRANSACTION_SUCCESS] = "success",
3013 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
3014 [DNS_TRANSACTION_TIMEOUT] = "timeout",
3015 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
3016 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
3017 [DNS_TRANSACTION_ERRNO] = "errno",
3018 [DNS_TRANSACTION_ABORTED] = "aborted",
3019 [DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
3020 [DNS_TRANSACTION_NO_TRUST_ANCHOR] = "no-trust-anchor",
3021 [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED] = "rr-type-unsupported",
3022 [DNS_TRANSACTION_NETWORK_DOWN] = "network-down",
3023 [DNS_TRANSACTION_NOT_FOUND] = "not-found",
3024 };
3025 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
3026
3027 static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
3028 [DNS_TRANSACTION_NETWORK] = "network",
3029 [DNS_TRANSACTION_CACHE] = "cache",
3030 [DNS_TRANSACTION_ZONE] = "zone",
3031 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
3032 };
3033 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);