From 17918b3e214d19fc4cc31da74511b3fe6b7038d1 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 1 May 2019 00:56:12 +0200 Subject: [PATCH] Added domain alias handling to quarantine mails and added recipients row to quarantine mail display If a mail is sent to a domain alias domain and rejected, mailcow does not currently store the mail in quarantine. This commit adds domain alias handling to the reject code and should fix this behavior. Also added displaying of recipient addresses into the quarantine mail dialog to be able to see what mail address was "leaked". --- data/conf/rspamd/meta_exporter/pipe.php | 22 ++++++++++++++++++++-- data/web/css/site/quarantine.css | 10 +++++++++- data/web/inc/ajax/qitem_details.php | 20 +++++++++++++++++++- data/web/js/site/quarantine.js | 10 +++++++++- data/web/lang/lang.ca.php | 1 + data/web/lang/lang.cs.php | 1 + data/web/lang/lang.de.php | 1 + data/web/lang/lang.en.php | 1 + data/web/lang/lang.lv.php | 1 + data/web/lang/lang.nl.php | 1 + data/web/modals/quarantine.php | 4 ++++ 11 files changed, 67 insertions(+), 5 deletions(-) diff --git a/data/conf/rspamd/meta_exporter/pipe.php b/data/conf/rspamd/meta_exporter/pipe.php index 692a0c2e0..31f6037f3 100644 --- a/data/conf/rspamd/meta_exporter/pipe.php +++ b/data/conf/rspamd/meta_exporter/pipe.php @@ -131,6 +131,14 @@ foreach (json_decode($rcpts, true) as $rcpt) { )); $gotos = $stmt->fetch(PDO::FETCH_ASSOC)['goto']; } + if (empty($gotos)) { + $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :rcpt AND `active` = '1'"); + $stmt->execute(array(':rcpt' => $parsed_rcpt['domain'])); + $goto_branch = $stmt->fetch(PDO::FETCH_ASSOC)['target_domain']; + if ($goto_branch) { + $gotos = $parsed_rcpt['local'] . '@' . $goto_branch; + } + } $gotos_array = explode(',', $gotos); $loop_c = 0; @@ -159,8 +167,18 @@ foreach (json_decode($rcpts, true) as $rcpt) { $stmt = $pdo->prepare("SELECT `goto` FROM `alias` WHERE `address` = :goto AND `active` = '1'"); $stmt->execute(array(':goto' => $goto)); $goto_branch = $stmt->fetch(PDO::FETCH_ASSOC)['goto']; - error_log("QUARANTINE: quarantine pipe: goto address " . $goto . " is a alias branch for " . $goto_branch); - $goto_branch_array = explode(',', $goto_branch); + if ($goto_branch) { + error_log("QUARANTINE: quarantine pipe: goto address " . $goto . " is a alias branch for " . $goto_branch); + $goto_branch_array = explode(',', $goto_branch); + } else { + $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain AND `active` AND '1'"); + $stmt->execute(array(':domain' => $parsed_goto['domain'])); + $goto_branch = $stmt->fetch(PDO::FETCH_ASSOC)['target_domain']; + if ($goto_branch) { + error_log("QUARANTINE: quarantine pipe: goto domain " . $parsed_gto['domain'] . " is a domain alias branch for " . $goto_branch); + $goto_branch_array = array($parsed_gto['local'] . '@' . $goto_branch); + } + } } } // goto item was processed, unset diff --git a/data/web/css/site/quarantine.css b/data/web/css/site/quarantine.css index 5d0fa1ef7..3a3718d17 100644 --- a/data/web/css/site/quarantine.css +++ b/data/web/css/site/quarantine.css @@ -48,4 +48,12 @@ table.footable>tbody>tr.footable-empty>td { background-color: #d4d4d4; border-radius: 50%; display: inline-block; -} \ No newline at end of file +} + +span.mail-address-item { + background-color: #f5f5f5; + border-radius: 4px; + border: 1px solid #ccc; + padding: 2px 7px; + margin-right: 7px; +} diff --git a/data/web/inc/ajax/qitem_details.php b/data/web/inc/ajax/qitem_details.php index 71d32cc90..3c82ee6ab 100644 --- a/data/web/inc/ajax/qitem_details.php +++ b/data/web/inc/ajax/qitem_details.php @@ -3,8 +3,9 @@ session_start(); header("Content-Type: application/json"); require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php'; if (!isset($_SESSION['mailcow_cc_role'])) { - exit(); + exit(); } + function rrmdir($src) { $dir = opendir($src); while(false !== ( $file = readdir($dir)) ) { @@ -21,6 +22,13 @@ function rrmdir($src) { closedir($dir); rmdir($src); } +function addAddresses(&$list, $mail, $headerName) { + $addresses = $mail->getAddresses($headerName); + foreach ($addresses as $address) { + $list[] = array('address' => $address['address'], 'type' => $headerName); + } +} + if (!empty($_GET['id']) && ctype_alnum($_GET['id'])) { $tmpdir = '/tmp/' . $_GET['id'] . '/'; $mailc = quarantine('details', $_GET['id']); @@ -36,6 +44,16 @@ if (!empty($_GET['id']) && ctype_alnum($_GET['id'])) { $html2text = new Html2Text\Html2Text(); // Load msg to parser $mail_parser->setText($mailc['msg']); + + // Get mail recipients + { + $recipientsList = array(); + addAddresses($recipientsList, $mail_parser, 'to'); + addAddresses($recipientsList, $mail_parser, 'cc'); + addAddresses($recipientsList, $mail_parser, 'bcc'); + $data['recipients'] = $recipientsList; + } + // Get text/plain content $data['text_plain'] = $mail_parser->getMessageBody('text'); // Get html content and convert to text diff --git a/data/web/js/site/quarantine.js b/data/web/js/site/quarantine.js index 4df1dbd42..c4d19cf9a 100644 --- a/data/web/js/site/quarantine.js +++ b/data/web/js/site/quarantine.js @@ -87,8 +87,16 @@ jQuery(function($){ $('#qid_detail_text').text(data.text_plain); $('#qid_detail_text_from_html').text(data.text_html); + $('#qid_detail_recipients').html(''); + if (typeof data.recipients !== 'undefined') { + $.each(data.recipients, function(index, value) { + var displayStr = value.address + (value.type != 'to' ? (' (' + value.type.toUpperCase() + ')') : ''); + $('#qid_detail_recipients').append('' + displayStr + ''); + }); + } + + var qAtts = $("#qid_detail_atts"); if (typeof data.attachments !== 'undefined') { - qAtts = $("#qid_detail_atts"); qAtts.text(''); $.each(data.attachments, function(index, value) { qAtts.append( diff --git a/data/web/lang/lang.ca.php b/data/web/lang/lang.ca.php index 91072ecf6..637226610 100644 --- a/data/web/lang/lang.ca.php +++ b/data/web/lang/lang.ca.php @@ -498,6 +498,7 @@ $lang['quarantine']['show_item'] = "Mostrar"; $lang['quarantine']['check_hash'] = "Comprovar el hash del fitxer a VT"; $lang['quarantine']['qitem'] = "Element en quarantena"; $lang['quarantine']['subj'] = "Assumpte"; +$lang['quarantine']['recipients'] = "Recipients"; $lang['quarantine']['text_plain_content'] = "Contingut (text/plain)"; $lang['quarantine']['text_from_html_content'] = "Contingut (a partir del HTML)"; $lang['quarantine']['atts'] = "Adjunts"; diff --git a/data/web/lang/lang.cs.php b/data/web/lang/lang.cs.php index ca2a4684e..efcac064e 100644 --- a/data/web/lang/lang.cs.php +++ b/data/web/lang/lang.cs.php @@ -712,6 +712,7 @@ $lang['quarantine']['show_item'] = "Zobrazit položku"; $lang['quarantine']['check_hash'] = "Hledat hash @ VT souboru"; $lang['quarantine']['qitem'] = "Položka v karanténě"; $lang['quarantine']['subj'] = "Předmět"; +$lang['quarantine']['recipients'] = "Příjemci"; $lang['quarantine']['text_plain_content'] = "Obsah (text/plain)"; $lang['quarantine']['text_from_html_content'] = "Obsah (konvertované html)"; $lang['quarantine']['atts'] = "Přílohy"; diff --git a/data/web/lang/lang.de.php b/data/web/lang/lang.de.php index aeb38c9b5..63b336149 100644 --- a/data/web/lang/lang.de.php +++ b/data/web/lang/lang.de.php @@ -732,6 +732,7 @@ $lang['quarantine']['show_item'] = "Details"; $lang['quarantine']['check_hash'] = "Checksumme auf VirusTotal suchen"; $lang['quarantine']['qitem'] = "Quarantäneeintrag"; $lang['quarantine']['subj'] = "Betreff"; +$lang['quarantine']['recipients'] = "Empfänger"; $lang['quarantine']['text_plain_content'] = "Inhalt (text/plain)"; $lang['quarantine']['text_from_html_content'] = "Inhalt (html, konvertiert)"; $lang['quarantine']['atts'] = "Anhänge"; diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index be92b3894..359990a20 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -754,6 +754,7 @@ $lang['quarantine']['show_item'] = "Show item"; $lang['quarantine']['check_hash'] = "Search file hash @ VT"; $lang['quarantine']['qitem'] = "Quarantine item"; $lang['quarantine']['subj'] = "Subject"; +$lang['quarantine']['recipients'] = "Recipients"; $lang['quarantine']['text_plain_content'] = "Content (text/plain)"; $lang['quarantine']['text_from_html_content'] = "Content (converted html)"; $lang['quarantine']['atts'] = "Attachments"; diff --git a/data/web/lang/lang.lv.php b/data/web/lang/lang.lv.php index 2fe3290ed..50e9884f0 100644 --- a/data/web/lang/lang.lv.php +++ b/data/web/lang/lang.lv.php @@ -494,6 +494,7 @@ $lang['quarantine']['show_item'] = "Parādīt vienumus"; $lang['quarantine']['check_hash'] = "Meklēt faila hašu @ VT"; $lang['quarantine']['qitem'] = "Karantīnas vienumi"; $lang['quarantine']['subj'] = "Priekšmets"; +$lang['quarantine']['recipients'] = "Adresāts"; $lang['quarantine']['text_plain_content'] = "Saturs (teksts/vienkāršs)"; $lang['quarantine']['text_from_html_content'] = "Saturs (konvertēts html)"; $lang['quarantine']['atts'] = "Pielikumi"; diff --git a/data/web/lang/lang.nl.php b/data/web/lang/lang.nl.php index 0c73ee990..1d5bb54ba 100644 --- a/data/web/lang/lang.nl.php +++ b/data/web/lang/lang.nl.php @@ -731,6 +731,7 @@ $lang['quarantine']['show_item'] = "Laat item zien"; $lang['quarantine']['check_hash'] = "Zoek bestandshash op in VT"; $lang['quarantine']['qitem'] = "Quarantaine-item"; $lang['quarantine']['subj'] = "Onderwerp"; +$lang['quarantine']['recipients'] = "Ontvangers"; $lang['quarantine']['text_plain_content'] = "Inhoud (tekst)"; $lang['quarantine']['text_from_html_content'] = "Inhoud (geconverteerde html)"; $lang['quarantine']['atts'] = "Bijlagen"; diff --git a/data/web/modals/quarantine.php b/data/web/modals/quarantine.php index e19299273..0d091163d 100644 --- a/data/web/modals/quarantine.php +++ b/data/web/modals/quarantine.php @@ -17,6 +17,10 @@ if (!isset($_SESSION['mailcow_cc_role'])) {

+
+ +

+