VELODATA

FIND US

Address
Level 19,  50 Cavill Ave
Surfers Paradise,  Qld. Aus

Hours
Monday-Friday:  9AM – 5:30PM
Saturday:  11AM – 3PM

Knowing what to look for

Velodata Scanning Logic

HOW TO GET THE MOST OUT OF THE VELODATA BLACKHOLE SOFTWARE

The following section explains the conditional programming logic used by the Blackhole Cyber Security System.

Got some questions?  By all means,  contact us.  

Let’s examine the Scanning Logic.

The standalone PHP version of Velodata’s Blackhole Cyber Security system contains four files:  The following Code Snippet shown below is from the main executable file,  blackhole.php  –  Please Note:  We’re not showing all of the main executable,  just the conditional logic.

If you’ve loaded the Blackhole System and you’re experiencing issues  (you shouldn’t by the way,  we’ve tested it extensively for years) well you can at least refer to this PHP code and perhaps identify why the triggering logic is not working the way you’d expect.

				
					<?php
/*

  Title:        Velodata Blackhole Cyber Security System
  Description:  Automatically scans incoming requests and ban/deflect requests which don't pass the rules.
  Benefits:     Super fast,  super light CPU consumption,  catches anything your outer firewalls (like Cloudflare etc) fail to catch.
                Has a 'self learning feature' which learns from past 404 phishing attempts and then bans future phishing IP address blocks in real time.
                Has a form of two factor authentication which denies access to phpMyAdmin and WordPress administration unless you know the Velodata Bypass Code.
  Project URL:  https://velodata.org
  Author:       Velodata Pty Ltd ( @velodata )
  Version:      2022.07.08
  License:      GPLv2 or later
  License URI:  https://www.gnu.org/licenses/gpl-2.0.txt

  For complete documentation, visit https://velodata.org
  
  If you want to tweak the ban logic,  search for function velodata_sorry_but_you_got_banned() 


 */




// EDIT HERE


define('PREPEND_TO',      'reply_to@your_website');             // email to
define('PREPEND_FROM',    'reply_to@your_website');           // email from
define('PREPEND_SUBJECT', 'Another Blackhole IP Ban!');       // email subject
define('PREPEND_CONTACT', '/contact/');                       // contact url


// DO NOT EDIT BELOW THIS LINE

define('PREPEND_VERSION', '4.5');
define('PREPEND_PATH', dirname(__FILE__) . '/');


blackhole_main_program();
return;


function console_log($output, $with_script_tags = true) {
    $js_code = 'console.log(' . json_encode($output, JSON_HEX_TAG) .
            ');';
    if ($with_script_tags) {
        $js_code = '<script>' . $js_code . '</script>';
    }
    echo $js_code;
}

function velodata_blackhole_get_vars() { 

    $ip = velodata_blackhole_get_ip();

    $ua = isset($_SERVER['HTTP_USER_AGENT'])       ? velodata_sanitize($_SERVER['HTTP_USER_AGENT']) : null;
    $request = isset($_SERVER['REQUEST_URI'])      ? velodata_sanitize($_SERVER['REQUEST_URI']) : null;
    $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? velodata_sanitize($_SERVER['SERVER_PROTOCOL']) : null;
    $method = isset($_SERVER['REQUEST_METHOD'])    ? velodata_sanitize($_SERVER['REQUEST_METHOD']) : null;
    $referrer = isset($_SERVER['HTTP_REFERER'])    ? velodata_sanitize($_SERVER['HTTP_REFERER']) : null;


    if ( isset($_SERVER['blackhole_ini_path']) ) {
        $ini_array = parse_ini_file($_SERVER["blackhole_ini_path"]);
    } else {
        $ini_array = parse_ini_file(dirname(__FILE__) . '/blackhole.ini');    
    }
    $ini_default_email = isset($ini_array['PARD_EMAIL_ADDRESS'])  ? velodata_sanitize($ini_array['PARD_EMAIL_ADDRESS']) : null;
    $ini_bypass_xword = isset($ini_array['PARD_BYPASS_XWORD'])    ? velodata_sanitize($ini_array['PARD_BYPASS_XWORD']) : null;


    $m0_OFFENDING_URI = filter_input(INPUT_GET, 'OFFENDING_URI');
    $m0_BASE_PATH     = isset($_SERVER['SERVER_NAME']) ? velodata_sanitize($_SERVER['SERVER_NAME']) : null;
    $lxHTTP_REASON   = filter_input(INPUT_GET, 'm0HTTP_REASON');


    $GLOBALS['PARD_EMAIL_NOTIFICATION_ADDRESS']      = isset($ini_array['PARD_EMAIL_NOTIFICATION_ADDRESS'])     ? velodata_sanitize($ini_array['PARD_EMAIL_NOTIFICATION_ADDRESS']) : null;
    $GLOBALS['PARD_EMAIL_REPLY_ADDRESS']             = isset($ini_array['PARD_EMAIL_REPLY_ADDRESS'])            ? velodata_sanitize($ini_array['PARD_EMAIL_REPLY_ADDRESS']) : null;
    $GLOBALS['ini_default_email']                    = isset($ini_array['PARD_EMAIL_ADDRESS'])                  ? velodata_sanitize($ini_array['PARD_EMAIL_ADDRESS']) : null;
    $GLOBALS['ini_bypass_xword']                     = isset($ini_array['PARD_BYPASS_XWORD'])                   ? velodata_sanitize($ini_array['PARD_BYPASS_XWORD']) : null;
    $GLOBALS['ini_PARD_DB_NAME']                     = isset($ini_array['PARD_DB_NAME'])                        ? velodata_sanitize($ini_array['PARD_DB_NAME']) : null;
    $GLOBALS['ini_PARD_DB_USER']                     = isset($ini_array['PARD_DB_USER'])                        ? velodata_sanitize($ini_array['PARD_DB_USER']) : null;
    $GLOBALS['ini_PARD_DB_PASSWORD']                 = isset($ini_array['PARD_DB_PASSWORD'])                    ? velodata_sanitize($ini_array['PARD_DB_PASSWORD']) : null;
    $GLOBALS['ini_PARD_DB_HOST']                     = isset($ini_array['PARD_DB_HOST'])                        ? velodata_sanitize($ini_array['PARD_DB_HOST']) : null;
    $GLOBALS['PARD_ARE_WE_USING_CLOUDFLARE']         = isset($ini_array['PARD_ARE_WE_USING_CLOUDFLARE'])        ? velodata_sanitize($ini_array['PARD_ARE_WE_USING_CLOUDFLARE']) : "NO";
    $GLOBALS['PARD_CLOUDFLARE_API_KEY']              = isset($ini_array['PARD_CLOUDFLARE_API_KEY'])             ? velodata_sanitize($ini_array['PARD_CLOUDFLARE_API_KEY']) : null;
    $GLOBALS['PARD_CLOUDFLARE_AUTH_EMAIL']           = isset($ini_array['PARD_CLOUDFLARE_AUTH_EMAIL'])          ? velodata_sanitize($ini_array['PARD_CLOUDFLARE_AUTH_EMAIL']) : null;
    $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS']         = isset($ini_array['PARD_ARE_WE_USING_VIP_ACCESS'])        ? velodata_sanitize($ini_array['PARD_ARE_WE_USING_VIP_ACCESS'])        : "NO";
    $GLOBALS['PARD_ARE_WE_USING_SELF_LEARNING']      = isset($ini_array['PARD_ARE_WE_USING_SELF_LEARNING'])     ? velodata_sanitize($ini_array['PARD_ARE_WE_USING_SELF_LEARNING'])     : "NO";
    $GLOBALS['PARD_ARE_WE_PROVIDING_FEEDBACK']       = isset($ini_array['PARD_ARE_WE_PROVIDING_FEEDBACK'])      ? velodata_sanitize($ini_array['PARD_ARE_WE_PROVIDING_FEEDBACK'])      : "NO";
    $GLOBALS['PARD_ARE_WE_SENDING_NOTIFICATIONS']    = isset($ini_array['PARD_ARE_WE_SENDING_NOTIFICATIONS'])   ? velodata_sanitize($ini_array['PARD_ARE_WE_SENDING_NOTIFICATIONS'])   : "NO";
    $GLOBALS['PARD_ARE_WE_USING_TRUSTED_RING']       = "NO";
    $GLOBALS['PARD_ARE_WE_PROTECTING_THE_API']       = "YES";
	$GLOBALS['PARD_BAN_UNAUTHORISED_HEAD_REQUESTS']  = "YES";
    $GLOBALS['PARD_BAN_UNAUTHORISED_POST_REQUESTS']  = isset($ini_array['PARD_BAN_UNAUTHORISED_POST_REQUESTS']) ? velodata_sanitize($ini_array['PARD_BAN_UNAUTHORISED_POST_REQUESTS']) : "NO";
    $GLOBALS['PARD_BAN_UNAUTHORISED_SPIDERBOTS']     = isset($ini_array['PARD_BAN_UNAUTHORISED_SPIDERBOTS'])    ? velodata_sanitize($ini_array['PARD_BAN_UNAUTHORISED_SPIDERBOTS'])    : "NO";
    $GLOBALS['PARD_BAN_UNAUTHORISED_PHP_REQUESTS']   = isset($ini_array['PARD_BAN_UNAUTHORISED_PHP_REQUESTS'])  ? velodata_sanitize($ini_array['PARD_BAN_UNAUTHORISED_PHP_REQUESTS'])  : "NO";
    $GLOBALS['PARD_BAN_UNAUTHORISED_URI_REQUESTS']   = isset($ini_array['PARD_BAN_UNAUTHORISED_URI_REQUESTS'])  ? velodata_sanitize($ini_array['PARD_BAN_UNAUTHORISED_URI_REQUESTS'])  : "NO";
    $GLOBALS['PARD_BAN_UNAUTHORISED_404_REQUESTS']   = isset($ini_array['PARD_BAN_UNAUTHORISED_404_REQUESTS'])  ? velodata_sanitize($ini_array['PARD_BAN_UNAUTHORISED_404_REQUESTS'])  : "NO";
    define('PREPEND_TEST_VARIABLE',                    isset($ini_array['PARD_CLOUDFLARE_API_KEY'])             ? velodata_sanitize($ini_array['PARD_CLOUDFLARE_API_KEY'])             : null );       


    $GLOBALS['PARD_TRUSTED_RANGE_01']   = isset($ini_array['PARD_TRUSTED_RANGE_01'])  ? velodata_sanitize($ini_array['PARD_TRUSTED_RANGE_01'])  : null;
    $GLOBALS['PARD_TRUSTED_RANGE_02']   = isset($ini_array['PARD_TRUSTED_RANGE_02'])  ? velodata_sanitize($ini_array['PARD_TRUSTED_RANGE_02'])  : null;
    $GLOBALS['PARD_TRUSTED_RANGE_03']   = isset($ini_array['PARD_TRUSTED_RANGE_03'])  ? velodata_sanitize($ini_array['PARD_TRUSTED_RANGE_03'])  : null;
    $GLOBALS['PARD_TRUSTED_RANGE_04']   = isset($ini_array['PARD_TRUSTED_RANGE_04'])  ? velodata_sanitize($ini_array['PARD_TRUSTED_RANGE_04'])  : null;
    $GLOBALS['PARD_TRUSTED_RANGE_05']   = isset($ini_array['PARD_TRUSTED_RANGE_05'])  ? velodata_sanitize($ini_array['PARD_TRUSTED_RANGE_05'])  : "";


    $GLOBALS['PARD_IP_TYPE'] = 'IPv4';
    $GLOBALS['ip']           = velodata_blackhole_get_ip();
    $GLOBALS['ua']           = isset($_SERVER['HTTP_USER_AGENT'])  ? velodata_sanitize($_SERVER['HTTP_USER_AGENT']) : null;
    $GLOBALS['request']      = isset($_SERVER['REQUEST_URI'])      ? velodata_sanitize($_SERVER['REQUEST_URI']) : null;
    $GLOBALS['query_string'] = isset($_SERVER['QUERY_STRING'])     ? velodata_sanitize($_SERVER['QUERY_STRING']) : null;
    $GLOBALS['protocol']     = isset($_SERVER['SERVER_PROTOCOL'])  ? velodata_sanitize($_SERVER['SERVER_PROTOCOL']) : null;
    $GLOBALS['method']       = isset($_SERVER['REQUEST_METHOD'])   ? velodata_sanitize($_SERVER['REQUEST_METHOD']) : null;
    $GLOBALS['referrer']     = isset($_SERVER['HTTP_REFERER'])     ? velodata_sanitize($_SERVER['HTTP_REFERER']) : null; 


    $GLOBALS['m0_OFFENDING_URI'] = filter_input(INPUT_GET, 'OFFENDING_URI');    
    $GLOBALS['m0_BASE_PATH']     = isset($_SERVER['SERVER_NAME']) ? velodata_sanitize($_SERVER['SERVER_NAME']) : null;
    $GLOBALS['SERVER_NAME']      = isset($_SERVER['SERVER_NAME']) ? velodata_sanitize($_SERVER['SERVER_NAME']) : null;
    $GLOBALS['REASON_FOR_BAN']   = filter_input(INPUT_GET, 'm0HTTP_REASON');

    date_default_timezone_set('UTC');

    $date = date('l, F jS Y @ H:i:s'); 
    $time = time();
    $GLOBALS['date'] = date('l, F jS Y @ H:i:s');
    $GLOBALS['time'] = time();

    return array($ip, $ua, $request, $referrer, $protocol, $method, $date, $time, $ini_array, $ini_bypass_xword, $m0_OFFENDING_URI, $m0_BASE_PATH, $lxHTTP_REASON);
}



