| #!/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"; |
| } |