captive portal: bye bye my love

The captive portal is being replaced!  This hooks up the
new page into the services section while ditching most of
the old code.  There'll be no migration, if you use package
`opnsense-devel' and the captive portal you'll have to switch
to `opnsense' or migrate to the new code.  Beware that the
new captive portal is going to be a huge step forward but
features will trickle in week after week until it is stable
enough to merge it.  Latest release date is going to be 16.1.
This commit is contained in:
Franco Fichtner 2015-10-15 23:37:28 +02:00
parent 1812da68d4
commit 5e5e6c2f27
63 changed files with 70 additions and 9325 deletions

View File

@ -1,4 +1,4 @@
ROOT= /usr/local
TREES= captiveportal etc opnsense pkg sbin wizard www
TREES= etc opnsense pkg sbin wizard www
.include "../Mk/tree.mk"

View File

@ -1,268 +0,0 @@
<?php
/*
Copyrigth (C) 2009 Ermal Luçi
Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("config.inc");
require_once("auth.inc");
require_once("interfaces.inc");
require_once("captiveportal.inc");
require_once("util.inc");
$errormsg = "Invalid credentials specified.";
header("Expires: 0");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Connection: close");
global $cpzone, $cpzoneid;
$cpzone = $_REQUEST['zone'];
$cpcfg = $config['captiveportal'][$cpzone];
if (empty($cpcfg)) {
log_error("Submission to captiveportal with unkown parameter zone: " . htmlspecialchars($cpzone));
portal_reply_page($redirurl, "error", $errormsg);
ob_flush();
return;
}
$cpzoneid = $cpcfg['zoneid'];
$orig_host = $_SERVER['HTTP_HOST'];
/* NOTE: IE 8/9 is buggy and that is why this is needed */
$orig_request = trim($_REQUEST['redirurl'], " /");
$clientip = $_SERVER['REMOTE_ADDR'];
if (!$clientip) {
/* not good - bail out */
log_error("Zone: {$cpzone} - Captive portal could not determine client's IP address.");
$error_message = "An error occurred. Please check the system logs for more information.";
portal_reply_page($redirurl, "error", $errormsg);
ob_flush();
return;
}
$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... */
$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'];
} elseif (preg_match("/redirurl=(.*)/", $orig_request, $matches)) {
$redirurl = urldecode($matches[1]);
} elseif ($_REQUEST['redirurl']) {
$redirurl = $_REQUEST['redirurl'];
}
$macfilter = !isset($cpcfg['nomacfilter']);
$passthrumac = isset($cpcfg['passthrumacadd']);
function ip_to_mac($addr)
{
$cmd = '/usr/sbin/arp -n ' . $addr;
$ret = false;
exec($cmd, $out, $ret);
if ($ret) {
log_error('The command `' . $cmd . '\' failed to execute');
} else {
$mac = explode(' ', $out[0]);
if (isset($mac[3])) {
$ret = $mac[3];
}
}
return $ret;
}
/* find MAC address for client */
if ($macfilter || $passthrumac) {
$tmpres = ip_to_mac($clientip);
if (!$tmpres) {
/* unable to find MAC address - shouldn't happen! - bail out */
captiveportal_logportalauth("unauthenticated", "noclientmac", $clientip, "ERROR");
echo "An error occurred. Please check the system logs for more information.";
log_error("Zone: {$cpzone} - Captive portal could not determine client's MAC address. Disable MAC address filtering in captive portal if you do not need this functionality.");
ob_flush();
return;
}
$clientmac = $tmpres;
unset($tmpres);
}
/* find out if we need RADIUS + RADIUSMAC or not */
if (file_exists("/var/db/captiveportal_radius_{$cpzone}.db")) {
$radius_enable = true;
if (isset($cpcfg['radmac_enable'])) {
$radmac_enable = true;
}
}
/* find radius context */
$radiusctx = 'first';
if ($_POST['auth_user2']) {
$radiusctx = 'second';
}
if ($_POST['logout_id']) {
echo <<<EOD
<html>
<head><title>Disconnecting...</title></head>
<body bgcolor="#435370">
<span style="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
<b>You have been disconnected.</b>
</span>
<script type="text/javascript">
<!--
setTimeout('window.close();',5000) ;
-->
</script>
</body>
</html>
EOD;
captiveportal_disconnect_client($_POST['logout_id']);
} elseif ($macfilter && $clientmac && captiveportal_blocked_mac($clientmac)) {
captiveportal_logportalauth($clientmac, $clientmac, $clientip, "Blocked MAC address");
if (!empty($cpcfg['blockedmacsurl'])) {
portal_reply_page($cpcfg['blockedmacsurl'], "redir");
} else {
portal_reply_page($redirurl, "error", "This MAC address has been blocked");
}
} elseif ($clientmac && $radmac_enable && portal_mac_radius($clientmac, $clientip, $radiusctx)) {
/* radius functions handle everything so we exit here since we're done */
} elseif (portal_consume_passthrough_credit($clientmac)) {
/* allow the client through if it had a pass-through credit for its MAC */
captiveportal_logportalauth("unauthenticated", $clientmac, $clientip, "ACCEPT");
portal_allow($clientip, $clientmac, "unauthenticated");
} elseif (isset($config['voucher'][$cpzone]['enable']) && $_POST['accept'] && $_POST['auth_voucher']) {
$voucher = trim($_POST['auth_voucher']);
$timecredit = voucher_auth($voucher);
// $timecredit contains either a credit in minutes or an error message
if ($timecredit > 0) { // voucher is valid. Remaining minutes returned
// if multiple vouchers given, use the first as username
$a_vouchers = preg_split("/[\t\n\r ]+/s", $voucher);
$voucher = $a_vouchers[0];
$attr = array( 'voucher' => 1,
'session_timeout' => $timecredit*60,
'session_terminate_time' => 0);
if (portal_allow($clientip, $clientmac, $voucher, null, $attr)) {
// YES: user is good for $timecredit minutes.
captiveportal_logportalauth($voucher, $clientmac, $clientip, "Voucher login good for $timecredit min.");
portal_reply_page($redirurl, "redir", "Just redirect the user.");
} else {
portal_reply_page($redirurl, "error", $config['voucher'][$cpzone]['msgexpired'] ? $config['voucher'][$cpzone]['msgexpired']: $errormsg);
}
} elseif (-1 == $timecredit) { // valid but expired
captiveportal_logportalauth($voucher, $clientmac, $clientip, "FAILURE", "voucher expired");
portal_reply_page($redirurl, "error", $config['voucher'][$cpzone]['msgexpired'] ? $config['voucher'][$cpzone]['msgexpired']: $errormsg);
} else {
captiveportal_logportalauth($voucher, $clientmac, $clientip, "FAILURE");
portal_reply_page($redirurl, "error", $config['voucher'][$cpzone]['msgnoaccess'] ? $config['voucher'][$cpzone]['msgnoaccess'] : $errormsg);
}
} elseif ($_POST['accept'] && $radius_enable) {
if (($_POST['auth_user'] && isset($_POST['auth_pass'])) || ($_POST['auth_user2'] && isset($_POST['auth_pass2']))) {
if (!empty($_POST['auth_user'])) {
$user = $_POST['auth_user'];
$paswd = $_POST['auth_pass'];
} elseif (!empty($_POST['auth_user2'])) {
$user = $_POST['auth_user2'];
$paswd = $_POST['auth_pass2'];
}
$auth_list = radius($user, $paswd, $clientip, $clientmac, "USER LOGIN", $radiusctx);
$type = "error";
if (!empty($auth_list['url_redirection'])) {
$redirurl = $auth_list['url_redirection'];
$type = "redir";
}
if ($auth_list['auth_val'] == 1) {
captiveportal_logportalauth($user, $clientmac, $clientip, "ERROR", $auth_list['error']);
portal_reply_page($redirurl, $type, $auth_list['error'] ? $auth_list['error'] : $errormsg);
} elseif ($auth_list['auth_val'] == 3) {
captiveportal_logportalauth($user, $clientmac, $clientip, "FAILURE", $auth_list['reply_message']);
portal_reply_page($redirurl, $type, $auth_list['reply_message'] ? $auth_list['reply_message'] : $errormsg);
} else {
portal_reply_page($redirurl, "redir", "Just redirect the user.");
}
} else {
if (!empty($_POST['auth_user'])) {
$user = $_POST['auth_user'];
} elseif (!empty($_POST['auth_user2'])) {
$user = $_POST['auth_user2'];
} else {
$user = 'unknown';
}
captiveportal_logportalauth($user, $clientmac, $clientip, "ERROR");
portal_reply_page($redirurl, "error", $errormsg);
}
} elseif ($_POST['accept'] && $cpcfg['auth_method'] == "local") {
if ($_POST['auth_user'] && $_POST['auth_pass']) {
//check against local user manager
$loginok = local_backed($_POST['auth_user'], $_POST['auth_pass']);
if ($loginok && isset($cpcfg['localauth_priv'])) {
$loginok = userHasPrivilege(getUserEntry($_POST['auth_user']), "user-services-captiveportal-login");
}
if ($loginok) {
captiveportal_logportalauth($_POST['auth_user'], $clientmac, $clientip, "LOGIN");
portal_allow($clientip, $clientmac, $_POST['auth_user']);
portal_reply_page($redirurl, "redir", "Just redirect the user.");
} else {
captiveportal_logportalauth($_POST['auth_user'], $clientmac, $clientip, "FAILURE");
portal_reply_page($redirurl, "error", $errormsg);
}
} else {
portal_reply_page($redirurl, "error", $errormsg);
}
} elseif ($_POST['accept'] && $clientip && $cpcfg['auth_method'] == "none") {
captiveportal_logportalauth("unauthenticated", $clientmac, $clientip, "ACCEPT");
portal_allow($clientip, $clientmac, "unauthenticated");
} else {
/* display captive portal page */
portal_reply_page($redirurl, "login", null, $clientmac, $clientip);
}
ob_flush();

View File

@ -457,6 +457,6 @@
</monitor_type>
</load_balancer>
<widgets>
<sequence>system_information-container:col1:show,captive_portal_status-container:col1:close,carp_status-container:col1:close,cpu_graphs-container:col1:close,gateways-container:col1:close,interface_statistics-container:col1:close,interface_list-container:col2:show,ipsec-container:col2:close,load_balancer_status-container:col2:close,log-container:col2:close,picture-container:col2:close,rss-container:col2:close,services_status-container:col2:close,traffic_graphs-container:col2:close</sequence>
<sequence>system_information-container:col1:show,carp_status-container:col1:close,gateways-container:col1:close,interface_statistics-container:col1:close,interface_list-container:col2:show,ipsec-container:col2:close,load_balancer_status-container:col2:close,log-container:col2:close,picture-container:col2:close,rss-container:col2:close,services_status-container:col2:close,traffic_graphs-container:col2:close</sequence>
</widgets>
</opnsense>

View File

@ -1,463 +0,0 @@
<?php
/*
Copyright (c) 2002-2010, Michael Bretterklieber <michael@bretterklieber.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This code cannot simply be copied and put under the GNU Public License or
any other GPL-like (LGPL, GPL2) License.
$Id: CHAP.php 302857 2010-08-28 21:12:59Z mbretter $
*/
require_once 'PEAR.inc';
/**
* Classes for generating packets for various CHAP Protocols:
* CHAP-MD5: RFC1994
* MS-CHAPv1: RFC2433
* MS-CHAPv2: RFC2759
*
* @package Crypt_CHAP
* @author Michael Bretterklieber <michael@bretterklieber.com>
* @access public
* @version $Revision: 302857 $
*/
/**
* class Crypt_CHAP
*
* Abstract base class for CHAP
*
* @package Crypt_CHAP
*/
class Crypt_CHAP extends PEAR
{
/**
* Random binary challenge
* @var string
*/
var $challenge = null;
/**
* Binary response
* @var string
*/
var $response = null;
/**
* User password
* @var string
*/
var $password = null;
/**
* Id of the authentication request. Should incremented after every request.
* @var integer
*/
var $chapid = 1;
/**
* Constructor
*
* Generates a random challenge
* @return void
*/
function Crypt_CHAP()
{
$this->PEAR();
$this->generateChallenge();
}
/**
* Generates a random binary challenge
*
* @param string $varname Name of the property
* @param integer $size Size of the challenge in Bytes
* @return void
*/
function generateChallenge($varname = 'challenge', $size = 8)
{
$this->$varname = '';
for ($i = 0; $i < $size; $i++) {
$this->$varname .= pack('C', 1 + mt_rand() % 255);
}
return $this->$varname;
}
/**
* Generates the response. Overwrite this.
*
* @return void
*/
function challengeResponse()
{
}
}
/**
* class Crypt_CHAP_MD5
*
* Generate CHAP-MD5 Packets
*
* @package Crypt_CHAP
*/
class Crypt_CHAP_MD5 extends Crypt_CHAP
{
/**
* Generates the response.
*
* CHAP-MD5 uses MD5-Hash for generating the response. The Hash consists
* of the chapid, the plaintext password and the challenge.
*
* @return string
*/
function challengeResponse()
{
return pack('H*', md5(pack('C', $this->chapid) . $this->password . $this->challenge));
}
}
/**
* class Crypt_CHAP_MSv1
*
* Generate MS-CHAPv1 Packets. MS-CHAP doesen't use the plaintext password, it uses the
* NT-HASH wich is stored in the SAM-Database or in the smbpasswd, if you are using samba.
* The NT-HASH is MD4(str2unicode(plaintextpass)).
* You need the hash extension for this class.
*
* @package Crypt_CHAP
*/
class Crypt_CHAP_MSv1 extends Crypt_CHAP
{
/**
* Wether using deprecated LM-Responses or not.
* 0 = use LM-Response, 1 = use NT-Response
* @var bool
*/
var $flags = 1;
/**
* Constructor
*
* Loads the hash extension
* @return void
*/
function Crypt_CHAP_MSv1()
{
$this->Crypt_CHAP();
self::loadExtension('hash');
}
/**
* Generates the NT-HASH from the given plaintext password.
*
* @access public
* @return string
*/
function ntPasswordHash($password = null)
{
if (isset($password)) {
return pack('H*',hash('md4', $this->str2unicode($password)));
} else {
return pack('H*',hash('md4', $this->str2unicode($this->password)));
}
}
/**
* Converts ascii to unicode.
*
* @access public
* @return string
*/
function str2unicode($str)
{
$uni = '';
$str = (string) $str;
for ($i = 0; $i < strlen($str); $i++) {
$a = ord($str{$i}) << 8;
$uni .= sprintf("%X", $a);
}
return pack('H*', $uni);
}
/**
* Generates the NT-Response.
*
* @access public
* @return string
*/
function challengeResponse()
{
return $this->_challengeResponse();
}
/**
* Generates the NT-Response.
*
* @access public
* @return string
*/
function ntChallengeResponse()
{
return $this->_challengeResponse(false);
}
/**
* Generates the LAN-Manager-Response.
*
* @access public
* @return string
*/
function lmChallengeResponse()
{
return $this->_challengeResponse(true);
}
/**
* Generates the response.
*
* Generates the response using DES.
*
* @param bool $lm wether generating LAN-Manager-Response
* @access private
* @return string
*/
function _challengeResponse($lm = false)
{
if ($lm) {
$hash = $this->lmPasswordHash();
} else {
$hash = $this->ntPasswordHash();
}
while (strlen($hash) < 21) {
$hash .= "\0";
}
$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$key = $this->_desAddParity(substr($hash, 0, 7));
mcrypt_generic_init($td, $key, $iv);
$resp1 = mcrypt_generic($td, $this->challenge);
mcrypt_generic_deinit($td);
$key = $this->_desAddParity(substr($hash, 7, 7));
mcrypt_generic_init($td, $key, $iv);
$resp2 = mcrypt_generic($td, $this->challenge);
mcrypt_generic_deinit($td);
$key = $this->_desAddParity(substr($hash, 14, 7));
mcrypt_generic_init($td, $key, $iv);
$resp3 = mcrypt_generic($td, $this->challenge);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $resp1 . $resp2 . $resp3;
}
/**
* Generates the LAN-Manager-HASH from the given plaintext password.
*
* @access public
* @return string
*/
function lmPasswordHash($password = null)
{
$plain = isset($password) ? $password : $this->password;
$plain = substr(strtoupper($plain), 0, 14);
while (strlen($plain) < 14) {
$plain .= "\0";
}
return $this->_desHash(substr($plain, 0, 7)) . $this->_desHash(substr($plain, 7, 7));
}
/**
* Generates an irreversible HASH.
*
* @access private
* @return string
*/
function _desHash($plain)
{
$key = $this->_desAddParity($plain);
$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$hash = mcrypt_generic($td, 'KGS!@#$%');
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $hash;
}
/**
* Adds the parity bit to the given DES key.
*
* @access private
* @param string $key 7-Bytes Key without parity
* @return string
*/
function _desAddParity($key)
{
static $odd_parity = array(
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254);
$bin = '';
for ($i = 0; $i < strlen($key); $i++) {
$bin .= sprintf('%08s', decbin(ord($key{$i})));
}
$str1 = explode('-', substr(chunk_split($bin, 7, '-'), 0, -1));
$x = '';
foreach($str1 as $s) {
$x .= sprintf('%02s', dechex($odd_parity[bindec($s . '0')]));
}
return pack('H*', $x);
}
/**
* Generates the response-packet.
*
* @param bool $lm wether including LAN-Manager-Response
* @access private
* @return string
*/
function response($lm = false)
{
$ntresp = $this->ntChallengeResponse();
if ($lm) {
$lmresp = $this->lmChallengeResponse();
} else {
$lmresp = str_repeat ("\0", 24);
}
// Response: LM Response, NT Response, flags (0 = use LM Response, 1 = use NT Response)
return $lmresp . $ntresp . pack('C', !$lm);
}
}
/**
* class Crypt_CHAP_MSv2
*
* Generate MS-CHAPv2 Packets. This version of MS-CHAP uses a 16 Bytes authenticator
* challenge and a 16 Bytes peer Challenge. LAN-Manager responses no longer exists
* in this version. The challenge is already a SHA1 challenge hash of both challenges
* and of the username.
*
* @package Crypt_CHAP
*/
class Crypt_CHAP_MSv2 extends Crypt_CHAP_MSv1
{
/**
* The username
* @var string
*/
var $username = null;
/**
* The 16 Bytes random binary peer challenge
* @var string
*/
var $peerChallenge = null;
/**
* The 16 Bytes random binary authenticator challenge
* @var string
*/
var $authChallenge = null;
/**
* Constructor
*
* Generates the 16 Bytes peer and authentication challenge
* @return void
*/
function Crypt_CHAP_MSv2()
{
$this->Crypt_CHAP_MSv1();
$this->generateChallenge('peerChallenge', 16);
$this->generateChallenge('authChallenge', 16);
}
/**
* Generates a hash from the NT-HASH.
*
* @access public
* @param string $nthash The NT-HASH
* @return string
*/
function ntPasswordHashHash($nthash)
{
return pack('H*',hash('md4', $nthash));
}
/**
* Generates the challenge hash from the peer and the authenticator challenge and
* the username. SHA1 is used for this, but only the first 8 Bytes are used.
*
* @access public
* @return string
*/
function challengeHash()
{
return substr(pack('H*',hash('sha1', $this->peerChallenge . $this->authChallenge . $this->username)), 0, 8);
}
/**
* Generates the response.
*
* @access public
* @return string
*/
function challengeResponse()
{
$this->challenge = $this->challengeHash();
return $this->_challengeResponse();
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -1,303 +0,0 @@
<?php
/*
Copyright (c) 2006, Jonathan De Graeve <jonathan.de.graeve@imelda.be>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This code cannot simply be copied and put under the GNU Public License or
any other GPL-like (LGPL, GPL2) License.
This code is made possible thx to samples made by Michael Bretterklieber <michael@bretterklieber.com>
author of the PHP PECL Radius package
*/
define('GIGAWORDS_RIGHT_OPERAND', '4294967296'); // 2^32
/*
RADIUS ACCOUNTING START
-----------------------
*/
PEAR::loadExtension('bcmath');
function RADIUS_ACCOUNTING_START($ruleno, $username, $sessionid, $radiusservers, $clientip, $clientmac) {
global $config, $cpzone;
$retvalue = array();
$nas_mac = mac_format(get_interface_mac("wan"));
$clientmac = mac_format($clientmac);
$nas_port = intval($ruleno);
$radiusvendor = $config['captiveportal'][$cpzone]['radiusvendor'] ? $config['captiveportal'][$cpzone]['radiusvendor'] : null;
switch($radiusvendor) {
case 'cisco':
$calledstationid = $clientmac;
$callingstationid = $clientip;
break;
default:
$calledstationid = getNasIP();
$callingstationid = $clientmac;
break;
}
// Create our instance
$racct = new Auth_RADIUS_Acct_Start;
/* Different Authentication options
*
* Its possible todo other authentication methods but still do radius accounting
*
* RADIUS_AUTH_RADIUS => authenticated via Radius
* RADIUS_AUTH_LOCAL => authenticated local
* RADIUS_AUTH_REMOTE => authenticated remote
*
*/
$racct->authentic = RADIUS_AUTH_RADIUS;
// Construct data package
$racct->username = $username;
/*
Add support for more then one radiusserver.
At most 10 servers may be specified.
When multiple servers are given, they are tried in round-robin fashion until a valid response is received
*/
foreach ($radiusservers as $radsrv) {
// Add a new server to our instance
$racct->addServer($radsrv['ipaddr'], $radsrv['acctport'], $radsrv['key']);
}
if (PEAR::isError($racct->start())) {
$retvalue['acct_val'] = 1;
$retvalue['error'] = $racct->getMessage();
// If we encounter an error immediately stop this function and go back
$racct->close();
return $retvalue;
}
/*
* NAS_PORT_TYPE, int => RADIUS_ETHERNET (15), RADIUS_WIRELESS_OTHER (18), RADIUS_WIRELESS_IEEE_802_11 (19)
*/
// Default attributes
$racct->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_ETHERNET);
$racct->putAttribute(RADIUS_NAS_PORT, $nas_port, 'integer');
$racct->putAttribute(RADIUS_ACCT_SESSION_ID, $sessionid);
// Extra data to identify the client and nas
$racct->putAttribute(RADIUS_FRAMED_IP_ADDRESS, $clientip, "addr");
$racct->putAttribute(RADIUS_CALLED_STATION_ID, $calledstationid);
$racct->putAttribute(RADIUS_CALLING_STATION_ID, $callingstationid);
// Send request
$result = $racct->send();
// Evaluation of the response
// 5 -> Accounting-Response
// See RFC2866 for this.
if (PEAR::isError($result)) {
$retvalue['acct_val'] = 1;
$retvalue['error'] = $result->getMessage();
} else if ($result === true) {
$retvalue['acct_val'] = 5 ;
} else {
$retvalue['acct_val'] = 1 ;
}
// close OO RADIUS_ACCOUNTING
$racct->close();
unset($racct);
return $retvalue ;
}
/*
RADIUS ACCOUNTING STOP/UPDATE
-----------------------------
*/
function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radiusservers,$clientip,$clientmac, $term_cause = 1, $interimupdate=false,$stop_time = null) {
global $config, $cpzone;
$retvalue = array();
$nas_mac = mac_format(get_interface_mac("wan"));
$clientmac = mac_format($clientmac);
$nas_port = intval($ruleno);
$radiusvendor = $config['captiveportal'][$cpzone]['radiusvendor'] ? $config['captiveportal'][$cpzone]['radiusvendor'] : null;
$stop_time = (empty($stop_time)) ? time() : $stop_time;
$session_time = $stop_time - $start_time;
$volume['input_bytes_radius'] = remainder(0);
$volume['input_gigawords'] = gigawords(0);
$volume['output_bytes_radius'] = remainder(0);
$volume['output_gigawords'] = gigawords(0);
switch($radiusvendor) {
case 'cisco':
$calledstationid = $clientmac;
$callingstationid = $clientip;
break;
default:
$calledstationid = getNasIP();
$callingstationid = $clientmac;
break;
}
// Create our instance, see if we should use Accounting Interim Updates or Accounting STOP messages
if ($interimupdate)
$racct = new Auth_RADIUS_Acct_Update;
else
$racct = new Auth_RADIUS_Acct_Stop;
/*
Add support for more then one radiusserver.
At most 10 servers may be specified.
When multiple servers are given, they are tried in round-robin fashion until a valid response is received
*/
foreach ($radiusservers as $radsrv) {
// Add a new server to our instance
$racct->addServer($radsrv['ipaddr'], $radsrv['acctport'], $radsrv['key']);
}
// See RADIUS_ACCOUNTING_START for info
$racct->authentic = RADIUS_AUTH_RADIUS;
// Construct data package
$racct->username = $username;
// Set session_time
$racct->session_time = $session_time;
if (PEAR::isError($racct->start())) {
$retvalue['acct_val'] = 1;
$retvalue['error'] = $racct->getMessage();
// If we encounter an error immediately stop this function and go back
$racct->close();
return $retvalue;
}
// The RADIUS PECL Package doesn't have this vars so we create them ourself
define("RADIUS_ACCT_INPUT_GIGAWORDS", "52");
define("RADIUS_ACCT_OUTPUT_GIGAWORDS", "53");
// Default attributes
$racct->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_ETHERNET);
$racct->putAttribute(RADIUS_NAS_PORT, $nas_port, 'integer');
$racct->putAttribute(RADIUS_ACCT_SESSION_ID, $sessionid);
// Extra data to identify the client and nas
$racct->putAttribute(RADIUS_FRAMED_IP_ADDRESS, $clientip, "addr");
$racct->putAttribute(RADIUS_CALLED_STATION_ID, $calledstationid);
$racct->putAttribute(RADIUS_CALLING_STATION_ID, $callingstationid);
// Volume stuff: Ingress
$racct->putAttribute(RADIUS_ACCT_INPUT_PACKETS, $volume['input_pkts'], "integer");
$racct->putAttribute(RADIUS_ACCT_INPUT_OCTETS, $volume['input_bytes_radius'], "integer");
$racct->putAttribute(RADIUS_ACCT_INPUT_GIGAWORDS, $volume['input_gigawords'], "integer");
// Volume stuff: Outgress
$racct->putAttribute(RADIUS_ACCT_OUTPUT_PACKETS, $volume['output_pkts'], "integer");
$racct->putAttribute(RADIUS_ACCT_OUTPUT_OCTETS, $volume['output_bytes_radius'], "integer");
$racct->putAttribute(RADIUS_ACCT_OUTPUT_GIGAWORDS, $volume['output_gigawords'], "integer");
$racct->putAttribute(RADIUS_ACCT_SESSION_TIME, $session_time, "integer");
if (!$interimupdate)
$racct->putAttribute(RADIUS_ACCT_TERMINATE_CAUSE, $term_cause);
// Send request
$result = $racct->send();
// Evaluation of the response
// 5 -> Accounting-Response
// See RFC2866 for this.
if (PEAR::isError($result)) {
$retvalue['acct_val'] = 1;
$retvalue['error'] = $result->getMessage();
} else if ($result === true) {
$retvalue['acct_val'] = 5 ;
} else {
$retvalue['acct_val'] = 1 ;
}
// close OO RADIUS_ACCOUNTING
$racct->close();
return $retvalue;
}
/**
* Radius Volume Helpers
*
*/
function gigawords($bytes) {
/*
* RFC2866 Specifies a 32bit unsigned integer, which is a max of 4294967295
* Currently there is a fault in the PECL radius_put_int function which can handle only 32bit signed integer.
*/
// We use BCMath functions since normal integers don't work with so large numbers
$gigawords = bcdiv( bcsub( $bytes, remainder($bytes) ) , GIGAWORDS_RIGHT_OPERAND) ;
// We need to manually set this to a zero instead of NULL for put_int() safety
if (is_null($gigawords)) {
$gigawords = 0;
}
return $gigawords;
}
function remainder($bytes) {
// Calculate the bytes we are going to send to the radius
$bytes = bcmod($bytes, GIGAWORDS_RIGHT_OPERAND);
if (is_null($bytes)) {
$bytes = 0;
}
return $bytes;
}
?>

