Project

General

Profile

Download (43.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	services_captiveportal.php
4
	part of m0n0wall (http://m0n0.ch/wall)
5

    
6
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
7
	Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
8
	All rights reserved.
9

    
10
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12

    
13
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15

    
16
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in the
18
	   documentation and/or other materials provided with the distribution.
19

    
20
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
	POSSIBILITY OF SUCH DAMAGE.
30
*/
31
/*
32
	pfSense_MODULE: captiveportal
33
*/
34

    
35
##|+PRIV
36
##|*IDENT=page-services-captiveportal
37
##|*NAME=Services: Captive portal page
38
##|*DESCR=Allow access to the 'Services: Captive portal' page.
39
##|*MATCH=services_captiveportal.php*
40
##|-PRIV
41

    
42
require_once("functions.inc");
43
require_once("filter.inc");
44
require_once("shaper.inc");
45
require_once("captiveportal.inc");
46

    
47
if (substr($_GET['act'], 0, 3) == "get") {
48
	$nocsrf = true;
49
}
50

    
51
require_once("guiconfig.inc");
52

    
53
global $cpzone;
54
global $cpzoneid;
55

    
56
$cpzoneid = 1; /* Just a default */
57
$cpzone = $_GET['zone'];
58
if (isset($_POST['zone'])) {
59
	$cpzone = $_POST['zone'];
60
}
61

    
62
if (empty($cpzone) || empty($config['captiveportal'][$cpzone])) {
63
	header("Location: services_captiveportal_zones.php");
64
	exit;
65
}
66

    
67
if (!is_array($config['captiveportal'])) {
68
	$config['captiveportal'] = array();
69
}
70
$a_cp =& $config['captiveportal'];
71

    
72
$pgtitle = array(gettext("Services"), gettext("Captive portal"), $a_cp[$cpzone]['zone']);
73
$shortcut_section = "captiveportal";
74

    
75
if ($_GET['act'] == "viewhtml") {
76
	if ($a_cp[$cpzone] && $a_cp[$cpzone]['page']['htmltext']) {
77
		echo base64_decode($a_cp[$cpzone]['page']['htmltext']);
78
	}
79
	exit;
80
} else if ($_GET['act'] == "gethtmlhtml" && $a_cp[$cpzone] && $a_cp[$cpzone]['page']['htmltext']) {
81
	$file_data = base64_decode($a_cp[$cpzone]['page']['htmltext']);
82
	$file_size = strlen($file_data);
83

    
84
	header("Content-Type: text/html");
85
	header("Content-Disposition: attachment; filename=portal.html");
86
	header("Content-Length: $file_size");
87
	echo $file_data;
88

    
89
	exit;
90
} else if ($_GET['act'] == "delhtmlhtml" && $a_cp[$cpzone] && $a_cp[$cpzone]['page']['htmltext']) {
91
	unset($a_cp[$cpzone]['page']['htmltext']);
92
	write_config(sprintf(gettext("Captive Portal: zone %s: Restore default portal page"), $cpzone));
93
	header("Location: services_captiveportal.php?zone={$cpzone}");
94
	exit;
95
} else if ($_GET['act'] == "viewerrhtml") {
96
	if ($a_cp[$cpzone] && $a_cp[$cpzone]['page']['errtext']) {
97
		echo base64_decode($a_cp[$cpzone]['page']['errtext']);
98
	}
99
	exit;
100
} else if ($_GET['act'] == "geterrhtml" && $a_cp[$cpzone] && $a_cp[$cpzone]['page']['errtext']) {
101
	$file_data = base64_decode($a_cp[$cpzone]['page']['errtext']);
102
	$file_size = strlen($file_data);
103

    
104
	header("Content-Type: text/html");
105
	header("Content-Disposition: attachment; filename=err.html");
106
	header("Content-Length: $file_size");
107
	echo $file_data;
108

    
109
	exit;
110
} else if ($_GET['act'] == "delerrhtml" && $a_cp[$cpzone] && $a_cp[$cpzone]['page']['errtext']) {
111
	unset($a_cp[$cpzone]['page']['errtext']);
112
	write_config(sprintf(gettext("Captive Portal: zone %s: Restore default error page"), $cpzone));
113
	header("Location: services_captiveportal.php?zone={$cpzone}");
114
	exit;
115
} else if ($_GET['act'] == "viewlogouthtml") {
116
	if ($a_cp[$cpzone] && $a_cp[$cpzone]['page']['logouttext']) {
117
		echo base64_decode($a_cp[$cpzone]['page']['logouttext']);
118
	}
119
	exit;
120
} else if ($_GET['act'] == "getlogouthtml" && $a_cp[$cpzone] && $a_cp[$cpzone]['page']['logouttext']) {
121
	$file_data = base64_decode($a_cp[$cpzone]['page']['logouttext']);
122
	$file_size = strlen($file_data);
123

    
124
	header("Content-Type: text/html");
125
	header("Content-Disposition: attachment; filename=logout.html");
126
	header("Content-Length: $file_size");
127
	echo $file_data;
128

    
129
	exit;
130
} else if ($_GET['act'] == "dellogouthtml" && $a_cp[$cpzone] && $a_cp[$cpzone]['page']['logouttext']) {
131
	unset($a_cp[$cpzone]['page']['logouttext']);
132
	write_config(sprintf(gettext("Captive Portal: zone %s: Restore default logout page"), $cpzone));
133
	header("Location: services_captiveportal.php?zone={$cpzone}");
134
	exit;
135
}
136

    
137
if (!is_array($config['ca'])) {
138
	$config['ca'] = array();
139
}
140

    
141
$a_ca =& $config['ca'];
142

    
143
if (!is_array($config['cert'])) {
144
	$config['cert'] = array();
145
}
146

    
147
$a_cert =& $config['cert'];
148

    
149
if ($a_cp[$cpzone]) {
150
	$cpzoneid = $pconfig['zoneid'] = $a_cp[$cpzone]['zoneid'];
151
	$pconfig['cinterface'] = $a_cp[$cpzone]['interface'];
152
	$pconfig['maxproc'] = $a_cp[$cpzone]['maxproc'];
153
	$pconfig['maxprocperip'] = $a_cp[$cpzone]['maxprocperip'];
154
	$pconfig['timeout'] = $a_cp[$cpzone]['timeout'];
155
	$pconfig['idletimeout'] = $a_cp[$cpzone]['idletimeout'];
156
	$pconfig['freelogins_count'] = $a_cp[$cpzone]['freelogins_count'];
157
	$pconfig['freelogins_resettimeout'] = $a_cp[$cpzone]['freelogins_resettimeout'];
158
	$pconfig['freelogins_updatetimeouts'] = isset($a_cp[$cpzone]['freelogins_updatetimeouts']);
159
	$pconfig['enable'] = isset($a_cp[$cpzone]['enable']);
160
	$pconfig['auth_method'] = $a_cp[$cpzone]['auth_method'];
161
	$pconfig['localauth_priv'] = isset($a_cp[$cpzone]['localauth_priv']);
162
	$pconfig['radacct_enable'] = isset($a_cp[$cpzone]['radacct_enable']);
163
	$pconfig['radmac_enable'] = isset($a_cp[$cpzone]['radmac_enable']);
164
	$pconfig['radmac_secret'] = $a_cp[$cpzone]['radmac_secret'];
165
	$pconfig['reauthenticate'] = isset($a_cp[$cpzone]['reauthenticate']);
166
	$pconfig['reauthenticateacct'] = $a_cp[$cpzone]['reauthenticateacct'];
167
	$pconfig['httpslogin_enable'] = isset($a_cp[$cpzone]['httpslogin']);
168
	$pconfig['httpsname'] = $a_cp[$cpzone]['httpsname'];
169
	$pconfig['preauthurl'] = strtolower($a_cp[$cpzone]['preauthurl']);
170
	$pconfig['blockedmacsurl'] = strtolower($a_cp[$cpzone]['blockedmacsurl']);
171
	$pconfig['certref'] = $a_cp[$cpzone]['certref'];
172
	$pconfig['nohttpsforwards'] = isset($a_cp[$cpzone]['nohttpsforwards']);
173
	$pconfig['logoutwin_enable'] = isset($a_cp[$cpzone]['logoutwin_enable']);
174
	$pconfig['peruserbw'] = isset($a_cp[$cpzone]['peruserbw']);
175
	$pconfig['bwdefaultdn'] = $a_cp[$cpzone]['bwdefaultdn'];
176
	$pconfig['bwdefaultup'] = $a_cp[$cpzone]['bwdefaultup'];
177
	$pconfig['nomacfilter'] = isset($a_cp[$cpzone]['nomacfilter']);
178
	$pconfig['noconcurrentlogins'] = isset($a_cp[$cpzone]['noconcurrentlogins']);
179
	$pconfig['radius_protocol'] = $a_cp[$cpzone]['radius_protocol'];
180
	$pconfig['redirurl'] = $a_cp[$cpzone]['redirurl'];
181
	$pconfig['radiusip'] = $a_cp[$cpzone]['radiusip'];
182
	$pconfig['radiusip2'] = $a_cp[$cpzone]['radiusip2'];
183
	$pconfig['radiusip3'] = $a_cp[$cpzone]['radiusip3'];
184
	$pconfig['radiusip4'] = $a_cp[$cpzone]['radiusip4'];
185
	$pconfig['radiusport'] = $a_cp[$cpzone]['radiusport'];
186
	$pconfig['radiusport2'] = $a_cp[$cpzone]['radiusport2'];
187
	$pconfig['radiusport3'] = $a_cp[$cpzone]['radiusport3'];
188
	$pconfig['radiusport4'] = $a_cp[$cpzone]['radiusport4'];
189
	$pconfig['radiusacctport'] = $a_cp[$cpzone]['radiusacctport'];
190
	$pconfig['radiuskey'] = $a_cp[$cpzone]['radiuskey'];
191
	$pconfig['radiuskey2'] = $a_cp[$cpzone]['radiuskey2'];
192
	$pconfig['radiuskey3'] = $a_cp[$cpzone]['radiuskey3'];
193
	$pconfig['radiuskey4'] = $a_cp[$cpzone]['radiuskey4'];
194
	$pconfig['radiusvendor'] = $a_cp[$cpzone]['radiusvendor'];
195
	$pconfig['radiussession_timeout'] = isset($a_cp[$cpzone]['radiussession_timeout']);
196
	$pconfig['radiussrcip_attribute'] = $a_cp[$cpzone]['radiussrcip_attribute'];
197
	$pconfig['passthrumacadd'] = isset($a_cp[$cpzone]['passthrumacadd']);
198
	$pconfig['passthrumacaddusername'] = isset($a_cp[$cpzone]['passthrumacaddusername']);
199
	$pconfig['radmac_format'] = $a_cp[$cpzone]['radmac_format'];
200
	$pconfig['reverseacct'] = isset($a_cp[$cpzone]['reverseacct']);
201
	$pconfig['radiusnasid'] = $a_cp[$cpzone]['radiusnasid'];
202
	$pconfig['page'] = array();
203
	if ($a_cp[$cpzone]['page']['htmltext']) {
204
		$pconfig['page']['htmltext'] = $a_cp[$cpzone]['page']['htmltext'];
205
	}
206
	if ($a_cp[$cpzone]['page']['errtext']) {
207
		$pconfig['page']['errtext'] = $a_cp[$cpzone]['page']['errtext'];
208
	}
209
	if ($a_cp[$cpzone]['page']['logouttext']) {
210
		$pconfig['page']['logouttext'] = $a_cp[$cpzone]['page']['logouttext'];
211
	}
212
}
213

    
214
if ($_POST) {
215

    
216
	unset($input_errors);
217
	$pconfig = $_POST;
218

    
219
	/* input validation */
220
	if ($_POST['enable']) {
221
		$reqdfields = explode(" ", "zone cinterface");
222
		$reqdfieldsn = array(gettext("Zone name"), gettext("Interface"));
223

    
224
		if (isset($_POST['auth_method']) && $_POST['auth_method'] == "radius") {
225
			$reqdfields[] = "radius_protocol";
226
			$reqdfieldsn[] = gettext("RADIUS Protocol");
227
			$reqdfields[] = "radiusip";
228
			$reqdfieldsn[] = gettext("Primary RADIUS server IP address");
229
		}
230

    
231
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
232

    
233
		/* make sure no interfaces are bridged or used on other zones */
234
		if (is_array($_POST['cinterface'])) {
235
			foreach ($pconfig['cinterface'] as $cpbrif) {
236
				if (link_interface_to_bridge($cpbrif)) {
237
					$input_errors[] = sprintf(gettext("The captive portal cannot be used on interface %s since it is part of a bridge."), $cpbrif);
238
				}
239
				foreach ($a_cp as $cpkey => $cp) {
240
					if ($cpkey != $cpzone || empty($cpzone)) {
241
						if (in_array($cpbrif, explode(",", $cp['interface']))) {
242
							$input_errors[] = sprintf(gettext("The captive portal cannot be used on interface %s since it is used already on %s instance."), $cpbrif, $cp['zone']);
243
						}
244
					}
245
				}
246
			}
247
		}
248

    
249
		if ($_POST['httpslogin_enable']) {
250
			if (!$_POST['certref']) {
251
				$input_errors[] = gettext("Certificate must be specified for HTTPS login.");
252
			}
253
			if (!$_POST['httpsname'] || !is_domain($_POST['httpsname'])) {
254
				$input_errors[] = gettext("The HTTPS server name must be specified for HTTPS login.");
255
			}
256
		}
257
	}
258

    
259
	if ($_POST['timeout']) {
260
		if (!is_numeric($_POST['timeout']) || ($_POST['timeout'] < 1)) {
261
			$input_errors[] = gettext("The timeout must be at least 1 minute.");
262
		} else if (isset($config['dhcpd']) && is_array($config['dhcpd'])) {
263
			foreach ($config['dhcpd'] as $dhcpd_if => $dhcpd_data) {
264
				if (!isset($dhcpd_data['enable'])) {
265
					continue;
266
				}
267
				if (!is_array($_POST['cinterface']) || !in_array($dhcpd_if, $_POST['cinterface'])) {
268
					continue;
269
				}
270

    
271
				$deftime = 7200; // Default lease time
272
				if (isset($dhcpd_data['defaultleasetime']) && is_numeric($dhcpd_data['defaultleasetime'])) {
273
					$deftime = $dhcpd_data['defaultleasetime'];
274
				}
275

    
276
				if ($_POST['timeout'] > $deftime) {
277
					$input_errors[] = gettext("Hard timeout must be less or equal Default lease time set on DHCP Server");
278
				}
279
			}
280
		}
281
	}
282
	
283
	if ($_POST['idletimeout'] && (!is_numeric($_POST['idletimeout']) || ($_POST['idletimeout'] < 1))) {
284
		$input_errors[] = gettext("The idle timeout must be at least 1 minute.");
285
	}
286
	
287
	if ($_POST['freelogins_count'] && (!is_numeric($_POST['freelogins_count']))) {
288
		$input_errors[] = gettext("The pass-through credit count must be a number or left blank.");
289
	} else if ($_POST['freelogins_count'] && is_numeric($_POST['freelogins_count']) && ($_POST['freelogins_count'] >= 1)) {
290
		if (empty($_POST['freelogins_resettimeout']) || !is_numeric($_POST['freelogins_resettimeout']) || ($_POST['freelogins_resettimeout'] <= 0)) {
291
			$input_errors[] = gettext("The waiting period to restore pass-through credits must be above 0 hours.");
292
		}
293
	}
294
	
295
	if (($_POST['radiusip'] && !is_ipaddr($_POST['radiusip']))) {
296
		$input_errors[] = sprintf(gettext("A valid IP address must be specified. [%s]"), $_POST['radiusip']);
297
	}
298
	
299
	if (($_POST['radiusip2'] && !is_ipaddr($_POST['radiusip2']))) {
300
		$input_errors[] = sprintf(gettext("A valid IP address must be specified. [%s]"), $_POST['radiusip2']);
301
	}
302
	
303
	if (($_POST['radiusip3'] && !is_ipaddr($_POST['radiusip3']))) {
304
		$input_errors[] = sprintf(gettext("A valid IP address must be specified. [%s]"), $_POST['radiusip3']);
305
	}
306
	
307
	if (($_POST['radiusip4'] && !is_ipaddr($_POST['radiusip4']))) {
308
		$input_errors[] = sprintf(gettext("A valid IP address must be specified. [%s]"), $_POST['radiusip4']);
309
	}
310
	
311
	if (($_POST['radiusport'] && !is_port($_POST['radiusport']))) {
312
		$input_errors[] = sprintf(gettext("A valid port number must be specified. [%s]"), $_POST['radiusport']);
313
	}
314
	
315
	if (($_POST['radiusport2'] && !is_port($_POST['radiusport2']))) {
316
		$input_errors[] = sprintf(gettext("A valid port number must be specified. [%s]"), $_POST['radiusport2']);
317
	}
318
	
319
	if (($_POST['radiusport3'] && !is_port($_POST['radiusport3']))) {
320
		$input_errors[] = sprintf(gettext("A valid port number must be specified. [%s]"), $_POST['radiusport3']);
321
	}
322
	
323
	if (($_POST['radiusport4'] && !is_port($_POST['radiusport4']))) {
324
		$input_errors[] = sprintf(gettext("A valid port number must be specified. [%s]"), $_POST['radiusport4']);
325
	}
326
	
327
	if (($_POST['radiusacctport'] && !is_port($_POST['radiusacctport']))) {
328
		$input_errors[] = sprintf(gettext("A valid port number must be specified. [%s]"), $_POST['radiusacctport']);
329
	}
330
	
331
	if ($_POST['maxproc'] && (!is_numeric($_POST['maxproc']) || ($_POST['maxproc'] < 4) || ($_POST['maxproc'] > 100))) {
332
		$input_errors[] = gettext("The maximum number of concurrent connections per client IP address may not be larger than the global maximum.");
333
	}
334
	
335
	if (trim($_POST['radiusnasid']) !== "" && !preg_match("/^[\x21-\x7e]{3,253}$/i", trim($_POST['radiusnasid']))) {
336
		$input_errors[] = gettext("The NAS-Identifier must be 3-253 characters long and should only contain ASCII characters.");
337
	}
338

    
339
	if (!$input_errors) {
340
		$newcp =& $a_cp[$cpzone];
341
		//$newcp['zoneid'] = $a_cp[$cpzone]['zoneid'];
342
		if (empty($newcp['zoneid'])) {
343
			$newcp['zoneid'] = 2;
344
			foreach ($a_cp as $keycpzone => $cp) {
345
				if ($cp['zoneid'] == $newcp['zoneid'] && $keycpzone != $cpzone) {
346
					$newcp['zoneid'] += 2; /* Reserve space for SSL config if needed */
347
				}
348
			}
349

    
350
			$cpzoneid = $newcp['zoneid'];
351
		}
352
		$oldifaces = explode(",", $newcp['interface']);
353
		if (is_array($_POST['cinterface'])) {
354
			$newcp['interface'] = implode(",", $_POST['cinterface']);
355
		}
356
		$newcp['maxproc'] = $_POST['maxproc'];
357
		$newcp['maxprocperip'] = $_POST['maxprocperip'] ? $_POST['maxprocperip'] : false;
358
		$newcp['timeout'] = $_POST['timeout'];
359
		$newcp['idletimeout'] = $_POST['idletimeout'];
360
		$newcp['freelogins_count'] = $_POST['freelogins_count'];
361
		$newcp['freelogins_resettimeout'] = $_POST['freelogins_resettimeout'];
362
		$newcp['freelogins_updatetimeouts'] = $_POST['freelogins_updatetimeouts'] ? true : false;
363
		if ($_POST['enable']) {
364
			$newcp['enable'] = true;
365
		} else {
366
			unset($newcp['enable']);
367
		}
368
		$newcp['auth_method'] = $_POST['auth_method'];
369
		$newcp['localauth_priv'] = isset($_POST['localauth_priv']);
370
		$newcp['radacct_enable'] = $_POST['radacct_enable'] ? true : false;
371
		$newcp['reauthenticate'] = $_POST['reauthenticate'] ? true : false;
372
		$newcp['radmac_enable'] = $_POST['radmac_enable'] ? true : false;
373
		$newcp['radmac_secret'] = $_POST['radmac_secret'] ? $_POST['radmac_secret'] : false;
374
		$newcp['reauthenticateacct'] = $_POST['reauthenticateacct'];
375
		if ($_POST['httpslogin_enable']) {
376
			$newcp['httpslogin'] = true;
377
		} else {
378
			unset($newcp['httpslogin']);
379
		}
380
		$newcp['httpsname'] = $_POST['httpsname'];
381
		$newcp['preauthurl'] = $_POST['preauthurl'];
382
		$newcp['blockedmacsurl'] = $_POST['blockedmacsurl'];
383
		$newcp['peruserbw'] = $_POST['peruserbw'] ? true : false;
384
		if (isset($_POST['bwdefaultdn'])) {
385
			$newcp['bwdefaultdn'] = $_POST['bwdefaultdn'];
386
		} else {
387
			unset($newcp['bwdefaultdn']);
388
		}
389
		if (isset($_POST['bwdefaultup'])) {
390
			$newcp['bwdefaultup'] = $_POST['bwdefaultup'];
391
		} else {
392
			unset($newcp['bwdefaultup']);
393
		}
394
		$newcp['certref'] = $_POST['certref'];
395
		$newcp['nohttpsforwards'] = $_POST['nohttpsforwards'] ? true : false;
396
		$newcp['logoutwin_enable'] = $_POST['logoutwin_enable'] ? true : false;
397
		$newcp['nomacfilter'] = $_POST['nomacfilter'] ? true : false;
398
		$newcp['noconcurrentlogins'] = $_POST['noconcurrentlogins'] ? true : false;
399
		$newcp['radius_protocol'] = $_POST['radius_protocol'];
400
		$newcp['redirurl'] = $_POST['redirurl'];
401
		if (isset($_POST['radiusip'])) {
402
			$newcp['radiusip'] = $_POST['radiusip'];
403
		} else {
404
			unset($newcp['radiusip']);
405
		}
406
		if (isset($_POST['radiusip2'])) {
407
			$newcp['radiusip2'] = $_POST['radiusip2'];
408
		} else {
409
			unset($newcp['radiusip2']);
410
		}
411
		if (isset($_POST['radiusip3'])) {
412
			$newcp['radiusip3'] = $_POST['radiusip3'];
413
		} else {
414
			unset($newcp['radiusip3']);
415
		}
416
		if (isset($_POST['radiusip4'])) {
417
			$newcp['radiusip4'] = $_POST['radiusip4'];
418
		} else {
419
			unset($newcp['radiusip4']);
420
		}
421
		$newcp['radiusport'] = $_POST['radiusport'];
422
		$newcp['radiusport2'] = $_POST['radiusport2'];
423
		if (isset($_POST['radiusport3'])) {
424
			$newcp['radiusport3'] = $_POST['radiusport3'];
425
		}
426
		if (isset($_POST['radiusport4'])) {
427
			$newcp['radiusport4'] = $_POST['radiusport4'];
428
		}
429
		$newcp['radiusacctport'] = $_POST['radiusacctport'];
430
		$newcp['radiuskey'] = $_POST['radiuskey'];
431
		$newcp['radiuskey2'] = $_POST['radiuskey2'];
432
		$newcp['radiuskey3'] = $_POST['radiuskey3'];
433
		$newcp['radiuskey4'] = $_POST['radiuskey4'];
434
		$newcp['radiusvendor'] = $_POST['radiusvendor'] ? $_POST['radiusvendor'] : false;
435
		$newcp['radiussession_timeout'] = $_POST['radiussession_timeout'] ? true : false;
436
		$newcp['radiussrcip_attribute'] = $_POST['radiussrcip_attribute'];
437
		$newcp['passthrumacadd'] = $_POST['passthrumacadd'] ? true : false;
438
		$newcp['passthrumacaddusername'] = $_POST['passthrumacaddusername'] ? true : false;
439
		$newcp['radmac_format'] = $_POST['radmac_format'] ? $_POST['radmac_format'] : false;
440
		$newcp['reverseacct'] = $_POST['reverseacct'] ? true : false;
441
		$newcp['radiusnasid'] = trim($_POST['radiusnasid']);
442

    
443
		if (!is_array($newcp['page'])) {
444
			$newcp['page'] = array();
445
		}
446

    
447
		/* file upload? */
448
		if (is_uploaded_file($_FILES['htmlfile']['tmp_name'])) {
449
			$newcp['page']['htmltext'] = base64_encode(file_get_contents($_FILES['htmlfile']['tmp_name']));
450
		}
451
		if (is_uploaded_file($_FILES['errfile']['tmp_name'])) {
452
			$newcp['page']['errtext'] = base64_encode(file_get_contents($_FILES['errfile']['tmp_name']));
453
		}
454
		if (is_uploaded_file($_FILES['logoutfile']['tmp_name'])) {
455
			$newcp['page']['logouttext'] = base64_encode(file_get_contents($_FILES['logoutfile']['tmp_name']));
456
		}
457

    
458
		write_config();
459

    
460
		/* Clear up unselected interfaces */
461
		$newifaces = explode(",", $newcp['interface']);
462
		$toremove = array_diff($oldifaces, $newifaces);
463

    
464
		if (!empty($toremove)) {
465
			foreach ($toremove as $removeif) {
466
				$removeif = get_real_interface($removeif);
467
				mwexec("/sbin/ipfw zone {$cpzoneid} mdel {$removeif}");
468
			}
469
		}
470

    
471
		captiveportal_configure_zone($newcp);
472
		unset($newcp, $newifaces, $toremove);
473
		filter_configure();
474
		header("Location: services_captiveportal_zones.php");
475
		exit;
476
	} else {
477
		if (is_array($_POST['cinterface'])) {
478
			$pconfig['cinterface'] = implode(",", $_POST['cinterface']);
479
		}
480
	}
481
}
482

    
483
function build_radiusnas_list() {
484
	$list = array();
485

    
486
	$iflist = get_configured_interface_with_descr();
487
	foreach ($iflist as $ifdesc => $ifdescr) {
488
		$ipaddr = get_interface_ip($ifdesc);
489
		if (is_ipaddr($ipaddr)) {
490
			$list[$ifdescr] = $ifdescr . ' - ' . $ipaddr;
491
		}
492
	}
493

    
494
	if (is_array($config['virtualip']['vip'])) {
495
		foreach ($config['virtualip']['vip'] as $sn) {
496
			if ($sn['mode'] == "proxyarp" && $sn['type'] == "network") {
497
				$start = ip2long32(gen_subnet($sn['subnet'], $sn['subnet_bits']));
498
				$end = ip2long32(gen_subnet_max($sn['subnet'], $sn['subnet_bits']));
499
				$len = $end - $start;
500

    
501
				for ($i = 0; $i <= $len; $i++) {
502
					$snip = long2ip32($start+$i);
503
					$list[$snip] = $sn['descr'] . ' - ' . $snip;
504
				}
505
			} else
506
				$list[$sn['subnet']] = $sn['descr'] . ' - ' . $sn['subnet'];
507
		}
508
	}
509

    
510
	return($list);
511
}
512

    
513
function build_cert_list() {
514
	global $a_cert;
515

    
516
	$list = array();
517

    
518
	foreach($a_cert as $cert)
519
		$list[$cert['refid']] = $cert['descr'];
520

    
521
	return($list);
522
}
523

    
524
$closehead = false;
525
include("head.inc");
526

    
527
if ($input_errors)
528
	print_input_errors($input_errors);
529

    
530
if ($savemsg)
531
	print_info_box($savemsg, 'success');
532

    
533
$tab_array = array();
534
$tab_array[] = array(gettext("Captive portal(s)"), true, "services_captiveportal.php?zone={$cpzone}");
535
$tab_array[] = array(gettext("MAC"), false, "services_captiveportal_mac.php?zone={$cpzone}");
536
$tab_array[] = array(gettext("Allowed IP addresses"), false, "services_captiveportal_ip.php?zone={$cpzone}");
537
$tab_array[] = array(gettext("Allowed Hostnames"), false, "services_captiveportal_hostname.php?zone={$cpzone}");
538
$tab_array[] = array(gettext("Vouchers"), false, "services_captiveportal_vouchers.php?zone={$cpzone}");
539
$tab_array[] = array(gettext("File Manager"), false, "services_captiveportal_filemanager.php?zone={$cpzone}");
540
display_top_tabs($tab_array, true);
541

    
542
require('classes/Form.class.php');
543

    
544
$form = new Form();
545

    
546
$section = new Form_Section('Captive Portal Configuration');
547

    
548
$section->addInput(new Form_Checkbox(
549
	'enable',
550
	'Enable',
551
	'Enable Captive Portal',
552
	$pconfig['enable']
553
));
554

    
555
$section->addInput(new Form_Select(
556
	'cinterface',
557
	'Interfaces',
558
	explode(",", $pconfig['cinterface']),
559
	get_configured_interface_with_descr(),
560
	true
561
))->addClass('general')->setHelp('Select the interface(s) to enable for captive portal.');
562

    
563
$section->addInput(new Form_Input(
564
	'maxprocperip',
565
	'Maximum concurrent connections',
566
	'number',
567
	$pconfig['maxprocperip'],
568
	['min' => '0', 'max' => '100']
569
))->setHelp('Timits the number of concurrent connections to the captive portal HTTP(S) server. This does not set how many users can be logged in ' .
570
			'to the captive portal, but rather how many users can load the portal page or authenticate at the same time! ' .
571
			'Possible setting allowed is: minimum 4 connections per client IP address, with a total maximum of 100 connections.');
572

    
573
$section->addInput(new Form_Input(
574
	'idletimeout',
575
	'Idle timeout (Minutes)',
576
	'number',
577
	$pconfig['idletimeout']
578
))->setHelp('Clients will be disconnected after this amount of inactivity. They may log in again immediately, though. Leave this field blank for no idle timeout.');
579

    
580
$section->addInput(new Form_Input(
581
	'timeout',
582
	'Hard timeout (Minutes)',
583
	'number',
584
	$pconfig['timeout']
585
))->setHelp('Clients will be disconnected after this amount of time, regardless of activity. They may log in again immediately, though. ' .
586
			'Leave this field blank for no hard timeout (not recommended unless an idle timeout is set).');
587

    
588
$section->addInput(new Form_Input(
589
	'freelogins_count',
590
	'Pass-through credits per MAC address.',
591
	'number',
592
	$pconfig['freelogins_count']
593
))->setHelp('Allows passing through the captive portal without authentication a limited number of times per MAC address. Once used up, ' .
594
			'the client can only log in with valid credentials until the waiting period specified below has expired. Recommended to set ' .
595
			'a hard timeout and/or idle timeout when using this for it to be effective.');
596

    
597
$section->addInput(new Form_Checkbox(
598
	'freelogins_updatetimeouts',
599
	'Reset waiting period',
600
	'Enable waiting period reset on attempted access',
601
	$pconfig['freelogins_updatetimeouts']
602
))->setHelp('If enabled, the waiting period is reset to the original duration if access is attempted when all pass-through credits have already been exhausted.');
603

    
604
$section->addInput(new Form_Checkbox(
605
	'logoutwin_enable',
606
	'Logout popup window',
607
	'Enable logout popup window',
608
	$pconfig['logoutwin_enable']
609
))->setHelp('If enabled, a popup window will appear when clients are allowed through the captive portal. ' .
610
			'This allows clients to explicitly disconnect themselves before the idle or hard timeout occurs.');
611

    
612
$section->addInput(new Form_Input(
613
	'preauthurl',
614
	'Pre-authentication redirect URL',
615
	'text',
616
	$pconfig['preauthurl']
617
))->setHelp('Use this field to set $PORTAL_REDIRURL$ variable which can be accessed using your custom captive portal index.php page or error pages.');
618

    
619
$section->addInput(new Form_Input(
620
	'redirurl',
621
	'After authentication Redirection URL',
622
	'text',
623
	$pconfig['redirurl']
624
))->setHelp('Clients will be redirected to this URL instead of the one they initially tried to access after they\'ve authenticated');
625

    
626
$section->addInput(new Form_Input(
627
	'blockedmacsurl',
628
	'Blocked MAC address redirect URL',
629
	'text',
630
	$pconfig['blockedmacsurl']
631
))->setHelp('Blocked MAC addresses will be redirected to this URL when attempting access.');
632

    
633
$section->addInput(new Form_Checkbox(
634
	'noconcurrentlogins',
635
	'Concurrent user logins',
636
	'Disable Concurrent user logins',
637
	$pconfig['noconcurrentlogins']
638
))->setHelp('If enabled only the most recent login per username will be active. Subsequent logins will cause machines previously logged in with the ' .
639
			'same username to be disconnected.');
640

    
641
$section->addInput(new Form_Checkbox(
642
	'nomacfilter',
643
	'MAC filtering',
644
	'Disable MAC filtering',
645
	$pconfig['nomacfilter']
646
))->setHelp('If enabled no attempts will be made to ensure that the MAC address of clients stays the same while they are logged in. ' .
647
			'This is required when the MAC address of the client cannot be determined (usually because there are routers betweenpfSenseand the clients). ' .
648
			'If this is enabled, RADIUS MAC authentication cannot be used.');
649

    
650
$section->addInput(new Form_Checkbox(
651
	'passthrumacadd',
652
	'Pass-through MAC Auto Entry',
653
	'Enable Pass-through MAC automatic additions',
654
	$pconfig['passthrumacadd']
655
))->setHelp(sprintf('If this enabled a MAC passthrough entry is automatically added after the user has successfully authenticated. Users of that MAC address will ' .
656
			'never have to authenticate again. To remove the passthrough MAC entry you either have to log in and remove it manually from the ' .
657
			'%s or send a POST from another system.'  .
658
			'If this is enabled, RADIUS MAC authentication cannot be used. Also, the logout window will not be shown.', '<a href="services_captiveportal_mac.php">MAC tab</a>'));
659

    
660
$section->addInput(new Form_Checkbox(
661
	'passthrumacaddusername',
662
	null,
663
	'Enable Pass-through MAC automatic addition with username',
664
	$pconfig['passthrumacaddusername']
665
))->setHelp(sprintf('If enabled with the automatically MAC passthrough entry created, the username used during authentication will be saved. ' .
666
			'To remove the passthrough MAC entry you either have to log in and remove it manually from the %s or send a POST from another system.',
667
			'<a href="services_captiveportal_mac.php">MAC tab</a>'));
668

    
669
$section->addInput(new Form_Checkbox(
670
	'peruserbw',
671
	'Per-user bandwidth restriction',
672
	'Enable per-user bandwidth restriction',
673
	$pconfig['peruserbw']
674
));
675

    
676
$section->addInput(new Form_Input(
677
	'bwdefaultdn',
678
	'Default download (Kbit/s)',
679
	'number',
680
	$pconfig['bwdefaultdn']
681
));
682

    
683
$section->addInput(new Form_Input(
684
	'bwdefaultup',
685
	'Default download (Kbit/s)',
686
	'number',
687
	$pconfig['bwdefaultup']
688
))->setHelp('If this option is set, the captive portal will restrict each user who logs in to the specified default bandwidth. ' .
689
			'RADIUS can override the default settings. Leave empty or set to 0 for no limit.');
690

    
691
$form->add($section);
692

    
693
$section = new Form_Section('Authentication');
694
$section->addClass('Authentication');
695

    
696
$group = new Form_Group('Authentication method');
697

    
698
$group->add(new Form_Checkbox(
699
	'auth_method',
700
	null,
701
	'No Authentication',
702
	$pconfig['auth_method'] == 'none',
703
	'none'
704
))->displayasRadio();
705

    
706
$group->add(new Form_Checkbox(
707
	'auth_method',
708
	null,
709
	'Local/Vouchers',
710
	$pconfig['auth_method'] == 'local',
711
	'local'
712
))->displayasRadio()->setHelp('<a href="system_usermanager.php">User Manager</a>');
713

    
714
$group->add(new Form_Checkbox(
715
	'auth_method',
716
	null,
717
	'RADIUS Authentication',
718
	$pconfig['auth_method'] == 'radius',
719
	'radius'
720
))->displayasRadio();
721

    
722
$section->add($group);
723

    
724
$section->addInput(new Form_Checkbox(
725
	'localauth_priv',
726
	null,
727
	'Allow only users/groups with "Captive portal login" privilege set',
728
	$pconfig['localauth_priv']
729
));
730

    
731
$group = new Form_Group('Radius protocol');
732

    
733
$group->add(new Form_Checkbox(
734
	'radius_protocol',
735
	null,
736
	'PAP',
737
	$pconfig['radius_protocol'] == 'PAP',
738
	'PAP'
739
))->displayasRadio();
740

    
741
$group->add(new Form_Checkbox(
742
	'radius_protocol',
743
	null,
744
	'CHAP-MD5',
745
	$pconfig['radius_protocol'] == 'CHAP_MD5',
746
	'CHAP_MD5'
747
))->displayasRadio();
748

    
749
$group->add(new Form_Checkbox(
750
	'radius_protocol',
751
	null,
752
	'MSCHAPv1',
753
	$pconfig['radius_protocol'] == 'MSCHAPv1',
754
	'MSCHAPv1'
755
))->displayasRadio();
756

    
757
$group->add(new Form_Checkbox(
758
	'radius_protocol',
759
	null,
760
	'MSCHAPv2',
761
	$pconfig['radius_protocol'] == 'MSCHAPv2',
762
	'SCHAPv2'
763
))->displayasRadio();
764

    
765
$section->add($group);
766

    
767
$form->add($section);
768

    
769
$section = new Form_Section('Primary Authentication Source');
770
$section->addClass('Primary');
771

    
772
$group = new Form_Group('Primary RADIUS server');
773

    
774
$group->add(new Form_IpAddress(
775
	'radiusip',
776
	null,
777
	$pconfig['radiusip']
778
));
779

    
780
$group->add(new Form_Input(
781
	'radiusport',
782
	null,
783
	'number',
784
	$pconfig['radiusport']
785
));
786

    
787
$group->add(new Form_Input(
788
	'radiuskey',
789
	null,
790
	'text',
791
	$pconfig['radiuskey']
792
));
793

    
794
$section->add($group);
795

    
796
$group = new Form_Group('Secondary RADIUS server');
797

    
798
$group->add(new Form_IpAddress(
799
	'radiusip2',
800
	null,
801
	$pconfig['radiusip2']
802
))->setHelp('IP address of the RADIUS server to authenticate against.');
803

    
804
$group->add(new Form_Input(
805
	'radiusport2',
806
	null,
807
	'number',
808
	$pconfig['radiusport2']
809
))->setHelp('Leave blank for default (1812)');
810

    
811
$group->add(new Form_Input(
812
	'radiuskey3',
813
	null,
814
	'text',
815
	$pconfig['radiuskey3']
816
))->setHelp('Leave blank to not use a RADIUS shared secret (not recommended)');
817

    
818
$section->add($group);
819

    
820
$form->add($section);
821

    
822
$section = new Form_Section('Secondary Authentication Source');
823
$section->addClass('Secondary');
824

    
825
$group = new Form_Group('Primary RADIUS server');
826

    
827
$group->add(new Form_IpAddress(
828
	'radiusip4',
829
	null,
830
	$pconfig['radiusip4']
831
));
832

    
833
$group->add(new Form_Input(
834
	'radiusport4',
835
	null,
836
	'number',
837
	$pconfig['radiusport4']
838
));
839

    
840
$group->add(new Form_Input(
841
	'radiuskey4',
842
	null,
843
	'text',
844
	$pconfig['radiuskey4']
845
));
846

    
847
$section->add($group);
848

    
849
$group = new Form_Group('Secondary RADIUS server');
850

    
851
$group->add(new Form_IpAddress(
852
	'radiusip',
853
	null,
854
	$pconfig['radiusip']
855
))->setHelp('IP address of the RADIUS server to authenticate against.');
856

    
857
$group->add(new Form_Input(
858
	'radiusport',
859
	null,
860
	'number',
861
	$pconfig['radiusport']
862
))->setHelp('Leave blank for default (1812)');
863

    
864
$group->add(new Form_Input(
865
	'radiuskey',
866
	null,
867
	'text',
868
	$pconfig['radiuskey']
869
))->setHelp('Leave blank to not use a RADIUS shared secret (not recommended)');
870

    
871
$section->add($group);
872
$form->add($section);
873

    
874
$section = new Form_Section('Accounting');
875
$section->addClass('Accounting');
876

    
877
$section->addInput(new Form_Checkbox(
878
	'radacct_enable',
879
	'RADIUS',
880
	'Send RADIUS accounting packets to the primary RADIUS server.',
881
	$pconfig['radacct_enable']
882
));
883

    
884
$section->addInput(new Form_Input(
885
	'radiusacctport',
886
	'Accounting Port',
887
	'text',
888
	$pconfig['radiusacctport']
889
))->setHelp('Leave blank to use the default port (1813).');
890

    
891
$group = new Form_Group('Accounting updates');
892

    
893
$group->add(new Form_Checkbox(
894
	'reauthenticateacct',
895
	null,
896
	'No Accounting updates',
897
	!$pconfig['reauthenticateacct']
898
))->displayasRadio();
899

    
900
$group->add(new Form_Checkbox(
901
	'reauthenticateacct',
902
	null,
903
	'Stop/stop Accounting',
904
	$pconfig['reauthenticateacct'] == 'stopstart'
905
))->displayasRadio();
906

    
907
$group->add(new Form_Checkbox(
908
	'reauthenticateacct',
909
	null,
910
	'Interim update',
911
	$pconfig['reauthenticateacct'] == 'interimupdate'
912
))->displayasRadio();
913

    
914
$section->add($group);
915

    
916
$form->add($section);
917

    
918
$section = new Form_Section('RADIUS options');
919
$section->addClass('Radius');
920

    
921
$section->addInput(new Form_Checkbox(
922
	'reauthenticate',
923
	'Reathentication',
924
	'Reauthenticate connected users every minute',
925
	$pconfig['reauthenticate']
926
))->setHelp('If reauthentication is enabled, Access-Requests will be sent to the RADIUS server for each user that is logged in every minute. ' .
927
			'If an Access-Reject is received for a user, that user is disconnected from the captive portal immediately.');
928

    
929
$section->addInput(new Form_Checkbox(
930
	'radmac_enable',
931
	'RADIUS MAC Authentication',
932
	'Enable RADIUS MAC authentication',
933
	$pconfig['radmac_enable']
934
))->setHelp('If this option is enabled, the captive portal will try to authenticate users by sending their MAC address as the username ' .
935
			'and the password entered below to the RADIUS server.');
936

    
937
$section->addInput(new Form_Input(
938
	'radmac_secret',
939
	'MAC authentication secret',
940
	'text',
941
	$pconfig['radmac_secret']
942
));
943

    
944
$section->addInput(new Form_Select(
945
	'radiussrcip_attribute',
946
	'RADIUS NAS IP Attribute',
947
	$pconfig['radiussrcip_attribute'],
948
	build_radiusnas_list()
949
))->setHelp('Choose the IP to use for calling station attribute.');
950

    
951
$section->addInput(new Form_Checkbox(
952
	'radiussession_timeout',
953
	'Session timeout',
954
	'Use RADIUS Session-Timeout attributes',
955
	$pconfig['radiussession_timeout']
956
))->setHelp('When enabled, clients will be disconnected after the amount of time retrieved from the RADIUS Session-Timeout attribute.');
957

    
958
$section->addInput(new Form_Select(
959
	'radiusvendor',
960
	'Type',
961
	$pconfig['radiusvendor'],
962
	['default' => 'default', 'cisco' => 'cisco']
963
))->setHelp('If RADIUS type is set to Cisco, in Access-Requests the value of Calling-Station-ID will be set to the client\'s IP address and the ' .
964
			'Called-Station-Id to the client\'s MAC address. Default behavior is Calling-Station-Id = client\'s MAC address and ' .
965
			'Called-Station-ID = pfSense\'s WAN IP address.');
966

    
967
$section->addInput(new Form_Checkbox(
968
	'reverseacct',
969
	'Accounting style',
970
	'Invert Acct-Input-Octets and Acct-Output-Octets',
971
	$pconfig['reverseacct']
972
))->setHelp('When enabled, data counts for RADIUS accounting packets will be taken from the client perspective, not the NAS. ' .
973
			'Acct-Input-Octets will represent download, and Acct-Output-Octets will represent upload.');
974

    
975
$section->addInput(new Form_Input(
976
	'radiusnasid',
977
	'NAS Identifier',
978
	'text',
979
	$pconfig['radiusnasid']
980
))->setHelp('Specify a NAS identifier to override the default value (pfSense.localdomain)');
981

    
982
$section->addInput(new Form_Select(
983
	'radmac_format',
984
	'MAC address format',
985
	$pconfig['radmac_format'],
986
	['default' => 'Default', 'singledash' => 'Single dash', 'ietf' => 'IETF', 'cisco' => 'Cisco', 'unformatted' => 'Unformatted']
987
))->setHelp('This option changes the MAC address format used in the whole RADIUS system. Change this if you also need to change the username format for ' .
988
			'RADIUS MAC authentication.' . '<br />' .
989
			'Default: 00:11:22:33:44:55' . '<br />' .
990
			'Single dash: 001122-334455' . '<br />' .
991
			'IETF: 00-11-22-33-44-55' . '<br />' .
992
			'Cisco: 0011.2233.4455' . '<br />' .
993
			'Unformatted: 001122334455');
994

    
995
$form->add($section);
996

    
997
$section = new Form_Section('HTTPS options');
998
$section->addClass('HTTPS');
999

    
1000
$section->addInput(new Form_Checkbox(
1001
	'httpslogin_enable',
1002
	'Login',
1003
	'Enable HTTPS login',
1004
	$pconfig['httpslogin_enable']
1005
))->setHelp('When enabled, the username and password will be transmitted over an HTTPS connection to protect against eavesdroppers. ' .
1006
			'A server name and certificate must also be specified below.');
1007

    
1008
$section->addInput(new Form_Input(
1009
	'httpsname',
1010
	'HTTPS server name',
1011
	'text',
1012
	$pconfig['httpsname']
1013
))->setHelp('This name will be used in the form action for the HTTPS POST and should match the Common Name (CN) in your certificate ' .
1014
			'(otherwise, the client browser will most likely display a security warning). ' .
1015
			'Make sure captive portal clients can resolve this name in DNS and verify on the client that the IP resolves to the correct interface IP on pfSense.');
1016

    
1017
$section->addInput(new Form_Select(
1018
	'certref',
1019
	'SSL Certigicate',
1020
	$pconfig['certref'],
1021
	build_cert_list()
1022
))->setHelp('If no certificates are defined, you may define one here: ' . '<a href="system_certmanager.php">System &gt; Cert Manager</a>');
1023

    
1024
$section->addInput(new Form_Checkbox(
1025
	'nohttpsforwards',
1026
	'HTTPS Forwards',
1027
	'Disable HTTPS Forwards',
1028
	$pconfig['nohttpsforwards']
1029
))->setHelp('If this option is set, attempts to connect to SSL/HTTPS (Port 443) sites will not be forwarded to the captive portal' .
1030
			'This prevents certificate errors from being presented to the user even if HTTPS logins are enabled. ' .
1031
			'Users must attempt a connecton to an HTTP (Port 80) site to get forwarded to the captive portal. ' .
1032
			'If HTTPS logins are enabled, the user will be redirected to the HTTPS login page.');
1033

    
1034
$form->add($section);
1035

    
1036
$section = new Form_Section('HTML page contents');
1037
$section->addClass('HTML');
1038

    
1039
$section->addInput(new Form_Input(
1040
	'htmlfile',
1041
	'Portal page contents',
1042
	'file',
1043
	$pconfig['htmlfile']
1044
))->setHelp('Upload an HTML/PHP file for the portal page here (leave blank to keep the current one). Make sure to include a form (POST to "$PORTAL_ACTION$") ' .
1045
			'with a submit button (name="accept") and a hidden field with name="redirurl" and value="$PORTAL_REDIRURL$". ' .
1046
			'Include the "auth_user" and "auth_pass" and/or "auth_voucher" input fields if authentication is enabled, otherwise it will always fail.' . '<br />' .
1047
			'Example code for the form:' . '<br />' .
1048
			'&lt;form method=&quot;post&quot; action=&quot;$PORTAL_ACTION$&quot;&gt;<br />
1049
			 &nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_user&quot; type=&quot;text&quot;&gt;<br />
1050
			 &nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_pass&quot; type=&quot;password&quot;&gt;<br />
1051
			 &nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_voucher&quot; type=&quot;text&quot;&gt;<br />
1052
			 &nbsp;&nbsp;&nbsp;&lt;input name=&quot;redirurl&quot; type=&quot;hidden&quot; value=&quot;$PORTAL_REDIRURL$&quot;&gt;<br />
1053
			 &nbsp;&nbsp;&nbsp;&lt;input name=&quot;accept&quot; type=&quot;submit&quot; value=&quot;Continue&quot;&gt;<br />
1054
			 &lt;/form&gt;')->addClass('btn btn-info btn-sm');
1055

    
1056
if ($pconfig['page']['htmltext']) {
1057
	$section->addInput(new Form_Button(
1058
		'btnview',
1059
		'View current page',
1060
		$href
1061
	))->removeClass('btn-primary')->addClass('btn btn-default btn-xs');
1062

    
1063
	$section->addInput(new Form_Button(
1064
		'btndownload',
1065
		'Download current page',
1066
		'?zone=' . $cpzone . '&amp;act=gethtmlhtml'
1067
	))->removeClass('btn-primary')->addClass('btn btn-info btn-xs');
1068

    
1069
	$section->addInput(new Form_Button(
1070
		'btndownload',
1071
		'Restore default portal page',
1072
		'?zone=' . $cpzone . '&amp;act=delhtmlhtml'
1073
	))->removeClass('btn-primary')->addClass('btn btn-danger btn-xs');
1074
}
1075

    
1076
$section->addInput(new Form_Input(
1077
	'errfile',
1078
	'Auth error page contents',
1079
	'file',
1080
	$pconfig['errfile']
1081
))->setHelp('The contents of the HTML/PHP file that you upload here are displayed when an authentication error occurs. ' .
1082
			'You may include "$PORTAL_MESSAGE$", which will be replaced by the error or reply messages from the RADIUS ' .
1083
			'server, if any.')->addClass('btn btn-info btn-sm');
1084

    
1085
if ($pconfig['page']['errtext']) {
1086
	$section->addInput(new Form_Button(
1087
		'btnview',
1088
		'View current page',
1089
		'?zone=' . $cpzone . '&amp;act=viewerrhtml'
1090
	))->removeClass('btn-primary')->addClass('btn btn-default btn-xs');
1091

    
1092
	$section->addInput(new Form_Button(
1093
		'btndownload',
1094
		'Download current page',
1095
		'?zone=' . $cpzone . '&amp;act=geterrhtml'
1096
	))->removeClass('btn-primary')->addClass('btn btn-info btn-xs');
1097

    
1098
	$section->addInput(new Form_Button(
1099
		'btndownload',
1100
		'Restore default portal page',
1101
		'?zone=' . $cpzone . '&amp;act=delerrhtml'
1102
	))->removeClass('btn-primary')->addClass('btn btn-danger btn-xs');
1103
}
1104

    
1105
$section->addInput(new Form_Input(
1106
	'logoutfile',
1107
	'Logout page contents',
1108
	'file',
1109
	$pconfig['logoutfile']
1110
))->setHelp('The contents of the HTML/PHP file that you upload here are displayed on authentication success when the logout popup is enabled.')->addClass('btn btn-info btn-sm');
1111

    
1112
if ($pconfig['page']['logouttext']) {
1113
	$section->addInput(new Form_Button(
1114
		'btnview',
1115
		'View current page',
1116
		'?zone=' . $cpzone . '&amp;act=viewlogouthtml'
1117
	))->removeClass('btn-primary')->addClass('btn btn-default btn-xs');
1118

    
1119
	$section->addInput(new Form_Button(
1120
		'btndownload',
1121
		'Download current page',
1122
		'?zone=' . $cpzone . '&amp;act=getlogouthtml'
1123
	))->removeClass('btn-primary')->addClass('btn btn-info btn-xs');
1124

    
1125
	$section->addInput(new Form_Button(
1126
		'btndownload',
1127
		'Restore default portal page',
1128
		'?zone=' . $cpzone . '&amp;act=dellogouthtml'
1129
	))->removeClass('btn-primary')->addClass('btn btn-danger btn-xs');
1130
}
1131
$section->addInput(new Form_Input(
1132
	'zone',
1133
	null,
1134
	'hidden',
1135
	$cpzone
1136
));
1137

    
1138
$form->add($section);
1139
print($form);
1140

    
1141
print_info_box(gettext('Warning:' . '<br />' . 'Changing any settings on this page will disconnect all clients! ' .
1142
					   'Don\'t forget to enable the DHCP server on your captive portal interface! ' .
1143
					   'Make sure that the default/maximum DHCP lease time is higher than the timeout entered on this page. ' .
1144
					   'Also, the DNS forwarder needs to be enabled for DNS lookups by unauthenticated clients to work.'));
1145

    
1146
?>
1147

    
1148
<script type="text/javascript">
1149
//<![CDATA[
1150
events.push(function(){
1151
	//---------- "Standard" show/hide functions ---------------------------------------------------
1152

    
1153
	// Hides all elements of the specified class. This will usually be a section or group
1154
	function hideClass(s_class, hide) {
1155
		if(hide)
1156
			$('.' + s_class).hide();
1157
		else
1158
			$('.' + s_class).show();
1159
	}
1160

    
1161
	// Hides all elements of the specified class belonging to a multiselect.
1162
	function hideMultiClass(s_class, hide) {
1163
		if(hide)
1164
			$('.' + s_class).parent().parent().hide();
1165
		else
1166
			$('.' + s_class).parent().parent().show();
1167
	}
1168

    
1169
	// Hides the <div> in which the specified input element lives so that the input, its label and help text are hidden
1170
	function hideInput(id, hide) {
1171
		if(hide)
1172
			$('#' + id).parent().parent('div').addClass('hidden');
1173
		else
1174
			$('#' + id).parent().parent('div').removeClass('hidden');
1175
	}
1176

    
1177
	// Hides the <div> in which the specified checkbox lives so that the checkbox, its label and help text are hidden
1178
	function hideCheckbox(id, hide) {
1179
		if(hide)
1180
			$('#' + id).parent().parent().parent('div').addClass('hidden');
1181
		else
1182
			$('#' + id).parent().parent().parent('div').removeClass('hidden');
1183
	}
1184

    
1185
	// Disables the specified input element
1186
	function disableInput(id, disable) {
1187
		$('#' + id).prop("disabled", disable);
1188
	}
1189

    
1190
	// ------- Show/hide sections based on checkbox settings --------------------------------------
1191
	function hideSections(hide) {
1192
		hideClass('Authentication', hide);
1193
		hideRadius();
1194
		hideHTTPS();
1195
		hideClass('HTTPS', hide);
1196
		hideClass('HTML', hide);
1197
		hideGeneral(hide)
1198
	}
1199

    
1200
	function hideRadius() {
1201
		hide = (!$('#enable').prop('checked') || (!($('input[name="auth_method"]:checked').val() == 'radius')));
1202

    
1203
		hideClass('Primary', hide);
1204
		hideClass('Secondary', hide);
1205
		hideClass('Accounting', hide);
1206
		hideClass('Radius', hide);
1207

    
1208
		disableInput('localauth_priv', !($('input[name="auth_method"]:checked').val() == 'local'));
1209
	}
1210

    
1211
	function hideHTTPS() {
1212
		hide = (!$('#httpslogin_enable').prop('checked') || !$('#enable').prop('checked'));
1213

    
1214
		hideInput('httpsname', hide);
1215
		hideInput('certref', hide);
1216
		hideCheckbox('nohttpsforwards', hide);
1217
	}
1218

    
1219
	function hideGeneral(hide) {
1220
		hideMultiClass('general', hide);
1221
		hideInput('maxprocperip', hide);
1222
		hideInput('idletimeout', hide);
1223
		hideInput('timeout', hide);
1224
		hideInput('freelogins_count', hide);
1225
		hideCheckbox('freelogins_updatetimeouts', hide);
1226
		hideCheckbox('logoutwin_enable', hide);
1227
		hideInput('preauthurl', hide);
1228
		hideInput('redirurl', hide);
1229
		hideInput('blockedmacsurl', hide);
1230
		hideCheckbox('noconcurrentlogins', hide);
1231
		hideCheckbox('nomacfilter', hide);
1232
		hideCheckbox('passthrumacadd', hide);
1233
		hideCheckbox('passthrumacaddusername', hide);
1234
		hideCheckbox('peruserbw', hide);
1235
		hideInput('bwdefaultdn', hide);
1236
		hideInput('bwdefaultup', hide);
1237
	}
1238

    
1239
	// ---------- Click checkbox handlers ---------------------------------------------------------
1240
	$("#enable").click(function() {
1241
		hideSections(!this.checked);
1242
	});
1243

    
1244
	$('input[name="auth_method"]').on('change', function() {
1245
		hideRadius();
1246
	});
1247

    
1248

    
1249
	$("#httpslogin_enable").click(function() {
1250
		hideHTTPS(!this.checked);
1251
	});
1252

    
1253
	// ---------- On itial page load --------------------------------------------------------------
1254
	hideSections(!$('#enable').prop('checked'));
1255
	disableInput('localauth_priv', !($('input[name="auth_method"]:checked').val() == 'local'));
1256
});
1257
//]]>
1258
</script>
1259

    
1260
<?php include("foot.inc");
(121-121/238)