Compare commits

..

64 Commits

Author SHA1 Message Date
Michael Kaufmann
b162324ff0 fix renew-check of let's encrypt implementation, set version to 0.10.5 for bugfix release; fixes #747
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-01 14:19:06 +01:00
Michael Kaufmann
6cd061d74c set version to 0.10.4 for upcoming maintenance release; minor code formatting + adjustments
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-01 11:16:13 +01:00
Michael Kaufmann
53b7420dc9 fix stripping of escape-sequences in api-endpoint; fixes #746
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-01 07:39:28 +01:00
Michael Kaufmann
aa85c648a3 check for renewal of certificates not only if there's a task to regenerate vhosts but everytime the letsencrypt cronjob runs (which is basically obsolete due to the integration into the tasks cron but perfect for checking renewal dates
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-31 21:37:54 +01:00
Michael Kaufmann
35e228ff09 Merge pull request #745 from pquerner/unittests/564
Add UnitTests for #679
2019-10-30 13:01:02 +01:00
Pascal
62236da496 changed method name 2019-10-30 12:50:16 +01:00
Pascal
e1cc896b6c add unit tests for Validate::is_ipv6 2019-10-30 12:39:56 +01:00
Pascal
36595baa65 Merge remote-tracking branch 'Froxlor/master' 2019-10-30 12:14:39 +01:00
Michael Kaufmann
ec3fd1d105 Create SECURITY.md 2019-10-30 11:00:08 +01:00
Michael Kaufmann
e39dcfbfe2 Update FUNDING.yml 2019-10-30 10:50:20 +01:00
Michael Kaufmann
ef6254b307 Merge pull request #679 from pquerner/#564
Allow CIDR and Netmask in mysql_host_access; fixes #564
2019-10-30 10:40:26 +01:00
Michael Kaufmann
44bf211ab5 Merge pull request #743 from kionez/fix_split_path_info
Correct fastcgi_split_path_info; fixes #744
2019-10-29 16:09:44 +01:00
kionez
b0e920104f Fix fastcgi_split_path_info as https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/ 2019-10-29 16:00:14 +01:00
kionez
299e201142 Fix fastcgi_split_path_info 2019-10-29 15:47:28 +01:00
Michael Kaufmann
46982ad2dc validate that a customer gets the default ftp account created even if the admin/reseller has no more resource for ftp accounts; fixes #741
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-29 07:52:00 +01:00
Michael Kaufmann
c0e07fd659 fix undefined variable in hosting-plans frontend, fixes #742
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-28 20:06:14 +01:00
Pascal
5c11eecbd7 remove code for checking ipv6 mapped ipv4 notation 2019-10-28 17:27:39 +01:00
Pascal
9689afc759 change method signature of \Froxlor\Validate\Validate::validate_ip2 2019-10-28 16:58:34 +01:00
Pascal
d76f4108e5 dont need $result if we're expecting an exception 2019-10-28 16:40:22 +01:00
Pascal
9c4d619840 remove inner if statement
check ipv6 when cidr>netmask flag is set
2019-10-28 16:32:52 +01:00
Pascal
7774e7606d dont check notated ips again 2019-10-28 16:29:53 +01:00
Pascal
2ed0cad27b #564:
cidr notation can only be 1 through 32
2019-10-28 16:27:54 +01:00
Pascal
686c2ae534 fix comparison 2019-10-28 16:00:43 +01:00
Pascal
faf3abe800 introduce new parameter to allow automatic convert cidr notation to netmask notation 2019-10-28 15:33:26 +01:00
Pascal
220b493a1b better readability 2019-10-28 14:16:27 +01:00
Pascal
e8d67f9711 check if ipv6 first 2019-10-28 14:07:31 +01:00
Pascal
83e932b068 switch join with implode 2019-10-28 13:26:32 +01:00
Pascal
84d1be538e block ipv6 addresses in cidr notation (mysql can't handle it) 2019-10-28 13:25:34 +01:00
Pascal
c97cdb1c0e make it more readable 2019-10-28 13:15:48 +01:00
Pascal
ffefe85fb4 Merge branch 'master' into #564 2019-10-28 12:18:55 +01:00
Pascal
27341ca490 Merge remote-tracking branch 'Froxlor/master' 2019-10-28 12:17:51 +01:00
Michael Kaufmann
822bb2bd4d fixed deletion of default-ftp-user possible via API (not through the interface though); refs #741
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-27 16:02:32 +01:00
Michael Kaufmann
88ee76e4c9 setting version to 0.10.3 for upcoming release
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-25 14:48:13 +02:00
Michael Kaufmann
90d921ebb5 preserve downward compatibility for 0.10.1 updaters regarding specialsettings for ssl-enabled domains; fixes #739
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-24 18:14:51 +02:00
Michael Kaufmann
7b162c4bd0 added tls-settings per domain for admins with change_serversettings-flag set; fixes #519
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-22 16:45:03 +02:00
Michael Kaufmann
32e2d48aed fallback to /tmp/froxlor.log if file-log is activated but no file given or not writeable; fixes #737
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-22 15:06:41 +02:00
Michael Kaufmann
1fdc524171 correct permissions
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-19 11:08:55 +02:00
Michael Kaufmann
4704798379 setting version to 0.10.2 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-18 13:39:23 +02:00
Michael Kaufmann
e5c1e8350d set default_theme value in settings-array to 'Sparkle' as it is in install/froxlor.sql; improve language strings for adding php-configurations and fpm-versions
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-17 18:40:53 +02:00
Michael Kaufmann
f0b36c03ad fix registration and termination date to flip between empty-value and 0000-00-00, thx to dxd
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-17 09:35:33 +02:00
Michael Kaufmann
79056f20ee display API in the list of features the customer is allowed to use; display total diskspace used by customer (web, mail and mysql) on customers dashboard, fixes #733
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-16 12:44:23 +02:00
Michael Kaufmann
5d6aa4d2bb Merge pull request #732 from TimoStramann/patch-1
fixing typo
2019-10-16 06:32:13 +02:00
Timo Stramann
f803276ca2 fixing typo
wrong variable name
2019-10-16 00:11:30 +02:00
Michael Kaufmann
5cf2d32e8a reverse parameter for Domains.add() into so users have to explicitly pass the parameter if they do NOT want the default ssl-ip to be used if left empty, so it behaves like the non-ssl ipandport parameter - if left empty, the system default is being used, thx J-BBB
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-15 14:35:42 +02:00
Michael Kaufmann
9430f77c2e Setting system.leapiversion exists and just needs to be updated, no added
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-15 07:22:41 +02:00
Michael Kaufmann
302fe994b7 adjust ip/port settings for downward compatibility when adding new ssl-specialsettings related settings
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-14 14:26:13 +02:00
Michael Kaufmann
9b122bc003 order tasks by type descending to create bind and webserver configs at the end of the run; cleanUp configs files after creation of certificates to minimize downtime, thx to SCD for testing
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-14 13:56:55 +02:00
Michael Kaufmann
9410356bc7 fix output of acme command when upgrading
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-14 10:12:26 +02:00
Michael Kaufmann
5d5cc3dda3 fix array to string conversion
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-13 22:49:03 +02:00
Michael Kaufmann
a7ccb7007f add Unit-test for DomainZones.listing()
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-13 14:47:39 +02:00
Michael Kaufmann
5680c88da0 implement DomainZones.listing() to actually return custom stored dns entries for a given domain, fixes #731
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-13 14:40:04 +02:00
Michael Kaufmann
cf01a587c7 fix typo in updater
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 14:53:13 +02:00
Michael Kaufmann
b6367e1be1 forgot to add the ssl-default-vhostconf-domain fields in ipsandports
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 14:39:58 +02:00
Michael Kaufmann
93aa8bff1e add default-ssl-vhost settings and optionally allow including of non-ssl default-vhost settings, fixes #727
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 14:34:18 +02:00
Michael Kaufmann
15fa035dc4 check for minimum required php version in autoupdater
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 14:04:43 +02:00
Michael Kaufmann
057f4aaa10 Passing the and parameters in reverse order to implode has been deprecated since PHP 7.4
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 10:22:11 +02:00
Michael Kaufmann
f588927bc5 check for existence of certificate files created by acme.sh
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 08:17:04 +02:00
Michael Kaufmann
03d2a76dd0 clean up language and code for dropped let's encrypt ACMEv1 support
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-11 20:53:34 +02:00
Michael Kaufmann
0d0e557715 force Let's Encrypt ACMEv2 API, fixed #728
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-11 18:17:05 +02:00
Michael Kaufmann
fb54b887f2 remove unneeded apihelp-page code in admin/customer_index; set explicit version to api-doc URL; check for acme.sh cronjob and uninstall it, as froxlor manages that itself
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-10 16:42:32 +02:00
Pascal
836b6f2fdb Merge remote-tracking branch 'upstream/master' 2019-05-10 02:54:33 +02:00
Pascal
f297058461 #564
fix wording
add validation for cidr syntax
add automatic transform of cidr to netmask for mysql
2019-05-04 00:39:12 +02:00
Pascal
0f4d8d76ae #564
fix wording
2019-05-03 23:31:31 +02:00
Pascal
12884c91a6 #564
fix #564 by allowing CIDR in mysql host validation. 
fix english and german field description accordingly
2019-05-03 22:32:57 +02:00
49 changed files with 1207 additions and 178 deletions

1
.github/FUNDING.yml vendored
View File

@@ -1,3 +1,4 @@
# These are supported funding model platforms
github: d00p
custom: ['https://paypal.me/Froxlor']

14
SECURITY.md Normal file
View 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.

View File

@@ -45,7 +45,7 @@ return array(
'settinggroup' => 'panel',
'varname' => 'default_theme',
'type' => 'option',
'default' => 'Froxlor',
'default' => 'Sparkle',
'option_mode' => 'one',
'option_options_method' => array(
'\\Froxlor\\UI\\Template',

View File

@@ -250,6 +250,23 @@ return array(
'default' => '',
'save_method' => 'storeSettingField'
),
'system_default_sslvhostconf' => array(
'label' => $lng['serversettings']['default_sslvhostconf'],
'settinggroup' => 'system',
'varname' => 'default_sslvhostconf',
'type' => 'text',
'default' => '',
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == 1
),
'system_include_default_vhostconf' => array(
'label' => $lng['serversettings']['includedefault_sslvhostconf'],
'settinggroup' => 'system',
'varname' => 'include_default_vhostconf',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField'
),
'system_apache_globaldiropt' => array(
'label' => $lng['serversettings']['apache_globaldiropt'],
'settinggroup' => 'system',

View File

@@ -141,7 +141,6 @@ return array(
'default' => '2',
'option_mode' => 'one',
'option_options' => array(
'1' => 'ACME v1',
'2' => 'ACME v2'
),
'save_method' => 'storeSettingField'

View File

@@ -36,6 +36,15 @@ if (! extension_loaded('zip')) {
));
}
// 0.10.x requires 7.0 at least
if (version_compare("7.0.0", PHP_VERSION, ">=")) {
\Froxlor\UI\Response::redirectTo($filename, array(
's' => $s,
'page' => 'error',
'errno' => 10
));
}
// display initial version check
if ($page == 'overview') {
@@ -221,5 +230,6 @@ elseif ($page == 'error') {
// 7 = local archive does not exist
// 8 = could not extract archive
// 9 = checksum mismatch
// 10 = <php-7.0
\Froxlor\UI\Response::standard_error('autoupdate_' . $errno);
}

View File

@@ -387,8 +387,6 @@ if ($page == 'overview') {
}
} elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) {
require_once __DIR__ . '/api_keys.php';
} elseif ($page == 'apihelp' && Settings::Get('api.enabled') == 1) {
require_once __DIR__ . '/apihelp.php';
} elseif ($page == '2fa' && Settings::Get('2fa.enabled') == 1) {
require_once __DIR__ . '/2fa.php';
}

View File

@@ -289,6 +289,7 @@ if ($page == '' || $page == 'overview') {
$result['customernumber'] = null;
$result['custom_notes'] = null;
$result['custom_notes_show'] = null;
$result['api_allowed'] = null;
$hosting_plans = null;
$admin_select_cnt = null;
$admin_select = null;

View File

@@ -23,7 +23,7 @@ if (empty($request)) {
}
// decode json request
$decoded_request = json_decode(stripslashes($request), true);
$decoded_request = json_decode($request, true);
// is it valid?
if (is_null($decoded_request)) {
@@ -32,6 +32,7 @@ if (is_null($decoded_request)) {
// validate content
try {
$decoded_request = stripcslashes_deep($decoded_request);
$request = \Froxlor\Api\FroxlorRPC::validateRequest($decoded_request);
// now actually do it
$cls = "\\Froxlor\\Api\\Commands\\" . $request['command']['class'];
@@ -72,3 +73,8 @@ function json_response($status, $status_message = '', $data = null)
echo $json_response;
exit();
}
function stripcslashes_deep($value)
{
return is_array($value) ? array_map('stripcslashes_deep', $value) : stripcslashes($value);
}

View File

@@ -98,10 +98,12 @@ if ($page == 'overview') {
$userinfo['diskspace_used'] = round($usages['webspace'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['mailspace_used'] = round($usages['mail'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['dbspace_used'] = round($usages['mysql'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['total_used'] = round(($usages['webspace'] + $usages['mail'] + $usages['mysql']) / 1024, Settings::Get('panel.decimal_places'));
} else {
$userinfo['diskspace_used'] = 0;
$userinfo['mailspace_used'] = 0;
$userinfo['dbspace_used'] = 0;
$userinfo['total_used'] = 0;
}
$userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
@@ -120,6 +122,8 @@ if ($page == 'overview') {
$se[] = "PHP";
if ($userinfo['perlenabled'] == '1')
$se[] = "Perl/CGI";
if ($userinfo['api_allowed'] == '1')
$se[] = '<a href="customer_index.php?s='.$s.'&page=apikeys">API</a>';
$services_enabled = implode(", ", $se);
eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/index') . "\";");
@@ -359,8 +363,6 @@ if ($page == 'overview') {
}
} elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) {
require_once __DIR__ . '/api_keys.php';
} elseif ($page == 'apihelp' && Settings::Get('api.enabled') == 1) {
require_once __DIR__ . '/apihelp.php';
} elseif ($page == '2fa' && Settings::Get('2fa.enabled') == 1) {
require_once __DIR__ . '/2fa.php';
}

View File

@@ -248,6 +248,8 @@ CREATE TABLE `panel_domains` (
`speciallogfile` tinyint(1) NOT NULL default '0',
`ssl_redirect` tinyint(4) NOT NULL default '0',
`specialsettings` text,
`ssl_specialsettings` text,
`include_specialsettings` tinyint(1) NOT NULL default '0',
`deactivated` tinyint(1) NOT NULL default '0',
`bindserial` varchar(10) NOT NULL default '2000010100',
`add_date` int( 11 ) NOT NULL default '0',
@@ -266,6 +268,10 @@ CREATE TABLE `panel_domains` (
`notryfiles` tinyint(1) DEFAULT '0',
`writeaccesslog` 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`),
KEY `customerid` (`customerid`),
KEY `parentdomain` (`parentdomainid`),
@@ -291,6 +297,10 @@ CREATE TABLE `panel_ipsandports` (
`default_vhostconf_domain` text,
`ssl_cert_chainfile` varchar(255) NOT NULL default '',
`docroot` varchar(255) NOT NULL default '',
`ssl_specialsettings` text,
`include_specialsettings` tinyint(1) NOT NULL default '0',
`ssl_default_vhostconf_domain` text,
`include_default_vhostconf_domain` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `ip_port` (`ip`,`port`)
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -685,8 +695,8 @@ opcache.interned_strings_buffer'),
('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'customer_hide_options', ''),
('panel', 'is_configured', '0'),
('panel', 'version', '0.10.1'),
('panel', 'db_version', '201910090');
('panel', 'version', '0.10.5'),
('panel', 'db_version', '201910200');
DROP TABLE IF EXISTS `panel_tasks`;

View File

@@ -304,7 +304,7 @@ if (\Froxlor\Froxlor::isDatabaseVersion('201907270')) {
"templates/Sparkle/customer/tickets"
);
$disabled = explode(',', ini_get('disable_functions'));
$exec_allowed = !in_array('exec', $disabled);
$exec_allowed = ! in_array('exec', $disabled);
$del_list = "";
foreach ($to_clean as $filedir) {
$complete_filedir = \Froxlor\Froxlor::getInstallDir() . $filedir;
@@ -324,7 +324,7 @@ if (\Froxlor\Froxlor::isDatabaseVersion('201907270')) {
lastStepStatus(0);
} else {
lastStepStatus(1, 'manual commands needed');
echo '<span class="update-step update-step-err">Please run the following commands manually:</span><br><pre>'.$del_list.'</pre><br>';
echo '<span class="update-step update-step-err">Please run the following commands manually:</span><br><pre>' . $del_list . '</pre><br>';
}
}
@@ -356,6 +356,104 @@ if (\Froxlor\Froxlor::isDatabaseVersion('201910030')) {
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.0')) {
showUpdateStep("Updating from 0.10.0 to 0.10.1 final", false);
\Froxlor\Froxlor::updateToVersion('0.10.1');
showUpdateStep("Updating from 0.10.0 to 0.10.1 final", false);
\Froxlor\Froxlor::updateToVersion('0.10.1');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201910090')) {
showUpdateStep("Adjusting Let's Encrypt API setting");
Settings::Set("system.leapiversion", '2');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201910110');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201910110')) {
showUpdateStep("Adding new settings for ssl-vhost default content");
Settings::AddNew("system.default_sslvhostconf", '');
Settings::AddNew("system.include_default_vhostconf", '0');
lastStepStatus(0);
showUpdateStep("Adding new fields to ips and ports-table");
Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `ssl_specialsettings` text AFTER `docroot`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `include_specialsettings` tinyint(1) NOT NULL default '0' AFTER `ssl_specialsettings`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `ssl_default_vhostconf_domain` text AFTER `include_specialsettings`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `include_default_vhostconf_domain` tinyint(1) NOT NULL default '0' AFTER `ssl_default_vhostconf_domain`;");
lastStepStatus(0);
showUpdateStep("Adding new fields to domains-table");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_specialsettings` text AFTER `specialsettings`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `include_specialsettings` tinyint(1) NOT NULL default '0' AFTER `ssl_specialsettings`;");
lastStepStatus(0);
// select all ips/ports with specialsettings and SSL enabled to include the specialsettings in the ssl-vhost
// because the former implementation included it and users might rely on that, see https://github.com/Froxlor/Froxlor/issues/727
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `specialsettings` <> '' AND `ssl` = '1'");
Database::pexecute($sel_stmt);
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_IPSANDPORTS . "` SET `include_specialsettings` = '1' WHERE `id` = :id");
if ($sel_stmt->columnCount() > 0) {
showUpdateStep("Adjusting IP/port settings for downward compatibility");
while ($row = $sel_stmt->fetch(PDO::FETCH_ASSOC)) {
Database::pexecute($upd_stmt, [
'id' => $row['id']
]);
}
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');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.1')) {
showUpdateStep("Updating from 0.10.1 to 0.10.2", false);
\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');
}

View File

@@ -144,9 +144,9 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
if (empty($matches)) {
$errors[] = $this->lng['error']['dns_content_invalid'];
} elseif (($matches['type'] == 'issue' || $matches['type'] == 'issuewild') && !\Froxlor\Validate\Validate::validateDomain($matches['domain'])) {
} elseif (($matches['type'] == 'issue' || $matches['type'] == 'issuewild') && ! \Froxlor\Validate\Validate::validateDomain($matches['domain'])) {
$errors[] = $this->lng['error']['dns_content_invalid'];
} elseif ($matches['type'] == 'iodef' && !\Froxlor\Validate\Validate::validateUrl($matches['url'])) {
} elseif ($matches['type'] == 'iodef' && ! \Froxlor\Validate\Validate::validateUrl($matches['url'])) {
$errors[] = $this->lng['error']['dns_content_invalid'];
} else {
$content = $matches[0];
@@ -373,12 +373,50 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
}
/**
* You cannot list dns zones.
* To get all domains use Domains.listing() or SubDomains.listing()
* List all entry records of a given domain by either id or domainname
*
* @param int $id
* optional, the domain id
* @param string $domainname
* optional, the domain name
*
* @access admin, customer
* @throws \Exception
* @return bool
*/
public function listing()
{
throw new \Exception('You cannot list dns zones. To get all domains use Domains.listing() or SubDomains.listing()', 303);
if (Settings::Get('system.dnsenabled') != '1') {
throw new \Exception("DNS service not enabled on this system", 405);
}
if ($this->isAdmin() == false && $this->getUserDetail('dnsenabled') != '1') {
throw new \Exception("You cannot access this resource", 405);
}
$id = $this->getParam('id', true, 0);
$dn_optional = ($id <= 0 ? false : true);
$domainname = $this->getParam('domainname', $dn_optional, '');
// get requested domain
$result = $this->apiCall('SubDomains.get', array(
'id' => $id,
'domainname' => $domainname
));
$id = $result['id'];
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_DOMAIN_DNS . "` WHERE `domain_id` = :did");
Database::pexecute($sel_stmt, array(
'did' => $id
), true, true);
$result = [];
while ($row = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
'count' => count($result),
'list' => $result
));
}
/**

View File

@@ -147,6 +147,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, currently not in use, default 0 (false)
* @param string $specialsettings
* optional, custom webserver vhost-content which is added to the generated vhost, default empty
* @param string $ssl_specialsettings
* optional, custom webserver vhost-content which is added to the generated ssl-vhost, default empty
* @param bool $include_specialsettings
* optional, whether or not to include non-ssl specialsettings in the generated ssl-vhost, default false
* @param bool $notryfiles
* optional, [nginx only] do not generate the default try-files directive, default 0 (false)
* @param bool $writeaccesslog
@@ -171,8 +175,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled
* @param array $ssl_ipandport
* optional, list of ssl-enabled ip/port id's to assign to this domain, default empty
* @param bool $use_default_ssl_ipandport_if_empty
* optional, set the systems default ssl ip addresses if none are given via $ssl_ipandport parameter
* @param bool $dont_use_default_ssl_ipandport_if_empty
* optional, do NOT set the systems default ssl ip addresses if none are given via $ssl_ipandport parameter
* @param bool $http2
* optional, whether to enable http/2 for this domain (requires to be enabled in the settings), default 0 (false)
* @param int $hsts_maxage
@@ -183,6 +187,14 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional whether or not to preload HSTS header value
* @param bool $ocsp_stapling
* 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
* @throws \Exception
@@ -214,6 +226,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$zonefile = $this->getParam('zonefile', true, '');
$dkim = $this->getBoolParam('dkim', true, 0);
$specialsettings = $this->getParam('specialsettings', true, '');
$ssl_specialsettings = $this->getParam('ssl_specialsettings', true, '');
$include_specialsettings = $this->getBoolParam('include_specialsettings', true, 0);
$notryfiles = $this->getBoolParam('notryfiles', true, 0);
$writeaccesslog = $this->getBoolParam('writeaccesslog', true, 1);
$writeerrorlog = $this->getBoolParam('writeerrorlog', true, 1);
@@ -225,14 +239,27 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$mod_fcgid_maxrequests = $this->getParam('mod_fcgid_maxrequests', true, - 1);
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, 0);
$letsencrypt = $this->getBoolParam('letsencrypt', true, 0);
$use_default_ssl_ipandport_if_empty = $this->getBoolParam('use_default_ssl_ipandport_if_empty', true, 0);
$p_ssl_ipandports = $this->getParam('ssl_ipandport', true, $use_default_ssl_ipandport_if_empty ? explode(',', Settings::Get('system.defaultsslip')) : array());
$dont_use_default_ssl_ipandport_if_empty = $this->getBoolParam('dont_use_default_ssl_ipandport_if_empty', true, 0);
$p_ssl_ipandports = $this->getParam('ssl_ipandport', true, $dont_use_default_ssl_ipandport_if_empty ? array() : explode(',', Settings::Get('system.defaultsslip')));
$http2 = $this->getBoolParam('http2', true, 0);
$hsts_maxage = $this->getParam('hsts_maxage', true, 0);
$hsts_sub = $this->getBoolParam('hsts_sub', true, 0);
$hsts_preload = $this->getBoolParam('hsts_preload', 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
if ($p_domain == Settings::Get('system.hostname')) {
\Froxlor\UI\Response::standard_error('admin_domain_emailsystemhostname', '', true);
@@ -286,7 +313,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'0',
''
), true);
if ($registration_date == '0000-00-00') {
if ($registration_date == '0000-00-00' || empty($registration_date)) {
$registration_date = null;
}
@@ -295,7 +322,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'0',
''
), true);
if ($termination_date == '0000-00-00') {
if ($termination_date == '0000-00-00' || empty($termination_date)) {
$termination_date = null;
}
@@ -319,6 +346,34 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} else {
$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 {
$isbinddomain = '0';
if (Settings::Get('system.bind_enable') == '1') {
@@ -328,10 +383,14 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$zonefile = '';
$dkim = '0';
$specialsettings = '';
$ssl_specialsettings = '';
$include_specialsettings = 0;
$notryfiles = '0';
$writeaccesslog = '1';
$writeerrorlog = '1';
$documentroot = $_documentroot;
$override_tls = '0';
$ssl_protocols = array();
}
if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') {
@@ -391,6 +450,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$ssl_ipandports = array();
if (Settings::Get('system.use_ssl') == "1" && ! empty($p_ssl_ipandports)) {
$ssl_ipandports = $this->validateIpAddresses($p_ssl_ipandports, true);
if ($this->getUserDetail('change_serversettings') == '1') {
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $ssl_specialsettings), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true);
}
}
if (Settings::Get('system.use_ssl') == "0" || empty($ssl_ipandports)) {
$ssl_redirect = 0;
@@ -407,17 +470,16 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
// OCSP stapling
$ocsp_stapling = 0;
// vhost container settings
$ssl_specialsettings = '';
$include_specialsettings = 0;
}
// We can't enable let's encrypt for wildcard - domains if using acme-v1
if ($serveraliasoption == '0' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '1') {
// We can't enable let's encrypt for wildcard-domains
if ($serveraliasoption == '0' && $letsencrypt == '1') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
}
// if using acme-v2 we cannot issue wildcard-certificates
// because they currently only support the dns-01 challenge
if ($serveraliasoption == '0' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '2') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencryptv2', '', true);
}
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
if ($ssl_redirect > 0 && $letsencrypt == 1) {
@@ -545,6 +607,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'openbasedir' => $openbasedir,
'speciallogfile' => $speciallogfile,
'specialsettings' => $specialsettings,
'ssl_specialsettings' => $ssl_specialsettings,
'include_specialsettings' => $include_specialsettings,
'notryfiles' => $notryfiles,
'writeaccesslog' => $writeaccesslog,
'writeerrorlog' => $writeerrorlog,
@@ -561,7 +625,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'hsts' => $hsts_maxage,
'hsts_sub' => $hsts_sub,
'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("
@@ -587,6 +655,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`openbasedir` = :openbasedir,
`speciallogfile` = :speciallogfile,
`specialsettings` = :specialsettings,
`ssl_specialsettings` = :ssl_specialsettings,
`include_specialsettings` = :include_specialsettings,
`notryfiles` = :notryfiles,
`writeaccesslog` = :writeaccesslog,
`writeerrorlog` = :writeerrorlog,
@@ -603,7 +673,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`hsts` = :hsts,
`hsts_sub` = :hsts_sub,
`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);
$domainid = Database::lastInsertId();
@@ -703,6 +777,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, currently not in use, default 0 (false)
* @param string $specialsettings
* optional, custom webserver vhost-content which is added to the generated vhost, default empty
* @param string $ssl_specialsettings
* optional, custom webserver vhost-content which is added to the generated ssl-vhost, default empty
* @param bool $include_specialsettings
* optional, whether or not to include non-ssl specialsettings in the generated ssl-vhost, default false
* @param bool $specialsettingsforsubdomains
* optional, whether to apply specialsettings to all subdomains of this domain, default 0 (false)
* @param bool $notryfiles
@@ -782,6 +860,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$zonefile = $this->getParam('zonefile', true, $result['zonefile']);
$dkim = $this->getBoolParam('dkim', true, $result['dkim']);
$specialsettings = $this->getParam('specialsettings', true, $result['specialsettings']);
$ssl_specialsettings = $this->getParam('ssl_specialsettings', true, $result['ssl_specialsettings']);
$include_specialsettings = $this->getBoolParam('include_specialsettings', true, $result['include_specialsettings']);
$ssfs = $this->getBoolParam('specialsettingsforsubdomains', true, 0);
$notryfiles = $this->getBoolParam('notryfiles', true, $result['notryfiles']);
$writeaccesslog = $this->getBoolParam('writeaccesslog', true, $result['writeaccesslog']);
@@ -802,6 +882,24 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']);
$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
$subdomains_stmt = Database::prepare("
SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE
@@ -908,7 +1006,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'0',
''
), true);
if ($registration_date == '0000-00-00') {
if ($registration_date == '0000-00-00' || empty($registration_date)) {
$registration_date = null;
}
$termination_date = \Froxlor\Validate\Validate::validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array(
@@ -916,7 +1014,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'0',
''
), true);
if ($termination_date == '0000-00-00') {
if ($termination_date == '0000-00-00' || empty($termination_date)) {
$termination_date = null;
}
@@ -971,16 +1069,48 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
\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 {
$isbinddomain = $result['isbinddomain'];
$zonefile = $result['zonefile'];
$dkim = $result['dkim'];
$specialsettings = $result['specialsettings'];
$ssl_specialsettings = $result['ssl_specialsettings'];
$include_specialsettings = $result['include_specialsettings'];
$ssfs = (empty($specialsettings) ? 0 : 1);
$notryfiles = $result['notryfiles'];
$writeaccesslog = $result['writeaccesslog'];
$writeerrorlog = $result['writeerrorlog'];
$documentroot = $result['documentroot'];
$override_tls = $result['override_tls'];
}
if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') {
@@ -1031,6 +1161,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$ssl_ipandports = array();
if (Settings::Get('system.use_ssl') == "1" && ! empty($p_ssl_ipandports)) {
$ssl_ipandports = $this->validateIpAddresses($p_ssl_ipandports, true, $result['id']);
if ($this->getUserDetail('change_serversettings') == '1') {
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $ssl_specialsettings), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true);
}
}
if (Settings::Get('system.use_ssl') == "0" || empty($ssl_ipandports)) {
$ssl_redirect = 0;
@@ -1047,17 +1181,16 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
// OCSP stapling
$ocsp_stapling = 0;
// vhost container settings
$ssl_specialsettings = '';
$include_specialsettings = 0;
}
// We can't enable let's encrypt for wildcard domains when using acme-v1
if ($serveraliasoption == '0' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '1') {
// We can't enable let's encrypt for wildcard-domains
if ($serveraliasoption == '0' && $letsencrypt == '1') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
}
// if using acme-v2 we cannot issue wildcard-certificates
// because they currently only support the dns-01 challenge
if ($serveraliasoption == '0' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '2') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencryptv2', '', true);
}
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) {
@@ -1255,12 +1388,16 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
if ($ssfs == 1) {
$_update_data['specialsettings'] = $specialsettings;
$upd_specialsettings = ", `specialsettings` = :specialsettings ";
$_update_data['ssl_specialsettings'] = $ssl_specialsettings;
$_update_data['include_specialsettings'] = $include_specialsettings;
$upd_specialsettings = ", `specialsettings` = :specialsettings, `ssl_specialsettings` = :ssl_specialsettings, `include_specialsettings` = :include_specialsettings ";
} else {
$upd_specialsettings = '';
unset($_update_data['specialsettings']);
unset($_update_data['ssl_specialsettings']);
unset($_update_data['include_specialsettings']);
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `specialsettings`='' WHERE `parentdomainid` = :id
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `specialsettings`='', `ssl_specialsettings`='', `include_specialsettings`='0' WHERE `parentdomainid` = :id
");
Database::pexecute($upd_stmt, array(
'id' => $id
@@ -1293,6 +1430,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$update_data['mod_fcgid_starter'] = $mod_fcgid_starter;
$update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests;
$update_data['specialsettings'] = $specialsettings;
$update_data['ssl_specialsettings'] = $ssl_specialsettings;
$update_data['include_specialsettings'] = $include_specialsettings;
$update_data['notryfiles'] = $notryfiles;
$update_data['writeaccesslog'] = $writeaccesslog;
$update_data['writeerrorlog'] = $writeerrorlog;
@@ -1305,6 +1444,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$update_data['hsts_sub'] = $hsts_sub;
$update_data['hsts_preload'] = $hsts_preload;
$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_stmt = Database::prepare("
@@ -1330,6 +1473,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`mod_fcgid_starter` = :mod_fcgid_starter,
`mod_fcgid_maxrequests` = :mod_fcgid_maxrequests,
`specialsettings` = :specialsettings,
`ssl_specialsettings` = :ssl_specialsettings,
`include_specialsettings` = :include_specialsettings,
`notryfiles` = :notryfiles,
`writeaccesslog` = :writeaccesslog,
`writeerrorlog` = :writeerrorlog,
@@ -1341,7 +1486,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`hsts` = :hsts,
`hsts_sub` = :hsts_sub,
`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
");
Database::pexecute($update_stmt, $update_data, true, true);
@@ -1352,6 +1501,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$_update_data['openbasedir'] = $openbasedir;
$_update_data['mod_fcgid_starter'] = $mod_fcgid_starter;
$_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;
// if php config is to be set for all subdomains, check here
@@ -1376,7 +1529,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`phpenabled` = :phpenabled,
`openbasedir` = :openbasedir,
`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 . "
WHERE `parentdomainid` = :parentdomainid
");

View File

@@ -56,7 +56,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
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
$path = $this->getParam('path');
@@ -71,7 +73,6 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$ftpdomain = $this->getParam('ftp_domain', true, '');
$additional_members = $this->getParam('additional_members', true, array());
$is_defaultuser = $this->getBoolParam('is_defaultuser', true, 0);
// validation
$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;
}
if (Settings::Get('customer.ftpatdomain') == '1' && !$is_defaultuser) {
if (Settings::Get('customer.ftpatdomain') == '1' && ! $is_defaultuser) {
if ($ftpusername == '') {
\Froxlor\UI\Response::standard_error(array(
'stringisempty',
@@ -541,6 +542,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
"username" => $customer_data['loginname']
);
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

View File

@@ -118,6 +118,14 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* optional, requires $ssl = 1, default empty
* @param string $ssl_cert_chainfile
* optional, requires $ssl = 1, default empty
* @param string $ssl_specialsettings
* optional, requires $ssl = 1, default empty
* @param bool $include_specialsettings
* optional, requires $ssl = 1, whether or not to include non-ssl specialsettings, default false
* @param string $ssl_default_vhostconf_domain
* optional, requires $ssl = 1, defatul empty
* @param bool $include_default_vhostconf_domain
* optional, requires $ssl = 1, whether or not to include non-ssl default_vhostconf_domain, default false
*
* @access admin
* @throws \Exception
@@ -127,7 +135,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
{
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(
'stringisempty',
'myport'
@@ -146,12 +154,20 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, ''), 'ssl_key_file', '', '', array(), true);
$ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, ''), 'ssl_ca_file', '', '', array(), true);
$ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, ''), 'ssl_cert_chainfile', '', '', array(), true);
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, '')), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true);
$include_specialsettings = ! empty($this->getBoolParam('include_specialsettings', true, 0)) ? 1 : 0;
$ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, '')), 'ssl_default_vhostconf_domain', '/^[^\0]*$/', '', array(), true);
$include_default_vhostconf_domain = ! empty($this->getBoolParam('include_default_vhostconf_domain', true, 0)) ? 1 : 0;
} else {
$ssl = 0;
$ssl_cert_file = '';
$ssl_key_file = '';
$ssl_ca_file = '';
$ssl_cert_chainfile = '';
$ssl_specialsettings = '';
$include_specialsettings = 0;
$ssl_default_vhostconf_domain = '';
$include_default_vhostconf_domain = 0;
}
if ($listen_statement != '1') {
@@ -217,7 +233,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
`specialsettings` = :ss, `ssl` = :ssl,
`ssl_cert_file` = :ssl_cert, `ssl_key_file` = :ssl_key,
`ssl_ca_file` = :ssl_ca, `ssl_cert_chainfile` = :ssl_chain,
`default_vhostconf_domain` = :dvhd, `docroot` = :docroot;
`default_vhostconf_domain` = :dvhd, `docroot` = :docroot,
`ssl_specialsettings` = :ssl_ss, `include_specialsettings` = :incss,
`ssl_default_vhostconf_domain` = :ssl_dvhd, `include_default_vhostconf_domain` = :incdvhd;
");
$ins_data = array(
'ip' => $ip,
@@ -233,7 +251,11 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'ssl_ca' => $ssl_ca_file,
'ssl_chain' => $ssl_cert_chainfile,
'dvhd' => $default_vhostconf_domain,
'docroot' => $docroot
'docroot' => $docroot,
'ssl_ss' => $ssl_specialsettings,
'incss' => $include_specialsettings,
'ssl_dvhd' => $ssl_default_vhostconf_domain,
'incdvhd' => $include_default_vhostconf_domain
);
Database::pexecute($ins_stmt, $ins_data);
$ins_data['id'] = Database::lastInsertId();
@@ -287,6 +309,14 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* optional, requires $ssl = 1, default empty
* @param string $ssl_cert_chainfile
* optional, requires $ssl = 1, default empty
* @param string $ssl_specialsettings
* optional, requires $ssl = 1, default empty
* @param bool $include_specialsettings
* optional, requires $ssl = 1, whether or not to include non-ssl specialsettings, default false
* @param string $ssl_default_vhostconf_domain
* optional, requires $ssl = 1, defatul empty
* @param bool $include_default_vhostconf_domain
* optional, requires $ssl = 1, whether or not to include non-ssl default_vhostconf_domain, default false
*
*
* @access admin
@@ -302,7 +332,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'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(
'stringisempty',
'myport'
@@ -321,12 +351,20 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, $result['ssl_key_file']), 'ssl_key_file', '', '', array(), true);
$ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, $result['ssl_ca_file']), 'ssl_ca_file', '', '', array(), true);
$ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, $result['ssl_cert_chainfile']), 'ssl_cert_chainfile', '', '', array(), true);
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, $result['ssl_specialsettings'])), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true);
$include_specialsettings = $this->getBoolParam('include_specialsettings', true, $result['include_specialsettings']);
$ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, $result['ssl_default_vhostconf_domain'])), 'ssl_default_vhostconf_domain', '/^[^\0]*$/', '', array(), true);
$include_default_vhostconf_domain = $this->getBoolParam('include_default_vhostconf_domain', true, $result['include_default_vhostconf_domain']);
} else {
$ssl = 0;
$ssl_cert_file = '';
$ssl_key_file = '';
$ssl_ca_file = '';
$ssl_cert_chainfile = '';
$ssl_specialsettings = '';
$include_specialsettings = 0;
$ssl_default_vhostconf_domain = '';
$include_default_vhostconf_domain = 0;
}
$result_checkfordouble_stmt = Database::prepare("
@@ -404,7 +442,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
`specialsettings` = :ss, `ssl` = :ssl,
`ssl_cert_file` = :ssl_cert, `ssl_key_file` = :ssl_key,
`ssl_ca_file` = :ssl_ca, `ssl_cert_chainfile` = :ssl_chain,
`default_vhostconf_domain` = :dvhd, `docroot` = :docroot
`default_vhostconf_domain` = :dvhd, `docroot` = :docroot,
`ssl_specialsettings` = :ssl_ss, `include_specialsettings` = :incss,
`ssl_default_vhostconf_domain` = :ssl_dvhd, `include_default_vhostconf_domain` = :incdvhd
WHERE `id` = :id;
");
$upd_data = array(
@@ -422,6 +462,10 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'ssl_chain' => $ssl_cert_chainfile,
'dvhd' => $default_vhostconf_domain,
'docroot' => $docroot,
'ssl_ss' => $ssl_specialsettings,
'incss' => $include_specialsettings,
'ssl_dvhd' => $ssl_default_vhostconf_domain,
'incdvhd' => $include_default_vhostconf_domain,
'id' => $id
);
Database::pexecute($upd_stmt, $upd_data);

View File

@@ -262,13 +262,20 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
`openbasedir_path` = :openbasedir_path,
`speciallogfile` = :speciallogfile,
`specialsettings` = :specialsettings,
`ssl_specialsettings` = :ssl_specialsettings,
`include_specialsettings` = :include_specialsettings,
`ssl_redirect` = :ssl_redirect,
`phpsettingid` = :phpsettingid,
`letsencrypt` = :letsencrypt,
`http2` = :http2,
`hsts` = :hsts,
`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(
"customerid" => $customer['customerid'],
@@ -285,13 +292,20 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"phpenabled" => $domain_check['phpenabled'],
"speciallogfile" => $domain_check['speciallogfile'],
"specialsettings" => $domain_check['specialsettings'],
"ssl_specialsettings" => $domain_check['ssl_specialsettings'],
"include_specialsettings" => $domain_check['include_specialsettings'],
"ssl_redirect" => $ssl_redirect,
"phpsettingid" => $phpsid_result['phpsettingid'],
"letsencrypt" => $letsencrypt,
"http2" => $http2,
"hsts" => $hsts_maxage,
"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);
$subdomain_id = Database::lastInsertId();
@@ -564,15 +578,10 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
}
}
// We can't enable let's encrypt for wildcard - domains when using acme-v1
if ($iswildcarddomain == '1' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '1') {
// We can't enable let's encrypt for wildcard-domains
if ($iswildcarddomain == '1' && $letsencrypt == '1') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt');
}
// if using acme-v2 we cannot issue wildcard-certificates
// because they currently only support the dns-01 challenge
if ($iswildcarddomain == '1' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '2') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencryptv2');
}
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) {

0
lib/Froxlor/Cli/ConfigServicesCmd.php Executable file → Normal file
View File

0
lib/Froxlor/Cli/SwitchServerIpCmd.php Executable file → Normal file
View File

View File

@@ -178,7 +178,7 @@ class Apache extends HttpConfigBase
$this->virtualhosts_data[$vhosts_filename] .= ' ServerName ' . Settings::Get('system.hostname') . "\n";
$froxlor_aliases = Settings::Get('system.froxloraliases');
if (!empty($froxlor_aliases)) {
if (! empty($froxlor_aliases)) {
$froxlor_aliases = explode(",", $froxlor_aliases);
$aliases = "";
foreach ($froxlor_aliases as $falias) {
@@ -187,7 +187,7 @@ class Apache extends HttpConfigBase
}
}
$aliases = trim($aliases);
if (!empty($aliases)) {
if (! empty($aliases)) {
$this->virtualhosts_data[$vhosts_filename] .= ' ServerAlias ' . $aliases . "\n";
}
}
@@ -403,11 +403,16 @@ class Apache extends HttpConfigBase
* end of dirprotection
*/
if ($row_ipsandports['specialsettings'] != '') {
if ($row_ipsandports['specialsettings'] != '' && ($row_ipsandports['ssl'] == '0' || ($row_ipsandports['ssl'] == '1' && Settings::Get('system.use_ssl') == '1' && $row_ipsandports['include_specialsettings'] == '1'))) {
$this->virtualhosts_data[$vhosts_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
if ($row_ipsandports['ssl'] == '1' && Settings::Get('system.use_ssl') == '1') {
if ($row_ipsandports['ssl_specialsettings'] != '') {
$this->virtualhosts_data[$vhosts_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
if ($row_ipsandports['ssl_cert_file'] == '') {
$row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($row_ipsandports['ssl_cert_file'])) {
@@ -478,7 +483,7 @@ class Apache extends HttpConfigBase
$this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
$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] .= ' SSLVerifyDepth 10' . "\n";
@@ -900,9 +905,12 @@ class Apache extends HttpConfigBase
$ipport = $domain['ip'] . ':' . $domain['port'] . ' ';
}
if ($ipandport['default_vhostconf_domain'] != '') {
if ($ipandport['default_vhostconf_domain'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $ipandport['include_default_vhostconf_domain'] == '1'))) {
$_vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($ipandport['ssl_default_vhostconf_domain'] != '' && $ssl_vhost == true) {
$_vhost_content .= $this->processSpecialConfigTemplate($ipandport['ssl_default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
$ipportlist .= $ipport;
}
@@ -959,8 +967,13 @@ class Apache extends HttpConfigBase
}
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 .= ' 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 (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1') {
$vhost_content .= ' Protocols h2 http/1.1' . "\n";
@@ -976,10 +989,10 @@ class Apache extends HttpConfigBase
}
// this makes it more secure, thx to Marcel (08/2013)
$vhost_content .= ' SSLHonorCipherOrder On' . "\n";
$vhost_content .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
$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) {
$vhost_content .= ' SSLCipherSuite TLSv1.3 ' . Settings::Get('system.tlsv13_cipher_list') . "\n";
$vhost_content .= ' SSLCipherSuite ' . $ssl_cipher_list . "\n";
$protocols = array_map('trim', explode(",", $ssl_protocols));
if (in_array("TLSv1.3", $protocols) && ! empty($tlsv13_cipher_list) && Settings::Get('system.apache24') == 1) {
$vhost_content .= ' SSLCipherSuite TLSv1.3 ' . $tlsv13_cipher_list . "\n";
}
$vhost_content .= ' SSLVerifyDepth 10' . "\n";
$vhost_content .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n";
@@ -1057,17 +1070,25 @@ class Apache extends HttpConfigBase
}
$vhost_content .= $this->getLogfiles($domain);
if ($domain['specialsettings'] != '') {
if ($domain['specialsettings'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $domain['include_specialsettings'] == 1))) {
$vhost_content .= $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($domain['ssl_specialsettings'] != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate($domain['ssl_specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($_vhost_content != '') {
$vhost_content .= $_vhost_content;
}
if (Settings::Get('system.default_vhostconf') != '') {
if (Settings::Get('system.default_vhostconf') != '' && ($ssl_vhost == false || ($ssl_vhost == true && Settings::Get('system.include_default_vhostconf') == 1))) {
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if (Settings::Get('system.default_sslvhostconf') != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_sslvhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
}
$vhost_content .= '</VirtualHost>' . "\n";

View File

@@ -45,19 +45,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
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("
SELECT
domssl.`id`,
@@ -94,6 +83,52 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
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("
SELECT
@@ -127,6 +162,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
// flag for re-generation of vhost files
$changedetected = 0;
$needRenew = self::needRenew();
// first - generate LE for system-vhost if enabled
if (Settings::Get('system.le_froxlor_enabled') == '1') {
@@ -147,15 +184,10 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
'id' => null
);
$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);
$froxlor_ssl = $needRenew ? $needRenew['froxlor_ssl'] : array();
$cert_mode = 'issue';
if ($froxlor_ssl) {
if (count($froxlor_ssl) > 0) {
$cert_mode = 'renew';
$certrow['id'] = $froxlor_ssl['id'];
$certrow['expirationdate'] = $froxlor_ssl['expirationdate'];
@@ -210,7 +242,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
}
// customer domains
$certrows = $certificates_stmt->fetchAll(\PDO::FETCH_ASSOC);
$certrows = $needRenew ? $needRenew['customer_ssl'] : array();
$cert_mode = 'issue';
foreach ($certrows as $certrow) {
@@ -224,7 +256,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
if ($certrow['ssl_redirect'] != 2) {
$do_force = false;
if (! empty($certrow['ssl_cert_file']) && !empty($certrow['expirationdate'])) {
if (! empty($certrow['ssl_cert_file']) && ! empty($certrow['expirationdate'])) {
$cert_mode = 'renew';
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Updating certificate for " . $certrow['domain']);
} else if (! empty($certrow['ssl_cert_file']) && empty($certrow['expirationdate'])) {
@@ -357,11 +389,20 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
$certificate_folder = \Froxlor\FileDir::makeCorrectDir($certificate_folder);
if (is_dir($certificate_folder)) {
$return['crt'] = file_get_contents(\Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $domain . '.cer'));
$return['key'] = file_get_contents(\Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $domain . '.key'));
$return['chain'] = file_get_contents(\Froxlor\FileDir::makeCorrectFile($certificate_folder . '/ca.cer'));
$return['fullchain'] = file_get_contents(\Froxlor\FileDir::makeCorrectFile($certificate_folder . '/fullchain.cer'));
$return['csr'] = file_get_contents(\Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $domain . '.csr'));
foreach ([
'crt' => $domain . '.cer',
'key' => $domain . '.key',
'chain' => 'ca.cer',
'fullchain' => 'fullchain.cer',
'csr' => $domain . '.csr'
] as $index => $sslfile) {
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $sslfile);
if (file_exists($ssl_file)) {
$return[$index] = file_get_contents($ssl_file);
} else {
$return[$index] = null;
}
}
}
}
@@ -379,6 +420,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
private static function checkUpgrade()
{
$acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade");
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result));
// check for activated cron (which is installed automatically) but we don't need it
$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));
}
}

View File

@@ -175,7 +175,7 @@ class Lighttpd extends HttpConfigBase
);
}
if ($row_ipsandports['specialsettings'] != '') {
if ($row_ipsandports['specialsettings'] != '' && ($row_ipsandports['ssl'] == '0' || ($row_ipsandports['ssl'] == '1' && Settings::Get('system.use_ssl') == '1' && $row_ipsandports['include_specialsettings'] == '1'))) {
$this->lighttpd_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
@@ -183,6 +183,11 @@ class Lighttpd extends HttpConfigBase
}
if ($row_ipsandports['ssl'] == '1') {
if ($row_ipsandports['ssl_specialsettings'] != '') {
$this->lighttpd_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
if ($row_ipsandports['ssl_cert_file'] == '') {
$row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($row_ipsandports['ssl_cert_file'])) {
@@ -512,17 +517,29 @@ class Lighttpd extends HttpConfigBase
$vhost_content .= $this->getSslSettings($domain, $ssl_vhost);
if ($domain['specialsettings'] != "") {
if ($domain['specialsettings'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $domain['include_specialsettings'] == 1))) {
$vhost_content .= $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($ipandport['default_vhostconf_domain'] != '') {
if ($domain['ssl_specialsettings'] != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate($domain['ssl_specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($ipandport['default_vhostconf_domain'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $ipandport['include_default_vhostconf_domain'] == '1'))) {
$vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if (Settings::Get('system.default_vhostconf') != '') {
if ($ipandport['ssl_default_vhostconf_domain'] != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate($ipandport['ssl_default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if (Settings::Get('system.default_vhostconf') != '' && ($ssl_vhost == false || ($ssl_vhost == true && Settings::Get('system.include_default_vhostconf') == 1))) {
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if (Settings::Get('system.default_sslvhostconf') != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_sslvhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
}
$vhost_content .= $this->getLogFiles($domain);
}
@@ -553,6 +570,8 @@ class Lighttpd extends HttpConfigBase
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_settings .= 'ssl.engine = "enable"' . "\n";
$ssl_settings .= 'ssl.use-compression = "disable"' . "\n";
@@ -566,7 +585,7 @@ class Lighttpd extends HttpConfigBase
}
$ssl_settings .= 'ssl.use-sslv2 = "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.pemfile = "' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n";

View File

@@ -258,7 +258,7 @@ class Nginx extends HttpConfigBase
$this->nginx_data[$vhost_filename] .= "\t" . '}' . "\n";
}
if ($row_ipsandports['specialsettings'] != '') {
if ($row_ipsandports['specialsettings'] != '' && ($row_ipsandports['ssl'] == '0' || ($row_ipsandports['ssl'] == '1' && Settings::Get('system.use_ssl') == '1' && $row_ipsandports['include_specialsettings'] == '1'))) {
$this->nginx_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], array(
'domain' => Settings::Get('system.hostname'),
'loginname' => Settings::Get('phpfpm.vhost_httpuser'),
@@ -273,11 +273,19 @@ class Nginx extends HttpConfigBase
if ($row_ipsandports['ssl'] == '1') {
$row_ipsandports['domain'] = Settings::Get('system.hostname');
$this->nginx_data[$vhost_filename] .= $this->composeSslSettings($row_ipsandports);
if ($row_ipsandports['ssl_specialsettings'] != '') {
$this->nginx_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], array(
'domain' => Settings::Get('system.hostname'),
'loginname' => Settings::Get('phpfpm.vhost_httpuser'),
'documentroot' => $mypath,
'customerroot' => $mypath
), $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
}
if (! $is_redirect) {
$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\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n";
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n";
@@ -447,10 +455,12 @@ class Nginx extends HttpConfigBase
$ipport = $domain['ip'] . ':' . $domain['port'];
}
if ($ipandport['default_vhostconf_domain'] != '') {
if ($ipandport['default_vhostconf_domain'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $ipandport['include_default_vhostconf_domain'] == '1'))) {
$_vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($ipandport['ssl_default_vhostconf_domain'] != '' && $ssl_vhost == true) {
$_vhost_content .= $this->processSpecialConfigTemplate($ipandport['ssl_default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
$http2 = $ssl_vhost == true && (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1');
$vhost_content .= "\t" . 'listen ' . $ipport . ($ssl_vhost == true ? ' ssl' : '') . ($http2 == true ? ' http2' : '') . ';' . "\n";
@@ -522,17 +532,25 @@ class Nginx extends HttpConfigBase
$vhost_content .= isset($this->needed_htpasswds[$domain['id']]) ? $this->needed_htpasswds[$domain['id']] . "\n" : '';
if ($domain['specialsettings'] != "") {
if ($domain['specialsettings'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $domain['include_specialsettings'] == 1))) {
$vhost_content = $this->mergeVhostCustom($vhost_content, $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost));
}
if ($domain['ssl_specialsettings'] != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate($domain['ssl_specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($_vhost_content != '') {
$vhost_content = $this->mergeVhostCustom($vhost_content, $_vhost_content);
}
if (Settings::Get('system.default_vhostconf') != '') {
if (Settings::Get('system.default_vhostconf') != '' && ($ssl_vhost == false || ($ssl_vhost == true && Settings::Get('system.include_default_vhostconf') == 1))) {
$vhost_content = $this->mergeVhostCustom($vhost_content, $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n");
}
if (Settings::Get('system.default_sslvhostconf') != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_sslvhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
}
}
$vhost_content .= "\n}\n\n";
@@ -660,10 +678,14 @@ class Nginx extends HttpConfigBase
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');
} 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
// $sslsettings .= "\t" . 'ssl on;' . "\n";
$sslsettings .= "\t" . 'ssl_protocols ' . str_replace(",", " ", Settings::Get('system.ssl_protocols')) . ';' . "\n";
$sslsettings .= "\t" . 'ssl_ciphers ' . Settings::Get('system.ssl_cipher_list') . ';' . "\n";
$sslsettings .= "\t" . 'ssl_protocols ' . str_replace(",", " ", $ssl_protocols) . ';' . "\n";
$sslsettings .= "\t" . 'ssl_ciphers ' . $ssl_cipher_list . ';' . "\n";
if (! empty(Settings::Get('system.dhparams_file'))) {
$dhparams = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.dhparams_file'));
if (! file_exists($dhparams)) {
@@ -675,7 +697,7 @@ class Nginx extends HttpConfigBase
// (When specifyng just one, there's no fallback when specific curve is not supported by client.)
// When >1.11.0: Defaults to auto, using recommended curves provided by OpenSSL.
// see https://github.com/Froxlor/Froxlor/issues/652
//$sslsettings .= "\t" . 'ssl_ecdh_curve secp384r1;' . "\n";
// $sslsettings .= "\t" . 'ssl_ecdh_curve secp384r1;' . "\n";
$sslsettings .= "\t" . 'ssl_prefer_server_ciphers on;' . "\n";
$sslsettings .= "\t" . 'ssl_session_cache shared:SSL:10m;' . "\n";
$sslsettings .= "\t" . 'ssl_certificate ' . \Froxlor\FileDir::makeCorrectFile($domain_or_ip['ssl_cert_file']) . ';' . "\n";
@@ -933,7 +955,7 @@ class Nginx extends HttpConfigBase
$phpopts .= "\t" . '}' . "\n\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\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n";
$phpopts .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n";

View File

@@ -37,7 +37,7 @@ class NginxFcgi extends Nginx
$php_options_text .= "\t" . 'location @php {' . "\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" . '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 PATH_INFO $2;' . "\n";
if ($domain['ssl'] == '1' && $ssl_vhost) {

View File

@@ -36,9 +36,7 @@ class WebserverBase
`d`.`phpsettingid`, `c`.`adminid`, `c`.`guid`, `c`.`email`,
`c`.`documentroot` AS `customerroot`, `c`.`deactivated`,
`c`.`phpenabled` AS `phpenabled_customer`,
`d`.`phpenabled` AS `phpenabled_vhost`,
`d`.`mod_fcgid_starter`,`d`.`mod_fcgid_maxrequests`,
`d`.`ocsp_stapling`
`d`.`phpenabled` AS `phpenabled_vhost`
FROM `" . TABLE_PANEL_DOMAINS . "` `d`
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`)

View File

@@ -30,8 +30,9 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
*/
self::$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "TasksCron: Searching for tasks to do");
// no type 99 (regenerate cron.d-file) and no type 20 (customer backup)
// order by type descending to re-create bind and then webserver at the end
$result_tasks_stmt = Database::query("
SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' AND `type` <> '20' ORDER BY `id` ASC
SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' AND `type` <> '20' ORDER BY `type` DESC, `id` ASC
");
$num_results = Database::num_rows();
$resultIDs = array();
@@ -108,7 +109,7 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
$where[] = "`id` = :id_" . (int) $id;
$where_data['id_' . $id] = $id;
}
$where = implode($where, ' OR ');
$where = implode(' OR ', $where);
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE " . $where);
Database::pexecute($del_stmt, $where_data);
unset($resultIDs);
@@ -120,10 +121,6 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
private static function rebuildWebserverConfigs()
{
// get configuration-I/O object
$configio = new \Froxlor\Cron\Http\ConfigIO();
// clean up old configs
$configio->cleanUp();
if (Settings::Get('system.webserver') == "apache2") {
$websrv = '\\Froxlor\\Cron\\Http\\Apache';
@@ -142,10 +139,15 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
}
}
// get configuration-I/O object
$configio = new \Froxlor\Cron\Http\ConfigIO();
// get webserver object
$webserver = new $websrv();
if (isset($webserver)) {
$webserver->init();
// clean up old configs
$configio->cleanUp();
$webserver->createIpPort();
$webserver->createVirtualHosts();
$webserver->createFileDirOptions();

View File

@@ -7,10 +7,10 @@ final class Froxlor
{
// Main version variable
const VERSION = '0.10.1';
const VERSION = '0.10.5';
// Database version (YYYYMMDDC where C is a daily counter)
const DBVERSION = '201910090';
const DBVERSION = '201910200';
// Distribution branding-tag (used for Debian etc.)
const BRANDING = '';

View File

@@ -87,6 +87,9 @@ class FroxlorLogger
self::$ml->pushHandler(new SyslogHandler('froxlor', LOG_USER, Logger::DEBUG));
break;
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));
break;
case 'mysql':

View File

@@ -252,6 +252,28 @@ class Store
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);
if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'mysql_access_host') {

View File

@@ -77,8 +77,7 @@ class Check
$mysql_access_host_array = array_map('trim', explode(',', $newfieldvalue));
foreach ($mysql_access_host_array as $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 != '%') {
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 != '%') {
return array(
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
'invalidmysqlhost',

View File

@@ -62,6 +62,38 @@ class Validate
\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
*
@@ -77,17 +109,35 @@ class Validate
* whether to allow private network addresses
* @param bool $allow_cidr
* 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
*/
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 = "";
if ($allow_cidr) {
$org_ip = $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];
if ($cidr_as_netmask && strlen($ip_cidr[1]) <= 2) {
$ip_cidr[1] = self::cidr2NetmaskAddr($org_ip);
}
$cidr = "/" . $ip_cidr[1];
} else {
$ip = $org_ip;

View File

@@ -180,6 +180,12 @@ return array(
'image' => 'icons/domain_add.png',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
'fields' => array(
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
),
'ssl_ipandport' => array(
'label' => $lng['domains']['ipandport_ssl_multi']['title'],
'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
@@ -227,11 +233,81 @@ return array(
),
'value' => array()
),
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
'override_tls' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'label' => $lng['admin']['domain_override_tls'],
'type' => 'checkbox',
'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(
'visible' => ($ssl_ipsandports != '' ? true : false),

View File

@@ -212,6 +212,12 @@ return array(
'image' => 'icons/domain_edit.png',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
'fields' => array(
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
),
'ssl_ipandport' => array(
'label' => $lng['domains']['ipandport_ssl_multi']['title'],
'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
@@ -265,11 +271,82 @@ return array(
$result['http2']
)
),
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
'override_tls' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'label' => $lng['admin']['domain_override_tls'],
'type' => 'checkbox',
'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(
'visible' => ($ssl_ipsandports != '' ? true : false),

View File

@@ -119,6 +119,26 @@ return array(
'type' => 'textarea',
'cols' => 60,
'rows' => 12
),
'ssl_default_vhostconf_domain' => array(
'visible' => (\Froxlor\Settings::Get('system.use_ssl') == 1 ? true : false),
'style' => 'align-top',
'label' => $lng['admin']['ipsandports']['ssl_default_vhostconf_domain'],
'desc' => $lng['serversettings']['default_vhostconf_domain']['description'],
'type' => 'textarea',
'cols' => 60,
'rows' => 12
),
'include_default_vhostconf_domain' => array(
'label' => $lng['admin']['include_ownvhostsettings'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array()
)
)
),
@@ -154,6 +174,25 @@ return array(
'label' => $lng['admin']['ipsandports']['ssl_cert_chainfile']['title'],
'desc' => $lng['admin']['ipsandports']['ssl_cert_chainfile']['description'],
'type' => 'text'
),
'ssl_specialsettings' => array(
'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()
)
)
)

View File

@@ -124,6 +124,29 @@ return array(
'cols' => 60,
'rows' => 12,
'value' => $result['default_vhostconf_domain']
),
'ssl_default_vhostconf_domain' => array(
'visible' => (\Froxlor\Settings::Get('system.use_ssl') == 1 ? true : false),
'style' => 'align-top',
'label' => $lng['admin']['ipsandports']['ssl_default_vhostconf_domain'],
'desc' => $lng['serversettings']['default_vhostconf_domain']['description'],
'type' => 'textarea',
'cols' => 60,
'rows' => 12,
'value' => $result['ssl_default_vhostconf_domain']
),
'include_default_vhostconf_domain' => array(
'label' => $lng['admin']['include_ownvhostsettings'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['include_default_vhostconf_domain']
)
)
)
),
@@ -165,6 +188,28 @@ return array(
'desc' => $lng['admin']['ipsandports']['ssl_cert_chainfile']['description'],
'type' => 'text',
'value' => $result['ssl_cert_chainfile']
),
'ssl_specialsettings' => array(
'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']
)
)
)
)

View File

@@ -44,7 +44,7 @@ return array(
'show_element' => (\Froxlor\Settings::Get('api.enabled') == true)
),
array(
'url' => 'customer_index.php?page=apihelp',
'url' => 'https://api.froxlor.org/doc/?v='.\Froxlor\Froxlor::getVersion(),
'label' => $lng['menue']['main']['apihelp'],
'show_element' => (\Froxlor\Settings::Get('api.enabled') == true)
),
@@ -195,7 +195,7 @@ return array(
'show_element' => (\Froxlor\Settings::Get('api.enabled') == true)
),
array(
'url' => 'admin_index.php?page=apihelp',
'url' => 'https://api.froxlor.org/doc/?v='.\Froxlor\Froxlor::getVersion(),
'label' => $lng['menue']['main']['apihelp'],
'show_element' => (\Froxlor\Settings::Get('api.enabled') == true)
),

View File

@@ -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['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
@@ -839,7 +839,8 @@ $lng['error']['nopermissionsorinvalidid'] = 'You don\'t have enough permissions
$lng['panel']['view'] = 'view';
$lng['question']['phpsetting_reallydelete'] = 'Do you really want to delete these settings? All domains which use these settings currently will be changed to the default config.';
$lng['question']['fpmsetting_reallydelete'] = 'Do you really want to delete these php-fpm settings? All php configurations which use these settings currently will be changed to the default config.';
$lng['admin']['phpsettings']['addnew'] = 'Create new settings';
$lng['admin']['phpsettings']['addnew'] = 'Create new PHP configuration';
$lng['admin']['fpmsettings']['addnew'] = 'Create new PHP version';
$lng['error']['phpsettingidwrong'] = 'A PHP Configuration with this id doesn\'t exist';
$lng['error']['descriptioninvalid'] = 'The description is too short, too long or contains illegal characters.';
$lng['error']['info'] = 'Info';
@@ -1829,7 +1830,7 @@ $lng['admin']['letsencrypt']['description'] = 'Get a free certificate from <a hr
$lng['customer']['letsencrypt']['title'] = 'Use Let\'s Encrypt';
$lng['customer']['letsencrypt']['description'] = 'Get a free certificate from <a href="https://letsencrypt.org">Let\'s Encrypt</a>. The certificate will be created and renewed automatically.<br><strong class="red">ATTENTION:</strong> This feature is still in beta.';
$lng['error']['sslredirectonlypossiblewithsslipport'] = 'Using Let\'s Encrypt is only possible when the domain has at least one ssl-enabled IP/port combination assigned.';
$lng['error']['nowildcardwithletsencrypt'] = 'Let\'s Encrypt cannot handle wildcard-domains using ACME v1. Please set the ServerAlias to WWW or disable it completely';
$lng['error']['nowildcardwithletsencrypt'] = 'Let\'s Encrypt cannot handle wildcard-domains using ACME in froxlor (requires dns-challenge), sorry. Please set the ServerAlias to WWW or disable it completely';
$lng['panel']['letsencrypt'] = 'Using Let\'s encrypt';
$lng['crondesc']['cron_letsencrypt'] = 'updating Let\'s Encrypt certificates';
$lng['serversettings']['letsencryptca']['title'] = "Let's Encrypt environment";
@@ -1866,6 +1867,7 @@ $lng['error']['autoupdate_6'] = 'Whoops, there was no (valid) version given to d
$lng['error']['autoupdate_7'] = 'The downloaded archive could not be found :(';
$lng['error']['autoupdate_8'] = 'The archive could not be extracted :(';
$lng['error']['autoupdate_9'] = 'The downloaded file did not pass the integrity check. Please try to update again.';
$lng['error']['autoupdate_10'] = 'Minimum supported version of PHP is 7.0';
$lng['admin']['server_php'] = 'PHP';
$lng['domains']['termination_date'] = 'Date of termination';
@@ -1985,8 +1987,7 @@ $lng['admin']['phpsettings']['activephpconfigs'] = 'In use for php-config(s)';
$lng['admin']['phpsettingsforsubdomains'] = 'Apply php-config to all subdomains:';
$lng['serversettings']['phpsettingsforsubdomains']['description'] = 'If yes the chosen php-config will be updated to all subdomains';
$lng['serversettings']['leapiversion']['title'] = "Choose Let's Encrypt ACME implementation";
$lng['serversettings']['leapiversion']['description'] = "Choose between ACME v1 and ACME v2 implementation for Let's Encrypt.";
$lng['error']['nowildcardwithletsencryptv2'] = 'Let\'s Encrypt can only validate wildcard-domains by DNS with ACME v2, sorry. Please set the ServerAlias to WWW or disable it completely';
$lng['serversettings']['leapiversion']['description'] = "Currently only ACME v2 implementation for Let's Encrypt is supported.";
$lng['admin']['phpsettings']['pass_authorizationheader'] = 'Add "-pass-header Authorization" / "CGIPassAuth On" to vhosts';
$lng['serversettings']['ssl']['ssl_protocols']['title'] = 'Configure the TLS protocol version';
$lng['serversettings']['ssl']['ssl_protocols']['description'] = 'This is a list of ssl protocols that you want (or don\'t want) to use when using SSL. <b>Notice:</b> Some older browsers may not support the newest protcol versions.<br /><br /><b>Default value is:</b><pre>TLSv1, TLSv1.2</pre>';
@@ -2072,3 +2073,9 @@ $lng['serversettings']['ssl']['tlsv13_cipher_list']['description'] = 'This is a
$lng['usersettings']['api_allowed']['title'] = 'Allow API access';
$lng['usersettings']['api_allowed']['description'] = 'When enabled in the settings, this user can create API keys and access the froxlor API';
$lng['usersettings']['api_allowed']['notice'] = 'API access is not allowed for your account.';
$lng['serversettings']['default_sslvhostconf']['title'] = 'Default SSL vHost-settings';
$lng['serversettings']['includedefault_sslvhostconf'] = 'Include non-SSL vHost-settings in SSL-vHost';
$lng['admin']['ownsslvhostsettings'] = 'Own SSL vHost-settings';
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Default SSL vHost-settings for every domain container';
$lng['customer']['total_diskspace'] = 'Total diskspace (MiB)';
$lng['admin']['domain_override_tls'] = 'Override system TLS settings';

View File

@@ -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['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
@@ -832,7 +832,8 @@ $lng['error']['nopermissionsorinvalidid'] = 'Entweder fehlen Ihnen die nötigen
$lng['panel']['view'] = 'ansehen';
$lng['question']['phpsetting_reallydelete'] = 'Wollen Sie diese PHP-Einstellungen wirklich löschen? Alle Domains die diese Einstellungen bis jetzt verwendet haben, werden dann auf die Standardeinstellungen umgestellt.';
$lng['question']['fpmsetting_reallydelete'] = 'Wollen Sie diese PHP-FPM Einstellungen wirklich löschen? Alle PHP Konfigurationen die diese Einstellungen bis jetzt verwendet haben, werden dann auf die Standardeinstellungen umgestellt.';
$lng['admin']['phpsettings']['addnew'] = 'Neue Konfiguration erstellen';
$lng['admin']['phpsettings']['addnew'] = 'Neue PHP Konfiguration erstellen';
$lng['admin']['fpmsettings']['addnew'] = 'Neue PHP Version erstellen';
$lng['error']['phpsettingidwrong'] = 'Eine PHP-Konfiguration mit dieser ID existiert nicht';
$lng['error']['descriptioninvalid'] = 'Der Beschreibungstext ist zu kurz, zu lang oder enthält ungültige Zeichen';
$lng['error']['info'] = 'Info';
@@ -1481,7 +1482,7 @@ $lng['admin']['letsencrypt']['description'] = 'Holt ein kostenloses Zertifikat v
$lng['customer']['letsencrypt']['title'] = 'SSL Zertifikat erstellen (Let\'s Encrypt)';
$lng['customer']['letsencrypt']['description'] = 'Holt ein kostenloses Zertifikat von <a href="https://letsencrypt.org">Let\'s Encrypt</a>. Das Zertifikat wird automatisch erstellt und verlängert.<br><strong class="red">ACHTUNG:</strong> Dieses Feature befindet sich noch im Test.';
$lng['error']['sslredirectonlypossiblewithsslipport'] = 'Die Nutzung von Let\'s Encrypt ist nur möglich, wenn die Domain mindestens eine IP/Port - Kombination mit aktiviertem SSL zugewiesen hat.';
$lng['error']['nowildcardwithletsencrypt'] = 'Let\'s Encrypt kann in ACME v1 nicht mit Wildcard-Domains umgehen. Bitte den ServerAlias auf WWW setzen oder deaktivieren';
$lng['error']['nowildcardwithletsencrypt'] = 'Let\'s Encrypt kann mittels ACME Wildcard-Domains nur via DNS validieren, sorry. Bitte den ServerAlias auf WWW setzen oder deaktivieren';
$lng['panel']['letsencrypt'] = 'Benutzt Let\'s encrypt';
$lng['crondesc']['cron_letsencrypt'] = 'Aktualisierung der Let\'s Encrypt Zertifikate';
$lng['serversettings']['letsencryptca']['title'] = "Let's Encrypt Umgebung";
@@ -1518,6 +1519,7 @@ $lng['error']['autoupdate_6'] = 'Woops, keine (gültige) Version angegeben für
$lng['error']['autoupdate_7'] = 'Das heruntergeladene Archiv konnte nicht gefunden werden :(';
$lng['error']['autoupdate_8'] = 'Das Archiv konnte nicht entpackt werden :(';
$lng['error']['autoupdate_9'] = 'Die heruntergeladene Datei konnte nicht verifiziert werden. Bitte erneut versuchen zu aktualisieren.';
$lng['error']['autoupdate_10'] = 'Minimum unterstützte Version von PHP ist 7.0';
$lng['domains']['termination_date'] = 'Kündigungsdatum';
$lng['domains']['termination_date_overview'] = 'gekündigt zum ';
@@ -1635,8 +1637,7 @@ $lng['admin']['phpsettings']['activephpconfigs'] = 'In Verwendung für PHP-Konfi
$lng['admin']['phpsettingsforsubdomains'] = 'PHP-Config für alle Subdomains übernehmen:';
$lng['serversettings']['phpsettingsforsubdomains']['description'] = 'Wenn ja, wird die gewählte PHP-Config für alle Subdomains übernommen';
$lng['serversettings']['leapiversion']['title'] = "Wählen Sie die Let's Encrypt ACME Implementierung";
$lng['serversettings']['leapiversion']['description'] = "Wählen Sie zwischen ACME v1 und ACME v2 Implementierung von Let's Encrypt.";
$lng['error']['nowildcardwithletsencryptv2'] = 'Let\'s Encrypt kann in ACME v2 Wildcard-Domains nur via DNS validieren, sorry. Bitte den ServerAlias auf WWW setzen oder deaktivieren';
$lng['serversettings']['leapiversion']['description'] = "Aktuell unterstützt froxlor lediglich die ACME v2 Implementierung von Let's Encrypt.";
$lng['admin']['phpsettings']['pass_authorizationheader'] = 'Füge "-pass-header Authorization" / "CGIPassAuth On" in Vhosts ein';
$lng['serversettings']['ssl']['ssl_protocols']['title'] = 'SSL Protokollversion festlegen';
$lng['serversettings']['ssl']['ssl_protocols']['description'] = 'Dies ist eine Liste von SSL/TLS Protokollversionen die genutzt werden sollen (oder auch nicht genutzt werden sollen), wenn SSL verwendet wird. <b>Hinweis:</b> Ältere Browser sind möglicherweise nicht vollständig zum neusten Protokoll kompatibel.<br /><br /><b>Standard-Wert ist:</b><pre>TLSv1, TLSv1.2</pre>';
@@ -1719,3 +1720,9 @@ $lng['serversettings']['ssl']['tlsv13_cipher_list']['description'] = 'Dies ist e
$lng['usersettings']['api_allowed']['title'] = 'Erlaube API Zugriff';
$lng['usersettings']['api_allowed']['description'] = 'Wenn in den Einstellungen aktiviert, kann der Benutzer API Schlüssel erstellen und auf die froxlor API Zugreifen';
$lng['usersettings']['api_allowed']['notice'] = 'API Zugriff ist für dieses Konto deaktiviert.';
$lng['serversettings']['default_sslvhostconf']['title'] = 'Standard SSL vHost-Einstellungen';
$lng['serversettings']['includedefault_sslvhostconf'] = 'Nicht-SSL vHost-Einstellungen in SSL-vHost inkludieren';
$lng['admin']['ownsslvhostsettings'] = 'Eigene SSL vHost-Einstellungen';
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Standard SSL vHost-Einstellungen für jeden Domain-Container';
$lng['customer']['total_diskspace'] = 'Gesamtspeicherplatz (MiB)';
$lng['admin']['domain_override_tls'] = 'Überschreibe System TLS Einstellungen';

View File

@@ -37,3 +37,6 @@ $lng['domains']['ipandport_ssl_multi']['description'] = $lng['domains']['ipandpo
$lng['success']['noupdatesavail'] = $lng['update']['noupdatesavail'];
$lng['error']['autoupdate_3'] = $lng['error']['customized_version'];
$lng['menue']['logger']['logger'] = $lng['admin']['loggersystem'];
$lng['serversettings']['default_sslvhostconf']['description'] = $lng['serversettings']['default_vhostconf']['description'];
$lng['admin']['include_ownvhostsettings'] = $lng['serversettings']['includedefault_sslvhostconf'];

View File

@@ -11,7 +11,7 @@ $header
<div class="overviewadd">
<img src="templates/{$theme}/assets/img/icons/add.png" alt="" />&nbsp;
<a href="{$linker->getLink(array('section' => 'phpsettings', 'page' => $page, 'action' => 'add'))}">{$lng['admin']['phpsettings']['addnew']}</a>
<a href="{$linker->getLink(array('section' => 'phpsettings', 'page' => $page, 'action' => 'add'))}">{$lng['admin']['fpmsettings']['addnew']}</a>
</div>
<table class="full hl">
@@ -32,7 +32,7 @@ $header
<if 15 < $count>
<div class="overviewadd">
<img src="templates/{$theme}/assets/img/icons/add.png" alt="" />&nbsp;
<a href="{$linker->getLink(array('section' => 'phpsettings', 'page' => $page, 'action' => 'add'))}">{$lng['admin']['phpsettings']['addnew']}</a>
<a href="{$linker->getLink(array('section' => 'phpsettings', 'page' => $page, 'action' => 'add'))}">{$lng['admin']['fpmsettings']['addnew']}</a>
</div>
</if>

View File

@@ -7,6 +7,20 @@ $header
<div class="grid-g">
<div class="grid-u-1-2" id="statsbox">
<if $userinfo['diskspace'] != '0'>
<div class="canvasbox">
<input type="hidden" id="totalspace" class="circular" data-used="{$userinfo['total_used']}" data-available="{$userinfo['diskspace']}">
<canvas id="totalspace-canvas" width="120" height="76"></canvas><br />
{$lng['customer']['total_diskspace']}<br />
<small>
{$userinfo['total_used']} {$lng['panel']['used']}<br />
<if $userinfo['diskspace'] != '∞'>
{$userinfo['diskspace']} {$lng['panel']['available']}
</if>
</small>
</div>
</if>
<if $userinfo['subdomains'] != '0'>
<div class="canvasbox">
<input type="hidden" id="subdomains" class="circular" data-used="{$userinfo['subdomains_used']}" data-available="{$userinfo['subdomains']}">

View File

@@ -65,7 +65,7 @@
</if>
<if \Froxlor\Settings::Get('api.enabled') == 1>
<li><a href="{$linker->getLink(array('section' => 'index', 'page' => 'apikeys'))}">{$lng['menue']['main']['apikeys']}</a></li>
<li><a href="https://api.froxlor.org/doc/" rel="external">{$lng['menue']['main']['apihelp']}</a></li>
<li><a href="https://api.froxlor.org/doc/?v={$version}" rel="external">{$lng['menue']['main']['apihelp']}</a></li>
</if>
</ul>
</li>

View File

@@ -189,7 +189,6 @@ class CertificatesTest extends TestCase
));
// export
openssl_csr_export($csr, $csrout);
openssl_x509_export($sscert, $certout);
openssl_pkey_export($privkey, $pkeyout, null);

View File

@@ -6,6 +6,7 @@ use Froxlor\Database\Database;
use Froxlor\Api\Commands\Admins;
use Froxlor\Api\Commands\Customers;
use Froxlor\Api\Commands\SubDomains;
use Froxlor\Api\Commands\Ftps;
/**
*
@@ -61,7 +62,9 @@ class CustomersTest extends TestCase
$this->assertEquals('secret', $result['custom_notes']);
// 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'];
$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.');
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']);
}
}

View File

@@ -58,13 +58,6 @@ class DomainZonesTest extends TestCase
DomainZones::getLocal($customer_userdata, $data)->get();
}
public function testAdminDomainZonesListing()
{
global $admin_userdata;
$this->expectExceptionCode(303);
DomainZones::getLocal($admin_userdata)->listing();
}
public function testAdminDomainZonesUpdate()
{
global $admin_userdata;
@@ -106,6 +99,25 @@ class DomainZonesTest extends TestCase
$this->assertEquals('www2 18000 IN A 127.0.0.1', $entry);
}
/**
* @depends testCustomerDomainZonesAddA
*/
public function testAdminDomainZonesListing()
{
global $admin_userdata;
$data = [
'domainname' => 'test2.local',
'record' => 'www2',
'type' => 'A',
'content' => '127.0.0.1'
];
$json_result = DomainZones::getLocal($admin_userdata, $data)->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']);
$this->assertEquals('www2', $result['list'][0]['record']);
}
/**
*
* @depends testCustomerDomainZonesAddA

View File

@@ -26,11 +26,17 @@ class DomainsTest extends TestCase
$customer_userdata = json_decode($json_result, true)['data'];
$data = [
'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();
$result = json_decode($json_result, true)['data'];
$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;
$data = [
'domainname' => 'test.local',
'email_only' => 1
'email_only' => 1,
'override_tls' => 0
];
$json_result = Domains::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['email_only']);
$this->assertFalse(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
}
/**

View File

@@ -50,7 +50,7 @@ class ValidateTest extends TestCase
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);
}
@@ -58,12 +58,12 @@ class ValidateTest extends TestCase
{
$this->expectException("Exception");
$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()
{
$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);
}
@@ -71,34 +71,65 @@ class ValidateTest extends TestCase
{
$this->expectException("Exception");
$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()
{
$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);
}
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);
}
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()
{
$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);
}
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()
{
$this->expectException("Exception");
$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()
{
$result = Validate::validateUrl("https://froxlor.org/");

View File

@@ -277,4 +277,21 @@ class FtpsTest extends TestCase
$result = json_decode($json_result, true)['data'];
$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();
}
}

View File

@@ -124,4 +124,63 @@ class FroxlorRpcTest extends TestCase
$this->assertEquals('listFunctions', $result['command']['method']);
$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
);
}
}