On 10/27/2017 06:51 PM, Norman Gray wrote: > At present, x2goserver sanitises usernames with a regexp in x2goutils.pm > and in x2gosqlitewrapper.pl (same in both places). [...] Just to make it clear - we're not really "validating user names". I couldn't care less about the user name as such - it's the system's responsibility to deal with user names and if users managed to login, we can assume the user name is valid, like you've already written on the -dev mailing list and here. What we really do in this part of code is validating a session ID, which happens to contain a user name. Sadly, as such, what we see as a user name must be correctly represented in order to check the session ID. Generally, a session ID should look like that: --_st_dp We want to make sure that this ID is valid and, further, that specific parts can be extracted from it. > A username of, eg, '1234567x' fails this test, and the x2go session > fails to start. This is a valid username on CentOS (which is the OS I'm > using in this case, but CentOS is far from unique here), therefore such > a username should _not_ be rejected. Okay, so we want to accept numeric and user names starting with digits. > An alternative test would be to use getpwent(3). This would verify that > the proffered username is valid, absolutely authoritatively, without > making any assumptions about what is or isn't valid on the current > platform. x2go should not second-guess getpwent(3). This is probably appropriate for other checks, yes, if we really need to make sure that a user name is valid on the system. > Note that the test may in fact be redundant, since if this code is being > run, then the corresponding user has already logged on to the system, so > that the username has already been verified as valid and existing. In theory it's redundant. But there is a possibility that we are reading garbage data, where ever that might come from. Any bug (including our scripts messing up splitting up something, or inserting something invalid into the database and reading it again later) could trigger such a situation, so IMHO validation of input strings is really not redundant. > * POSIX/Single Unix says of the username simply "To be portable > across systems conforming to POSIX.1-2008, the value is composed of > characters from the portable filename character set. The > character should not be used as the first character of a portable user > name." (see , > paragraph 3.437) So, hyphen is prohibited as the first character. Also, SUS recommends (but does not enforce) using the portable filename character set[0] only for portability, which is restricted to [A-Za-z0-9._-]. Specifically, this does not include any special characters like umlauts, accented characters or generally any other Unicode character. > * The Debian useradd(8) page recommends something matching > /^[a-z_][a-z0-9_-]*$/, but goes on to say "On Debian, the only > constraints are that usernames must neither start with a dash ('-') nor > contain a colon (':') or a whitespace (space: ' ', end of line: '\n', > tabulation: '\t', etc.). Note that using a slash ('/') may break the > default algorithm for the definition of the user's home directory." (see > eg ) This is a bit stricter than the SUS definition (ignoring the portability recommendation). If taken at face value, Debian allows any Unicode character but the restricted ones. Interestingly, the recommended matching regexp doesn't include uppercase characters and, arguably more interestingly, doesn't allow a user name to start with a digit (which would be problematic for you). > * The corresponding RedHat/CentOS manpage doesn't even include that, > and instead says only "Usernames may only be up to 32 characters long." > FreeBSD is similarly laid-back about the username. This is interesting as well, since it's the first document that mentions a maximum length. If interpreted directly, the previous documents did not restrict the length (unless you haven't pasted some information relating to the string length). Currently, we seem to limit the user name to a length of at least one to 48 characters. Not sure where this limit is coming from, but it's higher than what RHEL/CentOS documents. Specifically, if the 32 characters limit is a hard one, parsing longer user names than this successfully would be invalid. Then again, I'm not inclined to implement per-system limits, so I'd rather go with the most restricted set... In the current code, for some reason we are also allowing the characters $ and @, if they are not the first characters. I'm not sure why that is, but allowing @ might be a consequence of multi-server support (i.e., that @ acts a separator for the host name.) Also, a trailing character of $ is allowed, which ramps up the section to 49 characters in total. Going through the history, I can see that previously, a 32 (or 33) character limit was enforced, but changed to 48 (or 49) as part of this bug report: https://bugs.x2go.org/cgi-bin/bugreport.cgi?bug=574 The @ character indeed has been added to allow email-address-like user names as part of https://bugs.x2go.org/cgi-bin/bugreport.cgi?bug=573 Allowing $ as trailing characters has been part from the start, though I honestly don't understand why. So, with all that, the most unrestrained option would be to use /^[^-].*/ for the user name part. If taking the SUS recommendation for portable user names into account, that would change to /^[A-Za-z0-9._][A-Za-z0-9._-]*/. If also applying the RHEL restriction of 32 characters, we'd come out at /^[A-Za-z0-9._][A-Za-z0-9._-]{0,31}/. My initial idea was to just use the last regexp, but this would break setups with user@domain user names or user names longer than 32 characters. In theory, /^[A-Za-z0-9._][A-Za-z0-9._-@]*/ should be more liberal, not restrict the length, allow portable user names and expand on that by allowing domain-based user names as well. I'd drop the trailing $. Mihai [0] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282