Merge remote-tracking branch 'origin/pr-235'
Fix #227: Use stronger password hashes #235
This commit is contained in:
commit
f48618d0e5
2
Makefile
2
Makefile
|
@ -21,7 +21,7 @@
|
||||||
# Purpose of file: Global Makefile
|
# Purpose of file: Global Makefile
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
MAJOR=$(shell sed -ne 's/^[^(]*(\([^)]*\)).*/\1/;1p' debian/changelog)
|
MAJOR=$(shell sed -ne 's/^[^(]*(\([^)]*\)).*/\1/;1p' debian/changelog)
|
||||||
VERSION=$MAJOR
|
VERSION=$(MAJOR)
|
||||||
export VERSION
|
export VERSION
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
|
|
@ -541,7 +541,6 @@ function _md5cr($pass, $salt = "") {
|
||||||
return crypt($pass, $salt);
|
return crypt($pass, $salt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** split mysql database name between username and custom database name
|
/** split mysql database name between username and custom database name
|
||||||
* @param string $dbname database name
|
* @param string $dbname database name
|
||||||
* @return array returns username as first element, custom name as second
|
* @return array returns username as first element, custom name as second
|
||||||
|
@ -1204,3 +1203,42 @@ function csrf_check($token=null) {
|
||||||
$db->exec("DELETE FROM csrf WHERE created<DATE_SUB(NOW(), INTERVAL 1 DAY);");
|
$db->exec("DELETE FROM csrf WHERE created<DATE_SUB(NOW(), INTERVAL 1 DAY);");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a SHA512-CRYPT hash of a string.
|
||||||
|
*/
|
||||||
|
function _sha512cr($password, $salt = NULL) {
|
||||||
|
if (!$salt) {
|
||||||
|
// Aim to have a 16 character salt for SHA-512 crypt.
|
||||||
|
// @see https://secure.php.net/manual/en/function.crypt.php
|
||||||
|
if (function_exists('random_bytes')) {
|
||||||
|
// PHP >= 7.0
|
||||||
|
$salt = base64_encode(random_bytes(12));
|
||||||
|
}
|
||||||
|
else if (function_exists('mcrypt_create_iv')) {
|
||||||
|
$salt = base64_encode(mcrypt_create_iv(12, MCRYPT_DEV_URANDOM));
|
||||||
|
}
|
||||||
|
else if (function_exists('')) {
|
||||||
|
$salt = base64_encode(openssl_random_pseudo_bytes(12));
|
||||||
|
}
|
||||||
|
if (!$salt) {
|
||||||
|
throw Error('Unable to generate salt');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$salt = '$6$rounds=20000$' . $salt;
|
||||||
|
$hash = crypt($password, $salt);
|
||||||
|
return $hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a password hash for use with dovecot.
|
||||||
|
*/
|
||||||
|
function _dovecot_hash($password) {
|
||||||
|
// In any case the final password saved for dovecot can store the
|
||||||
|
// scheme to override the default on a per-account basis.
|
||||||
|
// Ideally this is updated to bcrypt or argon2 when those become
|
||||||
|
// available in dovecot.
|
||||||
|
// @see https://wiki.dovecot.org/Authentication/PasswordSchemes
|
||||||
|
$hash = _sha512cr($password);
|
||||||
|
return '{SHA512-CRYPT}' . $hash;
|
||||||
|
}
|
||||||
|
|
|
@ -634,7 +634,7 @@ class m_admin {
|
||||||
$msg->raise("ERROR", "admin", _("Login can only contains characters a-z, 0-9 and -"));
|
$msg->raise("ERROR", "admin", _("Login can only contains characters a-z, 0-9 and -"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$pass = _md5cr($pass);
|
$pass = password_hash($pass, PASSWORD_BCRYPT);
|
||||||
$db = new DB_System();
|
$db = new DB_System();
|
||||||
// Already exist?
|
// Already exist?
|
||||||
$db->query("SELECT count(*) AS cnt FROM membres WHERE login= ?;", array($login));
|
$db->query("SELECT count(*) AS cnt FROM membres WHERE login= ?;", array($login));
|
||||||
|
@ -772,7 +772,7 @@ class m_admin {
|
||||||
$db = new DB_System();
|
$db = new DB_System();
|
||||||
|
|
||||||
if ($pass) {
|
if ($pass) {
|
||||||
$pass = _md5cr($pass);
|
$pass = password_hash($pass, PASSWORD_BCRYPT);
|
||||||
$second_query = "UPDATE membres SET mail= ?, canpass= ?, enabled= ?, `type`= ?, notes= ? , pass = ? WHERE uid= ?;";
|
$second_query = "UPDATE membres SET mail= ?, canpass= ?, enabled= ?, `type`= ?, notes= ? , pass = ? WHERE uid= ?;";
|
||||||
$second_query_args = array($mail, $canpass, $enabled, $type, $notes, $pass, $uid);
|
$second_query_args = array($mail, $canpass, $enabled, $type, $notes, $pass, $uid);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -321,7 +321,7 @@ class m_ftp {
|
||||||
return false; // The error has been raised by checkPolicy()
|
return false; // The error has been raised by checkPolicy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$encrypted_password = _md5cr($pass, strrev(microtime(true)));
|
$encrypted_password = _sha512cr($pass);
|
||||||
$db->query("UPDATE ftpusers SET name= ? , password='', encrypted_password= ?, homedir= ?, uid= ? WHERE id= ?;", array($full_login, $encrypted_password, $absolute, $cuid, $id));
|
$db->query("UPDATE ftpusers SET name= ? , password='', encrypted_password= ?, homedir= ?, uid= ? WHERE id= ?;", array($full_login, $encrypted_password, $absolute, $cuid, $id));
|
||||||
} else {
|
} else {
|
||||||
$db->query("UPDATE ftpusers SET name= ? , homedir= ? , uid= ? WHERE id= ? ;", array($full_login, $absolute, $cuid, $id));
|
$db->query("UPDATE ftpusers SET name= ? , homedir= ? , uid= ? WHERE id= ? ;", array($full_login, $absolute, $cuid, $id));
|
||||||
|
@ -406,7 +406,7 @@ class m_ftp {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($quota->cancreate("ftp")) {
|
if ($quota->cancreate("ftp")) {
|
||||||
$encrypted_password = _md5cr($pass, strrev(microtime(true)));
|
$encrypted_password = _sha512cr($pass);
|
||||||
$db->query("INSERT INTO ftpusers (name,password, encrypted_password,homedir,uid) VALUES ( ?, '', ?, ?, ?)", array($full_login, $encrypted_password, $absolute, $cuid));
|
$db->query("INSERT INTO ftpusers (name,password, encrypted_password,homedir,uid) VALUES ( ?, '', ?, ?, ?)", array($full_login, $encrypted_password, $absolute, $cuid));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -620,8 +620,10 @@ ORDER BY
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($canbeempty && empty($pass)) {
|
if ($canbeempty && empty($pass)) {
|
||||||
return $db->query("UPDATE address SET password= ? where id = ? ;", array(null, $mail_id ));
|
return $db->query("UPDATE address SET password= ? where id = ? ;",
|
||||||
} else if (!$db->query("UPDATE address SET password= ? where id = ? ;", array(_md5cr($pass), $mail_id ))) {
|
array(null, $mail_id ));
|
||||||
|
} else if (!$db->query("UPDATE address SET password= ? where id = ? ;",
|
||||||
|
array(_dovecot_hash($pass), $mail_id ))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -93,7 +93,7 @@ class m_mem {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$db->next_record();
|
$db->next_record();
|
||||||
if (_md5cr($password, $db->f("pass")) != $db->f("pass")) {
|
if (!password_verify($password, $db->f('pass'))) {
|
||||||
$db->query("UPDATE membres SET lastfail=lastfail+1 WHERE uid= ? ;", array($db->f("uid")));
|
$db->query("UPDATE membres SET lastfail=lastfail+1 WHERE uid= ? ;", array($db->f("uid")));
|
||||||
$msg->raise("ERROR", "mem", _("User or password incorrect"));
|
$msg->raise("ERROR", "mem", _("User or password incorrect"));
|
||||||
return false;
|
return false;
|
||||||
|
@ -104,6 +104,12 @@ class m_mem {
|
||||||
}
|
}
|
||||||
$this->user = $db->Record;
|
$this->user = $db->Record;
|
||||||
$cuid = $db->f("uid");
|
$cuid = $db->f("uid");
|
||||||
|
// Transitional code to update md5 hashed passwords to those created
|
||||||
|
// with password_hash().
|
||||||
|
if (strncmp($db->f('pass'), '$1$', 3) == 0) {
|
||||||
|
$db->query("update membres set pass = ? where uid = ?",
|
||||||
|
array(password_hash($password, PASSWORD_BCRYPT), $cuid));
|
||||||
|
}
|
||||||
|
|
||||||
if (panel_islocked() && $cuid != 2000) {
|
if (panel_islocked() && $cuid != 2000) {
|
||||||
$msg->raise("ALERT", "mem", _("This website is currently under maintenance, login is currently disabled."));
|
$msg->raise("ALERT", "mem", _("This website is currently under maintenance, login is currently disabled."));
|
||||||
|
@ -396,7 +402,7 @@ class m_mem {
|
||||||
$msg->raise("ERROR", "mem", _("You are not allowed to change your password."));
|
$msg->raise("ERROR", "mem", _("You are not allowed to change your password."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($this->user["pass"] != _md5cr($oldpass, $this->user["pass"])) {
|
if (!password_verify($oldpass, $this->user['pass'])) {
|
||||||
$msg->raise("ERROR", "mem", _("The old password is incorrect"));
|
$msg->raise("ERROR", "mem", _("The old password is incorrect"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -410,7 +416,7 @@ class m_mem {
|
||||||
if (!$admin->checkPolicy("mem", $login, $newpass)) {
|
if (!$admin->checkPolicy("mem", $login, $newpass)) {
|
||||||
return false; // The error has been raised by checkPolicy()
|
return false; // The error has been raised by checkPolicy()
|
||||||
}
|
}
|
||||||
$newpass = _md5cr($newpass);
|
$newpass = password_hash($newpass, PASSWORD_BCRYPT);
|
||||||
$db->query("UPDATE membres SET pass= ? WHERE uid= ?;", array($newpass, $cuid));
|
$db->query("UPDATE membres SET pass= ? WHERE uid= ?;", array($newpass, $cuid));
|
||||||
$msg->init_msgs();
|
$msg->init_msgs();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -129,7 +129,7 @@ CREATE TABLE IF NOT EXISTS ftpusers (
|
||||||
id int(10) unsigned NOT NULL auto_increment,
|
id int(10) unsigned NOT NULL auto_increment,
|
||||||
name varchar(64) NOT NULL default '',
|
name varchar(64) NOT NULL default '',
|
||||||
password varchar(32) NOT NULL default '',
|
password varchar(32) NOT NULL default '',
|
||||||
encrypted_password VARCHAR(32) default NULL,
|
encrypted_password VARCHAR(255) default NULL,
|
||||||
homedir varchar(128) NOT NULL default '',
|
homedir varchar(128) NOT NULL default '',
|
||||||
uid int(10) unsigned NOT NULL default '0',
|
uid int(10) unsigned NOT NULL default '0',
|
||||||
enabled boolean NOT NULL DEFAULT TRUE,
|
enabled boolean NOT NULL DEFAULT TRUE,
|
||||||
|
@ -159,7 +159,7 @@ CREATE TABLE IF NOT EXISTS local (
|
||||||
CREATE TABLE IF NOT EXISTS membres (
|
CREATE TABLE IF NOT EXISTS membres (
|
||||||
uid int(10) unsigned NOT NULL auto_increment, -- Numéro du membre (GID)
|
uid int(10) unsigned NOT NULL auto_increment, -- Numéro du membre (GID)
|
||||||
login varchar(128) NOT NULL default '', -- Nom d`utilisateur
|
login varchar(128) NOT NULL default '', -- Nom d`utilisateur
|
||||||
pass varchar(64) NOT NULL default '', -- Mot de passe
|
pass varchar(255) NOT NULL default '', -- Mot de passe
|
||||||
enabled tinyint(4) NOT NULL default '1', -- Le compte est-il actif ?
|
enabled tinyint(4) NOT NULL default '1', -- Le compte est-il actif ?
|
||||||
su tinyint(4) NOT NULL default '0', -- Le compte est-il super-admin ?
|
su tinyint(4) NOT NULL default '0', -- Le compte est-il super-admin ?
|
||||||
mail varchar(128) NOT NULL default '', -- Adresse email du possesseur
|
mail varchar(128) NOT NULL default '', -- Adresse email du possesseur
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE `membres` MODIFY `pass` varchar(255);
|
||||||
|
ALTER TABLE `ftpusers` MODIFY `encrypted_password` varchar(255);
|
Loading…
Reference in New Issue