use TwoFactorAuth via composer
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
254
lib/Froxlor/Bulk/BulkAction.php
Normal file
254
lib/Froxlor/Bulk/BulkAction.php
Normal file
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
namespace Froxlor\Bulk;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract Class BulkAction to mass-import entities
|
||||
*
|
||||
* @author Michael Kaufmann (d00p) <d00p@froxlor.org>
|
||||
*
|
||||
*/
|
||||
abstract class BulkAction
|
||||
{
|
||||
|
||||
/**
|
||||
* complete path including filename of file to be imported
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_impFile = null;
|
||||
|
||||
/**
|
||||
* customer id of the user the entity is being added to
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_custId = null;
|
||||
|
||||
/**
|
||||
* array of customer data read from the database
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_custData = null;
|
||||
|
||||
/**
|
||||
* api-function to call for addingg entity
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $api_call = null;
|
||||
|
||||
/**
|
||||
* api-function parameter names, read from import-file (first line)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $api_params = null;
|
||||
|
||||
/**
|
||||
* errors while importing
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $errors = array();
|
||||
|
||||
/**
|
||||
* class constructor, optionally sets file and customer-id
|
||||
*
|
||||
* @param string $import_file
|
||||
* @param int $customer_id
|
||||
*
|
||||
* @return object BulkAction instance
|
||||
*/
|
||||
protected function __construct($import_file = null, $customer_id = 0)
|
||||
{
|
||||
if (! empty($import_file)) {
|
||||
$this->_impFile = \Froxlor\FileDir::makeCorrectFile($import_file);
|
||||
}
|
||||
$this->_custId = $customer_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* import the parsed import file data with an optional separator other then semicolon
|
||||
* and offset (maybe for header-line in csv or similar)
|
||||
*
|
||||
* @param string $separator
|
||||
* @param int $offset
|
||||
*
|
||||
* @return array 'all' => amount of records processed, 'imported' => number of imported records
|
||||
*/
|
||||
abstract public function doImport($separator = ";", $offset = 0);
|
||||
|
||||
/**
|
||||
* setter for import-file
|
||||
*
|
||||
* @param string $import_file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImportFile($import_file = null)
|
||||
{
|
||||
$this->_impFile = \Froxlor\FileDir::makeCorrectFile($import_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for customer-id
|
||||
*
|
||||
* @param int $customer_id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCustomer($customer_id = 0)
|
||||
{
|
||||
$this->_custId = $customer_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the list of errors
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for api_call
|
||||
*
|
||||
* @param string $api_call
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setApiCall($api_call = "")
|
||||
{
|
||||
$this->api_call = $api_call;
|
||||
}
|
||||
|
||||
protected function importEntity($data_array = null)
|
||||
{
|
||||
global $userinfo;
|
||||
|
||||
$module = '\\Froxlor\\Api\\Commands\\' . substr($this->api_call, 0, strpos($this->api_call, "."));
|
||||
$function = substr($this->api_call, strpos($this->api_call, ".") + 1);
|
||||
|
||||
$new_data = array();
|
||||
foreach ($this->api_params as $idx => $param) {
|
||||
if (isset($data_array[$idx]) && ! empty($data_array[$idx])) {
|
||||
$new_data[$param] = $data_array[$idx];
|
||||
}
|
||||
}
|
||||
|
||||
$result = null;
|
||||
try {
|
||||
$json_result = $module::getLocal($userinfo, $new_data)->$function();
|
||||
$result = json_decode($json_result, true)['data'];
|
||||
} catch (\Exception $e) {
|
||||
$this->errors[] = $e->getMessage();
|
||||
}
|
||||
return ! empty($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* reads in the csv import file and returns an array with
|
||||
* all the entites to be imported
|
||||
*
|
||||
* @param string $separator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _parseImportFile($separator = ";")
|
||||
{
|
||||
if (empty($this->_impFile)) {
|
||||
throw new \Exception("No file was given for import");
|
||||
}
|
||||
|
||||
if (! file_exists($this->_impFile)) {
|
||||
throw new \Exception("The file '" . $this->_impFile . "' could not be found");
|
||||
}
|
||||
|
||||
if (! is_readable($this->_impFile)) {
|
||||
throw new \Exception("Unable to read file '" . $this->_impFile . "'");
|
||||
}
|
||||
|
||||
$file_data = array();
|
||||
$is_params_line = true;
|
||||
$fh = @fopen($this->_impFile, "r");
|
||||
if ($fh) {
|
||||
while (($line = fgets($fh)) !== false) {
|
||||
$tmp_arr = explode($separator, $line);
|
||||
$data_arr = array();
|
||||
foreach ($tmp_arr as $idx => $data) {
|
||||
if ($is_params_line) {
|
||||
$this->api_params[$idx] = $data;
|
||||
} else {
|
||||
$data_arr[$idx] = $data;
|
||||
}
|
||||
}
|
||||
if ($is_params_line) {
|
||||
$is_params_line = false;
|
||||
continue;
|
||||
}
|
||||
$file_data[] = array_map("trim", $data_arr);
|
||||
}
|
||||
$this->api_params = array_map("trim", $this->api_params);
|
||||
} else {
|
||||
throw new \Exception("Unable to open file '" . $this->_impFile . "'");
|
||||
}
|
||||
fclose($fh);
|
||||
|
||||
return $file_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* to be called first in doImport() to read in customer and entity data
|
||||
*/
|
||||
protected function preImport()
|
||||
{
|
||||
$this->_readCustomerData();
|
||||
|
||||
if ($this->_custId <= 0) {
|
||||
throw new \Exception("Invalid customer selected");
|
||||
}
|
||||
|
||||
if (is_null($this->_custData)) {
|
||||
throw new \Exception("Failed to read customer data");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reads customer data from panel_customer by $_custId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _readCustomerData()
|
||||
{
|
||||
$cust_stmt = \Froxlor\Database\Database::prepare("SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `customerid` = :cid");
|
||||
$this->_custData = \Froxlor\Database\Database::pexecute_first($cust_stmt, array(
|
||||
'cid' => $this->_custId
|
||||
));
|
||||
if (is_array($this->_custData) && isset($this->_custData['customerid']) && $this->_custData['customerid'] == $this->_custId) {
|
||||
return true;
|
||||
}
|
||||
$this->_custData = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
110
lib/Froxlor/Bulk/DomainBulkAction.php
Normal file
110
lib/Froxlor/Bulk/DomainBulkAction.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
namespace Froxlor\Bulk;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.33
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class DomainBulkAction to mass-import domains for a given customer
|
||||
*
|
||||
* @author Michael Kaufmann (d00p) <d00p@froxlor.org>
|
||||
*
|
||||
*/
|
||||
class DomainBulkAction extends BulkAction
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @return object DomainBulkAction instance
|
||||
*/
|
||||
public function __construct($import_file = null, $customer_id = 0)
|
||||
{
|
||||
parent::__construct($import_file, $customer_id);
|
||||
$this->setApiCall('Domains.add');
|
||||
}
|
||||
|
||||
/**
|
||||
* import the parsed import file data with an optional separator other then semicolon
|
||||
* and offset (maybe for header-line in csv or similar)
|
||||
*
|
||||
* @param string $separator
|
||||
* @param int $offset
|
||||
*
|
||||
* @return array 'all' => amount of records processed, 'imported' => number of imported records
|
||||
*/
|
||||
public function doImport($separator = ";", $offset = 0)
|
||||
{
|
||||
$this->preImport();
|
||||
|
||||
// get the admins userinfo to check for domains_used, etc.
|
||||
global $userinfo;
|
||||
|
||||
if ($userinfo['domains'] == "-1") {
|
||||
$dom_unlimited = true;
|
||||
} else {
|
||||
$dom_unlimited = false;
|
||||
}
|
||||
|
||||
$domains_used = (int) $userinfo['domains_used'];
|
||||
$domains_avail = (int) $userinfo['domains'];
|
||||
|
||||
if (empty($separator) || strlen($separator) != 1) {
|
||||
throw new \Exception("Invalid separator specified: '" . $separator . "'");
|
||||
}
|
||||
|
||||
if (! is_int($offset) || $offset < 0) {
|
||||
throw new \Exception("Invalid offset specified");
|
||||
}
|
||||
|
||||
try {
|
||||
$domain_array = $this->_parseImportFile($separator);
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if (count($domain_array) <= 0) {
|
||||
throw new \Exception("No domains were read from the file.");
|
||||
}
|
||||
|
||||
$global_counter = 0;
|
||||
$import_counter = 0;
|
||||
$note = '';
|
||||
foreach ($domain_array as $idx => $dom) {
|
||||
if ($idx >= $offset) {
|
||||
if ($dom_unlimited || (! $dom_unlimited && $domains_used < $domains_avail)) {
|
||||
|
||||
$result = $this->importEntity($dom);
|
||||
if ($result) {
|
||||
$import_counter ++;
|
||||
$domains_used ++;
|
||||
}
|
||||
} else {
|
||||
$note .= 'You have reached your maximum allocation of domains (' . $domains_avail . ').';
|
||||
break;
|
||||
}
|
||||
}
|
||||
$global_counter ++;
|
||||
}
|
||||
|
||||
return array(
|
||||
'all' => $global_counter,
|
||||
'imported' => $import_counter,
|
||||
'notice' => $note
|
||||
);
|
||||
}
|
||||
}
|
||||
512
lib/Froxlor/Database/IntegrityCheck.php
Normal file
512
lib/Froxlor/Database/IntegrityCheck.php
Normal file
@@ -0,0 +1,512 @@
|
||||
<?php
|
||||
namespace Froxlor\Database;
|
||||
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* Copyright (c) 2014- the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2014-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Integrity
|
||||
*
|
||||
* IntegrityCheck - class
|
||||
*/
|
||||
class IntegrityCheck
|
||||
{
|
||||
|
||||
// Store all available checks
|
||||
public $available = array();
|
||||
|
||||
// logger object
|
||||
private $_log = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Parses all available checks into $this->available
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
global $userinfo;
|
||||
if (! isset($userinfo) || ! is_array($userinfo)) {
|
||||
$userinfo = array(
|
||||
'loginname' => 'integrity-check'
|
||||
);
|
||||
}
|
||||
$this->_log = \Froxlor\FroxlorLogger::getInstanceOf($userinfo);
|
||||
$this->available = get_class_methods($this);
|
||||
unset($this->available[array_search('__construct', $this->available)]);
|
||||
unset($this->available[array_search('checkAll', $this->available)]);
|
||||
unset($this->available[array_search('fixAll', $this->available)]);
|
||||
sort($this->available);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all occurring integrity problems at once
|
||||
*/
|
||||
public function checkAll()
|
||||
{
|
||||
$integrityok = true;
|
||||
foreach ($this->available as $check) {
|
||||
$integrityok = $this->$check() ? $integrityok : false;
|
||||
}
|
||||
return $integrityok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix all occurring integrity problems at once with default settings
|
||||
*/
|
||||
public function fixAll()
|
||||
{
|
||||
$integrityok = true;
|
||||
foreach ($this->available as $check) {
|
||||
$integrityok = $this->$check(true) ? $integrityok : false;
|
||||
}
|
||||
return $integrityok;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the froxlor database and its tables are in utf-8 character-set
|
||||
*
|
||||
* @param bool $fix
|
||||
* fix db charset/collation if not utf8
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function DatabaseCharset($fix = false)
|
||||
{
|
||||
|
||||
// get characterset
|
||||
$cs_stmt = Database::prepare('SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = :dbname');
|
||||
$resp = Database::pexecute_first($cs_stmt, array(
|
||||
'dbname' => Database::getDbName()
|
||||
));
|
||||
$charset = isset($resp['default_character_set_name']) ? $resp['default_character_set_name'] : null;
|
||||
if (! empty($charset) && strtolower($charset) != 'utf8') {
|
||||
$this->_log->logAction(ADM_ACTION, LOG_NOTICE, "database charset seems to be different from UTF-8, integrity-check can fix that");
|
||||
if ($fix) {
|
||||
// fix database
|
||||
Database::query('ALTER DATABASE `' . Database::getDbName() . '` CHARACTER SET utf8 COLLATE utf8_general_ci');
|
||||
// fix all tables
|
||||
$handle = Database::query('SHOW FULL TABLES WHERE Table_type != "VIEW"');
|
||||
while ($row = $handle->fetch(\PDO::FETCH_BOTH)) {
|
||||
$table = $row[0];
|
||||
Database::query('ALTER TABLE `' . $table . '` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;');
|
||||
}
|
||||
$this->_log->logAction(ADM_ACTION, LOG_WARNING, "database charset was different from UTF-8, integrity-check fixed that");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fix) {
|
||||
return $this->DatabaseCharset();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the integrity of the domain to ip/port - association
|
||||
*
|
||||
* @param bool $fix
|
||||
* Fix everything found directly
|
||||
*/
|
||||
public function DomainIpTable($fix = false)
|
||||
{
|
||||
$ips = array();
|
||||
$domains = array();
|
||||
$ipstodomains = array();
|
||||
$admips = array();
|
||||
|
||||
if ($fix) {
|
||||
// Prepare insert / delete statement for the fixes
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_DOMAINTOIP . "`
|
||||
WHERE `id_domain` = :domainid AND `id_ipandports` = :ipandportid ");
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_DOMAINTOIP . "`
|
||||
SET `id_domain` = :domainid, `id_ipandports` = :ipandportid ");
|
||||
|
||||
// Cache all IPs the admins have assigned
|
||||
$adm_stmt = Database::prepare("SELECT `adminid`, `ip` FROM `" . TABLE_PANEL_ADMINS . "` ORDER BY `adminid` ASC");
|
||||
Database::pexecute($adm_stmt);
|
||||
$default_ips = explode(',', Settings::Get('system.defaultip'));
|
||||
$default_ssl_ips = explode(',', Settings::Get('system.defaultsslip'));
|
||||
while ($row = $adm_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if ($row['ip'] < 0 || is_null($row['ip']) || empty($row['ip'])) {
|
||||
// Admin uses default-IP
|
||||
$admips[$row['adminid']] = array_merge($default_ips, $default_ssl_ips);
|
||||
} else {
|
||||
$admips[$row['adminid']] = array(
|
||||
$row['ip']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cache all available ip/port - combinations
|
||||
$result_stmt = Database::prepare("SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` ORDER BY `id` ASC");
|
||||
Database::pexecute($result_stmt);
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$ips[$row['id']] = $row['ip'] . ':' . $row['port'];
|
||||
}
|
||||
|
||||
// Cache all configured domains
|
||||
$result_stmt = Database::prepare("SELECT `id`, `adminid` FROM `" . TABLE_PANEL_DOMAINS . "` ORDER BY `id` ASC");
|
||||
Database::pexecute($result_stmt);
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$domains[$row['id']] = $row['adminid'];
|
||||
}
|
||||
|
||||
// Check if every domain to ip/port - association is valid in TABLE_DOMAINTOIP
|
||||
$result_stmt = Database::prepare("SELECT `id_domain`, `id_ipandports` FROM `" . TABLE_DOMAINTOIP . "`");
|
||||
Database::pexecute($result_stmt);
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if (! array_key_exists($row['id_ipandports'], $ips)) {
|
||||
if ($fix) {
|
||||
Database::pexecute($del_stmt, array(
|
||||
'domainid' => $row['id_domain'],
|
||||
'ipandportid' => $row['id_ipandports']
|
||||
));
|
||||
$this->_log->logAction(ADM_ACTION, LOG_WARNING, "found an ip/port-id in domain <> ip table which does not exist, integrity check fixed this");
|
||||
} else {
|
||||
$this->_log->logAction(ADM_ACTION, LOG_NOTICE, "found an ip/port-id in domain <> ip table which does not exist, integrity check can fix this");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (! array_key_exists($row['id_domain'], $domains)) {
|
||||
if ($fix) {
|
||||
Database::pexecute($del_stmt, array(
|
||||
'domainid' => $row['id_domain'],
|
||||
'ipandportid' => $row['id_ipandports']
|
||||
));
|
||||
$this->_log->logAction(ADM_ACTION, LOG_WARNING, "found a domain-id in domain <> ip table which does not exist, integrity check fixed this");
|
||||
} else {
|
||||
$this->_log->logAction(ADM_ACTION, LOG_NOTICE, "found a domain-id in domain <> ip table which does not exist, integrity check can fix this");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Save one IP/Port combination per domain, so we know, if one domain is missing an IP
|
||||
$ipstodomains[$row['id_domain']] = $row['id_ipandports'];
|
||||
}
|
||||
|
||||
// Check that all domains have at least one IP/Port combination
|
||||
foreach ($domains as $domainid => $adminid) {
|
||||
if (! array_key_exists($domainid, $ipstodomains)) {
|
||||
if ($fix) {
|
||||
foreach ($admips[$adminid] as $defaultip) {
|
||||
Database::pexecute($ins_stmt, array(
|
||||
'domainid' => $domainid,
|
||||
'ipandportid' => $defaultip
|
||||
));
|
||||
}
|
||||
$this->_log->logAction(ADM_ACTION, LOG_WARNING, "found a domain-id with no entry in domain <> ip table, integrity check fixed this");
|
||||
} else {
|
||||
$this->_log->logAction(ADM_ACTION, LOG_NOTICE, "found a domain-id with no entry in domain <> ip table, integrity check can fix this");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($fix) {
|
||||
return $this->DomainIpTable();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all subdomains have ssl-redirect = 0 if domain has no ssl-port
|
||||
*
|
||||
* @param bool $fix
|
||||
* Fix everything found directly
|
||||
*/
|
||||
public function SubdomainSslRedirect($fix = false)
|
||||
{
|
||||
$ips = array();
|
||||
$parentdomains = array();
|
||||
$subdomains = array();
|
||||
|
||||
if ($fix) {
|
||||
// Prepare update statement for the fixes
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DOMAINS . "`
|
||||
SET `ssl_redirect` = 0 WHERE `parentdomainid` = :domainid");
|
||||
}
|
||||
|
||||
// Cache all ssl ip/port - combinations
|
||||
$result_stmt = Database::prepare("SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `ssl` = 1 ORDER BY `id` ASC");
|
||||
Database::pexecute($result_stmt);
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$ips[$row['id']] = $row['ip'] . ':' . $row['port'];
|
||||
}
|
||||
|
||||
// Cache all configured domains
|
||||
$result_stmt = Database::prepare("SELECT `id`, `parentdomainid`, `ssl_redirect` FROM `" . TABLE_PANEL_DOMAINS . "` ORDER BY `id` ASC");
|
||||
$ip_stmt = Database::prepare("SELECT `id_domain`, `id_ipandports` FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :domainid");
|
||||
Database::pexecute($result_stmt);
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if ($row['parentdomainid'] == 0) {
|
||||
// All parentdomains by default have no ssl - ip/port
|
||||
$parentdomains[$row['id']] = false;
|
||||
Database::pexecute($ip_stmt, array(
|
||||
'domainid' => $row['id']
|
||||
));
|
||||
while ($iprow = $ip_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
// If the parentdomain has an ip/port assigned which we know is SSL enabled, set the parentdomain to "true"
|
||||
if (array_key_exists($iprow['id_ipandports'], $ips)) {
|
||||
$parentdomains[$row['id']] = true;
|
||||
}
|
||||
}
|
||||
} elseif ($row['ssl_redirect'] == 1) {
|
||||
// All subdomains with enabled ssl_redirect enabled are stored
|
||||
if (! isset($subdomains[$row['parentdomainid']])) {
|
||||
$subdomains[$row['parentdomainid']] = array();
|
||||
}
|
||||
$subdomains[$row['parentdomainid']][] = $row['id'];
|
||||
}
|
||||
}
|
||||
|
||||
// Check if every parentdomain with enabled ssl_redirect as SSL enabled
|
||||
foreach ($parentdomains as $id => $sslavailable) {
|
||||
// This parentdomain has no subdomains
|
||||
if (! isset($subdomains[$id])) {
|
||||
continue;
|
||||
}
|
||||
// This parentdomain has SSL enabled, doesn't matter what status the subdomains have
|
||||
if ($sslavailable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// At this point only parentdomains reside which have ssl_redirect enabled subdomains
|
||||
if ($fix) {
|
||||
// We make a blanket update to all subdomains of this parentdomain, doesn't matter which one is wrong, all have to be disabled
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'domainid' => $id
|
||||
));
|
||||
$this->_log->logAction(ADM_ACTION, LOG_WARNING, "found a subdomain with ssl_redirect=1 but parent-domain has ssl=0, integrity check fixed this");
|
||||
} else {
|
||||
// It's just the check, let the function fail
|
||||
$this->_log->logAction(ADM_ACTION, LOG_NOTICE, "found a subdomain with ssl_redirect=1 but parent-domain has ssl=0, integrity check can fix this");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fix) {
|
||||
return $this->SubdomainSslRedirect();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all subdomain have letsencrypt = 0 if domain has no ssl-port
|
||||
*
|
||||
* @param bool $fix
|
||||
* Fix everything found directly
|
||||
*/
|
||||
public function SubdomainLetsencrypt($fix = false)
|
||||
{
|
||||
$ips = array();
|
||||
$parentdomains = array();
|
||||
$subdomains = array();
|
||||
|
||||
if ($fix) {
|
||||
// Prepare update statement for the fixes
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DOMAINS . "`
|
||||
SET `letsencrypt` = 0 WHERE `parentdomainid` = :domainid");
|
||||
}
|
||||
|
||||
// Cache all ssl ip/port - combinations
|
||||
$result_stmt = Database::prepare("SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `ssl` = 1 ORDER BY `id` ASC");
|
||||
Database::pexecute($result_stmt);
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$ips[$row['id']] = $row['ip'] . ':' . $row['port'];
|
||||
}
|
||||
|
||||
// Cache all configured domains
|
||||
$result_stmt = Database::prepare("SELECT `id`, `parentdomainid`, `letsencrypt` FROM `" . TABLE_PANEL_DOMAINS . "` ORDER BY `id` ASC");
|
||||
$ip_stmt = Database::prepare("SELECT `id_domain`, `id_ipandports` FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :domainid");
|
||||
Database::pexecute($result_stmt);
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if ($row['parentdomainid'] == 0) {
|
||||
// All parentdomains by default have no ssl - ip/port
|
||||
$parentdomains[$row['id']] = false;
|
||||
Database::pexecute($ip_stmt, array(
|
||||
'domainid' => $row['id']
|
||||
));
|
||||
while ($iprow = $ip_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
// If the parentdomain has an ip/port assigned which we know is SSL enabled, set the parentdomain to "true"
|
||||
if (array_key_exists($iprow['id_ipandports'], $ips)) {
|
||||
$parentdomains[$row['id']] = true;
|
||||
}
|
||||
}
|
||||
} elseif ($row['letsencrypt'] == 1) {
|
||||
// All subdomains with enabled letsencrypt enabled are stored
|
||||
if (! isset($subdomains[$row['parentdomainid']])) {
|
||||
$subdomains[$row['parentdomainid']] = array();
|
||||
}
|
||||
$subdomains[$row['parentdomainid']][] = $row['id'];
|
||||
}
|
||||
}
|
||||
|
||||
// Check if every parentdomain with enabled letsencrypt as SSL enabled
|
||||
foreach ($parentdomains as $id => $sslavailable) {
|
||||
// This parentdomain has no subdomains
|
||||
if (! isset($subdomains[$id])) {
|
||||
continue;
|
||||
}
|
||||
// This parentdomain has SSL enabled, doesn't matter what status the subdomains have
|
||||
if ($sslavailable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// At this point only parentdomains reside which have letsencrypt enabled subdomains
|
||||
if ($fix) {
|
||||
// We make a blanket update to all subdomains of this parentdomain, doesn't matter which one is wrong, all have to be disabled
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'domainid' => $id
|
||||
));
|
||||
$this->_log->logAction(ADM_ACTION, LOG_WARNING, "found a subdomain with letsencrypt=1 but parent-domain has ssl=0, integrity check fixed this");
|
||||
} else {
|
||||
// It's just the check, let the function fail
|
||||
$this->_log->logAction(ADM_ACTION, LOG_NOTICE, "found a subdomain with letsencrypt=1 but parent-domain has ssl=0, integrity check can fix this");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fix) {
|
||||
return $this->SubdomainLetsencrypt();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the webserveruser is in
|
||||
* the customers groups when fcgid / php-fpm is used
|
||||
*
|
||||
* @param bool $fix
|
||||
* fix member/groups
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function WebserverGroupMemberForFcgidPhpFpm($fix = false)
|
||||
{
|
||||
if (Settings::Get('system.mod_fcgid') == 0 && Settings::Get('phpfpm.enabled') == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// get all customers that don't have the webserver-user in their group
|
||||
$cwg_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_FTP_GROUPS . "` WHERE NOT FIND_IN_SET(:webserveruser, `members`)
|
||||
");
|
||||
Database::pexecute($cwg_stmt, array(
|
||||
'webserveruser' => Settings::Get('system.httpuser')
|
||||
));
|
||||
|
||||
if ($cwg_stmt->rowCount() > 0) {
|
||||
$this->_log->logAction(ADM_ACTION, LOG_NOTICE, "Customers are missing the webserver-user as group-member, integrity-check can fix that");
|
||||
if ($fix) {
|
||||
// prepare update statement
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_GROUPS . "` SET `members` = CONCAT(`members`, :additionaluser)
|
||||
WHERE `id` = :id
|
||||
");
|
||||
$upd_data = array(
|
||||
'additionaluser' => "," . Settings::Get('system.httpuser')
|
||||
);
|
||||
|
||||
while ($cwg_row = $cwg_stmt->fetch()) {
|
||||
$upd_data['id'] = $cwg_row['id'];
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
}
|
||||
$this->_log->logAction(ADM_ACTION, LOG_NOTICE, "Customers were missing the webserver-user as group-member, integrity-check fixed that");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fix) {
|
||||
return $this->WebserverGroupMemberForFcgidPhpFpm();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the local froxlor user is in
|
||||
* the customers groups when fcgid / php-fpm and
|
||||
* fcgid/fpm in froxlor vhost is used
|
||||
*
|
||||
* @param bool $fix
|
||||
* fix member/groups
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function FroxlorLocalGroupMemberForFcgidPhpFpm($fix = false)
|
||||
{
|
||||
if (Settings::Get('system.mod_fcgid') == 0 && Settings::Get('phpfpm.enabled') == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Settings::get('system.mod_fcgid') == 1) {
|
||||
if (Settings::get('system.mod_fcgid_ownvhost') == 0) {
|
||||
return true;
|
||||
} else {
|
||||
$localuser = Settings::Get('system.mod_fcgid_httpuser');
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings::get('phpfpm.enabled') == 1) {
|
||||
if (Settings::get('phpfpm.enabled_ownvhost') == 0) {
|
||||
return true;
|
||||
} else {
|
||||
$localuser = Settings::Get('phpfpm.vhost_httpuser');
|
||||
}
|
||||
}
|
||||
|
||||
// get all customers that don't have the webserver-user in their group
|
||||
$cwg_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_FTP_GROUPS . "` WHERE NOT FIND_IN_SET(:localuser, `members`)
|
||||
");
|
||||
Database::pexecute($cwg_stmt, array(
|
||||
'localuser' => $localuser
|
||||
));
|
||||
|
||||
if ($cwg_stmt->rowCount() > 0) {
|
||||
$this->_log->logAction(ADM_ACTION, LOG_NOTICE, "Customers are missing the local froxlor-user as group-member, integrity-check can fix that");
|
||||
if ($fix) {
|
||||
// prepare update statement
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_GROUPS . "` SET `members` = CONCAT(`members`, :additionaluser)
|
||||
WHERE `id` = :id
|
||||
");
|
||||
$upd_data = array(
|
||||
'additionaluser' => "," . $localuser
|
||||
);
|
||||
|
||||
while ($cwg_row = $cwg_stmt->fetch()) {
|
||||
$upd_data['id'] = $cwg_row['id'];
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
}
|
||||
$this->_log->logAction(ADM_ACTION, LOG_NOTICE, "Customers were missing the local froxlor-user as group-member, integrity-check fixed that");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fix) {
|
||||
return $this->FroxlorLocalGroupMemberForFcgidPhpFpm();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
21
lib/Froxlor/FroxlorTwoFactorAuth.php
Normal file
21
lib/Froxlor/FroxlorTwoFactorAuth.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Froxlor;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class FroxlorTwoFactorAuth extends \RobThree\Auth\TwoFactorAuth
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user