mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2025-02-09 13:46:58 +02:00
[Web] Show ratelimit inheritance
[Web] Do not allow TLS-wrapped next shops (SMTPS) in transports [Web] Minor fixes or preparations
This commit is contained in:
parent
abf33b75f4
commit
0d8a92a365
@ -303,6 +303,16 @@ if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CAC
|
|||||||
<label for="password"><?=$lang['admin']['password'];?></label>
|
<label for="password"><?=$lang['admin']['password'];?></label>
|
||||||
<input class="form-control" name="password">
|
<input class="form-control" name="password">
|
||||||
</div>
|
</div>
|
||||||
|
<!-- <div class="form-group">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="lookup_mx" value="1"> <?=$lang['admin']['lookup_mx'];?>
|
||||||
|
</label>
|
||||||
|
</div> -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="active" value="1"> <?=$lang['admin']['active'];?>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<p class="help-block"><?=$lang['admin']['credentials_transport_warning'];?></p>
|
<p class="help-block"><?=$lang['admin']['credentials_transport_warning'];?></p>
|
||||||
<button class="btn btn-default" data-action="add_item" data-id="transport" data-api-url='add/transport' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['add'];?></button>
|
<button class="btn btn-default" data-action="add_item" data-id="transport" data-api-url='add/transport' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['add'];?></button>
|
||||||
</form>
|
</form>
|
||||||
@ -363,7 +373,7 @@ if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CAC
|
|||||||
else {
|
else {
|
||||||
?>
|
?>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-1"><input class="dkim_missing" type="checkbox" data-id="dkim" name="multi_select" value="<?=$domain;?>" disabled /></div>
|
<div class="col-md-1"><input class="dkim_missing" type="checkbox" data-id="dkim" name="multi_select" value="<?=$domain;?>" disabled /></div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<p><?=$lang['admin']['domain'];?>: <strong><?=htmlspecialchars($domain);?></strong><br /><span class="label label-danger"><?=$lang['admin']['dkim_key_missing'];?></span></p>
|
<p><?=$lang['admin']['domain'];?>: <strong><?=htmlspecialchars($domain);?></strong><br /><span class="label label-danger"><?=$lang['admin']['dkim_key_missing'];?></span></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -644,6 +644,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button class="btn btn-default" data-action="edit_selected" data-id="mboxratelimit" data-item="<?=htmlspecialchars($mailbox);?>" data-api-url='edit/rl-mbox' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
<button class="btn btn-default" data-action="edit_selected" data-id="mboxratelimit" data-item="<?=htmlspecialchars($mailbox);?>" data-api-url='edit/rl-mbox' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||||
</div>
|
</div>
|
||||||
|
<p class="help-block"><?=$lang['edit']['mbox_rl_info'];?></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -686,6 +687,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||||||
<label class="control-label col-sm-2" for="hostname"><?=$lang['add']['hostname'];?></label>
|
<label class="control-label col-sm-2" for="hostname"><?=$lang['add']['hostname'];?></label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" name="hostname" value="<?=htmlspecialchars($result['hostname'], ENT_QUOTES, 'UTF-8');?>" required>
|
<input type="text" class="form-control" name="hostname" value="<?=htmlspecialchars($result['hostname'], ENT_QUOTES, 'UTF-8');?>" required>
|
||||||
|
<p class="help-block"><?=$lang['add']['relayhost_wrapped_tls_info'];?></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -58,9 +58,11 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admi
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
$mail->SMTPDebug = 3;
|
$mail->SMTPDebug = 3;
|
||||||
if ($port == 465) {
|
// smtp: and smtp_enforced_tls: do not support wrapped tls, todo?
|
||||||
$mail->SMTPSecure = "ssl";
|
// 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) {
|
$mail->Debugoutput = function($str, $level) {
|
||||||
foreach(preg_split("/((\r?\n)|(\r\n?)|\n)/", $str) as $line){
|
foreach(preg_split("/((\r?\n)|(\r\n?)|\n)/", $str) as $line){
|
||||||
if (empty($line)) { continue; }
|
if (empty($line)) { continue; }
|
||||||
|
@ -3069,7 +3069,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
$mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576);
|
$mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576);
|
||||||
}
|
}
|
||||||
$mailboxdata['username'] = $row['username'];
|
$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['is_relayed'] = $row['backupmx'];
|
||||||
$mailboxdata['name'] = $row['name'];
|
$mailboxdata['name'] = $row['name'];
|
||||||
$mailboxdata['active'] = $row['active'];
|
$mailboxdata['active'] = $row['active'];
|
||||||
|
@ -187,6 +187,8 @@ function transport($_action, $_data = null) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$destination = trim($_data['destination']);
|
$destination = trim($_data['destination']);
|
||||||
|
$active = intval($_data['active']);
|
||||||
|
$lookup_mx = intval($_data['lookup_mx']);
|
||||||
$nexthop = trim($_data['nexthop']);
|
$nexthop = trim($_data['nexthop']);
|
||||||
preg_match('/\[(.+)\].*/', $nexthop, $next_hop_matches);
|
preg_match('/\[(.+)\].*/', $nexthop, $next_hop_matches);
|
||||||
$next_hop_clean = (isset($next_hop_matches[1])) ? $next_hop_matches[1] : $nexthop;
|
$next_hop_clean = (isset($next_hop_matches[1])) ? $next_hop_matches[1] : $nexthop;
|
||||||
@ -256,14 +258,15 @@ function transport($_action, $_data = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `transports` (`nexthop`, `destination`, `username` ,`password`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `transports` (`nexthop`, `destination`, `username` , `password`, `lookup_mx`, `active`)
|
||||||
VALUES (:nexthop, :destination, :username, :password, :active)");
|
VALUES (:nexthop, :destination, :username, :password, :lookup_mx, :active)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':nexthop' => $nexthop,
|
':nexthop' => $nexthop,
|
||||||
':destination' => $destination,
|
':destination' => $destination,
|
||||||
':username' => $username,
|
':username' => $username,
|
||||||
':password' => str_replace(':', '\:', $password),
|
':password' => str_replace(':', '\:', $password),
|
||||||
':active' => '1'
|
':lookup_mx' => $lookup_mx,
|
||||||
|
':active' => $active
|
||||||
));
|
));
|
||||||
$stmt = $pdo->prepare("UPDATE `transports` SET
|
$stmt = $pdo->prepare("UPDATE `transports` SET
|
||||||
`username` = :username,
|
`username` = :username,
|
||||||
@ -306,7 +309,8 @@ function transport($_action, $_data = null) {
|
|||||||
$nexthop = (!empty($_data['nexthop'])) ? trim($_data['nexthop']) : $is_now['nexthop'];
|
$nexthop = (!empty($_data['nexthop'])) ? trim($_data['nexthop']) : $is_now['nexthop'];
|
||||||
$username = (isset($_data['username'])) ? trim($_data['username']) : $is_now['username'];
|
$username = (isset($_data['username'])) ? trim($_data['username']) : $is_now['username'];
|
||||||
$password = (isset($_data['password'])) ? trim($_data['password']) : $is_now['password'];
|
$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 {
|
else {
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
@ -368,6 +372,7 @@ function transport($_action, $_data = null) {
|
|||||||
`nexthop` = :nexthop,
|
`nexthop` = :nexthop,
|
||||||
`username` = :username,
|
`username` = :username,
|
||||||
`password` = :password,
|
`password` = :password,
|
||||||
|
`lookup_mx` = :lookup_mx,
|
||||||
`active` = :active
|
`active` = :active
|
||||||
WHERE `id` = :id");
|
WHERE `id` = :id");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
@ -376,6 +381,7 @@ function transport($_action, $_data = null) {
|
|||||||
':nexthop' => $nexthop,
|
':nexthop' => $nexthop,
|
||||||
':username' => $username,
|
':username' => $username,
|
||||||
':password' => $password,
|
':password' => $password,
|
||||||
|
':lookup_mx' => $lookup_mx,
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
$stmt = $pdo->prepare("UPDATE `transports` SET
|
$stmt = $pdo->prepare("UPDATE `transports` SET
|
||||||
@ -453,8 +459,10 @@ function transport($_action, $_data = null) {
|
|||||||
`username`,
|
`username`,
|
||||||
`password`,
|
`password`,
|
||||||
`active` AS `active_int`,
|
`active` AS `active_int`,
|
||||||
|
`lookup_mx` AS `lookup_mx_int`,
|
||||||
CONCAT(LEFT(`password`, 3), '...') AS `password_short`,
|
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`
|
FROM `transports`
|
||||||
WHERE `id` = :id");
|
WHERE `id` = :id");
|
||||||
$stmt->execute(array(':id' => $_data));
|
$stmt->execute(array(':id' => $_data));
|
||||||
|
@ -3,7 +3,7 @@ function init_db_schema() {
|
|||||||
try {
|
try {
|
||||||
global $pdo;
|
global $pdo;
|
||||||
|
|
||||||
$db_version = "09062019_1208";
|
$db_version = "22082019_2140";
|
||||||
|
|
||||||
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
@ -116,6 +116,7 @@ function init_db_schema() {
|
|||||||
"nexthop" => "VARCHAR(255) NOT NULL",
|
"nexthop" => "VARCHAR(255) NOT NULL",
|
||||||
"username" => "VARCHAR(255) NOT NULL",
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
"password" => "VARCHAR(255) NOT NULL",
|
"password" => "VARCHAR(255) NOT NULL",
|
||||||
|
"lookup_mx" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||||
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
),
|
),
|
||||||
"keys" => array(
|
"keys" => array(
|
||||||
|
@ -352,6 +352,9 @@ jQuery(function($){
|
|||||||
item.rl = $.map(item.rl, function(e){
|
item.rl = $.map(item.rl, function(e){
|
||||||
return e;
|
return e;
|
||||||
}).join('/1');
|
}).join('/1');
|
||||||
|
if (item.rl_scope === 'domain') {
|
||||||
|
item.rl = '↪ ' + item.rl + ' (via ' + item.domain + ')';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
item.chkbox = '<input type="checkbox" data-id="mailbox" name="multi_select" value="' + encodeURIComponent(item.username) + '" />';
|
item.chkbox = '<input type="checkbox" data-id="mailbox" name="multi_select" value="' + encodeURIComponent(item.username) + '" />';
|
||||||
item.tls_enforce_in = '<span class="text-' + (item.attributes.tls_enforce_in == 1 ? 'success' : 'danger') + ' glyphicon glyphicon-lock"></span>';
|
item.tls_enforce_in = '<span class="text-' + (item.attributes.tls_enforce_in == 1 ? 'success' : 'danger') + ' glyphicon glyphicon-lock"></span>';
|
||||||
|
@ -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']['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.<br>
|
$lang['admin']['relayhosts_hint'] = 'Erstellen Sie senderabhängige Transporte, um diese im Einstellungsdialog einer Domain auszuwählen.<br>
|
||||||
Der Transporttyp lautet immer "smtp:". Benutzereinstellungen bezüglich Verschlüsselungsrichtlinie werden beim Transport berücksichtigt.';
|
Der Transporttyp lautet immer "smtp:". Benutzereinstellungen bezüglich Verschlüsselungsrichtlinie werden beim Transport berücksichtigt.';
|
||||||
$lang['admin']['transports_hint'] = '→ Transport Maps <b>überwiegen</b> senderabhängige Transport Maps.
|
$lang['admin']['transports_hint'] = '→ Transport Maps <b>überwiegen</b> senderabhängige Transport Maps.<br>
|
||||||
→ Transport Maps ignorieren Mailbox-Einstellungen für ausgehende Verschlüsselung. Eine serverweite TLS-Richtlinie wird jedoch angewendet.<br>
|
→ Transport Maps ignorieren Mailbox-Einstellungen für ausgehende Verschlüsselung. Eine serverweite TLS-Richtlinie wird jedoch angewendet.<br>
|
||||||
→ Der Transport erfolgt immer via "smtp:".<br>
|
→ Der Transport erfolgt immer via "smtp:".<br>
|
||||||
→ Adressen, die mit "/localhost$/" übereinstimmen, werden immer via "local:" transportiert, daher sind sie von einer Zieldefinition "*" ausgeschlossen.<br>
|
→ Adressen, die mit "/localhost$/" übereinstimmen, werden immer via "local:" transportiert, daher sind sie von einer Zieldefinition "*" ausgeschlossen.<br>
|
||||||
@ -852,3 +852,8 @@ $lang['admin']['validate_license_now'] = 'GUID erneut verifizieren';
|
|||||||
$lang['admin']['customer_id'] = 'Kunde';
|
$lang['admin']['customer_id'] = 'Kunde';
|
||||||
$lang['admin']['service_id'] = 'Service';
|
$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 <b>keine</b> TLS-wrapped Ports verwenden (etwa SMTPS via Port 465/tcp).<br>
|
||||||
|
Der Transport wird stattdessen STARTTLS anfordern, um TLS zu verwenden. TLS kann unter "TLS Policy Maps" erzwungen werden.';
|
||||||
|
@ -880,3 +880,10 @@ $lang['admin']['validate_license_now'] = 'Validate GUID against license server';
|
|||||||
|
|
||||||
$lang['admin']['customer_id'] = 'Customer ID';
|
$lang['admin']['customer_id'] = 'Customer ID';
|
||||||
$lang['admin']['service_id'] = 'Service 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 <b>not</b> use TLS-wrapped ports (mostly used on port 465).<br>
|
||||||
|
Use any non-wrapped port and issue STARTTLS. A TLS policy to enforce TLS can be created in "TLS policy maps".';
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user