From d74b5395ab7a61de8812c1281817484e8b87e8d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Tue, 8 Jun 2021 13:01:08 +0200 Subject: [PATCH] Add patches to add support for the yescrypt hash method --- libuser-0.63-PR49_add_yescrypt.patch | 260 ++++++++++++++++++++++ libuser-0.63-downstream_test_xcrypt.patch | 27 +++ libuser.spec | 10 +- 3 files changed, 295 insertions(+), 2 deletions(-) create mode 100644 libuser-0.63-PR49_add_yescrypt.patch create mode 100644 libuser-0.63-downstream_test_xcrypt.patch diff --git a/libuser-0.63-PR49_add_yescrypt.patch b/libuser-0.63-PR49_add_yescrypt.patch new file mode 100644 index 0000000..18a767d --- /dev/null +++ b/libuser-0.63-PR49_add_yescrypt.patch @@ -0,0 +1,260 @@ +From 3b8a2aa52bcee6e03f047840251ae42ab971a8a0 Mon Sep 17 00:00:00 2001 +From: Björn Esser +Date: Jun 07 2021 20:25:41 +0000 +Subject: [PATCH 1/5] lib/util.c: bcrypt should use $2b$ as prefix for setting. + + +This prefix is the recommended one for new bcrypt hashes +for a long time. + +Signed-off-by: Björn Esser + +--- + +diff --git a/lib/util.c b/lib/util.c +index 1b03f7d..e549a35 100644 +--- a/lib/util.c ++++ b/lib/util.c +@@ -124,7 +124,7 @@ static const struct { + } salt_type_info[] = { + {"$1$", "$", 8, FALSE }, + /* FIXME: number of rounds, base64 of 128 bits */ +- {"$2a$", "$", 8, FALSE }, ++ {"$2b$", "$", 8, FALSE }, + {"$5$", "$", 16, TRUE }, + {"$6$", "$", 16, TRUE }, + { "", "", 2 }, +@@ -231,7 +231,7 @@ lu_util_default_salt_specifier(struct lu_context *context) + } salt_types[] = { + { "des", "", FALSE }, + { "md5", "$1$", FALSE }, +- { "blowfish", "$2a$", FALSE }, ++ { "blowfish", "$2b$", FALSE }, + { "sha256", "$5$", TRUE }, + { "sha512", "$6$", TRUE }, + }; + +From 9dcc69425677cf510ec6da5ababfdd295f875c1a Mon Sep 17 00:00:00 2001 +From: Björn Esser +Date: Jun 17 2021 15:34:02 +0000 +Subject: [PATCH 2/5] lib/util.c: Use crypt_gensalt(), if available in libcrypt. + + +Most Linux distributions, including Fedora and RHEL 8, are shipping +with libxcrypt >= 4.0. + +Since that version of libxcrypt the provided family of crypt_gensalt() +functions are able to use automatic entropy drawn from secure system +ressources, like arc4random(), getentropy() or getrandom(). + +Anyways, the settings generated by crypt_gensalt() are always +guaranteed to works with the crypt() function. + +Using crypt_gesalt() is also needed to make proper use of newer +hashing methods, like yescrypt, provided by libxcrypt. + +Signed-off-by: Björn Esser + +--- + +diff --git a/lib/util.c b/lib/util.c +index e549a35..b6db2af 100644 +--- a/lib/util.c ++++ b/lib/util.c +@@ -43,6 +43,13 @@ + #define HASH_ROUNDS_MIN 1000 + #define HASH_ROUNDS_MAX 999999999 + ++#if (defined CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY && \ ++ CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY) ++#define USE_XCRYPT_GENSALT 1 ++#else ++#define USE_XCRYPT_GENSALT 0 ++#endif ++ + struct lu_lock { + int fd; + struct flock lock; +@@ -66,6 +73,7 @@ lu_strcmp(gconstpointer v1, gconstpointer v2) + return strcmp((char *) v1, (char *) v2); + } + ++#if !USE_XCRYPT_GENSALT + /* A list of allowed salt characters, according to SUSv2. */ + #define ACCEPTABLE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "abcdefghijklmnopqrstuvwxyz" \ +@@ -115,6 +123,7 @@ fill_urandom(char *output, size_t length) + close(fd); + return TRUE; + } ++#endif + + static const struct { + const char initial[5]; +@@ -135,6 +144,9 @@ lu_make_crypted(const char *plain, const char *previous) + { + char salt[2048]; + size_t i, len = 0; ++#if USE_XCRYPT_GENSALT ++ unsigned long rounds = 0; ++#endif + + if (previous == NULL) { + previous = LU_DEFAULT_SALT_TYPE; +@@ -151,6 +163,23 @@ lu_make_crypted(const char *plain, const char *previous) + + if (salt_type_info[i].sha_rounds != FALSE + && strncmp(previous + len, "rounds=", strlen("rounds=")) == 0) { ++#if USE_XCRYPT_GENSALT ++ const char *start; ++ char *end; ++ ++ start = previous + len + strlen("rounds="); ++ rounds = strtoul (start, &end, 10); ++ ++ if (rounds < HASH_ROUNDS_MIN) ++ rounds = HASH_ROUNDS_MIN; ++ else if (rounds > HASH_ROUNDS_MAX) ++ rounds = HASH_ROUNDS_MAX; ++ } ++ ++ g_assert(CRYPT_GENSALT_OUTPUT_SIZE <= sizeof(salt)); ++ ++ crypt_gensalt_rn(previous, rounds, NULL, 0, salt, sizeof(salt)); ++#else + const char *start, *end; + + start = previous + len + strlen("rounds="); +@@ -168,6 +197,7 @@ lu_make_crypted(const char *plain, const char *previous) + return NULL; + strcpy(salt + len + salt_type_info[i].salt_length, + salt_type_info[i].separator); ++#endif + + return crypt(plain, salt); + } +@@ -251,13 +281,18 @@ lu_util_default_salt_specifier(struct lu_context *context) + + found: + if (salt_types[i].sha_rounds != FALSE) { +- unsigned long rounds; ++ unsigned long rounds = 0; + + rounds = select_hash_rounds(context); ++#if USE_XCRYPT_GENSALT ++ return g_strdup(crypt_gensalt(salt_types[i].initializer, ++ rounds, NULL, 0)); ++#else + if (rounds != 0) + return g_strdup_printf("%srounds=%lu$", + salt_types[i].initializer, + rounds); ++#endif + } + return g_strdup(salt_types[i].initializer); + } + +From 2d40503977df3855f1415db995833ae4231e7944 Mon Sep 17 00:00:00 2001 +From: Björn Esser +Date: Jun 17 2021 15:34:02 +0000 +Subject: [PATCH 3/5] lib/util.c: Add yescrypt hashing method for user passwords. + + +The yescrypt hashing method is considered to be much stronger than +sha512crypt and fully supported by libxcrypt >= 4.3. It is based +on NIST-approved primitives and on par with argon2 in strength. + +Signed-off-by: Björn Esser + +--- + +diff --git a/lib/util.c b/lib/util.c +index b6db2af..bba9420 100644 +--- a/lib/util.c ++++ b/lib/util.c +@@ -50,6 +50,14 @@ + #define USE_XCRYPT_GENSALT 0 + #endif + ++#if ((defined XCRYPT_VERSION_NUM && \ ++ XCRYPT_VERSION_NUM >= ((4 << 16) | 3)) && \ ++ USE_XCRYPT_GENSALT) ++#define HAVE_YESCRYPT 1 ++#else ++#define HAVE_YESCRYPT 0 ++#endif ++ + struct lu_lock { + int fd; + struct flock lock; +@@ -136,6 +144,9 @@ static const struct { + {"$2b$", "$", 8, FALSE }, + {"$5$", "$", 16, TRUE }, + {"$6$", "$", 16, TRUE }, ++#if HAVE_YESCRYPT ++ {"$y$", "$", 24, FALSE }, ++#endif + { "", "", 2 }, + }; + +@@ -264,6 +275,9 @@ lu_util_default_salt_specifier(struct lu_context *context) + { "blowfish", "$2b$", FALSE }, + { "sha256", "$5$", TRUE }, + { "sha512", "$6$", TRUE }, ++#if HAVE_YESCRYPT ++ { "yescrypt", "$y$", FALSE }, ++#endif + }; + + const char *salt_type; + +From 71ef71fe1878a321612e1995cb5c59dcb501ff01 Mon Sep 17 00:00:00 2001 +From: Björn Esser +Date: Jun 17 2021 15:34:02 +0000 +Subject: [PATCH 4/5] docs/libuser.conf.5.in: Add yescrypt parameter for crypt_style. + + +Signed-off-by: Björn Esser + +--- + +diff --git a/docs/libuser.conf.5.in b/docs/libuser.conf.5.in +index 2af0828..bd1daa7 100644 +--- a/docs/libuser.conf.5.in ++++ b/docs/libuser.conf.5.in +@@ -69,8 +69,8 @@ The current algorithm may be retained + when changing a password of an existing user, depending on the application. + + Possible values are \fBdes\fR, \fBmd5\fR, \fBblowfish\fR, +-.B sha256 +-and \fBsha512\fR, all case-insensitive. ++.B sha256, ++\fBsha512\fR, and \fByescrypt\fR, all case-insensitive. + Unrecognized values are treated as \fBdes\fR. + Default value is \fBdes\fR. + + +From 284b3195393688105b112b905069e0225c3046d2 Mon Sep 17 00:00:00 2001 +From: Björn Esser +Date: Jun 17 2021 15:34:02 +0000 +Subject: [PATCH 5/5] libuser.conf: Use yescrypt as default value for crypt_style. + + +Signed-off-by: Björn Esser + +--- + +diff --git a/libuser.conf b/libuser.conf +index 8ff5b2e..cd25eb2 100644 +--- a/libuser.conf ++++ b/libuser.conf +@@ -17,7 +17,7 @@ default_useradd = /etc/default/useradd + # skeleton = /etc/skel + # mailspooldir = /var/mail + +-crypt_style = sha512 ++crypt_style = yescrypt + modules = files shadow + create_modules = files shadow + # modules = files shadow ldap + diff --git a/libuser-0.63-downstream_test_xcrypt.patch b/libuser-0.63-downstream_test_xcrypt.patch new file mode 100644 index 0000000..8375740 --- /dev/null +++ b/libuser-0.63-downstream_test_xcrypt.patch @@ -0,0 +1,27 @@ +diff --git a/tests/pwhash_test b/tests/pwhash_test +index ff89d60..525885e 100755 +--- a/tests/pwhash_test ++++ b/tests/pwhash_test +@@ -77,6 +77,22 @@ if [ "x${pw#\$6\$}" = "x$pw" ]; then + exit 1 + fi + ++cp "${LIBUSER_CONF}_" "$LIBUSER_CONF" ++echo 'crypt_style = blowfish' >> "$LIBUSER_CONF" ++pw=$(workdir="$workdir" $VALGRIND $PYTHON "$srcdir"/pwhash.py) ++if [ "x${pw#\$2b\$}" = "x$pw" ]; then ++ echo "Invalid BLOWFISH hash" >&2 ++ exit 1 ++fi ++ ++cp "${LIBUSER_CONF}_" "$LIBUSER_CONF" ++echo 'crypt_style = yescrypt' >> "$LIBUSER_CONF" ++pw=$(workdir="$workdir" $VALGRIND $PYTHON "$srcdir"/pwhash.py) ++if [ "x${pw#\$y\$}" = "x$pw" ]; then ++ echo "Invalid YESCRYPT hash" >&2 ++ exit 1 ++fi ++ + cp "${LIBUSER_CONF}_" "$LIBUSER_CONF" + cat >> "$LIBUSER_CONF" <<\EOF + crypt_style = sha256 diff --git a/libuser.spec b/libuser.spec index 476184d..8fb2eb5 100644 --- a/libuser.spec +++ b/libuser.spec @@ -1,6 +1,6 @@ Name: libuser Version: 0.63 -Release: 5%{?dist} +Release: 6%{?dist} License: LGPLv2+ URL: https://pagure.io/libuser Source: https://releases.pagure.org/libuser/libuser-%{version}.tar.xz @@ -29,6 +29,9 @@ BuildRequires: audit-libs-devel Summary: A user and group account administration library +Patch0: %{url}/pull-request/49.patch#/libuser-0.63-PR49_add_yescrypt.patch +Patch1: libuser-0.63-downstream_test_xcrypt.patch + %global __provides_exclude_from ^(%{_libdir}/%{name}|%{python3_sitearch})/.*$ %description @@ -62,7 +65,7 @@ the libuser library, which provides a Python 3 API for manipulating and administering user and group accounts. %prep -%setup -qn libuser-%{version} +%autosetup -p 1 %build ./autogen.sh @@ -118,6 +121,9 @@ make %{_datadir}/gtk-doc/html/* %changelog +* Tue Jun 15 2021 Björn Esser - 0.63-6 +- Add patches to add support for the yescrypt hash method + * Tue Jun 15 2021 Björn Esser - 0.63-5 - Fix renaming of the python package (#1964587)