PageRenderTime 69ms CodeModel.GetById 30ms RepoModel.GetById 7ms app.codeStats 0ms

/lib/sdk-1.5.5/authentication/signature_v3json.class.php

https://bitbucket.org/ardydedase/web-build-optimizer
PHP | 235 lines | 128 code | 38 blank | 69 comment | 17 complexity | 886798df7c07e5be8f4c45f20837ba43 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause
  1. <?php
  2. /*
  3. * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License").
  6. * You may not use this file except in compliance with the License.
  7. * A copy of the License is located at
  8. *
  9. * http://aws.amazon.com/apache2.0
  10. *
  11. * or in the "license" file accompanying this file. This file is distributed
  12. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  13. * express or implied. See the License for the specific language governing
  14. * permissions and limitations under the License.
  15. */
  16. /*%******************************************************************************************%*/
  17. // CLASS
  18. /**
  19. * Implements support for Signature v3 (JSON).
  20. *
  21. * @version 2011.12.08
  22. * @license See the included NOTICE.md file for more information.
  23. * @copyright See the included NOTICE.md file for more information.
  24. * @link http://aws.amazon.com/php/ PHP Developer Center
  25. */
  26. class AuthV3JSON extends Signer implements Signable
  27. {
  28. /**
  29. * Constructs a new instance of the <AuthV3JSON> class.
  30. *
  31. * @param string $endpoint (Required) The endpoint to direct the request to.
  32. * @param string $operation (Required) The operation to execute as a result of this request.
  33. * @param array $payload (Required) The options to use as part of the payload in the request.
  34. * @param CFCredential $credentials (Required) The credentials to use for signing and making requests.
  35. * @return void
  36. */
  37. public function __construct($endpoint, $operation, $payload, CFCredential $credentials)
  38. {
  39. parent::__construct($endpoint, $operation, $payload, $credentials);
  40. }
  41. /**
  42. * Generates a cURL handle with all of the required authentication bits set.
  43. *
  44. * @return resource A cURL handle ready for executing.
  45. */
  46. public function authenticate()
  47. {
  48. // Determine signing values
  49. $current_time = time();
  50. $date = gmdate(CFUtilities::DATE_FORMAT_RFC2616, $current_time);
  51. $timestamp = gmdate(CFUtilities::DATE_FORMAT_ISO8601, $current_time);
  52. $nonce = $this->util->generate_guid();
  53. $curlopts = array();
  54. $signed_headers = array();
  55. $return_curl_handle = false;
  56. $x_amz_target = null;
  57. $query = array('body' => $this->payload);
  58. // Do we have an authentication token?
  59. if ($this->auth_token)
  60. {
  61. $headers['X-Amz-Security-Token'] = $this->auth_token;
  62. $query['SecurityToken'] = $this->auth_token;
  63. }
  64. // Manage the key-value pairs that are used in the query.
  65. if (stripos($this->operation, 'x-amz-target') !== false)
  66. {
  67. $x_amz_target = trim(str_ireplace('x-amz-target:', '', $this->operation));
  68. }
  69. else
  70. {
  71. $query['Action'] = $this->operation;
  72. }
  73. // Only add it if it exists.
  74. if ($this->api_version)
  75. {
  76. $query['Version'] = $this->api_version;
  77. }
  78. $curlopts = array();
  79. // Set custom CURLOPT settings
  80. if (is_array($this->payload) && isset($this->payload['curlopts']))
  81. {
  82. $curlopts = $this->payload['curlopts'];
  83. unset($this->payload['curlopts']);
  84. }
  85. // Merge in any options that were passed in
  86. if (is_array($this->payload))
  87. {
  88. $query = array_merge($query, $this->payload);
  89. }
  90. $return_curl_handle = isset($query['returnCurlHandle']) ? $query['returnCurlHandle'] : false;
  91. unset($query['returnCurlHandle']);
  92. // Do a case-sensitive, natural order sort on the array keys.
  93. uksort($query, 'strcmp');
  94. // Normalize JSON input
  95. if (isset($query['body']) && $query['body'] === '[]')
  96. {
  97. $query['body'] = '{}';
  98. }
  99. // Create the string that needs to be hashed.
  100. $canonical_query_string = $this->util->encode_signature2($query['body']);
  101. // Remove the default scheme from the domain.
  102. $domain = str_replace(array('http://', 'https://'), '', $this->endpoint);
  103. // Parse our request.
  104. $parsed_url = parse_url('http://' . $domain);
  105. // Set the proper host header.
  106. if (isset($parsed_url['port']) && (integer) $parsed_url['port'] !== 80 && (integer) $parsed_url['port'] !== 443)
  107. {
  108. $host_header = strtolower($parsed_url['host']) . ':' . $parsed_url['port'];
  109. }
  110. else
  111. {
  112. $host_header = strtolower($parsed_url['host']);
  113. }
  114. // Set the proper request URI.
  115. $request_uri = isset($parsed_url['path']) ? $parsed_url['path'] : '/';
  116. // Generate the querystring from $query
  117. $this->querystring = $this->util->to_query_string($query);
  118. // Gather information to pass along to other classes.
  119. $helpers = array(
  120. 'utilities' => $this->utilities_class,
  121. 'request' => $this->request_class,
  122. 'response' => $this->response_class,
  123. );
  124. // Compose the request.
  125. $request_url = ($this->use_ssl ? 'https://' : 'http://') . $domain;
  126. $request_url .= !isset($parsed_url['path']) ? '/' : '';
  127. // Instantiate the request class
  128. $request = new $this->request_class($request_url, $this->proxy, $helpers, $this->credentials);
  129. $request->set_method('POST');
  130. //$request->set_body($this->querystring);
  131. //$headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
  132. // Signing using X-Amz-Target is handled differently.
  133. $headers['X-Amz-Target'] = $x_amz_target;
  134. $headers['Content-Type'] = 'application/x-amz-json-1.0';
  135. $request->set_body($query['body']);
  136. $this->querystring = $query['body'];
  137. // Pass along registered stream callbacks
  138. if ($this->registered_streaming_read_callback)
  139. {
  140. $request->register_streaming_read_callback($this->registered_streaming_read_callback);
  141. }
  142. if ($this->registered_streaming_write_callback)
  143. {
  144. $request->register_streaming_write_callback($this->registered_streaming_write_callback);
  145. }
  146. // Add authentication headers
  147. // $headers['X-Amz-Nonce'] = $nonce;
  148. $headers['Date'] = $date;
  149. $headers['Content-Length'] = strlen($this->querystring);
  150. $headers['Content-MD5'] = $this->util->hex_to_base64(md5($this->querystring));
  151. $headers['Host'] = $host_header;
  152. // Sort headers
  153. uksort($headers, 'strnatcasecmp');
  154. // Prepare the string to sign (HTTP)
  155. $this->string_to_sign = "POST\n$request_uri\n\n";
  156. // Add headers to request and compute the string to sign
  157. foreach ($headers as $header_key => $header_value)
  158. {
  159. // Strip linebreaks from header values as they're illegal and can allow for security issues
  160. $header_value = str_replace(array("\r", "\n"), '', $header_value);
  161. // Add the header if it has a value
  162. if ($header_value !== '')
  163. {
  164. $request->add_header($header_key, $header_value);
  165. }
  166. // Generate the string to sign
  167. if (
  168. substr(strtolower($header_key), 0, 8) === 'content-' ||
  169. strtolower($header_key) === 'date' ||
  170. strtolower($header_key) === 'expires' ||
  171. strtolower($header_key) === 'host' ||
  172. substr(strtolower($header_key), 0, 6) === 'x-amz-'
  173. )
  174. {
  175. $this->string_to_sign .= strtolower($header_key) . ':' . $header_value . "\n";
  176. $signed_headers[] = $header_key;
  177. }
  178. }
  179. $this->string_to_sign .= "\n";
  180. if (isset($query['body']) && $query['body'] !== '')
  181. {
  182. $this->string_to_sign .= $query['body'];
  183. }
  184. // Convert from string-to-sign to bytes-to-sign
  185. $bytes_to_sign = hash('sha256', $this->string_to_sign, true);
  186. // Hash the AWS secret key and generate a signature for the request.
  187. $signature = base64_encode(hash_hmac('sha256', $bytes_to_sign, $this->secret_key, true));
  188. $headers['X-Amzn-Authorization'] = 'AWS3'
  189. . ' AWSAccessKeyId=' . $this->key
  190. . ',Algorithm=HmacSHA256'
  191. . ',SignedHeaders=' . implode(';', $signed_headers)
  192. . ',Signature=' . $signature;
  193. $request->add_header('X-Amzn-Authorization', $headers['X-Amzn-Authorization']);
  194. $request->request_headers = $headers;
  195. return $request;
  196. }
  197. }