View File

@ -1,181 +0,0 @@
<?php
/*
Copyright (c) 2006, Jonathan De Graeve <jonathan.de.graeve@imelda.be>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This code cannot simply be copied and put under the GNU Public License or
any other GPL-like (LGPL, GPL2) License.
This code is made possible thx to samples made by Michael Bretterklieber <michael@bretterklieber.com>
author of the PHP PECL Radius package
*/
/*
RADIUS AUTHENTICATION
---------------------
*/
require_once("captiveportal.CHAP.inc");
function RADIUS_AUTHENTICATION($username,$password,$radiusservers,$clientip,$clientmac,$ruleno) {
global $config, $cpzone;
$retvalue = array();
$clientmac = mac_format($clientmac);
$nas_port = $ruleno;
$radiusvendor = $config['captiveportal'][$cpzone]['radiusvendor'] ? $config['captiveportal'][$cpzone]['radiusvendor'] : null;
$radius_protocol = $config['captiveportal'][$cpzone]['radius_protocol'];
// Do we even need to set it to NULL?
$retvalue['error'] = $retvalue['reply_message'] = $retvalue['url_redirection'] = $retvalue['session_timeout'] = null;
$retvalue['idle_timeout'] = $retvalue['session_terminate_time'] = $retvalue['interim_interval'] = null;
switch($radiusvendor) {
case 'cisco':
$calledstationid = $clientmac;
$callingstationid = $clientip;
break;
default:
$calledstationid = getNasIP();
$callingstationid = $clientmac;
break;
}
// Create our instance
$classname = 'Auth_RADIUS_' . $radius_protocol;
$rauth = new $classname($username, $password);
/*
* Add support for more then one radiusserver.
* At most 10 servers may be specified.
* When multiple servers are given, they are tried in round-robin fashion until a valid response is received
*/
foreach ($radiusservers as $radsrv) {
// Add a new server to our instance
$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['key']);
}
// Construct data package
$rauth->username = $username;
switch ($radius_protocol) {
case 'CHAP_MD5':
case 'MSCHAPv1':
$classname = $radius_protocol == 'MSCHAPv1' ? 'Crypt_CHAP_MSv1' : 'Crypt_CHAP_MD5';
$crpt = new $classname;
$crpt->username = $username;
$crpt->password = $password;
$rauth->challenge = $crpt->challenge;
$rauth->chapid = $crpt->chapid;
$rauth->response = $crpt->challengeResponse();
$rauth->flags = 1;
// If you must use deprecated and weak LAN-Manager-Responses use this:
//$rauth->lmResponse = $crpt->lmChallengeResponse();
//$rauth->flags = 0;
break;
case 'MSCHAPv2':
// Construct data package
$crpt = new Crypt_CHAP_MSv2;
$crpt->username = $username;
$crpt->password = $password;
$rauth->challenge = $crpt->authChallenge;
$rauth->peerChallenge = $crpt->peerChallenge;
$rauth->chapid = $crpt->chapid;
$rauth->response = $crpt->challengeResponse();
break;
default:
$rauth->password = $password;
break;
}
if (PEAR::isError($rauth->start())) {
$retvalue['auth_val'] = 1;
$retvalue['error'] = $rauth->getError();
// If we encounter an error immediately stop this function and go back
$rauth->close();
return $retvalue;
}
// Default attributes
$rauth->putAttribute(RADIUS_SERVICE_TYPE, RADIUS_LOGIN);
$rauth->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_ETHERNET);
$rauth->putAttribute(RADIUS_NAS_PORT, $nas_port, 'integer');
// Extra data to identify the client and nas
$rauth->putAttribute(RADIUS_FRAMED_IP_ADDRESS, $clientip, addr);
$rauth->putAttribute(RADIUS_CALLED_STATION_ID, $calledstationid);
$rauth->putAttribute(RADIUS_CALLING_STATION_ID, $callingstationid);
// Send request
$result = $rauth->send();
// Evaluation of the response
// 1 -> Access-Request => We will use this value as an error indicator since we can't get a 1 back from the radius
// 2 -> Access-Accept
// 3 -> Access-Reject
// See RFC2865 for this.
if (PEAR::isError($result)) {
$retvalue['auth_val'] = 1;
$retvalue['error'] = $result->getMessage();
} else if ($result === true) {
$retvalue['auth_val'] = 2;
} else {
$retvalue['auth_val'] = 3;
}
// Get attributes, even if auth failed.
// We will push the results in the retvalue array
if (!$rauth->getAttributes()) {
$retvalue['error'] = $rauth->getError();
} else {
$retvalue = array_merge($retvalue,$rauth->listAttributes());
// We convert the session_terminate_time to unixtimestamp if its set before returning the whole array to our caller
if (!empty($retvalue['session_terminate_time'])) {
$stt = &$retvalue['session_terminate_time'];
$stt = strtotime(preg_replace("/\+(\d+):(\d+)$/", " +\${1}\${2}", preg_replace("/(\d+)T(\d+)/", "\${1} \${2}",$stt)));
}
}
// close OO RADIUS_AUTHENTICATION
$rauth->close();
unset($rauth);
return $retvalue;
}
?>

View File

@ -475,30 +475,12 @@ function is_webgui_cert($certref)
$config['system']['webgui']['protocol'] != 'http';
}
function is_captiveportal_cert($certref)
{
global $config;
if (!isset($config['captiveportal'])) {
return;
}
foreach ($config['captiveportal'] as $portal) {
if (isset($portal['enable']) && isset($portal['httpslogin']) && ($portal['certref'] == $certref)) {
return true;
}
}
return false;
}
function cert_in_use($certref) {
return (is_webgui_cert($certref) ||
is_user_cert($certref) ||
is_openvpn_server_cert($certref) ||
is_openvpn_client_cert($certref) ||
is_ipsec_cert($certref) ||
is_captiveportal_cert($certref));
is_ipsec_cert($certref));
}
function crl_update(& $crl) {

View File

@ -3120,10 +3120,6 @@ function interface_configure($interface = 'wan', $reloadall = false, $linkupeven
/* update dyndns */
configd_run("dyndns reload {$interface}");
/* XXX: which CPZONE? Needed? */
/* reload captive portal */
captiveportal_init_rules();
}
}
@ -5412,3 +5408,21 @@ function get_ppp_uptime($port){
return $total_time;
}
}
/**
* Get the NAS-IP-Address based on the current wan address
*
* Use functions in interfaces.inc to find this out
*
*/
function getNasIP()
{
$nasIp = get_interface_ip();
if (!is_ipaddr($nasIp)) {
$nasIp = '0.0.0.0';
}
return $nasIp;
}

View File

@ -201,21 +201,6 @@ if (!function_exists("getNasID")) {
}
}
/**
* Get the NAS-IP-Address based on the current wan address
*
* Use functions in interfaces.inc to find this out
*
*/
if (!function_exists("getNasIP")) {
function getNasIP()
{
$nasIp = get_interface_ip();
if(!$nasIp)
$nasIp = "0.0.0.0";
return $nasIp;
}
}
/* setup syslog logging */
openlog("charon", LOG_ODELAY, LOG_AUTH);

View File

@ -198,21 +198,6 @@ function getNasID()
}
}
/**
* Get the NAS-IP-Address based on the current wan address
*
* Use functions in interfaces.inc to find this out
*
*/
if (!function_exists("getNasIP")) {
function getNasIP()
{
$nasIp = get_interface_ip();
if(!$nasIp)
$nasIp = "0.0.0.0";
return $nasIp;
}
}
/* setup syslog logging */
openlog("openvpn", LOG_ODELAY, LOG_AUTH);

View File

