diff options
Diffstat (limited to 'phpBB')
39 files changed, 1086 insertions, 215 deletions
diff --git a/phpBB/config/auth_providers.yml b/phpBB/config/auth_providers.yml index dac8b9d252..d2f22ec477 100644 --- a/phpBB/config/auth_providers.yml +++ b/phpBB/config/auth_providers.yml @@ -1,8 +1,9 @@ services: auth.provider_collection: - class: phpbb\di\service_collection + class: phpbb\auth\provider_collection arguments: - @service_container + - @config tags: - { name: service_collection, tag: auth.provider } auth.provider.db: diff --git a/phpBB/config/console.yml b/phpBB/config/console.yml index 9b0f0aa9a4..00b8f9cec0 100644 --- a/phpBB/config/console.yml +++ b/phpBB/config/console.yml @@ -75,6 +75,13 @@ services: tags: - { name: console.command } + console.command.dev.migration_tips: + class: phpbb\console\command\dev\migration_tips + arguments: + - @ext.manager + tags: + - { name: console.command } + console.command.extension.disable: class: phpbb\console\command\extension\disable arguments: diff --git a/phpBB/config/passwords.yml b/phpBB/config/passwords.yml index 9e249a2c12..3dc217286f 100644 --- a/phpBB/config/passwords.yml +++ b/phpBB/config/passwords.yml @@ -22,6 +22,14 @@ services: tags: - { name: passwords.driver } + passwords.driver.bcrypt_wcf2: + class: phpbb\passwords\driver\bcrypt_wcf2 + arguments: + - @passwords.driver.bcrypt + - @passwords.driver_helper + tags: + - { name: passwords.driver } + passwords.driver.salted_md5: class: phpbb\passwords\driver\salted_md5 arguments: @@ -38,6 +46,64 @@ services: tags: - { name: passwords.driver } + passwords.driver.convert_password: + class: phpbb\passwords\driver\convert_password + arguments: + - @config + - @passwords.driver_helper + tags: + - { name: passwords.driver } + + passwords.driver.sha1_smf: + class: phpbb\passwords\driver\sha1_smf + arguments: + - @config + - @passwords.driver_helper + tags: + - { name: passwords.driver } + + passwords.driver.sha1_wcf1: + class: phpbb\passwords\driver\sha1_wcf1 + arguments: + - @config + - @passwords.driver_helper + tags: + - { name: passwords.driver } + + passwords.driver.sha1: + class: phpbb\passwords\driver\sha1 + arguments: + - @config + - @passwords.driver_helper + tags: + - { name: passwords.driver } + + passwords.driver.md5_phpbb2: + class: phpbb\passwords\driver\md5_phpbb2 + arguments: + - @request + - @passwords.driver.salted_md5 + - %core.root_path% + - %core.php_ext% + tags: + - { name: passwords.driver } + + passwords.driver.md5_mybb: + class: phpbb\passwords\driver\md5_mybb + arguments: + - @config + - @passwords.driver_helper + tags: + - { name: passwords.driver } + + passwords.driver.md5_vb: + class: phpbb\passwords\driver\md5_vb + arguments: + - @config + - @passwords.driver_helper + tags: + - { name: passwords.driver } + passwords.driver_collection: class: phpbb\di\service_collection arguments: diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 5490e45afa..05085d39ab 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -44,17 +44,9 @@ require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx); $phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx); $phpbb_class_loader->register(); -class phpbb_extension_empty_manager extends \phpbb\extension\manager -{ - public function __construct() - { - $this->extensions = array(); - } -} - -$finder = new \phpbb\extension\finder(new \phpbb_extension_empty_manager(), new \phpbb\filesystem(), $phpbb_root_path); +$finder = new \phpbb\finder(new \phpbb\filesystem(), $phpbb_root_path); $classes = $finder->core_path('phpbb/') - ->directory('db/migration/data') + ->directory('/db/migration/data') ->get_classes(); $db = new \phpbb\db\driver\sqlite(); diff --git a/phpBB/develop/migration_tips.php b/phpBB/develop/migration_tips.php deleted file mode 100644 index fdb1e4544d..0000000000 --- a/phpBB/develop/migration_tips.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** -* -* This file is part of the phpBB Forum Software package. -* -* @copyright (c) phpBB Limited <https://www.phpbb.com> -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -// This is to help with creating migration files for new versions -// Use this to find what migrations are not depended on by any other migration -// (the current migration tree tips) - -define('IN_PHPBB', true); -$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; -$phpEx = substr(strrchr(__FILE__, '.'), 1); -include($phpbb_root_path . 'common.' . $phpEx); - -$phpbb_extension_manager = $phpbb_container->get('ext.manager'); -$finder = $phpbb_extension_manager->get_finder(); - -$migrations = $finder - ->core_path('phpbb/db/migration/data/') - ->get_classes(); -$tips = $migrations; - -foreach ($migrations as $migration_class) -{ - foreach ($migration_class::depends_on() as $dependency) - { - if (($tips_key = array_search($dependency, $tips)) !== false) - { - unset($tips[$tips_key]); - } - } -} - -foreach ($tips as $migration) -{ - echo "\t\t\t'{$migration}',\n"; -} - diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index 973e0e65c5..f10f0b1015 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -513,7 +513,7 @@ class acp_groups 'test_variables', ); extract($phpbb_dispatcher->trigger_event('core.acp_manage_group_initialise_data', compact($vars))); - + foreach ($test_variables as $test => $type) { if (isset($submit_ary[$test]) && ($action == 'add' || $group_row['group_' . $test] != $submit_ary[$test] || isset($group_attributes['group_avatar']) && strpos($test, 'avatar') === 0 || in_array($test, $set_attributes))) diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 61bae18557..5932f4cddd 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -561,14 +561,14 @@ class acp_modules $directory = $phpbb_root_path . 'includes/' . $module_class . '/info/'; $fileinfo = array(); - $finder = $phpbb_extension_manager->get_finder(); + $finder = $phpbb_extension_manager->get_finder($use_all_available); $modules = $finder ->extension_suffix('_module') ->extension_directory("/$module_class") ->core_path("includes/$module_class/info/") ->core_prefix($module_class . '_') - ->get_classes(true, $use_all_available); + ->get_classes(true); foreach ($modules as $cur_module) { diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 83ab88d48c..d07120a65f 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -922,7 +922,6 @@ class acp_users $sql_ary += array( 'user_password' => $passwords_manager->hash($data['new_password']), 'user_passchg' => time(), - 'user_pass_convert' => 0, ); $user->reset_login_keys($user_id); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index dafbb54af5..9d94ef2be4 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2854,7 +2854,8 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa $s_hidden_fields['credential'] = $credential; } - $auth_provider = $phpbb_container->get('auth.provider.' . $config['auth_method']); + $provider_collection = $phpbb_container->get('auth.provider_collection'); + $auth_provider = $provider_collection->get_provider(); $auth_provider_data = $auth_provider->get_login_data(); if ($auth_provider_data) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 22b8a8825e..4606a9f7ca 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -1371,7 +1371,7 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, */ function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank_img_src) { - global $ranks, $config, $phpbb_root_path; + global $ranks, $config, $phpbb_root_path, $phpbb_path_helper; if (empty($ranks)) { @@ -1382,8 +1382,8 @@ function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank if (!empty($user_rank)) { $rank_title = (isset($ranks['special'][$user_rank]['rank_title'])) ? $ranks['special'][$user_rank]['rank_title'] : ''; - $rank_img = (!empty($ranks['special'][$user_rank]['rank_image'])) ? '<img src="' . $phpbb_root_path . $config['ranks_path'] . '/' . $ranks['special'][$user_rank]['rank_image'] . '" alt="' . $ranks['special'][$user_rank]['rank_title'] . '" title="' . $ranks['special'][$user_rank]['rank_title'] . '" />' : ''; - $rank_img_src = (!empty($ranks['special'][$user_rank]['rank_image'])) ? $phpbb_root_path . $config['ranks_path'] . '/' . $ranks['special'][$user_rank]['rank_image'] : ''; + $rank_img_src = (!empty($ranks['special'][$user_rank]['rank_image'])) ? $phpbb_path_helper->update_web_root_path($phpbb_root_path . $config['ranks_path'] . '/' . $ranks['special'][$user_rank]['rank_image']) : ''; + $rank_img = (!empty($ranks['special'][$user_rank]['rank_image'])) ? '<img src="' . $rank_img_src . '" alt="' . $ranks['special'][$user_rank]['rank_title'] . '" title="' . $ranks['special'][$user_rank]['rank_title'] . '" />' : ''; } else if ($user_posts !== false) { @@ -1394,8 +1394,8 @@ function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank if ($user_posts >= $rank['rank_min']) { $rank_title = $rank['rank_title']; - $rank_img = (!empty($rank['rank_image'])) ? '<img src="' . $phpbb_root_path . $config['ranks_path'] . '/' . $rank['rank_image'] . '" alt="' . $rank['rank_title'] . '" title="' . $rank['rank_title'] . '" />' : ''; - $rank_img_src = (!empty($rank['rank_image'])) ? $phpbb_root_path . $config['ranks_path'] . '/' . $rank['rank_image'] : ''; + $rank_img_src = (!empty($rank['rank_image'])) ? $phpbb_path_helper->update_web_root_path($phpbb_root_path . $config['ranks_path'] . '/' . $rank['rank_image']) : ''; + $rank_img = (!empty($rank['rank_image'])) ? '<img src="' . $rank_img_src . '" alt="' . $rank['rank_title'] . '" title="' . $rank['rank_title'] . '" />' : ''; break; } } diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index fafe29f957..d728ed7d78 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -184,7 +184,6 @@ function user_add($user_row, $cp_data = false) 'username' => $user_row['username'], 'username_clean' => $username_clean, 'user_password' => (isset($user_row['user_password'])) ? $user_row['user_password'] : '', - 'user_pass_convert' => 0, 'user_email' => strtolower($user_row['user_email']), 'user_email_hash' => phpbb_email_hash($user_row['user_email']), 'group_id' => $user_row['group_id'], diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php index 06326e57e6..53dec89aad 100644 --- a/phpBB/includes/ucp/ucp_activate.php +++ b/phpBB/includes/ucp/ucp_activate.php @@ -78,7 +78,6 @@ class ucp_activate 'user_actkey' => '', 'user_password' => $user_row['user_newpasswd'], 'user_newpasswd' => '', - 'user_pass_convert' => 0, 'user_login_attempts' => 0, ); diff --git a/phpBB/install/schemas/schema.json b/phpBB/install/schemas/schema.json index f684fddc25..79f06693a6 100644 --- a/phpBB/install/schemas/schema.json +++ b/phpBB/install/schemas/schema.json @@ -3023,10 +3023,6 @@ "TIMESTAMP", 0 ], - "user_pass_convert": [ - "BOOL", - 0 - ], "user_email": [ "VCHAR_UNI:100", "" diff --git a/phpBB/phpbb/auth/provider/db.php b/phpBB/phpbb/auth/provider/db.php index 3be1d3873f..142a47247f 100644 --- a/phpBB/phpbb/auth/provider/db.php +++ b/phpBB/phpbb/auth/provider/db.php @@ -78,7 +78,7 @@ class db extends \phpbb\auth\provider\base $username_clean = utf8_clean_string($username); - $sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts + $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type, user_login_attempts FROM ' . USERS_TABLE . " WHERE username_clean = '" . $this->db->sql_escape($username_clean) . "'"; $result = $this->db->sql_query($sql); @@ -170,72 +170,8 @@ class db extends \phpbb\auth\provider\base } - // If the password convert flag is set we need to convert it - if ($row['user_pass_convert']) - { - // enable super globals to get literal value - // this is needed to prevent unicode normalization - $super_globals_disabled = $this->request->super_globals_disabled(); - if ($super_globals_disabled) - { - $this->request->enable_super_globals(); - } - - // in phpBB2 passwords were used exactly as they were sent, with addslashes applied - $password_old_format = isset($_REQUEST['password']) ? (string) $_REQUEST['password'] : ''; - $password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format; - $password_new_format = $this->request->variable('password', '', true); - - if ($super_globals_disabled) - { - $this->request->disable_super_globals(); - } - - if ($password == $password_new_format) - { - if (!function_exists('utf8_to_cp1252')) - { - include($this->phpbb_root_path . 'includes/utf/data/recode_basic.' . $this->php_ext); - } - - // cp1252 is phpBB2's default encoding, characters outside ASCII range might work when converted into that encoding - // plain md5 support left in for conversions from other systems. - if ((strlen($row['user_password']) == 34 && ($this->passwords_manager->check(md5($password_old_format), $row['user_password']) || $this->passwords_manager->check(md5(utf8_to_cp1252($password_old_format)), $row['user_password']))) - || (strlen($row['user_password']) == 32 && (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password']))) - { - $hash = $this->passwords_manager->hash($password_new_format); - - // Update the password in the users table to the new format and remove user_pass_convert flag - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_password = \'' . $this->db->sql_escape($hash) . '\', - user_pass_convert = 0 - WHERE user_id = ' . $row['user_id']; - $this->db->sql_query($sql); - - $row['user_pass_convert'] = 0; - $row['user_password'] = $hash; - } - else - { - // Although we weren't able to convert this password we have to - // increase login attempt count to make sure this cannot be exploited - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_login_attempts = user_login_attempts + 1 - WHERE user_id = ' . (int) $row['user_id'] . ' - AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX; - $this->db->sql_query($sql); - - return array( - 'status' => LOGIN_ERROR_PASSWORD_CONVERT, - 'error_msg' => 'LOGIN_ERROR_PASSWORD_CONVERT', - 'user_row' => $row, - ); - } - } - } - // Check password ... - if (!$row['user_pass_convert'] && $this->passwords_manager->check($password, $row['user_password'])) + if ($this->passwords_manager->check($password, $row['user_password'])) { // Check for old password hash... if ($this->passwords_manager->convert_flag || strlen($row['user_password']) == 32) @@ -244,8 +180,7 @@ class db extends \phpbb\auth\provider\base // Update the password in the users table to the new format $sql = 'UPDATE ' . USERS_TABLE . " - SET user_password = '" . $this->db->sql_escape($hash) . "', - user_pass_convert = 0 + SET user_password = '" . $this->db->sql_escape($hash) . "' WHERE user_id = {$row['user_id']}"; $this->db->sql_query($sql); diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index 2230ce15d1..07430bb42a 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -215,7 +215,7 @@ class oauth extends \phpbb\auth\provider\base } // Retrieve the user's account - $sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts + $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type, user_login_attempts FROM ' . $this->users_table . ' WHERE user_id = ' . (int) $row['user_id']; $result = $this->db->sql_query($sql); diff --git a/phpBB/phpbb/auth/provider_collection.php b/phpBB/phpbb/auth/provider_collection.php new file mode 100644 index 0000000000..27a3f24564 --- /dev/null +++ b/phpBB/phpbb/auth/provider_collection.php @@ -0,0 +1,65 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\auth; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** +* Collection of auth providers to be configured at container compile time. +*/ +class provider_collection extends \phpbb\di\service_collection +{ + /** @var \phpbb\config\config phpBB Config */ + protected $config; + + /** + * Constructor + * + * @param ContainerInterface $container Container object + * @param \phpbb\config\config $config phpBB config + */ + public function __construct($container, \phpbb\config\config $config) + { + $this->container = $container; + $this->config = $config; + } + + /** + * Get an auth provider. + * + * @return object Default auth provider selected in config if it + * does exist. Otherwise the standard db auth + * provider. + * @throws \RuntimeException If neither the auth provider that + * is specified by the phpBB config nor the db + * auth provider exist. The db auth provider + * should always exist in a phpBB installation. + */ + public function get_provider() + { + if ($this->offsetExists('auth.provider.' . basename(trim($this->config['auth_method'])))) + { + return $this->offsetGet('auth.provider.' . basename(trim($this->config['auth_method']))); + } + // Revert to db auth provider if selected method does not exist + elseif ($this->offsetExists('auth.provider.db')) + { + return $this->offsetGet('auth.provider.db'); + } + else + { + throw new \RuntimeException(sprintf('The authentication provider for the authentication method "%1$s" does not exist. It was not possible to recover from this by reverting to the database authentication provider.', $this->config['auth_method'])); + } + } +} diff --git a/phpBB/phpbb/console/command/dev/migration_tips.php b/phpBB/phpbb/console/command/dev/migration_tips.php new file mode 100644 index 0000000000..c2f61568ea --- /dev/null +++ b/phpBB/phpbb/console/command/dev/migration_tips.php @@ -0,0 +1,64 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ +namespace phpbb\console\command\dev; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class migration_tips extends \phpbb\console\command\command +{ + /** @var \phpbb\extension\manager */ + protected $extension_manager; + + function __construct(\phpbb\extension\manager $extension_manager) + { + $this->extension_manager = $extension_manager; + parent::__construct(); + } + + protected function configure() + { + $this + ->setName('dev:migration-tips') + ->setDescription('Finds migrations that are not depended on.') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $migrations = $this->extension_manager->get_finder() + ->set_extensions(array()) + ->core_path('phpbb/db/migration/data/') + ->get_classes(); + $tips = $migrations; + + foreach ($migrations as $migration_class) + { + foreach ($migration_class::depends_on() as $dependency) + { + $tips_key = array_search($dependency, $tips); + if ($tips_key !== false) + { + unset($tips[$tips_key]); + } + } + } + + $output->writeln("\t\tarray("); + foreach ($tips as $migration) + { + $output->writeln("\t\t\t'{$migration}',"); + } + $output->writeln("\t\t);"); + } +} diff --git a/phpBB/phpbb/controller/provider.php b/phpBB/phpbb/controller/provider.php index 91f3a07fb1..bd85385a41 100644 --- a/phpBB/phpbb/controller/provider.php +++ b/phpBB/phpbb/controller/provider.php @@ -46,10 +46,10 @@ class provider } /** - * @param \phpbb\extension\finder $finder + * @param \phpbb\finder $finder * @return null */ - public function find_routing_files(\phpbb\extension\finder $finder) + public function find_routing_files(\phpbb\finder $finder) { // We hardcode the path to the core config directory // because the finder cannot find it diff --git a/phpBB/phpbb/db/migration/data/v310/passwords_convert_p1.php b/phpBB/phpbb/db/migration/data/v310/passwords_convert_p1.php new file mode 100644 index 0000000000..004d94d8bd --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/passwords_convert_p1.php @@ -0,0 +1,85 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v310; + +class passwords_convert_p1 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\passwords_p2'); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'update_passwords'))), + ); + } + + public function update_passwords($start) + { + // Nothing to do if user_pass_convert column doesn't exist + if (!$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_pass_convert')) + { + return; + } + + $start = (int) $start; + $limit = 1000; + $converted_users = 0; + + $sql = 'SELECT user_password, user_id + FROM ' . $this->table_prefix . 'users + WHERE user_pass_convert = 1 + GROUP BY user_id + ORDER BY user_id'; + $result = $this->db->sql_query_limit($sql, $limit, $start); + + $update_users = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $converted_users++; + + $user_id = (int) $row['user_id']; + // Only prefix passwords without proper prefix + if (!isset($update_users[$user_id]) && !preg_match('#^\$([a-zA-Z0-9\\\]*?)\$#', $row['user_password'])) + { + // Use $CP$ prefix for passwords that need to + // be converted and set pass convert to false. + $update_users[$user_id] = array( + 'user_password' => '$CP$' . $row['user_password'], + 'user_pass_convert' => 0, + ); + } + } + $this->db->sql_freeresult($result); + + foreach ($update_users as $user_id => $user_data) + { + $sql = 'UPDATE ' . $this->table_prefix . 'users + SET ' . $this->db->sql_build_array('UPDATE', $user_data) . ' + WHERE user_id = ' . $user_id; + $this->sql_query($sql); + } + + if ($converted_users < $limit) + { + // There are no more users to be converted + return; + } + + // There are still more users to query, return the next start value + return $start + $limit; + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/passwords_convert_p2.php b/phpBB/phpbb/db/migration/data/v310/passwords_convert_p2.php new file mode 100644 index 0000000000..26a99184a6 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/passwords_convert_p2.php @@ -0,0 +1,49 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v310; + +class passwords_convert_p2 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_pass_convert'); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\passwords_convert_p1'); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'users' => array( + 'user_pass_convert', + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'users' => array( + 'user_pass_convert' => array('BOOL', 0, 'after' => 'user_passchg'), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 9b9532a7ad..5255c73c1c 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -714,7 +714,7 @@ class migrator /** * Load migration data files from a directory * - * @param \phpbb\extension\finder $finder + * @param \phpbb\finder $finder * @param string $path Path to migration data files * @param bool $check_fulfillable If TRUE (default), we will check * if all of the migrations are fulfillable after loading them. @@ -723,7 +723,7 @@ class migrator * with the last call to prevent throwing errors unnecessarily). * @return array Array of migration names */ - public function load_migrations(\phpbb\extension\finder $finder, $path, $check_fulfillable = true) + public function load_migrations(\phpbb\finder $finder, $path, $check_fulfillable = true) { if (!is_dir($path)) { diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index eb306aeb72..cbbd7bc622 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -23,7 +23,7 @@ class base implements \phpbb\extension\extension_interface /** @var ContainerInterface */ protected $container; - /** @var \phpbb\extension\finder */ + /** @var \phpbb\finder */ protected $finder; /** @var \phpbb\db\migrator */ @@ -39,11 +39,11 @@ class base implements \phpbb\extension\extension_interface * Constructor * * @param ContainerInterface $container Container object - * @param \phpbb\extension\finder $extension_finder + * @param \phpbb\finder $extension_finder * @param string $extension_name Name of this extension (from ext.manager) * @param string $extension_path Relative path to this extension */ - public function __construct(ContainerInterface $container, \phpbb\extension\finder $extension_finder, \phpbb\db\migrator $migrator, $extension_name, $extension_path) + public function __construct(ContainerInterface $container, \phpbb\finder $extension_finder, \phpbb\db\migrator $migrator, $extension_name, $extension_path) { $this->container = $container; $this->extension_finder = $extension_finder; diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index cd7289e085..b83bb1b189 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -532,12 +532,22 @@ class manager } /** - * Instantiates a \phpbb\extension\finder. + * Instantiates a \phpbb\finder. * - * @return \phpbb\extension\finder An extension finder instance + * @param bool $use_all_available Should we load all extensions, or just enabled ones + * @return \phpbb\finder An extension finder instance */ - public function get_finder() + public function get_finder($use_all_available = false) { - return new \phpbb\extension\finder($this, $this->filesystem, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder'); + $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder'); + if ($use_all_available) + { + $finder->set_extensions(array_keys($this->all_available())); + } + else + { + $finder->set_extensions(array_keys($this->all_enabled())); + } + return $finder; } } diff --git a/phpBB/phpbb/extension/finder.php b/phpBB/phpbb/finder.php index 6f2408094e..28f28825ba 100644 --- a/phpBB/phpbb/extension/finder.php +++ b/phpBB/phpbb/finder.php @@ -11,14 +11,14 @@ * */ -namespace phpbb\extension; +namespace phpbb; /** -* The extension finder provides a simple way to locate files in active extensions +* The finder provides a simple way to locate files in the core and a set of extensions */ class finder { - protected $extension_manager; + protected $extensions; protected $filesystem; protected $phpbb_root_path; protected $cache; @@ -48,9 +48,6 @@ class finder /** * Creates a new finder instance with its dependencies * - * @param \phpbb\extension\manager $extension_manager An extension manager - * instance that provides the finder with a list of active - * extensions and their locations * @param \phpbb\filesystem $filesystem Filesystem instance * @param string $phpbb_root_path Path to the phpbb root directory * @param \phpbb\cache\driver\driver_interface $cache A cache instance or null @@ -58,9 +55,8 @@ class finder * @param string $cache_name The name of the cache variable, defaults to * _ext_finder */ - public function __construct(\phpbb\extension\manager $extension_manager, \phpbb\filesystem $filesystem, $phpbb_root_path = '', \phpbb\cache\driver\driver_interface $cache = null, $php_ext = 'php', $cache_name = '_ext_finder') + public function __construct(\phpbb\filesystem $filesystem, $phpbb_root_path = '', \phpbb\cache\driver\driver_interface $cache = null, $php_ext = 'php', $cache_name = '_ext_finder') { - $this->extension_manager = $extension_manager; $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; $this->cache = $cache; @@ -76,15 +72,37 @@ class finder 'extension_prefix' => false, 'extension_directory' => false, ); + $this->extensions = array(); $this->cached_queries = ($this->cache) ? $this->cache->get($this->cache_name) : false; } /** + * Set the array of extensions + * + * @param array $extensions A list of extensions that should be searched aswell + * @param bool $replace_list Should the list be emptied before adding the extensions + * @return \phpbb\finder This object for chaining calls + */ + public function set_extensions(array $extensions, $replace_list = true) + { + if ($replace_list) + { + $this->extensions = array(); + } + + foreach ($extensions as $ext_name) + { + $this->extensions[$ext_name] = $this->phpbb_root_path . 'ext/' . $ext_name . '/'; + } + return $this; + } + + /** * Sets a core path to be searched in addition to extensions * * @param string $core_path The path relative to phpbb_root_path - * @return \phpbb\extension\finder This object for chaining calls + * @return \phpbb\finder This object for chaining calls */ public function core_path($core_path) { @@ -100,7 +118,7 @@ class finder * file extension is automatically added to suffixes. * * @param string $suffix A filename suffix - * @return \phpbb\extension\finder This object for chaining calls + * @return \phpbb\finder This object for chaining calls */ public function suffix($suffix) { @@ -117,7 +135,7 @@ class finder * file extension is automatically added to suffixes. * * @param string $extension_suffix A filename suffix - * @return \phpbb\extension\finder This object for chaining calls + * @return \phpbb\finder This object for chaining calls */ public function extension_suffix($extension_suffix) { @@ -133,7 +151,7 @@ class finder * file extension is automatically added to suffixes. * * @param string $core_suffix A filename suffix - * @return \phpbb\extension\finder This object for chaining calls + * @return \phpbb\finder This object for chaining calls */ public function core_suffix($core_suffix) { @@ -145,7 +163,7 @@ class finder * Sets the prefix all files found in extensions and core must match * * @param string $prefix A filename prefix - * @return \phpbb\extension\finder This object for chaining calls + * @return \phpbb\finder This object for chaining calls */ public function prefix($prefix) { @@ -158,7 +176,7 @@ class finder * Sets a prefix all files found in extensions must match * * @param string $extension_prefix A filename prefix - * @return \phpbb\extension\finder This object for chaining calls + * @return \phpbb\finder This object for chaining calls */ public function extension_prefix($extension_prefix) { @@ -170,7 +188,7 @@ class finder * Sets a prefix all files found in the core path must match * * @param string $core_prefix A filename prefix - * @return \phpbb\extension\finder This object for chaining calls + * @return \phpbb\finder This object for chaining calls */ public function core_prefix($core_prefix) { @@ -185,7 +203,7 @@ class finder * the current directory. * * @param string $directory - * @return \phpbb\extension\finder This object for chaining calls + * @return \phpbb\finder This object for chaining calls */ public function directory($directory) { @@ -198,7 +216,7 @@ class finder * Sets a directory all files found in extensions must be contained in * * @param string $extension_directory - * @return \phpbb\extension\finder This object for chaining calls + * @return \phpbb\finder This object for chaining calls */ public function extension_directory($extension_directory) { @@ -210,7 +228,7 @@ class finder * Sets a directory all files found in the core path must be contained in * * @param string $core_directory - * @return \phpbb\extension\finder This object for chaining calls + * @return \phpbb\finder This object for chaining calls */ public function core_directory($core_directory) { @@ -246,16 +264,14 @@ class finder * phpBB naming rules an incorrect class name will be returned. * * @param bool $cache Whether the result should be cached - * @param bool $use_all_available Use all available instead of just all - * enabled extensions * @return array An array of found class names */ - public function get_classes($cache = true, $use_all_available = false) + public function get_classes($cache = true) { $this->query['extension_suffix'] .= '.' . $this->php_ext; $this->query['core_suffix'] .= '.' . $this->php_ext; - $files = $this->find($cache, false, $use_all_available); + $files = $this->find($cache, false); return $this->get_classes_from_files($files); } @@ -290,27 +306,23 @@ class finder * Finds all directories matching the configured options * * @param bool $cache Whether the result should be cached - * @param bool $use_all_available Use all available instead of just all - * enabled extensions * @param bool $extension_keys Whether the result should have extension name as array key * @return array An array of paths to found directories */ - public function get_directories($cache = true, $use_all_available = false, $extension_keys = false) + public function get_directories($cache = true, $extension_keys = false) { - return $this->find_with_root_path($cache, true, $use_all_available, $extension_keys); + return $this->find_with_root_path($cache, true, $extension_keys); } /** * Finds all files matching the configured options. * * @param bool $cache Whether the result should be cached - * @param bool $use_all_available Use all available instead of just all - * enabled extensions * @return array An array of paths to found files */ - public function get_files($cache = true, $use_all_available = false) + public function get_files($cache = true) { - return $this->find_with_root_path($cache, false, $use_all_available); + return $this->find_with_root_path($cache, false); } /** @@ -318,16 +330,14 @@ class finder * * @param bool $cache Whether the result should be cached * @param bool $is_dir Directories will be returned when true, only files - * otherwise - * @param bool $use_all_available Use all available instead of just all - * enabled extensions + * otherwise * @param bool $extension_keys If true, result will be associative array * with extension name as key * @return array An array of paths to found items */ - protected function find_with_root_path($cache = true, $is_dir = false, $use_all_available = false, $extension_keys = false) + protected function find_with_root_path($cache = true, $is_dir = false, $extension_keys = false) { - $items = $this->find($cache, $is_dir, $use_all_available); + $items = $this->find($cache, $is_dir); $result = array(); foreach ($items as $item => $ext_name) @@ -351,21 +361,11 @@ class finder * @param bool $cache Whether the result should be cached * @param bool $is_dir Directories will be returned when true, only files * otherwise - * @param bool $use_all_available Use all available instead of just all - * enabled extensions * @return array An array of paths to found items */ - public function find($cache = true, $is_dir = false, $use_all_available = false) + public function find($cache = true, $is_dir = false) { - if ($use_all_available) - { - $extensions = $this->extension_manager->all_available(); - } - else - { - $extensions = $this->extension_manager->all_enabled(); - } - + $extensions = $this->extensions; if ($this->query['core_path']) { $extensions['/'] = $this->phpbb_root_path . $this->query['core_path']; diff --git a/phpBB/phpbb/passwords/driver/base.php b/phpBB/phpbb/passwords/driver/base.php index fffc9d1461..1d47180e55 100644 --- a/phpBB/phpbb/passwords/driver/base.php +++ b/phpBB/phpbb/passwords/driver/base.php @@ -43,4 +43,20 @@ abstract class base implements driver_interface { return true; } + + /** + * @inheritdoc + */ + public function is_legacy() + { + return false; + } + + /** + * @inheritdoc + */ + public function get_settings_only($hash, $full = false) + { + return false; + } } diff --git a/phpBB/phpbb/passwords/driver/bcrypt.php b/phpBB/phpbb/passwords/driver/bcrypt.php index 3edf7255c0..de5840c7cf 100644 --- a/phpBB/phpbb/passwords/driver/bcrypt.php +++ b/phpBB/phpbb/passwords/driver/bcrypt.php @@ -60,7 +60,7 @@ class bcrypt extends base /** * @inheritdoc */ - public function check($password, $hash) + public function check($password, $hash, $user_row = array()) { $salt = substr($hash, 0, 29); if (strlen($salt) != 29) diff --git a/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php b/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php new file mode 100644 index 0000000000..f706c7af69 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php @@ -0,0 +1,84 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +class bcrypt_wcf2 extends base +{ + const PREFIX = '$wcf2$'; + + /** @var \phpbb\passwords\driver\bcrypt */ + protected $bcrypt; + + /** @var phpbb\passwords\driver\helper */ + protected $helper; + + /** + * Constructor of passwords driver object + * + * @param \phpbb\passwords\driver\bcrypt $bcrypt Salted md5 driver + * @param \phpbb\passwords\driver\helper $helper Password driver helper + */ + public function __construct(\phpbb\passwords\driver\bcrypt $bcrypt, helper $helper) + { + $this->bcrypt = $bcrypt; + $this->helper = $helper; + } + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function is_legacy() + { + return true; + } + + /** + * @inheritdoc + */ + public function hash($password, $user_row = '') + { + // Do not support hashing + return false; + } + + /** + * @inheritdoc + */ + public function check($password, $hash, $user_row = array()) + { + if (empty($hash) || strlen($hash) != 60) + { + return false; + } + else + { + $salt = substr($hash, 0, 29); + + if (strlen($salt) != 29) + { + return false; + } + // Works for standard WCF 2.x, i.e. WBB4 and similar + return $hash === $this->bcrypt->hash($this->bcrypt->hash($password, $salt), $salt); + } + } +} diff --git a/phpBB/phpbb/passwords/driver/convert_password.php b/phpBB/phpbb/passwords/driver/convert_password.php new file mode 100644 index 0000000000..45d84f45c0 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/convert_password.php @@ -0,0 +1,43 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +class convert_password extends base +{ + const PREFIX = '$CP$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function hash($password, $user_row = '') + { + return false; + } + + /** + * @inheritdoc + */ + public function check($password, $hash, $user_row = array()) + { + return false; + } +} diff --git a/phpBB/phpbb/passwords/driver/driver_interface.php b/phpBB/phpbb/passwords/driver/driver_interface.php index 54c9d6500e..a257e71f23 100644 --- a/phpBB/phpbb/passwords/driver/driver_interface.php +++ b/phpBB/phpbb/passwords/driver/driver_interface.php @@ -23,6 +23,13 @@ interface driver_interface public function is_supported(); /** + * Check if hash type is a legacy hash type + * + * @return bool True if it's a legacy hash type, false if not + */ + public function is_legacy(); + + /** * Returns the hash prefix * * @return string Hash prefix @@ -44,10 +51,11 @@ interface driver_interface * * @param string $password The password to check * @param string $hash The password hash to check against + * @param string $user_row User's row in users table * * @return bool True if password is correct, else false */ - public function check($password, $hash); + public function check($password, $hash, $user_row = array()); /** * Get only the settings of the specified hash diff --git a/phpBB/phpbb/passwords/driver/md5_mybb.php b/phpBB/phpbb/passwords/driver/md5_mybb.php new file mode 100644 index 0000000000..0745bceb5e --- /dev/null +++ b/phpBB/phpbb/passwords/driver/md5_mybb.php @@ -0,0 +1,60 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +class md5_mybb extends base +{ + const PREFIX = '$md5_mybb$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function is_legacy() + { + return true; + } + + /** + * @inheritdoc + */ + public function hash($password, $user_row = '') + { + // Do not support hashing + return false; + } + + /** + * @inheritdoc + */ + public function check($password, $hash, $user_row = array()) + { + if (empty($hash) || strlen($hash) != 32 || !isset($user_row['user_passwd_salt'])) + { + return false; + } + else + { + // Works for myBB 1.1.x, 1.2.x, 1.4.x, 1.6.x + return $hash === md5(md5($user_row['user_passwd_salt']) . md5($password)); + } + } +} diff --git a/phpBB/phpbb/passwords/driver/md5_phpbb2.php b/phpBB/phpbb/passwords/driver/md5_phpbb2.php new file mode 100644 index 0000000000..de1993e8a1 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/md5_phpbb2.php @@ -0,0 +1,118 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +class md5_phpbb2 extends base +{ + const PREFIX = '$md5_phpbb2$'; + + /** @var \phpbb\request\request phpBB request object */ + protected $request; + + /** @var \phpbb\passwords\driver\salted_md5 */ + protected $salted_md5; + + /** @var phpBB root path */ + protected $phpbb_root_path; + + /** @var php file extension */ + protected $php_ext; + + /** + * Constructor of passwords driver object + * + * @param \phpbb\request\request $request phpBB request object + * @param \phpbb\passwords\driver\salted_md5 $salted_md5 Salted md5 driver + * @param string $phpbb_root_path phpBB root path + * @param string $php_ext PHP file extension + */ + public function __construct($request, \phpbb\passwords\driver\salted_md5 $salted_md5, $phpbb_root_path, $php_ext) + { + $this->request = $request; + $this->salted_md5 = $salted_md5; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + } + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function is_legacy() + { + return true; + } + + /** + * @inheritdoc + */ + public function hash($password, $user_row = '') + { + // Do not support hashing + return false; + } + + /** + * @inheritdoc + */ + public function check($password, $hash, $user_row = array()) + { + if (strlen($hash) != 32 && strlen($hash) != 34) + { + return false; + } + + // enable super globals to get literal value + // this is needed to prevent unicode normalization + $super_globals_disabled = $this->request->super_globals_disabled(); + if ($super_globals_disabled) + { + $this->request->enable_super_globals(); + } + + // in phpBB2 passwords were used exactly as they were sent, with addslashes applied + $password_old_format = isset($_REQUEST['password']) ? (string) $_REQUEST['password'] : ''; + $password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format; + $password_new_format = $this->request->variable('password', '', true); + + if ($super_globals_disabled) + { + $this->request->disable_super_globals(); + } + + if ($password == $password_new_format) + { + if (!function_exists('utf8_to_cp1252')) + { + include($this->phpbb_root_path . 'includes/utf/data/recode_basic.' . $this->php_ext); + } + + if (md5($password_old_format) === $hash || md5(\utf8_to_cp1252($password_old_format)) === $hash + || $this->salted_md5->check(md5($password_old_format), $hash) === true + || $this->salted_md5->check(md5(\utf8_to_cp1252($password_old_format)), $hash) === true) + { + return true; + } + } + + return false; + } +} diff --git a/phpBB/phpbb/passwords/driver/md5_vb.php b/phpBB/phpbb/passwords/driver/md5_vb.php new file mode 100644 index 0000000000..440b9e39e9 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/md5_vb.php @@ -0,0 +1,60 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +class md5_vb extends base +{ + const PREFIX = '$md5_vb$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function is_legacy() + { + return true; + } + + /** + * @inheritdoc + */ + public function hash($password, $user_row = '') + { + // Do not support hashing + return false; + } + + /** + * @inheritdoc + */ + public function check($password, $hash, $user_row = array()) + { + if (empty($hash) || strlen($hash) != 32 || !isset($user_row['user_passwd_salt'])) + { + return false; + } + else + { + // Works for vB 3.8.x, 4.x.x, 5.0.x + return $hash === md5(md5($password) . $user_row['user_passwd_salt']); + } + } +} diff --git a/phpBB/phpbb/passwords/driver/salted_md5.php b/phpBB/phpbb/passwords/driver/salted_md5.php index a9f6712751..b5f59754e1 100644 --- a/phpBB/phpbb/passwords/driver/salted_md5.php +++ b/phpBB/phpbb/passwords/driver/salted_md5.php @@ -56,6 +56,14 @@ class salted_md5 extends base /** * @inheritdoc */ + public function is_legacy() + { + return true; + } + + /** + * @inheritdoc + */ public function hash($password, $setting = '') { if ($setting) @@ -92,7 +100,7 @@ class salted_md5 extends base /** * @inheritdoc */ - public function check($password, $hash) + public function check($password, $hash, $user_row = array()) { if (strlen($hash) !== 34) { diff --git a/phpBB/phpbb/passwords/driver/sha1.php b/phpBB/phpbb/passwords/driver/sha1.php new file mode 100644 index 0000000000..5d6c93f6a8 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/sha1.php @@ -0,0 +1,52 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +class sha1 extends base +{ + const PREFIX = '$sha1$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function is_legacy() + { + return true; + } + + /** + * @inheritdoc + */ + public function hash($password, $user_row = '') + { + // Do not support hashing + return false; + } + + /** + * @inheritdoc + */ + public function check($password, $hash, $user_row = array()) + { + return (strlen($hash) == 40) ? $hash === sha1($password) : false; + } +} diff --git a/phpBB/phpbb/passwords/driver/sha1_smf.php b/phpBB/phpbb/passwords/driver/sha1_smf.php new file mode 100644 index 0000000000..3e3322d77f --- /dev/null +++ b/phpBB/phpbb/passwords/driver/sha1_smf.php @@ -0,0 +1,51 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +class sha1_smf extends base +{ + const PREFIX = '$smf$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function is_legacy() + { + return true; + } + + /** + * @inheritdoc + */ + public function hash($password, $user_row = '') + { + return (isset($user_row['login_name'])) ? sha1(strtolower($user_row['login_name']) . $password) : false; + } + + /** + * @inheritdoc + */ + public function check($password, $hash, $user_row = array()) + { + return (strlen($hash) == 40) ? $hash === $this->hash($password, $user_row) : false; + } +} diff --git a/phpBB/phpbb/passwords/driver/sha1_wcf1.php b/phpBB/phpbb/passwords/driver/sha1_wcf1.php new file mode 100644 index 0000000000..04a69705e9 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/sha1_wcf1.php @@ -0,0 +1,60 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +class sha1_wcf1 extends base +{ + const PREFIX = '$wcf1$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function is_legacy() + { + return true; + } + + /** + * @inheritdoc + */ + public function hash($password, $user_row = '') + { + // Do not support hashing + return false; + } + + /** + * @inheritdoc + */ + public function check($password, $hash, $user_row = array()) + { + if (empty($hash) || strlen($hash) != 40 || !isset($user_row['user_passwd_salt'])) + { + return false; + } + else + { + // Works for standard WCF 1.x, i.e. WBB3 and similar + return $hash === sha1($user_row['user_passwd_salt'] . sha1($user_row['user_passwd_salt'] . sha1($password))); + } + } +} diff --git a/phpBB/phpbb/passwords/driver/sha_xf1.php b/phpBB/phpbb/passwords/driver/sha_xf1.php new file mode 100644 index 0000000000..7ae0b90f51 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/sha_xf1.php @@ -0,0 +1,68 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +class sha_xf1 extends base +{ + const PREFIX = '$xf1$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function is_legacy() + { + return true; + } + + /** + * @inheritdoc + */ + public function hash($password, $user_row = '') + { + // Do not support hashing + return false; + } + + /** + * @inheritdoc + */ + public function check($password, $hash, $user_row = array()) + { + if (empty($hash) || (strlen($hash) != 40 && strlen($hash) != 64) || !isset($user_row['user_passwd_salt'])) + { + return false; + } + else + { + // Works for xenforo 1.0, 1.1 + if ($hash === sha1(sha1($password) . $user_row['user_passwd_salt']) + || $hash === hash('sha256', hash('sha256', $password) . $user_row['user_passwd_salt'])) + { + return true; + } + else + { + return false; + } + } + } +} diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php index 8b16cf55dd..0a349c4a14 100644 --- a/phpBB/phpbb/passwords/manager.php +++ b/phpBB/phpbb/passwords/manager.php @@ -141,7 +141,7 @@ class manager */ if (!preg_match('#^\$([a-zA-Z0-9\\\]*?)\$#', $hash, $match)) { - return $this->get_algorithm('$H$'); + return false; } // Be on the lookout for multiple hashing algorithms @@ -224,9 +224,10 @@ class manager * * @param string $password Password that should be checked * @param string $hash Stored hash + * @param array $user_row User's row in users table * @return string|bool True if password is correct, false if not */ - public function check($password, $hash) + public function check($password, $hash, $user_row = array()) { if (strlen($password) > 4096) { @@ -235,11 +236,19 @@ class manager return false; } + // Empty hashes can't be checked + if (empty($hash)) + { + return false; + } + // First find out what kind of hash we're dealing with $stored_hash_type = $this->detect_algorithm($hash); if ($stored_hash_type == false) { - return false; + // Still check MD5 hashes as that is what the installer + // will default to for the admin user + return $this->get_algorithm('$H$')->check($password, $hash); } // Multiple hash passes needed @@ -259,6 +268,21 @@ class manager $this->convert_flag = false; } + // Check all legacy hash types if prefix is $CP$ + if ($stored_hash_type->get_prefix() === '$CP$') + { + // Remove $CP$ prefix for proper checking + $hash = substr($hash, 4); + + foreach ($this->type_map as $algorithm) + { + if ($algorithm->is_legacy() && $algorithm->check($password, $hash, $user_row) === true) + { + return true; + } + } + } + return $stored_hash_type->check($password, $hash); } diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index c2669ea6cc..59b7ec2029 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -408,9 +408,8 @@ class session $session_expired = false; // Check whether the session is still valid if we have one - $method = basename(trim($config['auth_method'])); - - $provider = $phpbb_container->get('auth.provider.' . $method); + $provider_collection = $phpbb_container->get('auth.provider_collection'); + $provider = $provider_collection->get_provider(); if (!($provider instanceof \phpbb\auth\provider\provider_interface)) { @@ -577,9 +576,8 @@ class session } } - $method = basename(trim($config['auth_method'])); - - $provider = $phpbb_container->get('auth.provider.' . $method); + $provider_collection = $phpbb_container->get('auth.provider_collection'); + $provider = $provider_collection->get_provider(); $this->data = $provider->autologin(); if (sizeof($this->data)) @@ -898,9 +896,8 @@ class session $db->sql_query($sql); // Allow connecting logout with external auth method logout - $method = basename(trim($config['auth_method'])); - - $provider = $phpbb_container->get('auth.provider.' . $method); + $provider_collection = $phpbb_container->get('auth.provider_collection'); + $provider = $provider_collection->get_provider(); $provider->logout($this->data, $new_session); if ($this->data['user_id'] != ANONYMOUS) |