mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-14 16:44:39 +00:00
added captive portal model and some plumming for future use
This commit is contained in:
parent
b7905f6d03
commit
6f8cea824e
9
src/opnsense/mvc/app/cache/_users_ad_develop_deciso_opnsense_gui_app_views_index.volt.php
vendored
Normal file
9
src/opnsense/mvc/app/cache/_users_ad_develop_deciso_opnsense_gui_app_views_index.volt.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Phalcon PHP Framework</title>
|
||||
</head>
|
||||
<body>
|
||||
<?php echo $this->getContent(); ?>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,3 @@
|
||||
<h1>Congratulations!</h1>
|
||||
|
||||
<p>You're now flying with Phalcon. Great things are about to happen!</p>
|
||||
28
src/opnsense/mvc/app/config/config.php
Normal file
28
src/opnsense/mvc/app/config/config.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
return new \Phalcon\Config(array(
|
||||
'database' => array(
|
||||
'adapter' => 'Mysql',
|
||||
'host' => 'localhost',
|
||||
'username' => 'root',
|
||||
'password' => '',
|
||||
'dbname' => 'test',
|
||||
),
|
||||
'application' => array(
|
||||
'controllersDir' => __DIR__ . '/../../app/controllers/',
|
||||
'modelsDir' => __DIR__ . '/../../app/models/',
|
||||
'viewsDir' => __DIR__ . '/../../app/views/',
|
||||
'pluginsDir' => __DIR__ . '/../../app/plugins/',
|
||||
'libraryDir' => __DIR__ . '/../../app/library/',
|
||||
'cacheDir' => __DIR__ . '/../../app/cache/',
|
||||
'baseUri' => '/opnsense_gui/',
|
||||
),
|
||||
'globals' => array(
|
||||
'config_path' => '/conf/',
|
||||
'temp_path' => '/tmp/',
|
||||
'vardb_path' => '/var/db/',
|
||||
'debug' => true,
|
||||
'simulate_mode' => false
|
||||
|
||||
)
|
||||
));
|
||||
13
src/opnsense/mvc/app/config/loader.php
Normal file
13
src/opnsense/mvc/app/config/loader.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
$loader = new \Phalcon\Loader();
|
||||
|
||||
/**
|
||||
* We're a registering a set of directories taken from the configuration file
|
||||
*/
|
||||
$loader->registerDirs(
|
||||
array(
|
||||
$config->application->controllersDir,
|
||||
$config->application->modelsDir
|
||||
)
|
||||
)->register();
|
||||
83
src/opnsense/mvc/app/config/services.php
Normal file
83
src/opnsense/mvc/app/config/services.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
use Phalcon\DI\FactoryDefault;
|
||||
use Phalcon\Mvc\View;
|
||||
use Phalcon\Mvc\Url as UrlResolver;
|
||||
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
|
||||
use Phalcon\Mvc\View\Engine\Volt as VoltEngine;
|
||||
use Phalcon\Mvc\Model\Metadata\Memory as MetaDataAdapter;
|
||||
use Phalcon\Session\Adapter\Files as SessionAdapter;
|
||||
|
||||
/**
|
||||
* The FactoryDefault Dependency Injector automatically register the right services providing a full stack framework
|
||||
*/
|
||||
$di = new FactoryDefault();
|
||||
|
||||
/**
|
||||
* The URL component is used to generate all kind of urls in the application
|
||||
*/
|
||||
$di->set('url', function () use ($config) {
|
||||
$url = new UrlResolver();
|
||||
$url->setBaseUri($config->application->baseUri);
|
||||
|
||||
return $url;
|
||||
}, true);
|
||||
|
||||
/**
|
||||
* Setting up the view component
|
||||
*/
|
||||
$di->set('view', function () use ($config) {
|
||||
|
||||
$view = new View();
|
||||
|
||||
$view->setViewsDir($config->application->viewsDir);
|
||||
|
||||
$view->registerEngines(array(
|
||||
'.volt' => function ($view, $di) use ($config) {
|
||||
|
||||
$volt = new VoltEngine($view, $di);
|
||||
|
||||
$volt->setOptions(array(
|
||||
'compiledPath' => $config->application->cacheDir,
|
||||
'compiledSeparator' => '_'
|
||||
));
|
||||
|
||||
return $volt;
|
||||
},
|
||||
'.phtml' => 'Phalcon\Mvc\View\Engine\Php'
|
||||
));
|
||||
|
||||
return $view;
|
||||
}, true);
|
||||
|
||||
/**
|
||||
* Database connection is created based in the parameters defined in the configuration file
|
||||
*/
|
||||
$di->set('db', function () use ($config) {
|
||||
return new DbAdapter(array(
|
||||
'host' => $config->database->host,
|
||||
'username' => $config->database->username,
|
||||
'password' => $config->database->password,
|
||||
'dbname' => $config->database->dbname
|
||||
));
|
||||
});
|
||||
|
||||
/**
|
||||
* If the configuration specify the use of metadata adapter use it or use memory otherwise
|
||||
*/
|
||||
$di->set('modelsMetadata', function () {
|
||||
return new MetaDataAdapter();
|
||||
});
|
||||
|
||||
/**
|
||||
* Start the session the first time some component request the session service
|
||||
*/
|
||||
$di->set('session', function () {
|
||||
$session = new SessionAdapter();
|
||||
$session->start();
|
||||
|
||||
return $session;
|
||||
});
|
||||
|
||||
|
||||
$di->set('config',$config);
|
||||
8
src/opnsense/mvc/app/controllers/ControllerBase.php
Normal file
8
src/opnsense/mvc/app/controllers/ControllerBase.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Phalcon\Mvc\Controller;
|
||||
|
||||
class ControllerBase extends Controller
|
||||
{
|
||||
|
||||
}
|
||||
12
src/opnsense/mvc/app/controllers/IndexController.php
Normal file
12
src/opnsense/mvc/app/controllers/IndexController.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class IndexController extends ControllerBase
|
||||
{
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
82
src/opnsense/mvc/app/models/Captiveportal/ARP.php
Normal file
82
src/opnsense/mvc/app/models/Captiveportal/ARP.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* User: ad
|
||||
* Date: 09-12-14
|
||||
* Time: 16:26
|
||||
*/
|
||||
|
||||
namespace Captiveportal;
|
||||
|
||||
|
||||
class ARP {
|
||||
|
||||
/**
|
||||
* pointer to shell object
|
||||
* @var \Core\Shell
|
||||
*/
|
||||
private $shell ;
|
||||
|
||||
/**
|
||||
* construct new ARP table handlers
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->shell = new \Core\Shell();
|
||||
}
|
||||
|
||||
/**
|
||||
* set static arp entry
|
||||
* @param $ipaddress hosts ipaddress
|
||||
* @param $mac hosts physical address
|
||||
*/
|
||||
function setStatic($ipaddress,$mac){
|
||||
// validate input, only set static entries for valid addresses
|
||||
if (preg_match('/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', trim($mac))){
|
||||
if ( filter_var($ipaddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4|FILTER_FLAG_IPV6) ){
|
||||
$this->shell->exec("/usr/sbin/arp -s ".trim($ipaddress)." ".trim($mac));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* drop static arp entry
|
||||
* @param $ipaddress hosts ipaddress
|
||||
*/
|
||||
function dropStatic($ipaddress){
|
||||
// validate input, drop arp entry
|
||||
if ( filter_var($ipaddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4|FILTER_FLAG_IPV6) ){
|
||||
$this->shell->exec("/usr/sbin/arp -d ".trim($ipaddress) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return arp table hashed by mac address
|
||||
*/
|
||||
function getMACs(){
|
||||
$result = array();
|
||||
$shell_output = array();
|
||||
// execute arp shell command and collect (only valid) info into named array
|
||||
if ($this->shell->exec("arp -an",false,false,$shell_output) == 0 ){
|
||||
foreach($shell_output as $line){
|
||||
$line_parts = explode(" ",$line) ;
|
||||
if ( sizeof($line_parts) >= 4 ) {
|
||||
$ipaddress = substr($line_parts[1],1,strlen($line_parts[1])-2 ) ;
|
||||
// reformat mac addresses, sometimes arp return segments without trailing zero's
|
||||
$mac_raw = strtolower($line_parts[3]);
|
||||
$mac = "";
|
||||
foreach(explode(":",$mac_raw) as $segment ){
|
||||
if ( $mac != "") $mac .= ":";
|
||||
if (strlen($segment) == 1) $mac .= "0".$segment;
|
||||
else $mac .= $segment ;
|
||||
}
|
||||
if (preg_match('/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', trim($mac))){
|
||||
$result[$mac]= array('ip'=>$ipaddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
500
src/opnsense/mvc/app/models/Captiveportal/CPClient.php
Normal file
500
src/opnsense/mvc/app/models/Captiveportal/CPClient.php
Normal file
@ -0,0 +1,500 @@
|
||||
<?php namespace Captiveportal;
|
||||
|
||||
/**
|
||||
* Class CPClient
|
||||
* // TODO: CARP interfaces are probably not handled correctly
|
||||
* @package Captiveportal
|
||||
*/
|
||||
class CPClient {
|
||||
|
||||
|
||||
/**
|
||||
* config handle
|
||||
* @var Core_Config
|
||||
*/
|
||||
private $config = null;
|
||||
|
||||
/**
|
||||
* ipfw rule object
|
||||
* @var \Captiveportal\Rules
|
||||
*/
|
||||
private $rules = null;
|
||||
|
||||
/**
|
||||
* link to shell object
|
||||
* @var \Core\Shell
|
||||
*/
|
||||
private $shell = null;
|
||||
|
||||
/**
|
||||
* Request new pipeno
|
||||
* @return int
|
||||
*/
|
||||
private function new_ipfw_pipeno(){
|
||||
// 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
|
||||
*/
|
||||
private function reset_bandwidth($pipeno,$bw){
|
||||
//TODO : setup bandwidth for sessions ( check changed )
|
||||
//#pipe 2000 config bw 2000Kbit/s
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $cpzonename zone name
|
||||
* @param $sessionid session id
|
||||
*/
|
||||
private function _disconnect($cpzonename,$sessionid){
|
||||
|
||||
$zoneid = -1;
|
||||
foreach($this->config->object()->captiveportal->children() as $zone => $zoneobj){
|
||||
if ($zone == $cpzonename) $zoneid = $zoneobj->zoneid;
|
||||
}
|
||||
|
||||
if ($zoneid == -1) return; // not a valid zone
|
||||
|
||||
$db = new DB($cpzonename);
|
||||
$db_clients = $db->listClients(array("sessionid"=>$sessionid));
|
||||
|
||||
$ipfw_tables = $this->rules->getAuthUsersTables($zoneid);
|
||||
if ( sizeof($db_clients) > 0 ){
|
||||
if ($db_clients->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, false, false);
|
||||
// TODO: cleanup dummynet pipes $db_clients[0]->pipeno_in/out
|
||||
// TODO: log removal ( was : captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "DISCONNECT");)
|
||||
}
|
||||
$db->remove_session($sessionid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param $zoneid
|
||||
* @param $ip
|
||||
*/
|
||||
public function add_accounting($zoneid,$ip){
|
||||
// TODO: check 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,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, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct() {
|
||||
// Request handle to configuration
|
||||
$this->config = \Core\Config::getInstance();
|
||||
// generate new ruleset
|
||||
$this->rules = new \Captiveportal\Rules();
|
||||
// keep a link to the shell object
|
||||
$this->shell = new \Core\Shell();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconfigure zones ( generate and load ruleset )
|
||||
*/
|
||||
public function reconfigure(){
|
||||
$ruleset_filename = \Phalcon\DI\FactoryDefault::getDefault()->get('config')->globals->temp_path."/ipfw.rules";
|
||||
$this->rules->generate($ruleset_filename);
|
||||
|
||||
// load ruleset
|
||||
$this->shell->exec("/sbin/ipfw -f ".$ruleset_filename);
|
||||
|
||||
// update tables
|
||||
$this->update_config();
|
||||
}
|
||||
|
||||
/**
|
||||
* update zone(s) with new configuration data
|
||||
* @param string $zone
|
||||
*/
|
||||
public function update($zone=null){
|
||||
$this->refresh_allowed_ips($zone);
|
||||
$this->refresh_allowed_mac($zone);
|
||||
}
|
||||
|
||||
/**
|
||||
* refresh allowed ip's for defined zone ( null for all zones )
|
||||
* @param string $zone
|
||||
*/
|
||||
public function refresh_allowed_ips($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->rules->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->new_ipfw_pipeno() ;
|
||||
$pipeno_out = $this->new_ipfw_pipeno() ;
|
||||
|
||||
$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, false,false);
|
||||
// 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, false,false);
|
||||
// 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->reset_bandwidth($record["pipeno_in"],$record["bw_down"]);
|
||||
$this->reset_bandwidth($record["pipeno_out"],$record["bw_up"]);
|
||||
}
|
||||
}
|
||||
|
||||
unset($db);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $zone zone name or number
|
||||
*/
|
||||
public function refresh_allowed_mac($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->rules->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, false,false);
|
||||
// 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->new_ipfw_pipeno() ;
|
||||
$pipeno_out = $this->new_ipfw_pipeno() ;
|
||||
|
||||
// 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, false,false);
|
||||
|
||||
$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, false,false);
|
||||
// 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->reset_bandwidth($record["pipeno_in"],$record["bw_down"]);
|
||||
$this->reset_bandwidth($record["pipeno_out"],$record["bw_up"]);
|
||||
}
|
||||
}
|
||||
|
||||
unset($db);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cpzonename
|
||||
* @param string $clientip
|
||||
* @param string $clientmac
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $attributes
|
||||
* @param string $radiusctx
|
||||
*/
|
||||
public function portal_allow($cpzonename,$clientip,$clientmac,$username,$password = null,$bw_up=null,$bw_down=null, $attributes = null, $radiusctx = 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; // not a valid zone, bailout
|
||||
|
||||
|
||||
// grap needed data to generate our rules
|
||||
$ipfw_tables = $this->rules->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;
|
||||
} 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->remove_session($remove_sessions);
|
||||
}
|
||||
|
||||
// collect pipe numbers for dummynet
|
||||
$pipeno_in = $current_session->pipeno_in;
|
||||
$pipeno_out = $current_session->pipeno_out;
|
||||
|
||||
$db->update_session($current_session->sessionid,array("ip"=>$clientip,"mac"=>$clientmac));
|
||||
} else
|
||||
{
|
||||
// new session, allocate new dummynet pipes and generate a unique id
|
||||
$pipeno_in = $this->new_ipfw_pipeno();
|
||||
$pipeno_out = $this->new_ipfw_pipeno();
|
||||
|
||||
// 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"] = -1;
|
||||
$session_data["idle_timeout"] = -1;
|
||||
$session_data["session_terminate_time"] = -1;
|
||||
$session_data["interim_interval"] = -1;
|
||||
$session_data["radiusctx"] = $radiusctx;
|
||||
$session_data["allow_time"] = time(); // allow time is actual starting time of this session
|
||||
$sessionid = uniqid() ;
|
||||
|
||||
$db->insert_session($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, false,false);
|
||||
|
||||
// lock the user/ip to it's MAC address using arp
|
||||
$arp->setStatic($clientip,$clientmac);
|
||||
|
||||
// add accounting rule
|
||||
$this->add_accounting($zoneid,$clientip);
|
||||
|
||||
// cleanup
|
||||
unset($db);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* disconnect a session or a list of sessions depending on the parameter
|
||||
* @param string $cpzonename zone name or id
|
||||
* @param $sessionid
|
||||
*/
|
||||
public function disconnect($cpzonename,$sessionid){
|
||||
if ( is_array($sessionid)){
|
||||
foreach($sessionid as $sessid ){
|
||||
$this->_disconnect($cpzonename,$sessid);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$this->_disconnect($cpzonename,$sessionid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* flush zone (null flushes all zones)
|
||||
* @param null $zone
|
||||
*/
|
||||
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->rules->getAuthUsersTables($zoneid)["in"]." flush",
|
||||
"/sbin/ipfw -f table ".$this->rules->getAuthUsersTables($zoneid)["out"]." flush",
|
||||
"/sbin/ipfw -f table ".$this->rules->getAuthIPTables($zoneid)["in"]." flush",
|
||||
"/sbin/ipfw -f table ".$this->rules->getAuthIPTables($zoneid)["out"]." flush",
|
||||
"/sbin/ipfw -f table ".$this->rules->getAuthMACTables($zoneid)["in"]." flush",
|
||||
"/sbin/ipfw -f table ".$this->rules->getAuthMACTables($zoneid)["out"]." flush",
|
||||
"/sbin/ipfw delete set ".$zoneid,
|
||||
);
|
||||
$this->shell->exec($exec_commands, false,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
327
src/opnsense/mvc/app/models/Captiveportal/DB.php
Normal file
327
src/opnsense/mvc/app/models/Captiveportal/DB.php
Normal file
@ -0,0 +1,327 @@
|
||||
<?php
|
||||
/**
|
||||
* User: ad
|
||||
* Date: 08-12-14
|
||||
* Time: 18:11
|
||||
*/
|
||||
|
||||
namespace Captiveportal;
|
||||
|
||||
/**
|
||||
* Class DB, handles captive portal zone's adminstration
|
||||
* @package Captiveportal
|
||||
*/
|
||||
class DB {
|
||||
|
||||
/**
|
||||
* zone name
|
||||
* @var string
|
||||
*/
|
||||
private $zone = null ;
|
||||
|
||||
/**
|
||||
* database handle
|
||||
* @var SQLite3
|
||||
*/
|
||||
private $handle = null ;
|
||||
|
||||
/**
|
||||
* datatypes for captive portal table
|
||||
* @var array
|
||||
*/
|
||||
private $captiveportal_types = array(
|
||||
"allow_time" => \PDO::PARAM_INT,
|
||||
"pipeno_in" => \PDO::PARAM_INT,
|
||||
"pipeno_out" => \PDO::PARAM_INT,
|
||||
"ip" => \PDO::PARAM_STR,
|
||||
"mac" => \PDO::PARAM_STR,
|
||||
"username" => \PDO::PARAM_STR,
|
||||
"sessionid" => \PDO::PARAM_STR,
|
||||
"bpassword" => \PDO::PARAM_STR,
|
||||
"session_timeout" => \PDO::PARAM_INT,
|
||||
"idle_timeout" => \PDO::PARAM_INT,
|
||||
"session_terminate_time" => \PDO::PARAM_INT,
|
||||
"interim_interval" => \PDO::PARAM_INT,
|
||||
"radiusctx" => \PDO::PARAM_STR);
|
||||
|
||||
/**
|
||||
* datatypes for captive portal mac table
|
||||
* @var array
|
||||
*/
|
||||
private $captiveportal_mac_types=array(
|
||||
"mac" => \PDO::PARAM_STR,
|
||||
"ip" => \PDO::PARAM_STR,
|
||||
"pipeno_in" => \PDO::PARAM_INT,
|
||||
"pipeno_out" => \PDO::PARAM_INT,
|
||||
"last_checked" => \PDO::PARAM_INT);
|
||||
|
||||
/**
|
||||
* datatypes for captive portal ip table
|
||||
* @var array
|
||||
*/
|
||||
private $captiveportal_ip_types=array(
|
||||
"ip" => \PDO::PARAM_STR,
|
||||
"pipeno_in" => \PDO::PARAM_INT,
|
||||
"pipeno_out" => \PDO::PARAM_INT,
|
||||
"last_checked" => \PDO::PARAM_INT);
|
||||
|
||||
/**
|
||||
* open / create new captive portal database for zone
|
||||
* @param $zone zone name
|
||||
*/
|
||||
function __construct($zone)
|
||||
{
|
||||
$this->zone = $zone ;
|
||||
$this->open();
|
||||
}
|
||||
|
||||
/**
|
||||
* destruct, close sessions
|
||||
*/
|
||||
function __destruct() {
|
||||
if ( $this->handle != null){
|
||||
$this->handle->close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* open database, on failure send message tot syslog
|
||||
* creates structure needed for this captiveportal zone
|
||||
* @return SQLite3
|
||||
*/
|
||||
function open(){
|
||||
// open database
|
||||
$db_path = \Phalcon\DI\FactoryDefault::getDefault()->get('config')->globals->vardb_path ."/captiveportal".$this->zone.".db" ;
|
||||
try {
|
||||
$this->handle = new \Phalcon\Db\Adapter\Pdo\Sqlite(array("dbname" => $db_path));
|
||||
|
||||
// create structure on new database
|
||||
if (!$this->handle->execute("CREATE TABLE IF NOT EXISTS captiveportal (" . # table used for authenticated users
|
||||
"allow_time INTEGER, pipeno_in INTEGER, pipeno_out INTEGER, ip TEXT, mac TEXT, username TEXT, " .
|
||||
"sessionid TEXT, bpassword TEXT, session_timeout INTEGER, idle_timeout INTEGER, " .
|
||||
"session_terminate_time INTEGER, interim_interval INTEGER, radiusctx TEXT); " .
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS idx_active ON captiveportal (sessionid, username); " .
|
||||
"CREATE INDEX IF NOT EXISTS user ON captiveportal (username); " .
|
||||
"CREATE INDEX IF NOT EXISTS ip ON captiveportal (ip); " .
|
||||
"CREATE INDEX IF NOT EXISTS starttime ON captiveportal (allow_time);".
|
||||
"CREATE TABLE IF NOT EXISTS captiveportal_mac (" . # table used for static mac's
|
||||
"mac TEXT, ip TEXT,pipeno_in INTEGER, pipeno_out INTEGER, last_checked INTEGER );" .
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS idx_mac ON captiveportal_mac (mac) ;".
|
||||
"CREATE TABLE IF NOT EXISTS captiveportal_ip (" . # table used for static ip's
|
||||
"ip TEXT,pipeno_in INTEGER, pipeno_out INTEGER, last_checked INTEGER );" .
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS idx_ip ON captiveportal_ip (ip) "
|
||||
)
|
||||
) {
|
||||
|
||||
$logger = new \Phalcon\Logger\Adapter\Syslog("logportalauth", array(
|
||||
'option' => LOG_PID,
|
||||
'facility' => LOG_LOCAL4
|
||||
));
|
||||
$logger->error("Error during table {$this->zone} creation. Error message: {$this->handle->lastErrorMsg()}");
|
||||
$this->handle = null ;
|
||||
}
|
||||
|
||||
|
||||
}catch (\Exception $e) {
|
||||
$logger = new \Phalcon\Logger\Adapter\Syslog("logportalauth", array(
|
||||
'option' => LOG_PID,
|
||||
'facility' => LOG_LOCAL4
|
||||
));
|
||||
$logger->error("Error opening database for zone " . $this->zone . " : ".$e->getMessage()." ");
|
||||
$this->handle = null ;
|
||||
}
|
||||
|
||||
return $this->handle;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* remove session(s) from database
|
||||
* @param $sessionids session ids ( or id )
|
||||
*/
|
||||
function remove_session($sessionids){
|
||||
if ( $this->handle != null ){
|
||||
if ( is_array($sessionids) ) $tmpids = $sessionids;
|
||||
else $tmpids = array($sessionids);
|
||||
|
||||
$this->handle->begin() ;
|
||||
$stmt = $this->handle->prepare('DELETE FROM captiveportal WHERE sessionid = :sessionid');
|
||||
foreach( $tmpids as $session ) {
|
||||
$this->handle->executePrepared($stmt, array('sessionid' => $session),array("sessionid"=>\PDO::PARAM_STR));
|
||||
$stmt->execute();
|
||||
}
|
||||
$this->handle->commit() ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $sessionid session id
|
||||
* @param Array() $content data to alter ( fields from "captiveportal")
|
||||
*/
|
||||
function update_session($sessionid,$content){
|
||||
if ( $this->handle != null ) {
|
||||
$query = "update captiveportal set ";
|
||||
$bind_values = Array("sessionid" => $sessionid);
|
||||
foreach ($content as $fieldname => $fieldvalue) {
|
||||
// you may not alter data not described in $this->captiveportal_types
|
||||
if (array_key_exists($fieldname, $this->captiveportal_types)) {
|
||||
if (sizeof($bind_values) > 1) $query .= " , ";
|
||||
$query .= $fieldname." = "." :".$fieldname." ";
|
||||
$bind_values[$fieldname] = $fieldvalue;
|
||||
}
|
||||
}
|
||||
$query .= " where sessionid = :sessionid ";
|
||||
try {
|
||||
$this->handle->execute($query, $bind_values, $this->captiveportal_types);
|
||||
} catch (\Exception $e) {
|
||||
$logger = new \Phalcon\Logger\Adapter\Syslog("logportalauth", array(
|
||||
'option' => LOG_PID,
|
||||
'facility' => LOG_LOCAL4
|
||||
));
|
||||
$logger->error("Trying to modify DB returned error (zone = " . $this->zone . " ) : " . $e->getMessage() . " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* insert new session information into this zone's database
|
||||
*
|
||||
* @param string $sessionid unique session id
|
||||
* @param Array() field content ( defined fields in "captiveportal")
|
||||
*/
|
||||
function insert_session($sessionid,$content){
|
||||
if ( $this->handle != null ) {
|
||||
// construct insert query, using placeholders for bind variables
|
||||
$bind_values = Array("sessionid" => $sessionid);
|
||||
$query = "insert into captiveportal (sessionid ";
|
||||
$query_values = "values (:sessionid ";
|
||||
foreach ($content as $fieldname => $fieldvalue) {
|
||||
// you may not alter data not described in $this->captiveportal_types
|
||||
if (array_key_exists($fieldname, $this->captiveportal_types)) {
|
||||
$query .= "," . $fieldname . " ";
|
||||
$query_values .= ", :" . $fieldname;
|
||||
$bind_values[$fieldname] = $fieldvalue;
|
||||
}
|
||||
}
|
||||
$query .= " ) " . $query_values . ") ";
|
||||
try {
|
||||
$this->handle->execute($query, $bind_values, $this->captiveportal_types);
|
||||
} catch (\Exception $e) {
|
||||
$logger = new \Phalcon\Logger\Adapter\Syslog("logportalauth", array(
|
||||
'option' => LOG_PID,
|
||||
'facility' => LOG_LOCAL4
|
||||
));
|
||||
$logger->error("Trying to modify DB returned error (zone = " . $this->zone . " ) : " . $e->getMessage() . " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get captive portal clients
|
||||
* @param Array() $args
|
||||
*/
|
||||
function listClients($qryargs,$operator="and"){
|
||||
// construct query, only parse fields defined by $this->captiveportal_types
|
||||
$qry_tag = "where " ;
|
||||
$query = "select * from captiveportal ";
|
||||
foreach ( $qryargs as $fieldname => $fieldvalue ){
|
||||
if ( array_key_exists($fieldname,$this->captiveportal_types) ){
|
||||
$query .= $qry_tag . $fieldname." = "." :".$fieldname." ";
|
||||
$qry_tag = " ".$operator." ";
|
||||
}
|
||||
}
|
||||
|
||||
$resultset = $this->handle->query($query, $qryargs, $this->captiveportal_types);
|
||||
$resultset->setFetchMode(\Phalcon\Db::FETCH_OBJ);
|
||||
|
||||
return $resultset->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* list all fixed ip addresses for this zone
|
||||
*
|
||||
* @return Array()
|
||||
*/
|
||||
function listFixedIPs(){
|
||||
$result = array();
|
||||
if ($this->handle != null ) {
|
||||
$resultset = $this->handle->query("select ip,pipeno_in,pipeno_out,last_checked from captiveportal_ip");
|
||||
$resultset->setFetchMode(\Phalcon\Db::FETCH_OBJ);
|
||||
|
||||
foreach ($resultset->fetchAll() as $record) {
|
||||
$result[$record->ip] = $record;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* insert new passthru mac address
|
||||
* @param $ip hosts ip address
|
||||
*/
|
||||
function upsertFixedIP($ip,$pipeno_in=null,$pipeno_out=null){
|
||||
// perform an upsert to update the data for this physical host.
|
||||
// unfortunately this costs an extra write io for the first record, but provides cleaner code
|
||||
$params = array("ip"=>$ip,"pipeno_in"=>$pipeno_in,"pipeno_out"=>$pipeno_out,"last_checked"=>time());
|
||||
$this->handle->execute("insert or ignore into captiveportal_ip(ip) values (:ip)", array("ip"=>$ip),$this->captiveportal_ip_types);
|
||||
$this->handle->execute("update captiveportal_ip set ip=:ip, last_checked=:last_checked, pipeno_in = :pipeno_in, pipeno_out = :pipeno_out where ip =:ip ", $params,$this->captiveportal_ip_types);
|
||||
}
|
||||
|
||||
/**
|
||||
* drop address from administration (captiveportal_ip)
|
||||
* @param $mac physical address
|
||||
*/
|
||||
function dropFixedIP($ip){
|
||||
$this->handle->execute("delete from captiveportal_ip where ip =:ip ", array("ip"=>$ip),$this->captiveportal_ip_types);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* list all passthru mac addresses for this zone
|
||||
*
|
||||
* @return Array()
|
||||
*/
|
||||
function listPassthruMacs(){
|
||||
$result = array();
|
||||
if ($this->handle != null ) {
|
||||
$resultset = $this->handle->query("select mac,ip,last_checked,pipeno_in,pipeno_out from captiveportal_mac");
|
||||
$resultset->setFetchMode(\Phalcon\Db::FETCH_OBJ);
|
||||
|
||||
foreach ($resultset->fetchAll() as $record) {
|
||||
$result[$record->mac] = $record;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* insert new passthru mac address
|
||||
* @param $mac physical address
|
||||
* @param $ip hosts ip address
|
||||
*/
|
||||
function upsertPassthruMAC($mac,$ip,$pipeno_in=null,$pipeno_out=null){
|
||||
// perform an upsert to update the data for this physical host.
|
||||
// unfortunately this costs an extra write io for the first record, but provides cleaner code
|
||||
$params = array("mac"=>$mac,"ip"=>$ip,"pipeno_in"=>$pipeno_in,"pipeno_out"=>$pipeno_out,"last_checked"=>time());
|
||||
$this->handle->execute("insert or ignore into captiveportal_mac(mac) values (:mac)", array("mac"=>$mac),$this->captiveportal_mac_types);
|
||||
$this->handle->execute("update captiveportal_mac set ip=:ip, last_checked=:last_checked, pipeno_in = :pipeno_in, pipeno_out = :pipeno_out where mac =:mac ", $params,$this->captiveportal_mac_types);
|
||||
}
|
||||
|
||||
/**
|
||||
* drop address from administration (captiveportal_mac)
|
||||
* @param $mac physical address
|
||||
*/
|
||||
function dropPassthruMAC($mac){
|
||||
$this->handle->execute("delete from captiveportal_mac where mac =:mac ", array("mac"=>$mac),$this->captiveportal_mac_types);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
296
src/opnsense/mvc/app/models/Captiveportal/Rules.php
Normal file
296
src/opnsense/mvc/app/models/Captiveportal/Rules.php
Normal file
@ -0,0 +1,296 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: ad
|
||||
* Date: 05-12-14
|
||||
* Time: 11:28
|
||||
*/
|
||||
|
||||
namespace Captiveportal;
|
||||
|
||||
|
||||
/**
|
||||
* Class Rules
|
||||
* @package Captiveportal
|
||||
*/
|
||||
class Rules {
|
||||
|
||||
/**
|
||||
* config handle
|
||||
* @var Core_Config
|
||||
*/
|
||||
private $config = null;
|
||||
|
||||
|
||||
/**
|
||||
* generated ruleset
|
||||
* @var array
|
||||
*/
|
||||
private $rules = [] ;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
// Request handle to configuration
|
||||
$this->config = \Core\Config::getInstance();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get ipfw tables for authenticated users ( in/out )
|
||||
* @param $zoneid zoneid (number)
|
||||
* @return array
|
||||
*/
|
||||
function getAuthUsersTables($zoneid){
|
||||
return array("in"=>(6*($zoneid-1) )+1,"out"=>(6*($zoneid-1) )+2);
|
||||
}
|
||||
|
||||
/**
|
||||
* get ipfw tables for authenticated hosts ( in/out )
|
||||
* @param $zoneid zoneid (number)
|
||||
* @return array
|
||||
*/
|
||||
function getAuthIPTables($zoneid){
|
||||
return array("in"=>(6*($zoneid-1) )+3,"out"=>(6*($zoneid-1) )+4);
|
||||
}
|
||||
|
||||
/**
|
||||
* get ipfw tables used for authenticated physical addresses
|
||||
* @param $zoneid zoneid (number)
|
||||
* @return array
|
||||
*/
|
||||
function getAuthMACTables($zoneid){
|
||||
return array("in"=>(6*($zoneid-1) )+5,"out"=>(6*($zoneid-1) )+6);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* default rules
|
||||
* rule number range 1..1000
|
||||
*/
|
||||
private function generate_default_rules(){
|
||||
// define general purpose rules, rule number 1 .... 1000
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
$this->rules[] = "# flush ruleset ";
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
$this->rules[] = "flush" ;
|
||||
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
$this->rules[] = "# general purpose rules 1...1000 ";
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
$this->rules[] = "add 100 allow pfsync from any to any";
|
||||
$this->rules[] = "add 110 allow carp from any to any";
|
||||
$this->rules[] = "# layer 2: pass ARP";
|
||||
$this->rules[] = "add 120 pass layer2 mac-type arp,rarp";
|
||||
$this->rules[] = "# OPNsense requires for WPA";
|
||||
$this->rules[] = "add 130 pass layer2 mac-type 0x888e,0x88c7";
|
||||
$this->rules[] = "# PPP Over Ethernet Session Stage/Discovery Stage";
|
||||
$this->rules[] = "add 140 pass layer2 mac-type 0x8863,0x8864";
|
||||
$this->rules[] = "# layer 2: block anything else non-IP(v4/v6)";
|
||||
$this->rules[] = "add 150 deny layer2 not mac-type ip,ipv6";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Always allow traffic to our own host ( all static addresses from configuration )
|
||||
* rule number range 1001..1999
|
||||
*/
|
||||
private function generate_this_host_rules(){
|
||||
// search all static / non wan addresses and add rules to $this->rules
|
||||
$rulenum = 1001 ;
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
$this->rules[] = "# Allow traffic to this hosts static ip's ( 1001..1999 ) ";
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
foreach( $this->config->object()->interfaces->children() as $interface => $content ){
|
||||
if ( $interface != "wan" && $content->ipaddr != "dhcp" ){
|
||||
$this->rules[] = "add ".$rulenum++." allow ip from any to { 255.255.255.255 or ".$content->ipaddr." } in";
|
||||
$this->rules[] = "add ".$rulenum++." allow ip from { 255.255.255.255 or ".$content->ipaddr." } to any out";
|
||||
$this->rules[] = "add ".$rulenum++." allow icmp from { 255.255.255.255 or ".$content->ipaddr." } to any out icmptypes 0";
|
||||
$this->rules[] = "add ".$rulenum++." allow icmp from any to { 255.255.255.255 or ".$content->ipaddr." } in icmptypes 8";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generate zone rules, 4 ipfw tables per zone ( in/out, by host or address )
|
||||
* The tables are calculcated by zoneid using the getAuthxxxTables methods :
|
||||
* 1. authenticated users in
|
||||
* 2. authenticated users out
|
||||
* 3. allowed ip's in
|
||||
* 4. allowed ip's out
|
||||
* 5. allowed mac addresses in ( table contains corresponding ip's )
|
||||
* 6. allowed mac addresses out ( table contains corresponding ip's )
|
||||
*
|
||||
* A pipe to dummynet is automatically created for every stream
|
||||
*
|
||||
* Every zone receives it's own ruleset range of max 998 rules, defined by a starting position of 10.000
|
||||
* ( for example: zone 2 starts @ 12000 )
|
||||
*
|
||||
* rule number ranges 3001..3999, 10000...50000
|
||||
*/
|
||||
private function generate_zones(){
|
||||
foreach( $this->config->object()->captiveportal->children() as $cpzonename => $zone ) {
|
||||
// search interface
|
||||
$interface = $zone->interface->xpath("//" . $zone->interface);
|
||||
|
||||
// allocate tables for captive portal
|
||||
$table_id = (6*($zone->zoneid-1) );
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
$this->rules[] = "# zone " . $cpzonename . " (".$zone->zoneid.") configuration";
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
|
||||
if (count($interface) > 0) {
|
||||
$interface = $interface[0];
|
||||
// authenticated users ( table 1 + 2 )
|
||||
$this->rules[] = "add ".(3000+($zone->zoneid*10)+1)." skipto ".((($zone->zoneid*1000)+10000)+1)." ip from table(".$this->getAuthUsersTables($zone->zoneid)["in"].") to any via ".$interface->if ;
|
||||
$this->rules[] = "add ".(3000+($zone->zoneid*10)+2)." skipto ".((($zone->zoneid*1000)+10000)+1)." ip from any to table(".$this->getAuthUsersTables($zone->zoneid)["in"].") via ".$interface->if ;
|
||||
|
||||
// authenticated hosts ( table 3 + 4 )
|
||||
$this->rules[] = "add ".(3000+($zone->zoneid*10)+3)." skipto ".((($zone->zoneid*1000)+10000)+1)." ip from table(".$this->getAuthIPTables($zone->zoneid)["in"].") to any via ".$interface->if ;
|
||||
$this->rules[] = "add ".(3000+($zone->zoneid*10)+4)." skipto ".((($zone->zoneid*1000)+10000)+1)." ip from any to table(".$this->getAuthIPTables($zone->zoneid)["in"].") via ".$interface->if ;
|
||||
|
||||
// authenticated mac addresses ( table 5 + 6 )
|
||||
$this->rules[] = "add ".(3000+($zone->zoneid*10)+5)." skipto ".((($zone->zoneid*1000)+10000)+1)." ip from table(".$this->getAuthMACTables($zone->zoneid)["in"].") to any via ".$interface->if ;
|
||||
$this->rules[] = "add ".(3000+($zone->zoneid*10)+6)." skipto ".((($zone->zoneid*1000)+10000)+1)." ip from any to table(".$this->getAuthMACTables($zone->zoneid)["in"].") via ".$interface->if ;
|
||||
|
||||
// TODO: solve dummynet kernel issue on outgoing traffic
|
||||
// // dummynet 1,2
|
||||
// $this->rules[] = "add ".((($zone->zoneid*1000)+10000)+1)." pipe tablearg ip from table(".($table_id+1).") to any in via ".$interface->if ;
|
||||
// $this->rules[] = "add ".((($zone->zoneid*1000)+10000)+2)." pipe tablearg ip from any to table(".($table_id+2).") out via ".$interface->if ;
|
||||
//
|
||||
// // dummynet 3,4
|
||||
// $this->rules[] = "add ".((($zone->zoneid*1000)+10000)+3)." pipe tablearg ip from table(".($table_id+3).") to any in via ".$interface->if ;
|
||||
// $this->rules[] = "add ".((($zone->zoneid*1000)+10000)+4)." pipe tablearg ip from table(".($table_id+3).") to any out via ".$interface->if ;
|
||||
// $this->rules[] = "add ".((($zone->zoneid*1000)+10000)+5)." pipe tablearg ip from any to table(".($table_id+4).") in via ".$interface->if ;
|
||||
// $this->rules[] = "add ".((($zone->zoneid*1000)+10000)+6)." pipe tablearg ip from any to table(".($table_id+4).") out via ".$interface->if ;
|
||||
|
||||
// // dummynet 5,6
|
||||
// $this->rules[] = "add ".((($zone->zoneid*1000)+10000)+7)." pipe tablearg ip from table(".($table_id+5).") to any in via ".$interface->if ;
|
||||
// $this->rules[] = "add ".((($zone->zoneid*1000)+10000)+8)." pipe tablearg ip from table(".($table_id+5).") to any out via ".$interface->if ;
|
||||
// $this->rules[] = "add ".((($zone->zoneid*1000)+10000)+9)." pipe tablearg ip from any to table(".($table_id+6).") in via ".$interface->if ;
|
||||
// $this->rules[] = "add ".((($zone->zoneid*1000)+10000)+10)." pipe tablearg ip from any to table(".($table_id+6).") out via ".$interface->if ;
|
||||
|
||||
// statistics for this zone, placeholder to jump to
|
||||
$this->rules[] = "add ".((($zone->zoneid*1000)+10000)+1)." count ip from any to any via ".$interface->if ;
|
||||
|
||||
// jump to accounting section
|
||||
$this->rules[] = "add ".((($zone->zoneid*1000)+10000)+998)." skipto 30000 all from any to any via ".$interface->if ;
|
||||
$this->rules[] = "add ".((($zone->zoneid*1000)+10000)+999)." deny all from any to any not via ".$interface->if ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward all non authenticated traffic from captive portal zones
|
||||
* rule number range 5001..5999
|
||||
*/
|
||||
private function generate_reflect_rules(){
|
||||
$forward_port = 8000 ;
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
$this->rules[] = "# redirect non-authenticated clients to captive portal @ local port ".$forward_port." + zoneid ";
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
foreach( $this->config->object()->captiveportal->children() as $cpzonename => $zone ){
|
||||
// search interface
|
||||
$interface = $zone->interface->xpath("//".$zone->interface);
|
||||
if (count($interface) > 0){
|
||||
$interface = $interface[0] ;
|
||||
if ($interface->ipaddr != null){
|
||||
// add forward rule to this zone's http instance @ $forward_port + $zone->zoneid
|
||||
$this->rules[] ="add ".(5000+$zone->zoneid)." fwd 127.0.0.1,".($forward_port + $zone->zoneid )." tcp from any to any dst-port 80 in via ".$interface->if;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* for accounting statistics we setup a separate section in our config
|
||||
* rule number range 30000..65500
|
||||
*/
|
||||
private function generate_accounting_section(){
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
$this->rules[] = "# setup accounting section, first rule is counting all CP traffic ";
|
||||
$this->rules[] = "# rule 65500 unlocks the traffic already authorized from a CP zone";
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
$this->rules[] = "add 30000 set 0 count ip from any to any ";
|
||||
$this->rules[] = "add 65500 pass ip from any to any ";
|
||||
}
|
||||
|
||||
/**
|
||||
* generate closure tag, block all traffic coming from captiveportal interfaces
|
||||
* rule number range 6001..6999
|
||||
*/
|
||||
private function generate_closure(){
|
||||
$cpinterfaces = [];
|
||||
# find all cp interfaces
|
||||
foreach( $this->config->object()->captiveportal->children() as $cpzonename => $zone ) {
|
||||
// search interface
|
||||
$interface = $zone->interface->xpath("//" . $zone->interface);
|
||||
if (count($interface) > 0) {
|
||||
$interface = $interface[0];
|
||||
$cpinterfaces[$interface->if->__toString()] = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// generate accept rules for every interface not in captive portal
|
||||
$ruleid = 6001 ;
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
$this->rules[] = "# accept traffic from all interfaces not used by captive portal (5001..5999) ";
|
||||
$this->rules[] = "#=========================================================================================================";
|
||||
foreach( $this->config->object()->interfaces->children() as $interface => $content ){
|
||||
if ( !isset($cpinterfaces[$content->if->__toString()])){
|
||||
$this->rules[] = "add ".($ruleid++)." allow all from any to any via ".$content->if ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->rules[] = "# let the responses from the captive portal web server back out";
|
||||
$this->rules[] = "add ".($ruleid++)." pass tcp from any to any out";
|
||||
|
||||
// block every thing else (not mentioned before)
|
||||
$this->rules[] = "# block everything else";
|
||||
$this->rules[] = "add ".($ruleid)." skipto 65534 all from any to any";
|
||||
$this->rules[] = "add 65534 deny all from any to any";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* load ruleset
|
||||
*/
|
||||
public function generate($filename){
|
||||
/*
|
||||
* reset rules
|
||||
*/
|
||||
$this->rules = [] ;
|
||||
|
||||
/*
|
||||
* generate new
|
||||
*/
|
||||
$this->generate_default_rules();
|
||||
$this->generate_this_host_rules();
|
||||
$this->generate_zones();
|
||||
$this->generate_reflect_rules();
|
||||
$this->generate_accounting_section();
|
||||
$this->generate_closure();
|
||||
|
||||
// ruleset array -> text
|
||||
$ruleset_txt = "";
|
||||
$prev_rule = "#";
|
||||
foreach($this->rules as $rule){
|
||||
if (trim($rule)[0] == '#' && trim($prev_rule)[0] != "#" ) $ruleset_txt .= "\n";
|
||||
$ruleset_txt .= $rule."\n";
|
||||
$prev_rule = $rule ;
|
||||
}
|
||||
|
||||
// write to file
|
||||
file_put_contents($filename,$ruleset_txt);
|
||||
}
|
||||
|
||||
}
|
||||
130
src/opnsense/mvc/app/models/Core/Config.php
Normal file
130
src/opnsense/mvc/app/models/Core/Config.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php namespace Core;
|
||||
|
||||
/**
|
||||
* Class ConfigException
|
||||
* @package Core
|
||||
*/
|
||||
class ConfigException extends \Exception { }
|
||||
|
||||
/**
|
||||
* Class Config
|
||||
* @package Core
|
||||
*/
|
||||
class Config extends \Core\Singleton {
|
||||
|
||||
/**
|
||||
* config file location ( path + name )
|
||||
* @var string
|
||||
*/
|
||||
private $config_file = "";
|
||||
|
||||
/**
|
||||
* XMLDocument type reference to config
|
||||
* @var XMLDocument
|
||||
*/
|
||||
private $configxml = null ;
|
||||
|
||||
/**
|
||||
* SimpleXML type reference to config
|
||||
* @var SimpleXML
|
||||
*/
|
||||
private $simplexml = null;
|
||||
|
||||
/**
|
||||
* status field: valid config loaded
|
||||
* @var bool
|
||||
*/
|
||||
private $isValid = False;
|
||||
|
||||
/**
|
||||
* Load config file
|
||||
* @throws ConfigException
|
||||
*/
|
||||
private function load(){
|
||||
// exception handling
|
||||
if ( !file_exists($this->config_file) ) throw new ConfigException('file not found') ;
|
||||
$xml = file_get_contents($this->config_file);
|
||||
if (trim($xml) == '') {
|
||||
throw new ConfigException('empty file') ;
|
||||
}
|
||||
|
||||
$this->configxml = new \DOMDocument;
|
||||
$this->configxml->loadXML($xml);
|
||||
$this->simplexml = simplexml_import_dom($this->configxml);
|
||||
$this->isValid = true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
*/
|
||||
private function checkvalid(){
|
||||
if ( !$this->isValid ) throw new ConfigException('no valid config loaded') ;
|
||||
}
|
||||
|
||||
/*
|
||||
* parse configuration and dump to std output (test)
|
||||
* @param DOMElement $node
|
||||
* @param string $nodename
|
||||
* @throws ConfigException
|
||||
*/
|
||||
public function dump($node=null,$nodename=""){
|
||||
$this->checkvalid();
|
||||
// root node
|
||||
if ($node == null ) $node = $this->configxml;
|
||||
|
||||
$subNodes = $node->childNodes ;
|
||||
foreach($subNodes as $subNode){
|
||||
if ( $subNode->nodeType == XML_TEXT_NODE &&(strlen(trim($subNode->wholeText))>=1)) {
|
||||
print($nodename.".". $node->tagName." " .$subNode->nodeValue ."\n");
|
||||
}
|
||||
|
||||
if ( $subNode->hasChildNodes() ){
|
||||
if ( $nodename != "" ) $tmp = $nodename.".".$node->tagName;
|
||||
elseif ($node != $this->configxml) $tmp = $node->tagName;
|
||||
else $tmp = "";
|
||||
|
||||
$this->dump($subNode,$tmp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* init new config object, try to load current configuration
|
||||
* (executed via Singleton)
|
||||
*/
|
||||
protected function init() {
|
||||
$this->config_file = \Phalcon\DI\FactoryDefault::getDefault()->get('config')->globals->config_path . "config.xml";
|
||||
try {
|
||||
$this->load();
|
||||
} catch (\Exception $e){
|
||||
$this->configxml = null ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a xpath expression on config.xml
|
||||
* @param $query
|
||||
* @return \DOMNodeList
|
||||
* @throws ConfigException
|
||||
*/
|
||||
function xpath($query){
|
||||
$this->checkvalid();
|
||||
$xpath = new \DOMXPath($this->configxml);
|
||||
return $xpath->query($query);
|
||||
}
|
||||
|
||||
/*
|
||||
* object representation of xml document via simplexml, references the same underlying model
|
||||
* @return SimpleXML
|
||||
* @throws ConfigException
|
||||
*/
|
||||
function object(){
|
||||
$this->checkvalid();
|
||||
return $this->simplexml;
|
||||
}
|
||||
|
||||
}
|
||||
101
src/opnsense/mvc/app/models/Core/Shell.php
Normal file
101
src/opnsense/mvc/app/models/Core/Shell.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: ad
|
||||
* Date: 08-12-14
|
||||
* Time: 08:41
|
||||
*/
|
||||
|
||||
namespace Core;
|
||||
|
||||
|
||||
class Shell
|
||||
{
|
||||
|
||||
/**
|
||||
* simulation mode, only print commands, dom not execute
|
||||
* @var bool
|
||||
*/
|
||||
private $simulate = false;
|
||||
|
||||
/**
|
||||
* debug mode
|
||||
* @var bool
|
||||
*/
|
||||
private $debug = false;
|
||||
|
||||
/**
|
||||
* new shell object
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
// init, set simulation mode / debug autoput
|
||||
$this->simulate = \Phalcon\DI\FactoryDefault::getDefault()->get('config')->globals->simulate_mode;
|
||||
$this->debug = \Phalcon\DI\FactoryDefault::getDefault()->get('config')->globals->debug;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell command
|
||||
* @param string $command command to execute
|
||||
* @param bool $mute
|
||||
* @param bool $clearsigmask
|
||||
*/
|
||||
private function _exec($command, $mute = false, $clearsigmask = false,&$output=null){
|
||||
$oarr = array();
|
||||
$retval = 0;
|
||||
|
||||
// debug output
|
||||
if ($this->debug) {
|
||||
print("Shell->exec : " . $command . " \n");
|
||||
}
|
||||
|
||||
// only execute actual command if not in simulation mode
|
||||
if (!$this->simulate) {
|
||||
if ($clearsigmask) {
|
||||
$oldset = array();
|
||||
pcntl_sigprocmask(SIG_SETMASK, array(), $oldset);
|
||||
}
|
||||
|
||||
$garbage = exec("$command 2>&1", $output, $retval);
|
||||
|
||||
if (($retval <> 0) && ($mute === false)) {
|
||||
//log_error(sprintf(gettext("The command '%1\$s' returned exit code '%2\$d', the output was '%3\$s' "), implode(" ", $output);
|
||||
// TODO: log
|
||||
unset($output);
|
||||
}
|
||||
|
||||
|
||||
if ($clearsigmask) {
|
||||
pcntl_sigprocmask(SIG_SETMASK, $oldset);
|
||||
}
|
||||
|
||||
unset($oarr);
|
||||
return $retval;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* execute command or list of commands
|
||||
*
|
||||
* @param string/Array() $command command to execute
|
||||
* @param bool $mute
|
||||
* @param bool $clearsigmask
|
||||
* @param Array() &$output
|
||||
*/
|
||||
function exec($command, $mute = false, $clearsigmask = false,&$output=null)
|
||||
{
|
||||
if (is_array($command)){
|
||||
foreach($command as $comm ){
|
||||
$this->_exec($comm,$mute, $clearsigmask ,$output);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$this->_exec($command,$mute, $clearsigmask ,$output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
68
src/opnsense/mvc/app/models/Core/Singleton.php
Normal file
68
src/opnsense/mvc/app/models/Core/Singleton.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: ad
|
||||
* Date: 05-12-14
|
||||
* Time: 10:35
|
||||
*/
|
||||
|
||||
namespace Core;
|
||||
|
||||
|
||||
/**
|
||||
* Class Singleton
|
||||
* @package Core
|
||||
*/
|
||||
/**
|
||||
* Class Singleton
|
||||
* @package Core
|
||||
*/
|
||||
abstract class Singleton
|
||||
{
|
||||
/**
|
||||
* holder for singleton objects
|
||||
* @var static
|
||||
*/
|
||||
private static $instances;
|
||||
|
||||
/**
|
||||
* Cannot construct Singleton, use getInstance instead
|
||||
*/
|
||||
final private function __construct()
|
||||
{
|
||||
// call init on newly created object
|
||||
static::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not clone
|
||||
* @throws Exception
|
||||
*/
|
||||
final private function __clone()
|
||||
{
|
||||
throw new \Exception("An instance of ".get_called_class()." cannot be cloned.");
|
||||
}
|
||||
|
||||
/**
|
||||
* get (new) instance
|
||||
* @return object
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
$className = get_called_class();
|
||||
|
||||
if(isset(self::$instances[$className]) == false) {
|
||||
self::$instances[$className] = new static();
|
||||
}
|
||||
return self::$instances[$className];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* by default there must be an inherited init method
|
||||
* so an extended class could simply
|
||||
* specify its own init
|
||||
*/
|
||||
protected function init(){}
|
||||
|
||||
}
|
||||
9
src/opnsense/mvc/app/views/index.volt
Normal file
9
src/opnsense/mvc/app/views/index.volt
Normal file
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Phalcon PHP Framework</title>
|
||||
</head>
|
||||
<body>
|
||||
{{ content() }}
|
||||
</body>
|
||||
</html>
|
||||
3
src/opnsense/mvc/app/views/index/index.volt
Normal file
3
src/opnsense/mvc/app/views/index/index.volt
Normal file
@ -0,0 +1,3 @@
|
||||
<h1>Congratulations!</h1>
|
||||
|
||||
<p>You're now flying with Phalcon. Great things are about to happen!</p>
|
||||
21
src/opnsense/mvc/script/load_falcon.php
Normal file
21
src/opnsense/mvc/script/load_falcon.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* User: ad
|
||||
* Date: 08-12-14
|
||||
* Time: 20:23
|
||||
*/
|
||||
use Phalcon\DI\FactoryDefault;
|
||||
use Phalcon\Loader;
|
||||
|
||||
$di = new FactoryDefault();
|
||||
$config = include_once(__DIR__."/../app/config/config.php");
|
||||
|
||||
$loader = new Loader();
|
||||
$loader->registerDirs(
|
||||
array(
|
||||
$config->application->controllersDir,
|
||||
$config->application->modelsDir
|
||||
)
|
||||
)->register();
|
||||
|
||||
$di->set('config',$config);
|
||||
38
src/opnsense/mvc/script/test.php
Normal file
38
src/opnsense/mvc/script/test.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
require_once("load_falcon.php");
|
||||
|
||||
$cpc = new Captiveportal\CPClient();
|
||||
//$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('//pfsense/interfaces/*') );
|
||||
|
||||
//$rules= new \Core\Captiveportal\Rules();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user