#!/usr/bin/perl
#
# sign_request.pl
#
# Version 4.091210 - 10th December 2009
#
# This version created by Labbs (http://www.labbs.com), with help from
# Keith S.(ad104@yahoo.com).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
sub sign_request {
# External PERL modules required
# Digest
# Digest::SHA qw(hmac_sha256_base64)
# or Digest::SHA::PurePerl qw(hmac_sha256_base64)
# Try and load standard modules, but fallback to local PurePerl modules
my @UseModules=qw(
use Digest;
use Digest::SHA;
);
for(@UseModules)
{
if($@){
BEGIN{unshift @INC,"lib";$| =1;open(STDERR,">&STDOUT");}
use Digest;
use Digest::SHA::PurePerl qw(hmac_sha256_base64);
# $debug .= qq[Using Local PurePerl Module
\n];
}
else{
@UseModules;
# $debug .= qq[Using Server C Module
\n];
}}
my ($value) = @_;
my $MyTimeStamp = sprintf("%04d-%02d-%02dT%02d:%02d:%02d.000Z",
sub { ($_[5]+1900,
$_[4]+1,
$_[3],
$_[2],
$_[1],
$_[0])
}->(gmtime(time)));
my $stringToSign = $value . '&Timestamp=' . $MyTimeStamp . '&AWSAccessKeyId=' . $MY_variables{AWSAccessKey};
# split the host from the request parameters
my @request_elements = split('\?', $stringToSign);
# Get the host and parameters
my $request_host = $request_elements[0];
my @request_parameters = split('&', $request_elements[1]);
# Sort your parameter/value pairs by byte value (not alphabetically,
# lowercase parameters will be listed after uppercase ones).
# Rejoin the sorted parameter/value list with ampersands. The result
# is the canonical string that we'll sign:
my $request_string = '';
my @sorted_request_parameters = '';
foreach my $parameter (sort(@request_parameters)) {
# Uppercase URL % encoded characters as request signing expects them to be Upper Case
# $debug .= qq[Parameter before necessary translations: '$parameter'
\n];
$parameter =~ s/\%(.{2})/'%'.uc($1)/segi;
# Encode comma (,) and colon (:) in parameters
$parameter =~ s/[,]/'%2C'/seg;
$parameter =~ s/[:]/'%3A'/seg;
# Decode hyphen (-) encoded as %2d in parameters
$parameter =~ s/%2D/'-'/segi;
$parameter =~ s/%2E/'.'/segi; #tc fix for having a dot in the author name (8th Dec 2009)
# see http://www.absolutefreebies.com/phpBB2/viewtopic.php?p=61316#61316
# $debug .= qq[Parameter after necessary translations: '$parameter'
\n];
$request_string .= '&' . $parameter;
}
# Remove any leading & from our request string
while(index($request_string, '&') == 0) {
$request_string = substr($request_string, 1);
}
# $debug .= qq[Request String: '$request_string'
\n];
# Prepend the following three lines (with line breaks) before the canonical string:
# GET
# webservices.amazon.com
# /onca/xml
my $stringToSign = "GET\n$Internal_variables{amazon_server}.$Internal_variables{amazon_site}\n/onca/xml\n" . $request_string;
# Calculate an RFC 2104-compliant HMAC with the SHA256 hash algorithm
my $signature = hmac_sha256_base64 ($stringToSign, $MY_variables{AWSSecretKey}) . "=";
# URL encode the plus (+) and equal (=) characters in the signature:
$signature =~ s/[+]/'%2B'/seg;
$signature =~ s/[=]/'%3D'/seg;
# Add the URL encoded signature to your request and the result is a
#properly-formatted signed request:
return $request_host . '?' . $request_string . '&Signature=' . $signature;
}
1;
# end of sign_request.pl