Port the systemd hostname_is_valid() function to perform hostname validation and inform the user about a invalid hostname. Signed-off-by: Marco Felsch <m.felsch@xxxxxxxxxxxxxx> --- common/misc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/common/misc.c b/common/misc.c index e266f0951ee9..dc498ad0b318 100644 --- a/common/misc.c +++ b/common/misc.c @@ -13,6 +13,7 @@ #include <led.h> #include <of.h> #include <restart.h> +#include <string.h> #include <linux/stringify.h> int errno; @@ -146,6 +147,67 @@ static char *hostname; static char *serial_number; static char *of_machine_compatible; +/* Note that HOST_NAME_MAX is 64 on Linux */ +#define BAREBOX_HOST_NAME_MAX 64 + +static bool barebox_valid_ldh_char(char c) +{ + /* "LDH" -> "Letters, digits, hyphens", as per RFC 5890, Section 2.3.1 */ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || c == '-'; +} + +static bool barebox_hostname_is_valid(const char *s) +{ + unsigned int n_dots = 0; + const char *p; + bool dot, hyphen; + + /* + * Check if s looks like a valid hostname or FQDN. This does not do full + * DNS validation, but only checks if the name is composed of allowed + * characters and the length is not above the maximum allowed by Linux. + * Doesn't accept empty hostnames, hostnames with leading dots, and + * hostnames with multiple dots in a sequence. Doesn't allow hyphens at + * the beginning or end of label. + */ + if (isempty(s)) + return false; + + for (p = s, dot = hyphen = true; *p; p++) { + if (*p == '.') { + if (dot || hyphen) + return false; + + dot = true; + hyphen = false; + n_dots++; + + } else if (*p == '-') { + if (dot) + return false; + + dot = false; + hyphen = true; + + } else { + if (!barebox_valid_ldh_char(*p)) + return false; + + dot = false; + hyphen = false; + } + } + + if (dot || hyphen) + return false; + + if (p - s > BAREBOX_HOST_NAME_MAX) + return false; + + return true; +} + /* * The hostname is supposed to be the shortname of a board. It should * contain only lowercase letters, numbers, '-', '_'. No whitespaces @@ -156,6 +218,10 @@ void barebox_set_hostname(const char *__hostname) globalvar_add_simple_string("hostname", &hostname); free(hostname); + + if (!barebox_hostname_is_valid(__hostname)) + pr_warn("Hostname is not valid, please fix it\n"); + hostname = xstrdup(__hostname); } -- 2.39.2