1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include "alloc-util.h"
24 #include "dns-domain.h"
26 #include "random-util.h"
27 #include "resolved-dns-cache.h"
28 #include "resolved-dns-transaction.h"
29 #include "resolved-llmnr.h"
30 #include "string-table.h"
32 DnsTransaction
* dns_transaction_free(DnsTransaction
*t
) {
40 sd_event_source_unref(t
->timeout_event_source
);
42 dns_packet_unref(t
->sent
);
43 dns_packet_unref(t
->received
);
45 dns_answer_unref(t
->answer
);
47 sd_event_source_unref(t
->dns_udp_event_source
);
48 safe_close(t
->dns_udp_fd
);
50 dns_server_unref(t
->server
);
51 dns_stream_free(t
->stream
);
54 hashmap_remove_value(t
->scope
->transactions_by_key
, t
->key
, t
);
55 LIST_REMOVE(transactions_by_scope
, t
->scope
->transactions
, t
);
58 hashmap_remove(t
->scope
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
));
61 dns_resource_key_unref(t
->key
);
63 while ((c
= set_steal_first(t
->notify_query_candidates
)))
64 set_remove(c
->transactions
, t
);
65 set_free(t
->notify_query_candidates
);
67 while ((i
= set_steal_first(t
->notify_zone_items
)))
68 i
->probe_transaction
= NULL
;
69 set_free(t
->notify_zone_items
);
71 while ((z
= set_steal_first(t
->notify_transactions
)))
72 set_remove(z
->dnssec_transactions
, t
);
73 set_free(t
->notify_transactions
);
75 while ((z
= set_steal_first(t
->dnssec_transactions
))) {
76 set_remove(z
->notify_transactions
, t
);
77 dns_transaction_gc(z
);
79 set_free(t
->dnssec_transactions
);
81 dns_answer_unref(t
->validated_keys
);
88 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction
*, dns_transaction_free
);
90 void dns_transaction_gc(DnsTransaction
*t
) {
96 if (set_isempty(t
->notify_query_candidates
) &&
97 set_isempty(t
->notify_zone_items
) &&
98 set_isempty(t
->notify_transactions
))
99 dns_transaction_free(t
);
102 int dns_transaction_new(DnsTransaction
**ret
, DnsScope
*s
, DnsResourceKey
*key
) {
103 _cleanup_(dns_transaction_freep
) DnsTransaction
*t
= NULL
;
110 /* Don't allow looking up invalid or pseudo RRs */
111 if (!dns_type_is_valid_query(key
->type
))
114 /* We only support the IN class */
115 if (key
->class != DNS_CLASS_IN
&& key
->class != DNS_CLASS_ANY
)
118 r
= hashmap_ensure_allocated(&s
->manager
->dns_transactions
, NULL
);
122 r
= hashmap_ensure_allocated(&s
->transactions_by_key
, &dns_resource_key_hash_ops
);
126 t
= new0(DnsTransaction
, 1);
131 t
->answer_source
= _DNS_TRANSACTION_SOURCE_INVALID
;
132 t
->answer_dnssec_result
= _DNSSEC_RESULT_INVALID
;
133 t
->key
= dns_resource_key_ref(key
);
135 /* Find a fresh, unused transaction id */
137 random_bytes(&t
->id
, sizeof(t
->id
));
139 hashmap_get(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
)));
141 r
= hashmap_put(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
), t
);
147 r
= hashmap_replace(s
->transactions_by_key
, t
->key
, t
);
149 hashmap_remove(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
));
153 LIST_PREPEND(transactions_by_scope
, s
->transactions
, t
);
156 s
->manager
->n_transactions_total
++;
166 static void dns_transaction_stop(DnsTransaction
*t
) {
169 t
->timeout_event_source
= sd_event_source_unref(t
->timeout_event_source
);
170 t
->stream
= dns_stream_free(t
->stream
);
172 /* Note that we do not drop the UDP socket here, as we want to
173 * reuse it to repeat the interaction. */
176 static void dns_transaction_tentative(DnsTransaction
*t
, DnsPacket
*p
) {
177 _cleanup_free_
char *pretty
= NULL
;
183 if (manager_our_packet(t
->scope
->manager
, p
) != 0)
186 in_addr_to_string(p
->family
, &p
->sender
, &pretty
);
188 log_debug("Transaction %" PRIu16
" for <%s> on scope %s on %s/%s got tentative packet from %s.",
190 dns_transaction_key_string(t
),
191 dns_protocol_to_string(t
->scope
->protocol
),
192 t
->scope
->link
? t
->scope
->link
->name
: "*",
193 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
),
196 /* RFC 4795, Section 4.1 says that the peer with the
197 * lexicographically smaller IP address loses */
198 if (memcmp(&p
->sender
, &p
->destination
, FAMILY_ADDRESS_SIZE(p
->family
)) >= 0) {
199 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
203 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
206 while ((z
= set_first(t
->notify_zone_items
))) {
207 /* First, make sure the zone item drops the reference
209 dns_zone_item_probe_stop(z
);
211 /* Secondly, report this as conflict, so that we might
212 * look for a different hostname */
213 dns_zone_item_conflict(z
);
217 dns_transaction_gc(t
);
220 void dns_transaction_complete(DnsTransaction
*t
, DnsTransactionState state
) {
221 DnsQueryCandidate
*c
;
227 assert(!DNS_TRANSACTION_IS_LIVE(state
));
229 if (state
== DNS_TRANSACTION_DNSSEC_FAILED
)
230 log_struct(LOG_NOTICE
,
231 LOG_MESSAGE("DNSSEC validation failed for question %s: %s", dns_transaction_key_string(t
), dnssec_result_to_string(t
->answer_dnssec_result
)),
232 "DNS_TRANSACTION=%" PRIu16
, t
->id
,
233 "DNS_QUESTION=%s", dns_transaction_key_string(t
),
234 "DNSSEC_RESULT=%s", dnssec_result_to_string(t
->answer_dnssec_result
),
237 /* Note that this call might invalidate the query. Callers
238 * should hence not attempt to access the query or transaction
239 * after calling this function. */
241 log_debug("Transaction %" PRIu16
" for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).",
243 dns_transaction_key_string(t
),
244 dns_protocol_to_string(t
->scope
->protocol
),
245 t
->scope
->link
? t
->scope
->link
->name
: "*",
246 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
),
247 dns_transaction_state_to_string(state
),
248 t
->answer_source
< 0 ? "none" : dns_transaction_source_to_string(t
->answer_source
),
249 t
->answer_authenticated
? "authenticated" : "unsigned");
253 dns_transaction_stop(t
);
255 /* Notify all queries that are interested, but make sure the
256 * transaction isn't freed while we are still looking at it */
259 SET_FOREACH(c
, t
->notify_query_candidates
, i
)
260 dns_query_candidate_notify(c
);
261 SET_FOREACH(z
, t
->notify_zone_items
, i
)
262 dns_zone_item_notify(z
);
264 if (!set_isempty(t
->notify_transactions
)) {
268 /* We need to be careful when notifying other
269 * transactions, as that might destroy other
270 * transactions in our list. Hence, in order to be
271 * able to safely iterate through the list of
272 * transactions, take a GC lock on all of them
273 * first. Then, in a second loop, notify them, but
274 * first unlock that specific transaction. */
276 nt
= newa(DnsTransaction
*, set_size(t
->notify_transactions
));
277 SET_FOREACH(d
, t
->notify_transactions
, i
) {
282 assert(n
== set_size(t
->notify_transactions
));
284 for (j
= 0; j
< n
; j
++) {
285 if (set_contains(t
->notify_transactions
, nt
[j
]))
286 dns_transaction_notify(nt
[j
], t
);
289 dns_transaction_gc(nt
[j
]);
294 dns_transaction_gc(t
);
297 static int on_stream_complete(DnsStream
*s
, int error
) {
298 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
302 assert(s
->transaction
);
304 /* Copy the data we care about out of the stream before we
307 p
= dns_packet_ref(s
->read_packet
);
309 t
->stream
= dns_stream_free(t
->stream
);
311 if (IN_SET(error
, ENOTCONN
, ECONNRESET
, ECONNREFUSED
, ECONNABORTED
, EPIPE
)) {
312 dns_transaction_complete(t
, DNS_TRANSACTION_CONNECTION_FAILURE
);
317 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
321 if (dns_packet_validate_reply(p
) <= 0) {
322 log_debug("Invalid TCP reply packet.");
323 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
327 dns_scope_check_conflicts(t
->scope
, p
);
330 dns_transaction_process_reply(t
, p
);
333 /* If the response wasn't useful, then complete the transition now */
334 if (t
->state
== DNS_TRANSACTION_PENDING
)
335 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
340 static int dns_transaction_open_tcp(DnsTransaction
*t
) {
341 DnsServer
*server
= NULL
;
342 _cleanup_close_
int fd
= -1;
350 switch (t
->scope
->protocol
) {
351 case DNS_PROTOCOL_DNS
:
352 fd
= dns_scope_tcp_socket(t
->scope
, AF_UNSPEC
, NULL
, 53, &server
);
355 case DNS_PROTOCOL_LLMNR
:
356 /* When we already received a reply to this (but it was truncated), send to its sender address */
358 fd
= dns_scope_tcp_socket(t
->scope
, t
->received
->family
, &t
->received
->sender
, t
->received
->sender_port
, NULL
);
360 union in_addr_union address
;
361 int family
= AF_UNSPEC
;
363 /* Otherwise, try to talk to the owner of a
364 * the IP address, in case this is a reverse
367 r
= dns_name_address(DNS_RESOURCE_KEY_NAME(t
->key
), &family
, &address
);
372 if (family
!= t
->scope
->family
)
375 fd
= dns_scope_tcp_socket(t
->scope
, family
, &address
, LLMNR_PORT
, NULL
);
381 return -EAFNOSUPPORT
;
387 r
= dns_stream_new(t
->scope
->manager
, &t
->stream
, t
->scope
->protocol
, fd
);
393 r
= dns_stream_write_packet(t
->stream
, t
->sent
);
395 t
->stream
= dns_stream_free(t
->stream
);
399 dns_server_unref(t
->server
);
400 t
->server
= dns_server_ref(server
);
401 t
->received
= dns_packet_unref(t
->received
);
402 t
->answer
= dns_answer_unref(t
->answer
);
404 t
->stream
->complete
= on_stream_complete
;
405 t
->stream
->transaction
= t
;
407 /* The interface index is difficult to determine if we are
408 * connecting to the local host, hence fill this in right away
409 * instead of determining it from the socket */
411 t
->stream
->ifindex
= t
->scope
->link
->ifindex
;
416 static void dns_transaction_next_dns_server(DnsTransaction
*t
) {
419 t
->server
= dns_server_unref(t
->server
);
420 t
->dns_udp_event_source
= sd_event_source_unref(t
->dns_udp_event_source
);
421 t
->dns_udp_fd
= safe_close(t
->dns_udp_fd
);
423 dns_scope_next_dns_server(t
->scope
);
426 static void dns_transaction_cache_answer(DnsTransaction
*t
) {
429 /* For mDNS we cache whenever we get the packet, rather than
430 * in each transaction. */
431 if (!IN_SET(t
->scope
->protocol
, DNS_PROTOCOL_DNS
, DNS_PROTOCOL_LLMNR
))
434 /* We never cache if this packet is from the local host, under
435 * the assumption that a locally running DNS server would
436 * cache this anyway, and probably knows better when to flush
437 * the cache then we could. */
438 if (!DNS_PACKET_SHALL_CACHE(t
->received
))
441 dns_cache_put(&t
->scope
->cache
,
445 t
->answer_authenticated
,
448 &t
->received
->sender
);
451 static bool dns_transaction_dnssec_is_live(DnsTransaction
*t
) {
457 SET_FOREACH(dt
, t
->dnssec_transactions
, i
)
458 if (DNS_TRANSACTION_IS_LIVE(dt
->state
))
464 static void dns_transaction_process_dnssec(DnsTransaction
*t
) {
469 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
470 if (dns_transaction_dnssec_is_live(t
))
473 /* All our auxiliary DNSSEC transactions are complete now. Try
474 * to validate our RRset now. */
475 r
= dns_transaction_validate_dnssec(t
);
477 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
481 if (t
->answer_dnssec_result
== DNSSEC_INCOMPATIBLE_SERVER
&&
482 t
->scope
->dnssec_mode
== DNSSEC_YES
) {
483 /* We are not in automatic downgrade mode, and the
484 * server is bad, refuse operation. */
485 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
489 if (!IN_SET(t
->answer_dnssec_result
,
490 _DNSSEC_RESULT_INVALID
, /* No DNSSEC validation enabled */
491 DNSSEC_VALIDATED
, /* Answer is signed and validated successfully */
492 DNSSEC_UNSIGNED
, /* Answer is right-fully unsigned */
493 DNSSEC_INCOMPATIBLE_SERVER
)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
494 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
498 dns_transaction_cache_answer(t
);
500 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
)
501 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
503 dns_transaction_complete(t
, DNS_TRANSACTION_RCODE_FAILURE
);
506 void dns_transaction_process_reply(DnsTransaction
*t
, DnsPacket
*p
) {
512 assert(t
->state
== DNS_TRANSACTION_PENDING
);
514 assert(t
->scope
->manager
);
516 /* Note that this call might invalidate the query. Callers
517 * should hence not attempt to access the query or transaction
518 * after calling this function. */
520 log_debug("Processing incoming packet on transaction %" PRIu16
".", t
->id
);
522 switch (t
->scope
->protocol
) {
524 case DNS_PROTOCOL_LLMNR
:
525 assert(t
->scope
->link
);
527 /* For LLMNR we will not accept any packets from other
530 if (p
->ifindex
!= t
->scope
->link
->ifindex
)
533 if (p
->family
!= t
->scope
->family
)
536 /* Tentative packets are not full responses but still
537 * useful for identifying uniqueness conflicts during
539 if (DNS_PACKET_LLMNR_T(p
)) {
540 dns_transaction_tentative(t
, p
);
546 case DNS_PROTOCOL_MDNS
:
547 assert(t
->scope
->link
);
549 /* For mDNS we will not accept any packets from other interfaces */
550 if (p
->ifindex
!= t
->scope
->link
->ifindex
)
553 if (p
->family
!= t
->scope
->family
)
558 case DNS_PROTOCOL_DNS
:
562 assert_not_reached("Invalid DNS protocol.");
565 if (t
->received
!= p
) {
566 dns_packet_unref(t
->received
);
567 t
->received
= dns_packet_ref(p
);
570 t
->answer_source
= DNS_TRANSACTION_NETWORK
;
572 if (p
->ipproto
== IPPROTO_TCP
) {
573 if (DNS_PACKET_TC(p
)) {
574 /* Truncated via TCP? Somebody must be fucking with us */
575 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
579 if (DNS_PACKET_ID(p
) != t
->id
) {
580 /* Not the reply to our query? Somebody must be fucking with us */
581 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
586 assert_se(sd_event_now(t
->scope
->manager
->event
, clock_boottime_or_monotonic(), &ts
) >= 0);
588 switch (t
->scope
->protocol
) {
590 case DNS_PROTOCOL_DNS
:
593 if (IN_SET(DNS_PACKET_RCODE(p
), DNS_RCODE_FORMERR
, DNS_RCODE_SERVFAIL
, DNS_RCODE_NOTIMP
)) {
595 /* Request failed, immediately try again with reduced features */
596 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p
)));
598 dns_server_packet_failed(t
->server
, t
->current_features
);
600 r
= dns_transaction_go(t
);
602 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
608 dns_server_packet_received(t
->server
, t
->current_features
, ts
- t
->start_usec
, p
->size
);
612 case DNS_PROTOCOL_LLMNR
:
613 case DNS_PROTOCOL_MDNS
:
614 dns_scope_packet_received(t
->scope
, ts
- t
->start_usec
);
618 assert_not_reached("Invalid DNS protocol.");
621 if (DNS_PACKET_TC(p
)) {
623 /* Truncated packets for mDNS are not allowed. Give up immediately. */
624 if (t
->scope
->protocol
== DNS_PROTOCOL_MDNS
) {
625 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
629 /* Response was truncated, let's try again with good old TCP */
630 r
= dns_transaction_open_tcp(t
);
632 /* No servers found? Damn! */
633 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
637 /* On LLMNR, if we cannot connect to the host,
638 * we immediately give up */
639 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
) {
640 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
644 /* On DNS, couldn't send? Try immediately again, with a new server */
645 dns_transaction_next_dns_server(t
);
647 r
= dns_transaction_go(t
);
649 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
657 /* Parse message, if it isn't parsed yet. */
658 r
= dns_packet_extract(p
);
660 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
664 if (IN_SET(t
->scope
->protocol
, DNS_PROTOCOL_DNS
, DNS_PROTOCOL_LLMNR
)) {
666 /* Only consider responses with equivalent query section to the request */
667 r
= dns_packet_is_reply_for(p
, t
->key
);
669 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
673 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
677 /* Install the answer as answer to the transaction */
678 dns_answer_unref(t
->answer
);
679 t
->answer
= dns_answer_ref(p
->answer
);
680 t
->answer_rcode
= DNS_PACKET_RCODE(p
);
681 t
->answer_authenticated
= false;
683 r
= dns_transaction_request_dnssec_keys(t
);
685 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
689 /* There are DNSSEC transactions pending now. Update the state accordingly. */
690 t
->state
= DNS_TRANSACTION_VALIDATING
;
691 dns_transaction_stop(t
);
696 dns_transaction_process_dnssec(t
);
699 static int on_dns_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
700 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
701 DnsTransaction
*t
= userdata
;
707 r
= manager_recv(t
->scope
->manager
, fd
, DNS_PROTOCOL_DNS
, &p
);
711 if (dns_packet_validate_reply(p
) > 0 &&
712 DNS_PACKET_ID(p
) == t
->id
)
713 dns_transaction_process_reply(t
, p
);
715 log_debug("Invalid DNS packet, ignoring.");
720 static int dns_transaction_emit(DnsTransaction
*t
) {
725 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&& !t
->server
) {
726 DnsServer
*server
= NULL
;
727 _cleanup_close_
int fd
= -1;
729 fd
= dns_scope_udp_dns_socket(t
->scope
, &server
);
733 r
= sd_event_add_io(t
->scope
->manager
->event
, &t
->dns_udp_event_source
, fd
, EPOLLIN
, on_dns_packet
, t
);
739 t
->server
= dns_server_ref(server
);
742 r
= dns_scope_emit(t
->scope
, t
->dns_udp_fd
, t
->server
, t
->sent
);
747 t
->current_features
= t
->server
->possible_features
;
752 static int on_transaction_timeout(sd_event_source
*s
, usec_t usec
, void *userdata
) {
753 DnsTransaction
*t
= userdata
;
759 if (!t
->initial_jitter_scheduled
|| t
->initial_jitter_elapsed
) {
760 /* Timeout reached? Increase the timeout for the server used */
761 switch (t
->scope
->protocol
) {
762 case DNS_PROTOCOL_DNS
:
765 dns_server_packet_lost(t
->server
, t
->current_features
, usec
- t
->start_usec
);
768 case DNS_PROTOCOL_LLMNR
:
769 case DNS_PROTOCOL_MDNS
:
770 dns_scope_packet_lost(t
->scope
, usec
- t
->start_usec
);
774 assert_not_reached("Invalid DNS protocol.");
777 if (t
->initial_jitter_scheduled
)
778 t
->initial_jitter_elapsed
= true;
781 log_debug("Timeout reached on transaction %" PRIu16
".", t
->id
);
783 /* ...and try again with a new server */
784 dns_transaction_next_dns_server(t
);
786 r
= dns_transaction_go(t
);
788 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
793 static usec_t
transaction_get_resend_timeout(DnsTransaction
*t
) {
797 switch (t
->scope
->protocol
) {
798 case DNS_PROTOCOL_DNS
:
801 return t
->server
->resend_timeout
;
802 case DNS_PROTOCOL_MDNS
:
803 assert(t
->n_attempts
> 0);
804 return (1 << (t
->n_attempts
- 1)) * USEC_PER_SEC
;
805 case DNS_PROTOCOL_LLMNR
:
806 return t
->scope
->resend_timeout
;
808 assert_not_reached("Invalid DNS protocol.");
812 static int dns_transaction_prepare(DnsTransaction
*t
, usec_t ts
) {
818 had_stream
= !!t
->stream
;
820 dns_transaction_stop(t
);
822 if (t
->n_attempts
>= TRANSACTION_ATTEMPTS_MAX(t
->scope
->protocol
)) {
823 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
827 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& had_stream
) {
828 /* If we already tried via a stream, then we don't
829 * retry on LLMNR. See RFC 4795, Section 2.7. */
830 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
836 t
->received
= dns_packet_unref(t
->received
);
837 t
->answer
= dns_answer_unref(t
->answer
);
839 t
->answer_source
= _DNS_TRANSACTION_SOURCE_INVALID
;
841 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
842 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
) {
843 r
= dns_trust_anchor_lookup(&t
->scope
->manager
->trust_anchor
, t
->key
, &t
->answer
);
847 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
848 t
->answer_source
= DNS_TRANSACTION_TRUST_ANCHOR
;
849 t
->answer_authenticated
= true;
850 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
855 /* Check the zone, but only if this transaction is not used
856 * for probing or verifying a zone item. */
857 if (set_isempty(t
->notify_zone_items
)) {
859 r
= dns_zone_lookup(&t
->scope
->zone
, t
->key
, &t
->answer
, NULL
, NULL
);
863 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
864 t
->answer_source
= DNS_TRANSACTION_ZONE
;
865 t
->answer_authenticated
= true;
866 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
871 /* Check the cache, but only if this transaction is not used
872 * for probing or verifying a zone item. */
873 if (set_isempty(t
->notify_zone_items
)) {
875 /* Before trying the cache, let's make sure we figured out a
876 * server to use. Should this cause a change of server this
877 * might flush the cache. */
878 dns_scope_get_dns_server(t
->scope
);
880 /* Let's then prune all outdated entries */
881 dns_cache_prune(&t
->scope
->cache
);
883 r
= dns_cache_lookup(&t
->scope
->cache
, t
->key
, &t
->answer_rcode
, &t
->answer
, &t
->answer_authenticated
);
887 t
->answer_source
= DNS_TRANSACTION_CACHE
;
888 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
)
889 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
891 dns_transaction_complete(t
, DNS_TRANSACTION_RCODE_FAILURE
);
899 static int dns_transaction_make_packet_mdns(DnsTransaction
*t
) {
901 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
902 bool add_known_answers
= false;
903 DnsTransaction
*other
;
909 assert(t
->scope
->protocol
== DNS_PROTOCOL_MDNS
);
911 /* Discard any previously prepared packet, so we can start over and coalesce again */
912 t
->sent
= dns_packet_unref(t
->sent
);
914 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0, false);
918 r
= dns_packet_append_key(p
, t
->key
, NULL
);
924 if (dns_key_is_shared(t
->key
))
925 add_known_answers
= true;
928 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
929 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
930 * in our current scope, and see whether their timing contraints allow them to be sent.
933 assert_se(sd_event_now(t
->scope
->manager
->event
, clock_boottime_or_monotonic(), &ts
) >= 0);
935 LIST_FOREACH(transactions_by_scope
, other
, t
->scope
->transactions
) {
941 if (other
->state
!= DNS_TRANSACTION_PENDING
)
944 if (other
->next_attempt_after
> ts
)
947 if (qdcount
>= UINT16_MAX
)
950 r
= dns_packet_append_key(p
, other
->key
, NULL
);
953 * If we can't stuff more questions into the packet, just give up.
954 * One of the 'other' transactions will fire later and take care of the rest.
962 r
= dns_transaction_prepare(other
, ts
);
966 ts
+= transaction_get_resend_timeout(other
);
968 r
= sd_event_add_time(
969 other
->scope
->manager
->event
,
970 &other
->timeout_event_source
,
971 clock_boottime_or_monotonic(),
973 on_transaction_timeout
, other
);
977 other
->state
= DNS_TRANSACTION_PENDING
;
978 other
->next_attempt_after
= ts
;
982 if (dns_key_is_shared(other
->key
))
983 add_known_answers
= true;
986 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(qdcount
);
988 /* Append known answer section if we're asking for any shared record */
989 if (add_known_answers
) {
990 r
= dns_cache_export_shared_to_packet(&t
->scope
->cache
, p
);
1001 static int dns_transaction_make_packet(DnsTransaction
*t
) {
1002 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
1007 if (t
->scope
->protocol
== DNS_PROTOCOL_MDNS
)
1008 return dns_transaction_make_packet_mdns(t
);
1013 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0, t
->scope
->dnssec_mode
!= DNSSEC_NO
);
1017 r
= dns_scope_good_key(t
->scope
, t
->key
);
1023 r
= dns_packet_append_key(p
, t
->key
, NULL
);
1027 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(1);
1028 DNS_PACKET_HEADER(p
)->id
= t
->id
;
1036 int dns_transaction_go(DnsTransaction
*t
) {
1042 assert_se(sd_event_now(t
->scope
->manager
->event
, clock_boottime_or_monotonic(), &ts
) >= 0);
1044 r
= dns_transaction_prepare(t
, ts
);
1048 log_debug("Excercising transaction %" PRIu16
" for <%s> on scope %s on %s/%s.",
1050 dns_transaction_key_string(t
),
1051 dns_protocol_to_string(t
->scope
->protocol
),
1052 t
->scope
->link
? t
->scope
->link
->name
: "*",
1053 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
));
1055 if (!t
->initial_jitter_scheduled
&&
1056 (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
||
1057 t
->scope
->protocol
== DNS_PROTOCOL_MDNS
)) {
1058 usec_t jitter
, accuracy
;
1060 /* RFC 4795 Section 2.7 suggests all queries should be
1061 * delayed by a random time from 0 to JITTER_INTERVAL. */
1063 t
->initial_jitter_scheduled
= true;
1065 random_bytes(&jitter
, sizeof(jitter
));
1067 switch (t
->scope
->protocol
) {
1068 case DNS_PROTOCOL_LLMNR
:
1069 jitter
%= LLMNR_JITTER_INTERVAL_USEC
;
1070 accuracy
= LLMNR_JITTER_INTERVAL_USEC
;
1072 case DNS_PROTOCOL_MDNS
:
1073 jitter
%= MDNS_JITTER_RANGE_USEC
;
1074 jitter
+= MDNS_JITTER_MIN_USEC
;
1075 accuracy
= MDNS_JITTER_RANGE_USEC
;
1078 assert_not_reached("bad protocol");
1081 r
= sd_event_add_time(
1082 t
->scope
->manager
->event
,
1083 &t
->timeout_event_source
,
1084 clock_boottime_or_monotonic(),
1085 ts
+ jitter
, accuracy
,
1086 on_transaction_timeout
, t
);
1091 t
->next_attempt_after
= ts
;
1092 t
->state
= DNS_TRANSACTION_PENDING
;
1094 log_debug("Delaying %s transaction for " USEC_FMT
"us.", dns_protocol_to_string(t
->scope
->protocol
), jitter
);
1098 /* Otherwise, we need to ask the network */
1099 r
= dns_transaction_make_packet(t
);
1101 /* Not the right request to make on this network?
1102 * (i.e. an A request made on IPv6 or an AAAA request
1103 * made on IPv4, on LLMNR or mDNS.) */
1104 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
1110 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&&
1111 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), "in-addr.arpa") > 0 ||
1112 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), "ip6.arpa") > 0)) {
1114 /* RFC 4795, Section 2.4. says reverse lookups shall
1115 * always be made via TCP on LLMNR */
1116 r
= dns_transaction_open_tcp(t
);
1118 /* Try via UDP, and if that fails due to large size or lack of
1119 * support try via TCP */
1120 r
= dns_transaction_emit(t
);
1121 if (r
== -EMSGSIZE
|| r
== -EAGAIN
)
1122 r
= dns_transaction_open_tcp(t
);
1126 /* No servers to send this to? */
1127 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
1130 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
) {
1131 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
1135 /* Couldn't send? Try immediately again, with a new server */
1136 dns_transaction_next_dns_server(t
);
1138 return dns_transaction_go(t
);
1141 ts
+= transaction_get_resend_timeout(t
);
1143 r
= sd_event_add_time(
1144 t
->scope
->manager
->event
,
1145 &t
->timeout_event_source
,
1146 clock_boottime_or_monotonic(),
1148 on_transaction_timeout
, t
);
1152 t
->state
= DNS_TRANSACTION_PENDING
;
1153 t
->next_attempt_after
= ts
;
1158 static int dns_transaction_add_dnssec_transaction(DnsTransaction
*t
, DnsResourceKey
*key
, DnsTransaction
**ret
) {
1159 DnsTransaction
*aux
;
1166 aux
= dns_scope_find_transaction(t
->scope
, key
, true);
1168 r
= dns_transaction_new(&aux
, t
->scope
, key
);
1172 if (set_contains(t
->dnssec_transactions
, aux
)) {
1178 r
= set_ensure_allocated(&t
->dnssec_transactions
, NULL
);
1182 r
= set_ensure_allocated(&aux
->notify_transactions
, NULL
);
1186 r
= set_put(t
->dnssec_transactions
, aux
);
1190 r
= set_put(aux
->notify_transactions
, t
);
1192 (void) set_remove(t
->dnssec_transactions
, aux
);
1200 dns_transaction_gc(aux
);
1204 static int dns_transaction_request_dnssec_rr(DnsTransaction
*t
, DnsResourceKey
*key
) {
1205 _cleanup_(dns_answer_unrefp
) DnsAnswer
*a
= NULL
;
1206 DnsTransaction
*aux
;
1212 r
= dns_resource_key_equal(t
->key
, key
);
1215 if (r
> 0) /* Don't go in circles */
1218 /* Try to get the data from the trust anchor */
1219 r
= dns_trust_anchor_lookup(&t
->scope
->manager
->trust_anchor
, key
, &a
);
1223 r
= dns_answer_extend(&t
->validated_keys
, a
);
1230 /* This didn't work, ask for it via the network/cache then. */
1231 r
= dns_transaction_add_dnssec_transaction(t
, key
, &aux
);
1235 if (aux
->state
== DNS_TRANSACTION_NULL
) {
1236 r
= dns_transaction_go(aux
);
1244 static int dns_transaction_has_positive_answer(DnsTransaction
*t
, DnsAnswerFlags
*flags
) {
1249 /* Checks whether the answer is positive, i.e. either a direct
1250 * answer to the question, or a CNAME/DNAME for it */
1252 r
= dns_answer_match_key(t
->answer
, t
->key
, flags
);
1256 r
= dns_answer_find_cname_or_dname(t
->answer
, t
->key
, NULL
, flags
);
1263 static int dns_transaction_has_unsigned_negative_answer(DnsTransaction
*t
) {
1268 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
1269 * RRs to prove it */
1271 r
= dns_transaction_has_positive_answer(t
, NULL
);
1277 /* The answer does not contain any RRs that match to the
1278 * question. If so, let's see if there are any NSEC/NSEC3 RRs
1279 * included. If not, the answer is unsigned. */
1281 r
= dns_answer_contains_nsec_or_nsec3(t
->answer
);
1290 static int dns_transaction_is_primary_response(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
1296 /* Check if the specified RR is the "primary" response,
1297 * i.e. either matches the question precisely or is a
1298 * CNAME/DNAME for it, or is any kind of NSEC/NSEC3 RR */
1300 r
= dns_resource_key_match_rr(t
->key
, rr
, NULL
);
1304 r
= dns_resource_key_match_cname_or_dname(t
->key
, rr
->key
, NULL
);
1308 if (rr
->key
->type
== DNS_TYPE_NSEC3
) {
1311 p
= DNS_RESOURCE_KEY_NAME(rr
->key
);
1312 r
= dns_name_parent(&p
);
1316 r
= dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), p
);
1324 return rr
->key
->type
== DNS_TYPE_NSEC
;
1327 int dns_transaction_request_dnssec_keys(DnsTransaction
*t
) {
1328 DnsResourceRecord
*rr
;
1335 * Retrieve all auxiliary RRs for the answer we got, so that
1336 * we can verify signatures or prove that RRs are rightfully
1337 * unsigned. Specifically:
1339 * - For RRSIG we get the matching DNSKEY
1340 * - For DNSKEY we get the matching DS
1341 * - For unsigned SOA/NS we get the matching DS
1342 * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
1343 * - For other unsigned RRs we get the matching SOA RR
1344 * - For SOA/NS/DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
1345 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
1348 if (t
->scope
->dnssec_mode
== DNSSEC_NO
)
1351 if (t
->current_features
< DNS_SERVER_FEATURE_LEVEL_DO
)
1352 return 0; /* Server doesn't do DNSSEC, there's no point in requesting any RRs then. */
1353 if (t
->server
&& t
->server
->rrsig_missing
)
1354 return 0; /* Server handles DNSSEC requests, but isn't augmenting responses with RRSIGs. No point in trying DNSSEC then. */
1356 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
1358 if (dns_type_is_pseudo(rr
->key
->type
))
1361 switch (rr
->key
->type
) {
1363 case DNS_TYPE_RRSIG
: {
1364 /* For each RRSIG we request the matching DNSKEY */
1365 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*dnskey
= NULL
;
1367 /* If this RRSIG is about a DNSKEY RR and the
1368 * signer is the same as the owner, then we
1369 * already have the DNSKEY, and we don't have
1370 * to look for more. */
1371 if (rr
->rrsig
.type_covered
== DNS_TYPE_DNSKEY
) {
1372 r
= dns_name_equal(rr
->rrsig
.signer
, DNS_RESOURCE_KEY_NAME(rr
->key
));
1379 /* If the signer is not a parent of our
1380 * original query, then this is about an
1381 * auxiliary RRset, but not anything we asked
1382 * for. In this case we aren't interested,
1383 * because we don't want to request additional
1384 * RRs for stuff we didn't really ask for, and
1385 * also to avoid request loops, where
1386 * additional RRs from one transaction result
1387 * in another transaction whose additonal RRs
1388 * point back to the original transaction, and
1390 r
= dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), rr
->rrsig
.signer
);
1396 dnskey
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DNSKEY
, rr
->rrsig
.signer
);
1400 log_debug("Requesting DNSKEY to validate transaction %" PRIu16
" (%s, RRSIG with key tag: %" PRIu16
").", t
->id
, DNS_RESOURCE_KEY_NAME(rr
->key
), rr
->rrsig
.key_tag
);
1401 r
= dns_transaction_request_dnssec_rr(t
, dnskey
);
1407 case DNS_TYPE_DNSKEY
: {
1408 /* For each DNSKEY we request the matching DS */
1409 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*ds
= NULL
;
1411 /* If the DNSKEY we are looking at is not for
1412 * zone we are interested in, nor any of its
1413 * parents, we aren't interested, and don't
1414 * request it. After all, we don't want to end
1415 * up in request loops, and want to keep
1416 * additional traffic down. */
1418 r
= dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), DNS_RESOURCE_KEY_NAME(rr
->key
));
1424 ds
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DS
, DNS_RESOURCE_KEY_NAME(rr
->key
));
1428 log_debug("Requesting DS to validate transaction %" PRIu16
" (%s, DNSKEY with key tag: %" PRIu16
").", t
->id
, DNS_RESOURCE_KEY_NAME(rr
->key
), dnssec_keytag(rr
));
1429 r
= dns_transaction_request_dnssec_rr(t
, ds
);
1438 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*ds
= NULL
;
1440 /* For an unsigned SOA or NS, try to acquire
1441 * the matching DS RR, as we are at a zone cut
1442 * then, and whether a DS exists tells us
1443 * whether the zone is signed. Do so only if
1444 * this RR matches our original question,
1447 r
= dns_resource_key_match_rr(t
->key
, rr
, NULL
);
1453 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
1459 ds
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DS
, DNS_RESOURCE_KEY_NAME(rr
->key
));
1463 log_debug("Requesting DS to validate transaction %" PRIu16
" (%s, unsigned SOA/NS RRset).", t
->id
, DNS_RESOURCE_KEY_NAME(rr
->key
));
1464 r
= dns_transaction_request_dnssec_rr(t
, ds
);
1472 case DNS_TYPE_CNAME
:
1473 case DNS_TYPE_DNAME
: {
1474 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
1477 /* CNAMEs and DNAMEs cannot be located at a
1478 * zone apex, hence ask for the parent SOA for
1479 * unsigned CNAME/DNAME RRs, maybe that's the
1480 * apex. But do all that only if this is
1481 * actually a response to our original
1484 * Similar for DS RRs, which are signed when
1485 * the parent SOA is signed. */
1487 r
= dns_transaction_is_primary_response(t
, rr
);
1493 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
1499 name
= DNS_RESOURCE_KEY_NAME(rr
->key
);
1500 r
= dns_name_parent(&name
);
1506 soa
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_SOA
, name
);
1510 log_debug("Requesting parent SOA to validate transaction %" PRIu16
" (%s, unsigned CNAME/DNAME/DS RRset).", t
->id
, DNS_RESOURCE_KEY_NAME(rr
->key
));
1511 r
= dns_transaction_request_dnssec_rr(t
, soa
);
1519 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
1521 /* For other unsigned RRsets (including
1522 * NSEC/NSEC3!), look for proof the zone is
1523 * unsigned, by requesting the SOA RR of the
1524 * zone. However, do so only if they are
1525 * directly relevant to our original
1528 r
= dns_transaction_is_primary_response(t
, rr
);
1534 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
1540 soa
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_SOA
, DNS_RESOURCE_KEY_NAME(rr
->key
));
1544 log_debug("Requesting SOA to validate transaction %" PRIu16
" (%s, unsigned non-SOA/NS RRset <%s>).", t
->id
, DNS_RESOURCE_KEY_NAME(rr
->key
), dns_resource_record_to_string(rr
));
1545 r
= dns_transaction_request_dnssec_rr(t
, soa
);
1552 /* Above, we requested everything necessary to validate what
1553 * we got. Now, let's request what we need to validate what we
1556 r
= dns_transaction_has_unsigned_negative_answer(t
);
1562 name
= DNS_RESOURCE_KEY_NAME(t
->key
);
1564 /* If this was a SOA or NS request, then this
1565 * indicates that we are not at a zone apex, hence ask
1566 * the parent name instead. If this was a DS request,
1567 * then it's signed when the parent zone is signed,
1568 * hence ask the parent in that case, too. */
1570 if (IN_SET(t
->key
->type
, DNS_TYPE_SOA
, DNS_TYPE_NS
, DNS_TYPE_DS
)) {
1571 r
= dns_name_parent(&name
);
1575 log_debug("Requesting parent SOA to validate transaction %" PRIu16
" (%s, unsigned empty SOA/NS/DS response).", t
->id
, DNS_RESOURCE_KEY_NAME(t
->key
));
1579 log_debug("Requesting SOA to validate transaction %" PRIu16
" (%s, unsigned empty non-SOA/NS/DS response).", t
->id
, DNS_RESOURCE_KEY_NAME(t
->key
));
1582 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
1584 soa
= dns_resource_key_new(t
->key
->class, DNS_TYPE_SOA
, name
);
1588 r
= dns_transaction_request_dnssec_rr(t
, soa
);
1594 return dns_transaction_dnssec_is_live(t
);
1597 void dns_transaction_notify(DnsTransaction
*t
, DnsTransaction
*source
) {
1603 if (!IN_SET(t
->state
, DNS_TRANSACTION_PENDING
, DNS_TRANSACTION_VALIDATING
))
1606 /* Invoked whenever any of our auxiliary DNSSEC transactions
1607 completed its work. We copy any RRs from that transaction
1608 over into our list of validated keys -- but only if the
1609 answer is authenticated.
1611 Note that we fail our transaction if the auxiliary
1612 transaction failed, except on NXDOMAIN. This is because
1613 some broken DNS servers (Akamai...) will return NXDOMAIN
1614 for empty non-terminals. */
1616 switch (source
->state
) {
1618 case DNS_TRANSACTION_DNSSEC_FAILED
:
1620 log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(source
->answer_dnssec_result
));
1621 t
->answer_dnssec_result
= source
->answer_dnssec_result
; /* Copy error code over */
1622 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
1625 case DNS_TRANSACTION_RCODE_FAILURE
:
1627 if (source
->answer_rcode
!= DNS_RCODE_NXDOMAIN
) {
1628 log_debug("Auxiliary DNSSEC RR query failed with rcode=%i.", source
->answer_rcode
);
1632 /* fall-through: NXDOMAIN is good enough for us */
1634 case DNS_TRANSACTION_SUCCESS
:
1635 if (source
->answer_authenticated
) {
1636 r
= dns_answer_extend(&t
->validated_keys
, source
->answer
);
1638 log_error_errno(r
, "Failed to merge validated DNSSEC key data: %m");
1643 /* If the state is still PENDING, we are still in the loop
1644 * that adds further DNSSEC transactions, hence don't check if
1645 * we are ready yet. If the state is VALIDATING however, we
1646 * should check if we are complete now. */
1647 if (t
->state
== DNS_TRANSACTION_VALIDATING
)
1648 dns_transaction_process_dnssec(t
);
1652 log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(source
->state
));
1659 t
->answer_dnssec_result
= DNSSEC_FAILED_AUXILIARY
;
1660 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
1663 static int dns_transaction_validate_dnskey_by_ds(DnsTransaction
*t
) {
1664 DnsResourceRecord
*rr
;
1669 /* Add all DNSKEY RRs from the answer that are validated by DS
1670 * RRs from the list of validated keys to the list of
1671 * validated keys. */
1673 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, t
->answer
) {
1675 r
= dnssec_verify_dnskey_search(rr
, t
->validated_keys
);
1681 /* If so, the DNSKEY is validated too. */
1682 r
= dns_answer_add_extend(&t
->validated_keys
, rr
, ifindex
, DNS_ANSWER_AUTHENTICATED
);
1690 static int dns_transaction_requires_rrsig(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
1696 /* Checks if the RR we are looking for must be signed with an
1697 * RRSIG. This is used for positive responses. */
1699 if (t
->scope
->dnssec_mode
== DNSSEC_NO
)
1702 if (dns_type_is_pseudo(rr
->key
->type
))
1705 switch (rr
->key
->type
) {
1707 case DNS_TYPE_RRSIG
:
1708 /* RRSIGs are the signatures themselves, they need no signing. */
1716 /* For SOA or NS RRs we look for a matching DS transaction */
1718 SET_FOREACH(dt
, t
->dnssec_transactions
, i
) {
1720 if (dt
->key
->class != rr
->key
->class)
1722 if (dt
->key
->type
!= DNS_TYPE_DS
)
1725 r
= dns_name_equal(DNS_RESOURCE_KEY_NAME(dt
->key
), DNS_RESOURCE_KEY_NAME(rr
->key
));
1731 /* We found a DS transactions for the SOA/NS
1732 * RRs we are looking at. If it discovered signed DS
1733 * RRs, then we need to be signed, too. */
1735 if (!dt
->answer_authenticated
)
1738 return dns_answer_match_key(dt
->answer
, dt
->key
, NULL
);
1741 /* We found nothing that proves this is safe to leave
1742 * this unauthenticated, hence ask inist on
1743 * authentication. */
1748 case DNS_TYPE_CNAME
:
1749 case DNS_TYPE_DNAME
: {
1750 const char *parent
= NULL
;
1755 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
1757 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
1760 SET_FOREACH(dt
, t
->dnssec_transactions
, i
) {
1762 if (dt
->key
->class != rr
->key
->class)
1764 if (dt
->key
->type
!= DNS_TYPE_SOA
)
1768 parent
= DNS_RESOURCE_KEY_NAME(rr
->key
);
1769 r
= dns_name_parent(&parent
);
1773 if (rr
->key
->type
== DNS_TYPE_DS
)
1776 /* A CNAME/DNAME without a parent? That's sooo weird. */
1777 log_debug("Transaction %" PRIu16
" claims CNAME/DNAME at root. Refusing.", t
->id
);
1782 r
= dns_name_equal(DNS_RESOURCE_KEY_NAME(dt
->key
), parent
);
1788 return t
->answer_authenticated
;
1798 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
1800 SET_FOREACH(dt
, t
->dnssec_transactions
, i
) {
1802 if (dt
->key
->class != rr
->key
->class)
1804 if (dt
->key
->type
!= DNS_TYPE_SOA
)
1807 r
= dns_name_equal(DNS_RESOURCE_KEY_NAME(dt
->key
), DNS_RESOURCE_KEY_NAME(rr
->key
));
1813 /* We found the transaction that was supposed to find
1814 * the SOA RR for us. It was successful, but found no
1815 * RR for us. This means we are not at a zone cut. In
1816 * this case, we require authentication if the SOA
1817 * lookup was authenticated too. */
1818 return t
->answer_authenticated
;
1825 static int dns_transaction_requires_nsec(DnsTransaction
*t
) {
1833 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
1834 * this negative reply */
1836 if (t
->scope
->dnssec_mode
== DNSSEC_NO
)
1839 if (dns_type_is_pseudo(t
->key
->type
))
1842 name
= DNS_RESOURCE_KEY_NAME(t
->key
);
1844 if (IN_SET(t
->key
->type
, DNS_TYPE_SOA
, DNS_TYPE_NS
, DNS_TYPE_DS
)) {
1846 /* We got a negative reply for this SOA/NS lookup? If
1847 * so, then we are not at a zone apex, and thus should
1848 * look at the result of the parent SOA lookup.
1850 * We got a negative reply for this DS lookup? DS RRs
1851 * are signed when their parent zone is signed, hence
1852 * also check the parent SOA in this case. */
1854 r
= dns_name_parent(&name
);
1861 /* For all other RRs we check the SOA on the same level to see
1862 * if it's signed. */
1864 SET_FOREACH(dt
, t
->dnssec_transactions
, i
) {
1866 if (dt
->key
->class != t
->key
->class)
1868 if (dt
->key
->type
!= DNS_TYPE_SOA
)
1871 r
= dns_name_equal(DNS_RESOURCE_KEY_NAME(dt
->key
), name
);
1877 return dt
->answer_authenticated
;
1880 /* If in doubt, require NSEC/NSEC3 */
1884 static int dns_transaction_dnskey_authenticated(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
1885 DnsResourceRecord
*rrsig
;
1889 /* Checks whether any of the DNSKEYs used for the RRSIGs for
1890 * the specified RRset is authenticated (i.e. has a matching
1893 DNS_ANSWER_FOREACH(rrsig
, t
->answer
) {
1897 r
= dnssec_key_match_rrsig(rr
->key
, rrsig
);
1903 SET_FOREACH(dt
, t
->dnssec_transactions
, i
) {
1905 if (dt
->key
->class != rr
->key
->class)
1908 if (dt
->key
->type
== DNS_TYPE_DNSKEY
) {
1910 r
= dns_name_equal(DNS_RESOURCE_KEY_NAME(dt
->key
), rrsig
->rrsig
.signer
);
1916 /* OK, we found an auxiliary DNSKEY
1917 * lookup. If that lookup is
1918 * authenticated, report this. */
1920 if (dt
->answer_authenticated
)
1925 } else if (dt
->key
->type
== DNS_TYPE_DS
) {
1927 r
= dns_name_equal(DNS_RESOURCE_KEY_NAME(dt
->key
), rrsig
->rrsig
.signer
);
1933 /* OK, we found an auxiliary DS
1934 * lookup. If that lookup is
1935 * authenticated and non-zero, we
1938 if (!dt
->answer_authenticated
)
1941 return dns_answer_match_key(dt
->answer
, dt
->key
, NULL
);
1946 return found
? false : -ENXIO
;
1949 static int dns_transaction_known_signed(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
1953 /* We know that the root domain is signed, hence if it appears
1954 * not to be signed, there's a problem with the DNS server */
1956 return rr
->key
->class == DNS_CLASS_IN
&&
1957 dns_name_is_root(DNS_RESOURCE_KEY_NAME(rr
->key
));
1960 int dns_transaction_validate_dnssec(DnsTransaction
*t
) {
1961 _cleanup_(dns_answer_unrefp
) DnsAnswer
*validated
= NULL
;
1962 bool dnskeys_finalized
= false;
1963 DnsResourceRecord
*rr
;
1964 DnsAnswerFlags flags
;
1969 /* We have now collected all DS and DNSKEY RRs in
1970 * t->validated_keys, let's see which RRs we can now
1971 * authenticate with that. */
1973 if (t
->scope
->dnssec_mode
== DNSSEC_NO
)
1976 /* Already validated */
1977 if (t
->answer_dnssec_result
!= _DNSSEC_RESULT_INVALID
)
1980 /* Our own stuff needs no validation */
1981 if (IN_SET(t
->answer_source
, DNS_TRANSACTION_ZONE
, DNS_TRANSACTION_TRUST_ANCHOR
)) {
1982 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
1983 t
->answer_authenticated
= true;
1987 /* Cached stuff is not affected by validation. */
1988 if (t
->answer_source
!= DNS_TRANSACTION_NETWORK
)
1991 if (t
->current_features
< DNS_SERVER_FEATURE_LEVEL_DO
||
1992 (t
->server
&& t
->server
->rrsig_missing
)) {
1993 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
1994 t
->answer_dnssec_result
= DNSSEC_INCOMPATIBLE_SERVER
;
1998 log_debug("Validating response from transaction %" PRIu16
" (%s).", t
->id
, dns_transaction_key_string(t
));
2000 /* First see if there are DNSKEYs we already known a validated DS for. */
2001 r
= dns_transaction_validate_dnskey_by_ds(t
);
2006 bool changed
= false;
2008 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
2009 DnssecResult result
;
2011 if (rr
->key
->type
== DNS_TYPE_RRSIG
)
2014 r
= dnssec_verify_rrset_search(t
->answer
, rr
->key
, t
->validated_keys
, USEC_INFINITY
, &result
);
2018 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr
)), dnssec_result_to_string(result
));
2020 if (result
== DNSSEC_VALIDATED
) {
2022 if (rr
->key
->type
== DNS_TYPE_DNSKEY
) {
2023 /* If we just validated a
2024 * DNSKEY RRset, then let's
2025 * add these keys to the set
2026 * of validated keys for this
2029 r
= dns_answer_copy_by_key(&t
->validated_keys
, t
->answer
, rr
->key
, DNS_ANSWER_AUTHENTICATED
);
2034 /* Add the validated RRset to the new
2035 * list of validated RRsets, and
2036 * remove it from the unvalidated
2037 * RRsets. We mark the RRset as
2038 * authenticated and cacheable. */
2039 r
= dns_answer_move_by_key(&validated
, &t
->answer
, rr
->key
, DNS_ANSWER_AUTHENTICATED
|DNS_ANSWER_CACHEABLE
);
2043 t
->scope
->manager
->n_dnssec_secure
++;
2045 /* Exit the loop, we dropped something from the answer, start from the beginning */
2049 } else if (dnskeys_finalized
) {
2051 /* If we haven't read all DNSKEYs yet
2052 * a negative result of the validation
2053 * is irrelevant, as there might be
2054 * more DNSKEYs coming. */
2056 if (result
== DNSSEC_NO_SIGNATURE
) {
2057 r
= dns_transaction_requires_rrsig(t
, rr
);
2061 /* Data does not require signing. In that case, just copy it over,
2062 * but remember that this is by no means authenticated.*/
2063 r
= dns_answer_move_by_key(&validated
, &t
->answer
, rr
->key
, 0);
2067 t
->scope
->manager
->n_dnssec_insecure
++;
2073 r
= dns_transaction_known_signed(t
, rr
);
2077 /* This is an RR we know has to be signed. If it isn't this means
2078 * the server is not attaching RRSIGs, hence complain. */
2080 dns_server_packet_rrsig_missing(t
->server
);
2082 if (t
->scope
->dnssec_mode
== DNSSEC_DOWNGRADE_OK
) {
2084 /* Downgrading is OK? If so, just consider the information unsigned */
2086 r
= dns_answer_move_by_key(&validated
, &t
->answer
, rr
->key
, 0);
2090 t
->scope
->manager
->n_dnssec_insecure
++;
2095 /* Otherwise, fail */
2096 t
->answer_dnssec_result
= DNSSEC_INCOMPATIBLE_SERVER
;
2103 DNSSEC_SIGNATURE_EXPIRED
,
2104 DNSSEC_UNSUPPORTED_ALGORITHM
)) {
2106 r
= dns_transaction_dnskey_authenticated(t
, rr
);
2107 if (r
< 0 && r
!= -ENXIO
)
2110 /* The DNSKEY transaction was not authenticated, this means there's
2111 * no DS for this, which means it's OK if no keys are found for this signature. */
2113 r
= dns_answer_move_by_key(&validated
, &t
->answer
, rr
->key
, 0);
2117 t
->scope
->manager
->n_dnssec_insecure
++;
2126 DNSSEC_SIGNATURE_EXPIRED
,
2127 DNSSEC_NO_SIGNATURE
,
2128 DNSSEC_UNSUPPORTED_ALGORITHM
))
2129 t
->scope
->manager
->n_dnssec_bogus
++;
2131 t
->scope
->manager
->n_dnssec_indeterminate
++;
2133 r
= dns_transaction_is_primary_response(t
, rr
);
2137 /* This is a primary response
2138 * to our question, and it
2139 * failed validation. That's
2141 t
->answer_dnssec_result
= result
;
2145 /* This is just some auxiliary
2146 * data. Just remove the RRset and
2148 r
= dns_answer_remove_by_key(&t
->answer
, rr
->key
);
2152 /* Exit the loop, we dropped something from the answer, start from the beginning */
2161 if (!dnskeys_finalized
) {
2162 /* OK, now we know we have added all DNSKEYs
2163 * we possibly could to our validated
2164 * list. Now run the whole thing once more,
2165 * and strip everything we still cannot
2168 dnskeys_finalized
= true;
2176 dns_answer_unref(t
->answer
);
2177 t
->answer
= validated
;
2180 /* At this point the answer only contains validated
2181 * RRsets. Now, let's see if it actually answers the question
2182 * we asked. If so, great! If it doesn't, then see if
2183 * NSEC/NSEC3 can prove this. */
2184 r
= dns_transaction_has_positive_answer(t
, &flags
);
2186 /* Yes, it answers the question! */
2188 if (flags
& DNS_ANSWER_AUTHENTICATED
) {
2189 /* The answer is fully authenticated, yay. */
2190 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
2191 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
2192 t
->answer_authenticated
= true;
2194 /* The answer is not fully authenticated. */
2195 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
2196 t
->answer_authenticated
= false;
2199 } else if (r
== 0) {
2200 DnssecNsecResult nr
;
2201 bool authenticated
= false;
2203 /* Bummer! Let's check NSEC/NSEC3 */
2204 r
= dnssec_test_nsec(t
->answer
, t
->key
, &nr
, &authenticated
);
2210 case DNSSEC_NSEC_NXDOMAIN
:
2211 /* NSEC proves the domain doesn't exist. Very good. */
2212 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t
->id
, dns_transaction_key_string(t
));
2213 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
2214 t
->answer_rcode
= DNS_RCODE_NXDOMAIN
;
2215 t
->answer_authenticated
= authenticated
;
2218 case DNSSEC_NSEC_NODATA
:
2219 /* NSEC proves that there's no data here, very good. */
2220 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t
->id
, dns_transaction_key_string(t
));
2221 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
2222 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
2223 t
->answer_authenticated
= authenticated
;
2226 case DNSSEC_NSEC_OPTOUT
:
2227 /* NSEC3 says the data might not be signed */
2228 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t
->id
, dns_transaction_key_string(t
));
2229 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
2230 t
->answer_authenticated
= false;
2233 case DNSSEC_NSEC_NO_RR
:
2234 /* No NSEC data? Bummer! */
2236 r
= dns_transaction_requires_nsec(t
);
2240 t
->answer_dnssec_result
= DNSSEC_NO_SIGNATURE
;
2242 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
2243 t
->answer_authenticated
= false;
2248 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM
:
2249 /* We don't know the NSEC3 algorithm used? */
2250 t
->answer_dnssec_result
= DNSSEC_UNSUPPORTED_ALGORITHM
;
2253 case DNSSEC_NSEC_FOUND
:
2254 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
2255 t
->answer_dnssec_result
= DNSSEC_NSEC_MISMATCH
;
2259 assert_not_reached("Unexpected NSEC result.");
2266 const char *dns_transaction_key_string(DnsTransaction
*t
) {
2269 if (!t
->key_string
) {
2270 if (dns_resource_key_to_string(t
->key
, &t
->key_string
) < 0)
2274 return strstrip(t
->key_string
);
2277 static const char* const dns_transaction_state_table
[_DNS_TRANSACTION_STATE_MAX
] = {
2278 [DNS_TRANSACTION_NULL
] = "null",
2279 [DNS_TRANSACTION_PENDING
] = "pending",
2280 [DNS_TRANSACTION_VALIDATING
] = "validating",
2281 [DNS_TRANSACTION_RCODE_FAILURE
] = "rcode-failure",
2282 [DNS_TRANSACTION_SUCCESS
] = "success",
2283 [DNS_TRANSACTION_NO_SERVERS
] = "no-servers",
2284 [DNS_TRANSACTION_TIMEOUT
] = "timeout",
2285 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
] = "attempts-max-reached",
2286 [DNS_TRANSACTION_INVALID_REPLY
] = "invalid-reply",
2287 [DNS_TRANSACTION_RESOURCES
] = "resources",
2288 [DNS_TRANSACTION_CONNECTION_FAILURE
] = "connection-failure",
2289 [DNS_TRANSACTION_ABORTED
] = "aborted",
2290 [DNS_TRANSACTION_DNSSEC_FAILED
] = "dnssec-failed",
2292 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state
, DnsTransactionState
);
2294 static const char* const dns_transaction_source_table
[_DNS_TRANSACTION_SOURCE_MAX
] = {
2295 [DNS_TRANSACTION_NETWORK
] = "network",
2296 [DNS_TRANSACTION_CACHE
] = "cache",
2297 [DNS_TRANSACTION_ZONE
] = "zone",
2298 [DNS_TRANSACTION_TRUST_ANCHOR
] = "trust-anchor",
2300 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source
, DnsTransactionSource
);