Skip to content

Commit

Permalink
refactor(wopi): Use symfony/http-foundation util to match ip addresses
Browse files Browse the repository at this point in the history
Signed-off-by: Julius Härtl <[email protected]>
  • Loading branch information
juliusknorr committed Dec 21, 2022
1 parent ee8817c commit f32dbe8
Showing 1 changed file with 3 additions and 62 deletions.
65 changes: 3 additions & 62 deletions lib/Middleware/WOPIMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use OCP\IConfig;
use OCP\IRequest;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\IpUtils;

class WOPIMiddleware extends Middleware {
/** @var IConfig */
Expand Down Expand Up @@ -98,71 +99,11 @@ public function isWOPIAllowed(): bool {
$allowedRanges = preg_split('/(\s|,|;|\|)+/', $allowedRanges);

$userIp = $this->request->getRemoteAddress();
foreach ($allowedRanges as $range) {
if ($this->matchCidr($userIp, $range)) {
return true;
}
if (IpUtils::checkIp($userIp, $allowedRanges)) {
return true;
}

$this->logger->info('WOPI request denied from ' . $userIp . ' as it does not match the configured ranges: ' . implode(', ', $allowedRanges));
return false;
}

/**
* @copyright https://stackoverflow.com/questions/594112/matching-an-ip-to-a-cidr-mask-in-php-5/594134#594134
* @copyright (IPv4) https://stackoverflow.com/questions/594112/matching-an-ip-to-a-cidr-mask-in-php-5/594134#594134
* @copyright (IPv6) MW. https://stackoverflow.com/questions/7951061/matching-ipv6-address-to-a-cidr-subnet via
*/
private function matchCidr(string $ip, string $range): bool {
list($subnet, $bits) = array_pad(explode('/', $range), 2, null);
if ($bits === null) {
$bits = strpos($subnet, ':') !== false ? 128 : 32;
}
$bits = (int)$bits;

if ($this->isIpv4($ip) && $this->isIpv4($subnet)) {
$mask = -1 << (32 - $bits);

$ip = ip2long($ip);
$subnet = ip2long($subnet);
$subnet &= $mask;
return ($ip & $mask) === $subnet;
}

if ($this->isIpv6($ip) && $this->isIPv6($subnet)) {
$subnet = inet_pton($subnet);
$ip = inet_pton($ip);

$binMask = str_repeat("f", $bits / 4);
switch ($bits % 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);

if (($ip & $binMask) === $subnet) {
return true;
}
}
return false;
}

private function isIpv4($ip) {
return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
}

private function isIpv6($ip) {
return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
}
}

0 comments on commit f32dbe8

Please sign in to comment.