public function execute()
 {
     $label = $this->translator->translate('Installation_SystemCheckWriteDirs');
     $result = new DiagnosticResult($label);
     $directories = Filechecks::checkDirectoriesWritable($this->getDirectories());
     $error = false;
     foreach ($directories as $directory => $isWritable) {
         if ($isWritable) {
             $status = DiagnosticResult::STATUS_OK;
         } else {
             $status = DiagnosticResult::STATUS_ERROR;
             $error = true;
         }
         $result->addItem(new DiagnosticResultItem($status, $directory));
     }
     if ($error) {
         $longErrorMessage = $this->translator->translate('Installation_SystemCheckWriteDirsHelp');
         $longErrorMessage .= '<ul>';
         foreach ($directories as $directory => $isWritable) {
             if (!$isWritable) {
                 $longErrorMessage .= sprintf('<li><pre>chmod a+w %s</pre></li>', $directory);
             }
         }
         $longErrorMessage .= '</ul>';
         $result->setLongErrorMessage($longErrorMessage);
     }
     return array($result);
 }
Example #2
0
 protected function write(array $record)
 {
     try {
         parent::write($record);
     } catch (\UnexpectedValueException $e) {
         throw new \Exception(Filechecks::getErrorMessageMissingPermissions($this->url));
     }
 }
 public function execute()
 {
     $label = $this->translator->translate('Installation_SystemCheckOpenURL');
     $httpMethod = Http::getTransportMethod();
     if ($httpMethod) {
         return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, $httpMethod));
     }
     $canAutoUpdate = Filechecks::canAutoUpdate();
     $comment = $this->translator->translate('Installation_SystemCheckOpenURLHelp');
     if (!$canAutoUpdate) {
         $comment .= '<br/>' . $this->translator->translate('Installation_SystemCheckAutoUpdateHelp');
     }
     return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
 }
Example #4
0
 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));
 }
 public function execute()
 {
     $label = $this->translator->translate('Installation_SystemCheckFileIntegrity');
     $messages = Filechecks::getFileIntegrityInformation();
     $ok = array_shift($messages);
     if (empty($messages)) {
         return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK));
     }
     if ($ok) {
         $status = DiagnosticResult::STATUS_WARNING;
         return array(DiagnosticResult::singleResult($label, $status, $messages[0]));
     }
     $comment = $this->translator->translate('General_FileIntegrityWarningExplanation');
     // Keep only the 20 first lines else it becomes unmanageable
     if (count($messages) > 20) {
         $messages = array_slice($messages, 0, 20);
         $messages[] = '...';
     }
     $comment .= '<br/><br/><pre style="overflow-x: scroll;max-width: 600px;">' . implode("\n", $messages) . '</pre>';
     return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
 }
