[ Index ] |
PHP Cross Reference of phpBB-3.1.12-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 namespace phpbb\passwords; 15 16 class manager 17 { 18 /** 19 * Default hashing method 20 */ 21 protected $type = false; 22 23 /** 24 * Hashing algorithm type map 25 * Will be used to map hash prefix to type 26 */ 27 protected $type_map = false; 28 29 /** 30 * Service collection of hashing algorithms 31 * Needs to be public for passwords helper 32 */ 33 public $algorithms = false; 34 35 /** 36 * Password convert flag. Signals that password should be converted 37 */ 38 public $convert_flag = false; 39 40 /** 41 * Passwords helper 42 * @var \phpbb\passwords\helper 43 */ 44 protected $helper; 45 46 /** 47 * phpBB configuration 48 * @var \phpbb\config\config 49 */ 50 protected $config; 51 52 /** 53 * Construct a passwords object 54 * 55 * @param \phpbb\config\config $config phpBB configuration 56 * @param array $hashing_algorithms Hashing driver 57 * service collection 58 * @param \phpbb\passwords\helper $helper Passwords helper object 59 * @param array $defaults List of default driver types 60 */ 61 public function __construct(\phpbb\config\config $config, $hashing_algorithms, helper $helper, $defaults) 62 { 63 $this->config = $config; 64 $this->helper = $helper; 65 66 $this->fill_type_map($hashing_algorithms); 67 $this->register_default_type($defaults); 68 } 69 70 /** 71 * Register default type 72 * Will register the first supported type from the list of default types 73 * 74 * @param array $defaults List of default types in order from first to 75 * use to last to use 76 */ 77 protected function register_default_type($defaults) 78 { 79 foreach ($defaults as $type) 80 { 81 if ($this->algorithms[$type]->is_supported()) 82 { 83 $this->type = $this->algorithms[$type]->get_prefix(); 84 break; 85 } 86 } 87 } 88 89 /** 90 * Fill algorithm type map 91 * 92 * @param \phpbb\di\service_collection $hashing_algorithms 93 */ 94 protected function fill_type_map($hashing_algorithms) 95 { 96 foreach ($hashing_algorithms as $algorithm) 97 { 98 if (!isset($this->type_map[$algorithm->get_prefix()])) 99 { 100 $this->type_map[$algorithm->get_prefix()] = $algorithm; 101 } 102 } 103 $this->algorithms = $hashing_algorithms; 104 } 105 106 /** 107 * Get the algorithm specified by a specific prefix 108 * 109 * @param string $prefix Password hash prefix 110 * 111 * @return object|bool The hash type object or false if prefix is not 112 * supported 113 */ 114 protected function get_algorithm($prefix) 115 { 116 if (isset($this->type_map[$prefix])) 117 { 118 return $this->type_map[$prefix]; 119 } 120 else 121 { 122 return false; 123 } 124 } 125 126 /** 127 * Detect the hash type of the supplied hash 128 * 129 * @param string $hash Password hash that should be checked 130 * 131 * @return object|bool The hash type object or false if the specified 132 * type is not supported 133 */ 134 public function detect_algorithm($hash) 135 { 136 /* 137 * preg_match() will also show hashing algos like $2a\H$, which 138 * is a combination of bcrypt and phpass. Legacy algorithms 139 * like md5 will not be matched by this and need to be treated 140 * differently. 141 */ 142 if (!preg_match('#^\$([a-zA-Z0-9\\\]*?)\$#', $hash, $match)) 143 { 144 return false; 145 } 146 147 // Be on the lookout for multiple hashing algorithms 148 // 2 is correct: H\2a > 2, H\P > 2 149 if (strlen($match[1]) > 2) 150 { 151 $hash_types = explode('\\', $match[1]); 152 $return_ary = array(); 153 foreach ($hash_types as $type) 154 { 155 // we do not support the same hashing 156 // algorithm more than once 157 if (isset($return_ary[$type])) 158 { 159 return false; 160 } 161 162 $return_ary[$type] = $this->get_algorithm('$' . $type . '$'); 163 164 if (empty($return_ary[$type])) 165 { 166 return false; 167 } 168 } 169 return $return_ary; 170 } 171 172 // get_algorithm() will automatically return false if prefix 173 // is not supported 174 return $this->get_algorithm($match[0]); 175 } 176 177 /** 178 * Hash supplied password 179 * 180 * @param string $password Password that should be hashed 181 * @param string $type Hash type. Will default to standard hash type if 182 * none is supplied 183 * @return string|bool Password hash of supplied password or false if 184 * if something went wrong during hashing 185 */ 186 public function hash($password, $type = '') 187 { 188 if (strlen($password) > 4096) 189 { 190 // If the password is too huge, we will simply reject it 191 // and not let the server try to hash it. 192 return false; 193 } 194 195 // Try to retrieve algorithm by service name if type doesn't 196 // start with dollar sign 197 if (!is_array($type) && strpos($type, '$') !== 0 && isset($this->algorithms[$type])) 198 { 199 $type = $this->algorithms[$type]->get_prefix(); 200 } 201 202 $type = ($type === '') ? $this->type : $type; 203 204 if (is_array($type)) 205 { 206 return $this->combined_hash_password($password, $type); 207 } 208 209 if (isset($this->type_map[$type])) 210 { 211 $hashing_algorithm = $this->type_map[$type]; 212 } 213 else 214 { 215 return false; 216 } 217 218 return $hashing_algorithm->hash($password); 219 } 220 221 /** 222 * Check supplied password against hash and set convert_flag if password 223 * needs to be converted to different format (preferrably newer one) 224 * 225 * @param string $password Password that should be checked 226 * @param string $hash Stored hash 227 * @param array $user_row User's row in users table 228 * @return string|bool True if password is correct, false if not 229 */ 230 public function check($password, $hash, $user_row = array()) 231 { 232 if (strlen($password) > 4096) 233 { 234 // If the password is too huge, we will simply reject it 235 // and not let the server try to hash it. 236 return false; 237 } 238 239 // Empty hashes can't be checked 240 if (empty($hash)) 241 { 242 return false; 243 } 244 245 // First find out what kind of hash we're dealing with 246 $stored_hash_type = $this->detect_algorithm($hash); 247 if ($stored_hash_type == false) 248 { 249 // Still check MD5 hashes as that is what the installer 250 // will default to for the admin user 251 return $this->get_algorithm('$H$')->check($password, $hash); 252 } 253 254 // Multiple hash passes needed 255 if (is_array($stored_hash_type)) 256 { 257 $correct = $this->check_combined_hash($password, $stored_hash_type, $hash); 258 $this->convert_flag = ($correct === true) ? true : false; 259 return $correct; 260 } 261 262 if ($stored_hash_type->get_prefix() !== $this->type) 263 { 264 $this->convert_flag = true; 265 } 266 else 267 { 268 $this->convert_flag = false; 269 } 270 271 // Check all legacy hash types if prefix is $CP$ 272 if ($stored_hash_type->get_prefix() === '$CP$') 273 { 274 // Remove $CP$ prefix for proper checking 275 $hash = substr($hash, 4); 276 277 foreach ($this->type_map as $algorithm) 278 { 279 if ($algorithm->is_legacy() && $algorithm->check($password, $hash, $user_row) === true) 280 { 281 return true; 282 } 283 } 284 } 285 286 return $stored_hash_type->check($password, $hash); 287 } 288 289 /** 290 * Create combined hash from already hashed password 291 * 292 * @param string $password_hash Complete current password hash 293 * @param string $type Type of the hashing algorithm the password hash 294 * should be combined with 295 * @return string|bool Combined password hash if combined hashing was 296 * successful, else false 297 */ 298 public function combined_hash_password($password_hash, $type) 299 { 300 $data = array( 301 'prefix' => '$', 302 'settings' => '$', 303 ); 304 $hash_settings = $this->helper->get_combined_hash_settings($password_hash); 305 $hash = $hash_settings[0]; 306 307 // Put settings of current hash into data array 308 $stored_hash_type = $this->detect_algorithm($password_hash); 309 $this->helper->combine_hash_output($data, 'prefix', $stored_hash_type->get_prefix()); 310 $this->helper->combine_hash_output($data, 'settings', $stored_hash_type->get_settings_only($password_hash)); 311 312 // Hash current hash with the defined types 313 foreach ($type as $cur_type) 314 { 315 if (isset($this->algorithms[$cur_type])) 316 { 317 $new_hash_type = $this->algorithms[$cur_type]; 318 } 319 else 320 { 321 $new_hash_type = $this->get_algorithm($cur_type); 322 } 323 324 if (!$new_hash_type) 325 { 326 return false; 327 } 328 329 $new_hash = $new_hash_type->hash(str_replace($stored_hash_type->get_settings_only($password_hash), '', $hash)); 330 $this->helper->combine_hash_output($data, 'prefix', $new_hash_type->get_prefix()); 331 $this->helper->combine_hash_output($data, 'settings', substr(str_replace('$', '\\', $new_hash_type->get_settings_only($new_hash, true)), 0)); 332 $hash = str_replace($new_hash_type->get_settings_only($new_hash), '', $this->helper->obtain_hash_only($new_hash)); 333 } 334 return $this->helper->combine_hash_output($data, 'hash', $hash); 335 } 336 337 /** 338 * Check combined password hash against the supplied password 339 * 340 * @param string $password Password entered by user 341 * @param array $stored_hash_type An array containing the hash types 342 * as described by stored password hash 343 * @param string $hash Stored password hash 344 * 345 * @return bool True if password is correct, false if not 346 */ 347 public function check_combined_hash($password, $stored_hash_type, $hash) 348 { 349 $i = 0; 350 $data = array( 351 'prefix' => '$', 352 'settings' => '$', 353 ); 354 $hash_settings = $this->helper->get_combined_hash_settings($hash); 355 foreach ($stored_hash_type as $key => $hash_type) 356 { 357 $rebuilt_hash = $this->helper->rebuild_hash($hash_type->get_prefix(), $hash_settings[$i]); 358 $this->helper->combine_hash_output($data, 'prefix', $key); 359 $this->helper->combine_hash_output($data, 'settings', $hash_settings[$i]); 360 $cur_hash = $hash_type->hash($password, $rebuilt_hash); 361 $password = str_replace($rebuilt_hash, '', $cur_hash); 362 $i++; 363 } 364 return ($hash === $this->helper->combine_hash_output($data, 'hash', $password)); 365 } 366 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |