private function getLongErrorMessage() { $message = '<p>'; if (SettingsServer::isWindows()) { $message .= $this->translator->translate( 'Installation_SystemCheckWinPdoAndMysqliHelp', array('<br /><br /><code>extension=php_mysqli.dll</code><br /><code>extension=php_pdo.dll</code><br /><code>extension=php_pdo_mysql.dll</code><br />') ); } else { $message .= $this->translator->translate( 'Installation_SystemCheckPdoAndMysqliHelp', array( '<br /><br /><code>--with-mysqli</code><br /><code>--with-pdo-mysql</code><br /><br />', '<br /><br /><code>extension=mysqli.so</code><br /><code>extension=pdo.so</code><br /><code>extension=pdo_mysql.so</code><br />' ) ); } $message .= $this->translator->translate('Installation_RestartWebServer') . '<br/><br/>'; $message .= $this->translator->translate('Installation_SystemCheckPhpPdoAndMysqli', array( '<a style="color:red" href="http://php.net/pdo">', '</a>', '<a style="color:red" href="http://php.net/mysqli">', '</a>', )); $message .= '</p>'; return $message; }
/** * @return string */ protected static function getPythonBinary() { if (\Piwik\SettingsServer::isWindows()) { return "C:\\Python27\\python.exe"; } if (IntegrationTestCase::isTravisCI()) { return 'python2.6'; } return 'python'; }
public function execute() { $label = $this->translator->translate('CustomPiwikJs_DiagnosticPiwikJsWritable'); $file = new File(PIWIK_DOCUMENT_ROOT . '/piwik.js'); if ($file->hasWriteAccess()) { return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, '')); } $comment = $this->translator->translate('CustomPiwikJs_DiagnosticPiwikJsNotWritable'); if (!SettingsServer::isWindows()) { $realpath = Filesystem::realpath(PIWIK_INCLUDE_PATH . '/piwik.js'); $command = "<br/><code> chmod +w {$realpath}<br/> chown " . Filechecks::getUserAndGroup() . " " . $realpath . "</code><br />"; $comment .= $this->translator->translate('CustomPiwikJs_DiagnosticPiwikJsMakeWritable', $command); } return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment)); }
/** * Batch insert into table from CSV (or other delimited) file. * * @param string $tableName Name of table * @param array $fields Field names * @param string $filePath Path name of a file. * @param array $fileSpec File specifications (delimiter, line terminator, etc) * * @throws Exception * @return bool True if successful; false otherwise */ public static function createTableFromCSVFile($tableName, $fields, $filePath, $fileSpec) { // Chroot environment: prefix the path with the absolute chroot path $chrootPath = Config::getInstance()->General['absolute_chroot_path']; if (!empty($chrootPath)) { $filePath = $chrootPath . $filePath; } // On Windows, MySQL expects forward slashes as directory separators if (SettingsServer::isWindows()) { $filePath = str_replace('\\', '/', $filePath); } $query = "\n\t\t\t\t'{$filePath}'\n\t\t\tREPLACE\n\t\t\tINTO TABLE\n\t\t\t\t`" . $tableName . "`"; if (isset($fileSpec['charset'])) { $query .= ' CHARACTER SET ' . $fileSpec['charset']; } $fieldList = '(' . join(',', $fields) . ')'; $query .= "\n\t\t\tFIELDS TERMINATED BY\n\t\t\t\t'" . $fileSpec['delim'] . "'\n\t\t\tENCLOSED BY\n\t\t\t\t'" . $fileSpec['quote'] . "'\n\t\t"; if (isset($fileSpec['escape'])) { $query .= " ESCAPED BY '" . $fileSpec['escape'] . "'"; } $query .= "\n\t\t\tLINES TERMINATED BY\n\t\t\t\t'" . $fileSpec['eol'] . "'\n\t\t\t{$fieldList}\n\t\t"; /* * First attempt: assume web server and MySQL server are on the same machine; * this requires that the db user have the FILE privilege; however, since this is * a global privilege, it may not be granted due to security concerns */ $keywords = array(''); /* * Second attempt: using the LOCAL keyword means the client reads the file and sends it to the server; * the LOCAL keyword may trigger a known PHP PDO\MYSQL bug when MySQL not built with --enable-local-infile * @see http://bugs.php.net/bug.php?id=54158 */ $openBaseDir = ini_get('open_basedir'); $safeMode = ini_get('safe_mode'); if (empty($openBaseDir) && empty($safeMode)) { // php 5.x - LOAD DATA LOCAL INFILE is disabled if open_basedir restrictions or safe_mode enabled $keywords[] = 'LOCAL '; } $exceptions = array(); foreach ($keywords as $keyword) { $queryStart = 'LOAD DATA ' . $keyword . 'INFILE '; $sql = $queryStart . $query; try { $result = @Db::exec($sql); if (empty($result) || $result < 0) { continue; } return true; } catch (Exception $e) { // echo $sql . ' ---- ' . $e->getMessage(); $code = $e->getCode(); $message = $e->getMessage() . ($code ? "[{$code}]" : ''); if (!Db::get()->isErrNo($e, '1148')) { Log::info("LOAD DATA INFILE failed... Error was: %s", $message); } $exceptions[] = "\n Try #" . (count($exceptions) + 1) . ': ' . $queryStart . ": " . $message; } } if (count($exceptions)) { throw new Exception(implode(",", $exceptions)); } return false; }
/** * readfile() replacement. * Behaves similar to readfile($filename); * * @author anthon (dot) pang (at) gmail (dot) com * * @param string $filename * @param bool $useIncludePath * @param resource $context * @return int the number of bytes read from the file, or false if an error occurs */ function _readfile($filename, $byteStart, $byteEnd, $useIncludePath = false, $context = null) { $count = @filesize($filename); // built-in function has a 2 MB limit when using mmap if (function_exists('readfile') && $count <= 2 * 1024 * 1024 && $byteStart == 0 && $byteEnd == $count) { return @readfile($filename, $useIncludePath, $context); } // when in doubt (or when readfile() function is disabled) $handle = @fopen($filename, SettingsServer::isWindows() ? "rb" : "r"); if ($handle) { fseek($handle, $byteStart); for ($pos = $byteStart; $pos < $byteEnd && !feof($handle); $pos = ftell($handle)) { echo fread($handle, min(8192, $byteEnd - $pos)); ob_flush(); flush(); } fclose($handle); return $byteEnd - $byteStart; } return false; }
/** * Returns the help text displayed to suggest which command to run to give writable access to a file or directory * * @param string $realpath * @return string */ private static function getMakeWritableCommand($realpath) { if (SettingsServer::isWindows()) { return "<code>cacls {$realpath} /t /g " . self::getUser() . ":f</code><br />\n"; } return "<code>chmod -R 0755 {$realpath}</code><br />"; }
/** * Get system information */ public static function getSystemInformation() { global $piwik_minimumPHPVersion; $minimumMemoryLimit = Config::getInstance()->General['minimum_memory_limit']; $infos = array(); $directoriesToCheck = array('/tmp/', '/tmp/assets/', '/tmp/cache/', '/tmp/climulti/', '/tmp/latest/', '/tmp/logs/', '/tmp/sessions/', '/tmp/tcpdf/', '/tmp/templates_c/'); if (!DbHelper::isInstalled()) { // at install, need /config to be writable (so we can create config.ini.php) $directoriesToCheck[] = '/config/'; } $infos['directories'] = Filechecks::checkDirectoriesWritable($directoriesToCheck); $infos['can_auto_update'] = Filechecks::canAutoUpdate(); self::initServerFilesForSecurity(); $infos['phpVersion_minimum'] = $piwik_minimumPHPVersion; $infos['phpVersion'] = PHP_VERSION; $infos['phpVersion_ok'] = self::isPhpVersionValid($infos['phpVersion']); // critical errors $extensions = @get_loaded_extensions(); $needed_extensions = array('zlib', 'SPL', 'iconv', 'json', 'mbstring'); // HHVM provides the required subset of Reflection but lists Reflections as missing if (!defined('HHVM_VERSION')) { $needed_extensions[] = 'Reflection'; } $infos['needed_extensions'] = $needed_extensions; $infos['missing_extensions'] = array(); foreach ($needed_extensions as $needed_extension) { if (!in_array($needed_extension, $extensions)) { $infos['missing_extensions'][] = $needed_extension; } } // Special case for mbstring if (!function_exists('mb_get_info') || (int) ini_get('mbstring.func_overload') != 0) { $infos['missing_extensions'][] = 'mbstring'; } $infos['pdo_ok'] = false; if (in_array('PDO', $extensions)) { $infos['pdo_ok'] = true; } $infos['adapters'] = Adapter::getAdapters(); $needed_functions = array('debug_backtrace', 'create_function', 'eval', 'gzcompress', 'gzuncompress', 'pack'); $infos['needed_functions'] = $needed_functions; $infos['missing_functions'] = array(); foreach ($needed_functions as $needed_function) { if (!self::functionExists($needed_function)) { $infos['missing_functions'][] = $needed_function; } } // warnings $desired_extensions = array('json', 'libxml', 'dom', 'SimpleXML'); $infos['desired_extensions'] = $desired_extensions; $infos['missing_desired_extensions'] = array(); foreach ($desired_extensions as $desired_extension) { if (!in_array($desired_extension, $extensions)) { $infos['missing_desired_extensions'][] = $desired_extension; } } $desired_functions = array('set_time_limit', 'mail', 'parse_ini_file', 'glob', 'gzopen'); $infos['missing_desired_functions'] = array(); foreach ($desired_functions as $desired_function) { if (!self::functionExists($desired_function)) { $infos['missing_desired_functions'][] = $desired_function; } } $sessionAutoStarted = (int) ini_get('session.auto_start'); if ($sessionAutoStarted) { $infos['missing_desired_functions'][] = 'session.auto_start'; } $desired_settings = array('session.auto_start'); $infos['desired_functions'] = array_merge($desired_functions, $desired_settings); $infos['openurl'] = Http::getTransportMethod(); $infos['gd_ok'] = SettingsServer::isGdExtensionEnabled(); $serverSoftware = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : ''; $infos['serverVersion'] = addslashes($serverSoftware); $infos['serverOs'] = @php_uname(); $infos['serverTime'] = date('H:i:s'); $infos['memoryMinimum'] = $minimumMemoryLimit; $infos['memory_ok'] = true; $infos['memoryCurrent'] = ''; $raised = SettingsServer::raiseMemoryLimitIfNecessary(); if (($memoryValue = SettingsServer::getMemoryLimitValue()) > 0) { $infos['memoryCurrent'] = $memoryValue . 'M'; $infos['memory_ok'] = $memoryValue >= $minimumMemoryLimit; } $infos['isWindows'] = SettingsServer::isWindows(); $integrityInfo = Filechecks::getFileIntegrityInformation(); $infos['integrity'] = $integrityInfo[0]; $infos['integrityErrorMessages'] = array(); if (isset($integrityInfo[1])) { if ($infos['integrity'] == false) { $infos['integrityErrorMessages'][] = Piwik::translate('General_FileIntegrityWarningExplanation'); } $infos['integrityErrorMessages'] = array_merge($infos['integrityErrorMessages'], array_slice($integrityInfo, 1)); } $infos['timezone'] = SettingsServer::isTimezoneSupportEnabled(); $process = new CliMulti(); $infos['cli_process_ok'] = $process->supportsAsync(); $infos['tracker_status'] = Common::getRequestVar('trackerStatus', 0, 'int'); // check if filesystem is NFS, if it is file based sessions won't work properly $infos['is_nfs'] = Filesystem::checkIfFileSystemIsNFS(); $infos = self::enrichSystemChecks($infos); return $infos; }
public static function isSupported() { if (SettingsServer::isWindows()) { return false; } if (self::shellExecFunctionIsDisabled()) { return false; } if (self::isSystemNotSupported()) { return false; } if (!self::commandExists('ps') || !self::returnsSuccessCode('ps') || !self::commandExists('awk')) { return false; } if (count(self::getRunningProcesses()) > 0) { return true; } if (!self::isProcFSMounted()) { return false; } return true; }
private function setLogFilePathFromConfig($logConfig) { $logPath = $logConfig[self::LOGGER_FILE_PATH_CONFIG_OPTION]; if (!SettingsServer::isWindows() && $logPath[0] != '/') { $logPath = PIWIK_USER_PATH . DIRECTORY_SEPARATOR . $logPath; } $logPath = SettingsPiwik::rewriteTmpPathWithInstanceId($logPath); if (is_dir($logPath)) { $logPath .= '/piwik.log'; } $this->logToFilePath = $logPath; }
/** * @param OutputInterface $output */ protected function writeAlertMessageWhenCommandExecutedWithUnexpectedUser(OutputInterface $output) { if (SettingsServer::isWindows()) { // does not work on windows return; } $processUserAndGroup = Filechecks::getUserAndGroup(); $fileOwnerUserAndGroup = Filechecks::getOwnerOfPiwikFiles(); if (!$fileOwnerUserAndGroup || $processUserAndGroup == $fileOwnerUserAndGroup) { // current process user/group appear to be same as the Piwik filesystem user/group -> OK return; } $output->writeln(sprintf("<comment>It appears you have executed this update with user %s, while your Piwik files are owned by %s. \n\nTo ensure that the Piwik files are readable by the correct user, you may need to run the following command (or a similar command depending on your server configuration):\n\n\$ %s</comment>", $processUserAndGroup, $fileOwnerUserAndGroup, Filechecks::getCommandToChangeOwnerOfPiwikFiles())); }
/** * Checks that "HTTP/1.0 505 Internal server error" is returned when Piwik::serverStaticFile is called with a * non-readable file * * @group Core */ public function test_nonReadableFile() { /** * This test would fail on a windows environment because it is not possible to remove reading rights on a * windows file using PHP. */ if (SettingsServer::isWindows()) { return; } // Setting mode so the testing file is non-readable chmod(TEST_FILE_LOCATION, 0200); $curlHandle = curl_init(); curl_setopt($curlHandle, CURLOPT_URL, $url = $this->getTestFileSrvModeUrl()); curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true); curl_exec($curlHandle); $responseInfo = curl_getinfo($curlHandle); curl_close($curlHandle); // Restoring file mode chmod(TEST_FILE_LOCATION, 0644); $this->assertEquals($responseInfo["http_code"], 505); }
/** * readfile() replacement. * Behaves similar to readfile($filename); * * @author anthon (dot) pang (at) gmail (dot) com * * @param string $filename * @param bool $useIncludePath * @param resource $context * @return int the number of bytes read from the file, or false if an error occurs */ function _readfile($filename, $useIncludePath = false, $context = null) { $count = @filesize($filename); // built-in function has a 2 MB limit when using mmap if (function_exists('readfile') && $count <= 2 * 1024 * 1024) { return @readfile($filename, $useIncludePath, $context); } // when in doubt (or when readfile() function is disabled) $handle = @fopen($filename, SettingsServer::isWindows() ? "rb" : "r"); if ($handle) { while (!feof($handle)) { echo fread($handle, 8192); ob_flush(); flush(); } fclose($handle); return $count; } return false; }
/** * Get system information */ public static function getSystemInformation() { global $piwik_minimumPHPVersion; $minimumMemoryLimit = Config::getInstance()->General['minimum_memory_limit']; $infos = array(); $infos['general_infos'] = array(); $directoriesToCheck = array(); if (!DbHelper::isInstalled()) { // at install, need /config to be writable (so we can create config.ini.php) $directoriesToCheck[] = '/config/'; } $directoriesToCheck = array_merge($directoriesToCheck, array('/tmp/', '/tmp/assets/', '/tmp/cache/', '/tmp/latest/', '/tmp/logs/', '/tmp/sessions/', '/tmp/tcpdf/', '/tmp/templates_c/')); $infos['directories'] = Filechecks::checkDirectoriesWritable($directoriesToCheck); $infos['can_auto_update'] = Filechecks::canAutoUpdate(); self::initServerFilesForSecurity(); $infos['phpVersion_minimum'] = $piwik_minimumPHPVersion; $infos['phpVersion'] = PHP_VERSION; $infos['phpVersion_ok'] = version_compare($piwik_minimumPHPVersion, $infos['phpVersion']) === -1; // critical errors $extensions = @get_loaded_extensions(); $needed_extensions = array('zlib', 'SPL', 'iconv', 'Reflection'); $infos['needed_extensions'] = $needed_extensions; $infos['missing_extensions'] = array(); foreach ($needed_extensions as $needed_extension) { if (!in_array($needed_extension, $extensions)) { $infos['missing_extensions'][] = $needed_extension; } } $infos['pdo_ok'] = false; if (in_array('PDO', $extensions)) { $infos['pdo_ok'] = true; } $infos['adapters'] = Adapter::getAdapters(); $needed_functions = array('debug_backtrace', 'create_function', 'eval', 'gzcompress', 'gzuncompress', 'pack'); $infos['needed_functions'] = $needed_functions; $infos['missing_functions'] = array(); foreach ($needed_functions as $needed_function) { if (!self::functionExists($needed_function)) { $infos['missing_functions'][] = $needed_function; } } // warnings $desired_extensions = array('json', 'libxml', 'dom', 'SimpleXML'); $infos['desired_extensions'] = $desired_extensions; $infos['missing_desired_extensions'] = array(); foreach ($desired_extensions as $desired_extension) { if (!in_array($desired_extension, $extensions)) { $infos['missing_desired_extensions'][] = $desired_extension; } } $desired_functions = array('set_time_limit', 'mail', 'parse_ini_file', 'glob'); $infos['desired_functions'] = $desired_functions; $infos['missing_desired_functions'] = array(); foreach ($desired_functions as $desired_function) { if (!self::functionExists($desired_function)) { $infos['missing_desired_functions'][] = $desired_function; } } $infos['openurl'] = Http::getTransportMethod(); $infos['gd_ok'] = SettingsServer::isGdExtensionEnabled(); $infos['hasMbstring'] = false; $infos['multibyte_ok'] = true; if (function_exists('mb_internal_encoding')) { $infos['hasMbstring'] = true; if ((int) ini_get('mbstring.func_overload') != 0) { $infos['multibyte_ok'] = false; } } $serverSoftware = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : ''; $infos['serverVersion'] = addslashes($serverSoftware); $infos['serverOs'] = @php_uname(); $infos['serverTime'] = date('H:i:s'); $infos['registerGlobals_ok'] = ini_get('register_globals') == 0; $infos['memoryMinimum'] = $minimumMemoryLimit; $infos['memory_ok'] = true; $infos['memoryCurrent'] = ''; $raised = SettingsServer::raiseMemoryLimitIfNecessary(); if (($memoryValue = SettingsServer::getMemoryLimitValue()) > 0) { $infos['memoryCurrent'] = $memoryValue . 'M'; $infos['memory_ok'] = $memoryValue >= $minimumMemoryLimit; } $infos['isWindows'] = SettingsServer::isWindows(); $integrityInfo = Filechecks::getFileIntegrityInformation(); $infos['integrity'] = $integrityInfo[0]; $infos['integrityErrorMessages'] = array(); if (isset($integrityInfo[1])) { if ($infos['integrity'] == false) { $infos['integrityErrorMessages'][] = Piwik::translate('General_FileIntegrityWarningExplanation'); } $infos['integrityErrorMessages'] = array_merge($infos['integrityErrorMessages'], array_slice($integrityInfo, 1)); } $infos['timezone'] = SettingsServer::isTimezoneSupportEnabled(); $infos['tracker_status'] = Common::getRequestVar('trackerStatus', 0, 'int'); $infos['protocol'] = ProxyHeaders::getProtocolInformation(); if (!\Piwik\ProxyHttp::isHttps() && $infos['protocol'] !== null) { $infos['general_infos']['assume_secure_protocol'] = '1'; } if (count($headers = ProxyHeaders::getProxyClientHeaders()) > 0) { $infos['general_infos']['proxy_client_headers'] = $headers; } if (count($headers = ProxyHeaders::getProxyHostHeaders()) > 0) { $infos['general_infos']['proxy_host_headers'] = $headers; } // check if filesystem is NFS, if it is file based sessions won't work properly $infos['is_nfs'] = Filesystem::checkIfFileSystemIsNFS(); $infos = self::enrichSystemChecks($infos); return $infos; }