@@ -89,52 +89,78 @@ foreach (@dirlist) {
8989 }
9090}
9191
92+ sub copy_file {
93+ my ($src_fname , $dst_fname ) = @_ ;
94+
95+ if (open (my $in , " <" , $src_fname )) {
96+ if (open (my $out , " >" , $dst_fname )) {
97+ print $out $_ while (<$in >);
98+ close $out ;
99+ } else {
100+ warn " Cannot open $dst_fname for write, $! " ;
101+ }
102+ close $in ;
103+ } else {
104+ warn " Cannot open $src_fname for read, $! " ;
105+ }
106+ }
107+
92108sub hash_dir {
93- my %hashlist ;
94- print " Doing $_ [0]\n " ;
95- chdir $_ [0];
96- opendir (DIR, " ." );
97- my @flist = readdir (DIR);
98- closedir DIR;
99- if ( $removelinks ) {
100- # Delete any existing symbolic links
101- foreach (grep {/ ^[\d a-f]+\. r{0,1}\d +$ / } @flist ) {
102- if (-l $_ ) {
103- unlink $_ ;
104- print " unlink $_ " if $verbose ;
105- }
106- }
107- }
108- FILE: foreach $fname (grep {/ \. (pem)|(crt)|(cer)|(crl)$ / } @flist ) {
109- # Check to see if certificates and/or CRLs present.
110- my ($cert , $crl ) = check_file($fname );
111- if (!$cert && !$crl ) {
112- print STDERR " WARNING: $fname does not contain a certificate or CRL: skipping\n " ;
113- next ;
114- }
115- link_hash_cert($fname ) if ($cert );
116- link_hash_crl($fname ) if ($crl );
117- }
109+ my $dir = shift ;
110+ my %hashlist ;
111+
112+ print " Doing $dir \n " ;
113+
114+ if (!chdir $dir ) {
115+ print STDERR " WARNING: Cannot chdir to '$dir ', $! \n " ;
116+ return ;
117+ }
118+
119+ opendir (DIR, " ." ) || print STDERR " WARNING: Cannot opendir '.', $! \n " ;
120+ my @flist = sort readdir (DIR);
121+ closedir DIR;
122+ if ( $removelinks ) {
123+ # Delete any existing symbolic links
124+ foreach (grep {/ ^[\d a-f]+\. r{0,1}\d +$ / } @flist ) {
125+ if (-l $_ ) {
126+ print " unlink $_ \n " if $verbose ;
127+ unlink $_ || warn " Can't unlink $_ , $! \n " ;
128+ }
129+ }
130+ }
131+ FILE: foreach $fname (grep {/ \. (pem)|(crt)|(cer)|(crl)$ / } @flist ) {
132+ # Check to see if certificates and/or CRLs present.
133+ my ($cert , $crl ) = check_file($fname );
134+ if (!$cert && !$crl ) {
135+ print STDERR " WARNING: $fname does not contain a certificate or CRL: skipping\n " ;
136+ next ;
137+ }
138+ link_hash_cert($fname ) if ($cert );
139+ link_hash_crl($fname ) if ($crl );
140+ }
141+
142+ chdir $pwd ;
118143}
119144
120145sub check_file {
121- my ($is_cert , $is_crl ) = (0,0);
122- my $fname = $_ [0];
123- open IN, $fname ;
124- while (<IN>) {
125- if (/ ^-----BEGIN (.*)-----/ ) {
126- my $hdr = $1 ;
127- if ($hdr =~ / ^(X509 |TRUSTED |)CERTIFICATE$ / ) {
128- $is_cert = 1;
129- last if ($is_crl );
130- } elsif ($hdr eq " X509 CRL" ) {
131- $is_crl = 1;
132- last if ($is_cert );
133- }
134- }
135- }
136- close IN;
137- return ($is_cert , $is_crl );
146+ my ($is_cert , $is_crl ) = (0,0);
147+ my $fname = $_ [0];
148+
149+ open (my $in , " <" , $fname );
150+ while (<$in >) {
151+ if (/ ^-----BEGIN (.*)-----/ ) {
152+ my $hdr = $1 ;
153+ if ($hdr =~ / ^(X509 |TRUSTED |)CERTIFICATE$ / ) {
154+ $is_cert = 1;
155+ last if ($is_crl );
156+ } elsif ($hdr eq " X509 CRL" ) {
157+ $is_crl = 1;
158+ last if ($is_cert );
159+ }
160+ }
161+ }
162+ close $in ;
163+ return ($is_cert , $is_crl );
138164}
139165
140166sub compute_hash {
@@ -162,70 +188,49 @@ sub compute_hash {
162188# certificate fingerprints
163189
164190sub link_hash_cert {
165- my $fname = $_ [0];
166- my ($hash , $fprint ) = compute_hash($openssl , " x509" , $x509hash ,
167- " -fingerprint" , " -noout" ,
168- " -in" , $fname );
169- chomp $hash ;
170- chomp $fprint ;
171- return if !$hash ;
172- $fprint =~ s / ^.*=// ;
173- $fprint =~ tr / :// d;
174- my $suffix = 0;
175- # Search for an unused hash filename
176- while (exists $hashlist {" $hash .$suffix " }) {
177- # Hash matches: if fingerprint matches its a duplicate cert
178- if ($hashlist {" $hash .$suffix " } eq $fprint ) {
179- print STDERR " WARNING: Skipping duplicate certificate $fname \n " ;
180- return ;
181- }
182- $suffix ++;
183- }
184- $hash .= " .$suffix " ;
185- if ($symlink_exists ) {
186- symlink $fname , $hash ;
187- print " link $fname -> $hash \n " if $verbose ;
188- } else {
189- open IN," <$fname " or die " can't open $fname for read" ;
190- open OUT," >$hash " or die " can't open $hash for write" ;
191- print OUT <IN>; # does the job for small text files
192- close OUT;
193- close IN;
194- print " copy $fname -> $hash \n " if $verbose ;
195- }
196- $hashlist {$hash } = $fprint ;
191+ link_hash($_ [0], ' cert' );
197192}
198193
199194# Same as above except for a CRL. CRL links are of the form <hash>.r<n>
200195
201196sub link_hash_crl {
202- my $fname = $_ [0];
203- my ($hash , $fprint ) = compute_hash($openssl , " crl" , $crlhash ,
204- " -fingerprint" , " -noout" ,
205- " -in" , $fname );
206- chomp $hash ;
207- chomp $fprint ;
208- return if !$hash ;
209- $fprint =~ s / ^.*=// ;
210- $fprint =~ tr / :// d;
211- my $suffix = 0;
212- # Search for an unused hash filename
213- while (exists $hashlist {" $hash .r$suffix " }) {
214- # Hash matches: if fingerprint matches its a duplicate cert
215- if ($hashlist {" $hash .r$suffix " } eq $fprint ) {
216- print STDERR " WARNING: Skipping duplicate CRL $fname \n " ;
217- return ;
218- }
219- $suffix ++;
220- }
221- $hash .= " .r$suffix " ;
222- if ($symlink_exists ) {
223- symlink $fname , $hash ;
224- print " link $fname -> $hash \n " if $verbose ;
225- } else {
226- system (" cp" , $fname , $hash );
227- print " cp $fname -> $hash \n " if $verbose ;
228- }
229- $hashlist {$hash } = $fprint ;
197+ link_hash($_ [0], ' crl' );
198+ }
199+
200+ sub link_hash {
201+ my ($fname , $type ) = @_ ;
202+ my $is_cert = $type eq ' cert' ;
203+
204+ my ($hash , $fprint ) = compute_hash($openssl ,
205+ $is_cert ? " x509" : " crl" ,
206+ $is_cert ? $x509hash : $crlhash ,
207+ " -fingerprint" , " -noout" ,
208+ " -in" , $fname );
209+ chomp $hash ;
210+ chomp $fprint ;
211+ return if !$hash ;
212+ $fprint =~ s / ^.*=// ;
213+ $fprint =~ tr / :// d;
214+ my $suffix = 0;
215+ # Search for an unused hash filename
216+ my $crlmark = $is_cert ? " " : " r" ;
217+ while (exists $hashlist {" $hash .$crlmark$suffix " }) {
218+ # Hash matches: if fingerprint matches its a duplicate cert
219+ if ($hashlist {" $hash .$crlmark$suffix " } eq $fprint ) {
220+ my $what = $is_cert ? ' certificate' : ' CRL' ;
221+ print STDERR " WARNING: Skipping duplicate $what $fname \n " ;
222+ return ;
223+ }
224+ $suffix ++;
225+ }
226+ $hash .= " .$crlmark$suffix " ;
227+ if ($symlink_exists ) {
228+ print " link $fname -> $hash \n " if $verbose ;
229+ symlink $fname , $hash || warn " Can't symlink, $! " ;
230+ } else {
231+ print " copy $fname -> $hash \n " if $verbose ;
232+ copy_file($fname , $hash );
233+ }
234+ $hashlist {$hash } = $fprint ;
230235}
231236
0 commit comments