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