@ -288,22 +288,15 @@ class Auth_RADIUS extends PEAR {
*/
function putStandardAttributes()
{
global $config, $cpzone;
global $config;
$ipaddr = getNasIP();
if (!function_exists("getNasIp")) {
$ipaddr = "0.0.0.0";
} else {
$ipaddr = getNasIP();
}
// Add support for sending NAS-IP-Address, set this explicitly as an ip_addr
$this->putAttribute(RADIUS_NAS_IP_ADDRESS, $ipaddr, "addr");
// Add support for sending NAS-Identifier
if (empty($config["captiveportal"][$cpzone]["radiusnasid"])) {
$nasId = php_uname("n");
} else {
$nasId = $config["captiveportal"][$cpzone]["radiusnasid"];
}
$nasId = php_uname("n");
$this->putAttribute(RADIUS_NAS_IDENTIFIER, $nasId);
}

View File

@ -97,8 +97,6 @@ function enable_rrd_graphing()
$mbuf = "-mbuf.rrd";
$cellular = "-cellular.rrd";
$vpnusers = "-vpnusers.rrd";
$captiveportalconcurrent = "-concurrent.rrd";
$captiveportalloggedin = "-loggedin.rrd";
$ntpd = "ntpd.rrd";
$rrdtool = "/usr/local/bin/rrdtool";
@ -110,7 +108,6 @@ function enable_rrd_graphing()
$php = "/usr/local/bin/php";
$cpustats = "/usr/local/sbin/cpustats";
$ifconfig = "/sbin/ifconfig";
$captiveportal_gather = "/usr/local/sbin/captiveportal_gather_stats.php";
$ntpq = "/usr/local/sbin/ntpq";
$rrdtrafficinterval = 60;
@ -123,7 +120,6 @@ function enable_rrd_graphing()
$rrdmbufinterval = 60;
$rrdcellularinterval = 60;
$rrdvpninterval = 60;
$rrdcaptiveportalinterval = 60;
$rrdntpdinterval = 60;
$trafficvalid = $rrdtrafficinterval * 2;
@ -136,7 +132,6 @@ function enable_rrd_graphing()
$mbufvalid = $rrdmbufinterval * 2;
$cellularvalid = $rrdcellularinterval * 2;
$vpnvalid = $rrdvpninterval * 2;
$captiveportalvalid = $rrdcaptiveportalinterval * 2;
$ntpdvalid = $rrdntpdinterval * 2;
/* Assume 2*10GigE for now */
@ -486,94 +481,10 @@ function enable_rrd_graphing()
$rrdupdatesh .= "MBUF=`$netstat -m | ";
$rrdupdatesh .= " $awk '/mbuf clusters in use/ { gsub(/\//, \":\", $1); print $1; }'`\n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$mbuf N:\${MBUF}\n";
/* End mbuf statistics */
/* End System statistics */
/* Captive Portal statistics, set up the rrd file */
if(is_array($config['captiveportal'])) {
foreach ($config['captiveportal'] as $cpkey => $cp) {
if (!isset($cp['enable']))
continue;
$ifname= "captiveportal";
$concurrent_filename = $rrddbpath . $ifname . '-' . $cpkey . $captiveportalconcurrent;
if (!file_exists("$concurrent_filename")) {
$rrdcreate = "$rrdtool create $concurrent_filename --step $rrdcaptiveportalinterval ";
$rrdcreate .= "DS:concurrentusers:GAUGE:$captiveportalvalid:0:10000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
$rrdcreate .= "RRA:MIN:0.5:5:720 ";
$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
$rrdcreate .= "RRA:MAX:0.5:5:720 ";
$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
$rrdcreate .= "RRA:MAX:0.5:1440:2284 ";
$rrdcreate .= "RRA:LAST:0.5:1:1200 ";
$rrdcreate .= "RRA:LAST:0.5:5:720 ";
$rrdcreate .= "RRA:LAST:0.5:60:1860 ";
$rrdcreate .= "RRA:LAST:0.5:1440:2284 ";
create_new_rrd($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if(file_exists("/var/run/booting")) {
mwexec("$rrdtool update $concurrent_filename N:U");
}
/* the Captive Portal stats gathering function. */
$rrdupdatesh .= "\n";
$rrdupdatesh .= "# polling Captive Portal for number of concurrent users\n";
$rrdupdatesh .= "CP=`${php} -q ${captiveportal_gather} '${cpkey}' 'concurrent'`\n";
$rrdupdatesh .= "$rrdtool update $concurrent_filename \${CP}\n";
$loggedin_filename = $rrddbpath . $ifname . '-' . $cpkey . $captiveportalloggedin;
if (!file_exists("$loggedin_filename")) {
$rrdcreate = "$rrdtool create $loggedin_filename --step $rrdcaptiveportalinterval ";
$rrdcreate .= "DS:loggedinusers:GAUGE:$captiveportalvalid:0:10000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
$rrdcreate .= "RRA:MIN:0.5:5:720 ";
$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
$rrdcreate .= "RRA:MAX:0.5:5:720 ";
$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
$rrdcreate .= "RRA:MAX:0.5:1440:2284 ";
$rrdcreate .= "RRA:LAST:0.5:1:1200 ";
$rrdcreate .= "RRA:LAST:0.5:5:720 ";
$rrdcreate .= "RRA:LAST:0.5:60:1860 ";
$rrdcreate .= "RRA:LAST:0.5:1440:2284 ";
create_new_rrd($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if(file_exists("/var/run/booting")) {
mwexec("$rrdtool update $loggedin_filename N:U");
}
/* the Captive Portal stats gathering function. */
$rrdupdatesh .= "\n";
$rrdupdatesh .= "# polling Captive Portal for number of logged in users\n";
$rrdupdatesh .= "CP=`${php} -q ${captiveportal_gather} '${cpkey}' 'loggedin'`\n";
$rrdupdatesh .= "$rrdtool update $loggedin_filename \${CP}\n";
}
}
/* End Captive Portal statistics */
/* NTP, set up the ntpd rrd file */
if (isset($config['ntpd']['statsgraph'])) {
/* set up the ntpd rrd file */

View File

@ -1025,32 +1025,13 @@ function system_generate_lighty_config(
$port = 80,
$document_root = '/usr/local/www/',
$cert_location = 'cert.pem',
$ca_location = 'ca.pem',
$captive_portal = false)
$ca_location = 'ca.pem')
{
global $config;
@mkdir('/tmp/lighttpdcompress');
if ($captive_portal !== false) {
$captiveportal = ',"mod_evasive"';
$http_rewrite_rules = "url.rewrite-once = ( \"(.*captiveportal.*)\" => \"$1\", \"(.*)\" => \"/index.php?zone={$captive_portal}&redirurl=$1\" )\n";
if (!isset($config['captiveportal'][$captive_portal]['maxprocperip']) || empty($config['captiveportal'][$captive_portal]['maxprocperip'])) {
$maxprocperip = 10;
} else {
$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
}
$captive_portal_mod_evasive = "evasive.max-conns-per-ip = {$maxprocperip}";
$server_upload_dirs = "server.upload-dirs = ( \"/tmp/captiveportal/\" )\n";
@mkdir('/tmp/captiveportal', 0555);
$server_max_request_size = "server.max-request-size = 384";
$cgi_config = "";
} else {
$captiveportal = ",\"mod_cgi\"";
$http_rewrite_rules = <<<EOD
$http_rewrite_rules = <<<EOD
# Phalcon ui and api routing
alias.url += ( "/ui/" => "/usr/local/opnsense/www/" )
alias.url += ( "/api/" => "/usr/local/opnsense/www/" )
@ -1059,11 +1040,9 @@ url.rewrite-if-not-file = ( "^/ui/(.*)$" => "/ui/index.php?_url=/$1" ,
)
EOD;
$captive_portal_mod_evasive = "";
$server_upload_dirs = "server.upload-dirs = ( \"/root/\", \"/tmp/\", \"/var/\" )\n";
$server_max_request_size = "server.max-request-size = 2097152";
$cgi_config = "cgi.assign = ( \".cgi\" => \"\" )";
}
$server_upload_dirs = "server.upload-dirs = ( \"/root/\", \"/tmp/\", \"/var/\" )\n";
$server_max_request_size = "server.max-request-size = 2097152";
$cgi_config = "cgi.assign = ( \".cgi\" => \"\" )";
if (empty($port))
$lighty_port = "80";
@ -1079,26 +1058,10 @@ EOD;
else
$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM
if ($captive_portal !== false) {
if ($realmem > 135 and $realmem < 256) {
$max_procs += 1; // 2 worker processes
} else if ($realmem > 255 and $realmem < 513) {
$max_procs += 2; // 3 worker processes
} else if ($realmem > 512) {
$max_procs += 4; // 6 worker processes
}
if ($max_procs > 1)
$max_php_children = intval($max_procs/2);
else
$max_php_children = 1;
} else {
if ($realmem < 78)
$max_php_children = 0;
else
$max_php_children = 1;
}
if ($realmem < 78)
$max_php_children = 0;
else
$max_php_children = 1;
if(!isset($config['syslog']['nologlighttpd'])) {
$lighty_use_syslog = <<<EOD
@ -1107,11 +1070,7 @@ server.errorlog-use-syslog="enable"
EOD;
}
if ($captive_portal !== false) {
$fast_cgi_path = "/tmp/php-fastcgi-{$captive_portal}.socket";
} else {
$fast_cgi_path = "/tmp/php-fastcgi.socket";
}
$fast_cgi_path = "/tmp/php-fastcgi.socket";
$fastcgi_config = <<<EOD
#### fastcgi module
@ -1147,7 +1106,7 @@ server.network-backend = "writev"
## modules to load
server.modules = ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
{$captiveportal}, "mod_fastcgi","mod_alias", "mod_rewrite"
"mod_cgi", "mod_fastcgi","mod_alias", "mod_rewrite"
)
server.max-keep-alive-requests = 15
@ -1285,8 +1244,6 @@ compress.filetype = ("text/plain","text/css", "text/xml", "text/javascript" )
{$cgi_config}
{$captive_portal_mod_evasive}
expire.url = (
"" => "access 50 hours",
)
@ -1337,7 +1294,7 @@ EOD;
}
// Add HTTP to HTTPS redirect
if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
if ($config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
if($lighty_port != "443") {
$redirectport = ":{$lighty_port}";
} else {

View File

@ -1059,36 +1059,11 @@ function ip_in_subnet($addr,$subnet) {
}
}
function mac_format($clientmac) {
global $config, $cpzone;
$mac = explode(":", $clientmac);
$mac_format = $cpzone ? $config['captiveportal'][$cpzone]['radmac_format'] : false;
switch($mac_format) {
case 'singledash':
return "$mac[0]$mac[1]$mac[2]-$mac[3]$mac[4]$mac[5]";
case 'ietf':
return "$mac[0]-$mac[1]-$mac[2]-$mac[3]-$mac[4]-$mac[5]";
case 'cisco':
return "$mac[0]$mac[1].$mac[2]$mac[3].$mac[4]$mac[5]";
case 'unformatted':
return "$mac[0]$mac[1]$mac[2]$mac[3]$mac[4]$mac[5]";
default:
return $clientmac;
}
}
function resolve_retry($hostname, $retries = 5) {
if (is_ipaddr($hostname))
function resolve_retry($hostname, $retries = 5)
{
if (is_ipaddr($hostname)) {
return $hostname;
}
for ($i = 0; $i < $retries; $i++) {
// FIXME: gethostbyname does not work for AAAA hostnames, boo, hiss

View File

@ -1,521 +0,0 @@
<?php
/*
Copyright (C) 2010-2012 Ermal Luci <eri@pfsense.org>
Copyright (C) 2010 Scott Ullrich <sullrich@gmail.com>
Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
function voucher_expire($voucher_received) {
global $g, $config, $cpzone;
$cpdb = new OPNsense\CaptivePortal\DB($cpzone);
$cpc = new OPNsense\CaptivePortal\CPClient();
// read rolls into assoc array with rollid as key and minutes as value
$tickets_per_roll = array();
$minutes_per_roll = array();
if (is_array($config['voucher'][$cpzone]['roll'])) {
foreach ($config['voucher'][$cpzone]['roll'] as $rollent) {
$tickets_per_roll[$rollent['number']] = $rollent['count'];
$minutes_per_roll[$rollent['number']] = $rollent['minutes'];
}
}
// split into an array. Useful for multiple vouchers given
$a_vouchers_received = preg_split("/[\t\n\r ]+/s", $voucher_received);
$active_dirty = false;
// go through all received vouchers, check their valid and extract
// Roll# and Ticket# using the external readvoucher binary
foreach ($a_vouchers_received as $voucher) {
$v = escapeshellarg($voucher);
if (strlen($voucher) < 3)
continue; // seems too short to be a voucher!
unset($output);
$_gb = exec("/usr/local/bin/voucher -c /var/etc/voucher_{$cpzone}.cfg -k /var/etc/voucher_{$cpzone}.public -- $v", $output);
list($status, $roll, $nr) = explode(" ", $output[0]);
if ($status == "OK") {
// check if we have this ticket on a registered roll for this ticket
if ($tickets_per_roll[$roll] && ($nr <= $tickets_per_roll[$roll])) {
// voucher is from a registered roll.
if (!isset($active_vouchers[$roll]))
$active_vouchers[$roll] = voucher_read_active_db($roll);
// valid voucher. Store roll# and ticket#
if (!empty($active_vouchers[$roll][$voucher])) {
$active_dirty = true;
unset($active_vouchers[$roll][$voucher]);
}
// check if voucher already marked as used
if (!isset($bitstring[$roll]))
$bitstring[$roll] = voucher_read_used_db($roll);
$pos = $nr >> 3; // divide by 8 -> octet
$mask = 1 << ($nr % 8);
// mark bit for this voucher as used
if (!(ord($bitstring[$roll][$pos]) & $mask))
$bitstring[$roll][$pos] = chr(ord($bitstring[$roll][$pos]) | $mask);
captiveportal_syslog("{$voucher} ({$roll}/{$nr}) forced to expire");
/* Check if this voucher has any active sessions */
$clients = $cpdb->listClients(array("username"=>$voucher),null, null);
foreach($clients as $client ){
$cpc->disconnect($cpzone,$client->sessionid);
}
} else
captiveportal_syslog("$voucher ($roll/$nr): not found on any registererd Roll");
} else
// hmm, thats weird ... not what I expected
captiveportal_syslog("$voucher invalid: {$output[0]}!!");
}
// Refresh active DBs
if ($active_dirty == true) {
foreach ($active_vouchers as $roll => $active) {
voucher_write_active_db($roll, $active);
}
unset($active_vouchers);
/* trigger a sync of the vouchers on config */
voucher_save_db_to_config();
}
// Write back the used DB's
if (is_array($bitstring)) {
foreach ($bitstring as $roll => $used) {
if(is_array($used)) {
foreach($used as $u)
voucher_write_used_db($roll, base64_encode($u));
} else {
voucher_write_used_db($roll, base64_encode($used));
}
}
unset($bitstring);
}
unset($cpdb);
unset($cpc);
return true;
}
/*
* Authenticate a voucher and return the remaining time credit in minutes
* if $test is set, don't mark the voucher as used nor add it to the list
* of active vouchers
* If $test is set, simply test the voucher. Don't change anything
* but return a more verbose error and result message back
*/
function voucher_auth($voucher_received, $test = 0) {
global $g, $config, $cpzone, $dbc;
if (!isset($config['voucher'][$cpzone]['enable']))
return 0;
// read rolls into assoc array with rollid as key and minutes as value
$tickets_per_roll = array();
$minutes_per_roll = array();
if (is_array($config['voucher'][$cpzone]['roll'])) {
foreach ($config['voucher'][$cpzone]['roll'] as $rollent) {
$tickets_per_roll[$rollent['number']] = $rollent['count'];
$minutes_per_roll[$rollent['number']] = $rollent['minutes'];
}
}
// split into an array. Useful for multiple vouchers given
$a_vouchers_received = preg_split("/[\t\n\r ]+/s", $voucher_received);
$error = 0;
$test_result = array(); // used to display for voucher test option in GUI
$total_minutes = 0;
$first_voucher = "";
$first_voucher_roll = 0;
// go through all received vouchers, check their valid and extract
// Roll# and Ticket# using the external readvoucher binary
foreach ($a_vouchers_received as $voucher) {
$v = escapeshellarg($voucher);
if (strlen($voucher) < 3)
continue; // seems too short to be a voucher!
$result = exec("/usr/local/bin/voucher -c /var/etc/voucher_{$cpzone}.cfg -k /var/etc/voucher_{$cpzone}.public -- $v");
list($status, $roll, $nr) = explode(" ", $result);
if ($status == "OK") {
if (!$first_voucher) {
// store first voucher. Thats the one we give the timecredit
$first_voucher = $voucher;
$first_voucher_roll = $roll;
}
// check if we have this ticket on a registered roll for this ticket
if ($tickets_per_roll[$roll] && ($nr <= $tickets_per_roll[$roll])) {
// voucher is from a registered roll.
if (!isset($active_vouchers[$roll]))
$active_vouchers[$roll] = voucher_read_active_db($roll);
// valid voucher. Store roll# and ticket#
if (!empty($active_vouchers[$roll][$voucher])) {
list($timestamp,$minutes) = explode(",", $active_vouchers[$roll][$voucher]);
// we have an already active voucher here.
$remaining = intval((($timestamp + (60*$minutes)) - time())/60);
$test_result[] = sprintf(gettext('%1$s (%2$s/%3$s) active and good for %4$d Minutes'), $voucher, $roll, $nr, $remaining);
$total_minutes += $remaining;
} else {
// voucher not used. Check if ticket Id is on the roll (not too high)
// and if the ticket is marked used.
// check if voucher already marked as used
if (!isset($bitstring[$roll]))
$bitstring[$roll] = voucher_read_used_db($roll);
$pos = $nr >> 3; // divide by 8 -> octet
$mask = 1 << ($nr % 8);
if (ord($bitstring[$roll][$pos]) & $mask) {
$test_result[] = "$voucher ($roll/$nr) already used and expired";
captiveportal_syslog("$voucher ($roll/$nr) already used and expired");
$total_minutes = -1; // voucher expired
$error++;
} else {
// mark bit for this voucher as used
$bitstring[$roll][$pos] = chr(ord($bitstring[$roll][$pos]) | $mask);
$test_result[] = "$voucher ($roll/$nr) good for {$minutes_per_roll[$roll]} Minutes";
$total_minutes += $minutes_per_roll[$roll];
}
}
} else {
$test_result[] = "$voucher ($roll/$nr): not found on any registererd Roll";
captiveportal_syslog("$voucher ($roll/$nr): not found on any registererd Roll");
}
} else {
// hmm, thats weird ... not what I expected
$test_result[] = "$voucher invalid: $result !!";
captiveportal_syslog("$voucher invalid: $result !!");
$error++;
}
}
// if this was a test call, we're done. Return the result.
if ($test) {
if ($error) {
$test_result[] = gettext("Access denied!");
} else {
$test_result[] = sprintf(gettext("Access granted for %d Minutes in total."),$total_minutes);
}
return $test_result;
}
// if we had an error (one of the vouchers is invalid), return 0.
// Discussion: we could return the time remaining for good vouchers, but then
// the user wouldn't know that he used at least one invalid voucher.
if ($error) {
if ($total_minutes > 0) // probably not needed, but want to make sure
$total_minutes = 0; // we only report -1 (expired) or 0 (no access)
return $total_minutes; // well, at least one voucher had errors. Say NO ACCESS
}
// All given vouchers were valid and this isn't simply a test.
// Write back the used DB's
if (is_array($bitstring)) {
foreach ($bitstring as $roll => $used) {
if(is_array($used)) {
foreach($used as $u)
voucher_write_used_db($roll, base64_encode($u));
} else {
voucher_write_used_db($roll, base64_encode($used));
}
}
}
// Active DB: we only add the first voucher if multiple given
// and give that one all the time credit. This allows the user to logout and
// log in later using just the first voucher. It also keeps username limited
// to one voucher and that voucher shows the correct time credit in 'active vouchers'
if (!empty($active_vouchers[$first_voucher_roll][$first_voucher])) {
list($timestamp, $minutes) = explode(",", $active_vouchers[$first_voucher_roll][$first_voucher]);
} else {
$timestamp = time(); // new voucher
$minutes = $total_minutes;
}
$active_vouchers[$first_voucher_roll][$first_voucher] = "$timestamp,$minutes";
voucher_write_active_db($first_voucher_roll, $active_vouchers[$first_voucher_roll]);
/* trigger a sync of the vouchers on config */
voucher_save_db_to_config();
return $total_minutes;
}
function voucher_configure($sync = false)
{
global $config, $cpzone;
$ret = true;
if (!isset($config['voucher']) || !is_array($config['voucher'])) {
return $ret;
}
foreach ($config['voucher'] as $voucherzone => $vcfg) {
$cpzone = $voucherzone;
$error = voucher_configure_zone($sync);
if ($error) {
$ret = false;
}
}
return $ret;
}
function voucher_configure_zone($sync = false)
{
global $config, $g, $cpzone;
if (!isset($config['voucher'][$cpzone]['enable'])) {
return 0;
}
$voucherlck = lock("voucher{$cpzone}", LOCK_EX);
/* write public key used to verify vouchers */
$pubkey = base64_decode($config['voucher'][$cpzone]['publickey']);
$fd = fopen("/var/etc/voucher_{$cpzone}.public", "w");
if (!$fd) {
captiveportal_syslog("Voucher error: cannot write voucher.public\n");
unlock($voucherlck);
return 1;
}
fwrite($fd, $pubkey);
fclose($fd);
@chmod("/var/etc/voucher_{$cpzone}.public", 0600);
/* write config file used by voucher binary to decode vouchers */
$fd = fopen("/var/etc/voucher_{$cpzone}.cfg", "w");
if (!$fd) {
captiveportal_syslog(gettext("Error: cannot write voucher.cfg") . "\n");
unlock($voucherlck);
return 1;
}
fwrite($fd, "{$config['voucher'][$cpzone]['rollbits']},{$config['voucher'][$cpzone]['ticketbits']},{$config['voucher'][$cpzone]['checksumbits']},{$config['voucher'][$cpzone]['magic']},{$config['voucher'][$cpzone]['charset']}\n");
fclose($fd);
@chmod("/var/etc/voucher_{$cpzone}.cfg", 0600);
unlock($voucherlck);
if (!$sync) {
return 0;
}
captiveportal_syslog('Writing voucher db from sync data...');
if (isset($config['voucher'][$cpzone]['roll'])) {
$voucherlck = lock("voucher{$cpzone}", LOCK_EX);
// create active and used DB per roll on ramdisk from config
foreach ($config['voucher'][$cpzone]['roll'] as $rollent) {
$roll = $rollent['number'];
voucher_write_used_db($roll, $rollent['used']);
$minutes = $rollent['minutes'];
$active_vouchers = array();
$a_active = &$rollent['active'];
if (is_array($a_active)) {
foreach ($a_active as $activent) {
$voucher = $activent['voucher'];
$timestamp = $activent['timestamp'];
$minutes = $activent['minutes'];
// its tempting to check for expired timestamps, but during
// bootup, we most likely don't have the correct time time.
$active_vouchers[$voucher] = "$timestamp,$minutes";
}
}
voucher_write_active_db($roll, $active_vouchers);
}
unlock($voucherlck);
}
return 0;
}
/* write bitstring of used vouchers to ramdisk.
* Bitstring must already be base64_encoded!
*/
function voucher_write_used_db($roll, $vdb)
{
global $cpzone;
$fn = "/var/db/voucher_{$cpzone}_used_{$roll}.db";
$fd = fopen($fn, 'w');
if ($fd) {
fwrite($fd, $vdb . "\n");
fclose($fd);
} else {
voucher_log(LOG_ERR, sprintf(gettext('Can\'t write %s'), $fn));
}
}
/* return assoc array of active vouchers with activation timestamp
* voucher is index.
*/
function voucher_read_active_db($roll) {
global $g, $cpzone;
$active = array();
$dirty = 0;
$file = "/var/db/voucher_{$cpzone}_active_{$roll}.db";
if (file_exists($file)) {
$fd = fopen($file, "r");
if ($fd) {
while (!feof($fd)) {
$line = trim(fgets($fd));
if ($line) {
list($voucher,$timestamp,$minutes) = explode(",", $line); // voucher,timestamp
if ((($timestamp + (60*$minutes)) - time()) > 0)
$active[$voucher] = "$timestamp,$minutes";
else
$dirty=1;
}
}
fclose($fd);
if ($dirty) {
/* if we found expired entries, lets save our snapshot */
voucher_write_active_db($roll, $active);
/* trigger a sync of the vouchers on config */
voucher_save_db_to_config();
}
}
}
return $active;
}
/* store array of active vouchers back to DB */
function voucher_write_active_db($roll, $active) {
global $g, $cpzone;
if (!is_array($active))
return;
$fd = fopen("/var/db/voucher_{$cpzone}_active_{$roll}.db", "w");
if ($fd) {
foreach($active as $voucher => $value)
fwrite($fd, "$voucher,$value\n");
fclose($fd);
}
}
function voucher_read_used_db($roll)
{
global $cpzone;
$fn = "/var/db/voucher_{$cpzone}_used_{$roll}.db";
$vdb = '';
$fd = fopen($fn, 'r');
if ($fd) {
$vdb = trim(fgets($fd));
fclose($fd);
} else {
voucher_log(LOG_ERR, sprintf(gettext('Can\'t read %s'), $fn));
}
return base64_decode($vdb);
}
/* we share the log with captiveportal for now */
function voucher_log($priority, $message)
{
$message = trim($message);
openlog("logportalauth", LOG_PID, LOG_LOCAL4);
syslog($priority, sprintf(gettext("Voucher: %s"),$message));
closelog();
}
/*
* Save active and used voucher DB into XML config and write it to config
* Called during reboot and every active voucher change
*/
function voucher_save_db_to_config()
{
global $config, $cpzone;
if (!isset($config['voucher'])) {
return;
}
$needs_write = 0;
foreach ($config['voucher'] as $voucherzone => $vcfg) {
$cpzone = $voucherzone;
$needs_write += voucher_save_db_to_config_zone();
}
if ($needs_write) {
write_config("Backing up vouchers");
}
}
function voucher_save_db_to_config_zone()
{
global $config, $cpzone;
if (!isset($config['voucher'][$cpzone]['enable'])) {
// no vouchers or don't want to save DB's
return 0;
}
if (!isset($config['voucher'][$cpzone]['roll'])) {
return 0;
}
$voucherlck = lock("voucher{$cpzone}", LOCK_EX);
// walk all active rolls and save runtime DBs
$a_roll = &$config['voucher'][$cpzone]['roll'];
while (list($key, $value) = each($a_roll)) {
$rollent = &$a_roll[$key];
$roll = $rollent['number'];
$bitmask = voucher_read_used_db($roll);
$rollent['used'] = base64_encode($bitmask);
$active_vouchers = voucher_read_active_db($roll);
$db = array();
$dbi = 1;
foreach($active_vouchers as $voucher => $line) {
list($timestamp, $minutes) = explode(',', $line);
$activent['voucher'] = $voucher;
$activent['timestamp'] = $timestamp;
$activent['minutes'] = $minutes;
$db["v{$dbi}"] = $activent;
$dbi++;
}
$rollent['active'] = $db;
unset($active_vouchers);
}
unlock($voucherlck);
return 1;
}

View File

@ -1,45 +0,0 @@
#!/usr/local/bin/php
<?php
/*
Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("config.inc");
require_once("interfaces.inc");
require_once("util.inc");
require_once("filter.inc");
require_once("captiveportal.inc");
global $config, $cpzone;
if (isset($config['captiveportal'])) {
foreach ($config['captiveportal'] as $cpzone => $cp) {
captiveportal_radius_stop_all();
captiveportal_send_server_accounting(true);
}
}
voucher_save_db_to_config();

View File

@ -137,8 +137,6 @@ require_once("vpn.inc");
echo ".";
require_once("openvpn.inc");
echo ".";
require_once("captiveportal.inc");
echo ".";
require_once("rrd.inc");
echo ".";
echo " done.\n";
@ -306,12 +304,6 @@ filter_configure_sync();
/* setup pppoe and pptp */
vpn_setup();
/* start the captive portal */
captiveportal_configure();
/* start Voucher support */
echo 'Enabling voucher support...' . (voucher_configure(true) ? 'done.' : 'failed.') . PHP_EOL;
/* start IPsec tunnels */
$ipsec_dynamic_hosts = vpn_ipsec_configure();

View File

@ -355,10 +355,6 @@ if (is_array($config['hasync'])) {
$config['schedules'] = array();
$sections[] = 'schedules';
}
if (isset($hasync['synchronizecaptiveportal']) && isset($config['captiveportal']) && is_array($config['captiveportal']))
$sections[] = 'captiveportal';
if (isset($hasync['synchronizecaptiveportal']) && isset($config['vouchers']) && is_array($config['vouchers']))
$sections[] = 'vouchers';
if (count($sections) <= 0) {
log_error("Nothing has been configured to be synched. Skipping....");

View File

@ -33,7 +33,6 @@ require_once("config.console.inc");
require_once("filter.inc");
require_once("util.inc");
require_once("vpn.inc");
require_once("captiveportal.inc");
require_once("rrd.inc");
require_once("system.inc");
require_once("services.inc");

View File

@ -85,7 +85,6 @@ function handle_argument_group($iface, $argument2) {
log_error("DEVD Ethernet attached event for {$iface}");
log_error("HOTPLUG: Configuring interface {$iface}");
require_once("vpn.inc");
require_once("captiveportal.inc");
// Do not try to readd to bridge otherwise em(4) has problems
interface_configure($iface, true, true);
break;

View File

@ -1,63 +0,0 @@
#!/usr/local/bin/php
<?php
/*
Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("config.inc");
require_once("interfaces.inc");
require_once("filter.inc");
require_once("captiveportal.inc");
require_once("util.inc");
global $g;
global $cpzone;
global $cpzoneid;
$cpzone = str_replace("\n", "", $argv[1]);
if (!is_array($config['captiveportal'][$cpzone])) {
log_error("{$cpzone} is not a valid zone in the configuration!");
return;
}
$cpzoneid = $config['captiveportal'][$cpzone]['zoneid'];
if (file_exists('/tmp/.rc.prunecaptiveportal.running')) {
$stat = stat('/tmp/.rc.prunecaptiveportal.running');
if (time() - $stat['mtime'] >= 120) {
@unlink('/tmp/.rc.prunecaptiveportal.running');
} else {
log_error("Skipping CP prunning process because previous/another instance is already running");
return;
}
}
@file_put_contents('/tmp/.rc.prunecaptiveportal.running', '');
captiveportal_prune_old();
@unlink('/tmp/.rc.prunecaptiveportal.running');

View File

@ -32,7 +32,6 @@ require_once("interfaces.inc");
require_once("openvpn.inc");
require_once("filter.inc");
require_once("vpn.inc");
require_once("captiveportal.inc");
require_once("util.inc");
require_once("system.inc");
require_once("pfsense-utils.inc");

View File

@ -32,7 +32,6 @@ require_once("filter.inc");
require_once("util.inc");
require_once("openvpn.inc");
require_once("vpn.inc");
require_once("captiveportal.inc");
require_once("system.inc");
require_once("interfaces.inc");
require_once("openvpn.inc");
@ -43,5 +42,3 @@ require_once("unbound.inc");
system_routing_enable();
interfaces_configure();
filter_configure_sync();
/* XXX: needs fixing */
//ovpn_config_server("pfreload");

View File

@ -3,7 +3,6 @@
require_once('config.inc');
require_once('interfaces.inc');
require_once('captiveportal.inc');
require_once('rrd.inc');
require_once('util.inc');
require_once('system.inc');
@ -31,7 +30,6 @@ while (is_process_running('lighttpd')) {
}
system_webgui_start();
captiveportal_init_webgui();
enable_rrd_graphing();
echo 'done.' . PHP_EOL;

View File

@ -168,15 +168,7 @@
</Diagnostics>
</Firewall>
<Services order="4" cssClass="glyphicon glyphicon-cog">
<CaptivePortal VisibleName="Captive Portal" url="/services_captiveportal_zones.php">
<Edit url="/services_captiveportal.php?zone=*"/>
<IP url="/services_captiveportal_ip.php?zone=*"/>
<IP_edit url="/services_captiveportal_ip_edit.php?zone=*"/>
<MAC url="/services_captiveportal_mac.php?zone=*"/>
<MAC_edit url="/services_captiveportal_mac_edit.php?zone=*"/>
<Voucher url="/services_captiveportal_vouchers.php?zone=*"/>
<FileManager url="/services_captiveportal_filemanager.php?zone=*"/>
</CaptivePortal>
<CaptivePortal VisibleName="Captive Portal" url="/ui/captiveportal/" cssClass="fa fa-paper-plane-o"/>
<DHCPRelay VisibleName="DHCP Relay" url="/services_dhcp_relay.php"/>
<DHCPServer VisibleName="DHCP Server" url="/services_dhcp.php">
<DHCPServerTab url="/services_dhcp.php?if=*"/>
@ -279,9 +271,6 @@
</PPTP>
</VPN>
<Status order="6" cssClass="glyphicon glyphicon-tasks">
<CaptivePortal VisibleName="Captive Portal" url="/status_captiveportal.php">
<CaptivePortalDetails url="/status_captiveportal.php?*"/>
</CaptivePortal>
<DHCPLeases VisibleName="DHCP IPv4 Leases" url="/status_dhcp_leases.php">
<DHCPLeasesDetails url="/status_dhcp_leases.php?*"/>
</DHCPLeases>

View File

@ -1,824 +0,0 @@
<?php
/**
* Copyright (C) 2015 Deciso B.V.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
namespace OPNsense\CaptivePortal;
use \Phalcon\Logger\Adapter\Syslog;
use \Phalcon\DI\FactoryDefault;
use \OPNsense\Core;
use \OPNsense\Core\Backend;
/**
* Class CPClient main class for captive portal backend functionality
* // TODO: CARP interfaces are probably not handled correctly
* @package CaptivePortal
*/
class CPClient
{
/**
* config handle
* @var Core_Config
*/
private $config = null;
/**
* link to shell object
* @var Core\Shell
*/
private $shell = null;
/**
* get ipfw tables for authenticated users ( in/out )
* @param int $zoneid zoneid (number)
* @return array
*/
public function getAuthUsersTables($zoneid)
{
return array("in"=>(6*($zoneid-1) )+1,"out"=>(6*($zoneid-1) )+2);
}
/**
* get ipfw tables for authenticated hosts ( in/out )
* @param int $zoneid zoneid (number)
* @return array
*/
public function getAuthIPTables($zoneid)
{
return array("in"=>(6*($zoneid-1) )+3,"out"=>(6*($zoneid-1) )+4);
}
/**
* get ipfw tables used for authenticated physical addresses
* @param int $zoneid zoneid (number)
* @return array
*/
public function getAuthMACTables($zoneid)
{
return array("in"=>(6*($zoneid-1) )+5,"out"=>(6*($zoneid-1) )+6);
}
/**
* Constructor
*/
public function __construct()
{
// Request handle to configuration
$this->config = Core\Config::getInstance();
// keep a link to the shell object
$this->shell = new Core\Shell();
}
/**
* reset traffic counters
*
* @param string|null $rulenum
*/
public function zeroCounters($rulenum = null)
{
if ($rulenum != null and is_numeric($rulenum)) {
$this->shell->exec("/sbin/ipfw zero " . $rulenum);
} elseif ($rulenum == null) {
$this->shell->exec("/sbin/ipfw zero ");
}
}
/**
* Reconfigure zones ( generate and load ruleset )
*/
public function reconfigure()
{
$backend = new Backend();
if ($this->isEnabled()) {
$response = $backend->configdRun("template reload OPNsense.IPFW");
if (trim($response) == "OK") {
// load ruleset when ruleset is successfully loaded
$this->shell->exec("/etc/rc.d/ipfw start");
}
// update tables
$this->update();
// after reinit all accounting rules are vanished, reapply them for active sessions
$this->loadAccounting();
} else {
// captiveportal is disabled, create new config and reload ipfw
$response = $backend->configdRun("template reload OPNsense.IPFW");
$this->shell->exec("/etc/rc.d/ipfw start");
}
}
/**
* check if captiveportal is enabled (traverse zones, if none active return false )
* @return bool
*/
public function isEnabled()
{
$enabled_zones = 0 ;
$conf = $this->config->object();
if (isset($conf->captiveportal)) {
foreach ($conf->captiveportal->children() as $cpzonename => $zone) {
if (isset($zone->enable)) {
$enabled_zones++;
}
}
}
if ($enabled_zones > 0) {
return true;
} else {
return false ;
}
}
/**
* update zone(s) with new configuration data
* @param string|null $zone
*/
public function update($zone = null)
{
$this->refreshAllowedIPs($zone);
$this->refreshAllowedMACs($zone);
}
/**
* refresh allowed ip's for defined zone ( null for all zones )
* @param string|null $cpzone
*/
public function refreshAllowedIPs($cpzone = null)
{
$handled_addresses = array();
foreach ($this->config->object()->captiveportal->children() as $cpzonename => $zone) {
// search requested zone (id)
if ($cpzonename == $cpzone || $zone->zoneid == $cpzone || $cpzone == null) {
$db = new DB($cpzonename);
$db_iplist = $db->listFixedIPs();
// calculate table numbers for this zone
$ipfw_tables = $this->getAuthIPTables($zone->zoneid);
foreach ($zone->children() as $tagname => $tagcontent) {
$ip = $tagcontent->ip->__toString();
if ($tagname == 'allowedip') {
$handled_addresses[$ip] = array();
$handled_addresses[$ip]["bw_up"] = $tagcontent->bw_up->__toString() ;
$handled_addresses[$ip]["bw_down"] = $tagcontent->bw_down->__toString() ;
if (!array_key_exists($ip, $db_iplist)) {
// only insert new values
$pipeno_in = $this->newIPFWpipeno() ;
$pipeno_out = $this->newIPFWpipeno() ;
$exec_commands = array(
# insert new ip address
"/sbin/ipfw table ". $ipfw_tables["in"] ." add " .
$ip . "/" . $tagcontent->sn->__toString() . " " . $pipeno_in,
"/sbin/ipfw table ". $ipfw_tables["out"] ." add " .
$ip . "/" . $tagcontent->sn->__toString() . " " . $pipeno_out,
);
// execute all ipfw actions
$this->shell->exec($exec_commands);
// update administration
$db->upsertFixedIP($ip, $pipeno_in, $pipeno_out);
// save bandwidth data
$handled_addresses[$ip]["pipeno_in"] = $pipeno_in ;
$handled_addresses[$ip]["pipeno_out"] = $pipeno_out ;
} else {
//
$handled_addresses[$ip]["pipeno_in"] = $db_iplist[$ip]->pipeno_in ;
$handled_addresses[$ip]["pipeno_out"] = $db_iplist[$ip]->pipeno_out ;
}
}
}
// Cleanup deleted addresses
foreach ($db_iplist as $ip => $record) {
if (!array_key_exists($ip, $handled_addresses)) {
$exec_commands = array(
# insert new ip address
"/sbin/ipfw table ". $ipfw_tables["in"] .
" del " . $ip . "/" . $tagcontent->sn->__toString() ,
"/sbin/ipfw table ". $ipfw_tables["out"] .
" del " . $ip . "/" . $tagcontent->sn->__toString() ,
);
// execute all ipfw actions
$this->shell->exec($exec_commands);
// TODO : cleanup $record->pipeno_in, $record->pipeno_out ;
$db->dropFixedIP($ip);
}
}
// reset bandwidth,
foreach ($handled_addresses as $mac => $record) {
if (array_key_exists("pipeno_in", $record)) {
$this->resetBandwidth($record["pipeno_in"], $record["bw_down"]);
$this->resetBandwidth($record["pipeno_out"], $record["bw_up"]);
}
}
unset($db);
}
}
}
/**
* Request new pipeno
* @return int
*/
private function newIPFWpipeno()
{
// TODO: implement global pipe number assigment
return 999;
}
/**
* reset bandwidth, if the current bandwidth is unchanged, do nothing
* @param int $pipeno system pipeno
* @param int $bw bandwidth in Kbit/s
* @return status
*/
private function resetBandwidth($pipeno, $bw)
{
//TODO : setup bandwidth for sessions ( check changed )
//#pipe 2000 config bw 2000Kbit/s
return false;
}
/**
* To be able to grant access to physical pc's, we need to do some administration.
* Our captive portal database keeps a list of every used address and last know mac address
*
* @param string|null $cpzone zone name or number
*/
public function refreshAllowedMACs($cpzone = null)
{
// read ARP table
$arp= new ARP();
$arp_maclist = $arp->getMACs();
// keep a list of handled addresses, so we can cleanup the rest and keep track of needed bandwidth restrictions
$handled_mac_addresses = array();
foreach ($this->config->object()->captiveportal->children() as $cpzonename => $zone) {
if ($cpzonename == $cpzone || $zone->zoneid == $cpzone || $cpzone == null) {
// open administrative database for this zone
$db = new DB($cpzonename);
$db_maclist = $db->listPassthruMacs();
$ipfw_tables = $this->getAuthMACTables($zone->zoneid);
foreach ($zone->children() as $tagname => $tagcontent) {
$mac = trim(strtolower($tagcontent->mac));
if ($tagname == 'passthrumac') {
// only accept valid macaddresses
if (preg_match('/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', $mac)) {
if ($tagcontent->action == "pass") {
$handled_mac_addresses[$mac] = array("action"=>"skipped" );
$handled_mac_addresses[$mac]["bw_up"] = $tagcontent->bw_up ;
$handled_mac_addresses[$mac]["bw_down"] = $tagcontent->bw_down ;
// only handle addresses we know of
if (array_key_exists($mac, $arp_maclist)) {
// if the address is already in our database, check if it has changed
if (array_key_exists($mac, $db_maclist)) {
// save pipe numbers for bandwidth restriction
$handled_mac_addresses[$mac]["pipeno_in"] = $db_maclist[$mac]->pipeno_in ;
$handled_mac_addresses[$mac]["pipeno_out"] = $db_maclist[$mac]->pipeno_out ;
if ($db_maclist[$mac]->ip != $arp_maclist[$mac]['ip']) {
// handle changed ip,
$handled_mac_addresses[$mac]["action"] = "changed ip";
$exec_commands = array(
# delete old ip address
"/sbin/ipfw table ". $ipfw_tables["in"] .
" delete ". $db_maclist[$mac]->ip,
"/sbin/ipfw table ". $ipfw_tables["out"] .
" delete ". $db_maclist[$mac]->ip,
# insert new ip address
"/sbin/ipfw table ". $ipfw_tables["in"] .
" add " . $arp_maclist[$mac]['ip']. " " . $db_maclist[$mac]->pipeno_in,
"/sbin/ipfw table ". $ipfw_tables["out"] .
" add " . $arp_maclist[$mac]['ip']. " " . $db_maclist[$mac]->pipeno_out,
);
// execute all ipfw actions
$this->shell->exec($exec_commands);
// update administration
$db->upsertPassthruMAC(
$tagcontent->mac,
$arp_maclist[$mac]['ip'],
$db_maclist[$mac]->pipeno_in,
$db_maclist[$mac]->pipeno_out
); // new ip according to arp table
}
} else {
// new host, not seen it yet
$handled_mac_addresses[$mac]["action"] = "new";
$pipeno_in = $this->newIPFWpipeno() ;
$pipeno_out = $this->newIPFWpipeno() ;
// execute all ipfw actions
$exec_commands = array(
# insert new ip address
"/sbin/ipfw table ". $ipfw_tables["in"] .
" add " . $arp_maclist[$mac]['ip']. " " . $pipeno_in,
"/sbin/ipfw table ". $ipfw_tables["out"] .
" add " . $arp_maclist[$mac]['ip']. " " . $pipeno_out,
);
$this->shell->exec($exec_commands);
$db->upsertPassthruMAC(
$tagcontent->mac,
$arp_maclist[$mac]['ip'],
$pipeno_in,
$pipeno_out
);
// save pipe numbers for bandwidth restriction
$handled_mac_addresses[$mac]["pipeno_in"] = $pipeno_in ;
$handled_mac_addresses[$mac]["pipeno_out"] = $pipeno_out ;
}
}
}
}
}
}
//
// cleanup old addresses
//
foreach ($db_maclist as $mac => $record) {
if (!array_key_exists($mac, $handled_mac_addresses)) {
# delete old ip address, execute all actions
$exec_commands = array(
"/sbin/ipfw table ". $ipfw_tables["in"] .
" delete ". $db_maclist[$mac]->ip,
"/sbin/ipfw table ". $ipfw_tables["out"] .
" delete ". $db_maclist[$mac]->ip,
);
$this->shell->exec($exec_commands);
// TODO : cleanup $record->pipeno_in, $record->pipeno_out ;
$db->dropPassthruMAC($mac);
}
}
// reset bandwidth
foreach ($handled_mac_addresses as $mac => $record) {
if (array_key_exists("pipeno_in", $record)) {
$this->resetBandwidth($record["pipeno_in"], $record["bw_down"]);
$this->resetBandwidth($record["pipeno_out"], $record["bw_up"]);
}
}
unset($db);
}
}
}
/**
* load accounting rules into ruleset, used for reinitialisation of the ruleset.
* triggers addAccounting() for all active clients in all zones
*/
private function loadAccounting()
{
foreach ($this->config->object()->captiveportal->children() as $cpzonename => $zone) {
$db = new DB($cpzonename);
foreach ($db->listClients(array()) as $client) {
$this->addAccounting($zone->zoneid, $client->ip) ;
}
unset($db);
}
}
/**
* add accounting rules for ip
* @param int $zoneid zone
* @param string $ip ip address
*/
public function addAccounting($zoneid, $ip)
{
// TODO: check processing speed, this might need some improvement
// check if our ip is already in the list and collect first free rule number to place it there if necessary
$shell_output=array();
$this->shell->exec('/sbin/ipfw show', false, $shell_output);
$prev_id = 0;
$new_id = null;
foreach ($shell_output as $line) {
// only trigger on counter rules and last item in the list
if (strpos($line, " count ") !== false || strpos($line, "65535 ") !== false) {
if (strpos($line, " ".$ip." ") !== false) {
// already in table... exit
return;
}
$this_line_id = (int)(explode(" ", $line)[0]) ;
if ($this_line_id > 30000 and ($this_line_id -1) > $prev_id and $new_id == null) {
// new id found
if ($this_line_id == 65535) {
$new_id = $prev_id+1;
} else {
$new_id = $this_line_id-1;
}
}
$prev_id = $this_line_id;
}
}
if ($new_id != null) {
$exec_commands = array(
"/sbin/ipfw add " . $new_id . " set " . $zoneid . " count ip from " . $ip . " to any ",
"/sbin/ipfw add " . $new_id . " set " . $zoneid . " count ip from any to " . $ip,
);
// execute all ipfw actions
$this->shell->exec($exec_commands);
}
}
/**
* unlock host for captiveportal use
* @param string $cpzonename
* @param string $clientip
* @param string $clientmac
* @param string $username
* @param string|null $password
* @param string|null $bw_up
* @param string|null $bw_down
* @param string|null $radiusctx
* @param int|null $session_timeout
* @param int|null $idle_timeout
* @param int|null $session_terminate_time
* @param int|null $interim_interval
* @return bool|string
*/
public function portalAllow(
$cpzonename,
$clientip,
$clientmac,
$username,
$password = null,
$bw_up = null,
$bw_down = null,
$radiusctx = null,
$session_timeout = null,
$idle_timeout = null,
$session_terminate_time = null,
$interim_interval = null
) {
// defines
$exec_commands = array() ;
$db = new DB($cpzonename);
$arp= new ARP();
// find zoneid for this named zone
$zoneid = -1;
foreach ($this->config->object()->captiveportal->children() as $zone => $zoneobj) {
if ($zone == $cpzonename) {
$zoneid = $zoneobj->zoneid;
}
}
if ($zoneid == -1) {
return false; // not a valid zone, bailout
}
// grap needed data to generate our rules
$ipfw_tables = $this->getAuthUsersTables($zoneid);
$cp_table = $db->listClients(array("mac"=>$clientmac, "ip"=>$clientip), "or");
if (sizeof($cp_table) > 0 && ($cp_table[0]->ip == $clientip && $cp_table[0]->mac == $clientmac)) {
// nothing (important) changed here... move on
return $cp_table[0]->sessionid;
} elseif (sizeof($cp_table) > 0) {
// something changed...
// prevent additional sessions to popup,
// one MAC should have only one active session, remove the rest (if any)
$cnt = 0;
$remove_sessions = array();
foreach ($cp_table as $record) {
if ($cnt >0) {
$remove_sessions[] = $record->sessionid;
} else {
$current_session = $record;
}
$cnt++;
// prepare removal for all ip addresses belonging to this host
$exec_commands[] = "/sbin/ipfw table ". $ipfw_tables["in"] ." delete ". $record->ip;
$exec_commands[] = "/sbin/ipfw table ". $ipfw_tables["out"] ." delete ". $record->ip;
// TODO: if for some strange reason there is more than one session, we are failing to drop the pipes
$exec_commands[] = "/usr/sbin/arp -d ".trim($record->ip); // drop static arp entry (prevent MAC change)
}
if (sizeof($remove_sessions)) {
$db->removeSession($remove_sessions);
}
// collect pipe numbers for dummynet
$pipeno_in = $current_session->pipeno_in;
$pipeno_out = $current_session->pipeno_out;
$db->updateSession($current_session->sessionid, array("ip"=>$clientip, "mac"=>$clientmac));
// preserve session for response
$sessionid = $current_session->sessionid;
} else {
// new session, allocate new dummynet pipes and generate a unique id
$pipeno_in = $this->newIPFWpipeno();
$pipeno_out = $this->newIPFWpipeno();
// construct session data
$session_data=array();
$session_data["ip"]=$clientip;
$session_data["mac"]=$clientmac;
$session_data["pipeno_in"] = $pipeno_in;
$session_data["pipeno_out"] = $pipeno_out;
$session_data["username"]=\SQLite3::escapeString($username);
$session_data["bpassword"] = base64_encode($password);
$session_data["session_timeout"] = $session_timeout;
$session_data["idle_timeout"] = $idle_timeout;
$session_data["session_terminate_time"] = $session_terminate_time;
$session_data["interim_interval"] = $interim_interval;
$session_data["radiusctx"] = $radiusctx;
$session_data["allow_time"] = time(); // allow time is actual starting time of this session
$sessionid = uniqid() ;
$db->insertSession($sessionid, $session_data);
}
// add commands for access tables, and execute all collected
$exec_commands[] = "/sbin/ipfw table ". $ipfw_tables["in"] ." add ". $clientip . " ".$pipeno_in;
$exec_commands[] = "/sbin/ipfw table ". $ipfw_tables["out"] ." add ". $clientip . " ".$pipeno_out;
$this->shell->exec($exec_commands);
// lock the user/ip to it's MAC address using arp
$arp->setStatic($clientip, $clientmac);
// add accounting rule
$this->addAccounting($zoneid, $clientip);
// set bandwidth restrictions
$this->resetBandwidth($pipeno_in, $bw_up);
$this->resetBandwidth($pipeno_in, $bw_down);
// log
$this->logportalauth($cpzonename, $username, $clientmac, $clientip, $status = "LOGIN");
// cleanup
unset($db);
return $sessionid;
}
/**
* send message to syslog
* @param string $cpzonename
* @param string $user
* @param string $mac
* @param string $ip
* @param string $status
* @param string $message
*/
private function logportalauth($cpzonename, $user, $mac, $ip, $status, $message = "")
{
$message = trim($message);
$message = "Zone : {$cpzonename} {$status}: {$user}, {$mac}, {$ip}, {$message}";
$logger = new Syslog("logportalauth", array(
'option' => LOG_PID,
'facility' => LOG_LOCAL4
));
$logger->info($message);
}
/**
* flush zone (null flushes all zones)
* @param string|null $zone zone name or id
*/
public function flush($zone = null)
{
if ($zone == null) {
$shell = new Core\Shell();
$shell->exec("/sbin/ipfw -f table all flush");
} else {
// find zoneid for this named zone
if (preg_match("/^[0-9]{1,2}$/", trim($zone))) {
$zoneid = $zone;
} else {
$zoneid = -1;
foreach ($this->config->object()->captiveportal->children() as $zonenm => $zoneobj) {
if ($zonenm == $zone) {
$zoneid = $zoneobj->zoneid;
}
}
}
if ($zoneid != -1) {
$exec_commands= array(
"/sbin/ipfw -f table ".$this->getAuthUsersTables($zoneid)["in"]." flush",
"/sbin/ipfw -f table ".$this->getAuthUsersTables($zoneid)["out"]." flush",
"/sbin/ipfw -f table ".$this->getAuthIPTables($zoneid)["in"]." flush",
"/sbin/ipfw -f table ".$this->getAuthIPTables($zoneid)["out"]." flush",
"/sbin/ipfw -f table ".$this->getAuthMACTables($zoneid)["in"]." flush",
"/sbin/ipfw -f table ".$this->getAuthMACTables($zoneid)["out"]." flush",
"/sbin/ipfw delete set ".$zoneid,
);
$this->shell->exec($exec_commands);
}
}
}
/**
* cleanup portal sessions
* @param $cpzone|null zone name
*/
public function portalCleanupSessions($cpzone = null)
{
$acc_list = $this->listAccounting();
foreach ($this->config->object()->captiveportal->children() as $cpzonename => $zoneobj) {
if ($cpzone == null || $cpzone == $cpzonename) {
$db = new DB($cpzonename);
$clients = $db->listClients(array(), null, null);
foreach ($clients as $client) {
$idle_time = 0;
if (array_key_exists($client->ip, $acc_list)) {
$idle_time = $acc_list[$client->ip]['idle_time'];
}
// if session timeout is reached, disconnect
if (is_numeric($client->session_timeout) && $client->session_timeout > 0) {
if (((time() - $client->allow_time) ) > $client->session_timeout) {
$this->disconnect($cpzonename, $client->sessionid);
$this->logportalauth(
$cpzonename,
$client->username,
$client->mac,
$client->ip,
$status = "SESSION TIMEOUT"
);
continue;
}
}
// disconnect session if idle timeout is reached
if (is_numeric($client->idle_timeout) && $client->idle_timeout > 0 && $idle_time > 0) {
if ($idle_time > $client->idle_timeout) {
$this->disconnect($cpzonename, $client->sessionid);
$this->logportalauth(
$cpzonename,
$client->username,
$client->mac,
$client->ip,
$status = "IDLE TIMEOUT"
);
continue;
}
}
// disconnect on session terminate time
if (is_numeric($client->session_terminate_time) &&
$client->session_terminate_time > 0 &&
$client->session_terminate_time < time()) {
$this->disconnect($cpzonename, $client->sessionid);
$this->logportalauth(
$cpzonename,
$client->username,
$client->mac,
$client->ip,
$status = "TERMINATE TIME REACHED"
);
continue;
}
}
unset($db);
}
}
unset($acc_list);
}
/**
* list (ipfw) accounting information
* @param string|null $ipaddr ip address
* @return array (key = hosts ip)
*/
public function listAccounting($ipaddr = null)
{
$filter_cmd = "";
$result = array();
$shell_output = array();
if ($ipaddr != null) {
$filter_cmd =" | /usr/bin/grep ' " . $ipaddr ." '" ;
}
if ($this->shell->exec("/sbin/ipfw -aT list ".$filter_cmd, false, $shell_output) == 0) {
foreach ($shell_output as $line) {
if (strpos($line, ' count ip from') !== false) {
$parts = preg_split('/\s+/', $line);
if (count($parts) > 8 && $parts[7] != 'any' and strlen($parts[7]) > 5) {
$result[$parts[7]] = array(
"rulenum" => $parts[0],
"last_accessed" => (int)$parts[3],
"idle_time" => time() - (int)$parts[3],
"out_packets" => (int)$parts[1],
"in_packets" => (int)$parts[2]
);
}
}
}
}
return $result;
}
/**
* disconnect a session or a list of sessions depending on the parameter
* @param string $cpzonename zone name or id
* @param string $sessionid session id
*/
public function disconnect($cpzonename, $sessionid)
{
if (is_array($sessionid)) {
foreach ($sessionid as $sessid) {
$this->disconnectSession($cpzonename, $sessid);
}
} else {
$this->disconnectSession($cpzonename, $sessionid);
}
}
/**
* @param string $cpzonename zone name
* @param string $sessionid session id
* @return boolean false for invalid request
*/
private function disconnectSession($cpzonename, $sessionid)
{
$zoneid = -1;
foreach ($this->config->object()->captiveportal->children() as $zone => $zoneobj) {
if ($zone == $cpzonename) {
$zoneid = $zoneobj->zoneid;
}
}
if ($zoneid == -1) {
// not a valid zone
return false;
}
$db = new DB($cpzonename);
$db_clients = $db->listClients(array("sessionid"=>$sessionid));
$ipfw_tables = $this->getAuthUsersTables($zoneid);
if (sizeof($db_clients) > 0) {
if ($db_clients[0]->ip != null) {
// only handle disconnect if we can find a client in our database
$exec_commands[] = "/sbin/ipfw table " . $ipfw_tables["in"] . " delete " . $db_clients[0]->ip;
$exec_commands[] = "/sbin/ipfw table " . $ipfw_tables["out"] . " delete " . $db_clients[0]->ip;
$this->shell->exec($exec_commands);
// TODO: cleanup dummynet pipes $db_clients[0]->pipeno_in/out
// TODO: log removal
// ( was : captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "DISCONNECT");)
}
$db->removeSession($sessionid);
}
return true;
}
}

View File

@ -3,10 +3,6 @@
"name": "User - Config - Deny Config Write",
"descr": "If present, ignores requests from this user to write config.xml."
},
"user-services-captiveportal-login": {
"name": "User - Services - Captive portal login",
"descr": "Indicates whether the user is able to login on the captive portal."
},
"user-shell-access": {
"name": "User - System - Shell account access",
"descr": "Indicates whether the user is able to login for example via SSH."
@ -639,90 +635,6 @@
"wizard.php*"
]
},
"page-services-captiveportal": {
"name": "WebCfg - Services: Captive portal page",
"descr": "Allow access to the 'Services: Captive portal' page.",
"match": [
"services_captiveportal.php*"
]
},
"page-services-captiveportal-allowedhostnames": {
"name": "WebCfg - Services: Captive portal: Allowed Hostnames page",
"descr": "Allow access to the 'Services: Captive portal: Allowed Hostnames' page.",
"match": [
"services_captiveportal_hostname.php*"
]
},
"page-services-captiveportal-allowedips": {
"name": "WebCfg - Services: Captive portal: Allowed IPs page",
"descr": "Allow access to the 'Services: Captive portal: Allowed IPs' page.",
"match": [
"services_captiveportal_ip.php*"
]
},
"page-services-captiveportal-editallowedhostnames": {
"name": "WebCfg - Services: Captive portal: Edit Allowed Hostnames page",
"descr": "Allow access to the 'Services: Captive portal: Allowed Hostnames' page.",
"match": [
"services_captiveportal_hostname_edit.php*"
]
},
"page-services-captiveportal-editallowedips": {
"name": "WebCfg - Services: Captive portal: Edit Allowed IPs page",
"descr": "Allow access to the 'Services: Captive portal: Edit Allowed IPs' page.",
"match": [
"services_captiveportal_ip_edit.php*"
]
},
"page-services-captiveportal-editmacaddresses": {
"name": "WebCfg - Services: Captive portal: Edit MAC Addresses page",
"descr": "Allow access to the 'Services: Captive portal: Edit MAC Addresses' page.",
"match": [
"services_captiveportal_mac_edit.php*"
]
},
"page-services-captiveportal-voucher-edit": {
"name": "WebCfg - Services: Captive portal: Edit Voucher Rolls page",
"descr": "Allow access to the 'Services: Captive portal: Edit Voucher Rolls' page.",
"match": [
"services_captiveportal_vouchers_edit.php*"
]
},
"page-services-captiveportal-editzones": {
"name": "WebCfg - Services: Captive portal: Edit Zones page",
"descr": "Allow access to the 'Services: Captive portal: Edit Zones' page.",
"match": [
"services_captiveportal_zones_edit.php*"
]
},
"page-services-captiveportal-filemanager": {
"name": "WebCfg - Services: Captive portal: File Manager page",
"descr": "Allow access to the 'Services: Captive portal: File Manager' page.",
"match": [
"services_captiveportal_filemanager.php*"
]
},
"page-services-captiveportal-macaddresses": {
"name": "WebCfg - Services: Captive portal: Mac Addresses page",
"descr": "Allow access to the 'Services: Captive portal: Mac Addresses' page.",
"match": [
"services_captiveportal_mac.php*"
]
},
"page-services-captiveportal-vouchers": {
"name": "WebCfg - Services: Captive portal: Vouchers page",
"descr": "Allow access to the 'Services: Captive portal: Vouchers' page.",
"match": [
"services_captiveportal_vouchers.php*"
]
},
"page-services-captiveportal-zones": {
"name": "WebCfg - Services: Captive portal: Zones page",
"descr": "Allow access to the 'Services: Captive portal: Zones' page.",
"match": [
"services_captiveportal_zones.php*"
]
},
"page-services-dhcprelay": {
"name": "WebCfg - Services: DHCP Relay page",
"descr": "Allow access to the 'Services: DHCP Relay' page.",
@ -975,41 +887,6 @@
"services_wol_edit.php*"
]
},
"page-status-captiveportal": {
"name": "WebCfg - Status: Captive portal page",
"descr": "Allow access to the 'Status: Captive portal' page.",
"match": [
"status_captiveportal.php*"
]
},
"page-status-captiveportal-expire": {
"name": "WebCfg - Status: Captive portal: Expire Vouchers page",
"descr": "Allow access to the 'Status: Captive portal: Expire Vouchers' page.",
"match": [
"status_captiveportal_expire.php*"
]
},
"page-status-captiveportal-test": {
"name": "WebCfg - Status: Captive portal: Test Vouchers page",
"descr": "Allow access to the 'Status: Captive portal: Test Vouchers' page.",
"match": [
"status_captiveportal_test.php*"
]
},
"page-status-captiveportal-voucher-rolls": {
"name": "WebCfg - Status: Captive portal: Voucher Rolls page",
"descr": "Allow access to the 'Status: Captive portal: Voucher Rolls' page.",
"match": [
"status_captiveportal_voucher_rolls.php*"
]
},
"page-status-captiveportal-vouchers": {
"name": "WebCfg - Status: Captive portal: Vouchers page",
"descr": "Allow access to the 'Status: Captive portal: Vouchers' page.",
"match": [
"status_captiveportal_vouchers.php*"
]
},
"page-status-carp": {
"name": "WebCfg - Status: CARP page",
"descr": "Allow access to the 'Status: CARP' page.",

View File

@ -1,39 +0,0 @@
<?php
require_once("script/load_phalcon.php");
$cpc = new Captiveportal\CPClient();
$acc_list = $cpc->list_accounting();
print_r($acc_list);
//$cpc->portal_allow("test","10.211.55.101","00:1C:42:49:B7:B2","Fritsx");
//$cpc->disconnect("test",array("5489714eba263","gdsajhgadsjhg"));
//$cpc->reconfigure();
//$cpc->refresh_allowed_mac();
//$cpc->refresh_allowed_ips();
//$db = new Captiveportal\DB("test");
//$db->remove_session("XXX");
//$db->insert_session(100,1,"10.211.55.101","00:1C:42:49:B7:B2","frits","XXX","aksjdhaskjh",
// null,null, null,null, null);
//
//$clients = $db->listClients( array("sessionid" => "XXX") );
//
//foreach($clients as $client ){
// print($client->pipeno) ;
//}
//$arp = new \Captiveportal\ARP();
//$arp->setStatic("172.20.0.1",'00:1c:42:49:b7:b1');
//$arp->dropStatic("172.20.0.1");
//$config = \Core\Core\Config::getInstance();
//$config->dump();
//print_r($config->xpath('//opnsense/interfaces/*') );
//$rules= new \Core\Captiveportal\Rules();

View File

@ -1,114 +0,0 @@
#!/usr/local/bin/php
<?php
/*
Copyright (C) 2011 Warren Baker
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("interfaces.inc");
require_once("config.inc");
require_once("captiveportal.inc");
require_once("util.inc");
global $cpzone;
$cpzone = $argv[1];
$type = $argv[2];
// TODO: fix this file
/* read in captive portal db */
$cpdb = array();// captiveportal_read_db();
/* determine number of logged in users */
$no_users = count($cpdb);
$concurrent_users = $no_users;
/* set initial user count to zero */
$current_user_count = 0;
/* tmp file to use to store old data (per interface)*/
$tmpfile = '/var/db/captiveportal_online_users';
if (empty($type)) {
exit;
}
/* echo the rrd required syntax */
echo "N:";
$result = "NaN";
if ($type == "loggedin") {
$timestamp = 0;
/* Find out the previous user timestamp
* so we can determine the difference between the current
* and previous user count. If the file is empty return a 0.
*/
$fd = @fopen($tmpfile, "r");
if ($fd) {
while (!feof($fd)) {
$line = trim(fgets($fd));
if ($line) {
$previous_user_timestamp = $line;
} else {
$previous_user_timestamp = 0;
}
}
} else {
$previous_user_timestamp = 0;
}
@fclose($fd);
foreach ($cpdb as $user) {
$user_ip = $user[2];
// Record the timestamp
$timestamp = $user[0];
if ($timestamp > $previous_user_timestamp) {
$current_user_count = $current_user_count + 1;
}
}
// Write out the latest timestamp but not if it is empty
if (!empty($timestamp)) {
$fd = @fopen($tmpfile, "w");
if ($fd) {
fwrite($fd, $timestamp);
}
@fclose($fd);
}
/* If $timestamp is less than or equal to previous_user_timestamp return 0,
* as we only want the 'X' number of users logged in since last RRD poll.
*/
if ($timestamp <= $previous_user_timestamp) {
$result = 0;
} else {
$result = $current_user_count;
}
} elseif ($type == "concurrent")
$result = $no_users;
echo "$result";

View File

@ -29,7 +29,6 @@
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
function upload_crash_report($files, $agent)
{

View File

@ -1,6 +1,7 @@
<?php
/*
Copyright (C) 2014 Deciso B.V.
Copyright (C) 2014 Deciso B.V.
Copyright (C) 2010 Ermal Luçi
All rights reserved.
@ -28,6 +29,7 @@
require_once("guiconfig.inc");
require_once("PEAR.inc");
require_once("interfaces.inc");
require_once("radius.inc");
function getUserGroups($username, $authcfg)

View File

@ -150,8 +150,6 @@ function spit_out_select_items($name, $showall) {
global $config;
$areas = array("aliases" => gettext("Aliases"),
"captiveportal" => gettext("Captive Portal"),
"voucher" => gettext("Captive Portal Vouchers"),
"dnsmasq" => gettext("DNS Forwarder"),
"dhcpd" => gettext("DHCP Server"),
"dhcpdv6" => gettext("DHCPv6 Server"),
@ -445,15 +443,6 @@ if ($_POST) {
$savemsg = gettext("The m0n0wall configuration has been restored and upgraded to OPNsense.");
mark_subsystem_dirty("restore");
}
if(is_array($config['captiveportal'])) {
foreach($config['captiveportal'] as $cp) {
if (isset($cp['enable'])) {
/* for some reason ipfw doesn't init correctly except on bootup sequence */
mark_subsystem_dirty("restore");
break;
}
}
}
setup_serial_port();
} else {
$input_errors[] = gettext("The configuration could not be restored.");

View File

@ -45,7 +45,6 @@ if ($_POST['clear']) {
}
$pgtitle = array(gettext("Status"),gettext("System logs"),gettext("Portal Auth"));
$shortcut_section = "captiveportal";
include("head.inc");
?>

View File

@ -38,15 +38,6 @@ function find_service_by_name($name) {
return array();
}
function find_service_by_cp_zone($zone) {
$services = get_services();
foreach ($services as $service)
if (($service["name"] == "captiveportal") && isset($service["zone"]) && ($service["zone"] == $zone))
return $service;
return array();
}
/* Determine automated help URL. Should output the page name and
parameters separately */
$uri_split = "";
@ -243,9 +234,6 @@ if($need_alert_display == true) {
case "openvpn":
$ssvc = find_service_by_openvpn_vpnid($vpnid);
break;
case "captiveportal":
$ssvc = find_service_by_cp_zone($cpzone);
break;
default:
$ssvc = find_service_by_name($shortcuts[$shortcut_section]['service']);

View File

@ -33,7 +33,6 @@
require_once("guiconfig.inc");
require_once("vpn.inc");
require_once("captiveportal.inc");
require_once("filter.inc");
require_once("rrd.inc");
require_once("vpn.inc");

View File

@ -33,7 +33,6 @@ $pgtitle = array(gettext("Interfaces"),gettext("Assign network ports"));
require_once("guiconfig.inc");
require_once("filter.inc");
require_once("vpn.inc");
require_once("captiveportal.inc");
require_once("rrd.inc");
require_once("system.inc");
require_once("interfaces.inc");

View File

@ -1,4 +1,5 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
@ -27,7 +28,6 @@
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("system.inc");
$pgtitle = array(gettext("Diagnostics"),gettext("Reboot System"));

File diff suppressed because it is too large Load Diff

View File

@ -1,261 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2005-2006 Jonathan De Graeve (jonathan.de.graeve@imelda.be)
and Paul Taylor (paultaylor@winn-dixie.com).
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
require_once("interfaces.inc");
$captiveportal_element_sizelimit = 1048576;
function cpelementscmp($a, $b)
{
return strcasecmp($a['name'], $b['name']);
}
function cpelements_sort()
{
global $config, $cpzone;
usort($config['captiveportal'][$cpzone]['element'], "cpelementscmp");
}
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone)) {
header("Location: services_captiveportal_zones.php");
exit;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
$pgtitle = array(gettext("Services"),gettext("Captive portal"), $a_cp[$cpzone]['zone']);
$shortcut_section = "captiveportal";
if (!is_array($a_cp[$cpzone]['element'])) {
$a_cp[$cpzone]['element'] = array();
}
$a_element =& $a_cp[$cpzone]['element'];
// Calculate total size of all files
$total_size = 0;
foreach ($a_element as $element) {
$total_size += $element['size'];
}
if ($_POST) {
unset($input_errors);
if (is_uploaded_file($_FILES['new']['tmp_name'])) {
if (!stristr($_FILES['new']['name'], "captiveportal-")) {
$name = "captiveportal-" . $_FILES['new']['name'];
} else {
$name = $_FILES['new']['name'];
}
$size = filesize($_FILES['new']['tmp_name']);
// is there already a file with that name?
foreach ($a_element as $element) {
if ($element['name'] == $name) {
$input_errors[] = sprintf(gettext("A file with the name '%s' already exists."), $name);
break;
}
}
// check total file size
if (($total_size + $size) > $captiveportal_element_sizelimit) {
$input_errors[] = gettext("The total size of all files uploaded may not exceed ") .
format_bytes($captiveportal_element_sizelimit) . ".";
}
if (!$input_errors) {
$element = array();
$element['name'] = $name;
$element['size'] = $size;
$element['content'] = base64_encode(file_get_contents($_FILES['new']['tmp_name']));
$a_element[] = $element;
cpelements_sort();
write_config();
captiveportal_write_elements();
header("Location: services_captiveportal_filemanager.php?zone={$cpzone}");
exit;
}
}
} elseif (($_GET['act'] == "del") && !empty($cpzone) && $a_element[$_GET['id']]) {
@unlink("/var/db/cpelements/" . $a_element[$_GET['id']]['name']);
@unlink("/usr/local/captiveportal/" . $a_element[$_GET['id']]['name']);
unset($a_element[$_GET['id']]);
write_config();
header("Location: services_captiveportal_filemanager.php?zone={$cpzone}");
exit;
}
include("head.inc");
$main_buttons = array(
array('label'=>gettext('add file'), 'href'=>'services_captiveportal_filemanager.php?zone='.$cpzone.'&act=add'),
);
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
} ?>
<section class="col-xs-12">
<?php
$tab_array = array();
$tab_array[] = array(gettext("Captive portal(s)"), false, "services_captiveportal.php?zone={$cpzone}");
$tab_array[] = array(gettext("MAC"), false, "services_captiveportal_mac.php?zone={$cpzone}");
$tab_array[] = array(gettext("Allowed IP addresses"), false, "services_captiveportal_ip.php?zone={$cpzone}");
// Hide Allowed Hostnames as this feature is currently not supported
// $tab_array[] = array(gettext("Allowed Hostnames"), false, "services_captiveportal_hostname.php?zone={$cpzone}");
$tab_array[] = array(gettext("Vouchers"), false, "services_captiveportal_vouchers.php?zone={$cpzone}");
$tab_array[] = array(gettext("File Manager"), true, "services_captiveportal_filemanager.php?zone={$cpzone}");
display_top_tabs($tab_array, true);
?>
<div class="tab-content content-box col-xs-12">
<div class="container-fluid">
<form action="services_captiveportal_filemanager.php" method="post" name="iform" id="iform" enctype="multipart/form-data">
<input type="hidden" name="zone" id="zone" value="<?=htmlspecialchars($cpzone);?>" />
<?php if ($_GET['act'] == 'add') :
?>
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td width="10%">Upload file</td>
<td class="listlr" colspan="2"><input type="file" name="new" class="formfld file" size="40" id="new" /></td>
</tr>
<tr>
<td></td>
<td><input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Upload"); ?>" />
<a href="services_captiveportal_filemanager.php?zone=<?=$cpzone;?>" class="btn btn-default">Cancel</a>
</td>
</tr>
</table>
</div>
<br/>
<?php
endif; ?>
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td width="70%" class="listhdrr"><?=gettext("Name"); ?></td>
<td width="20%" class="listhdr"><?=gettext("Size"); ?></td>
<td width="10%" class="list">
</td>
</tr>
<?php if (is_array($a_cp[$cpzone]['element'])) :
$i = 0; foreach ($a_cp[$cpzone]['element'] as $element) :
?>
<tr>
<td class="listlr"><?=htmlspecialchars($element['name']);?></td>
<td class="listr" align="right"><?=format_bytes($element['size']);?></td>
<td valign="middle" class="list nowrap">
<a href="services_captiveportal_filemanager.php?zone=<?=$cpzone;
?>&amp;act=del&amp;id=<?=$i;
?>" onclick="return confirm('<?=gettext("Do you really want to delete this file?"); ?>')">
<span class="glyphicon glyphicon-remove" title="<?=gettext("delete file"); ?>"></span></a>
</td>
</tr>
<?php $i++;
endforeach;
endif; ?>
<?php if ($total_size > 0) :
?>
<tr>
<td class="listlr" style="background-color: #eee"><strong><?=gettext("TOTAL"); ?></strong></td>
<td class="listr" style="background-color: #eee" align="right"><strong><?=format_bytes($total_size);?></strong></td>
<td valign="middle" style="background-color: #eee" class="list nowrap"></td>
</tr>
<?php
endif; ?>
</table>
</div>
<span class="vexpl"><span class="text-danger"><strong>
<?=gettext("Note:"); ?><br />
</strong></span>
<?=gettext("Any files that you upload here with the filename prefix of captiveportal- will " .
"be made available in the root directory of the captive portal HTTP(S) server. " .
"You may reference them directly from your portal page HTML code using relative paths. " .
"Example: you've uploaded an image with the name 'captiveportal-test.jpg' using the " .
"file manager. Then you can include it in your portal page like this:"); ?><br /><br />
<tt>&lt;img src=&quot;captiveportal-test.jpg&quot; width=... height=...&gt;</tt>
<br /><br />
<?=gettext("In addition, you can also upload .php files for execution. You can pass the filename " .
"to your custom page from the initial page by using text similar to:"); ?>
<br /><br />
<tt>&lt;a href="/captiveportal-aup.php?zone=$PORTAL_ZONE$&amp;redirurl=$PORTAL_REDIRURL$"&gt;<?=gettext("Acceptable usage policy"); ?>&lt;/a&gt;</tt>
<br /><br />
<?php printf(gettext("The total size limit for all files is %s."), format_bytes($captiveportal_element_sizelimit));?></span>
</form>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -1,172 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
require_once("interfaces.inc");
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone) || empty($config['captiveportal'][$cpzone])) {
header("Location: services_captiveportal_zones.php");
exit;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
$pgtitle = array(gettext("Services"),gettext("Captive portal"), $a_cp[$cpzone]['zone']);
$shortcut_section = "captiveportal";
if ($_GET['act'] == "del") {
$a_allowedips =& $config['captiveportal'][$cpzone]['allowedip'];
if ($a_allowedips[$_GET['id']]) {
$ipent = $a_allowedips[$_GET['id']];
unset($a_allowedips[$_GET['id']]);
write_config();
header("Location: services_captiveportal_ip.php?zone={$cpzone}");
exit;
}
}
include("head.inc");
$main_buttons = array(
array('label'=>'Add IP address', 'href'=>'services_captiveportal_ip_edit.php?zone='.$cpzone),
);
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($savemsg)) {
print_info_box($savemsg);
} ?>
<section class="col-xs-12">
<?php
$tab_array = array();
$tab_array[] = array(gettext("Captive portal(s)"), false, "services_captiveportal.php?zone={$cpzone}");
$tab_array[] = array(gettext("MAC"), false, "services_captiveportal_mac.php?zone={$cpzone}");
$tab_array[] = array(gettext("Allowed IP addresses"), true, "services_captiveportal_ip.php?zone={$cpzone}");
// Hide Allowed Hostnames as this feature is currently not supported
// $tab_array[] = array(gettext("Allowed Hostnames"), false, "services_captiveportal_hostname.php?zone={$cpzone}");
$tab_array[] = array(gettext("Vouchers"), false, "services_captiveportal_vouchers.php?zone={$cpzone}");
$tab_array[] = array(gettext("File Manager"), false, "services_captiveportal_filemanager.php?zone={$cpzone}");
display_top_tabs($tab_array, true);
?>
<div class="tab-content content-box col-xs-12">
<div class="container-fluid">
<form action="services_captiveportal_ip.php" method="post" name="iform" id="iform">
<input type="hidden" name="zone" id="zone" value="<?=htmlspecialchars($cpzone);?>" />
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td width="40%" class="listhdrr"><?=gettext("IP address"); ?></td>
<td width="50%" class="listhdr"><?=gettext("Description"); ?></td>
<td width="10%" class="list">
</td>
</tr>
<?php if (is_array($a_cp[$cpzone]['allowedip'])) :
$i = 0; foreach ($a_cp[$cpzone]['allowedip'] as $ip) :
?>
<tr ondblclick="document.location='services_captiveportal_ip_edit.php?zone=<?=$cpzone;
?>&amp;id=<?=$i;?>'">
<td class="listlr">
<?php
if ($ip['dir'] == "to") {
echo "any <span class=\"glyphicon glyphicon-arrow-right\" aria-hidden=\"true\" alt=\"in\"></span> ";
}
if ($ip['dir'] == "both") {
echo "<span class=\"glyphicon glyphicon-resize-horizontal\" aria-hidden=\"true\" alt=\"pass\"></span> ";
}
echo strtolower($ip['ip']);
if ($ip['sn'] != "32" && is_numeric($ip['sn'])) {
$sn = $ip['sn'];
echo "/$sn";
}
if ($ip['dir'] == "from") {
echo "<span class=\"glyphicon glyphicon-arrow-right\" aria-hidden=\"true\" alt=\"any\"></span> any";
}
?>
</td>
<td class="listbg">
<?=htmlspecialchars($ip['descr']);?>&nbsp;
</td>
<td valign="middle" class="list nowrap"><a href="services_captiveportal_ip_edit.php?zone=<?=$cpzone;
?>&amp;id=<?=$i;?>" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-pencil"></span></a>
<a href="services_captiveportal_ip.php?zone=<?=$cpzone;
?>&amp;act=del&amp;id=<?=$i;
?>" onclick="return confirm('<?=gettext("Do you really want to delete this address?"); ?>')" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-remove"></span></a></td>
</tr>
<?php $i++;
endforeach;
endif; ?>
<tr>
<td colspan="2" class="list"><p class="vexpl"><span class="red"><strong>
<?=gettext("Note:"); ?><br />
</strong></span>
<?=gettext("Adding allowed IP addresses will allow IP access to/from these addresses through the captive portal without being taken to the portal page. This can be used for a web server serving images for the portal page or a DNS server on another network, for example."); ?></p>
</td>
<td class="list">&nbsp;</td>
</tr>
</table>
</div>
</form>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -1,253 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2011 Scott Ullrich <sullrich@gmail.com>
Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
require_once("interfaces.inc");
function allowedipscmp($a, $b)
{
return strcmp($a['ip'], $b['ip']);
}
function allowedips_sort()
{
global $g, $config, $cpzone;
usort($config['captiveportal'][$cpzone]['allowedip'], "allowedipscmp");
}
$pgtitle = array(gettext("Services"),gettext("Captive portal"),gettext("Edit allowed IP address"));
$shortcut_section = "captiveportal";
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone) || empty($config['captiveportal'][$cpzone])) {
header("Location: services_captiveportal_zones.php");
exit;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
if (is_numericint($_GET['id'])) {
$id = $_GET['id'];
}
if (isset($_POST['id']) && is_numericint($_POST['id'])) {
$id = $_POST['id'];
}
if (!is_array($config['captiveportal'][$cpzone]['allowedip'])) {
$config['captiveportal'][$cpzone]['allowedip'] = array();
}
$a_allowedips =& $config['captiveportal'][$cpzone]['allowedip'];
if (isset($id) && $a_allowedips[$id]) {
$pconfig['ip'] = $a_allowedips[$id]['ip'];
$pconfig['sn'] = $a_allowedips[$id]['sn'];
$pconfig['bw_up'] = $a_allowedips[$id]['bw_up'];
$pconfig['bw_down'] = $a_allowedips[$id]['bw_down'];
$pconfig['descr'] = $a_allowedips[$id]['descr'];
}
if ($_POST) {
unset($input_errors);
$pconfig = $_POST;
/* input validation */
$reqdfields = explode(" ", "ip sn");
$reqdfieldsn = array(gettext("Allowed IP address"), gettext("Subnet mask"));
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
if ($_POST['ip'] && !is_ipaddr($_POST['ip'])) {
$input_errors[] = sprintf(gettext("A valid IP address must be specified. [%s]"), $_POST['ip']);
}
if ($_POST['sn'] && (!is_numeric($_POST['sn']) || ($_POST['sn'] < 1) || ($_POST['sn'] > 32))) {
$input_errors[] = gettext("A valid subnet mask must be specified");
}
if ($_POST['bw_up'] && !is_numeric($_POST['bw_up'])) {
$input_errors[] = gettext("Upload speed needs to be an integer");
}
if ($_POST['bw_down'] && !is_numeric($_POST['bw_down'])) {
$input_errors[] = gettext("Download speed needs to be an integer");
}
foreach ($a_allowedips as $ipent) {
if (isset($id) && ($a_allowedips[$id]) && ($a_allowedips[$id] === $ipent)) {
continue;
}
if ($ipent['ip'] == $_POST['ip']) {
$input_errors[] = sprintf("[%s] %s.", $_POST['ip'], gettext("already allowed")) ;
break ;
}
}
if (!$input_errors) {
$ip = array();
$ip['ip'] = $_POST['ip'];
$ip['sn'] = $_POST['sn'];
$ip['descr'] = $_POST['descr'];
if ($_POST['bw_up']) {
$ip['bw_up'] = $_POST['bw_up'];
}
if ($_POST['bw_down']) {
$ip['bw_down'] = $_POST['bw_down'];
}
if (isset($id) && $a_allowedips[$id]) {
$oldip = $a_allowedips[$id]['ip'];
if (!empty($a_allowedips[$id]['sn'])) {
$oldmask = $a_allowedips[$id]['sn'];
} else {
$oldmask = 32;
}
$a_allowedips[$id] = $ip;
} else {
$a_allowedips[] = $ip;
}
allowedips_sort();
write_config();
if (isset($a_cp[$cpzone]['enable']) && is_module_loaded("ipfw.ko")) {
$rules = "";
$cpzoneid = $a_cp[$cpzone]['zoneid'];
unset($ipfw);
captiveportal_allowedip_configure_entry($ip);
$uniqid = uniqid("{$cpzone}_allowed");
}
header("Location: services_captiveportal_ip.php?zone={$cpzone}");
exit;
}
}
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
} ?>
<section class="col-xs-12">
<div class="content-box">
<form action="services_captiveportal_ip_edit.php" method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td colspan="2" valign="top" class="listtopic"><?=gettext("Edit allowed ip rule");?></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("IP address"); ?></td>
<td width="78%" class="vtable">
<input name="ip" type="text" class="formfld unknown" id="ip" size="17" value="<?=htmlspecialchars($pconfig['ip']);?>" />
/<select name='sn' class="formselect" id='sn'>
<?php for ($i = 32; $i >= 1; $i--) :
?>
<option value="<?=$i;?>" <?php if ($i == $pconfig['sn']) {
echo "selected=\"selected\"";
} ?>><?=$i;?></option>
<?php
endfor; ?>
</select>
<br />
<span class="vexpl"><?=gettext("IP address and subnet mask. Use /32 for a single IP");?>.</span>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?=gettext("Description"); ?></td>
<td width="78%" class="vtable">
<input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>" />
<br /> <span class="vexpl"><?=gettext("You may enter a description here for your reference (not parsed)"); ?>.</span>
</td>
</tr>
<!--
<tr>
<td width="22%" valign="top" class="vncell"><?=gettext("Bandwidth up"); ?></td>
<td width="78%" class="vtable">
<input name="bw_up" type="text" class="formfld unknown" id="bw_up" size="10" value="<?=htmlspecialchars($pconfig['bw_up']);?>" />
<br /> <span class="vexpl"><?=gettext("Enter a upload limit to be enforced on this IP address in Kbit/s"); ?></span>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?=gettext("Bandwidth down"); ?></td>
<td width="78%" class="vtable">
<input name="bw_down" type="text" class="formfld unknown" id="bw_down" size="10" value="<?=htmlspecialchars($pconfig['bw_down']);?>" />
<br /> <span class="vexpl"><?=gettext("Enter a download limit to be enforced on this IP address in Kbit/s"); ?></span>
</td>
</tr>
-->
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
<input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Save"); ?>" />
<input name="zone" type="hidden" value="<?=htmlspecialchars($cpzone);?>" />
<?php if (isset($id) && $a_allowedips[$id]) :
?>
<input name="id" type="hidden" value="<?=htmlspecialchars($id);?>" />
<?php
endif; ?>
</td>
</tr>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -1,229 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
require_once("interfaces.inc");
global $cpzone;
global $cpzoneid;
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone) || empty($config['captiveportal'][$cpzone])) {
header("Location: services_captiveportal_zones.php");
exit;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
$pgtitle = array(gettext("Services"),gettext("Captive portal"), $a_cp[$cpzone]['zone']);
$shortcut_section = "captiveportal";
if ($_POST) {
$pconfig = $_POST;
if ($_POST['apply']) {
$retval = 0;
$rules = captiveportal_passthrumac_configure();
$savemsg = get_std_save_message();
if ($retval == 0) {
clear_subsystem_dirty('passthrumac');
}
}
if ($_POST['postafterlogin']) {
if (!is_array($a_passthrumacs)) {
echo gettext("No entry exists yet!") ."\n";
exit;
}
if (empty($_POST['zone'])) {
echo gettext("Please set the zone on which the operation should be allowed");
exit;
}
if (!is_array($a_cp[$cpzone]['passthrumac'])) {
$a_cp[$cpzone]['passthrumac'] = array();
}
$a_passthrumacs =& $a_cp[$cpzone]['passthrumac'];
if ($_POST['username']) {
$mac = captiveportal_passthrumac_findbyname($_POST['username']);
if (!empty($mac)) {
$_POST['delmac'] = $mac['mac'];
} else {
echo gettext("No entry exists for this username:") . " " . $_POST['username'] . "\n";
}
}
if ($_POST['delmac']) {
$found = false;
foreach ($a_passthrumacs as $idx => $macent) {
if ($macent['mac'] == $_POST['delmac']) {
$found = true;
break;
}
}
if ($found == true) {
$cpzoneid = $a_cp[$cpzone]['zoneid'];
captiveportal_passthrumac_delete_entry($a_passthrumacs[$idx]);
unset($a_passthrumacs[$idx]);
write_config();
echo gettext("The entry was sucessfully deleted") . "\n";
} else {
echo gettext("No entry exists for this mac address:") . " " . $_POST['delmac'] . "\n";
}
}
exit;
}
}
if ($_GET['act'] == "del") {
$a_passthrumacs =& $a_cp[$cpzone]['passthrumac'];
if ($a_passthrumacs[$_GET['id']]) {
$cpzoneid = $a_cp[$cpzone]['zoneid'];
captiveportal_passthrumac_delete_entry($a_passthrumacs[$_GET['id']]);
unset($a_passthrumacs[$_GET['id']]);
write_config();
header("Location: services_captiveportal_mac.php?zone={$cpzone}");
exit;
}
}
include("head.inc");
$main_buttons = array(
array('label'=>gettext("add host"), 'href'=>'services_captiveportal_mac_edit.php?zone='.$cpzone),
);
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($savemsg)) {
print_info_box($savemsg);
} ?>
<?php if (is_subsystem_dirty('passthrumac')) :
?><p>
<?php print_info_box_np(gettext("The captive portal MAC address configuration has been changed.<br />You must apply the changes in order for them to take effect."));?><br />
<?php
endif; ?>
<section class="col-xs-12">
<?php
$tab_array = array();
$tab_array[] = array(gettext("Captive portal(s)"), false, "services_captiveportal.php?zone={$cpzone}");
$tab_array[] = array(gettext("MAC"), true, "services_captiveportal_mac.php?zone={$cpzone}");
$tab_array[] = array(gettext("Allowed IP addresses"), false, "services_captiveportal_ip.php?zone={$cpzone}");
// Hide Allowed Hostnames as this feature is currently not supported
// $tab_array[] = array(gettext("Allowed Hostnames"), false, "services_captiveportal_hostname.php?zone={$cpzone}");
$tab_array[] = array(gettext("Vouchers"), false, "services_captiveportal_vouchers.php?zone={$cpzone}");
$tab_array[] = array(gettext("File Manager"), false, "services_captiveportal_filemanager.php?zone={$cpzone}");
display_top_tabs($tab_array, true);
?>
<div class="tab-content content-box col-xs-12">
<div class="container-fluid">
<form action="services_captiveportal_mac.php" method="post" name="iform" id="iform">
<input type="hidden" name="zone" id="zone" value="<?=htmlspecialchars($cpzone);?>" />
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td width="3%" class="list"></td>
<td width="37%" class="listhdrr"><?=gettext("MAC address"); ?></td>
<td width="50%" class="listhdr"><?=gettext("Description"); ?></td>
<td width="10%" class="list"></td>
</tr>
<?php
if (is_array($a_cp[$cpzone]['passthrumac'])) :
$i = 0;
foreach ($a_cp[$cpzone]['passthrumac'] as $mac) :
?>
<tr ondblclick="document.location='services_captiveportal_mac_edit.php?zone=<?=$cpzone;
?>&amp;id=<?=$i;?>'">
<td valign="middle" class="list nowrap">
<img src="./themes/<?= $g['theme'];
?>/images/icons/icon_<?=$mac['action'];?>.gif" width="11" height="11" border="0" alt="icon" />
</td>
<td class="listlr">
<?=$mac['mac'];?>
</td>
<td class="listbg">
<?=htmlspecialchars($mac['descr']);?>&nbsp;
</td>
<td valign="middle" class="list nowrap">
<a href="services_captiveportal_mac_edit.php?zone=<?=$cpzone;
?>&amp;id=<?=$i;?>" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-pencil"></span></a>
&nbsp;
<a href="services_captiveportal_mac.php?zone=<?=$cpzone;
?>&amp;act=del&amp;id=<?=$i;
?>" onclick="return confirm('<?=gettext("Do you really want to delete this host?"); ?>')" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-remove"></span></a>
</td>
</tr>
<?php
$i++;
endforeach;
endif;
?>
<tr>
<td colspan="3" class="list">
<span class="vexpl">
<span class="text-danger"><strong><?=gettext("Note:"); ?><br /></strong></span>
<?=gettext("Adding MAC addresses as 'pass' MACs allows them access through the captive portal automatically without being taken to the portal page."); ?>
</span>
</td>
<td class="list">&nbsp;</td>
</tr>
</table>
</div>
</form>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -1,282 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
require_once("interfaces.inc");
function passthrumacscmp($a, $b)
{
return strcmp($a['mac'], $b['mac']);
}
function passthrumacs_sort()
{
global $config, $cpzone;
usort($config['captiveportal'][$cpzone]['passthrumac'], "passthrumacscmp");
}
global $cpzone;
global $cpzoneid;
$pgtitle = array(gettext("Services"),gettext("Captive portal"),gettext("Edit MAC address rules"));
$shortcut_section = "captiveportal";
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone) || empty($config['captiveportal'][$cpzone])) {
header("Location: services_captiveportal_zones.php");
exit;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
if (is_numericint($_GET['id'])) {
$id = $_GET['id'];
}
if (isset($_POST['id']) && is_numericint($_POST['id'])) {
$id = $_POST['id'];
}
if (!is_array($a_cp[$cpzone]['passthrumac'])) {
$a_cp[$cpzone]['passthrumac'] = array();
}
$a_passthrumacs = &$a_cp[$cpzone]['passthrumac'];
if (isset($id) && $a_passthrumacs[$id]) {
$pconfig['action'] = $a_passthrumacs[$id]['action'];
$pconfig['mac'] = $a_passthrumacs[$id]['mac'];
$pconfig['bw_up'] = $a_passthrumacs[$id]['bw_up'];
$pconfig['bw_down'] = $a_passthrumacs[$id]['bw_down'];
$pconfig['descr'] = $a_passthrumacs[$id]['descr'];
$pconfig['username'] = $a_passthrumacs[$id]['username'];
}
if ($_POST) {
unset($input_errors);
$pconfig = $_POST;
/* input validation */
$reqdfields = explode(" ", "action mac");
$reqdfieldsn = array(gettext("Action"), gettext("MAC address"));
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
$_POST['mac'] = strtolower(str_replace("-", ":", $_POST['mac']));
if ($_POST['mac']) {
if (is_macaddr($_POST['mac'])) {
$iflist = get_interface_list();
foreach ($iflist as $if) {
if ($_POST['mac'] == strtolower($if['mac'])) {
$input_errors[] = sprintf(gettext("The MAC address %s belongs to a local interface, you cannot use it here."), $_POST['mac']);
break;
}
}
} else {
$input_errors[] = sprintf("%s. [%s]", gettext("A valid MAC address must be specified"), $_POST['mac']);
}
}
if ($_POST['bw_up'] && !is_numeric($_POST['bw_up'])) {
$input_errors[] = gettext("Upload speed needs to be an integer");
}
if ($_POST['bw_down'] && !is_numeric($_POST['bw_down'])) {
$input_errors[] = gettext("Download speed needs to be an integer");
}
foreach ($a_passthrumacs as $macent) {
if (isset($id) && ($a_passthrumacs[$id]) && ($a_passthrumacs[$id] === $macent)) {
continue;
}
if ($macent['mac'] == $_POST['mac']) {
$input_errors[] = sprintf("[%s] %s.", $_POST['mac'], gettext("already exists"));
break;
}
}
if (!$input_errors) {
$mac = array();
$mac['action'] = $_POST['action'];
$mac['mac'] = $_POST['mac'];
if ($_POST['bw_up']) {
$mac['bw_up'] = $_POST['bw_up'];
}
if ($_POST['bw_down']) {
$mac['bw_down'] = $_POST['bw_down'];
}
if ($_POST['username']) {
$mac['username'] = $_POST['username'];
}
$mac['descr'] = $_POST['descr'];
if (isset($id) && $a_passthrumacs[$id]) {
$oldmac = $a_passthrumacs[$id];
$a_passthrumacs[$id] = $mac;
} else {
$oldmac = $mac;
$a_passthrumacs[] = $mac;
}
passthrumacs_sort();
write_config();
if (isset($config['captiveportal'][$cpzone]['enable'])) {
$cpzoneid = $config['captiveportal'][$cpzone]['zoneid'];
captiveportal_passthrumac_delete_entry($oldmac);
captiveportal_passthrumac_configure_entry($mac);
unset($cpzoneid);
}
header("Location: services_captiveportal_mac.php?zone={$cpzone}");
exit;
}
}
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
} ?>
<section class="col-xs-12">
<div class="content-box">
<form action="services_captiveportal_mac_edit.php" method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td colspan="2" valign="top" class="listtopic"><?=gettext("Edit MAC address rules");?></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("Action"); ?></td>
<td width="78%" class="vtable">
<select name="action" class="formselect">
<?php
$actions = explode(" ", "Pass Block");
foreach ($actions as $action) :
?>
<option value="<?=strtolower($action);?>"<?php if (strtolower($action) == strtolower($pconfig['action'])) {
echo "selected=\"selected\"";
} ?>>
<?=htmlspecialchars($action);?>
</option>
<?php
endforeach;
?>
</select>
<br />
<span class="vexpl"><?=gettext("Choose what to do with packets coming from this MAC address"); ?>.</span>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("MAC address"); ?></td>
<td width="78%" class="vtable">
<input name="mac" type="text" class="formfld unknown" id="mac" size="17" value="<?=htmlspecialchars($pconfig['mac']);?>" />
<?php
$ip = getenv('REMOTE_ADDR');
$mac = `/usr/sbin/arp -an | grep {$ip} | cut -d" " -f4`;
$mac = str_replace("\n", "", $mac);
?>
<a onclick="document.forms[0].mac.value='<?=$mac?>';" href="#"><?=gettext("Copy my MAC address");?></a>
<br />
<span class="vexpl"><?=gettext("MAC address (6 hex octets separated by colons)"); ?></span></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?=gettext("Description"); ?></td>
<td width="78%" class="vtable">
<input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>" />
<br />
<span class="vexpl"><?=gettext("You may enter a description here for your reference (not parsed)"); ?>.</span>
</td>
</tr>
<!--
<tr>
<td width="22%" valign="top" class="vncell"><?=gettext("Bandwidth up"); ?></td>
<td width="78%" class="vtable">
<input name="bw_up" type="text" class="formfld unknown" id="bw_up" size="10" value="<?=htmlspecialchars($pconfig['bw_up']);?>" />
<br />
<span class="vexpl"><?=gettext("Enter a upload limit to be enforced on this MAC address in Kbit/s"); ?></span>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?=gettext("Bandwidth down"); ?></td>
<td width="78%" class="vtable">
<input name="bw_down" type="text" class="formfld unknown" id="bw_down" size="10" value="<?=htmlspecialchars($pconfig['bw_down']);?>" />
<br />
<span class="vexpl"><?=gettext("Enter a download limit to be enforced on this MAC address in Kbit/s"); ?></span>
</td>
</tr>
-->
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
<input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Save"); ?>" />
<input name="zone" type="hidden" value="<?=htmlspecialchars($cpzone);?>" />
<?php if (isset($id) && $a_passthrumacs[$id]) :
?>
<input name="id" type="hidden" value="<?=htmlspecialchars($id);?>" />
<?php
endif; ?>
<?php if (isset($pconfig['username']) && $pconfig['username']) :
?>
<input name="username" type="hidden" value="<?=htmlspecialchars($pconfig['username']);?>" />
<?php
endif; ?>
</td>
</tr>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -1,588 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
if ($_POST['postafterlogin']) {
$nocsrf = true;
}
require_once('guiconfig.inc');
require_once('interfaces.inc');
require_once('captiveportal.inc');
require_once("services.inc");
require_once("pfsense-utils.inc");
function voucher_unlink_db($roll)
{
global $cpzone;
@unlink("/var/db/voucher_{$cpzone}_used_{$roll}.db");
@unlink("/var/db/voucher_{$cpzone}_active_{$roll}.db");
}
$referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/services_captiveportal_vouchers.php');
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone)) {
header("Location: services_captiveportal_zones.php");
exit;
}
function generatekey($exponent)
{
$ret = array();
/* generate a random 64 bit RSA key pair using the voucher binary */
$fd = popen(sprintf('/usr/local/bin/voucher -g 64 -e %s', $exponent), 'r');
if ($fd !== false) {
$output = fread($fd, 16384);
pclose($fd);
list($privkey, $pubkey) = explode("\0", $output);
$ret['priv'] = $privkey;
$ret['pub'] = $pubkey;
}
return $ret;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
if (!is_array($config['voucher'])) {
$config['voucher'] = array();
}
if (empty($a_cp[$cpzone])) {
log_error("Submission on captiveportal page with unknown zone parameter: " . htmlspecialchars($cpzone));
header("Location: services_captiveportal_zones.php");
exit;
}
$pgtitle = array(gettext("Services"), gettext("Captive portal"), gettext("Vouchers"), $a_cp[$cpzone]['zone']);
$shortcut_section = "captiveportal-vouchers";
if (!is_array($config['voucher'][$cpzone]['roll'])) {
$config['voucher'][$cpzone]['roll'] = array();
}
if (!isset($config['voucher'][$cpzone]['charset'])) {
$config['voucher'][$cpzone]['charset'] = '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
}
if (!isset($config['voucher'][$cpzone]['rollbits'])) {
$config['voucher'][$cpzone]['rollbits'] = 16;
}
if (!isset($config['voucher'][$cpzone]['ticketbits'])) {
$config['voucher'][$cpzone]['ticketbits'] = 10;
}
if (!isset($config['voucher'][$cpzone]['checksumbits'])) {
$config['voucher'][$cpzone]['checksumbits'] = 5;
}
if (!isset($config['voucher'][$cpzone]['magic'])) {
$config['voucher'][$cpzone]['magic'] = rand(); // anything slightly random will do
}if (!isset($config['voucher'][$cpzone]['exponent'])) {
while (true) {
while (($exponent = rand()) % 30000 < 5000) {
continue;
}
$exponent = ($exponent * 2) + 1; // Make it odd number
if ($exponent <= 65537) {
break;
}
}
$config['voucher'][$cpzone]['exponent'] = $exponent;
unset($exponent);
}
if ($_REQUEST['generatekey']) {
$key = generatekey($config['voucher'][$cpzone]['exponent']);
$alertmessage = gettext(
'You will need to recreate any existing Voucher Rolls due ' .
'to the public and private key changes. Click cancel if you ' .
'do not wish to recreate the vouchers.'
);
echo json_encode(array(
'alertmessage' => $alertmessage,
'privatekey' => $key['priv'],
'publickey' => $key['pub'],
));
exit;
}
if (!isset($config['voucher'][$cpzone]['publickey'])) {
$key = generatekey($config['voucher'][$cpzone]['exponent']);
$config['voucher'][$cpzone]['publickey'] = base64_encode($key['pub']);
$config['voucher'][$cpzone]['privatekey'] = base64_encode($key['priv']);
}
// Check for invalid or expired vouchers
if (!isset($config['voucher'][$cpzone]['descrmsgnoaccess'])) {
$config['voucher'][$cpzone]['descrmsgnoaccess'] = gettext("Voucher invalid");
}
if (!isset($config['voucher'][$cpzone]['descrmsgexpired'])) {
$config['voucher'][$cpzone]['descrmsgexpired'] = gettext("Voucher expired");
}
$a_roll = &$config['voucher'][$cpzone]['roll'];
if ($_GET['act'] == "del") {
$id = $_GET['id'];
if ($a_roll[$id]) {
$roll = $a_roll[$id]['number'];
$voucherlck = lock("voucher{$cpzone}");
unset($a_roll[$id]);
voucher_unlink_db($roll);
unlock($voucherlck);
write_config();
}
header("Location: services_captiveportal_vouchers.php?zone={$cpzone}");
exit;
} /* print all vouchers of the selected roll */
elseif ($_GET['act'] == "csv") {
$privkey = base64_decode($config['voucher'][$cpzone]['privatekey']);
if (strstr($privkey, "BEGIN RSA PRIVATE KEY")) {
$fd = fopen("/var/etc/voucher_{$cpzone}.private", "w");
if (!$fd) {
$input_errors[] = gettext("Cannot write private key file") . ".\n";
} else {
chmod("/var/etc/voucher_{$cpzone}.private", 0600);
fwrite($fd, $privkey);
fclose($fd);
$a_voucher = &$config['voucher'][$cpzone]['roll'];
$id = $_GET['id'];
if (isset($id) && $a_voucher[$id]) {
$number = $a_voucher[$id]['number'];
$count = $a_voucher[$id]['count'];
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=vouchers_{$cpzone}_roll{$number}.csv");
if (file_exists("/var/etc/voucher_{$cpzone}.cfg")) {
system("/usr/local/bin/voucher -c /var/etc/voucher_{$cpzone}.cfg -p /var/etc/voucher_{$cpzone}.private $number $count");
}
@unlink("/var/etc/voucher_{$cpzone}.private");
} else {
header("Location: services_captiveportal_vouchers.php?zone={$cpzone}");
}
exit;
}
} else {
$input_errors[] = gettext("Need private RSA key to print vouchers") . "\n";
}
}
$pconfig['enable'] = isset($config['voucher'][$cpzone]['enable']);
$pconfig['charset'] = $config['voucher'][$cpzone]['charset'];
$pconfig['rollbits'] = $config['voucher'][$cpzone]['rollbits'];
$pconfig['ticketbits'] = $config['voucher'][$cpzone]['ticketbits'];
$pconfig['checksumbits'] = $config['voucher'][$cpzone]['checksumbits'];
$pconfig['magic'] = $config['voucher'][$cpzone]['magic'];
$pconfig['exponent'] = $config['voucher'][$cpzone]['exponent'];
$pconfig['publickey'] = base64_decode($config['voucher'][$cpzone]['publickey']);
$pconfig['privatekey'] = base64_decode($config['voucher'][$cpzone]['privatekey']);
$pconfig['msgnoaccess'] = $config['voucher'][$cpzone]['descrmsgnoaccess'];
$pconfig['msgexpired'] = $config['voucher'][$cpzone]['descrmsgexpired'];
if ($_POST) {
unset($input_errors);
if ($_POST['postafterlogin']) {
voucher_expire($_POST['voucher_expire']);
exit;
}
$pconfig = $_POST;
/* input validation */
if ($_POST['enable'] == "yes") {
$reqdfields = explode(" ", "charset rollbits ticketbits checksumbits publickey magic");
$reqdfieldsn = array(gettext("charset"),gettext("rollbits"),gettext("ticketbits"),gettext("checksumbits"),gettext("publickey"),gettext("magic"));
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
}
// Check for form errors
if ($_POST['charset'] && (strlen($_POST['charset'] < 2))) {
$input_errors[] = gettext("Need at least 2 characters to create vouchers.");
}
if ($_POST['charset'] && (strpos($_POST['charset'], "\"")>0)) {
$input_errors[] = gettext("Double quotes aren't allowed.");
}
if ($_POST['charset'] && (strpos($_POST['charset'], ",")>0)) {
$input_errors[] = "',' " . gettext("aren't allowed.");
}
if ($_POST['rollbits'] && (!is_numeric($_POST['rollbits']) || ($_POST['rollbits'] < 1) || ($_POST['rollbits'] > 31))) {
$input_errors[] = gettext("# of Bits to store Roll Id needs to be between 1..31.");
}
if ($_POST['ticketbits'] && (!is_numeric($_POST['ticketbits']) || ($_POST['ticketbits'] < 1) || ($_POST['ticketbits'] > 16))) {
$input_errors[] = gettext("# of Bits to store Ticket Id needs to be between 1..16.");
}
if ($_POST['checksumbits'] && (!is_numeric($_POST['checksumbits']) || ($_POST['checksumbits'] < 1) || ($_POST['checksumbits'] > 31))) {
$input_errors[] = gettext("# of Bits to store checksum needs to be between 1..31.");
}
if ($_POST['publickey'] && (!strstr($_POST['publickey'], "BEGIN PUBLIC KEY"))) {
$input_errors[] = gettext("This doesn't look like an RSA Public key.");
}
if ($_POST['privatekey'] && (!strstr($_POST['privatekey'], "BEGIN RSA PRIVATE KEY"))) {
$input_errors[] = gettext("This doesn't look like an RSA Private key.");
}
if ($_POST['vouchersyncdbip'] && (is_ipaddr_configured($_POST['vouchersyncdbip']))) {
$input_errors[] = gettext("You cannot sync the voucher database to this host (itself).");
}
if (!$input_errors) {
if (empty($config['voucher'][$cpzone])) {
$newvoucher = array();
} else {
$newvoucher = $config['voucher'][$cpzone];
}
if ($_POST['enable'] == "yes") {
$newvoucher['enable'] = true;
} else {
unset($newvoucher['enable']);
}
$newvoucher['charset'] = $_POST['charset'];
$newvoucher['rollbits'] = $_POST['rollbits'];
$newvoucher['ticketbits'] = $_POST['ticketbits'];
$newvoucher['checksumbits'] = $_POST['checksumbits'];
$newvoucher['magic'] = $_POST['magic'];
$newvoucher['exponent'] = $_POST['exponent'];
$newvoucher['publickey'] = base64_encode($_POST['publickey']);
$newvoucher['privatekey'] = base64_encode($_POST['privatekey']);
$newvoucher['descrmsgnoaccess'] = $_POST['msgnoaccess'];
$newvoucher['descrmsgexpired'] = $_POST['msgexpired'];
$config['voucher'][$cpzone] = $newvoucher;
write_config();
voucher_configure_zone();
if (!$input_errors) {
header("Location: services_captiveportal_vouchers.php?zone={$cpzone}");
exit;
}
}
}
$closehead = false;
include("head.inc");
if ($pconfig['enable']) {
$main_buttons = array(
array('label'=>gettext("add voucher"), 'href'=>'services_captiveportal_vouchers_edit.php?zone='.$cpzone),
);
}
?>
<body>
<script type="text/javascript">
//<![CDATA[
function generatenewkey() {
jQuery('#publickey').val('One moment please...');
jQuery('#privatekey').val('One moment please...');
jQuery.ajax("services_captiveportal_vouchers.php?zone=<?php echo($cpzone); ?>&generatekey=true", {
type: 'get',
dataType: 'json',
success: function(json) {
jQuery('#privatekey').val(json.privatekey);
jQuery('#publickey').val(json.publickey);
jQuery('#privatekey').addClass('alert-warning');
jQuery('#publickey').addClass('alert-warning');
alert(json.alertmessage);
}});
}
function before_save() {
document.iform.charset.disabled = false;
document.iform.rollbits.disabled = false;
document.iform.ticketbits.disabled = false;
document.iform.checksumbits.disabled = false;
document.iform.magic.disabled = false;
document.iform.publickey.disabled = false;
document.iform.privatekey.disabled = false;
document.iform.msgnoaccess.disabled = false;
document.iform.msgexpired.disabled = false;
for(var x=0; x < <?php echo count($a_roll); ?>; x++)
jQuery('#addeditdelete' + x).show();
jQuery('#addnewroll').show();
}
function enable_change(enable_change) {
var endis;
endis = !(document.iform.enable.checked || enable_change);
document.iform.charset.disabled = endis;
document.iform.rollbits.disabled = endis;
document.iform.ticketbits.disabled = endis;
document.iform.checksumbits.disabled = endis;
document.iform.magic.disabled = endis;
document.iform.publickey.disabled = endis;
document.iform.privatekey.disabled = endis;
document.iform.msgnoaccess.disabled = endis;
document.iform.msgexpired.disabled = endis;
for(var x=0; x < <?php echo count($a_roll); ?>; x++)
jQuery('#addeditdelete' + x).show();
jQuery('#addnewroll').show();
}
//]]>
</script>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
} ?>
<?php if (isset($savemsg)) {
print_info_box($savemsg);
} ?>
<section class="col-xs-12">
<?php
$tab_array = array();
$tab_array[] = array(gettext("Captive portal(s)"), false, "services_captiveportal.php?zone={$cpzone}");
$tab_array[] = array(gettext("MAC"), false, "services_captiveportal_mac.php?zone={$cpzone}");
$tab_array[] = array(gettext("Allowed IP addresses"), false, "services_captiveportal_ip.php?zone={$cpzone}");
// Hide Allowed Hostnames as this feature is currently not supported
// $tab_array[] = array(gettext("Allowed Hostnames"), false, "services_captiveportal_hostname.php?zone={$cpzone}");
$tab_array[] = array(gettext("Vouchers"), true, "services_captiveportal_vouchers.php?zone={$cpzone}");
$tab_array[] = array(gettext("File Manager"), false, "services_captiveportal_filemanager.php?zone={$cpzone}");
display_top_tabs($tab_array, true);
?>
<div class="tab-content content-box col-xs-12">
<div class="container-fluid">
<form action="services_captiveportal_vouchers.php" method="post" name="iform" id="iform">
<input type="hidden" name="zone" id="zone" value="<?=htmlspecialchars($cpzone);?>" />
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td width="22%" valign="top" class="vtable">&nbsp;</td>
<td width="78%" class="vtable">
<input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) {
echo "checked=\"checked\"";
} ?> onclick="enable_change(false)" />
<strong><?=gettext("Enable Vouchers"); ?></strong>
</td>
</tr>
<tr>
<td valign="top" class="vncell">
<?=gettext("Voucher Rolls"); ?>
</td>
<td class="vtable">
<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="content pane">
<tr>
<td width="10%" class="listhdrr"><?=gettext("Roll"); ?> #</td>
<td width="20%" class="listhdrr"><?=gettext("Minutes/Ticket"); ?></td>
<td width="20%" class="listhdrr"># <?=gettext("of Tickets"); ?></td>
<td width="35%" class="listhdr"><?=gettext("Comment"); ?></td>
<td width="15%" class="list"></td>
</tr>
<?php $i = 0; foreach ($a_roll as $rollent) :
?>
<tr>
<td class="listlr">
<?=htmlspecialchars($rollent['number']); ?>&nbsp;
</td>
<td class="listr">
<?=htmlspecialchars($rollent['minutes']);?>&nbsp;
</td>
<td class="listr">
<?=htmlspecialchars($rollent['count']);?>&nbsp;
</td>
<td class="listr">
<?=htmlspecialchars($rollent['descr']); ?>&nbsp;
</td>
<td valign="middle" class="list nowrap">
<div id='addeditdelete<?=$i?>'>
<?php if ($pconfig['enable']) :
?>
<a class="btn btn-default btn-xs" href="services_captiveportal_vouchers_edit.php?zone=<?=$cpzone;
?>&amp;id=<?=$i;
?>"><span class="glyphicon glyphicon-pencil" title="<?=gettext("edit voucher");
?>" alt="<?=gettext("edit voucher"); ?>" ></span></a>
<a class="btn btn-default btn-xs" href="services_captiveportal_vouchers.php?zone=<?=$cpzone;
?>&amp;act=del&amp;id=<?=$i;
?>" onclick="return confirm('<?=gettext("Do you really want to delete this voucher? This makes all vouchers from this roll invalid");
?>')"><span class="glyphicon glyphicon-remove" title="<?=gettext("delete vouchers");
?>" alt="<?=gettext("delete vouchers"); ?>"></span></a>
<a class="btn btn-default btn-xs" href="services_captiveportal_vouchers.php?zone=<?=$cpzone;
?>&amp;act=csv&amp;id=<?=$i;
?>"><span class="glyphicon glyphicon-download-alt" title="<?=gettext("generate vouchers for this roll to CSV file");
?>" alt="<?=gettext("generate vouchers for this roll to CSV file"); ?>"></span></a>
<?php
endif;?>
</div>
</td>
</tr>
<?php $i++;
endforeach; ?>
</table>
<?php if ($pconfig['enable']) :
?>
<?=gettext("Create, generate and activate Rolls with Vouchers that allow access through the " .
"captive portal for the configured time. Once a voucher is activated, " .
"its clock is started and runs uninterrupted until it expires. During that " .
"time, the voucher can be re-used from the same or a different computer. If the voucher " .
"is used again from another computer, the previous session is stopped."); ?>
<?php
else :
?>
<?=gettext("Enable Voucher support first using the checkbox above and hit Save at the bottom."); ?>
<?php
endif;?>
</td>
</tr>
<tr>
<td valign="top" class="vncellreq">
<?=gettext("Voucher public key"); ?>
</td>
<td class="vtable">
<textarea name="publickey" cols="65" rows="4" id="publickey" class="formpre"><?=htmlspecialchars($pconfig['publickey']);?></textarea>
<br />
<?=gettext("Paste an RSA public key (64 Bit or smaller) in PEM format here. This key is used to decrypt vouchers.");
?> <a href='#' onclick='generatenewkey();'><?=gettext('Generate');
?></a> <?=gettext('new key');?>.</td>
</tr>
<tr>
<td valign="top" class="vncell"><?=gettext("Voucher private key"); ?></td>
<td class="vtable">
<textarea name="privatekey" cols="65" rows="5" id="privatekey" class="formpre"><?=htmlspecialchars($pconfig['privatekey']);?></textarea>
<br />
<?=gettext("Paste an RSA private key (64 Bit or smaller) in PEM format here. This key is only used to generate encrypted vouchers and doesn't need to be available if the vouchers have been generated offline.");
?> <a href='#' onclick='generatenewkey();'> <?=gettext('Generate');
?></a> <?=gettext('new key');?>.</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("Character set"); ?></td>
<td width="78%" class="vtable">
<input name="charset" type="text" class="formfld" id="charset" size="80" value="<?=htmlspecialchars($pconfig['charset']);?>" />
<br />
<?=gettext("Tickets are generated with the specified character set. It should contain printable characters (numbers, lower case and upper case letters) that are hard to confuse with others. Avoid e.g. 0/O and l/1."); ?>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"># <?=gettext("of Roll Bits"); ?></td>
<td width="78%" class="vtable">
<input name="rollbits" type="text" class="formfld" id="rollbits" size="2" value="<?=htmlspecialchars($pconfig['rollbits']);?>" />
<br />
<?=gettext("Reserves a range in each voucher to store the Roll # it belongs to. Allowed range: 1..31. Sum of Roll+Ticket+Checksum bits must be one Bit less than the RSA key size."); ?>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"># <?=gettext("of Ticket Bits"); ?></td>
<td width="78%" class="vtable">
<input name="ticketbits" type="text" class="formfld" id="ticketbits" size="2" value="<?=htmlspecialchars($pconfig['ticketbits']);?>" />
<br />
<?=gettext("Reserves a range in each voucher to store the Ticket# it belongs to. Allowed range: 1..16. Using 16 bits allows a roll to have up to 65535 vouchers. A bit array, stored in RAM and in the config, is used to mark if a voucher has been used. A bit array for 65535 vouchers requires 8 KB of storage."); ?>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"># <?=gettext("of Checksum Bits"); ?></td>
<td width="78%" class="vtable">
<input name="checksumbits" type="text" class="formfld" id="checksumbits" size="2" value="<?=htmlspecialchars($pconfig['checksumbits']);?>" />
<br />
<?=gettext("Reserves a range in each voucher to store a simple checksum over Roll # and Ticket#. Allowed range is 0..31."); ?>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("Magic Number"); ?></td>
<td width="78%" class="vtable">
<input name="magic" type="text" class="formfld" id="magic" size="20" value="<?=htmlspecialchars($pconfig['magic']);?>" />
<br />
<?=gettext("Magic number stored in every voucher. Verified during voucher check. Size depends on how many bits are left by Roll+Ticket+Checksum bits. If all bits are used, no magic number will be used and checked."); ?>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("Invalid Voucher Message"); ?></td>
<td width="78%" class="vtable">
<input name="msgnoaccess" type="text" class="formfld" id="msgnoaccess" size="80" value="<?=htmlspecialchars($pconfig['msgnoaccess']);?>" />
<br /><?=gettext("Error message displayed for invalid vouchers on captive portal error page"); ?> ($PORTAL_MESSAGE$).
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("Expired Voucher Message"); ?></td>
<td width="78%" class="vtable">
<input name="msgexpired" type="text" class="formfld" id="msgexpired" size="80" value="<?=htmlspecialchars($pconfig['msgexpired']);?>" />
<br /><?=gettext("Error message displayed for expired vouchers on captive portal error page"); ?> ($PORTAL_MESSAGE$).
</td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
&nbsp;
</td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
<input type="hidden" name="zone" id="zone" value="<?=htmlspecialchars($cpzone);?>" />
<input type="hidden" name="exponent" id="exponent" value="<?=$pconfig['exponent'];?>" />
<input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Save"); ?>" onclick="enable_change(true); before_save();" />
<input type="button" class="btn btn-default" value="<?=gettext("Cancel");
?>" onclick="window.location.href='<?=$referer;?>'" />
</td>
</tr>
<tr>
<td colspan="2" class="list"><p class="vexpl">
<span class="red"><strong> <?=gettext("Note:"); ?><br /> </strong></span>
<?=gettext("Changing any Voucher parameter (apart from managing the list of Rolls) on this page will render existing vouchers useless if they were generated with different settings."); ?>
<br />
<?=gettext("Specifying the Voucher Database Synchronization options will not record any other value from the other options. They will be retrieved/synced from the master."); ?>
</p>
</td>
</tr>
</table>
</div>
</form>
</div>
</div>
</section>
</div>
</div>
</section>
<script type="text/javascript">
//<![CDATA[
enable_change(false);
//]]>
</script>
<?php include("foot.inc");

View File

@ -1,245 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
$pgtitle = array(gettext("Services"), gettext("Captive portal"), gettext("Edit Voucher Rolls"));
$shortcut_section = "captiveportal-vouchers";
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone) || empty($config['captiveportal'][$cpzone])) {
header("Location: services_captiveportal_zones.php");
exit;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
if (!is_array($config['voucher'])) {
$config['voucher'] = array();
}
if (!is_array($config['voucher'][$cpzone]['roll'])) {
$config['voucher'][$cpzone]['roll'] = array();
}
$a_roll = &$config['voucher'][$cpzone]['roll'];
if (is_numericint($_GET['id'])) {
$id = $_GET['id'];
}
if (isset($_POST['id']) && is_numericint($_POST['id'])) {
$id = $_POST['id'];
}
if (isset($id) && $a_roll[$id]) {
$pconfig['zone'] = $a_roll[$id]['zone'];
$pconfig['number'] = $a_roll[$id]['number'];
$pconfig['count'] = $a_roll[$id]['count'];
$pconfig['minutes'] = $a_roll[$id]['minutes'];
$pconfig['descr'] = $a_roll[$id]['descr'];
}
$maxnumber = (1<<$config['voucher'][$cpzone]['rollbits']) -1; // Highest Roll#
$maxcount = (1<<$config['voucher'][$cpzone]['ticketbits']) -1; // Highest Ticket#
if ($_POST) {
unset($input_errors);
$pconfig = $_POST;
/* input validation */
$reqdfields = explode(" ", "number count minutes");
$reqdfieldsn = array(gettext("Number"),gettext("Count"),gettext("minutes"));
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
// Look for duplicate roll #
foreach ($a_roll as $re) {
if ($re['number'] == $_POST['number']) {
$input_errors[] = sprintf(gettext("Roll number %s already exists."), $_POST['number']);
break;
}
}
if (!is_numeric($_POST['number']) || $_POST['number'] >= $maxnumber) {
$input_errors[] = sprintf(gettext("Roll number must be numeric and less than %s"), $maxnumber);
}
if (!is_numeric($_POST['count']) || $_POST['count'] < 1 || $_POST['count'] > $maxcount) {
$input_errors[] = sprintf(gettext("A roll has at least one voucher and less than %s."), $maxcount);
}
if (!is_numeric($_POST['minutes']) || $_POST['minutes'] < 1) {
$input_errors[] = gettext("Each voucher must be good for at least 1 minute.");
}
if (!$input_errors) {
if (isset($id) && $a_roll[$id]) {
$rollent = $a_roll[$id];
}
$rollent['zone'] = $_POST['zone'];
$rollent['number'] = $_POST['number'];
$rollent['minutes'] = $_POST['minutes'];
$rollent['descr'] = $_POST['descr'];
/* New Roll or modified voucher count: create bitmask */
$voucherlck = lock("voucher{$cpzone}");
if ($_POST['count'] != $rollent['count']) {
$rollent['count'] = $_POST['count'];
$len = ($rollent['count']>>3) + 1; // count / 8 +1
$rollent['used'] = base64_encode(str_repeat("\000", $len)); // 4 bitmask
$rollent['active'] = array();
voucher_write_used_db($rollent['number'], $rollent['used']);
voucher_write_active_db($rollent['number'], array()); // create empty DB
voucher_log(LOG_INFO, sprintf(gettext('All %1$s vouchers from Roll %2$s marked unused'), $rollent['count'], $rollent['number']));
} else {
// existing roll has been modified but without changing the count
// read active and used DB from ramdisk and store it in XML config
$rollent['used'] = base64_encode(voucher_read_used_db($rollent['number']));
$activent = array();
$db = array();
$active_vouchers = voucher_read_active_db($rollent['number'], $rollent['minutes']);
foreach ($active_vouchers as $voucher => $line) {
list($timestamp, $minutes) = explode(",", $line);
$activent['voucher'] = $voucher;
$activent['timestamp'] = $timestamp;
$activent['minutes'] = $minutes;
$db[] = $activent;
}
$rollent['active'] = $db;
}
unlock($voucherlck);
if (isset($id) && $a_roll[$id]) {
$a_roll[$id] = $rollent;
} else {
$a_roll[] = $rollent;
}
write_config();
header("Location: services_captiveportal_vouchers.php?zone={$cpzone}");
exit;
}
}
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
} ?>
<?php if (isset($savemsg)) {
print_info_box($savemsg);
} ?>
<section class="col-xs-12">
<div class="content-box">
<form action="services_captiveportal_vouchers_edit.php" method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("Roll"); ?>#</td>
<td width="78%" class="vtable">
<input name="number" type="text" class="formfld" id="number" size="10" value="<?=htmlspecialchars($pconfig['number']);?>" />
<br />
<span class="vexpl"><?=gettext("Enter the Roll");
?># (0..<?=htmlspecialchars($maxnumber);
?>) <?=gettext("found on top of the generated/printed vouchers"); ?>.</span>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("Minutes per Ticket"); ?></td>
<td width="78%" class="vtable">
<input name="minutes" type="text" class="formfld" id="minutes" size="10" value="<?=htmlspecialchars($pconfig['minutes']);?>" />
<br />
<span class="vexpl"><?=gettext("Defines the time in minutes that a user is allowed access. The clock starts ticking the first time a voucher is used for authentication"); ?>.</span>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("Count"); ?></td>
<td width="78%" class="vtable">
<input name="count" type="text" class="formfld" id="count" size="10" value="<?=htmlspecialchars($pconfig['count']);?>" />
<br />
<span class="vexpl"><?=gettext("Enter the number of vouchers");
?> (1..<?=htmlspecialchars($maxcount);
?>) <?=gettext("found on top of the generated/printed vouchers. WARNING: Changing this number for an existing Roll will mark all vouchers as unused again"); ?>.</span>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?=gettext("Comment"); ?></td>
<td width="78%" class="vtable">
<input name="descr" type="text" class="formfld" id="descr" size="60" value="<?=htmlspecialchars($pconfig['descr']);?>" />
<br />
<span class="vexpl"><?=gettext("Can be used to further identify this roll. Ignored by the system"); ?>.</span>
</td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
<input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Save"); ?>" />
<input name="zone" type="hidden" value="<?=htmlspecialchars($cpzone);?>" />
<?php if (isset($id) && $a_roll[$id]) :
?>
<input name="id" type="hidden" value="<?=htmlspecialchars($id);?>" />
<?php
endif; ?>
</td>
</tr>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -1,144 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
require_once("system.inc");
require_once("interfaces.inc");
global $cpzone;
global $cpzoneid;
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp = &$config['captiveportal'];
if ($_GET['act'] == "del" && !empty($_GET['zone'])) {
$cpzone = $_GET['zone'];
if ($a_cp[$cpzone]) {
$cpzoneid = $a_cp[$cpzone]['zoneid'];
unset($a_cp[$cpzone]['enable']);
unset($a_cp[$cpzone]);
if (isset($config['voucher'][$cpzone])) {
unset($config['voucher'][$cpzone]);
}
write_config();
captiveportal_configure();
header("Location: services_captiveportal_zones.php");
exit;
}
}
$pgtitle = array(gettext("Captiveportal"),gettext("Zones"));
$shortcut_section = "captiveportal";
include("head.inc");
$main_buttons = array(
array('href'=>'services_captiveportal_zones_edit.php', 'label'=>gettext("add a new captiveportal instance")),
);
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($savemsg)) {
print_info_box($savemsg);
} ?>
<?php if (is_subsystem_dirty('captiveportal')) :
?><p>
<?php print_info_box_np(gettext("The CaptivePortal entry list has been changed") . ".<br />" . gettext("You must apply the changes in order for them to take effect."));?>
<?php
endif; ?>
<section class="col-xs-12">
<div class="content-box">
<form action="services_captiveportal_zones.php" method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td width="15%" class="listhdrr"><?=gettext("Zone");?></td>
<td width="30%" class="listhdrr"><?=gettext("Interfaces");?></td>
<td width="10%" class="listhdrr"><?=gettext("Users");?></td>
<td width="35%" class="listhdrr"><?=gettext("Description");?></td>
<td width="10%" class="list">
</td>
</tr>
<?php foreach ($a_cp as $cpzone => $cpitem) :
if (!is_array($cpitem)) {
continue;
}
?>
<tr>
<td class="listlr" ondblclick="document.location='services_captiveportal.php?zone=<?=$cpzone;?>';">
<?=htmlspecialchars($cpitem['zone']);?>
</td>
<td class="listlr" ondblclick="document.location='services_captiveportal.php?zone=<?=$cpzone;?>';">
<?php $cpifaces = explode(",", $cpitem['interface']);
foreach ($cpifaces as $cpiface) {
echo convert_friendly_interface_to_friendly_descr($cpiface) . " ";
}
?>
</td>
<td class="listr" ondblclick="document.location='services_captiveportal.php?zone=<?=$cpzone;?>';">
<?php
$cpdb = new OPNsense\CaptivePortal\DB($cpzone) ;
echo $cpdb->countClients() ;
?>
</td>
<td class="listbg" ondblclick="document.location='services_captiveportal.php?zone=<?=$cpzone;?>';">
<?=htmlspecialchars($cpitem['descr']);?>&nbsp;
</td>
<td valign="middle" class="list nowrap">
<a href="services_captiveportal.php?zone=<?=$cpzone?>" title="<?=gettext("edit captiveportal instance"); ?>" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-pencil"></span></a>
<a href="services_captiveportal_zones.php?act=del&amp;zone=<?=$cpzone;
?>" onclick="return confirm('<?=gettext("Do you really want to delete this entry?");
?>')" title="<?=gettext("delete captiveportal instance");?>" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-remove"></span></a>
</td>
</tr>
<?php
endforeach; ?>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -1,135 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2011 Ermal Luci
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
require_once("interfaces.inc");
$pgtitle = array(gettext("Services"),gettext("Captive portal"),gettext("Edit Zones"));
$shortcut_section = "captiveportal";
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
if ($_POST) {
unset($input_errors);
$pconfig = $_POST;
/* input validation */
$reqdfields = explode(" ", "zone");
$reqdfieldsn = array(gettext("Zone name"));
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
if (preg_match('/[^A-Za-z0-9_]/', $_POST['zone'])) {
$input_errors[] = gettext("The zone name can only contain letters, digits, and underscores (_).");
}
foreach ($a_cp as $cpkey => $cpent) {
if ($cpent['zone'] == $_POST['zone']) {
$input_errors[] = sprintf("[%s] %s.", $_POST['zone'], gettext("already exists"));
break;
}
}
if (!$input_errors) {
$cpzone = strtolower($_POST['zone']);
$a_cp[$cpzone] = array();
$a_cp[$cpzone]['zone'] = str_replace(" ", "", $_POST['zone']);
$a_cp[$cpzone]['descr'] = $_POST['descr'];
$a_cp[$cpzone]['localauth_priv'] = true;
write_config();
header("Location: services_captiveportal.php?zone={$cpzone}");
exit;
}
}
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
} ?>
<section class="col-xs-12">
<div class="content-box">
<header class="content-box-head container-fluid">
<h3><?=gettext("Edit Captiveportal Zones");?></h3>
</header>
<div class="content-box-main">
<div class="table-responsive">
<form action="services_captiveportal_zones_edit.php" method="post" name="iform" id="iform">
<table class="table table-striped table-sort">
<tr>
<td width="22%" valign="top" class="vncellreq"><?=gettext("Zone name"); ?></td>
<td width="78%" class="vtable">
<input name="zone" type="text" class="form-control unknown" id="zone" size="64" />
<br />
<span class="vexpl"><?=gettext("Zone name. Can only contain letters, digits, and underscores (_)."); ?></span>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?=gettext("Description"); ?></td>
<td width="78%" class="vtable">
<input name="descr" type="text" class="form-control unknown" id="descr" size="40" />
<br />
<span class="vexpl"><?=gettext("You may enter a description here for your reference (not parsed)"); ?>.</span>
</td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
<input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Continue"); ?>" />
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -239,25 +239,6 @@ if (isset($_POST['submit'])) {
if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60)))
$input_errors[] = gettext("The default lease time must be at least 60 seconds.");
if (isset($config['captiveportal']) && is_array($config['captiveportal'])) {
$deftime = 7200; // Default value if it's empty
if (is_numeric($_POST['deftime']))
$deftime = $_POST['deftime'];
foreach ($config['captiveportal'] as $cpZone => $cpdata) {
if (!isset($cpdata['enable']))
continue;
if (!isset($cpdata['timeout']) || !is_numeric($cpdata['timeout']))
continue;
$cp_ifs = explode(',', $cpdata['interface']);
if (!in_array($if, $cp_ifs))
continue;
if ($cpdata['timeout'] > $deftime)
$input_errors[] = sprintf(gettext(
"The Captive Portal zone '%s' has Hard Timeout parameter set to a value bigger than Default lease time (%s)."), $cpZone, $deftime);
}
}
if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime'])))
$input_errors[] = gettext("The maximum lease time must be at least 60 seconds and higher than the default lease time.");
if (($_POST['ddnsdomain'] && !is_domain($_POST['ddnsdomain'])))

