From ed4052f1d5309cc974b134c2b78724d727ef9349 Mon Sep 17 00:00:00 2001 From: Anthony Ferrara Date: Thu, 21 May 2015 17:12:51 -0400 Subject: [PATCH] Fixed bug #69686 password_verify reports back error on PHP7 will null string. The deprecation of DES salts created a warning when trying to verify them with password_hash. This bug fix adds a quiet mode to php_crypt() which is used by password_verify. --- NEWS | 4 +++- ext/standard/crypt.c | 15 ++++++++++----- ext/standard/password.c | 4 ++-- ext/standard/php_crypt.h | 2 +- ext/standard/tests/password/password_verify.phpt | 10 ++++++++++ 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index 035cff9ed4466..162cdf9ff12e7 100644 --- a/NEWS +++ b/NEWS @@ -221,7 +221,9 @@ . Fixed bug #65272 (flock() out parameter not set correctly in windows). (Daniel Lowrey) . Added preg_replace_callback_array function. (Wei Dai) - . Deprecated salt option to password_hash. (Anthony) + . Deprecated salt option to password_hash. (Anthony) + . Fixed bug #69686 (password_verify reports back error on PHP7 will null + string). (Anthony) . Added Windows support for getrusage(). (Kalle) - Streams: diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index da51ee98858b1..74ab291f62e90 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -151,7 +151,7 @@ static void php_to64(char *s, zend_long v, int n) /* {{{ */ } /* }}} */ -PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const char *salt, int salt_len) +PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const char *salt, int salt_len, zend_bool quiet) { char *crypt_res; zend_string *result; @@ -225,7 +225,10 @@ PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const ch if (salt[0] != '_') { /* DES style hashes */ if (!IS_VALID_SALT_CHARACTER(salt[0]) || !IS_VALID_SALT_CHARACTER(salt[1])) { - php_error_docref(NULL, E_DEPRECATED, DES_INVALID_SALT_ERROR); + if (!quiet) { + /* error consistently about invalid DES fallbacks */ + php_error_docref(NULL, E_DEPRECATED, DES_INVALID_SALT_ERROR); + } } } @@ -254,8 +257,10 @@ PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const ch # error Data struct used by crypt_r() is unknown. Please report. # endif if (salt[0] != '$' && salt[0] != '_' && (!IS_VALID_SALT_CHARACTER(salt[0]) || !IS_VALID_SALT_CHARACTER(salt[1]))) { - /* error consistently about invalid DES fallbacks */ - php_error_docref(NULL, E_DEPRECATED, DES_INVALID_SALT_ERROR); + if (!quiet) { + /* error consistently about invalid DES fallbacks */ + php_error_docref(NULL, E_DEPRECATED, DES_INVALID_SALT_ERROR); + } } crypt_res = crypt_r(password, salt, &buffer); if (!crypt_res || (salt[0] == '*' && salt[1] == '0')) { @@ -313,7 +318,7 @@ PHP_FUNCTION(crypt) } salt[salt_in_len] = '\0'; - if ((result = php_crypt(str, (int)str_len, salt, (int)salt_in_len)) == NULL) { + if ((result = php_crypt(str, (int)str_len, salt, (int)salt_in_len, 0)) == NULL) { if (salt[0] == '*' && salt[1] == '0') { RETURN_STRING("*1"); } else { diff --git a/ext/standard/password.c b/ext/standard/password.c index 209e2533f8f8c..4ad955e018549 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -260,7 +260,7 @@ PHP_FUNCTION(password_verify) if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &password, &password_len, &hash, &hash_len) == FAILURE) { RETURN_FALSE; } - if ((ret = php_crypt(password, (int)password_len, hash, (int)hash_len)) == NULL) { + if ((ret = php_crypt(password, (int)password_len, hash, (int)hash_len, 1)) == NULL) { RETURN_FALSE; } @@ -415,7 +415,7 @@ PHP_FUNCTION(password_hash) /* This cast is safe, since both values are defined here in code and cannot overflow */ hash_len = (int) (hash_format_len + salt_len); - if ((result = php_crypt(password, (int)password_len, hash, hash_len)) == NULL) { + if ((result = php_crypt(password, (int)password_len, hash, hash_len, 1)) == NULL) { efree(hash); RETURN_FALSE; } diff --git a/ext/standard/php_crypt.h b/ext/standard/php_crypt.h index d77180bd0ba93..88368c966ff9a 100644 --- a/ext/standard/php_crypt.h +++ b/ext/standard/php_crypt.h @@ -23,7 +23,7 @@ #ifndef PHP_CRYPT_H #define PHP_CRYPT_H -PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const char *salt, int salt_len); +PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const char *salt, int salt_len, zend_bool quiet); PHP_FUNCTION(crypt); #if HAVE_CRYPT PHP_MINIT_FUNCTION(crypt); diff --git a/ext/standard/tests/password/password_verify.phpt b/ext/standard/tests/password/password_verify.phpt index e7ecc7edd3086..a196763c1362e 100644 --- a/ext/standard/tests/password/password_verify.phpt +++ b/ext/standard/tests/password/password_verify.phpt @@ -11,6 +11,13 @@ var_dump(password_verify("foo", '$2a$07$usesomesillystringforsalt$')); var_dump(password_verify('rasmusler', '$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi')); var_dump(password_verify('rasmuslerdorf', '$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi')); + +var_dump(password_verify("foo", null)); + +var_dump(password_verify("rasmuslerdorf", "rl.3StKT.4T8M")); + +var_dump(password_verify("foo", "$1")); + echo "OK!"; ?> --EXPECT-- @@ -18,4 +25,7 @@ bool(false) bool(false) bool(false) bool(true) +bool(false) +bool(true) +bool(false) OK!