diff options
author | Ermal <eri@pfsense.org> | 2010-05-05 15:28:00 +0000 |
---|---|---|
committer | Ermal <eri@pfsense.org> | 2010-05-05 15:28:00 +0000 |
commit | 9faa6c3c3fa6d3079581a5904855da60f32e961a (patch) | |
tree | 2d58f8eb4e8a91ce14f0766179875ba4ec247f87 /usr/local | |
parent | f3c5638e508d18d65d796fdde953d31c227e41b9 (diff) | |
download | pfsense-9faa6c3c3fa6d3079581a5904855da60f32e961a.zip pfsense-9faa6c3c3fa6d3079581a5904855da60f32e961a.tar.gz |
Improve/correct the passthrumac rules when this option is enabled.
Diffstat (limited to 'usr/local')
-rwxr-xr-x | usr/local/captiveportal/index.php | 358 |
1 files changed, 176 insertions, 182 deletions
diff --git a/usr/local/captiveportal/index.php b/usr/local/captiveportal/index.php index 4f68026..c100ecf 100755 --- a/usr/local/captiveportal/index.php +++ b/usr/local/captiveportal/index.php @@ -234,193 +234,188 @@ function portal_mac_radius($clientmac,$clientip) { function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $ruleno = null) { - global $redirurl, $g, $config, $url_redirection, $type; - - /* See if a ruleno is passed, if not start locking the sessions because this means there isn't one atm */ - $captiveshouldunlock = false; - if ($ruleno == null) { - $cplock = lock('captiveportal'); - $captiveshouldunlock = true; - $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"); - log_error("WARNING! Captive portal has reached maximum login capacity"); - if ($captiveshouldunlock == true) - unlock($cplock); - 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(); - - if ($attributes['voucher']) - $remaining_time = $attributes['session_timeout']; - - /* 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 (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpdb[$i][4] == $username)) { - // user logged in with an active voucher. Check for how long and calculate - // how much time we can give him (voucher credit - used time) - $remaining_time = $cpdb[$i][0] + $cpdb[$i][7] - time(); - if ($remaining_time < 0) // just in case. - $remaining_time = 0; - - /* 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; - } - elseif ((isset($config['captiveportal']['noconcurrentlogins'])) && ($username != 'unauthenticated')) { - /* on the same username */ - if (strcasecmp($cpdb[$i][4], $username) == 0) { - /* 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 ($attributes['voucher'] && $remaining_time <= 0) { - unlock($cplock); - return 0; // voucher already used and no time left - } - - $writecfg = false; - 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 rules since traffic will pass due to the following kernel option - * net.inet.ip.fw.one_pass: 1 - */ - $peruserbw = isset($config['captiveportal']['peruserbw']); - $passthrumacadd = isset($config['captiveportal']['passthrumacadd']); - - $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 ($passthrumacadd) { - $mac = array(); - $mac['mac'] = $clientmac; - $mac['descr'] = "Auto added pass-through MAC for user {$username}"; - if (!empty($bw_up)) - $mac['bw_up'] = $bw_up; - if (!empty($bw_down)) - $mac['bw_down'] = $bw_down; - if (!is_array($config['captiveportal']['passthrumac'])) - $config['captiveportal']['passthrumac'] = array(); - $config['captiveportal']['passthrumac'][] = $mac; - $writecfg = true; + global $redirurl, $g, $config, $url_redirection, $type; + + /* See if a ruleno is passed, if not start locking the sessions because this means there isn't one atm */ + $captiveshouldunlock = false; + if ($ruleno == null) { + $cplock = lock('captiveportal'); + $captiveshouldunlock = true; + $ruleno = captiveportal_get_next_ipfw_ruleno(); } - - if ($peruserbw && !empty($bw_up) && is_numeric($bw_up)) { - $bw_up_pipeno = $ruleno + 20000; - //$bw_up /= 1000; // Scale to Kbit/s - mwexec("/sbin/ipfw pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100"); - - if (!isset($config['captiveportal']['nomacfilter']) || $passthrumacadd) - mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac} {$bw_up_pipeno}"); - else - mwexec("/sbin/ipfw table 1 add {$clientip} {$bw_up_pipeno}"); - } else { - if (!isset($config['captiveportal']['nomacfilter']) || $passthrumacadd) - mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac}"); - else - mwexec("/sbin/ipfw table 1 add {$clientip}"); - } - if ($peruserbw && !empty($bw_down) && is_numeric($bw_down)) { - $bw_down_pipeno = $ruleno + 20001; - //$bw_down /= 1000; // Scale to Kbit/s - mwexec("/sbin/ipfw pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100"); - - if (!isset($config['captiveportal']['nomacfilter']) || $passthrumacadd) - mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac} {$bw_down_pipeno}"); - else - mwexec("/sbin/ipfw table 2 add {$clientip} {$bw_down_pipeno}"); - } else { - if (!isset($config['captiveportal']['nomacfilter']) || $passthrumacadd) - mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac}"); - else - mwexec("/sbin/ipfw table 2 add {$clientip}"); - } - if ($attributes['voucher']) - $attributes['session_timeout'] = $remaining_time; - - /* 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']) && !empty($radiusservers)) { - $acct_val = RADIUS_ACCOUNTING_START($ruleno, - $username, - $sessionid, - $radiusservers, - $clientip, - $clientmac); - - if ($acct_val == 1) - captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED"); - } + /* if the pool is empty, return appropriate message and exit */ + if (is_null($ruleno)) { + portal_reply_page($redirurl, "error", "System reached maximum login capacity"); + log_error("WARNING! Captive portal has reached maximum login capacity"); + if ($captiveshouldunlock == true) + unlock($cplock); + exit; + } - /* rewrite information to database */ - captiveportal_write_db($cpdb); - } + // Ensure we create an array if we are missing attributes + if (!is_array($attributes)) + $attributes = array(); - if ($captiveshouldunlock == true) - unlock($cplock); + /* read in client database */ + $cpdb = captiveportal_read_db(); - if ($writecfg == true) { - write_config(); - captiveportal_passthrumac_configure(true); - } + $radiusservers = captiveportal_get_radius_servers(); - /* 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 ($attributes['voucher']) + $remaining_time = $attributes['session_timeout']; + + /* 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 (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpdb[$i][4] == $username)) { + // user logged in with an active voucher. Check for how long and calculate + // how much time we can give him (voucher credit - used time) + $remaining_time = $cpdb[$i][0] + $cpdb[$i][7] - time(); + if ($remaining_time < 0) // just in case. + $remaining_time = 0; + + /* 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; + } + elseif ((isset($config['captiveportal']['noconcurrentlogins'])) && ($username != 'unauthenticated')) { + /* on the same username */ + if (strcasecmp($cpdb[$i][4], $username) == 0) { + /* 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($config['captiveportal']['logoutwin_enable']) && !isset($config['captiveportal']['passthrumacadd'])) { + if ($attributes['voucher'] && $remaining_time <= 0) { + unlock($cplock); + return 0; // voucher already used and no time left + } - if (isset($config['captiveportal']['httpslogin'])) - $logouturl = "https://{$config['captiveportal']['httpsname']}:8001/"; - else { - $ifip = portal_ip_from_client_ip($clientip); - if (!$ifip) - $ourhostname = $config['system']['hostname'] . ":8000"; - else - $ourhostname = "{$ifip}:8000"; - $logouturl = "http://{$ourhostname}/"; + $writecfg = false; + 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 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 ($passthrumac) { + $mac = array(); + $mac['mac'] = $clientmac; + $mac['descr'] = "Auto added pass-through MAC for user {$username}"; + if (!empty($bw_up)) + $mac['bw_up'] = $bw_up; + if (!empty($bw_down)) + $mac['bw_down'] = $bw_down; + if (!is_array($config['captiveportal']['passthrumac'])) + $config['captiveportal']['passthrumac'] = array(); + $config['captiveportal']['passthrumac'][] = $mac; + $macrules = captiveportal_passthrumac_configure_entry($mac); + file_put_contents("{$g['tmp_path']}/macentry.rules.tmp", $macrules); + mwexec("/sbin/ipfw -q {$g['tmp_path']}/macentry.rules.tmp"); + $writecfg = true; + } else { + + if ($peruserbw && !empty($bw_up) && is_numeric($bw_up)) { + $bw_up_pipeno = $ruleno + 20000; + //$bw_up /= 1000; // Scale to Kbit/s + mwexec("/sbin/ipfw pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100"); + + if (!isset($config['captiveportal']['nomacfilter'])) + mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac} {$bw_up_pipeno}"); + else + mwexec("/sbin/ipfw table 1 add {$clientip} {$bw_up_pipeno}"); + } else { + if (!isset($config['captiveportal']['nomacfilter'])) + mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac}"); + else + mwexec("/sbin/ipfw table 1 add {$clientip}"); + } + if ($peruserbw && !empty($bw_down) && is_numeric($bw_down)) { + $bw_down_pipeno = $ruleno + 20001; + //$bw_down /= 1000; // Scale to Kbit/s + mwexec("/sbin/ipfw pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100"); + + if (!isset($config['captiveportal']['nomacfilter'])) + mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac} {$bw_down_pipeno}"); + else + mwexec("/sbin/ipfw table 2 add {$clientip} {$bw_down_pipeno}"); + } else { + if (!isset($config['captiveportal']['nomacfilter'])) + mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac}"); + else + mwexec("/sbin/ipfw table 2 add {$clientip}"); + } + + if ($attributes['voucher']) + $attributes['session_timeout'] = $remaining_time; + + /* 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']) && !empty($radiusservers)) { + $acct_val = RADIUS_ACCOUNTING_START($ruleno, + $username, $sessionid, $radiusservers, $clientip, $clientmac); + + if ($acct_val == 1) + captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED"); + } + + /* rewrite information to database */ + captiveportal_write_db($cpdb); + } } - echo <<<EOD + if ($captiveshouldunlock == true) + unlock($cplock); + + if ($writecfg == true) + write_config(); + + /* 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']) && !isset($config['captiveportal']['passthrumacadd'])) { + + if (isset($config['captiveportal']['httpslogin'])) + $logouturl = "https://{$config['captiveportal']['httpsname']}:8001/"; + 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> <HEAD><TITLE>Redirecting...</TITLE></HEAD> <BODY> @@ -452,12 +447,11 @@ document.location.href="{$my_redirurl}"; </HTML> EOD; - } else { - header("Location: " . $my_redirurl); - return $sessionid; - } + } else { + header("Location: " . $my_redirurl); + } - return $sessionid; + return $sessionid; } |