summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/rehash.c4
-rw-r--r--doc/apps/rehash.pod22
-rw-r--r--tools/c_rehash.in64
3 files changed, 55 insertions, 35 deletions
diff --git a/apps/rehash.c b/apps/rehash.c
index 8417449235..b0d6d9cc13 100644
--- a/apps/rehash.c
+++ b/apps/rehash.c
@@ -313,6 +313,10 @@ static int do_dir(const char *dirname, enum Hash h)
const char *filename;
char *buf;
+ if (app_access(dirname, W_OK) < 0) {
+ BIO_printf(bio_err, "Skipping %s, can't write\n", dirname);
+ return 0;
+ }
buflen = strlen(dirname);
pathsep = (buflen && dirname[buflen - 1] == '/') ? "" : "/";
buflen += NAME_MAX + 2;
diff --git a/doc/apps/rehash.pod b/doc/apps/rehash.pod
index 00ab29b140..6c8c6074d0 100644
--- a/doc/apps/rehash.pod
+++ b/doc/apps/rehash.pod
@@ -23,7 +23,8 @@ I<flags...>
=head1 DESCRIPTION
On some platforms, the OpenSSL B<rehash> command is available as
-an external script called B<c_rehash>. They are functionally equivalent.
+an external script called B<c_rehash>. They are functionally equivalent,
+except for minor differences noted below.
B<rehash> scans directories and calculates a hash value of each
C<.pem>, C<.crt>, C<.cer>, or C<.crl>
@@ -41,12 +42,13 @@ If that is not set then the default directory (installation-specific
but often B</usr/local/ssl/certs>) is processed.
In order for a directory to be processed, the user must have write
-permissions on that directory, otherwise it will be skipped.
+permissions on that directory, otherwise an error will be generated.
+
The links created are of the form C<HHHHHHHH.D>, where each B<H>
is a hexadecimal character and B<D> is a single decimal digit.
When processing a directory, B<rehash> will first remove all links
-that have a name in that syntax. If you have links in that format
-used for other purposes, they will be removed.
+that have a name in that syntax, even if they are being used for some
+other purpose.
To skip the removal step, use the B<-n> flag.
Hashes for CRL's look similar except the letter B<r> appears after
the period, like this: C<HHHHHHHH.rD>.
@@ -57,9 +59,13 @@ full SHA-1 fingerprint. A warning will be displayed if a duplicate
is found.
A warning will also be displayed if there are files that
-cannot be parsed as either a certificate or a CRL.
+cannot be parsed as either a certificate or a CRL or if
+more than one such object appears in the file.
+
+=head2 Script Configuration
-The program uses the B<openssl> program to compute the hashes and
+The B<c_rehash> script
+uses the B<openssl> program to compute the hashes and
fingerprints. If not found in the user's B<PATH>, then set the
B<OPENSSL> environment variable to the full pathname.
Any program can be used, it will be invoked as follows for either
@@ -79,8 +85,8 @@ optionally prefixed with some text and an equals sign.
=item B<-old>
Use old-style hashing (MD5, as opposed to SHA-1) for generating
-links for releases before 1.0.0. Note that current versions will
-not use the old style.
+links to be used for releases before 1.0.0.
+Note that current versions will not use the old style.
=item B<-h>
diff --git a/tools/c_rehash.in b/tools/c_rehash.in
index b086ff9cf0..6c2ff065d1 100644
--- a/tools/c_rehash.in
+++ b/tools/c_rehash.in
@@ -54,24 +54,24 @@ if (defined(&Cwd::getcwd)) {
my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':';
$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : "");
-if(! -x $openssl) {
+if (! -x $openssl) {
my $found = 0;
foreach (split /$path_delim/, $ENV{PATH}) {
- if(-x "$_/$openssl") {
+ if (-x "$_/$openssl") {
$found = 1;
$openssl = "$_/$openssl";
last;
}
}
- if($found == 0) {
+ if ($found == 0) {
print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
exit 0;
}
}
-if(@ARGV) {
+if (@ARGV) {
@dirlist = @ARGV;
-} elsif($ENV{SSL_CERT_DIR}) {
+} elsif ($ENV{SSL_CERT_DIR}) {
@dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR};
} else {
$dirlist[0] = "$dir/certs";
@@ -84,8 +84,12 @@ if (-d $dirlist[0]) {
}
foreach (@dirlist) {
- if(-d $_ and -w $_) {
+ if (-d $_ ) {
+ if ( -w $_) {
hash_dir($_);
+ } else {
+ print "Skipping $_, can't write\n";
+ }
}
}
@@ -99,21 +103,21 @@ sub hash_dir {
if ( $removelinks ) {
# Delete any existing symbolic links
foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
- if(-l $_) {
- unlink $_;
+ if (-l $_) {
print "unlink $_" if $verbose;
+ unlink $_ || warn "Can't unlink $_, $!\n";
}
}
}
FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) {
# Check to see if certificates and/or CRLs present.
my ($cert, $crl) = check_file($fname);
- if(!$cert && !$crl) {
+ if (!$cert && !$crl) {
print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
next;
}
- link_hash_cert($fname) if($cert);
- link_hash_crl($fname) if($crl);
+ link_hash_cert($fname) if ($cert);
+ link_hash_crl($fname) if ($crl);
}
}
@@ -122,14 +126,14 @@ sub check_file {
my $fname = $_[0];
open IN, $fname;
while(<IN>) {
- if(/^-----BEGIN (.*)-----/) {
+ if (/^-----BEGIN (.*)-----/) {
my $hdr = $1;
- if($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
+ if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
$is_cert = 1;
- last if($is_crl);
- } elsif($hdr eq "X509 CRL") {
+ last if ($is_crl);
+ } elsif ($hdr eq "X509 CRL") {
$is_crl = 1;
- last if($is_cert);
+ last if ($is_cert);
}
}
}
@@ -156,7 +160,7 @@ sub link_hash_cert {
# Search for an unused hash filename
while(exists $hashlist{"$hash.$suffix"}) {
# Hash matches: if fingerprint matches its a duplicate cert
- if($hashlist{"$hash.$suffix"} eq $fprint) {
+ if ($hashlist{"$hash.$suffix"} eq $fprint) {
print STDERR "WARNING: Skipping duplicate certificate $fname\n";
return;
}
@@ -164,15 +168,21 @@ sub link_hash_cert {
}
$hash .= ".$suffix";
if ($symlink_exists) {
- symlink $fname, $hash;
print "link $fname -> $hash\n" if $verbose;
+ symlink $fname, $hash || warn "Can't symlink, $!";
} else {
- open IN,"<$fname" or die "can't open $fname for read";
- open OUT,">$hash" or die "can't open $hash for write";
- print OUT <IN>; # does the job for small text files
- close OUT;
- close IN;
print "copy $fname -> $hash\n" if $verbose;
+ if (open($in, "<", $fname)) {
+ if (open($out,">", $hash)) {
+ print $out $_ while (<$in>);
+ close $out;
+ } else {
+ warn "can't open $hash for write, $!";
+ }
+ close $in;
+ } else {
+ warn "can't open $fname for read, $!";
+ }
}
$hashlist{$hash} = $fprint;
}
@@ -191,7 +201,7 @@ sub link_hash_crl {
# Search for an unused hash filename
while(exists $hashlist{"$hash.r$suffix"}) {
# Hash matches: if fingerprint matches its a duplicate cert
- if($hashlist{"$hash.r$suffix"} eq $fprint) {
+ if ($hashlist{"$hash.r$suffix"} eq $fprint) {
print STDERR "WARNING: Skipping duplicate CRL $fname\n";
return;
}
@@ -199,12 +209,12 @@ sub link_hash_crl {
}
$hash .= ".r$suffix";
if ($symlink_exists) {
- symlink $fname, $hash;
print "link $fname -> $hash\n" if $verbose;
+ symlink $fname, $hash || warn "Can't symlink, $!";
} else {
- system ("cp", $fname, $hash);
print "cp $fname -> $hash\n" if $verbose;
+ system ("cp", $fname, $hash);
+ warn "Can't copy, $!" if ($? >> 8) != 0;
}
$hashlist{$hash} = $fprint;
}
-