f3b728d
From 86eed7ca01864b9fd17099e57f10f2b9b6b568a1 Mon Sep 17 00:00:00 2001
f3b728d
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
f3b728d
Date: Mon, 26 Nov 2018 22:33:17 +0100
f3b728d
Subject: [PATCH] pam_unix: Report unusable hashes found by checksalt to
f3b728d
 syslog.
f3b728d
f3b728d
libxcrypt can be build-time configured to support (or not support)
f3b728d
various hashing methods.  Future versions will also have support for
f3b728d
runtime configuration by the system's vendor and/or administrator.
f3b728d
f3b728d
For that reason adminstrator should be notified by pam if users cannot
f3b728d
log into their account anymore because of such a change in the system's
f3b728d
configuration of libxcrypt.
f3b728d
f3b728d
Also check for malformed hashes, like descrypt hashes starting with
f3b728d
"$2...", which might have been generated by unsafe base64 encoding
f3b728d
functions as used in glibc <= 2.16.
f3b728d
Such hashes are likely to be rejected by many recent implementations
f3b728d
of libcrypt.
f3b728d
f3b728d
* modules/pam_unix/passverify.c (verify_pwd_hash): Report unusable
f3b728d
hashes found by checksalt to syslog.
f3b728d
---
f3b728d
 modules/pam_unix/passverify.c | 36 +++++++++++++++++++++++++++++++++++
f3b728d
 1 file changed, 36 insertions(+)
f3b728d
f3b728d
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
f3b728d
index eb2444bb..2c808eb5 100644
f3b728d
--- a/modules/pam_unix/passverify.c
f3b728d
+++ b/modules/pam_unix/passverify.c
f3b728d
@@ -103,6 +103,42 @@ verify_pwd_hash(const char *p, char *hash, unsigned int nullok)
f3b728d
 			 * Ok, we don't know the crypt algorithm, but maybe
f3b728d
 			 * libcrypt knows about it? We should try it.
f3b728d
 			 */
f3b728d
+#if defined(CRYPT_CHECKSALT_AVAILABLE) && CRYPT_CHECKSALT_AVAILABLE
f3b728d
+			/* Get the status of the hash from checksalt */
f3b728d
+			int retval_checksalt = crypt_checksalt(hash);
f3b728d
+
f3b728d
+			/*
f3b728d
+			 * Check for hashing methods that are disabled by
f3b728d
+			 * libcrypt configuration and/or system preset.
f3b728d
+			 */
f3b728d
+			if (retval_checksalt == CRYPT_SALT_METHOD_DISABLED) {
f3b728d
+				/*
f3b728d
+				 * pam_syslog() needs a pam handle,
f3b728d
+				 * but that's not available here.
f3b728d
+				 */
f3b728d
+				helper_log_err(LOG_ERR,
f3b728d
+				  "pam_unix(verify_pwd_hash): The method "
f3b728d
+				  "for computing the hash \"%.6s\" has been "
f3b728d
+				  "disabled in libcrypt by the preset from "
f3b728d
+				  "the system's vendor and/or administrator.",
f3b728d
+				  hash);
f3b728d
+			}
f3b728d
+			/*
f3b728d
+			 * Check for malformed hashes, like descrypt hashes
f3b728d
+			 * starting with "$2...", which might have been
f3b728d
+			 * generated by unsafe base64 encoding functions
f3b728d
+			 * as used in glibc <= 2.16.
f3b728d
+			 * Such hashes are likely to be rejected by many
f3b728d
+			 * recent implementations of libcrypt.
f3b728d
+			 */
f3b728d
+			if (retval_checksalt == CRYPT_SALT_INVALID) {
f3b728d
+				helper_log_err(LOG_ERR,
f3b728d
+				  "pam_unix(verify_pwd_hash): The hash \"%.6s\""
f3b728d
+				  "does not use a method known by the version "
f3b728d
+				  "of libcrypt this system is supplied with.",
f3b728d
+				  hash);
f3b728d
+			}
f3b728d
+#endif
f3b728d
 #ifdef HAVE_CRYPT_R
f3b728d
 			struct crypt_data *cdata;
f3b728d
 			cdata = malloc(sizeof(*cdata));