diff --git a/lib/Froxlor/Cli/ConfigServices.php b/lib/Froxlor/Cli/ConfigServices.php index ba6389ba..1833e0e2 100644 --- a/lib/Froxlor/Cli/ConfigServices.php +++ b/lib/Froxlor/Cli/ConfigServices.php @@ -402,7 +402,7 @@ final class ConfigServices extends CliCommand case "file": if (array_key_exists('content', $action)) { $output->writeln('Creating file "' . $action['name'] . '"'); - file_put_contents($action['name'], trim(strtr($action['content'], $replace_arr))); + file_put_contents($action['name'], trim(strtr($action['content'], $replace_arr)) . PHP_EOL); } elseif (array_key_exists('subcommands', $action)) { foreach ($action['subcommands'] as $fileaction) { if (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "pre") { @@ -411,7 +411,7 @@ final class ConfigServices extends CliCommand exec(strtr($fileaction['content'], $replace_arr)); } elseif ($fileaction['type'] == 'file') { $output->writeln('Creating file "' . $fileaction['name'] . '"'); - file_put_contents($fileaction['name'], trim(strtr($fileaction['content'], $replace_arr))); + file_put_contents($fileaction['name'], trim(strtr($fileaction['content'], $replace_arr)) . PHP_EOL); } } } diff --git a/lib/Froxlor/Cron/Http/DomainSSL.php b/lib/Froxlor/Cron/Http/DomainSSL.php index 2e263d95..e6f3cc9f 100644 --- a/lib/Froxlor/Cron/Http/DomainSSL.php +++ b/lib/Froxlor/Cron/Http/DomainSSL.php @@ -43,23 +43,29 @@ class DomainSSL * domain-array as reference so we can set the corresponding array-indices * * @return null + * @throws \Exception */ public function setDomainSSLFilesArray(array &$domain = null) { // check if the domain itself has a certificate defined $dom_certs_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domid + SELECT s.*, d.domain + FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s + LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON d.id = s.domainid + WHERE s.`domainid` = :domid "); $dom_certs = Database::pexecute_first($dom_certs_stmt, [ 'domid' => $domain['id'] ]); + $parent_certificate = false; if (!is_array($dom_certs) || !isset($dom_certs['ssl_cert_file']) || $dom_certs['ssl_cert_file'] == '') { // maybe its parent? if (isset($domain['parentdomainid']) && $domain['parentdomainid'] != 0) { $dom_certs = Database::pexecute_first($dom_certs_stmt, [ 'domid' => $domain['parentdomainid'] ]); + $parent_certificate = true; } } @@ -73,8 +79,8 @@ class DomainSSL } // make correct files for the certificates $ssl_files = [ - 'ssl_cert_file' => FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '.crt'), - 'ssl_key_file' => FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '.key') + 'ssl_cert_file' => FileDir::makeCorrectFile($sslcertpath . '/' . ($parent_certificate ? $dom_certs['domain'] : $domain['domain']) . '.crt'), + 'ssl_key_file' => FileDir::makeCorrectFile($sslcertpath . '/' . ($parent_certificate ? $dom_certs['domain'] : $domain['domain']) . '.key') ]; if (!$this->validateCertificate($dom_certs)) { @@ -93,19 +99,19 @@ class DomainSSL $ssl_files['ssl_cert_chainfile'] = ''; // set them if they are != empty if ($dom_certs['ssl_ca_file'] != '') { - $ssl_files['ssl_ca_file'] = FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_CA.pem'); + $ssl_files['ssl_ca_file'] = FileDir::makeCorrectFile($sslcertpath . '/' . ($parent_certificate ? $dom_certs['domain'] : $domain['domain']) . '_CA.pem'); } if ($dom_certs['ssl_cert_chainfile'] != '') { if (Settings::Get('system.webserver') == 'nginx') { // put ca.crt in my.crt, as nginx does not support a separate chain file. $dom_certs['ssl_cert_file'] = trim($dom_certs['ssl_cert_file']) . "\n" . trim($dom_certs['ssl_cert_chainfile']) . "\n"; } else { - $ssl_files['ssl_cert_chainfile'] = FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_chain.pem'); + $ssl_files['ssl_cert_chainfile'] = FileDir::makeCorrectFile($sslcertpath . '/' . ($parent_certificate ? $dom_certs['domain'] : $domain['domain']) . '_chain.pem'); } } // will only be generated to be used externally, froxlor does not need this if ($dom_certs['ssl_fullchain_file'] != '') { - $ssl_files['ssl_fullchain_file'] = FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_fullchain.pem'); + $ssl_files['ssl_fullchain_file'] = FileDir::makeCorrectFile($sslcertpath . '/' . ($parent_certificate ? $dom_certs['domain'] : $domain['domain']) . '_fullchain.pem'); } // create them on the filesystem foreach ($ssl_files as $type => $filename) { @@ -131,7 +137,7 @@ class DomainSSL return; } - private function validateCertificate($dom_certs = []) + private function validateCertificate($dom_certs = []): bool { return openssl_x509_check_private_key($dom_certs['ssl_cert_file'], $dom_certs['ssl_key_file']); } diff --git a/lib/Froxlor/Cron/Traffic/TrafficCron.php b/lib/Froxlor/Cron/Traffic/TrafficCron.php index 421505e3..4c11dcdf 100644 --- a/lib/Froxlor/Cron/Traffic/TrafficCron.php +++ b/lib/Froxlor/Cron/Traffic/TrafficCron.php @@ -193,6 +193,8 @@ class TrafficCron extends FroxlorCron } else { $httptraffic += floatval(self::callWebalizerGetTraffic($row['loginname'] . '-' . $domain, $row['documentroot'] . '/webalizer/' . $domain . '/', $domain, $domainlist[$row['customerid']])); } + // kind of a keep-alive-call as this unsets the link which leads to a new connection to the database + Database::needRoot(); } } } @@ -210,6 +212,8 @@ class TrafficCron extends FroxlorCron } else { $httptraffic += floatval(self::callWebalizerGetTraffic($row['loginname'], $row['documentroot'] . '/webalizer/', $caption, $domainlist[$row['customerid']])); } + // kind of a keep-alive-call as this unsets the link which leads to a new connection to the database + Database::needRoot(); // make the stuff readable for the customer, #258 Statistics::makeChownWithNewStats($row); @@ -618,7 +622,7 @@ class TrafficCron extends FroxlorCron $format = Settings::Get('system.logfiles_type') == '2' ? 'VCOMBINED' : 'COMBINED'; $monthyear = $monthyear_arr['month'] . '/' . $monthyear_arr['year']; $return_value = false; - FileDir::safe_exec("grep '" . $monthyear . "' " . escapeshellarg($logfile) . " | goaccess " . $keep_params . " --db-path=" . escapeshellarg($outputdir) . " -o " . escapeshellarg($outputdir . '.tmp.json') . " -o " . escapeshellarg($outputdir . 'index.html') . " --html-report-title=" . escapeshellarg($caption) . " --log-format=" . $format . " - ", $return_value, ['|']); + FileDir::safe_exec("grep '" . $monthyear . "' " . escapeshellarg($logfile) . " | goaccess " . $keep_params . " --db-path=" . escapeshellarg($outputdir) . " -o " . escapeshellarg($outputdir . '.tmp.json') . " -o " . escapeshellarg($outputdir . 'index.html') . " --html-report-title=" . escapeshellarg($caption) . " --log-format=" . $format . " --no-parsing-spinner --no-progress - ", $return_value, ['|']); if (file_exists($outputdir . '.tmp.json')) { // need jq here because of potentially LARGE json files @@ -787,6 +791,8 @@ class TrafficCron extends FroxlorCron // 'real' domains and no subdomains which are aliases in the // model-config-file. $returnval += self::awstatsDoSingleDomain($singledomain, $outputdir, $current_stamp); + // kind of a keep-alive-call as this unsets the link which leads to a new connection to the database + Database::needRoot(); } /** diff --git a/lib/Froxlor/UI/Callbacks/Domain.php b/lib/Froxlor/UI/Callbacks/Domain.php index 03da7c8c..c4d989aa 100644 --- a/lib/Froxlor/UI/Callbacks/Domain.php +++ b/lib/Froxlor/UI/Callbacks/Domain.php @@ -81,7 +81,7 @@ class Domain return lng('domains.aliasdomain') . ' ' . $attributes['fields']['aliasdomain']; } - public static function domainExternalLinkInfo(array $attributes) + public static function domainExternalLinkInfo(array $attributes): string { $result = ''; if ($attributes['fields']['parentdomainid'] != 0) { @@ -89,7 +89,11 @@ class Domain } $result .= '' . $attributes['data'] . ''; // check for statistics if parentdomainid==0 to show stats-link for customers - if ((int)UI::getCurrentUser()['adminsession'] == 0 && $attributes['fields']['parentdomainid'] == 0 && $attributes['fields']['deactivated'] == 0) { + if ((int)UI::getCurrentUser()['adminsession'] == 0 + && $attributes['fields']['parentdomainid'] == 0 + && $attributes['fields']['deactivated'] == 0 + && preg_match('/^https?:\/\/(.*)/i', $attributes['fields']['documentroot']) == false + ) { $statsapp = Settings::Get('system.traffictool'); $result .= ' '; }