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