Project

General

Profile

Download (20.1 KB) Statistics
| Branch: | Tag: | Revision:
1 8c1ce6c7 Scott Ullrich
<?php
2 5b237745 Scott Ullrich
/*
3 65fbb388 Scott Ullrich
    $Id$
4
    part of m0n0wall (http://m0n0.ch/wall)
5
6 9568c1a1 Ermal Lu?i
    Copyrigth (C) 2009	    Ermal Lu?i
7 65fbb388 Scott Ullrich
    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 5b237745 Scott Ullrich
*/
31 f5024891 Scott Ullrich
/*
32
	pfSense_BUILDER_BINARIES:	/sbin/ipfw	
33
	pfSense_MODULE:	captiveportal
34
*/
35 5b237745 Scott Ullrich
36 0092b3bd mgrooms
require_once("auth.inc");
37 65fbb388 Scott Ullrich
require_once("functions.inc");
38 483e6de8 Scott Ullrich
require_once("captiveportal.inc");
39 65fbb388 Scott Ullrich
40 eb15decb Ermal
$errormsg = "Invalid credentials specified.";
41
42 65fbb388 Scott Ullrich
header("Expires: 0");
43
header("Cache-Control: no-store, no-cache, must-revalidate");
44
header("Cache-Control: post-check=0, pre-check=0", false);
45
header("Pragma: no-cache");
46 5b237745 Scott Ullrich
47
$orig_host = $_ENV['HTTP_HOST'];
48 fe383a26 Ermal
$orig_request = $_REQUEST['redirurl'];
49 6fa4bdc6 Scott Ullrich
$clientip = $_SERVER['REMOTE_ADDR'];
50 5b237745 Scott Ullrich
51
if (!$clientip) {
52 65fbb388 Scott Ullrich
    /* not good - bail out */
53 18cbd65f Chris Buechler
    echo "An error occurred.  Please check the system logs for more information.";
54
    log_error("Captive portal could not determine client's IP address.");
55 65fbb388 Scott Ullrich
    exit;
56
}
57
58
if (isset($config['captiveportal']['httpslogin']))
59
    $ourhostname = $config['captiveportal']['httpsname'] . ":8001";
