diff options
Diffstat (limited to 'phpBB/phpbb/passwords')
| -rw-r--r-- | phpBB/phpbb/passwords/driver/base.php | 12 | ||||
| -rw-r--r-- | phpBB/phpbb/passwords/driver/bcrypt.php | 32 | ||||
| -rw-r--r-- | phpBB/phpbb/passwords/driver/rehashable_driver_interface.php | 25 | ||||
| -rw-r--r-- | phpBB/phpbb/passwords/manager.php | 59 | 
4 files changed, 116 insertions, 12 deletions
| diff --git a/phpBB/phpbb/passwords/driver/base.php b/phpBB/phpbb/passwords/driver/base.php index fd07a61bf4..0997b5b700 100644 --- a/phpBB/phpbb/passwords/driver/base.php +++ b/phpBB/phpbb/passwords/driver/base.php @@ -13,7 +13,7 @@  namespace phpbb\passwords\driver; -abstract class base implements driver_interface +abstract class base implements rehashable_driver_interface  {  	/** @var \phpbb\config\config */  	protected $config; @@ -21,7 +21,7 @@ abstract class base implements driver_interface  	/** @var \phpbb\passwords\driver\helper */  	protected $helper; -	/** @var driver name */ +	/** @var string Driver name */  	protected $name;  	/** @@ -53,6 +53,14 @@ abstract class base implements driver_interface  	}  	/** +	 * {@inheritdoc} +	 */ +	public function needs_rehash($hash) +	{ +		return false; +	} + +	/**  	* {@inheritdoc}  	*/  	public function get_settings_only($hash, $full = false) diff --git a/phpBB/phpbb/passwords/driver/bcrypt.php b/phpBB/phpbb/passwords/driver/bcrypt.php index eab1c3d569..eb1aeeeb76 100644 --- a/phpBB/phpbb/passwords/driver/bcrypt.php +++ b/phpBB/phpbb/passwords/driver/bcrypt.php @@ -17,6 +17,24 @@ class bcrypt extends base  {  	const PREFIX = '$2a$'; +	/** @var int Hashing cost factor */ +	protected $cost_factor; + +	/** +	 * Constructor of passwords driver object +	 * +	 * @param \phpbb\config\config $config phpBB config +	 * @param \phpbb\passwords\driver\helper $helper Password driver helper +	 * @param int $cost_factor Hashing cost factor (optional) +	 */ +	public function __construct(\phpbb\config\config $config, helper $helper, $cost_factor = 10) +	{ +		parent::__construct($config, $helper); + +		// Don't allow cost factor to be below default setting +		$this->cost_factor = max(10, $cost_factor); +	} +  	/**  	* {@inheritdoc}  	*/ @@ -26,6 +44,18 @@ class bcrypt extends base  	}  	/** +	 * {@inheritdoc} +	 */ +	public function needs_rehash($hash) +	{ +		preg_match('/^' . preg_quote($this->get_prefix()) . '([0-9]+)\$/', $hash, $matches); + +		list(, $cost_factor) = $matches; + +		return empty($cost_factor) || $this->cost_factor !== intval($cost_factor); +	} + +	/**  	* {@inheritdoc}  	*/  	public function hash($password, $salt = '') @@ -46,7 +76,7 @@ class bcrypt extends base  		if ($salt == '')  		{ -			$salt = $prefix . '10$' . $this->get_random_salt(); +			$salt = $prefix . $this->cost_factor . '$' . $this->get_random_salt();  		}  		$hash = crypt($password, $salt); diff --git a/phpBB/phpbb/passwords/driver/rehashable_driver_interface.php b/phpBB/phpbb/passwords/driver/rehashable_driver_interface.php new file mode 100644 index 0000000000..ca30748502 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/rehashable_driver_interface.php @@ -0,0 +1,25 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +interface rehashable_driver_interface extends driver_interface +{ +	/** +	 * Check if password needs to be rehashed +	 * +	 * @param string $hash Hash to check for rehash +	 * @return bool True if password needs to be rehashed, false if not +	 */ +	public function needs_rehash($hash); +} diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php index aa9147ecf4..fad76a9fe5 100644 --- a/phpBB/phpbb/passwords/manager.php +++ b/phpBB/phpbb/passwords/manager.php @@ -50,21 +50,47 @@ class manager  	protected $config;  	/** +	 * @var bool Whether or not initialized() has been called +	 */ +	private $initialized = false; + +	/** +	 * @var array Hashing driver service collection +	 */ +	private $hashing_algorithms; + +	/** +	 * @var array List of default driver types +	 */ +	private $defaults; + +	/**  	* Construct a passwords object  	* -	* @param \phpbb\config\config $config phpBB configuration -	* @param array $hashing_algorithms Hashing driver -	*			service collection -	* @param \phpbb\passwords\helper $helper Passwords helper object -	* @param array $defaults List of default driver types +	* @param \phpbb\config\config		$config				phpBB configuration +	* @param array						$hashing_algorithms	Hashing driver service collection +	* @param \phpbb\passwords\helper	$helper				Passwords helper object +	* @param array						$defaults			List of default driver types  	*/  	public function __construct(\phpbb\config\config $config, $hashing_algorithms, helper $helper, $defaults)  	{  		$this->config = $config;  		$this->helper = $helper; +		$this->hashing_algorithms = $hashing_algorithms; +		$this->defaults = $defaults; +	} -		$this->fill_type_map($hashing_algorithms); -		$this->register_default_type($defaults); +	/** +	 * Initialize the internal state +	 */ +	protected function initialize() +	{ +		if (!$this->initialized) +		{ +			$this->initialized = true; +			$this->fill_type_map($this->hashing_algorithms); +			$this->register_default_type($this->defaults); +		}  	}  	/** @@ -144,9 +170,11 @@ class manager  			return false;  		} +		$this->initialize(); +  		// Be on the lookout for multiple hashing algorithms  		// 2 is correct: H\2a > 2, H\P > 2 -		if (strlen($match[1]) > 2) +		if (strlen($match[1]) > 2 && strpos($match[1], '\\') !== false)  		{  			$hash_types = explode('\\', $match[1]);  			$return_ary = array(); @@ -192,6 +220,8 @@ class manager  			return false;  		} +		$this->initialize(); +  		// Try to retrieve algorithm by service name if type doesn't  		// start with dollar sign  		if (!is_array($type) && strpos($type, '$') !== 0 && isset($this->algorithms[$type])) @@ -242,6 +272,8 @@ class manager  			return false;  		} +		$this->initialize(); +  		// First find out what kind of hash we're dealing with  		$stored_hash_type = $this->detect_algorithm($hash);  		if ($stored_hash_type == false) @@ -265,7 +297,14 @@ class manager  		}  		else  		{ -			$this->convert_flag = false; +			if ($stored_hash_type instanceof driver\rehashable_driver_interface) +			{ +				$this->convert_flag = $stored_hash_type->needs_rehash($hash); +			} +			else +			{ +				$this->convert_flag = false; +			}  		}  		// Check all legacy hash types if prefix is $CP$ @@ -297,6 +336,8 @@ class manager  	*/  	public function combined_hash_password($password_hash, $type)  	{ +		$this->initialize(); +  		$data = array(  			'prefix' => '$',  			'settings' => '$', | 
