plugins/experimental/url_sig/sign.pl (231 lines of code) (raw):

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