2013-01-23 01:15:54 +01:00
|
|
|
<?php
|
|
|
|
|
2015-01-02 05:27:45 +01:00
|
|
|
final class PhabricatorPHPConfigSetupCheck extends PhabricatorSetupCheck {
|
2013-01-23 01:15:54 +01:00
|
|
|
|
2015-02-10 21:53:00 +01:00
|
|
|
public function getDefaultGroup() {
|
|
|
|
return self::GROUP_PHP;
|
|
|
|
}
|
|
|
|
|
2013-01-23 01:15:54 +01:00
|
|
|
public function getExecutionOrder() {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function executeChecks() {
|
2016-07-05 02:55:11 +02:00
|
|
|
if (version_compare(phpversion(), 7, '>=')) {
|
|
|
|
$message = pht(
|
|
|
|
'This version of Phabricator does not support PHP 7. You '.
|
|
|
|
'are running PHP %s.',
|
|
|
|
phpversion());
|
|
|
|
|
|
|
|
$this->newIssue('php.version7')
|
|
|
|
->setIsFatal(true)
|
|
|
|
->setName(pht('PHP 7 Not Supported'))
|
|
|
|
->setMessage($message)
|
|
|
|
->addLink(
|
|
|
|
'https://phurl.io/u/php7',
|
|
|
|
pht('Phabricator PHP 7 Compatibility Information'));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-01-23 01:15:54 +01:00
|
|
|
$safe_mode = ini_get('safe_mode');
|
|
|
|
if ($safe_mode) {
|
|
|
|
$message = pht(
|
2015-05-22 09:27:56 +02:00
|
|
|
"You have '%s' enabled in your PHP configuration, but Phabricator ".
|
|
|
|
"will not run in safe mode. Safe mode has been deprecated in PHP 5.3 ".
|
|
|
|
"and removed in PHP 5.4.\n\nDisable safe mode to continue.",
|
|
|
|
'safe_mode');
|
2013-01-23 01:15:54 +01:00
|
|
|
|
|
|
|
$this->newIssue('php.safe_mode')
|
|
|
|
->setIsFatal(true)
|
2015-05-22 09:27:56 +02:00
|
|
|
->setName(pht('Disable PHP %s', 'safe_mode'))
|
2013-01-23 01:15:54 +01:00
|
|
|
->setMessage($message)
|
|
|
|
->addPHPConfig('safe_mode');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-08-13 19:11:05 +02:00
|
|
|
// Check for `disable_functions` or `disable_classes`. Although it's
|
|
|
|
// possible to disable a bunch of functions (say, `array_change_key_case()`)
|
|
|
|
// and classes and still have Phabricator work fine, it's unreasonably
|
|
|
|
// difficult for us to be sure we'll even survive setup if these options
|
|
|
|
// are enabled. Phabricator needs access to the most dangerous functions,
|
|
|
|
// so there is no reasonable configuration value here which actually
|
|
|
|
// provides a benefit while guaranteeing Phabricator will run properly.
|
|
|
|
|
|
|
|
$disable_options = array('disable_functions', 'disable_classes');
|
|
|
|
foreach ($disable_options as $disable_option) {
|
2013-08-13 21:23:29 +02:00
|
|
|
$disable_value = ini_get($disable_option);
|
|
|
|
if ($disable_value) {
|
2013-08-13 19:11:05 +02:00
|
|
|
|
2013-08-13 21:23:29 +02:00
|
|
|
// By default Debian installs the pcntl extension but disables all of
|
|
|
|
// its functions using configuration. Whitelist disabling these
|
|
|
|
// functions so that Debian PHP works out of the box (we do not need to
|
|
|
|
// call these functions from the web UI). This is pretty ridiculous but
|
|
|
|
// it's not the users' fault and they haven't done anything crazy to
|
|
|
|
// get here, so don't make them pay for Debian's unusual choices.
|
|
|
|
// See: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=605571
|
|
|
|
$fatal = true;
|
|
|
|
if ($disable_option == 'disable_functions') {
|
|
|
|
$functions = preg_split('/[, ]+/', $disable_value);
|
|
|
|
$functions = array_filter($functions);
|
|
|
|
foreach ($functions as $k => $function) {
|
|
|
|
if (preg_match('/^pcntl_/', $function)) {
|
|
|
|
unset($functions[$k]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!$functions) {
|
|
|
|
$fatal = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($fatal) {
|
|
|
|
$message = pht(
|
|
|
|
"You have '%s' enabled in your PHP configuration.\n\n".
|
|
|
|
"This option is not compatible with Phabricator. Remove ".
|
|
|
|
"'%s' from your configuration to continue.",
|
|
|
|
$disable_option,
|
|
|
|
$disable_option);
|
|
|
|
|
|
|
|
$this->newIssue('php.'.$disable_option)
|
|
|
|
->setIsFatal(true)
|
|
|
|
->setName(pht('Remove PHP %s', $disable_option))
|
|
|
|
->setMessage($message)
|
|
|
|
->addPHPConfig($disable_option);
|
|
|
|
}
|
2013-08-13 19:11:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-04 16:59:02 +02:00
|
|
|
$overload_option = 'mbstring.func_overload';
|
|
|
|
$func_overload = ini_get($overload_option);
|
|
|
|
if ($func_overload) {
|
|
|
|
$message = pht(
|
|
|
|
"You have '%s' enabled in your PHP configuration.\n\n".
|
|
|
|
"This option is not compatible with Phabricator. Disable ".
|
|
|
|
"'%s' in your PHP configuration to continue.",
|
|
|
|
$overload_option,
|
|
|
|
$overload_option);
|
|
|
|
|
|
|
|
$this->newIssue('php'.$overload_option)
|
|
|
|
->setIsFatal(true)
|
|
|
|
->setName(pht('Disable PHP %s', $overload_option))
|
|
|
|
->setMessage($message)
|
|
|
|
->addPHPConfig($overload_option);
|
|
|
|
}
|
|
|
|
|
2013-01-23 01:15:54 +01:00
|
|
|
$open_basedir = ini_get('open_basedir');
|
|
|
|
if ($open_basedir) {
|
|
|
|
|
|
|
|
// 'open_basedir' restricts which files we're allowed to access with
|
|
|
|
// file operations. This might be okay -- we don't need to write to
|
|
|
|
// arbitrary places in the filesystem -- but we need to access certain
|
|
|
|
// resources. This setting is unlikely to be providing any real measure
|
|
|
|
// of security so warn even if things look OK.
|
|
|
|
|
|
|
|
$failures = array();
|
|
|
|
|
|
|
|
try {
|
|
|
|
$open_libphutil = class_exists('Future');
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
$failures[] = $ex->getMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$open_arcanist = class_exists('ArcanistDiffParser');
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
$failures[] = $ex->getMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
$open_urandom = false;
|
|
|
|
try {
|
|
|
|
Filesystem::readRandomBytes(1);
|
|
|
|
$open_urandom = true;
|
|
|
|
} catch (FilesystemException $ex) {
|
|
|
|
$failures[] = $ex->getMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$tmp = new TempFile();
|
|
|
|
file_put_contents($tmp, '.');
|
|
|
|
$open_tmp = @fopen((string)$tmp, 'r');
|
|
|
|
if (!$open_tmp) {
|
|
|
|
$failures[] = pht(
|
|
|
|
"Unable to read temporary file '%s'.",
|
|
|
|
(string)$tmp);
|
|
|
|
}
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
$message = $ex->getMessage();
|
|
|
|
$dir = sys_get_temp_dir();
|
|
|
|
$failures[] = pht(
|
|
|
|
"Unable to open temp files from '%s': %s",
|
|
|
|
$dir,
|
|
|
|
$message);
|
|
|
|
}
|
|
|
|
|
|
|
|
$issue = $this->newIssue('php.open_basedir')
|
2015-05-22 09:27:56 +02:00
|
|
|
->setName(pht('Disable PHP %s', 'open_basedir'))
|
2013-01-23 01:15:54 +01:00
|
|
|
->addPHPConfig('open_basedir');
|
|
|
|
|
|
|
|
if ($failures) {
|
|
|
|
$message = pht(
|
2015-05-22 09:27:56 +02:00
|
|
|
"Your server is configured with '%s', which prevents Phabricator ".
|
|
|
|
"from opening files it requires access to.\n\n".
|
|
|
|
"Disable this setting to continue.\n\nFailures:\n\n%s",
|
|
|
|
'open_basedir',
|
2013-01-23 01:15:54 +01:00
|
|
|
implode("\n\n", $failures));
|
|
|
|
|
|
|
|
$issue
|
|
|
|
->setIsFatal(true)
|
|
|
|
->setMessage($message);
|
|
|
|
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
$summary = pht(
|
2015-05-22 09:27:56 +02:00
|
|
|
"You have '%s' configured in your PHP settings, which ".
|
|
|
|
"may cause some features to fail.",
|
|
|
|
'open_basedir');
|
2013-01-23 01:15:54 +01:00
|
|
|
|
|
|
|
$message = pht(
|
2015-05-22 09:27:56 +02:00
|
|
|
"You have '%s' configured in your PHP settings. Although this ".
|
|
|
|
"setting appears permissive enough that Phabricator will work ".
|
|
|
|
"properly, you may still run into problems because of it.\n\n".
|
|
|
|
"Consider disabling '%s'.",
|
|
|
|
'open_basedir',
|
|
|
|
'open_basedir');
|
2013-01-23 01:15:54 +01:00
|
|
|
|
|
|
|
$issue
|
|
|
|
->setSummary($summary)
|
|
|
|
->setMessage($message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|