diff options
author | lgcosta <lgcosta@pfsense.org> | 2011-02-22 16:27:15 -0300 |
---|---|---|
committer | lgcosta <lgcosta@pfsense.org> | 2011-02-22 16:27:15 -0300 |
commit | ac631bba8ed37b9a4adc9a5ae714c9965cc7a37c (patch) | |
tree | 71acc4fb62b8d4e2bac1de2cabebaf0abbf992c3 | |
parent | f1beeba5d18d28af460fb56458539799511223b1 (diff) | |
download | pfsense-ac631bba8ed37b9a4adc9a5ae714c9965cc7a37c.zip pfsense-ac631bba8ed37b9a4adc9a5ae714c9965cc7a37c.tar.gz |
Move all functions from index.php for captiveportal.inc
-rw-r--r-- | etc/inc/captiveportal.inc | 413 | ||||
-rwxr-xr-x | usr/local/captiveportal/index.php | 406 |
2 files changed, 412 insertions, 407 deletions
diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc index e2275ac..013a28a 100644 --- a/etc/inc/captiveportal.inc +++ b/etc/inc/captiveportal.inc @@ -1522,4 +1522,415 @@ function portal_ip_from_client_ip($cliip) { return false; } -?>
\ No newline at end of file +/* functions move from index.php */ + +function portal_reply_page($redirurl, $type = null, $message = null, $clientmac = null, $clientip = null, $username = null, $password = null) { + global $g, $config; + + /* Get captive portal layout */ + if ($type == "redir") { + header("Location: {$redirurl}"); + return; + } else if ($type == "login") + $htmltext = get_include_contents("{$g['varetc_path']}/captiveportal.html"); + else + $htmltext = get_include_contents("{$g['varetc_path']}/captiveportal-error.html"); + + /* substitute the PORTAL_REDIRURL variable */ + if ($config['captiveportal']['preauthurl']) { + $htmltext = str_replace("\$PORTAL_REDIRURL\$", "{$config['captiveportal']['preauthurl']}", $htmltext); + $htmltext = str_replace("#PORTAL_REDIRURL#", "{$config['captiveportal']['preauthurl']}", $htmltext); + } + + /* substitute other variables */ + if (isset($config['captiveportal']['httpslogin'])) { + $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext); + $htmltext = str_replace("#PORTAL_ACTION#", "https://{$config['captiveportal']['httpsname']}:8001/", $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_ACTION#", "http://{$ourhostname}/", $htmltext); + } + + $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext); + $htmltext = str_replace("\$PORTAL_MESSAGE\$", htmlspecialchars($message), $htmltext); + $htmltext = str_replace("\$CLIENT_MAC\$", htmlspecialchars($clientmac), $htmltext); + $htmltext = str_replace("\$CLIENT_IP\$", htmlspecialchars($clientip), $htmltext); + + // Special handling case for captive portal master page so that it can be ran + // through the PHP interpreter using the include method above. We convert the + // $VARIABLE$ case to #VARIABLE# in /etc/inc/captiveportal.inc before writing out. + $htmltext = str_replace("#PORTAL_REDIRURL#", htmlspecialchars($redirurl), $htmltext); + $htmltext = str_replace("#PORTAL_MESSAGE#", htmlspecialchars($message), $htmltext); + $htmltext = str_replace("#CLIENT_MAC#", htmlspecialchars($clientmac), $htmltext); + $htmltext = str_replace("#CLIENT_IP#", htmlspecialchars($clientip), $htmltext); + $htmltext = str_replace("#USERNAME#", htmlspecialchars($username), $htmltext); + $htmltext = str_replace("#PASSWORD#", htmlspecialchars($password), $htmltext); + + echo $htmltext; +} + +function portal_mac_radius($clientmac,$clientip) { + global $config ; + + $radmac_secret = $config['captiveportal']['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"); + + return FALSE; +} + +function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $ruleno = null) { + + global $redirurl, $g, $config, $type, $passthrumac, $_POST; + + /* See if a ruleno is passed, if not start sessions because this means there isn't one atm */ + if ($ruleno == null) + $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"); + 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']; + + $writecfg = false; + /* Find an existing session */ + if ((isset($config['captiveportal']['noconcurrentlogins'])) && $passthrumac) { + if (isset($config['captiveportal']['passthrumacadd'])) { + $mac = captiveportal_passthrumac_findbyname($username); + if (!empty($mac)) { + if ($_POST['replacemacpassthru']) { + foreach ($config['captiveportal']['passthrumac'] as $idx => $macent) { + if ($macent['mac'] == $mac['mac']) { + $macrules = ""; + $ruleno = captiveportal_get_ipfw_passthru_ruleno($mac['mac']); + if ($ruleno) { + captiveportal_free_ipfw_ruleno($ruleno, true); + $macrules .= "delete {$ruleno}\n"; + ++$ruleno; + $macrules .= "delete {$ruleno}\n"; + } + unset($config['captiveportal']['passthrumac'][$idx]); + $mac['mac'] = $clientmac; + $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; + $sessionid = true; + break; + } + } + } else { + portal_reply_page($redirurl, "error", "Username: {$username} is already authenticated using another MAC address.", + $clientmac, $clientip, $username, $password); + exit; + } + } + } + } + + $nousers = count($cpdb); + for ($i = 0; $i < $nousers; $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) + return 0; // voucher already used and no time left + + 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; + if (isset($config['captiveportal']['passthrumacaddusername'])) + $mac['username'] = $username; + $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); + } + } + + if ($writecfg == true) + write_config(); + + /* redirect user to desired destination */ + if (!empty($attributes['url_redirection'])) + $my_redirurl = $attributes['url_redirection']; + else if ($config['captiveportal']['redirurl']) + $my_redirurl = $config['captiveportal']['redirurl']; + else + $my_redirurl = $redirurl; + + if(isset($config['captiveportal']['logoutwin_enable']) && !$passthrumac) { + + 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}/"; + } + + if (isset($attributes['reply_message'])) + $message = $attributes['reply_message']; + else + $message = 0; + + include("{$g['varetc_path']}/captiveportal-logout.html"); + + } else { + header("Location: " . $my_redirurl); + } + + return $sessionid; +} + + + +/* remove a single client by session ID + * by Dinesh Nair + */ +function disconnect_client($sessionid, $logoutReason = "LOGOUT", $term_cause = 1) { + global $g, $config; + + /* read database */ + $cpdb = captiveportal_read_db(); + + $radiusservers = captiveportal_get_radius_servers(); + + /* find entry */ + $dbcount = count($cpdb); + for ($i = 0; $i < $dbcount; $i++) { + if ($cpdb[$i][5] == $sessionid) { + captiveportal_disconnect($cpdb[$i],$radiusservers, $term_cause); + captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],$logoutReason); + unset($cpdb[$i]); + break; + } + } + + /* write database */ + captiveportal_write_db($cpdb); +} + +/* + * Used for when pass-through credits are enabled. + * Returns true when there was at least one free login to deduct for the MAC. + * Expired entries are removed as they are seen. + * Active entries are updated according to the configuration. + */ +function portal_consume_passthrough_credit($clientmac) { + global $config; + + if (!empty($config['captiveportal']['freelogins_count']) && is_numeric($config['captiveportal']['freelogins_count'])) + $freeloginscount = $config['captiveportal']['freelogins_count']; + else + return false; + + if (!empty($config['captiveportal']['freelogins_resettimeout']) && is_numeric($config['captiveportal']['freelogins_resettimeout'])) + $resettimeout = $config['captiveportal']['freelogins_resettimeout']; + else + return false; + + if ($freeloginscount < 1 || $resettimeout <= 0 || !clientmac) + return false; + + $updatetimeouts = isset($config['captiveportal']['freelogins_updatetimeouts']); + + /* + * Read database of used MACs. Lines are a comma-separated list + * of the time, MAC, then the count of pass-through credits remaining. + */ + $usedmacs = captiveportal_read_usedmacs_db(); + + $currenttime = time(); + $found = false; + foreach ($usedmacs as $key => $usedmac) { + $usedmac = explode(",", $usedmac); + + if ($usedmac[1] == $clientmac) { + if ($usedmac[0] + ($resettimeout * 3600) > $currenttime) { + if ($usedmac[2] < 1) { + if ($updatetimeouts) { + $usedmac[0] = $currenttime; + unset($usedmacs[$key]); + $usedmacs[] = implode(",", $usedmac); + captiveportal_write_usedmacs_db($usedmacs); + } + + return false; + } else { + $usedmac[2] -= 1; + $usedmacs[$key] = implode(",", $usedmac); + } + + $found = true; + } else + unset($usedmacs[$key]); + + break; + } else if ($usedmac[0] + ($resettimeout * 3600) <= $currenttime) + unset($usedmacs[$key]); + } + + if (!$found) { + $usedmac = array($currenttime, $clientmac, $freeloginscount - 1); + $usedmacs[] = implode(",", $usedmac); + } + + captiveportal_write_usedmacs_db($usedmacs); + return true; +} + +function captiveportal_read_usedmacs_db() { + global $g; + + $cpumaclck = lock('captiveusedmacs'); + if (file_exists("{$g['vardb_path']}/captiveportal_usedmacs.db")) { + $usedmacs = file("{$g['vardb_path']}/captiveportal_usedmacs.db", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (!usedmacs) + $usedmacs = array(); + } else + $usedmacs = array(); + + unlock($cpumaclck); + return $usedmacs; +} + +function captiveportal_write_usedmacs_db($usedmacs) { + global $g; + + $cpumaclck = lock('captiveusedmacs', LOCK_EX); + @file_put_contents("{$g['vardb_path']}/captiveportal_usedmacs.db", implode("\n", $usedmacs)); + unlock($cpumaclck); +} + + + +?> diff --git a/usr/local/captiveportal/index.php b/usr/local/captiveportal/index.php index caaa4d2..30dec37 100755 --- a/usr/local/captiveportal/index.php +++ b/usr/local/captiveportal/index.php @@ -204,411 +204,5 @@ EOD; exit; -function portal_reply_page($redirurl, $type = null, $message = null, $clientmac = null, $clientip = null, $username = null, $password = null) { - global $g, $config; - - /* Get captive portal layout */ - if ($type == "redir") { - header("Location: {$redirurl}"); - return; - } else if ($type == "login") - $htmltext = get_include_contents("{$g['varetc_path']}/captiveportal.html"); - else - $htmltext = get_include_contents("{$g['varetc_path']}/captiveportal-error.html"); - - /* substitute the PORTAL_REDIRURL variable */ - if ($config['captiveportal']['preauthurl']) { - $htmltext = str_replace("\$PORTAL_REDIRURL\$", "{$config['captiveportal']['preauthurl']}", $htmltext); - $htmltext = str_replace("#PORTAL_REDIRURL#", "{$config['captiveportal']['preauthurl']}", $htmltext); - } - - /* substitute other variables */ - if (isset($config['captiveportal']['httpslogin'])) { - $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext); - $htmltext = str_replace("#PORTAL_ACTION#", "https://{$config['captiveportal']['httpsname']}:8001/", $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_ACTION#", "http://{$ourhostname}/", $htmltext); - } - - $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext); - $htmltext = str_replace("\$PORTAL_MESSAGE\$", htmlspecialchars($message), $htmltext); - $htmltext = str_replace("\$CLIENT_MAC\$", htmlspecialchars($clientmac), $htmltext); - $htmltext = str_replace("\$CLIENT_IP\$", htmlspecialchars($clientip), $htmltext); - - // Special handling case for captive portal master page so that it can be ran - // through the PHP interpreter using the include method above. We convert the - // $VARIABLE$ case to #VARIABLE# in /etc/inc/captiveportal.inc before writing out. - $htmltext = str_replace("#PORTAL_REDIRURL#", htmlspecialchars($redirurl), $htmltext); - $htmltext = str_replace("#PORTAL_MESSAGE#", htmlspecialchars($message), $htmltext); - $htmltext = str_replace("#CLIENT_MAC#", htmlspecialchars($clientmac), $htmltext); - $htmltext = str_replace("#CLIENT_IP#", htmlspecialchars($clientip), $htmltext); - $htmltext = str_replace("#USERNAME#", htmlspecialchars($username), $htmltext); - $htmltext = str_replace("#PASSWORD#", htmlspecialchars($password), $htmltext); - - echo $htmltext; -} - -function portal_mac_radius($clientmac,$clientip) { - global $config ; - - $radmac_secret = $config['captiveportal']['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"); - - return FALSE; -} - -function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $ruleno = null) { - - global $redirurl, $g, $config, $type, $passthrumac, $_POST; - - /* See if a ruleno is passed, if not start sessions because this means there isn't one atm */ - if ($ruleno == null) - $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"); - 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']; - - $writecfg = false; - /* Find an existing session */ - if ((isset($config['captiveportal']['noconcurrentlogins'])) && $passthrumac) { - if (isset($config['captiveportal']['passthrumacadd'])) { - $mac = captiveportal_passthrumac_findbyname($username); - if (!empty($mac)) { - if ($_POST['replacemacpassthru']) { - foreach ($config['captiveportal']['passthrumac'] as $idx => $macent) { - if ($macent['mac'] == $mac['mac']) { - $macrules = ""; - $ruleno = captiveportal_get_ipfw_passthru_ruleno($mac['mac']); - if ($ruleno) { - captiveportal_free_ipfw_ruleno($ruleno, true); - $macrules .= "delete {$ruleno}\n"; - ++$ruleno; - $macrules .= "delete {$ruleno}\n"; - } - unset($config['captiveportal']['passthrumac'][$idx]); - $mac['mac'] = $clientmac; - $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; - $sessionid = true; - break; - } - } - } else { - portal_reply_page($redirurl, "error", "Username: {$username} is already authenticated using another MAC address.", - $clientmac, $clientip, $username, $password); - exit; - } - } - } - } - - $nousers = count($cpdb); - for ($i = 0; $i < $nousers; $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) - return 0; // voucher already used and no time left - - 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; - if (isset($config['captiveportal']['passthrumacaddusername'])) - $mac['username'] = $username; - $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); - } - } - - if ($writecfg == true) - write_config(); - - /* redirect user to desired destination */ - if (!empty($attributes['url_redirection'])) - $my_redirurl = $attributes['url_redirection']; - else if ($config['captiveportal']['redirurl']) - $my_redirurl = $config['captiveportal']['redirurl']; - else - $my_redirurl = $redirurl; - - if(isset($config['captiveportal']['logoutwin_enable']) && !$passthrumac) { - - 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}/"; - } - - if (isset($attributes['reply_message'])) - $message = $attributes['reply_message']; - else - $message = 0; - - include("{$g['varetc_path']}/captiveportal-logout.html"); - - } else { - header("Location: " . $my_redirurl); - } - - return $sessionid; -} - - - -/* remove a single client by session ID - * by Dinesh Nair - */ -function disconnect_client($sessionid, $logoutReason = "LOGOUT", $term_cause = 1) { - global $g, $config; - - /* read database */ - $cpdb = captiveportal_read_db(); - - $radiusservers = captiveportal_get_radius_servers(); - - /* find entry */ - $dbcount = count($cpdb); - for ($i = 0; $i < $dbcount; $i++) { - if ($cpdb[$i][5] == $sessionid) { - captiveportal_disconnect($cpdb[$i],$radiusservers, $term_cause); - captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],$logoutReason); - unset($cpdb[$i]); - break; - } - } - - /* write database */ - captiveportal_write_db($cpdb); -} - -/* - * Used for when pass-through credits are enabled. - * Returns true when there was at least one free login to deduct for the MAC. - * Expired entries are removed as they are seen. - * Active entries are updated according to the configuration. - */ -function portal_consume_passthrough_credit($clientmac) { - global $config; - - if (!empty($config['captiveportal']['freelogins_count']) && is_numeric($config['captiveportal']['freelogins_count'])) - $freeloginscount = $config['captiveportal']['freelogins_count']; - else - return false; - - if (!empty($config['captiveportal']['freelogins_resettimeout']) && is_numeric($config['captiveportal']['freelogins_resettimeout'])) - $resettimeout = $config['captiveportal']['freelogins_resettimeout']; - else - return false; - - if ($freeloginscount < 1 || $resettimeout <= 0 || !clientmac) - return false; - - $updatetimeouts = isset($config['captiveportal']['freelogins_updatetimeouts']); - - /* - * Read database of used MACs. Lines are a comma-separated list - * of the time, MAC, then the count of pass-through credits remaining. - */ - $usedmacs = captiveportal_read_usedmacs_db(); - - $currenttime = time(); - $found = false; - foreach ($usedmacs as $key => $usedmac) { - $usedmac = explode(",", $usedmac); - - if ($usedmac[1] == $clientmac) { - if ($usedmac[0] + ($resettimeout * 3600) > $currenttime) { - if ($usedmac[2] < 1) { - if ($updatetimeouts) { - $usedmac[0] = $currenttime; - unset($usedmacs[$key]); - $usedmacs[] = implode(",", $usedmac); - captiveportal_write_usedmacs_db($usedmacs); - } - - return false; - } else { - $usedmac[2] -= 1; - $usedmacs[$key] = implode(",", $usedmac); - } - - $found = true; - } else - unset($usedmacs[$key]); - - break; - } else if ($usedmac[0] + ($resettimeout * 3600) <= $currenttime) - unset($usedmacs[$key]); - } - - if (!$found) { - $usedmac = array($currenttime, $clientmac, $freeloginscount - 1); - $usedmacs[] = implode(",", $usedmac); - } - - captiveportal_write_usedmacs_db($usedmacs); - return true; -} - -function captiveportal_read_usedmacs_db() { - global $g; - - $cpumaclck = lock('captiveusedmacs'); - if (file_exists("{$g['vardb_path']}/captiveportal_usedmacs.db")) { - $usedmacs = file("{$g['vardb_path']}/captiveportal_usedmacs.db", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); - if (!usedmacs) - $usedmacs = array(); - } else - $usedmacs = array(); - - unlock($cpumaclck); - return $usedmacs; -} - -function captiveportal_write_usedmacs_db($usedmacs) { - global $g; - - $cpumaclck = lock('captiveusedmacs', LOCK_EX); - @file_put_contents("{$g['vardb_path']}/captiveportal_usedmacs.db", implode("\n", $usedmacs)); - unlock($cpumaclck); -} ?> |