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";