aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb/passwords/manager.php
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/phpbb/passwords/manager.php')
-rw-r--r--phpBB/phpbb/passwords/manager.php210
1 files changed, 210 insertions, 0 deletions
diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php
new file mode 100644
index 0000000000..9477ef5c2b
--- /dev/null
+++ b/phpBB/phpbb/passwords/manager.php
@@ -0,0 +1,210 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2013 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* @package passwords
+*/
+class phpbb_passwords_manager
+{
+ /**
+ * Default hashing method
+ */
+ protected $type = false;
+
+ /**
+ * Hashing algorithm types
+ */
+ protected $type_map = false;
+
+ /**
+ * Password convert flag. Password should be converted
+ */
+ public $convert_flag = false;
+
+ /**
+ * Crypto helper
+ * @var phpbb_passwords_helper
+ */
+ protected $helper;
+
+ /**
+ * phpBB configuration
+ * @var phpbb_config
+ */
+ protected $config;
+
+ /**
+ * phpBB compiled container
+ * @var service_container
+ */
+ protected $container;
+
+ /**
+ * Construct a passwords object
+ *
+ * @param phpbb_config $config phpBB configuration
+ */
+ public function __construct($config, $container, $hashing_algorithms, $default)
+ {
+ $this->config = $config;
+ $this->container = $container;
+ $this->type = $default;
+
+ $this->fill_type_map($hashing_algorithms);
+ $this->load_passwords_helper();
+ }
+
+ /**
+ * Fill algorithm type map
+ *
+ * @param phpbb_di_service_collection $hashing_algorithms
+ */
+ protected function fill_type_map($hashing_algorithms)
+ {
+ foreach ($hashing_algorithms as $algorithm)
+ {
+ if (!isset($this->type_map[$algorithm->get_prefix()]))
+ {
+ $this->type_map[$algorithm->get_prefix()] = $algorithm;
+ }
+ }
+ }
+
+ /**
+ * Load passwords helper class
+ */
+ protected function load_passwords_helper()
+ {
+ if ($this->helper === null)
+ {
+ $this->helper = new phpbb_passwords_helper($this, $this->container);
+ }
+ }
+
+ /**
+ * Get the hash type from the supplied hash
+ *
+ * @param string $hash Password hash that should be checked
+ *
+ * @return object The hash type object
+ */
+ public function get_hashing_algorithm($hash)
+ {
+ /*
+ * preg_match() will also show hashing algos like $2a\H$, which
+ * is a combination of bcrypt and phpass. Legacy algorithms
+ * like md5 will not be matched by this and need to be treated
+ * differently.
+ */
+ if (!preg_match('#^\$([a-zA-Z0-9\\\]*?)\$#', $hash, $match))
+ {
+ return $this->type_map['$H$'];
+ }
+
+ // Be on the lookout for multiple hashing algorithms
+ // 2 is correct: H\2a > 2, H\P > 2
+ if (strlen($match[1]) > 2)
+ {
+ $hash_types = explode('\\', $match[1]);
+ $return_ary = array();
+ foreach ($hash_types as $type)
+ {
+ if (isset($this->type_map["\${$type}\$"]))
+ {
+ // we do not support the same hashing
+ // algorithm more than once
+ if (isset($return_ary[$type]))
+ {
+ return false;
+ }
+ $return_ary[$type] = $this->type_map["\${$type}\$"];
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return $return_ary;
+ }
+ if (isset($this->type_map[$match[0]]))
+ {
+ return $this->type_map[$match[0]];
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Hash supplied password
+ *
+ * @param string $password Password that should be hashed
+ * @param string $type Hash type. Will default to standard hash type if
+ * none is supplied
+ * @return string|bool Password hash of supplied password or false if
+ * if something went wrong during hashing
+ */
+ public function hash_password($password, $type = '')
+ {
+ $type = ($type === '') ? $this->type : $type;
+
+ if (is_array($type))
+ {
+ return $this->helper->combined_hash_password($password, $type);
+ }
+
+ $hashing_algorithm = $this->container->get($type);
+ // Do not support 8-bit characters with $2a$ bcrypt
+ if ($type === 'passwords.driver.bcrypt' || ($type === 'passwords.driver.bcrypt_2y' && !$hashing_algorithm->is_supported()))
+ {
+ if (ord($password[strlen($password)-1]) & 128)
+ {
+ return false;
+ }
+ }
+
+ return $this->container->get($type)->hash($password);
+ }
+
+ public function check_hash($password, $hash)
+ {
+ // First find out what kind of hash we're dealing with
+ $stored_hash_type = $this->get_hashing_algorithm($hash);
+ if ($stored_hash_type == false)
+ {
+ return false;
+ }
+
+ // Multiple hash passes needed
+ if (is_array($stored_hash_type))
+ {
+ return $this->helper->check_combined_hash($password, $stored_hash_type, $hash);
+ }
+
+ if ($stored_hash_type->get_name() !== $this->type)
+ {
+ $this->convert_flag = true;
+ }
+ else
+ {
+ $this->convert_flag = false;
+ }
+
+ return $stored_hash_type->check($password, $hash);
+ }
+}