Backups Created:
/home/japatmex/public_html/wp-content/edit-wolf.php
Savvy
W
olf -
MANAGER
Edit File: emailservicerequest.php
<?php namespace GOSMTP\mailer\amazonses; /** * EmailServiceRequest PHP class * * @link https://github.com/daniel-zahariev/php-aws-ses * @package AmazonEmailService * @version v0.9.1 */ class EmailServiceRequest { private $ses, $verb, $parameters = array(); // CURL request handler that can be reused protected $curl_handler = null; // Holds the response from calling AWS's API protected $response; // public static $curlOptions = array(); /** * Constructor * * @param EmailService $ses The EmailService object making this request * @param string $verb HTTP verb * @return void */ public function __construct(EmailService $ses = null, $verb = 'GET') { $this->ses = $ses; $this->verb = $verb; $this->response = (object) array('body' => '', 'code' => 0, 'error' => false); } /** * Set SES class * * @param EmailService $ses * @return EmailServiceRequest $this */ public function setSES(EmailService $ses) { $this->ses = $ses; return $this; } /** * Set HTTP method * * @param string $verb * @return EmailServiceRequest $this */ public function setVerb($verb) { $this->verb = $verb; return $this; } /** * Set request parameter * * @param string $key Key * @param string $value Value * @param boolean $replace Whether to replace the key if it already exists (default true) * @return EmailServiceRequest $this */ public function setParameter($key, $value, $replace = true) { if(!$replace && isset($this->parameters[$key])) { $temp = (array)($this->parameters[$key]); $temp[] = $value; $this->parameters[$key] = $temp; } else { $this->parameters[$key] = $value; } return $this; } /** * Get the params for the request * * @return array $params */ public function getParametersEncoded() { $params = array(); foreach ($this->parameters as $var => $value) { if(is_array($value)) { foreach($value as $v) { $params[] = $var.'='.$this->__customUrlEncode($v); } } else { $params[] = $var.'='.$this->__customUrlEncode($value); } } sort($params, SORT_STRING); return $params; } /** * Clear the request parameters * @return EmailServiceRequest $this */ public function clearParameters() { $this->parameters = array(); return $this; } /** * Instantiate and setup CURL handler for sending requests. * Instance is cashed in `$this->curl_handler` * * @return resource $curl_handler */ protected function getCurlHandler() { if (!empty($this->curl_handler)) return $this->curl_handler; $curl = curl_init(); curl_setopt($curl, CURLOPT_USERAGENT, 'EmailService/php'); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, ($this->ses->verifyHost() ? 2 : 0)); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, ($this->ses->verifyPeer() ? 1 : 0)); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, false); curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback')); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); foreach(self::$curlOptions as $option => $value) { curl_setopt($curl, $option, $value); } $this->curl_handler = $curl; return $this->curl_handler; } /** * Get the response * * @return object | false */ public function getResponse() { $url = 'https://'.$this->ses->getHost().'/'; $query = implode('&', $this->getParametersEncoded()); $headers = $this->getHeaders($query); $curl_handler = $this->getCurlHandler(); curl_setopt($curl_handler, CURLOPT_CUSTOMREQUEST, $this->verb); // Request types switch ($this->verb) { case 'GET': case 'DELETE': $url .= '?'.$query; break; case 'POST': curl_setopt($curl_handler, CURLOPT_POSTFIELDS, $query); $headers[] = 'Content-Type: application/x-www-form-urlencoded'; break; } curl_setopt($curl_handler, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl_handler, CURLOPT_URL, $url); // Execute, grab errors if (curl_exec($curl_handler)) { $this->response->code = curl_getinfo($curl_handler, CURLINFO_HTTP_CODE); } else { $this->response->error = array( 'curl' => true, 'code' => curl_errno($curl_handler), 'message' => curl_error($curl_handler), ); } // cleanup for reusing the current instance for multiple requests curl_setopt($curl_handler, CURLOPT_POSTFIELDS, ''); $this->parameters = array(); // Parse body into XML if ($this->response->error === false && !empty($this->response->body)) { $this->response->body = simplexml_load_string($this->response->body); // Grab SES errors if (!in_array($this->response->code, array(200, 201, 202, 204)) && isset($this->response->body->Error)) { $error = $this->response->body->Error; $output = array(); $output['curl'] = false; $output['Error'] = array(); $output['Error']['Type'] = (string)$error->Type; $output['Error']['Code'] = (string)$error->Code; $output['Error']['Message'] = (string)$error->Message; $output['RequestId'] = (string)$this->response->body->RequestId; $this->response->error = $output; unset($this->response->body); } } $response = $this->response; $this->response = (object) array('body' => '', 'code' => 0, 'error' => false); return $response; } /** * Get request headers * @param string $query * @return array */ protected function getHeaders($query) { $headers = array(); if ($this->ses->getRequestSignatureVersion() == EmailService::REQUEST_SIGNATURE_V4) { $date = (new \DateTime('now', new \DateTimeZone('UTC')))->format('Ymd\THis\Z'); $headers[] = 'X-Amz-Date: ' . $date; $headers[] = 'Host: ' . $this->ses->getHost(); $headers[] = 'Authorization: ' . $this->__getAuthHeaderV4($date, $query); } else { // must be in format 'Sun, 06 Nov 1994 08:49:37 GMT' $date = gmdate('D, d M Y H:i:s e'); $auth = 'AWS3-HTTPS AWSAccessKeyId='.$this->ses->getAccessKey(); $auth .= ',Algorithm=HmacSHA256,Signature='.$this->__getSignature($date); $headers[] = 'Date: ' . $date; $headers[] = 'Host: ' . $this->ses->getHost(); $headers[] = 'X-Amzn-Authorization: ' . $auth; } return $headers; } /** * Destroy any leftover handlers */ public function __destruct() { if (!empty($this->curl_handler)) @curl_close($this->curl_handler); } /** * CURL write callback * * @param resource $curl CURL resource * @param string $data Data * @return integer */ private function __responseWriteCallback($curl, $data) { if (!isset($this->response->body)) { $this->response->body = $data; } else { $this->response->body .= $data; } return strlen($data); } /** * Contributed by afx114 * URL encode the parameters as per http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?Query_QueryAuth.html * PHP's rawurlencode() follows RFC 1738, not RFC 3986 as required by Amazon. The only difference is the tilde (~), so convert it back after rawurlencode * See: http://www.morganney.com/blog/API/AWS-Product-Advertising-API-Requires-a-Signed-Request.php * * @param string $var String to encode * @return string */ private function __customUrlEncode($var) { return str_replace('%7E', '~', rawurlencode($var)); } /** * Generate the auth string using Hmac-SHA256 * * @internal Used by EmailServiceRequest::getResponse() * @param string $string String to sign * @return string */ private function __getSignature($string) { return base64_encode(hash_hmac('sha256', $string, $this->ses->getSecretKey(), true)); } /** * @param string $key * @param string $dateStamp * @param string $regionName * @param string $serviceName * @param string $algo * @return string */ private function __getSigningKey($key, $dateStamp, $regionName, $serviceName, $algo) { $kDate = hash_hmac($algo, $dateStamp, 'AWS4' . $key, true); $kRegion = hash_hmac($algo, $regionName, $kDate, true); $kService = hash_hmac($algo, $serviceName, $kRegion, true); return hash_hmac($algo,'aws4_request', $kService, true); } /** * Implementation of AWS Signature Version 4 * @see https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html * @param string $amz_datetime * @param string $query * @return string */ private function __getAuthHeaderV4($amz_datetime, $query) { $amz_date = substr($amz_datetime, 0, 8); $algo = 'sha256'; $aws_algo = 'AWS4-HMAC-' . strtoupper($algo); $host_parts = explode('.', $this->ses->getHost()); $service = $host_parts[0]; $region = $host_parts[1]; $canonical_uri = '/'; if($this->verb === 'POST') { $canonical_querystring = ''; $payload_data = $query; } else { $canonical_querystring = $query; $payload_data = ''; } // ************* TASK 1: CREATE A CANONICAL REQUEST ************* $canonical_headers_list = [ 'host:' . $this->ses->getHost(), 'x-amz-date:' . $amz_datetime ]; $canonical_headers = implode("\n", $canonical_headers_list) . "\n"; $signed_headers = 'host;x-amz-date'; $payload_hash = hash($algo, $payload_data, false); $canonical_request = implode("\n", array( $this->verb, $canonical_uri, $canonical_querystring, $canonical_headers, $signed_headers, $payload_hash )); // ************* TASK 2: CREATE THE STRING TO SIGN************* $credential_scope = $amz_date. '/' . $region . '/' . $service . '/' . 'aws4_request'; $string_to_sign = implode("\n", array( $aws_algo, $amz_datetime, $credential_scope, hash($algo, $canonical_request, false) )); // ************* TASK 3: CALCULATE THE SIGNATURE ************* // Create the signing key using the function defined above. $signing_key = $this->__getSigningKey($this->ses->getSecretKey(), $amz_date, $region, $service, $algo); // Sign the string_to_sign using the signing_key $signature = hash_hmac($algo, $string_to_sign, $signing_key, false); // ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST ************* return $aws_algo . ' ' . implode(', ', array( 'Credential=' . $this->ses->getAccessKey() . '/' . $credential_scope, 'SignedHeaders=' . $signed_headers , 'Signature=' . $signature )); } }