? sites/default/files
? sites/default/settings.php
Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.206
diff -u -r1.206 bootstrap.inc
--- includes/bootstrap.inc	10 Jan 2008 22:47:17 -0000	1.206
+++ includes/bootstrap.inc	3 Mar 2008 16:26:46 -0000
@@ -953,12 +953,17 @@
       break;
 
     case DRUPAL_BOOTSTRAP_ACCESS:
-      // Deny access to hosts which were banned - t() is not yet available.
+      // Deny access to hosts and referrers which were banned - t() is not yet available.
       if (drupal_is_denied('host', ip_address())) {
         header('HTTP/1.1 403 Forbidden');
         print 'Sorry, '. check_plain(ip_address()) .' has been banned.';
         exit();
       }
+      elseif (drupal_is_denied('referrer', $_SERVER['HTTP_REFERER'])) {
+        header('HTTP/1.0 403 Forbidden');
+        print "Sorry, your referer has been banned.";
+        exit();
+      }
       break;
 
     case DRUPAL_BOOTSTRAP_SESSION:
Index: modules/statistics/statistics.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.admin.inc,v
retrieving revision 1.6
diff -u -r1.6 statistics.admin.inc
--- modules/statistics/statistics.admin.inc	8 Jan 2008 10:35:42 -0000	1.6
+++ modules/statistics/statistics.admin.inc	3 Mar 2008 16:36:40 -0000
@@ -107,6 +107,13 @@
  * Menu callback; presents the "referrer" page.
  */
 function statistics_top_referrers() {
+  // Remove trailing port designations from $_SERVER['HTTP_HOST'].
+  $http_host = $_SERVER['HTTP_HOST'];
+  $colon_position = strrpos($http_host, ':');
+  if ($colon_position !== FALSE) {
+    $http_host = substr($http_host, 0, $colon_position-1);
+  }
+  
   $query = "SELECT url, COUNT(url) AS hits, MAX(timestamp) AS last FROM {accesslog} WHERE url NOT LIKE '%%%s%%' AND url <> '' GROUP BY url";
   $query_cnt = "SELECT COUNT(DISTINCT(url)) FROM {accesslog} WHERE url <> '' AND url NOT LIKE '%%%s%%'";
   drupal_set_title(t('Top referrers in the past %interval', array('%interval' => format_interval(variable_get('statistics_flush_accesslog_timer', 259200)))));
@@ -115,14 +122,16 @@
     array('data' => t('Hits'), 'field' => 'hits', 'sort' => 'desc'),
     array('data' => t('Url'), 'field' => 'url'),
     array('data' => t('Last visit'), 'field' => 'last'),
+    array('data' => t('Ban referrer')),
   );
 
   $query .= tablesort_sql($header);
-  $result = pager_query($query, 30, 0, $query_cnt, $_SERVER['HTTP_HOST']);
+  $result = pager_query($query, 30, 0, $query_cnt, $http_host);
 
   $rows = array();
   while ($referrer = db_fetch_object($result)) {
-    $rows[] = array($referrer->hits, _statistics_link($referrer->url), t('@time ago', array('@time' => format_interval(time() - $referrer->last))));
+    $referrer_parsed = parse_url($referrer->url);
+    $rows[] = array($referrer->hits, _statistics_link($referrer->url), t('@time ago', array('@time' => format_interval(time() - $referrer->last))), l(t("Ban Referrer"), "admin/access/rules/add/%25". $referrer_parsed['host'] ."%25/referrer"));
   }
 
   if (empty($rows)) {
Index: modules/user/user.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.admin.inc,v
retrieving revision 1.19
diff -u -r1.19 user.admin.inc
--- modules/user/user.admin.inc	20 Feb 2008 13:46:43 -0000	1.19
+++ modules/user/user.admin.inc	3 Mar 2008 16:52:24 -0000
@@ -718,6 +718,7 @@
   $output = drupal_get_form('user_admin_check_user');
   $output .= drupal_get_form('user_admin_check_mail');
   $output .= drupal_get_form('user_admin_check_host');
+  $output .= drupal_get_form('user_admin_check_referrer');
   return $output;
 }
 
@@ -775,7 +776,7 @@
     '#default_value' => isset($edit['status']) ? $edit['status'] : 0,
     '#options' => array('1' => t('Allow'), '0' => t('Deny')),
   );
