Issues (3)

src/Auth/Source/Hash.php (1 issue)

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)) {
0 ignored issues
show
Deprecated Code introduced by
The function SimpleSAML\Utils\Crypto::pwValid() has been deprecated: Use Symfony NativePasswordHasher::verify instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

103
                if (/** @scrutinizer ignore-deprecated */ $cryptoUtils->pwValid($matches[1], $password)) {

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.

Loading history...
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