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