mirror of
https://github.com/fusionpbx/fusionpbx.git
synced 2026-01-06 11:43:50 +00:00
Rename app/switch/resources/service/event_guard.php to app/event_guard/resources/service/event_guard.php
Move the event_guard service to its own directory name.
This commit is contained in:
@@ -1,441 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (C) 2022 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
//check the permission
|
||||
if (defined('STDIN')) {
|
||||
$document_root = str_replace("\\", "/", $_SERVER["PHP_SELF"]);
|
||||
preg_match("/^(.*)\/app\/.*$/", $document_root, $matches);
|
||||
$document_root = $matches[1];
|
||||
set_include_path($document_root);
|
||||
$_SERVER["DOCUMENT_ROOT"] = $document_root;
|
||||
require_once "resources/require.php";
|
||||
}
|
||||
else {
|
||||
//only allow running this from command line
|
||||
exit;
|
||||
include "root.php";
|
||||
require_once "resources/require.php";
|
||||
require_once "resources/pdo.php";
|
||||
}
|
||||
|
||||
//increase limits
|
||||
set_time_limit(0);
|
||||
ini_set('max_execution_time', 0);
|
||||
ini_set('memory_limit', '256M');
|
||||
|
||||
//save the arguments to variables
|
||||
$script_name = $argv[0];
|
||||
if (!empty($argv[1])) {
|
||||
parse_str($argv[1], $_GET);
|
||||
}
|
||||
|
||||
//set the variables
|
||||
if (isset($_GET['hostname'])) {
|
||||
$hostname = urldecode($_GET['hostname']);
|
||||
}
|
||||
if (isset($_GET['debug'])) {
|
||||
if (is_numeric($_GET['debug'])) {
|
||||
$debug_level = $_GET['debug'];
|
||||
}
|
||||
$debug = true;
|
||||
}
|
||||
|
||||
//set the php operating system
|
||||
$php_os = strtolower(PHP_OS);
|
||||
|
||||
//define the firewall command
|
||||
if ($php_os == 'freebsd') {
|
||||
$firewall = 'pf';
|
||||
}
|
||||
if ($php_os == 'linux') {
|
||||
$firewall = 'iptables';
|
||||
}
|
||||
|
||||
//add the iptables chains
|
||||
if ($firewall == 'iptables') {
|
||||
//create a chain array
|
||||
$chains[] = 'sip-auth-ip';
|
||||
$chains[] = 'sip-auth-fail';
|
||||
|
||||
//loop through the chains
|
||||
foreach ($chains as $chain) {
|
||||
$command = 'iptables --list INPUT | grep '.$chain;
|
||||
if ($debug) {
|
||||
echo $command."\n";
|
||||
}
|
||||
if (strlen(shell($command)) == 0) {
|
||||
system('iptables --new '.$chain);
|
||||
system('iptables -I INPUT -j '.$chain);
|
||||
echo "Add iptables ".$chain." chain\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//test a specific address
|
||||
//$ip_address = '10.7.0.253';
|
||||
//$result = access_allowed($ip_address);
|
||||
|
||||
//get the settings
|
||||
//$setting_name = $_SESSION['category']['subcategory']['text'];
|
||||
|
||||
//connect to event socket
|
||||
$socket = new event_socket;
|
||||
if (!$socket->connect($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password'])) {
|
||||
echo "Unable to connect to event socket\n";
|
||||
}
|
||||
|
||||
//loop through the switch events
|
||||
$cmd = "event json ALL";
|
||||
$result = $socket->request($cmd);
|
||||
while ($socket) {
|
||||
|
||||
//read the socket
|
||||
$response = $socket->read_event();
|
||||
|
||||
//decode the response
|
||||
$array = json_decode($response['$'], true);
|
||||
|
||||
//registration failed - block IP address unless they are registered,
|
||||
if ($array['Event-Subclass'] == 'sofia::register_failure') {
|
||||
//not registered so block the address
|
||||
if (!access_allowed($array['network-ip'])) {
|
||||
block($array['network-ip'], 'sip-auth-fail', $array);
|
||||
}
|
||||
}
|
||||
|
||||
//registration to the IP address
|
||||
if ($array['Event-Subclass'] == 'sofia::pre_register') {
|
||||
if (isset($array['to-host'])) {
|
||||
$is_valid_ip = filter_var($array['to-host'], FILTER_VALIDATE_IP);
|
||||
if ($is_valid_ip) {
|
||||
//if not registered block the address
|
||||
if (!access_allowed($array['network-ip'])) {
|
||||
block($array['network-ip'], 'sip-auth-ip', $array);
|
||||
}
|
||||
|
||||
//debug info
|
||||
if ($debug) {
|
||||
echo "network-ip ".$array['network-ip']."\n";
|
||||
echo "to-host ".$array['to-host']."\n";
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//debug information
|
||||
if ($debug && ($array['Event-Subclass'] == 'sofia::register_failure' || $array['Event-Subclass'] == 'sofia::pre_register')) {
|
||||
echo "\n";
|
||||
print_r($array);
|
||||
|
||||
//echo "event_name: ".$array['Event-Name']."\n";
|
||||
//echo "event_type: ".$array['event_type']."\n";
|
||||
//echo "event_subclass: ".$array['Event-Subclass']."\n";
|
||||
//echo "status: ".$array['status']."\n";
|
||||
//echo "network_ip: ".$array['network-ip']."\n";
|
||||
//echo "channel_state: ".$array['Channel-State']."\n";
|
||||
//echo "channel_call_state: ".$array['Channel-Call-State']."\n";
|
||||
//echo "call_direction: ".$array['Call-Direction']."\n";
|
||||
//echo "channel_call_uuid: ".$array['Channel-Call-UUID']."\n";
|
||||
//echo "answer_state: ".$array['Answer-State']."\n";
|
||||
//echo "hangup_cause: ".$array['Hangup-Cause']."\n";
|
||||
//echo "to-host: $array['to-host']\n";
|
||||
//echo "\n";
|
||||
}
|
||||
|
||||
//debug info
|
||||
if ($debug && $debug_level == '2') {
|
||||
//current memory
|
||||
$memory_usage = memory_get_usage();
|
||||
|
||||
//peak memory
|
||||
$memory_peak = memory_get_peak_usage();
|
||||
echo "\n";
|
||||
echo 'Current memory: ' . round($memory_usage / 1024) . " KB\n";
|
||||
echo 'Peak memory: ' . round($memory_peak / 1024) . " KB\n\n";
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
|
||||
//run command and capture standard output
|
||||
function shell($command) {
|
||||
ob_start();
|
||||
$result = system($command);
|
||||
ob_get_clean();
|
||||
return $result;
|
||||
}
|
||||
|
||||
//block an ip address
|
||||
function block($ip_address, $filter, $array) {
|
||||
//set global variables
|
||||
global $firewall;
|
||||
|
||||
//invalid ip address
|
||||
if (!filter_var($ip_address, FILTER_VALIDATE_IP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//create the cache object
|
||||
$cache = new cache;
|
||||
|
||||
if (!is_blocked($ip_address)) {
|
||||
//log the blocked ip address
|
||||
openlog("fusionpbx", LOG_PID | LOG_PERROR);
|
||||
syslog(LOG_WARNING, "fusionpbx: blocked: [ip_address: ".$ip_address.", filter: ".$filter.", to-user: ".$array['to-user'].", to-host: ".$array['to-host'].", line: ".__line__."]");
|
||||
closelog();
|
||||
|
||||
//add the blocked ip address to the cache
|
||||
$cache->set("switch:blocked:".$ip_address, 'true');
|
||||
|
||||
//run the block command for iptables
|
||||
if ($firewall == 'iptables') {
|
||||
//example: iptables -I INPUT -s 127.0.0.1 -j DROP
|
||||
$command = 'iptables -I '.$filter.' -s '.$ip_address.' -j DROP';
|
||||
$result = shell($command);
|
||||
}
|
||||
|
||||
//run the block command for pf
|
||||
if ($firewall == 'pf') {
|
||||
//example: pfctl -t sip-auth-ip -T add 127.0.0.5/32
|
||||
$command = 'pfctl -t '.$filter.' -T add '.$ip_address.'/32';
|
||||
$result = shell($command);
|
||||
}
|
||||
|
||||
//send debug information to the console
|
||||
if ($debug) {
|
||||
echo "blocked address ".$ip_address .", line ".__line__."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//unblock the ip address
|
||||
function unblock($ip_address, $chain) {
|
||||
//set global variables
|
||||
global $firewall;
|
||||
|
||||
//invalid ip address
|
||||
if (!filter_var($ip_address, FILTER_VALIDATE_IP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//create the cache object
|
||||
$cache = new cache;
|
||||
|
||||
//delete the blocked ip address from the cache
|
||||
$cache->delete("switch:blocked:".$ip_address);
|
||||
|
||||
//unblock the address
|
||||
if ($firewall == 'iptables') {
|
||||
$command = 'iptables -L -n --line-numbers | grep '.$ip_address;
|
||||
$result = shell($command);
|
||||
echo "\n". $command . " line ".__line__." result ".$result."\n";
|
||||
if (strlen($result) > 3) {
|
||||
$array = explode(' ', trim($result));
|
||||
$line_number = trim($array[0]);
|
||||
|
||||
//$result = shell('iptables -D INPUT '.$line_number);
|
||||
$command = 'iptables -D '.$chain.' '.$line_number;
|
||||
$result = shell($command);
|
||||
echo "Unblock address ".$ip_address ." line ".$line_number." command ".$command." result ".$result."\n";
|
||||
}
|
||||
}
|
||||
|
||||
//unblock the address
|
||||
if ($firewall == 'pf') {
|
||||
//example: pfctl -t sip-auth-ip -T delete 127.0.0.5/32
|
||||
$command = 'pfctl -t '.$filter.' -T delete '.$ip_address.'/32';
|
||||
$result = shell($command);
|
||||
}
|
||||
|
||||
//send debug information to the console
|
||||
if ($debug) {
|
||||
echo "Unblock address ".$ip_address ."\n";
|
||||
}
|
||||
}
|
||||
|
||||
//is the ip address blocked
|
||||
function is_blocked($ip_address) {
|
||||
//set global variables
|
||||
global $firewall;
|
||||
|
||||
//invalid ip address
|
||||
if (!filter_var($ip_address, FILTER_VALIDATE_IP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//create the cache object
|
||||
$cache = new cache;
|
||||
|
||||
//set blocked to false by default
|
||||
$blocked = false;
|
||||
|
||||
//check the cache to see if the address is blocked
|
||||
if ($cache->get("switch:blocked:".$ip_address) === 'true') {
|
||||
$blocked = true;
|
||||
}
|
||||
else {
|
||||
//run command to see if address is blocked
|
||||
if ($firewall == 'iptables') {
|
||||
//check to see if the address is blocked
|
||||
$command = 'iptables -L -n --line-numbers | grep '.$ip_address;
|
||||
//echo $command."\n";
|
||||
$result = shell($command);
|
||||
if (strlen($result) > 3) {
|
||||
//address is blocked but not cached add it to the cache
|
||||
$cache->set("switch:blocked:".$ip_address, 'true');
|
||||
|
||||
//set blocked to true
|
||||
$blocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
//run command to see if address is blocked
|
||||
if ($firewall == 'pf') {
|
||||
//check to see if the address is blocked
|
||||
$command = 'pfctl -t ".$filter." -Ts | grep '.$ip_address;
|
||||
//echo $command."\n";
|
||||
$result = shell($command);
|
||||
if (strlen($result) > 3) {
|
||||
//address is blocked but not cached add it to the cache
|
||||
$cache->set("switch:blocked:".$ip_address, 'true');
|
||||
|
||||
//set blocked to true
|
||||
$blocked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $blocked;
|
||||
}
|
||||
|
||||
//is the ip address registered
|
||||
function is_registered($ip_address) {
|
||||
//invalid ip address
|
||||
if (!filter_var($ip_address, FILTER_VALIDATE_IP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$registered = false;
|
||||
$command = "fs_cli -x 'show registrations as json' ";
|
||||
$result = shell($command);
|
||||
$array = json_decode($result, true);
|
||||
foreach ($array['rows'] as $row) {
|
||||
if ($row['network_ip'] == $ip_address) {
|
||||
$registered = true;
|
||||
}
|
||||
}
|
||||
//print_r($array);
|
||||
return $registered;
|
||||
}
|
||||
|
||||
//determine if the IP address has been allowed by the access control list node cidr
|
||||
function access_allowed($ip_address) {
|
||||
//define global variables
|
||||
global $debug;
|
||||
|
||||
//check the cache to see if the address is allowed
|
||||
$cache = new cache;
|
||||
if ($cache->get("switch:allowed:".$ip_address) === 'true') {
|
||||
//debug info
|
||||
if ($debug) {
|
||||
echo "allowed by: cache\n";
|
||||
}
|
||||
|
||||
//return boolean true
|
||||
return true;
|
||||
}
|
||||
|
||||
//auto allow if there is a registration from the same IP address
|
||||
if (is_registered($ip_address)) {
|
||||
//save address to the cache as allowed
|
||||
$cache->set("switch:allowed:".$ip_address, 'true');
|
||||
|
||||
//debug info
|
||||
if ($debug) {
|
||||
echo "allowed by: registration\n";
|
||||
}
|
||||
|
||||
//return boolean true
|
||||
return true;
|
||||
}
|
||||
|
||||
//allow access if the cidr address is allowed
|
||||
if (access_control_allowed($ip_address)) {
|
||||
//save address to the cache as allowed
|
||||
$cache->set("switch:allowed:".$ip_address, 'true');
|
||||
|
||||
//debug info
|
||||
if ($debug) {
|
||||
echo "allowed by: access controls\n";
|
||||
}
|
||||
|
||||
//return boolean true
|
||||
return true;
|
||||
}
|
||||
|
||||
//return
|
||||
return false;
|
||||
}
|
||||
|
||||
//determine if the IP address has been allowed by the access control list node cidr
|
||||
function access_control_allowed($ip_address) {
|
||||
|
||||
//invalid ip address
|
||||
if (!filter_var($ip_address, FILTER_VALIDATE_IP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//get the access control allowed nodes
|
||||
$sql = "select access_control_node_uuid, access_control_uuid, node_cidr, node_description ";
|
||||
$sql .= "from v_access_control_nodes ";
|
||||
$sql .= "where node_type = 'allow' ";
|
||||
$sql .= "and length(node_cidr) > 0 ";
|
||||
$parameters = null;
|
||||
$database = new database;
|
||||
$allowed_nodes = $database->select($sql, $parameters, 'all');
|
||||
|
||||
//default authorized to false
|
||||
$allowed = false;
|
||||
|
||||
//use the ip address to get the authorized nodes
|
||||
foreach($allowed_nodes as $row) {
|
||||
if (check_cidr($row['node_cidr'], $ip_address)) {
|
||||
//debug info
|
||||
if ($debug) {
|
||||
print_r($row);
|
||||
echo $ip_address."\n";
|
||||
}
|
||||
|
||||
//set the allowed to true
|
||||
$allowed = true;
|
||||
|
||||
//exit the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//return
|
||||
return $allowed;
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user