summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/inc/captiveportal.inc132
-rw-r--r--etc/inc/interfaces.inc4
-rw-r--r--etc/inc/util.inc3
-rwxr-xr-xusr/local/captiveportal/index.php31
-rwxr-xr-xusr/local/www/services_captiveportal.php10
5 files changed, 121 insertions, 59 deletions
diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc
index 0093495..ef793e7 100644
--- a/etc/inc/captiveportal.inc
+++ b/etc/inc/captiveportal.inc
@@ -47,10 +47,32 @@ function captiveportal_configure() {
global $config, $g;
$captiveportallck = lock('captiveportal');
+
+ $cpactive = false;
+ if (isset($config['captiveportal']['enable'])) {
+ $cpips = array();
+ $ifaces = get_configured_interface_list();
+ $cpinterfaces = explode(",", $config['captiveportal']['interface']);
+ $firsttime = 0;
+ foreach ($cpinterfaces as $cpifgrp) {
+ if (!isset($ifaces[$cpifgrp]))
+ continue;
+ if ($firsttime > 0)
+ $cpinterface .= " or ";
+ $firsttime = 1;
+ $tmpif = get_real_interface($cpifgrp);
+ if (!empty($tmpif)) {
+ $cpinterface .= "via {$tmpif}";
+ $cpips[] = get_interface_ip($cpifgrp);
+ }
+ }
+ if (count($cpips) > 0) {
+ $cpactive = true;
+ $cpinterface = "{ {$cpinterface} } ";
+ }
+ }
- if (isset($config['captiveportal']['enable']) &&
- (($config['captiveportal']['interface'] == "lan") ||
- isset($config['interfaces'][$config['captiveportal']['interface']]['enable']))) {
+ if ($cpactive == true) {
if ($g['booting'])
echo "Starting captive portal... ";
@@ -69,7 +91,7 @@ function captiveportal_configure() {
mwexec("/sbin/kldload dummynet");
/* generate ipfw rules */
- $cprules = captiveportal_rules_generate();
+ $cprules = captiveportal_rules_generate($cpinterface, $cpips);
/* stop accounting on all clients */
captiveportal_radius_stop_all(true);
@@ -276,17 +298,15 @@ EOD;
mwexec("/sbin/kldunload ipfw.ko");
}
- unlock($captiveportallck);
+ unlock($captiveportallck);
return 0;
}
-function captiveportal_rules_generate() {
+function captiveportal_rules_generate($cpif, &$cpiparray) {
global $config, $g;
$cpifn = $config['captiveportal']['interface'];
- $cpif = get_real_interface($cpifn);
- $cpip = get_interface_ip($cpifn);
$lanip = get_interface_ip("lan");
/* note: the captive portal daemon inserts all pass rules for authenticated
@@ -301,27 +321,27 @@ function captiveportal_rules_generate() {
/* if list */
$iflist = get_configured_interface_list();
foreach ($iflist as $ifent => $ifname) {
- if($cpifn == $ifname)
+ if(stristr($cpifn, $ifname))
continue;
$int = get_real_interface($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") {
+ if (stristr($cpifn, "lan")) {
/* add anti-lockout rules */
$cprules .= <<<EOD
-add 500 set 1 pass all from $cpip to any out via $cpif
-add 501 set 1 pass all from any to $cpip in via $cpif
+add 500 set 1 pass all from $lanip to any out $cpif
+add 501 set 1 pass all from any to $lanip in $cpif
EOD;
}
$cprules .= <<<EOD
# skip to traffic shaper if not on captive portal interface
-add 1000 set 1 skipto 50000 all from any to any not layer2 not via $cpif
+add 1000 set 1 skipto 50000 all from any to any not layer2 not $cpif
# pass all layer2 traffic on other interfaces
-add 1001 set 1 pass layer2 not via $cpif
+add 1001 set 1 pass layer2 not $cpif
# layer 2: pass ARP
add 1100 set 1 pass layer2 mac-type arp
@@ -341,39 +361,50 @@ add 1101 set 1 deny layer2 not mac-type ip
# layer 2: check if MAC addresses of authenticated clients are correct
add 1102 set 1 skipto 20000 layer2
-# allow access to our DHCP server (which needs to be able to ping clients as well)
-add 1200 set 1 pass udp from any 68 to 255.255.255.255 67 in
-add 1201 set 1 pass udp from any 68 to $cpip 67 in
-add 1202 set 1 pass udp from $cpip 67 to any 68 out
-add 1203 set 1 pass icmp from $cpip to any out icmptype 8
-add 1204 set 1 pass icmp from any to $cpip in icmptype 0
-
-# allow access to our DNS forwarder
-add 1300 set 1 pass udp from any to $cpip 53 in
-add 1301 set 1 pass udp from $cpip 53 to any out
-
-# allow access to our DNS forwarder if it incorrectly resolves the hostname to $lanip
-add 1300 set 1 pass udp from any to $lanip 53 in
-add 1301 set 1 pass udp from $lanip 53 to any out
-
-# allow access to our web server
-add 1302 set 1 pass tcp from any to $cpip 8000 in
-add 1303 set 1 pass tcp from $cpip 8000 to any out
-
-# allow access to lan web server incase the dns name resolves incorrectly to $lanip
-add 1302 set 1 pass tcp from any to $lanip 8000 in
-add 1303 set 1 pass tcp from $lanip 8000 to any out
-
EOD;
- if (isset($config['captiveportal']['httpslogin'])) {
- $cprules .= <<<EOD
-add 1304 set 1 pass tcp from any to $cpip 8001 in
-add 1305 set 1 pass tcp from $cpip 8001 to any out
-
-EOD;
+ $rulenum = 1200;
+ foreach ($cpiparray as $cpip) {
+ //# allow access to our DHCP server (which needs to be able to ping clients as well)
+ $cprules .= "add {$rulenum} set 1 pass udp from any 68 to 255.255.255.255 67 in \n";
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass udp from any 68 to {$cpip} 67 in \n";
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass udp from {$cpip} 67 to any 68 out \n";
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass icmp from {$cpip} to any out icmptype 8\n";
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass icmp from any to {$cpip} in icmptype 0 \n";
+ $rulenum++;
+ //# allow access to our DNS forwarder
+ $cprules .= "add {$rulenum} set 1 pass udp from any to {$cpip} 53 in \n";
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass udp from {$cpip} 53 to any out \n";
+ $rulenum++;
+ # allow access to our web server
+ $cprules .= "add {$rulenum} set 1 pass tcp from any to {$cpip} 8000 in \n";
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass tcp from {$cpip} 8000 to any out \n";
+
+ if (isset($config['captiveportal']['httpslogin'])) {
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass tcp from any to {$cpip} 8001 in \n";
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass tcp from {$cpip} 8001 to any out \n";
+ }
}
+ $rulenum++;
+ //# allow access to our DNS forwarder if it incorrectly resolves the hostname to $lanip
+ $cprules .= "add {$rulenum} set 1 pass udp from any to {$lanip} 53 in \n";
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass udp from {$lanip} 53 to any out \n";
+ //# allow access to lan web server incase the dns name resolves incorrectly to $lanip
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass tcp from any to {$lanip} 8000 in \n";
+ $rulenum++;
+ $cprules .= "add {$rulenum} set 1 pass tcp from {$lanip} 8000 to any out \n";
+
$cprules .= <<<EOD
# ... 10000-19899: rules per authenticated client go here...
@@ -956,7 +987,6 @@ function captiveportal_write_elements() {
* within the range specified based on the actual installed rules
*
*/
-
function captiveportal_get_next_ipfw_ruleno($rulenos_start = 10000, $rulenos_range_max = 9899) {
$fwrules = "";
@@ -1065,4 +1095,18 @@ function portal_mac_fixed($clientmac) {
return FALSE ;
}
+function portal_ip_from_client_ip($cliip) {
+ global $config;
+
+ $interfaces = explode(",", $config['captiveportal']['interface']);
+ foreach ($interfaces as $cpif) {
+ $ip = get_interface_ip($cpif);
+ $sn = get_interface_subnet($cpif);
+ if (ip_in_subnet($cliip, "{$ip}/{$sn}"))
+ return $ip;
+ }
+
+ return false;
+}
+
?>
diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc
index 3ec42a3..8e65a1d 100644
--- a/etc/inc/interfaces.inc
+++ b/etc/inc/interfaces.inc
@@ -2184,9 +2184,9 @@ function get_real_interface($interface = "wan") {
function guess_interface_from_ip($ipaddress) {
$ret = `/usr/bin/netstat -rn | /usr/bin/awk '/^{$ipaddress}/ {print \$6}'`;
- if(empty($ret)) {
+ if (empty($ret))
return false;
- }
+
return $ret;
}
diff --git a/etc/inc/util.inc b/etc/inc/util.inc
index b318f92..c419369 100644
--- a/etc/inc/util.inc
+++ b/etc/inc/util.inc
@@ -732,7 +732,6 @@ function verify_digital_signature($fname) {
global $g;
return mwexec("/usr/local/sbin/gzsig verify {$g['etc_path']}/pubkey.pem < " . escapeshellarg($fname));
-
}
/* obtain MAC address given an IP address by looking at the ARP table */
@@ -967,4 +966,4 @@ function is_interface_mismatch() {
return $do_assign;
}
-?> \ No newline at end of file
+?>
diff --git a/usr/local/captiveportal/index.php b/usr/local/captiveportal/index.php
index eab9763..3771bf9 100755
--- a/usr/local/captiveportal/index.php
+++ b/usr/local/captiveportal/index.php
@@ -49,8 +49,13 @@ if (!$clientip) {
if (isset($config['captiveportal']['httpslogin']))
$ourhostname = $config['captiveportal']['httpsname'] . ":8001";
-else
- $ourhostname = get_interface_ip($config['captiveportal']['interface']) . ":8000";
+else {
+ $ifip = portal_ip_from_client_ip($clientip);
+ if (!$ifip)
+ $ourhostname = $config['system']['hostname'] . ":8000";
+ else
+ $ourhostname = "{$ifip}:8000";
+}
if ($orig_host != $ourhostname) {
/* the client thinks it's connected to the desired web server, but instead
@@ -84,7 +89,7 @@ if (!$clientmac && $macfilter) {
/* 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']))
+ if (isset($config['captiveportal']['radmac_enable']))
$radmac_enable = TRUE;
}
@@ -167,8 +172,14 @@ function portal_reply_page($redirurl, $type = null, $message = null, $clientmac
/* 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://" . get_interface_ip($config['captiveportal']['interface']) . ":8000/", $htmltext);
+ else {
+ $ifip = portal_ip_from_client_ip($clientip);
+ if (!$ifip)
+ $ourhostname = $config['system']['hostname'] . ":8000";
+ else
+ $ourhostname = "{$ifip}:8000";
+ $htmltext = str_replace("\$PORTAL_ACTION\$", "http://{$ourhostname}/", $htmltext);
+ }
$htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext);
$htmltext = str_replace("\$PORTAL_MESSAGE\$", htmlspecialchars($message), $htmltext);
@@ -320,8 +331,14 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut
if (isset($config['captiveportal']['httpslogin']))
$logouturl = "https://{$config['captiveportal']['httpsname']}:8001/";
- else
- $logouturl = "http://" . get_interface_ip($config['captiveportal']['interface']) . ":8000/";
+ else {
+ $ifip = portal_ip_from_client_ip($clientip);
+ if (!$ifip)
+ $ourhostname = $config['system']['hostname'] . ":8000";
+ else
+ $ourhostname = "{$ifip}:8000";
+ $logouturl = "http://{$ourhostname}/";
+ }
echo <<<EOD
<HTML>
diff --git a/usr/local/www/services_captiveportal.php b/usr/local/www/services_captiveportal.php
index 7d5a73d..bc07fb2 100755
--- a/usr/local/www/services_captiveportal.php
+++ b/usr/local/www/services_captiveportal.php
@@ -149,7 +149,7 @@ if ($_POST) {
}
if (!$input_errors) {
- $config['captiveportal']['interface'] = $_POST['cinterface'];
+ $config['captiveportal']['interface'] = implode(",", $_POST['cinterface']);
$config['captiveportal']['maxproc'] = $_POST['maxproc'];
$config['captiveportal']['maxprocperip'] = $_POST['maxprocperip'] ? $_POST['maxprocperip'] : false;
$config['captiveportal']['timeout'] = $_POST['timeout'];
@@ -194,6 +194,8 @@ if ($_POST) {
$retval = captiveportal_configure();
$savemsg = get_std_save_message($retval);
+
+ $pconfig['cinterface'] = implode(",", $_POST['cinterface']);
}
}
include("head.inc");
@@ -276,16 +278,16 @@ function enable_change(enable_change) {
<tr>
<td width="22%" valign="top" class="vncellreq">Interface</td>
<td width="78%" class="vtable">
- <select name="cinterface" class="formselect" id="cinterface">
+ <select name="cinterface[]" multiple="true" size="3" class="formselect" id="cinterface">
<?php
$interfaces = get_configured_interface_with_descr();
foreach ($interfaces as $iface => $ifacename): ?>
- <option value="<?=$iface;?>" <?php if ($iface == $pconfig['cinterface']) echo "selected"; ?>>
+ <option value="<?=$iface;?>" <?php if (stristr($pconfig['cinterface'], $iface)) echo "selected"; ?>>
<?=htmlspecialchars($ifacename);?>
</option>
<?php endforeach; ?>
</select> <br>
- <span class="vexpl">Choose which interface to run the captive portal on.</span></td>
+ <span class="vexpl">Choose which interface(s) to run the captive portal on.</span></td>
</tr>
<tr>
<td valign="top" class="vncell">Maximum concurrent connections</td>
OpenPOWER on IntegriCloud