Project

General

Profile

Download (12 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * authgui.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2003-2006 Manuel Kasper <mk@neon1.net>
7
 * Copyright (c) 2005-2006 Bill Marquette <bill.marquette@gmail.com>
8
 * Copyright (c) 2006 Paul Taylor <paultaylor@winn-dixie.com>
9
 * Copyright (c) 2004-2018 Rubicon Communications, LLC (Netgate)
10
 * All rights reserved.
11
 *
12
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15
 *
16
 * http://www.apache.org/licenses/LICENSE-2.0
17
 *
18
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23
 */
24

    
25
include_once("auth.inc");
26
include_once("priv.inc");
27
if (!function_exists('platform_booting')) {
28
	require_once('globals.inc');
29
}
30
require_once('pfsense-utils.inc');
31

    
32
/* Authenticate user - exit if failed */
33
if (!session_auth()) {
34
	display_login_form();
35
	exit;
36
}
37

    
38
phpsession_begin();
39

    
40
/*
41
 * Once here, the user has authenticated with the web server.
42
 * We give them access only to the appropriate pages based on
43
 * the user or group privileges.
44
 */
45
$allowedpages = getAllowedPages($_SESSION['Username'], $_SESSION['user_radius_attributes']);
46

    
47
/*
48
 * Get user-based preference settings so they can be easily referenced.
49
 */
50
$user_settings = get_user_settings($_SESSION['Username']);
51

    
52
/*
53
 * redirect to first allowed page if requesting a wrong url
54
 */
55

    
56
/* Fix this up otherwise the privilege check will fail. See Redmine #5909. */
57
if ($_SERVER['REQUEST_URI'] == "/") {
58
	$_SERVER['REQUEST_URI'] = "/index.php";
59
}
60

    
61
if (!isAllowedPage($_SERVER['REQUEST_URI'])) {
62
	if (count($allowedpages) > 0) {
63
		$page = str_replace('*', '', $allowedpages[0]);
64
		$_SESSION['Post_Login'] = true;
65
		require_once("functions.inc");
66
		pfSenseHeader("/{$page}");
67

    
68
		$username = empty($_SESSION["Username"]) ? "(system)" : $_SESSION['Username'];
69
		if (!empty($_SERVER['REMOTE_ADDR'])) {
70
			$username .= '@' . $_SERVER['REMOTE_ADDR'];
71
		}
72
		log_error("{$username} attempted to access {$_SERVER['SCRIPT_NAME']} but does not have access to that page. Redirecting to {$page}.");
73

    
74
		exit;
75
	} else {
76
		// add this so they don't get stuck on the logout page when they have no permissions.
77
		$_SESSION["Logged_In"] = false;
78
		display_error_form("201", gettext("No page assigned to this user! Click here to logout."));
79

    
80
		exit;
81
	}
82
} else {
83
	$_SESSION['Post_Login'] = true;
84
}
85

    
86
/*
87
 * redirect browsers post-login to avoid pages
88
 * taking action in response to a POST request
89
 */
90
if (!$_SESSION['Post_Login']) {
91
	$_SESSION['Post_Login'] = true;
92
	require_once("functions.inc");
93
	pfSenseHeader($_SERVER['REQUEST_URI']);
94
	exit;
95
}
96

    
97
/*
98
 * Close session data to allow other scripts from same host to come in.
99
 * A session can be reactivated from calling phpsession_begin again
100
 */
101
phpsession_end(true);
102

    
103
/*
104
 * determine if the user is allowed access to the requested page
105
 */
106
function display_error_form($http_code, $desc) {
107
	global $config, $user_settings, $g;
108

    
109
	if (isAjax()) {
110
		printf(gettext('Error: %1$s Description: %2$s'), $http_code, $desc);
111
		return;
112
	}
113

    
114
	$logincssfile = "#770101";
115
?>
116

    
117
<!DOCTYPE html>
118
<html lang="en">
119
	<head>
120
		<meta name="viewport" content="width=device-width, initial-scale=1">
121
	    <link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css" type="text/css">
122
	    <link rel="stylesheet" href="/css/login.css?v=<?=filemtime('/usr/local/www/css/login.css')?>" type="text/css">
123
		<title><?=gettext("Error"); ?></title>
124
	</head>
125

    
126
	<body id="error" >
127
		<div id="total">
128
			<header>
129
				<div id="headerrow">
130
					<div class="row">
131
						<div class="col-sm-4">
132
							<div id="logodiv" style="text-align:center" class="nowarning">
133
								<?php include("/usr/local/www/logo.svg"); ?>
134
							</div>
135
						</div>
136
						<div class="col-sm-8 nowarning msgbox text-center">
137
							<span id="hostspan">
138
							</span>
139
						</div>
140
					</div>
141
				</div>
142
			</header>
143

    
144
			<div style="background: <?=$logincssfile?>;" class="pagebody">
145
				<div class="col-sm-2"></div>
146

    
147
				<div class="col-sm-8 offset-md-4 logoCol">
148
					<div class="loginCont center-block error-panel">
149
						<a href="index.php?logout"><?=$desc;?></a>
150
					</div>
151
				</div>
152

    
153
			<div class="col-sm-2"></div>
154
			</div>
155

    
156
			<footer id="3">
157
			<div id="footertext">
158
					<p class="text-muted">
159
						<a target="_blank" href="https://www.pfsense.org/?gui=bootstrap">pfSense</a> is &copy;
160
						2004 - 2018 by <a href="https://pfsense.org/license" class="tblnk">Rubicon Communications, LLC (Netgate)</a>. All Rights Reserved.
161
						[<a href="/license.php" class="tblnk">view license</a>]
162
					</p>
163
				</div>
164
			</footer>
165
		</div>
166
	</body>
167
</html>
168

    
169
<?php
170

    
171
} // end function
172

    
173

    
174
function display_login_form() {
175
	require_once("globals.inc");
176
	global $config, $g;
177

    
178
	unset($input_errors);
179

    
180
	if (isAjax()) {
181
		if (isset($_POST['login'])) {
182
			if ($_SESSION['Logged_In'] <> "True") {
183
				isset($_SESSION['Login_Error']) ? $login_error = $_SESSION['Login_Error'] : $login_error = gettext("unknown reason");
184
				printf("showajaxmessage('" . gettext("Invalid login (%s).") . "')", $login_error);
185
			}
186
			if (file_exists("{$g['tmp_path']}/webconfigurator.lock")) {
187
				// TODO: add the IP from the user who did lock the device
188
				$whom = file_get_contents("{$g['tmp_path']}/webconfigurator.lock");
189
				printf("showajaxmessage('" . gettext("This device is currently being maintained by: %s.") . "');", $whom);
190
			}
191
		}
192
		//If session ended
193
		echo "SESSION_TIMEOUT";
194
		exit;
195
	}
196

    
197
	/* Check against locally configured IP addresses, which will catch when someone
198
	   port forwards WebGUI access from WAN to an internal IP on the router. */
199
	global $FilterIflist, $nifty_background;
200

    
201
	$local_ip = false;
202

    
203
	if (strpos($_SERVER['HTTP_HOST'], ":") === FALSE) {
204
		$http_host_port = explode(":", $_SERVER['HTTP_HOST']);
205
		$http_host = $http_host_port[0];
206
	} else {
207
		$http_host = $_SERVER['HTTP_HOST'];
208
	}
209

    
210
	if (empty($FilterIflist)) {
211
		require_once('filter.inc');
212
		require_once('shaper.inc');
213
		filter_generate_optcfg_array();
214
	}
215

    
216
	foreach ($FilterIflist as $iflist) {
217
		if ($iflist['ip'] == $http_host) {
218
			$local_ip = true;
219
		} else if ($iflist['ipv6'] == $http_host) {
220
			$local_ip = true;
221
		} else if (is_array($iflist['vips'])) {
222
			foreach ($iflist['vips'] as $vip) {
223
				if ($vip['ip'] == $http_host) {
224
					$local_ip = true;
225
					break;
226
				}
227
			}
228

    
229
			unset($vip);
230
		}
231

    
232
		if ($local_ip == true) {
233
			break;
234
		}
235
	}
236

    
237
	unset($FilterIflist);
238
	unset($iflist);
239

    
240
	if ($local_ip == false) {
241
		if (is_array($config['openvpn']['openvpn-server'])) {
242
			foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
243
				if (is_ipaddrv4($http_host) && !empty($ovpns['tunnel_network']) && ip_in_subnet($http_host, $ovpns['tunnel_network'])) {
244
					$local_ip = true;
245
				} else if (is_ipaddrv6($http_host) && !empty($ovpns['tunnel_networkv6']) && ip_in_subnet($http_host, $ovpns['tunnel_networkv6'])) {
246
					$local_ip = true;
247
				}
248

    
249
				if ($local_ip == true) {
250
					break;
251
				}
252
			}
253
		}
254
	}
255

    
256
	// For the login form, get the settings of no particular user.
257
	// That ensures we will use the system default theme for the login form.
258
	$user_settings = get_user_settings("");
259
	$cssfile = "/css/pfSense.css";
260

    
261
	if (isset($user_settings['webgui']['webguicss'])) {
262
		if (file_exists("/usr/local/www/css/" . $user_settings['webgui']['webguicss'])) {
263
			$cssfile = "/css/" . $user_settings['webgui']['webguicss'];
264
		}
265
	}
266

    
267
	$logincssfile = "#1e3f75";
268

    
269
	if (isset($user_settings['webgui']['logincss']) && strlen($user_settings['webgui']['logincss']) == 6) {
270
		$logincssfile = "#" . $user_settings['webgui']['logincss'];
271
	}
272

    
273
	if (isset($config['system']['webgui']['loginshowhost'])) {
274
		$loginbannerstr = sprintf(gettext('%1$s.%2$s'), htmlspecialchars($config['system']['hostname']), htmlspecialchars($config['system']['domain']));
275
	} else {
276
		$loginbannerstr = sprintf(gettext('Login to %1$s'), $g['product_name']);
277
	}
278

    
279
	$loginautocomplete = isset($config['system']['webgui']['loginautocomplete']) ? '' : 'autocomplete="off"';
280

    
281
	if (is_ipaddr($http_host) && !$local_ip && !isset($config['system']['webgui']['nohttpreferercheck'])) {
282
		$warnclass = "pagebodywarn";	// Make room for a warning display row
283
	} else {
284
		$warnclass = "pagebody";
285
	}
286
?>
287
<!DOCTYPE html>
288
<html lang="en">
289
	<head>
290
		<meta name="viewport" content="width=device-width, initial-scale=1">
291
	    <link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css" type="text/css">
292
	    <link rel="stylesheet" href="/css/login.css?v=<?=filemtime('/usr/local/www/css/login.css')?>" type="text/css">
293
		<title><?=gettext("Login"); ?></title>
294
		<script type="text/javascript">
295
			//<![CDATA{
296
			var events = events || [];
297
			//]]>
298
		</script>
299
	</head>
300

    
301
	<body id="login" >
302
		<div id="total">
303
			<header>
304
				<div id="headerrow">
305
					<div class="row">
306
						<!-- Header left logo box -->
307
						<div class="col-sm-4">
308
							<div id="logodiv" style="text-align:center" class="nowarning">
309
								<?php include("/usr/local/www/logo.svg"); ?>
310
							</div>
311
						</div>
312

    
313
						<!-- Header center message box -->
314
						<div class="col-sm-4 nowarning msgbox text-center text-danger">
315
<?php
316
						if (!empty($_POST['usernamefld'])) {
317
							print("<h4>" . $_SESSION['Login_Error'] . "</h4>");
318
						}
319
?>
320
						</div>
321

    
322
						<!-- Header right message box (hostname or msg)-->
323
						<div class="col-sm-4 nowarning msgbox text-center">
324
							<span id="hostspan">
325
								<a><h4><?=$loginbannerstr?></h4></a>
326
							</span>
327
						</div>
328
					</div>
329
<?php
330
	if ($warnclass == "pagebodywarn") {
331
?>
332
					<div class="row">
333
						<div class="col-sm-12">
334
							<div class="alert alert-warning <?=$warnclass?>">
335
								<?=gettext("The IP address being used to access this router is not configured locally, which may be forwarded by NAT or other means.
336
								If this forwarding is unexpected, it should be verified that a man-in-the-middle attack is not taking place.")?>
337
							</div>
338
						</div>
339
					</div>
340
<?php
341
	}
342
?>
343
	            </div>
344
	        </header>
345

    
346
	        <div style="background: <?=$logincssfile?>;" class="<?=$warnclass?>">
347
	        	<div class="col-sm-4"></div>
348

    
349
	        	<div class="col-sm-4 offset-md-4 logoCol">
350
					<div class="loginCont center-block">
351
		                <form method="post" <?=$loginautocomplete?> class="login">
352
			                <p class="form-title">Sign In</p>
353
			                <input name="usernamefld" id="usernamefld" type="text" placeholder="Username" autocorrect="off" autocapitalize="none"/>
354
			                <input name="passwordfld" id="passwordfld" type="password" placeholder="Password" />
355
			                <input type="submit" name="login" value="Sign In" class="btn btn-success btn-sm" />
356
		                </form>
357
					</div>
358
	            </div>
359

    
360
	        	<div class="col-sm-4"></div>
361
	        </div>
362

    
363
	        <footer id="3">
364
	            <div id="footertext">
365
					<p class="text-muted">
366
						<a target="_blank" href="https://www.pfsense.org/?gui=bootstrap">pfSense</a> is &copy;
367
						2004 - 2018 by <a href="https://pfsense.org/license" class="tblnk">Rubicon Communications, LLC (Netgate)</a>. All Rights Reserved.
368
						[<a href="/license.php" class="tblnk">view license</a>]
369
					</p>
370
	            </div>
371
	        </footer>
372
	    </div>
373

    
374
		<script src="/vendor/jquery/jquery-1.12.0.min.js?v=<?=filemtime('/usr/local/www/vendor/jquery/jquery-1.12.0.min.js')?>"></script>
375
		<script src="/vendor/bootstrap/js/bootstrap.min.js?v=<?=filemtime('/usr/local/www/vendor/bootstrap/js/bootstrap.min.js')?>"></script>
376
		<script src="/js/pfSense.js?v=<?=filemtime('/usr/local/www/js/pfSense.js')?>"></script>
377

    
378
		<script type="text/javascript">
379
		//!<[CDATA[
380
		events.push(function() {
381
			document.cookie=
382
				"cookie_test=1" +
383
				"<?php echo $config['system']['webgui']['protocol'] == 'https' ? '; secure' : '';?>";
384

    
385
			if (document.cookie.indexOf("cookie_test") == -1) {
386
				alert("<?=gettext('The browser must support cookies to login.')?>");
387
			}
388

    
389
			// Delete it
390
			document.cookie = "cookie_test=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";
391
		});
392
		//]]>
393
		</script>
394

    
395
	</body>
396
</html>
397

    
398
<?php
399
} // end function
(5-5/60)