Okay, a first ci of the new captcha plugins. We'll add dynamic template includes later, as well as documentation on how to use this. I'm prepared to get yelled at for bugs (oh, I know that there are plenty); but please blame spammers for broken styles and MODs.

git-svn-id: file:///svn/phpbb/branches/phpBB-3_0_0@9524 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
Henry Sudhof 2009-06-02 14:12:23 +00:00
parent b9ece6bdfe
commit b776d02682
36 changed files with 2472 additions and 534 deletions

View file

@ -27,67 +27,31 @@
<dd><label><input type="radio" class="radio" id="confirm_refresh" name="confirm_refresh" value="1"<!-- IF CONFIRM_REFRESH --> checked="checked"<!-- ENDIF --> /> {L_ENABLED}</label> <dd><label><input type="radio" class="radio" id="confirm_refresh" name="confirm_refresh" value="1"<!-- IF CONFIRM_REFRESH --> checked="checked"<!-- ENDIF --> /> {L_ENABLED}</label>
<label><input type="radio" class="radio" name="confirm_refresh" value="0"<!-- IF not CONFIRM_REFRESH --> checked="checked"<!-- ENDIF --> /> {L_DISABLED}</label></dd> <label><input type="radio" class="radio" name="confirm_refresh" value="0"<!-- IF not CONFIRM_REFRESH --> checked="checked"<!-- ENDIF --> /> {L_DISABLED}</label></dd>
</dl> </dl>
<!-- IF GD -->
<dl>
<dt><label for="captcha_gd">{L_CAPTCHA_GD}:</label><br /><span>{L_CAPTCHA_GD_EXPLAIN}</span></dt>
<dd><label><input id="captcha_gd" name="captcha_gd" value="1" class="radio" type="radio"<!-- IF CAPTCHA_GD --> checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input name="captcha_gd" value="0" class="radio" type="radio"<!-- IF not CAPTCHA_GD --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
</dl>
<dl>
<dt><label for="captcha_gd_foreground_noise">{L_CAPTCHA_GD_FOREGROUND_NOISE}:</label><br /><span>{L_CAPTCHA_GD_FOREGROUND_NOISE_EXPLAIN}</span></dt>
<dd><label><input id="captcha_gd_foreground_noise" name="captcha_gd_foreground_noise" value="1" class="radio" type="radio"<!-- IF CAPTCHA_GD_FOREGROUND_NOISE --> checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input name="captcha_gd_foreground_noise" value="0" class="radio" type="radio"<!-- IF not CAPTCHA_GD_FOREGROUND_NOISE --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
</dl>
<dl>
<dt><label for="captcha_gd_x_grid">{L_CAPTCHA_GD_X_GRID}:</label><br /><span>{L_CAPTCHA_GD_X_GRID_EXPLAIN}</span></dt>
<dd><input id="captcha_gd_x_grid" name="captcha_gd_x_grid" value="{CAPTCHA_GD_X_GRID}" type="text" /></dd>
</dl>
<dl>
<dt><label for="captcha_gd_y_grid">{L_CAPTCHA_GD_Y_GRID}:</label><br /><span>{L_CAPTCHA_GD_Y_GRID_EXPLAIN}</span></dt>
<dd><input id="captcha_gd_y_grid" name="captcha_gd_y_grid" value="{CAPTCHA_GD_Y_GRID}" type="text" /></dd>
</dl>
<dl>
<dt><label for="captcha_gd_wave">{L_CAPTCHA_GD_WAVE}:</label><br /><span>{L_CAPTCHA_GD_WAVE_EXPLAIN}</span></dt>
<dd><label><input id="captcha_gd_wave" name="captcha_gd_wave" value="1" class="radio" type="radio"<!-- IF CAPTCHA_GD_WAVE --> checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input name="captcha_gd_wave" value="0" class="radio" type="radio"<!-- IF not CAPTCHA_GD_WAVE --> checked="checked"<!-- ENDIF --> /> {L_NO}</label>
</dd>
</dl>
<dl>
<dt><label for="captcha_gd_3d_noise">{L_CAPTCHA_GD_3D_NOISE}:</label><br /><span>{L_CAPTCHA_GD_3D_NOISE_EXPLAIN}</span></dt>
<dd><label><input id="captcha_gd_3d_noise" name="captcha_gd_3d_noise" value="1" class="radio" type="radio"<!-- IF CAPTCHA_GD_3D_NOISE --> checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input name="captcha_gd_3d_noise" value="0" class="radio" type="radio"<!-- IF not CAPTCHA_GD_3D_NOISE --> checked="checked"<!-- ENDIF --> /> {L_NO}</label>
</dd>
</dl>
<dl>
<dt><label for="captcha_gd_fonts">{L_CAPTCHA_GD_FONTS}:</label><br /><span>{L_CAPTCHA_GD_FONTS_EXPLAIN}</span></dt>
<dd><label><input id="captcha_gd_fonts" name="captcha_gd_fonts" value="1" class="radio" type="radio"<!-- IF CAPTCHA_GD_FONTS == 1 --> checked="checked"<!-- ENDIF --> /> {L_CAPTCHA_FONT_DEFAULT}</label>
<label><input name="captcha_gd_fonts" value="2" class="radio" type="radio"<!-- IF CAPTCHA_GD_FONTS == 2 --> checked="checked"<!-- ENDIF --> /> {L_CAPTCHA_FONT_NEW}</label>
<label><input name="captcha_gd_fonts" value="3" class="radio" type="radio"<!-- IF CAPTCHA_GD_FONTS == 3 --> checked="checked"<!-- ENDIF --> /> {L_CAPTCHA_FONT_LOWER}</label>
</dd>
</dl>
<!-- ENDIF -->
</fieldset> </fieldset>
<fieldset>
<legend>{L_AVAILABLE_CAPTCHAS}</legend>
<dl>
<dt><label for="captcha_select">{L_CAPTCHA_SELECT}:</label><br /><span>{L_CAPTCHA_SELECT_EXPLAIN}</span></dt>
<dd><select id="captcha_select" name="select_captcha" onchange="(document.getElementById('acp_captcha')).submit()" >{CAPTCHA_SELECT}</select></dd>
</dl>
<dl>
<dt><label for="configure">{L_CAPTCHA_CONFIGURE}:</label><br /><span>{L_CAPTCHA_CONFIGURE_EXPLAIN}</span></dt>
<dd><input class="button2" type="submit" id="configure" name="configure" value="{L_CONFIGURE}" /></dd>
</dl>
</fieldset>
<!-- IF CAPTCHA_PREVIEW -->
<fieldset> <fieldset>
<legend>{L_PREVIEW}</legend> <legend>{L_PREVIEW}</legend>
<!-- IF PREVIEW --> {CAPTCHA_PREVIEW}
<div class="successbox">
<h3>{L_WARNING}</h3>
<p>{L_CAPTCHA_PREVIEW_MSG}</p>
</div>
<!-- ENDIF -->
<dl>
<dt><label for="captcha_preview">{L_PREVIEW}:</label><br /><span>{L_CAPTCHA_PREVIEW_EXPLAIN}</span></dt>
<dd><img src="{CAPTCHA_PREVIEW}" alt="{L_PREVIEW}" <!-- IF CAPTCHA_GD_PREVIEWED -->width="360" height="96"<!-- ELSE --> width="320" height="50"<!-- ENDIF --> id="captcha_preview" /></dd>
</dl>
</fieldset> </fieldset>
<!-- ENDIF -->
<fieldset class="submit-buttons"> <fieldset class="submit-buttons">
<legend>{L_SUBMIT}</legend> <legend>{L_SUBMIT}</legend>
<input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" />&nbsp; <input class="button1" type="submit" id="main_submit" name="main_submit" value="{L_SUBMIT}" />&nbsp;
<input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" />&nbsp; <input class="button2" type="reset" id="form_reset" name="reset" value="{L_RESET}" />&nbsp;
<input class="button2" type="submit" id="preview" name="preview" value="{L_PREVIEW}" />
{S_FORM_TOKEN} {S_FORM_TOKEN}
</fieldset> </fieldset>
</form> </form>

View file

@ -0,0 +1,5 @@
<dl>
<dt><label for="captcha_preview">{L_PREVIEW}:</label><br /><span>{L_CAPTCHA_PREVIEW_EXPLAIN}</span></dt>
<dd><img src="{CONFIRM_IMAGE}" alt="{L_PREVIEW}" width="360" height="96" id="captcha_preview" /></dd>
</dl>

View file

@ -0,0 +1,74 @@
<!-- INCLUDE overall_header.html -->
<a name="maincontent"></a>
<h1>{L_ACP_VC_SETTINGS}</h1>
<p>{L_ACP_VC_SETTINGS_EXPLAIN}</p>
<form id="acp_captcha" method="post" action="{U_ACTION}">
<fieldset>
<legend>{L_GENERAL_OPTIONS}</legend>
<dl>
<dt><label for="captcha_gd_foreground_noise">{L_CAPTCHA_GD_FOREGROUND_NOISE}:</label><br /><span>{L_CAPTCHA_GD_FOREGROUND_NOISE_EXPLAIN}</span></dt>
<dd><label><input id="captcha_gd_foreground_noise" name="captcha_gd_foreground_noise" value="1" class="radio" type="radio"<!-- IF CAPTCHA_GD_FOREGROUND_NOISE --> checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input name="captcha_gd_foreground_noise" value="0" class="radio" type="radio"<!-- IF not CAPTCHA_GD_FOREGROUND_NOISE --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
</dl>
<dl>
<dt><label for="captcha_gd_x_grid">{L_CAPTCHA_GD_X_GRID}:</label><br /><span>{L_CAPTCHA_GD_X_GRID_EXPLAIN}</span></dt>
<dd><input id="captcha_gd_x_grid" name="captcha_gd_x_grid" value="{CAPTCHA_GD_X_GRID}" type="text" /></dd>
</dl>
<dl>
<dt><label for="captcha_gd_y_grid">{L_CAPTCHA_GD_Y_GRID}:</label><br /><span>{L_CAPTCHA_GD_Y_GRID_EXPLAIN}</span></dt>
<dd><input id="captcha_gd_y_grid" name="captcha_gd_y_grid" value="{CAPTCHA_GD_Y_GRID}" type="text" /></dd>
</dl>
<dl>
<dt><label for="captcha_gd_wave">{L_CAPTCHA_GD_WAVE}:</label><br /><span>{L_CAPTCHA_GD_WAVE_EXPLAIN}</span></dt>
<dd><label><input id="captcha_gd_wave" name="captcha_gd_wave" value="1" class="radio" type="radio"<!-- IF CAPTCHA_GD_WAVE --> checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input name="captcha_gd_wave" value="0" class="radio" type="radio"<!-- IF not CAPTCHA_GD_WAVE --> checked="checked"<!-- ENDIF --> /> {L_NO}</label>
</dd>
</dl>
<dl>
<dt><label for="captcha_gd_3d_noise">{L_CAPTCHA_GD_3D_NOISE}:</label><br /><span>{L_CAPTCHA_GD_3D_NOISE_EXPLAIN}</span></dt>
<dd><label><input id="captcha_gd_3d_noise" name="captcha_gd_3d_noise" value="1" class="radio" type="radio"<!-- IF CAPTCHA_GD_3D_NOISE --> checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input name="captcha_gd_3d_noise" value="0" class="radio" type="radio"<!-- IF not CAPTCHA_GD_3D_NOISE --> checked="checked"<!-- ENDIF --> /> {L_NO}</label>
</dd>
</dl>
<dl>
<dt><label for="captcha_gd_fonts">{L_CAPTCHA_GD_FONTS}:</label><br /><span>{L_CAPTCHA_GD_FONTS_EXPLAIN}</span></dt>
<dd><label><input id="captcha_gd_fonts" name="captcha_gd_fonts" value="1" class="radio" type="radio"<!-- IF CAPTCHA_GD_FONTS == 1 --> checked="checked"<!-- ENDIF --> /> {L_CAPTCHA_FONT_DEFAULT}</label>
<label><input name="captcha_gd_fonts" value="2" class="radio" type="radio"<!-- IF CAPTCHA_GD_FONTS == 2 --> checked="checked"<!-- ENDIF --> /> {L_CAPTCHA_FONT_NEW}</label>
<label><input name="captcha_gd_fonts" value="3" class="radio" type="radio"<!-- IF CAPTCHA_GD_FONTS == 3 --> checked="checked"<!-- ENDIF --> /> {L_CAPTCHA_FONT_LOWER}</label>
</dd>
</dl>
</fieldset>
<fieldset>
<legend>{L_PREVIEW}</legend>
<!-- IF PREVIEW -->
<div class="successbox">
<h3>{L_WARNING}</h3>
<p>{L_CAPTCHA_PREVIEW_MSG}</p>
</div>
<!-- ENDIF -->
{CAPTCHA_PREVIEW}
</fieldset>
<fieldset class="submit-buttons">
<legend>{L_SUBMIT}</legend>
<input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" />&nbsp;
<input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" />&nbsp;
<input class="button2" type="submit" id="preview" name="preview" value="{L_PREVIEW}" />&nbsp;
<input type="hidden" name="select_captcha" value="{CAPTCHA_NAME}" />
<input type="hidden" name="configure" value="1" />
{S_FORM_TOKEN}
</fieldset>
</form>
<!-- INCLUDE overall_footer.html -->

