summaryrefslogtreecommitdiff
path: root/modules/system
diff options
context:
space:
mode:
Diffstat (limited to 'modules/system')
-rw-r--r--modules/system/system.admin.inc88
-rw-r--r--modules/system/system.install87
-rw-r--r--modules/system/system.module50
3 files changed, 225 insertions, 0 deletions
diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc
index 76c52c656..318c7f6fa 100644
--- a/modules/system/system.admin.inc
+++ b/modules/system/system.admin.inc
@@ -1106,6 +1106,94 @@ function system_modules_uninstall_submit($form, &$form_state) {
}
/**
+ * Menu callback. Display blocked IP addresses.
+ */
+function system_ip_blocking() {
+ $output = '';
+ $rows = array();
+ $header = array(t('IP address'), t('Operations'));
+ $result = db_query('SELECT * FROM {blocked_ips}');
+ while ($ip = db_fetch_object($result)) {
+ $rows[] = array(
+ $ip->ip,
+ l(t('delete'), "admin/settings/ip-blocking/delete/$ip->iid"),
+ );
+ }
+
+ $output .= theme('table', $header, $rows);
+
+ $output .= drupal_get_form('system_ip_blocking_form');
+
+ return $output;
+}
+
+/**
+ * Define the form for blocking IP addresses.
+ *
+ * @ingroup forms
+ * @see system_ip_blocking_form_validate()
+ * @see system_ip_blocking_form_submit()
+ */
+function system_ip_blocking_form($form_state) {
+ $form['ip'] = array(
+ '#title' => t('IP address'),
+ '#type' => 'textfield',
+ '#size' => 64,
+ '#maxlength' => 32,
+ '#description' => t('Enter a valid IP address.'),
+ );
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save'),
+ );
+ $form['#submit'][] = 'system_ip_blocking_form_submit';
+ $form['#validate'][] = 'system_ip_blocking_form_validate';
+ return $form;
+}
+
+function system_ip_blocking_form_validate($form, &$form_state) {
+ $ip = $form_state['values']['ip'];
+ if (db_result(db_query("SELECT * FROM {blocked_ips} WHERE ip = '%s'", $ip))) {
+ form_set_error('ip', t('This IP address is already blocked.'));
+ }
+ else if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) == FALSE) {
+ form_set_error('ip', t('Please enter a valid IP address.'));
+ }
+}
+
+function system_ip_blocking_form_submit($form, &$form_state) {
+ $ip = $form_state['values']['ip'];
+ db_query("INSERT INTO {blocked_ips} (ip) VALUES ('%s')", $ip);
+ drupal_set_message(t('The IP address %ip has been blocked.', array('%ip' => $ip)));
+ $form_state['redirect'] = 'admin/settings/ip-blocking';
+ return;
+}
+
+/**
+ * IP deletion confirm page.
+ *
+ * @see system_ip_blocking_delete_submit()
+ */
+function system_ip_blocking_delete(&$form_state, $iid) {
+ $form['blocked_ip'] = array(
+ '#type' => 'value',
+ '#value' => $iid,
+ );
+ return confirm_form($form, t('Are you sure you want to delete %ip?', array('%ip' => $iid['ip'])), 'admin/settings/ip-blocking', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
+}
+
+/**
+ * Process system_ip_blocking_delete form submissions.
+ */
+function system_ip_blocking_delete_submit($form, &$form_state) {
+ $blocked_ip = $form_state['values']['blocked_ip'];
+ db_query("DELETE FROM {blocked_ips} WHERE iid = %d", $blocked_ip['iid']);
+ watchdog('user', 'Deleted %ip', array('%ip' => $blocked_ip['ip']));
+ drupal_set_message(t('The IP address %ip was deleted.', array('%ip' => $blocked_ip['ip'])));
+ $form_state['redirect'] = 'admin/settings/ip-blocking';
+}
+
+/**
* Form builder; The general site information form.
*
* @ingroup forms
diff --git a/modules/system/system.install b/modules/system/system.install
index fc78a4db2..6d627c8bd 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -527,6 +527,29 @@ function system_schema() {
),
);
+ $schema['blocked_ips'] = array(
+ 'description' => t('Stores blocked IP addresses.'),
+ 'fields' => array(
+ 'iid' => array(
+ 'description' => t('Primary Key: unique ID for IP addresses.'),
+ 'type' => 'serial',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ ),
+ 'ip' => array(
+ 'description' => t('IP address'),
+ 'type' => 'varchar',
+ 'length' => 32,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ ),
+ 'indexes' => array(
+ 'blocked_ip' => array('ip'),
+ ),
+ 'primary key' => array('iid'),
+ );
+
$schema['cache'] = array(
'description' => t('Generic cache table for caching things not separated out into their own tables. Contributed modules may also use this to store cached items.'),
'fields' => array(
@@ -2668,6 +2691,70 @@ function system_update_7001() {
return $ret;
}
+/**
+ * Add a table to store blocked IP addresses.
+ */
+function system_update_7002() {
+ $ret = array();
+ $schema['blocked_ips'] = array(
+ 'description' => t('Stores blocked IP addresses.'),
+ 'fields' => array(
+ 'iid' => array(
+ 'description' => t('Primary Key: unique ID for IP addresses.'),
+ 'type' => 'serial',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ ),
+ 'ip' => array(
+ 'description' => t('IP address'),
+ 'type' => 'varchar',
+ 'length' => 32,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ ),
+ 'indexes' => array(
+ 'blocked_ip' => array('ip'),
+ ),
+ 'primary key' => array('iid'),
+ );
+
+ db_create_table($ret, 'blocked_ips', $schema['blocked_ips']);
+
+ return $ret;
+}
+
+/**
+ * Update {blocked_ips} with valid IP addresses from {access}.
+ */
+function system_update_7003() {
+ $ret = array();
+ $type = 'host';
+ $result = db_query("SELECT mask FROM {access} WHERE status = %d AND TYPE = '%s'", 0, $type);
+ while ($blocked = db_fetch_object($result)) {
+ if (filter_var($blocked->mask, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) !== FALSE) {
+ $ret[] = update_sql("INSERT INTO {blocked_ips} (ip) VALUES ('$blocked->mask')");
+ }
+ else {
+ $invalid_host = check_plain($blocked->mask);
+ $ret[] = array('success' => TRUE, 'query' => 'The host '. $invalid_host .' is no longer blocked because it is not a valid IP address.');
+ }
+ }
+ if (isset($invalid_host)) {
+ drupal_set_message('Drupal no longer supports wildcard IP address blocking. Visitors whose IP addresses match ranges you have previously set using <em>access rules</em> will no longer be blocked from your site when you take it out of maintenance mode. See the <a href="http://drupal.org/node/24302">IP address and referrer blocking Handbook page</a> for alternative methods.', 'warning');
+ $ret[] = array('success' => TRUE, 'query' => '');
+ }
+ // Make sure not to block any IP addresses that were specifically allowed by access rules.
+ if (!empty($result)) {
+ $result = db_query("SELECT mask FROM {access} WHERE status = %d AND type = '%s'", 1, $type);
+ while ($allowed = db_fetch_object($result)) {
+ $ret[] = update_sql("DELETE FROM {blocked_ips} WHERE LOWER(ip) LIKE LOWER('$allowed->mask')");
+ }
+ }
+
+ return $ret;
+}
+
/**
* @} End of "defgroup updates-6.x-to-7.x"
diff --git a/modules/system/system.module b/modules/system/system.module
index 82d74a449..bc41ce018 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -99,6 +99,8 @@ function system_help($path, $arg) {
return $output;
case 'admin/settings/actions/configure':
return t('An advanced action offers additional configuration options which may be filled out below. Changing the <em>Description</em> field is recommended, in order to better identify the precise action taking place. This description will be displayed in modules such as the trigger module when assigning actions to system events, so it is best if it is as descriptive as possible (for example, "Send e-mail to Moderation Team" rather than simply "Send e-mail").');
+ case 'admin/settings/ip-blocking':
+ return '<p>'. t('IP addresses listed here are blocked from your site before any modules are loaded. You may add IP addresses to the list, or delete existing entries.') .'</p>';
case 'admin/reports/status':
return '<p>'. t("Here you can find a short overview of your site's parameters as well as any problems detected with your installation. It may be useful to copy and paste this information into support requests filed on drupal.org's support forums and project issue queues.") .'</p>';
}
@@ -163,6 +165,7 @@ function system_perm() {
'access site reports' => t('View reports from system logs and other status information.'),
'select different theme' => t('Select a theme other than the default theme set by the site administrator.'),
'administer files' => t('Manage user-uploaded files.'),
+ 'block IP addresses' => t('Block IP addresses from accessing your site.'),
);
}
@@ -486,6 +489,23 @@ function system_menu() {
'type' => MENU_CALLBACK,
);
+ // IP address blocking.
+ $items['admin/settings/ip-blocking'] = array(
+ 'title' => 'IP address blocking',
+ 'description' => 'Manage blocked IP addresses.',
+ 'page callback' => 'system_ip_blocking',
+ 'access arguments' => array('block IP addresses'),
+ 'file' => 'system.admin.inc',
+ );
+ $items['admin/settings/ip-blocking/delete/%blocked_ip'] = array(
+ 'title' => 'Delete IP address',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_ip_blocking_delete', 4),
+ 'access arguments' => array('block IP addresses'),
+ 'type' => MENU_CALLBACK,
+ 'file' => 'system.admin.inc',
+ );
+
// Settings:
$items['admin/settings/site-information'] = array(
'title' => 'Site information',
@@ -636,6 +656,20 @@ function system_menu() {
}
/**
+ * Retrieve a blocked IP address from the database.
+ *
+ * @param $iid integer
+ * The ID of the blocked IP address to retrieve.
+ *
+ * @return
+ * The blocked IP address from the database as an array.
+ */
+function blocked_ip_load($iid) {
+ $blocked_ip = db_fetch_array(db_query("SELECT * FROM {blocked_ips} WHERE iid = %d", $iid));
+ return $blocked_ip;
+}
+
+/**
* Menu item access callback - only admin or enabled themes can be accessed.
*/
function _system_themes_access($theme) {
@@ -1408,6 +1442,12 @@ function system_action_info() {
'taxonomy' => array('insert', 'update', 'delete'),
)
),
+ 'system_block_ip_action' => array(
+ 'description' => t('Ban IP address of current user'),
+ 'type' => 'user',
+ 'configurable' => FALSE,
+ 'hooks' => array(),
+ ),
'system_goto_action' => array(
'description' => t('Redirect to URL'),
'type' => 'system',
@@ -1964,6 +2004,16 @@ function system_goto_action($object, $context) {
}
/**
+ * Implementation of a Drupal action.
+ * Blocks the user's IP address.
+ */
+function system_block_ip_action() {
+ $ip = ip_address();
+ db_query("INSERT INTO {blocked_ips} (ip) VALUES ('%s')", $ip);;
+ watchdog('action', 'Banned IP address %ip', array('%ip' => $ip));
+}
+
+/**
* Generate an array of time zones and their local time&date.
*/
function _system_zonelist() {