aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
authorHenry Sudhof <kellanved@phpbb.com>2008-09-19 13:17:30 +0000
committerHenry Sudhof <kellanved@phpbb.com>2008-09-19 13:17:30 +0000
commit461be11e8d0f5d4bd879cf95bd1472dbe985e0b6 (patch)
treed170e1a09d717a49bf676ef1f2ed9edbfa1be0db /phpBB/includes
parent5349280538df70d63c5e6f91e7f4e6ecad01d23d (diff)
downloadforums-461be11e8d0f5d4bd879cf95bd1472dbe985e0b6.tar
forums-461be11e8d0f5d4bd879cf95bd1472dbe985e0b6.tar.gz
forums-461be11e8d0f5d4bd879cf95bd1472dbe985e0b6.tar.bz2
forums-461be11e8d0f5d4bd879cf95bd1472dbe985e0b6.tar.xz
forums-461be11e8d0f5d4bd879cf95bd1472dbe985e0b6.zip
Okay, that is pretty raw, but better to have it in place than trying to play catch-up. Introducing an early stage of CAPTCHA modules.
git-svn-id: file:///svn/phpbb/trunk@8889 89ea8834-ac86-4346-8a33-228a782c2dd0
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/acp/acp_captcha.php165
-rw-r--r--phpBB/includes/auth/auth_db.php39
-rwxr-xr-xphpBB/includes/captcha/captcha_factory.php90
-rw-r--r--phpBB/includes/captcha/captcha_non_gd.php6
-rwxr-xr-xphpBB/includes/captcha/captcha_plugin.php97
-rwxr-xr-xphpBB/includes/captcha/plugins/captcha_abstract.php301
-rwxr-xr-xphpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php101
-rwxr-xr-xphpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php58
-rw-r--r--phpBB/includes/functions.php30
-rw-r--r--phpBB/includes/session.php38
-rw-r--r--phpBB/includes/ucp/ucp_confirm.php43
-rw-r--r--phpBB/includes/ucp/ucp_register.php139
12 files changed, 804 insertions, 303 deletions
diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php
index e61b8c2170..57de03c4c9 100644
--- a/phpBB/includes/acp/acp_captcha.php
+++ b/phpBB/includes/acp/acp_captcha.php
@@ -10,6 +10,8 @@
/**
* @ignore
*/
+
+
if (!defined('IN_PHPBB'))
{
exit;
@@ -28,94 +30,115 @@ class acp_captcha
$user->add_lang('acp/board');
+ include(PHPBB_ROOT_PATH . 'includes/captcha/captcha_factory.' . PHP_EXT);
- $captcha_vars = array(
- 'captcha_gd_x_grid' => 'CAPTCHA_GD_X_GRID',
- 'captcha_gd_y_grid' => 'CAPTCHA_GD_Y_GRID',
- 'captcha_gd_foreground_noise' => 'CAPTCHA_GD_FOREGROUND_NOISE',
- 'captcha_gd' => 'CAPTCHA_GD_PREVIEWED'
- );
-
- if (isset($_GET['demo']))
+ $selected = request_var('select_captcha', $config['captcha_plugin']);
+ $configure = request_var('configure', false);
+
+ // Oh, they are just here for the view
+ if (isset($_GET['captcha_demo']))
{
- $captcha_vars = array_keys($captcha_vars);
- foreach ($captcha_vars as $captcha_var)
- {
- $config[$captcha_var] = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, 0) : $config[$captcha_var];
- }
-
- if ($config['captcha_gd'])
- {
- include(PHPBB_ROOT_PATH . 'includes/captcha/captcha_gd.' . PHP_EXT);
- }
- else
- {
- include(PHPBB_ROOT_PATH . 'includes/captcha/captcha_non_gd.' . PHP_EXT);
- }
- captcha::execute(gen_rand_string(mt_rand(5, 8)), time());
- exit;
+ $this->deliver_demo($selected);
+ }
+
+ // Delegate
+ if ($configure)
+ {
+ $config_captcha = phpbb_captcha_factory::get_instance($selected);
+ $config_captcha->acp_page($id, $this);
}
+ else
+ {
+ $captchas = phpbb_captcha_factory::get_captcha_types();
- $config_vars = array(
- 'enable_confirm' => 'REG_ENABLE',
- 'enable_post_confirm' => 'POST_ENABLE',
- 'captcha_gd' => 'CAPTCHA_GD',
- );
+ $config_vars = array(
+ 'enable_confirm' => 'REG_ENABLE',
+ 'enable_post_confirm' => 'POST_ENABLE',
+ );
- $this->tpl_name = 'acp_captcha';
- $this->page_title = 'ACP_VC_SETTINGS';
- $form_key = 'acp_captcha';
- add_form_key($form_key);
+ $this->tpl_name = 'acp_captcha';
+ $this->page_title = 'ACP_VC_SETTINGS';
+ $form_key = 'acp_captcha';
+ add_form_key($form_key);
- $submit = request_var('submit', '');
+ $submit = request_var('main_submit', false);
- if ($submit && check_form_key($form_key))
- {
- $config_vars = array_keys($config_vars);
- foreach ($config_vars as $config_var)
- {
- set_config($config_var, request_var($config_var, ''));
- }
- $captcha_vars = array_keys($captcha_vars);
- foreach ($captcha_vars as $captcha_var)
+ if ($submit && check_form_key($form_key))
{
- $value = request_var($captcha_var, 0);
- if ($value >= 0)
+ $config_vars = array_keys($config_vars);
+ foreach ($config_vars as $config_var)
{
- set_config($captcha_var, $value);
+ set_config($config_var, request_var($config_var, false));
}
+ if ($selected !== $config['captcha_plugin'])
+ {
+ // sanity check
+ if (isset($captchas['available'][$selected]))
+ {
+ $old_captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $old_captcha->uninstall();
+ set_config('captcha_plugin', $selected);
+ $new_captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $old_captcha->install();
+ }
+ else
+ {
+ trigger_error($user->lang['CAPTCHA_UNAVAILABLE'] . adm_back_link($this->u_action));
+ }
+ }
+ trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
}
- trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
- }
- else if ($submit)
- {
- trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action));
- }
- else
- {
-
- $preview_image_src = append_sid(append_sid(PHPBB_ADMIN_PATH . 'index.' . PHP_EXT, "i=$id&amp;demo=demo"));
- if (@extension_loaded('gd'))
- {
- $template->assign_var('GD', true);
- }
- foreach ($config_vars as $config_var => $template_var)
+ else if ($submit)
{
- $template->assign_var($template_var, (isset($_REQUEST[$config_var])) ? request_var($config_var, '') : $config[$config_var]) ;
+ trigger_error($user->lang['FORM_INVALID'] . adm_back_link());
}
- foreach ($captcha_vars as $captcha_var => $template_var)
+ else
{
- $var = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, 0) : $config[$captcha_var];
- $template->assign_var($template_var, $var);
- $preview_image_src .= "&amp;$captcha_var=" . $var;
- }
- $template->assign_vars(array(
- 'CAPTCHA_PREVIEW' => $preview_image_src,
- 'PREVIEW' => isset($_POST['preview']),
- ));
+ $captcha_select = '';
+ foreach ($captchas['available'] as $value => $title)
+ {
+ $current = ($selected !== false && $value == $selected) ? ' selected="selected"' : '';
+ $captcha_select .= '<option value="' . $value . '"' . $current . '>' . $user->lang[$title] . '</option>';
+ }
+ foreach ($captchas['unavailable'] as $value => $title)
+ {
+ $captcha_select .= '<option value="' . $value . '"' . $current . ' class="disabled-option" >' . $user->lang[$title] . '</option>';
+ }
+
+ $demo_captcha = phpbb_captcha_factory::get_instance($selected);
+
+ foreach ($config_vars as $config_var => $template_var)
+ {
+ $template->assign_var($template_var, (isset($_REQUEST[$config_var])) ? request_var($config_var, '') : $config[$config_var]) ;
+ }
+ $template->assign_vars(array(
+ 'CAPTCHA_PREVIEW' => $demo_captcha->get_demo_template($id),
+ 'CAPTCHA_SELECT' => $captcha_select,
+ ));
+ }
+
}
}
+
+
+ /**
+ * Entry point for delivering image CAPTCHAs in the ACP.
+ */
+ function deliver_demo($selected)
+ {
+ global $db, $user, $config;
+
+ $captcha = phpbb_captcha_factory::get_instance($selected);
+ $captcha->init(CONFIRM_REG);
+ $captcha->execute_demo();
+ garbage_collection();
+ exit_handler();
+ }
+
+
+
+
}
?> \ No newline at end of file
diff --git a/phpBB/includes/auth/auth_db.php b/phpBB/includes/auth/auth_db.php
index fa99a2fe4c..402f22f827 100644
--- a/phpBB/includes/auth/auth_db.php
+++ b/phpBB/includes/auth/auth_db.php
@@ -81,42 +81,15 @@ function login_db(&$username, &$password)
}
else
{
- global $user;
-
- $sql = 'SELECT code
- FROM ' . CONFIRM_TABLE . "
- WHERE confirm_id = '" . $db->sql_escape($confirm_id) . "'
- AND session_id = '" . $db->sql_escape($user->session_id) . "'
- AND confirm_type = " . CONFIRM_LOGIN;
- $result = $db->sql_query($sql);
- $confirm_row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if ($confirm_row)
+ $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $captcha->init(CONFIRM_LOGIN);
+ $vc_response = $captcha->validate();
+ if ($vc_response)
{
- if (strcasecmp($confirm_row['code'], $confirm_code) === 0)
- {
- $sql = 'DELETE FROM ' . CONFIRM_TABLE . "
- WHERE confirm_id = '" . $db->sql_escape($confirm_id) . "'
- AND session_id = '" . $db->sql_escape($user->session_id) . "'
- AND confirm_type = " . CONFIRM_LOGIN;
- $db->sql_query($sql);
- }
- else
- {
- return array(
+ return array(
'status' => LOGIN_ERROR_ATTEMPTS,
- 'error_msg' => 'CONFIRM_CODE_WRONG',
+ 'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
'user_row' => $row,
- );
- }
- }
- else
- {
- return array(
- 'status' => LOGIN_ERROR_ATTEMPTS,
- 'error_msg' => 'CONFIRM_CODE_WRONG',
- 'user_row' => $row,
);
}
}
diff --git a/phpBB/includes/captcha/captcha_factory.php b/phpBB/includes/captcha/captcha_factory.php
new file mode 100755
index 0000000000..dfbe605917
--- /dev/null
+++ b/phpBB/includes/captcha/captcha_factory.php
@@ -0,0 +1,90 @@
+<?
+/**
+*
+* @package VC
+* @version $Id: $
+* @copyright (c) 2008 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+if (!interface_exists('phpbb_captcha_plugin'))
+{
+ include(PHPBB_ROOT_PATH . "includes/captcha/captcha_plugin." . PHP_EXT);
+}
+
+/** A small class until we get the autoloader done */
+class phpbb_captcha_factory
+{
+ /**
+ * return an instance of class $name in file $name_plugin.php
+ */
+ public static function get_instance($name)
+ {
+ $name = basename($name);
+ if (!class_exists($name))
+ {
+ include(PHPBB_ROOT_PATH . "includes/captcha/plugins/{$name}_plugin." . PHP_EXT);
+ }
+ return call_user_func(array($name, 'get_instance'));
+ }
+
+ /**
+ * Call the garbage collector
+ */
+ public static function garbage_collect($name)
+ {
+ $name = basename($name);
+ if (!class_exists($name))
+ {
+ include(PHPBB_ROOT_PATH . "includes/captcha/plugins/{$name}_plugin." . PHP_EXT);
+ }
+ call_user_func(array($name, 'garbage_collect'), 0);
+ }
+
+ /**
+ * return a list of all discovered CAPTCHA plugins
+ */
+ public static function get_captcha_types()
+ {
+ $captchas = array();
+ $captchas['available'] = array();
+ $captchas['unavailable'] = array();
+
+ $dp = @opendir(PHPBB_ROOT_PATH . 'includes/captcha/plugins');
+
+ if ($dp)
+ {
+ while (($file = readdir($dp)) !== false)
+ {
+ if ((preg_match('#_plugin\.' . PHP_EXT . '$#', $file)))
+ {
+ $name = preg_replace('#^(.*?)_plugin\.' . PHP_EXT . '$#', '\1', $file);
+ if (!class_exists($name))
+ {
+ include(PHPBB_ROOT_PATH . "includes/captcha/plugins/$file");
+ }
+ if (call_user_func(array($name, 'is_available')))
+ {
+ $captchas['available'][$name] = call_user_func(array($name, 'get_name'));
+ }
+ else
+ {
+ $captchas['unavailable'][$name] = call_user_func(array($name, 'get_name'));
+ }
+ }
+ }
+ closedir($dp);
+ }
+
+ return $captchas;
+ }
+} \ No newline at end of file
diff --git a/phpBB/includes/captcha/captcha_non_gd.php b/phpBB/includes/captcha/captcha_non_gd.php
index 24452aca26..3f9db24f3a 100644
--- a/phpBB/includes/captcha/captcha_non_gd.php
+++ b/phpBB/includes/captcha/captcha_non_gd.php
@@ -85,7 +85,7 @@ class captcha
}
else
{
- for ($j = 0; $j < $this->width; $j++)
+ for ($j = 0; $j < self::width; $j++)
{
$image .= chr(mt_rand(140, 255));
}
@@ -93,7 +93,7 @@ class captcha
}
unset($hold_chars);
- $image = self::create_png($image, $this->width, $this->height);
+ $image = self::create_png($image, self::width, self::height);
// Output image
header('Content-Type: image/png');
@@ -149,7 +149,7 @@ class captcha
* png because it's a fully recognised open standard and supported
* by practically all modern browsers and OSs
*/
- function create_png($raw_image, $width, $height)
+ static function create_png($raw_image, $width, $height)
{
// SIG
$image = pack('C8', 137, 80, 78, 71, 13, 10, 26, 10);
diff --git a/phpBB/includes/captcha/captcha_plugin.php b/phpBB/includes/captcha/captcha_plugin.php
new file mode 100755
index 0000000000..08a149764c
--- /dev/null
+++ b/phpBB/includes/captcha/captcha_plugin.php
@@ -0,0 +1,97 @@
+<?
+
+interface phpbb_captcha_plugin
+{
+ /**
+ * Initiates the CAPTCHA to validate codes.
+ * @param int $type the type as defined in constants.php
+ */
+ function init($type);
+
+
+ /**
+ * Returns true if the captcha will work on the current install
+ */
+ static function is_available();
+
+ /**
+ * Returns the translated pretty name of the captcha.
+ */
+ static function get_name();
+
+ /**
+ * Returns the class name of the captcha.
+ */
+ static function get_class_name();
+
+ /**
+ * Returns an instance; does not have to be the same instance twice.
+ */
+ static function get_instance();
+
+ /**
+ * Returns the HTML needed to embed the captcha in another template
+ */
+ function get_template();
+
+
+ /**
+ * Delivers the image of image based captchas; not required for text/remote etc CAPTCHAs
+ */
+ function execute();
+
+ /**
+ * Returns the HTML needed to display a demo of the captcha
+ */
+ function get_demo_template($id);
+
+
+ /**
+ * Delivers the demo image of image based captchas; not required for text/remote etc CAPTCHAs
+ */
+ function execute_demo();
+
+ /**
+ * Clears leftover entries in the database.
+ */
+ static function garbage_collect($type);
+
+
+ /**
+ * Clears all entries from the database if the CAPTCHA is replaced
+ */
+ function uninstall();
+
+ /**
+ * Sets up the CAPTCHA when it is selected in the ACP.
+ */
+ function install();
+
+
+ /**
+ * Checks the captcha; returns false if the code was correct; a translated error string otherwise
+ */
+ function validate();
+
+ /**
+ * Prepares the captcha to ask a new question; required call on failed answers
+ */
+ function reset();
+
+ /**
+ * Displays the configuration options in the ACP
+ */
+ function acp_page($id, &$module);
+
+ /**
+ * Returns the entries for the hidden field array needed to preserve the current state.
+ */
+ function get_hidden_fields();
+
+
+ /**
+ * Returns the number of solving attempts of the current user
+ */
+ function get_attempt_count();
+
+} \ No newline at end of file
diff --git a/phpBB/includes/captcha/plugins/captcha_abstract.php b/phpBB/includes/captcha/plugins/captcha_abstract.php
new file mode 100755
index 0000000000..a1a56db1e1
--- /dev/null
+++ b/phpBB/includes/captcha/plugins/captcha_abstract.php
@@ -0,0 +1,301 @@
+<?
+/**
+*
+* @package VC
+* @version $Id: $
+* @copyright (c) 2006 2008 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+
+/**
+* This class holds the code shared by the two default 3.0 CAPTCHAs.
+*/
+abstract class phpbb_default_captcha implements phpbb_captcha_plugin
+{
+ protected $confirm_id;
+ protected $confirm_code;
+ protected $code;
+ protected $seed;
+ protected $type;
+ protected $solved = false;
+
+
+ function init($type)
+ {
+ global $config, $db, $user;
+
+ // read input
+ $this->confirm_id = request_var('confirm_id', '');
+ $this->confirm_code = request_var('confirm_code', '');
+ $this->type = (int) $type;
+
+ if (!strlen($this->confirm_id))
+ {
+ // we have no confirm ID, better get ready to display something
+ $this->generate_code();
+ }
+ }
+
+ function execute_demo()
+ {
+ global $user;
+
+ $this->code = gen_rand_string(mt_rand(5, 8));
+ $this->seed = hexdec(substr(unique_id(), 4, 10));
+
+ // compute $seed % 0x7fffffff
+ $this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff);
+
+ captcha::execute($this->code, $this->seed);
+ }
+
+
+ function execute()
+ {
+ if (empty($this->code))
+ {
+ if (!$this->load_code())
+ {
+ // invalid request, bail out
+ return false;
+ }
+ }
+ captcha::execute($this->code, $this->seed);
+ }
+
+
+ function get_template()
+ {
+ global $config, $user, $template;
+
+ $template->set_filenames(array(
+ 'captcha' => 'captcha_default.html')
+ );
+
+ $template->assign_vars(array(
+ 'CONFIRM_IMAGE' => append_sid('ucp', 'mode=confirm&amp;confirm_id=' . $this->confirm_id . '&amp;type=' . $this->type),
+ 'CONFIRM_ID' => $this->confirm_id,
+ ));
+
+ return $template->assign_display('captcha');
+ }
+
+ function get_demo_template($id)
+ {
+ global $config, $user, $template;
+
+ $template->set_filenames(array(
+ 'captcha_demo' => 'captcha_default_acp_demo.html')
+ );
+ // acp_captcha has a delivery function; let's use it
+ $template->assign_vars(array(
+ 'CONFIRM_IMAGE' => append_sid(PHPBB_ADMIN_PATH . 'index.' . PHP_EXT, 'captcha_demo=1&amp;mode=visual&amp;i=' . $id . '&amp;select_captcha=' . $this->get_class_name()),
+ 'CONFIRM_ID' => $this->confirm_id,
+ ));
+
+ return $template->assign_display('captcha_demo');
+ }
+
+ function get_hidden_fields()
+ {
+ $hidden_fields = array();
+
+ // this is required for postig.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;
+ }
+
+ static 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()
+ {
+ self::garbage_collect(0);
+ }
+
+ function install()
+ {
+ return;
+ }
+
+ function validate()
+ {
+ global $config, $db, $user;
+
+ $this->confirm_code = request_var('confirm_code', '');
+
+ if (!$this->confirm_id)
+ {
+ $error = $user->lang['CONFIRM_CODE_WRONG'];
+ }
+ else
+ {
+ if ($this->check_code())
+ {
+ // $this->delete_code(); commented out to allow posting.php to repeat the question
+ $this->solved = true;
+ }
+ else
+ {
+ $error = $user->lang['CONFIRM_CODE_WRONG'];
+ }
+ }
+
+ if (strlen($error))
+ {
+ // okay, inorect answer. Let's ask a new question
+ $this->reset();
+ return $error;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ /**
+ * The old way to generate code, suitable for GD and non-GD. Resets the internal state.
+ */
+ protected function generate_code()
+ {
+ global $db, $user;
+
+ $this->code = gen_rand_string(mt_rand(5, 8));
+ $this->confirm_id = md5(unique_id($user->ip));
+ $this->seed = hexdec(substr(unique_id(), 4, 10));
+ $this->solved = false;
+ // 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);
+ }
+
+ /**
+ * Look up everything we need for painting&checking.
+ */
+ protected function load_code()
+ {
+ global $db, $user;
+ $sql = 'SELECT code, seed
+ 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'];
+ return true;
+ }
+ return false;
+
+ }
+
+ protected function check_code()
+ {
+ global $db;
+
+ if (empty($this->code))
+ {
+ if (!$this->load_code())
+ {
+ return false;
+ }
+ }
+ return (strcasecmp($this->code, $this->confirm_code) === 0);
+ }
+
+ protected function delete_code()
+ {
+ global $db, $user;
+
+ $sql = 'DELETE FROM ' . CONFIRM_TABLE . "
+ WHERE confirm_id = '" . $db->sql_escape($confirm_id) . "'
+ AND session_id = '" . $db->sql_escape($user->session_id) . "'
+ AND confirm_type = " . $this->type;
+ $db->sql_query($sql);
+ }
+
+ function get_attempt_count()
+ {
+ global $db, $user;
+
+ $sql = 'SELECT COUNT(session_id) AS attempts
+ FROM ' . CONFIRM_TABLE . "
+ WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
+ AND confirm_type = " . $this->type;
+ $result = $db->sql_query($sql);
+ $attempts = (int) $db->sql_fetchfield('attempts');
+ $db->sql_freeresult($result);
+
+ return $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();
+ }
+
+}
+
diff --git a/phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php
new file mode 100755
index 0000000000..e4f0bff87e
--- /dev/null
+++ b/phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php
@@ -0,0 +1,101 @@
+<?
+/**
+*
+* @package VC
+* @version $Id: $
+* @copyright (c) 2006 2008 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Placeholder for autoload
+*/
+include_once(PHPBB_ROOT_PATH . "includes/captcha/plugins/captcha_abstract." . PHP_EXT);
+
+class phpbb_captcha_gd extends phpbb_default_captcha implements phpbb_captcha_plugin
+{
+
+ function __construct()
+ {
+ include_once(PHPBB_ROOT_PATH . "includes/captcha/captcha_gd." . PHP_EXT);
+ }
+
+ public static function get_instance()
+ {
+ return new phpbb_captcha_gd();
+ }
+
+ static function is_available()
+ {
+ return (@extension_loaded('gd') || can_load_dll('gd'));
+ }
+
+ static function get_name()
+ {
+ return 'CAPTCHA_GD';
+ }
+
+ static function get_class_name()
+ {
+ return 'phpbb_captcha_gd';
+ }
+
+ function acp_page($id, &$module)
+ {
+ global $config, $db, $template, $user;
+
+ $captcha_vars = array(
+ 'captcha_gd_x_grid' => 'CAPTCHA_GD_X_GRID',
+ 'captcha_gd_y_grid' => 'CAPTCHA_GD_Y_GRID',
+ 'captcha_gd_foreground_noise' => 'CAPTCHA_GD_FOREGROUND_NOISE',
+ 'captcha_gd' => 'CAPTCHA_GD_PREVIEWED'
+ );
+
+ $module->tpl_name = 'captcha_gd_acp';
+ $module->page_title = 'ACP_VC_SETTINGS';
+ $form_key = 'acp_captcha';
+ add_form_key($form_key);
+
+ $submit = request_var('submit', '');
+
+ if ($submit && check_form_key($form_key))
+ {
+ $captcha_vars = array_keys($captcha_vars);
+ foreach ($captcha_vars as $captcha_var)
+ {
+ $value = request_var($captcha_var, 0);
+ if ($value >= 0)
+ {
+ set_config($captcha_var, $value);
+ }
+ }
+ trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action));
+ }
+ else if ($submit)
+ {
+ trigger_error($user->lang['FORM_INVALID'] . adm_back_link($module->u_action));
+ }
+ else
+ {
+ foreach ($captcha_vars as $captcha_var => $template_var)
+ {
+ $var = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, 0) : $config[$captcha_var];
+ $template->assign_var($template_var, $var);
+ }
+ $template->assign_vars(array(
+ 'CAPTCHA_PREVIEW' => $this->get_demo_template($id),
+ 'CAPTCHA_NAME' => $this->get_class_name(),
+ ));
+
+ }
+ }
+}
+
diff --git a/phpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php
new file mode 100755
index 0000000000..a2521a330e
--- /dev/null
+++ b/phpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php
@@ -0,0 +1,58 @@
+<?
+/**
+*
+* @package VC
+* @version $Id: $
+* @copyright (c) 2006 2008 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+include_once(PHPBB_ROOT_PATH . "includes/captcha/plugins/captcha_abstract." . PHP_EXT);
+
+class phpbb_captcha_nogd extends phpbb_default_captcha implements phpbb_captcha_plugin
+{
+
+ function __construct()
+ {
+ include_once(PHPBB_ROOT_PATH . "includes/captcha/captcha_non_gd." . PHP_EXT);
+ }
+
+ public static function get_instance()
+ {
+ return new phpbb_captcha_nogd();
+ }
+
+ static function is_available()
+ {
+ return true;
+ }
+
+ static function get_name()
+ {
+ global $user;
+
+ return 'CAPTCHA_NO_GD';
+ }
+
+ static function get_class_name()
+ {
+ return 'phpbb_captcha_nogd';
+ }
+
+
+ function acp_page($id, &$module)
+ {
+ global $user;
+
+ trigger_error($user->lang['CAPTCHA_NO_OPTIONS'] . adm_back_link($module->u_action));
+ }
+}
+
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 8fef702ab1..734a9716c8 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -2365,6 +2365,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
{
global $db, $user, $template, $auth, $config;
+ include(PHPBB_ROOT_PATH . 'includes/captcha/captcha_factory.' . PHP_EXT);
$err = '';
@@ -2483,34 +2484,13 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
{
case LOGIN_ERROR_ATTEMPTS:
- // Show confirm image
- $sql = 'DELETE FROM ' . CONFIRM_TABLE . "
- WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
- AND confirm_type = " . CONFIRM_LOGIN;
- $db->sql_query($sql);
-
- // Generate code
- $code = gen_rand_string(mt_rand(5, 8));
- $confirm_id = md5(unique_id($user->ip));
- $seed = hexdec(substr(unique_id(), 4, 10));
-
- // compute $seed % 0x7fffffff
- $seed -= 0x7fffffff * floor($seed / 0x7fffffff);
-
- $sql = 'INSERT INTO ' . CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array(
- 'confirm_id' => (string) $confirm_id,
- 'session_id' => (string) $user->session_id,
- 'confirm_type' => (int) CONFIRM_LOGIN,
- 'code' => (string) $code,
- 'seed' => (int) $seed)
- );
- $db->sql_query($sql);
+ $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $captcha->init(CONFIRM_LOGIN);
+ $captcha->reset();
$template->assign_vars(array(
'S_CONFIRM_CODE' => true,
- 'CONFIRM_ID' => $confirm_id,
- 'CONFIRM_IMAGE' => '<img src="' . append_sid('ucp', 'mode=confirm&amp;id=' . $confirm_id . '&amp;type=' . CONFIRM_LOGIN) . '" alt="" title="" />',
- 'L_LOGIN_CONFIRM_EXPLAIN' => sprintf($user->lang['LOGIN_CONFIRM_EXPLAIN'], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>'),
+ 'CONFIRM' => $captcha->get_template(''),
));
$err = $user->lang[$result['error_msg']];
diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php
index b5f2a9b6a1..450f044414 100644
--- a/phpBB/includes/session.php
+++ b/phpBB/includes/session.php
@@ -923,40 +923,16 @@ class session
WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time']));
$db->sql_query($sql);
}
- $this->confirm_gc();
- }
-
- return;
- }
-
- function confirm_gc($type = 0)
- {
- 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
+
+ // only called from CRON; should be a safe workaround until the infrastructure gets going
+ if (!class_exists('captcha_factory'))
{
- $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);
+ include(PHPBB_ROOT_PATH . "includes/captcha/captcha_factory." . PHP_EXT);
}
+ captcha_factory::garbage_collect($config['captcha_plugin']);
}
- $db->sql_freeresult($result);
+
+ return;
}
diff --git a/phpBB/includes/ucp/ucp_confirm.php b/phpBB/includes/ucp/ucp_confirm.php
index 94fb9a729f..26ffc3c5fb 100644
--- a/phpBB/includes/ucp/ucp_confirm.php
+++ b/phpBB/includes/ucp/ucp_confirm.php
@@ -3,7 +3,7 @@
*
* @package VC
* @version $Id$
-* @copyright (c) 2005 phpBB Group
+* @copyright (c) 2005 2008 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
@@ -36,43 +36,10 @@ class ucp_confirm
function main($id, $mode)
{
global $db, $user, $config;
-
- // Do we have an id? No, then just exit
- $confirm_id = request_var('id', '');
- $type = request_var('type', 0);
-
- if (!$confirm_id || !$type)
- {
- exit;
- }
-
- // Try and grab code for this id and session
- $sql = 'SELECT code, seed
- FROM ' . CONFIRM_TABLE . "
- WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
- AND confirm_id = '" . $db->sql_escape($confirm_id) . "'
- AND confirm_type = $type";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- // If we have a row then grab data else create a new id
- if (!$row)
- {
- exit;
- }
-
- if ($config['captcha_gd'])
- {
- include(PHPBB_ROOT_PATH . 'includes/captcha/captcha_gd.' . PHP_EXT);
- }
- else
- {
- include(PHPBB_ROOT_PATH . 'includes/captcha/captcha_non_gd.' . PHP_EXT);
- }
-
- captcha::execute($row['code'], $row['seed']);
-
+ include(PHPBB_ROOT_PATH . 'includes/captcha/captcha_factory.' . PHP_EXT);
+ $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $captcha->init(request_var('type', 0));
+ $captcha->execute();
garbage_collection();
exit_handler();
}
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 0246e96061..c0ebd5f2c5 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -37,7 +37,6 @@ class ucp_register
include(PHPBB_ROOT_PATH . 'includes/functions_profile_fields.' . PHP_EXT);
- $confirm_id = request_var('confirm_id', '');
$coppa = (isset($_REQUEST['coppa'])) ? ((!empty($_REQUEST['coppa'])) ? 1 : 0) : false;
$agreed = (!empty($_POST['agreed'])) ? 1 : 0;
$submit = (isset($_POST['submit'])) ? true : false;
@@ -53,7 +52,14 @@ class ucp_register
add_form_key('ucp_register_terms');
}
-
+
+ if ($config['enable_confirm'])
+ {
+ include(PHPBB_ROOT_PATH . 'includes/captcha/captcha_factory.' . PHP_EXT);
+ $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $captcha->init(CONFIRM_REG);
+ }
+
if ($change_lang || $user_lang != $config['default_lang'])
{
$use_lang = ($change_lang) ? basename($change_lang) : basename($user_lang);
@@ -88,8 +94,8 @@ class ucp_register
{
$add_lang = ($change_lang) ? '&amp;change_lang=' . urlencode($change_lang) : '';
$add_coppa = ($coppa !== false) ? '&amp;coppa=' . $coppa : '';
-
- $s_hidden_fields = ($confirm_id) ? array('confirm_id' => $confirm_id) : array();
+
+ $s_hidden_fields = array();
// If we change the language, we want to pass on some more possible parameter.
if ($change_lang)
@@ -99,11 +105,14 @@ class ucp_register
'username' => utf8_normalize_nfc(request_var('username', '', true)),
'email' => strtolower(request_var('email', '')),
'email_confirm' => strtolower(request_var('email_confirm', '')),
- 'confirm_code' => request_var('confirm_code', ''),
- 'confirm_id' => request_var('confirm_id', ''),
'lang' => $user->lang_name,
'tz' => request_var('tz', (float) $config['board_timezone']),
));
+
+ if ($config['enable_confirm'])
+ {
+ $s_hidden_fields = array_merge($s_hidden_fields, $captcha->get_hidden_fields());
+ }
}
if ($coppa === false && $config['coppa_enable'])
@@ -167,7 +176,6 @@ class ucp_register
'password_confirm' => request_var('password_confirm', '', true),
'email' => strtolower(request_var('email', '')),
'email_confirm' => strtolower(request_var('email_confirm', '')),
- 'confirm_code' => request_var('confirm_code', ''),
'lang' => basename(request_var('lang', $user->lang_name)),
'tz' => request_var('tz', (float) $timezone),
);
@@ -187,7 +195,6 @@ class ucp_register
array('string', false, 6, 60),
array('email')),
'email_confirm' => array('string', false, 6, 60),
- 'confirm_code' => array('string', !$config['enable_confirm'], 5, 8),
'tz' => array('num', false, -14, 14),
'lang' => array('match', false, '#^[a-z_\-]{2,}$#i'),
));
@@ -198,6 +205,22 @@ class ucp_register
// Replace "error" strings with their real, localised form
$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
+ if ($config['enable_confirm'])
+ {
+ $vc_response = $captcha->validate();
+ if ($vc_response)
+ {
+ $error[] = $vc_response;
+ }
+ else
+ {
+ $captcha->reset();
+ }
+ if ($config['max_reg_attempts'] && $captcha->get_attempt_count() > $config['max_reg_attempts'])
+ {
+ $error[] = $user->lang['TOO_MANY_REGISTERS'];
+ }
+ }
// DNSBL check
if ($config['check_dnsbl'])
{
@@ -210,50 +233,6 @@ class ucp_register
// validate custom profile fields
$cp->submit_cp_field('register', $user->get_iso_lang_id(), $cp_data, $error);
- // Visual Confirmation handling
- $wrong_confirm = false;
- if ($config['enable_confirm'])
- {
- if (!$confirm_id)
- {
- $error[] = $user->lang['CONFIRM_CODE_WRONG'];
- $wrong_confirm = true;
- }
- else
- {
- $sql = 'SELECT code
- FROM ' . CONFIRM_TABLE . "
- WHERE confirm_id = '" . $db->sql_escape($confirm_id) . "'
- AND session_id = '" . $db->sql_escape($user->session_id) . "'
- AND confirm_type = " . CONFIRM_REG;
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if ($row)
- {
- if (strcasecmp($row['code'], $data['confirm_code']) === 0)
- {
- $sql = 'DELETE FROM ' . CONFIRM_TABLE . "
- WHERE confirm_id = '" . $db->sql_escape($confirm_id) . "'
- AND session_id = '" . $db->sql_escape($user->session_id) . "'
- AND confirm_type = " . CONFIRM_REG;
- $db->sql_query($sql);
- }
- else
- {
- $error[] = $user->lang['CONFIRM_CODE_WRONG'];
- $wrong_confirm = true;
- }
- }
- else
- {
- $error[] = $user->lang['CONFIRM_CODE_WRONG'];
- $wrong_confirm = true;
- }
- }
- }
-
if (!sizeof($error))
{
if ($data['new_password'] != $data['password_confirm'])
@@ -451,57 +430,16 @@ class ucp_register
if ($change_lang)
{
$str = '&amp;change_lang=' . $change_lang;
- $sql = 'SELECT code
- FROM ' . CONFIRM_TABLE . "
- WHERE confirm_id = '" . $db->sql_escape($confirm_id) . "'
- AND session_id = '" . $db->sql_escape($user->session_id) . "'
- AND confirm_type = " . CONFIRM_REG;
- $result = $db->sql_query($sql);
- if (!$row = $db->sql_fetchrow($result))
- {
- $confirm_id = '';
- }
- $db->sql_freeresult($result);
}
else
{
$str = '';
}
- if (!$change_lang || !$confirm_id)
- {
- $user->confirm_gc(CONFIRM_REG);
-
- $sql = 'SELECT COUNT(session_id) AS attempts
- FROM ' . CONFIRM_TABLE . "
- WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
- AND confirm_type = " . CONFIRM_REG;
- $result = $db->sql_query($sql);
- $attempts = (int) $db->sql_fetchfield('attempts');
- $db->sql_freeresult($result);
-
- if ($config['max_reg_attempts'] && $attempts > $config['max_reg_attempts'])
- {
- trigger_error('TOO_MANY_REGISTERS');
- }
-
- $code = gen_rand_string(mt_rand(5, 8));
- $confirm_id = md5(unique_id($user->ip));
- $seed = hexdec(substr(unique_id(), 4, 10));
-
- // compute $seed % 0x7fffffff
- $seed -= 0x7fffffff * floor($seed / 0x7fffffff);
-
- $sql = 'INSERT INTO ' . CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array(
- 'confirm_id' => (string) $confirm_id,
- 'session_id' => (string) $user->session_id,
- 'confirm_type' => (int) CONFIRM_REG,
- 'code' => (string) $code,
- 'seed' => (int) $seed)
- );
- $db->sql_query($sql);
- }
- $confirm_image = '<img src="' . append_sid('ucp', 'mode=confirm&amp;id=' . $confirm_id . '&amp;type=' . CONFIRM_REG . $str) . '" alt="" title="" />';
- $s_hidden_fields .= '<input type="hidden" name="confirm_id" value="' . $confirm_id . '" />';
+
+ $template->assign_vars(array(
+ 'L_CONFIRM_EXPLAIN' => sprintf($user->lang['CONFIRM_EXPLAIN'], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>'),
+ 'S_CAPTCHA' => $captcha->get_template(),
+ ));
}
//
@@ -516,7 +454,7 @@ class ucp_register
$l_reg_cond = $user->lang['UCP_ADMIN_ACTIVATE'];
break;
}
-
+
$template->assign_vars(array(
'ERROR' => (sizeof($error)) ? implode('<br />', $error) : '',
'USERNAME' => $data['username'],
@@ -524,16 +462,13 @@ class ucp_register
'PASSWORD_CONFIRM' => $data['password_confirm'],
'EMAIL' => $data['email'],
'EMAIL_CONFIRM' => $data['email_confirm'],
- 'CONFIRM_IMG' => $confirm_image,
- 'L_CONFIRM_EXPLAIN' => sprintf($user->lang['CONFIRM_EXPLAIN'], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>'),
'L_REG_COND' => $l_reg_cond,
'L_USERNAME_EXPLAIN' => sprintf($user->lang[$config['allow_name_chars'] . '_EXPLAIN'], $config['min_name_chars'], $config['max_name_chars']),
'L_PASSWORD_EXPLAIN' => sprintf($user->lang[$config['pass_complex'] . '_EXPLAIN'], $config['min_pass_chars'], $config['max_pass_chars']),
'S_LANG_OPTIONS' => language_select($data['lang']),
'S_TZ_OPTIONS' => tz_select($data['tz']),
- 'S_CONFIRM_CODE' => ($config['enable_confirm']) ? true : false,
'S_COPPA' => $coppa,
'S_HIDDEN_FIELDS' => $s_hidden_fields,
'S_UCP_ACTION' => append_sid('ucp', 'mode=register'),