Project

General

Profile

Feature #15904 » index-2411-Dec11.php

Dale Harron, 12/12/2024 12:55 AM

 
1
<?php
2
/*
3
 * index.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2024 Rubicon Communications, LLC (Netgate)
9
 * All rights reserved.
10
 *
11
 * Originally part of m0n0wall (http://m0n0.ch/wall)
12
 * Copyright (c) 2003-2006 Manuel Kasper <mk@neon1.net>.
13
 * All rights reserved.
14
 *
15
 * Licensed under the Apache License, Version 2.0 (the "License");
16
 * you may not use this file except in compliance with the License.
17
 * You may obtain a copy of the License at
18
 *
19
 * http://www.apache.org/licenses/LICENSE-2.0
20
 *
21
 * Unless required by applicable law or agreed to in writing, software
22
 * distributed under the License is distributed on an "AS IS" BASIS,
23
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
 * See the License for the specific language governing permissions and
25
 * limitations under the License.
26
 */
27

    
28
require_once("auth.inc");
29
require_once("util.inc");
30
require_once("functions.inc");
31
require_once("captiveportal.inc");
32

    
33
header("Expires: 0");
34
header("Cache-Control: no-cache, no-store, must-revalidate");
35
header("Connection: close");
36

    
37
global $cpzone, $cpzoneid, $cpzoneprefix;
38

    
39
$cpzone = strtolower($_REQUEST['zone']);
40
$cpcfg = config_get_path("captiveportal/{$cpzone}", []);
41

    
42
/* NOTE: IE 8/9 is buggy and that is why this is needed */
43
$orig_request = trim($_REQUEST['redirurl'], " /");
44

    
45
/* If the post-auth redirect is set, always use it. Otherwise take what was supplied in URL. */
46
if (!empty($cpcfg) && is_URL($cpcfg['redirurl'], true)) {
47
	$redirurl = $cpcfg['redirurl'];
48
} elseif (preg_match("/redirurl=(.*)/", $orig_request, $matches)) {
49
	$redirurl = urldecode($matches[1]);
50
} elseif ($_REQUEST['redirurl']) {
51
	$redirurl = $_REQUEST['redirurl'];
52
}
53
/* Sanity check: If the redirect target is not a URL, do not attempt to use it like one. */
54
if (!is_URL(urldecode($redirurl), true)) {
55
	$redirurl = "";
56
}
57

    
58
if (empty($cpcfg)) {
59
	log_error("Submission to captiveportal with unknown parameter zone: " . htmlspecialchars($cpzone));
60
	portal_reply_page($redirurl, "error", gettext("Internal error"));
61
	ob_flush();
62
	return;
63
}
64

    
65
$cpzoneid = $cpcfg['zoneid'];
66
$cpzoneprefix = CPPREFIX . $cpzoneid;
67
$orig_host = $_SERVER['HTTP_HOST'];
68
$clientip = $_SERVER['REMOTE_ADDR'];
69

    
70
if (!$clientip) {
71
	/* not good - bail out */
72
	log_error("Zone: {$cpzone} - Captive portal could not determine client's IP address.");
73
	$errormsg = gettext("An error occurred.  Please check the system logs for more information.");
74
	portal_reply_page($redirurl, "error", $errormsg);
75
	ob_flush();
76
	return;
77
}
78

    
79
$ourhostname = portal_hostname_from_client_ip($clientip);
80
$protocol = (config_path_enabled("captiveportal/{$cpzone}", "httpslogin")) ? 'https://' : 'http://';
81
$logouturl = "{$protocol}{$ourhostname}/";
82

    
83
$cpsession = captiveportal_isip_logged($clientip);
84
if (!empty($cpsession)) {
85
  $sessionid = $cpsession['sessionid'];
86
}
87

    
88
/* ----------------------CUSTOM CODE -------------------------------------------------------------------------
89
        Index.php Custom Code for Kea DHCP, check MAC address instead of IP to verify a sesson ID exists
90
              Kea flushes the IP quickly after the client disconnects, creating IP/MAC conflicts 
91
              within the captive portal database of validated clients.  
92
              It is the MAC that it validated, not the IP as IP changes frequently
93
        This code matches the current IP to the MAC in the database and Reconnects users to the Portal
94
        so that the corrected login immediately works.   Dale Harron, 10 December 2024. 
95
------------------------------------------------------------------------------------------------------------- */
96

    
97
$dbchanged = "no";
98

    
99
$ARPforIP = shell_exec("arp '$clientip'");
100
$clientmac = substr($ARPforIP, 17, 24);
101
if (preg_match('/([a-fA-F0-9]{2}[:|\-]?){6}/', "'{$clientmac}'", $matches)) {
102
    $clientmac = $matches[0];
103
}
104

    
105
/* query the cp database for this client MAC address to see if it is already authorized */
106
$query = "WHERE mac = '{$clientmac}'";
107
$cpdbqry = captiveportal_read_db($query);
108
foreach ($cpdbqry as $cpentrymac) {
109
  $cpsessionmac = $cpentrymac;
110
}
111
$sessionidmac = $cpentrymac[5];
112
$cpdbip = $cpentrymac[2];
113
$cpdbmac = $cpentrymac[3];
114

    
115
//  captiveportal_logportalauth($clientmac, $cpdbmac, $cpdbip, $clientip, $clientmac . "=" . $cpdbmac . "=" . $clientip . "=" . $cpdbip . "=" . $clientmac);
116
//  $dbchanged = "yes";
117
if( ($clientip <> $cpdbip) && ($cpdbmac == $clientmac)) {
118
  // Next update the IP in the Captive Portal database for the authorized MAC of this device
119
  $updt_field = "ip";
120
  $new_value = "'{$clientip}'";
121
  captiveportal_write_db("UPDATE captiveportal SET {$updt_field} = {$new_value} WHERE sessionid = '{$sessionidmac}'");
122
  $dbchanged = "yes";
123
}  
124

    
125
unset($cpdbqry);
126

    
127

    
128
// If this is a new MAC that has an authorized IP but is not yet authorized itself, change the IP in the cp database to OFFLINE.
129
// This will retain the old MAC's authorization and free up the IP to be assigned to this device's MAC; present the login page.
130

    
131
/* query the cp database for this client IP address to see if it is already associated with an authorized MAC*/
132
$query = "WHERE ip = '{$clientip}'";
133
$cpdbqry = captiveportal_read_db($query);
134
foreach ($cpdbqry as $cpentryip) {
135
  $cpsessionip = $cpentryip;
136
}
137
$sessionidip = $cpentryip[5];
138
$cpdbip = $cpentryip[2];
139

    
140
if (!$cpdbmac && $cpdbip == $clientip) {
141
  $updt_field = 'ip';
142
  $new_value_tmp = "OFFLINE";
143
  $new_value = "'{$new_value_tmp}'";
144
  captiveportal_write_db("UPDATE captiveportal SET {$updt_field} = {$new_value} WHERE sessionid = '{$sessionid}'");
145
  $dbchanged = "yes";
146
}
147
unset($cpdbqry);
148

    
149

    
150
/*
151
//For Testing, Enable changing CP database IP
152
// Disconnect device with first client IP from cp, fill in the existing temp IP and new value IP
153
//uncomment the top and bottom comment out block, save and log into the client IP system.  Recomment the test code
154

    
155
if ($clientip == "192.168.50.8") {
156

    
157
  $tempip = "192.168.50.2";
158
  $query = "WHERE ip = '{$tempip}'";
159
  $cpdbqry = captiveportal_read_db($query);
160
  foreach ($cpdbqry as $cpentryip) {
161
    $cpsession = $cpentryip;
162
  }
163
  $sessionidtmp = $cpentryip[5];
164
  $clientiptmp = $cpentryip[2];
165
  $clientmactmp = $cpentryip[3];
166
  $updt_field = 'ip';
167
  $new_value_tmp = "192.168.50.99";
168
  $new_value = "'{$new_value_tmp}'";
169
  captiveportal_write_db("UPDATE captiveportal SET {$updt_field} = {$new_value} WHERE sessionid = '{$sessionidtmp}'");
170
  $dbchanged = "yes";
171
  $sessionid=$sessionidtmp;
172
  unset($cpdbqry);
173
  captiveportal_logportalauth($clientmac, $clientmactmp, $clientip, $clientiptmp, $clientmact . "=" . $clientmactmp . "=" . $clientip . "=" . $clientiptmp . "=" . $clientmac);
174
}
175
*/
176

    
177
/*
178
//For Testing, Enable changing CP database MAC
179
// Disconnect device with first client IP from cp, fill in the existing temp IP and new value IP
180
//uncomment the top and bottom comment out block, save and log into the client IP system.  Recomment the test code
181

    
182
if ($clientip == "192.168.50.8") {
183

    
184
  $tempmac = "9c:fc:e8:9f:3e:22";
185
  $tempip = "OFFLINE";
186
  $query = "WHERE ip = '{$tempip}'";
187
  $cpdbqry = captiveportal_read_db($query);
188
  foreach ($cpdbqry as $cpentryip) {
189
    $cpsession = $cpentryip;
190
  }
191
  $sessionidtmp = $cpentryip[5];
192
  $clientiptmp = $cpentryip[2];
193
  $clientmactmp = $cpentryip[3];
194
  $updt_field = 'mac';
195
  $new_value_tmp = $tempmac;
196
  $new_value = "'{$new_value_tmp}'";
197
  captiveportal_write_db("UPDATE captiveportal SET {$updt_field} = {$new_value} WHERE sessionid = '{$sessionidtmp}'");
198
  $dbchanged = "yes";
199
  $sessionid=$sessionidtmp;
200
  unset($cpdbqry);
201
  captiveportal_logportalauth($clientmactmp, $tempmac, $clientiptmp, $clientip, $clientmactmp . "=" . $tempmac . "=" . $clientiptmp . "=" . $clientip . "=" . $clientmac);
202
}
203
*/
204

    
205

    
206
/* If this MAC/IP pair does not match the MAC/IP in the Captive Portal database, then the IP has changed */
207
/* update the Captive Portal database to associate the current IP with this already authorized MAC  */
208
/* Note, this could result in multiple IP/MAC pairs of the same IP in the Captive Portal database. Repair all invalid conflicts */
209

    
210
        if(($cpidmac <> $clientmac) && ($cpdbip == $clientip)) {  
211
	  //Remove IP conflicts assigned to other MACs in the Captive Portal Database
212
	  $query = "WHERE ip = '{$clientip}'";
213
	  $cpdb_ip = captiveportal_read_db($query);
214
	  foreach ($cpdb_ip as $cpentryip) {
215
            $cpsessionip = $cpentryip;
216
	    $sessionidip = $cpsessionip['sessionid'];
217
            $updt_field = "ip";
218
	    $unassignip = 'OFFLINE';
219
            $new_value = "'{$unassignip}'";
220
	    if($clientmac <> $cpentryip[3]) {
221
               captiveportal_write_db("UPDATE captiveportal SET {$updt_field} = {$new_value} WHERE sessionid = '{$sessionidip}'");
222
	       $dbchanged = "yes";
223
captiveportal_logportalauth($clientmac, $cpdbmac, $clientip, $cpdbip, $clientmac . "=" . $cpdbmac . "=" . $clientip . "=" . $cpdbip . "=" . $clientmac);
224
	    }
225
            unset($cpdb_ip);
226
          }
227
	}
