403Webshell
Server IP : 192.158.238.246  /  Your IP : 18.216.1.197
Web Server : LiteSpeed
System : Linux uniform.iwebfusion.net 4.18.0-553.27.1.lve.1.el8.x86_64 #1 SMP Wed Nov 20 15:58:00 UTC 2024 x86_64
User : jenniferflocom ( 1321)
PHP Version : 8.1.32
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /usr/local/lsws/add-ons/cpanel/lsws_whm_plugin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/local/lsws/add-ons/cpanel/lsws_whm_plugin/WhmMod_LiteSpeed_Util.php
<?php

/** ******************************************
 * LiteSpeed Web Server Plugin for WHM
 *
 * @author LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
 * @copyright (c) 2013-2020
 * ******************************************* */

namespace LsPanel;

use \Lsc\Wp\Panel\CPanel;

class WhmMod_LiteSpeed_Util
{

    const LSCACHE_STATUS_NOT_SUPPORTED = 0;
    const LSCACHE_STATUS_MISSING = 1;
    const LSCACHE_STATUS_DETECTED = 2;
    const LSCACHE_STATUS_UNKNOWN = 3;

    /**
     * @var string
     */
    private $moduleCmd;

    /**
     * @var string
     */
    private $latestVersFile;

    /**
     * @var string
     */
    private $newBuildFile;

    /**
     * @var string
     */
    private $serial_file;

    /**
     * @var string
     */
    private $trial_key_file;

    /**
     * @var string
     */
    private $version_file;

    /**
     * @var string
     */
    private $build_file;

    /**
     * @var string
     */
    private $stable_file;

    /**
     * @var string
     */
    private $admin_conf;

    /**
     * @var string
     */
    private $serv_conf;

    /**
     * @var string[]
     */
    private static $success_msgs = array();

    /**
     * @var string[]
     */
    private static $err_msgs = array();

    public function __construct()
    {
        $this->Init();
    }

    public function Init()
    {
        $lswsHome = (defined('LSWS_HOME')) ? LSWS_HOME : '/usr/local/lsws';

        $this->moduleCmd = WhmMod_LiteSpeed_ControlApp::CGI_DIR
            . '/bin/lsws_cmd.sh ' . escapeshellarg($lswsHome);
        $this->latestVersFile =
                WhmMod_LiteSpeed_ControlApp::CGI_DIR . '/latest_vers';
        $this->newBuildFile =
            WhmMod_LiteSpeed_ControlApp::CGI_DIR . '/new_build';
        $this->serial_file = "{$lswsHome}/conf/serial.no";
        $this->trial_key_file = "{$lswsHome}/conf/trial.key";
        $this->version_file = "{$lswsHome}/VERSION";
        $this->build_file = "{$lswsHome}/BUILD";
        $this->stable_file = "{$lswsHome}/autoupdate/follow_stable";
        $this->admin_conf = "{$lswsHome}/admin/conf/admin_config.xml";
        $this->serv_conf = "{$lswsHome}/conf/httpd_config.xml";
    }

    public static function add_success_msg( $success_mesg )
    {
        if ( is_array($success_mesg) ) {
            self::$success_msgs = array_merge(self::$success_msgs,
                    $success_mesg);
        }
        else {
            self::$success_msgs[] = $success_mesg;
        }
    }

    public static function get_success_msg()
    {
        return self::$success_msgs;
    }

    public static function add_error_msg( $err_mesg )
    {
        if ( is_array($err_mesg) ) {
            self::$err_msgs = array_merge(self::$err_msgs, $err_mesg);
        }
        else {
            self::$err_msgs[] = $err_mesg;
        }
    }

    public static function get_error_msg()
    {
        return self::$err_msgs;
    }

    /**
     *
     * @since 4.1  Added param $default.
     *
     * @param string  $tag
     * @param mixed   $default  The default value to be passed back when the
     *                          request var is not found.
     * @return mixed|null|string
     */
    public static function get_request_var( $tag, $default = null )
    {
        $varValue = $default;

        if ( isset($_REQUEST[$tag])  ) {
            $varValue = $_REQUEST[$tag];

            if ( $varValue !== null ) {
                $varValue = trim($varValue);
            }
        }

        return $varValue;
    }

    /**
     *
     * @since 4.1  Added param $default.
     *
     * @param string  $tag
     * @param mixed   $default  The default value to be passed back when the
     *                          request list is not found.
     * @return mixed|null|array
     *
     * @noinspection PhpUnused
     */
    public static function get_request_list( $tag, $default = null )
    {
        $listValue = $default;

        if ( isset($_REQUEST[$tag]) ) {
            $result = $_REQUEST[$tag];

            $listValue = (is_array($result)) ? $result : $default;
        }

        return $listValue;
    }

