blob: 7cf3850dd0c3dc61a98cf9d5e2fa76bf62ab4332 [file] [log] [blame]
#!/usr/bin/perl
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
use Digest::SHA qw(hmac_sha1 hmac_sha1_hex);
use Digest::HMAC_MD5 qw(hmac_md5 hmac_md5_hex);
use Getopt::Long;
use MIME::Base64::URLSafe ();
use strict;
use warnings;
my $key = undef;
my $string = undef;
my $useparts = undef;
my $result = undef;
my $duration = undef;
my $keyindex = undef;
my $verbose = 0;
my $url = undef;
my $client = undef;
my $algorithm = 1;
my $pathparams = 0;
my $sig_anchor = undef;
my $proxy = undef;
my $scheme = "http://";
$result = GetOptions(
"url=s" => \$url,
"useparts=s" => \$useparts,
"duration=i" => \$duration,
"key=s" => \$key,
"client=s" => \$client,
"algorithm=i" => \$algorithm,
"keyindex=i" => \$keyindex,
"verbose" => \$verbose,
"pathparams" => \$pathparams,
"proxy=s" => \$proxy,
"siganchor=s" => \$sig_anchor
);
if (!defined($key) || !defined($url) || !defined($duration) || !defined($keyindex)) {
&help();
exit(1);
}
if (defined($proxy)) {
if ($proxy !~ /http\:\/\/.*\:\d\d/) {
&help();
}
}
if ($url =~ m/^https/) {
$url =~ s/^https:\/\///;
$scheme = "https://";
} else {
$url =~ s/^http:\/\///;
}
my $url_prefix = $url;
$url_prefix =~ s/^([^:]*:\/\/).*$/$1/;
$url =~ s/^[^:]+:\/\///;
my $i = 0;
my $part_active = 0;
my $j = 0;
my @inactive_parts = ();
my $query_params = undef;
my $urlHasParams = index($url, "?");
my $file = undef;
my @parts = (split(/\//, $url));
my $parts_size = scalar(@parts);
if ($pathparams) {
if (scalar(@parts) > 1) {
$file = pop @parts;
} else {
print STDERR "\nERROR: No file segment in the path when using --pathparams.\n\n";
&help();
exit 1;
}
if ($urlHasParams) {
$file = (split(/\?/, $file))[0];
}
$parts_size = scalar(@parts);
}
if ($urlHasParams > 0) {
if (!$pathparams) {
($parts[$parts_size - 1], $query_params) = (split(/\?/, $parts[$parts_size - 1]));
} else {
$query_params = (split(/\?/, $url))[1];
}
}
foreach my $part (@parts) {
if (length($useparts) > $i) {
$part_active = substr($useparts, $i++, 1);
}
if ($part_active) {
$string .= $part . "/";
} else {
$inactive_parts[$j] = $part;
}
$j++;
}
my $signing_signature = undef;
chop($string);
if ($pathparams) {
if (defined($client)) {
$signing_signature =
";C=" . $client . ";E=" . (time() + $duration) . ";A=" . $algorithm . ";K=" . $keyindex . ";P=" . $useparts . ";S=";
$string .= $signing_signature;
} else {
$signing_signature = ";E=" . (time() + $duration) . ";A=" . $algorithm . ";K=" . $keyindex . ";P=" . $useparts . ";S=";
$string .= $signing_signature;
}
} else {
if (defined($client)) {
if ($urlHasParams > 0) {
$signing_signature =
"?$query_params" . "&C="
. $client . "&E="
. (time() + $duration) . "&A="
. $algorithm . "&K="
. $keyindex . "&P="
. $useparts . "&S=";
$string .= $signing_signature;
} else {
$signing_signature =
"?C=" . $client . "&E=" . (time() + $duration) . "&A=" . $algorithm . "&K=" . $keyindex . "&P=" . $useparts . "&S=";
$string .= $signing_signature;
}
} else {
if ($urlHasParams > 0) {
$signing_signature =
"?$query_params" . "&E=" . (time() + $duration) . "&A=" . $algorithm . "&K=" . $keyindex . "&P=" . $useparts . "&S=";
$string .= $signing_signature;
} else {
$signing_signature = "?E=" . (time() + $duration) . "&A=" . $algorithm . "&K=" . $keyindex . "&P=" . $useparts . "&S=";
$string .= $signing_signature;
}
}
}
my $digest;
if ($algorithm == 1) {
$digest = hmac_sha1_hex($string, $key);
} else {
$digest = hmac_md5_hex($string, $key);
}
$verbose && print "\nSigned String: $string\n\n";
$verbose && print "\nUrl: $url\n";
$verbose && print "\nsigning_signature: $signing_signature\n";
$verbose && print "\ndigest: $digest\n";
if ($urlHasParams == -1) { # no application query parameters.
if (!defined($proxy)) {
if (!$pathparams) {
print "curl -s -o /dev/null -v --max-redirs 0 '$scheme" . $url . $signing_signature . $digest . "'\n\n";
} else {
my $index = rindex($url, '/');
$url = substr($url, 0, $index);
my $encoded = MIME::Base64::URLSafe::encode($signing_signature . $digest);
if (defined($sig_anchor)) {
print "curl -s -o /dev/null -v --max-redirs 0 '$scheme" . $url . ";${sig_anchor}=" . $encoded . "/$file" . "'\n\n";
} else {
print "curl -s -o /dev/null -v --max-redirs 0 '$scheme" . $url . "/" . $encoded . "/$file" . "'\n\n";
}
}
} else {
if (!$pathparams) {
print "curl -s -o /dev/null -v --max-redirs 0 --proxy $proxy '$scheme" . $url . $signing_signature . $digest . "'\n\n";
} else {
my $index = rindex($url, '/');
$url = substr($url, 0, $index);
my $encoded = MIME::Base64::URLSafe::encode($signing_signature . $digest);
if (defined($sig_anchor)) {
print "curl -s -o /dev/null -v --max-redirs 0 --proxy $proxy '$scheme"
. $url
. ";${sig_anchor}="
. $encoded
. "/$file" . "'\n\n";
} else {
print "curl -s -o /dev/null -v --max-redirs 0 --proxy $proxy '$scheme" . $url . "/" . $encoded . "/$file" . "'\n\n";
}
}
}
} else { # has application parameters.
$url = (split(/\?/, $url))[0];
if (!defined($proxy)) {
if (!$pathparams) {
print "curl -s -o /dev/null -v --max-redirs 0 '$scheme" . $url . $signing_signature . $digest . "'\n\n";
} else {
my $index = rindex($url, '/');
$url = substr($url, 0, $index);
my $encoded = MIME::Base64::URLSafe::encode($signing_signature . $digest);
if (defined($sig_anchor)) {
print "curl -s -o /dev/null -v --max-redirs 0 '$scheme"
. $url
. ";${sig_anchor}="
. $encoded . "/"
. $file
. "?$query_params" . "'\n\n";
} else {
print "curl -s -o /dev/null -v --max-redirs 0 '$scheme" . $url . "/" . $encoded . "/" . $file . "?$query_params"
. "'\n\n";
}
}
} else {
if (!$pathparams) {
print "curl -s -o /dev/null -v --max-redirs 0 --proxy $proxy '$scheme" . $url . $signing_signature . $digest . "'\n\n";
} else {
my $index = rindex($url, '/');
$url = substr($url, 0, $index);
my $encoded = MIME::Base64::URLSafe::encode($signing_signature . $digest);
if (defined($sig_anchor)) {
print "curl -s -o /dev/null -v --max-redirs 0 --proxy $proxy '$scheme"
. $url
. ";${sig_anchor}="
. $encoded . "/"
. $file
. "?$query_params" . "'\n\n";
} else {
print "curl -s -o /dev/null -v --max-redirs 0 --proxy $proxy '$scheme"
. $url . "/"
. $encoded
. "/$file?$query_params" . "'\n\n";
}
}
}
}
sub help
{
print "sign.pl - Example signing utility in perl for signed URLs\n";
print "Usage: \n";
print " ./sign.pl --url <value> \\ \n";
print " --useparts <value> \\ \n";
print " --algorithm <value> \\ \n";
print " --duration <value> \\ \n";
print " --keyindex <value> \\ \n";
print " [--client <value>] \\ \n";
print " --key <value> \\ \n";
print " [--verbose] \n";
print " [--pathparams] \n";
print " [--proxy <url:port value>] ex value: http://myproxy:80\n";
print "\n";
}