aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorVincent Petry <vincent@nextcloud.com>2021-11-23 10:36:46 +0100
committerGitHub <noreply@github.com>2021-11-23 10:36:46 +0100
commit3040386bf8bc55be05641181128723da998879d6 (patch)
treec0b5f2d33be37af5098f655c1324aabe1c521180 /lib
parent079c4c82d3e10040fc100c61b74907bf006a239a (diff)
parent19f41a60a0a61f8abb014a2062621819c71d79ac (diff)
downloadnextcloud-server-3040386bf8bc55be05641181128723da998879d6.tar.gz
nextcloud-server-3040386bf8bc55be05641181128723da998879d6.zip
Merge pull request #29835 from nextcloud/bugfix/noid/fix-ipv4-mapped-ipv6-subnet
Fix getting subnet of ipv4 mapped ipv6 addresses
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Security/Normalizer/IpAddress.php41
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/private/Security/Normalizer/IpAddress.php b/lib/private/Security/Normalizer/IpAddress.php
index 705235413e4..98d85ce07a1 100644
--- a/lib/private/Security/Normalizer/IpAddress.php
+++ b/lib/private/Security/Normalizer/IpAddress.php
@@ -93,6 +93,38 @@ class IpAddress {
}
/**
+ * Returns the IPv4 address embedded in an IPv6 if applicable.
+ * The detected format is "::ffff:x.x.x.x" using the binary form.
+ *
+ * @return string|null embedded IPv4 string or null if none was found
+ */
+ private function getEmbeddedIpv4(string $ipv6): ?string {
+ $binary = inet_pton($ipv6);
+ if (!$binary) {
+ return null;
+ }
+ for ($i = 0; $i <= 9; $i++) {
+ if (unpack('C', $binary[$i])[1] !== 0) {
+ return null;
+ }
+ }
+
+ for ($i = 10; $i <= 11; $i++) {
+ if (unpack('C', $binary[$i])[1] !== 255) {
+ return null;
+ }
+ }
+
+ $binary4 = '';
+ for ($i = 12; $i < 16; $i++) {
+ $binary4 .= $binary[$i];
+ }
+
+ return inet_ntop($binary4);
+ }
+
+
+ /**
* Gets either the /32 (IPv4) or the /64 (IPv6) subnet of an IP address
*
* @return string
@@ -104,6 +136,15 @@ class IpAddress {
32
);
}
+
+ $ipv4 = $this->getEmbeddedIpv4($this->ip);
+ if ($ipv4 !== null) {
+ return $this->getIPv4Subnet(
+ $ipv4,
+ 32
+ );
+ }
+
return $this->getIPv6Subnet(
$this->ip,
64