From ad435b386b22b456724dc5c5b8d9f2d1beffc558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Thu, 15 Nov 2018 16:57:35 +0100 Subject: pam_unix: Add crypt_default method, if supported. libxcrypt since v4.4.0 supports a default method for its gensalt function on most system configurations. As the default method is to be considered the strongest available hash method, it should be preferred over all other hash methods supported by pam. * modules/pam_unix/pam_unix.8.xml: Documentation for crypt_default. * modules/pam_unix/passverify.c: Add crypt_default method. * modules/pam_unix/support.h: Likewise. --- modules/pam_unix/pam_unix.8.xml | 20 ++++++++++++++++++++ modules/pam_unix/passverify.c | 9 +++++++++ modules/pam_unix/support.h | 22 ++++++++++++---------- 3 files changed, 41 insertions(+), 10 deletions(-) (limited to 'modules/pam_unix') diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml index cae2aeaa..82e0c9af 100644 --- a/modules/pam_unix/pam_unix.8.xml +++ b/modules/pam_unix/pam_unix.8.xml @@ -361,6 +361,23 @@ + + + + + + + When a user changes their password next, + encrypt it with the default algorithm and the default + amount of rounds provided by the system configuration + of libcrypt. If this default algorithm is not known to + the + crypt3 + function, + fall back to MD5. + + + @@ -371,6 +388,9 @@ blowfish, gost-yescrypt, and yescrypt password hashing algorithms to n. + This option will be ignored when the crypt_default option + is used, as the default algorithm always uses the value + from the system configuration of libcrypt. diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index eb2444bb..0a4c67b4 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -395,6 +395,14 @@ PAMH_ARG_DECL(char * create_password_hash, if (on(UNIX_MD5_PASS, ctrl)) { /* algoid = "$1" */ return crypt_md5_wrapper(password); +#if (defined(CRYPT_PREFERRED_METHOD_AVAILABLE) && CRYPT_PREFERRED_METHOD_AVAILABLE) + } else if (on(UNIX_CRYPT_DEFAULT_PASS, ctrl) + && crypt_preferred_method() != NULL) { + algoid = crypt_preferred_method(); + rounds = 0; /* always use the system preset */ +#endif + } else if (on(UNIX_CRYPT_DEFAULT_PASS, ctrl)) { + algoid = "*0"; /* never ever a valid method */ } else if (on(UNIX_YESCRYPT_PASS, ctrl)) { algoid = "$y$"; } else if (on(UNIX_GOST_YESCRYPT_PASS, ctrl)) { @@ -461,6 +469,7 @@ PAMH_ARG_DECL(char * create_password_hash, pam_syslog(pamh, LOG_ERR, "Algo %s not supported by the crypto backend, " "falling back to MD5\n", + on(UNIX_CRYPT_DEFAULT_PASS, ctrl) ? "crypt_default \"" algoid "\"" : on(UNIX_YESCRYPT_PASS, ctrl) ? "yescrypt" : on(UNIX_GOST_YESCRYPT_PASS, ctrl) ? "gost_yescrypt" : on(UNIX_BLOWFISH_PASS, ctrl) ? "blowfish" : diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h index e02c05e0..60a5872d 100644 --- a/modules/pam_unix/support.h +++ b/modules/pam_unix/support.h @@ -100,10 +100,11 @@ typedef struct { #define UNIX_DES 30 /* DES, default */ #define UNIX_GOST_YESCRYPT_PASS 31 /* new password hashes will use gost-yescrypt */ #define UNIX_YESCRYPT_PASS 32 /* new password hashes will use yescrypt */ +#define UNIX_CRYPT_DEFAULT_PASS 33 /* new password hashes will use the libcrypt default */ /* -------------- */ -#define UNIX_CTRLS_ 33 /* number of ctrl arguments defined */ +#define UNIX_CTRLS_ 34 /* number of ctrl arguments defined */ -#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)&&off(UNIX_GOST_YESCRYPT_PASS,ctrl)&&off(UNIX_YESCRYPT_PASS,ctrl)) +#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)&&off(UNIX_GOST_YESCRYPT_PASS,ctrl)&&off(UNIX_YESCRYPT_PASS,ctrl)&&off(UNIX_CRYPT_DEFAULT_PASS,ctrl)) static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = { @@ -123,26 +124,27 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = /* UNIX__QUIET */ {NULL, _ALL_ON_, 02000, 0}, /* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000, 0}, /* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000, 0}, -/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(015660420000ULL), 020000, 1}, +/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(035660420000ULL), 020000, 1}, /* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000ULL), 0, 0}, /* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000, 0}, /* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000, 0}, /* UNIX_NIS */ {"nis", _ALL_ON_, 0200000, 0}, -/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(015660420000ULL), 0400000, 1}, +/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(035660420000ULL), 0400000, 1}, /* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000, 0}, /* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000, 0}, /* UNIX_NOREAP */ {"noreap", _ALL_ON_, 04000000, 0}, /* UNIX_BROKEN_SHADOW */ {"broken_shadow", _ALL_ON_, 010000000, 0}, -/* UNIX_SHA256_PASS */ {"sha256", _ALL_ON_^(015660420000ULL), 020000000, 1}, -/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(015660420000ULL), 040000000, 1}, +/* UNIX_SHA256_PASS */ {"sha256", _ALL_ON_^(035660420000ULL), 020000000, 1}, +/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(035660420000ULL), 040000000, 1}, /* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000, 0}, -/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(015660420000ULL), 0200000000, 1}, +/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(035660420000ULL), 0200000000, 1}, /* UNIX_MIN_PASS_LEN */ {"minlen=", _ALL_ON_, 0400000000, 0}, /* UNIX_QUIET */ {"quiet", _ALL_ON_, 01000000000, 0}, /* UNIX_NO_PASS_EXPIRY */ {"no_pass_expiry", _ALL_ON_, 02000000000, 0}, -/* UNIX_DES */ {"des", _ALL_ON_^(015660420000ULL), 0, 1}, -/* UNIX_GOST_YESCRYPT_PASS */ {"gost_yescrypt", _ALL_ON_^(015660420000ULL), 04000000000, 1}, -/* UNIX_YESCRYPT_PASS */ {"yescrypt", _ALL_ON_^(015660420000ULL), 010000000000, 1}, +/* UNIX_DES */ {"des", _ALL_ON_^(035660420000ULL), 0, 1}, +/* UNIX_GOST_YESCRYPT_PASS */ {"gost_yescrypt", _ALL_ON_^(035660420000ULL), 04000000000, 1}, +/* UNIX_YESCRYPT_PASS */ {"yescrypt", _ALL_ON_^(035660420000ULL), 010000000000, 1}, +/* UNIX_CRYPT_DEFAULT_PASS */ {"crypt_default", _ALL_ON_^(035660420000ULL), 020000000000, 1}, }; #define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) -- cgit v1.2.3