View source
<?php
function fail2ban_permission() {
return array(
'administer fail2ban' => array(
'title' => t('Administer Fail2Ban'),
'description' => t('Configure fail2ban module settings.'),
),
'submit addresses to fail2ban' => array(
'title' => t('Submit Addresses'),
'description' => t('Submit IP addresses to the fail2ban firewall utility.'),
'restrict access' => TRUE,
),
);
}
function fail2ban_menu() {
$items['admin/config/people/fail2ban'] = array(
'title' => 'Fail2ban',
'description' => 'Fail2ban is a system utility that allows you to automatically add firewall entries.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'fail2ban_admin_settings',
),
'access arguments' => array(
'administer fail2ban',
),
'file' => 'fail2ban.admin.inc',
);
return $items;
}
function fail2ban_form_comment_admin_overview_alter(&$form, $form_state) {
if (user_access('submit addresses to fail2ban')) {
module_load_include('inc', 'fail2ban', 'fail2ban.admin');
$form['options']['fail2ban'] = array(
'#type' => 'checkbox',
'#prefix' => '<br />',
'#title' => 'Firewall originating IP address',
);
$form['#submit'][] = 'fail2ban_comment_admin_overview_submit';
}
}
function fail2ban_comment_admin_overview_submit($form, &$form_state) {
if ($form_state['values']['fail2ban'] == 1) {
if (strpos($form_state['values']['operation'], '-' > 0)) {
list($id, $operation) = explode('-', $form_state['values']['operation']);
}
else {
$operation = $form_state['values']['operation'];
}
foreach ($form_state['values']['comments'] as $cid => $value) {
if ($value) {
if ($comment = comment_load($cid)) {
if ($operation == 'unpublish' || $operation == 'delete') {
fail2ban_syslog($comment->hostname);
}
}
}
}
}
}
function fail2ban_syslog($address) {
if (empty($address) || !is_string($address)) {
return;
}
if (fail2ban_whitelist($address)) {
drupal_set_message(t('The address !address is !whitelisted and will not be submitted to the firewall', array(
'!address' => $address,
'!whitelisted' => l('whitelisted', 'admin/settings/fail2ban'),
)));
return;
}
$settings = variable_get('fail2ban', fail2ban_defaults());
$options = 0;
foreach ($settings['logopt']['options'] as $option) {
$options = $options | $option;
}
$priority = 0;
foreach ($settings['logopt']['priority'] as $option) {
$priority = $priority | $option;
}
$message = strtr($settings['logstring'], array(
'!address' => $address,
));
if (openlog($settings['identifier'], $options, $settings['logopt']['facility']) == FALSE) {
watchdog('fail2ban', 'Unable to connect to the syslog daemon', NULL, WATCHDOG_ERROR);
drupal_set_message(t('Unable to connect to the syslog daemon'), 'error');
return;
}
if (syslog($priority, $message) == FALSE) {
watchdog('fail2ban', 'Cannot write message to the syslog daemon', NULL, WATCHDOG_ERROR);
drupal_set_message(t('Cannot write message to the syslog daemon'), 'error');
}
else {
drupal_set_message(t('The address !address has been submitted to the firewall', array(
'!address' => $address,
)));
}
if (closelog() == FALSE) {
watchdog('fail2ban', 'Cannot close connection to the syslog daemon', NULL, WATCHDOG_ERROR);
}
}
function fail2ban_whitelist($address) {
$client_ip = ip2long($address);
if ($client_ip === FALSE) {
return TRUE;
}
$settings = variable_get('fail2ban', fail2ban_defaults());
$list = preg_split("/[\\s,]+/", $settings['whitelist'] . "\n" . ip_address());
foreach ($list as $entry) {
$network = preg_split("/\\//", trim($entry));
if (count($network) == 1 || empty($network[1])) {
if ($address == $network[0]) {
return TRUE;
}
}
else {
if (fail2ban_ip_in_network($address, $network[0], $network[1]) == TRUE) {
return TRUE;
}
}
}
return FALSE;
}
function fail2ban_ip_in_network($ip, $net_addr, $net_mask) {
if ($net_mask <= 0) {
return FALSE;
}
$ip_binary_string = sprintf("%032b", ip2long($ip));
$net_binary_string = sprintf("%032b", ip2long($net_addr));
return substr_compare($ip_binary_string, $net_binary_string, 0, $net_mask) === 0;
}
function fail2ban_defaults() {
return array(
'logstring' => 'Submitting address [!address] to the firewall',
'whitelist' => "127.0.0.0/8\n" . ip_address(),
'logopt' => array(
'identifier' => 'drupal',
'options' => array(
LOG_ODELAY,
),
'facility' => LOG_USER,
'priority' => array(
LOG_NOTICE,
),
),
);
}