Skip to content

Commit

Permalink
added cmd_learn command to sa_blacklist driver
Browse files Browse the repository at this point in the history
  • Loading branch information
mbhangui committed Aug 13, 2023
1 parent cba7dbc commit 16bc393
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 11 deletions.
2 changes: 2 additions & 0 deletions ircube-x/doc/ChangeLog
Expand Up @@ -29,6 +29,8 @@ Release 1.0.0-1.1 Start 13/09/2022 End 20/04/2023
13. updated markasjunk2, sauserprefs plugins to latest from github
25/07/2023
14. updated for rockylinux, oraclelinux
13/08/2023
15. markasjunk2: added cmd_learn command to sa_blacklist

* Thu 08 Sep 2022 14:38:16 +0000 Manvendra Bhangui <ircube@indimail.org> 1.0.0-1.1%{?dist}
Release @version@-@release@ Start 13/03/2017 End 08/09/2022
Expand Down
16 changes: 8 additions & 8 deletions ircube-x/plugins/markasjunk2/README.md
Expand Up @@ -60,8 +60,8 @@ All config parameters are optional
The Learning Driver
-------------------
The learning driver allows you to perform additional processing on each message
marked as spam/ham. A driver must contain a class named markasjunk2_{driver
file name}. The class must contain 3 functions:
marked as spam/ham. A driver must contain a class named
markasjunk2\_{driver file name}. The class must contain 3 functions:

**spam:** This function should take 2 arguments: an array of UIDs of message(s)
being marked as spam, the name of the mailbox containing those messages
Expand Down Expand Up @@ -96,7 +96,7 @@ email attached then this is detached and saved in the Inbox, the spam report is
deleted

**edit_headers:** Edit the message headers. Headers are edited using
preg_replace.
preg\_replace.

**WARNING:** Be sure to match the entire header line, including the name of the
header, and include the ^ and $ and test carefully before use on real messages.
Expand All @@ -109,8 +109,8 @@ drivers at your own risk! It may be safer to create one driver that does
everything you want.

It is possible to run multiple drivers when marking a message as spam/ham. For
example running sa_blacklist followed by cmd_learn or edit_headers and
cmd_learn. An [example multi-driver][multidriver] is available. This is a
example running sa\_blacklist followed by cmd\_learn or edit\_headers and
cmd\_learn. An [example multi-driver][multidriver] is available. This is a
starting point only, it requires modification for individual cases.

Spam learning commands
Expand All @@ -127,19 +127,19 @@ Spamassassin:
```sa-learn --ham --username=%u %f``` or
```sa-learn --ham --prefs-file=/var/mail/%d/%l/.spamassassin/user_prefs %f```

edit_headers example config
edit\_headers example config
---------------------------
**WARNING:** These are simple examples of how to configure the driver options,
use at your own risk

