public
nobgit
read
NobMail
Based on mailcow: dockerized
Languages
Repository composition by tracked source files.
PHP
49%
JavaScript
35%
HTML
9%
CSS
4%
Shell
2%
Python
1%
Lua
0%
Perl
0%
Ruby
0%
SCSS
0%
Create file
Wiki Documentation
Clone
https://nobgit.com/orgs/nobgit/nobmail.git
ssh://[email protected]:2222/orgs/nobgit/nobmail.git
Commit
[Web] More checks and fixes for transport maps
6dc2a0ee
data/web/inc/functions.transports.inc.php | 87 +++++++++++++++++++++++++------
data/web/lang/lang.de.php | 2 +
data/web/lang/lang.en.php | 2 +
3 files changed, 76 insertions(+), 15 deletions(-)
Diff
diff --git a/data/web/inc/functions.transports.inc.php b/data/web/inc/functions.transports.inc.php
index 5956868c..4d0f151c 100644
--- a/data/web/inc/functions.transports.inc.php
+++ b/data/web/inc/functions.transports.inc.php
@@ -188,8 +188,11 @@ function transport($_action, $_data = null) {
}
$destination = trim($_data['destination']);
$nexthop = trim($_data['nexthop']);
+ preg_match('/\[(.+)\].*/', $nexthop, $next_hop_matches);
+ $next_hop_clean = (isset($next_hop_matches[1])) ? $next_hop_matches[1] : $nexthop;
$username = str_replace(':', '\:', trim($_data['username']));
$password = str_replace(':', '\:', trim($_data['password']));
+ // ".domain" is a valid destination, "..domain" is not
if (empty($destination) || (is_valid_domain_name(preg_replace('/^' . preg_quote('.', '/') . '/', '', $destination)) === false && $destination != '*')) {
$_SESSION['return'][] = array(
'type' => 'danger',
@@ -206,18 +209,39 @@ function transport($_action, $_data = null) {
);
return false;
}
- if (!empty($username)) {
- $transports = transport('get');
- if (!empty($transports)) {
- foreach ($transports as $transport) {
- if (transport('details', $transport['id'])['nexthop'] == $nexthop && transport('details', $transport['id'])['username'] != $username) {
- $_SESSION['return'][] = array(
- 'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_data_log),
- 'msg' => 'invalid_nexthop_authenticated'
- );
- return false;
- }
+ $transports = transport('get');
+ if (!empty($transports)) {
+ foreach ($transports as $transport) {
+ $transport_data = transport('details', $transport['id']);
+ $existing_nh[] = $transport_data['nexthop'];
+ preg_match('/\[(.+)\].*/', $transport_data['nexthop'], $existing_clean_nh[]);
+ if (($transport_data['nexthop'] == $nexthop || $transport_data['nexthop'] == $next_hop_clean) && $transport_data['username'] != $username) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_data_log),
+ 'msg' => 'invalid_nexthop_authenticated'
+ );
+ return false;
+ }
+ }
+ }
+ if (in_array($next_hop_clean, $existing_nh)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_data_log),
+ 'msg' => array('next_hop_interferes', $next_hop_clean, $nexthop)
+ );
+ return false;
+ }
+ if (!isset($next_hop_matches[1])) {
+ foreach ($existing_clean_nh as $existing_clean_nh_each) {
+ if ($existing_clean_nh_each[1] == $nexthop) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_data_log),
+ 'msg' => array('next_hop_interferes_any', $nexthop)
+ );
+ return false;
}
}
}
@@ -274,9 +298,6 @@ function transport($_action, $_data = null) {
$password = (isset($_data['password'])) ? trim($_data['password']) : $is_now['password'];
$active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
}
- if (empty($username)) {
- $password = '';
- }
else {
$_SESSION['return'][] = array(
'type' => 'danger',
@@ -285,6 +306,42 @@ function transport($_action, $_data = null) {
);
continue;
}
+ preg_match('/\[(.+)\].*/', $nexthop, $next_hop_matches);
+ $next_hop_clean = (isset($next_hop_matches[1])) ? $next_hop_matches[1] : $nexthop;
+ $transports = transport('get');
+ if (!empty($transports)) {
+ foreach ($transports as $transport) {
+ $transport_data = transport('details', $transport['id']);
+ if ($transport['id'] == $id) {
+ continue;
+ }
+ $existing_nh[] = $transport_data['nexthop'];
+ preg_match('/\[(.+)\].*/', $transport_data['nexthop'], $existing_clean_nh[]);
+ }
+ }
+ if (in_array($next_hop_clean, $existing_nh)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_data_log),
+ 'msg' => array('next_hop_interferes', $next_hop_clean, $nexthop)
+ );
+ return false;
+ }
+ if (!isset($next_hop_matches[1])) {
+ foreach ($existing_clean_nh as $existing_clean_nh_each) {
+ if ($existing_clean_nh_each[1] == $nexthop) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_data_log),
+ 'msg' => array('next_hop_interferes_any', $nexthop)
+ );
+ return false;
+ }
+ }
+ }
+ if (empty($username)) {
+ $password = '';
+ }
try {
$stmt = $pdo->prepare("UPDATE `transports` SET
`destination` = :destination,
diff --git a/data/web/lang/lang.de.php b/data/web/lang/lang.de.php
index 4f20c1c3..a6429d66 100644
--- a/data/web/lang/lang.de.php
+++ b/data/web/lang/lang.de.php
@@ -32,6 +32,8 @@ $lang['danger']['ip_list_empty'] = "Liste erlaubter IPs darf nicht leer sein";
$lang['danger']['invalid_destination'] = "Ziel-Format ist ungültig";
$lang['danger']['invalid_nexthop'] = "Next Hop ist ungültig";
$lang['danger']['invalid_nexthop_authenticated'] = 'Dieser Next Hop existiert bereits mit abweichenden Authentifizierungsdaten. Die bestehenden Authentifizierungsdaten dieses "Next Hops" müssen vorab angepasst werden.';
+$lang['danger']['next_hop_interferes'] = "%s verhindert das Hinzufügen von Next Hop %s";
+$lang['danger']['next_hop_interferes_any'] = "Ein vorhandener Eintrag verhindert das Hinzufügen von Next Hop %s";
$lang['danger']['rspamd_ui_pw_length'] = "Rspamd UI Passwort muss mindestens 6 Zeichen lang sein";
$lang['success']['rspamd_ui_pw_set'] = "Rspamd UI Passwort wurde gesetzt";
$lang['success']['queue_command_success'] = "Queue-Aufgabe erfolgreich ausgeführt";
diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php
index bc310c33..4e9516a1 100644
--- a/data/web/lang/lang.en.php
+++ b/data/web/lang/lang.en.php
@@ -33,6 +33,8 @@ $lang['danger']['ip_list_empty'] = "List of allowed IPs cannot be empty";
$lang['danger']['invalid_destination'] = "Destination format is invalid";
$lang['danger']['invalid_nexthop'] = "Next hop format is invalid";
$lang['danger']['invalid_nexthop_authenticated'] = "Next hops exists with different credentials, please update the existing credentials for this next hop first.";
+$lang['danger']['next_hop_interferes'] = "%s interferes with nexthop %s";
+$lang['danger']['next_hop_interferes_any'] = "An existing next hop interferes with %s";
$lang['danger']['rspamd_ui_pw_length'] = "Rspamd UI password should be at least 6 chars long";
$lang['success']['rspamd_ui_pw_set'] = "Rspamd UI password successfully set";
$lang['success']['queue_command_success'] = "Queue command completed successfully";