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