Permalink
Browse files

merge in lib_password/bcrypt stuff even though it is currently unnece…

…ssary
  • Loading branch information...
1 parent 734bfeb commit 09a60e4e1ee041e491ed2cf61e7e4e1069e95c43 straup committed Jun 12, 2012
@@ -29,8 +29,7 @@
$ok = 1;
- if (login_encrypt_password($old_pass) !== $GLOBALS['cfg']['user']['password']){
-
+ if (! passwords_validate_password_for_user($old_pass, $GLOBALS['cfg']['user'])){
$smarty->assign('error_oldpass_mismatch', 1);
$ok = 0;
}
@@ -48,10 +47,7 @@
}
if ($ok){
-
- $rsp = users_update_password($GLOBALS['cfg']['user'], $new_pass1);
-
- if (! $rsp['ok']){
+ if (! users_update_password($GLOBALS['cfg']['user'], $new_pass1)){
$smarty->assign('error_fail', 1);
$ok = 0;
@@ -213,6 +213,7 @@ function handle_error_notices($errno, $errstr){
}
loadlib('features');
+ loadlib('passwords');
loadlib('error');
loadlib('sanitize');
loadlib('db');
@@ -222,10 +223,7 @@ function handle_error_notices($errno, $errstr){
loadlib('crumb');
loadlib('login');
loadlib('email');
- #loadlib('args');
- #loadlib('calendar');
loadlib('users');
- #loadlib('versions');
loadlib('http');
loadlib('sanitize');
loadlib('filter');
@@ -0,0 +1,105 @@
+<?php
+#
+# lib_bcrypt - bcrypt hashing in PHP
+#
+# Based on Portable PHP password hashing framework:
+#
+# http://www.openwall.com/phpass/
+#
+# There's absolutely no warranty.
+#
+class BCryptHasher {
+ private $random_state;
+
+ function BCryptHasher()
+ {
+ if (CRYPT_BLOWFISH != 1) die("lib_bcyrpt requires CRYPT_BLOWFISH PHP support!");
+
+ $this->random_state = microtime();
+ if (function_exists('getmypid'))
+ $this->random_state .= getmypid();
+ }
+
+ function get_random_bytes($count)
+ {
+ $output = '';
+ if (is_readable('/dev/urandom') &&
+ ($fh = @fopen('/dev/urandom', 'rb'))) {
+ $output = fread($fh, $count);
+ fclose($fh);
+ }
+
+ if (strlen($output) < $count) {
+ $output = '';
+ for ($i = 0; $i < $count; $i += 16) {
+ $this->random_state =
+ md5(microtime() . $this->random_state);
+ $output .=
+ pack('H*', md5($this->random_state));
+ }
+ $output = substr($output, 0, $count);
+ }
+
+ return $output;
+ }
+
+ function gensalt_blowfish($input, $work_factor)
+ {
+ # This one needs to use a different order of characters and a
+ # different encoding scheme from the one in encode64() in phpass.
+ # We care because the last character in our encoded string will
+ # only represent 2 bits. While two known implementations of
+ # bcrypt will happily accept and correct a salt string which
+ # has the 4 unused bits set to non-zero, we do not want to take
+ # chances and we also do not want to waste an additional byte
+ # of entropy.
+ $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+
+ $output = '$2a$';
+ $output .= chr(ord('0') + $work_factor / 10);
+ $output .= chr(ord('0') + $work_factor % 10);
+ $output .= '$';
+
+ $i = 0;
+ do {
+ $c1 = ord($input[$i++]);
+ $output .= $itoa64[$c1 >> 2];
+ $c1 = ($c1 & 0x03) << 4;
+ if ($i >= 16) {
+ $output .= $itoa64[$c1];
+ break;
+ }
+
+ $c2 = ord($input[$i++]);
+ $c1 |= $c2 >> 4;
+ $output .= $itoa64[$c1];
+ $c1 = ($c2 & 0x0f) << 2;
+
+ $c2 = ord($input[$i++]);
+ $c1 |= $c2 >> 6;
+ $output .= $itoa64[$c1];
+ $output .= $itoa64[$c2 & 0x3f];
+ } while (1);
+
+ return $output;
+ }
+
+ function HashPassword($password, $work_factor=8)
+ {
+ if ($work_factor < 4 || $work_factor > 31) $work_factor = 8;
+
+ $random = $this->get_random_bytes(16);
+ $salt = $this->gensalt_blowfish($random, $work_factor);
+ $hash = crypt($password, $salt);
+ if (strlen($hash) == 60) return $hash;
+ return '*';
+ }
+
+ function CheckPassword($password, $stored_hash)
+ {
+ $hash = crypt($password, $stored_hash);
+ return $hash == $stored_hash;
+ }
+}
+
+?>
@@ -137,12 +137,6 @@ function login_generate_auth_cookie(&$user){
#################################################################
- function login_encrypt_password($pass){
- return hash_hmac("sha256", $pass, $GLOBALS['cfg']['crypto_password_secret']);
- }
-
- #################################################################
-
function login_get_cookie($name){
return $_COOKIE[$name];
}
@@ -0,0 +1,99 @@
+<?php
+
+ $GLOBALS['passwords_canhas_bcrypt'] = 0;
+
+ if (CRYPT_BLOWFISH){
+ $GLOBALS['passwords_canhas_bcrypt'] = 1;
+ loadlib("bcrypt");
+ }
+
+ #################################################################
+
+ function passwords_encrypt_password($password, $more=array()){
+
+ $defaults = array(
+ 'use_bcrypt' => 1
+ );
+
+ $more = array_merge($defaults, $more);
+
+ if (($GLOBALS['passwords_canhas_bcrypt']) && ($more['use_bcrypt'])){
+ $h = new BCryptHasher();
+ return $h->HashPassword($password);
+ }
+
+ return hash_hmac("sha256", $password, $GLOBALS['cfg']['crypto_password_secret']);
+ }
+
+ #################################################################
+
+ function passwords_validate_password($password, $enc_password, $more=array()){
+
+ $defaults = array(
+ 'use_bcrypt' => 1
+ );
+
+ $more = array_merge($defaults, $more);
+
+ if (($GLOBALS['passwords_canhas_bcrypt']) && ($more['use_bcrypt'])){
+ $h = new BCryptHasher();
+ return $h->CheckPassword($password, $enc_password);
+ }
+
+ $test = passwords_encrypt_password($password, $more);
+
+ $len_test = strlen($test);
+ $len_pswd = strlen($enc_password);
+
+ if ($len_test != $len_pswd){
+ return 0;
+ }
+
+ for ($i=0; $i < $len_test; $i++){
+
+ if ($test[$i] != $enc_password[$i]){
+ return 0;
+ }
+ }
+
+ return 1;
+ }
+
+ #################################################################
+
+ # Basically a helper function to save a tiny amount of typing but
+ # mostly to make it easier to ensure that user passwords are encrypted
+ # using the "safe thing", which is currently bcrypt (20120611/straup)
+
+ function passwords_validate_password_for_user($password, &$user, $more=array()){
+
+ $defaults = array(
+ 'ensure_bcrypt' => 1,
+ );
+
+ $more = array_merge($defaults, $more);
+
+ $enc_password = $user['password'];
+
+ $is_bcrypt = (substr($enc_password, 0, 4) == '$2a$') ? 1 : 0;
+
+ $validate_more = array(
+ 'use_bcrypt' => $is_bcrypt,
+ );
+
+ $is_ok = passwords_validate_password($password, $enc_password, $validate_more);
+
+ if (($is_ok) && (! $is_bcrypt) && ($more['ensure_bcrypt']) && ($GLOBALS['passwords_canhas_bcrypt'])){
+
+ # note the pass-by-ref above
+
+ if (users_update_password($user, $password)){
+ $user = users_get_by_id($user['id']);
+ }
+ }
+
+ return $is_ok;
+ }
+
+ #################################################################
+?>
@@ -23,7 +23,7 @@ function users_create_user($user){
loadlib('random');
- $user['password'] = login_encrypt_password($user['password']);
+ $user['password'] = passwords_encrypt_password($user['password']);
$user['created'] = time();
$user['conf_code'] = random_string(24);
@@ -86,7 +86,7 @@ function users_update_user(&$user, $update){
function users_update_password(&$user, $new_password){
- $enc_password = login_encrypt_password($new_password);
+ $enc_password = passwords_encrypt_password($new_password);
return users_update_user($user, array(
'password' => AddSlashes($enc_password),
@@ -175,7 +175,7 @@ function users_get_by_login($email, $password){
return null;
}
- if ($user['password'] != login_encrypt_password($password)){
+ if (! passwords_validate_password($password, $user['password'])){
return null;
}
View
@@ -5,10 +5,7 @@
include("include/init.php");
- if (!$GLOBALS['cfg']['enable_feature_signin']){
- $smarty->display('page_signin_disabled.txt');
- exit;
- }
+ features_ensure_enabled("signin");
login_ensure_loggedout();
@@ -77,10 +74,8 @@
#
if ($ok){
- $enc_password = login_encrypt_password($password, $GLOBALS['cfg']['crypto_password_secret']);
-
- if ($enc_password != $user['password']){
+ if (! passwords_validate_password_for_user($password, $user)){
$smarty->assign('error_password', 1);
$ok = 0;
}
@@ -105,4 +100,4 @@
#
$smarty->display('page_signin.txt');
-?>
+?>
View
@@ -28,10 +28,6 @@
exit;
}
-
- #
- # output
- #
-
$smarty->display("page_signout.txt");
+ exit();
?>
@@ -1,19 +1,18 @@
{assign var="page_title" value="Change your password"}
{include file="inc_head.txt"}
-{include file="inc_account_head.txt"}
{if $error_oldpass_mismatch} <p class="error">Incorrect old password.</p>{/if}
{if $error_newpass_empty} <p class="error">Please choose a new password.</p>{/if}
{if $error_newpass_mismatch} <p class="error">Your new passwords need to match.</p>{/if}
{if $error_fail} <p class="error">Unknown failure :(</p>{/if}
-<form action="/account/password/" method="post" accept-encoding="UTF-8">
+<form action="{$cfg.abs_root_url}account/password/" method="post" accept-encoding="UTF-8">
<input type="hidden" name="change" value="1" />
{$crumb_key|crumb_input}
<input type="password" name="old_password" size="40" value="" /><label for="old_password">your current password</label><br />
<input type="password" name="new_password1" size="40" value="" /><label for="new_password1">your new password</label><br />
<input type="password" name="new_password2" size="40" value="" /><label for="new_password2">your new password (again)</label><br />
<input type="SUBMIT" value="CHANGE MY PASSWORD" />
</form>
-
+
{include file="inc_foot.txt"}
@@ -7,7 +7,7 @@
{if $error_notsent} <p class="error">Something went wrong :(</p>{/if}
-<form action="/forgot/" method="post" accept-encoding="UTF-8">
+<form action="{$cfg.abs_root_url}forgot/" method="post" accept-encoding="UTF-8">
<input type="hidden" name="remind" value="1" />
<label for="email">Email:</label> <input type="text" name="email" size="40" value="" /><br />
<input type="SUBMIT" value="SEND PASSWORD REMINDER" />
@@ -1,16 +1,12 @@
{assign var='page_title' value='Sign in'}
{include file='inc_head.txt'}
-{if $error.signin_disabled}
-<p class="error">Sign ins are currently disabled.</p>
-{else}
-
{if $error_missing} <p class="error">Please enter your email address and password.</p>{/if}
{if $error_nouser} <p class="error">Sorry, we can't find an account with that email address.</p>{/if}
{if $error_deleted} <p class="error">Account has been deleted.</p>{/if}
{if $error_password} <p class="error">Incorrect password.</p>{/if}
-<form action="/signin/" method="post" accept-encoding="UTF-8">
+<form action="{$cfg.abs_root_url}signin/" method="post" accept-encoding="UTF-8">
<input type="text" name="email" size="40" value="{$email|escape}" /><label for="email">email address</label><br />
<input type="password" name="password" size="40" /><label for="password">password</label><br />
<input type="hidden" name="signin" value="1" />
@@ -19,7 +15,7 @@
</form>
{if $cfg.enable_feature_password_retrieval}
-<p><a href="/forgot/">Forgotten your password?</a></p>
+<p><a href="{$cfg.abs_root_url}forgot/">Forgotten your password?</a></p>
{/if}
{include file='inc_foot.txt'}

0 comments on commit 09a60e4

Please sign in to comment.