<?php
namespace XF\Spam\Checker;
use function count, intval, is_array;
abstract class AbstractDnsBl extends AbstractProvider
{
protected function checkIp($host, $getFinalOctet = true)
{
$ip = $this->app()->request()->getIp();
$dnsBlCache = $this->app()->registry()['dnsBlCache'] ?: [];
if (!empty($dnsBlCache[$ip]) && $dnsBlCache[$ip]['expiry'] > time())
{
return $this->processDecision($dnsBlCache[$ip]['type']); // seen before
}
$parts = explode('.', trim($ip));
if (count($parts) != 4)
{
return false;
}
$parts = array_map('intval', $parts);
$parts = array_reverse($parts);
$query = sprintf($host, implode('.', $parts));
$result = gethostbyname($query);
if (!$result)
{
return false;
}
if ($result === $query)
{
// not found
return false;
}
$resultParts = explode('.', $result);
if (count($resultParts) < 4)
{
return false;
}
if ($getFinalOctet)
{
return $this->getFinalOctetIf($resultParts);
}
else
{
return $resultParts;
}
}
protected function getFinalOctetIf($resultParts, $part0 = '127', $part1 = '0', $part2 = '0')
{
if (!is_array($resultParts) || count($resultParts) != 4)
{
return false;
}
if ($resultParts[0] == $part0 && $resultParts[1] == $part1 && $resultParts[2] == $part2)
{
return intval($resultParts[3]);
}
else
{
return false;
}
}
protected function processDecision($block, $cacheResult = false)
{
$decision = 'allowed';
if ($block)
{
$action = $this->app()->options()->registrationCheckDnsBl['action'];
if ($action == 'block')
{
$decision = 'denied';
}
else
{
$decision = 'moderated';
}
$this->logDetail('dnsbl_matched');
}
if ($cacheResult)
{
$registry= $this->app()->registry();
$ip = $this->app()->request()->getIp();
$dnsBlCache = $registry['dnsBlCache'] ?: [];
$dnsBlCache[$ip] = ['type' => $block, 'expiry' => time() + 3600];
foreach ($dnsBlCache AS $key => $data)
{
if ($data['expiry'] <= time())
{
unset($dnsBlCache[$key]);
}
}
$registry->set('dnsBlCache', $dnsBlCache);
}
$this->logDecision($decision);
return false;
}
}