Example #6
0
 /**
  * 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;
 }
Example #7
0
 private function downloadArchive($version, $url)
 {
     $path = $this->tmpPath . self::PATH_TO_EXTRACT_LATEST_VERSION;
     $archiveFile = $path . 'latest.zip';
     Filechecks::dieIfDirectoriesNotWritable(array($path));
     $url .= '?cb=' . $version;
     try {
         Http::fetchRemoteFile($url, $archiveFile, 0, self::DOWNLOAD_TIMEOUT);
     } catch (Exception $e) {
         // We throw a specific exception allowing to offer HTTP download if HTTPS failed
         throw new ArchiveDownloadException($e);
     }
     return $archiveFile;
 }
Example #8
0
 private static function tryToCopyFileAndVerifyItWasCopied($source, $dest)
 {
     if (!@copy($source, $dest)) {
         @chmod($dest, 0755);
         if (!@copy($source, $dest)) {
             $message = "Error while creating/copying file to <code>{$dest}</code>. <br />" . Filechecks::getErrorMessageMissingPermissions(self::getPathToPiwikRoot());
             throw new Exception($message);
         }
     }
     if (file_exists($source) && file_exists($dest)) {
         return self::havePhpFilesSameContent($source, $dest);
     }
     return true;
 }
Example #9
0
 private function doWelcomeUpdates($view, $componentsWithUpdateFile)
 {
     $view->new_piwik_version = Version::VERSION;
     $view->commandUpgradePiwik = "<br /><code>php " . Filesystem::getPathToPiwikRoot() . "/console core:update </code>";
     $pluginNamesToUpdate = array();
     $dimensionsToUpdate = array();
     $coreToUpdate = false;
     // handle case of existing database with no tables
     if (!DbHelper::isInstalled()) {
         $this->errorMessages[] = Piwik::translate('CoreUpdater_EmptyDatabaseError', Config::getInstance()->database['dbname']);
         $this->coreError = true;
         $currentVersion = 'N/A';
     } else {
         $this->errorMessages = array();
         try {
             $currentVersion = Option::get('version_core');
         } catch (Exception $e) {
             $currentVersion = '<= 0.2.9';
         }
         foreach ($componentsWithUpdateFile as $name => $filenames) {
             if ($name == 'core') {
                 $coreToUpdate = true;
             } elseif (0 === strpos($name, 'log_')) {
                 $dimensionsToUpdate[] = $name;
             } else {
                 $pluginNamesToUpdate[] = $name;
             }
         }
     }
     // check file integrity
     $integrityInfo = Filechecks::getFileIntegrityInformation();
     if (isset($integrityInfo[1])) {
         if ($integrityInfo[0] == false) {
             $this->warningMessages[] = Piwik::translate('General_FileIntegrityWarningExplanation');
         }
         $this->warningMessages = array_merge($this->warningMessages, array_slice($integrityInfo, 1));
     }
     Filesystem::deleteAllCacheOnUpdate();
     $view->coreError = $this->coreError;
     $view->warningMessages = $this->warningMessages;
     $view->errorMessages = $this->errorMessages;
     $view->current_piwik_version = $currentVersion;
     $view->pluginNamesToUpdate = $pluginNamesToUpdate;
     $view->dimensionsToUpdate = $dimensionsToUpdate;
     $view->coreToUpdate = $coreToUpdate;
 }
 private function makeSureFoldersAreWritable()
 {
     Filechecks::dieIfDirectoriesNotWritable(array(self::PATH_TO_DOWNLOAD, self::PATH_TO_EXTRACT));
 }
Example #11
0
 /**
  * Start the session
  *
  * @param array|bool $options An array of configuration options; the auto-start (bool) setting is ignored
  * @return void
  * @throws Exception if starting a session fails
  */
 public static function start($options = false)
 {
     if (headers_sent() || self::$sessionStarted || defined('PIWIK_ENABLE_SESSION_START') && !PIWIK_ENABLE_SESSION_START) {
         return;
     }
     self::$sessionStarted = true;
     // use cookies to store session id on the client side
     @ini_set('session.use_cookies', '1');
     // prevent attacks involving session ids passed in URLs
     @ini_set('session.use_only_cookies', '1');
     // advise browser that session cookie should only be sent over secure connection
     if (ProxyHttp::isHttps()) {
         @ini_set('session.cookie_secure', '1');
     }
     // advise browser that session cookie should only be accessible through the HTTP protocol (i.e., not JavaScript)
     @ini_set('session.cookie_httponly', '1');
     // don't use the default: PHPSESSID
     @ini_set('session.name', self::SESSION_NAME);
     // proxies may cause the referer check to fail and
     // incorrectly invalidate the session
     @ini_set('session.referer_check', '');
     $currentSaveHandler = ini_get('session.save_handler');
     $config = Config::getInstance();
     if (self::isFileBasedSessions()) {
         // Note: this handler doesn't work well in load-balanced environments and may have a concurrency issue with locked session files
         // for "files", use our own folder to prevent local session file hijacking
         $sessionPath = self::getSessionsDirectory();
         // We always call mkdir since it also chmods the directory which might help when permissions were reverted for some reasons
         Filesystem::mkdir($sessionPath);
         @ini_set('session.save_handler', 'files');
         @ini_set('session.save_path', $sessionPath);
     } elseif ($config->General['session_save_handler'] === 'dbtable' || in_array($currentSaveHandler, array('user', 'mm'))) {
         // We consider these to be misconfigurations, in that:
         // - user  - we can't verify that user-defined session handler functions have already been set via session_set_save_handler()
         // - mm    - this handler is not recommended, unsupported, not available for Windows, and has a potential concurrency issue
         $config = array('name' => Common::prefixTable('session'), 'primary' => 'id', 'modifiedColumn' => 'modified', 'dataColumn' => 'data', 'lifetimeColumn' => 'lifetime');
         $saveHandler = new DbTable($config);
         if ($saveHandler) {
             self::setSaveHandler($saveHandler);
         }
     }
     // garbage collection may disabled by default (e.g., Debian)
     if (ini_get('session.gc_probability') == 0) {
         @ini_set('session.gc_probability', 1);
     }
     try {
         parent::start();
         register_shutdown_function(array('Zend_Session', 'writeClose'), true);
     } catch (Exception $e) {
         Log::error('Unable to start session: ' . $e->getMessage());
         $enableDbSessions = '';
         if (DbHelper::isInstalled()) {
             $enableDbSessions = "<br/>If you still experience issues after trying these changes,\n\t\t\t            \t\t\twe recommend that you <a href='http://piwik.org/faq/how-to-install/#faq_133' rel='noreferrer' target='_blank'>enable database session storage</a>.";
         }
         $pathToSessions = Filechecks::getErrorMessageMissingPermissions(self::getSessionsDirectory());
         $message = sprintf("Error: %s %s %s\n<pre>Debug: the original error was \n%s</pre>", Piwik::translate('General_ExceptionUnableToStartSession'), $pathToSessions, $enableDbSessions, $e->getMessage());
         $ex = new MissingFilePermissionException($message, $e->getCode(), $e);
         $ex->setIsHtmlMessage();
         throw $ex;
     }
 }
 /**
  * Must be called before dispatch()
  * - checks that directories are writable,
  * - loads the configuration file,
  * - loads the plugin,
  * - inits the DB connection,
  * - etc.
  *
  * @throws Exception
  * @return void
  */
 public function init()
 {
     static $initialized = false;
     if ($initialized) {
         return;
     }
     $initialized = true;
     try {
         Registry::set('timer', new Timer());
         $directoriesToCheck = array('/tmp/', '/tmp/assets/', '/tmp/cache/', '/tmp/logs/', '/tmp/tcpdf/', '/tmp/templates_c/');
         Filechecks::dieIfDirectoriesNotWritable($directoriesToCheck);
         self::assignCliParametersToRequest();
         Translate::loadEnglishTranslation();
         $exceptionToThrow = self::createConfigObject();
         if (Session::isFileBasedSessions()) {
             Session::start();
         }
         $this->handleMaintenanceMode();
         $this->handleSSLRedirection();
         $this->handleProfiler();
         $pluginsManager = \Piwik\Plugin\Manager::getInstance();
         $pluginsToLoad = Config::getInstance()->Plugins['Plugins'];
         $pluginsManager->loadPlugins($pluginsToLoad);
         if ($exceptionToThrow) {
             throw $exceptionToThrow;
         }
         try {
             Db::createDatabaseObject();
             Option::get('TestingIfDatabaseConnectionWorked');
         } catch (Exception $exception) {
             if (self::shouldRethrowException()) {
                 throw $exception;
             }
             /**
              * Triggered if the INI config file has the incorrect format or if certain required configuration
              * options are absent.
              * 
              * This event can be used to start the installation process or to display a custom error message.
              * 
              * @param Exception $exception The exception thrown from creating and testing the database
              *                             connection.
              */
             Piwik::postEvent('Config.badConfigurationFile', array($exception), $pending = true);
             throw $exception;
         }
         // Init the Access object, so that eg. core/Updates/* can enforce Super User and use some APIs
         Access::getInstance();
         /**
          * Triggered just after the platform is initialized and plugins are loaded.
          * 
          * This event can be used to do early initialization.
          * 
          * _Note: At this point the user is not authenticated yet._
          */
         Piwik::postEvent('Request.dispatchCoreAndPluginUpdatesScreen');
         \Piwik\Plugin\Manager::getInstance()->installLoadedPlugins();
         // ensure the current Piwik URL is known for later use
         if (method_exists('Piwik\\SettingsPiwik', 'getPiwikUrl')) {
             $host = SettingsPiwik::getPiwikUrl();
         }
         /**
          * Triggered before the user is authenticated, when the global authentication object
          * should be created.
          * 
          * Plugins that provide their own authentication implementation should use this event
          * to set the global authentication object (which must derive from {@link Piwik\Auth}).
          * 
          * **Example**
          * 
          *     Piwik::addAction('Request.initAuthenticationObject', function() {
          *         Piwik\Registry::set('auth', new MyAuthImplementation());
          *     });
          */
         Piwik::postEvent('Request.initAuthenticationObject');
         try {
             $authAdapter = Registry::get('auth');
         } catch (Exception $e) {
             throw new Exception("Authentication object cannot be found in the Registry. Maybe the Login plugin is not activated?\n                                <br />You can activate the plugin by adding:<br />\n                                <code>Plugins[] = Login</code><br />\n                                under the <code>[Plugins]</code> section in your config/config.ini.php");
         }
         Access::getInstance()->reloadAccess($authAdapter);
         // Force the auth to use the token_auth if specified, so that embed dashboard
         // and all other non widgetized controller methods works fine
         if (($token_auth = Common::getRequestVar('token_auth', false, 'string')) !== false) {
             Request::reloadAuthUsingTokenAuth();
         }
         SettingsServer::raiseMemoryLimitIfNecessary();
         Translate::reloadLanguage();
         $pluginsManager->postLoadPlugins();
         /**
          * Triggered after the platform is initialized and after the user has been authenticated, but
          * before the platform has handled the request.
          * 
          * Piwik uses this event to check for updates to Piwik.
          */
         Piwik::postEvent('Updater.checkForUpdates');
     } catch (Exception $e) {
         if (self::shouldRethrowException()) {
             throw $e;
         }
         $debugTrace = $e->getTraceAsString();
         Piwik_ExitWithMessage($e->getMessage(), $debugTrace, true);
     }
 }
