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