From f769cb435c4db2e7f6d11e14fe87a1c81e0912fe Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 23 May 2018 12:43:26 +0200 Subject: [PATCH 155/173] lslogins: fix password verification Let's follow the standard $id$salt$encrypted password format in verification code. The current code is useless and for example PWD-LOCK column is always FALSE. Upstream: http://github.com/karelzak/util-linux/commit/214fbec40abf0432b8e7968f05024ee76d11b3c7 Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1581611 Signed-off-by: Karel Zak --- login-utils/lslogins.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/login-utils/lslogins.c b/login-utils/lslogins.c index d7a24b1fb..041053625 100644 --- a/login-utils/lslogins.c +++ b/login-utils/lslogins.c @@ -541,14 +541,84 @@ static int get_nprocs(const uid_t uid) return nprocs; } +static const char *get_pwd_method(const char *str, const char **next, unsigned int *sz) +{ + const char *p = str; + const char *res = NULL; + + if (!p || *p++ != '$') + return NULL; + + if (sz) + *sz = 0; + + switch (*p) { + case '1': + res = "MD5"; + if (sz) + *sz = 22; + break; + case '2': + p++; + if (*p == 'a' || *p == 'y') + res = "Blowfish"; + break; + case '5': + res = "SHA-256"; + if (sz) + *sz = 43; + break; + case '6': + res = "SHA-512"; + if (sz) + *sz = 86; + break; + default: + return NULL; + } + p++; + + if (!*p || *p != '$') + return NULL; + if (next) + *next = ++p; + return res; +} + +#define is_valid_pwd_char(x) (isalnum((unsigned char) (x)) || (x) == '.' || (x) == '/') + static int valid_pwd(const char *str) { - const char *p; + const char *p = str; + unsigned int sz = 0, n; + + /* $id$ */ + if (get_pwd_method(str, &p, &sz) == NULL) + return 0; + if (!*p) + return 0; - for (p = str; p && *p; p++) - if (!isalnum((unsigned int) *p)) + /* salt$ */ + for (; p && *p; p++) { + if (*p == '$') { + p++; + break; + } + if (!is_valid_pwd_char(*p)) return 0; - return p > str ? 1 : 0; + } + if (!*p) + return 0; + + /* encrypted */ + for (n = 0; p && *p; p++, n++) { + if (!is_valid_pwd_char(*p)) + return 0; + } + + if (sz && n != sz) + return 0; + return 1; } static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const char *username) -- 2.14.4