diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc index c760d458d4..7ed2647b48 100644 --- a/etc/inc/captiveportal.inc +++ b/etc/inc/captiveportal.inc @@ -94,31 +94,28 @@ function get_default_captive_portal_html() {
- - - - - + + + + + EOD; if(isset($config['voucher'][$cpzone]['enable'])) { $htmltext .= << + + + + EOD; } $htmltext .= << - - + + +
Welcome to the {$g['product_name']} Captive Portal!
 
Username:
Password:
 
Welcome to the {$g['product_name']} Captive Portal!
 
Username:
Password:
 
- Enter Voucher Code: - - -
Enter Voucher Code:
-
-
@@ -148,17 +145,17 @@ EOD; } function captiveportal_load_modules() { - global $config; + global $config; mute_kernel_msgs(); - if (!is_module_loaded("ipfw.ko")) { - mwexec("/sbin/kldload ipfw"); - /* make sure ipfw is not on pfil hooks */ - mwexec("/sbin/sysctl net.inet.ip.pfil.inbound=\"pf\" net.inet6.ip6.pfil.inbound=\"pf\"" . - " net.inet.ip.pfil.outbound=\"pf\" net.inet6.ip6.pfil.outbound=\"pf\""); + if (!is_module_loaded("ipfw.ko")) { + mwexec("/sbin/kldload ipfw"); + /* make sure ipfw is not on pfil hooks */ + mwexec("/sbin/sysctl net.inet.ip.pfil.inbound=\"pf\" net.inet6.ip6.pfil.inbound=\"pf\"" . + " net.inet.ip.pfil.outbound=\"pf\" net.inet6.ip6.pfil.outbound=\"pf\""); /* Activate layer2 filtering */ mwexec("/sbin/sysctl net.link.ether.ipfw=1 net.inet.ip.fw.one_pass=1"); - } + } /* Always load dummynet now that even allowed ip and mac passthrough use it. */ if (!is_module_loaded("dummynet.ko")) { @@ -167,12 +164,12 @@ function captiveportal_load_modules() { } unmute_kernel_msgs(); - /* XXX: This are not used in pfSense, if needed can be tuned - if($config['system']['maximumstates'] <> "" && is_numeric($config['system']['maximumstates'])) { - mwexec("sysctl net.inet.ip.fw.dyn_max={$config['system']['maximumstates']}"); - } else { - mwexec("sysctl net.inet.ip.fw.dyn_max=10000"); - } + /* XXX: This are not used in pfSense, if needed can be tuned + if($config['system']['maximumstates'] <> "" && is_numeric($config['system']['maximumstates'])) { + mwexec("sysctl net.inet.ip.fw.dyn_max={$config['system']['maximumstates']}"); + } else { + mwexec("sysctl net.inet.ip.fw.dyn_max=10000"); + } */ } @@ -416,7 +413,7 @@ function captiveportal_init_webgui_zone($cpcfg) { $crt = base64_decode($cert['crt']); $key = base64_decode($cert['prv']); $ca = ca_chain($cert); - + /* generate lighttpd configuration */ $listenporthttps = $cpcfg['listenporthttps'] ? $cpcfg['listenporthttps'] : ($cpcfg['zoneid'] + 1); system_generate_lighty_config("{$g['varetc_path']}/lighty-{$cpzone}-CaptivePortal-SSL.conf", @@ -599,7 +596,7 @@ function captiveportal_prune_old() { $idletimeout = $cpcfg['idletimeout'] * 60; /* Is there any job to do? */ - if (!$timeout && !$idletimeout && !isset($cpcfg['reauthenticate']) && + if (!$timeout && !$idletimeout && !isset($cpcfg['reauthenticate']) && !isset($cpcfg['radiussession_timeout']) && !isset($vcpcfg['enable'])) return; @@ -1362,16 +1359,16 @@ function captiveportal_get_next_dn_ruleno($rulenos_start = 2000, $rulenos_range_ } function captiveportal_free_dn_ruleno($ruleno) { - global $config, $g; + global $config, $g; - $cpruleslck = lock("captiveportalrulesdn", LOCK_EX); - if (file_exists("{$g['vardb_path']}/captiveportaldn.rules")) { - $rules = unserialize(file_get_contents("{$g['vardb_path']}/captiveportaldn.rules")); - $rules[$ruleno] = false; - $rules[++$ruleno] = false; - file_put_contents("{$g['vardb_path']}/captiveportaldn.rules", serialize($rules)); - } - unlock($cpruleslck); + $cpruleslck = lock("captiveportalrulesdn", LOCK_EX); + if (file_exists("{$g['vardb_path']}/captiveportaldn.rules")) { + $rules = unserialize(file_get_contents("{$g['vardb_path']}/captiveportaldn.rules")); + $rules[$ruleno] = false; + $rules[++$ruleno] = false; + file_put_contents("{$g['vardb_path']}/captiveportaldn.rules", serialize($rules)); + } + unlock($cpruleslck); } function captiveportal_get_dn_passthru_ruleno($value) { @@ -1589,6 +1586,30 @@ function portal_ip_from_client_ip($cliip) { return false; } +function portal_hostname_from_client_ip($cliip) { + global $config, $cpzone; + + $cpcfg = $config['captiveportal'][$cpzone]; + + if (isset($cpcfg['httpslogin'])) { + $listenporthttps = $cpcfg['listenporthttps'] ? $cpcfg['listenporthttps'] : ($cpcfg['zoneid'] + 1); + $ourhostname = $cpcfg['httpsname']; + + if ($listenporthttps != 443) + $ourhostname .= ":" . $listenporthttps; + } else { + $listenporthttp = $cpcfg['listenporthttp'] ? $cpcfg['listenporthttp'] : $cpcfg['zoneid']; + $ifip = portal_ip_from_client_ip($cliip); + if (!$ifip) + $ourhostname = "{$config['system']['hostname']}.{$config['system']['domain']}"; + else + $ourhostname = (is_ipaddrv6($ifip)) ? "[{$ifip}]" : "{$ifip}"; + + if ($listenporthttp != 80) + $ourhostname .= ":" . $listenporthttp; + } +} + /* functions move from index.php */ function portal_reply_page($redirurl, $type = null, $message = null, $clientmac = null, $clientip = null, $username = null, $password = null) { @@ -1606,30 +1627,16 @@ function portal_reply_page($redirurl, $type = null, $message = null, $clientmac $cpcfg = $config['captiveportal'][$cpzone]; /* substitute the PORTAL_REDIRURL variable */ - if ($config['captiveportal'][$cpzone]['preauthurl']) { - $htmltext = str_replace("\$PORTAL_REDIRURL\$", "{$config['captiveportal'][$cpzone]['preauthurl']}", $htmltext); - $htmltext = str_replace("#PORTAL_REDIRURL#", "{$config['captiveportal'][$cpzone]['preauthurl']}", $htmltext); + if ($cpcfg['preauthurl']) { + $htmltext = str_replace("\$PORTAL_REDIRURL\$", "{$cpcfg['preauthurl']}", $htmltext); + $htmltext = str_replace("#PORTAL_REDIRURL#", "{$cpcfg['preauthurl']}", $htmltext); } /* substitute other variables */ - if (isset($config['captiveportal'][$cpzone]['httpslogin'])) { - $httpsport = $cpcfg['listenporthttps'] ? $cpcfg['listenporthttps'] : ($cpcfg['zoneid'] + 1); - $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal'][$cpzone]['httpsname']}:{$httpsport}/", $htmltext); - $htmltext = str_replace("#PORTAL_ACTION#", "https://{$config['captiveportal'][$cpzone]['httpsname']}:{$httpsport}/", $htmltext); - } else { - $httpport = $cpcfg['listenporthttp'] ? $cpcfg['listenporthttp'] : $cpcfg['zoneid']; - $ifip = portal_ip_from_client_ip($clientip); - if (!$ifip) { - $ourhostname = $config['system']['hostname'] . ":{$httpport}"; - } else { - if (is_ipaddrv6($ifip)) - $ourhostname = "[{$ifip}]:{$httpport}"; - else - $ourhostname = "{$ifip}:{$httpport}"; - } - $htmltext = str_replace("\$PORTAL_ACTION\$", "http://{$ourhostname}/", $htmltext); - $htmltext = str_replace("#PORTAL_ACTION#", "http://{$ourhostname}/", $htmltext); - } + $ourhostname = portal_hostname_from_client_ip($clientip); + $protocol = (isset($cpcfg['httpslogin'])) ? 'https://' : 'http://'; + $htmltext = str_replace("\$PORTAL_ACTION\$", "{$protocol}{$ourhostname}/", $htmltext); + $htmltext = str_replace("#PORTAL_ACTION#", "{$protocol}{$ourhostname}/", $htmltext); $htmltext = str_replace("\$PORTAL_ZONE\$", htmlspecialchars($cpzone), $htmltext); $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext); @@ -1648,40 +1655,41 @@ function portal_reply_page($redirurl, $type = null, $message = null, $clientmac $htmltext = str_replace("#USERNAME#", htmlspecialchars($username), $htmltext); $htmltext = str_replace("#PASSWORD#", htmlspecialchars($password), $htmltext); - echo $htmltext; + echo $htmltext; } function portal_mac_radius($clientmac,$clientip) { - global $config, $cpzone; + global $config, $cpzone; - $radmac_secret = $config['captiveportal'][$cpzone]['radmac_secret']; + $radmac_secret = $config['captiveportal'][$cpzone]['radmac_secret']; - /* 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; - if (!empty($auth_list['url_redirection'])) - portal_reply_page($auth_list['url_redirection'], "redir"); + /* 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; + if (!empty($auth_list['url_redirection'])) + portal_reply_page($auth_list['url_redirection'], "redir"); + + return FALSE; } function captiveportal_reapply_attributes($cpentry, $attributes) { global $config, $cpzone, $g; - + $dwfaultbw_up = isset($config['captiveportal'][$cpzone]['bwdefaultup']) ? $config['captiveportal'][$cpzone]['bwdefaultup'] : 0; $dwfaultbw_down = isset($config['captiveportal'][$cpzone]['bwdefaultdn']) ? $config['captiveportal'][$cpzone]['bwdefaultdn'] : 0; - $bw_up = isset($attributes['bw_up']) ? round(intval($attributes['bw_up'])/1000, 2) : $dwfaultbw_up; - $bw_down = isset($attributes['bw_down']) ? round(intval($attributes['bw_down'])/1000, 2) : $dwfaultbw_down; - $bw_up_pipeno = $cpentry[1]; - $bw_down_pipeno = $cpentry[1]+1; + $bw_up = isset($attributes['bw_up']) ? round(intval($attributes['bw_up'])/1000, 2) : $dwfaultbw_up; + $bw_down = isset($attributes['bw_down']) ? round(intval($attributes['bw_down'])/1000, 2) : $dwfaultbw_down; + $bw_up_pipeno = $cpentry[1]; + $bw_down_pipeno = $cpentry[1]+1; pfSense_pipe_action("pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100 buckets 16"); pfSense_pipe_action("pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100 buckets 16"); //captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "RADIUS_BANDWIDTH_REAPPLY", "{$bw_up}/{$bw_down}"); - unset($bw_up_pipeno, $bw_down_pipeno, $bw_up, $bw_down); + unset($bw_up_pipeno, $bw_down_pipeno, $bw_up, $bw_down); } function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $pipeno = null, $radiusctx = null) { @@ -1711,17 +1719,17 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut $macrules = ""; $ruleno = captiveportal_get_ipfw_passthru_ruleno($mac['mac']); $pipeno = captiveportal_get_dn_passthru_ruleno($mac['mac']); - if ($ruleno) { + if ($ruleno) { captiveportal_free_ipfw_ruleno($ruleno); - $macrules .= "delete {$ruleno}\n"; + $macrules .= "delete {$ruleno}\n"; ++$ruleno; - $macrules .= "delete {$ruleno}\n"; - } + $macrules .= "delete {$ruleno}\n"; + } if ($pipeno) { captiveportal_free_dn_ruleno($pipeno); - $macrules .= "pipe delete {$pipeno}\n"; + $macrules .= "pipe delete {$pipeno}\n"; ++$pipeno; - $macrules .= "pipe delete {$pipeno}\n"; + $macrules .= "pipe delete {$pipeno}\n"; } unset($config['captiveportal'][$cpzone]['passthrumac'][$idx]); $mac['mac'] = $clientmac; @@ -1735,7 +1743,7 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut break; } } - } else { + } else { portal_reply_page($redirurl, "error", "Username: {$username} is already authenticated using another MAC address.", $clientmac, $clientip, $username, $password); unlock($cpdblck); @@ -1764,7 +1772,7 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut $cpentry[10] = 'first'; /* on the same ip */ if ($cpentry[2] == $clientip) { - if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) + if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - REUSING OLD SESSION"); else captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - REUSING IP {$cpentry[2]} WITH DIFFERENT MAC ADDRESS {$cpentry[3]}"); @@ -1890,8 +1898,7 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut unlock($cpdblck); if (isset($config['captiveportal'][$cpzone]['radacct_enable']) && !empty($radiusservers[$radiusctx])) { - $acct_val = RADIUS_ACCOUNTING_START($pipeno, - $username, $sessionid, $radiusservers[$radiusctx], $clientip, $clientmac); + $acct_val = RADIUS_ACCOUNTING_START($pipeno, $username, $sessionid, $radiusservers[$radiusctx], $clientip, $clientmac); if ($acct_val == 1) captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED"); } @@ -1911,29 +1918,9 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut $my_redirurl = $redirurl; if(isset($config['captiveportal'][$cpzone]['logoutwin_enable']) && !$passthrumac) { - - if (isset($config['captiveportal'][$cpzone]['httpslogin'])) { - $httpsport = - $config['captiveportal'][$cpzone]['listenporthttps'] ? - $config['captiveportal'][$cpzone]['listenporthttps'] : - ($config['captiveportal'][$cpzone]['zoneid'] + 1); - $logouturl = "https://{$config['captiveportal'][$cpzone]['httpsname']}:{$httpsport}/"; - } else { - $ifip = portal_ip_from_client_ip($clientip); - $httpport = - $config['captiveportal'][$cpzone]['listenporthttp'] ? - $config['captiveportal'][$cpzone]['listenporthttp'] : - $config['captiveportal'][$cpzone]['zoneid']; - if (!$ifip) - $ourhostname = $config['system']['hostname'] . ":{$httpport}"; - else { - if (is_ipaddrv6($ifip)) - $ourhostname = "[{$ifip}]:{$httpport}"; - else - $ourhostname = "{$ifip}:{$httpport}"; - } - $logouturl = "http://{$ourhostname}/"; - } + $ourhostname = portal_hostname_from_client_ip($clientip); + $protocol = (isset($config['captiveportal'][$cpzone]['httpslogin'])) ? 'https://' : 'http://'; + $logouturl = "{$protocol}{$ourhostname}/"; if (isset($attributes['reply_message'])) $message = $attributes['reply_message']; diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc index 270428e744..797df0c748 100644 --- a/etc/inc/interfaces.inc +++ b/etc/inc/interfaces.inc @@ -1061,6 +1061,60 @@ function interface_vip_bring_down($vip) { } } +function interface_cleanup($interface = "wan") { + global $config, $g; + + if (!isset($config['interfaces'][$interface])) + return; + + $ifcfg = $config['interfaces'][$interface]; + + $ppp_types = array("ppp", "pppoe", "pptp", "l2tp"); + + $realifs = array(get_real_interface($interface)); + + if (in_array($ifcfg['ipaddr'], $ppp_types)) { + if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) { + foreach ($config['ppps']['ppp'] as $pppid => $ppp) { + if (get_real_interface($interface) == $ppp['if']) { + $realifs = array(); + $ports = explode(',',$ppp['ports']); + foreach($ports as $port) { + $realifs[] = get_real_interface($port); + } + } + } + } + } + + foreach ($ppp_types as $type) { + if (($ifcfg['ipaddr'] != $type) && file_exists("{$g['varrun_path']}/{$type}_{$interface}.pid")) { + killbypid("{$g['varrun_path']}/{$type}_{$interface}.pid"); + sleep(2); + } + } + + if (!in_array($ifcfg['ipaddr'], $ppp_types)) + unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf"); + + if ($ifcfg['ipaddr'] != "dhcp") { + foreach($realifs as $realif) { + $pid = find_dhclient_process($realif); + if($pid) + mwexec("/bin/kill {$pid}"); + sleep(1); + } + unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf"); + } + + if (!is_ipaddrv4($ifcfg['ipaddr'])) { + foreach($realifs as $realif) { + mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true); + mwexec("/usr/sbin/arp -d -i {$realif} -a"); + } + } +} + function interface_bring_down($interface = "wan", $destroy = false) { global $config, $g; @@ -1072,6 +1126,8 @@ function interface_bring_down($interface = "wan", $destroy = false) { $realif = get_real_interface($interface); + interface_cleanup($interface); + switch ($ifcfg['ipaddr']) { case "ppp": case "pppoe": diff --git a/usr/local/captiveportal/index.php b/usr/local/captiveportal/index.php index 681e9a6764..28931a4032 100755 --- a/usr/local/captiveportal/index.php +++ b/usr/local/captiveportal/index.php @@ -61,35 +61,17 @@ if (!$clientip) { return; } -$listenporthttps = $cpcfg['listenporthttps'] ? $cpcfg['listenporthttps'] : ($cpcfg['zoneid'] + 1); -$listenporthttp = $cpcfg['listenporthttp'] ? $cpcfg['listenporthttp'] : $cpcfg['zoneid']; - -if (isset($cpcfg['httpslogin'])) - $ourhostname = $cpcfg['httpsname'] . ":" . $listenporthttps; -else { - $ifip = portal_ip_from_client_ip($clientip); - if (!$ifip) { - $ourhostname = "{$config['system']['hostname']}.{$config['system']['domain']}:{$listenporthttp}"; - } else { - if (is_ipaddrv6($ifip)) - $ourhostname = "[{$ifip}]:{$listenporthttp}"; - else - $ourhostname = "{$ifip}:{$listenporthttp}"; - } -} - +$ourhostname = portal_hostname_from_client_ip($clientip); 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($cpcfg['httpslogin'])) - header("Location: https://{$ourhostname}/index.php?zone={$cpzone}&redirurl=" . urlencode("http://{$orig_host}/{$orig_request}")); - else - header("Location: http://{$ourhostname}/index.php?zone={$cpzone}&redirurl=" . urlencode("http://{$orig_host}/{$orig_request}")); + $protocol = (isset($cpcfg['httpslogin'])) ? 'https://' : 'http://'; + header("Location: {$protocol}{$ourhostname}/index.php?zone={$cpzone}&redirurl=" . urlencode("http://{$orig_host}/{$orig_request}")); ob_flush(); return; } + if (!empty($cpcfg['redirurl'])) $redirurl = $cpcfg['redirurl']; else if (preg_match("/redirurl=(.*)/", $orig_request, $matches)) @@ -238,4 +220,4 @@ EOD; ob_flush(); -?> \ No newline at end of file +?>