diff options
Diffstat (limited to 'phpBB/phpbb/captcha/plugins/captcha_abstract.php')
| -rw-r--r-- | phpBB/phpbb/captcha/plugins/captcha_abstract.php | 390 | 
1 files changed, 390 insertions, 0 deletions
diff --git a/phpBB/phpbb/captcha/plugins/captcha_abstract.php b/phpBB/phpbb/captcha/plugins/captcha_abstract.php new file mode 100644 index 0000000000..24ed7f939d --- /dev/null +++ b/phpBB/phpbb/captcha/plugins/captcha_abstract.php @@ -0,0 +1,390 @@ +<?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\captcha\plugins; + +/** +* This class holds the code shared by the two default 3.0.x CAPTCHAs. +*/ +abstract class captcha_abstract +{ +	var $confirm_id; +	var $confirm_code; +	var $code; +	var $seed; +	var $attempts = 0; +	var $type; +	var $solved = 0; +	var $captcha_vars = false; + +	/** +	* @var string name of the service. +	*/ +	protected $service_name; + +	function init($type) +	{ +		global $config, $db, $user; + +		// read input +		$this->confirm_id = request_var('confirm_id', ''); +		$this->confirm_code = request_var('confirm_code', ''); +		$refresh = request_var('refresh_vc', false) && $config['confirm_refresh']; + +		$this->type = (int) $type; + +		if (!strlen($this->confirm_id) || !$this->load_code()) +		{ +			// we have no confirm ID, better get ready to display something +			$this->generate_code(); +		} +		else if ($refresh) +		{ +			$this->regenerate_code(); +		} +	} + +	function execute_demo() +	{ +		global $user; + +		$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); +		$this->seed = hexdec(substr(unique_id(), 4, 10)); + +		// compute $seed % 0x7fffffff +		$this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff); + +		$generator = $this->get_generator_class(); +		$captcha = new $generator(); +		define('IMAGE_OUTPUT', 1); +		$captcha->execute($this->code, $this->seed); +	} + +	function execute() +	{ +		if (empty($this->code)) +		{ +			if (!$this->load_code()) +			{ +				// invalid request, bail out +				return false; +			} +		} +		$generator = $this->get_generator_class(); +		$captcha = new $generator(); +		define('IMAGE_OUTPUT', 1); +		$captcha->execute($this->code, $this->seed); +	} + +	function get_template() +	{ +		global $config, $user, $template, $phpEx, $phpbb_root_path; + +		if ($this->is_solved()) +		{ +			return false; +		} +		else +		{ +			$link = append_sid($phpbb_root_path . 'ucp.' . $phpEx,  'mode=confirm&confirm_id=' . $this->confirm_id . '&type=' . $this->type); +			$contact_link = phpbb_get_board_contact_link($config, $phpbb_root_path, $phpEx); +			$explain = $user->lang(($this->type != CONFIRM_POST) ? 'CONFIRM_EXPLAIN' : 'POST_CONFIRM_EXPLAIN', '<a href="' . $contact_link . '">', '</a>'); + +			$template->assign_vars(array( +				'CONFIRM_IMAGE_LINK'		=> $link, +				'CONFIRM_IMAGE'				=> '<img src="' . $link . '" />', +				'CONFIRM_IMG'				=> '<img src="' . $link . '" />', +				'CONFIRM_ID'				=> $this->confirm_id, +				'S_CONFIRM_CODE'			=> true, +				'S_TYPE'					=> $this->type, +				'S_CONFIRM_REFRESH'			=> ($config['enable_confirm'] && $config['confirm_refresh'] && $this->type == CONFIRM_REG) ? true : false, +				'L_CONFIRM_EXPLAIN'			=> $explain, +			)); + +			return 'captcha_default.html'; +		} +	} + +	function get_demo_template($id) +	{ +		global $config, $user, $template, $phpbb_admin_path, $phpEx; + +		$variables = ''; + +		if (is_array($this->captcha_vars)) +		{ +			foreach ($this->captcha_vars as $captcha_var => $template_var) +			{ +				$variables .= '&' . rawurlencode($captcha_var) . '=' . request_var($captcha_var, (int) $config[$captcha_var]); +			} +		} + +		// acp_captcha has a delivery function; let's use it +		$template->assign_vars(array( +			'CONFIRM_IMAGE'		=> append_sid($phpbb_admin_path . 'index.' . $phpEx, 'captcha_demo=1&mode=visual&i=' . $id . '&select_captcha=' . $this->get_service_name()) . $variables, +			'CONFIRM_ID'		=> $this->confirm_id, +		)); + +		return 'captcha_default_acp_demo.html'; +	} + +	function get_hidden_fields() +	{ +		$hidden_fields = array(); + +		// this is required for posting.php - otherwise we would forget about the captcha being already solved +		if ($this->solved) +		{ +			$hidden_fields['confirm_code'] = $this->confirm_code; +		} +		$hidden_fields['confirm_id'] = $this->confirm_id; +		return $hidden_fields; +	} + +	function garbage_collect($type) +	{ +		global $db, $config; + +		$sql = 'SELECT DISTINCT c.session_id +			FROM ' . CONFIRM_TABLE . ' c +			LEFT JOIN ' . SESSIONS_TABLE . ' s ON (c.session_id = s.session_id) +			WHERE s.session_id IS NULL' . +				((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type); +		$result = $db->sql_query($sql); + +		if ($row = $db->sql_fetchrow($result)) +		{ +			$sql_in = array(); +			do +			{ +				$sql_in[] = (string) $row['session_id']; +			} +			while ($row = $db->sql_fetchrow($result)); + +			if (sizeof($sql_in)) +			{ +				$sql = 'DELETE FROM ' . CONFIRM_TABLE . ' +					WHERE ' . $db->sql_in_set('session_id', $sql_in); +				$db->sql_query($sql); +			} +		} +		$db->sql_freeresult($result); +	} + +	function uninstall() +	{ +		$this->garbage_collect(0); +	} + +	function install() +	{ +		return; +	} + +	function validate() +	{ +		global $config, $db, $user; + +		if (empty($user->lang)) +		{ +			$user->setup(); +		} + +		$error = ''; +		if (!$this->confirm_id) +		{ +			$error = $user->lang['CONFIRM_CODE_WRONG']; +		} +		else +		{ +			if ($this->check_code()) +			{ +				$this->solved = true; +			} +			else +			{ +				$error = $user->lang['CONFIRM_CODE_WRONG']; +			} +		} + +		if (strlen($error)) +		{ +			// okay, incorrect answer. Let's ask a new question. +			$this->new_attempt(); +			return $error; +		} +		else +		{ +			return false; +		} +	} + +	/** +	* The old way to generate code, suitable for GD and non-GD. Resets the internal state. +	*/ +	function generate_code() +	{ +		global $db, $user; + +		$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); +		$this->confirm_id = md5(unique_id($user->ip)); +		$this->seed = hexdec(substr(unique_id(), 4, 10)); +		$this->solved = 0; +		// compute $seed % 0x7fffffff +		$this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff); + +		$sql = 'INSERT INTO ' . CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array( +				'confirm_id'	=> (string) $this->confirm_id, +				'session_id'	=> (string) $user->session_id, +				'confirm_type'	=> (int) $this->type, +				'code'			=> (string) $this->code, +				'seed'			=> (int) $this->seed) +		); +		$db->sql_query($sql); +	} + +	/** +	* New Question, if desired. +	*/ +	function regenerate_code() +	{ +		global $db, $user; + +		$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); +		$this->seed = hexdec(substr(unique_id(), 4, 10)); +		$this->solved = 0; +		// compute $seed % 0x7fffffff +		$this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff); + +		$sql = 'UPDATE ' . CONFIRM_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array( +				'code'			=> (string) $this->code, +				'seed'			=> (int) $this->seed)) . ' +				WHERE +				confirm_id = \'' . $db->sql_escape($this->confirm_id) . '\' +					AND session_id = \'' . $db->sql_escape($user->session_id) . '\''; +		$db->sql_query($sql); +	} + +	/** +	* New Question, if desired. +	*/ +	function new_attempt() +	{ +		global $db, $user; + +		$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); +		$this->seed = hexdec(substr(unique_id(), 4, 10)); +		$this->solved = 0; +		// compute $seed % 0x7fffffff +		$this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff); + +		$sql = 'UPDATE ' . CONFIRM_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array( +				'code'			=> (string) $this->code, +				'seed'			=> (int) $this->seed)) . ' +				, attempts = attempts + 1 +				WHERE +				confirm_id = \'' . $db->sql_escape($this->confirm_id) . '\' +					AND session_id = \'' . $db->sql_escape($user->session_id) . '\''; +		$db->sql_query($sql); +	} + +	/** +	* Look up everything we need for painting&checking. +	*/ +	function load_code() +	{ +		global $db, $user; + +		$sql = 'SELECT code, seed, attempts +			FROM ' . CONFIRM_TABLE . " +			WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "' +				AND session_id = '" . $db->sql_escape($user->session_id) . "' +				AND confirm_type = " . $this->type; +		$result = $db->sql_query($sql); +		$row = $db->sql_fetchrow($result); +		$db->sql_freeresult($result); + +		if ($row) +		{ +			$this->code = $row['code']; +			$this->seed = $row['seed']; +			$this->attempts = $row['attempts']; +			return true; +		} + +		return false; +	} + +	function check_code() +	{ +		return (strcasecmp($this->code, $this->confirm_code) === 0); +	} + +	function get_attempt_count() +	{ +		return $this->attempts; +	} + +	function reset() +	{ +		global $db, $user; + +		$sql = 'DELETE FROM ' . CONFIRM_TABLE . " +			WHERE session_id = '" . $db->sql_escape($user->session_id) . "' +				AND confirm_type = " . (int) $this->type; +		$db->sql_query($sql); + +		// we leave the class usable by generating a new question +		$this->generate_code(); +	} + +	function is_solved() +	{ +		if (request_var('confirm_code', false) && $this->solved === 0) +		{ +			$this->validate(); +		} +		return (bool) $this->solved; +	} + +	/** +	*  API function +	*/ +	function has_config() +	{ +		return false; +	} + +	/** +	* @return string the name of the service corresponding to the plugin +	*/ +	function get_service_name() +	{ +		return $this->service_name; +	} + +	/** +	* Set the name of the plugin +	* +	* @param string $name +	*/ +	public function set_name($name) +	{ +		$this->service_name = $name; +	} + +	/** +	* @return string the name of the class used to generate the captcha +	*/ +	abstract function get_generator_class(); +}  | 
