diff options
Diffstat (limited to 'ext/standard/crypt.c')
| -rw-r--r-- | ext/standard/crypt.c | 102 |
1 files changed, 93 insertions, 9 deletions
diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index 3743e1eb9..b4a5167b9 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | + | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -15,10 +15,11 @@ | Authors: Stig Bakken <ssb@php.net> | | Zeev Suraski <zeev@zend.com> | | Rasmus Lerdorf <rasmus@php.net> | + | Pierre Joye <pierre@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: crypt.c 272370 2008-12-31 11:15:49Z sebastian $ */ +/* $Id: crypt.c 295421 2010-02-23 17:49:00Z pajoye $ */ #include <stdlib.h> @@ -82,6 +83,12 @@ #define PHP_MAX_SALT_LEN 60 #endif +#if PHP_SHA512_CRYPT +#undef PHP_MAX_SALT_LEN +#define PHP_MAX_SALT_LEN 123 +#endif + + /* If the configure-time checks fail, we provide DES. * XXX: This is a hack. Fix the real problem! */ @@ -100,6 +107,9 @@ PHP_MINIT_FUNCTION(crypt) /* {{{ */ REGISTER_LONG_CONSTANT("CRYPT_EXT_DES", PHP_EXT_DES_CRYPT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CRYPT_MD5", PHP_MD5_CRYPT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CRYPT_BLOWFISH", PHP_BLOWFISH_CRYPT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("CRYPT_SHA256", PHP_SHA256_CRYPT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("CRYPT_SHA512", PHP_SHA512_CRYPT, CONST_CS | CONST_PERSISTENT); + #ifdef PHP_USE_PHP_CRYPT_R php_init_crypt_r(); @@ -137,7 +147,7 @@ PHP_FUNCTION(crypt) char salt[PHP_MAX_SALT_LEN + 1]; char *str, *salt_in = NULL; int str_len, salt_in_len = 0; - + char *crypt_res; salt[0] = salt[PHP_MAX_SALT_LEN] = '\0'; /* This will produce suitable results if people depend on DES-encryption @@ -163,6 +173,7 @@ PHP_FUNCTION(crypt) php_to64(&salt[0], PHP_CRYPT_RAND, 2); salt[2] = '\0'; #endif + salt_in_len = strlen(salt); } /* Windows (win32/crypt) has a stripped down version of libxcrypt and @@ -175,7 +186,53 @@ PHP_FUNCTION(crypt) char output[MD5_HASH_MAX_LEN]; RETURN_STRING(php_md5_crypt_r(str, salt, output), 1); - } else if ( + } else if (salt[0]=='$' && salt[1]=='6' && salt[2]=='$') { + const char sha512_salt_prefix[] = "$6$"; + const char sha512_rounds_prefix[] = "rounds="; + char *output; + int needed = (sizeof(sha512_salt_prefix) - 1 + + sizeof(sha512_rounds_prefix) + 9 + 1 + + strlen(salt) + 1 + 43 + 1); + output = emalloc(needed * sizeof(char *)); + salt[salt_in_len] = '\0'; + + crypt_res = php_sha512_crypt_r(str, salt, output, needed); + if (!crypt_res) { + if (salt[0]=='*' && salt[1]=='0') { + RETVAL_STRING("*1", 1); + } else { + RETVAL_STRING("*0", 1); + } + } else { + RETVAL_STRING(output, 1); + } + + memset(output, 0, PHP_MAX_SALT_LEN + 1); + efree(output); + } else if (salt[0]=='$' && salt[1]=='5' && salt[2]=='$') { + const char sha256_salt_prefix[] = "$5$"; + const char sha256_rounds_prefix[] = "rounds="; + char *output; + int needed = (sizeof(sha256_salt_prefix) - 1 + + sizeof(sha256_rounds_prefix) + 9 + 1 + + strlen(salt) + 1 + 43 + 1); + output = emalloc(needed * sizeof(char *)); + salt[salt_in_len] = '\0'; + + crypt_res = php_sha256_crypt_r(str, salt, output, needed); + if (!crypt_res) { + if (salt[0]=='*' && salt[1]=='0') { + RETVAL_STRING("*1", 1); + } else { + RETVAL_STRING("*0", 1); + } + } else { + RETVAL_STRING(output, 1); + } + + memset(output, 0, PHP_MAX_SALT_LEN + 1); + efree(output); + } else if ( salt[0] == '$' && salt[1] == '2' && salt[2] == 'a' && @@ -186,14 +243,33 @@ PHP_FUNCTION(crypt) char output[PHP_MAX_SALT_LEN + 1]; memset(output, 0, PHP_MAX_SALT_LEN + 1); - php_crypt_blowfish_rn(str, salt, output, sizeof(output)); - RETVAL_STRING(output, 1); + crypt_res = php_crypt_blowfish_rn(str, salt, output, sizeof(output)); + if (!crypt_res) { + if (salt[0]=='*' && salt[1]=='0') { + RETVAL_STRING("*1", 1); + } else { + RETVAL_STRING("*0", 1); + } + } else { + RETVAL_STRING(output, 1); + } + memset(output, 0, PHP_MAX_SALT_LEN + 1); } else { memset(&buffer, 0, sizeof(buffer)); _crypt_extended_init_r(); - RETURN_STRING(_crypt_extended_r(str, salt, &buffer), 1); + + crypt_res = _crypt_extended_r(str, salt, &buffer); + if (!crypt_res) { + if (salt[0]=='*' && salt[1]=='0') { + RETURN_STRING("*1", 1); + } else { + RETURN_STRING("*0", 1); + } + } else { + RETURN_STRING(crypt_res, 1); + } } } #else @@ -208,8 +284,16 @@ PHP_FUNCTION(crypt) # else # error Data struct used by crypt_r() is unknown. Please report. # endif - - RETURN_STRING(crypt_r(str, salt, &buffer), 1); + crypt_res = crypt_r(str, salt, &buffer); + if (!crypt_res) { + if (salt[0]=='*' && salt[1]=='0') { + RETURN_STRING("*1", 1); + } else { + RETURN_STRING("*0", 1); + } + } else { + RETURN_STRING(crypt_res, 1); + } } # endif #endif |
