summaryrefslogtreecommitdiff
path: root/lib/VNDB/Util/Auth.pm
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2014-10-15 12:34:40 +0200
committerYorhel <git@yorhel.nl>2014-10-15 12:34:40 +0200
commit2640d51d745bdbd85bf52f92aa4ed46253ccf99d (patch)
tree8536f89531cd6bb8e12fcd1f68dd16b530b491f4 /lib/VNDB/Util/Auth.pm
parenta1b4da1d3ae9e6ed9326df41f9831be81f6b839a (diff)
SQL: Merge users.(passwd|salt) in one column + document values
It doesn't make a whole lot to separate the hashed password and the salt from each other, you need both to do anything with them, and from the database perspective they're both completely opaque strings only usable for direct comparison with other hashed strings. This change is mostly as preparation for switching to a proper key derivation function (sha256 isn't...) and to add support for longer and/or binary salt. Because the passwd field now needs to be interpreted in Perl, it's being passed around as a binary string rather than a hex-encoded value. API login is broken in this commit. I'll get to that.
Diffstat (limited to 'lib/VNDB/Util/Auth.pm')
-rw-r--r--lib/VNDB/Util/Auth.pm43
1 files changed, 17 insertions, 26 deletions
diff --git a/lib/VNDB/Util/Auth.pm b/lib/VNDB/Util/Auth.pm
index 89cbd215..63812d36 100644
--- a/lib/VNDB/Util/Auth.pm
+++ b/lib/VNDB/Util/Auth.pm
@@ -5,7 +5,7 @@ package VNDB::Util::Auth;
use strict;
use warnings;
use Exporter 'import';
-use Digest::SHA qw|sha1_hex sha256_hex|;
+use Digest::SHA qw|sha1 sha1_hex sha256|;
use Time::HiRes;
use Encode 'encode_utf8';
use POSIX 'strftime';
@@ -30,7 +30,7 @@ sub authInit {
my $token = substr($cookie, 0, 40);
my $uid = substr($cookie, 40);
$self->{_auth} = $uid =~ /^\d+$/ && $self->dbUserGet(uid => $uid, session => $token, what => 'extended notifycount prefs')->[0];
- # update the sessions.lastused column if lastused < now()'6 hours'
+ # update the sessions.lastused column if lastused < now()-'6 hours'
$self->dbSessionUpdateLastUsed($uid, $token) if $self->{_auth} && $self->{_auth}{session_lastused} < time()-6*3600;
return $self->resCookie(auth => undef) if !$self->{_auth};
}
@@ -103,9 +103,9 @@ sub _authCheck {
return 0 if !$user || length($user) > 15 || length($user) < 2 || !$pass;
my $d = $self->dbUserGet(username => $user, what => 'extended notifycount')->[0];
- return 0 if !$d->{id} || $d->{salt} =~ /^ *$/;
+ return 0 if !$d->{id} || length $d->{passwd} != 41;
- if(_authEncryptPass($self, $pass, $d->{salt}) eq $d->{passwd}) {
+ if($self->authPreparePass($pass, substr $d->{passwd}, 0, 9) eq $d->{passwd}) {
$self->{_auth} = $d;
return 1;
}
@@ -114,43 +114,34 @@ sub _authCheck {
}
-# Encryption algorithm for user passwords
-# Arguments: self, pass, salt
-# Returns: encrypted password (in hex)
-sub _authEncryptPass {
- my($self, $pass, $salt, $bin) = @_;
- return sha256_hex($self->{global_salt} . encode_utf8($pass) . encode_utf8($salt));
-}
-
-
# Prepares a plaintext password for database storage
-# Arguments: pass
-# Returns: list (pass, salt)
+# Arguments: pass, optionally salt
+# Returns: encrypted password (as a binary string)
sub authPreparePass {
- my($self, $pass) = @_;
- my $salt = join '', map chr(rand(93)+33), 1..9;
- my $hash = _authEncryptPass($self, $pass, $salt);
- return ($hash, $salt);
+ my($self, $pass, $salt) = @_;
+ $salt ||= encode_utf8(join '', map chr(rand(93)+33), 1..9);
+ return $salt.sha256($self->{global_salt} . encode_utf8($pass) . $salt);
}
# Generates a random token that can be used to reset the password.
-# Returns: token, token-encrypted, salt
+# Returns: token (hex string), token-encrypted (binary string)
sub authPrepareReset {
my $self = shift;
my $token = sha1_hex(join('', Time::HiRes::gettimeofday()) . join('', map chr(rand(93)+33), 1..9));
my $salt = join '', map chr(rand(93)+33), 1..9;
- my $token_e = sha1_hex(lc($token).$salt);
- return ($token, $token_e, $salt);
+ my $token_e = encode_utf8($salt) . sha1(lc($token).$salt);
+ return ($token, $token_e);
}
# Checks whether the password reset token is valid.
-# Arguments: $u obj, token
+# Arguments: passwd (binary string), token (hex string)
sub authValidateReset {
- my($self, $u, $t) = @_;
- return 0 if !$u->{salt} || !$u->{passwd} || length $u->{passwd} != 40
- || lc sha1_hex(lc($t).$u->{salt}) ne lc $u->{passwd};
+ my($self, $passwd, $token) = @_;
+ return 0 if length $passwd != 29;
+ my $salt = substr $passwd, 0, 9;
+ return 0 if $salt.sha1(lc($token).$salt) ne $passwd;
return 1;
}