60 f8b11310 Ermal Lu?i
else {
61
    $ifip = portal_ip_from_client_ip($clientip);
62
    if (!$ifip)
63
    	$ourhostname = $config['system']['hostname'] . ":8000";
64
    else
65
    	$ourhostname = "{$ifip}:8000";
66
}
67 65fbb388 Scott Ullrich
68
if ($orig_host != $ourhostname) {
69
    /* the client thinks it's connected to the desired web server, but instead
70
       it's connected to us. Issue a redirect... */
71
72
    if (isset($config['captiveportal']['httpslogin']))
73
        header("Location: https://{$ourhostname}/index.php?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
74
    else
75
        header("Location: http://{$ourhostname}/index.php?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
76
77
    exit;
78 5b237745 Scott Ullrich
}
79
80 65fbb388 Scott Ullrich
if (preg_match("/redirurl=(.*)/", $orig_request, $matches))
81
    $redirurl = urldecode($matches[1]);
82
if ($_POST['redirurl'])
83
    $redirurl = $_POST['redirurl'];
84
85
$macfilter = !isset($config['captiveportal']['nomacfilter']);
86 0852838c Ermal
$passthrumac = isset($config['captiveportal']['passthrumacadd']);
87 65fbb388 Scott Ullrich
88 5b237745 Scott Ullrich
/* find MAC address for client */
89
$clientmac = arp_get_mac_by_ip($clientip);
90 0852838c Ermal
if (!$clientmac && ($macfilter || $passthrumac)) {
91 65fbb388 Scott Ullrich
    /* unable to find MAC address - shouldn't happen! - bail out */
92
    captiveportal_logportalauth("unauthenticated","noclientmac",$clientip,"ERROR");
93 18cbd65f Chris Buechler
    echo "An error occurred.  Please check the system logs for more information.";
94 d102e3ed Chris Buechler
    log_error("Captive portal could not determine client's MAC address.  Disable MAC address filtering in captive portal if you do not need this functionality.");
95 65fbb388 Scott Ullrich
    exit;
96 5b237745 Scott Ullrich
}
97
98 65fbb388 Scott Ullrich
/* find out if we need RADIUS + RADIUSMAC or not */
99
if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
100
    $radius_enable = TRUE;
101 f8b11310 Ermal Lu?i
    if (isset($config['captiveportal']['radmac_enable']))
102 65fbb388 Scott Ullrich
        $radmac_enable = TRUE;
103
}
104 6e865a74 Scott Ullrich
105 65fbb388 Scott Ullrich
if ($_POST['logout_id']) {
106
    disconnect_client($_POST['logout_id']);
107
    echo <<<EOD
108 5b237745 Scott Ullrich
<HTML>
109
<HEAD><TITLE>Disconnecting...</TITLE></HEAD>
110
<BODY BGCOLOR="#435370">
111
<SPAN STYLE="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
112 b2ce71ff Scott Ullrich
<B>You have been disconnected.</B>
113 5b237745 Scott Ullrich
</SPAN>
114
<SCRIPT LANGUAGE="JavaScript">
115
<!--
116
setTimeout('window.close();',5000) ;
117
-->
118
</SCRIPT>
119
</BODY>
120
</HTML>
121
122
EOD;
123 0852838c Ermal
exit;
124 65fbb388 Scott Ullrich
} else if ($clientmac && $radmac_enable && portal_mac_radius($clientmac,$clientip)) {
125
    /* radius functions handle everything so we exit here since we're done */
126
    exit;
127
128 336e3c1c Charlie
} else if ($_POST['accept'] && $_POST['auth_voucher']) {
129
130
    $voucher = trim($_POST['auth_voucher']);
131
    $timecredit = voucher_auth($voucher);
132
    // $timecredit contains either a credit in minutes or an error message
133
    if ($timecredit > 0) {  // voucher is valid. Remaining minutes returned
134
        // if multiple vouchers given, use the first as username
135
        $a_vouchers = split("[\t\n\r ]+",$voucher);
136
        $voucher = $a_vouchers[0];
137
        $attr = array( 'voucher' => 1,
138
                'session_timeout' => $timecredit*60,
139
                'session_terminate_time' => 0);
140
        if (portal_allow($clientip, $clientmac,$voucher,null,$attr)) {
141
142
            // YES: user is good for $timecredit minutes.
143 d102e3ed Chris Buechler
            captiveportal_logportalauth($voucher,$clientmac,$clientip,"Voucher login good for $timecredit min.");
144 336e3c1c Charlie
        } else {
145 eb15decb Ermal
            portal_reply_page($redirurl, "error", $config['voucher']['msgexpired'] ? $config['voucher']['msgexpired']: $errormsg);
146 336e3c1c Charlie
        }
147
    } else if (-1 == $timecredit) {  // valid but expired
148
        captiveportal_logportalauth($voucher,$clientmac,$clientip,"FAILURE","voucher expired");
149 eb15decb Ermal
        portal_reply_page($redirurl, "error", $config['voucher']['msgexpired'] ? $config['voucher']['msgexpired']: $errormsg);
150 336e3c1c Charlie
    } else {
151
        captiveportal_logportalauth($voucher,$clientmac,$clientip,"FAILURE");
152 eb15decb Ermal
        portal_reply_page($redirurl, "error", $config['voucher']['msgnoaccess'] ? $config['voucher']['msgnoaccess'] : $errormsg);
153 336e3c1c Charlie
    }
154
155 65fbb388 Scott Ullrich
} else if ($_POST['accept'] && $radius_enable) {
156
157
    if ($_POST['auth_user'] && $_POST['auth_pass']) {
158
        $auth_list = radius($_POST['auth_user'],$_POST['auth_pass'],$clientip,$clientmac,"USER LOGIN");
159 814992f7 Ermal
	$type = "error";
160
	if (!empty($auth_list['url_redirection'])) {
161
		$redirurl = $auth_list['url_redirection'];
162
		$type = "redir";
163
	}
164 65fbb388 Scott Ullrich
165
        if ($auth_list['auth_val'] == 1) {
166
            captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"ERROR",$auth_list['error']);
167 eb15decb Ermal
 	    portal_reply_page($redirurl, $type, $auth_list['error'] ? $auth_list['error'] : $errormsg);
168 65fbb388 Scott Ullrich
        }
169
        else if ($auth_list['auth_val'] == 3) {
170
            captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE",$auth_list['reply_message']);
171 eb15decb Ermal
            portal_reply_page($redirurl, $type, $auth_list['reply_message'] ? $auth_list['reply_message'] : $errormsg);
172 65fbb388 Scott Ullrich
        }
173
    } else {
174
        captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"ERROR");
175 eb15decb Ermal
        portal_reply_page($redirurl, "error", $errormsg);
176 65fbb388 Scott Ullrich
    }
