Compare commits

...

27 Commits

Author SHA1 Message Date
Michael Kaufmann
9167608794 set version to 0.10.1 for maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-10 14:55:45 +02:00
Michael Kaufmann
050af61082 show success in updater when there are no more old files to delete and exec() is disallowed (showed empty list)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-09 12:05:04 +02:00
Michael Kaufmann
2c23431daf show on API keys page wether api access is allowed
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-09 11:52:55 +02:00
Michael Kaufmann
4543c73b4f add possibility to enable/disable api access on a per user base
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-09 11:43:22 +02:00
Michael Kaufmann
88d85fc02e fix curly bracket array access (deprecated)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-09 07:59:38 +02:00
Michael Kaufmann
6102fabcb6 allow setting http2 flag for (sub)domains in customer view, fixes #725
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-09 07:59:11 +02:00
Michael Kaufmann
d7a7412973 Merge pull request #724 from kionez/add-ssl-expirationdate
Add expiration date to SSL certificates loaded via API request, fixes #723
2019-10-08 18:59:27 +02:00
kionez
1b3029b826 Fix typo 2019-10-08 18:50:10 +02:00
Michael Kaufmann
26cb53c8fb correctly validate that a domain has not a certificate in Certificates.add(), refs #722
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 18:44:42 +02:00
Michael Kaufmann
b4999fcc83 Throw exception if domain used to call Certificates.get() does not have a certificate, fixes #722
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 18:01:59 +02:00
kionez
05f602d457 Fix for null expiration date and coding style 2019-10-08 17:44:41 +02:00
Michael Kaufmann
89b95d61d2 return empty array in FroxlorAPI.php example class if last call was unsuccessful, fixes #722
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 17:36:42 +02:00
kionez
9ec03bade7 Add expiration date to SSL certificates loaded via API request 2019-10-08 17:32:03 +02:00
Michael Kaufmann
20699a15a6 update composer dependencies
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 12:54:15 +02:00
Michael Kaufmann
9b8a6e7e67 more php-7.4 compatibility
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 12:38:22 +02:00
Michael Kaufmann
3a8d5a9517 correct Mysql.add phpDoc to produce correct api-doc, fixes #721
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 12:11:00 +02:00
Michael Kaufmann
557b28a69d more php-7.4 compatibility
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 12:08:36 +02:00
Michael Kaufmann
0f1c5506e2 do not create username@domain ftp user if the default-ftp-user is being created in Ftps.add, fixes #720
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 12:04:10 +02:00
Michael Kaufmann
c6a93fa336 fix possible php-7.4 notice 'Trying to access array offset on value of type bool'
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 11:26:05 +02:00
Michael Kaufmann
466ea0fa99 show update steps for version updates (forgot that once or twice); add fallback for file deletion if exec() is not allowed; fix php7.4 warnings
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 10:54:08 +02:00
Michael Kaufmann
8f850ee7f3 simplify config-templates for cronjob setup
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-06 22:54:54 +02:00
Michael Kaufmann
55d21e475d set low timeout for version-check and output message if check is not possible (due to connection error, downtime of server, etc.)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-06 18:53:30 +02:00
Michael Kaufmann
fa3e3da7ac only flush privileges if anything at all happened
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-06 14:47:04 +02:00
Michael Kaufmann
05d66c034e update min-required version of php in composer.json
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-06 09:04:18 +02:00
Michael Kaufmann
98f0839664 Merge branch 'master' of github.com:Froxlor/Froxlor 2019-10-06 09:01:15 +02:00
Michael Kaufmann
4d52c6b6d0 Update README.md 2019-10-04 21:48:10 +02:00
Michael Kaufmann
eb5ea51da1 add explicit tlsv1.3 ciphersuite setting (used for apache-only as of now) 2019-10-04 17:43:11 +02:00
48 changed files with 377 additions and 251 deletions

View File

@@ -54,7 +54,7 @@ https://files.froxlor.org/releases/froxlor-latest.tar.gz [MD5](https://files.fro
[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-debian)
/etc/apt/sources.list.d/froxlor.list
> deb http://debian.froxlor.org {wheezy|jessie|stretch} main
> deb http://debian.froxlor.org {stretch|buster} main
### Gentoo repository

View File

