You are here

fail2ban.module in Fail2ban Firewall Integration 6

Same filename and directory in other branches
  1. 7.2 fail2ban.module
  2. 7 fail2ban.module

File

fail2ban.module
View source
<?php

/**
 * Implementation of hook_perm()
 */
function fail2ban_perm() {
  return array(
    'administer fail2ban',
    'submit addresses to fail2ban',
  );
}

/**
 * Implementation of hook_menu()
 */
function fail2ban_menu() {
  $items['admin/settings/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',
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'fail2ban.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_form_FORMID_alter().
 *
 * @see fail2ban_comment_admin_overview_submit()
 */
function fail2ban_form_comment_admin_overview_alter(&$form, $form_state) {
  if (user_access('submit addresses to fail2ban')) {
    module_load_include('inc', 'fail2ban', 'fail2ban.admin');

    // Add copies of the existing options, with the firewall options appended.
    $form['options']['fail2ban'] = array(
      '#type' => 'checkbox',
      '#prefix' => '<br />',
      '#title' => 'Firewall originating IP address',
    );
    $form['#submit'][] = 'fail2ban_comment_admin_overview_submit';
  }
}

/**
 * Form submit handler to mass-report and unpublish or delete comments.
 */
function fail2ban_comment_admin_overview_submit($form, &$form_state) {
  if ($form_state['values']['fail2ban'] == 1) {

    // The mollom module prefixes the operation name with its own guff.
    // Cope with it.
    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);
          }
        }
      }
    }
  }
}

/**
 * The function that does the actual work, writing a log message.
 *
 * @param $address
 *   String - An IP address or net/mask.
 */
function fail2ban_syslog($address) {
  if (empty($address) || !is_string($address)) {
    return;
  }

  // Check if the address is in the whitelist. If so, just 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;
  }

  // Get the log identifier
  //
  $identifier = variable_get('fail2ban_identifier', 'drupal');

  // Turn on all the right log options.
  //
  $options = 0;
  foreach (variable_get('fail2ban_options', array(
    LOG_ODELAY,
  )) as $option) {
    $options = $options | $option;
  }

  // Get the facility.
  //
  $facility = variable_get('fail2ban_facility', LOG_USER);

  // Get the priority.
  //
  $priority = 0;
  foreach (variable_get('fail2ban_priority', array(
    LOG_NOTICE,
  )) as $option) {
    $priority = $priority | $option;
  }

  // Get the log string.
  //
  $message = strtr(variable_get('fail2ban_logstring', 'Submitting address [!address] to the firewall'), array(
    '!address' => $address,
  ));

  // Open the log stream.
  //
  if (openlog($identifier, $options, $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);
  }
}

/**
 * Check if a given address is whitelisted.
 *
 * Shamelessly copied from http://php.net/manual/en/function.ip2long.php
 */
function fail2ban_whitelist($address) {
  $client_ip = ip2long($address);

  // Return true if this is not a valid IP.
  //
  if ($client_ip === FALSE) {
    return TRUE;
  }

  // Load and split the list.
  //
  $whitelist = variable_get('fail2ban_whitelist', "127.0.0.0/8\n" . ip_address());
  $list = split("\n", $whitelist);

  // Iterate.
  //
  foreach ($list as $entry) {
    $network = split('/', trim($entry));

    // Check if we're dealing with a single address.
    //
    if (!$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;
}

/**
 * Check if a given address exists on a network.
 *
 * Shamelessly copied from http://php.net/manual/en/function.ip2long.php
 */
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;
}

Functions

Namesort descending Description
fail2ban_comment_admin_overview_submit Form submit handler to mass-report and unpublish or delete comments.
fail2ban_form_comment_admin_overview_alter Implements hook_form_FORMID_alter().
fail2ban_ip_in_network Check if a given address exists on a network.
fail2ban_menu Implementation of hook_menu()
fail2ban_perm Implementation of hook_perm()
fail2ban_syslog The function that does the actual work, writing a log message.
fail2ban_whitelist Check if a given address is whitelisted.