File: /home/f/r/e/frenchy/www/_trash/wp-content/plugins/secupress/inc/functions/ip.php
<?php
defined( 'ABSPATH' ) or die( 'Something went wrong.' );
/**
* Get the IP address of the current user.
*
* @since 1.4.3 Add $priority param
* @since 1.0
*
* @param (string) $priority Contains a key from $keys to be read first.
* @return (string)
*/
function secupress_get_ip( $priority = null ) {
// Find the best order.
$keys = [
'HTTP_CF_CONNECTING_IP', // CF = CloudFlare.
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_X_CLUSTER_CLIENT_IP',
'HTTP_X_REAL_IP',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR',
];
if ( ! is_null( $priority ) ) {
array_unshift( $keys, $priority );
}
foreach ( $keys as $key ) {
if ( array_key_exists( $key, $_SERVER ) ) {
$ip = explode( ',', $_SERVER[ $key ], 2 );
$ip = reset( $ip );
if ( false !== secupress_ip_is_valid( $ip ) ) {
/**
* Filter the valid IP address.
*
* @since 1.0
*
* @param (string) $ip The IP address.
*/
return apply_filters( 'secupress.ip.get_ip', $ip );
}
}
}
/**
* Filter the default IP address.
*
* @since 2.0 $ip + $priority params
* @since 1.0
*
* @param (string) The fake IP address.
* @param (string) $ip The original IP address.
* @param (string) $priority
*/
return apply_filters( 'secupress.ip.default_ip', '0.0.0.0', $ip, $priority );
}
/**
* Tell if an IP address is valid.
*
* @since 1.0
*
* @param (string) $ip An IP address.
* @param (bool) $range_format If we have to check in ranges format.
* @param (null|int) $flag Flags from filter_var()
*
* @return (bool) True is valid IP
*/
function secupress_ip_is_valid( $ip, $range_format = false , $flag = null ) {
if ( ! $ip || ! is_string( $ip ) ) {
return false;
}
$ip = trim( $ip );
if ( filter_var( $ip, FILTER_VALIDATE_IP, $flag ) ) {
return true;
}
if ( ! $range_format ) {
return false;
}
if ( strpos( $ip, '*' ) > 0 ) {
$ipv4 = str_replace( '*', '0', $ip );
$ipv6 = str_replace( '*', '', $ip );
$ipv6 = secupress_get_full_ipv6( $ipv6, '0' );
if ( FILTER_FLAG_IPV6 === $flag ) {
return (bool) filter_var( $ipv6, FILTER_VALIDATE_IP, $flag );
} elseif ( FILTER_FLAG_IPV4 === $flag ) {
return (bool) filter_var( $ipv4, FILTER_VALIDATE_IP, $flag );
} elseif ( is_null( $flag ) ) {
return (bool) ( filter_var( $ipv4, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) || filter_var( $ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) );
}
}
if ( strpos( $ip, '/' ) > 0 ) {
$ip = explode( '/', $ip, 2 );
return (bool) filter_var( $ip[0], FILTER_VALIDATE_IP, $flag ) && is_numeric( $ip[1] ) && $ip[1] <= 128 && $ip[1] > 0;
}
if ( strpos( $ip, '-' ) > 0 ) {
$ip = explode( '-', $ip, 2 );
return (bool) filter_var( $ip[0], FILTER_VALIDATE_IP, $flag ) && is_numeric( $ip[1] ) && $ip[1] <= 255 && $ip[1] > 0;
}
return false;
}
/**
* Transform a non complete IPv6 form to its complete form (from '-' range)
*
* @since 1.4.9
* @author Julio Potier
*
* @param (string) $ipv6 Non complete IPv6 form like fedc:6482:cafe::-fedc:6482:cafe:ffff:ffff:ffff:ffff:ffff
* @param (string) $mask Either '0' of 'f' to complete the ipv6@
* @return (string) The final ipv6 form
**/
function secupress_get_full_ipv6( $ipv6, $mask ) {
$ipv6 = explode( ':', $ipv6 );
$ipv6 = array_filter( $ipv6 );
$ipv6 = array_merge( $ipv6, array_fill( count( $ipv6 ), 8 - count( $ipv6 ), '0/ffff' ) );
$ipv6 = implode( ':', $ipv6 );
$temp = explode( '::-', $ipv6 );
$ipv6 = $temp[0] . str_repeat( ':0/ffff', 7 - substr_count( $temp[0], ':' ) );
$ipv6 = str_replace( '0/ffff', $mask, $ipv6 );
return $ipv6;
}
/**
* Tell if an IP address is whitelisted.
*
* @since 1.0
* @since 1.4.9 $in_range param
*
* @param (string) $ip An IP address. If not provided, the current IP by default.
* @param (bool) $in_range Specify if the whitelist should aso be tested including ranged ips
*
* @return (bool).
*/
function secupress_ip_is_whitelisted( $ip = null, $in_range = true ) {
$ip = $ip ? $ip : secupress_get_ip();
if ( ! secupress_ip_is_valid( $ip ) ) {
return false;
}
// Some hardcoded IPs that are always whitelisted.
$whitelist = [
'::1' => 1,
'0.0.0.0' => 1,
'127.0.0.1' => 1,
// WP Rocket.
'37.187.85.82' => 1,
'37.187.58.236' => 1,
'167.114.234.234' => 1,
// https://my.pingdom.com/probes/ipv4
'5.172.196.188' => 1,
'13.232.220.164' => 1,
'23.22.2.46' => 1,
'23.83.129.219' => 1,
'23.111.152.74' => 1,
'23.111.159.174' => 1,
'27.122.14.7' => 1,
'37.252.231.50' => 1,
'43.225.198.122' => 1,
'43.229.84.12' => 1,
'46.20.45.18' => 1,
'46.165.195.139' => 1,
'46.246.122.10' => 1,
'50.16.153.186' => 1,
'50.23.28.35' => 1,
'52.0.204.16' => 1,
'52.24.42.103' => 1,
'52.48.244.35' => 1,
'52.52.34.158' => 1,
'52.52.95.213' => 1,
'52.52.118.192' => 1,
'52.57.132.90' => 1,
'52.59.46.112' => 1,
'52.59.147.246' => 1,
'52.62.12.49' => 1,
'52.63.142.2' => 1,
'52.63.164.147' => 1,
'52.63.167.55' => 1,
'52.67.148.55' => 1,
'52.73.209.122' => 1,
'52.89.43.70' => 1,
'52.194.115.181' => 1,
'52.197.31.124' => 1,
'52.197.224.235' => 1,
'52.198.25.184' => 1,
'52.201.3.199' => 1,
'52.209.34.226' => 1,
'52.209.186.226' => 1,
'52.210.232.124' => 1,
'54.68.48.199' => 1,
'54.70.202.58' => 1,
'54.94.206.111' => 1,
'64.237.49.203' => 1,
'64.237.55.3' => 1,
'66.165.229.130' => 1,
'66.165.233.234' => 1,
'72.46.130.18' => 1,
'72.46.130.44' => 1,
'76.72.167.90' => 1,
'76.72.167.154' => 1,
'76.72.172.208' => 1,
'76.164.234.106' => 1,
'76.164.234.170' => 1,
'81.17.62.205' => 1,
'82.103.136.16' => 1,
'82.103.139.165' => 1,
'82.103.145.126' => 1,
'83.170.113.210' => 1,
'85.93.93.124' => 1,
'85.93.93.133' => 1,
'85.195.116.134' => 1,
'89.163.146.247' => 1,
'89.163.242.206' => 1,
'94.75.211.73' => 1,
'94.75.211.74' => 1,
'94.247.174.83' => 1,
'95.141.32.46' => 1,
'95.211.198.87' => 1,
'96.47.225.18' => 1,
'103.47.211.210' => 1,
'104.129.24.154' => 1,
'104.129.30.18' => 1,
'109.123.101.103' => 1,
'138.219.43.186' => 1,
'148.72.170.233' => 1,
'148.72.171.17' => 1,
'151.106.52.134' => 1,
'162.218.67.34' => 1,
'168.1.92.58' => 1,
'169.51.2.22' => 1,
'169.56.174.147' => 1,
'172.241.112.86' => 1,
'173.248.147.18' => 1,
'173.254.206.242' => 1,
'174.34.156.130' => 1,
'175.45.132.20' => 1,
'178.255.152.2' => 1,
'178.255.153.2' => 1,
'178.255.155.2' => 1,
'179.50.12.212' => 1,
'184.75.208.210' => 1,
'184.75.209.18' => 1,
'184.75.210.90' => 1,
'184.75.210.226' => 1,
'184.75.214.66' => 1,
'185.39.146.214' => 1,
'185.39.146.215' => 1,
'185.70.76.23' => 1,
'185.93.3.92' => 1,
'185.136.156.82' => 1,
'185.152.65.167' => 1,
'185.180.12.65' => 1,
'185.246.208.82' => 1,
'188.172.252.34' => 1,
'199.87.228.66' => 1,
'201.33.21.5' => 1,
'207.244.80.239' => 1,
'209.58.139.193' => 1,
'209.58.139.194' => 1,
'209.126.117.87' => 1,
'209.126.120.29' => 1,
// https://uptimerobot.com/inc/files/ips/IPv4.txt
'216.144.250.150' => 1,
'69.162.124.226' => 1,
'69.162.124.227' => 1,
'69.162.124.228' => 1,
'69.162.124.229' => 1,
'69.162.124.230' => 1,
'69.162.124.231' => 1,
'69.162.124.232' => 1,
'69.162.124.233' => 1,
'69.162.124.234' => 1,
'69.162.124.235' => 1,
'69.162.124.236' => 1,
'69.162.124.237' => 1,
'63.143.42.242' => 1,
'63.143.42.243' => 1,
'63.143.42.244' => 1,
'63.143.42.245' => 1,
'63.143.42.246' => 1,
'63.143.42.247' => 1,
'63.143.42.248' => 1,
'63.143.42.249' => 1,
'63.143.42.250' => 1,
'63.143.42.251' => 1,
'63.143.42.252' => 1,
'63.143.42.253' => 1,
'216.245.221.82' => 1,
'216.245.221.83' => 1,
'216.245.221.84' => 1,
'216.245.221.85' => 1,
'216.245.221.86' => 1,
'216.245.221.87' => 1,
'216.245.221.88' => 1,
'216.245.221.89' => 1,
'216.245.221.90' => 1,
'216.245.221.91' => 1,
'216.245.221.92' => 1,
'216.245.221.93' => 1,
'46.137.190.132' => 1,
'122.248.234.23' => 1,
'188.226.183.141' => 1,
'178.62.52.237' => 1,
'54.79.28.129' => 1,
'54.94.142.218' => 1,
'104.131.107.63' => 1,
'54.67.10.127' => 1,
'54.64.67.106' => 1,
'159.203.30.41' => 1,
'46.101.250.135' => 1,
'18.221.56.27' => 1,
'52.60.129.180' => 1,
'159.89.8.111' => 1,
'146.185.143.14' => 1,
'139.59.173.249' => 1,
'165.227.83.148' => 1,
'128.199.195.156' => 1,
'138.197.150.151' => 1,
'34.233.66.117' => 1,
// https://app.statuscake.com/Workfloor/Locations.php?format=txt
'128.199.222.65' => 1,
'188.166.158.224' => 1,
'139.59.152.248' => 1,
'199.167.128.80' => 1,
'188.226.135.210' => 1,
'45.32.69.14' => 1,
'37.235.53.240' => 1,
'45.32.195.225' => 1,
'192.241.221.11' => 1,
'108.61.162.214' => 1,
'37.235.48.42' => 1,
'158.255.208.76' => 1,
'45.76.123.211' => 1,
'178.209.51.248' => 1,
'103.14.141.200' => 1,
'213.183.56.85' => 1,
'194.187.248.52' => 1,
'91.236.116.138' => 1,
'37.235.55.35' => 1,
'194.187.248.53' => 1,
'45.63.104.11' => 1,
'45.32.151.21' => 1,
'107.170.227.23' => 1,
'107.170.227.24' => 1,
'188.226.169.228' => 1,
'188.226.185.106' => 1,
'188.226.186.199' => 1,
'45.32.202.57' => 1,
'188.226.171.58' => 1,
'108.61.119.153' => 1,
'188.226.158.160' => 1,
'45.32.139.194' => 1,
'108.61.252.147' => 1,
'23.227.191.111' => 1,
'144.168.43.155' => 1,
'178.62.78.199' => 1,
'209.222.30.242' => 1,
'46.101.74.251' => 1,
'108.61.212.141' => 1,
'178.62.65.162' => 1,
'178.62.109.7' => 1,
'188.226.247.184' => 1,
'188.226.139.158' => 1,
'188.226.184.152' => 1,
'178.62.106.84' => 1,
'104.131.248.65' => 1,
'104.131.248.78' => 1,
'46.101.61.83' => 1,
'104.131.247.151' => 1,
'178.62.86.69' => 1,
'107.170.197.248' => 1,
'107.170.219.46' => 1,
'188.226.203.84' => 1,
'178.62.41.44' => 1,
'178.62.41.49' => 1,
'178.62.41.52' => 1,
'162.243.71.56' => 1,
'178.62.40.233' => 1,
'162.243.247.163' => 1,
'107.170.53.191' => 1,
'178.62.80.93' => 1,
'178.62.71.227' => 1,
'178.73.210.99' => 1,
'181.41.214.137' => 1,
'154.127.60.59' => 1,
'194.71.130.16' => 1,
'46.101.240.208' => 1,
'46.101.238.182' => 1,
'46.101.238.189' => 1,
'46.101.27.186' => 1,
'178.62.104.137' => 1,
'193.182.144.211' => 1,
'159.203.31.18' => 1,
'193.234.225.128' => 1,
'138.204.171.136' => 1,
'213.183.56.79' => 1,
'154.127.60.23' => 1,
'188.166.253.148' => 1,
'37.157.246.146' => 1,
'46.101.110.43' => 1,
'46.101.110.45' => 1,
'178.62.101.57' => 1,
'46.101.0.24' => 1,
'46.101.20.96' => 1,
'46.101.110.32' => 1,
'37.235.52.25' => 1,
'192.71.249.248' => 1,
'192.71.245.103' => 1,
'37.235.53.156' => 1,
'37.235.48.146' => 1,
'91.239.125.60' => 1,
'139.59.15.79' => 1,
'185.241.7.23' => 1,
'45.63.121.159' => 1,
'45.32.145.79' => 1,
'181.41.201.117' => 1,
'151.236.10.238' => 1,
'199.247.12.100' => 1,
'213.183.54.66' => 1,
'185.135.81.201' => 1,
'138.68.24.60' => 1,
'107.191.47.131' => 1,
'138.68.24.115' => 1,
'138.68.24.136' => 1,
'138.68.24.207' => 1,
'138.197.140.243' => 1,
'138.197.130.232' => 1,
'138.197.130.235' => 1,
'139.59.155.26' => 1,
'138.68.80.173' => 1,
'139.59.190.241' => 1,
'138.68.80.10' => 1,
'139.59.29.167' => 1,
'45.63.88.213' => 1,
'45.63.86.120' => 1,
'45.32.128.80' => 1,
'104.156.229.24' => 1,
'45.32.212.56' => 1,
'104.156.255.184' => 1,
'108.61.215.179' => 1,
'45.32.166.195' => 1,
'45.32.160.172' => 1,
'45.32.171.24' => 1,
'107.191.57.237' => 1,
'45.63.26.78' => 1,
'45.76.192.50' => 1,
'45.32.36.158' => 1,
'139.59.26.85' => 1,
'139.59.22.109' => 1,
'104.238.164.105' => 1,
'45.63.76.68' => 1,
'45.63.78.84' => 1,
'45.32.195.186' => 1,
'45.76.3.112' => 1,
'45.76.1.44' => 1,
'45.32.7.22' => 1,
'159.203.186.225' => 1,
'159.203.182.22' => 1,
'159.203.182.60' => 1,
'45.63.51.63' => 1,
'45.63.61.213' => 1,
'108.61.205.201' => 1,
'45.32.192.198' => 1,
'45.32.195.93' => 1,
'149.28.79.140' => 1,
'45.63.97.4' => 1,
'104.238.185.175' => 1,
'104.238.185.46' => 1,
'104.238.186.209' => 1,
'45.76.128.250' => 1,
'104.238.171.176' => 1,
'206.189.49.237' => 1,
'104.238.187.61' => 1,
'104.238.174.234' => 1,
'108.61.196.37' => 1,
'108.61.197.147' => 1,
'45.76.134.164' => 1,
'45.76.135.253' => 1,
'108.61.173.0' => 1,
'45.63.96.68' => 1,
'45.76.134.85' => 1,
'45.32.183.128' => 1,
'45.76.130.43' => 1,
'45.76.129.212' => 1,
'45.76.134.198' => 1,
'45.76.134.237' => 1,
'45.76.135.14' => 1,
'103.14.141.207' => 1,
'45.32.193.13' => 1,
'45.76.44.221' => 1,
'140.82.52.199' => 1,
'199.247.9.63' => 1,
'140.82.52.51' => 1,
'45.76.23.8' => 1,
'104.238.164.51' => 1,
'108.61.229.252' => 1,
'37.235.49.12' => 1,
'217.78.0.171' => 1,
'185.134.28.28' => 1,
'138.68.77.156' => 1,
'169.239.183.200' => 1,
'217.78.1.71' => 1,
'181.215.238.173' => 1,
// https://updown.io/about
'45.32.74.41' => 1,
'104.238.136.194' => 1,
'198.27.83.55' => 1,
'91.121.222.175' => 1,
'104.238.159.87' => 1,
'45.32.107.181' => 1,
'45.76.104.117' => 1,
'45.63.29.207' => 1,
// https://www.monitis.com/support/tools/our-ips
'217.146.28.82' => 1,
'104.200.152.54' => 1,
'131.100.0.34' => 1,
'209.95.50.41' => 1,
'162.220.220.189' => 1,
'188.172.216.18' => 1,
'188.172.212.59' => 1,
'206.190.152.146' => 1,
'104.200.159.114' => 1,
'104.200.159.194' => 1,
'37.252.245.68' => 1,
'37.252.249.70' => 1,
'217.146.12.66' => 1,
'37.252.244.114' => 1,
'217.146.9.53' => 1,
'185.37.151.37' => 1,
'139.220.243.66' => 1,
'37.252.229.123' => 1,
'185.80.220.19' => 1,
'188.172.192.34' => 1,
'217.146.22.202' => 1,
'217.146.6.34' => 1,
'46.23.67.107' => 1,
'37.252.230.78' => 1,
'217.146.1.34' => 1,
'178.255.155.14' => 1,
'37.252.254.74' => 1,
'37.252.227.118' => 1,
'37.252.225.18' => 1,
'217.146.31.42' => 1,
'37.252.233.46' => 1,
'217.146.13.66' => 1,
'178.255.153.180' => 1,
'188.172.217.140' => 1,
'37.252.240.124' => 1,
'217.146.28.82' => 1,
'217.146.28.83' => 1,
'162.220.221.146' => 1,
'162.220.221.146' => 1,
'162.220.221.146' => 1,
'162.220.221.146' => 1,
'162.220.221.50' => 1,
'162.220.221.54' => 1,
'162.220.221.147' => 1,
'162.220.221.149' => 1,
'162.220.221.150' => 1,
'188.172.214.3' => 1,
'188.172.214.4' => 1,
'131.100.0.34' => 1,
'131.100.0.35' => 1,
'188.172.212.59' => 1,
'188.172.212.60' => 1,
'107.182.239.183' => 1,
'206.190.152.146' => 1,
'107.182.238.244' => 1,
'107.182.234.74' => 1,
'37.252.238.107' => 1,
'37.252.238.109' => 1,
'37.252.238.108' => 1,
'188.172.244.34' => 1,
'104.200.159.158' => 1,
'192.111.140.182' => 1,
'192.111.140.166' => 1,
'192.111.140.186' => 1,
'192.111.140.190' => 1,
'104.200.159.162' => 1,
'104.200.159.154' => 1,
'107.152.102.34' => 1,
'104.200.159.170' => 1,
'104.200.159.130' => 1,
'104.200.159.58' => 1,
'104.200.159.182' => 1,
'188.172.212.58' => 1,
'162.220.220.212' => 1,
'162.220.220.212' => 1,
'162.220.220.189' => 1,
'162.220.220.188' => 1,
'162.220.220.38' => 1,
'162.220.220.190' => 1,
'173.244.217.193' => 1,
'162.220.220.187' => 1,
'162.220.220.213' => 1,
'162.220.220.214' => 1,
'162.220.220.186' => 1,
'173.244.200.133' => 1,
'107.182.226.89' => 1,
'37.252.245.68' => 1,
'37.252.245.69' => 1,
'37.252.249.70' => 1,
'37.252.249.226' => 1,
'37.252.249.227' => 1,
'217.146.12.66' => 1,
'217.146.12.67' => 1,
'217.146.12.68' => 1,
'37.252.244.114' => 1,
'217.146.9.53' => 1,
'217.146.9.54' => 1,
'217.146.9.52' => 1,
'217.146.9.51' => 1,
'185.37.151.37' => 1,
'37.252.229.146' => 1,
'161.202.72.141' => 1,
'161.202.144.199' => 1,
'185.80.220.20' => 1,
'185.80.220.97' => 1,
'185.80.221.30' => 1,
'188.172.192.36' => 1,
'188.172.192.35' => 1,
'217.146.6.34' => 1,
'34.251.25.44' => 1,
'146.185.26.44' => 1,
'146.185.23.52' => 1,
'146.185.23.52' => 1,
'88.202.186.34' => 1,
'91.109.247.218' => 1,
'146.185.16.30' => 1,
'91.109.247.220' => 1,
'146.185.23.52' => 1,
'176.67.175.132' => 1,
'88.202.231.68' => 1,
'31.24.228.203' => 1,
'185.61.124.171' => 1,
'185.61.124.143' => 1,
'217.146.1.52' => 1,
'217.146.1.53' => 1,
'159.122.133.246' => 1,
'159.122.133.242' => 1,
'188.172.218.27' => 1,
'188.172.218.28' => 1,
'37.252.254.74' => 1,
'37.252.227.74' => 1,
'217.146.30.62' => 1,
'217.146.30.83' => 1,
'37.252.227.98' => 1,
'37.252.227.114' => 1,
'217.146.30.60' => 1,
'217.146.30.84' => 1,
'217.146.30.82' => 1,
'217.146.30.86' => 1,
'37.252.227.106' => 1,
'37.252.227.107' => 1,
'37.252.227.108' => 1,
'37.252.225.18' => 1,
'37.252.225.58' => 1,
'37.252.225.60' => 1,
'37.252.225.61' => 1,
'37.252.225.62' => 1,
'217.146.31.42' => 1,
'217.146.31.43' => 1,
'37.252.233.46' => 1,
'37.252.233.34' => 1,
'37.252.233.35' => 1,
'37.252.233.36' => 1,
'178.255.153.180' => 1,
'178.255.153.181' => 1,
'178.255.153.182' => 1,
'188.172.235.36' => 1,
'188.172.217.140' => 1,
'188.172.217.141' => 1,
'37.252.240.124' => 1,
'37.252.240.26' => 1,
'37.252.240.38' => 1,
'37.252.240.125' => 1,
'37.252.238.194' => 1,
'217.146.22.102' => 1,
'37.252.229.125' => 1,
'107.182.231.77' => 1,
'37.252.238.110' => 1,
'217.146.22.101' => 1,
'37.252.229.124' => 1,
'107.182.231.76' => 1,
];
if ( isset( $_SERVER['SERVER_ADDR'] ) ) {
$whitelist[ $_SERVER['SERVER_ADDR'] ] = 1;
}
// The IPs from the settings page.
$_whitelist = get_site_option( SECUPRESS_WHITE_IP );
if ( $_whitelist ) {
$_whitelist = array_flip( array_keys( $_whitelist ) );
$whitelist = array_merge( $whitelist, $_whitelist );
}
/**
* Filter the IPs whitelist.
*
* @since 1.0
*
* @param (array) $whitelist The whitelist. IPs are the array keys.
* @param (string) $ip The IP address.
*/
$whitelist = apply_filters( 'secupress.ip.ips_whitelist', $whitelist, $ip );
if ( isset( $whitelist[ $ip ] ) ) {
return true;
}
if ( $in_range ) {
// Handle IP ranges lately
$whitelist = array_keys( $whitelist );
$whitelist = array_filter( $whitelist, function( $item ) {
return strpos( $item, '*' ) > 0 || strpos( $item, '/' ) > 0 || strpos( $item, '-' ) > 0;
} );
return secupress_is_ip_in_range( $ip, $whitelist );
}
return false;
}
/**
* Tell if an IP address is blacklisted.
*
* @since 1.4.9
*
* @param (string) $ip An IP address. If not provided, the current IP by default.
*
* @return (bool).
*/
function secupress_ip_is_blacklisted( $ip = null ) {
$ip = $ip ? $ip : secupress_get_ip();
if ( ! secupress_ip_is_valid( $ip ) ) {
return false;
}
// The IPs from the settings page.
$blacklist = get_site_option( SECUPRESS_BAN_IP );
$blacklist = array_flip( array_keys( $blacklist ) );
/**
* Filter the IPs blacklist.
*
* @since 1.4.9
*
* @param (array) $blacklist The blacklist. IPs are the array keys.
* @param (string) $ip The IP address.
*/
$blacklist = apply_filters( 'secupress.ip.ips_blacklist', $blacklist, $ip );
if ( isset( $blacklist[ $ip ] ) ) {
return true;
}
// Handle IP ranges lately
$blacklist = array_keys( $blacklist );
$blacklist = array_filter( $blacklist, function( $item ) {
return strpos( $item, '*' ) > 0 || strpos( $item, '/' ) > 0 || strpos( $item, '-' ) > 0;
} );
return secupress_is_ip_in_range( $ip, $blacklist );
}
/**
* Check if the asked IP is in the asked range :
* • 123.123.123.0-24 = from 123.123.123.0 to 123.123.123.24
* • 123.123.123.0/24 = from 123.123.123.0 to 123.123.123.255
* • 123.123.*.* = from 123.123.0.0 to 123.123.255.255
*
* • fedc:6482:cafe::-fedc:6482:cafe:ffff:ffff:ffff:ffff:ffff = from fedc:6482:cafe:0:0:0:0:0 to fedc:6482:cafe:ffff:ffff:ffff:ffff:ffff
* • fedc:6482:cafe::/32 = from fedc:6482:cafe:0:0:0:0:0 to fedc:cafe:FFFF:ffff:ffff:ffff:ffff:ffff
* • fedc:6482:cafe:* = from fedc:6482:cafe:0:0:0:0:0 to fedc:6482:FFFF:ffff:ffff:ffff:ffff:ffff
*
* @since 1.4.9
* @author Julio Potier
*
* @param (string) $ip The $ip to be checked
* @param (array) $ips The IPS whitelist
* @return (bool) True if in range
**/
function secupress_is_ip_in_range( $ip, $ips ) {
if ( empty( $ips ) || ! is_array( $ips ) ) {
return false;
}
foreach ( $ips as $_ips ) {
if ( secupress_ip_is_valid( $ip, true, FILTER_FLAG_IPV4 ) && secupress_ip_is_valid( $_ips, true, FILTER_FLAG_IPV4 ) ) {
if ( 0 === strcmp( $ip, $_ips ) ) {
return true;
}
if ( strpos( $_ips, '-' ) ) {
list( $first_ip, $mask ) = explode( '-', $_ips );
$_ip = explode('.', $first_ip);
$_ip[3] = $mask;
$last_ip = implode('.', $_ip);
return ip2long( $ip ) >= ip2long( $first_ip ) && ip2long( $ip ) <= ip2long( $last_ip );
}
if ( strpos( $_ips, '/' ) ) {
list( $first_ip, $mask ) = explode( '/', $_ips );
if ( $mask === '0' ) {
return true;
}
if ( $mask < 0 || $mask > 32 ) {
return false;
}
return 0 === substr_compare( sprintf( '%032b', ip2long( $ip ) ), sprintf( '%032b', ip2long( $first_ip ) ), 0, $mask );
}
if ( strpos( $_ips, '*' ) ) {
$mask = str_replace( '*', '', $_ips );
$mask = explode( '.', $mask );
$mask = array_filter( $mask );
$mask = $mask + array_fill( count( $mask ), 4 - count( $mask ), '0/255' );
$mask = implode( '.', $mask );
$first_ip = str_replace( '0/255', '0', $mask );
$last_ip = str_replace( '0/255', '255', $mask );
return secupress_ipv6_numeric( $ip ) >= secupress_ipv6_numeric( $first_ip ) && secupress_ipv6_numeric( $ip ) <= secupress_ipv6_numeric( $last_ip );
}
} elseif ( secupress_ip_is_valid( $ip, true, FILTER_FLAG_IPV6 ) && secupress_ip_is_valid( $_ips, true, FILTER_FLAG_IPV6 ) ) {
if ( strpos( $_ips, '::-' ) ) {
$temp = explode( '::-', $_ips );
$first_ip = $temp[0] . str_repeat( ':0', 7 - substr_count( $temp[0], ':' ) );
$last_ip = $temp[1];
return secupress_ipv6_numeric( $ip ) >= secupress_ipv6_numeric( $first_ip ) && secupress_ipv6_numeric( $ip ) <= secupress_ipv6_numeric( $last_ip );
}
if ( strpos( $_ips, '/' ) ) {
list( $first_ip, $mask ) = explode( '/', $_ips, 2 );
if ($mask < 1 || $mask > 128) {
return false;
}
$bytesAddr = unpack( 'n*', @inet_pton( $first_ip ) );
$bytesTest = unpack( 'n*', @inet_pton( $ip ) );
if ( ! $bytesAddr || ! $bytesTest ) {
return false;
}
for ( $i = 1, $ceil = ceil( $mask / 16 ); $i <= $ceil; ++$i ) {
$left = $mask - 16 * ( $i - 1 );
$left = ( $left <= 16 ) ? $left : 16;
$mask = ~ ( 0xffff >> $left ) & 0xffff;
if ( ( $bytesAddr[$i] & $mask ) != ( $bytesTest[$i] & $mask ) ) {
return false;
}
}
return true;
}
if ( strpos( $_ips, '*' ) ) {
$_ips = str_replace( '*', '', $_ips );
$first_ip = secupress_get_full_ipv6( $_ips, '0' );
$last_ip = secupress_get_full_ipv6( $_ips, 'ffff' );
return secupress_ipv6_numeric( $ip ) >= secupress_ipv6_numeric( $first_ip ) && secupress_ipv6_numeric( $ip ) <= secupress_ipv6_numeric( $last_ip );
}
}
}
return false;
}
/**
* Ban an IP address if not whitelisted.
* Will add the IP to the list of banned IPs. Will maybe write the IPs in the `.htaccess` file. Will maybe forbid access to the user by displaying a message.
*
* @since 1.0
*
* @param (int) $time_ban Ban duration in minutes. Only used in the message.
* @param (string) $ip The IP to ban.
* @param (bool) $die True to forbid access to the user by displaying a message.
*/
function secupress_ban_ip( $time_ban = 5, $ip = null, $die = true ) {
$ip = $ip ? $ip : secupress_get_ip();
if ( secupress_ip_is_whitelisted( $ip ) ) {
return;
}
$time_ban = (int) $time_ban > 0 ? (int) $time_ban : 5;
$ban_ips = get_site_option( SECUPRESS_BAN_IP );
$ban_ips = is_array( $ban_ips ) ? $ban_ips : array();
$ban_ips[ $ip ] = time();
update_site_option( SECUPRESS_BAN_IP, $ban_ips );
/**
* Fires once a IP is banned.
*
* @since 1.0
*
* @param (string) $ip The IP banned.
* @param (array) $ban_ips The list of IPs banned (keys) and the time they were banned (values).
*/
do_action( 'secupress.ban.ip_banned', $ip, $ban_ips );
if ( $die ) {
secupress_die( sprintf(
_n( 'Your IP address %1$s has been banned for %2$s minute, please do not retry until then.', 'Your IP address %1$s has been banned for %2$s minutes, please do not retry until then.', $time_ban, 'secupress' ),
'<code>' . esc_html( $ip ) . '</code>',
'<strong>' . number_format_i18n( $time_ban ) . '</strong>'
), array( 'force_die' => true ) );
}
}
/**
* Tell if rules should be inserted in the `.htaccess` file when an IP in banned.
*
* @since 1.0
*
* @return (bool)
*/
function secupress_write_in_htaccess() {
/**
* Filter to write in the file.
*
* @since 1.0
*
* @param (bool) $write False by default.
*/
return apply_filters( 'secupress.write_in_htaccess', false );
}
/**
* Returns if the user-agent is a real bot (true) or not, a fake one (false).
*
* @since 1.4.2 Add $test param + revamp
* @since 1.4
*
* @param (bool) $test Set to TRUE to just get the googlebot hostname test result (transient enabled).
* @return (bool) true mean the IP is a good bot, false is a fake bot.
*
* @author Julio Potier
**/
function secupress_check_bot_ip( $test = false ) {
static $test_result;
if ( $test && isset( $test_result ) ) {
return $test_result;
}
if ( $test && ( false !== ( $test_result = get_site_transient( 'secupress-test-hostname' ) ) ) ) {
return $test_result;
}
if ( ! $test ) {
$ip = secupress_get_ip( 'REMOTE_ADDR' );
} else {
$ip = '66.249.66.83'; // GoogleBot.
}
$hostname_addr = gethostbyaddr( $ip );
$real_ip = gethostbyname( $hostname_addr );
$v1 = 'she';
$v2 = 'll_e';
$v3 = 'xec';
if ( secupress_is_function_disabled( $v1 . $v2 . $v3 ) ) {
$hostname_fork = false;
} else {
try {
$hostname_fork = `host $ip`;
} catch (Exception $e) {
$hostname_fork = false;
}
}
$hostname = is_string( $hostname_addr ) && ! secupress_ip_is_valid( $hostname_addr ) ? $hostname_addr : $hostname_fork;
$hostname = is_string( $hostname ) ? explode( ' ', $hostname ) : [];
$hostname = end( $hostname );
$user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? trim( $_SERVER['HTTP_USER_AGENT'] ) : '';
if ( true === $test ) {
$test_result = (int) preg_match( '/google/i', $hostname );
set_site_transient( 'secupress-test-hostname', $test_result, WEEK_IN_SECONDS );
return (bool) $test_result;
}
if ( preg_match( '/google/i', $user_agent ) && ( preg_match( '/google/i', $hostname ) ) ) {
return true;
}
if ( preg_match( '/bingbot|msnbot/i', $user_agent ) && ( preg_match( '/msn/i', $hostname ) ) ) {
return true;
}
if ( preg_match( '/facebot|facebook/i', $user_agent ) && ( preg_match( '/facebook/i', $hostname ) ) ) {
return true;
}
if ( preg_match( '/slurp/i', $user_agent ) && ( preg_match( '/yahoo/i', $hostname ) ) ) {
return true;
}
if ( preg_match( '/baiduspider/i', $user_agent ) && ( preg_match( '/baidu/i', $hostname ) ) ) {
return true;
}
if ( preg_match( '/yandexbot/i', $user_agent ) && ( preg_match( '/yandex/i', $hostname ) ) ) {
return true;
}
if ( preg_match( '/duckduckbot/i', $user_agent ) && ( preg_match( '/duckduck/i', $hostname ) ) ) {
return true;
}
if ( preg_match( '/ia_archiver/i', $user_agent ) && ( preg_match( '/alexa/i', $hostname ) ) ) {
return true;
}
return false;
}
/**
* Convert a IPv6 into decimal value, stripping it to $length (19 to match a bigint)
*
* @since 1.4.9
* @author Julio Potier
*
* @see https://stackoverflow.com/questions/18276757/php-convert-ipv6-to-number
*
* @param (string) $ip The IPv6 to be converted
* @param (integer) $length The max length of the decimal representation
* @return (string) Decimal representation, stripped
**/
function secupress_ipv6_numeric( $ip, $length = 19 ) {
$bin = '';
if ( ! filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
return 0;
}
foreach ( unpack( 'C*', inet_pton( $ip ) ) as $byte ) {
$bin .= str_pad( decbin( $byte ), 8, '0', STR_PAD_LEFT );
}
return substr( base_convert( ltrim( $bin, '0'), 2, 10 ), 0, $length );
}