1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include "sd-messages.h"
4 
5 #include "af-list.h"
6 #include "alloc-util.h"
7 #include "dns-domain.h"
8 #include "errno-list.h"
9 #include "errno-util.h"
10 #include "fd-util.h"
11 #include "random-util.h"
12 #include "resolved-dns-cache.h"
13 #include "resolved-dns-transaction.h"
14 #include "resolved-dnstls.h"
15 #include "resolved-llmnr.h"
16 #include "string-table.h"
17 
18 #define TRANSACTIONS_MAX 4096
19 #define TRANSACTION_TCP_TIMEOUT_USEC (10U*USEC_PER_SEC)
20 
21 /* After how much time to repeat classic DNS requests */
22 #define DNS_TIMEOUT_USEC (SD_RESOLVED_QUERY_TIMEOUT_USEC / DNS_TRANSACTION_ATTEMPTS_MAX)
23 
dns_transaction_reset_answer(DnsTransaction * t)24 static void dns_transaction_reset_answer(DnsTransaction *t) {
25         assert(t);
26 
27         t->received = dns_packet_unref(t->received);
28         t->answer = dns_answer_unref(t->answer);
29         t->answer_rcode = 0;
30         t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
31         t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
32         t->answer_query_flags = 0;
33         t->answer_nsec_ttl = UINT32_MAX;
34         t->answer_errno = 0;
35 }
36 
dns_transaction_flush_dnssec_transactions(DnsTransaction * t)37 static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) {
38         DnsTransaction *z;
39 
40         assert(t);
41 
42         while ((z = set_steal_first(t->dnssec_transactions))) {
43                 set_remove(z->notify_transactions, t);
44                 set_remove(z->notify_transactions_done, t);
45                 dns_transaction_gc(z);
46         }
47 }
48 
dns_transaction_close_connection(DnsTransaction * t,bool use_graveyard)49 static void dns_transaction_close_connection(
50                 DnsTransaction *t,
51                 bool use_graveyard) { /* Set use_graveyard = false when you know the connection is already
52                                        * dead, for example because you got a connection error back from the
53                                        * kernel. In that case there's no point in keeping the fd around,
54                                        * hence don't. */
55         int r;
56 
57         assert(t);
58 
59         if (t->stream) {
60                 /* Let's detach the stream from our transaction, in case something else keeps a reference to it. */
61                 LIST_REMOVE(transactions_by_stream, t->stream->transactions, t);
62 
63                 /* Remove packet in case it's still in the queue */
64                 dns_packet_unref(ordered_set_remove(t->stream->write_queue, t->sent));
65 
66                 t->stream = dns_stream_unref(t->stream);
67         }
68 
69         t->dns_udp_event_source = sd_event_source_disable_unref(t->dns_udp_event_source);
70 
71         /* If we have an UDP socket where we sent a packet, but never received one, then add it to the socket
72          * graveyard, instead of closing it right away. That way it will stick around for a moment longer,
73          * and the reply we might still get from the server will be eaten up instead of resulting in an ICMP
74          * port unreachable error message. */
75 
76         if (use_graveyard && t->dns_udp_fd >= 0 && t->sent && !t->received) {
77                 r = manager_add_socket_to_graveyard(t->scope->manager, t->dns_udp_fd);
78                 if (r < 0)
79                         log_debug_errno(r, "Failed to add UDP socket to graveyard, closing immediately: %m");
80                 else
81                         TAKE_FD(t->dns_udp_fd);
82         }
83 
84         t->dns_udp_fd = safe_close(t->dns_udp_fd);
85 }
86 
dns_transaction_stop_timeout(DnsTransaction * t)87 static void dns_transaction_stop_timeout(DnsTransaction *t) {
88         assert(t);
89 
90         t->timeout_event_source = sd_event_source_disable_unref(t->timeout_event_source);
91 }
92 
dns_transaction_free(DnsTransaction * t)93 DnsTransaction* dns_transaction_free(DnsTransaction *t) {
94         DnsQueryCandidate *c;
95         DnsZoneItem *i;
96         DnsTransaction *z;
97 
98         if (!t)
99                 return NULL;
100 
101         log_debug("Freeing transaction %" PRIu16 ".", t->id);
102 
103         dns_transaction_close_connection(t, true);
104         dns_transaction_stop_timeout(t);
105 
106         dns_packet_unref(t->sent);
107         dns_transaction_reset_answer(t);
108 
109         dns_server_unref(t->server);
110 
111         if (t->scope) {
112                 if (t->key) {
113                         DnsTransaction *first;
114 
115                         first = hashmap_get(t->scope->transactions_by_key, t->key);
116                         LIST_REMOVE(transactions_by_key, first, t);
117                         if (first)
118                                 hashmap_replace(t->scope->transactions_by_key, first->key, first);
119                         else
120                                 hashmap_remove(t->scope->transactions_by_key, t->key);
121                 }
122 
123                 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
124 
125                 if (t->id != 0)
126                         hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
127         }
128 
129         while ((c = set_steal_first(t->notify_query_candidates)))
130                 set_remove(c->transactions, t);
131         set_free(t->notify_query_candidates);
132 
133         while ((c = set_steal_first(t->notify_query_candidates_done)))
134                 set_remove(c->transactions, t);
135         set_free(t->notify_query_candidates_done);
136 
137         while ((i = set_steal_first(t->notify_zone_items)))
138                 i->probe_transaction = NULL;
139         set_free(t->notify_zone_items);
140 
141         while ((i = set_steal_first(t->notify_zone_items_done)))
142                 i->probe_transaction = NULL;
143         set_free(t->notify_zone_items_done);
144 
145         while ((z = set_steal_first(t->notify_transactions)))
146                 set_remove(z->dnssec_transactions, t);
147         set_free(t->notify_transactions);
148 
149         while ((z = set_steal_first(t->notify_transactions_done)))
150                 set_remove(z->dnssec_transactions, t);
151         set_free(t->notify_transactions_done);
152 
153         dns_transaction_flush_dnssec_transactions(t);
154         set_free(t->dnssec_transactions);
155 
156         dns_answer_unref(t->validated_keys);
157         dns_resource_key_unref(t->key);
158         dns_packet_unref(t->bypass);
159 
160         return mfree(t);
161 }
162 
163 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
164 
dns_transaction_gc(DnsTransaction * t)165 DnsTransaction* dns_transaction_gc(DnsTransaction *t) {
166         assert(t);
167 
168         /* Returns !NULL if we can't gc yet. */
169 
170         if (t->block_gc > 0)
171                 return t;
172 
173         if (set_isempty(t->notify_query_candidates) &&
174             set_isempty(t->notify_query_candidates_done) &&
175             set_isempty(t->notify_zone_items) &&
176             set_isempty(t->notify_zone_items_done) &&
177             set_isempty(t->notify_transactions) &&
178             set_isempty(t->notify_transactions_done))
179                 return dns_transaction_free(t);
180 
181         return t;
182 }
183 
pick_new_id(Manager * m)184 static uint16_t pick_new_id(Manager *m) {
185         uint16_t new_id;
186 
187         /* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the
188          * number of transactions, and it's much lower than the space of IDs. */
189 
190         assert_cc(TRANSACTIONS_MAX < 0xFFFF);
191 
192         do
193                 random_bytes(&new_id, sizeof(new_id));
194         while (new_id == 0 ||
195                hashmap_get(m->dns_transactions, UINT_TO_PTR(new_id)));
196 
197         return new_id;
198 }
199 
key_ok(DnsScope * scope,DnsResourceKey * key)200 static int key_ok(
201                 DnsScope *scope,
202                 DnsResourceKey *key) {
203 
204         /* Don't allow looking up invalid or pseudo RRs */
205         if (!dns_type_is_valid_query(key->type))
206                 return -EINVAL;
207         if (dns_type_is_obsolete(key->type))
208                 return -EOPNOTSUPP;
209 
210         /* We only support the IN class */
211         if (!IN_SET(key->class, DNS_CLASS_IN, DNS_CLASS_ANY))
212                 return -EOPNOTSUPP;
213 
214         /* Don't allows DNSSEC RRs to be looked up via LLMNR/mDNS. They don't really make sense
215          * there, and it speeds up our queries if we refuse this early */
216         if (scope->protocol != DNS_PROTOCOL_DNS &&
217             dns_type_is_dnssec(key->type))
218                 return -EOPNOTSUPP;
219 
220         return 0;
221 }
222 
dns_transaction_new(DnsTransaction ** ret,DnsScope * s,DnsResourceKey * key,DnsPacket * bypass,uint64_t query_flags)223 int dns_transaction_new(
224                 DnsTransaction **ret,
225                 DnsScope *s,
226                 DnsResourceKey *key,
227                 DnsPacket *bypass,
228                 uint64_t query_flags) {
229 
230         _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
231         int r;
232 
233         assert(ret);
234         assert(s);
235 
236         if (key) {
237                 assert(!bypass);
238 
239                 r = key_ok(s, key);
240                 if (r < 0)
241                         return r;
242         } else {
243                 DnsResourceKey *qk;
244                 assert(bypass);
245 
246                 r = dns_packet_validate_query(bypass);
247                 if (r < 0)
248                         return r;
249 
250                 DNS_QUESTION_FOREACH(qk, bypass->question) {
251                         r = key_ok(s, qk);
252                         if (r < 0)
253                                 return r;
254                 }
255         }
256 
257         if (hashmap_size(s->manager->dns_transactions) >= TRANSACTIONS_MAX)
258                 return -EBUSY;
259 
260         r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
261         if (r < 0)
262                 return r;
263 
264         if (key) {
265                 r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
266                 if (r < 0)
267                         return r;
268         }
269 
270         t = new(DnsTransaction, 1);
271         if (!t)
272                 return -ENOMEM;
273 
274         *t = (DnsTransaction) {
275                 .dns_udp_fd = -1,
276                 .answer_source = _DNS_TRANSACTION_SOURCE_INVALID,
277                 .answer_dnssec_result = _DNSSEC_RESULT_INVALID,
278                 .answer_nsec_ttl = UINT32_MAX,
279                 .key = dns_resource_key_ref(key),
280                 .query_flags = query_flags,
281                 .bypass = dns_packet_ref(bypass),
282                 .current_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID,
283                 .clamp_feature_level_servfail = _DNS_SERVER_FEATURE_LEVEL_INVALID,
284                 .clamp_feature_level_nxdomain = _DNS_SERVER_FEATURE_LEVEL_INVALID,
285                 .id = pick_new_id(s->manager),
286         };
287 
288         r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
289         if (r < 0) {
290                 t->id = 0;
291                 return r;
292         }
293 
294         if (t->key) {
295                 DnsTransaction *first;
296 
297                 first = hashmap_get(s->transactions_by_key, t->key);
298                 LIST_PREPEND(transactions_by_key, first, t);
299 
300                 r = hashmap_replace(s->transactions_by_key, first->key, first);
301                 if (r < 0) {
302                         LIST_REMOVE(transactions_by_key, first, t);
303                         return r;
304                 }
305         }
306 
307         LIST_PREPEND(transactions_by_scope, s->transactions, t);
308         t->scope = s;
309 
310         s->manager->n_transactions_total++;
311 
312         if (ret)
313                 *ret = t;
314 
315         TAKE_PTR(t);
316         return 0;
317 }
318 
dns_transaction_shuffle_id(DnsTransaction * t)319 static void dns_transaction_shuffle_id(DnsTransaction *t) {
320         uint16_t new_id;
321         assert(t);
322 
323         /* Pick a new ID for this transaction. */
324 
325         new_id = pick_new_id(t->scope->manager);
326         assert_se(hashmap_remove_and_put(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id), UINT_TO_PTR(new_id), t) >= 0);
327 
328         log_debug("Transaction %" PRIu16 " is now %" PRIu16 ".", t->id, new_id);
329         t->id = new_id;
330 
331         /* Make sure we generate a new packet with the new ID */
332         t->sent = dns_packet_unref(t->sent);
333 }
334 
dns_transaction_tentative(DnsTransaction * t,DnsPacket * p)335 static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
336         _cleanup_free_ char *pretty = NULL;
337         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
338         DnsZoneItem *z;
339 
340         assert(t);
341         assert(p);
342         assert(t->scope->protocol == DNS_PROTOCOL_LLMNR);
343 
344         if (manager_packet_from_local_address(t->scope->manager, p) != 0)
345                 return;
346 
347         (void) in_addr_to_string(p->family, &p->sender, &pretty);
348 
349         log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s got tentative packet from %s.",
350                   t->id,
351                   dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str),
352                   dns_protocol_to_string(t->scope->protocol),
353                   t->scope->link ? t->scope->link->ifname : "*",
354                   af_to_name_short(t->scope->family),
355                   strnull(pretty));
356 
357         /* RFC 4795, Section 4.1 says that the peer with the
358          * lexicographically smaller IP address loses */
359         if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
360                 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
361                 return;
362         }
363 
364         log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
365 
366         t->block_gc++;
367 
368         while ((z = set_first(t->notify_zone_items))) {
369                 /* First, make sure the zone item drops the reference
370                  * to us */
371                 dns_zone_item_probe_stop(z);
372 
373                 /* Secondly, report this as conflict, so that we might
374                  * look for a different hostname */
375                 dns_zone_item_conflict(z);
376         }
377         t->block_gc--;
378 
379         dns_transaction_gc(t);
380 }
381 
dns_transaction_complete(DnsTransaction * t,DnsTransactionState state)382 void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
383         DnsQueryCandidate *c;
384         DnsZoneItem *z;
385         DnsTransaction *d;
386         const char *st;
387         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
388 
389         assert(t);
390         assert(!DNS_TRANSACTION_IS_LIVE(state));
391 
392         if (state == DNS_TRANSACTION_DNSSEC_FAILED) {
393                 dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str);
394 
395                 log_struct(LOG_NOTICE,
396                            "MESSAGE_ID=" SD_MESSAGE_DNSSEC_FAILURE_STR,
397                            LOG_MESSAGE("DNSSEC validation failed for question %s: %s",
398                                        key_str, dnssec_result_to_string(t->answer_dnssec_result)),
399                            "DNS_TRANSACTION=%" PRIu16, t->id,
400                            "DNS_QUESTION=%s", key_str,
401                            "DNSSEC_RESULT=%s", dnssec_result_to_string(t->answer_dnssec_result),
402                            "DNS_SERVER=%s", strna(dns_server_string_full(t->server)),
403                            "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t->server->possible_feature_level));
404         }
405 
406         /* Note that this call might invalidate the query. Callers
407          * should hence not attempt to access the query or transaction
408          * after calling this function. */
409 
410         if (state == DNS_TRANSACTION_ERRNO)
411                 st = errno_to_name(t->answer_errno);
412         else
413                 st = dns_transaction_state_to_string(state);
414 
415         log_debug("%s transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s; %s).",
416                   t->bypass ? "Bypass" : "Regular",
417                   t->id,
418                   dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str),
419                   dns_protocol_to_string(t->scope->protocol),
420                   t->scope->link ? t->scope->link->ifname : "*",
421                   af_to_name_short(t->scope->family),
422                   st,
423                   t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
424                   FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) ? "not validated" :
425                   (FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED) ? "authenticated" : "unsigned"),
426                   FLAGS_SET(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL) ? "confidential" : "non-confidential");
427 
428         t->state = state;
429 
430         dns_transaction_close_connection(t, true);
431         dns_transaction_stop_timeout(t);
432 
433         /* Notify all queries that are interested, but make sure the
434          * transaction isn't freed while we are still looking at it */
435         t->block_gc++;
436 
437         SET_FOREACH_MOVE(c, t->notify_query_candidates_done, t->notify_query_candidates)
438                 dns_query_candidate_notify(c);
439         SWAP_TWO(t->notify_query_candidates, t->notify_query_candidates_done);
440 
441         SET_FOREACH_MOVE(z, t->notify_zone_items_done, t->notify_zone_items)
442                 dns_zone_item_notify(z);
443         SWAP_TWO(t->notify_zone_items, t->notify_zone_items_done);
444         if (t->probing && t->state == DNS_TRANSACTION_ATTEMPTS_MAX_REACHED)
445                 (void) dns_scope_announce(t->scope, false);
446 
447         SET_FOREACH_MOVE(d, t->notify_transactions_done, t->notify_transactions)
448                 dns_transaction_notify(d, t);
449         SWAP_TWO(t->notify_transactions, t->notify_transactions_done);
450 
451         t->block_gc--;
452         dns_transaction_gc(t);
453 }
454 
dns_transaction_complete_errno(DnsTransaction * t,int error)455 static void dns_transaction_complete_errno(DnsTransaction *t, int error) {
456         assert(t);
457         assert(error != 0);
458 
459         t->answer_errno = abs(error);
460         dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
461 }
462 
dns_transaction_pick_server(DnsTransaction * t)463 static int dns_transaction_pick_server(DnsTransaction *t) {
464         DnsServer *server;
465 
466         assert(t);
467         assert(t->scope->protocol == DNS_PROTOCOL_DNS);
468 
469         /* Pick a DNS server and a feature level for it. */
470 
471         server = dns_scope_get_dns_server(t->scope);
472         if (!server)
473                 return -ESRCH;
474 
475         /* If we changed the server invalidate the feature level clamping, as the new server might have completely
476          * different properties. */
477         if (server != t->server) {
478                 t->clamp_feature_level_servfail = _DNS_SERVER_FEATURE_LEVEL_INVALID;
479                 t->clamp_feature_level_nxdomain = _DNS_SERVER_FEATURE_LEVEL_INVALID;
480         }
481 
482         t->current_feature_level = dns_server_possible_feature_level(server);
483 
484         /* Clamp the feature level if that is requested. */
485         if (t->clamp_feature_level_servfail != _DNS_SERVER_FEATURE_LEVEL_INVALID &&
486             t->current_feature_level > t->clamp_feature_level_servfail)
487                 t->current_feature_level = t->clamp_feature_level_servfail;
488         if (t->clamp_feature_level_nxdomain != _DNS_SERVER_FEATURE_LEVEL_INVALID &&
489             t->current_feature_level > t->clamp_feature_level_nxdomain)
490                 t->current_feature_level = t->clamp_feature_level_nxdomain;
491 
492         log_debug("Using feature level %s for transaction %u.", dns_server_feature_level_to_string(t->current_feature_level), t->id);
493 
494         if (server == t->server)
495                 return 0;
496 
497         dns_server_unref(t->server);
498         t->server = dns_server_ref(server);
499 
500         t->n_picked_servers ++;
501 
502         log_debug("Using DNS server %s for transaction %u.", strna(dns_server_string_full(t->server)), t->id);
503 
504         return 1;
505 }
506 
dns_transaction_retry(DnsTransaction * t,bool next_server)507 static void dns_transaction_retry(DnsTransaction *t, bool next_server) {
508         int r;
509 
510         assert(t);
511 
512         /* Retries the transaction as it is, possibly on a different server */
513 
514         if (next_server && t->scope->protocol == DNS_PROTOCOL_DNS)
515                 log_debug("Retrying transaction %" PRIu16 ", after switching servers.", t->id);
516         else
517                 log_debug("Retrying transaction %" PRIu16 ".", t->id);
518 
519         /* Before we try again, switch to a new server. */
520         if (next_server)
521                 dns_scope_next_dns_server(t->scope, t->server);
522 
523         r = dns_transaction_go(t);
524         if (r < 0)
525                 dns_transaction_complete_errno(t, r);
526 }
527 
dns_transaction_limited_retry(DnsTransaction * t)528 static bool dns_transaction_limited_retry(DnsTransaction *t) {
529         assert(t);
530 
531         /* If we haven't tried all different servers yet, let's try again with a different server */
532 
533         if (t->n_picked_servers >= dns_scope_get_n_dns_servers(t->scope))
534                 return false;
535 
536         dns_transaction_retry(t, /* next_server= */ true);
537         return true;
538 }
539 
dns_transaction_maybe_restart(DnsTransaction * t)540 static int dns_transaction_maybe_restart(DnsTransaction *t) {
541         int r;
542 
543         assert(t);
544 
545         /* Restarts the transaction, under a new ID if the feature level of the server changed since we first
546          * tried, without changing DNS server. Returns > 0 if the transaction was restarted, 0 if not. */
547 
548         if (!t->server)
549                 return 0;
550 
551         if (t->current_feature_level <= dns_server_possible_feature_level(t->server))
552                 return 0;
553 
554         /* The server's current feature level is lower than when we sent the original query. We learnt something from
555            the response or possibly an auxiliary DNSSEC response that we didn't know before.  We take that as reason to
556            restart the whole transaction. This is a good idea to deal with servers that respond rubbish if we include
557            OPT RR or DO bit. One of these cases is documented here, for example:
558            https://open.nlnetlabs.nl/pipermail/dnssec-trigger/2014-November/000376.html */
559 
560         log_debug("Server feature level is now lower than when we began our transaction. Restarting with new ID.");
561         dns_transaction_shuffle_id(t);
562 
563         r = dns_transaction_go(t);
564         if (r < 0)
565                 return r;
566 
567         return 1;
568 }
569 
on_transaction_stream_error(DnsTransaction * t,int error)570 static void on_transaction_stream_error(DnsTransaction *t, int error) {
571         assert(t);
572 
573         dns_transaction_close_connection(t, true);
574 
575         if (ERRNO_IS_DISCONNECT(error)) {
576                 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
577                         /* If the LLMNR/TCP connection failed, the host doesn't support LLMNR, and we cannot answer the
578                          * question on this scope. */
579                         dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
580                         return;
581                 }
582 
583                 dns_transaction_retry(t, true);
584                 return;
585         }
586         if (error != 0)
587                 dns_transaction_complete_errno(t, error);
588 }
589 
dns_transaction_on_stream_packet(DnsTransaction * t,DnsStream * s,DnsPacket * p)590 static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsStream *s, DnsPacket *p) {
591         bool encrypted;
592 
593         assert(t);
594         assert(s);
595         assert(p);
596 
597         encrypted = s->encrypted;
598 
599         dns_transaction_close_connection(t, true);
600 
601         if (dns_packet_validate_reply(p) <= 0) {
602                 log_debug("Invalid TCP reply packet.");
603                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
604                 return 0;
605         }
606 
607         dns_scope_check_conflicts(t->scope, p);
608 
609         t->block_gc++;
610         dns_transaction_process_reply(t, p, encrypted);
611         t->block_gc--;
612 
613         /* If the response wasn't useful, then complete the transition
614          * now. After all, we are the worst feature set now with TCP
615          * sockets, and there's really no point in retrying. */
616         if (t->state == DNS_TRANSACTION_PENDING)
617                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
618         else
619                 dns_transaction_gc(t);
620 
621         return 0;
622 }
623 
on_stream_complete(DnsStream * s,int error)624 static int on_stream_complete(DnsStream *s, int error) {
625         assert(s);
626 
627         if (ERRNO_IS_DISCONNECT(error) && s->protocol != DNS_PROTOCOL_LLMNR) {
628                 log_debug_errno(error, "Connection failure for DNS TCP stream: %m");
629 
630                 if (s->transactions) {
631                         DnsTransaction *t;
632 
633                         t = s->transactions;
634                         dns_server_packet_lost(t->server, IPPROTO_TCP, t->current_feature_level);
635                 }
636         }
637 
638         if (error != 0)
639                 LIST_FOREACH(transactions_by_stream, t, s->transactions)
640                         on_transaction_stream_error(t, error);
641 
642         return 0;
643 }
644 
on_stream_packet(DnsStream * s,DnsPacket * p)645 static int on_stream_packet(DnsStream *s, DnsPacket *p) {
646         DnsTransaction *t;
647 
648         assert(s);
649         assert(s->manager);
650         assert(p);
651 
652         t = hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
653         if (t && t->stream == s) /* Validate that the stream we got this on actually is the stream the
654                                   * transaction was using. */
655                 return dns_transaction_on_stream_packet(t, s, p);
656 
657         /* Ignore incorrect transaction id as an old transaction can have been canceled. */
658         log_debug("Received unexpected TCP reply packet with id %" PRIu16 ", ignoring.", DNS_PACKET_ID(p));
659         return 0;
660 }
661 
dns_transaction_port(DnsTransaction * t)662 static uint16_t dns_transaction_port(DnsTransaction *t) {
663         assert(t);
664 
665         if (t->server->port > 0)
666                 return t->server->port;
667 
668         return DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level) ? 853 : 53;
669 }
670 
dns_transaction_emit_tcp(DnsTransaction * t)671 static int dns_transaction_emit_tcp(DnsTransaction *t) {
672         usec_t stream_timeout_usec = DNS_STREAM_DEFAULT_TIMEOUT_USEC;
673         _cleanup_(dns_stream_unrefp) DnsStream *s = NULL;
674         _cleanup_close_ int fd = -1;
675         union sockaddr_union sa;
676         DnsStreamType type;
677         int r;
678 
679         assert(t);
680         assert(t->sent);
681 
682         dns_transaction_close_connection(t, true);
683 
684         switch (t->scope->protocol) {
685 
686         case DNS_PROTOCOL_DNS:
687                 r = dns_transaction_pick_server(t);
688                 if (r < 0)
689                         return r;
690 
691                 if (manager_server_is_stub(t->scope->manager, t->server))
692                         return -ELOOP;
693 
694                 if (!t->bypass) {
695                         if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(dns_transaction_key(t)->type))
696                                 return -EOPNOTSUPP;
697 
698                         r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
699                         if (r < 0)
700                                 return r;
701                 }
702 
703                 if (t->server->stream && (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level) == t->server->stream->encrypted))
704                         s = dns_stream_ref(t->server->stream);
705                 else
706                         fd = dns_scope_socket_tcp(t->scope, AF_UNSPEC, NULL, t->server, dns_transaction_port(t), &sa);
707 
708                 /* Lower timeout in DNS-over-TLS opportunistic mode. In environments where DoT is blocked
709                  * without ICMP response overly long delays when contacting DoT servers are nasty, in
710                  * particular if multiple DNS servers are defined which we try in turn and all are
711                  * blocked. Hence, substantially lower the timeout in that case. */
712                 if (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level) &&
713                     dns_server_get_dns_over_tls_mode(t->server) == DNS_OVER_TLS_OPPORTUNISTIC)
714                         stream_timeout_usec = DNS_STREAM_OPPORTUNISTIC_TLS_TIMEOUT_USEC;
715 
716                 type = DNS_STREAM_LOOKUP;
717                 break;
718 
719         case DNS_PROTOCOL_LLMNR:
720                 /* When we already received a reply to this (but it was truncated), send to its sender address */
721                 if (t->received)
722                         fd = dns_scope_socket_tcp(t->scope, t->received->family, &t->received->sender, NULL, t->received->sender_port, &sa);
723                 else {
724                         union in_addr_union address;
725                         int family = AF_UNSPEC;
726 
727                         /* Otherwise, try to talk to the owner of a
728                          * the IP address, in case this is a reverse
729                          * PTR lookup */
730 
731                         r = dns_name_address(dns_resource_key_name(dns_transaction_key(t)), &family, &address);
732                         if (r < 0)
733                                 return r;
734                         if (r == 0)
735                                 return -EINVAL;
736                         if (family != t->scope->family)
737                                 return -ESRCH;
738 
739                         fd = dns_scope_socket_tcp(t->scope, family, &address, NULL, LLMNR_PORT, &sa);
740                 }
741 
742                 type = DNS_STREAM_LLMNR_SEND;
743                 break;
744 
745         default:
746                 return -EAFNOSUPPORT;
747         }
748 
749         if (!s) {
750                 if (fd < 0)
751                         return fd;
752 
753                 r = dns_stream_new(t->scope->manager, &s, type, t->scope->protocol, fd, &sa,
754                                    on_stream_packet, on_stream_complete, stream_timeout_usec);
755                 if (r < 0)
756                         return r;
757 
758                 fd = -1;
759 
760 #if ENABLE_DNS_OVER_TLS
761                 if (t->scope->protocol == DNS_PROTOCOL_DNS &&
762                     DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level)) {
763 
764                         assert(t->server);
765                         r = dnstls_stream_connect_tls(s, t->server);
766                         if (r < 0)
767                                 return r;
768                 }
769 #endif
770 
771                 if (t->server) {
772                         dns_server_unref_stream(t->server);
773                         s->server = dns_server_ref(t->server);
774                         t->server->stream = dns_stream_ref(s);
775                 }
776 
777                 /* The interface index is difficult to determine if we are
778                  * connecting to the local host, hence fill this in right away
779                  * instead of determining it from the socket */
780                 s->ifindex = dns_scope_ifindex(t->scope);
781         }
782 
783         t->stream = TAKE_PTR(s);
784         LIST_PREPEND(transactions_by_stream, t->stream->transactions, t);
785 
786         r = dns_stream_write_packet(t->stream, t->sent);
787         if (r < 0) {
788                 dns_transaction_close_connection(t, /* use_graveyard= */ false);
789                 return r;
790         }
791 
792         dns_transaction_reset_answer(t);
793 
794         t->tried_stream = true;
795 
796         return 0;
797 }
798 
dns_transaction_cache_answer(DnsTransaction * t)799 static void dns_transaction_cache_answer(DnsTransaction *t) {
800         assert(t);
801 
802         /* For mDNS we cache whenever we get the packet, rather than
803          * in each transaction. */
804         if (!IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR))
805                 return;
806 
807         /* Caching disabled? */
808         if (t->scope->manager->enable_cache == DNS_CACHE_MODE_NO)
809                 return;
810 
811         /* If validation is turned off for this transaction, but DNSSEC is on, then let's not cache this */
812         if (FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) && t->scope->dnssec_mode != DNSSEC_NO)
813                 return;
814 
815         /* Packet from localhost? */
816         if (!t->scope->manager->cache_from_localhost &&
817             in_addr_is_localhost(t->received->family, &t->received->sender) != 0)
818                 return;
819 
820         dns_cache_put(&t->scope->cache,
821                       t->scope->manager->enable_cache,
822                       dns_transaction_key(t),
823                       t->answer_rcode,
824                       t->answer,
825                       DNS_PACKET_CD(t->received) ? t->received : NULL, /* only cache full packets with CD on,
826                                                                         * since our usecase for caching them
827                                                                         * is "bypass" mode which is only
828                                                                         * enabled for CD packets. */
829                       t->answer_query_flags,
830                       t->answer_dnssec_result,
831                       t->answer_nsec_ttl,
832                       t->received->family,
833                       &t->received->sender);
834 }
835 
dns_transaction_dnssec_is_live(DnsTransaction * t)836 static bool dns_transaction_dnssec_is_live(DnsTransaction *t) {
837         DnsTransaction *dt;
838 
839         assert(t);
840 
841         SET_FOREACH(dt, t->dnssec_transactions)
842                 if (DNS_TRANSACTION_IS_LIVE(dt->state))
843                         return true;
844 
845         return false;
846 }
847 
dns_transaction_dnssec_ready(DnsTransaction * t)848 static int dns_transaction_dnssec_ready(DnsTransaction *t) {
849         DnsTransaction *dt;
850         int r;
851 
852         assert(t);
853 
854         /* Checks whether the auxiliary DNSSEC transactions of our transaction have completed, or are still
855          * ongoing. Returns 0, if we aren't ready for the DNSSEC validation, positive if we are. */
856 
857         SET_FOREACH(dt, t->dnssec_transactions) {
858 
859                 switch (dt->state) {
860 
861                 case DNS_TRANSACTION_NULL:
862                 case DNS_TRANSACTION_PENDING:
863                 case DNS_TRANSACTION_VALIDATING:
864                         /* Still ongoing */
865                         return 0;
866 
867                 case DNS_TRANSACTION_RCODE_FAILURE:
868                         if (!IN_SET(dt->answer_rcode, DNS_RCODE_NXDOMAIN, DNS_RCODE_SERVFAIL)) {
869                                 log_debug("Auxiliary DNSSEC RR query failed with rcode=%s.", dns_rcode_to_string(dt->answer_rcode));
870                                 goto fail;
871                         }
872 
873                         /* Fall-through: NXDOMAIN/SERVFAIL is good enough for us. This is because some DNS servers
874                          * erroneously return NXDOMAIN/SERVFAIL for empty non-terminals (Akamai...) or missing DS
875                          * records (Facebook), and we need to handle that nicely, when asking for parent SOA or similar
876                          * RRs to make unsigned proofs. */
877 
878                 case DNS_TRANSACTION_SUCCESS:
879                         /* All good. */
880                         break;
881 
882                 case DNS_TRANSACTION_DNSSEC_FAILED:
883                         /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
884                          * validation result */
885 
886                         log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result));
887                         t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */
888                         dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
889                         return 0;
890 
891                 default:
892                         log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(dt->state));
893                         goto fail;
894                 }
895         }
896 
897         /* All is ready, we can go and validate */
898         return 1;
899 
900 fail:
901         /* Some auxiliary DNSSEC transaction failed for some reason. Maybe we learned something about the
902          * server due to this failure, and the feature level is now different? Let's see and restart the
903          * transaction if so. If not, let's propagate the auxiliary failure.
904          *
905          * This is particularly relevant if an auxiliary request figured out that DNSSEC doesn't work, and we
906          * are in permissive DNSSEC mode, and thus should restart things without DNSSEC magic. */
907         r = dns_transaction_maybe_restart(t);
908         if (r < 0)
909                 return r;
910         if (r > 0)
911                 return 0; /* don't validate just yet, we restarted things */
912 
913         t->answer_dnssec_result = DNSSEC_FAILED_AUXILIARY;
914         dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
915         return 0;
916 }
917 
dns_transaction_process_dnssec(DnsTransaction * t)918 static void dns_transaction_process_dnssec(DnsTransaction *t) {
919         int r;
920 
921         assert(t);
922 
923         /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
924         r = dns_transaction_dnssec_ready(t);
925         if (r < 0)
926                 goto fail;
927         if (r == 0) /* We aren't ready yet (or one of our auxiliary transactions failed, and we shouldn't validate now */
928                 return;
929 
930         /* See if we learnt things from the additional DNSSEC transactions, that we didn't know before, and better
931          * restart the lookup immediately. */
932         r = dns_transaction_maybe_restart(t);
933         if (r < 0)
934                 goto fail;
935         if (r > 0) /* Transaction got restarted... */
936                 return;
937 
938         /* All our auxiliary DNSSEC transactions are complete now. Try
939          * to validate our RRset now. */
940         r = dns_transaction_validate_dnssec(t);
941         if (r == -EBADMSG) {
942                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
943                 return;
944         }
945         if (r < 0)
946                 goto fail;
947 
948         if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER &&
949             t->scope->dnssec_mode == DNSSEC_YES) {
950 
951                 /*  We are not in automatic downgrade mode, and the server is bad. Let's try a different server, maybe
952                  *  that works. */
953 
954                 if (dns_transaction_limited_retry(t))
955                         return;
956 
957                 /* OK, let's give up, apparently all servers we tried didn't work. */
958                 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
959                 return;
960         }
961 
962         if (!IN_SET(t->answer_dnssec_result,
963                     _DNSSEC_RESULT_INVALID,        /* No DNSSEC validation enabled */
964                     DNSSEC_VALIDATED,              /* Answer is signed and validated successfully */
965                     DNSSEC_UNSIGNED,               /* Answer is right-fully unsigned */
966                     DNSSEC_INCOMPATIBLE_SERVER)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
967                 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
968                 return;
969         }
970 
971         if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER)
972                 dns_server_warn_downgrade(t->server);
973 
974         dns_transaction_cache_answer(t);
975 
976         if (t->answer_rcode == DNS_RCODE_SUCCESS)
977                 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
978         else
979                 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
980 
981         return;
982 
983 fail:
984         dns_transaction_complete_errno(t, r);
985 }
986 
dns_transaction_has_positive_answer(DnsTransaction * t,DnsAnswerFlags * flags)987 static int dns_transaction_has_positive_answer(DnsTransaction *t, DnsAnswerFlags *flags) {
988         int r;
989 
990         assert(t);
991 
992         /* Checks whether the answer is positive, i.e. either a direct
993          * answer to the question, or a CNAME/DNAME for it */
994 
995         r = dns_answer_match_key(t->answer, dns_transaction_key(t), flags);
996         if (r != 0)
997                 return r;
998 
999         r = dns_answer_find_cname_or_dname(t->answer, dns_transaction_key(t), NULL, flags);
1000         if (r != 0)
1001                 return r;
1002 
1003         return false;
1004 }
1005 
dns_transaction_fix_rcode(DnsTransaction * t)1006 static int dns_transaction_fix_rcode(DnsTransaction *t) {
1007         int r;
1008 
1009         assert(t);
1010 
1011         /* Fix up the RCODE to SUCCESS if we get at least one matching RR in a response. Note that this contradicts the
1012          * DNS RFCs a bit. Specifically, RFC 6604 Section 3 clarifies that the RCODE shall say something about a
1013          * CNAME/DNAME chain element coming after the last chain element contained in the message, and not the first
1014          * one included. However, it also indicates that not all DNS servers implement this correctly. Moreover, when
1015          * using DNSSEC we usually only can prove the first element of a CNAME/DNAME chain anyway, hence let's settle
1016          * on always processing the RCODE as referring to the immediate look-up we do, i.e. the first element of a
1017          * CNAME/DNAME chain. This way, we uniformly handle CNAME/DNAME chains, regardless if the DNS server
1018          * incorrectly implements RCODE, whether DNSSEC is in use, or whether the DNS server only supplied us with an
1019          * incomplete CNAME/DNAME chain.
1020          *
1021          * Or in other words: if we get at least one positive reply in a message we patch NXDOMAIN to become SUCCESS,
1022          * and then rely on the CNAME chasing logic to figure out that there's actually a CNAME error with a new
1023          * lookup. */
1024 
1025         if (t->answer_rcode != DNS_RCODE_NXDOMAIN)
1026                 return 0;
1027 
1028         r = dns_transaction_has_positive_answer(t, NULL);
1029         if (r <= 0)
1030                 return r;
1031 
1032         t->answer_rcode = DNS_RCODE_SUCCESS;
1033         return 0;
1034 }
1035 
dns_transaction_process_reply(DnsTransaction * t,DnsPacket * p,bool encrypted)1036 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypted) {
1037         bool retry_with_tcp = false;
1038         int r;
1039 
1040         assert(t);
1041         assert(p);
1042         assert(t->scope);
1043         assert(t->scope->manager);
1044 
1045         if (t->state != DNS_TRANSACTION_PENDING)
1046                 return;
1047 
1048         /* Note that this call might invalidate the query. Callers
1049          * should hence not attempt to access the query or transaction
1050          * after calling this function. */
1051 
1052         log_debug("Processing incoming packet of size %zu on transaction %" PRIu16" (rcode=%s).",
1053                   p->size,
1054                   t->id, dns_rcode_to_string(DNS_PACKET_RCODE(p)));
1055 
1056         switch (t->scope->protocol) {
1057 
1058         case DNS_PROTOCOL_LLMNR:
1059                 /* For LLMNR we will not accept any packets from other interfaces */
1060 
1061                 if (p->ifindex != dns_scope_ifindex(t->scope))
1062                         return;
1063 
1064                 if (p->family != t->scope->family)
1065                         return;
1066 
1067                 /* Tentative packets are not full responses but still
1068                  * useful for identifying uniqueness conflicts during
1069                  * probing. */
1070                 if (DNS_PACKET_LLMNR_T(p)) {
1071                         dns_transaction_tentative(t, p);
1072                         return;
1073                 }
1074 
1075                 break;
1076 
1077         case DNS_PROTOCOL_MDNS:
1078                 /* For mDNS we will not accept any packets from other interfaces */
1079 
1080                 if (p->ifindex != dns_scope_ifindex(t->scope))
1081                         return;
1082 
1083                 if (p->family != t->scope->family)
1084                         return;
1085 
1086                 break;
1087 
1088         case DNS_PROTOCOL_DNS:
1089                 /* Note that we do not need to verify the
1090                  * addresses/port numbers of incoming traffic, as we
1091                  * invoked connect() on our UDP socket in which case
1092                  * the kernel already does the needed verification for
1093                  * us. */
1094                 break;
1095 
1096         default:
1097                 assert_not_reached();
1098         }
1099 
1100         if (t->received != p)
1101                 DNS_PACKET_REPLACE(t->received, dns_packet_ref(p));
1102 
1103         t->answer_source = DNS_TRANSACTION_NETWORK;
1104 
1105         if (p->ipproto == IPPROTO_TCP) {
1106                 if (DNS_PACKET_TC(p)) {
1107                         /* Truncated via TCP? Somebody must be fucking with us */
1108                         dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1109                         return;
1110                 }
1111 
1112                 if (DNS_PACKET_ID(p) != t->id) {
1113                         /* Not the reply to our query? Somebody must be fucking with us */
1114                         dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1115                         return;
1116                 }
1117         }
1118 
1119         switch (t->scope->protocol) {
1120 
1121         case DNS_PROTOCOL_DNS:
1122                 assert(t->server);
1123 
1124                 if (!t->bypass &&
1125                     IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
1126 
1127                         /* Request failed, immediately try again with reduced features */
1128 
1129                         if (t->current_feature_level <= DNS_SERVER_FEATURE_LEVEL_UDP) {
1130 
1131                                 /* This was already at UDP feature level? If so, it doesn't make sense to downgrade
1132                                  * this transaction anymore, but let's see if it might make sense to send the request
1133                                  * to a different DNS server instead. If not let's process the response, and accept the
1134                                  * rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
1135                                  * packet loss, but is not going to give us better rcodes should we actually have
1136                                  * managed to get them already at UDP level. */
1137 
1138                                 if (dns_transaction_limited_retry(t))
1139                                         return;
1140 
1141                                 /* Give up, accept the rcode */
1142                                 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
1143                                 break;
1144                         }
1145 
1146                         /* SERVFAIL can happen for many reasons and may be transient.
1147                          * To avoid unnecessary downgrades retry once with the initial level.
1148                          * Check for clamp_feature_level_servfail having an invalid value as a sign that this is the
1149                          * first attempt to downgrade. If so, clamp to the current value so that the transaction
1150                          * is retried without actually downgrading. If the next try also fails we will downgrade by
1151                          * hitting the else branch below. */
1152                         if (DNS_PACKET_RCODE(p) == DNS_RCODE_SERVFAIL &&
1153                             t->clamp_feature_level_servfail < 0) {
1154                                 t->clamp_feature_level_servfail = t->current_feature_level;
1155                                 log_debug("Server returned error %s, retrying transaction.",
1156                                           dns_rcode_to_string(DNS_PACKET_RCODE(p)));
1157                         } else {
1158                                 /* Reduce this feature level by one and try again. */
1159                                 switch (t->current_feature_level) {
1160                                 case DNS_SERVER_FEATURE_LEVEL_TLS_DO:
1161                                         t->clamp_feature_level_servfail = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN;
1162                                         break;
1163                                 case DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN + 1:
1164                                         /* Skip plain TLS when TLS is not supported */
1165                                         t->clamp_feature_level_servfail = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN - 1;
1166                                         break;
1167                                 default:
1168                                         t->clamp_feature_level_servfail = t->current_feature_level - 1;
1169                                 }
1170 
1171                                 log_debug("Server returned error %s, retrying transaction with reduced feature level %s.",
1172                                           dns_rcode_to_string(DNS_PACKET_RCODE(p)),
1173                                           dns_server_feature_level_to_string(t->clamp_feature_level_servfail));
1174                         }
1175 
1176                         dns_transaction_retry(t, false /* use the same server */);
1177                         return;
1178                 }
1179 
1180                 if (DNS_PACKET_RCODE(p) == DNS_RCODE_REFUSED) {
1181                         /* This server refused our request? If so, try again, use a different server */
1182                         log_debug("Server returned REFUSED, switching servers, and retrying.");
1183 
1184                         if (dns_transaction_limited_retry(t))
1185                                 return;
1186 
1187                         break;
1188                 }
1189 
1190                 if (DNS_PACKET_TC(p))
1191                         dns_server_packet_truncated(t->server, t->current_feature_level);
1192 
1193                 break;
1194 
1195         case DNS_PROTOCOL_LLMNR:
1196         case DNS_PROTOCOL_MDNS:
1197                 dns_scope_packet_received(t->scope, p->timestamp - t->start_usec);
1198                 break;
1199 
1200         default:
1201                 assert_not_reached();
1202         }
1203 
1204         if (DNS_PACKET_TC(p)) {
1205 
1206                 /* Truncated packets for mDNS are not allowed. Give up immediately. */
1207                 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
1208                         dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1209                         return;
1210                 }
1211 
1212                 /* Response was truncated, let's try again with good old TCP */
1213                 log_debug("Reply truncated, retrying via TCP.");
1214                 retry_with_tcp = true;
1215 
1216         } else if (t->scope->protocol == DNS_PROTOCOL_DNS &&
1217                    DNS_PACKET_IS_FRAGMENTED(p)) {
1218 
1219                 /* Report the fragment size, so that we downgrade from LARGE to regular EDNS0 if needed */
1220                 if (t->server)
1221                         dns_server_packet_udp_fragmented(t->server, dns_packet_size_unfragmented(p));
1222 
1223                 if (t->current_feature_level > DNS_SERVER_FEATURE_LEVEL_UDP) {
1224                         /* Packet was fragmented. Let's retry with TCP to avoid fragmentation attack
1225                          * issues. (We don't do that on the lowest feature level however, since crappy DNS
1226                          * servers often do not implement TCP, hence falling back to TCP on fragmentation is
1227                          * counter-productive there.) */
1228 
1229                         log_debug("Reply fragmented, retrying via TCP. (Largest fragment size: %zu; Datagram size: %zu)",
1230                                   p->fragsize, p->size);
1231                         retry_with_tcp = true;
1232                 }
1233         }
1234 
1235         if (retry_with_tcp) {
1236                 r = dns_transaction_emit_tcp(t);
1237                 if (r == -ESRCH) {
1238                         /* No servers found? Damn! */
1239                         dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1240                         return;
1241                 }
1242                 if (r == -EOPNOTSUPP) {
1243                         /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC  */
1244                         dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
1245                         return;
1246                 }
1247                 if (r < 0) {
1248                         /* On LLMNR, if we cannot connect to the host,
1249                          * we immediately give up */
1250                         if (t->scope->protocol != DNS_PROTOCOL_DNS)
1251                                 goto fail;
1252 
1253                         /* On DNS, couldn't send? Try immediately again, with a new server */
1254                         if (dns_transaction_limited_retry(t))
1255                                 return;
1256 
1257                         /* No new server to try, give up */
1258                         dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1259                 }
1260 
1261                 return;
1262         }
1263 
1264         /* After the superficial checks, actually parse the message. */
1265         r = dns_packet_extract(p);
1266         if (r < 0) {
1267                 if (t->server) {
1268                         dns_server_packet_invalid(t->server, t->current_feature_level);
1269 
1270                         r = dns_transaction_maybe_restart(t);
1271                         if (r < 0)
1272                                 goto fail;
1273                         if (r > 0) /* Transaction got restarted... */
1274                                 return;
1275                 }
1276 
1277                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1278                 return;
1279         }
1280 
1281         if (t->scope->protocol == DNS_PROTOCOL_DNS &&
1282             !t->bypass &&
1283             DNS_PACKET_RCODE(p) == DNS_RCODE_NXDOMAIN &&
1284             p->opt && !DNS_PACKET_DO(p) &&
1285             DNS_SERVER_FEATURE_LEVEL_IS_EDNS0(t->current_feature_level) &&
1286             DNS_SERVER_FEATURE_LEVEL_IS_UDP(t->current_feature_level) &&
1287             t->scope->dnssec_mode != DNSSEC_YES) {
1288 
1289                 /* Some captive portals are special in that the Aruba/Datavalet hardware will miss
1290                  * replacing the packets with the local server IP to point to the authenticated side
1291                  * of the network if EDNS0 is enabled. Instead they return NXDOMAIN, with DO bit set
1292                  * to zero... nothing to see here, yet respond with the captive portal IP, when using
1293                  * the more simple UDP level.
1294                  *
1295                  * Common portal names that fail like so are:
1296                  *     secure.datavalet.io
1297                  *     securelogin.arubanetworks.com
1298                  *     securelogin.networks.mycompany.com
1299                  *
1300                  * Thus retry NXDOMAIN RCODES with a lower feature level.
1301                  *
1302                  * Do not lower the server's tracked feature level, as the captive portal should not
1303                  * be lying for the wider internet (e.g. _other_ queries were observed fine with
1304                  * EDNS0 on these networks, post auth), i.e. let's just lower the level transaction's
1305                  * feature level.
1306                  *
1307                  * This is reported as https://github.com/dns-violations/dns-violations/blob/master/2018/DVE-2018-0001.md
1308                  */
1309 
1310                 t->clamp_feature_level_nxdomain = DNS_SERVER_FEATURE_LEVEL_UDP;
1311 
1312                 log_debug("Server returned error %s in EDNS0 mode, retrying transaction with reduced feature level %s (DVE-2018-0001 mitigation)",
1313                           dns_rcode_to_string(DNS_PACKET_RCODE(p)),
1314                           dns_server_feature_level_to_string(t->clamp_feature_level_nxdomain));
1315 
1316                 dns_transaction_retry(t, false /* use the same server */);
1317                 return;
1318         }
1319 
1320         if (t->server) {
1321                 /* Report that we successfully received a valid packet with a good rcode after we initially got a bad
1322                  * rcode and subsequently downgraded the protocol */
1323 
1324                 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN) &&
1325                     t->clamp_feature_level_servfail != _DNS_SERVER_FEATURE_LEVEL_INVALID)
1326                         dns_server_packet_rcode_downgrade(t->server, t->clamp_feature_level_servfail);
1327 
1328                 /* Report that the OPT RR was missing */
1329                 if (!p->opt)
1330                         dns_server_packet_bad_opt(t->server, t->current_feature_level);
1331 
1332                 /* Report that the server didn't copy our query DO bit from request to response */
1333                 if (DNS_PACKET_DO(t->sent) && !DNS_PACKET_DO(t->received))
1334                         dns_server_packet_do_off(t->server, t->current_feature_level);
1335 
1336                 /* Report that we successfully received a packet. We keep track of the largest packet
1337                  * size/fragment size we got. Which is useful for announcing the EDNS(0) packet size we can
1338                  * receive to our server. */
1339                 dns_server_packet_received(t->server, p->ipproto, t->current_feature_level, dns_packet_size_unfragmented(p));
1340         }
1341 
1342         /* See if we know things we didn't know before that indicate we better restart the lookup immediately. */
1343         r = dns_transaction_maybe_restart(t);
1344         if (r < 0)
1345                 goto fail;
1346         if (r > 0) /* Transaction got restarted... */
1347                 return;
1348 
1349         /* When dealing with protocols other than mDNS only consider responses with equivalent query section
1350          * to the request. For mDNS this check doesn't make sense, because the section 6 of RFC6762 states
1351          * that "Multicast DNS responses MUST NOT contain any questions in the Question Section". */
1352         if (t->scope->protocol != DNS_PROTOCOL_MDNS) {
1353                 r = dns_packet_is_reply_for(p, dns_transaction_key(t));
1354                 if (r < 0)
1355                         goto fail;
1356                 if (r == 0) {
1357                         dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1358                         return;
1359                 }
1360         }
1361 
1362         /* Install the answer as answer to the transaction. We ref the answer twice here: the main `answer`
1363          * field is later replaced by the DNSSEC validated subset. The 'answer_auxiliary' field carries the
1364          * original complete record set, including RRSIG and friends. We use this when passing data to
1365          * clients that ask for DNSSEC metadata. */
1366         DNS_ANSWER_REPLACE(t->answer, dns_answer_ref(p->answer));
1367         t->answer_rcode = DNS_PACKET_RCODE(p);
1368         t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
1369         SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
1370         SET_FLAG(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL, encrypted);
1371 
1372         r = dns_transaction_fix_rcode(t);
1373         if (r < 0)
1374                 goto fail;
1375 
1376         /* Block GC while starting requests for additional DNSSEC RRs */
1377         t->block_gc++;
1378         r = dns_transaction_request_dnssec_keys(t);
1379         t->block_gc--;
1380 
1381         /* Maybe the transaction is ready for GC'ing now? If so, free it and return. */
1382         if (!dns_transaction_gc(t))
1383                 return;
1384 
1385         /* Requesting additional keys might have resulted in this transaction to fail, since the auxiliary
1386          * request failed for some reason. If so, we are not in pending state anymore, and we should exit
1387          * quickly. */
1388         if (t->state != DNS_TRANSACTION_PENDING)
1389                 return;
1390         if (r < 0)
1391                 goto fail;
1392         if (r > 0) {
1393                 /* There are DNSSEC transactions pending now. Update the state accordingly. */
1394                 t->state = DNS_TRANSACTION_VALIDATING;
1395                 dns_transaction_close_connection(t, true);
1396                 dns_transaction_stop_timeout(t);
1397                 return;
1398         }
1399 
1400         dns_transaction_process_dnssec(t);
1401         return;
1402 
1403 fail:
1404         dns_transaction_complete_errno(t, r);
1405 }
1406 
on_dns_packet(sd_event_source * s,int fd,uint32_t revents,void * userdata)1407 static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1408         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1409         DnsTransaction *t = userdata;
1410         int r;
1411 
1412         assert(t);
1413         assert(t->scope);
1414 
1415         r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
1416         if (ERRNO_IS_DISCONNECT(r)) {
1417                 usec_t usec;
1418 
1419                 /* UDP connection failures get reported via ICMP and then are possibly delivered to us on the
1420                  * next recvmsg(). Treat this like a lost packet. */
1421 
1422                 log_debug_errno(r, "Connection failure for DNS UDP packet: %m");
1423                 assert_se(sd_event_now(t->scope->manager->event, CLOCK_BOOTTIME, &usec) >= 0);
1424                 dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level);
1425 
1426                 dns_transaction_close_connection(t, /* use_graveyard = */ false);
1427 
1428                 if (dns_transaction_limited_retry(t)) /* Try a different server */
1429                         return 0;
1430 
1431                 dns_transaction_complete_errno(t, r);
1432                 return 0;
1433         }
1434         if (r < 0) {
1435                 dns_transaction_complete_errno(t, r);
1436                 return 0;
1437         }
1438         if (r == 0)
1439                 /* Spurious wakeup without any data */
1440                 return 0;
1441 
1442         r = dns_packet_validate_reply(p);
1443         if (r < 0) {
1444                 log_debug_errno(r, "Received invalid DNS packet as response, ignoring: %m");
1445                 return 0;
1446         }
1447         if (r == 0) {
1448                 log_debug("Received inappropriate DNS packet as response, ignoring.");
1449                 return 0;
1450         }
1451 
1452         if (DNS_PACKET_ID(p) != t->id) {
1453                 log_debug("Received packet with incorrect transaction ID, ignoring.");
1454                 return 0;
1455         }
1456 
1457         dns_transaction_process_reply(t, p, false);
1458         return 0;
1459 }
1460 
dns_transaction_emit_udp(DnsTransaction * t)1461 static int dns_transaction_emit_udp(DnsTransaction *t) {
1462         int r;
1463 
1464         assert(t);
1465 
1466         if (t->scope->protocol == DNS_PROTOCOL_DNS) {
1467 
1468                 r = dns_transaction_pick_server(t);
1469                 if (r < 0)
1470                         return r;
1471 
1472                 if (manager_server_is_stub(t->scope->manager, t->server))
1473                         return -ELOOP;
1474 
1475                 if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_UDP || DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level))
1476                         return -EAGAIN; /* Sorry, can't do UDP, try TCP! */
1477 
1478                 if (!t->bypass && !dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(dns_transaction_key(t)->type))
1479                         return -EOPNOTSUPP;
1480 
1481                 if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */
1482                         int fd;
1483 
1484                         dns_transaction_close_connection(t, true);
1485 
1486                         /* Before we allocate a new UDP socket, let's process the graveyard a bit to free some fds */
1487                         manager_socket_graveyard_process(t->scope->manager);
1488 
1489                         fd = dns_scope_socket_udp(t->scope, t->server);
1490                         if (fd < 0)
1491                                 return fd;
1492 
1493                         r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
1494                         if (r < 0) {
1495                                 safe_close(fd);
1496                                 return r;
1497                         }
1498 
1499                         (void) sd_event_source_set_description(t->dns_udp_event_source, "dns-transaction-udp");
1500                         t->dns_udp_fd = fd;
1501                 }
1502 
1503                 if (!t->bypass) {
1504                         r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
1505                         if (r < 0)
1506                                 return r;
1507                 }
1508         } else
1509                 dns_transaction_close_connection(t, true);
1510 
1511         r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->server ? t->server->family : AF_UNSPEC, t->sent);
1512         if (r < 0)
1513                 return r;
1514 
1515         dns_transaction_reset_answer(t);
1516 
1517         return 0;
1518 }
1519 
on_transaction_timeout(sd_event_source * s,usec_t usec,void * userdata)1520 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
1521         DnsTransaction *t = userdata;
1522 
1523         assert(s);
1524         assert(t);
1525 
1526         if (t->initial_jitter_scheduled && !t->initial_jitter_elapsed) {
1527                 log_debug("Initial jitter phase for transaction %" PRIu16 " elapsed.", t->id);
1528                 t->initial_jitter_elapsed = true;
1529         } else {
1530                 /* Timeout reached? Increase the timeout for the server used */
1531                 switch (t->scope->protocol) {
1532 
1533                 case DNS_PROTOCOL_DNS:
1534                         assert(t->server);
1535                         dns_server_packet_lost(t->server, t->stream ? IPPROTO_TCP : IPPROTO_UDP, t->current_feature_level);
1536                         break;
1537 
1538                 case DNS_PROTOCOL_LLMNR:
1539                 case DNS_PROTOCOL_MDNS:
1540                         dns_scope_packet_lost(t->scope, usec - t->start_usec);
1541                         break;
1542 
1543                 default:
1544                         assert_not_reached();
1545                 }
1546 
1547                 log_debug("Timeout reached on transaction %" PRIu16 ".", t->id);
1548         }
1549 
1550         dns_transaction_retry(t, /* next_server= */ true); /* try a different server, but given this means
1551                                                             * packet loss, let's do so even if we already
1552                                                             * tried a bunch */
1553         return 0;
1554 }
1555 
transaction_get_resend_timeout(DnsTransaction * t)1556 static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
1557         assert(t);
1558         assert(t->scope);
1559 
1560         switch (t->scope->protocol) {
1561 
1562         case DNS_PROTOCOL_DNS:
1563 
1564                 /* When we do TCP, grant a much longer timeout, as in this case there's no need for us to quickly
1565                  * resend, as the kernel does that anyway for us, and we really don't want to interrupt it in that
1566                  * needlessly. */
1567                 if (t->stream)
1568                         return TRANSACTION_TCP_TIMEOUT_USEC;
1569 
1570                 return DNS_TIMEOUT_USEC;
1571 
1572         case DNS_PROTOCOL_MDNS:
1573                 assert(t->n_attempts > 0);
1574                 if (t->probing)
1575                         return MDNS_PROBING_INTERVAL_USEC;
1576                 else
1577                         return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
1578 
1579         case DNS_PROTOCOL_LLMNR:
1580                 return t->scope->resend_timeout;
1581 
1582         default:
1583                 assert_not_reached();
1584         }
1585 }
1586 
dns_transaction_randomize_answer(DnsTransaction * t)1587 static void dns_transaction_randomize_answer(DnsTransaction *t) {
1588         int r;
1589 
1590         assert(t);
1591 
1592         /* Randomizes the order of the answer array. This is done for all cached responses, so that we return
1593          * a different order each time. We do this only for DNS traffic, in order to do some minimal, crappy
1594          * load balancing. We don't do this for LLMNR or mDNS, since the order (preferring link-local
1595          * addresses, and such like) might have meaning there, and load balancing is pointless. */
1596 
1597         if (t->scope->protocol != DNS_PROTOCOL_DNS)
1598                 return;
1599 
1600         /* No point in randomizing, if there's just one RR */
1601         if (dns_answer_size(t->answer) <= 1)
1602                 return;
1603 
1604         r = dns_answer_reserve_or_clone(&t->answer, 0);
1605         if (r < 0) /* If this fails, just don't randomize, this is non-essential stuff after all */
1606                 return (void) log_debug_errno(r, "Failed to clone answer record, not randomizing RR order of answer: %m");
1607 
1608         dns_answer_randomize(t->answer);
1609 }
1610 
dns_transaction_prepare(DnsTransaction * t,usec_t ts)1611 static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
1612         int r;
1613 
1614         assert(t);
1615 
1616         /* Returns 0 if dns_transaction_complete() has been called. In that case the transaction and query
1617          * candidate objects may have been invalidated and must not be accessed. Returns 1 if the transaction
1618          * has been prepared. */
1619 
1620         dns_transaction_stop_timeout(t);
1621 
1622         if (!dns_scope_network_good(t->scope)) {
1623                 dns_transaction_complete(t, DNS_TRANSACTION_NETWORK_DOWN);
1624                 return 0;
1625         }
1626 
1627         if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
1628                 DnsTransactionState result;
1629 
1630                 if (t->scope->protocol == DNS_PROTOCOL_LLMNR)
1631                         /* If we didn't find anything on LLMNR, it's not an error, but a failure to resolve
1632                          * the name. */
1633                         result = DNS_TRANSACTION_NOT_FOUND;
1634                 else
1635                         result = DNS_TRANSACTION_ATTEMPTS_MAX_REACHED;
1636 
1637                 dns_transaction_complete(t, result);
1638                 return 0;
1639         }
1640 
1641         if (t->scope->protocol == DNS_PROTOCOL_LLMNR && t->tried_stream) {
1642                 /* If we already tried via a stream, then we don't
1643                  * retry on LLMNR. See RFC 4795, Section 2.7. */
1644                 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1645                 return 0;
1646         }
1647 
1648         t->n_attempts++;
1649         t->start_usec = ts;
1650 
1651         dns_transaction_reset_answer(t);
1652         dns_transaction_flush_dnssec_transactions(t);
1653 
1654         /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
1655         if (t->scope->protocol == DNS_PROTOCOL_DNS &&
1656             !FLAGS_SET(t->query_flags, SD_RESOLVED_NO_TRUST_ANCHOR)) {
1657                 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, dns_transaction_key(t), &t->answer);
1658                 if (r < 0)
1659                         return r;
1660                 if (r > 0) {
1661                         t->answer_rcode = DNS_RCODE_SUCCESS;
1662                         t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
1663                         SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL, true);
1664                         dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1665                         return 0;
1666                 }
1667 
1668                 if (dns_name_is_root(dns_resource_key_name(dns_transaction_key(t))) &&
1669                     dns_transaction_key(t)->type == DNS_TYPE_DS) {
1670 
1671                         /* Hmm, this is a request for the root DS? A DS RR doesn't exist in the root zone,
1672                          * and if our trust anchor didn't know it either, this means we cannot do any DNSSEC
1673                          * logic anymore. */
1674 
1675                         if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
1676                                 /* We are in downgrade mode. In this case, synthesize an unsigned empty
1677                                  * response, so that the any lookup depending on this one can continue
1678                                  * assuming there was no DS, and hence the root zone was unsigned. */
1679 
1680                                 t->answer_rcode = DNS_RCODE_SUCCESS;
1681                                 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
1682                                 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
1683                                 SET_FLAG(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL, true);
1684                                 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1685                         } else
1686                                 /* If we are not in downgrade mode, then fail the lookup, because we cannot
1687                                  * reasonably answer it. There might be DS RRs, but we don't know them, and
1688                                  * the DNS server won't tell them to us (and even if it would, we couldn't
1689                                  * validate and trust them. */
1690                                 dns_transaction_complete(t, DNS_TRANSACTION_NO_TRUST_ANCHOR);
1691 
1692                         return 0;
1693                 }
1694         }
1695 
1696         /* Check the zone. */
1697         if (!FLAGS_SET(t->query_flags, SD_RESOLVED_NO_ZONE)) {
1698                 r = dns_zone_lookup(&t->scope->zone, dns_transaction_key(t), dns_scope_ifindex(t->scope), &t->answer, NULL, NULL);
1699                 if (r < 0)
1700                         return r;
1701                 if (r > 0) {
1702                         t->answer_rcode = DNS_RCODE_SUCCESS;
1703                         t->answer_source = DNS_TRANSACTION_ZONE;
1704                         SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL, true);
1705                         dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1706                         return 0;
1707                 }
1708         }
1709 
1710         /* Check the cache. */
1711         if (!FLAGS_SET(t->query_flags, SD_RESOLVED_NO_CACHE)) {
1712 
1713                 /* Before trying the cache, let's make sure we figured out a server to use. Should this cause
1714                  * a change of server this might flush the cache. */
1715                 (void) dns_scope_get_dns_server(t->scope);
1716 
1717                 /* Let's then prune all outdated entries */
1718                 dns_cache_prune(&t->scope->cache);
1719 
1720                 r = dns_cache_lookup(
1721                                 &t->scope->cache,
1722                                 dns_transaction_key(t),
1723                                 t->query_flags,
1724                                 &t->answer_rcode,
1725                                 &t->answer,
1726                                 &t->received,
1727                                 &t->answer_query_flags,
1728                                 &t->answer_dnssec_result);
1729                 if (r < 0)
1730                         return r;
1731                 if (r > 0) {
1732                         dns_transaction_randomize_answer(t);
1733 
1734                         if (t->bypass && t->scope->protocol == DNS_PROTOCOL_DNS && !t->received)
1735                                 /* When bypass mode is on, do not use cached data unless it came with a full
1736                                  * packet. */
1737                                 dns_transaction_reset_answer(t);
1738                         else {
1739                                 t->answer_source = DNS_TRANSACTION_CACHE;
1740                                 if (t->answer_rcode == DNS_RCODE_SUCCESS)
1741                                         dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1742                                 else
1743                                         dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
1744                                 return 0;
1745                         }
1746                 }
1747         }
1748 
1749         if (FLAGS_SET(t->query_flags, SD_RESOLVED_NO_NETWORK)) {
1750                 dns_transaction_complete(t, DNS_TRANSACTION_NO_SOURCE);
1751                 return 0;
1752         }
1753 
1754         return 1;
1755 }
1756 
dns_transaction_make_packet_mdns(DnsTransaction * t)1757 static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
1758         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1759         bool add_known_answers = false;
1760         DnsResourceKey *tkey;
1761         _cleanup_set_free_ Set *keys = NULL;
1762         unsigned qdcount;
1763         unsigned nscount = 0;
1764         usec_t ts;
1765         int r;
1766 
1767         assert(t);
1768         assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
1769 
1770         /* Discard any previously prepared packet, so we can start over and coalesce again */
1771         t->sent = dns_packet_unref(t->sent);
1772 
1773         r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
1774         if (r < 0)
1775                 return r;
1776 
1777         r = dns_packet_append_key(p, dns_transaction_key(t), 0, NULL);
1778         if (r < 0)
1779                 return r;
1780 
1781         qdcount = 1;
1782 
1783         if (dns_key_is_shared(dns_transaction_key(t)))
1784                 add_known_answers = true;
1785 
1786         if (dns_transaction_key(t)->type == DNS_TYPE_ANY) {
1787                 r = set_ensure_put(&keys, &dns_resource_key_hash_ops, dns_transaction_key(t));
1788                 if (r < 0)
1789                         return r;
1790         }
1791 
1792         /*
1793          * For mDNS, we want to coalesce as many open queries in pending transactions into one single
1794          * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
1795          * in our current scope, and see whether their timing constraints allow them to be sent.
1796          */
1797 
1798         assert_se(sd_event_now(t->scope->manager->event, CLOCK_BOOTTIME, &ts) >= 0);
1799 
1800         LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
1801 
1802                 /* Skip ourselves */
1803                 if (other == t)
1804                         continue;
1805 
1806                 if (other->state != DNS_TRANSACTION_PENDING)
1807                         continue;
1808 
1809                 if (other->next_attempt_after > ts)
1810                         continue;
1811 
1812                 if (qdcount >= UINT16_MAX)
1813                         break;
1814 
1815                 r = dns_packet_append_key(p, dns_transaction_key(other), 0, NULL);
1816 
1817                 /*
1818                  * If we can't stuff more questions into the packet, just give up.
1819                  * One of the 'other' transactions will fire later and take care of the rest.
1820                  */
1821                 if (r == -EMSGSIZE)
1822                         break;
1823 
1824                 if (r < 0)
1825                         return r;
1826 
1827                 r = dns_transaction_prepare(other, ts);
1828                 if (r <= 0)
1829                         continue;
1830 
1831                 ts += transaction_get_resend_timeout(other);
1832 
1833                 r = sd_event_add_time(
1834                                 other->scope->manager->event,
1835                                 &other->timeout_event_source,
1836                                 CLOCK_BOOTTIME,
1837                                 ts, 0,
1838                                 on_transaction_timeout, other);
1839                 if (r < 0)
1840                         return r;
1841 
1842                 (void) sd_event_source_set_description(other->timeout_event_source, "dns-transaction-timeout");
1843 
1844                 other->state = DNS_TRANSACTION_PENDING;
1845                 other->next_attempt_after = ts;
1846 
1847                 qdcount++;
1848 
1849                 if (dns_key_is_shared(dns_transaction_key(other)))
1850                         add_known_answers = true;
1851 
1852                 if (dns_transaction_key(other)->type == DNS_TYPE_ANY) {
1853                         r = set_ensure_put(&keys, &dns_resource_key_hash_ops, dns_transaction_key(other));
1854                         if (r < 0)
1855                                 return r;
1856                 }
1857         }
1858 
1859         DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
1860 
1861         /* Append known answer section if we're asking for any shared record */
1862         if (add_known_answers) {
1863                 r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
1864                 if (r < 0)
1865                         return r;
1866         }
1867 
1868         SET_FOREACH(tkey, keys) {
1869                 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1870                 bool tentative;
1871 
1872                 r = dns_zone_lookup(&t->scope->zone, tkey, t->scope->link->ifindex, &answer, NULL, &tentative);
1873                 if (r < 0)
1874                         return r;
1875 
1876                 r = dns_packet_append_answer(p, answer, &nscount);
1877                 if (r < 0)
1878                         return r;
1879         }
1880         DNS_PACKET_HEADER(p)->nscount = htobe16(nscount);
1881 
1882         t->sent = TAKE_PTR(p);
1883 
1884         return 0;
1885 }
1886 
dns_transaction_make_packet(DnsTransaction * t)1887 static int dns_transaction_make_packet(DnsTransaction *t) {
1888         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1889         int r;
1890 
1891         assert(t);
1892 
1893         if (t->scope->protocol == DNS_PROTOCOL_MDNS)
1894                 return dns_transaction_make_packet_mdns(t);
1895 
1896         if (t->sent)
1897                 return 0;
1898 
1899         if (t->bypass && t->bypass->protocol == t->scope->protocol) {
1900                 /* If bypass logic is enabled and the protocol if the original packet and our scope match,
1901                  * take the original packet, copy it, and patch in our new ID */
1902                 r = dns_packet_dup(&p, t->bypass);
1903                 if (r < 0)
1904                         return r;
1905         } else {
1906                 r = dns_packet_new_query(
1907                                 &p, t->scope->protocol,
1908                                 /* min_alloc_dsize = */ 0,
1909                                 /* dnssec_cd = */ !FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) &&
1910                                                   t->scope->dnssec_mode != DNSSEC_NO);
1911                 if (r < 0)
1912                         return r;
1913 
1914                 r = dns_packet_append_key(p, dns_transaction_key(t), 0, NULL);
1915                 if (r < 0)
1916                         return r;
1917 
1918                 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
1919         }
1920 
1921         DNS_PACKET_HEADER(p)->id = t->id;
1922 
1923         t->sent = TAKE_PTR(p);
1924         return 0;
1925 }
1926 
dns_transaction_go(DnsTransaction * t)1927 int dns_transaction_go(DnsTransaction *t) {
1928         usec_t ts;
1929         int r;
1930         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
1931 
1932         assert(t);
1933 
1934         /* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has
1935          * finished now. In the latter case, the transaction and query candidate objects must not be accessed.
1936          */
1937 
1938         assert_se(sd_event_now(t->scope->manager->event, CLOCK_BOOTTIME, &ts) >= 0);
1939 
1940         r = dns_transaction_prepare(t, ts);
1941         if (r <= 0)
1942                 return r;
1943 
1944         log_debug("Firing %s transaction %" PRIu16 " for <%s> scope %s on %s/%s (validate=%s).",
1945                   t->bypass ? "bypass" : "regular",
1946                   t->id,
1947                   dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str),
1948                   dns_protocol_to_string(t->scope->protocol),
1949                   t->scope->link ? t->scope->link->ifname : "*",
1950                   af_to_name_short(t->scope->family),
1951                   yes_no(!FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE)));
1952 
1953         if (!t->initial_jitter_scheduled &&
1954             IN_SET(t->scope->protocol, DNS_PROTOCOL_LLMNR, DNS_PROTOCOL_MDNS)) {
1955                 usec_t jitter, accuracy;
1956 
1957                 /* RFC 4795 Section 2.7 suggests all queries should be delayed by a random time from 0 to
1958                  * JITTER_INTERVAL. */
1959 
1960                 t->initial_jitter_scheduled = true;
1961 
1962                 switch (t->scope->protocol) {
1963 
1964                 case DNS_PROTOCOL_LLMNR:
1965                         jitter = random_u64_range(LLMNR_JITTER_INTERVAL_USEC);
1966                         accuracy = LLMNR_JITTER_INTERVAL_USEC;
1967                         break;
1968 
1969                 case DNS_PROTOCOL_MDNS:
1970                         jitter = usec_add(random_u64_range(MDNS_JITTER_RANGE_USEC), MDNS_JITTER_MIN_USEC);
1971                         accuracy = MDNS_JITTER_RANGE_USEC;
1972                         break;
1973                 default:
1974                         assert_not_reached();
1975                 }
1976 
1977                 assert(!t->timeout_event_source);
1978 
1979                 r = sd_event_add_time_relative(
1980                                 t->scope->manager->event,
1981                                 &t->timeout_event_source,
1982                                 CLOCK_BOOTTIME,
1983                                 jitter, accuracy,
1984                                 on_transaction_timeout, t);
1985                 if (r < 0)
1986                         return r;
1987 
1988                 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1989 
1990                 t->n_attempts = 0;
1991                 t->next_attempt_after = ts;
1992                 t->state = DNS_TRANSACTION_PENDING;
1993 
1994                 log_debug("Delaying %s transaction %" PRIu16 " for " USEC_FMT "us.",
1995                           dns_protocol_to_string(t->scope->protocol),
1996                           t->id,
1997                           jitter);
1998                 return 1;
1999         }
2000 
2001         /* Otherwise, we need to ask the network */
2002         r = dns_transaction_make_packet(t);
2003         if (r < 0)
2004                 return r;
2005 
2006         if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
2007             (dns_name_endswith(dns_resource_key_name(dns_transaction_key(t)), "in-addr.arpa") > 0 ||
2008              dns_name_endswith(dns_resource_key_name(dns_transaction_key(t)), "ip6.arpa") > 0)) {
2009 
2010                 /* RFC 4795, Section 2.4. says reverse lookups shall
2011                  * always be made via TCP on LLMNR */
2012                 r = dns_transaction_emit_tcp(t);
2013         } else {
2014                 /* Try via UDP, and if that fails due to large size or lack of
2015                  * support try via TCP */
2016                 r = dns_transaction_emit_udp(t);
2017                 if (r == -EMSGSIZE)
2018                         log_debug("Sending query via TCP since it is too large.");
2019                 else if (r == -EAGAIN)
2020                         log_debug("Sending query via TCP since UDP isn't supported or DNS-over-TLS is selected.");
2021                 if (IN_SET(r, -EMSGSIZE, -EAGAIN))
2022                         r = dns_transaction_emit_tcp(t);
2023         }
2024         if (r == -ELOOP) {
2025                 if (t->scope->protocol != DNS_PROTOCOL_DNS)
2026                         return r;
2027 
2028                 /* One of our own stub listeners */
2029                 log_debug_errno(r, "Detected that specified DNS server is our own extra listener, switching DNS servers.");
2030 
2031                 dns_scope_next_dns_server(t->scope, t->server);
2032 
2033                 if (dns_scope_get_dns_server(t->scope) == t->server) {
2034                         log_debug_errno(r, "Still pointing to extra listener after switching DNS servers, refusing operation.");
2035                         dns_transaction_complete(t, DNS_TRANSACTION_STUB_LOOP);
2036                         return 0;
2037                 }
2038 
2039                 return dns_transaction_go(t);
2040         }
2041         if (r == -ESRCH) {
2042                 /* No servers to send this to? */
2043                 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
2044                 return 0;
2045         }
2046         if (r == -EOPNOTSUPP) {
2047                 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC  */
2048                 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
2049                 return 0;
2050         }
2051         if (t->scope->protocol == DNS_PROTOCOL_LLMNR && ERRNO_IS_DISCONNECT(r)) {
2052                 /* On LLMNR, if we cannot connect to a host via TCP when doing reverse lookups. This means we cannot
2053                  * answer this request with this protocol. */
2054                 dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
2055                 return 0;
2056         }
2057         if (r < 0) {
2058                 if (t->scope->protocol != DNS_PROTOCOL_DNS)
2059                         return r;
2060 
2061                 /* Couldn't send? Try immediately again, with a new server */
2062                 dns_scope_next_dns_server(t->scope, t->server);
2063 
2064                 return dns_transaction_go(t);
2065         }
2066 
2067         ts += transaction_get_resend_timeout(t);
2068 
2069         r = sd_event_add_time(
2070                         t->scope->manager->event,
2071                         &t->timeout_event_source,
2072                         CLOCK_BOOTTIME,
2073                         ts, 0,
2074                         on_transaction_timeout, t);
2075         if (r < 0)
2076                 return r;
2077 
2078         (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
2079 
2080         t->state = DNS_TRANSACTION_PENDING;
2081         t->next_attempt_after = ts;
2082 
2083         return 1;
2084 }
2085 
dns_transaction_find_cyclic(DnsTransaction * t,DnsTransaction * aux)2086 static int dns_transaction_find_cyclic(DnsTransaction *t, DnsTransaction *aux) {
2087         DnsTransaction *n;
2088         int r;
2089 
2090         assert(t);
2091         assert(aux);
2092 
2093         /* Try to find cyclic dependencies between transaction objects */
2094 
2095         if (t == aux)
2096                 return 1;
2097 
2098         SET_FOREACH(n, aux->dnssec_transactions) {
2099                 r = dns_transaction_find_cyclic(t, n);
2100                 if (r != 0)
2101                         return r;
2102         }
2103 
2104         return 0;
2105 }
2106 
dns_transaction_add_dnssec_transaction(DnsTransaction * t,DnsResourceKey * key,DnsTransaction ** ret)2107 static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
2108         _cleanup_(dns_transaction_gcp) DnsTransaction *aux = NULL;
2109         int r;
2110 
2111         assert(t);
2112         assert(ret);
2113         assert(key);
2114 
2115         aux = dns_scope_find_transaction(t->scope, key, t->query_flags);
2116         if (!aux) {
2117                 r = dns_transaction_new(&aux, t->scope, key, NULL, t->query_flags);
2118                 if (r < 0)
2119                         return r;
2120         } else {
2121                 if (set_contains(t->dnssec_transactions, aux)) {
2122                         *ret = aux;
2123                         return 0;
2124                 }
2125 
2126                 r = dns_transaction_find_cyclic(t, aux);
2127                 if (r < 0)
2128                         return r;
2129                 if (r > 0) {
2130                         char s[DNS_RESOURCE_KEY_STRING_MAX], saux[DNS_RESOURCE_KEY_STRING_MAX];
2131 
2132                         return log_debug_errno(SYNTHETIC_ERRNO(ELOOP),
2133                                                "Potential cyclic dependency, refusing to add transaction %" PRIu16 " (%s) as dependency for %" PRIu16 " (%s).",
2134                                                aux->id,
2135                                                dns_resource_key_to_string(dns_transaction_key(t), s, sizeof s),
2136                                                t->id,
2137                                                dns_resource_key_to_string(dns_transaction_key(aux), saux, sizeof saux));
2138                 }
2139         }
2140 
2141         r = set_ensure_allocated(&aux->notify_transactions_done, NULL);
2142         if (r < 0)
2143                 return r;
2144 
2145         r = set_ensure_put(&t->dnssec_transactions, NULL, aux);
2146         if (r < 0)
2147                 return r;
2148 
2149         r = set_ensure_put(&aux->notify_transactions, NULL, t);
2150         if (r < 0) {
2151                 (void) set_remove(t->dnssec_transactions, aux);
2152                 return r;
2153         }
2154 
2155         *ret = TAKE_PTR(aux);
2156         return 1;
2157 }
2158 
dns_transaction_request_dnssec_rr(DnsTransaction * t,DnsResourceKey * key)2159 static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
2160         _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL;
2161         DnsTransaction *aux;
2162         int r;
2163 
2164         assert(t);
2165         assert(key);
2166 
2167         /* Try to get the data from the trust anchor */
2168         r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, key, &a);
2169         if (r < 0)
2170                 return r;
2171         if (r > 0) {
2172                 r = dns_answer_extend(&t->validated_keys, a);
2173                 if (r < 0)
2174                         return r;
2175 
2176                 return 0;
2177         }
2178 
2179         /* This didn't work, ask for it via the network/cache then. */
2180         r = dns_transaction_add_dnssec_transaction(t, key, &aux);
2181         if (r == -ELOOP) /* This would result in a cyclic dependency */
2182                 return 0;
2183         if (r < 0)
2184                 return r;
2185 
2186         if (aux->state == DNS_TRANSACTION_NULL) {
2187                 r = dns_transaction_go(aux);
2188                 if (r < 0)
2189                         return r;
2190         }
2191 
2192         return 1;
2193 }
2194 
dns_transaction_negative_trust_anchor_lookup(DnsTransaction * t,const char * name)2195 static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const char *name) {
2196         int r;
2197 
2198         assert(t);
2199 
2200         /* Check whether the specified name is in the NTA
2201          * database, either in the global one, or the link-local
2202          * one. */
2203 
2204         r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, name);
2205         if (r != 0)
2206                 return r;
2207 
2208         if (!t->scope->link)
2209                 return 0;
2210 
2211         return link_negative_trust_anchor_lookup(t->scope->link, name);
2212 }
2213 
dns_transaction_has_negative_answer(DnsTransaction * t)2214 static int dns_transaction_has_negative_answer(DnsTransaction *t) {
2215         int r;
2216 
2217         assert(t);
2218 
2219         /* Checks whether the answer is negative, and lacks NSEC/NSEC3
2220          * RRs to prove it */
2221 
2222         r = dns_transaction_has_positive_answer(t, NULL);
2223         if (r < 0)
2224                 return r;
2225         if (r > 0)
2226                 return false;
2227 
2228         /* Is this key explicitly listed as a negative trust anchor?
2229          * If so, it's nothing we need to care about */
2230         r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(dns_transaction_key(t)));
2231         if (r < 0)
2232                 return r;
2233         return !r;
2234 }
2235 
dns_transaction_is_primary_response(DnsTransaction * t,DnsResourceRecord * rr)2236 static int dns_transaction_is_primary_response(DnsTransaction *t, DnsResourceRecord *rr) {
2237         int r;
2238 
2239         assert(t);
2240         assert(rr);
2241 
2242         /* Check if the specified RR is the "primary" response,
2243          * i.e. either matches the question precisely or is a
2244          * CNAME/DNAME for it. */
2245 
2246         r = dns_resource_key_match_rr(dns_transaction_key(t), rr, NULL);
2247         if (r != 0)
2248                 return r;
2249 
2250         return dns_resource_key_match_cname_or_dname(dns_transaction_key(t), rr->key, NULL);
2251 }
2252 
dns_transaction_dnssec_supported(DnsTransaction * t)2253 static bool dns_transaction_dnssec_supported(DnsTransaction *t) {
2254         assert(t);
2255 
2256         /* Checks whether our transaction's DNS server is assumed to be compatible with DNSSEC. Returns false as soon
2257          * as we changed our mind about a server, and now believe it is incompatible with DNSSEC. */
2258 
2259         if (t->scope->protocol != DNS_PROTOCOL_DNS)
2260                 return false;
2261 
2262         /* If we have picked no server, then we are working from the cache or some other source, and DNSSEC might well
2263          * be supported, hence return true. */
2264         if (!t->server)
2265                 return true;
2266 
2267         /* Note that we do not check the feature level actually used for the transaction but instead the feature level
2268          * the server is known to support currently, as the transaction feature level might be lower than what the
2269          * server actually supports, since we might have downgraded this transaction's feature level because we got a
2270          * SERVFAIL earlier and wanted to check whether downgrading fixes it. */
2271 
2272         return dns_server_dnssec_supported(t->server);
2273 }
2274 
dns_transaction_dnssec_supported_full(DnsTransaction * t)2275 static bool dns_transaction_dnssec_supported_full(DnsTransaction *t) {
2276         DnsTransaction *dt;
2277 
2278         assert(t);
2279 
2280         /* Checks whether our transaction our any of the auxiliary transactions couldn't do DNSSEC. */
2281 
2282         if (!dns_transaction_dnssec_supported(t))
2283                 return false;
2284 
2285         SET_FOREACH(dt, t->dnssec_transactions)
2286                 if (!dns_transaction_dnssec_supported(dt))
2287                         return false;
2288 
2289         return true;
2290 }
2291 
dns_transaction_request_dnssec_keys(DnsTransaction * t)2292 int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
2293         DnsResourceRecord *rr;
2294 
2295         int r;
2296 
2297         assert(t);
2298 
2299         /*
2300          * Retrieve all auxiliary RRs for the answer we got, so that
2301          * we can verify signatures or prove that RRs are rightfully
2302          * unsigned. Specifically:
2303          *
2304          * - For RRSIG we get the matching DNSKEY
2305          * - For DNSKEY we get the matching DS
2306          * - For unsigned SOA/NS we get the matching DS
2307          * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
2308          * - For other unsigned RRs we get the matching SOA RR
2309          * - For SOA/NS queries with no matching response RR, and no NSEC/NSEC3, the DS RR
2310          * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
2311          * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
2312          */
2313 
2314         if (FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) || t->scope->dnssec_mode == DNSSEC_NO)
2315                 return 0;
2316         if (t->answer_source != DNS_TRANSACTION_NETWORK)
2317                 return 0; /* We only need to validate stuff from the network */
2318         if (!dns_transaction_dnssec_supported(t))
2319                 return 0; /* If we can't do DNSSEC anyway there's no point in getting the auxiliary RRs */
2320 
2321         DNS_ANSWER_FOREACH(rr, t->answer) {
2322 
2323                 if (dns_type_is_pseudo(rr->key->type))
2324                         continue;
2325 
2326                 /* If this RR is in the negative trust anchor, we don't need to validate it. */
2327                 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
2328                 if (r < 0)
2329                         return r;
2330                 if (r > 0)
2331                         continue;
2332 
2333                 switch (rr->key->type) {
2334 
2335                 case DNS_TYPE_RRSIG: {
2336                         /* For each RRSIG we request the matching DNSKEY */
2337                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
2338 
2339                         /* If this RRSIG is about a DNSKEY RR and the
2340                          * signer is the same as the owner, then we
2341                          * already have the DNSKEY, and we don't have
2342                          * to look for more. */
2343                         if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
2344                                 r = dns_name_equal(rr->rrsig.signer, dns_resource_key_name(rr->key));
2345                                 if (r < 0)
2346                                         return r;
2347                                 if (r > 0)
2348                                         continue;
2349                         }
2350 
2351                         /* If the signer is not a parent of our
2352                          * original query, then this is about an
2353                          * auxiliary RRset, but not anything we asked
2354                          * for. In this case we aren't interested,
2355                          * because we don't want to request additional
2356                          * RRs for stuff we didn't really ask for, and
2357                          * also to avoid request loops, where
2358                          * additional RRs from one transaction result
2359                          * in another transaction whose additional RRs
2360                          * point back to the original transaction, and
2361                          * we deadlock. */
2362                         r = dns_name_endswith(dns_resource_key_name(dns_transaction_key(t)), rr->rrsig.signer);
2363                         if (r < 0)
2364                                 return r;
2365                         if (r == 0)
2366                                 continue;
2367 
2368                         dnskey = dns_resource_key_new(rr->key->class, DNS_TYPE_DNSKEY, rr->rrsig.signer);
2369                         if (!dnskey)
2370                                 return -ENOMEM;
2371 
2372                         log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").",
2373                                   t->id, dns_resource_key_name(rr->key), rr->rrsig.key_tag);
2374                         r = dns_transaction_request_dnssec_rr(t, dnskey);
2375                         if (r < 0)
2376                                 return r;
2377                         break;
2378                 }
2379 
2380                 case DNS_TYPE_DNSKEY: {
2381                         /* For each DNSKEY we request the matching DS */
2382                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
2383 
2384                         /* If the DNSKEY we are looking at is not for
2385                          * zone we are interested in, nor any of its
2386                          * parents, we aren't interested, and don't
2387                          * request it. After all, we don't want to end
2388                          * up in request loops, and want to keep
2389                          * additional traffic down. */
2390 
2391                         r = dns_name_endswith(dns_resource_key_name(dns_transaction_key(t)), dns_resource_key_name(rr->key));
2392                         if (r < 0)
2393                                 return r;
2394                         if (r == 0)
2395                                 continue;
2396 
2397                         ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
2398                         if (!ds)
2399                                 return -ENOMEM;
2400 
2401                         log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").",
2402                                   t->id, dns_resource_key_name(rr->key), dnssec_keytag(rr, false));
2403                         r = dns_transaction_request_dnssec_rr(t, ds);
2404                         if (r < 0)
2405                                 return r;
2406 
2407                         break;
2408                 }
2409 
2410                 case DNS_TYPE_SOA:
2411                 case DNS_TYPE_NS: {
2412                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
2413 
2414                         /* For an unsigned SOA or NS, try to acquire
2415                          * the matching DS RR, as we are at a zone cut
2416                          * then, and whether a DS exists tells us
2417                          * whether the zone is signed. Do so only if
2418                          * this RR matches our original question,
2419                          * however. */
2420 
2421                         r = dns_resource_key_match_rr(dns_transaction_key(t), rr, NULL);
2422                         if (r < 0)
2423                                 return r;
2424                         if (r == 0) {
2425                                 /* Hmm, so this SOA RR doesn't match our original question. In this case, maybe this is
2426                                  * a negative reply, and we need the SOA RR's TTL in order to cache a negative entry?
2427                                  * If so, we need to validate it, too. */
2428 
2429                                 r = dns_answer_match_key(t->answer, dns_transaction_key(t), NULL);
2430                                 if (r < 0)
2431                                         return r;
2432                                 if (r > 0) /* positive reply, we won't need the SOA and hence don't need to validate
2433                                             * it. */
2434                                         continue;
2435 
2436                                 /* Only bother with this if the SOA/NS RR we are looking at is actually a parent of
2437                                  * what we are looking for, otherwise there's no value in it for us. */
2438                                 r = dns_name_endswith(dns_resource_key_name(dns_transaction_key(t)), dns_resource_key_name(rr->key));
2439                                 if (r < 0)
2440                                         return r;
2441                                 if (r == 0)
2442                                         continue;
2443                         }
2444 
2445                         r = dnssec_has_rrsig(t->answer, rr->key);
2446                         if (r < 0)
2447                                 return r;
2448                         if (r > 0)
2449                                 continue;
2450 
2451                         ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
2452                         if (!ds)
2453                                 return -ENOMEM;
2454 
2455                         log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).",
2456                                   t->id, dns_resource_key_name(rr->key));
2457                         r = dns_transaction_request_dnssec_rr(t, ds);
2458                         if (r < 0)
2459                                 return r;
2460 
2461                         break;
2462                 }
2463 
2464                 case DNS_TYPE_DS:
2465                 case DNS_TYPE_CNAME:
2466                 case DNS_TYPE_DNAME: {
2467                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2468                         const char *name;
2469 
2470                         /* CNAMEs and DNAMEs cannot be located at a
2471                          * zone apex, hence ask for the parent SOA for
2472                          * unsigned CNAME/DNAME RRs, maybe that's the
2473                          * apex. But do all that only if this is
2474                          * actually a response to our original
2475                          * question.
2476                          *
2477                          * Similar for DS RRs, which are signed when
2478                          * the parent SOA is signed. */
2479 
2480                         r = dns_transaction_is_primary_response(t, rr);
2481                         if (r < 0)
2482                                 return r;
2483                         if (r == 0)
2484                                 continue;
2485 
2486                         r = dnssec_has_rrsig(t->answer, rr->key);
2487                         if (r < 0)
2488                                 return r;
2489                         if (r > 0)
2490                                 continue;
2491 
2492                         r = dns_answer_has_dname_for_cname(t->answer, rr);
2493                         if (r < 0)
2494                                 return r;
2495                         if (r > 0)
2496                                 continue;
2497 
2498                         name = dns_resource_key_name(rr->key);
2499                         r = dns_name_parent(&name);
2500                         if (r < 0)
2501                                 return r;
2502                         if (r == 0)
2503                                 continue;
2504 
2505                         soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
2506                         if (!soa)
2507                                 return -ENOMEM;
2508 
2509                         log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).",
2510                                   t->id, dns_resource_key_name(rr->key));
2511                         r = dns_transaction_request_dnssec_rr(t, soa);
2512                         if (r < 0)
2513                                 return r;
2514 
2515                         break;
2516                 }
2517 
2518                 default: {
2519                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2520 
2521                         /* For other unsigned RRsets (including
2522                          * NSEC/NSEC3!), look for proof the zone is
2523                          * unsigned, by requesting the SOA RR of the
2524                          * zone. However, do so only if they are
2525                          * directly relevant to our original
2526                          * question. */
2527 
2528                         r = dns_transaction_is_primary_response(t, rr);
2529                         if (r < 0)
2530                                 return r;
2531                         if (r == 0)
2532                                 continue;
2533 
2534                         r = dnssec_has_rrsig(t->answer, rr->key);
2535                         if (r < 0)
2536                                 return r;
2537                         if (r > 0)
2538                                 continue;
2539 
2540                         soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, dns_resource_key_name(rr->key));
2541                         if (!soa)
2542                                 return -ENOMEM;
2543 
2544                         log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).",
2545                                   t->id, dns_resource_key_name(rr->key), dns_resource_record_to_string(rr));
2546                         r = dns_transaction_request_dnssec_rr(t, soa);
2547                         if (r < 0)
2548                                 return r;
2549                         break;
2550                 }}
2551         }
2552 
2553         /* Above, we requested everything necessary to validate what
2554          * we got. Now, let's request what we need to validate what we
2555          * didn't get... */
2556 
2557         r = dns_transaction_has_negative_answer(t);
2558         if (r < 0)
2559                 return r;
2560         if (r > 0) {
2561                 const char *name, *signed_status;
2562                 uint16_t type = 0;
2563 
2564                 name = dns_resource_key_name(dns_transaction_key(t));
2565                 signed_status = dns_answer_contains_nsec_or_nsec3(t->answer) ? "signed" : "unsigned";
2566 
2567                 /* If this was a SOA or NS request, then check if there's a DS RR for the same domain. Note that this
2568                  * could also be used as indication that we are not at a zone apex, but in real world setups there are
2569                  * too many broken DNS servers (Hello, incapdns.net!) where non-terminal zones return NXDOMAIN even
2570                  * though they have further children. If this was a DS request, then it's signed when the parent zone
2571                  * is signed, hence ask the parent SOA in that case. If this was any other RR then ask for the SOA RR,
2572                  * to see if that is signed. */
2573 
2574                 if (dns_transaction_key(t)->type == DNS_TYPE_DS) {
2575                         r = dns_name_parent(&name);
2576                         if (r > 0) {
2577                                 type = DNS_TYPE_SOA;
2578                                 log_debug("Requesting parent SOA (→ %s) to validate transaction %" PRIu16 " (%s, %s empty DS response).",
2579                                           name, t->id, dns_resource_key_name(dns_transaction_key(t)), signed_status);
2580                         } else
2581                                 name = NULL;
2582 
2583                 } else if (IN_SET(dns_transaction_key(t)->type, DNS_TYPE_SOA, DNS_TYPE_NS)) {
2584 
2585                         type = DNS_TYPE_DS;
2586                         log_debug("Requesting DS (→ %s) to validate transaction %" PRIu16 " (%s, %s empty SOA/NS response).",
2587                                   name, t->id, name, signed_status);
2588 
2589                 } else {
2590                         type = DNS_TYPE_SOA;
2591                         log_debug("Requesting SOA (→ %s) to validate transaction %" PRIu16 " (%s, %s empty non-SOA/NS/DS response).",
2592                                   name, t->id, name, signed_status);
2593                 }
2594 
2595                 if (name) {
2596                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2597 
2598                         soa = dns_resource_key_new(dns_transaction_key(t)->class, type, name);
2599                         if (!soa)
2600                                 return -ENOMEM;
2601 
2602                         r = dns_transaction_request_dnssec_rr(t, soa);
2603                         if (r < 0)
2604                                 return r;
2605                 }
2606         }
2607 
2608         return dns_transaction_dnssec_is_live(t);
2609 }
2610 
dns_transaction_notify(DnsTransaction * t,DnsTransaction * source)2611 void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source) {
2612         assert(t);
2613         assert(source);
2614 
2615         /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
2616            we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
2617            the state is VALIDATING however, we should check if we are complete now. */
2618 
2619         if (t->state == DNS_TRANSACTION_VALIDATING)
2620                 dns_transaction_process_dnssec(t);
2621 }
2622 
dns_transaction_validate_dnskey_by_ds(DnsTransaction * t)2623 static int dns_transaction_validate_dnskey_by_ds(DnsTransaction *t) {
2624         DnsAnswerItem *item;
2625         int r;
2626 
2627         assert(t);
2628 
2629         /* Add all DNSKEY RRs from the answer that are validated by DS
2630          * RRs from the list of validated keys to the list of
2631          * validated keys. */
2632 
2633         DNS_ANSWER_FOREACH_ITEM(item, t->answer) {
2634 
2635                 r = dnssec_verify_dnskey_by_ds_search(item->rr, t->validated_keys);
2636                 if (r < 0)
2637                         return r;
2638                 if (r == 0)
2639                         continue;
2640 
2641                 /* If so, the DNSKEY is validated too. */
2642                 r = dns_answer_add_extend(&t->validated_keys, item->rr, item->ifindex, item->flags|DNS_ANSWER_AUTHENTICATED, item->rrsig);
2643                 if (r < 0)
2644                         return r;
2645         }
2646 
2647         return 0;
2648 }
2649 
dns_transaction_requires_rrsig(DnsTransaction * t,DnsResourceRecord * rr)2650 static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *rr) {
2651         int r;
2652 
2653         assert(t);
2654         assert(rr);
2655 
2656         /* Checks if the RR we are looking for must be signed with an
2657          * RRSIG. This is used for positive responses. */
2658 
2659         if (t->scope->dnssec_mode == DNSSEC_NO)
2660                 return false;
2661 
2662         if (dns_type_is_pseudo(rr->key->type))
2663                 return -EINVAL;
2664 
2665         r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
2666         if (r < 0)
2667                 return r;
2668         if (r > 0)
2669                 return false;
2670 
2671         switch (rr->key->type) {
2672 
2673         case DNS_TYPE_RRSIG:
2674                 /* RRSIGs are the signatures themselves, they need no signing. */
2675                 return false;
2676 
2677         case DNS_TYPE_SOA:
2678         case DNS_TYPE_NS: {
2679                 DnsTransaction *dt;
2680 
2681                 /* For SOA or NS RRs we look for a matching DS transaction */
2682 
2683                 SET_FOREACH(dt, t->dnssec_transactions) {
2684 
2685                         if (dns_transaction_key(dt)->class != rr->key->class)
2686                                 continue;
2687                         if (dns_transaction_key(dt)->type != DNS_TYPE_DS)
2688                                 continue;
2689 
2690                         r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), dns_resource_key_name(rr->key));
2691                         if (r < 0)
2692                                 return r;
2693                         if (r == 0)
2694                                 continue;
2695 
2696                         /* We found a DS transactions for the SOA/NS
2697                          * RRs we are looking at. If it discovered signed DS
2698                          * RRs, then we need to be signed, too. */
2699 
2700                         if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
2701                                 return false;
2702 
2703                         return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL);
2704                 }
2705 
2706                 /* We found nothing that proves this is safe to leave
2707                  * this unauthenticated, hence ask inist on
2708                  * authentication. */
2709                 return true;
2710         }
2711 
2712         case DNS_TYPE_DS:
2713         case DNS_TYPE_CNAME:
2714         case DNS_TYPE_DNAME: {
2715                 const char *parent = NULL;
2716                 DnsTransaction *dt;
2717 
2718                 /*
2719                  * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
2720                  *
2721                  * DS RRs are signed if the parent is signed, hence also look at the parent SOA
2722                  */
2723 
2724                 SET_FOREACH(dt, t->dnssec_transactions) {
2725 
2726                         if (dns_transaction_key(dt)->class != rr->key->class)
2727                                 continue;
2728                         if (dns_transaction_key(dt)->type != DNS_TYPE_SOA)
2729                                 continue;
2730 
2731                         if (!parent) {
2732                                 parent = dns_resource_key_name(rr->key);
2733                                 r = dns_name_parent(&parent);
2734                                 if (r < 0)
2735                                         return r;
2736                                 if (r == 0) {
2737                                         if (rr->key->type == DNS_TYPE_DS)
2738                                                 return true;
2739 
2740                                         /* A CNAME/DNAME without a parent? That's sooo weird. */
2741                                         return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
2742                                                                "Transaction %" PRIu16 " claims CNAME/DNAME at root. Refusing.", t->id);
2743                                 }
2744                         }
2745 
2746                         r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), parent);
2747                         if (r < 0)
2748                                 return r;
2749                         if (r == 0)
2750                                 continue;
2751 
2752                         return FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
2753                 }
2754 
2755                 return true;
2756         }
2757 
2758         default: {
2759                 DnsTransaction *dt;
2760 
2761                 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
2762 
2763                 SET_FOREACH(dt, t->dnssec_transactions) {
2764 
2765                         if (dns_transaction_key(dt)->class != rr->key->class)
2766                                 continue;
2767                         if (dns_transaction_key(dt)->type != DNS_TYPE_SOA)
2768                                 continue;
2769 
2770                         r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), dns_resource_key_name(rr->key));
2771                         if (r < 0)
2772                                 return r;
2773                         if (r == 0)
2774                                 continue;
2775 
2776                         /* We found the transaction that was supposed to find the SOA RR for us. It was
2777                          * successful, but found no RR for us. This means we are not at a zone cut. In this
2778                          * case, we require authentication if the SOA lookup was authenticated too. */
2779                         return FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
2780                 }
2781 
2782                 return true;
2783         }}
2784 }
2785 
dns_transaction_in_private_tld(DnsTransaction * t,const DnsResourceKey * key)2786 static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKey *key) {
2787         DnsTransaction *dt;
2788         const char *tld;
2789         int r;
2790 
2791         /* If DNSSEC downgrade mode is on, checks whether the
2792          * specified RR is one level below a TLD we have proven not to
2793          * exist. In such a case we assume that this is a private
2794          * domain, and permit it.
2795          *
2796          * This detects cases like the Fritz!Box router networks. Each
2797          * Fritz!Box router serves a private "fritz.box" zone, in the
2798          * non-existing TLD "box". Requests for the "fritz.box" domain
2799          * are served by the router itself, while requests for the
2800          * "box" domain will result in NXDOMAIN.
2801          *
2802          * Note that this logic is unable to detect cases where a
2803          * router serves a private DNS zone directly under
2804          * non-existing TLD. In such a case we cannot detect whether
2805          * the TLD is supposed to exist or not, as all requests we
2806          * make for it will be answered by the router's zone, and not
2807          * by the root zone. */
2808 
2809         assert(t);
2810 
2811         if (t->scope->dnssec_mode != DNSSEC_ALLOW_DOWNGRADE)
2812                 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
2813 
2814         tld = dns_resource_key_name(key);
2815         r = dns_name_parent(&tld);
2816         if (r < 0)
2817                 return r;
2818         if (r == 0)
2819                 return false; /* Already the root domain */
2820 
2821         if (!dns_name_is_single_label(tld))
2822                 return false;
2823 
2824         SET_FOREACH(dt, t->dnssec_transactions) {
2825 
2826                 if (dns_transaction_key(dt)->class != key->class)
2827                         continue;
2828 
2829                 r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), tld);
2830                 if (r < 0)
2831                         return r;
2832                 if (r == 0)
2833                         continue;
2834 
2835                 /* We found an auxiliary lookup we did for the TLD. If
2836                  * that returned with NXDOMAIN, we know the TLD didn't
2837                  * exist, and hence this might be a private zone. */
2838 
2839                 return dt->answer_rcode == DNS_RCODE_NXDOMAIN;
2840         }
2841 
2842         return false;
2843 }
2844 
dns_transaction_requires_nsec(DnsTransaction * t)2845 static int dns_transaction_requires_nsec(DnsTransaction *t) {
2846         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
2847         DnsTransaction *dt;
2848         const char *name;
2849         uint16_t type = 0;
2850         int r;
2851 
2852         assert(t);
2853 
2854         /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
2855          * this negative reply */
2856 
2857         if (t->scope->dnssec_mode == DNSSEC_NO)
2858                 return false;
2859 
2860         if (dns_type_is_pseudo(dns_transaction_key(t)->type))
2861                 return -EINVAL;
2862 
2863         r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(dns_transaction_key(t)));
2864         if (r < 0)
2865                 return r;
2866         if (r > 0)
2867                 return false;
2868 
2869         r = dns_transaction_in_private_tld(t, dns_transaction_key(t));
2870         if (r < 0)
2871                 return r;
2872         if (r > 0) {
2873                 /* The lookup is from a TLD that is proven not to
2874                  * exist, and we are in downgrade mode, hence ignore
2875                  * that fact that we didn't get any NSEC RRs. */
2876 
2877                 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
2878                          dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str));
2879                 return false;
2880         }
2881 
2882         name = dns_resource_key_name(dns_transaction_key(t));
2883 
2884         if (dns_transaction_key(t)->type == DNS_TYPE_DS) {
2885 
2886                 /* We got a negative reply for this DS lookup? DS RRs are signed when their parent zone is signed,
2887                  * hence check the parent SOA in this case. */
2888 
2889                 r = dns_name_parent(&name);
2890                 if (r < 0)
2891                         return r;
2892                 if (r == 0)
2893                         return true;
2894 
2895                 type = DNS_TYPE_SOA;
2896 
2897         } else if (IN_SET(dns_transaction_key(t)->type, DNS_TYPE_SOA, DNS_TYPE_NS))
2898                 /* We got a negative reply for this SOA/NS lookup? If so, check if there's a DS RR for this */
2899                 type = DNS_TYPE_DS;
2900         else
2901                 /* For all other negative replies, check for the SOA lookup */
2902                 type = DNS_TYPE_SOA;
2903 
2904         /* For all other RRs we check the SOA on the same level to see
2905          * if it's signed. */
2906 
2907         SET_FOREACH(dt, t->dnssec_transactions) {
2908 
2909                 if (dns_transaction_key(dt)->class != dns_transaction_key(t)->class)
2910                         continue;
2911                 if (dns_transaction_key(dt)->type != type)
2912                         continue;
2913 
2914                 r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), name);
2915                 if (r < 0)
2916                         return r;
2917                 if (r == 0)
2918                         continue;
2919 
2920                 return FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
2921         }
2922 
2923         /* If in doubt, require NSEC/NSEC3 */
2924         return true;
2925 }
2926 
dns_transaction_dnskey_authenticated(DnsTransaction * t,DnsResourceRecord * rr)2927 static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRecord *rr) {
2928         DnsResourceRecord *rrsig;
2929         bool found = false;
2930         int r;
2931 
2932         /* Checks whether any of the DNSKEYs used for the RRSIGs for
2933          * the specified RRset is authenticated (i.e. has a matching
2934          * DS RR). */
2935 
2936         r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
2937         if (r < 0)
2938                 return r;
2939         if (r > 0)
2940                 return false;
2941 
2942         DNS_ANSWER_FOREACH(rrsig, t->answer) {
2943                 DnsTransaction *dt;
2944 
2945                 r = dnssec_key_match_rrsig(rr->key, rrsig);
2946                 if (r < 0)
2947                         return r;
2948                 if (r == 0)
2949                         continue;
2950 
2951                 SET_FOREACH(dt, t->dnssec_transactions) {
2952 
2953                         if (dns_transaction_key(dt)->class != rr->key->class)
2954                                 continue;
2955 
2956                         if (dns_transaction_key(dt)->type == DNS_TYPE_DNSKEY) {
2957 
2958                                 r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), rrsig->rrsig.signer);
2959                                 if (r < 0)
2960                                         return r;
2961                                 if (r == 0)
2962                                         continue;
2963 
2964                                 /* OK, we found an auxiliary DNSKEY lookup. If that lookup is authenticated,
2965                                  * report this. */
2966 
2967                                 if (FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
2968                                         return true;
2969 
2970                                 found = true;
2971 
2972                         } else if (dns_transaction_key(dt)->type == DNS_TYPE_DS) {
2973 
2974                                 r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), rrsig->rrsig.signer);
2975                                 if (r < 0)
2976                                         return r;
2977                                 if (r == 0)
2978                                         continue;
2979 
2980                                 /* OK, we found an auxiliary DS lookup. If that lookup is authenticated and
2981                                  * non-zero, we won! */
2982 
2983                                 if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
2984                                         return false;
2985 
2986                                 return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL);
2987                         }
2988                 }
2989         }
2990 
2991         return found ? false : -ENXIO;
2992 }
2993 
dns_transaction_known_signed(DnsTransaction * t,DnsResourceRecord * rr)2994 static int dns_transaction_known_signed(DnsTransaction *t, DnsResourceRecord *rr) {
2995         assert(t);
2996         assert(rr);
2997 
2998         /* We know that the root domain is signed, hence if it appears
2999          * not to be signed, there's a problem with the DNS server */
3000 
3001         return rr->key->class == DNS_CLASS_IN &&
3002                 dns_name_is_root(dns_resource_key_name(rr->key));
3003 }
3004 
dns_transaction_check_revoked_trust_anchors(DnsTransaction * t)3005 static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
3006         DnsResourceRecord *rr;
3007         int r;
3008 
3009         assert(t);
3010 
3011         /* Maybe warn the user that we encountered a revoked DNSKEY
3012          * for a key from our trust anchor. Note that we don't care
3013          * whether the DNSKEY can be authenticated or not. It's
3014          * sufficient if it is self-signed. */
3015 
3016         DNS_ANSWER_FOREACH(rr, t->answer) {
3017                 r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, rr, t->answer);
3018                 if (r < 0)
3019                         return r;
3020         }
3021 
3022         return 0;
3023 }
3024 
dns_transaction_invalidate_revoked_keys(DnsTransaction * t)3025 static int dns_transaction_invalidate_revoked_keys(DnsTransaction *t) {
3026         bool changed;
3027         int r;
3028 
3029         assert(t);
3030 
3031         /* Removes all DNSKEY/DS objects from t->validated_keys that
3032          * our trust anchors database considers revoked. */
3033 
3034         do {
3035                 DnsResourceRecord *rr;
3036 
3037                 changed = false;
3038 
3039                 DNS_ANSWER_FOREACH(rr, t->validated_keys) {
3040                         r = dns_trust_anchor_is_revoked(&t->scope->manager->trust_anchor, rr);
3041                         if (r < 0)
3042                                 return r;
3043                         if (r > 0) {
3044                                 r = dns_answer_remove_by_rr(&t->validated_keys, rr);
3045                                 if (r < 0)
3046                                         return r;
3047 
3048                                 assert(r > 0);
3049                                 changed = true;
3050                                 break;
3051                         }
3052                 }
3053         } while (changed);
3054 
3055         return 0;
3056 }
3057 
dns_transaction_copy_validated(DnsTransaction * t)3058 static int dns_transaction_copy_validated(DnsTransaction *t) {
3059         DnsTransaction *dt;
3060         int r;
3061 
3062         assert(t);
3063 
3064         /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
3065 
3066         SET_FOREACH(dt, t->dnssec_transactions) {
3067 
3068                 if (DNS_TRANSACTION_IS_LIVE(dt->state))
3069                         continue;
3070 
3071                 if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
3072                         continue;
3073 
3074                 r = dns_answer_extend(&t->validated_keys, dt->answer);
3075                 if (r < 0)
3076                         return r;
3077         }
3078 
3079         return 0;
3080 }
3081 
3082 typedef enum {
3083         DNSSEC_PHASE_DNSKEY,   /* Phase #1, only validate DNSKEYs */
3084         DNSSEC_PHASE_NSEC,     /* Phase #2, only validate NSEC+NSEC3 */
3085         DNSSEC_PHASE_ALL,      /* Phase #3, validate everything else */
3086 } Phase;
3087 
dnssec_validate_records(DnsTransaction * t,Phase phase,bool * have_nsec,DnsAnswer ** validated)3088 static int dnssec_validate_records(
3089                 DnsTransaction *t,
3090                 Phase phase,
3091                 bool *have_nsec,
3092                 DnsAnswer **validated) {
3093 
3094         DnsResourceRecord *rr;
3095         int r;
3096 
3097         /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
3098 
3099         DNS_ANSWER_FOREACH(rr, t->answer) {
3100                 _unused_ _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr_ref = dns_resource_record_ref(rr);
3101                 DnsResourceRecord *rrsig = NULL;
3102                 DnssecResult result;
3103 
3104                 switch (rr->key->type) {
3105                 case DNS_TYPE_RRSIG:
3106                         continue;
3107 
3108                 case DNS_TYPE_DNSKEY:
3109                         /* We validate DNSKEYs only in the DNSKEY and ALL phases */
3110                         if (phase == DNSSEC_PHASE_NSEC)
3111                                 continue;
3112                         break;
3113 
3114                 case DNS_TYPE_NSEC:
3115                 case DNS_TYPE_NSEC3:
3116                         *have_nsec = true;
3117 
3118                         /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
3119                         if (phase == DNSSEC_PHASE_DNSKEY)
3120                                 continue;
3121                         break;
3122 
3123                 default:
3124                         /* We validate all other RRs only in the ALL phases */
3125                         if (phase != DNSSEC_PHASE_ALL)
3126                                 continue;
3127                 }
3128 
3129                 r = dnssec_verify_rrset_search(
3130                                 t->answer,
3131                                 rr->key,
3132                                 t->validated_keys,
3133                                 USEC_INFINITY,
3134                                 &result,
3135                                 &rrsig);
3136                 if (r < 0)
3137                         return r;
3138 
3139                 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
3140 
3141                 if (result == DNSSEC_VALIDATED) {
3142                         assert(rrsig);
3143 
3144                         if (rr->key->type == DNS_TYPE_DNSKEY) {
3145                                 /* If we just validated a DNSKEY RRset, then let's add these keys to
3146                                  * the set of validated keys for this transaction. */
3147 
3148                                 r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED, rrsig);
3149                                 if (r < 0)
3150                                         return r;
3151 
3152                                 /* Some of the DNSKEYs we just added might already have been revoked,
3153                                  * remove them again in that case. */
3154                                 r = dns_transaction_invalidate_revoked_keys(t);
3155                                 if (r < 0)
3156                                         return r;
3157                         }
3158 
3159                         /* Add the validated RRset to the new list of validated RRsets, and remove it from
3160                          * the unvalidated RRsets.  We mark the RRset as authenticated and cacheable. */
3161                         r = dns_answer_move_by_key(validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE, rrsig);
3162                         if (r < 0)
3163                                 return r;
3164 
3165                         manager_dnssec_verdict(t->scope->manager, DNSSEC_SECURE, rr->key);
3166 
3167                         /* Exit the loop, we dropped something from the answer, start from the beginning */
3168                         return 1;
3169                 }
3170 
3171                 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
3172                  * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet,
3173                  * we cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
3174                 if (phase != DNSSEC_PHASE_ALL)
3175                         continue;
3176 
3177                 if (result == DNSSEC_VALIDATED_WILDCARD) {
3178                         bool authenticated = false;
3179                         const char *source;
3180 
3181                         assert(rrsig);
3182 
3183                         /* This RRset validated, but as a wildcard. This means we need
3184                          * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists. */
3185 
3186                         /* First step, determine the source of synthesis */
3187                         r = dns_resource_record_source(rrsig, &source);
3188                         if (r < 0)
3189                                 return r;
3190 
3191                         r = dnssec_test_positive_wildcard(*validated,
3192                                                           dns_resource_key_name(rr->key),
3193                                                           source,
3194                                                           rrsig->rrsig.signer,
3195                                                           &authenticated);
3196 
3197                         /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
3198                         if (r == 0)
3199                                 result = DNSSEC_INVALID;
3200                         else {
3201                                 r = dns_answer_move_by_key(
3202                                                 validated,
3203                                                 &t->answer,
3204                                                 rr->key,
3205                                                 authenticated ? (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE) : 0,
3206                                                 rrsig);
3207                                 if (r < 0)
3208                                         return r;
3209 
3210                                 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, rr->key);
3211 
3212                                 /* Exit the loop, we dropped something from the answer, start from the beginning */
3213                                 return 1;
3214                         }
3215                 }
3216 
3217                 if (result == DNSSEC_NO_SIGNATURE) {
3218                         r = dns_transaction_requires_rrsig(t, rr);
3219                         if (r < 0)
3220                                 return r;
3221                         if (r == 0) {
3222                                 /* Data does not require signing. In that case, just copy it over,
3223                                  * but remember that this is by no means authenticated. */
3224                                 r = dns_answer_move_by_key(
3225                                                 validated,
3226                                                 &t->answer,
3227                                                 rr->key,
3228                                                 0,
3229                                                 NULL);
3230                                 if (r < 0)
3231                                         return r;
3232 
3233                                 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3234                                 return 1;
3235                         }
3236 
3237                         r = dns_transaction_known_signed(t, rr);
3238                         if (r < 0)
3239                                 return r;
3240                         if (r > 0) {
3241                                 /* This is an RR we know has to be signed. If it isn't this means
3242                                  * the server is not attaching RRSIGs, hence complain. */
3243 
3244                                 dns_server_packet_rrsig_missing(t->server, t->current_feature_level);
3245 
3246                                 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
3247 
3248                                         /* Downgrading is OK? If so, just consider the information unsigned */
3249 
3250                                         r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0, NULL);
3251                                         if (r < 0)
3252                                                 return r;
3253 
3254                                         manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3255                                         return 1;
3256                                 }
3257 
3258                                 /* Otherwise, fail */
3259                                 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
3260                                 return 0;
3261                         }
3262 
3263                         r = dns_transaction_in_private_tld(t, rr->key);
3264                         if (r < 0)
3265                                 return r;
3266                         if (r > 0) {
3267                                 char s[DNS_RESOURCE_KEY_STRING_MAX];
3268 
3269                                 /* The data is from a TLD that is proven not to exist, and we are in downgrade
3270                                  * mode, hence ignore the fact that this was not signed. */
3271 
3272                                 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.",
3273                                          dns_resource_key_to_string(rr->key, s, sizeof s));
3274 
3275                                 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0, NULL);
3276                                 if (r < 0)
3277                                         return r;
3278 
3279                                 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3280                                 return 1;
3281                         }
3282                 }
3283 
3284                 if (IN_SET(result,
3285                            DNSSEC_MISSING_KEY,
3286                            DNSSEC_SIGNATURE_EXPIRED,
3287                            DNSSEC_UNSUPPORTED_ALGORITHM)) {
3288 
3289                         r = dns_transaction_dnskey_authenticated(t, rr);
3290                         if (r < 0 && r != -ENXIO)
3291                                 return r;
3292                         if (r == 0) {
3293                                 /* The DNSKEY transaction was not authenticated, this means there's
3294                                  * no DS for this, which means it's OK if no keys are found for this signature. */
3295 
3296                                 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0, NULL);
3297                                 if (r < 0)
3298                                         return r;
3299 
3300                                 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3301                                 return 1;
3302                         }
3303                 }
3304 
3305                 r = dns_transaction_is_primary_response(t, rr);
3306                 if (r < 0)
3307                         return r;
3308                 if (r > 0) {
3309                         /* Look for a matching DNAME for this CNAME */
3310                         r = dns_answer_has_dname_for_cname(t->answer, rr);
3311                         if (r < 0)
3312                                 return r;
3313                         if (r == 0) {
3314                                 /* Also look among the stuff we already validated */
3315                                 r = dns_answer_has_dname_for_cname(*validated, rr);
3316                                 if (r < 0)
3317                                         return r;
3318                         }
3319 
3320                         if (r == 0) {
3321                                 if (IN_SET(result,
3322                                            DNSSEC_INVALID,
3323                                            DNSSEC_SIGNATURE_EXPIRED,
3324                                            DNSSEC_NO_SIGNATURE))
3325                                         manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key);
3326                                 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
3327                                         manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key);
3328 
3329                                 /* This is a primary response to our question, and it failed validation.
3330                                  * That's fatal. */
3331                                 t->answer_dnssec_result = result;
3332                                 return 0;
3333                         }
3334 
3335                         /* This is a primary response, but we do have a DNAME RR
3336                          * in the RR that can replay this CNAME, hence rely on
3337                          * that, and we can remove the CNAME in favour of it. */
3338                 }
3339 
3340                 /* This is just some auxiliary data. Just remove the RRset and continue. */
3341                 r = dns_answer_remove_by_key(&t->answer, rr->key);
3342                 if (r < 0)
3343                         return r;
3344 
3345                 /* We dropped something from the answer, start from the beginning. */
3346                 return 1;
3347         }
3348 
3349         return 2; /* Finito. */
3350 }
3351 
dns_transaction_validate_dnssec(DnsTransaction * t)3352 int dns_transaction_validate_dnssec(DnsTransaction *t) {
3353         _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
3354         Phase phase;
3355         DnsAnswerFlags flags;
3356         int r;
3357         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
3358 
3359         assert(t);
3360 
3361         /* We have now collected all DS and DNSKEY RRs in t->validated_keys, let's see which RRs we can now
3362          * authenticate with that. */
3363 
3364         if (FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) || t->scope->dnssec_mode == DNSSEC_NO)
3365                 return 0;
3366 
3367         /* Already validated */
3368         if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
3369                 return 0;
3370 
3371         /* Our own stuff needs no validation */
3372         if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
3373                 t->answer_dnssec_result = DNSSEC_VALIDATED;
3374                 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, true);
3375                 return 0;
3376         }
3377 
3378         /* Cached stuff is not affected by validation. */
3379         if (t->answer_source != DNS_TRANSACTION_NETWORK)
3380                 return 0;
3381 
3382         if (!dns_transaction_dnssec_supported_full(t)) {
3383                 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
3384                 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
3385                 log_debug("Not validating response for %" PRIu16 ", used server feature level does not support DNSSEC.", t->id);
3386                 return 0;
3387         }
3388 
3389         log_debug("Validating response from transaction %" PRIu16 " (%s).",
3390                   t->id,
3391                   dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str));
3392 
3393         /* First, see if this response contains any revoked trust
3394          * anchors we care about */
3395         r = dns_transaction_check_revoked_trust_anchors(t);
3396         if (r < 0)
3397                 return r;
3398 
3399         /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
3400         r = dns_transaction_copy_validated(t);
3401         if (r < 0)
3402                 return r;
3403 
3404         /* Second, see if there are DNSKEYs we already know a
3405          * validated DS for. */
3406         r = dns_transaction_validate_dnskey_by_ds(t);
3407         if (r < 0)
3408                 return r;
3409 
3410         /* Fourth, remove all DNSKEY and DS RRs again that our trust
3411          * anchor says are revoked. After all we might have marked
3412          * some keys revoked above, but they might still be lingering
3413          * in our validated_keys list. */
3414         r = dns_transaction_invalidate_revoked_keys(t);
3415         if (r < 0)
3416                 return r;
3417 
3418         phase = DNSSEC_PHASE_DNSKEY;
3419         for (;;) {
3420                 bool have_nsec = false;
3421 
3422                 r = dnssec_validate_records(t, phase, &have_nsec, &validated);
3423                 if (r <= 0)
3424                         return r;
3425 
3426                 /* Try again as long as we managed to achieve something */
3427                 if (r == 1)
3428                         continue;
3429 
3430                 if (phase == DNSSEC_PHASE_DNSKEY && have_nsec) {
3431                         /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
3432                         phase = DNSSEC_PHASE_NSEC;
3433                         continue;
3434                 }
3435 
3436                 if (phase != DNSSEC_PHASE_ALL) {
3437                         /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now.
3438                          * Note that in this third phase we start to remove RRs we couldn't validate. */
3439                         phase = DNSSEC_PHASE_ALL;
3440                         continue;
3441                 }
3442 
3443                 /* We're done */
3444                 break;
3445         }
3446 
3447         DNS_ANSWER_REPLACE(t->answer, TAKE_PTR(validated));
3448 
3449         /* At this point the answer only contains validated
3450          * RRsets. Now, let's see if it actually answers the question
3451          * we asked. If so, great! If it doesn't, then see if
3452          * NSEC/NSEC3 can prove this. */
3453         r = dns_transaction_has_positive_answer(t, &flags);
3454         if (r > 0) {
3455                 /* Yes, it answers the question! */
3456 
3457                 if (flags & DNS_ANSWER_AUTHENTICATED) {
3458                         /* The answer is fully authenticated, yay. */
3459                         t->answer_dnssec_result = DNSSEC_VALIDATED;
3460                         t->answer_rcode = DNS_RCODE_SUCCESS;
3461                         SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, true);
3462                 } else {
3463                         /* The answer is not fully authenticated. */
3464                         t->answer_dnssec_result = DNSSEC_UNSIGNED;
3465                         SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
3466                 }
3467 
3468         } else if (r == 0) {
3469                 DnssecNsecResult nr;
3470                 bool authenticated = false;
3471 
3472                 /* Bummer! Let's check NSEC/NSEC3 */
3473                 r = dnssec_nsec_test(t->answer, dns_transaction_key(t), &nr, &authenticated, &t->answer_nsec_ttl);
3474                 if (r < 0)
3475                         return r;
3476 
3477                 switch (nr) {
3478 
3479                 case DNSSEC_NSEC_NXDOMAIN:
3480                         /* NSEC proves the domain doesn't exist. Very good. */
3481                         log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
3482                         t->answer_dnssec_result = DNSSEC_VALIDATED;
3483                         t->answer_rcode = DNS_RCODE_NXDOMAIN;
3484                         SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, authenticated);
3485 
3486                         manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, dns_transaction_key(t));
3487                         break;
3488 
3489                 case DNSSEC_NSEC_NODATA:
3490                         /* NSEC proves that there's no data here, very good. */
3491                         log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
3492                         t->answer_dnssec_result = DNSSEC_VALIDATED;
3493                         t->answer_rcode = DNS_RCODE_SUCCESS;
3494                         SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, authenticated);
3495 
3496                         manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, dns_transaction_key(t));
3497                         break;
3498 
3499                 case DNSSEC_NSEC_OPTOUT:
3500                         /* NSEC3 says the data might not be signed */
3501                         log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
3502                         t->answer_dnssec_result = DNSSEC_UNSIGNED;
3503                         SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
3504 
3505                         manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, dns_transaction_key(t));
3506                         break;
3507 
3508                 case DNSSEC_NSEC_NO_RR:
3509                         /* No NSEC data? Bummer! */
3510 
3511                         r = dns_transaction_requires_nsec(t);
3512                         if (r < 0)
3513                                 return r;
3514                         if (r > 0) {
3515                                 t->answer_dnssec_result = DNSSEC_NO_SIGNATURE;
3516                                 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, dns_transaction_key(t));
3517                         } else {
3518                                 t->answer_dnssec_result = DNSSEC_UNSIGNED;
3519                                 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
3520                                 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, dns_transaction_key(t));
3521                         }
3522 
3523                         break;
3524 
3525                 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM:
3526                         /* We don't know the NSEC3 algorithm used? */
3527                         t->answer_dnssec_result = DNSSEC_UNSUPPORTED_ALGORITHM;
3528                         manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, dns_transaction_key(t));
3529                         break;
3530 
3531                 case DNSSEC_NSEC_FOUND:
3532                 case DNSSEC_NSEC_CNAME:
3533                         /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
3534                         t->answer_dnssec_result = DNSSEC_NSEC_MISMATCH;
3535                         manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, dns_transaction_key(t));
3536                         break;
3537 
3538                 default:
3539                         assert_not_reached();
3540                 }
3541         }
3542 
3543         return 1;
3544 }
3545 
3546 static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
3547         [DNS_TRANSACTION_NULL]                 = "null",
3548         [DNS_TRANSACTION_PENDING]              = "pending",
3549         [DNS_TRANSACTION_VALIDATING]           = "validating",
3550         [DNS_TRANSACTION_RCODE_FAILURE]        = "rcode-failure",
3551         [DNS_TRANSACTION_SUCCESS]              = "success",
3552         [DNS_TRANSACTION_NO_SERVERS]           = "no-servers",
3553         [DNS_TRANSACTION_TIMEOUT]              = "timeout",
3554         [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
3555         [DNS_TRANSACTION_INVALID_REPLY]        = "invalid-reply",
3556         [DNS_TRANSACTION_ERRNO]                = "errno",
3557         [DNS_TRANSACTION_ABORTED]              = "aborted",
3558         [DNS_TRANSACTION_DNSSEC_FAILED]        = "dnssec-failed",
3559         [DNS_TRANSACTION_NO_TRUST_ANCHOR]      = "no-trust-anchor",
3560         [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED]  = "rr-type-unsupported",
3561         [DNS_TRANSACTION_NETWORK_DOWN]         = "network-down",
3562         [DNS_TRANSACTION_NOT_FOUND]            = "not-found",
3563         [DNS_TRANSACTION_NO_SOURCE]            = "no-source",
3564         [DNS_TRANSACTION_STUB_LOOP]            = "stub-loop",
3565 };
3566 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
3567 
3568 static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
3569         [DNS_TRANSACTION_NETWORK]      = "network",
3570         [DNS_TRANSACTION_CACHE]        = "cache",
3571         [DNS_TRANSACTION_ZONE]         = "zone",
3572         [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
3573 };
3574 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);
3575