Seditio Source
Root |
./othercms/elxis_5.3_atlas_rev2452/includes/libraries/elxis/helpers/captcha.helper.php
<?php
/**
* @version        $Id: captcha.helper.php 1870 2016-07-18 15:54:27Z sannosi $
* @package        Elxis
* @subpackage    Helpers/Captcha
* @copyright    Copyright (c) 2006-2019 Elxis CMS (http://www.elxis.org). All rights reserved.
* @license        Elxis Public License ( http://www.elxis.org/elxis-public-license.html )
* @author        Elxis Team ( http://www.elxis.org )
* @description     Elxis CMS is free software. Read the license for copyright notices and details
*/

defined('_ELXIS_') or die ('Direct access to this location is not allowed');


class
elxisCaptchaHelper {

    private
$errormsg = '';


   
/***************/
    /* CONSTRUCTOR */
    /***************/
   
public function __construct() {
    }


   
/*********************/
    /* GET ERROR MESSAGE */
    /*********************/
   
public function getError() {
        return
$this->errormsg;
    }


   
/***********************/
    /* RESET ERROR MESSAGE */
    /***********************/
   
public function resetError() {
       
$this->errormsg = '';
    }


   
/***********************************/
    /* GENERATE CAPTCHA KEY (NO ROBOT) */
    /***********************************/
   
public function generate($custom='') {
       
$all_elements = array(
           
'CONFIG_DB_HOST',
           
'CONFIG_DB_USER',
           
'CONFIG_DEFAULT_ROUTE',
           
'CONFIG_DEFENDER',
           
'CONFIG_MAIL_EMAIL',
           
'CONFIG_MAIL_MANAGER_EMAIL',
           
'CONFIG_REPO_PATH',
           
'CONFIG_SITELANGS',
           
'CONFIG_TIMEZONE',
           
'CONFIG_MAIL_SMTP_HOST',
           
'CONFIG_SESSION_HANDLER',
           
'IP',
           
'AGENT',
           
'HTLANGUAGE',
           
'PATH',
           
'REVISION',
           
'RELDATE',
        );

       
shuffle($all_elements);

       
$elxis = eFactory::getElxis();

       
$elements = array();
       
$num = rand(6, 10);
       
$unenc = '';
        foreach (
$all_elements as $element) {
            if (
count($elements) >= $num) { break; }
            if (
strpos($element, 'CONFIG_') === 0) {//Elxis configuration option
               
$x = str_replace('CONFIG_', '', $element);
               
$v = $elxis->getConfig($x);
            } else if (
$element == 'IP') {
               
$v = $this->getUserIP();
            } else if (
$element == 'AGENT') {
               
$v = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
            } else if (
$element == 'HTLANGUAGE') {
               
$v = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : '';
            } else if (
$element == 'PATH') {
               
$v = ELXIS_PATH;
            } else if (
$element == 'REVISION') {
               
$v = (string)$elxis->fromVersion('REVISION');
            } else if (
$element == 'RELDATE') {
               
$v = (string)$elxis->fromVersion('RELDATE');
            } else {
               
$v = '';
            }
            if (
$v == '') { continue; }

           
$elements[] = $element;

            if (
$unenc == '') {
               
$unenc = $v;
            } else {
               
$unenc .= ','.$v;
            }
        }

        if (
$custom != '') {
            if (
strpos($custom, ',') === false) {//comma is not allowed
               
$elements[] = 'CUSTOM_'.$custom;
               
$unenc .= ','.$custom;
            }
        }

       
$ts = time();
       
$elements[] = 'TIME_'.$ts;
       
$unenc .= ','.$ts.','.$elxis->getConfig('ENCRYPT_KEY');
       
$captchakey = sha1($unenc);

       
$db = eFactory::getDB();

       
$elem_str = implode(',', $elements);
       
$sql = "INSERT INTO ".$db->quoteId('#__captcha')." (".$db->quoteId('cid').", ".$db->quoteId('ckey').", ".$db->quoteId('elements').", ".$db->quoteId('keytime').")"
       
."\n VALUES (NULL, :xkey, :xelem, :xtime)";
       
$stmt = $db->prepare($sql);
       
$stmt->bindParam(':xkey', $captchakey, PDO::PARAM_STR);
       
$stmt->bindParam(':xelem', $elem_str, PDO::PARAM_STR);
       
$stmt->bindParam(':xtime', $ts, PDO::PARAM_INT);
       
$stmt->execute();

       
//5% probability to delete past generated keys (half hour old or more)
       
if (rand(1, 20) == 10) {
           
$ts2 = $ts - 1800;
           
$sql = "DELETE FROM ".$db->quoteId('#__captcha')." WHERE ".$db->quoteId('keytime')." < :xkt";
           
$stmt = $db->prepare($sql);
           
$stmt->bindParam(':xkt', $ts2, PDO::PARAM_INT);
           
$stmt->execute();
        }

        return
$captchakey;
    }


   
/**********************************************/
    /* VALIDATE SUBMITTED CAPTCHA (NO ROBOT/MATH) */
    /**********************************************/
   
public function validate($method, $math_sesname, $math_postname, $robot_keyname, $robot_customname='') {
        if (
$method == 'NONE') { return true; }
        if (
$method == 'MATH') {
           
$ok = $this->validateMath($math_sesname, $math_postname);
            if (!
$ok) {
               
$this->errormsg = eFactory::getLang()->get('INVALIDSECCODE');
            }
            return
$ok;
        }

       
//NOROBOT
       
if (isset($_POST[$robot_keyname])) {
           
$captchakey = trim(filter_input(INPUT_POST, $robot_keyname, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW));
        } else {
           
$captchakey = '';
        }
        if (
$captchakey == '') {
           
$this->errormsg = eFactory::getLang()->get('VERIFY_NOROBOT');
            return
false;
        }

       
$recheck_custom = '';
        if ((
$robot_customname != '') && (isset($_POST[$robot_customname]))) {
           
$recheck_custom = trim(filter_input(INPUT_POST, $robot_customname, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW));
        }

       
$ok = $this->validateNoRobot($captchakey, $recheck_custom);
        if (!
$ok) {
           
$this->errormsg = eFactory::getLang()->get('VERIFY_NOROBOT');
        } else {
           
$this->deleteKey($captchakey);
        }

        return
$ok;
    }


   
/*********************************************/
    /* VALIDATE SUBMITTED CAPTCHA KEY (NO ROBOT) */
    /*********************************************/
   
public function validateNoRobot($captchakey, $recheck_custom='') {
        if (
trim($captchakey) == '') { return false; }

       
$filtered = preg_replace("/[^A-Za-z0-9 ]/", '', $captchakey);
        if (
$filtered != $captchakey) { return false; }

       
$db = eFactory::getDB();
       
$sql = "SELECT ".$db->quoteId('elements')." FROM ".$db->quoteId('#__captcha')." WHERE ".$db->quoteId('ckey')." = :xk";
       
$stmt = $db->prepareLimit($sql, 0, 1);
       
$stmt->bindParam(':xk', $captchakey, PDO::PARAM_STR);
       
$stmt->execute();
       
$elements_str = $stmt->fetchResult();
        if (!
$elements_str) { return false; }
        if (
trim($elements_str) == '') { return false; }

       
$elxis = eFactory::getElxis();
       
$elements = explode(',', $elements_str);

       
$time = 0;
       
$unenc = '';
        foreach (
$elements as $element) {
            if (
strpos($element, 'CONFIG_') === 0) {//Elxis configuration option
               
$x = str_replace('CONFIG_', '', $element);
               
$v = $elxis->getConfig($x);
            } else if (
$element == 'IP') {
               
$v = $this->getUserIP();
            } else if (
$element == 'AGENT') {
               
$v = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
            } else if (
$element == 'HTLANGUAGE') {
               
$v = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : '';
            } else if (
$element == 'PATH') {
               
$v = ELXIS_PATH;
            } else if (
$element == 'REVISION') {
               
$v = (string)$elxis->fromVersion('REVISION');
            } else if (
$element == 'RELDATE') {
               
$v = (string)$elxis->fromVersion('RELDATE');
            } else if (
strpos($element, 'TIME_') === 0) {
               
$v = intval(str_replace('TIME_', '', $element));
               
$time = $v;
            } else if (
strpos($element, 'CUSTOM_') === 0) {
               
$v = str_replace('CUSTOM_', '', $element);
                if (
$recheck_custom != '') {
                    if (
$v != $recheck_custom) { return false; }
                }
            } else {
               
$v = '';
            }

            if (
$unenc == '') {
               
$unenc = $v;
            } else {
               
$unenc .= ','.$v;
            }
        }

        if (
$time == 0) { return false; }
        if (
time() - $time > 900) { return false; } //maximum lifetime 15 minutes

       
$unenc .= ','.$elxis->getConfig('ENCRYPT_KEY');
       
$captchakey2 = sha1($unenc);

        return (
$captchakey == $captchakey2) ? true : false;
    }


   
/*********************************************/
    /* VALIDATE SUBMITTED CAPTCHA KEY (MATH) */
    /*********************************************/
   
public function validateMath($session_name, $post_name) {
        if ((
$session_name == '') || ($post_name == '')) { return false; }

       
$eSession = eFactory::getSession();

       
$sess_captcha = trim($eSession->get($session_name));
        if (isset(
$_POST[$post_name])) {
           
$seccode = trim(filter_input(INPUT_POST, $post_name, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW));
        } else {
           
$seccode = '';
        }

        if ((
$sess_captcha == '') || ($seccode == '') || ($seccode != $sess_captcha)) {
            return
false;
        }
        return
true;
    }


   
/****************************************************************/
    /* DELETE NOROBOT CAPTCHA FROM DB (AFTER SUCESSFULL VALIDATION) */
    /****************************************************************/
   
public function deleteKey($captchakey) {
       
$db = eFactory::getDB();
       
$sql = "DELETE FROM ".$db->quoteId('#__captcha')." WHERE ".$db->quoteId('ckey')." = :xk";
       
$stmt = $db->prepare($sql);
       
$stmt->bindParam(':xk', $captchakey, PDO::PARAM_STR);
       
$stmt->execute();
    }


   
/***********************/
    /* GET USER IP ADDRESS */
    /***********************/
   
private function getUserIP() {
        if (isset(
$_SERVER['HTTP_CLIENT_IP']) && ($_SERVER['HTTP_CLIENT_IP'] != '')) {
           
$ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset(
$_SERVER['HTTP_X_FORWARDED_FOR']) && ($_SERVER['HTTP_X_FORWARDED_FOR'] != '')) {
           
$n = strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',');//Required in case we have multiple IPs
           
if ($n === false) {
               
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            } else {
               
$ip = substr($_SERVER['HTTP_X_FORWARDED_FOR'], 0, $n);//get the first IP in the list
           
}
        } elseif (isset(
$_SERVER['REMOTE_ADDR']) && ($_SERVER['REMOTE_ADDR'] != '')) {
           
$ip = $_SERVER['REMOTE_ADDR'];
        } else {
           
$ip = '';
        }

        return
$ip;
    }

}

?>