Passed
Push — master ( dd5a4c...421573 )
by Roeland
11:19 queued 11s
created

OC::handleAuthHeaders()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 12
nc 8
nop 0
dl 0
loc 18
rs 8.8333
c 1
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Adam Williamson <[email protected]>
6
 * @author Andreas Fischer <[email protected]>
7
 * @author Arthur Schiwon <[email protected]>
8
 * @author Bart Visscher <[email protected]>
9
 * @author Bernhard Posselt <[email protected]>
10
 * @author Bjoern Schiessle <[email protected]>
11
 * @author Björn Schießle <[email protected]>
12
 * @author Christoph Wurst <[email protected]>
13
 * @author Damjan Georgievski <[email protected]>
14
 * @author davidgumberg <[email protected]>
15
 * @author Eric Masseran <[email protected]>
16
 * @author Florin Peter <[email protected]>
17
 * @author Greta Doci <[email protected]>
18
 * @author Jakob Sack <[email protected]>
19
 * @author jaltek <[email protected]>
20
 * @author Jan-Christoph Borchardt <[email protected]>
21
 * @author Joachim Sokolowski <[email protected]>
22
 * @author Joas Schilling <[email protected]>
23
 * @author John Molakvoæ (skjnldsv) <[email protected]>
24
 * @author Jörn Friedrich Dreyer <[email protected]>
25
 * @author Juan Pablo Villafáñez <[email protected]>
26
 * @author Julius Härtl <[email protected]>
27
 * @author Ko- <[email protected]>
28
 * @author Lukas Reschke <[email protected]>
29
 * @author MartB <[email protected]>
30
 * @author Michael Gapczynski <[email protected]>
31
 * @author Morris Jobke <[email protected]>
32
 * @author Owen Winkler <[email protected]>
33
 * @author Phil Davis <[email protected]>
34
 * @author Ramiro Aparicio <[email protected]>
35
 * @author Robin Appelman <[email protected]>
36
 * @author Robin McCorkell <[email protected]>
37
 * @author Roeland Jago Douma <[email protected]>
38
 * @author Sebastian Wessalowski <[email protected]>
39
 * @author Stefan Weil <[email protected]>
40
 * @author Thomas Müller <[email protected]>
41
 * @author Thomas Tanghus <[email protected]>
42
 * @author Tobia De Koninck <[email protected]>
43
 * @author Vincent Petry <[email protected]>
44
 * @author Volkan Gezer <[email protected]>
45
 *
46
 * @license AGPL-3.0
47
 *
48
 * This code is free software: you can redistribute it and/or modify
49
 * it under the terms of the GNU Affero General Public License, version 3,
50
 * as published by the Free Software Foundation.
51
 *
52
 * This program is distributed in the hope that it will be useful,
53
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
54
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55
 * GNU Affero General Public License for more details.
56
 *
57
 * You should have received a copy of the GNU Affero General Public License, version 3,
58
 * along with this program. If not, see <http://www.gnu.org/licenses/>
59
 *
60
 */
61
62
use OCP\ILogger;
63
use OCP\Share;
64
use OC\Encryption\HookManager;
65
use OC\Files\Filesystem;
66
use OC\Share20\Hooks;
67
68
require_once 'public/Constants.php';
69
70
/**
71
 * Class that is a namespace for all global OC variables
72
 * No, we can not put this class in its own file because it is used by
73
 * OC_autoload!
74
 */
75
class OC {
76
	/**
77
	 * Associative array for autoloading. classname => filename
78
	 */
79
	public static $CLASSPATH = array();
80
	/**
81
	 * The installation path for Nextcloud  on the server (e.g. /srv/http/nextcloud)
82
	 */
83
	public static $SERVERROOT = '';
84
	/**
85
	 * the current request path relative to the Nextcloud root (e.g. files/index.php)
86
	 */
87
	private static $SUBURI = '';
88
	/**
89
	 * the Nextcloud root path for http requests (e.g. nextcloud/)
90
	 */
91
	public static $WEBROOT = '';
92
	/**
93
	 * The installation path array of the apps folder on the server (e.g. /srv/http/nextcloud) 'path' and
94
	 * web path in 'url'
95
	 */
96
	public static $APPSROOTS = array();
97
98
	/**
99
	 * @var string
100
	 */
101
	public static $configDir;
102
103
	/**
104
	 * requested app
105
	 */
106
	public static $REQUESTEDAPP = '';
107
108
	/**
109
	 * check if Nextcloud runs in cli mode
110
	 */
111
	public static $CLI = false;
112
113
	/**
114
	 * @var \OC\Autoloader $loader
115
	 */
116
	public static $loader = null;
117
118
	/** @var \Composer\Autoload\ClassLoader $composerAutoloader */
119
	public static $composerAutoloader = null;
120
121
	/**
122
	 * @var \OC\Server
123
	 */
124
	public static $server = null;
125
126
	/**
127
	 * @var \OC\Config
128
	 */
129
	private static $config = null;
130
131
	/**
132
	 * @throws \RuntimeException when the 3rdparty directory is missing or
133
	 * the app path list is empty or contains an invalid path
134
	 */
135
	public static function initPaths() {
136
		if(defined('PHPUNIT_CONFIG_DIR')) {
137
			self::$configDir = OC::$SERVERROOT . '/' . PHPUNIT_CONFIG_DIR . '/';
0 ignored issues
show
Bug introduced by
The constant PHPUNIT_CONFIG_DIR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
138
		} elseif(defined('PHPUNIT_RUN') and PHPUNIT_RUN and is_dir(OC::$SERVERROOT . '/tests/config/')) {
0 ignored issues
show
Bug introduced by
The constant PHPUNIT_RUN was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
139
			self::$configDir = OC::$SERVERROOT . '/tests/config/';
140
		} elseif($dir = getenv('NEXTCLOUD_CONFIG_DIR')) {
141
			self::$configDir = rtrim($dir, '/') . '/';
142
		} else {
143
			self::$configDir = OC::$SERVERROOT . '/config/';
144
		}
145
		self::$config = new \OC\Config(self::$configDir);
146
147
		OC::$SUBURI = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen(OC::$SERVERROOT)));
