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