PHP Code:
<?php
if (!isset($GLOBALS['vbulletin']->db))
{
exit;
}
require_once(DIR . '/includes/class_vurl.php');
class vB_HumanVerify_New_Recaptcha extends vB_HumanVerify_Abstract
{
public static $verify_url = 'https://www.google.com/recaptcha/api/siteverify';
/**
* Constructor
*
* @return void
*/
function __construct(&$registry)
{
parent::__construct($registry);
}
private static function get_error_phrase($result)
{
if (isset($result['error-codes']))
$errormsg = current($result['error-codes']);
else
$errormsg = '';
switch ($errormsg)
{
case 'missing-input-secret':
case 'invalid-input-secret':
$error = 'humanverify_new_recaptcha_secret';
break;
case 'missing-input-response':
$error = 'humanverify_new_recaptcha_noanswer';
break;
case 'invalid-input-response':
default:
$error = 'humanverify_new_recaptcha_wronganswer';
}
return $error;
}
function verify_token($input)
{
$this->registry->input->clean_array_gpc('p', array(
'g-recaptcha-response' => TYPE_STR,
));
if ($this->delete_token($input['hash']) AND isset($this->registry->GPC['g-recaptcha-response']) AND
$this->registry->GPC['g-recaptcha-response'] !== '')
{
$secret = urlencode($this->registry->options['hv_new_recaptcha_privatekey']);
$remoteip = urlencode(IPADDRESS);
$response = urlencode($this->registry->GPC['g-recaptcha-response']);
$vurl = new vB_vURL($this->registry);
$vurl->set_option(VURL_URL, self::$verify_url."?secret=$secret&remoteip=$remoteip&response=$response");
$vurl->set_option(VURL_USERAGENT, 'vBulletin ' . FILE_VERSION);
$vurl->set_option(VURL_RETURNTRANSFER, 1);
$vurl->set_option(VURL_CLOSECONNECTION, 1);
if (($result = $vurl->exec()) === false || ($result = json_decode($result, true)) === NULL)
{
$this->error = 'humanverify_new_recaptcha_unreachable';
return false;
}
else
{
if ($result['success'] === true)
{
return true;
}
$this->error = self::get_error_phrase($result);
return false;
}
}
else
{
$this->error = 'humanverify_new_recaptcha_wronganswer';
return false;
}
}
function output_token($var_prefix = 'humanverify')
{
global $vbphrase, $show;
$vbulletin =& $this->registry;
$humanverify = $this->generate_token();
$humanverify['publickey'] = ($this->registry->options['hv_new_recaptcha_publickey'] ? $this->registry->options['hv_new_recaptcha_publickey'] : '');
$humanverify['theme'] = $this->registry->options['hv_new_recaptcha_theme'];
$humanverify['type'] = $this->registry->options['hv_new_recaptcha_type'];
if (preg_match('#^([a-z]{2})-?#i', vB_Template_Runtime::fetchStyleVar('languagecode'), $matches))
{
$humanverify['hl'] = strtolower($matches[1]);
}
$templater = vB_Template::create('humanverify_new_recaptcha');
$templater->register('humanverify', $humanverify);
$templater->register('var_prefix', $var_prefix);
$output = $templater->render();
return $output;
}
function fetch_answer()
{
return '';
}
public static function test_check_config()
{
global $vbulletin;
$output = array();
if (!is_string($vbulletin->options['hv_new_recaptcha_publickey']) || $vbulletin->options['hv_new_recaptcha_publickey']=='')
$output[] = array(1, 'Site key is not set.');
else
$output[] = array(0, 'Site key is set: '.$vbulletin->options['hv_new_recaptcha_publickey']);
if (!is_string($vbulletin->options['hv_new_recaptcha_privatekey']) || $vbulletin->options['hv_new_recaptcha_privatekey']=='')
$output[] = array(1, 'Secret key is not set.');
else
$output[] = array(0, 'Secret key is set: '.$vbulletin->options['hv_new_recaptcha_privatekey']);
if (!function_exists('curl_init'))
$output[] = array(1, 'cURL must be enabled, and any curl_ functions must be removed from disable_functions in php.ini');
else
{
$output[] = array(0, 'cURL is enabled');
$curlinfo = curl_version();
if (empty($curlinfo['ssl_version']))
$output[] = array(1, 'cURL does not have ssl enabled');
else
{
$o = array("cURL version info:");
foreach ($curlinfo AS $key=>$value)
{
if ($key == 'features')
$value = '0x'.dechex($value);
if ($key == 'protocols')
$value = implode(', ',$value);
$o[] = $key.': '.$value;
}
$output[] = array(0, $o);
}
if (($ch = curl_init()) === false)
$output[] = array(1, 'curl_init failed');
else
curl_close($ch);
if (!function_exists('curl_exec'))
$output[] = array(1, 'Function curl_exec is disabled. curl_exec must be removed from disable_functions in php.ini.');
else
$output[] = array(0, 'curl_exec function is not disabled');
}
return $output;
}
public static function test_display_widget()
{
global $vbulletin;
return '<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="'.$vbulletin->options['hv_new_recaptcha_publickey'].'"></div>';
}
public static function test_verify()
{
global $vbulletin, $vbphrase;
$output = array();
$vbulletin->input->clean_array_gpc('p', array(
'g-recaptcha-response' => TYPE_STR,
));
if (!isset($vbulletin->GPC['g-recaptcha-response']) || $vbulletin->GPC['g-recaptcha-response'] == '')
$output[] = array(1, 'g-recaptcha-response is not set. Complete the human verification challenge before pressing Submit.');
else
{
$output[] = array(0, 'g-recaptcha-response: ' . fetch_trimmed_title($vbulletin->GPC['g-recaptcha-response'], 50));
$secret = urlencode($vbulletin->options['hv_new_recaptcha_privatekey']);
$remoteip = urlencode(IPADDRESS);
$response = urlencode($vbulletin->GPC['g-recaptcha-response']);
$url = self::$verify_url."?secret=$secret&remoteip=$remoteip&response=$response";
$output[] = array(0, "verify url: '".fetch_trimmed_title($url,160)."'");
if (($ch = curl_init()) !== false)
{
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array());
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$result = curl_exec($ch);
if ($result === false AND curl_errno($ch) == '60')
{
$output[] = array(0, "Error 60, retrying with CAINFO");
curl_setopt($ch, CURLOPT_CAINFO, DIR . '/includes/paymentapi/ca-bundle.crt');
$result = curl_exec($ch);
}
$info = curl_getinfo($ch);
if ($result === false)
$output[] = array(1, "curl_exec returned false: ".curl_error($ch));
else
{
if ($info['http_code'] != 200)
$output[] = array(1, "Http response code " . $info['http_code']);
$o = array("cURL transfer info:");
foreach ($info AS $key=>$value)
{
$o[] = $key.': '.$value;
}
$output[] = array($info['http_code'] != 200, $o);
if ($info['http_code'] == 200)
{
$output[] = array(0, "Raw response: ".htmlspecialchars($result));
if (($result = json_decode($result, true)) === NULL)
$output[] = array(1, "json_decode of response failed");
else
{
$o = array("Decoded response:");
foreach ($result AS $key=>$value)
{
if ($key == 'success')
$value = ($value ? 'true' : 'false');
if ($key == 'error-codes')
$value = implode(',', $value);
$o[] = $key.': '.$value;
}
$output[] = array($result['success'] ? 0 : 1, $o);
if ($result['success'] !== true)
{
$error = self::get_error_phrase($result);
require_once(DIR.'/includes/functions_misc.php');
$output[] = array(1, "Error Phrase: ".fetch_phrase($error, 'error'));
}
}
}
else
$output[] = array(1, "Http Response: ".htmlspecialchars($result));
}
curl_close($ch);
}
else
$output[] = array(1, "curl_init() failed.");
}
return $output;
}
}
?>