177 8c1ce6c7 Scott Ullrich
178 65fbb388 Scott Ullrich
} else if ($_POST['accept'] && $config['captiveportal']['auth_method'] == "local") {
179 8c1ce6c7 Scott Ullrich
180 0092b3bd mgrooms
	//check against local user manager
181
	$loginok = local_backed($_POST['auth_user'], $_POST['auth_pass']);
182 65fbb388 Scott Ullrich
    if ($loginok){
183
        captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"LOGIN");
184
        portal_allow($clientip, $clientmac,$_POST['auth_user']);
185
    } else {
186
        captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE");
187 eb15decb Ermal
        portal_reply_page($redirurl, "error", $errormsg);
188 65fbb388 Scott Ullrich
    }
189
} else if ($_POST['accept'] && $clientip) {
190
    captiveportal_logportalauth("unauthenticated",$clientmac,$clientip,"ACCEPT");
191
    portal_allow($clientip, $clientmac, "unauthenticated");
192
} else {
193
    /* display captive portal page */
194 4993f81c Chris Buechler
    portal_reply_page($redirurl, "login",null,$clientmac,$clientip);
195 5b237745 Scott Ullrich
}
196
197
exit;
198
199 72b9e452 Ermal
function portal_reply_page($redirurl, $type = null, $message = null, $clientmac = null, $clientip = null, $username = null, $password = null) {
200 65fbb388 Scott Ullrich
    global $g, $config;
201 5b237745 Scott Ullrich
202 65fbb388 Scott Ullrich
    /* Get captive portal layout */
203 4fc68c5a Ermal
    if ($type == "redir") {
204 814992f7 Ermal
	header("Location: {$redirurl}");
205
	return;
206
    } else if ($type == "login")
207 7a7e94a7 Scott Ullrich
        $htmltext = get_include_contents("{$g['varetc_path']}/captiveportal.html");
208 65fbb388 Scott Ullrich
    else
209 7a7e94a7 Scott Ullrich
        $htmltext = get_include_contents("{$g['varetc_path']}/captiveportal-error.html");
210 5b237745 Scott Ullrich
211 65fbb388 Scott Ullrich
    /* substitute other variables */
212 7a7e94a7 Scott Ullrich
    if (isset($config['captiveportal']['httpslogin'])) {
213 65fbb388 Scott Ullrich
        $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext);
214 7a7e94a7 Scott Ullrich
        $htmltext = str_replace("#PORTAL_ACTION#", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext);
215
    } else {
216
		$ifip = portal_ip_from_client_ip($clientip);
217 f8b11310 Ermal Lu?i
    	if (!$ifip)
218
        	$ourhostname = $config['system']['hostname'] . ":8000";
219
    	else
220
        	$ourhostname = "{$ifip}:8000";
221
        $htmltext = str_replace("\$PORTAL_ACTION\$", "http://{$ourhostname}/", $htmltext);
222 7a7e94a7 Scott Ullrich
        $htmltext = str_replace("#PORTAL_ACTION#", "http://{$ourhostname}/", $htmltext);
223 f8b11310 Ermal Lu?i
    }
224 8c1ce6c7 Scott Ullrich
225 65fbb388 Scott Ullrich
    $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext);
226
    $htmltext = str_replace("\$PORTAL_MESSAGE\$", htmlspecialchars($message), $htmltext);
227 4993f81c Chris Buechler
    $htmltext = str_replace("\$CLIENT_MAC\$", htmlspecialchars($clientmac), $htmltext);
228
    $htmltext = str_replace("\$CLIENT_IP\$", htmlspecialchars($clientip), $htmltext);
229 5b237745 Scott Ullrich
230 7a7e94a7 Scott Ullrich
	// Special handling case for captive portal master page so that it can be ran 
231
	// through the PHP interpreter using the include method above.  We convert the
232
	// $VARIABLE$ case to #VARIABLE# in /etc/inc/captiveportal.inc before writing out.
233
	$htmltext = str_replace("#PORTAL_REDIRURL#", htmlspecialchars($redirurl), $htmltext);
234
	$htmltext = str_replace("#PORTAL_MESSAGE#", htmlspecialchars($message), $htmltext);
235
	$htmltext = str_replace("#CLIENT_MAC#", htmlspecialchars($clientmac), $htmltext);
236
	$htmltext = str_replace("#CLIENT_IP#", htmlspecialchars($clientip), $htmltext);
237 72b9e452 Ermal
	$htmltext = str_replace("#USERNAME#", htmlspecialchars($username), $htmltext);
238
	$htmltext = str_replace("#PASSWORD#", htmlspecialchars($password), $htmltext);
239 7a7e94a7 Scott Ullrich
240 65fbb388 Scott Ullrich
    echo $htmltext;
