summaryrefslogtreecommitdiffstats
path: root/usr/local/captiveportal
diff options
context:
space:
mode:
authorScott Ullrich <sullrich@pfsense.org>2006-09-05 17:01:27 +0000
committerScott Ullrich <sullrich@pfsense.org>2006-09-05 17:01:27 +0000
commit65fbb3889680ae561f0d60c8038dbc1a737af0a2 (patch)
tree7abb23bc94a6b4ce3129f0273b06f72b8b24eaeb /usr/local/captiveportal
parentcf83f490b89ba56da3f02f9f1d13873035a9daf2 (diff)
downloadpfsense-65fbb3889680ae561f0d60c8038dbc1a737af0a2.zip
pfsense-65fbb3889680ae561f0d60c8038dbc1a737af0a2.tar.gz
Fix $VARIABLES$
Diffstat (limited to 'usr/local/captiveportal')
-rwxr-xr-xusr/local/captiveportal/index.php755
1 files changed, 373 insertions, 382 deletions
diff --git a/usr/local/captiveportal/index.php b/usr/local/captiveportal/index.php
index 788efcf..c74e593 100755
--- a/usr/local/captiveportal/index.php
+++ b/usr/local/captiveportal/index.php
@@ -1,135 +1,95 @@
<?php
/*
- index.php
- part of m0n0wall (http://m0n0.ch/wall)
-
- Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
+ $Id$
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
*/
-require("globals.inc");
-require("util.inc");
-require("config.inc");
-require("radius_authentication.inc");
-require("radius_accounting.inc");
+require_once("functions.inc");
+
+header("Expires: 0");
+header("Cache-Control: no-store, no-cache, must-revalidate");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
$orig_host = $_ENV['HTTP_HOST'];
$orig_request = $_GET['redirurl'];
-$lockfile = "{$g['varrun_path']}/captiveportal.lock";
$clientip = $_SERVER['REMOTE_ADDR'];
if (!$clientip) {
- /* not good - bail out */
+ /* not good - bail out */
echo "An error occured. Please check the system logs for more information.";
log_error("Captive portal could not deterimine clients ip address.");
- exit;
+ exit;
+}
+
+if (isset($config['captiveportal']['httpslogin']))
+ $ourhostname = $config['captiveportal']['httpsname'] . ":8001";
+else
+ $ourhostname = $config['interfaces'][$config['captiveportal']['interface']]['ipaddr'] . ":8000";
+
+if ($orig_host != $ourhostname) {
+ /* the client thinks it's connected to the desired web server, but instead
+ it's connected to us. Issue a redirect... */
+
+ if (isset($config['captiveportal']['httpslogin']))
+ header("Location: https://{$ourhostname}/index.php?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
+ else
+ header("Location: http://{$ourhostname}/index.php?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
+
+ exit;
}
+if (preg_match("/redirurl=(.*)/", $orig_request, $matches))
+ $redirurl = urldecode($matches[1]);
+if ($_POST['redirurl'])
+ $redirurl = $_POST['redirurl'];
+
+$macfilter = !isset($config['captiveportal']['nomacfilter']);
+
/* find MAC address for client */
$clientmac = arp_get_mac_by_ip($clientip);
-if (!$clientmac && !isset($config['captiveportal']['nomacfilter'])) {
- /* unable to find MAC address - shouldn't happen! - bail out */
+if (!$clientmac && $macfilter) {
+ /* unable to find MAC address - shouldn't happen! - bail out */
+ captiveportal_logportalauth("unauthenticated","noclientmac",$clientip,"ERROR");
echo "An error occured. Please check the system logs for more information.";
log_error("Captive portal could not deterimine clients MAC address. Disable MAC address filtering in captive portal if you do not needs this functionality.");
- exit;
+ exit;
}
-if ($clientmac && portal_mac_fixed($clientmac)) {
- /* punch hole in ipfw for pass thru mac addresses */
- portal_allow($clientip, $clientmac, "unauthenticated");
-
-} else if ($_POST['accept'] && file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
-
- /* authenticate against radius server */
- $radiusservers = captiveportal_get_radius_servers();
-
- if ($_POST['auth_user'] && $_POST['auth_pass']) {
- $auth_val = RADIUS_AUTHENTICATION($_POST['auth_user'],
- $_POST['auth_pass'],
- $radiusservers[0]['ipaddr'],
- $radiusservers[0]['port'],
- $radiusservers[0]['key']);
- if ($auth_val == 2) {
- captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"LOGIN");
- $sessionid = portal_allow($clientip, $clientmac, $_POST['auth_user'], $_POST['auth_pass']);
- if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
- $auth_val = RADIUS_ACCOUNTING_START($_POST['auth_user'],
- $sessionid,
- $radiusservers[0]['ipaddr'],
- $radiusservers[0]['acctport'],
- $radiusservers[0]['key'],
- $clientip);
- }
- } else {
- captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE");
- readfile("{$g['varetc_path']}/captiveportal-error.html");
- }
- } else {
- readfile("{$g['varetc_path']}/captiveportal-error.html");
- }
-
-} else if ($_POST['accept'] && $config['captiveportal']['auth_method'] == "local") {
-
- //check against local usermanager
- $userdb = &$config['captiveportal']['user'];
-
- $loginok = false;
-
- //erase expired accounts
- if (is_array($userdb)) {
- $moddb = false;
- for ($i = 0; $i < count($userdb); $i++) {
- if ($userdb[$i]['expirationdate'] && (strtotime("-1 day") > strtotime($userdb[$i]['expirationdate']))) {
- unset($userdb[$i]);
- $moddb = true;
- }
- }
- if ($moddb)
- write_config();
-
- $userdb = &$config['captiveportal']['user'];
-
- for ($i = 0; $i < count($userdb); $i++) {
- if (($userdb[$i]['name'] == $_POST['auth_user']) && ($userdb[$i]['password'] == md5($_POST['auth_pass']))) {
- $loginok = true;
- break;
- }
- }
- }
+/* find out if we need RADIUS + RADIUSMAC or not */
+if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
+ $radius_enable = TRUE;
+ if ($radius_enable && isset($config['captiveportal']['radmac_enable']))
+ $radmac_enable = TRUE;
+}
- if ($loginok){
- captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"LOGIN");
- portal_allow($clientip, $clientmac,$_POST['auth_user'],0,0);
- } else {
- captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE");
- readfile("{$g['varetc_path']}/captiveportal-error.html");
- }
-} else if ($_POST['accept'] && $clientip) {
- portal_allow($clientip, $clientmac, "unauthenticated");
-} else if ($_POST['logout_id']) {
- disconnect_client($_POST['logout_id']);
- echo <<<EOD
+if ($_POST['logout_id']) {
+ disconnect_client($_POST['logout_id']);
+ echo <<<EOD
<HTML>
<HEAD><TITLE>Disconnecting...</TITLE></HEAD>
<BODY BGCOLOR="#435370">
@@ -145,323 +105,354 @@ setTimeout('window.close();',5000) ;
</HTML>
EOD;
-} else if (($_ENV['SERVER_PORT'] != 8001) && isset($config['captiveportal']['httpslogin'])) {
- /* redirect to HTTPS login page */
- header("Location: https://{$config['captiveportal']['httpsname']}:8001/index.php?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
-} else {
-
- header("Expires: 0");
- header("Cache-Control: no-store, no-cache, must-revalidate");
- header("Cache-Control: post-check=0, pre-check=0", false);
- header("Pragma: no-cache");
-
- /* display captive portal page */
- $htmltext = file_get_contents("{$g['varetc_path']}/captiveportal.html");
-
- /* substitute variables */
- if (isset($config['captiveportal']['httpslogin']))
- $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext);
- else
- $htmltext = str_replace("\$PORTAL_ACTION\$", "http://{$config['interfaces'][$config['captiveportal']['interface']]['ipaddr']}:8000/", $htmltext);
+/* The $macfilter can be removed safely since we first check if the $clientmac is present, if not we fail */
+} else if ($clientmac && portal_mac_fixed($clientmac)) {
+ /* punch hole in ipfw for pass thru mac addresses */
+ portal_allow($clientip, $clientmac, "unauthenticated");
+ exit;
+
+} else if ($clientmac && $radmac_enable && portal_mac_radius($clientmac,$clientip)) {
+ /* radius functions handle everything so we exit here since we're done */
+ exit;
+
+} else if ($_POST['accept'] && $radius_enable) {
+
+ if ($_POST['auth_user'] && $_POST['auth_pass']) {
+ $auth_list = radius($_POST['auth_user'],$_POST['auth_pass'],$clientip,$clientmac,"USER LOGIN");
+
+ if ($auth_list['auth_val'] == 1) {
+ captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"ERROR",$auth_list['error']);
+ portal_reply_page($redirurl, "error", $auth_list['error']);
+ }
+ else if ($auth_list['auth_val'] == 3) {
+ captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE",$auth_list['reply_message']);
+ portal_reply_page($redirurl, "error", $auth_list['reply_message']);
+ }
+ } else {
+ captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"ERROR");
+ portal_reply_page($redirurl, "error");
+ }
- if (preg_match("/redirurl=(.*)/", $orig_request, $matches))
- $redirurl = urldecode($matches[1]);
- else
- $redirurl = "http://{$orig_host}{$orig_request}";
- $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext);
+} else if ($_POST['accept'] && $config['captiveportal']['auth_method'] == "local") {
- echo $htmltext;
+ //check against local usermanager
+ $userdb = &$config['captiveportal']['user'];
+
+ $loginok = false;
+
+ //erase expired accounts
+ if (is_array($userdb)) {
+ $moddb = false;
+ for ($i = 0; $i < count($userdb); $i++) {
+ if ($userdb[$i]['expirationdate'] && (strtotime("-1 day") > strtotime($userdb[$i]['expirationdate']))) {
+ unset($userdb[$i]);
+ $moddb = true;
+ }
+ }
+ if ($moddb)
+ write_config();
+
+ $userdb = &$config['captiveportal']['user'];
+
+ for ($i = 0; $i < count($userdb); $i++) {
+ if (($userdb[$i]['name'] == $_POST['auth_user']) && ($userdb[$i]['password'] == md5($_POST['auth_pass']))) {
+ $loginok = true;
+ break;
+ }
+ }
+ }
+
+ if ($loginok){
+ captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"LOGIN");
+ portal_allow($clientip, $clientmac,$_POST['auth_user']);
+ } else {
+ captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE");
+ portal_reply_page($redirurl, "error");
+ }
+} else if ($_POST['accept'] && $clientip) {
+ captiveportal_logportalauth("unauthenticated",$clientmac,$clientip,"ACCEPT");
+ portal_allow($clientip, $clientmac, "unauthenticated");
+} else {
+ /* display captive portal page */
+ portal_reply_page($redirurl, "login");
}
-
exit;
-function portal_mac_fixed($clientmac) {
- global $g ;
-
- /* open captive portal mac db */
- if (file_exists("{$g['vardb_path']}/captiveportal_mac.db")) {
- $fd = @fopen("{$g['vardb_path']}/captiveportal_mac.db","r") ;
- if (!$fd) {
- return FALSE;
- }
- while (!feof($fd)) {
- $mac = trim(fgets($fd)) ;
- if(strcasecmp($clientmac, $mac) == 0) {
- fclose($fd) ;
- return TRUE ;
- }
- }
- fclose($fd) ;
- }
- return FALSE ;
-}
-
-function portal_allow($clientip,$clientmac,$clientuser,$password = "") {
+function portal_reply_page($redirurl, $type = null, $message = null) {
+ global $g, $config;
- global $orig_host, $orig_request, $g, $config;
+ /* Get captive portal layout */
+ if ($type == "login")
+ $htmltext = file_get_contents("{$g['varetc_path']}/captiveportal.html");
+ else
+ $htmltext = file_get_contents("{$g['varetc_path']}/captiveportal-error.html");
- /* user has accepted AUP - let him in */
- portal_lock();
+ /* substitute other variables */
+ if (isset($config['captiveportal']['httpslogin']))
+ $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext);
+ else
+ $htmltext = str_replace("\$PORTAL_ACTION\$", "http://{$config['interfaces'][$config['captiveportal']['interface']]['ipaddr']}:8000/", $htmltext);
- /* get next ipfw rule number */
- if (file_exists("{$g['vardb_path']}/captiveportal.nextrule"))
- $ruleno = trim(file_get_contents("{$g['vardb_path']}/captiveportal.nextrule"));
- if (!$ruleno)
- $ruleno = 10000; /* first rule number */
+ $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext);
+ $htmltext = str_replace("\$PORTAL_MESSAGE\$", htmlspecialchars($message), $htmltext);
- $saved_ruleno = $ruleno;
-
- /* generate unique session ID */
- $tod = gettimeofday();
- $sessionid = substr(md5(mt_rand() . $tod['sec'] . $tod['usec'] . $clientip . $clientmac), 0, 16);
-
- /* add ipfw rules for layer 3 */
- exec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from $clientip to any in");
- exec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to $clientip out");
-
- /* add ipfw rules for layer 2 */
- if (!isset($config['captiveportal']['nomacfilter'])) {
- $l2ruleno = $ruleno + 10000;
- exec("/sbin/ipfw add $l2ruleno set 3 deny all from $clientip to any not MAC any $clientmac layer2 in");
- exec("/sbin/ipfw add $l2ruleno set 3 deny all from any to $clientip not MAC $clientmac any layer2 out");
- }
-
- /* read in client database */
- $cpdb = array();
-
- $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
- if ($fd) {
- while (!feof($fd)) {
- $line = trim(fgets($fd)) ;
- if($line) {
- $cpdb[] = explode(",",$line);
- }
- }
- fclose($fd);
- }
-
- $radiusservers = captiveportal_get_radius_servers();
-
- /* find an existing entry and delete it */
- for ($i = 0; $i < count($cpdb); $i++) {
- if(!strcasecmp($cpdb[$i][2],$clientip)) {
- if(isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
- RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno
- $cpdb[$i][4], // username
- $cpdb[$i][5], // sessionid
- $cpdb[$i][0], // start time
- $radiusservers[0]['ipaddr'],
- $radiusservers[0]['acctport'],
- $radiusservers[0]['key'],
- $clientip);
- }
- mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
- unset($cpdb[$i]);
- break;
- }
- }
-
- /* rewrite information to database */
- $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
- if ($fd) {
- foreach ($cpdb as $cpent) {
- fwrite($fd, join(",", $cpent) . "\n");
- }
- /* write in this new entry */
- /* encode password in Base64 just in case it contains commas */
- $bpassword = base64_encode($password);
- fwrite($fd, time().",{$ruleno},{$clientip},{$clientmac},{$clientuser},{$sessionid},{$bpassword}\n") ;
- fclose($fd);
- }
-
- /* write next rule number */
- $fd = @fopen("{$g['vardb_path']}/captiveportal.nextrule", "w");
- if ($fd) {
- $ruleno++;
- if ($ruleno > 19899)
- $ruleno = 10000; /* wrap around */
- fwrite($fd, $ruleno);
- fclose($fd);
- }
+ echo $htmltext;
+}
- portal_unlock();
+function portal_mac_fixed($clientmac) {
+ global $g ;
+
+ /* open captive portal mac db */
+ if (file_exists("{$g['vardb_path']}/captiveportal_mac.db")) {
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_mac.db","r") ;
+ if (!$fd) {
+ return FALSE;
+ }
+ while (!feof($fd)) {
+ $mac = trim(fgets($fd)) ;
+ if(strcasecmp($clientmac, $mac) == 0) {
+ fclose($fd) ;
+ return TRUE ;
+ }
+ }
+ fclose($fd) ;
+ }
+ return FALSE ;
+}
- /* redirect user to desired destination */
- if ($config['captiveportal']['redirurl'])
- $redirurl = $config['captiveportal']['redirurl'];
- else if ($_POST['redirurl'])
- $redirurl = $_POST['redirurl'];
- else
- $redirurl = "http://{$orig_host}{$orig_request}";
+function portal_mac_radius($clientmac,$clientip) {
+ global $config ;
- if(isset($config['captiveportal']['logoutwin_enable'])) {
+ $radmac_secret = $config['captiveportal']['radmac_secret'];
- if (isset($config['captiveportal']['httpslogin']))
- $logouturl = "https://{$config['captiveportal']['httpsname']}:8001/";
- else
- $logouturl = "http://{$config['interfaces'][$config['captiveportal']['interface']]['ipaddr']}:8000/";
+ /* authentication against the radius server */
+ $username = mac_format($clientmac);
+ $auth_list = radius($username,$radmac_secret,$clientip,$clientmac,"MACHINE LOGIN");
+ if ($auth_list['auth_val'] == 2) {
+ return TRUE;
+ }
+ return FALSE;
+}
- echo <<<EOD
+function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $ruleno = null) {
+
+ global $redirurl, $g, $config;
+
+ /* See if a ruleno is passed, if not start locking the sessions because this means there isn't one atm */
+ if ($ruleno == null) {
+ captiveportal_lock();
+ $ruleno = captiveportal_get_next_ipfw_ruleno();
+ }
+
+ /* if the pool is empty, return appropriate message and exit */
+ if (is_null($ruleno)) {
+ portal_reply_page($redirurl, "error", "System reached maximum login capacity");
+ captiveportal_unlock();
+ exit;
+ }
+
+ // Ensure we create an array if we are missing attributes
+ if (!is_array($attributes))
+ $attributes = array();
+
+ /* read in client database */
+ $cpdb = captiveportal_read_db();
+
+ $radiusservers = captiveportal_get_radius_servers();
+
+ /* Find an existing session */
+ for ($i = 0; $i < count($cpdb); $i++) {
+ /* on the same ip */
+ if($cpdb[$i][2] == $clientip) {
+ captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"CONCURRENT LOGIN - REUSING OLD SESSION");
+ $sessionid = $cpdb[$i][5];
+ break;
+ }
+ elseif ((isset($config['captiveportal']['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
+ /* on the same username */
+ if ($cpdb[$i][4] == $username) {
+ /* This user was already logged in so we disconnect the old one */
+ captiveportal_disconnect($cpdb[$i],$radiusservers,13);
+ captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"CONCURRENT LOGIN - TERMINATING OLD SESSION");
+ unset($cpdb[$i]);
+ break;
+ }
+ }
+ }
+
+ if (!isset($sessionid)) {
+
+ /* generate unique session ID */
+ $tod = gettimeofday();
+ $sessionid = substr(md5(mt_rand() . $tod['sec'] . $tod['usec'] . $clientip . $clientmac), 0, 16);
+
+ /* Add rules for traffic shaping
+ * We don't need to add extra l3 allow rules since traffic will pass due to the following kernel option
+ * net.inet.ip.fw.one_pass: 1
+ */
+ $peruserbw = isset($config['captiveportal']['peruserbw']);
+
+ $bw_up = isset($attributes['bw_up']) ? trim($attributes['bw_up']) : $config['captiveportal']['bwdefaultup'];
+ $bw_down = isset($attributes['bw_down']) ? trim($attributes['bw_down']) : $config['captiveportal']['bwdefaultdn'];
+
+ if ($peruserbw && !empty($bw_up) && is_numeric($bw_up)) {
+ $bw_up_pipeno = $ruleno + 40500;
+ exec("/sbin/ipfw add $ruleno set 2 pipe $bw_up_pipeno ip from $clientip to any in");
+ exec("/sbin/ipfw pipe $bw_up_pipeno config bw {$bw_up}Kbit/s queue 100");
+ } else {
+ exec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from $clientip to any in");
+ }
+ if ($peruserbw && !empty($bw_down) && is_numeric($bw_down)) {
+ $bw_down_pipeno = $ruleno + 45500;
+ exec("/sbin/ipfw add $ruleno set 2 pipe $bw_down_pipeno ip from any to $clientip out");
+ exec("/sbin/ipfw pipe $bw_down_pipeno config bw {$bw_down}Kbit/s queue 100");
+ } else {
+ exec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to $clientip out");
+ }
+
+ /* add ipfw rules for layer 2 */
+ if (!isset($config['captiveportal']['nomacfilter'])) {
+ $l2ruleno = $ruleno + 10000;
+ exec("/sbin/ipfw add $l2ruleno set 3 deny all from $clientip to any not MAC any $clientmac layer2 in");
+ exec("/sbin/ipfw add $l2ruleno set 3 deny all from any to $clientip not MAC $clientmac any layer2 out");
+ }
+
+ /* encode password in Base64 just in case it contains commas */
+ $bpassword = base64_encode($password);
+ $cpdb[] = array(time(), $ruleno, $clientip, $clientmac, $username, $sessionid, $bpassword,
+ $attributes['session_timeout'],
+ $attributes['idle_timeout'],
+ $attributes['session_terminate_time']);
+
+ if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
+ $acct_val = RADIUS_ACCOUNTING_START($ruleno,
+ $username,
+ $sessionid,
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key'],
+ $clientip,
+ $clientmac);
+ if ($acct_val == 1)
+ captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED");
+ }
+
+
+ }
+
+ /* rewrite information to database */
+ captiveportal_write_db($cpdb);
+
+ /* redirect user to desired destination */
+ if ($url_redirection)
+ $my_redirurl = $url_redirection;
+ else if ($config['captiveportal']['redirurl'])
+ $my_redirurl = $config['captiveportal']['redirurl'];
+ else
+ $my_redirurl = $redirurl;
+
+ if(isset($config['captiveportal']['logoutwin_enable'])) {
+
+ if (isset($config['captiveportal']['httpslogin']))
+ $logouturl = "https://{$config['captiveportal']['httpsname']}:8001/";
+ else
+ $logouturl = "http://{$config['interfaces'][$config['captiveportal']['interface']]['ipaddr']}:8000/";
+
+ echo <<<EOD
<HTML>
<HEAD><TITLE>Redirecting...</TITLE></HEAD>
<BODY>
<SPAN STYLE="font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
-<B>Redirecting to <A HREF="{$redirurl}">{$redirurl}</A>...</B>
+<B>Redirecting to <A HREF="{$my_redirurl}">{$my_redirurl}</A>...</B>
</SPAN>
<SCRIPT LANGUAGE="JavaScript">
<!--
LogoutWin = window.open('', 'Logout', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=256,height=64');
if (LogoutWin) {
- LogoutWin.document.write('<HTML>');
- LogoutWin.document.write('<HEAD><TITLE>Logout</TITLE></HEAD>') ;
- LogoutWin.document.write('<BODY BGCOLOR="#435370">');
- LogoutWin.document.write('<DIV ALIGN="center" STYLE="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">') ;
- LogoutWin.document.write('<B>Click the button below to disconnect</B><P>');
- LogoutWin.document.write('<FORM METHOD="POST" ACTION="{$logouturl}">');
- LogoutWin.document.write('<INPUT NAME="logout_id" TYPE="hidden" VALUE="{$sessionid}">');
- LogoutWin.document.write('<INPUT NAME="logout" TYPE="submit" VALUE="Logout">');
- LogoutWin.document.write('</FORM>');
- LogoutWin.document.write('</DIV></BODY>');
- LogoutWin.document.write('</HTML>');
- LogoutWin.document.close();
+ LogoutWin.document.write('<HTML>');
+ LogoutWin.document.write('<HEAD><TITLE>Logout</TITLE></HEAD>') ;
+ LogoutWin.document.write('<BODY BGCOLOR="#435370">');
+ LogoutWin.document.write('<DIV ALIGN="center" STYLE="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">') ;
+ LogoutWin.document.write('<B>Click the button below to disconnect</B><P>');
+ LogoutWin.document.write('<FORM METHOD="POST" ACTION="{$logouturl}">');
+ LogoutWin.document.write('<INPUT NAME="logout_id" TYPE="hidden" VALUE="{$sessionid}">');
+ LogoutWin.document.write('<INPUT NAME="logout" TYPE="submit" VALUE="Logout">');
+ LogoutWin.document.write('</FORM>');
+ LogoutWin.document.write('</DIV></BODY>');
+ LogoutWin.document.write('</HTML>');
+ LogoutWin.document.close();
}
-document.location.href="{$redirurl}";
+document.location.href="{$my_redirurl}";
-->
</SCRIPT>
</BODY>
</HTML>
EOD;
- } else {
- header("Location: " . $redirurl);
- }
+ } else {
+ header("Location: " . $my_redirurl);
+ }
- return $sessionid;
+ captiveportal_unlock();
+ return $sessionid;
}
-/* read RADIUS servers into array */
-function captiveportal_get_radius_servers() {
-
- global $g;
-
- if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
- $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db","r");
- if ($fd) {
- $radiusservers = array();
- while (!feof($fd)) {
- $line = trim(fgets($fd));
- if ($line) {
- $radsrv = array();
- list($radsrv['ipaddr'],$radsrv['port'],$radsrv['acctport'],$radsrv['key']) = explode(",",$line);
- $radiusservers[] = $radsrv;
- }
- }
- fclose($fd);
-
- return $radiusservers;
- }
- }
- return false;
-}
-/* lock captive portal information, decide that the lock file is stale after
- 10 seconds */
-function portal_lock() {
-
- global $lockfile;
-
- $n = 0;
- while ($n < 10) {
- /* open the lock file in append mode to avoid race condition */
- if ($fd = @fopen($lockfile, "x")) {
- /* succeeded */
- fclose($fd);
- return;
- } else {
- /* file locked, wait and try again */
- sleep(1);
- $n++;
- }
- }
-}
+/* remove a single client by session ID
+ by Dinesh Nair
+ */
+function disconnect_client($sessionid, $logoutReason = "LOGOUT", $term_cause = 1) {
-/* unlock captive portal information file */
-function portal_unlock() {
+ global $g, $config;
- global $lockfile;
+ captiveportal_lock();
+ /* read database */
+ $cpdb = captiveportal_read_db();
- if (file_exists($lockfile))
- unlink($lockfile);
+ $radiusservers = captiveportal_get_radius_servers();
+
+ /* find entry */
+ for ($i = 0; $i < count($cpdb); $i++) {
+ if ($cpdb[$i][5] == $sessionid) {
+ captiveportal_disconnect($cpdb[$i],$radiusservers, $term_cause);
+ captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],$logoutReason);
+ unset($cpdb[$i]);
+ break;
+ }
+ }
+
+ /* write database */
+ captiveportal_write_db($cpdb);
+
+ captiveportal_unlock();
}
-/* remove a single client by session ID
- by Dinesh Nair
+/*
+ * This function will calculate the lowest free firewall ruleno
+ * within the range specified based on the actual installed rules
+ *
*/
-function disconnect_client($sessionid) {
-
- global $g, $config;
-
- portal_lock();
-
- /* read database */
- $cpdb = array() ;
- $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
- if ($fd) {
- while (!feof($fd)) {
- $line = trim(fgets($fd)) ;
- if($line) {
- $cpdb[] = explode(",",$line);
- }
- }
- fclose($fd);
- }
- $radiusservers = captiveportal_get_radius_servers();
-
- /* find entry */
- for ($i = 0; $i < count($cpdb); $i++) {
- if ($cpdb[$i][5] == $sessionid) {
- /* this client needs to be deleted - remove ipfw rules */
- if(isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
- RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno
- $cpdb[$i][4], // username
- $cpdb[$i][5], // sessionid
- $cpdb[$i][0], // start time
- $radiusservers[0]['ipaddr'],
- $radiusservers[0]['acctport'],
- $radiusservers[0]['key'],
- $cpdb[$i][2]);
- }
- mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
- captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"LOGOUT");
- unset($cpdb[$i]);
- break;
- }
- }
+function captiveportal_get_next_ipfw_ruleno($rulenos_start = 10000, $rulenos_range_max = 9899) {
- /* rewrite information to database */
- $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
- if ($fd) {
- foreach ($cpdb as $cpent) {
- fwrite($fd, join(",", $cpent) . "\n");
- }
- fclose($fd);
+ exec("/sbin/ipfw show", $fwrules);
+ foreach ($fwrules as $fwrule) {
+ preg_match("/^(\d+)\s+/", $fwrule, $matches);
+ $rulenos_used[] = $matches[1];
}
+ $rulenos_used = array_unique($rulenos_used);
+ $rulenos_range = count($rulenos_used);
+ if ($rulenos_range > $rulenos_range_max) {
+ return NULL;
+ }
+ $rulenos_pool = range($rulenos_start, ($rulenos_start + $rulenos_range));
+ $rulenos_free = array_diff($rulenos_pool, $rulenos_used);
+ $ruleno = array_shift($rulenos_free);
- portal_unlock();
-}
-
-/* log successful captive portal authentication to syslog */
-/* part of this code from php.net */
-function captiveportal_logportalauth($user,$mac,$ip,$status) {
- define_syslog_variables();
- openlog("logportalauth", LOG_PID, LOG_LOCAL4);
- // Log it
- syslog(LOG_INFO, "$status: $user, $mac, $ip");
- closelog();
+ return $ruleno;
}
-?>
+?> \ No newline at end of file
OpenPOWER on IntegriCloud