Example #13
0
 /**
  * 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;
 }
Example #14
0
 /**
  * @param $path
  * @return string
  */
 private function getMessageWhenFileExistsButNotReadable($path)
 {
     $format = " \n<b>» %s </b>";
     if (Common::isPhpCliMode()) {
         $format = "\n » %s \n";
     }
     return sprintf($format, $this->translator->translate('General_ExceptionConfigurationFilePleaseCheckReadableByUser', array($path, Filechecks::getUser())));
 }
Example #15
0
 private function logToFile($level, $tag, $datetime, $message)
 {
     if (is_string($message)) {
         $message = $this->formatMessage($level, $tag, $datetime, $message);
     } else {
         $logger = $this;
         /**
          * Triggered when trying to log an object to a file. Plugins can use
          * this event to convert objects to strings before they are logged.
          *
          * **Example**
          * 
          *     public function formatFileMessage(&$message, $level, $tag, $datetime, $logger) {
          *         if ($message instanceof MyCustomDebugInfo) {
          *             $message = $message->formatForFile();
          *         }
          *     }
          * 
          * @param mixed &$message The object that is being logged. Event handlers should
          *                        check if the object is of a certain type and if it is,
          *                        set `$message` to the string that should be logged.
          * @param int $level The log level used with this log entry.
          * @param string $tag The current plugin that started logging (or if no plugin,
          *                    the current class).
          * @param string $datetime Datetime of the logging call.
          * @param Log $logger The Log singleton.
          */
         Piwik::postEvent(self::FORMAT_FILE_MESSAGE_EVENT, array(&$message, $level, $tag, $datetime, $logger));
     }
     if (empty($message)) {
         return;
     }
     if (!file_put_contents($this->logToFilePath, $message . "\n", FILE_APPEND)) {
         $message = Filechecks::getErrorMessageMissingPermissions($this->logToFilePath);
         throw new \Exception($message);
     }
 }
