From d1d565b1d9d984afa317ea7ef31f6090590cf7e3 Mon Sep 17 00:00:00 2001 From: Slawomir Koszewski Date: Mon, 26 Oct 2026 09:11:13 +0100 Subject: [PATCH] fix: a service account may be named by a GUID in lowercase, as the Router Manager proposes for a new one. --- README.md | 4 +++- debian-package/debian/changelog | 10 ++++++++++ .../src/usr/lib/vpn-router/vpnrouter_users.py | 14 +++++++++----- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 272b0f4..b0374b8 100644 --- a/README.md +++ b/README.md @@ -717,7 +717,9 @@ vpn-router-user otp-remove alice | `console (--posix \| --account LOCAL \| --off)` | Switches the console login of a member of `admins` enrolled for TOTP on, as the user's own POSIX account or a local account, or off (see Console login and SSH) | | `passkeys-remove ` | Removes all the user's passkeys (see Passkeys) | -A user name is 1 to 32 lowercase letters, digits and hyphens, starting with a letter; a +A user name is 1 to 32 lowercase letters, digits and hyphens, starting with a letter, and a +service account may instead be named by a GUID in lowercase, such as +`3f2b8c1e-9a4d-4e6f-8b2a-1c5d7e9f0a3b`; a password has 8 to 128 characters; a first or last name has 1 to 64 printable characters; an e-mail address has one `@`, no spaces and a dot in its domain; a TOTP secret is 32 base32 characters, as `otp-new` makes it, and a code 6 digits. Once enrolled, a user logs in to OpenVPN diff --git a/debian-package/debian/changelog b/debian-package/debian/changelog index 72b3f53..b4888f9 100644 --- a/debian-package/debian/changelog +++ b/debian-package/debian/changelog @@ -1,3 +1,13 @@ +vpn-router (0.26.2-1) unstable; urgency=medium + + fix: a service account may be named by a GUID in lowercase, as the Router Manager proposes for a new one. + + * vpn-router-user add --service and POST /service-accounts take a GUID + in lowercase as the name, besides a user name; users and groups keep + the rules of user names. + + -- Slawomir Koszewski Mon, 26 Oct 2026 10:00:00 +0100 + vpn-router (0.26.1-1) unstable; urgency=medium fix: the package installs vpnrouter_passkeys, without which the web service and vpn-router-user do not start. diff --git a/debian-package/src/usr/lib/vpn-router/vpnrouter_users.py b/debian-package/src/usr/lib/vpn-router/vpnrouter_users.py index d3d4106..9880daa 100644 --- a/debian-package/src/usr/lib/vpn-router/vpnrouter_users.py +++ b/debian-package/src/usr/lib/vpn-router/vpnrouter_users.py @@ -74,6 +74,8 @@ import vpnrouter_pki #: A user name is one lowercase DNS label, as it is also the common name of the certificate. NAME = re.compile(r'^[a-z][a-z0-9-]{0,30}[a-z0-9]$|^[a-z]$') +#: The other name of a service account: a GUID in lowercase hexadecimal, as the Router Manager proposes one. +GUID = re.compile(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$') PASSWORD_MIN = 8 PASSWORD_MAX = 128 #: The longest first or last name, in characters. @@ -135,9 +137,11 @@ def session(): connection.unbind_s() -def check_name(name): - if not isinstance(name, str) or not NAME.match(name): - raise Failure('a user name is 1 to 32 lowercase letters, digits and hyphens, starting with a letter', 2) +def check_name(name, service=True): + """Refuse a name that is not a user name (NAME), or, with service, the GUID of a service account either.""" + if not isinstance(name, str) or not (NAME.match(name) or service and GUID.match(name)): + raise Failure('a user name is 1 to 32 lowercase letters, digits and hyphens, starting with a letter' + + (', or, for a service account, a GUID in lowercase' if service else ''), 2) def check_password(value): @@ -462,8 +466,8 @@ def list_users(connection): def add(connection, name, password, values, service=False): """Add a user: a VPN user with its certificate when values gives all three person attributes, a Manager-only account with at most the e-mail address when it gives neither name, and, with service, a service account, with at most the - e-mail address and its labels (labels).""" - check_name(name) + e-mail address and its labels (labels); only a service account may be named by a GUID.""" + check_name(name, service) details = person(values, required=False) vpn_user = 'givenName' in details or 'sn' in details if service and vpn_user: