cdown / rpms / util-linux

Forked from rpms/util-linux 2 years ago
Clone
Blob Blame History Raw
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