[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/password/ -> Password.php (source)

   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  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1