diff --git a/data/conf/rspamd/meta_exporter/pipe.php b/data/conf/rspamd/meta_exporter/pipe.php index 0687851e..485a7b3c 100644 --- a/data/conf/rspamd/meta_exporter/pipe.php +++ b/data/conf/rspamd/meta_exporter/pipe.php @@ -51,6 +51,7 @@ $raw_data = mb_convert_encoding($raw_data_content, 'HTML-ENTITIES', "UTF-8"); $headers = getallheaders(); $qid = $headers['X-Rspamd-Qid']; +$fuzzy = $headers['X-Rspamd-Fuzzy']; $subject = $headers['X-Rspamd-Subject']; $score = $headers['X-Rspamd-Score']; $rcpts = $headers['X-Rspamd-Rcpt']; @@ -215,8 +216,8 @@ foreach (json_decode($rcpts, true) as $rcpt) { foreach ($rcpt_final_mailboxes as $rcpt_final) { error_log("QUARANTINE: quarantine pipe: processing quarantine message for rcpt " . $rcpt_final . PHP_EOL); try { - $stmt = $pdo->prepare("INSERT INTO `quarantine` (`qid`, `subject`, `score`, `sender`, `rcpt`, `symbols`, `user`, `ip`, `msg`, `action`) - VALUES (:qid, :subject, :score, :sender, :rcpt, :symbols, :user, :ip, :msg, :action)"); + $stmt = $pdo->prepare("INSERT INTO `quarantine` (`qid`, `subject`, `score`, `sender`, `rcpt`, `symbols`, `user`, `ip`, `msg`, `action`, `fuzzy_hashes`) + VALUES (:qid, :subject, :score, :sender, :rcpt, :symbols, :user, :ip, :msg, :action, :fuzzy_hashes)"); $stmt->execute(array( ':qid' => $qid, ':subject' => $subject, @@ -227,7 +228,8 @@ foreach ($rcpt_final_mailboxes as $rcpt_final) { ':user' => $user, ':ip' => $ip, ':msg' => $raw_data, - ':action' => $action + ':action' => $action, + ':fuzzy_hashes' => $fuzzy )); $stmt = $pdo->prepare('DELETE FROM `quarantine` WHERE `rcpt` = :rcpt AND `id` NOT IN ( SELECT `id` diff --git a/data/web/inc/ajax/qitem_details.php b/data/web/inc/ajax/qitem_details.php index 0ea89047..74898c64 100644 --- a/data/web/inc/ajax/qitem_details.php +++ b/data/web/inc/ajax/qitem_details.php @@ -63,6 +63,8 @@ if (!empty($_GET['hash']) && ctype_alnum($_GET['hash'])) { $data['score'] = $mailc['score']; // Get rspamd symbols $data['symbols'] = json_decode($mailc['symbols']); + // Get fuzzy hashes + $data['fuzzy_hashes'] = json_decode($mailc['fuzzy_hashes']); $data['subject'] = $mail_parser->getHeader('subject'); (empty($data['subject'])) ? $data['subject'] = '-' : null; echo json_encode($data); @@ -118,6 +120,8 @@ elseif (!empty($_GET['id']) && ctype_alnum($_GET['id'])) { $data['score'] = $mailc['score']; // Get rspamd symbols $data['symbols'] = json_decode($mailc['symbols']); + // Get fuzzy hashes + $data['fuzzy_hashes'] = json_decode($mailc['fuzzy_hashes']); // Get text/plain content $data['text_plain'] = $mail_parser->getMessageBody('text'); // Get html content and convert to text diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index efc0d627..1a1addde 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -3,7 +3,7 @@ function init_db_schema() { try { global $pdo; - $db_version = "26092020_2000"; + $db_version = "24102020_0900"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -260,6 +260,7 @@ function init_db_schema() { "ip" => "VARCHAR(50)", "action" => "CHAR(20) NOT NULL DEFAULT 'unknown'", "symbols" => "JSON", + "fuzzy_hashes" => "JSON", "sender" => "VARCHAR(255) NOT NULL DEFAULT 'unknown'", "rcpt" => "VARCHAR(255)", "msg" => "LONGTEXT", diff --git a/data/web/js/site/qhandler.js b/data/web/js/site/qhandler.js index c6851fdd..2690ce44 100644 --- a/data/web/js/site/qhandler.js +++ b/data/web/js/site/qhandler.js @@ -18,6 +18,14 @@ jQuery(function($){ $('#qid_detail_efrom').text(data.env_from); $('#qid_detail_score').text(data.score); $('#qid_detail_symbols').html(''); + $('#qid_detail_fuzzy').html(''); + if (data.fuzzy_hashes !== null) { + $.each(data.fuzzy_hashes, function (index, value) { + $('#qid_detail_fuzzy').append('

' + value + '

'); + }); + } else { + $('#qid_detail_fuzzy').append('-'); + } if (typeof data.symbols !== 'undefined') { data.symbols.sort(function (a, b) { if (a.score === 0) return 1 diff --git a/data/web/js/site/quarantine.js b/data/web/js/site/quarantine.js index e7817c8c..685b8861 100644 --- a/data/web/js/site/quarantine.js +++ b/data/web/js/site/quarantine.js @@ -148,6 +148,7 @@ jQuery(function($){ $('#qid_detail_efrom').text(data.env_from); $('#qid_detail_score').text(data.score); $('#qid_detail_symbols').html(''); + $('#qid_detail_fuzzy').html(''); if (typeof data.symbols !== 'undefined') { data.symbols.sort(function (a, b) { if (a.score === 0) return 1 @@ -169,7 +170,13 @@ jQuery(function($){ }); $('[data-toggle="tooltip"]').tooltip() } - + if (data.fuzzy_hashes !== null) { + $.each(data.fuzzy_hashes, function (index, value) { + $('#qid_detail_fuzzy').append('

' + value + '

'); + }); + } else { + $('#qid_detail_fuzzy').append('-'); + } $('#qid_detail_recipients').html(''); if (typeof data.recipients !== 'undefined') { $.each(data.recipients, function(index, value) { diff --git a/data/web/modals/quarantine.php b/data/web/modals/quarantine.php index 2ec40b85..88b3fb4d 100644 --- a/data/web/modals/quarantine.php +++ b/data/web/modals/quarantine.php @@ -26,6 +26,10 @@ if (!isset($_SESSION['mailcow_cc_role'])) {

+
+ +

+

diff --git a/data/web/qhandler.php b/data/web/qhandler.php index 23e66410..ca8ea576 100644 --- a/data/web/qhandler.php +++ b/data/web/qhandler.php @@ -56,6 +56,10 @@ elseif (in_array($_GET['action'], array('release', 'delete'))) {

+
+ +

+