PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.12.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.12.1
5.12.1 5.12.0 5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / vendor / prefixed / symfony / http-foundation / IpUtils.php
matomo / app / vendor / prefixed / symfony / http-foundation Last commit date
Exception 2 years ago File 1 year ago RateLimiter 2 years ago Session 1 year ago Test 1 year ago AcceptHeader.php 1 year ago AcceptHeaderItem.php 2 years ago BinaryFileResponse.php 1 year ago Cookie.php 1 year ago ExpressionRequestMatcher.php 2 years ago FileBag.php 1 year ago HeaderBag.php 1 year ago HeaderUtils.php 1 year ago InputBag.php 2 years ago IpUtils.php 1 year ago JsonResponse.php 1 year ago LICENSE 2 years ago ParameterBag.php 1 year ago README.md 2 years ago RedirectResponse.php 2 years ago Request.php 8 months ago RequestMatcher.php 1 year ago RequestMatcherInterface.php 2 years ago RequestStack.php 2 years ago Response.php 1 year ago ResponseHeaderBag.php 1 year ago ServerBag.php 1 year ago StreamedResponse.php 1 year ago UrlHelper.php 2 years ago
IpUtils.php
182 lines
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 namespace Matomo\Dependencies\Symfony\Component\HttpFoundation;
12
13 /**
14 * Http utility functions.
15 *
16 * @author Fabien Potencier <fabien@symfony.com>
17 */
18 class IpUtils
19 {
20 private static $checkedIps = [];
21 /**
22 * This class should not be instantiated.
23 */
24 private function __construct()
25 {
26 }
27 /**
28 * Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets.
29 *
30 * @param string|array $ips List of IPs or subnets (can be a string if only a single one)
31 *
32 * @return bool
33 */
34 public static function checkIp(?string $requestIp, $ips)
35 {
36 if (null === $requestIp) {
37 trigger_deprecation('symfony/http-foundation', '5.4', 'Passing null as $requestIp to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
38 return \false;
39 }
40 if (!\is_array($ips)) {
41 $ips = [$ips];
42 }
43 $method = substr_count($requestIp, ':') > 1 ? 'checkIp6' : 'checkIp4';
44 foreach ($ips as $ip) {
45 if (self::$method($requestIp, $ip)) {
46 return \true;
47 }
48 }
49 return \false;
50 }
51 /**
52 * Compares two IPv4 addresses.
53 * In case a subnet is given, it checks if it contains the request IP.
54 *
55 * @param string $ip IPv4 address or subnet in CIDR notation
56 *
57 * @return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet
58 */
59 public static function checkIp4(?string $requestIp, string $ip)
60 {
61 if (null === $requestIp) {
62 trigger_deprecation('symfony/http-foundation', '5.4', 'Passing null as $requestIp to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
63 return \false;
64 }
65 $cacheKey = $requestIp . '-' . $ip . '-v4';
66 if (isset(self::$checkedIps[$cacheKey])) {
67 return self::$checkedIps[$cacheKey];
68 }
69 if (!filter_var($requestIp, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) {
70 return self::$checkedIps[$cacheKey] = \false;
71 }
72 if (str_contains($ip, '/')) {
73 [$address, $netmask] = explode('/', $ip, 2);
74 if ('0' === $netmask) {
75 return self::$checkedIps[$cacheKey] = \false !== filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4);
76 }
77 if ($netmask < 0 || $netmask > 32) {
78 return self::$checkedIps[$cacheKey] = \false;
79 }
80 } else {
81 $address = $ip;
82 $netmask = 32;
83 }
84 if (\false === ip2long($address)) {
85 return self::$checkedIps[$cacheKey] = \false;
86 }
87 return self::$checkedIps[$cacheKey] = 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
88 }
89 /**
90 * Compares two IPv6 addresses.
91 * In case a subnet is given, it checks if it contains the request IP.
92 *
93 * @author David Soria Parra <dsp at php dot net>
94 *
95 * @see https://github.com/dsp/v6tools
96 *
97 * @param string $ip IPv6 address or subnet in CIDR notation
98 *
99 * @return bool
100 *
101 * @throws \RuntimeException When IPV6 support is not enabled
102 */
103 public static function checkIp6(?string $requestIp, string $ip)
104 {
105 if (null === $requestIp) {
106 trigger_deprecation('symfony/http-foundation', '5.4', 'Passing null as $requestIp to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
107 return \false;
108 }
109 $cacheKey = $requestIp . '-' . $ip . '-v6';
110 if (isset(self::$checkedIps[$cacheKey])) {
111 return self::$checkedIps[$cacheKey];
112 }
113 if (!(\extension_loaded('sockets') && \defined('AF_INET6') || @inet_pton('::1'))) {
114 throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
115 }
116 // Check to see if we were given a IP4 $requestIp or $ip by mistake
117 if (!filter_var($requestIp, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
118 return self::$checkedIps[$cacheKey] = \false;
119 }
120 if (str_contains($ip, '/')) {
121 [$address, $netmask] = explode('/', $ip, 2);
122 if (!filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
123 return self::$checkedIps[$cacheKey] = \false;
124 }
125 if ('0' === $netmask) {
126 return (bool) unpack('n*', @inet_pton($address));
127 }
128 if ($netmask < 1 || $netmask > 128) {
129 return self::$checkedIps[$cacheKey] = \false;
130 }
131 } else {
132 if (!filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
133 return self::$checkedIps[$cacheKey] = \false;
134 }
135 $address = $ip;
136 $netmask = 128;
137 }
138 $bytesAddr = unpack('n*', @inet_pton($address));
139 $bytesTest = unpack('n*', @inet_pton($requestIp));
140 if (!$bytesAddr || !$bytesTest) {
141 return self::$checkedIps[$cacheKey] = \false;
142 }
143 for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
144 $left = $netmask - 16 * ($i - 1);
145 $left = $left <= 16 ? $left : 16;
146 $mask = ~(0xffff >> $left) & 0xffff;
147 if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
148 return self::$checkedIps[$cacheKey] = \false;
149 }
150 }
151 return self::$checkedIps[$cacheKey] = \true;
152 }
153 /**
154 * Anonymizes an IP/IPv6.
155 *
156 * Removes the last byte for v4 and the last 8 bytes for v6 IPs
157 */
158 public static function anonymize(string $ip) : string
159 {
160 $wrappedIPv6 = \false;
161 if ('[' === substr($ip, 0, 1) && ']' === substr($ip, -1, 1)) {
162 $wrappedIPv6 = \true;
163 $ip = substr($ip, 1, -1);
164 }
165 $packedAddress = inet_pton($ip);
166 if (4 === \strlen($packedAddress)) {
167 $mask = '255.255.255.0';
168 } elseif ($ip === inet_ntop($packedAddress & inet_pton('::ffff:ffff:ffff'))) {
169 $mask = '::ffff:ffff:ff00';
170 } elseif ($ip === inet_ntop($packedAddress & inet_pton('::ffff:ffff'))) {
171 $mask = '::ffff:ff00';
172 } else {
173 $mask = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000';
174 }
175 $ip = inet_ntop($packedAddress & inet_pton($mask));
176 if ($wrappedIPv6) {
177 $ip = '[' . $ip . ']';
178 }
179 return $ip;
180 }
181 }
182