additional_plugins/serendipity_event_recaptcha/serendipity_event_recaptcha.php
Andre Pawlowski 88316697e2 Update serendipity_event_recaptcha.php
Try to auto-detect if site is served via HTTPS or HTTP. The original version requests the captcha via HTTP. So if the site is served via HTTPS, the browser will block this attempt and no captcha will be shown on the site.

It is not a perfect solution (a better one would be to let the user configure it), since it would not detect the correct value if the webserver is behind a proxy (the proxy serves the site via HTTPS and the webserver via HTTP to the proxy). But this solution will work in most of the cases until a serendipity developer can add an extra configuration option.
2015-11-27 23:25:37 +01:00

366 lines
14 KiB
PHP

<?php #
if (IN_serendipity !== true) {
die ("Don't hack!");
}
// Probe for a language include with constants. Still include defines later on, if some constants were missing
$probelang = dirname(__FILE__) . '/' . $serendipity['charset'] . 'lang_' . $serendipity['lang'] . '.inc.php';
if (file_exists($probelang)) {
include $probelang;
}
include dirname(__FILE__) . '/lang_en.inc.php';
require_once dirname(__FILE__) . '/recaptcha/recaptchalib.php';
$GLOBALS['recaptcha_api_server'] = 'http://api.recaptcha.net';
$GLOBALS['recaptcha_api_secure_server'] = 'https://api-secure.recaptcha.net';
$GLOBALS['recaptcha_verify_server'] = 'api-verify.recaptcha.net';
class serendipity_event_recaptcha extends serendipity_event
{
var $error=null;
function introspect(&$propbag)
{
global $serendipity;
$this->title = PLUGIN_EVENT_RECAPTCHA_TITLE;
$propbag->add('name', PLUGIN_EVENT_RECAPTCHA_TITLE);
$propbag->add('description', PLUGIN_EVENT_RECAPTCHA_DESC);
$propbag->add('stackable', false);
$propbag->add('author', 'Christian Brabandt (based on work of Garvin Hicking, Sebastian Nohn)');
$propbag->add('requirements', array(
'serendipity' => '1.0',
'smarty' => '2.6.7',
'php' => '4.1.0'
));
$propbag->add('version', '0.11');
$propbag->add('event_hooks', array(
'frontend_configure' => true,
'frontend_saveComment' => true,
'frontend_comment' => true
));
$propbag->add('configuration', array(
'info',
'sep',
'hide_for_authors',
'recaptcha',
'recaptcha_style',
'recaptcha_pub',
'recaptcha_priv',
'captchas_ttl',
'logtype',
'logfile'));
$propbag->add('groups', array('ANTISPAM'));
}
function introspect_config_item($name, &$propbag)
{
global $serendipity;
switch($name) {
case 'recaptcha':
$propbag->add('type', 'radio');
$propbag->add('name', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA);
$propbag->add('description', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_DESC);
$propbag->add('default', 'no');
$propbag->add('radio', array(
'value' => array('yes', 'no'),
'desc' => array(YES, NO)
));
break;
case 'recaptcha_pub':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_PUB);
$propbag->add('description', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_PUB_DESC);
$propbag->add('default', '');
break;
case 'recaptcha_priv':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_PRIV);
$propbag->add('description', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_PRIV_DESC);
$propbag->add('default', '');
break;
case 'recaptcha_style':
$propbag->add('type', 'radio');
$propbag->add('name', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_STYLE);
$propbag->add('description', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_STYLE_DESC);
$propbag->add('default', 'red');
$propbag->add('radio', array(
'value' => array('red', 'white', 'blackglass'),
'desc' => array('Red', 'White', 'Blackglass')
));
break;
case 'hide_for_authors':
$_groups =& serendipity_getAllGroups();
$groups = array(
'all' => ALL_AUTHORS,
'none' => NONE
);
foreach($_groups AS $group) {
$groups[$group['confkey']] = $group['confvalue'];
}
$propbag->add('type', 'multiselect');
$propbag->add('name', PLUGIN_EVENT_RECAPTCHA_HIDE);
$propbag->add('description', PLUGIN_EVENT_RECAPTCHA_HIDE_DESC);
$propbag->add('select_values', $groups);
$propbag->add('select_size', 5);
$propbag->add('default', 'all');
break;
case 'logfile':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_EVENT_RECAPTCHA_LOGFILE);
$propbag->add('description', PLUGIN_EVENT_RECAPTCHA_LOGFILE_DESC);
$propbag->add('default', $serendipity['serendipityPath'] . 'spamblock.log');
break;
case 'logtype':
$propbag->add('type', 'radio');
$propbag->add('name', PLUGIN_EVENT_RECAPTCHA_LOGTYPE);
$propbag->add('description', PLUGIN_EVENT_RECAPTCHA_LOGTYPE_DESC);
$propbag->add('default', 'db');
$propbag->add('radio', array(
'value' => array('file', 'db', 'none'),
'desc' => array(PLUGIN_EVENT_RECAPTCHA_LOGTYPE_FILE, PLUGIN_EVENT_RECAPTCHA_LOGTYPE_DB, PLUGIN_EVENT_RECAPTCHA_LOGTYPE_NONE)
));
$propbag->add('radio_per_row', '1');
break;
case 'captchas_ttl':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_EVENT_RECAPTCHA_CAPTCHAS_TTL);
$propbag->add('description', PLUGIN_EVENT_RECAPTCHA_CAPTCHAS_TTL_DESC);
$propbag->add('default', '7');
break;
case 'info':
$suche='!http(?:s)?:\/\/(?:(?:[^.]*)\.)?([^.\/]*)!';
$result=preg_match($suche,$serendipity['baseURL'],$domain);
$propbag->add('type', 'content');
$propbag->add('default', PLUGIN_EVENT_RECAPTCHA_INFO1.$domain[1]. PLUGIN_EVENT_RECAPTCHA_INFO2);
break;
case 'sep':
$propbag->add('type', 'seperator');
break;
default:
return false;
}
return true;
}
function generate_content(&$title) {
$title = $this->title;
}
// Checks whether the current author is contained in one of the groups that
// need no spam checking
function inGroup() {
global $serendipity;
$checkgroups = explode('^', $this->get_config('hide_for_authors'));
if (!isset($serendipity['authorid']) || !is_array($checkgroups)) {
return false;
}
$mygroups =& serendipity_getGroups($serendipity['authorid'], true);
if (!is_array($mygroups)) {
return false;
}
foreach($checkgroups AS $key => $groupid) {
if ($groupid == 'all') {
return true;
} elseif (in_array($groupid, $mygroups)) {
return true;
}
}
return false;
}
function event_hook($event, &$bag, &$eventData, $addData = null) {
global $serendipity;
$hooks = &$bag->get('event_hooks');
if (isset($hooks[$event])) {
$captchas_ttl = $this->get_config('captchas_ttl', 7);
$_recaptcha = $this->get_config('recaptcha', 'no');
$recaptcha = ($_recaptcha ==='yes' || $_recaptcha !== 'no' || serendipity_db_bool($_recaptcha));
// Check if the entry is older than the allowed amount of time.
// Enforce captchas if that is true of if captchas are activated
// for every entry
$show_captcha = (($recaptcha) && isset($eventData['timestamp']) && ($captchas_ttl < 1 || ($eventData['timestamp'] < (time() - ($captchas_ttl*60*60*24)))) ? true : false);
switch($event) {
case 'frontend_configure':
// set a variable, so that the spamblock plugin can disable the captcha when recaptcha is found.
if ($_recaptcha) {
$serendipity['plugins']['disable_internal_captcha'] = true;
}
return true;
break;
case 'frontend_saveComment':
if (!is_array($eventData) || serendipity_db_bool($eventData['allow_comments'])) {
//$serendipity['csuccess'] = 'true';
$logfile = $this->logfile = $this->get_config('logfile', $serendipity['serendipityPath'] . 'spamblock.log');
// Check whether to allow comments from registered authors
if (serendipity_userLoggedIn() && $this->inGroup()) {
return true;
}
// Captcha checking
if ($show_captcha && $addData['type'] == 'NORMAL') {
$privatekey = $this->get_config('recaptcha_priv');
if ($_POST["recaptcha_response_field"] != 1) {
$resp = recaptcha_check_answer($privatekey,
$_SERVER["REMOTE_ADDR"],
$_POST["recaptcha_challenge_field"],
$_POST["recaptcha_response_field"]);
if (!$resp->is_valid) {
# set the error code so that we can display it
$this->error = $resp->error;
$this->log($logfile, $eventData['id'], 'REJECTED', $this->error, $addData);
$eventData = array('allow_comments' => false);
$serendipity['messagestack']['comments'][] = PLUGIN_EVENT_RECAPTCHA_ERROR_CAPTCHAS;
return false;
}
} else {
return false;
}
}
}
return true;
break;
case 'frontend_comment':
// Check whether to allow comments from registered authors
if (serendipity_userLoggedIn() && $this->inGroup()) {
return true;
}
if ($show_captcha) {
$pubkey = $this->get_config('recaptcha_pub');
$privkey = $this->get_config('recaptcha_priv');
if ( $recaptcha && (($pubkey == null || $pubkey == '') || ($privkey == null || $pubkey == '')) ) {
$recaptcha = false;
//$captchas = true;
printf('<div class="serendipity_center serendipity_msg_important">%s</div>',PLUGIN_EVENT_RECAPTCHA_ERROR_RECAPTCHA);
}
// The response from recaptcha.net
$resp = null;
$theme = $this->get_config('recaptcha_style', 'red');
echo "\n<script type=\"text/javascript\">\n var RecaptchaOptions = { theme : '".$theme."', lang : '" . $serendipity['lang'] . "' };\n</script>";
$use_ssl = false;
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
$use_ssl = true;
}
echo recaptcha_get_html($pubkey, $this->error, $use_ssl);
}
return true;
break;
default:
return false;
break;
}
} else {
return false;
}
}
function log($logfile, $id, $switch, $reason, $comment) {
global $serendipity;
$method = $this->get_config('logtype');
switch($method) {
case 'file':
if (empty($logfile)) {
return;
}
$fp = @fopen($logfile, 'a+');
if (!is_resource($fp)) {
return;
}
fwrite($fp, sprintf(
'[%s] - [%s: %s] - [#%s, Name "%s", E-Mail "%s", URL "%s", User-Agent "%s", IP %s] - [%s]' . "\n",
date('Y-m-d H:i:s', serendipity_serverOffsetHour()),
$switch,
$reason,
$id,
str_replace("\n", ' ', $comment['name']),
str_replace("\n", ' ', $comment['email']),
str_replace("\n", ' ', $comment['url']),
str_replace("\n", ' ', $_SERVER['HTTP_USER_AGENT']),
$_SERVER['REMOTE_ADDR'],
str_replace("\n", ' ', $comment['comment'])
));
fclose($fp);
break;
case 'none':
return;
break;
case 'db':
default:
$q = sprintf("INSERT INTO {$serendipity['dbPrefix']}spamblocklog
(timestamp, type, reason, entry_id, author, email, url, useragent, ip, referer, body)
VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')",
serendipity_serverOffsetHour(),
serendipity_db_escape_string($switch),
serendipity_db_escape_string($reason),
serendipity_db_escape_string($id),
serendipity_db_escape_string($comment['name']),
serendipity_db_escape_string($comment['email']),
serendipity_db_escape_string($comment['url']),
serendipity_db_escape_string($_SERVER['HTTP_USER_AGENT']),
serendipity_db_escape_string($_SERVER['REMOTE_ADDR']),
serendipity_db_escape_string(isset($_SESSION['HTTP_REFERER']) ? $_SESSION['HTTP_REFERER'] : $_SERVER['HTTP_REFERER']),
serendipity_db_escape_string($comment['comment'])
);
serendipity_db_query($q);
break;
}
}
}
/* vim: set sts=4 ts=4 expandtab : */