Mini Shell
<?php
/**
* Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
*
* Licensed under CLOUD LINUX LICENSE AGREEMENT
* http://cloudlinux.com/docs/LICENSE.TXT
*/
if(file_exists(__DIR__ . '/vendor.php')) {
include_once(__DIR__ . '/vendor.php');
}
class LveManager {
/**
* Path to "cloudlinux-cli.py" script.
*
* @var string
*/
public $CLOUDLINUX_CLI = '/usr/bin/sudo /usr/share/l.v.e-manager/utils/cloudlinux-cli.py';
// Default app mode
const APP_MODE = 'PRODUCTION_MODE';
const CONFIG_INI_FILE = '/opt/cpvendor/etc/integration.ini';
protected $userData;
protected $owner = 'user';
protected $bundleName = 'main';
protected $pluginName;
/**
* Required parameters.
*
* @var array
*/
public $userInfo;
public $config;
const OWNER_ADMIN = 'admin';
const OWNER_USER = 'user';
const OWNER_RESELLER = 'reseller';
/**
* Read config file and prepare.
* @return string
*/
function __construct($pluginName = 'lvemanager') {
$this->pluginName = $pluginName;
$budleMapping = Array(
'lvemanager' => 'main',
'resource-usage' => 'resource_usage'
);
$this->bundleName = isset($budleMapping[$pluginName]) ? $budleMapping[$pluginName] : $pluginName;
$this->loadConfig();
$this->loadUserData();
}
function loadConfig()
{
$iniData = file_get_contents(self::CONFIG_INI_FILE);
$this->config = parse_ini_string($iniData, true)['lvemanager_config'];
if (!$this->config) {
$this->config = Array();
}
}
function loadUserData()
{
$userInfoCli = $this->config['ui_user_info'];
$token = $this->defineAndGetSessionToken();
$this->userData = json_decode(shell_exec($userInfoCli.' '.escapeshellarg($token)));
}
function validateUserData($data) {
if (
!is_object($data)
||
!property_exists($data, 'userName')
||
!is_string($data->userName)
||
!property_exists($data, 'userType')
||
!in_array($data->userType, ['admin', 'reseller', 'user'])
) {
$this->sendErrorResponse('INVALID USER DATA', false, true);
}
}
/**
* Update and return session token if it was provided by vendor.
* @return string
*/
public function defineAndGetSessionToken()
{
if (@$_GET['token']) {
setcookie('CLSIDTOKEN', @$_GET['token']);
return @$_GET['token'];
}
if (isset($_COOKIE['CLSIDTOKEN'])) {
return $_COOKIE['CLSIDTOKEN'];
}
$this->sendErrorResponse('INVALID SESSION TOKEN', false, true);
}
/**
* Get base URL of site.
* @return string
*/
public function getBaseUrl()
{
return $this->userData->baseUri;
}
/**
* Get plugin version
* @return string
*/
public static function getPluginVersion()
{
return trim(exec('cat /usr/share/l.v.e-manager/version'));
}
/**
* Get name of current authorized user in system.
* @return string
*/
public function getLogin()
{
return $this->userData->userName;
}
/**
* Get name of current authorized user in system.
* @return string
*/
public function getUserId()
{
return $this->userData->userId;
}
/**
* Get URL to vendor resources,
* which were defined in integration config file
* @return string
*/
public function getVendorSrcUrl()
{
return $this->getBaseUrl().'/vendor_src/';
}
/**
* Get current user type: admin|reseller|user
* @return string
*/
public function getUserType() {
return $this->userData->userType;
}
public function getRequestHandler()
{
$pluginMapping = Array(
'lvemanager' => 'send-request.php',
'nodejs_selector' => 'send-request-nodejs.php',
'python_selector' => 'send-request-python.php',
'php_selector' => 'send-request-php-selector.php',
'xray' => 'send-request-xray.php',
'resource_usage' => 'send-request-resource-usage.php',
'wpos' => 'send-request-awp.php',
);
return $pluginMapping[$this->pluginName] ? $pluginMapping[$this->pluginName] : $pluginMapping['lvemanager'];
}
/**
* Check reseller have not access to admin
* and user have not acces to reseller and admin.
*
* @param $owner
* @return down privileges value
*/
public function checkOwner($owner) {
switch ($this->userData->userType) {
case $this::OWNER_RESELLER:
$newOwner = in_array($owner, array($this::OWNER_RESELLER, $this::OWNER_USER)) ? $owner : $this::OWNER_RESELLER;
break;
case $this::OWNER_USER:
$newOwner = $this::OWNER_USER;
break;
default:
$newOwner = $owner;
}
return $newOwner;
}
/**
* Processes of incoming post request.
*
* @param $owner
* @throws pm_Exception
*/
public function processRequest($owner, $plugin_name = '')
{
$this->_checkVulnerabilities();
$this->validateUserData($this->userData);
$this->owner = $this->checkOwner($owner);
if (!isset($_POST['command'])) {
$this->sendErrorResponse('COMMAND NOT SPECIFIED');
}
$data['owner'] = $this->owner;
$data['command'] = $_POST['command'];
if (isset($_POST['method'])) {
$data['method'] = $_POST['method'];
}
if (isset($_POST['params'])) {
$data['params'] = $_POST['params'];
}
if (in_array($this->owner, array(self::OWNER_USER, self::OWNER_RESELLER))) {
$this->userInfo = array(
'username' => $this->getLogin(),
'lve-id' => $this->getUserId(),
);
$data['user_info'] = $this->userInfo;
}
if (isset($_POST['mockJson'])) {
$data['mockJson'] = $_POST['mockJson'];
}
if (isset($_POST['lang'])) {
$data['lang'] = $_POST['lang'];
}
if ($plugin_name !== '') {
$data['plugin_name'] = $plugin_name;
}
$fullCommandStr = sprintf(
"%s --data=%s 2>&1",
$this->CLOUDLINUX_CLI, base64_encode(json_encode($data))
);
putenv('LC_ALL=en_US.UTF-8');
ob_start();
passthru($fullCommandStr);
$responseInJson = ob_get_contents();
ob_end_clean();
$response = json_decode($responseInJson, true);
if (is_null($response) && !empty($responseInJson)) {
$this->sendErrorResponse(
'ERROR.wrong_received_data', false, false,
503, $responseInJson
);
}
if (isset($response['result']) && $response['result'] === 'file') {
$this->serveFile($response['filepath'], $response['filesize'], $data);
} else if (isset($response['result']) && $response['result'] !== 'success' && $response['result'] !== 'rollback') {
$this->sendErrorResponse($responseInJson, true);
} else if (empty($responseInJson)) {
$this->sendErrorResponse('RESPONSE OF COMMAND IS EMPTY');
}
echo $responseInJson;
}
/**
* Returns response to SPA with error code, message and break execution of
* script with status code.
*
* @param $message
* @param $isJSON
* @param $logoutSignal
* @param int $statusCode
* @param string $details
*/
public function sendErrorResponse(
$message, $isJSON = false,
$logoutSignal = false, $statusCode = 503,
$details = ''
) {
http_response_code($statusCode);
if ($isJSON) {
echo $message;
} else {
$response = array(
'result' => $message,
'logoutSignal' => $logoutSignal,
'details' => $details,
);
echo json_encode($response);
}
exit();
}
/**
* Returns response to SPA with file
*
* @param $filepath
*/
public function serveFile($fileName, $fileSize, $requestData) {
header("Content-Type: application/x-download");
header("Content-Length: $fileSize");
$requestData['method'] = 'log_data';
$fullCommandStr = sprintf(
"%s --data=%s 2>&1",
$this->CLOUDLINUX_CLI, base64_encode(json_encode($requestData))
);
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$pipes = array();
$process = proc_open($fullCommandStr, $descriptorspec, $pipes);
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
flush();
}
}
exit();
}
/**
* Checking of vulnerabilities: CSRF and HTTP_REFERER
*/
private function _checkVulnerabilities()
{
$this->_checkCSRFToken();
$this->_checkReferer();
}
/*
* Check CSRF token.
*/
private function _checkCSRFToken()
{
if (!isset($_COOKIE['csrftoken'])
|| $_COOKIE['csrftoken'] !== $_SERVER['HTTP_X_CSRFTOKEN']
) {
$this->sendErrorResponse('BAD FORGERY PROTECTION TOKEN', false, true);
}
}
/**
* Check HTTP_REFERER.
*/
private function _checkReferer()
{
if (!preg_match(
sprintf(
'/^%s:\/\/%s/',
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on')
? 'https' : 'http',
$_SERVER['HTTP_HOST']
),
$_SERVER['HTTP_REFERER'])
) {
$this->sendErrorResponse('BAD REFERER', false, true);
}
}
public function setCSRFToken()
{
if (!isset($_COOKIE['csrftoken'])) {
setcookie("csrftoken", md5(uniqid(rand(), true)));
}
}
public function getAppMode()
{
$modeFile = '/usr/share/l.v.e-manager/spa/app_mode.status';
if (file_exists($modeFile)) {
return trim(file_get_contents($modeFile));
}
return self::APP_MODE;
}
/**
* Instert static files
*/
public function insertPanel()
{
$pluginVersion = $this->getPluginVersion();
$requestHandler = $this->getRequestHandler();
if ($this->pluginName == 'wpos') {
return <<<TEMPLATE
<base href="{$this->getBaseUrl()}">
<link rel="stylesheet" href="{$this->userData->assetsUri}/assets/awp-user/common-styles.css" />
<link rel="stylesheet" href="{$this->userData->assetsUri}/assets/awp-user/bootstrap.min.css" />
<lvemanager>
Loading...
</lvemanager>
<script type="text/javascript">
var APP_MODE = '{$this->getAppMode()}';
var mainAction = '{$this->userData->baseUri}/{$this->getRequestHandler()}';
var panelName = 'Unknown';
var pluginVersion = '{$pluginVersion}';
var userType = '{$this->userData->userType}';
var userName = '{$this->userData->userName}';
var currentLanguage = '{$this->userData->lang}';
var localePath = '{$this->userData->assetsUri}/assets/awp-user/i18n/';
</script>
<script src="{$this->userData->assetsUri}/assets/awp-user/polyfills.bundle.min.js?v={$pluginVersion}"></script>
<script src="{$this->userData->assetsUri}/assets/awp-user/vendor.bundle.min.js?v={$pluginVersion}"></script>
<script src="{$this->userData->assetsUri}/assets/awp-user/wpos.bundle.min.js?v={$pluginVersion}"></script>
TEMPLATE;
} else if ($this->pluginName == 'xray') {
return <<<TEMPLATE
<base href="{$this->getBaseUrl()}">
<link rel="stylesheet" href="{$this->userData->assetsUri}/assets/xray-user/css/xray-common.css" />
<lvemanager>
Loading...
</lvemanager>
<script type="text/javascript">
var APP_MODE = '{$this->getAppMode()}';
var mainAction = '{$this->userData->baseUri}/{$this->getRequestHandler()}';
var panelName = 'Unknown';
var pluginVersion = '{$pluginVersion}';
var userType = '{$this->userData->userType}';
var userName = '{$this->userData->userName}';
var currentLanguage = '{$this->userData->lang}';
var assetsStaticPath = '{$this->userData->assetsUri}/assets/';
var localePath = '{$this->userData->assetsUri}/assets/xray-user/i18n/';
</script>
<script src="{$this->userData->assetsUri}/assets/xray-user/xray.bundle.min.js?v={$pluginVersion}"></script>
TEMPLATE;
} else {
return <<<TEMPLATE
<base href="{$this->getBaseUrl()}">
<link rel="stylesheet" href="{$this->userData->assetsUri}/assets/css/bootstrap.min.css" />
<link rel="stylesheet" href="{$this->userData->assetsUri}/assets/css/style.css" />
<link rel="stylesheet" href="{$this->userData->assetsUri}/assets/static/common-styles.css" />
<link rel="stylesheet" href="{$this->userData->assetsUri}/assets/css/lvemanager.css" />
<lvemanager>
<div class="big_loader_wrapper">
<div class="big_loader">
<img src="{$this->userData->assetsUri}/assets/images/loader.svg">
</div>
</div>
</lvemanager>
<script src="{$this->userData->assetsUri}/assets/js/jquery.min.js"></script>
<script src="{$this->userData->assetsUri}/assets/js/bootstrap.min.js"></script>
<script src="{$this->userData->assetsUri}/assets/js/common.js"></script>
<script type="text/javascript">
var APP_MODE = '{$this->getAppMode()}';
var mainAction = '{$this->userData->baseUri}/{$this->getRequestHandler()}';
var panelName = 'Unknown';
var pluginVersion = '{$pluginVersion}';
var userType = '{$this->userData->userType}';
var userName = '{$this->userData->userName}';
var currentLanguage = '{$this->userData->lang}';
var localePath = '{$this->userData->assetsUri}/assets/i18n/';
var assetsStaticPath = '{$this->userData->assetsUri}/assets/';
</script>
<script src="{$this->userData->assetsUri}/assets/js/locales/{$this->userData->lang}.js"></script>
<script src="{$this->userData->assetsUri}/assets/static/common.bundle.min.js?v={$pluginVersion}"></script>
<script src="{$this->userData->assetsUri}/assets/static/polyfills.bundle.min.js?v={$pluginVersion}"></script>
<script src="{$this->userData->assetsUri}/assets/static/vendor.bundle.min.js?v={$pluginVersion}"></script>
<script src="{$this->userData->assetsUri}/assets/static/{$this->bundleName}.bundle.min.js?v={$pluginVersion}"></script>
TEMPLATE;
}
}
public function availableProducts()
{
$pluginList = Array();
if ($this->userData->userType == 'user')
{
$pluginList[] = Array(
'name' => 'PHP',
'image' => 'image',
'link' => '/open.php?plugin=php_selector'
);
$pluginList[] = Array(
'name' => 'NodeJS',
'image' => 'image',
'link' => '/open.php?plugin=nodejs_selector'
);
$pluginList[] = Array(
'name' => 'Python',
'image' => 'image',
'link' => '/open.php?plugin=python_selector'
);
$pluginList[] = Array(
'name' => 'X-Ray',
'image' => 'image',
'link' => '/open.php?plugin=xray'
);
$pluginList[] = Array(
'name' => 'AccelerateWP',
'image' => 'image',
'link' => '/open.php?plugin=wpos'
);
} else {
$pluginList[] = Array(
'name' => 'LveManager',
'image' => 'image',
'link' => '/open.php?plugin=lvemanager'
);
}
return $pluginList;
}
}
Zerion Mini Shell 1.0