241
}
242 8c1ce6c7 Scott Ullrich
243 65fbb388 Scott Ullrich
function portal_mac_radius($clientmac,$clientip) {
244
    global $config ;
245 8c1ce6c7 Scott Ullrich
246 65fbb388 Scott Ullrich
    $radmac_secret = $config['captiveportal']['radmac_secret'];
247 8c1ce6c7 Scott Ullrich
248 65fbb388 Scott Ullrich
    /* authentication against the radius server */
249
    $username = mac_format($clientmac);
250
    $auth_list = radius($username,$radmac_secret,$clientip,$clientmac,"MACHINE LOGIN");
251 814992f7 Ermal
    if ($auth_list['auth_val'] == 2)
252 65fbb388 Scott Ullrich
        return TRUE;
253 0eb9b1b4 Ermal
    if (!empty($auth_list['url_redirection']))
254 814992f7 Ermal
	portal_reply_page($auth_list['url_redirection'], "redir");
255 0eb9b1b4 Ermal
256 65fbb388 Scott Ullrich
    return FALSE;
257
}
258 8c1ce6c7 Scott Ullrich
259 65fbb388 Scott Ullrich
function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $ruleno = null)  {
260
261 72b9e452 Ermal
	global $redirurl, $g, $config, $type, $passthrumac, $_POST;
262 9faa6c3c Ermal
263
	/* See if a ruleno is passed, if not start locking the sessions because this means there isn't one atm */
264
	$captiveshouldunlock = false;
265
	if ($ruleno == null) {
266
		$cplock = lock('captiveportal');
267
		$captiveshouldunlock = true;
268
		$ruleno = captiveportal_get_next_ipfw_ruleno();
269 6ce61a8f Ermal
	}
270 65fbb388 Scott Ullrich
271 9faa6c3c Ermal
	/* if the pool is empty, return appropriate message and exit */
272
	if (is_null($ruleno)) {
273
		portal_reply_page($redirurl, "error", "System reached maximum login capacity");
274
		log_error("WARNING!  Captive portal has reached maximum login capacity");
275
		if ($captiveshouldunlock == true)
276
		unlock($cplock);
277
		exit;
278
	}
279 65fbb388 Scott Ullrich
280 9faa6c3c Ermal
	// Ensure we create an array if we are missing attributes
281
	if (!is_array($attributes))
282
		$attributes = array();
283 65fbb388 Scott Ullrich
284 9faa6c3c Ermal
	/* read in client database */
285
	$cpdb = captiveportal_read_db();
286 65fbb388 Scott Ullrich
287 9faa6c3c Ermal
	$radiusservers = captiveportal_get_radius_servers();
288 6ce61a8f Ermal
289 9faa6c3c Ermal
	if ($attributes['voucher'])
290
		$remaining_time = $attributes['session_timeout'];
291
292 72b9e452 Ermal
	$writecfg = false;
293 9faa6c3c Ermal
	/* Find an existing session */
294 1c291e64 Ermal
	if ((isset($config['captiveportal']['noconcurrentlogins'])) && $passthrumac) {
295
		if (isset($config['captiveportal']['passthrumacadd'])) {
296
			$mac = captiveportal_passthrumac_findbyname($username);
297
			if (!empty($mac)) {
298 72b9e452 Ermal
				if ($_POST['replacemacpassthru']) {
299 3bf8eb93 Ermal
					foreach ($config['captiveportal']['passthrumac'] as $idx => $macent) {
300 72b9e452 Ermal
						if ($macent['mac'] == $mac['mac']) {
301 4d349ede Ermal
							$macrules = "";
302
							$ruleno = captiveportal_get_ipfw_passthru_ruleno($mac['mac']);
303
                                			if ($ruleno) {
304
								captiveportal_free_ipfw_ruleno($ruleno, true);
305 b90996c5 Ermal
                                        			$macrules .= "delete {$ruleno}\n";
306 4d349ede Ermal
								++$ruleno;
307 b90996c5 Ermal
                                        			$macrules .= "delete {$ruleno}\n";
308 4d349ede Ermal
                                			}
309 72b9e452 Ermal
							unset($config['captiveportal']['passthrumac'][$idx]);
310
							$mac['mac'] = $clientmac;
311
							$config['captiveportal']['passthrumac'][] = $mac;
312 e06b7fa2 Ermal
							$macrules .= captiveportal_passthrumac_configure_entry($mac);
313 72b9e452 Ermal
							file_put_contents("{$g['tmp_path']}/macentry.rules.tmp", $macrules);
314
							mwexec("/sbin/ipfw -q {$g['tmp_path']}/macentry.rules.tmp");
315
							$writecfg = true;
316
							$sessionid = true;
317
							break;
318
						}
319
					}
320
                                } else {
321
					portal_reply_page($redirurl, "error", "Username: {$username} is known with another mac address.",
322
						$clientmac, $clientip, $username, $password);
323
					exit;
324
				}
325 1c291e64 Ermal
			}
326
		}
327
	}
328
329
	$nousers = count($cpdb);
330
	for ($i = 0; $i < $nousers; $i++) {
331 9faa6c3c Ermal
		/* on the same ip */
332
		if($cpdb[$i][2] == $clientip) {
333
			captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"CONCURRENT LOGIN - REUSING OLD SESSION");
334
			$sessionid = $cpdb[$i][5];
335
			break;
336
		}
337
		elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpdb[$i][4] == $username)) {
338
			// user logged in with an active voucher. Check for how long and calculate 
339
			// how much time we can give him (voucher credit - used time)
340
			$remaining_time = $cpdb[$i][0] + $cpdb[$i][7] - time();
341
			if ($remaining_time < 0)    // just in case. 
342
				$remaining_time = 0;
343
344
			/* This user was already logged in so we disconnect the old one */
345
			captiveportal_disconnect($cpdb[$i],$radiusservers,13);
346
			captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"CONCURRENT LOGIN - TERMINATING OLD SESSION");
347
			unset($cpdb[$i]);
348
			break;
349
		}
