X-Git-Url: https://vcs.fsf.org/?p=squirrelmail.git;a=blobdiff_plain;f=plugins%2Ffilters%2Ffilters.php;h=b73e69f66191cda85ed4a3de4e5d297ee70cbbbb;hp=b41302fa60a1bec498143aff96c119006f748933;hb=16dd8736f68b753f06df30ff39892ef18579e2ce;hpb=4b4abf93a9624311afef0c385023724ee46a2b60 diff --git a/plugins/filters/filters.php b/plugins/filters/filters.php index b41302fa..b73e69f6 100644 --- a/plugins/filters/filters.php +++ b/plugins/filters/filters.php @@ -3,22 +3,33 @@ /** * Message and Spam Filter Plugin - Filtering Functions * - * @copyright © 1999-2005 The SquirrelMail Project Team + * @copyright 1999-2012 The SquirrelMail Project Team * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @version $Id$ * @package plugins * @subpackage filters */ -/** @ignore */ -if (! defined('SM_PATH')) define('SM_PATH','../../'); +/** + * do not allow to call this file directly + */ +if (isset($_SERVER['SCRIPT_FILENAME']) && $_SERVER['SCRIPT_FILENAME'] == __FILE__) { + header("Location: ../../src/login.php"); + die(); +} /** load globals */ -global $UseSeparateImapConnection, - $AllowSpamFilters, $SpamFilters_YourHop, $SpamFilters_ShowCommercial, - $SpamFilters_DNScache, $SpamFilters_BulkQuery, $SpamFilters_SharedCache, +global $UseSeparateImapConnection, + $AllowSpamFilters, $SpamFilters_YourHop, $SpamFilters_ShowCommercial, + $SpamFilters_DNScache, $SpamFilters_BulkQuery, $SpamFilters_SharedCache, $SpamFilters_CacheTTL; +/** + * load required functions. Plugin depends on IMAP functions and they are not + * loaded in src/webmail.php + */ +include_once (SM_PATH . 'functions/imap.php'); + /** load default config */ if (file_exists(SM_PATH . 'plugins/filters/config_default.php')) { include_once (SM_PATH . 'plugins/filters/config_default.php'); @@ -40,27 +51,6 @@ if (file_exists(SM_PATH . 'config/filters_config.php')) { include_once (SM_PATH . 'plugins/filters/config.php'); } -/** - * Init Hooks - * @access private - */ -function filters_init_hooks () { - global $squirrelmail_plugin_hooks; - - if (! sqgetGlobalVar('mailbox',$mailbox,SQ_FORM)) { - $mailbox = 'INBOX'; - } - - $squirrelmail_plugin_hooks['left_main_before']['filters'] = 'start_filters_hook'; - if (isset($mailbox) && $mailbox == 'INBOX') { - $squirrelmail_plugin_hooks['right_main_after_header']['filters'] = 'start_filters_hook'; - } - $squirrelmail_plugin_hooks['optpage_register_block']['filters'] = 'filters_optpage_register_block_hook'; - $squirrelmail_plugin_hooks['special_mailbox']['filters'] = 'filters_special_mailbox'; - $squirrelmail_plugin_hooks['rename_or_delete_folder']['filters'] = 'update_for_folder_hook'; - $squirrelmail_plugin_hooks['webmail_bottom']['filters'] = 'start_filters_hook'; -} - /** * Register option blocks * @access private @@ -85,6 +75,18 @@ function filters_optpage_register_block() { } } +/* Receive the status of the folder and do something with it */ +function filters_folder_status($statusarr) { + + global $filter_inbox_count; + if (empty($filter_inbox_count)) $filter_inbox_count=0; + + if ($statusarr['MAILBOX'] == 'INBOX') + { + if (!empty($statusarr['MESSAGES'])) $filter_inbox_count=$statusarr['MESSAGES']; + } +} + /** * Saves the DNS Cache to disk * @access private @@ -140,7 +142,7 @@ function filters_LoadCache () { /** * Uses the BulkQuery executable to query all the RBLs at once - * @param array $filters Array of SPAM Fitlers + * @param array $filters Array of SPAM Filters * @param array $IPs Array of IP Addresses * @access private */ @@ -183,20 +185,50 @@ function filters_bulkquery($filters, $IPs) { /** * Starts the filtering process + * @param array $hook_args (since 1.5.2) do hook arguments. Is used to check + * hook name, array key = 0. * @access private */ -function start_filters() { +function start_filters($hook_args) { global $imapServerAddress, $imapPort, $imap_stream, $imapConnection, - $UseSeparateImapConnection, $AllowSpamFilters; + $UseSeparateImapConnection, $AllowSpamFilters, $filter_inbox_count, + $username; + + /** + * check hook that calls filtering. If filters are called by right_main_after_header, + * do filtering only when we are in INBOX folder. + */ + if ($hook_args[0]=='right_main_after_header' && + (sqgetGlobalVar('mailbox',$mailbox,SQ_FORM) && $mailbox!='INBOX')) { + return; + } + + $filters = load_filters(); + + // No point running spam filters if there aren't any to run // + if ($AllowSpamFilters) { + $spamfilters = load_spam_filters(); + + $AllowSpamFilters = false; + foreach($spamfilters as $value) { + if ($value['enabled'] == SMPREF_ON) { + $AllowSpamFilters = true; + break; + } + } + } + + // No user filters, and no spam filters, no need to continue // + if (!$AllowSpamFilters && empty($filters)) { + return; + } - sqgetGlobalVar('username', $username, SQ_SESSION); - sqgetGlobalVar('key', $key, SQ_COOKIE); // Detect if we have already connected to IMAP or not. // Also check if we are forced to use a separate IMAP connection if ((!isset($imap_stream) && !isset($imapConnection)) || $UseSeparateImapConnection ) { - $stream = sqimap_login($username, $key, $imapServerAddress, + $stream = sqimap_login($username, false, $imapServerAddress, $imapPort, 10); $previously_connected = false; } else if (isset($imapConnection)) { @@ -206,9 +238,17 @@ function start_filters() { $previously_connected = true; $stream = $imap_stream; } - $aStatus = sqimap_status_messages ($stream, 'INBOX', array('MESSAGES')); - if ($aStatus['MESSAGES']) { + if (!isset($filter_inbox_count)) { + $aStatus = sqimap_status_messages ($stream, 'INBOX', array('MESSAGES')); + if (!empty($aStatus['MESSAGES'])) { + $filter_inbox_count=$aStatus['MESSAGES']; + } else { + $filter_inbox_count=0; + } + } + + if ($filter_inbox_count > 0) { sqimap_mailbox_select($stream, 'INBOX'); // Filter spam from inbox before we sort them into folders if ($AllowSpamFilters) { @@ -272,18 +312,20 @@ function user_filters($imap_stream) { /** * Creates and runs the IMAP command to filter messages + * @param string $imap_stream TODO: Document this parameter * @param string $where Which part of the message to search (TO, CC, SUBJECT, etc...) * @param string $what String to search for * @param string $where_to Folder it will move to * @param string $user_scan Whether to search all or just unseen * @param string $should_expunge - * @param boolean $where Which part of location to search * @access private */ function filter_search_and_delete($imap_stream, $where, $what, $where_to, $user_scan, $should_expunge) { global $languages, $squirrelmail_language, $allow_charset_search, $imap_server_type; + //TODO: make use of new mailbox cache. See mailbox_display.phpinfo + if (strtolower($where_to) == 'inbox') { return array(); } @@ -306,6 +348,7 @@ function filter_search_and_delete($imap_stream, $where, $what, $where_to, $user_ } if ($where == 'Header') { $what = explode(':', $what); + $where = strtoupper($where); $where = trim($where . ' ' . $what[0]); $what = addslashes(trim($what[1])); } @@ -313,19 +356,33 @@ function filter_search_and_delete($imap_stream, $where, $what, $where_to, $user_ // see comments in squirrelmail sqimap_search function if ($imap_server_type == 'macosx' || $imap_server_type == 'hmailserver') { $search_str .= ' ' . $where . ' ' . $what; + /* read data back from IMAP */ + $read = sqimap_run_command($imap_stream, $search_str, true, $response, $message, TRUE); } else { - $search_str .= ' ' . $where . ' {' . strlen($what) . "}\r\n" - . $what . "\r\n"; + $search_str .= ' ' . $where . ' {' . strlen($what) . "}"; + $sid = sqimap_session_id(true); + fputs ($imap_stream, $sid . ' ' . $search_str . "\r\n"); + $read2 = sqimap_fgets($imap_stream); + # server should respond with Ready for argument, then we will send search text + #echo "RR2 $read2
"; + fputs ($imap_stream, "$what\r\n"); + #echo "SS $what
"; + $read2 = sqimap_fgets($imap_stream); + #echo "RR2 $read2
"; + $read[]=$read2; + $read3 = sqimap_fgets($imap_stream); + #echo "RR3 $read3
"; + list($rtag,$response,$message)=explode(' ',$read3,3); +## $read2 = sqimap_retrieve_imap_response($imap_stream, $sid, true, +## $response, $message, $search_str, false, true, false); + #echo "RR2 $read2 / RESPONSE $response
"; } - /* read data back from IMAP */ - $read = sqimap_run_command($imap_stream, $search_str, true, $response, $message, TRUE); if (isset($read[0])) { $ids = array(); for ($i = 0, $iCnt = count($read); $i < $iCnt; ++$i) { if (preg_match("/^\* SEARCH (.+)$/", $read[$i], $regs)) { - $ids = preg_split("/ /", trim($regs[1])); - break; + $ids += explode(' ', trim($regs[1])); } } if ($response == 'OK' && count($ids)) { @@ -333,6 +390,18 @@ function filter_search_and_delete($imap_stream, $where, $what, $where_to, $user_ $should_expunge = true; sqimap_msgs_list_move ($imap_stream, $ids, $where_to, false); } + } elseif ($response != 'OK') { + $query = $search_str . "\r\n".$what ."\r\n"; + if ($response == 'NO') { + if (strpos($message,'BADCHARSET') !== false || + strpos($message,'character') !== false) { + sqm_trigger_imap_error('SQM_IMAP_BADCHARSET',$query, $response, $message); + } else { + sqm_trigger_imap_error('SQM_IMAP_ERROR',$query, $response, $message); + } + } else { + sqm_trigger_imap_error('SQM_IMAP_ERROR',$query, $response, $message); + } } } return $should_expunge; @@ -361,7 +430,7 @@ function spam_filters($imap_stream) { $run = false; - foreach ($filters as $Key => $Value) { + foreach ($filters as $Value) { if ($Value['enabled']) { $run = true; break; @@ -382,8 +451,8 @@ function spam_filters($imap_stream) { if (isset($read[0])) { for ($i = 0, $iCnt = count($read); $i < $iCnt; ++$i) { if (preg_match("/^\* SEARCH (.+)$/", $read[$i], $regs)) { - $search_array = preg_split("/ /", trim($regs[1])); - break; + $search_array = explode(' ', trim($regs[1])); + break; } } } @@ -424,14 +493,15 @@ function spam_filters($imap_stream) { $aSpamIds[] = $MsgNum; $isspam = true; } + if ($bulkquery) { array_shift($aMatch); - $IP = explode('.',$aMatch); + $IP = explode('.', $aMatch); 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; + $IPs[$IP] = true; + break; } } } @@ -448,7 +518,7 @@ function spam_filters($imap_stream) { } // Lookie! It's spam! Yum! if (count($aSpamIds) && sqimap_mailbox_exists($imap_stream, $filters_spam_folder)) { - sqimap_msgs_list_move ($imap_stream, $aSpamIds, $filters_spam_folder); + sqimap_msgs_list_move($imap_stream, $aSpamIds, $filters_spam_folder); sqimap_mailbox_expunge($imap_stream, 'INBOX'); } @@ -479,8 +549,14 @@ function filters_spam_check_site($a, $b, $c, $d, &$filters) { foreach ($filters as $key => $value) { if ($filters[$key]['enabled']) { if ($filters[$key]['dns']) { + + /** + * RFC allows . on end of hostname to force domain lookup to + * not use search domain from resolv.conf, i.e. to ensure + * search domain isn't used if no hostname is found + */ $filter_revip = $d . '.' . $c . '.' . $b . '.' . $a . '.' . - $filters[$key]['dns']; + $filters[$key]['dns'] . '.'; if(!isset($SpamFilters_DNScache[$filter_revip]['L'])) $SpamFilters_DNScache[$filter_revip]['L'] = ''; @@ -494,8 +570,12 @@ function filters_spam_check_site($a, $b, $c, $d, &$filters) { $SpamFilters_DNScache[$filter_revip]['T'] = time() + $SpamFilters_CacheTTL; } - if ($SpamFilters_DNScache[$filter_revip]['L'] == - $filters[$key]['result']) { + + /** + * gethostbyname returns ip if resolved, or returns original + * host supplied to function if there is no resolution + */ + if ($SpamFilters_DNScache[$filter_revip]['L'] != $filter_revip) { return 1; } } @@ -516,7 +596,7 @@ function load_filters() { for ($i = 0; $fltr = getPref($data_dir, $username, 'filter' . $i); $i++) { $ary = explode(',', $fltr); $filters[$i]['where'] = $ary[0]; - $filters[$i]['what'] = $ary[1]; + $filters[$i]['what'] = str_replace('###COMMA###', ',', $ary[1]); $filters[$i]['folder'] = $ary[2]; } return $filters; @@ -580,14 +660,6 @@ function load_spam_filters() { _("COMMERCIAL - RBL+ Dial-up entries."); } - $filters['ORDB']['prefname'] = 'filters_spam_ordb'; - $filters['ORDB']['name'] = 'Open Relay Database List'; - $filters['ORDB']['link'] = 'http://www.ordb.org/'; - $filters['ORDB']['dns'] = 'relays.ordb.org'; - $filters['ORDB']['result'] = '127.0.0.2'; - $filters['ORDB']['comment'] = - _("FREE - ORDB was born when ORBS went off the air. It seems to have fewer false positives than ORBS did though."); - $filters['FiveTen Direct']['prefname'] = 'filters_spam_fiveten_src'; $filters['FiveTen Direct']['name'] = 'Five-Ten-sg.com Direct SPAM Sources'; $filters['FiveTen Direct']['link'] = 'http://www.five-ten-sg.com/blackhole.php'; @@ -656,7 +728,7 @@ function load_spam_filters() { $filters['SPAMhaus']['name'] = 'SPAMhaus Lists'; $filters['SPAMhaus']['link'] = 'http://www.spamhaus.org'; $filters['SPAMhaus']['dns'] = 'sbl.spamhaus.org'; - $filters['SPAMhaus']['result'] = '127.0.0.6'; + $filters['SPAMhaus']['result'] = '127.0.0.2'; $filters['SPAMhaus']['comment'] = _("FREE - SPAMhaus - A list of well-known SPAM sources."); @@ -772,32 +844,8 @@ function load_spam_filters() { $filters['NJABL DUL']['comment'] = _("FREE, for now - Not Just Another Blacklist - Dial-up IPs."); - $filters['Conf DSBL.ORG Relay']['prefname'] = 'filters_spam_dsbl_conf_ss'; - $filters['Conf DSBL.ORG Relay']['name'] = 'DSBL.org Confirmed Relay List'; - $filters['Conf DSBL.ORG Relay']['link'] = 'http://www.dsbl.org/'; - $filters['Conf DSBL.ORG Relay']['dns'] = 'list.dsbl.org'; - $filters['Conf DSBL.ORG Relay']['result'] = '127.0.0.2'; - $filters['Conf DSBL.ORG Relay']['comment'] = - _("FREE - Distributed Sender Boycott List - Confirmed Relays"); - - $filters['Conf DSBL.ORG Multi-Stage']['prefname'] = 'filters_spam_dsbl_conf_ms'; - $filters['Conf DSBL.ORG Multi-Stage']['name'] = 'DSBL.org Confirmed Multi-Stage Relay List'; - $filters['Conf DSBL.ORG Multi-Stage']['link'] = 'http://www.dsbl.org/'; - $filters['Conf DSBL.ORG Multi-Stage']['dns'] = 'multihop.dsbl.org'; - $filters['Conf DSBL.ORG Multi-Stage']['result'] = '127.0.0.2'; - $filters['Conf DSBL.ORG Multi-Stage']['comment'] = - _("FREE - Distributed Sender Boycott List - Confirmed Multi-stage Relays"); - - $filters['UN-Conf DSBL.ORG']['prefname'] = 'filters_spam_dsbl_unc'; - $filters['UN-Conf DSBL.ORG']['name'] = 'DSBL.org UN-Confirmed Relay List'; - $filters['UN-Conf DSBL.ORG']['link'] = 'http://www.dsbl.org/'; - $filters['UN-Conf DSBL.ORG']['dns'] = 'unconfirmed.dsbl.org'; - $filters['UN-Conf DSBL.ORG']['result'] = '127.0.0.2'; - $filters['UN-Conf DSBL.ORG']['comment'] = - _("FREE - Distributed Sender Boycott List - UN-Confirmed Relays"); - foreach ($filters as $Key => $Value) { - $filters[$Key]['enabled'] = getPref($data_dir, $username, $filters[$Key]['prefname']); + $filters[$Key]['enabled'] = (bool)getPref($data_dir, $username, $filters[$Key]['prefname']); } return $filters; @@ -843,7 +891,6 @@ function filter_swap($id1, $id2) { * @access private */ function update_for_folder ($args) { - $old_folder = $args[0]; $new_folder = $args[2]; $action = $args[1]; @@ -882,5 +929,3 @@ function do_error($string) { echo $string; echo "

\n"; } - -?> \ No newline at end of file