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