    /**
     *
     * @param string   $url
     * @param boolean  $headerOnly
     * @return string
     */
    public static function get_url_contents( $url, $headerOnly = false )
    {
        if ( ini_get('allow_url_fopen') ) {
            /**
             * silence warning when OpenSSL missing while getting LSCWP ver
             * file.
             */
            $url_content = @file_get_contents($url);

            if ( $url_content !== false ) {

                if ( $headerOnly ) {
                    return implode("\n", $http_response_header);
                }

                return $url_content;
            }
        }

        if ( function_exists('curl_version') ) {
            $ch = curl_init();

            curl_setopt_array(
                    $ch,
                    array(
                        CURLOPT_URL => $url,
                        CURLOPT_RETURNTRANSFER => true,
                        CURLOPT_HEADER => $headerOnly,
                        CURLOPT_NOBODY => $headerOnly,
                        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1
                    )
            );

            $url_content = curl_exec($ch);
            curl_close($ch);

            if ( $url_content !== false ) {
                return $url_content;
            }
        }

        $cmd = 'curl';

        if ( $headerOnly ) {
            $cmd .= ' -s -I';
        }

        exec("{$cmd} {$url}", $output, $ret);

        if ( $ret === 0 ) {
            $url_content = implode("\n", $output);
            return $url_content;
        }

        return '';
    }

    public function getLSPID()
    {
        $cmd = "{$this->moduleCmd} CHECK_LSWS_RUNNING";
        exec($cmd, $output, $return_var);

        /**
         * pid
         */
        return $output[0];
    }

    public function getApachePID()
    {
        $cmd = "{$this->moduleCmd} CHECK_AP_RUNNING";
        exec($cmd, $output);

        /**
         * pid
         */
        return $output[0];
    }

    /**
     *
     * @since 4.1.3
     *
     * @return string
     */
    private static function getLatestWhmPluginVerFilePath()
    {
        return WhmMod_LiteSpeed_ControlApp::CGI_DIR . '/LATEST_VER';
    }

    /**
     *
     * @since 3.3.7
     *
     * @param int  $litespeedPID
     * @param int  $apachePID
     * @param int  $portOffset
     * @return boolean
     */
    public static function isServerSpooling( $litespeedPID, $apachePID,
            $portOffset )
    {
        if ( $litespeedPID > 0 && $apachePID > 0 && $portOffset === 0 ) {
            return true;
        }

        return false;
    }

    public function GetCurrentSerialNo()
    {
        if ( defined('LSWS_HOME') ) {

            if ( file_exists($this->serial_file) ) {
                return file_get_contents($this->serial_file);
            }

            if ( file_exists($this->trial_key_file) ) {
                return 'TRIAL';
            }
        }

        return '';
    }

    private function GetCacheType( $line, &$res )
    {
        if ( preg_match('/FEATURES: ([0-9\.]+)/', $line, $m) ) {
            $feature = $m[1];

            if ( ($feature & 1) == 1 ) {
                $res['has_cache'] = self::LSCACHE_STATUS_DETECTED;
                $feature &= 11;

                switch ($feature) {
                    case 1:
                        $res['lic_type'] .= ' (with LSCache Standard)';
                        break;
                    case 9:
                        $res['lic_type'] .= ' (with LiteMage Starter)';
                        break;
                    case 11:
                        $res['lic_type'] .= ' (with LiteMage Standard)';
                        break;
                    case 3:
                        $res['lic_type'] .= ' (with LiteMage Unlimited)';
                        break;
                    //no default case
                }
            }
            else {
                $res['has_cache'] = self::LSCACHE_STATUS_MISSING;
            }
        }
        else {
            $res['has_cache'] = self::LSCACHE_STATUS_NOT_SUPPORTED;
        }
    }

    /**
     * Takes license type string and returns the expanded translation. In the
     * case where no translation is available (old format) , the license type
     * string is returned as is.
     *
     * @param string  $type  License type string.
     * @return string
     */
     private function translateLicType( $type )
    {
        if ( strlen($type) > 1 && strncmp($type, '9:', 2) == 0 ) {
            return 'Web Host Elite (X-Worker = ' . substr($type, 2) . ')';
        }

        switch ($type) {
            /**
             * old license types to be retired
             */
            case 'V':
                return 'VPS (1-Worker with 2GB Memory Limit)';
            case 'U':
            case 'VU':
            case 'U1':
                return 'UltraVPS (1-Worker with 8GB Memory Limit)';
            case '8':
                return '8-CPU (8-Worker)';

            /**
             * current license types
             */
            case 'F':
                return 'Free Starter (1-Domain & 1-Worker with 2GB Memory '
                        . 'Limit)';
            case 'S':
                return 'Site Owner Plus (5-Domains & 1-Worker)';
            case 'SM':
                return 'Site Owner (5-Domains & 1-Worker with 8GB Memory '
                        . 'Limit)';

            /**
             * 'D' and 'DM' license types are reserved and not used.
             */
            case 'D':
                return 'Domain Limited (Limited-Domain & 1-Worker)';
            case 'DM':
                return 'Domain Limited (Limited-Domain & 1-Worker with 8GB '
                        . 'Memory Limit)';

            case '1M':
                return 'Web Host Lite (1-Worker with 8GB Memory Limit)';
            case '1':
                return 'Web Host Essential (1-Worker)';
            case '2':
                return 'Web Host Professional (2-Worker)';
            case '3':
                return 'Dedicated (3-Worker)';
            case '4':
                return 'Web Host Enterprise (4-Worker)';
            case 'X':
            case '9':
                /**
                 * Failsafe case, should not happen.
                 */
                return 'Web Host Elite (X-Worker)';
            default :
                return $type;
        }
    }

