From 7cf95470f3aaeb5091ebd493f9ba4427e421d5dd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Feb 2025 21:08:58 +0900 Subject: [PATCH 1/8] resolve: unify two validate_and_mangle_flags() The argument `Manager *manager`, is currently unused, but will be used later. --- src/resolve/resolved-bus.c | 65 ++++---------------------------- src/resolve/resolved-dns-query.c | 46 ++++++++++++++++++++++ src/resolve/resolved-dns-query.h | 2 + src/resolve/resolved-varlink.c | 54 ++------------------------ 4 files changed, 60 insertions(+), 107 deletions(-) diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index b81b9358d5..96cfd32257 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -361,51 +361,6 @@ finish: } } -static int validate_and_mangle_flags( - const char *name, - uint64_t *flags, - uint64_t ok, - sd_bus_error *error) { - - assert(flags); - - /* Checks that the client supplied interface index and flags parameter actually are valid and make - * sense in our method call context. Specifically: - * - * 1. Checks that the interface index is either 0 (meaning *all* interfaces) or positive - * - * 2. Only the protocols flags and a bunch of NO_XYZ flags are set, at most. Plus additional flags - * specific to our method, passed in the "ok" parameter. - * - * 3. If zero protocol flags are specified it is automatically turned into *all* protocols. This way - * clients can simply pass 0 as flags and all will work as it should. They can also use this so - * that clients don't have to know all the protocols resolved implements, but can just specify 0 - * to mean "all supported protocols". - */ - - if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL| - SD_RESOLVED_NO_CNAME| - SD_RESOLVED_NO_VALIDATE| - SD_RESOLVED_NO_SYNTHESIZE| - SD_RESOLVED_NO_CACHE| - SD_RESOLVED_NO_ZONE| - SD_RESOLVED_NO_TRUST_ANCHOR| - SD_RESOLVED_NO_NETWORK| - SD_RESOLVED_NO_STALE| - SD_RESOLVED_RELAX_SINGLE_LABEL| - ok)) - return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter"); - - if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */ - *flags |= SD_RESOLVED_PROTOCOLS_ALL; - - /* Imply SD_RESOLVED_NO_SEARCH if permitted and name is dot suffixed. */ - if (name && FLAGS_SET(ok, SD_RESOLVED_NO_SEARCH) && dns_name_dot_suffixed(name) > 0) - *flags |= SD_RESOLVED_NO_SEARCH; - - return 0; -} - static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname, int family, uint64_t flags) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_free_ char *canonical = NULL; @@ -519,9 +474,8 @@ static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family); - r = validate_and_mangle_flags(hostname, &flags, SD_RESOLVED_NO_SEARCH, error); - if (r < 0) - return r; + if (validate_and_mangle_query_flags(m, &flags, hostname, SD_RESOLVED_NO_SEARCH) < 0) + return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter"); r = parse_as_address(message, ifindex, hostname, family, flags); if (r != 0) @@ -674,9 +628,8 @@ static int bus_method_resolve_address(sd_bus_message *message, void *userdata, s if (ifindex < 0) return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index"); - r = validate_and_mangle_flags(NULL, &flags, 0, error); - if (r < 0) - return r; + if (validate_and_mangle_query_flags(m, &flags, /* name = */ NULL, /* ok = */ 0) < 0) + return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter"); r = dns_question_new_reverse(&question, family, &a); if (r < 0) @@ -843,9 +796,8 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd if (dns_type_is_obsolete(type)) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Specified DNS resource record type %" PRIu16 " is obsolete.", type); - r = validate_and_mangle_flags(name, &flags, 0, error); - if (r < 0) - return r; + if (validate_and_mangle_query_flags(m, &flags, name, /* ok = */ 0) < 0) + return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter"); question = dns_question_new(1); if (!question) @@ -1378,9 +1330,8 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s if (name && !type) return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type."); - r = validate_and_mangle_flags(name, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error); - if (r < 0) - return r; + if (validate_and_mangle_query_flags(m, &flags, name, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS) < 0) + return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter"); r = dns_question_new_service(&question_utf8, name, type, domain, !(flags & SD_RESOLVED_NO_TXT), false); if (r < 0) diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index 78c57da181..5698511b80 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -1440,3 +1440,49 @@ bool dns_query_fully_authoritative(DnsQuery *q) { * explicitly check previous redirects here.) */ return (q->answer_query_flags & SD_RESOLVED_FROM_MASK & ~(SD_RESOLVED_FROM_TRUST_ANCHOR | SD_RESOLVED_FROM_ZONE)) == 0; } + +int validate_and_mangle_query_flags( + Manager *manager, + uint64_t *flags, + const char *name, + uint64_t ok) { + + assert(manager); + assert(flags); + + /* Checks that the client supplied interface index and flags parameter actually are valid and make + * sense in our method call context. Specifically: + * + * 1. Checks that the interface index is either 0 (meaning *all* interfaces) or positive + * + * 2. Only the protocols flags and a bunch of NO_XYZ flags are set, at most. Plus additional flags + * specific to our method, passed in the "ok" parameter. + * + * 3. If zero protocol flags are specified it is automatically turned into *all* protocols. This way + * clients can simply pass 0 as flags and all will work as it should. They can also use this so + * that clients don't have to know all the protocols resolved implements, but can just specify 0 + * to mean "all supported protocols". + */ + + if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL| + SD_RESOLVED_NO_CNAME| + SD_RESOLVED_NO_VALIDATE| + SD_RESOLVED_NO_SYNTHESIZE| + SD_RESOLVED_NO_CACHE| + SD_RESOLVED_NO_ZONE| + SD_RESOLVED_NO_TRUST_ANCHOR| + SD_RESOLVED_NO_NETWORK| + SD_RESOLVED_NO_STALE| + SD_RESOLVED_RELAX_SINGLE_LABEL| + ok)) + return -EINVAL; + + if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */ + *flags |= SD_RESOLVED_PROTOCOLS_ALL; + + /* Imply SD_RESOLVED_NO_SEARCH if permitted and name is dot suffixed. */ + if (name && FLAGS_SET(ok, SD_RESOLVED_NO_SEARCH) && dns_name_dot_suffixed(name) > 0) + *flags |= SD_RESOLVED_NO_SEARCH; + + return 0; +} diff --git a/src/resolve/resolved-dns-query.h b/src/resolve/resolved-dns-query.h index 1097e90dc0..3a93ff7f1a 100644 --- a/src/resolve/resolved-dns-query.h +++ b/src/resolve/resolved-dns-query.h @@ -158,6 +158,8 @@ bool dns_query_fully_authenticated(DnsQuery *q); bool dns_query_fully_confidential(DnsQuery *q); bool dns_query_fully_authoritative(DnsQuery *q); +int validate_and_mangle_query_flags(Manager *manager, uint64_t *flags, const char *name, uint64_t ok); + static inline uint64_t dns_query_reply_flags_make(DnsQuery *q) { assert(q); diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c index d04bcc332e..c687dd694f 100644 --- a/src/resolve/resolved-varlink.c +++ b/src/resolve/resolved-varlink.c @@ -166,52 +166,6 @@ static void vl_on_notification_disconnect(sd_varlink_server *s, sd_varlink *link } } -static bool validate_and_mangle_flags( - const char *name, - uint64_t *flags, - uint64_t ok) { - - assert(flags); - - /* This checks that the specified client-provided flags parameter actually makes sense, and mangles - * it slightly. Specifically: - * - * 1. We check that only the protocol flags and a bunch of NO_XYZ flags are on at most, plus the - * method-specific flags specified in 'ok'. - * - * 2. If no protocols are enabled we automatically convert that to "all protocols are enabled". - * - * The second rule means that clients can just pass 0 as flags for the common case, and all supported - * protocols are enabled. Moreover it's useful so that client's do not have to be aware of all - * protocols implemented in resolved, but can use 0 as protocols flags set as indicator for - * "everything". - */ - - if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL| - SD_RESOLVED_NO_CNAME| - SD_RESOLVED_NO_VALIDATE| - SD_RESOLVED_NO_SYNTHESIZE| - SD_RESOLVED_NO_CACHE| - SD_RESOLVED_NO_ZONE| - SD_RESOLVED_NO_TRUST_ANCHOR| - SD_RESOLVED_NO_NETWORK| - SD_RESOLVED_NO_STALE| - SD_RESOLVED_RELAX_SINGLE_LABEL| - ok)) - return false; - - if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */ - *flags |= SD_RESOLVED_PROTOCOLS_ALL; - - /* If the SD_RESOLVED_NO_SEARCH flag is acceptable, and the query name is dot-suffixed, turn off - * search domains. Note that DNS name normalization drops the dot suffix, hence we propagate this - * into the flags field as early as we can. */ - if (name && FLAGS_SET(ok, SD_RESOLVED_NO_SEARCH) && dns_name_dot_suffixed(name) > 0) - *flags |= SD_RESOLVED_NO_SEARCH; - - return true; -} - static int find_addr_records( sd_json_variant **array, DnsQuestion *question, @@ -387,7 +341,7 @@ static int vl_method_resolve_hostname(sd_varlink *link, sd_json_variant *paramet if (!IN_SET(p.family, AF_UNSPEC, AF_INET, AF_INET6)) return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("family")); - if (!validate_and_mangle_flags(p.name, &p.flags, SD_RESOLVED_NO_SEARCH)) + if (validate_and_mangle_query_flags(m, &p.flags, p.name, SD_RESOLVED_NO_SEARCH) < 0) return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags")); r = parse_as_address(link, &p); @@ -550,7 +504,7 @@ static int vl_method_resolve_address(sd_varlink *link, sd_json_variant *paramete if (FAMILY_ADDRESS_SIZE(p.family) != p.address_size) return sd_varlink_error(link, "io.systemd.Resolve.BadAddressSize", NULL); - if (!validate_and_mangle_flags(NULL, &p.flags, 0)) + if (validate_and_mangle_query_flags(m, &p.flags, /* name = */ NULL, /* ok = */ 0) < 0) return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags")); r = dns_question_new_reverse(&question, p.family, &p.address); @@ -1044,7 +998,7 @@ static int vl_method_resolve_service(sd_varlink* link, sd_json_variant* paramete if (p.name && !p.type) /* Service name cannot be specified without service type. */ return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("type")); - if (!validate_and_mangle_flags(p.name, &p.flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS)) + if (validate_and_mangle_query_flags(m, &p.flags, p.name, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS) < 0) return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags")); r = dns_question_new_service(&question_utf8, p.name, p.type, p.domain, !(p.flags & SD_RESOLVED_NO_TXT), false); @@ -1184,7 +1138,7 @@ static int vl_method_resolve_record(sd_varlink *link, sd_json_variant *parameter if (dns_type_is_obsolete(p.type)) return sd_varlink_error(link, "io.systemd.Resolve.ResourceRecordTypeObsolete", NULL); - if (!validate_and_mangle_flags(p.name, &p.flags, SD_RESOLVED_NO_SEARCH)) + if (validate_and_mangle_query_flags(m, &p.flags, p.name, SD_RESOLVED_NO_SEARCH) < 0) return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags")); _cleanup_(dns_question_unrefp) DnsQuestion *question = dns_question_new(1); From 3c31cc39812bb9735a1d8bb2fc113df374d4b49f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Feb 2025 21:10:55 +0900 Subject: [PATCH 2/8] resolve: allow to specify SD_RESOLVED_NO_SEARCH flag in ResolveRecord The varlink method io.systemd.Resolve.ResolveRecord already accepts the flag. Let's also the bus method accept the flag, for consistency. --- src/resolve/resolved-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 96cfd32257..8415444463 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -796,7 +796,7 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd if (dns_type_is_obsolete(type)) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Specified DNS resource record type %" PRIu16 " is obsolete.", type); - if (validate_and_mangle_query_flags(m, &flags, name, /* ok = */ 0) < 0) + if (validate_and_mangle_query_flags(m, &flags, name, SD_RESOLVED_NO_SEARCH) < 0) return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter"); question = dns_question_new(1); From 9ec25fba5a421d0b59dda9a59aa5b1b5da9f3c37 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Feb 2025 21:16:31 +0900 Subject: [PATCH 3/8] resolve: if both A and AAAA are refused, do not resolve address when resolving service Similarly, set NO_TXT flag if TXT is filtered. Follow-up for 81ae2237c1792943a1ec712ae2e630bcc592175b. Fixes https://github.com/systemd/systemd/pull/36353#issuecomment-2659558382. --- src/resolve/resolved-dns-query.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index 5698511b80..4522328319 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -1484,5 +1484,16 @@ int validate_and_mangle_query_flags( if (name && FLAGS_SET(ok, SD_RESOLVED_NO_SEARCH) && dns_name_dot_suffixed(name) > 0) *flags |= SD_RESOLVED_NO_SEARCH; + /* If both A and AAAA are refused, set SD_RESOLVED_NO_ADDRESS flag if it is allowed. */ + if (set_contains(manager->refuse_record_types, INT_TO_PTR(DNS_TYPE_A)) && + set_contains(manager->refuse_record_types, INT_TO_PTR(DNS_TYPE_AAAA)) && + FLAGS_SET(ok, SD_RESOLVED_NO_ADDRESS)) + *flags |= SD_RESOLVED_NO_ADDRESS; + + /* Similarly, if TXT is refused, set SD_RESOLVED_NO_TXT flag if it is allowed. */ + if (set_contains(manager->refuse_record_types, INT_TO_PTR(DNS_TYPE_TXT)) && + FLAGS_SET(ok, SD_RESOLVED_NO_TXT)) + *flags |= SD_RESOLVED_NO_TXT; + return 0; } From 0592f3f413cb9877de85b558254c10834527a1e7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Feb 2025 22:54:44 +0900 Subject: [PATCH 4/8] resolve: refuse ResolveService method if SRV is filtered Follow-up for 81ae2237c1792943a1ec712ae2e630bcc592175b. --- src/resolve/resolved-bus.c | 4 ++++ src/resolve/resolved-varlink.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 8415444463..d5782e4687 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -1333,6 +1333,10 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s if (validate_and_mangle_query_flags(m, &flags, name, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS) < 0) return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter"); + /* Refuse the method if SRV is filtered. */ + if (set_contains(m->refuse_record_types, INT_TO_PTR(DNS_TYPE_SRV))) + return sd_bus_error_set(error, BUS_ERROR_DNS_REFUSED, "DNS query type refused."); + r = dns_question_new_service(&question_utf8, name, type, domain, !(flags & SD_RESOLVED_NO_TXT), false); if (r < 0) return r; diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c index c687dd694f..61f9f8e646 100644 --- a/src/resolve/resolved-varlink.c +++ b/src/resolve/resolved-varlink.c @@ -1001,6 +1001,10 @@ static int vl_method_resolve_service(sd_varlink* link, sd_json_variant* paramete if (validate_and_mangle_query_flags(m, &p.flags, p.name, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS) < 0) return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags")); + /* Refuse the method if SRV is filtered. */ + if (set_contains(m->refuse_record_types, INT_TO_PTR(DNS_TYPE_SRV))) + return sd_varlink_error(link, "io.systemd.Resolve.QueryRefused", NULL); + r = dns_question_new_service(&question_utf8, p.name, p.type, p.domain, !(p.flags & SD_RESOLVED_NO_TXT), false); if (r < 0) return r; From 6ad252c1a5c87d9acdfc12f7813824516d73325e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Feb 2025 22:16:34 +0900 Subject: [PATCH 5/8] TEST-75-RESOLVED: drop unnecessary symlink creation It is always done in setup(). --- test/units/TEST-75-RESOLVED.sh | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index cf78e8b6dd..3ba908981f 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -850,7 +850,6 @@ testcase_11_nft() { echo "[Resolve]" echo "StaleRetentionSec=1d" } >/run/systemd/resolved.conf.d/test.conf - ln -svf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf systemctl reload systemd-resolved.service run dig stale1.unsigned.test -t A @@ -1096,10 +1095,6 @@ testcase_14_refuse_record_types() { # shellcheck disable=SC2317 cleanup() { rm -f /run/systemd/resolved.conf.d/refuserecords.conf - if [[ -e /etc/resolv.conf.bak ]]; then - rm -f /etc/resolv.conf - mv /etc/resolv.conf.bak /etc/resolv.conf - fi restart_resolved } trap cleanup RETURN ERR @@ -1109,11 +1104,8 @@ testcase_14_refuse_record_types() { echo "[Resolve]" echo "RefuseRecordTypes=AAAA SRV TXT" } >/run/systemd/resolved.conf.d/refuserecords.conf - if [[ -e /etc/resolv.conf ]]; then - mv /etc/resolv.conf /etc/resolv.conf.bak - fi - ln -svf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf systemctl reload systemd-resolved.service + run dig localhost -t AAAA grep -qF "status: REFUSED" "$RUN_OUT" From 5a07bb2c55adfcde88a7bf6cf99a1e9d79163232 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Feb 2025 22:35:19 +0900 Subject: [PATCH 6/8] TEST-75-RESOLVED: revert changes done in each test case --- test/units/TEST-75-RESOLVED.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index 3ba908981f..8afd5a6476 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -942,6 +942,7 @@ testcase_12_resolvectl2() { cleanup() { rm -f /run/systemd/resolved.conf.d/reload.conf systemctl reload systemd-resolved.service + resolvectl revert dns0 } trap cleanup RETURN @@ -1023,6 +1024,7 @@ testcase_13_varlink_subscribe_dns_configuration() { echo "==========" rm -f /run/systemd/resolved.conf.d/global-dns.conf restart_resolved + resolvectl revert dns0 } trap cleanup RETURN ERR From d13b5fdc011f8d6e780f9573ade2a90f936cce6f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Feb 2025 23:10:16 +0900 Subject: [PATCH 7/8] TEST-75-RESOLVED: check TXT field --- test/units/TEST-75-RESOLVED.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index 8afd5a6476..8df5caea4e 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -551,6 +551,7 @@ testcase_08_resolved() { # Check SRV support run resolvectl service _mysvc._tcp signed.test grep -qF "myservice.signed.test:1234" "$RUN_OUT" + grep -qF "This is TXT for myservice" "$RUN_OUT" grep -qF "10.0.0.20" "$RUN_OUT" grep -qF "fd00:dead:beef:cafe::17" "$RUN_OUT" grep -qF "authenticated: yes" "$RUN_OUT" From 7ffa9dc61605d9807c7b29ffa52b7c658e271bd4 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Feb 2025 21:22:22 +0900 Subject: [PATCH 8/8] TEST-75-RESOLVED: add test cases for resolving service with record type filter --- test/units/TEST-75-RESOLVED.sh | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index 8df5caea4e..1b2f317532 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -1136,6 +1136,10 @@ testcase_14_refuse_record_types() { run resolvectl query localhost5 --type=A grep -qF "127.128.0.5" "$RUN_OUT" + (! run resolvectl service _mysvc._tcp signed.test) + (! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"name":"","type":"_mysvc._tcp","domain":"signed.test"}') + + # Filter only AAAA { echo "[Resolve]" echo "RefuseRecordTypes=AAAA" @@ -1159,6 +1163,74 @@ testcase_14_refuse_record_types() { (! run resolvectl query localhost5 --type=AAAA) grep -qF "DNS query type refused." "$RUN_OUT" + + run resolvectl service _mysvc._tcp signed.test + grep -qF "myservice.signed.test:1234" "$RUN_OUT" + grep -qF "This is TXT for myservice" "$RUN_OUT" + grep -qF "10.0.0.20" "$RUN_OUT" + (! grep -qF "fd00:dead:beef:cafe::17" "$RUN_OUT") + grep -qF "authenticated: yes" "$RUN_OUT" + + run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"name":"","type":"_mysvc._tcp","domain":"signed.test"}' + grep -qF '"services":[{"priority":10,"weight":5,"port":1234,"hostname":"myservice.signed.test","canonicalName":"myservice.signed.test"' "$RUN_OUT" + grep -qF '"addresses":[{"ifindex":' "$RUN_OUT" + grep -qF '"family":2,"address":[10,0,0,20]' "$RUN_OUT" + (! grep -qF '"family":10,"address":[253,0,222,173,190,239,202,254,0,0,0,0,0,0,0,23]' "$RUN_OUT") + grep -qF '"txt":["This is TXT for myservice"]' "$RUN_OUT" + grep -qF '"canonical":{"name":null,"type":"_mysvc._tcp","domain":"signed.test"}' "$RUN_OUT" + + # Filter both A and AAAA + { + echo "[Resolve]" + echo "RefuseRecordTypes=A AAAA" + } >/run/systemd/resolved.conf.d/refuserecords.conf + systemctl reload systemd-resolved.service + + run resolvectl service _mysvc._tcp signed.test + grep -qF "myservice.signed.test:1234" "$RUN_OUT" + grep -qF "This is TXT for myservice" "$RUN_OUT" + (! grep -qF "10.0.0.20" "$RUN_OUT") + (! grep -qF "fd00:dead:beef:cafe::17" "$RUN_OUT") + grep -qF "authenticated: yes" "$RUN_OUT" + + run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"name":"","type":"_mysvc._tcp","domain":"signed.test"}' + grep -qF '"services":[{"priority":10,"weight":5,"port":1234,"hostname":"myservice.signed.test"}]' "$RUN_OUT" + (! grep -qF '"addresses":[{"ifindex":' "$RUN_OUT") + (! grep -qF '"family":2,"address":[10,0,0,20]' "$RUN_OUT") + (! grep -qF '"family":10,"address":[253,0,222,173,190,239,202,254,0,0,0,0,0,0,0,23]' "$RUN_OUT") + grep -qF '"txt":["This is TXT for myservice"]' "$RUN_OUT" + grep -qF '"canonical":{"name":null,"type":"_mysvc._tcp","domain":"signed.test"}' "$RUN_OUT" + + # Filter AAAA and TXT + { + echo "[Resolve]" + echo "RefuseRecordTypes=AAAA TXT" + } >/run/systemd/resolved.conf.d/refuserecords.conf + systemctl reload systemd-resolved.service + + run resolvectl service _mysvc._tcp signed.test + grep -qF "myservice.signed.test:1234" "$RUN_OUT" + grep -qF "10.0.0.20" "$RUN_OUT" + (! grep -qF "fd00:dead:beef:cafe::17" "$RUN_OUT") + grep -qF "authenticated: yes" "$RUN_OUT" + + run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"name":"","type":"_mysvc._tcp","domain":"signed.test"}' + grep -qF '"services":[{"priority":10,"weight":5,"port":1234,"hostname":"myservice.signed.test","canonicalName":"myservice.signed.test"' "$RUN_OUT" + grep -qF '"addresses":[{"ifindex":' "$RUN_OUT" + grep -qF '"family":2,"address":[10,0,0,20]' "$RUN_OUT" + (! grep -qF '"family":10,"address":[253,0,222,173,190,239,202,254,0,0,0,0,0,0,0,23]' "$RUN_OUT") + (! grep -qF '"txt":["This is TXT for myservice"]' "$RUN_OUT") + grep -qF '"canonical":{"name":null,"type":"_mysvc._tcp","domain":"signed.test"}' "$RUN_OUT" + + # Filter SRV + { + echo "[Resolve]" + echo "RefuseRecordTypes=SRV" + } >/run/systemd/resolved.conf.d/refuserecords.conf + systemctl reload systemd-resolved.service + + (! run resolvectl service _mysvc._tcp signed.test) + (! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"name":"","type":"_mysvc._tcp","domain":"signed.test"}') } # PRE-SETUP