<?php
							 | 
						|
								
							 | 
						|
								namespace App\Helpers;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 *  hande nginx vhosts
							 | 
						|
								 *
							 | 
						|
								 *  @author Björn Hase, Tentakelfabrik
							 | 
						|
								 *  @license http://opensource.org/licenses/MIT The MIT License
							 | 
						|
								 *  @link https://gitea.tentakelfabrik.de/Tentakelfabrik/mcp
							 | 
						|
								 *
							 | 
						|
								 */
							 | 
						|
								class NginxVhostHelper
							 | 
						|
								{
							 | 
						|
								    // path for available files
							 | 
						|
								    const SITES_AVAILABLE = '/etc/nginx/sites-available';
							 | 
						|
								
							 | 
						|
								    // path for enabled files
							 | 
						|
								    const SITES_ENABLED = '/etc/nginx/sites-enabled';
							 | 
						|
								
							 | 
						|
								    // regex to get files for
							 | 
						|
								    const REGEX_SSL_CERTIFICATE = '/\bssl_certificate\s+\K\S+/';
							 | 
						|
								    const REGEX_SSL_CERTIFICATE_KEY = '/\bssl_certificate_key\s+\K\S+/';
							 | 
						|
								
							 | 
						|
								    // ignore files
							 | 
						|
								    const IGNORE_FILES = [
							 | 
						|
								        '.', '..'
							 | 
						|
								    ];
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *  get sites that are in sites-available
							 | 
						|
								     *
							 | 
						|
								     *
							 | 
						|
								     *  @return array
							 | 
						|
								     *
							 | 
						|
								     */
							 | 
						|
								    private function getSitesAvailable()
							 | 
						|
								    {
							 | 
						|
								        return scandir(self::SITES_AVAILABLE);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *  get sites that are in sites-enabled
							 | 
						|
								     *
							 | 
						|
								     *
							 | 
						|
								     *  @return array
							 | 
						|
								     *
							 | 
						|
								     */
							 | 
						|
								    private function getSitesEnabled()
							 | 
						|
								    {
							 | 
						|
								        return scandir(self::SITES_ENABLED);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *  find path for certificates in .conf-files
							 | 
						|
								     *
							 | 
						|
								     *
							 | 
						|
								     *  ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
							 | 
						|
								     *  ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
							 | 
						|
								     *
							 | 
						|
								     *  @param  string $filename
							 | 
						|
								     *
							 | 
						|
								     */
							 | 
						|
								    private function getCertificate($path)
							 | 
						|
								    {
							 | 
						|
								        $result = [
							 | 
						|
								            'ssl' => false,
							 | 
						|
								            'ssl_certificate_exists' => false,
							 | 
						|
								            'ssl_certificate_expired_at' => false
							 | 
						|
								        ];
							 | 
						|
								
							 | 
						|
								        // getting .conf-file
							 | 
						|
								        $content = file_get_contents($path);
							 | 
						|
								
							 | 
						|
								        // check for path of sites
							 | 
						|
								        preg_match(self::REGEX_SSL_CERTIFICATE, $content, $certificates);
							 | 
						|
								        $matches = array_merge([], $certificates);
							 | 
						|
								
							 | 
						|
								        preg_match(self::REGEX_SSL_CERTIFICATE_KEY, $content, $certificates);
							 | 
						|
								        $matches = array_merge($matches, $certificates);
							 | 
						|
								
							 | 
						|
								        // check ssl certificates
							 | 
						|
								        if (count($matches) >= 2) {
							 | 
						|
								            $result['ssl'] = true;
							 | 
						|
								
							 | 
						|
								            // @TODO find a regex that ignore the ";"
							 | 
						|
								            foreach($matches as $index => $match) {
							 | 
						|
								                $matches[$index] = str_replace(';', '', $match);
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            if (file_exists($matches[0]) && file_exists($matches[1])) {
							 | 
						|
								                $result['ssl_certificate_exists'] = true;
							 | 
						|
								
							 | 
						|
								                // getting expired
							 | 
						|
								                exec('openssl x509 -noout -dates -in '.$matches[0], $openssl);
							 | 
						|
								
							 | 
						|
								                if (isset($openssl[1])) {
							 | 
						|
								                    $result['ssl_certificate_expired_at'] = str_replace('notAfter=', '', $openssl[1]);
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        return $result;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *
							 | 
						|
								     *  @return
							 | 
						|
								     */
							 | 
						|
								    private function getRedirect($path, $domain)
							 | 
						|
								    {
							 | 
						|
								        // getting .conf-file
							 | 
						|
								        $content = file_get_contents($path);
							 | 
						|
								
							 | 
						|
								        // result
							 | 
						|
								        $result = false;
							 | 
						|
								
							 | 
						|
								        preg_match('/server_name www.'.$domain.'/', $content, $matches);
							 | 
						|
								
							 | 
						|
								        if (count($matches) > 0) {
							 | 
						|
								            $result = true;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        return $result;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *  get vhost
							 | 
						|
								     *
							 | 
						|
								     *  @param  string $filename
							 | 
						|
								     *  @param  array $enabled
							 | 
						|
								     *  @return array
							 | 
						|
								     */
							 | 
						|
								    private function getVhost($filename, $enabled)
							 | 
						|
								    {
							 | 
						|
								        // getting full path
							 | 
						|
								        $path = self::SITES_AVAILABLE.'/'.$filename;
							 | 
						|
								
							 | 
						|
								        // getting certificates from a configuration
							 | 
						|
								        $certificate = $this->getCertificate($path);
							 | 
						|
								
							 | 
						|
								        // domain
							 | 
						|
								        $domain = str_replace('.conf', '', $filename);
							 | 
						|
								
							 | 
						|
								        $result = array_merge([
							 | 
						|
								            'domain' => $domain,
							 | 
						|
								            'path' => $path,
							 | 
						|
								            'file' => $filename,
							 | 
						|
								            'redirect_www' => $this->getRedirect($path, $domain),
							 | 
						|
								            'enabled' => in_array($filename, $enabled),
							 | 
						|
								        ], $certificate);
							 | 
						|
								
							 | 
						|
								        return $result;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *  find single vhost by filename
							 | 
						|
								     *
							 | 
						|
								     *  @param  string $filename
							 | 
						|
								     *  @return array
							 | 
						|
								     */
							 | 
						|
								    public function findOneByFilename($filename)
							 | 
						|
								    {
							 | 
						|
								        // getting enabled
							 | 
						|
								        $enabled = $this->getSitesEnabled();
							 | 
						|
								        return $this->getVhost($filename, $enabled);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *  find all vhost
							 | 
						|
								     *
							 | 
						|
								     *  @return array
							 | 
						|
								     */
							 | 
						|
								    public function find()
							 | 
						|
								    {
							 | 
						|
								        $results = [];
							 | 
						|
								
							 | 
						|
								        // getting available
							 | 
						|
								        $available = $this->getSitesAvailable();
							 | 
						|
								
							 | 
						|
								        // getting enabled
							 | 
						|
								        $enabled = $this->getSitesEnabled();
							 | 
						|
								
							 | 
						|
								        foreach($available as $filename)
							 | 
						|
								        {
							 | 
						|
								            if (!in_array($filename, self::IGNORE_FILES)) {
							 | 
						|
								                $results[] = $this->getVhost($filename, $enabled);
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        return $results;
							 | 
						|
								    }
							 | 
						|
								}
							 |