diff options
Diffstat (limited to 'plugins/markasjunk2/drivers')
-rw-r--r-- | plugins/markasjunk2/drivers/cmd_learn.php | 74 | ||||
-rw-r--r-- | plugins/markasjunk2/drivers/dir_learn.php | 49 | ||||
-rw-r--r-- | plugins/markasjunk2/drivers/edit_headers.php | 53 | ||||
-rw-r--r-- | plugins/markasjunk2/drivers/email_learn.php | 191 | ||||
-rw-r--r-- | plugins/markasjunk2/drivers/sa_blacklist.php | 103 | ||||
-rw-r--r-- | plugins/markasjunk2/drivers/sa_detach.php | 47 |
6 files changed, 517 insertions, 0 deletions
diff --git a/plugins/markasjunk2/drivers/cmd_learn.php b/plugins/markasjunk2/drivers/cmd_learn.php new file mode 100644 index 000000000..f27adc1d1 --- /dev/null +++ b/plugins/markasjunk2/drivers/cmd_learn.php @@ -0,0 +1,74 @@ +<?php + +/** + * Command line learn driver + * @version 2.0 + * @author Philip Weir + * Patched by Julien Vehent to support DSPAM + * Enhanced support for DSPAM by Stevan Bajic <stevan@bajic.ch> + */ + +class markasjunk2_cmd_learn +{ + public function spam($uids) + { + $this->_do_salearn($uids, true); + } + + public function ham($uids) + { + $this->_do_salearn($uids, false); + } + + private function _do_salearn($uids, $spam) + { + $rcmail = rcube::get_instance(); + $temp_dir = realpath($rcmail->config->get('temp_dir')); + + if ($spam) + $command = $rcmail->config->get('markasjunk2_spam_cmd'); + else + $command = $rcmail->config->get('markasjunk2_ham_cmd'); + + if (!$command) + return; + + $command = str_replace('%u', $_SESSION['username'], $command); + $command = str_replace('%l', $rcmail->user->get_username('local'), $command); + $command = str_replace('%d', $rcmail->user->get_username('domain'), $command); + if (preg_match('/%i/', $command)) { + $identity_arr = $rcmail->user->get_identity(); + $command = str_replace('%i', $identity_arr['email'], $command); + } + + foreach (explode(",", $uids) as $uid) { + // get DSPAM signature from header (if %xds macro is used) + if (preg_match('/%xds/', $command)) { + if (preg_match('/^X\-DSPAM\-Signature:\s+((\d+,)?([a-f\d]+))\s*$/im', $rcmail->storage->get_raw_headers($uid), $dspam_signature)) + $tmp_command = str_replace('%xds', $dspam_signature[1], $command); + else + continue; // no DSPAM signature found in headers -> continue with next uid/message + } + + if (preg_match('/%f/', $command)) { + $tmpfname = tempnam($temp_dir, 'rcmSALearn'); + file_put_contents($tmpfname, $rcmail->storage->get_raw_body($uid)); + $tmp_command = str_replace('%f', $tmpfname, $command); + } + + exec($tmp_command, $output); + + if ($rcmail->config->get('markasjunk2_debug')) { + rcube::write_log('markasjunk2', $tmp_command); + rcube::write_log('markasjunk2', $output); + } + + if (preg_match('/%f/', $command)) + unlink($tmpfname); + + $output = ''; + } + } +} + +?>
\ No newline at end of file diff --git a/plugins/markasjunk2/drivers/dir_learn.php b/plugins/markasjunk2/drivers/dir_learn.php new file mode 100644 index 000000000..88dc7e4eb --- /dev/null +++ b/plugins/markasjunk2/drivers/dir_learn.php @@ -0,0 +1,49 @@ +<?php + +/** + * Copy spam/ham messages to a direcotry for learning later + * @version 2.0 + * @author Philip Weir + */ + +class markasjunk2_dir_learn +{ + public function spam($uids) + { + $this->_do_messagemove($uids, true); + } + + public function ham($uids) + { + $this->_do_messagemove($uids, false); + } + + private function _do_messagemove($uids, $spam) + { + $rcmail = rcube::get_instance(); + + if ($spam) + $dest_dir = unslashify($rcmail->config->get('markasjunk2_spam_dir')); + else + $dest_dir = unslashify($rcmail->config->get('markasjunk2_ham_dir')); + + if (!$dest_dir) + return; + + $filename = $rcmail->config->get('markasjunk2_filename'); + $filename = str_replace('%u', $_SESSION['username'], $filename); + $filename = str_replace('%t', ($spam) ? 'spam' : 'ham', $filename); + $filename = str_replace('%l', $rcmail->user->get_username('local'), $filename); + $filename = str_replace('%d', $rcmail->user->get_username('domain'), $filename); + + foreach (explode(",", $uids) as $uid) { + $tmpfname = tempnam($dest_dir, $filename); + file_put_contents($tmpfname, $rcmail->storage->get_raw_body($uid)); + + if ($rcmail->config->get('markasjunk2_debug')) + rcube::write_log('markasjunk2', $tmpfname); + } + } +} + +?>
\ No newline at end of file diff --git a/plugins/markasjunk2/drivers/edit_headers.php b/plugins/markasjunk2/drivers/edit_headers.php new file mode 100644 index 000000000..9ee71ff79 --- /dev/null +++ b/plugins/markasjunk2/drivers/edit_headers.php @@ -0,0 +1,53 @@ +<?php + +/** + * Edit headers + * @version 1.0 + * @author Philip Weir + */ + +class markasjunk2_edit_headers +{ + public function spam(&$uids) + { + $this->_edit_headers($uids, true); + } + + public function ham(&$uids) + { + $this->_edit_headers($uids, false); + } + + private function _edit_headers(&$uids, $spam) + { + $rcmail = rcube::get_instance(); + $args = $spam ? $rcmail->config->get('markasjunk2_spam_patterns') : $rcmail->config->get('markasjunk2_ham_patterns'); + + if (sizeof($args['patterns']) == 0) + return; + + $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST); + + $new_uids = array(); + foreach (explode(",", $uids) as $uid) { + $raw_message = $rcmail->storage->get_raw_body($uid); + $raw_headers = $rcmail->storage->get_raw_headers($uid); + + $updated_headers = preg_replace($args['patterns'], $args['replacements'], $raw_headers); + $raw_message = str_replace($raw_headers, $updated_headers, $raw_message); + + $saved = $rcmail->storage->save_message($mbox, $raw_message); + + if ($saved !== false) { + $rcmail->output->command('rcmail_markasjunk2_move', null, $uid); + array_push($new_uids, $saved); + } + + } + + if (sizeof($new_uids) > 0) + $uids = implode(',', $new_uids); + } +} + +?>
\ No newline at end of file diff --git a/plugins/markasjunk2/drivers/email_learn.php b/plugins/markasjunk2/drivers/email_learn.php new file mode 100644 index 000000000..b7f9f87ea --- /dev/null +++ b/plugins/markasjunk2/drivers/email_learn.php @@ -0,0 +1,191 @@ +<?php + +/** + * Email learn driver + * @version 2.0 + * @author Philip Weir + */ + +class markasjunk2_email_learn +{ + public function spam($uids) + { + $this->_do_emaillearn($uids, true); + } + + public function ham($uids) + { + $this->_do_emaillearn($uids, false); + } + + private function _do_emaillearn($uids, $spam) + { + $rcmail = rcube::get_instance(); + $identity_arr = $rcmail->user->get_identity(); + $from = $identity_arr['email']; + + if ($spam) + $mailto = $rcmail->config->get('markasjunk2_email_spam'); + else + $mailto = $rcmail->config->get('markasjunk2_email_ham'); + + $mailto = str_replace('%u', $_SESSION['username'], $mailto); + $mailto = str_replace('%l', $rcmail->user->get_username('local'), $mailto); + $mailto = str_replace('%d', $rcmail->user->get_username('domain'), $mailto); + $mailto = str_replace('%i', $from, $mailto); + + if (!$mailto) + return; + + $message_charset = $rcmail->output->get_charset(); + // chose transfer encoding + $charset_7bit = array('ASCII', 'ISO-2022-JP', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-15'); + $transfer_encoding = in_array(strtoupper($message_charset), $charset_7bit) ? '7bit' : '8bit'; + + $temp_dir = realpath($rcmail->config->get('temp_dir')); + + $subject = $rcmail->config->get('markasjunk2_email_subject'); + $subject = str_replace('%u', $_SESSION['username'], $subject); + $subject = str_replace('%t', ($spam) ? 'spam' : 'ham', $subject); + $subject = str_replace('%l', $rcmail->user->get_username('local'), $subject); + $subject = str_replace('%d', $rcmail->user->get_username('domain'), $subject); + + // compose headers array + $headers = array(); + $headers['Date'] = date('r'); + $headers['From'] = format_email_recipient($identity_arr['email'], $identity_arr['name']); + $headers['To'] = $mailto; + $headers['Subject'] = $subject; + + foreach (explode(",", $uids) as $uid) { + $MESSAGE = new rcube_message($uid); + + // set message charset as default + if (!empty($MESSAGE->headers->charset)) + $rcmail->storage->set_charset($MESSAGE->headers->charset); + + $MAIL_MIME = new Mail_mime($rcmail->config->header_delimiter()); + + if ($rcmail->config->get('markasjunk2_email_attach', false)) { + $tmpPath = tempnam($temp_dir, 'rcmMarkASJunk2'); + + // send mail as attachment + $MAIL_MIME->setTXTBody(($spam ? 'Spam' : 'Ham'). ' report from ' . $rcmail->config->get('product_name'), false, true); + + $raw_message = $rcmail->storage->get_raw_body($uid); + $subject = $MESSAGE->get_header('subject'); + + if (isset($subject) && $subject !="") + $disp_name = $subject . ".eml"; + else + $disp_name = "message_rfc822.eml"; + + if (file_put_contents($tmpPath, $raw_message)) { + $MAIL_MIME->addAttachment($tmpPath, "message/rfc822", $disp_name, true, + $transfer_encoding, 'attachment', '', '', '', + $rcmail->config->get('mime_param_folding') ? 'quoted-printable' : NULL, + $rcmail->config->get('mime_param_folding') == 2 ? 'quoted-printable' : NULL, + '', RCUBE_CHARSET + ); + } + + // encoding settings for mail composing + $MAIL_MIME->setParam('text_encoding', $transfer_encoding); + $MAIL_MIME->setParam('html_encoding', 'quoted-printable'); + $MAIL_MIME->setParam('head_encoding', 'quoted-printable'); + $MAIL_MIME->setParam('head_charset', $message_charset); + $MAIL_MIME->setParam('html_charset', $message_charset); + $MAIL_MIME->setParam('text_charset', $message_charset); + + // pass headers to message object + $MAIL_MIME->headers($headers); + } + else { + $headers['Resent-From'] = $headers['From']; + $headers['Resent-Date'] = $headers['Date']; + $headers['Date'] = $MESSAGE->headers->date; + $headers['From'] = $MESSAGE->headers->from; + $headers['Subject'] = $MESSAGE->headers->subject; + $MAIL_MIME->headers($headers); + + if ($MESSAGE->has_html_part()) { + $body = $MESSAGE->first_html_part(); + $MAIL_MIME->setHTMLBody($body); + } + + $body = $MESSAGE->first_text_part(); + $MAIL_MIME->setTXTBody($body, false, true); + + foreach ($MESSAGE->attachments as $attachment) { + $MAIL_MIME->addAttachment( + $MESSAGE->get_part_content($attachment->mime_id), + $attachment->mimetype, + $attachment->filename, + false, + $attachment->encoding, + $attachment->disposition, + '', $attachment->charset + ); + } + + foreach ($MESSAGE->mime_parts as $attachment) { + if (!empty($attachment->content_id)) { + // covert CID to Mail_MIME format + $attachment->content_id = str_replace('<', '', $attachment->content_id); + $attachment->content_id = str_replace('>', '', $attachment->content_id); + + if (empty($attachment->filename)) + $attachment->filename = $attachment->content_id; + + $message_body = $MAIL_MIME->getHTMLBody(); + $dispurl = 'cid:' . $attachment->content_id; + $message_body = str_replace($dispurl, $attachment->filename, $message_body); + $MAIL_MIME->setHTMLBody($message_body); + + $MAIL_MIME->addHTMLImage( + $MESSAGE->get_part_content($attachment->mime_id), + $attachment->mimetype, + $attachment->filename, + false + ); + } + } + + // encoding settings for mail composing + $MAIL_MIME->setParam('head_encoding', $MESSAGE->headers->encoding); + $MAIL_MIME->setParam('head_charset', $MESSAGE->headers->charset); + + foreach ($MESSAGE->mime_parts as $mime_id => $part) { + $mimetype = strtolower($part->ctype_primary . '/' . $part->ctype_secondary); + + if ($mimetype == 'text/html') { + $MAIL_MIME->setParam('text_encoding', $part->encoding); + $MAIL_MIME->setParam('html_charset', $part->charset); + } + else if ($mimetype == 'text/plain') { + $MAIL_MIME->setParam('html_encoding', $part->encoding); + $MAIL_MIME->setParam('text_charset', $part->charset); + } + } + } + + $rcmail->rcmail_deliver_message($MAIL_MIME, $from, $mailto, $smtp_error, $body_file); + + // clean up + if (file_exists($tmpPath)) + unlink($tmpPath); + + if ($rcmail->config->get('markasjunk2_debug')) { + if ($spam) + rcube::write_log('markasjunk2', $uid . ' SPAM ' . $mailto . ' (' . $subject . ')'); + else + rcube::write_log('markasjunk2', $uid . ' HAM ' . $mailto . ' (' . $subject . ')'); + + if ($smtp_error['vars']) + rcube::write_log('markasjunk2', $smtp_error['vars']); + } + } + } +} + +?>
\ No newline at end of file diff --git a/plugins/markasjunk2/drivers/sa_blacklist.php b/plugins/markasjunk2/drivers/sa_blacklist.php new file mode 100644 index 000000000..dd2ce6bc7 --- /dev/null +++ b/plugins/markasjunk2/drivers/sa_blacklist.php @@ -0,0 +1,103 @@ +<?php + +/** + * SpamAssassin Blacklist driver + * @version 2.0 + * @requires SAUserPrefs plugin + * @author Philip Weir + */ + +class markasjunk2_sa_blacklist +{ + public function spam($uids) + { + $this->_do_list($uids, true); + } + + public function ham($uids) + { + $this->_do_list($uids, false); + } + + private function _do_list($uids, $spam) + { + $rcmail = rcube::get_instance(); + if (is_file($rcmail->config->get('markasjunk2_sauserprefs_config')) && !$rcmail->config->load_from_file($rcmail->config->get('markasjunk2_sauserprefs_config'))) { + rcube::raise_error(array('code' => 527, 'type' => 'php', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Failed to load config from " . $rcmail->config->get('markasjunk2_sauserprefs_config')), true, false); + return false; + } + + $db = rcube_db::factory($rcmail->config->get('sauserprefs_db_dsnw'), $rcmail->config->get('sauserprefs_db_dsnr'), $rcmail->config->get('sauserprefs_db_persistent')); + $db->db_connect('w'); + + // check DB connections and exit on failure + if ($err_str = $db->is_error()) { + rcube::raise_error(array( + 'code' => 603, + 'type' => 'db', + 'message' => $err_str), FALSE, TRUE); + } + + foreach (explode(",", $uids) as $uid) { + $message = new rcube_message($uid); + $email = $message->sender['mailto']; + + if ($spam) { + // delete any whitelisting for this address + $db->query( + "DELETE FROM ". $rcmail->config->get('sauserprefs_sql_table_name') ." WHERE ". $rcmail->config->get('sauserprefs_sql_username_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_preference_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_value_field') ." = ?;", + $_SESSION['username'], + 'whitelist_from', + $email); + + // check address is not already blacklisted + $sql_result = $db->query( + "SELECT value FROM ". $rcmail->config->get('sauserprefs_sql_table_name') ." WHERE ". $rcmail->config->get('sauserprefs_sql_username_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_preference_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_value_field') ." = ?;", + $_SESSION['username'], + 'blacklist_from', + $email); + + if (!$db->fetch_array($sql_result)) { + $db->query( + "INSERT INTO ". $rcmail->config->get('sauserprefs_sql_table_name') ." (". $rcmail->config->get('sauserprefs_sql_username_field') .", ". $rcmail->config->get('sauserprefs_sql_preference_field') .", ". $rcmail->config->get('sauserprefs_sql_value_field') .") VALUES (?, ?, ?);", + $_SESSION['username'], + 'blacklist_from', + $email); + + if ($rcmail->config->get('markasjunk2_debug')) + rcube::write_log('markasjunk2', $_SESSION['username'] . ' blacklist ' . $email); + } + } + else { + // delete any blacklisting for this address + $db->query( + "DELETE FROM ". $rcmail->config->get('sauserprefs_sql_table_name') ." WHERE ". $rcmail->config->get('sauserprefs_sql_username_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_preference_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_value_field') ." = ?;", + $_SESSION['username'], + 'blacklist_from', + $email); + + // check address is not already whitelisted + $sql_result = $db->query( + "SELECT value FROM ". $rcmail->config->get('sauserprefs_sql_table_name') ." WHERE ". $rcmail->config->get('sauserprefs_sql_username_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_preference_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_value_field') ." = ?;", + $_SESSION['username'], + 'whitelist_from', + $email); + + if (!$db->fetch_array($sql_result)) { + $db->query( + "INSERT INTO ". $rcmail->config->get('sauserprefs_sql_table_name') ." (". $rcmail->config->get('sauserprefs_sql_username_field') .", ". $rcmail->config->get('sauserprefs_sql_preference_field') .", ". $rcmail->config->get('sauserprefs_sql_value_field') .") VALUES (?, ?, ?);", + $_SESSION['username'], + 'whitelist_from', + $email); + + if ($rcmail->config->get('markasjunk2_debug')) + rcube::write_log('markasjunk2', $_SESSION['username'] . ' whitelist ' . $email); + } + } + } + } +} + +?>
\ No newline at end of file diff --git a/plugins/markasjunk2/drivers/sa_detach.php b/plugins/markasjunk2/drivers/sa_detach.php new file mode 100644 index 000000000..947b4b8a7 --- /dev/null +++ b/plugins/markasjunk2/drivers/sa_detach.php @@ -0,0 +1,47 @@ +<?php + +/** + * SpamAssassin detach ham driver + * @version 2.0 + * @author Philip Weir + */ + +class markasjunk2_sa_detach +{ + public function spam($uids) + { + // do nothing + } + + public function ham(&$uids) + { + $rcmail = rcube::get_instance(); + $storage = $rcmail->storage; + $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST); + + $new_uids = array(); + foreach (explode(",", $uids) as $uid) { + $saved = false; + $message = new rcube_message($uid); + + if (sizeof($message->attachments) > 0) { + foreach ($message->attachments as $part) { + if ($part->ctype_primary == 'message' && $part->ctype_secondary == 'rfc822') { + $orig_message_raw = $storage->get_message_part($message->uid, $part->mime_id, $part); + $saved = $storage->save_message($mbox, $orig_message_raw); + + if ($saved !== false) { + $rcmail->output->command('rcmail_markasjunk2_move', null, $uid); + array_push($new_uids, $saved); + } + } + } + } + } + + if (sizeof($new_uids) > 0) + $uids = implode(',', $new_uids); + } +} + +?>
\ No newline at end of file |