Completed
Push — master ( 6b653f...35751f )
by Thomas
19:51 queued 07:41
created

Internal::start()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 5
nop 0
dl 0
loc 15
rs 9.7666
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 ($_SESSION === null) {
55
			throw new \Exception('Failed to start session');
56
		}
57
	}
58
59
	/**
60
	 * @param string $key
61
	 * @param integer $value
62
	 * @throws \Exception
63
	 */
64
	public function set($key, $value) {
65
		$this->validateSession();
66
		$_SESSION[$key] = $value;
67
	}
68
69
	/**
70
	 * @param string $key
71
	 * @return mixed
72
	 */
73
	public function get($key) {
74
		if (!$this->exists($key)) {
75
			return null;
76
		}
77
		return $_SESSION[$key];
78
	}
79
80
	/**
81
	 * @param string $key
82
	 * @return bool
83
	 */
84
	public function exists($key) {
85
		return isset($_SESSION[$key]);
86
	}
87
88
	/**
89
	 * @param string $key
90
	 */
91
	public function remove($key) {
92
		if (isset($_SESSION[$key])) {
93
			unset($_SESSION[$key]);
94
		}
95
	}
96
97
	public function clear() {
98
		\session_unset();
99
		$this->regenerateId();
100
		@\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...
101
		@\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...
102
		$_SESSION = [];
103
	}
104
105
	public function close() {
106
		\session_write_close();
107
		parent::close();
108
	}
109
110
	/**
111
	 * Wrapper around session_regenerate_id
112
	 *
113
	 * @param bool $deleteOldSession Whether to delete the old associated session file or not.
114
	 * @return void
115
	 */
116
	public function regenerateId($deleteOldSession = true) {
117
		@\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...
118
	}
119
120
	/**
121
	 * Wrapper around session_id
122
	 *
123
	 * @return string
124
	 * @throws SessionNotAvailableException
125
	 * @since 9.1.0
126
	 */
127
	public function getId() {
128
		$id = @\session_id();
129
		if ($id === '') {
130
			throw new SessionNotAvailableException();
131
		}
132
		return $id;
133
	}
134
135
	/**
136
	 * @throws \Exception
137
	 */
138
	public function reopen() {
139
		throw new \Exception('The session cannot be reopened - reopen() is ony to be used in unit testing.');
140
	}
141
142
	/**
143
	 * @param int $errorNumber
144
	 * @param string $errorString
145
	 * @throws \ErrorException
146
	 */
147
	public function trapError($errorNumber, $errorString) {
148
		throw new \ErrorException($errorString);
149
	}
150
151
	/**
152
	 * @throws \Exception
153
	 */
154
	private function validateSession() {
155
		if ($this->sessionClosed) {
156
			throw new SessionNotAvailableException('Session has been closed - no further changes to the session are allowed');
157
		}
158
	}
159
160
	private function start(): void {
161
		if (@\session_id() === '') {
162
			// prevents javascript from accessing php session cookies
163
			\ini_set('session.cookie_httponly', true);
164
165
			// set the cookie path to the ownCloud directory
166
			$cookie_path = \OC::$WEBROOT ? : '/';
167
			\ini_set('session.cookie_path', $cookie_path);
168
169
			if ($this->getServerProtocol() === 'https') {
170
				\ini_set('session.cookie_secure', true);
171
			}
172
		}
173
		\session_start();
174
	}
175
176
	private function getServerProtocol() {
177
		$req = new Request(
178
			[
179
				'get' => $_GET,
180
				'post' => $_POST,
181
				'files' => $_FILES,
182
				'server' => $_SERVER,
183
				'env' => $_ENV,
184
				'cookies' => $_COOKIE,
185
				'method' => $_SERVER['REQUEST_METHOD'] ?? null,
186
				'urlParams' => [],
187
			],
188
			null,
189
			\OC::$server->getConfig(),
190
			null
191
		);
192
193
		return $req->getServerProtocol();
194
	}
195
}
196