View file

@ -0,0 +1,19 @@
<!-- IF S_RECAPTCHA_AVAILABLE -->
<dl>
<script type="text/javascript" src="{RECAPTCHA_SERVER}/challenge?k={RECAPTCHA_PUBKEY}{RECAPTCHA_ERRORGET}">
// <![CDATA[
var RecaptchaOptions = {
lang : {L_RECAPTCHA_LANG}
};
// ]]>
</script>
<noscript>
<iframe src="{RECAPTCHA_SERVER}/noscript?k={RECAPTCHA_PUBKEY}{RECAPTCHA_ERRORGET}" height="300" width="500" frameborder="0"></iframe><br/>
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
</noscript>
</dl>
<!-- ELSE -->
{L_RECAPTCHA_NOT_AVAILABLE}
<!-- ENDIF -->

View file

@ -0,0 +1,48 @@
<!-- INCLUDE overall_header.html -->
<a name="maincontent"></a>
<h1>{L_ACP_VC_SETTINGS}</h1>
<p>{L_ACP_VC_SETTINGS_EXPLAIN}</p>
<form id="acp_captcha" method="post" action="{U_ACTION}">
<fieldset>
<legend>{L_GENERAL_OPTIONS}</legend>
<dl>
<dt><label for="recaptcha_pubkey">{L_RECAPTCHA_PUBLIC}:</label><br /><span>{L_RECAPTCHA_PUBLIC_EXPLAIN}</span></dt>
<dd><input id="recaptcha_pubkey" name="recaptcha_pubkey" value="{RECAPTCHA_PUBKEY}" size="50" type="text" /></dd>
</dl>
<dl>
<dt><label for="recaptcha_privkey">{L_RECAPTCHA_PRIVATE}:</label><br /><span>{L_RECAPTCHA_PRIVATE_EXPLAIN}</span></dt>
<dd><input id="recaptcha_privkey" name="recaptcha_privkey" value="{RECAPTCHA_PRIVKEY}" size="50" type="text" /></dd>
</dl>
</fieldset>
<fieldset>
<legend>{L_PREVIEW}</legend>
<!-- IF PREVIEW -->
<div class="successbox">
<h3>{L_WARNING}</h3>
<p>{L_CAPTCHA_PREVIEW_MSG}</p>
</div>
<!-- ENDIF -->
{CAPTCHA_PREVIEW}
</fieldset>
<fieldset class="submit-buttons">
<legend>{L_SUBMIT}</legend>
<input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" />&nbsp;
<input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" />&nbsp;
<input type="hidden" name="select_captcha" value="{CAPTCHA_NAME}" />
<input type="hidden" name="configure" value="1" />
{S_FORM_TOKEN}
</fieldset>
</form>
<!-- INCLUDE overall_footer.html -->

View file

