installed plugin W3 Total Cache
version 2.3.2
This commit is contained in:
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\Sns\Exception;
|
||||
|
||||
/**
|
||||
* Runtime exception thrown by the SNS Message Validator.
|
||||
*/
|
||||
class InvalidSnsMessageException extends \RuntimeException
|
||||
{
|
||||
}
|
161
wp-content/plugins/w3-total-cache/vendor/aws/aws-php-sns-message-validator/src/Message.php
vendored
Normal file
161
wp-content/plugins/w3-total-cache/vendor/aws/aws-php-sns-message-validator/src/Message.php
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
namespace Aws\Sns;
|
||||
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Represents an SNS message received over http(s).
|
||||
*/
|
||||
class Message implements \ArrayAccess, \IteratorAggregate
|
||||
{
|
||||
private static $requiredKeys = [
|
||||
'Message',
|
||||
'MessageId',
|
||||
'Timestamp',
|
||||
'TopicArn',
|
||||
'Type',
|
||||
'Signature',
|
||||
['SigningCertURL', 'SigningCertUrl'],
|
||||
'SignatureVersion',
|
||||
];
|
||||
|
||||
private static $subscribeKeys = [
|
||||
['SubscribeURL', 'SubscribeUrl'],
|
||||
'Token'
|
||||
];
|
||||
|
||||
/** @var array The message data */
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* Creates a Message object from the raw POST data
|
||||
*
|
||||
* @return Message
|
||||
* @throws \RuntimeException If the POST data is absent, or not a valid JSON document
|
||||
*/
|
||||
public static function fromRawPostData()
|
||||
{
|
||||
// Make sure the SNS-provided header exists.
|
||||
if (!isset($_SERVER['HTTP_X_AMZ_SNS_MESSAGE_TYPE'])) {
|
||||
throw new \RuntimeException('SNS message type header not provided.');
|
||||
}
|
||||
|
||||
// Read the raw POST data and JSON-decode it into a message.
|
||||
return self::fromJsonString(file_get_contents('php://input'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Message object from a PSR-7 Request or ServerRequest object.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @return Message
|
||||
*/
|
||||
public static function fromPsrRequest(RequestInterface $request)
|
||||
{
|
||||
return self::fromJsonString($request->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Message object from a JSON-decodable string.
|
||||
*
|
||||
* @param string $requestBody
|
||||
* @return Message
|
||||
*/
|
||||
public static function fromJsonString($requestBody)
|
||||
{
|
||||
$data = json_decode($requestBody, true);
|
||||
if (JSON_ERROR_NONE !== json_last_error() || !is_array($data)) {
|
||||
throw new \RuntimeException('Invalid POST data.');
|
||||
}
|
||||
|
||||
return new Message($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Message object from an array of raw message data.
|
||||
*
|
||||
* @param array $data The message data.
|
||||
*
|
||||
* @throws \InvalidArgumentException If a valid type is not provided or
|
||||
* there are other required keys missing.
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
// Ensure that all the required keys for the message's type are present.
|
||||
$this->validateRequiredKeys($data, self::$requiredKeys);
|
||||
if ($data['Type'] === 'SubscriptionConfirmation'
|
||||
|| $data['Type'] === 'UnsubscribeConfirmation'
|
||||
) {
|
||||
$this->validateRequiredKeys($data, self::$subscribeKeys);
|
||||
}
|
||||
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->data);
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($key)
|
||||
{
|
||||
return isset($this->data[$key]);
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($key)
|
||||
{
|
||||
return isset($this->data[$key]) ? $this->data[$key] : null;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($key, $value)
|
||||
{
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($key)
|
||||
{
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the message data as a plain array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
private function validateRequiredKeys(array $data, array $keys)
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
$keyIsArray = is_array($key);
|
||||
if (!$keyIsArray) {
|
||||
$found = isset($data[$key]);
|
||||
} else {
|
||||
$found = false;
|
||||
foreach ($key as $keyOption) {
|
||||
if (isset($data[$keyOption])) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
if ($keyIsArray) {
|
||||
$key = $key[0];
|
||||
}
|
||||
throw new \InvalidArgumentException(
|
||||
"\"{$key}\" is required to verify the SNS Message."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
195
wp-content/plugins/w3-total-cache/vendor/aws/aws-php-sns-message-validator/src/MessageValidator.php
vendored
Normal file
195
wp-content/plugins/w3-total-cache/vendor/aws/aws-php-sns-message-validator/src/MessageValidator.php
vendored
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
namespace Aws\Sns;
|
||||
|
||||
use Aws\Sns\Exception\InvalidSnsMessageException;
|
||||
|
||||
/**
|
||||
* Uses openssl to verify SNS messages to ensure that they were sent by AWS.
|
||||
*/
|
||||
class MessageValidator
|
||||
{
|
||||
const SIGNATURE_VERSION_1 = '1';
|
||||
const SIGNATURE_VERSION_2 = '2';
|
||||
|
||||
/**
|
||||
* @var callable Callable used to download the certificate content.
|
||||
*/
|
||||
private $certClient;
|
||||
|
||||
/** @var string */
|
||||
private $hostPattern;
|
||||
|
||||
/**
|
||||
* @var string A pattern that will match all regional SNS endpoints, e.g.:
|
||||
* - sns.<region>.amazonaws.com (AWS)
|
||||
* - sns.us-gov-west-1.amazonaws.com (AWS GovCloud)
|
||||
* - sns.cn-north-1.amazonaws.com.cn (AWS China)
|
||||
*/
|
||||
private static $defaultHostPattern
|
||||
= '/^sns\.[a-zA-Z0-9\-]{3,}\.amazonaws\.com(\.cn)?$/';
|
||||
|
||||
private static function isLambdaStyle(Message $message)
|
||||
{
|
||||
return isset($message['SigningCertUrl']);
|
||||
}
|
||||
|
||||
private static function convertLambdaMessage(Message $lambdaMessage)
|
||||
{
|
||||
$keyReplacements = [
|
||||
'SigningCertUrl' => 'SigningCertURL',
|
||||
'SubscribeUrl' => 'SubscribeURL',
|
||||
'UnsubscribeUrl' => 'UnsubscribeURL',
|
||||
];
|
||||
|
||||
$message = clone $lambdaMessage;
|
||||
foreach ($keyReplacements as $lambdaKey => $canonicalKey) {
|
||||
if (isset($message[$lambdaKey])) {
|
||||
$message[$canonicalKey] = $message[$lambdaKey];
|
||||
unset($message[$lambdaKey]);
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the Message Validator object and ensures that openssl is
|
||||
* installed.
|
||||
*
|
||||
* @param callable $certClient Callable used to download the certificate.
|
||||
* Should have the following function signature:
|
||||
* `function (string $certUrl) : string|false $certContent`
|
||||
* @param string $hostNamePattern
|
||||
*/
|
||||
public function __construct(
|
||||
callable $certClient = null,
|
||||
$hostNamePattern = ''
|
||||
) {
|
||||
$this->certClient = $certClient ?: function($certUrl) {
|
||||
return @ file_get_contents($certUrl);
|
||||
};
|
||||
$this->hostPattern = $hostNamePattern ?: self::$defaultHostPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a message from SNS to ensure that it was delivered by AWS.
|
||||
*
|
||||
* @param Message $message Message to validate.
|
||||
*
|
||||
* @throws InvalidSnsMessageException If the cert cannot be retrieved or its
|
||||
* source verified, or the message
|
||||
* signature is invalid.
|
||||
*/
|
||||
public function validate(Message $message)
|
||||
{
|
||||
if (self::isLambdaStyle($message)) {
|
||||
$message = self::convertLambdaMessage($message);
|
||||
}
|
||||
|
||||
// Get the certificate.
|
||||
$this->validateUrl($message['SigningCertURL']);
|
||||
$certificate = call_user_func($this->certClient, $message['SigningCertURL']);
|
||||
if ($certificate === false) {
|
||||
throw new InvalidSnsMessageException(
|
||||
"Cannot get the certificate from \"{$message['SigningCertURL']}\"."
|
||||
);
|
||||
}
|
||||
|
||||
// Extract the public key.
|
||||
$key = openssl_get_publickey($certificate);
|
||||
if (!$key) {
|
||||
throw new InvalidSnsMessageException(
|
||||
'Cannot get the public key from the certificate.'
|
||||
);
|
||||
}
|
||||
|
||||
// Verify the signature of the message.
|
||||
$content = $this->getStringToSign($message);
|
||||
$signature = base64_decode($message['Signature']);
|
||||
$algo = ($message['SignatureVersion'] === self::SIGNATURE_VERSION_1 ? OPENSSL_ALGO_SHA1 : OPENSSL_ALGO_SHA256);
|
||||
if (openssl_verify($content, $signature, $key, $algo) !== 1) {
|
||||
throw new InvalidSnsMessageException(
|
||||
'The message signature is invalid.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a message is valid and that is was delivered by AWS. This
|
||||
* method does not throw exceptions and returns a simple boolean value.
|
||||
*
|
||||
* @param Message $message The message to validate
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid(Message $message)
|
||||
{
|
||||
try {
|
||||
$this->validate($message);
|
||||
return true;
|
||||
} catch (InvalidSnsMessageException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds string-to-sign according to the SNS message spec.
|
||||
*
|
||||
* @param Message $message Message for which to build the string-to-sign.
|
||||
*
|
||||
* @return string
|
||||
* @link http://docs.aws.amazon.com/sns/latest/gsg/SendMessageToHttp.verify.signature.html
|
||||
*/
|
||||
public function getStringToSign(Message $message)
|
||||
{
|
||||
static $signableKeys = [
|
||||
'Message',
|
||||
'MessageId',
|
||||
'Subject',
|
||||
'SubscribeURL',
|
||||
'Timestamp',
|
||||
'Token',
|
||||
'TopicArn',
|
||||
'Type',
|
||||
];
|
||||
|
||||
if ($message['SignatureVersion'] !== self::SIGNATURE_VERSION_1
|
||||
&& $message['SignatureVersion'] !== self::SIGNATURE_VERSION_2) {
|
||||
throw new InvalidSnsMessageException(
|
||||
"The SignatureVersion \"{$message['SignatureVersion']}\" is not supported."
|
||||
);
|
||||
}
|
||||
|
||||
$stringToSign = '';
|
||||
foreach ($signableKeys as $key) {
|
||||
if (isset($message[$key])) {
|
||||
$stringToSign .= "{$key}\n{$message[$key]}\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $stringToSign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the URL of the certificate is one belonging to AWS, and not
|
||||
* just something from the amazonaws domain, which could include S3 buckets.
|
||||
*
|
||||
* @param string $url Certificate URL
|
||||
*
|
||||
* @throws InvalidSnsMessageException if the cert url is invalid.
|
||||
*/
|
||||
private function validateUrl($url)
|
||||
{
|
||||
$parsed = parse_url($url);
|
||||
if (empty($parsed['scheme'])
|
||||
|| empty($parsed['host'])
|
||||
|| $parsed['scheme'] !== 'https'
|
||||
|| substr($url, -4) !== '.pem'
|
||||
|| !preg_match($this->hostPattern, $parsed['host'])
|
||||
) {
|
||||
throw new InvalidSnsMessageException(
|
||||
'The certificate is located on an invalid domain.'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user