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