mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
mk-ca-bundle: Change URL retrieval to HTTPS-only by default
- Change all predefined Mozilla URLs to HTTPS (Gregory Szorc). - New option -k to allow URLs other than HTTPS and enable HTTP fallback. Prior to this change the default URL retrieval mode was to fall back to HTTP if HTTPS didn't work. Reported-by: Gregory Szorc Closes #1012
This commit is contained in:
parent
c30a2d97ed
commit
1ad2bdcf11
@ -32,9 +32,8 @@
|
|||||||
#
|
#
|
||||||
use Getopt::Std;
|
use Getopt::Std;
|
||||||
use MIME::Base64;
|
use MIME::Base64;
|
||||||
use LWP::UserAgent;
|
|
||||||
use strict;
|
use strict;
|
||||||
use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_l $opt_m $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
|
use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_k $opt_l $opt_m $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
|
||||||
use List::Util;
|
use List::Util;
|
||||||
use Text::Wrap;
|
use Text::Wrap;
|
||||||
my $MOD_SHA = "Digest::SHA";
|
my $MOD_SHA = "Digest::SHA";
|
||||||
@ -43,18 +42,19 @@ if ($@) {
|
|||||||
$MOD_SHA = "Digest::SHA::PurePerl";
|
$MOD_SHA = "Digest::SHA::PurePerl";
|
||||||
eval "require $MOD_SHA";
|
eval "require $MOD_SHA";
|
||||||
}
|
}
|
||||||
|
eval "require LWP::UserAgent";
|
||||||
|
|
||||||
my %urls = (
|
my %urls = (
|
||||||
'nss' =>
|
'nss' =>
|
||||||
'http://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
|
'https://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
|
||||||
'central' =>
|
'central' =>
|
||||||
'http://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
'https://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||||
'aurora' =>
|
'aurora' =>
|
||||||
'http://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
'https://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||||
'beta' =>
|
'beta' =>
|
||||||
'http://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
'https://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||||
'release' =>
|
'release' =>
|
||||||
'http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
'https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||||
);
|
);
|
||||||
|
|
||||||
$opt_d = 'release';
|
$opt_d = 'release';
|
||||||
@ -62,7 +62,7 @@ $opt_d = 'release';
|
|||||||
# If the OpenSSL commandline is not in search path you can configure it here!
|
# If the OpenSSL commandline is not in search path you can configure it here!
|
||||||
my $openssl = 'openssl';
|
my $openssl = 'openssl';
|
||||||
|
|
||||||
my $version = '1.26';
|
my $version = '1.27';
|
||||||
|
|
||||||
$opt_w = 76; # default base64 encoded lines length
|
$opt_w = 76; # default base64 encoded lines length
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ my @valid_signature_algorithms = (
|
|||||||
|
|
||||||
$0 =~ s@.*(/|\\)@@;
|
$0 =~ s@.*(/|\\)@@;
|
||||||
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
||||||
getopts('bd:fhilmnp:qs:tuvw:');
|
getopts('bd:fhiklmnp:qs:tuvw:');
|
||||||
|
|
||||||
if(!defined($opt_d)) {
|
if(!defined($opt_d)) {
|
||||||
# to make plain "-d" use not cause warnings, and actually still work
|
# to make plain "-d" use not cause warnings, and actually still work
|
||||||
@ -117,7 +117,16 @@ if(!defined($opt_d)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Use predefined URL or else custom URL specified on command line.
|
# Use predefined URL or else custom URL specified on command line.
|
||||||
my $url = ( defined( $urls{$opt_d} ) ) ? $urls{$opt_d} : $opt_d;
|
my $url;
|
||||||
|
if(defined($urls{$opt_d})) {
|
||||||
|
$url = $urls{$opt_d};
|
||||||
|
if(!$opt_k && $url !~ /^https:\/\//i) {
|
||||||
|
die "The URL for '$opt_d' is not HTTPS. Use -k to override (insecure).\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$url = $opt_d;
|
||||||
|
}
|
||||||
|
|
||||||
my $curl = `curl -V`;
|
my $curl = `curl -V`;
|
||||||
|
|
||||||
@ -128,8 +137,8 @@ if ($opt_i) {
|
|||||||
print "Operating System Name : $^O\n";
|
print "Operating System Name : $^O\n";
|
||||||
print "Getopt::Std.pm Version : ${Getopt::Std::VERSION}\n";
|
print "Getopt::Std.pm Version : ${Getopt::Std::VERSION}\n";
|
||||||
print "MIME::Base64.pm Version : ${MIME::Base64::VERSION}\n";
|
print "MIME::Base64.pm Version : ${MIME::Base64::VERSION}\n";
|
||||||
print "LWP::UserAgent.pm Version : ${LWP::UserAgent::VERSION}\n";
|
print "LWP::UserAgent.pm Version : ${LWP::UserAgent::VERSION}\n" if($LWP::UserAgent::VERSION);
|
||||||
print "LWP.pm Version : ${LWP::VERSION}\n";
|
print "LWP.pm Version : ${LWP::VERSION}\n" if($LWP::VERSION);
|
||||||
print "Digest::SHA.pm Version : ${Digest::SHA::VERSION}\n" if ($Digest::SHA::VERSION);
|
print "Digest::SHA.pm Version : ${Digest::SHA::VERSION}\n" if ($Digest::SHA::VERSION);
|
||||||
print "Digest::SHA::PurePerl.pm Version : ${Digest::SHA::PurePerl::VERSION}\n" if ($Digest::SHA::PurePerl::VERSION);
|
print "Digest::SHA::PurePerl.pm Version : ${Digest::SHA::PurePerl::VERSION}\n" if ($Digest::SHA::PurePerl::VERSION);
|
||||||
print ("=" x 78 . "\n");
|
print ("=" x 78 . "\n");
|
||||||
@ -139,7 +148,7 @@ sub warning_message() {
|
|||||||
if ( $opt_d =~ m/^risk$/i ) { # Long Form Warning and Exit
|
if ( $opt_d =~ m/^risk$/i ) { # Long Form Warning and Exit
|
||||||
print "Warning: Use of this script may pose some risk:\n";
|
print "Warning: Use of this script may pose some risk:\n";
|
||||||
print "\n";
|
print "\n";
|
||||||
print " 1) Using http is subject to man in the middle attack of certdata content\n";
|
print " 1) If you use HTTP URLs they are subject to a man in the middle attack\n";
|
||||||
print " 2) Default to 'release', but more recent updates may be found in other trees\n";
|
print " 2) Default to 'release', but more recent updates may be found in other trees\n";
|
||||||
print " 3) certdata.txt file format may change, lag time to update this script\n";
|
print " 3) certdata.txt file format may change, lag time to update this script\n";
|
||||||
print " 4) Generally unwise to blindly trust CAs without manual review & verification\n";
|
print " 4) Generally unwise to blindly trust CAs without manual review & verification\n";
|
||||||
@ -153,13 +162,14 @@ sub warning_message() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub HELP_MESSAGE() {
|
sub HELP_MESSAGE() {
|
||||||
print "Usage:\t${0} [-b] [-d<certdata>] [-f] [-i] [-l] [-n] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-u] [-v] [-w<l>] [<outputfile>]\n";
|
print "Usage:\t${0} [-b] [-d<certdata>] [-f] [-i] [-k] [-l] [-n] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-u] [-v] [-w<l>] [<outputfile>]\n";
|
||||||
print "\t-b\tbackup an existing version of ca-bundle.crt\n";
|
print "\t-b\tbackup an existing version of ca-bundle.crt\n";
|
||||||
print "\t-d\tspecify Mozilla tree to pull certdata.txt or custom URL\n";
|
print "\t-d\tspecify Mozilla tree to pull certdata.txt or custom URL\n";
|
||||||
print "\t\t Valid names are:\n";
|
print "\t\t Valid names are:\n";
|
||||||
print "\t\t ", join( ", ", map { ( $_ =~ m/$opt_d/ ) ? "$_ (default)" : "$_" } sort keys %urls ), "\n";
|
print "\t\t ", join( ", ", map { ( $_ =~ m/$opt_d/ ) ? "$_ (default)" : "$_" } sort keys %urls ), "\n";
|
||||||
print "\t-f\tforce rebuild even if certdata.txt is current\n";
|
print "\t-f\tforce rebuild even if certdata.txt is current\n";
|
||||||
print "\t-i\tprint version info about used modules\n";
|
print "\t-i\tprint version info about used modules\n";
|
||||||
|
print "\t-k\tallow URLs other than HTTPS, enable HTTP fallback (insecure)\n";
|
||||||
print "\t-l\tprint license info about certdata.txt\n";
|
print "\t-l\tprint license info about certdata.txt\n";
|
||||||
print "\t-m\tinclude meta data in output\n";
|
print "\t-m\tinclude meta data in output\n";
|
||||||
print "\t-n\tno download of certdata.txt (to use existing)\n";
|
print "\t-n\tno download of certdata.txt (to use existing)\n";
|
||||||
@ -287,36 +297,69 @@ my $oldhash = oldhash($crt);
|
|||||||
|
|
||||||
report "SHA256 of old file: $oldhash";
|
report "SHA256 of old file: $oldhash";
|
||||||
|
|
||||||
report "Downloading '$txt' ...";
|
if(!$opt_n) {
|
||||||
|
report "Downloading $txt ...";
|
||||||
|
|
||||||
if($curl && !$opt_n) {
|
# If we have an HTTPS URL then use curl
|
||||||
my $https = $url;
|
if($url =~ /^https:\/\//i) {
|
||||||
$https =~ s/^http:/https:/;
|
if($curl) {
|
||||||
report "Get certdata over HTTPS with curl!";
|
if($curl =~ /^Protocols:.* https( |$)/m) {
|
||||||
|
report "Get certdata with curl!";
|
||||||
|
my $proto = !$opt_k ? "--proto =https" : "";
|
||||||
my $quiet = $opt_q ? "-s" : "";
|
my $quiet = $opt_q ? "-s" : "";
|
||||||
my @out = `curl -w %{response_code} $quiet -O $https`;
|
my @out = `curl -w %{response_code} $proto $quiet -o "$txt" "$url"`;
|
||||||
if(@out && $out[0] == 200) {
|
if(@out && $out[0] == 200) {
|
||||||
$fetched = 1;
|
$fetched = 1;
|
||||||
} else {
|
report "Downloaded $txt";
|
||||||
report "Failed downloading HTTPS with curl, trying HTTP with LWP";
|
}
|
||||||
|
else {
|
||||||
|
report "Failed downloading via HTTPS with curl";
|
||||||
|
if(-e $txt && !unlink($txt)) {
|
||||||
|
report "Failed to remove '$txt': $!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
report "curl lacks https support";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
report "curl not found";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unless ($fetched || ($opt_n and -e $txt)) {
|
# If nothing was fetched then use LWP
|
||||||
|
if(!$fetched) {
|
||||||
|
if($url =~ /^https:\/\//i) {
|
||||||
|
report "Falling back to HTTP";
|
||||||
|
$url =~ s/^https:\/\//http:\/\//i;
|
||||||
|
}
|
||||||
|
if(!$opt_k) {
|
||||||
|
report "URLs other than HTTPS are disabled by default, to enable use -k";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
report "Get certdata with LWP!";
|
||||||
|
if(!defined(${LWP::UserAgent::VERSION})) {
|
||||||
|
report "LWP is not available (LWP::UserAgent not found)";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
my $ua = new LWP::UserAgent(agent => "$0/$version");
|
my $ua = new LWP::UserAgent(agent => "$0/$version");
|
||||||
$ua->env_proxy();
|
$ua->env_proxy();
|
||||||
$resp = $ua->mirror($url, $txt);
|
$resp = $ua->mirror($url, $txt);
|
||||||
if ($resp && $resp->code eq '304') {
|
if($resp && $resp->code eq '304') {
|
||||||
report "Not modified";
|
report "Not modified";
|
||||||
exit 0 if -e $crt && !$opt_f;
|
exit 0 if -e $crt && !$opt_f;
|
||||||
} else {
|
|
||||||
$fetched = 1;
|
|
||||||
}
|
}
|
||||||
if( !$resp || $resp->code !~ /^(?:200|304)$/ ) {
|
else {
|
||||||
|
$fetched = 1;
|
||||||
|
report "Downloaded $txt";
|
||||||
|
}
|
||||||
|
if(!$resp || $resp->code !~ /^(?:200|304)$/) {
|
||||||
report "Unable to download latest data: "
|
report "Unable to download latest data: "
|
||||||
. ($resp? $resp->code . ' - ' . $resp->message : "LWP failed");
|
. ($resp? $resp->code . ' - ' . $resp->message : "LWP failed");
|
||||||
exit 1 if -e $crt || ! -r $txt;
|
exit 1 if -e $crt || ! -r $txt;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $filedate = $resp ? $resp->last_modified : (stat($txt))[9];
|
my $filedate = $resp ? $resp->last_modified : (stat($txt))[9];
|
||||||
@ -503,5 +546,7 @@ unless( $stdout ) {
|
|||||||
}
|
}
|
||||||
rename "$crt.~", $crt or die "Failed to rename $crt.~ to $crt: $!\n";
|
rename "$crt.~", $crt or die "Failed to rename $crt.~ to $crt: $!\n";
|
||||||
}
|
}
|
||||||
unlink $txt if ($opt_u);
|
if($opt_u && -e $txt && !unlink($txt)) {
|
||||||
|
report "Failed to remove $txt: $!\n";
|
||||||
|
}
|
||||||
report "Done ($certnum CA certs processed, $skipnum skipped).";
|
report "Done ($certnum CA certs processed, $skipnum skipped).";
|
||||||
|
Loading…
Reference in New Issue
Block a user