diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-02-16 13:40:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-16 13:40:46 +0100 |
commit | ff05157f828f2e5689bfbc101552566b623567f3 (patch) | |
tree | 3d40bd2c072f21a1a6631ce396f56b2925357720 | |
parent | Merge pull request #18611 from poettering/ifname-validate-tighter (diff) | |
parent | resolved: propagate source where an RR from back to client (diff) | |
download | systemd-ff05157f828f2e5689bfbc101552566b623567f3.tar.xz systemd-ff05157f828f2e5689bfbc101552566b623567f3.zip |
Merge pull request #18617 from poettering/resolved-confidential
resolved: tell clients which source a response is from, and whether it was never sent via unencrypted transports
-rw-r--r-- | src/resolve/resolvectl.c | 17 | ||||
-rw-r--r-- | src/resolve/resolved-bus.c | 11 | ||||
-rw-r--r-- | src/resolve/resolved-def.h | 20 | ||||
-rw-r--r-- | src/resolve/resolved-dns-cache.c | 77 | ||||
-rw-r--r-- | src/resolve/resolved-dns-cache.h | 4 | ||||
-rw-r--r-- | src/resolve/resolved-dns-packet.h | 9 | ||||
-rw-r--r-- | src/resolve/resolved-dns-query.c | 45 | ||||
-rw-r--r-- | src/resolve/resolved-dns-query.h | 14 | ||||
-rw-r--r-- | src/resolve/resolved-dns-scope.c | 2 | ||||
-rw-r--r-- | src/resolve/resolved-dns-transaction.c | 86 | ||||
-rw-r--r-- | src/resolve/resolved-dns-transaction.h | 38 | ||||
-rw-r--r-- | src/resolve/resolved-llmnr.c | 2 | ||||
-rw-r--r-- | src/resolve/resolved-mdns.c | 8 | ||||
-rw-r--r-- | src/resolve/resolved-varlink.c | 7 |
14 files changed, 226 insertions, 114 deletions
diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 6301b6ba09..2302ca48ba 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -155,9 +155,22 @@ static void print_source(uint64_t flags, usec_t rtt) { assert_se(format_timespan(rtt_str, sizeof(rtt_str), rtt, 100)); printf(" in %s.%s\n" - "%s-- Data is authenticated: %s%s\n", + "%s-- Data is authenticated: %s; Data was acquired via local or encrypted transport: %s%s\n", rtt_str, ansi_normal(), - ansi_grey(), yes_no(flags & SD_RESOLVED_AUTHENTICATED), ansi_normal()); + ansi_grey(), + yes_no(flags & SD_RESOLVED_AUTHENTICATED), + yes_no(flags & SD_RESOLVED_CONFIDENTIAL), + ansi_normal()); + + if ((flags & (SD_RESOLVED_FROM_MASK|SD_RESOLVED_SYNTHETIC)) != 0) + printf("%s-- Data from:%s%s%s%s%s%s\n", + ansi_grey(), + FLAGS_SET(flags, SD_RESOLVED_SYNTHETIC) ? " synthetic" : "", + FLAGS_SET(flags, SD_RESOLVED_FROM_CACHE) ? " cache" : "", + FLAGS_SET(flags, SD_RESOLVED_FROM_ZONE) ? " zone" : "", + FLAGS_SET(flags, SD_RESOLVED_FROM_TRUST_ANCHOR) ? " trust-anchor" : "", + FLAGS_SET(flags, SD_RESOLVED_FROM_NETWORK) ? " network" : "", + ansi_normal()); } static void print_ifindex_comment(int printed_so_far, int ifindex) { diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 0c1124f7dd..71374a19ad 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -252,7 +252,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) { r = sd_bus_message_append( reply, "st", normalized, - SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q))); + dns_query_reply_flags_make(q)); if (r < 0) goto finish; @@ -367,7 +367,8 @@ static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname return r; r = sd_bus_message_append(reply, "st", canonical, - SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags), ff, true)); + SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags), ff, true, true) | + SD_RESOLVED_SYNTHETIC); if (r < 0) return r; @@ -510,7 +511,7 @@ static void bus_method_resolve_address_complete(DnsQuery *q) { if (r < 0) goto finish; - r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q))); + r = sd_bus_message_append(reply, "t", dns_query_reply_flags_make(q)); if (r < 0) goto finish; @@ -672,7 +673,7 @@ static void bus_method_resolve_record_complete(DnsQuery *q) { if (r < 0) goto finish; - r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q))); + r = sd_bus_message_append(reply, "t", dns_query_reply_flags_make(q)); if (r < 0) goto finish; @@ -1048,7 +1049,7 @@ static void resolve_service_all_complete(DnsQuery *q) { reply, "ssst", name, type, domain, - SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q))); + dns_query_reply_flags_make(q)); if (r < 0) goto finish; diff --git a/src/resolve/resolved-def.h b/src/resolve/resolved-def.h index 133cf0556f..702d3f8b41 100644 --- a/src/resolve/resolved-def.h +++ b/src/resolve/resolved-def.h @@ -52,8 +52,28 @@ /* Input: If reply is answered from cache, the TTLs will be adjusted by age of cache entry */ #define SD_RESOLVED_CLAMP_TTL (UINT64_C(1) << 17) +/* Output: Result was only sent via encrypted channels, or never left this system */ +#define SD_RESOLVED_CONFIDENTIAL (UINT64_C(1) << 18) + +/* Output: Result was (at least partially) synthesized locally */ +#define SD_RESOLVED_SYNTHETIC (UINT64_C(1) << 19) + +/* Output: Result was (at least partially) answered from cache */ +#define SD_RESOLVED_FROM_CACHE (UINT64_C(1) << 20) + +/* Output: Result was (at least partially) answered from local zone */ +#define SD_RESOLVED_FROM_ZONE (UINT64_C(1) << 21) + +/* Output: Result was (at least partially) answered from trust anchor */ +#define SD_RESOLVED_FROM_TRUST_ANCHOR (UINT64_C(1) << 22) + +/* Output: Result was (at least partially) answered from network */ +#define SD_RESOLVED_FROM_NETWORK (UINT64_C(1) << 23) + #define SD_RESOLVED_LLMNR (SD_RESOLVED_LLMNR_IPV4|SD_RESOLVED_LLMNR_IPV6) #define SD_RESOLVED_MDNS (SD_RESOLVED_MDNS_IPV4|SD_RESOLVED_MDNS_IPV6) #define SD_RESOLVED_PROTOCOLS_ALL (SD_RESOLVED_MDNS|SD_RESOLVED_LLMNR|SD_RESOLVED_DNS) +#define SD_RESOLVED_FROM_MASK (SD_RESOLVED_FROM_CACHE|SD_RESOLVED_FROM_ZONE|SD_RESOLVED_FROM_TRUST_ANCHOR|SD_RESOLVED_FROM_NETWORK) + #define SD_RESOLVED_QUERY_TIMEOUT_USEC (120 * USEC_PER_SEC) diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index cf0e221621..1a10357123 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -22,6 +22,8 @@ * now) */ #define CACHE_TTL_STRANGE_RCODE_USEC (10 * USEC_PER_SEC) +#define CACHEABLE_QUERY_FLAGS (SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL) + typedef enum DnsCacheItemType DnsCacheItemType; typedef struct DnsCacheItem DnsCacheItem; @@ -41,8 +43,8 @@ struct DnsCacheItem { int rcode; usec_t until; - bool authenticated:1; bool shared_owner:1; + uint64_t query_flags; /* SD_RESOLVED_AUTHENTICATED and/or SD_RESOLVED_CONFIDENTIAL */ DnssecResult dnssec_result; int ifindex; @@ -353,7 +355,7 @@ static void dns_cache_item_update_positive( DnsResourceRecord *rr, DnsAnswer *answer, DnsPacket *full_packet, - bool authenticated, + uint64_t query_flags, bool shared_owner, DnssecResult dnssec_result, usec_t timestamp, @@ -390,7 +392,7 @@ static void dns_cache_item_update_positive( i->full_packet = full_packet; i->until = calculate_until(rr, UINT32_MAX, timestamp, false); - i->authenticated = authenticated; + i->query_flags = query_flags & CACHEABLE_QUERY_FLAGS; i->shared_owner = shared_owner; i->dnssec_result = dnssec_result; @@ -407,7 +409,7 @@ static int dns_cache_put_positive( DnsResourceRecord *rr, DnsAnswer *answer, DnsPacket *full_packet, - bool authenticated, + uint64_t query_flags, bool shared_owner, DnssecResult dnssec_result, usec_t timestamp, @@ -448,7 +450,7 @@ static int dns_cache_put_positive( rr, answer, full_packet, - authenticated, + query_flags, shared_owner, dnssec_result, timestamp, @@ -476,7 +478,7 @@ static int dns_cache_put_positive( .answer = dns_answer_ref(answer), .full_packet = dns_packet_ref(full_packet), .until = calculate_until(rr, (uint32_t) -1, timestamp, false), - .authenticated = authenticated, + .query_flags = query_flags & CACHEABLE_QUERY_FLAGS, .shared_owner = shared_owner, .dnssec_result = dnssec_result, .ifindex = ifindex, @@ -495,8 +497,9 @@ static int dns_cache_put_positive( (void) in_addr_to_string(i->owner_family, &i->owner_address, &t); - log_debug("Added positive %s%s cache entry for %s "USEC_FMT"s on %s/%s/%s", - i->authenticated ? "authenticated" : "unauthenticated", + log_debug("Added positive %s %s%s cache entry for %s "USEC_FMT"s on %s/%s/%s", + FLAGS_SET(i->query_flags, SD_RESOLVED_AUTHENTICATED) ? "authenticated" : "unauthenticated", + FLAGS_SET(i->query_flags, SD_RESOLVED_CONFIDENTIAL) ? "confidential" : "non-confidential", i->shared_owner ? " shared" : "", dns_resource_key_to_string(i->key, key_str, sizeof key_str), (i->until - timestamp) / USEC_PER_SEC, @@ -515,7 +518,7 @@ static int dns_cache_put_negative( int rcode, DnsAnswer *answer, DnsPacket *full_packet, - bool authenticated, + uint64_t query_flags, DnssecResult dnssec_result, uint32_t nsec_ttl, usec_t timestamp, @@ -566,7 +569,7 @@ static int dns_cache_put_negative( .type = rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA : rcode == DNS_RCODE_NXDOMAIN ? DNS_CACHE_NXDOMAIN : DNS_CACHE_RCODE, - .authenticated = authenticated, + .query_flags = query_flags & CACHEABLE_QUERY_FLAGS, .dnssec_result = dnssec_result, .owner_family = owner_family, .owner_address = *owner_address, @@ -669,7 +672,7 @@ int dns_cache_put( int rcode, DnsAnswer *answer, DnsPacket *full_packet, - bool authenticated, + uint64_t query_flags, DnssecResult dnssec_result, uint32_t nsec_ttl, int owner_family, @@ -761,7 +764,8 @@ int dns_cache_put( item->rr, primary ? answer : NULL, primary ? full_packet : NULL, - item->flags & DNS_ANSWER_AUTHENTICATED, + ((item->flags & DNS_ANSWER_AUTHENTICATED) ? SD_RESOLVED_AUTHENTICATED : 0) | + (query_flags & SD_RESOLVED_CONFIDENTIAL), item->flags & DNS_ANSWER_SHARED_OWNER, dnssec_result, timestamp, @@ -802,7 +806,8 @@ int dns_cache_put( if (r > 0) { /* Refuse using the SOA data if it is unsigned, but the key is * signed */ - if (authenticated && (flags & DNS_ANSWER_AUTHENTICATED) == 0) + if (FLAGS_SET(query_flags, SD_RESOLVED_AUTHENTICATED) && + (flags & DNS_ANSWER_AUTHENTICATED) == 0) return 0; } @@ -819,7 +824,7 @@ int dns_cache_put( rcode, answer, full_packet, - authenticated, + query_flags, dnssec_result, nsec_ttl, timestamp, @@ -951,7 +956,7 @@ int dns_cache_lookup( int *ret_rcode, DnsAnswer **ret_answer, DnsPacket **ret_full_packet, - bool *ret_authenticated, + uint64_t *ret_query_flags, DnssecResult *ret_dnssec_result) { _cleanup_(dns_packet_unrefp) DnsPacket *full_packet = NULL; @@ -961,7 +966,7 @@ int dns_cache_lookup( int r; bool nxdomain = false; DnsCacheItem *j, *first, *nsec = NULL; - bool have_authenticated = false, have_non_authenticated = false; + bool have_authenticated = false, have_non_authenticated = false, have_confidential = false, have_non_confidential = false; usec_t current; int found_rcode = -1; DnssecResult dnssec_result = -1; @@ -1013,11 +1018,16 @@ int dns_cache_lookup( n++; } - if (j->authenticated) + if (FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED)) have_authenticated = true; else have_non_authenticated = true; + if (FLAGS_SET(j->query_flags, SD_RESOLVED_CONFIDENTIAL)) + have_confidential = true; + else + have_non_confidential = true; + if (j->dnssec_result < 0) { have_dnssec_result = false; /* an entry without dnssec result? then invalidate things for good */ dnssec_result = _DNSSEC_RESULT_INVALID; @@ -1049,7 +1059,14 @@ int dns_cache_lookup( } } else if (j->rr) { - r = answer_add_clamp_ttl(&answer, j->rr, j->ifindex, j->authenticated ? DNS_ANSWER_AUTHENTICATED : 0, NULL, query_flags, j->until, current); + r = answer_add_clamp_ttl(&answer, + j->rr, + j->ifindex, + FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0, + NULL, + query_flags, + j->until, + current); if (r < 0) return r; } @@ -1072,8 +1089,8 @@ int dns_cache_lookup( *ret_answer = TAKE_PTR(answer); if (ret_full_packet) *ret_full_packet = TAKE_PTR(full_packet); - if (ret_authenticated) - *ret_authenticated = false; + if (ret_query_flags) + *ret_query_flags = 0; if (ret_dnssec_result) *ret_dnssec_result = dnssec_result; @@ -1097,8 +1114,8 @@ int dns_cache_lookup( *ret_answer = TAKE_PTR(answer); if (ret_full_packet) *ret_full_packet = TAKE_PTR(full_packet); - if (ret_authenticated) - *ret_authenticated = nsec->authenticated; + if (ret_query_flags) + *ret_query_flags = nsec->query_flags; if (ret_dnssec_result) *ret_dnssec_result = nsec->dnssec_result; @@ -1127,8 +1144,10 @@ int dns_cache_lookup( *ret_answer = TAKE_PTR(answer); if (ret_full_packet) *ret_full_packet = TAKE_PTR(full_packet); - if (ret_authenticated) - *ret_authenticated = have_authenticated && !have_non_authenticated; + if (ret_query_flags) + *ret_query_flags = + ((have_authenticated && !have_non_authenticated) ? SD_RESOLVED_AUTHENTICATED : 0) | + ((have_confidential && !have_non_confidential) ? SD_RESOLVED_CONFIDENTIAL : 0); if (ret_dnssec_result) *ret_dnssec_result = dnssec_result; @@ -1143,8 +1162,10 @@ int dns_cache_lookup( *ret_answer = TAKE_PTR(answer); if (ret_full_packet) *ret_full_packet = TAKE_PTR(full_packet); - if (ret_authenticated) - *ret_authenticated = have_authenticated && !have_non_authenticated; + if (ret_query_flags) + *ret_query_flags = + ((have_authenticated && !have_non_authenticated) ? SD_RESOLVED_AUTHENTICATED : 0) | + ((have_confidential && !have_non_confidential) ? SD_RESOLVED_CONFIDENTIAL : 0); if (ret_dnssec_result) *ret_dnssec_result = dnssec_result; @@ -1157,8 +1178,8 @@ miss: *ret_answer = NULL; if (ret_full_packet) *ret_full_packet = NULL; - if (ret_authenticated) - *ret_authenticated = false; + if (ret_query_flags) + *ret_query_flags = 0; if (ret_dnssec_result) *ret_dnssec_result = _DNSSEC_RESULT_INVALID; diff --git a/src/resolve/resolved-dns-cache.h b/src/resolve/resolved-dns-cache.h index cfae24fb71..621b52f892 100644 --- a/src/resolve/resolved-dns-cache.h +++ b/src/resolve/resolved-dns-cache.h @@ -30,7 +30,7 @@ int dns_cache_put( int rcode, DnsAnswer *answer, DnsPacket *full_packet, - bool authenticated, + uint64_t query_flags, DnssecResult dnssec_result, uint32_t nsec_ttl, int owner_family, @@ -43,7 +43,7 @@ int dns_cache_lookup( int *ret_rcode, DnsAnswer **ret_answer, DnsPacket **ret_full_packet, - bool *ret_authenticated, + uint64_t *ret_query_flags, DnssecResult *ret_dnssec_result); int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address); diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h index 9fe278264b..c7b88310e5 100644 --- a/src/resolve/resolved-dns-packet.h +++ b/src/resolve/resolved-dns-packet.h @@ -269,12 +269,17 @@ DnsProtocol dns_protocol_from_string(const char *s) _pure_; extern const struct hash_ops dns_packet_hash_ops; -static inline uint64_t SD_RESOLVED_FLAGS_MAKE(DnsProtocol protocol, int family, bool authenticated) { +static inline uint64_t SD_RESOLVED_FLAGS_MAKE( + DnsProtocol protocol, + int family, + bool authenticated, + bool confidential) { uint64_t f; /* Converts a protocol + family into a flags field as used in queries and responses */ - f = authenticated ? SD_RESOLVED_AUTHENTICATED : 0; + f = (authenticated ? SD_RESOLVED_AUTHENTICATED : 0) | + (confidential ? SD_RESOLVED_CONFIDENTIAL : 0); switch (protocol) { case DNS_PROTOCOL_DNS: diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index aa05844642..1413afe3b9 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -346,7 +346,7 @@ static void dns_query_reset_answer(DnsQuery *q) { q->answer_rcode = 0; q->answer_dnssec_result = _DNSSEC_RESULT_INVALID; q->answer_errno = 0; - q->answer_authenticated = false; + q->answer_query_flags = 0; q->answer_protocol = _DNS_PROTOCOL_INVALID; q->answer_family = AF_UNSPEC; q->answer_search_domain = dns_search_domain_unref(q->answer_search_domain); @@ -630,7 +630,7 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { q->answer_rcode = DNS_RCODE_NXDOMAIN; q->answer_protocol = dns_synthesize_protocol(q->flags); q->answer_family = dns_synthesize_family(q->flags); - q->answer_authenticated = true; + q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL|SD_RESOLVED_SYNTHETIC; *state = DNS_TRANSACTION_RCODE_FAILURE; return 0; @@ -644,7 +644,7 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { q->answer_rcode = DNS_RCODE_SUCCESS; q->answer_protocol = dns_synthesize_protocol(q->flags); q->answer_family = dns_synthesize_family(q->flags); - q->answer_authenticated = true; + q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL|SD_RESOLVED_SYNTHETIC; *state = DNS_TRANSACTION_SUCCESS; @@ -676,7 +676,7 @@ static int dns_query_try_etc_hosts(DnsQuery *q) { q->answer_rcode = DNS_RCODE_SUCCESS; q->answer_protocol = dns_synthesize_protocol(q->flags); q->answer_family = dns_synthesize_family(q->flags); - q->answer_authenticated = true; + q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL|SD_RESOLVED_SYNTHETIC; return 1; } @@ -795,7 +795,7 @@ fail: static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) { DnsTransactionState state = DNS_TRANSACTION_NO_SERVERS; - bool has_authenticated = false, has_non_authenticated = false; + bool has_authenticated = false, has_non_authenticated = false, has_confidential = false, has_non_confidential = false; DnssecResult dnssec_result_authenticated = _DNSSEC_RESULT_INVALID, dnssec_result_non_authenticated = _DNSSEC_RESULT_INVALID; DnsTransaction *t; int r; @@ -817,7 +817,7 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) { q->answer = dns_answer_unref(q->answer); q->answer_rcode = 0; q->answer_dnssec_result = _DNSSEC_RESULT_INVALID; - q->answer_authenticated = false; + q->answer_query_flags = 0; q->answer_errno = c->error_code; q->answer_full_packet = dns_packet_unref(q->answer_full_packet); } @@ -833,10 +833,14 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) { r = dns_answer_extend(&q->answer, t->answer); if (r < 0) goto fail; + + q->answer_query_flags |= dns_transaction_source_to_query_flags(t->answer_source); } else { /* Override non-successful previous answers */ dns_answer_unref(q->answer); q->answer = dns_answer_ref(t->answer); + + q->answer_query_flags = dns_transaction_source_to_query_flags(t->answer_source); } q->answer_rcode = t->answer_rcode; @@ -845,7 +849,7 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) { dns_packet_unref(q->answer_full_packet); q->answer_full_packet = dns_packet_ref(t->received); - if (t->answer_authenticated) { + if (FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) { has_authenticated = true; dnssec_result_authenticated = t->answer_dnssec_result; } else { @@ -853,6 +857,11 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) { dnssec_result_non_authenticated = t->answer_dnssec_result; } + if (FLAGS_SET(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL)) + has_confidential = true; + else + has_non_confidential = true; + state = DNS_TRANSACTION_SUCCESS; break; } @@ -870,14 +879,15 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) { continue; /* If there's already an authenticated negative reply stored, then prefer that over any unauthenticated one */ - if (q->answer_authenticated && !t->answer_authenticated) + if (FLAGS_SET(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED) && + !FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) continue; dns_answer_unref(q->answer); q->answer = dns_answer_ref(t->answer); q->answer_rcode = t->answer_rcode; q->answer_dnssec_result = t->answer_dnssec_result; - q->answer_authenticated = t->answer_authenticated; + q->answer_query_flags = t->answer_query_flags | dns_transaction_source_to_query_flags(t->answer_source); q->answer_errno = t->answer_errno; dns_packet_unref(q->answer_full_packet); q->answer_full_packet = dns_packet_ref(t->received); @@ -888,8 +898,9 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) { } if (state == DNS_TRANSACTION_SUCCESS) { - q->answer_authenticated = has_authenticated && !has_non_authenticated; - q->answer_dnssec_result = q->answer_authenticated ? dnssec_result_authenticated : dnssec_result_non_authenticated; + SET_FLAG(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED, has_authenticated && !has_non_authenticated); + SET_FLAG(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL, has_confidential && !has_non_confidential); + q->answer_dnssec_result = FLAGS_SET(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED) ? dnssec_result_authenticated : dnssec_result_non_authenticated; } q->answer_protocol = c->scope->protocol; @@ -1049,8 +1060,10 @@ int dns_query_process_cname(DnsQuery *q) { if (q->flags & SD_RESOLVED_NO_CNAME) return -ELOOP; - if (!q->answer_authenticated) + if (!FLAGS_SET(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) q->previous_redirect_unauthenticated = true; + if (!FLAGS_SET(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL)) + q->previous_redirect_non_confidential = true; /* OK, let's actually follow the CNAME */ r = dns_query_cname_redirect(q, cname); @@ -1119,5 +1132,11 @@ const char *dns_query_string(DnsQuery *q) { bool dns_query_fully_authenticated(DnsQuery *q) { assert(q); - return q->answer_authenticated && !q->previous_redirect_unauthenticated; + return FLAGS_SET(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED) && !q->previous_redirect_unauthenticated; +} + +bool dns_query_fully_confidential(DnsQuery *q) { + assert(q); + + return FLAGS_SET(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL) && !q->previous_redirect_non_confidential; } diff --git a/src/resolve/resolved-dns-query.h b/src/resolve/resolved-dns-query.h index a7916712c1..4874aa0c17 100644 --- a/src/resolve/resolved-dns-query.h +++ b/src/resolve/resolved-dns-query.h @@ -66,12 +66,13 @@ struct DnsQuery { DnsAnswer *answer; int answer_rcode; DnssecResult answer_dnssec_result; - bool answer_authenticated; + uint64_t answer_query_flags; DnsProtocol answer_protocol; int answer_family; DnsSearchDomain *answer_search_domain; int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */ bool previous_redirect_unauthenticated; + bool previous_redirect_non_confidential; DnsPacket *answer_full_packet; /* Bus + Varlink client information */ @@ -132,3 +133,14 @@ const char *dns_query_string(DnsQuery *q); DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuery*, dns_query_free); bool dns_query_fully_authenticated(DnsQuery *q); +bool dns_query_fully_confidential(DnsQuery *q); + +static inline uint64_t dns_query_reply_flags_make(DnsQuery *q) { + assert(q); + + return SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, + q->answer_family, + dns_query_fully_authenticated(q), + dns_query_fully_confidential(q)) | + (q->answer_query_flags & (SD_RESOLVED_FROM_MASK|SD_RESOLVED_SYNTHETIC)); +} diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index c962af9aba..8b5dd25732 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -505,7 +505,7 @@ DnsScopeMatch dns_scope_good_domain( if (ifindex != 0 && (!s->link || s->link->ifindex != ifindex)) return DNS_SCOPE_NO; - if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family, 0) & flags) == 0) + if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family, false, false) & flags) == 0) return DNS_SCOPE_NO; /* Never resolve any loopback hostname or IP address via DNS, LLMNR or mDNS. Instead, always rely on diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 55b9114f58..36e38f6532 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -29,7 +29,7 @@ static void dns_transaction_reset_answer(DnsTransaction *t) { t->answer_rcode = 0; t->answer_dnssec_result = _DNSSEC_RESULT_INVALID; t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID; - t->answer_authenticated = false; + t->answer_query_flags = 0; t->answer_nsec_ttl = (uint32_t) -1; t->answer_errno = 0; } @@ -410,7 +410,7 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) { else st = dns_transaction_state_to_string(state); - log_debug("%s transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).", + log_debug("%s transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s; %s).", t->bypass ? "Bypass" : "Regular", t->id, dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str), @@ -420,7 +420,8 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) { st, t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source), FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) ? "not validated" : - (t->answer_authenticated ? "authenticated" : "unsigned")); + (FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED) ? "authenticated" : "unsigned"), + FLAGS_SET(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL) ? "confidential" : "non-confidential"); t->state = state; @@ -561,10 +562,15 @@ static void on_transaction_stream_error(DnsTransaction *t, int error) { dns_transaction_complete_errno(t, error); } -static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsPacket *p) { +static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsStream *s, DnsPacket *p) { + bool encrypted; + assert(t); + assert(s); assert(p); + encrypted = s->encrypted; + dns_transaction_close_connection(t, true); if (dns_packet_validate_reply(p) <= 0) { @@ -576,7 +582,7 @@ static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsPacket *p) { dns_scope_check_conflicts(t->scope, p); t->block_gc++; - dns_transaction_process_reply(t, p); + dns_transaction_process_reply(t, p, encrypted); t->block_gc--; /* If the response wasn't useful, then complete the transition @@ -621,12 +627,11 @@ static int on_stream_packet(DnsStream *s) { assert(s); /* Take ownership of packet to be able to receive new packets */ - p = dns_stream_take_read_packet(s); - assert(p); + assert_se(p = dns_stream_take_read_packet(s)); t = hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p))); if (t) - return dns_transaction_on_stream_packet(t, p); + return dns_transaction_on_stream_packet(t, s, p); /* Ignore incorrect transaction id as an old transaction can have been canceled. */ log_debug("Received unexpected TCP reply packet with id %" PRIu16 ", ignoring.", DNS_PACKET_ID(p)); @@ -793,7 +798,7 @@ static void dns_transaction_cache_answer(DnsTransaction *t) { * since our usecase for caching them * is "bypass" mode which is only * enabled for CD packets. */ - t->answer_authenticated, + t->answer_query_flags, t->answer_dnssec_result, t->answer_nsec_ttl, t->received->family, @@ -990,7 +995,7 @@ static int dns_transaction_fix_rcode(DnsTransaction *t) { return 0; } -void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) { +void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypted) { int r; assert(t); @@ -1231,7 +1236,8 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) { t->answer = dns_answer_ref(p->answer); t->answer_rcode = DNS_PACKET_RCODE(p); t->answer_dnssec_result = _DNSSEC_RESULT_INVALID; - t->answer_authenticated = false; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false); + SET_FLAG(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL, encrypted); r = dns_transaction_fix_rcode(t); if (r < 0) @@ -1315,7 +1321,7 @@ static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *use return 0; } - dns_transaction_process_reply(t, p); + dns_transaction_process_reply(t, p, false); return 0; } @@ -1519,7 +1525,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) { if (r > 0) { t->answer_rcode = DNS_RCODE_SUCCESS; t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR; - t->answer_authenticated = true; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL, true); dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS); return 0; } @@ -1538,7 +1544,8 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) { t->answer_rcode = DNS_RCODE_SUCCESS; t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR; - t->answer_authenticated = false; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false); + SET_FLAG(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL, true); dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS); } else /* If we are not in downgrade mode, then fail the lookup, because we cannot @@ -1559,7 +1566,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) { if (r > 0) { t->answer_rcode = DNS_RCODE_SUCCESS; t->answer_source = DNS_TRANSACTION_ZONE; - t->answer_authenticated = true; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL, true); dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS); return 0; } @@ -1582,7 +1589,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) { &t->answer_rcode, &t->answer, &t->received, - &t->answer_authenticated, + &t->answer_query_flags, &t->answer_dnssec_result); if (r < 0) return r; @@ -2566,7 +2573,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord * * RRs we are looking at. If it discovered signed DS * RRs, then we need to be signed, too. */ - if (!dt->answer_authenticated) + if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) return false; return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL); @@ -2618,7 +2625,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord * if (r == 0) continue; - return t->answer_authenticated; + return FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED); } return true; @@ -2642,12 +2649,10 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord * if (r == 0) continue; - /* We found the transaction that was supposed to find - * the SOA RR for us. It was successful, but found no - * RR for us. This means we are not at a zone cut. In - * this case, we require authentication if the SOA - * lookup was authenticated too. */ - return t->answer_authenticated; + /* We found the transaction that was supposed to find the SOA RR for us. It was + * successful, but found no RR for us. This means we are not at a zone cut. In this + * case, we require authentication if the SOA lookup was authenticated too. */ + return FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED); } return true; @@ -2788,7 +2793,7 @@ static int dns_transaction_requires_nsec(DnsTransaction *t) { if (r == 0) continue; - return dt->answer_authenticated; + return FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED); } /* If in doubt, require NSEC/NSEC3 */ @@ -2832,11 +2837,10 @@ static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRe if (r == 0) continue; - /* OK, we found an auxiliary DNSKEY - * lookup. If that lookup is - * authenticated, report this. */ + /* OK, we found an auxiliary DNSKEY lookup. If that lookup is authenticated, + * report this. */ - if (dt->answer_authenticated) + if (FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) return true; found = true; @@ -2849,12 +2853,10 @@ static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRe if (r == 0) continue; - /* OK, we found an auxiliary DS - * lookup. If that lookup is - * authenticated and non-zero, we - * won! */ + /* OK, we found an auxiliary DS lookup. If that lookup is authenticated and + * non-zero, we won! */ - if (!dt->answer_authenticated) + if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) return false; return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL); @@ -2942,7 +2944,7 @@ static int dns_transaction_copy_validated(DnsTransaction *t) { if (DNS_TRANSACTION_IS_LIVE(dt->state)) continue; - if (!dt->answer_authenticated) + if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) continue; r = dns_answer_extend(&t->validated_keys, dt->answer); @@ -3244,7 +3246,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { /* Our own stuff needs no validation */ if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) { t->answer_dnssec_result = DNSSEC_VALIDATED; - t->answer_authenticated = true; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, true); return 0; } @@ -3332,11 +3334,11 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { /* The answer is fully authenticated, yay. */ t->answer_dnssec_result = DNSSEC_VALIDATED; t->answer_rcode = DNS_RCODE_SUCCESS; - t->answer_authenticated = true; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, true); } else { /* The answer is not fully authenticated. */ t->answer_dnssec_result = DNSSEC_UNSIGNED; - t->answer_authenticated = false; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false); } } else if (r == 0) { @@ -3355,7 +3357,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str); t->answer_dnssec_result = DNSSEC_VALIDATED; t->answer_rcode = DNS_RCODE_NXDOMAIN; - t->answer_authenticated = authenticated; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, authenticated); manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, dns_transaction_key(t)); break; @@ -3365,7 +3367,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str); t->answer_dnssec_result = DNSSEC_VALIDATED; t->answer_rcode = DNS_RCODE_SUCCESS; - t->answer_authenticated = authenticated; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, authenticated); manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, dns_transaction_key(t)); break; @@ -3374,7 +3376,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { /* NSEC3 says the data might not be signed */ log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str); t->answer_dnssec_result = DNSSEC_UNSIGNED; - t->answer_authenticated = false; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false); manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, dns_transaction_key(t)); break; @@ -3390,7 +3392,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, dns_transaction_key(t)); } else { t->answer_dnssec_result = DNSSEC_UNSIGNED; - t->answer_authenticated = false; + SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false); manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, dns_transaction_key(t)); } diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h index 9376d504bf..b036adec2e 100644 --- a/src/resolve/resolved-dns-transaction.h +++ b/src/resolve/resolved-dns-transaction.h @@ -77,15 +77,12 @@ struct DnsTransaction { uint32_t answer_nsec_ttl; int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */ - /* Indicates whether the primary answer is authenticated, - * i.e. whether the RRs from answer which directly match the - * question are authenticated, or, if there are none, whether - * the NODATA or NXDOMAIN case is. It says nothing about - * additional RRs listed in the answer, however they have - * their own DNS_ANSWER_AUTHORIZED FLAGS. Note that this bit - * is defined different than the AD bit in DNS packets, as - * that covers more than just the actual primary answer. */ - bool answer_authenticated; + /* SD_RESOLVED_AUTHENTICATED here indicates whether the primary answer is authenticated, i.e. whether + * the RRs from answer which directly match the question are authenticated, or, if there are none, + * whether the NODATA or NXDOMAIN case is. It says nothing about additional RRs listed in the answer, + * however they have their own DNS_ANSWER_AUTHORIZED FLAGS. Note that this bit is defined different + * than the AD bit in DNS packets, as that covers more than just the actual primary answer. */ + uint64_t answer_query_flags; /* Contains DNSKEY, DS, SOA RRs we already verified and need * to authenticate this reply */ @@ -148,7 +145,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_gc); int dns_transaction_go(DnsTransaction *t); -void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p); +void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypted); void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state); void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source); @@ -172,6 +169,27 @@ static inline DnsResourceKey *dns_transaction_key(DnsTransaction *t) { return t->bypass->question->keys[0]; } +static inline uint64_t dns_transaction_source_to_query_flags(DnsTransactionSource s) { + + switch (s) { + + case DNS_TRANSACTION_NETWORK: + return SD_RESOLVED_FROM_NETWORK; + + case DNS_TRANSACTION_CACHE: + return SD_RESOLVED_FROM_CACHE; + + case DNS_TRANSACTION_ZONE: + return SD_RESOLVED_FROM_ZONE; + + case DNS_TRANSACTION_TRUST_ANCHOR: + return SD_RESOLVED_FROM_TRUST_ANCHOR; + + default: + return 0; + } +} + const char* dns_transaction_state_to_string(DnsTransactionState p) _const_; DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_; diff --git a/src/resolve/resolved-llmnr.c b/src/resolve/resolved-llmnr.c index b1b8351e00..cc933d6b8e 100644 --- a/src/resolve/resolved-llmnr.c +++ b/src/resolve/resolved-llmnr.c @@ -99,7 +99,7 @@ static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *u t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p))); if (t) - dns_transaction_process_reply(t, p); + dns_transaction_process_reply(t, p, false); } else if (dns_packet_validate_query(p) > 0) { log_debug("Got LLMNR UDP query packet for id %u", DNS_PACKET_ID(p)); diff --git a/src/resolve/resolved-mdns.c b/src/resolve/resolved-mdns.c index 6fccc5a1e5..5b4d08cce8 100644 --- a/src/resolve/resolved-mdns.c +++ b/src/resolve/resolved-mdns.c @@ -303,20 +303,20 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us t = dns_scope_find_transaction(scope, rr->key, SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE); if (t) - dns_transaction_process_reply(t, p); + dns_transaction_process_reply(t, p, false); /* Also look for the various types of ANY transactions */ t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(rr->key->class, DNS_TYPE_ANY, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE); if (t) - dns_transaction_process_reply(t, p); + dns_transaction_process_reply(t, p, false); t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_ANY, rr->key->type, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE); if (t) - dns_transaction_process_reply(t, p); + dns_transaction_process_reply(t, p, false); t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_ANY, DNS_TYPE_ANY, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE); if (t) - dns_transaction_process_reply(t, p); + dns_transaction_process_reply(t, p, false); } dns_cache_put(&scope->cache, scope->manager->enable_cache, NULL, DNS_PACKET_RCODE(p), p->answer, NULL, false, _DNSSEC_RESULT_INVALID, (uint32_t) -1, p->family, &p->sender); diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c index b691e59d3e..77e75b8a8d 100644 --- a/src/resolve/resolved-varlink.c +++ b/src/resolve/resolved-varlink.c @@ -222,7 +222,7 @@ static void vl_method_resolve_hostname_complete(DnsQuery *q) { JSON_BUILD_OBJECT( JSON_BUILD_PAIR("addresses", JSON_BUILD_VARIANT(array)), JSON_BUILD_PAIR("name", JSON_BUILD_STRING(normalized)), - JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)))))); + JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(dns_query_reply_flags_make(q))))); finish: if (r < 0) { log_error_errno(r, "Failed to send hostname reply: %m"); @@ -267,7 +267,8 @@ static int parse_as_address(Varlink *link, LookupParameters *p) { JSON_BUILD_PAIR("family", JSON_BUILD_INTEGER(ff)), JSON_BUILD_PAIR("address", JSON_BUILD_BYTE_ARRAY(&parsed, FAMILY_ADDRESS_SIZE(ff)))))), JSON_BUILD_PAIR("name", JSON_BUILD_STRING(canonical)), - JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(p->flags), ff, true))))); + JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(p->flags), ff, true, true)| + SD_RESOLVED_SYNTHETIC)))); } static int vl_method_resolve_hostname(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) { @@ -440,7 +441,7 @@ static void vl_method_resolve_address_complete(DnsQuery *q) { r = varlink_replyb(q->varlink_request, JSON_BUILD_OBJECT( JSON_BUILD_PAIR("names", JSON_BUILD_VARIANT(array)), - JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)))))); + JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(dns_query_reply_flags_make(q))))); finish: if (r < 0) { log_error_errno(r, "Failed to send address reply: %m"); |