AWSRoute53Request.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. namespace MGModule\DNSManager2\mgLibs\custom\dns\submodules\AWSRoute53;
  3. use MGModule\DNSManager2\mgLibs\custom\dns\submodules\AWSRoute53 as awsRoute53;
  4. use MGModule\DNSManager2 as main;
  5. class AWSRoute53Request implements \MGModule\DNSManager2\mgLibs\custom\dns\submodules\AWSRoute53\AWSRoute53RequestInterface
  6. {
  7. private $apiKey;
  8. private $apiSecret;
  9. private $apiUrl = 'route53.amazonaws.com';
  10. private $_curl;
  11. private $result;
  12. private $responseHandler;
  13. private $timeHeader;
  14. private $dateHeader;
  15. private $requestType;
  16. private $service = 'route53';
  17. private $region;
  18. private $relativeUrl;
  19. private $reqBody;
  20. private $action;
  21. public function __construct(awsRoute53\AWSRoute53ResponseInterface $responseHandler, $apiKey, $apiSecret, $region = false)
  22. {
  23. $this->apiKey = $apiKey;
  24. $this->apiSecret = $apiSecret;
  25. $this->region = $region ? $region : 'us-east-1';
  26. $this->responseHandler = $responseHandler;
  27. }
  28. public function makeRequest($url, $type, $action, $body = false)
  29. {
  30. $this->cleanResponse();
  31. $this->result = false;
  32. $this->reqBody = false;
  33. $this->requestType = $type;
  34. $this->relativeUrl = $url;
  35. $this->action = $action;
  36. $this->prepareConnectionObject($body);
  37. $this->setApiHeaders();
  38. $this->result = curl_exec($this->_curl);
  39. $this->log();
  40. if(curl_errno($this->_curl))
  41. {
  42. $this->error = curl_errno($this->_curl);
  43. $this->log($action.' Error');
  44. curl_close($this->_curl);
  45. $this->responseHandler->prepareTextResponse('error', $this->error);
  46. }
  47. curl_close($this->_curl);
  48. return $this->responseHandler->prepareResponse($this->result);
  49. }
  50. private function prepareConnectionObject($body = false)
  51. {
  52. $this->_curl = curl_init();
  53. curl_setopt($this->_curl, CURLOPT_URL, 'https://'.$this->apiUrl.$this->relativeUrl);
  54. curl_setopt($this->_curl, CURLOPT_CUSTOMREQUEST, $this->requestType);
  55. curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, true);
  56. curl_setopt($this->_curl, CURLOPT_SSL_VERIFYPEER, true);
  57. curl_setopt($this->_curl, CURLOPT_SSL_VERIFYHOST, true);
  58. curl_setopt($this->_curl, CURLINFO_HEADER_OUT, true);
  59. if($body)
  60. {
  61. $this->reqBody = $body;
  62. curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $body);
  63. }
  64. }
  65. private function setApiHeaders()
  66. {
  67. $this->timeHeader = gmdate('Ymd\THis\Z');
  68. $this->dateHeader = gmdate('Ymd');
  69. $signatrue = $this->getSignaure();
  70. curl_setopt($this->_curl, CURLOPT_HTTPHEADER,
  71. array(
  72. "x-amz-date:$this->timeHeader",
  73. "authorization:AWS4-HMAC-SHA256 Credential=$this->apiKey/$this->dateHeader/$this->region/$this->service/aws4_request, SignedHeaders=content-length;content-type;host;user-agent;x-amz-date;x-amz-target, Signature=$signatrue"
  74. )
  75. );
  76. }
  77. private function getSignaure()
  78. {
  79. $parsedHash = $this->getSignatureKey();
  80. $scope = $this->createScope();
  81. $canonical = $this->getCanonicalBody();
  82. $toSign = $this->createStringToSign($this->timeHeader, $scope, $canonical);
  83. $signature = hash_hmac('sha256', $toSign, $parsedHash);
  84. return $signature;
  85. }
  86. private function getCanonicalBody()
  87. {
  88. $payloadHash = $this->getPayloadHash();
  89. $url = explode('?', $this->relativeUrl);
  90. $contLenght = strlen($this->reqBody);
  91. $boundary = $this->requestType === 'POST' ?
  92. "content-length:$contLenght\ncontent-type:application/x-www-form-urlencoded\n"
  93. : "content-length:\ncontent-type:\n";
  94. $canonical = $this->requestType."\n";
  95. $canonical .= $url[0]."\n$url[1]\n";
  96. $canonical .= $boundary."host:$this->apiUrl\nuser-agent:\n";
  97. $canonical .= "x-amz-date:$this->timeHeader\n";
  98. $canonical .= "x-amz-target:\n\ncontent-length;content-type;host;user-agent;x-amz-date;x-amz-target\n";
  99. $canonical .= $payloadHash;
  100. return $canonical;
  101. }
  102. private function log($action = false)
  103. {
  104. $addonConfig = main\addon::config();
  105. logmodulecall(
  106. $addonConfig['name'],
  107. 'AWSRoute53 '.($action ? $action : $this->action),
  108. curl_getinfo($this->_curl),
  109. $this->result,
  110. null,
  111. array($this->apiKey, $this->apiSecret)
  112. );
  113. }
  114. private function getSignatureKey()
  115. {
  116. $dateKey = hash_hmac('sha256', $this->dateHeader, "AWS4{$this->apiSecret}", true);
  117. $regionKey = hash_hmac('sha256', $this->region, $dateKey, true);
  118. $serviceKey = hash_hmac('sha256', $this->service, $regionKey, true);
  119. $finalHash = hash_hmac('sha256', 'aws4_request', $serviceKey, true);
  120. return $finalHash;
  121. }
  122. private function createStringToSign($longDate, $credentialScope, $creq)
  123. {
  124. $hash = hash('sha256', $creq);
  125. return "AWS4-HMAC-SHA256\n{$longDate}\n{$credentialScope}\n{$hash}";
  126. }
  127. private function createScope()
  128. {
  129. return "$this->dateHeader/$this->region/$this->service/aws4_request";
  130. }
  131. private function getPayloadHash()
  132. {
  133. return hash('sha256', $this->reqBody ? : '');
  134. }
  135. private function cleanResponse()
  136. {
  137. $rsponseHandlerClassName = get_class($this->responseHandler);
  138. $this->responseHandler = new $rsponseHandlerClassName;
  139. }
  140. }