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