    public function GetLicenseType()
    {
        $res = array( 'lic_type' => '' );
        $statusFile = '/tmp/lshttpd/.status';

        if ( !file_exists($statusFile) ) {
            $res['has_cache'] = self::LSCACHE_STATUS_UNKNOWN;
        }
        else {
            $f = fopen($statusFile, 'r');

            if ( $f === false ) {
                $res['has_cache'] = self::LSCACHE_STATUS_UNKNOWN;
            }
            else {
                $type = '';

                fseek($f, -128, SEEK_END);
                $line = fread($f, 128);
                fclose($f);

                if ( preg_match('/TYPE: (.+)/', $line, $m) ) {
                    $type = $m[1];

                    $translation = $this->translateLicType($type);

                    $res['lic_type'] = "{$translation} License";
                }

                $this->GetCacheType($line, $res);

                /**
                 * Special case to avoid old 1-CPU license w/o LSCache from
                 * appearing as the new license type assumed to include LSCache.
                 */
                if ( $type == '1' &&
                        $res['has_cache'] != self::LSCACHE_STATUS_DETECTED ) {

                    $res['lic_type'] = '1-CPU (1-Worker) License';
                }
            }
        }

        return $res;
    }

    /**
     * Adds LSWS stable version and build info to the referenced array.
     *
     * @param array  $info
     */
    private function populateStableVersionInfo( &$info )
    {
        $newVer = $newBuild = '';

        $info['lsws_version'] = $currVer = $this->GetCurrentVersion();

        $updateInfo = file_get_contents($this->latestVersFile);

        if ( preg_match('/.*LSWS_STABLE=([0-9\.]*)/', $updateInfo, $matches) ) {
            $stableVer = $matches[1];

            if ( version_compare($stableVer, $currVer, '>') ) {
                $newVer = $stableVer;
            }
        }

        $info['new_version'] = $newVer;

        if ( version_compare($info['lsws_version'], '5.2.2', '>=') ) {
            $info['lsws_build'] = $currBuild = $this->GetCurrentBuild();

            if ( isset($stableVer) ) {

                if ( $currVer == $stableVer ) {

                    if ( preg_match('/.*LSWS_STABLE=[0-9\.]* BUILD ([0-9]*)/',
                            $updateInfo, $matches) ) {

                        $stableBuild = $matches[1];

                        if ( $stableBuild > $currBuild ) {
                            $newBuild = $stableBuild;
                        }
                    }
                }
                elseif ( version_compare($currVer, $stableVer, '<') ) {
                    $newBuild = $this->GetNewBuild($currVer, $currBuild);
                }
            }
        }

        $info['new_build'] = $newBuild;
    }

    /**
     * Adds LSWS version and build info to the referenced array.
     *
     * @param array  $info
     */
    public function populateVersionInfo( &$info )
    {
        if ( !file_exists($this->latestVersFile)
                || (time() - filemtime($this->latestVersFile)) > 86400 ) {

            $updateInfo = $this->get_url_contents(
                'http://update.litespeedtech.com/ws/latest.php'
            );

            file_put_contents($this->latestVersFile, $updateInfo);
        }

        if ( file_exists($this->stable_file) ) {
            $this->populateStableVersionInfo($info);
        }
        else {
            $info['lsws_version'] = $this->GetCurrentVersion();
            $info['new_version'] = $this->GetNewVersion($info['lsws_version']);

            if ( version_compare($info['lsws_version'], '5.2.2', '>=') ) {
                $info['lsws_build'] = $this->GetCurrentBuild();
                $info['new_build'] = $this->GetNewBuild($info['lsws_version'],
                        $info['lsws_build']);
            }
        }
    }

    /**
     *
     * @return string
     */
    private function GetCurrentVersion()
    {
        return trim(file_get_contents($this->version_file));
    }

    /**
     *
     * @param string  $currVer
     * @return string
     */
    private function GetNewVersion( $currVer )
    {
        $new_version = '';

        $info = file_get_contents($this->latestVersFile);

        if ( preg_match('/.*LSWS=([0-9\.]*)/', $info, $matches) ) {
            $new = $matches[1];

            if ( version_compare($new, $currVer, '>') ) {
                $new_version = $new;
            }
        }

        return $new_version;
    }

    /**
     *
     * @return string
     */
    private function GetCurrentBuild()
    {
        return trim(file_get_contents($this->build_file));
    }

    /**
     *
     * @param string  $currVersion
     * @param string  $currBuild
     * @return string
     */
    private function getNewBuildFileVer( $currVersion, $currBuild )
    {
        $newBuildFile = $this->newBuildFile;
        $newBuild = '';

        if ( file_exists($newBuildFile) ) {
            $buildFileContent = file_get_contents($newBuildFile);

            preg_match('/ver: (.+)/', $buildFileContent, $verMatches );

            if ( isset($verMatches[1]) && $verMatches[1] == $currVersion ) {
                preg_match('/build: (\d+)/', $buildFileContent, $buildMatches);

                if ( isset($buildMatches[1])
                        && ($fileBuild = $buildMatches[1]) > $currBuild ) {

                    $newBuild = $fileBuild;
                }
            }

            if ( empty($newBuild) ) {
                unlink($newBuildFile);
            }
        }

        return $newBuild;
    }

    /**
     *
     * @param string  $currVersion
     * @param string  $newBuild
     */
    private function writeNewBuildFileVer( $currVersion, $newBuild )
    {
        $content = <<<EOF
ver: {$currVersion}
build: {$newBuild}
EOF;

        file_put_contents($this->newBuildFile, $content);
    }

