epic-ts
[kivitendo-erp.git] / SL / Auth / Password.pm
1 package SL::Auth::Password;
2
3 use strict;
4
5 use Carp;
6 use Digest::MD5 ();
7 use Digest::SHA ();
8
9 sub hash {
10   my ($class, %params) = @_;
11
12   $params{algorithm} ||= 'SHA256S';
13
14   my $salt = $params{algorithm} =~ m/S$/ ? $params{login} : '';
15
16   if ($params{algorithm} =~ m/^SHA256/) {
17     return '{' . $params{algorithm} . '}' . Digest::SHA::sha256_hex($salt . $params{password});
18
19   } elsif ($params{algorithm} =~ m/^SHA1/) {
20     return '{' . $params{algorithm} . '}' . Digest::SHA::sha1_hex($salt . $params{password});
21
22   } elsif ($params{algorithm} =~ m/^MD5/) {
23     return '{' . $params{algorithm} . '}' . Digest::MD5::md5_hex($salt . $params{password});
24
25   } elsif ($params{algorithm} eq 'CRYPT') {
26     return '{CRYPT}' . crypt($params{password}, substr($params{login}, 0, 2));
27
28   } else {
29     croak 'Unsupported hash algorithm ' . $params{algorithm};
30   }
31 }
32
33 sub hash_if_unhashed {
34   my ($class, %params) = @_;
35
36   my ($algorithm, $password) = $class->parse($params{password}, 'NONE');
37
38   return $params{password} unless $algorithm eq 'NONE';
39
40   if ($params{look_up_algorithm}) {
41     my $stored_password    = $params{auth}->get_stored_password($params{login});
42     my ($stored_algorithm) = $class->parse($stored_password);
43     $params{algorithm}     = $stored_algorithm;
44   }
45
46   return $class->hash(%params);
47 }
48
49 sub parse {
50   my ($class, $password, $default_algorithm) = @_;
51
52   return ($1, $2) if $password =~ m/^\{ ([^\}]+) \} (.+)/x;
53   return ($default_algorithm || 'CRYPT', $password);
54 }
55
56 1;