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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
password.php
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 }