function httpbl_comment_presave in http:BL 8
Same name and namespace in other branches
- 7 httpbl.module \httpbl_comment_presave()
Implements hook_comment_presave().
Checks and Blocks comment submissions from nuisance IPs.
File
- ./
httpbl.module, line 88 - Implements Project Honeypot's http:BL for Drupal. It provides IP-based blacklisting through http:BL and allows linking to a honeypot.
Code
function httpbl_comment_presave($comment) {
// Exit immediately if not configured for comment blocking only.
if (\Drupal::state()
->get('httpbl.check') != HTTPBL_CHECK_COMMENTS) {
return;
}
//Get the log service.
$logTrapper = \Drupal::service('httpbl.logtrapper');
// Check available storage options. These are used while blocking comment to
// inform comment reviewer of the extent of their options.
if (\Drupal::state()
->get('httpbl.storage') == HTTPBL_DB_HH || \Drupal::state()
->get('httpbl.storage') == HTTPBL_DB_HH_DRUPAL) {
// If auto-banning is enabled (using Httpbl with Ban module).
if (\Drupal::state()
->get('httpbl.storage') == HTTPBL_DB_HH_DRUPAL) {
$blacklist_and_ban = TRUE;
$no_storage = FALSE;
$blacklist_only = FALSE;
}
elseif (\Drupal::state()
->get('httpbl.storage') == HTTPBL_DB_HH) {
$no_storage = FALSE;
$blacklist_and_ban = FALSE;
$blacklist_only = TRUE;
}
}
else {
$no_storage = TRUE;
$blacklist_and_ban = FALSE;
$blacklist_only = FALSE;
}
// Get request info needed below.
$request = Drupal::request();
$requestUri = $request
->getRequestUri();
$ip = $request
->getClientIp();
// Log this comment check.
$logTrapper
->trapDebug('Checking @ip during comment pre-save.', [
'@ip' => $ip,
]);
//Get Evaluator service.
$httpblEvaluator = \Drupal::service('httpbl.evaluator');
// No Project Honeypot support for IPv6 addresses.
// If this is not an IPv4, set to skip evaluation.
$project_supported = TRUE;
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$project_supported = FALSE;
}
// Evaluation and comment processing begins.
if (!isset($evaluated)) {
// Evaluate this visitor IP.
$evaluated = $httpblEvaluator
->evaluateVisitor($ip, $request, $project_supported);
// If visitor was evaluated as not safe...
if ($evaluated[1] > HTTPBL_LIST_SAFE) {
// Comment user's IP found in Project Honeypot.
// Let them know.
drupal_set_message(t('Your comment was rejected because your IP address (@ip) is ranked "suspicious" by Project Honeypot.', [
'@ip' => $ip,
]), 'error', FALSE);
// Prepare to alter the comment subject and body.
// Make link to the blocked host profile on Project Honeypot.
$url = Url::fromUri('http://www.projecthoneypot.org/search_ip.php?ip=' . $ip);
$url_options = [
'attributes' => [
'class' => [
'httpbl-comment-blocked',
'httpbl-comment-blocked-profile',
],
'absolute' => TRUE,
],
];
$url
->setOptions($url_options);
$link = Link::fromTextAndUrl(t('Project Honeypot'), $url)
->toString();
$honeypot_profile = 'http://www.projecthoneypot.org/search_ip.php?ip=' . $ip;
// Force the comment to unpublished status.
$comment
->setPublished(0);
// Save original subject, then alter.
$original_subject = $comment
->getSubject();
$subject = t('(THIS COMMENT HAS BEEN Http:BL BLOCKED!)');
$comment
->setSubject($subject);
// Save original body, then alter
$original_body = $comment
->get('comment_body')->value;
// Add details for later comment review. Why the comment was blocked,
// with a link to the host's profile, if further research is desired.
$blocked_body = t('<p><strong>!!! This comment was blocked and unpublished by the httpbl module!!!</strong></p>');
$blocked_body .= t('<p><strong>Host IP (@ip) has been identified as a nuisance, by @Project.</strong></p>', [
'@ip' => $ip,
'@Project' => $link,
]);
// Prepare a suggestion link for using httpbl to blacklist (and possibly
// ban) a grey-listed host that makes repeated, comment annoyances.
$blacklistUrl = Url::fromRoute('httpbl.host_add');
$blacklistUrl_options = [
'attributes' => [
'class' => [
'httpbl-comment-blocked',
'httpbl-comment-blocked-config',
],
'target' => '_blank',
],
];
$blacklistUrl
->setOptions($blacklistUrl_options);
$blacklistLink = Link::fromTextAndUrl(t('blacklisting'), $blacklistUrl)
->toString();
// Prepare a suggestion link for using ban manager to ban IP.
$banUrl = Url::fromRoute('ban.admin_page');
$banUrl_options = [
'attributes' => [
'class' => [
'httpbl-comment-blocked',
'httpbl-comment-blocked-config',
],
'target' => '_blank',
],
];
$banUrl
->setOptions($banUrl_options);
$banLink = Link::fromTextAndUrl(t('banning'), $banUrl)
->toString();
// If this host is blacklisted...
if ($evaluated[1] == HTTPBL_LIST_BLACK) {
// Check for blacklisting & auto-banning
if ($blacklist_and_ban) {
// Find the host and get its ID and expiry date.
$hosts = HostQuery::loadHostsByIp($ip);
// Get the host expire time (from httpbl).
foreach ($hosts as $host) {
$hostId = $host->hid->value;
$expires = \Drupal::service('date.formatter')
->formatTimeDiffUntil($host->expire->value);
}
//Get BanManager service.
$banManager = \Drupal::service('ban.ip_manager');
//Is this IP now successfully banned?
if ($banManager
->isBanned($ip)) {
// Advise comment reviewer that this visiting host is now
// blacklisted and banned, for some (configured) amount of time.
$blocked_body .= t('<p><strong>@ip has now been blacklisted and auto-banned from future site visits for @time.</strong></p>', [
'@ip' => $ip,
'@time' => $expires,
]);
}
else {
// Prepare a suggestion link for using httpbl to update and auto-ban
// a previously blacklisted host that was not previously banned, or
// they can just ban it.
$blacklistUrl2 = Url::fromUri('internal:/admin/httpbl/host/' . $hostId . '/edit');
$blacklistUrl2_options = [
'attributes' => [
'class' => [
'httpbl-comment-blocked',
'httpbl-comment-blocked-config',
],
'target' => '_blank',
],
];
$blacklistUrl2
->setOptions($blacklistUrl2_options);
$blacklistLink2 = Link::fromTextAndUrl(t('updating'), $blacklistUrl2)
->toString();
// Advise comment reviewer that this visiting host is already
// blacklisted, but was not previously banned.
$blocked_body .= t('<p><strong>@ip is already blacklisted on this site, but is not yet banned. Consider @banning it or @updating it.</strong></p>', [
'@ip' => $ip,
'@banning' => $banLink,
'@updating' => $blacklistLink2,
]);
}
// Advise commenter they are history!
drupal_set_message(t('Your address (@ip) has been blacklisted for @time.', [
'@ip' => $ip,
'@time' => $expires,
]), 'error', FALSE);
}
// Check for blacklisting storage only (no auto-banning configured).
if ($blacklist_only) {
// Advise comment review that blacklisting commenters alone will not
// prevent future visits from the same nuisance IP, but they can ban it.
$blocked_body .= t('<p><strong>@ip is blacklisted on this site, but neither auto-banning or page-checking are configured to prevent future site visits. Consider @banning it.</strong></p>', [
'@ip' => $ip,
'@banning' => $banLink,
]);
}
// No blacklisting or banning storage options configured.
// Advise comment reviewer of this situation.
if ($no_storage) {
$blocked_body .= t('<p><strong>@ip is blacklisted on this site, but NO http:BL options are configured to prevent future site visits.</strong></p>', [
'@ip' => $ip,
]);
}
// Log this (blacklisted) blocked comment.
$logTrapper
->trapWarning('Blocked comment from blacklisted @ip.', [
'@ip' => $ip,
]);
}
elseif ($evaluated[1] == HTTPBL_LIST_GREY) {
// Advise comment reviewer of this situation.
$blocked_body .= t('<p><strong>@ip is currently grey-listed on this site. If @ip is becoming a repeated nuisance, then consider @blacklisting it. In the meantime, the commenter was offered a challenge for session white-listing, if they pass. </strong></p>', [
'@ip' => $ip,
'@blacklisting' => $blacklistLink,
]);
// Since commenter is only greylisted, offer them a chance (a link)
// to take the whitelist challenge.
$whitelistUrl = Url::fromRoute('httpbl.whitelist_challenge_form');
$whitelistUrl_options = [
'attributes' => [
'class' => [
'httpbl-whitelist-message',
],
'target' => '_blank',
],
];
$whitelistUrl
->setOptions($whitelistUrl_options);
$whitelistLink = Link::fromTextAndUrl(t('challenge'), $whitelistUrl)
->toString();
drupal_set_message(t('You can become white-listed for your current session by passing this @challenge.', [
'@challenge' => $whitelistLink,
]), 'warning', FALSE);
// Log this (greylisted) blocked comment.
$logTrapper
->trapNotice('Blocked comment from grey-listed @ip.', [
'@ip' => $ip,
]);
}
// Add in original comment content, in case it wasn't that bad, even
// though the host IP comes up dirty.
$blocked_body .= t('<p><strong>Original subject: </strong>' . $original_subject . '</p>');
$blocked_body .= t('<p><strong>Original comment below:</strong></p>');
$blocked_body .= $original_body;
// Force filter on this comment to full html to be sure we see the profile
// link with its attributes.
$comment_body = [
'summary' => '',
'value' => $blocked_body,
'format' => 'full_html',
];
// Set the altered comment.
$comment
->set('comment_body', $comment_body);
// Update statistics if configured.
if (\Drupal::state()
->get('httpbl.stats')) {
\Drupal::state()
->set('httpbl.stat_comment', \Drupal::state()
->get('httpbl.stat_comment') + 1);
}
}
}
}