X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FAuth%2FDB.pm;h=dd6350623f1a7451c1e187b5d727185652eebe5a;hb=27ffa16a85221662dee49da0f210312383341240;hp=d4e4d48ccad1a83a099a9fef7314b8664d13c85d;hpb=c510d88bbfea6818ffafaddb7286e88aec96d3b8;p=kivitendo-erp.git diff --git a/SL/Auth/DB.pm b/SL/Auth/DB.pm index d4e4d48cc..dd6350623 100644 --- a/SL/Auth/DB.pm +++ b/SL/Auth/DB.pm @@ -1,11 +1,12 @@ package SL::Auth::DB; -use DBI; +use strict; -#use SL::Auth; -use SL::DBUtils; +use Carp; +use Scalar::Util qw(weaken); -use strict; +use SL::Auth::Constants qw(:all); +use SL::DBUtils; sub new { $main::lxdebug->enter_sub(); @@ -14,6 +15,7 @@ sub new { my $self = {}; $self->{auth} = shift; + weaken $self->{auth}; bless $self, $type; @@ -28,24 +30,28 @@ sub authenticate { my $self = shift; my $login = shift; my $password = shift; - my $is_crypted = shift; my $dbh = $self->{auth}->dbconnect(); if (!$dbh) { $main::lxdebug->leave_sub(); - return SL::Auth->ERR_BACKEND(); + return ERR_BACKEND; } my $query = qq|SELECT password FROM auth."user" WHERE login = ?|; my ($stored_password) = $dbh->selectrow_array($query, undef, $login); - $password = crypt $password, substr($login, 0, 2) if (!$password || !$is_crypted); - $stored_password = crypt $stored_password, substr($login, 0, 2) if (!$stored_password); + my ($algorithm, $algorithm2); + + # Empty password hashes in the database mean just that -- empty + # passwords. Hash it for easier comparison. + $stored_password = $self->hash_password(password => $stored_password) unless $stored_password; + ($algorithm, $stored_password) = $self->parse_password_entry($stored_password); + ($algorithm2, $password) = $self->parse_password_entry($self->hash_password(password => $password, algorithm => $algorithm, login => $login)); $main::lxdebug->leave_sub(); - return $password eq $stored_password ? SL::Auth->OK() : SL::Auth->ERR_PASSWORD(); + return $password eq $stored_password ? OK : ERR_PASSWORD; } sub can_change_password { @@ -64,10 +70,10 @@ sub change_password { if (!$dbh) { $main::lxdebug->leave_sub(); - return SL::Auth->ERR_BACKEND() + return ERR_BACKEND; } - $password = crypt $password, substr($login, 0, 2) if (!$is_crypted); + $password = $self->hash_password(password => $password) unless $is_crypted; do_query($main::form, $dbh, qq|UPDATE auth."user" SET password = ? WHERE login = ?|, $password, $login); @@ -82,4 +88,42 @@ sub verify_config { return 1; } +sub hash_password { + my ($self, %params) = @_; + + if (!$params{algorithm}) { + $params{algorithm} = 'SHA1'; + $params{fallback_algorithm} = 'MD5'; + } + + if ($params{algorithm} eq 'SHA1') { + if (eval { require Digest::SHA1; 1 }) { + return '{SHA1}' . Digest::SHA1::sha1_hex($params{password}); + + } elsif ($params{fallback_algorithm}) { + return $self->hash_password(%params, algorithm => $params{fallback_algorithm}); + + } else { + die 'Digest::SHA1 not available'; + } + + } elsif ($params{algorithm} eq 'MD5') { + require Digest::MD5; + return '{MD5}' . Digest::MD5::md5_hex($params{password}); + + } elsif ($params{algorithm} eq 'CRYPT') { + return '{CRYPT}' . crypt($params{password}, substr($params{login}, 0, 2)); + + } else { + croak 'Unsupported hash algorithm ' . $params{algorithm}; + } +} + +sub parse_password_entry { + my ($self, $password) = @_; + + return ($1, $2) if $password =~ m/^\{ ([^\}]+) \} (.+)/x; + return ('CRYPT', $password); +} + 1;