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