summaryrefslogtreecommitdiffstats
path: root/etc/inc/captiveportal.inc
diff options
context:
space:
mode:
authorScott Ullrich <sullrich@pfsense.org>2006-08-24 17:01:26 +0000
committerScott Ullrich <sullrich@pfsense.org>2006-08-24 17:01:26 +0000
commit36254e4a000239342d2acbac8dd4fbca7dc54bd5 (patch)
treee9ac8416013731e832a55c8eb37f84fc29af9655 /etc/inc/captiveportal.inc
parent4f652345020ae228ff7a29ee777c7b2290e994f7 (diff)
downloadpfsense-36254e4a000239342d2acbac8dd4fbca7dc54bd5.zip
pfsense-36254e4a000239342d2acbac8dd4fbca7dc54bd5.tar.gz
Carefully sync captive portal against m0n0wall 1.22
Diffstat (limited to 'etc/inc/captiveportal.inc')
-rw-r--r--etc/inc/captiveportal.inc917
1 files changed, 504 insertions, 413 deletions
diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc
index 28af59f..2e56b64 100644
--- a/etc/inc/captiveportal.inc
+++ b/etc/inc/captiveportal.inc
@@ -2,20 +2,20 @@
/*
captiveportal.inc
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
@@ -33,7 +33,7 @@
added rules which may have been created by other per-user code (index.php, etc).
These changes are (c) 2004 Keycom PLC.
*/
-
+
/* include all configuration functions */
require_once("functions.inc");
require_once("radius_authentication.inc");
@@ -43,27 +43,27 @@ $lockfile = "{$g['varrun_path']}/captiveportal.lock";
function captiveportal_configure() {
global $config, $g;
-
+
if (isset($config['captiveportal']['enable']) &&
(($config['captiveportal']['interface'] == "lan") ||
isset($config['interfaces'][$config['captiveportal']['interface']]['enable']))) {
-
+
if ($g['booting'])
echo "Starting captive portal... ";
-
+
/* kill any running mini_httpd */
killbypid("{$g['varrun_path']}/lighty-CaptivePortal.pid");
killbypid("{$g['varrun_path']}/lighty-CaptivePortal-SSL.pid");
-
+
/* kill any running minicron */
killbypid("{$g['varrun_path']}/minicron.pid");
-
+
/* generate ipfw rules */
$cprules = captiveportal_rules_generate();
-
+
/* make sure ipfw is loaded */
mwexec("/sbin/kldload ipfw");
-
+
/* stop accounting on all clients */
captiveportal_radius_stop_all();
@@ -74,12 +74,11 @@ function captiveportal_configure() {
if ((!is_numeric($croninterval)) || ($croninterval < 10)) { $croninterval = 60; }
/* remove old information */
- unlink_if_exists("{$g['vardb_path']}/captiveportal.nextrule");
- unlink_if_exists("{$g['vardb_path']}/captiveportal.db");
- unlink_if_exists("{$g['vardb_path']}/captiveportal_mac.db");
- unlink_if_exists("{$g['vardb_path']}/captiveportal_ip.db");
- unlink_if_exists("{$g['vardb_path']}/captiveportal_radius.db");
-
+ unlink_if_exists("{$g['vardb_path']}/captiveportal.db");
+ unlink_if_exists("{$g['vardb_path']}/captiveportal_mac.db");
+ unlink_if_exists("{$g['vardb_path']}/captiveportal_ip.db");
+ unlink_if_exists("{$g['vardb_path']}/captiveportal_radius.db");
+
/* write portal page */
if ($config['captiveportal']['page']['htmltext'])
$htmltext = base64_decode($config['captiveportal']['page']['htmltext']);
@@ -120,9 +119,9 @@ EOD;
$fd = @fopen("{$g['varetc_path']}/captiveportal.html", "w");
if ($fd) {
fwrite($fd, $htmltext);
- fclose($fd);
+ fclose($fd);
}
-
+
/* write error page */
if ($config['captiveportal']['page']['errtext'])
$errtext = base64_decode($config['captiveportal']['page']['errtext']);
@@ -149,9 +148,9 @@ EOD;
$fd = @fopen("{$g['varetc_path']}/captiveportal-error.html", "w");
if ($fd) {
fwrite($fd, $errtext);
- fclose($fd);
+ fclose($fd);
}
-
+
/* write elements */
captiveportal_write_elements();
@@ -159,7 +158,7 @@ EOD;
mwexec("/sbin/ipfw -f delete set 1");
mwexec("/sbin/ipfw -f delete set 2");
mwexec("/sbin/ipfw -f delete set 3");
-
+
/* ipfw cannot accept rules directly on stdin,
so we have to write them to a temporary file first */
$fd = @fopen("{$g['tmp_path']}/ipfw.cp.rules", "w");
@@ -167,19 +166,19 @@ EOD;
printf("Cannot open ipfw.cp.rules in captiveportal_configure()\n");
return 1;
}
-
+
fwrite($fd, $cprules);
fclose($fd);
-
+
mwexec("/sbin/ipfw {$g['tmp_path']}/ipfw.cp.rules");
-
+
unlink("{$g['tmp_path']}/ipfw.cp.rules");
-
+
/* filter on layer2 as well so we can check MAC addresses */
mwexec("/sbin/sysctl net.link.ether.ipfw=1");
-
+
chdir($g['captiveportal_path']);
-
+
/* TEMPORARY! FAST_CGI reports _FALSE_ client ip
* addresses.
*/
@@ -189,7 +188,7 @@ EOD;
$maxproc = $config['captiveportal']['maxproc'];
else
$maxproc = 16;
-
+
if(isset($config['captiveportal']['httpslogin'])) {
$cert = base64_decode($config['captiveportal']['certificate']);
$key = base64_decode($config['captiveportal']['private-key']);
@@ -198,68 +197,68 @@ EOD;
$cert, $key, "lighty-CaptivePortal-ssl.pid", "8001", "/usr/local/captiveportal/",
"cert-portal.pem", "1", $maxproc, $use_fastcgi, true);
}
-
+
/* generate lighttpd configuration */
system_generate_lighty_config("{$g['varetc_path']}/lighty-CaptivePortal.conf",
"", "", "lighty-CaptivePortal.pid", "8000", "/usr/local/captiveportal/",
"cert-portal.pem", "1", $maxproc, $use_fastcgi, true);
-
+
/* attempt to start lighttpd */
$res = mwexec("/usr/local/sbin/lighttpd -f {$g['varetc_path']}/lighty-CaptivePortal.conf");
-
+
/* fire up https instance */
if(isset($config['captiveportal']['httpslogin']))
$res = mwexec("/usr/local/sbin/lighttpd -f {$g['varetc_path']}/lighty-CaptivePortal-SSL.conf");
-
+
/* start pruning process (interval defaults to 60 seconds) */
mwexec("/usr/local/bin/minicron $croninterval {$g['varrun_path']}/minicron.pid " .
"/etc/rc.prunecaptiveportal");
-
+
/* generate passthru mac database */
captiveportal_passthrumac_configure();
/* create allowed ip database and insert ipfw rules to make it so */
captiveportal_allowedip_configure();
-
- /* generate radius server database */
- if ($config['captiveportal']['radiusip'] && (!isset($config['captiveportal']['auth_method']) ||
- ($config['captiveportal']['auth_method'] == "radius"))) {
- $radiusip = $config['captiveportal']['radiusip'];
- $radiusip2 = ($config['captiveportal']['radiusip2']) ? $config['captiveportal']['radiusip2'] : null;
-
- if ($config['captiveportal']['radiusport'])
- $radiusport = $config['captiveportal']['radiusport'];
- else
- $radiusport = 1812;
-
- if ($config['captiveportal']['radiusacctport'])
- $radiusacctport = $config['captiveportal']['radiusacctport'];
- else
- $radiusacctport = 1813;
-
- if ($config['captiveportal']['radiusport2'])
- $radiusport2 = $config['captiveportal']['radiusport2'];
- else
- $radiusport2 = 1812;
-
- $radiuskey = $config['captiveportal']['radiuskey'];
- $radiuskey2 = ($config['captiveportal']['radiuskey2']) ? $config['captiveportal']['radiuskey2'] : null;
-
- $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db", "w");
- if (!$fd) {
- printf("Error: cannot open radius DB file in captiveportal_configure().\n");
- return 1;
- } else if (isset($radiusip2, $radiuskey2)) {
- fwrite($fd,$radiusip . "," . $radiusport . "," . $radiusacctport . "," . $radiuskey . "\n"
- . $radiusip2 . "," . $radiusport2 . "," . $radiusacctport . "," . $radiuskey2);
- } else {
- fwrite($fd,$radiusip . "," . $radiusport . "," . $radiusacctport . "," . $radiuskey);
- }
- fclose($fd);
- }
- if ($g['booting'])
- echo "done\n";
-
+ /* generate radius server database */
+ if ($config['captiveportal']['radiusip'] && (!isset($config['captiveportal']['auth_method']) ||
+ ($config['captiveportal']['auth_method'] == "radius"))) {
+ $radiusip = $config['captiveportal']['radiusip'];
+ $radiusip2 = ($config['captiveportal']['radiusip2']) ? $config['captiveportal']['radiusip2'] : null;
+
+ if ($config['captiveportal']['radiusport'])
+ $radiusport = $config['captiveportal']['radiusport'];
+ else
+ $radiusport = 1812;
+
+ if ($config['captiveportal']['radiusacctport'])
+ $radiusacctport = $config['captiveportal']['radiusacctport'];
+ else
+ $radiusacctport = 1813;
+
+ if ($config['captiveportal']['radiusport2'])
+ $radiusport2 = $config['captiveportal']['radiusport2'];
+ else
+ $radiusport2 = 1812;
+
+ $radiuskey = $config['captiveportal']['radiuskey'];
+ $radiuskey2 = ($config['captiveportal']['radiuskey2']) ? $config['captiveportal']['radiuskey2'] : null;
+
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db", "w");
+ if (!$fd) {
+ printf("Error: cannot open radius DB file in captiveportal_configure().\n");
+ return 1;
+ } else if (isset($radiusip2, $radiuskey2)) {
+ fwrite($fd,$radiusip . "," . $radiusport . "," . $radiusacctport . "," . $radiuskey . "\n"
+ . $radiusip2 . "," . $radiusport2 . "," . $radiusacctport . "," . $radiuskey2);
+ } else {
+ fwrite($fd,$radiusip . "," . $radiusport . "," . $radiusacctport . "," . $radiuskey);
+ }
+ fclose($fd);
+ }
+
+ if ($g['booting'])
+ echo "done\n";
+
} else {
killbypid("{$g['varrun_path']}/lighty-CaptivePortal.pid");
killbypid("{$g['varrun_path']}/minicron.pid");
@@ -278,13 +277,13 @@ EOD;
mwexec("/sbin/ipfw -f delete set 3");
}
}
-
+
return 0;
}
function captiveportal_rules_generate() {
global $config, $g;
-
+
$cpifn = $config['captiveportal']['interface'];
$cpif = $config['interfaces'][$cpifn]['if'];
$cpip = $config['interfaces'][$cpifn]['ipaddr'];
@@ -299,15 +298,15 @@ function captiveportal_rules_generate() {
*/
$iflist = array("lan" => "LAN", "wan" => "WAN");
$captive_portal_interface = strtoupper($cpifn);
- for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
- $iflist['opt' . $i] = "OPT{$i}";
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
+ $iflist['opt' . $i] = "OPT{$i}";
foreach ($iflist as $ifent => $ifname) {
if($captive_portal_interface == strtoupper($ifname))
continue;
$int = convert_friendly_interface_to_real_interface_name($ifname);
$cprules .= "add 30 set 1 skipto 50000 all from any to any in via {$int} keep-state\n";
}
-
+
/* captive portal on LAN interface? */
if ($cpifn == "lan") {
/* add anti-lockout rules */
@@ -329,7 +328,7 @@ add 1100 set 1 pass layer2 mac-type arp
# pfsense requires for WPA
add 1100 set 1 pass layer2 mac-type 0x888e
-# PPP Over Ethernet Discovery Stage
+# PPP Over Ethernet Discovery Stage
add 1100 set 1 pass layer2 mac-type 0x8863
# PPP Over Ethernet Session Stage
add 1100 set 1 pass layer2 mac-type 0x8864
@@ -363,7 +362,7 @@ add 1305 set 1 pass tcp from $cpip 8001 to any out
EOD;
}
-
+
$cprules .= <<<EOD
# ... 10000-19899: rules per authenticated client go here...
@@ -396,265 +395,265 @@ EOD;
}
/* remove clients that have been around for longer than the specified amount of time */
-/* db file structure:
+/* db file structure:
timestamp,ipfw_rule_no,clientip,clientmac,username,sessionid,password,session_timeout,idle_timeout,session_terminate_time */
/* (password is in Base64 and only saved when reauthentication is enabled) */
function captiveportal_prune_old() {
-
- global $g, $config;
-
- /* check for expired entries */
- if ($config['captiveportal']['timeout'])
- $timeout = $config['captiveportal']['timeout'] * 60;
- else
- $timeout = 0;
-
- if ($config['captiveportal']['idletimeout'])
- $idletimeout = $config['captiveportal']['idletimeout'] * 60;
- else
- $idletimeout = 0;
-
- if (!$timeout && !$idletimeout && !isset($config['captiveportal']['reauthenticate']))
- return;
-
- captiveportal_lock();
-
- /* read database */
- $cpdb = captiveportal_read_db();
-
- $radiusservers = captiveportal_get_radius_servers();
-
- for ($i = 0; $i < count($cpdb); $i++) {
-
- $timedout = false;
- $term_cause = 1;
-
- /* hard timeout? */
- if ($timeout) {
- if ((time() - $cpdb[$i][0]) >= $timeout) {
- $timedout = true;
- $term_cause = 5; // Session-Timeout
- }
- }
- /* Session-Terminate-Time */
- if (!$timedout && !empty($cpdb[$i][9])) {
- if (time() >= $cpdb[$i][9]) {
- $timedout = true;
- $term_cause = 5; // Session-Timeout
- }
- }
-
- /* check if the radius idle_timeout attribute has been set and if its set change the idletimeout to this value */
- $idletimeout = (is_numeric($cpdb[$i][8])) ? $cpdb[$i][8] : $idletimeout;
- /* if an idle timeout is specified, get last activity timestamp from ipfw */
- if (!$timedout && $idletimeout) {
- $lastact = captiveportal_get_last_activity($cpdb[$i][1]);
- if ($lastact && ((time() - $lastact) >= $idletimeout)) {
- $timedout = true;
- $term_cause = 4; // Idle-Timeout
- $stop_time = $lastact; // Entry added to comply with WISPr
- }
- }
+ global $g, $config;
- /* if radius session_timeout is enabled and the session_timeout is not null, then check if the user should be logged out */
- if (!$timedout && isset($config['captiveportal']['radiussession_timeout']) && !empty($cpdb[$i][7])) {
- if (time() >= ($cpdb[$i][0] + $cpdb[$i][7])) {
- $timedout = true;
- $term_cause = 5; // Session-Timeout
- }
- }
-
- if ($timedout) {
- captiveportal_disconnect($cpdb[$i], $radiusservers,$term_cause,$stop_time);
- captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "TIMEOUT");
- unset($cpdb[$i]);
- }
-
- /* do periodic RADIUS reauthentication? */
- if (!$timedout && isset($config['captiveportal']['reauthenticate']) &&
- ($radiusservers !== false)) {
-
- if (isset($config['captiveportal']['radacct_enable'])) {
- if ($config['captiveportal']['reauthenticateacct'] == "stopstart") {
- /* stop and restart accounting */
- 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], // clientip
- $cpdb[$i][3], // clientmac
- 10); // NAS Request
- exec("/sbin/ipfw zero {$cpdb[$i][1]}");
- RADIUS_ACCOUNTING_START($cpdb[$i][1], // ruleno
- $cpdb[$i][4], // username
- $cpdb[$i][5], // sessionid
- $radiusservers[0]['ipaddr'],
- $radiusservers[0]['acctport'],
- $radiusservers[0]['key'],
- $cpdb[$i][2], // clientip
- $cpdb[$i][3]); // clientmac
- } else if ($config['captiveportal']['reauthenticateacct'] == "interimupdate") {
- 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], // clientip
- $cpdb[$i][3], // clientmac
- 10, // NAS Request
- true); // Interim Updates
- }
- }
-
- /* check this user against RADIUS again */
- $auth_list = RADIUS_AUTHENTICATION($cpdb[$i][4], // username
- base64_decode($cpdb[$i][6]), // password
- $radiusservers,
- $cpdb[$i][2], // clientip
- $cpdb[$i][3], // clientmac
- $cpdb[$i][1]); // ruleno
-
- if ($auth_list['auth_val'] == 3) {
- captiveportal_disconnect($cpdb[$i], $radiusservers, 17);
- captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "RADIUS_DISCONNECT", $auth_list['reply_message']);
- unset($cpdb[$i]);
- }
- }
- }
-
- /* write database */
- captiveportal_write_db($cpdb);
-
- captiveportal_unlock();
+ /* check for expired entries */
+ if ($config['captiveportal']['timeout'])
+ $timeout = $config['captiveportal']['timeout'] * 60;
+ else
+ $timeout = 0;
+
+ if ($config['captiveportal']['idletimeout'])
+ $idletimeout = $config['captiveportal']['idletimeout'] * 60;
+ else
+ $idletimeout = 0;
+
+ if (!$timeout && !$idletimeout && !isset($config['captiveportal']['reauthenticate']) && !isset($config['captiveportal']['radiussession_timeout']))
+ return;
+
+ captiveportal_lock();
+
+ /* read database */
+ $cpdb = captiveportal_read_db();
+
+ $radiusservers = captiveportal_get_radius_servers();
+
+ for ($i = 0; $i < count($cpdb); $i++) {
+
+ $timedout = false;
+ $term_cause = 1;
+
+ /* hard timeout? */
+ if ($timeout) {
+ if ((time() - $cpdb[$i][0]) >= $timeout) {
+ $timedout = true;
+ $term_cause = 5; // Session-Timeout
+ }
+ }
+
+ /* Session-Terminate-Time */
+ if (!$timedout && !empty($cpdb[$i][9])) {
+ if (time() >= $cpdb[$i][9]) {
+ $timedout = true;
+ $term_cause = 5; // Session-Timeout
+ }
+ }
+
+ /* check if the radius idle_timeout attribute has been set and if its set change the idletimeout to this value */
+ $idletimeout = (is_numeric($cpdb[$i][8])) ? $cpdb[$i][8] : $idletimeout;
+ /* if an idle timeout is specified, get last activity timestamp from ipfw */
+ if (!$timedout && $idletimeout) {
+ $lastact = captiveportal_get_last_activity($cpdb[$i][1]);
+ if ($lastact && ((time() - $lastact) >= $idletimeout)) {
+ $timedout = true;
+ $term_cause = 4; // Idle-Timeout
+ $stop_time = $lastact; // Entry added to comply with WISPr
+ }
+ }
+
+ /* if radius session_timeout is enabled and the session_timeout is not null, then check if the user should be logged out */
+ if (!$timedout && isset($config['captiveportal']['radiussession_timeout']) && !empty($cpdb[$i][7])) {
+ if (time() >= ($cpdb[$i][0] + $cpdb[$i][7])) {
+ $timedout = true;
+ $term_cause = 5; // Session-Timeout
+ }
+ }
+
+ if ($timedout) {
+ captiveportal_disconnect($cpdb[$i], $radiusservers,$term_cause,$stop_time);
+ captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "TIMEOUT");
+ unset($cpdb[$i]);
+ }
+
+ /* do periodic RADIUS reauthentication? */
+ if (!$timedout && isset($config['captiveportal']['reauthenticate']) &&
+ ($radiusservers !== false)) {
+
+ if (isset($config['captiveportal']['radacct_enable'])) {
+ if ($config['captiveportal']['reauthenticateacct'] == "stopstart") {
+ /* stop and restart accounting */
+ 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], // clientip
+ $cpdb[$i][3], // clientmac
+ 10); // NAS Request
+ exec("/sbin/ipfw zero {$cpdb[$i][1]}");
+ RADIUS_ACCOUNTING_START($cpdb[$i][1], // ruleno
+ $cpdb[$i][4], // username
+ $cpdb[$i][5], // sessionid
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key'],
+ $cpdb[$i][2], // clientip
+ $cpdb[$i][3]); // clientmac
+ } else if ($config['captiveportal']['reauthenticateacct'] == "interimupdate") {
+ 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], // clientip
+ $cpdb[$i][3], // clientmac
+ 10, // NAS Request
+ true); // Interim Updates
+ }
+ }
+
+ /* check this user against RADIUS again */
+ $auth_list = RADIUS_AUTHENTICATION($cpdb[$i][4], // username
+ base64_decode($cpdb[$i][6]), // password
+ $radiusservers,
+ $cpdb[$i][2], // clientip
+ $cpdb[$i][3], // clientmac
+ $cpdb[$i][1]); // ruleno
+
+ if ($auth_list['auth_val'] == 3) {
+ captiveportal_disconnect($cpdb[$i], $radiusservers, 17);
+ captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "RADIUS_DISCONNECT", $auth_list['reply_message']);
+ unset($cpdb[$i]);
+ }
+ }
+ }
+
+ /* write database */
+ captiveportal_write_db($cpdb);
+
+ captiveportal_unlock();
}
/* remove a single client according to the DB entry */
function captiveportal_disconnect($dbent, $radiusservers,$term_cause = 1,$stop_time = null) {
-
- global $g, $config;
-
- $stop_time = (empty($stop_time)) ? time() : $stop_time;
-
- /* this client needs to be deleted - remove ipfw rules */
- if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
- RADIUS_ACCOUNTING_STOP($dbent[1], // ruleno
- $dbent[4], // username
- $dbent[5], // sessionid
- $dbent[0], // start time
- $radiusservers[0]['ipaddr'],
- $radiusservers[0]['acctport'],
- $radiusservers[0]['key'],
- $dbent[2], // clientip
- $dbent[3], // clientmac
- $term_cause, // Acct-Terminate-Cause
- false,
- $stop_time);
- }
-
- mwexec("/sbin/ipfw delete " . $dbent[1] . " " . ($dbent[1]+10000));
-
- //KEYCOM: we need to delete +40500 and +45500 as well...
- //these are the rule numbers we use to control traffic shaping for each logged in user via captive portal
- //we only need to remove our rules if peruserbw is turned on.
- if (isset($config['captiveportal']['peruserbw'])) {
- mwexec("/sbin/ipfw delete " . ($dbent[1]+40500));
- mwexec("/sbin/ipfw delete " . ($dbent[1]+45500));
- }
+
+ global $g, $config;
+
+ $stop_time = (empty($stop_time)) ? time() : $stop_time;
+
+ /* this client needs to be deleted - remove ipfw rules */
+ if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
+ RADIUS_ACCOUNTING_STOP($dbent[1], // ruleno
+ $dbent[4], // username
+ $dbent[5], // sessionid
+ $dbent[0], // start time
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key'],
+ $dbent[2], // clientip
+ $dbent[3], // clientmac
+ $term_cause, // Acct-Terminate-Cause
+ false,
+ $stop_time);
+ }
+
+ mwexec("/sbin/ipfw delete " . $dbent[1] . " " . ($dbent[1]+10000));
+
+ //KEYCOM: we need to delete +40500 and +45500 as well...
+ //these are the rule numbers we use to control traffic shaping for each logged in user via captive portal
+ //we only need to remove our rules if peruserbw is turned on.
+ if (isset($config['captiveportal']['peruserbw'])) {
+ mwexec("/sbin/ipfw delete " . ($dbent[1]+40500));
+ mwexec("/sbin/ipfw delete " . ($dbent[1]+45500));
+ }
}
/* remove a single client by ipfw rule number */
function captiveportal_disconnect_client($id,$term_cause = 1) {
-
- global $g, $config;
-
- captiveportal_lock();
-
- /* read database */
- $cpdb = captiveportal_read_db();
- $radiusservers = captiveportal_get_radius_servers();
-
- /* find entry */
- for ($i = 0; $i < count($cpdb); $i++) {
- if ($cpdb[$i][1] == $id) {
- captiveportal_disconnect($cpdb[$i], $radiusservers, $term_cause);
- captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "DISCONNECT");
- unset($cpdb[$i]);
- break;
- }
- }
-
- /* write database */
- captiveportal_write_db($cpdb);
-
- captiveportal_unlock();
+
+ global $g, $config;
+
+ captiveportal_lock();
+
+ /* read database */
+ $cpdb = captiveportal_read_db();
+ $radiusservers = captiveportal_get_radius_servers();
+
+ /* find entry */
+ for ($i = 0; $i < count($cpdb); $i++) {
+ if ($cpdb[$i][1] == $id) {
+ captiveportal_disconnect($cpdb[$i], $radiusservers, $term_cause);
+ captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "DISCONNECT");
+ unset($cpdb[$i]);
+ break;
+ }
+ }
+
+ /* write database */
+ captiveportal_write_db($cpdb);
+
+ captiveportal_unlock();
}
/* send RADIUS acct stop for all current clients */
function captiveportal_radius_stop_all() {
- global $g, $config;
-
- if (!isset($config['captiveportal']['radacct_enable']))
- return;
-
- captiveportal_lock();
- $cpdb = captiveportal_read_db();
-
- $radiusservers = captiveportal_get_radius_servers();
-
- if (isset($radiusservers[0])) {
- for ($i = 0; $i < count($cpdb); $i++) {
- 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], // clientip
- $cpdb[$i][3], // clientmac
- 7); // Admin Reboot
- }
- }
- captiveportal_unlock();
+ global $g, $config;
+
+ if (!isset($config['captiveportal']['radacct_enable']))
+ return;
+
+ captiveportal_lock();
+ $cpdb = captiveportal_read_db();
+
+ $radiusservers = captiveportal_get_radius_servers();
+
+ if (isset($radiusservers[0])) {
+ for ($i = 0; $i < count($cpdb); $i++) {
+ 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], // clientip
+ $cpdb[$i][3], // clientmac
+ 7); // Admin Reboot
+ }
+ }
+ captiveportal_unlock();
}
function captiveportal_passthrumac_configure() {
global $config, $g;
-
+
captiveportal_lock();
-
+
/* clear out passthru macs, if necessary */
unlink_if_exists("{$g['vardb_path']}/captiveportal_mac.db");
-
+
if (is_array($config['captiveportal']['passthrumac'])) {
-
+
$fd = @fopen("{$g['vardb_path']}/captiveportal_mac.db", "w");
if (!$fd) {
printf("Error: cannot open passthru mac DB file in captiveportal_passthrumac_configure().\n");
captiveportal_unlock();
- return 1;
+ return 1;
}
-
+
foreach ($config['captiveportal']['passthrumac'] as $macent) {
/* record passthru mac so it can be recognized and let thru */
fwrite($fd, $macent['mac'] . "\n");
}
-
- fclose($fd);
+
+ fclose($fd);
}
/* pass through mac entries should always exist. the reason
* for this is because we do not have native mac address filtering
* mechanisms. this allows us to filter by mac address easily
* and get around this limitation. I consider this a bug in
- * m0n0wall and pfSense as m0n0wall does not have native mac
+ * m0n0wall and pfSense as m0n0wall does not have native mac
* filtering mechanisms as well. -Scott Ullrich
*/
if (is_array($config['captiveportal']['passthrumac'])) {
@@ -668,13 +667,13 @@ function captiveportal_passthrumac_configure() {
}
captiveportal_unlock();
-
+
return 0;
}
function captiveportal_allowedip_configure() {
global $config, $g;
-
+
captiveportal_lock();
/* clear out existing allowed ips, if necessary */
@@ -686,7 +685,7 @@ function captiveportal_allowedip_configure() {
if ($line) {
list($ip,$rule) = explode(",",$line);
mwexec("/sbin/ipfw delete $rule");
- }
+ }
}
}
fclose($fd);
@@ -698,21 +697,21 @@ function captiveportal_allowedip_configure() {
$ruleno = trim(file_get_contents("{$g['vardb_path']}/captiveportal.nextrule"));
if (!$ruleno)
$ruleno = 10000; /* first rule number */
-
+
if (is_array($config['captiveportal']['allowedip'])) {
-
+
$fd = @fopen("{$g['vardb_path']}/captiveportal_ip.db", "w");
if (!$fd) {
printf("Error: cannot open allowed ip DB file in captiveportal_allowedip_configure().\n");
captiveportal_unlock();
- return 1;
+ return 1;
}
-
+
foreach ($config['captiveportal']['allowedip'] as $ipent) {
-
+
/* record allowed ip so it can be recognized and removed later */
fwrite($fd, $ipent['ip'] . "," . $ruleno ."\n");
-
+
/* insert ipfw rule to allow ip thru */
if ($ipent['dir'] == "from") {
mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from " . $ipent['ip'] . " to any in");
@@ -721,13 +720,13 @@ function captiveportal_allowedip_configure() {
mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to " . $ipent['ip'] . " in");
mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from " . $ipent['ip'] . " to any out");
}
-
+
$ruleno++;
if ($ruleno > 19899)
$ruleno = 10000;
}
-
- fclose($fd);
+
+ fclose($fd);
/* write next rule number */
$fd = @fopen("{$g['vardb_path']}/captiveportal.nextrule", "w");
@@ -736,26 +735,24 @@ function captiveportal_allowedip_configure() {
fclose($fd);
}
}
-
+
captiveportal_unlock();
return 0;
}
/* get last activity timestamp given ipfw rule number */
function captiveportal_get_last_activity($ruleno) {
-
- $ipfwoutput = "";
-
- exec("/sbin/ipfw -T list {$ruleno} 2>/dev/null", $ipfwoutput);
-
- /* in */
- if ($ipfwoutput[0]) {
- $ri = explode(" ", $ipfwoutput[0]);
- if ($ri[1])
- return $ri[1];
- }
-
- return 0;
+
+ exec("/sbin/ipfw -T list {$ruleno} 2>/dev/null", $ipfwoutput);
+
+ /* in */
+ if ($ipfwoutput[0]) {
+ $ri = explode(" ", $ipfwoutput[0]);
+ if ($ri[1])
+ return $ri[1];
+ }
+
+ return 0;
}
/* read RADIUS servers into array */
@@ -817,57 +814,63 @@ function captiveportal_unlock() {
/* log successful captive portal authentication to syslog */
/* part of this code from php.net */
function captiveportal_logportalauth($user,$mac,$ip,$status, $message = null) {
- define_syslog_variables();
- $message = trim($message);
- openlog("logportalauth", LOG_PID, LOG_LOCAL4);
- // Log it
- if (!$message)
- syslog(LOG_INFO, "$status: $user, $mac, $ip");
- else
- syslog(LOG_INFO, "$status: $user, $mac, $ip, $message");
- closelog();
+ define_syslog_variables();
+ $message = trim($message);
+ openlog("logportalauth", LOG_PID, LOG_LOCAL4);
+ // Log it
+ if (!$message)
+ syslog(LOG_INFO, "$status: $user, $mac, $ip");
+ else
+ syslog(LOG_INFO, "$status: $user, $mac, $ip, $message");
+ closelog();
}
function radius($username,$password,$clientip,$clientmac,$type) {
- global $g, $config;
-
- $next_ruleno = get_next_ipfw_ruleno();
- $radiusservers = captiveportal_get_radius_servers();
- $radacct_enable = isset($config['captiveportal']['radacct_enable']);
-
- $auth_list = RADIUS_AUTHENTICATION($username,
- $password,
- $radiusservers,
- $clientip,
- $clientmac,
- $next_ruleno);
-
- if ($auth_list['auth_val'] == 2) {
- captiveportal_logportalauth($username,$clientmac,$clientip,$type);
- $sessionid = portal_allow($clientip,
- $clientmac,
- $username,
- $password,
- $auth_list['session_timeout'],
- $auth_list['idle_timeout'],
- $auth_list['url_redirection'],
- $auth_list['session_terminate_time']);
-
- if ($radacct_enable) {
- $auth_list['acct_val'] = RADIUS_ACCOUNTING_START($next_ruleno,
- $username,
- $sessionid,
- $radiusservers[0]['ipaddr'],
- $radiusservers[0]['acctport'],
- $radiusservers[0]['key'],
- $clientip,
- $clientmac);
- if ($auth_list['acct_val'] == 1)
- captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED");
- }
- }
+ global $g, $config;
+
+ $ruleno = captiveportal_get_next_ipfw_ruleno();
+
+ /* if the pool is empty, return apprioriate message and fail authentication */
+ if (is_null($ruleno)) {
+ $auth_list = array();
+ $auth_list['auth_val'] = 1;
+ $auth_list['error'] = "System reached maximum login capacity";
+ return $auth_list;
+ }
+
+ $radiusservers = captiveportal_get_radius_servers();
+ $radacct_enable = isset($config['captiveportal']['radacct_enable']);
+
+ $auth_list = RADIUS_AUTHENTICATION($username,
+ $password,
+ $radiusservers,
+ $clientip,
+ $clientmac,
+ $ruleno);
+
+ if ($auth_list['auth_val'] == 2) {
+ captiveportal_logportalauth($username,$clientmac,$clientip,$type);
+ $sessionid = portal_allow($clientip,
+ $clientmac,
+ $username,
+ $password,
+ $auth_list);
+
+ if ($radacct_enable) {
+ $auth_list['acct_val'] = RADIUS_ACCOUNTING_START($ruleno,
+ $username,
+ $sessionid,
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key'],
+ $clientip,
+ $clientmac);
+ if ($auth_list['acct_val'] == 1)
+ captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED");
+ }
+ }
- return $auth_list;
+ return $auth_list;
}
@@ -892,52 +895,140 @@ function captiveportal_read_db() {
/* write captive portal DB */
function captiveportal_write_db($cpdb) {
-
+
global $g;
-
+
$fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
- if ($fd) {
+ if ($fd) {
foreach ($cpdb as $cpent) {
fwrite($fd, join(",", $cpent) . "\n");
- }
+ }
fclose($fd);
- }
+ }
}
function captiveportal_write_elements() {
- global $g, $config;
-
- /* delete any existing elements */
- if (is_dir($g['captiveportal_element_path'])) {
- $dh = opendir($g['captiveportal_element_path']);
- while (($file = readdir($dh)) !== false) {
- if ($file != "." && $file != "..")
- unlink($g['captiveportal_element_path'] . "/" . $file);
- }
- closedir($dh);
- } else {
- mkdir($g['captiveportal_element_path']);
- }
-
- if (is_array($config['captiveportal']['element'])) {
- conf_mount_rw();
- foreach ($config['captiveportal']['element'] as $data) {
- $fd = @fopen($g['captiveportal_element_path'] . '/' . $data['name'], "wb");
- if (!$fd) {
- printf("Error: cannot open '{$data['name']}' in captiveportal_write_elements().\n");
- return 1;
- }
- $decoded = base64_decode($data['content']);
- fwrite($fd,$decoded);
- fclose($fd);
- unlink_if_exists("{$g['captiveportal_path']}/{$data['name']}");
- unlink_if_exists("{$g['captiveportal_path']}/{$data['name']}");
- mwexec("cd {$g['captiveportal_path']}/ && ln -s {$g['captiveportal_element_path']}/{$data['name']} {$data['name']}");
- }
- conf_mount_ro();
- }
-
- return 0;
+ global $g, $config;
+
+ /* delete any existing elements */
+ if (is_dir($g['captiveportal_element_path'])) {
+ $dh = opendir($g['captiveportal_element_path']);
+ while (($file = readdir($dh)) !== false) {
+ if ($file != "." && $file != "..")
+ unlink($g['captiveportal_element_path'] . "/" . $file);
+ }
+ closedir($dh);
+ } else {
+ mkdir($g['captiveportal_element_path']);
+ }
+
+ if (is_array($config['captiveportal']['element'])) {
+
+ foreach ($config['captiveportal']['element'] as $data) {
+ $fd = @fopen($g['captiveportal_element_path'] . '/' . $data['name'], "wb");
+ if (!$fd) {
+ printf("Error: cannot open '{$data['name']}' in captiveportal_write_elements().\n");
+ return 1;
+ }
+ $decoded = base64_decode($data['content']);
+ fwrite($fd,$decoded);
+ fclose($fd);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * This function will calculate the lowest free firewall ruleno
+ * within the range specified based on the actual installed rules
+ *
+ */
+
+function captiveportal_get_next_ipfw_ruleno($rulenos_start = 10000, $rulenos_range_max = 9899) {
+ $fwrules = "";
+ 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);
+
+ return $ruleno;
+}
+
+
+/**
+ * This function will calculate the traffic produced by a client
+ * based on its firewall rule
+ *
+ * Point of view: NAS
+ *
+ * Input means: from the client
+ * Output means: to the client
+ *
+ */
+
+function getVolume($ruleno) {
+
+ $volume = array();
+
+ // Initialize vars properly, since we don't want NULL vars
+ $volume['input_pkts'] = $volume['input_bytes'] = $volume['output_pkts'] = $volume['output_bytes'] = 0 ;
+
+ // Ingress
+ $ipfw = "";
+ exec("/sbin/ipfw show {$ruleno}", $ipfw);
+ preg_match("/(\d+)\s+(\d+)\s+(\d+)\s+skipto/", $ipfw[0], $matches);
+ $volume['input_pkts'] = $matches[2];
+ $volume['input_bytes'] = $matches[3];
+
+ // Flush internal buffer
+ unset($matches);
+
+ // Outgress
+ preg_match("/(\d+)\s+(\d+)\s+(\d+)\s+skipto/", $ipfw[1], $matches);
+ $volume['output_pkts'] = $matches[2];
+ $volume['output_bytes'] = $matches[3];
+
+ return $volume;
+}
+
+/**
+ * Get the NAS-Identifier
+ *
+ * We will use our local hostname to make up the nas_id
+ */
+
+function getNasID()
+{
+ $nasId = "";
+ exec("/bin/hostname", $nasId);
+ if(!$nasId[0])
+ $nasId[0] = "m0n0wall";
+ return $nasId[0];
+}
+
+/**
+ * Get the NAS-IP-Address based on the current wan address
+ *
+ * Use functions in interfaces.inc to find this out
+ *
+ */
+
+function getNasIP()
+{
+ $nasIp = get_current_wan_address();
+ if(!$nasIp)
+ $nasIp = "0.0.0.0";
+ return $nasIp;
}
-?>
+?> \ No newline at end of file
OpenPOWER on IntegriCloud