    /**
     *
     * @param string  $currVersion
     * @param string  $currBuild
     * @return string
     */
    private function GetNewBuild( $currVersion, $currBuild )
    {
        $newBuild = $this->getNewBuildFileVer($currVersion, $currBuild);

        if ( !empty($currBuild)
                && (time() - filemtime($this->build_file)) > 86400 ) {

            $verDir = "{$currVersion[0]}.0";

            $file_content = $this->get_url_contents(
                    "https://www.litespeedtech.com/packages/{$verDir}/"
                    . "lsws-{$currVersion}-ent-x86_64-linux.tar.gz.lastbuild");

            $lastBuild = trim($file_content);

            if ( $currBuild < $lastBuild ) {
                $newBuild = $lastBuild;

                $this->writeNewBuildFileVer($currVersion, $newBuild);
            }

            touch($this->build_file);
        }

        return $newBuild;
    }

    /**
     *
     * @return string[]
     */
    public function GetInstalledVersions()
    {
        $installed_releases = array();
        $dir = LSWS_HOME . '/bin';
        $dh = @opendir($dir);

        if ( $dh ) {

            while ( ($fname = readdir($dh)) !== false ) {
                $matches = array();

                if ( preg_match('/^lswsctrl\.(.*)$/', $fname, $matches) ) {
                    $installed_releases[] = $matches[1];
                }
            }

            closedir($dh);
        }

        return $installed_releases;
    }

    /**
     * Checks for the existence of any modules that will cause file permission
     * problems with LSWS and returns the first module name found.
     *
     * @since 2.2.2
     *
     * @return string
     */
    public function CheckFileProtectWarning()
    {
        $modules = array( 'ruid2', 'mpm_itk' );

        foreach ( $modules as $module ) {
            $cmd = "httpd -M | grep {$module} | wc -l";
            $val = exec($cmd);

            if ( $val === '1' ) {
                return $module;
            }
        }

        return '';
    }

    /**
     * Only checked for EA4.
     *
     * @param string[]  $eaPHP_vers
     * @return int                   1 = missing timezonedb
     *                                2 = update available
     *                                0  = no change.
     */
    public function checkTimezoneDBStatus( $eaPHP_vers )
    {
        foreach ( $eaPHP_vers as $verNum ) {
            $eaPHP_path = "/opt/cpanel/ea-php{$verNum}/root/usr";

            if ( file_exists("{$eaPHP_path}/bin/phpize")
                    && !file_exists("{$eaPHP_path}/lib64/php/modules/timezonedb.so") ) {

                return 1;
            }
        }

        /**
         * Check daily for updates.
         */
        $timezoneDB_flag = WhmMod_LiteSpeed_ControlApp::CGI_DIR
                . '/litespeed_timezonedb';

        if ( !file_exists($timezoneDB_flag)
                || (time() - filemtime($timezoneDB_flag)) > 86400 ) {

            $script = WhmMod_LiteSpeed_ControlApp::CGI_DIR
                    . '/buildtimezone_ea4.sh';
            $cmd = "{$script} y true";

            $output = shell_exec($cmd);

            if ( preg_match('/Newer version found/', $output) ) {
                return 2;
            }

            touch($timezoneDB_flag);
        }

        return 0;
    }

    public function getTimezoneDBMsgs( $output )
    {
        $msgs = array(
            'succ' => preg_grep('/^EA4 PHP ([0-9]+\.)?[0-9]+\.[0-9]+ (?!not)/',
                    $output),
            'warn' => preg_grep('/^EA4 PHP ([0-9]+\.)?[0-9]+\.[0-9]+ not/',
                    $output),
            'err' => preg_grep('/^\*\*ERROR\*\*/', $output)
        );

        $msgs['succ'] = array_merge($msgs['succ'],
                preg_grep('/^CageFS updated/', $output));

        return $msgs;
    }

    /**
     *
     * @noinspection PhpUnused
     */
    public function cpanelInstallPlugin()
    {
        exec(__DIR__ . '/res/ls_web_cache_mgr/install.sh');

        WhmMod_LiteSpeed_CPanelConf::verifyCpanelPluginConfFile();

        CPanel::turnOnCpanelPluginAutoInstall();

        $this->add_success_msg(
            'LiteSpeed cPanel Plugin Installed Successfully');
    }

    /**
     *
     * @noinspection PhpUnused
     */
    public function cpanelUninstallPlugin()
    {
        $cmd = 'res/ls_web_cache_mgr/uninstall.sh';
        exec($cmd);

        CPanel::turnOffCpanelPluginAutoInstall();

        $this->add_success_msg(
            'LiteSpeed cPanel Plugin Uninstalled Successfully');
    }

    private function unparseURL( $urlParts )
    {
        $scheme = isset($urlParts['scheme']) ? "{$urlParts['scheme']}://" : '';
        $host = isset($urlParts['host']) ? $urlParts['host'] : '';
        $port = isset($urlParts['port']) ? ":{$urlParts['port']}" : '';
        $user = isset($urlParts['user']) ? $urlParts['user'] : '';
        $pass = isset($urlParts['pass']) ? ":{$urlParts['pass']}" : '';
        $pass = ($user || $pass) ? "{$pass}@" : '';
        $path = isset($urlParts['path']) ? $urlParts['path'] : '';
        $query = isset($urlParts['query']) ? "?{$urlParts['query']}" : '';
        $fragment =
            isset($urlParts['fragment']) ? "#{$urlParts['fragment']}" : '';

        return $scheme . $user . $pass . $host . $port . $path . $query
                . $fragment;
    }

