Project

General

Profile

Download (11.4 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 = get_config_user();
69
		log_error("{$username} attempted to access {$_SERVER['SCRIPT_NAME']} but does not have access to that page. Redirecting to {$page}.");
70

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

    
77
		exit;
78
	}
79
} else {
80
	$_SESSION['Post_Login'] = true;
81
}
82

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

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

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

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

    
111
	$logincssfile = "#770101";
112
?>
113

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

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

    
141
			<div style="background: <?=$logincssfile?>;" class="pagebody">
142
				<div class="col-sm-2"></div>
143

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

    
150
			<div class="col-sm-2"></div>
151
			</div>
152

    
153
			<footer id="3">
154
			<div id="footertext">
155
					<p class="text-muted">
156
						<?=print_credit()?>
157
					</p>
158
				</div>
159
			</footer>
160
		</div>
161
	</body>
162
</html>
163

    
164
<?php
165

    
166
} // end function
167

    
168

    
169
function display_login_form() {
170
	require_once("globals.inc");
171
	global $config, $g;
172

    
173
	unset($input_errors);
174

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

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

    
196
	$local_ip = false;
197

    
198
	if (strpos($_SERVER['HTTP_HOST'], ":") === FALSE) {
199
		$http_host_port = explode(":", $_SERVER['HTTP_HOST']);
200
		$http_host = $http_host_port[0];
201
	} else {
202
		$http_host = $_SERVER['HTTP_HOST'];
203
	}
204

    
205
	if (empty($FilterIflist)) {
206
		require_once('filter.inc');
207
		require_once('shaper.inc');
208
		filter_generate_optcfg_array();
209
	}
210

    
211
	foreach ($FilterIflist as $iflist) {
212
		if ($iflist['ip'] == $http_host) {
213
			$local_ip = true;
214
		} else if ($iflist['ipv6'] == $http_host) {
215
			$local_ip = true;
216
		} else if (is_array($iflist['vips'])) {
217
			foreach ($iflist['vips'] as $vip) {
218
				if ($vip['ip'] == $http_host) {
219
					$local_ip = true;
220
					break;
221
				}
222
			}
223

    
224
			unset($vip);
225
		}
226

    
227
		if ($local_ip == true) {
228
			break;
229
		}
230
	}
231

    
232
	unset($FilterIflist);
233
	unset($iflist);
234

    
235
	if ($local_ip == false) {
236
		if (is_array($config['openvpn']['openvpn-server'])) {
237
			foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
238
				if (is_ipaddrv4($http_host) && !empty($ovpns['tunnel_network']) && ip_in_subnet($http_host, $ovpns['tunnel_network'])) {
239
					$local_ip = true;
240
				} else if (is_ipaddrv6($http_host) && !empty($ovpns['tunnel_networkv6']) && ip_in_subnet($http_host, $ovpns['tunnel_networkv6'])) {
241
					$local_ip = true;
242
				}
243

    
244
				if ($local_ip == true) {
245
					break;
246
				}
247
			}
248
		}
249
	}
250

    
251
	// For the login form, get the settings of no particular user.
252
	// That ensures we will use the system default theme for the login form.
253
	$user_settings = get_user_settings("");
254
	$cssfile = "/css/pfSense.css";
255

    
256
	if (isset($user_settings['webgui']['webguicss'])) {
257
		if (file_exists("/usr/local/www/css/" . $user_settings['webgui']['webguicss'])) {
258
			$cssfile = "/css/" . $user_settings['webgui']['webguicss'];
259
		}
260
	}
261

    
262
	$logincssfile = "#1e3f75";
263

    
264
	if (isset($user_settings['webgui']['logincss']) && strlen($user_settings['webgui']['logincss']) == 6) {
265
		$logincssfile = "#" . $user_settings['webgui']['logincss'];
266
	}
267

    
268
	if (isset($config['system']['webgui']['loginshowhost'])) {
269
		$loginbannerstr = sprintf(gettext('%1$s.%2$s'), htmlspecialchars($config['system']['hostname']), htmlspecialchars($config['system']['domain']));
270
	} else {
271
		$loginbannerstr = sprintf(gettext('Login to %1$s'), $g['product_name']);
272
	}
273

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

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

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

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

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

    
341
	        <div style="background: <?=$logincssfile?>;" class="<?=$warnclass?>">
342
	        	<div class="col-sm-4"></div>
343

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

    
355
	        	<div class="col-sm-4"></div>
356
	        </div>
357

    
358
	        <footer id="3">
359
	            <div id="footertext">
360
					<p class="text-muted">
361
						<?=print_credit()?>
362
					</p>
363
	            </div>
364
	        </footer>
365
	    </div>
366

    
367
		<script src="/vendor/jquery/jquery-1.12.0.min.js?v=<?=filemtime('/usr/local/www/vendor/jquery/jquery-1.12.0.min.js')?>"></script>
368
		<script src="/vendor/bootstrap/js/bootstrap.min.js?v=<?=filemtime('/usr/local/www/vendor/bootstrap/js/bootstrap.min.js')?>"></script>
369
		<script src="/js/pfSense.js?v=<?=filemtime('/usr/local/www/js/pfSense.js')?>"></script>
370

    
371
		<script type="text/javascript">
372
		//!<[CDATA[
373
		events.push(function() {
374
			document.cookie=
375
				"cookie_test=1" +
376
				"<?php echo $config['system']['webgui']['protocol'] == 'https' ? '; secure' : '';?>";
377

    
378
			if (document.cookie.indexOf("cookie_test") == -1) {
379
				alert("<?=gettext('The browser must support cookies to login.')?>");
380
			}
381

    
382
			// Delete it
383
			document.cookie = "cookie_test=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";
384
		});
385
		//]]>
386
		</script>
387

    
388
	</body>
389
</html>
390

    
391
<?php
392
} // end function
(5-5/60)