MDL-39356 add ca certificate bundles for cURL

This is necessary because PHP in Windows does not have any certificates and some *nix systems have outdated or missing ca bundles too.

The order is:
1/ dataroot/moodleorgca.crt always wins - needs to be added manually by admin
2/ php.ini setting "curl.cainfo" is next
3/ on Windows libdir/cacert.pem is used because it does not have any default cert bundles
4/ system default is the last - the previous value, ok for properly configured *nix systems
This commit is contained in:
Petr Škoda 2013-04-28 17:42:06 +02:00
parent cf5a3296c4
commit c2140b5d95
7 changed files with 3982 additions and 31 deletions

View File

@ -366,13 +366,6 @@ class tool_installaddon_installer {
'ssl_verifyhost' => 2,
);
$cacertfile = $CFG->dataroot.'/moodleorgca.crt';
if (is_readable($cacertfile)) {
// Do not use CA certs provided by the operating system. Instead,
// use this CA cert to verify the ZIP provider.
$options['cainfo'] = $cacertfile;
}
$curl = new curl(array('proxy' => true));
$result = $curl->download_one($source, null, $options);

View File

@ -151,13 +151,6 @@ class tool_installaddon_pluginfo_client {
'CURLOPT_SSL_VERIFYPEER' => true,
);
$cacertfile = $CFG->dataroot.'/moodleorgca.crt';
if (is_readable($cacertfile)) {
// Do not use CA certs provided by the operating system. Instead,
// use this CA cert to verify the updates provider.
$options['CURLOPT_CAINFO'] = $cacertfile;
}
return $options;
}

3895
lib/cacert.pem Normal file

File diff suppressed because it is too large Load Diff

20
lib/cacert.txt Normal file
View File

@ -0,0 +1,20 @@
CA Certificates for cURL library
================================
The file cacert.pem can be downloaded from http://curl.haxx.se/docs/caextract.html
or created directly from http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt
using mk-ca-bundle conversion tool.
The file is licensed under the same licenses as the Mozilla source file:
MPL 1.1, GPL v2.0 or LGPL 2.1
This file is by default used in all Windows installations that do not have
any "curl.cainfo =" specified in php.ini
It is also possible to force using of arbitrary CA bundle by putting it
into $CFG->dataroot/moodleorgca.crt, this may be useful especially on
non-windows servers with outdated system certificates.
More information at http://docs.moodle.org/en/SSL_certificate_for_moodle.org
Petr Skoda (skodak)

View File

@ -1209,6 +1209,10 @@ function download_file_content($url, $headers=null, $postdata=null, $fullrespons
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connecttimeout);
if ($cacert = curl::get_cacert()) {
curl_setopt($ch, CURLOPT_CAINFO, $cacert);
}
if (!ini_get('open_basedir') and !ini_get('safe_mode')) {
// TODO: add version test for '7.10.5'
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
@ -2930,6 +2934,39 @@ class curl {
$this->options['CURLOPT_SSL_VERIFYPEER'] = 0;
$this->options['CURLOPT_SSL_VERIFYHOST'] = 2;
$this->options['CURLOPT_CONNECTTIMEOUT'] = 30;
if ($cacert = self::get_cacert()) {
$this->options['CURLOPT_CAINFO'] = $cacert;
}
}
/**
* Get the location of ca certificates.
* @return string absolute file path or empty if default used
*/
public static function get_cacert() {
global $CFG;
// Bundle in dataroot always wins.
if (is_readable("$CFG->dataroot/moodleorgca.crt")) {
return realpath("$CFG->dataroot/moodleorgca.crt");
}
// Next comes the default from php.ini
$cacert = ini_get('curl.cainfo');
if (!empty($cacert) and is_readable($cacert)) {
return realpath($cacert);
}
// Windows PHP does not have any certs, we need to use something.
if ($CFG->ostype === 'WINDOWS') {
if (is_readable("$CFG->libdir/cacert.pem")) {
return realpath("$CFG->libdir/cacert.pem");
}
}
// Use default, this should work fine on all properly configured *nix systems.
return null;
}
/**

View File

@ -1429,13 +1429,6 @@ class available_update_checker {
'CURLOPT_SSL_VERIFYPEER' => true,
);
$cacertfile = $CFG->dataroot.'/moodleorgca.crt';
if (is_readable($cacertfile)) {
// Do not use CA certs provided by the operating system. Instead,
// use this CA cert to verify the updates provider.
$options['CURLOPT_CAINFO'] = $cacertfile;
}
return $options;
}
@ -2318,13 +2311,6 @@ class available_update_deployer {
'CURLOPT_SSL_VERIFYPEER' => true,
);
$cacertfile = $CFG->dataroot.'/moodleorgca.crt';
if (is_readable($cacertfile)) {
// Do not use CA certs provided by the operating system. Instead,
// use this CA cert to verify the updates provider.
$curloptions['CURLOPT_CAINFO'] = $cacertfile;
}
$curl = new curl(array('proxy' => true));
$result = $curl->head($downloadurl, $curloptions);
$errno = $curl->get_errno();

View File

@ -1054,9 +1054,7 @@ class worker extends singleton_pattern {
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); // nah, moodle.org is never unavailable! :-p
curl_setopt($ch, CURLOPT_URL, $source);
$dataroot = $this->input->get_option('dataroot');
$cacertfile = $dataroot.'/moodleorgca.crt';
if (is_readable($cacertfile)) {
if ($cacertfile = $this->get_cacert()) {
// Do not use CA certs provided by the operating system. Instead,
// use this CA cert to verify the ZIP provider.
$this->log('Using custom CA certificate '.$cacertfile);
@ -1116,6 +1114,35 @@ class worker extends singleton_pattern {
return true;
}
/**
* Get the location of ca certificates.
* @return string absolute file path or empty if default used
*/
protected function get_cacert() {
$dataroot = $this->input->get_option('dataroot');
// Bundle in dataroot always wins.
if (is_readable($dataroot.'/moodleorgca.crt')) {
return realpath($dataroot.'/moodleorgca.crt');
}
// Next comes the default from php.ini
$cacert = ini_get('curl.cainfo');
if (!empty($cacert) and is_readable($cacert)) {
return realpath($cacert);
}
// Windows PHP does not have any certs, we need to use something.
if (stristr(PHP_OS, 'win') && !stristr(PHP_OS, 'darwin')) {
if (is_readable(__DIR__.'/lib/cacert.pem')) {
return realpath(__DIR__.'/lib/cacert.pem');
}
}
// Use default, this should work fine on all properly configured *nix systems.
return null;
}
/**
* Log a message
*