    private function removeExtURLPort( &$url )
    {
        $urlParts = parse_url($url);

        if ( !isset($urlParts['port']) ) {
            return;
        }

        unset($urlParts['port']);

        $url = $this->unparseURL($urlParts);
    }

    public function GetAdminUrl()
    {
        $data = file_get_contents($this->admin_conf);
        $url = '';

        if ( $data != '' ) {
            /**
             * http://' . $_SERVER['HTTP_HOST'] . ':' . $admin_port . '/
             */

            /*
             * <address>*:7080</address>
             */
            $port = "7080";

            if ( preg_match("/<address>.*:(\d+)<\/address>/", $data, $matches) ) {
                $port = $matches[1];
            }

            /*
             * <secure>0</secure>
             */
            $is_secure = '';

            if ( preg_match("/<secure>(\d)<\/secure>/", $data, $matches)
                    && $matches[1] == 1 ) {

                $is_secure = 's';
            }

            $host = $_SERVER['HTTP_HOST'];
            $this->removeExtURLPort($host);

            $url = "http{$is_secure}://{$host}:{$port}";
        }

        return $url;
    }

    /**
     *
     * @param string|string[]|null  $fields
     * @return string[]
     */
    public function GetLSConfig( $fields = NULL )
    {
        $contents = file_get_contents($this->serv_conf);
        $entry = array();

        if ( is_array($fields) ) {

            foreach ( $fields as $f ) {
                $entry[$f] = '';
            }
        }
        else {
            $entry[$fields] = '';
        }

        foreach ( $entry as $key => $val ) {

            if ( preg_match("/<{$key}>(.*?)<\/{$key}>/s", $contents, $matches) ) {
                $entry[$key] = $matches[1];
            }
        }

        return $entry;
    }

    public function GetApachePortOffset()
    {
        $field = 'apachePortOffset';
        $d = $this->GetLSConfig($field);

        return (int)$d[$field];
    }

    public function ChangePortOffset( $new_port_offset, &$output )
    {
        $cmd = "{$this->moduleCmd} CHANGE_PORT_OFFSET {$new_port_offset}";
        exec($cmd, $output, $return_var);

        return $return_var;
    }

    /**
     *
     * @param string  $serial
     * @param array   $output
     * @return int
     */
    public function ChangeLicense( $serial, &$output )
    {
        $cmd = "{$this->moduleCmd} CHANGE_LICENSE {$serial}";
        exec($cmd, $output, $return_var);

        self::removeCriticalAlertMsg();

        return $return_var;
    }

    /**
     *
     * @param array  $output
     * @return int
     */
    public function RestartLSWS( &$output )
    {
        $cmd = "{$this->moduleCmd} RESTART_LSWS";
        exec($cmd, $output, $return_var);

        return $return_var;
    }

    public function Switch2LSWS( &$output )
    {
        $cmd = "{$this->moduleCmd} SWITCH_TO_LSWS";
        exec($cmd, $output, $return_var);

        return $return_var;
    }

    public function Switch2Apache( &$output )
    {
        $cmd = "{$this->moduleCmd} SWITCH_TO_APACHE";
        exec($cmd, $output, $return_var);

        return $return_var;
    }

    /**
     *
     * @since 3.3.7
     *
     * @return string
     */
    private static function getCriticalAlertFilePath()
    {
        if ( defined('LSWS_HOME') && LSWS_HOME != '' ) {
            return LSWS_HOME . '/logs/critical_alert';
        }

        return '';
    }

    /**
     * Return LSWS critical alert if one exists.
     *
     * @since 3.3.5
     *
     * @return string
     */
    public static function getCriticalAlertMsg()
    {
        $msg = '';

        if ( ($criticalAlertFile = self::getCriticalAlertFilePath()) != ''
                && file_exists($criticalAlertFile) ) {

            $msg = trim(file_get_contents($criticalAlertFile));

            /**
             * Messages stored in this file should only be license related.
             */
            $msg .= ' (If you have recently made a change to or a payment for '
                . 'this license and believe this message to be in error, '
                . 'please visit the '
                . '<a href="?do=check_license">License Status</a> page to '
                . 'refresh your license status)';
        }

        return $msg;
    }

    /**
     * Remove LSWS critical alert file if it exists.
     *
     * @since 3.3.7
     *
     * @return boolean
     */
    private static function removeCriticalAlertMsg()
    {
        if ( ($criticalAlertFile = self::getCriticalAlertFilePath()) != ''
                && file_exists($criticalAlertFile) ) {

            return unlink($criticalAlertFile);
        }

        return false;
    }

    public function GetCurrentLicenseStatus( &$output )
    {
        self::removeCriticalAlertMsg();

        $cmd = "{$this->moduleCmd} CHECK_LICENSE";
        exec($cmd, $output, $return_var);

        return $return_var;
    }

    public function UninstallLSWS( $keepConf, $keepLog, &$output )
    {
        $cmd = "{$this->moduleCmd} UNINSTALL {$keepConf} {$keepLog}";
        exec($cmd, $output, $return_var);

        return $return_var;
    }

    public function DetectLSWS_HOME()
    {
        /**
         * Testing possible locations
         */
        $possible_loc = array( '/usr/local/lsws', '/opt/lsws' );

        foreach ( $possible_loc as $path ) {

            if ( is_file("{$path}/bin/lshttpd") ) {
                return $path;
            }
        }

        return '';
    }

