Sindbad~EG File Manager

Current Path : /proc/self/root/proc/self/root/proc/self/root/opt/nginxhttpd_/src/Command/
Upload File :
Current File : //proc/self/root/proc/self/root/proc/self/root/opt/nginxhttpd_/src/Command/IpxtenderSslChecker.php

<?php

namespace App\Command;

use Doctrine\ORM\EntityManagerInterface;
use GuzzleHttp\Client;
use O2switch\CpanelLib\Client\NginxVarnish;
use O2switch\CpanelLib\DataEntity\ApiVhost;
use O2switch\CpanelLib\DataEntity\NginxVarnishConfig;
use O2switch\CpanelLib\Entity\Customization;
use O2switch\CpanelLib\Entity\WafCustomization;
use O2switch\CpanelLib\Helper\ConfigHelper;
use O2switch\CpanelLib\Helper\ProxyInfo;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class IpxtenderSslChecker extends BaseCommand
{
    /** @var EntityManagerInterface */
    private $em;

    protected static $defaultName = 'ipxtender:ssl-checker';


    protected function configure(){
        $this
            ->setDescription("Check for SSL certificates that are not up to date on ipxtender based on the local databases and SSL files.")
            ->setHelp("This command will loop over all local customization and check on ipxtender that the SSL is up-to-date. If not it will try to reinstall the certificate from the local file.")
            ->addOption('reinstall', null, InputOption::VALUE_OPTIONAL, "Set to 1 to try forcing reinstallating the domain on ipxtender to update the SSL", "0");
        ;

    }

    protected function execute(InputInterface $input, OutputInterface $output){
        $reinstall = $input->getOption('reinstall') === 1 || $input->getOption('reinstall') === '1'
            ? true
            : false;

        if($reinstall){
            if(file_exists('/usr/local/cpanel/share/o2switch-xtrem-cache/o2switch-xtrem-cache-code/config/prod.php')){
                $tmp = include '/usr/local/cpanel/share/o2switch-xtrem-cache/o2switch-xtrem-cache-code/config/prod.php';
                $ipxtenderConfig = $conf;
                $configHelper = new ConfigHelper($ipxtenderConfig);
                unset($conf, $tmp, $dbParams, $cmsRules, $ieOnFr, $plOnFr, $deOnFr, $nlOnFr, $ltOnFr, $czOnFr, $ptOnFr, $itOnFr,
                    $frOnFr, $beOnFr, $beOnFr, $esOnFr, $fiOnFr, $ukOnFr, $ipxtenderConfig);
                $apiClient = new NginxVarnish(new Client(), $this->log);
            } else {
                $output->writeln(sprintf('<error>Cant use the reinstall option because the o2switch-xtrem-cache file is not accessible.</error>'));
                return Command::FAILURE;
            }
        }

        $customizations = $this->em->getRepository(Customization::class)->findAll();

        if(!$this->apacheHttpdParser->parse($this->apacheHttpdConf)){
            $output->writeln(sprintf('<error>Cant parse the httpd.conf !</error>'));
            return Command::FAILURE;
        }

        $httpdData = $this->apacheHttpdParser->getData();

        /**
         * @var Customization $c
         */
        foreach($customizations as $c){
            if(!isset($c->getChains()[0]) || !is_string($c->getChains()[0]->getServerIp())){
                $output->writeln(sprintf('<comment>Ignoring %s, cant retrieve the IP</comment>', $c->getMainDomain()));
                continue;
            }

            if(!isset($httpdData[$c->getMainDomain()]['sslCertificateFilepath'])){
                $output->writeln(sprintf('<comment>Ignoring %s, domain is not on the httpd.conf, probably deleted.</comment>', $c->getMainDomain()));
                continue;
            }

            $info = $httpdData[$c->getMainDomain()];
            if(empty($info['sslCertificateFilepath'])){
                $output->writeln(sprintf('<comment>Ignoring %s, dont have a SSL installed.</comment>', $c->getMainDomain()));
                continue;
            }

            $sslPath = $info['sslCertificateFilepath'];
            if(!file_exists($sslPath)){
                $output->writeln(sprintf('<comment>Ignoring %s %s dont exists</comment>', $c->getMainDomain(), $sslPath));
                continue;
            }

            $cert = file_get_contents($sslPath);
            if($cert === false){
                $output->writeln(sprintf('<comment>Ignoring %s, cant open the SSL file %s</comment>', $c->getMainDomain(), $sslPath));
                continue;
            }

            $cert = openssl_x509_parse($cert);
            if($cert === false || !isset($cert['serialNumber'])){
                $output->writeln(sprintf('<comment>Ignoring %s, cant parse the SSL file %s to retrieve the serialNumber</comment>', $c->getMainDomain(), $sslPath));
                continue;
            }

            $ip = $c->getChains()[0]->getServerIp();
            $domain = $c->getMainDomain();

            $g = stream_context_create ([
                "http" => [
                    'method' => 'HEAD'
                ],
                'header' => [
                    'host' => $domain,
                ],
                "ssl" => [
                    "capture_peer_cert" => true,
                    'SNI_enabled' => true,
                    'SNI_server_name' => $domain,
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                    'allow_self_signed' => true,
                    'CN_match' => $domain,
                    'disable_compression' => true,
                    "peer_name" => $domain
                ]
            ]);

            try {
                $r = stream_socket_client("ssl://$ip:443", $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $g);
                if($r === false){
                    throw new \Exception("stream_socket_client() returned false");
                }
                $params = stream_context_get_params($r);
                fclose($r);
            } catch (\Exception $e){
                $output->writeln(sprintf('<comment>Ignoring %s, exception received %s</comment>', $c->getMainDomain(), $e->getMessage()));
                continue;
            }

            if(!isset($params["options"]["ssl"]["peer_certificate"])){
                $output->writeln(sprintf('<comment>Ignoring %s, cant retrieve SSL details</comment>', $c->getMainDomain()));
                continue;
            }

            $installedCert = openssl_x509_parse($params["options"]["ssl"]["peer_certificate"]);
            if($installedCert === false || !isset($installedCert['serialNumber'])){
                $output->writeln(sprintf('<comment>Ignoring %s, cant parse the remote SSL to retrieve the serialNumber</comment>', $c->getMainDomain()));
                continue;
            }


            if($installedCert['serialNumber'] === $cert['serialNumber']){
                $output->writeln(sprintf('<info>%s seems OK. Expected %s == %s</info>', $c->getMainDomain(), $cert['serialNumber'], $installedCert['serialNumber']));
                continue;
            }

            $output->writeln(sprintf('<comment>%s seems to have a fucked SSL certificate. Expected %s != %s</comment>', $c->getMainDomain(), $cert['serialNumber'], $installedCert['serialNumber']));

            usleep(1000000);
            if(!$reinstall){
                continue;
            }

            continue;
            // TODO

            $apiVhost = (new ApiVhost())
                ->setSslKeyFile($this->data['data']['args']['key'] ?? null)
                ->setSslCrtFile($this->data['data']['args']['cert'] ?? null)
                ->setSslCaBundleFile(!empty($this->data['data']['args']['cabundle'] ?? null) ? $this->data['data']['args']['cabundle'] : null)
                ->setMainDomain($c->getMainDomain())
                ->setCpUser($c->getCpUser())
                ->setTemplateName('default')
                ->setAdditionalsParams($c->getAdditionalData())
                ->setDomainAliases('www.' . $c->getMainDomain())
                ->setIsSslAvailable(true)
                ->setOriginalBackendIp($c->getOriginalBackendIP())
                ->setListenToIp($c->getChains()[0]->getServerIp())
                ->setListenToPort(ProxyInfo::getIpxtenderProxyPassInfo($c, 'listenToPort'))
                ->setListenToSslPort(ProxyInfo::getIpxtenderProxyPassInfo($c, 'listenToSslPort'))
                ->setProxyPassIp(ProxyInfo::getIpxtenderProxyPassInfo($c, 'proxyPassIp'))
                ->setProxyPassPort(ProxyInfo::getIpxtenderProxyPassInfo($c, 'proxyPassPort'))
                ->setProxyPassProtocol(ProxyInfo::getIpxtenderProxyPassInfo($c, 'proxyPassProtocol'))
                ->setProxyPassSslIp(ProxyInfo::getIpxtenderProxyPassInfo($c, 'proxyPassSslIp'))
                ->setProxyPassSslPort(ProxyInfo::getIpxtenderProxyPassInfo($c, 'proxyPassSslPort'))
                ->setProxyPassSslProtocol(ProxyInfo::getIpxtenderProxyPassInfo($c, 'proxyPassSslProtocol'))
            ;

            $wafCustomization = $this->em->getRepository(WafCustomization::class)->findOneBy([
                'domain' => $domain,
                'cpUser' => $c->getCpUser()
            ]);

            if($wafCustomization instanceof WafCustomization){
                $apiVhost->setAdditionalsParams(
                    is_array($apiVhost->getAdditionalsParams())
                        ? array_merge($apiVhost->getAdditionalsParams(), ['wafCustomization' => $wafCustomization->getRules()])
                        : ['wafCustomization' => $wafCustomization->getRules()]
                );
            }

            $serverId = $configHelper->getServerNameByIp($ip);
            $nginxVarnishConfig = (new NginxVarnishConfig())
                ->setServerIp($configHelper->getServerMainIp($serverId))
                ->setPort($configHelper->getServerPort($serverId, 'nginx'))
                ->setToken($configHelper->getServerToken($serverId))
                ->setAlgo($configHelper->getServerAlgo($serverId))
                ->setSecretHash($configHelper->getServerSecret($serverId))
            ;

            try {
                $apiClient
                    ->setConfig($nginxVarnishConfig)
                    ->configureVhost('nginx', $apiVhost);
            } catch (\Exception $e){
                $output->writeln(sprintf('<comment>%s reinstalled on ipxtender</comment>', $domain));
                continue;
            }

            $output->writeln(sprintf('<info>%s reinstalled on ipxtender', $domain));
        }
        return Command::SUCCESS;
    }

    /**
     * @param string $cert
     * @return null[]|string[]
     */
    private function splitCombinedCertificates(string $cert) : array {
        $key = null;
        $crt = null;
        $cabundle = null;
        $i = 0;
        foreach(explode("\n", $cert) as $line){
            if (strpos($line, 'BEGIN RSA PRIVATE KEY') !== false) {
                $mode = 'key';
            } elseif (strpos($line, 'BEGIN CERTIFICATE') !== false) {
                $mode = 'crt';
                $i++;
            }

            if($mode === 'key'){
                $key .= "$line\n";
            } elseif ($mode === 'crt') {
                if($i === 1){
                    $crt .= "$line\n";
                } else {
                    $cabundle .= "$line\n";
                }
            }
        }
        return [$key, $crt, $cabundle];
    }
    /**
     * @required
     */
    public function setEm(EntityManagerInterface $em): void
    {
        $this->em = $em;
    }
}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists