From 2d6d9eb4ffaaf5371ecfba1734ab1f86873013ea Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Sat, 27 Jul 2019 21:18:24 +0200 Subject: [PATCH] - Support CRYPT-SHA512 and SHA256 for passwords, implements #5353 --- .../sql/incremental/upd_dev_collection.sql | 5 ++++ install/sql/ispconfig3.sql | 10 ++++---- interface/lib/classes/auth.inc.php | 25 +++++++++++++++---- interface/lib/classes/remote.d/client.inc.php | 14 ++++------- interface/lib/classes/remoting.inc.php | 10 ++------ interface/web/admin/users_edit.php | 10 +++----- interface/web/client/reseller_edit.php | 24 +++++++----------- 7 files changed, 49 insertions(+), 49 deletions(-) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index e69de29bb2..d5b7b0e017 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -0,0 +1,5 @@ +ALTER TABLE `client` CHANGE COLUMN `password` `password` VARCHAR(200) DEFAULT NULL; +ALTER TABLE `ftp_user` CHANGE COLUMN `password` `password` VARCHAR(200) DEFAULT NULL; +ALTER TABLE `shell_user` CHANGE COLUMN `password` `password` VARCHAR(200) DEFAULT NULL; +ALTER TABLE `sys_user` CHANGE COLUMN `passwort` `passwort` VARCHAR(200) DEFAULT NULL; +ALTER TABLE `webdav_user` CHANGE COLUMN `password` `password` VARCHAR(200) DEFAULT NULL; \ No newline at end of file diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 2417ef0d21..3f534eedf0 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -243,7 +243,7 @@ CREATE TABLE `client` ( `limit_openvz_vm_template_id` int(11) NOT NULL DEFAULT '0', `parent_client_id` int(11) unsigned NOT NULL DEFAULT '0', `username` varchar(64) DEFAULT NULL, - `password` varchar(64) DEFAULT NULL, + `password` varchar(200) DEFAULT NULL, `language` char(2) NOT NULL DEFAULT 'en', `usertheme` varchar(32) NOT NULL DEFAULT 'default', `template_master` int(11) unsigned NOT NULL DEFAULT '0', @@ -705,7 +705,7 @@ CREATE TABLE `ftp_user` ( `parent_domain_id` int(11) unsigned NOT NULL default '0', `username` varchar(64) default NULL, `username_prefix` varchar(50) NOT NULL default '', - `password` varchar(64) default NULL, + `password` varchar(200) default NULL, `quota_size` bigint(20) NOT NULL default '-1', `active` enum('n','y') NOT NULL default 'y', `uid` varchar(64) default NULL, @@ -1440,7 +1440,7 @@ CREATE TABLE `shell_user` ( `parent_domain_id` int(11) unsigned NOT NULL default '0', `username` varchar(64) default NULL, `username_prefix` varchar(50) NOT NULL default '', - `password` varchar(64) default NULL, + `password` varchar(200) default NULL, `quota_size` bigint(20) NOT NULL default '-1', `active` enum('n','y') NOT NULL default 'y', `puser` varchar(255) default NULL, @@ -1864,7 +1864,7 @@ CREATE TABLE `sys_user` ( `sys_perm_group` varchar(5) NOT NULL default 'riud', `sys_perm_other` varchar(5) NOT NULL default '', `username` varchar(64) NOT NULL default '', - `passwort` varchar(64) NOT NULL default '', + `passwort` varchar(200) NOT NULL default '', `modules` varchar(255) NOT NULL default '', `startmodule` varchar(255) NOT NULL default '', `app_theme` varchar(32) NOT NULL default 'default', @@ -1899,7 +1899,7 @@ CREATE TABLE `webdav_user` ( `parent_domain_id` int(11) unsigned NOT NULL DEFAULT '0', `username` varchar(64) DEFAULT NULL, `username_prefix` varchar(50) NOT NULL default '', - `password` varchar(64) DEFAULT NULL, + `password` varchar(200) DEFAULT NULL, `active` enum('n','y') NOT NULL DEFAULT 'y', `dir` varchar(255) DEFAULT NULL, PRIMARY KEY (`webdav_user_id`) diff --git a/interface/lib/classes/auth.inc.php b/interface/lib/classes/auth.inc.php index 6658c4c116..afe50ac692 100644 --- a/interface/lib/classes/auth.inc.php +++ b/interface/lib/classes/auth.inc.php @@ -231,12 +231,27 @@ class auth { if($charset != 'UTF-8') { $cleartext_password = mb_convert_encoding($cleartext_password, $charset, 'UTF-8'); } - $salt="$1$"; - $base64_alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - for ($n=0;$n<8;$n++) { - $salt.=$base64_alphabet[mt_rand(0, 63)]; + + if(defined('CRYPT_SHA512') && CRYPT_SHA512 == 1) { + $salt = '$6$rounds=5000$'; + $salt_length = 16; + } elseif(defined('CRYPT_SHA256') && CRYPT_SHA256 == 1) { + $salt = '$5$rounds=5000$'; + $salt_length = 16; + } else { + $salt = '$1$'; + $salt_length = 12; + } + + if(function_exists('openssl_random_pseudo_bytes')) { + $salt .= substr(bin2hex(openssl_random_pseudo_bytes($salt_length)), 0, $salt_length); + } else { + $base64_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./'; + for($n = 0; $n < $salt_length; $n++) { + $salt .= $base64_alphabet[mt_rand(0, 63)]; + } } - $salt.="$"; + $salt .= "$"; return crypt($cleartext_password, $salt); } diff --git a/interface/lib/classes/remote.d/client.inc.php b/interface/lib/classes/remote.d/client.inc.php index b91909c9d3..e07e227e60 100644 --- a/interface/lib/classes/remote.d/client.inc.php +++ b/interface/lib/classes/remote.d/client.inc.php @@ -604,11 +604,9 @@ class remoting_client extends remoting { if($user) { $saved_password = stripslashes($user['password']); - if(substr($saved_password, 0, 3) == '$1$') { - //* The password is crypt-md5 encrypted - $salt = '$1$'.substr($saved_password, 3, 8).'$'; - - if(crypt(stripslashes($password), $salt) != $saved_password) { + if(preg_match('/^\$[156]\$/', $saved_password)) { + //* The password is crypt encrypted + if(crypt(stripslashes($password), $saved_password) !== $saved_password) { $user = false; } } else { @@ -636,11 +634,9 @@ class remoting_client extends remoting { if($user) { $saved_password = stripslashes($user['passwort']); - if(substr($saved_password, 0, 3) == '$1$') { + if(preg_match('/^\$[156]\$/', $saved_password)) { //* The password is crypt-md5 encrypted - $salt = '$1$'.substr($saved_password, 3, 8).'$'; - - if(crypt(stripslashes($password), $salt) != $saved_password) { + if(crypt(stripslashes($password), $saved_password) != $saved_password) { $user = false; } } else { diff --git a/interface/lib/classes/remoting.inc.php b/interface/lib/classes/remoting.inc.php index 6e551355a6..e1fc1ada86 100644 --- a/interface/lib/classes/remoting.inc.php +++ b/interface/lib/classes/remoting.inc.php @@ -99,28 +99,22 @@ class remoting { if($user) { $saved_password = stripslashes($user['passwort']); - if(substr($saved_password, 0, 3) == '$1$') { + if(preg_match('/^\$[156]\$/', $saved_password)) { //* The password is crypt-md5 encrypted - $salt = '$1$'.substr($saved_password, 3, 8).'$'; - - if(crypt(stripslashes($password), $salt) != $saved_password) { + if(crypt(stripslashes($password), $saved_password) != $saved_password) { throw new SoapFault('client_login_failed', 'The login failed. Username or password wrong.'); - return false; } } else { //* The password is md5 encrypted if(md5($password) != $saved_password) { throw new SoapFault('client_login_failed', 'The login failed. Username or password wrong.'); - return false; } } } else { throw new SoapFault('client_login_failed', 'The login failed. Username or password wrong.'); - return false; } if($user['active'] != 1) { throw new SoapFault('client_login_failed', 'The login failed. User is blocked.'); - return false; } // now we need the client data diff --git a/interface/web/admin/users_edit.php b/interface/web/admin/users_edit.php index 4c5c97409f..7f0c691c42 100644 --- a/interface/web/admin/users_edit.php +++ b/interface/web/admin/users_edit.php @@ -104,6 +104,8 @@ class page_action extends tform_actions { function onAfterUpdate() { global $app, $conf; + $app->uses('auth'); + $client = $app->db->queryOneRecord("SELECT * FROM sys_user WHERE userid = ?", $this->id); $client_id = $app->functions->intval($client['client_id']); $username = $this->dataRecord["username"]; @@ -121,13 +123,7 @@ class page_action extends tform_actions { // password changed if(isset($conf['demo_mode']) && $conf['demo_mode'] != true && isset($this->dataRecord["passwort"]) && $this->dataRecord["passwort"] != '') { $password = $this->dataRecord["passwort"]; - $salt="$1$"; - $base64_alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - for ($n=0;$n<8;$n++) { - $salt.=$base64_alphabet[mt_rand(0, 63)]; - } - $salt.="$"; - $password = crypt(stripslashes($password), $salt); + $password = $app->auth->crypt_password($password); $sql = "UPDATE client SET password = ? WHERE client_id = ? AND username = ?"; $app->db->query($sql, $password, $client_id, $username); } diff --git a/interface/web/client/reseller_edit.php b/interface/web/client/reseller_edit.php index 59699ec163..3078e01fbc 100644 --- a/interface/web/client/reseller_edit.php +++ b/interface/web/client/reseller_edit.php @@ -200,6 +200,9 @@ class page_action extends tform_actions { */ function onAfterInsert() { global $app, $conf; + + $app->uses('auth'); + // Create the group for the reseller $groupid = $app->db->datalogInsert('sys_group', array("name" => $this->dataRecord["username"], "description" => '', "client_id" => $this->id), 'groupid'); $groups = $groupid; @@ -213,14 +216,8 @@ class page_action extends tform_actions { $active = 1; $language = $this->dataRecord["language"]; - $salt="$1$"; - $base64_alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - for ($n=0;$n<8;$n++) { - $salt.=$base64_alphabet[mt_rand(0, 63)]; - } - $salt.="$"; - $password = crypt(stripslashes($password), $salt); - + $password = $app->auth->crypt_password(stripslashes($password)); + // Create the controlpaneluser for the reseller $sql = "INSERT INTO sys_user (`username`,`passwort`,`modules`,`startmodule`,`app_theme`,`typ`, `active`,`language`,`groups`,`default_group`,`client_id`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; @@ -313,6 +310,8 @@ class page_action extends tform_actions { function onAfterUpdate() { global $app, $conf; + $app->uses('auth'); + // username changed if(isset($conf['demo_mode']) && $conf['demo_mode'] != true && isset($this->dataRecord['username']) && $this->dataRecord['username'] != '' && $this->oldDataRecord['username'] != $this->dataRecord['username']) { $username = $this->dataRecord["username"]; @@ -329,13 +328,8 @@ class page_action extends tform_actions { if(isset($conf['demo_mode']) && $conf['demo_mode'] != true && isset($this->dataRecord["password"]) && $this->dataRecord["password"] != '') { $password = $this->dataRecord["password"]; $client_id = $this->id; - $salt="$1$"; - $base64_alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - for ($n=0;$n<8;$n++) { - $salt.=$base64_alphabet[mt_rand(0, 63)]; - } - $salt.="$"; - $password = crypt(stripslashes($password), $salt); + + $password = $app->auth->crypt_password(stripslashes($password)); $sql = "UPDATE sys_user SET passwort = ? WHERE client_id = ?"; $app->db->query($sql, $password, $client_id); } -- GitLab