    public function Validate_LSWS_HOME( $lsws_home_input,
            $hasInstalled = false )
    {

        if ( $lsws_home_input == '' ) {
            return 'Missing input!';
        }

        if ( $hasInstalled && !is_file($lsws_home_input . '/bin/lshttpd') ) {
            return "Invalid path: cannot find {$lsws_home_input}/bin/lshttpd!";
        }
        else {

            if ( strpos($lsws_home_input, ' ') !== FALSE ) {
                return 'Do not allow space in the path!';
            }

            /**
             * New installation, prohibit certain paths.
             */
            $forbiddenDirs = array(
                '/etc', '/usr/sbin', '/usr/bin', '/usr/lib', '/usr/local/bin',
                '/usr/local/sbin', '/usr/local/lib'
            );

            foreach ( $forbiddenDirs as $dir ) {

                if ( strpos($lsws_home_input, $dir) !== FALSE ) {
                    return 'It is not safe to install under this system '
                            . 'directory';
                }
            }
        }

        return NULL;
    }

    public function Validate_NewPortOffset( $new_port_offset,
            $old_port_offset )
    {
        $err = $this->validate_port_offset($new_port_offset);

        if ( $err == NULL && $new_port_offset == $old_port_offset ) {
            $err = 'New value is same as current one';
        }

        return $err;
    }

    public function Validate_ChangeLicenseInput( $input )
    {
        return $this->validate_license_type($input);
    }

    public function Validate_InstallInput( $input )
    {
        $errors = $this->validate_license_type($input);

        $err = $this->Validate_LSWS_HOME($input['lsws_home_input']);

        if ( $err != NULL ) {
            $errors['lsws_home_input'] = $err;
        }

        $err = $this->validate_port_offset($input['port_offset']);

        if ( $err != NULL ) {
            $errors['port_offset'] = $err;
        }

        if ( $input['admin_login'] == '' ) {
            $errors['admin_login'] = 'Missing login ID!';
        }
        elseif ( !preg_match('/^[a-zA-Z0-9_\-]+$/', $input['admin_login']) ) {
            $errors['admin_login'] =
                'Accepted characters for login ID are [a-zA-Z0-9_\-]';
        }

        if ( $input['admin_pass'] == '' ) {
            $errors['admin_pass'] = 'Missing login password';
        }
        elseif ( $input['admin_pass1'] == '' ) {
            $errors['admin_pass1'] = 'Missing login password';
        }
        elseif ( $input['admin_pass'] != $input['admin_pass1'] ) {
            $errors['admin_pass1'] = 'Passwords do not match!';
        }
        elseif ( strlen($input['admin_pass']) < 6 ) {
            $errors['admin_pass'] = 'Password must be at least 6 characters!';
        }
        elseif ( strlen($input['admin_pass']) > 64 ) {
            $errors['admin_pass'] =
                'Password is too long, must be less than 64 characters!';
        }
        elseif ( strpos($input['admin_pass'], ' ') !== FALSE ) {
            $errors['admin_pass'] = 'Password cannot contain space!';
        }

        if ( $input['admin_email'] == '' ) {
            $errors['admin_email'] = 'Missing Admin Email!';
        }
        else {
            $emails = preg_split("/, /", $input['admin_email'], -1,
                    PREG_SPLIT_NO_EMPTY);

            foreach ( $emails as $em ) {

                if ( !preg_match("/^[[:alnum:]._-]+@[[:alnum:]._-]+$/", $em) ) {
                    $errors['admin_email'] = "invalid email format - {$em}";
                    break;
                }
            }
        }

        return $errors;
    }

    public function InstallLSWS( $input, &$output )
    {
        $install_cmd =
                WhmMod_LiteSpeed_ControlApp::CGI_DIR . '/install_lsws_cp.sh '
                . escapeshellarg($input['lsws_home_input']) . ' '
                . escapeshellarg($input['serial_no']) . ' '
                . "{$input['port_offset']} "
                . "{$input['php_suexec']} "
                . escapeshellarg($input['admin_login']) . ' '
                . escapeshellarg($input['admin_pass']) . ' '
                . escapeshellarg($input['admin_email']);

        exec($install_cmd, $output, $return_var);

        return $return_var;
    }

    /**
     *
     * @param mixed[]  $info
     * @return string|string[]
     */
    public function Validate_LicenseTransfer( $info )
    {
        $error = '';

        if ( $info['licstatus_return'] != 0 ) {
            $error = 'Current license can no longer be used, not valid for '
                    . 'transfer.';
        }
        else {
            $buf = implode('<br/>', $info['licstatus_output']);

            if ( preg_match('/ -[0-9]+ /', $buf) ) {
                /**
                 * Has been migrated.
                 */
                $error = array();
                $error[] = 'Current license has been transferred. You cannot '
                        . 'transfer this license again!';
                $error[] = 'You can use the same serial number to register a '
                        . 'new license on a new machine.';
                $error[] = 'If you want to reuse the same serial number on '
                        . 'this machine, use the "change license" option with '
                        . 'the same serial number to get a new license key if '
                        . 'it has not been used elsewhere. Otherwise, you will '
                        . 'need to release the serial number before you can '
                        . 'activate it on another machine.';
            }
        }

        return $error;
    }

