Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b162324ff0 | ||
|
|
6cd061d74c | ||
|
|
53b7420dc9 | ||
|
|
aa85c648a3 | ||
|
|
35e228ff09 | ||
|
|
62236da496 | ||
|
|
e1cc896b6c | ||
|
|
36595baa65 | ||
|
|
ec3fd1d105 | ||
|
|
e39dcfbfe2 | ||
|
|
ef6254b307 | ||
|
|
44bf211ab5 | ||
|
|
b0e920104f | ||
|
|
299e201142 | ||
|
|
46982ad2dc | ||
|
|
c0e07fd659 | ||
|
|
5c11eecbd7 | ||
|
|
9689afc759 | ||
|
|
d76f4108e5 | ||
|
|
9c4d619840 | ||
|
|
7774e7606d | ||
|
|
2ed0cad27b | ||
|
|
686c2ae534 | ||
|
|
faf3abe800 | ||
|
|
220b493a1b | ||
|
|
e8d67f9711 | ||
|
|
83e932b068 | ||
|
|
84d1be538e | ||
|
|
c97cdb1c0e | ||
|
|
ffefe85fb4 | ||
|
|
27341ca490 | ||
|
|
822bb2bd4d | ||
|
|
88ee76e4c9 | ||
|
|
90d921ebb5 | ||
|
|
7b162c4bd0 | ||
|
|
32e2d48aed | ||
|
|
1fdc524171 | ||
|
|
836b6f2fdb | ||
|
|
f297058461 | ||
|
|
0f4d8d76ae | ||
|
|
12884c91a6 |
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@@ -1,3 +1,4 @@
|
|||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: d00p
|
||||||
custom: ['https://paypal.me/Froxlor']
|
custom: ['https://paypal.me/Froxlor']
|
||||||
|
|||||||
14
SECURITY.md
Normal file
14
SECURITY.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
Our main and active version is currently 0.10.x. It will receive maintenance and security updates periodically. The older version 0.9.x will not receive any kind of updates. Please update to [0.10.x](https://github.com/Froxlor/Froxlor/wiki/Updating-Froxlor)
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| 0.10.x | :white_check_mark: |
|
||||||
|
| 0.9.x | :x: |
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
If you think you have found a vulnerability in froxlor, please send an email to [team@froxlor.org](mailto:team@froxlor.org) with as many information as possible. Also, please give us appropriate time to fix the issue and build update-packages before publishing anything into the wild.
|
||||||
@@ -289,6 +289,7 @@ if ($page == '' || $page == 'overview') {
|
|||||||
$result['customernumber'] = null;
|
$result['customernumber'] = null;
|
||||||
$result['custom_notes'] = null;
|
$result['custom_notes'] = null;
|
||||||
$result['custom_notes_show'] = null;
|
$result['custom_notes_show'] = null;
|
||||||
|
$result['api_allowed'] = null;
|
||||||
$hosting_plans = null;
|
$hosting_plans = null;
|
||||||
$admin_select_cnt = null;
|
$admin_select_cnt = null;
|
||||||
$admin_select = null;
|
$admin_select = null;
|
||||||
|
|||||||
8
api.php
8
api.php
@@ -23,7 +23,7 @@ if (empty($request)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// decode json request
|
// decode json request
|
||||||
$decoded_request = json_decode(stripslashes($request), true);
|
$decoded_request = json_decode($request, true);
|
||||||
|
|
||||||
// is it valid?
|
// is it valid?
|
||||||
if (is_null($decoded_request)) {
|
if (is_null($decoded_request)) {
|
||||||
@@ -32,6 +32,7 @@ if (is_null($decoded_request)) {
|
|||||||
|
|
||||||
// validate content
|
// validate content
|
||||||
try {
|
try {
|
||||||
|
$decoded_request = stripcslashes_deep($decoded_request);
|
||||||
$request = \Froxlor\Api\FroxlorRPC::validateRequest($decoded_request);
|
$request = \Froxlor\Api\FroxlorRPC::validateRequest($decoded_request);
|
||||||
// now actually do it
|
// now actually do it
|
||||||
$cls = "\\Froxlor\\Api\\Commands\\" . $request['command']['class'];
|
$cls = "\\Froxlor\\Api\\Commands\\" . $request['command']['class'];
|
||||||
@@ -72,3 +73,8 @@ function json_response($status, $status_message = '', $data = null)
|
|||||||
echo $json_response;
|
echo $json_response;
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stripcslashes_deep($value)
|
||||||
|
{
|
||||||
|
return is_array($value) ? array_map('stripcslashes_deep', $value) : stripcslashes($value);
|
||||||
|
}
|
||||||
|
|||||||
@@ -268,6 +268,10 @@ CREATE TABLE `panel_domains` (
|
|||||||
`notryfiles` tinyint(1) DEFAULT '0',
|
`notryfiles` tinyint(1) DEFAULT '0',
|
||||||
`writeaccesslog` tinyint(1) DEFAULT '1',
|
`writeaccesslog` tinyint(1) DEFAULT '1',
|
||||||
`writeerrorlog` tinyint(1) DEFAULT '1',
|
`writeerrorlog` tinyint(1) DEFAULT '1',
|
||||||
|
`override_tls` tinyint(1) DEFAULT '0',
|
||||||
|
`ssl_protocols` text,
|
||||||
|
`ssl_cipher_list` text,
|
||||||
|
`tlsv13_cipher_list` text,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `customerid` (`customerid`),
|
KEY `customerid` (`customerid`),
|
||||||
KEY `parentdomain` (`parentdomainid`),
|
KEY `parentdomain` (`parentdomainid`),
|
||||||
@@ -691,8 +695,8 @@ opcache.interned_strings_buffer'),
|
|||||||
('panel', 'password_special_char', '!?<>§$%+#=@'),
|
('panel', 'password_special_char', '!?<>§$%+#=@'),
|
||||||
('panel', 'customer_hide_options', ''),
|
('panel', 'customer_hide_options', ''),
|
||||||
('panel', 'is_configured', '0'),
|
('panel', 'is_configured', '0'),
|
||||||
('panel', 'version', '0.10.2'),
|
('panel', 'version', '0.10.5'),
|
||||||
('panel', 'db_version', '201910120');
|
('panel', 'db_version', '201910200');
|
||||||
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `panel_tasks`;
|
DROP TABLE IF EXISTS `panel_tasks`;
|
||||||
|
|||||||
@@ -403,6 +403,26 @@ if (\Froxlor\Froxlor::isDatabaseVersion('201910110')) {
|
|||||||
lastStepStatus(0);
|
lastStepStatus(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// select all domains with an ssl IP connected and specialsettings content to include these in the ssl-vhost
|
||||||
|
// to maintain former behavior
|
||||||
|
$sel_stmt = Database::prepare("
|
||||||
|
SELECT d.id FROM `" . TABLE_PANEL_DOMAINS . "` d
|
||||||
|
LEFT JOIN `" . TABLE_DOMAINTOIP . "` d2i ON d2i.id_domain = d.id
|
||||||
|
LEFT JOIN `" . TABLE_PANEL_IPSANDPORTS . "` i ON i.id = d2i.id_ipandports
|
||||||
|
WHERE d.specialsettings <> '' AND i.ssl = '1'
|
||||||
|
");
|
||||||
|
Database::pexecute($sel_stmt);
|
||||||
|
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `include_specialsettings` = '1' WHERE `id` = :id");
|
||||||
|
if ($sel_stmt->columnCount() > 0) {
|
||||||
|
showUpdateStep("Adjusting domain settings for downward compatibility");
|
||||||
|
while ($row = $sel_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
|
Database::pexecute($upd_stmt, [
|
||||||
|
'id' => $row['id']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
lastStepStatus(0);
|
||||||
|
}
|
||||||
|
|
||||||
\Froxlor\Froxlor::updateToDbVersion('201910120');
|
\Froxlor\Froxlor::updateToDbVersion('201910120');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,3 +430,30 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.1')) {
|
|||||||
showUpdateStep("Updating from 0.10.1 to 0.10.2", false);
|
showUpdateStep("Updating from 0.10.1 to 0.10.2", false);
|
||||||
\Froxlor\Froxlor::updateToVersion('0.10.2');
|
\Froxlor\Froxlor::updateToVersion('0.10.2');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (\Froxlor\Froxlor::isDatabaseVersion('201910120')) {
|
||||||
|
|
||||||
|
showUpdateStep("Adding new TLS options to domains-table");
|
||||||
|
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `override_tls` tinyint(1) DEFAULT '0' AFTER `writeerrorlog`;");
|
||||||
|
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_protocols` text AFTER `override_tls`;");
|
||||||
|
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_cipher_list` text AFTER `ssl_protocols`;");
|
||||||
|
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `tlsv13_cipher_list` text AFTER `ssl_cipher_list`;");
|
||||||
|
lastStepStatus(0);
|
||||||
|
|
||||||
|
\Froxlor\Froxlor::updateToDbVersion('201910200');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.2')) {
|
||||||
|
showUpdateStep("Updating from 0.10.2 to 0.10.3", false);
|
||||||
|
\Froxlor\Froxlor::updateToVersion('0.10.3');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.3')) {
|
||||||
|
showUpdateStep("Updating from 0.10.3 to 0.10.4", false);
|
||||||
|
\Froxlor\Froxlor::updateToVersion('0.10.4');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.4')) {
|
||||||
|
showUpdateStep("Updating from 0.10.4 to 0.10.5", false);
|
||||||
|
\Froxlor\Froxlor::updateToVersion('0.10.5');
|
||||||
|
}
|
||||||
|
|||||||
@@ -187,6 +187,14 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
* optional whether or not to preload HSTS header value
|
* optional whether or not to preload HSTS header value
|
||||||
* @param bool $ocsp_stapling
|
* @param bool $ocsp_stapling
|
||||||
* optional whether to enable ocsp-stapling for this domain. default 0 (false), requires SSL
|
* optional whether to enable ocsp-stapling for this domain. default 0 (false), requires SSL
|
||||||
|
* @param bool $override_tls
|
||||||
|
* optional whether or not to override system-tls settings like protocol, ssl-ciphers and if applicable tls-1.3 ciphers, requires change_serversettings flag for the admin, default false
|
||||||
|
* @param array $ssl_protocols
|
||||||
|
* optional list of allowed/used ssl/tls protocols, see system.ssl_protocols setting, only used/required if $override_tls is true, default empty or system.ssl_protocols setting if $override_tls is true
|
||||||
|
* @param string $ssl_cipher_list
|
||||||
|
* optional list of allowed/used ssl/tls ciphers, see system.ssl_cipher_list setting, only used/required if $override_tls is true, default empty or system.ssl_cipher_list setting if $override_tls is true
|
||||||
|
* @param string $tlsv13_cipher_list
|
||||||
|
* optional list of allowed/used tls-1.3 specific ciphers, see system.tlsv13_cipher_list setting, only used/required if $override_tls is true, default empty or system.tlsv13_cipher_list setting if $override_tls is true
|
||||||
*
|
*
|
||||||
* @access admin
|
* @access admin
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
@@ -239,6 +247,19 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
$hsts_preload = $this->getBoolParam('hsts_preload', true, 0);
|
$hsts_preload = $this->getBoolParam('hsts_preload', true, 0);
|
||||||
$ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, 0);
|
$ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, 0);
|
||||||
|
|
||||||
|
$override_tls = $this->getBoolParam('override_tls', true, 0);
|
||||||
|
$p_ssl_protocols = array();
|
||||||
|
$ssl_cipher_list = "";
|
||||||
|
$tlsv13_cipher_list = "";
|
||||||
|
|
||||||
|
if ($this->getUserDetail('change_serversettings') == '1') {
|
||||||
|
if ($override_tls) {
|
||||||
|
$p_ssl_protocols = $this->getParam('ssl_protocols', true, explode(',', Settings::Get('system.ssl_protocols')));
|
||||||
|
$ssl_cipher_list = $this->getParam('ssl_cipher_list', true, Settings::Get('system.ssl_cipher_list'));
|
||||||
|
$tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, Settings::Get('system.tlsv13_cipher_list'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// validation
|
// validation
|
||||||
if ($p_domain == Settings::Get('system.hostname')) {
|
if ($p_domain == Settings::Get('system.hostname')) {
|
||||||
\Froxlor\UI\Response::standard_error('admin_domain_emailsystemhostname', '', true);
|
\Froxlor\UI\Response::standard_error('admin_domain_emailsystemhostname', '', true);
|
||||||
@@ -325,6 +346,34 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
} else {
|
} else {
|
||||||
$documentroot = $_documentroot;
|
$documentroot = $_documentroot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$ssl_protocols = array();
|
||||||
|
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
|
||||||
|
$p_ssl_protocols = array(
|
||||||
|
$p_ssl_protocols
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (! empty($p_ssl_protocols) && ! is_array($p_ssl_protocols)) {
|
||||||
|
$p_ssl_protocols = json_decode($p_ssl_protocols, true);
|
||||||
|
}
|
||||||
|
if (! empty($p_ssl_protocols) && is_array($p_ssl_protocols)) {
|
||||||
|
$protocols_available = array(
|
||||||
|
'TLSv1',
|
||||||
|
'TLSv1.1',
|
||||||
|
'TLSv1.2',
|
||||||
|
'TLSv1.3'
|
||||||
|
);
|
||||||
|
foreach ($p_ssl_protocols as $ssl_protocol) {
|
||||||
|
if (! in_array(trim($ssl_protocol), $protocols_available)) {
|
||||||
|
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_DEBUG, "[API] unknown SSL protocol '" . trim($ssl_protocol) . "'");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$ssl_protocols[] = $ssl_protocol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($ssl_protocols)) {
|
||||||
|
$override_tls = '0';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$isbinddomain = '0';
|
$isbinddomain = '0';
|
||||||
if (Settings::Get('system.bind_enable') == '1') {
|
if (Settings::Get('system.bind_enable') == '1') {
|
||||||
@@ -340,6 +389,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
$writeaccesslog = '1';
|
$writeaccesslog = '1';
|
||||||
$writeerrorlog = '1';
|
$writeerrorlog = '1';
|
||||||
$documentroot = $_documentroot;
|
$documentroot = $_documentroot;
|
||||||
|
$override_tls = '0';
|
||||||
|
$ssl_protocols = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') {
|
if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') {
|
||||||
@@ -574,7 +625,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
'hsts' => $hsts_maxage,
|
'hsts' => $hsts_maxage,
|
||||||
'hsts_sub' => $hsts_sub,
|
'hsts_sub' => $hsts_sub,
|
||||||
'hsts_preload' => $hsts_preload,
|
'hsts_preload' => $hsts_preload,
|
||||||
'ocsp_stapling' => $ocsp_stapling
|
'ocsp_stapling' => $ocsp_stapling,
|
||||||
|
'override_tls' => $override_tls,
|
||||||
|
'ssl_protocols' => implode(",", $ssl_protocols),
|
||||||
|
'ssl_cipher_list' => $ssl_cipher_list,
|
||||||
|
'tlsv13_cipher_list' => $tlsv13_cipher_list
|
||||||
);
|
);
|
||||||
|
|
||||||
$ins_stmt = Database::prepare("
|
$ins_stmt = Database::prepare("
|
||||||
@@ -618,7 +673,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
`hsts` = :hsts,
|
`hsts` = :hsts,
|
||||||
`hsts_sub` = :hsts_sub,
|
`hsts_sub` = :hsts_sub,
|
||||||
`hsts_preload` = :hsts_preload,
|
`hsts_preload` = :hsts_preload,
|
||||||
`ocsp_stapling` = :ocsp_stapling
|
`ocsp_stapling` = :ocsp_stapling,
|
||||||
|
`override_tls` = :override_tls,
|
||||||
|
`ssl_protocols` = :ssl_protocols,
|
||||||
|
`ssl_cipher_list` = :ssl_cipher_list,
|
||||||
|
`tlsv13_cipher_list` = :tlsv13_cipher_list
|
||||||
");
|
");
|
||||||
Database::pexecute($ins_stmt, $ins_data, true, true);
|
Database::pexecute($ins_stmt, $ins_data, true, true);
|
||||||
$domainid = Database::lastInsertId();
|
$domainid = Database::lastInsertId();
|
||||||
@@ -823,6 +882,24 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
$hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']);
|
$hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']);
|
||||||
$ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, $result['ocsp_stapling']);
|
$ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, $result['ocsp_stapling']);
|
||||||
|
|
||||||
|
$override_tls = $this->getBoolParam('override_tls', true, $result['override_tls']);
|
||||||
|
|
||||||
|
if ($this->getUserDetail('change_serversettings') == '1') {
|
||||||
|
if ($override_tls) {
|
||||||
|
$p_ssl_protocols = $this->getParam('ssl_protocols', true, explode(',', $result['ssl_protocols']));
|
||||||
|
$ssl_cipher_list = $this->getParam('ssl_cipher_list', true, $result['ssl_cipher_list']);
|
||||||
|
$tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, $result['tlsv13_cipher_list']);
|
||||||
|
} else {
|
||||||
|
$p_ssl_protocols = array();
|
||||||
|
$ssl_cipher_list = "";
|
||||||
|
$tlsv13_cipher_list = "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$p_ssl_protocols = explode(',', $result['ssl_protocols']);
|
||||||
|
$ssl_cipher_list = $result['ssl_cipher_list'];
|
||||||
|
$tlsv13_cipher_list = $result['tlsv13_cipher_list'];
|
||||||
|
}
|
||||||
|
|
||||||
// count subdomain usage of source-domain
|
// count subdomain usage of source-domain
|
||||||
$subdomains_stmt = Database::prepare("
|
$subdomains_stmt = Database::prepare("
|
||||||
SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE
|
SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE
|
||||||
@@ -992,6 +1069,34 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
|
if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
|
||||||
\Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true);
|
\Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$ssl_protocols = array();
|
||||||
|
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
|
||||||
|
$p_ssl_protocols = array(
|
||||||
|
$p_ssl_protocols
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (! empty($p_ssl_protocols) && ! is_array($p_ssl_protocols)) {
|
||||||
|
$p_ssl_protocols = json_decode($p_ssl_protocols, true);
|
||||||
|
}
|
||||||
|
if (! empty($p_ssl_protocols) && is_array($p_ssl_protocols)) {
|
||||||
|
$protocols_available = array(
|
||||||
|
'TLSv1',
|
||||||
|
'TLSv1.1',
|
||||||
|
'TLSv1.2',
|
||||||
|
'TLSv1.3'
|
||||||
|
);
|
||||||
|
foreach ($p_ssl_protocols as $ssl_protocol) {
|
||||||
|
if (! in_array(trim($ssl_protocol), $protocols_available)) {
|
||||||
|
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_DEBUG, "[API] unknown SSL protocol '" . trim($ssl_protocol) . "'");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$ssl_protocols[] = $ssl_protocol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($ssl_protocols)) {
|
||||||
|
$override_tls = '0';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$isbinddomain = $result['isbinddomain'];
|
$isbinddomain = $result['isbinddomain'];
|
||||||
$zonefile = $result['zonefile'];
|
$zonefile = $result['zonefile'];
|
||||||
@@ -1004,6 +1109,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
$writeaccesslog = $result['writeaccesslog'];
|
$writeaccesslog = $result['writeaccesslog'];
|
||||||
$writeerrorlog = $result['writeerrorlog'];
|
$writeerrorlog = $result['writeerrorlog'];
|
||||||
$documentroot = $result['documentroot'];
|
$documentroot = $result['documentroot'];
|
||||||
|
|
||||||
|
$override_tls = $result['override_tls'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') {
|
if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') {
|
||||||
@@ -1337,6 +1444,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
$update_data['hsts_sub'] = $hsts_sub;
|
$update_data['hsts_sub'] = $hsts_sub;
|
||||||
$update_data['hsts_preload'] = $hsts_preload;
|
$update_data['hsts_preload'] = $hsts_preload;
|
||||||
$update_data['ocsp_stapling'] = $ocsp_stapling;
|
$update_data['ocsp_stapling'] = $ocsp_stapling;
|
||||||
|
$update_data['override_tls'] = $override_tls;
|
||||||
|
$update_data['ssl_protocols'] = implode(",", $ssl_protocols);
|
||||||
|
$update_data['ssl_cipher_list'] = $ssl_cipher_list;
|
||||||
|
$update_data['tlsv13_cipher_list'] = $tlsv13_cipher_list;
|
||||||
$update_data['id'] = $id;
|
$update_data['id'] = $id;
|
||||||
|
|
||||||
$update_stmt = Database::prepare("
|
$update_stmt = Database::prepare("
|
||||||
@@ -1375,7 +1486,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
`hsts` = :hsts,
|
`hsts` = :hsts,
|
||||||
`hsts_sub` = :hsts_sub,
|
`hsts_sub` = :hsts_sub,
|
||||||
`hsts_preload` = :hsts_preload,
|
`hsts_preload` = :hsts_preload,
|
||||||
`ocsp_stapling` = :ocsp_stapling
|
`ocsp_stapling` = :ocsp_stapling,
|
||||||
|
`override_tls` = :override_tls,
|
||||||
|
`ssl_protocols` = :ssl_protocols,
|
||||||
|
`ssl_cipher_list` = :ssl_cipher_list,
|
||||||
|
`tlsv13_cipher_list` = :tlsv13_cipher_list
|
||||||
WHERE `id` = :id
|
WHERE `id` = :id
|
||||||
");
|
");
|
||||||
Database::pexecute($update_stmt, $update_data, true, true);
|
Database::pexecute($update_stmt, $update_data, true, true);
|
||||||
@@ -1386,6 +1501,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
$_update_data['openbasedir'] = $openbasedir;
|
$_update_data['openbasedir'] = $openbasedir;
|
||||||
$_update_data['mod_fcgid_starter'] = $mod_fcgid_starter;
|
$_update_data['mod_fcgid_starter'] = $mod_fcgid_starter;
|
||||||
$_update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests;
|
$_update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests;
|
||||||
|
$_update_data['override_tls'] = $override_tls;
|
||||||
|
$_update_data['ssl_protocols'] = implode(",", $ssl_protocols);
|
||||||
|
$_update_data['ssl_cipher_list'] = $ssl_cipher_list;
|
||||||
|
$_update_data['tlsv13_cipher_list'] = $tlsv13_cipher_list;
|
||||||
$_update_data['parentdomainid'] = $id;
|
$_update_data['parentdomainid'] = $id;
|
||||||
|
|
||||||
// if php config is to be set for all subdomains, check here
|
// if php config is to be set for all subdomains, check here
|
||||||
@@ -1410,7 +1529,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
`phpenabled` = :phpenabled,
|
`phpenabled` = :phpenabled,
|
||||||
`openbasedir` = :openbasedir,
|
`openbasedir` = :openbasedir,
|
||||||
`mod_fcgid_starter` = :mod_fcgid_starter,
|
`mod_fcgid_starter` = :mod_fcgid_starter,
|
||||||
`mod_fcgid_maxrequests` = :mod_fcgid_maxrequests
|
`mod_fcgid_maxrequests` = :mod_fcgid_maxrequests,
|
||||||
|
`override_tls` = :override_tls,
|
||||||
|
`ssl_protocols` = :ssl_protocols,
|
||||||
|
`ssl_cipher_list` = :ssl_cipher_list,
|
||||||
|
`tlsv13_cipher_list` = :tlsv13_cipher_list
|
||||||
" . $update_phpconfig . $upd_specialsettings . $updatechildren . $update_sslredirect . "
|
" . $update_phpconfig . $upd_specialsettings . $updatechildren . $update_sslredirect . "
|
||||||
WHERE `parentdomainid` = :parentdomainid
|
WHERE `parentdomainid` = :parentdomainid
|
||||||
");
|
");
|
||||||
|
|||||||
@@ -56,7 +56,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
|||||||
throw new \Exception("You cannot access this resource", 405);
|
throw new \Exception("You cannot access this resource", 405);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->getUserDetail('ftps_used') < $this->getUserDetail('ftps') || $this->getUserDetail('ftps') == '-1') {
|
$is_defaultuser = $this->getBoolParam('is_defaultuser', true, 0);
|
||||||
|
|
||||||
|
if (($this->getUserDetail('ftps_used') < $this->getUserDetail('ftps') || $this->getUserDetail('ftps') == '-1') || $this->isAdmin() && $is_defaultuser == 1) {
|
||||||
|
|
||||||
// required paramters
|
// required paramters
|
||||||
$path = $this->getParam('path');
|
$path = $this->getParam('path');
|
||||||
@@ -71,7 +73,6 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
|||||||
$ftpdomain = $this->getParam('ftp_domain', true, '');
|
$ftpdomain = $this->getParam('ftp_domain', true, '');
|
||||||
|
|
||||||
$additional_members = $this->getParam('additional_members', true, array());
|
$additional_members = $this->getParam('additional_members', true, array());
|
||||||
$is_defaultuser = $this->getBoolParam('is_defaultuser', true, 0);
|
|
||||||
|
|
||||||
// validation
|
// validation
|
||||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||||
@@ -105,7 +106,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
|||||||
$sendinfomail = 0;
|
$sendinfomail = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings::Get('customer.ftpatdomain') == '1' && !$is_defaultuser) {
|
if (Settings::Get('customer.ftpatdomain') == '1' && ! $is_defaultuser) {
|
||||||
if ($ftpusername == '') {
|
if ($ftpusername == '') {
|
||||||
\Froxlor\UI\Response::standard_error(array(
|
\Froxlor\UI\Response::standard_error(array(
|
||||||
'stringisempty',
|
'stringisempty',
|
||||||
@@ -541,6 +542,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
|||||||
"username" => $customer_data['loginname']
|
"username" => $customer_data['loginname']
|
||||||
);
|
);
|
||||||
Database::pexecute($stmt, $params, true, true);
|
Database::pexecute($stmt, $params, true, true);
|
||||||
|
} else {
|
||||||
|
// do not allow removing default ftp-account
|
||||||
|
\Froxlor\UI\Response::standard_error('ftp_cantdeletemainaccount', '', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove all quotatallies
|
// remove all quotatallies
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
|||||||
{
|
{
|
||||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
||||||
|
|
||||||
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, false, false, true);
|
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, false, false, false, true);
|
||||||
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, 80), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
|
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, 80), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
|
||||||
'stringisempty',
|
'stringisempty',
|
||||||
'myport'
|
'myport'
|
||||||
@@ -332,7 +332,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
|||||||
'id' => $id
|
'id' => $id
|
||||||
));
|
));
|
||||||
|
|
||||||
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, false, false, true);
|
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, false, false, false, true);
|
||||||
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, $result['port']), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
|
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, $result['port']), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
|
||||||
'stringisempty',
|
'stringisempty',
|
||||||
'myport'
|
'myport'
|
||||||
|
|||||||
@@ -270,7 +270,12 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
|||||||
`http2` = :http2,
|
`http2` = :http2,
|
||||||
`hsts` = :hsts,
|
`hsts` = :hsts,
|
||||||
`hsts_sub` = :hsts_sub,
|
`hsts_sub` = :hsts_sub,
|
||||||
`hsts_preload` = :hsts_preload
|
`hsts_preload` = :hsts_preload,
|
||||||
|
`ocsp_stapling` = :ocsp_stapling,
|
||||||
|
`override_tls` = :override_tls,
|
||||||
|
`ssl_protocols` = :ssl_protocols,
|
||||||
|
`ssl_cipher_list` = :ssl_cipher_list,
|
||||||
|
`tlsv13_cipher_list` = :tlsv13_cipher_list
|
||||||
");
|
");
|
||||||
$params = array(
|
$params = array(
|
||||||
"customerid" => $customer['customerid'],
|
"customerid" => $customer['customerid'],
|
||||||
@@ -295,7 +300,12 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
|||||||
"http2" => $http2,
|
"http2" => $http2,
|
||||||
"hsts" => $hsts_maxage,
|
"hsts" => $hsts_maxage,
|
||||||
"hsts_sub" => $hsts_sub,
|
"hsts_sub" => $hsts_sub,
|
||||||
"hsts_preload" => $hsts_preload
|
"hsts_preload" => $hsts_preload,
|
||||||
|
"ocsp_stapling" => $domain_check['ocsp_stapling'],
|
||||||
|
"override_tls" => $domain_check['override_tls'],
|
||||||
|
"ssl_protocols" => $domain_check['ssl_protocols'],
|
||||||
|
"ssl_cipher_list" => $domain_check['ssl_cipher_list'],
|
||||||
|
"tlsv13_cipher_list" => $domain_check['tlsv13_cipher_list']
|
||||||
);
|
);
|
||||||
Database::pexecute($stmt, $params, true, true);
|
Database::pexecute($stmt, $params, true, true);
|
||||||
$subdomain_id = Database::lastInsertId();
|
$subdomain_id = Database::lastInsertId();
|
||||||
|
|||||||
0
lib/Froxlor/Cli/ConfigServicesCmd.php
Executable file → Normal file
0
lib/Froxlor/Cli/ConfigServicesCmd.php
Executable file → Normal file
0
lib/Froxlor/Cli/SwitchServerIpCmd.php
Executable file → Normal file
0
lib/Froxlor/Cli/SwitchServerIpCmd.php
Executable file → Normal file
@@ -178,7 +178,7 @@ class Apache extends HttpConfigBase
|
|||||||
$this->virtualhosts_data[$vhosts_filename] .= ' ServerName ' . Settings::Get('system.hostname') . "\n";
|
$this->virtualhosts_data[$vhosts_filename] .= ' ServerName ' . Settings::Get('system.hostname') . "\n";
|
||||||
|
|
||||||
$froxlor_aliases = Settings::Get('system.froxloraliases');
|
$froxlor_aliases = Settings::Get('system.froxloraliases');
|
||||||
if (!empty($froxlor_aliases)) {
|
if (! empty($froxlor_aliases)) {
|
||||||
$froxlor_aliases = explode(",", $froxlor_aliases);
|
$froxlor_aliases = explode(",", $froxlor_aliases);
|
||||||
$aliases = "";
|
$aliases = "";
|
||||||
foreach ($froxlor_aliases as $falias) {
|
foreach ($froxlor_aliases as $falias) {
|
||||||
@@ -187,7 +187,7 @@ class Apache extends HttpConfigBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aliases = trim($aliases);
|
$aliases = trim($aliases);
|
||||||
if (!empty($aliases)) {
|
if (! empty($aliases)) {
|
||||||
$this->virtualhosts_data[$vhosts_filename] .= ' ServerAlias ' . $aliases . "\n";
|
$this->virtualhosts_data[$vhosts_filename] .= ' ServerAlias ' . $aliases . "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,7 +483,7 @@ class Apache extends HttpConfigBase
|
|||||||
$this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n";
|
$this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n";
|
||||||
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
|
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
|
||||||
$protocols = array_map('trim', explode(",", Settings::Get('system.ssl_protocols')));
|
$protocols = array_map('trim', explode(",", Settings::Get('system.ssl_protocols')));
|
||||||
if (in_array("TLSv1.3", $protocols) && !empty(Settings::Get('system.tlsv13_cipher_list')) && Settings::Get('system.apache24') == 1) {
|
if (in_array("TLSv1.3", $protocols) && ! empty(Settings::Get('system.tlsv13_cipher_list')) && Settings::Get('system.apache24') == 1) {
|
||||||
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite TLSv1.3 ' . Settings::Get('system.tlsv13_cipher_list') . "\n";
|
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite TLSv1.3 ' . Settings::Get('system.tlsv13_cipher_list') . "\n";
|
||||||
}
|
}
|
||||||
$this->virtualhosts_data[$vhosts_filename] .= ' SSLVerifyDepth 10' . "\n";
|
$this->virtualhosts_data[$vhosts_filename] .= ' SSLVerifyDepth 10' . "\n";
|
||||||
@@ -967,8 +967,13 @@ class Apache extends HttpConfigBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($domain['ssl_cert_file'] != '') {
|
if ($domain['ssl_cert_file'] != '') {
|
||||||
|
|
||||||
|
$ssl_protocols = ($domain['override_tls'] == '1' && ! empty($domain['ssl_protocols'])) ? $domain['ssl_protocols'] : Settings::Get('system.ssl_protocols');
|
||||||
|
$ssl_cipher_list = ($domain['override_tls'] == '1' && ! empty($domain['ssl_cipher_list'])) ? $domain['ssl_cipher_list'] : Settings::Get('system.ssl_cipher_list');
|
||||||
|
$tlsv13_cipher_list = ($domain['override_tls'] == '1' && ! empty($domain['tlsv13_cipher_list'])) ? $domain['tlsv13_cipher_list'] : Settings::Get('system.tlsv13_cipher_list');
|
||||||
|
|
||||||
$vhost_content .= ' SSLEngine On' . "\n";
|
$vhost_content .= ' SSLEngine On' . "\n";
|
||||||
$vhost_content .= ' SSLProtocol -ALL +' . str_replace(",", " +", Settings::Get('system.ssl_protocols')) . "\n";
|
$vhost_content .= ' SSLProtocol -ALL +' . str_replace(",", " +", $ssl_protocols) . "\n";
|
||||||
if (Settings::Get('system.apache24') == '1') {
|
if (Settings::Get('system.apache24') == '1') {
|
||||||
if (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1') {
|
if (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1') {
|
||||||
$vhost_content .= ' Protocols h2 http/1.1' . "\n";
|
$vhost_content .= ' Protocols h2 http/1.1' . "\n";
|
||||||
@@ -984,10 +989,10 @@ class Apache extends HttpConfigBase
|
|||||||
}
|
}
|
||||||
// this makes it more secure, thx to Marcel (08/2013)
|
// this makes it more secure, thx to Marcel (08/2013)
|
||||||
$vhost_content .= ' SSLHonorCipherOrder On' . "\n";
|
$vhost_content .= ' SSLHonorCipherOrder On' . "\n";
|
||||||
$vhost_content .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
|
$vhost_content .= ' SSLCipherSuite ' . $ssl_cipher_list . "\n";
|
||||||
$protocols = array_map('trim', explode(",", Settings::Get('system.ssl_protocols')));
|
$protocols = array_map('trim', explode(",", $ssl_protocols));
|
||||||
if (in_array("TLSv1.3", $protocols) && !empty(Settings::Get('system.tlsv13_cipher_list')) && Settings::Get('system.apache24') == 1) {
|
if (in_array("TLSv1.3", $protocols) && ! empty($tlsv13_cipher_list) && Settings::Get('system.apache24') == 1) {
|
||||||
$vhost_content .= ' SSLCipherSuite TLSv1.3 ' . Settings::Get('system.tlsv13_cipher_list') . "\n";
|
$vhost_content .= ' SSLCipherSuite TLSv1.3 ' . $tlsv13_cipher_list . "\n";
|
||||||
}
|
}
|
||||||
$vhost_content .= ' SSLVerifyDepth 10' . "\n";
|
$vhost_content .= ' SSLVerifyDepth 10' . "\n";
|
||||||
$vhost_content .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n";
|
$vhost_content .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n";
|
||||||
|
|||||||
@@ -45,19 +45,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
|||||||
|
|
||||||
public static $no_inserttask = false;
|
public static $no_inserttask = false;
|
||||||
|
|
||||||
public static function run($internal = false)
|
private static function needRenew()
|
||||||
{
|
{
|
||||||
if (! defined('CRON_IS_FORCED') && ! defined('CRON_DEBUG_FLAG') && $internal == false) {
|
|
||||||
// FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Let's Encrypt cronjob is combined with regeneration of webserver configuration files.\nFor debugging purposes you can use the --debug switch and/or the --force switch to run the cron manually.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
self::checkInstall();
|
|
||||||
|
|
||||||
self::$apiserver = 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org/directory';
|
|
||||||
|
|
||||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Requesting/renewing Let's Encrypt certificates");
|
|
||||||
|
|
||||||
$certificates_stmt = Database::query("
|
$certificates_stmt = Database::query("
|
||||||
SELECT
|
SELECT
|
||||||
domssl.`id`,
|
domssl.`id`,
|
||||||
@@ -94,6 +83,52 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
|||||||
OR domssl.`expirationdate` IS NULL
|
OR domssl.`expirationdate` IS NULL
|
||||||
)
|
)
|
||||||
");
|
");
|
||||||
|
$customer_ssl = $certificates_stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||||
|
if (!$customer_ssl) {
|
||||||
|
$customer_ssl = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$froxlor_ssl = array();
|
||||||
|
if (Settings::Get('system.le_froxlor_enabled') == '1') {
|
||||||
|
$froxlor_ssl_settings_stmt = Database::prepare("
|
||||||
|
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
||||||
|
WHERE `domainid` = '0' AND
|
||||||
|
(`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY) OR `expirationdate` IS NULL)
|
||||||
|
");
|
||||||
|
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
|
||||||
|
if (!$froxlor_ssl) {
|
||||||
|
$froxlor_ssl = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($customer_ssl) > 0 || count($froxlor_ssl) > 0) {
|
||||||
|
return array(
|
||||||
|
'customer_ssl' => $customer_ssl,
|
||||||
|
'froxlor_ssl' => $froxlor_ssl
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function run($internal = false)
|
||||||
|
{
|
||||||
|
if (! defined('CRON_IS_FORCED') && ! defined('CRON_DEBUG_FLAG') && $internal == false) {
|
||||||
|
// Let's Encrypt cronjob is combined with regeneration of webserver configuration files.
|
||||||
|
// For debugging purposes you can use the --debug switch and the --force switch to run the cron manually.
|
||||||
|
// check whether we MIGHT need to run although there is no task to regenerate config-files
|
||||||
|
$needRenew = self::needRenew();
|
||||||
|
if ($needRenew) {
|
||||||
|
// insert task to generate certificates and vhost-configs
|
||||||
|
\Froxlor\System\Cronjob::inserttask(1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
self::checkInstall();
|
||||||
|
|
||||||
|
self::$apiserver = 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org/directory';
|
||||||
|
|
||||||
|
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Requesting/renewing Let's Encrypt certificates");
|
||||||
|
|
||||||
$aliasdomains_stmt = Database::prepare("
|
$aliasdomains_stmt = Database::prepare("
|
||||||
SELECT
|
SELECT
|
||||||
@@ -127,6 +162,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
|||||||
// flag for re-generation of vhost files
|
// flag for re-generation of vhost files
|
||||||
$changedetected = 0;
|
$changedetected = 0;
|
||||||
|
|
||||||
|
$needRenew = self::needRenew();
|
||||||
|
|
||||||
// first - generate LE for system-vhost if enabled
|
// first - generate LE for system-vhost if enabled
|
||||||
if (Settings::Get('system.le_froxlor_enabled') == '1') {
|
if (Settings::Get('system.le_froxlor_enabled') == '1') {
|
||||||
|
|
||||||
@@ -147,15 +184,10 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
|||||||
'id' => null
|
'id' => null
|
||||||
);
|
);
|
||||||
|
|
||||||
$froxlor_ssl_settings_stmt = Database::prepare("
|
$froxlor_ssl = $needRenew ? $needRenew['froxlor_ssl'] : array();
|
||||||
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
|
||||||
WHERE `domainid` = '0' AND
|
|
||||||
(`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY) OR `expirationdate` IS NULL)
|
|
||||||
");
|
|
||||||
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
|
|
||||||
|
|
||||||
$cert_mode = 'issue';
|
$cert_mode = 'issue';
|
||||||
if ($froxlor_ssl) {
|
if (count($froxlor_ssl) > 0) {
|
||||||
$cert_mode = 'renew';
|
$cert_mode = 'renew';
|
||||||
$certrow['id'] = $froxlor_ssl['id'];
|
$certrow['id'] = $froxlor_ssl['id'];
|
||||||
$certrow['expirationdate'] = $froxlor_ssl['expirationdate'];
|
$certrow['expirationdate'] = $froxlor_ssl['expirationdate'];
|
||||||
@@ -210,7 +242,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
|||||||
}
|
}
|
||||||
|
|
||||||
// customer domains
|
// customer domains
|
||||||
$certrows = $certificates_stmt->fetchAll(\PDO::FETCH_ASSOC);
|
$certrows = $needRenew ? $needRenew['customer_ssl'] : array();
|
||||||
$cert_mode = 'issue';
|
$cert_mode = 'issue';
|
||||||
foreach ($certrows as $certrow) {
|
foreach ($certrows as $certrow) {
|
||||||
|
|
||||||
@@ -390,6 +422,6 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
|||||||
$acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade");
|
$acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade");
|
||||||
// check for activated cron (which is installed automatically) but we don't need it
|
// check for activated cron (which is installed automatically) but we don't need it
|
||||||
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::$acmesh . " --uninstall-cronjob");
|
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::$acmesh . " --uninstall-cronjob");
|
||||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result)."\n".implode("\n", $acmesh_result2));
|
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result) . "\n" . implode("\n", $acmesh_result2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -570,6 +570,8 @@ class Lighttpd extends HttpConfigBase
|
|||||||
|
|
||||||
if ($domain['ssl_cert_file'] != '') {
|
if ($domain['ssl_cert_file'] != '') {
|
||||||
|
|
||||||
|
$ssl_cipher_list = ($domain['override_tls'] == '1' && ! empty($domain['ssl_cipher_list'])) ? $domain['ssl_cipher_list'] : Settings::Get('system.ssl_cipher_list');
|
||||||
|
|
||||||
// ssl.engine only necessary once in the ip/port vhost (SERVER['socket'] condition)
|
// ssl.engine only necessary once in the ip/port vhost (SERVER['socket'] condition)
|
||||||
// $ssl_settings .= 'ssl.engine = "enable"' . "\n";
|
// $ssl_settings .= 'ssl.engine = "enable"' . "\n";
|
||||||
$ssl_settings .= 'ssl.use-compression = "disable"' . "\n";
|
$ssl_settings .= 'ssl.use-compression = "disable"' . "\n";
|
||||||
@@ -583,7 +585,7 @@ class Lighttpd extends HttpConfigBase
|
|||||||
}
|
}
|
||||||
$ssl_settings .= 'ssl.use-sslv2 = "disable"' . "\n";
|
$ssl_settings .= 'ssl.use-sslv2 = "disable"' . "\n";
|
||||||
$ssl_settings .= 'ssl.use-sslv3 = "disable"' . "\n";
|
$ssl_settings .= 'ssl.use-sslv3 = "disable"' . "\n";
|
||||||
$ssl_settings .= 'ssl.cipher-list = "' . Settings::Get('system.ssl_cipher_list') . '"' . "\n";
|
$ssl_settings .= 'ssl.cipher-list = "' . $ssl_cipher_list . '"' . "\n";
|
||||||
$ssl_settings .= 'ssl.honor-cipher-order = "enable"' . "\n";
|
$ssl_settings .= 'ssl.honor-cipher-order = "enable"' . "\n";
|
||||||
$ssl_settings .= 'ssl.pemfile = "' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n";
|
$ssl_settings .= 'ssl.pemfile = "' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n";
|
||||||
|
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ class Nginx extends HttpConfigBase
|
|||||||
|
|
||||||
if (! $is_redirect) {
|
if (! $is_redirect) {
|
||||||
$this->nginx_data[$vhost_filename] .= "\tlocation ~ \.php {\n";
|
$this->nginx_data[$vhost_filename] .= "\tlocation ~ \.php {\n";
|
||||||
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_split_path_info ^(.+\.php)(/.+)\$;\n";
|
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_split_path_info ^(.+?\.php)(/.*)$;\n";
|
||||||
$this->nginx_data[$vhost_filename] .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n";
|
$this->nginx_data[$vhost_filename] .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n";
|
||||||
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n";
|
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n";
|
||||||
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n";
|
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n";
|
||||||
@@ -678,10 +678,14 @@ class Nginx extends HttpConfigBase
|
|||||||
if (! file_exists($domain_or_ip['ssl_cert_file'])) {
|
if (! file_exists($domain_or_ip['ssl_cert_file'])) {
|
||||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, $domain_or_ip['domain'] . ' :: certificate file "' . $domain_or_ip['ssl_cert_file'] . '" does not exist! Cannot create ssl-directives');
|
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, $domain_or_ip['domain'] . ' :: certificate file "' . $domain_or_ip['ssl_cert_file'] . '" does not exist! Cannot create ssl-directives');
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
$ssl_protocols = (isset($domain_or_ip['override_tls']) && $domain_or_ip['override_tls'] == '1' && ! empty($domain_or_ip['ssl_protocols'])) ? $domain_or_ip['ssl_protocols'] : Settings::Get('system.ssl_protocols');
|
||||||
|
$ssl_cipher_list = (isset($domain_or_ip['override_tls']) && $domain_or_ip['override_tls'] == '1' && ! empty($domain_or_ip['ssl_cipher_list'])) ? $domain_or_ip['ssl_cipher_list'] : Settings::Get('system.ssl_cipher_list');
|
||||||
|
|
||||||
// obsolete: ssl on now belongs to the listen block as 'ssl' at the end
|
// obsolete: ssl on now belongs to the listen block as 'ssl' at the end
|
||||||
// $sslsettings .= "\t" . 'ssl on;' . "\n";
|
// $sslsettings .= "\t" . 'ssl on;' . "\n";
|
||||||
$sslsettings .= "\t" . 'ssl_protocols ' . str_replace(",", " ", Settings::Get('system.ssl_protocols')) . ';' . "\n";
|
$sslsettings .= "\t" . 'ssl_protocols ' . str_replace(",", " ", $ssl_protocols) . ';' . "\n";
|
||||||
$sslsettings .= "\t" . 'ssl_ciphers ' . Settings::Get('system.ssl_cipher_list') . ';' . "\n";
|
$sslsettings .= "\t" . 'ssl_ciphers ' . $ssl_cipher_list . ';' . "\n";
|
||||||
if (! empty(Settings::Get('system.dhparams_file'))) {
|
if (! empty(Settings::Get('system.dhparams_file'))) {
|
||||||
$dhparams = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.dhparams_file'));
|
$dhparams = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.dhparams_file'));
|
||||||
if (! file_exists($dhparams)) {
|
if (! file_exists($dhparams)) {
|
||||||
@@ -951,7 +955,7 @@ class Nginx extends HttpConfigBase
|
|||||||
$phpopts .= "\t" . '}' . "\n\n";
|
$phpopts .= "\t" . '}' . "\n\n";
|
||||||
|
|
||||||
$phpopts .= "\tlocation @php {\n";
|
$phpopts .= "\tlocation @php {\n";
|
||||||
$phpopts .= "\t\tfastcgi_split_path_info ^(.+\.php)(/.+)\$;\n";
|
$phpopts .= "\t\tfastcgi_split_path_info ^(.+?\.php)(/.*)$;\n";
|
||||||
$phpopts .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n";
|
$phpopts .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n";
|
||||||
$phpopts .= "\t\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n";
|
$phpopts .= "\t\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n";
|
||||||
$phpopts .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n";
|
$phpopts .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n";
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class NginxFcgi extends Nginx
|
|||||||
$php_options_text .= "\t" . 'location @php {' . "\n";
|
$php_options_text .= "\t" . 'location @php {' . "\n";
|
||||||
$php_options_text .= "\t\t" . 'try_files $1 =404;' . "\n\n";
|
$php_options_text .= "\t\t" . 'try_files $1 =404;' . "\n\n";
|
||||||
$php_options_text .= "\t\t" . 'include ' . Settings::Get('nginx.fastcgiparams') . ";\n";
|
$php_options_text .= "\t\t" . 'include ' . Settings::Get('nginx.fastcgiparams') . ";\n";
|
||||||
$php_options_text .= "\t\t" . 'fastcgi_split_path_info ^(.+\.php)(/.+)\$;' . "\n";
|
$php_options_text .= "\t\t" . 'fastcgi_split_path_info ^(.+?\.php)(/.*)$;' . "\n";
|
||||||
$php_options_text .= "\t\t" . 'fastcgi_param SCRIPT_FILENAME $request_filename;' . "\n";
|
$php_options_text .= "\t\t" . 'fastcgi_param SCRIPT_FILENAME $request_filename;' . "\n";
|
||||||
$php_options_text .= "\t\t" . 'fastcgi_param PATH_INFO $2;' . "\n";
|
$php_options_text .= "\t\t" . 'fastcgi_param PATH_INFO $2;' . "\n";
|
||||||
if ($domain['ssl'] == '1' && $ssl_vhost) {
|
if ($domain['ssl'] == '1' && $ssl_vhost) {
|
||||||
|
|||||||
@@ -36,9 +36,7 @@ class WebserverBase
|
|||||||
`d`.`phpsettingid`, `c`.`adminid`, `c`.`guid`, `c`.`email`,
|
`d`.`phpsettingid`, `c`.`adminid`, `c`.`guid`, `c`.`email`,
|
||||||
`c`.`documentroot` AS `customerroot`, `c`.`deactivated`,
|
`c`.`documentroot` AS `customerroot`, `c`.`deactivated`,
|
||||||
`c`.`phpenabled` AS `phpenabled_customer`,
|
`c`.`phpenabled` AS `phpenabled_customer`,
|
||||||
`d`.`phpenabled` AS `phpenabled_vhost`,
|
`d`.`phpenabled` AS `phpenabled_vhost`
|
||||||
`d`.`mod_fcgid_starter`,`d`.`mod_fcgid_maxrequests`,
|
|
||||||
`d`.`ocsp_stapling`
|
|
||||||
FROM `" . TABLE_PANEL_DOMAINS . "` `d`
|
FROM `" . TABLE_PANEL_DOMAINS . "` `d`
|
||||||
|
|
||||||
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`)
|
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`)
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ final class Froxlor
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Main version variable
|
// Main version variable
|
||||||
const VERSION = '0.10.2';
|
const VERSION = '0.10.5';
|
||||||
|
|
||||||
// Database version (YYYYMMDDC where C is a daily counter)
|
// Database version (YYYYMMDDC where C is a daily counter)
|
||||||
const DBVERSION = '201910120';
|
const DBVERSION = '201910200';
|
||||||
|
|
||||||
// Distribution branding-tag (used for Debian etc.)
|
// Distribution branding-tag (used for Debian etc.)
|
||||||
const BRANDING = '';
|
const BRANDING = '';
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ class FroxlorLogger
|
|||||||
self::$ml->pushHandler(new SyslogHandler('froxlor', LOG_USER, Logger::DEBUG));
|
self::$ml->pushHandler(new SyslogHandler('froxlor', LOG_USER, Logger::DEBUG));
|
||||||
break;
|
break;
|
||||||
case 'file':
|
case 'file':
|
||||||
|
if (empty(Settings::Get('logger.logfile')) || ! is_writeable(Settings::Get('logger.logfile'))) {
|
||||||
|
Settings::Set('logger.logfile', '/tmp/froxlor.log');
|
||||||
|
}
|
||||||
self::$ml->pushHandler(new StreamHandler(Settings::Get('logger.logfile'), Logger::DEBUG));
|
self::$ml->pushHandler(new StreamHandler(Settings::Get('logger.logfile'), Logger::DEBUG));
|
||||||
break;
|
break;
|
||||||
case 'mysql':
|
case 'mysql':
|
||||||
|
|||||||
@@ -252,6 +252,28 @@ class Store
|
|||||||
|
|
||||||
public static function storeSettingMysqlAccessHost($fieldname, $fielddata, $newfieldvalue)
|
public static function storeSettingMysqlAccessHost($fieldname, $fielddata, $newfieldvalue)
|
||||||
{
|
{
|
||||||
|
$ips = $newfieldvalue;
|
||||||
|
// Convert cidr to netmask for mysql, if needed be
|
||||||
|
if (strpos($ips, ',') !== false) {
|
||||||
|
$ips = explode(',', $ips);
|
||||||
|
}
|
||||||
|
if (is_array($ips) && count($ips) > 0) {
|
||||||
|
$newfieldvalue = [];
|
||||||
|
foreach ($ips as $ip) {
|
||||||
|
$org_ip = $ip;
|
||||||
|
$ip_cidr = explode("/", $ip);
|
||||||
|
if (count($ip_cidr) === 2) {
|
||||||
|
$ip = $ip_cidr[0];
|
||||||
|
if (strlen($ip_cidr[1]) <= 2) {
|
||||||
|
$ip_cidr[1] = \Froxlor\Validate\Validate::cidr2NetmaskAddr($org_ip);
|
||||||
|
}
|
||||||
|
$newfieldvalue[] = $ip . '/' . $ip_cidr[1];
|
||||||
|
} else {
|
||||||
|
$newfieldvalue[] = $org_ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$newfieldvalue = implode(',', $newfieldvalue);
|
||||||
|
}
|
||||||
$returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
|
$returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
|
||||||
|
|
||||||
if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'mysql_access_host') {
|
if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'mysql_access_host') {
|
||||||
|
|||||||
@@ -77,8 +77,7 @@ class Check
|
|||||||
$mysql_access_host_array = array_map('trim', explode(',', $newfieldvalue));
|
$mysql_access_host_array = array_map('trim', explode(',', $newfieldvalue));
|
||||||
|
|
||||||
foreach ($mysql_access_host_array as $host_entry) {
|
foreach ($mysql_access_host_array as $host_entry) {
|
||||||
|
if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true, true, true, false) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
|
||||||
if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
|
|
||||||
return array(
|
return array(
|
||||||
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
|
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
|
||||||
'invalidmysqlhost',
|
'invalidmysqlhost',
|
||||||
|
|||||||
@@ -62,6 +62,38 @@ class Validate
|
|||||||
\Froxlor\UI\Response::standard_error($lng, $fieldname, $throw_exception);
|
\Froxlor\UI\Response::standard_error($lng, $fieldname, $throw_exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts CIDR to a netmask address
|
||||||
|
*
|
||||||
|
* @thx to https://stackoverflow.com/a/5711080/3020926
|
||||||
|
* @param string $cidr
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function cidr2NetmaskAddr($cidr)
|
||||||
|
{
|
||||||
|
$ta = substr($cidr, strpos($cidr, '/') + 1) * 1;
|
||||||
|
$netmask = str_split(str_pad(str_pad('', $ta, '1'), 32, '0'), 8);
|
||||||
|
|
||||||
|
foreach ($netmask as &$element) {
|
||||||
|
$element = bindec($element);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('.', $netmask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if an $address (IP) is IPv6
|
||||||
|
*
|
||||||
|
* @param string $address
|
||||||
|
*
|
||||||
|
* @return string|bool ip address on success, false on failure
|
||||||
|
*/
|
||||||
|
public static function is_ipv6($address)
|
||||||
|
{
|
||||||
|
return filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether it is a valid ip
|
* Checks whether it is a valid ip
|
||||||
*
|
*
|
||||||
@@ -77,17 +109,35 @@ class Validate
|
|||||||
* whether to allow private network addresses
|
* whether to allow private network addresses
|
||||||
* @param bool $allow_cidr
|
* @param bool $allow_cidr
|
||||||
* whether to allow CIDR values e.g. 10.10.10.10/16
|
* whether to allow CIDR values e.g. 10.10.10.10/16
|
||||||
|
* @param bool $cidr_as_netmask
|
||||||
|
* whether to format CIDR nodation to netmask notation
|
||||||
|
* @param bool $throw_exception
|
||||||
|
* whether to throw an exception on failure
|
||||||
*
|
*
|
||||||
* @return string|bool ip address on success, false on failure
|
* @return string|bool ip address on success, false on failure
|
||||||
*/
|
*/
|
||||||
public static function validate_ip2($ip, $return_bool = false, $lng = 'invalidip', $allow_localhost = false, $allow_priv = false, $allow_cidr = false, $throw_exception = false)
|
public static function validate_ip2($ip, $return_bool = false, $lng = 'invalidip', $allow_localhost = false, $allow_priv = false, $allow_cidr = false, $cidr_as_netmask = false, $throw_exception = false)
|
||||||
{
|
{
|
||||||
$cidr = "";
|
$cidr = "";
|
||||||
if ($allow_cidr) {
|
if ($allow_cidr) {
|
||||||
$org_ip = $ip;
|
$org_ip = $ip;
|
||||||
$ip_cidr = explode("/", $ip);
|
$ip_cidr = explode("/", $ip);
|
||||||
if (count($ip_cidr) == 2) {
|
if (count($ip_cidr) === 2) {
|
||||||
|
if (strlen($ip_cidr[1]) <= 2 && in_array((int) $ip_cidr[1], array_values(range(1, 32)), true) === false) {
|
||||||
|
\Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception);
|
||||||
|
}
|
||||||
|
if ($cidr_as_netmask && self::is_ipv6($ip_cidr[0])) {
|
||||||
|
// MySQL does not handle CIDR of IPv6 addresses, return error
|
||||||
|
if ($return_bool) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
\Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
$ip = $ip_cidr[0];
|
$ip = $ip_cidr[0];
|
||||||
|
if ($cidr_as_netmask && strlen($ip_cidr[1]) <= 2) {
|
||||||
|
$ip_cidr[1] = self::cidr2NetmaskAddr($org_ip);
|
||||||
|
}
|
||||||
$cidr = "/" . $ip_cidr[1];
|
$cidr = "/" . $ip_cidr[1];
|
||||||
} else {
|
} else {
|
||||||
$ip = $org_ip;
|
$ip = $org_ip;
|
||||||
|
|||||||
@@ -180,6 +180,12 @@ return array(
|
|||||||
'image' => 'icons/domain_add.png',
|
'image' => 'icons/domain_add.png',
|
||||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
|
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
|
||||||
'fields' => array(
|
'fields' => array(
|
||||||
|
'no_ssl_available_info' => array(
|
||||||
|
'visible' => ($ssl_ipsandports == '' ? true : false),
|
||||||
|
'label' => 'SSL',
|
||||||
|
'type' => 'label',
|
||||||
|
'value' => $lng['panel']['nosslipsavailable']
|
||||||
|
),
|
||||||
'ssl_ipandport' => array(
|
'ssl_ipandport' => array(
|
||||||
'label' => $lng['domains']['ipandport_ssl_multi']['title'],
|
'label' => $lng['domains']['ipandport_ssl_multi']['title'],
|
||||||
'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
|
'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
|
||||||
@@ -188,26 +194,6 @@ return array(
|
|||||||
'value' => explode(',', \Froxlor\Settings::Get('system.defaultsslip')),
|
'value' => explode(',', \Froxlor\Settings::Get('system.defaultsslip')),
|
||||||
'is_array' => 1
|
'is_array' => 1
|
||||||
),
|
),
|
||||||
'ssl_specialsettings' => array(
|
|
||||||
'visible' => ($userinfo['change_serversettings'] == '1' ? true : false),
|
|
||||||
'style' => 'align-top',
|
|
||||||
'label' => $lng['admin']['ownsslvhostsettings'],
|
|
||||||
'desc' => $lng['serversettings']['default_vhostconf']['description'],
|
|
||||||
'type' => 'textarea',
|
|
||||||
'cols' => 60,
|
|
||||||
'rows' => 12
|
|
||||||
),
|
|
||||||
'include_specialsettings' => array(
|
|
||||||
'label' => $lng['admin']['include_ownvhostsettings'],
|
|
||||||
'type' => 'checkbox',
|
|
||||||
'values' => array(
|
|
||||||
array(
|
|
||||||
'label' => $lng['panel']['yes'],
|
|
||||||
'value' => '1'
|
|
||||||
)
|
|
||||||
),
|
|
||||||
'value' => array()
|
|
||||||
),
|
|
||||||
'ssl_redirect' => array(
|
'ssl_redirect' => array(
|
||||||
'visible' => ($ssl_ipsandports != '' ? true : false),
|
'visible' => ($ssl_ipsandports != '' ? true : false),
|
||||||
'label' => $lng['domains']['ssl_redirect']['title'],
|
'label' => $lng['domains']['ssl_redirect']['title'],
|
||||||
@@ -247,11 +233,81 @@ return array(
|
|||||||
),
|
),
|
||||||
'value' => array()
|
'value' => array()
|
||||||
),
|
),
|
||||||
'no_ssl_available_info' => array(
|
'override_tls' => array(
|
||||||
'visible' => ($ssl_ipsandports == '' ? true : false),
|
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
|
||||||
'label' => 'SSL',
|
'label' => $lng['admin']['domain_override_tls'],
|
||||||
'type' => 'label',
|
'type' => 'checkbox',
|
||||||
'value' => $lng['panel']['nosslipsavailable']
|
'values' => array(
|
||||||
|
array(
|
||||||
|
'label' => $lng['panel']['yes'],
|
||||||
|
'value' => '1'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'value' => array()
|
||||||
|
),
|
||||||
|
'ssl_protocols' => array(
|
||||||
|
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' && \Froxlor\Settings::Get('system.webserver') != 'lighttpd' ? true : false),
|
||||||
|
'label' => $lng['serversettings']['ssl']['ssl_protocols']['title'],
|
||||||
|
'desc' => $lng['serversettings']['ssl']['ssl_protocols']['description'],
|
||||||
|
'type' => 'checkbox',
|
||||||
|
'value' => array(
|
||||||
|
'TLSv1',
|
||||||
|
'TLSv1.2'
|
||||||
|
),
|
||||||
|
'values' => array(
|
||||||
|
array(
|
||||||
|
'value' => 'TLSv1',
|
||||||
|
'label' => 'TLSv1<br />'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'value' => 'TLSv1.1',
|
||||||
|
'label' => 'TLSv1.1<br />'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'value' => 'TLSv1.2',
|
||||||
|
'label' => 'TLSv1.2<br />'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'value' => 'TLSv1.3',
|
||||||
|
'label' => 'TLSv1.3<br />'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'is_array' => 1
|
||||||
|
),
|
||||||
|
'ssl_cipher_list' => array(
|
||||||
|
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
|
||||||
|
'label' => $lng['serversettings']['ssl']['ssl_cipher_list']['title'],
|
||||||
|
'desc' => $lng['serversettings']['ssl']['ssl_cipher_list']['description'],
|
||||||
|
'type' => 'text',
|
||||||
|
'value' => \Froxlor\Settings::Get('system.ssl_cipher_list')
|
||||||
|
),
|
||||||
|
'tlsv13_cipher_list' => array(
|
||||||
|
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' && \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1 ? true : false),
|
||||||
|
'label' => $lng['serversettings']['ssl']['tlsv13_cipher_list']['title'],
|
||||||
|
'desc' => $lng['serversettings']['ssl']['tlsv13_cipher_list']['description'],
|
||||||
|
'type' => 'text',
|
||||||
|
'value' => \Froxlor\Settings::Get('system.tlsv13_cipher_list')
|
||||||
|
),
|
||||||
|
'ssl_specialsettings' => array(
|
||||||
|
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
|
||||||
|
'style' => 'align-top',
|
||||||
|
'label' => $lng['admin']['ownsslvhostsettings'],
|
||||||
|
'desc' => $lng['serversettings']['default_vhostconf']['description'],
|
||||||
|
'type' => 'textarea',
|
||||||
|
'cols' => 60,
|
||||||
|
'rows' => 12
|
||||||
|
),
|
||||||
|
'include_specialsettings' => array(
|
||||||
|
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
|
||||||
|
'label' => $lng['admin']['include_ownvhostsettings'],
|
||||||
|
'type' => 'checkbox',
|
||||||
|
'values' => array(
|
||||||
|
array(
|
||||||
|
'label' => $lng['panel']['yes'],
|
||||||
|
'value' => '1'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'value' => array()
|
||||||
),
|
),
|
||||||
'hsts_maxage' => array(
|
'hsts_maxage' => array(
|
||||||
'visible' => ($ssl_ipsandports != '' ? true : false),
|
'visible' => ($ssl_ipsandports != '' ? true : false),
|
||||||
|
|||||||
@@ -212,6 +212,12 @@ return array(
|
|||||||
'image' => 'icons/domain_edit.png',
|
'image' => 'icons/domain_edit.png',
|
||||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
|
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
|
||||||
'fields' => array(
|
'fields' => array(
|
||||||
|
'no_ssl_available_info' => array(
|
||||||
|
'visible' => ($ssl_ipsandports == '' ? true : false),
|
||||||
|
'label' => 'SSL',
|
||||||
|
'type' => 'label',
|
||||||
|
'value' => $lng['panel']['nosslipsavailable']
|
||||||
|
),
|
||||||
'ssl_ipandport' => array(
|
'ssl_ipandport' => array(
|
||||||
'label' => $lng['domains']['ipandport_ssl_multi']['title'],
|
'label' => $lng['domains']['ipandport_ssl_multi']['title'],
|
||||||
'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
|
'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
|
||||||
@@ -220,29 +226,6 @@ return array(
|
|||||||
'value' => $usedips,
|
'value' => $usedips,
|
||||||
'is_array' => 1
|
'is_array' => 1
|
||||||
),
|
),
|
||||||
'ssl_specialsettings' => array(
|
|
||||||
'visible' => ($userinfo['change_serversettings'] == '1' ? true : false),
|
|
||||||
'style' => 'align-top',
|
|
||||||
'label' => $lng['admin']['ownsslvhostsettings'],
|
|
||||||
'desc' => $lng['serversettings']['default_vhostconf']['description'],
|
|
||||||
'type' => 'textarea',
|
|
||||||
'cols' => 60,
|
|
||||||
'rows' => 12,
|
|
||||||
'value' => $result['ssl_specialsettings']
|
|
||||||
),
|
|
||||||
'include_specialsettings' => array(
|
|
||||||
'label' => $lng['admin']['include_ownvhostsettings'],
|
|
||||||
'type' => 'checkbox',
|
|
||||||
'values' => array(
|
|
||||||
array(
|
|
||||||
'label' => $lng['panel']['yes'],
|
|
||||||
'value' => '1'
|
|
||||||
)
|
|
||||||
),
|
|
||||||
'value' => array(
|
|
||||||
$result['include_specialsettings']
|
|
||||||
)
|
|
||||||
),
|
|
||||||
'ssl_redirect' => array(
|
'ssl_redirect' => array(
|
||||||
'visible' => ($ssl_ipsandports != '' ? true : false),
|
'visible' => ($ssl_ipsandports != '' ? true : false),
|
||||||
'label' => $lng['domains']['ssl_redirect']['title'],
|
'label' => $lng['domains']['ssl_redirect']['title'],
|
||||||
@@ -288,11 +271,82 @@ return array(
|
|||||||
$result['http2']
|
$result['http2']
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'no_ssl_available_info' => array(
|
'override_tls' => array(
|
||||||
'visible' => ($ssl_ipsandports == '' ? true : false),
|
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
|
||||||
'label' => 'SSL',
|
'label' => $lng['admin']['domain_override_tls'],
|
||||||
'type' => 'label',
|
'type' => 'checkbox',
|
||||||
'value' => $lng['panel']['nosslipsavailable']
|
'values' => array(
|
||||||
|
array(
|
||||||
|
'label' => $lng['panel']['yes'],
|
||||||
|
'value' => '1'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'value' => array(
|
||||||
|
$result['override_tls']
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'ssl_protocols' => array(
|
||||||
|
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' && \Froxlor\Settings::Get('system.webserver') != 'lighttpd' ? true : false),
|
||||||
|
'label' => $lng['serversettings']['ssl']['ssl_protocols']['title'],
|
||||||
|
'desc' => $lng['serversettings']['ssl']['ssl_protocols']['description'],
|
||||||
|
'type' => 'checkbox',
|
||||||
|
'value' => !empty($result['ssl_protocols']) ? explode(",", $result['ssl_protocols']) : explode(",", \Froxlor\Settings::Get('system.ssl_protocols')),
|
||||||
|
'values' => array(
|
||||||
|
array(
|
||||||
|
'value' => 'TLSv1',
|
||||||
|
'label' => 'TLSv1<br />'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'value' => 'TLSv1.1',
|
||||||
|
'label' => 'TLSv1.1<br />'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'value' => 'TLSv1.2',
|
||||||
|
'label' => 'TLSv1.2<br />'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'value' => 'TLSv1.3',
|
||||||
|
'label' => 'TLSv1.3<br />'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'is_array' => 1
|
||||||
|
),
|
||||||
|
'ssl_cipher_list' => array(
|
||||||
|
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
|
||||||
|
'label' => $lng['serversettings']['ssl']['ssl_cipher_list']['title'],
|
||||||
|
'desc' => $lng['serversettings']['ssl']['ssl_cipher_list']['description'],
|
||||||
|
'type' => 'text',
|
||||||
|
'value' => !empty($result['ssl_cipher_list']) ? $result['ssl_cipher_list'] : \Froxlor\Settings::Get('system.ssl_cipher_list')
|
||||||
|
),
|
||||||
|
'tlsv13_cipher_list' => array(
|
||||||
|
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' && \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1 ? true : false),
|
||||||
|
'label' => $lng['serversettings']['ssl']['tlsv13_cipher_list']['title'],
|
||||||
|
'desc' => $lng['serversettings']['ssl']['tlsv13_cipher_list']['description'],
|
||||||
|
'type' => 'text',
|
||||||
|
'value' => !empty($result['tlsv13_cipher_list']) ? $result['tlsv13_cipher_list'] : \Froxlor\Settings::Get('system.tlsv13_cipher_list')
|
||||||
|
),
|
||||||
|
'ssl_specialsettings' => array(
|
||||||
|
'visible' => ($userinfo['change_serversettings'] == '1' ? true : false),
|
||||||
|
'style' => 'align-top',
|
||||||
|
'label' => $lng['admin']['ownsslvhostsettings'],
|
||||||
|
'desc' => $lng['serversettings']['default_vhostconf']['description'],
|
||||||
|
'type' => 'textarea',
|
||||||
|
'cols' => 60,
|
||||||
|
'rows' => 12,
|
||||||
|
'value' => $result['ssl_specialsettings']
|
||||||
|
),
|
||||||
|
'include_specialsettings' => array(
|
||||||
|
'label' => $lng['admin']['include_ownvhostsettings'],
|
||||||
|
'type' => 'checkbox',
|
||||||
|
'values' => array(
|
||||||
|
array(
|
||||||
|
'label' => $lng['panel']['yes'],
|
||||||
|
'value' => '1'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'value' => array(
|
||||||
|
$result['include_specialsettings']
|
||||||
|
)
|
||||||
),
|
),
|
||||||
'hsts_maxage' => array(
|
'hsts_maxage' => array(
|
||||||
'visible' => ($ssl_ipsandports != '' ? true : false),
|
'visible' => ($ssl_ipsandports != '' ? true : false),
|
||||||
|
|||||||
@@ -569,7 +569,7 @@ $lng['serversettings']['apacheconf_htpasswddir']['description'] = 'Where should
|
|||||||
|
|
||||||
$lng['error']['formtokencompromised'] = 'The request seems to be compromised. For security reasons you were logged out.';
|
$lng['error']['formtokencompromised'] = 'The request seems to be compromised. For security reasons you were logged out.';
|
||||||
$lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts';
|
$lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts';
|
||||||
$lng['serversettings']['mysql_access_host']['description'] = 'A comma separated list of hosts from which users should be allowed to connect to the MySQL-Server.';
|
$lng['serversettings']['mysql_access_host']['description'] = 'A comma separated list of hosts from which users should be allowed to connect to the MySQL-Server. To allow a subnet the netmask or cidr syntax is valid.';
|
||||||
|
|
||||||
// ADDED IN 1.2.18-svn1
|
// ADDED IN 1.2.18-svn1
|
||||||
|
|
||||||
@@ -2078,3 +2078,4 @@ $lng['serversettings']['includedefault_sslvhostconf'] = 'Include non-SSL vHost-s
|
|||||||
$lng['admin']['ownsslvhostsettings'] = 'Own SSL vHost-settings';
|
$lng['admin']['ownsslvhostsettings'] = 'Own SSL vHost-settings';
|
||||||
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Default SSL vHost-settings for every domain container';
|
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Default SSL vHost-settings for every domain container';
|
||||||
$lng['customer']['total_diskspace'] = 'Total diskspace (MiB)';
|
$lng['customer']['total_diskspace'] = 'Total diskspace (MiB)';
|
||||||
|
$lng['admin']['domain_override_tls'] = 'Override system TLS settings';
|
||||||
|
|||||||
@@ -564,7 +564,7 @@ $lng['serversettings']['apacheconf_htpasswddir']['description'] = 'Wo sollen die
|
|||||||
|
|
||||||
$lng['error']['formtokencompromised'] = 'Das Formular scheint manipuliert worden zu sein. Aus Sicherheitsgründen wurden Sie ausgelogged.';
|
$lng['error']['formtokencompromised'] = 'Das Formular scheint manipuliert worden zu sein. Aus Sicherheitsgründen wurden Sie ausgelogged.';
|
||||||
$lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts';
|
$lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts';
|
||||||
$lng['serversettings']['mysql_access_host']['description'] = 'Eine durch Komma getrennte Liste mit den Hostnamen aller Hostnames/IP-Adressen, von denen sich die Benutzer einloggen dürfen.';
|
$lng['serversettings']['mysql_access_host']['description'] = 'Eine durch Komma getrennte Liste mit den Hostnamen aller Hostnames/IP-Adressen, von denen sich die Benutzer einloggen dürfen. Um ein Subnetz zu erlauben ist die Netzmaske oder CIDR Syntax erlaubt.';
|
||||||
|
|
||||||
// ADDED IN 1.2.18-svn1
|
// ADDED IN 1.2.18-svn1
|
||||||
|
|
||||||
@@ -1725,3 +1725,4 @@ $lng['serversettings']['includedefault_sslvhostconf'] = 'Nicht-SSL vHost-Einstel
|
|||||||
$lng['admin']['ownsslvhostsettings'] = 'Eigene SSL vHost-Einstellungen';
|
$lng['admin']['ownsslvhostsettings'] = 'Eigene SSL vHost-Einstellungen';
|
||||||
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Standard SSL vHost-Einstellungen für jeden Domain-Container';
|
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Standard SSL vHost-Einstellungen für jeden Domain-Container';
|
||||||
$lng['customer']['total_diskspace'] = 'Gesamtspeicherplatz (MiB)';
|
$lng['customer']['total_diskspace'] = 'Gesamtspeicherplatz (MiB)';
|
||||||
|
$lng['admin']['domain_override_tls'] = 'Überschreibe System TLS Einstellungen';
|
||||||
|
|||||||
@@ -189,7 +189,6 @@ class CertificatesTest extends TestCase
|
|||||||
));
|
));
|
||||||
|
|
||||||
// export
|
// export
|
||||||
openssl_csr_export($csr, $csrout);
|
|
||||||
openssl_x509_export($sscert, $certout);
|
openssl_x509_export($sscert, $certout);
|
||||||
openssl_pkey_export($privkey, $pkeyout, null);
|
openssl_pkey_export($privkey, $pkeyout, null);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use Froxlor\Database\Database;
|
|||||||
use Froxlor\Api\Commands\Admins;
|
use Froxlor\Api\Commands\Admins;
|
||||||
use Froxlor\Api\Commands\Customers;
|
use Froxlor\Api\Commands\Customers;
|
||||||
use Froxlor\Api\Commands\SubDomains;
|
use Froxlor\Api\Commands\SubDomains;
|
||||||
|
use Froxlor\Api\Commands\Ftps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -61,7 +62,9 @@ class CustomersTest extends TestCase
|
|||||||
$this->assertEquals('secret', $result['custom_notes']);
|
$this->assertEquals('secret', $result['custom_notes']);
|
||||||
|
|
||||||
// validate that the std-subdomain has been added
|
// validate that the std-subdomain has been added
|
||||||
$json_result = SubDomains::getLocal($admin_userdata, array('id' => $result['standardsubdomain']))->get();
|
$json_result = SubDomains::getLocal($admin_userdata, array(
|
||||||
|
'id' => $result['standardsubdomain']
|
||||||
|
))->get();
|
||||||
$result = json_decode($json_result, true)['data'];
|
$result = json_decode($json_result, true)['data'];
|
||||||
$this->assertEquals('test1.dev.froxlor.org', $result['domain']);
|
$this->assertEquals('test1.dev.froxlor.org', $result['domain']);
|
||||||
}
|
}
|
||||||
@@ -555,4 +558,49 @@ class CustomersTest extends TestCase
|
|||||||
$this->expectExceptionMessage('Loginname contains too many characters. Only ' . (\Froxlor\Database\Database::getSqlUsernameLength() - strlen(Settings::Get('customer.mysqlprefix'))) . ' characters are allowed.');
|
$this->expectExceptionMessage('Loginname contains too many characters. Only ' . (\Froxlor\Database\Database::getSqlUsernameLength() - strlen(Settings::Get('customer.mysqlprefix'))) . ' characters are allowed.');
|
||||||
Customers::getLocal($admin_userdata, $data)->add();
|
Customers::getLocal($admin_userdata, $data)->add();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @depends testAdminCustomersAddAutoLoginname
|
||||||
|
*/
|
||||||
|
public function testResellerCustomersAddNoFtpValidateDefaultUserExists()
|
||||||
|
{
|
||||||
|
global $admin_userdata;
|
||||||
|
// get reseller
|
||||||
|
$json_result = Admins::getLocal($admin_userdata, array(
|
||||||
|
'loginname' => 'reseller'
|
||||||
|
))->get();
|
||||||
|
$reseller_userdata = json_decode($json_result, true)['data'];
|
||||||
|
$reseller_userdata['adminsession'] = 1;
|
||||||
|
|
||||||
|
// set available ftp resources to 0 to validate that when the customer
|
||||||
|
// is added the default ftp user for the customer is created too regardless of
|
||||||
|
// available resource of the reseller/admin
|
||||||
|
$reseller_userdata['ftps'] = 0;
|
||||||
|
|
||||||
|
// add new customer
|
||||||
|
$data = [
|
||||||
|
'new_loginname' => 'testftpx',
|
||||||
|
'email' => 'testftp@froxlor.org',
|
||||||
|
'firstname' => 'Test',
|
||||||
|
'name' => 'Ftpman',
|
||||||
|
'customernumber' => 1339,
|
||||||
|
'new_customer_password' => 'h0lYmo1y'
|
||||||
|
];
|
||||||
|
Customers::getLocal($reseller_userdata, $data)->add();
|
||||||
|
|
||||||
|
// get FTP user
|
||||||
|
$json_result = Ftps::getLocal($reseller_userdata, [
|
||||||
|
'username' => 'testftpx'
|
||||||
|
])->get();
|
||||||
|
$ftp_data = json_decode($json_result, true)['data'];
|
||||||
|
$this->assertEquals("testftpx", $ftp_data['username']);
|
||||||
|
|
||||||
|
// now get rid of the customer again
|
||||||
|
$json_result = Customers::getLocal($reseller_userdata, array(
|
||||||
|
'loginname' => 'testftpx'
|
||||||
|
))->delete();
|
||||||
|
$result = json_decode($json_result, true)['data'];
|
||||||
|
$this->assertEquals('testftpx', $result['loginname']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,11 +26,17 @@ class DomainsTest extends TestCase
|
|||||||
$customer_userdata = json_decode($json_result, true)['data'];
|
$customer_userdata = json_decode($json_result, true)['data'];
|
||||||
$data = [
|
$data = [
|
||||||
'domain' => 'test.local',
|
'domain' => 'test.local',
|
||||||
'customerid' => $customer_userdata['customerid']
|
'customerid' => $customer_userdata['customerid'],
|
||||||
|
'override_tls' => 1,
|
||||||
|
'ssl_protocols' => array(
|
||||||
|
'TLSv1.2',
|
||||||
|
'TLSv1.3'
|
||||||
|
)
|
||||||
];
|
];
|
||||||
$json_result = Domains::getLocal($admin_userdata, $data)->add();
|
$json_result = Domains::getLocal($admin_userdata, $data)->add();
|
||||||
$result = json_decode($json_result, true)['data'];
|
$result = json_decode($json_result, true)['data'];
|
||||||
$this->assertEquals($customer_userdata['documentroot'] . 'test.local/', $result['documentroot']);
|
$this->assertEquals($customer_userdata['documentroot'] . 'test.local/', $result['documentroot']);
|
||||||
|
$this->assertTrue(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,11 +159,13 @@ class DomainsTest extends TestCase
|
|||||||
global $admin_userdata;
|
global $admin_userdata;
|
||||||
$data = [
|
$data = [
|
||||||
'domainname' => 'test.local',
|
'domainname' => 'test.local',
|
||||||
'email_only' => 1
|
'email_only' => 1,
|
||||||
|
'override_tls' => 0
|
||||||
];
|
];
|
||||||
$json_result = Domains::getLocal($admin_userdata, $data)->update();
|
$json_result = Domains::getLocal($admin_userdata, $data)->update();
|
||||||
$result = json_decode($json_result, true)['data'];
|
$result = json_decode($json_result, true)['data'];
|
||||||
$this->assertEquals(1, $result['email_only']);
|
$this->assertEquals(1, $result['email_only']);
|
||||||
|
$this->assertFalse(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class ValidateTest extends TestCase
|
|||||||
|
|
||||||
public function testValidateIp()
|
public function testValidateIp()
|
||||||
{
|
{
|
||||||
$result = Validate::validate_ip2("12.34.56.78", false, 'invalidip', false, false, false, true);
|
$result = Validate::validate_ip2("12.34.56.78", false, 'invalidip', false, false, false, false, true);
|
||||||
$this->assertEquals("12.34.56.78", $result);
|
$this->assertEquals("12.34.56.78", $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,12 +58,12 @@ class ValidateTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->expectException("Exception");
|
$this->expectException("Exception");
|
||||||
$this->expectExceptionCode(400);
|
$this->expectExceptionCode(400);
|
||||||
Validate::validate_ip2("10.0.0.1", false, 'invalidip', false, false, false, true);
|
Validate::validate_ip2("10.0.0.1", false, 'invalidip', false, false, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateIpPrivNotAllowedBool()
|
public function testValidateIpPrivNotAllowedBool()
|
||||||
{
|
{
|
||||||
$result = Validate::validate_ip2("10.0.0.1", true, 'invalidip', false, false, false, true);
|
$result = Validate::validate_ip2("10.0.0.1", true, 'invalidip', false, false, false, false, true);
|
||||||
$this->assertFalse($result);
|
$this->assertFalse($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,34 +71,65 @@ class ValidateTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->expectException("Exception");
|
$this->expectException("Exception");
|
||||||
$this->expectExceptionCode(400);
|
$this->expectExceptionCode(400);
|
||||||
Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, false, true);
|
Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateIpCidrNotAllowedBool()
|
public function testValidateIpCidrNotAllowedBool()
|
||||||
{
|
{
|
||||||
$result = Validate::validate_ip2("12.34.56.78/24", true, 'invalidip', false, false, false, true);
|
$result = Validate::validate_ip2("12.34.56.78/24", true, 'invalidip', false, false, false, false, true);
|
||||||
$this->assertFalse($result);
|
$this->assertFalse($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateIpCidr()
|
public function testValidateIpCidr()
|
||||||
{
|
{
|
||||||
$result = Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, true, true);
|
$result = Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, true, false, true);
|
||||||
$this->assertEquals("12.34.56.78/24", $result);
|
$this->assertEquals("12.34.56.78/24", $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testValidateIpv6Disallowed()
|
||||||
|
{
|
||||||
|
$this->expectException("Exception");
|
||||||
|
$this->expectExceptionCode(400);
|
||||||
|
Validate::validate_ip2("2620:0:2d0:200::7/32", false, 'invalidip', false, false, true, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
public function testValidateIpLocalhostAllowed()
|
public function testValidateIpLocalhostAllowed()
|
||||||
{
|
{
|
||||||
$result = Validate::validate_ip2("127.0.0.1/32", false, 'invalidip', true, false, true, true);
|
$result = Validate::validate_ip2("127.0.0.1/32", false, 'invalidip', true, false, true, false, true);
|
||||||
$this->assertEquals("127.0.0.1/32", $result);
|
$this->assertEquals("127.0.0.1/32", $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testValidateCidrNoationToNetmaskNotationIPv4()
|
||||||
|
{
|
||||||
|
$result = Validate::validate_ip2("1.1.1.1/4", false, 'invalidip', true, false, true, true, true);
|
||||||
|
$this->assertEquals("1.1.1.1/240.0.0.0", $result);
|
||||||
|
$result = Validate::validate_ip2("8.8.8.8/18", false, 'invalidip', true, false, true, true, true);
|
||||||
|
$this->assertEquals("8.8.8.8/255.255.192.0", $result);
|
||||||
|
$result = Validate::validate_ip2("8.8.8.8/1", false, 'invalidip', true, false, true, true, true);
|
||||||
|
$this->assertEquals("8.8.8.8/128.0.0.0", $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateIPv6()
|
||||||
|
{
|
||||||
|
$result = Validate::is_ipv6('1.1.1.1/4');
|
||||||
|
$this->assertFalse($result);
|
||||||
|
$result = Validate::is_ipv6('1.1.1.1');
|
||||||
|
$this->assertFalse($result);
|
||||||
|
$result = Validate::is_ipv6('::ffff:10.20.30.40');
|
||||||
|
$this->assertEquals('::ffff:10.20.30.40', $result);
|
||||||
|
$result = Validate::is_ipv6('2620:0:2d0:200::7/32');
|
||||||
|
$this->assertFalse($result);
|
||||||
|
$result = Validate::is_ipv6('2620:0:2d0:200::7');
|
||||||
|
$this->assertEquals('2620:0:2d0:200::7', $result);
|
||||||
|
}
|
||||||
|
|
||||||
public function testValidateIpLocalhostAllowedWrongIp()
|
public function testValidateIpLocalhostAllowedWrongIp()
|
||||||
{
|
{
|
||||||
$this->expectException("Exception");
|
$this->expectException("Exception");
|
||||||
$this->expectExceptionCode(400);
|
$this->expectExceptionCode(400);
|
||||||
Validate::validate_ip2("127.0.0.2", false, 'invalidip', true, false, false, true);
|
Validate::validate_ip2("127.0.0.2", false, 'invalidip', true, false, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateUrl()
|
public function testValidateUrl()
|
||||||
{
|
{
|
||||||
$result = Validate::validateUrl("https://froxlor.org/");
|
$result = Validate::validateUrl("https://froxlor.org/");
|
||||||
|
|||||||
@@ -277,4 +277,21 @@ class FtpsTest extends TestCase
|
|||||||
$result = json_decode($json_result, true)['data'];
|
$result = json_decode($json_result, true)['data'];
|
||||||
$this->assertEquals('test1ftp2', $result['username']);
|
$this->assertEquals('test1ftp2', $result['username']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCustomerFtpsDeleteDefaultUser()
|
||||||
|
{
|
||||||
|
global $admin_userdata;
|
||||||
|
|
||||||
|
// get customer
|
||||||
|
$json_result = Customers::getLocal($admin_userdata, array(
|
||||||
|
'loginname' => 'test1'
|
||||||
|
))->get();
|
||||||
|
$customer_userdata = json_decode($json_result, true)['data'];
|
||||||
|
$data = [
|
||||||
|
'username' => 'test1'
|
||||||
|
];
|
||||||
|
$this->expectExceptionCode(400);
|
||||||
|
$this->expectExceptionMessage('You cannot delete your main FTP account');
|
||||||
|
Ftps::getLocal($customer_userdata, $data)->delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,4 +124,63 @@ class FroxlorRpcTest extends TestCase
|
|||||||
$this->assertEquals('listFunctions', $result['command']['method']);
|
$this->assertEquals('listFunctions', $result['command']['method']);
|
||||||
$this->assertNull($result['params']);
|
$this->assertNull($result['params']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testApiPhpEscaping()
|
||||||
|
{
|
||||||
|
$key = $this->generateKey();
|
||||||
|
$request = array(
|
||||||
|
'body' => [
|
||||||
|
'command' => 'Froxlor.listFunctions',
|
||||||
|
'params' => $key
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$json_request = json_encode($request);
|
||||||
|
$decoded_request = json_decode($json_request, true);
|
||||||
|
$decoded_request = $this->stripcslashes_deep($decoded_request);
|
||||||
|
$this->assertEquals($key['key'], $decoded_request['body']['params']['key']);
|
||||||
|
$this->assertEquals($key['cert'], $decoded_request['body']['params']['cert']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stripcslashes_deep($value)
|
||||||
|
{
|
||||||
|
return is_array($value) ? array_map([$this, 'stripcslashes_deep'], $value) : stripcslashes($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateKey()
|
||||||
|
{
|
||||||
|
$dn = array(
|
||||||
|
"countryName" => "DE",
|
||||||
|
"stateOrProvinceName" => "Hessen",
|
||||||
|
"localityName" => "Frankfurt",
|
||||||
|
"organizationName" => "Froxlor",
|
||||||
|
"organizationalUnitName" => "Testing",
|
||||||
|
"commonName" => "test2.local",
|
||||||
|
"emailAddress" => "team@froxlor.org"
|
||||||
|
);
|
||||||
|
|
||||||
|
// generate key pair
|
||||||
|
$privkey = openssl_pkey_new(array(
|
||||||
|
"private_key_bits" => 2048,
|
||||||
|
"private_key_type" => OPENSSL_KEYTYPE_RSA
|
||||||
|
));
|
||||||
|
|
||||||
|
// generate csr
|
||||||
|
$csr = openssl_csr_new($dn, $privkey, array(
|
||||||
|
'digest_alg' => 'sha256'
|
||||||
|
));
|
||||||
|
|
||||||
|
// generate self-signed certificate
|
||||||
|
$sscert = openssl_csr_sign($csr, null, $privkey, 365, array(
|
||||||
|
'digest_alg' => 'sha256'
|
||||||
|
));
|
||||||
|
|
||||||
|
// export
|
||||||
|
openssl_x509_export($sscert, $certout);
|
||||||
|
openssl_pkey_export($privkey, $pkeyout, null);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'cert' => $certout,
|
||||||
|
'key' => $pkeyout
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user