function addWriteToFile() { Piwik_Common::mkdir(dirname($this->logToFileFilename)); $writerFile = new Zend_Log_Writer_Stream($this->logToFileFilename); $writerFile->setFormatter($this->fileFormatter); $this->addWriter($writerFile); }
/** * A function to store content a cache entry. * * @param string $id The filename where cache entry is stored * @param array $content The cache content * @return bool True if the entry was succesfully stored */ function set($id, $content) { if (!is_dir($this->cachePath)) { Piwik_Common::mkdir($this->cachePath); } if (!is_writable($this->cachePath)) { return false; } $id = $this->cachePath . $id . ".php"; $cache_literal = "<" . "?php\n\n"; $cache_literal .= "\$" . "content = " . var_export($content, true) . ";\n\n"; $cache_literal .= "\$" . "cache_complete = true;\n\n"; $cache_literal .= "?" . ">"; // Write cache to a temp file, then rename it, overwritng the old cache // On *nix systems this should guarantee atomicity $tmp_filename = tempnam($this->cachePath, 'tmp_'); if ($fp = @fopen($tmp_filename, 'wb')) { @fwrite($fp, $cache_literal, strlen($cache_literal)); @fclose($fp); if (!@rename($tmp_filename, $id)) { // On some systems rename() doesn't overwrite destination @unlink($id); if (!@rename($tmp_filename, $id)) { // Make sure that no temporary file is left over // if the destination is not writable @unlink($tmp_filename); } } return true; } return false; }
/** * Sends http request ensuring the request will fail before $timeout seconds * * If no $destinationPath is specified, the trimmed response (without header) is returned as a string. * If a $destinationPath is specified, the response (without header) is saved to a file. * * @param string $aUrl * @param int $timeout * @param string $userAgent * @param string $destinationPath * @param int $followDepth * @return bool true (or string) on success; false on HTTP response error code (1xx or 4xx) * @throws Exception for all other errors */ public static function sendHttpRequest($aUrl, $timeout, $userAgent = null, $destinationPath = null, $followDepth = 0) { // create output file $file = null; if ($destinationPath) { // Ensure destination directory exists Piwik_Common::mkdir(dirname($destinationPath)); if (($file = @fopen($destinationPath, 'wb')) === false || !is_resource($file)) { throw new Exception('Error while creating the file: ' . $destinationPath); } } return self::sendHttpRequestBy(self::getTransportMethod(), $aUrl, $timeout, $userAgent, $destinationPath, $file, $followDepth); }
public static function start($options = false) { if (Piwik_Common::isPhpCliMode()) { return; } // 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 (Piwik_Url::getCurrentScheme() === 'https') { @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 $sessionName = defined('PIWIK_SESSION_NAME') ? PIWIK_SESSION_NAME : 'PIWIK_SESSID'; @ini_set('session.name', $sessionName); // we consider these to be misconfigurations, in that // - user - Piwik doesn't implement user-defined session handler functions // - mm - is not recommended, not supported, not available for Windows, and has a potential concurrency issue $currentSaveHandler = ini_get('session.save_handler'); if ($currentSaveHandler == 'user' || $currentSaveHandler == 'mm') { @ini_set('session.save_handler', 'files'); @ini_set('session.save_path', ''); } // for "files", we want a writeable folder; // for shared hosting, we assume the web server has been securely configured to prevent local session file hijacking if (ini_get('session.save_handler') == 'files') { $sessionPath = ini_get('session.save_path'); if (preg_match('/^[0-9]+;(.*)/', $sessionPath, $matches)) { $sessionPath = $matches[1]; } if (ini_get('safe_mode') || ini_get('open_basedir') || empty($sessionPath) || !@is_readable($sessionPath) || !@is_writable($sessionPath)) { $sessionPath = PIWIK_USER_PATH . '/tmp/sessions'; $ok = true; if (!is_dir($sessionPath)) { Piwik_Common::mkdir($sessionPath); if (!is_dir($sessionPath)) { // Unable to mkdir $sessionPath $ok = false; } } else { if (!@is_writable($sessionPath)) { // $sessionPath is not writable $ok = false; } } if ($ok) { @ini_set('session.save_path', $sessionPath); // garbage collection may disabled by default (e.g., Debian) if (ini_get('session.gc_probability') == 0) { @ini_set('session.gc_probability', 1); } } // else rely on default setting (assuming it is configured to a writeable folder) } } try { Zend_Session::start(); } catch (Exception $e) { // This message is not translateable because translations haven't been loaded yet. Piwik_ExitWithMessage('Unable to start session. Check that session.save_path or tmp/sessions is writeable, and session.auto_start = 0.'); } }
/** * Check if the merged file directory exists and is writable. * * @return string The directory location * @throws Exception if directory is not writable. */ private static function getMergedFileDirectory() { $mergedFileDirectory = PIWIK_USER_PATH . '/' . self::MERGED_FILE_DIR; if (!is_dir($mergedFileDirectory)) { Piwik_Common::mkdir($mergedFileDirectory); } if (!is_writable($mergedFileDirectory)) { throw new Exception("Directory " . $mergedFileDirectory . " has to be writable."); } return $mergedFileDirectory; }
public static function install() { Piwik_Common::mkdir(Zend_Registry::get('config')->smarty->compile_dir); }
/** * Checks if directories are writable and create them if they do not exist. * * @param array $directoriesToCheck array of directories to check - if not given default Piwik directories that needs write permission are checked * @return array directory name => true|false (is writable) */ public static function checkDirectoriesWritable($directoriesToCheck = null) { if ($directoriesToCheck == null) { $directoriesToCheck = array('/config/', '/tmp/', '/tmp/templates_c/', '/tmp/cache/', '/tmp/assets/', '/tmp/latest/', '/tmp/tcpdf/', '/tmp/sessions/'); } $resultCheck = array(); foreach ($directoriesToCheck as $directoryToCheck) { if (!preg_match('/^' . preg_quote(PIWIK_USER_PATH, '/') . '/', $directoryToCheck)) { $directoryToCheck = PIWIK_USER_PATH . $directoryToCheck; } if (!file_exists($directoryToCheck)) { Piwik_Common::mkdir($directoryToCheck); } $directory = Piwik_Common::realpath($directoryToCheck); $resultCheck[$directory] = false; if ($directory !== false && is_writable($directoryToCheck)) { $resultCheck[$directory] = true; } } return $resultCheck; }
/** * Start the session * * @param array|bool $options An array of configuration options; the auto-start (bool) setting is ignored * @return void */ public static function start($options = false) { if (Piwik_Common::isPhpCliMode() || 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 (Piwik::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 $sessionName = defined('PIWIK_SESSION_NAME') ? PIWIK_SESSION_NAME : 'PIWIK_SESSID'; @ini_set('session.name', $sessionName); // 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 = Piwik_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 = PIWIK_USER_PATH . '/tmp/sessions'; // We always call mkdir since it also chmods the directory which might help when permissions were reverted for some reasons Piwik_Common::mkdir($sessionPath); @ini_set('session.save_handler', 'files'); @ini_set('session.save_path', $sessionPath); } else { if ($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 $db = Zend_Registry::get('db'); $config = array('name' => Piwik_Common::prefixTable('session'), 'primary' => 'id', 'modifiedColumn' => 'modified', 'dataColumn' => 'data', 'lifetimeColumn' => 'lifetime', 'db' => $db); $saveHandler = new Piwik_Session_SaveHandler_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 { Zend_Session::start(); register_shutdown_function(array('Zend_Session', 'writeClose'), true); } catch (Exception $e) { Piwik::log('Unable to start session: ' . $e->getMessage()); $enableDbSessions = ''; if (Piwik::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' target='_blank'>enable database session storage</a>."; } $message = 'Error: ' . Piwik_Translate('General_ExceptionUnableToStartSession') . ' ' . Piwik::getErrorMessageMissingPermissions(Piwik_Common::getPathToPiwikRoot() . '/tmp/sessions/') . $enableDbSessions . "\n<pre>Debug: the original error was \n" . $e->getMessage() . "</pre>"; Piwik_ExitWithMessage($message); } }