Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13997948
D10315.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
D10315.diff
View Options
diff --git a/resources/ssl/README b/resources/ssl/README
--- a/resources/ssl/README
+++ b/resources/ssl/README
@@ -1,3 +1,23 @@
+This document describes how to set Certificate Authority information.
+Usually, you need to do this only if you're using a self-signed certificate.
+
+
+OSX after Yosemite
+==================
+
+If you're using a version of Mac OSX after Yosemite, you can not configure
+certificates from the command line. All libphutil and arcanist options
+related to CA configuration are ignored.
+
+Instead, you need to add them to the system keychain. The easiest way to do this
+is to visit the site in Safari and choose to permanently accept the certificate.
+
+You can also use `security add-trusted-cert` from the command line.
+
+
+All Other Systems
+=================
+
If "curl.cainfo" is not set (or you are using PHP older than 5.3.7, where the
option was introduced), libphutil uses the "default.pem" certificate authority
bundle when making HTTPS requests with cURL. This bundle is extracted from
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -57,6 +57,7 @@
'FutureProxy' => 'future/FutureProxy.php',
'HTTPFuture' => 'future/http/HTTPFuture.php',
'HTTPFutureCURLResponseStatus' => 'future/http/status/HTTPFutureCURLResponseStatus.php',
+ 'HTTPFutureCertificateResponseStatus' => 'future/http/status/HTTPFutureCertificateResponseStatus.php',
'HTTPFutureHTTPResponseStatus' => 'future/http/status/HTTPFutureHTTPResponseStatus.php',
'HTTPFutureParseResponseStatus' => 'future/http/status/HTTPFutureParseResponseStatus.php',
'HTTPFutureResponseStatus' => 'future/http/status/HTTPFutureResponseStatus.php',
@@ -161,6 +162,7 @@
'PhutilExcessiveServiceCallsDaemon' => 'daemon/torture/PhutilExcessiveServiceCallsDaemon.php',
'PhutilExecChannel' => 'channel/PhutilExecChannel.php',
'PhutilExecPassthru' => 'future/exec/PhutilExecPassthru.php',
+ 'PhutilExecutionEnvironment' => 'utils/PhutilExecutionEnvironment.php',
'PhutilExtensionsTestCase' => 'moduleutils/__tests__/PhutilExtensionsTestCase.php',
'PhutilFacebookAuthAdapter' => 'auth/PhutilFacebookAuthAdapter.php',
'PhutilFatalDaemon' => 'daemon/torture/PhutilFatalDaemon.php',
@@ -504,6 +506,7 @@
'FutureProxy' => 'Future',
'HTTPFuture' => 'BaseHTTPFuture',
'HTTPFutureCURLResponseStatus' => 'HTTPFutureResponseStatus',
+ 'HTTPFutureCertificateResponseStatus' => 'HTTPFutureResponseStatus',
'HTTPFutureHTTPResponseStatus' => 'HTTPFutureResponseStatus',
'HTTPFutureParseResponseStatus' => 'HTTPFutureResponseStatus',
'HTTPFutureResponseStatus' => 'Exception',
diff --git a/src/future/http/HTTPSFuture.php b/src/future/http/HTTPSFuture.php
--- a/src/future/http/HTTPSFuture.php
+++ b/src/future/http/HTTPSFuture.php
@@ -278,8 +278,15 @@
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
}
+ // We're going to try to set CAINFO below. This doesn't work at all on
+ // OSX around Yosemite (see T5913). On these systems, we'll use the
+ // system CA and then try to tell the user that their settings were
+ // ignored and how to fix things if we encounter a CA-related error.
+ // Assume we have custom CA settings to start with; we'll clear this
+ // flag if we read the default CA info below.
+
// Try some decent fallbacks here:
- // - First, check if a bundle is set explicit for this request, via
+ // - First, check if a bundle is set explicitly for this request, via
// `setCABundle()` or similar.
// - Then, check if a global bundle is set explicitly for all requests,
// via `setGlobalCABundle()` or similar.
@@ -308,7 +315,9 @@
}
}
- curl_setopt($curl, CURLOPT_CAINFO, $this->getCABundle());
+ if ($this->canSetCAInfo()) {
+ curl_setopt($curl, CURLOPT_CAINFO, $this->getCABundle());
+ }
$domain = id(new PhutilURI($uri))->getDomain();
if (!empty(self::$blindTrustDomains[$domain])) {
@@ -360,7 +369,14 @@
$err_code = $info['result'];
if ($err_code) {
- $status = new HTTPFutureCURLResponseStatus($err_code, $uri);
+ if (($err_code == CURLE_SSL_CACERT) && !$this->canSetCAInfo()) {
+ $status = new HTTPFutureCertificateResponseStatus(
+ HTTPFutureCertificateResponseStatus::ERROR_IMMUTABLE_CERTIFICATES,
+ $uri);
+ } else {
+ $status = new HTTPFutureCURLResponseStatus($err_code, $uri);
+ }
+
$body = null;
$headers = array();
$this->result = array($status, $body, $headers);
@@ -578,4 +594,21 @@
'request.'));
}
+
+ /**
+ * Determine whether CURLOPT_CAINFO is usable on this system.
+ */
+ private function canSetCAInfo() {
+ // We cannot set CAInfo on OSX after Yosemite.
+
+ $osx_version = PhutilExecutionEnvironment::getOSXVersion();
+ if ($osx_version) {
+ if (version_compare($osx_version, 14, '>=')) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
}
diff --git a/src/future/http/status/HTTPFutureCertificateResponseStatus.php b/src/future/http/status/HTTPFutureCertificateResponseStatus.php
new file mode 100644
--- /dev/null
+++ b/src/future/http/status/HTTPFutureCertificateResponseStatus.php
@@ -0,0 +1,33 @@
+<?php
+
+final class HTTPFutureCertificateResponseStatus
+ extends HTTPFutureResponseStatus {
+
+ const ERROR_IMMUTABLE_CERTIFICATES = 1;
+
+ protected function getErrorCodeType($code) {
+ return 'Certificate';
+ }
+
+ public function isError() {
+ return true;
+ }
+
+ public function isTimeout() {
+ return false;
+ }
+
+ protected function getErrorCodeDescription($code) {
+ return pht(
+ "There was an error verifying the SSL Certificate Authority while ".
+ "negotiating the SSL connection. This usually indicates you are ".
+ "using a self-signed certificate.\n\n".
+ "As of OSX Yosemite, certificates must be added to the OSX keychain. ".
+ "You can do this with `security add-trusted-cert` from the command ".
+ "line, or by visiting the site in Safari and choosing to trust the ".
+ "certificate permanently.\n\n".
+ 'For more information, see instructions in '.
+ '"libphutil/resources/ssl/README".');
+ }
+
+}
diff --git a/src/utils/PhutilExecutionEnvironment.php b/src/utils/PhutilExecutionEnvironment.php
new file mode 100644
--- /dev/null
+++ b/src/utils/PhutilExecutionEnvironment.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * Get information about the current execution environment.
+ */
+final class PhutilExecutionEnvironment {
+
+ public static function getOSXVersion() {
+ if (php_uname('s') != 'Darwin') {
+ return null;
+ }
+
+ return php_uname('r');
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 25, 6:58 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6726960
Default Alt Text
D10315.diff (6 KB)
Attached To
Mode
D10315: Work around OSX after Yosemite no longer respecting CURLOPT_CAINFO
Attached
Detach File
Event Timeline
Log In to Comment