3 # update-ca-certificates
5 # Copyright (c) 2010 SUSE Linux Products GmbH
6 # Author: Ludwig Nussel
8 # Inspired by Debian's update-ca-certificates
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program; if not, write to the Free Software
22 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301,
32 my $certsconf = '/etc/ca-certificates.conf';
33 my $hooksdir1 = '/etc/ca-certificates/update.d';
34 my $hooksdir2 = '/usr/lib/ca-certificates/update.d';
35 # only search /usr/share/ca-certificates/certs because of code-signing certs
36 my $certsdir = "/usr/share/ca-certificates/certs";
37 my $localcertsdir = "/usr/local/share/ca-certificates";
38 my $etccertsdir = "/etc/ssl/certs";
40 my (%blacklist, %whitelist, %added, %removed);
42 my ($opt_verbose, $opt_fresh, $opt_help);
46 return $_[1] eq substr($_[0], 0, length($_[1]));
51 my $t = $etccertsdir.'/'.basename($_[0]);
59 my $t = targetfilename($f);
62 unlink $t if -l $t; # dangling symlink
63 if (symlink($f, $t)) {
65 delete $removed{$f} if exists $removed{$f};
67 print STDERR "symlink of $t failed: $!\n";
73 my $t = targetfilename($_[0]);
80 Getopt::Long::Configure("no_ignore_case");
82 "verbose|v" => \$opt_verbose,
83 "fresh|f" => \$opt_fresh,
84 "help|h" => \$opt_help,
89 print "USAGE: $0 [OPTIONS]\n";
91 print " --verbose, -v verbose output\n";
92 print " --fresh, -f start from scratch\n";
93 print " --help, -h this screen\n";
97 if (open(F, '<', $certsconf)) {
101 next unless length($_);
112 if ($opt_fresh || %whitelist) {
113 for my $f (glob "$etccertsdir/*" ) {
116 next unless defined $l;
117 if (startswith($l, $etccertsdir)
118 || startswith($l, $localcertsdir))
120 if ($opt_fresh || %whitelist &&
121 !exists($whitelist{basename($l)}))
134 -f && /\.(?:pem|crt|[0-9])$/ && push @files, $_;
138 my $n = substr($f, length($certsdir)+1);
139 if (exists($blacklist{$n})) {
143 next if %whitelist && !exists($whitelist{$n});
147 for my $f (glob "$localcertsdir/*.{pem,crt}") {
151 for my $f (glob "$etccertsdir/*.{pem,[0-9]}") {
152 if (-l $f && !-e $f) {
153 if (startswith($f, $etccertsdir)
154 || startswith($f, $localcertsdir))
158 # clean dangling symlinks
163 chdir $etccertsdir || die "$!";
164 if (%added || %removed || $opt_fresh) {
165 print "Updating certificates in $etccertsdir...\n";
166 # tizen ca-certs suffix isn't .pem|.crt|.cer|.crl
167 # so c_rehash cannot be used.
168 # my $redir = ($opt_verbose?'':'> /dev/null');
169 # system("c_rehash . $redir");
171 printf("%d added, %d removed.\n",
172 (%added?(scalar keys %added):0),
173 (%removed?(scalar keys %removed):0));
177 push @args, '-f' if $opt_fresh;
178 push @args, '-v' if $opt_verbose;
179 for my $f (glob("$hooksdir2/*.run"), glob("$hooksdir1/*.run")) {