]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-transaction.c
Merge pull request #1359 from jengelh/ue
[thirdparty/systemd.git] / src / resolve / resolved-dns-transaction.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <sd-messages.h>
23
24 #include "af-list.h"
25 #include "alloc-util.h"
26 #include "dns-domain.h"
27 #include "fd-util.h"
28 #include "random-util.h"
29 #include "resolved-dns-cache.h"
30 #include "resolved-dns-transaction.h"
31 #include "resolved-llmnr.h"
32 #include "string-table.h"
33
34 #define TRANSACTIONS_MAX 4096
35
36 static void dns_transaction_reset_answer(DnsTransaction *t) {
37 assert(t);
38
39 t->received = dns_packet_unref(t->received);
40 t->answer = dns_answer_unref(t->answer);
41 t->answer_rcode = 0;
42 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
43 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
44 t->answer_authenticated = false;
45 t->answer_nsec_ttl = (uint32_t) -1;
46 }
47
48 static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) {
49 DnsTransaction *z;
50
51 assert(t);
52
53 while ((z = set_steal_first(t->dnssec_transactions))) {
54 set_remove(z->notify_transactions, t);
55 dns_transaction_gc(z);
56 }
57 }
58
59 static void dns_transaction_close_connection(DnsTransaction *t) {
60 assert(t);
61
62 t->stream = dns_stream_free(t->stream);
63 t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source);
64 t->dns_udp_fd = safe_close(t->dns_udp_fd);
65 }
66
67 static void dns_transaction_stop_timeout(DnsTransaction *t) {
68 assert(t);
69
70 t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
71 }
72
73 DnsTransaction* dns_transaction_free(DnsTransaction *t) {
74 DnsQueryCandidate *c;
75 DnsZoneItem *i;
76 DnsTransaction *z;
77
78 if (!t)
79 return NULL;
80
81 log_debug("Freeing transaction %" PRIu16 ".", t->id);
82
83 dns_transaction_close_connection(t);
84 dns_transaction_stop_timeout(t);
85
86 dns_packet_unref(t->sent);
87 dns_transaction_reset_answer(t);
88
89 dns_server_unref(t->server);
90
91 if (t->scope) {
92 hashmap_remove_value(t->scope->transactions_by_key, t->key, t);
93 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
94
95 if (t->id != 0)
96 hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
97 }
98
99 while ((c = set_steal_first(t->notify_query_candidates)))
100 set_remove(c->transactions, t);
101 set_free(t->notify_query_candidates);
102
103 while ((i = set_steal_first(t->notify_zone_items)))
104 i->probe_transaction = NULL;
105 set_free(t->notify_zone_items);
106
107 while ((z = set_steal_first(t->notify_transactions)))
108 set_remove(z->dnssec_transactions, t);
109 set_free(t->notify_transactions);
110
111 dns_transaction_flush_dnssec_transactions(t);
112 set_free(t->dnssec_transactions);
113
114 dns_answer_unref(t->validated_keys);
115 dns_resource_key_unref(t->key);
116 free(t->key_string);
117
118 free(t);
119 return NULL;
120 }
121
122 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
123
124 bool dns_transaction_gc(DnsTransaction *t) {
125 assert(t);
126
127 if (t->block_gc > 0)
128 return true;
129
130 if (set_isempty(t->notify_query_candidates) &&
131 set_isempty(t->notify_zone_items) &&
132 set_isempty(t->notify_transactions)) {
133 dns_transaction_free(t);
134 return false;
135 }
136
137 return true;
138 }
139
140 static uint16_t pick_new_id(Manager *m) {
141 uint16_t new_id;
142
143 /* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the number of
144 * transactions, and it's much lower than the space of IDs. */
145
146 assert_cc(TRANSACTIONS_MAX < 0xFFFF);
147
148 do
149 random_bytes(&new_id, sizeof(new_id));
150 while (new_id == 0 ||
151 hashmap_get(m->dns_transactions, UINT_TO_PTR(new_id)));
152
153 return new_id;
154 }
155
156 int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) {
157 _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
158 int r;
159
160 assert(ret);
161 assert(s);
162 assert(key);
163
164 /* Don't allow looking up invalid or pseudo RRs */
165 if (!dns_type_is_valid_query(key->type))
166 return -EINVAL;
167 if (dns_type_is_obsolete(key->type))
168 return -EOPNOTSUPP;
169
170 /* We only support the IN class */
171 if (key->class != DNS_CLASS_IN && key->class != DNS_CLASS_ANY)
172 return -EOPNOTSUPP;
173
174 if (hashmap_size(s->manager->dns_transactions) >= TRANSACTIONS_MAX)
175 return -EBUSY;
176
177 r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
178 if (r < 0)
179 return r;
180
181 r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
182 if (r < 0)
183 return r;
184
185 t = new0(DnsTransaction, 1);
186 if (!t)
187 return -ENOMEM;
188
189 t->dns_udp_fd = -1;
190 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
191 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
192 t->answer_nsec_ttl = (uint32_t) -1;
193 t->key = dns_resource_key_ref(key);
194 t->current_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
195
196 t->id = pick_new_id(s->manager);
197
198 r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
199 if (r < 0) {
200 t->id = 0;
201 return r;
202 }
203
204 r = hashmap_replace(s->transactions_by_key, t->key, t);
205 if (r < 0) {
206 hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
207 return r;
208 }
209
210 LIST_PREPEND(transactions_by_scope, s->transactions, t);
211 t->scope = s;
212
213 s->manager->n_transactions_total ++;
214
215 if (ret)
216 *ret = t;
217
218 t = NULL;
219
220 return 0;
221 }
222
223 static void dns_transaction_shuffle_id(DnsTransaction *t) {
224 uint16_t new_id;
225 assert(t);
226
227 /* Pick a new ID for this transaction. */
228
229 new_id = pick_new_id(t->scope->manager);
230 assert_se(hashmap_remove_and_put(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id), UINT_TO_PTR(new_id), t) >= 0);
231
232 log_debug("Transaction %" PRIu16 " is now %" PRIu16 ".", t->id, new_id);
233 t->id = new_id;
234
235 /* Make sure we generate a new packet with the new ID */
236 t->sent = dns_packet_unref(t->sent);
237 }
238
239 static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
240 _cleanup_free_ char *pretty = NULL;
241 DnsZoneItem *z;
242
243 assert(t);
244 assert(p);
245
246 if (manager_our_packet(t->scope->manager, p) != 0)
247 return;
248
249 in_addr_to_string(p->family, &p->sender, &pretty);
250
251 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s got tentative packet from %s.",
252 t->id,
253 dns_transaction_key_string(t),
254 dns_protocol_to_string(t->scope->protocol),
255 t->scope->link ? t->scope->link->name : "*",
256 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
257 pretty);
258
259 /* RFC 4795, Section 4.1 says that the peer with the
260 * lexicographically smaller IP address loses */
261 if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
262 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
263 return;
264 }
265
266 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
267
268 t->block_gc++;
269 while ((z = set_first(t->notify_zone_items))) {
270 /* First, make sure the zone item drops the reference
271 * to us */
272 dns_zone_item_probe_stop(z);
273
274 /* Secondly, report this as conflict, so that we might
275 * look for a different hostname */
276 dns_zone_item_conflict(z);
277 }
278 t->block_gc--;
279
280 dns_transaction_gc(t);
281 }
282
283 void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
284 DnsQueryCandidate *c;
285 DnsZoneItem *z;
286 DnsTransaction *d;
287 Iterator i;
288
289 assert(t);
290 assert(!DNS_TRANSACTION_IS_LIVE(state));
291
292 if (state == DNS_TRANSACTION_DNSSEC_FAILED)
293 log_struct(LOG_NOTICE,
294 LOG_MESSAGE_ID(SD_MESSAGE_DNSSEC_FAILURE),
295 LOG_MESSAGE("DNSSEC validation failed for question %s: %s", dns_transaction_key_string(t), dnssec_result_to_string(t->answer_dnssec_result)),
296 "DNS_TRANSACTION=%" PRIu16, t->id,
297 "DNS_QUESTION=%s", dns_transaction_key_string(t),
298 "DNSSEC_RESULT=%s", dnssec_result_to_string(t->answer_dnssec_result),
299 NULL);
300
301 /* Note that this call might invalidate the query. Callers
302 * should hence not attempt to access the query or transaction
303 * after calling this function. */
304
305 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).",
306 t->id,
307 dns_transaction_key_string(t),
308 dns_protocol_to_string(t->scope->protocol),
309 t->scope->link ? t->scope->link->name : "*",
310 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
311 dns_transaction_state_to_string(state),
312 t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
313 t->answer_authenticated ? "authenticated" : "unsigned");
314
315 t->state = state;
316
317 dns_transaction_close_connection(t);
318 dns_transaction_stop_timeout(t);
319
320 /* Notify all queries that are interested, but make sure the
321 * transaction isn't freed while we are still looking at it */
322 t->block_gc++;
323
324 SET_FOREACH(c, t->notify_query_candidates, i)
325 dns_query_candidate_notify(c);
326 SET_FOREACH(z, t->notify_zone_items, i)
327 dns_zone_item_notify(z);
328
329 if (!set_isempty(t->notify_transactions)) {
330 DnsTransaction **nt;
331 unsigned j, n = 0;
332
333 /* We need to be careful when notifying other
334 * transactions, as that might destroy other
335 * transactions in our list. Hence, in order to be
336 * able to safely iterate through the list of
337 * transactions, take a GC lock on all of them
338 * first. Then, in a second loop, notify them, but
339 * first unlock that specific transaction. */
340
341 nt = newa(DnsTransaction*, set_size(t->notify_transactions));
342 SET_FOREACH(d, t->notify_transactions, i) {
343 nt[n++] = d;
344 d->block_gc++;
345 }
346
347 assert(n == set_size(t->notify_transactions));
348
349 for (j = 0; j < n; j++) {
350 if (set_contains(t->notify_transactions, nt[j]))
351 dns_transaction_notify(nt[j], t);
352
353 nt[j]->block_gc--;
354 dns_transaction_gc(nt[j]);
355 }
356 }
357
358 t->block_gc--;
359 dns_transaction_gc(t);
360 }
361
362 static int dns_transaction_pick_server(DnsTransaction *t) {
363 DnsServer *server;
364
365 assert(t);
366 assert(t->scope->protocol == DNS_PROTOCOL_DNS);
367
368 server = dns_scope_get_dns_server(t->scope);
369 if (!server)
370 return -ESRCH;
371
372 t->current_feature_level = dns_server_possible_feature_level(server);
373
374 if (server == t->server)
375 return 0;
376
377 dns_server_unref(t->server);
378 t->server = dns_server_ref(server);
379
380 return 1;
381 }
382
383 static void dns_transaction_retry(DnsTransaction *t) {
384 int r;
385
386 assert(t);
387
388 log_debug("Retrying transaction %" PRIu16 ".", t->id);
389
390 /* Before we try again, switch to a new server. */
391 dns_scope_next_dns_server(t->scope);
392
393 r = dns_transaction_go(t);
394 if (r < 0)
395 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
396 }
397
398 static int dns_transaction_maybe_restart(DnsTransaction *t) {
399 assert(t);
400
401 if (!t->server)
402 return 0;
403
404 if (t->current_feature_level <= dns_server_possible_feature_level(t->server))
405 return 0;
406
407 /* The server's current feature level is lower than when we sent the original query. We learnt something from
408 the response or possibly an auxiliary DNSSEC response that we didn't know before. We take that as reason to
409 restart the whole transaction. This is a good idea to deal with servers that respond rubbish if we include
410 OPT RR or DO bit. One of these cases is documented here, for example:
411 https://open.nlnetlabs.nl/pipermail/dnssec-trigger/2014-November/000376.html */
412
413 log_debug("Server feature level is now lower than when we began our transaction. Restarting with new ID.");
414 dns_transaction_shuffle_id(t);
415 return dns_transaction_go(t);
416 }
417
418 static int on_stream_complete(DnsStream *s, int error) {
419 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
420 DnsTransaction *t;
421
422 assert(s);
423 assert(s->transaction);
424
425 /* Copy the data we care about out of the stream before we
426 * destroy it. */
427 t = s->transaction;
428 p = dns_packet_ref(s->read_packet);
429
430 t->stream = dns_stream_free(t->stream);
431
432 if (ERRNO_IS_DISCONNECT(error)) {
433 usec_t usec;
434
435 log_debug_errno(error, "Connection failure for DNS TCP stream: %m");
436 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
437 dns_server_packet_lost(t->server, IPPROTO_TCP, t->current_feature_level, usec - t->start_usec);
438
439 dns_transaction_retry(t);
440 return 0;
441 }
442 if (error != 0) {
443 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
444 return 0;
445 }
446
447 if (dns_packet_validate_reply(p) <= 0) {
448 log_debug("Invalid TCP reply packet.");
449 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
450 return 0;
451 }
452
453 dns_scope_check_conflicts(t->scope, p);
454
455 t->block_gc++;
456 dns_transaction_process_reply(t, p);
457 t->block_gc--;
458
459 /* If the response wasn't useful, then complete the transition
460 * now. After all, we are the worst feature set now with TCP
461 * sockets, and there's really no point in retrying. */
462 if (t->state == DNS_TRANSACTION_PENDING)
463 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
464 else
465 dns_transaction_gc(t);
466
467 return 0;
468 }
469
470 static int dns_transaction_open_tcp(DnsTransaction *t) {
471 _cleanup_close_ int fd = -1;
472 int r;
473
474 assert(t);
475
476 dns_transaction_close_connection(t);
477
478 switch (t->scope->protocol) {
479
480 case DNS_PROTOCOL_DNS:
481 r = dns_transaction_pick_server(t);
482 if (r < 0)
483 return r;
484
485 if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
486 return -EOPNOTSUPP;
487
488 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
489 if (r < 0)
490 return r;
491
492 fd = dns_scope_socket_tcp(t->scope, AF_UNSPEC, NULL, t->server, 53);
493 break;
494
495 case DNS_PROTOCOL_LLMNR:
496 /* When we already received a reply to this (but it was truncated), send to its sender address */
497 if (t->received)
498 fd = dns_scope_socket_tcp(t->scope, t->received->family, &t->received->sender, NULL, t->received->sender_port);
499 else {
500 union in_addr_union address;
501 int family = AF_UNSPEC;
502
503 /* Otherwise, try to talk to the owner of a
504 * the IP address, in case this is a reverse
505 * PTR lookup */
506
507 r = dns_name_address(DNS_RESOURCE_KEY_NAME(t->key), &family, &address);
508 if (r < 0)
509 return r;
510 if (r == 0)
511 return -EINVAL;
512 if (family != t->scope->family)
513 return -ESRCH;
514
515 fd = dns_scope_socket_tcp(t->scope, family, &address, NULL, LLMNR_PORT);
516 }
517
518 break;
519
520 default:
521 return -EAFNOSUPPORT;
522 }
523
524 if (fd < 0)
525 return fd;
526
527 r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
528 if (r < 0)
529 return r;
530 fd = -1;
531
532 r = dns_stream_write_packet(t->stream, t->sent);
533 if (r < 0) {
534 t->stream = dns_stream_free(t->stream);
535 return r;
536 }
537
538 t->stream->complete = on_stream_complete;
539 t->stream->transaction = t;
540
541 /* The interface index is difficult to determine if we are
542 * connecting to the local host, hence fill this in right away
543 * instead of determining it from the socket */
544 if (t->scope->link)
545 t->stream->ifindex = t->scope->link->ifindex;
546
547 dns_transaction_reset_answer(t);
548
549 t->tried_stream = true;
550
551 return 0;
552 }
553
554 static void dns_transaction_cache_answer(DnsTransaction *t) {
555 assert(t);
556
557 /* For mDNS we cache whenever we get the packet, rather than
558 * in each transaction. */
559 if (!IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR))
560 return;
561
562 /* We never cache if this packet is from the local host, under
563 * the assumption that a locally running DNS server would
564 * cache this anyway, and probably knows better when to flush
565 * the cache then we could. */
566 if (!DNS_PACKET_SHALL_CACHE(t->received))
567 return;
568
569 dns_cache_put(&t->scope->cache,
570 t->key,
571 t->answer_rcode,
572 t->answer,
573 t->answer_authenticated,
574 t->answer_nsec_ttl,
575 0,
576 t->received->family,
577 &t->received->sender);
578 }
579
580 static bool dns_transaction_dnssec_is_live(DnsTransaction *t) {
581 DnsTransaction *dt;
582 Iterator i;
583
584 assert(t);
585
586 SET_FOREACH(dt, t->dnssec_transactions, i)
587 if (DNS_TRANSACTION_IS_LIVE(dt->state))
588 return true;
589
590 return false;
591 }
592
593 static int dns_transaction_dnssec_ready(DnsTransaction *t) {
594 DnsTransaction *dt;
595 Iterator i;
596
597 assert(t);
598
599 /* Checks whether the auxiliary DNSSEC transactions of our transaction have completed, or are still
600 * ongoing. Returns 0, if we aren't ready for the DNSSEC validation, positive if we are. */
601
602 SET_FOREACH(dt, t->dnssec_transactions, i) {
603
604 switch (dt->state) {
605
606 case DNS_TRANSACTION_NULL:
607 case DNS_TRANSACTION_PENDING:
608 case DNS_TRANSACTION_VALIDATING:
609 /* Still ongoing */
610 return 0;
611
612 case DNS_TRANSACTION_RCODE_FAILURE:
613 if (dt->answer_rcode != DNS_RCODE_NXDOMAIN) {
614 log_debug("Auxiliary DNSSEC RR query failed with rcode=%s.", dns_rcode_to_string(dt->answer_rcode));
615 goto fail;
616 }
617
618 /* Fall-through: NXDOMAIN is good enough for us. This is because some DNS servers erronously
619 * return NXDOMAIN for empty non-terminals (Akamai...), and we need to handle that nicely, when
620 * asking for parent SOA or similar RRs to make unsigned proofs. */
621
622 case DNS_TRANSACTION_SUCCESS:
623 /* All good. */
624 break;
625
626 case DNS_TRANSACTION_DNSSEC_FAILED:
627 /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
628 * validationr result */
629
630 log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result));
631 t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */
632 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
633 return 0;
634
635
636 default:
637 log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(dt->state));
638 goto fail;
639 }
640 }
641
642 /* All is ready, we can go and validate */
643 return 1;
644
645 fail:
646 t->answer_dnssec_result = DNSSEC_FAILED_AUXILIARY;
647 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
648 return 0;
649 }
650
651 static void dns_transaction_process_dnssec(DnsTransaction *t) {
652 int r;
653
654 assert(t);
655
656 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
657 r = dns_transaction_dnssec_ready(t);
658 if (r < 0) {
659 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
660 return;
661 }
662 if (r == 0) /* We aren't ready yet (or one of our auxiliary transactions failed, and we shouldn't validate now */
663 return;
664
665 /* See if we learnt things from the additional DNSSEC transactions, that we didn't know before, and better
666 * restart the lookup immediately. */
667 r = dns_transaction_maybe_restart(t);
668 if (r < 0) {
669 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
670 return;
671 }
672 if (r > 0) /* Transaction got restarted... */
673 return;
674
675 /* All our auxiliary DNSSEC transactions are complete now. Try
676 * to validate our RRset now. */
677 r = dns_transaction_validate_dnssec(t);
678 if (r < 0) {
679 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
680 return;
681 }
682
683 if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER &&
684 t->scope->dnssec_mode == DNSSEC_YES) {
685 /* We are not in automatic downgrade mode, and the
686 * server is bad, refuse operation. */
687 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
688 return;
689 }
690
691 if (!IN_SET(t->answer_dnssec_result,
692 _DNSSEC_RESULT_INVALID, /* No DNSSEC validation enabled */
693 DNSSEC_VALIDATED, /* Answer is signed and validated successfully */
694 DNSSEC_UNSIGNED, /* Answer is right-fully unsigned */
695 DNSSEC_INCOMPATIBLE_SERVER)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
696 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
697 return;
698 }
699
700 dns_transaction_cache_answer(t);
701
702 if (t->answer_rcode == DNS_RCODE_SUCCESS)
703 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
704 else
705 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
706 }
707
708 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
709 usec_t ts;
710 int r;
711
712 assert(t);
713 assert(p);
714 assert(t->scope);
715 assert(t->scope->manager);
716
717 if (t->state != DNS_TRANSACTION_PENDING)
718 return;
719
720 /* Note that this call might invalidate the query. Callers
721 * should hence not attempt to access the query or transaction
722 * after calling this function. */
723
724 log_debug("Processing incoming packet on transaction %" PRIu16".", t->id);
725
726 switch (t->scope->protocol) {
727
728 case DNS_PROTOCOL_LLMNR:
729 assert(t->scope->link);
730
731 /* For LLMNR we will not accept any packets from other
732 * interfaces */
733
734 if (p->ifindex != t->scope->link->ifindex)
735 return;
736
737 if (p->family != t->scope->family)
738 return;
739
740 /* Tentative packets are not full responses but still
741 * useful for identifying uniqueness conflicts during
742 * probing. */
743 if (DNS_PACKET_LLMNR_T(p)) {
744 dns_transaction_tentative(t, p);
745 return;
746 }
747
748 break;
749
750 case DNS_PROTOCOL_MDNS:
751 assert(t->scope->link);
752
753 /* For mDNS we will not accept any packets from other interfaces */
754 if (p->ifindex != t->scope->link->ifindex)
755 return;
756
757 if (p->family != t->scope->family)
758 return;
759
760 break;
761
762 case DNS_PROTOCOL_DNS:
763 /* Note that we do not need to verify the
764 * addresses/port numbers of incoming traffic, as we
765 * invoked connect() on our UDP socket in which case
766 * the kernel already does the needed verification for
767 * us. */
768 break;
769
770 default:
771 assert_not_reached("Invalid DNS protocol.");
772 }
773
774 if (t->received != p) {
775 dns_packet_unref(t->received);
776 t->received = dns_packet_ref(p);
777 }
778
779 t->answer_source = DNS_TRANSACTION_NETWORK;
780
781 if (p->ipproto == IPPROTO_TCP) {
782 if (DNS_PACKET_TC(p)) {
783 /* Truncated via TCP? Somebody must be fucking with us */
784 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
785 return;
786 }
787
788 if (DNS_PACKET_ID(p) != t->id) {
789 /* Not the reply to our query? Somebody must be fucking with us */
790 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
791 return;
792 }
793 }
794
795 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
796
797 switch (t->scope->protocol) {
798
799 case DNS_PROTOCOL_DNS:
800 assert(t->server);
801
802 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
803
804 /* Request failed, immediately try again with reduced features */
805 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
806
807 dns_server_packet_failed(t->server, t->current_feature_level);
808 dns_transaction_retry(t);
809 return;
810 } else if (DNS_PACKET_TC(p))
811 dns_server_packet_truncated(t->server, t->current_feature_level);
812
813 break;
814
815 case DNS_PROTOCOL_LLMNR:
816 case DNS_PROTOCOL_MDNS:
817 dns_scope_packet_received(t->scope, ts - t->start_usec);
818 break;
819
820 default:
821 assert_not_reached("Invalid DNS protocol.");
822 }
823
824 if (DNS_PACKET_TC(p)) {
825
826 /* Truncated packets for mDNS are not allowed. Give up immediately. */
827 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
828 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
829 return;
830 }
831
832 log_debug("Reply truncated, retrying via TCP.");
833
834 /* Response was truncated, let's try again with good old TCP */
835 r = dns_transaction_open_tcp(t);
836 if (r == -ESRCH) {
837 /* No servers found? Damn! */
838 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
839 return;
840 }
841 if (r == -EOPNOTSUPP) {
842 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
843 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
844 return;
845 }
846 if (r < 0) {
847 /* On LLMNR, if we cannot connect to the host,
848 * we immediately give up */
849 if (t->scope->protocol != DNS_PROTOCOL_DNS) {
850 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
851 return;
852 }
853
854 /* On DNS, couldn't send? Try immediately again, with a new server */
855 dns_transaction_retry(t);
856 }
857
858 return;
859 }
860
861 /* After the superficial checks, actually parse the message. */
862 r = dns_packet_extract(p);
863 if (r < 0) {
864 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
865 return;
866 }
867
868 /* Report that the OPT RR was missing */
869 if (t->server) {
870 if (!p->opt)
871 dns_server_packet_bad_opt(t->server, t->current_feature_level);
872
873 dns_server_packet_received(t->server, p->ipproto, t->current_feature_level, ts - t->start_usec, p->size);
874 }
875
876 /* See if we know things we didn't know before that indicate we better restart the lookup immediately. */
877 r = dns_transaction_maybe_restart(t);
878 if (r < 0) {
879 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
880 return;
881 }
882 if (r > 0) /* Transaction got restarted... */
883 return;
884
885 if (IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR)) {
886
887 /* Only consider responses with equivalent query section to the request */
888 r = dns_packet_is_reply_for(p, t->key);
889 if (r < 0) {
890 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
891 return;
892 }
893 if (r == 0) {
894 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
895 return;
896 }
897
898 /* Install the answer as answer to the transaction */
899 dns_answer_unref(t->answer);
900 t->answer = dns_answer_ref(p->answer);
901 t->answer_rcode = DNS_PACKET_RCODE(p);
902 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
903 t->answer_authenticated = false;
904
905 /* Block GC while starting requests for additional DNSSEC RRs */
906 t->block_gc++;
907 r = dns_transaction_request_dnssec_keys(t);
908 t->block_gc--;
909
910 /* Maybe the transaction is ready for GC'ing now? If so, free it and return. */
911 if (!dns_transaction_gc(t))
912 return;
913
914 /* Requesting additional keys might have resulted in
915 * this transaction to fail, since the auxiliary
916 * request failed for some reason. If so, we are not
917 * in pending state anymore, and we should exit
918 * quickly. */
919 if (t->state != DNS_TRANSACTION_PENDING)
920 return;
921 if (r < 0) {
922 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
923 return;
924 }
925 if (r > 0) {
926 /* There are DNSSEC transactions pending now. Update the state accordingly. */
927 t->state = DNS_TRANSACTION_VALIDATING;
928 dns_transaction_close_connection(t);
929 dns_transaction_stop_timeout(t);
930 return;
931 }
932 }
933
934 dns_transaction_process_dnssec(t);
935 }
936
937 static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
938 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
939 DnsTransaction *t = userdata;
940 int r;
941
942 assert(t);
943 assert(t->scope);
944
945 r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
946 if (ERRNO_IS_DISCONNECT(-r)) {
947 usec_t usec;
948
949 /* UDP connection failure get reported via ICMP and then are possible delivered to us on the next
950 * recvmsg(). Treat this like a lost packet. */
951
952 log_debug_errno(r, "Connection failure for DNS UDP packet: %m");
953 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
954 dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level, usec - t->start_usec);
955
956 dns_transaction_retry(t);
957 return 0;
958 }
959 if (r < 0) {
960 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
961 return 0;
962 }
963
964 r = dns_packet_validate_reply(p);
965 if (r < 0) {
966 log_debug_errno(r, "Received invalid DNS packet as response, ignoring: %m");
967 return 0;
968 }
969 if (r == 0) {
970 log_debug("Received inappropriate DNS packet as response, ignoring.");
971 return 0;
972 }
973
974 if (DNS_PACKET_ID(p) != t->id) {
975 log_debug("Received packet with incorrect transaction ID, ignoring.");
976 return 0;
977 }
978
979 dns_transaction_process_reply(t, p);
980 return 0;
981 }
982
983 static int dns_transaction_emit_udp(DnsTransaction *t) {
984 int r;
985
986 assert(t);
987
988 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
989
990 r = dns_transaction_pick_server(t);
991 if (r < 0)
992 return r;
993
994 if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_UDP)
995 return -EAGAIN;
996
997 if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
998 return -EOPNOTSUPP;
999
1000 if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */
1001 int fd;
1002
1003 dns_transaction_close_connection(t);
1004
1005 fd = dns_scope_socket_udp(t->scope, t->server, 53);
1006 if (fd < 0)
1007 return fd;
1008
1009 r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
1010 if (r < 0) {
1011 safe_close(fd);
1012 return r;
1013 }
1014
1015 (void) sd_event_source_set_description(t->dns_udp_event_source, "dns-transaction-udp");
1016 t->dns_udp_fd = fd;
1017 }
1018
1019 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
1020 if (r < 0)
1021 return r;
1022 } else
1023 dns_transaction_close_connection(t);
1024
1025 r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->sent);
1026 if (r < 0)
1027 return r;
1028
1029 dns_transaction_reset_answer(t);
1030
1031 return 0;
1032 }
1033
1034 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
1035 DnsTransaction *t = userdata;
1036
1037 assert(s);
1038 assert(t);
1039
1040 if (!t->initial_jitter_scheduled || t->initial_jitter_elapsed) {
1041 /* Timeout reached? Increase the timeout for the server used */
1042 switch (t->scope->protocol) {
1043
1044 case DNS_PROTOCOL_DNS:
1045 assert(t->server);
1046 dns_server_packet_lost(t->server, t->stream ? IPPROTO_TCP : IPPROTO_UDP, t->current_feature_level, usec - t->start_usec);
1047 break;
1048
1049 case DNS_PROTOCOL_LLMNR:
1050 case DNS_PROTOCOL_MDNS:
1051 dns_scope_packet_lost(t->scope, usec - t->start_usec);
1052 break;
1053
1054 default:
1055 assert_not_reached("Invalid DNS protocol.");
1056 }
1057
1058 if (t->initial_jitter_scheduled)
1059 t->initial_jitter_elapsed = true;
1060 }
1061
1062 log_debug("Timeout reached on transaction %" PRIu16 ".", t->id);
1063
1064 dns_transaction_retry(t);
1065 return 0;
1066 }
1067
1068 static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
1069 assert(t);
1070 assert(t->scope);
1071
1072 switch (t->scope->protocol) {
1073
1074 case DNS_PROTOCOL_DNS:
1075 assert(t->server);
1076 return t->server->resend_timeout;
1077
1078 case DNS_PROTOCOL_MDNS:
1079 assert(t->n_attempts > 0);
1080 return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
1081
1082 case DNS_PROTOCOL_LLMNR:
1083 return t->scope->resend_timeout;
1084
1085 default:
1086 assert_not_reached("Invalid DNS protocol.");
1087 }
1088 }
1089
1090 static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
1091 int r;
1092
1093 assert(t);
1094
1095 dns_transaction_stop_timeout(t);
1096
1097 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
1098 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1099 return 0;
1100 }
1101
1102 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && t->tried_stream) {
1103 /* If we already tried via a stream, then we don't
1104 * retry on LLMNR. See RFC 4795, Section 2.7. */
1105 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1106 return 0;
1107 }
1108
1109 t->n_attempts++;
1110 t->start_usec = ts;
1111
1112 dns_transaction_reset_answer(t);
1113 dns_transaction_flush_dnssec_transactions(t);
1114
1115 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
1116 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
1117 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, t->key, &t->answer);
1118 if (r < 0)
1119 return r;
1120 if (r > 0) {
1121 t->answer_rcode = DNS_RCODE_SUCCESS;
1122 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
1123 t->answer_authenticated = true;
1124 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1125 return 0;
1126 }
1127
1128 if (dns_name_is_root(DNS_RESOURCE_KEY_NAME(t->key)) &&
1129 t->key->type == DNS_TYPE_DS) {
1130
1131 /* Hmm, this is a request for the root DS? A
1132 * DS RR doesn't exist in the root zone, and
1133 * if our trust anchor didn't know it either,
1134 * this means we cannot do any DNSSEC logic
1135 * anymore. */
1136
1137 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
1138 /* We are in downgrade mode. In this
1139 * case, synthesize an unsigned empty
1140 * response, so that the any lookup
1141 * depending on this one can continue
1142 * assuming there was no DS, and hence
1143 * the root zone was unsigned. */
1144
1145 t->answer_rcode = DNS_RCODE_SUCCESS;
1146 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
1147 t->answer_authenticated = false;
1148 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1149 } else
1150 /* If we are not in downgrade mode,
1151 * then fail the lookup, because we
1152 * cannot reasonably answer it. There
1153 * might be DS RRs, but we don't know
1154 * them, and the DNS server won't tell
1155 * them to us (and even if it would,
1156 * we couldn't validate it and trust
1157 * it). */
1158 dns_transaction_complete(t, DNS_TRANSACTION_NO_TRUST_ANCHOR);
1159
1160 return 0;
1161 }
1162 }
1163
1164 /* Check the zone, but only if this transaction is not used
1165 * for probing or verifying a zone item. */
1166 if (set_isempty(t->notify_zone_items)) {
1167
1168 r = dns_zone_lookup(&t->scope->zone, t->key, &t->answer, NULL, NULL);
1169 if (r < 0)
1170 return r;
1171 if (r > 0) {
1172 t->answer_rcode = DNS_RCODE_SUCCESS;
1173 t->answer_source = DNS_TRANSACTION_ZONE;
1174 t->answer_authenticated = true;
1175 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1176 return 0;
1177 }
1178 }
1179
1180 /* Check the cache, but only if this transaction is not used
1181 * for probing or verifying a zone item. */
1182 if (set_isempty(t->notify_zone_items)) {
1183
1184 /* Before trying the cache, let's make sure we figured out a
1185 * server to use. Should this cause a change of server this
1186 * might flush the cache. */
1187 dns_scope_get_dns_server(t->scope);
1188
1189 /* Let's then prune all outdated entries */
1190 dns_cache_prune(&t->scope->cache);
1191
1192 r = dns_cache_lookup(&t->scope->cache, t->key, &t->answer_rcode, &t->answer, &t->answer_authenticated);
1193 if (r < 0)
1194 return r;
1195 if (r > 0) {
1196 t->answer_source = DNS_TRANSACTION_CACHE;
1197 if (t->answer_rcode == DNS_RCODE_SUCCESS)
1198 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1199 else
1200 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
1201 return 0;
1202 }
1203 }
1204
1205 return 1;
1206 }
1207
1208 static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
1209
1210 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1211 bool add_known_answers = false;
1212 DnsTransaction *other;
1213 unsigned qdcount;
1214 usec_t ts;
1215 int r;
1216
1217 assert(t);
1218 assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
1219
1220 /* Discard any previously prepared packet, so we can start over and coalesce again */
1221 t->sent = dns_packet_unref(t->sent);
1222
1223 r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
1224 if (r < 0)
1225 return r;
1226
1227 r = dns_packet_append_key(p, t->key, NULL);
1228 if (r < 0)
1229 return r;
1230
1231 qdcount = 1;
1232
1233 if (dns_key_is_shared(t->key))
1234 add_known_answers = true;
1235
1236 /*
1237 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
1238 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
1239 * in our current scope, and see whether their timing contraints allow them to be sent.
1240 */
1241
1242 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
1243
1244 LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
1245
1246 /* Skip ourselves */
1247 if (other == t)
1248 continue;
1249
1250 if (other->state != DNS_TRANSACTION_PENDING)
1251 continue;
1252
1253 if (other->next_attempt_after > ts)
1254 continue;
1255
1256 if (qdcount >= UINT16_MAX)
1257 break;
1258
1259 r = dns_packet_append_key(p, other->key, NULL);
1260
1261 /*
1262 * If we can't stuff more questions into the packet, just give up.
1263 * One of the 'other' transactions will fire later and take care of the rest.
1264 */
1265 if (r == -EMSGSIZE)
1266 break;
1267
1268 if (r < 0)
1269 return r;
1270
1271 r = dns_transaction_prepare(other, ts);
1272 if (r <= 0)
1273 continue;
1274
1275 ts += transaction_get_resend_timeout(other);
1276
1277 r = sd_event_add_time(
1278 other->scope->manager->event,
1279 &other->timeout_event_source,
1280 clock_boottime_or_monotonic(),
1281 ts, 0,
1282 on_transaction_timeout, other);
1283 if (r < 0)
1284 return r;
1285
1286 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1287
1288 other->state = DNS_TRANSACTION_PENDING;
1289 other->next_attempt_after = ts;
1290
1291 qdcount ++;
1292
1293 if (dns_key_is_shared(other->key))
1294 add_known_answers = true;
1295 }
1296
1297 DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
1298
1299 /* Append known answer section if we're asking for any shared record */
1300 if (add_known_answers) {
1301 r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
1302 if (r < 0)
1303 return r;
1304 }
1305
1306 t->sent = p;
1307 p = NULL;
1308
1309 return 0;
1310 }
1311
1312 static int dns_transaction_make_packet(DnsTransaction *t) {
1313 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1314 int r;
1315
1316 assert(t);
1317
1318 if (t->scope->protocol == DNS_PROTOCOL_MDNS)
1319 return dns_transaction_make_packet_mdns(t);
1320
1321 if (t->sent)
1322 return 0;
1323
1324 r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode != DNSSEC_NO);
1325 if (r < 0)
1326 return r;
1327
1328 r = dns_scope_good_key(t->scope, t->key);
1329 if (r < 0)
1330 return r;
1331 if (r == 0)
1332 return -EDOM;
1333
1334 r = dns_packet_append_key(p, t->key, NULL);
1335 if (r < 0)
1336 return r;
1337
1338 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
1339 DNS_PACKET_HEADER(p)->id = t->id;
1340
1341 t->sent = p;
1342 p = NULL;
1343
1344 return 0;
1345 }
1346
1347 int dns_transaction_go(DnsTransaction *t) {
1348 usec_t ts;
1349 int r;
1350
1351 assert(t);
1352
1353 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
1354
1355 r = dns_transaction_prepare(t, ts);
1356 if (r <= 0)
1357 return r;
1358
1359 log_debug("Excercising transaction %" PRIu16 " for <%s> on scope %s on %s/%s.",
1360 t->id,
1361 dns_transaction_key_string(t),
1362 dns_protocol_to_string(t->scope->protocol),
1363 t->scope->link ? t->scope->link->name : "*",
1364 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
1365
1366 if (!t->initial_jitter_scheduled &&
1367 (t->scope->protocol == DNS_PROTOCOL_LLMNR ||
1368 t->scope->protocol == DNS_PROTOCOL_MDNS)) {
1369 usec_t jitter, accuracy;
1370
1371 /* RFC 4795 Section 2.7 suggests all queries should be
1372 * delayed by a random time from 0 to JITTER_INTERVAL. */
1373
1374 t->initial_jitter_scheduled = true;
1375
1376 random_bytes(&jitter, sizeof(jitter));
1377
1378 switch (t->scope->protocol) {
1379
1380 case DNS_PROTOCOL_LLMNR:
1381 jitter %= LLMNR_JITTER_INTERVAL_USEC;
1382 accuracy = LLMNR_JITTER_INTERVAL_USEC;
1383 break;
1384
1385 case DNS_PROTOCOL_MDNS:
1386 jitter %= MDNS_JITTER_RANGE_USEC;
1387 jitter += MDNS_JITTER_MIN_USEC;
1388 accuracy = MDNS_JITTER_RANGE_USEC;
1389 break;
1390 default:
1391 assert_not_reached("bad protocol");
1392 }
1393
1394 r = sd_event_add_time(
1395 t->scope->manager->event,
1396 &t->timeout_event_source,
1397 clock_boottime_or_monotonic(),
1398 ts + jitter, accuracy,
1399 on_transaction_timeout, t);
1400 if (r < 0)
1401 return r;
1402
1403 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1404
1405 t->n_attempts = 0;
1406 t->next_attempt_after = ts;
1407 t->state = DNS_TRANSACTION_PENDING;
1408
1409 log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
1410 return 0;
1411 }
1412
1413 /* Otherwise, we need to ask the network */
1414 r = dns_transaction_make_packet(t);
1415 if (r == -EDOM) {
1416 /* Not the right request to make on this network?
1417 * (i.e. an A request made on IPv6 or an AAAA request
1418 * made on IPv4, on LLMNR or mDNS.) */
1419 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1420 return 0;
1421 }
1422 if (r < 0)
1423 return r;
1424
1425 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
1426 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "in-addr.arpa") > 0 ||
1427 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "ip6.arpa") > 0)) {
1428
1429 /* RFC 4795, Section 2.4. says reverse lookups shall
1430 * always be made via TCP on LLMNR */
1431 r = dns_transaction_open_tcp(t);
1432 } else {
1433 /* Try via UDP, and if that fails due to large size or lack of
1434 * support try via TCP */
1435 r = dns_transaction_emit_udp(t);
1436 if (r == -EMSGSIZE)
1437 log_debug("Sending query via TCP since it is too large.");
1438 if (r == -EAGAIN)
1439 log_debug("Sending query via TCP since server doesn't support UDP.");
1440 if (r == -EMSGSIZE || r == -EAGAIN)
1441 r = dns_transaction_open_tcp(t);
1442 }
1443
1444 if (r == -ESRCH) {
1445 /* No servers to send this to? */
1446 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1447 return 0;
1448 }
1449 if (r == -EOPNOTSUPP) {
1450 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
1451 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
1452 return 0;
1453 }
1454 if (r < 0) {
1455 if (t->scope->protocol != DNS_PROTOCOL_DNS) {
1456 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
1457 return 0;
1458 }
1459
1460 /* Couldn't send? Try immediately again, with a new server */
1461 dns_scope_next_dns_server(t->scope);
1462
1463 return dns_transaction_go(t);
1464 }
1465
1466 ts += transaction_get_resend_timeout(t);
1467
1468 r = sd_event_add_time(
1469 t->scope->manager->event,
1470 &t->timeout_event_source,
1471 clock_boottime_or_monotonic(),
1472 ts, 0,
1473 on_transaction_timeout, t);
1474 if (r < 0)
1475 return r;
1476
1477 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1478
1479 t->state = DNS_TRANSACTION_PENDING;
1480 t->next_attempt_after = ts;
1481
1482 return 1;
1483 }
1484
1485 static int dns_transaction_find_cyclic(DnsTransaction *t, DnsTransaction *aux) {
1486 DnsTransaction *n;
1487 Iterator i;
1488 int r;
1489
1490 assert(t);
1491 assert(aux);
1492
1493 /* Try to find cyclic dependencies between transaction objects */
1494
1495 if (t == aux)
1496 return 1;
1497
1498 SET_FOREACH(n, aux->dnssec_transactions, i) {
1499 r = dns_transaction_find_cyclic(t, n);
1500 if (r != 0)
1501 return r;
1502 }
1503
1504 return 0;
1505 }
1506
1507 static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
1508 DnsTransaction *aux;
1509 int r;
1510
1511 assert(t);
1512 assert(ret);
1513 assert(key);
1514
1515 aux = dns_scope_find_transaction(t->scope, key, true);
1516 if (!aux) {
1517 r = dns_transaction_new(&aux, t->scope, key);
1518 if (r < 0)
1519 return r;
1520 } else {
1521 if (set_contains(t->dnssec_transactions, aux)) {
1522 *ret = aux;
1523 return 0;
1524 }
1525
1526 r = dns_transaction_find_cyclic(t, aux);
1527 if (r < 0)
1528 return r;
1529 if (r > 0) {
1530 log_debug("Detected potential cyclic dependency, refusing to add transaction %" PRIu16 " (%s) as dependency for %" PRIu16 " (%s).",
1531 aux->id,
1532 strna(dns_transaction_key_string(aux)),
1533 t->id,
1534 strna(dns_transaction_key_string(t)));
1535 return -ELOOP;
1536 }
1537 }
1538
1539 r = set_ensure_allocated(&t->dnssec_transactions, NULL);
1540 if (r < 0)
1541 goto gc;
1542
1543 r = set_ensure_allocated(&aux->notify_transactions, NULL);
1544 if (r < 0)
1545 goto gc;
1546
1547 r = set_put(t->dnssec_transactions, aux);
1548 if (r < 0)
1549 goto gc;
1550
1551 r = set_put(aux->notify_transactions, t);
1552 if (r < 0) {
1553 (void) set_remove(t->dnssec_transactions, aux);
1554 goto gc;
1555 }
1556
1557 *ret = aux;
1558 return 1;
1559
1560 gc:
1561 dns_transaction_gc(aux);
1562 return r;
1563 }
1564
1565 static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
1566 _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL;
1567 DnsTransaction *aux;
1568 int r;
1569
1570 assert(t);
1571 assert(key);
1572
1573 /* Try to get the data from the trust anchor */
1574 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, key, &a);
1575 if (r < 0)
1576 return r;
1577 if (r > 0) {
1578 r = dns_answer_extend(&t->validated_keys, a);
1579 if (r < 0)
1580 return r;
1581
1582 return 0;
1583 }
1584
1585 /* This didn't work, ask for it via the network/cache then. */
1586 r = dns_transaction_add_dnssec_transaction(t, key, &aux);
1587 if (r == -ELOOP) /* This would result in a cyclic dependency */
1588 return 0;
1589 if (r < 0)
1590 return r;
1591
1592 if (aux->state == DNS_TRANSACTION_NULL) {
1593 r = dns_transaction_go(aux);
1594 if (r < 0)
1595 return r;
1596 }
1597
1598 return 1;
1599 }
1600
1601 static int dns_transaction_has_positive_answer(DnsTransaction *t, DnsAnswerFlags *flags) {
1602 int r;
1603
1604 assert(t);
1605
1606 /* Checks whether the answer is positive, i.e. either a direct
1607 * answer to the question, or a CNAME/DNAME for it */
1608
1609 r = dns_answer_match_key(t->answer, t->key, flags);
1610 if (r != 0)
1611 return r;
1612
1613 r = dns_answer_find_cname_or_dname(t->answer, t->key, NULL, flags);
1614 if (r != 0)
1615 return r;
1616
1617 return false;
1618 }
1619
1620 static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const char *name) {
1621 int r;
1622
1623 assert(t);
1624
1625 /* Check whether the specified name is in the the NTA
1626 * database, either in the global one, or the link-local
1627 * one. */
1628
1629 r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, name);
1630 if (r != 0)
1631 return r;
1632
1633 if (!t->scope->link)
1634 return 0;
1635
1636 return set_contains(t->scope->link->dnssec_negative_trust_anchors, name);
1637 }
1638
1639 static int dns_transaction_has_unsigned_negative_answer(DnsTransaction *t) {
1640 int r;
1641
1642 assert(t);
1643
1644 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
1645 * RRs to prove it */
1646
1647 r = dns_transaction_has_positive_answer(t, NULL);
1648 if (r < 0)
1649 return r;
1650 if (r > 0)
1651 return false;
1652
1653 /* Is this key explicitly listed as a negative trust anchor?
1654 * If so, it's nothing we need to care about */
1655 r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(t->key));
1656 if (r < 0)
1657 return r;
1658 if (r > 0)
1659 return false;
1660
1661 /* The answer does not contain any RRs that match to the
1662 * question. If so, let's see if there are any NSEC/NSEC3 RRs
1663 * included. If not, the answer is unsigned. */
1664
1665 r = dns_answer_contains_nsec_or_nsec3(t->answer);
1666 if (r < 0)
1667 return r;
1668 if (r > 0)
1669 return false;
1670
1671 return true;
1672 }
1673
1674 static int dns_transaction_is_primary_response(DnsTransaction *t, DnsResourceRecord *rr) {
1675 int r;
1676
1677 assert(t);
1678 assert(rr);
1679
1680 /* Check if the specified RR is the "primary" response,
1681 * i.e. either matches the question precisely or is a
1682 * CNAME/DNAME for it, or is any kind of NSEC/NSEC3 RR */
1683
1684 r = dns_resource_key_match_rr(t->key, rr, NULL);
1685 if (r != 0)
1686 return r;
1687
1688 r = dns_resource_key_match_cname_or_dname(t->key, rr->key, NULL);
1689 if (r != 0)
1690 return r;
1691
1692 if (rr->key->type == DNS_TYPE_NSEC3) {
1693 const char *p;
1694
1695 p = DNS_RESOURCE_KEY_NAME(rr->key);
1696 r = dns_name_parent(&p);
1697 if (r < 0)
1698 return r;
1699 if (r > 0) {
1700 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), p);
1701 if (r < 0)
1702 return r;
1703 if (r > 0)
1704 return true;
1705 }
1706 }
1707
1708 return rr->key->type == DNS_TYPE_NSEC;
1709 }
1710
1711 static bool dns_transaction_dnssec_supported(DnsTransaction *t) {
1712 assert(t);
1713
1714 /* Checks whether our transaction's DNS server is assumed to be compatible with DNSSEC. Returns false as soon
1715 * as we changed our mind about a server, and now believe it is incompatible with DNSSEC. */
1716
1717 if (t->scope->protocol != DNS_PROTOCOL_DNS)
1718 return false;
1719
1720 /* If we have picked no server, then we are working from the cache or some other source, and DNSSEC might well
1721 * be supported, hence return true. */
1722 if (!t->server)
1723 return true;
1724
1725 if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_DO)
1726 return false;
1727
1728 return dns_server_dnssec_supported(t->server);
1729 }
1730
1731 static bool dns_transaction_dnssec_supported_full(DnsTransaction *t) {
1732 DnsTransaction *dt;
1733 Iterator i;
1734
1735 assert(t);
1736
1737 /* Checks whether our transaction our any of the auxiliary transactions couldn't do DNSSEC. */
1738
1739 if (!dns_transaction_dnssec_supported(t))
1740 return false;
1741
1742 SET_FOREACH(dt, t->dnssec_transactions, i)
1743 if (!dns_transaction_dnssec_supported(dt))
1744 return false;
1745
1746 return true;
1747 }
1748
1749 int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
1750 DnsResourceRecord *rr;
1751
1752 int r;
1753
1754 assert(t);
1755
1756 /*
1757 * Retrieve all auxiliary RRs for the answer we got, so that
1758 * we can verify signatures or prove that RRs are rightfully
1759 * unsigned. Specifically:
1760 *
1761 * - For RRSIG we get the matching DNSKEY
1762 * - For DNSKEY we get the matching DS
1763 * - For unsigned SOA/NS we get the matching DS
1764 * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
1765 * - For other unsigned RRs we get the matching SOA RR
1766 * - For SOA/NS/DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
1767 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
1768 */
1769
1770 if (t->scope->dnssec_mode == DNSSEC_NO)
1771 return 0;
1772 if (t->answer_source != DNS_TRANSACTION_NETWORK)
1773 return 0; /* We only need to validate stuff from the network */
1774 if (!dns_transaction_dnssec_supported(t))
1775 return 0; /* If we can't do DNSSEC anyway there's no point in geting the auxiliary RRs */
1776
1777 DNS_ANSWER_FOREACH(rr, t->answer) {
1778
1779 if (dns_type_is_pseudo(rr->key->type))
1780 continue;
1781
1782 /* If this RR is in the negative trust anchor, we don't need to validate it. */
1783 r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key));
1784 if (r < 0)
1785 return r;
1786 if (r > 0)
1787 continue;
1788
1789 switch (rr->key->type) {
1790
1791 case DNS_TYPE_RRSIG: {
1792 /* For each RRSIG we request the matching DNSKEY */
1793 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
1794
1795 /* If this RRSIG is about a DNSKEY RR and the
1796 * signer is the same as the owner, then we
1797 * already have the DNSKEY, and we don't have
1798 * to look for more. */
1799 if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
1800 r = dns_name_equal(rr->rrsig.signer, DNS_RESOURCE_KEY_NAME(rr->key));
1801 if (r < 0)
1802 return r;
1803 if (r > 0)
1804 continue;
1805 }
1806
1807 /* If the signer is not a parent of our
1808 * original query, then this is about an
1809 * auxiliary RRset, but not anything we asked
1810 * for. In this case we aren't interested,
1811 * because we don't want to request additional
1812 * RRs for stuff we didn't really ask for, and
1813 * also to avoid request loops, where
1814 * additional RRs from one transaction result
1815 * in another transaction whose additonal RRs
1816 * point back to the original transaction, and
1817 * we deadlock. */
1818 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), rr->rrsig.signer);
1819 if (r < 0)
1820 return r;
1821 if (r == 0)
1822 continue;
1823
1824 dnskey = dns_resource_key_new(rr->key->class, DNS_TYPE_DNSKEY, rr->rrsig.signer);
1825 if (!dnskey)
1826 return -ENOMEM;
1827
1828 log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").", t->id, DNS_RESOURCE_KEY_NAME(rr->key), rr->rrsig.key_tag);
1829 r = dns_transaction_request_dnssec_rr(t, dnskey);
1830 if (r < 0)
1831 return r;
1832 break;
1833 }
1834
1835 case DNS_TYPE_DNSKEY: {
1836 /* For each DNSKEY we request the matching DS */
1837 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1838
1839 /* If the DNSKEY we are looking at is not for
1840 * zone we are interested in, nor any of its
1841 * parents, we aren't interested, and don't
1842 * request it. After all, we don't want to end
1843 * up in request loops, and want to keep
1844 * additional traffic down. */
1845
1846 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), DNS_RESOURCE_KEY_NAME(rr->key));
1847 if (r < 0)
1848 return r;
1849 if (r == 0)
1850 continue;
1851
1852 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(rr->key));
1853 if (!ds)
1854 return -ENOMEM;
1855
1856 log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").", t->id, DNS_RESOURCE_KEY_NAME(rr->key), dnssec_keytag(rr, false));
1857 r = dns_transaction_request_dnssec_rr(t, ds);
1858 if (r < 0)
1859 return r;
1860
1861 break;
1862 }
1863
1864 case DNS_TYPE_SOA:
1865 case DNS_TYPE_NS: {
1866 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1867
1868 /* For an unsigned SOA or NS, try to acquire
1869 * the matching DS RR, as we are at a zone cut
1870 * then, and whether a DS exists tells us
1871 * whether the zone is signed. Do so only if
1872 * this RR matches our original question,
1873 * however. */
1874
1875 r = dns_resource_key_match_rr(t->key, rr, NULL);
1876 if (r < 0)
1877 return r;
1878 if (r == 0)
1879 continue;
1880
1881 r = dnssec_has_rrsig(t->answer, rr->key);
1882 if (r < 0)
1883 return r;
1884 if (r > 0)
1885 continue;
1886
1887 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(rr->key));
1888 if (!ds)
1889 return -ENOMEM;
1890
1891 log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
1892 r = dns_transaction_request_dnssec_rr(t, ds);
1893 if (r < 0)
1894 return r;
1895
1896 break;
1897 }
1898
1899 case DNS_TYPE_DS:
1900 case DNS_TYPE_CNAME:
1901 case DNS_TYPE_DNAME: {
1902 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1903 const char *name;
1904
1905 /* CNAMEs and DNAMEs cannot be located at a
1906 * zone apex, hence ask for the parent SOA for
1907 * unsigned CNAME/DNAME RRs, maybe that's the
1908 * apex. But do all that only if this is
1909 * actually a response to our original
1910 * question.
1911 *
1912 * Similar for DS RRs, which are signed when
1913 * the parent SOA is signed. */
1914
1915 r = dns_transaction_is_primary_response(t, rr);
1916 if (r < 0)
1917 return r;
1918 if (r == 0)
1919 continue;
1920
1921 r = dnssec_has_rrsig(t->answer, rr->key);
1922 if (r < 0)
1923 return r;
1924 if (r > 0)
1925 continue;
1926
1927 r = dns_answer_has_dname_for_cname(t->answer, rr);
1928 if (r < 0)
1929 return r;
1930 if (r > 0)
1931 continue;
1932
1933 name = DNS_RESOURCE_KEY_NAME(rr->key);
1934 r = dns_name_parent(&name);
1935 if (r < 0)
1936 return r;
1937 if (r == 0)
1938 continue;
1939
1940 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
1941 if (!soa)
1942 return -ENOMEM;
1943
1944 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
1945 r = dns_transaction_request_dnssec_rr(t, soa);
1946 if (r < 0)
1947 return r;
1948
1949 break;
1950 }
1951
1952 default: {
1953 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1954
1955 /* For other unsigned RRsets (including
1956 * NSEC/NSEC3!), look for proof the zone is
1957 * unsigned, by requesting the SOA RR of the
1958 * zone. However, do so only if they are
1959 * directly relevant to our original
1960 * question. */
1961
1962 r = dns_transaction_is_primary_response(t, rr);
1963 if (r < 0)
1964 return r;
1965 if (r == 0)
1966 continue;
1967
1968 r = dnssec_has_rrsig(t->answer, rr->key);
1969 if (r < 0)
1970 return r;
1971 if (r > 0)
1972 continue;
1973
1974 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, DNS_RESOURCE_KEY_NAME(rr->key));
1975 if (!soa)
1976 return -ENOMEM;
1977
1978 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).", t->id, DNS_RESOURCE_KEY_NAME(rr->key), dns_resource_record_to_string(rr));
1979 r = dns_transaction_request_dnssec_rr(t, soa);
1980 if (r < 0)
1981 return r;
1982 break;
1983 }}
1984 }
1985
1986 /* Above, we requested everything necessary to validate what
1987 * we got. Now, let's request what we need to validate what we
1988 * didn't get... */
1989
1990 r = dns_transaction_has_unsigned_negative_answer(t);
1991 if (r < 0)
1992 return r;
1993 if (r > 0) {
1994 const char *name;
1995
1996 name = DNS_RESOURCE_KEY_NAME(t->key);
1997
1998 /* If this was a SOA or NS request, then this
1999 * indicates that we are not at a zone apex, hence ask
2000 * the parent name instead. If this was a DS request,
2001 * then it's signed when the parent zone is signed,
2002 * hence ask the parent in that case, too. */
2003
2004 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
2005 r = dns_name_parent(&name);
2006 if (r < 0)
2007 return r;
2008 if (r > 0)
2009 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned empty SOA/NS/DS response).", t->id, DNS_RESOURCE_KEY_NAME(t->key));
2010 else
2011 name = NULL;
2012 } else
2013 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned empty non-SOA/NS/DS response).", t->id, DNS_RESOURCE_KEY_NAME(t->key));
2014
2015 if (name) {
2016 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2017
2018 soa = dns_resource_key_new(t->key->class, DNS_TYPE_SOA, name);
2019 if (!soa)
2020 return -ENOMEM;
2021
2022 r = dns_transaction_request_dnssec_rr(t, soa);
2023 if (r < 0)
2024 return r;
2025 }
2026 }
2027
2028 return dns_transaction_dnssec_is_live(t);
2029 }
2030
2031 void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source) {
2032 assert(t);
2033 assert(source);
2034
2035 /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
2036 we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
2037 the state is VALIDATING however, we should check if we are complete now. */
2038
2039 if (t->state == DNS_TRANSACTION_VALIDATING)
2040 dns_transaction_process_dnssec(t);
2041 }
2042
2043 static int dns_transaction_validate_dnskey_by_ds(DnsTransaction *t) {
2044 DnsResourceRecord *rr;
2045 int ifindex, r;
2046
2047 assert(t);
2048
2049 /* Add all DNSKEY RRs from the answer that are validated by DS
2050 * RRs from the list of validated keys to the list of
2051 * validated keys. */
2052
2053 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, t->answer) {
2054
2055 r = dnssec_verify_dnskey_by_ds_search(rr, t->validated_keys);
2056 if (r < 0)
2057 return r;
2058 if (r == 0)
2059 continue;
2060
2061 /* If so, the DNSKEY is validated too. */
2062 r = dns_answer_add_extend(&t->validated_keys, rr, ifindex, DNS_ANSWER_AUTHENTICATED);
2063 if (r < 0)
2064 return r;
2065 }
2066
2067 return 0;
2068 }
2069
2070 static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *rr) {
2071 int r;
2072
2073 assert(t);
2074 assert(rr);
2075
2076 /* Checks if the RR we are looking for must be signed with an
2077 * RRSIG. This is used for positive responses. */
2078
2079 if (t->scope->dnssec_mode == DNSSEC_NO)
2080 return false;
2081
2082 if (dns_type_is_pseudo(rr->key->type))
2083 return -EINVAL;
2084
2085 r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key));
2086 if (r < 0)
2087 return r;
2088 if (r > 0)
2089 return false;
2090
2091 switch (rr->key->type) {
2092
2093 case DNS_TYPE_RRSIG:
2094 /* RRSIGs are the signatures themselves, they need no signing. */
2095 return false;
2096
2097 case DNS_TYPE_SOA:
2098 case DNS_TYPE_NS: {
2099 DnsTransaction *dt;
2100 Iterator i;
2101
2102 /* For SOA or NS RRs we look for a matching DS transaction */
2103
2104 SET_FOREACH(dt, t->dnssec_transactions, i) {
2105
2106 if (dt->key->class != rr->key->class)
2107 continue;
2108 if (dt->key->type != DNS_TYPE_DS)
2109 continue;
2110
2111 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), DNS_RESOURCE_KEY_NAME(rr->key));
2112 if (r < 0)
2113 return r;
2114 if (r == 0)
2115 continue;
2116
2117 /* We found a DS transactions for the SOA/NS
2118 * RRs we are looking at. If it discovered signed DS
2119 * RRs, then we need to be signed, too. */
2120
2121 if (!dt->answer_authenticated)
2122 return false;
2123
2124 return dns_answer_match_key(dt->answer, dt->key, NULL);
2125 }
2126
2127 /* We found nothing that proves this is safe to leave
2128 * this unauthenticated, hence ask inist on
2129 * authentication. */
2130 return true;
2131 }
2132
2133 case DNS_TYPE_DS:
2134 case DNS_TYPE_CNAME:
2135 case DNS_TYPE_DNAME: {
2136 const char *parent = NULL;
2137 DnsTransaction *dt;
2138 Iterator i;
2139
2140 /*
2141 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
2142 *
2143 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
2144 */
2145
2146 SET_FOREACH(dt, t->dnssec_transactions, i) {
2147
2148 if (dt->key->class != rr->key->class)
2149 continue;
2150 if (dt->key->type != DNS_TYPE_SOA)
2151 continue;
2152
2153 if (!parent) {
2154 parent = DNS_RESOURCE_KEY_NAME(rr->key);
2155 r = dns_name_parent(&parent);
2156 if (r < 0)
2157 return r;
2158 if (r == 0) {
2159 if (rr->key->type == DNS_TYPE_DS)
2160 return true;
2161
2162 /* A CNAME/DNAME without a parent? That's sooo weird. */
2163 log_debug("Transaction %" PRIu16 " claims CNAME/DNAME at root. Refusing.", t->id);
2164 return -EBADMSG;
2165 }
2166 }
2167
2168 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), parent);
2169 if (r < 0)
2170 return r;
2171 if (r == 0)
2172 continue;
2173
2174 return t->answer_authenticated;
2175 }
2176
2177 return true;
2178 }
2179
2180 default: {
2181 DnsTransaction *dt;
2182 Iterator i;
2183
2184 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
2185
2186 SET_FOREACH(dt, t->dnssec_transactions, i) {
2187
2188 if (dt->key->class != rr->key->class)
2189 continue;
2190 if (dt->key->type != DNS_TYPE_SOA)
2191 continue;
2192
2193 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), DNS_RESOURCE_KEY_NAME(rr->key));
2194 if (r < 0)
2195 return r;
2196 if (r == 0)
2197 continue;
2198
2199 /* We found the transaction that was supposed to find
2200 * the SOA RR for us. It was successful, but found no
2201 * RR for us. This means we are not at a zone cut. In
2202 * this case, we require authentication if the SOA
2203 * lookup was authenticated too. */
2204 return t->answer_authenticated;
2205 }
2206
2207 return true;
2208 }}
2209 }
2210
2211 static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKey *key) {
2212 DnsTransaction *dt;
2213 const char *tld;
2214 Iterator i;
2215 int r;
2216
2217 /* If DNSSEC downgrade mode is on, checks whether the
2218 * specified RR is one level below a TLD we have proven not to
2219 * exist. In such a case we assume that this is a private
2220 * domain, and permit it.
2221 *
2222 * This detects cases like the Fritz!Box router networks. Each
2223 * Fritz!Box router serves a private "fritz.box" zone, in the
2224 * non-existing TLD "box". Requests for the "fritz.box" domain
2225 * are served by the router itself, while requests for the
2226 * "box" domain will result in NXDOMAIN.
2227 *
2228 * Note that this logic is unable to detect cases where a
2229 * router serves a private DNS zone directly under
2230 * non-existing TLD. In such a case we cannot detect whether
2231 * the TLD is supposed to exist or not, as all requests we
2232 * make for it will be answered by the router's zone, and not
2233 * by the root zone. */
2234
2235 assert(t);
2236
2237 if (t->scope->dnssec_mode != DNSSEC_ALLOW_DOWNGRADE)
2238 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
2239
2240 tld = DNS_RESOURCE_KEY_NAME(key);
2241 r = dns_name_parent(&tld);
2242 if (r < 0)
2243 return r;
2244 if (r == 0)
2245 return false; /* Already the root domain */
2246
2247 if (!dns_name_is_single_label(tld))
2248 return false;
2249
2250 SET_FOREACH(dt, t->dnssec_transactions, i) {
2251
2252 if (dt->key->class != key->class)
2253 continue;
2254
2255 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), tld);
2256 if (r < 0)
2257 return r;
2258 if (r == 0)
2259 continue;
2260
2261 /* We found an auxiliary lookup we did for the TLD. If
2262 * that returned with NXDOMAIN, we know the TLD didn't
2263 * exist, and hence this might be a private zone. */
2264
2265 return dt->answer_rcode == DNS_RCODE_NXDOMAIN;
2266 }
2267
2268 return false;
2269 }
2270
2271 static int dns_transaction_requires_nsec(DnsTransaction *t) {
2272 DnsTransaction *dt;
2273 const char *name;
2274 Iterator i;
2275 int r;
2276
2277 assert(t);
2278
2279 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
2280 * this negative reply */
2281
2282 if (t->scope->dnssec_mode == DNSSEC_NO)
2283 return false;
2284
2285 if (dns_type_is_pseudo(t->key->type))
2286 return -EINVAL;
2287
2288 r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(t->key));
2289 if (r < 0)
2290 return r;
2291 if (r > 0)
2292 return false;
2293
2294 r = dns_transaction_in_private_tld(t, t->key);
2295 if (r < 0)
2296 return r;
2297 if (r > 0) {
2298 /* The lookup is from a TLD that is proven not to
2299 * exist, and we are in downgrade mode, hence ignore
2300 * that fact that we didn't get any NSEC RRs.*/
2301
2302 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.", dns_transaction_key_string(t));
2303 return false;
2304 }
2305
2306 name = DNS_RESOURCE_KEY_NAME(t->key);
2307
2308 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
2309
2310 /* We got a negative reply for this SOA/NS lookup? If
2311 * so, then we are not at a zone apex, and thus should
2312 * look at the result of the parent SOA lookup.
2313 *
2314 * We got a negative reply for this DS lookup? DS RRs
2315 * are signed when their parent zone is signed, hence
2316 * also check the parent SOA in this case. */
2317
2318 r = dns_name_parent(&name);
2319 if (r < 0)
2320 return r;
2321 if (r == 0)
2322 return true;
2323 }
2324
2325 /* For all other RRs we check the SOA on the same level to see
2326 * if it's signed. */
2327
2328 SET_FOREACH(dt, t->dnssec_transactions, i) {
2329
2330 if (dt->key->class != t->key->class)
2331 continue;
2332 if (dt->key->type != DNS_TYPE_SOA)
2333 continue;
2334
2335 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), name);
2336 if (r < 0)
2337 return r;
2338 if (r == 0)
2339 continue;
2340
2341 return dt->answer_authenticated;
2342 }
2343
2344 /* If in doubt, require NSEC/NSEC3 */
2345 return true;
2346 }
2347
2348 static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRecord *rr) {
2349 DnsResourceRecord *rrsig;
2350 bool found = false;
2351 int r;
2352
2353 /* Checks whether any of the DNSKEYs used for the RRSIGs for
2354 * the specified RRset is authenticated (i.e. has a matching
2355 * DS RR). */
2356
2357 r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key));
2358 if (r < 0)
2359 return r;
2360 if (r > 0)
2361 return false;
2362
2363 DNS_ANSWER_FOREACH(rrsig, t->answer) {
2364 DnsTransaction *dt;
2365 Iterator i;
2366
2367 r = dnssec_key_match_rrsig(rr->key, rrsig);
2368 if (r < 0)
2369 return r;
2370 if (r == 0)
2371 continue;
2372
2373 SET_FOREACH(dt, t->dnssec_transactions, i) {
2374
2375 if (dt->key->class != rr->key->class)
2376 continue;
2377
2378 if (dt->key->type == DNS_TYPE_DNSKEY) {
2379
2380 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), rrsig->rrsig.signer);
2381 if (r < 0)
2382 return r;
2383 if (r == 0)
2384 continue;
2385
2386 /* OK, we found an auxiliary DNSKEY
2387 * lookup. If that lookup is
2388 * authenticated, report this. */
2389
2390 if (dt->answer_authenticated)
2391 return true;
2392
2393 found = true;
2394
2395 } else if (dt->key->type == DNS_TYPE_DS) {
2396
2397 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), rrsig->rrsig.signer);
2398 if (r < 0)
2399 return r;
2400 if (r == 0)
2401 continue;
2402
2403 /* OK, we found an auxiliary DS
2404 * lookup. If that lookup is
2405 * authenticated and non-zero, we
2406 * won! */
2407
2408 if (!dt->answer_authenticated)
2409 return false;
2410
2411 return dns_answer_match_key(dt->answer, dt->key, NULL);
2412 }
2413 }
2414 }
2415
2416 return found ? false : -ENXIO;
2417 }
2418
2419 static int dns_transaction_known_signed(DnsTransaction *t, DnsResourceRecord *rr) {
2420 assert(t);
2421 assert(rr);
2422
2423 /* We know that the root domain is signed, hence if it appears
2424 * not to be signed, there's a problem with the DNS server */
2425
2426 return rr->key->class == DNS_CLASS_IN &&
2427 dns_name_is_root(DNS_RESOURCE_KEY_NAME(rr->key));
2428 }
2429
2430 static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
2431 DnsResourceRecord *rr;
2432 int r;
2433
2434 assert(t);
2435
2436 /* Maybe warn the user that we encountered a revoked DNSKEY
2437 * for a key from our trust anchor. Note that we don't care
2438 * whether the DNSKEY can be authenticated or not. It's
2439 * sufficient if it is self-signed. */
2440
2441 DNS_ANSWER_FOREACH(rr, t->answer) {
2442 r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, rr, t->answer);
2443 if (r < 0)
2444 return r;
2445 }
2446
2447 return 0;
2448 }
2449
2450 static int dns_transaction_invalidate_revoked_keys(DnsTransaction *t) {
2451 bool changed;
2452 int r;
2453
2454 assert(t);
2455
2456 /* Removes all DNSKEY/DS objects from t->validated_keys that
2457 * our trust anchors database considers revoked. */
2458
2459 do {
2460 DnsResourceRecord *rr;
2461
2462 changed = false;
2463
2464 DNS_ANSWER_FOREACH(rr, t->validated_keys) {
2465 r = dns_trust_anchor_is_revoked(&t->scope->manager->trust_anchor, rr);
2466 if (r < 0)
2467 return r;
2468 if (r > 0) {
2469 r = dns_answer_remove_by_rr(&t->validated_keys, rr);
2470 if (r < 0)
2471 return r;
2472
2473 assert(r > 0);
2474 changed = true;
2475 break;
2476 }
2477 }
2478 } while (changed);
2479
2480 return 0;
2481 }
2482
2483 static int dns_transaction_copy_validated(DnsTransaction *t) {
2484 DnsTransaction *dt;
2485 Iterator i;
2486 int r;
2487
2488 assert(t);
2489
2490 /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
2491
2492 SET_FOREACH(dt, t->dnssec_transactions, i) {
2493
2494 if (DNS_TRANSACTION_IS_LIVE(dt->state))
2495 continue;
2496
2497 if (!dt->answer_authenticated)
2498 continue;
2499
2500 r = dns_answer_extend(&t->validated_keys, dt->answer);
2501 if (r < 0)
2502 return r;
2503 }
2504
2505 return 0;
2506 }
2507
2508 int dns_transaction_validate_dnssec(DnsTransaction *t) {
2509 _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
2510 enum {
2511 PHASE_DNSKEY, /* Phase #1, only validate DNSKEYs */
2512 PHASE_NSEC, /* Phase #2, only validate NSEC+NSEC3 */
2513 PHASE_ALL, /* Phase #3, validate everything else */
2514 } phase;
2515 DnsResourceRecord *rr;
2516 DnsAnswerFlags flags;
2517 int r;
2518
2519 assert(t);
2520
2521 /* We have now collected all DS and DNSKEY RRs in
2522 * t->validated_keys, let's see which RRs we can now
2523 * authenticate with that. */
2524
2525 if (t->scope->dnssec_mode == DNSSEC_NO)
2526 return 0;
2527
2528 /* Already validated */
2529 if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
2530 return 0;
2531
2532 /* Our own stuff needs no validation */
2533 if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
2534 t->answer_dnssec_result = DNSSEC_VALIDATED;
2535 t->answer_authenticated = true;
2536 return 0;
2537 }
2538
2539 /* Cached stuff is not affected by validation. */
2540 if (t->answer_source != DNS_TRANSACTION_NETWORK)
2541 return 0;
2542
2543 if (!dns_transaction_dnssec_supported_full(t)) {
2544 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
2545 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2546 log_debug("Not validating response, server lacks DNSSEC support.");
2547 return 0;
2548 }
2549
2550 log_debug("Validating response from transaction %" PRIu16 " (%s).", t->id, dns_transaction_key_string(t));
2551
2552 /* First, see if this response contains any revoked trust
2553 * anchors we care about */
2554 r = dns_transaction_check_revoked_trust_anchors(t);
2555 if (r < 0)
2556 return r;
2557
2558 /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
2559 r = dns_transaction_copy_validated(t);
2560 if (r < 0)
2561 return r;
2562
2563 /* Second, see if there are DNSKEYs we already know a
2564 * validated DS for. */
2565 r = dns_transaction_validate_dnskey_by_ds(t);
2566 if (r < 0)
2567 return r;
2568
2569 /* Fourth, remove all DNSKEY and DS RRs again that our trust
2570 * anchor says are revoked. After all we might have marked
2571 * some keys revoked above, but they might still be lingering
2572 * in our validated_keys list. */
2573 r = dns_transaction_invalidate_revoked_keys(t);
2574 if (r < 0)
2575 return r;
2576
2577 phase = PHASE_DNSKEY;
2578 for (;;) {
2579 bool changed = false, have_nsec = false;
2580
2581 DNS_ANSWER_FOREACH(rr, t->answer) {
2582 DnsResourceRecord *rrsig = NULL;
2583 DnssecResult result;
2584
2585 switch (rr->key->type) {
2586
2587 case DNS_TYPE_RRSIG:
2588 continue;
2589
2590 case DNS_TYPE_DNSKEY:
2591 /* We validate DNSKEYs only in the DNSKEY and ALL phases */
2592 if (phase == PHASE_NSEC)
2593 continue;
2594 break;
2595
2596 case DNS_TYPE_NSEC:
2597 case DNS_TYPE_NSEC3:
2598 have_nsec = true;
2599
2600 /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
2601 if (phase == PHASE_DNSKEY)
2602 continue;
2603
2604 break;
2605
2606 default:
2607 /* We validate all other RRs only in the ALL phases */
2608 if (phase != PHASE_ALL)
2609 continue;
2610
2611 break;
2612 }
2613
2614 r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result, &rrsig);
2615 if (r < 0)
2616 return r;
2617
2618 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
2619
2620 if (result == DNSSEC_VALIDATED) {
2621
2622 if (rr->key->type == DNS_TYPE_DNSKEY) {
2623 /* If we just validated a
2624 * DNSKEY RRset, then let's
2625 * add these keys to the set
2626 * of validated keys for this
2627 * transaction. */
2628
2629 r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
2630 if (r < 0)
2631 return r;
2632
2633 /* some of the DNSKEYs we just
2634 * added might already have
2635 * been revoked, remove them
2636 * again in that case. */
2637 r = dns_transaction_invalidate_revoked_keys(t);
2638 if (r < 0)
2639 return r;
2640 }
2641
2642 /* Add the validated RRset to the new
2643 * list of validated RRsets, and
2644 * remove it from the unvalidated
2645 * RRsets. We mark the RRset as
2646 * authenticated and cacheable. */
2647 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE);
2648 if (r < 0)
2649 return r;
2650
2651 t->scope->manager->n_dnssec_secure++;
2652
2653 /* Exit the loop, we dropped something from the answer, start from the beginning */
2654 changed = true;
2655 break;
2656 }
2657
2658 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
2659 * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet, we
2660 * cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
2661 if (phase != PHASE_ALL)
2662 continue;
2663
2664 if (result == DNSSEC_VALIDATED_WILDCARD) {
2665 bool authenticated = false;
2666 const char *source;
2667
2668 /* This RRset validated, but as a wildcard. This means we need to prove via NSEC/NSEC3
2669 * that no matching non-wildcard RR exists.*/
2670
2671 /* First step, determine the source of synthesis */
2672 r = dns_resource_record_source(rrsig, &source);
2673 if (r < 0)
2674 return r;
2675
2676 r = dnssec_test_positive_wildcard(
2677 validated,
2678 DNS_RESOURCE_KEY_NAME(rr->key),
2679 source,
2680 rrsig->rrsig.signer,
2681 &authenticated);
2682
2683 /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
2684 if (r == 0)
2685 result = DNSSEC_INVALID;
2686 else {
2687 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, authenticated ? (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE) : 0);
2688 if (r < 0)
2689 return r;
2690
2691 if (authenticated)
2692 t->scope->manager->n_dnssec_secure++;
2693 else
2694 t->scope->manager->n_dnssec_insecure++;
2695
2696 /* Exit the loop, we dropped something from the answer, start from the beginning */
2697 changed = true;
2698 break;
2699 }
2700 }
2701
2702 if (result == DNSSEC_NO_SIGNATURE) {
2703 r = dns_transaction_requires_rrsig(t, rr);
2704 if (r < 0)
2705 return r;
2706 if (r == 0) {
2707 /* Data does not require signing. In that case, just copy it over,
2708 * but remember that this is by no means authenticated.*/
2709 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2710 if (r < 0)
2711 return r;
2712
2713 t->scope->manager->n_dnssec_insecure++;
2714 changed = true;
2715 break;
2716 }
2717
2718 r = dns_transaction_known_signed(t, rr);
2719 if (r < 0)
2720 return r;
2721 if (r > 0) {
2722 /* This is an RR we know has to be signed. If it isn't this means
2723 * the server is not attaching RRSIGs, hence complain. */
2724
2725 dns_server_packet_rrsig_missing(t->server, t->current_feature_level);
2726
2727 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
2728
2729 /* Downgrading is OK? If so, just consider the information unsigned */
2730
2731 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2732 if (r < 0)
2733 return r;
2734
2735 t->scope->manager->n_dnssec_insecure++;
2736 changed = true;
2737 break;
2738 }
2739
2740 /* Otherwise, fail */
2741 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2742 return 0;
2743 }
2744
2745 r = dns_transaction_in_private_tld(t, rr->key);
2746 if (r < 0)
2747 return r;
2748 if (r > 0) {
2749 _cleanup_free_ char *s = NULL;
2750
2751 /* The data is from a TLD that is proven not to exist, and we are in downgrade
2752 * mode, hence ignore the fact that this was not signed. */
2753
2754 (void) dns_resource_key_to_string(rr->key, &s);
2755 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.", strna(s ? strstrip(s) : NULL));
2756
2757 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2758 if (r < 0)
2759 return r;
2760
2761 t->scope->manager->n_dnssec_insecure++;
2762 changed = true;
2763 break;
2764 }
2765 }
2766
2767 if (IN_SET(result,
2768 DNSSEC_MISSING_KEY,
2769 DNSSEC_SIGNATURE_EXPIRED,
2770 DNSSEC_UNSUPPORTED_ALGORITHM)) {
2771
2772 r = dns_transaction_dnskey_authenticated(t, rr);
2773 if (r < 0 && r != -ENXIO)
2774 return r;
2775 if (r == 0) {
2776 /* The DNSKEY transaction was not authenticated, this means there's
2777 * no DS for this, which means it's OK if no keys are found for this signature. */
2778
2779 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2780 if (r < 0)
2781 return r;
2782
2783 t->scope->manager->n_dnssec_insecure++;
2784 changed = true;
2785 break;
2786 }
2787 }
2788
2789 if (IN_SET(result,
2790 DNSSEC_INVALID,
2791 DNSSEC_SIGNATURE_EXPIRED,
2792 DNSSEC_NO_SIGNATURE))
2793 t->scope->manager->n_dnssec_bogus++;
2794 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
2795 t->scope->manager->n_dnssec_indeterminate++;
2796
2797 r = dns_transaction_is_primary_response(t, rr);
2798 if (r < 0)
2799 return r;
2800 if (r > 0) {
2801
2802 /* Look for a matching DNAME for this CNAME */
2803 r = dns_answer_has_dname_for_cname(t->answer, rr);
2804 if (r < 0)
2805 return r;
2806 if (r == 0) {
2807 /* Also look among the stuff we already validated */
2808 r = dns_answer_has_dname_for_cname(validated, rr);
2809 if (r < 0)
2810 return r;
2811 }
2812
2813 if (r == 0) {
2814 /* This is a primary response to our question, and it failed validation. That's
2815 * fatal. */
2816 t->answer_dnssec_result = result;
2817 return 0;
2818 }
2819
2820 /* This is a primary response, but we do have a DNAME RR in the RR that can replay this
2821 * CNAME, hence rely on that, and we can remove the CNAME in favour of it. */
2822 }
2823
2824 /* This is just some auxiliary data. Just remove the RRset and continue. */
2825 r = dns_answer_remove_by_key(&t->answer, rr->key);
2826 if (r < 0)
2827 return r;
2828
2829 /* Exit the loop, we dropped something from the answer, start from the beginning */
2830 changed = true;
2831 break;
2832 }
2833
2834 /* Restart the inner loop as long as we managed to achieve something */
2835 if (changed)
2836 continue;
2837
2838 if (phase == PHASE_DNSKEY && have_nsec) {
2839 /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
2840 phase = PHASE_NSEC;
2841 continue;
2842 }
2843
2844 if (phase != PHASE_ALL) {
2845 /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now. Note that in this
2846 * third phase we start to remove RRs we couldn't validate. */
2847 phase = PHASE_ALL;
2848 continue;
2849 }
2850
2851 /* We're done */
2852 break;
2853 }
2854
2855 dns_answer_unref(t->answer);
2856 t->answer = validated;
2857 validated = NULL;
2858
2859 /* At this point the answer only contains validated
2860 * RRsets. Now, let's see if it actually answers the question
2861 * we asked. If so, great! If it doesn't, then see if
2862 * NSEC/NSEC3 can prove this. */
2863 r = dns_transaction_has_positive_answer(t, &flags);
2864 if (r > 0) {
2865 /* Yes, it answers the question! */
2866
2867 if (flags & DNS_ANSWER_AUTHENTICATED) {
2868 /* The answer is fully authenticated, yay. */
2869 t->answer_dnssec_result = DNSSEC_VALIDATED;
2870 t->answer_rcode = DNS_RCODE_SUCCESS;
2871 t->answer_authenticated = true;
2872 } else {
2873 /* The answer is not fully authenticated. */
2874 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2875 t->answer_authenticated = false;
2876 }
2877
2878 } else if (r == 0) {
2879 DnssecNsecResult nr;
2880 bool authenticated = false;
2881
2882 /* Bummer! Let's check NSEC/NSEC3 */
2883 r = dnssec_nsec_test(t->answer, t->key, &nr, &authenticated, &t->answer_nsec_ttl);
2884 if (r < 0)
2885 return r;
2886
2887 switch (nr) {
2888
2889 case DNSSEC_NSEC_NXDOMAIN:
2890 /* NSEC proves the domain doesn't exist. Very good. */
2891 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
2892 t->answer_dnssec_result = DNSSEC_VALIDATED;
2893 t->answer_rcode = DNS_RCODE_NXDOMAIN;
2894 t->answer_authenticated = authenticated;
2895 break;
2896
2897 case DNSSEC_NSEC_NODATA:
2898 /* NSEC proves that there's no data here, very good. */
2899 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
2900 t->answer_dnssec_result = DNSSEC_VALIDATED;
2901 t->answer_rcode = DNS_RCODE_SUCCESS;
2902 t->answer_authenticated = authenticated;
2903 break;
2904
2905 case DNSSEC_NSEC_OPTOUT:
2906 /* NSEC3 says the data might not be signed */
2907 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
2908 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2909 t->answer_authenticated = false;
2910 break;
2911
2912 case DNSSEC_NSEC_NO_RR:
2913 /* No NSEC data? Bummer! */
2914
2915 r = dns_transaction_requires_nsec(t);
2916 if (r < 0)
2917 return r;
2918 if (r > 0)
2919 t->answer_dnssec_result = DNSSEC_NO_SIGNATURE;
2920 else {
2921 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2922 t->answer_authenticated = false;
2923 }
2924
2925 break;
2926
2927 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM:
2928 /* We don't know the NSEC3 algorithm used? */
2929 t->answer_dnssec_result = DNSSEC_UNSUPPORTED_ALGORITHM;
2930 break;
2931
2932 case DNSSEC_NSEC_FOUND:
2933 case DNSSEC_NSEC_CNAME:
2934 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
2935 t->answer_dnssec_result = DNSSEC_NSEC_MISMATCH;
2936 break;
2937
2938 default:
2939 assert_not_reached("Unexpected NSEC result.");
2940 }
2941 }
2942
2943 return 1;
2944 }
2945
2946 const char *dns_transaction_key_string(DnsTransaction *t) {
2947 assert(t);
2948
2949 if (!t->key_string) {
2950 if (dns_resource_key_to_string(t->key, &t->key_string) < 0)
2951 return "n/a";
2952 }
2953
2954 return strstrip(t->key_string);
2955 }
2956
2957 static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
2958 [DNS_TRANSACTION_NULL] = "null",
2959 [DNS_TRANSACTION_PENDING] = "pending",
2960 [DNS_TRANSACTION_VALIDATING] = "validating",
2961 [DNS_TRANSACTION_RCODE_FAILURE] = "rcode-failure",
2962 [DNS_TRANSACTION_SUCCESS] = "success",
2963 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
2964 [DNS_TRANSACTION_TIMEOUT] = "timeout",
2965 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
2966 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
2967 [DNS_TRANSACTION_RESOURCES] = "resources",
2968 [DNS_TRANSACTION_ABORTED] = "aborted",
2969 [DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
2970 [DNS_TRANSACTION_NO_TRUST_ANCHOR] = "no-trust-anchor",
2971 [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED] = "rr-type-unsupported",
2972 };
2973 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
2974
2975 static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
2976 [DNS_TRANSACTION_NETWORK] = "network",
2977 [DNS_TRANSACTION_CACHE] = "cache",
2978 [DNS_TRANSACTION_ZONE] = "zone",
2979 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
2980 };
2981 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);