| [ Index ] |
PHP Cross Reference of MyBB 1.8.40 |
[Summary view] [Print] [Text view]
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 * 9 = CF Turnstile 48 * 49 * @var int 50 */ 51 public $type = 0; 52 53 /** 54 * CAPTCHA constants declaration 55 * 56 * @var int 57 */ 58 const DEFAULT_CAPTCHA = 1; 59 const NOCAPTCHA_RECAPTCHA = 4; 60 const RECAPTCHA_INVISIBLE = 5; 61 const HCAPTCHA = 6; 62 const HCAPTCHA_INVISIBLE = 7; 63 const RECAPTCHA_V3 = 8; 64 const CFTURNSTILE = 9; 65 66 /** 67 * The template to display the CAPTCHA in 68 * 69 * @var string 70 */ 71 public $captcha_template = ''; 72 73 /** 74 * CAPTCHA Server URL 75 * 76 * @var string 77 */ 78 public $server = ''; 79 80 /** 81 * CAPTCHA Verify Server 82 * 83 * @var string 84 */ 85 public $verify_server = ''; 86 87 /** 88 * HTML of the built CAPTCHA 89 * 90 * @var string 91 */ 92 public $html = ''; 93 94 /** 95 * The errors that occurred when handling data. 96 * 97 * @var array 98 */ 99 public $errors = array(); 100 101 /** 102 * @param bool $build 103 * @param string $template 104 */ 105 function __construct($build = false, $template = "") 106 { 107 global $mybb, $plugins; 108 109 $this->type = (int)$mybb->settings['captchaimage']; 110 111 $args = array( 112 'this' => &$this, 113 'build' => &$build, 114 'template' => &$template, 115 ); 116 117 $plugins->run_hooks('captcha_build_start', $args); 118 119 // Prepare the build template 120 if($template) 121 { 122 $this->captcha_template = $template; 123 124 if($this->type == captcha::NOCAPTCHA_RECAPTCHA) 125 { 126 $this->captcha_template .= "_nocaptcha"; 127 } 128 elseif($this->type == captcha::RECAPTCHA_INVISIBLE) 129 { 130 $this->captcha_template .= "_recaptcha_invisible"; 131 } 132 elseif($this->type == captcha::HCAPTCHA) 133 { 134 $this->captcha_template .= "_hcaptcha"; 135 } 136 elseif($this->type == captcha::HCAPTCHA_INVISIBLE) 137 { 138 $this->captcha_template .= "_hcaptcha_invisible"; 139 } 140 elseif($this->type == captcha::RECAPTCHA_V3) 141 { 142 $this->captcha_template .= "_recaptcha_invisible"; 143 } 144 elseif($this->type == captcha::CFTURNSTILE) 145 { 146 $this->captcha_template .= "_cfturnstile"; 147 } 148 } 149 150 // Work on which CAPTCHA we've got installed 151 if(in_array($this->type, array(captcha::NOCAPTCHA_RECAPTCHA, captcha::RECAPTCHA_INVISIBLE, captcha::RECAPTCHA_V3)) && $mybb->settings['recaptchapublickey'] && $mybb->settings['recaptchaprivatekey']) 152 { 153 // We want to use noCAPTCHA or reCAPTCHA invisible, set the server options 154 $this->server = "//www.google.com/recaptcha/api.js"; 155 $this->verify_server = "https://www.google.com/recaptcha/api/siteverify"; 156 157 if($build == true) 158 { 159 $this->build_recaptcha(); 160 } 161 } 162 elseif(in_array($this->type, array(captcha::HCAPTCHA, captcha::HCAPTCHA_INVISIBLE)) && $mybb->settings['hcaptchapublickey'] && $mybb->settings['hcaptchaprivatekey']) 163 { 164 // We want to use hCaptcha or hCaptcha invisible, set the server options 165 $this->server = "//js.hcaptcha.com/1/api.js"; 166 $this->verify_server = "https://hcaptcha.com/siteverify"; 167 168 if($build == true) 169 { 170 $this->build_hcaptcha(); 171 } 172 } 173 elseif($this->type == captcha::CFTURNSTILE && $mybb->settings['cfturnstilepublickey'] && $mybb->settings['cfturnstileprivatekey']) 174 { 175 // JS and backend server validation 176 $this->server = "//challenges.cloudflare.com/turnstile/v0/api.js"; 177 $this->verify_server = "https://challenges.cloudflare.com/turnstile/v0/siteverify"; 178 179 if($build == true) 180 { 181 $this->build_cfturnstile(); 182 } 183 } 184 elseif($this->type == captcha::DEFAULT_CAPTCHA) 185 { 186 if(!function_exists("imagecreatefrompng")) 187 { 188 // We want to use the default CAPTCHA, but it's not installed 189 return; 190 } 191 elseif($build == true) 192 { 193 $this->build_captcha(); 194 } 195 } 196 197 $plugins->run_hooks('captcha_build_end', $args); 198 } 199 200 /** 201 * @param bool $return Not used 202 */ 203 function build_captcha($return = false) 204 { 205 global $db, $lang, $templates, $theme, $mybb; 206 207 // This will build a MyBB CAPTCHA 208 $randomstr = random_str(5); 209 $imagehash = md5(random_str(12)); 210 211 $insert_array = array( 212 "imagehash" => $imagehash, 213 "imagestring" => $randomstr, 214 "dateline" => TIME_NOW 215 ); 216 217 $db->insert_query("captcha", $insert_array); 218 eval("\$this->html = \"".$templates->get($this->captcha_template)."\";"); 219 //eval("\$this->html = \"".$templates->get("member_register_regimage")."\";"); 220 } 221 222 function build_recaptcha() 223 { 224 global $lang, $mybb, $templates; 225 226 // This will build a reCAPTCHA 227 $server = $this->server; 228 $public_key = $mybb->settings['recaptchapublickey']; 229 230 eval("\$this->html = \"".$templates->get($this->captcha_template, 1, 0)."\";"); 231 //eval("\$this->html = \"".$templates->get("member_register_regimage_recaptcha")."\";"); 232 } 233 234 function build_hcaptcha() 235 { 236 global $lang, $mybb, $templates, $theme; 237 238 // This will build a hCaptcha 239 $server = $this->server; 240 $public_key = $mybb->settings['hcaptchapublickey']; 241 $captcha_theme = $mybb->settings['hcaptchatheme']; 242 $captcha_size = $mybb->settings['hcaptchasize']; 243 244 eval("\$this->html = \"".$templates->get($this->captcha_template, 1, 0)."\";"); 245 } 246 247 function build_cfturnstile() 248 { 249 global $lang, $mybb, $templates, $theme; 250 251 // This will build a hCaptcha 252 $server = $this->server; 253 $public_key = $mybb->settings['cfturnstilepublickey']; 254 $captcha_theme = $mybb->settings['cfturnstiletheme']; 255 $captcha_size = $mybb->settings['cfturnstilesize']; 256 257 eval("\$this->html = \"".$templates->get($this->captcha_template, 1, 0)."\";"); 258 } 259 260 /** 261 * @return string 262 */ 263 function build_hidden_captcha() 264 { 265 global $db, $mybb, $templates; 266 267 $field = array(); 268 269 if($this->type == captcha::DEFAULT_CAPTCHA) 270 { 271 // Names 272 $hash = "imagehash"; 273 $string = "imagestring"; 274 275 // Values 276 $field['hash'] = $db->escape_string($mybb->get_input('imagehash')); 277 $field['string'] = $db->escape_string($mybb->get_input('imagestring')); 278 } 279 elseif($this->type == 3) 280 { 281 // Are You a Human can't be built as a hidden captcha 282 return ''; 283 } 284 285 eval("\$this->html = \"".$templates->get("post_captcha_hidden")."\";"); 286 return $this->html; 287 } 288 289 /** 290 * @return bool 291 */ 292 function validate_captcha() 293 { 294 global $db, $lang, $mybb, $session, $plugins; 295 296 $plugins->run_hooks('captcha_validate_start', $this); 297 298 if($this->type == captcha::DEFAULT_CAPTCHA) 299 { 300 // We have a normal CAPTCHA to handle 301 $imagehash = $db->escape_string($mybb->get_input('imagehash')); 302 $imagestring = $db->escape_string(my_strtolower($mybb->get_input('imagestring'))); 303 304 switch($db->type) 305 { 306 case 'mysql': 307 case 'mysqli': 308 $field = 'imagestring'; 309 break; 310 default: 311 $field = 'LOWER(imagestring)'; 312 break; 313 } 314 315 $query = $db->simple_select("captcha", "*", "imagehash = '{$imagehash}' AND {$field} = '{$imagestring}'"); 316 $imgcheck = $db->fetch_array($query); 317 318 if(!$imgcheck) 319 { 320 $this->set_error($lang->invalid_captcha_verify); 321 $db->delete_query("captcha", "imagehash = '{$imagehash}'"); 322 } 323 } 324 elseif(in_array($this->type, array(captcha::NOCAPTCHA_RECAPTCHA, captcha::RECAPTCHA_INVISIBLE))) 325 { 326 $response = $mybb->get_input('g-recaptcha-response'); 327 if(!$response || strlen($response) == 0) 328 { 329 $this->set_error($lang->invalid_nocaptcha); 330 } 331 else 332 { 333 // We have a noCAPTCHA or reCAPTCHA invisible to handle 334 // Contact Google and see if our reCAPTCHA was successful 335 $response = fetch_remote_file($this->verify_server, array( 336 'secret' => $mybb->settings['recaptchaprivatekey'], 337 'remoteip' => $session->ipaddress, 338 'response' => $response 339 )); 340 341 if($response == false) 342 { 343 $this->set_error($lang->invalid_nocaptcha_transmit); 344 } 345 else 346 { 347 $answer = json_decode($response, true); 348 349 if($answer['success'] != 'true') 350 { 351 // We got it wrong! Oh no... 352 $this->set_error($lang->invalid_nocaptcha); 353 } 354 } 355 } 356 } 357 elseif($this->type == captcha::RECAPTCHA_V3) 358 { 359 $response = $mybb->get_input('g-recaptcha-response'); 360 if(!$response || strlen($response) == 0) 361 { 362 $this->set_error($lang->invalid_nocaptcha); 363 } 364 else 365 { 366 // We have a reCAPTCHA invisible to handle 367 // Contact Google and see if our reCAPTCHA was successful 368 $response = fetch_remote_file($this->verify_server, array( 369 'secret' => $mybb->settings['recaptchaprivatekey'], 370 'score' => $mybb->settings['recaptchascore'], 371 'remoteip' => $session->ipaddress, 372 'response' => $response 373 )); 374 375 if($response === false) 376 { 377 $this->set_error($lang->invalid_nocaptcha_transmit); 378 } 379 else 380 { 381 $answer = json_decode($response, true); 382 383 if($answer['success'] != 'true' || $answer['score'] < $mybb->settings['recaptchascore']) 384 { 385 // We got it wrong! Oh no... 386 $this->set_error($lang->invalid_nocaptcha); 387 } 388 } 389 } 390 } 391 elseif(in_array($this->type, array(captcha::HCAPTCHA, captcha::HCAPTCHA_INVISIBLE))) 392 { 393 $response = $mybb->get_input('h-captcha-response'); 394 if(!$response || strlen($response) == 0) 395 { 396 $this->set_error($lang->invalid_hcaptcha); 397 } 398 else 399 { 400 // We have an hCaptcha or hCaptcha invisible to handle 401 // Contact hCaptcha and see if our hCaptcha was successful 402 $response = fetch_remote_file($this->verify_server, array( 403 'secret' => $mybb->settings['hcaptchaprivatekey'], 404 'remoteip' => $session->ipaddress, 405 'response' => $response 406 )); 407 408 if($response == false) 409 { 410 $this->set_error($lang->invalid_hcaptcha_transmit); 411 } 412 else 413 { 414 $answer = json_decode($response, true); 415 if($answer['success'] != 'true') 416 { 417 // We got it wrong! Oh no... 418 $this->set_error($lang->invalid_hcaptcha); 419 } 420 } 421 } 422 } 423 elseif($this->type === self::CFTURNSTILE) 424 { 425 $response = $mybb->get_input('cf-turnstile-response'); 426 if(!$response || strlen($response) == 0) 427 { 428 $this->set_error($lang->invalid_cfturnstile); 429 } 430 else 431 { 432 // Contact CF-Turnstile and see if our CF-Turnstile request was successful 433 $response = fetch_remote_file($this->verify_server, array( 434 'secret' => $mybb->settings['cfturnstileprivatekey'], 435 'remoteip' => $session->ipaddress, 436 'response' => $response 437 )); 438 439 if($response == false) 440 { 441 $this->set_error($lang->invalid_cfturnstile_transmit); 442 } 443 else 444 { 445 $answer = json_decode($response, true); 446 if($answer['success'] != 'true') 447 { 448 // We got it wrong! Oh no... 449 $this->set_error($lang->invalid_cfturnstile); 450 } 451 } 452 } 453 } 454 455 $plugins->run_hooks('captcha_validate_end', $this); 456 457 if(count($this->errors) > 0) 458 { 459 return false; 460 } 461 else 462 { 463 return true; 464 } 465 } 466 467 function invalidate_captcha() 468 { 469 global $db, $mybb, $plugins; 470 471 if($this->type == captcha::DEFAULT_CAPTCHA) 472 { 473 // We have a normal CAPTCHA to handle 474 $imagehash = $db->escape_string($mybb->get_input('imagehash')); 475 if($imagehash) 476 { 477 $db->delete_query("captcha", "imagehash = '{$imagehash}'"); 478 } 479 } 480 // Not necessary for reCAPTCHA or Are You a Human 481 482 $plugins->run_hooks('captcha_invalidate_end', $this); 483 } 484 485 /** 486 * Add an error to the error array. 487 * 488 * @param string $error 489 * @param string $data 490 */ 491 function set_error($error, $data='') 492 { 493 $this->errors[$error] = array( 494 "error_code" => $error, 495 "data" => $data 496 ); 497 } 498 499 /** 500 * Returns the error(s) that occurred when handling data 501 * in a format that MyBB can handle. 502 * 503 * @return array An array of errors in a MyBB format. 504 */ 505 function get_errors() 506 { 507 global $lang; 508 509 $errors = array(); 510 foreach($this->errors as $error) 511 { 512 $lang_string = $error['error_code']; 513 514 if(!$lang_string) 515 { 516 if($lang->invalid_captcha_verify) 517 { 518 $lang_string = 'invalid_captcha_verify'; 519 } 520 else 521 { 522 $lang_string = 'unknown_error'; 523 } 524 } 525 526 if(!isset($lang->$lang_string)) 527 { 528 $errors[] = $error['error_code']; 529 continue; 530 } 531 532 if(!empty($error['data']) && !is_array($error['data'])) 533 { 534 $error['data'] = array($error['data']); 535 } 536 537 if(is_array($error['data'])) 538 { 539 array_unshift($error['data'], $lang->$lang_string); 540 $errors[] = call_user_func_array(array($lang, "sprintf"), $error['data']); 541 } 542 else 543 { 544 $errors[] = $lang->$lang_string; 545 } 546 } 547 548 return $errors; 549 } 550 551 /** 552 * @param array $data 553 * 554 * @return string 555 */ 556 private function _qsencode($data) 557 { 558 $req = ''; 559 foreach($data as $key => $value) 560 { 561 $req .= $key.'='.urlencode(stripslashes($value)).'&'; 562 } 563 564 $req = substr($req, 0, (strlen($req) - 1)); 565 566 return $req; 567 } 568 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| 2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup | Cross-referenced by PHPXref |