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