summaryrefslogtreecommitdiff
path: root/lib/captcha_gen.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/captcha_gen.php')
-rw-r--r--lib/captcha_gen.php325
1 files changed, 325 insertions, 0 deletions
diff --git a/lib/captcha_gen.php b/lib/captcha_gen.php
new file mode 100644
index 0000000..2ae824b
--- /dev/null
+++ b/lib/captcha_gen.php
@@ -0,0 +1,325 @@
+<?php
+
+class captcha{
+
+ public function __construct($frontend, $get, $filters, $page, $output){
+
+ /*
+ Validate cookie, if it exists
+ */
+ if(isset($_COOKIE["pass"])){
+
+ if(
+ // check if key is not malformed
+ preg_match(
+ '/^c[0-9]+\.[A-Za-z0-9]{20}$/',
+ $_COOKIE["pass"]
+ ) &&
+ // does key exist
+ apcu_exists($_COOKIE["pass"])
+ ){
+
+ // exists, increment counter
+ $inc = apcu_inc($_COOKIE["pass"]);
+
+ // we start counting from 1
+ // when it has been incremented to 102, it has reached
+ // 100 reqs
+ if($inc >= 102){
+
+ // reached limit, delete and give captcha
+ apcu_delete($_COOKIE["pass"]);
+ }else{
+
+ // the cookie is OK! dont die() and give results
+ if($output === true){
+ $frontend->loadheader(
+ $get,
+ $filters,
+ $page
+ );
+ }
+ return;
+ }
+ }
+ }
+
+ if($output === false){
+
+ echo json_encode([
+ "status" => "The \"pass\" token in your cookies is missing or has expired!!"
+ ]);
+ die();
+ }
+
+ /*
+ Validate form data
+ */
+ $lines =
+ explode(
+ "\r\n",
+ file_get_contents("php://input")
+ );
+
+ $invalid = false;
+ $answers = [];
+ $key = false;
+ $error = "";
+
+ foreach($lines as $line){
+
+ $line = explode("=", $line, 2);
+
+ if(count($line) !== 2){
+
+ $invalid = true;
+ break;
+ }
+
+ preg_match(
+ '/^c\[([0-9]+)\]$/',
+ $line[0],
+ $regex
+ );
+
+ if(
+ $line[1] != "on" ||
+ !isset($regex[0][1])
+ ){
+
+ // check if its k
+ if(
+ $line[0] == "k" &&
+ strpos($line[1], "c.") === 0
+ ){
+
+ $key = apcu_fetch($line[1]);
+ apcu_delete($line[1]);
+ }
+ break;
+ }
+
+ $regex = (int)$regex[1];
+
+ if(
+ $regex >= 16 ||
+ $regex <= -1
+ ){
+
+ $invalid = true;
+ break;
+ }
+
+ $answers[] = $regex;
+ }
+
+ if(
+ !$invalid &&
+ $key !== false
+ ){
+ $check = $key[1];
+
+ // validate answer
+ for($i=0; $i<count($key[0]); $i++){
+
+ if(!in_array($i, $answers)){
+
+ continue;
+ }
+
+ if($key[0][$i][0] == $key[2]){
+
+ $check--;
+ }else{
+
+ // got a wrong answer
+ $check = -1;
+ break;
+ }
+ }
+
+ if($check === 0){
+
+ // we passed the captcha
+ // set cookie
+ $inc = apcu_inc("cookie");
+ $chars =
+ array_merge(
+ range("A", "Z"),
+ range("a", "z"),
+ range(0, 9)
+ );
+
+ $c = count($chars) - 1;
+
+ $key = "c" . $inc . ".";
+
+ for($i=0; $i<20; $i++){
+
+ $key .= $chars[random_int(0, $c)];
+ }
+
+ apcu_inc($key, 1, $stupid, 86400);
+
+ setcookie(
+ "pass",
+ $key,
+ [
+ "expires" => time() + 86400, // expires in 24 hours
+ "samesite" => "Strict",
+ "path" => "/"
+ ]
+ );
+
+ $frontend->loadheader(
+ $get,
+ $filters,
+ $page
+ );
+ return;
+
+ }else{
+
+ $error = "<div class=\"quote\">You were <a href=\"https://www.youtube.com/watch?v=e1d7fkQx2rk\" target=\"_BLANK\" rel=\"noreferrer nofollow\">kicked out of Mensa.</a> Please try again.</div>";
+ }
+ }
+
+ /*
+ Generate random grid data to pass to captcha.php
+ */
+ $dataset = [
+ ["birds", 2263],
+ ["fumo_plushies", 1006],
+ ["minecraft", 848]
+ ];
+
+ // get the positions for the answers
+ // will return between 3 and 6 answer positions
+ $range = range(0, 15);
+ $answer_pos = [];
+
+ array_splice($range, 0, 1);
+
+ for($i=0; $i<random_int(3, 6); $i++){
+
+ $answer_pos_tmp =
+ array_splice(
+ $range,
+ random_int(
+ 0,
+ 14 - $i
+ ),
+ 1
+ );
+
+ $answer_pos[] = $answer_pos_tmp[0];
+ }
+
+ // choose a dataset
+ $choosen = &$dataset[random_int(0, count($dataset) - 1)];
+ $choices = [];
+
+ for($i=0; $i<count($dataset); $i++){
+
+ if($dataset[$i][0] == $choosen[0]){
+
+ continue;
+ }
+
+ $choices[] = $dataset[$i];
+ }
+
+ // generate grid data
+ $grid = [];
+
+ for($i=0; $i<16; $i++){
+
+ if(in_array($i, $answer_pos)){
+
+ $grid[] = $choosen;
+ }else{
+
+ $grid[] = $choices[random_int(0, count($choices) - 1)];
+ }
+ }
+
+ $key = "c." . apcu_inc("captcha_gen", 1) . "." . random_int(0, 100000000);
+
+ apcu_store(
+ $key,
+ [
+ $grid,
+ count($answer_pos),
+ $choosen[0],
+ false // has captcha been generated?
+ ],
+ 120 // we give user 2 minutes to get captcha, in case of network error
+ );
+
+ $payload = [
+ "class" => "",
+ "right-left" => "",
+ "right-right" => "",
+ "left" =>
+ '<div class="infobox">' .
+ '<h1>IQ test</h1>' .
+ 'Due to getting hit with 20,000 bot requests per day, I had to put this up. Sorry.<br><br>' .
+ 'Solving this captcha will allow you to make 100 searches today. I will add a way for legit users to bypass the captcha later. Sorry /g/tards!!' .
+ $error .
+ '<form method="POST" enctype="text/plain" autocomplete="off">' .
+ '<div class="captcha-wrapper">' .
+ '<div class="captcha">' .
+ '<img src="captcha.php?k=' . $key . '" alt="Captcha image">' .
+ '<div class="captcha-controls">' .
+ '<input type="checkbox" name="c[0]" id="c0">' .
+ '<label for="c0"></label>' .
+ '<input type="checkbox" name="c[1]" id="c1">' .
+ '<label for="c1"></label>' .
+ '<input type="checkbox" name="c[2]" id="c2">' .
+ '<label for="c2"></label>' .
+ '<input type="checkbox" name="c[3]" id="c3">' .
+ '<label for="c3"></label>' .
+ '<input type="checkbox" name="c[4]" id="c4">' .
+ '<label for="c4"></label>' .
+ '<input type="checkbox" name="c[5]" id="c5">' .
+ '<label for="c5"></label>' .
+ '<input type="checkbox" name="c[6]" id="c6">' .
+ '<label for="c6"></label>' .
+ '<input type="checkbox" name="c[7]" id="c7">' .
+ '<label for="c7"></label>' .
+ '<input type="checkbox" name="c[8]" id="c8">' .
+ '<label for="c8"></label>' .
+ '<input type="checkbox" name="c[9]" id="c9">' .
+ '<label for="c9"></label>' .
+ '<input type="checkbox" name="c[10]" id="c10">' .
+ '<label for="c10"></label>' .
+ '<input type="checkbox" name="c[11]" id="c11">' .
+ '<label for="c11"></label>' .
+ '<input type="checkbox" name="c[12]" id="c12">' .
+ '<label for="c12"></label>' .
+ '<input type="checkbox" name="c[13]" id="c13">' .
+ '<label for="c13"></label>' .
+ '<input type="checkbox" name="c[14]" id="c14">' .
+ '<label for="c14"></label>' .
+ '<input type="checkbox" name="c[15]" id="c15">' .
+ '<label for="c15"></label>' .
+ '</div>' .
+ '</div>' .
+ '</div>' .
+ '<input type="hidden" name="k" value="' . $key . '">' .
+ '<input type="submit" value="Check IQ" class="captcha-submit">' .
+ '</form>' .
+ '</div>'
+ ];
+
+ http_response_code(429); // too many reqs
+ $frontend->loadheader(
+ $get,
+ $filters,
+ "web"
+ );
+
+ echo $frontend->load("search.html", $payload);
+ die();
+ }
+}