View File

@ -76,12 +76,6 @@ function get_shortcut_main_link($shortcut_section, $addspace = true, $service =
else
$link = $shortcuts[$shortcut_section]['main'];
break;
case "captiveportal":
if (!empty($service['zone']))
$link = "services_captiveportal.php?zone={$service['zone']}";
else
$link = $shortcuts[$shortcut_section]['main'];
break;
default:
$link = $shortcuts[$shortcut_section]['main'];
break;
@ -94,35 +88,29 @@ function get_shortcut_main_link($shortcut_section, $addspace = true, $service =
}
}
function get_shortcut_status_link($shortcut_section, $addspace = true, $service = array()) {
global $g, $shortcuts, $cpzone;
if(empty($shortcut_section))
return "";
$space = ($addspace) ? "&nbsp;" : "" ;
if (!empty($cpzone))
$zone = $cpzone;
elseif (!empty($service['zone']))
$zone = $service['zone'];
switch ($shortcut_section) {
case "captiveportal":
if (!empty($zone))
$link = "status_captiveportal.php?zone={$zone}";
else
$link = $shortcuts[$shortcut_section]['status'];
break;
default:
if (isset($shortcuts[$shortcut_section]['status'])) {
$link = $shortcuts[$shortcut_section]['status'];
} else {
$link = null;
}
break;
function get_shortcut_status_link($shortcut_section, $addspace = true, $service = array())
{
global $g, $shortcuts;
if (empty($shortcut_section)) {
return '';
}
if(!empty($link))
if (strtok($_SERVER['REQUEST_URI'],'?') != "/status_services.php")
$space = ($addspace) ? "&nbsp;" : "" ;
if (isset($shortcuts[$shortcut_section]['status'])) {
$link = $shortcuts[$shortcut_section]['status'];
} else {
$link = null;
}
if (!empty($link)) {
if (strtok($_SERVER['REQUEST_URI'],'?') != "/status_services.php") {
return "{$space}<a href=\"{$link}\" title=\"" . gettext("Status of items on this page") . "\">Status</a>";
else
} else {
return "{$space}<a href=\"{$link}\" class=\"btn btn-default\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"" . gettext("Status of items on this page") . "\"><span class=\"glyphicon glyphicon-eye-open\"></span></a>";
}
}
}
function get_shortcut_log_link($shortcut_section, $addspace = true) {
@ -155,17 +143,6 @@ $shortcuts['relayd-virtualservers']['log'] = "diag_logs_relayd.php";
$shortcuts['relayd-virtualservers']['status'] = "status_lb_vs.php";
$shortcuts['relayd-virtualservers']['service'] = "relayd";
$shortcuts['captiveportal'] = array();
$shortcuts['captiveportal']['main'] = "services_captiveportal_zones.php";
$shortcuts['captiveportal']['log'] = "diag_logs_auth.php";
$shortcuts['captiveportal']['status'] = "status_captiveportal.php";
$shortcuts['captiveportal']['service'] = "captiveportal";
$shortcuts['captiveportal-vouchers'] = array();
$shortcuts['captiveportal-vouchers']['log'] = "diag_logs_auth.php";
$shortcuts['captiveportal-vouchers']['status'] = "status_captiveportal_vouchers.php";
$shortcuts['captiveportal-vouchers']['service'] = "captiveportal";
$shortcuts['dhcp'] = array();
$shortcuts['dhcp']['main'] = "services_dhcp.php";
$shortcuts['dhcp']['log'] = "diag_logs_dhcp.php";

View File

@ -119,9 +119,7 @@ defCmdT("top | head -n5", "/usr/bin/top | /usr/bin/head -n5");
defCmdT("sysctl hw.physmem","/sbin/sysctl hw.physmem");
if (isset($config['captiveportal'])) {
defCmdT("ipfw show", "/sbin/ipfw show");
}
defCmdT("ipfw show", "/sbin/ipfw show");
defCmdT("pfctl -sn", "/sbin/pfctl -sn");
defCmdT("pfctl -sr", "/sbin/pfctl -sr");

View File

@ -1,227 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
require_once("pfsense-utils.inc");
require_once("interfaces.inc");
$cpzone = $_GET['zone'];
if (isset($_POST['zone']))
$cpzone = $_POST['zone'];
if ($_GET['act'] == "del" && !empty($cpzone)) {
captiveportal_disconnect_client($_GET['id']);
header("Location: status_captiveportal.php?zone={$cpzone}");
exit;
}
$pgtitle = array(gettext("Status: Captive portal"));
$shortcut_section = "captiveportal";
if (!is_array($config['captiveportal']))
$config['captiveportal'] = array();
$a_cp =& $config['captiveportal'];
if (count($a_cp) == 1)
$cpzone = current(array_keys($a_cp));
include("head.inc");
?>
<?php
flush();
function clientcmp($a, $b) {
global $order;
return strcmp($a[$order], $b[$order]);
}
if (!empty($cpzone)) {
$cpdb_handle = new OPNsense\CaptivePortal\DB($cpzone);
$cpclient_handle = new OPNsense\CaptivePortal\CPClient();
$order = "";
if ($_GET['order']) {
if ($_GET['order'] == "ip") $order = "ip";
else if ($_GET['order'] == "mac") $order = "mac";
else if ($_GET['order'] == "user") $order = "username";
}
$cpdb = $cpdb_handle->listClients(array(),"and",array($order) ) ;
if ($_GET['showact']) {
$accounting_info = $cpclient_handle->listAccounting();
}
else {
$accounting_info = array() ;
}
}
else {
$cpdb = array() ;
}
// Load MAC-Manufacturer table
$mac_man = load_mac_manufacturer_table();
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<section class="col-xs-12">
<?php if (!empty($cpzone) && isset($config['voucher'][$cpzone]['enable'])): ?>
<?php
$tab_array = array();
$tab_array[] = array(gettext("Active Users"), true, "status_captiveportal.php?zone={$cpzone}");
$tab_array[] = array(gettext("Active Vouchers"), false, "status_captiveportal_vouchers.php?zone={$cpzone}");
$tab_array[] = array(gettext("Voucher Rolls"), false, "status_captiveportal_voucher_rolls.php?zone={$cpzone}");
$tab_array[] = array(gettext("Test Vouchers"), false, "status_captiveportal_test.php?zone={$cpzone}");
$tab_array[] = array(gettext("Expire Vouchers"), false, "status_captiveportal_expire.php?zone={$cpzone}");
display_top_tabs($tab_array);
?>
<?php endif; ?>
<div class="tab-content content-box col-xs-12">
<div class="container-fluid">
<form action="<?=$_SERVER['REQUEST_URI'];?>" method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td width="20%" class="vncell" valign="top">
<br /><?=gettext("Captive Portal Zone"); ?><br/><br />
</td>
<td class="vncell" width="30%" align="center">
<?php if (count($a_cp) > 1) { ?>
<form action="status_captiveportal.php" method="post" enctype="multipart/form-data" name="form1" id="form1">
<select name="zone" class="formselect" onchange="document.form1.submit()">
<option value="">none</option>
<?php foreach ($a_cp as $cpkey => $cp) {
echo "<option value=\"{$cpkey}\" ";
if ($cpzone == $cpkey)
echo "selected=\"selected\"";
echo ">" . htmlspecialchars($cp['zone']) . "</option>\n";
}
?>
</select>
<br />
</form>
<?php } else echo $a_cp[$cpzone]['zone']; ?>
</td>
<td colspan="6" width="50%"></td>
</tr>
<tr><td colspan="6"><br /></td></tr>
<?php if (!empty($cpzone)): ?>
<tr>
<td colspan="7" valign="top" class="listtopic"><?=gettext("Captiveportal status");?></td>
</tr>
<tr>
<td class="listhdrr"><a href="?zone=<?=$cpzone?>&amp;order=ip&amp;showact=<?=htmlspecialchars($_GET['showact']);?>"><?=gettext("IP address");?></a></td>
<td class="listhdrr"><a href="?zone=<?=$cpzone?>&amp;order=mac&amp;showact=<?=htmlspecialchars($_GET['showact']);?>"><?=gettext("MAC address");?></a></td>
<td class="listhdrr"><a href="?zone=<?=$cpzone?>&amp;order=user&amp;showact=<?=htmlspecialchars($_GET['showact']);?>"><?=gettext("Username");?></a></td>
<?php if ($_GET['showact']): ?>
<td class="listhdrr"><a href="?zone=<?=$cpzone?>&amp;order=start&amp;showact=<?=htmlspecialchars($_GET['showact']);?>"><?=gettext("Session start");?></a></td>
<td class="listhdr"><a href="?zone=<?=$cpzone?>&amp;order=lastact&amp;showact=<?=htmlspecialchars($_GET['showact']);?>"><?=gettext("Last activity");?></a></td>
<?php else: ?>
<td class="listhdr" colspan="2"><a href="?zone=<?=$cpzone?>&amp;order=start&amp;showact=<?=htmlspecialchars($_GET['showact']);?>"><?=gettext("Session start");?></a></td>
<?php endif; ?>
<td class="list sort_ignore"></td>
</tr>
<?php foreach ($cpdb as $cpent): ?>
<tr>
<td class="listlr"><?=$cpent->ip;?></td>
<td class="listr">
<?php
$mac=trim($cpent->mac);
if (!empty($mac)) {
$mac_hi = strtoupper($mac[0] . $mac[1] . $mac[3] . $mac[4] . $mac[6] . $mac[7]);
print htmlentities($mac);
if(isset($mac_man[$mac_hi])){ print "<br /><font size=\"-2\"><i>{$mac_man[$mac_hi]}</i></font>"; }
}
?>&nbsp;
</td>
<td class="listr"><?=htmlspecialchars($cpent->username);?>&nbsp;</td>
<td class="listr"><?=htmlspecialchars(date("m/d/Y H:i:s", $cpent->allow_time));?></td>
<?php if ($_GET['showact']):
if ( array_key_exists($cpent->ip,$accounting_info) ) $last_act = $accounting_info[$cpent->ip]['last_accessed'] ;
else $last_act=0;
?>
<td class="listr"><?php if ($last_act != 0) echo htmlspecialchars(date("m/d/Y H:i:s", $last_act));?></td>
<?php else: ?>
<td class="listr" colspan="2"></td>
<?php endif; ?>
<td valign="middle" class="list nowrap">
<a class="btn btn-default btn-xs" href="?zone=<?=$cpzone;?>&amp;order=<?=$_GET['order'];?>&amp;showact=<?=htmlspecialchars($_GET['showact']);?>&amp;act=del&amp;id=<?=$cpent->sessionid;?>" onclick="return confirm('<?=gettext("Do you really want to disconnect this client?");?>')" title="<?=gettext("Disconnect");?>"><span class="glyphicon glyphicon-remove"></span></a>
</td>
</tr>
<?php endforeach; endif; ?>
</table>
</div>
</form>
<form action="status_captiveportal.php" method="get" style="margin: 14px;">
<input type="hidden" name="order" value="<?=htmlspecialchars($_GET['order']);?>" />
<?php if (!empty($cpzone)): ?>
<?php if ($_GET['showact']): ?>
<input type="hidden" name="showact" value="0" />
<input type="submit" class="btn btn-primary" value="<?=gettext("Don't show last activity");?>" />
<?php else: ?>
<input type="hidden" name="showact" value="1" />
<input type="submit" class="btn btn-primary" value="<?=gettext("Show last activity");?>" />
<?php endif; ?>
<input type="hidden" name="zone" value="<?=htmlspecialchars($cpzone);?>" />
<?php endif; ?>
</form>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc"); ?>

View File

@ -1,126 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone)) {
header("Location: status_captiveportal.php");
exit;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
$pgtitle = array(gettext("Status"), gettext("Captive portal"), gettext("Expire Vouchers"), $a_cp[$cpzone]['zone']);
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<section class="col-xs-12">
<?php
$tab_array = array();
$tab_array[] = array(gettext("Active Users"), false, "status_captiveportal.php?zone={$cpzone}");
$tab_array[] = array(gettext("Active Vouchers"), false, "status_captiveportal_vouchers.php?zone={$cpzone}");
$tab_array[] = array(gettext("Voucher Rolls"), false, "status_captiveportal_voucher_rolls.php?zone={$cpzone}");
$tab_array[] = array(gettext("Test Vouchers"), false, "status_captiveportal_test.php?zone={$cpzone}");
$tab_array[] = array(gettext("Expire Vouchers"), true, "status_captiveportal_expire.php?zone={$cpzone}");
display_top_tabs($tab_array);
?>
<div class="tab-content content-box col-xs-12">
<div class="container-fluid">
<form action="status_captiveportal_expire.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td valign="top" class="vncellreq"><?=gettext("Voucher(s)"); ?></td>
<td class="vtable">
<textarea name="vouchers" cols="65" rows="3" id="vouchers" class="formpre"><?=htmlspecialchars($_POST['vouchers']);?></textarea>
<br />
<?=gettext("Enter multiple vouchers separated by space or newline. All valid vouchers will be marked as expired"); ?>.</td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
<input name="zone" type="hidden" value="<?=htmlspecialchars($cpzone);?>" />
<input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Submit"); ?>" />
</td>
</tr>
</table>
<?php
if ($_POST) {
if ($_POST['vouchers']) {
$result = voucher_expire($_POST['vouchers']);
echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"4\" width=\"100%\" summary=\"results\">\n";
if ($result) {
echo "<tr><td bgcolor=\"#D9DEE8\"><img src=\"/themes/{$g['theme']}/images/icons/icon_pass.gif\" alt=\"pass\" /></td>";
echo "<td bgcolor=\"#D9DEE8\">Success</td></tr>";
} else {
echo "<tr><td bgcolor=\"#FFD9D1\"><img src=\"/themes/{$g['theme']}/images/icons/icon_block.gif\" alt=\"block\" /></td>";
echo "<td bgcolor=\"#FFD9D1\">Error</td></tr>";
}
echo "</table>";
}
}
?>
</div>
</form>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -1,130 +0,0 @@
<?php
/*
Copyright (C) 2014 Deciso B.V.
Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone)) {
header("Location: status_captiveportal.php");
exit;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
$pgtitle = array(gettext("Status"), gettext("Captive portal"), gettext("Test Vouchers"), $a_cp[$cpzone]['zone']);
$shortcut_section = "captiveportal-vouchers";
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<section class="col-xs-12">
<?php
$tab_array = array();
$tab_array[] = array(gettext("Active Users"), false, "status_captiveportal.php?zone={$cpzone}");
$tab_array[] = array(gettext("Active Vouchers"), false, "status_captiveportal_vouchers.php?zone={$cpzone}");
$tab_array[] = array(gettext("Voucher Rolls"), false, "status_captiveportal_voucher_rolls.php?zone={$cpzone}");
$tab_array[] = array(gettext("Test Vouchers"), true, "status_captiveportal_test.php?zone={$cpzone}");
$tab_array[] = array(gettext("Expire Vouchers"), false, "status_captiveportal_expire.php?zone={$cpzone}");
display_top_tabs($tab_array);
?>
<div class="tab-content content-box col-xs-12">
<div class="container-fluid">
<form action="status_captiveportal_test.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td valign="top" class="vncellreq"><?=gettext("Voucher(s)"); ?></td>
<td class="vtable">
<textarea name="vouchers" cols="65" rows="3" id="vouchers" class="formpre"><?=htmlspecialchars($_POST['vouchers']);?></textarea>
<br />
<?=gettext("Enter multiple vouchers separated by space or newline. The remaining time, if valid, will be shown for each voucher"); ?>.</td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
<input name="zone" type="hidden" value="<?=htmlspecialchars($cpzone);?>" />
<input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Submit"); ?>" />
</td>
</tr>
</table>
<br/>
<?php
if ($_POST) {
if ($_POST['vouchers']) {
$test_results = voucher_auth($_POST['vouchers'], 1);
echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"4\" width=\"100%\" summary=\"results\">\n";
foreach ($test_results as $result) {
if (strpos($result, " good ") || strpos($result, " granted ")) {
echo "<tr><td bgcolor=\"#D9DEE8\"><span class=\"glyphicon glyphicon-play text-success\" alt=\"pass\"></span></td>";
echo "<td bgcolor=\"#D9DEE8\">$result</td></tr>";
} else {
echo "<tr><td bgcolor=\"#FFD9D1\"><span class=\"glyphicon glyphicon-remove text-danger\" alt=\"block\"></span></td>";
echo "<td bgcolor=\"#FFD9D1\">$result</td></tr>";
}
}
echo "</table>";
}
}
?>
</div>
</form>
</div>
</div>
</section>
</div>
</div>
</section>
<? include("foot.inc");

View File

@ -1,164 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
/* return how many vouchers are marked used on a roll */
function voucher_used_count($roll) {
global $g, $cpzone;
$bitstring = voucher_read_used_db($roll);
$max = strlen($bitstring) * 8;
$used = 0;
for ($i = 1; $i <= $max; $i++) {
// check if ticket already used or not.
$pos = $i >> 3; // divide by 8 -> octet
$mask = 1 << ($i % 8); // mask to test bit in octet
if (ord($bitstring[$pos]) & $mask)
$used++;
}
unset($bitstring);
return $used;
}
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone)) {
header("Location: status_captiveportal.php");
exit;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
$pgtitle = array(gettext("Status"), gettext("Captive portal"), gettext("Voucher Rolls"), $a_cp[$cpzone]['zone']);
$shortcut_section = "captiveportal-vouchers";
if (!is_array($config['voucher'][$cpzone]['roll'])) {
$config['voucher'][$cpzone]['roll'] = array();
}
$a_roll = &$config['voucher'][$cpzone]['roll'];
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<section class="col-xs-12">
<?php
$tab_array = array();
$tab_array[] = array(gettext("Active Users"), false, "status_captiveportal.php?zone={$cpzone}");
$tab_array[] = array(gettext("Active Vouchers"), false, "status_captiveportal_vouchers.php?zone={$cpzone}");
$tab_array[] = array(gettext("Voucher Rolls"), true, "status_captiveportal_voucher_rolls.php?zone={$cpzone}");
$tab_array[] = array(gettext("Test Vouchers"), false, "status_captiveportal_test.php?zone={$cpzone}");
$tab_array[] = array(gettext("Expire Vouchers"), false, "status_captiveportal_expire.php?zone={$cpzone}");
display_top_tabs($tab_array);
?>
<div class="tab-content content-box col-xs-12">
<div class="container-fluid">
<form action="status_captiveportal_voucher_rolls.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td class="listhdrr"><?=gettext("Roll#"); ?></td>
<td class="listhdrr"><?=gettext("Minutes/Ticket"); ?></td>
<td class="listhdrr"><?=gettext("# of Tickets"); ?></td>
<td class="listhdrr"><?=gettext("Comment"); ?></td>
<td class="listhdrr"><?=gettext("used"); ?></td>
<td class="listhdrr"><?=gettext("active"); ?></td>
<td class="listhdr"><?=gettext("ready"); ?></td>
</tr>
<?php
$voucherlck = lock("vouche{$cpzone}r");
$i = 0; foreach ($a_roll as $rollent) :
$used = voucher_used_count($rollent['number']);
$active = count(voucher_read_active_db($rollent['number']), $rollent['minutes']);
$ready = $rollent['count'] - $used;
/* used also count active vouchers, remove them */
$used = $used - $active;
?>
<tr>
<td class="listlr">
<?=htmlspecialchars($rollent['number']); ?>&nbsp;
</td>
<td class="listr">
<?=htmlspecialchars($rollent['minutes']);?>&nbsp;
</td>
<td class="listr">
<?=htmlspecialchars($rollent['count']);?>&nbsp;
</td>
<td class="listr">
<?=htmlspecialchars($rollent['comment']); ?>&nbsp;
</td>
<td class="listr">
<?=htmlspecialchars($used); ?>&nbsp;
</td>
<td class="listr">
<?=htmlspecialchars($active); ?>&nbsp;
</td>
<td class="listr">
<?=htmlspecialchars($ready); ?>&nbsp;
</td>
</tr>
<?php $i++;
endforeach;
unlock($voucherlck); ?>
</table>
</div>
</form>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -1,160 +0,0 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
$cpzone = $_GET['zone'];
if (isset($_POST['zone'])) {
$cpzone = $_POST['zone'];
}
if (empty($cpzone)) {
header("Location: status_captiveportal.php");
exit;
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
$pgtitle = array(gettext("Status"), gettext("Captive portal"), gettext("Vouchers"), $a_cp[$cpzone]['zone']);
$shortcut_section = "captiveportal-vouchers";
function clientcmp($a, $b)
{
global $order;
return strcmp($a[$order], $b[$order]);
}
if (!is_array($config['voucher'][$cpzone]['roll'])) {
$config['voucher'][$cpzone]['roll'] = array();
}
$a_roll = $config['voucher'][$cpzone]['roll'];
$db = array();
foreach ($a_roll as $rollent) {
$roll = $rollent['number'];
$minutes = $rollent['minutes'];
if (!file_exists("/var/db/voucher_{$cpzone}_active_{$roll}.db")) {
continue;
}
$active_vouchers = file("/var/db/voucher_{$cpzone}_active_{$roll}.db", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($active_vouchers as $voucher => $line) {
list($voucher,$timestamp, $minutes) = explode(",", $line);
$remaining = (($timestamp + 60*$minutes) - time());
if ($remaining > 0) {
$dbent[0] = $voucher;
$dbent[1] = $roll;
$dbent[2] = $timestamp;
$dbent[3] = intval($remaining/60);
$dbent[4] = $timestamp + 60*$minutes; // expires at
$db[] = $dbent;
}
}
}
if ($_GET['order']) {
$order = $_GET['order'];
usort($db, "clientcmp");
}
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<section class="col-xs-12">
<?php
$tab_array = array();
$tab_array[] = array(gettext("Active Users"), false, "status_captiveportal.php?zone={$cpzone}");
$tab_array[] = array(gettext("Active Vouchers"), true, "status_captiveportal_vouchers.php?zone={$cpzone}");
$tab_array[] = array(gettext("Voucher Rolls"), false, "status_captiveportal_voucher_rolls.php?zone={$cpzone}");
$tab_array[] = array(gettext("Test Vouchers"), false, "status_captiveportal_test.php?zone={$cpzone}");
$tab_array[] = array(gettext("Expire Vouchers"), false, "status_captiveportal_expire.php?zone={$cpzone}");
display_top_tabs($tab_array);
?>
<div class="tab-content content-box col-xs-12">
<div class="container-fluid">
<form action="status_captiveportal_vouchers.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td class="listhdrr"><a href="?order=0&amp;showact=<?=htmlspecialchars($_GET['showact']);
?>"><?=gettext("Voucher"); ?></a></td>
<td class="listhdrr"><a href="?order=1&amp;showact=<?=htmlspecialchars($_GET['showact']);
?>"><?=gettext("Roll"); ?></a></td>
<td class="listhdrr"><a href="?order=2&amp;showact=<?=htmlspecialchars($_GET['showact']);
?>"><?=gettext("Activated at"); ?></a></td>
<td class="listhdrr"><a href="?order=3&amp;showact=<?=htmlspecialchars($_GET['showact']);
?>"><?=gettext("Expires in"); ?></a></td>
<td class="listhdr"><a href="?order=4&amp;showact=<?=htmlspecialchars($_GET['showact']);
?>"><?=gettext("Expires at"); ?></a></td>
<td class="list"></td>
</tr>
<?php foreach ($db as $dbent) :
?>
<tr>
<td class="listlr"><?=$dbent[0];?></td>
<td class="listr"><?=$dbent[1];?></td>
<td class="listr"><?=htmlspecialchars(date("m/d/Y H:i:s", $dbent[2]));?></td>
<td class="listr"><?=$dbent[3];
?> <?=gettext("min"); ?></td>
<td class="listr"><?=htmlspecialchars(date("m/d/Y H:i:s", $dbent[4]));?></td>
<td class="list"></td>
</tr>
<?php
endforeach; ?>
</table>
</div>
</form>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View File

@ -33,7 +33,6 @@ require_once("services.inc");
require_once("vslb.inc");
require_once("system.inc");
require_once("unbound.inc");
require_once("captiveportal.inc");
require_once("pfsense-utils.inc");
require_once("openvpn.inc");
require_once("filter.inc");
@ -73,9 +72,6 @@ function service_control_start($name, $extras) {
case 'radvd':
services_radvd_configure();
break;
case 'captiveportal':
captiveportal_configure();
break;
case 'ntpd':
system_ntp_configure();
break;
@ -141,11 +137,6 @@ function service_control_stop($name, $extras) {
case 'radvd':
killbypid("/var/run/radvd.pid");
break;
case 'captiveportal':
$zone = htmlspecialchars($extras['zone']);
killbypid("/var/run/lighty-{$zone}-CaptivePortal.pid");
killbypid("/var/run/lighty-{$zone}-CaptivePortal-SSL.pid");
break;
case 'ntpd':
killbyname("ntpd");
break;
@ -216,9 +207,6 @@ function service_control_restart($name, $extras) {
case 'radvd':
services_radvd_configure();
break;
case 'captiveportal':
captiveportal_configure();
break;
case 'ntpd':
system_ntp_configure();
break;

View File

@ -1311,11 +1311,6 @@ endif; ?>
IPsec Tunnel<br />
<?php
endif; ?>
<?php if (is_captiveportal_cert($cert['refid'])) :
?>
Captive Portal<br />
<?php
endif; ?>
<a href="system_certmanager.php?act=exp&amp;id=<?=$i;

View File

@ -38,7 +38,8 @@ if (!isset($config['hasync']) || !is_array($config['hasync'])) {
$a_hasync = &$config['hasync'];
$checkbox_names = array('pfsyncenabled',
$checkbox_names = array(
'pfsyncenabled',
'synchronizeusers',
'synchronizeauthservers',
'synchronizecerts',
@ -54,7 +55,7 @@ $checkbox_names = array('pfsyncenabled',
'synchronizelb',
'synchronizevirtualip',
'synchronizednsforwarder',
'synchronizecaptiveportal');
);
if ($_POST) {
$pconfig = $_POST;
@ -349,15 +350,6 @@ include("head.inc");
Automatically sync the DNS Forwarder configuration to the other HA host when changes are made.
</td>
</tr>
<tr valign="top">
<td width="22%" class="vncell">Synchronize Captive Portal</td>
<td class="vtable">
<input id='synchronizecaptiveportal' type='checkbox' name='synchronizecaptiveportal' value='on' <?php if ($pconfig['synchronizecaptiveportal'] === "on") {
echo "checked='checked'";
} ?> />
Automatically sync the Captive Portal configuration to the other HA host when changes are made.
</td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">

View File

@ -1,3 +0,0 @@
<?php
$captive_portal_status_title = "Captive Portal Status";
$captive_portal_status_title_link = "status_captiveportal.php";

View File

@ -1,245 +0,0 @@
/******************************************************************************
$Id: graphlink.js,v 1.1 2006/12/21 17:10:25 dberlin Exp $
This file is part of the GraphLink software.
GraphLink is distributed under the MIT License.
Copyright (C) 2005-2006 Max Khitrov <max@mxsoft.org>
******************************************************************************/
/***** Global data ************************************************************/
var gl_graphCount = 0; // Number of graphs on the current page
/***** Constants **************************************************************/
var GL_START = 0;
var GL_END = 1;
var GL_STATIC = 0;
var GL_DYNAMIC = 1;
/***** Public functions *******************************************************/
/**
* Creates a graph and returns the graph data structure which can later be
* manipulated using the other graph functions.
*
* element_id - DOM element id (should be a DIV) that will contain the graph.
* width - The width of the graph in pixels.
* height - Height of the graph in pixels.
* bar_width - Width of each bar on the graph. This number should divide width
* evenly, or else width will be adjusted to meet this requirement.
* General formula to keep in mind:
* Smaller bar width = more bars = higher CPU usage on client-side.
*
* Returns graph data structure on success, false on error.
*/
function GraphInitialize(element_id, width, height, bar_width) {
// Find the page element which will contain the graph
var owner;
if((owner = jQuery('#' + element_id)) == null) {
alert("GraphLink Error: Element ID '" + element_id + "' not found.");
return false;
}
// Make sure width is divisible by bar_width
if(width / bar_width != Math.floor(width / bar_width))
width = Math.floor(width / bar_width) * bar_width;
var bar_count = width / bar_width;
// Create the graph data structure
var graph = new Array();
graph['id'] = gl_graphCount; // ID used to separate elements of one graph from those of another
graph['width'] = width; // Graph width
graph['height'] = height; // Graph height
graph['bar_count'] = bar_count; // Number of bars on the graph
graph['scale_type'] = GL_STATIC; // How the graph is scaled
graph['scale'] = 1; // Multiplier for the bar height
graph['max'] = 0; // Largest value currently on the graph
graph['vmax'] = height; // Virtual graph maximum
graph['spans'] = new Array(bar_count); // References to all the spans for each graph
graph['vals'] = new Array(bar_count); // The height of each bar on the graph, actually it's (graph height - bar height)
gl_graphCount++;
// Build the graph (x)html
var graph_html = '';
graph_html += '<div id="GraphLinkData' + graph['id'] + '" class="GraphLinkData">';
for(var i = 0; i < bar_count; i++) {
graph['vals'][i] = height;
graph_html += '<span id="GraphLinkBar' + graph['id'] + '_' + i + '" class="GraphLinkBar"></span>';
}
graph_html += '</div>';
owner.html(graph_html);
graph['element_id'] = jQuery('#GraphLinkData' + graph['id']);
for(i = 0; i < bar_count; i++) {
graph['spans'][i] = jQuery('#GraphLinkBar' + graph['id'] + '_' + i);
graph['spans'][i].css('width',bar_width + 'px');
graph['spans'][i].css('margin-top',height + 'px');
}
return graph;
}
/**
* Adds a new value to a graph.
*
* graph - Graph object to which to add the new value.
* value - Value to add.
* where - (optional) GL_START (0) or GL_END (1), depending on where you want
* the new value to appear. GL_START will add the value on the left
* of the graph, GL_END will add it on the right (default).
*/
function GraphValue(graph, value, where) {
if(typeof(where) == 'undefined')
where = GL_END;
var rescale = false;
var lost = 0;
if(value < 0)
value = 0;
if(graph['scale_type'] == GL_DYNAMIC && value > graph['max'])
rescale = true;
if(graph['scale_type'] == GL_STATIC) {
if(value > graph['vmax'])
value = graph['vmax'];
value = Math.round(value * graph['scale']);
}
if(where == GL_START) {
graph['vals'].unshift(graph['height'] - value);
lost = graph['vals'].pop();
}
else {
graph['vals'].push(graph['height'] - value);
lost = graph['vals'].shift();
}
if(graph['scale_type'] == GL_DYNAMIC && (graph['height'] - lost) == graph['max'])
rescale = true;
if(rescale)
GraphAdjustScale(graph)
GraphDraw(graph);
}
/**
* Sets a virtual maximum for the graph allowing you to have non-scaled graphs
* that can show a value greater then the graph height. This function will
* automatically set the graph to a static scale mode, meaning that no values
* above the maximum will be permitted. If you need to have a graph with no
* pre-defined maximum, make it dynamic. Also note that if you set a vmax on a
* graph that has data larger than vmax, that data will be reduced.
*
* graph - Graph object for which to set virtual max.
* vmax - The virtual maximum value for the graph.
*/
function GraphSetVMax(graph, vmax) {
graph['scale_type'] = GL_STATIC;
graph['vmax'] = vmax;
GraphAdjustScale(graph);
GraphDraw(graph);
}
/**
* This function instructs the graph to be scaled according to what the maximum
* value is. That value is used as the graph maximum and is reevaluated whenever
* a new value is added, or the current maximum is removed. Dynamic scaling is a
* good way of showing data for which you don't know what the maximum will be,
* but it also is a bit more resource-intensive then statically scaled graphs.
*
* graph - Graph object for which to enable dynamic scaling.
*/
function GraphDynamicScale(graph) {
graph['scale_type'] = GL_DYNAMIC;
GraphAdjustScale(graph);
GraphDraw(graph);
}
/***** Private functions ******************************************************/
/**
* Checks if the current scale of the graph is still valid, or needs to be
* adjusted.
*
* graph - Graph object for which to check the scale.
*/
function GraphAdjustScale(graph) {
var limit = graph['bar_count'];
var new_max = 0;
var new_scale = 0;
var val = 0;
if(graph['scale_type'] == GL_STATIC) {
new_max = graph['vmax'];
new_scale = graph['height'] / new_max;
if(new_scale == graph['scale'])
return;
}
for(var i = 0; i < limit; i++) {
if(graph['scale_type'] == GL_STATIC) {
val = (graph['height'] - graph['vals'][i]) * graph['scale'];
val = val * new_scale;
if(val > new_max)
val = new_max;
graph['vals'][i] = graph['height'] - Math.round(val * new_scale);
}
else if((graph['height'] - graph['vals'][i]) > new_max) {
new_max = graph['height'] - graph['vals'][i];
}
}
if(graph['scale_type'] == GL_STATIC) {
graph['scale'] = new_scale;
}
else {
if(new_max == 0)
graph['scale'] = 1;
else
graph['scale'] = graph['height'] / new_max;
graph['max'] = new_max;
}
}
/**
* Redraws the graph on the screen.
*
* graph - Graph object which needs to be re-drawn.
*/
function GraphDraw(graph) {
var count = graph['bar_count'];
if(graph['scale_type'] == GL_STATIC)
var getMargin = function(i) {
return graph['vals'][i] + 'px';
};
else
var getMargin = function(i) {
var h = graph['height'];
var s = graph['scale'];
var v = graph['vals'][i];
return (h - Math.round((h - v) * s)) + 'px';
};
graph['spans'][count - 1].css("display", "none");
for(var i = 0; i < count; i++)
graph['spans'][i].css("marginTop", getMargin(i));
// jQuery('#' + graph['spans'][count - 1]).fadeIn(500);
}

View File

@ -1,115 +0,0 @@
<?php
/*
Copyright (C) 2014 Deciso B.V.
Copyright (C) 2007 Sam Wenham
Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
$nocsrf = true;
require_once("guiconfig.inc");
require_once("pfsense-utils.inc");
require_once("captiveportal.inc");
if (($_GET['act'] == "del") && (!empty($_GET['zone']))) {
$cpzone = $_GET['zone'];
captiveportal_disconnect_client($_GET['id']);
}
flush();
function clientcmp($a, $b)
{
global $order;
return strcmp($a[$order], $b[$order]);
}
if (!is_array($config['captiveportal'])) {
$config['captiveportal'] = array();
}
$a_cp =& $config['captiveportal'];
$cpdb_all = array();
foreach ($a_cp as $cpzone => $cp) {
$cpdb_handle = new OPNsense\CaptivePortal\DB($cpzone);
$order = "";
if ($_GET['order']) {
if ($_GET['order'] == "ip") {
$order = "ip";
} elseif ($_GET['order'] == "mac") {
$order = "mac";
} elseif ($_GET['order'] == "user") {
$order = "username";
}
}
$cpdb = $cpdb_handle->listClients(array(), "and", array($order)) ;
$cpdb_all[$cpzone] = $cpdb;
}
?>
<table class="table table-striped sortable" id="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0" summary="captive portal status">
<tr>
<td class="listhdrr"><a href="?order=ip&amp;showact=<?=$_GET['showact'];?>"><b>IP address</b></a></td>
<td class="listhdrr"><a href="?order=mac&amp;showact=<?=$_GET['showact'];?>"><b>MAC address</b></a></td>
<td class="listhdrr"><a href="?order=user&amp;showact=<?=$_GET['showact'];
?>"><b><?=gettext("Username");?></b></a></td>
<?php if ($_GET['showact']) :
?>
<td class="listhdrr"><a href="?order=start&amp;showact=<?=$_GET['showact'];
?>"><b><?=gettext("Session start");?></b></a></td>
<td class="listhdrr"><a href="?order=start&amp;showact=<?=$_GET['showact'];
?>"><b><?=gettext("Last activity");?></b></a></td>
<?php
endif; ?>
</tr>
<?php foreach ($cpdb_all as $cpzone => $cpdb) :
?>
<?php foreach ($cpdb as $cpent) :
?>
<tr>
<td class="listlr"><?=$cpent->ip;?></td>
<td class="listr"><?=$cpent->mac;?>&nbsp;</td>
<td class="listr"><?=$cpent->username;?>&nbsp;</td>
<?php if ($_GET['showact']) :
?>
<td class="listr"><?=htmlspecialchars(date("m/d/Y H:i:s", $cpent->allow_time));?></td>
<td class="listr">?</td>
<?php
endif; ?>
<td valign="middle" class="list nowrap">
<a href="?order=<?=$_GET['order'];
?>&amp;showact=<?=$_GET['showact'];
?>&amp;act=del&amp;zone=<?=$cpzone;
?>&amp;id=<?=$cpent->sessionid;?>" onclick="return confirm('<?= gettext('Do you really want to disconnect this client?');?>')"><span class="glyphicon glyphicon-remove"></span></a></td>
</tr>
<?php
endforeach; ?>
<?php
endforeach; ?>
</table>

View File

@ -32,7 +32,6 @@
$nocsrf = true;
require_once("guiconfig.inc");
require_once("captiveportal.inc");
require_once("services.inc");
require_once("vpn.inc");
require_once("widgets/include/services_status.inc");