modhashing.class.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <?php
  2. /*
  3. * This file is part of MODX Revolution.
  4. *
  5. * Copyright (c) MODX, LLC. All Rights Reserved.
  6. *
  7. * For complete copyright and license information, see the COPYRIGHT and LICENSE
  8. * files found in the top-level directory of this distribution.
  9. */
  10. /**
  11. * This file contains the modHashing service class definition and the modHash abstract implementation class.
  12. * @package modx
  13. * @subpackage hashing
  14. */
  15. /**
  16. * The modX hashing service class.
  17. *
  18. * @package modx
  19. * @subpackage hashing
  20. */
  21. class modHashing {
  22. /**
  23. * A reference to an xPDO instance communicating with this service instance.
  24. *
  25. * Though this is typically a modX instance, an xPDO instance must work for new installs.
  26. * @var xPDO
  27. */
  28. public $modx= null;
  29. /**
  30. * An array of options for the hashing service.
  31. * @var array
  32. */
  33. public $options= array();
  34. /**
  35. * An array of loaded modHash implementations.
  36. * @var array
  37. */
  38. protected $_hashes= array();
  39. /**
  40. * Constructs a new instance of the modHashing service class.
  41. *
  42. * @param xPDO &$modx A reference to an modX (or xPDO) instance.
  43. * @param array|null $options An array of options for the hashing service.
  44. */
  45. function __construct(xPDO &$modx, $options= array()) {
  46. $this->modx= & $modx;
  47. if (is_array($options)) {
  48. $this->options = $options;
  49. }
  50. }
  51. /**
  52. * Get an option for the MODX hashing service.
  53. *
  54. * Searches for local options and then prefixes keys with encrypt_ to look for
  55. * MODX System Settings.
  56. *
  57. * @param string $key The option key to get a value for.
  58. * @param array|null $options An optional array of options to look in first.
  59. * @param mixed $default An optional default value to return if no value is set.
  60. * @return mixed The option value or the specified default if not found.
  61. */
  62. public function getOption($key, $options = null, $default = null) {
  63. if (is_array($options) && array_key_exists($key, $options)) {
  64. $option = $options[$key];
  65. } elseif (array_key_exists($key, $this->options)) {
  66. $option = $this->options[$key];
  67. } else {
  68. $option = $this->modx->getOption('hashing_' . $key, $this->options, $default);
  69. }
  70. return $option;
  71. }
  72. /**
  73. * Get a hash implementation instance.
  74. *
  75. * The implementation is made available as a member variable of the modHashing service.
  76. *
  77. * @param string $key A key string identifying the instance; must be a valid PHP variable name.
  78. * @param string $class A valid fully-qualified modHash derivative class name
  79. * @param array|null $options An optional array of hash options.
  80. * @return modHash|null A reference to a modHash instance or null if could not be instantiated.
  81. */
  82. public function getHash($key, $class, $options = array()) {
  83. $className = $this->modx->loadClass($class, '', false, true);
  84. if ($className) {
  85. if (empty($key)) $key = strtolower(str_replace('mod', '', $className));
  86. if (!array_key_exists($key, $this->_hashes)) {
  87. $hash = new $className($this, $options);
  88. if ($hash instanceof $className) {
  89. $this->_hashes[$key] = $hash;
  90. $this->$key =& $this->_hashes[$key];
  91. }
  92. }
  93. if (array_key_exists($key, $this->_hashes)) {
  94. return $this->_hashes[$key];
  95. }
  96. }
  97. return null;
  98. }
  99. }
  100. /**
  101. * Defines the interface for a modHash implementation.
  102. *
  103. * @abstract Implement a derivative of this class to define an actual hash algorithm implementation.
  104. * @package modx
  105. * @subpackage hashing
  106. */
  107. abstract class modHash {
  108. /**
  109. * A reference to the modHashing service hosting this modHash instance.
  110. * @var modHashing
  111. */
  112. public $host= null;
  113. /**
  114. * An array of options for the modHash implementation.
  115. * @var array
  116. */
  117. public $options= array();
  118. /**
  119. * Constructs a new instance of the modHash class.
  120. *
  121. * @param modHashing $host A reference to the modHashing instance
  122. * @param array|null $options An optional array of configuration options
  123. * @return modHash A new derivative instance of the modHash class
  124. */
  125. public function __construct(modHashing &$host, $options= array()) {
  126. $this->host =& $host;
  127. if (is_array($options)) {
  128. $this->options = $options;
  129. }
  130. }
  131. /**
  132. * Get an option for this modHash implementation
  133. *
  134. * Searches for local options and then prefixes keys with hashing_ to look for
  135. * MODX System Settings.
  136. *
  137. * @param string $key The option key to get a value for.
  138. * @param array|null $options An optional array of options to look in first.
  139. * @param mixed $default An optional default value to return if no value is set.
  140. * @return mixed The option value or the specified default if not found.
  141. */
  142. public function getOption($key, $options = null, $default = null) {
  143. if (is_array($options) && array_key_exists($key, $options)) {
  144. $option = $options[$key];
  145. } else {
  146. $option = $this->host->getOption($key, $this->options, $default);
  147. }
  148. return $option;
  149. }
  150. /**
  151. * Generate a hash of the given string using the provided options.
  152. *
  153. * @abstract
  154. * @param string $string A string to generate a secure hash from.
  155. * @param array $options An array of options to be passed to the hash implementation.
  156. * @return mixed The hash result or false on failure.
  157. */
  158. public abstract function hash($string, array $options = array());
  159. /**
  160. * Verifies if $string, when hashed according to this hash implementation, matches the stored hash in $expected.
  161. *
  162. * @param string $string
  163. * @param string $expected
  164. * @param array $options Implementation-specific hash options.
  165. * @return bool
  166. */
  167. public function verify($string, $expected, array $options = array())
  168. {
  169. $hashedPassword = $this->hash($string, $options);
  170. return $expected === $hashedPassword;
  171. }
  172. }