File salted-passwords.patch of Package zabbix.25188

From 0bc1a41104cf747edbda6d2c84c7ade9d714fb30 Mon Sep 17 00:00:00 2001
From: Vasily Goncharenko <vasilijs.goncarenko@zabbix.com>
Date: Wed, 11 Dec 2019 14:28:07 +0200
Subject: [PATCH] A......... [ZBXNEXT-1898] implemented strong cryptography for
 encoding frontend passwords

---
 ChangeLog.d/feature/ZBXNEXT-1898              |  1 +
 create/src/data.tmpl                          |  6 ++--
 create/src/schema.tmpl                        |  4 +--
 .../include/classes/api/services/CUser.php    | 30 +++++++++++++++++--
 frontends/php/include/defines.inc.php         |  5 +++-
 frontends/php/include/schema.inc.php          |  2 +-
 src/libs/zbxdbupgrade/dbupgrade_4050.c        |  8 +++++
 7 files changed, 46 insertions(+), 10 deletions(-)
 create mode 100644 ChangeLog.d/feature/ZBXNEXT-1898

Index: zabbix-4.0.12/ChangeLog.d/feature/ZBXNEXT-1898
===================================================================
--- /dev/null
+++ zabbix-4.0.12/ChangeLog.d/feature/ZBXNEXT-1898
@@ -0,0 +1 @@
+A......... [ZBXNEXT-1898] implemented strong cryptography for encoding frontend passwords (vasilijs)
Index: zabbix-4.0.12/frontends/php/include/classes/api/services/CUser.php
===================================================================
--- zabbix-4.0.12.orig/frontends/php/include/classes/api/services/CUser.php
+++ zabbix-4.0.12/frontends/php/include/classes/api/services/CUser.php
@@ -298,7 +298,9 @@ class CUser extends CApiService {
 			 * If user is created without a password (e.g. for GROUP_GUI_ACCESS_LDAP), store an empty string
 			 * as his password in database.
 			 */
-			$user['passwd'] = (array_key_exists('passwd', $user)) ? md5($user['passwd']) : '';
+			$user['passwd'] = array_key_exists('passwd', $user)
+				? password_hash($user['passwd'], PASSWORD_BCRYPT, ['cost' => ZBX_BCRYPT_COST])
+				: '';
 		}
 		unset($user);
 
@@ -440,7 +442,7 @@ class CUser extends CApiService {
 					self::exception(ZBX_API_ERROR_PARAMETERS, _('Not allowed to set password for user "guest".'));
 				}
 
-				$user['passwd'] = md5($user['passwd']);
+				$user['passwd'] = password_hash($user['passwd'], PASSWORD_BCRYPT, ['cost' => ZBX_BCRYPT_COST]);
 			}
 		}
 		unset($user);
