mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-15 00:54:41 +00:00
(Captiveportal, new) send radius accounting messages and cleanup sessions
This commit is contained in:
parent
fe45340cb9
commit
3cfac591ba
@ -33,6 +33,7 @@ import ujson
|
||||
import time
|
||||
import syslog
|
||||
import traceback
|
||||
import subprocess
|
||||
from lib import Config
|
||||
from lib.db import DB
|
||||
from lib.arp import ARP
|
||||
@ -190,6 +191,7 @@ def main():
|
||||
""" Background process loop, runs as backend daemon for all zones. only one should be active at all times.
|
||||
The main job of this procedure is to sync the administration with the actual situation in the ipfw firewall.
|
||||
"""
|
||||
last_cleanup_timestamp = 0
|
||||
bgprocess = CPBackgroundProcess()
|
||||
bgprocess.initialize_fixed()
|
||||
|
||||
@ -198,6 +200,11 @@ def main():
|
||||
# open database
|
||||
bgprocess.db.open()
|
||||
|
||||
# cleanup old settings, every 5 minutes
|
||||
if time.time() - last_cleanup_timestamp > 300:
|
||||
bgprocess.db.cleanup_sessions()
|
||||
last_cleanup_timestamp = time.time()
|
||||
|
||||
# reload cached arp table contents
|
||||
bgprocess.arp.reload()
|
||||
|
||||
@ -211,6 +218,9 @@ def main():
|
||||
# close the database handle while waiting for the next poll
|
||||
bgprocess.db.close()
|
||||
|
||||
# process accounting messages (uses php script, for reuse of Auth classes)
|
||||
subprocess.call(['/usr/local/opnsense/scripts/OPNsense/CaptivePortal/process_accounting_messages.php'])
|
||||
|
||||
# sleep
|
||||
time.sleep(5)
|
||||
except KeyboardInterrupt:
|
||||
|
||||
@ -355,3 +355,49 @@ class DB(object):
|
||||
else:
|
||||
self._connection.commit()
|
||||
return 'update'
|
||||
|
||||
def cleanup_sessions(self):
|
||||
""" cleanup removed sessions, but wait for accounting to finish when busy
|
||||
"""
|
||||
cur = self._connection.cursor()
|
||||
cur.execute(""" delete
|
||||
from cp_clients
|
||||
where cp_clients.deleted = 1
|
||||
and not exists (
|
||||
select 1
|
||||
from accounting_state
|
||||
where accounting_state.zoneid = cp_clients.zoneid
|
||||
and accounting_state.sessionid = cp_clients.sessionid
|
||||
and accounting_state.state <> 'STOPPED'
|
||||
)
|
||||
""")
|
||||
cur.execute(""" delete
|
||||
from accounting_state
|
||||
where not exists (
|
||||
select 1
|
||||
from cp_clients
|
||||
where cp_clients.zoneid = accounting_state.zoneid
|
||||
and cp_clients.sessionid = accounting_state.sessionid
|
||||
)
|
||||
""")
|
||||
cur.execute(""" delete
|
||||
from session_info
|
||||
where not exists (
|
||||
select 1
|
||||
from cp_clients
|
||||
where session_info.zoneid = cp_clients.zoneid
|
||||
and session_info.sessionid = cp_clients.sessionid
|
||||
)
|
||||
""")
|
||||
|
||||
cur.execute(""" delete
|
||||
from session_restrictions
|
||||
where not exists (
|
||||
select 1
|
||||
from cp_clients
|
||||
where session_restrictions.zoneid = cp_clients.zoneid
|
||||
and session_restrictions.sessionid = cp_clients.sessionid
|
||||
)
|
||||
""")
|
||||
|
||||
self._connection.commit()
|
||||
|
||||
96
src/opnsense/scripts/OPNsense/CaptivePortal/process_accounting_messages.php
Executable file
96
src/opnsense/scripts/OPNsense/CaptivePortal/process_accounting_messages.php
Executable file
@ -0,0 +1,96 @@
|
||||
#!/usr/local/bin/php
|
||||
<?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.
|
||||
*
|
||||
*/
|
||||
|
||||
require_once('script/load_phalcon.php');
|
||||
|
||||
use OPNsense\Core\Config;
|
||||
use OPNsense\Auth\AuthenticationFactory;
|
||||
|
||||
// open database
|
||||
$database_filename = '/var/captiveportal/captiveportal.sqlite';
|
||||
$db = new SQLite3($database_filename);
|
||||
|
||||
// query all sessions with client restrictions
|
||||
$result = $db->query('
|
||||
select c.zoneid
|
||||
, c.sessionid
|
||||
, c.username
|
||||
, c.authenticated_via
|
||||
, c.deleted
|
||||
, c.created
|
||||
, accs.state
|
||||
from cp_clients c
|
||||
inner join session_restrictions sr on sr.zoneid = c.zoneid and sr.sessionid = c.sessionid
|
||||
left join session_info si on c.zoneid = si.zoneid and c.sessionid = si.sessionid
|
||||
left join accounting_state accs on accs.zoneid = c.zoneid and accs.sessionid = c.sessionid
|
||||
order by c.authenticated_via
|
||||
');
|
||||
|
||||
// process all sessions
|
||||
while($row = $result->fetchArray(SQLITE3_ASSOC) ){
|
||||
$authFactory = new OPNsense\Auth\AuthenticationFactory;
|
||||
$authenticator = $authFactory->get($row['authenticated_via']);
|
||||
if ($authenticator != null) {
|
||||
if ($row['state'] == null) {
|
||||
// new accounting state, send start event (if applicable)
|
||||
$stmt = $db->prepare('insert into accounting_state(zoneid, sessionid, state)
|
||||
values (:zoneid, :sessionid, \'RUNNING\')');
|
||||
$stmt->bindParam(':zoneid', $row['zoneid']);
|
||||
$stmt->bindParam(':sessionid', $row['sessionid']);
|
||||
$stmt->execute();
|
||||
if (method_exists($authenticator,'startAccounting')) {
|
||||
// send start accounting event
|
||||
$authenticator->startAccounting($row['username'], $row['sessionid']);
|
||||
}
|
||||
} elseif ($row['deleted'] == 1 && $row['state'] != 'STOPPED') {
|
||||
// stop accounting, send stop event (if applicable)
|
||||
$stmt = $db->prepare('update accounting_state
|
||||
set state = \'STOPPED\'
|
||||
where zoneid = :zoneid
|
||||
and sessionid = :sessionid');
|
||||
$stmt->bindParam(':zoneid', $row['zoneid']);
|
||||
$stmt->bindParam(':sessionid', $row['sessionid']);
|
||||
$stmt->execute();
|
||||
if (method_exists($authenticator,'startAccounting')) {
|
||||
|
||||
$time_spend = time() - $row['created'];
|
||||
$authenticator->stopAccounting($row['username'], $row['sessionid'], $time_spend);
|
||||
}
|
||||
} elseif ($row['state'] != 'STOPPED') {
|
||||
// send interim updates (if applicable)
|
||||
if (method_exists($authenticator,'updateAccounting')) {
|
||||
// send interim update event
|
||||
$time_spend = time() - $row['created'];
|
||||
$authenticator->updateAccounting($row['username'], $row['sessionid'], $time_spend);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$db->close();
|
||||
Loading…
x
Reference in New Issue
Block a user