Merge pull request #6453 from Noxwizard/ticket/17092

[ticket/17092] Check for Spamhaus error codes
This commit is contained in:
Marc Alexander 2023-01-18 19:52:18 +01:00
commit 6590827316
No known key found for this signature in database
GPG key ID: 50E0D2423696F995
2 changed files with 111 additions and 7 deletions

View file

@ -738,6 +738,10 @@ $lang = array_merge($lang, array(
'LOG_SEARCH_INDEX_CREATED' => '<strong>Created search index for</strong><br />» %s',
'LOG_SEARCH_INDEX_REMOVED' => '<strong>Removed search index for</strong><br />» %s',
'LOG_SPHINX_ERROR' => '<strong>Sphinx Error</strong><br />» %s',
'LOG_SPAMHAUS_OPEN_RESOLVER' => 'Spamhaus does not allow queries using an open resolver. Blacklist checking has been disabled. For more information, see https://www.spamhaus.com/product/help-for-spamhaus-public-mirror-users/.',
'LOG_SPAMHAUS_VOLUME_LIMIT' => 'Spamhaus query volume limit has been exceeded. Blacklist checking has been disabled. For more information, see https://www.spamhaus.com/product/help-for-spamhaus-public-mirror-users/.',
'LOG_STYLE_ADD' => '<strong>Added new style</strong><br />» %s',
'LOG_STYLE_DELETE' => '<strong>Deleted style</strong><br />» %s',
'LOG_STYLE_EDIT_DETAILS' => '<strong>Edited style</strong><br />» %s',

View file

@ -1346,6 +1346,109 @@ class session
}
}
/**
* Check if ip is blacklisted by Spamhaus SBL
*
* Disables DNSBL setting if errors are returned by Spamhaus due to a policy violation.
* https://www.spamhaus.com/product/help-for-spamhaus-public-mirror-users/
*
* @param string $dnsbl the blacklist to check against
* @param string|false $ip the IPv4 address to check
*
* @return bool true if listed in spamhaus database, false if not
*/
function check_dnsbl_spamhaus($dnsbl, $ip = false)
{
global $config, $phpbb_log;
if ($ip === false)
{
$ip = $this->ip;
}
// Spamhaus does not support IPv6 addresses.
if (strpos($ip, ':') !== false)
{
return false;
}
if ($ip)
{
$quads = explode('.', $ip);
$reverse_ip = $quads[3] . '.' . $quads[2] . '.' . $quads[1] . '.' . $quads[0];
$records = dns_get_record($reverse_ip . '.' . $dnsbl . '.', DNS_A);
if (empty($records))
{
return false;
}
else
{
$error = false;
foreach ($records as $record)
{
if ($record['ip'] == '127.255.255.254')
{
$error = 'LOG_SPAMHAUS_OPEN_RESOLVER';
break;
}
else if ($record['ip'] == '127.255.255.255')
{
$error = 'LOG_SPAMHAUS_VOLUME_LIMIT';
break;
}
}
if ($error !== false)
{
$config->set('check_dnsbl', 0);
$phpbb_log->add('critical', $this->data['user_id'], $ip, $error);
}
else
{
// The existence of a non-error A record means it's a hit
return true;
}
}
}
return false;
}
/**
* Checks if an IPv4 address is in a specified DNS blacklist
*
* Only checks if a record is returned or not.
*
* @param string $dnsbl the blacklist to check against
* @param string|false $ip the IPv4 address to check
*
* @return bool true if record is returned, false if not
*/
function check_dnsbl_ipv4_generic($dnsbl, $ip = false)
{
if ($ip === false)
{
$ip = $this->ip;
}
// This function does not support IPv6 addresses.
if (strpos($ip, ':') !== false)
{
return false;
}
$quads = explode('.', $ip);
$reverse_ip = $quads[3] . '.' . $quads[2] . '.' . $quads[1] . '.' . $quads[0];
if (checkdnsrr($reverse_ip . '.' . $dnsbl . '.', 'A') === true)
{
return true;
}
return false;
}
/**
* Check if ip is blacklisted
* This should be called only where absolutely necessary
@ -1372,28 +1475,25 @@ class session
}
$dnsbl_check = array(
'sbl.spamhaus.org' => 'http://www.spamhaus.org/query/bl?ip=',
'sbl.spamhaus.org' => ['http://www.spamhaus.org/query/bl?ip=', 'check_dnsbl_spamhaus'],
);
if ($mode == 'register')
{
$dnsbl_check['bl.spamcop.net'] = 'http://spamcop.net/bl.shtml?';
$dnsbl_check['bl.spamcop.net'] = ['http://spamcop.net/bl.shtml?', 'check_dnsbl_ipv4_generic'];
}
if ($ip)
{
$quads = explode('.', $ip);
$reverse_ip = $quads[3] . '.' . $quads[2] . '.' . $quads[1] . '.' . $quads[0];
// Need to be listed on all servers...
$listed = true;
$info = array();
foreach ($dnsbl_check as $dnsbl => $lookup)
{
if (checkdnsrr($reverse_ip . '.' . $dnsbl . '.', 'A') === true)
if (call_user_func(array($this, $lookup[1]), $dnsbl, $ip) === true)
{
$info = array($dnsbl, $lookup . $ip);
$info = array($dnsbl, $lookup[0] . $ip);
}
else
{