1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
* @category Piwik
* @package Piwik
*/
use Piwik\Core\Config;
/**
* Session initialization.
*
* @package Piwik
* @subpackage Piwik_Session
*/
class Piwik_Session extends Zend_Session
{
protected static $sessionStarted = false;
/**
* Are we using file-based session store?
*
* @return bool True if file-based; false otherwise
*/
public static function isFileBasedSessions()
{
$config = Config::getInstance();
return !isset($config->General['session_save_handler'])
|| $config->General['session_save_handler'] === 'files';
}
/**
* 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 = 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
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,
we recommend that you <a href='http://piwik.org/faq/how-to-install/#faq_133' target='_blank'>enable database session storage</a>.";
}
$message = sprintf("Error: %s %s %s\n<pre>Debug: the original error was \n%s</pre>",
Piwik_Translate('General_ExceptionUnableToStartSession'),
Piwik::getErrorMessageMissingPermissions(Piwik_Common::getPathToPiwikRoot() . '/tmp/sessions/'),
$enableDbSessions,
$e->getMessage()
);
Piwik_ExitWithMessage($message);
}
}
/**
* Returns the directory session files are stored in.
*
* @return string
*/
public static function getSessionsDirectory()
{
return PIWIK_USER_PATH . '/tmp/sessions';
}
}
|