-  $type_options = array('user' => t('Username'), 'mail' => t('E-mail'), 'host' => t('Host'));
+  $type_options = array('user' => t('Username'), 'mail' => t('E-mail'), 'host' => t('Host'), 'referrer' => t('Referrer'));
   $form['type'] = array(
     '#type' => 'radios',
     '#title' => t('Rule type'),
@@ -835,6 +836,17 @@
   return $form;
 }
 
+function user_admin_check_referrer() {
+  $form['referrer'] = array('#type' => 'fieldset', '#title' => t('Referrer'));
+  $form['referrer']['test'] = array('#type' => 'textfield', '#title' => '', '#description' => t('Enter a referrer to check if it will be denied or allowed.'), '#size' => 30, '#maxlength' => 64);
+  $form['referrer']['type'] = array('#type' => 'hidden', '#value' => 'referrer');
+  $form['referrer']['submit'] = array('#type' => 'submit', '#value' => t('Check referrer'));
+  $form['#submit'][] = 'user_admin_access_check_submit';
+  $form['#validate'][] = 'user_admin_access_check_validate';
+  $form['#theme'] = 'user_admin_access_check';
+  return $form;
+}
+
 function user_admin_access_check_submit($form, &$form_state) {
   switch ($form_state['values']['type']) {
     case 'user':
@@ -861,6 +873,14 @@
         drupal_set_message(t('The hostname %host is allowed.', array('%host' => $form_state['values']['test'])));
       }
       break;
+    case 'referrer':
+      if (drupal_is_denied('referrer', $form_state['values']['test'])) {
+        drupal_set_message(t('The referrer %referrer is not allowed.', array('%referrer' => $form_state['values']['test'])));
+      }
+      else {
+        drupal_set_message(t('The hostname %referrer is allowed.', array('%referrer' => $form_state['values']['test'])));
+      }
+      break;
     default:
       break;
   }
@@ -900,7 +920,7 @@
 function user_admin_access() {
   $header = array(array('data' => t('Access type'), 'field' => 'status'), array('data' => t('Rule type'), 'field' => 'type'), array('data' => t('Mask'), 'field' => 'mask'), array('data' => t('Operations'), 'colspan' => 2));
   $result = db_query("SELECT aid, type, status, mask FROM {access}". tablesort_sql($header));
-  $access_types = array('user' => t('username'), 'mail' => t('e-mail'), 'host' => t('host'));
+  $access_types = array('user' => t('username'), 'mail' => t('e-mail'), 'host' => t('host'), 'referrer' => t('referrer'));
   $rows = array();
   while ($rule = db_fetch_object($result)) {
     $rows[] = array($rule->status ? t('allow') : t('deny'), $access_types[$rule->type], $rule->mask, l(t('edit'), 'admin/user/rules/edit/'. $rule->aid), l(t('delete'), 'admin/user/rules/delete/'. $rule->aid));
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.896
diff -u -r1.896 user.module
--- modules/user/user.module	20 Feb 2008 13:46:43 -0000	1.896
+++ modules/user/user.module	3 Mar 2008 16:53:34 -0000
@@ -1834,7 +1834,7 @@
     case 'admin/user/user/account/create':
       return '<p>'. t("This web page allows administrators to register new users. Users' e-mail addresses and usernames must be unique.") .'</p>';
     case 'admin/user/rules':
-      return '<p>'. t('Set up username and e-mail address access rules for new <em>and</em> existing accounts (currently logged in accounts will not be logged out). If a username or e-mail address for an account matches any deny rule, but not an allow rule, then the account will not be allowed to be created or to log in. A host rule is effective for every page view, not just registrations.') .'</p>';
+      return '<p>'. t('Set up username and e-mail address access rules for new <em>and</em> existing accounts (currently logged in accounts will not be logged out). If a username or e-mail address for an account matches any deny rule, but not an allow rule, then the account will not be allowed to be created or to log in. Host and referrer rules are effective for every page view, not just registrations.') .'</p>';
     case 'admin/user/permissions':
       return '<p>'. t('Permissions let you control what users can do on your site. Each user role (defined on the <a href="@role">user roles page</a>) has its own set of permissions. For example, you could give users classified as "Administrators" permission to "administer nodes" but deny this power to ordinary, "authenticated" users. You can use permissions to reveal new features to privileged users (those with subscriptions, for example). Permissions also allow trusted users to share the administrative burden of running a busy site.', array('@role' => url('admin/user/roles'))) .'</p>';
     case 'admin/user/roles':