Example #16
0
 /**
  * Copies a file from `$source` to `$dest`.
  *
  * @param string $source A path to a file, eg. './tmp/latest/index.php'. The file must exist.
  * @param string $dest A path to a file, eg. './index.php'. The file does not have to exist.
  * @param bool $excludePhp Whether to avoid copying files if the file is related to PHP
  *                         (includes .php, .tpl, .twig files).
  * @throws Exception If the file cannot be copied.
  * @return true
  * @api
  */
 public static function copy($source, $dest, $excludePhp = false)
 {
     static $phpExtensions = array('php', 'tpl', 'twig');
     if ($excludePhp) {
         $path_parts = pathinfo($source);
         if (in_array($path_parts['extension'], $phpExtensions)) {
             return true;
         }
     }
     if (!@copy($source, $dest)) {
         @chmod($dest, 0755);
         if (!@copy($source, $dest)) {
             $message = "Error while creating/copying file to <code>{$dest}</code>. <br />" . Filechecks::getErrorMessageMissingPermissions(self::getPathToPiwikRoot());
             throw new Exception($message);
         }
     }
     return true;
 }
Example #17
0
 /**
  * @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()));
 }
 /**
  * Must be called before dispatch()
  * - checks that directories are writable,
  * - loads the configuration file,
  * - loads the plugin,
  * - inits the DB connection,
  * - etc.
  *
  * @throws Exception
  * @return void
  */
 public function init()
 {
     static $initialized = false;
     if ($initialized) {
         return;
     }
     $initialized = true;
     $tmpPath = StaticContainer::get('path.tmp');
     $directoriesToCheck = array($tmpPath, $tmpPath . '/assets/', $tmpPath . '/cache/', $tmpPath . '/logs/', $tmpPath . '/tcpdf/', $tmpPath . '/templates_c/');
     Filechecks::dieIfDirectoriesNotWritable($directoriesToCheck);
     $this->handleMaintenanceMode();
     $this->handleProfiler();
     $this->handleSSLRedirection();
     Plugin\Manager::getInstance()->loadPluginTranslations();
     Plugin\Manager::getInstance()->loadActivatedPlugins();
     // try to connect to the database
     try {
         Db::createDatabaseObject();
         Db::fetchAll("SELECT DATABASE()");
     } catch (Exception $exception) {
         if (self::shouldRethrowException()) {
             throw $exception;
         }
         Log::debug($exception);
         /**
          * Triggered when Piwik cannot connect to the database.
          *
          * This event can be used to start the installation process or to display a custom error
          * message.
          *
          * @param Exception $exception The exception thrown from creating and testing the database
          *                             connection.
          */
         Piwik::postEvent('Db.cannotConnectToDb', array($exception), $pending = true);
         throw $exception;
     }
     // try to get an option (to check if data can be queried)
     try {
         Option::get('TestingIfDatabaseConnectionWorked');
     } catch (Exception $exception) {
         if (self::shouldRethrowException()) {
             throw $exception;
         }
         Log::debug($exception);
         /**
          * Triggered when Piwik cannot access database data.
          *
          * This event can be used to start the installation process or to display a custom error
          * message.
          *
          * @param Exception $exception The exception thrown from trying to get an option value.
          */
         Piwik::postEvent('Config.badConfigurationFile', array($exception), $pending = true);
         throw $exception;
     }
     // Init the Access object, so that eg. core/Updates/* can enforce Super User and use some APIs
     Access::getInstance();
     /**
      * Triggered just after the platform is initialized and plugins are loaded.
      *
      * This event can be used to do early initialization.
      *
      * _Note: At this point the user is not authenticated yet._
      */
     Piwik::postEvent('Request.dispatchCoreAndPluginUpdatesScreen');
     $this->throwIfPiwikVersionIsOlderThanDBSchema();
     \Piwik\Plugin\Manager::getInstance()->installLoadedPlugins();
     // ensure the current Piwik URL is known for later use
     if (method_exists('Piwik\\SettingsPiwik', 'getPiwikUrl')) {
         SettingsPiwik::getPiwikUrl();
     }
     /**
      * Triggered before the user is authenticated, when the global authentication object
      * should be created.
      *
      * Plugins that provide their own authentication implementation should use this event
      * to set the global authentication object (which must derive from {@link Piwik\Auth}).
      *
      * **Example**
      *
      *     Piwik::addAction('Request.initAuthenticationObject', function() {
      *         StaticContainer::getContainer()->set('Piwik\Auth', new MyAuthImplementation());
      *     });
      */
     Piwik::postEvent('Request.initAuthenticationObject');
     try {
         $authAdapter = StaticContainer::get('Piwik\\Auth');
     } catch (Exception $e) {
         $message = "Authentication object cannot be found in the container. Maybe the Login plugin is not activated?\n                        <br />You can activate the plugin by adding:<br />\n                        <code>Plugins[] = Login</code><br />\n                        under the <code>[Plugins]</code> section in your config/config.ini.php";
         $ex = new AuthenticationFailedException($message);
         $ex->setIsHtmlMessage();
         throw $ex;
     }
     Access::getInstance()->reloadAccess($authAdapter);
     // Force the auth to use the token_auth if specified, so that embed dashboard
     // and all other non widgetized controller methods works fine
     if (Common::getRequestVar('token_auth', false, 'string') !== false) {
         Request::reloadAuthUsingTokenAuth();
     }
     SettingsServer::raiseMemoryLimitIfNecessary();
     \Piwik\Plugin\Manager::getInstance()->postLoadPlugins();
     /**
      * Triggered after the platform is initialized and after the user has been authenticated, but
      * before the platform has handled the request.
      *
      * Piwik uses this event to check for updates to Piwik.
      */
     Piwik::postEvent('Platform.initialized');
 }
