From 3251067b38c6ccdb87e1731ce6a3c59f3082feab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Wed, 28 Feb 2018 21:31:42 +0100 Subject: [PATCH] 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 --- lib/HashAlgorithm/Cleartext.php | 75 +++++++++++++++++++++++++++++ lib/user_sql.php | 85 +++++++++++++++++++++++---------- templates/admin.php | 2 +- 3 files changed, 135 insertions(+), 27 deletions(-) create mode 100644 lib/HashAlgorithm/Cleartext.php diff --git a/lib/HashAlgorithm/Cleartext.php b/lib/HashAlgorithm/Cleartext.php new file mode 100644 index 0000000..17526b1 --- /dev/null +++ b/lib/HashAlgorithm/Cleartext.php @@ -0,0 +1,75 @@ + + * + * 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 . + */ + +namespace OCA\user_sql\HashAlgorithm; + +/** + * Cleartext password hash implementation. + * @author Marcin Łojewski + */ +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() + { + } +} diff --git a/lib/user_sql.php b/lib/user_sql.php index b696027..cb6f2a5 100644 --- a/lib/user_sql.php +++ b/lib/user_sql.php @@ -30,7 +30,7 @@ namespace OCA\user_sql; use OC\User\Backend; - +use OCA\user_sql\HashAlgorithm\HashAlgorithm; use OCP\IConfig; use OCP\IUser; use OCP\IUserSession; @@ -280,6 +280,15 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend, 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 * 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) { 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 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)); } else { $enc_password = $this->pacrypt($password, $old_password); - } + }*/ + $res = $this->helper->runQuery('setPass', array('uid' => $uid, 'enc_password' => $enc_password), true); @@ -396,7 +419,16 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend, Util::writeLog('OC_USER_SQL', "Encrypting and checking password", 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 (!function_exists('user_check_password')) { 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->hash_equals($this->pacrypt($password, $db_pass), $db_pass); - } + }*/ + if ($ret) { Util::writeLog('OC_USER_SQL', "Passwords matching, return true", @@ -620,7 +653,7 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend, */ 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 * @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::DEBUG); @@ -710,7 +743,7 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend, Util::writeLog('OC_USER_SQL', "pacrypt() done, return", Util::DEBUG); return $password; - } + }*/ /** * md5crypt @@ -721,7 +754,7 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend, * @return string The encrypted password */ - private function md5crypt($pw, $salt = "", $magic = "") + /*private function md5crypt($pw, $salt = "", $magic = "") { $MAGIC = "$1$"; @@ -792,18 +825,18 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend, (ord($final[10]) << 8) | (ord($final[5]))), 4); $passwd .= $this->to64(ord($final[11]), 2); return "$magic$salt\$$passwd"; - } + }*/ /** * Create a new salte * @return string The salt */ - private function create_md5salt() + /*private function create_md5salt() { srand((double)microtime() * 1000000); $salt = substr(md5(rand(0, 9999999)), 0, 8); return $salt; - } + }*/ /** * Encrypt using SSHA256 algorithm @@ -811,17 +844,17 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend, * @param string $salt The salt to use * @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); - } + }*/ /** * PostfixAdmin's hex2bin function * @param string $str The string to convert * @return string The converted string */ - private function pahex2bin($str) + /*private function pahex2bin($str) { if (function_exists('hex2bin')) { return hex2bin($str); @@ -834,12 +867,12 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend, } return $nstr; } - } + }*/ /** * Convert to 64? */ - private function to64($v, $n) + /*private function to64($v, $n) { $ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -850,7 +883,7 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend, $v = $v >> 6; } return $ret; - } + }*/ /** * 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; } - private function create_systemsalt($length = 20) + /*private function create_systemsalt($length = 20) { $fp = fopen('/dev/urandom', 'r'); $randomString = fread($fp, $length); fclose($fp); $salt = base64_encode($randomString); return $salt; - } + }*/ - private function pw_hash($password) + /*private function pw_hash($password) { $options = [ 'cost' => 10, ]; return password_hash($password, PASSWORD_BCRYPT, $options); - } + }*/ - function hash_equals($a, $b) + /*function hash_equals($a, $b) { $a_length = strlen($a); @@ -935,14 +968,14 @@ class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend, } return $result === 0; - } + }*/ - private static function hex_to_base64($hex) + /*private static function hex_to_base64($hex) { $hex_chr = ''; foreach (str_split($hex, 2) as $hexpair) { $hex_chr .= chr(hexdec($hexpair)); } return base64_encode($hex_chr); - } + }*/ } diff --git a/templates/admin.php b/templates/admin.php index 5ff8a8e..fbc35d8 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -106,7 +106,7 @@ $cfgClass = 'section'; 'drupal' => 'Drupal 7', 'md5' => 'MD5', 'md5crypt' => 'MD5 Crypt', - 'cleartext' => 'Cleartext', + 'Cleartext' => 'Cleartext', 'mysql_encrypt' => 'mySQL ENCRYPT()', 'system' => 'System (crypt)', 'password_hash' => 'password_hash',