From e5d2e82ef546b250dca16fecc344fa78af884aea Mon Sep 17 00:00:00 2001
From: rxu <rxu@mail.ru>
Date: Fri, 28 Jun 2024 11:08:46 +0700
Subject: [PATCH] [ticket/17351] Correctly handle md5 passwords rehashing

PHPBB-17351
---
 phpBB/phpbb/console/command/fixup/update_hashes.php | 10 +++++++++-
 phpBB/phpbb/cron/task/core/update_hashes.php        | 10 +++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/phpBB/phpbb/console/command/fixup/update_hashes.php b/phpBB/phpbb/console/command/fixup/update_hashes.php
index 8a2ef60771..5a9c12f2a5 100644
--- a/phpBB/phpbb/console/command/fixup/update_hashes.php
+++ b/phpBB/phpbb/console/command/fixup/update_hashes.php
@@ -100,7 +100,15 @@ class update_hashes extends \phpbb\console\command\command
 		while ($row = $this->db->sql_fetchrow($result))
 		{
 			$old_hash = preg_replace('/^\$CP\$/', '', $row['user_password']);
-			$new_hash = $this->passwords_manager->hash($old_hash, array($this->default_type));
+
+			// If stored hash type is unknown then it's md5 hash with no prefix
+			// First rehash it using $H$ as hash type identifier (salted_md5)
+			if (!$this->passwords_manager->detect_algorithm($old_hash))
+			{
+				$old_hash = $this->passwords_manager->hash($old_hash, '$H$');
+			}
+
+			$new_hash = $this->passwords_manager->hash($old_hash, [$this->default_type]);
 
 			$sql = 'UPDATE ' . USERS_TABLE . "
 					SET user_password = '" . $this->db->sql_escape($new_hash) . "'
diff --git a/phpBB/phpbb/cron/task/core/update_hashes.php b/phpBB/phpbb/cron/task/core/update_hashes.php
index 3348a4576e..78221bb35f 100644
--- a/phpBB/phpbb/cron/task/core/update_hashes.php
+++ b/phpBB/phpbb/cron/task/core/update_hashes.php
@@ -107,7 +107,15 @@ class update_hashes extends \phpbb\cron\task\base
 			while ($row = $this->db->sql_fetchrow($result))
 			{
 				$old_hash = preg_replace('/^\$CP\$/', '', $row['user_password']);
-				$new_hash = $this->passwords_manager->hash($old_hash, array($this->default_type));
+
+				// If stored hash type is unknown then it's md5 hash with no prefix
+				// First rehash it using $H$ as hash type identifier (salted_md5)
+				if (!$this->passwords_manager->detect_algorithm($old_hash))
+				{
+					$old_hash = $this->passwords_manager->hash($old_hash, '$H$');
+				}
+
+				$new_hash = $this->passwords_manager->hash($old_hash, [$this->default_type]);
 
 				// Increase number so we know that users were selected from the database
 				$affected_rows++;