PageRenderTime 76ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/stats/core/Session.php

https://bitbucket.org/webstar1987923/mycampaignsio
PHP | 156 lines | 90 code | 25 blank | 41 comment | 12 complexity | cb89e58ec3c358f582e03a7b184a0768 MD5 | raw file
Possible License(s): BSD-3-Clause, MPL-2.0-no-copyleft-exception, GPL-3.0, GPL-2.0, WTFPL, BSD-2-Clause, LGPL-2.1, Apache-2.0, MIT, AGPL-3.0
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik;
  10. use Exception;
  11. use Piwik\Container\StaticContainer;
  12. use Piwik\Exception\MissingFilePermissionException;
  13. use Piwik\Session\SaveHandler\DbTable;
  14. use Zend_Session;
  15. /**
  16. * Session initialization.
  17. */
  18. class Session extends Zend_Session
  19. {
  20. const SESSION_NAME = 'PIWIK_SESSID';
  21. protected static $sessionStarted = false;
  22. /**
  23. * Are we using file-based session store?
  24. *
  25. * @return bool True if file-based; false otherwise
  26. */
  27. public static function isFileBasedSessions()
  28. {
  29. $config = Config::getInstance();
  30. return !isset($config->General['session_save_handler'])
  31. || $config->General['session_save_handler'] === 'files';
  32. }
  33. /**
  34. * Start the session
  35. *
  36. * @param array|bool $options An array of configuration options; the auto-start (bool) setting is ignored
  37. * @return void
  38. * @throws Exception if starting a session fails
  39. */
  40. public static function start($options = false)
  41. {
  42. if (headers_sent()
  43. || self::$sessionStarted
  44. || (defined('PIWIK_ENABLE_SESSION_START') && !PIWIK_ENABLE_SESSION_START)
  45. ) {
  46. return;
  47. }
  48. self::$sessionStarted = true;
  49. // use cookies to store session id on the client side
  50. @ini_set('session.use_cookies', '1');
  51. // prevent attacks involving session ids passed in URLs
  52. @ini_set('session.use_only_cookies', '1');
  53. // advise browser that session cookie should only be sent over secure connection
  54. if (ProxyHttp::isHttps()) {
  55. @ini_set('session.cookie_secure', '1');
  56. }
  57. // advise browser that session cookie should only be accessible through the HTTP protocol (i.e., not JavaScript)
  58. @ini_set('session.cookie_httponly', '1');
  59. // don't use the default: PHPSESSID
  60. @ini_set('session.name', self::SESSION_NAME);
  61. // proxies may cause the referer check to fail and
  62. // incorrectly invalidate the session
  63. @ini_set('session.referer_check', '');
  64. $currentSaveHandler = ini_get('session.save_handler');
  65. $config = Config::getInstance();
  66. if (self::isFileBasedSessions()) {
  67. // Note: this handler doesn't work well in load-balanced environments and may have a concurrency issue with locked session files
  68. // for "files", use our own folder to prevent local session file hijacking
  69. $sessionPath = self::getSessionsDirectory();
  70. // We always call mkdir since it also chmods the directory which might help when permissions were reverted for some reasons
  71. Filesystem::mkdir($sessionPath);
  72. @ini_set('session.save_handler', 'files');
  73. @ini_set('session.save_path', $sessionPath);
  74. } elseif ($config->General['session_save_handler'] === 'dbtable'
  75. || in_array($currentSaveHandler, array('user', 'mm'))
  76. ) {
  77. // We consider these to be misconfigurations, in that:
  78. // - user - we can't verify that user-defined session handler functions have already been set via session_set_save_handler()
  79. // - mm - this handler is not recommended, unsupported, not available for Windows, and has a potential concurrency issue
  80. $config = array(
  81. 'name' => Common::prefixTable('session'),
  82. 'primary' => 'id',
  83. 'modifiedColumn' => 'modified',
  84. 'dataColumn' => 'data',
  85. 'lifetimeColumn' => 'lifetime',
  86. );
  87. $saveHandler = new DbTable($config);
  88. if ($saveHandler) {
  89. self::setSaveHandler($saveHandler);
  90. }
  91. }
  92. // garbage collection may disabled by default (e.g., Debian)
  93. if (ini_get('session.gc_probability') == 0) {
  94. @ini_set('session.gc_probability', 1);
  95. }
  96. try {
  97. parent::start();
  98. register_shutdown_function(array('Zend_Session', 'writeClose'), true);
  99. } catch (Exception $e) {
  100. Log::error('Unable to start session: ' . $e->getMessage());
  101. $enableDbSessions = '';
  102. if (DbHelper::isInstalled()) {
  103. $enableDbSessions = "<br/>If you still experience issues after trying these changes,
  104. we recommend that you <a href='https://matomo.org/faq/how-to-install/#faq_133' rel='noreferrer' target='_blank'>enable database session storage</a>.";
  105. }
  106. $pathToSessions = Filechecks::getErrorMessageMissingPermissions(self::getSessionsDirectory());
  107. $message = sprintf("Error: %s %s %s\n<pre>Debug: the original error was \n%s</pre>",
  108. Piwik::translate('General_ExceptionUnableToStartSession'),
  109. $pathToSessions,
  110. $enableDbSessions,
  111. $e->getMessage()
  112. );
  113. $ex = new MissingFilePermissionException($message, $e->getCode(), $e);
  114. $ex->setIsHtmlMessage();
  115. throw $ex;
  116. }
  117. }
  118. /**
  119. * Returns the directory session files are stored in.
  120. *
  121. * @return string
  122. */
  123. public static function getSessionsDirectory()
  124. {
  125. return StaticContainer::get('path.tmp') . '/sessions';
  126. }
  127. public static function close()
  128. {
  129. parent::writeClose();
  130. }
  131. }