diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-11-21 22:58:13 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-12-10 09:56:56 +0100 |
commit | 7470cc4c73c3736b93070ec01369e449e40a7cb3 (patch) | |
tree | 7f996421d5fb688a7f48f1f6b4d623f06b9f1990 /src/resolve | |
parent | bd0052777981044cf54a1e9d6e3acb1c3d813656 (diff) | |
download | systemd-7470cc4c73c3736b93070ec01369e449e40a7cb3.tar.gz |
resolve: reject host names with leading or trailing dashes in /etc/hosts
https://tools.ietf.org/html/rfc1035#section-2.3.1 says (approximately)
that only letters, numbers, and non-leading non-trailing dashes are allowed
(for entries with A/AAAA records). We set no restrictions.
hosts(5) says:
> Host names may contain only alphanumeric characters, minus signs ("-"), and
> periods ("."). They must begin with an alphabetic character and end with an
> alphanumeric character.
nss-files follows those rules, and will ignore names in /etc/hosts that do not
follow this rule.
Let's follow the documented rules for /etc/hosts. In particular, this makes us
consitent with nss-files, reducing surprises for the user.
I'm pretty sure we should apply stricter filtering to names received over DNS
and LLMNR and MDNS, but it's a bigger project, because the rules differ
depepending on which level the label appears (rules for top-level names are
stricter), and this patch takes the minimalistic approach and only changes
behaviour for /etc/hosts.
Escape syntax is also disallowed in /etc/hosts, even if the resulting character
would be allowed. Other tools that parse /etc/hosts do not support this, and
there is no need to use it because no allowed characters benefit from escaping.
Diffstat (limited to 'src/resolve')
-rw-r--r-- | src/resolve/resolved-bus.c | 8 | ||||
-rw-r--r-- | src/resolve/resolved-dns-dnssec.c | 8 | ||||
-rw-r--r-- | src/resolve/resolved-dns-packet.c | 2 | ||||
-rw-r--r-- | src/resolve/resolved-dns-rr.c | 6 | ||||
-rw-r--r-- | src/resolve/resolved-dns-search-domain.c | 2 | ||||
-rw-r--r-- | src/resolve/resolved-dnssd.c | 4 | ||||
-rw-r--r-- | src/resolve/resolved-etc-hosts.c | 2 | ||||
-rw-r--r-- | src/resolve/resolved-manager.c | 10 | ||||
-rw-r--r-- | src/resolve/test-resolved-etc-hosts.c | 12 |
9 files changed, 24 insertions, 30 deletions
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 75702d593f..d80b16c9d9 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -191,7 +191,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) { /* The key names are not necessarily normalized, make sure that they are when we return them to our bus * clients. */ - r = dns_name_normalize(dns_resource_key_name(canonical->key), &normalized); + r = dns_name_normalize(dns_resource_key_name(canonical->key), 0, &normalized); if (r < 0) goto finish; @@ -404,7 +404,7 @@ static void bus_method_resolve_address_complete(DnsQuery *q) { if (r == 0) continue; - r = dns_name_normalize(rr->ptr.name, &normalized); + r = dns_name_normalize(rr->ptr.name, 0, &normalized); if (r < 0) goto finish; @@ -742,7 +742,7 @@ static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) if (r < 0) return r; - r = dns_name_normalize(rr->srv.name, &normalized); + r = dns_name_normalize(rr->srv.name, 0, &normalized); if (r < 0) return r; @@ -798,7 +798,7 @@ static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) if (canonical) { normalized = mfree(normalized); - r = dns_name_normalize(dns_resource_key_name(canonical->key), &normalized); + r = dns_name_normalize(dns_resource_key_name(canonical->key), 0, &normalized); if (r < 0) return r; } diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index 13da4e5991..d9633629e8 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -74,7 +74,7 @@ int dnssec_canonicalize(const char *n, char *buffer, size_t buffer_max) { return -ENOBUFS; for (;;) { - r = dns_label_unescape(&n, buffer, buffer_max); + r = dns_label_unescape(&n, buffer, buffer_max, 0); if (r < 0) return r; if (r == 0) @@ -1705,7 +1705,7 @@ static int dnssec_nsec_wildcard_equal(DnsResourceRecord *rr, const char *name) { return 0; n = dns_resource_key_name(rr->key); - r = dns_label_unescape(&n, label, sizeof(label)); + r = dns_label_unescape(&n, label, sizeof label, 0); if (r <= 0) return r; if (r != 1 || label[0] != '*') @@ -1827,13 +1827,13 @@ static int dnssec_nsec_covers_wildcard(DnsResourceRecord *rr, const char *name) return r; if (r > 0) /* If the name we are interested in is a child of the NSEC RR, then append the asterisk to the NSEC * RR's name. */ - r = dns_name_concat("*", dns_resource_key_name(rr->key), &wc); + r = dns_name_concat("*", dns_resource_key_name(rr->key), 0, &wc); else { r = dns_name_common_suffix(dns_resource_key_name(rr->key), rr->nsec.next_domain_name, &common_suffix); if (r < 0) return r; - r = dns_name_concat("*", common_suffix, &wc); + r = dns_name_concat("*", common_suffix, 0, &wc); } if (r < 0) return r; diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 0ff444acd0..572271be95 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -535,7 +535,7 @@ int dns_packet_append_name( } } - r = dns_label_unescape(&name, label, sizeof(label)); + r = dns_label_unescape(&name, label, sizeof label, 0); if (r < 0) goto fail; diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index b67c734e04..a1dffb08a3 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -77,7 +77,7 @@ int dns_resource_key_new_append_suffix(DnsResourceKey **ret, DnsResourceKey *key return 0; } - r = dns_name_concat(dns_resource_key_name(key), name, &joined); + r = dns_name_concat(dns_resource_key_name(key), name, 0, &joined); if (r < 0) return r; @@ -222,7 +222,7 @@ int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr, if (search_domain) { _cleanup_free_ char *joined = NULL; - r = dns_name_concat(dns_resource_key_name(key), search_domain, &joined); + r = dns_name_concat(dns_resource_key_name(key), search_domain, 0, &joined); if (r < 0) return r; @@ -254,7 +254,7 @@ int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsRe if (search_domain) { _cleanup_free_ char *joined = NULL; - r = dns_name_concat(dns_resource_key_name(key), search_domain, &joined); + r = dns_name_concat(dns_resource_key_name(key), search_domain, 0, &joined); if (r < 0) return r; diff --git a/src/resolve/resolved-dns-search-domain.c b/src/resolve/resolved-dns-search-domain.c index 368ec4da19..21c2442c51 100644 --- a/src/resolve/resolved-dns-search-domain.c +++ b/src/resolve/resolved-dns-search-domain.c @@ -19,7 +19,7 @@ int dns_search_domain_new( assert((type == DNS_SEARCH_DOMAIN_LINK) == !!l); assert(name); - r = dns_name_normalize(name, &normalized); + r = dns_name_normalize(name, 0, &normalized); if (r < 0) return r; diff --git a/src/resolve/resolved-dnssd.c b/src/resolve/resolved-dnssd.c index ea96255dc1..2c28ec227a 100644 --- a/src/resolve/resolved-dnssd.c +++ b/src/resolve/resolved-dnssd.c @@ -228,10 +228,10 @@ int dnssd_update_rrs(DnssdService *s) { if (r < 0) return r; - r = dns_name_concat(s->type, "local", &service_name); + r = dns_name_concat(s->type, "local", 0, &service_name); if (r < 0) return r; - r = dns_name_concat(n, service_name, &full_name); + r = dns_name_concat(n, service_name, 0, &full_name); if (r < 0) return r; diff --git a/src/resolve/resolved-etc-hosts.c b/src/resolve/resolved-etc-hosts.c index 26a9e48c4c..01cde4acf7 100644 --- a/src/resolve/resolved-etc-hosts.c +++ b/src/resolve/resolved-etc-hosts.c @@ -99,7 +99,7 @@ static int parse_line(EtcHosts *hosts, unsigned nr, const char *line) { found = true; - r = dns_name_is_valid(name); + r = dns_name_is_valid_ldh(name); if (r <= 0) { log_warning_errno(r, "/etc/hosts:%u: hostname \"%s\" is not valid, ignoring.", nr, name); continue; diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 2174d660ff..f6832917c1 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -333,7 +333,7 @@ static int determine_hostname(char **full_hostname, char **llmnr_hostname, char return log_debug_errno(r, "Can't determine system hostname: %m"); p = h; - r = dns_label_unescape(&p, label, sizeof label); + r = dns_label_unescape(&p, label, sizeof label, 0); if (r < 0) return log_error_errno(r, "Failed to unescape host name: %m"); if (r == 0) @@ -371,7 +371,7 @@ static int determine_hostname(char **full_hostname, char **llmnr_hostname, char return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "System hostname is 'localhost', ignoring."); - r = dns_name_concat(n, "local", mdns_hostname); + r = dns_name_concat(n, "local", 0, mdns_hostname); if (r < 0) return log_error_errno(r, "Failed to determine mDNS hostname: %m"); @@ -403,7 +403,7 @@ static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname, assert(mdns_hostname); p = fallback_hostname(); - r = dns_label_unescape(&p, label, sizeof(label)); + r = dns_label_unescape(&p, label, sizeof label, 0); if (r < 0) return log_error_errno(r, "Failed to unescape fallback host name: %m"); @@ -413,7 +413,7 @@ static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname, if (r < 0) return log_error_errno(r, "Failed to escape fallback hostname: %m"); - r = dns_name_concat(n, "local", &m); + r = dns_name_concat(n, "local", 0, &m); if (r < 0) return log_error_errno(r, "Failed to concatenate mDNS hostname: %m"); @@ -1147,7 +1147,7 @@ int manager_next_hostname(Manager *m) { if (r < 0) return r; - r = dns_name_concat(h, "local", &k); + r = dns_name_concat(h, "local", 0, &k); if (r < 0) return r; diff --git a/src/resolve/test-resolved-etc-hosts.c b/src/resolve/test-resolved-etc-hosts.c index 0a08294d17..27e67df01f 100644 --- a/src/resolve/test-resolved-etc-hosts.c +++ b/src/resolve/test-resolved-etc-hosts.c @@ -91,15 +91,9 @@ static void test_parse_etc_hosts(void) { assert_se(bn->n_allocated >= 1); assert_se(address_equal_4(bn->addresses[0], inet_addr("1.2.3.6"))); - /* Those names do not follow the LDH rule, but so far we allow them. - * Let's make this explicit by adding a test. - * See https://tools.ietf.org/html/rfc1035#section-2.3.1 */ - FOREACH_STRING(s, "bad-dash-", "-bad-dash", "-bad-dash.bad-") { - assert_se(bn = hashmap_get(hosts.by_name, s)); - assert_se(bn->n_addresses == 1); - assert_se(bn->n_allocated >= 1); - assert_se(address_equal_4(bn->addresses[0], inet_addr("1.2.3.7"))); - } + /* See https://tools.ietf.org/html/rfc1035#section-2.3.1 */ + FOREACH_STRING(s, "bad-dash-", "-bad-dash", "-bad-dash.bad-") + assert_se(!hashmap_get(hosts.by_name, s)); assert_se(bn = hashmap_get(hosts.by_name, "before.comment")); assert_se(bn->n_addresses == 4); |