1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace SimpleSAML\Module\authcrypt\Auth\Source; |
6
|
|
|
|
7
|
|
|
use Exception; |
8
|
|
|
use SimpleSAML\{Error, Logger, Utils}; |
9
|
|
|
use SimpleSAML\Module\core\Auth\UserPassBase; |
10
|
|
|
|
11
|
|
|
use function explode; |
12
|
|
|
use function is_string; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Authentication source for username & hashed password. |
16
|
|
|
* |
17
|
|
|
* This class is an authentication source which stores all username/hashes in an array, |
18
|
|
|
* and authenticates users against this array. |
19
|
|
|
* |
20
|
|
|
* @package SimpleSAMLphp |
21
|
|
|
*/ |
22
|
|
|
|
23
|
|
|
class Hash extends UserPassBase |
24
|
|
|
{ |
25
|
|
|
/** |
26
|
|
|
* Our users, stored in an associative array. The key of the array is "<username>:<passwordhash>", |
27
|
|
|
* while the value of each element is a new array with the attributes for each user. |
28
|
|
|
* |
29
|
|
|
* @var array<string, mixed> |
30
|
|
|
*/ |
31
|
|
|
private array $users; |
32
|
|
|
|
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Constructor for this authentication source. |
36
|
|
|
* |
37
|
|
|
* @param array<string, mixed> $info Information about this authentication source. |
38
|
|
|
* @param array<string, mixed> $config Configuration. |
39
|
|
|
* |
40
|
|
|
* @throws \Exception in case of a configuration error. |
41
|
|
|
*/ |
42
|
|
|
public function __construct(array $info, array $config) |
43
|
|
|
{ |
44
|
|
|
// Call the parent constructor first, as required by the interface |
45
|
|
|
parent::__construct($info, $config); |
46
|
|
|
|
47
|
|
|
$this->users = []; |
48
|
|
|
|
49
|
|
|
// Validate and parse our configuration |
50
|
|
|
foreach ($config as $userpass => $attributes) { |
51
|
|
|
if (!is_string($userpass)) { |
52
|
|
|
throw new Exception('Invalid <username>:<passwordhash> for authentication source ' . |
53
|
|
|
$this->authId . ': ' . $userpass); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
$userpass = explode(':', $userpass, 2); |
57
|
|
|
if (count($userpass) !== 2) { |
58
|
|
|
throw new Exception('Invalid <username>:<passwordhash> for authentication source ' . |
59
|
|
|
$this->authId . ': ' . $userpass[0]); |
60
|
|
|
} |
61
|
|
|
$username = $userpass[0]; |
62
|
|
|
$passwordhash = $userpass[1]; |
63
|
|
|
|
64
|
|
|
try { |
65
|
|
|
$attrUtils = new Utils\Attributes(); |
66
|
|
|
$attributes = $attrUtils->normalizeAttributesArray($attributes); |
67
|
|
|
} catch (Exception $e) { |
68
|
|
|
throw new Exception('Invalid attributes for user ' . $username . |
69
|
|
|
' in authentication source ' . $this->authId . ': ' . |
70
|
|
|
$e->getMessage()); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
$this->users[$username . ':' . $passwordhash] = $attributes; |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Attempt to log in using the given username and password. |
80
|
|
|
* |
81
|
|
|
* On a successful login, this function should return the users attributes. On failure, |
82
|
|
|
* it should throw an exception. If the error was caused by the user entering the wrong |
83
|
|
|
* username OR password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown. |
84
|
|
|
* |
85
|
|
|
* The username is UTF-8 encoded, and the hash is base64 encoded. |
86
|
|
|
* |
87
|
|
|
* @param string $username The username the user wrote. |
88
|
|
|
* @param string $password The password the user wrote. |
89
|
|
|
* |
90
|
|
|
* @return array<string, mixed> Associative array with the users attributes. |
91
|
|
|
* |
92
|
|
|
* @throws \SimpleSAML\Error\Error if authentication fails. |
93
|
|
|
*/ |
94
|
|
|
protected function login( |
95
|
|
|
string $username, |
96
|
|
|
#[\SensitiveParameter] |
97
|
|
|
string $password, |
98
|
|
|
): array { |
99
|
|
|
$cryptoUtils = new Utils\Crypto(); |
100
|
|
|
foreach ($this->users as $userpass => $attrs) { |
101
|
|
|
$matches = explode(':', $userpass, 2); |
102
|
|
|
if ($matches[0] === $username) { |
103
|
|
|
if ($cryptoUtils->pwValid($matches[1], $password)) { |
|
|
|
|
104
|
|
|
return $attrs; |
105
|
|
|
} else { |
106
|
|
|
Logger::debug('Incorrect password "' . $password . '" for user ' . $username); |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
throw new Error\Error('WRONGUSERPASS'); |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.