Completed
Pull Request — master (#32298)
by Thomas
24:20 queued 08:08
created

Internal::start()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 5
nop 0
dl 0
loc 30
rs 9.44
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author cetra3 <[email protected]>
4
 * @author Christoph Wurst <[email protected]>
5
 * @author Lukas Reschke <[email protected]>
6
 * @author Morris Jobke <[email protected]>
7
 * @author Phil Davis <[email protected]>
8
 * @author Robin Appelman <[email protected]>
9
 * @author Thomas Müller <[email protected]>
10
 *
11
 * @copyright Copyright (c) 2018, ownCloud GmbH
12
 * @license AGPL-3.0
13
 *
14
 * This code is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Affero General Public License, version 3,
16
 * as published by the Free Software Foundation.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
 * GNU Affero General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU Affero General Public License, version 3,
24
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
25
 *
26
 */
27
28
namespace OC\Session;
29
30
use OC\AppFramework\Http\Request;
31
use OCP\Session\Exceptions\SessionNotAvailableException;
32
33
/**
34
 * Class Internal
35
 *
36
 * wrap php's internal session handling into the Session interface
37
 *
38
 * @package OC\Session
39
 */
40
class Internal extends Session {
41
	/**
42
	 * @param string $name
43
	 * @throws \Exception
44
	 */
45
	public function __construct($name) {
46
		\session_name($name);
47
		\set_error_handler([$this, 'trapError']);
48
		try {
49
			$this->start();
50
		} catch (\Exception $e) {
51
			\setcookie(\session_name(), null, -1, \OC::$WEBROOT ? : '/');
52
		}
53
		\restore_error_handler();
54
		if (!isset($_SESSION)) {
55
			throw new \Exception('Failed to start session');
56
		}
57
	}
58
59
	/**
60
	 * @param string $key
61
	 * @param integer $value
62
	 */
63
	public function set($key, $value) {
64
		$this->validateSession();
65
		$_SESSION[$key] = $value;
66
	}
67
68
	/**
69
	 * @param string $key
70
	 * @return mixed
71
	 */
72
	public function get($key) {
73
		if (!$this->exists($key)) {
74
			return null;
75
		}
76
		return $_SESSION[$key];
77
	}
78
79
	/**
80
	 * @param string $key
81
	 * @return bool
82
	 */
83
	public function exists($key) {
84
		return isset($_SESSION[$key]);
85
	}
86
87
	/**
88
	 * @param string $key
89
	 */
90
	public function remove($key) {
91
		if (isset($_SESSION[$key])) {
92
			unset($_SESSION[$key]);
93
		}
94
	}
95
96
	public function clear() {
97
		\session_unset();
98
		$this->regenerateId();
99
		@\session_destroy();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
100
		@\session_start();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
101
		$_SESSION = [];
102
	}
103
104
	public function close() {
105
		\session_write_close();
106
		parent::close();
107
	}
108
109
	/**
110
	 * Wrapper around session_regenerate_id
111
	 *
112
	 * @param bool $deleteOldSession Whether to delete the old associated session file or not.
113
	 * @return void
114
	 */
115
	public function regenerateId($deleteOldSession = true) {
116
		@\session_regenerate_id($deleteOldSession);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
117
	}
118
119
	/**
120
	 * Wrapper around session_id
121
	 *
122
	 * @return string
123
	 * @throws SessionNotAvailableException
124
	 * @since 9.1.0
125
	 */
126
	public function getId() {
127
		$id = @\session_id();
128
		if ($id === '') {
129
			throw new SessionNotAvailableException();
130
		}
131
		return $id;
132
	}
133
134
	/**
135
	 * @throws \Exception
136
	 */
137
	public function reopen() {
138
		throw new \Exception('The session cannot be reopened - reopen() is ony to be used in unit testing.');
139
	}
140
141
	/**
142
	 * @param int $errorNumber
143
	 * @param string $errorString
144
	 * @throws \ErrorException
145
	 */
146
	public function trapError($errorNumber, $errorString) {
147
		throw new \ErrorException($errorString);
148
	}
149
150
	/**
151
	 * @throws \Exception
152
	 */
153
	private function validateSession() {
154
		if ($this->sessionClosed) {
155
			throw new SessionNotAvailableException('Session has been closed - no further changes to the session are allowed');
156
		}
157
	}
158
159
	private function start(): void {
160
		if (@\session_id() === '') {
161
			// prevents javascript from accessing php session cookies
162
			\ini_set('session.cookie_httponly', true);
163
164
			// set the cookie path to the ownCloud directory
165
			$cookie_path = \OC::$WEBROOT ? : '/';
166
			\ini_set('session.cookie_path', $cookie_path);
167
168
			\ini_set('display_errors', 0);
169
			\ini_set('log_errors', 1);
170
171
			\ini_set('max_execution_time', 3600);
172
			\ini_set('max_input_time', 3600);
173
174
			//try to set the maximum filesize to 10G
175
			\ini_set('upload_max_filesize', '10G');
176
			\ini_set('post_max_size', '10G');
177
			\ini_set('file_uploads', '50');
178
179
			if ($this->getServerProtocol() === 'https') {
180
				\ini_set('session.cookie_secure', true);
181
			}
182
183
			//try to set the session lifetime
184
			$sessionLifeTime = \OC::getSessionLifeTime();
185
			@\ini_set('gc_maxlifetime', (string)$sessionLifeTime);
186
		}
187
		\session_start();
188
	}
189
190
	private function getServerProtocol() {
191
		$req = new Request(
192
			[
193
				'get' => $_GET,
194
				'post' => $_POST,
195
				'files' => $_FILES,
196
				'server' => $_SERVER,
197
				'env' => $_ENV,
198
				'cookies' => $_COOKIE,
199
				'method' => (isset($_SERVER, $_SERVER['REQUEST_METHOD']))
200
					? $_SERVER['REQUEST_METHOD']
201
					: null,
202
				'urlParams' => [],
203
			],
204
			null,
205
			\OC::$server->getConfig(),
206
			null
207
		);
208
209
		return $req->getServerProtocol();
210
	}
211
}
212