Source for file filters.php

Documentation is available at filters.php

  1. <?php
  2.  
  3. /**
  4.  * Message and Spam Filter Plugin - Filtering Functions
  5.  *
  6.  * @copyright 1999-2020 The SquirrelMail Project Team
  7.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  8.  * @version $Id: filters.php 14845 2020-01-07 08:09:34Z pdontthink $
  9.  * @package plugins
  10.  * @subpackage filters
  11.  */
  12.  
  13. // TODO: This plugin has an issue that seems to corrupt folder cache for subfolders of INBOX
  14. /**
  15.  * do not allow to call this file directly
  16.  */
  17. if (isset($_SERVER['SCRIPT_FILENAME']&& $_SERVER['SCRIPT_FILENAME'== __FILE__{
  18.     header("Location: ../../src/login.php");
  19.     die();
  20. }
  21.  
  22. /** load globals */
  23. global $UseSeparateImapConnection,
  24.     $AllowSpamFilters$SpamFilters_YourHop$SpamFilters_ShowCommercial,
  25.     $SpamFilters_DNScache$SpamFilters_BulkQuery$SpamFilters_SharedCache,
  26.     $SpamFilters_CacheTTL;
  27.  
  28. /**
  29.  * load required functions. Plugin depends on IMAP functions and they are not
  30.  * loaded in src/webmail.php
  31.  */
  32. include_once (SM_PATH 'functions/imap.php');
  33.  
  34. /** load default config */
  35. if (file_exists(SM_PATH 'plugins/filters/config_default.php')) {
  36.     include_once (SM_PATH 'plugins/filters/config_default.php');
  37. else {
  38.     // default config was removed.
  39.     $UseSeparateImapConnection false;
  40.     $AllowSpamFilters true;
  41.     $SpamFilters_YourHop ' ';
  42.     $SpamFilters_ShowCommercial false;
  43.     $SpamFilters_DNScache array();
  44.     $SpamFilters_BulkQuery '';
  45.     $SpamFilters_SharedCache true;
  46.     $SpamFilters_CacheTTL 7200;
  47. }
  48.  
  49. if (file_exists(SM_PATH 'config/filters_config.php')) {
  50.     include_once (SM_PATH 'config/filters_config.php');
  51. elseif (file_exists(SM_PATH 'plugins/filters/config.php')) {
  52.     include_once (SM_PATH 'plugins/filters/config.php');
  53. }
  54.  
  55. /**
  56.  * Register option blocks
  57.  * @access private
  58.  */
  59. function filters_optpage_register_block({
  60.     global $optpage_blocks$AllowSpamFilters;
  61.  
  62.     $optpage_blocks[array(
  63.         'name' => _("Message Filters"),
  64.         'url'  => SM_PATH 'plugins/filters/options.php',
  65.         'desc' => _("Filtering enables messages with different criteria to be automatically filtered into different folders for easier organization."),
  66.         'js'   => false
  67.     );
  68.  
  69.     if ($AllowSpamFilters{
  70.         $optpage_blocks[array(
  71.             'name' => _("SPAM Filters"),
  72.             'url'  => SM_PATH 'plugins/filters/spamoptions.php',
  73.             'desc' => _("SPAM filters allow you to select from various DNS based blacklists to detect junk email in your INBOX and move it to another folder (like Trash)."),
  74.             'js'   => false
  75.         );
  76.     }
  77. }
  78.  
  79. /* Receive the status of the folder and do something with it */
  80. function filters_folder_status($statusarr{
  81.  
  82.     global $filter_inbox_count;
  83.     if (empty($filter_inbox_count)) $filter_inbox_count=0;
  84.  
  85.     if ($statusarr['MAILBOX'== 'INBOX')
  86.     {
  87.      if (!empty($statusarr['MESSAGES'])) $filter_inbox_count=$statusarr['MESSAGES'];
  88.     }
  89. }
  90.  
  91. /**
  92.  * Saves the DNS Cache to disk
  93.  * @access private
  94.  */
  95. function filters_SaveCache ({
  96.     global $data_dir$SpamFilters_DNScache;
  97.  
  98.     if (file_exists($data_dir '/dnscache')) {
  99.         $fp fopen($data_dir '/dnscache''r');
  100.     else {
  101.         $fp false;
  102.     }
  103.     if ($fp{
  104.         flock($fp,LOCK_EX);
  105.     else {
  106.        $fp fopen($data_dir '/dnscache''w+');
  107.        fclose($fp);
  108.        $fp fopen($data_dir '/dnscache''r');
  109.        flock($fp,LOCK_EX);
  110.     }
  111.     $fp1 fopen($data_dir '/dnscache''w+');
  112.  
  113.     foreach ($SpamFilters_DNScache as $Key=> $Value{
  114.        $tstr $Key ',' $Value['L'',' $Value['T'"\n";
  115.        fputs ($fp1$tstr);
  116.     }
  117.     fclose($fp1);
  118.     flock($fp,LOCK_UN);
  119.     fclose($fp);
  120. }
  121.  
  122. /**
  123.  * Loads the DNS Cache from disk
  124.  * @access private
  125.  */
  126. function filters_LoadCache ({
  127.     global $data_dir$SpamFilters_DNScache;
  128.  
  129.     if (file_exists($data_dir '/dnscache')) {
  130.         $SpamFilters_DNScache array();
  131.         if ($fp fopen ($data_dir '/dnscache''r')) {
  132.             flock($fp,LOCK_SH);
  133.             while ($data fgetcsv($fp,1024)) {
  134.                if ($data[2time()) {
  135.                   $SpamFilters_DNScache[$data[0]]['L'$data[1];
  136.                   $SpamFilters_DNScache[$data[0]]['T'$data[2];
  137.                }
  138.             }
  139.             flock($fp,LOCK_UN);
  140.         }
  141.     }
  142. }
  143.  
  144. /**
  145.  * Uses the BulkQuery executable to query all the RBLs at once
  146.  * @param array $filters Array of SPAM Filters
  147.  * @param array $IPs Array of IP Addresses
  148.  * @access private
  149.  */
  150. function filters_bulkquery($filters$IPs{
  151.     global $attachment_dir$username,
  152.            $SpamFilters_CacheTTL;
  153.  
  154.     if (count($IPs0{
  155.         $rbls array();
  156.         foreach ($filters as $key => $value{
  157.             if ($filters[$key]['enabled']{
  158.                 if ($filters[$key]['dns']{
  159.                     $rbls[$filters[$key]['dns']] true;
  160.                 }
  161.             }
  162.         }
  163.  
  164.         $bqfil $attachment_dir $username '-bq.in';
  165.         $fp fopen($bqfil'w');
  166.         fputs ($fp$SpamFilters_CacheTTL "\n");
  167.         foreach ($rbls as $key => $value{
  168.             fputs ($fp'.' $key "\n");
  169.         }
  170.         fputs ($fp"----------\n");
  171.         foreach ($IPs as $key => $value{
  172.             fputs ($fp$key "\n");
  173.         }
  174.         fclose ($fp);
  175.         $bqout array();
  176.         exec ($SpamFilters_BulkQuery ' < ' $bqfil$bqout);
  177.         foreach ($bqout as $value{
  178.             $Chunks explode(','$value);
  179.             $SpamFilters_DNScache[$Chunks[0]]['L'$Chunks[1];
  180.             $SpamFilters_DNScache[$Chunks[0]]['T'$Chunks[2time();
  181.         }
  182.         unlink($bqfil);
  183.     }
  184. }
  185.  
  186. /**
  187.  * Starts the filtering process
  188.  * @param array $hook_args (since 1.5.2) do hook arguments. Is used to check
  189.  *  hook name, array key = 0.
  190.  * @access private
  191.  */
  192. function start_filters($hook_args{
  193.     global $imapServerAddress$imapPort$imap_stream_options$imap_stream,
  194.            $imapConnection$UseSeparateImapConnection$AllowSpamFilters,
  195.            $filter_inbox_count$username;
  196.  
  197.     // if there were filtering errors previously during
  198.     // this login session, we won't try again
  199.     //
  200.     // (errors that this plugin was able to catch or a "NO"
  201.     // response/failure from IMAP found in the current session,
  202.     // which could have resulted from an attempted filter copy
  203.     // (over quota), in which case execution halts before this
  204.     // plugin can catch the problem -- note, however, that any
  205.     // other IMAP "NO" failure (caused by unrelated actions) at
  206.     // any time during the current session will cause this plugin
  207.     // to effectively shut down)
  208.     //
  209.     sqgetGlobalVar('filters_error'$filters_errorSQ_SESSIONFALSE);
  210.     sqgetGlobalVar('IMAP_FATAL_ERROR_TYPE'$imap_fatal_errorSQ_SESSION'');
  211.     if ($filters_error || $imap_fatal_error == 'NO')
  212.         return;
  213.  
  214.     /**
  215.      * check hook that calls filtering. If filters are called by right_main_after_header,
  216.      * do filtering only when we are in INBOX folder.
  217.      */
  218.     if ($hook_args[0]=='right_main_after_header' &&
  219.         (sqgetGlobalVar('mailbox',$mailbox,SQ_FORM&& $mailbox!='INBOX')) {
  220.         return;
  221.     }
  222.  
  223.     $filters load_filters();
  224.  
  225.     // No point running spam filters if there aren't any to run //
  226.     if ($AllowSpamFilters{
  227.         $spamfilters load_spam_filters();
  228.  
  229.         $AllowSpamFilters false;
  230.         foreach($spamfilters as $value{
  231.             if ($value['enabled'== SMPREF_ON{
  232.                 $AllowSpamFilters true;
  233.                 break;
  234.             }
  235.         }
  236.     }
  237.  
  238.     // No user filters, and no spam filters, no need to continue //
  239.     if (!$AllowSpamFilters && empty($filters)) {
  240.         return;
  241.     }
  242.  
  243.  
  244.     // Detect if we have already connected to IMAP or not.
  245.     // Also check if we are forced to use a separate IMAP connection
  246.     if ((!isset($imap_stream&& !isset($imapConnection)) ||
  247.         $UseSeparateImapConnection {
  248.             $stream sqimap_login($usernamefalse$imapServerAddress,
  249.                                 $imapPort10$imap_stream_options);
  250.             $previously_connected false;
  251.     else if (isset($imapConnection)) {
  252.         $stream $imapConnection;
  253.         $previously_connected true;
  254.     else {
  255.         $previously_connected true;
  256.         $stream $imap_stream;
  257.     }
  258.  
  259.     if (!isset($filter_inbox_count)) {
  260.         $aStatus sqimap_status_messages ($stream'INBOX'array('MESSAGES'));
  261.         if (!empty($aStatus['MESSAGES'])) {
  262.             $filter_inbox_count=$aStatus['MESSAGES'];
  263.         else {
  264.             $filter_inbox_count=0;
  265.         }
  266.     }
  267.  
  268.     if ($filter_inbox_count 0{
  269.         sqimap_mailbox_select($stream'INBOX');
  270.         // Filter spam from inbox before we sort them into folders
  271.         if ($AllowSpamFilters{
  272.             spam_filters($stream);
  273.         }
  274.  
  275.         // Sort into folders
  276.         user_filters($stream);
  277.     }
  278.  
  279.     if (!$previously_connected{
  280.         sqimap_logout($stream);
  281.     }
  282. }
  283.  
  284. /**
  285.  * Does the loop through each filter
  286.  * @param stream imap_stream the stream to read from
  287.  * @access private
  288.  */
  289. function user_filters($imap_stream{
  290.     global $data_dir$username;
  291.     $filters load_filters();
  292.     if ($filtersreturn;
  293.     $filters_user_scan getPref($data_dir$username'filters_user_scan');
  294.  
  295.     $expunge false;
  296.     // For every rule
  297.     for ($i=0$num count($filters)$i $num$i++{
  298.         // If it is the "combo" rule
  299.         if ($filters[$i]['where'== 'To or Cc'{
  300.             /*
  301.             *  If it's "TO OR CC", we have to do two searches, one for TO
  302.             *  and the other for CC.
  303.             */
  304.             $expunge filter_search_and_delete($imap_stream'TO',
  305.                   $filters[$i]['what']$filters[$i]['folder']$filters_user_scan$expunge);
  306.             $expunge filter_search_and_delete($imap_stream'CC',
  307.                   $filters[$i]['what']$filters[$i]['folder']$filters_user_scan$expunge);
  308.         else if ($filters[$i]['where'== 'Header and Body'{
  309.             $expunge filter_search_and_delete($imap_stream'TEXT',
  310.                   $filters[$i]['what']$filters[$i]['folder']$filters_user_scan$expunge);
  311.         else if ($filters[$i]['where'== 'Message Body'{
  312.             $expunge filter_search_and_delete($imap_stream'BODY',
  313.                   $filters[$i]['what']$filters[$i]['folder']$filters_user_scan$expunge);
  314.         else {
  315.             /*
  316.             *  If it's a normal TO, CC, SUBJECT, or FROM, then handle it
  317.             *  normally.
  318.             */
  319.             $expunge filter_search_and_delete($imap_stream$filters[$i]['where'],
  320.                  $filters[$i]['what']$filters[$i]['folder']$filters_user_scan$expunge);
  321.         }
  322.     }
  323.     // Clean out the mailbox whether or not auto_expunge is on
  324.     // That way it looks like it was redirected properly
  325.     if ($expunge{
  326.         sqimap_mailbox_expunge($imap_stream'INBOX');
  327.     }
  328. }
  329.  
  330. /**
  331.  * Creates and runs the IMAP command to filter messages
  332.  * @param string $imap_stream TODO: Document this parameter
  333.  * @param string $where Which part of the message to search (TO, CC, SUBJECT, etc...)
  334.  * @param string $what String to search for
  335.  * @param string $where_to Folder it will move to
  336.  * @param string $user_scan Whether to search all or just unseen
  337.  * @param string $should_expunge 
  338.  * @access private
  339.  */
  340. function filter_search_and_delete($imap_stream$where$what$where_to$user_scan,
  341.                                   $should_expunge{
  342.     global $languages$squirrelmail_language$allow_charset_search$imap_server_type;
  343.  
  344.     //TODO: make use of new mailbox cache. See mailbox_display.phpinfo
  345.  
  346.     if (strtolower($where_to== 'inbox'{
  347.         return array();
  348.     }
  349.  
  350.     if ($user_scan == 'new'{
  351.         $category 'UNSEEN';
  352.     else {
  353.         $category 'ALL';
  354.     }
  355.     $category .= ' UNDELETED';
  356.  
  357.     if ($allow_charset_search &&
  358.         isset($languages[$squirrelmail_language]['CHARSET']&&
  359.         $languages[$squirrelmail_language]['CHARSET']{
  360.         $search_str 'SEARCH CHARSET '
  361.                     . strtoupper($languages[$squirrelmail_language]['CHARSET'])
  362.                     . ' ' $category;
  363.     else {
  364.         $search_str 'SEARCH CHARSET US-ASCII ' $category;
  365.     }
  366.     if ($where == 'Header'{
  367.         $what  explode(':'$what);
  368.         $where strtoupper($where);
  369.         $where trim($where ' ' $what[0]);
  370.         $what  addslashes(trim($what[1]));
  371.     }
  372.  
  373.     // see comments in squirrelmail sqimap_search function
  374.     if ($imap_server_type == 'macosx' || $imap_server_type == 'hmailserver'{
  375.         $search_str .= ' ' $where ' ' $what;
  376.         /* read data back from IMAP */
  377.         $read sqimap_run_command($imap_stream$search_strtrue$response$messageTRUE);
  378.     else {
  379.         $search_str .= ' ' $where ' {' strlen($what"}";
  380.         $sid sqimap_session_id(true);
  381.         fputs ($imap_stream$sid ' ' $search_str "\r\n");
  382.         $read2 sqimap_fgets($imap_stream);
  383.         # server should respond with Ready for argument, then we will send search text
  384.         #echo "RR2 $read2<br>";
  385.         fputs ($imap_stream"$what\r\n");
  386.         #echo "SS $what<br>";
  387.         $read2 sqimap_fgets($imap_stream);
  388.         #echo "RR2 $read2<br>";
  389.         $read[]=$read2;
  390.         $read3 sqimap_fgets($imap_stream);
  391.         #echo "RR3 $read3<br>";
  392.         list($rtag,$response,$message)=explode(' ',$read3,3);
  393. ##        $read2 = sqimap_retrieve_imap_response($imap_stream, $sid, true,
  394. ##              $response, $message, $search_str, false, true, false);
  395.         #echo "RR2 $read2 / RESPONSE $response<br>";
  396.     }
  397.  
  398.     if (isset($read[0])) {
  399.         $ids array();
  400.         for ($i 0$iCnt count($read)$i $iCnt++$i{
  401.             if (preg_match("/^\* SEARCH (.+)$/"$read[$i]$regs)) {
  402.                 $ids += explode(' 'trim($regs[1]));
  403.             }
  404.         }
  405.         if ($response == 'OK' && count($ids)) {
  406.             if (sqimap_mailbox_exists($imap_stream$where_to)) {
  407.                 if (!sqimap_msgs_list_move ($imap_stream$ids$where_tofalse)) {
  408.                     // if errors occurred, don't try to filter again during this session
  409.                     sqsession_register(TRUE'filters_error');
  410.                     global $color;
  411.                     error_box(_("A problem occurred filtering messages. Check filter settings and account quota if applicable. Filtering is disabled for the remainder of this login session.")$color);
  412.                 }
  413.  
  414.                 // expunge even in the case of errors, in case some
  415.                 // messages were filtered before the error happened
  416.                 $should_expunge true;
  417.             }
  418.         elseif ($response != 'OK'{
  419.             $query $search_str "\r\n".$what ."\r\n";
  420.             if ($response == 'NO'{
  421.                 if (strpos($message,'BADCHARSET'!== false ||
  422.                     strpos($message,'character'!== false{
  423.                     sqm_trigger_imap_error('SQM_IMAP_BADCHARSET',$query$response$message);
  424.                 else {
  425.                     sqm_trigger_imap_error('SQM_IMAP_ERROR',$query$response$message);
  426.                 }
  427.             else {
  428.                 sqm_trigger_imap_error('SQM_IMAP_ERROR',$query$response$message);
  429.             }
  430.         }
  431.     }
  432.     return $should_expunge;
  433. }
  434.  
  435. /**
  436.  * Loops through all the Received Headers to find IP Addresses
  437.  * @param stream imap_stream the stream to read from
  438.  * @access private
  439.  */
  440. function spam_filters($imap_stream{
  441.     global $data_dir$username;
  442.     global $SpamFilters_YourHop;
  443.     global $SpamFilters_DNScache;
  444.     global $SpamFilters_SharedCache;
  445.     global $SpamFilters_BulkQuery;
  446.     global $SpamFilters_CacheTTL;
  447.  
  448.     $filters_spam_scan getPref($data_dir$username'filters_spam_scan');
  449.     $filters_spam_folder getPref($data_dir$username'filters_spam_folder');
  450.     $filters load_spam_filters();
  451.  
  452.     if ($SpamFilters_SharedCache{
  453.        filters_LoadCache();
  454.     }
  455.  
  456.     $run false;
  457.  
  458.     foreach ($filters as $Value{
  459.         if ($Value['enabled']{
  460.             $run true;
  461.             break;
  462.         }
  463.     }
  464.  
  465.     // short-circuit
  466.     if (!$run{
  467.         return;
  468.     }
  469.  
  470.     // Ask for a big list of all "Received" headers in the inbox with
  471.     // flags for each message.  Kinda big.
  472.  
  473.     if ($filters_spam_scan == 'new'{
  474.         $search_array array();
  475.         $read sqimap_run_command($imap_stream'SEARCH UNSEEN'true$response$messageTRUE);
  476.         if (isset($read[0])) {
  477.             for ($i 0$iCnt count($read)$i $iCnt++$i{
  478.                 if (preg_match("/^\* SEARCH (.+)$/"$read[$i]$regs)) {
  479.                     $search_array explode(' 'trim($regs[1]));
  480.                     break;
  481.                 }
  482.             }
  483.         }
  484.     }
  485.     if ($filters_spam_scan == 'new' && count($search_array)) {
  486.         $headers sqimap_get_small_header_list ($imap_stream$search_arrayarray('Received'),array());
  487.     else if ($filters_spam_scan != 'new'{
  488.         $headers sqimap_get_small_header_list ($imap_streamnull array('Received'),array());
  489.     else {
  490.         return;
  491.     }
  492.     if (!count($headers)) {
  493.         return;
  494.     }
  495.     $bulkquery (strlen($SpamFilters_BulkQuerytrue false);
  496.     $IPs array();
  497.     $aSpamIds array();
  498.     foreach ($headers as $id => $aValue{
  499.         if (isset($aValue['UID'])) {
  500.             $MsgNum $aValue['UID'];
  501.         else {
  502.             $MsgNum $id;
  503.         }
  504.         // Look through all of the Received headers for IP addresses
  505.         if (isset($aValue['RECEIVED'])) {
  506.             foreach ($aValue['RECEIVED'as $received{
  507.                 // Check to see if this line is the right "Received from" line
  508.                 // to check
  509.  
  510.                 // $aValue['Received'] is an array with all the received lines.
  511.                 // We should check them from bottom to top and only check the first 2.
  512.                 // Currently we check only the header where $SpamFilters_YourHop in occures
  513.  
  514.                 if (is_int(strpos($received$SpamFilters_YourHop))) {
  515.                     if (preg_match('/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/',$received,$aMatch)) {
  516.                         $isspam false;
  517.                         if (filters_spam_check_site($aMatch[1],$aMatch[2],$aMatch[3],$aMatch[4],$filters)) {
  518.                             $aSpamIds[$MsgNum;
  519.                             $isspam true;
  520.                         }
  521.  
  522.                         if ($bulkquery{
  523.                             array_shift($aMatch);
  524.                             $IP explode('.'$aMatch);
  525.                             foreach ($filters as $key => $value{
  526.                                 if ($filters[$key]['enabled'&& $filters[$key]['dns']{
  527.                                     if (strlen($SpamFilters_DNScache[$IP.'.'.$filters[$key]['dns']]== 0{
  528.                                         $IPs[$IPtrue;
  529.                                         break;
  530.                                     }
  531.                                 }
  532.                             }
  533.                         }
  534.                         // If we've checked one IP and YourHop is
  535.                         // just a space
  536.                         if ($SpamFilters_YourHop == ' ' || $isspam{
  537.                             break;  // don't check any more
  538.                         }
  539.                     }
  540.                 }
  541.             }
  542.         }
  543.     }
  544.     // Lookie!  It's spam!  Yum!
  545.     if (count($aSpamIds&& sqimap_mailbox_exists($imap_stream$filters_spam_folder)) {
  546.         if (!sqimap_msgs_list_move($imap_stream$aSpamIds$filters_spam_folder)) {
  547.            // if errors occurred, don't try to filter again during this session
  548.            sqsession_register(TRUE'filters_error');
  549.            global $color;
  550.            error_box(_("A problem occurred filtering messages. Check filter settings and account quota if applicable. Filtering is disabled for the remainder of this login session.")$color);
  551.         }
  552.  
  553.         // expunge even in the case of errors, in case some
  554.         // messages were filtered before the error happened
  555.         sqimap_mailbox_expunge($imap_stream'INBOX');
  556.     }
  557.  
  558.     if ($bulkquery && count($IPs)) {
  559.         filters_bulkquery($filters$IPs);
  560.     }
  561.  
  562.     if ($SpamFilters_SharedCache{
  563.        filters_SaveCache();
  564.     else {
  565.        sqsession_register($SpamFilters_DNScache'SpamFilters_DNScache');
  566.     }
  567. }
  568.  
  569. /**
  570.  * Does the loop through each enabled filter for the specified IP address.
  571.  * IP format:  $a.$b.$c.$d
  572.  * @param int $a First subset of IP
  573.  * @param int $b Second subset of IP
  574.  * @param int $c Third subset of IP
  575.  * @param int $d Forth subset of IP
  576.  * @param array $filters The Spam Filters
  577.  * @return boolean Whether the IP is Spam
  578.  * @access private
  579.  */
  580. function filters_spam_check_site($a$b$c$d&$filters{
  581.     foreach ($filters as $key => $value{
  582.         if ($filters[$key]['enabled']{
  583.             if ($filters[$key]['dns']{
  584.  
  585.                 /**
  586.                  * RFC allows . on end of hostname to force domain lookup to
  587.                  * not use search domain from resolv.conf, i.e. to ensure
  588.                  * search domain isn't used if no hostname is found
  589.                  */
  590.                 $filter_revip $d '.' $c '.' $b '.' $a '.' .
  591.                                 $filters[$key]['dns''.';
  592.  
  593.                 if(!isset($SpamFilters_DNScache[$filter_revip]['L']))
  594.                         $SpamFilters_DNScache[$filter_revip]['L''';
  595.  
  596.                 if(!isset($SpamFilters_DNScache[$filter_revip]['T']))
  597.                         $SpamFilters_DNScache[$filter_revip]['T''';
  598.  
  599.                 if (strlen($SpamFilters_DNScache[$filter_revip]['L']== 0{
  600.                     $SpamFilters_DNScache[$filter_revip]['L'=
  601.                                     gethostbyname($filter_revip);
  602.                     $SpamFilters_DNScache[$filter_revip]['T'=
  603.                                        time($SpamFilters_CacheTTL;
  604.                 }
  605.  
  606.                 /**
  607.                  * gethostbyname returns ip if resolved, or returns original
  608.                  * host supplied to function if there is no resolution
  609.                  */
  610.                 if ($SpamFilters_DNScache[$filter_revip]['L'!= $filter_revip{
  611.                     return 1;
  612.                 }
  613.             }
  614.         }
  615.     }
  616.     return 0;
  617. }
  618.  
  619. /**
  620.  * Loads the filters from the user preferences
  621.  * @return array All the user filters
  622.  * @access private
  623.  */
  624. function load_filters({
  625.     global $data_dir$username;
  626.  
  627.     $filters array();
  628.     for ($i 0$fltr getPref($data_dir$username'filter' $i)$i++{
  629.         $ary explode(','$fltr);
  630.         $filters[$i]['where'$ary[0];
  631.         $filters[$i]['what'str_replace('###COMMA###'','$ary[1]);
  632.         $filters[$i]['folder'$ary[2];
  633.     }
  634.     return $filters;
  635. }
  636.  
  637. /**
  638.  * Loads the Spam Filters and checks the preferences for the enabled status
  639.  * @return array All the spam filters
  640.  * @access private
  641.  */
  642. function load_spam_filters({
  643.     global $data_dir$username$SpamFilters_ShowCommercial;
  644.  
  645.     if ($SpamFilters_ShowCommercial{
  646.         $filters['MAPS RBL']['prefname''filters_spam_maps_rbl';
  647.         $filters['MAPS RBL']['name''MAPS Realtime Blackhole List';
  648.         $filters['MAPS RBL']['link''http://www.mail-abuse.org/rbl/';
  649.         $filters['MAPS RBL']['dns''blackholes.mail-abuse.org';
  650.         $filters['MAPS RBL']['result''127.0.0.2';
  651.         $filters['MAPS RBL']['comment'=
  652.             _("COMMERCIAL - This list contains servers that are verified spam senders. It is a pretty reliable list to scan spam from.");
  653.  
  654.         $filters['MAPS RSS']['prefname''filters_spam_maps_rss';
  655.         $filters['MAPS RSS']['name''MAPS Relay Spam Stopper';
  656.         $filters['MAPS RSS']['link''http://www.mail-abuse.org/rss/';
  657.         $filters['MAPS RSS']['dns''relays.mail-abuse.org';
  658.         $filters['MAPS RSS']['result''127.0.0.2';
  659.         $filters['MAPS RSS']['comment'=
  660.             _("COMMERCIAL - Servers that are configured (or misconfigured) to allow spam to be relayed through their system will be banned with this. Another good one to use.");
  661.  
  662.         $filters['MAPS DUL']['prefname''filters_spam_maps_dul';
  663.         $filters['MAPS DUL']['name''MAPS Dial-Up List';
  664.         $filters['MAPS DUL']['link''http://www.mail-abuse.org/dul/';
  665.         $filters['MAPS DUL']['dns''dialups.mail-abuse.org';
  666.         $filters['MAPS DUL']['result''127.0.0.3';
  667.         $filters['MAPS DUL']['comment'=
  668.             _("COMMERCIAL - Dial-up users are often filtered out since they should use their ISP's mail servers to send mail. Spammers typically get a dial-up account and send spam directly from there.");
  669.  
  670.         $filters['MAPS RBLplus-RBL']['prefname''filters_spam_maps_rblplus_rbl';
  671.         $filters['MAPS RBLplus-RBL']['name''MAPS RBL+ RBL List';
  672.         $filters['MAPS RBLplus-RBL']['link''http://www.mail-abuse.org/';
  673.         $filters['MAPS RBLplus-RBL']['dns''rbl-plus.mail-abuse.org';
  674.         $filters['MAPS RBLplus-RBL']['result''127.0.0.2';
  675.         $filters['MAPS RBLplus-RBL']['comment'=
  676.             _("COMMERCIAL - RBL+ Blackhole entries.");
  677.  
  678.         $filters['MAPS RBLplus-RSS']['prefname''filters_spam_maps_rblplus_rss';
  679.         $filters['MAPS RBLplus-RSS']['name''MAPS RBL+ List RSS entries';
  680.         $filters['MAPS RBLplus-RSS']['link''http://www.mail-abuse.org/';
  681.         $filters['MAPS RBLplus-RSS']['dns''rbl-plus.mail-abuse.org';
  682.         $filters['MAPS RBLplus-RSS']['result''127.0.0.2';
  683.         $filters['MAPS RBLplus-RSS']['comment'=
  684.             _("COMMERCIAL - RBL+ OpenRelay entries.");
  685.  
  686.         $filters['MAPS RBLplus-DUL']['prefname''filters_spam_maps_rblplus_dul';
  687.         $filters['MAPS RBLplus-DUL']['name''MAPS RBL+ List DUL entries';
  688.         $filters['MAPS RBLplus-DUL']['link''http://www.mail-abuse.org/';
  689.         $filters['MAPS RBLplus-DUL']['dns''rbl-plus.mail-abuse.org';
  690.         $filters['MAPS RBLplus-DUL']['result''127.0.0.3';
  691.         $filters['MAPS RBLplus-DUL']['comment'=
  692.             _("COMMERCIAL - RBL+ Dial-up entries.");
  693.     }
  694.  
  695.     $filters['FiveTen Direct']['prefname''filters_spam_fiveten_src';
  696.     $filters['FiveTen Direct']['name''Five-Ten-sg.com Direct SPAM Sources';
  697.     $filters['FiveTen Direct']['link''http://www.five-ten-sg.com/blackhole.php';
  698.     $filters['FiveTen Direct']['dns''blackholes.five-ten-sg.com';
  699.     $filters['FiveTen Direct']['result''127.0.0.2';
  700.     $filters['FiveTen Direct']['comment'=
  701.         _("FREE - Five-Ten-sg.com - Direct SPAM sources.");
  702.  
  703.     $filters['FiveTen DUL']['prefname''filters_spam_fiveten_dul';
  704.     $filters['FiveTen DUL']['name''Five-Ten-sg.com DUL Lists';
  705.     $filters['FiveTen DUL']['link''http://www.five-ten-sg.com/blackhole.php';
  706.     $filters['FiveTen DUL']['dns''blackholes.five-ten-sg.com';
  707.     $filters['FiveTen DUL']['result''127.0.0.3';
  708.     $filters['FiveTen DUL']['comment'=
  709.         _("FREE - Five-Ten-sg.com - Dial-up lists - includes some DSL IPs.");
  710.  
  711.     $filters['FiveTen Unc. OptIn']['prefname''filters_spam_fiveten_oi';
  712.     $filters['FiveTen Unc. OptIn']['name''Five-Ten-sg.com Unconfirmed OptIn Lists';
  713.     $filters['FiveTen Unc. OptIn']['link''http://www.five-ten-sg.com/blackhole.php';
  714.     $filters['FiveTen Unc. OptIn']['dns''blackholes.five-ten-sg.com';
  715.     $filters['FiveTen Unc. OptIn']['result''127.0.0.4';
  716.     $filters['FiveTen Unc. OptIn']['comment'=
  717.         _("FREE - Five-Ten-sg.com - Bulk mailers that do not use confirmed opt-in.");
  718.  
  719.     $filters['FiveTen Others']['prefname''filters_spam_fiveten_oth';
  720.     $filters['FiveTen Others']['name''Five-Ten-sg.com Other Misc. Servers';
  721.     $filters['FiveTen Others']['link''http://www.five-ten-sg.com/blackhole.php';
  722.     $filters['FiveTen Others']['dns''blackholes.five-ten-sg.com';
  723.     $filters['FiveTen Others']['result''127.0.0.5';
  724.     $filters['FiveTen Others']['comment'=
  725.         _("FREE - Five-Ten-sg.com - Other misc. servers.");
  726.  
  727.     $filters['FiveTen Single Stage']['prefname''filters_spam_fiveten_ss';
  728.     $filters['FiveTen Single Stage']['name''Five-Ten-sg.com Single Stage Servers';
  729.     $filters['FiveTen Single Stage']['link''http://www.five-ten-sg.com/blackhole.php';
  730.     $filters['FiveTen Single Stage']['dns''blackholes.five-ten-sg.com';
  731.     $filters['FiveTen Single Stage']['result''127.0.0.6';
  732.     $filters['FiveTen Single Stage']['comment'=
  733.         _("FREE - Five-Ten-sg.com - Single Stage servers.");
  734.  
  735.     $filters['FiveTen SPAM Support']['prefname''filters_spam_fiveten_supp';
  736.     $filters['FiveTen SPAM Support']['name''Five-Ten-sg.com SPAM Support Servers';
  737.     $filters['FiveTen SPAM Support']['link''http://www.five-ten-sg.com/blackhole.php';
  738.     $filters['FiveTen SPAM Support']['dns''blackholes.five-ten-sg.com';
  739.     $filters['FiveTen SPAM Support']['result''127.0.0.7';
  740.     $filters['FiveTen SPAM Support']['comment'=
  741.         _("FREE - Five-Ten-sg.com - SPAM Support servers.");
  742.  
  743.     $filters['FiveTen Web forms']['prefname''filters_spam_fiveten_wf';
  744.     $filters['FiveTen Web forms']['name''Five-Ten-sg.com Web Form IPs';
  745.     $filters['FiveTen Web forms']['link''http://www.five-ten-sg.com/blackhole.php';
  746.     $filters['FiveTen Web forms']['dns''blackholes.five-ten-sg.com';
  747.     $filters['FiveTen Web forms']['result''127.0.0.8';
  748.     $filters['FiveTen Web forms']['comment'=
  749.         _("FREE - Five-Ten-sg.com - Web Form IPs.");
  750.  
  751.     $filters['Dorkslayers']['prefname''filters_spam_dorks';
  752.     $filters['Dorkslayers']['name''Dorkslayers Lists';
  753.     $filters['Dorkslayers']['link''http://www.dorkslayers.com';
  754.     $filters['Dorkslayers']['dns''orbs.dorkslayers.com';
  755.     $filters['Dorkslayers']['result''127.0.0.2';
  756.     $filters['Dorkslayers']['comment'=
  757.         _("FREE - Dorkslayers appears to include only really bad open relays outside the US to avoid being sued. Interestingly enough, their website recommends you NOT use their service.");
  758.  
  759.     $filters['SPAMhaus']['prefname''filters_spam_spamhaus';
  760.     $filters['SPAMhaus']['name''SPAMhaus Lists';
  761.     $filters['SPAMhaus']['link''http://www.spamhaus.org';
  762.     $filters['SPAMhaus']['dns''sbl.spamhaus.org';
  763.     $filters['SPAMhaus']['result''127.0.0.2';
  764.     $filters['SPAMhaus']['comment'=
  765.         _("FREE - SPAMhaus - A list of well-known SPAM sources.");
  766.  
  767.     $filters['SPAMcop']['prefname''filters_spam_spamcop';
  768.     $filters['SPAMcop']['name''SPAM Cop Lists';
  769.     $filters['SPAMcop']['link''http://spamcop.net/bl.shtml';
  770.     $filters['SPAMcop']['dns''bl.spamcop.net';
  771.     $filters['SPAMcop']['result''127.0.0.2';
  772.     $filters['SPAMcop']['comment'=
  773.         _("FREE, for now - SpamCop - An interesting solution that lists servers that have a very high spam to legit email ratio (85 percent or more).");
  774.  
  775.     $filters['dev.null.dk']['prefname''filters_spam_devnull';
  776.     $filters['dev.null.dk']['name''dev.null.dk Lists';
  777.     $filters['dev.null.dk']['link''http://dev.null.dk/';
  778.     $filters['dev.null.dk']['dns''dev.null.dk';
  779.     $filters['dev.null.dk']['result''127.0.0.2';
  780.     $filters['dev.null.dk']['comment'=
  781.         _("FREE - dev.null.dk - I don't have any detailed info on this list.");
  782.  
  783.     $filters['visi.com']['prefname''filters_spam_visi';
  784.     $filters['visi.com']['name''visi.com Relay Stop List';
  785.     $filters['visi.com']['link''http://relays.visi.com';
  786.     $filters['visi.com']['dns''relays.visi.com';
  787.     $filters['visi.com']['result''127.0.0.2';
  788.     $filters['visi.com']['comment'=
  789.         _("FREE - visi.com - Relay Stop List. Very conservative OpenRelay List.");
  790.  
  791.     $filters['ahbl.org Open Relays']['prefname''filters_spam_2mb_or';
  792.     $filters['ahbl.org Open Relays']['name''ahbl.org Open Relays List';
  793.     $filters['ahbl.org Open Relays']['link''http://www.ahbl.org/';
  794.     $filters['ahbl.org Open Relays']['dns''dnsbl.ahbl.org';
  795.     $filters['ahbl.org Open Relays']['result''127.0.0.2';
  796.     $filters['ahbl.org Open Relays']['comment'=
  797.         _("FREE - ahbl.org Open Relays - Another list of Open Relays.");
  798.  
  799.     $filters['ahbl.org SPAM Source']['prefname''filters_spam_2mb_ss';
  800.     $filters['ahbl.org SPAM Source']['name''ahbl.org SPAM Source List';
  801.     $filters['ahbl.org SPAM Source']['link''http://www.ahbl.org/';
  802.     $filters['ahbl.org SPAM Source']['dns''dnsbl.ahbl.org';
  803.     $filters['ahbl.org SPAM Source']['result''127.0.0.4';
  804.     $filters['ahbl.org SPAM Source']['comment'=
  805.         _("FREE - ahbl.org SPAM Source - List of Direct SPAM Sources.");
  806.  
  807.     $filters['ahbl.org SPAM ISPs']['prefname''filters_spam_2mb_isp';
  808.     $filters['ahbl.org SPAM ISPs']['name''ahbl.org SPAM-friendly ISP List';
  809.     $filters['ahbl.org SPAM ISPs']['link''http://www.ahbl.org/';
  810.     $filters['ahbl.org SPAM ISPs']['dns''dnsbl.ahbl.org';
  811.     $filters['ahbl.org SPAM ISPs']['result''127.0.0.7';
  812.     $filters['ahbl.org SPAM ISPs']['comment'=
  813.         _("FREE - ahbl.org SPAM ISPs - List of SPAM-friendly ISPs.");
  814.  
  815.     $filters['Leadmon DUL']['prefname''filters_spam_lm_dul';
  816.     $filters['Leadmon DUL']['name''Leadmon.net DUL List';
  817.     $filters['Leadmon DUL']['link''http://www.leadmon.net/spamguard/';
  818.     $filters['Leadmon DUL']['dns''spamguard.leadmon.net';
  819.     $filters['Leadmon DUL']['result''127.0.0.2';
  820.     $filters['Leadmon DUL']['comment'=
  821.         _("FREE - Leadmon DUL - Another list of Dial-up or otherwise dynamically assigned IPs.");
  822.  
  823.     $filters['Leadmon SPAM Source']['prefname''filters_spam_lm_ss';
  824.     $filters['Leadmon SPAM Source']['name''Leadmon.net SPAM Source List';
  825.     $filters['Leadmon SPAM Source']['link''http://www.leadmon.net/spamguard/';
  826.     $filters['Leadmon SPAM Source']['dns''spamguard.leadmon.net';
  827.     $filters['Leadmon SPAM Source']['result''127.0.0.3';
  828.     $filters['Leadmon SPAM Source']['comment'=
  829.         _("FREE - Leadmon SPAM Source - List of IPs Leadmon.net has received SPAM directly from.");
  830.  
  831.     $filters['Leadmon Bulk Mailers']['prefname''filters_spam_lm_bm';
  832.     $filters['Leadmon Bulk Mailers']['name''Leadmon.net Bulk Mailers List';
  833.     $filters['Leadmon Bulk Mailers']['link''http://www.leadmon.net/spamguard/';
  834.     $filters['Leadmon Bulk Mailers']['dns''spamguard.leadmon.net';
  835.     $filters['Leadmon Bulk Mailers']['result''127.0.0.4';
  836.     $filters['Leadmon Bulk Mailers']['comment'=
  837.         _("FREE - Leadmon Bulk Mailers - Bulk mailers that do not require confirmed opt-in or that have allowed known spammers to become clients and abuse their services.");
  838.  
  839.     $filters['Leadmon Open Relays']['prefname''filters_spam_lm_or';
  840.     $filters['Leadmon Open Relays']['name''Leadmon.net Open Relays List';
  841.     $filters['Leadmon Open Relays']['link''http://www.leadmon.net/spamguard/';
  842.     $filters['Leadmon Open Relays']['dns''spamguard.leadmon.net';
  843.     $filters['Leadmon Open Relays']['result''127.0.0.5';
  844.     $filters['Leadmon Open Relays']['comment'=
  845.         _("FREE - Leadmon Open Relays - Single Stage Open Relays that are not listed on other active RBLs.");
  846.  
  847.     $filters['Leadmon Multi-stage']['prefname''filters_spam_lm_ms';
  848.     $filters['Leadmon Multi-stage']['name''Leadmon.net Multi-Stage Relay List';
  849.     $filters['Leadmon Multi-stage']['link''http://www.leadmon.net/spamguard/';
  850.     $filters['Leadmon Multi-stage']['dns''spamguard.leadmon.net';
  851.     $filters['Leadmon Multi-stage']['result''127.0.0.6';
  852.     $filters['Leadmon Multi-stage']['comment'=
  853.         _("FREE - Leadmon Multi-stage - Multi-Stage Open Relays that are not listed on other active RBLs and that have sent SPAM to Leadmon.net.");
  854.  
  855.     $filters['Leadmon SpamBlock']['prefname''filters_spam_lm_sb';
  856.     $filters['Leadmon SpamBlock']['name''Leadmon.net SpamBlock Sites List';
  857.     $filters['Leadmon SpamBlock']['link''http://www.leadmon.net/spamguard/';
  858.     $filters['Leadmon SpamBlock']['dns''spamguard.leadmon.net';
  859.     $filters['Leadmon SpamBlock']['result''127.0.0.7';
  860.     $filters['Leadmon SpamBlock']['comment'=
  861.         _("FREE - Leadmon SpamBlock - Sites on this listing have sent Leadmon.net direct SPAM from IPs in netblocks where the entire block has no DNS mappings. It's a list of BLOCKS of IPs being used by people who have SPAMmed Leadmon.net.");
  862.  
  863.     $filters['NJABL Open Relays']['prefname''filters_spam_njabl_or';
  864.     $filters['NJABL Open Relays']['name''NJABL Open Relay/Direct Spam Source List';
  865.     $filters['NJABL Open Relays']['link''http://www.njabl.org/';
  866.     $filters['NJABL Open Relays']['dns''dnsbl.njabl.org';
  867.     $filters['NJABL Open Relays']['result''127.0.0.2';
  868.     $filters['NJABL Open Relays']['comment'=
  869.         _("FREE, for now - Not Just Another Blacklist - Both Open Relays and Direct SPAM Sources.");
  870.  
  871.     $filters['NJABL DUL']['prefname''filters_spam_njabl_dul';
  872.     $filters['NJABL DUL']['name''NJABL Dial-ups List';
  873.     $filters['NJABL DUL']['link''http://www.njabl.org/';
  874.     $filters['NJABL DUL']['dns''dnsbl.njabl.org';
  875.     $filters['NJABL DUL']['result''127.0.0.3';
  876.     $filters['NJABL DUL']['comment'=
  877.         _("FREE, for now - Not Just Another Blacklist - Dial-up IPs.");
  878.  
  879.     foreach ($filters as $Key => $Value{
  880.         $filters[$Key]['enabled'= (bool)getPref($data_dir$username$filters[$Key]['prefname']);
  881.     }
  882.  
  883.     return $filters;
  884. }
  885.  
  886. /**
  887.  * Removes a User filter
  888.  * @param int $id ID of the filter to remove
  889.  * @access private
  890.  */
  891. function remove_filter ($id{
  892.     global $data_dir$username;
  893.  
  894.     while ($nextFilter getPref($data_dir$username'filter' ($id 1))) {
  895.         setPref($data_dir$username'filter' $id$nextFilter);
  896.         $id ++;
  897.     }
  898.  
  899.     removePref($data_dir$username'filter' $id);
  900. }
  901.  
  902. /**
  903.  * Swaps two filters
  904.  * @param int $id1 ID of first filter to swap
  905.  * @param int $id2 ID of second filter to swap
  906.  * @access private
  907.  */
  908. function filter_swap($id1$id2{
  909.     global $data_dir$username;
  910.  
  911.     $FirstFilter getPref($data_dir$username'filter' $id1);
  912.     $SecondFilter getPref($data_dir$username'filter' $id2);
  913.  
  914.     if ($FirstFilter && $SecondFilter{
  915.         setPref($data_dir$username'filter' $id2$FirstFilter);
  916.         setPref($data_dir$username'filter' $id1$SecondFilter);
  917.     }
  918. }
  919.  
  920. /**
  921.  * This updates the filter rules when renaming or deleting folders
  922.  * @param array $args 
  923.  * @access private
  924.  */
  925. function update_for_folder ($args{
  926.     $old_folder $args[0];
  927.     $new_folder $args[2];
  928.     $action $args[1];
  929.     global $data_dir$username;
  930.     $filters array();
  931.     $filters load_filters();
  932.     $filter_count count($filters);
  933.     $p 0;
  934.     for ($i 0$i $filter_count$i++{
  935.         if (!empty($filters)) {
  936.             if ($old_folder == $filters[$i]['folder']{
  937.                 if ($action == 'rename'{
  938.                     $filters[$i]['folder'$new_folder;
  939.                     setPref($data_dir$username'filter'.$i,
  940.                     $filters[$i]['where'].','.$filters[$i]['what'].','.$new_folder);
  941.                 }
  942.                 elseif ($action == 'delete'{
  943.                     remove_filter($p);
  944.                     $p $p-1;
  945.                 }
  946.             }
  947.         $p++;
  948.         }
  949.     }
  950. }
  951.  
  952. /**
  953.  * Display formated error message
  954.  * @param string $string text message
  955.  * @return string html formated text message
  956.  * @access private
  957.  */
  958. function do_error($string{
  959.     global $color;
  960.     echo "<p align=\"center\"><font color=\"$color[2]\">";
  961.     echo $string;
  962.     echo "</font></p>\n";
  963. }

Documentation generated on Mon, 13 Jan 2020 04:22:30 +0100 by phpDocumentor 1.4.3