diff --git a/.travis.yml b/.travis.yml
index 800a4f2f1..fa96bc75b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,10 +6,12 @@ php:
- 5.4
- 5.5
- hhvm
+ - 5.6
matrix:
allow_failures:
- php: hhvm
+ - php: 5.6
before_script:
- sudo apt-get install parallel
diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php
index 445bcc1aa..1d2450630 100644
--- a/src/Composer/Command/DiagnoseCommand.php
+++ b/src/Composer/Command/DiagnoseCommand.php
@@ -14,6 +14,7 @@ namespace Composer\Command;
use Composer\Composer;
use Composer\Factory;
+use Composer\Config;
use Composer\Downloader\TransportException;
use Composer\Plugin\CommandEvent;
use Composer\Plugin\PluginEvents;
@@ -48,6 +49,7 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output)
{
+
$this->rfs = new RemoteFilesystem($this->getIO());
$this->process = new ProcessExecutor($this->getIO());
@@ -57,19 +59,6 @@ EOT
$output->write('Checking git settings: ');
$this->outputResult($output, $this->checkGit());
- $output->write('Checking http connectivity: ');
- $this->outputResult($output, $this->checkHttp());
-
- $opts = stream_context_get_options(StreamContextFactory::getContext('http://example.org'));
- if (!empty($opts['http']['proxy'])) {
- $output->write('Checking HTTP proxy: ');
- $this->outputResult($output, $this->checkHttpProxy());
- $output->write('Checking HTTP proxy support for request_fulluri: ');
- $this->outputResult($output, $this->checkHttpProxyFullUriRequestParam());
- $output->write('Checking HTTPS proxy support for request_fulluri: ');
- $this->outputResult($output, $this->checkHttpsProxyFullUriRequestParam());
- }
-
$composer = $this->getComposer(false);
if ($composer) {
$commandEvent = new CommandEvent(PluginEvents::COMMAND, 'diagnose', $input, $output);
@@ -85,6 +74,19 @@ EOT
$config = Factory::createConfig();
}
+ $output->write('Checking http connectivity: ');
+ $this->outputResult($output, $this->checkHttp($config));
+
+ $opts = stream_context_get_options(StreamContextFactory::getContext('http://example.org'));
+ if (!empty($opts['http']['proxy'])) {
+ $output->write('Checking HTTP proxy: ');
+ $this->outputResult($output, $this->checkHttpProxy());
+ $output->write('Checking HTTP proxy support for request_fulluri: ');
+ $this->outputResult($output, $this->checkHttpProxyFullUriRequestParam());
+ $output->write('Checking HTTPS proxy support for request_fulluri: ');
+ $this->outputResult($output, $this->checkHttpsProxyFullUriRequestParam());
+ }
+
if ($oauth = $config->get('github-oauth')) {
foreach ($oauth as $domain => $token) {
$output->write('Checking '.$domain.' oauth access: ');
@@ -135,13 +137,45 @@ EOT
return true;
}
- private function checkHttp()
+ private function checkHttp(Config $config)
{
- $protocol = extension_loaded('openssl') ? 'https' : 'http';
+ $disableTls = false;
+ $result = array();
+ if($config->get('disable-tls') === true) {
+ $protocol = 'http';
+ $disableTls = true;
+ $result[] = 'Composer is configured to disable SSL/TLS protection. This will leave remote HTTPS requests vulnerable to Man-In-The-Middle attacks.';
+ } else {
+ $protocol = 'https';
+ }
+ if (!extension_loaded('openssl') && !$disableTls) {
+ $result[] = 'Composer is configured to use SSL/TLS protection but the openssl extension is not available.';
+ }
+
+ $remoteFilesystemOptions = array();
+ if (!is_null($config->get('cafile'))) {
+ $remoteFilesystemOptions = array('ssl'=>array('cafile'=>$config->get('cafile')));
+ }
try {
- $json = $this->rfs->getContents('packagist.org', $protocol . '://packagist.org/packages.json', false);
+ $remoteFilesystem = new RemoteFilesystem($this->getIO(), $remoteFilesystemOptions, $disableTls);
+ } catch (TransportException $e) {
+ if (preg_match('|cafile|', $e->getMessage())) {
+ $result[] = '[' . get_class($e) . '] ' . $e->getMessage() . '';
+ $result[] = 'Unable to locate a valid CA certificate file. You must set a valid \'cafile\' option.';
+ $result[] = 'You can alternatively disable this error, at your own risk, by enabling the \'disable-tls\' option.';
+ } else {
+ throw $e;
+ }
+ }
+
+ try {
+ $json = $remoteFilesystem->getContents('packagist.org', $protocol . '://packagist.org/packages.json', false, array(), $disableTls);
} catch (\Exception $e) {
- return $e;
+ array_unshift($result, '[' . get_class($e) . '] ' . $e->getMessage());
+ }
+
+ if (count($result) > 0) {
+ return $result;
}
return true;
@@ -271,7 +305,13 @@ EOT
if ($result instanceof \Exception) {
$output->writeln('['.get_class($result).'] '.$result->getMessage());
} elseif ($result) {
- $output->writeln($result);
+ if (is_array($result)) {
+ foreach ($result as $message) {
+ $output->writeln($message);
+ }
+ } else {
+ $output->writeln($result);
+ }
}
}
}
diff --git a/src/Composer/Command/SelfUpdateCommand.php b/src/Composer/Command/SelfUpdateCommand.php
index 07dd86033..7036a5727 100644
--- a/src/Composer/Command/SelfUpdateCommand.php
+++ b/src/Composer/Command/SelfUpdateCommand.php
@@ -63,7 +63,7 @@ EOT
$disableTls = false;
if($config->get('disable-tls') === true || $input->getOption('disable-tls')) {
- $output->writeln('You are running Composer with SSL/TLS protection disabled.');
+ $output->writeln('You are running Composer with SSL/TLS protection disabled.');
$baseUrl = 'http://' . self::HOMEPAGE;
$disableTls = true;
} elseif (!extension_loaded('openssl')) {
@@ -74,13 +74,14 @@ EOT
$baseUrl = 'https://' . self::HOMEPAGE;
}
+ $remoteFilesystemOptions = array();
+ if (!is_null($config->get('cafile'))) {
+ $remoteFilesystemOptions = array('ssl'=>array('cafile'=>$config->get('cafile')));
+ }
+ if (!is_null($input->get('cafile'))) {
+ $remoteFilesystemOptions = array('ssl'=>array('cafile'=>$input->get('cafile')));
+ }
try {
- if (!is_null($config->get('cafile'))) {
- $remoteFilesystemOptions = array('ssl'=>array('cafile'=>$config->get('cafile')));
- }
- if (!is_null($input->get('cafile'))) {
- $remoteFilesystemOptions = array('ssl'=>array('cafile'=>$input->get('cafile')));
- }
$remoteFilesystem = new RemoteFilesystem($this->getIO(), $remoteFilesystemOptions, $disableTls);
} catch (TransportException $e) {
if (preg_match('|cafile|', $e->getMessage())) {
diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php
index f829cb459..57f02d81a 100644
--- a/src/Composer/Factory.php
+++ b/src/Composer/Factory.php
@@ -163,7 +163,7 @@ class Factory
if (!isset($repo['type'])) {
throw new \UnexpectedValueException('Repository '.$index.' ('.json_encode($repo).') must have a type defined');
}
- $name = is_int($index) && isset($repo['url']) ? preg_replace('{^https?://}i', '', $repo['url']) : $index;
+ $name = is_int($index) && isset($repo['url']) ? preg_replace('{^https?://}i', '', $repo['url']) : $index; //CHECK: Why is scheme stripped?
while (isset($repos[$name])) {
$name .= '2';
}
diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php
index f54715590..ff2e94c31 100644
--- a/src/Composer/Util/RemoteFilesystem.php
+++ b/src/Composer/Util/RemoteFilesystem.php
@@ -72,7 +72,7 @@ class RemoteFilesystem
*
* @return bool true
*/
- public function copy($originUrl, $fileUrl, $fileName, $progress = true, $options = array(), $disableTls = false)
+ public function copy($originUrl, $fileUrl, $fileName, $progress = true, $options = array(), $disableTls = false) //REFACTOR: to constructor for TLS opt
{
return $this->get($originUrl, $fileUrl, $options, $fileName, $progress, $disableTls);
}