Happy New Year
[squirrelmail.git] / include / init.php
CommitLineData
202bcbcc 1<?php
2
3/**
4 * init.php -- initialisation file
5 *
6 * File should be loaded in every file in src/ or plugins that occupate an entire frame
7 *
353d074a 8 * @copyright 2006-2018 The SquirrelMail Project Team
202bcbcc 9 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
10 * @version $Id$
11 * @package squirrelmail
12 */
13
202bcbcc 14/**
15 * This is a development version so in order to track programmer mistakes we
16 * set the error reporting to E_ALL
1888b1bf 17FIXME: disabling this for now, because we now have $sm_debug_mode, but the problem with that is that we don't know what it will be until we have loaded the config file, a good 175 lines below after several important files have been included, etc. For now, we'll trust that developers have turned on E_ALL in php.ini anyway, but this can be uncommented if not.
202bcbcc 18 */
1888b1bf 19//error_reporting(E_ALL);
20
202bcbcc 21
202bcbcc 22/**
c7ebdfcf 23 * Make sure we have a page name
24 *
25 */
26if ( !defined('PAGE_NAME') ) define('PAGE_NAME', NULL);
27
28
29/**
6a2a6e44 30 * If register_globals are on, unregister globals.
a3b99374 31 * Second test covers boolean set as string (php_value register_globals off).
6a2a6e44 32 */
55dd9abf 33if ((bool) ini_get('register_globals') &&
a3b99374 34 strtolower(ini_get('register_globals'))!='off') {
6a2a6e44 35 /**
55dd9abf 36 * Remove all globals that are not reserved by PHP
37 * 'value' and 'key' are used by foreach. Don't unset them inside foreach.
6a2a6e44 38 */
55dd9abf 39 foreach ($GLOBALS as $key => $value) {
40 switch($key) {
41 case 'HTTP_POST_VARS':
42 case '_POST':
43 case 'HTTP_GET_VARS':
44 case '_GET':
45 case 'HTTP_COOKIE_VARS':
46 case '_COOKIE':
47 case 'HTTP_SERVER_VARS':
48 case '_SERVER':
49 case 'HTTP_ENV_VARS':
50 case '_ENV':
51 case 'HTTP_POST_FILES':
52 case '_FILES':
53 case '_REQUEST':
54 case 'HTTP_SESSION_VARS':
55 case '_SESSION':
56 case 'GLOBALS':
57 case 'key':
58 case 'value':
59 break;
55dd9abf 60 default:
61 unset($GLOBALS[$key]);
62 }
6a2a6e44 63 }
55dd9abf 64 // Unset variables used in foreach
65 unset($GLOBALS['key']);
66 unset($GLOBALS['value']);
6a2a6e44 67}
68
71efd1ed 69/**
d849b570 70 * Used as a dummy value, e.g., for passing as an empty
e39d00e9 71 * hook argument (where the value is passed by reference,
72 * and therefore NULL itself is not acceptable).
d849b570 73 */
086ad092 74global $null;
d849b570 75$null = NULL;
76
77/**
dbbd586e 78 * The global $server_os variable will be "windows" if
79 * we are working in a Windows environment or "*nix"
80 * otherwise.
81 */
82global $server_os;
83if (DIRECTORY_SEPARATOR == '\\') $server_os = 'windows'; else $server_os = '*nix';
84
85/**
71efd1ed 86 * [#1518885] session.use_cookies = off breaks SquirrelMail
87 *
086ad092 88 * When session cookies are not used, all http redirects, meta refreshes,
89 * src/download.php and javascript URLs are broken. Setting must be set
71efd1ed 90 * before session is started.
91 */
92if (!(bool)ini_get('session.use_cookies') ||
93 ini_get('session.use_cookies') == 'off') {
94 ini_set('session.use_cookies','1');
95}
6a2a6e44 96
79dd8c72 97/**
98 * Initialize seed of random number generator.
99 * We use a number of things to randomize input: current time in ms,
100 * info about the remote client, info about the current process, the
101 * randomness of uniqid and stat of the current file.
102 *
103 * We seed this here only once per init, not only to save cycles
104 * but also to make the result of mt_rand more random (it now also
105 * depends on the number of times mt_rand was called before in this
106 * execution.
107 */
108$seed = microtime() . $_SERVER['REMOTE_PORT'] . $_SERVER['REMOTE_ADDR'] . getmypid();
109
110if (function_exists('getrusage')) {
111 /* Avoid warnings with Win32 */
112 $dat = @getrusage();
113 if (isset($dat) && is_array($dat)) { $seed .= implode('', $dat); }
114}
115
116if(!empty($_SERVER['UNIQUE_ID'])) {
117 $seed .= $_SERVER['UNIQUE_ID'];
118}
119
120$seed .= uniqid(mt_rand(),TRUE);
7428254a 121$seed .= implode('', stat( __FILE__));
79dd8c72 122
8313aa5e 123// mt_srand() uses an integer to seed, so we need to distill our
124// very large seed to something useful (without taking a sub-string,
125// the integer conversion of such a large number is always 0 on
126// many systems, but strangely, 9 hex numbers - even if larger
127// than a signed 32 bit integer - seem to be an acceptable "integer"
128// seed (perhaps it is used as unsigned?)...
129// we may want to revisit this and always force it to be less than
130// 2,147,483,647
131//
132$seed = hexdec(substr(md5($seed), 0, 9));
133
134// PHP 4.2 and up don't require seeding, but their used seed algorithm
135// is of questionable quality, so we keep doing it ourselves. */
136mt_srand($seed);
3f081dd0 137
6a2a6e44 138/**
202bcbcc 139 * calculate SM_PATH and calculate the base_uri
140 * assumptions made: init.php is only called from plugins or from the src dir.
141 * files in the plugin directory may not be part of a subdirectory called "src"
142 *
143 */
144if (isset($_SERVER['SCRIPT_NAME'])) {
3f081dd0 145 $a = explode('/', $_SERVER['SCRIPT_NAME']);
202bcbcc 146} elseif (isset($HTTP_SERVER_VARS['SCRIPT_NAME'])) {
3f081dd0 147 $a = explode('/', $HTTP_SERVER_VARS['SCRIPT_NAME']);
b0829edf 148} else {
3f081dd0 149 $error = 'Unable to detect script environment. Please test your PHP '
150 . 'settings and send your PHP core configuration, $_SERVER and '
151 . '$HTTP_SERVER_VARS contents to the SquirrelMail developers.';
b0829edf 152 die($error);
202bcbcc 153}
154$sSM_PATH = '';
3f081dd0 155for($i = count($a) -2; $i > -1; --$i) {
202bcbcc 156 $sSM_PATH .= '../';
157 if ($a[$i] === 'src' || $a[$i] === 'plugins') {
158 break;
159 }
160}
161
3f081dd0 162$base_uri = implode('/', array_slice($a, 0, $i)). '/';
202bcbcc 163
202bcbcc 164define('SM_PATH',$sSM_PATH);
6a2a6e44 165define('SM_BASE_URI', $base_uri);
3f081dd0 166
167
202bcbcc 168/**
169 * global var $bInit is used to check if initialisation took place.
170 * At this moment it's a workarounf for the include of addrbook_search_html
171 * inside compose.php. If we found a better way then remove this. Do only use
172 * this var if you know for sure a page can be called stand alone and be included
173 * in another file.
174 */
175$bInit = true;
176
8e1e2794 177/**
178 * This theme as a failsafe if no themes were found, or if we error
179 * out before anything could be initialised.
180 */
181$color = array();
182$color[0] = '#DCDCDC'; /* light gray TitleBar */
183$color[1] = '#800000'; /* red */
184$color[2] = '#CC0000'; /* light red Warning/Error Messages */
185$color[3] = '#A0B8C8'; /* green-blue Left Bar Background */
186$color[4] = '#FFFFFF'; /* white Normal Background */
187$color[5] = '#FFFFCC'; /* light yellow Table Headers */
188$color[6] = '#000000'; /* black Text on left bar */
189$color[7] = '#0000CC'; /* blue Links */
190$color[8] = '#000000'; /* black Normal text */
191$color[9] = '#ABABAB'; /* mid-gray Darker version of #0 */
192$color[10] = '#666666'; /* dark gray Darker version of #9 */
193$color[11] = '#770000'; /* dark red Special Folders color */
194$color[12] = '#EDEDED';
195$color[13] = '#800000'; /* (dark red) Color for quoted text -- > 1 quote */
196$color[14] = '#ff0000'; /* (red) Color for quoted text -- >> 2 or more */
197$color[15] = '#002266'; /* (dark blue) Unselectable folders */
198$color[16] = '#ff9933'; /* (orange) Highlight color */
199
1888b1bf 200require(SM_PATH . 'include/constants.php');
202bcbcc 201require(SM_PATH . 'functions/global.php');
4ffcf13a 202require(SM_PATH . 'functions/strings.php');
918fcc1d 203require(SM_PATH . 'functions/arrays.php');
67c826ce 204require(SM_PATH . 'functions/files.php');
5e68a08e 205
206/* load default configuration */
207require(SM_PATH . 'config/config_default.php');
208/* reset arrays in default configuration */
209$ldap_server = array();
210$plugins = array();
211$fontsets = array();
5e68a08e 212$aTemplateSet = array();
28294310 213$aTemplateSet[0]['ID'] = 'default';
214$aTemplateSet[0]['NAME'] = 'Default';
01fd1d1a 215
5e68a08e 216/* load site configuration */
202bcbcc 217require(SM_PATH . 'config/config.php');
5e68a08e 218/* load local configuration overrides */
219if (file_exists(SM_PATH . 'config/config_local.php')) {
220 require(SM_PATH . 'config/config_local.php');
221}
222
1888b1bf 223
224/**
225 * Set PHP error reporting level based on the SquirrelMail debug mode
3f55fe04 226 * E_STRICT = 2048
227 * E_DEPRECATED = 8192
1888b1bf 228 */
229$error_level = 0;
230if ($sm_debug_mode & SM_DEBUG_MODE_SIMPLE)
231 $error_level |= E_ERROR;
232if ($sm_debug_mode & SM_DEBUG_MODE_MODERATE
233 || $sm_debug_mode & SM_DEBUG_MODE_ADVANCED)
3f55fe04 234 $error_level = ($error_level | E_ALL) & ~2048 & ~8192;
1888b1bf 235if ($sm_debug_mode & SM_DEBUG_MODE_STRICT)
3f55fe04 236 $error_level |= 2048 | 8192;
1888b1bf 237error_reporting($error_level);
238
239
8f557b94 240/**
241 * Detect SSL connections
242 */
243$is_secure_connection = is_ssl_secured_connection();
244
245
202bcbcc 246require(SM_PATH . 'functions/plugin.php');
202bcbcc 247require(SM_PATH . 'include/languages.php');
42b5e8aa 248require(SM_PATH . 'class/template/Template.class.php');
5ab684a5 249require(SM_PATH . 'class/error.class.php');
202bcbcc 250
251/**
252 * If magic_quotes_runtime is on, SquirrelMail breaks in new and creative ways.
253 * Force magic_quotes_runtime off.
254 * tassium@squirrelmail.org - I put it here in the hopes that all SM code includes this.
255 * If there's a better place, please let me know.
256 */
257ini_set('magic_quotes_runtime','0');
258
259
260/* if running with magic_quotes_gpc then strip the slashes
261 from POST and GET global arrays */
430a19f3 262if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc()) {
202bcbcc 263 sqstripslashes($_GET);
264 sqstripslashes($_POST);
265}
266
202bcbcc 267
960b7ec2 268/**
269 * Strip any tags added to the url from PHP_SELF.
270 * This fixes hand crafted url XXS expoits for any
271 * page that uses PHP_SELF as the FORM action
272 * Update: strip_tags() won't catch something like
273 * src/right_main.php?sort=0&startMessage=1&mailbox=INBOX&xxx="><script>window.open("http://example.com")</script>
274 * or
275 * contrib/decrypt_headers.php/%22%20onmouseover=%22alert(%27hello%20world%27)%22%3E
276 * because it doesn't bother with broken tags.
3047e291 277 * sm_encode_html_special_chars() is the preferred method.
960b7ec2 278 * QUERY_STRING also needs the same treatment since it is
279 * used in php_self().
b837b30f 280 * Update again: the encoding of ampersands that occurs
3047e291 281 * using sm_encode_html_special_chars() corrupts the query strings
b837b30f 282 * in normal URIs, so we have to let those through.
283FIXME: will the de-sanitizing of ampersands create any security/XSS problems?
960b7ec2 284 */
49ec41bc 285if (isset($_SERVER['REQUEST_URI']))
3047e291 286 $_SERVER['REQUEST_URI'] = str_replace('&amp;', '&', sm_encode_html_special_chars($_SERVER['REQUEST_URI']));
49ec41bc 287if (isset($_SERVER['PHP_SELF']))
3047e291 288 $_SERVER['PHP_SELF'] = str_replace('&amp;', '&', sm_encode_html_special_chars($_SERVER['PHP_SELF']));
49ec41bc 289if (isset($_SERVER['QUERY_STRING']))
3047e291 290 $_SERVER['QUERY_STRING'] = str_replace('&amp;', '&', sm_encode_html_special_chars($_SERVER['QUERY_STRING']));
202bcbcc 291
292$PHP_SELF = php_self();
293
294/**
295 * Initialize the session
296 */
297
e8c4e350 298/** set the name of the session cookie */
299if (!isset($session_name) || !$session_name) {
300 $session_name = 'SQMSESSID';
301}
302
303/**
319ad3c0 304 * When session.auto_start is On we want to destroy/close the session
1d537493 305 */
306$sSessionAutostartName = session_name();
ccb5faf0 307$sSessionAutostartID = session_id();
308if (!empty($sSessionAutostartID) && $sSessionAutostartName !== $session_name) {
1d537493 309 $sCookiePath = ini_get('session.cookie_path');
310 $sCookieDomain = ini_get('session.cookie_domain');
e8c4e350 311 // reset the cookie
ccb5faf0 312 sqsetcookie($sSessionAutostartName,'',1,$sCookiePath,$sCookieDomain);
e8c4e350 313 @session_destroy();
314 session_write_close();
1d537493 315}
e8c4e350 316
202bcbcc 317/**
318 * includes from classes stored in the session
319 */
320require(SM_PATH . 'class/mime.class.php');
321
202bcbcc 322ini_set('session.name' , $session_name);
323session_set_cookie_params (0, $base_uri);
324sqsession_is_active();
325
202bcbcc 326/**
319ad3c0 327 * When on login page, have to reset the user session, making
328 * sure to save session restore data first
329 */
330if (PAGE_NAME == 'login') {
331 if (!sqGetGlobalVar('session_expired_post', $sep, SQ_SESSION))
332 $sep = '';
333 if (!sqGetGlobalVar('session_expired_location', $sel, SQ_SESSION))
334 $sel = '';
335 sqsession_destroy();
336 session_write_close();
337
338 /**
339 * in some rare instances, the session seems to stick
340 * around even after destroying it (!!), so if it does,
341 * we'll manually flatten the $_SESSION data
342 */
343 if (!empty($_SESSION))
344 $_SESSION = array();
345
bc3acc5a 346 /**
347 * Allow administrators to define custom session handlers
348 * for SquirrelMail without needing to change anything in
349 * php.ini (application-level).
350 *
351 * In config_local.php, admin needs to put:
352 *
353 * $custom_session_handlers = array(
354 * 'my_open_handler',
355 * 'my_close_handler',
356 * 'my_read_handler',
357 * 'my_write_handler',
358 * 'my_destroy_handler',
359 * 'my_gc_handler',
360 * );
361 * session_module_name('user');
362 * session_set_save_handler(
363 * $custom_session_handlers[0],
364 * $custom_session_handlers[1],
365 * $custom_session_handlers[2],
366 * $custom_session_handlers[3],
367 * $custom_session_handlers[4],
368 * $custom_session_handlers[5]
369 * );
370 *
371 * We need to replicate that code once here because PHP has
372 * long had a bug that resets the session handler mechanism
373 * when the session data is also destroyed. Because of this
374 * bug, even administrators who define custom session handlers
375 * via a PHP pre-load defined in php.ini (auto_prepend_file)
376 * will still need to define the $custom_session_handlers array
377 * in config_local.php.
378 */
379 global $custom_session_handlers;
380 if (!empty($custom_session_handlers)) {
381 $open = $custom_session_handlers[0];
382 $close = $custom_session_handlers[1];
383 $read = $custom_session_handlers[2];
384 $write = $custom_session_handlers[3];
385 $destroy = $custom_session_handlers[4];
386 $gc = $custom_session_handlers[5];
387 session_module_name('user');
388 session_set_save_handler($open, $close, $read, $write, $destroy, $gc);
389 }
390
319ad3c0 391 sqsession_is_active();
392 session_regenerate_id();
ef33def6 393
394 // put session restore data back into session if necessary
395 if (!empty($sel)) {
396 sqsession_register($sel, 'session_expired_location');
397 if (!empty($sep))
398 sqsession_register($sep, 'session_expired_post');
399 }
319ad3c0 400}
401
402/**
5aed95be 403 * SquirrelMail internal version number -- DO NOT CHANGE
404 * $sm_internal_version = array (release, major, minor)
405 */
a895042a 406$SQM_INTERNAL_VERSION = explode('.', SM_VERSION, 3);
b37e457f 407$SQM_INTERNAL_VERSION[2] = intval($SQM_INTERNAL_VERSION[2]);
5aed95be 408
93d67e0d 409
6d5775db 410/* load prefs system; even when user not logged in, should be OK to do this here */
411require(SM_PATH . 'functions/prefs.php');
412
6d5775db 413
086ad092 414/* if plugins are disabled only for one user and
93d67e0d 415 * the current user is NOT that user, turn them
416 * back on
417 */
0d56053e 418sqgetGlobalVar('username', $username, SQ_SESSION);
93d67e0d 419if ($disable_plugins && !empty($disable_plugins_user)
420 && $username != $disable_plugins_user) {
421 $disable_plugins = false;
422}
423
4a9f6063 424
93d67e0d 425/* remove all plugins if they are disabled */
426if ($disable_plugins) {
427 $plugins = array();
428}
429
430
5aed95be 431/**
432 * Include Compatibility plugin if available.
433 */
93d67e0d 434if (!$disable_plugins && file_exists(SM_PATH . 'plugins/compatibility/functions.php'))
5aed95be 435 include_once(SM_PATH . 'plugins/compatibility/functions.php');
436
4a9f6063 437
5aed95be 438/**
439 * MAIN PLUGIN LOADING CODE HERE
086ad092 440 * On init, we no longer need to load all plugin setup files.
5aed95be 441 * Now, we load the statically generated hook registrations here
442 * and let the hook calls include only the plugins needed.
443 */
444$squirrelmail_plugin_hooks = array();
93d67e0d 445if (!$disable_plugins && file_exists(SM_PATH . 'config/plugin_hooks.php')) {
4a9f6063 446//FIXME: if we keep the plugin hooks array static like this, it seems like we should also keep the template files list in a static file too (when a new user session is started or the template set is changed, the code will dynamically iterate through the directory heirarchy of the template directory and catalog all the template files therein (and store the "catalog" in PHP session) -- instead, we could do that once at config-time and keep that static so SM can just include the file just like the line below)
5aed95be 447 require(SM_PATH . 'config/plugin_hooks.php');
448}
449
4a9f6063 450
5aed95be 451/**
4a9f6063 452 * Plugin authors note that the "config_override" hook used to be
453 * executed here, but please adapt your plugin to use this "prefs_backend"
454 * hook instead, making sure that it does NOT return anything, since
455 * doing so will interfere with proper prefs system functionality.
456 * Of course, otherwise, this hook may be used to do any configuration
457 * overrides as needed, as well as set up a custom preferences backend.
5aed95be 458 */
4a9f6063 459$prefs_backend = do_hook('prefs_backend', $null);
460if (isset($prefs_backend) && !empty($prefs_backend) && file_exists(SM_PATH . $prefs_backend)) {
461 require(SM_PATH . $prefs_backend);
462} elseif (isset($prefs_dsn) && !empty($prefs_dsn)) {
463 require(SM_PATH . 'functions/db_prefs.php');
464} else {
465 require(SM_PATH . 'functions/file_prefs.php');
466}
467
468
5aed95be 469
470/**
3464e1f4 471 * DISABLED.
202bcbcc 472 * Remove globalized session data in rg=on setups
086ad092 473 *
3464e1f4 474 * Code can be utilized when session is started, but data is not loaded.
086ad092 475 * We have already loaded configuration and other important vars. Can't
aae60854 476 * clean session globals here, beside, the cleanout of globals at the
477 * top of this file will have removed anything this code would find anyway.
3464e1f4 478if ((bool) @ini_get('register_globals') &&
479 strtolower(ini_get('register_globals'))!='off') {
202bcbcc 480 foreach ($_SESSION as $key => $value) {
481 unset($GLOBALS[$key]);
482 }
483}
3464e1f4 484*/
6a2a6e44 485
826ddd72 486sqsession_register(SM_BASE_URI,'base_uri');
6a2a6e44 487
202bcbcc 488/**
489 * Retrieve the language cookie
490 */
491if (! sqgetGlobalVar('squirrelmail_language',$squirrelmail_language,SQ_COOKIE)) {
492 $squirrelmail_language = '';
493}
494
bf3abdc3 495
202bcbcc 496/**
775a1f52 497 * In some cases, buffering all output allows more complex functionality,
498 * especially for plugins that want to add headers on hooks that are beyond
499 * the point of output having been sent to the browser otherwise.
500 *
501 * Note that we don't turn this on any earlier since we want to allow plugins
502 * to turn it on themselves via a configuration override on the prefs_backend
503 * hook.
504 *
505 */
506if ($buffer_output) ob_start(!empty($buffered_output_handler) ? $buffered_output_handler : NULL);
507
508
509/**
f0d28f44 510 * Do something special for some pages. This is based on the PAGE_NAME constant
9e06a3ea 511 * set at the top of every page.
202bcbcc 512 */
0d56053e 513$set_up_langage_after_template_setup = FALSE;
9e06a3ea 514switch (PAGE_NAME) {
086ad092 515 case 'style':
c4e5f61f 516
2b26084f 517 // need to get the right template set up
28294310 518 //
519 sqGetGlobalVar('templateid', $templateid, SQ_GET);
c4e5f61f 520
2b26084f 521 // sanitize just in case...
28294310 522 //
523 $templateid = preg_replace('/(\.\.\/){1,}/', '', $templateid);
524
525 // make sure given template actually is available
526 //
28294310 527 $found_templateset = false;
528 for ($i = 0; $i < count($aTemplateSet); ++$i) {
529 if ($aTemplateSet[$i]['ID'] == $templateid) {
530 $found_templateset = true;
531 break;
532 }
533 }
c4e5f61f 534
be155e14 535// FIXME: do we need/want to check here for actual (physical) presence of template sets?
28294310 536 // selected template not available, fall back to default template
537 //
538 if (!$found_templateset) {
42b5e8aa 539 $sTemplateID = Template::get_default_template_set();
28294310 540 } else {
541 $sTemplateID = $templateid;
c4e5f61f 542 }
543
2b26084f 544 session_write_close();
c4e5f61f 545 break;
546
f0d28f44 547 case 'mailto':
548 // nothing to do
549 break;
550
202bcbcc 551 case 'redirect':
2e616fa4 552 require(SM_PATH . 'functions/auth.php');
202bcbcc 553 //nobreak;
bf3abdc3 554
202bcbcc 555 case 'login':
556 require(SM_PATH . 'functions/display_messages.php' );
557 require(SM_PATH . 'functions/page_header.php');
558 require(SM_PATH . 'functions/html.php');
42b5e8aa 559
560 // reset template file cache
561 //
562 $sTemplateID = Template::get_default_template_set();
d81572f7 563 Template::cache_template_file_hierarchy($sTemplateID, TRUE);
42b5e8aa 564
1d537493 565 /**
01fd1d1a 566 * Make sure icon variables are setup for the login page.
567 */
568 $icon_theme = $icon_themes[$icon_theme_def]['PATH'];
569 /*
570 * NOTE: The $icon_theme_path var should contain the path to the icon
571 * theme to use. If the admin has disabled icons, or the user has
572 * set the icon theme to "None," no icons will be used.
573 */
574 $icon_theme_path = (!$use_icons || $icon_theme=='none') ? NULL : ($icon_theme == 'template' ? SM_PATH . Template::calculate_template_images_directory($sTemplateID) : $icon_theme);
575
202bcbcc 576 break;
577 default:
578 require(SM_PATH . 'functions/display_messages.php' );
579 require(SM_PATH . 'functions/page_header.php');
580 require(SM_PATH . 'functions/html.php');
202bcbcc 581
582
583 /**
7428254a 584 * Check if we are logged in and does optional referrer check
202bcbcc 585 */
586 require(SM_PATH . 'functions/auth.php');
587
7428254a 588 global $check_referrer, $domain;
589 if (!sqgetGlobalVar('HTTP_REFERER', $referrer, SQ_SERVER)) $referrer = '';
590 if ($check_referrer == '###DOMAIN###') $check_referrer = $domain;
591 if (!empty($check_referrer)) {
592 $ssl_check_referrer = 'https://' . $check_referrer;
593 $check_referrer = 'http://' . $check_referrer;
594 }
595 if (!sqsession_is_registered('user_is_logged_in')
596 || ($check_referrer && !empty($referrer)
597 && strpos(strtolower($referrer), strtolower($check_referrer)) !== 0
598 && strpos(strtolower($referrer), strtolower($ssl_check_referrer)) !== 0)) {
f8eb968d 599
600 // use $message to indicate what logout text the user
601 // will see... if 0, typical "You must be logged in"
602 // if 1, information that the user session was saved
7428254a 603 // and will be resumed after (re)login, if 2, there
604 // seems to have been a XSS or phishing attack (bad
605 // referrer)
f8eb968d 606 //
607 $message = 0;
608
202bcbcc 609 // First we store some information in the new session to prevent
610 // information-loss.
611 //
612 $session_expired_post = $_POST;
f8e68605 613 $session_expired_location = PAGE_NAME;
202bcbcc 614 if (!sqsession_is_registered('session_expired_post')) {
615 sqsession_register($session_expired_post,'session_expired_post');
616 }
617 if (!sqsession_is_registered('session_expired_location')) {
618 sqsession_register($session_expired_location,'session_expired_location');
f8e68605 619 if ($session_expired_location == 'compose')
f8eb968d 620 $message = 1;
202bcbcc 621 }
7428254a 622
623 // was bad referrer the reason we were rejected?
624 //
625 if (sqsession_is_registered('user_is_logged_in')
626 && $check_referrer && !empty($referrer))
627 $message = 2;
628
202bcbcc 629 // signout page will deal with users who aren't logged
630 // in on its own; don't show error here
631 //
9e06a3ea 632 if ( PAGE_NAME == 'signout' ) {
a140422a 633 return;
202bcbcc 634 }
635
8efadc6b 636 /**
637 * Initialize the template object (logout_error uses it)
638 */
8efadc6b 639 /*
086ad092 640 * $sTemplateID is not initialized when a user is not logged in, so we
641 * will use the config file defaults here. If the neccesary variables
d81572f7 642 * are not set, force a default value.
8efadc6b 643 */
d81572f7 644 if (PAGE_NAME == 'squirrelmail_rpc') {
645 $sTemplateID = Template::get_rpc_template_set();
646 } else {
647 $sTemplateID = Template::get_default_template_set();
648 }
28294310 649 $oTemplate = Template::construct_template($sTemplateID);
8efadc6b 650
202bcbcc 651 set_up_language($squirrelmail_language, true);
f8eb968d 652 if (!$message)
653 logout_error( _("You must be logged in to access this page.") );
7428254a 654 else if ($message == 1)
f8eb968d 655 logout_error( _("Your session has expired, but will be resumed after logging in again.") );
7428254a 656 else if ($message == 2)
657 logout_error( _("The current page request appears to have originated from an unrecognized source.") );
202bcbcc 658 exit;
659 }
660
79524620 661 sqgetGlobalVar('authz',$authz,SQ_SESSION);
202bcbcc 662
663 /**
664 * Setting the prefs backend
665 */
666 sqgetGlobalVar('prefs_cache', $prefs_cache, SQ_SESSION );
667 sqgetGlobalVar('prefs_are_cached', $prefs_are_cached, SQ_SESSION );
668
669 if ( !sqsession_is_registered('prefs_are_cached') ||
670 !isset( $prefs_cache) ||
671 !is_array( $prefs_cache)) {
672 $prefs_are_cached = false;
673 $prefs_cache = false; //array();
674 }
675
202bcbcc 676 /**
677 * initializing user settings
678 */
679 require(SM_PATH . 'include/load_prefs.php');
680
202bcbcc 681 /**
682 * We'll need this to later have a noframes version
683 *
684 * Check if the user has a language preference, but no cookie.
685 * Send him a cookie with his language preference, if there is
686 * such discrepancy.
687 */
688 $my_language = getPref($data_dir, $username, 'language');
689 if ($my_language != $squirrelmail_language) {
690 sqsetcookie('squirrelmail_language', $my_language, time()+2592000, $base_uri);
691 }
202bcbcc 692
0d56053e 693 $set_up_langage_after_template_setup = TRUE;
202bcbcc 694
695 $timeZone = getPref($data_dir, $username, 'timezone');
cf039c51 696 global $server_timezone, $server_timezone_offset, $server_timezone_offset_seconds;
697 list($server_timezone, $server_timezone_offset, $server_timezone_offset_seconds)
698 = explode('::', date('T::O::Z'));
202bcbcc 699
700 /* Check to see if we are allowed to set the TZ environment variable.
701 * We are able to do this if ...
702 * safe_mode is disabled OR
703 * safe_mode_allowed_env_vars is empty (you are allowed to set any) OR
704 * safe_mode_allowed_env_vars contains TZ
705 */
706 $tzChangeAllowed = (!ini_get('safe_mode')) ||
707 !strcmp(ini_get('safe_mode_allowed_env_vars'),'') ||
708 preg_match('/^([\w_]+,)*TZ/', ini_get('safe_mode_allowed_env_vars'));
709
710 if ( $timeZone != SMPREF_NONE && ($timeZone != "")
711 && $tzChangeAllowed ) {
712
713 // get time zone key, if strict or custom strict timezones are used
714 if (isset($time_zone_type) &&
715 ($time_zone_type == 1 || $time_zone_type == 3)) {
716 /* load time zone functions */
717 require(SM_PATH . 'include/timezones.php');
718 $realTimeZone = sq_get_tz_key($timeZone);
719 } else {
720 $realTimeZone = $timeZone;
721 }
722
723 // set time zone
724 if ($realTimeZone) {
725 putenv("TZ=".$realTimeZone);
726 }
727 }
867fed37 728
729 /**
730 * php 5.1.0 added time zone functions. Set time zone with them in order
731 * to prevent E_STRICT notices and allow time zone modifications in safe_mode.
732 */
733 if (function_exists('date_default_timezone_set')) {
734 if ($timeZone != SMPREF_NONE && $timeZone != "") {
735 date_default_timezone_set($timeZone);
736 } else {
737 // interface runs on server's time zone. Remove php E_STRICT complains
738 $default_timezone = @date_default_timezone_get();
086ad092 739 date_default_timezone_set($default_timezone);
867fed37 740 }
741 }
202bcbcc 742 break;
743}
744
202bcbcc 745/*
086ad092 746 * $sTemplateID is not initialized when a user is not logged in, so we
747 * will use the config file defaults here. If the neccesary variables
28294310 748 * are not set, force a default value.
086ad092 749 *
750 * If the user is logged in, $sTemplateID will be set in load_prefs.php,
28294310 751 * so we shouldn't change it here.
202bcbcc 752 */
28294310 753if (!isset($sTemplateID)) {
d81572f7 754 if (PAGE_NAME == 'squirrelmail_rpc') {
755 $sTemplateID = Template::get_rpc_template_set();
756 } else {
757 $sTemplateID = Template::get_default_template_set();
758 }
28294310 759 $icon_theme_path = !$use_icons ? NULL : Template::calculate_template_images_directory($sTemplateID);
3aa46abc 760}
be155e14 761
762// template object may have already been constructed in load_prefs.php
763//
764if (empty($oTemplate)) {
765 $oTemplate = Template::construct_template($sTemplateID);
766}
202bcbcc 767
7aae649d 768// We want some variables to always be available to the template
551c7b53 769//
e39d00e9 770$oTemplate->assign('javascript_on',
771 (sqGetGlobalVar('user_is_logged_in', $user_is_logged_in, SQ_SESSION)
772 ? checkForJavascript() : 0));
fe8103c2 773$oTemplate->assign('base_uri', sqm_baseuri());
457e8593 774$always_include = array('sTemplateID', 'icon_theme_path');
7aae649d 775foreach ($always_include as $var) {
776 $oTemplate->assign($var, (isset($$var) ? $$var : NULL));
777}
778
551c7b53 779// A few output elements are used often, so just get them once here
780//
781$nbsp = $oTemplate->fetch('non_breaking_space.tpl');
782$br = $oTemplate->fetch('line_break.tpl');
783
0d56053e 784
785/**
786 * Set up the language.
787 *
788 * This code block corresponds to the *default* block of the switch
789 * statement above, but the language cannot be set up until after the
790 * template is instantiated, so we set $set_up_langage_after_template_setup
791 * above and do the linguistic stuff now.
792 */
793if ($set_up_langage_after_template_setup) {
794 $err=set_up_language(getPref($data_dir, $username, 'language'));
795
796 // Japanese translation used without mbstring support
797 if ($err==2) {
798 $sError = "<p>Your administrator needs to have PHP installed with the multibyte string extension enabled (using configure option --enable-mbstring).</p>\n"
799 . "<p>This system has assumed that you accidently switched to Japanese and has reverted your language preference to English.</p>\n"
800 . "<p>Please refresh this page in order to continue using your webmail.</p>\n";
801 error_box($sError);
802 }
803}
804
805
202bcbcc 806/**
807 * Initialize our custom error handler object
808 */
202bcbcc 809$oErrorHandler = new ErrorHandler($oTemplate,'error_message.tpl');
810
0d56053e 811
202bcbcc 812/**
813 * Activate custom error handling
814 */
815if (version_compare(PHP_VERSION, "4.3.0", ">=")) {
816 $oldErrorHandler = set_error_handler(array($oErrorHandler, 'SquirrelMailErrorhandler'));
817} else {
818 $oldErrorHandler = set_error_handler('SquirrelMailErrorhandler');
819}
820
f0d28f44 821
822// ============================================================================
823// ================= End of Live Code, Beginning of Functions =================
824// ============================================================================
825
826
202bcbcc 827/**
828 * Javascript support detection function
829 * @param boolean $reset recheck javascript support if set to true.
867fed37 830 * @return integer SMPREF_JS_ON or SMPREF_JS_OFF ({@see include/constants.php})
202bcbcc 831 * @since 1.5.1
832 */
202bcbcc 833function checkForJavascript($reset = FALSE) {
834 global $data_dir, $username, $javascript_on, $javascript_setting;
835
836 if ( !$reset && sqGetGlobalVar('javascript_on', $javascript_on, SQ_SESSION) )
837 return $javascript_on;
838
960b7ec2 839 //FIXME: this isn't used anywhere else in this function; can we remove it? why is it here?
e39d00e9 840 $user_is_logged_in = FALSE;
bf3abdc3 841 if ( $reset || !isset($javascript_setting) )
202bcbcc 842 $javascript_setting = getPref($data_dir, $username, 'javascript_setting', SMPREF_JS_AUTODETECT);
843
844 if ( !sqGetGlobalVar('new_js_autodetect_results', $js_autodetect_results) &&
845 !sqGetGlobalVar('js_autodetect_results', $js_autodetect_results) )
846 $js_autodetect_results = SMPREF_JS_OFF;
847
848 if ( $javascript_setting == SMPREF_JS_AUTODETECT )
849 $javascript_on = $js_autodetect_results;
850 else
851 $javascript_on = $javascript_setting;
852
853 sqsession_register($javascript_on, 'javascript_on');
854 return $javascript_on;
855}
856
857function sqm_baseuri() {
858 global $base_uri;
859 return $base_uri;
8e1e2794 860}