From d7784e5e45cab354f3e7b1aa810020badcfe26bc Mon Sep 17 00:00:00 2001 From: Craig Knudsen Date: Tue, 15 Feb 2022 13:23:59 -0500 Subject: [PATCH] Manual merge of pull request 250 from master into bootstrap-ui: Upgrade password hashing function for better security --- includes/user.php | 28 +++++++++++++++++++++++----- install/index.php | 4 ++-- install/sql/tables-db2.sql | 2 +- install/sql/tables-ibase.sql | 2 +- install/sql/tables-mssql.sql | 2 +- install/sql/tables-mysql.sql | 2 +- install/sql/tables-oracle.sql | 2 +- install/sql/tables-postgres.sql | 2 +- install/sql/tables-sqlite.php | 2 +- install/sql/tables-sqlite3.php | 2 +- install/sql/upgrade-db2.sql | 1 + install/sql/upgrade-ibase.sql | 1 + install/sql/upgrade-mssql.sql | 1 + install/sql/upgrade-mysql.sql | 1 + install/sql/upgrade-oracle.sql | 1 + install/sql/upgrade-postgres.sql | 1 + install/sql/upgrade.sql | 2 ++ 17 files changed, 41 insertions(+), 15 deletions(-) diff --git a/includes/user.php b/includes/user.php index bbcdda58a..731ff6661 100644 --- a/includes/user.php +++ b/includes/user.php @@ -41,14 +41,32 @@ function user_valid_login ( $login, $password, $silent=false ) { global $error; $ret = $enabled = false; - $sql = 'SELECT cal_login, cal_enabled FROM webcal_user WHERE cal_login = ? AND cal_passwd = ?'; - $res = dbi_execute ( $sql, [$login, md5 ( $password )] ); + $sql = 'SELECT cal_login, cal_enabled, cal_passwd FROM webcal_user WHERE cal_login = ?'; + $res = dbi_execute ( $sql, [$login] ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( $row && $row[0] != '' ) { + // Check the password + $expected_hash = $row[2]; + if ( strlen ( $expected_hash ) == 32 && ctype_xdigit ( $expected_hash ) ) { + // Old-Style MD5 password + $supplied_hash = md5 ( $password ); + $okay = hash_equals ( $supplied_hash, $expected_hash ); + $rehash = true; + } else { + // New-Style Secure Password + $okay = password_verify ( $password, $expected_hash ); + $rehash = password_needs_rehash ( $expected_hash, PASSWORD_DEFAULT ); + } + // Upgrade insecurely stored passwords + if ( $okay && $rehash ){ + $new_hash = password_hash ( $password, PASSWORD_DEFAULT ); + $sql = 'UPDATE webcal_user SET cal_passwd = ? WHERE cal_login = ?'; + dbi_execute ( $sql, [$new_hash, $login] ); + } $enabled = ( $row[1] == 'Y' ? true : false ); // MySQL seems to do case insensitive matching, so double-check the login. - if ( $row[0] == $login ) + if ( $okay && $row[0] == $login ) $ret = true; // found login/password else if ( ! $silent ) $error = translate ( 'Invalid login', true ) . ': ' . @@ -221,7 +239,7 @@ function user_add_user ( $user, $password, $firstname, else $ulastname = NULL; if ( strlen ( $password ) ) - $upassword = md5 ( $password ); + $upassword = password_hash ( $password, PASSWORD_DEFAULT ); else $upassword = NULL; if ( $admin != 'Y' ) @@ -302,7 +320,7 @@ function user_update_user_password ( $user, $password ) { global $error; $sql = 'UPDATE webcal_user SET cal_passwd = ? WHERE cal_login = ?'; - if ( ! dbi_execute ( $sql, [md5 ( $password ), $user] ) ) { + if ( ! dbi_execute ( $sql, [password_hash ( $password , PASSWORD_DEFAULT ), $user] ) ) { $error = db_error(); return false; } diff --git a/install/index.php b/install/index.php index c7ef01f72..d3cff0159 100644 --- a/install/index.php +++ b/install/index.php @@ -371,14 +371,14 @@ db_populate( $install_filename, $display_sql ); } if( empty( $display_sql ) ) { - // Convert passwords to md5 hashes if needed. + // Convert passwords to secure hashes if needed. $res = dbi_execute( 'SELECT cal_login, cal_passwd FROM webcal_user', array(), false, $show_all_errors ); if( $res ) { while( $row = dbi_fetch_row( $res ) ) { if( strlen( $row[1] ) < 30 ) dbi_execute( 'UPDATE webcal_user SET cal_passwd = ? - WHERE cal_login = ?', array( md5( $row[1] ), $row[0] ) ); + WHERE cal_login = ?', array( password_hash( $row[1], PASSWORD_DEFAULT ), $row[0] ) ); } dbi_free_result( $res ); } diff --git a/install/sql/tables-db2.sql b/install/sql/tables-db2.sql index 790042188..5b52cd6a5 100644 --- a/install/sql/tables-db2.sql +++ b/install/sql/tables-db2.sql @@ -1,6 +1,6 @@ CREATE TABLE webcal_user ( cal_login VARCHAR(25) NOT NULL, - cal_passwd VARCHAR(32), + cal_passwd VARCHAR(255), cal_lastname VARCHAR(25), cal_firstname VARCHAR(25), cal_is_admin CHAR(1) DEFAULT 'N', diff --git a/install/sql/tables-ibase.sql b/install/sql/tables-ibase.sql index 077bd20e6..86ef80ccb 100644 --- a/install/sql/tables-ibase.sql +++ b/install/sql/tables-ibase.sql @@ -23,7 +23,7 @@ CREATE TABLE WEBCAL_ENTRY CREATE TABLE WEBCAL_USER ( CAL_LOGIN VARCHAR(25) CHARACTER SET WIN1252 NOT NULL, - CAL_PASSWD VARCHAR(32) CHARACTER SET WIN1252, + CAL_PASSWD VARCHAR(255) CHARACTER SET WIN1252, CAL_LASTNAME VARCHAR(25) CHARACTER SET WIN1252, CAL_FIRSTNAME VARCHAR(25) CHARACTER SET WIN1252, CAL_IS_ADMIN CHAR(1) CHARACTER SET WIN1252 DEFAULT 'N', diff --git a/install/sql/tables-mssql.sql b/install/sql/tables-mssql.sql index 71e9b18d8..255e77c6f 100644 --- a/install/sql/tables-mssql.sql +++ b/install/sql/tables-mssql.sql @@ -1,6 +1,6 @@ CREATE TABLE webcal_user ( cal_login VARCHAR(25) NOT NULL, - cal_passwd VARCHAR(32) NULL, + cal_passwd VARCHAR(255) NULL, cal_lastname VARCHAR(25) NULL, cal_firstname VARCHAR(25) NULL, cal_is_admin CHAR(1) DEFAULT 'N', diff --git a/install/sql/tables-mysql.sql b/install/sql/tables-mysql.sql index 31e73fb2f..d26a96b40 100644 --- a/install/sql/tables-mysql.sql +++ b/install/sql/tables-mysql.sql @@ -14,7 +14,7 @@ CREATE TABLE webcal_user ( /* the unique user login */ cal_login VARCHAR(25) NOT NULL, /* the user's password. (not used for http) */ - cal_passwd VARCHAR(32), + cal_passwd VARCHAR(255), /* user's last name */ cal_lastname VARCHAR(25), /* user's first name */ diff --git a/install/sql/tables-oracle.sql b/install/sql/tables-oracle.sql index 2b679ab86..703c6dd4f 100644 --- a/install/sql/tables-oracle.sql +++ b/install/sql/tables-oracle.sql @@ -8,7 +8,7 @@ CREATE TABLE webcal_user ( cal_lastname VARCHAR2(25), cal_is_admin CHAR(1) DEFAULT 'N', cal_last_login INT NULL, - cal_passwd VARCHAR2(32), + cal_passwd VARCHAR2(255), cal_telephone VARCHAR2(50) NULL, cal_title VARCHAR2(75) NULL, PRIMARY KEY ( cal_login ) diff --git a/install/sql/tables-postgres.sql b/install/sql/tables-postgres.sql index 1db246181..b34654bb2 100644 --- a/install/sql/tables-postgres.sql +++ b/install/sql/tables-postgres.sql @@ -1,6 +1,6 @@ CREATE TABLE webcal_user ( cal_login VARCHAR(25) NOT NULL, - cal_passwd VARCHAR(32), + cal_passwd VARCHAR(255), cal_lastname VARCHAR(25), cal_firstname VARCHAR(25), cal_is_admin CHAR(1) DEFAULT 'N', diff --git a/install/sql/tables-sqlite.php b/install/sql/tables-sqlite.php index 0b57753bf..ac4714303 100644 --- a/install/sql/tables-sqlite.php +++ b/install/sql/tables-sqlite.php @@ -4,7 +4,7 @@ * This file will create an SQLite database. */ function populate_sqlite_db ( $database, $db ) { - sqlite_query($db, "CREATE TABLE webcal_user (cal_login VARCHAR(25) NOT NULL, cal_passwd VARCHAR(32), cal_lastname VARCHAR(25), cal_firstname VARCHAR(25), cal_is_admin CHAR(1) DEFAULT 'N',cal_email VARCHAR(75) NULL,cal_enabled CHAR(1) DEFAULT 'Y',cal_telephone VARCHAR(50) NULL,cal_address VARCHAR(75) NULL,cal_title VARCHAR(75) NULL,cal_birthday INT,cal_last_login INT, PRIMARY KEY ( cal_login ))"); + sqlite_query($db, "CREATE TABLE webcal_user (cal_login VARCHAR(25) NOT NULL, cal_passwd VARCHAR(255), cal_lastname VARCHAR(25), cal_firstname VARCHAR(25), cal_is_admin CHAR(1) DEFAULT 'N',cal_email VARCHAR(75) NULL,cal_enabled CHAR(1) DEFAULT 'Y',cal_telephone VARCHAR(50) NULL,cal_address VARCHAR(75) NULL,cal_title VARCHAR(75) NULL,cal_birthday INT,cal_last_login INT, PRIMARY KEY ( cal_login ))"); sqlite_query($db, "INSERT INTO webcal_user ( cal_login, cal_passwd, cal_lastname, cal_firstname, cal_is_admin ) VALUES ( 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator', 'Default', 'Y' );"); sqlite_query($db, "CREATE TABLE webcal_entry ( cal_id INT NOT NULL, cal_group_id INT NULL, cal_ext_for_id INT NULL, cal_create_by VARCHAR(25) NOT NULL, cal_date INT NOT NULL, cal_time INT NULL, cal_mod_date INT, cal_mod_time INT, cal_duration INT NOT NULL, cal_due_date INT default NULL, cal_due_time INT default NULL, cal_location varchar(100) default NULL, cal_url varchar(100) default NULL, cal_completed INT default NULL, cal_priority INT DEFAULT 5, cal_type CHAR(1) DEFAULT 'E', cal_access CHAR(1) DEFAULT 'P', cal_name VARCHAR(80) NOT NULL, cal_description TEXT, PRIMARY KEY ( cal_id ))"); sqlite_query($db, "CREATE TABLE webcal_entry_repeats ( cal_id INT DEFAULT 0 NOT NULL, cal_type VARCHAR(20), cal_end INT, cal_frequency INT DEFAULT 1, cal_days CHAR(7), cal_endtime int(11) default NULL, cal_bymonth varchar(50) default NULL, cal_bymonthday varchar(100) default NULL, cal_byday varchar(100) default NULL, cal_bysetpos varchar(50) default NULL, cal_byweekno varchar(50) default NULL, cal_byyearday varchar(50) default NULL, cal_wkst char(2) default 'MO', cal_count int(11) default NULL, PRIMARY KEY (cal_id))"); diff --git a/install/sql/tables-sqlite3.php b/install/sql/tables-sqlite3.php index 6403d1877..08d97ab0a 100644 --- a/install/sql/tables-sqlite3.php +++ b/install/sql/tables-sqlite3.php @@ -5,7 +5,7 @@ */ function populate_sqlite_db ( $database, $db ) { #$c = new SQLite3 ( $database, SQLITE3_OPEN_CREATE ); - $db->query("CREATE TABLE webcal_user (cal_login VARCHAR(25) NOT NULL, cal_passwd VARCHAR(32), cal_lastname VARCHAR(25), cal_firstname VARCHAR(25), cal_is_admin CHAR(1) DEFAULT 'N',cal_email VARCHAR(75) NULL,cal_enabled CHAR(1) DEFAULT 'Y',cal_telephone VARCHAR(50) NULL,cal_address VARCHAR(75) NULL,cal_title VARCHAR(75) NULL,cal_birthday INT,cal_last_login INT, PRIMARY KEY ( cal_login ))"); + $db->query("CREATE TABLE webcal_user (cal_login VARCHAR(25) NOT NULL, cal_passwd VARCHAR(255), cal_lastname VARCHAR(25), cal_firstname VARCHAR(25), cal_is_admin CHAR(1) DEFAULT 'N',cal_email VARCHAR(75) NULL,cal_enabled CHAR(1) DEFAULT 'Y',cal_telephone VARCHAR(50) NULL,cal_address VARCHAR(75) NULL,cal_title VARCHAR(75) NULL,cal_birthday INT,cal_last_login INT, PRIMARY KEY ( cal_login ))"); $db->query("INSERT INTO webcal_user ( cal_login, cal_passwd, cal_lastname, cal_firstname, cal_is_admin ) VALUES ( 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator', 'Default', 'Y' );"); $db->query("CREATE TABLE webcal_entry ( cal_id INT NOT NULL, cal_group_id INT NULL, cal_ext_for_id INT NULL, cal_create_by VARCHAR(25) NOT NULL, cal_date INT NOT NULL, cal_time INT NULL, cal_mod_date INT, cal_mod_time INT, cal_duration INT NOT NULL, cal_due_date INT default NULL, cal_due_time INT default NULL, cal_location varchar(100) default NULL, cal_url varchar(100) default NULL, cal_completed INT default NULL, cal_priority INT DEFAULT 5, cal_type CHAR(1) DEFAULT 'E', cal_access CHAR(1) DEFAULT 'P', cal_name VARCHAR(80) NOT NULL, cal_description TEXT, PRIMARY KEY ( cal_id ))"); $db->query("CREATE TABLE webcal_entry_repeats ( cal_id INT DEFAULT 0 NOT NULL, cal_type VARCHAR(20), cal_end INT, cal_frequency INT DEFAULT 1, cal_days CHAR(7), cal_endtime int(11) default NULL, cal_bymonth varchar(50) default NULL, cal_bymonthday varchar(100) default NULL, cal_byday varchar(100) default NULL, cal_bysetpos varchar(50) default NULL, cal_byweekno varchar(50) default NULL, cal_byyearday varchar(50) default NULL, cal_wkst char(2) default 'MO', cal_count int(11) default NULL, PRIMARY KEY (cal_id))"); diff --git a/install/sql/upgrade-db2.sql b/install/sql/upgrade-db2.sql index f4581edf1..df629e9d4 100644 --- a/install/sql/upgrade-db2.sql +++ b/install/sql/upgrade-db2.sql @@ -288,3 +288,4 @@ CREATE TABLE webcal_timezones ( ); /*upgrade_v1.3.0*/ +ALTER TABLE webcal_user MODIFY cal_passwd VARCHAR(255); \ No newline at end of file diff --git a/install/sql/upgrade-ibase.sql b/install/sql/upgrade-ibase.sql index bfef022cb..d86e5be60 100644 --- a/install/sql/upgrade-ibase.sql +++ b/install/sql/upgrade-ibase.sql @@ -302,3 +302,4 @@ CREATE TABLE webcal_TIMEZONES ( ); CREATE INDEX IWEBCAL_TIMEZONESNEWINDEX ON WEBCAL_TIMEZONES(TZID); /*upgrade_v1.3.0*/ +ALTER TABLE WEBCAL_USER ALTER CAL_PASSWD VARCHAR(255); \ No newline at end of file diff --git a/install/sql/upgrade-mssql.sql b/install/sql/upgrade-mssql.sql index 0bb9215b8..10ca50208 100644 --- a/install/sql/upgrade-mssql.sql +++ b/install/sql/upgrade-mssql.sql @@ -288,3 +288,4 @@ CREATE TABLE webcal_timezones ( PRIMARY KEY ( tzid ) ); /*upgrade_v1.3.0*/ +ALTER TABLE webcal_user MODIFY cal_passwd VARCHAR(255) NULL; \ No newline at end of file diff --git a/install/sql/upgrade-mysql.sql b/install/sql/upgrade-mysql.sql index ca8c25dc5..0fcd40ad4 100644 --- a/install/sql/upgrade-mysql.sql +++ b/install/sql/upgrade-mysql.sql @@ -267,3 +267,4 @@ CREATE INDEX IF NOT EXISTS webcal_import_data_type ON webcal_import_data(cal_import_type); CREATE INDEX IF NOT EXISTS webcal_import_data_ext_id ON webcal_import_data(cal_external_id); +ALTER TABLE webcal_user MODIFY cal_passwd VARCHAR(255); diff --git a/install/sql/upgrade-oracle.sql b/install/sql/upgrade-oracle.sql index 7778ba655..ffdea7fe2 100644 --- a/install/sql/upgrade-oracle.sql +++ b/install/sql/upgrade-oracle.sql @@ -288,3 +288,4 @@ CREATE TABLE webcal_timezones ( PRIMARY KEY ( tzid ) ); /*upgrade_v1.3.0*/ +ALTER TABLE webcal_user MODIFY cal_passwd VARCHAR2(255) NULL; \ No newline at end of file diff --git a/install/sql/upgrade-postgres.sql b/install/sql/upgrade-postgres.sql index 7bfade2b7..8b7606aa7 100644 --- a/install/sql/upgrade-postgres.sql +++ b/install/sql/upgrade-postgres.sql @@ -306,3 +306,4 @@ CREATE TABLE webcal_timezones ( PRIMARY KEY ( tzid ) ); /*upgrade_v1.3.0*/ +ALTER TABLE webcal_user ALTER COLUMN cal_passwd TYPE VARCHAR(255); \ No newline at end of file diff --git a/install/sql/upgrade.sql b/install/sql/upgrade.sql index 3105a4aba..adcebcb16 100644 --- a/install/sql/upgrade.sql +++ b/install/sql/upgrade.sql @@ -607,3 +607,5 @@ ALTER TABLE webcal_view MODIFY cal_view_id int UNSIGNED NOT NULL AUTO_INCREMENT ALTER TABLE webcal_view_user ENGINE MyISAM CHARACTER SET utf8 COMMENT '''Specify users in a view.'; ALTER TABLE webcal_view_user MODIFY cal_login varchar(25) NOT NULL COMMENT 'A user in the view. From webcal_user table.'; ALTER TABLE webcal_view_user MODIFY cal_view_id int UNSIGNED NOT NULL COMMENT 'view id from webcal_view table.' FIRST; +/*upgrade_v1.3.1*/ +ALTER TABLE webcal_user MODIFY cal_passwd VARCHAR(255); \ No newline at end of file