SHARE
TWEET

function portal_allow (in /etc/inc/captiveportal.inc)

Nowwhat47 Jan 21st, 2015 (edited) 481 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $pipeno = null, $radiusctx = null)  {
  2.         global $redirurl, $g, $config, $type, $passthrumac, $_POST, $cpzone;
  3.  
  4.         // Ensure we create an array if we are missing attributes
  5.         if (!is_array($attributes))
  6.                 $attributes = array();
  7.  
  8.         unset($sessionid);
  9.  
  10.         /* Do not allow concurrent login execution. */
  11.         $cpdblck = lock("captiveportaldb{$cpzone}", LOCK_EX);
  12.  
  13.         if ($attributes['voucher'])
  14.                 $remaining_time = $attributes['session_timeout'];
  15.  
  16.         $writecfg = false;
  17.         /* Find an existing session */
  18.         if ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && $passthrumac) {
  19.                 if (isset($config['captiveportal'][$cpzone]['passthrumacadd'])) {
  20.                         $mac = captiveportal_passthrumac_findbyname($username);
  21.                         if (!empty($mac)) {
  22.                                 if ($_POST['replacemacpassthru']) {
  23.                                         foreach ($config['captiveportal'][$cpzone]['passthrumac'] as $idx => $macent) {
  24.                                                 if ($macent['mac'] == $mac['mac']) {
  25.                                                         $macrules = "";
  26.                                                         $ruleno = captiveportal_get_ipfw_passthru_ruleno($mac['mac']);
  27.                                                         $pipeno = captiveportal_get_dn_passthru_ruleno($mac['mac']);
  28.                                                         if ($ruleno) {
  29.                                                                 captiveportal_free_ipfw_ruleno($ruleno);
  30.                                                                 $macrules .= "delete {$ruleno}\n";
  31.                                                                 ++$ruleno;
  32.                                                                 $macrules .= "delete {$ruleno}\n";
  33.                                                         }
  34.                                                         if ($pipeno) {
  35.                                                                 captiveportal_free_dn_ruleno($pipeno);
  36.                                                                 $macrules .= "pipe delete {$pipeno}\n";
  37.                                                                 ++$pipeno;
  38.                                                                 $macrules .= "pipe delete {$pipeno}\n";
  39.                                                         }
  40.                                                         unset($config['captiveportal'][$cpzone]['passthrumac'][$idx]);
  41.                                                         $mac['mac'] = $clientmac;
  42.                                                         $config['captiveportal'][$cpzone]['passthrumac'][] = $mac;
  43.                                                         $macrules .= captiveportal_passthrumac_configure_entry($mac);
  44.                                                         file_put_contents("{$g['tmp_path']}/macentry_{$cpzone}.rules.tmp", $macrules);
  45.                                                         mwexec("/sbin/ipfw -x {$cpzone} -q {$g['tmp_path']}/macentry_{$cpzone}.rules.tmp");
  46.                                                         $writecfg = true;
  47.                                                         $sessionid = true;
  48.                                                         break;
  49.                                                 }
  50.                                         }
  51.                                 } else {
  52.                                         portal_reply_page($redirurl, "error", "Username: {$username} is already authenticated using another MAC address.",
  53.                                                 $clientmac, $clientip, $username, $password);
  54.                                         unlock($cpdblck);
  55.                                         return;
  56.                                 }
  57.                         }
  58.                 }
  59.         }
  60.  
  61.         /* read in client database */
  62.         $query = "WHERE ip = '{$clientip}'";
  63.         $tmpusername = strtolower($username);
  64.         if (isset($config['captiveportal'][$cpzone]['noconcurrentlogins']))
  65.                 $query .= " OR (username != 'unauthenticated' AND lower(username) = '{$tmpusername}')";
  66.         $cpdb = captiveportal_read_db($query);
  67.  
  68.         /* Snapshot the timestamp */
  69.         $allow_time = time();
  70.         $radiusservers = captiveportal_get_radius_servers();
  71.         $unsetindexes = array();
  72.         if (is_null($radiusctx))
  73.                 $radiusctx = 'first';
  74.  
  75.         foreach ($cpdb as $cpentry) {
  76.                 if (empty($cpentry[11])) {
  77.                         $cpentry[11] = 'first';
  78.                 }
  79.                 /* on the same ip */
  80.                 if ($cpentry[2] == $clientip) {
  81.                         if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac)
  82.                                 captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - REUSING OLD SESSION");
  83.                         else
  84.                                 captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - REUSING IP {$cpentry[2]} WITH DIFFERENT MAC ADDRESS {$cpentry[3]}");
  85.                         $sessionid = $cpentry[5];
  86.                         break;
  87.                 }
  88.                 elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username)) {
  89.                         // user logged in with an active voucher. Check for how long and calculate
  90.                         // how much time we can give him (voucher credit - used time)
  91.                         $remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
  92.                         if ($remaining_time < 0)    // just in case.
  93.                                 $remaining_time = 0;
  94.  
  95.                         /* This user was already logged in so we disconnect the old one */
  96.                         captiveportal_disconnect($cpentry,$radiusservers[$cpentry[11]],13);
  97.                         captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - TERMINATING OLD SESSION");
  98.                         $unsetindexes[] = $cpentry[5];
  99.                         break;
  100.                 }
  101.                 elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
  102.                         /* on the same username */
  103.                         if (strcasecmp($cpentry[4], $username) == 0) {
  104.                                 /* This user was already logged in so we disconnect the old one */
  105.                                 captiveportal_disconnect($cpentry,$radiusservers[$cpentry[11]],13);
  106.                                 captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - TERMINATING OLD SESSION");
  107.                                 $unsetindexes[] = $cpentry[5];
  108.                                 break;
  109.                         }
  110.                 }
  111.         }
  112.         unset($cpdb);
  113.  
  114.         if (!empty($unsetindexes))
  115.                 captiveportal_remove_entries($unsetindexes);
  116.  
  117.         if ($attributes['voucher'] && $remaining_time <= 0)
  118.                 return 0;       // voucher already used and no time left
  119.  
  120.         if (!isset($sessionid)) {
  121.                 /* generate unique session ID */
  122.                 $tod = gettimeofday();
  123.                 $sessionid = substr(md5(mt_rand() . $tod['sec'] . $tod['usec'] . $clientip . $clientmac), 0, 16);
  124.  
  125.                 if ($passthrumac) {
  126.                         $mac = array();
  127.                         $mac['mac'] = $clientmac;
  128.                         $mac['ip'] = $clientip; /* Used only for logging */
  129.                         if (isset($config['captiveportal'][$cpzone]['passthrumacaddusername'])) {
  130.                                 $mac['username'] = $username;
  131.                                 if ($attributes['voucher'])
  132.                                         $mac['logintype'] = "voucher";
  133.                         }
  134.                         $mac['descr'] =  "Auto added pass-through MAC for user {$username}";
  135.                         if (!empty($bw_up))
  136.                                 $mac['bw_up'] = $bw_up;
  137.                         if (!empty($bw_down))
  138.                                 $mac['bw_down'] = $bw_down;
  139.                         if (!is_array($config['captiveportal'][$cpzone]['passthrumac']))
  140.                                 $config['captiveportal'][$cpzone]['passthrumac'] = array();
  141.                         $config['captiveportal'][$cpzone]['passthrumac'][] = $mac;
  142.                         unlock($cpdblck);
  143.                         $macrules = captiveportal_passthrumac_configure_entry($mac);
  144.                         file_put_contents("{$g['tmp_path']}/macentry_{$cpzone}.rules.tmp", $macrules);
  145.                         mwexec("/sbin/ipfw -x {$cpzone} -q {$g['tmp_path']}/macentry_{$cpzone}.rules.tmp");
  146.                         $writecfg = true;
  147.                 } else {
  148.                         /* See if a pipeno is passed, if not start sessions because this means there isn't one atm */
  149.                         if (is_null($pipeno))
  150.                                 $pipeno = captiveportal_get_next_dn_ruleno();
  151.  
  152.                         /* if the pool is empty, return appropriate message and exit */
  153.                         if (is_null($pipeno)) {
  154.                                 portal_reply_page($redirurl, "error", "System reached maximum login capacity");
  155.                                 log_error("WARNING!  Captive portal has reached maximum login capacity");
  156.                                 unlock($cpdblck);
  157.                                 return;
  158.                         }
  159.  
  160.                         $dwfaultbw_up = isset($config['captiveportal'][$cpzone]['bwdefaultup']) ? $config['captiveportal'][$cpzone]['bwdefaultup'] : 0;
  161.                         $dwfaultbw_down = isset($config['captiveportal'][$cpzone]['bwdefaultdn']) ? $config['captiveportal'][$cpzone]['bwdefaultdn'] : 0;
  162.                         $bw_up = isset($attributes['bw_up']) ? round(intval($attributes['bw_up'])/1000, 2) : $dwfaultbw_up;
  163.                         $bw_down = isset($attributes['bw_down']) ? round(intval($attributes['bw_down'])/1000, 2) : $dwfaultbw_down;
  164.  
  165.                         $bw_up_pipeno = $pipeno;
  166.                         $bw_down_pipeno = $pipeno + 1;
  167.                         //$bw_up /= 1000; // Scale to Kbit/s
  168.                         $_gb = @pfSense_pipe_action("pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100 buckets 16");
  169.                         $_gb = @pfSense_pipe_action("pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100 buckets 16");
  170.  
  171.                         $clientsn = (is_ipaddrv6($clientip)) ? 128 : 32;
  172.                         if (!isset($config['captiveportal'][$cpzone]['nomacfilter']))
  173.                                 $_gb = @pfSense_ipfw_Tableaction($cpzone, IP_FW_TABLE_ADD, 1, $clientip, $clientsn, $clientmac, $bw_up_pipeno);
  174.                         else
  175.                                 $_gb = @pfSense_ipfw_Tableaction($cpzone, IP_FW_TABLE_ADD, 1, $clientip, $clientsn, NULL, $bw_up_pipeno);
  176.  
  177.                         if (!isset($config['captiveportal'][$cpzone]['nomacfilter']))
  178.                                 $_gb = @pfSense_ipfw_Tableaction($cpzone, IP_FW_TABLE_ADD, 2, $clientip, $clientsn, $clientmac, $bw_down_pipeno);
  179.                         else
  180.                                 $_gb = @pfSense_ipfw_Tableaction($cpzone, IP_FW_TABLE_ADD, 2, $clientip, $clientsn, NULL, $bw_down_pipeno);
  181.  
  182.                         if ($attributes['voucher'])
  183.                                 $attributes['session_timeout'] = $remaining_time;
  184.                        
  185.                         /* handle empty attributes */
  186.                         $session_timeout = (!empty($attributes['session_timeout'])) ? $attributes['session_timeout'] : 'NULL';
  187.                         $idle_timeout = (!empty($attributes['idle_timeout'])) ? $attributes['idle_timeout'] : 'NULL';
  188.                         $session_terminate_time = (!empty($attributes['session_terminate_time'])) ? $attributes['session_terminate_time'] : 'NULL';
  189.                         $interim_interval = (!empty($attributes['interim_interval'])) ? $attributes['interim_interval'] : 'NULL';
  190.  
  191.                         /* escape username */
  192.                         $safe_username = sqlite_escape_string($username);
  193.  
  194.                         /* encode password in Base64 just in case it contains commas */
  195.                         $bpassword = base64_encode($password);
  196.                         $insertquery  = "INSERT INTO captiveportal (allow_time, pipeno, ip, mac, username, sessionid, bpassword, session_timeout, idle_timeout, session_terminate_time, interim_interval, radiusctx) ";
  197.                         $insertquery .= "VALUES ({$allow_time}, {$pipeno}, '{$clientip}', '{$clientmac}', '{$safe_username}', '{$sessionid}', '{$bpassword}', ";
  198.                         $insertquery .= "{$session_timeout}, {$idle_timeout}, {$session_terminate_time}, {$interim_interval}, '{$radiusctx}')";
  199.  
  200.                         /* store information to database */
  201.                         captiveportal_write_db($insertquery);
  202.                         unlock($cpdblck);
  203.                         unset($insertquery, $bpassword);
  204.  
  205.                         if (isset($config['captiveportal'][$cpzone]['radacct_enable']) && !empty($radiusservers[$radiusctx])) {
  206.                                 $acct_val = RADIUS_ACCOUNTING_START($pipeno, $username, $sessionid, $radiusservers[$radiusctx], $clientip, $clientmac);
  207.                                 if ($acct_val == 1)
  208.                                         captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED");
  209.                         }
  210.                 }
  211.         } else {
  212.                 /* NOTE: #3062-11 If the pipeno has been allocated free it to not DoS the CP and maintain proper operation as in radius() case */
  213.                 if (!is_null($pipeno))
  214.                         captiveportal_free_dn_ruleno($pipeno);
  215.  
  216.                 unlock($cpdblck);
  217.         }
  218.  
  219.         if ($writecfg == true)
  220.                 write_config();
  221.  
  222.         $timeout = 0;
  223.         if (!empty($config['captiveportal'][$cpzone]['timeout']) && is_numeric($config['captiveportal'][$cpzone]['timeout'])) {
  224.                 $timeout = time() + $config['captiveportal'][$cpzone]['timeout'] * 60;
  225.                 setcookie("cookie_portal", $sessionid, $timeout);
  226.         } else
  227.                 setcookie("cookie_portal", $sessionid, $timeout);      
  228.                
  229.         /* redirect user to desired destination */
  230.         if (!empty($attributes['url_redirection']))
  231.                 $my_redirurl = $attributes['url_redirection'];
  232.         else if (!empty($redirurl))
  233.                 $my_redirurl = $redirurl;
  234.         else if (!empty($config['captiveportal'][$cpzone]['redirurl']))
  235.                 $my_redirurl = $config['captiveportal'][$cpzone]['redirurl'];
  236.  
  237.         if(isset($config['captiveportal'][$cpzone]['logoutwin_enable']) && !$passthrumac) {
  238.                 $ourhostname = portal_hostname_from_client_ip($clientip);
  239.                 $protocol = (isset($config['captiveportal'][$cpzone]['httpslogin'])) ? 'https://' : 'http://';
  240.                 $logouturl = "{$protocol}{$ourhostname}/";
  241.  
  242.                 if (isset($attributes['reply_message']))
  243.                         $message = $attributes['reply_message'];
  244.                 else
  245.                         $message = 0;
  246.  
  247.                 include("{$g['varetc_path']}/captiveportal-{$cpzone}-logout.html");
  248.  
  249.         } else {
  250.                 portal_reply_page($my_redirurl, "redir", "Just redirect the user.");
  251.         }
  252.  
  253.         return $sessionid;
  254. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top