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