Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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

password.php

Zuletzt modifiziert: 09.10.2024, 12:55 - Dateigröße: 12.14 KiB


001  <?php
002  /**
003   * A Compatibility library with PHP 5.5's simplified password hashing API.
004   *
005   * @author Anthony Ferrara <ircmaxell@php.net>
006   * @license http://www.opensource.org/licenses/mit-license.html MIT License
007   * @copyright 2012 The Authors
008   */
009   
010  namespace {
011   
012      if (!defined('PASSWORD_BCRYPT')) {
013          /**
014           * PHPUnit Process isolation caches constants, but not function declarations.
015           * So we need to check if the constants are defined separately from 
016           * the functions to enable supporting process isolation in userland
017           * code.
018           */
019          define('PASSWORD_BCRYPT', 1);
020          define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
021          define('PASSWORD_BCRYPT_DEFAULT_COST', 10);
022      }
023   
024      if (!function_exists('password_hash')) {
025   
026          /**
027           * Hash the password using the specified algorithm
028           *
029           * @param string $password The password to hash
030           * @param int    $algo     The algorithm to use (Defined by PASSWORD_* constants)
031           * @param array  $options  The options for the algorithm to use
032           *
033           * @return string|false The hashed password, or false on error.
034           */
035          function password_hash($password, $algo, array $options = array()) {
036              if (!function_exists('crypt')) {
037                  trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
038                  return null;
039              }
040              if (is_null($password) || is_int($password)) {
041                  $password = (string) $password;
042              }
043              if (!is_string($password)) {
044                  trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
045                  return null;
046              }
047              if (!is_int($algo)) {
048                  trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
049                  return null;
050              }
051              $resultLength = 0;
052              switch ($algo) {
053                  case PASSWORD_BCRYPT:
054                      $cost = PASSWORD_BCRYPT_DEFAULT_COST;
055                      if (isset($options['cost'])) {
056                          $cost = $options['cost'];
057                          if ($cost < 4 || $cost > 31) {
058                              trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
059                              return null;
060                          }
061                      }
062                      // The length of salt to generate
063                      $raw_salt_len = 16;
064                      // The length required in the final serialization
065                      $required_salt_len = 22;
066                      $hash_format = sprintf("$2y$%02d$", $cost);
067                      // The expected length of the final crypt() output
068                      $resultLength = 60;
069                      break;
070                  default:
071                      trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
072                      return null;
073              }
074              $salt_requires_encoding = false;
075              if (isset($options['salt'])) {
076                  switch (gettype($options['salt'])) {
077                      case 'NULL':
078                      case 'boolean':
079                      case 'integer':
080                      case 'double':
081                      case 'string':
082                          $salt = (string) $options['salt'];
083                          break;
084                      case 'object':
085                          if (method_exists($options['salt'], '__tostring')) {
086                              $salt = (string) $options['salt'];
087                              break;
088                          }
089                      case 'array':
090                      case 'resource':
091                      default:
092                          trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
093                          return null;
094                  }
095                  if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) {
096                      trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING);
097                      return null;
098                  } elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
099                      $salt_requires_encoding = true;
100                  }
101              } else {
102                  $buffer = '';
103                  $buffer_valid = false;
104                  if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
105                      $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
106                      if ($buffer) {
107                          $buffer_valid = true;
108                      }
109                  }
110                  if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
111                      $buffer = openssl_random_pseudo_bytes($raw_salt_len);
112                      if ($buffer) {
113                          $buffer_valid = true;
114                      }
115                  }
116                  if (!$buffer_valid && @is_readable('/dev/urandom')) {
117                      $f = fopen('/dev/urandom', 'r');
118                      $read = PasswordCompat\binary\_strlen($buffer);
119                      while ($read < $raw_salt_len) {
120                          $buffer .= fread($f, $raw_salt_len - $read);
121                          $read = PasswordCompat\binary\_strlen($buffer);
122                      }
123                      fclose($f);
124                      if ($read >= $raw_salt_len) {
125                          $buffer_valid = true;
126                      }
127                  }
128                  if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) {
129                      $bl = PasswordCompat\binary\_strlen($buffer);
130                      for ($i = 0; $i < $raw_salt_len; $i++) {
131                          if ($i < $bl) {
132                              $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
133                          } else {
134                              $buffer .= chr(mt_rand(0, 255));
135                          }
136                      }
137                  }
138                  $salt = $buffer;
139                  $salt_requires_encoding = true;
140              }
141              if ($salt_requires_encoding) {
142                  // encode string with the Base64 variant used by crypt
143                  $base64_digits =
144                      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
145                  $bcrypt64_digits =
146                      './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
147   
148                  $base64_string = base64_encode($salt);
149                  $salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits);
150              }
151              $salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len);
152   
153              $hash = $hash_format . $salt;
154   
155              $ret = crypt($password, $hash);
156   
157              if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) {
158                  return false;
159              }
160   
161              return $ret;
162          }
163   
164          /**
165           * Get information about the password hash. Returns an array of the information
166           * that was used to generate the password hash.
167           *
168           * array(
169           *    'algo' => 1,
170           *    'algoName' => 'bcrypt',
171           *    'options' => array(
172           *        'cost' => PASSWORD_BCRYPT_DEFAULT_COST,
173           *    ),
174           * )
175           *
176           * @param string $hash The password hash to extract info from
177           *
178           * @return array The array of information about the hash.
179           */
180          function password_get_info($hash) {
181              $return = array(
182                  'algo' => 0,
183                  'algoName' => 'unknown',
184                  'options' => array(),
185              );
186              if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) {
187                  $return['algo'] = PASSWORD_BCRYPT;
188                  $return['algoName'] = 'bcrypt';
189                  list($cost) = sscanf($hash, "$2y$%d$");
190                  $return['options']['cost'] = $cost;
191              }
192              return $return;
193          }
194   
195          /**
196           * Determine if the password hash needs to be rehashed according to the options provided
197           *
198           * If the answer is true, after validating the password using password_verify, rehash it.
199           *
200           * @param string $hash    The hash to test
201           * @param int    $algo    The algorithm used for new password hashes
202           * @param array  $options The options array passed to password_hash
203           *
204           * @return boolean True if the password needs to be rehashed.
205           */
206          function password_needs_rehash($hash, $algo, array $options = array()) {
207              $info = password_get_info($hash);
208              if ($info['algo'] != $algo) {
209                  return true;
210              }
211              switch ($algo) {
212                  case PASSWORD_BCRYPT:
213                      $cost = isset($options['cost']) ? $options['cost'] : PASSWORD_BCRYPT_DEFAULT_COST;
214                      if ($cost != $info['options']['cost']) {
215                          return true;
216                      }
217                      break;
218              }
219              return false;
220          }
221   
222          /**
223           * Verify a password against a hash using a timing attack resistant approach
224           *
225           * @param string $password The password to verify
226           * @param string $hash     The hash to verify against
227           *
228           * @return boolean If the password matches the hash
229           */
230          function password_verify($password, $hash) {
231              if (!function_exists('crypt')) {
232                  trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
233                  return false;
234              }
235              $ret = crypt($password, $hash);
236              if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) {
237                  return false;
238              }
239   
240              $status = 0;
241              for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) {
242                  $status |= (ord($ret[$i]) ^ ord($hash[$i]));
243              }
244   
245              return $status === 0;
246          }
247      }
248   
249  }
250   
251  namespace PasswordCompat\binary {
252   
253      if (!function_exists('PasswordCompat\\binary\\_strlen')) {
254   
255          /**
256           * Count the number of bytes in a string
257           *
258           * We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension.
259           * In this case, strlen() will count the number of *characters* based on the internal encoding. A
260           * sequence of bytes might be regarded as a single multibyte character.
261           *
262           * @param string $binary_string The input string
263           *
264           * @internal
265           * @return int The number of bytes
266           */
267          function _strlen($binary_string) {
268              if (function_exists('mb_strlen')) {
269                  return mb_strlen($binary_string, '8bit');
270              }
271              return strlen($binary_string);
272          }
273   
274          /**
275           * Get a substring based on byte limits
276           *
277           * @see _strlen()
278           *
279           * @param string $binary_string The input string
280           * @param int    $start
281           * @param int    $length
282           *
283           * @internal
284           * @return string The substring
285           */
286          function _substr($binary_string, $start, $length) {
287              if (function_exists('mb_substr')) {
288                  return mb_substr($binary_string, $start, $length, '8bit');
289              }
290              return substr($binary_string, $start, $length);
291          }
292   
293          /**
294           * Check if current PHP version is compatible with the library
295           *
296           * @return boolean the check result
297           */
298          function check() {
299              static $pass = NULL;
300   
301              if (is_null($pass)) {
302                  if (function_exists('crypt')) {
303                      $hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
304                      $test = crypt("password", $hash);
305                      $pass = $test == $hash;
306                  } else {
307                      $pass = false;
308                  }
309              }
310              return $pass;
311          }
312   
313      }
314  }