148
		/**
149
		 * FIXME: The following lines are required because we can't yet instantiate
150
		 *        \OC::$server->getRequest() since \OC::$server does not yet exist.
151
		 */
152
		$params = [
153
			'server' => [
154
				'SCRIPT_NAME' => $_SERVER['SCRIPT_NAME'],
155
				'SCRIPT_FILENAME' => $_SERVER['SCRIPT_FILENAME'],
156
			],
157
		];
158
		$fakeRequest = new \OC\AppFramework\Http\Request($params, null, new \OC\AllConfig(new \OC\SystemConfig(self::$config)));
159
		$scriptName = $fakeRequest->getScriptName();
160
		if (substr($scriptName, -1) == '/') {
161
			$scriptName .= 'index.php';
162
			//make sure suburi follows the same rules as scriptName
163
			if (substr(OC::$SUBURI, -9) != 'index.php') {
164
				if (substr(OC::$SUBURI, -1) != '/') {
165
					OC::$SUBURI = OC::$SUBURI . '/';
166
				}
167
				OC::$SUBURI = OC::$SUBURI . 'index.php';
168
			}
169
		}
170
171
172
		if (OC::$CLI) {
173
			OC::$WEBROOT = self::$config->getValue('overwritewebroot', '');
174
		} else {
175
			if (substr($scriptName, 0 - strlen(OC::$SUBURI)) === OC::$SUBURI) {
176
				OC::$WEBROOT = substr($scriptName, 0, 0 - strlen(OC::$SUBURI));
177
178
				if (OC::$WEBROOT != '' && OC::$WEBROOT[0] !== '/') {
179
					OC::$WEBROOT = '/' . OC::$WEBROOT;
180
				}
181
			} else {
182
				// The scriptName is not ending with OC::$SUBURI
183
				// This most likely means that we are calling from CLI.
184
				// However some cron jobs still need to generate
185
				// a web URL, so we use overwritewebroot as a fallback.
186
				OC::$WEBROOT = self::$config->getValue('overwritewebroot', '');
187
			}
188
189
			// Resolve /nextcloud to /nextcloud/ to ensure to always have a trailing
190
			// slash which is required by URL generation.
191
			if (isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI'] === \OC::$WEBROOT &&
192
					substr($_SERVER['REQUEST_URI'], -1) !== '/') {
193
				header('Location: '.\OC::$WEBROOT.'/');
194
				exit();
195
			}
196
		}
197
198
		// search the apps folder
199
		$config_paths = self::$config->getValue('apps_paths', array());
200
		if (!empty($config_paths)) {
201
			foreach ($config_paths as $paths) {
202
				if (isset($paths['url']) && isset($paths['path'])) {
203
					$paths['url'] = rtrim($paths['url'], '/');
204
					$paths['path'] = rtrim($paths['path'], '/');
205
					OC::$APPSROOTS[] = $paths;
206
				}
207
			}
208
		} elseif (file_exists(OC::$SERVERROOT . '/apps')) {
209
			OC::$APPSROOTS[] = array('path' => OC::$SERVERROOT . '/apps', 'url' => '/apps', 'writable' => true);
210
		} elseif (file_exists(OC::$SERVERROOT . '/../apps')) {
211
			OC::$APPSROOTS[] = array(
212
				'path' => rtrim(dirname(OC::$SERVERROOT), '/') . '/apps',
213
				'url' => '/apps',
214
				'writable' => true
215
			);
216
		}
217
218
		if (empty(OC::$APPSROOTS)) {
219
			throw new \RuntimeException('apps directory not found! Please put the Nextcloud apps folder in the Nextcloud folder'
220
				. ' or the folder above. You can also configure the location in the config.php file.');
221
		}
222
		$paths = array();
223
		foreach (OC::$APPSROOTS as $path) {
224
			$paths[] = $path['path'];
225
			if (!is_dir($path['path'])) {
226
				throw new \RuntimeException(sprintf('App directory "%s" not found! Please put the Nextcloud apps folder in the'
227
					. ' Nextcloud folder or the folder above. You can also configure the location in the'
228
					. ' config.php file.', $path['path']));
229
			}
230
		}
231
232
		// set the right include path
233
		set_include_path(
234
			implode(PATH_SEPARATOR, $paths)
235
		);
236
	}