function velodata_are_we_authorised() {
    /*
    Purpose:    By default the Login screens for WordPress and PHPMyAdmin are open to the world until you fine tune 
                your blackhole.ini configuration file.  
  
                If this function returns "true" then the WordPress login screens can be reachedand you won't get banned,
  
                If this function returns "false" the WordPress login screens CANNOT be reached.  
    */
    $GLOBALS['PARD_ARE_WE_USING_TRUSTED_RING'] = "NO" ;
    if ( velodata_evaluate_trusted_ip( $GLOBALS['PARD_TRUSTED_RANGE_01'] ) || 
         velodata_evaluate_trusted_ip( $GLOBALS['PARD_TRUSTED_RANGE_02'] ) || 
         velodata_evaluate_trusted_ip( $GLOBALS['PARD_TRUSTED_RANGE_03'] ) || 
         velodata_evaluate_trusted_ip( $GLOBALS['PARD_TRUSTED_RANGE_04'] ) || 
         velodata_evaluate_trusted_ip( $GLOBALS['PARD_TRUSTED_RANGE_05'] ) ) {
         $GLOBALS['PARD_ARE_WE_USING_TRUSTED_RING'] = "YES" ;
        //  
        //  Dear User:  If you have specified a Trusted Ring of IP Addresses in your blackhole.ini then this subroutine sets $GLOBALS['PARD_ARE_WE_USING_TRUSTED_RING'] === 'YES' 
        //              This is the ONLY location where this global flag gets set to 'YES'.  We're confirming the Trusted Ring is using valid IP addresses and/or ranges.
        //  
    }
    if ( $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS'] === 'YES'  ) {
        if (isset($_COOKIE['velodata_bypass_code']) && $_COOKIE['velodata_bypass_code'] === $GLOBALS['ini_bypass_xword']) {
            //  
            //  Dear User:  The VIP Access System means you can ONLY reach the WordPress or PHPMyAdmin administration screens if you have provided a valid VIP Bypass Code.
            //              But it also means you can access the Login screens from anywhere in the world,  which can be useful if you're on holidays for example.
            //  
            return true;
        }
        $lxBYPASS = filter_input(INPUT_GET, 'bypass');
        if (! isset($lxBYPASS)) {
            $lxBYPASS = filter_input(INPUT_POST, 'bypass');
        }
        if ( isset($lxBYPASS) && $lxBYPASS === $GLOBALS['ini_bypass_xword'] )  {
            //  
            //  Dear User:  This section checks if the remote client has specified the Velodata Bypass Code in their URL request.  
            //              If this test passes,  we create a cookie with the authorisation flag in it.
            //              If the user removes all their cookies,  future authorisation gets removed.  
            //  
            setcookie("velodata_bypass_code", $lxBYPASS, time() + 86400 * 30, "/");
            return true;
        }
    }
    if ( $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS'] === 'NO' && $GLOBALS['PARD_ARE_WE_USING_TRUSTED_RING'] === 'YES' ) {
        if ( velodata_is_IP_whitelisted($GLOBALS['ip']) === true ) {
            //
            //  Dear User:  if you are NOT using VIP Access but you are using a Trusted Ring of IP ranges AND if this IP Address IS a part of your Trusted Ring, return true.
            //
            return true;
        } 
    }
    if ( $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS'] === 'NO' && $GLOBALS['PARD_ARE_WE_USING_TRUSTED_RING'] === 'NO' ) {
        //  
        //  Dear User:  If the VIP Access System is NOT active AND if the Trusted Ring of IP Addresses is also NOT active,  return "true".
        //              This is the default behaviour for the Blackhole system when you first load the software,  but before you fine tine the blackhole.ini configuration file.
        //  
        return true;
    }
    //  
    //  Dear User:  If we've reached this far in the code it means one of two things.
    //              (1) the bypass code which was sent in the browser's URL request is wrong or...  or it wasn't sent at all.
    //              (2) It could also mean the "bypass code cookie" which was sent by the browser request is also wrong.  Perhaps you've changed the VIP Bypass Code in the blackhole.ini file.
    //              
    //              Delete any prexisting permission cookies related to this browser.  Doing this immediatly removes Administration Authorisation.
    //              For example,  if you decide to change the VIP Bypass Code because an ex-employee knows what the old Bypass Code used to be...
    //  
    setcookie("velodata_bypass_code", "", time() - 3600, "/"); 
    return false;
}




