Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

manager.php

Zuletzt modifiziert: 09.10.2024, 12:52 - Dateigröße: 9.30 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb\passwords;
015   
016  class manager
017  {
018      /**
019      * Default hashing method
020      */
021      protected $type = false;
022   
023      /**
024      * Hashing algorithm type map
025      * Will be used to map hash prefix to type
026      */
027      protected $type_map = false;
028   
029      /**
030      * Service collection of hashing algorithms
031      * Needs to be public for passwords helper
032      */
033      public $algorithms = false;
034   
035      /**
036      * Password convert flag. Signals that password should be converted
037      */
038      public $convert_flag = false;
039   
040      /**
041      * Passwords helper
042      * @var \phpbb\passwords\helper
043      */
044      protected $helper;
045   
046      /**
047      * phpBB configuration
048      * @var \phpbb\config\config
049      */
050      protected $config;
051   
052      /**
053      * Construct a passwords object
054      *
055      * @param \phpbb\config\config $config phpBB configuration
056      * @param array $hashing_algorithms Hashing driver
057      *            service collection
058      * @param \phpbb\passwords\helper $helper Passwords helper object
059      * @param string $defaults List of default driver types
060      */
061      public function __construct(\phpbb\config\config $config, $hashing_algorithms, helper $helper, $defaults)
062      {
063          $this->config = $config;
064          $this->helper = $helper;
065   
066          $this->fill_type_map($hashing_algorithms);
067          $this->register_default_type($defaults);
068      }
069   
070      /**
071      * Register default type
072      * Will register the first supported type from the list of default types
073      *
074      * @param array $defaults List of default types in order from first to
075      *            use to last to use
076      */
077      protected function register_default_type($defaults)
078      {
079          foreach ($defaults as $type)
080          {
081              if ($this->algorithms[$type]->is_supported())
082              {
083                  $this->type = $this->algorithms[$type]->get_prefix();
084                  break;
085              }
086          }
087      }
088   
089      /**
090      * Fill algorithm type map
091      *
092      * @param \phpbb\di\service_collection $hashing_algorithms
093      */
094      protected function fill_type_map($hashing_algorithms)
095      {
096          foreach ($hashing_algorithms as $algorithm)
097          {
098              if (!isset($this->type_map[$algorithm->get_prefix()]))
099              {
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  }
367