    public function TransferLicense( &$output )
    {
        $cmd = "{$this->moduleCmd} TRANSFER_LICENSE";
        exec($cmd, $output, $return_var);

        return $return_var;
    }

    /**
     * @param string[]  $info
     * @return string|null
     */
    public function Validate_VersionManage( $info )
    {
        if ( !in_array($info['act'], array( 'download', 'switchTo', 'remove' )) ) {
            return 'Invalid action';
        }

        if ( !preg_match('/^[1-9]+\.[0-9RC\.]+$/', $info['actId']) ) {
            return 'Invalid version';
        }

        return null;
    }

    /**
     *
     * @param string  $act
     * @param string  $actId
     * @return void
     */
    public function VersionManage( $act, $actId )
    {
        $cmd = $this->moduleCmd;

        switch ($act) {
            case 'download':
                /**
                 * '>/dev/null 2>&1' needed since lsws/admin/misc file
                 * 'ap_lsws.sh.in' changed it's restart cmd to
                 * 'service lsws restart' (LSWS 5.2.4+) causing exec() to stall
                 * after/at the end of 'lsws_cmd' script execution. This will
                 * hide (redirect) said output, fixing the issue.
                 */
                $cmd .= " VER_UP {$actId} >/dev/null 2>&1";

                break;
            case 'switchTo':
                $cmd .= " VER_SWITCH {$actId}";

                break;
            case 'remove':
                $cmd .= " VER_DEL {$actId}";

                break;
            default:
                return;
        }

        exec($cmd, $output, $return_var);

        if ( $return_var == 0 ) {
            if ( $act == 'switchTo' ) {
               /**
                * Purposely not used.
                */
                $output2 = array();

                $this->RestartLSWS($output2);
            }

            WhmPluginLogger::uiSuccess('Successfully switched version.');
        }
        else {
            $outputMsg = implode('<br />', $output);

            /**
             * $act must be checked here as 'download' will return 2 when
             * failing to download.
             */
            if ( $act == 'remove' && $return_var == 2 ) {
                $msg = "{$outputMsg}<br /><br />Successfully removed the "
                        . 'selected version';
                WhmPluginLogger::uiSuccess($msg);
            }
            elseif ( $act == 'download' ) {
                WhmPluginLogger::uiError(
                    "Failed to force reinstall LSWS {$actId}");
            }
            else {
                WhmPluginLogger::uiError($outputMsg);
            }
        }
    }

    private function validate_serial_no( $serial )
    {
        $error = '';

        if ( $serial == "" ) {
            $error = 'Missing serial number!';
        }
        else {
            $pattern = '[a-zA-Z0-9/+]{4}';

            $validSerial = "%^{$pattern}-{$pattern}-{$pattern}-{$pattern}$%";

            if ( strlen($serial) != 19 || !preg_match($validSerial, $serial) ) {
                $error = 'Invalid serial number';
            }
        }

        return $error;
    }

    private function validate_port_offset( $port_offset )
    {
        if ( !preg_match('/^[0-9]+$/', $port_offset) ) {
            return 'Invalid number.';
        }

        $port = intval($port_offset);

        if ( $port < 0 || $port > 65535 ) {
            return 'Number out of range (0~65535)';
        }

        return NULL;
    }

    /**
     * Used in install & change license.
     *
     * @param (int|string)[]  $input
     * @return string[]
     */
    private function validate_license_type( $input )
    {
        $errors = NULL;

        if ( $input['license_agree'] != 'agree' ) {
            $errors['license_agree'] =
                'Cannot proceed without agreement to EULA';
        }

        if ( $input['install_type'] == '' ) {
            $errors['install_type'] = 'Please select one';
        }
        elseif ( $input['install_type'] == 'prod' ) {
            $err = $this->validate_serial_no($input['serial_no']);

            if ( $err != NULL ) {
                $errors['serial_no'] = $err;
            }
        }
        elseif ( $input['install_type'] == 'trial' ) {

            if ( $input['serial_no'] != '' ) {
                $errors['serial_no'] =
                    'Cannot select trial license with serial number.';
            }
        }
        else {
            $errors['install_type'] = 'Invalid type';
        }

        return $errors;
    }

    public function Validate_ConfigSuExec( $info )
    {
        $errors = array();
        $val_phpSuExec = $info['new']['phpSuExec'];
        $val_phpSuExecMaxConn = $info['new']['phpSuExecMaxConn'];

        if ( $val_phpSuExec !== '0' && $val_phpSuExec !== '1'
                && $val_phpSuExec !== '2' ) {

            $errors['phpSuExec'] = 'Invalid selection';
        }

        $val_phpSuExecMaxConn = intval($val_phpSuExecMaxConn);

        if ( $val_phpSuExecMaxConn <= 0 ) {
            $errors['phpSuExecMaxConn'] =
                'Need an integer number larger than 0';
        }

        if ( $info['cur']['phpSuExec'] == $val_phpSuExec
                && $info['cur']['phpSuExecMaxConn'] == $val_phpSuExecMaxConn ) {

            WhmPluginLogger::uiError(
                'No fields have been changed. No need to update.');
        }

        return $errors;
    }

