From 57a1e2b274d0a6376d92ada9926e5c5741e7da20 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Fri, 24 Jan 2014 22:18:32 +0000 Subject: pam_userdb: fix password hash comparison Starting with commit Linux-PAM-0-77-28-g0b3e583 that introduced hashed passwords support in pam_userdb, hashes are compared case-insensitively. This bug leads to accepting hashes for completely different passwords in addition to those that should be accepted. Additionally, commit Linux-PAM-1_1_6-13-ge2a8187 that added support for modern password hashes with different lengths and settings, did not update the hash comparison accordingly, which leads to accepting computed hashes longer than stored hashes when the latter is a prefix of the former. * modules/pam_userdb/pam_userdb.c (user_lookup): Reject the computed hash whose length differs from the stored hash length. Compare computed and stored hashes case-sensitively. Fixes CVE-2013-7041. Bug-Debian: http://bugs.debian.org/731368 --- modules/pam_userdb/pam_userdb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'modules/pam_userdb/pam_userdb.c') diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c index de8b5b1e..ff040e6f 100644 --- a/modules/pam_userdb/pam_userdb.c +++ b/modules/pam_userdb/pam_userdb.c @@ -222,12 +222,15 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, } else { cryptpw = crypt (pass, data.dptr); - if (cryptpw) { - compare = strncasecmp (data.dptr, cryptpw, data.dsize); + if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) { + compare = memcmp(data.dptr, cryptpw, data.dsize); } else { compare = -2; if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_INFO, "crypt() returned NULL"); + if (cryptpw) + pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ"); + else + pam_syslog(pamh, LOG_INFO, "crypt() returned NULL"); } }; -- cgit v1.2.3 From 154c00e1a480d2bac7e8aba3b13888eb909f8e7f Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Fri, 24 Jan 2014 23:53:09 +0000 Subject: Fix gratuitous use of strdup and x_strdup There is no need to copy strings passed as arguments to execve, the only potentially noticeable effect of using strdup/x_strdup would be a malformed argument list in case of memory allocation error. Also, x_strdup, being a thin wrapper around strdup, is of no benefit when its argument is known to be non-NULL, and should not be used in such cases. * modules/pam_cracklib/pam_cracklib.c (password_check): Use strdup instead of x_strdup, the latter is of no benefit in this case. * modules/pam_ftp/pam_ftp.c (lookup): Likewise. * modules/pam_userdb/pam_userdb.c (user_lookup): Likewise. * modules/pam_userdb/pam_userdb.h (x_strdup): Remove. * modules/pam_mkhomedir/pam_mkhomedir.c (create_homedir): Do not use x_strdup for strings passed as arguments to execve. * modules/pam_unix/pam_unix_acct.c (_unix_run_verify_binary): Likewise. * modules/pam_unix/pam_unix_passwd.c (_unix_run_update_binary): Likewise. * modules/pam_unix/support.c (_unix_run_helper_binary): Likewise. (_unix_verify_password): Use strdup instead of x_strdup, the latter is of no benefit in this case. * modules/pam_xauth/pam_xauth.c (run_coprocess): Do not use strdup for strings passed as arguments to execv. --- modules/pam_userdb/pam_userdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/pam_userdb/pam_userdb.c') diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c index ff040e6f..ba36ebf2 100644 --- a/modules/pam_userdb/pam_userdb.c +++ b/modules/pam_userdb/pam_userdb.c @@ -184,7 +184,7 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, else key.dsize = strlen(key.dptr); } else { - key.dptr = x_strdup(user); + key.dptr = strdup(user); key.dsize = strlen(user); } -- cgit v1.2.3 From edcd6ce3a097c9b813909186dcb4accc35e604ef Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 7 Apr 2015 10:52:16 +0200 Subject: Use crypt_r if available in pam_userdb and in pam_unix. * modules/pam_unix/passverify.c (create_password_hash): Call crypt_r() instead of crypt() if available. * modules/pam_userdb/pam_userdb.c (user_lookup): Call crypt_r() instead of crypt() if available. --- modules/pam_userdb/pam_userdb.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'modules/pam_userdb/pam_userdb.c') diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c index ba36ebf2..8df1a40c 100644 --- a/modules/pam_userdb/pam_userdb.c +++ b/modules/pam_userdb/pam_userdb.c @@ -213,15 +213,23 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, /* crypt(3) password storage */ - char *cryptpw; + char *cryptpw = NULL; if (data.dsize < 13) { compare = -2; } else if (ctrl & PAM_ICASE_ARG) { compare = -2; } else { +#ifdef HAVE_CRYPT_R + struct crypt_data *cdata = NULL; + cdata = malloc(sizeof(*cdata)); + if (cdata != NULL) { + cdata->initialized = 0; + cryptpw = crypt_r(pass, data.dptr, cdata); + } +#else cryptpw = crypt (pass, data.dptr); - +#endif if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) { compare = memcmp(data.dptr, cryptpw, data.dsize); } else { @@ -232,9 +240,11 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, else pam_syslog(pamh, LOG_INFO, "crypt() returned NULL"); } - }; - - }; + } +#ifdef HAVE_CRYPT_R + free(cdata); +#endif + } } else { -- cgit v1.2.3 From a684595c0bbd88df71285f43fb27630e3829121e Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Tue, 29 Mar 2016 14:14:03 +0200 Subject: Remove "--enable-static-modules" option and support from Linux-PAM. It was never official supported and was broken since years. * configure.ac: Remove --enable-static-modules option. * doc/man/pam_sm_acct_mgmt.3.xml: Remove PAM_EXTERN. * doc/man/pam_sm_authenticate.3.xml: Likewise. * doc/man/pam_sm_chauthtok.3.xml: Likewise. * doc/man/pam_sm_close_session.3.xml: Likewise. * doc/man/pam_sm_open_session.3.xml: Likewise. * doc/man/pam_sm_setcred.3.xml: Likewise. * libpam/Makefile.am: Remove STATIC_MODULES cases. * libpam/include/security/pam_modules.h: Remove PAM_STATIC parts. * libpam/pam_dynamic.c: Likewise. * libpam/pam_handlers.c: Likewise. * libpam/pam_private.h: Likewise. * libpam/pam_static.c: Remove file. * libpam/pam_static_modules.h: Remove header file. * modules/pam_access/pam_access.c: Remove PAM_EXTERN and PAM_STATIC parts. * modules/pam_cracklib/pam_cracklib.c: Likewise. * modules/pam_debug/pam_debug.c: Likewise. * modules/pam_deny/pam_deny.c: Likewise. * modules/pam_echo/pam_echo.c: Likewise. * modules/pam_env/pam_env.c: Likewise. * modules/pam_exec/pam_exec.c: Likewise. * modules/pam_faildelay/pam_faildelay.c: Likewise. * modules/pam_filter/pam_filter.c: Likewise. * modules/pam_ftp/pam_ftp.c: Likewise. * modules/pam_group/pam_group.c: Likewise. * modules/pam_issue/pam_issue.c: Likewise. * modules/pam_keyinit/pam_keyinit.c: Likewise. * modules/pam_lastlog/pam_lastlog.c: Likewise. * modules/pam_limits/pam_limits.c: Likewise. * modules/pam_listfile/pam_listfile.c: Likewise. * modules/pam_localuser/pam_localuser.c: Likewise. * modules/pam_loginuid/pam_loginuid.c: Likewise. * modules/pam_mail/pam_mail.c: Likewise. * modules/pam_mkhomedir/pam_mkhomedir.c: Likewise. * modules/pam_motd/pam_motd.c: Likewise. * modules/pam_namespace/pam_namespace.c: Likewise. * modules/pam_nologin/pam_nologin.c: Likewise. * modules/pam_permit/pam_permit.c: Likewise. * modules/pam_pwhistory/pam_pwhistory.c: Likewise. * modules/pam_rhosts/pam_rhosts.c: Likewise. * modules/pam_rootok/pam_rootok.c: Likewise. * modules/pam_securetty/pam_securetty.c: Likewise. * modules/pam_selinux/pam_selinux.c: Likewise. * modules/pam_sepermit/pam_sepermit.c: Likewise. * modules/pam_shells/pam_shells.c: Likewise. * modules/pam_stress/pam_stress.c: Likewise. * modules/pam_succeed_if/pam_succeed_if.c: Likewise. * modules/pam_tally/pam_tally.c: Likewise. * modules/pam_tally2/pam_tally2.c: Likewise. * modules/pam_time/pam_time.c: Likewise. * modules/pam_timestamp/pam_timestamp.c: Likewise. * modules/pam_tty_audit/pam_tty_audit.c: Likewise. * modules/pam_umask/pam_umask.c: Likewise. * modules/pam_userdb/pam_userdb.c: Likewise. * modules/pam_warn/pam_warn.c: Likewise. * modules/pam_wheel/pam_wheel.c: Likewise. * modules/pam_xauth/pam_xauth.c: Likewise. * modules/pam_unix/Makefile.am: Remove STATIC_MODULES part. * modules/pam_unix/pam_unix_acct.c: Remove PAM_STATIC part. * modules/pam_unix/pam_unix_auth.c: Likewise. * modules/pam_unix/pam_unix_passwd.c: Likewise. * modules/pam_unix/pam_unix_sess.c: Likewise. * modules/pam_unix/pam_unix_static.c: Removed. * modules/pam_unix/pam_unix_static.h: Removed. * po/POTFILES.in: Remove removed files. * tests/tst-dlopen.c: Remove PAM_STATIC part. --- modules/pam_userdb/pam_userdb.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'modules/pam_userdb/pam_userdb.c') diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c index 8df1a40c..09ab8d33 100644 --- a/modules/pam_userdb/pam_userdb.c +++ b/modules/pam_userdb/pam_userdb.c @@ -334,7 +334,7 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, /* --- authentication management functions (only) --- */ -PAM_EXTERN int +int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { @@ -423,14 +423,14 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, return PAM_IGNORE; } -PAM_EXTERN int +int pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, int argc UNUSED, const char **argv UNUSED) { return PAM_SUCCESS; } -PAM_EXTERN int +int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { @@ -475,23 +475,6 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, return PAM_SUCCESS; } - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_userdb_modstruct = { - "pam_userdb", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif - /* * Copyright (c) Cristian Gafton , 1999 * All rights reserved -- cgit v1.2.3