xref: /aoo4110/main/postprocess/signing/signing.pl (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski:
2*b1cdbd2cSJim Jagielskieval 'exec perl -wS $0 ${1+"$@"}'
3*b1cdbd2cSJim Jagielski    if 0;
4*b1cdbd2cSJim Jagielski#**************************************************************
5*b1cdbd2cSJim Jagielski#
6*b1cdbd2cSJim Jagielski#  Licensed to the Apache Software Foundation (ASF) under one
7*b1cdbd2cSJim Jagielski#  or more contributor license agreements.  See the NOTICE file
8*b1cdbd2cSJim Jagielski#  distributed with this work for additional information
9*b1cdbd2cSJim Jagielski#  regarding copyright ownership.  The ASF licenses this file
10*b1cdbd2cSJim Jagielski#  to you under the Apache License, Version 2.0 (the
11*b1cdbd2cSJim Jagielski#  "License"); you may not use this file except in compliance
12*b1cdbd2cSJim Jagielski#  with the License.  You may obtain a copy of the License at
13*b1cdbd2cSJim Jagielski#
14*b1cdbd2cSJim Jagielski#    http://www.apache.org/licenses/LICENSE-2.0
15*b1cdbd2cSJim Jagielski#
16*b1cdbd2cSJim Jagielski#  Unless required by applicable law or agreed to in writing,
17*b1cdbd2cSJim Jagielski#  software distributed under the License is distributed on an
18*b1cdbd2cSJim Jagielski#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19*b1cdbd2cSJim Jagielski#  KIND, either express or implied.  See the License for the
20*b1cdbd2cSJim Jagielski#  specific language governing permissions and limitations
21*b1cdbd2cSJim Jagielski#  under the License.
22*b1cdbd2cSJim Jagielski#
23*b1cdbd2cSJim Jagielski#**************************************************************
24*b1cdbd2cSJim Jagielski
25*b1cdbd2cSJim Jagielski
26*b1cdbd2cSJim Jagielski
27*b1cdbd2cSJim Jagielskiuse strict;
28*b1cdbd2cSJim Jagielskiuse Getopt::Long;
29*b1cdbd2cSJim Jagielski
30*b1cdbd2cSJim Jagielskimy $debug = 0;
31*b1cdbd2cSJim Jagielskimy $max_files = 20; 		  # sign $max_files with one command line
32*b1cdbd2cSJim Jagielski
33*b1cdbd2cSJim Jagielski#### globals #####
34*b1cdbd2cSJim Jagielskimy $myname 		= "";
35*b1cdbd2cSJim Jagielskimy $opt_dir 	= "";
36*b1cdbd2cSJim Jagielskimy $opt_exclude = "";         # file with a list of not signable dll and exe files
37*b1cdbd2cSJim Jagielskimy $opt_verbose = 0;
38*b1cdbd2cSJim Jagielskimy $opt_help	= 0;
39*b1cdbd2cSJim Jagielskimy $opt_log		= "";		  # for logging
40*b1cdbd2cSJim Jagielskimy $opt_pass	= "";         # password for signing
41*b1cdbd2cSJim Jagielskimy $opt_pfxfile = "";		  # Personal Information Exchange file
42*b1cdbd2cSJim Jagielskimy $opt_timestamp_url = "";   # timestamp url
43*b1cdbd2cSJim Jagielskimy %exclude_files = ();  	  # list of not signable dll and exe files
44*b1cdbd2cSJim Jagielskimy $signtool    = "signtool.exe sign";
45*b1cdbd2cSJim Jagielskimy @args		= ();
46*b1cdbd2cSJim Jagielskimy @files_to_sign = ();
47*b1cdbd2cSJim Jagielski
48*b1cdbd2cSJim Jagielski#### main #####
49*b1cdbd2cSJim Jagielski$myname = script_id();
50*b1cdbd2cSJim Jagielskiif ( $#ARGV < 2 ) {
51*b1cdbd2cSJim Jagielski	usage();
52*b1cdbd2cSJim Jagielski    exit(1);
53*b1cdbd2cSJim Jagielski}
54*b1cdbd2cSJim Jagielski@args = parse_options();
55*b1cdbd2cSJim Jagielskiget_exclude_files();
56*b1cdbd2cSJim Jagielski@files_to_sign = get_files(\@args);
57*b1cdbd2cSJim Jagielskiif ( $opt_log ) {               # logging
58*b1cdbd2cSJim Jagielski	open(LOG,">$opt_log") || die "Can't open log file $opt_log\n";
59*b1cdbd2cSJim Jagielski}
60*b1cdbd2cSJim Jagielskisign_files(\@files_to_sign);
61*b1cdbd2cSJim Jagielskiclose LOG if ($opt_log);        # logging
62*b1cdbd2cSJim Jagielskiexit 0;
63*b1cdbd2cSJim Jagielski
64*b1cdbd2cSJim Jagielski
65*b1cdbd2cSJim Jagielski#### subroutines ####
66*b1cdbd2cSJim Jagielski
67*b1cdbd2cSJim Jagielskisub script_id
68*b1cdbd2cSJim Jagielski{
69*b1cdbd2cSJim Jagielski    ( my $script_name = $0 ) =~ s/^.*[\\\/]([\w\.]+)$/$1/;
70*b1cdbd2cSJim Jagielski
71*b1cdbd2cSJim Jagielski    my $script_rev;
72*b1cdbd2cSJim Jagielski    my $id_str = ' $Revision$ ';
73*b1cdbd2cSJim Jagielski    $id_str =~ /Revision:\s+(\S+)\s+\$/
74*b1cdbd2cSJim Jagielski      ? ($script_rev = $1) : ($script_rev = "-");
75*b1cdbd2cSJim Jagielski#    print "\n$script_name -- version: $script_rev\n";
76*b1cdbd2cSJim Jagielski    return $script_name;
77*b1cdbd2cSJim Jagielski}
78*b1cdbd2cSJim Jagielski
79*b1cdbd2cSJim Jagielski############################################################################
80*b1cdbd2cSJim Jagielskisub parse_options		#09.07.2007 08:13
81*b1cdbd2cSJim Jagielski############################################################################
82*b1cdbd2cSJim Jagielski{
83*b1cdbd2cSJim Jagielski	# e exclude list file
84*b1cdbd2cSJim Jagielski	# v verbose
85*b1cdbd2cSJim Jagielski    my $filelist_filename = undef;
86*b1cdbd2cSJim Jagielski	my $success = GetOptions('h' => \$opt_help,
87*b1cdbd2cSJim Jagielski         'd=s' => \$opt_dir, 'e=s'=>\$opt_exclude, 'f=s'=>\$opt_pfxfile, 'l=s'=>\$opt_log,
88*b1cdbd2cSJim Jagielski		 'p=s'=>\$opt_pass,'v'=>\$opt_verbose, 't=s'=>\$opt_timestamp_url, 'i=s'=>\$filelist_filename);
89*b1cdbd2cSJim Jagielski    if ( !$success || $opt_help ) {
90*b1cdbd2cSJim Jagielski        usage();
91*b1cdbd2cSJim Jagielski        exit(1);
92*b1cdbd2cSJim Jagielski    }
93*b1cdbd2cSJim Jagielski	if ( !$opt_exclude || !$opt_pfxfile || !$opt_pass || !$opt_timestamp_url) {
94*b1cdbd2cSJim Jagielski		print "ERROR: Parameter missing!\n!";
95*b1cdbd2cSJim Jagielski        usage();
96*b1cdbd2cSJim Jagielski        exit(1);
97*b1cdbd2cSJim Jagielski	}
98*b1cdbd2cSJim Jagielski
99*b1cdbd2cSJim Jagielski    # Read the names of files to sign from the given file.
100*b1cdbd2cSJim Jagielski    die "no list of files given" unless defined $filelist_filename;
101*b1cdbd2cSJim Jagielski    open my $in, $filelist_filename;
102*b1cdbd2cSJim Jagielski    my @filelist = ();
103*b1cdbd2cSJim Jagielski    while (<$in>)
104*b1cdbd2cSJim Jagielski    {
105*b1cdbd2cSJim Jagielski        chomp($_);
106*b1cdbd2cSJim Jagielski        push @filelist, $_;
107*b1cdbd2cSJim Jagielski    }
108*b1cdbd2cSJim Jagielski	return @filelist;
109*b1cdbd2cSJim Jagielski}	##parse_options
110*b1cdbd2cSJim Jagielski
111*b1cdbd2cSJim Jagielski############################################################################
112*b1cdbd2cSJim Jagielskisub get_exclude_files		#09.07.2007 10:12
113*b1cdbd2cSJim Jagielski############################################################################
114*b1cdbd2cSJim Jagielski{
115*b1cdbd2cSJim Jagielski	if ( -e $opt_exclude ) {
116*b1cdbd2cSJim Jagielski            # get data from cache file
117*b1cdbd2cSJim Jagielski            open( IN, "<$opt_exclude") || die "Can't open exclude file $opt_exclude\n";
118*b1cdbd2cSJim Jagielski            while ( my $line = <IN> ) {
119*b1cdbd2cSJim Jagielski			chomp($line);
120*b1cdbd2cSJim Jagielski			$exclude_files{$line} = 1;			# fill hash
121*b1cdbd2cSJim Jagielski			print "$line - $exclude_files{$line}\n" if ($debug);
122*b1cdbd2cSJim Jagielski            }
123*b1cdbd2cSJim Jagielski        } else
124*b1cdbd2cSJim Jagielski        {
125*b1cdbd2cSJim Jagielski			print_error("Can't open $opt_exclude file!\n");
126*b1cdbd2cSJim Jagielski		}
127*b1cdbd2cSJim Jagielski}	##get_exclude_files
128*b1cdbd2cSJim Jagielski
129*b1cdbd2cSJim Jagielski############################################################################
130*b1cdbd2cSJim Jagielskisub get_files		#10.07.2007 10:19
131*b1cdbd2cSJim Jagielski############################################################################
132*b1cdbd2cSJim Jagielski {
133*b1cdbd2cSJim Jagielski	use File::Basename;
134*b1cdbd2cSJim Jagielski    my $target = shift;
135*b1cdbd2cSJim Jagielski	my $file_pattern;
136*b1cdbd2cSJim Jagielski	my $file;
137*b1cdbd2cSJim Jagielski	my @files = ();
138*b1cdbd2cSJim Jagielski	print "\n";
139*b1cdbd2cSJim Jagielski	foreach $file_pattern ( @$target )
140*b1cdbd2cSJim Jagielski	{
141*b1cdbd2cSJim Jagielski		print "Files: $file_pattern\n";
142*b1cdbd2cSJim Jagielski        foreach $file ( glob( $file_pattern ) )
143*b1cdbd2cSJim Jagielski		{
144*b1cdbd2cSJim Jagielski            my $lib = File::Basename::basename $file;
145*b1cdbd2cSJim Jagielski			if ( ! $exclude_files{$lib} ) {
146*b1cdbd2cSJim Jagielski				push @files,$file;
147*b1cdbd2cSJim Jagielski			}
148*b1cdbd2cSJim Jagielski			else
149*b1cdbd2cSJim Jagielski			{
150*b1cdbd2cSJim Jagielski				print "exclude=$lib\n" if ($opt_verbose);
151*b1cdbd2cSJim Jagielski			}
152*b1cdbd2cSJim Jagielski		}
153*b1cdbd2cSJim Jagielski	}
154*b1cdbd2cSJim Jagielski	print "\n";
155*b1cdbd2cSJim Jagielski	return @files;
156*b1cdbd2cSJim Jagielski}	##get_files
157*b1cdbd2cSJim Jagielski
158*b1cdbd2cSJim Jagielski############################################################################
159*b1cdbd2cSJim Jagielskisub sign_files		#09.07.2007 10:36
160*b1cdbd2cSJim Jagielski############################################################################
161*b1cdbd2cSJim Jagielski{
162*b1cdbd2cSJim Jagielski	my $files_to_sign = shift;
163*b1cdbd2cSJim Jagielski	my $commandline_base = ""; # contains whole stuff without the file name
164*b1cdbd2cSJim Jagielski	my $file = "";
165*b1cdbd2cSJim Jagielski	my $result = "";
166*b1cdbd2cSJim Jagielski
167*b1cdbd2cSJim Jagielski	print_error("Can't open PFX file: $opt_pfxfile\n") if ( ! -e $opt_pfxfile );
168*b1cdbd2cSJim Jagielski	print_error("Password is empty\n") if ( !$opt_pass );
169*b1cdbd2cSJim Jagielski	if ( $opt_pass =~ /\.exe$/ ) {
170*b1cdbd2cSJim Jagielski		# get password by tool
171*b1cdbd2cSJim Jagielski		open(PIPE, "$opt_pass 2>&1 |") || die "Can't open PIPE!\n";
172*b1cdbd2cSJim Jagielski		my $pass = <PIPE>;
173*b1cdbd2cSJim Jagielski		close PIPE;
174*b1cdbd2cSJim Jagielski		print_error("Can't get password!\n") if ( !$pass ); # exit here
175*b1cdbd2cSJim Jagielski		$opt_pass = $pass;
176*b1cdbd2cSJim Jagielski	}
177*b1cdbd2cSJim Jagielski	$signtool .= " -v" if ($opt_verbose);
178*b1cdbd2cSJim Jagielski	$commandline_base = $signtool . " " . "-f $opt_pfxfile -p $opt_pass -t $opt_timestamp_url";
179*b1cdbd2cSJim Jagielski
180*b1cdbd2cSJim Jagielski	# Here switch between:
181*b1cdbd2cSJim Jagielski	# one command line for muliple files (all doesn't work, too much) / for each file one command line
182*b1cdbd2cSJim Jagielski	if ( $max_files > 1 ) {
183*b1cdbd2cSJim Jagielski		exec_multi_sign($files_to_sign, $commandline_base);
184*b1cdbd2cSJim Jagielski	} else
185*b1cdbd2cSJim Jagielski	{
186*b1cdbd2cSJim Jagielski		exec_single_sign($files_to_sign, $commandline_base);
187*b1cdbd2cSJim Jagielski	}
188*b1cdbd2cSJim Jagielski}	##sign_files
189*b1cdbd2cSJim Jagielski
190*b1cdbd2cSJim Jagielski############################################################################
191*b1cdbd2cSJim Jagielskisub exec_single_sign		#11.07.2007 09:05
192*b1cdbd2cSJim Jagielski############################################################################
193*b1cdbd2cSJim Jagielski{
194*b1cdbd2cSJim Jagielski	my $files_to_sign    = shift;
195*b1cdbd2cSJim Jagielski	my $commandline_base = shift; 				  # contains whole stuff without the file name
196*b1cdbd2cSJim Jagielski	my $file = "";
197*b1cdbd2cSJim Jagielski	my $commandline = "";
198*b1cdbd2cSJim Jagielski
199*b1cdbd2cSJim Jagielski	foreach $file (@$files_to_sign)
200*b1cdbd2cSJim Jagielski	{
201*b1cdbd2cSJim Jagielski		$commandline = $commandline_base . " $file";
202*b1cdbd2cSJim Jagielski		print "$commandline\n" if ($debug);
203*b1cdbd2cSJim Jagielski		execute($commandline);
204*b1cdbd2cSJim Jagielski	} #foreach
205*b1cdbd2cSJim Jagielski}	##exec_single_sign
206*b1cdbd2cSJim Jagielski
207*b1cdbd2cSJim Jagielski############################################################################
208*b1cdbd2cSJim Jagielskisub exec_multi_sign		#11.07.2007 08:56
209*b1cdbd2cSJim Jagielski############################################################################
210*b1cdbd2cSJim Jagielski {
211*b1cdbd2cSJim Jagielski	# sign multiple file with one command line
212*b1cdbd2cSJim Jagielski	my $files_to_sign    = shift;
213*b1cdbd2cSJim Jagielski	my $commandline_base = shift; 				  # contains whole stuff without the file name
214*b1cdbd2cSJim Jagielski	my $commandline = $commandline_base;	      # contains stuff which will be executed
215*b1cdbd2cSJim Jagielski	my $file = "";
216*b1cdbd2cSJim Jagielski	my $counter = 0;
217*b1cdbd2cSJim Jagielski
218*b1cdbd2cSJim Jagielski	foreach $file (@$files_to_sign)
219*b1cdbd2cSJim Jagielski	{
220*b1cdbd2cSJim Jagielski		$commandline .= " $file";
221*b1cdbd2cSJim Jagielski		++$counter;
222*b1cdbd2cSJim Jagielski		if ( $counter >= $max_files ) {
223*b1cdbd2cSJim Jagielski			execute($commandline);
224*b1cdbd2cSJim Jagielski			$counter = 0;						 # reset counter
225*b1cdbd2cSJim Jagielski			$commandline = $commandline_base;    # reset command line
226*b1cdbd2cSJim Jagielski		}
227*b1cdbd2cSJim Jagielski	}
228*b1cdbd2cSJim Jagielski	execute($commandline) if ($counter > 0);
229*b1cdbd2cSJim Jagielski}	##exec_multi_sign
230*b1cdbd2cSJim Jagielski
231*b1cdbd2cSJim Jagielski############################################################################
232*b1cdbd2cSJim Jagielskisub execute		#11.07.2007 10:02
233*b1cdbd2cSJim Jagielski############################################################################
234*b1cdbd2cSJim Jagielski{
235*b1cdbd2cSJim Jagielski	my $commandline = shift;
236*b1cdbd2cSJim Jagielski	my $result = "";
237*b1cdbd2cSJim Jagielski
238*b1cdbd2cSJim Jagielski  	print "$commandline\n" if ($debug);
239*b1cdbd2cSJim Jagielski  	open(PIPE, "$commandline 2>&1 |") || die "Error: Cant open pipe!\n";
240*b1cdbd2cSJim Jagielski  	while ( $result = <PIPE> ) {
241*b1cdbd2cSJim Jagielski  		print LOG "$result" if ($opt_log);        # logging
242*b1cdbd2cSJim Jagielski  		if ( $result =~ /SignTool Error\:/ ) {
243*b1cdbd2cSJim Jagielski			close PIPE;
244*b1cdbd2cSJim Jagielski  			print_error( "$result\n" );
245*b1cdbd2cSJim Jagielski  		} # if error
246*b1cdbd2cSJim Jagielski  	} # while
247*b1cdbd2cSJim Jagielski  	close PIPE;
248*b1cdbd2cSJim Jagielski}	##execute
249*b1cdbd2cSJim Jagielski
250*b1cdbd2cSJim Jagielski############################################################################
251*b1cdbd2cSJim Jagielskisub print_error		#09.07.2007 11:21
252*b1cdbd2cSJim Jagielski############################################################################
253*b1cdbd2cSJim Jagielski {
254*b1cdbd2cSJim Jagielski	my $text = shift;
255*b1cdbd2cSJim Jagielski	print "ERROR: $text\n";
256*b1cdbd2cSJim Jagielski	print LOG "ERROR: $text\n" if ($opt_log);        # logging
257*b1cdbd2cSJim Jagielski	close LOG if ($opt_log);        				 # logging
258*b1cdbd2cSJim Jagielski	exit(1);
259*b1cdbd2cSJim Jagielski}	##print_error
260*b1cdbd2cSJim Jagielski
261*b1cdbd2cSJim Jagielski############################################################################
262*b1cdbd2cSJim Jagielskisub usage		#09.07.2007 08:39
263*b1cdbd2cSJim Jagielski############################################################################
264*b1cdbd2cSJim Jagielski {
265*b1cdbd2cSJim Jagielski	print "Usage:\t $myname <-e filename> <-f filename> <-p password> <-t timestamp> <-i filename> [-l filename] [-v]\n";
266*b1cdbd2cSJim Jagielski    print "Options:\n";
267*b1cdbd2cSJim Jagielski	print "\t -e filename\t\t\tFile which contains a list of files which don't have to be signed.\n";
268*b1cdbd2cSJim Jagielski    print                            "Mandatory.\n";
269*b1cdbd2cSJim Jagielski    print "\t -f pfx_filename\t\t\"Personal Information Exchange\" file. ";
270*b1cdbd2cSJim Jagielski    print                            "Mandatory.\n";
271*b1cdbd2cSJim Jagielski    print "\t -p password\t\t\tPassword for \"Personal Information Exchange\" file. Mandatory.\n";
272*b1cdbd2cSJim Jagielski    print "\t -t timestamp\t\t\tTimestamp URL e.g. \"http://timestamp.verisign.com/scripts/timstamp.dll\"\n";
273*b1cdbd2cSJim Jagielski    print "\t -i filename\t\t\tName of the file that contains the names of files to sign.\"\n";
274*b1cdbd2cSJim Jagielski    print "\t\t\t\t\tMandatory.\n";
275*b1cdbd2cSJim Jagielski	print "\t -l log_filename\t\tFile for logging.\n";
276*b1cdbd2cSJim Jagielski    print "\t -v\t\t\t\tVerbose.\n";
277*b1cdbd2cSJim Jagielski}	##usage
278