added password_compat for PHP >=5.3 <5.5
This commit is contained in:
parent
d7dbaf52d4
commit
adb01c4d0e
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"firebase/php-jwt": "^5.0"
|
"firebase/php-jwt": "^5.0",
|
||||||
|
"ircmaxell/password-compat": "^1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"_readme": [
|
"_readme": [
|
||||||
"This file locks the dependencies of your project to a known state",
|
"This file locks the dependencies of your project to a known state",
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "7f97fc9c4d2beaf06d019ba50f7efcbc",
|
"content-hash": "5759823f1f047089a354efaa25903378",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "firebase/php-jwt",
|
"name": "firebase/php-jwt",
|
||||||
|
@ -51,6 +51,48 @@
|
||||||
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
||||||
"homepage": "https://github.com/firebase/php-jwt",
|
"homepage": "https://github.com/firebase/php-jwt",
|
||||||
"time": "2017-06-27T22:17:23+00:00"
|
"time": "2017-06-27T22:17:23+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ircmaxell/password-compat",
|
||||||
|
"version": "v1.0.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ircmaxell/password_compat.git",
|
||||||
|
"reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c",
|
||||||
|
"reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "4.*"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"lib/password.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Anthony Ferrara",
|
||||||
|
"email": "ircmaxell@php.net",
|
||||||
|
"homepage": "http://blog.ircmaxell.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
|
||||||
|
"homepage": "https://github.com/ircmaxell/password_compat",
|
||||||
|
"keywords": [
|
||||||
|
"hashing",
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"time": "2014-11-20T16:49:30+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [],
|
"packages-dev": [],
|
||||||
|
|
|
@ -67,7 +67,7 @@ if ( $action == 'user' ) {
|
||||||
$pass_hash = '"'.password_hash($pass, PASSWORD_BCRYPT).'"';
|
$pass_hash = '"'.password_hash($pass, PASSWORD_BCRYPT).'"';
|
||||||
} else {
|
} else {
|
||||||
$pass_hash = ' PASSWORD('.dbEscape($_REQUEST['newUser']['Password']).') ';
|
$pass_hash = ' PASSWORD('.dbEscape($_REQUEST['newUser']['Password']).') ';
|
||||||
ZM\Info ('Cannot use bcrypt as you are using PHP < 5.5');
|
ZM\Info ('Cannot use bcrypt as you are using PHP < 5.3');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,8 @@ function migrateHash($user, $pass) {
|
||||||
dbQuery($update_password_sql);
|
dbQuery($update_password_sql);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Not really an error, so an info
|
|
||||||
// there is also a compat library https://github.com/ircmaxell/password_compat
|
ZM\Info ('Cannot migrate password scheme to bcrypt, as you are using PHP < 5.3');
|
||||||
// not sure if its worth it. Do a lot of people really use PHP < 5.5?
|
|
||||||
ZM\Info ('Cannot migrate password scheme to bcrypt, as you are using PHP < 5.5');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -377,7 +377,7 @@ foreach ( array_map('basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
||||||
foreach( dbFetchAll($sql) as $row ) {
|
foreach( dbFetchAll($sql) as $row ) {
|
||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="colUsername"><?php echo $row['Id']." ".validHtmlStr($row['Username']) ?></td>
|
<td class="colUsername"><?php echo validHtmlStr($row['Username']) ?></td>
|
||||||
<td class="colMark"><input type="checkbox" name="tokenUids[]" value="<?php echo $row['Id'] ?>" /></td>
|
<td class="colMark"><input type="checkbox" name="tokenUids[]" value="<?php echo $row['Id'] ?>" /></td>
|
||||||
<td class="colMark"><input type="checkbox" name="apiUids[]" value="<?php echo $row['Id']?>" <?php echo $row['APIEnabled']?'checked':''?> /></td>
|
<td class="colMark"><input type="checkbox" name="apiUids[]" value="<?php echo $row['Id']?>" <?php echo $row['APIEnabled']?'checked':''?> /></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -279,7 +279,7 @@ class ClassLoader
|
||||||
*/
|
*/
|
||||||
public function setApcuPrefix($apcuPrefix)
|
public function setApcuPrefix($apcuPrefix)
|
||||||
{
|
{
|
||||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,16 +1,52 @@
|
||||||
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: Composer
|
||||||
|
Upstream-Contact: Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
Source: https://github.com/composer/composer
|
||||||
|
|
||||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
Files: *
|
||||||
|
Copyright: 2016, Nils Adermann <naderman@naderman.de>
|
||||||
|
2016, Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
License: Expat
|
||||||
|
|
||||||
|
Files: src/Composer/Util/TlsHelper.php
|
||||||
|
Copyright: 2016, Nils Adermann <naderman@naderman.de>
|
||||||
|
2016, Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
2013, Evan Coury <me@evancoury.com>
|
||||||
|
License: Expat and BSD-2-Clause
|
||||||
|
|
||||||
|
License: BSD-2-Clause
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
.
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
.
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
License: Expat
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is furnished
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
to do so, subject to the following conditions:
|
to do so, subject to the following conditions:
|
||||||
|
.
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
.
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
@ -18,4 +54,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_files.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'e40631d46120a9c38ea139981f8dab26' => $vendorDir . '/ircmaxell/password-compat/lib/password.php',
|
||||||
|
);
|
|
@ -47,6 +47,24 @@ class ComposerAutoloaderInit254e25e69fe049d603f41f5fd853ef2b
|
||||||
|
|
||||||
$loader->register(true);
|
$loader->register(true);
|
||||||
|
|
||||||
|
if ($useStaticLoader) {
|
||||||
|
$includeFiles = Composer\Autoload\ComposerStaticInit254e25e69fe049d603f41f5fd853ef2b::$files;
|
||||||
|
} else {
|
||||||
|
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||||
|
}
|
||||||
|
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||||
|
composerRequire254e25e69fe049d603f41f5fd853ef2b($fileIdentifier, $file);
|
||||||
|
}
|
||||||
|
|
||||||
return $loader;
|
return $loader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function composerRequire254e25e69fe049d603f41f5fd853ef2b($fileIdentifier, $file)
|
||||||
|
{
|
||||||
|
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||||
|
require $file;
|
||||||
|
|
||||||
|
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@ namespace Composer\Autoload;
|
||||||
|
|
||||||
class ComposerStaticInit254e25e69fe049d603f41f5fd853ef2b
|
class ComposerStaticInit254e25e69fe049d603f41f5fd853ef2b
|
||||||
{
|
{
|
||||||
|
public static $files = array (
|
||||||
|
'e40631d46120a9c38ea139981f8dab26' => __DIR__ . '/..' . '/ircmaxell/password-compat/lib/password.php',
|
||||||
|
);
|
||||||
|
|
||||||
public static $prefixLengthsPsr4 = array (
|
public static $prefixLengthsPsr4 = array (
|
||||||
'F' =>
|
'F' =>
|
||||||
array (
|
array (
|
||||||
|
|
|
@ -46,5 +46,49 @@
|
||||||
],
|
],
|
||||||
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
||||||
"homepage": "https://github.com/firebase/php-jwt"
|
"homepage": "https://github.com/firebase/php-jwt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ircmaxell/password-compat",
|
||||||
|
"version": "v1.0.4",
|
||||||
|
"version_normalized": "1.0.4.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ircmaxell/password_compat.git",
|
||||||
|
"reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c",
|
||||||
|
"reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "4.*"
|
||||||
|
},
|
||||||
|
"time": "2014-11-20T16:49:30+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"lib/password.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Anthony Ferrara",
|
||||||
|
"email": "ircmaxell@php.net",
|
||||||
|
"homepage": "http://blog.ircmaxell.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
|
||||||
|
"homepage": "https://github.com/ircmaxell/password_compat",
|
||||||
|
"keywords": [
|
||||||
|
"hashing",
|
||||||
|
"password"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
Copyright (c) 2012 Anthony Ferrara
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"name": "ircmaxell/password-compat",
|
||||||
|
"description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
|
||||||
|
"keywords": ["password", "hashing"],
|
||||||
|
"homepage": "https://github.com/ircmaxell/password_compat",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Anthony Ferrara",
|
||||||
|
"email": "ircmaxell@php.net",
|
||||||
|
"homepage": "http://blog.ircmaxell.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "4.*"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": ["lib/password.php"]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,314 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* A Compatibility library with PHP 5.5's simplified password hashing API.
|
||||||
|
*
|
||||||
|
* @author Anthony Ferrara <ircmaxell@php.net>
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
|
* @copyright 2012 The Authors
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
if (!defined('PASSWORD_BCRYPT')) {
|
||||||
|
/**
|
||||||
|
* PHPUnit Process isolation caches constants, but not function declarations.
|
||||||
|
* So we need to check if the constants are defined separately from
|
||||||
|
* the functions to enable supporting process isolation in userland
|
||||||
|
* code.
|
||||||
|
*/
|
||||||
|
define('PASSWORD_BCRYPT', 1);
|
||||||
|
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
|
||||||
|
define('PASSWORD_BCRYPT_DEFAULT_COST', 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('password_hash')) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash the password using the specified algorithm
|
||||||
|
*
|
||||||
|
* @param string $password The password to hash
|
||||||
|
* @param int $algo The algorithm to use (Defined by PASSWORD_* constants)
|
||||||
|
* @param array $options The options for the algorithm to use
|
||||||
|
*
|
||||||
|
* @return string|false The hashed password, or false on error.
|
||||||
|
*/
|
||||||
|
function password_hash($password, $algo, array $options = array()) {
|
||||||
|
if (!function_exists('crypt')) {
|
||||||
|
trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (is_null($password) || is_int($password)) {
|
||||||
|
$password = (string) $password;
|
||||||
|
}
|
||||||
|
if (!is_string($password)) {
|
||||||
|
trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!is_int($algo)) {
|
||||||
|
trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$resultLength = 0;
|
||||||
|
switch ($algo) {
|
||||||
|
case PASSWORD_BCRYPT:
|
||||||
|
$cost = PASSWORD_BCRYPT_DEFAULT_COST;
|
||||||
|
if (isset($options['cost'])) {
|
||||||
|
$cost = $options['cost'];
|
||||||
|
if ($cost < 4 || $cost > 31) {
|
||||||
|
trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The length of salt to generate
|
||||||
|
$raw_salt_len = 16;
|
||||||
|
// The length required in the final serialization
|
||||||
|
$required_salt_len = 22;
|
||||||
|
$hash_format = sprintf("$2y$%02d$", $cost);
|
||||||
|
// The expected length of the final crypt() output
|
||||||
|
$resultLength = 60;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$salt_requires_encoding = false;
|
||||||
|
if (isset($options['salt'])) {
|
||||||
|
switch (gettype($options['salt'])) {
|
||||||
|
case 'NULL':
|
||||||
|
case 'boolean':
|
||||||
|
case 'integer':
|
||||||
|
case 'double':
|
||||||
|
case 'string':
|
||||||
|
$salt = (string) $options['salt'];
|
||||||
|
break;
|
||||||
|
case 'object':
|
||||||
|
if (method_exists($options['salt'], '__tostring')) {
|
||||||
|
$salt = (string) $options['salt'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'array':
|
||||||
|
case 'resource':
|
||||||
|
default:
|
||||||
|
trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) {
|
||||||
|
trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING);
|
||||||
|
return null;
|
||||||
|
} elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
|
||||||
|
$salt_requires_encoding = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$buffer = '';
|
||||||
|
$buffer_valid = false;
|
||||||
|
if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
|
||||||
|
$buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
|
||||||
|
if ($buffer) {
|
||||||
|
$buffer_valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
|
||||||
|
$buffer = openssl_random_pseudo_bytes($raw_salt_len);
|
||||||
|
if ($buffer) {
|
||||||
|
$buffer_valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$buffer_valid && @is_readable('/dev/urandom')) {
|
||||||
|
$f = fopen('/dev/urandom', 'r');
|
||||||
|
$read = PasswordCompat\binary\_strlen($buffer);
|
||||||
|
while ($read < $raw_salt_len) {
|
||||||
|
$buffer .= fread($f, $raw_salt_len - $read);
|
||||||
|
$read = PasswordCompat\binary\_strlen($buffer);
|
||||||
|
}
|
||||||
|
fclose($f);
|
||||||
|
if ($read >= $raw_salt_len) {
|
||||||
|
$buffer_valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) {
|
||||||
|
$bl = PasswordCompat\binary\_strlen($buffer);
|
||||||
|
for ($i = 0; $i < $raw_salt_len; $i++) {
|
||||||
|
if ($i < $bl) {
|
||||||
|
$buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
|
||||||
|
} else {
|
||||||
|
$buffer .= chr(mt_rand(0, 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$salt = $buffer;
|
||||||
|
$salt_requires_encoding = true;
|
||||||
|
}
|
||||||
|
if ($salt_requires_encoding) {
|
||||||
|
// encode string with the Base64 variant used by crypt
|
||||||
|
$base64_digits =
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||||
|
$bcrypt64_digits =
|
||||||
|
'./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
|
||||||
|
$base64_string = base64_encode($salt);
|
||||||
|
$salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits);
|
||||||
|
}
|
||||||
|
$salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len);
|
||||||
|
|
||||||
|
$hash = $hash_format . $salt;
|
||||||
|
|
||||||
|
$ret = crypt($password, $hash);
|
||||||
|
|
||||||
|
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get information about the password hash. Returns an array of the information
|
||||||
|
* that was used to generate the password hash.
|
||||||
|
*
|
||||||
|
* array(
|
||||||
|
* 'algo' => 1,
|
||||||
|
* 'algoName' => 'bcrypt',
|
||||||
|
* 'options' => array(
|
||||||
|
* 'cost' => PASSWORD_BCRYPT_DEFAULT_COST,
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @param string $hash The password hash to extract info from
|
||||||
|
*
|
||||||
|
* @return array The array of information about the hash.
|
||||||
|
*/
|
||||||
|
function password_get_info($hash) {
|
||||||
|
$return = array(
|
||||||
|
'algo' => 0,
|
||||||
|
'algoName' => 'unknown',
|
||||||
|
'options' => array(),
|
||||||
|
);
|
||||||
|
if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) {
|
||||||
|
$return['algo'] = PASSWORD_BCRYPT;
|
||||||
|
$return['algoName'] = 'bcrypt';
|
||||||
|
list($cost) = sscanf($hash, "$2y$%d$");
|
||||||
|
$return['options']['cost'] = $cost;
|
||||||
|
}
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the password hash needs to be rehashed according to the options provided
|
||||||
|
*
|
||||||
|
* If the answer is true, after validating the password using password_verify, rehash it.
|
||||||
|
*
|
||||||
|
* @param string $hash The hash to test
|
||||||
|
* @param int $algo The algorithm used for new password hashes
|
||||||
|
* @param array $options The options array passed to password_hash
|
||||||
|
*
|
||||||
|
* @return boolean True if the password needs to be rehashed.
|
||||||
|
*/
|
||||||
|
function password_needs_rehash($hash, $algo, array $options = array()) {
|
||||||
|
$info = password_get_info($hash);
|
||||||
|
if ($info['algo'] != $algo) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
switch ($algo) {
|
||||||
|
case PASSWORD_BCRYPT:
|
||||||
|
$cost = isset($options['cost']) ? $options['cost'] : PASSWORD_BCRYPT_DEFAULT_COST;
|
||||||
|
if ($cost != $info['options']['cost']) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify a password against a hash using a timing attack resistant approach
|
||||||
|
*
|
||||||
|
* @param string $password The password to verify
|
||||||
|
* @param string $hash The hash to verify against
|
||||||
|
*
|
||||||
|
* @return boolean If the password matches the hash
|
||||||
|
*/
|
||||||
|
function password_verify($password, $hash) {
|
||||||
|
if (!function_exists('crypt')) {
|
||||||
|
trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$ret = crypt($password, $hash);
|
||||||
|
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = 0;
|
||||||
|
for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) {
|
||||||
|
$status |= (ord($ret[$i]) ^ ord($hash[$i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $status === 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace PasswordCompat\binary {
|
||||||
|
|
||||||
|
if (!function_exists('PasswordCompat\\binary\\_strlen')) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count the number of bytes in a string
|
||||||
|
*
|
||||||
|
* We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension.
|
||||||
|
* In this case, strlen() will count the number of *characters* based on the internal encoding. A
|
||||||
|
* sequence of bytes might be regarded as a single multibyte character.
|
||||||
|
*
|
||||||
|
* @param string $binary_string The input string
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
* @return int The number of bytes
|
||||||
|
*/
|
||||||
|
function _strlen($binary_string) {
|
||||||
|
if (function_exists('mb_strlen')) {
|
||||||
|
return mb_strlen($binary_string, '8bit');
|
||||||
|
}
|
||||||
|
return strlen($binary_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a substring based on byte limits
|
||||||
|
*
|
||||||
|
* @see _strlen()
|
||||||
|
*
|
||||||
|
* @param string $binary_string The input string
|
||||||
|
* @param int $start
|
||||||
|
* @param int $length
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
* @return string The substring
|
||||||
|
*/
|
||||||
|
function _substr($binary_string, $start, $length) {
|
||||||
|
if (function_exists('mb_substr')) {
|
||||||
|
return mb_substr($binary_string, $start, $length, '8bit');
|
||||||
|
}
|
||||||
|
return substr($binary_string, $start, $length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if current PHP version is compatible with the library
|
||||||
|
*
|
||||||
|
* @return boolean the check result
|
||||||
|
*/
|
||||||
|
function check() {
|
||||||
|
static $pass = NULL;
|
||||||
|
|
||||||
|
if (is_null($pass)) {
|
||||||
|
if (function_exists('crypt')) {
|
||||||
|
$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
|
||||||
|
$test = crypt("password", $hash);
|
||||||
|
$pass = $test == $hash;
|
||||||
|
} else {
|
||||||
|
$pass = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require "lib/password.php";
|
||||||
|
|
||||||
|
echo "Test for functionality of compat library: " . (PasswordCompat\binary\check() ? "Pass" : "Fail");
|
||||||
|
echo "\n";
|
Loading…
Reference in New Issue