Project

General

Profile

« Previous | Next » 

Revision 5ed493d8

Added by Viktor Gurov about 5 years ago

Block additional Captive Portal Logins. Implements #9432

View differences:

src/etc/inc/captiveportal.inc
2355 2355
	$writecfg = false;
2356 2356
	/* If both "Add MAC addresses of connected users as pass-through MAC" and "Disable concurrent logins" are checked,
2357 2357
	then we need to check if the user was already authenticated using another MAC Address, and if so remove the previous Pass-Through MAC. */
2358
	if ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated') && isset($config['captiveportal'][$cpzone]['passthrumacadd'])) {
2358
	if ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($config['captiveportal'][$cpzone]['noconcurrentlogins'] == 'last') && ($username != 'unauthenticated') && isset($config['captiveportal'][$cpzone]['passthrumacadd'])) {
2359 2359
		$mac = captiveportal_passthrumac_findbyname($username);
2360 2360
		if (!empty($mac)) {
2361 2361
			foreach ($config['captiveportal'][$cpzone]['passthrumac'] as $idx => $macent) {
......
2395 2395
	$unsetindexes = array();
2396 2396

  
2397 2397
	foreach ($cpdb as $cpentry) {
2398
		captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "Entering for each loop $username = {$username}");	
2399
		if (isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) {
2400
			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "config['captiveportal'][$cpzone]['noconcurrentlogins'] exists = set");	
2401
		} else {
2402
			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "config['captiveportal'][$cpzone]['noconcurrentlogins'] does not exists = NOT set");
2403
		}
2398 2404
		/* on the same ip */
2399 2405
		if ($cpentry[2] == $clientip) {
2400 2406
			if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) {
......
2412 2418
				$remaining_time = 0;
2413 2419
			}
2414 2420

  
2415
			/* This user was already logged in so we disconnect the old one */
2416
			captiveportal_disconnect($cpentry, 13);
2417
			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
2418
			$unsetindexes[] = $cpentry[5];
2419
			break;
2420
		} elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
2421
			/* on the same username */
2422
			if (strcasecmp($cpentry[4], $username) == 0) {
2423
				/* This user was already logged in so we disconnect the old one */
2421
			/* This user was already logged in so we disconnect the old one, or 
2422
			keep the old one, refusing the new login, or
2423
			allow the login */
2424

  
2425
			if (!isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) {
2426
				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "config['captiveportal'][$cpzone]['noconcurrentlogins'] 2 does not exists = NOT set");		
2427
			} else {
2428
				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "config['captiveportal'][$cpzone]['noconcurrentlogins'] 2 exists = set");		
2429
			}
2430

  
2431
			if ($config['captiveportal'][$cpzone]['noconcurrentlogins'] == "last") {
2432
				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "Found last");
2433
			} else {
2434
				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "Found NOT last");
2435
			}
2436
				
2437
			if (!isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) {
2438
				/* 'noconcurrentlogins' not set : accept login 'username' creating multiple sessions. */
2439
				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "config['captiveportal'][$cpzone]['noconcurrentlogins'] 3 does not exists = NOT set");
2440
				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - NOT TERMINATING EXISTING SESSION(S)");			
2441
			} elseif ($config['captiveportal'][$cpzone]['noconcurrentlogins'] == "last") {
2442
				/* Classic situation : accept the new login, disconnect the old - present - connection */
2443
				if (isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) {
2444
					captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "config['captiveportal'][$cpzone]['noconcurrentlogins'] 4 exists = set");		
2445
				} else {
2446
					captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "config['captiveportal'][$cpzone]['noconcurrentlogins'] 4 does not exists = NOT set");		
2447
				}
2448
				
2424 2449
				captiveportal_disconnect($cpentry, 13);
2425 2450
				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
2426 2451
				$unsetindexes[] = $cpentry[5];
2427 2452
				break;
2453
			} else {
2454
				/* Implicit 'first' : refuse the new login - 'username' is already logged in */
2455
				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT VOUCHER LOGIN - NOT ALLOWED KEEPING OLD SESSION ");
2456
				unlock($cpdblck);
2457
				return 2;
2458
			}
2459
		} elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
2460
			if ($config['captiveportal'][$cpzone]['noconcurrentlogins'] == "last") {
2461
				/* on the same username */
2462
				if (strcasecmp($cpentry[4], $username) == 0) {
2463
					/* This user was already logged in so we disconnect the old one */
2464
					captiveportal_disconnect($cpentry, 13);
2465
					captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT USER LOGIN - TERMINATING OLD SESSION");
2466
					$unsetindexes[] = $cpentry[5];
2467
					break;
2468
				}
2469
			} else {
2470
				/* Implicit 'first' : refuse the new login - 'username' is already logged in */
2471
				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT USER LOGIN - NOT ALLOWED KEEPING OLD SESSION ");
2472
				unlock($cpdblck);
2473
				return 2;				
2428 2474
			}
2429 2475
		}
2430 2476
	}
src/usr/local/captiveportal/index.php
170 170
			'voucher' => 1,
171 171
			'session_timeout' => $timecredit*60,
172 172
			'session_terminate_time' => 0);
