[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Implements the Password class for the MediaWiki software. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 * http://www.gnu.org/copyleft/gpl.html 19 * 20 * @file 21 */ 22 23 /** 24 * Represents a password hash for use in authentication 25 * 26 * Note: All password types are transparently prefixed with :<TYPE>:, where <TYPE> 27 * is the registered type of the hash. This prefix is stripped in the constructor 28 * and is added back in the toString() function. 29 * 30 * When inheriting this class, there are a couple of expectations 31 * to be fulfilled: 32 * * If Password::toString() is called on an object, and the result is passed back in 33 * to PasswordFactory::newFromCiphertext(), the result will be identical to the original. 34 * * The string representations of two Password objects are equal only if 35 * the original plaintext passwords match. In other words, if the toString() result of 36 * two objects match, the passwords are the same, and the user will be logged in. 37 * Since the string representation of a hash includes its type name (@see Password::toString), 38 * this property is preserved across all classes that inherit Password. 39 * If a hashing scheme does not fulfill this expectation, it must make sure to override the 40 * Password::equals() function and use custom comparison logic. However, this is not 41 * recommended unless absolutely required by the hashing mechanism. 42 * With these two points in mind, when creating a new Password sub-class, there are some functions 43 * you have to override (because they are abstract) and others that you may want to override. 44 * 45 * The abstract functions that must be overridden are: 46 * * Password::crypt(), which takes a plaintext password and hashes it into a string hash suitable 47 * for being passed to the constructor of that class, and then stores that hash (and whatever 48 * other data) into the internal state of the object. 49 * The functions that can optionally be overridden are: 50 * * Password::parseHash(), which can be useful to override if you need to extract values from or 51 * otherwise parse a password hash when it's passed to the constructor. 52 * * Password::needsUpdate(), which can be useful if a specific password hash has different 53 * logic for when the hash needs to be updated. 54 * * Password::toString(), which can be useful if the hash was changed in the constructor and 55 * needs to be re-assembled before being returned as a string. This function is expected to add 56 * the type back on to the hash, so make sure to do that if you override the function. 57 * * Password::equals() - This function compares two Password objects to see if they are equal. 58 * The default is to just do a timing-safe string comparison on the $this->hash values. 59 * 60 * After creating a new password hash type, it can be registered using the static 61 * Password::register() method. The default type is set using the Password::setDefaultType() type. 62 * Types must be registered before they can be set as the default. 63 * 64 * @since 1.24 65 */ 66 abstract class Password { 67 /** 68 * @var PasswordFactory Factory that created the object 69 */ 70 protected $factory; 71 72 /** 73 * String representation of the hash without the type 74 * @var string 75 */ 76 protected $hash; 77 78 /** 79 * Array of configuration variables injected from the constructor 80 * @var array 81 */ 82 protected $config; 83 84 /** 85 * Construct the Password object using a string hash 86 * 87 * It is strongly recommended not to call this function directly unless you 88 * have a reason to. Use the PasswordFactory class instead. 89 * 90 * @throws MWException If $config does not contain required parameters 91 * 92 * @param PasswordFactory $factory Factory object that created the password 93 * @param array $config Array of engine configuration options for hashing 94 * @param string|null $hash The raw hash, including the type 95 */ 96 final public function __construct( PasswordFactory $factory, array $config, $hash = null ) { 97 if ( !isset( $config['type'] ) ) { 98 throw new MWException( 'Password configuration must contain a type name.' ); 99 } 100 $this->config = $config; 101 $this->factory = $factory; 102 103 if ( $hash !== null && strlen( $hash ) >= 3 ) { 104 // Strip the type from the hash for parsing 105 $hash = substr( $hash, strpos( $hash, ':', 1 ) + 1 ); 106 } 107 108 $this->hash = $hash; 109 $this->parseHash( $hash ); 110 } 111 112 /** 113 * Get the type name of the password 114 * 115 * @return string Password type 116 */ 117 final public function getType() { 118 return $this->config['type']; 119 } 120 121 /** 122 * Perform any parsing necessary on the hash to see if the hash is valid 123 * and/or to perform logic for seeing if the hash needs updating. 124 * 125 * @param string $hash The hash, with the :<TYPE>: prefix stripped 126 * @throws PasswordError If there is an error in parsing the hash 127 */ 128 protected function parseHash( $hash ) { 129 } 130 131 /** 132 * Determine if the hash needs to be updated 133 * 134 * @return bool True if needs update, false otherwise 135 */ 136 public function needsUpdate() { 137 } 138 139 /** 140 * Compare one Password object to this object 141 * 142 * By default, do a timing-safe string comparison on the result of 143 * Password::toString() for each object. This can be overridden to do 144 * custom comparison, but it is not recommended unless necessary. 145 * 146 * @param Password|string $other The other password 147 * @return bool True if equal, false otherwise 148 */ 149 public function equals( $other ) { 150 if ( !$other instanceof self ) { 151 // No need to use the factory because we're definitely making 152 // an object of the same type. 153 $obj = clone $this; 154 $obj->crypt( $other ); 155 $other = $obj; 156 } 157 158 return hash_equals( $this->toString(), $other->toString() ); 159 } 160 161 /** 162 * Convert this hash to a string that can be stored in the database 163 * 164 * The resulting string should be considered the seralized representation 165 * of this hash, i.e., if the return value were recycled back into 166 * PasswordFactory::newFromCiphertext, the returned object would be equivalent to 167 * this; also, if two objects return the same value from this function, they 168 * are considered equivalent. 169 * 170 * @return string 171 */ 172 public function toString() { 173 return ':' . $this->config['type'] . ':' . $this->hash; 174 } 175 176 /** 177 * Hash a password and store the result in this object 178 * 179 * The result of the password hash should be put into the internal 180 * state of the hash object. 181 * 182 * @param string $password Password to hash 183 * @throws PasswordError If an internal error occurs in hashing 184 */ 185 abstract public function crypt( $password ); 186 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |