You are here

path2ban.module in path2ban 7

Same filename and directory in other branches
  1. 7.2 path2ban.module

path2ban module.

File

path2ban.module
View source
<?php

/**
 * @file
 * path2ban module.
 *
 *
 */

/**
 * Implements hook_permission().
 */
function path2ban_permission() {
  $permissions = array();
  $permissions['administer path2ban'] = array(
    'title' => t('Administer path2ban'),
    'description' => t('Administer path2ban configuration settings.'),
  );
  $permissions['bypass path2ban'] = array(
    'title' => t('Bypass path2ban'),
    'description' => t('path2ban will not block this role.'),
  );
  return $permissions;
}

/**
 * Display path2ban settings form.
 */
function path2ban_settings() {

  //TODO: hard and soft IP block
  $form = array();
  $form['path2ban_options'] = array(
    '#type' => 'fieldset',
    '#title' => t('path2ban options'),
  );
  $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array(
    '%blog' => 'blog',
    '%blog-wildcard' => 'blog/*',
    '%front' => '<front>',
  ));
  $form['path2ban_options']['path2ban_list'] = array(
    '#type' => 'textarea',
    '#title' => t('List of restricted paths'),
    '#description' => $description,
    '#default_value' => variable_get('path2ban_list', ''),
    '#rows' => 25,
  );
  $form['path2ban_options']['path2ban_threshold_limit'] = array(
    '#type' => 'textfield',
    '#title' => t('Threshold limit'),
    //'#description' => t('Please enter the ...'),
    '#default_value' => variable_get('path2ban_threshold_limit', 5),
  );
  $form['path2ban_options']['path2ban_threshold_window'] = array(
    '#type' => 'textfield',
    '#title' => t('Threshold window'),
    '#description' => t('Please enter the threshold window in seconds'),
    '#default_value' => variable_get('path2ban_threshold_window', 3600),
  );
  $form['path2ban_options']['path2ban_notify'] = array(
    '#type' => 'checkbox',
    '#title' => t('Notify User One?'),
    '#default_value' => variable_get('path2ban_notify', 0),
    '#description' => t('Notify User One by email about blocked IP addresses'),
  );

  /*  $form['path2ban_options']['path2ban_test_mode'] = array(
      '#type' => 'checkbox',
      '#title' => t('Test mode'),
      '#default_value' => variable_get('path2ban_test_mode', 0),
      '#description' => t('Do not block any IP addresses'),
    );*/
  return system_settings_form($form);
}

/**
 * Implements hook_menu().
 */
function path2ban_menu() {
  $menu = array();
  $menu['path2ban/%'] = array(
    'page callback' => 'path2ban_pitfall',
    'page arguments' => array(
      1,
    ),
    'access callback' => TRUE,
    //'access arguments' => array('access content'), // TRUE - проверить
    'type' => MENU_CALLBACK,
  );
  $menu['admin/config/people/path2ban'] = array(
    'title' => 'path2ban',
    'description' => 'Ban IP of visitors, who try to scan restricted paths.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'path2ban_settings',
    ),
    'access arguments' => array(
      'administer path2ban',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  return $menu;
}

/*
 * This function compare real path and restricted.
 */
function path2ban_pitfall($state = 404) {
  $pages = drupal_strtolower(variable_get('path2ban_list', ''));

  // Convert the Drupal path to lowercase.
  $destination = drupal_strtolower($_GET['destination']);

  // Compare the lowercase paths.
  $page_match = drupal_match_path($destination, $pages);
  if ($page_match) {
    path2ban_action();
  }

  // Return menu code
  $result = $state == 403 ? MENU_ACCESS_DENIED : MENU_NOT_FOUND;
  return $result;
}

/*
 * This function register attacks, send notification emails to User One and ban IP adresses of web scanners.
 */
function path2ban_action() {
  $bypass = user_access('bypass path2ban');
  $window = intval(variable_get('path2ban_threshold_window', 3600));
  $limit = intval(variable_get('path2ban_threshold_limit', 5));
  $limit = $limit < 1 ? 1 : $limit;

  //$testmode = variable_get('path2ban_test_mode', 0);
  $ip = ip_address();
  flood_register_event('path2ban', $window);

  // by default: $window=3600, $identifier=ip
  if ($bypass) {
    drupal_set_message(t('Your IP address has been logged.'), 'warning');
  }
  if (!flood_is_allowed('path2ban', $limit, $window)) {

    // by default: $window=3600
    if (!$bypass) {
      db_insert('blocked_ips')
        ->fields(array(
        'ip' => $ip,
      ))
        ->execute();
      watchdog('path2ban', 'Banned IP address %ip', array(
        '%ip' => $ip,
      ));
      drupal_set_message(t('Sorry, your IP has been banned.'), 'error');

      // Notify user one.
      if (variable_get('path2ban_notify', 0)) {
        $user1 = user_load(1);
        $testmode = $bypass ? t('(User has bypass permission. IP address has not been blocked!)') : '';
        $url = url('admin/config/people/ip-blocking', array(
          'absolute' => TRUE,
        ));
        $params['subject'] = variable_get('site_name') . t(': Blocked IP due to web-scanner attack');
        $params['body'][] = t("Hi User One,\n        There were suspected web-scanner activities.\n        Associated IP (@ip) has been blocked.\n        You can review the list of blocked IPs at @url\n        Thank you.\n        Sent by path2ban module.\n        @testmode\n        ", array(
          '@ip' => $ip,
          '@url' => $url,
          '@testmode' => $testmode,
        ));

        //drupal_mail('path2ban', 'blocked-ip', $user1->mail, language_default(), $params);
        drupal_mail('path2ban', 'blocked-ip', $user1->mail, user_preferred_language($user1), $params);
      }
    }
    else {
      watchdog('path2ban', 'Would have banned IP address %ip but they have the \'bypass path2ban\' role.', array(
        '%ip' => $ip,
      ));
    }
  }
  global $user;
  if ($user->uid == 1) {
    drupal_set_message(t('Hi User One! Use another account and another IP for testing path2ban module. Your IP not banned.'));
  }
}

/*
 * Implements hook_mail().
 */
function path2ban_mail($key, &$message, $params) {
  $message['subject'] = $params['subject'];
  $message['body'] = $params['body'];
}

Functions

Namesort descending Description
path2ban_action
path2ban_mail
path2ban_menu Implements hook_menu().
path2ban_permission Implements hook_permission().
path2ban_pitfall
path2ban_settings Display path2ban settings form.