Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

include/MVC/SugarApplication.php (6 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*********************************************************************************
3
 * SugarCRM Community Edition is a customer relationship management program developed by
4
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
5
 *
6
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
7
 * Copyright (C) 2011 - 2016 Salesagility Ltd.
8
 *
9
 * This program is free software; you can redistribute it and/or modify it under
10
 * the terms of the GNU Affero General Public License version 3 as published by the
11
 * Free Software Foundation with the addition of the following permission added
12
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
13
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
14
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
15
 *
16
 * This program is distributed in the hope that it will be useful, but WITHOUT
17
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
19
 * details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License along with
22
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
23
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24
 * 02110-1301 USA.
25
 *
26
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
27
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
28
 *
29
 * The interactive user interfaces in modified source and object code versions
30
 * of this program must display Appropriate Legal Notices, as required under
31
 * Section 5 of the GNU Affero General Public License version 3.
32
 *
33
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
34
 * these Appropriate Legal Notices must retain the display of the "Powered by
35
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
36
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
37
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
38
 ********************************************************************************/
39
40
/*
41
 * Created on Mar 21, 2007
42
 *
43
 * To change the template for this generated file go to
44
 * Window - Preferences - PHPeclipse - PHP - Code Templates
45
 */
46
require_once('include/MVC/Controller/ControllerFactory.php');
47
require_once('include/MVC/View/ViewFactory.php');
48
49
/**
50
 * SugarCRM application
51
 * @api
52
 */
53
class SugarApplication
54
{
55
 	var $controller = null;
56
 	var $headerDisplayed = false;
57
 	var $default_module = 'Home';
58
 	var $default_action = 'index';
59
60 19
 	public function __construct()
61 19
 	{}
62
63
    /**
64
     * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead
65
     */
66
    public function SugarApplication(){
67
        $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code';
68
        if(isset($GLOBALS['log'])) {
69
            $GLOBALS['log']->deprecated($deprecatedMessage);
70
        }
71
        else {
72
            trigger_error($deprecatedMessage, E_USER_DEPRECATED);
73
        }
74
        self::__construct();
75
    }
76
77
78
 	/**
0 ignored issues
show
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
79
 	 * Perform execution of the application. This method is called from index2.php
80
 	 */
81 1
	function execute(){
82 1
		global $sugar_config;
83 1
		if(!empty($sugar_config['default_module']))
84 1
			$this->default_module = $sugar_config['default_module'];
85 1
		$module = $this->default_module;
86 1
		if(!empty($_REQUEST['module']))$module = $_REQUEST['module'];
87 1
		insert_charset_header();
88
		$this->setupPrint();
89
		$this->controller = ControllerFactory::getController($module);
90
        // If the entry point is defined to not need auth, then don't authenticate.
91
		if( empty($_REQUEST['entryPoint'])
92
                || $this->controller->checkEntryPointRequiresAuth($_REQUEST['entryPoint']) ){
93
            $this->loadUser();
94
            $this->ACLFilter();
95
            $this->preProcess();
96
            $this->controller->preProcess();
97
            $this->checkHTTPReferer();
98
        }
99
100
        SugarThemeRegistry::buildRegistry();
101
        $this->loadLanguages();
102
		$this->loadDisplaySettings();
103
		$this->loadGlobals();
104
		$this->setupResourceManagement($module);
105
		$this->controller->execute();
106
		sugar_cleanup();
107
	}
108
109
	/**
110
	 * Load the authenticated user. If there is not an authenticated user then redirect to login screen.
111
	 */
112
	function loadUser(){
113
		global $authController, $sugar_config;
114
		// Double check the server's unique key is in the session.  Make sure this is not an attempt to hijack a session
115
		$user_unique_key = (isset($_SESSION['unique_key'])) ? $_SESSION['unique_key'] : '';
116
		$server_unique_key = (isset($sugar_config['unique_key'])) ? $sugar_config['unique_key'] : '';
117
		$allowed_actions = (!empty($this->controller->allowed_actions)) ? $this->controller->allowed_actions : $allowed_actions = array('Authenticate', 'Login', 'LoggedOut');
118
119
        $authController = new AuthenticationController();
120
121
		if(($user_unique_key != $server_unique_key) && (!in_array($this->controller->action, $allowed_actions)) &&
122
		   (!isset($_SESSION['login_error'])))
123
		   {
124
			session_destroy();
125
126
			if(!empty($this->controller->action)){
127
			    if(strtolower($this->controller->action) == 'delete')
128
			        $this->controller->action = 'DetailView';
129
			    elseif(strtolower($this->controller->action) == 'save')
130
			        $this->controller->action = 'EditView';
131
                elseif(strtolower($this->controller->action) == 'quickcreate') {
132
                    $this->controller->action = 'index';
133
                    $this->controller->module = 'home';
134
                }
135
			    elseif(isset($_REQUEST['massupdate'])|| isset($_GET['massupdate']) || isset($_POST['massupdate']))
136
			        $this->controller->action = 'index';
137
			    elseif($this->isModifyAction())
138
			        $this->controller->action = 'index';
139
                elseif ($this->controller->action == $this->default_action
140
                    && $this->controller->module == $this->default_module) {
141
                    $this->controller->action = '';
142
                    $this->controller->module = '';
143
                }
144
				elseif(strtolower($this->controller->module) == 'alerts' && strtolower($this->controller->action) == 'get') {
145
					echo 'lost session';
146
					exit();
147
				}
148
			}
149
150
            $authController->authController->redirectToLogin($this);
151
		}
152
153
		$GLOBALS['current_user'] = new User();
154
		if(isset($_SESSION['authenticated_user_id'])){
155
			// set in modules/Users/Authenticate.php
156
			if(!$authController->sessionAuthenticate()){
157
				 // if the object we get back is null for some reason, this will break - like user prefs are corrupted
158
				$GLOBALS['log']->fatal('User retrieval for ID: ('.$_SESSION['authenticated_user_id'].') does not exist in database or retrieval failed catastrophically.  Calling session_destroy() and sending user to Login page.');
159
				session_destroy();
160
				SugarApplication::redirect('index.php?action=Login&module=Users');
161
				die();
162
			}//fi
163
		}elseif(!($this->controller->module == 'Users' && in_array($this->controller->action, $allowed_actions))){
164
			session_destroy();
165
			SugarApplication::redirect('index.php?action=Login&module=Users');
166
			die();
167
		}
168
		$GLOBALS['log']->debug('Current user is: '.$GLOBALS['current_user']->user_name);
169
170
		//set cookies
171
		if(isset($_SESSION['authenticated_user_id'])){
172
			$GLOBALS['log']->debug("setting cookie ck_login_id_20 to ".$_SESSION['authenticated_user_id']);
173
			self::setCookie('ck_login_id_20', $_SESSION['authenticated_user_id'], time() + 86400 * 90);
174
		}
175
		if(isset($_SESSION['authenticated_user_theme'])){
176
			$GLOBALS['log']->debug("setting cookie ck_login_theme_20 to ".$_SESSION['authenticated_user_theme']);
177
			self::setCookie('ck_login_theme_20', $_SESSION['authenticated_user_theme'], time() + 86400 * 90);
178
		}
179
		if(isset($_SESSION['authenticated_user_theme_color'])){
180
			$GLOBALS['log']->debug("setting cookie ck_login_theme_color_20 to ".$_SESSION['authenticated_user_theme_color']);
181
			self::setCookie('ck_login_theme_color_20', $_SESSION['authenticated_user_theme_color'], time() + 86400 * 90);
182
		}
183
		if(isset($_SESSION['authenticated_user_theme_font'])){
184
			$GLOBALS['log']->debug("setting cookie ck_login_theme_font_20 to ".$_SESSION['authenticated_user_theme_font']);
185
			self::setCookie('ck_login_theme_font_20', $_SESSION['authenticated_user_theme_font'], time() + 86400 * 90);
186
		}
187
		if(isset($_SESSION['authenticated_user_language'])){
188
			$GLOBALS['log']->debug("setting cookie ck_login_language_20 to ".$_SESSION['authenticated_user_language']);
189
			self::setCookie('ck_login_language_20', $_SESSION['authenticated_user_language'], time() + 86400 * 90);
190
		}
191
		//check if user can access
192
193
	}
194
195 1
	function ACLFilter(){
196 1
		ACLController :: filterModuleList($GLOBALS['moduleList']);
197 1
	}
198
199
	/**
200
	 * setupResourceManagement
201
	 * This function initialize the ResourceManager and calls the setup method
202
	 * on the ResourceManager instance.
203
	 *
204
	 */
205 1
	function setupResourceManagement($module) {
206 1
		require_once('include/resource/ResourceManager.php');
207 1
		$resourceManager = ResourceManager::getInstance();
208 1
		$resourceManager->setup($module);
209 1
	}
210
211 1
	function setupPrint() {
212 1
		$GLOBALS['request_string'] = '';
213
214
		// merge _GET and _POST, but keep the results local
215
		// this handles the issues where values come in one way or the other
216
		// without affecting the main super globals
217 1
		$merged = array_merge($_GET, $_POST);
218 1
		foreach ($merged as $key => $val)
219
		{
220
		   if(is_array($val))
221
		   {
222
		       foreach ($val as $k => $v)
223
		       {
224
                           //If an array, then skip the urlencoding. This should be handled with stringify instead.
225
                           if(is_array($v))
226
                                continue;
227
228
                           $GLOBALS['request_string'] .= urlencode($key).'['.$k.']='.urlencode($v).'&';
229
		       }
230
		   }
231
		   else
232
		   {
233
		       $GLOBALS['request_string'] .= urlencode($key).'='.urlencode($val).'&';
234
		   }
235
		}
236 1
		$GLOBALS['request_string'] .= 'print=true';
237 1
	}
238
239 1
	function preProcess(){
240 1
	    $config = new Administration;
241 1
	    $config->retrieveSettings();
242 1
		if(!empty($_SESSION['authenticated_user_id'])){
243
			if(isset($_SESSION['hasExpiredPassword']) && $_SESSION['hasExpiredPassword'] == '1'){
244
				if( $this->controller->action!= 'Save' && $this->controller->action != 'Logout') {
245
	                $this->controller->module = 'Users';
246
	                $this->controller->action = 'ChangePassword';
247
	                $record = $GLOBALS['current_user']->id;
248
	             }else{
249
					$this->handleOfflineClient();
250
				 }
251
			}else{
252
				$ut = $GLOBALS['current_user']->getPreference('ut');
253
			    if(empty($ut)
254
			            && $this->controller->action != 'AdminWizard'
255
			            && $this->controller->action != 'EmailUIAjax'
256
			            && $this->controller->action != 'Wizard'
257
			            && $this->controller->action != 'SaveAdminWizard'
258
			            && $this->controller->action != 'SaveUserWizard'
259
			            && $this->controller->action != 'SaveTimezone'
260
			            && $this->controller->action != 'Logout') {
261
					$this->controller->module = 'Users';
262
					$this->controller->action = 'SetTimezone';
263
					$record = $GLOBALS['current_user']->id;
264
				}else{
265
					if($this->controller->action != 'AdminWizard'
266
			            && $this->controller->action != 'EmailUIAjax'
267
			            && $this->controller->action != 'Wizard'
268
			            && $this->controller->action != 'SaveAdminWizard'
269
			            && $this->controller->action != 'SaveUserWizard'){
270
							$this->handleOfflineClient();
271
			            }
272
				}
273
			}
274
		}
275 1
		$this->handleAccessControl();
276 1
	}
277
278 1
	function handleOfflineClient(){
279 1
		if(isset($GLOBALS['sugar_config']['disc_client']) && $GLOBALS['sugar_config']['disc_client']){
280
			if(isset($_REQUEST['action']) && $_REQUEST['action'] != 'SaveTimezone'){
281
				if (!file_exists('modules/Sync/file_config.php')){
282
					if($_REQUEST['action'] != 'InitialSync' && $_REQUEST['action'] != 'Logout' &&
283
					   ($_REQUEST['action'] != 'Popup' && $_REQUEST['module'] != 'Sync')){
284
						//echo $_REQUEST['action'];
285
						//die();
286
					   		$this->controller->module = 'Sync';
287
							$this->controller->action = 'InitialSync';
288
						}
289
		    	}else{
290
		    		require_once ('modules/Sync/file_config.php');
291
		    		if(isset($file_sync_info['is_first_sync']) && $file_sync_info['is_first_sync']){
0 ignored issues
show
The variable $file_sync_info seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
292
		    			if($_REQUEST['action'] != 'InitialSync' && $_REQUEST['action'] != 'Logout' &&
293
		    			   ( $_REQUEST['action'] != 'Popup' && $_REQUEST['module'] != 'Sync')){
294
								$this->controller->module = 'Sync';
295
								$this->controller->action = 'InitialSync';
296
						}
297
		    		}
298
		    	}
299
			}
300
			global $moduleList, $sugar_config, $sync_modules;
301
			require_once('modules/Sync/SyncController.php');
302
			$GLOBALS['current_user']->is_admin = '0'; //No admins for disc client
303
		}
304 1
	}
305
306
	/**
307
	 * Handles everything related to authorization.
308
	 */
309 2
	function handleAccessControl(){
310 2
		if($GLOBALS['current_user']->isDeveloperForAnyModule())
311
			return;
312 2
	    if(!empty($_REQUEST['action']) && $_REQUEST['action']=="RetrieveEmail")
313
            return;
314 2
		if(!is_admin($GLOBALS['current_user']) && !empty($GLOBALS['adminOnlyList'][$this->controller->module])
315 2
		&& !empty($GLOBALS['adminOnlyList'][$this->controller->module]['all'])
316 2
		&& (empty($GLOBALS['adminOnlyList'][$this->controller->module][$this->controller->action]) || $GLOBALS['adminOnlyList'][$this->controller->module][$this->controller->action] != 'allow')) {
317
			$this->controller->hasAccess = false;
318
			return;
319
		}
320
321
		// Bug 20916 - Special case for check ACL access rights for Subpanel QuickCreates
322 2
		if(isset($_POST['action']) && $_POST['action'] == 'SubpanelCreates') {
323
            $actual_module = $_POST['target_module'];
324
            if(!empty($GLOBALS['modListHeader']) && !in_array($actual_module,$GLOBALS['modListHeader'])) {
325
                $this->controller->hasAccess = false;
326
            }
327
            return;
328
        }
329
330
331 2
		if(!empty($GLOBALS['current_user']) && empty($GLOBALS['modListHeader']))
332 2
			$GLOBALS['modListHeader'] = query_module_access_list($GLOBALS['current_user']);
333
334 2
		if(in_array($this->controller->module, $GLOBALS['modInvisList']) &&
335
			((in_array('Activities', $GLOBALS['moduleList'])              &&
336
			in_array('Calendar',$GLOBALS['moduleList']))                 &&
337 2
			in_array($this->controller->module, $GLOBALS['modInvisListActivities']))
338
			){
339
				$this->controller->hasAccess = false;
340
				return;
341
		}
342 2
	}
343
344
	/**
345
	 * Load only bare minimum of language that can be done before user init and MVC stuff
346
	 */
347 1
	static function preLoadLanguages()
348
	{
349 1
		if(!empty($_SESSION['authenticated_user_language'])) {
350
			$GLOBALS['current_language'] = $_SESSION['authenticated_user_language'];
351
		}
352
		else {
353 1
			$GLOBALS['current_language'] = $GLOBALS['sugar_config']['default_language'];
354
		}
355 1
		$GLOBALS['log']->debug('current_language is: '.$GLOBALS['current_language']);
356
		//set module and application string arrays based upon selected language
357 1
		$GLOBALS['app_strings'] = return_application_language($GLOBALS['current_language']);
358 1
	}
359
360
	/**
361
	 * Load application wide languages as well as module based languages so they are accessible
362
	 * from the module.
363
	 */
364 1
	function loadLanguages(){
365 1
		if(!empty($_SESSION['authenticated_user_language'])) {
366
			$GLOBALS['current_language'] = $_SESSION['authenticated_user_language'];
367
		}
368
		else {
369 1
			$GLOBALS['current_language'] = $GLOBALS['sugar_config']['default_language'];
370
		}
371 1
		$GLOBALS['log']->debug('current_language is: '.$GLOBALS['current_language']);
372
		//set module and application string arrays based upon selected language
373 1
		$GLOBALS['app_strings'] = return_application_language($GLOBALS['current_language']);
374 1
		if(empty($GLOBALS['current_user']->id))$GLOBALS['app_strings']['NTC_WELCOME'] = '';
375 1
		if(!empty($GLOBALS['system_config']->settings['system_name']))$GLOBALS['app_strings']['LBL_BROWSER_TITLE'] = $GLOBALS['system_config']->settings['system_name'];
376 1
		$GLOBALS['app_list_strings'] = return_app_list_strings_language($GLOBALS['current_language']);
377 1
		$GLOBALS['mod_strings'] = return_module_language($GLOBALS['current_language'], $this->controller->module);
378 1
	}
379
	/**
380
	* checkDatabaseVersion
381
	* Check the db version sugar_version.php and compare to what the version is stored in the config table.
382
	* Ensure that both are the same.
383
	*/
384 1
 	function checkDatabaseVersion($dieOnFailure = true)
385
 	{
386 1
 	    $row_count = sugar_cache_retrieve('checkDatabaseVersion_row_count');
387 1
 	    if ( empty($row_count) )
388
 	    {
389
            $version_query = "SELECT count(*) as the_count FROM config WHERE category='info' AND name='sugar_version' AND ".
390 1
            $GLOBALS['db']->convert('value', 'text2char')." = ".$GLOBALS['db']->quoted($GLOBALS['sugar_db_version']);
391
392 1
            $result = $GLOBALS['db']->query($version_query);
393 1
            $row = $GLOBALS['db']->fetchByAssoc($result);
394 1
            $row_count = $row['the_count'];
395 1
            sugar_cache_put('checkDatabaseVersion_row_count', $row_count);
396
        }
397
398 1
		if ($row_count == 0 && empty($GLOBALS['sugar_config']['disc_client']))
399
		{
400 1
			if ( $dieOnFailure )
401
			{
402
				$replacementStrings = array(
403
					0 => $GLOBALS['sugar_version'],
404
					1 => $GLOBALS['sugar_db_version'],
405
				);
406
				sugar_die(string_format($GLOBALS['app_strings']['ERR_DB_VERSION'], $replacementStrings));
407
			}
408
			else
409
			{
410 1
			    return false;
411
			}
412
		}
413
414
		return true;
415
	}
416
417
	/**
418
	 * Load the themes/images.
419
	 */
420 1
	function loadDisplaySettings()
421
    {
422 1
        global $theme;
423
424
        // load the user's default theme
425 1
        $theme = $GLOBALS['current_user']->getPreference('user_theme');
426
427 1
        if (is_null($theme)) {
428 1
            $theme = $GLOBALS['sugar_config']['default_theme'];
429 1
            if(!empty($_SESSION['authenticated_user_theme'])){
430
                $theme = $_SESSION['authenticated_user_theme'];
431
            }
432 1
            else if(!empty($_COOKIE['sugar_user_theme'])){
433
                $theme = $_COOKIE['sugar_user_theme'];
434
            }
435
436 1
			if(isset($_SESSION['authenticated_user_theme']) && $_SESSION['authenticated_user_theme'] != '') {
437
				$_SESSION['theme_changed'] = false;
438
			}
439
		}
440
441 1
        $available_themes = SugarThemeRegistry::availableThemes();
442 1
        if(!isset($available_themes[$theme])){
443
            $theme = $GLOBALS['sugar_config']['default_theme'];
444
        }
445
446 1
        if(!is_null($theme) && !headers_sent())
447
        {
448
            setcookie('sugar_user_theme', $theme, time() + 31536000, null, null, false, true); // expires in a year
449
        }
450
451 1
        SugarThemeRegistry::set($theme);
452 1
        require_once('include/utils/layout_utils.php');
453 1
        $GLOBALS['image_path'] = SugarThemeRegistry::current()->getImagePath().'/';
454 1
        if ( defined('TEMPLATE_URL') )
455
            $GLOBALS['image_path'] = TEMPLATE_URL . '/'. $GLOBALS['image_path'];
456
457 1
        if ( isset($GLOBALS['current_user']) ) {
458 1
            $GLOBALS['gridline'] = (int) ($GLOBALS['current_user']->getPreference('gridline') == 'on');
0 ignored issues
show
The method getPreference cannot be called on $GLOBALS['current_user'] (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
459 1
            $GLOBALS['current_user']->setPreference('user_theme', $theme, 0, 'global');
460
        }
461 1
	}
462
463 1
	function loadLicense(){
464 1
		loadLicense();
465 1
		global $user_unique_key, $server_unique_key;
466 1
		$user_unique_key = (isset($_SESSION['unique_key'])) ? $_SESSION['unique_key'] : '';
467 1
		$server_unique_key = (isset($sugar_config['unique_key'])) ? $sugar_config['unique_key'] : '';
0 ignored issues
show
The variable $sugar_config seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
468 1
	}
469
470 1
	function loadGlobals(){
471 1
		global $currentModule;
472 1
		$currentModule = $this->controller->module;
473 1
		if($this->controller->module == $this->default_module){
474 1
			$_REQUEST['module'] = $this->controller->module;
475 1
			if(empty($_REQUEST['action']))
476 1
			$_REQUEST['action'] = $this->default_action;
477
		}
478 1
	}
479
480
	/**
481
	 * Actions that modify data in this controller's instance and thus require referrers
482
	 * @var array
483
	 */
484
	protected $modifyActions = array();
485
	/**
486
	 * Actions that always modify data and thus require referrers
487
	 * save* and delete* hardcoded as modified
488
	 * @var array
489
	 */
490
	private $globalModifyActions = array(
491
		'massupdate', 'configuredashlet', 'import', 'importvcardsave', 'inlinefieldsave',
492
	    'wlsave', 'quicksave'
493
	);
494
495
	/**
496
	 * Modules that modify data and thus require referrers for all actions
497
	 */
498
	private $modifyModules = array(
499
		'Administration' => true,
500
		'UpgradeWizard' => true,
501
		'Configurator' => true,
502
		'Studio' => true,
503
		'ModuleBuilder' => true,
504
		'Emails' => true,
505
	    'DCETemplates' => true,
506
		'DCEInstances' => true,
507
		'DCEActions' => true,
508
		'Trackers' => array('trackersettings'),
509
	    'SugarFavorites' => array('tag'),
510
	    'Import' => array('last', 'undo'),
511
	    'Users' => array('changepassword', "generatepassword"),
512
	);
513
514
	protected function isModifyAction()
515
	{
516
	    $action = strtolower($this->controller->action);
517
	    if(substr($action, 0, 4) == "save" || substr($action, 0, 6) == "delete") {
518
	        return true;
519
	    }
520
	    if(isset($this->modifyModules[$this->controller->module])) {
521
	        if($this->modifyModules[$this->controller->module] === true) {
522
	            return true;
523
	        }
524
	        if(in_array($this->controller->action, $this->modifyModules[$this->controller->module])) {
525
	            return true;
526
527
	        }
528
	    }
529
	    if(in_array($this->controller->action, $this->globalModifyActions)) {
530
            return true;
531
        }
532
	    if(in_array($this->controller->action, $this->modifyActions)) {
533
            return true;
534
        }
535
        return false;
536
	}
537
538
    /**
539
     * The list of the actions excepted from referer checks by default
540
     * @var array
541
     */
542
	protected $whiteListActions = array('index', 'ListView', 'DetailView', 'EditView', 'oauth', 'authorize', 'Authenticate', 'Login', 'SupportPortal');
543
544
	/**
545
	 *
546
	 * Checks a request to ensure the request is coming from a valid source or it is for one of the white listed actions
547
	 */
548
	protected function checkHTTPReferer($dieIfInvalid = true)
549
	{
550
		global $sugar_config;
551
		if(!empty($sugar_config['http_referer']['actions'])) {
552
		    $this->whiteListActions = array_merge($sugar_config['http_referer']['actions'], $this->whiteListActions);
553
		}
554
555
		$strong = empty($sugar_config['http_referer']['weak']);
556
557
		// Bug 39691 - Make sure localhost and 127.0.0.1 are always valid HTTP referers
558
		$whiteListReferers = array('127.0.0.1','localhost');
559
		if(!empty($_SERVER['SERVER_ADDR']))$whiteListReferers[]  = $_SERVER['SERVER_ADDR'];
560
		if ( !empty($sugar_config['http_referer']['list']) ) {
561
			$whiteListReferers = array_merge($whiteListReferers,$sugar_config['http_referer']['list']);
562
		}
563
564
		if($strong && empty($_SERVER['HTTP_REFERER']) && !in_array($this->controller->action, $this->whiteListActions ) && $this->isModifyAction()) {
565
		    $http_host = explode(':', $_SERVER['HTTP_HOST']);
566
            $whiteListActions = $this->whiteListActions;
567
			$whiteListActions[] = $this->controller->action;
568
			$whiteListString = "'" . implode("', '", $whiteListActions) . "'";
569
            if ( $dieIfInvalid ) {
570
                header("Cache-Control: no-cache, must-revalidate");
571
                $ss = new Sugar_Smarty;
572
                $ss->assign('host', $http_host[0]);
573
                $ss->assign('action',$this->controller->action);
574
                $ss->assign('whiteListString',$whiteListString);
575
                $ss->display('include/MVC/View/tpls/xsrf.tpl');
576
                sugar_cleanup(true);
577
            }
578
            return false;
579
		} else
580
		if(!empty($_SERVER['HTTP_REFERER']) && !empty($_SERVER['SERVER_NAME'])){
581
			$http_ref = parse_url($_SERVER['HTTP_REFERER']);
582
			if($http_ref['host'] !== $_SERVER['SERVER_NAME']  && !in_array($this->controller->action, $this->whiteListActions) &&
583
584
				(empty($whiteListReferers) || !in_array($http_ref['host'], $whiteListReferers))){
585
                if ( $dieIfInvalid ) {
586
                    header("Cache-Control: no-cache, must-revalidate");
587
                    $whiteListActions = $this->whiteListActions;
588
                    $whiteListActions[] = $this->controller->action;
589
                    $whiteListString = "'" . implode("', '", $whiteListActions) . "'";
590
591
                    $ss = new Sugar_Smarty;
592
                    $ss->assign('host',$http_ref['host']);
593
                    $ss->assign('action',$this->controller->action);
594
                    $ss->assign('whiteListString',$whiteListString);
595
                    $ss->display('include/MVC/View/tpls/xsrf.tpl');
596
                    sugar_cleanup(true);
597
                }
598
                return false;
599
			}
600
		}
601
         return true;
602
	}
603 1
	function startSession()
604
	{
605 1
	    $sessionIdCookie = isset($_COOKIE['PHPSESSID']) ? $_COOKIE['PHPSESSID'] : null;
606 1
	    if(isset($_REQUEST['MSID'])) {
607
			session_id($_REQUEST['MSID']);
608
			session_start();
609
            if(!isset($_SESSION['user_id'])){
610
				if(isset($_COOKIE['PHPSESSID'])){
611
	       			self::setCookie('PHPSESSID', '', time()-42000, '/');
612
        		}
613
	    		sugar_cleanup(false);
614
	    		session_destroy();
615
	    		exit('Not a valid entry method');
616
			}
617
		}else{
618 1
			if(can_start_session()){
619 1
				session_start();
620
			}
621
		}
622
623
        //set the default module to either Home or specified default
624 1
        $default_module = !empty($GLOBALS['sugar_config']['default_module'])?  $GLOBALS['sugar_config']['default_module'] : 'Home';
625
626
        //set session expired message if login module and action are set to a non login default
627
        //AND session id in cookie is set but super global session array is empty
628 1
		if ( isset($_REQUEST['login_module']) && isset($_REQUEST['login_action'])
629 1
		        && !($_REQUEST['login_module'] == $default_module && $_REQUEST['login_action'] == 'index') ) {
630
            if ( !is_null($sessionIdCookie) && empty($_SESSION) ) {
631
                self::setCookie('loginErrorMessage', 'LBL_SESSION_EXPIRED', time()+30, '/');
632
            }
633
        }
634
635
636 1
        LogicHook::initialize()->call_custom_logic('', 'after_session_start');
637 1
	}
638
639
640
641
642 1
	function endSession(){
643 1
		session_destroy();
644 1
	}
645
 	/**
0 ignored issues
show
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
646
	 * Redirect to another URL
647
	 *
648
	 * @access	public
649
	 * @param	string	$url	The URL to redirect to
650
	 */
651
 	static function redirect(
652
 	    $url
653
 	    )
654
	{
655
		/*
656
		 * If the headers have been sent, then we cannot send an additional location header
657
		 * so we will output a javascript redirect statement.
658
		 */
659
		if (!empty($_REQUEST['ajax_load']))
660
        {
661
            ob_get_clean();
662
            $ajax_ret = array(
663
                 'content' => "<script>SUGAR.ajaxUI.loadContent('$url');</script>\n",
664
                 'menu' => array(
665
                     'module' => $_REQUEST['module'],
666
                     'label' => translate($_REQUEST['module']),
667
                 ),
668
            );
669
            $json = getJSONobj();
670
            echo $json->encode($ajax_ret);
671
        } else {
672
            if (headers_sent()) {
673
                echo "<script>SUGAR.ajaxUI.loadContent('$url');</script>\n";
674
            } else {
675
                //@ob_end_clean(); // clear output buffer
676
                session_write_close();
677
                header( 'HTTP/1.1 301 Moved Permanently' );
678
                header( "Location: ". $url );
679
            }
680
        }
681
		exit();
682
	}
683
684
    /**
685
	 * Redirect to another URL
686
	 *
687
	 * @access	public
688
	 * @param	string	$url	The URL to redirect to
0 ignored issues
show
There is no parameter named $url. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
689
	 */
690 1
 	public static function appendErrorMessage($error_message)
691
	{
692 1
        if (empty($_SESSION['user_error_message']) || !is_array($_SESSION['user_error_message'])){
693 1
            $_SESSION['user_error_message'] = array();
694
        }
695 1
		$_SESSION['user_error_message'][] = $error_message;
696 1
	}
697
698 3
    public static function getErrorMessages()
699
	{
700 3
		if (isset($_SESSION['user_error_message']) && is_array($_SESSION['user_error_message']) ) {
701
            $msgs = $_SESSION['user_error_message'];
702
            unset($_SESSION['user_error_message']);
703
            return $msgs;
704
        }else{
705 3
            return array();
706
        }
707
	}
708
709
	/**
710
	 * Wrapper for the PHP setcookie() function, to handle cases where headers have
711
	 * already been sent
712
	 */
713 1
	public static function setCookie(
714
	    $name,
715
	    $value,
716
	    $expire = 0,
717
	    $path = '/',
718
	    $domain = null,
719
	    $secure = false,
720
	    $httponly = true
721
	    )
722
	{
723 1
	    if ( is_null($domain) )
724 1
	        if ( isset($_SERVER["HTTP_HOST"]) )
725
	            $domain = $_SERVER["HTTP_HOST"];
726
	        else
727 1
	            $domain = 'localhost';
728
729 1
	    if (!headers_sent())
730
	        setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
731
732 1
	    $_COOKIE[$name] = $value;
733 1
	}
734
735
	protected $redirectVars = array('module', 'action', 'record', 'token', 'oauth_token', 'mobile');
736
737
	/**
738
	 * Create string to attach to login URL with vars to preserve post-login
739
	 * @return string URL part with login vars
740
	 */
741 1
	public function createLoginVars()
742
	{
743 1
	    $ret = array();
744 1
        foreach($this->redirectVars as $var) {
745 1
            if(!empty($this->controller->$var)) {
746
                $ret["login_".$var] = $this->controller->$var;
747
                continue;
748
            }
749 1
            if(!empty($_REQUEST[$var])) {
750 1
                $ret["login_".$var] = $_REQUEST[$var];
751
            }
752
        }
753 1
        if(isset($_REQUEST['mobile'])) {
754
            $ret['mobile'] = $_REQUEST['mobile'];
755
        }
756 1
        if(isset($_REQUEST['no_saml'])) {
757
            $ret['no_saml'] = $_REQUEST['no_saml'];
758
        }
759 1
        if(empty($ret)) return '';
760
        return "&".http_build_query($ret);
761
	}
762
763
	/**
764
	 * Get the list of vars passed with login form
765
	 * @param bool $add_empty Add empty vars to the result?
766
	 * @return array List of vars passed with login
767
	 */
768 1
	public function getLoginVars($add_empty = true)
769
	{
770 1
	    $ret = array();
771 1
        foreach($this->redirectVars as $var) {
772 1
            if(!empty($_REQUEST['login_'.$var]) || $add_empty) {
773 1
                $ret["login_".$var] = isset($_REQUEST['login_'.$var])?$_REQUEST['login_'.$var]:'';
774
            }
775
        }
776 1
	    return $ret;
777
	}
778
779
	/**
780
	 * Get URL to redirect after the login
781
	 * @return string the URL to redirect to
782
	 */
783 1
	public function getLoginRedirect()
784
	{
785 1
        $vars = array();
786 1
        foreach($this->redirectVars as $var) {
787 1
            if(!empty($_REQUEST['login_'.$var])) $vars[$var] = $_REQUEST['login_'.$var];
788
        }
789 1
        if(isset($_REQUEST['mobile'])) {
790
            $vars['mobile'] = $_REQUEST['mobile'];
791
        }
792
793 1
        if(isset($_REQUEST['mobile']))
794
        {
795
         	      $vars['mobile'] = $_REQUEST['mobile'];
796
        }
797 1
        if(empty($vars)) {
798 1
            return "index.php?module=Home&action=index";
799
        } else {
800
            return "index.php?".http_build_query($vars);
801
        }
802
	}
803
}
804