Set to default new logic. Add cleartext password hash implementation.

TODO:
- add new implementation of the rest of currently supported hashes
- create update.php changing hash names in the config
This commit is contained in:
Marcin Łojewski
2018-02-28 21:31:42 +01:00
parent 7672c66c75
commit 3251067b38
3 changed files with 135 additions and 27 deletions

View File

@@ -0,0 +1,75 @@
<?php
/**
* Nextcloud - user_sql
* Copyright (C) 2012-2018 Andreas Böhler <dev (at) aboehler (dot) at>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace OCA\user_sql\HashAlgorithm;
/**
* Cleartext password hash implementation.
* @author Marcin Łojewski <dev@mlojewski.me>
*/
class Cleartext implements HashAlgorithm
{
/**
* @var Cleartext
*/
private static $instance;
private function __construct()
{
}
/**
* @return Cleartext
*/
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new Cleartext();
}
return self::$instance;
}
/**
* @inheritdoc
*/
public function getVisibleName()
{
return "Cleartext";
}
/**
* @inheritdoc
*/
public function getPasswordHash($password)
{
return $password;
}
/**
* @inheritdoc
*/
public function checkPassword($password, $dbHash)
{
return $password === $dbHash;
}
private function __clone()
{
}
}

View File

@@ -30,7 +30,7 @@
namespace OCA\user_sql; namespace OCA\user_sql;
use OC\User\Backend; use OC\User\Backend;
use OCA\user_sql\HashAlgorithm\HashAlgorithm;
use OCP\IConfig; use OCP\IConfig;
use OCP\IUser; use OCP\IUser;
use OCP\IUserSession; use OCP\IUserSession;
@@ -280,6 +280,15 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
return false; return false;
} }
/**
* @return HashAlgorithm|bool
*/
private function getHashAlgorithmInstance() {
$cryptoType = $this->settings['set_crypt_type'];
require_once('HashAlgorithm/'. $cryptoType . '.php');
return call_user_func('OCA\\user_sql\\HashAlgorithm\\' . $cryptoType . "::getInstance");
}
/** /**
* Set (change) a user password * Set (change) a user password
* This can be enabled/disabled in the settings (set_allow_pwchange) * This can be enabled/disabled in the settings (set_allow_pwchange)
@@ -305,7 +314,20 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
if ($row === false) { if ($row === false) {
return false; return false;
} }
$old_password = $row[$this->settings['col_password']];
$hashAlgorithm = $this->getHashAlgorithmInstance();
if ($hashAlgorithm === false) {
return false;
}
$enc_password = $hashAlgorithm->getPasswordHash($password);
if ($enc_password === false) {
return false;
}
/*$old_password = $row[$this->settings['col_password']];
// Added and disabled updating passwords for Drupal 7 WD 2018-01-04 // Added and disabled updating passwords for Drupal 7 WD 2018-01-04
if ($this->settings['set_crypt_type'] === 'drupal') { if ($this->settings['set_crypt_type'] === 'drupal') {
@@ -356,7 +378,8 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
$enc_password = '{SHA256}' . OC_USER_SQL::hex_to_base64(hash('sha256', $password, false)); $enc_password = '{SHA256}' . OC_USER_SQL::hex_to_base64(hash('sha256', $password, false));
} else { } else {
$enc_password = $this->pacrypt($password, $old_password); $enc_password = $this->pacrypt($password, $old_password);
} }*/
$res = $this->helper->runQuery('setPass', $res = $this->helper->runQuery('setPass',
array('uid' => $uid, 'enc_password' => $enc_password), array('uid' => $uid, 'enc_password' => $enc_password),
true); true);
@@ -396,7 +419,16 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
Util::writeLog('OC_USER_SQL', "Encrypting and checking password", Util::writeLog('OC_USER_SQL', "Encrypting and checking password",
Util::DEBUG); Util::DEBUG);
// Added handling for Drupal 7 passwords WD 2018-01-04
$hashAlgorithm = $this->getHashAlgorithmInstance();
if ($hashAlgorithm === false) {
return false;
}
$ret = $hashAlgorithm->checkPassword($password, $db_pass);
/*// Added handling for Drupal 7 passwords WD 2018-01-04
if ($this->settings['set_crypt_type'] === 'drupal') { if ($this->settings['set_crypt_type'] === 'drupal') {
if (!function_exists('user_check_password')) { if (!function_exists('user_check_password')) {
require_once('drupal.php'); require_once('drupal.php');
@@ -437,7 +469,8 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
// $ret = $this -> pacrypt($password, $db_pass) === $db_pass; // $ret = $this -> pacrypt($password, $db_pass) === $db_pass;
$ret = $this->hash_equals($this->pacrypt($password, $db_pass), $ret = $this->hash_equals($this->pacrypt($password, $db_pass),
$db_pass); $db_pass);
} }*/
if ($ret) { if ($ret) {
Util::writeLog('OC_USER_SQL', Util::writeLog('OC_USER_SQL',
"Passwords matching, return true", "Passwords matching, return true",
@@ -620,7 +653,7 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
*/ */
public function getBackendName() public function getBackendName()
{ {
return 'SQL'; return 'user_sql';
} }
/** /**
@@ -637,7 +670,7 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
* @param string $pw_db encrypted password from database * @param string $pw_db encrypted password from database
* @return string encrypted password. * @return string encrypted password.
*/ */
private function pacrypt($pw, $pw_db = "") /*private function pacrypt($pw, $pw_db = "")
{ {
Util::writeLog('OC_USER_SQL', "Entering private pacrypt()", Util::writeLog('OC_USER_SQL', "Entering private pacrypt()",
Util::DEBUG); Util::DEBUG);
@@ -710,7 +743,7 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
Util::writeLog('OC_USER_SQL', "pacrypt() done, return", Util::writeLog('OC_USER_SQL', "pacrypt() done, return",
Util::DEBUG); Util::DEBUG);
return $password; return $password;
} }*/
/** /**
* md5crypt * md5crypt
@@ -721,7 +754,7 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
* @return string The encrypted password * @return string The encrypted password
*/ */
private function md5crypt($pw, $salt = "", $magic = "") /*private function md5crypt($pw, $salt = "", $magic = "")
{ {
$MAGIC = "$1$"; $MAGIC = "$1$";
@@ -792,18 +825,18 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
(ord($final[10]) << 8) | (ord($final[5]))), 4); (ord($final[10]) << 8) | (ord($final[5]))), 4);
$passwd .= $this->to64(ord($final[11]), 2); $passwd .= $this->to64(ord($final[11]), 2);
return "$magic$salt\$$passwd"; return "$magic$salt\$$passwd";
} }*/
/** /**
* Create a new salte * Create a new salte
* @return string The salt * @return string The salt
*/ */
private function create_md5salt() /*private function create_md5salt()
{ {
srand((double)microtime() * 1000000); srand((double)microtime() * 1000000);
$salt = substr(md5(rand(0, 9999999)), 0, 8); $salt = substr(md5(rand(0, 9999999)), 0, 8);
return $salt; return $salt;
} }*/
/** /**
* Encrypt using SSHA256 algorithm * Encrypt using SSHA256 algorithm
@@ -811,17 +844,17 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
* @param string $salt The salt to use * @param string $salt The salt to use
* @return string The hashed password, prefixed by {SSHA256} * @return string The hashed password, prefixed by {SSHA256}
*/ */
private function ssha256($pw, $salt) /*private function ssha256($pw, $salt)
{ {
return '{SSHA256}' . base64_encode(hash('sha256', $pw . $salt, true) . $salt); return '{SSHA256}' . base64_encode(hash('sha256', $pw . $salt, true) . $salt);
} }*/
/** /**
* PostfixAdmin's hex2bin function * PostfixAdmin's hex2bin function
* @param string $str The string to convert * @param string $str The string to convert
* @return string The converted string * @return string The converted string
*/ */
private function pahex2bin($str) /*private function pahex2bin($str)
{ {
if (function_exists('hex2bin')) { if (function_exists('hex2bin')) {
return hex2bin($str); return hex2bin($str);
@@ -834,12 +867,12 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
} }
return $nstr; return $nstr;
} }
} }*/
/** /**
* Convert to 64? * Convert to 64?
*/ */
private function to64($v, $n) /*private function to64($v, $n)
{ {
$ITOA64 = $ITOA64 =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -850,7 +883,7 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
$v = $v >> 6; $v = $v >> 6;
} }
return $ret; return $ret;
} }*/
/** /**
* Store a value in memcache or the session, if no memcache is available * Store a value in memcache or the session, if no memcache is available
@@ -894,25 +927,25 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
return $retVal; return $retVal;
} }
private function create_systemsalt($length = 20) /*private function create_systemsalt($length = 20)
{ {
$fp = fopen('/dev/urandom', 'r'); $fp = fopen('/dev/urandom', 'r');
$randomString = fread($fp, $length); $randomString = fread($fp, $length);
fclose($fp); fclose($fp);
$salt = base64_encode($randomString); $salt = base64_encode($randomString);
return $salt; return $salt;
} }*/
private function pw_hash($password) /*private function pw_hash($password)
{ {
$options = [ $options = [
'cost' => 10, 'cost' => 10,
]; ];
return password_hash($password, PASSWORD_BCRYPT, $options); return password_hash($password, PASSWORD_BCRYPT, $options);
} }*/
function hash_equals($a, $b) /*function hash_equals($a, $b)
{ {
$a_length = strlen($a); $a_length = strlen($a);
@@ -935,14 +968,14 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
} }
return $result === 0; return $result === 0;
} }*/
private static function hex_to_base64($hex) /*private static function hex_to_base64($hex)
{ {
$hex_chr = ''; $hex_chr = '';
foreach (str_split($hex, 2) as $hexpair) { foreach (str_split($hex, 2) as $hexpair) {
$hex_chr .= chr(hexdec($hexpair)); $hex_chr .= chr(hexdec($hexpair));
} }
return base64_encode($hex_chr); return base64_encode($hex_chr);
} }*/
} }

View File

@@ -106,7 +106,7 @@ $cfgClass = 'section';
'drupal' => 'Drupal 7', 'drupal' => 'Drupal 7',
'md5' => 'MD5', 'md5' => 'MD5',
'md5crypt' => 'MD5 Crypt', 'md5crypt' => 'MD5 Crypt',
'cleartext' => 'Cleartext', 'Cleartext' => 'Cleartext',
'mysql_encrypt' => 'mySQL ENCRYPT()', 'mysql_encrypt' => 'mySQL ENCRYPT()',
'system' => 'System (crypt)', 'system' => 'System (crypt)',
'password_hash' => 'password_hash', 'password_hash' => 'password_hash',