<?php
/**
 * This file is a part of the CIDRAM package.
 * Homepage: https://cidram.github.io/
 *
 * CIDRAM COPYRIGHT 2016 and beyond by Caleb Mazalevskis (Maikuolan).
 *
 * License: GNU/GPLv2
 * @see LICENSE.txt
 *
 * This file: Default signature bypasses (last modified: 2025.07.27).
 */

/** Prevents execution from outside of the checkFactors method. */
if (!isset($Factors[$FactorIndex])) {
    die('[CIDRAM] This should not be accessed directly.');
}

/** Safety. */
if (!isset($this->CIDRAM['RunParamResCache'])) {
    $this->CIDRAM['RunParamResCache'] = [];
}

/**
 * Define object for these rules for later recall (all parameters inherited from CheckFactors).
 *
 * @param array $Factors All CIDR factors of the IP being checked.
 * @param int $FactorIndex The index of the CIDR factor of the triggered rule.
 * @param string $LN The line information generated by CheckFactors.
 * @param string $Tag The triggered rule's section's name (if there's any).
 */
$this->CIDRAM['RunParamResCache']['bypasses.php'] = function (array $Factors = [], int $FactorIndex = 0, string $LN = '', string $Tag = '') {
    /** Skip processing if the bypasses aren't active. */
    if (!isset($this->Configuration['bypasses'])) {
        return;
    }

    $Bypasses = array_flip(explode("\n", $this->Configuration['bypasses']['used']));

    /**
     * OVH rules (determine which directive the signatures should fall under,
     * since in order to do so, it requires additional checks beyond just the
     * range itself; i.e., checking the hostname).
     */
    if ($Tag === 'OVH Systems') {
        /** Fetch hostname. */
        if (empty($this->CIDRAM['Hostname'])) {
            $this->CIDRAM['Hostname'] = $this->dnsReverse($this->BlockInfo['IPAddr']);
        }

        /** ADSL hostnames (should fall under "spam" directive, since not a cloud service). */
        if (preg_match('~(?:dsl\.ovh|ovhtelecom)\.fr$~i', $this->CIDRAM['Hostname'])) {
            /** Return early if spam signatures aren't set to be blocked. */
            if (!isset($this->Shorthand['Spam:Block'])) {
                return;
            }

            $this->BlockInfo['ReasonMessage'] = $this->L10N->getString('ReasonMessage.Spam');
            if (!empty($this->BlockInfo['WhyReason'])) {
                $this->BlockInfo['WhyReason'] .= ', ';
            }
            $this->BlockInfo['WhyReason'] .= $this->L10N->getString('Short.Spam') . $LN;
            $this->addProfileEntry('Spam');
            if (!empty($this->BlockInfo['Signatures'])) {
                $this->BlockInfo['Signatures'] .= ', ';
            }
            $this->BlockInfo['Signatures'] .= $Factors[$FactorIndex];
            $this->BlockInfo['SignatureCount']++;

            /** Exit. */
            return;
        }

        /** Return early if cloud signatures aren't set to be blocked. */
        if (!isset($this->Shorthand['Cloud:Block'])) {
            return;
        }

        $this->BlockInfo['ReasonMessage'] = $this->L10N->getString('ReasonMessage.Cloud');
        if (!empty($this->BlockInfo['WhyReason'])) {
            $this->BlockInfo['WhyReason'] .= ', ';
        }
        $this->BlockInfo['WhyReason'] .= $this->L10N->getString('Short.Cloud') . $LN;
        $this->addProfileEntry('Cloud');
        if (!empty($this->BlockInfo['Signatures'])) {
            $this->BlockInfo['Signatures'] .= ', ';
        }
        $this->BlockInfo['Signatures'] .= $Factors[$FactorIndex];
        $this->BlockInfo['SignatureCount']++;

        /** Exit. */
        return;
    }

    /**
     * Skip further processing if cloud signatures aren't set to be blocked, or
     * if no section tag has been defined.
     */
    if (!isset($this->Shorthand['Cloud:Block']) || $Tag === '') {
        return;
    }

    /** Amazon AWS bypasses. */
    if ($Tag === 'Amazon.com, Inc') {
        /**
         * AmazonAdBot bypass.
         * @link https://github.com/CIDRAM/CIDRAM/issues/260
         */
        if (isset($Bypasses['AmazonAdBot']) && strpos($this->BlockInfo['UALC'], 'amazonadbot/') !== false) {
            return;
        }

        /** DuckDuckGo bypass. */
        if (isset($Bypasses['DuckDuckBot']) && preg_match('~duckduck(?:go-favicons-)?bot~', $this->BlockInfo['UALC'])) {
            return 4;
        }

        /**
         * Embedly bypass.
         * @link https://github.com/CIDRAM/CIDRAM/issues/80
         */
        if (isset($Bypasses['Embedly']) && strpos($this->BlockInfo['UALC'], 'embedly') !== false) {
            return;
        }

        /**
         * Feedspot bypass.
         * @link https://udger.com/resources/ua-list/bot-detail?bot=Feedspotbot
         */
        if (isset($Bypasses['Feedspot']) && strpos($this->BlockInfo['UA'], '+https://www.feedspot.com/fs/fetcher') !== false) {
            return;
        }

        /**
         * Pinterest bypass.
         * @link https://github.com/CIDRAM/CIDRAM/issues/253
         */
        if (isset($Bypasses['Pinterest']) && strpos($this->BlockInfo['UALC'], 'pinterest') !== false) {
            return;
        }

        /**
         * Redditbot bypass.
         * @link https://github.com/CIDRAM/CIDRAM/issues/243
         */
        if (isset($Bypasses['Redditbot']) && strpos($this->BlockInfo['UALC'], 'redditbot/') !== false) {
            return;
        }

        /**
         * Snapchat bypass.
         * @link https://github.com/CIDRAM/CIDRAM/issues/422
         */
        if (isset($Bypasses['Snapchat']) && preg_match('~developers\.snap\.com/robots$~', $this->BlockInfo['UALC'])) {
            return;
        }
    }

    /** Azure bypasses. */
    if ($Tag === 'Azure') {
        /**
         * Bingbot bypass.
         * @link https://github.com/CIDRAM/CIDRAM/issues/242
         */
        if (isset($Bypasses['Bingbot'])) {
            if (empty($this->CIDRAM['Hostname'])) {
                $this->CIDRAM['Hostname'] = $this->dnsReverse($this->BlockInfo['IPAddr']);
            }
            if (
                preg_match('~^msnbot-\d+-\d+-\d+-\d+\.search\.msn\.com$~i', $this->CIDRAM['Hostname']) ||
                preg_match('~(?:msn|bing)bot|bingpreview~', $this->BlockInfo['UALC'])
            ) {
                $this->addProfileEntry('Bypass flagged');
                $this->CIDRAM['Flag-Bypass-Bingbot-Check'] = true;
                return 4;
            }
        }

        /**
         * DuckDuckGo bypass.
         * @link https://duckduckgo.com/duckduckbot
         */
        if (isset($Bypasses['DuckDuckBot']) && preg_match('~duckduck(?:go-favicons-)?bot~', $this->BlockInfo['UALC'])) {
            return 4;
        }
    }

    /** Google bypasses. */
    if ($Tag === 'Google LLC') {
        /** Googlebot bypass. */
        if (isset($Bypasses['Googlebot'])) {
            if (empty($this->CIDRAM['Hostname'])) {
                $this->CIDRAM['Hostname'] = $this->dnsReverse($this->BlockInfo['IPAddr']);
            }
            if (preg_match('~(?:^|\.)google(?:bot)?\.com$~i', $this->CIDRAM['Hostname'])) {
                return 2;
            }
        }

        /** Google Fiber bypass. */
        if (isset($Bypasses['GoogleFiber'])) {
            if (empty($this->CIDRAM['Hostname'])) {
                $this->CIDRAM['Hostname'] = $this->dnsReverse($this->BlockInfo['IPAddr']);
            }
            if (preg_match('~(?:^|\.)googlefiber\.net$~i', $this->CIDRAM['Hostname'])) {
                return 2;
            }
        }
    }

    /** Huawei Cloud bypasses. */
    if ($Tag === 'Huawei Cloud Service') {
        /**
         * PetalBot bypass.
         * @link https://github.com/CIDRAM/CIDRAM/issues/254
         */
        if (isset($Bypasses['PetalBot'])) {
            if (empty($this->CIDRAM['Hostname'])) {
                $this->CIDRAM['Hostname'] = $this->dnsReverse($this->BlockInfo['IPAddr']);
            }
            if (
                preg_match('~(?:^|\.)(?:aspiegel|petalsearch)\.com$~i', $this->CIDRAM['Hostname']) ||
                strpos($this->BlockInfo['UALC'], 'petalbot') !== false
            ) {
                return 4;
            }
        }
    }

    /**
     * Automattic and SingleHop bypasses.
     * @link https://github.com/CIDRAM/CIDRAM/issues/65
     */
    if ($Tag === 'Automattic' || $Tag === 'SingleHop, Inc') {
        /** Feedbot bypass. */
        if (isset($Bypasses['Feedbot']) && strpos($this->BlockInfo['UALC'], 'wp.com feedbot/1.0 (+https://wp.com)') !== false) {
            return;
        }

        /** Jetpack bypass. */
        if (isset($Bypasses['Jetpack']) && preg_match('~^(?:jetpack|photon/)~', $this->BlockInfo['UALC'])) {
            return;
        }
    }

    /** AbuseIPDB webmaster verification bot bypass. */
    if ($Tag === 'Digital Ocean, Inc' && isset($Bypasses['AbuseIPDB']) && $this->BlockInfo['UA'] === 'AbuseIPDB_Bot/1.0') {
        return;
    }

    /** Yandex bypass. */
    if ($Tag === 'Yandex' && isset($Bypasses['Yandex'])) {
        if (empty($this->CIDRAM['Hostname'])) {
            $this->CIDRAM['Hostname'] = $this->dnsReverse($this->BlockInfo['IPAddr']);
        }
        if (preg_match('~(?:^|\.)yandex\.(?:com|net|ru)$~i', $this->CIDRAM['Hostname']) && strpos($this->BlockInfo['UALC'], 'yandex') !== false) {
            return;
        }
    }

    /** Baiduspider bypass. */
    if ($Tag === 'Beijing Baidu Netcom' && isset($Bypasses['Baidu'])) {
        if (empty($this->CIDRAM['Hostname'])) {
            $this->CIDRAM['Hostname'] = $this->dnsReverse($this->BlockInfo['IPAddr']);
        }
        if (preg_match('~(?:^|\.)baidu\.(?:com|jp)$~i', $this->CIDRAM['Hostname']) && strpos($this->BlockInfo['UALC'], 'baiduspider') !== false) {
            return;
        }
    }

    /** Sogou bypass. */
    if ($Tag === 'Shenzhen Tencent' && isset($Bypasses['Sogou'])) {
        if (empty($this->CIDRAM['Hostname'])) {
            $this->CIDRAM['Hostname'] = $this->dnsReverse($this->BlockInfo['IPAddr']);
        }
        if (preg_match('~(?:^|\.)sogou\.com$~i', $this->CIDRAM['Hostname']) && strpos($this->BlockInfo['UALC'], 'sogou') !== false) {
            return;
        }
    }

    $this->BlockInfo['ReasonMessage'] = $this->L10N->getString('ReasonMessage.Cloud');
    if (!empty($this->BlockInfo['WhyReason'])) {
        $this->BlockInfo['WhyReason'] .= ', ';
    }
    $this->BlockInfo['WhyReason'] .= $this->L10N->getString('Short.Cloud') . $LN;
    $this->addProfileEntry('Cloud');
    if (!empty($this->BlockInfo['Signatures'])) {
        $this->BlockInfo['Signatures'] .= ', ';
    }
    $this->BlockInfo['Signatures'] .= $Factors[$FactorIndex];
    $this->BlockInfo['SignatureCount']++;
};

/** Execute object. */
$RunExitCode = $this->CIDRAM['RunParamResCache']['bypasses.php']($Factors, $FactorIndex, $LN, $Tag);