@@ -54,6 +54,16 @@ return array(
'default' => 'ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128',
'save_method' => 'storeSettingField'
),
'system_tlsv13_cipher_list' => array(
'label' => $lng['serversettings']['ssl']['tlsv13_cipher_list'],
'settinggroup' => 'system',
'varname' => 'tlsv13_cipher_list',
'type' => 'string',
'string_emptyallowed' => true,
'default' => '',
'visible' => \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1,
'save_method' => 'storeSettingField',
),
'system_ssl_cert_file' => array(
'label' => $lng['serversettings']['ssl']['ssl_cert_file'],
'settinggroup' => 'system',

View File

@@ -43,8 +43,11 @@ if ($page == 'overview') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "checking auto-update");
// check for new version
$latestversion = HttpClient::urlGet(UPDATE_URI);
try {
$latestversion = HttpClient::urlGet(UPDATE_URI, true, 3);
} catch (\Exception $e) {
\Froxlor\UI\Response::dynamic_error("Version-check currently unavailable, please try again later");
}
$latestversion = explode('|', $latestversion);
if (is_array($latestversion) && count($latestversion) >= 1) {
@@ -175,6 +178,8 @@ elseif ($page == 'extract') {
$zip->close();
// success - remove unused archive
@unlink($localArchive);
// wait a bit before we redirect to be sure
sleep(2);
} else {
// error
\Froxlor\UI\Response::redirectTo($filename, array(

View File

@@ -91,10 +91,16 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
'cid' => $row['customerid']
));
$row['webspace_used'] = round($usages['webspace'] / 1024, $dec_places);
$row['mailspace_used'] = round($usages['mail'] / 1024, $dec_places);
$row['dbspace_used'] = round($usages['mysql'] / 1024, $dec_places);
if ($usages)
{
$row['webspace_used'] = round($usages['webspace'] / 1024, $dec_places);
$row['mailspace_used'] = round($usages['mail'] / 1024, $dec_places);
$row['dbspace_used'] = round($usages['mysql'] / 1024, $dec_places);
} else {
$row['webspace_used'] = 0;
$row['mailspace_used'] = 0;
$row['dbspace_used'] = 0;
}
$row['traffic_used'] = round($row['traffic_used'] / (1024 * 1024), $dec_places);
$row['traffic'] = round($row['traffic'] / (1024 * 1024), $dec_places);
$row['diskspace_used'] = round($row['diskspace_used'] / 1024, $dec_places);

View File

@@ -30,7 +30,7 @@
"docs": "https://github.com/Froxlor/Froxlor/wiki"
},
"require": {
"php": ">=5.6",
"php": ">=7.0",
"ext-session": "*",
"ext-ctype": "*",
"ext-pdo": "*",

80
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5be3ef1341b33f64d1eab9a4afa10f20",
"content-hash": "77819131afd1abe70f1ea6caad9fc3e5",
"packages": [
{
"name": "algo26-matthias/idna-convert",
@@ -922,22 +922,22 @@
},
{
"name": "phpspec/prophecy",
"version": "1.8.1",
"version": "1.9.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76"
"reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
"reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203",
"reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.3|^7.0",
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
"sebastian/comparator": "^1.1|^2.0|^3.0",
"sebastian/recursion-context": "^1.0|^2.0|^3.0"
},
@@ -981,7 +981,7 @@
"spy",
"stub"
],
"time": "2019-06-13T12:50:23+00:00"
"time": "2019-10-03T11:07:50+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -1237,16 +1237,16 @@
},
{
"name": "phpunit/phpunit",
"version": "8.3.5",
"version": "8.4.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "302faed7059fde575cf3403a78c730c5e3a62750"
"reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/302faed7059fde575cf3403a78c730c5e3a62750",
"reference": "302faed7059fde575cf3403a78c730c5e3a62750",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/366a4a0f2b971fd43b7c351d621e8dd7d7131869",
"reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869",
"shasum": ""
},
"require": {
@@ -1290,7 +1290,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "8.3-dev"
"dev-master": "8.4-dev"
}
},
"autoload": {
@@ -1316,7 +1316,7 @@
"testing",
"xunit"
],
"time": "2019-09-14T09:12:03+00:00"
"time": "2019-10-07T12:57:41+00:00"
},
{
"name": "psr/container",
@@ -2125,16 +2125,16 @@
},
{
"name": "symfony/config",
"version": "v4.3.4",
"version": "v4.3.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
"reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece"
"reference": "0acb26407a9e1a64a275142f0ae5e36436342720"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/07d49c0f823e0bc367c6d84e35b61419188a5ece",
"reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece",
"url": "https://api.github.com/repos/symfony/config/zipball/0acb26407a9e1a64a275142f0ae5e36436342720",
"reference": "0acb26407a9e1a64a275142f0ae5e36436342720",
"shasum": ""
},
"require": {
@@ -2185,20 +2185,20 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
"time": "2019-08-26T08:26:39+00:00"
"time": "2019-09-19T15:51:53+00:00"
},
{
"name": "symfony/console",
"version": "v4.3.4",
"version": "v4.3.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "de63799239b3881b8a08f8481b22348f77ed7b36"
"reference": "929ddf360d401b958f611d44e726094ab46a7369"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/de63799239b3881b8a08f8481b22348f77ed7b36",
"reference": "de63799239b3881b8a08f8481b22348f77ed7b36",
"url": "https://api.github.com/repos/symfony/console/zipball/929ddf360d401b958f611d44e726094ab46a7369",
"reference": "929ddf360d401b958f611d44e726094ab46a7369",
"shasum": ""
},
"require": {
@@ -2260,20 +2260,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2019-08-26T08:26:39+00:00"
"time": "2019-10-07T12:36:49+00:00"
},
{
"name": "symfony/dependency-injection",
"version": "v4.3.4",
"version": "v4.3.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
"reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9"
"reference": "e1e0762a814b957a1092bff75a550db49724d05b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d3ad14b66ac773ba6123622eb9b5b010165fe3d9",
"reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e1e0762a814b957a1092bff75a550db49724d05b",
"reference": "e1e0762a814b957a1092bff75a550db49724d05b",
"shasum": ""
},
"require": {
@@ -2333,11 +2333,11 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
"time": "2019-08-26T16:27:33+00:00"
"time": "2019-10-02T12:58:58+00:00"
},
{
"name": "symfony/filesystem",
"version": "v4.3.4",
"version": "v4.3.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
@@ -2387,16 +2387,16 @@
},
{
"name": "symfony/finder",
"version": "v4.3.4",
"version": "v4.3.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2"
"reference": "5e575faa95548d0586f6bedaeabec259714e44d1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/86c1c929f0a4b24812e1eb109262fc3372c8e9f2",
"reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2",
"url": "https://api.github.com/repos/symfony/finder/zipball/5e575faa95548d0586f6bedaeabec259714e44d1",
"reference": "5e575faa95548d0586f6bedaeabec259714e44d1",
"shasum": ""
},
"require": {
@@ -2432,7 +2432,7 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2019-08-14T12:26:46+00:00"
"time": "2019-09-16T11:29:48+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -2611,16 +2611,16 @@
},
{
"name": "symfony/service-contracts",
"version": "v1.1.6",
"version": "v1.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3"
"reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/ea7263d6b6d5f798b56a45a5b8d686725f2719a3",
"reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/ffcde9615dc5bb4825b9f6aed07716f1f57faae0",
"reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0",
"shasum": ""
},
"require": {
@@ -2665,7 +2665,7 @@
"interoperability",
"standards"
],
"time": "2019-08-20T14:44:19+00:00"
"time": "2019-09-17T11:12:18+00:00"
},
{
"name": "theseer/directoryscanner",
@@ -2942,7 +2942,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.6",
"php": ">=7.0",
"ext-session": "*",
"ext-ctype": "*",
"ext-pdo": "*",

View File

@@ -93,11 +93,17 @@ if ($page == 'overview') {
'cid' => $userinfo['customerid']
));
if ($usages)
{
$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'));
} else {
$userinfo['diskspace_used'] = 0;
$userinfo['mailspace_used'] = 0;
$userinfo['dbspace_used'] = 0;
}
$userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, Settings::Get('panel.decimal_places'));
$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['traffic'] = round($userinfo['traffic'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
$userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains');

View File

@@ -148,6 +148,11 @@ class FroxlorAPI
*/
public function getLastResponse(): array
{
if (!empty($this->getLastError())) {
// nothing is returned when the last call
// was not successful
return [];
}
return $this->last_body;
}

View File

@@ -132,6 +132,7 @@ CREATE TABLE `panel_admins` (
`custom_notes_show` tinyint(1) NOT NULL default '0',
`type_2fa` tinyint(1) NOT NULL default '0',
`data_2fa` varchar(500) NOT NULL default '',
`api_allowed` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`adminid`),
UNIQUE KEY `loginname` (`loginname`)
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -199,6 +200,7 @@ CREATE TABLE `panel_customers` (
`allowed_phpconfigs` varchar(500) NOT NULL default '',
`type_2fa` tinyint(1) NOT NULL default '0',
`data_2fa` varchar(500) NOT NULL default '',
`api_allowed` tinyint(1) NOT NULL default '1',
`logviewenabled` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`customerid`),
UNIQUE KEY `loginname` (`loginname`)
@@ -640,6 +642,7 @@ opcache.interned_strings_buffer'),
('system', 'nssextrausers', '0'),
('system', 'disable_le_selfcheck', '0'),
('system', 'ssl_protocols', 'TLSv1,TLSv1.2'),
('system', 'tlsv13_cipher_list', ''),
('system', 'logfiles_format', ''),
('system', 'logfiles_type', '1'),
('system', 'logfiles_piped', '0'),
@@ -682,8 +685,8 @@ opcache.interned_strings_buffer'),
('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'customer_hide_options', ''),
('panel', 'is_configured', '0'),
('panel', 'version', '0.10.0'),
('panel', 'db_version', '201909150');
('panel', 'version', '0.10.1'),
('panel', 'db_version', '201910090');
DROP TABLE IF EXISTS `panel_tasks`;

View File

@@ -407,6 +407,7 @@ class FroxlorInstall
`name` = 'Froxlor-Administrator',
`email` = :email,
`def_language` = :deflang,
`api_allowed` = 1,
`customers` = -1,
`customers_see_all` = 1,
`caneditphpsettings` = 1,

View File

@@ -265,6 +265,7 @@ if (\Froxlor\Froxlor::isDatabaseVersion('201904100')) {
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.0-rc1')) {
showUpdateStep("Updating from 0.10.0-rc1 to 0.10.0-rc2", false);
\Froxlor\Froxlor::updateToVersion('0.10.0-rc2');
}
@@ -302,17 +303,59 @@ if (\Froxlor\Froxlor::isDatabaseVersion('201907270')) {
"templates/Sparkle/admin/tickets",
"templates/Sparkle/customer/tickets"
);
$disabled = explode(',', ini_get('disable_functions'));
$exec_allowed = !in_array('exec', $disabled);
$del_list = "";
foreach ($to_clean as $filedir) {
$complete_filedir = \Froxlor\Froxlor::getInstallDir() . $filedir;
if (file_exists($complete_filedir)) {
Froxlor\FileDir::safe_exec("rm -rf " . escapeshellarg($complete_filedir));
if ($exec_allowed) {
Froxlor\FileDir::safe_exec("rm -rf " . escapeshellarg($complete_filedir));
} else {
$del_list .= "rm -rf " . escapeshellarg($complete_filedir) . PHP_EOL;
}
}
}
if ($exec_allowed) {
lastStepStatus(0);
} else {
if (empty($del_list)) {
// none of the files existed
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>';
}
}
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201909150');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.0-rc2')) {
showUpdateStep("Updating from 0.10.0-rc2 to 0.10.0 final", false);
\Froxlor\Froxlor::updateToVersion('0.10.0');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201909150')) {
showUpdateStep("Adding TLSv1.3-cipherlist setting");
Settings::AddNew("system.tlsv13_cipher_list", '');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201910030');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201910030')) {
showUpdateStep("Adding field api_allowed to admins and customers");
Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `api_allowed` tinyint(1) NOT NULL default '1';");
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `api_allowed` tinyint(1) NOT NULL default '1';");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201910090');
}
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');
}