350
		elseif ((isset($config['captiveportal']['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
351
			/* on the same username */
352
			if (strcasecmp($cpdb[$i][4], $username) == 0) {
353
				/* This user was already logged in so we disconnect the old one */
354
				captiveportal_disconnect($cpdb[$i],$radiusservers,13);
355
				captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"CONCURRENT LOGIN - TERMINATING OLD SESSION");
356
				unset($cpdb[$i]);
357
				break;
358
			}
359
		}
360
	}
361 65fbb388 Scott Ullrich
362 9faa6c3c Ermal
	if ($attributes['voucher'] && $remaining_time <= 0) {
363
		unlock($cplock);
364
		return 0;       // voucher already used and no time left
365
	}
366 65fbb388 Scott Ullrich
367 9faa6c3c Ermal
	if (!isset($sessionid)) {
368
369
		/* generate unique session ID */
370
		$tod = gettimeofday();
371
		$sessionid = substr(md5(mt_rand() . $tod['sec'] . $tod['usec'] . $clientip . $clientmac), 0, 16);
372
373
		/* Add rules for traffic shaping
374
		 * We don't need to add extra rules since traffic will pass due to the following kernel option
375
		 * net.inet.ip.fw.one_pass: 1
376
		 */
377
		$peruserbw = isset($config['captiveportal']['peruserbw']);
378
379
		$bw_up = isset($attributes['bw_up']) ? trim($attributes['bw_up']) : $config['captiveportal']['bwdefaultup'];
380
		$bw_down = isset($attributes['bw_down']) ? trim($attributes['bw_down']) : $config['captiveportal']['bwdefaultdn'];
381
382
		if ($passthrumac) {
383
			$mac = array();
384
			$mac['mac'] = $clientmac;
385 1c291e64 Ermal
			if (isset($config['captiveportal']['passthrumacaddusername']))
386
				$mac['username'] = $username;
387 9faa6c3c Ermal
			$mac['descr'] =  "Auto added pass-through MAC for user {$username}";
388
			if (!empty($bw_up))
389
				$mac['bw_up'] = $bw_up;
390
			if (!empty($bw_down))
391
				$mac['bw_down'] = $bw_down;
392
			if (!is_array($config['captiveportal']['passthrumac']))
393
				$config['captiveportal']['passthrumac'] = array();
394
			$config['captiveportal']['passthrumac'][] = $mac;
395
			$macrules = captiveportal_passthrumac_configure_entry($mac);
396
			file_put_contents("{$g['tmp_path']}/macentry.rules.tmp", $macrules);
397
			mwexec("/sbin/ipfw -q {$g['tmp_path']}/macentry.rules.tmp");
398
			$writecfg = true;
399
		} else {
400
401
			if ($peruserbw && !empty($bw_up) && is_numeric($bw_up)) {
402
				$bw_up_pipeno = $ruleno + 20000;
403
				//$bw_up /= 1000; // Scale to Kbit/s
404
				mwexec("/sbin/ipfw pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100");
405
406
				if (!isset($config['captiveportal']['nomacfilter']))
407
					mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac} {$bw_up_pipeno}");
408
				else
409
					mwexec("/sbin/ipfw table 1 add {$clientip} {$bw_up_pipeno}");
410
			} else {
411
				if (!isset($config['captiveportal']['nomacfilter']))
412
					mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac}");
413
				else
414
					mwexec("/sbin/ipfw table 1 add {$clientip}");
415
			}
416
			if ($peruserbw && !empty($bw_down) && is_numeric($bw_down)) {
417
				$bw_down_pipeno = $ruleno + 20001;
418
				//$bw_down /= 1000; // Scale to Kbit/s
419
				mwexec("/sbin/ipfw pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100");
420
421
				if (!isset($config['captiveportal']['nomacfilter']))
422
					mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac} {$bw_down_pipeno}");
423
				else
424
					mwexec("/sbin/ipfw table 2 add {$clientip} {$bw_down_pipeno}");
425
			} else {
426
				if (!isset($config['captiveportal']['nomacfilter']))
427
					mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac}");
428
				else
429
					mwexec("/sbin/ipfw table 2 add {$clientip}");
430
			}
431
432
			if ($attributes['voucher'])
433
				$attributes['session_timeout'] = $remaining_time;
434
435
			/* encode password in Base64 just in case it contains commas */
436
			$bpassword = base64_encode($password);
437
			$cpdb[] = array(time(), $ruleno, $clientip, $clientmac, $username, $sessionid, $bpassword,
438
				$attributes['session_timeout'], $attributes['idle_timeout'], $attributes['session_terminate_time']);
439
440
			if (isset($config['captiveportal']['radacct_enable']) && !empty($radiusservers)) {
441
				$acct_val = RADIUS_ACCOUNTING_START($ruleno,
442
                                		$username, $sessionid, $radiusservers, $clientip, $clientmac);
443
444
				if ($acct_val == 1)
445
					captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED");
446
			}
