From 28be09f3d7d4dba4e5c3fa6abc8206f21589cb2f Mon Sep 17 00:00:00 2001 From: andryyy Date: Thu, 6 Dec 2018 16:51:11 +0100 Subject: [PATCH] [Web] Allow to toggle release format of quarantine msgs --- data/web/admin.php | 37 ++++-- data/web/inc/functions.quarantine.inc.php | 155 ++++++++++++++++------ data/web/lang/lang.en.php | 3 + data/web/modals/quarantine.php | 1 - 4 files changed, 142 insertions(+), 54 deletions(-) diff --git a/data/web/admin.php b/data/web/admin.php index d077bd7e..7edfa861 100644 --- a/data/web/admin.php +++ b/data/web/admin.php @@ -557,7 +557,7 @@ $tfa_data = get_tfa();
- +
@@ -573,17 +573,30 @@ $tfa_data = get_tfa();
-
-
- +
+
+
+ + +
+
+
+
+
+ +
+
diff --git a/data/web/inc/functions.quarantine.inc.php b/data/web/inc/functions.quarantine.inc.php index e854bca3..73c97a7a 100644 --- a/data/web/inc/functions.quarantine.inc.php +++ b/data/web/inc/functions.quarantine.inc.php @@ -74,12 +74,19 @@ function quarantine($_action, $_data = null) { return false; } $retention_size = $_data['retention_size']; + if ($_data['release_format'] == 'attachment' || $_data['release_format'] == 'raw') { + $release_format = $_data['release_format']; + } + else { + $release_format = 'raw'; + } $max_size = $_data['max_size']; $exclude_domains = (array)$_data['exclude_domains']; try { $redis->Set('Q_RETENTION_SIZE', intval($retention_size)); $redis->Set('Q_MAX_SIZE', intval($max_size)); $redis->Set('Q_EXCLUDE_DOMAINS', json_encode($exclude_domains)); + $redis->Set('Q_RELEASE_FORMAT', $release_format); } catch (RedisException $e) { $_SESSION['return'][] = array( @@ -124,54 +131,119 @@ function quarantine($_action, $_data = null) { continue; } $sender = (isset($row['sender'])) ? $row['sender'] : 'sender-unknown@rspamd'; - try { - $mail = new PHPMailer(true); - $mail->isSMTP(); - $mail->SMTPDebug = 0; - $mail->SMTPOptions = array( - 'ssl' => array( - 'verify_peer' => false, - 'verify_peer_name' => false, - 'allow_self_signed' => true - ) - ); - if (!empty(gethostbynamel('postfix-mailcow'))) { - $postfix = 'postfix-mailcow'; - } - if (!empty(gethostbynamel('postfix'))) { - $postfix = 'postfix'; - } - else { - $_SESSION['return'][] = array( - 'type' => 'warning', - 'log' => array(__FUNCTION__, $_action, $_data_log), - 'msg' => array('release_send_failed', 'Cannot determine Postfix host') - ); - continue; - } - $mail->Host = $postfix; - $mail->Port = 590; - $mail->setFrom($sender); - $mail->CharSet = 'UTF-8'; - $mail->Subject = sprintf($lang['quarantine']['release_subject'], $row['qid']); - $mail->addAddress($row['rcpt']); - $mail->IsHTML(false); - $msg_tmpf = tempnam("/tmp", $row['qid']); - file_put_contents($msg_tmpf, $row['msg']); - $mail->addAttachment($msg_tmpf, $row['qid'] . '.eml'); - $mail->Body = sprintf($lang['quarantine']['release_body']); - $mail->send(); - unlink($msg_tmpf); + if (!empty(gethostbynamel('postfix-mailcow'))) { + $postfix = 'postfix-mailcow'; } - catch (phpmailerException $e) { - unlink($msg_tmpf); + if (!empty(gethostbynamel('postfix'))) { + $postfix = 'postfix'; + } + else { $_SESSION['return'][] = array( 'type' => 'warning', 'log' => array(__FUNCTION__, $_action, $_data_log), - 'msg' => array('release_send_failed', $e->errorMessage()) + 'msg' => array('release_send_failed', 'Cannot determine Postfix host') ); continue; } + try { + $release_format = $redis->Get('Q_RELEASE_FORMAT'); + } + catch (RedisException $e) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_data_log), + 'msg' => array('redis_error', $e) + ); + return false; + } + if ($release_format == 'attachment') { + try { + $mail = new PHPMailer(true); + $mail->isSMTP(); + $mail->SMTPDebug = 0; + $mail->SMTPOptions = array( + 'ssl' => array( + 'verify_peer' => false, + 'verify_peer_name' => false, + 'allow_self_signed' => true + ) + ); + if (!empty(gethostbynamel('postfix-mailcow'))) { + $postfix = 'postfix-mailcow'; + } + if (!empty(gethostbynamel('postfix'))) { + $postfix = 'postfix'; + } + else { + $_SESSION['return'][] = array( + 'type' => 'warning', + 'log' => array(__FUNCTION__, $_action, $_data_log), + 'msg' => array('release_send_failed', 'Cannot determine Postfix host') + ); + continue; + } + $mail->Host = $postfix; + $mail->Port = 590; + $mail->setFrom($sender); + $mail->CharSet = 'UTF-8'; + $mail->Subject = sprintf($lang['quarantine']['release_subject'], $row['qid']); + $mail->addAddress($row['rcpt']); + $mail->IsHTML(false); + $msg_tmpf = tempnam("/tmp", $row['qid']); + file_put_contents($msg_tmpf, $row['msg']); + $mail->addAttachment($msg_tmpf, $row['qid'] . '.eml'); + $mail->Body = sprintf($lang['quarantine']['release_body']); + $mail->send(); + unlink($msg_tmpf); + } + catch (phpmailerException $e) { + unlink($msg_tmpf); + $_SESSION['return'][] = array( + 'type' => 'warning', + 'log' => array(__FUNCTION__, $_action, $_data_log), + 'msg' => array('release_send_failed', $e->errorMessage()) + ); + continue; + } + } + elseif ($release_format == 'raw') { + $postfix_talk = array( + array('220', 'HELO quarantine' . chr(10)), + array('250', 'MAIL FROM: ' . $sender . chr(10)), + array('250', 'RCPT TO: ' . $row['rcpt'] . chr(10)), + array('250', 'DATA' . chr(10)), + array('354', $row['msg'] . chr(10) . '.' . chr(10)), + array('250', 'QUIT' . chr(10)), + array('221', '') + ); + // Thanks to https://stackoverflow.com/questions/6632399/given-an-email-as-raw-text-how-can-i-send-it-using-php + $smtp_connection = fsockopen($postfix, 590, $errno, $errstr, 1); + if (!$smtp_connection) { + $_SESSION['return'][] = array( + 'type' => 'warning', + 'log' => array(__FUNCTION__, $_action, $_data_log), + 'msg' => 'Cannot connect to Postfix' + ); + return false; + } + for ($i=0; $i < count($postfix_talk); $i++) { + $smtp_resource = fgets($smtp_connection, 256); + if (substr($smtp_resource, 0, 3) !== $postfix_talk[$i][0]) { + $ret = substr($smtp_resource, 0, 3); + $ret = (empty($ret)) ? '-' : $ret; + $_SESSION['return'][] = array( + 'type' => 'warning', + 'log' => array(__FUNCTION__, $_action, $_data_log), + 'msg' => 'Postfix returned SMTP code ' . $smtp_resource . ', expected ' . $postfix_talk[$i][0] + ); + return false; + } + if ($postfix_talk[$i][1] !== '') { + fputs($smtp_connection, $postfix_talk[$i][1]); + } + } + fclose($smtp_connection); + } try { $stmt = $pdo->prepare("DELETE FROM `quarantine` WHERE `id` = :id"); $stmt->execute(array( @@ -355,6 +427,7 @@ function quarantine($_action, $_data = null) { } $settings['max_size'] = $redis->Get('Q_MAX_SIZE'); $settings['retention_size'] = $redis->Get('Q_RETENTION_SIZE'); + $settings['release_format'] = $redis->Get('Q_RELEASE_FORMAT'); } catch (RedisException $e) { $_SESSION['return'][] = array( diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index 0929c463..08c1b654 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -613,6 +613,9 @@ $lang['admin']['quarantine'] = "Quarantine"; $lang['admin']['quarantine_retention_size'] = "Retentions per mailbox
0 indicates inactive!"; $lang['admin']['quarantine_max_size'] = "Maximum size in MiB (larger elements are discarded)
0 does not indicate unlimited!"; $lang['admin']['quarantine_exclude_domains'] = "Exclude domains and alias-domains:"; +$lang['admin']['quarantine_release_format'] = "Format of released items:"; +$lang['admin']['quarantine_release_format_raw'] = "Unmodified original"; +$lang['admin']['quarantine_release_format_att'] = "As attachment"; $lang['admin']['ui_texts'] = "UI labels and texts"; $lang['admin']['help_text'] = "Override help text below login mask (HTML allowed)"; diff --git a/data/web/modals/quarantine.php b/data/web/modals/quarantine.php index 30a0d3b8..5a22446e 100644 --- a/data/web/modals/quarantine.php +++ b/data/web/modals/quarantine.php @@ -12,7 +12,6 @@ if (!isset($_SESSION['mailcow_cc_role'])) {