00001 <?php
00002
00003
00022 define('DRUPAL_HASH_COUNT', 14);
00023
00027 define('DRUPAL_MIN_HASH_COUNT', 7);
00028
00032 define('DRUPAL_MAX_HASH_COUNT', 30);
00033
00037 function _password_itoa64() {
00038 return './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
00039 }
00040
00052 function _password_base64_encode($input, $count) {
00053 $output = '';
00054 $i = 0;
00055 $itoa64 = _password_itoa64();
00056 do {
00057 $value = ord($input[$i++]);
00058 $output .= $itoa64[$value & 0x3f];
00059 if ($i < $count) {
00060 $value |= ord($input[$i]) << 8;
00061 }
00062 $output .= $itoa64[($value >> 6) & 0x3f];
00063 if ($i++ >= $count) {
00064 break;
00065 }
00066 if ($i < $count) {
00067 $value |= ord($input[$i]) << 16;
00068 }
00069 $output .= $itoa64[($value >> 12) & 0x3f];
00070 if ($i++ >= $count) {
00071 break;
00072 }
00073 $output .= $itoa64[($value >> 18) & 0x3f];
00074 } while ($i < $count);
00075
00076 return $output;
00077 }
00078
00095 function _password_generate_salt($count_log2) {
00096 $output = '$P$';
00097
00098 $count_log2 = max($count_log2, DRUPAL_MIN_HASH_COUNT);
00099
00100
00101 $itoa64 = _password_itoa64();
00102 $output .= $itoa64[min($count_log2, DRUPAL_MAX_HASH_COUNT)];
00103
00104 $output .= _password_base64_encode(drupal_random_bytes(6), 6);
00105 return $output;
00106 }
00107
00124 function _password_crypt($password, $setting) {
00125
00126 $setting = substr($setting, 0, 12);
00127
00128 if (substr($setting, 0, 3) != '$P$') {
00129 return FALSE;
00130 }
00131 $count_log2 = _password_get_count_log2($setting);
00132
00133 if ($count_log2 < DRUPAL_MIN_HASH_COUNT || $count_log2 > DRUPAL_MAX_HASH_COUNT) {
00134 return FALSE;
00135 }
00136 $salt = substr($setting, 4, 8);
00137
00138 if (strlen($salt) != 8) {
00139 return FALSE;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148 $count = 1 << $count_log2;
00149
00150 $hash = md5($salt . $password, TRUE);
00151 do {
00152 $hash = md5($hash . $password, TRUE);
00153 } while (--$count);
00154
00155 $output = $setting . _password_base64_encode($hash, 16);
00156
00157 return (strlen($output) == 34) ? $output : FALSE;
00158 }
00159
00163 function _password_get_count_log2($setting) {
00164 $itoa64 = _password_itoa64();
00165 return strpos($itoa64, $setting[3]);
00166 }
00167
00180 function user_hash_password($password, $count_log2 = 0) {
00181 if (empty($count_log2)) {
00182
00183 $count_log2 = variable_get('password_count_log2', DRUPAL_HASH_COUNT);
00184 }
00185 return _password_crypt($password, _password_generate_salt($count_log2));
00186 }
00187
00203 function user_check_password($password, $account) {
00204 if (substr($account->pass, 0, 3) == 'U$P') {
00205
00206
00207 $stored_hash = substr($account->pass, 1);
00208 $password = md5($password);
00209 }
00210 else {
00211 $stored_hash = $account->pass;
00212 }
00213 $hash = _password_crypt($password, $stored_hash);
00214 return ($hash && $stored_hash == $hash);
00215 }
00216
00235 function user_needs_new_hash($account) {
00236
00237 if ((substr($account->pass, 0, 3) != '$P$') || (strlen($account->pass) != 34)) {
00238 return TRUE;
00239 }
00240
00241 return (_password_get_count_log2($account->pass) != variable_get('password_count_log2', DRUPAL_HASH_COUNT));
00242 }
00243