fort/bin/lua/wipf/util/conf.lua
2015-02-03 11:41:02 +05:00

367 lines
8.4 KiB
Lua

-- WIPF Configuration Utilities
local bit = require"bit"
local wipf = require"wipflua"
local i18n = require"wipf.util.i18n"
local util_fs = require"wipf.util.fs"
local util_ip = require"wipf.util.ip"
local util_conf = {
APP_GROUP_MAX = 16,
APP_GROUP_NAME_MAX = 128,
APP_PATH_MAX = 1024
}
local function parse_app(line)
local path = string.gsub(line, "(\"?%s*)$", "")
if path == "" then
return
end
path = path:lower()
if path == "system" then
path = "System"
else
path = util_fs.path_to_dospath(path)
end
return path
end
local function parse_apps(text, blocked, apps_map, group_offset)
for line in string.gmatch(text, "%s*\"?([^\n]+)") do
local app = parse_app(line)
if app then
local app_perms = apps_map[app] or 0
local val_perm = blocked and 2 or 1
local app_perm = bit.lshift(val_perm, group_offset * 2)
apps_map[app] = bit.bor(app_perms, app_perm)
end
end
end
-- Convert app. group objects to plain tables
local function app_groups_to_plain(app_groups)
local group_bits = 0
local groups, groups_count = {}, app_groups.n
local apps_map = {}
if groups_count > util_conf.APP_GROUP_MAX then
return nil, i18n.tr_fmt('err_conf_group_max', util_conf.APP_GROUP_MAX)
end
for i = 1, groups_count do
local app_group = app_groups[i]
local group_offset = i - 1
local name = app_group:get_name()
if #name > util_conf.APP_GROUP_NAME_MAX then
return nil, i18n.tr_fmt('err_conf_group_name_max', util_conf.APP_GROUP_NAME_MAX)
end
groups[i] = name
if app_group:get_enabled() then
local group_bit = bit.lshift(1, group_offset)
group_bits = bit.bor(group_bits, group_bit)
end
parse_apps(app_group:get_block(), true, apps_map, group_offset)
parse_apps(app_group:get_allow(), false, apps_map, group_offset)
end
-- fill "apps" array
local apps, apps_count = {}, 0
for app in pairs(apps_map) do
if #app > util_conf.APP_PATH_MAX then
return nil, i18n.tr_fmt('err_conf_app_path_max', util_conf.APP_PATH_MAX)
end
apps_count = apps_count + 1
apps[apps_count] = app
end
table.sort(apps)
-- fill "apps_perms" array
local apps_perms = {}
for i = 1, apps_count do
local app = apps[i]
apps_perms[i] = apps_map[app]
end
groups.n = groups_count
apps_perms.n, apps.n = apps_count, apps_count
return group_bits, groups, apps_perms, apps
end
-- Create app. group objects from plain tables
local function app_groups_from_plain(group_bits, groups, apps_perms, apps)
local app_groups = {}
local groups_count, apps_count = groups.n, apps.n
for i = 1, groups_count do
local app_group = util_conf.new_app_group()
local group_offset = i - 1
app_group:set_name(groups[i])
do
local group_bit = bit.lshift(1, group_offset)
local val = bit.band(group_bits, group_bit)
app_group:set_enabled(val ~= 0)
end
-- fill 'block' & 'allow' apps
local block, allow = "", ""
for app_index = 1, apps_count do
local app_perms = apps_perms[app_index]
local val_perm = bit.rshift(app_perms, group_offset * 2)
local allowed = bit.band(val_perm, 1) ~= 0
local blocked = bit.band(val_perm, 2) ~= 0
if allowed or blocked then
local app = apps[app_index]
app = util_fs.dospath_to_path(app)
if blocked then
block = block .. app .. "\n"
end
if allowed then
allow = allow .. app .. "\n"
end
end
end
app_group:set_block(block)
app_group:set_allow(allow)
app_groups[i] = app_group
end
app_groups.n = groups_count
return app_groups
end
-- Calculate total length of strings in table
local function get_strings_len(t, n)
local len = 0
for i = 1, n do
len = len + #t[i]
end
return len
end
-- Configuration objects meta-table
local conf_meta = {}
conf_meta.__index = conf_meta
function conf_meta:set_ip_include_all(bool)
self.ip_include_all = bool
end
function conf_meta:get_ip_include_all()
return self.ip_include_all
end
function conf_meta:set_ip_exclude_all(bool)
self.ip_exclude_all = bool
end
function conf_meta:get_ip_exclude_all()
return self.ip_exclude_all
end
function conf_meta:set_app_log_blocked(bool)
self.app_log_blocked = bool
end
function conf_meta:get_app_log_blocked()
return self.app_log_blocked
end
function conf_meta:set_app_block_all(bool)
self.app_block_all = bool
end
function conf_meta:get_app_block_all()
return self.app_block_all
end
function conf_meta:set_app_allow_all(bool)
self.app_allow_all = bool
end
function conf_meta:get_app_allow_all()
return self.app_allow_all
end
function conf_meta:set_ip_include(str)
self.ip_include = str
end
function conf_meta:get_ip_include()
return self.ip_include
end
function conf_meta:set_ip_exclude(str)
self.ip_exclude = str
end
function conf_meta:get_ip_exclude()
return self.ip_exclude
end
function conf_meta:get_app_groups()
return self.app_groups
end
function conf_meta:add_app_group(app_group)
local app_groups = self.app_groups
table.insert(app_groups, app_group)
app_groups.n = app_groups.n + 1
end
function conf_meta:remove_app_group(index)
local app_groups = self.app_groups
table.remove(app_groups, index)
app_groups.n = app_groups.n - 1
end
-- Write conf. object to buffer
function conf_meta:write(buf)
local iprange_from_inc, iprange_to_inc =
util_ip.ip4range_to_numbers(self.ip_include)
if not iprange_from_inc then
return nil, i18n.tr_fmt('err_conf_iprange_inc', iprange_to_inc)
end
local iprange_from_exc, iprange_to_exc =
util_ip.ip4range_to_numbers(self.ip_exclude)
if not iprange_from_exc then
return nil, i18n.tr_fmt('err_conf_iprange_exc', iprange_to_exc)
end
local group_bits, groups, apps_perms, apps =
app_groups_to_plain(self.app_groups)
if not group_bits then
return nil, groups
end
-- calculate maximum required buffer size
local buf_size = wipf.conf_buffer_size(
iprange_from_inc.n, iprange_from_exc.n,
groups.n, get_strings_len(groups, groups.n),
apps.n, get_strings_len(apps, apps.n))
if not (buf_size and buf:reserve(buf_size)) then
return nil, i18n.tr('err_conf_size')
end
local conf_size = wipf.conf_write(buf:getptr(),
self.ip_include_all, self.ip_exclude_all,
self.app_log_blocked,
self.app_block_all, self.app_allow_all,
iprange_from_inc.n, iprange_from_inc, iprange_to_inc,
iprange_from_exc.n, iprange_from_exc, iprange_to_exc,
apps.n, apps_perms, apps,
group_bits, groups.n, groups)
buf:seek(conf_size)
return conf_size
end
-- Read conf. object from buffer
function conf_meta:read(buf)
local ip_include_all, ip_exclude_all,
app_log_blocked, app_block_all, app_allow_all,
iprange_from_inc, iprange_to_inc,
iprange_from_exc, iprange_to_exc,
apps_perms, apps, group_bits, groups = wipf.conf_read(buf:getptr())
self.ip_include_all = ip_include_all
self.ip_exclude_all = ip_exclude_all
self.app_log_blocked = app_log_blocked
self.app_block_all = app_block_all
self.app_allow_all = app_allow_all
self.ip_include = util_ip.ip4range_from_numbers(
iprange_from_inc, iprange_to_inc)
self.ip_exclude = util_ip.ip4range_from_numbers(
iprange_from_exc, iprange_to_exc)
self.app_groups = app_groups_from_plain(
group_bits, groups, apps_perms, apps)
end
-- New conf. object
function util_conf.new_conf()
return setmetatable({
ip_include_all = false,
ip_exclude_all = false,
app_log_blocked = true,
app_block_all = true,
app_allow_all = false,
ip_include = "",
ip_exclude = "",
app_groups = {n = 0}
}, conf_meta)
end
-- Application group's meta-table
local app_group_meta = {}
app_group_meta.__index = app_group_meta
function app_group_meta:set_name(str)
self.name = str
end
function app_group_meta:get_name()
return self.name
end
function app_group_meta:set_enabled(bool)
self.enabled = bool
end
function app_group_meta:get_enabled()
return self.enabled
end
function app_group_meta:set_block(str)
self.block = str
end
function app_group_meta:get_block()
return self.block
end
function app_group_meta:set_allow(str)
self.allow = str
end
function app_group_meta:get_allow()
return self.allow
end
-- New app. group object
function util_conf.new_app_group()
return setmetatable({
name = "",
enabled = true,
block = "",
allow = ""
}, app_group_meta)
end
return util_conf