mirror of
https://github.com/phpbb/phpbb.git
synced 2025-05-28 10:09:15 +02:00
At the end of the login method, the captcha was entered correctly and only the password was incorrect. Therefore, just tell the user that the password was incorrect. He will see that he still needs to enter a captcha. PHPBB3-13204
240 lines
6.9 KiB
PHP
240 lines
6.9 KiB
PHP
<?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\provider;
|
|
|
|
/**
|
|
* Database authentication provider for phpBB3
|
|
* This is for authentication via the integrated user table
|
|
*/
|
|
class db extends \phpbb\auth\provider\base
|
|
{
|
|
/**
|
|
* phpBB passwords manager
|
|
*
|
|
* @var \phpbb\passwords\manager
|
|
*/
|
|
protected $passwords_manager;
|
|
|
|
/**
|
|
* DI container
|
|
*
|
|
* @var \Symfony\Component\DependencyInjection\ContainerInterface
|
|
*/
|
|
protected $phpbb_container;
|
|
|
|
/**
|
|
* Database Authentication Constructor
|
|
*
|
|
* @param \phpbb\db\driver\driver_interface $db
|
|
* @param \phpbb\config\config $config
|
|
* @param \phpbb\passwords\manager $passwords_manager
|
|
* @param \phpbb\request\request $request
|
|
* @param \phpbb\user $user
|
|
* @param \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container DI container
|
|
* @param string $phpbb_root_path
|
|
* @param string $php_ext
|
|
*/
|
|
public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, $phpbb_root_path, $php_ext)
|
|
{
|
|
$this->db = $db;
|
|
$this->config = $config;
|
|
$this->passwords_manager = $passwords_manager;
|
|
$this->request = $request;
|
|
$this->user = $user;
|
|
$this->phpbb_root_path = $phpbb_root_path;
|
|
$this->php_ext = $php_ext;
|
|
$this->phpbb_container = $phpbb_container;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function login($username, $password)
|
|
{
|
|
// Auth plugins get the password untrimmed.
|
|
// For compatibility we trim() here.
|
|
$password = trim($password);
|
|
|
|
// do not allow empty password
|
|
if (!$password)
|
|
{
|
|
return array(
|
|
'status' => LOGIN_ERROR_PASSWORD,
|
|
'error_msg' => 'NO_PASSWORD_SUPPLIED',
|
|
'user_row' => array('user_id' => ANONYMOUS),
|
|
);
|
|
}
|
|
|
|
if (!$username)
|
|
{
|
|
return array(
|
|
'status' => LOGIN_ERROR_USERNAME,
|
|
'error_msg' => 'LOGIN_ERROR_USERNAME',
|
|
'user_row' => array('user_id' => ANONYMOUS),
|
|
);
|
|
}
|
|
|
|
$username_clean = utf8_clean_string($username);
|
|
|
|
$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);
|
|
$row = $this->db->sql_fetchrow($result);
|
|
$this->db->sql_freeresult($result);
|
|
|
|
if (($this->user->ip && !$this->config['ip_login_limit_use_forwarded']) ||
|
|
($this->user->forwarded_for && $this->config['ip_login_limit_use_forwarded']))
|
|
{
|
|
$sql = 'SELECT COUNT(*) AS attempts
|
|
FROM ' . LOGIN_ATTEMPT_TABLE . '
|
|
WHERE attempt_time > ' . (time() - (int) $this->config['ip_login_limit_time']);
|
|
if ($this->config['ip_login_limit_use_forwarded'])
|
|
{
|
|
$sql .= " AND attempt_forwarded_for = '" . $this->db->sql_escape($this->user->forwarded_for) . "'";
|
|
}
|
|
else
|
|
{
|
|
$sql .= " AND attempt_ip = '" . $this->db->sql_escape($this->user->ip) . "' ";
|
|
}
|
|
|
|
$result = $this->db->sql_query($sql);
|
|
$attempts = (int) $this->db->sql_fetchfield('attempts');
|
|
$this->db->sql_freeresult($result);
|
|
|
|
$attempt_data = array(
|
|
'attempt_ip' => $this->user->ip,
|
|
'attempt_browser' => trim(substr($this->user->browser, 0, 149)),
|
|
'attempt_forwarded_for' => $this->user->forwarded_for,
|
|
'attempt_time' => time(),
|
|
'user_id' => ($row) ? (int) $row['user_id'] : 0,
|
|
'username' => $username,
|
|
'username_clean' => $username_clean,
|
|
);
|
|
$sql = 'INSERT INTO ' . LOGIN_ATTEMPT_TABLE . $this->db->sql_build_array('INSERT', $attempt_data);
|
|
$result = $this->db->sql_query($sql);
|
|
}
|
|
else
|
|
{
|
|
$attempts = 0;
|
|
}
|
|
|
|
if (!$row)
|
|
{
|
|
if ($this->config['ip_login_limit_max'] && $attempts >= $this->config['ip_login_limit_max'])
|
|
{
|
|
return array(
|
|
'status' => LOGIN_ERROR_ATTEMPTS,
|
|
'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
|
|
'user_row' => array('user_id' => ANONYMOUS),
|
|
);
|
|
}
|
|
|
|
return array(
|
|
'status' => LOGIN_ERROR_USERNAME,
|
|
'error_msg' => 'LOGIN_ERROR_USERNAME',
|
|
'user_row' => array('user_id' => ANONYMOUS),
|
|
);
|
|
}
|
|
|
|
$show_captcha = ($this->config['max_login_attempts'] && $row['user_login_attempts'] >= $this->config['max_login_attempts']) ||
|
|
($this->config['ip_login_limit_max'] && $attempts >= $this->config['ip_login_limit_max']);
|
|
|
|
// If there are too many login attempts, we need to check for a confirm image
|
|
// Every auth module is able to define what to do by itself...
|
|
if ($show_captcha)
|
|
{
|
|
$captcha_factory = $this->phpbb_container->get('captcha.factory');
|
|
$captcha = $captcha_factory->get_instance($this->config['captcha_plugin']);
|
|
$captcha->init(CONFIRM_LOGIN);
|
|
$vc_response = $captcha->validate($row);
|
|
if ($vc_response)
|
|
{
|
|
return array(
|
|
'status' => LOGIN_ERROR_ATTEMPTS,
|
|
'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
|
|
'user_row' => $row,
|
|
);
|
|
}
|
|
else
|
|
{
|
|
$captcha->reset();
|
|
}
|
|
|
|
}
|
|
|
|
// Check 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)
|
|
{
|
|
$hash = $this->passwords_manager->hash($password);
|
|
|
|
// Update the password in the users table to the new format
|
|
$sql = 'UPDATE ' . USERS_TABLE . "
|
|
SET user_password = '" . $this->db->sql_escape($hash) . "'
|
|
WHERE user_id = {$row['user_id']}";
|
|
$this->db->sql_query($sql);
|
|
|
|
$row['user_password'] = $hash;
|
|
}
|
|
|
|
$sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . '
|
|
WHERE user_id = ' . $row['user_id'];
|
|
$this->db->sql_query($sql);
|
|
|
|
if ($row['user_login_attempts'] != 0)
|
|
{
|
|
// Successful, reset login attempts (the user passed all stages)
|
|
$sql = 'UPDATE ' . USERS_TABLE . '
|
|
SET user_login_attempts = 0
|
|
WHERE user_id = ' . $row['user_id'];
|
|
$this->db->sql_query($sql);
|
|
}
|
|
|
|
// User inactive...
|
|
if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
|
|
{
|
|
return array(
|
|
'status' => LOGIN_ERROR_ACTIVE,
|
|
'error_msg' => 'ACTIVE_ERROR',
|
|
'user_row' => $row,
|
|
);
|
|
}
|
|
|
|
// Successful login... set user_login_attempts to zero...
|
|
return array(
|
|
'status' => LOGIN_SUCCESS,
|
|
'error_msg' => false,
|
|
'user_row' => $row,
|
|
);
|
|
}
|
|
|
|
// Password incorrect - increase login attempts
|
|
$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);
|
|
|
|
// Give status about wrong password...
|
|
return array(
|
|
'status' => ($show_captcha) ? LOGIN_ERROR_ATTEMPTS : LOGIN_ERROR_PASSWORD,
|
|
'error_msg' => 'LOGIN_ERROR_PASSWORD',
|
|
'user_row' => $row,
|
|
);
|
|
}
|
|
}
|