Commit 5f8d03fe authored by Wolfgang Knopki's avatar Wolfgang Knopki
Browse files

added compatibility with simplesamlphp 1.19

parent 8e8e5b35
...@@ -12,216 +12,222 @@ ...@@ -12,216 +12,222 @@
* @package simpleSAMLphp * @package simpleSAMLphp
* @version $Id$ * @version $Id$
*/ */
class sspmod_sqlauthBcrypt_Auth_Source_SQL extends sspmod_core_Auth_UserPassBase { /*class sspmod_sqlauthBcrypt_Auth_Source_SQL extends sspmod_core_Auth_UserPassBase {*/
namespace SimpleSAML\Module\sqlauthbcrypt\Auth\Source;
/**
* The DSN we should connect to.
*/
private $dsn; class sql extends \SimpleSAML\Module\core\Auth\UserPassBase {
/**
/** * The DSN we should connect to.
* The username we should connect to the database with. */
*/ private $dsn;
private $username;
/**
/** * The username we should connect to the database with.
* The password we should connect to the database with. */
*/ private $username;
private $password;
/**
/** * The password we should connect to the database with.
* The query we should use to retrieve the attributes for the user. */
* private $password;
* The username and password will be available as :username and :password.
*/
private $query; /**
* The query we should use to retrieve the attributes for the user.
*
/** * The username and password will be available as :username and :password.
* The pepper used to generate the password hash. */
*/ private $query;
private $pepper;
/**
/** * The pepper used to generate the password hash.
* The column holding the password hash. */
*/ private $pepper;
private $hash_column;
/** /**
* Constructor for this authentication source. * The column holding the password hash.
* */
* @param array $info Information about this authentication source. private $hash_column;
* @param array $config Configuration.
*/ /**
public function __construct($info, $config) { * Constructor for this authentication source.
assert('is_array($info)'); *
assert('is_array($config)'); * @param array $info Information about this authentication source.
* @param array $config Configuration.
/* Call the parent constructor first, as required by the interface. */ */
parent::__construct($info, $config); public function __construct($info, $config) {
assert('is_array($info)');
/* Make sure that all required parameters are present. */ assert('is_array($config)');
foreach (array('dsn', 'username', 'password', 'query', 'pepper') as $param) {
if (!array_key_exists($param, $config)) { /* Call the parent constructor first, as required by the interface. */
throw new Exception('Missing required attribute \'' . $param . parent::__construct($info, $config);
'\' for authentication source ' . $this->authId);
} /* Make sure that all required parameters are present. */
foreach (array('dsn', 'username', 'password', 'query', 'pepper') as $param) {
if (!is_string($config[$param])) { if (!array_key_exists($param, $config)) {
throw new Exception('Expected parameter \'' . $param . throw new \Exception('Missing required attribute \'' . $param .
'\' for authentication source ' . $this->authId . '\' for authentication source ' . $this->authId);
' to be a string. Instead it was: ' . }
var_export($config[$param], TRUE));
} if (!is_string($config[$param])) {
} throw new \Exception('Expected parameter \'' . $param .
'\' for authentication source ' . $this->authId .
$this->dsn = $config['dsn']; ' to be a string. Instead it was: ' .
$this->username = $config['username']; var_export($config[$param], TRUE));
$this->password = $config['password']; }
$this->query = $config['query']; }
$this->pepper = $config['pepper'];
$this->hash_column = $config['hash_column']; $this->dsn = $config['dsn'];
} $this->username = $config['username'];
$this->password = $config['password'];
$this->query = $config['query'];
/** $this->pepper = $config['pepper'];
* Create a database connection. $this->hash_column = $config['hash_column'];
* }
* @return PDO The database connection.
*/
private function connect() { /**
try { * Create a database connection.
$db = new PDO($this->dsn, $this->username, $this->password); *
} catch (PDOException $e) { * @return PDO The database connection.
throw new Exception('sqlauthBcrypt:' . $this->authId . */
': - Failed to connect to \'' . $this->dsn . '\': '. $e->getMessage()); private function connect() {
} try {
$db = new \PDO($this->dsn, $this->username, $this->password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (\PDOException $e) {
throw new \Exception('sqlauthBcrypt:' . $this->authId .
': - Failed to connect to \'' . $this->dsn . '\': '. $e->getMessage());
$driver = explode(':', $this->dsn, 2); }
$driver = strtolower($driver[0]);
$db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
/* Driver specific initialization. */
switch ($driver) {
case 'mysql': $driver = explode(':', $this->dsn, 2);
/* Use UTF-8. */ $driver = strtolower($driver[0]);
$db->exec("SET NAMES 'utf8'");
break; /* Driver specific initialization. */
case 'pgsql': switch ($driver) {
/* Use UTF-8. */ case 'mysql':
$db->exec("SET NAMES 'UTF8'"); /* Use UTF-8. */
break; $db->exec("SET NAMES 'utf8'");
} break;
case 'pgsql':
return $db; /* Use UTF-8. */
} $db->exec("SET NAMES 'UTF8'");
break;
}
/**
* Attempt to log in using the given username and password. return $db;
* }
* On a successful login, this function should return the users attributes. On failure,
* it should throw an exception. If the error was caused by the user entering the wrong
* username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown. /**
* * Attempt to log in using the given username and password.
* Note that both the username and the password are UTF-8 encoded. *
* * On a successful login, this function should return the users attributes. On failure,
* @param string $username The username the user wrote. * it should throw an exception. If the error was caused by the user entering the wrong
* @param string $password The password the user wrote. * username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown.
* @return array Associative array with the users attributes. *
*/ * Note that both the username and the password are UTF-8 encoded.
protected function login($username, $password) { *
assert('is_string($username)'); * @param string $username The username the user wrote.
assert('is_string($password)'); * @param string $password The password the user wrote.
* @return array Associative array with the users attributes.
$db = $this->connect(); */
protected function login(string $username,string $password):array {
try { assert('is_string($username)');
$sth = $db->prepare($this->query); assert('is_string($password)');
} catch (PDOException $e) {
throw new Exception('sqlauthBcrypt:' . $this->authId . $db = $this->connect();
': - Failed to prepare query: ' . $e->getMessage());
} try {
$sth = $db->prepare($this->query);
try { } catch (\PDOException $e) {
$res = $sth->execute(array('username' => $username)); throw new \Exception('sqlauthBcrypt:' . $this->authId .
} catch (PDOException $e) { ': - Failed to prepare query: ' . $e->getMessage());
throw new Exception('sqlauthBcrypt:' . $this->authId . }
': - Failed to execute query: ' . $e->getMessage());
} try {
$res = $sth->execute(array('username' => $username));
try { } catch ( \PDOException $e) {
$data = $sth->fetchAll(PDO::FETCH_ASSOC); throw new \Exception('sqlauthBcrypt:' . $this->authId .
} catch (PDOException $e) { ': - Failed to execute query: ' . $e->getMessage());
throw new Exception('sqlauth:' . $this->authId . }
': - Failed to fetch result set: ' . $e->getMessage());
} try {
$data = $sth->fetchAll(\PDO::FETCH_ASSOC);
SimpleSAML_Logger::info('sqlauthBcrypt:' . $this->authId . } catch (\PDOException $e) {
': Got ' . count($data) . ' rows from database'); throw new \Exception('sqlauth:' . $this->authId .
': - Failed to fetch result set: ' . $e->getMessage());
if (count($data) === 0) { }
/* No rows returned - invalid username */
SimpleSAML_Logger::error('sqlauthBcrypt:' . $this->authId . \SimpleSAML\Logger::info('sqlauthBcrypt:' . $this->authId .
': No rows in result set. Wrong username or sqlauthBcrypt is misconfigured.'); ': Got ' . count($data) . ' rows from database');
throw new SimpleSAML_Error_Error('WRONGUSERPASS');
} if (count($data) === 0) {
/* No rows returned - invalid username */
/* Validate stored password hash (must be in first row of resultset) */ \SimpleSAML\Logger::error('sqlauthBcrypt:' . $this->authId .
$password_hash = $data[0][$this->hash_column]; ': No rows in result set. Wrong username or sqlauthBcrypt is misconfigured.');
throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
if ($password_hash !== crypt($password.$this->pepper, $password_hash)) { }
/* Invalid password */
SimpleSAML_Logger::error('sqlauthBcrypt:' . $this->authId . /* Validate stored password hash (must be in first row of resultset) */
': Hash does not match. Wrong password or sqlauthBcrypt is misconfigured.'); $password_hash = $data[0][$this->hash_column];
throw new SimpleSAML_Error_Error('WRONGUSERPASS');
} if ($password_hash !== crypt($password.$this->pepper, $password_hash)) {
/* Invalid password */
/* Extract attributes. We allow the resultset to consist of multiple rows. Attributes \SimpleSAML\Logger::error('sqlauthBcrypt:' . $this->authId .
* which are present in more than one row will become multivalued. NULL values and ': Hash does not match. Wrong password or sqlauthBcrypt is misconfigured.');
* duplicate values will be skipped. All values will be converted to strings. throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
*/ }
$attributes = array();
foreach ($data as $row) { /* Extract attributes. We allow the resultset to consist of multiple rows. Attributes
foreach ($row as $name => $value) { * which are present in more than one row will become multivalued. NULL values and
* duplicate values will be skipped. All values will be converted to strings.
if ($value === NULL) { */
continue; $attributes = array();
} foreach ($data as $row) {
foreach ($row as $name => $value) {
if ($name === $this->hash_column) {
/* Don't add password hash to attributes */ if ($value === NULL) {
continue; continue;
} }
$value = (string)$value; if ($name === $this->hash_column) {
/* Don't add password hash to attributes */
if (!array_key_exists($name, $attributes)) { continue;
$attributes[$name] = array(); }
}
$value = (string)$value;
if (in_array($value, $attributes[$name], TRUE)) {
/* Value already exists in attribute. */ if (!array_key_exists($name, $attributes)) {
continue; $attributes[$name] = array();
} }
$attributes[$name][] = $value; if (in_array($value, $attributes[$name], TRUE)) {
} /* Value already exists in attribute. */
} continue;
}
SimpleSAML_Logger::info('sqlauthBcrypt:' . $this->authId .
': Attributes: ' . implode(',', array_keys($attributes))); $attributes[$name][] = $value;
}
return $attributes; }
}
\SimpleSAML\Logger::info('sqlauthBcrypt:' . $this->authId .
': Attributes: ' . implode(',', array_keys($attributes)));
return $attributes;
}
} }
?> ?>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment