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