summaryrefslogtreecommitdiff
path: root/misc/freeswitch/scripts/common
diff options
context:
space:
mode:
Diffstat (limited to 'misc/freeswitch/scripts/common')
-rw-r--r--misc/freeswitch/scripts/common/array.lua13
-rw-r--r--misc/freeswitch/scripts/common/call_forwarding.lua35
-rw-r--r--misc/freeswitch/scripts/common/configuration_table.lua59
-rw-r--r--misc/freeswitch/scripts/common/gateway.lua7
-rw-r--r--misc/freeswitch/scripts/common/intruder.lua2
-rw-r--r--misc/freeswitch/scripts/common/log.lua2
-rw-r--r--misc/freeswitch/scripts/common/pager.lua75
-rw-r--r--misc/freeswitch/scripts/common/perimeter.lua38
8 files changed, 204 insertions, 27 deletions
diff --git a/misc/freeswitch/scripts/common/array.lua b/misc/freeswitch/scripts/common/array.lua
index b1b7a71..c3cabec 100644
--- a/misc/freeswitch/scripts/common/array.lua
+++ b/misc/freeswitch/scripts/common/array.lua
@@ -4,6 +4,8 @@
module(...,package.seeall)
+MAX_JSON_DEPTH = 100;
+
function try(array, arguments)
if type(arguments) ~= 'string' or type(array) ~= 'table' then
return nil;
@@ -79,12 +81,19 @@ function keys_to_s(array, separator, prefix, suffix)
end
-- convert to JSON
-function to_json(array)
+function to_json(array, max_depth)
+ max_depth = tonumber(max_depth) or MAX_JSON_DEPTH;
+ max_depth = max_depth - 1;
+
+ if max_depth <= 0 then
+ return 'null';
+ end
+
require 'common.str';
local buffer = '{';
for key, value in pairs(array) do
if type(value) == 'table' then
- buffer = buffer .. '"' .. key .. '":' .. to_json(value) .. ',';
+ buffer = buffer .. '"' .. key .. '":' .. to_json(value, max_depth) .. ',';
else
buffer = buffer .. '"' .. key .. '":' .. common.str.to_json(value) .. ',';
end
diff --git a/misc/freeswitch/scripts/common/call_forwarding.lua b/misc/freeswitch/scripts/common/call_forwarding.lua
index 3429dc9..9556de3 100644
--- a/misc/freeswitch/scripts/common/call_forwarding.lua
+++ b/misc/freeswitch/scripts/common/call_forwarding.lua
@@ -17,6 +17,7 @@ function CallForwarding.new(self, arg, object)
self.record = arg.record;
self.domain = arg.domain;
self.parent = arg.parent;
+ self.caller = arg.caller;
return object;
end
@@ -70,12 +71,38 @@ function CallForwarding.list_by_owner(self, call_forwardable_id, call_forwardabl
else
local sources = common.str.strip_to_a(forwarding_entry.source, ',')
for source_index=1, #sources do
- for caller_id_index=1, #caller_ids do
- if caller_ids[caller_id_index]:match(sources[source_index]) then
- entry_match = true;
- self.log:debug('CALL_FORWARDING - source match: ', sources[source_index], ' ~ ', caller_ids[caller_id_index] );
+ local variable_name, pattern = common.str.partition(sources[source_index], '!=')
+ local invert = variable_name ~= nil;
+ if not variable_name then
+ variable_name, pattern = common.str.partition(sources[source_index], '=')
+ end
+ if variable_name and self.caller then
+ local search_string = tostring(common.array.try(self.caller, variable_name));
+ local success, result = pcall(string.find, pattern, '^%d+-%d+$');
+
+ if success and result and tonumber(search_string) then
+ local min, max = common.str.partition(pattern, '-')
+ entry_match = tonumber(search_string) >= tonumber(min) and tonumber(search_string) <= tonumber(max);
+ else
+ local success, result = pcall(string.find, search_string, pattern);
+ entry_match = common.str.to_b(result);
+ end
+ if invert then
+ entry_match = not entry_match;
+ end
+
+ if entry_match == false then
break;
end
+ self.log:debug('CALL_FORWARDING ', forwarding_entry.service, ' - element match: ', entry_match, ', variable: ', variable_name, ' = ', pattern, ' ~ ', search_string);
+ else
+ for caller_id_index=1, #caller_ids do
+ if caller_ids[caller_id_index]:match(sources[source_index]) then
+ entry_match = true;
+ self.log:debug('CALL_FORWARDING ', forwarding_entry.service, ' - source match: ', sources[source_index], ' ~ ', caller_ids[caller_id_index] );
+ break;
+ end
+ end
end
end
end
diff --git a/misc/freeswitch/scripts/common/configuration_table.lua b/misc/freeswitch/scripts/common/configuration_table.lua
index 85bc014..1b8d8b7 100644
--- a/misc/freeswitch/scripts/common/configuration_table.lua
+++ b/misc/freeswitch/scripts/common/configuration_table.lua
@@ -4,12 +4,43 @@
module(...,package.seeall)
+
+function cast(variable_type, value, default)
+ require 'common.str';
+
+ if variable_type == 'boolean' then
+ return common.str.to_b(value);
+ elseif variable_type == 'integer' then
+ if default and not tonumber(value) then
+ return default;
+ end
+ return common.str.to_i(value);
+ elseif variable_type == 'float' then
+ if default and not tonumber(value) then
+ return default;
+ end
+ return common.str.to_n(value);
+ elseif variable_type == 'string' then
+ if default and not value then
+ return default;
+ end
+ return common.str.to_s(value);
+ elseif variable_type == 'array' then
+ if default and not value then
+ return default;
+ end
+ return common.str.to_a(value, ',');
+ end
+end
+
-- retrieve configuration from database
-function get(database, entity, section)
+function get(database, entity, section, defaults)
if not database or not entity then
return {};
end
+ defaults = defaults or {};
+
require 'common.str'
local sql_query = 'SELECT * FROM `gs_parameters` WHERE `entity` = "' .. entity .. '"';
@@ -17,7 +48,7 @@ function get(database, entity, section)
sql_query = sql_query .. ' AND `section` = "' .. section .. '"';
end
- local root = {}
+ local root = defaults[1] or {}
local parameter_class = '';
database:query(sql_query, function(parameters)
@@ -26,21 +57,27 @@ function get(database, entity, section)
local p_name = common.str.strip(parameters.name);
if not root[p_section] then
- root[p_section] = {};
+ root[p_section] = defaults[p_section] or {};
end
- if p_class_type == 'boolean' then
- root[p_section][p_name] = common.str.to_b(parameters.value);
- elseif p_class_type == 'integer' then
- root[p_section][p_name] = common.str.to_i(parameters.value);
- else
- root[p_section][p_name] = tostring(parameters.value);
- end
+ root[p_section][p_name] = cast(p_class_type, parameters.value);
end)
if section then
- return root[section];
+ return root[section] or defaults[section];
end
return root;
end
+
+
+function settings(database, table_name, key, value, defaults)
+ local sql_query = 'SELECT * FROM ' .. database:escape(table_name, '`') .. ' WHERE ' .. database:escape(key, '`') .. ' = ' .. database:escape(value, '"');
+
+ local settings_entries = defaults or {};
+ database:query(sql_query, function(record)
+ settings_entries[record.name] = cast(record.class_type:lower(), record.value, settings_entries[record.name]);
+ end);
+
+ return settings_entries;
+end
diff --git a/misc/freeswitch/scripts/common/gateway.lua b/misc/freeswitch/scripts/common/gateway.lua
index ac38326..09e8c4b 100644
--- a/misc/freeswitch/scripts/common/gateway.lua
+++ b/misc/freeswitch/scripts/common/gateway.lua
@@ -34,6 +34,10 @@ end
function Gateway.find_by_id(self, id)
+ if not tonumber(id) then
+ return nil;
+ end
+
local sql_query = 'SELECT `a`.*, `c`.`sip_host` AS `domain`, `c`.`contact` AS `contact_full`, `c`.`network_ip`, `c`.`network_port` \
FROM `gateways` `a` \
LEFT JOIN `gateway_settings` `b` ON `a`.`id` = `b`.`gateway_id` AND `b`.`name` = "inbound_username" \
@@ -57,6 +61,9 @@ function Gateway.find_by_id(self, id)
if gateway then
gateway.settings = self:config_table_get('gateway_settings', gateway.id);
+ if common.str.blank(gateway.domain) then
+ gateway.domain = gateway.settings.domain;
+ end
end
return gateway;
diff --git a/misc/freeswitch/scripts/common/intruder.lua b/misc/freeswitch/scripts/common/intruder.lua
index 7d12155..f5e7a41 100644
--- a/misc/freeswitch/scripts/common/intruder.lua
+++ b/misc/freeswitch/scripts/common/intruder.lua
@@ -35,7 +35,7 @@ function Intruder.update_blacklist(self, event)
contacts_per_second_max = event.contacts_per_second_max,
user_agent = event.user_agent,
to_user = event.to_user,
- comment = 'Permimeter',
+ comment = 'Perimeter',
created_at = {'NOW()', raw = true },
updated_at = {'NOW()', raw = true },
};
diff --git a/misc/freeswitch/scripts/common/log.lua b/misc/freeswitch/scripts/common/log.lua
index b9893ac..7201d2a 100644
--- a/misc/freeswitch/scripts/common/log.lua
+++ b/misc/freeswitch/scripts/common/log.lua
@@ -38,7 +38,7 @@ function Log.message(self, log_level, message_arguments )
if type(index) == 'number' then
if type(value) == 'table' then
require 'common.array';
- message = message .. common.array.to_json(value);
+ message = message .. common.array.to_json(value, 3);
else
message = message .. tostring(value);
end
diff --git a/misc/freeswitch/scripts/common/pager.lua b/misc/freeswitch/scripts/common/pager.lua
new file mode 100644
index 0000000..d9440f4
--- /dev/null
+++ b/misc/freeswitch/scripts/common/pager.lua
@@ -0,0 +1,75 @@
+-- Gemeinschaft 5 module: pager class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+Pager = {}
+
+function Pager.new(self, arg)
+ arg = arg or {}
+ pager = arg.pager or {}
+ setmetatable(pager, self);
+ self.__index = self;
+ self.class = 'pager';
+ self.log = arg.log;
+ self.database = arg.database;
+ self.caller = arg.caller;
+
+ return pager;
+end
+
+
+function Pager.find_by_id(self, id)
+ local sql_query = 'SELECT * FROM `pager_groups` WHERE `id`= '.. tonumber(id) .. ' LIMIT 1';
+ local pager = nil;
+
+ self.database:query(sql_query, function(entry)
+ pager = Pager:new(self);
+ pager.record = entry;
+ pager.id = tonumber(entry.id);
+ pager.uuid = entry.uuid;
+ pager.identifier = 'pager' .. entry.id;
+ end)
+
+ return pager;
+end
+
+
+function Pager.enter(self)
+ local flags = 'mute';
+
+ if not self.caller.account or self.caller.account.class ~= 'sipaccount' then
+ return false;
+ end
+
+ if tonumber(self.record.sip_account_id) == tonumber(self.caller.account.id) then
+ flags = 'moderator|endconf';
+ end
+
+ self:callback();
+
+ local result = self.caller:execute('conference', self.identifier .. "@profile_" .. self.identifier .. "++flags{" .. flags .. "}");
+ self.caller:hangup('NORMAL_CLEARING');
+ self:callback();
+end
+
+
+function Pager.callback(self)
+ local destination = {
+ pager_group_id = self.id,
+ state = 'terminated',
+ }
+
+ if self.caller.account and self.caller.account.class == 'sipaccount' then
+ destination.sip_account_id = self.caller.account.id;
+ end
+
+ if self.caller and self.caller:ready() then
+ destination.state = 'active';
+ end
+
+ local command = 'http_request.lua ' .. self.caller.uuid .. ' ' .. common.array.expand_variables(self.record.callback_url, destination, self.caller);
+ require 'common.fapi';
+ return common.fapi.FApi:new():execute('luarun', command);
+end
diff --git a/misc/freeswitch/scripts/common/perimeter.lua b/misc/freeswitch/scripts/common/perimeter.lua
index d3b601c..fcef97c 100644
--- a/misc/freeswitch/scripts/common/perimeter.lua
+++ b/misc/freeswitch/scripts/common/perimeter.lua
@@ -47,6 +47,7 @@ function Perimeter.setup(self, event)
self.ban_tries = 1;
self.checks = { register = {}, call = {} };
self.bad_headers = { register = {}, call = {} };
+ self.serial = freeswitch.getGlobalVariable('switch_serial');
if config and config.general then
for key, value in pairs(config.general) do
@@ -56,8 +57,14 @@ function Perimeter.setup(self, event)
self.checks.register = config.checks_register or {};
self.checks.call = config.checks_call or {};
- self.bad_headers.register = config.bad_headers_register;
- self.bad_headers.call = config.bad_headers_call;
+
+ for header, patterns in pairs(config.bad_headers_register) do
+ self.bad_headers.register[header] = common.str.strip_to_a(patterns, ',');
+ end
+
+ for header, patterns in pairs(config.bad_headers_call) do
+ self.bad_headers.call[header] = common.str.strip_to_a(patterns, ',');
+ end
self.log:info('[perimeter] PERIMETER - setup perimeter defense');
end
@@ -93,6 +100,7 @@ function Perimeter.record_update(self, event)
event.record.span_start = event.span_start or event.record.span_start;
event.record.span_contact_count = (event.span_contact_count or event.record.span_contact_count) + 1;
event.record.users = event.users or event.record.users;
+ event.record.updated = event.updated or event.record.updated;
end
@@ -144,6 +152,7 @@ function Perimeter.check(self, event)
end
self:execute_ban(event);
event.ban_time = os.time();
+ event.banned = true;
end
event.record.banned = event.record.banned + 1;
@@ -205,12 +214,14 @@ end
function Perimeter.check_bad_headers(self, event)
local points = nil;
- for name, pattern in pairs(self.bad_headers[event.action]) do
- pattern = common.array.expand_variables(pattern, event);
- local success, result = pcall(string.find, event[name], pattern);
- if success and result then
- self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_BAD_HEADERS - ', name, '=', event[name], ' ~= ', pattern);
- points = (points or 0) + 1;
+ for name, patterns in pairs(self.bad_headers[event.action]) do
+ for index, pattern in ipairs(patterns) do
+ pattern = common.array.expand_variables(pattern, event);
+ local success, result = pcall(string.find, event[name], pattern);
+ if success and result then
+ self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_BAD_HEADERS - ', name, '=', event[name], ' ~= ', pattern);
+ points = (points or 0) + 1;
+ end
end
end
@@ -247,6 +258,17 @@ end
function Perimeter.update_intruder(self, event)
require 'common.intruder';
local result = common.intruder.Intruder:new{ log = self.log, database = self.database }:update_blacklist(event);
+
+ if not common.str.blank(self.report_url) and (not event.record.updated or event.banned) then
+ event.serial = common.fapi.FApi:new():execute('md5', self.serial);
+ event.blacklisted = tostring(common.str.to_b(event.banned));
+ local command = 'http_request.lua perimeter ' .. common.array.expand_variables(self.report_url, event);
+ require 'common.fapi'
+ common.fapi.FApi:new():execute('luarun', command);
+ self.log:devel(command);
+ end
+
+ event.updated = common.str.to_i(event.updated) + 1;
end