From 0d8a92a36525ea141bd0c50a03162cc251c0223f Mon Sep 17 00:00:00 2001 From: andryyy Date: Sun, 25 Aug 2019 16:02:58 +0200 Subject: [PATCH] [Web] Show ratelimit inheritance [Web] Do not allow TLS-wrapped next shops (SMTPS) in transports [Web] Minor fixes or preparations --- data/web/admin.php | 12 +++++++++++- data/web/edit.php | 2 ++ data/web/inc/ajax/transport_check.php | 8 +++++--- data/web/inc/functions.mailbox.inc.php | 9 ++++++++- data/web/inc/functions.transports.inc.php | 18 +++++++++++++----- data/web/inc/init_db.inc.php | 3 ++- data/web/js/site/mailbox.js | 3 +++ data/web/lang/lang.de.php | 7 ++++++- data/web/lang/lang.en.php | 7 +++++++ 9 files changed, 57 insertions(+), 12 deletions(-) diff --git a/data/web/admin.php b/data/web/admin.php index da27a7d6..07d38776 100644 --- a/data/web/admin.php +++ b/data/web/admin.php @@ -303,6 +303,16 @@ if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CAC + +
+ +

@@ -363,7 +373,7 @@ if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CAC else { ?>
-
+

:

diff --git a/data/web/edit.php b/data/web/edit.php index 3bb8a26c..72431812 100644 --- a/data/web/edit.php +++ b/data/web/edit.php @@ -644,6 +644,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
+

@@ -686,6 +687,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
+

diff --git a/data/web/inc/ajax/transport_check.php b/data/web/inc/ajax/transport_check.php index e956f4f2..f959ee35 100644 --- a/data/web/inc/ajax/transport_check.php +++ b/data/web/inc/ajax/transport_check.php @@ -58,9 +58,11 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admi ) ); $mail->SMTPDebug = 3; - if ($port == 465) { - $mail->SMTPSecure = "ssl"; - } + // smtp: and smtp_enforced_tls: do not support wrapped tls, todo? + // change postfix map to detect wrapped tls or add a checkbox to toggle wrapped tls + // if ($port == 465) { + // $mail->SMTPSecure = "ssl"; + // } $mail->Debugoutput = function($str, $level) { foreach(preg_split("/((\r?\n)|(\r\n?)|\n)/", $str) as $line){ if (empty($line)) { continue; } diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 80d6900f..d16c3a18 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -3069,7 +3069,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576); } $mailboxdata['username'] = $row['username']; - $mailboxdata['rl'] = $rl; + if (!empty($rl)) { + $mailboxdata['rl'] = $rl; + $mailboxdata['rl_scope'] = 'mailbox'; + } + else { + $mailboxdata['rl'] = ratelimit('get', 'domain', $row['domain']); + $mailboxdata['rl_scope'] = 'domain'; + } $mailboxdata['is_relayed'] = $row['backupmx']; $mailboxdata['name'] = $row['name']; $mailboxdata['active'] = $row['active']; diff --git a/data/web/inc/functions.transports.inc.php b/data/web/inc/functions.transports.inc.php index e007f94d..0bc19c13 100644 --- a/data/web/inc/functions.transports.inc.php +++ b/data/web/inc/functions.transports.inc.php @@ -187,6 +187,8 @@ function transport($_action, $_data = null) { return false; } $destination = trim($_data['destination']); + $active = intval($_data['active']); + $lookup_mx = intval($_data['lookup_mx']); $nexthop = trim($_data['nexthop']); preg_match('/\[(.+)\].*/', $nexthop, $next_hop_matches); $next_hop_clean = (isset($next_hop_matches[1])) ? $next_hop_matches[1] : $nexthop; @@ -256,14 +258,15 @@ function transport($_action, $_data = null) { } } try { - $stmt = $pdo->prepare("INSERT INTO `transports` (`nexthop`, `destination`, `username` ,`password`, `active`) - VALUES (:nexthop, :destination, :username, :password, :active)"); + $stmt = $pdo->prepare("INSERT INTO `transports` (`nexthop`, `destination`, `username` , `password`, `lookup_mx`, `active`) + VALUES (:nexthop, :destination, :username, :password, :lookup_mx, :active)"); $stmt->execute(array( ':nexthop' => $nexthop, ':destination' => $destination, ':username' => $username, ':password' => str_replace(':', '\:', $password), - ':active' => '1' + ':lookup_mx' => $lookup_mx, + ':active' => $active )); $stmt = $pdo->prepare("UPDATE `transports` SET `username` = :username, @@ -306,7 +309,8 @@ function transport($_action, $_data = null) { $nexthop = (!empty($_data['nexthop'])) ? trim($_data['nexthop']) : $is_now['nexthop']; $username = (isset($_data['username'])) ? trim($_data['username']) : $is_now['username']; $password = (isset($_data['password'])) ? trim($_data['password']) : $is_now['password']; - $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int']; + $lookup_mx = (isset($_data['lookup_mx']) && $_data['lookup_mx'] != '') ? intval($_data['lookup_mx']) : $is_now['lookup_mx_int']; + $active = (isset($_data['active']) && $_data['active'] != '') ? intval($_data['active']) : $is_now['active_int']; } else { $_SESSION['return'][] = array( @@ -368,6 +372,7 @@ function transport($_action, $_data = null) { `nexthop` = :nexthop, `username` = :username, `password` = :password, + `lookup_mx` = :lookup_mx, `active` = :active WHERE `id` = :id"); $stmt->execute(array( @@ -376,6 +381,7 @@ function transport($_action, $_data = null) { ':nexthop' => $nexthop, ':username' => $username, ':password' => $password, + ':lookup_mx' => $lookup_mx, ':active' => $active )); $stmt = $pdo->prepare("UPDATE `transports` SET @@ -453,8 +459,10 @@ function transport($_action, $_data = null) { `username`, `password`, `active` AS `active_int`, + `lookup_mx` AS `lookup_mx_int`, CONCAT(LEFT(`password`, 3), '...') AS `password_short`, - CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active` + CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`, + CASE `lookup_mx` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `lookup_mx` FROM `transports` WHERE `id` = :id"); $stmt->execute(array(':id' => $_data)); diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index ddbf5ab1..cd8ca1c7 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 = "09062019_1208"; + $db_version = "22082019_2140"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -116,6 +116,7 @@ function init_db_schema() { "nexthop" => "VARCHAR(255) NOT NULL", "username" => "VARCHAR(255) NOT NULL", "password" => "VARCHAR(255) NOT NULL", + "lookup_mx" => "TINYINT(1) NOT NULL DEFAULT '1'", "active" => "TINYINT(1) NOT NULL DEFAULT '1'" ), "keys" => array( diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index 50b5956d..9a8e555e 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -352,6 +352,9 @@ jQuery(function($){ item.rl = $.map(item.rl, function(e){ return e; }).join('/1'); + if (item.rl_scope === 'domain') { + item.rl = '↪ ' + item.rl + ' (via ' + item.domain + ')'; + } } item.chkbox = ''; item.tls_enforce_in = ''; diff --git a/data/web/lang/lang.de.php b/data/web/lang/lang.de.php index 243d7432..b7215750 100644 --- a/data/web/lang/lang.de.php +++ b/data/web/lang/lang.de.php @@ -614,7 +614,7 @@ $lang['admin']['forwarding_hosts_hint'] = 'Eingehende Nachrichten werden von den $lang['admin']['forwarding_hosts_add_hint'] = 'Sie können entweder IPv4/IPv6-Adressen, Netzwerke in CIDR-Notation, Hostnamen (die zu IP-Adressen aufgelöst werden), oder Domainnamen (die zu IP-Adressen aufgelöst werden, indem ihr SPF-Record abgefragt wird oder, in dessen Abwesenheit, ihre MX-Records) angeben.'; $lang['admin']['relayhosts_hint'] = 'Erstellen Sie senderabhängige Transporte, um diese im Einstellungsdialog einer Domain auszuwählen.
Der Transporttyp lautet immer "smtp:". Benutzereinstellungen bezüglich Verschlüsselungsrichtlinie werden beim Transport berücksichtigt.'; -$lang['admin']['transports_hint'] = '→ Transport Maps überwiegen senderabhängige Transport Maps. +$lang['admin']['transports_hint'] = '→ Transport Maps überwiegen senderabhängige Transport Maps.
→ Transport Maps ignorieren Mailbox-Einstellungen für ausgehende Verschlüsselung. Eine serverweite TLS-Richtlinie wird jedoch angewendet.
→ Der Transport erfolgt immer via "smtp:".
→ Adressen, die mit "/localhost$/" übereinstimmen, werden immer via "local:" transportiert, daher sind sie von einer Zieldefinition "*" ausgeschlossen.
@@ -852,3 +852,8 @@ $lang['admin']['validate_license_now'] = 'GUID erneut verifizieren'; $lang['admin']['customer_id'] = 'Kunde'; $lang['admin']['service_id'] = 'Service'; +$lang['admin']['lookup_mx'] = 'Ziel gegen MX prüfen (etwa .outlook.com, um alle Ziele mit MX *.outlook.com zu routen)'; +$lang['edit']['mbox_rl_info'] = 'Dieses Limit wird auf den SASL Loginnamen angewendet und betrifft daher alle Absenderadressen, die der eingeloggte Benutzer verwendet. Eub Mailbox Ratelimit überwiegt ein Domain-weites Ratelimit.'; + +$lang['add']['relayhost_wrapped_tls_info'] = 'Bitte keine TLS-wrapped Ports verwenden (etwa SMTPS via Port 465/tcp).
+Der Transport wird stattdessen STARTTLS anfordern, um TLS zu verwenden. TLS kann unter "TLS Policy Maps" erzwungen werden.'; diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index b5748482..3d6f599f 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -880,3 +880,10 @@ $lang['admin']['validate_license_now'] = 'Validate GUID against license server'; $lang['admin']['customer_id'] = 'Customer ID'; $lang['admin']['service_id'] = 'Service ID'; + +$lang['admin']['lookup_mx'] = 'Match destination against MX (.outlook.com to route all mail targeted to a MX *.outlook.com over this hop)'; +$lang['edit']['mbox_rl_info'] = 'This rate limit is applied on the SASL login name, it matches any "from" address used by the logged-in user. A mailbox rate limit overrides a domain-wide rate limit.'; + +$lang['add']['relayhost_wrapped_tls_info'] = 'Please do not use TLS-wrapped ports (mostly used on port 465).
+Use any non-wrapped port and issue STARTTLS. A TLS policy to enforce TLS can be created in "TLS policy maps".'; +