Skip to content

Commit c2140b5

Browse files
committedApr 28, 2013
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
1 parent cf5a329 commit c2140b5

File tree

7 files changed

+3982
-31
lines changed

7 files changed

+3982
-31
lines changed
 

‎admin/tool/installaddon/classes/installer.php

-7
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,6 @@ public function download_file($source, $target) {
366366
'ssl_verifyhost' => 2,
367367
);
368368

369-
$cacertfile = $CFG->dataroot.'/moodleorgca.crt';
370-
if (is_readable($cacertfile)) {
371-
// Do not use CA certs provided by the operating system. Instead,
372-
// use this CA cert to verify the ZIP provider.
373-
$options['cainfo'] = $cacertfile;
374-
}
375-
376369
$curl = new curl(array('proxy' => true));
377370

378371
$result = $curl->download_one($source, null, $options);

‎admin/tool/installaddon/classes/pluginfo_client.php

-7
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,6 @@ protected function service_request_options() {
151151
'CURLOPT_SSL_VERIFYPEER' => true,
152152
);
153153

154-
$cacertfile = $CFG->dataroot.'/moodleorgca.crt';
155-
if (is_readable($cacertfile)) {
156-
// Do not use CA certs provided by the operating system. Instead,
157-
// use this CA cert to verify the updates provider.
158-
$options['CURLOPT_CAINFO'] = $cacertfile;
159-
}
160-
161154
return $options;
162155
}
163156

‎lib/cacert.pem

+3,895
Large diffs are not rendered by default.

‎lib/cacert.txt

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

‎lib/filelib.php

+37
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,10 @@ function download_file_content($url, $headers=null, $postdata=null, $fullrespons
12091209
curl_setopt($ch, CURLOPT_HEADER, false);
12101210
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connecttimeout);
12111211

1212+
if ($cacert = curl::get_cacert()) {
1213+
curl_setopt($ch, CURLOPT_CAINFO, $cacert);
1214+
}
1215+
12121216
if (!ini_get('open_basedir') and !ini_get('safe_mode')) {
12131217
// TODO: add version test for '7.10.5'
12141218
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
@@ -2930,6 +2934,39 @@ public function resetopt(){
29302934
$this->options['CURLOPT_SSL_VERIFYPEER'] = 0;
29312935
$this->options['CURLOPT_SSL_VERIFYHOST'] = 2;
29322936
$this->options['CURLOPT_CONNECTTIMEOUT'] = 30;
2937+
2938+
if ($cacert = self::get_cacert()) {
2939+
$this->options['CURLOPT_CAINFO'] = $cacert;
2940+
}
2941+
}
2942+
2943+
/**
2944+
* Get the location of ca certificates.
2945+
* @return string absolute file path or empty if default used
2946+
*/
2947+
public static function get_cacert() {
2948+
global $CFG;
2949+
2950+
// Bundle in dataroot always wins.
2951+
if (is_readable("$CFG->dataroot/moodleorgca.crt")) {
2952+
return realpath("$CFG->dataroot/moodleorgca.crt");
2953+
}
2954+
2955+
// Next comes the default from php.ini
2956+
$cacert = ini_get('curl.cainfo');
2957+
if (!empty($cacert) and is_readable($cacert)) {
2958+
return realpath($cacert);
2959+
}
2960+
2961+
// Windows PHP does not have any certs, we need to use something.
2962+
if ($CFG->ostype === 'WINDOWS') {
2963+
if (is_readable("$CFG->libdir/cacert.pem")) {
2964+
return realpath("$CFG->libdir/cacert.pem");
2965+
}
2966+
}
2967+
2968+
// Use default, this should work fine on all properly configured *nix systems.
2969+
return null;
29332970
}
29342971

29352972
/**

‎lib/pluginlib.php

-14
Original file line numberDiff line numberDiff line change
@@ -1429,13 +1429,6 @@ protected function prepare_request_options() {
14291429
'CURLOPT_SSL_VERIFYPEER' => true,
14301430
);
14311431

1432-
$cacertfile = $CFG->dataroot.'/moodleorgca.crt';
1433-
if (is_readable($cacertfile)) {
1434-
// Do not use CA certs provided by the operating system. Instead,
1435-
// use this CA cert to verify the updates provider.
1436-
$options['CURLOPT_CAINFO'] = $cacertfile;
1437-
}
1438-
14391432
return $options;
14401433
}
14411434

@@ -2318,13 +2311,6 @@ protected function update_downloadable($downloadurl) {
23182311
'CURLOPT_SSL_VERIFYPEER' => true,
23192312
);
23202313

2321-
$cacertfile = $CFG->dataroot.'/moodleorgca.crt';
2322-
if (is_readable($cacertfile)) {
2323-
// Do not use CA certs provided by the operating system. Instead,
2324-
// use this CA cert to verify the updates provider.
2325-
$curloptions['CURLOPT_CAINFO'] = $cacertfile;
2326-
}
2327-
23282314
$curl = new curl(array('proxy' => true));
23292315
$result = $curl->head($downloadurl, $curloptions);
23302316
$errno = $curl->get_errno();

‎mdeploy.php

+30-3
Original file line numberDiff line numberDiff line change
@@ -1054,9 +1054,7 @@ protected function download_file($source, $target) {
10541054
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); // nah, moodle.org is never unavailable! :-p
10551055
curl_setopt($ch, CURLOPT_URL, $source);
10561056

1057-
$dataroot = $this->input->get_option('dataroot');
1058-
$cacertfile = $dataroot.'/moodleorgca.crt';
1059-
if (is_readable($cacertfile)) {
1057+
if ($cacertfile = $this->get_cacert()) {
10601058
// Do not use CA certs provided by the operating system. Instead,
10611059
// use this CA cert to verify the ZIP provider.
10621060
$this->log('Using custom CA certificate '.$cacertfile);
@@ -1116,6 +1114,35 @@ protected function download_file($source, $target) {
11161114
return true;
11171115
}
11181116

1117+
/**
1118+
* Get the location of ca certificates.
1119+
* @return string absolute file path or empty if default used
1120+
*/
1121+
protected function get_cacert() {
1122+
$dataroot = $this->input->get_option('dataroot');
1123+
1124+
// Bundle in dataroot always wins.
1125+
if (is_readable($dataroot.'/moodleorgca.crt')) {
1126+
return realpath($dataroot.'/moodleorgca.crt');
1127+
}
1128+
1129+
// Next comes the default from php.ini
1130+
$cacert = ini_get('curl.cainfo');
1131+
if (!empty($cacert) and is_readable($cacert)) {
1132+
return realpath($cacert);
1133+
}
1134+
1135+
// Windows PHP does not have any certs, we need to use something.
1136+
if (stristr(PHP_OS, 'win') && !stristr(PHP_OS, 'darwin')) {
1137+
if (is_readable(__DIR__.'/lib/cacert.pem')) {
1138+
return realpath(__DIR__.'/lib/cacert.pem');
1139+
}
1140+
}
1141+
1142+
// Use default, this should work fine on all properly configured *nix systems.
1143+
return null;
1144+
}
1145+
11191146
/**
11201147
* Log a message
11211148
*

0 commit comments

Comments
 (0)
Please sign in to comment.