Example #19
0
 private function logToFile($level, $tag, $datetime, $message)
 {
     $message = $this->getMessageFormattedFile($level, $tag, $datetime, $message);
     if (empty($message)) {
         return;
     }
     if (!file_put_contents($this->logToFilePath, $message, FILE_APPEND)) {
         $message = Filechecks::getErrorMessageMissingPermissions($this->logToFilePath);
         throw new \Exception($message);
     }
 }
Example #20
0
 public function uninstall($redirectAfter = true)
 {
     $pluginName = $this->initPluginModification(static::UNINSTALL_NONCE);
     $this->dieIfPluginsAdminIsDisabled();
     $uninstalled = \Piwik\Plugin\Manager::getInstance()->uninstallPlugin($pluginName);
     if (!$uninstalled) {
         $path = Filesystem::getPathToPiwikRoot() . '/plugins/' . $pluginName . '/';
         $messagePermissions = Filechecks::getErrorMessageMissingPermissions($path);
         $messageIntro = $this->translator->translate("Warning: \"%s\" could not be uninstalled. Piwik did not have enough permission to delete the files in {$path}. ", $pluginName);
         $exitMessage = $messageIntro . "<br/><br/>" . $messagePermissions;
         $exitMessage .= "<br> Or manually delete this directory (using FTP or SSH access)";
         $ex = new MissingFilePermissionException($exitMessage);
         $ex->setIsHtmlMessage();
         throw $ex;
     }
     $this->redirectAfterModification($redirectAfter);
 }
 private function makeSureFoldersAreWritable()
 {
     Filechecks::dieIfDirectoriesNotWritable(array(StaticContainer::get('path.tmp') . self::PATH_TO_DOWNLOAD, self::PATH_TO_EXTRACT));
 }