Skip to content

Instantly share code, notes, and snippets.

@leonid-shevtsov
Created May 27, 2020 06:05
Show Gist options
  • Save leonid-shevtsov/8e9bd97331fd412f2082d33eb3016d01 to your computer and use it in GitHub Desktop.
Save leonid-shevtsov/8e9bd97331fd412f2082d33eb3016d01 to your computer and use it in GitHub Desktop.
Send data to AWS SQS (Simple Queue Service) from Halon MTA (with signature)
function signedHeaders($headers) {
return array_join(array_sort(function ($a, $b) { return $a < $b; }, array_map(function($key) { return str_lower($key); }, array_keys($headers))), ";");
}
function canonicalRequest($method, $uriPath, $queryString, $headers, $signedHeaders, $requestBody) {
$headersString = array_join(array_sort(function ($a, $b) { return $a < $b; }, array_map(function($key) closure($headers) { return str_lower($key) . ":" . $headers[$key]. "\n"; }, array_keys($headers))));
$payloadHash = sha2($requestBody, 256);
return $method . "\n" . $uriPath . "\n" . $queryString . "\n" . $headersString . "\n" . $signedHeaders . "\n" . $payloadHash;
}
function stringToSign($timeStamp, $scope, $canonicalRequest) {
return "AWS4-HMAC-SHA256\n" . $timeStamp . "\n" . $scope . "\n" . sha2($canonicalRequest, 256);
}
function signingKey($secretAccessKey, $date, $region, $service) {
$kSecret = $secretAccessKey;
$kDate = pack("H*", hmac_sha2("AWS4" . $kSecret, $date, 256));
$kRegion = pack("H*", hmac_sha2($kDate, $region, 256));
$kService = pack("H*", hmac_sha2($kRegion, $service, 256));
return pack("H*", hmac_sha2($kService, "aws4_request", 256));
}
function signature($signingKey, $stringToSign) {
return hmac_sha2($signingKey, $stringToSign, 256);
}
function authorizationHeader($accessKeyID, $scope, $signedHeaders, $signature) {
return "AWS4-HMAC-SHA256 Credential=" . $accessKeyID . "/" . $scope . ", SignedHeaders=" . $signedHeaders . ", Signature=" . $signature;
}
function makeAWSRequest($method, $hostname, $path, $queryString, $headers, $requestBody, $accessKeyID, $secretAccessKey, $region, $service) {
$time = time();
$timeStamp = strftime("%Y%m%dT%H%M%SZ", $time);
$date = strftime("%Y%m%d", $time);
$headers["Host"] = $hostname;
$headers["Content-Type"] = "application/x-www-form-urlencoded";
$headers["X-Amz-Date"] = $timeStamp;
$signedHeaders = signedHeaders($headers);
$requestString = canonicalRequest($method, $path, $queryString, $headers, $signedHeaders, $requestBody);
$scope = $date . "/" . $region . "/" . $service . "/aws4_request";
$stringToSign = stringToSign($timeStamp, $scope, $requestString);
$signingKey = signingKey($secretAccessKey, $date, $region, $service);
$signature = signature($signingKey, $stringToSign);
$authorizationHeader = authorizationHeader($accessKeyID, $scope, $signedHeaders, $signature);
$headers["Authorization"] = $authorizationHeader;
$url = "https://" . $hostname . $path;
$headers_for_http = array_map(function($key) closure($headers) { return $key . ": " . $headers[$key];}, array_keys($headers));
$response = http($url, ["headers" => $headers_for_http, "method" => $method, "extended_result" => true, "tls_verify_peer" => false], $queryString, $requestBody);
return $response;
}
$region = "XXX";
$service = "sqs";
$host = "sqs." . $region . ".amazonaws.com";
$path = "/ACCOUNT_ID/QUEUE_NAME";
$requestBody = "Action=SendMessage&MessageBody=XXX";
$keyID = "SOME_AWS_ACCESS_KEY_ID";
$secret = "SOME_AWS_SECRET_KEY";
echo makeAWSRequest("POST", $host, $path, "", [], $requestBody, $keyID, $secret, $region, $service);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment