Initial Commit
This commit is contained in:
84
dependencies/spatie/dns/src/Dns.php
vendored
Normal file
84
dependencies/spatie/dns/src/Dns.php
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\Dns;
|
||||
|
||||
use WP_Ultimo\Dependencies\Spatie\Dns\Exceptions\CouldNotFetchDns;
|
||||
use WP_Ultimo\Dependencies\Spatie\Dns\Exceptions\InvalidArgument;
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\Process\Process;
|
||||
class Dns
|
||||
{
|
||||
protected string $domain = '';
|
||||
protected string $nameserver = '';
|
||||
protected array $recordTypes = ['A', 'AAAA', 'CNAME', 'NS', 'SOA', 'MX', 'SRV', 'TXT', 'DNSKEY', 'CAA', 'NAPTR'];
|
||||
public static function of(string $domain, string $nameserver = '') : self
|
||||
{
|
||||
return new static($domain, $nameserver);
|
||||
}
|
||||
public function __construct(string $domain, string $nameserver = '')
|
||||
{
|
||||
if (empty($domain)) {
|
||||
throw InvalidArgument::domainIsMissing();
|
||||
}
|
||||
$this->nameserver = $nameserver;
|
||||
$this->domain = $this->sanitizeDomainName($domain);
|
||||
}
|
||||
public function useNameserver(string $nameserver)
|
||||
{
|
||||
$this->nameserver = $nameserver;
|
||||
return $this;
|
||||
}
|
||||
public function getDomain() : string
|
||||
{
|
||||
return $this->domain;
|
||||
}
|
||||
public function getNameserver() : string
|
||||
{
|
||||
return $this->nameserver;
|
||||
}
|
||||
public function getRecords(...$types) : string
|
||||
{
|
||||
$types = $this->determineTypes($types);
|
||||
$types = \count($types) ? $types : $this->recordTypes;
|
||||
$dnsRecords = \array_map([$this, 'getRecordsOfType'], $types);
|
||||
return \implode('', \array_filter($dnsRecords));
|
||||
}
|
||||
/**
|
||||
* @throws InvalidArgument
|
||||
*/
|
||||
protected function determineTypes(array $types) : array
|
||||
{
|
||||
$types = \is_array($types[0] ?? null) ? $types[0] : $types;
|
||||
$types = \array_map('strtoupper', $types);
|
||||
if ($invalidTypes = \array_diff($types, $this->recordTypes)) {
|
||||
throw InvalidArgument::filterIsNotAValidRecordType(\reset($invalidTypes), $this->recordTypes);
|
||||
}
|
||||
return $types;
|
||||
}
|
||||
protected function sanitizeDomainName(string $domain) : string
|
||||
{
|
||||
$domain = \str_replace(['http://', 'https://'], '', $domain);
|
||||
$domain = \strtok($domain, '/');
|
||||
return \strtolower($domain);
|
||||
}
|
||||
/**
|
||||
* @throws CouldNotFetchDns
|
||||
*/
|
||||
protected function getRecordsOfType(string $type) : string
|
||||
{
|
||||
$nameserverPart = $this->getSpecificNameserverPart();
|
||||
$command = \array_filter(['dig', '+nocmd', $nameserverPart, $this->domain, $type, '+multiline', '+noall', '+answer', '+noidnout']);
|
||||
$process = new Process($command);
|
||||
$process->run();
|
||||
if (!$process->isSuccessful()) {
|
||||
throw CouldNotFetchDns::digReturnedWithError(\trim($process->getErrorOutput()));
|
||||
}
|
||||
return $process->getOutput();
|
||||
}
|
||||
protected function getSpecificNameserverPart() : ?string
|
||||
{
|
||||
if ($this->nameserver === '') {
|
||||
return null;
|
||||
}
|
||||
return '@' . $this->nameserver;
|
||||
}
|
||||
}
|
11
dependencies/spatie/dns/src/Exceptions/CouldNotFetchDns.php
vendored
Normal file
11
dependencies/spatie/dns/src/Exceptions/CouldNotFetchDns.php
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\Dns\Exceptions;
|
||||
|
||||
class CouldNotFetchDns extends \Exception
|
||||
{
|
||||
public static function digReturnedWithError($output)
|
||||
{
|
||||
return new static("Dig command failed with message: `{$output}`");
|
||||
}
|
||||
}
|
17
dependencies/spatie/dns/src/Exceptions/InvalidArgument.php
vendored
Normal file
17
dependencies/spatie/dns/src/Exceptions/InvalidArgument.php
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\Dns\Exceptions;
|
||||
|
||||
use InvalidArgumentException;
|
||||
class InvalidArgument extends InvalidArgumentException
|
||||
{
|
||||
public static function domainIsMissing()
|
||||
{
|
||||
return new static('A domain name is required');
|
||||
}
|
||||
public static function filterIsNotAValidRecordType($filter, array $validRecordTypes)
|
||||
{
|
||||
$recordTypeString = \implode(', ', $validRecordTypes);
|
||||
return new static("The given filter `{$filter}` is not valid. It should be one of {$recordTypeString}");
|
||||
}
|
||||
}
|
61
dependencies/spatie/macroable/src/Macroable.php
vendored
Normal file
61
dependencies/spatie/macroable/src/Macroable.php
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\Macroable;
|
||||
|
||||
use Closure;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use BadMethodCallException;
|
||||
trait Macroable
|
||||
{
|
||||
protected static $macros = [];
|
||||
/**
|
||||
* Register a custom macro.
|
||||
*
|
||||
* @param string $name
|
||||
* @param object|callable $macro
|
||||
*/
|
||||
public static function macro(string $name, $macro)
|
||||
{
|
||||
static::$macros[$name] = $macro;
|
||||
}
|
||||
/**
|
||||
* Mix another object into the class.
|
||||
*
|
||||
* @param object $mixin
|
||||
*/
|
||||
public static function mixin($mixin)
|
||||
{
|
||||
$methods = (new ReflectionClass($mixin))->getMethods(ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED);
|
||||
foreach ($methods as $method) {
|
||||
$method->setAccessible(\true);
|
||||
static::macro($method->name, $method->invoke($mixin));
|
||||
}
|
||||
}
|
||||
public static function hasMacro(string $name) : bool
|
||||
{
|
||||
return isset(static::$macros[$name]);
|
||||
}
|
||||
public static function __callStatic($method, $parameters)
|
||||
{
|
||||
if (!static::hasMacro($method)) {
|
||||
throw new BadMethodCallException("Method {$method} does not exist.");
|
||||
}
|
||||
$macro = static::$macros[$method];
|
||||
if ($macro instanceof Closure) {
|
||||
return \call_user_func_array(Closure::bind($macro, null, static::class), $parameters);
|
||||
}
|
||||
return \call_user_func_array($macro, $parameters);
|
||||
}
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
if (!static::hasMacro($method)) {
|
||||
throw new BadMethodCallException("Method {$method} does not exist.");
|
||||
}
|
||||
$macro = static::$macros[$method];
|
||||
if ($macro instanceof Closure) {
|
||||
return \call_user_func_array($macro->bindTo($this, static::class), $parameters);
|
||||
}
|
||||
return \call_user_func_array($macro, $parameters);
|
||||
}
|
||||
}
|
132
dependencies/spatie/ssl-certificate/src/Downloader.php
vendored
Normal file
132
dependencies/spatie/ssl-certificate/src/Downloader.php
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\SslCertificate;
|
||||
|
||||
use WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\CouldNotDownloadCertificate;
|
||||
use WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\InvalidIpAddress;
|
||||
class Downloader
|
||||
{
|
||||
/** @var int */
|
||||
protected $port = 443;
|
||||
/** @var string */
|
||||
protected $ipAddress = null;
|
||||
/** @var bool */
|
||||
protected $usingIpAddress = \false;
|
||||
/** @var int */
|
||||
protected $timeout = 30;
|
||||
/** @var bool */
|
||||
protected $enableSni = \true;
|
||||
/** @var bool */
|
||||
protected $capturePeerChain = \false;
|
||||
/** @var array */
|
||||
protected $socketContextOptions = [];
|
||||
/** @var bool */
|
||||
protected $verifyPeer = \true;
|
||||
/** @var bool */
|
||||
protected $verifyPeerName = \true;
|
||||
/** @var int */
|
||||
protected $followLocation = 1;
|
||||
public function usingPort(int $port)
|
||||
{
|
||||
$this->port = $port;
|
||||
return $this;
|
||||
}
|
||||
public function usingSni(bool $sni)
|
||||
{
|
||||
$this->enableSni = $sni;
|
||||
return $this;
|
||||
}
|
||||
public function withSocketContextOptions(array $socketContextOptions)
|
||||
{
|
||||
$this->socketContextOptions = $socketContextOptions;
|
||||
return $this;
|
||||
}
|
||||
public function withFullChain(bool $fullChain)
|
||||
{
|
||||
$this->capturePeerChain = $fullChain;
|
||||
return $this;
|
||||
}
|
||||
public function withVerifyPeer(bool $verifyPeer)
|
||||
{
|
||||
$this->verifyPeer = $verifyPeer;
|
||||
return $this;
|
||||
}
|
||||
public function withVerifyPeerName(bool $verifyPeerName)
|
||||
{
|
||||
$this->verifyPeerName = $verifyPeerName;
|
||||
return $this;
|
||||
}
|
||||
public function setTimeout(int $timeOutInSeconds)
|
||||
{
|
||||
$this->timeout = $timeOutInSeconds;
|
||||
return $this;
|
||||
}
|
||||
public function setFollowLocation(int $followLocation)
|
||||
{
|
||||
$this->followLocation = $followLocation;
|
||||
return $this;
|
||||
}
|
||||
public function fromIpAddress(string $ipAddress)
|
||||
{
|
||||
if (!\filter_var($ipAddress, \FILTER_VALIDATE_IP)) {
|
||||
throw InvalidIpAddress::couldNotValidate($ipAddress);
|
||||
}
|
||||
$this->ipAddress = $ipAddress;
|
||||
$this->usingIpAddress = \true;
|
||||
return $this;
|
||||
}
|
||||
public function getCertificates(string $hostName) : array
|
||||
{
|
||||
$response = $this->fetchCertificates($hostName);
|
||||
$remoteAddress = $response['remoteAddress'];
|
||||
$peerCertificate = $response['options']['ssl']['peer_certificate'];
|
||||
$peerCertificateChain = $response['options']['ssl']['peer_certificate_chain'] ?? [];
|
||||
$fullCertificateChain = \array_merge([$peerCertificate], $peerCertificateChain);
|
||||
$certificates = \array_map(function ($certificate) use($remoteAddress) {
|
||||
$certificateFields = \openssl_x509_parse($certificate);
|
||||
$fingerprint = \openssl_x509_fingerprint($certificate);
|
||||
$fingerprintSha256 = \openssl_x509_fingerprint($certificate, 'sha256');
|
||||
return new SslCertificate($certificateFields, $fingerprint, $fingerprintSha256, $remoteAddress);
|
||||
}, $fullCertificateChain);
|
||||
return \array_unique($certificates);
|
||||
}
|
||||
public function forHost(string $hostName) : SslCertificate
|
||||
{
|
||||
$hostName = (new Url($hostName))->getHostName();
|
||||
$certificates = $this->getCertificates($hostName);
|
||||
return $certificates[0] ?? \false;
|
||||
}
|
||||
public static function downloadCertificateFromUrl(string $url, int $timeout = 30, bool $verifyCertificate = \true) : SslCertificate
|
||||
{
|
||||
return (new static())->setTimeout($timeout)->withVerifyPeer($verifyCertificate)->withVerifyPeerName($verifyCertificate)->forHost($url);
|
||||
}
|
||||
protected function fetchCertificates(string $hostName) : array
|
||||
{
|
||||
$hostName = (new Url($hostName))->getHostName();
|
||||
$sslOptions = ['capture_peer_cert' => \true, 'capture_peer_cert_chain' => $this->capturePeerChain, 'SNI_enabled' => $this->enableSni, 'peer_name' => $hostName, 'verify_peer' => $this->verifyPeer, 'verify_peer_name' => $this->verifyPeerName, 'follow_location' => $this->followLocation];
|
||||
$streamContext = \stream_context_create(['socket' => $this->socketContextOptions, 'ssl' => $sslOptions]);
|
||||
$connectTo = $this->usingIpAddress ? $this->ipAddress : $hostName;
|
||||
$client = @\stream_socket_client("ssl://{$connectTo}:{$this->port}", $errorNumber, $errorDescription, $this->timeout, \STREAM_CLIENT_CONNECT, $streamContext);
|
||||
if (!empty($errorDescription)) {
|
||||
throw $this->buildFailureException($connectTo, $errorDescription);
|
||||
}
|
||||
if (!$client) {
|
||||
$clientErrorMessage = $this->usingIpAddress ? "Could not connect to `{$connectTo}` or it does not have a certificate matching `{$hostName}`." : "Could not connect to `{$connectTo}`.";
|
||||
throw CouldNotDownloadCertificate::unknownError($hostName, $clientErrorMessage);
|
||||
}
|
||||
$response = \stream_context_get_params($client);
|
||||
$response['remoteAddress'] = \stream_socket_get_name($client, \true);
|
||||
\fclose($client);
|
||||
return $response;
|
||||
}
|
||||
protected function buildFailureException(string $hostName, string $errorDescription)
|
||||
{
|
||||
if (\str_contains($errorDescription, 'getaddrinfo failed')) {
|
||||
return CouldNotDownloadCertificate::hostDoesNotExist($hostName);
|
||||
}
|
||||
if (\str_contains($errorDescription, 'error:14090086')) {
|
||||
return CouldNotDownloadCertificate::noCertificateInstalled($hostName);
|
||||
}
|
||||
return CouldNotDownloadCertificate::unknownError($hostName, $errorDescription);
|
||||
}
|
||||
}
|
23
dependencies/spatie/ssl-certificate/src/Exceptions/CouldNotDownloadCertificate.php
vendored
Normal file
23
dependencies/spatie/ssl-certificate/src/Exceptions/CouldNotDownloadCertificate.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\CouldNotDownloadCertificate\HostDoesNotExist;
|
||||
use WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\CouldNotDownloadCertificate\NoCertificateInstalled;
|
||||
use WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\CouldNotDownloadCertificate\UnknownError;
|
||||
class CouldNotDownloadCertificate extends Exception
|
||||
{
|
||||
public static function hostDoesNotExist(string $hostName) : self
|
||||
{
|
||||
return new HostDoesNotExist($hostName);
|
||||
}
|
||||
public static function noCertificateInstalled(string $hostName) : self
|
||||
{
|
||||
return new NoCertificateInstalled($hostName);
|
||||
}
|
||||
public static function unknownError(string $hostName, string $errorMessage) : self
|
||||
{
|
||||
return new UnknownError($hostName, $errorMessage);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\CouldNotDownloadCertificate;
|
||||
|
||||
use WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\CouldNotDownloadCertificate;
|
||||
class HostDoesNotExist extends CouldNotDownloadCertificate
|
||||
{
|
||||
public function __construct(string $hostName)
|
||||
{
|
||||
parent::__construct("The host named `{$hostName}` does not exist.");
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\CouldNotDownloadCertificate;
|
||||
|
||||
use WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\CouldNotDownloadCertificate;
|
||||
class NoCertificateInstalled extends CouldNotDownloadCertificate
|
||||
{
|
||||
public function __construct(string $hostName)
|
||||
{
|
||||
parent::__construct("Could not find a certificate on host named `{$hostName}`.");
|
||||
}
|
||||
}
|
12
dependencies/spatie/ssl-certificate/src/Exceptions/CouldNotDownloadCertificate/UnknownError.php
vendored
Normal file
12
dependencies/spatie/ssl-certificate/src/Exceptions/CouldNotDownloadCertificate/UnknownError.php
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\CouldNotDownloadCertificate;
|
||||
|
||||
use WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\CouldNotDownloadCertificate;
|
||||
class UnknownError extends CouldNotDownloadCertificate
|
||||
{
|
||||
public function __construct(string $hostName, string $errorMessage)
|
||||
{
|
||||
parent::__construct("Could not download certificate for host `{$hostName}` because {$errorMessage}");
|
||||
}
|
||||
}
|
12
dependencies/spatie/ssl-certificate/src/Exceptions/InvalidIpAddress.php
vendored
Normal file
12
dependencies/spatie/ssl-certificate/src/Exceptions/InvalidIpAddress.php
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions;
|
||||
|
||||
use Exception;
|
||||
class InvalidIpAddress extends Exception
|
||||
{
|
||||
public static function couldNotValidate(string $ipAddress) : self
|
||||
{
|
||||
return new static("String `{$ipAddress}` is not a valid IP address.");
|
||||
}
|
||||
}
|
16
dependencies/spatie/ssl-certificate/src/Exceptions/InvalidUrl.php
vendored
Normal file
16
dependencies/spatie/ssl-certificate/src/Exceptions/InvalidUrl.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions;
|
||||
|
||||
use Exception;
|
||||
class InvalidUrl extends Exception
|
||||
{
|
||||
public static function couldNotValidate(string $url) : self
|
||||
{
|
||||
return new static("String `{$url}` is not a valid url.");
|
||||
}
|
||||
public static function couldNotDetermineHost(string $url) : self
|
||||
{
|
||||
return new static("Could not determine host from url `{$url}`.");
|
||||
}
|
||||
}
|
225
dependencies/spatie/ssl-certificate/src/SslCertificate.php
vendored
Normal file
225
dependencies/spatie/ssl-certificate/src/SslCertificate.php
vendored
Normal file
@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\SslCertificate;
|
||||
|
||||
use WP_Ultimo\Dependencies\Carbon\Carbon;
|
||||
use WP_Ultimo\Dependencies\Spatie\Macroable\Macroable;
|
||||
class SslCertificate
|
||||
{
|
||||
use Macroable;
|
||||
/** @var array */
|
||||
protected $rawCertificateFields = [];
|
||||
/** @var string */
|
||||
protected $fingerprint = '';
|
||||
/** @var string */
|
||||
private $fingerprintSha256 = '';
|
||||
/** @var string */
|
||||
private $remoteAddress = '';
|
||||
public static function download() : Downloader
|
||||
{
|
||||
return new Downloader();
|
||||
}
|
||||
public static function createForHostName(string $url, int $timeout = 30, bool $verifyCertificate = \true) : self
|
||||
{
|
||||
return Downloader::downloadCertificateFromUrl($url, $timeout, $verifyCertificate);
|
||||
}
|
||||
public static function createFromFile(string $pathToCertificate) : self
|
||||
{
|
||||
return self::createFromString(\file_get_contents($pathToCertificate));
|
||||
}
|
||||
public static function createFromString(string $certificatePem) : self
|
||||
{
|
||||
$certificateFields = \openssl_x509_parse($certificatePem);
|
||||
$fingerprint = \openssl_x509_fingerprint($certificatePem);
|
||||
$fingerprintSha256 = \openssl_x509_fingerprint($certificatePem, 'sha256');
|
||||
return new self($certificateFields, $fingerprint, $fingerprintSha256);
|
||||
}
|
||||
public function __construct(array $rawCertificateFields, string $fingerprint = '', string $fingerprintSha256 = '', string $remoteAddress = '')
|
||||
{
|
||||
$this->rawCertificateFields = $rawCertificateFields;
|
||||
$this->fingerprint = $fingerprint;
|
||||
$this->fingerprintSha256 = $fingerprintSha256;
|
||||
$this->remoteAddress = $remoteAddress;
|
||||
}
|
||||
public function getRawCertificateFields() : array
|
||||
{
|
||||
return $this->rawCertificateFields;
|
||||
}
|
||||
public function getIssuer() : string
|
||||
{
|
||||
return $this->rawCertificateFields['issuer']['CN'] ?? '';
|
||||
}
|
||||
public function getDomain() : string
|
||||
{
|
||||
if (!\array_key_exists('CN', $this->rawCertificateFields['subject'])) {
|
||||
return '';
|
||||
}
|
||||
if (\is_string($this->rawCertificateFields['subject']['CN'])) {
|
||||
return $this->rawCertificateFields['subject']['CN'];
|
||||
}
|
||||
if (\is_array($this->rawCertificateFields['subject']['CN'])) {
|
||||
return $this->rawCertificateFields['subject']['CN'][0];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
public function getSignatureAlgorithm() : string
|
||||
{
|
||||
return $this->rawCertificateFields['signatureTypeSN'] ?? '';
|
||||
}
|
||||
public function getOrganization() : string
|
||||
{
|
||||
return $this->rawCertificateFields['issuer']['O'] ?? '';
|
||||
}
|
||||
public function getFingerprint() : string
|
||||
{
|
||||
return $this->fingerprint;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFingerprintSha256() : string
|
||||
{
|
||||
return $this->fingerprintSha256;
|
||||
}
|
||||
public function getAdditionalDomains() : array
|
||||
{
|
||||
$additionalDomains = \explode(', ', $this->rawCertificateFields['extensions']['subjectAltName'] ?? '');
|
||||
return \array_map(function (string $domain) {
|
||||
return \str_replace('DNS:', '', $domain);
|
||||
}, $additionalDomains);
|
||||
}
|
||||
public function validFromDate() : Carbon
|
||||
{
|
||||
return Carbon::createFromTimestampUTC($this->rawCertificateFields['validFrom_time_t']);
|
||||
}
|
||||
public function expirationDate() : Carbon
|
||||
{
|
||||
return Carbon::createFromTimestampUTC($this->rawCertificateFields['validTo_time_t']);
|
||||
}
|
||||
public function lifespanInDays() : int
|
||||
{
|
||||
return $this->validFromDate()->diffInDays($this->expirationDate());
|
||||
}
|
||||
public function isExpired() : bool
|
||||
{
|
||||
return $this->expirationDate()->isPast();
|
||||
}
|
||||
public function isValid(string $url = null)
|
||||
{
|
||||
if (!Carbon::now()->between($this->validFromDate(), $this->expirationDate())) {
|
||||
return \false;
|
||||
}
|
||||
if (!empty($url)) {
|
||||
return $this->appliesToUrl($url ?? $this->getDomain());
|
||||
}
|
||||
return \true;
|
||||
}
|
||||
public function isSelfSigned() : bool
|
||||
{
|
||||
return $this->getIssuer() === $this->getDomain();
|
||||
}
|
||||
public function usesSha1Hash() : bool
|
||||
{
|
||||
$certificateFields = $this->getRawCertificateFields();
|
||||
if ($certificateFields['signatureTypeSN'] === 'RSA-SHA1') {
|
||||
return \true;
|
||||
}
|
||||
if ($certificateFields['signatureTypeLN'] === 'sha1WithRSAEncryption') {
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function isValidUntil(Carbon $carbon, string $url = null) : bool
|
||||
{
|
||||
if ($this->expirationDate()->lte($carbon)) {
|
||||
return \false;
|
||||
}
|
||||
return $this->isValid($url);
|
||||
}
|
||||
public function daysUntilExpirationDate() : int
|
||||
{
|
||||
$endDate = $this->expirationDate();
|
||||
$interval = Carbon::now()->diff($endDate);
|
||||
return (int) $interval->format('%r%a');
|
||||
}
|
||||
public function getDomains() : array
|
||||
{
|
||||
$allDomains = $this->getAdditionalDomains();
|
||||
$allDomains[] = $this->getDomain();
|
||||
$uniqueDomains = \array_unique($allDomains);
|
||||
return \array_values(\array_filter($uniqueDomains));
|
||||
}
|
||||
public function appliesToUrl(string $url) : bool
|
||||
{
|
||||
if (\filter_var($url, \FILTER_VALIDATE_IP)) {
|
||||
$host = $url;
|
||||
} else {
|
||||
$host = (new Url($url))->getHostName();
|
||||
}
|
||||
$certificateHosts = $this->getDomains();
|
||||
foreach ($certificateHosts as $certificateHost) {
|
||||
$certificateHost = \str_replace('ip address:', '', \strtolower($certificateHost));
|
||||
if ($host === $certificateHost) {
|
||||
return \true;
|
||||
}
|
||||
if ($this->wildcardHostCoversHost($certificateHost, $host)) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
protected function wildcardHostCoversHost(string $wildcardHost, string $host) : bool
|
||||
{
|
||||
if ($host === $wildcardHost) {
|
||||
return \true;
|
||||
}
|
||||
if (!starts_with($wildcardHost, '*')) {
|
||||
return \false;
|
||||
}
|
||||
if (\substr_count($wildcardHost, '.') < \substr_count($host, '.')) {
|
||||
return \false;
|
||||
}
|
||||
$wildcardHostWithoutWildcard = \substr($wildcardHost, 1);
|
||||
$hostWithDottedPrefix = ".{$host}";
|
||||
return ends_with($hostWithDottedPrefix, $wildcardHostWithoutWildcard);
|
||||
}
|
||||
public function getRawCertificateFieldsJson() : string
|
||||
{
|
||||
return \json_encode($this->getRawCertificateFields());
|
||||
}
|
||||
public function getHash() : string
|
||||
{
|
||||
return \md5($this->getRawCertificateFieldsJson());
|
||||
}
|
||||
public function getRemoteAddress() : string
|
||||
{
|
||||
return $this->remoteAddress;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return $this->getRawCertificateFieldsJson();
|
||||
}
|
||||
public function containsDomain(string $domain) : bool
|
||||
{
|
||||
$certificateHosts = $this->getDomains();
|
||||
foreach ($certificateHosts as $certificateHost) {
|
||||
if ($certificateHost == $domain) {
|
||||
return \true;
|
||||
}
|
||||
if (ends_with($domain, '.' . $certificateHost)) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function isPreCertificate() : bool
|
||||
{
|
||||
if (!\array_key_exists('extensions', $this->rawCertificateFields)) {
|
||||
return \false;
|
||||
}
|
||||
if (!\array_key_exists('ct_precert_poison', $this->rawCertificateFields['extensions'])) {
|
||||
return \false;
|
||||
}
|
||||
return \true;
|
||||
}
|
||||
}
|
37
dependencies/spatie/ssl-certificate/src/Url.php
vendored
Normal file
37
dependencies/spatie/ssl-certificate/src/Url.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\SslCertificate;
|
||||
|
||||
use WP_Ultimo\Dependencies\Spatie\SslCertificate\Exceptions\InvalidUrl;
|
||||
class Url
|
||||
{
|
||||
/** @var string */
|
||||
protected $url;
|
||||
/** @var array */
|
||||
protected $parsedUrl;
|
||||
public function __construct(string $url)
|
||||
{
|
||||
if (!starts_with($url, ['http://', 'https://', 'ssl://'])) {
|
||||
$url = "https://{$url}";
|
||||
}
|
||||
if (\function_exists('idn_to_ascii') && \strlen($url) < 61) {
|
||||
$url = \idn_to_ascii($url, \false, \INTL_IDNA_VARIANT_UTS46);
|
||||
}
|
||||
if (!\filter_var($url, \FILTER_VALIDATE_URL)) {
|
||||
throw InvalidUrl::couldNotValidate($url);
|
||||
}
|
||||
$this->url = $url;
|
||||
$this->parsedUrl = \parse_url($url);
|
||||
if (!isset($this->parsedUrl['host'])) {
|
||||
throw InvalidUrl::couldNotDetermineHost($this->url);
|
||||
}
|
||||
}
|
||||
public function getHostName() : string
|
||||
{
|
||||
return $this->parsedUrl['host'];
|
||||
}
|
||||
public function getPort() : int
|
||||
{
|
||||
return $this->parsedUrl['port'] ?? 443;
|
||||
}
|
||||
}
|
71
dependencies/spatie/ssl-certificate/src/helpers.php
vendored
Normal file
71
dependencies/spatie/ssl-certificate/src/helpers.php
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Spatie\SslCertificate;
|
||||
|
||||
function starts_with($haystack, $needles) : bool
|
||||
{
|
||||
foreach ((array) $needles as $needle) {
|
||||
if ($needle != '' && \mb_strpos($haystack, $needle) === 0) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
/**
|
||||
* Determine if a given string ends with a given substring.
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string|array $needles
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function ends_with(string $haystack, $needles) : bool
|
||||
{
|
||||
foreach ((array) $needles as $needle) {
|
||||
if ((string) $needle === \substr($haystack, -length($needle))) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
/**
|
||||
* Returns the portion of string specified by the start and length parameters.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $start
|
||||
* @param int|null $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function substr(string $string, int $start, int $length = null) : string
|
||||
{
|
||||
return \mb_substr($string, $start, $length, 'UTF-8');
|
||||
}
|
||||
/**
|
||||
* Return the length of the given string.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function length(string $value) : int
|
||||
{
|
||||
return \mb_strlen($value);
|
||||
}
|
||||
/**
|
||||
* Determine if a given string contains a given substring.
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string|array $needles
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function str_contains(string $haystack, $needles) : bool
|
||||
{
|
||||
foreach ((array) $needles as $needle) {
|
||||
if ($needle != '' && \mb_strpos($haystack, $needle) !== \false) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
Reference in New Issue
Block a user