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