diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index 64096bbed3..1bc0cf11af 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -738,6 +738,10 @@ $lang = array_merge($lang, array(
'LOG_SEARCH_INDEX_CREATED' => 'Created search index for
» %s',
'LOG_SEARCH_INDEX_REMOVED' => 'Removed search index for
» %s',
'LOG_SPHINX_ERROR' => 'Sphinx Error
» %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' => 'Added new style
» %s',
'LOG_STYLE_DELETE' => 'Deleted style
» %s',
'LOG_STYLE_EDIT_DETAILS' => 'Edited style
» %s',
diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php
index 6f25d3b650..0e016962bd 100644
--- a/phpBB/phpbb/session.php
+++ b/phpBB/phpbb/session.php
@@ -1346,6 +1346,110 @@ 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 true if listed in spamhaus database
+ */
+ 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 ($records === false || 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)
+ {
+ echo 'Error encountered
';
+ $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 true if record is returned
+ */
+ 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 +1476,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
{