From f769cb435c4db2e7f6d11e14fe87a1c81e0912fe Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
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 <kzak@redhat.com>
---
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