1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-08-06 16:56:44 +02:00

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
This commit is contained in:
Henry Sudhof
2008-09-19 13:17:30 +00:00
parent 5349280538
commit 461be11e8d
23 changed files with 937 additions and 415 deletions

View File

@@ -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);
}
$config_vars = array(
'enable_confirm' => 'REG_ENABLE',
'enable_post_confirm' => 'POST_ENABLE',
'captcha_gd' => 'CAPTCHA_GD',
);
$this->tpl_name = 'acp_captcha';
$this->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))
// Delegate
if ($configure)
{
$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)
{
$value = request_var($captcha_var, 0);
if ($value >= 0)
{
set_config($captcha_var, $value);
}
}
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));
$config_captcha = phpbb_captcha_factory::get_instance($selected);
$config_captcha->acp_page($id, $this);
}
else
{
$captchas = phpbb_captcha_factory::get_captcha_types();
$preview_image_src = append_sid(append_sid(PHPBB_ADMIN_PATH . 'index.' . PHP_EXT, "i=$id&demo=demo"));
if (@extension_loaded('gd'))
{
$template->assign_var('GD', true);
}
foreach ($config_vars as $config_var => $template_var)
{
$template->assign_var($template_var, (isset($_REQUEST[$config_var])) ? request_var($config_var, '') : $config[$config_var]) ;
}
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);
$preview_image_src .= "&$captcha_var=" . $var;
}
$template->assign_vars(array(
'CAPTCHA_PREVIEW' => $preview_image_src,
'PREVIEW' => isset($_POST['preview']),
));
$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);
$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, 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));
}
else if ($submit)
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link());
}
else
{
$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();
}
}
?>

View File

@@ -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)
{
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(
'status' => LOGIN_ERROR_ATTEMPTS,
'error_msg' => 'CONFIRM_CODE_WRONG',
'user_row' => $row,
);
}
}
else
$captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
$vc_response = $captcha->validate();
if ($vc_response)
{
return array(
'status' => LOGIN_ERROR_ATTEMPTS,
'error_msg' => 'CONFIRM_CODE_WRONG',
'user_row' => $row,
'status' => LOGIN_ERROR_ATTEMPTS,
'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
'user_row' => $row,
);
}
}

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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();
}
}

View File

@@ -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(),
));
}
}
}

View File

@@ -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));
}
}

View File

@@ -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']];

View File

@@ -923,42 +923,18 @@ class session
WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time']));
$db->sql_query($sql);
}
$this->confirm_gc();
// only called from CRON; should be a safe workaround until the infrastructure gets going
if (!class_exists('captcha_factory'))
{
include(PHPBB_ROOT_PATH . "includes/captcha/captcha_factory." . PHP_EXT);
}
captcha_factory::garbage_collect($config['captcha_plugin']);
}
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
{
$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);
}
/**
* Sets a cookie

View File

@@ -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();
}

View File

@@ -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'),