summaryrefslogtreecommitdiffstats
path: root/etc
diff options
context:
space:
mode:
authorScott Ullrich <sullrich@pfsense.org>2005-03-07 23:12:41 +0000
committerScott Ullrich <sullrich@pfsense.org>2005-03-07 23:12:41 +0000
commit9699028a571f1df9bd54799a8df0b97d03f6901b (patch)
tree44b7a6d30f21088895656ad7f0e9395c6f606f3a /etc
parent90b7aa76dae8c8436f968d2cb47f25a1c52ef989 (diff)
downloadpfsense-9699028a571f1df9bd54799a8df0b97d03f6901b.zip
pfsense-9699028a571f1df9bd54799a8df0b97d03f6901b.tar.gz
Add local user manager code imported from Pascal Suter's m0n0wall developers group message.
Diffstat (limited to 'etc')
-rw-r--r--etc/inc/captiveportal.inc256
1 files changed, 129 insertions, 127 deletions
diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc
index abb8a1b..719d0d8 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-2004 Manuel Kasper <mk@neon1.net>.
+
+ 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
@@ -26,35 +26,41 @@
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.
-*/
+ This version of captiveportal.inc has been modified by Rob Parker
+ <rob.parker@keycom.co.uk> to include changes for per-user bandwidth management
+ via returned RADIUS attributes. This page has been modified to delete any
+ 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_accounting.inc") ;
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']}/mini_httpd.cp.pid");
killbypid("{$g['varrun_path']}/mini_httpd.cps.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() ;
@@ -64,7 +70,7 @@ function captiveportal_configure() {
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']);
@@ -72,37 +78,16 @@ function captiveportal_configure() {
/* example/template page */
$htmltext = <<<EOD
<html>
-<title>pfSense's captive portal</title>
<head>
- <STYLE type="text/css">
-.listhdrr {
- background-color: #BBBBBB;
- padding-right: 16px;
- padding-left: 6px;
- font-weight: bold;
- border-right: 1px solid #999999;
- border-bottom: 1px solid #999999;
- font-size: 11px;
- padding-top: 5px;
- padding-bottom: 5px;
-}
-
- </STYLE>
+<title>m0n0wall captive portal</title>
</head>
-<body bgcolor="#990000">
-<center>
-<font color="white" face="arial" size="+1">Welcome to pfSense's captive portal!</font>
-<p>
-<form method="post" action="$PORTAL_ACTION$">
-<table border="0" cellpadding="6" cellspacing="0">
-<tr><td align="right" class="listhdrr"><font color="white">Username:</td><td class="listhdrr"><input name="auth_user" type="text"></td></tr>
-<tr><td align="right" class="listhdrr"><font color="white">Password:</td><td class="listhdrr"><input name="auth_pass" type="password"></td></tr>
-<input name="redirurl" type="hidden" value="$PORTAL_REDIRURL$">
-</table>
-<p>
-<center><input name="accept" type="submit" value="Continue">
+<body>
+<h2>m0n0wall captive portal</h2>
+<p>This is the default captive portal page. Please upload your own custom HTML file on the <em>Services: Captive portal</em> screen in the m0n0wall webGUI.</p>
+<form method="post" action="\$PORTAL_ACTION\$">
+ <input name="accept" type="submit" value="Continue">
+ <input name="redirurl" type="hidden" value="\$PORTAL_REDIRURL\$">
</form>
-</center>
</body>
</html>
@@ -112,9 +97,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']);
@@ -141,14 +126,14 @@ EOD;
$fd = @fopen("{$g['varetc_path']}/captiveportal-error.html", "w");
if ($fd) {
fwrite($fd, $errtext);
- fclose($fd);
+ fclose($fd);
}
/* load rules */
mwexec("/sbin/ipfw -f delete set 1");
mwexec("/sbin/ipfw -f delete set 2");
mwexec("/sbin/ipfw -f delete set 3");
-
+
/* XXX - seems like 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");
@@ -156,30 +141,30 @@ 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']);
-
+
/* start web server */
mwexec("/usr/local/sbin/mini_httpd -a -M 0 -u root -maxproc 16" .
" -p 8000 -i {$g['varrun_path']}/mini_httpd.cp.pid");
-
+
/* fire up another one for HTTPS if requested */
if (isset($config['captiveportal']['httpslogin']) &&
$config['captiveportal']['certificate'] && $config['captiveportal']['private-key']) {
-
+
$cert = base64_decode($config['captiveportal']['certificate']);
$key = base64_decode($config['captiveportal']['private-key']);
-
+
$fd = fopen("{$g['varetc_path']}/cert-portal.pem", "w");
if (!$fd) {
printf("Error: cannot open cert-portal.pem in system_webgui_start().\n");
@@ -190,23 +175,23 @@ EOD;
fwrite($fd, "\n");
fwrite($fd, $key);
fclose($fd);
-
+
mwexec("/usr/local/sbin/mini_httpd -S -a -M 0 -E {$g['varetc_path']}/cert-portal.pem" .
" -u root -maxproc 16 -p 8001" .
" -i {$g['varrun_path']}/mini_httpd.cps.pid");
}
-
+
/* start pruning process (interval = 60 seconds) */
mwexec("/usr/local/bin/minicron 60 {$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']) {
+ if($config['captiveportal']['radiusip'] && $config['captiveportal']['auth_method']=="radius") {
$radiusip = $config['captiveportal']['radiusip'] ;
if($config['captiveportal']['radiusport'])
@@ -234,7 +219,7 @@ EOD;
if ($g['booting'])
echo "done\n";
-
+
} else {
killbypid("{$g['varrun_path']}/mini_httpd.cp.pid");
killbypid("{$g['varrun_path']}/minicron.pid");
@@ -250,13 +235,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'];
@@ -265,7 +250,7 @@ function captiveportal_rules_generate() {
clients as skipto 50000 rules to make traffic shaping work */
$cprules = "";
-
+
/* captive portal on LAN interface? */
if ($cpifn == "lan") {
/* add anti-lockout rules */
@@ -313,7 +298,7 @@ add 1305 set 1 pass tcp from $cpip 8001 to any out
EOD;
}
-
+
$cprules .= <<<EOD
# ... 10000-19899: rules per authenticated client go here...
@@ -338,47 +323,47 @@ EOD;
/* remove clients that have been around for longer than the specified amount of time */
/* db file structure: timestamp,ipfw_rule_no,clientip,clientmac,username,sessionid */
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)
return;
-
+
captiveportal_lock();
-
+
/* read database */
$cpdb = captiveportal_read_db();
-
+
$radiusservers = captiveportal_get_radius_servers();
-
+
for ($i = 0; $i < count($cpdb); $i++) {
-
+
$timedout = false;
-
+
/* hard timeout? */
if ($timeout) {
if ((time() - $cpdb[$i][0]) >= $timeout)
- $timedout = true;
+ $timedout = true;
}
-
+
/* 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;
}
-
+
if ($timedout) {
/* this client needs to be deleted - remove ipfw rules */
if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
@@ -388,31 +373,40 @@ function captiveportal_prune_old() {
$cpdb[$i][0], // start time
$radiusservers[0]['ipaddr'],
$radiusservers[0]['acctport'],
- $radiusservers[0]['key']);
+ $radiusservers[0]['key'],
+ $cpdb[$i][2]); //clientip
+ syslog(LOG_INFO,"Authenticated user $cpdb[$i][4] timed out");
}
+ //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
mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
+ //we only need to remove our rules if peruserbw is turned on.
+ if(isset($config['captiveportal']['peruserbw'])) {
+ mwexec("/sbin/ipfw delete " . ($cpdb[$i][1]+40500));
+ mwexec("/sbin/ipfw delete " . ($cpdb[$i][1]+45500));
+ }
unset($cpdb[$i]);
}
}
-
+
/* write database */
captiveportal_write_db($cpdb);
-
+
captiveportal_unlock();
}
/* remove a single client by ipfw rule number */
function captiveportal_disconnect_client($id) {
-
+
global $g, $config;
-
+
captiveportal_lock();
-
+
/* read database */
$cpdb = captiveportal_read_db();
$radiusservers = captiveportal_get_radius_servers();
-
- /* find entry */
+
+ /* find entry */
for ($i = 0; $i < count($cpdb); $i++) {
if ($cpdb[$i][1] == $id) {
/* this client needs to be deleted - remove ipfw rules */
@@ -423,17 +417,24 @@ function captiveportal_disconnect_client($id) {
$cpdb[$i][0], // start time
$radiusservers[0]['ipaddr'],
$radiusservers[0]['acctport'],
- $radiusservers[0]['key']);
+ $radiusservers[0]['key'],
+ $cpdb[$i][2]); //clientip
+ syslog(LOG_INFO,"Authenticated user $cpdb[$i][4] disconnected");
}
mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
+ //we only need to remove our rules if peruserbw is turned on.
+ if(isset($config['captiveportal']['peruserbw'])) {
+ mwexec("/sbin/ipfw delete " . ($cpdb[$i][1]+40500));
+ mwexec("/sbin/ipfw delete " . ($cpdb[$i][1]+45500));
+ }
unset($cpdb[$i]);
break;
}
}
-
+
/* write database */
captiveportal_write_db($cpdb);
-
+
captiveportal_unlock();
}
@@ -443,9 +444,9 @@ function captiveportal_radius_stop_all() {
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
@@ -454,7 +455,8 @@ function captiveportal_radius_stop_all() {
$cpdb[$i][0], // start time
$radiusservers[0]['ipaddr'],
$radiusservers[0]['acctport'],
- $radiusservers[0]['key']);
+ $radiusservers[0]['key'],
+ $cpdb[$i][2]); //clientip
}
}
captiveportal_unlock() ;
@@ -462,34 +464,34 @@ function captiveportal_radius_stop_all() {
function captiveportal_passthrumac_configure() {
global $config, $g;
-
+
/* clear out passthru macs, if necessary */
if (file_exists("{$g['vardb_path']}/captiveportal_mac.db")) {
unlink("{$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");
- 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);
}
-
+
return 0;
}
function captiveportal_allowedip_configure() {
global $config, $g;
-
+
captiveportal_lock() ;
/* clear out existing allowed ips, if necessary */
@@ -501,7 +503,7 @@ function captiveportal_allowedip_configure() {
if($line) {
list($ip,$rule) = explode(",",$line);
mwexec("/sbin/ipfw delete $rule") ;
- }
+ }
}
}
fclose($fd) ;
@@ -513,16 +515,16 @@ 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");
@@ -538,8 +540,8 @@ function captiveportal_allowedip_configure() {
if ($ruleno > 19899)
$ruleno = 10000;
}
-
- fclose($fd);
+
+ fclose($fd);
/* write next rule number */
$fd = @fopen("{$g['vardb_path']}/captiveportal.nextrule", "w");
@@ -548,31 +550,31 @@ function captiveportal_allowedip_configure() {
fclose($fd);
}
}
-
+
captiveportal_unlock() ;
return 0;
}
/* get last activity timestamp given ipfw rule number */
function captiveportal_get_last_activity($ruleno) {
-
+
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 captive portal DB into array */
function captiveportal_read_db() {
-
+
global $g;
-
+
$cpdb = array();
$fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
if ($fd) {
@@ -580,7 +582,7 @@ function captiveportal_read_db() {
$line = trim(fgets($fd));
if ($line) {
$cpdb[] = explode(",", $line);
- }
+ }
}
fclose($fd);
}
@@ -589,9 +591,9 @@ 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) {
foreach ($cpdb as $cpent) {
@@ -603,9 +605,9 @@ function captiveportal_write_db($cpdb) {
/* 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) {
@@ -619,22 +621,22 @@ function captiveportal_get_radius_servers() {
}
}
fclose($fd);
-
+
return $radiusservers;
}
}
-
+
return false;
}
/* lock captive portal information, decide that the lock file is stale after
10 seconds */
function captiveportal_lock() {
-
+
global $g;
-
+
$lockfile = "{$g['varrun_path']}/captiveportal.lock";
-
+
$n = 0;
while ($n < 10) {
/* open the lock file in append mode to avoid race condition */
@@ -652,11 +654,11 @@ function captiveportal_lock() {
/* unlock configuration file */
function captiveportal_unlock() {
-
+
global $g;
-
+
$lockfile = "{$g['varrun_path']}/captiveportal.lock";
-
+
if (file_exists($lockfile))
unlink($lockfile);
}
OpenPOWER on IntegriCloud