447
448
			/* rewrite information to database */
449
			captiveportal_write_db($cpdb);
450
		}
451 f8b11310 Ermal Lu?i
	}
452 65fbb388 Scott Ullrich
453 9faa6c3c Ermal
	if ($captiveshouldunlock == true)
454
		unlock($cplock);
455
456
	if ($writecfg == true)
457
		write_config();
458
459
	/* redirect user to desired destination */
460 9628bd1c Ermal
	if (!empty($attributes['url_redirection']))
461
		$my_redirurl = $attributes['url_redirection'];
462 9faa6c3c Ermal
	else if ($config['captiveportal']['redirurl'])
463
		$my_redirurl = $config['captiveportal']['redirurl'];
464
	else
465
		$my_redirurl = $redirurl;
466
467 091cb5e9 Ermal
	if(isset($config['captiveportal']['logoutwin_enable']) && !$passthrumac) {
468 9faa6c3c Ermal
469
		if (isset($config['captiveportal']['httpslogin']))
470
			$logouturl = "https://{$config['captiveportal']['httpsname']}:8001/";
471
		else {
472
			$ifip = portal_ip_from_client_ip($clientip);
473
			if (!$ifip)
474
				$ourhostname = $config['system']['hostname'] . ":8000";
475
			else
476
				$ourhostname = "{$ifip}:8000";
477
			$logouturl = "http://{$ourhostname}/";
478
		}
479
480 2e12b76c jim-p
		if (isset($attributes['reply_message']))
481
			$message = $attributes['reply_message'];
482
		else
483
			$message = 0;
484
485 5b87b24e Ermal
		include("{$g['varetc_path']}/captiveportal-logout.html");
486 5b237745 Scott Ullrich
487 9faa6c3c Ermal
	} else {
488 3bc77cd3 Scott Ullrich
		if($_POST['ORIGINAL_PORTAL_IP'] && $_SERVER['SERVER_NAME'] != $_POST['ORIGINAL_PORTAL_IP']) {
489 7a7e94a7 Scott Ullrich
 			header ('HTTP/1.1 301 Moved Permanently');
490
			header("Location: " . $_POST['ORIGINAL_PORTAL_IP']);
491
		} else {
492
			header("Location: " . $my_redirurl);
493
		}
494 9faa6c3c Ermal
	}
495 8c1ce6c7 Scott Ullrich
496 9faa6c3c Ermal
	return $sessionid;
497 5b237745 Scott Ullrich
}
498
499 8c1ce6c7 Scott Ullrich
500 5b237745 Scott Ullrich
501 65fbb388 Scott Ullrich
/* remove a single client by session ID
502
   by Dinesh Nair
503
 */
504
function disconnect_client($sessionid, $logoutReason = "LOGOUT", $term_cause = 1) {
505 5b237745 Scott Ullrich
506 65fbb388 Scott Ullrich
    global $g, $config;
507 8c1ce6c7 Scott Ullrich
508 f80a6148 Ermal Lu?i
    $cplock = lock('captiveportal');
509 65fbb388 Scott Ullrich
    /* read database */
510
    $cpdb = captiveportal_read_db();
511 8c1ce6c7 Scott Ullrich
512 65fbb388 Scott Ullrich
    $radiusservers = captiveportal_get_radius_servers();
513
514
    /* find entry */
515 6ce61a8f Ermal
    $dbcount = count($cpdb);
516
    for ($i = 0; $i < $dbcount; $i++) {
517 65fbb388 Scott Ullrich
        if ($cpdb[$i][5] == $sessionid) {
518
            captiveportal_disconnect($cpdb[$i],$radiusservers, $term_cause);
519
            captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],$logoutReason);
520
            unset($cpdb[$i]);
521
            break;
522
        }
523
    }
524
525
    /* write database */
526
    captiveportal_write_db($cpdb);
527
528 f80a6148 Ermal Lu?i
    unlock($cplock);
529 5b237745 Scott Ullrich
}
530
531 9628bd1c Ermal
?>