summaryrefslogtreecommitdiff
path: root/ext/standard/crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/crypt.c')
-rw-r--r--ext/standard/crypt.c102
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