237
238
	public static function checkConfig() {
239
		$l = \OC::$server->getL10N('lib');
240
241
		// Create config if it does not already exist
242
		$configFilePath = self::$configDir .'/config.php';
243
		if(!file_exists($configFilePath)) {
244
			@touch($configFilePath);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for touch(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

244
			/** @scrutinizer ignore-unhandled */ @touch($configFilePath);

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...
245
		}
246
247
		// Check if config is writable
248
		$configFileWritable = is_writable($configFilePath);
249
		if (!$configFileWritable && !OC_Helper::isReadOnlyConfigEnabled()
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: (! $configFileWritable &...OCP\Util::needUpgrade(), Probably Intended Meaning: ! $configFileWritable &&...CP\Util::needUpgrade())
Loading history...
250
			|| !$configFileWritable && \OCP\Util::needUpgrade()) {
251
252
			$urlGenerator = \OC::$server->getURLGenerator();
253
254
			if (self::$CLI) {
255
				echo $l->t('Cannot write into "config" directory!')."\n";
256
				echo $l->t('This can usually be fixed by giving the webserver write access to the config directory')."\n";
257
				echo $l->t('See %s', [ $urlGenerator->linkToDocs('admin-dir_permissions') ])."\n";
258
				echo "\n";
259
				echo $l->t('Or, if you prefer to keep config.php file read only, set the option "config_is_read_only" to true in it.')."\n";
260
				echo $l->t('See %s', [ $urlGenerator->linkToDocs('admin-config') ])."\n";
261
				exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
262
			} else {
263
				OC_Template::printErrorPage(
264
					$l->t('Cannot write into "config" directory!'),
265
					$l->t('This can usually be fixed by giving the webserver write access to the config directory. See %s',
266
					[ $urlGenerator->linkToDocs('admin-dir_permissions') ]) . '. '
267
					. $l->t('Or, if you prefer to keep config.php file read only, set the option "config_is_read_only" to true in it. See %s',
268
					[ $urlGenerator->linkToDocs('admin-config') ] ),
269
					503
270
				);
271
			}
272
		}
273
	}
274
275
	public static function checkInstalled() {
276
		if (defined('OC_CONSOLE')) {
277
			return;
278
		}
279
		// Redirect to installer if not installed
280
		if (!\OC::$server->getSystemConfig()->getValue('installed', false) && OC::$SUBURI !== '/index.php' && OC::$SUBURI !== '/status.php') {
281
			if (OC::$CLI) {
282
				throw new Exception('Not installed');
283
			} else {
284
				$url = OC::$WEBROOT . '/index.php';
285
				header('Location: ' . $url);
286
			}
287
			exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
288
		}
289
	}
290
291
	public static function checkMaintenanceMode() {
292
		// Allow ajax update script to execute without being stopped
293
		if (((bool) \OC::$server->getSystemConfig()->getValue('maintenance', false)) && OC::$SUBURI != '/core/ajax/update.php') {
294
			// send http status 503
295
			http_response_code(503);
296
			header('Retry-After: 120');
297
298
			// render error page
299
			$template = new OC_Template('', 'update.user', 'guest');
300
			OC_Util::addScript('dist/maintenance');
301
			OC_Util::addStyle('core', 'guest');
302
			$template->printPage();
303
			die();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
304
		}
305
	}
306
307
	/**
308
	 * Prints the upgrade page
309
	 *
310
	 * @param \OC\SystemConfig $systemConfig
311
	 */
312
	private static function printUpgradePage(\OC\SystemConfig $systemConfig) {
313
		$disableWebUpdater = $systemConfig->getValue('upgrade.disable-web', false);
314
		$tooBig = false;
315
		if (!$disableWebUpdater) {
316
			$apps = \OC::$server->getAppManager();
317
			if ($apps->isInstalled('user_ldap')) {
318
				$qb = \OC::$server->getDatabaseConnection()->getQueryBuilder();
319
320
				$result = $qb->select($qb->func()->count('*', 'user_count'))
321
					->from('ldap_user_mapping')
322
					->execute();
323
				$row = $result->fetch();
324
				$result->closeCursor();
325
326
				$tooBig = ($row['user_count'] > 50);
327
			}
328
			if (!$tooBig && $apps->isInstalled('user_saml')) {
329
				$qb = \OC::$server->getDatabaseConnection()->getQueryBuilder();
330
331
				$result = $qb->select($qb->func()->count('*', 'user_count'))
332
					->from('user_saml_users')
333
					->execute();
334
				$row = $result->fetch();
335
				$result->closeCursor();
336
337
				$tooBig = ($row['user_count'] > 50);
338
			}
339
			if (!$tooBig) {
340
				// count users
341
				$stats = \OC::$server->getUserManager()->countUsers();
342
				$totalUsers = array_sum($stats);
343
				$tooBig = ($totalUsers > 50);
344
			}
345
		}
346
		$ignoreTooBigWarning = isset($_GET['IKnowThatThisIsABigInstanceAndTheUpdateRequestCouldRunIntoATimeoutAndHowToRestoreABackup']) &&
347
			$_GET['IKnowThatThisIsABigInstanceAndTheUpdateRequestCouldRunIntoATimeoutAndHowToRestoreABackup'] === 'IAmSuperSureToDoThis';
348
349
		if ($disableWebUpdater || ($tooBig && !$ignoreTooBigWarning)) {
350
			// send http status 503
351
			http_response_code(503);
352
			header('Retry-After: 120');
353
354
			// render error page
355
			$template = new OC_Template('', 'update.use-cli', 'guest');
356
			$template->assign('productName', 'nextcloud'); // for now
357
			$template->assign('version', OC_Util::getVersionString());
358
			$template->assign('tooBig', $tooBig);
359
360
			$template->printPage();
361
			die();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
362
		}
363
364
		// check whether this is a core update or apps update
365
		$installedVersion = $systemConfig->getValue('version', '0.0.0');
366
		$currentVersion = implode('.', \OCP\Util::getVersion());
367
368
		// if not a core upgrade, then it's apps upgrade
369
		$isAppsOnlyUpgrade = version_compare($currentVersion, $installedVersion, '=');
370
371
		$oldTheme = $systemConfig->getValue('theme');
372
		$systemConfig->setValue('theme', '');
373
		OC_Util::addScript('config'); // needed for web root
374
		OC_Util::addScript('update');
375
376
		/** @var \OC\App\AppManager $appManager */
377
		$appManager = \OC::$server->getAppManager();
378
379
		$tmpl = new OC_Template('', 'update.admin', 'guest');
380
		$tmpl->assign('version', OC_Util::getVersionString());
381
		$tmpl->assign('isAppsOnlyUpgrade', $isAppsOnlyUpgrade);
382
383
		// get third party apps
384
		$ocVersion = \OCP\Util::getVersion();
385
		$ocVersion = implode('.', $ocVersion);
386
		$incompatibleApps = $appManager->getIncompatibleApps($ocVersion);
387
		$incompatibleShippedApps = [];
388
		foreach ($incompatibleApps as $appInfo) {
389
			if ($appManager->isShipped($appInfo['id'])) {
390
				$incompatibleShippedApps[] = $appInfo['name'] . ' (' . $appInfo['id'] . ')';
391
			}
392
		}
393
394
		if (!empty($incompatibleShippedApps)) {
395
			$l = \OC::$server->getL10N('core');
396
			$hint = $l->t('The files of the app %1$s were not replaced correctly. Make sure it is a version compatible with the server.', [implode(', ', $incompatibleShippedApps)]);
397
			throw new \OC\HintException('The files of the app ' . implode(', ', $incompatibleShippedApps) . ' were not replaced correctly. Make sure it is a version compatible with the server.', $hint);
398
		}
399
400
		$tmpl->assign('appsToUpgrade', $appManager->getAppsNeedingUpgrade($ocVersion));
401
		$tmpl->assign('incompatibleAppsList', $incompatibleApps);
402
		$tmpl->assign('productName', 'Nextcloud'); // for now
403
		$tmpl->assign('oldTheme', $oldTheme);
404
		$tmpl->printPage();
405
	}
406
407
	public static function initSession() {
408
		if(self::$server->getRequest()->getServerProtocol() === 'https') {
409
			ini_set('session.cookie_secure', true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $newvalue of ini_set(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

409
			ini_set('session.cookie_secure', /** @scrutinizer ignore-type */ true);
Loading history...
410
		}
411
412
		// prevents javascript from accessing php session cookies
413
		ini_set('session.cookie_httponly', 'true');
414
415
		// set the cookie path to the Nextcloud directory
416
		$cookie_path = OC::$WEBROOT ? : '/';
417
		ini_set('session.cookie_path', $cookie_path);
418
419
		// Let the session name be changed in the initSession Hook
420
		$sessionName = OC_Util::getInstanceId();
421
422
		try {
423
			// Allow session apps to create a custom session object
424
			$useCustomSession = false;
425
			$session = self::$server->getSession();
426
			OC_Hook::emit('OC', 'initSession', array('session' => &$session, 'sessionName' => &$sessionName, 'useCustomSession' => &$useCustomSession));
427
			if (!$useCustomSession) {
0 ignored issues
show
introduced by
The condition $useCustomSession is always false.
Loading history...
428
				// set the session name to the instance id - which is unique
429
				$session = new \OC\Session\Internal($sessionName);
430
			}
431
432
			$cryptoWrapper = \OC::$server->getSessionCryptoWrapper();
433
			$session = $cryptoWrapper->wrapSession($session);
434
			self::$server->setSession($session);
435
436
			// if session can't be started break with http 500 error
437
		} catch (Exception $e) {
438
			\OC::$server->getLogger()->logException($e, ['app' => 'base']);
439
			//show the user a detailed error page
440
			OC_Template::printExceptionErrorPage($e, 500);
441
			die();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
442
		}
443
444
		$sessionLifeTime = self::getSessionLifeTime();
445
446
		// session timeout
447
		if ($session->exists('LAST_ACTIVITY') && (time() - $session->get('LAST_ACTIVITY') > $sessionLifeTime)) {
448
			if (isset($_COOKIE[session_name()])) {
449
				setcookie(session_name(), '', -1, self::$WEBROOT ? : '/');
450
			}
451
			\OC::$server->getUserSession()->logout();
452
		}
453
454
		$session->set('LAST_ACTIVITY', time());
455
	}
456
457
	/**
458
	 * @return string
459
	 */
460
	private static function getSessionLifeTime() {
461
		return \OC::$server->getConfig()->getSystemValue('session_lifetime', 60 * 60 * 24);
462
	}
463
464
	/**
465
	 * Try to set some values to the required Nextcloud default
466
	 */
467
	public static function setRequiredIniValues() {
468
		@ini_set('default_charset', 'UTF-8');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for ini_set(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

468
		/** @scrutinizer ignore-unhandled */ @ini_set('default_charset', 'UTF-8');

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...
469
		@ini_set('gd.jpeg_ignore_warning', '1');
470
	}
471
472
	/**
473
	 * Send the same site cookies
474
	 */
475
	private static function sendSameSiteCookies() {
476
		$cookieParams = session_get_cookie_params();
477
		$secureCookie = ($cookieParams['secure'] === true) ? 'secure; ' : '';
478
		$policies = [
479
			'lax',
480
			'strict',
481
		];
482
483
		// Append __Host to the cookie if it meets the requirements
484
		$cookiePrefix = '';
485
		if($cookieParams['secure'] === true && $cookieParams['path'] === '/') {
486
			$cookiePrefix = '__Host-';
487
		}
488
489
		foreach($policies as $policy) {
490
			header(
491
				sprintf(
492
					'Set-Cookie: %snc_sameSiteCookie%s=true; path=%s; httponly;' . $secureCookie . 'expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=%s',
493
					$cookiePrefix,
494
					$policy,
495
					$cookieParams['path'],
496
					$policy
497
				),
498
				false
499
			);
500
		}
501
	}
502
503
	/**
504
	 * Same Site cookie to further mitigate CSRF attacks. This cookie has to
505
	 * be set in every request if cookies are sent to add a second level of
506
	 * defense against CSRF.
507
	 *
508
	 * If the cookie is not sent this will set the cookie and reload the page.
509
	 * We use an additional cookie since we want to protect logout CSRF and
510
	 * also we can't directly interfere with PHP's session mechanism.
511
	 */
512
	private static function performSameSiteCookieProtection() {
513
		$request = \OC::$server->getRequest();
514
515
		// Some user agents are notorious and don't really properly follow HTTP
516
		// specifications. For those, have an automated opt-out. Since the protection
517
		// for remote.php is applied in base.php as starting point we need to opt out
518
		// here.
519
		$incompatibleUserAgents = \OC::$server->getConfig()->getSystemValue('csrf.optout');
520
521
		// Fallback, if csrf.optout is unset
522
		if (!is_array($incompatibleUserAgents)) {
523
			$incompatibleUserAgents = [
524
				// OS X Finder
525
				'/^WebDAVFS/',
526
				// Windows webdav drive
527
				'/^Microsoft-WebDAV-MiniRedir/',
528
			];
529
		}
530
531
		if($request->isUserAgent($incompatibleUserAgents)) {
532
			return;
533
		}
534
535
		if(count($_COOKIE) > 0) {
536
			$requestUri = $request->getScriptName();
537
			$processingScript = explode('/', $requestUri);
538
			$processingScript = $processingScript[count($processingScript)-1];
539
540
			// index.php routes are handled in the middleware
541
			if($processingScript === 'index.php') {
542
				return;
543
			}
544
545
			// All other endpoints require the lax and the strict cookie
546
			if(!$request->passesStrictCookieCheck()) {
547
				self::sendSameSiteCookies();
548
				// Debug mode gets access to the resources without strict cookie
549
				// due to the fact that the SabreDAV browser also lives there.
550
				if(!\OC::$server->getConfig()->getSystemValue('debug', false)) {
551
					http_response_code(\OCP\AppFramework\Http::STATUS_SERVICE_UNAVAILABLE);
552
					exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
553
				}
554
			}
555
		} elseif(!isset($_COOKIE['nc_sameSiteCookielax']) || !isset($_COOKIE['nc_sameSiteCookiestrict'])) {
556
			self::sendSameSiteCookies();
557
		}
558
	}
559
560
	public static function init() {
561
		// calculate the root directories
562
		OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4));
563
564
		// register autoloader
565
		$loaderStart = microtime(true);
566
		require_once __DIR__ . '/autoloader.php';
567
		self::$loader = new \OC\Autoloader([
568
			OC::$SERVERROOT . '/lib/private/legacy',
569
		]);
570
		if (defined('PHPUNIT_RUN')) {
571
			self::$loader->addValidRoot(OC::$SERVERROOT . '/tests');
572
		}
573
		spl_autoload_register(array(self::$loader, 'load'));
574
		$loaderEnd = microtime(true);
575
576
		self::$CLI = (php_sapi_name() == 'cli');
577
578
		// Add default composer PSR-4 autoloader
579
		self::$composerAutoloader = require_once OC::$SERVERROOT . '/lib/composer/autoload.php';
580
581
		try {
582
			self::initPaths();
583
			// setup 3rdparty autoloader
584
			$vendorAutoLoad = OC::$SERVERROOT. '/3rdparty/autoload.php';
585
			if (!file_exists($vendorAutoLoad)) {
586
				throw new \RuntimeException('Composer autoloader not found, unable to continue. Check the folder "3rdparty". Running "git submodule update --init" will initialize the git submodule that handles the subfolder "3rdparty".');
587
			}
588
			require_once $vendorAutoLoad;
589
590
		} catch (\RuntimeException $e) {
591
			if (!self::$CLI) {
592
				http_response_code(503);
593
			}
594
			// we can't use the template error page here, because this needs the
595
			// DI container which isn't available yet
596
			print($e->getMessage());
597
			exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
598
		}
599
600
		// setup the basic server
601
		self::$server = new \OC\Server(\OC::$WEBROOT, self::$config);
602
		\OC::$server->getEventLogger()->log('autoloader', 'Autoloader', $loaderStart, $loaderEnd);
603
		\OC::$server->getEventLogger()->start('boot', 'Initialize');
604
605
		// Don't display errors and log them
606
		error_reporting(E_ALL | E_STRICT);
607
		@ini_set('display_errors', '0');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for ini_set(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

607
		/** @scrutinizer ignore-unhandled */ @ini_set('display_errors', '0');

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...
608
		@ini_set('log_errors', '1');
609
610
		if(!date_default_timezone_set('UTC')) {
611
			throw new \RuntimeException('Could not set timezone to UTC');
612
		}
613
614
		//try to configure php to enable big file uploads.
615
		//this doesn´t work always depending on the webserver and php configuration.
616
		//Let´s try to overwrite some defaults anyway
617
618
		//try to set the maximum execution time to 60min
619
		if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
620
			@set_time_limit(3600);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for set_time_limit(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

620
			/** @scrutinizer ignore-unhandled */ @set_time_limit(3600);

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...
621
		}
622
		@ini_set('max_execution_time', '3600');
623
		@ini_set('max_input_time', '3600');
624
625
		//try to set the maximum filesize to 10G
626
		@ini_set('upload_max_filesize', '10G');
627
		@ini_set('post_max_size', '10G');
628
		@ini_set('file_uploads', '50');
629
630
		self::setRequiredIniValues();
631
		self::handleAuthHeaders();
632
		self::registerAutoloaderCache();
633
634
		// initialize intl fallback is necessary
635
		\Patchwork\Utf8\Bootup::initIntl();
636
		OC_Util::isSetLocaleWorking();
637
638
		if (!defined('PHPUNIT_RUN')) {
639
			OC\Log\ErrorHandler::setLogger(\OC::$server->getLogger());
640
			$debug = \OC::$server->getConfig()->getSystemValue('debug', false);
641
			OC\Log\ErrorHandler::register($debug);
642
		}
643
644
		\OC::$server->getEventLogger()->start('init_session', 'Initialize session');
645
		OC_App::loadApps(array('session'));
646
		if (!self::$CLI) {
647
			self::initSession();
648
		}
649
		\OC::$server->getEventLogger()->end('init_session');
650
		self::checkConfig();
651
		self::checkInstalled();
652
653
		OC_Response::addSecurityHeaders();
654
655
		self::performSameSiteCookieProtection();
656
657
		if (!defined('OC_CONSOLE')) {
658
			$errors = OC_Util::checkServer(\OC::$server->getSystemConfig());
659
			if (count($errors) > 0) {
660
				if (!self::$CLI) {
661
					http_response_code(503);
662
					OC_Util::addStyle('guest');
663
					try {
664
						OC_Template::printGuestPage('', 'error', array('errors' => $errors));
665
						exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
666
					} catch (\Exception $e) {
667
						// In case any error happens when showing the error page, we simply fall back to posting the text.
668
						// This might be the case when e.g. the data directory is broken and we can not load/write SCSS to/from it.
669
					}
670
				}
671
672
				// Convert l10n string into regular string for usage in database
673
				$staticErrors = [];
674
				foreach ($errors as $error) {
675
					echo $error['error'] . "\n";
676
					echo $error['hint'] . "\n\n";
677
					$staticErrors[] = [
678
						'error' => (string)$error['error'],
679
						'hint' => (string)$error['hint'],
680
					];
681
				}
682
683
				try {
684
					\OC::$server->getConfig()->setAppValue('core', 'cronErrors', json_encode($staticErrors));
685
				} catch (\Exception $e) {
686
					echo('Writing to database failed');
687
				}
688
				exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
689
			} elseif (self::$CLI && \OC::$server->getConfig()->getSystemValue('installed', false)) {
690
				\OC::$server->getConfig()->deleteAppValue('core', 'cronErrors');
691
			}
692
		}
693
		//try to set the session lifetime
694
		$sessionLifeTime = self::getSessionLifeTime();
695
		@ini_set('gc_maxlifetime', (string)$sessionLifeTime);
696
697
		$systemConfig = \OC::$server->getSystemConfig();
698
699
		// User and Groups
700
		if (!$systemConfig->getValue("installed", false)) {
701
			self::$server->getSession()->set('user_id', '');
702
		}
703
704
		OC_User::useBackend(new \OC\User\Database());
705
		\OC::$server->getGroupManager()->addBackend(new \OC\Group\Database());
706
707
		// Subscribe to the hook
708
		\OCP\Util::connectHook(
709
			'\OCA\Files_Sharing\API\Server2Server',
710
			'preLoginNameUsedAsUserName',
711
			'\OC\User\Database',
712
			'preLoginNameUsedAsUserName'
713
		);
714
715
		//setup extra user backends
716
		if (!\OCP\Util::needUpgrade()) {
717
			OC_User::setupBackends();
718
		} else {
719
			// Run upgrades in incognito mode
720
			OC_User::setIncognitoMode(true);
721
		}
722
723
		self::registerCleanupHooks();
724
		self::registerFilesystemHooks();
725
		self::registerShareHooks();
726
		self::registerEncryptionWrapper();
727
		self::registerEncryptionHooks();
728
		self::registerAccountHooks();
729
		self::registerResourceCollectionHooks();
730
		self::registerAppRestrictionsHooks();
731
732
		// Make sure that the application class is not loaded before the database is setup
733
		if ($systemConfig->getValue("installed", false)) {
734
			OC_App::loadApp('settings');
735
			$settings = \OC::$server->query(\OCA\Settings\AppInfo\Application::class);
736
			$settings->register();
737
		}
738
739
		//make sure temporary files are cleaned up
740
		$tmpManager = \OC::$server->getTempManager();
741
		register_shutdown_function(array($tmpManager, 'clean'));
742
		$lockProvider = \OC::$server->getLockingProvider();
743
		register_shutdown_function(array($lockProvider, 'releaseAll'));
744
745
		// Check whether the sample configuration has been copied
746
		if($systemConfig->getValue('copied_sample_config', false)) {
747
			$l = \OC::$server->getL10N('lib');
748
			OC_Template::printErrorPage(
749
				$l->t('Sample configuration detected'),
750
				$l->t('It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php'),
751
				503
752
			);
753
			return;
754
		}
755
756
		$request = \OC::$server->getRequest();
757
		$host = $request->getInsecureServerHost();
758
		/**
759
		 * if the host passed in headers isn't trusted
760
		 * FIXME: Should not be in here at all :see_no_evil:
761
		 */
762
		if (!OC::$CLI
763
			&& !\OC::$server->getTrustedDomainHelper()->isTrustedDomain($host)
764
			&& self::$server->getConfig()->getSystemValue('installed', false)
765
		) {
766
			// Allow access to CSS resources
767
			$isScssRequest = false;
768
			if(strpos($request->getPathInfo(), '/css/') === 0) {
769
				$isScssRequest = true;
770
			}
771
772
			if(substr($request->getRequestUri(), -11) === '/status.php') {
773
				http_response_code(400);
774
				header('Content-Type: application/json');
775
				echo '{"error": "Trusted domain error.", "code": 15}';
776
				exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
777
			}
778
779
			if (!$isScssRequest) {
780
				http_response_code(400);
781
782
				\OC::$server->getLogger()->info(
783
					'Trusted domain error. "{remoteAddress}" tried to access using "{host}" as host.',
784
					[
785
						'app' => 'core',
786
						'remoteAddress' => $request->getRemoteAddress(),
787
						'host' => $host,
788
					]
789
				);
790
791
				$tmpl = new OCP\Template('core', 'untrustedDomain', 'guest');
792
				$tmpl->assign('docUrl', \OC::$server->getURLGenerator()->linkToDocs('admin-trusted-domains'));
793
				$tmpl->printPage();
794
795
				exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
796
			}
797
		}
798
		\OC::$server->getEventLogger()->end('boot');
799
	}
800
801
	/**
802
	 * register hooks for the cleanup of cache and bruteforce protection
803
	 */
804
	public static function registerCleanupHooks() {
805
		//don't try to do this before we are properly setup
806
		if (\OC::$server->getSystemConfig()->getValue('installed', false) && !\OCP\Util::needUpgrade()) {
807
808
			// NOTE: This will be replaced to use OCP
809
			$userSession = self::$server->getUserSession();
810
			$userSession->listen('\OC\User', 'postLogin', function () use ($userSession) {
0 ignored issues
show
Unused Code introduced by
The import $userSession is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
811
				if (!defined('PHPUNIT_RUN')) {
812
					// reset brute force delay for this IP address and username
813
					$uid = \OC::$server->getUserSession()->getUser()->getUID();
814
					$request = \OC::$server->getRequest();
815
					$throttler = \OC::$server->getBruteForceThrottler();
816
					$throttler->resetDelay($request->getRemoteAddress(), 'login', ['user' => $uid]);
0 ignored issues
show
Bug introduced by
array('user' => $uid) of type array<string,string> is incompatible with the type string expected by parameter $metadata of OC\Security\Bruteforce\Throttler::resetDelay(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

816
					$throttler->resetDelay($request->getRemoteAddress(), 'login', /** @scrutinizer ignore-type */ ['user' => $uid]);
Loading history...
817
				}
818
819
				try {
820
					$cache = new \OC\Cache\File();
821
					$cache->gc();
822
				} catch (\OC\ServerNotAvailableException $e) {
823
					// not a GC exception, pass it on
824
					throw $e;
825
				} catch (\OC\ForbiddenException $e) {
826
					// filesystem blocked for this request, ignore
827
				} catch (\Exception $e) {
828
					// a GC exception should not prevent users from using OC,
829
					// so log the exception
830
					\OC::$server->getLogger()->logException($e, [
831
						'message' => 'Exception when running cache gc.',
832
						'level' => ILogger::WARN,
833
						'app' => 'core',
834
					]);
835
				}
836
			});
837
		}
838
	}
839
840
	private static function registerEncryptionWrapper() {
841
		$manager = self::$server->getEncryptionManager();
842
		\OCP\Util::connectHook('OC_Filesystem', 'preSetup', $manager, 'setupStorage');
843
	}
844
845
	private static function registerEncryptionHooks() {
846
		$enabled = self::$server->getEncryptionManager()->isEnabled();
847
		if ($enabled) {
848
			\OCP\Util::connectHook(Share::class, 'post_shared', HookManager::class, 'postShared');
849
			\OCP\Util::connectHook(Share::class, 'post_unshare', HookManager::class, 'postUnshared');
850
			\OCP\Util::connectHook('OC_Filesystem', 'post_rename', HookManager::class, 'postRename');
851
			\OCP\Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', HookManager::class, 'postRestore');
852
		}
853
	}
854
855
	private static function registerAccountHooks() {
856
		$hookHandler = new \OC\Accounts\Hooks(\OC::$server->getLogger());
857
		\OCP\Util::connectHook('OC_User', 'changeUser', $hookHandler, 'changeUserHook');
858
	}
859
860
	private static function registerAppRestrictionsHooks() {
861
		$groupManager = self::$server->query(\OCP\IGroupManager::class);
862
		$groupManager->listen ('\OC\Group', 'postDelete', function (\OCP\IGroup $group) {
863
			$appManager = self::$server->getAppManager();
864
			$apps = $appManager->getEnabledAppsForGroup($group);
865
			foreach ($apps as $appId) {
866
				$restrictions = $appManager->getAppRestriction($appId);
867
				if (empty($restrictions)) {
868
					continue;
869
				}
870
				$key = array_search($group->getGID(), $restrictions);
871
				unset($restrictions[$key]);
872
				$restrictions = array_values($restrictions);
873
				if (empty($restrictions)) {
874
					$appManager->disableApp($appId);
875
				}
876
				else{
877
					$appManager->enableAppForGroups($appId, $restrictions);
878
				}
879
880
			}
881
		});
882
	}
883
884
	private static function registerResourceCollectionHooks() {
885
		\OC\Collaboration\Resources\Listener::register(\OC::$server->getEventDispatcher());
0 ignored issues
show
Deprecated Code introduced by
The function OC\Server::getEventDispatcher() has been deprecated: 18.0.0 use \OCP\EventDispatcher\IEventDispatcher ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

885
		\OC\Collaboration\Resources\Listener::register(/** @scrutinizer ignore-deprecated */ \OC::$server->getEventDispatcher());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
886
	}
887
888
	/**
889
	 * register hooks for the filesystem
890
	 */
891
	public static function registerFilesystemHooks() {
892
		// Check for blacklisted files
893
		OC_Hook::connect('OC_Filesystem', 'write', Filesystem::class, 'isBlacklisted');
894
		OC_Hook::connect('OC_Filesystem', 'rename', Filesystem::class, 'isBlacklisted');
895
	}
896
897
	/**
898
	 * register hooks for sharing
899
	 */
900
	public static function registerShareHooks() {
901
		if (\OC::$server->getSystemConfig()->getValue('installed')) {
902
			OC_Hook::connect('OC_User', 'post_deleteUser', Hooks::class, 'post_deleteUser');
903
			OC_Hook::connect('OC_User', 'post_removeFromGroup', Hooks::class, 'post_removeFromGroup');
904
			OC_Hook::connect('OC_User', 'post_deleteGroup', Hooks::class, 'post_deleteGroup');
905
		}
906
	}
907
908
	protected static function registerAutoloaderCache() {
909
		// The class loader takes an optional low-latency cache, which MUST be
910
		// namespaced. The instanceid is used for namespacing, but might be
911
		// unavailable at this point. Furthermore, it might not be possible to
912
		// generate an instanceid via \OC_Util::getInstanceId() because the
913
		// config file may not be writable. As such, we only register a class
914
		// loader cache if instanceid is available without trying to create one.
915
		$instanceId = \OC::$server->getSystemConfig()->getValue('instanceid', null);
916
		if ($instanceId) {
917
			try {
918
				$memcacheFactory = \OC::$server->getMemCacheFactory();
919
				self::$loader->setMemoryCache($memcacheFactory->createLocal('Autoloader'));
920
			} catch (\Exception $ex) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
921
			}
922
		}
923
	}
924
925
	/**
926
	 * Handle the request
927
	 */
928
	public static function handleRequest() {
929
930
		\OC::$server->getEventLogger()->start('handle_request', 'Handle request');
931
		$systemConfig = \OC::$server->getSystemConfig();
932
933
		// Check if Nextcloud is installed or in maintenance (update) mode
934
		if (!$systemConfig->getValue('installed', false)) {
935
			\OC::$server->getSession()->clear();
936
			$setupHelper = new OC\Setup(
937
				$systemConfig,
938
				\OC::$server->getIniWrapper(),
939
				\OC::$server->getL10N('lib'),
940
				\OC::$server->query(\OCP\Defaults::class),
941
				\OC::$server->getLogger(),
942
				\OC::$server->getSecureRandom(),
943
				\OC::$server->query(\OC\Installer::class)
944
			);
945
			$controller = new OC\Core\Controller\SetupController($setupHelper);
946
			$controller->run($_POST);
947
			exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
948
		}
949
950
		$request = \OC::$server->getRequest();
951
		$requestPath = $request->getRawPathInfo();
952
		if ($requestPath === '/heartbeat') {
953
			return;
954
		}
955
		if (substr($requestPath, -3) !== '.js') { // we need these files during the upgrade
956
			self::checkMaintenanceMode();
957
958
			if (\OCP\Util::needUpgrade()) {
959
				if (function_exists('opcache_reset')) {
960
					opcache_reset();
961
				}
962
				if (!((bool) $systemConfig->getValue('maintenance', false))) {
963
					self::printUpgradePage($systemConfig);
964
					exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
965
				}
966
			}
967
		}
968
969
		// emergency app disabling
970
		if ($requestPath === '/disableapp'
971
			&& $request->getMethod() === 'POST'
972
			&& ((array)$request->getParam('appid')) !== ''
973
		) {
974
			\OC_JSON::callCheck();
0 ignored issues
show
Deprecated Code introduced by
The function OC_JSON::callCheck() has been deprecated: Use annotation based CSRF checks from the AppFramework instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

974
			/** @scrutinizer ignore-deprecated */ \OC_JSON::callCheck();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
975
			\OC_JSON::checkAdminUser();
976
			$appIds = (array)$request->getParam('appid');
977
			foreach($appIds as $appId) {
978
				$appId = \OC_App::cleanAppId($appId);
979
				\OC::$server->getAppManager()->disableApp($appId);
980
			}
981
			\OC_JSON::success();
982
			exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
983
		}
984
985
		// Always load authentication apps
986
		OC_App::loadApps(['authentication']);
987
988
		// Load minimum set of apps
989
		if (!\OCP\Util::needUpgrade()
990
			&& !((bool) $systemConfig->getValue('maintenance', false))) {
991
			// For logged-in users: Load everything
992
			if(\OC::$server->getUserSession()->isLoggedIn()) {
993
				OC_App::loadApps();
994
			} else {
995
				// For guests: Load only filesystem and logging
996
				OC_App::loadApps(array('filesystem', 'logging'));
997
				self::handleLogin($request);
998
			}
999
		}
1000
1001
		if (!self::$CLI) {
1002
			try {
1003
				if (!((bool) $systemConfig->getValue('maintenance', false)) && !\OCP\Util::needUpgrade()) {
1004
					OC_App::loadApps(array('filesystem', 'logging'));
1005
					OC_App::loadApps();
1006
				}
1007
				OC_Util::setupFS();
1008
				OC::$server->getRouter()->match(\OC::$server->getRequest()->getRawPathInfo());
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Route\IRouter::match() has been deprecated: 9.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1008
				/** @scrutinizer ignore-deprecated */ OC::$server->getRouter()->match(\OC::$server->getRequest()->getRawPathInfo());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1009
				return;
1010
			} catch (Symfony\Component\Routing\Exception\ResourceNotFoundException $e) {
1011
				//header('HTTP/1.0 404 Not Found');
1012
			} catch (Symfony\Component\Routing\Exception\MethodNotAllowedException $e) {
1013
				http_response_code(405);
1014
				return;
1015
			}
1016
		}
1017
1018
		// Handle WebDAV
1019
		if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PROPFIND') {
1020
			// not allowed any more to prevent people
1021
			// mounting this root directly.
1022
			// Users need to mount remote.php/webdav instead.
1023
			http_response_code(405);
1024
			return;
1025
		}
1026
1027
		// Someone is logged in
1028
		if (\OC::$server->getUserSession()->isLoggedIn()) {
1029
			OC_App::loadApps();
1030
			OC_User::setupBackends();
1031
			OC_Util::setupFS();
1032
			// FIXME
1033
			// Redirect to default application
1034
			OC_Util::redirectToDefaultPage();
1035
		} else {
1036
			// Not handled and not logged in
1037
			header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute('core.login.showLoginForm'));
1038
		}
1039
	}
1040
1041
	/**
1042
	 * Check login: apache auth, auth token, basic auth
1043
	 *
1044
	 * @param OCP\IRequest $request
1045
	 * @return boolean
1046
	 */
1047
	static function handleLogin(OCP\IRequest $request) {
1048
		$userSession = self::$server->getUserSession();
1049
		if (OC_User::handleApacheAuth()) {
1050
			return true;
1051
		}
1052
		if ($userSession->tryTokenLogin($request)) {
1053
			return true;
1054
		}
1055
		if (isset($_COOKIE['nc_username'])
1056
			&& isset($_COOKIE['nc_token'])
1057
			&& isset($_COOKIE['nc_session_id'])
1058
			&& $userSession->loginWithCookie($_COOKIE['nc_username'], $_COOKIE['nc_token'], $_COOKIE['nc_session_id'])) {
1059
			return true;
1060
		}
1061
		if ($userSession->tryBasicAuthLogin($request, \OC::$server->getBruteForceThrottler())) {
1062
			return true;
1063
		}
1064
		return false;
1065
	}
1066
1067
	protected static function handleAuthHeaders() {
1068
		//copy http auth headers for apache+php-fcgid work around
1069
		if (isset($_SERVER['HTTP_XAUTHORIZATION']) && !isset($_SERVER['HTTP_AUTHORIZATION'])) {
1070
			$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['HTTP_XAUTHORIZATION'];
1071
		}
1072
1073
		// Extract PHP_AUTH_USER/PHP_AUTH_PW from other headers if necessary.
1074
		$vars = array(
1075
			'HTTP_AUTHORIZATION', // apache+php-cgi work around
1076
			'REDIRECT_HTTP_AUTHORIZATION', // apache+php-cgi alternative
1077
		);
1078
		foreach ($vars as $var) {
1079
			if (isset($_SERVER[$var]) && preg_match('/Basic\s+(.*)$/i', $_SERVER[$var], $matches)) {
1080
				$credentials = explode(':', base64_decode($matches[1]), 2);
1081
				if (count($credentials) === 2) {
1082
					$_SERVER['PHP_AUTH_USER'] = $credentials[0];
1083
					$_SERVER['PHP_AUTH_PW'] = $credentials[1];
1084
					break;
1085
				}
1086
			}
1087
		}
1088
	}
1089
}
1090
1091
OC::init();
1092