Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:GA
pam-modules
0004-add-workarounds-for-blowfish-signedness-bu...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0004-add-workarounds-for-blowfish-signedness-bug.diff of Package pam-modules
From 7a3e5fd2d79657674e72212ad13ea350d72e8306 Mon Sep 17 00:00:00 2001 From: Ludwig Nussel <ludwig.nussel@suse.de> Date: Wed, 13 Jul 2011 08:50:58 +0200 Subject: [PATCH 4/4] add workarounds for blowfish signedness bug The option BLOWFISH_2a2x allows to enable compat modes. --- configure.in | 18 +++++++++++++++++- etc/passwd | 16 ++++++++++++++++ src/get_options.c | 11 +++++++++++ src/public.h | 4 ++++ src/support.c | 30 ++++++++++++++++++++++++++++++ src/unix_auth.c | 8 +------- src/unix_passwd.c | 10 +++++++--- 7 files changed, 86 insertions(+), 11 deletions(-) diff --git a/configure.in b/configure.in index f4cdcd1..10c4e1f 100644 --- a/configure.in +++ b/configure.in @@ -48,13 +48,29 @@ dnl Should we compile with SELinux support? default: yes AC_ARG_ENABLE([selinux], AC_HELP_STRING([--disable-selinux],[Enable SELinux support (default=yes)]), WITH_SELINUX=$enableval, WITH_SELINUX=yes) -if test "$WITH_SELINUX" == "yes" ; then +if test "$WITH_SELINUX" = "yes" ; then AC_CHECK_LIB(selinux,is_selinux_enabled, [AC_DEFINE(WITH_SELINUX,1, [Define if you want to compile in SELinux support]) LIBS="$LIBS -lselinux"]) fi +AC_ARG_ENABLE([blowfish-bug-workaround], + AC_HELP_STRING([--disable-blowfish-bug-workaround],[Enable workarounds for blowfish signedness bug]), + CRYPT_BLOWFISH_SIGNEDNESS_BUG_WORKAROUNDS=$enableval, CRYPT_BLOWFISH_SIGNEDNESS_BUG_WORKAROUNDS=yes) +if test "$CRYPT_BLOWFISH_SIGNEDNESS_BUG_WORKAROUNDS" = "yes" ; then + AC_DEFINE(CRYPT_BLOWFISH_SIGNEDNESS_BUG_WORKAROUNDS,1, + [Define if you want to enable workarounds for blowfish signedness bug]) +fi + +AC_ARG_ENABLE([blowfish-bug-compatmode], + AC_HELP_STRING([--enable-blowfish-bug-compatmode],[Enable blowfish compat mode by default]), + CRYPT_BLOWFISH_COMPATMODE=$enableval, CRYPT_BLOWFISH_COMPATMODE=no) +if test "$CRYPT_BLOWFISH_COMPATMODE" = "yes" ; then + AC_DEFINE(CRYPT_BLOWFISH_COMPATMODE,1, + [Define if you want to enable blowfish compat mode by default]) +fi + dnl Check standard headers AC_HEADER_STDC AC_CHECK_HEADERS(crypt.h) diff --git a/etc/passwd b/etc/passwd index bd86963..ec6f0d4 100644 --- a/etc/passwd +++ b/etc/passwd @@ -36,3 +36,19 @@ CRYPT= # sha256/sha512: 1000-9999999 # SHA512_CRYPT_FILES=1000 +# In June 2011 it was discovered that the Linux crypt_blowfish +# implementation contained a bug that made passwords with non-ASCII +# characters easier to crack (CVE-2011-2483). Affected passwords are +# also incompatible with the original, correct OpenBSD +# implementation. Therefore the $2a hash identifier previously used +# for blowfish now is ambiguous as it could mean the hash was +# generated with the correct implementation on OpenBSD or the buggy +# one on Linux. To avoid the ambiguity two new identifier were +# introduced. $2x now explicitly identifies hashes that were +# generated with the buggy algorithm while $2y is used for hashes +# generated with the correct algorithm. New passwords are now +# generated with the $2y identifier. +# +# Setting the following option to "yes" tells the sytem that $2a +# hashes are to be treated as generated with the buggy algorithm. +BLOWFISH_2a2x= diff --git a/src/get_options.c b/src/get_options.c index faf8aa0..f899155 100644 --- a/src/get_options.c +++ b/src/get_options.c @@ -138,6 +138,17 @@ get_options (pam_handle_t *pamh, options_t *options, const char *type, /* Set some default values, which could be overwritten later. */ options->use_crypt = NONE; +#ifdef CRYPT_BLOWFISH_SIGNEDNESS_BUG_WORKAROUNDS + options->blowfish_2a2x = getlogindefs_bool("BLOWFISH_2a2x", +#ifdef CRYPT_BLOWFISH_COMPATMODE + 1 +#else + 0 +#endif + ); + free_getlogindefs_data(); +#endif + /* Parse parameters for module */ for ( ; argc-- > 0; argv++) parse_option (pamh, *argv, type, options); diff --git a/src/public.h b/src/public.h index 7200759..ec476b8 100644 --- a/src/public.h +++ b/src/public.h @@ -68,6 +68,7 @@ struct options_t { int nullok; int use_authtok; int use_first_pass; + int blowfish_2a2x; char **use_other_modules; char *nisdir; crypt_t use_crypt; @@ -86,6 +87,9 @@ extern int __call_other_module(pam_handle_t * pamh, int flags, const char *mod_name, const char *func_name, options_t *options); +extern int __check_password_match (const char *hash, const char *pass, + options_t *options); + extern int get_options (pam_handle_t *pamh, options_t *options, const char *type, int argc, const char **argv); diff --git a/src/support.c b/src/support.c index 6a1ce5e..b3b94c8 100644 --- a/src/support.c +++ b/src/support.c @@ -48,6 +48,11 @@ #include <security/pam_ext.h> #endif +#if defined(HAVE_CRYPT_H) +#define _OW_SOURCE +#include <crypt.h> +#endif + #include "public.h" int @@ -360,3 +365,28 @@ struct pam_module _pam_unix2_modstruct = pam_sm_chauthtok }; #endif + +int +__check_password_match (const char *hash, const char *pass, options_t *options) +{ + struct crypt_data output; + char *h = NULL; + int r; + + memset (&output, 0, sizeof (output)); + +#ifdef CRYPT_BLOWFISH_SIGNEDNESS_BUG_WORKAROUNDS + if ((options->blowfish_2a2x) + && !strncmp(hash, "$2a$", 4)) + { + h = strdupa(hash); + h[2] = 'x'; + hash = h; + } +#endif + + r = (strcmp (hash, crypt_r (pass, hash, &output)) == 0); + if (h) + _pam_overwrite(h); + return r; +} diff --git a/src/unix_auth.c b/src/unix_auth.c index e61c45e..e78c520 100644 --- a/src/unix_auth.c +++ b/src/unix_auth.c @@ -61,10 +61,6 @@ #include <security/pam_ext.h> #endif -#if defined(HAVE_CRYPT_H) -#include <crypt.h> -#endif - #include "public.h" @@ -124,7 +120,6 @@ int pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, const char **argv) { - struct crypt_data output; int retval; int sp_buflen = 256; char *sp_buffer = alloca (sp_buflen); @@ -141,7 +136,6 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, options_t options; int ask_user, ask_password; - memset (&output, 0, sizeof (output)); memset (&options, 0, sizeof (options)); if (get_options (pamh, &options, "auth", argc, argv) < 0) @@ -325,7 +319,7 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, *cp = '\0'; } - if (strcmp (crypt_r (password, salt, &output), salt) != 0) + if (!__check_password_match(salt, password, &options)) { if (options.debug) pam_syslog (pamh, LOG_DEBUG, "wrong password, return PAM_AUTH_ERR"); diff --git a/src/unix_passwd.c b/src/unix_passwd.c index 8491adf..e00615b 100644 --- a/src/unix_passwd.c +++ b/src/unix_passwd.c @@ -257,8 +257,7 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) /* Check if the old password was correct. */ if ((getuid () || (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) && - strcmp (data->oldpassword, - crypt_r (oldpass, data->oldpassword, &output)) != 0) + !__check_password_match(data->oldpassword, oldpass, &options)) { if (options.debug) pam_syslog (pamh, LOG_DEBUG, @@ -686,7 +685,12 @@ __do_setpass (pam_handle_t *pamh, int flags, user_t *data, case BLOWFISH: salt = make_crypt_salt ("$2a$", options->crypt_rounds, pamh, flags); if (salt != NULL) - newpassword = crypt_r (data->newpassword, salt, output); + { +#ifdef CRYPT_BLOWFISH_SIGNEDNESS_BUG_WORKAROUNDS + salt[2] = 'y'; +#endif + newpassword = crypt_r (data->newpassword, salt, output); + } else { __write_message (pamh, flags, PAM_ERROR_MSG, -- 1.7.3.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor