diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-08-09 04:05:13 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-08-09 04:05:13 +0200 |
| commit | 7485086f1eca78998d6cd31b0ce18a8a8ea3fc35 (patch) | |
| tree | ad3a754a07e29b0c86514bdac98c63618628b37d /libbb | |
| parent | 6e42b89b8d136316e1b97b56cf885e8ef9d64caf (diff) | |
| download | busybox-w32-7485086f1eca78998d6cd31b0ce18a8a8ea3fc35.tar.gz busybox-w32-7485086f1eca78998d6cd31b0ce18a8a8ea3fc35.tar.bz2 busybox-w32-7485086f1eca78998d6cd31b0ce18a8a8ea3fc35.zip | |
die_if_bad_username: tighten up a bit
function old new delta
die_if_bad_username 77 97 +20
Based on patches from Tito.
The changes are:
better comments
we disallow '@' now - in practice such usernames will be unusable
use of the portable filename character set plus '$'
don't use isalnum as it allows non-ASCII letters in legacy 8-bit locales (pointed out by Rich Felker)
enforce maximum length of LOGIN_NAME_MAX (including NUL)
don't allow '$', '.', and '-' as first char
don't print the illegal char in error message as if it is a wide char it will be unreadable
print the position of the illegal character
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/die_if_bad_username.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/libbb/die_if_bad_username.c b/libbb/die_if_bad_username.c index 9946e3a1d..cf1297bd6 100644 --- a/libbb/die_if_bad_username.c +++ b/libbb/die_if_bad_username.c | |||
| @@ -18,23 +18,45 @@ | |||
| 18 | 18 | ||
| 19 | void FAST_FUNC die_if_bad_username(const char *name) | 19 | void FAST_FUNC die_if_bad_username(const char *name) |
| 20 | { | 20 | { |
| 21 | /* 1st char being dash or dot isn't valid: */ | 21 | const char *start = name; |
| 22 | goto skip; | 22 | |
| 23 | /* For example, name like ".." can make adduser | 23 | /* 1st char being dash or dot isn't valid: |
| 24 | * chown "/home/.." recursively - NOT GOOD | 24 | * for example, name like ".." can make adduser |
| 25 | * chown "/home/.." recursively - NOT GOOD. | ||
| 26 | * Name of just a single "$" is also rejected. | ||
| 25 | */ | 27 | */ |
| 28 | goto skip; | ||
| 26 | 29 | ||
| 27 | do { | 30 | do { |
| 28 | if (*name == '-' || *name == '.') | 31 | unsigned char ch; |
| 32 | |||
| 33 | /* These chars are valid unless they are at the 1st pos: */ | ||
| 34 | if (*name == '-' | ||
| 35 | || *name == '.' | ||
| 36 | /* $ is allowed if it's the last char: */ | ||
| 37 | || (*name == '$' && !name[1]) | ||
| 38 | ) { | ||
| 29 | continue; | 39 | continue; |
| 40 | } | ||
| 30 | skip: | 41 | skip: |
| 31 | if (isalnum(*name) | 42 | ch = *name; |
| 32 | || *name == '_' | 43 | if (ch == '_' |
| 33 | || *name == '@' | 44 | /* || ch == '@' -- we disallow this too. Think about "user@host" */ |
| 34 | || (*name == '$' && !name[1]) | 45 | /* open-coded isalnum: */ |
| 46 | || (ch >= '0' && ch <= '9') | ||
| 47 | || ((ch|0x20) >= 'a' && (ch|0x20) <= 'z') | ||
| 35 | ) { | 48 | ) { |
| 36 | continue; | 49 | continue; |
| 37 | } | 50 | } |
| 38 | bb_error_msg_and_die("illegal character '%c'", *name); | 51 | bb_error_msg_and_die("illegal character with code %u at position %u", |
| 52 | (unsigned)ch, (unsigned)(name - start)); | ||
| 39 | } while (*++name); | 53 | } while (*++name); |
| 54 | |||
| 55 | /* The minimum size of the login name is one char or two if | ||
| 56 | * last char is the '$'. Violations of this are caught above. | ||
| 57 | * The maximum size of the login name is LOGIN_NAME_MAX | ||
| 58 | * including the terminating null byte. | ||
| 59 | */ | ||
| 60 | if (name - start >= LOGIN_NAME_MAX) | ||
| 61 | bb_error_msg_and_die("name is too long"); | ||
| 40 | } | 62 | } |
