summaryrefslogtreecommitdiff
path: root/misc/freeswitch/scripts/event
diff options
context:
space:
mode:
Diffstat (limited to 'misc/freeswitch/scripts/event')
-rw-r--r--misc/freeswitch/scripts/event/dump_variables.lua52
-rw-r--r--misc/freeswitch/scripts/event/event.lua33
-rw-r--r--misc/freeswitch/scripts/event/perimeter.lua107
-rw-r--r--misc/freeswitch/scripts/event/perimeter_defense.lua114
4 files changed, 191 insertions, 115 deletions
diff --git a/misc/freeswitch/scripts/event/dump_variables.lua b/misc/freeswitch/scripts/event/dump_variables.lua
new file mode 100644
index 0000000..96eb8f7
--- /dev/null
+++ b/misc/freeswitch/scripts/event/dump_variables.lua
@@ -0,0 +1,52 @@
+-- Gemeinschaft 5 module: dump_variables event handler class
+-- (c) AMOOMA GmbH 2012-2013
+--
+
+module(...,package.seeall)
+
+
+function handler_class()
+ return DumpVariables
+end
+
+
+DumpVariables = {}
+
+
+function DumpVariables.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.log = arg.log;
+ self.class = 'DumpVariables'
+ self.dump_file = arg.file or '/var/log/freeswitch/variables';
+
+ return object;
+end
+
+
+function DumpVariables.event_handlers(self)
+ return { CHANNEL_CREATE = { [true] = self.channel_data } }
+end
+
+
+function DumpVariables.channel_data(self, event)
+ local sequence = event:getHeader('Event-Sequence');
+ local direction = event:getHeader('Call-Direction');
+
+ if not direction or direction ~= 'inbound' then
+ return;
+ end
+
+ local file = io.open(self.dump_file, 'w');
+ if not file then
+ self.log:error('[', event.sequence, '] DUMP_VARIABLES - could not open file for writing: ', self.dump_file);
+ return;
+ end
+
+ self.log:debug('[', event.sequence, '] DUMP_VARIABLES - dumping channel data to: ', self.dump_file);
+
+ file:write(event:serialize(), '\n');
+ file:close();
+end
diff --git a/misc/freeswitch/scripts/event/event.lua b/misc/freeswitch/scripts/event/event.lua
index 08d8bfe..652fc48 100644
--- a/misc/freeswitch/scripts/event/event.lua
+++ b/misc/freeswitch/scripts/event/event.lua
@@ -16,29 +16,40 @@ function EventManager.new(self, arg)
self.class = 'eventmanager'
self.database = arg.database;
self.domain = arg.domain;
+ self.consumer = arg.consumer;
return object;
end
function EventManager.register(self)
- self.consumer = freeswitch.EventConsumer('all');
+ if not self.consumer then
+ self.consumer = freeswitch.EventConsumer('all');
+ end
return (self.consumer ~= nil);
end
-function EventManager.load_event_modules(self)
- require 'common.configuration_table'
- self.config = common.configuration_table.get(self.database, 'events');
+function EventManager.load_event_modules(self, modules)
+ local event_modules = {};
+
+ for module_name, index in pairs(modules) do
+ if tonumber(index) and index > 0 then
+ event_modules[index] = module_name;
+ self.log:debug('[event] EVENT_MANAGER - enabled handler module: ', module_name);
+ else
+ self.log:debug('[event] EVENT_MANAGER - disabled handler module: ', module_name);
+ end
+ end
- return self.config.modules;
+ return event_modules;
end
function EventManager.load_event_handlers(self, event_modules)
event_handlers = {}
-
- for event_module_name, index in pairs(event_modules) do
+ for index, event_module_name in ipairs(event_modules) do
+ package.loaded['event.' .. event_module_name] = nil;
event_module = require('event.' .. event_module_name);
if event_module then
self.log:info('[event] EVENT_MANAGER - loading handler module: ', event_module_name);
@@ -71,8 +82,12 @@ end
function EventManager.run(self)
+ require 'common.configuration_table'
+ self.config = common.configuration_table.get(self.database, 'events');
+
+ local event_modules = self:load_event_modules(self.config.modules);
+ self.log:info('[event] EVENT_MANAGER_START - handler modules: ', #event_modules);
- local event_modules = self:load_event_modules();
local event_handlers = self:load_event_handlers(event_modules);
if not event_handlers then
@@ -104,4 +119,6 @@ function EventManager.run(self)
end
end
end
+
+ self.log:info('[event] EVENT_MANAGER_EXIT - action: ', freeswitch.getGlobalVariable('gs_event_manager'));
end
diff --git a/misc/freeswitch/scripts/event/perimeter.lua b/misc/freeswitch/scripts/event/perimeter.lua
deleted file mode 100644
index 5bbb032..0000000
--- a/misc/freeswitch/scripts/event/perimeter.lua
+++ /dev/null
@@ -1,107 +0,0 @@
--- Gemeinschaft 5 module: cdr event handler class
--- (c) AMOOMA GmbH 2012-2013
---
-
-module(...,package.seeall)
-
-
-function handler_class()
- return Perimeter
-end
-
-
-
-Perimeter = {}
-
-MALICIOUS_CONTACT_COUNT = 20;
-MALICIOUS_CONTACT_TIME_SPAN = 2;
-BAN_FUTILE = 2;
-
-function Perimeter.new(self, arg)
- arg = arg or {}
- object = arg.object or {}
- setmetatable(object, self);
- self.__index = self;
- self.log = arg.log;
- self.class = 'cdrsave'
- self.database = arg.database;
- self.domain = arg.domain;
-
- self.ip_address_table = {}
- self:init();
-
- return object;
-end
-
-
-function Perimeter.event_handlers(self)
- return { CUSTOM = { ['sofia::pre_register'] = self.sofia_pre_register } }
-end
-
-
-function Perimeter.init(self)
- require 'common.configuration_table';
- local config = common.configuration_table.get(self.database, 'perimeter');
- if config and config.general then
- self.malicious_contact_count = tonumber(config.general.malicious_contact_count) or MALICIOUS_CONTACT_COUNT;
- self.malicious_contact_time_span = tonumber(config.general.malicious_contact_time_span) or MALICIOUS_CONTACT_TIME_SPAN;
- self.ban_futile = tonumber(config.general.ban_futile) or BAN_FUTILE;
- self.execute = config.general.execute;
- end
-
- self.log:info('[perimeter] PERIMETER - setup perimeter defense - config: ', self.malicious_contact_count, '/', self.malicious_contact_time_span, ', execute: ', self.execute);
-end
-
-
-function Perimeter.sofia_pre_register(self, event)
- local ip_address = event:getHeader('network-ip');
- self:check_ip(ip_address);
-end
-
-
-function Perimeter.check_ip(self, ip_address)
- local event_time = os.time();
-
- if not self.ip_address_table[ip_address] then
- self.ip_address_table[ip_address] = { last_contact = event_time, contact_count = 0, start_stamp = event_time, banned = 0 }
- end
-
- local ip_record = self.ip_address_table[ip_address];
- ip_record.last_contact = event_time;
- ip_record.contact_count = ip_record.contact_count + 1;
-
- if ip_record.contact_count > MALICIOUS_CONTACT_COUNT then
- if (event_time - ip_record.start_stamp) <= MALICIOUS_CONTACT_TIME_SPAN then
- self.log:warning('[', ip_address, '] PERIMETER - too many registration attempts');
- ip_record.start_stamp = event_time;
- ip_record.contact_count = 0;
- if ip_record.banned < BAN_FUTILE then
- ip_record.banned = ip_record.banned + 1;
- self:ban_ip(ip_address);
- else
- self.log:error('[', ip_address, '] PERIMETER - ban futile');
- end
- end
- end
-end
-
-
-function Perimeter.ban_ip(self, ip_address)
- self.ip_address = ip_address;
-
- if self.execute then
- local command = self:expand_variables(self.execute);
- self.log:debug('[', ip_address, '] PERIMETER - execute: ', command);
- local result = os.execute(command);
- if tostring(result) == '0' then
- self.log:warning('[', ip_address, '] PERIMETER - IP banned');
- end
- end
-end
-
-
-function Perimeter.expand_variables(self, line)
- return (line:gsub('{([%a%d_-]+)}', function(captured)
- return self[captured];
- end))
-end
diff --git a/misc/freeswitch/scripts/event/perimeter_defense.lua b/misc/freeswitch/scripts/event/perimeter_defense.lua
new file mode 100644
index 0000000..acdfa8d
--- /dev/null
+++ b/misc/freeswitch/scripts/event/perimeter_defense.lua
@@ -0,0 +1,114 @@
+-- Gemeinschaft 5 module: perimeter defense event handler class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+function handler_class()
+ return PerimeterDefense
+end
+
+PerimeterDefense = {}
+
+function PerimeterDefense.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.log = arg.log;
+ self.class = 'perimeterdefense'
+ self.database = arg.database;
+ self.domain = arg.domain;
+
+ require 'common.perimeter';
+ self.perimeter = common.perimeter.Perimeter:new(arg);
+ self.perimeter:setup();
+
+ return object;
+end
+
+
+function PerimeterDefense.event_handlers(self)
+ return {
+ CUSTOM = {
+ ['sofia::pre_register'] = self.sofia_pre_register,
+ ['sofia::register_attempt'] = self.sofia_register_attempt,
+ ['sofia::register_failure'] = self.sofia_register_failure,
+ },
+ CHANNEL_HANGUP = { [true] = self.channel_hangup },
+ };
+end
+
+
+function PerimeterDefense.to_register_record(self, event, class)
+ return {
+ action = 'register',
+ class = class,
+ key = event:getHeader('network-ip'),
+ sequence = tonumber(event:getHeader('Event-Sequence')),
+ timestamp = tonumber(event:getHeader('Event-Date-Timestamp')),
+ received_ip = event:getHeader('network-ip'),
+ received_port = event:getHeader('network-port'),
+ from_user = event:getHeader('from-user'),
+ from_host = event:getHeader('from-host'),
+ to_user = event:getHeader('to-user'),
+ to_host = event:getHeader('to-host'),
+ user_agent = event:getHeader('user-agent'),
+ username = event:getHeader('username'),
+ realm = event:getHeader('realm'),
+ auth_result = event:getHeader('auth-result'),
+ contact = event:getHeader('contact'),
+ };
+end
+
+
+function PerimeterDefense.to_call_record(self, event, class)
+ return {
+ action = 'call',
+ class = class,
+ key = event:getHeader('Caller-Network-Addr'),
+ sequence = tonumber(event:getHeader('Event-Sequence')),
+ timestamp = tonumber(event:getHeader('Event-Date-Timestamp')),
+ received_ip = event:getHeader('Caller-Network-Addr'),
+ received_port = event:getHeader('variable_sip_network_port'),
+ hangup_cause = event:getHeader('Hangup-Cause'),
+ endpoint_disposition = event:getHeader('variable_endpoint_disposition'),
+ direction = event:getHeader('Call-Direction'),
+ destination_number = event:getHeader('Caller-Destination-Number');
+ caller_id_name = event:getHeader('Caller-Caller-ID-Name');
+ caller_id_number = event:getHeader('Caller-Caller-ID-Number');
+ from_user = event:getHeader('variable_sip_from_user'),
+ from_host = event:getHeader('variable_sip_from_host'),
+ to_user = event:getHeader('variable_sip_to_user'),
+ to_host = event:getHeader('variable_sip_to_host'),
+ req_user = event:getHeader('variable_sip_req_user'),
+ req_host = event:getHeader('variable_sip_req_host'),
+ user_agent = event:getHeader('variable_sip_user_agent'),
+ username = event:getHeader('Caller-Username'),
+ contact = event:getHeader('variable_sip_contact_uri'),
+ };
+end
+
+
+function PerimeterDefense.sofia_pre_register(self, event)
+ local record = self:to_register_record(event, 'pre_register');
+ self.perimeter:check(record);
+end
+
+
+function PerimeterDefense.sofia_register_attempt(self, event)
+ local record = self:to_register_record(event, 'register_attempt');
+ self.perimeter:check(record);
+end
+
+
+function PerimeterDefense.sofia_register_failure(self, event)
+ local record = self:to_register_record(event, 'register_failure');
+ self.perimeter:check(record);
+end
+
+
+function PerimeterDefense.channel_hangup(self, event)
+ local record = self:to_call_record(event, 'channel_hangup');
+ self.perimeter:check(record);
+end