[ Index ]

PHP Cross Reference of MyBB 1.8.37

title

Body

[close]

/inc/ -> class_captcha.php (source)

   1  <?php
   2  /**
   3   * MyBB 1.8
   4   * Copyright 2014 MyBB Group, All Rights Reserved
   5   *
   6   * Website: http://www.mybb.com
   7   * License: http://www.mybb.com/about/license
   8   *
   9   * This class is based from reCAPTCHA's PHP library, adapted for use in MyBB.
  10   *
  11   * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
  12   * AUTHORS:
  13   *   Mike Crawford
  14   *   Ben Maurer
  15   *
  16   * Permission is hereby granted, free of charge, to any person obtaining a copy
  17   * of this software and associated documentation files (the "Software"), to deal
  18   * in the Software without restriction, including without limitation the rights
  19   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  20   * copies of the Software, and to permit persons to whom the Software is
  21   * furnished to do so, subject to the following conditions:
  22   *
  23   * The above copyright notice and this permission notice shall be included in
  24   * all copies or substantial portions of the Software.
  25   *
  26   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  27   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  28   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  29   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  30   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  31   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  32   * THE SOFTWARE.
  33   *
  34   */
  35  
  36  class captcha
  37  {
  38      /**
  39       * Type of CAPTCHA.
  40       *
  41       * 1 = Default CAPTCHA
  42       * 4 = NoCATPCHA reCAPTCHA
  43       * 5 = reCAPTCHA invisible
  44       * 6 = hCaptcha
  45       * 7 = hCaptcha invisible
  46       * 8 = reCAPTCHA v3
  47       *
  48       * @var int
  49       */
  50      public $type = 0;
  51  
  52      /**
  53       * CAPTCHA constants declaration
  54       * 
  55       * @var int
  56       */
  57      const DEFAULT_CAPTCHA = 1;
  58      const NOCAPTCHA_RECAPTCHA = 4;
  59      const RECAPTCHA_INVISIBLE = 5;
  60      const HCAPTCHA = 6;
  61      const HCAPTCHA_INVISIBLE = 7;
  62      const RECAPTCHA_V3 = 8;
  63  
  64      /**
  65       * The template to display the CAPTCHA in
  66       *
  67       * @var string
  68       */
  69       public $captcha_template = '';
  70  
  71      /**
  72       * CAPTCHA Server URL
  73       *
  74       * @var string
  75       */
  76      public $server = '';
  77  
  78      /**
  79       * CAPTCHA Verify Server
  80       *
  81       * @var string
  82       */
  83      public $verify_server = '';
  84  
  85      /**
  86       * HTML of the built CAPTCHA
  87       *
  88       * @var string
  89       */
  90      public $html = '';
  91  
  92      /**
  93       * The errors that occurred when handling data.
  94       *
  95       * @var array
  96       */
  97      public $errors = array();
  98  
  99      /**
 100       * @param bool   $build
 101       * @param string $template
 102       */
 103  	function __construct($build = false, $template = "")
 104      {
 105          global $mybb, $plugins;
 106  
 107          $this->type = $mybb->settings['captchaimage'];
 108  
 109          $args = array(
 110              'this' => &$this,
 111              'build' => &$build,
 112              'template' => &$template,
 113          );
 114  
 115          $plugins->run_hooks('captcha_build_start', $args);
 116  
 117          // Prepare the build template
 118          if($template)
 119          {
 120              $this->captcha_template = $template;
 121  
 122              if($this->type == captcha::NOCAPTCHA_RECAPTCHA)
 123              {
 124                  $this->captcha_template .= "_nocaptcha";
 125              }
 126              elseif($this->type == captcha::RECAPTCHA_INVISIBLE)
 127              {
 128                  $this->captcha_template .= "_recaptcha_invisible";
 129              }
 130              elseif($this->type == captcha::HCAPTCHA)
 131              {
 132                  $this->captcha_template .= "_hcaptcha";
 133              }
 134              elseif($this->type == captcha::HCAPTCHA_INVISIBLE)
 135              {
 136                  $this->captcha_template .= "_hcaptcha_invisible";
 137              }
 138              elseif($this->type == captcha::RECAPTCHA_V3)
 139              {
 140                  $this->captcha_template .= "_recaptcha_invisible";
 141              }
 142          }
 143  
 144          // Work on which CAPTCHA we've got installed
 145          if(in_array($this->type, array(captcha::NOCAPTCHA_RECAPTCHA, captcha::RECAPTCHA_INVISIBLE, captcha::RECAPTCHA_V3)) && $mybb->settings['recaptchapublickey'] && $mybb->settings['recaptchaprivatekey'])
 146          {
 147              // We want to use noCAPTCHA or reCAPTCHA invisible, set the server options
 148              $this->server = "//www.google.com/recaptcha/api.js";
 149              $this->verify_server = "https://www.google.com/recaptcha/api/siteverify";
 150  
 151              if($build == true)
 152              {
 153                  $this->build_recaptcha();
 154              }
 155          }
 156          elseif(in_array($this->type, array(captcha::HCAPTCHA, captcha::HCAPTCHA_INVISIBLE)) && $mybb->settings['hcaptchapublickey'] && $mybb->settings['hcaptchaprivatekey'])
 157          {
 158              // We want to use hCaptcha or hCaptcha invisible, set the server options
 159              $this->server = "//js.hcaptcha.com/1/api.js";
 160              $this->verify_server = "https://hcaptcha.com/siteverify";
 161  
 162              if($build == true)
 163              {
 164                  $this->build_hcaptcha();
 165              }
 166          }
 167          elseif($this->type == captcha::DEFAULT_CAPTCHA)
 168          {
 169              if(!function_exists("imagecreatefrompng"))
 170              {
 171                  // We want to use the default CAPTCHA, but it's not installed
 172                  return;
 173              }
 174              elseif($build == true)
 175              {
 176                  $this->build_captcha();
 177              }
 178          }
 179  
 180          $plugins->run_hooks('captcha_build_end', $args);
 181      }
 182  
 183      /**
 184       * @param bool $return Not used
 185       */
 186  	function build_captcha($return = false)
 187      {
 188          global $db, $lang, $templates, $theme, $mybb;
 189  
 190          // This will build a MyBB CAPTCHA
 191          $randomstr = random_str(5);
 192          $imagehash = md5(random_str(12));
 193  
 194          $insert_array = array(
 195              "imagehash" => $imagehash,
 196              "imagestring" => $randomstr,
 197              "dateline" => TIME_NOW
 198          );
 199  
 200          $db->insert_query("captcha", $insert_array);
 201          eval("\$this->html = \"".$templates->get($this->captcha_template)."\";");
 202          //eval("\$this->html = \"".$templates->get("member_register_regimage")."\";");
 203      }
 204  
 205  	function build_recaptcha()
 206      {
 207          global $lang, $mybb, $templates;
 208  
 209          // This will build a reCAPTCHA
 210          $server = $this->server;
 211          $public_key = $mybb->settings['recaptchapublickey'];
 212  
 213          eval("\$this->html = \"".$templates->get($this->captcha_template, 1, 0)."\";");
 214          //eval("\$this->html = \"".$templates->get("member_register_regimage_recaptcha")."\";");
 215      }
 216  
 217  	function build_hcaptcha()
 218      {
 219          global $lang, $mybb, $templates, $theme;
 220  
 221          // This will build a hCaptcha
 222          $server = $this->server;
 223          $public_key = $mybb->settings['hcaptchapublickey'];
 224          $captcha_theme = $mybb->settings['hcaptchatheme'];
 225          $captcha_size = $mybb->settings['hcaptchasize'];
 226          
 227          eval("\$this->html = \"".$templates->get($this->captcha_template, 1, 0)."\";");
 228      }
 229  
 230      /**
 231       * @return string
 232       */
 233  	function build_hidden_captcha()
 234      {
 235          global $db, $mybb, $templates;
 236  
 237          $field = array();
 238  
 239          if($this->type == captcha::DEFAULT_CAPTCHA)
 240          {
 241              // Names
 242              $hash = "imagehash";
 243              $string = "imagestring";
 244  
 245              // Values
 246              $field['hash'] = $db->escape_string($mybb->get_input('imagehash'));
 247              $field['string'] = $db->escape_string($mybb->get_input('imagestring'));
 248          }
 249          elseif($this->type == 3)
 250          {
 251              // Are You a Human can't be built as a hidden captcha
 252              return '';
 253          }
 254  
 255          eval("\$this->html = \"".$templates->get("post_captcha_hidden")."\";");
 256          return $this->html;
 257      }
 258  
 259      /**
 260       * @return bool
 261       */
 262  	function validate_captcha()
 263      {
 264          global $db, $lang, $mybb, $session, $plugins;
 265  
 266          $plugins->run_hooks('captcha_validate_start', $this);
 267  
 268          if($this->type == captcha::DEFAULT_CAPTCHA)
 269          {
 270              // We have a normal CAPTCHA to handle
 271              $imagehash = $db->escape_string($mybb->get_input('imagehash'));
 272              $imagestring = $db->escape_string(my_strtolower($mybb->get_input('imagestring')));
 273  
 274              switch($db->type)
 275              {
 276                  case 'mysql':
 277                  case 'mysqli':
 278                      $field = 'imagestring';
 279                      break;
 280                  default:
 281                      $field = 'LOWER(imagestring)';
 282                      break;
 283              }
 284  
 285              $query = $db->simple_select("captcha", "*", "imagehash = '{$imagehash}' AND {$field} = '{$imagestring}'");
 286              $imgcheck = $db->fetch_array($query);
 287  
 288              if(!$imgcheck)
 289              {
 290                  $this->set_error($lang->invalid_captcha_verify);
 291                  $db->delete_query("captcha", "imagehash = '{$imagehash}'");
 292              }
 293          }
 294          elseif(in_array($this->type, array(captcha::NOCAPTCHA_RECAPTCHA, captcha::RECAPTCHA_INVISIBLE)))
 295          {
 296              $response = $mybb->get_input('g-recaptcha-response');
 297              if(!$response || strlen($response) == 0)
 298              {
 299                  $this->set_error($lang->invalid_nocaptcha);
 300              }
 301              else
 302              {
 303                  // We have a noCAPTCHA or reCAPTCHA invisible to handle
 304                  // Contact Google and see if our reCAPTCHA was successful
 305                  $response = fetch_remote_file($this->verify_server, array(
 306                      'secret' => $mybb->settings['recaptchaprivatekey'],
 307                      'remoteip' => $session->ipaddress,
 308                      'response' => $response
 309                  ));
 310  
 311                  if($response == false)
 312                  {
 313                      $this->set_error($lang->invalid_nocaptcha_transmit);
 314                  }
 315                  else
 316                  {
 317                      $answer = json_decode($response, true);
 318  
 319                      if($answer['success'] != 'true')
 320                      {
 321                          // We got it wrong! Oh no...
 322                          $this->set_error($lang->invalid_nocaptcha);
 323                      }
 324                  }
 325              }
 326          }
 327          elseif($this->type == captcha::RECAPTCHA_V3)
 328          {
 329              $response = $mybb->get_input('g-recaptcha-response');
 330              if(!$response || strlen($response) == 0)
 331              {
 332                  $this->set_error($lang->invalid_nocaptcha);
 333              }
 334              else
 335              {
 336                  // We have a reCAPTCHA invisible to handle
 337                  // Contact Google and see if our reCAPTCHA was successful
 338                  $response = fetch_remote_file($this->verify_server, array(
 339                      'secret' => $mybb->settings['recaptchaprivatekey'],
 340                      'score' => $mybb->settings['recaptchascore'],
 341                      'remoteip' => $session->ipaddress,
 342                      'response' => $response
 343                  ));
 344  
 345                  if($response === false)
 346                  {
 347                      $this->set_error($lang->invalid_nocaptcha_transmit);
 348                  }
 349                  else
 350                  {
 351                      $answer = json_decode($response, true);
 352  
 353                      if($answer['success'] != 'true' || $answer['score'] < $mybb->settings['recaptchascore'])
 354                      {
 355                          // We got it wrong! Oh no...
 356                          $this->set_error($lang->invalid_nocaptcha);
 357                      }
 358                  }
 359              }
 360          }
 361          elseif(in_array($this->type, array(captcha::HCAPTCHA, captcha::HCAPTCHA_INVISIBLE)))
 362          {
 363              $response = $mybb->get_input('h-captcha-response');
 364              if(!$response || strlen($response) == 0)
 365              {
 366                  $this->set_error($lang->invalid_hcaptcha);
 367              }
 368              else
 369              {
 370                  // We have an hCaptcha or hCaptcha invisible to handle
 371                  // Contact hCaptcha and see if our hCaptcha was successful
 372                  $response = fetch_remote_file($this->verify_server, array(
 373                      'secret' => $mybb->settings['hcaptchaprivatekey'],
 374                      'remoteip' => $session->ipaddress,
 375                      'response' => $response
 376                  ));
 377  
 378                  if($response == false)
 379                  {
 380                      $this->set_error($lang->invalid_hcaptcha_transmit);
 381                  }
 382                  else
 383                  {
 384                      $answer = json_decode($response, true);
 385                      if($answer['success'] != 'true')
 386                      {
 387                          // We got it wrong! Oh no...
 388                          $this->set_error($lang->invalid_hcaptcha);
 389                      }
 390                  }
 391              }
 392          }
 393          $plugins->run_hooks('captcha_validate_end', $this);
 394  
 395          if(count($this->errors) > 0)
 396          {
 397              return false;
 398          }
 399          else
 400          {
 401              return true;
 402          }
 403      }
 404  
 405  	function invalidate_captcha()
 406      {
 407          global $db, $mybb, $plugins;
 408  
 409          if($this->type == captcha::DEFAULT_CAPTCHA)
 410          {
 411              // We have a normal CAPTCHA to handle
 412              $imagehash = $db->escape_string($mybb->get_input('imagehash'));
 413              if($imagehash)
 414              {
 415                  $db->delete_query("captcha", "imagehash = '{$imagehash}'");
 416              }
 417          }
 418          // Not necessary for reCAPTCHA or Are You a Human
 419  
 420          $plugins->run_hooks('captcha_invalidate_end', $this);
 421      }
 422  
 423      /**
 424       * Add an error to the error array.
 425       *
 426       * @param string $error
 427       * @param string $data
 428       */
 429  	function set_error($error, $data='')
 430      {
 431          $this->errors[$error] = array(
 432              "error_code" => $error,
 433              "data" => $data
 434          );
 435      }
 436  
 437      /**
 438       * Returns the error(s) that occurred when handling data
 439       * in a format that MyBB can handle.
 440       *
 441       * @return array An array of errors in a MyBB format.
 442       */
 443  	function get_errors()
 444      {
 445          global $lang;
 446  
 447          $errors = array();
 448          foreach($this->errors as $error)
 449          {
 450              $lang_string = $error['error_code'];
 451  
 452              if(!$lang_string)
 453              {
 454                  if($lang->invalid_captcha_verify)
 455                  {
 456                      $lang_string = 'invalid_captcha_verify';
 457                  }
 458                  else
 459                  {
 460                      $lang_string = 'unknown_error';
 461                  }
 462              }
 463  
 464              if(!isset($lang->$lang_string))
 465              {
 466                  $errors[] = $error['error_code'];
 467                  continue;
 468              }
 469  
 470              if(!empty($error['data']) && !is_array($error['data']))
 471              {
 472                  $error['data'] = array($error['data']);
 473              }
 474  
 475              if(is_array($error['data']))
 476              {
 477                  array_unshift($error['data'], $lang->$lang_string);
 478                  $errors[] = call_user_func_array(array($lang, "sprintf"), $error['data']);
 479              }
 480              else
 481              {
 482                  $errors[] = $lang->$lang_string;
 483              }
 484          }
 485  
 486          return $errors;
 487      }
 488  
 489      /**
 490       * @param array $data
 491       *
 492       * @return string
 493       */
 494  	private function _qsencode($data)
 495      {
 496          $req = '';
 497          foreach($data as $key => $value)
 498          {
 499              $req .= $key.'='.urlencode(stripslashes($value)).'&';
 500          }
 501  
 502          $req = substr($req, 0, (strlen($req) - 1));
 503  
 504          return $req;
 505      }
 506  }


2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup Cross-referenced by PHPXref