blob: b65eb5035173e76cacf7493eede2b8bb66eae3bf [file] [log] [blame]
:
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
#**************************************************************
#
# 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 strict;
use Getopt::Long;
my $debug = 0;
my $max_files = 20; # sign $max_files with one command line
#### globals #####
my $myname = "";
my $opt_dir = "";
my $opt_exclude = ""; # file with a list of not signable dll and exe files
my $opt_verbose = 0;
my $opt_help = 0;
my $opt_log = ""; # for logging
my $opt_pass = ""; # password for signing
my $opt_pfxfile = ""; # Personal Information Exchange file
my $opt_timestamp_url = ""; # timestamp url
my %exclude_files = (); # list of not signable dll and exe files
my $signtool = "signtool.exe sign";
my @args = ();
my @files_to_sign = ();
#### main #####
$myname = script_id();
if ( $#ARGV < 2 ) {
usage();
exit(1);
}
@args = parse_options();
get_exclude_files();
@files_to_sign = get_files(\@args);
if ( $opt_log ) { # logging
open(LOG,">$opt_log") || die "Can't open log file $opt_log\n";
}
sign_files(\@files_to_sign);
close LOG if ($opt_log); # logging
exit 0;
#### subroutines ####
sub script_id
{
( my $script_name = $0 ) =~ s/^.*[\\\/]([\w\.]+)$/$1/;
my $script_rev;
my $id_str = ' $Revision$ ';
$id_str =~ /Revision:\s+(\S+)\s+\$/
? ($script_rev = $1) : ($script_rev = "-");
# print "\n$script_name -- version: $script_rev\n";
return $script_name;
}
############################################################################
sub parse_options #09.07.2007 08:13
############################################################################
{
# e exclude list file
# v verbose
my $filelist_filename = undef;
my $success = GetOptions('h' => \$opt_help,
'd=s' => \$opt_dir, 'e=s'=>\$opt_exclude, 'f=s'=>\$opt_pfxfile, 'l=s'=>\$opt_log,
'p=s'=>\$opt_pass,'v'=>\$opt_verbose, 't=s'=>\$opt_timestamp_url, 'i=s'=>\$filelist_filename);
if ( !$success || $opt_help ) {
usage();
exit(1);
}
if ( !$opt_exclude || !$opt_pfxfile || !$opt_pass || !$opt_timestamp_url) {
print "ERROR: Parameter missing!\n!";
usage();
exit(1);
}
# Read the names of files to sign from the given file.
die "no list of files given" unless defined $filelist_filename;
open my $in, $filelist_filename;
my @filelist = ();
while (<$in>)
{
chomp($_);
push @filelist, $_;
}
return @filelist;
} ##parse_options
############################################################################
sub get_exclude_files #09.07.2007 10:12
############################################################################
{
if ( -e $opt_exclude ) {
# get data from cache file
open( IN, "<$opt_exclude") || die "Can't open exclude file $opt_exclude\n";
while ( my $line = <IN> ) {
chomp($line);
$exclude_files{$line} = 1; # fill hash
print "$line - $exclude_files{$line}\n" if ($debug);
}
} else
{
print_error("Can't open $opt_exclude file!\n");
}
} ##get_exclude_files
############################################################################
sub get_files #10.07.2007 10:19
############################################################################
{
use File::Basename;
my $target = shift;
my $file_pattern;
my $file;
my @files = ();
print "\n";
foreach $file_pattern ( @$target )
{
print "Files: $file_pattern\n";
foreach $file ( glob( $file_pattern ) )
{
my $lib = File::Basename::basename $file;
if ( ! $exclude_files{$lib} ) {
push @files,$file;
}
else
{
print "exclude=$lib\n" if ($opt_verbose);
}
}
}
print "\n";
return @files;
} ##get_files
############################################################################
sub sign_files #09.07.2007 10:36
############################################################################
{
my $files_to_sign = shift;
my $commandline_base = ""; # contains whole stuff without the file name
my $file = "";
my $result = "";
print_error("Can't open PFX file: $opt_pfxfile\n") if ( ! -e $opt_pfxfile );
print_error("Password is empty\n") if ( !$opt_pass );
if ( $opt_pass =~ /\.exe$/ ) {
# get password by tool
open(PIPE, "$opt_pass 2>&1 |") || die "Can't open PIPE!\n";
my $pass = <PIPE>;
close PIPE;
print_error("Can't get password!\n") if ( !$pass ); # exit here
$opt_pass = $pass;
}
$signtool .= " -v" if ($opt_verbose);
$commandline_base = $signtool . " " . "-f $opt_pfxfile -p $opt_pass -t $opt_timestamp_url";
# Here switch between:
# one command line for muliple files (all doesn't work, too much) / for each file one command line
if ( $max_files > 1 ) {
exec_multi_sign($files_to_sign, $commandline_base);
} else
{
exec_single_sign($files_to_sign, $commandline_base);
}
} ##sign_files
############################################################################
sub exec_single_sign #11.07.2007 09:05
############################################################################
{
my $files_to_sign = shift;
my $commandline_base = shift; # contains whole stuff without the file name
my $file = "";
my $commandline = "";
foreach $file (@$files_to_sign)
{
$commandline = $commandline_base . " $file";
print "$commandline\n" if ($debug);
execute($commandline);
} #foreach
} ##exec_single_sign
############################################################################
sub exec_multi_sign #11.07.2007 08:56
############################################################################
{
# sign multiple file with one command line
my $files_to_sign = shift;
my $commandline_base = shift; # contains whole stuff without the file name
my $commandline = $commandline_base; # contains stuff which will be executed
my $file = "";
my $counter = 0;
foreach $file (@$files_to_sign)
{
$commandline .= " $file";
++$counter;
if ( $counter >= $max_files ) {
execute($commandline);
$counter = 0; # reset counter
$commandline = $commandline_base; # reset command line
}
}
execute($commandline) if ($counter > 0);
} ##exec_multi_sign
############################################################################
sub execute #11.07.2007 10:02
############################################################################
{
my $commandline = shift;
my $result = "";
print "$commandline\n" if ($debug);
open(PIPE, "$commandline 2>&1 |") || die "Error: Cant open pipe!\n";
while ( $result = <PIPE> ) {
print LOG "$result" if ($opt_log); # logging
if ( $result =~ /SignTool Error\:/ ) {
close PIPE;
print_error( "$result\n" );
} # if error
} # while
close PIPE;
} ##execute
############################################################################
sub print_error #09.07.2007 11:21
############################################################################
{
my $text = shift;
print "ERROR: $text\n";
print LOG "ERROR: $text\n" if ($opt_log); # logging
close LOG if ($opt_log); # logging
exit(1);
} ##print_error
############################################################################
sub usage #09.07.2007 08:39
############################################################################
{
print "Usage:\t $myname <-e filename> <-f filename> <-p password> <-t timestamp> <-i filename> [-l filename] [-v]\n";
print "Options:\n";
print "\t -e filename\t\t\tFile which contains a list of files which don't have to be signed.\n";
print "Mandatory.\n";
print "\t -f pfx_filename\t\t\"Personal Information Exchange\" file. ";
print "Mandatory.\n";
print "\t -p password\t\t\tPassword for \"Personal Information Exchange\" file. Mandatory.\n";
print "\t -t timestamp\t\t\tTimestamp URL e.g. \"http://timestamp.verisign.com/scripts/timstamp.dll\"\n";
print "\t -i filename\t\t\tName of the file that contains the names of files to sign.\"\n";
print "\t\t\t\t\tMandatory.\n";
print "\t -l log_filename\t\tFile for logging.\n";
print "\t -v\t\t\t\tVerbose.\n";
} ##usage