diff options
author | Vincent Petry <vincent@nextcloud.com> | 2021-11-23 10:36:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-23 10:36:46 +0100 |
commit | 3040386bf8bc55be05641181128723da998879d6 (patch) | |
tree | c0b5f2d33be37af5098f655c1324aabe1c521180 /lib | |
parent | 079c4c82d3e10040fc100c61b74907bf006a239a (diff) | |
parent | 19f41a60a0a61f8abb014a2062621819c71d79ac (diff) | |
download | nextcloud-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.php | 41 |
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 |