This commit is contained in:
Purple
2026-01-17 23:37:18 +00:00
parent 17fd69c4f7
commit 9bb80eb7d9

View File

@@ -2483,44 +2483,72 @@ function handlePtrLookup($db) {
/**
* Make AWS Route53 API request with Signature Version 4
* Note: Route53 is a global service, always uses us-east-1 for signing
*/
function awsRoute53Request($method, $path, $body, $accessKeyId, $secretAccessKey, $region) {
$service = 'route53';
$host = 'route53.amazonaws.com';
$endpoint = "https://{$host}/{$path}";
// Route53 is a global service, always use us-east-1 for signing
$signingRegion = 'us-east-1';
$algorithm = 'AWS4-HMAC-SHA256';
$timestamp = gmdate('Ymd\THis\Z');
$datestamp = gmdate('Ymd');
// Create canonical request
$canonicalUri = '/' . $path;
// Parse path and query string
$canonicalUri = '/' . ltrim($path, '/');
$canonicalQuerystring = '';
// Parse query string if present
if (strpos($path, '?') !== false) {
list($canonicalUri, $queryString) = explode('?', '/' . $path, 2);
list($pathPart, $queryString) = explode('?', $path, 2);
$canonicalUri = '/' . ltrim($pathPart, '/');
parse_str($queryString, $queryParams);
ksort($queryParams);
$canonicalQuerystring = http_build_query($queryParams);
// Build query string with proper encoding
$pairs = [];
foreach ($queryParams as $k => $v) {
$pairs[] = rawurlencode($k) . '=' . rawurlencode($v);
}
$canonicalQuerystring = implode('&', $pairs);
}
$payloadHash = hash('sha256', is_array($body) ? json_encode($body) : '');
$endpoint = "https://{$host}{$canonicalUri}" . ($canonicalQuerystring ? "?{$canonicalQuerystring}" : '');
// For GET requests, body is empty
$payload = '';
if ($method === 'POST' && !empty($body)) {
$payload = is_array($body) ? json_encode($body) : $body;
}
$payloadHash = hash('sha256', $payload);
// Build canonical headers - must be sorted alphabetically and lowercase
$canonicalHeaders = "host:{$host}\n" .
"x-amz-date:{$timestamp}\n";
$signedHeaders = 'host;x-amz-date';
$canonicalRequest = "{$method}\n{$canonicalUri}\n{$canonicalQuerystring}\n{$canonicalHeaders}\n{$signedHeaders}\n{$payloadHash}";
// Build canonical request
$canonicalRequest = implode("\n", [
$method,
$canonicalUri,
$canonicalQuerystring,
$canonicalHeaders,
$signedHeaders,
$payloadHash
]);
// Create string to sign
$credentialScope = "{$datestamp}/{$region}/{$service}/aws4_request";
$stringToSign = "{$algorithm}\n{$timestamp}\n{$credentialScope}\n" . hash('sha256', $canonicalRequest);
$credentialScope = "{$datestamp}/{$signingRegion}/{$service}/aws4_request";
$stringToSign = implode("\n", [
$algorithm,
$timestamp,
$credentialScope,
hash('sha256', $canonicalRequest)
]);
// Calculate signature
// Calculate signature using HMAC-SHA256
$kSecret = 'AWS4' . $secretAccessKey;
$kDate = hash_hmac('sha256', $datestamp, $kSecret, true);
$kRegion = hash_hmac('sha256', $region, $kDate, true);
$kRegion = hash_hmac('sha256', $signingRegion, $kDate, true);
$kService = hash_hmac('sha256', $service, $kRegion, true);
$kSigning = hash_hmac('sha256', 'aws4_request', $kService, true);
$signature = hash_hmac('sha256', $stringToSign, $kSigning);
@@ -2537,14 +2565,13 @@ function awsRoute53Request($method, $path, $body, $accessKeyId, $secretAccessKey
CURLOPT_HTTPHEADER => [
"Host: {$host}",
"X-Amz-Date: {$timestamp}",
"Authorization: {$authorizationHeader}",
"Content-Type: application/xml"
"Authorization: {$authorizationHeader}"
]
]);
if ($method === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($body) ? json_encode($body) : $body);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
}
$response = curl_exec($ch);