Added options for Shared Cache and Bulkquery program
authorbbice <bbice@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Mon, 25 Mar 2002 05:37:17 +0000 (05:37 +0000)
committerbbice <bbice@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Mon, 25 Mar 2002 05:37:17 +0000 (05:37 +0000)
git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@2634 7612ce4b-ef26-0410-bec9-ea0150e637f0

plugins/filters/filters.php
plugins/filters/setup.php

index 66de188..6257cd9 100644 (file)
  * $Id$
  */
 
+function filters_SaveCache () {
+    global $data_dir, $SpamFilters_DNScache;
+
+    if (file_exists($data_dir . "/dnscache")) {
+        $fp = fopen($data_dir . "/dnscache", "r");
+    } else {
+        $fp = false;
+    }
+    if ($fp) {
+        flock($fp,LOCK_EX);
+    } else {
+       $fp = fopen($data_dir . "/dnscache", "w+");
+       fclose($fp);
+       $fp = fopen($data_dir . "/dnscache", "r");
+       flock($fp,LOCK_EX);
+    }
+    $fp1=fopen($data_dir . "/dnscache", "w+");
+
+    foreach ($SpamFilters_DNScache as $Key=> $Value) {
+       $tstr = $Key . ',' . $Value['L'] . ',' . $Value['T'] . "\n";
+       fputs ($fp1, $tstr);
+    }
+    fclose($fp1);
+    flock($fp,LOCK_UN);
+    fclose($fp);
+}
+
+
+function filters_LoadCache () {
+    global $data_dir, $SpamFilters_DNScache;
+
+    if (file_exists($data_dir . "/dnscache")) {
+        if ($fp = fopen ($data_dir . "/dnscache", "r")) {
+            flock($fp,LOCK_SH);
+            while ($data=fgetcsv($fp,1024)) {
+               if ($data[2] > time()) {
+                  $SpamFilters_DNScache[$data[0]]['L'] = $data[1];
+                  $SpamFilters_DNScache[$data[0]]['T'] = $data[2];
+               }
+            }
+
+            flock($fp,LOCK_UN);
+        }
+    }
+}
+
+function filters_bulkquery($filters_spam_scan, $filters, $read) {
+    global $SpamFilters_YourHop, $attachment_dir, $username,
+           $SpamFilters_DNScache, $SpamFilters_BulkQuery;
+
+    $IPs = array();
+    $i = 0;
+    while ($i < count($read)) {
+        // EIMS will give funky results
+        $Chunks = explode(' ', $read[$i]);
+        if ($Chunks[0] != '*') {
+            $i ++;
+            continue;
+        }
+        $MsgNum = $Chunks[1];
+
+        $i ++;
+        $Scan = 1;
+
+        // Check for normal IMAP servers
+        if ($filters_spam_scan == 'new') {
+            if (is_int(strpos($Chunks[4], '\Seen'))) {
+                $Scan = 0;
+            }
+        }
+
+        // Look through all of the Received headers for IP addresses
+        // Stop when I get ")" on a line
+        // Stop if I get "*" on a line (don't advance)
+        // and above all, stop if $i is bigger than the total # of lines
+        while (($i < count($read)) &&
+                ($read[$i][0] != ')' && $read[$i][0] != '*' &&
+                $read[$i][0] != "\n")) {
+            // Check to see if this line is the right "Received from" line
+            // to check
+            if (is_int(strpos($read[$i], $SpamFilters_YourHop))) {
+
+                // short-circuit and skip work if we don't scan this one
+                if ($Scan) {
+                    $read[$i] = ereg_replace('[^0-9\.]', ' ', $read[$i]);
+                    $elements = explode(' ', $read[$i]);
+                    foreach ($elements as $value) {
+                        if ($value != '' &&
+                            ereg('[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}',
+                                $value, $regs)) {
+                            $Chunks = explode('.', $value);
+                            $IP = $Chunks[3] . '.' . $Chunks[2] . '.' .
+                                  $Chunks[1] . '.' . $Chunks[0];
+                            foreach ($filters as $key => $value) {
+                                if ($filters[$key]['enabled'] &&
+                                          $filters[$key]['dns']) {
+                                    if (strlen($SpamFilters_DNScache[$IP.'.'.$filters[$key]['dns']]) == 0) {
+                                       $IPs[$IP] = true;
+                                       break;
+                                    }
+                                }
+                            }
+                            // If we've checked one IP and YourHop is
+                            // just a space
+                            if ($SpamFilters_YourHop == ' ') {
+                                break;  // don't check any more
+                            }
+                        }
+                    }
+                }
+            }
+            $i ++;
+        }
+    }
+
+    if (count($IPs) > 0) {
+        $rbls = array();
+        foreach ($filters as $key => $value) {
+            if ($filters[$key]['enabled']) {
+                if ($filters[$key]['dns']) {
+                    $rbls[$filters[$key]['dns']] = true;
+                }
+            }
+        }
+
+        $bqfil = $attachment_dir . $username . "-bq.in";
+        $fp = fopen($bqfil, "w");
+        foreach ($rbls as $key => $value) {
+            fputs ($fp, "." . $key . "\n");
+        }
+        fputs ($fp, "----------\n");
+        foreach ($IPs as $key => $value) {
+            fputs ($fp, $key . "\n");
+        }
+        fclose ($fp);
+        $bqout = array();
+        exec ($SpamFilters_BulkQuery . " < " . $bqfil, $bqout);
+        foreach ($bqout as $value) {
+            $Chunks = explode(',', $value);
+            $SpamFilters_DNScache[$Chunks[0]]['L'] = $Chunks[1];
+            $SpamFilters_DNScache[$Chunks[0]]['T'] = $Chunks[2] + time();
+        }
+        unlink($bqfil);
+    }
+}
+
+
 function filters_sqimap_read_data ($imap_stream, $pre, $handle_errors, &$response, &$message) {
     global $color, $squirrelmail_language, $imap_general_debug;
 
@@ -203,11 +350,17 @@ function spam_filters($imap_stream) {
     global $data_dir, $username;
     global $SpamFilters_YourHop;
     global $SpamFilters_DNScache;
+    global $SpamFilters_SharedCache;
+    global $SpamFilters_BulkQuery;
 
     $filters_spam_scan = getPref($data_dir, $username, 'filters_spam_scan');
     $filters_spam_folder = getPref($data_dir, $username, 'filters_spam_folder');
     $filters = load_spam_filters();
 
+    if ($SpamFilters_SharedCache) {
+       filters_LoadCache();
+    }
+
     $run = 0;
 
     foreach ($filters as $Key=> $Value) {
@@ -235,6 +388,10 @@ function spam_filters($imap_stream) {
         return;
     }
 
+    if (strlen($SpamFilters_BulkQuery) > 0) {
+       filters_bulkquery($filters_spam_scan, $filters, $read);
+    }
+
     $i = 0;
     while ($i < count($read)) {
         // EIMS will give funky results
@@ -309,24 +466,30 @@ function spam_filters($imap_stream) {
 
     sqimap_mailbox_expunge($imap_stream, 'INBOX');
 
-    session_register('SpamFilters_DNScache');
+    if ($SpamFilters_SharedCache) {
+       filters_SaveCache();
+    } else {
+       session_register('SpamFilters_DNScache');
+    }
 }
 
 
 // Does the loop through each enabled filter for the specified IP address.
 // IP format:  $a.$b.$c.$d
 function filters_spam_check_site($a, $b, $c, $d, &$filters) {
-    global $SpamFilters_DNScache;
+    global $SpamFilters_DNScache, $SpamFilters_CacheTTL;
     foreach ($filters as $key => $value) {
         if ($filters[$key]['enabled']) {
             if ($filters[$key]['dns']) {
                 $filter_revip = $d . '.' . $c . '.' . $b . '.' . $a . '.' .
                                 $filters[$key]['dns'];
-                if (strlen($SpamFilters_DNScache[$filter_revip]) == 0) {
-                    $SpamFilters_DNScache[$filter_revip] =
+                if (strlen($SpamFilters_DNScache[$filter_revip]['L']) == 0) {
+                    $SpamFilters_DNScache[$filter_revip]['L'] =
                                         gethostbyname($filter_revip);
+                    $SpamFilters_DNScache[$filter_revip]['T'] =
+                                           time() + $SpamFilters_CacheTTL;
                 }
-                if ($SpamFilters_DNScache[$filter_revip] ==
+                if ($SpamFilters_DNScache[$filter_revip]['L'] ==
                     $filters[$key]['result']) {
                     return 1;
                 }
@@ -693,8 +856,8 @@ function filter_swap($id1, $id2) {
    renaming or deleting folders */
 function update_for_folder ($args) {
     $old_folder = $args[0];
-       $new_folder = $args[2];
-       $action = $args[1];
+        $new_folder = $args[2];
+        $action = $args[1];
     global $plugins, $data_dir, $username;
     $filters = array();
     $filters = load_filters();
index de06bc3..8dd576a 100644 (file)
@@ -60,10 +60,10 @@ $SpamFilters_YourHop = ' ';
  * Some of the SPAM filters are COMMERCIAL and require a fee. If your users
  * select them and you're not allowed to use them, it will make SPAM filtering
  * very slow. If you don't want them to even be offered to the users, you
- * set SpamFilters_ShowCommercial to false.
+ * should set SpamFilters_ShowCommercial to false.
  */
 global $SpamFilters_ShowCommercial;
-$SpamFilters_ShowCommercial = true;
+$SpamFilters_ShowCommercial = false;
 
 /*
  * A cache of IPs we've already checked or are known bad boys or good boys
@@ -74,6 +74,29 @@ $SpamFilters_ShowCommercial = true;
  */
 global $SpamFilters_DNScache;
 
+/*
+ * Absolute path to the bulkquery program. Leave blank if you don't have
+ * bulkquery compiled, installed, and lwresd running. See the README file
+ * in the bulkquery directory for more information on using bulkquery.
+ */
+global $SpamFilters_BulkQuery;
+$SpamFilters_BulkQuery = "";
+
+/*
+ * Do you want to use a shared file for the DNS cache or a session variable?
+ * Using a shared file means that every user can benefit from any queries
+ * made by other users. The shared file is named "dnscache" and is in the
+ * data directory.
+ */
+global $SpamFilters_SharedCache;
+$SpamFilters_SharedCache = true;
+
+/*
+ * How long should DNS query results be cached for by default (in seconds)?
+ */
+global $SpamFilters_CacheTTL;
+$SpamFilters_CacheTTL = 7200;
+
 require_once ('../plugins/filters/filters.php');
 
 function squirrelmail_plugin_init_filters() {
@@ -89,7 +112,7 @@ function squirrelmail_plugin_init_filters() {
     $squirrelmail_plugin_hooks['rename_or_delete_folder']['filters'] = 'update_for_folder';
     $squirrelmail_plugin_hooks['webmail_bottom']['filters'] = 'start_filters';
 }
-       
+
 function filters_special_mailbox( $mb ) {
     GLOBAL $data_dir, $username;