Test Failed
Push — master ( c4f486...829997 )
by
unknown
35:45 queued 20:22
created
Labels
Severity
1
<?php
2
3
/**
4
 * This is the entry point for every request that should return HTML
5
 * (one exception is that it also returns translated text for javascript).
6
 */
7
8
// Bootstrap the script
9
require_once 'server/includes/bootstrap.php';
10
11
// Added in 3.4.0, remove check in 3.5.0
12
if (!function_exists('gitversion')) {
13
	/**
14
	 * Obtain the current Git working branch.
15
	 *
16
	 * @return string the current git working branch
17
	 */
18
	function gitversion() {
19
		if (is_dir(BASE_PATH . DIRECTORY_SEPARATOR . '.git')) {
20
			return trim(@shell_exec("git symbolic-ref --short HEAD || git rev-parse --short HEAD ."));
0 ignored issues
show
It seems like @shell_exec('git symboli...-parse --short HEAD .') can also be of type false and null; however, parameter $string of trim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

20
			return trim(/** @scrutinizer ignore-type */ @shell_exec("git symbolic-ref --short HEAD || git rev-parse --short HEAD ."));
Loading history...
21
		}
22
23
		return '';
24
	}
25
}
26
else {
27
	error_log('Remove gitversion() function in debug.php it\'s deprecated');
28
}
29
30
/*
31
 * Get the favicon either from theme or use the default.
32
 *
33
 * @param string theme the users theme
34
 * @return string favicon
35
 */
