Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. /* Poweradmin, a friendly web-based admin tool for PowerDNS.
  3. * See <http://www.poweradmin.org> for more details.
  4. *
  5. * Copyright 2007-2009 Rejo Zenger <rejo@zenger.nl>
  6. * Copyright 2010-2016 Poweradmin Development Team
  7. * <http://www.poweradmin.org/credits.html>
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. /**
  23. * Password functions
  24. *
  25. * @package Poweradmin
  26. * @copyright 2007-2010 Rejo Zenger <rejo@zenger.nl>
  27. * @copyright 2010-2016 Poweradmin Development Team
  28. * @license http://opensource.org/licenses/GPL-3.0 GPL
  29. */
  30. namespace Poweradmin;
  31. class Password {
  32. /**
  33. * Generate random salt for encryption
  34. *
  35. * @param int $len salt length (default=5)
  36. *
  37. * @return string salt string
  38. */
  39. public static function salt($len = 5) {
  40. $valid_characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890@#$%^*()_-!';
  41. $valid_len = strlen($valid_characters) - 1;
  42. $salt = '';
  43. for ($i = 0; $i < $len; $i++) {
  44. $salt .= $valid_characters[mt_rand(0, $valid_len)];
  45. }
  46. return $salt;
  47. }
  48. public static function hash($password) {
  49. global $password_encryption, $password_encryption_cost;
  50. if ($password_encryption === 'md5salt') {
  51. return self::gen_mix_salt($password);
  52. } elseif ($password_encryption === 'bcrypt') {
  53. return password_hash($password, PASSWORD_BCRYPT, array('cost' => $password_encryption_cost));
  54. } else {
  55. return md5($password);
  56. }
  57. }
  58. public static function verify($password, $hash) {
  59. global $password_encryption;
  60. if ($password_encryption === 'md5salt') {
  61. return self::_strsafecmp(self::mix_salt(self::extract_salt($hash), $password), $hash);
  62. } elseif ($password_encryption === 'bcrypt') {
  63. return password_verify($password, $hash);
  64. } else {
  65. return self::_strsafecmp(md5($password), $hash);
  66. }
  67. }
  68. public static function needs_rehash($hash) {
  69. // @todo
  70. }
  71. /**
  72. * Generate random salt and salted password
  73. *
  74. * @param string $pass password
  75. *
  76. * @return string salted password
  77. */
  78. private static function gen_mix_salt($pass) {
  79. $salt = self::salt();
  80. return self::mix_salt($salt, $pass);
  81. }
  82. /**
  83. * Generate salted password
  84. *
  85. * @param string $salt salt
  86. * @param string $pass password
  87. *
  88. * @return string salted password
  89. */
  90. private static function mix_salt($salt, $pass) {
  91. return md5($salt . $pass) . ':' . $salt;
  92. }
  93. /**
  94. * Extract salt from password
  95. *
  96. * @param string $password salted password
  97. *
  98. * @return string salt
  99. */
  100. private static function extract_salt($password) {
  101. return substr(strstr($password, ':'), 1);
  102. }
  103. /**
  104. * Count the number of bytes in a string
  105. * @see https://github.com/ircmaxell/password_compat
  106. *
  107. * @param string $binary_string The input string
  108. *
  109. * @return int The number of bytes
  110. */
  111. private static function _strlen($binary_string) {
  112. if (function_exists('mb_strlen')) {
  113. return mb_strlen($binary_string, '8bit');
  114. }
  115. return strlen($binary_string);
  116. }
  117. /**
  118. *
  119. * @see https://github.com/ircmaxell/password_compat
  120. *
  121. * @param string $str1 The first string
  122. * @param string $str2 The second string
  123. *
  124. * @return bool true if they are equal, otherwise - false
  125. */
  126. private static function _strsafecmp($str1, $str2) {
  127. if (!is_string($str1) || !is_string($str2) || self::_strlen($str1) !== self::_strlen($str2)) {
  128. return false;
  129. }
  130. $status = 0;
  131. for ($i = 0; $i < self::_strlen($str1); $i++) {
  132. $status |= (ord($str1[$i]) ^ ord($str2[$i]));
  133. }
  134. return $status === 0;
  135. }
  136. }