View File

@@ -97,6 +97,8 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, default auto-generated
* @param string $def_language
* optional, default is system-default language
* @param bool $api_allowed
* optional, default is true if system setting api.enabled is true, else false
* @param string $custom_notes
* optional, default empty
* @param bool $custom_notes_show
@@ -171,6 +173,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// parameters
$def_language = $this->getParam('def_language', true, Settings::Get('panel.standardlanguage'));
$api_allowed = $this->getBoolParam('api_allowed', true, Settings::Get('api.enabled'));
$custom_notes = $this->getParam('custom_notes', true, '');
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0);
$password = $this->getParam('admin_password', true, '');
@@ -271,6 +274,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
'name' => $name,
'email' => $email,
'lang' => $def_language,
'api_allowed' => $api_allowed,
'change_serversettings' => $change_serversettings,
'customers' => $customers,
'customers_see_all' => $customers_see_all,
@@ -299,6 +303,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
`name` = :name,
`email` = :email,
`def_language` = :lang,
`api_allowed` = :api_allowed,
`change_serversettings` = :change_serversettings,
`customers` = :customers,
`customers_see_all` = :customers_see_all,
@@ -350,6 +355,8 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, default auto-generated
* @param string $def_language
* optional, default is system-default language
* @param bool $api_allowed
* optional, default is true if system setting api.enabled is true, else false
* @param string $custom_notes
* optional, default empty
* @param string $theme
@@ -444,6 +451,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// you cannot edit some of the details of yourself
if ($result['adminid'] == $this->getUserDetail('adminid')) {
$api_allowed = $result['api_allowed'];
$deactivated = $result['deactivated'];
$customers = $result['customers'];
$domains = $result['domains'];
@@ -462,6 +470,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$traffic = $result['traffic'];
$ipaddress = ($result['ip'] != - 1 ? json_decode($result['ip'], true) : - 1);
} else {
$api_allowed = $this->getBoolParam('api_allowed', true, $result['api_allowed']);
$deactivated = $this->getBoolParam('deactivated', true, $result['deactivated']);
$dec_places = Settings::Get('panel.decimal_places');
@@ -578,6 +587,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
'name' => $name,
'email' => $email,
'lang' => $def_language,
'api_allowed' => $api_allowed,
'change_serversettings' => $change_serversettings,
'customers' => $customers,
'customers_see_all' => $customers_see_all,
@@ -607,6 +617,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
`name` = :name,
`email` = :email,
`def_language` = :lang,
`api_allowed` = :api_allowed,
`change_serversettings` = :change_serversettings,
`customers` = :customers,
`customers_see_all` = :customers_see_all,
@@ -793,7 +804,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param string $extra
* optional, default empty
* @param int $increase_by
* optional, default 1
* optional, default 1
*/
public static function increaseUsage($adminid = 0, $resource = null, $extra = '', $increase_by = 1)
{
@@ -808,7 +819,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param string $extra
* optional, default empty
* @param int $decrease_by
* optional, default 1
* optional, default 1
*/
public static function decreaseUsage($adminid = 0, $resource = null, $extra = '', $decrease_by = 1)
{

View File

@@ -63,10 +63,19 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$ssl_cert_chainfile = $this->getParam('ssl_cert_chainfile', true, '');
// validate whether the domain does not already have an entry
$result = $this->apiCall('Certificates.get', array(
'id' => $domainid
));
if (empty($result)) {
$has_cert = true;
try {
$this->apiCall('Certificates.get', array(
'id' => $domainid
));
} catch (\Exception $e) {
if ($e->getCode() == 412) {
$has_cert = false;
} else {
throw $e;
}
}
if (!$has_cert) {
$this->addOrUpdateCertificate($domain['id'], $ssl_cert_file, $ssl_key_file, $ssl_ca_file, $ssl_cert_chainfile, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added ssl-certificate for '" . $domain['domain'] . "'");
$result = $this->apiCall('Certificates.get', array(
@@ -110,6 +119,9 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = Database::pexecute_first($stmt, array(
"domainid" => $domainid
));
if (! $result) {
throw new \Exception("Domain '" . $domain['domain'] . "' does not have a certificate.", 412);
}
return $this->response(200, "successfull", $result);
}
@@ -271,6 +283,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
throw new \Exception("Unable to determine SSL certificate. Maybe no access?", 406);
}
/**
* insert or update certificates entry
*
@@ -292,6 +305,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
}
$do_verify = true;
$expirationdate = null;
// no cert-file given -> forget everything
if ($ssl_cert_file == '') {
$ssl_key_file = '';
@@ -332,6 +346,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
} else {
\Froxlor\UI\Response::standard_error('sslcertificateinvalidcert', '', true);
}
$expirationdate = empty($cert_content['validTo_time_t']) ? null : date("Y-m-d H:i:s", $cert_content['validTo_time_t']);
}
// Add/Update database entry
@@ -345,7 +360,8 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
`ssl_cert_file` = :ssl_cert_file,
`ssl_key_file` = :ssl_key_file,
`ssl_ca_file` = :ssl_ca_file,
`ssl_cert_chainfile` = :ssl_cert_chainfile
`ssl_cert_chainfile` = :ssl_cert_chainfile,
`expirationdate` = :expirationdate
" . $qrywhere . " `domainid`= :domainid
");
$params = array(
@@ -353,6 +369,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
"ssl_key_file" => $ssl_key_file,
"ssl_ca_file" => $ssl_ca_file,
"ssl_cert_chainfile" => $ssl_cert_chainfile,
"expirationdate" => $expirationdate,
"domainid" => $domainid
);
Database::pexecute($stmt, $params, true, true);

View File

@@ -136,6 +136,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* optional
* @param string $def_language,
* optional, default is system-default language
* @param bool $api_allowed
* optional, default is true if system setting api.enabled is true, else false
* @param int $gender
* optional, 0 = no-gender, 1 = male, 2 = female
* @param string $custom_notes
@@ -229,6 +231,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$fax = $this->getParam('fax', true, '');
$customernumber = $this->getParam('customernumber', true, '');
$def_language = $this->getParam('def_language', true, Settings::Get('panel.standardlanguage'));
$api_allowed = $this->getBoolParam('api_allowed', true, Settings::Get('api.enabled'));
$gender = (int) $this->getParam('gender', true, 0);
$custom_notes = $this->getParam('custom_notes', true, '');
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0);
@@ -388,26 +391,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
\Froxlor\UI\Response::standard_error('documentrootexists', $documentroot, true);
}
if ($createstdsubdomain != '1') {
$createstdsubdomain = '0';
}
if ($phpenabled != '0') {
$phpenabled = '1';
}
if ($perlenabled != '0') {
$perlenabled = '1';
}
if ($dnsenabled != '0') {
$dnsenabled = '1';
}
if ($logviewenabled != '0') {
$logviewenabled = '1';
}
if ($password == '') {
$password = \Froxlor\System\Crypt::generatePassword();
}
@@ -430,6 +413,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'email' => $email,
'customerno' => $customernumber,
'lang' => $def_language,
'api_allowed' => $api_allowed,
'docroot' => $documentroot,
'guid' => $guid,
'diskspace' => $diskspace,
@@ -470,6 +454,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
`email` = :email,
`customernumber` = :customerno,
`def_language` = :lang,
`api_allowed` = :api_allowed,
`documentroot` = :docroot,
`guid` = :guid,
`diskspace` = :diskspace,
@@ -755,6 +740,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* optional
* @param string $def_language,
* optional, default is system-default language
* @param bool $api_allowed
* optional, default is true if system setting api.enabled is true, else false
* @param int $gender
* optional, 0 = no-gender, 1 = male, 2 = female
* @param string $custom_notes
@@ -857,6 +844,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$fax = $this->getParam('fax', true, $result['fax']);
$customernumber = $this->getParam('customernumber', true, $result['customernumber']);
$def_language = $this->getParam('def_language', true, $result['def_language']);
$api_allowed = $this->getBoolParam('api_allowed', true, $result['api_allowed']);
$gender = (int) $this->getParam('gender', true, $result['gender']);
$custom_notes = $this->getParam('custom_notes', true, $result['custom_notes']);
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, $result['custom_notes_show']);
@@ -999,30 +987,10 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
\Froxlor\System\Cronjob::inserttask('1');
}
if ($deactivated != '1') {
$deactivated = '0';
}
if ($phpenabled != '0') {
$phpenabled = '1';
}
if ($perlenabled != '0') {
$perlenabled = '1';
}
if ($dnsenabled != '0') {
$dnsenabled = '1';
}
if ($phpenabled != $result['phpenabled'] || $perlenabled != $result['perlenabled']) {
\Froxlor\System\Cronjob::inserttask('1');
}
if ($logviewenabled != '0') {
$logviewenabled = '1';
}
// activate/deactivate customer services
if ($deactivated != $result['deactivated']) {
@@ -1067,6 +1035,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$dbm = new \Froxlor\Database\DbManager($this->logger());
// For each of them
$priv_changed = false;
while ($row_database = $databases_stmt->fetch(\PDO::FETCH_ASSOC)) {
if ($last_dbserver != $row_database['dbserver']) {
@@ -1087,10 +1056,13 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$dbm->getManager()->enableUser($row_database['databasename'], $mysql_access_host);
}
}
$priv_changed = true;
}
// At last flush the new privileges
$dbm->getManager()->flushPrivileges();
if ($priv_changed) {
$dbm->getManager()->flushPrivileges();
}
Database::needRoot(false);
// reactivate/deactivate api-keys
@@ -1162,7 +1134,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'dnsenabled' => $dnsenabled,
'logviewenabled' => $logviewenabled,
'custom_notes' => $custom_notes,
'custom_notes_show' => $custom_notes_show
'custom_notes_show' => $custom_notes_show,
'api_allowed' => $api_allowed
);
$upd_data = $upd_data + $admin_upd_data;
}
@@ -1203,7 +1176,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
`dnsenabled` = :dnsenabled,
`logviewenabled` = :logviewenabled,
`custom_notes` = :custom_notes,
`custom_notes_show` = :custom_notes_show";
`custom_notes_show` = :custom_notes_show,
`api_allowed` = :api_allowed";
$upd_query .= $admin_upd_query;
}
$upd_query .= " WHERE `customerid` = :customerid";
@@ -1371,6 +1345,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$dbm = new \Froxlor\Database\DbManager($this->logger());
$priv_changed = false;
while ($row_database = $databases_stmt->fetch(\PDO::FETCH_ASSOC)) {
if ($last_dbserver != $row_database['dbserver']) {
Database::needRoot(true, $row_database['dbserver']);
@@ -1378,8 +1353,11 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$last_dbserver = $row_database['dbserver'];
}
$dbm->getManager()->deleteDatabase($row_database['databasename']);
$priv_changed = true;
}
if ($priv_changed) {
$dbm->getManager()->flushPrivileges();
}
$dbm->getManager()->flushPrivileges();
Database::needRoot(false);
// delete customer itself

View File

@@ -39,7 +39,11 @@ class Froxlor extends \Froxlor\Api\ApiCommand
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] checking for updates");
// check for new version
$latestversion = \Froxlor\Http\HttpClient::urlGet(UPDATE_URI);
try {
$latestversion = \Froxlor\Http\HttpClient::urlGet(UPDATE_URI, true, 3);
} catch (\Exception $e) {
$latestversion = \Froxlor\Froxlor::getVersion()."|Version-check currently unavailable, please try again later";
}
$latestversion = explode('|', $latestversion);
if (is_array($latestversion) && count($latestversion) >= 1) {

View File

@@ -105,7 +105,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$sendinfomail = 0;
}
if (Settings::Get('customer.ftpatdomain') == '1') {
if (Settings::Get('customer.ftpatdomain') == '1' && !$is_defaultuser) {
if ($ftpusername == '') {
\Froxlor\UI\Response::standard_error(array(
'stringisempty',

View File

@@ -33,7 +33,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, description for database
* @param bool $sendinfomail
* optional, send created resource-information to customer, default: false
* @param int $customer_id
* @param int $customerid
* required when called as admin, not needed when called as customer
*
* @access admin, customer

View File

@@ -45,6 +45,8 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* optional, whether to generate a https-redirect or not, default false; requires SSL to be enabled
* @param bool $letsencrypt
* optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled
* @param bool $http2
* optional, whether to enable http/2 for this subdomain (requires to be enabled in the settings), default 0 (false)
* @param int $hsts_maxage
* optional max-age value for HSTS header, default 0
* @param bool $hsts_sub
@@ -76,12 +78,14 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
if (Settings::Get('system.use_ssl')) {
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, 0);
$letsencrypt = $this->getBoolParam('letsencrypt', true, 0);
$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);
} else {
$ssl_redirect = 0;
$letsencrypt = 0;
$http2 = 0;
$hsts_maxage = 0;
$hsts_sub = 0;
$hsts_preload = 0;
@@ -241,7 +245,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$phpsid_result['phpsettingid'] = intval($phpsettingid);
}
// acutall insert domain
// actually insert domain
$stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET
`customerid` = :customerid,
@@ -261,6 +265,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
`ssl_redirect` = :ssl_redirect,
`phpsettingid` = :phpsettingid,
`letsencrypt` = :letsencrypt,
`http2` = :http2,
`hsts` = :hsts,
`hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload
@@ -283,6 +288,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"ssl_redirect" => $ssl_redirect,
"phpsettingid" => $phpsid_result['phpsettingid'],
"letsencrypt" => $letsencrypt,
"http2" => $http2,
"hsts" => $hsts_maxage,
"hsts_sub" => $hsts_sub,
"hsts_preload" => $hsts_preload
@@ -430,6 +436,8 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* optional, whether to generate a https-redirect or not, default false; requires SSL to be enabled
* @param bool $letsencrypt
* optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled
* @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
* optional max-age value for HSTS header
* @param bool $hsts_sub
@@ -473,12 +481,14 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
if (Settings::Get('system.use_ssl')) {
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, $result['ssl_redirect']);
$letsencrypt = $this->getBoolParam('letsencrypt', true, $result['letsencrypt']);
$http2 = $this->getBoolParam('http2', true, $result['http2']);
$hsts_maxage = $this->getParam('hsts_maxage', true, $result['hsts']);
$hsts_sub = $this->getBoolParam('hsts_sub', true, $result['hsts_sub']);
$hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']);
} else {
$ssl_redirect = 0;
$letsencrypt = 0;
$http2 = 0;
$hsts_maxage = 0;
$hsts_sub = 0;
$hsts_preload = 0;
@@ -599,6 +609,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
`openbasedir_path`= :openbasedir_path,
`ssl_redirect`= :ssl_redirect,
`letsencrypt`= :letsencrypt,
`http2` = :http2,
`hsts` = :hsts,
`hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload,
@@ -614,6 +625,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"openbasedir_path" => $openbasedir_path,
"ssl_redirect" => $ssl_redirect,
"letsencrypt" => $letsencrypt,
"http2" => $http2,
"hsts" => $hsts_maxage,
"hsts_sub" => $hsts_sub,
"hsts_preload" => $hsts_preload,

View File

@@ -55,13 +55,20 @@ class FroxlorRPC
*/
private static function validateAuth($key, $secret)
{
$sel_stmt = \Froxlor\Database\Database::prepare("SELECT * FROM `api_keys` WHERE `apikey` = :ak AND `secret` = :as");
$sel_stmt = \Froxlor\Database\Database::prepare("
SELECT ak.*, a.api_allowed as admin_api_allowed, c.api_allowed as cust_api_allowed
FROM `api_keys` ak
LEFT JOIN `panel_admins` a ON a.adminid = ak.adminid
LEFT JOIN `panel_customers` c ON c.customerid = ak.customerid
WHERE `apikey` = :ak AND `secret` = :as
");
$result = \Froxlor\Database\Database::pexecute_first($sel_stmt, array(
'ak' => $key,
'as' => $secret
), true, true);
if ($result) {
if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == - 1 || $result['valid_until'] >= time())) {
if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == - 1 || $result['valid_until'] >= time()) && (($result['customerid'] == 0 && $result['admin_api_allowed'] == 1) || ($result['customerid'] > 0 && $result['cust_api_allowed'] == 1))) {
// get user to check whether api call is allowed
if (! empty($result['allowed_from'])) {
// @todo allow specification and validating of whole subnets later
$ip_list = explode(",", $result['allowed_from']);

View File

@@ -103,7 +103,7 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
echo PHP_EOL;
while (! in_array($_daemons_config['distro'], $distributions_select_data)) {
$_daemons_config['distro'] = ConfigServicesCmd::getInput("choose distribution", "stretch");
$_daemons_config['distro'] = ConfigServicesCmd::getInput("choose distribution", "buster");
}
// go through all services and let user check whether to include it or not

View File

@@ -477,6 +477,10 @@ class Apache extends HttpConfigBase
// this makes it more secure, thx to Marcel (08/2013)
$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) {
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite TLSv1.3 ' . Settings::Get('system.tlsv13_cipher_list') . "\n";
}
$this->virtualhosts_data[$vhosts_filename] .= ' SSLVerifyDepth 10' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n";
@@ -924,7 +928,7 @@ class Apache extends HttpConfigBase
'domainid' => $domain['id']
));
if ($ssldestport['port'] != '') {
if ($ssldestport && $ssldestport['port'] != '') {
$_sslport = ":" . $ssldestport['port'];
}
@@ -959,7 +963,7 @@ class Apache extends HttpConfigBase
$vhost_content .= ' SSLProtocol -ALL +' . str_replace(",", " +", Settings::Get('system.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";
$vhost_content .= ' Protocols h2 http/1.1' . "\n";
}
if (! empty(Settings::Get('system.dhparams_file'))) {
$dhparams = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.dhparams_file'));
@@ -973,6 +977,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 .= ' SSLVerifyDepth 10' . "\n";
$vhost_content .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n";

View File

@@ -191,7 +191,7 @@ class ConfigIO
/**
* don't do anything if the file does not exist
*/
if (@file_exists($awstatsclean['fullentry'])) {
if (@file_exists($awstatsclean['fullentry']) && $awstatsclean['entry'] != '.' && $awstatsclean['entry'] != '..') {
$awstatsclean['fh'] = fopen($awstatsclean['fullentry'], 'r');
$awstatsclean['headerRead'] = fgets($awstatsclean['fh'], strlen($awstatsclean['header']) + 1);
fclose($awstatsclean['fh']);

View File

@@ -133,7 +133,7 @@ class HttpConfigBase
");
$ssldestport = Database::pexecute_first($ssldestport_stmt);
if ($ssldestport['port'] != '') {
if ($ssldestport && $ssldestport['port'] != '') {
$_sslport = ":" . $ssldestport['port'];
}

View File

@@ -451,7 +451,7 @@ class Lighttpd extends HttpConfigBase
'domainid' => $domain['id']
));
if ($ssldestport['port'] != '') {
if ($ssldestport && $ssldestport['port'] != '') {
$_sslport = ":" . $ssldestport['port'];
}

View File

@@ -476,7 +476,7 @@ class Nginx extends HttpConfigBase
'domainid' => $domain['id']
));
if ($ssldestport['port'] != '') {
if ($ssldestport && $ssldestport['port'] != '') {
$_sslport = ":" . $ssldestport['port'];
}

View File

@@ -44,8 +44,9 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
echo "Below are possible parameters for this file\n\n";
echo "--[cronname]\t\tincludes the given cron-file\n";
echo "--force\t\t\tforces re-generating of config-files (webserver, nameserver, etc.)\n";
echo "--run-task\t\trun a specific task [1 = re-generate configs, 4 = re-generate dns zones, 10 = re-set quotas, 99 = re-create cron.d-file]\n";
echo "--debug\t\t\toutput debug information about what is going on to STDOUT.\n";
echo "--no-fork\t\t\tdo not fork to backkground (traffic cron only).\n\n";
echo "--no-fork\t\tdo not fork to backkground (traffic cron only).\n\n";
}
/**
@@ -75,6 +76,14 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
define('CRON_DEBUG_FLAG', 1);
} elseif (strtolower($argv[$x]) == '--no-fork') {
define('CRON_NOFORK_FLAG', 1);
} elseif (strtolower($argv[$x]) == '--run-task') {
if (isset($argv[$x+1]) && in_array($argv[$x+1], [1,4,10,99])) {
\Froxlor\System\Cronjob::inserttask($argv[$x+1]);
array_push($jobs_to_run, 'tasks');
} else {
echo "Invalid argument for --run-task\n";
exit;
}
} elseif (substr(strtolower($argv[$x]), 0, 2) == '--') {
// --[cronname]
if (strlen($argv[$x]) > 3) {

View File

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

View File

@@ -11,7 +11,7 @@ class HttpClient
*
* @return array
*/
public static function urlGet($url, $follow_location = true)
public static function urlGet($url, $follow_location = true, $timeout = 10)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
@@ -19,6 +19,7 @@ class HttpClient
if ($follow_location) {
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
}
curl_setopt($ch, CURLOPT_TIMEOUT, (int)$timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
if ($output === false) {

View File

@@ -282,7 +282,7 @@ class Paging
$field .= '`';
}
if ($field{0} != '`') {
if ($field[0] != '`') {
$field = '`' . $field;
}
@@ -352,7 +352,7 @@ class Paging
$field .= '`';
}
if ($field{0} != '`') {
if ($field[0] != '`') {
$field = '`' . $field;
}

View File

@@ -23,8 +23,6 @@ class Validate
*/
public static function validate($str, $fieldname, $pattern = '', $lng = '', $emptydefault = array(), $throw_exception = false)
{
global $log;
if (! is_array($emptydefault)) {
$emptydefault_array = array(
$emptydefault
@@ -48,6 +46,7 @@ class Validate
// everything else is removed from the string.
$allowed = "/[^a-z0-9\\040\\.\\-\\_\\\\]/i";
$str = preg_replace($allowed, "", $str);
$log = \Froxlor\FroxlorLogger::getInstanceOf();
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "cleaned bad formatted string (" . $str . ")");
}
}

View File

@@ -4539,21 +4539,7 @@ UPLOADGID=
<!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor"
mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640">
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon>
<!-- AWstats -->

View File

@@ -4741,21 +4741,7 @@ UPLOADGID=
<!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor"
mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640">
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon>
<!-- AWstats -->

View File

@@ -3657,21 +3657,7 @@ account required pam_mysql.so user=<SQL_UNPRIVILEGED_USER> passwd=<SQL_UN
<!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor"
mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640">
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon>
<!-- AWstats -->

View File

@@ -4461,21 +4461,7 @@ UPLOADGID=
<!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor"
mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640">
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon>
<!-- AWstats -->

View File

@@ -2289,21 +2289,7 @@ ControlsLog /var/log/proftpd/controls.log
<!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor"
mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640">
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/1 * * * * root /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon>
<!-- AWstats -->

View File

@@ -4528,21 +4528,7 @@ UPLOADGID=
<!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor"
mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640">
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon>
<!-- AWstats -->

View File

@@ -1546,21 +1546,7 @@ UPLOADGID=
<!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor"
mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640">
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon>
<!-- AWstats -->

View File

@@ -4539,21 +4539,7 @@ UPLOADGID=
<!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor"
mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640">
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon>
<!-- AWstats -->

View File

@@ -44,6 +44,21 @@ return array(
'label' => $lng['login']['language'],
'type' => 'select',
'select_var' => $language_options
),
'api_allowed' => array(
'label' => $lng['usersettings']['api_allowed']['title'],
'desc' => $lng['usersettings']['api_allowed']['description'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
'1'
),
'visible' => (\Froxlor\Settings::Get('api.enabled') == '1' ? true : false)
)
)
),

View File

@@ -59,6 +59,21 @@ return array(
'type' => 'select',
'select_var' => $language_options,
'visible' => ($result['adminid'] == $userinfo['userid'] ? false : true)
),
'api_allowed' => array(
'label' => $lng['usersettings']['api_allowed']['title'],
'desc' => $lng['usersettings']['api_allowed']['description'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['api_allowed']
),
'visible' => (\Froxlor\Settings::Get('api.enabled') == '1' ? true : false)
)
)
),

View File

@@ -81,6 +81,21 @@ return array(
'label' => $lng['login']['language'],
'type' => 'select',
'select_var' => $language_options
),
'api_allowed' => array(
'label' => $lng['usersettings']['api_allowed']['title'],
'desc' => $lng['usersettings']['api_allowed']['description'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
'1'
),
'visible' => (\Froxlor\Settings::Get('api.enabled') == '1' ? true : false)
)
)
),
@@ -294,9 +309,9 @@ return array(
'values' => $phpconfigs,
'value' => ((int) \Froxlor\Settings::Get('system.mod_fcgid') == 1 ? array(
\Froxlor\Settings::Get('system.mod_fcgid_defaultini')
) : (int) \Froxlor\Settings::Get('phpfpm.enabled') == 1 ? array(
) : ((int) \Froxlor\Settings::Get('phpfpm.enabled') == 1 ? array(
\Froxlor\Settings::Get('phpfpm.defaultini')
) : array()),
) : array())),
'is_array' => 1
),
'perlenabled' => array(

View File

@@ -74,6 +74,21 @@ return array(
'label' => $lng['login']['language'],
'type' => 'select',
'select_var' => $language_options
),
'api_allowed' => array(
'label' => $lng['usersettings']['api_allowed']['title'],
'desc' => $lng['usersettings']['api_allowed']['description'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['api_allowed']
),
'visible' => (\Froxlor\Settings::Get('api.enabled') == '1' ? true : false)
)
)
),

View File

@@ -108,6 +108,19 @@ return array(
),
'value' => array()
),
'http2' => array(
'visible' => ($ssl_ipsandports != '' ? true : false) && \Froxlor\Settings::Get('system.webserver') != 'lighttpd' && \Froxlor\Settings::Get('system.http2_support') == '1',
'label' => $lng['admin']['domain_http2']['title'],
'desc' => $lng['admin']['domain_http2']['description'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array()
),
'hsts_maxage' => array(
'label' => $lng['admin']['domain_hsts_maxage']['title'],
'desc' => $lng['admin']['domain_hsts_maxage']['description'],

View File

@@ -128,6 +128,21 @@ return array(
$result['letsencrypt']
)
),
'http2' => array(
'visible' => ($ssl_ipsandports != '' ? true : false) && \Froxlor\Settings::Get('system.webserver') != 'lighttpd' && \Froxlor\Settings::Get('system.http2_support') == '1',
'label' => $lng['admin']['domain_http2']['title'],
'desc' => $lng['admin']['domain_http2']['description'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['http2']
)
),
'hsts_maxage' => array(
'label' => $lng['admin']['domain_hsts_maxage']['title'],
'desc' => $lng['admin']['domain_hsts_maxage']['description'],

View File

@@ -220,7 +220,7 @@ if (isset($s) && $s != "" && $nosession != 1) {
$userinfo_stmt = Database::prepare($query);
$userinfo = Database::pexecute_first($userinfo_stmt, $userinfo_data);
if ((($userinfo['adminsession'] == '1' && AREA == 'admin' && isset($userinfo['adminid'])) || ($userinfo['adminsession'] == '0' && (AREA == 'customer' || AREA == 'login') && isset($userinfo['customerid']))) && (! isset($userinfo['deactivated']) || $userinfo['deactivated'] != '1')) {
if ($userinfo && (($userinfo['adminsession'] == '1' && AREA == 'admin' && isset($userinfo['adminid'])) || ($userinfo['adminsession'] == '0' && (AREA == 'customer' || AREA == 'login') && isset($userinfo['customerid']))) && (! isset($userinfo['deactivated']) || $userinfo['deactivated'] != '1')) {
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_SESSIONS . "` SET
`lastactivity` = :lastactive

View File

@@ -2066,3 +2066,9 @@ $lng['serversettings']['letsencryptecc']['title'] = "Issue ECC / ECDSA certifica
$lng['serversettings']['letsencryptecc']['description'] = "If set to a valid key-size the certificate issued will use ECC / ECDSA";
$lng['serversettings']['froxloraliases']['title'] = "Domain aliases for froxlor vhost";
$lng['serversettings']['froxloraliases']['description'] = "Comma separated list of domains to add as server alias to the froxlor vhost";
$lng['serversettings']['ssl']['tlsv13_cipher_list']['title'] = 'Configure explicit TLSv1.3 ciphers if used';
$lng['serversettings']['ssl']['tlsv13_cipher_list']['description'] = 'This is a list of ciphers that you want (or don\'t want) to use when talking TLSv1.3. For a list of ciphers and how to include/exclude them, see <a href="https://wiki.openssl.org/index.php/TLS1.3">the docs for TLSv1.3</a>.<br /><br /><b>Default value is empty</b>';
$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.';

View File

@@ -1713,3 +1713,9 @@ $lng['serversettings']['letsencryptecc']['title'] = "ECC / ECDSA Zertifikate aus
$lng['serversettings']['letsencryptecc']['description'] = "Wenn eine Schlüsselgröße ausgewählt wird, werden ECC / ECDSA Zertifikate erstellt";
$lng['serversettings']['froxloraliases']['title'] = "Domain Aliase für Froxlor Vhost";
$lng['serversettings']['froxloraliases']['description'] = "Komma getrennte Liste von Domains, welche als Server Alias zum Froxlor Vhost hinzugefügt werden";
$lng['serversettings']['ssl']['tlsv13_cipher_list']['title'] = 'Explizite TLSv1.3 Ciphers, wenn genutzt';
$lng['serversettings']['ssl']['tlsv13_cipher_list']['description'] = 'Dies ist eine Liste von Ciphers, die genutzt werden sollen (oder auch nicht genutzt werden sollen), wenn eine TLSv1.3 Verbindung hergestellt werden soll. Eine Liste aller Ciphers und wie diese hinzugefügt/ausgeschlossen werden ist <a href="https://wiki.openssl.org/index.php/TLS1.3">der Dokumentation für TLSv1.3</a> zu entnehmen.<br /><br /><b>Standard-Wert ist leer</b>';
$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.';

View File

@@ -16,6 +16,15 @@
</div>
</if>
<if (int)$userinfo['api_allowed'] != 1>
<div class="messagewrapperfull">
<div class="warningcontainer bradius">
<div class="warningtitle">{$lng['admin']['warning']}</div>
<div class="warning">{$lng['usersettings']['api_allowed']['notice']}</div>
</div>
</div>
</if>
<section>
<form action="{$linker->getLink(array('section' => 'index', 'page' => $page))}" method="post" enctype="application/x-www-form-urlencoded">
@@ -26,10 +35,12 @@
{$searchcode}
</div>
<if (int)$userinfo['api_allowed'] == 1>
<div class="overviewadd">
<img src="templates/{$theme}/assets/img/icons/add.png" alt="" />
<a href="{$linker->getLink(array('section' => 'index', 'page' => $page, 'action' => 'add'))}">{$lng['apikeys']['key_add']}</a>
</div>
</if>
<table class="full hl">
<thead>
@@ -58,11 +69,13 @@
</form>
<if 15 < $count >
<if (int)$userinfo['api_allowed'] == 1>
<div class="overviewadd">
<img src="templates/{$theme}/assets/img/icons/add.png" alt="" />
<a href="{$linker->getLink(array('section' => 'index', 'page' => $page, 'action' => 'add'))}">{$lng['apikeys']['key_add']}</a>
</div>
</if>
</if>
</section>
</article>
$footer