Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.220
diff -u -p -r1.220 bootstrap.inc
--- includes/bootstrap.inc	21 Aug 2008 19:36:36 -0000	1.220
+++ includes/bootstrap.inc	27 Aug 2008 15:21:27 -0000
@@ -921,7 +921,7 @@ function drupal_get_messages($type = NUL
  * @return bool
  *   TRUE if access is denied, FALSE if access is allowed.
  */
-function drupal_is_denied($ip) {
+function drupal_denied_ip($ip) {
   // Because this function is called on every page request, we first check
   // for an array of IP addresses in settings.php before querying the
   // database.
@@ -934,6 +934,19 @@ function drupal_is_denied($ip) {
     return (bool) db_result(db_query($sql, $ip));
   }
 }
+function drupal_denied_referrer($referrer) {
+  // Because this function is called on every page request, we first check
+  // for an array of IP addresses in settings.php before querying the
+  // database.
+  $blocked_referrers = variable_get('blocked_referrers', NULL);
+  if (isset($blocked_referrers) && is_array($blocked_referrers)) {
+    return in_array($referrer, $blocked_referrers);
+  }
+  else {
+    $sql = "SELECT 1 FROM {blocked_referrers} WHERE referrer = '%s'";
+    return (bool) db_result(db_query($sql, $referrer));
+  }
+}
 
 /**
  * Generates a default anonymous $user object.
@@ -1032,12 +1045,18 @@ function _drupal_bootstrap($phase) {
       break;
 
     case DRUPAL_BOOTSTRAP_ACCESS:
-      // Deny access to blocked IP addresses - t() is not yet available.
-      if (drupal_is_denied(ip_address())) {
+      // Deny access to blocked IP addresses and referrers - t() is not yet available.
+      if (drupal_denied_ip(ip_address())) {
         header('HTTP/1.1 403 Forbidden');
         print 'Sorry, ' . check_plain(ip_address()) . ' has been banned.';
         exit();
       }
+      elseif (drupal_denied_referrer(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST))) {
+        header('HTTP/1.0 403 Forbidden');
+        print "Sorry, your referer has been banned.";
+        exit();
+      }
+
       break;
 
     case DRUPAL_BOOTSTRAP_SESSION:
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.85
diff -u -p -r1.85 system.admin.inc
--- modules/system/system.admin.inc	21 Aug 2008 19:36:38 -0000	1.85
+++ modules/system/system.admin.inc	27 Aug 2008 15:21:28 -0000
@@ -1197,6 +1197,95 @@ function system_ip_blocking_delete_submi
 }
 
 /**
+ * Menu callback. Display blocked referrers.
+ */
+function system_referrer_blocking() {
+  $output = '';
+  $rows = array();
+  $header = array(t('Referrer'), t('Operations'));
+  $result = db_query('SELECT * FROM {blocked_referrers}');
+  while ($referrer = db_fetch_object($result)) {
+    $rows[] = array(
+      $referrer->referrer,
+      l(t('delete'), "admin/settings/referrer-blocking/delete/$referrer->rid"),
+    );
+  }
+
+  $output .= drupal_get_form('system_referrer_blocking_form');
+
+  $output .= theme('table', $header, $rows);
+
+  return $output;
+}
+
+/**
+ * Define the form for blocking referrers.
+ *
+ * @ingroup forms
+ * @see system_referrer_blocking_form_validate()
+ * @see system_referrer_blocking_form_submit()
+ */
+function system_referrer_blocking_form($form_state) {
+  $form['referrer'] = array(
+    '#title' => t('Referrer'),
+    '#type' => 'textfield',
+    '#size' => 64,
+    '#maxlength' => 255,
+    '#default_value' => arg(3),
+    '#description' => t('Enter a valid Referrer.'),
+  );
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+  );
+  $form['#submit'][] = 'system_referrer_blocking_form_submit';
+  $form['#validate'][] = 'system_referrer_blocking_form_validate';
+  return $form;
+}
+
+function system_referrer_blocking_form_validate($form, &$form_state) {
+  $referrer = trim($form_state['values']['referrer']);
+  if (db_result(db_query("SELECT * FROM {blocked_referrers} WHERE referrer = '%s'", $referrer))) {
+    form_set_error('referrer', t('This referrer is already blocked.'));
+  }
+  else if ($referrer == $_SERVER['HTTP_HOST']) {
+    form_set_error('referrer', t('You may not block your own host.'));
+  }
+}
+
+function system_referrer_blocking_form_submit($form, &$form_state) {
+  $referrer = trim($form_state['values']['referrer']);
+  db_query("INSERT INTO {blocked_referrers} (referrer) VALUES ('%s')", $referrer);
+  drupal_set_message(t('The referrer %referrer has been blocked.', array('%referrer' => $referrer)));
+  $form_state['redirect'] = 'admin/settings/referrer-blocking';
+  return;
+}
+
+/**
+ * Referrer deletion confirm page.
+ *
+ * @see system_referrer_blocking_delete_submit()
+ */
+function system_referrer_blocking_delete(&$form_state, $iid) {
+  $form['blocked_referrer'] = array(
+    '#type' => 'value',
+    '#value' => $iid,
+  );
+  return confirm_form($form, t('Are you sure you want to delete %referrer?', array('%referrer' => $iid['referrer'])), 'admin/settings/referrer-blocking', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
+}
+
+/**
+ * Process system_referrer_blocking_delete form submissions.
+ */
+function system_referrer_blocking_delete_submit($form, &$form_state) {
+  $blocked_referrer = $form_state['values']['blocked_referrer'];
+  db_query("DELETE FROM {blocked_referrers} WHERE iid = %d", $blocked_referrer['iid']);
+  watchdog('user', 'Deleted %referrer', array('%referrer' => $blocked_referrer['referrer']));
+  drupal_set_message(t('The referrer address %referrer was deleted.', array('%referrer' => $blocked_ip['referrer'])));
+  $form_state['redirect'] = 'admin/settings/referrer-blocking';
+}
+
+/**
  * Form builder; The general site information form.
  *
  * @ingroup forms
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.261
diff -u -p -r1.261 system.install
--- modules/system/system.install	23 Aug 2008 08:15:37 -0000	1.261
+++ modules/system/system.install	27 Aug 2008 15:21:28 -0000
@@ -568,6 +568,29 @@ function system_schema() {
     ),
     'primary key' => array('iid'),
   );
+  
+  $schema['blocked_referrers'] = array(
+    'description' => t('Stores blocked referrers.'),
+    'fields' => array(
+       'rid' => array(
+        'description' => t('Primary Key: unique ID for referrers.'),
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'referrer' => array(
+        'description' => t('Referrer'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+    ),
+    'indexes' => array(
+      'blocked_referrer' => array('referrer'),
+    ),
+    'primary key' => array('rid'),
+  );  
 
   $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.'),
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.613
diff -u -p -r1.613 system.module
--- modules/system/system.module	21 Aug 2008 19:36:38 -0000	1.613
+++ modules/system/system.module	27 Aug 2008 15:21:28 -0000
@@ -172,6 +172,7 @@ function system_perm() {
     '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.'),
+    'block referrers' => t('Block referrers from sending traffic to your site.'),
   );
 }
 
@@ -519,6 +520,28 @@ function system_menu() {
     'access arguments' => array('block IP addresses'),
     'type' => MENU_CALLBACK,
   );
+  
+  // Referrer blocking.
+  $items['admin/settings/referrer-blocking'] = array(
+    'title' => 'Referrer blocking',
+    'description' => 'Manage blocked referrers.',
+    'page callback' => 'system_referrer_blocking',
+    'access arguments' => array('block referrers'),
+  );
+  $items['admin/settings/referrer-blocking/%'] = array(
+    'title' => 'Referrer blocking',
+    'description' => 'Manage blocked referrers.',
+    'page callback' => 'system_referrer_blocking',
+    'access arguments' => array('block referrers'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/settings/referrer-blocking/delete/%blocked_referrer'] = array(
+    'title' => 'Delete referrer',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('system_referrer_blocking_delete', 4),
+    'access arguments' => array('block referrers'),
+    'type' => MENU_CALLBACK,
+  );  
 
   // Settings:
   $items['admin/settings/site-information'] = array(
