b0y-101 Mini Shell


Current Path : E:/www/plan/administrator/components/com_coalawebtraffic/helpers/
File Upload :
Current File : E:/www/plan/administrator/components/com_coalawebtraffic/helpers/iptools.php

<?php

/**
 * @package     Joomla
 * @subpackage  CoalaWeb Traffic
 * @author      Steven Palmer <support@coalaweb.com>
 * @link        https://coalaweb.com/
 * @license     GNU/GPL V3 or later; https://www.gnu.org/licenses/gpl-3.0.html
 * @copyright   Copyright (c) 2020 Steven Palmer All rights reserved.
 *
 * CoalaWeb Traffic is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

defined('_JEXEC') or die('Restricted access');

jimport('joomla.log.log');

/**
 *  CoalaWeb Traffic component helper.
 */
class CoalawebtrafficHelperIptools
{
    /**
     * Get users IP address
     * 
     * @return string
     */
    public static function getUserIP() 
    {
        $ip = self::_real_getUserIP();

        if ((strstr($ip, ',') !== false) || (strstr($ip, ' ') !== false)) {
            $ip = str_replace(' ', ',', $ip);
            $ip = str_replace(',,', ',', $ip);
            $ips = explode(',', $ip);
            $ip = '';
            while (empty($ip) && !empty($ips)) {
                $ip = array_pop($ips);
                $ip = trim($ip);
            }
        } else {
            $ip = trim($ip);
        }

        return $ip;
    }

    /**
     * Gets the visitor's IP address
     *
     * @return string
     */
    private static function _real_getUserIP() {
        //Should we check for proxies?
        $comParams = JComponentHelper::getParams('com_coalawebtraffic');
        $checkProxy = $comParams->get('check_proxy', 1);

        // Normally the $_SERVER superglobal is set
        if (isset($_SERVER)) {

            //If we need to check what is contained in SERVER we can turn on the option below
            //and save it to a log file for further investigation
            if ($comParams->get('log_debug')) {
                //Start our log file code
                JLog::addLogger(array('text_file' => 'com_coalawebtraffic_debug.log.php'), JLog::DEBUG, 'com_coalawebtraffic_debug');

                //Step through each part
                $logit = array();
                foreach($_SERVER as $key => $value){
                    $logit[$key] = $value;
                }

                //Save our json encoded array
                JLog::add(json_encode($logit), JLog::DEBUG, 'com_coalawebtraffic_debug');
            }

            if ($checkProxy) {
                $ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR');


                foreach ($ip_keys as $key) {

                    if (array_key_exists($key, $_SERVER) === true) {
                        foreach (explode(',', $_SERVER[$key]) as $ip) {
                            // trim for safety measures
                            JLog::add($ip, JLog::WARNING, 'com_coalawebtraffic');
                            $ip = trim($ip);
                            // attempt to validate IP
                            if (self::validate_ip($ip)) {
                                return $ip;
                            }
                        }
                    }
                }

            } else {
                //This is done to over come strange behaviour by OVH hosting servers
                $ip = strtok($_SERVER['REMOTE_ADDR'], " ");
                $ip = trim($ip);
                // attempt to validate IP
                if (self::validate_ip($ip)) {
                    return $ip;
                }
            }

            return self::validate_ip($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
        }

        // This part is executed on PHP running as CGI, or on SAPIs which do
        // not set the $_SERVER superglobal
        // If getenv() is disabled, you're screwed
        if (function_exists('getenv')) {
            
            if ($checkProxy) {
                $ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR');
            } else {
                $ip_keys = array('REMOTE_ADDR');
            }
            
            foreach ($ip_keys as $key) {
                if (getenv($key)) {
                    foreach (explode(',', getenv($key)) as $ip) {
                        // trim for safety measures
                        $ip = trim($ip);
                        // attempt to validate IP
                        if (self::validate_ip($ip)) {
                            return $ip;
                        }
                    }
                }
            }

            return self::validate_ip(getenv('REMOTE_ADDR')) ? getenv('REMOTE_ADDR') : '';
        }

        // Catch-all case for broken servers, apparently
        return '';
    }

    /**
     * Ensures an ip address is both a valid IP and does not fall within
     * a private network range.
     */
    protected static function validate_ip($ip) {
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
            return false;
        }
        return true;
    }

