diff options
Diffstat (limited to 'misc/freeswitch/scripts/event')
-rw-r--r-- | misc/freeswitch/scripts/event/dump_variables.lua | 52 | ||||
-rw-r--r-- | misc/freeswitch/scripts/event/event.lua | 33 | ||||
-rw-r--r-- | misc/freeswitch/scripts/event/perimeter.lua | 107 | ||||
-rw-r--r-- | misc/freeswitch/scripts/event/perimeter_defense.lua | 114 |
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 |