From 9cc402c997d6cc36e6acf93001d5d136208c3cf3 Mon Sep 17 00:00:00 2001 From: Jon Stovell Date: Thu, 30 Jan 2025 12:02:30 -0700 Subject: [PATCH] Moves QueryString::matchIPtoCIDR() to IP::matchToCIDR() Signed-off-by: Jon Stovell --- Sources/IP.php | 47 +++++++++++++++++++++++++++++++++++++ Sources/QueryString.php | 52 ++++------------------------------------- Sources/Subs-Compat.php | 10 ++++---- 3 files changed, 56 insertions(+), 53 deletions(-) diff --git a/Sources/IP.php b/Sources/IP.php index 75e10abc62..58b73172b3 100644 --- a/Sources/IP.php +++ b/Sources/IP.php @@ -206,6 +206,53 @@ public function getHost(int $timeout = 1000): string return $this->host; } + /** + * Detect if a IP is in a CIDR address. + * + * @param string $cidr_address CIDR address to verify. + * @return bool Whether the IP matches the CIDR. + */ + public function matchToCIDR(string $cidr_address): bool + { + list($cidr_network, $cidr_subnetmask) = preg_split('~/~', $cidr_address); + + $ip_address = $this->ip; + + // v6? + if ((str_contains($cidr_network, ':'))) { + if (!filter_var($ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || !filter_var($cidr_network, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + return false; + } + + $ip_address = inet_pton($ip_address); + $cidr_network = inet_pton($cidr_network); + $binMask = str_repeat('f', (int) $cidr_subnetmask / 4); + + switch ($cidr_subnetmask % 4) { + case 0: + break; + + case 1: + $binMask .= '8'; + break; + + case 2: + $binMask .= 'c'; + break; + + case 3: + $binMask .= 'e'; + break; + } + $binMask = str_pad($binMask, 32, '0'); + $binMask = pack('H*', $binMask); + + return ($ip_address & $binMask) == $cidr_network; + } + + return (ip2long($ip_address) & (~((1 << (32 - $cidr_subnetmask)) - 1))) == ip2long($cidr_network); + } + /*********************** * Public static methods ***********************/ diff --git a/Sources/QueryString.php b/Sources/QueryString.php index 33fb06f665..0aa5a48737 100644 --- a/Sources/QueryString.php +++ b/Sources/QueryString.php @@ -275,7 +275,10 @@ public static function cleanRequest(): void $valid_sender = false; foreach (explode(',', Config::$modSettings['proxy_ip_servers']) as $proxy) { - if ($proxy == $_SERVER['REMOTE_ADDR'] || self::matchIPtoCIDR($_SERVER['REMOTE_ADDR'], $proxy)) { + if ( + $proxy == $_SERVER['REMOTE_ADDR'] + || (new IP($_SERVER['REMOTE_ADDR']))->matchToCIDR($proxy) + ) { $valid_sender = true; break; } @@ -467,53 +470,6 @@ function ($m) { return $buffer; } - /** - * Detect if a IP is in a CIDR address. - * - * @static - * @param string $ip_address IP address to check. - * @param string $cidr_address CIDR address to verify. - * @return bool Whether the IP matches the CIDR. - */ - public static function matchIPtoCIDR(string $ip_address, string $cidr_address): bool - { - list($cidr_network, $cidr_subnetmask) = preg_split('~/~', $cidr_address); - - // v6? - if ((str_contains($cidr_network, ':'))) { - if (!filter_var($ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || !filter_var($cidr_network, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { - return false; - } - - $ip_address = inet_pton($ip_address); - $cidr_network = inet_pton($cidr_network); - $binMask = str_repeat('f', (int) $cidr_subnetmask / 4); - - switch ($cidr_subnetmask % 4) { - case 0: - break; - - case 1: - $binMask .= '8'; - break; - - case 2: - $binMask .= 'c'; - break; - - case 3: - $binMask .= 'e'; - break; - } - $binMask = str_pad($binMask, 32, '0'); - $binMask = pack('H*', $binMask); - - return ($ip_address & $binMask) == $cidr_network; - } - - return (ip2long($ip_address) & (~((1 << (32 - $cidr_subnetmask)) - 1))) == ip2long($cidr_network); - } - /** * Handles redirecting 'index.php?msg=123' links to the canonical URL. */ diff --git a/Sources/Subs-Compat.php b/Sources/Subs-Compat.php index 46fb187559..c9a063f943 100644 --- a/Sources/Subs-Compat.php +++ b/Sources/Subs-Compat.php @@ -3817,6 +3817,11 @@ function expandIPv6(string $ip, bool $return_bool_if_invalid = true): string|boo return $ip->expand(); } + function matchIPtoCIDR(string $ip_address, string $cidr_address): bool + { + return (new SMF\IP($ip_address))->matchtoCIDR($cidr_address); + } + /** * Begin * SMF\ItemList @@ -4252,11 +4257,6 @@ function ob_sessrewrite(string $buffer): string return SMF\QueryString::ob_sessrewrite($buffer); } - function matchIPtoCIDR(string $ip_address, string $cidr_address): bool - { - return SMF\QueryString::matchIPtoCIDR($ip_address, $cidr_address); - } - /** * Begin * SMF\Sapi