aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/auth/provider/db.php
diff options
context:
space:
mode:
authorJoas Schilling <nickvergessen@gmx.de>2013-07-11 11:41:48 +0200
committerJoas Schilling <nickvergessen@gmx.de>2013-07-11 11:41:48 +0200
commitbdb7ec0ceb3210955b2457bfe6fe469b1781d8d6 (patch)
tree4a6cd814385ae839f577866d3c45175f9ea4928e /phpBB/includes/auth/provider/db.php
parentd41cf293e1609be9d0cc08e5ccd37947481e61ca (diff)
parent2fcae1ca16d096d2839b487e8c1bcbe0f313d91f (diff)
downloadforums-bdb7ec0ceb3210955b2457bfe6fe469b1781d8d6.tar
forums-bdb7ec0ceb3210955b2457bfe6fe469b1781d8d6.tar.gz
forums-bdb7ec0ceb3210955b2457bfe6fe469b1781d8d6.tar.bz2
forums-bdb7ec0ceb3210955b2457bfe6fe469b1781d8d6.tar.xz
forums-bdb7ec0ceb3210955b2457bfe6fe469b1781d8d6.zip
Merge remote-tracking branch 'phpbb/develop' into feature/softdelete-1-permission
* phpbb/develop: (704 commits) [ticket/11630] Improvements to the PHP lint pre-commit hook [feature/auth-refactor] Move auth providers to separate directory [ticket/11619] Use HTTP/1.0 because of lack of chunked-encoding handling. [ticket/11619] Some tests for get_remote_file(). [ticket/11617] Remove spaces and tabs from empty lines [ticket/11617] Missing U_ACTION in acp_captcha.php [feature/auth-refactor] Fix code style issue [feature/auth-refactor] Fix comment grammar [feature/auth-refactor] Fix the actual cause of test failures [ticket/10838] Fix URL for wiki and remove irrelevant line [ticket/10838] Remove php 5.4 and builtin server references [ticket/10838] Fix missing data [ticket/10838] separate database used mentioned in unit tests [ticket/11585] Make $auth_admin class property [feature/auth-refactor] A possible fix for the functional test failures [ticket/11566] Subsilver template error displayed after table headers [ticket/11566] Remove extra pair of brackets from conditional statement [ticket/11566] Check that guest doesn't have reporting permission by default [ticket/11566] Add captcha to report post template in subsilver [ticket/11566] Use the new constant CONFIRM_REPORT for captcha init ... Conflicts: phpBB/docs/sphinx.sample.conf phpBB/feed.php phpBB/styles/prosilver/template/search_results.html phpBB/styles/prosilver/template/viewforum_body.html
Diffstat (limited to 'phpBB/includes/auth/provider/db.php')
-rw-r--r--phpBB/includes/auth/provider/db.php337
1 files changed, 337 insertions, 0 deletions
diff --git a/phpBB/includes/auth/provider/db.php b/phpBB/includes/auth/provider/db.php
new file mode 100644
index 0000000000..894041c9cf
--- /dev/null
+++ b/phpBB/includes/auth/provider/db.php
@@ -0,0 +1,337 @@
+<?php
+/**
+*
+* @package auth
+* @copyright (c) 2013 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+ * Database authentication provider for phpBB3
+ *
+ * This is for authentication via the integrated user table
+ *
+ * @package auth
+ */
+class phpbb_auth_provider_db implements phpbb_auth_provider_interface
+{
+
+ /**
+ * Database Authentication Constructor
+ *
+ * @param phpbb_db_driver $db
+ * @param phpbb_config $config
+ * @param phpbb_request $request
+ * @param phpbb_user $user
+ * @param string $phpbb_root_path
+ * @param string $php_ext
+ */
+ public function __construct(phpbb_db_driver $db, phpbb_config $config, phpbb_request $request, phpbb_user $user, $phpbb_root_path, $php_ext)
+ {
+ $this->db = $db;
+ $this->config = $config;
+ $this->request = $request;
+ $this->user = $user;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function init()
+ {
+ return;
+ }
+
+ /**
+ * {@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_pass_convert, 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)
+ {
+ // Visual Confirmation handling
+ if (!class_exists('phpbb_captcha_factory', false))
+ {
+ include ($this->phpbb_root_path . 'includes/captcha/captcha_factory.' . $this->php_ext);
+ }
+
+ $captcha = phpbb_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();
+ }
+
+ }
+
+ // 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 && (phpbb_check_hash(md5($password_old_format), $row['user_password']) || phpbb_check_hash(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 = phpbb_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'] && phpbb_check_hash($password, $row['user_password']))
+ {
+ // Check for old password hash...
+ if (strlen($row['user_password']) == 32)
+ {
+ $hash = phpbb_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) . "',
+ user_pass_convert = 0
+ 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' => ($show_captcha) ? 'LOGIN_ERROR_ATTEMPTS' : 'LOGIN_ERROR_PASSWORD',
+ 'user_row' => $row,
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function autologin()
+ {
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function acp($new)
+ {
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function logout($data, $new_session)
+ {
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate_session($user)
+ {
+ return;
+ }
+}