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