summaryrefslogtreecommitdiff
path: root/src/basic/hostname-util.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-12-05 12:26:29 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-12-10 09:56:56 +0100
commitd65652f1f21a4b0c59711320f34266c635393c89 (patch)
tree1486de1f51215bf0a6577f4594eaf9f42f26a481 /src/basic/hostname-util.c
parent7470cc4c73c3736b93070ec01369e449e40a7cb3 (diff)
downloadsystemd-d65652f1f21a4b0c59711320f34266c635393c89.tar.gz
Partially unify hostname_is_valid() and dns_name_is_valid()
This makes hostname_is_valid() apply the ldh checks too, rejecting more hostnames.
Diffstat (limited to 'src/basic/hostname-util.c')
-rw-r--r--src/basic/hostname-util.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/src/basic/hostname-util.c b/src/basic/hostname-util.c
index 3a3479910d..0230821d22 100644
--- a/src/basic/hostname-util.c
+++ b/src/basic/hostname-util.c
@@ -69,12 +69,12 @@ int gethostname_strict(char **ret) {
return 0;
}
-static bool hostname_valid_char(char c) {
+bool valid_ldh_char(char c) {
return
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
- IN_SET(c, '-', '_', '.');
+ c == '-';
}
/**
@@ -90,7 +90,7 @@ static bool hostname_valid_char(char c) {
bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
unsigned n_dots = 0;
const char *p;
- bool dot;
+ bool dot, hyphen;
if (isempty(s))
return false;
@@ -100,23 +100,34 @@ bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
* sequence. Also ensures that the length stays below
* HOST_NAME_MAX. */
- for (p = s, dot = true; *p; p++) {
+ for (p = s, dot = hyphen = true; *p; p++)
if (*p == '.') {
- if (dot)
+ if (dot || hyphen)
return false;
dot = true;
+ hyphen = false;
n_dots++;
+
+ } else if (*p == '-') {
+ if (dot)
+ return false;
+
+ dot = false;
+ hyphen = true;
+
} else {
- if (!hostname_valid_char(*p))
+ if (!valid_ldh_char(*p))
return false;
dot = false;
+ hyphen = false;
}
- }
if (dot && (n_dots < 2 || !allow_trailing_dot))
return false;
+ if (hyphen)
+ return false;
if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on
* Linux, but DNS allows domain names
@@ -128,29 +139,40 @@ bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
char* hostname_cleanup(char *s) {
char *p, *d;
- bool dot;
+ bool dot, hyphen;
assert(s);
strshorten(s, HOST_NAME_MAX);
- for (p = s, d = s, dot = true; *p; p++) {
+ for (p = s, d = s, dot = hyphen = true; *p; p++)
if (*p == '.') {
- if (dot)
+ if (dot || hyphen)
continue;
*(d++) = '.';
dot = true;
- } else if (hostname_valid_char(*p)) {
+ hyphen = false;
+
+ } else if (*p == '-') {
+ if (dot)
+ continue;
+
+ *(d++) = '-';
+ dot = false;
+ hyphen = true;
+
+ } else if (valid_ldh_char(*p)) {
*(d++) = *p;
dot = false;
+ hyphen = false;
}
- }
- if (dot && d > s)
- d[-1] = 0;
- else
- *d = 0;
+ if (d > s && IN_SET(d[-1], '-', '.'))
+ /* The dot can occur at most once, but we might have multiple
+ * hyphens, hence the loop */
+ d--;
+ *d = 0;
return s;
}