36
function getFavicon($theme) {
37
	$favicon = Theming::getFavicon($theme);
38
39
	if (!isset($favicon) || $favicon === false) {
40
		$favicon = 'client/resources/images/favicon.ico?kv2.2.0';
41
	}
42
43
	return $favicon;
44
}
45
46
// If the user wants to logout (and is not using single-signon)
47
// then destroy the session and redirect to this page, so the login page
48
// will be shown
49
50
if (isset($_GET['logout'])) {
51
	if (isset($_SESSION['_keycloak_auth'])) {
52
		$keycloak_auth = $_SESSION['_keycloak_auth']->logout();
53
		header("Location:" . $keycloak_auth . "");
54
	}
55
	else {
56
		// GET variable user will be set when the user was logged out because of session timeout
57
		// or because he logged out in another window.
58
		$username = sanitizeGetValue('user', '', USERNAME_REGEX);
59
		$location = rtrim(dirname($_SERVER['PHP_SELF']), '/') . '/';
60
		header('Location: ' . $location . ($username ? '?user=' . rawurlencode($username) : ''), true, 303);
61
	}
62
	$webappSession->destroy();
63
64
	exit;
65
}
66
67
// Check if an action GET-parameter was sent with the request.
68
// This parameter is set when the webapp was opened by clicking on
69
// a mailto: link in the browser.
70
// If so, we will store it in the session, so we can use it later.
71
if (isset($_GET['action']) && !empty($_GET['action'])) {
72
	storeURLDataToSession();
73
}
74
75
// Check if the continue parameter was set. This will be set e.g. when someone
76
// uses the grommunio Web to login to another application with OpenID Connect.
77
if (isset($_GET['continue']) && !empty($_GET['continue']) && !isset($_GET['wacontinue'])) {
78
	$_SESSION['continue'] = $_GET['continue'];
79
}
80
81
// Try to authenticate the user
82
WebAppAuthentication::authenticate();
83
84
$webappTitle = defined('WEBAPP_TITLE') && WEBAPP_TITLE ? WEBAPP_TITLE : 'grommunio Web';
85
if (isset($_COOKIE['webapp_title'])) {
86
	$webappTitle .= " – " . $_COOKIE['webapp_title'];
87
}
88
89
// If we could not authenticate the user, we will show the login page
90
if (!WebAppAuthentication::isAuthenticated()) {
91
	// Get language from the cookie, or from the language that is set by the admin
92
	$Language = new Language();
93
	$lang = isset($_COOKIE['lang']) ? $_COOKIE['lang'] : LANG;
94
	$lang = $Language->resolveLanguage($lang);
95
	$Language->setLanguage($lang);
96
97
	// If GET parameter 'load' is defined, we defer handling to the load.php script
98
	if (isset($_GET['load']) && $_GET['load'] !== 'logon') {
99
		include BASE_PATH . 'server/includes/load.php';
100
101
		exit;
102
	}
103
104
	// Set some template variables for the login page
105
	$branch = DEBUG_LOADER === LOAD_SOURCE ? gitversion() : '';
106
	$version = 'grommunio Web ' . trim(file_get_contents('version'));
107
	$user = sanitizeGetValue('user', '', USERNAME_REGEX);
108
109
	$url = '?logon';
110
111
	if (isset($_GET["logout"]) && $_GET["logout"] == "auto") {
112
		$error = _("You have been automatically logged out");
113
	}
114
	else {
115
		$error = WebAppAuthentication::getErrorMessage();
116
		if (empty($error) && useSecureCookies() && getRequestProtocol() == 'http') {
117
			header("HTTP/1.0 400 Bad Request");
118
			include BASE_PATH . 'server/includes/templates/BadRequest.php';
119
			error_log("Rejected insecure request as configuration for 'SECURE_COOKIES' is true.");
120
121
			exit;
122
		}
123
	}
124
125
	// If a username was passed as GET parameter we will prefill the username input
126
	// of the login form with it.
127
	$user = isset($_GET['user']) ? htmlentities($_GET['user']) : '';
128
129
	// Lets add a header when login failed (DeskApp needs it to identify failed login attempts)
130
	if (WebAppAuthentication::getErrorCode() !== NOERROR) {
131
		header("X-grommunio-Hresult: " . get_mapi_error_name(WebAppAuthentication::getErrorCode()));
132
	}
133
134
	// Set a template variable for the favicon of the login, welcome, and webclient page
135
	$theme = Theming::getActiveTheme();
136
	$favicon = getFavicon(Theming::getActiveTheme());
137
	include BASE_PATH . 'server/includes/templates/login.php';
138
139
	exit;
140
}
141
142
// The user is authenticated! Let's get ready to start the webapp.
143
// If the user just logged in or if url data was stored in the session,
144
// we will redirect to make sure that a browser refresh will not post
145
// the credentials again, and that the url data is taken away from the
146
// url in the address bar (so a browser refresh will not pass them again)
147
if (isset($_GET['code']) || (WebAppAuthentication::isUsingLoginForm() || isset($_GET['action']) && !empty($_GET['action']))) {
148
	$location = rtrim(dirname($_SERVER['PHP_SELF']), '/') . '/';
149
	header('Location: ' . $location, true, 303);
150
151
	exit;
152
}
153
154
// TODO: we could replace all references to $GLOBALS['mapisession']
155
// with WebAppAuthentication::getMAPISession(), that way we would
156
// lose at least one GLOBAL (because globals suck)
157
$GLOBALS['mapisession'] = WebAppAuthentication::getMAPISession();
158
159
// check if it's DB or LDAP for the password plugin
160
$result = @json_decode(@file_get_contents(ADMIN_API_STATUS_ENDPOINT, false), true);
161
if (isset($result['ldap']) && $result['ldap']) {
162
	$GLOBALS['usersinldap'] = true;
163
}
164
165
// Instantiate Plugin Manager and init the plugins (btw: globals suck)
166
$GLOBALS['PluginManager'] = new PluginManager(ENABLE_PLUGINS);
167
$GLOBALS['PluginManager']->detectPlugins(DISABLED_PLUGINS_LIST);
168
169
// Initialize plugins and prevent any output which might be written as
170
// plugins might be uncleanly output white-space and other stuff. We must
171
// not allow this here as it can destroy the response data.
172
ob_start();
173
$GLOBALS['PluginManager']->initPlugins(DEBUG_LOADER);
174
ob_end_clean();
175
176
// Create globals settings object (btw: globals suck)
177
$GLOBALS["settings"] = new Settings();
178
179
// Create global operations object
180
$GLOBALS["operations"] = new Operations();
181
182
// If webapp feature is not enabled for the user,
183
// we will show the login page with appropriated error message.
184
if ($GLOBALS['mapisession']->isWebappDisableAsFeature()) {
185
	header("X-grommunio-Hresult: " . get_mapi_error_name(MAPI_E_WEBAPP_FEATURE_DISABLED));
186
187
	$error = _("Sorry, access to grommunio Web is not available with this user account. Please contact your system administrator.");
188
	// Set some template variables for the login page
189
	$user = sanitizeGetValue('user', '', USERNAME_REGEX);
190
191
	$url = '?logon';
192
	// Set a template variable for the favicon of the login, welcome, and webclient page
193
	$theme = Theming::getActiveTheme();
194
	$favicon = getFavicon(Theming::getActiveTheme());
195
	$webappSession->destroy();
196
	// Include the login template
197
	include BASE_PATH . 'server/includes/templates/login.php';
198
199
	exit;
200
}
201
202
$Language = new Language();
203
204
// Set session settings (language & style)
205
foreach ($GLOBALS["settings"]->getSessionSettings($Language) as $key => $value) {
206
	$_SESSION[$key] = $value;
207
}
208
209
// Get language from the request, or the session, or the user settings, or the config
210
if (isset($_REQUEST["language"]) && $Language->is_language($_REQUEST["language"])) {
211
	$lang = $_REQUEST["language"];
212
	$GLOBALS["settings"]->set("zarafa/v1/main/language", $lang);
213
}
214
elseif (isset($_SESSION["lang"])) {
215
	$lang = $_SESSION["lang"];
216
	$GLOBALS["settings"]->set("zarafa/v1/main/language", $lang);
217
}
218
else {
219
	$lang = $GLOBALS["settings"]->get("zarafa/v1/main/language");
220
	if (empty($lang)) {
221
		$lang = LANG;
222
		$GLOBALS["settings"]->set("zarafa/v1/main/language", $lang);
223
	}
224
}
225
226
$Language->setLanguage($lang);
227
setcookie('lang', $lang, [
228
	'expires' => time() + 31536000,
229
	'path' => '/',
230
	'domain' => '',
231
	'secure' => true,
232
	'httponly' => true,
233
	'samesite' => 'Strict',
234
]);
235
236
// add extra header
237
header("X-grommunio: " . trim(file_get_contents('version')));
238
239
// Set a template variable for the favicon of the login, welcome, and webclient page
240
$theme = Theming::getActiveTheme();
241
$favicon = getFavicon(Theming::getActiveTheme());
242
$hideFavorites = $GLOBALS["settings"]->get("zarafa/v1/contexts/hierarchy/hide_favorites") ? 'hideFavorites' : '';
243
$scrollFavorites = $GLOBALS["settings"]->get("zarafa/v1/contexts/hierarchy/scroll_favorites") ? 'scrollFavorites' : '';
244
$unreadBorders = $GLOBALS["settings"]->get("zarafa/v1/main/unread_borders") === false ? '' : 'k-unreadborders';
245
246
// If GET parameter 'load' is defined, we defer handling to the load.php script
247
if (isset($_GET['load'])) {
248
	include BASE_PATH . 'server/includes/load.php';
249
250
	exit;
251
}
252
253
if (ENABLE_WELCOME_SCREEN && $GLOBALS["settings"]->get("zarafa/v1/main/show_welcome") !== false) {
254
	// These hooks are defined twice (also when there is a "load" argument supplied)
255
	$GLOBALS['PluginManager']->triggerHook("server.index.load.welcome.before");
256
	include BASE_PATH . 'server/includes/templates/welcome.php';
257
	$GLOBALS['PluginManager']->triggerHook("server.index.load.welcome.after");
258
}
259
else {
260
	// Set the show_welcome to false, so that when the admin is changing the
261
	// ENABLE_WELCOME_SCREEN option to false after some time, the users who are already
262
	// using grommunio Web are not bothered with the Welcome Screen.
263
	$GLOBALS["settings"]->set("zarafa/v1/main/show_welcome", false);
264
265
	// Clean up old state files in tmp/session/
266
	$state = new State("index");
267
	$state->clean();
268
269
	// Clean up old attachments in tmp/attachments/
270
	$state = new AttachmentState();
271
	$state->clean();
272
273
	// Fetch the hierarchy state cache for unread counters notifications for subfolders
274
	$counterState = new State('counters_sessiondata');
275
	$counterState->open();
276
	$counterState->write("sessionData", updateHierarchyCounters());
277
	$counterState->close();
278
279
	// clean search folders
280
	cleanSearchFolders();
281
282
	// These hooks are defined twice (also when there is a "load" argument supplied)
283
	$GLOBALS['PluginManager']->triggerHook("server.index.load.main.before");
284
285
	// Include webclient
286
	include BASE_PATH . 'server/includes/templates/webclient.php';
287
	$GLOBALS['PluginManager']->triggerHook("server.index.load.main.after");
288
}
289