‪TYPO3CMS  10.4
FileSessionHandler.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
23 
28 class ‪FileSessionHandler implements \SessionHandlerInterface
29 {
31 
39  private ‪$sessionPath = 'session/';
40 
47 
49  {
50  $this->sessionPath = rtrim(‪$sessionPath, '/') . '/';
51  $this->expirationTimeInMinutes = ‪$expirationTimeInMinutes;
52  // Start our PHP session early so that hasSession() works
53  session_save_path($this->‪getSessionSavePath());
54  }
55 
62  private function ‪getSessionSavePath()
63  {
64  if (empty(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
65  throw new \TYPO3\CMS\Install\Exception(
66  'No encryption key set to secure session',
67  1371243449
68  );
69  }
70  $sessionSavePath = $this->sessionPath . GeneralUtility::hmac('session:' . ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
71  $this->‪ensureSessionSavePathExists($sessionSavePath);
72  return $sessionSavePath;
73  }
74 
81  private function ‪getSessionFile($id)
82  {
83  $sessionSavePath = $this->‪getSessionSavePath();
84  return $sessionSavePath . '/hash_' . $this->‪getSessionHash($id);
85  }
86 
94  public function ‪open($savePath, $sessionName)
95  {
96  return true;
97  }
98 
104  public function ‪close()
105  {
106  return true;
107  }
108 
115  public function ‪read($id)
116  {
117  $sessionFile = $this->‪getSessionFile($id);
118  $content = '';
119  if (file_exists($sessionFile)) {
120  if ($fd = fopen($sessionFile, 'rb')) {
121  $lockres = flock($fd, LOCK_SH);
122  if ($lockres) {
123  $length = (int)filesize($sessionFile);
124  if ($length > 0) {
125  $content = (string)fread($fd, $length);
126  }
127  flock($fd, LOCK_UN);
128  }
129  fclose($fd);
130  }
131  }
132  // Do a "test write" of the session file after opening it. The real session data is written in
133  // __destruct() and we can not create a sane error message there anymore, so this test should fail
134  // before if final session file can not be written due to permission problems.
135  $this->‪write($id, $content);
136  return $content;
137  }
138 
147  public function ‪write($id, $sessionData)
148  {
149  $sessionFile = $this->‪getSessionFile($id);
150  $result = false;
151  $changePermissions = !@is_file($sessionFile);
152  if ($fd = fopen($sessionFile, 'cb')) {
153  if (flock($fd, LOCK_EX)) {
154  ftruncate($fd, 0);
155  $res = fwrite($fd, $sessionData);
156  if ($res !== false) {
157  fflush($fd);
158  $result = true;
159  }
160  flock($fd, LOCK_UN);
161  }
162  fclose($fd);
163  // Change the permissions only if the file has just been created
164  if ($changePermissions) {
165  ‪GeneralUtility::fixPermissions($sessionFile);
166  }
167  }
168  if (!$result) {
169  throw new Exception(
170  'Session file not writable. Please check permission on ' .
171  $this->sessionPath . ' and its subdirectories.',
172  1424355157
173  );
174  }
175  return $result;
176  }
177 
184  public function ‪destroy($id): bool
185  {
186  $sessionFile = $this->‪getSessionFile($id);
187  return @unlink($sessionFile);
188  }
189 
196  public function ‪gc($maxLifeTime)
197  {
198  $sessionSavePath = $this->‪getSessionSavePath();
199  $files = glob($sessionSavePath . '/hash_*');
200  if (!is_array($files)) {
201  return true;
202  }
203  foreach ($files as $filename) {
204  if (filemtime($filename) + $this->expirationTimeInMinutes * 60 < time()) {
205  @unlink($filename);
206  }
207  }
208  return true;
209  }
210 
222  public function ‪__destruct()
223  {
224  session_write_close();
225  }
226 
232  public function ‪getSessionId()
233  {
234  return session_id();
235  }
236 
245  private function ‪getSessionHash($sessionId = '')
246  {
247  if (empty(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
248  throw new \TYPO3\CMS\Install\Exception(
249  'No encryption key set to secure session',
250  1371243450
251  );
252  }
253  if (!$sessionId) {
254  $sessionId = $this->‪getSessionId();
255  }
256  return md5(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . '|' . $sessionId);
257  }
258 
266  private function ‪ensureSessionSavePathExists($sessionSavePath)
267  {
268  if (!is_dir($sessionSavePath)) {
269  try {
270  ‪GeneralUtility::mkdir_deep($sessionSavePath);
271  } catch (\RuntimeException $exception) {
272  throw new \TYPO3\CMS\Install\Exception(
273  'Could not create session folder in ' . $this->sessionPath . '. Make sure it is writeable!',
274  1294587484
275  );
276  }
277  $htaccessContent = '
278 # Apache < 2.3
279 <IfModule !mod_authz_core.c>
280  Order allow,deny
281  Deny from all
282  Satisfy All
283 </IfModule>
284 
285 # Apache ≥ 2.3
286 <IfModule mod_authz_core.c>
287  Require all denied
288 </IfModule>
289  ';
290  ‪GeneralUtility::writeFile($sessionSavePath . '/.htaccess', $htaccessContent);
291  $indexContent = '<!DOCTYPE html>';
292  $indexContent .= '<html><head><title></title><meta http-equiv=Refresh Content="0; Url=../../"/>';
293  $indexContent .= '</head></html>';
294  ‪GeneralUtility::writeFile($sessionSavePath . '/index.html', $indexContent);
295  }
296  }
297 }
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\read
‪string read($id)
Definition: FileSessionHandler.php:113
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\getSessionFile
‪string getSessionFile($id)
Definition: FileSessionHandler.php:79
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\getSessionSavePath
‪string getSessionSavePath()
Definition: FileSessionHandler.php:60
‪TYPO3\CMS\Install\Service\Exception
Definition: ConfigurationChangedException.php:18
‪TYPO3\CMS\Install\Service\Session
Definition: FileSessionHandler.php:18
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler
Definition: FileSessionHandler.php:29
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\ensureSessionSavePathExists
‪ensureSessionSavePathExists($sessionSavePath)
Definition: FileSessionHandler.php:264
‪TYPO3\CMS\Core\Security\BlockSerializationTrait
Definition: BlockSerializationTrait.php:28
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\__destruct
‪__destruct()
Definition: FileSessionHandler.php:220
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\$sessionPath
‪string $sessionPath
Definition: FileSessionHandler.php:38
‪TYPO3\CMS\Core\Utility\GeneralUtility\fixPermissions
‪static mixed fixPermissions($path, $recursive=false)
Definition: GeneralUtility.php:1863
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir_deep
‪static mkdir_deep($directory)
Definition: GeneralUtility.php:2022
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\close
‪bool close()
Definition: FileSessionHandler.php:102
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\getSessionHash
‪string getSessionHash($sessionId='')
Definition: FileSessionHandler.php:243
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\__construct
‪__construct(string $sessionPath, int $expirationTimeInMinutes)
Definition: FileSessionHandler.php:46
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\getSessionId
‪string getSessionId()
Definition: FileSessionHandler.php:230
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\$expirationTimeInMinutes
‪int $expirationTimeInMinutes
Definition: FileSessionHandler.php:44
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\write
‪bool write($id, $sessionData)
Definition: FileSessionHandler.php:145
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility\writeFile
‪static bool writeFile($file, $content, $changePermissions=false)
Definition: GeneralUtility.php:1836
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\open
‪bool open($savePath, $sessionName)
Definition: FileSessionHandler.php:92
‪TYPO3\CMS\Install\Service\Exception
Definition: Exception.php:22
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\destroy
‪bool destroy($id)
Definition: FileSessionHandler.php:182
‪TYPO3\CMS\Install\Service\Session\FileSessionHandler\gc
‪bool gc($maxLifeTime)
Definition: FileSessionHandler.php:194