aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/_test/tests/inc/Ip.test.php
diff options
context:
space:
mode:
Diffstat (limited to '_test/tests/inc/Ip.test.php')
-rw-r--r--_test/tests/inc/Ip.test.php335
1 files changed, 335 insertions, 0 deletions
diff --git a/_test/tests/inc/Ip.test.php b/_test/tests/inc/Ip.test.php
new file mode 100644
index 000000000..4d84a77ec
--- /dev/null
+++ b/_test/tests/inc/Ip.test.php
@@ -0,0 +1,335 @@
+<?php
+
+use dokuwiki\Ip;
+
+class ip_test extends DokuWikiTest {
+
+ /**
+ * The data provider for ipToNumber() tests.
+ *
+ * @return mixed[][] Returns an array of test cases.
+ */
+ public function ip_to_number_provider() : array
+ {
+ $tests = [
+ ['127.0.0.1', 4, 0x00000000, 0x7f000001],
+ ['::127.0.0.1', 6, 0x00000000, 0x7f000001],
+ ['::1', 6, 0x00000000, 0x00000001],
+ ['38AF:3033:AA39:CDE3:1A46:094C:44ED:5300', 6, 0x38AF3033AA39CDE3, 0x1A46094C44ED5300],
+ ['193.53.125.7', 4, 0x00000000, 0xC1357D07],
+ ];
+
+ return $tests;
+ }
+
+ /**
+ * Test ipToNumber().
+ *
+ * @dataProvider ip_to_number_provider
+ *
+ * @param string $ip The IP address to convert.
+ * @param int $version The IP version, either 4 or 6.
+ * @param int $upper The upper 64 bits of the IP.
+ * @param int $lower The lower 64 bits of the IP.
+ *
+ * @return void
+ */
+ public function test_ip_to_number(string $ip, int $version, int $upper, int $lower): void
+ {
+ $result = Ip::ipToNumber($ip);
+
+ $this->assertSame($version, $result['version']);
+ $this->assertSame($upper, $result['upper']);
+ $this->assertSame($lower, $result['lower']);
+ }
+
+ /**
+ * The data provider for test_ip_in_range().
+ *
+ * @return mixed[][] Returns an array of test cases.
+ */
+ public function ip_in_range_provider(): array
+ {
+ $tests = [
+ ['192.168.11.2', '192.168.0.0/16', true],
+ ['192.168.11.2', '192.168.64.1/16', true],
+ ['192.168.11.2', '192.168.64.1/18', false],
+ ['192.168.11.2', '192.168.11.0/20', true],
+ ['127.0.0.1', '127.0.0.0/7', true],
+ ['127.0.0.1', '127.0.0.0/8', true],
+ ['127.0.0.1', '127.200.0.0/8', true],
+ ['127.0.0.1', '127.200.0.0/9', false],
+ ['127.0.0.1', '127.0.0.0/31', true],
+ ['127.0.0.1', '127.0.0.0/32', false],
+ ['127.0.0.1', '127.0.0.1/32', true],
+ ['1111:2222:3333:4444:5555:6666:7777:8888', '1110::/12', true],
+ ['1110:2222:3333:4444:5555:6666:7777:8888', '1110::/12', true],
+ ['1100:2222:3333:4444:5555:6666:7777:8888', '1110::/12', false],
+ ['1111:2222:3333:4444:5555:6666:7777:8888', '1111:2222:3300::/40', true],
+ ['1111:2222:3333:4444:5555:6666:7777:8888', '1111:2222:3200::/40', false],
+ ['1111:2222:3333:4444:5555:6666:7777:8888', '1111:2222:3333:4444:5555:6666:7777:8889/127', true],
+ ['1111:2222:3333:4444:5555:6666:7777:8888', '1111:2222:3333:4444:5555:6666:7777:8889/128', false],
+ ['1111:2222:3333:4444:5555:6666:7777:8889', '1111:2222:3333:4444:5555:6666:7777:8889/128', true],
+ ['abcd:ef0a:bcde:f0ab:cdef:0abc:def0:abcd', 'abcd:ef0a:bcde:f0ab:cdef:0abc:def0:abcd/128', true],
+ ['abcd:ef0a:bcde:f0ab:cdef:0abc:def0:abce', 'abcd:ef0a:bcde:f0ab:cdef:0abc:def0:abcd/128', false],
+ ];
+
+ return $tests;
+ }
+
+ /**
+ * Test ipInRange().
+ *
+ * @dataProvider ip_in_range_provider
+ *
+ * @param string $ip The IP to test.
+ * @param string $range The IP range to test against.
+ * @param bool $expected The expected result from ipInRange().
+ *
+ * @return void
+ */
+ public function test_ip_in_range(string $ip, string $range, bool $expected): void
+ {
+ $result = Ip::ipInRange($ip, $range);
+
+ $this->assertSame($expected, $result);
+ }
+
+ /**
+ * Data provider for test_ip_matches().
+ *
+ * @return mixed[][] Returns an array of test cases.
+ */
+ public function ip_matches_provider(): array
+ {
+ // Tests for a CIDR range.
+ $rangeTests = $this->ip_in_range_provider();
+
+ // Tests for an exact IP match.
+ $exactTests = [
+ ['127.0.0.1', '127.0.0.1', true],
+ ['127.0.0.1', '127.0.0.0', false],
+ ['aaaa:bbbb:cccc:dddd:eeee::', 'aaaa:bbbb:cccc:dddd:eeee:0000:0000:0000', true],
+ ['aaaa:bbbb:cccc:dddd:eeee:0000:0000:0000', 'aaaa:bbbb:cccc:dddd:eeee::', true],
+ ['aaaa:bbbb:0000:0000:0000:0000:0000:0001', 'aaaa:bbbb::1', true],
+ ['aaaa:bbbb::0001', 'aaaa:bbbb::1', true],
+ ['aaaa:bbbb::0001', 'aaaa:bbbb::', false],
+ ['::ffff:127.0.0.1', '127.0.0.1', false],
+ ['::ffff:127.0.0.1', '::0:ffff:127.0.0.1', true],
+ ];
+
+
+ return array_merge($rangeTests, $exactTests);
+ }
+
+ /**
+ * Test ipMatches().
+ *
+ * @dataProvider ip_matches_provider
+ *
+ * @param string $ip The IP to test.
+ * @param string $ipOrRange The IP or IP range to test against.
+ * @param bool $expected The expeced result from ipMatches().
+ *
+ * @return void
+ */
+ public function test_ip_matches(string $ip, string $ipOrRange, bool $expected): void
+ {
+ $result = Ip::ipMatches($ip, $ipOrRange);
+
+ $this->assertSame($expected, $result);
+ }
+
+ /**
+ * Data provider for proxyIsTrusted().
+ *
+ * @return mixed[][] Returns an array of test cases.
+ */
+ public function proxy_is_trusted_provider(): array
+ {
+ // The default value that shipped with the config.
+ $legacyDefault = '^(::1|[fF][eE]80:|127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)';
+
+ // The new default configuration value.
+ $default = ['::1', 'fe80::/10', '127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'];
+
+ // Adding some custom trusted proxies.
+ $custom = array_merge($default, ['1.2.3.4', '1122::', '3.0.0.1/8', '1111:2222::/32']);
+
+ $tests = [
+ // Empty configuration.
+ ['', '127.0.0.1', false],
+
+ // Legacy configuration with a regular expression.
+ [$legacyDefault, '127.0.0.1', true],
+ [$legacyDefault, '127.1.2.3', true],
+ [$legacyDefault, '10.1.2.3', true],
+ [$legacyDefault, '11.1.2.3', false],
+ [$legacyDefault, '172.16.0.1', true],
+ [$legacyDefault, '172.160.0.1', false],
+ [$legacyDefault, '172.31.255.255', true],
+ [$legacyDefault, '172.32.0.0', false],
+ [$legacyDefault, '172.200.0.0', false],
+ [$legacyDefault, '192.168.2.3', true],
+ [$legacyDefault, '192.169.1.2', false],
+ [$legacyDefault, '::1', true],
+
+ // Configuration with an array of IPs/CIDRs.
+ [$default, '127.0.0.1', true],
+ [$default, '127.1.2.3', true],
+ [$default, '10.1.2.3', true],
+ [$default, '11.1.2.3', false],
+ [$default, '172.16.0.1', true],
+ [$default, '172.160.0.1', false],
+ [$default, '172.31.255.255', true],
+ [$default, '172.32.0.0', false],
+ [$default, '172.200.0.0', false],
+ [$default, '192.168.2.3', true],
+ [$default, '192.169.1.2', false],
+ [$default, '::1', true],
+ [$default, '0000:0000:0000:0000:0000:0000:0000:0001', true],
+
+ // With custom proxies set.
+ [$custom, '127.0.0.1', true],
+ [$custom, '1.2.3.4', true],
+ [$custom, '3.0.1.2', true],
+ [$custom, '1122::', true],
+ [$custom, '1122:0000:0000:0000:0000:0000:0000:0000', true],
+ [$custom, '1111:2223::', false],
+ [$custom, '1111:2222::', true],
+ [$custom, '1111:2222:3333::', true],
+ [$custom, '1111:2222:3333::1', true],
+ ];
+
+ return $tests;
+ }
+
+ /**
+ * Test proxyIsTrusted().
+ *
+ * @dataProvider proxy_is_trusted_provider
+ *
+ * @param string|string[] $config The value for $conf[trustedproxy].
+ * @param string $ip The proxy IP to test.
+ * @param bool $expected The expected result from proxyIsTrusted().
+ */
+ public function test_proxy_is_trusted($config, string $ip, bool $expected): void
+ {
+ global $conf;
+ $conf['trustedproxy'] = $config;
+
+ $result = Ip::proxyIsTrusted($ip);
+
+ $this->assertSame($expected, $result);
+ }
+
+ /**
+ * Data provider for test_forwarded_for().
+ *
+ * @return mixed[][] Returns an array of test cases.
+ */
+ public function forwarded_for_provider(): array
+ {
+ // The default value that shipped with the config.
+ $legacyDefault = '^(::1|[fF][eE]80:|127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)';
+
+ // The new default configuration value.
+ $default = ['::1', 'fe80::/10', '127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'];
+
+ // Adding some custom trusted proxies.
+ $custom = array_merge($default, ['1.2.3.4', '1122::', '3.0.0.1/8', '1111:2222::/32']);
+
+ $tests = [
+ // Empty config value should always return empty array.
+ ['', '', '127.0.0.1', []],
+ ['', '127.0.0.1', '127.0.0.1', []],
+ [[], '', '127.0.0.1', []],
+ [[], '127.0.0.1', '127.0.0.1', []],
+
+ // The old default configuration.
+ [$legacyDefault, '', '127.0.0.1', []],
+ [$legacyDefault, '1.2.3.4', '127.0.0.1', ['1.2.3.4', '127.0.0.1']],
+ [$legacyDefault, '1.2.3.4', '192.168.1.1', ['1.2.3.4', '192.168.1.1']],
+ [$legacyDefault, '1.2.3.4,172.16.0.1', '192.168.1.1', ['1.2.3.4', '172.16.0.1', '192.168.1.1']],
+ [$legacyDefault, '1.2.3.4,172.16.0.1', '::1', ['1.2.3.4', '172.16.0.1', '::1']],
+
+ // Directly from an untrusted proxy.
+ [$legacyDefault, '', '127.0.0.1', []],
+ [$legacyDefault, '1.2.3.4', '11.22.33.44', []],
+ [$legacyDefault, '::1', '11.22.33.44', []],
+
+ // From a trusted proxy, but via an untrusted proxy.
+ [$legacyDefault, '1.2.3.4,11.22.33.44,172.16.0.1', '192.168.1.1', []],
+ [$legacyDefault, '1.2.3.4,::2,172.16.0.1', '::1', []],
+
+ // The new default configuration.
+ [$default, '', '127.0.0.1', []],
+ [$default, '1.2.3.4', '127.0.0.1', ['1.2.3.4', '127.0.0.1']],
+ [$default, '1.2.3.4', '192.168.1.1', ['1.2.3.4', '192.168.1.1']],
+ [$default, '1.2.3.4,172.16.0.1', '192.168.1.1', ['1.2.3.4', '172.16.0.1', '192.168.1.1']],
+ [$default, '1.2.3.4,172.16.0.1', '::1', ['1.2.3.4', '172.16.0.1', '::1']],
+ [$default, '1.2.3.4,172.16.0.1', '::0001', ['1.2.3.4', '172.16.0.1', '::0001']],
+
+ // Directly from an untrusted proxy.
+ [$default, '', '127.0.0.1', []],
+ [$default, '1.2.3.4', '11.22.33.44', []],
+ [$default, '::1', '11.22.33.44', []],
+ [$default, '::1', '::2', []],
+
+ // From a trusted proxy, but via an untrusted proxy.
+ [$default, '1.2.3.4,11.22.33.44,172.16.0.1', '192.168.1.1', []],
+ [$default, '1.2.3.4,::2,172.16.0.1', '::1', []],
+
+ // A custom configuration.
+ [$custom, '', '127.0.0.1', []],
+ [$custom, '1.2.3.4', '127.0.0.1', ['1.2.3.4', '127.0.0.1']],
+ [$custom, '1.2.3.4', '192.168.1.1', ['1.2.3.4', '192.168.1.1']],
+ [$custom, '1.2.3.4,172.16.0.1', '192.168.1.1', ['1.2.3.4', '172.16.0.1', '192.168.1.1']],
+ [$custom, '1.2.3.4,172.16.0.1', '::1', ['1.2.3.4', '172.16.0.1', '::1']],
+ [$custom, '1.2.3.4,172.16.0.1', '::0001', ['1.2.3.4', '172.16.0.1', '::0001']],
+
+ // Directly from an untrusted proxy.
+ [$custom, '', '127.0.0.1', []],
+ [$custom, '1.2.3.4', '11.22.33.44', []],
+ [$custom, '::1', '11.22.33.44', []],
+ [$custom, '::1', '::2', []],
+
+ // From a trusted proxy, but via an untrusted proxy.
+ [$custom, '1.2.3.4,11.22.33.44,172.16.0.1', '192.168.1.1', []],
+ [$custom, '1.2.3.4,::2,172.16.0.1', '::1', []],
+
+ // Via a custom proxy.
+ [$custom, '11.2.3.4,3.1.2.3,172.16.0.1', '192.168.1.1', ['11.2.3.4', '3.1.2.3', '172.16.0.1', '192.168.1.1']],
+ [$custom, '11.2.3.4,1122::,172.16.0.1', '3.0.0.1', ['11.2.3.4', '1122::', '172.16.0.1', '3.0.0.1']],
+ [$custom, '11.2.3.4,1122::,172.16.0.1', '1111:2222:3333::', ['11.2.3.4', '1122::', '172.16.0.1', '1111:2222:3333::']],
+ ];
+
+ return $tests;
+ }
+
+ /**
+ * Test forwardedFor().
+ *
+ * @dataProvider forwarded_for_provider
+ *
+ * @param string|string[] $config The trustedproxy config value.
+ * @param string $header The X-Forwarded-For header value.
+ * @param string $remoteAddr The TCP/IP peer address.
+ * @param array $expected The expected result from forwardedFor().
+ *
+ * @return void
+ */
+ public function test_forwarded_for($config, string $header, string $remoteAddr, array $expected): void
+ {
+ /* @var Input $INPUT */
+ global $INPUT, $conf;
+
+ $conf['trustedproxy'] = $config;
+ $INPUT->server->set('HTTP_X_FORWARDED_FOR', $header);
+ $INPUT->server->set('REMOTE_ADDR', $remoteAddr);
+
+ $result = Ip::forwardedFor();
+
+ $this->assertSame($expected, $result);
+ }
+}