    public function ConfigSuExec( $info )
    {
        $contents = file_get_contents($this->serv_conf);

        if ( $contents == FALSE ) {
            WhmPluginLogger::uiError('Failed to read config file.');
            return;
        }

        $pattern = array();
        $replacement = array();

        foreach ( $info['new'] as $key => $val ) {
            $pattern[] = "/<{$key}>(.*?)<\/{$key}>/s";
            $replacement[] = "<{$key}>{$val}</{$key}>";
        }

        $new_contents = preg_replace($pattern, $replacement, $contents, 1);

        if ( $new_contents != NULL ) {
            file_put_contents($this->serv_conf, $new_contents);

            $msg = 'Updated configuration file successfully. Changes to these '
                    . 'settings do not take effect until LiteSpeed Web Server '
                    . 'is restarted.';
            WhmPluginLogger::uiSuccess($msg);
        }
        else {
            WhmPluginLogger::uiError(preg_last_error());
        }
    }

    /**
     * Touches a flag file to inform LiteSpeed Web Server to restart running
     * detached PHP processes the next time the server uses that PHP handler.
     */
    public function restartDetachedPHP()
    {
        $restartPHPFlagFile = LSWS_HOME . '/admin/tmp/.lsphp_restart.txt';

        touch($restartPHPFlagFile);
    }

    /**
     * Recursively a directory's contents and optionally the directory itself.
     *
     * @param string   $dir         Directory path
     * @param boolean  $keepParent  Only remove directory contents when true.
     * @return boolean
     *
     * @noinspection PhpUnused
     */
    public static function rrmdir( $dir, $keepParent = false )
    {
        if ( $dir != '' && is_dir($dir) ) {

            foreach ( glob("{$dir}/*") as $file ) {

                if ( is_dir($file) ) {
                    self::rrmdir($file);
                }
                else {
                    unlink($file);
                }
            }

            if ( !$keepParent ) {
                rmdir($dir);
            }

            return true;
        }

        return false;
    }

    /**
     *
     * @param string  $dir
     * @return false|string
     *
     * @noinspection PhpUnused
     */
    public static function DirectoryMd5( $dir )
    {
        if ( !is_dir($dir) ) {
            return false;
        }

        $filemd5s = array();
        $d = dir($dir);

        while ( ($entry = $d->read()) !== false ) {

            if ( $entry != '.' && $entry != '..' ) {

                $currEntry = "{$dir}/{$entry}";

                if ( is_dir($currEntry) ) {
                    $filemd5s[] = self::DirectoryMd5($currEntry);
                }
                else {
                    $filemd5s[] = md5_file($currEntry);
                }
            }
        }

        $d->close();
        return md5(implode('', $filemd5s));
    }

    /**
     *
     * @since 3.3.4
     * @since 3.3.7  Added param $useOldMethod with a default value of false
     *               for backward compatibility.
     *
     * @param boolean $useOldMethod  Use old method of force updating shared
     *                               code library.
     * @return boolean
     */
    public static function updateSharedCode( $useOldMethod = false )
    {
        $updateCmd = LSWS_HOME . '/admin/misc/lscmctl';
        $updateCmd .= ($useOldMethod) ? ' --update-lib' : ' --force-update-lib';

        exec($updateCmd, $output, $ret);

        return ($ret == 0);
    }

    /**
     *
     * @since 4.1
     *
     * @return string[]
     */
    public static function getQuicCloudIps()
    {
        $ipList = array();

        $content = self::get_url_contents('https://quic.cloud/ips?json');

        if ( $content != '' ) {
            $ipList = json_decode($content, true);
        }

        return $ipList;
    }

    /**
     *
     * @param mixed[]  $ajaxInfo
     *
     * @noinspection PhpUnused
     */
    public static function ajaxReturn( $ajaxInfo )
    {
        echo json_encode($ajaxInfo);
        exit;
    }

    /**
     *
     * @since 4.1.3
     */
    private static function updateLatestWhmPluginVerFile()
    {
        $newVersionFile = self::getLatestWhmPluginVerFilePath();

        $content = self::get_url_contents(
            'https://www.litespeedtech.com/packages/cpanel/WHM_LATEST_VER'
        );

        if ( !empty($content) ) {
            file_put_contents($newVersionFile, trim($content));
        }
        else {
            file_put_contents(
                $newVersionFile,
                WhmMod_LiteSpeed_ControlApp::MODULE_VERSION
            );
        }
    }

    /**
     *
     * @since 4.1.3
     *
     * @return string
     */
    public static function getLatestWhmPluginVer()
    {
        $newVersionFile = self::getLatestWhmPluginVerFilePath();

        if ( !file_exists($newVersionFile)
                || (time() - filemtime($newVersionFile)) > 86400 ) {

            self::updateLatestWhmPluginVerFile();
        }

        return trim(file_get_contents($newVersionFile));
    }

    /**
     * Update current WHM plugin to the latest release version.
     *
     * @since 4.1.3
     */
    public static function updateToLatestWhmPlugin()
    {
        exec(
            WhmMod_LiteSpeed_ControlApp::CGI_DIR
                . '/lsws_whm_plugin_install.sh'
        );

        if ( defined('LSWS_HOME') && LSWS_HOME != '' ) {
            file_put_contents(
                WhmMod_LiteSpeed_ControlApp::CGI_DIR .'/LSWS_HOME.config',
                'LSWS_HOME=' . LSWS_HOME
            );
        }

        WhmPluginLogger::uiSuccess('Plugin updated successfully');
    }

}

Youez - 2016 - github.com/yon3zu
LinuXploit