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