diff --git a/bin/lua/wipf/lang/en.lua b/bin/lua/wipf/lang/en.lua index d4101cf4..a5d0d864 100644 --- a/bin/lua/wipf/lang/en.lua +++ b/bin/lua/wipf/lang/en.lua @@ -2,4 +2,6 @@ err_conf_iprange_inc = "Bad Include IP address: line %d" err_conf_iprange_exc = "Bad Exclude IP address: line %d" -err_conf_app_group_max = "Number of Application Groups must be < %d" +err_conf_group_max = "Number of Application Groups must be < %d" +err_conf_group_name_max = "Length of Application Group's Name must be < %d" +err_conf_size = "Size of configuration is too big" diff --git a/bin/lua/wipf/util/conf.lua b/bin/lua/wipf/util/conf.lua index a90272c7..32f5f993 100644 --- a/bin/lua/wipf/util/conf.lua +++ b/bin/lua/wipf/util/conf.lua @@ -9,7 +9,8 @@ local util_ip = require"wipf.util.ip" local util_conf = { - APP_GROUP_MAX = 10 + APP_GROUP_MAX = 10, + APP_GROUP_NAME_MAX = 128 } @@ -56,7 +57,7 @@ local function app_groups_to_plain(app_groups) local apps_map = {} if groups_count > util_conf.APP_GROUP_MAX then - return nil, i18n.tr_fmt('err_conf_app_group_max', util_conf.APP_GROUP_MAX) + return nil, i18n.tr_fmt('err_conf_group_max', util_conf.APP_GROUP_MAX) end for i = 1, groups_count do @@ -68,8 +69,12 @@ local function app_groups_to_plain(app_groups) group_bits = bit.bor(group_bits, group_bit) end - groups_count = groups_count + 1 - groups[groups_count] = app_group:get_name() + 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 parse_apps(app_group:get_block(), true, apps_map, group_index) parse_apps(app_group:get_allow(), false, apps_map, group_index) @@ -97,6 +102,15 @@ local function app_groups_to_plain(app_groups) return group_bits, groups, app_3bits, apps 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 = {} @@ -185,6 +199,15 @@ function conf_meta:write(buf) 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 + return true end diff --git a/src/drv/wipfdrv.c b/src/drv/wipfdrv.c index a0660ac0..396300d1 100644 --- a/src/drv/wipfdrv.c +++ b/src/drv/wipfdrv.c @@ -426,7 +426,7 @@ wipf_device_control (PDEVICE_OBJECT device, PIRP irp) const PWIPF_CONF conf = irp->AssociatedIrp.SystemBuffer; const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength; - if (len > sizeof(WIPF_CONF)) { + if (len > WIPF_CONF_SIZE_MIN) { PWIPF_CONF_REF conf_ref = wipf_conf_ref_new(conf, len); if (conf_ref == NULL) { diff --git a/src/lua/wipflua.c b/src/lua/wipflua.c index 130778db..d752de95 100644 --- a/src/lua/wipflua.c +++ b/src/lua/wipflua.c @@ -14,9 +14,9 @@ #include #include "../common.h" +#include "../wipfconf.h" #include "../wipflog.c" -#include "../wipfconf.c" /* @@ -68,9 +68,9 @@ static int wipf_lua_log_write (lua_State *L) { char *out = lua_touserdata(L, 1); - const unsigned long remote_ip = lua_tointeger(L, 2); - const unsigned long pid = lua_tointeger(L, 3); - size_t path_len; + const UINT32 remote_ip = lua_tointeger(L, 2); + const UINT32 pid = lua_tointeger(L, 3); + UINT32 path_len; const char *path = lua_tolstring(L, 4, &path_len); if (!out) return 0; @@ -91,8 +91,8 @@ wipf_lua_log_read (lua_State *L) { char *in = lua_touserdata(L, 1); const int off = lua_tointeger(L, 2); - unsigned long remote_ip, pid; - size_t path_len; + UINT32 remote_ip, pid; + UINT32 path_len; const char *path; if (!in) return 0; @@ -114,6 +114,36 @@ wipf_lua_log_read (lua_State *L) return 3; } +/* + * Arguments: ip_include_n (number), ip_exclude_n (number) + * groups_n (number), groups_len (number), + * apps_n (number), apps_len (number) + * Returns: length (number) + */ +static int +wipf_lua_conf_buffer_size (lua_State *L) +{ + const int ip_include_n = lua_tointeger(L, 1); + const int ip_exclude_n = lua_tointeger(L, 2); + const int groups_n = lua_tointeger(L, 3); + const int groups_len = lua_tointeger(L, 4) * 2; + const int apps_n = lua_tointeger(L, 5); + const int apps_len = lua_tointeger(L, 6) * 2; + + if (ip_include_n > WIPF_CONF_IP_MAX + || ip_exclude_n > WIPF_CONF_IP_MAX + || groups_len > WIPF_CONF_GROUPS_LEN_MAX + || apps_len > WIPF_CONF_APPS_LEN_MAX) + return 0; + + lua_pushinteger(L, WIPF_CONF_SIZE_MIN + + (ip_include_n + ip_exclude_n) * 2 * sizeof(UINT32) + + (groups_n + apps_n) * sizeof(UINT16) + + groups_len + apps_len + + apps_n * sizeof(UINT32)); + return 1; +} + static luaL_Reg wipf_lib[] = { {"device_name", wipf_lua_device_name}, @@ -122,6 +152,7 @@ static luaL_Reg wipf_lib[] = { {"buffer_size", wipf_lua_buffer_size}, {"log_write", wipf_lua_log_write}, {"log_read", wipf_lua_log_read}, + {"conf_buffer_size", wipf_lua_conf_buffer_size}, {NULL, NULL} }; diff --git a/src/wipfconf.c b/src/wipfconf.c index 609e4978..6d0d59bd 100644 --- a/src/wipfconf.c +++ b/src/wipfconf.c @@ -1,4 +1,4 @@ -/* Windows IP Filter Configuration Reader */ +/* Windows IP Filter Configuration */ #include "wipfconf.h" @@ -10,4 +10,3 @@ wipf_conf_ipblocked (const PWIPF_CONF conf, UINT32 remote_ip, *notify = TRUE; return FALSE; } - diff --git a/src/wipfconf.h b/src/wipfconf.h index 95901fe1..3308a58a 100644 --- a/src/wipfconf.h +++ b/src/wipfconf.h @@ -2,8 +2,35 @@ #define WIPFCONF_H typedef struct wipf_conf { - UINT32 len; + UINT32 ip_include_all : 1; + UINT32 ip_exclude_all : 1; + UINT32 app_log_blocked : 1; + UINT32 app_block_all : 1; + UINT32 app_allow_all : 1; + UINT32 group_bits : 10; + + UINT16 ip_include_n; + UINT16 ip_exclude_n; + + UINT16 groups_n; + UINT16 groups_len; + + UINT16 apps_n; + UINT16 apps_len; + + UINT32 ip_include_off; + UINT32 ip_exclude_off; + UINT32 groups_off; + UINT32 apps_off; + UCHAR data[4]; } WIPF_CONF, *PWIPF_CONF; +#define WIPF_CONF_SIZE_MIN offsetof(WIPF_CONF, data) +#define WIPF_CONF_IP_MAX (1 * 1024 * 1024) +#define WIPF_CONF_GROUP_MAX 10 +#define WIPF_CONF_GROUP_NAME_MAX 256 +#define WIPF_CONF_GROUPS_LEN_MAX (WIPF_CONF_GROUP_MAX * WIPF_CONF_GROUP_NAME_MAX) +#define WIPF_CONF_APPS_LEN_MAX (64 * 1024) + #endif WIPFCONF_H diff --git a/test/wipf_test.lua b/test/wipf_test.lua index 9698cf75..e2e007f8 100644 --- a/test/wipf_test.lua +++ b/test/wipf_test.lua @@ -80,7 +80,6 @@ end print"-- Conf Read/Write" do - local buf = assert(mem.pointer():alloc()) local conf = util_conf.new_conf() conf:set_ip_include_all(true) @@ -120,6 +119,7 @@ do conf:add_app_group(app_group1) conf:add_app_group(app_group2) + local buf = assert(mem.pointer():alloc()) assert(conf:write(buf)) print("OK")