    /**
     * Is this an IPv6 IP address?
     *
     * @param string $ip An IPv4 or IPv6 address
     *
     * @return boolean  True if it's IPv6
     */
    public static function isIPv6($ip) 
    {
        if (strstr($ip, ':')) {
            return true;
        }

        return false;
    }

    /**
     * Converts inet_pton output to bits string
     *
     * @param string $inet The in_addr representation of an IPv4 or IPv6 address
     *
     * @return string
     */
    protected static function inet_to_bits($inet) 
    {
        if (strlen($inet) == 4) {
            $unpacked = unpack('A4', $inet);
        } else {
            $unpacked = unpack('A16', $inet);
        }
        $unpacked = str_split($unpacked[1]);
        $binaryip = '';

        foreach ($unpacked as $char) {
            $binaryip .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT);
        }

        return $binaryip;
    }

    /**
     * Checks if an IP is contained in a list of IPs or IP expressions
     *
     * @param string $ip      The IPv4/IPv6 address to check
     * @param array  $ipTable The list of IP expressions
     *
     * @return null|boolean  True if it's in the list, null if the filtering can't proceed
     */
    public static function ipinList($ip, $ipTable = array()) 
    {
        // No point proceeding with an empty IP list
        if (empty($ipTable)) {
            return null;
        }

        // If no IP address is found, return null (unsupported)
        if ($ip == '0.0.0.0') {
            return null;
        }

        // If no IP is given, return null (unsupported)
        if (empty($ip)) {
            return null;
        }

        // Sanity check
        if (!function_exists('inet_pton')) {
            return null;
        }

        // Get the IP's in_adds representation
        $myIP = @inet_pton($ip);

        // If the IP is in an unrecognisable format, quite
        if ($myIP === false) {
            return null;
        }

        $ipv6 = self::isIPv6($ip);

        foreach ($ipTable as $ipExpression) {
            $ipExpression = trim($ipExpression);

            // Inclusive IP range, i.e. 123.123.123.123-124.125.126.127
            if (strstr($ipExpression, '-')) {
                list($from, $to) = explode('-', $ipExpression, 2);

                if ($ipv6 && (!self::isIPv6($from) || !self::isIPv6($to))) {
                    // Do not apply IPv4 filtering on an IPv6 address
                    continue;
                } elseif (!$ipv6 && (self::isIPv6($from) || self::isIPv6($to))) {
                    // Do not apply IPv6 filtering on an IPv4 address
                    continue;
                }

                $from = @inet_pton(trim($from));
                $to = @inet_pton(trim($to));

                // Sanity check
                if (($from === false) || ($to === false)) {
                    continue;
                }

                // Swap from/to if they're in the wrong order
                if ($from > $to) {
                    list($from, $to) = array($to, $from);
                }

                if (($myIP >= $from) && ($myIP <= $to)) {
                    return true;
                }
            }
            // Netmask or CIDR provided
            elseif (strstr($ipExpression, '/')) {
                $binaryip = self::inet_to_bits($myIP);

                list($net, $maskbits) = explode('/', $ipExpression, 2);
                if ($ipv6 && !self::isIPv6($net)) {
                    // Do not apply IPv4 filtering on an IPv6 address
                    continue;
                } elseif (!$ipv6 && self::isIPv6($net)) {
                    // Do not apply IPv6 filtering on an IPv4 address
                    continue;
                } elseif (!$ipv6 && strstr($maskbits, '.')) {
                    // Convert IPv4 netmask to CIDR
                    $long = ip2long($maskbits);
                    $base = ip2long('255.255.255.255');
                    $maskbits = 32 - log(($long ^ $base) + 1, 2);
                }

                // Convert network IP to in_addr representation
                $net = @inet_pton($net);

                // Sanity check
                if ($net === false) {
                    continue;
                }

                // Get the network's binary representation
                $binarynet = self::inet_to_bits($net);

                // Check the corresponding bits of the IP and the network
                $ip_net_bits = substr($binaryip, 0, $maskbits);
                $net_bits = substr($binarynet, 0, $maskbits);

                if ($ip_net_bits == $net_bits) {
                    return true;
                }
            } else {
                // IPv6: Only single IPs are supported
                if ($ipv6) {
                    $ipExpression = trim($ipExpression);

                    if (!self::isIPv6($ipExpression)) {
                        continue;
                    }

                    $ipCheck = @inet_pton($ipExpression);
                    if ($ipCheck === false) {
                        continue;
                    }

                    if ($ipCheck == $myIP) {
                        return true;
                    }
                } else {
                    // Standard IPv4 address, i.e. 123.123.123.123 or partial IP address, i.e. 123.[123.][123.][123]
                    $dots = 0;
                    if (substr($ipExpression, -1) == '.') {
                        // Partial IP address. Convert to CIDR and re-match
                        foreach (count_chars($ipExpression, 1) as $i => $val) {
                            if ($i == 46) {
                                $dots = $val; 
                            }
                        }
                        switch ($dots) {
                        case 1:
                            $netmask = '255.0.0.0';
                            $ipExpression .= '0.0.0';
                            break;

                        case 2:
                            $netmask = '255.255.0.0';
                            $ipExpression .= '0.0';
                            break;

                        case 3:
                            $netmask = '255.255.255.0';
                            $ipExpression .= '0';
                            break;

                        default:
                            $dots = 0;
                        }

                        if ($dots) {
                            $binaryip = self::inet_to_bits($myIP);

                            // Convert netmask to CIDR
                            $long = ip2long($netmask);
                            $base = ip2long('255.255.255.255');
                            $maskbits = 32 - log(($long ^ $base) + 1, 2);

                            $net = @inet_pton($ipExpression);

                            // Sanity check
                            if ($net === false) {
                                continue;
                            }

                            // Get the network's binary representation
                            $binarynet = self::inet_to_bits($net);

                            // Check the corresponding bits of the IP and the network
                            $ip_net_bits = substr($binaryip, 0, $maskbits);
                            $net_bits = substr($binarynet, 0, $maskbits);

                            if ($ip_net_bits == $net_bits) {
                                return true;
                            }
                        }
                    }
                    if (!$dots) {
                        $ip = @inet_pton(trim($ipExpression));
                        if ($ip == $myIP) {
                            return true;
                        }
                    }
                }
            }
        }

        return false;
    }

    /**
     * Checks if an IP is contained in a list of IPs or IP expressions
     *
     * @param string $ip      The IPv4/IPv6 address to check
     * @param array  $ipTable The list of IP expressions
     *
     * @return null|boolean  True if it's in the list, null if the filtering can't proceed
     */
    public static function titleinList($ip, $ipTable = array()) 
    {
        // No point proceeding with an empty IP list
        if (empty($ipTable)) {
            return null;
        }

        // If no IP address is found, return null (unsupported)
        if ($ip == '0.0.0.0') {
            return null;
        }

        // If no IP is given, return null (unsupported)
        if (empty($ip)) {
            return null;
        }

        // Sanity check
        if (!function_exists('inet_pton')) {
            return null;
        }

        // Get the IP's in_adds representation
        $myIP = @inet_pton($ip);

        // If the IP is in an unrecognisable format, quite
        if ($myIP === false) {
            return null;
        }

        $ipv6 = self::isIPv6($ip);

        foreach ($ipTable as $i => $ipExpression) {

            $ipExpression2 = trim($ipExpression['0']);
            $foo = '';

            // Inclusive IP range, i.e. 123.123.123.123-124.125.126.127
            if (strstr($ipExpression2, '-')) {
                list($from, $to) = explode('-', $ipExpression2, 2);

                if ($ipv6 && (!self::isIPv6($from) || !self::isIPv6($to))) {
                    // Do not apply IPv4 filtering on an IPv6 address
                    continue;
                } elseif (!$ipv6 && (self::isIPv6($from) || self::isIPv6($to))) {
                    // Do not apply IPv6 filtering on an IPv4 address
                    continue;
                }

                $from = @inet_pton(trim($from));
                $to = @inet_pton(trim($to));

                // Sanity check
                if (($from === false) || ($to === false)) {
                    continue;
                }

                // Swap from/to if they're in the wrong order
                if ($from > $to) {
                    list($from, $to) = array($to, $from);
                }

                if (($myIP >= $from) && ($myIP <= $to)) {
                    $foo = $ipExpression['1'];
                    return $foo;
                }
            }
            // Netmask or CIDR provided
            elseif (strstr($ipExpression2, '/')) {
                $binaryip = self::inet_to_bits($myIP);

                list($net, $maskbits) = explode('/', $ipExpression2, 2);
                if ($ipv6 && !self::isIPv6($net)) {
                    // Do not apply IPv4 filtering on an IPv6 address
                    continue;
                } elseif (!$ipv6 && self::isIPv6($net)) {
                    // Do not apply IPv6 filtering on an IPv4 address
                    continue;
                } elseif (!$ipv6 && strstr($maskbits, '.')) {
                    // Convert IPv4 netmask to CIDR
                    $long = ip2long($maskbits);
                    $base = ip2long('255.255.255.255');
                    $maskbits = 32 - log(($long ^ $base) + 1, 2);
                }

                // Convert network IP to in_addr representation
                $net = @inet_pton($net);

                // Sanity check
                if ($net === false) {
                    continue;
                }

                // Get the network's binary representation
                $binarynet = self::inet_to_bits($net);

                // Check the corresponding bits of the IP and the network
                $ip_net_bits = substr($binaryip, 0, $maskbits);
                $net_bits = substr($binarynet, 0, $maskbits);

                if ($ip_net_bits == $net_bits) {
                    $foo = $ipExpression['1'];
                    return $foo;
                }
            } else {
                // IPv6: Only single IPs are supported
                if ($ipv6) {
                    $ipExpression2 = trim($ipExpression2);

                    if (!self::isIPv6($ipExpression2)) {
                        continue;
                    }

                    $ipCheck = @inet_pton($ipExpression2);
                    if ($ipCheck === false) {
                        continue;
                    }

                    if ($ipCheck == $myIP) {
                        $foo = $ipExpression['1'];
                        return $foo;
                    }
                } else {
                    // Standard IPv4 address, i.e. 123.123.123.123 or partial IP address, i.e. 123.[123.][123.][123]
                    $dots = 0;
                    if (substr($ipExpression2, -1) == '.') {
                        // Partial IP address. Convert to CIDR and re-match
                        foreach (count_chars($ipExpression2, 1) as $i => $val) {
                            if ($i == 46) {
                                $dots = $val; 
                            }
                        }
                        switch ($dots) {
                        case 1:
                            $netmask = '255.0.0.0';
                            $ipExpression2.= '0.0.0';
                            break;

                        case 2:
                            $netmask = '255.255.0.0';
                            $ipExpression2.= '0.0';
                            break;

                        case 3:
                            $netmask = '255.255.255.0';
                            $ipExpression2.= '0';
                            break;

                        default:
                            $dots = 0;
                        }

                        if ($dots) {
                            $binaryip = self::inet_to_bits($myIP);

                            // Convert netmask to CIDR
                            $long = ip2long($netmask);
                            $base = ip2long('255.255.255.255');
                            $maskbits = 32 - log(($long ^ $base) + 1, 2);

                            $net = @inet_pton($ipExpression2);

                            // Sanity check
                            if ($net === false) {
                                continue;
                            }

                            // Get the network's binary representation
                            $binarynet = self::inet_to_bits($net);

                            // Check the corresponding bits of the IP and the network
                            $ip_net_bits = substr($binaryip, 0, $maskbits);
                            $net_bits = substr($binarynet, 0, $maskbits);

                            if ($ip_net_bits == $net_bits) {
                                $foo = $ipExpression['1'];
                                return $foo;
                            }
                        }
                    }
                    if (!$dots) {
                        $ip = @inet_pton(trim($ipExpression2));
                        if ($ip == $myIP) {
                            $foo = $ipExpression['1'];
                            return $foo;
                        }
                    }
                }
            }
        }

        return $foo;
    }
}

Copyright © 2019 by b0y-101