function velodata_scan_the_request($ip, $ua, $request, $referrer, $ini_bypass_xword, $lxHTTP_REASON) {



    
    $lxAuthorised = velodata_are_we_authorised();
    // If lxAuthorised = "true" then the WordPress login screens can be reached. 
    // If lxAuthorised = "true" we are not going to get banned at the Firewall, even if we deliberately ask for a bannable URL.. 
    // If lxAuthorised = "true" it could me we're in the Trusted Ring of addresses.  
    // If lxAuthorised = "false" the login screens CANNOT be reached.  
    $lxFBCLID = filter_input(INPUT_GET, 'fbclid');
    $GLOBALS['REASON_FOR_BAN'] = 'UNAUTHORISED_REQUEST';




    if ( \preg_match("/velodata.info.php/i", $request) === 1 ||  preg_match("/index.phpinfo.php/i", $request) === 1 ) {
        echo '<meta name="robots" content="noindex,nofollow,noarchive,nosnippet,noodp,noydir">';
        echo '<h1>Good News!  Your Blackhole Cyber Security is operational.</h1>';
        echo '<p>However, now we need to do some fine tuning.  Let\'s get cracking then!</p>';
        echo '<p></p>';
    	echo '<p>the value of PREPEND_PATH = ' . PREPEND_PATH . '</p>';
    	echo '<p>Your IP address = ' . $GLOBALS['ip'] . '</p>';
    	echo '<p>Your IPv type = ' . $GLOBALS['PARD_IP_TYPE'] . '</p>';
    	echo '<p>Your reply email address = ' . $GLOBALS['PARD_EMAIL_REPLY_ADDRESS'] . '</p>';
	    echo '<p>Your offending URI = ' . velodata_sanitize($_SERVER['HTTP_HOST']) . $GLOBALS['request'] . '</p>';
    	echo '<p>Internal Domain = ' . $_SERVER['base_path'] . '</p>';
    	echo '<p>Reason for Ban = ' . $GLOBALS['REASON_FOR_BAN'] . '</p>';
    	echo '<p></p>';
    	//echo '<p>If you have any question please contact <a href="mailto:' . $default_email .'">The Webmaster</a>.</p>';
    	echo '<p>If you have any question please <a href="mailto:' . $GLOBALS['PARD_EMAIL_REPLY_ADDRESS'] . '">contact the Administrator</a>.</p>';

        console_log('    ');
        console_log('PARD_ARE_WE_USING_CLOUDFLARE = '       . $GLOBALS['PARD_ARE_WE_USING_CLOUDFLARE']); 
        console_log('PARD_ARE_WE_USING_TRUSTED_RING = '     . $GLOBALS['PARD_ARE_WE_USING_TRUSTED_RING']); 
        console_log('PARD_ARE_WE_USING_SELF_LEARNING = '    . $GLOBALS['PARD_ARE_WE_USING_SELF_LEARNING']); 
        console_log('PARD_ARE_WE_USING_VIP_ACCESS = '       . $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS']); 
        console_log('PARD_ARE_WE_SENDING_NOTIFICATIONS = '  . $GLOBALS['PARD_ARE_WE_SENDING_NOTIFICATIONS']); 
        console_log('PARD_ARE_WE_PROVIDING_FEEDBACK = '     . $GLOBALS['PARD_ARE_WE_PROVIDING_FEEDBACK']); 
        console_log('PARD_IP_TYPE = '                       . $GLOBALS['PARD_IP_TYPE']); 

        console_log("    ");
        //  console_log("Default Notification email address = "  . $GLOBALS['PARD_EMAIL_NOTIFICATION_ADDRESS']); 
        console_log("blackhole_exe_file = "                  . __FILE__ ); 
        console_log("blackhole_ini_file = "                  . $_SERVER["blackhole_ini_path"] ); 
        console_log("PARD_BAN_UNAUTHORISED_POST_REQUESTS = " . $GLOBALS['PARD_BAN_UNAUTHORISED_POST_REQUESTS']);
        console_log("PARD_BAN_UNAUTHORISED_SPIDERBOTS = "    . $GLOBALS['PARD_BAN_UNAUTHORISED_SPIDERBOTS']);
        console_log("PARD_BAN_UNAUTHORISED_PHP_REQUESTS = "  . $GLOBALS['PARD_BAN_UNAUTHORISED_PHP_REQUESTS']);
        console_log("PARD_BAN_UNAUTHORISED_URI_REQUESTS = "  . $GLOBALS['PARD_BAN_UNAUTHORISED_URI_REQUESTS']);
        console_log("PARD_BAN_UNAUTHORISED_404_REQUESTS = "  . $GLOBALS['PARD_BAN_UNAUTHORISED_404_REQUESTS']);
        console_log("    ");
        console_log("    ");
        if ( $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS'] === 'YES' && $lxAuthorised !== true ) {
            console_log("Please Note:  This website allows Blackhole VIP Access,  but you are currently not Authorised.    ");
            console_log("              Try adding the ?bypass=<your access code> parameter...    ");
        }
        exit;
    }


    if ( preg_match("/index.phpinfo.php/i", $request) === 1) {
        echo '<meta name="robots" content="noindex,nofollow,noarchive,nosnippet,noodp,noydir">';
        exit;
    }


    if (preg_match("/(adreview|aiohttp|Baiduspider|Barkrowler|BLEXBot|BPImageWalker|CensysInspect|coccocbot|CrowdTanglebot|curl)/i", $ua) == 1 ||
        preg_match("/(Dataprovider|Dispatch|DotBo|Go-http-client|ia_archiver|hypefactors|krzana-rss-bot)/i", $ua) == 1 ||
        preg_match("/(linkfluence|LightspeedSystemsCrawler|my-tiny-bot|MJ12bot|NetcraftSurveyAgent|NetSystemsResearch|Nimbostratus)/i", $ua) == 1 ||
        preg_match("/(paloaltonetworks.com|petalbot|pdrlabs.net|python-httpx|Python|python-requests|QIHU 360SE|Ruby)/i", $ua) == 1 ||
        preg_match("/(Slackbot|SemrushBot|serpstatbot|SeznamBot|Typhoeus|ubermetrics|yandex|zgrab|ZoominfoBot)/i", $ua) == 1) {
        //              
        //  Dear User:- Spiderbots are a pain in the ass,  especially the ultra hungry Facebook version called cortex.  scaninfo@paloaltonetworks.com
        //              But we don't want to necessarily ban the IP addresses they belong to  -  but you can if you want!
        //              So what we do is we reply with http 200 but then we divert them to their own http://127.0.0.1 localhost. 
        //              
        //              Please note, a lot of unwanted Spiderbot problems go away if you're using a DNS Content Delivery service like Cloudflare
        //              
        if ( $GLOBALS['PARD_BAN_UNAUTHORISED_SPIDERBOTS'] === "YES" ) {
            $GLOBALS['REASON_FOR_BAN'] = "UNAUTHORISED_SPIDERBOT_REQUEST";
            return 0;  //  ban them!
        }
    }


    if ( $_SERVER["REQUEST_METHOD"] === "HEAD" ) {
        //              
        //  Dear User:-  Some scanners try to use the HEAD request method to find weakspots.  We're going to ban them if they're not an approved Spiderbot.
        //              
        if ( $GLOBALS['PARD_BAN_UNAUTHORISED_HEAD_REQUESTS']  === "YES" ) {
	        $GLOBALS['REASON_FOR_BAN'] = "UNAUTHORISED_HTTP_HEAD_REQUEST";
    	   return 0;  //  ban them!
        } 
    }


    if ( preg_match("/\?fbclid=/", $_SERVER['QUERY_STRING']) == 1 || preg_match("/\?fb_comment_id=/", $_SERVER['QUERY_STRING']) == 1 ) {
        //  Dear User:- This subroutine checks for the presence of a typical Facebook parameter in the QUERY STRING of the original URL 
        //  		    If the QUERY STRING has a correctly formatted Facebook link then let's allow the request.  It's a legitimate link to your website on Facebook.
        return 999; //  999 = good to go
    }



    $request_only = $GLOBALS['request']; 
    if (preg_match("/\?/", $GLOBALS['request']) == 1) {
        //              
        //  Dear User:- This subroutine strips dodgy query string parameters from the original URL request to prevent 404 phishing...
        //              However,  it only does this if you are NOT an authorised user of WordPress.  If you ARE an authorised user,  let the parameters exist.
        //              
        //              
        $original_request = $GLOBALS['request']; 
        $query_string = '?' . $GLOBALS['query_string'];
        $replace_string = '';
        $request_only = str_replace($query_string, $replace_string, $original_request); 
        if (preg_match("/^abc=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^author=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^code=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^d=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^daksldlkdsadas=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^emailaddress=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^f=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^file=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^Ghost=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^n=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^p=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^s=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^test=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^type=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^u=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^upload=/", $GLOBALS['query_string']) == 1 ||
            preg_match("/^v=/", $GLOBALS['query_string']) == 1           
           ) 
        {
            if ($lxAuthorised !== true) {
                $new_URL = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . $request_only;
                header("Location: " . $new_URL);
                die;
            } 
        }
    }


    if (preg_match("/.bmp|.css|.flv|.gif|.gz|.jpeg|.jpg|.png|.mp3|.mp4|.pdf|.rar|.swf|.txt|.zip/i", $request) == 1) {
        //  Dear User:- This subroutine only gets called if a remote client requests a media resource which does NOT exist on the file system.
        //  			You can either 'die' the process with zero feedback to the calling client OR,  you can ban them by returning 0
        //  			We recommend banning these requests at the IPTABLES level  (by returning 0) because they're only going to come back again
        //  			and also,  because it's stops potential Denial of Service attacks. Let the function velodata_check_for_not_found() do it's thing!
        //              
        //  Please Note:-  XML files are generated by the XML sitemap plugin.  This can make processing for 404 files tricky. apple-touch-icon-precomposed.png
        //              
        //              
        if (preg_match("/\%20/i", $request) == 1) {
            header("HTTP/1.1 406 PREPEND Blackhole Software");
            die; //  
        }
        if (preg_match("/.zip/i", $request) == 1) {
            header("HTTP/1.1 406 PREPEND Blackhole Software");
            die; //  
        }
        if (preg_match("/robots.txt/", $request) == 1) {
            return 999; //  999 = good to go
        }
        if (preg_match("/apple-touch-icon/", $request) == 1) {
            header("HTTP/1.1 406 PREPEND Blackhole Software");
            die; //  
        }
    }


    if (preg_match("/author/i", $request) == 1) {
        //  Dear User:- This subroutine only gets called if a remote client requests a media resource which does NOT exist on the file system.
        //  			You can either 'die' the process with zero feedback to the calling client OR,  you can ban them by returning 0
        //  			We recommend banning these requests at the IPTABLES level  (by returning 0) because they're only going to come back again
        //  			and also,  because it's stops potential Denial of Service attacks. Let the function velodata_check_for_not_found() do it's thing!
        //              
        //  Please Note:-  XML files are generated by the XML sitemap plugin.  This can make processing for 404 files tricky. apple-touch-icon-precomposed.png
        //              
        //              
        header("HTTP/1.1 406 PREPEND Blackhole Software");
        die; //  
    }


    if (preg_match("/wp-cron/", $request) == 1) {
        if (velodata_if_wordpress_useragent($ua)) {
            return 999; //  999 = good to go
        }
        if ($lxAuthorised === true) {
            return 999; //  999 = good to go
        } 
        if ( velodata_is_IP_whitelisted($ip )) {
            if ( $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS'] === 'YES' ) {
                $GLOBALS['REASON_FOR_BAN'] = "WPLOGIN_ACCESS_CODE_REQUIRED";
                return 998; //  998 = remind the user to enter a Velodata Bypass Code  
            } 
        }
        $GLOBALS['REASON_FOR_BAN'] = "WPLOGIN_ADMIN_FAIL";
        return 0;  //  0 = BAN THEM and die!
    }


    if (preg_match("/wp-login/", $request) == 1 || preg_match("/wp-admin/", $request) == 1) {
        if (velodata_if_wordpress_useragent($ua)) {
            return 999; //  999 = good to go
        }
        if ($lxAuthorised === true) {
            return 999; //  999 = good to go
        } 
        if ( velodata_is_IP_whitelisted($ip )) {
            if ( $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS'] === 'YES' ) {
                $GLOBALS['REASON_FOR_BAN'] = "WPLOGIN_ACCESS_CODE_REQUIRED";
                return 998; //  998 = remind the user to enter a Velodata Bypass Code  
            } else {
                return 999; //  999 = good to go
            }
        }
        $GLOBALS['REASON_FOR_BAN'] = "WPLOGIN_ADMIN_FAIL";
        return 0;  //  0 = BAN THEM and die!
    }


    if (preg_match("/phpmyadmin/i", $request) == 1) {
        if ($lxAuthorised === true) {
            return 999; //  999 = good to go
        } 
        if ( velodata_is_IP_whitelisted($ip )) {
            if ( $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS'] === 'YES' ) {
                $GLOBALS['REASON_FOR_BAN'] = "WPLOGIN_ACCESS_CODE_REQUIRED";
                return 998; //  998 = remind the user to enter a Velodata Bypass Code  
            } else {
                return 999; //  999 = good to go
            }
        }
        $GLOBALS['REASON_FOR_BAN'] = "PHP_MY_ADMIN_FAIL";
        return 0;  //  0 = BAN THEM and die!
    }


    if ( preg_match("/wp-json/", $request) == 1 ) {
        if ($lxAuthorised == true) {
            return 999; //  999 = good to go
        } 
        $GLOBALS['REASON_FOR_BAN'] = "WP_API_JSON_ACCESS_DENIED";
        return 0; //ban them
    }


    if ( preg_match("/\/.env/i", $request) == 1 ||
         preg_match("/\/autodiscover/i", $request) == 1 ||
         preg_match("/\/license.txt/i", $request) == 1 ||
         preg_match("/\/readme.html/i", $request) == 1 ||
         preg_match("/\/readme.txt/i", $request) == 1 ||
         preg_match("/\/.htaccess/i", $request) == 1 ||
         preg_match("/\/debug.log/i", $request) == 1 ||
         preg_match("/\/web/i", $request) == 1 ||
         preg_match("/\/portal/i", $request) == 1 ||
         preg_match("/\/cms/i", $request) == 1 ||
         preg_match("/\/dev/i", $request) == 1 ||
         preg_match("/\/tmp/i", $request) == 1 ||
         preg_match("/\/home/i", $request) == 1 ||
         preg_match("/\/demo/i", $request) == 1 ||
         preg_match("/\/backup/i", $request) == 1 ||
         preg_match("/\/site/i", $request) == 1 ||
         preg_match("/\/testing/i", $request) == 1 ||
         preg_match("/\/main/i", $request) == 1 ||
         preg_match("/\/test/i", $request) == 1 ||
         preg_match("/\/newsite/i", $request) == 1 ||
         preg_match("/\/old/i", $request) == 1 ||
         preg_match("/\/new/i", $request) == 1 ||
         preg_match("/\/blog/i", $request) == 1 ||
         preg_match("/\/nolink.php/i", $request) == 1 ||
         preg_match("/\/up.php/i", $request) == 1 ||
         preg_match("/\/wp/i", $request) == 1 ||
         preg_match("/\/wordpress/i", $request) == 1 ||
         preg_match("/XXX_END_OF_LIST/", $ua) == 1 ) 
    {
        if (velodata_spiderbot_whitelist($ua) === true ) {
        	return 999; //  999 = good to go
        }
    	$GLOBALS['REASON_FOR_BAN'] = "UNAUTHORISED_FILE_REQUEST";
        return 0;
    }
    //              
    //              
    //              
    if (preg_match("/xmlrpc.php/i", $request) == 1 || preg_match("/xmlprc.php/i", $request) == 1) {
        $GLOBALS['REASON_FOR_BAN'] = "XMLRPC_REQUEST_FAIL";
        return 0;
    }
    //              
    //              
    //              
    if (preg_match("/wp-config.php/", $request) == 1 || preg_match("/wp-config-sample.php/", $request) == 1) {
        $GLOBALS['REASON_FOR_BAN'] = "WP_CONFIG_FAIL";
        return 0;
    }
    //              
    //              
    //              
    //  Dear User:- Nobody should be allowed to circumvent our Cloudflare protection layer and reach our raw IPv4 addresses...
    //              But this is only true if the Hit is NOT authorised.  So let's BAN THEM!  
    //              
    if ($_SERVER['base_path'] === 'deadend.org' && $lxAuthorised !== true) {
        return 0;
    }


    //  Dear User:- OK,  we've come this far which means EITHER we're going to process a REAL WordPress request or we're going to reach a 404...
    //              So let's check and see if the REQUEST has previously added 404 records in the 404 database....  
    //              
    if ($GLOBALS['PARD_ARE_WE_USING_SELF_LEARNING'] === 'YES') {
        if ($lxAuthorised === true) {
            // return 999; //  999 = good to go
            //              
            //  Dear User:- If we're an Authorised user of the WordPress/PhpMyAdmin system,  proceed without visiting the 404 Anti Phishing Self Learning Algorithm.
            //              After all,  it is possible that we ourselves create a legitimate 404 error by mistake,  so we SHOULD know about that.
            //              
        } 
        velodata_check_for_not_found();
    }
    return 999; //  999 = good to go
}

// END OF MAIN SCAN LOOP




function velodata_you_didnt_get_banned() {
    //  Dear User:- The purpose of this function is to visually test the scanning logic which decides whether a IP address should be banned or not.
    //              If YOUR ip address is part of the Trusted Ring of approved ip addresses,  you will see this html screen instead of being banned.
    //              This gives you the ability to test a known problematic URL/useragent/referrer etc etc without getting banned yourself.
    //              
    //              If you ever do get banned,  you only get banned on Ports 80 and 443.  This means you can still do Operating System administration.
    //              Worst case scenario,  if you (or your staff) have access to the operating system you can issue the commaned :  iptables -f
    //              The 'iptables -F' command flushes all the dynamic firewall rules and the velodata software starts banning from scratch again.
    //              
    echo '<meta name="robots" content="noindex,nofollow,noarchive,nosnippet,noodp,noydir">';
    echo '<h1>Normally you would get banned at this point,  but your IP address is whitelisted for this domain.</h1>';
    echo '<p>However,  this script was called by a failed URL trigger in the .htaccess file.</p>';
    echo '<p></p>';
    echo '<p>the value of PREPEND_PATH = ' . PREPEND_PATH . '</p>';
    echo '<p>Your IP address = ' . $GLOBALS['ip'] . '</p>';
    echo '<p>Your Notification email address = ' . $GLOBALS['PARD_EMAIL_NOTIFICATION_ADDRESS'] . '</p>';
    echo '<p>Your offending URI = ' . velodata_sanitize($_SERVER['HTTP_HOST']) . $GLOBALS['request'] . '</p>';
    echo '<p>Internal Domain = ' . $_SERVER['base_path'] . '</p>';
    echo '<p>Reason for Ban = ' . $GLOBALS['REASON_FOR_BAN'] . '</p>';
    echo '<p></p>';
    //echo '<p>If you have any question please contact <a href="mailto:' . $default_email .'">The Webmaster</a>.</p>';
    echo '<p>If you have any question please <a href="mailto:' . $GLOBALS['PARD_EMAIL_REPLY_ADDRESS'] . '">contact the Administrator</a>.</p>';
    exit;
}




function velodata_sorry_but_you_got_banned() {
    //              
    //  Dear User:- The purpose of this function is to ban  (or deflect via the 127.0.0.1 REDIRECT option) any request and it's associated 0/24 block of ip addresses.
    //              If your ip address is part of the Trusted Ring of approved ip addresses,  you should never reach this function  -  like ever!
    //              You can create up to five trusted ip address blocks in the associated INI file which gets referred to with every request.
    //              
    //              Scenario One  -  you accidentally get banned at the IP level and your website does NOT sit behind Cloudflare
    //              Well the good news is you only get banned in IPTABLES on Ports 80 and 443.  This means you can still do Operating System administration. 
    //              Worst case scenario,  if you (or your staff) have access to the operating system you can issue the commaned :  iptables -F
    //              The 'iptables -F' command flushes all the dynamic firewall rules and the velodata software starts from scratch again.
    //              
    //              Scenario Two  -  you accidentally get banned at the IP level and your website DOES sit behind CloudflareHowever,  
    //              The good news is you can remove your banning by visiting your Cloudlfare account and negotiating to Cloudflate > Your Website > Firewall > Tools
    //              That's the location where ip addresses get banned,  all you need to do is look (or search for) your IP address and then you delete that record!
    //              
    //              OK,  before anything else,  let's check the separate category instructions regarding what to do for each type of transgression.
    //              
    //              
    //
    //  
    //  Dear User:  The next bit of logic allows us to distinguish between IPv4 format or IPv6 format.
    //              We need to do this because they require different slightly different banning instructions to the Firewall
    //              The default assumption is IPv4.  Only change that if we are definitely using IPv6.
    // 	 
    $isValidIPv6 = filter_var($GLOBALS['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
    if ($isValidIPv6 === $GLOBALS['ip']) {
        $GLOBALS['PARD_IP_TYPE'] = 'IPv6';
    }
    if ( $GLOBALS['PARD_IP_TYPE'] === 'IPv6' ) {
		// if we reached this point,  it' means the remote user did something that deserves a banning...
        header("HTTP/1.1 407 PREPEND Blackhole Software");
        die;
		// header("Location: http://127.0.0.1");
		// die();
    } 
	if ( $GLOBALS['PARD_IP_TYPE'] === 'IPv4' ) {
        header("HTTP/1.1 408 PREPEND Blackhole Software");
        // die;


	    $mask = '255.255.255.0';
	    $wcmask = long2ip(~ip2long($mask));
	    $subnet = long2ip(ip2long($GLOBALS['ip']) & ip2long($mask)) . '/24';
	    if ( $subnet === '0.0.0.0/24' ) {
	        die;
	    }
	    //              
	    //  Dear User:- OK,  we know for sure we're going to ban this IP Address subnet,  let's first cross check our DAT file to see if we've already done this in the past.
	    //              By doing this,  we prevent multiple entries in the IPTABLES rule set.  Please note that Cloudflare prevents you from creating multiple entries.
	    //              
	    //  Dear User:- Let's ban the IP address subnet either at the IPTABLES Operating System level,  and also at the Cloudflare level if specified.
	    //
        $m0cloudflareproceed === false;
	    if ( $m0cloudflareproceed === true && 3 < 2) {
	        $command = '';
	        $command = $command . 'sudo curl -s -X POST "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules"' ;
	        $command = $command . ' -H "X-Auth-Email: ' . $GLOBALS['PARD_CLOUDFLARE_AUTH_EMAIL'] . '" -H "X-Auth-Key: ' . $GLOBALS['PARD_CLOUDFLARE_API_KEY'] . '" ' ;
	        $command = $command . ' -H "Content-Type: application/json" ' ;
	        $command = $command . '--data \'{"mode":"block","configuration":{"target":"ip_range","value":"' . $subnet . '"},"notes":"' . $GLOBALS['REASON_FOR_BAN'] . '"}\'';
	        $output = shell_exec("$command");    
	    } 
	    //
	    //  Dear User:- Uncomment the next lineif you want to activate the "Have we been banned previously" bit of logic.
	    //              This function checks to see if our IP address has already been entered into the blackhole.dat
        //              If the Request IP already exists in blackhole.dat file,  this process DIES.
		velodata_have_we_been_banned_already($GLOBALS['ip']);
	    //  
	    //  Dear User:- The next line is where we write a banning to the IPTABLES command...  let Cloudflare (above) do it it instead
    	$output = shell_exec('sudo iptables -A INPUT -s ' . $subnet . ' -p tcp -m multiport --dports 80,443 -j DROP');
	    //  
    }
    //              
    //              
    //  Dear User:- Next,  let's write a new entry in the supporting blackhole.dat file.  This file is usually kept in the same directory as the velodata software.
    //
    $filename = PREPEND_PATH . 'blackhole.dat';
    $fp = fopen($filename, 'a+');
    fwrite($fp, $GLOBALS['date'] . ' | ' . $GLOBALS['REASON_FOR_BAN'] . ' | ' . $GLOBALS['ip'] . ' | ' . $GLOBALS['method'] . ' ' . $GLOBALS['m0_BASE_PATH'] . $_SERVER['REQUEST_URI'] . ' | ' . $GLOBALS['ua']  . "\n");
    fclose($fp);
    //              
    //              
    //  Dear User:- Next,  let's prepare some background information to include in the notification email which let's us know this user was banned...
    //
    $recent_hits = shell_exec("sudo tail -100 /var/log/apache2/other_vhosts_access.log | awk '($2 ~ /" . $GLOBALS['ip'] . "/)' | awk '{ print }'");
    //echo "<pre>$output</pre>";    
    $whois = velodata_blackhole_whois();
    $host = $GLOBALS['ip'];
    if (filter_var($GLOBALS['ip'], FILTER_VALIDATE_IP)) {
        $host = velodata_sanitize(gethostbyaddr($GLOBALS['ip']));
    }
    //
    //
    //
    $message = $GLOBALS['date'] . "\n\n";
    $message .= 'URL Request: ' . $GLOBALS['request'] . "\n";
    $message .= 'IP Address: ' . $GLOBALS['ip'] . "\n";
    $message .= 'Subnet: ' . $subnet . "\n";
    $message .= 'Host Name: ' . $host . "\n";
    $message .= ' ' . "\n\n";
    $message .= 'Internal Domain: ' . $_SERVER['base_path'] . "\n";
    $message .= 'Offending URL: ' . $GLOBALS['m0_BASE_PATH'] . $_SERVER['REQUEST_URI'] . "\n";
    $message .= 'Reason For Ban: ' . $GLOBALS['REASON_FOR_BAN'] . "\n";
    $message .= 'User Agent: ' . $GLOBALS['ua'] . "\n";
    $message .= 'Referrer: ' . $GLOBALS['referrer'] . "\n";
    $message .= ' ' . "\n\n";
    $message .= 'Recent Hits: ' . "\n\n" . $recent_hits . "\n\n";
    $message .= 'GeoIP Lookup: ' . "\n\n" . 'https://whatismyipaddress.com/ip/' . $GLOBALS['ip'] . "\n\n";
    $message .= 'Whois Lookup: ' . "\n\n" . $whois . "\n\n";
    //              
    //  Dear User:- Next,  let's send a special header response to the client request.  4 0 6 is a rarely used response  -  that's why we use it to indicate this user got banned by Velodata.
    //
    //              
    //  Dear User:- Next,  let's make a decision...  do you want to send a notification email,  or perhaps not?
    //              Comment out the next line if you start getting tired of the BAN emails....  you can undo your decision at any time. 
    //
    if ($GLOBALS['PARD_ARE_WE_SENDING_NOTIFICATIONS'] === 'YES') {
        mail ($GLOBALS['PARD_EMAIL_NOTIFICATION_ADDRESS'], $_SERVER['base_path'] . ' ' . $GLOBALS['ip'] . '  banned', $message, 'From: '. PREPEND_FROM);
    } 
    //              
    //  Dear User:- Finally,  do you want the user to receive anything in the form of HTML which explains why they've been banned.
    //              Comment out the next line if you don't want BANNED hackers to get any feedback as to WHY they've been banned,,,,,
    //
    // if ($GLOBALS['PARD_ARE_WE_PROVIDING_FEEDBACK'] !== 'YES') {
        die;  //  don't give the malicious offender an explanation  -  simply kill the process and proceed no further....
    // } 
    //
    //
    //
    ?><!DOCTYPE html>
    <html lang="en-US">
        <head>
            <title>Welcome to the Blackhole!</title>
            <meta name="robots" content="noindex,nofollow,noarchive,nosnippet,noodp,noydir">
            <style>
                body { color: #fff; background-color: #851507; font: 14px/1.5 Helvetica, Arial, sans-serif; }
                #blackhole { margin: 20px auto; width: 700px; }
                pre { padding: 20px; white-space: pre-line; border-radius: 10px; background-color: #b34334; }
                a { color: #fff; }
            </style>
        </head>
        <body>
            <div id="blackhole">
                <h1>Sorry,  but you have been banned!</h1>
                <p>
                    This site’s <a href="/robots.txt">robots.txt</a> file explicitly forbids your presence at this location. 
                    The following Whois data will be reviewed carefully. If it is determined that you suck, you will be banned from this site. 
                    If you think this is a mistake, <em>now</em> is the time to <a href="mailto:<?php echo $GLOBALS['PARD_EMAIL_REPLY_ADDRESS']; ?>">contact the Administrator</a>.
                </p>
                <h3>
                    Your IP Address is <?php echo $GLOBALS['ip']; ?><br>
                    Your Host Name is <?php echo $host; ?>
                </h3>
                <pre>WHOIS Lookup for <?php echo $GLOBALS['ip'] . "\n" . $GLOBALS['date'] . "\n\n" . $whois; ?></pre>
                <p>
            </div>
        </body>
    </html><?php
    exit;
}





function blackhole_main_program() {
    //
    list ($ip, $ua, $request, $referrer, $protocol, $method, $date, $time, $ini_array, $ini_bypass_xword, $m0_OFFENDING_URI, $m0_BASE_PATH, $lxHTTP_REASON) = velodata_blackhole_get_vars();
    //
    $badbot = velodata_scan_the_request($ip, $ua, $request, $referrer, $ini_bypass_xword, $lxHTTP_REASON);
    //  
    //  Dear User:  The function named velodata_scan_the_request() should,  under normal operation,  return one of three values.  998,  or 999,  or 0 
    //              Our goal is to give legitimate users a chance to log in without drama with a correct Velodata Bypass Code if they are using VIP Access control.
    //  
    //              999 = totally good to,  return program flow immediately to the downstream processing and leave the prepend Blachole Cyber Security software.
    //              998 = almost good to go.  The user failed to provide a Velodata Bypass Code,  however,  their IP address is in the Trusted Ring of IP addresses.
    //              000 = This is a bannable offender....  however....  the user won't get banned if the user is in the Trusted Ring of IP addresses.  You can do debug tests this way.
    //  


    if ($badbot === 999) {
        return;  //  999 = good to go
    }

    if ($badbot === 998) {
        //  
        //  Dear User:  This subroutine gets called when the Velodata Bypass Code is not net in the user's cookie header.
        //              Our goal is to give legitimate users a chance to try again with the correct Velodata Bypass Code
        //  
        //  
        header("HTTP/1.1 200 PREPEND Blackhole Software");
?>
    <!DOCTYPE html>
    <html lang="en-US">
        <head>
            <title>Welcome to Blackhole!</title>
            <meta name="robots" content="noindex,nofollow,noarchive,nosnippet,noodp,noydir">
            <style>
            #blackhole { margin: 20px auto; width: 700px; }
            pre { padding: 20px; white-space: pre-line; border-radius: 10px; background-color: #b34334; }
            a { color: #fff; }
            </style>
            <style>
                <?php
                $css_data = file_get_contents(PREPEND_PATH . "blackhole.min.css");
                echo htmlentities($css_data);
                ?>
            </style>
        </head>
        <body>
            <div id="blackhole">
                <?php
                echo '<meta name="robots" content="noindex,nofollow,noarchive,nosnippet,noodp,noydir">', PHP_EOL;
                echo '<h1></h1>', PHP_EOL;
                echo '<h1>Cybersecurity Bypass Code Required.</h1>', PHP_EOL;
                echo '<p></p>';
                echo '<p>Your IP address = ' . $ip . '</p>';
                echo '<p>Your failed URL = ' . velodata_sanitize($_SERVER['HTTP_HOST']) . $request . '</p>';
                echo '<p></p>';
                echo '<p>Reason for stopping = ' . $GLOBALS['REASON_FOR_BAN'] . '</p>';
                echo '<p></p>';
                echo '<p>If you have any question please <a href="mailto:' . $GLOBALS['PARD_EMAIL_REPLY_ADDRESS'] . '">contact the Administrator</a>.</p>';
                ?>
                <form class="form-horizontal">
                    <fieldset>

                        <!-- Form Name -->
                        <legend>Welcome to our <?php echo $GLOBALS['SERVER_NAME'] ?> cybersecurity form.</legend>

                        <p>If you think you know the correct Bypass Code,  try entering it here.</p>

                        <!-- Text input-->
                        <div class="form-group">
                            <label class="col-md-4 control-label" for="textinput">Please enter your Bypass Code</label>  
                            <div class="col-md-4">
                                <input id="bypass" name="bypass" type="text" placeholder="placeholder" class="form-control input-md">
                                <span class="help-block">help</span>  
                            </div>
                        </div>

                        <!-- Button (Double) -->
                        <div class="form-group">
                            <label class="col-md-4 control-label" for="button1id">Double Button</label>
                            <div class="col-md-8">
                                <button id="button1id" name="button1id" class="btn btn-success">Good Button</button>
                                <button id="button2id" name="button2id" class="btn btn-danger">Scary Button</button>
                            </div>
                        </div>

                    </fieldset>
                </form>
            </div>
        </body>
    </html>
<?php
        exit;
        return false;
    }

    $badbot = 0;
    if (velodata_is_IP_whitelisted($ip)) {
        $badbot = -1;
    }
    if (velodata_spiderbot_whitelist($ua)) {
        $badbot = -1;
    }


    /*

      Description:  blackhole_checkbot() returns three values. 

      999 = Good to go,  a valid request
      999 = Good to go,  well amost except the user failed to provide a valid Velodata Bypass Code.
      -1  = You didn't get banned because your IP addresss is whitelisted.  This option exists so that you can test URL's which would otherwise be banned for everyone else.
       0  = OK,  ban the IP address and send an email to your pre-defined notifications email address.
      +1  = IP Address is already banned,  send some HTML to the bad caller and exit/die the script.

      So it's pretty smart,  if we kill the script,  that's the end of CPU usage,  and that's the goal.

    */


    if ($badbot === -1) {
        velodata_you_didnt_get_banned();
        die;
    }
    if ($badbot === 0) {
        velodata_sorry_but_you_got_banned();
        die;
    }
    if ($badbot > 0) {
        echo '<meta name="robots" content="noindex,nofollow,noarchive,nosnippet,noodp,noydir">';
        echo '<h1>You have been previously banned from this domain</h1>';
        echo '<p>If you think there has been a mistake, <a href="' . PREPEND_CONTACT . '">contact the administrator</a> via proxy server.</p>';
        exit;
    } 
    return false;
}






function velodata_have_we_been_banned_already($ip) {
    $filename = PREPEND_PATH . 'blackhole.dat';
    $fp = fopen($filename, 'r') or die('<p>Error: Data File</p>');
    while ($line = fgets($fp)) {
        //  if ( preg_match("/ \| /", $line) ) {
        if ( strpos($line, " | ") !== false) {            
            $ua_logged = explode(' | ', $line, 4);
            //  
            //  Dear User:  This function is designed to prevent multiple entries being added for the same IP subnet to the official .dat file.
            //              It takes a little while for a new firewall rule to become active,  hence,  there's a window of opportunity for a bad actor to keep sending bad hits.
            //              
            //              Before anything else,  let's calculate the subnet for this request.  For example,  1.128.17.49 becomes 1.128.17.0/24
            //              We can then analyse if a previous IP ban is in the same subnet as the current IP address.
            //              For the record,  unless you change the programming code which creates entries in the .dat file  (don't EVER do that!) then $ua_logged[2] will always be the previous banned IP address.
            //              And the delimiter between fields in the .dat file equals [space] + [pipe symbol] + [space] which equals " | "
            //              In the code below,  the console_log entries are for debugging purposes.  Use a browser in Developer Mode to see their output.
            //  
            $mask = '255.255.255.0';
            $subnet = long2ip( ip2long( $ua_logged[2] ) & ip2long( $mask ) ) . '/24';
            if (velodata_valid_iprange( $GLOBALS['ip'], $subnet ) === true) {
                fclose( $fp );
                header("HTTP/1.1 403 PREPEND Blackhole Software");
                console_log('$ua_logged[0] = ' . $ua_logged[0]);
                console_log('$ua_logged[1] = ' . $ua_logged[1]);
                console_log('$ua_logged[2] = ' . $ua_logged[2]);
                console_log('$ua_logged[3] = ' . $ua_logged[3]);
                echo '<meta name="robots" content="noindex,nofollow,noarchive,nosnippet,noodp,noydir">';
                echo '<h1>Your IP Address has been previously banned from this domain.</h1>';
                echo '<p>If you think there has been a mistake, <a href="' . PREPEND_CONTACT . '">contact the administrator</a> via email.</p>';
                exit;
                die;
            }
        }
    }
    fclose($fp);
}






function velodata_spiderbot_whitelist($ua) {
    //  if (preg_match("/(a6-indexer|adsbot-google|ahrefsbot|aolbuild|apis-google|baidu|bingbot|bingpreview|butterfly|cloudflare|cortex|duckduckgo|embedly|facebookexternalhit|facebot|googlebot|ia_archiver|linkedinbot|mediapartners-google|msnbot|netcraftsurvey|outbrain|pinterest|quora|rogerbot|showyoubot|slackbot|slurp|sogou|teoma|tweetmemebot|twitterbot|uptimerobot|urlresolver|vkshare|w3c_validator|wordpress|wp rocket|yandex)/i", $ua)) {
    if (preg_match("/(bingbot|bingpreview|cortex|duckduckgo|Googlebot-Image|Googlebot|facebookexternalhit|letsencrypt|LinkedInBot|msnbot|Twitterbot|wordpress)/i", $GLOBALS['ua'])) {
        return true;
    }
    return false;
}


function velodata_referrer_whitelist($referrer) {
    if ( preg_match("/http(s)?:\/\/" . $GLOBALS['SERVER_NAME'] . "/", $referrer) ) {
        return true;
    }
    if ( velodata_is_IP_whitelisted( $GLOBALS['ip'] ) && preg_match("/www\.west\-wind\.com/", $referrer)) {
        return true;
    }
    return false;
}


function velodata_if_wordpress_useragent($ua) {
    if (preg_match("/WordPress/", $ua) && preg_match("/http(s)?:\/\/" . $GLOBALS['SERVER_NAME'] . "/", $ua)) {
        return true;
    }
    return false;
}

function prepend_ban_on_sight_blacklist($ua) {
    if (preg_match("/(petalbot|zgrab|ZoominfoBot)/i", $ua)) {
        return true;
    }
    //  Now we do a check to see if this request is the Internet Archive Way Back Machine ip address range.
    //  The Way Back Machine is NOT an honest player.  It delibarately makes requests with fake User Agents to avoid anti-scraping rules.  So we BAN their entire IP range. 
    $test_range = "207.241.224.0/20";  
    if ( velodata_valid_iprange($GLOBALS['ip'], $test_range) === true) {
        $GLOBALS['REASON_FOR_BAN'] = "UNAUTHORISED_WAY_BACK_MACHINE_REQUEST";
        return true;
    }
    return false;
}



function velodata_is_IP_whitelisted($ip) {

    // return false;
    $mystring = $ip;
    $findme = 'a';
    $pos = strpos($mystring, $findme);


    $test_range = $GLOBALS['PARD_TRUSTED_RANGE_01'];
    if (velodata_evaluate_trusted_ip( $test_range) ) {
        if ( velodata_valid_iprange($ip, $test_range) === true) {
            return true;
        }
    }
    $test_range = $GLOBALS['PARD_TRUSTED_RANGE_02'];
    if (velodata_evaluate_trusted_ip( $test_range) ) {
        if ( velodata_valid_iprange($ip, $test_range) === true) {
            return true;
        }
    }
    $test_range = $GLOBALS['PARD_TRUSTED_RANGE_03'];
    if (velodata_evaluate_trusted_ip( $test_range) ) {
        if ( velodata_valid_iprange($ip, $test_range) === true) {
            return true;
        }
    }
    $test_range = $GLOBALS['PARD_TRUSTED_RANGE_04'];
    if (velodata_evaluate_trusted_ip( $test_range) ) {
        if ( velodata_valid_iprange($ip, $test_range) === true) {
            return true;
        }
    }
    $test_range = $GLOBALS['PARD_TRUSTED_RANGE_05'];
    if (velodata_evaluate_trusted_ip( $test_range) ) {
        if ( velodata_valid_iprange($ip, $test_range) === true) {
            return true;
        }
    }
    return false;
}



function velodata_valid_iprange($ip, $range) {
    if (strpos($range, '/') === false) {
        $range .= '/32';
    }
    // $range is in IP/CIDR format 
    list( $range, $netmask ) = explode('/', $range, 2);
    $range_decimal = ip2long($range);
    $ip_decimal = ip2long($ip);
    $wildcard_decimal = pow(2, ( 32 - $netmask)) - 1;
    $netmask_decimal = ~ $wildcard_decimal;
    //	console_log('$range = ' . $range);
    //	console_log('$netmask = ' . $netmask);
    //	console_log('$range_decimal = ' . $range_decimal);
    //	console_log('$ip_decimal = ' . $ip_decimal);
    //	console_log('$wildcard_decimal = ' . $wildcard_decimal);
    //	console_log('$netmask_decimal = ' . $netmask_decimal);
    if ($ip_decimal >= $range_decimal && $ip_decimal <= $range_decimal + $wildcard_decimal) {
        return true;
    }

    return false;
    
}

function velodata_sanitize($string) {

    $string1 = trim($string);
    $string2 = strip_tags($string1);
    $string3 = htmlspecialchars($string2, ENT_QUOTES, 'UTF-8');
    $string4 = str_replace("\n", "", $string3);
    $string5 = trim($string4);

    return $string5;
}

function velodata_blackhole_get_ip() {

    $ip = velodata_blackhole_evaluate_ip();

    if (preg_match('/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/', $ip, $ip_match)) {

        $ip = $ip_match[1];
    }

    return velodata_sanitize($ip);
}

function velodata_blackhole_evaluate_ip() {

    $ip_keys = array('HTTP_CF_CONNECTING_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_X_REAL_IP', 'HTTP_X_COMING_FROM', 'HTTP_PROXY_CONNECTION', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'HTTP_COMING_FROM', 'HTTP_VIA', 'REMOTE_ADDR');

    if ( isset($_SERVER['HTTP_HOST']) ) {
        if ( preg_match('/localhost/', $_SERVER['HTTP_HOST']) === 1) {
        	$ip = "127.0.0.1";
        	return $ip;
        }
    }

    foreach ($ip_keys as $key) {

        if (array_key_exists($key, $_SERVER) === true) {

            foreach (explode(',', $_SERVER[$key]) as $ip) {

                $ip = trim($ip);

                $ip = velodata_blackhole_normalize_ip($ip);

                if (velodata_blackhole_validate_ip($ip)) {
                    return $ip;
                }
            }
        }
    }

    return 'Error: Invalid Address';
}

function velodata_blackhole_normalize_ip($ip) {


    if (strpos($ip, ':') !== false && substr_count($ip, '.') == 3 && strpos($ip, '[') === false) {
        // IPv4 with port (e.g., 123.123.123:80)
		
        $ip = explode(':', $ip);
        $ip = $ip[0];
    } else {

        // IPv6 with port (e.g., [::1]:80)
		
        $ip = explode(']', $ip);
        $ip = ltrim($ip[0], '[');
    }

    return $ip;
}

function velodata_blackhole_validate_ip($ip) {


    $options = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;

    $filtered = filter_var($ip, FILTER_VALIDATE_IP, $options);

    if (!$filtered || empty($filtered)) {

        if (preg_match("/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/", $ip)) {
            return $ip; // IPv4
        } elseif (preg_match("/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/", $ip)) {
            return $ip; // IPv6
        }

        error_log('Invalid IP Address: ' . $ip);

        return false;
    }

    return $filtered;
}





function velodata_evaluate_trusted_ip( $test_ip ) {

    if ( is_null( $test_ip ) ) {
        return false;        
    }
    if ( isset( $test_ip ) ) {
        //console_log('$test_ip is set! The value = ' . $test_ip );        
        if ( $test_ip  === ""  ) {
            //console_log('$test_ip = ""');        
            return false;        
        } 
        if (strpos($test_ip, '.') !== false && substr_count($test_ip, '.') == 3 && strpos($test_ip, '[') === false) {
            // IPv4 with possible subnet mask (e.g., 123.123.123.0/24)
            $test_ip_array = explode('.', $test_ip);

            //console_log('Octet 1 = ' . $test_ip_array[0] );        
            if (preg_match("/^([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/", $test_ip_array[0])) {
            } else {   
                //console_log('Octet 1 is NOT a valid IP Address Octet' );        
                return false;
            }

            //console_log('Octet 2 = ' . $test_ip_array[1] );        
            if (preg_match("/^([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/", $test_ip_array[1])) {
            } else {   
                //console_log('Octet 2 is NOT a valid IP Address Octet' );        
                return false;
            }

            //console_log('Octet 3 = ' . $test_ip_array[2] );        
            if (preg_match("/^([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/", $test_ip_array[2])) {
            } else {   
                //console_log('Octet 3 is NOT a valid IP Address Octet' );        
                return false;
            }

            //console_log('Octet 4 = ' . $test_ip_array[3] );        
            if (preg_match("/^([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/", $test_ip_array[3])) {
                return true;
            } else {   
                if (preg_match("/^0\/(1[0-9]|2[0-9]|3[0-2])$/", $test_ip_array[3])) {
                    //console_log('Octet 4 is a VALID subnet mask' );        
                    return true;
                } 
                //console_log('Octet 4 is NOT a valid IP Address Octet' );        
                return false;
            }
        } else {
            //console_log('$test_ip does NOT adhere to a valid IPv4 Octet Structure.  Test Failed.' );        
            return false;
        }
    }

return 'Error: Invalid Address';
}



function velodata_blackhole_whois() {
    //return 999; //  999 = good to go
    $msg = '';
    $extra = '';
    $buffer = '';
    $server = 'whois.arin.net';

    $ip = velodata_blackhole_get_ip();

    if (!$ip = gethostbyname($ip)) {

        $msg .= 'Can’t perform lookup without an IP address.' . "\n\n";
    } else {

        if (!$sock = fsockopen($server, 43, $num, $error, 20)) {

            unset($sock);
            $msg .= 'Timed-out connecting to $server (port 43).' . "\n\n";
        } else {

            // fputs($sock, "$ip\n");
            fputs($sock, "n $ip\n");
            $buffer = '';
            while (!feof($sock))
                $buffer .= fgets($sock, 10240);
            fclose($sock);
        }

        if (stripos($buffer, 'ripe.net')) {

            $nextServer = 'whois.ripe.net';
        } elseif (stripos($buffer, 'nic.ad.jp')) {

            $nextServer = 'whois.nic.ad.jp';
            $extra = '/e'; // suppress JaPaNIC characters
        } elseif (stripos($buffer, 'registro.br')) {

            $nextServer = 'whois.registro.br';
        }

        if (isset($nextServer)) {

            $buffer = '';
            $msg .= 'Deferred to specific whois server: ' . $nextServer . '...' . "\n\n";

            if (!$sock = fsockopen($nextServer, 43, $num, $error, 10)) {

                unset($sock);
                $msg .= 'Timed-out connecting to ' . $nextServer . ' (port 43)' . "\n\n";
            } else {

                fputs($sock, $ip . $extra . "\n");
                while (!feof($sock))
                    $buffer .= fgets($sock, 10240);
                fclose($sock);
            }
        }

        $replacements = array("\n", "\n\n", "");
        $patterns = array("/\\n\\n\\n\\n/i", "/\\n\\n\\n/i", "/#(\s)?/i");
        $buffer = preg_replace($patterns, $replacements, $buffer);
        $buffer = htmlentities(trim($buffer), ENT_QUOTES, 'UTF-8');

        // $msg .= nl2br($buffer);
        $msg .= $buffer;
    }

    return $msg;
}




function velodata_check_for_not_found() 
{
    //  Dear User:- Let's check and see if this request triggers the BAN ON SIGHT Blacklist.
    //              If so,  ban or deflect this request....
    //              
	if (prepend_ban_on_sight_blacklist($GLOBALS['ua'])) {
        if (velodata_is_IP_whitelisted($GLOBALS['ip'])) {
            velodata_you_didnt_get_banned();
            die;
        } else {
            velodata_sorry_but_you_got_banned();
            die;
        }
    }
	//  
    //  Dear User:-  The purpose of this function is to test if this request is a known 'previous 404' response in the relevant data table.
    //               This function only gets called if the official scanning logic did NOT return program flow to the WordPress engine.
    //               If this function determines the request is a 'phishing request' the user gets banned or deflected.  (You choose).
    //  
    $request_only = $GLOBALS['request']; 
    if (preg_match("/\?/", $GLOBALS['request']) == 1) {
        //              
        //  Dear User:- This subroutine strips the query string parameter from the original URL request for internal scanning purposes.
        //              
        //              
        $original_request = $GLOBALS['request']; 
        $query_string = '?' . $GLOBALS['query_string'];
        $replace_string = '';
        $request_only = str_replace($query_string, $replace_string, $original_request);
        //  console_log('$REQUEST_URI_ORIGINAL = ' . $original_request); 
        //  console_log('$QUERY_STRING = ' . $_SERVER['QUERY_STRING']);
        //  console_log('$REQUEST_URI_TRUNCATED = ' . $new_request);
    }

    if ( $request_only === '/') {
        //  
        //  Dear User:-  If the request is for the domain root directory (and nothing else) that's clearly never going to be a 404 in the real world so let's get out of here.
        //  
        return 999; //  999 = good to go
    }


    $sql_details = velodata_mysql_login_details();
    $db = velodata_open_db($sql_details);
    //$pdoSQL = "SELECT COUNT(url) AS total_Count FROM `wp_redirection_404` WHERE url LIKE '%" . $request_only . "%'";
    $pdoSQL = "SELECT COUNT(url) AS total_Count FROM `wp_redirection_404` WHERE url = '" . $request_only . "'";
    $pdoStmt1 = $db->prepare($pdoSQL);
    $pdoStmt1->execute();
    $resultArray = $pdoStmt1->fetch(PDO::FETCH_ASSOC);
    $lntotal_Count = intval($resultArray['total_Count']);
    

    if ($lntotal_Count === 0 || preg_match("/js\.map/", $GLOBALS['request']) == 1 ) {
        return 999; //  999 = good to go
    }


    if (velodata_spiderbot_whitelist($GLOBALS['ua'])) {
        //  
        //  Dear User:-  We can live with an approved spiderbot like Google asking for a 404 request.  There's no menace involved so simply die the process.
        //               
        die;
    }
    

    if ( velodata_referrer_whitelist($GLOBALS['referrer']) ) {
        //  
        //  Dear User:-  If we got this far in the code it means (a) we've already searched the 404 Data Table and we got a hit,  and (b) it also means the Referrer field has quoted your SERVER HOST NAME 
        //               in the Referrer field in the URI request.  That means there MIGHT be an old WordPress link in your content.  So let's do some extra logic checking.
        //               Under normal circumstances,  WordPress NEVER produces a referrer field with your SERVER HOST NAME plus a missing URL in the referrer field  -  WordPress doesn't work that way.
        //               Hence,  if the REFERRER field contains the 404 request within the referrer field,  it's a malicious actor  -  that's what they often do to spoof the system.
        //  
        if (strpos($GLOBALS['referrer'], $GLOBALS['request']) > 0) {
            //  continue to next section,  this is a bad guy trying to trick the system....
            console_log("<p>This is a malicious 404 request. The REFERRER string contains the 404 REQUEST string.</p>");
        } else {
            //  this is a legitimate 404 most likely caused by an old link in the WordPress data somewhere....
            //  header("HTTP/1.1 404 PREPEND BLACKHOLE SOFTWARE");
            die;
        }
    }


    $GLOBALS['REASON_FOR_BAN'] = "MAXIMUM NUMBER OF 404 ATTEMPTS";
    if (velodata_is_IP_whitelisted($GLOBALS['ip'])) {
        //  return 999; //  999 = good to go
        velodata_you_didnt_get_banned();
        die;
    } else {
        velodata_sorry_but_you_got_banned();
        die;
    }
}

function velodata_open_db($conn) {
    if (is_array($conn)) {
        return velodata_sql_connect($conn);
    }

    return $conn;
}

function velodata_sql_connect($sql_details) {
    try {
        $db = @new PDO(
                "mysql:host={$sql_details['host']};dbname={$sql_details['db']}", $sql_details['user'], $sql_details['pass'], array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
        );
    } catch (PDOException $e) {
        velodata_fatal_errormsg(
                "An error occurred while connecting to the database. " .
                "The error reported by the server was: " . $e->getMessage()
        );
    }

    return $db;
}

function velodata_fatal_errormsg($msg) {
    echo json_encode(array(
        "error" => $msg
    ));

    exit(0);
}

function velodata_mysql_login_details() {
    return array(
        'user' => $GLOBALS['ini_PARD_DB_USER'],
        'pass' => $GLOBALS['ini_PARD_DB_PASSWORD'],
        'db'   => $GLOBALS['ini_PARD_DB_NAME'],
        'host' => $GLOBALS['ini_PARD_DB_HOST']
    );
}











				
			

How Can We Help?

At Velodata your privacy is paramount.  We never share customer data with ANYONE.

Feel free to answer any or all of the fields in this contact form as best as you can.  You don’t have to fill them all in, but if you do, we can be efficient right from the word go.

Step 1:  Enter some contact details so we can get back to you
Step 2:  Give us some info about your IT systems to help us help you.
Step 3:  Confirm you’re a human and then submit!

HOW CAN WE HELP?

At Velodata your privacy is paramount.  We never share customer data with ANYONE.  Our goal is to help make your website and your webservers as secure as possible.

PHONE ENQUIRIES

0408 572 055

EMAIL ENQUIRIES

VELODATA

Specialists in Wordpress Cyber Security

IVAN JULIAN  –  VELODATA

GOLD COAST,  QUEENSLAND,  4216

P.O. BOX 359 RUNAWAY BAY,  QLD,  4216

VELODATA

Specialists in Wordpress Cyber Security

DOWNLOAD THE SOFTWARE

The Blackhole Cyber Security system is free to download and use,  however we do require a valid email address to prevent unlimited hotlinking to our website.

Step 1:  Please enter your name and a valid email address.  Phone Number is optional.
Step 2:  Confirm you’re a human and then click the download button!

Thanks for contacting us. We'll be in touch shortly!

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex.