From 9cdd829299d6a60a92466f62b91cba74c366d827 Mon Sep 17 00:00:00 2001 From: jmhunter <19241458+jmhunter@users.noreply.github.com> Date: Wed, 17 Mar 2021 09:36:27 +0000 Subject: [PATCH 1/2] Update NAME_REGEX as per bug #1916325 The NAME_REGEX currently used is "[a-z_][a-z0-9_-]*" which does correctly prevent hostnames starting with a hyphen.. but also prevents otherwise perfectly valid hostnames that start with a number. (Interestingly, an underscore is not defined as a valid hostname character, but is included as valid in the regex, I'm not sure why this is included but am leaving it in for backwards compatibility) This patch adds 0-9 as valid characters at the start of a hostname, as per https://man7.org/linux/man-pages/man7/hostname.7.html#:~:text=Valid%20characters%20for%20hostnames%20are,to%20an%20address%20for%20use. Each element of the hostname must be from 1 to 63 characters long and the entire hostname, including the dots, can be at most 253 characters long. Valid characters for hostnames are ASCII(7) letters from a to z, the digits from 0 to 9, and the hyphen (-). A hostname may not start with a hyphen. --- subiquity/ui/views/identity.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subiquity/ui/views/identity.py b/subiquity/ui/views/identity.py index fcab46c7..e1760301 100644 --- a/subiquity/ui/views/identity.py +++ b/subiquity/ui/views/identity.py @@ -107,8 +107,8 @@ class IdentityForm(Form): "Server name too long, must be less than {limit}" ).format(limit=HOSTNAME_MAXLEN) - if not re.match(r'[a-z_][a-z0-9_-]*', self.hostname.value): - return _("Hostname must match NAME_REGEX, i.e. [a-z_][a-z0-9_-]*") + if not re.match(r'[a-z0-9_][a-z0-9_-]*', self.hostname.value): + return _("Hostname must match NAME_REGEX, i.e. [a-z0-9_][a-z0-9_-]*") def validate_username(self): username = self.username.value From c65c322fc659f452e2e16aa136b3afae45482b84 Mon Sep 17 00:00:00 2001 From: Jonathan Hunter <19241458+jmhunter@users.noreply.github.com> Date: Wed, 17 Mar 2021 20:09:41 +0000 Subject: [PATCH 2/2] Add variables to hold username and hostname regex Also adjust displayed message to match. Tested locally using 'make dryrun' --- subiquity/ui/views/identity.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/subiquity/ui/views/identity.py b/subiquity/ui/views/identity.py index e1760301..de41fca7 100644 --- a/subiquity/ui/views/identity.py +++ b/subiquity/ui/views/identity.py @@ -40,9 +40,11 @@ from subiquity.common.types import IdentityData log = logging.getLogger("subiquity.views.identity") HOSTNAME_MAXLEN = 64 +HOSTNAME_REGEX = r'[a-z0-9_][a-z0-9_-]*' REALNAME_MAXLEN = 160 SSH_IMPORT_MAXLEN = 256 + 3 # account for lp: or gh: USERNAME_MAXLEN = 32 +USERNAME_REGEX = r'[a-z_][a-z0-9_-]*' class RealnameEditor(StringEditor, WantsToKnowFormField): @@ -107,8 +109,9 @@ class IdentityForm(Form): "Server name too long, must be less than {limit}" ).format(limit=HOSTNAME_MAXLEN) - if not re.match(r'[a-z0-9_][a-z0-9_-]*', self.hostname.value): - return _("Hostname must match NAME_REGEX, i.e. [a-z0-9_][a-z0-9_-]*") + if not re.match(HOSTNAME_REGEX, self.hostname.value): + return _( + "Hostname must match HOSTNAME_REGEX: " + HOSTNAME_REGEX) def validate_username(self): username = self.username.value @@ -121,7 +124,8 @@ class IdentityForm(Form): ).format(limit=USERNAME_MAXLEN) if not re.match(r'[a-z_][a-z0-9_-]*', username): - return _("Username must match NAME_REGEX, i.e. [a-z_][a-z0-9_-]*") + return _( + "Username must match USERNAME_REGEX: " + USERNAME_REGEX) if username in self.reserved_usernames: return _(