```php
```
$config['markasjunk2_spam_patterns'] = array(
'patterns' => array('/^(Subject:\s*)(.*)$/m'),
'replacements' => array('$1[SPAM] $2')
);
```

```php
```
$config['markasjunk2_ham_patterns'] = array(
'patterns' => array('/^(Subject:\s*)\[SPAM\](.*)$/m'),
'replacements' => array('$1$2')
Expand Down
11 changes: 8 additions & 3 deletions ircube-x/plugins/markasjunk2/config.inc.php
Expand Up @@ -5,7 +5,8 @@
*/

// Learning driver
// Use an external process such as sa-learn to learn from spam/ham messages. Default: null.
// Use an external process such as sa_learn, sa_blacklist to learn from spam/ham messages. Default: null.
// sa_blacklist also runs the cmd_learn driver
// Please see the README for more information
$config['markasjunk2_learning_driver'] = 'sa_blacklist';

Expand All @@ -32,7 +33,8 @@

// Add flag to messages marked as ham (flag will be removed when marking as spam)
// If you do not want to use message flags set this to false
$config['markasjunk2_ham_flag'] = 'NonJunk';
// $config['markasjunk2_ham_flag'] = 'NonJunk';
$config['markasjunk2_ham_flag'] = false;

// Write output from spam/ham commands to the log for debug
$config['markasjunk2_debug'] = false;
Expand All @@ -52,7 +54,8 @@
$config['markasjunk2_move_ham'] = false;

// Some drivers create new copies of the target message(s), in this case the original message(s) will be deleted
// Rather than deleting the message(s) (moving to Trash) setting this option true will cause the original message(s) to be permanently removed
// Rather than deleting the message(s) (moving to Trash) setting this option true will cause the original message(s)
// to be permanently removed
$config['markasjunk2_permanently_remove'] = false;

// Display only a mark as spam button
Expand Down Expand Up @@ -80,6 +83,7 @@
// %s is replaced with the email address the message is from
// %f is replaced with the path to the message file
// %h:<header name> is replaced with the content of that header from the message (lower case) eg: %h:x-dspam-signature
// %m is replaced with the mysql connect string
// If you do not want to run the command set this to null
$config['markasjunk2_spam_cmd'] = '/usr/libexec/indimail/bogo-learn %m %u dummy spam %f';

Expand All @@ -92,6 +96,7 @@
// %s is replaced with the email address the message is from
// %f is replaced with the path to the message file
// %h:<header name> is replaced with the content of that header from the message (lower case) eg: %h:x-dspam-signature
// %m is replaced with the mysql connect string
// If you do not want to run the command set this to null
$config['markasjunk2_ham_cmd'] = '/usr/libexec/indimail/bogo-learn %m %u dummy ham %f';

Expand Down
82 changes: 82 additions & 0 deletions ircube-x/plugins/markasjunk2/drivers/sa_blacklist.php
Expand Up @@ -141,4 +141,86 @@ private function _do_list($uids, $spam)
}
}
}

private function _do_salearn($uids, $spam)
{
$rcube = rcube::get_instance();
$temp_dir = realpath($rcube->config->get('temp_dir'));
$command = $rcube->config->get($spam ? 'markasjunk2_spam_cmd' : 'markasjunk2_ham_cmd');

if (!$command)
return;

// backwards compatibility %xds removed in markasjunk2 v1.12
$command = str_replace('%xds', '%h:x-dspam-signature', $command);

$command = str_replace('%u', $_SESSION['username'], $command);
$command = str_replace('%l', $rcube->user->get_username('local'), $command);
$command = str_replace('%d', $rcube->user->get_username('domain'), $command);
$command = str_replace('%m', $rcube->config->get('sauserprefs_db_dsnw'), $command);
if (preg_match('/%i/', $command)) {
$identity_arr = $rcube->user->get_identity();
$command = str_replace('%i', $identity_arr['email'], $command);
}

foreach ($uids as $uid) {
// reset command for next message
$tmp_command = $command;

// 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', $rcube->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 (strpos($tmp_command, '%s') !== false) {
$message = new rcube_message($uid);
$tmp_command = str_replace('%s', escapeshellarg($message->sender['mailto']), $tmp_command);
}

if (strpos($command, '%h') !== false) {
$storage = $rcube->get_storage();
$storage->check_connection();
$storage->conn->select($src_mbox);

preg_match_all('/%h:([\w-_]+)/', $tmp_command, $header_names, PREG_SET_ORDER);
foreach ($header_names as $header) {
$val = null;
if ($msg = $storage->conn->fetchHeader($src_mbox, $uid, true, false, array($header[1]))) {
$val = $msg->{$header[1]} ?: $msg->others[$header[1]];
}

if (!empty($val)) {
$tmp_command = str_replace($header[0], escapeshellarg($val), $tmp_command);
}
else {
if ($rcube->config->get('markasjunk2_debug')) {
rcube::write_log('markasjunk2', 'header ' . $header[1] . ' not found in message ' . $src_mbox . '/' . $uid);
}

continue 2;
}
}
}

if (strpos($command, '%f') !== false) {
$tmpfname = tempnam($temp_dir, 'rcmSALearn');
file_put_contents($tmpfname, $rcube->storage->get_raw_body($uid));
$tmp_command = str_replace('%f', escapeshellarg($tmpfname), $tmp_command);
}

$output = shell_exec($tmp_command);

if ($rcube->config->get('markasjunk2_debug')) {
rcube::write_log('markasjunk2', $tmp_command);
rcube::write_log('markasjunk2', $output);
}

if (strpos($command, '%f') !== false) {
unlink($tmpfname);
}
}
}
}

0 comments on commit 16bc393

Please sign in to comment.