228

    
229

    
230

    
231

    
232
//If the Database has been updated, reload the database for this zone.
233
if( $dbchanged == "yes" ) {
234
  //Now reload this database with these changes to make them active
235
  if (isset($cpcfg['preservedb']) || $reload_rules ||
236
    captiveportal_xmlrpc_sync_get_details($syncip, $syncport, $syncuser, $syncpass)) {
237
    $connected_users = captiveportal_read_db();
238
    if (!empty($connected_users)) {
239
      //echo "Reconnecting users to captive portal {$cpcfg['zone']}... ";
240
      foreach ($connected_users as $user) {
241
      captiveportal_reserve_ruleno($user['pipeno']);
242
      captiveportal_ether_configure_entry($user, 'auth', true);
243
      }
244
    //echo "done\n";
245
    }
246
    $cpsession = captiveportal_isip_logged($clientip);
247
    if (!empty($cpsession)) {
248
      $sessionid = $cpsession['sessionid'];
249
    }
250
  }
251
}
252

    
253
//captiveportal_logportalauth($clientmac, $cpdbmac, $clientip, $cpdbip, $clientmac . "=" . $cpdbmac . "=" . $clientip . "=" . $cpdbip . "=" . $clientmac);
254

    
255
/* ----------- End Custom Code  ----------- */
256

    
257
/* Automatically switching to the logout page requires a custom logout page to be present. */
258
if ((!empty($cpsession)) && (! $_POST['logout_id']) && (!empty($cpcfg['page']['logouttext']))) {
259
	/* if client already connected and a custom logout page is set : show logout page */
260
	$attributes = array();
261
	if (!empty($cpsession['session_timeout']))
262
		$attributes['session_timeout'] = $cpsession['session_timeout'];
263
	if (!empty($cpsession['session_terminate_time']))
264
		$attributes['session_terminate_time'] = $cpsession['session_terminate_time'];
265

    
266
	include("{$g['varetc_path']}/captiveportal-{$cpzone}-logout.html");
267
	ob_flush();
268
	return;
269
} elseif (!empty($cpsession) && !isset($_POST['logout_id'])) {
270
	/* If the client tries to access the captive portal page while already connected,
271
		but no custom logout page exists */
272
	$logo_src = "{$protocol}{$ourhostname}/" . get_captive_portal_logo();
273
	$bg_src = get_captive_portal_bg();
274
?>
275
<!DOCTYPE html>
276
<html>
277
<head>
278
  <meta charset="UTF-8">
279
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
280
  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
281
  <title>Captive Portal</title>
282
  <style>
283
	  #content,.login,.login-card a,.login-card h1,.login-help{text-align:center}body,html{margin:0;padding:0;width:100%;height:100%;display:table}#content{font-family:'Source Sans Pro',sans-serif;background-color:#1C1275;background:<?= $bg_src ?>;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;display:table-cell;vertical-align:middle}.login-card{padding:40px;width:280px;background-color:#F7F7F7;margin:100px auto 10px;border-radius:2px;box-shadow:0 2px 2px rgba(0,0,0,.3);overflow:hidden}.login-card h1{font-weight:400;font-size:2.3em;color:#1383c6}.login-card h1 span{color:#f26721}.login-card img{width:70%;height:70%}.login-card input[type=submit]{width:100%;display:block;margin-bottom:10px;position:relative}.login-card input[type=text],input[type=password]{height:44px;font-size:16px;width:100%;margin-bottom:10px;-webkit-appearance:none;background:#fff;border:1px solid #d9d9d9;border-top:1px solid silver;padding:0 8px;box-sizing:border-box;-moz-box-sizing:border-box}.login-card input[type=text]:hover,input[type=password]:hover{border:1px solid #b9b9b9;border-top:1px solid #a0a0a0;-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.login{font-size:14px;font-family:Arial,sans-serif;font-weight:700;height:36px;padding:0 8px}.login-submit{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;color:#fff;text-shadow:0 1px rgba(0,0,0,.1);background-color:#4d90fe}.login-submit:disabled{opacity:.6}.login-submit:hover{border:0;text-shadow:0 1px rgba(0,0,0,.3);background-color:#357ae8}.login-card a{text-decoration:none;color:#222;font-weight:400;display:inline-block;opacity:.6;transition:opacity ease .5s}.login-card a:hover{opacity:1}.login-help{width:100%;font-size:12px}.list{list-style-type:none;padding:0}.list__item{margin:0 0 .7rem;padding:0}label{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;text-align:left;font-size:14px;}input[type=checkbox]{-webkit-box-flex:0;-webkit-flex:none;-ms-flex:none;flex:none;margin-right:10px;float:left}@media screen and (max-width:450px){.login-card{width:70%!important}.login-card img{width:30%;height:30%}}textarea{width:66%;margin:auto;height:120px;max-height:120px;background-color:#f7f7f7;padding:20px}#terms{display:none;padding-top:100px;padding-bottom:300px;}.auth_source{border: 1px solid lightgray; padding:20px 8px 0px 8px; margin-top: -2em; border-radius: 2px; }.auth_head{background-color:#f7f7f7;display:inline-block;}.auth_head_div{text-align:left;}#error-message{text-align:left;color:#ff3e3e;font-style:italic;}
284
  </style>
285
</head>
286

    
287
<body>
288
<div id="content">
289
	<div class="login-card">
290
		<img src="<?= $logo_src ?>"/><br>
291
		<h1></h1>
292
		<div class="login-help">
293
			<?= gettext("The portal session is connected.") ?>
294
<?php if (!empty($redirurl)):
295
		$redirurl = htmlspecialchars($redirurl); ?>
296
			<br/><br/>
297
			<?= gettext("Proceed to: ") ?>
298
			<a href="<?=$redirurl?>"><?=$redirurl?></a>
299
<?php endif; ?>
300
		</div>
301
<br/>
302
	<form method="POST" action="<?=$logouturl;?>">
303
		<input name="logout_id" type="hidden" value="<?=$sessionid;?>" />
304
		<input name="zone" type="hidden" value="<?=$cpzone;?>" />
305
		<input name="logout" type="submit" value="<?= gettext("Disconnect") ?>" />
306
	</form>
307
	<br  />
308
	<span> <i>Made with &hearts; by</i> <strong>Netgate</strong></span>
309
	</div>
310
</div>
311
</body>
312
</html>
313
<?php
314
	ob_flush();
315
	return;
316
} elseif ($orig_host != $ourhostname) {
317
	/* the client thinks it's connected to the desired web server, but instead
318
	   it's connected to us. Issue a redirect... */
319
	$protocol = (isset($cpcfg['httpslogin'])) ? 'https://' : 'http://';
320
	header("Location: {$protocol}{$ourhostname}/index.php?zone={$cpzone}&redirurl=" . urlencode("http://{$orig_host}/{$orig_request}"));
321

    
322
	ob_flush();
323
	return;
324
}
325

    
326
/* find MAC address for client */
327
$tmpres = pfSense_ip_to_mac($clientip);
328
if (!is_array($tmpres)) {
329
	if (!isset($cpcfg['nomacfilter']) || isset($cpcfg['passthrumacadd'])) {
330
		/* unable to find MAC address - shouldn't happen! - bail out */
331
		captiveportal_logportalauth("unauthenticated", "noclientmac", $clientip, "ERROR");
332
		echo "An error occurred.  Please check the system logs for more information.";
333
		log_error("Zone: {$cpzone} - Captive portal could not determine client's MAC address.  Disable MAC address filtering in captive portal if you do not need this functionality.");
334
		ob_flush();
335
		return;
336
	}
337
} else {
338
	/* always save MAC address in DB to allow macfilter/nomacfilter switching without flushing all clients */
339
	$clientmac = $tmpres['macaddr'];
340
}
341
unset($tmpres);
342

    
343
if ($_POST['logout_id']) {
344
	$safe_logout_id = SQLite3::escapeString($_POST['logout_id']);
345
	captiveportal_disconnect_client($safe_logout_id);
346
	header("Location: index.php?zone=" . $cpzone);
347
	ob_flush();
348
	return;
349
} elseif (($_POST['accept'] || $cpcfg['auth_method'] === 'radmac' || !empty($cpcfg['blockedmacsurl'])) && !isset($cpcfg['nomacfilter']) && $clientmac && captiveportal_blocked_mac($clientmac)) {
350
	captiveportal_logportalauth($clientmac, $clientmac, $clientip, "Blocked MAC address");
351
	if (!empty($cpcfg['blockedmacsurl'])) {
352
		portal_reply_page($cpcfg['blockedmacsurl'], "redir");
353
	} else {
354
		if ($cpcfg['auth_method'] === 'radmac') {
355
			echo gettext("This MAC address has been blocked");
356
		} else {
357
			portal_reply_page($redirurl, "error", "This MAC address has been blocked", $clientmac, $clientip);
358
		}
359
	}
360
} elseif (portal_consume_passthrough_credit($clientmac)) {
361
	/* allow the client through if it had a pass-through credit for its MAC */
362
	captiveportal_logportalauth("unauthenticated", $clientmac, $clientip, "ACCEPT");
363
	portal_allow($clientip, $clientmac, "unauthenticated", null, $redirurl);
364

    
365
} elseif (config_path_enabled("voucher/{$cpzone}") && ($_POST['accept'] && $_POST['auth_voucher']) || $_GET['voucher']) {
366
	if (isset($_POST['auth_voucher'])) {
367
		$voucher = trim($_POST['auth_voucher']);
368
	} else {
369
		/* submit voucher via URL, see https://redmine.pfsense.org/issues/1984 */
370
		$voucher = trim($_GET['voucher']);
371
		portal_reply_page($redirurl, "login", null, $clientmac, $clientip, null, null, $voucher);
372
		return;
373
	}
374
	$errormsg = gettext("Invalid credentials specified.");
375
	$timecredit = voucher_auth($voucher);
376
	// $timecredit contains either a credit in minutes or an error message
377
	if ($timecredit > 0) {  // voucher is valid. Remaining minutes returned
378
		// if multiple vouchers given, use the first as username
379
		$a_vouchers = preg_split("/[\t\n\r ]+/s", $voucher);
380
		$voucher = $a_vouchers[0];
381
		$attr = array(
382
			'voucher' => 1,
383
			'session_timeout' => $timecredit*60,
384
			'session_terminate_time' => 0);
385
		if (portal_allow($clientip, $clientmac, $voucher, null, $redirurl, $attr, null, 'voucher', 'voucher') === 2) {
386
			portal_reply_page($redirurl, "error", "Reuse of identification not allowed.", $clientmac, $clientip);
387
		} elseif (portal_allow($clientip, $clientmac, $voucher, null, $redirurl, $attr, null, 'voucher', 'voucher')) {
388
			// YES: user is good for $timecredit minutes.
389
			captiveportal_logportalauth($voucher, $clientmac, $clientip, "Voucher login good for $timecredit min.");
390
		} else {
391
			portal_reply_page($redirurl, "error", config_get_path("voucher/{$cpzone}/descrmsgexpired") ? config_get_path("voucher/{$cpzone}/descrmsgexpired"): $errormsg, $clientmac, $clientip);
392
		}
393
	} elseif (-1 == $timecredit) {  // valid but expired
394
		captiveportal_logportalauth($voucher, $clientmac, $clientip, "FAILURE", "voucher expired");
395
		portal_reply_page($redirurl, "error", config_get_path("voucher/{$cpzone}/descrmsgexpired") ? config_get_path("voucher/{$cpzone}/descrmsgexpired"): $errormsg, $clientmac, $clientip);
396
	} else {
397
		captiveportal_logportalauth($voucher, $clientmac, $clientip, "FAILURE");
398
		portal_reply_page($redirurl, "error", config_get_path("voucher/{$cpzone}/descrmsgnoaccess") ? config_get_path("voucher/{$cpzone}/descrmsgnoaccess") : $errormsg, $clientmac, $clientip);
399
	}
400

    
401
} elseif ($_POST['accept'] || $cpcfg['auth_method'] === 'radmac') {
402
	
403
		if ($cpcfg['auth_method'] === 'radmac' && !isset($_POST['accept'])) {
404
			$user = $clientmac; 
405
			$passwd = $cpcfg['radmac_secret'];
406
			$context = 'radmac'; // Radius MAC authentication
407
		} elseif (!empty(trim($_POST['auth_user2']))) { 
408
			$user = trim($_POST['auth_user2']);
409
			$passwd = $_POST['auth_pass2'];
410
			$context = 'second'; // Assume users to use the first context if auth_user2 is empty/does not exist
411
		} else {
412
			$user = trim($_POST['auth_user']);
413
			$passwd = $_POST['auth_pass'];
414
			$context = 'first';
415
		}
416
	
417
	$pipeno = captiveportal_get_next_dn_ruleno('auth', 2000, 64500, true);
418
	/* if the pool is empty, return appropriate message and exit */
419
	if (is_null($pipeno)) {
420
		$replymsg = gettext("System reached maximum login capacity");
421
		if ($cpcfg['auth_method'] === 'radmac') {
422
			echo $replymsg;
423
			ob_flush();
424
			return;
425
		} else {
426
			portal_reply_page($redirurl, "error", $replymsg, $clientmac, $clientip);
427
		}
428
		log_error("Zone: {$cpzone} - WARNING!  Captive portal has reached maximum login capacity");
429
		
430
	}
431
	
432
	$auth_result = captiveportal_authenticate_user($user, $passwd, $clientmac, $clientip, $pipeno, $context);
433
	
434
	if ($auth_result['result']) {
435
		captiveportal_logportalauth($user, $clientmac, $clientip, $auth_result['login_status']);
436
		portal_allow($clientip, $clientmac, $user, $passwd, $redirurl, $auth_result['attributes'], null, $auth_result['auth_method'], $context);
437
	} else {
438
		$type = "error";
439
			
440
		if (is_URL($auth_result['attributes']['url_redirection'], true)) {
441
			$redirurl = $auth_result['attributes']['url_redirection'];
442
			$type = "redir";
443
		}
444
		
445
		if ($auth_result['login_message']) {
446
			$replymsg = $auth_result['login_message'];
447
		} else {
448
			$replymsg = gettext("Invalid credentials specified.");
449
		}
450
		
451
		captiveportal_logportalauth($user, $clientmac, $clientip, $auth_result['login_status'], $replymsg);
452

    
453
		/* Radius MAC authentication. */
454
		if ($context === 'radmac' && $type !== 'redir' && !isset($cpcfg['radmac_fallback'])) {
455
			echo $replymsg;
456
		} else {
457
			portal_reply_page($redirurl, $type, $replymsg, $clientmac, $clientip);
458
		}
459
	}
460
} else {
461
	/* display captive portal page */
462
	portal_reply_page($redirurl, "login", null, $clientmac, $clientip);
463
}
464

    
465
ob_flush();
466

    
467
?>
(5-5/7)