diff options
Diffstat (limited to 'tests/passwords')
| -rw-r--r-- | tests/passwords/drivers_test.php | 81 | ||||
| -rw-r--r-- | tests/passwords/manager_test.php | 295 | 
2 files changed, 376 insertions, 0 deletions
diff --git a/tests/passwords/drivers_test.php b/tests/passwords/drivers_test.php new file mode 100644 index 0000000000..2d26be7da5 --- /dev/null +++ b/tests/passwords/drivers_test.php @@ -0,0 +1,81 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_passwords_helper_test extends PHPUnit_Framework_TestCase +{ +	public function setUp() +	{ +		// Prepare dependencies for drivers +		$config =  new \phpbb\config\config(array()); +		$this->driver_helper = new \phpbb\passwords\driver\helper($config); + +		$this->passwords_drivers = array( +			'passwords.driver.bcrypt_2y'	=> new \phpbb\passwords\driver\bcrypt_2y($config, $this->driver_helper), +			'passwords.driver.bcrypt'		=> new \phpbb\passwords\driver\bcrypt($config, $this->driver_helper), +			'passwords.driver.salted_md5'	=> new \phpbb\passwords\driver\salted_md5($config, $this->driver_helper), +			'passwords.driver.phpass'		=> new \phpbb\passwords\driver\phpass($config, $this->driver_helper), +		); +	} + +	public function data_helper_encode64() +	{ +		return array( +			array('foobar', 6, 'axqPW3aQ'), +			array('foobar', 7, 'axqPW3aQ..'), +			array('foobar', 5, 'axqPW34'), +		); +	} + +	/** +	* @dataProvider data_helper_encode64 +	*/ +	public function test_helper_encode64($input, $length, $output) +	{ +		$return = $this->driver_helper->hash_encode64($input, $length); +		$this->assertEquals($output, $return); +	} + +	public function data_get_random_salt() +	{ +		return array( +			array(24, false), +			array(24, '/dev/foobar'), +		); +	} + +	/** +	* @dataProvider data_get_random_salt +	*/ +	public function test_get_random_salt($length, $rand_seed) +	{ +		$rand_string = (empty($rand_seed)) ? $this->driver_helper->get_random_salt($length) : $this->driver_helper->get_random_salt($length, $rand_seed); +		$start = microtime(true); + +		// Run each test for max. 1 second +		while ((microtime(true) - $start) < 1) +		{ +			$urandom_string = (empty($rand_seed)) ? $this->driver_helper->get_random_salt($length) : $this->driver_helper->get_random_salt($length, $rand_seed); +			$this->assertEquals($length, strlen($urandom_string)); +			$this->assertNotEquals($rand_string, $urandom_string); +		} +	} + +	public function test_get_hash_settings_salted_md5() +	{ +		$settings = $this->passwords_drivers['passwords.driver.salted_md5']->get_hash_settings('$H$9isfrtKXWqrz8PvztXlL3.daw4U0zI1'); +		$this->assertEquals(array( +				'count'	=> pow(2, 11), +				'salt'	=> 'isfrtKXW', +				'full'	=> '$H$9isfrtKXW', +			), +			$settings +		); +		$this->assertEquals(false, $this->passwords_drivers['passwords.driver.salted_md5']->get_hash_settings(false)); +	} +} diff --git a/tests/passwords/manager_test.php b/tests/passwords/manager_test.php new file mode 100644 index 0000000000..ee295ff043 --- /dev/null +++ b/tests/passwords/manager_test.php @@ -0,0 +1,295 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_passwords_manager_test extends PHPUnit_Framework_TestCase +{ +	protected $passwords_drivers; + +	protected $pw_characters = '0123456789abcdefghijklmnopqrstuvwyzABCDEFGHIJKLMNOPQRSTUVXYZ.,_!?/\\'; + +	protected $default_pw = 'foobar'; + +	public function setUp() +	{ +		// Prepare dependencies for manager and driver +		$config =  new \phpbb\config\config(array()); +		$this->driver_helper = new \phpbb\passwords\driver\helper($config); + +		$this->passwords_drivers = array( +			'passwords.driver.bcrypt_2y'	=> new \phpbb\passwords\driver\bcrypt_2y($config, $this->driver_helper), +			'passwords.driver.bcrypt'		=> new \phpbb\passwords\driver\bcrypt($config, $this->driver_helper), +			'passwords.driver.salted_md5'	=> new \phpbb\passwords\driver\salted_md5($config, $this->driver_helper), +			'passwords.driver.phpass'		=> new \phpbb\passwords\driver\phpass($config, $this->driver_helper), +		); + +		$this->helper = new \phpbb\passwords\helper; +		// Set up passwords manager +		$this->manager = new \phpbb\passwords\manager($config, $this->passwords_drivers, $this->helper, array_keys($this->passwords_drivers)); +	} + +	public function hash_password_data() +	{ +		if (version_compare(PHP_VERSION, '5.3.7', '<')) +		{ +			return array( +				array('', '2a', 60), +				array('passwords.driver.bcrypt_2y', '2a', 60), +				array('passwords.driver.bcrypt', '2a', 60), +				array('passwords.driver.salted_md5', 'H', 34), +				array('passwords.driver.foobar', '', false), +			); +		} +		else +		{ +			return array( +				array('', '2y', 60), +				array('passwords.driver.bcrypt_2y', '2y', 60), +				array('passwords.driver.bcrypt', '2a', 60), +				array('passwords.driver.salted_md5', 'H', 34), +				array('passwords.driver.foobar', '', false), +			); +		} +	} + +	/** +	* @dataProvider hash_password_data +	*/ +	public function test_hash_password($type, $prefix, $length) +	{ +		$password = $this->default_pw; + +		if (!$length) +		{ +			$this->assertEquals(false, $hash = $this->manager->hash($password, $type)); +			return; +		} +		$time = microtime(true); + +		// Limit each test to 1 second +		while ((microtime(true) - $time) < 1) +		{ +			$hash = $this->manager->hash($password, $type); +			preg_match('#^\$([a-zA-Z0-9\\\]*?)\$#', $hash, $match); +			$this->assertEquals($prefix, $match[1]); +			$this->assertEquals($length, strlen($hash)); +			$password .= $this->pw_characters[mt_rand(0, 66)]; +		} +	} + +	public function check_password_data() +	{ +		if (version_compare(PHP_VERSION, '5.3.7', '<')) +		{ +			return array( +				array('passwords.driver.bcrypt'), +				array('passwords.driver.salted_md5'), +				array('passwords.driver.phpass'), +			); +		} +		else +		{ +			return array( +				array('passwords.driver.bcrypt_2y'), +				array('passwords.driver.bcrypt'), +				array('passwords.driver.salted_md5'), +				array('passwords.driver.phpass'), +			); +		} +	} + +	/** +	* @dataProvider check_password_data +	*/ +	public function test_check_password($hash_type) +	{ +		$password = $this->default_pw; +		$time = microtime(true); +		// Limit each test to 1 second +		while ((microtime(true) - $time) < 1) +		{ +			$hash = $this->manager->hash($password, $hash_type); +			$this->assertEquals(true, $this->manager->check($password, $hash)); +			$password .= $this->pw_characters[mt_rand(0, 66)]; +			$this->assertEquals(false, $this->manager->check($password, $hash)); +		} + +		// Check if convert_flag is correctly set +		$default_type = (version_compare(PHP_VERSION, '5.3.7', '<')) ? 'passwords.driver.bcrypt' : 'passwords.driver.bcrypt_2y'; +		$this->assertEquals(($hash_type !== $default_type), $this->manager->convert_flag); +	} + + +	public function check_hash_exceptions_data() +	{ +		return array( +			array('foobar', '3858f62230ac3c915f300c664312c63f', true), +			array('foobar', '$S$b57a939fa4f2c04413a4eea9734a0903647b7adb93181295', false), +			array('foobar', '$2a\S$kkkkaakdkdiej39023903204j2k3490234jk234j02349', false), +			array('foobar', '$H$kklk938d023k//k3023', false), +			array('foobar', '$H$3PtYMgXb39lrIWkgoxYLWtRkZtY3AY/', false), +			array('foobar', '$2a$kwiweorurlaeirw', false), +		); +	} + +	/** +	* @dataProvider check_hash_exceptions_data +	*/ +	public function test_check_hash_exceptions($password, $hash, $expected) +	{ +		$this->assertEquals($expected, $this->manager->check($password, $hash)); +	} + +	public function data_hash_password_length() +	{ +		return array( +			array('passwords.driver.bcrypt', false), +			array('passwords.driver.bcrypt_2y', false), +			array('passwords.driver.salted_md5', '3858f62230ac3c915f300c664312c63f'), +			array('passwords.driver.phpass', '3858f62230ac3c915f300c664312c63f'), +		); +	} + +	/** +	* @dataProvider data_hash_password_length +	*/ +	public function test_hash_password_length($driver, $expected) +	{ +		$this->assertEquals($expected, $this->passwords_drivers[$driver]->hash('foobar', 'foobar')); +	} + +	public function test_hash_password_8bit_bcrypt() +	{ +		$this->assertEquals(false, $this->manager->hash('foobar𝄞', 'passwords.driver.bcrypt')); +		if (version_compare(PHP_VERSION, '5.3.7', '<')) +		{ +			$this->assertEquals(false, $this->manager->hash('foobar𝄞', 'passwords.driver.bcrypt_2y')); +		} +		else +		{ +			$this->assertNotEquals(false, $this->manager->hash('foobar𝄞', 'passwords.driver.bcrypt_2y')); +		} +	} + +	public function test_combined_hash_data() +	{ +		if (version_compare(PHP_VERSION, '5.3.7', '<')) +		{ +			return array( +				array( +					'passwords.driver.salted_md5', +					array('passwords.driver.bcrypt'), +				), +				array( +					'passwords.driver.phpass', +					array('passwords.driver.salted_md5'), +				), +				array( +					'passwords.driver.salted_md5', +					array('passwords.driver.phpass', 'passwords.driver.bcrypt'), +				), +				array( +					'passwords.driver.salted_md5', +					array('passwords.driver.salted_md5'), +					false, +				), +				array( +					'$H$', +					array('$2a$'), +				), +			); +		} +		else +		{ +			return array( +				array( +					'passwords.driver.salted_md5', +					array('passwords.driver.bcrypt_2y'), +				), +				array( +					'passwords.driver.salted_md5', +					array('passwords.driver.bcrypt'), +				), +				array( +					'passwords.driver.phpass', +					array('passwords.driver.salted_md5'), +				), +				array( +					'passwords.driver.salted_md5', +					array('passwords.driver.bcrypt_2y', 'passwords.driver.bcrypt'), +				), +				array( +					'passwords.driver.salted_md5', +					array('passwords.driver.salted_md5'), +					false, +				), +				array( +					'passwords.driver.bcrypt_2y', +					array('passwords.driver.salted_md4'), +					false, +				), +				array( +					'$H$', +					array('$2y$'), +				), +			); +		} +	} + +	/** +	* @dataProvider test_combined_hash_data +	*/ +	public function test_combined_hash_password($first_type, $second_type, $expected = true) +	{ +		$password = $this->default_pw; +		$time = microtime(true); +		// Limit each test to 1 second +		while ((microtime(true) - $time) < 1) +		{ +			$hash = $this->manager->hash($password, $first_type); +			$combined_hash = $this->manager->hash($hash, $second_type); +			$this->assertEquals($expected, $this->manager->check($password, $combined_hash)); +			$password .= $this->pw_characters[mt_rand(0, 66)]; +			$this->assertEquals(false, $this->manager->check($password, $combined_hash)); + +			// If we are expecting the check to fail then there is +			// no need to run this more than once +			if (!$expected) +			{ +				break; +			} +		} +	} + +	public function test_unique_id() +	{ +		$time = microtime(true); +		$first_id = $this->driver_helper->unique_id(); +		// Limit test to 1 second +		while ((microtime(true) - $time) < 1) +		{ +			$this->assertNotEquals($first_id, $this->driver_helper->unique_id()); +		} +	} + +	public function test_check_hash_with_large_input() +	{ +		// 16 MB password, should be rejected quite fast +		$start_time = time(); +		$this->assertFalse($this->manager->check(str_repeat('a', 1024 * 1024 * 16), '$H$9isfrtKXWqrz8PvztXlL3.daw4U0zI1')); +		$this->assertLessThanOrEqual(5, time() - $start_time); +	} + +	public function test_hash_password_with_large_input() +	{ +		// 16 MB password, should be rejected quite fast +		$start_time = time(); +		$this->assertFalse($this->manager->hash(str_repeat('a', 1024 * 1024 * 16))); +		$this->assertLessThanOrEqual(5, time() - $start_time); +	} +}  | 
