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