173
		if (portal_allow($clientip, $clientmac, $voucher, null, $redirurl, $attr, null, 'voucher', 'voucher')) {
173
		if (portal_allow($clientip, $clientmac, $voucher, null, $redirurl, $attr, null, 'voucher', 'voucher') === 2) {
174
			portal_reply_page($redirurl, "error", "Reuse of identification not allowed.");
175
		} elseif (portal_allow($clientip, $clientmac, $voucher, null, $redirurl, $attr, null, 'voucher', 'voucher')) {
174 176
			// YES: user is good for $timecredit minutes.
175 177
			captiveportal_logportalauth($voucher, $clientmac, $clientip, "Voucher login good for $timecredit min.");
176 178
		} else {
src/usr/local/www/services_captiveportal.php
46 46
global $cpzone;
47 47
global $cpzoneid;
48 48

  
49
$concurrentlogins_list = array("disabled" => "Disabled", "multiple" => "Multiple", "last" => "Last login", "first" => "First login");
49 50
$cpzoneid = 1; /* Just a default */
50 51
$cpzone = $_REQUEST['zone'];
51 52

  
......
142 143
	$pconfig['bwdefaultdn'] = $a_cp[$cpzone]['bwdefaultdn'];
143 144
	$pconfig['bwdefaultup'] = $a_cp[$cpzone]['bwdefaultup'];
144 145
	$pconfig['nomacfilter'] = isset($a_cp[$cpzone]['nomacfilter']);
145
	$pconfig['noconcurrentlogins'] = isset($a_cp[$cpzone]['noconcurrentlogins']);
146
	if (isset($a_cp[$cpzone]['noconcurrentlogins'])) {
147
		if (!empty($a_cp[$cpzone]['noconcurrentlogins'])) {
148
			$pconfig['noconcurrentlogins'] = $a_cp[$cpzone]['noconcurrentlogins'];
149
		} else {
150
			$pconfig['noconcurrentlogins'] = 'disabled';
151
		}
152
	} else {
153
		$pconfig['noconcurrentlogins'] = 'multiple';
154
	}
146 155
	$pconfig['redirurl'] = $a_cp[$cpzone]['redirurl'];
147 156
	$pconfig['radiussession_timeout'] = isset($a_cp[$cpzone]['radiussession_timeout']);
148 157
	$pconfig['radiustraffic_quota'] = isset($a_cp[$cpzone]['radiustraffic_quota']);
......
278 287
		}
279 288
	}
280 289

  
290
	if (isset($_POST['noconcurrentlogins']) && !in_array($_POST['noconcurrentlogins'], array_keys($concurrentlogins_list))) {
291
		$input_errors[] = gettext("You need to select an option for Concurrent user logins.");
292
	}
293

  
281 294
	if (isset($_POST['radacct_enable']) && empty(auth_get_authserver($_POST['radacct_server']))) {
282 295
		$input_errors[] = gettext("You need to select at least one accounting server.");
283 296
	}
......
373 386
		$newcp['nohttpsforwards'] = $_POST['nohttpsforwards'] ? true : false;
374 387
		$newcp['logoutwin_enable'] = $_POST['logoutwin_enable'] ? true : false;
375 388
		$newcp['nomacfilter'] = $_POST['nomacfilter'] ? true : false;
376
		$newcp['noconcurrentlogins'] = $_POST['noconcurrentlogins'] ? true : false;
389
		if ($_POST['noconcurrentlogins'] == 'multiple') {
390
			unset($newcp['noconcurrentlogins']);
391
		} elseif ($_POST['noconcurrentlogins'] == 'disabled') {
392
			$newcp['noconcurrentlogins'] = true;
393
		} else {
394
			$newcp['noconcurrentlogins'] = $_POST['noconcurrentlogins'];
395
		}
377 396
		$newcp['redirurl'] = $_POST['redirurl'];
378 397
		$newcp['radiussession_timeout'] = $_POST['radiussession_timeout'] ? true : false;
379 398
		$newcp['radiustraffic_quota'] = $_POST['radiustraffic_quota'] ? true : false;
......
633 652
	))->setHelp("If enabled, connected users won't be disconnected during a pfSense reboot.");
634 653
}
635 654

  
636
$section->addInput(new Form_Checkbox(
655
$section->addInput(new Form_Select(
637 656
	'noconcurrentlogins',
638 657
	'Concurrent user logins',
639
	'Disable Concurrent user logins',
640
	$pconfig['noconcurrentlogins']
641
))->setHelp('If enabled only the most recent login per username will be active. Subsequent logins will cause machines previously logged in with the ' .
642
			'same username to be disconnected.');
658
	$pconfig['noconcurrentlogins'],
659
	$concurrentlogins_list
660
))->setHelp('Disabled: Do not allow concurrent logins per username or voucher.%1$s' .
661
			'Multiple: No restrictions to the number of logins per username or voucher will be applied.%1$s' .
662
			'Last login: Only the most recent login per username or voucher will be granted. ' .
663
			'Previous logins will be disconnected.%1$s' .
664
			'First login: Only the first login per username or voucher will be granted. ' .
665
			'Further login attempts using the username or voucher will not be possible while an initial user is already active.', '<br />');
643 666

  
644 667
$section->addInput(new Form_Checkbox(
645 668
	'nomacfilter',
......
1178 1201
		hideInput('preauthurl', hide);
1179 1202
		hideInput('redirurl', hide);
1180 1203
		hideInput('blockedmacsurl', hide);
1204
		hideInput('noconcurrentlogins', hide);
1181 1205
		hideCheckbox('preservedb', hide);
1182 1206
		hideCheckbox('preservedb_disabled', hide);
1183
		hideCheckbox('noconcurrentlogins', hide);
1184 1207
		hideCheckbox('nomacfilter', hide);
1185 1208
		hideCheckbox('passthrumacadd', hide);
1186 1209
		hideCheckbox('peruserbw', hide);

Also available in: Unified diff