@ -53,6 +53,7 @@
<ol> <ol>
<li><a href="#changelog">Changelog</a> <li><a href="#changelog">Changelog</a>
<ol style="list-style-type: lower-roman;"> <ol style="list-style-type: lower-roman;">
<li><a href="#v305">Changes since 3.0.5</a></li>
<li><a href="#v304">Changes since 3.0.4</a></li> <li><a href="#v304">Changes since 3.0.4</a></li>
<li><a href="#v303">Changes since 3.0.3</a></li> <li><a href="#v303">Changes since 3.0.3</a></li>
<li><a href="#v302">Changes since 3.0.2</a></li> <li><a href="#v302">Changes since 3.0.2</a></li>
@ -84,7 +85,12 @@
<div class="inner"><span class="corners-top"><span></span></span> <div class="inner"><span class="corners-top"><span></span></span>
<div class="content"> <div class="content">
<a name="v304"></a><h3>1.i. Changes since 3.0.4</h3> <a name="v305"></a><h3>1.i. Changes since 3.0.5</h3>
<ul>
<li>[Feature] Backported 3.2 cpatcha plugins.</li>
</ul>
<a name="v304"></a><h3>1.ii. Changes since 3.0.4</h3>
<ul> <ul>
<li>[Fix] Delete user entry from ban list table upon user deletion (Bug #40015 - Patch by TerraFrost)</li> <li>[Fix] Delete user entry from ban list table upon user deletion (Bug #40015 - Patch by TerraFrost)</li>
@ -173,7 +179,7 @@
<li>[Sec] Only use forum id supplied for posting if global announcement detected. (Reported by nickvergessen)</li> <li>[Sec] Only use forum id supplied for posting if global announcement detected. (Reported by nickvergessen)</li>
</ul> </ul>
<a name="v303"></a><h3>1.ii. Changes since 3.0.3</h3> <a name="v303"></a><h3>1.iii. Changes since 3.0.3</h3>
<ul> <ul>
<li>[Fix] Allow mixed-case template directories to be inherited (Bug #36725)</li> <li>[Fix] Allow mixed-case template directories to be inherited (Bug #36725)</li>
@ -205,7 +211,7 @@
<li>[Sec] Ask for forum password if post within passworded forum quoted in private message. (Reported by nickvergessen)</li> <li>[Sec] Ask for forum password if post within passworded forum quoted in private message. (Reported by nickvergessen)</li>
</ul> </ul>
<a name="v302"></a><h3>1.iii. Changes since 3.0.2</h3> <a name="v302"></a><h3>1.iv. Changes since 3.0.2</h3>
<ul> <ul>
<li>[Fix] Correctly set topic starter if first post in topic removed (Bug #30575 - Patch by blueray2048)</li> <li>[Fix] Correctly set topic starter if first post in topic removed (Bug #30575 - Patch by blueray2048)</li>
@ -304,7 +310,7 @@
<li>[Sec Precaution] Stricter validation of the HTTP_HOST header (Thanks to Techie-Micheal et al for pointing out possible issues in derived code)</li> <li>[Sec Precaution] Stricter validation of the HTTP_HOST header (Thanks to Techie-Micheal et al for pointing out possible issues in derived code)</li>
</ul> </ul>
<a name="v301"></a><h3>1.iv. Changes since 3.0.1</h3> <a name="v301"></a><h3>1.v. Changes since 3.0.1</h3>
<ul> <ul>
<li>[Fix] Ability to set permissions on non-mysql dbms (Bug #24955)</li> <li>[Fix] Ability to set permissions on non-mysql dbms (Bug #24955)</li>
@ -352,7 +358,7 @@
<li>[Sec] Only allow urls gone through redirect() being used within login_box(). (thanks nookieman)</li> <li>[Sec] Only allow urls gone through redirect() being used within login_box(). (thanks nookieman)</li>
</ul> </ul>
<a name="v300"></a><h3>1.v. Changes since 3.0.0</h3> <a name="v300"></a><h3>1.vi Changes since 3.0.0</h3>
<ul> <ul>
<li>[Change] Validate birthdays (Bug #15004)</li> <li>[Change] Validate birthdays (Bug #15004)</li>
@ -423,7 +429,7 @@
<li>[Fix] Find and display colliding usernames correctly when converting from one database to another (Bug #23925)</li> <li>[Fix] Find and display colliding usernames correctly when converting from one database to another (Bug #23925)</li>
</ul> </ul>
<a name="v30rc8"></a><h3>1.vi. Changes since 3.0.RC8</h3> <a name="v30rc8"></a><h3>1.vii. Changes since 3.0.RC8</h3>
<ul> <ul>
<li>[Fix] Cleaned usernames contain only single spaces, so &quot;a_name&quot; and &quot;a__name&quot; are treated as the same name (Bug #15634)</li> <li>[Fix] Cleaned usernames contain only single spaces, so &quot;a_name&quot; and &quot;a__name&quot; are treated as the same name (Bug #15634)</li>
@ -432,7 +438,7 @@
<li>[Fix] Call garbage_collection() within database updater to correctly close connections (affects Oracle for example)</li> <li>[Fix] Call garbage_collection() within database updater to correctly close connections (affects Oracle for example)</li>
</ul> </ul>
<a name="v30rc7"></a><h3>1.vii. Changes since 3.0.RC7</h3> <a name="v30rc7"></a><h3>1.viii. Changes since 3.0.RC7</h3>
<ul> <ul>
<li>[Fix] Fixed MSSQL related bug in the update system</li> <li>[Fix] Fixed MSSQL related bug in the update system</li>
@ -467,7 +473,7 @@
<li>[Fix] No duplication of active topics (Bug #15474)</li> <li>[Fix] No duplication of active topics (Bug #15474)</li>
</ul> </ul>
<a name="v30rc6"></a><h3>1.viii. Changes since 3.0.RC6</h3> <a name="v30rc6"></a><h3>1.ix. Changes since 3.0.RC6</h3>
<ul> <ul>
<li>[Fix] Submitting language changes using acp_language (Bug #14736)</li> <li>[Fix] Submitting language changes using acp_language (Bug #14736)</li>
@ -477,7 +483,7 @@
<li>[Fix] Able to request new password (Bug #14743)</li> <li>[Fix] Able to request new password (Bug #14743)</li>
</ul> </ul>
<a name="v30rc5"></a><h3>1.ix. Changes since 3.0.RC5</h3> <a name="v30rc5"></a><h3>1.x. Changes since 3.0.RC5</h3>
<ul> <ul>
<li>[Feature] Removing constant PHPBB_EMBEDDED in favor of using an exit_handler(); the constant was meant to achive this more or less.</li> <li>[Feature] Removing constant PHPBB_EMBEDDED in favor of using an exit_handler(); the constant was meant to achive this more or less.</li>
@ -540,7 +546,7 @@
<li>[Sec] New password hashing mechanism for storing passwords (#i42)</li> <li>[Sec] New password hashing mechanism for storing passwords (#i42)</li>
</ul> </ul>
<a name="v30rc4"></a><h3>1.x. Changes since 3.0.RC4</h3> <a name="v30rc4"></a><h3>1.xi. Changes since 3.0.RC4</h3>
<ul> <ul>
<li>[Fix] MySQL, PostgreSQL and SQLite related database fixes (Bug #13862)</li> <li>[Fix] MySQL, PostgreSQL and SQLite related database fixes (Bug #13862)</li>
@ -591,7 +597,7 @@
<li>[Fix] odbc_autocommit causing existing result sets to be dropped (Bug #14182)</li> <li>[Fix] odbc_autocommit causing existing result sets to be dropped (Bug #14182)</li>
</ul> </ul>
<a name="v30rc3"></a><h3>1.xi. Changes since 3.0.RC3</h3> <a name="v30rc3"></a><h3>1.xii. Changes since 3.0.RC3</h3>
<ul> <ul>
<li>[Fix] Fixing some subsilver2 and prosilver style issues</li> <li>[Fix] Fixing some subsilver2 and prosilver style issues</li>
@ -700,7 +706,7 @@
</ul> </ul>
<a name="v30rc2"></a><h3>1.xii. Changes since 3.0.RC2</h3> <a name="v30rc2"></a><h3>1.xiii. Changes since 3.0.RC2</h3>
<ul> <ul>
<li>[Fix] Re-allow searching within the memberlist</li> <li>[Fix] Re-allow searching within the memberlist</li>
@ -746,7 +752,7 @@
</ul> </ul>
<a name="v30rc1"></a><h3>1.xiii. Changes since 3.0.RC1</h3> <a name="v30rc1"></a><h3>1.xiv. Changes since 3.0.RC1</h3>
<ul> <ul>
<li>[Fix] (X)HTML issues within the templates (Bug #11255, #11255)</li> <li>[Fix] (X)HTML issues within the templates (Bug #11255, #11255)</li>

View file

@ -10,6 +10,8 @@
/** /**
* @ignore * @ignore
*/ */
if (!defined('IN_PHPBB')) if (!defined('IN_PHPBB'))
{ {
exit; exit;
@ -28,45 +30,32 @@ class acp_captcha
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
$user->add_lang('acp/board'); $user->add_lang('acp/board');
$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',
'captcha_gd_wave' => 'CAPTCHA_GD_WAVE',
'captcha_gd_3d_noise' => 'CAPTCHA_GD_3D_NOISE',
'captcha_gd_fonts' => 'CAPTCHA_GD_FONTS',
); include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
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); $this->deliver_demo($selected);
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']) // Delegate
if ($configure)
{ {
include($phpbb_root_path . 'includes/captcha/captcha_gd.' . $phpEx); $config_captcha = phpbb_captcha_factory::get_instance($selected);
$config_captcha->acp_page($id, $this);
add_log('admin', 'LOG_CONFIG_VISUAL');
} }
else else
{ {
include($phpbb_root_path . 'includes/captcha/captcha_non_gd.' . $phpEx); $captchas = phpbb_captcha_factory::get_captcha_types();
}
$captcha = new captcha();
$captcha->execute(gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)), time());
exit;
}
$config_vars = array( $config_vars = array(
'enable_confirm' => 'REG_ENABLE', 'enable_confirm' => 'REG_ENABLE',
'enable_post_confirm' => 'POST_ENABLE', 'enable_post_confirm' => 'POST_ENABLE',
'confirm_refresh' => 'CONFIRM_REFRESH', 'confirm_refresh' => 'CONFIRM_REFRESH',
'captcha_gd' => 'CAPTCHA_GD',
); );
$this->tpl_name = 'acp_captcha'; $this->tpl_name = 'acp_captcha';
@ -74,62 +63,86 @@ class acp_captcha
$form_key = 'acp_captcha'; $form_key = 'acp_captcha';
add_form_key($form_key); add_form_key($form_key);
$submit = request_var('submit', ''); $submit = request_var('main_submit', false);
if ($submit && check_form_key($form_key)) if ($submit && check_form_key($form_key))
{ {
$config_vars = array_keys($config_vars); $config_vars = array_keys($config_vars);
foreach ($config_vars as $config_var) foreach ($config_vars as $config_var)
{ {
set_config($config_var, request_var($config_var, '')); set_config($config_var, request_var($config_var, false));
} }
if ($selected !== $config['captcha_plugin'])
$captcha_vars = array_keys($captcha_vars);
foreach ($captcha_vars as $captcha_var)
{ {
$value = request_var($captcha_var, 0); // sanity check
if ($value >= 0) if (isset($captchas['available'][$selected]))
{ {
set_config($captcha_var, $value); $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();
add_log('admin', 'LOG_CONFIG_VISUAL'); add_log('admin', 'LOG_CONFIG_VISUAL');
}
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) else if ($submit)
{ {
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action)); trigger_error($user->lang['FORM_INVALID'] . adm_back_link());
} }
else else
{ {
$preview_image_src = append_sid(append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&amp;demo=demo")); $captcha_select = '';
foreach ($captchas['available'] as $value => $title)
if (@extension_loaded('gd'))
{ {
$template->assign_var('GD', true); $current = ($selected !== false && $value == $selected) ? ' selected="selected"' : '';
$captcha_select .= '<option value="' . $value . '"' . $current . '>' . $user->lang[$title] . '</option>';
} }
foreach ($captchas['unavailable'] as $value => $title)
{
$current = ($selected !== false && $value == $selected) ? ' selected="selected"' : '';
$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) 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_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 .= "&amp;$captcha_var=" . $var;
}
$template->assign_vars(array( $template->assign_vars(array(
'CAPTCHA_PREVIEW' => $preview_image_src, 'CAPTCHA_PREVIEW' => $demo_captcha->get_demo_template($id),
'PREVIEW' => isset($_POST['preview']), '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,41 +81,14 @@ function login_db(&$username, &$password)
} }
else else
{ {
global $user; $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
$sql = 'SELECT code $vc_response = $captcha->validate();
FROM ' . CONFIRM_TABLE . " if ($vc_response)
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( return array(
'status' => LOGIN_ERROR_ATTEMPTS, '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, 'user_row' => $row,
); );
} }

View file

@ -0,0 +1,92 @@
<?
/**
*
* @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;
}
/** A small class until we get the autoloader done */
class phpbb_captcha_factory
{
/**
* return an instance of class $name in file $name_plugin.php
*/
function get_instance($name)
{
global $phpbb_root_path, $phpEx;
$name = basename($name);
if (!class_exists($name))
{
include($phpbb_root_path . "includes/captcha/plugins/{$name}_plugin." . $phpEx);
}
return call_user_func(array($name, 'get_instance'));
}
/**
* Call the garbage collector
*/
function garbage_collect($name)
{
global $phpbb_root_path, $phpEx;
$name = basename($name);
if (!class_exists($name))
{
include($phpbb_root_path . "includes/captcha/plugins/{$name}_plugin." . $phpEx);
}
call_user_func(array($name, 'garbage_collect'), 0);
}
/**
* return a list of all discovered CAPTCHA plugins
*/
function get_captcha_types()
{
global $phpbb_root_path, $phpEx;
$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\.' . $phpEx . '$#', $file)))
{
$name = preg_replace('#^(.*?)_plugin\.' . $phpEx . '$#', '\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

@ -0,0 +1,842 @@
<?php
/**
*
* @package VC
* @version $Id: captcha_gd.php,v 1.19 2007/01/26 16:07:43 acydburn Exp $
* @copyright (c) 2006 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
/**
Wave3D CAPTCHA by Robert Hetzler
*/
class captcha
{
var $width = 360;
var $height = 96;
function execute($code, $seed)
{
global $starttime;
// seed the random generator
mt_srand($seed);
// set height and width
$img_x = $this->width;
$img_y = $this->height;
// Generate image
$img = imagecreatetruecolor($img_x, $img_y);
$x_grid = mt_rand(6, 10);
$y_grid = mt_rand(6, 10);
// Ok, so lets cut to the chase. We could accurately represent this in 3d and
// do all the appropriate linear transforms. my questions is... why bother?
// The computational overhead is unnecessary when you consider the simple fact:
// we're not here to accurately represent a model, but to just show off some random-ish
// polygons
// Conceive of 3 spaces.
// 1) planar-space (discrete "pixel" grid)
// 2) 3-space. (planar-space with z/height aspect)
// 3) image space (pixels on the screen)
// resolution of the planar-space we're embedding the text code in
$plane_x = 100;
$plane_y = 30;
$subdivision_factor = 3;
// $box is the 4 points in img_space that correspond to the corners of the plane in 3-space
$box = array(
'upper_left' => array(
'x' => mt_rand(5, 15),
'y' => mt_rand(10, 15)
),
'upper_right' => array(
'x' => mt_rand($img_x - 35, $img_x - 19),
'y' => mt_rand(10, 17)
),
'lower_left' => array(
'x' => mt_rand($img_x - 5, $img_x - 45),
'y' => mt_rand($img_y - 0, $img_y - 15)
),
);
$box['lower_right'] = array(
'x' => $box['lower_left']['x'] + $box['upper_left']['x'] - $box['upper_right']['x'],
'y' => $box['lower_left']['y'] + $box['upper_left']['y'] - $box['upper_right']['y'],
);
// TODO
$background = imagecolorallocate($img, mt_rand(155, 255), mt_rand(155, 255), mt_rand(155, 255));
imagefill($img, 0, 0, $background);
$black = imagecolorallocate($img, 0, 0, 0);
$random = array();
$fontcolors = array();
for ($i = 0; $i < 15; ++$i)
{
$random[$i] = imagecolorallocate($img, mt_rand(120, 255), mt_rand(120, 255), mt_rand(120, 255));
}
$fontcolors[0] = imagecolorallocate($img, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120));
$colors = array();
$minr = mt_rand(20, 30);
$ming = mt_rand(20, 30);
$minb = mt_rand(20, 30);
$maxr = mt_rand(150, 230);
$maxg = mt_rand(150, 230);
$maxb = mt_rand(150, 230);
for ($i = -30; $i <= 30; ++$i)
{
$coeff1 = ($i + 12) / 45;
$coeff2 = 1 - $coeff1;
$colors[$i] = imagecolorallocate($img, ($coeff2 * $maxr) + ($coeff1 * $minr), ($coeff2 * $maxg) + ($coeff1 * $ming), ($coeff2 * $maxb) + ($coeff1 * $minb));
}
// $img_buffer is the last row of 3-space positions (converted to img-space), cached
// (using this means we don't need to recalculate all 4 positions for each new polygon,
// merely the newest point that we're adding, which is then cached.
$img_buffer = array(array(), array());
// In image-space, the x- and y-offset necessary to move one unit in the x-direction in planar-space
$dxx = ($box['upper_right']['x'] - $box['upper_left']['x']) / ($subdivision_factor * $plane_x);
$dxy = ($box['upper_right']['y'] - $box['upper_left']['y']) / ($subdivision_factor * $plane_x);
// In image-space, the x- and y-offset necessary to move one unit in the y-direction in planar-space
$dyx = ($box['lower_right']['x'] - $box['upper_left']['x']) / ($subdivision_factor * $plane_y);
$dyy = ($box['lower_right']['y'] - $box['upper_left']['y']) / ($subdivision_factor * $plane_y);
// Initial captcha-letter offset in planar-space
$plane_offset_x = mt_rand(3, 8);
$plane_offset_y = mt_rand( 12, 15);
// character map
$map = $this->captcha_bitmaps();
// matrix
$plane = array();
// for each character, we'll silkscreen it into our boolean pixel plane
for ($c = 0, $code_num = strlen($code); $c < $code_num; ++$c)
{
$letter = $code[$c];
for ($x = $map['width'] - 1; $x >= 0; --$x)
{
for ($y = $map['height'] - 1; $y >= 0; --$y)
{
if ($map['data'][$letter][$y][$x])
{
$plane[$y + $plane_offset_y + (($c & 1) ? 1 : -1)][$x + $plane_offset_x] = true;
}
}
}
$plane_offset_x += 11;
}
// calculate our first buffer, we can't actually draw polys with these yet
// img_pos_prev == screen x,y location to our immediate left.
// img_pos_cur == current screen x,y location
// we calculate screen position of our
// current cell based on the difference from the previous cell
// rather than recalculating from absolute coordinates
// What we cache into the $img_buffer contains the raised text coordinates.
$img_pos_prev = $img_buffer[0][0] = array($box['upper_left']['x'], $box['upper_left']['y']);
$cur_height = $prev_height = $this->wave_height(0, 0, $subdivision_factor);
$full_x = $plane_x * $subdivision_factor;
$full_y = $plane_y * $subdivision_factor;
for ($x = 1; $x <= $full_x; ++$x)
{
$cur_height = $this->wave_height($x, 0, $subdivision_factor);
$offset = $cur_height - $prev_height;
$img_pos_cur = array($img_pos_prev[0] + $dxx, $img_pos_prev[1] + $dxy + $offset);
$img_buffer[0][$x] = $img_pos_cur;
$img_pos_prev = $img_pos_cur;
$prev_height = $cur_height;
}
for ($y = 1; $y <= $full_y; ++$y)
{
// swap buffers
$buffer_cur = $y & 1;
$buffer_prev = 1 - $buffer_cur;
$prev_height = $this->wave_height(0, $y, $subdivision_factor);
$offset = $prev_height - $this->wave_height(0, $y - 1, $subdivision_factor);
$img_pos_cur = array($img_buffer[$buffer_prev][0][0] + $dyx, min($img_buffer[$buffer_prev][0][1] + $dyy + $offset, $img_y - 1));
// make sure we don't try to write off the page
$img_pos_prev = $img_pos_cur;
$img_buffer[$buffer_cur][0] = $img_pos_cur;
for ($x = 1; $x <= $full_x; ++$x)
{
$cur_height = $this->wave_height($x, $y, $subdivision_factor) + $this->grid_height($x, $y, 1, $x_grid, $y_grid);
// height is a z-factor, not a y-factor
$offset = $cur_height - $prev_height;
$img_pos_cur = array($img_pos_prev[0] + $dxx, $img_pos_prev[1] + $dxy + $offset);
// height is float, index it to an int, get closest color
$color = $colors[intval($cur_height)];
$img_pos_prev = $img_pos_cur;
$prev_height = $cur_height;
$y_index_old = intval(($y - 1) / $subdivision_factor);
$y_index_new = intval($y / $subdivision_factor);
$x_index_old = intval(($x - 1) / $subdivision_factor);
$x_index_new = intval($x / $subdivision_factor);
if (!empty($plane[$y_index_new][$x_index_new]))
{
$img_pos_cur[1] += $this->wave_height($x, $y, $subdivision_factor, 1) - 30 - $cur_height;
$color = $colors[20];
}
$img_pos_cur[1] = min($img_pos_cur[1], $img_y - 1);
$img_buffer[$buffer_cur][$x] = $img_pos_cur;
// Smooth the edges as much as possible by having not more than one low<->high traingle per square
// Otherwise, just
$diag_down = (empty($plane[$y_index_old][$x_index_old]) == empty($plane[$y_index_new][$x_index_new]));
$diag_up = (empty($plane[$y_index_old][$x_index_new]) == empty($plane[$y_index_new][$x_index_old]));
// natural switching
$mode = ($x + $y) & 1;
// override if it requires it
if ($diag_down != $diag_up)
{
$mode = $diag_up;
}
if ($mode)
{
// +-/ /
// 1 |/ 2 /|
// / /-+
$poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x]);
$poly2 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_cur][$x], $img_buffer[$buffer_prev][$x]);
}
else
{
// \ \-+
// 1 |\ 2 \|
// +-\ \
$poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_cur][$x]);
$poly2 = array_merge($img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x], $img_buffer[$buffer_cur][$x]);
}
imagefilledpolygon($img, $poly1, 3, $color);
imagefilledpolygon($img, $poly2, 3, $color);
}
}
// Output image
header('Content-Type: image/png');
header('Cache-control: no-cache, no-store');
//$mtime = explode(' ', microtime());
//$totaltime = $mtime[0] + $mtime[1] - $starttime;
//echo $totaltime . "<br />\n";
//echo memory_get_usage() - $tmp;
imagepng($img);
imagedestroy($img);
}
function wave_height($x, $y, $factor = 1, $tweak = 0.7)
{
// stretch the wave. TODO: pretty it up
$x = $x/5 + 180;
$y = $y/4;
return ((sin($x / (3 * $factor)) + sin($y / (3 * $factor))) * 10 * $tweak);
}
function grid_height($x, $y, $factor = 1, $x_grid, $y_grid)
{
return ((!($x % ($x_grid * $factor)) || !($y % ($y_grid * $factor))) ? 3 : 0);
}
function captcha_bitmaps()
{
return array(
'width' => 9,
'height' => 13,
'data' => array(
'A' => array(
array(0,0,1,1,1,1,0,0,0),
array(0,1,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,1,1,1,1,1,1,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,0,0,0),
),
'B' => array(
array(1,1,1,1,1,1,0,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,1,0,0),
array(1,1,1,1,1,1,0,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,1,0,0),
array(1,1,1,1,1,1,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'C' => array(
array(0,0,1,1,1,1,1,0,0),
array(0,1,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'D' => array(
array(1,1,1,1,1,1,1,0,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,1,0),
array(1,1,1,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'E' => array(
array(0,0,1,1,1,1,1,1,1),
array(0,1,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,1,1,1,1,1,1,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(0,1,0,0,0,0,0,0,0),
array(0,0,1,1,1,1,1,1,1),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'F' => array(
array(0,0,1,1,1,1,1,1,0),
array(0,1,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,1,1,1,1,1,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'G' => array(
array(0,0,1,1,1,1,1,0,0),
array(0,1,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,1,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'H' => array(
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,1,1,1,1,1,1,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'I' => array(
array(0,1,1,1,1,1,1,1,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,1,1,1,1,1,1,1,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'J' => array(
array(0,0,0,0,0,0,1,1,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,0,1),
array(0,0,1,0,0,0,0,1,0),
array(0,0,0,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'K' => array(
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,1,0,0,0),
array(1,0,0,0,1,0,0,0,0),
array(1,0,0,1,0,0,0,0,0),
array(1,0,1,0,0,0,0,0,0),
array(1,1,0,0,0,0,0,0,0),
array(1,0,1,0,0,0,0,0,0),
array(1,0,0,1,0,0,0,0,0),
array(1,0,0,0,1,0,0,0,0),
array(1,0,0,0,0,1,0,0,0),
array(1,0,0,0,0,0,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'L' => array(
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(0,1,0,0,0,0,0,0,0),
array(0,0,1,1,1,1,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'M' => array(
array(0,1,0,0,0,0,0,1,0),
array(0,1,1,0,0,0,1,1,0),
array(0,1,0,1,0,1,0,1,0),
array(0,1,0,0,1,0,0,1,0),
array(0,1,0,0,0,0,0,1,0),
array(0,1,0,0,0,0,0,1,0),
array(0,1,0,0,0,0,0,1,0),
array(0,1,0,0,0,0,0,1,0),
array(0,1,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'N' => array(
array(1,0,0,0,0,0,0,0,1),
array(1,1,0,0,0,0,0,0,1),
array(1,0,1,0,0,0,0,0,1),
array(1,0,0,1,0,0,0,0,1),
array(1,0,0,0,1,0,0,0,1),
array(1,0,0,0,0,1,0,0,1),
array(1,0,0,0,0,0,1,0,1),
array(1,0,0,0,0,0,0,1,1),
array(1,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'O' => array(
array(0,0,0,1,1,1,0,0,0),
array(0,0,1,0,0,0,1,0,0),
array(0,1,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,0,0,0,1,0,0),
array(0,0,0,1,1,1,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'P' => array(
array(1,1,1,1,1,1,0,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,1,0,0),
array(1,1,1,1,1,1,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'Q' => array(
array(0,0,1,1,1,1,0,0,0),
array(0,1,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,1,0,0,1,0),
array(1,0,0,0,0,1,0,1,0),
array(0,1,0,0,0,0,1,0,0),
array(0,0,1,1,1,1,0,1,0),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'R' => array(
array(1,1,1,1,1,1,0,0,0),
array(1,0,0,0,0,0,1,0,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,1,0,0),
array(1,1,1,1,1,1,0,0,0),
array(1,0,1,0,0,0,0,0,0),
array(1,0,0,1,0,0,0,0,0),
array(1,0,0,0,1,0,0,0,0),
array(1,0,0,0,0,1,0,0,0),
array(1,0,0,0,0,0,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'S' => array(
array(0,0,1,1,1,1,1,1,1),
array(0,1,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(0,1,0,0,0,0,0,0,0),
array(0,0,1,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,1,0),
array(1,1,1,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'T' => array(
array(1,1,1,1,1,1,1,1,1),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'U' => array(
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'V' => array(
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,0,0,0,1,0,0),
array(0,0,0,1,0,1,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'W' => array(
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,1,0,0,0,1),
array(1,0,0,1,0,1,0,0,1),
array(1,0,1,0,0,0,1,0,1),
array(1,1,0,0,0,0,0,1,1),
array(1,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'X' => array(
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,0,0,0,1,0,0),
array(0,0,0,1,0,1,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,1,0,1,0,0,0),
array(0,0,1,0,0,0,1,0,0),
array(0,1,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'Y' => array(
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,0,0,0,1,0,0),
array(0,0,0,1,0,1,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'Z' => array(
array(1,1,1,1,1,1,1,1,1),
array(1,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,1,0,0),
array(0,0,0,0,0,1,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,1,0,0,0,0,0),
array(0,0,1,0,0,0,0,0,0),
array(0,1,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,1),
array(1,1,1,1,1,1,1,1,1),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'1' => array(
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,1,1,0,0,0,0),
array(0,0,1,0,1,0,0,0,0),
array(0,1,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,1,1,1,1,1,1,1,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'2' => array(
array(0,0,0,1,1,1,0,0,0),
array(0,0,1,0,0,0,1,0,0),
array(0,1,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,1,0,0),
array(0,0,0,0,0,1,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,1,0,0,0,0,0),
array(0,0,1,0,0,0,0,0,0),
array(0,1,1,1,1,1,1,1,1),
array(0,0,0,0,0,0,0,0,0),
),
'3' => array(
array(0,0,0,1,1,1,1,0,0),
array(0,0,1,0,0,0,0,1,0),
array(0,1,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,1,1,0,0),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,0,1),
array(0,0,1,0,0,0,0,1,0),
array(0,0,0,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'4' => array(
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,1,1,0),
array(0,0,0,0,0,1,0,1,0),
array(0,0,0,0,1,0,0,1,0),
array(0,0,0,1,0,0,0,1,0),
array(0,0,1,0,0,0,0,1,0),
array(0,1,1,1,1,1,1,1,1),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'5' => array(
array(1,1,1,1,1,1,1,1,1),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(0,1,0,0,0,0,0,0,0),
array(0,0,1,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'6' => array(
array(0,0,1,1,1,1,1,0,0),
array(0,1,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,0,0,0,0,0,0),
array(1,0,0,1,1,1,1,0,0),
array(1,0,1,0,0,0,0,1,0),
array(1,1,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'7' => array(
array(1,1,1,1,1,1,1,1,1),
array(1,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,1,0),
array(0,0,0,0,0,0,1,0,0),
array(0,0,0,0,0,1,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,1,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'8' => array(
array(0,0,1,1,1,1,1,0,0),
array(0,1,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,1,1,1,1,0,0),
array(0,1,0,0,0,0,0,1,0),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(1,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,0),
array(0,0,1,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
),
'9' => array(
array(0,0,0,1,1,1,1,0,0),
array(0,0,1,0,0,0,0,1,0),
array(0,1,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,1,1),
array(0,0,1,1,1,1,1,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,0,0,0,0,0,0,0,1),
array(0,1,0,0,0,0,0,0,1),
array(0,0,1,0,0,0,0,1,0),
array(0,0,0,1,1,1,1,0,0),
array(0,0,0,0,0,0,0,0,0),
array(0,0,0,0,0,0,0,0,0),
),
)
);
}
}
?>

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,332 @@
<?
/**
*
* @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.
*/
class phpbb_default_captcha
{
var $confirm_id;
var $confirm_code;
var $code;
var $seed;
var $type;
var $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', '');
$refresh = request_var('refresh_vc', false) && $config['confirm_refresh'];
$this->type = (int) $type;
if (!strlen($this->confirm_id))
{
// 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(mt_rand(5, 8));
$this->seed = hexdec(substr(unique_id(), 4, 10));
// compute $seed % 0x7fffffff
$this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff);
$captcha = new captcha();
$captcha->execute($this->code, $this->seed);
}
function execute()
{
if (empty($this->code))
{
if (!$this->load_code())
{
// invalid request, bail out
return false;
}
}
$captcha = new captcha();
$captcha->execute($this->code, $this->seed);
}
function get_template()
{
global $config, $user, $template, $phpEx, $phpbb_root_path;
$template->set_filenames(array(
'captcha' => 'captcha_default.html')
);
$template->assign_vars(array(
'CONFIRM_IMAGE' => append_sid($phpbb_root_path . 'ucp.' . $phpEx . '?mode=confirm&amp;confirm_id=' . $this->confirm_id . '&amp;type=' . $this->type),
'CONFIRM_ID' => $this->confirm_id,
'S_REFRESH' => (bool) $config['confirm_refresh'],
));
return $template->assign_display('captcha');
}
function get_demo_template($id)
{
global $config, $user, $template, $phpbb_admin_path, $phpEx;
$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.' . $phpEx . '?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;
}
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->generate_code();
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(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);
}
/**
* New Question, if desired.
*/
function regenerate_code()
{
global $db, $user;
$this->code = gen_rand_string(mt_rand(5, 8));
$this->seed = hexdec(substr(unique_id(), 4, 10));
$this->solved = false;
// 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);
}
/**
* Look up everything we need for painting&checking.
*/
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;
}
function check_code()
{
global $db;
if (empty($this->code))
{
if (!$this->load_code())
{
return false;
}
}
return (strcasecmp($this->code, $this->confirm_code) === 0);
}
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,122 @@
<?
/**
*
* @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
*/
if (!class_exists('phpbb_default_captcha'))
{
include_once($phpbb_root_path . "includes/captcha/plugins/captcha_abstract." . $phpEx);
}
class phpbb_captcha_gd extends phpbb_default_captcha
{
function phpbb_captcha_gd()
{
global $phpbb_root_path, $phpEx;
if (!class_exists('captcha'))
{
include_once($phpbb_root_path . "includes/captcha/captcha_gd." . $phpEx);
}
}
function get_instance()
{
return new phpbb_captcha_gd();
}
function is_available()
{
return (@extension_loaded('gd') || can_load_dll('gd'));
}
function get_name()
{
return 'CAPTCHA_GD';
}
function get_class_name()
{
return 'phpbb_captcha_gd';
}
function acp_page($id, &$module)
{
global $db, $user, $auth, $template;
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
$user->add_lang('acp/board');
$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',
'captcha_gd_wave' => 'CAPTCHA_GD_WAVE',
'captcha_gd_3d_noise' => 'CAPTCHA_GD_3D_NOISE',
'captcha_gd_fonts' => 'CAPTCHA_GD_FONTS',
);
$config_vars = array(
'enable_confirm' => 'REG_ENABLE',
'enable_post_confirm' => 'POST_ENABLE',
'confirm_refresh' => 'CONFIRM_REFRESH',
'captcha_gd' => 'CAPTCHA_GD',
);
$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,66 @@
<?php
/**
*
* @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
*/
if (!class_exists('captcha_abstract'))
{
include_once($phpbb_root_path . 'includes/captcha/plugins/captcha_abstract.' . $phpEx);
}
class phpbb_captcha_gd_wave extends phpbb_default_captcha
{
function phpbb_captcha_gd_wave()
{
global $phpbb_root_path, $phpEx;
if (!class_exists('captcha'))
{
include_once($phpbb_root_path . 'includes/captcha/captcha_gd_wave.' . $phpEx);
}
}
function get_instance()
{
return new phpbb_captcha_gd_wave();
}
function is_available()
{
return (@extension_loaded('gd') || can_load_dll('gd'));
}
function get_name()
{
return 'CAPTCHA_GD_WAVE';
}
function get_class_name()
{
return 'phpbb_captcha_gd_wave';
}
function acp_page($id, &$module)
{
global $config, $db, $template, $user;
trigger_error($user->lang['CAPTCHA_NO_OPTIONS'] . adm_back_link($module->u_action));
}
}
?>

View file

@ -0,0 +1,68 @@
<?
/**
*
* @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
*/
if (!class_exists('phpbb_default_captcha'))
{
include_once($phpbb_root_path . "includes/captcha/plugins/captcha_abstract." . $phpEx);
}
class phpbb_captcha_nogd extends phpbb_default_captcha
{
function phpbb_captcha_nogd()
{
global $phpbb_root_path, $phpEx;
if (!class_exists('captcha'))
{
include_once($phpbb_root_path . "includes/captcha/captcha_non_gd." . $phpEx);
}
}
function get_instance()
{
return new phpbb_captcha_nogd();
}
function is_available()
{
return true;
}
function get_name()
{
global $user;
return 'CAPTCHA_NO_GD';
}
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

@ -0,0 +1,312 @@
<?
/**
*
* @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;
}
if (!class_exists('phpbb_default_captcha'))
{
// we need the classic captcha code for tracking solutions and attempts
include_once($phpbb_root_path . "includes/captcha/plugins/captcha_abstract." . $phpEx);
}
class phpbb_recaptcha extends phpbb_default_captcha
{
var $recaptcha_server = 'http://api.recaptcha.net';
var $recaptcha_verify_server = 'api-verify.recaptcha.net';
var $challenge;
var $response;
function init($type)
{
global $config, $db, $user;
$user->add_lang('recaptcha');
parent::init($type);
$this->challenge = request_var('recaptcha_challenge_field', '');
$this->response = request_var('recaptcha_response_field', '');
}
function get_instance()
{
return new phpbb_recaptcha();
}
function is_available()
{
global $config, $user;
$user->add_lang('recaptcha');
return (isset($config['recaptcha_pubkey']) && !empty($config['recaptcha_pubkey']));
}
function get_name()
{
return 'CAPTCHA_RECAPTCHA';
}
function get_class_name()
{
return 'phpbb_recaptcha';
}
function acp_page($id, &$module)
{
global $config, $db, $template, $user;
$captcha_vars = array(
'recaptcha_pubkey' => 'RECAPTCHA_PUBKEY',
'recaptcha_privkey' => 'RECAPTCHA_PRIVKEY',
);
$module->tpl_name = 'captcha_recaptcha_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, '');
if ($value)
{
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, '') : ((isset($config[$captcha_var])) ? $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(),
));
}
}
// not needed
function execute_demo()
{
}
// not needed
function execute()
{
}
function get_template()
{
global $config, $user, $template;
$template->set_filenames(array(
'captcha' => 'captcha_recaptcha.html')
);
$template->assign_vars(array(
'RECAPTCHA_SERVER' => $this->recaptcha_server,
'RECAPTCHA_PUBKEY' => isset($config['recaptcha_pubkey']) ? $config['recaptcha_pubkey'] : '',
'RECAPTCHA_ERRORGET' => '',
'S_RECAPTCHA_AVAILABLE' => $this->is_available(),
));
return $template->assign_display('captcha');
}
function get_demo_template($id)
{
return $this->get_template();
}
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;
}
function uninstall()
{
self::garbage_collect(0);
}
function install()
{
return;
}
function validate()
{
if (!parent::validate())
{
return false;
}
else
{
return $this->recaptcha_check_answer();
}
}
// Code from here on is based on recaptchalib.php
/*
* This is a PHP library that handles calling reCAPTCHA.
* - Documentation and latest version
* http://recaptcha.net/plugins/php/
* - Get a reCAPTCHA API Key
* http://recaptcha.net/api/getkey
* - Discussion group
* http://groups.google.com/group/recaptcha
*
* Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
* AUTHORS:
* Mike Crawford
* Ben Maurer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* Submits an HTTP POST to a reCAPTCHA server
* @param string $host
* @param string $path
* @param array $data
* @param int port
* @return array response
*/
function _recaptcha_http_post($host, $path, $data, $port = 80)
{
$req = $this->_recaptcha_qsencode ($data);
$http_request = "POST $path HTTP/1.0\r\n";
$http_request .= "Host: $host\r\n";
$http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
$http_request .= "Content-Length: " . strlen($req) . "\r\n";
$http_request .= "User-Agent: reCAPTCHA/PHP/phpBB\r\n";
$http_request .= "\r\n";
$http_request .= $req;
$response = '';
if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
die ('Could not open socket');
}
fwrite($fs, $http_request);
while ( !feof($fs) )
$response .= fgets($fs, 1160); // One TCP-IP packet
fclose($fs);
$response = explode("\r\n\r\n", $response, 2);
return $response;
}
/**
* Calls an HTTP POST function to verify if the user's guess was correct
* @param array $extra_params an array of extra variables to post to the server
* @return ReCaptchaResponse
*/
function recaptcha_check_answer ($extra_params = array())
{
global $config, $user;
//discard spam submissions
if ($this->challenge == null || strlen($this->challenge) == 0 || $this->response == null || strlen($this->response) == 0)
{
return $user->lang['RECAPTCHA_INCORRECT'];
}
$response = $this->_recaptcha_http_post ($this->recaptcha_verify_server, "/verify",
array (
'privatekey' => $config['recaptcha_privkey'],
'remoteip' => $user->ip,
'challenge' => $this->challenge,
'response' => $this->response
) + $extra_params
);
$answers = explode ("\n", $response[1]);
if (trim ($answers[0]) === 'true')
{
$this->solved = true;
return false;
}
else
{
if ($answers[1] === 'incorrect-captcha-sol')
{
return $user->lang['RECAPTCHA_INCORRECT'];
}
}
}
/**
* Encodes the given data into a query string format
* @param $data - array of string elements to be encoded
* @return string - encoded request
*/
function _recaptcha_qsencode ($data)
{
$req = '';
foreach ( $data as $key => $value )
{
$req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
}
// Cut the last '&'
$req=substr($req,0,strlen($req)-1);
return $req;
}
}

View file

@ -2520,6 +2520,11 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
{ {
global $db, $user, $template, $auth, $phpEx, $phpbb_root_path, $config; global $db, $user, $template, $auth, $phpEx, $phpbb_root_path, $config;
if (!class_exists('phpbb_captcha_factory'))
{
include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
}
$err = ''; $err = '';
// Make sure user->setup() has been called // Make sure user->setup() has been called
@ -2630,34 +2635,14 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
{ {
case LOGIN_ERROR_ATTEMPTS: case LOGIN_ERROR_ATTEMPTS:
// Show confirm image $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$sql = 'DELETE FROM ' . CONFIRM_TABLE . " $captcha->init(CONFIRM_LOGIN);
WHERE session_id = '" . $db->sql_escape($user->session_id) . "' $captcha->reset();
AND confirm_type = " . CONFIRM_LOGIN;
$db->sql_query($sql);
// Generate code
$code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
$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);
$template->assign_vars(array( $template->assign_vars(array(
'S_CONFIRM_CODE' => true, 'S_CONFIRM_CODE' => true,
'CONFIRM_ID' => $confirm_id, 'CONFIRM' => $captcha->get_template(''),
'CONFIRM_IMAGE' => '<img src="' . append_sid("{$phpbb_root_path}ucp.$phpEx", '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>'),
)); ));
$err = $user->lang[$result['error_msg']]; $err = $user->lang[$result['error_msg']];

View file

@ -891,7 +891,7 @@ class session
*/ */
function session_gc() function session_gc()
{ {
global $db, $config; global $db, $config, $phpbb_root_path, $phpEx;
$batch_size = 10; $batch_size = 10;
@ -949,42 +949,18 @@ class session
WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time'])); WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time']));
$db->sql_query($sql); $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." . $phpEx);
}
captcha_factory::garbage_collect($config['captcha_plugin']);
} }
return; 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 * Sets a cookie

View file

@ -3,7 +3,7 @@
* *
* @package VC * @package VC
* @version $Id$ * @version $Id$
* @copyright (c) 2005 phpBB Group * @copyright (c) 2005 2008 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License * @license http://opensource.org/licenses/gpl-license.php GNU Public License
* *
*/ */
@ -37,42 +37,10 @@ class ucp_confirm
{ {
global $db, $user, $phpbb_root_path, $config, $phpEx; global $db, $user, $phpbb_root_path, $config, $phpEx;
// Do we have an id? No, then just exit include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
$confirm_id = request_var('id', ''); $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$type = request_var('type', 0); $captcha->init(request_var('type', 0));
$captcha->execute();
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.' . $phpEx);
}
else
{
include($phpbb_root_path . 'includes/captcha/captcha_non_gd.' . $phpEx);
}
$captcha = new captcha();
$captcha->execute($row['code'], $row['seed']);
garbage_collection(); garbage_collection();
exit_handler(); exit_handler();

View file

@ -37,14 +37,12 @@ class ucp_register
include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx);
$confirm_id = request_var('confirm_id', '');
$confirm_refresh = (isset($_POST['confirm_refresh']) && $config['confirm_refresh']) ? ((!empty($_POST['confirm_refresh'])) ? 1 : 0) : false;
$coppa = (isset($_REQUEST['coppa'])) ? ((!empty($_REQUEST['coppa'])) ? 1 : 0) : false; $coppa = (isset($_REQUEST['coppa'])) ? ((!empty($_REQUEST['coppa'])) ? 1 : 0) : false;
$agreed = (!empty($_POST['agreed'])) ? 1 : 0; $agreed = (!empty($_POST['agreed'])) ? 1 : 0;
$submit = (isset($_POST['submit'])) ? true : false; $submit = (isset($_POST['submit'])) ? true : false;
$change_lang = request_var('change_lang', ''); $change_lang = request_var('change_lang', '');
$user_lang = request_var('lang', $user->lang_name); $user_lang = request_var('lang', $user->lang_name);
$confirm_refresh = (isset($_POST['confirm_refresh']) && $config['confirm_refresh']) ? ((!empty($_POST['confirm_refresh'])) ? 1 : 0) : false;
if ($agreed) if ($agreed)
{ {
add_form_key('ucp_register'); add_form_key('ucp_register');
@ -55,6 +53,13 @@ class ucp_register
} }
if ($config['enable_confirm'])
{
include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
$captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_REG);
}
if ($change_lang || $user_lang != $config['default_lang']) if ($change_lang || $user_lang != $config['default_lang'])
{ {
$use_lang = ($change_lang) ? basename($change_lang) : basename($user_lang); $use_lang = ($change_lang) ? basename($change_lang) : basename($user_lang);
@ -90,7 +95,7 @@ class ucp_register
$add_lang = ($change_lang) ? '&amp;change_lang=' . urlencode($change_lang) : ''; $add_lang = ($change_lang) ? '&amp;change_lang=' . urlencode($change_lang) : '';
$add_coppa = ($coppa !== false) ? '&amp;coppa=' . $coppa : ''; $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 we change the language, we want to pass on some more possible parameter.
if ($change_lang) if ($change_lang)
@ -100,11 +105,14 @@ class ucp_register
'username' => utf8_normalize_nfc(request_var('username', '', true)), 'username' => utf8_normalize_nfc(request_var('username', '', true)),
'email' => strtolower(request_var('email', '')), 'email' => strtolower(request_var('email', '')),
'email_confirm' => strtolower(request_var('email_confirm', '')), 'email_confirm' => strtolower(request_var('email_confirm', '')),
'confirm_code' => request_var('confirm_code', ''),
'confirm_id' => request_var('confirm_id', ''),
'lang' => $user->lang_name, 'lang' => $user->lang_name,
'tz' => request_var('tz', (float) $config['board_timezone']), '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']) if ($coppa === false && $config['coppa_enable'])
@ -168,7 +176,6 @@ class ucp_register
'password_confirm' => request_var('password_confirm', '', true), 'password_confirm' => request_var('password_confirm', '', true),
'email' => strtolower(request_var('email', '')), 'email' => strtolower(request_var('email', '')),
'email_confirm' => strtolower(request_var('email_confirm', '')), 'email_confirm' => strtolower(request_var('email_confirm', '')),
'confirm_code' => request_var('confirm_code', ''),
'lang' => basename(request_var('lang', $user->lang_name)), 'lang' => basename(request_var('lang', $user->lang_name)),
'tz' => request_var('tz', (float) $timezone), 'tz' => request_var('tz', (float) $timezone),
); );
@ -188,7 +195,6 @@ class ucp_register
array('string', false, 6, 60), array('string', false, 6, 60),
array('email')), array('email')),
'email_confirm' => array('string', false, 6, 60), 'email_confirm' => array('string', false, 6, 60),
'confirm_code' => array('string', !$config['enable_confirm'], CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS),
'tz' => array('num', false, -14, 14), 'tz' => array('num', false, -14, 14),
'lang' => array('match', false, '#^[a-z_\-]{2,}$#i'), 'lang' => array('match', false, '#^[a-z_\-]{2,}$#i'),
)); ));
@ -199,6 +205,22 @@ class ucp_register
// Replace "error" strings with their real, localised form // Replace "error" strings with their real, localised form
$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error); $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 // DNSBL check
if ($config['check_dnsbl']) if ($config['check_dnsbl'])
{ {
@ -211,50 +233,6 @@ class ucp_register
// validate custom profile fields // validate custom profile fields
$cp->submit_cp_field('register', $user->get_iso_lang_id(), $cp_data, $error); $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 (!sizeof($error))
{ {
if ($data['new_password'] != $data['password_confirm']) if ($data['new_password'] != $data['password_confirm'])
@ -452,74 +430,17 @@ class ucp_register
if ($change_lang || $confirm_refresh) if ($change_lang || $confirm_refresh)
{ {
$str = '&amp;change_lang=' . $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 else
{ {
$str = ''; $str = '';
} }
if (!$change_lang || !$confirm_id || !$confirm_refresh) $template->assign_vars(array(
{ 'L_CONFIRM_EXPLAIN' => sprintf($user->lang['CONFIRM_EXPLAIN'], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>'),
$user->confirm_gc(CONFIRM_REG); 'S_CAPTCHA' => $captcha->get_template(),
));
$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(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
$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);
}
else if ($confirm_refresh)
{
$code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
$confirm_id = md5(unique_id($user->ip));
$seed = hexdec(substr(unique_id(), 4, 10));
// compute $seed % 0x7fffffff
$seed -= 0x7fffffff * floor($seed / 0x7fffffff);
$sql = 'UPDATE ' . CONFIRM_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array(
'confirm_type' => (int) CONFIRM_REG,
'code' => (string) $code,
'seed' => (int) $seed)) . "
WHERE
confirm_id = '" . $db->sql_escape($confirm_id) . "' AND
session_id = '" . $db->sql_escape($session_id) . "' AND
confirm_type = " . (int) CONFIRM_REG;
$db->sql_query($sql);
}
$confirm_image = '<img src="' . append_sid("{$phpbb_root_path}ucp.$phpEx", '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 . '" />';
} }
// //
@ -542,16 +463,13 @@ class ucp_register
'PASSWORD_CONFIRM' => $data['password_confirm'], 'PASSWORD_CONFIRM' => $data['password_confirm'],
'EMAIL' => $data['email'], 'EMAIL' => $data['email'],
'EMAIL_CONFIRM' => $data['email_confirm'], '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_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_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']), '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_LANG_OPTIONS' => language_select($data['lang']),
'S_TZ_OPTIONS' => tz_select($data['tz']), 'S_TZ_OPTIONS' => tz_select($data['tz']),
'S_CONFIRM_CODE' => ($config['enable_confirm']) ? true : false,
'S_CONFIRM_REFRESH' => ($config['enable_confirm'] && $config['confirm_refresh']) ? true : false, 'S_CONFIRM_REFRESH' => ($config['enable_confirm'] && $config['confirm_refresh']) ? true : false,
'S_COPPA' => $coppa, 'S_COPPA' => $coppa,
'S_HIDDEN_FIELDS' => $s_hidden_fields, 'S_HIDDEN_FIELDS' => $s_hidden_fields,

View file

@ -8,7 +8,7 @@
* *
*/ */
$updates_to_version = '3.0.5'; $updates_to_version = '3.0.6-dev';
// Enter any version to update from to test updates. The version within the db will not be updated. // Enter any version to update from to test updates. The version within the db will not be updated.
$debug_from_version = false; $debug_from_version = false;
@ -677,6 +677,9 @@ function database_update_info()
// No changes from 3.0.5-RC1 to 3.0.5 // No changes from 3.0.5-RC1 to 3.0.5
'3.0.5-RC1' => array(), '3.0.5-RC1' => array(),
// No changes from 3.0.5
'3.0.5' => array(),
); );
} }
@ -1012,6 +1015,14 @@ function change_database_data(&$no_updates, $version)
// No changes from 3.0.5-RC1 to 3.0.5 // No changes from 3.0.5-RC1 to 3.0.5
case '3.0.5-RC1': case '3.0.5-RC1':
break; break;
case '3.0.5':
// TODO: smarter detection here; problem without GD.
set_config('captcha_plugin', 'phpbb_captcha_nogd');
break;
} }
} }

View file

@ -1373,8 +1373,8 @@ class install_install extends module
if (@extension_loaded('gd') || can_load_dll('gd')) if (@extension_loaded('gd') || can_load_dll('gd'))
{ {
$sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
SET config_value = '1' SET config_value = 'phpbb_captcha_gd'
WHERE config_name = 'captcha_gd'"; WHERE config_name = 'captcha_plugin'";
} }
$ref = substr($referer, strpos($referer, '://') + 3); $ref = substr($referer, strpos($referer, '://') + 3);

View file

@ -60,7 +60,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('browser_check', '1
INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_interval', '10'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_interval', '10');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_type', 'd'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_type', 'd');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('cache_gc', '7200'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('cache_gc', '7200');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_plugin', 'phpbb_captcha_nogd');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_foreground_noise', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_foreground_noise', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_x_grid', '25'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_x_grid', '25');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_y_grid', '25'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_y_grid', '25');

View file

@ -234,8 +234,10 @@ $lang = array_merge($lang, array(
// Visual Confirmation Settings // Visual Confirmation Settings
$lang = array_merge($lang, array( $lang = array_merge($lang, array(
'ACP_VC_SETTINGS_EXPLAIN' => 'Here you are able to define visual confirmation defaults and CAPTCHA settings.', 'ACP_VC_SETTINGS_EXPLAIN' => 'Here you are able to define visual confirmation defaults and CAPTCHA settings.',
'AVAILABLE_CAPTCHAS' => 'Available plugins',
'CAPTCHA_UNAVAILABLE' => 'The CAPTCHA cannot be selected as its requirements are not met.',
'CAPTCHA_GD' => 'GD CAPTCHA', 'CAPTCHA_GD' => 'GD CAPTCHA',
'CAPTCHA_GD_WAVE' => 'GD Wave Captcha',
'CAPTCHA_GD_FOREGROUND_NOISE' => 'GD CAPTCHA foreground noise', 'CAPTCHA_GD_FOREGROUND_NOISE' => 'GD CAPTCHA foreground noise',
'CAPTCHA_GD_EXPLAIN' => 'Use GD to make a more advanced CAPTCHA.', 'CAPTCHA_GD_EXPLAIN' => 'Use GD to make a more advanced CAPTCHA.',
'CAPTCHA_GD_FOREGROUND_NOISE_EXPLAIN' => 'Use foreground noise to make the GD based CAPTCHA harder.', 'CAPTCHA_GD_FOREGROUND_NOISE_EXPLAIN' => 'Use foreground noise to make the GD based CAPTCHA harder.',
@ -252,10 +254,16 @@ $lang = array_merge($lang, array(
'CAPTCHA_FONT_DEFAULT' => 'Default', 'CAPTCHA_FONT_DEFAULT' => 'Default',
'CAPTCHA_FONT_NEW' => 'New Shapes', 'CAPTCHA_FONT_NEW' => 'New Shapes',
'CAPTCHA_FONT_LOWER' => 'Also use lowercase', 'CAPTCHA_FONT_LOWER' => 'Also use lowercase',
'CAPTCHA_NO_GD' => 'CAPTCHA without GD',
'CAPTCHA_PREVIEW_MSG' => 'Your changes to the visual confirmation setting were not saved. This is just a preview.', 'CAPTCHA_PREVIEW_MSG' => 'Your changes to the visual confirmation setting were not saved. This is just a preview.',
'CAPTCHA_PREVIEW_EXPLAIN' => 'The CAPTCHA as it will look like using the current settings. Use the preview button to refresh. Note that captchas are randomized and will differ from one view to the next.', 'CAPTCHA_PREVIEW_EXPLAIN' => 'The CAPTCHA as it would look like using the current selection.',
'CAPTCHA_SELECT' => 'Installed CAPTCHA plugins',
'CAPTCHA_SELECT_EXPLAIN' => 'The dropdown holds the CAPTCHA plugins recognized by the board. Gray entries are not available right now and might need configuration prior to use.',
'CAPTCHA_CONFIGURE' => 'Configure CAPTCHAs',
'CAPTCHA_CONFIGURE_EXPLAIN' => 'Change the settings for the selected CAPTCHA.',
'CONFIGURE' => 'Configure',
'CAPTCHA_NO_OPTIONS' => 'This CAPTCHA has no configuration options.',
'VISUAL_CONFIRM_POST' => 'Enable visual confirmation for guest postings', 'VISUAL_CONFIRM_POST' => 'Enable visual confirmation for guest postings',
'VISUAL_CONFIRM_POST_EXPLAIN' => 'Requires anonymous users to enter a random code matching an image to help prevent mass postings.', 'VISUAL_CONFIRM_POST_EXPLAIN' => 'Requires anonymous users to enter a random code matching an image to help prevent mass postings.',
'VISUAL_CONFIRM_REG' => 'Enable visual confirmation for registrations', 'VISUAL_CONFIRM_REG' => 'Enable visual confirmation for registrations',

View file

@ -0,0 +1,51 @@
<?php
/**
*
* recaptcha [English]
*
* @package language
* @version $Id: groups.php 8477 2008-03-29 00:08:34Z naderman $
* @copyright (c) 2008 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
/**
* DO NOT CHANGE
*/
if (!defined('IN_PHPBB'))
{
exit;
}
if (empty($lang) || !is_array($lang))
{
$lang = array();
}
// DEVELOPERS PLEASE NOTE
//
// All language files should use UTF-8 as their encoding and the files must not contain a BOM.
//
// Placeholders can now contain order information, e.g. instead of
// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows
// translators to re-order the output of data while ensuring it remains correct
//
// You do not need this where single placeholders are used, e.g. 'Message %d' is fine
// equally where a string contains only two placeholders which are used to wrap text
// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
$lang = array_merge($lang, array(
'RECAPTCHA_LANG' => 'en',
'RECAPTCHA_NOT_AVAILABLE' => 'You have to register for reCaptcha at <a href="http://recaptcha.net">reCaptcha.net</a>.',
'CAPTCHA_RECAPTCHA' => 'reCaptcha',
'RECAPTCHA_INCORRECT' => 'The entered visual confirmation was incorrect',
'RECAPTCHA_PUBLIC' => 'Public reCaptcha key',
'RECAPTCHA_PUBLIC_EXPLAIN' => 'Your public reCaptcha key. You can obtain keys from <a href="http://recaptcha.net">reCaptcha.net</a>.',
'RECAPTCHA_PRIVATE' => 'Private reCaptcha key',
'RECAPTCHA_PRIVATE_EXPLAIN' => 'Your private reCaptcha key. You can obtain keys from <a href="http://recaptcha.net">reCaptcha.net</a>.',
));
?>

View file

@ -45,6 +45,12 @@ $mode = ($delete && !$preview && !$refresh && $submit) ? 'delete' : request_var
$error = $post_data = array(); $error = $post_data = array();
$current_time = time(); $current_time = time();
if ($config['enable_post_confirm'] && !$user->data['is_registered'])
{
include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
$captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_POST);
}
// Was cancel pressed? If so then redirect to the appropriate page // Was cancel pressed? If so then redirect to the appropriate page
if ($cancel || ($current_time - $lastclick < 2 && $submit)) if ($cancel || ($current_time - $lastclick < 2 && $submit))
@ -763,21 +769,10 @@ if ($submit || $preview || $refresh)
if ($config['enable_post_confirm'] && !$user->data['is_registered'] && in_array($mode, array('quote', 'post', 'reply'))) if ($config['enable_post_confirm'] && !$user->data['is_registered'] && in_array($mode, array('quote', 'post', 'reply')))
{ {
$confirm_id = request_var('confirm_id', ''); $vc_response = $captcha->validate();
$confirm_code = request_var('confirm_code', ''); if ($vc_response)
$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_POST;
$result = $db->sql_query($sql);
$confirm_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (empty($confirm_row['code']) || strcasecmp($confirm_row['code'], $confirm_code) !== 0)
{ {
$error[] = $user->lang['CONFIRM_CODE_WRONG']; $error[] = $vc_response;
} }
else else
{ {
@ -1021,7 +1016,10 @@ if ($submit || $preview || $refresh)
} }
$redirect_url = submit_post($mode, $post_data['post_subject'], $post_data['username'], $post_data['topic_type'], $poll, $data, $update_message); $redirect_url = submit_post($mode, $post_data['post_subject'], $post_data['username'], $post_data['topic_type'], $poll, $data, $update_message);
if ($config['enable_post_confirm'] && !$user->data['is_registered'] && in_array($mode, array('quote', 'post', 'reply')))
{
$captcha->reset();
}
// Check the permissions for post approval, as well as the queue trigger where users are put on approval with a post count lower than specified. Moderators are not affected. // Check the permissions for post approval, as well as the queue trigger where users are put on approval with a post count lower than specified. Moderators are not affected.
if ((($config['enable_queue_trigger'] && $user->data['user_posts'] < $config['queue_trigger_posts']) || !$auth->acl_get('f_noapprove', $data['forum_id'])) && !$auth->acl_get('m_approve', $data['forum_id'])) if ((($config['enable_queue_trigger'] && $user->data['user_posts'] < $config['queue_trigger_posts']) || !$auth->acl_get('f_noapprove', $data['forum_id'])) && !$auth->acl_get('m_approve', $data['forum_id']))
{ {
@ -1242,34 +1240,12 @@ generate_forum_rules($post_data);
if ($config['enable_post_confirm'] && !$user->data['is_registered'] && $solved_captcha === false && ($mode == 'post' || $mode == 'reply' || $mode == 'quote')) if ($config['enable_post_confirm'] && !$user->data['is_registered'] && $solved_captcha === false && ($mode == 'post' || $mode == 'reply' || $mode == 'quote'))
{ {
// Show confirm image $captcha->reset();
$sql = 'DELETE FROM ' . CONFIRM_TABLE . "
WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
AND confirm_type = " . CONFIRM_POST;
$db->sql_query($sql);
// Generate code
$code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
$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_POST,
'code' => (string) $code,
'seed' => (int) $seed)
);
$db->sql_query($sql);
$template->assign_vars(array( $template->assign_vars(array(
'S_CONFIRM_CODE' => true, 'S_CONFIRM_CODE' => true,
'CONFIRM_ID' => $confirm_id, 'CONFIRM' => $captcha->get_template(),
'CONFIRM_IMAGE' => '<img src="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=confirm&amp;id=' . $confirm_id . '&amp;type=' . CONFIRM_POST) . '" alt="" title="" />',
'L_POST_CONFIRM_EXPLAIN' => sprintf($user->lang['POST_CONFIRM_EXPLAIN'], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>'),
)); ));
} }
@ -1280,10 +1256,7 @@ $s_hidden_fields .= ($draft_id || isset($_REQUEST['draft_loaded'])) ? '<input ty
// Add the confirm id/code pair to the hidden fields, else an error is displayed on next submit/preview // Add the confirm id/code pair to the hidden fields, else an error is displayed on next submit/preview
if ($solved_captcha !== false) if ($solved_captcha !== false)
{ {
$s_hidden_fields .= build_hidden_fields(array( $s_hidden_fields .= build_hidden_fields($captcha->get_hidden_fields());
'confirm_id' => request_var('confirm_id', ''),
'confirm_code' => request_var('confirm_code', ''))
);
} }
$form_enctype = (@ini_get('file_uploads') == '0' || strtolower(@ini_get('file_uploads')) == 'off' || !$config['allow_attachments'] || !$auth->acl_get('u_attach') || !$auth->acl_get('f_attach', $forum_id)) ? '' : ' enctype="multipart/form-data"'; $form_enctype = (@ini_get('file_uploads') == '0' || strtolower(@ini_get('file_uploads')) == 'off' || !$config['allow_attachments'] || !$auth->acl_get('u_attach') || !$auth->acl_get('f_attach', $forum_id)) ? '' : ' enctype="multipart/form-data"';

View file

@ -0,0 +1,9 @@
<dl>
<dt><label for="confirm_code">{L_CONFIRM_CODE}:</label></dt>
<dd><img src="{CONFIRM_IMAGE}" alt="" /></dd>
<dd><input type="text" name="confirm_code" id="confirm_code" size="8" maxlength="8" class="inputbox narrow" title="{L_CONFIRM_CODE}" />
<!-- IF S_REFRESH --><input type="submit" name="refresh_vc" id="refresh_vc" class="button2" value="{L_VC_REFRESH}" /><!-- ENDIF -->
<input type="hidden" name="confirm_id" id="confirm_id" value="{CONFIRM_ID}" /></dd>
<dd>{L_CONFIRM_CODE_EXPLAIN}</dd>
</dl>

View file

@ -0,0 +1,19 @@
<!-- IF S_RECAPTCHA_AVAILABLE -->
<dl>
<script type="text/javascript" src="{RECAPTCHA_SERVER}/challenge?k={RECAPTCHA_PUBKEY}{RECAPTCHA_ERRORGET}">
// <![CDATA[
var RecaptchaOptions = {
lang : {L_RECAPTCHA_LANG}
};
// ]]>
</script>
<noscript>
<iframe src="{RECAPTCHA_SERVER}/noscript?k={RECAPTCHA_PUBKEY}{RECAPTCHA_ERRORGET}" height="300" width="500" frameborder="0"></iframe><br/>
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
</noscript>
</dl>
<!-- ELSE -->
{L_RECAPTCHA_NOT_AVAILABLE}
<!-- ENDIF -->

View file

@ -21,21 +21,16 @@
<!-- IF U_RESEND_ACTIVATION --><dd><a href="{U_RESEND_ACTIVATION}">{L_RESEND_ACTIVATION}</a></dd><!-- ENDIF --> <!-- IF U_RESEND_ACTIVATION --><dd><a href="{U_RESEND_ACTIVATION}">{L_RESEND_ACTIVATION}</a></dd><!-- ENDIF -->
<!-- ENDIF --> <!-- ENDIF -->
</dl> </dl>
<!-- IF S_CONFIRM_CODE --> <!-- IF S_CONFIRM_CODE -->
<dl> {CONFIRM}
<dt><label for="confirm_code">{L_CONFIRM_CODE}:</label><br /><span>{L_CONFIRM_CODE_EXPLAIN}</span></dt>
<dd><input type="hidden" name="confirm_id" value="{CONFIRM_ID}" />{CONFIRM_IMAGE}</dd>
<dd><input type="text" name="confirm_code" id="confirm_code" size="8" maxlength="8" tabindex="3" class="inputbox narrow" title="{L_CONFIRM_CODE}" /></dd>
</dl>
<!-- ENDIF --> <!-- ENDIF -->
<!-- IF S_DISPLAY_FULL_LOGIN --> <!-- IF S_DISPLAY_FULL_LOGIN -->
<dl> <dl>
<!-- IF S_AUTOLOGIN_ENABLED --><dd><label for="autologin"><input type="checkbox" name="autologin" id="autologin" tabindex="4" /> {L_LOG_ME_IN}</label></dd><!-- ENDIF --> <!-- IF S_AUTOLOGIN_ENABLED --><dd><label for="autologin"><input type="checkbox" name="autologin" id="autologin" tabindex="4" /> {L_LOG_ME_IN}</label></dd><!-- ENDIF -->
<dd><label for="viewonline"><input type="checkbox" name="viewonline" id="viewonline" tabindex="5" /> {L_HIDE_ME}</label></dd> <dd><label for="viewonline"><input type="checkbox" name="viewonline" id="viewonline" tabindex="5" /> {L_HIDE_ME}</label></dd>
</dl> </dl>
<!-- ENDIF --> <!-- ENDIF -->
<dl> <dl>
<dt>&nbsp;</dt> <dt>&nbsp;</dt>
<dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" tabindex="6" value="{L_LOGIN}" class="button1" /></dd> <dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" tabindex="6" value="{L_LOGIN}" class="button1" /></dd>
@ -46,6 +41,7 @@
<span class="corners-bottom"><span></span></span></div> <span class="corners-bottom"><span></span></span></div>
</div> </div>
<!-- IF not S_ADMIN_AUTH and S_REGISTER_ENABLED --> <!-- IF not S_ADMIN_AUTH and S_REGISTER_ENABLED -->
<div class="panel"> <div class="panel">
<div class="inner"><span class="corners-top"><span></span></span> <div class="inner"><span class="corners-top"><span></span></span>

View file

@ -100,11 +100,7 @@
<dd><input type="text" name="subject" id="subject" size="45" maxlength="<!-- IF S_NEW_MESSAGE -->60<!-- ELSE -->64<!-- ENDIF -->" tabindex="2" value="{SUBJECT}{DRAFT_SUBJECT}" class="inputbox autowidth" /></dd> <dd><input type="text" name="subject" id="subject" size="45" maxlength="<!-- IF S_NEW_MESSAGE -->60<!-- ELSE -->64<!-- ENDIF -->" tabindex="2" value="{SUBJECT}{DRAFT_SUBJECT}" class="inputbox autowidth" /></dd>
</dl> </dl>
<!-- IF S_CONFIRM_CODE --> <!-- IF S_CONFIRM_CODE -->
<dl> {CONFIRM}
<dt><label for="confirm_code">{L_CONFIRM_CODE}:</label><br /><span>{L_CONFIRM_CODE_EXPLAIN}</span></dt>
<dd><input type="hidden" name="confirm_id" value="{CONFIRM_ID}" />{CONFIRM_IMAGE}</dd>
<dd><input type="text" name="confirm_code" id="confirm_code" size="8" maxlength="8" tabindex="3" class="inputbox narrow" title="{L_CONFIRM_CODE}" /></dd>
</dl>
<!-- ENDIF --> <!-- ENDIF -->
<!-- ENDIF --> <!-- ENDIF -->

View file

@ -71,8 +71,7 @@
</dl> </dl>
<!-- END profile_fields --> <!-- END profile_fields -->
</fieldset> </fieldset>
<!-- IF S_CAPTCHA -->
<!-- IF S_CONFIRM_CODE -->
<span class="corners-bottom"><span></span></span></div> <span class="corners-bottom"><span></span></span></div>
</div> </div>
@ -83,16 +82,11 @@
<p>{L_CONFIRM_EXPLAIN}</p> <p>{L_CONFIRM_EXPLAIN}</p>
<fieldset class="fields2"> <fieldset class="fields2">
<dl> {S_CAPTCHA}
<dt><label for="confirm_code">{L_CONFIRM_CODE}:</label></dt>
<dd>{CONFIRM_IMG}</dd>
<dd><input type="text" name="confirm_code" id="confirm_code" size="8" maxlength="8" class="inputbox narrow" title="{L_CONFIRM_CODE}" /></dd>
<dd>{L_CONFIRM_CODE_EXPLAIN}<!-- IF S_CONFIRM_REFRESH --> {L_VC_REFRESH_EXPLAIN}<!-- ENDIF --></dd>
<!-- IF S_CONFIRM_REFRESH --><dd><input type="submit" value="{L_VC_REFRESH}" class="button2" /></dd> <!-- ENDIF -->
</dl>
</fieldset>
<!-- ENDIF -->
</fieldset>
<!-- ENDIF -->
<!-- IF S_COPPA --> <!-- IF S_COPPA -->
<span class="corners-bottom"><span></span></span></div> <span class="corners-bottom"><span></span></span></div>
</div> </div>

View file

@ -0,0 +1,19 @@
<tr>
<th colspan="2" valign="middle">{L_CONFIRM_CODE}</th>
</tr>
<tr>
<td class="row3" colspan="2"><span class="gensmall">{L_CONFIRM_CODE_EXPLAIN}</span></td>
</tr>
<tr>
<td class="row1" colspan="2" align="center"><img src="{CONFIRM_IMAGE}" alt="{L_CONFIRM_CODE}" />
<input type="hidden" name="confirm_id" id="confirm_id" value="{CONFIRM_ID}" /></dd>
</td>
</tr>
<tr>
<td class="row1"><b class="genmed">{L_CONFIRM_CODE}: </b><br /><span class="gensmall">{L_CONFIRM_CODE_EXPLAIN}
</span></td>
<td class="row2"><input class="post" type="text" name="confirm_code" size="8" maxlength="8" />
<!-- IF S_REFRESH --><input type="submit" name="refresh_vc" id="refresh_vc" class="button2" value="{L_VC_REFRESH}" /><!-- ENDIF --></td>
</tr>

View file

@ -0,0 +1,21 @@
<!-- IF S_RECAPTCHA_AVAILABLE -->
<tr><td colspan="22>
<script type="text/javascript" src="{RECAPTCHA_SERVER}/challenge?k={RECAPTCHA_PUBKEY}{RECAPTCHA_ERRORGET}">
// <![CDATA[
var RecaptchaOptions = {
lang : {L_RECAPTCHA_LANG}
};
// ]]>
</script>
<noscript>
<iframe src="{RECAPTCHA_SERVER}/noscript?k={RECAPTCHA_PUBKEY}{RECAPTCHA_ERRORGET}" height="300" width="500" frameborder="0"></iframe><br/>
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
</noscript></td></tr>
<!-- ELSE -->
{L_RECAPTCHA_NOT_AVAILABLE}
<!-- ENDIF -->

View file

@ -65,26 +65,13 @@
</td> </td>
</tr> </tr>
<!-- IF S_CONFIRM_CODE --> <!-- IF S_CAPTCHA -->
</table> </table>
<table class="tablebg" width="100%" cellspacing="1"> <table class="tablebg" width="100%" cellspacing="1">
<tr>
<th colspan="2" valign="middle">{L_LOGIN_CONFIRMATION}</th> {S_CAPTCHA}
</tr> <!-- ENDIF -->
<tr>
<td class="row3" colspan="2"><span class="gensmall">{L_LOGIN_CONFIRM_EXPLAIN}</span></td>
</tr>
<tr>
<td class="row1" colspan="2" align="center">
<input type="hidden" name="confirm_id" value="{CONFIRM_ID}" />
{CONFIRM_IMAGE}
</td>
</tr>
<tr>
<td class="row1"><b class="genmed">{L_CONFIRM_CODE}: </b><br /><span class="gensmall">{L_CONFIRM_CODE_EXPLAIN}</span></td>
<td class="row2"><input class="post" type="text" name="confirm_code" size="8" maxlength="8" /></td>
</tr>
<!-- ENDIF -->
<tr> <tr>
<td class="cat" <!-- IF not S_ADMIN_AUTH or S_CONFIRM_CODE -->colspan="2"<!-- ENDIF --> align="center">{S_HIDDEN_FIELDS}<input type="submit" name="login" class="btnmain" value="{L_LOGIN}" tabindex="5" /></td> <td class="cat" <!-- IF not S_ADMIN_AUTH or S_CONFIRM_CODE -->colspan="2"<!-- ENDIF --> align="center">{S_HIDDEN_FIELDS}<input type="submit" name="login" class="btnmain" value="{L_LOGIN}" tabindex="5" /></td>
</tr> </tr>

View file

@ -332,24 +332,10 @@
</tr> </tr>
<!-- ENDIF --> <!-- ENDIF -->
<!-- IF S_CONFIRM_CODE --> <!-- IF S_CAPTCHA -->
<tr> {S_CAPTCHA}
<th colspan="2" valign="middle">{L_POST_CONFIRMATION}</th> <!-- ENDIF -->
</tr>
<tr>
<td class="row3" colspan="2"><span class="gensmall">{L_POST_CONFIRM_EXPLAIN}</span></td>
</tr>
<tr>
<td class="row1" colspan="2" align="center">
<input type="hidden" name="confirm_id" value="{CONFIRM_ID}" />
{CONFIRM_IMAGE}
</td>
</tr>
<tr>
<td class="row1"><b class="genmed">{L_CONFIRM_CODE}: </b><br /><span class="gensmall">{L_CONFIRM_CODE_EXPLAIN}</span></td>
<td class="row2"><input class="post" type="text" name="confirm_code" size="8" maxlength="8" /></td>
</tr>
<!-- ENDIF -->
<!-- IF S_SHOW_ATTACH_BOX or S_SHOW_POLL_BOX --> <!-- IF S_SHOW_ATTACH_BOX or S_SHOW_POLL_BOX -->
<tr> <tr>

View file

@ -77,21 +77,9 @@
</tr> </tr>
<!-- END profile_fields --> <!-- END profile_fields -->
<!-- IF S_CONFIRM_CODE --> <!-- IF S_CAPTCHA -->
<tr> {S_CAPTCHA}
<th colspan="2" valign="middle">{L_CONFIRMATION}</th> <!-- ENDIF -->
</tr>
<tr>
<td class="row3" colspan="2"><span class="gensmall">{L_CONFIRM_EXPLAIN}</span></td>
</tr>
<tr>
<td class="row1" colspan="2" align="center">{CONFIRM_IMG}</td>
</tr>
<tr>
<td class="row1"><b class="genmed">{L_CONFIRM_CODE}: </b><br /><span class="gensmall">{L_CONFIRM_CODE_EXPLAIN} <!-- IF S_CONFIRM_REFRESH -->{L_VC_REFRESH_EXPLAIN}<!-- ENDIF --></span></td>
<td class="row2"><input class="post" type="text" name="confirm_code" size="8" maxlength="8" /><!-- IF S_CONFIRM_REFRESH -->&nbsp;<input type="submit" value="{L_VC_REFRESH}" class="btnlite" /><!-- ENDIF --></td>
</tr>
<!-- ENDIF -->
<!-- IF S_COPPA --> <!-- IF S_COPPA -->
<tr> <tr>