@@ -1197,7 +1199,7 @@ class CUser extends CApiService {
 					break;
 
 				case ZBX_AUTH_INTERNAL:
-					if (md5($user['password']) !== $db_user['passwd']) {
+                    if (!$this->isPasswordVerified($user['password'], $db_user)) {
 						self::exception(ZBX_API_ERROR_PERMISSIONS, _('Login name or password is incorrect.'));
 					}
 					break;
@@ -1245,6 +1247,28 @@ class CUser extends CApiService {
 	}
 
 	/**
+	 * @param string $password
+	 * @param array  $user
+	 *
+	 * @return bool
+	 */
+    private function isPasswordVerified($password, $db_user) {
+		if (strlen($db_user['passwd']) > ZBX_MD5_SIZE) {
+			return password_verify($password, $db_user['passwd']);
+		}
+		elseif (hash_equals(md5($password), $db_user['passwd'])) {
+			DB::update('users', [
+				'values' => ['passwd' => password_hash($password, PASSWORD_BCRYPT, ['cost' => ZBX_BCRYPT_COST])],
+				'where' => ['userid' => $db_user['userid']]
+			]);
+
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
 	 * Method is ONLY for internal use!
 	 * Login user by alias. Return array with user data.
 	 *
Index: zabbix-4.0.12/frontends/php/include/defines.inc.php
===================================================================
--- zabbix-4.0.12.orig/frontends/php/include/defines.inc.php
+++ zabbix-4.0.12/frontends/php/include/defines.inc.php
@@ -22,7 +22,7 @@
 define('ZABBIX_VERSION',		'4.0.12');
 define('ZABBIX_API_VERSION',	'4.0.12');
 define('ZABBIX_EXPORT_VERSION',	'4.0');
-define('ZABBIX_DB_VERSION',		4000000);
+define('ZABBIX_DB_VERSION',		4000005);
 
 define('ZABBIX_COPYRIGHT_FROM',	'2001');
 define('ZABBIX_COPYRIGHT_TO',	'2019');
@@ -30,6 +30,9 @@ define('ZABBIX_COPYRIGHT_TO',	'2019');
 define('ZBX_LOGIN_ATTEMPTS',	5);
 define('ZBX_LOGIN_BLOCK',		30); // sec
 
+define('ZBX_BCRYPT_COST',		10);
+define('ZBX_MD5_SIZE',			32);
+
 define('ZBX_SESSION_NAME', 'zbx_sessionid'); // Session cookie name for Zabbix front-end.
 
 define('ZBX_KIBIBYTE',	'1024');
Index: zabbix-4.0.12/frontends/php/include/schema.inc.php
===================================================================
--- zabbix-4.0.12.orig/frontends/php/include/schema.inc.php
+++ zabbix-4.0.12/frontends/php/include/schema.inc.php
@@ -29,7 +29,7 @@ return [
 			'passwd' => [
 				'null' => false,
 				'type' => DB::FIELD_TYPE_CHAR,
-				'length' => 32,
+				'length' => 60,
 				'default' => '',
 			],
 			'url' => [
Index: zabbix-4.0.12/database/ibm_db2/data.sql
===================================================================
--- zabbix-4.0.12.orig/database/ibm_db2/data.sql
+++ zabbix-4.0.12/database/ibm_db2/data.sql
@@ -1,5 +1,5 @@
-INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('1','Admin','Zabbix','Administrator','5fce1b3e34b520afeffb37ce08c7cd66','','1','0','en_GB','30s','3','default','50');
-INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('2','guest','','','d41d8cd98f00b204e9800998ecf8427e','','0','15m','en_GB','30s','1','default','50');
+INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('1','Admin','Zabbix','Administrator','$2y$10$92nDno4n0Zm7Ej7Jfsz8WukBfgSS/U0QkIuu8WkJPihXBb2A1UrEK','','1','0','en_GB','30s','3','default','50');
+INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('2','guest','','','$2y$10$89otZrRNmde97rIyzclecuk6LwKAsHN0BcvoOKGjbT.BwMBfm7G06','','0','15m','en_GB','30s','1','default','50');
 INSERT INTO hstgrp (groupid,name,internal,flags) values ('1','Templates','0','0');
 INSERT INTO hstgrp (groupid,name,internal,flags) values ('2','Linux servers','0','0');
 INSERT INTO hstgrp (groupid,name,internal,flags) values ('4','Zabbix servers','0','0');
Index: zabbix-4.0.12/database/ibm_db2/schema.sql
===================================================================
--- zabbix-4.0.12.orig/database/ibm_db2/schema.sql
+++ zabbix-4.0.12/database/ibm_db2/schema.sql
@@ -3,7 +3,7 @@ CREATE TABLE users (
 	alias                    varchar(100)    WITH DEFAULT ''           NOT NULL,
 	name                     varchar(100)    WITH DEFAULT ''           NOT NULL,
 	surname                  varchar(100)    WITH DEFAULT ''           NOT NULL,
-	passwd                   varchar(32)     WITH DEFAULT ''           NOT NULL,
+	passwd                   varchar(60)     WITH DEFAULT ''           NOT NULL,
 	url                      varchar(255)    WITH DEFAULT ''           NOT NULL,
 	autologin                integer         WITH DEFAULT '0'          NOT NULL,
 	autologout               varchar(32)     WITH DEFAULT '15m'        NOT NULL,
@@ -1762,7 +1762,7 @@ CREATE TABLE dbversion (
 	mandatory                integer         WITH DEFAULT '0'          NOT NULL,
 	optional                 integer         WITH DEFAULT '0'          NOT NULL
 );
-INSERT INTO dbversion VALUES ('4000000','4000004');
+INSERT INTO dbversion VALUES ('4000005','4000005');
 ALTER TABLE hosts ADD CONSTRAINT c_hosts_1 FOREIGN KEY (proxy_hostid) REFERENCES hosts (hostid);
 ALTER TABLE hosts ADD CONSTRAINT c_hosts_2 FOREIGN KEY (maintenanceid) REFERENCES maintenances (maintenanceid);
 ALTER TABLE hosts ADD CONSTRAINT c_hosts_3 FOREIGN KEY (templateid) REFERENCES hosts (hostid) ON DELETE CASCADE;
Index: zabbix-4.0.12/database/mysql/data.sql
===================================================================
--- zabbix-4.0.12.orig/database/mysql/data.sql
+++ zabbix-4.0.12/database/mysql/data.sql
@@ -1,6 +1,6 @@
 START TRANSACTION;
-INSERT INTO `users` (`userid`,`alias`,`name`,`surname`,`passwd`,`url`,`autologin`,`autologout`,`lang`,`refresh`,`type`,`theme`,`rows_per_page`) values ('1','Admin','Zabbix','Administrator','5fce1b3e34b520afeffb37ce08c7cd66','','1','0','en_GB','30s','3','default','50');
-INSERT INTO `users` (`userid`,`alias`,`name`,`surname`,`passwd`,`url`,`autologin`,`autologout`,`lang`,`refresh`,`type`,`theme`,`rows_per_page`) values ('2','guest','','','d41d8cd98f00b204e9800998ecf8427e','','0','15m','en_GB','30s','1','default','50');
+INSERT INTO `users` (`userid`,`alias`,`name`,`surname`,`passwd`,`url`,`autologin`,`autologout`,`lang`,`refresh`,`type`,`theme`,`rows_per_page`) values ('1','Admin','Zabbix','Administrator','$2y$10$92nDno4n0Zm7Ej7Jfsz8WukBfgSS/U0QkIuu8WkJPihXBb2A1UrEK','','1','0','en_GB','30s','3','default','50');
+INSERT INTO `users` (`userid`,`alias`,`name`,`surname`,`passwd`,`url`,`autologin`,`autologout`,`lang`,`refresh`,`type`,`theme`,`rows_per_page`) values ('2','guest','','','$2y$10$89otZrRNmde97rIyzclecuk6LwKAsHN0BcvoOKGjbT.BwMBfm7G06','','0','15m','en_GB','30s','1','default','50');
 INSERT INTO `hstgrp` (`groupid`,`name`,`internal`,`flags`) values ('1','Templates','0','0');
 INSERT INTO `hstgrp` (`groupid`,`name`,`internal`,`flags`) values ('2','Linux servers','0','0');
 INSERT INTO `hstgrp` (`groupid`,`name`,`internal`,`flags`) values ('4','Zabbix servers','0','0');
Index: zabbix-4.0.12/database/mysql/schema.sql
===================================================================
--- zabbix-4.0.12.orig/database/mysql/schema.sql
+++ zabbix-4.0.12/database/mysql/schema.sql
@@ -3,7 +3,7 @@ CREATE TABLE `users` (
 	`alias`                  varchar(100)    DEFAULT ''                NOT NULL,
 	`name`                   varchar(100)    DEFAULT ''                NOT NULL,
 	`surname`                varchar(100)    DEFAULT ''                NOT NULL,
-	`passwd`                 varchar(32)     DEFAULT ''                NOT NULL,
+	`passwd`                 varchar(60)     DEFAULT ''                NOT NULL,
 	`url`                    varchar(255)    DEFAULT ''                NOT NULL,
 	`autologin`              integer         DEFAULT '0'               NOT NULL,
 	`autologout`             varchar(32)     DEFAULT '15m'             NOT NULL,
@@ -1762,7 +1762,7 @@ CREATE TABLE `dbversion` (
 	`mandatory`              integer         DEFAULT '0'               NOT NULL,
 	`optional`               integer         DEFAULT '0'               NOT NULL
 ) ENGINE=InnoDB;
-INSERT INTO dbversion VALUES ('4000000','4000004');
+INSERT INTO dbversion VALUES ('4000005','4000005');
 ALTER TABLE `hosts` ADD CONSTRAINT `c_hosts_1` FOREIGN KEY (`proxy_hostid`) REFERENCES `hosts` (`hostid`);
 ALTER TABLE `hosts` ADD CONSTRAINT `c_hosts_2` FOREIGN KEY (`maintenanceid`) REFERENCES `maintenances` (`maintenanceid`);
 ALTER TABLE `hosts` ADD CONSTRAINT `c_hosts_3` FOREIGN KEY (`templateid`) REFERENCES `hosts` (`hostid`) ON DELETE CASCADE;
Index: zabbix-4.0.12/database/oracle/data.sql
===================================================================
--- zabbix-4.0.12.orig/database/oracle/data.sql
+++ zabbix-4.0.12/database/oracle/data.sql
@@ -1,10 +1,10 @@
 SET DEFINE OFF
 INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page)
-values ('1','Admin','Zabbix','Administrator','5fce1b3e34b520afeffb37ce08c7cd66','','1','0','en_GB','30s','3','default','50')
+values ('1','Admin','Zabbix','Administrator','$2y$10$92nDno4n0Zm7Ej7Jfsz8WukBfgSS/U0QkIuu8WkJPihXBb2A1UrEK','','1','0','en_GB','30s','3','default','50')
 /
 
 INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page)
-values ('2','guest','','','d41d8cd98f00b204e9800998ecf8427e','','0','15m','en_GB','30s','1','default','50')
+values ('2','guest','','','$2y$10$89otZrRNmde97rIyzclecuk6LwKAsHN0BcvoOKGjbT.BwMBfm7G06','','0','15m','en_GB','30s','1','default','50')
 /
 
 INSERT INTO hstgrp (groupid,name,internal,flags)
Index: zabbix-4.0.12/database/oracle/schema.sql
===================================================================
--- zabbix-4.0.12.orig/database/oracle/schema.sql
+++ zabbix-4.0.12/database/oracle/schema.sql
@@ -3,7 +3,7 @@ CREATE TABLE users (
 	alias                    nvarchar2(100)  DEFAULT ''                ,
 	name                     nvarchar2(100)  DEFAULT ''                ,
 	surname                  nvarchar2(100)  DEFAULT ''                ,
-	passwd                   nvarchar2(32)   DEFAULT ''                ,
+	passwd                   nvarchar2(60)   DEFAULT ''                ,
 	url                      nvarchar2(255)  DEFAULT ''                ,
 	autologin                number(10)      DEFAULT '0'               NOT NULL,
 	autologout               nvarchar2(32)   DEFAULT '15m'             ,
@@ -1762,7 +1762,7 @@ CREATE TABLE dbversion (
 	mandatory                number(10)      DEFAULT '0'               NOT NULL,
 	optional                 number(10)      DEFAULT '0'               NOT NULL
 );
-INSERT INTO dbversion VALUES ('4000000','4000004');
+INSERT INTO dbversion VALUES ('4000005','4000005');
 CREATE SEQUENCE proxy_history_seq
 START WITH 1
 INCREMENT BY 1
Index: zabbix-4.0.12/database/postgresql/data.sql
===================================================================
--- zabbix-4.0.12.orig/database/postgresql/data.sql
+++ zabbix-4.0.12/database/postgresql/data.sql
@@ -1,6 +1,6 @@
 START TRANSACTION;
-INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('1','Admin','Zabbix','Administrator','5fce1b3e34b520afeffb37ce08c7cd66','','1','0','en_GB','30s','3','default','50');
-INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('2','guest','','','d41d8cd98f00b204e9800998ecf8427e','','0','15m','en_GB','30s','1','default','50');
+INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('1','Admin','Zabbix','Administrator','$2y$10$92nDno4n0Zm7Ej7Jfsz8WukBfgSS/U0QkIuu8WkJPihXBb2A1UrEK','','1','0','en_GB','30s','3','default','50');
+INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('2','guest','','','$2y$10$89otZrRNmde97rIyzclecuk6LwKAsHN0BcvoOKGjbT.BwMBfm7G06','','0','15m','en_GB','30s','1','default','50');
 INSERT INTO hstgrp (groupid,name,internal,flags) values ('1','Templates','0','0');
 INSERT INTO hstgrp (groupid,name,internal,flags) values ('2','Linux servers','0','0');
 INSERT INTO hstgrp (groupid,name,internal,flags) values ('4','Zabbix servers','0','0');
Index: zabbix-4.0.12/database/postgresql/schema.sql
===================================================================
--- zabbix-4.0.12.orig/database/postgresql/schema.sql
+++ zabbix-4.0.12/database/postgresql/schema.sql
@@ -3,7 +3,7 @@ CREATE TABLE users (
 	alias                    varchar(100)    DEFAULT ''                NOT NULL,
 	name                     varchar(100)    DEFAULT ''                NOT NULL,
 	surname                  varchar(100)    DEFAULT ''                NOT NULL,
-	passwd                   varchar(32)     DEFAULT ''                NOT NULL,
+	passwd                   varchar(60)     DEFAULT ''                NOT NULL,
 	url                      varchar(255)    DEFAULT ''                NOT NULL,
 	autologin                integer         DEFAULT '0'               NOT NULL,
 	autologout               varchar(32)     DEFAULT '15m'             NOT NULL,
@@ -1762,7 +1762,7 @@ CREATE TABLE dbversion (
 	mandatory                integer         DEFAULT '0'               NOT NULL,
 	optional                 integer         DEFAULT '0'               NOT NULL
 );
-INSERT INTO dbversion VALUES ('4000000','4000004');
+INSERT INTO dbversion VALUES ('4000005','4000005');
 ALTER TABLE ONLY hosts ADD CONSTRAINT c_hosts_1 FOREIGN KEY (proxy_hostid) REFERENCES hosts (hostid);
 ALTER TABLE ONLY hosts ADD CONSTRAINT c_hosts_2 FOREIGN KEY (maintenanceid) REFERENCES maintenances (maintenanceid);
 ALTER TABLE ONLY hosts ADD CONSTRAINT c_hosts_3 FOREIGN KEY (templateid) REFERENCES hosts (hostid) ON DELETE CASCADE;
Index: zabbix-4.0.12/database/sqlite3/data.sql
===================================================================
--- zabbix-4.0.12.orig/database/sqlite3/data.sql
+++ zabbix-4.0.12/database/sqlite3/data.sql
@@ -1,6 +1,6 @@
 BEGIN TRANSACTION;
-INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('1','Admin','Zabbix','Administrator','5fce1b3e34b520afeffb37ce08c7cd66','','1','0','en_GB','30s','3','default','50');
-INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('2','guest','','','d41d8cd98f00b204e9800998ecf8427e','','0','15m','en_GB','30s','1','default','50');
+INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('1','Admin','Zabbix','Administrator','$2y$10$92nDno4n0Zm7Ej7Jfsz8WukBfgSS/U0QkIuu8WkJPihXBb2A1UrEK','','1','0','en_GB','30s','3','default','50');
+INSERT INTO users (userid,alias,name,surname,passwd,url,autologin,autologout,lang,refresh,type,theme,rows_per_page) values ('2','guest','','','$2y$10$89otZrRNmde97rIyzclecuk6LwKAsHN0BcvoOKGjbT.BwMBfm7G06','','0','15m','en_GB','30s','1','default','50');
 INSERT INTO hstgrp (groupid,name,internal,flags) values ('1','Templates','0','0');
 INSERT INTO hstgrp (groupid,name,internal,flags) values ('2','Linux servers','0','0');
 INSERT INTO hstgrp (groupid,name,internal,flags) values ('4','Zabbix servers','0','0');
Index: zabbix-4.0.12/database/sqlite3/schema.sql
===================================================================
--- zabbix-4.0.12.orig/database/sqlite3/schema.sql
+++ zabbix-4.0.12/database/sqlite3/schema.sql
@@ -3,7 +3,7 @@ CREATE TABLE users (
 	alias                    varchar(100)    DEFAULT ''                NOT NULL,
 	name                     varchar(100)    DEFAULT ''                NOT NULL,
 	surname                  varchar(100)    DEFAULT ''                NOT NULL,
-	passwd                   varchar(32)     DEFAULT ''                NOT NULL,
+	passwd                   varchar(60)     DEFAULT ''                NOT NULL,
 	url                      varchar(255)    DEFAULT ''                NOT NULL,
 	autologin                integer         DEFAULT '0'               NOT NULL,
 	autologout               varchar(32)     DEFAULT '15m'             NOT NULL,
@@ -1759,4 +1759,4 @@ CREATE TABLE dbversion (
 	mandatory                integer         DEFAULT '0'               NOT NULL,
 	optional                 integer         DEFAULT '0'               NOT NULL
 );
-INSERT INTO dbversion VALUES ('4000000','4000004');
+INSERT INTO dbversion VALUES ('4000005','4000005');
Index: zabbix-4.0.12/src/libs/zbxdbupgrade/dbupgrade_4000.c
===================================================================
--- zabbix-4.0.12.orig/src/libs/zbxdbupgrade/dbupgrade_4000.c
+++ zabbix-4.0.12/src/libs/zbxdbupgrade/dbupgrade_4000.c
@@ -252,6 +252,13 @@ static int	DBpatch_4000004(void)
 	return SUCCEED;
 }
 
+static int	DBpatch_4000005(void)
+{
+	const ZBX_FIELD	field = {"passwd", "", NULL, NULL, 60, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0};
+
+	return DBmodify_field_type("users", &field, NULL);
+}
+
 #endif
 
 DBPATCH_START(4000)
@@ -263,5 +270,6 @@ DBPATCH_ADD(4000001, 0, 0)
 DBPATCH_ADD(4000002, 0, 0)
 DBPATCH_ADD(4000003, 0, 0)
 DBPATCH_ADD(4000004, 0, 0)
+DBPATCH_ADD(4000005, 0, 1)
 
 DBPATCH_END()
openSUSE Build Service is sponsored by