Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5832346f75 | ||
|
|
4b4770ab36 | ||
|
|
8c998dd6f2 | ||
|
|
965359ec79 | ||
|
|
d1d42f2055 | ||
|
|
5f41b37770 | ||
|
|
61265778a5 | ||
|
|
8f0f890145 | ||
|
|
5ccae3f9bb | ||
|
|
f4d9e64804 | ||
|
|
149c0935fa | ||
|
|
cb0b537f6c | ||
|
|
b54c012579 | ||
|
|
389d83f5a3 | ||
|
|
00771381e8 |
@@ -1,6 +1,6 @@
|
||||
[](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml)
|
||||
[](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml)
|
||||
[](https://gitter.im/Froxlor/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[](https://discord.froxlor.org)
|
||||
|
||||
# Froxlor
|
||||
|
||||
@@ -27,6 +27,10 @@ https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-from-tarball
|
||||
|
||||
You may find help in the following places:
|
||||
|
||||
### Discord
|
||||
|
||||
The froxlor community discord server can be found here: https://discord.froxlor.org
|
||||
|
||||
### IRC
|
||||
|
||||
froxlor may be found on libera.chat, channel #froxlor:
|
||||
|
||||
@@ -133,6 +133,15 @@ return array(
|
||||
'cronmodule' => 'froxlor/letsencrypt',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_acmeshpath' => array(
|
||||
'label' => $lng['serversettings']['acmeshpath'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'acmeshpath',
|
||||
'type' => 'string',
|
||||
'string_type' => 'file',
|
||||
'default' => '/root/.acme.sh/acme.sh',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_letsencryptacmeconf' => array(
|
||||
'label' => $lng['serversettings']['letsencryptacmeconf'],
|
||||
'settinggroup' => 'system',
|
||||
|
||||
@@ -682,6 +682,7 @@ opcache.interned_strings_buffer'),
|
||||
('system', 'createstdsubdom_default', '1'),
|
||||
('system', 'froxlorusergroup', ''),
|
||||
('system', 'froxlorusergroup_gid', ''),
|
||||
('system', 'acmeshpath', '/root/.acme.sh/acme.sh'),
|
||||
('api', 'enabled', '0'),
|
||||
('2fa', 'enabled', '1'),
|
||||
('panel', 'decimal_places', '4'),
|
||||
@@ -722,8 +723,8 @@ opcache.interned_strings_buffer'),
|
||||
('panel', 'logo_image_login', ''),
|
||||
('panel', 'logo_overridetheme', '0'),
|
||||
('panel', 'logo_overridecustom', '0'),
|
||||
('panel', 'version', '0.10.30'),
|
||||
('panel', 'db_version', '202109040');
|
||||
('panel', 'version', '0.10.32'),
|
||||
('panel', 'db_version', '202112310');
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `panel_tasks`;
|
||||
|
||||
@@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'no';
|
||||
$lng['requirements']['notfound'] = 'not found';
|
||||
$lng['requirements']['notinstalled'] = 'not installed';
|
||||
$lng['requirements']['activated'] = 'enabled';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.0';
|
||||
$lng['requirements']['newerphpprefered'] = 'Good, but php-7.1 is preferred.';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.1';
|
||||
$lng['requirements']['newerphpprefered'] = 'Good, but php-7.4 is preferred.';
|
||||
$lng['requirements']['phppdo'] = 'PHP PDO extension and PDO-MySQL driver...';
|
||||
$lng['requirements']['phpsession'] = 'PHP session-extension...';
|
||||
$lng['requirements']['phpctype'] = 'PHP ctype-extension...';
|
||||
|
||||
@@ -22,7 +22,7 @@ $lng['requirements']['not_true'] = 'non';
|
||||
$lng['requirements']['notfound'] = 'introuvable';
|
||||
$lng['requirements']['notinstalled'] = 'non installé';
|
||||
$lng['requirements']['activated'] = 'activé';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.0';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.1';
|
||||
$lng['requirements']['phppdo'] = 'extension PHP PDO et pilote PDO-MySQL ...';
|
||||
$lng['requirements']['phpxml'] = 'extension PHP XML...';
|
||||
$lng['requirements']['phpfilter'] = 'extension PHP filter ...';
|
||||
|
||||
@@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'nein';
|
||||
$lng['requirements']['notfound'] = 'nicht gefunden';
|
||||
$lng['requirements']['notinstalled'] = 'nicht installiert';
|
||||
$lng['requirements']['activated'] = 'ist aktiviert.';
|
||||
$lng['requirements']['phpversion'] = 'PHP Version >= 7.0';
|
||||
$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.1 wird bevorzugt.';
|
||||
$lng['requirements']['phpversion'] = 'PHP Version >= 7.1';
|
||||
$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.4 wird bevorzugt.';
|
||||
$lng['requirements']['phppdo'] = 'PHP PDO Erweiterung und PDO-MySQL Treiber...';
|
||||
$lng['requirements']['phpsession'] = 'PHP session-Erweiterung...';
|
||||
$lng['requirements']['phpctype'] = 'PHP ctype-Erweiterung...';
|
||||
|
||||
@@ -948,3 +948,20 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.29.1')) {
|
||||
showUpdateStep("Updating from 0.10.29.1 to 0.10.30", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.30');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.30')) {
|
||||
showUpdateStep("Updating from 0.10.30 to 0.10.31", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.31');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202109040')) {
|
||||
showUpdateStep("Add setting for acme.sh install location", true);
|
||||
Settings::AddNew("system.acmeshpath", '/root/.acme.sh/acme.sh');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202112310');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.31')) {
|
||||
showUpdateStep("Updating from 0.10.31 to 0.10.32", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.32');
|
||||
}
|
||||
|
||||
@@ -915,7 +915,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* @param bool $mysqls_ul
|
||||
* optional, whether customer should have unlimited mysql-databases, default 0 (false)
|
||||
* @param bool $createstdsubdomain
|
||||
* optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default 0 (false)
|
||||
* optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default 1 (if customer has std-subdomain) else 0 (false)
|
||||
* @param bool $phpenabled
|
||||
* optional, whether to allow usage of PHP, default 0 (false)
|
||||
* @param array $allowed_phpconfigs
|
||||
@@ -979,7 +979,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$email_pop3 = $this->getParam('email_pop3', true, $result['pop3']);
|
||||
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, $result['ftps']);
|
||||
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, $result['mysqls']);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, 0);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, ($result['standardsubdomain'] != 0 ? 1 : 0));
|
||||
$password = $this->getParam('new_customer_password', true, '');
|
||||
$phpenabled = $this->getBoolParam('phpenabled', true, $result['phpenabled']);
|
||||
$allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, json_decode($result['allowed_phpconfigs'], true));
|
||||
@@ -1051,7 +1051,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
}
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
if ($createstdsubdomain != '1') {
|
||||
if ($createstdsubdomain != '1' || $deactivated) {
|
||||
$createstdsubdomain = '0';
|
||||
}
|
||||
|
||||
|
||||
@@ -427,6 +427,20 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
$_documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . $path_suffix);
|
||||
|
||||
$documentroot = \Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (! empty($documentroot)) {
|
||||
if (substr($documentroot, 0, 1) != '/' && ! preg_match('/^https?\:\/\//', $documentroot)) {
|
||||
$documentroot = $_documentroot . '/' . $documentroot;
|
||||
} elseif (substr($documentroot, 0, 1) == '/' && $this->getUserDetail('change_serversettings') != '1') {
|
||||
\Froxlor\UI\Response::standard_error('pathmustberelative', '', true);
|
||||
}
|
||||
} else {
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
$registration_date = \Froxlor\Validate\Validate::validate($registration_date, 'registration_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array(
|
||||
'0000-00-00',
|
||||
'0',
|
||||
@@ -454,17 +468,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
|
||||
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $specialsettings), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
\Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (! empty($documentroot)) {
|
||||
if (substr($documentroot, 0, 1) != '/' && ! preg_match('/^https?\:\/\//', $documentroot)) {
|
||||
$documentroot = $_documentroot . '/' . $documentroot;
|
||||
}
|
||||
} else {
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
$ssl_protocols = array();
|
||||
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
|
||||
@@ -507,7 +510,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$notryfiles = '0';
|
||||
$writeaccesslog = '1';
|
||||
$writeerrorlog = '1';
|
||||
$documentroot = $_documentroot;
|
||||
$override_tls = '0';
|
||||
$ssl_protocols = array();
|
||||
}
|
||||
@@ -1187,6 +1189,38 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$serveraliasoption = $p_serveraliasoption;
|
||||
}
|
||||
|
||||
$documentroot = \Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
if (! empty($documentroot) && $documentroot != $result['documentroot'] && substr($documentroot, 0, 1) == '/' && substr($documentroot, 0, strlen($customer['documentroot'])) != $customer['documentroot'] && $this->getUserDetail('change_serversettings') != '1') {
|
||||
\Froxlor\UI\Response::standard_error('pathmustberelative', '', true);
|
||||
}
|
||||
|
||||
// when moving customer and no path is specified, update would normally reuse the current document-root
|
||||
// which would point to the wrong customer, therefore we will re-create that directory
|
||||
if (! empty($documentroot) && $customerid > 0 && $customerid != $result['customerid'] && Settings::Get('panel.allow_domain_change_customer') == '1') {
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$_documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$_documentroot = $customer['documentroot'];
|
||||
}
|
||||
// set the customers default docroot
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
if ($documentroot == '') {
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$documentroot = $customer['documentroot'];
|
||||
}
|
||||
}
|
||||
|
||||
if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
|
||||
\Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true);
|
||||
}
|
||||
|
||||
if ($this->getUserDetail('change_serversettings') == '1') {
|
||||
|
||||
if (Settings::Get('system.bind_enable') == '1') {
|
||||
@@ -1201,33 +1235,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
|
||||
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $specialsettings), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$documentroot = \Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
// when moving customer and no path is specified, update would normally reuse the current document-root
|
||||
// which would point to the wrong customer, therefore we will re-create that directory
|
||||
if (! empty($documentroot) && $customerid > 0 && $customerid != $result['customerid'] && Settings::Get('panel.allow_domain_change_customer') == '1') {
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$_documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$_documentroot = $customer['documentroot'];
|
||||
}
|
||||
// set the customers default docroot
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
if ($documentroot == '') {
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$documentroot = $customer['documentroot'];
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
@@ -1267,7 +1274,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$notryfiles = $result['notryfiles'];
|
||||
$writeaccesslog = $result['writeaccesslog'];
|
||||
$writeerrorlog = $result['writeerrorlog'];
|
||||
$documentroot = $result['documentroot'];
|
||||
$ssl_protocols = $p_ssl_protocols;
|
||||
$override_tls = $result['override_tls'];
|
||||
}
|
||||
@@ -1458,7 +1464,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$wwwserveralias = ($serveraliasoption == '1') ? '1' : '0';
|
||||
$iswildcarddomain = ($serveraliasoption == '0') ? '1' : '0';
|
||||
|
||||
if ($documentroot != $result['documentroot'] || $ssl_redirect != $result['ssl_redirect'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $phpenabled != $result['phpenabled'] || $openbasedir != $result['openbasedir'] || $phpsettingid != $result['phpsettingid'] || $mod_fcgid_starter != $result['mod_fcgid_starter'] || $mod_fcgid_maxrequests != $result['mod_fcgid_maxrequests'] || $specialsettings != $result['specialsettings'] || $notryfiles != $result['notryfiles'] || $writeaccesslog != $result['writeaccesslog'] || $writeerrorlog != $result['writeerrorlog'] || $aliasdomain != $result['aliasdomain'] || $issubof != $result['ismainbutsubto'] || $email_only != $result['email_only'] || ($speciallogfile != $result['speciallogfile'] && $speciallogverified == '1') || $letsencrypt != $result['letsencrypt'] || $http2 != $result['http2'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $ocsp_stapling != $result['ocsp_stapling']) {
|
||||
if ($documentroot != $result['documentroot'] || $ssl_redirect != $result['ssl_redirect'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $phpenabled != $result['phpenabled'] || $openbasedir != $result['openbasedir'] || $phpsettingid != $result['phpsettingid'] || $mod_fcgid_starter != $result['mod_fcgid_starter'] || $mod_fcgid_maxrequests != $result['mod_fcgid_maxrequests'] || $specialsettings != $result['specialsettings'] || $ssl_specialsettings != $result['ssl_specialsettings'] || $notryfiles != $result['notryfiles'] || $writeaccesslog != $result['writeaccesslog'] || $writeerrorlog != $result['writeerrorlog'] || $aliasdomain != $result['aliasdomain'] || $issubof != $result['ismainbutsubto'] || $email_only != $result['email_only'] || ($speciallogfile != $result['speciallogfile'] && $speciallogverified == '1') || $letsencrypt != $result['letsencrypt'] || $http2 != $result['http2'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $ocsp_stapling != $result['ocsp_stapling']) {
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
}
|
||||
|
||||
|
||||
@@ -268,8 +268,11 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
} else {
|
||||
$allowed_phpconfigs = [];
|
||||
}
|
||||
if (! in_array($phpsid_result['phpsettingid'], $allowed_phpconfigs)) {
|
||||
\Froxlor\UI\Response::standard_error('notallowedphpconfigused', '', true);
|
||||
// only with fcgid/fpm enabled will it be possible to select a php-setting
|
||||
if ((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if (! in_array($phpsid_result['phpsettingid'], $allowed_phpconfigs)) {
|
||||
\Froxlor\UI\Response::standard_error('notallowedphpconfigused', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// actually insert domain
|
||||
@@ -654,8 +657,11 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
} else {
|
||||
$allowed_phpconfigs = [];
|
||||
}
|
||||
if (! in_array($phpsettingid, $allowed_phpconfigs)) {
|
||||
\Froxlor\UI\Response::standard_error('notallowedphpconfigused', '', true);
|
||||
// only with fcgid/fpm enabled will it be possible to select a php-setting
|
||||
if ((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if (! in_array($phpsettingid, $allowed_phpconfigs)) {
|
||||
\Froxlor\UI\Response::standard_error('notallowedphpconfigused', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// handle redirect
|
||||
|
||||
@@ -310,7 +310,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
{
|
||||
if (! empty($domains)) {
|
||||
|
||||
$acmesh_cmd = self::$acmesh . " --server " . self::$apiserver . " --issue -d " . implode(" -d ", $domains);
|
||||
$acmesh_cmd = self::getAcmeSh() . " --server " . self::$apiserver . " --issue -d " . implode(" -d ", $domains);
|
||||
// challenge path
|
||||
$acmesh_cmd .= " -w " . Settings::Get('system.letsencryptchallengepath');
|
||||
if (Settings::Get('system.leecc') > 0) {
|
||||
@@ -530,7 +530,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
if (Settings::Get('system.leecc') > 0 && ! $forced_noecc) {
|
||||
$domain .= "_ecc";
|
||||
}
|
||||
$env_file = FileDir::makeCorrectFile(dirname(self::$acmesh) . '/acme.sh.env');
|
||||
$env_file = FileDir::makeCorrectFile(dirname(self::getAcmeSh()) . '/acme.sh.env');
|
||||
if (file_exists($env_file)) {
|
||||
$output = [];
|
||||
$cut = <<<EOC
|
||||
@@ -541,11 +541,15 @@ EOC;
|
||||
return FileDir::makeCorrectDir($output[0] . "/" . $domain);
|
||||
}
|
||||
}
|
||||
return FileDir::makeCorrectDir(dirname(self::$acmesh) . "/" . $domain);
|
||||
return FileDir::makeCorrectDir(dirname(self::getAcmeSh()) . "/" . $domain);
|
||||
}
|
||||
|
||||
public static function getAcmeSh()
|
||||
{
|
||||
$from_settings = Settings::Get('system.acmeshpath');
|
||||
if (file_exists($from_settings)) {
|
||||
return $from_settings;
|
||||
}
|
||||
return self::$acmesh;
|
||||
}
|
||||
|
||||
@@ -599,16 +603,24 @@ EOC;
|
||||
*/
|
||||
private static function checkInstall($tries = 0)
|
||||
{
|
||||
if (! file_exists(self::$acmesh) && $tries > 0) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::$acmesh . "'");
|
||||
echo PHP_EOL . "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::$acmesh . "'" . PHP_EOL;
|
||||
if (! file_exists(self::getAcmeSh()) && $tries > 0) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::getAcmeSh() . "'");
|
||||
echo PHP_EOL . "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::getAcmeSh() . "'" . PHP_EOL;
|
||||
return false;
|
||||
} else if (! file_exists(self::$acmesh)) {
|
||||
} else if (! file_exists(self::getAcmeSh())) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Could not find acme.sh - installing it to /root/.acme.sh/");
|
||||
$return = false;
|
||||
\Froxlor\FileDir::safe_exec("wget -O - https://get.acme.sh | sh", $return, array(
|
||||
\Froxlor\FileDir::safe_exec("wget -O - https://get.acme.sh | sh -s email=" . Settings::Get('panel.adminmail'), $return, array(
|
||||
'|'
|
||||
));
|
||||
$set_path = self::getAcmeSh();
|
||||
// after this, regardless of what the user specified, the acme.sh installation will be in /root/.acme.sh
|
||||
if ($set_path != '/root/.acme.sh/acme.sh') {
|
||||
Settings::Set('system.acmeshpath', '/root/.acme.sh/acme.sh', true);
|
||||
// let the user know
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Acme.sh could not be found in '" . $set_path . "' so froxlor installed it to the default location, which is '/root/.acme.sh/'");
|
||||
echo PHP_EOL . "Acme.sh could not be found in '" . $set_path . "' so froxlor installed it to the default location, which is '/root/.acme.sh/'" . PHP_EOL;
|
||||
}
|
||||
// check whether the installation worked
|
||||
return self::checkInstall(++ $tries);
|
||||
}
|
||||
@@ -620,9 +632,9 @@ EOC;
|
||||
*/
|
||||
private static function checkUpgrade()
|
||||
{
|
||||
$acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade --auto-upgrade 0");
|
||||
$acmesh_result = \Froxlor\FileDir::safe_exec(self::getAcmeSh() . " --upgrade --auto-upgrade 0");
|
||||
// check for activated cron
|
||||
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::$acmesh . " --install-cronjob");
|
||||
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::getAcmeSh() . " --install-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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ class Dns
|
||||
if (! $isMainButSubTo) {
|
||||
self::addRequiredEntry('@', 'NS', $required_entries);
|
||||
}
|
||||
if ($domain['isemaildomain'] === '1') {
|
||||
if ($domain['isemaildomain'] == '1') {
|
||||
self::addRequiredEntry('@', 'MX', $required_entries);
|
||||
if (Settings::Get('system.dns_createmailentry')) {
|
||||
foreach (array(
|
||||
|
||||
@@ -16,7 +16,7 @@ class FileDir
|
||||
* @param array $allowedChars
|
||||
* optional array of allowed characters in path/command
|
||||
*
|
||||
* @return string result of exec()
|
||||
* @return array result of exec()
|
||||
*/
|
||||
public static function safe_exec($exec_string, &$return_value = false, $allowedChars = null)
|
||||
{
|
||||
|
||||
@@ -7,10 +7,10 @@ final class Froxlor
|
||||
{
|
||||
|
||||
// Main version variable
|
||||
const VERSION = '0.10.30';
|
||||
const VERSION = '0.10.32';
|
||||
|
||||
// Database version (YYYYMMDDC where C is a daily counter)
|
||||
const DBVERSION = '202109040';
|
||||
const DBVERSION = '202112310';
|
||||
|
||||
// Distribution branding-tag (used for Debian etc.)
|
||||
const BRANDING = '';
|
||||
|
||||
@@ -1722,7 +1722,7 @@ $lng['serversettings']['panel_password_special_char_required']['description'] =
|
||||
$lng['serversettings']['panel_password_special_char']['title'] = 'Special characters list';
|
||||
$lng['serversettings']['panel_password_special_char']['description'] = 'One of these characters is required if the above option is set.';
|
||||
$lng['phpfpm']['use_mod_proxy']['title'] = 'Use mod_proxy / mod_proxy_fcgi';
|
||||
$lng['phpfpm']['use_mod_proxy']['description'] = '<strong class="red">Must be enabled when using Debian 9.x (Stretch)</strong>. Activate to use php-fpm via mod_proxy_fcgi. Requires at least apache-2.4.9';
|
||||
$lng['phpfpm']['use_mod_proxy']['description'] = '<strong class="red">Must be enabled when using Debian 9.x (Stretch) or newer</strong>. Activate to use php-fpm via mod_proxy_fcgi. Requires at least apache-2.4.9';
|
||||
$lng['error']['no_phpinfo'] = 'Sorry, unable to read phpinfo()';
|
||||
|
||||
$lng['admin']['movetoadmin'] = 'Move customer';
|
||||
@@ -2135,3 +2135,6 @@ $lng['error']['notallowedphpconfigused'] = 'Trying to use php-config which is no
|
||||
|
||||
$lng['serversettings']['phpfpm_settings']['allow_all_customers']['title'] = 'Assign this configuration to all currently existing customers';
|
||||
$lng['serversettings']['phpfpm_settings']['allow_all_customers']['description'] = 'Set this to "true" if you want to assign this configuration to all currently existing customers so it can be used by them. This setting is not permanent but can be run multiple times.';
|
||||
$lng['error']['pathmustberelative'] = 'The user does not have the permission to specify directories outside the customers home-directory. Please specify a relative path (no leading /).';
|
||||
$lng['serversettings']['acmeshpath']['title'] = 'Path to acme.sh';
|
||||
$lng['serversettings']['acmeshpath']['description'] = 'Set this to where acme.sh is installed to, including the acme.sh script<br>Default is <b>/root/.acme.sh/acme.sh</b>';
|
||||
|
||||
@@ -1445,7 +1445,7 @@ $lng['serversettings']['panel_password_special_char_required']['description'] =
|
||||
$lng['serversettings']['panel_password_special_char']['title'] = 'Sonderzeichen-Liste';
|
||||
$lng['serversettings']['panel_password_special_char']['description'] = 'Mindestens eines dieser Sonderzeichen muss in dem Passwort vorkommen, sofern die Sonderzeichen-Option aktiviert ist.';
|
||||
$lng['phpfpm']['use_mod_proxy']['title'] = 'Verwende mod_proxy / mod_proxy_fcgi';
|
||||
$lng['phpfpm']['use_mod_proxy']['description'] = '<strong class="red">Muss gesetzt sein bei Debian 9.x (Stretch)</strong>. Diese Option kann aktiviert werden, um php-fpm via mod_proxy_fcgi einzubinden. Dies setzt mindestens apache-2.4.9 voraus';
|
||||
$lng['phpfpm']['use_mod_proxy']['description'] = '<strong class="red">Muss gesetzt sein bei Debian 9.x (Stretch) oder neuer</strong>. Diese Option kann aktiviert werden, um php-fpm via mod_proxy_fcgi einzubinden. Dies setzt mindestens apache-2.4.9 voraus';
|
||||
$lng['error']['no_phpinfo'] = 'Entschuldigung, es ist nicht möglich die phpinfo() auszulesen.';
|
||||
|
||||
$lng['admin']['movetoadmin'] = 'Kunde verschieben';
|
||||
@@ -1781,3 +1781,6 @@ $lng['error']['notallowedphpconfigused'] = 'Nutzung einer PHP-Konfiguration welc
|
||||
|
||||
$lng['serversettings']['phpfpm_settings']['allow_all_customers']['title'] = 'Für aktuelle Kunden automatisch hinzufügen';
|
||||
$lng['serversettings']['phpfpm_settings']['allow_all_customers']['description'] = 'Ist diese Einstellung aktiv, wird die Konfiguration automatisch allen aktuell existierenden Kunden-Accounts zugewiesen. Diese Einstellung ist nicht permanent, kann aber mehrfach / nach Bedarf ausgeführt werden.';
|
||||
$lng['error']['pathmustberelative'] = 'Der Benutzer hat nicht die benötigten Berechtigungen, um Pfade außerhalb des Kunden-Heimatverzeichnisses anzugeben. Bitte einen relativen Pfad angeben (kein führendes /).';
|
||||
$lng['serversettings']['acmeshpath']['title'] = 'Pfad zu acme.sh';
|
||||
$lng['serversettings']['acmeshpath']['description'] = 'Installationspfad zu acme.sh, inklusive acme.sh Script<br>Standard ist <b>/root/.acme.sh/acme.sh</b>';
|
||||
|
||||
@@ -21,6 +21,7 @@ class DomainZonesTest extends TestCase
|
||||
global $admin_userdata;
|
||||
|
||||
Settings::Set('system.dnsenabled', 1, true);
|
||||
Settings::Set('system.mxservers', 'mx.hostname.tld', true);
|
||||
|
||||
// get customer
|
||||
$json_result = Customers::getLocal($admin_userdata, array(
|
||||
@@ -35,6 +36,9 @@ class DomainZonesTest extends TestCase
|
||||
$result = json_decode($json_result, true)['data'];
|
||||
$this->assertTrue(count($result) > 1);
|
||||
$this->assertEquals('$ORIGIN test2.local.', $result[1]);
|
||||
$resstr = preg_replace('/\s+/', '', $result[count($result)-2]);
|
||||
$against = preg_replace('/\s+/', '', '@ 604800 IN MX 10 mx.hostname.tld.');
|
||||
$this->assertEquals($against, $resstr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -138,6 +138,25 @@ class DomainsTest extends TestCase
|
||||
$this->assertEquals(2, $result['subcanemaildomain']);
|
||||
}
|
||||
|
||||
public function testResellerDomainsAddWithAbsolutePathNoChangeServerSettings()
|
||||
{
|
||||
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;
|
||||
$data = [
|
||||
'domain' => 'test3.local',
|
||||
'customerid' => 1,
|
||||
'documentroot' => '/some/absolute/directory/the_reseller/cannot/set/',
|
||||
'ipandport' => 4
|
||||
];
|
||||
$this->expectExceptionMessage("The user does not have the permission to specify directories outside the customers home-directory. Please specify a relative path (no leading /).");
|
||||
$json_result = Domains::getLocal($reseller_userdata, $data)->add();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @depends testAdminDomainsAdd
|
||||
@@ -153,12 +172,35 @@ class DomainsTest extends TestCase
|
||||
$reseller_userdata['adminsession'] = 1;
|
||||
$data = [
|
||||
'domainname' => 'test2.local',
|
||||
'ssl_protocols' => 'TLSv1'
|
||||
'ssl_protocols' => 'TLSv1',
|
||||
'documentroot' => '/var/customers/webs/test1/sub/'
|
||||
];
|
||||
$json_result = Domains::getLocal($reseller_userdata, $data)->update();
|
||||
$result = json_decode($json_result, true)['data'];
|
||||
$this->assertEmpty($result['ssl_protocols']);
|
||||
$this->assertEquals('test2.local', $result['domain']);
|
||||
$this->assertEquals('/var/customers/webs/test1/sub/', $result['documentroot']);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @depends testResellerDomainsUpdate
|
||||
*/
|
||||
public function testResellerDomainsUpdateAboslutePathNotAllowed()
|
||||
{
|
||||
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;
|
||||
$data = [
|
||||
'domainname' => 'test2.local',
|
||||
'documentroot' => '/some/other/dir'
|
||||
];
|
||||
$this->expectExceptionMessage("The user does not have the permission to specify directories outside the customers home-directory. Please specify a relative path (no leading /).");
|
||||
$json_result = Domains::getLocal($reseller_userdata, $data)->update();
|
||||
}
|
||||
|
||||
public function testAdminDomainsAddSysHostname()
|
||||
@@ -402,6 +444,7 @@ class DomainsTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @refs https://github.com/Froxlor/Froxlor/issues/899
|
||||
*/
|
||||
public function testAdminIdn2DomainsAdd()
|
||||
|
||||
Reference in New Issue
Block a user