]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-transaction.c
resolved: don't conclude NODATA if CNAME exists
[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 "af-list.h"
23 #include "alloc-util.h"
24 #include "dns-domain.h"
25 #include "fd-util.h"
26 #include "random-util.h"
27 #include "resolved-dns-cache.h"
28 #include "resolved-dns-transaction.h"
29 #include "resolved-llmnr.h"
30 #include "string-table.h"
31
32 static void dns_transaction_reset_answer(DnsTransaction *t) {
33 assert(t);
34
35 t->received = dns_packet_unref(t->received);
36 t->answer = dns_answer_unref(t->answer);
37 t->answer_rcode = 0;
38 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
39 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
40 t->answer_authenticated = false;
41 }
42
43 static void dns_transaction_close_connection(DnsTransaction *t) {
44 assert(t);
45
46 t->stream = dns_stream_free(t->stream);
47 t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source);
48 t->dns_udp_fd = safe_close(t->dns_udp_fd);
49 }
50
51 static void dns_transaction_stop_timeout(DnsTransaction *t) {
52 assert(t);
53
54 t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
55 }
56
57 DnsTransaction* dns_transaction_free(DnsTransaction *t) {
58 DnsQueryCandidate *c;
59 DnsZoneItem *i;
60 DnsTransaction *z;
61
62 if (!t)
63 return NULL;
64
65 dns_transaction_close_connection(t);
66 dns_transaction_stop_timeout(t);
67
68 dns_packet_unref(t->sent);
69 dns_transaction_reset_answer(t);
70
71 dns_server_unref(t->server);
72
73 if (t->scope) {
74 hashmap_remove_value(t->scope->transactions_by_key, t->key, t);
75 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
76
77 if (t->id != 0)
78 hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
79 }
80
81 while ((c = set_steal_first(t->notify_query_candidates)))
82 set_remove(c->transactions, t);
83 set_free(t->notify_query_candidates);
84
85 while ((i = set_steal_first(t->notify_zone_items)))
86 i->probe_transaction = NULL;
87 set_free(t->notify_zone_items);
88
89 while ((z = set_steal_first(t->notify_transactions)))
90 set_remove(z->dnssec_transactions, t);
91 set_free(t->notify_transactions);
92
93 while ((z = set_steal_first(t->dnssec_transactions))) {
94 set_remove(z->notify_transactions, t);
95 dns_transaction_gc(z);
96 }
97 set_free(t->dnssec_transactions);
98
99 dns_answer_unref(t->validated_keys);
100 dns_resource_key_unref(t->key);
101 free(t->key_string);
102
103 free(t);
104 return NULL;
105 }
106
107 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
108
109 void dns_transaction_gc(DnsTransaction *t) {
110 assert(t);
111
112 if (t->block_gc > 0)
113 return;
114
115 if (set_isempty(t->notify_query_candidates) &&
116 set_isempty(t->notify_zone_items) &&
117 set_isempty(t->notify_transactions))
118 dns_transaction_free(t);
119 }
120
121 int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) {
122 _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
123 int r;
124
125 assert(ret);
126 assert(s);
127 assert(key);
128
129 /* Don't allow looking up invalid or pseudo RRs */
130 if (!dns_type_is_valid_query(key->type))
131 return -EINVAL;
132
133 /* We only support the IN class */
134 if (key->class != DNS_CLASS_IN && key->class != DNS_CLASS_ANY)
135 return -EOPNOTSUPP;
136
137 r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
138 if (r < 0)
139 return r;
140
141 r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
142 if (r < 0)
143 return r;
144
145 t = new0(DnsTransaction, 1);
146 if (!t)
147 return -ENOMEM;
148
149 t->dns_udp_fd = -1;
150 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
151 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
152 t->key = dns_resource_key_ref(key);
153
154 /* Find a fresh, unused transaction id */
155 do
156 random_bytes(&t->id, sizeof(t->id));
157 while (t->id == 0 ||
158 hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(t->id)));
159
160 r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
161 if (r < 0) {
162 t->id = 0;
163 return r;
164 }
165
166 r = hashmap_replace(s->transactions_by_key, t->key, t);
167 if (r < 0) {
168 hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
169 return r;
170 }
171
172 LIST_PREPEND(transactions_by_scope, s->transactions, t);
173 t->scope = s;
174
175 s->manager->n_transactions_total ++;
176
177 if (ret)
178 *ret = t;
179
180 t = NULL;
181
182 return 0;
183 }
184
185 static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
186 _cleanup_free_ char *pretty = NULL;
187 DnsZoneItem *z;
188
189 assert(t);
190 assert(p);
191
192 if (manager_our_packet(t->scope->manager, p) != 0)
193 return;
194
195 in_addr_to_string(p->family, &p->sender, &pretty);
196
197 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s got tentative packet from %s.",
198 t->id,
199 dns_transaction_key_string(t),
200 dns_protocol_to_string(t->scope->protocol),
201 t->scope->link ? t->scope->link->name : "*",
202 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
203 pretty);
204
205 /* RFC 4795, Section 4.1 says that the peer with the
206 * lexicographically smaller IP address loses */
207 if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
208 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
209 return;
210 }
211
212 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
213
214 t->block_gc++;
215 while ((z = set_first(t->notify_zone_items))) {
216 /* First, make sure the zone item drops the reference
217 * to us */
218 dns_zone_item_probe_stop(z);
219
220 /* Secondly, report this as conflict, so that we might
221 * look for a different hostname */
222 dns_zone_item_conflict(z);
223 }
224 t->block_gc--;
225
226 dns_transaction_gc(t);
227 }
228
229 void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
230 DnsQueryCandidate *c;
231 DnsZoneItem *z;
232 DnsTransaction *d;
233 Iterator i;
234
235 assert(t);
236 assert(!DNS_TRANSACTION_IS_LIVE(state));
237
238 if (state == DNS_TRANSACTION_DNSSEC_FAILED)
239 log_struct(LOG_NOTICE,
240 LOG_MESSAGE("DNSSEC validation failed for question %s: %s", dns_transaction_key_string(t), dnssec_result_to_string(t->answer_dnssec_result)),
241 "DNS_TRANSACTION=%" PRIu16, t->id,
242 "DNS_QUESTION=%s", dns_transaction_key_string(t),
243 "DNSSEC_RESULT=%s", dnssec_result_to_string(t->answer_dnssec_result),
244 NULL);
245
246 /* Note that this call might invalidate the query. Callers
247 * should hence not attempt to access the query or transaction
248 * after calling this function. */
249
250 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).",
251 t->id,
252 dns_transaction_key_string(t),
253 dns_protocol_to_string(t->scope->protocol),
254 t->scope->link ? t->scope->link->name : "*",
255 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
256 dns_transaction_state_to_string(state),
257 t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
258 t->answer_authenticated ? "authenticated" : "unsigned");
259
260 t->state = state;
261
262 dns_transaction_close_connection(t);
263 dns_transaction_stop_timeout(t);
264
265 /* Notify all queries that are interested, but make sure the
266 * transaction isn't freed while we are still looking at it */
267 t->block_gc++;
268
269 SET_FOREACH(c, t->notify_query_candidates, i)
270 dns_query_candidate_notify(c);
271 SET_FOREACH(z, t->notify_zone_items, i)
272 dns_zone_item_notify(z);
273
274 if (!set_isempty(t->notify_transactions)) {
275 DnsTransaction **nt;
276 unsigned j, n = 0;
277
278 /* We need to be careful when notifying other
279 * transactions, as that might destroy other
280 * transactions in our list. Hence, in order to be
281 * able to safely iterate through the list of
282 * transactions, take a GC lock on all of them
283 * first. Then, in a second loop, notify them, but
284 * first unlock that specific transaction. */
285
286 nt = newa(DnsTransaction*, set_size(t->notify_transactions));
287 SET_FOREACH(d, t->notify_transactions, i) {
288 nt[n++] = d;
289 d->block_gc++;
290 }
291
292 assert(n == set_size(t->notify_transactions));
293
294 for (j = 0; j < n; j++) {
295 if (set_contains(t->notify_transactions, nt[j]))
296 dns_transaction_notify(nt[j], t);
297
298 nt[j]->block_gc--;
299 dns_transaction_gc(nt[j]);
300 }
301 }
302
303 t->block_gc--;
304 dns_transaction_gc(t);
305 }
306
307 static int dns_transaction_pick_server(DnsTransaction *t) {
308 DnsServer *server;
309
310 assert(t);
311 assert(t->scope->protocol == DNS_PROTOCOL_DNS);
312
313 server = dns_scope_get_dns_server(t->scope);
314 if (!server)
315 return -ESRCH;
316
317 t->current_features = dns_server_possible_feature_level(server);
318
319 if (server == t->server)
320 return 0;
321
322 dns_server_unref(t->server);
323 t->server = dns_server_ref(server);
324
325 return 1;
326 }
327
328 static int on_stream_complete(DnsStream *s, int error) {
329 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
330 DnsTransaction *t;
331
332 assert(s);
333 assert(s->transaction);
334
335 /* Copy the data we care about out of the stream before we
336 * destroy it. */
337 t = s->transaction;
338 p = dns_packet_ref(s->read_packet);
339
340 t->stream = dns_stream_free(t->stream);
341
342 if (IN_SET(error, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE)) {
343 dns_transaction_complete(t, DNS_TRANSACTION_CONNECTION_FAILURE);
344 return 0;
345 }
346
347 if (error != 0) {
348 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
349 return 0;
350 }
351
352 if (dns_packet_validate_reply(p) <= 0) {
353 log_debug("Invalid TCP reply packet.");
354 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
355 return 0;
356 }
357
358 dns_scope_check_conflicts(t->scope, p);
359
360 t->block_gc++;
361 dns_transaction_process_reply(t, p);
362 t->block_gc--;
363
364 /* If the response wasn't useful, then complete the transition
365 * now. After all, we are the worst feature set now with TCP
366 * sockets, and there's really no point in retrying. */
367 if (t->state == DNS_TRANSACTION_PENDING)
368 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
369 else
370 dns_transaction_gc(t);
371
372 return 0;
373 }
374
375 static int dns_transaction_open_tcp(DnsTransaction *t) {
376 _cleanup_close_ int fd = -1;
377 int r;
378
379 assert(t);
380
381 dns_transaction_close_connection(t);
382
383 switch (t->scope->protocol) {
384
385 case DNS_PROTOCOL_DNS:
386 r = dns_transaction_pick_server(t);
387 if (r < 0)
388 return r;
389
390 r = dns_server_adjust_opt(t->server, t->sent, t->current_features);
391 if (r < 0)
392 return r;
393
394 fd = dns_scope_socket_tcp(t->scope, AF_UNSPEC, NULL, t->server, 53);
395 break;
396
397 case DNS_PROTOCOL_LLMNR:
398 /* When we already received a reply to this (but it was truncated), send to its sender address */
399 if (t->received)
400 fd = dns_scope_socket_tcp(t->scope, t->received->family, &t->received->sender, NULL, t->received->sender_port);
401 else {
402 union in_addr_union address;
403 int family = AF_UNSPEC;
404
405 /* Otherwise, try to talk to the owner of a
406 * the IP address, in case this is a reverse
407 * PTR lookup */
408
409 r = dns_name_address(DNS_RESOURCE_KEY_NAME(t->key), &family, &address);
410 if (r < 0)
411 return r;
412 if (r == 0)
413 return -EINVAL;
414 if (family != t->scope->family)
415 return -ESRCH;
416
417 fd = dns_scope_socket_tcp(t->scope, family, &address, NULL, LLMNR_PORT);
418 }
419
420 break;
421
422 default:
423 return -EAFNOSUPPORT;
424 }
425
426 if (fd < 0)
427 return fd;
428
429 r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
430 if (r < 0)
431 return r;
432 fd = -1;
433
434 r = dns_stream_write_packet(t->stream, t->sent);
435 if (r < 0) {
436 t->stream = dns_stream_free(t->stream);
437 return r;
438 }
439
440 t->stream->complete = on_stream_complete;
441 t->stream->transaction = t;
442
443 /* The interface index is difficult to determine if we are
444 * connecting to the local host, hence fill this in right away
445 * instead of determining it from the socket */
446 if (t->scope->link)
447 t->stream->ifindex = t->scope->link->ifindex;
448
449 dns_transaction_reset_answer(t);
450
451 t->tried_stream = true;
452
453 return 0;
454 }
455
456 static void dns_transaction_cache_answer(DnsTransaction *t) {
457 assert(t);
458
459 /* For mDNS we cache whenever we get the packet, rather than
460 * in each transaction. */
461 if (!IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR))
462 return;
463
464 /* We never cache if this packet is from the local host, under
465 * the assumption that a locally running DNS server would
466 * cache this anyway, and probably knows better when to flush
467 * the cache then we could. */
468 if (!DNS_PACKET_SHALL_CACHE(t->received))
469 return;
470
471 dns_cache_put(&t->scope->cache,
472 t->key,
473 t->answer_rcode,
474 t->answer,
475 t->answer_authenticated,
476 0,
477 t->received->family,
478 &t->received->sender);
479 }
480
481 static bool dns_transaction_dnssec_is_live(DnsTransaction *t) {
482 DnsTransaction *dt;
483 Iterator i;
484
485 assert(t);
486
487 SET_FOREACH(dt, t->dnssec_transactions, i)
488 if (DNS_TRANSACTION_IS_LIVE(dt->state))
489 return true;
490
491 return false;
492 }
493
494 static void dns_transaction_process_dnssec(DnsTransaction *t) {
495 int r;
496
497 assert(t);
498
499 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
500 if (dns_transaction_dnssec_is_live(t))
501 return;
502
503 /* All our auxiliary DNSSEC transactions are complete now. Try
504 * to validate our RRset now. */
505 r = dns_transaction_validate_dnssec(t);
506 if (r < 0) {
507 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
508 return;
509 }
510
511 if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER &&
512 t->scope->dnssec_mode == DNSSEC_YES) {
513 /* We are not in automatic downgrade mode, and the
514 * server is bad, refuse operation. */
515 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
516 return;
517 }
518
519 if (!IN_SET(t->answer_dnssec_result,
520 _DNSSEC_RESULT_INVALID, /* No DNSSEC validation enabled */
521 DNSSEC_VALIDATED, /* Answer is signed and validated successfully */
522 DNSSEC_UNSIGNED, /* Answer is right-fully unsigned */
523 DNSSEC_INCOMPATIBLE_SERVER)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
524 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
525 return;
526 }
527
528 dns_transaction_cache_answer(t);
529
530 if (t->answer_rcode == DNS_RCODE_SUCCESS)
531 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
532 else
533 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
534 }
535
536 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
537 usec_t ts;
538 int r;
539
540 assert(t);
541 assert(p);
542 assert(t->scope);
543 assert(t->scope->manager);
544
545 if (t->state != DNS_TRANSACTION_PENDING)
546 return;
547
548 /* Note that this call might invalidate the query. Callers
549 * should hence not attempt to access the query or transaction
550 * after calling this function. */
551
552 log_debug("Processing incoming packet on transaction %" PRIu16".", t->id);
553
554 switch (t->scope->protocol) {
555
556 case DNS_PROTOCOL_LLMNR:
557 assert(t->scope->link);
558
559 /* For LLMNR we will not accept any packets from other
560 * interfaces */
561
562 if (p->ifindex != t->scope->link->ifindex)
563 return;
564
565 if (p->family != t->scope->family)
566 return;
567
568 /* Tentative packets are not full responses but still
569 * useful for identifying uniqueness conflicts during
570 * probing. */
571 if (DNS_PACKET_LLMNR_T(p)) {
572 dns_transaction_tentative(t, p);
573 return;
574 }
575
576 break;
577
578 case DNS_PROTOCOL_MDNS:
579 assert(t->scope->link);
580
581 /* For mDNS we will not accept any packets from other interfaces */
582 if (p->ifindex != t->scope->link->ifindex)
583 return;
584
585 if (p->family != t->scope->family)
586 return;
587
588 break;
589
590 case DNS_PROTOCOL_DNS:
591 break;
592
593 default:
594 assert_not_reached("Invalid DNS protocol.");
595 }
596
597 if (t->received != p) {
598 dns_packet_unref(t->received);
599 t->received = dns_packet_ref(p);
600 }
601
602 t->answer_source = DNS_TRANSACTION_NETWORK;
603
604 if (p->ipproto == IPPROTO_TCP) {
605 if (DNS_PACKET_TC(p)) {
606 /* Truncated via TCP? Somebody must be fucking with us */
607 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
608 return;
609 }
610
611 if (DNS_PACKET_ID(p) != t->id) {
612 /* Not the reply to our query? Somebody must be fucking with us */
613 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
614 return;
615 }
616 }
617
618 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
619
620 switch (t->scope->protocol) {
621
622 case DNS_PROTOCOL_DNS:
623 assert(t->server);
624
625 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
626
627 /* Request failed, immediately try again with reduced features */
628 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
629
630 dns_server_packet_failed(t->server, t->current_features);
631
632 r = dns_transaction_go(t);
633 if (r < 0) {
634 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
635 return;
636 }
637
638 return;
639 } else
640 dns_server_packet_received(t->server, t->current_features, ts - t->start_usec, p->size);
641
642 break;
643
644 case DNS_PROTOCOL_LLMNR:
645 case DNS_PROTOCOL_MDNS:
646 dns_scope_packet_received(t->scope, ts - t->start_usec);
647 break;
648
649 default:
650 assert_not_reached("Invalid DNS protocol.");
651 }
652
653 if (DNS_PACKET_TC(p)) {
654
655 /* Truncated packets for mDNS are not allowed. Give up immediately. */
656 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
657 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
658 return;
659 }
660
661 /* Response was truncated, let's try again with good old TCP */
662 r = dns_transaction_open_tcp(t);
663 if (r == -ESRCH) {
664 /* No servers found? Damn! */
665 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
666 return;
667 }
668 if (r < 0) {
669 /* On LLMNR, if we cannot connect to the host,
670 * we immediately give up */
671 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
672 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
673 return;
674 }
675
676 /* On DNS, couldn't send? Try immediately again, with a new server */
677 dns_scope_next_dns_server(t->scope);
678
679 r = dns_transaction_go(t);
680 if (r < 0) {
681 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
682 return;
683 }
684 }
685
686 return;
687 }
688
689 /* Parse message, if it isn't parsed yet. */
690 r = dns_packet_extract(p);
691 if (r < 0) {
692 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
693 return;
694 }
695
696 if (IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR)) {
697
698 /* Only consider responses with equivalent query section to the request */
699 r = dns_packet_is_reply_for(p, t->key);
700 if (r < 0) {
701 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
702 return;
703 }
704 if (r == 0) {
705 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
706 return;
707 }
708
709 /* Install the answer as answer to the transaction */
710 dns_answer_unref(t->answer);
711 t->answer = dns_answer_ref(p->answer);
712 t->answer_rcode = DNS_PACKET_RCODE(p);
713 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
714 t->answer_authenticated = false;
715
716 r = dns_transaction_request_dnssec_keys(t);
717 if (r < 0) {
718 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
719 return;
720 }
721 if (r > 0) {
722 /* There are DNSSEC transactions pending now. Update the state accordingly. */
723 t->state = DNS_TRANSACTION_VALIDATING;
724 dns_transaction_close_connection(t);
725 dns_transaction_stop_timeout(t);
726 return;
727 }
728 }
729
730 dns_transaction_process_dnssec(t);
731 }
732
733 static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
734 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
735 DnsTransaction *t = userdata;
736 int r;
737
738 assert(t);
739 assert(t->scope);
740
741 r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
742 if (r <= 0)
743 return r;
744
745 if (dns_packet_validate_reply(p) > 0 &&
746 DNS_PACKET_ID(p) == t->id)
747 dns_transaction_process_reply(t, p);
748 else
749 log_debug("Invalid DNS UDP packet, ignoring.");
750
751 return 0;
752 }
753
754 static int dns_transaction_emit_udp(DnsTransaction *t) {
755 int r;
756
757 assert(t);
758
759 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
760
761 r = dns_transaction_pick_server(t);
762 if (r < 0)
763 return r;
764
765 if (t->current_features < DNS_SERVER_FEATURE_LEVEL_UDP)
766 return -EAGAIN;
767
768 if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */
769 int fd;
770
771 dns_transaction_close_connection(t);
772
773 fd = dns_scope_socket_udp(t->scope, t->server, 53);
774 if (fd < 0)
775 return fd;
776
777 r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
778 if (r < 0) {
779 safe_close(fd);
780 return r;
781 }
782
783 t->dns_udp_fd = fd;
784 }
785
786 r = dns_server_adjust_opt(t->server, t->sent, t->current_features);
787 if (r < 0)
788 return r;
789 } else
790 dns_transaction_close_connection(t);
791
792 r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->sent);
793 if (r < 0)
794 return r;
795
796 dns_transaction_reset_answer(t);
797
798 return 0;
799 }
800
801 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
802 DnsTransaction *t = userdata;
803 int r;
804
805 assert(s);
806 assert(t);
807
808 if (!t->initial_jitter_scheduled || t->initial_jitter_elapsed) {
809 /* Timeout reached? Increase the timeout for the server used */
810 switch (t->scope->protocol) {
811
812 case DNS_PROTOCOL_DNS:
813 assert(t->server);
814 dns_server_packet_lost(t->server, t->current_features, usec - t->start_usec);
815 break;
816
817 case DNS_PROTOCOL_LLMNR:
818 case DNS_PROTOCOL_MDNS:
819 dns_scope_packet_lost(t->scope, usec - t->start_usec);
820 break;
821
822 default:
823 assert_not_reached("Invalid DNS protocol.");
824 }
825
826 if (t->initial_jitter_scheduled)
827 t->initial_jitter_elapsed = true;
828 }
829
830 log_debug("Timeout reached on transaction %" PRIu16 ".", t->id);
831
832 /* ...and try again with a new server */
833 dns_scope_next_dns_server(t->scope);
834
835 r = dns_transaction_go(t);
836 if (r < 0)
837 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
838
839 return 0;
840 }
841
842 static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
843 assert(t);
844 assert(t->scope);
845
846 switch (t->scope->protocol) {
847
848 case DNS_PROTOCOL_DNS:
849 assert(t->server);
850 return t->server->resend_timeout;
851
852 case DNS_PROTOCOL_MDNS:
853 assert(t->n_attempts > 0);
854 return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
855
856 case DNS_PROTOCOL_LLMNR:
857 return t->scope->resend_timeout;
858
859 default:
860 assert_not_reached("Invalid DNS protocol.");
861 }
862 }
863
864 static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
865 int r;
866
867 assert(t);
868
869 dns_transaction_stop_timeout(t);
870
871 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
872 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
873 return 0;
874 }
875
876 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && t->tried_stream) {
877 /* If we already tried via a stream, then we don't
878 * retry on LLMNR. See RFC 4795, Section 2.7. */
879 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
880 return 0;
881 }
882
883 t->n_attempts++;
884 t->start_usec = ts;
885
886 dns_transaction_reset_answer(t);
887
888 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
889 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
890 r = dns_trust_anchor_lookup(&t->scope->manager->trust_anchor, t->key, &t->answer);
891 if (r < 0)
892 return r;
893 if (r > 0) {
894 t->answer_rcode = DNS_RCODE_SUCCESS;
895 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
896 t->answer_authenticated = true;
897 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
898 return 0;
899 }
900 }
901
902 /* Check the zone, but only if this transaction is not used
903 * for probing or verifying a zone item. */
904 if (set_isempty(t->notify_zone_items)) {
905
906 r = dns_zone_lookup(&t->scope->zone, t->key, &t->answer, NULL, NULL);
907 if (r < 0)
908 return r;
909 if (r > 0) {
910 t->answer_rcode = DNS_RCODE_SUCCESS;
911 t->answer_source = DNS_TRANSACTION_ZONE;
912 t->answer_authenticated = true;
913 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
914 return 0;
915 }
916 }
917
918 /* Check the cache, but only if this transaction is not used
919 * for probing or verifying a zone item. */
920 if (set_isempty(t->notify_zone_items)) {
921
922 /* Before trying the cache, let's make sure we figured out a
923 * server to use. Should this cause a change of server this
924 * might flush the cache. */
925 dns_scope_get_dns_server(t->scope);
926
927 /* Let's then prune all outdated entries */
928 dns_cache_prune(&t->scope->cache);
929
930 r = dns_cache_lookup(&t->scope->cache, t->key, &t->answer_rcode, &t->answer, &t->answer_authenticated);
931 if (r < 0)
932 return r;
933 if (r > 0) {
934 t->answer_source = DNS_TRANSACTION_CACHE;
935 if (t->answer_rcode == DNS_RCODE_SUCCESS)
936 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
937 else
938 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
939 return 0;
940 }
941 }
942
943 return 1;
944 }
945
946 static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
947
948 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
949 bool add_known_answers = false;
950 DnsTransaction *other;
951 unsigned qdcount;
952 usec_t ts;
953 int r;
954
955 assert(t);
956 assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
957
958 /* Discard any previously prepared packet, so we can start over and coalesce again */
959 t->sent = dns_packet_unref(t->sent);
960
961 r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
962 if (r < 0)
963 return r;
964
965 r = dns_packet_append_key(p, t->key, NULL);
966 if (r < 0)
967 return r;
968
969 qdcount = 1;
970
971 if (dns_key_is_shared(t->key))
972 add_known_answers = true;
973
974 /*
975 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
976 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
977 * in our current scope, and see whether their timing contraints allow them to be sent.
978 */
979
980 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
981
982 LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
983
984 /* Skip ourselves */
985 if (other == t)
986 continue;
987
988 if (other->state != DNS_TRANSACTION_PENDING)
989 continue;
990
991 if (other->next_attempt_after > ts)
992 continue;
993
994 if (qdcount >= UINT16_MAX)
995 break;
996
997 r = dns_packet_append_key(p, other->key, NULL);
998
999 /*
1000 * If we can't stuff more questions into the packet, just give up.
1001 * One of the 'other' transactions will fire later and take care of the rest.
1002 */
1003 if (r == -EMSGSIZE)
1004 break;
1005
1006 if (r < 0)
1007 return r;
1008
1009 r = dns_transaction_prepare(other, ts);
1010 if (r <= 0)
1011 continue;
1012
1013 ts += transaction_get_resend_timeout(other);
1014
1015 r = sd_event_add_time(
1016 other->scope->manager->event,
1017 &other->timeout_event_source,
1018 clock_boottime_or_monotonic(),
1019 ts, 0,
1020 on_transaction_timeout, other);
1021 if (r < 0)
1022 return r;
1023
1024 other->state = DNS_TRANSACTION_PENDING;
1025 other->next_attempt_after = ts;
1026
1027 qdcount ++;
1028
1029 if (dns_key_is_shared(other->key))
1030 add_known_answers = true;
1031 }
1032
1033 DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
1034
1035 /* Append known answer section if we're asking for any shared record */
1036 if (add_known_answers) {
1037 r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
1038 if (r < 0)
1039 return r;
1040 }
1041
1042 t->sent = p;
1043 p = NULL;
1044
1045 return 0;
1046 }
1047
1048 static int dns_transaction_make_packet(DnsTransaction *t) {
1049 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1050 int r;
1051
1052 assert(t);
1053
1054 if (t->scope->protocol == DNS_PROTOCOL_MDNS)
1055 return dns_transaction_make_packet_mdns(t);
1056
1057 if (t->sent)
1058 return 0;
1059
1060 r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode != DNSSEC_NO);
1061 if (r < 0)
1062 return r;
1063
1064 r = dns_scope_good_key(t->scope, t->key);
1065 if (r < 0)
1066 return r;
1067 if (r == 0)
1068 return -EDOM;
1069
1070 r = dns_packet_append_key(p, t->key, NULL);
1071 if (r < 0)
1072 return r;
1073
1074 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
1075 DNS_PACKET_HEADER(p)->id = t->id;
1076
1077 t->sent = p;
1078 p = NULL;
1079
1080 return 0;
1081 }
1082
1083 int dns_transaction_go(DnsTransaction *t) {
1084 usec_t ts;
1085 int r;
1086
1087 assert(t);
1088
1089 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
1090
1091 r = dns_transaction_prepare(t, ts);
1092 if (r <= 0)
1093 return r;
1094
1095 log_debug("Excercising transaction %" PRIu16 " for <%s> on scope %s on %s/%s.",
1096 t->id,
1097 dns_transaction_key_string(t),
1098 dns_protocol_to_string(t->scope->protocol),
1099 t->scope->link ? t->scope->link->name : "*",
1100 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
1101
1102 if (!t->initial_jitter_scheduled &&
1103 (t->scope->protocol == DNS_PROTOCOL_LLMNR ||
1104 t->scope->protocol == DNS_PROTOCOL_MDNS)) {
1105 usec_t jitter, accuracy;
1106
1107 /* RFC 4795 Section 2.7 suggests all queries should be
1108 * delayed by a random time from 0 to JITTER_INTERVAL. */
1109
1110 t->initial_jitter_scheduled = true;
1111
1112 random_bytes(&jitter, sizeof(jitter));
1113
1114 switch (t->scope->protocol) {
1115
1116 case DNS_PROTOCOL_LLMNR:
1117 jitter %= LLMNR_JITTER_INTERVAL_USEC;
1118 accuracy = LLMNR_JITTER_INTERVAL_USEC;
1119 break;
1120
1121 case DNS_PROTOCOL_MDNS:
1122 jitter %= MDNS_JITTER_RANGE_USEC;
1123 jitter += MDNS_JITTER_MIN_USEC;
1124 accuracy = MDNS_JITTER_RANGE_USEC;
1125 break;
1126 default:
1127 assert_not_reached("bad protocol");
1128 }
1129
1130 r = sd_event_add_time(
1131 t->scope->manager->event,
1132 &t->timeout_event_source,
1133 clock_boottime_or_monotonic(),
1134 ts + jitter, accuracy,
1135 on_transaction_timeout, t);
1136 if (r < 0)
1137 return r;
1138
1139 t->n_attempts = 0;
1140 t->next_attempt_after = ts;
1141 t->state = DNS_TRANSACTION_PENDING;
1142
1143 log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
1144 return 0;
1145 }
1146
1147 /* Otherwise, we need to ask the network */
1148 r = dns_transaction_make_packet(t);
1149 if (r == -EDOM) {
1150 /* Not the right request to make on this network?
1151 * (i.e. an A request made on IPv6 or an AAAA request
1152 * made on IPv4, on LLMNR or mDNS.) */
1153 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1154 return 0;
1155 }
1156 if (r < 0)
1157 return r;
1158
1159 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
1160 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "in-addr.arpa") > 0 ||
1161 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "ip6.arpa") > 0)) {
1162
1163 /* RFC 4795, Section 2.4. says reverse lookups shall
1164 * always be made via TCP on LLMNR */
1165 r = dns_transaction_open_tcp(t);
1166 } else {
1167 /* Try via UDP, and if that fails due to large size or lack of
1168 * support try via TCP */
1169 r = dns_transaction_emit_udp(t);
1170 if (r == -EMSGSIZE || r == -EAGAIN)
1171 r = dns_transaction_open_tcp(t);
1172 }
1173
1174 if (r == -ESRCH) {
1175 /* No servers to send this to? */
1176 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1177 return 0;
1178 } else if (r < 0) {
1179 if (t->scope->protocol != DNS_PROTOCOL_DNS) {
1180 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
1181 return 0;
1182 }
1183
1184 /* Couldn't send? Try immediately again, with a new server */
1185 dns_scope_next_dns_server(t->scope);
1186
1187 return dns_transaction_go(t);
1188 }
1189
1190 ts += transaction_get_resend_timeout(t);
1191
1192 r = sd_event_add_time(
1193 t->scope->manager->event,
1194 &t->timeout_event_source,
1195 clock_boottime_or_monotonic(),
1196 ts, 0,
1197 on_transaction_timeout, t);
1198 if (r < 0)
1199 return r;
1200
1201 t->state = DNS_TRANSACTION_PENDING;
1202 t->next_attempt_after = ts;
1203
1204 return 1;
1205 }
1206
1207 static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
1208 DnsTransaction *aux;
1209 int r;
1210
1211 assert(t);
1212 assert(ret);
1213 assert(key);
1214
1215 aux = dns_scope_find_transaction(t->scope, key, true);
1216 if (!aux) {
1217 r = dns_transaction_new(&aux, t->scope, key);
1218 if (r < 0)
1219 return r;
1220 } else {
1221 if (set_contains(t->dnssec_transactions, aux)) {
1222 *ret = aux;
1223 return 0;
1224 }
1225 }
1226
1227 r = set_ensure_allocated(&t->dnssec_transactions, NULL);
1228 if (r < 0)
1229 goto gc;
1230
1231 r = set_ensure_allocated(&aux->notify_transactions, NULL);
1232 if (r < 0)
1233 goto gc;
1234
1235 r = set_put(t->dnssec_transactions, aux);
1236 if (r < 0)
1237 goto gc;
1238
1239 r = set_put(aux->notify_transactions, t);
1240 if (r < 0) {
1241 (void) set_remove(t->dnssec_transactions, aux);
1242 goto gc;
1243 }
1244
1245 *ret = aux;
1246 return 1;
1247
1248 gc:
1249 dns_transaction_gc(aux);
1250 return r;
1251 }
1252
1253 static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
1254 _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL;
1255 DnsTransaction *aux;
1256 int r;
1257
1258 assert(t);
1259 assert(key);
1260
1261 r = dns_resource_key_equal(t->key, key);
1262 if (r < 0)
1263 return r;
1264 if (r > 0) /* Don't go in circles */
1265 return 0;
1266
1267 /* Try to get the data from the trust anchor */
1268 r = dns_trust_anchor_lookup(&t->scope->manager->trust_anchor, key, &a);
1269 if (r < 0)
1270 return r;
1271 if (r > 0) {
1272 r = dns_answer_extend(&t->validated_keys, a);
1273 if (r < 0)
1274 return r;
1275
1276 return 0;
1277 }
1278
1279 /* This didn't work, ask for it via the network/cache then. */
1280 r = dns_transaction_add_dnssec_transaction(t, key, &aux);
1281 if (r < 0)
1282 return r;
1283
1284 if (aux->state == DNS_TRANSACTION_NULL) {
1285 r = dns_transaction_go(aux);
1286 if (r < 0)
1287 return r;
1288 }
1289
1290 return 0;
1291 }
1292
1293 static int dns_transaction_has_positive_answer(DnsTransaction *t, DnsAnswerFlags *flags) {
1294 int r;
1295
1296 assert(t);
1297
1298 /* Checks whether the answer is positive, i.e. either a direct
1299 * answer to the question, or a CNAME/DNAME for it */
1300
1301 r = dns_answer_match_key(t->answer, t->key, flags);
1302 if (r != 0)
1303 return r;
1304
1305 r = dns_answer_find_cname_or_dname(t->answer, t->key, NULL, flags);
1306 if (r != 0)
1307 return r;
1308
1309 return false;
1310 }
1311
1312 static int dns_transaction_has_unsigned_negative_answer(DnsTransaction *t) {
1313 int r;
1314
1315 assert(t);
1316
1317 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
1318 * RRs to prove it */
1319
1320 r = dns_transaction_has_positive_answer(t, NULL);
1321 if (r < 0)
1322 return r;
1323 if (r > 0)
1324 return false;
1325
1326 /* The answer does not contain any RRs that match to the
1327 * question. If so, let's see if there are any NSEC/NSEC3 RRs
1328 * included. If not, the answer is unsigned. */
1329
1330 r = dns_answer_contains_nsec_or_nsec3(t->answer);
1331 if (r < 0)
1332 return r;
1333 if (r > 0)
1334 return false;
1335
1336 return true;
1337 }
1338
1339 static int dns_transaction_is_primary_response(DnsTransaction *t, DnsResourceRecord *rr) {
1340 int r;
1341
1342 assert(t);
1343 assert(rr);
1344
1345 /* Check if the specified RR is the "primary" response,
1346 * i.e. either matches the question precisely or is a
1347 * CNAME/DNAME for it, or is any kind of NSEC/NSEC3 RR */
1348
1349 r = dns_resource_key_match_rr(t->key, rr, NULL);
1350 if (r != 0)
1351 return r;
1352
1353 r = dns_resource_key_match_cname_or_dname(t->key, rr->key, NULL);
1354 if (r != 0)
1355 return r;
1356
1357 if (rr->key->type == DNS_TYPE_NSEC3) {
1358 const char *p;
1359
1360 p = DNS_RESOURCE_KEY_NAME(rr->key);
1361 r = dns_name_parent(&p);
1362 if (r < 0)
1363 return r;
1364 if (r > 0) {
1365 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), p);
1366 if (r < 0)
1367 return r;
1368 if (r > 0)
1369 return true;
1370 }
1371 }
1372
1373 return rr->key->type == DNS_TYPE_NSEC;
1374 }
1375
1376 int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
1377 DnsResourceRecord *rr;
1378
1379 int r;
1380
1381 assert(t);
1382
1383 /*
1384 * Retrieve all auxiliary RRs for the answer we got, so that
1385 * we can verify signatures or prove that RRs are rightfully
1386 * unsigned. Specifically:
1387 *
1388 * - For RRSIG we get the matching DNSKEY
1389 * - For DNSKEY we get the matching DS
1390 * - For unsigned SOA/NS we get the matching DS
1391 * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
1392 * - For other unsigned RRs we get the matching SOA RR
1393 * - For SOA/NS/DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
1394 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
1395 */
1396
1397 if (t->scope->dnssec_mode == DNSSEC_NO)
1398 return 0;
1399
1400 if (t->current_features < DNS_SERVER_FEATURE_LEVEL_DO)
1401 return 0; /* Server doesn't do DNSSEC, there's no point in requesting any RRs then. */
1402 if (t->server && t->server->rrsig_missing)
1403 return 0; /* Server handles DNSSEC requests, but isn't augmenting responses with RRSIGs. No point in trying DNSSEC then. */
1404
1405 DNS_ANSWER_FOREACH(rr, t->answer) {
1406
1407 if (dns_type_is_pseudo(rr->key->type))
1408 continue;
1409
1410 switch (rr->key->type) {
1411
1412 case DNS_TYPE_RRSIG: {
1413 /* For each RRSIG we request the matching DNSKEY */
1414 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
1415
1416 /* If this RRSIG is about a DNSKEY RR and the
1417 * signer is the same as the owner, then we
1418 * already have the DNSKEY, and we don't have
1419 * to look for more. */
1420 if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
1421 r = dns_name_equal(rr->rrsig.signer, DNS_RESOURCE_KEY_NAME(rr->key));
1422 if (r < 0)
1423 return r;
1424 if (r > 0)
1425 continue;
1426 }
1427
1428 /* If the signer is not a parent of our
1429 * original query, then this is about an
1430 * auxiliary RRset, but not anything we asked
1431 * for. In this case we aren't interested,
1432 * because we don't want to request additional
1433 * RRs for stuff we didn't really ask for, and
1434 * also to avoid request loops, where
1435 * additional RRs from one transaction result
1436 * in another transaction whose additonal RRs
1437 * point back to the original transaction, and
1438 * we deadlock. */
1439 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), rr->rrsig.signer);
1440 if (r < 0)
1441 return r;
1442 if (r == 0)
1443 continue;
1444
1445 dnskey = dns_resource_key_new(rr->key->class, DNS_TYPE_DNSKEY, rr->rrsig.signer);
1446 if (!dnskey)
1447 return -ENOMEM;
1448
1449 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);
1450 r = dns_transaction_request_dnssec_rr(t, dnskey);
1451 if (r < 0)
1452 return r;
1453 break;
1454 }
1455
1456 case DNS_TYPE_DNSKEY: {
1457 /* For each DNSKEY we request the matching DS */
1458 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1459
1460 /* If the DNSKEY we are looking at is not for
1461 * zone we are interested in, nor any of its
1462 * parents, we aren't interested, and don't
1463 * request it. After all, we don't want to end
1464 * up in request loops, and want to keep
1465 * additional traffic down. */
1466
1467 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), DNS_RESOURCE_KEY_NAME(rr->key));
1468 if (r < 0)
1469 return r;
1470 if (r == 0)
1471 continue;
1472
1473 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(rr->key));
1474 if (!ds)
1475 return -ENOMEM;
1476
1477 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));
1478 r = dns_transaction_request_dnssec_rr(t, ds);
1479 if (r < 0)
1480 return r;
1481
1482 break;
1483 }
1484
1485 case DNS_TYPE_SOA:
1486 case DNS_TYPE_NS: {
1487 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1488
1489 /* For an unsigned SOA or NS, try to acquire
1490 * the matching DS RR, as we are at a zone cut
1491 * then, and whether a DS exists tells us
1492 * whether the zone is signed. Do so only if
1493 * this RR matches our original question,
1494 * however. */
1495
1496 r = dns_resource_key_match_rr(t->key, rr, NULL);
1497 if (r < 0)
1498 return r;
1499 if (r == 0)
1500 continue;
1501
1502 r = dnssec_has_rrsig(t->answer, rr->key);
1503 if (r < 0)
1504 return r;
1505 if (r > 0)
1506 continue;
1507
1508 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(rr->key));
1509 if (!ds)
1510 return -ENOMEM;
1511
1512 log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
1513 r = dns_transaction_request_dnssec_rr(t, ds);
1514 if (r < 0)
1515 return r;
1516
1517 break;
1518 }
1519
1520 case DNS_TYPE_DS:
1521 case DNS_TYPE_CNAME:
1522 case DNS_TYPE_DNAME: {
1523 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1524 const char *name;
1525
1526 /* CNAMEs and DNAMEs cannot be located at a
1527 * zone apex, hence ask for the parent SOA for
1528 * unsigned CNAME/DNAME RRs, maybe that's the
1529 * apex. But do all that only if this is
1530 * actually a response to our original
1531 * question.
1532 *
1533 * Similar for DS RRs, which are signed when
1534 * the parent SOA is signed. */
1535
1536 r = dns_transaction_is_primary_response(t, rr);
1537 if (r < 0)
1538 return r;
1539 if (r == 0)
1540 continue;
1541
1542 r = dnssec_has_rrsig(t->answer, rr->key);
1543 if (r < 0)
1544 return r;
1545 if (r > 0)
1546 continue;
1547
1548 name = DNS_RESOURCE_KEY_NAME(rr->key);
1549 r = dns_name_parent(&name);
1550 if (r < 0)
1551 return r;
1552 if (r == 0)
1553 continue;
1554
1555 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
1556 if (!soa)
1557 return -ENOMEM;
1558
1559 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
1560 r = dns_transaction_request_dnssec_rr(t, soa);
1561 if (r < 0)
1562 return r;
1563
1564 break;
1565 }
1566
1567 default: {
1568 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1569
1570 /* For other unsigned RRsets (including
1571 * NSEC/NSEC3!), look for proof the zone is
1572 * unsigned, by requesting the SOA RR of the
1573 * zone. However, do so only if they are
1574 * directly relevant to our original
1575 * question. */
1576
1577 r = dns_transaction_is_primary_response(t, rr);
1578 if (r < 0)
1579 return r;
1580 if (r == 0)
1581 continue;
1582
1583 r = dnssec_has_rrsig(t->answer, rr->key);
1584 if (r < 0)
1585 return r;
1586 if (r > 0)
1587 continue;
1588
1589 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, DNS_RESOURCE_KEY_NAME(rr->key));
1590 if (!soa)
1591 return -ENOMEM;
1592
1593 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));
1594 r = dns_transaction_request_dnssec_rr(t, soa);
1595 if (r < 0)
1596 return r;
1597 break;
1598 }}
1599 }
1600
1601 /* Above, we requested everything necessary to validate what
1602 * we got. Now, let's request what we need to validate what we
1603 * didn't get... */
1604
1605 r = dns_transaction_has_unsigned_negative_answer(t);
1606 if (r < 0)
1607 return r;
1608 if (r > 0) {
1609 const char *name;
1610
1611 name = DNS_RESOURCE_KEY_NAME(t->key);
1612
1613 /* If this was a SOA or NS request, then this
1614 * indicates that we are not at a zone apex, hence ask
1615 * the parent name instead. If this was a DS request,
1616 * then it's signed when the parent zone is signed,
1617 * hence ask the parent in that case, too. */
1618
1619 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
1620 r = dns_name_parent(&name);
1621 if (r < 0)
1622 return r;
1623 if (r > 0)
1624 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned empty SOA/NS/DS response).", t->id, DNS_RESOURCE_KEY_NAME(t->key));
1625 else
1626 name = NULL;
1627 } else
1628 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned empty non-SOA/NS/DS response).", t->id, DNS_RESOURCE_KEY_NAME(t->key));
1629
1630 if (name) {
1631 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1632
1633 soa = dns_resource_key_new(t->key->class, DNS_TYPE_SOA, name);
1634 if (!soa)
1635 return -ENOMEM;
1636
1637 r = dns_transaction_request_dnssec_rr(t, soa);
1638 if (r < 0)
1639 return r;
1640 }
1641 }
1642
1643 return dns_transaction_dnssec_is_live(t);
1644 }
1645
1646 void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source) {
1647 int r;
1648
1649 assert(t);
1650 assert(source);
1651
1652 if (!IN_SET(t->state, DNS_TRANSACTION_PENDING, DNS_TRANSACTION_VALIDATING))
1653 return;
1654
1655 /* Invoked whenever any of our auxiliary DNSSEC transactions
1656 completed its work. We copy any RRs from that transaction
1657 over into our list of validated keys -- but only if the
1658 answer is authenticated.
1659
1660 Note that we fail our transaction if the auxiliary
1661 transaction failed, except on NXDOMAIN. This is because
1662 some broken DNS servers (Akamai...) will return NXDOMAIN
1663 for empty non-terminals. */
1664
1665 switch (source->state) {
1666
1667 case DNS_TRANSACTION_DNSSEC_FAILED:
1668
1669 log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(source->answer_dnssec_result));
1670 t->answer_dnssec_result = source->answer_dnssec_result; /* Copy error code over */
1671 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
1672 break;
1673
1674 case DNS_TRANSACTION_RCODE_FAILURE:
1675
1676 if (source->answer_rcode != DNS_RCODE_NXDOMAIN) {
1677 log_debug("Auxiliary DNSSEC RR query failed with rcode=%i.", source->answer_rcode);
1678 goto fail;
1679 }
1680
1681 /* fall-through: NXDOMAIN is good enough for us */
1682
1683 case DNS_TRANSACTION_SUCCESS:
1684 if (source->answer_authenticated) {
1685 r = dns_answer_extend(&t->validated_keys, source->answer);
1686 if (r < 0) {
1687 log_error_errno(r, "Failed to merge validated DNSSEC key data: %m");
1688 goto fail;
1689 }
1690 }
1691
1692 /* If the state is still PENDING, we are still in the loop
1693 * that adds further DNSSEC transactions, hence don't check if
1694 * we are ready yet. If the state is VALIDATING however, we
1695 * should check if we are complete now. */
1696 if (t->state == DNS_TRANSACTION_VALIDATING)
1697 dns_transaction_process_dnssec(t);
1698 break;
1699
1700 default:
1701 log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(source->state));
1702 goto fail;
1703 }
1704
1705 return;
1706
1707 fail:
1708 t->answer_dnssec_result = DNSSEC_FAILED_AUXILIARY;
1709 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
1710 }
1711
1712 static int dns_transaction_validate_dnskey_by_ds(DnsTransaction *t) {
1713 DnsResourceRecord *rr;
1714 int ifindex, r;
1715
1716 assert(t);
1717
1718 /* Add all DNSKEY RRs from the answer that are validated by DS
1719 * RRs from the list of validated keys to the list of
1720 * validated keys. */
1721
1722 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, t->answer) {
1723
1724 r = dnssec_verify_dnskey_search(rr, t->validated_keys);
1725 if (r < 0)
1726 return r;
1727 if (r == 0)
1728 continue;
1729
1730 /* If so, the DNSKEY is validated too. */
1731 r = dns_answer_add_extend(&t->validated_keys, rr, ifindex, DNS_ANSWER_AUTHENTICATED);
1732 if (r < 0)
1733 return r;
1734 }
1735
1736 return 0;
1737 }
1738
1739 static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *rr) {
1740 int r;
1741
1742 assert(t);
1743 assert(rr);
1744
1745 /* Checks if the RR we are looking for must be signed with an
1746 * RRSIG. This is used for positive responses. */
1747
1748 if (t->scope->dnssec_mode == DNSSEC_NO)
1749 return false;
1750
1751 if (dns_type_is_pseudo(rr->key->type))
1752 return -EINVAL;
1753
1754 switch (rr->key->type) {
1755
1756 case DNS_TYPE_RRSIG:
1757 /* RRSIGs are the signatures themselves, they need no signing. */
1758 return false;
1759
1760 case DNS_TYPE_SOA:
1761 case DNS_TYPE_NS: {
1762 DnsTransaction *dt;
1763 Iterator i;
1764
1765 /* For SOA or NS RRs we look for a matching DS transaction */
1766
1767 SET_FOREACH(dt, t->dnssec_transactions, i) {
1768
1769 if (dt->key->class != rr->key->class)
1770 continue;
1771 if (dt->key->type != DNS_TYPE_DS)
1772 continue;
1773
1774 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), DNS_RESOURCE_KEY_NAME(rr->key));
1775 if (r < 0)
1776 return r;
1777 if (r == 0)
1778 continue;
1779
1780 /* We found a DS transactions for the SOA/NS
1781 * RRs we are looking at. If it discovered signed DS
1782 * RRs, then we need to be signed, too. */
1783
1784 if (!dt->answer_authenticated)
1785 return false;
1786
1787 return dns_answer_match_key(dt->answer, dt->key, NULL);
1788 }
1789
1790 /* We found nothing that proves this is safe to leave
1791 * this unauthenticated, hence ask inist on
1792 * authentication. */
1793 return true;
1794 }
1795
1796 case DNS_TYPE_DS:
1797 case DNS_TYPE_CNAME:
1798 case DNS_TYPE_DNAME: {
1799 const char *parent = NULL;
1800 DnsTransaction *dt;
1801 Iterator i;
1802
1803 /*
1804 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
1805 *
1806 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
1807 */
1808
1809 SET_FOREACH(dt, t->dnssec_transactions, i) {
1810
1811 if (dt->key->class != rr->key->class)
1812 continue;
1813 if (dt->key->type != DNS_TYPE_SOA)
1814 continue;
1815
1816 if (!parent) {
1817 parent = DNS_RESOURCE_KEY_NAME(rr->key);
1818 r = dns_name_parent(&parent);
1819 if (r < 0)
1820 return r;
1821 if (r == 0) {
1822 if (rr->key->type == DNS_TYPE_DS)
1823 return true;
1824
1825 /* A CNAME/DNAME without a parent? That's sooo weird. */
1826 log_debug("Transaction %" PRIu16 " claims CNAME/DNAME at root. Refusing.", t->id);
1827 return -EBADMSG;
1828 }
1829 }
1830
1831 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), parent);
1832 if (r < 0)
1833 return r;
1834 if (r == 0)
1835 continue;
1836
1837 return t->answer_authenticated;
1838 }
1839
1840 return true;
1841 }
1842
1843 default: {
1844 DnsTransaction *dt;
1845 Iterator i;
1846
1847 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
1848
1849 SET_FOREACH(dt, t->dnssec_transactions, i) {
1850
1851 if (dt->key->class != rr->key->class)
1852 continue;
1853 if (dt->key->type != DNS_TYPE_SOA)
1854 continue;
1855
1856 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), DNS_RESOURCE_KEY_NAME(rr->key));
1857 if (r < 0)
1858 return r;
1859 if (r == 0)
1860 continue;
1861
1862 /* We found the transaction that was supposed to find
1863 * the SOA RR for us. It was successful, but found no
1864 * RR for us. This means we are not at a zone cut. In
1865 * this case, we require authentication if the SOA
1866 * lookup was authenticated too. */
1867 return t->answer_authenticated;
1868 }
1869
1870 return true;
1871 }}
1872 }
1873
1874 static int dns_transaction_requires_nsec(DnsTransaction *t) {
1875 DnsTransaction *dt;
1876 const char *name;
1877 Iterator i;
1878 int r;
1879
1880 assert(t);
1881
1882 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
1883 * this negative reply */
1884
1885 if (t->scope->dnssec_mode == DNSSEC_NO)
1886 return false;
1887
1888 if (dns_type_is_pseudo(t->key->type))
1889 return -EINVAL;
1890
1891 name = DNS_RESOURCE_KEY_NAME(t->key);
1892
1893 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
1894
1895 /* We got a negative reply for this SOA/NS lookup? If
1896 * so, then we are not at a zone apex, and thus should
1897 * look at the result of the parent SOA lookup.
1898 *
1899 * We got a negative reply for this DS lookup? DS RRs
1900 * are signed when their parent zone is signed, hence
1901 * also check the parent SOA in this case. */
1902
1903 r = dns_name_parent(&name);
1904 if (r < 0)
1905 return r;
1906 if (r == 0)
1907 return true;
1908 }
1909
1910 /* For all other RRs we check the SOA on the same level to see
1911 * if it's signed. */
1912
1913 SET_FOREACH(dt, t->dnssec_transactions, i) {
1914
1915 if (dt->key->class != t->key->class)
1916 continue;
1917 if (dt->key->type != DNS_TYPE_SOA)
1918 continue;
1919
1920 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), name);
1921 if (r < 0)
1922 return r;
1923 if (r == 0)
1924 continue;
1925
1926 return dt->answer_authenticated;
1927 }
1928
1929 /* If in doubt, require NSEC/NSEC3 */
1930 return true;
1931 }
1932
1933 static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRecord *rr) {
1934 DnsResourceRecord *rrsig;
1935 bool found = false;
1936 int r;
1937
1938 /* Checks whether any of the DNSKEYs used for the RRSIGs for
1939 * the specified RRset is authenticated (i.e. has a matching
1940 * DS RR). */
1941
1942 DNS_ANSWER_FOREACH(rrsig, t->answer) {
1943 DnsTransaction *dt;
1944 Iterator i;
1945
1946 r = dnssec_key_match_rrsig(rr->key, rrsig);
1947 if (r < 0)
1948 return r;
1949 if (r == 0)
1950 continue;
1951
1952 SET_FOREACH(dt, t->dnssec_transactions, i) {
1953
1954 if (dt->key->class != rr->key->class)
1955 continue;
1956
1957 if (dt->key->type == DNS_TYPE_DNSKEY) {
1958
1959 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), rrsig->rrsig.signer);
1960 if (r < 0)
1961 return r;
1962 if (r == 0)
1963 continue;
1964
1965 /* OK, we found an auxiliary DNSKEY
1966 * lookup. If that lookup is
1967 * authenticated, report this. */
1968
1969 if (dt->answer_authenticated)
1970 return true;
1971
1972 found = true;
1973
1974 } else if (dt->key->type == DNS_TYPE_DS) {
1975
1976 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), rrsig->rrsig.signer);
1977 if (r < 0)
1978 return r;
1979 if (r == 0)
1980 continue;
1981
1982 /* OK, we found an auxiliary DS
1983 * lookup. If that lookup is
1984 * authenticated and non-zero, we
1985 * won! */
1986
1987 if (!dt->answer_authenticated)
1988 return false;
1989
1990 return dns_answer_match_key(dt->answer, dt->key, NULL);
1991 }
1992 }
1993 }
1994
1995 return found ? false : -ENXIO;
1996 }
1997
1998 static int dns_transaction_known_signed(DnsTransaction *t, DnsResourceRecord *rr) {
1999 assert(t);
2000 assert(rr);
2001
2002 /* We know that the root domain is signed, hence if it appears
2003 * not to be signed, there's a problem with the DNS server */
2004
2005 return rr->key->class == DNS_CLASS_IN &&
2006 dns_name_is_root(DNS_RESOURCE_KEY_NAME(rr->key));
2007 }
2008
2009 int dns_transaction_validate_dnssec(DnsTransaction *t) {
2010 _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
2011 bool dnskeys_finalized = false;
2012 DnsResourceRecord *rr;
2013 DnsAnswerFlags flags;
2014 int r;
2015
2016 assert(t);
2017
2018 /* We have now collected all DS and DNSKEY RRs in
2019 * t->validated_keys, let's see which RRs we can now
2020 * authenticate with that. */
2021
2022 if (t->scope->dnssec_mode == DNSSEC_NO)
2023 return 0;
2024
2025 /* Already validated */
2026 if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
2027 return 0;
2028
2029 /* Our own stuff needs no validation */
2030 if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
2031 t->answer_dnssec_result = DNSSEC_VALIDATED;
2032 t->answer_authenticated = true;
2033 return 0;
2034 }
2035
2036 /* Cached stuff is not affected by validation. */
2037 if (t->answer_source != DNS_TRANSACTION_NETWORK)
2038 return 0;
2039
2040 if (t->current_features < DNS_SERVER_FEATURE_LEVEL_DO ||
2041 (t->server && t->server->rrsig_missing)) {
2042 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
2043 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2044 return 0;
2045 }
2046
2047 log_debug("Validating response from transaction %" PRIu16 " (%s).", t->id, dns_transaction_key_string(t));
2048
2049 /* First see if there are DNSKEYs we already known a validated DS for. */
2050 r = dns_transaction_validate_dnskey_by_ds(t);
2051 if (r < 0)
2052 return r;
2053
2054 for (;;) {
2055 bool changed = false;
2056
2057 DNS_ANSWER_FOREACH(rr, t->answer) {
2058 DnssecResult result;
2059
2060 if (rr->key->type == DNS_TYPE_RRSIG)
2061 continue;
2062
2063 r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result);
2064 if (r < 0)
2065 return r;
2066
2067 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
2068
2069 if (result == DNSSEC_VALIDATED) {
2070
2071 if (rr->key->type == DNS_TYPE_DNSKEY) {
2072 /* If we just validated a
2073 * DNSKEY RRset, then let's
2074 * add these keys to the set
2075 * of validated keys for this
2076 * transaction. */
2077
2078 r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
2079 if (r < 0)
2080 return r;
2081 }
2082
2083 /* Add the validated RRset to the new
2084 * list of validated RRsets, and
2085 * remove it from the unvalidated
2086 * RRsets. We mark the RRset as
2087 * authenticated and cacheable. */
2088 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE);
2089 if (r < 0)
2090 return r;
2091
2092 t->scope->manager->n_dnssec_secure++;
2093
2094 /* Exit the loop, we dropped something from the answer, start from the beginning */
2095 changed = true;
2096 break;
2097
2098 } else if (dnskeys_finalized) {
2099
2100 /* If we haven't read all DNSKEYs yet
2101 * a negative result of the validation
2102 * is irrelevant, as there might be
2103 * more DNSKEYs coming. */
2104
2105 if (result == DNSSEC_NO_SIGNATURE) {
2106 r = dns_transaction_requires_rrsig(t, rr);
2107 if (r < 0)
2108 return r;
2109 if (r == 0) {
2110 /* Data does not require signing. In that case, just copy it over,
2111 * but remember that this is by no means authenticated.*/
2112 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2113 if (r < 0)
2114 return r;
2115
2116 t->scope->manager->n_dnssec_insecure++;
2117
2118 changed = true;
2119 break;
2120 }
2121
2122 r = dns_transaction_known_signed(t, rr);
2123 if (r < 0)
2124 return r;
2125 if (r > 0) {
2126 /* This is an RR we know has to be signed. If it isn't this means
2127 * the server is not attaching RRSIGs, hence complain. */
2128
2129 dns_server_packet_rrsig_missing(t->server);
2130
2131 if (t->scope->dnssec_mode == DNSSEC_DOWNGRADE_OK) {
2132
2133 /* Downgrading is OK? If so, just consider the information unsigned */
2134
2135 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2136 if (r < 0)
2137 return r;
2138
2139 t->scope->manager->n_dnssec_insecure++;
2140 changed = true;
2141 break;
2142 }
2143
2144 /* Otherwise, fail */
2145 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2146 return 0;
2147 }
2148 }
2149
2150 if (IN_SET(result,
2151 DNSSEC_MISSING_KEY,
2152 DNSSEC_SIGNATURE_EXPIRED,
2153 DNSSEC_UNSUPPORTED_ALGORITHM)) {
2154
2155 r = dns_transaction_dnskey_authenticated(t, rr);
2156 if (r < 0 && r != -ENXIO)
2157 return r;
2158 if (r == 0) {
2159 /* The DNSKEY transaction was not authenticated, this means there's
2160 * no DS for this, which means it's OK if no keys are found for this signature. */
2161
2162 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
2163 if (r < 0)
2164 return r;
2165
2166 t->scope->manager->n_dnssec_insecure++;
2167
2168 changed = true;
2169 break;
2170 }
2171 }
2172
2173 if (IN_SET(result,
2174 DNSSEC_INVALID,
2175 DNSSEC_SIGNATURE_EXPIRED,
2176 DNSSEC_NO_SIGNATURE,
2177 DNSSEC_UNSUPPORTED_ALGORITHM))
2178 t->scope->manager->n_dnssec_bogus++;
2179 else
2180 t->scope->manager->n_dnssec_indeterminate++;
2181
2182 r = dns_transaction_is_primary_response(t, rr);
2183 if (r < 0)
2184 return r;
2185 if (r > 0) {
2186 /* This is a primary response
2187 * to our question, and it
2188 * failed validation. That's
2189 * fatal. */
2190 t->answer_dnssec_result = result;
2191 return 0;
2192 }
2193
2194 /* This is just some auxiliary
2195 * data. Just remove the RRset and
2196 * continue. */
2197 r = dns_answer_remove_by_key(&t->answer, rr->key);
2198 if (r < 0)
2199 return r;
2200
2201 /* Exit the loop, we dropped something from the answer, start from the beginning */
2202 changed = true;
2203 break;
2204 }
2205 }
2206
2207 if (changed)
2208 continue;
2209
2210 if (!dnskeys_finalized) {
2211 /* OK, now we know we have added all DNSKEYs
2212 * we possibly could to our validated
2213 * list. Now run the whole thing once more,
2214 * and strip everything we still cannot
2215 * validate.
2216 */
2217 dnskeys_finalized = true;
2218 continue;
2219 }
2220
2221 /* We're done */
2222 break;
2223 }
2224
2225 dns_answer_unref(t->answer);
2226 t->answer = validated;
2227 validated = NULL;
2228
2229 /* At this point the answer only contains validated
2230 * RRsets. Now, let's see if it actually answers the question
2231 * we asked. If so, great! If it doesn't, then see if
2232 * NSEC/NSEC3 can prove this. */
2233 r = dns_transaction_has_positive_answer(t, &flags);
2234 if (r > 0) {
2235 /* Yes, it answers the question! */
2236
2237 if (flags & DNS_ANSWER_AUTHENTICATED) {
2238 /* The answer is fully authenticated, yay. */
2239 t->answer_dnssec_result = DNSSEC_VALIDATED;
2240 t->answer_rcode = DNS_RCODE_SUCCESS;
2241 t->answer_authenticated = true;
2242 } else {
2243 /* The answer is not fully authenticated. */
2244 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2245 t->answer_authenticated = false;
2246 }
2247
2248 } else if (r == 0) {
2249 DnssecNsecResult nr;
2250 bool authenticated = false;
2251
2252 /* Bummer! Let's check NSEC/NSEC3 */
2253 r = dnssec_test_nsec(t->answer, t->key, &nr, &authenticated);
2254 if (r < 0)
2255 return r;
2256
2257 switch (nr) {
2258
2259 case DNSSEC_NSEC_NXDOMAIN:
2260 /* NSEC proves the domain doesn't exist. Very good. */
2261 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
2262 t->answer_dnssec_result = DNSSEC_VALIDATED;
2263 t->answer_rcode = DNS_RCODE_NXDOMAIN;
2264 t->answer_authenticated = authenticated;
2265 break;
2266
2267 case DNSSEC_NSEC_NODATA:
2268 /* NSEC proves that there's no data here, very good. */
2269 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
2270 t->answer_dnssec_result = DNSSEC_VALIDATED;
2271 t->answer_rcode = DNS_RCODE_SUCCESS;
2272 t->answer_authenticated = authenticated;
2273 break;
2274
2275 case DNSSEC_NSEC_OPTOUT:
2276 /* NSEC3 says the data might not be signed */
2277 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
2278 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2279 t->answer_authenticated = false;
2280 break;
2281
2282 case DNSSEC_NSEC_NO_RR:
2283 /* No NSEC data? Bummer! */
2284
2285 r = dns_transaction_requires_nsec(t);
2286 if (r < 0)
2287 return r;
2288 if (r > 0)
2289 t->answer_dnssec_result = DNSSEC_NO_SIGNATURE;
2290 else {
2291 t->answer_dnssec_result = DNSSEC_UNSIGNED;
2292 t->answer_authenticated = false;
2293 }
2294
2295 break;
2296
2297 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM:
2298 /* We don't know the NSEC3 algorithm used? */
2299 t->answer_dnssec_result = DNSSEC_UNSUPPORTED_ALGORITHM;
2300 break;
2301
2302 case DNSSEC_NSEC_FOUND:
2303 case DNSSEC_NSEC_CNAME:
2304 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
2305 t->answer_dnssec_result = DNSSEC_NSEC_MISMATCH;
2306 break;
2307
2308 default:
2309 assert_not_reached("Unexpected NSEC result.");
2310 }
2311 }
2312
2313 return 1;
2314 }
2315
2316 const char *dns_transaction_key_string(DnsTransaction *t) {
2317 assert(t);
2318
2319 if (!t->key_string) {
2320 if (dns_resource_key_to_string(t->key, &t->key_string) < 0)
2321 return "n/a";
2322 }
2323
2324 return strstrip(t->key_string);
2325 }
2326
2327 static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
2328 [DNS_TRANSACTION_NULL] = "null",
2329 [DNS_TRANSACTION_PENDING] = "pending",
2330 [DNS_TRANSACTION_VALIDATING] = "validating",
2331 [DNS_TRANSACTION_RCODE_FAILURE] = "rcode-failure",
2332 [DNS_TRANSACTION_SUCCESS] = "success",
2333 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
2334 [DNS_TRANSACTION_TIMEOUT] = "timeout",
2335 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
2336 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
2337 [DNS_TRANSACTION_RESOURCES] = "resources",
2338 [DNS_TRANSACTION_CONNECTION_FAILURE] = "connection-failure",
2339 [DNS_TRANSACTION_ABORTED] = "aborted",
2340 [DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
2341 };
2342 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
2343
2344 static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
2345 [DNS_TRANSACTION_NETWORK] = "network",
2346 [DNS_TRANSACTION_CACHE] = "cache",
2347 [DNS_TRANSACTION_ZONE] = "zone",
2348 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
2349 };
2350 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);