summaryrefslogtreecommitdiff
path: root/src/resolve
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-11-21 22:58:13 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-12-10 09:56:56 +0100
commit7470cc4c73c3736b93070ec01369e449e40a7cb3 (patch)
tree7f996421d5fb688a7f48f1f6b4d623f06b9f1990 /src/resolve
parentbd0052777981044cf54a1e9d6e3acb1c3d813656 (diff)
downloadsystemd-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.c8
-rw-r--r--src/resolve/resolved-dns-dnssec.c8
-rw-r--r--src/resolve/resolved-dns-packet.c2
-rw-r--r--src/resolve/resolved-dns-rr.c6
-rw-r--r--src/resolve/resolved-dns-search-domain.c2
-rw-r--r--src/resolve/resolved-dnssd.c4
-rw-r--r--src/resolve/resolved-etc-hosts.c2
-rw-r--r--src/resolve/resolved-manager.c10
-rw-r--r--src/resolve/test-resolved-etc-hosts.c12
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);