1: 2eval 'exec perl -wS $0 ${1+"$@"}' 3 if 0; 4# 5# This file is part of the LibreOffice project. 6# 7# This Source Code Form is subject to the terms of the Mozilla Public 8# License, v. 2.0. If a copy of the MPL was not distributed with this 9# file, You can obtain one at http://mozilla.org/MPL/2.0/. 10# 11# This file incorporates work covered by the following license notice: 12# 13# Licensed to the Apache Software Foundation (ASF) under one or more 14# contributor license agreements. See the NOTICE file distributed 15# with this work for additional information regarding copyright 16# ownership. The ASF licenses this file to you under the Apache 17# License, Version 2.0 (the "License"); you may not use this file 18# except in compliance with the License. You may obtain a copy of 19# the License at http://www.apache.org/licenses/LICENSE-2.0 . 20# 21 22use strict; 23use Getopt::Long; 24 25my $debug = 0; 26my $max_files = 400; # sign $max_files with one command line 27 28#### globals ##### 29my $myname = ""; 30my $opt_desc = ""; 31my $opt_exclude = ""; # file with a list of not signable dll and exe files 32my $opt_verbose = 0; 33my $opt_help = 0; 34my $opt_log = ""; # for logging 35my $opt_pass = ""; # password for signing 36my $opt_pfxfile = ""; # Personal Information Exchange file 37my $opt_timestamp_url = ""; # timestamp url 38my %exclude_files = (); # list of not signable dll and exe files 39my $signtool = "signtool.exe sign"; 40my @args = (); 41my @files_to_sign = (); 42 43#### main ##### 44$myname = script_id(); 45if ( $#ARGV < 2 ) { 46 usage(); 47 exit(1); 48} 49@args = parse_options(); 50get_exclude_files() if ($opt_exclude ne ""); 51@files_to_sign = get_files(\@args); 52if ( $opt_log ) { # logging 53 open(LOG,">$opt_log") || die "Can't open log file $opt_log\n"; 54} 55sign_files(\@files_to_sign); 56close LOG if ($opt_log); # logging 57exit 0; 58 59 60#### subroutines #### 61 62sub script_id 63{ 64 ( my $script_name = $0 ) =~ s/^.*[\\\/]([\w\.]+)$/$1/; 65 return $script_name; 66} 67 68############################################################################ 69sub parse_options #09.07.2007 08:13 70############################################################################ 71{ 72 # e exclude list file 73 # v verbose 74 my $success = GetOptions('h' => \$opt_help, 75 'd=s' => \$opt_desc, 'e=s'=>\$opt_exclude, 'f=s'=>\$opt_pfxfile, 'l=s'=>\$opt_log, 76 'p=s'=>\$opt_pass,'v'=>\$opt_verbose, 't=s'=>\$opt_timestamp_url); 77 if ( !$success || $opt_help ) { 78 usage(); 79 exit(1); 80 } 81 return @ARGV; 82} ##parse_options 83 84############################################################################ 85sub get_exclude_files #09.07.2007 10:12 86############################################################################ 87{ 88 if ( -e $opt_exclude ) { 89 # get data from cache file 90 open( IN, "<$opt_exclude") || die "Can't open exclude file $opt_exclude\n"; 91 while ( my $line = <IN> ) { 92 chomp($line); 93 $exclude_files{$line} = 1; # fill hash 94 print "$line - $exclude_files{$line}\n" if ($debug); 95 } 96 } else 97 { 98 print_error("Can't open $opt_exclude file!\n"); 99 } 100} ##get_exclude_files 101 102############################################################################ 103sub get_files #10.07.2007 10:19 104############################################################################ 105 { 106 use File::Basename; 107 my $target = shift; 108 my $file_pattern; 109 my $file; 110 my @files = (); 111 print "\n"; 112 foreach $file_pattern ( @$target ) 113 { 114 print "Files: $file_pattern\n"; 115 foreach $file ( glob( $file_pattern ) ) 116 { 117 my $lib = File::Basename::basename $file; 118 if ( ! $exclude_files{$lib} ) { 119 push @files,$file; 120 } 121 else 122 { 123 print "exclude=$lib\n" if ($opt_verbose); 124 } 125 } 126 } 127 print "\n"; 128 return @files; 129} ##get_files 130 131############################################################################ 132sub sign_files #09.07.2007 10:36 133############################################################################ 134{ 135 my $files_to_sign = shift; 136 my $commandline_base = ""; # contains whole stuff without the file name 137 my $file = ""; 138 my $result = ""; 139 140 if ( $opt_pass =~ /\.exe$/ ) { 141 # get password by tool 142 open(PIPE, "$opt_pass 2>&1 |") || die "Can't open PIPE!\n"; 143 my $pass = <PIPE>; 144 close PIPE; 145 print_error("Can't get password!\n") if ( !$pass ); # exit here 146 $opt_pass = $pass; 147 } 148 $signtool .= " -v" if ($opt_verbose); 149 $commandline_base = $signtool; 150 $commandline_base .= " -f $opt_pfxfile" if ($opt_pfxfile ne ""); 151 $commandline_base .= " -p $opt_pass" if ($opt_pass ne ""); 152 $commandline_base .= " -t $opt_timestamp_url" if ($opt_timestamp_url ne ""); 153 $commandline_base .= " -d \"$opt_desc\"" if ($opt_desc ne ""); 154 155 # Here switch between: 156 # one command line for multiple files (all doesn't work, too much) / for each file one command line 157 if ( $max_files > 1 ) { 158 exec_multi_sign($files_to_sign, $commandline_base); 159 } else 160 { 161 exec_single_sign($files_to_sign, $commandline_base); 162 } 163} ##sign_files 164 165############################################################################ 166sub exec_single_sign #11.07.2007 09:05 167############################################################################ 168{ 169 my $files_to_sign = shift; 170 my $commandline_base = shift; # contains whole stuff without the file name 171 my $file = ""; 172 my $commandline = ""; 173 174 foreach $file (@$files_to_sign) 175 { 176 $commandline = $commandline_base . " $file"; 177 print "$commandline\n" if ($debug); 178 execute($commandline); 179 } #foreach 180} ##exec_single_sign 181 182############################################################################ 183sub exec_multi_sign #11.07.2007 08:56 184############################################################################ 185 { 186 # sign multiple file with one command line 187 my $files_to_sign = shift; 188 my $commandline_base = shift; # contains whole stuff without the file name 189 my $commandline = $commandline_base; # contains stuff which will be executed 190 my $file = ""; 191 my $counter = 0; 192 193 foreach $file (@$files_to_sign) 194 { 195 $commandline .= " $file"; 196 ++$counter; 197 if ( $counter >= $max_files ) { 198 execute($commandline); 199 $counter = 0; # reset counter 200 $commandline = $commandline_base; # reset command line 201 } 202 } 203 execute($commandline) if ($counter > 0); 204} ##exec_multi_sign 205 206############################################################################ 207sub execute #11.07.2007 10:02 208############################################################################ 209{ 210 my $commandline = shift; 211 my $result = ""; 212 my $errorlines = ""; 213 214 print "$commandline\n" if ($debug); 215 open(PIPE, "$commandline 2>&1 |") || die "Error: Cannot execute '$commandline' - $!\n"; 216 while ( $result = <PIPE> ) { 217 print LOG "$result" if ($opt_log); 218 $errorlines .= $result if ($result =~ /SignTool Error\:/); 219 } # while 220 close PIPE; 221 print_error( "$errorlines\n" ) if ($errorlines); 222} ##execute 223 224############################################################################ 225sub print_error #09.07.2007 11:21 226############################################################################ 227 { 228 my $text = shift; 229 print "ERROR: $text\n"; 230 print LOG "ERROR: $text\n" if ($opt_log); # logging 231 close LOG if ($opt_log); # logging 232 exit(1); 233} ##print_error 234 235############################################################################ 236sub usage #09.07.2007 08:39 237############################################################################ 238 { 239 print "Usage:\t $myname [-e filename] [-f filename] [-p password] [-t timestamp] [-l filename] [-v] <file[list]> \n"; 240 print "Options:\n"; 241 print "\t -e filename\t\t\tFile which contains a list of files which don't have to be signed.\n"; 242 print "\t -f pfx_filename\t\t\"Personal Information Exchange\" file.\n"; 243 print "\t -p password\t\t\tPassword for \"Personal Information Exchange\" file.\n"; 244 print "\t -t timestamp\t\t\tTimestamp URL e.g. \"http://timestamp.verisign.com/scripts/timstamp.dll\"\n"; 245 print "\t -l log_filename\t\tFile for logging.\n"; 246 print "\t -v\t\t\t\tVerbose.\n"; 247} ##usage 248 249 250 251 252