From 240c6fa376d0e58f752e19f515f31ba8e1889353 Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Mon, 2 Feb 2015 13:37:27 +0500 Subject: [PATCH] Improve Provider (un)registration. --- bin/scripts/provider.lua | 27 +++++++ src/common.h | 2 + src/drv/wipfdrv.c | 101 +------------------------- src/lua/wipflua.c | 33 +++++++++ src/wipfprov.c | 148 +++++++++++++++++++++++++++++++++++++++ test/log_read.lua | 32 ++++++++- 6 files changed, 242 insertions(+), 101 deletions(-) create mode 100644 bin/scripts/provider.lua create mode 100644 src/wipfprov.c diff --git a/bin/scripts/provider.lua b/bin/scripts/provider.lua new file mode 100644 index 00000000..a6322699 --- /dev/null +++ b/bin/scripts/provider.lua @@ -0,0 +1,27 @@ +-- WIPF Provider (Un)Registration script + +local wipf = require"wipflua" +local sys = require"sys" + + +local persist, boot + +-- Process arguments +for _, v in ipairs(arg) do + if v == "persist" then + persist = true + elseif v == "boot" then + boot = true + end +end + +wipf.prov_unregister() + +if persist then + local _, err = wipf.prov_register(persist, boot) + if err then + sys.stderr:write("Error: ", sys.strerror(err)) + sys.exit(false) + end +end + diff --git a/src/common.h b/src/common.h index 667199c4..d236a492 100644 --- a/src/common.h +++ b/src/common.h @@ -28,6 +28,8 @@ DEFINE_GUID(WIPF_GUID_FILTER_CONNECT_V4, DEFINE_GUID(WIPF_GUID_FILTER_ACCEPT_V4, 0x544a3e25, 0x7beb, 0x4970, 0x88, 0xef, 0xb4, 0xbc, 0xa2, 0xce, 0x24, 0x82); +#define WIPF_VERSION 0x000100 + #define WIPF_DEVICE_NAME "\\\\.\\wipf" #define WIPF_DEVICE_TYPE 0xD000 diff --git a/src/drv/wipfdrv.c b/src/drv/wipfdrv.c index 396300d1..d33e7ae8 100644 --- a/src/drv/wipfdrv.c +++ b/src/drv/wipfdrv.c @@ -15,6 +15,7 @@ #define WIPF_DEVICE_POOL_TAG 'IPFD' #include "../wipfconf.c" +#include "../wipfprov.c" #include "wipfbuf.c" typedef struct wipf_conf_ref { @@ -267,101 +268,6 @@ wipf_callout_remove (void) g_device->active = FALSE; } -static NTSTATUS -wipf_provider_install (void) -{ - FWPM_PROVIDER0 provider; - FWPM_CALLOUT0 ocallout4, icallout4; - FWPM_SUBLAYER0 sublayer; - FWPM_FILTER0 ofilter4, ifilter4; - HANDLE engine; - NTSTATUS status; - - RtlZeroMemory(&provider, sizeof(FWPM_PROVIDER0)); - provider.providerKey = WIPF_GUID_PROVIDER; - provider.displayData.name = L"WipfProvider"; - provider.displayData.description = L"Windows IP Filter Provider"; - - RtlZeroMemory(&ocallout4, sizeof(FWPM_CALLOUT0)); - ocallout4.calloutKey = WIPF_GUID_CALLOUT_CONNECT_V4; - ocallout4.displayData.name = L"WipfCalloutConnect4"; - ocallout4.displayData.description = L"Windows IP Filter Callout Connect V4"; - ocallout4.providerKey = (GUID *) &WIPF_GUID_PROVIDER; - ocallout4.applicableLayer = FWPM_LAYER_ALE_AUTH_CONNECT_V4; - - RtlZeroMemory(&icallout4, sizeof(FWPM_CALLOUT0)); - icallout4.calloutKey = WIPF_GUID_CALLOUT_ACCEPT_V4; - icallout4.displayData.name = L"WipfCalloutAccept4"; - icallout4.displayData.description = L"Windows IP Filter Callout Accept V4"; - icallout4.providerKey = (GUID *) &WIPF_GUID_PROVIDER; - icallout4.applicableLayer = FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4; - - RtlZeroMemory(&sublayer, sizeof(FWPM_SUBLAYER0)); - sublayer.subLayerKey = WIPF_GUID_SUBLAYER; - sublayer.displayData.name = L"WipfSublayer"; - sublayer.displayData.description = L"Windows IP Filter Sublayer"; - sublayer.providerKey = (GUID *) &WIPF_GUID_PROVIDER; - - RtlZeroMemory(&ofilter4, sizeof(FWPM_FILTER0)); - ofilter4.flags = FWPM_FILTER_FLAG_PERMIT_IF_CALLOUT_UNREGISTERED; - ofilter4.filterKey = WIPF_GUID_FILTER_CONNECT_V4; - ofilter4.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4; - ofilter4.subLayerKey = WIPF_GUID_SUBLAYER; - ofilter4.displayData.name = L"WipfFilterConnect4"; - ofilter4.displayData.description = L"Windows IP Filter Connect V4"; - ofilter4.action.type = FWP_ACTION_CALLOUT_UNKNOWN; - ofilter4.action.calloutKey = WIPF_GUID_CALLOUT_CONNECT_V4; - - RtlZeroMemory(&ifilter4, sizeof(FWPM_FILTER0)); - ifilter4.flags = FWPM_FILTER_FLAG_PERMIT_IF_CALLOUT_UNREGISTERED; - ifilter4.filterKey = WIPF_GUID_FILTER_ACCEPT_V4; - ifilter4.layerKey = FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4; - ifilter4.subLayerKey = WIPF_GUID_SUBLAYER; - ifilter4.displayData.name = L"WipfFilterAccept4"; - ifilter4.displayData.description = L"Windows IP Filter Accept V4"; - ifilter4.action.type = FWP_ACTION_CALLOUT_UNKNOWN; - ifilter4.action.calloutKey = WIPF_GUID_CALLOUT_ACCEPT_V4; - - if (NT_SUCCESS(status = FwpmEngineOpen0( - NULL, RPC_C_AUTHN_WINNT, NULL, NULL, &engine))) { - - if (!NT_SUCCESS(status = FwpmTransactionBegin0(engine, 0)) - || !NT_SUCCESS(status = FwpmProviderAdd0(engine, &provider, NULL)) - || !NT_SUCCESS(status = FwpmCalloutAdd0(engine, &ocallout4, NULL, NULL)) - || !NT_SUCCESS(status = FwpmCalloutAdd0(engine, &icallout4, NULL, NULL)) - || !NT_SUCCESS(status = FwpmSubLayerAdd0(engine, &sublayer, NULL)) - || !NT_SUCCESS(status = FwpmFilterAdd0(engine, &ofilter4, NULL, NULL)) - || !NT_SUCCESS(status = FwpmFilterAdd0(engine, &ifilter4, NULL, NULL)) - || !NT_SUCCESS(status = FwpmTransactionCommit0(engine)) - ) - FwpmTransactionAbort0(engine); - - FwpmEngineClose0(engine); - } - - if (!NT_SUCCESS(status)) { - DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "WIPF: Provider Install: Error: %d\n", status); - } - - return status; -} - -static void -wipf_provider_remove (void) -{ - HANDLE engine; - - if (NT_SUCCESS(FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, NULL, &engine))) { - FwpmFilterDeleteByKey0(engine, (GUID *) &WIPF_GUID_FILTER_CONNECT_V4); - FwpmFilterDeleteByKey0(engine, (GUID *) &WIPF_GUID_FILTER_ACCEPT_V4); - FwpmSubLayerDeleteByKey0(engine, (GUID *) &WIPF_GUID_SUBLAYER); - FwpmCalloutDeleteByKey0(engine, (GUID *) &WIPF_GUID_CALLOUT_CONNECT_V4); - FwpmCalloutDeleteByKey0(engine, (GUID *) &WIPF_GUID_CALLOUT_ACCEPT_V4); - FwpmProviderDeleteByKey0(engine, (GUID *) &WIPF_GUID_PROVIDER); - FwpmEngineClose0(engine); - } -} - static NTSTATUS wipf_device_create (PDEVICE_OBJECT device, PIRP irp) { @@ -476,7 +382,7 @@ wipf_driver_unload (PDRIVER_OBJECT driver) wipf_buffer_close(&g_device->buffer); - wipf_provider_remove(); + wipf_prov_unregister(); RtlInitUnicodeString(&device_link, DOS_DEVICE_NAME); IoDeleteSymbolicLink(&device_link); @@ -520,8 +426,7 @@ DriverEntry (PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) KeInitializeSpinLock(&g_device->conf_lock); - wipf_provider_remove(); - status = wipf_provider_install(); + status = wipf_prov_register(FALSE, FALSE); } } diff --git a/src/lua/wipflua.c b/src/lua/wipflua.c index 697e933b..4e1dac10 100644 --- a/src/lua/wipflua.c +++ b/src/lua/wipflua.c @@ -17,6 +17,7 @@ #include "../wipfconf.h" #include "../wipflog.c" +#include "../wipfprov.c" /* @@ -395,6 +396,36 @@ wipf_lua_conf_read (lua_State *L) return 13; } +/* + * Arguments: persist (boolean), boot (boolean) + * Returns: boolean | nil, err_code + */ +static int +wipf_lua_prov_register (lua_State *L) +{ + const BOOL persist = lua_toboolean(L, 1); + const BOOL boot = lua_toboolean(L, 2); + const DWORD status = wipf_prov_register(persist, boot); + + if (!status) { + lua_pushboolean(L, 1); + return 1; + } + + lua_pushnil(L); + lua_pushinteger(L, status); + return 2; +} + +static int +wipf_lua_prov_unregister (lua_State *L) +{ + (void) L; + + wipf_prov_unregister(); + return 0; +} + static luaL_Reg wipf_lib[] = { {"device_name", wipf_lua_device_name}, @@ -406,6 +437,8 @@ static luaL_Reg wipf_lib[] = { {"conf_buffer_size", wipf_lua_conf_buffer_size}, {"conf_write", wipf_lua_conf_write}, {"conf_read", wipf_lua_conf_read}, + {"prov_register", wipf_lua_prov_register}, + {"prov_unregister", wipf_lua_prov_unregister}, {NULL, NULL} }; diff --git a/src/wipfprov.c b/src/wipfprov.c new file mode 100644 index 00000000..fb7f8564 --- /dev/null +++ b/src/wipfprov.c @@ -0,0 +1,148 @@ +/* Windows IP Filter Provider (Un)Registration */ + +typedef struct wipf_prov_data { + UINT32 version : 24; + UINT32 persist : 1; + UINT32 boot : 1; +} WIPF_PROV_DATA, *PWIPF_PROV_DATA; + +static BOOL g_providerPersist = FALSE; + + +static void +wipf_prov_delete (HANDLE engine) +{ + FwpmFilterDeleteByKey0(engine, (GUID *) &WIPF_GUID_FILTER_CONNECT_V4); + FwpmFilterDeleteByKey0(engine, (GUID *) &WIPF_GUID_FILTER_ACCEPT_V4); + FwpmSubLayerDeleteByKey0(engine, (GUID *) &WIPF_GUID_SUBLAYER); + FwpmCalloutDeleteByKey0(engine, (GUID *) &WIPF_GUID_CALLOUT_CONNECT_V4); + FwpmCalloutDeleteByKey0(engine, (GUID *) &WIPF_GUID_CALLOUT_ACCEPT_V4); + FwpmProviderDeleteByKey0(engine, (GUID *) &WIPF_GUID_PROVIDER); +} + +static void +wipf_prov_unregister (void) +{ + HANDLE engine; + + if (g_providerPersist + || FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, NULL, &engine)) + return; + + wipf_prov_delete(engine); + + FwpmEngineClose0(engine); +} + +static DWORD +wipf_prov_register (BOOL persist, BOOL boot) +{ + FWPM_PROVIDER0 *old_provider, provider; + FWPM_CALLOUT0 ocallout4, icallout4; + FWPM_SUBLAYER0 sublayer; + FWPM_FILTER0 ofilter4, ifilter4; + HANDLE engine; + WIPF_PROV_DATA provider_data; + UINT32 filter_flags; + DWORD status; + + if ((status = FwpmEngineOpen0( + NULL, RPC_C_AUTHN_WINNT, NULL, NULL, &engine))) + goto end; + + if (!(status = FwpmProviderGetByKey0( + engine, (GUID *) &WIPF_GUID_PROVIDER, &old_provider))) { + PWIPF_PROV_DATA old_provider_data = + (PWIPF_PROV_DATA) old_provider->providerData.data; + + if (old_provider_data) { + provider_data = *old_provider_data; + } + FwpmFreeMemory0(&old_provider); + + if (old_provider_data) { + if (provider_data.persist) { + g_providerPersist = TRUE; + + if (provider_data.version == WIPF_VERSION) + goto end_close; + + persist = provider_data.persist; + boot = provider_data.boot; + } + wipf_prov_delete(engine); + } + } + + provider_data.version = WIPF_VERSION; + provider_data.persist = persist; + provider_data.boot = boot; + + filter_flags = boot ? 0 : FWPM_FILTER_FLAG_PERMIT_IF_CALLOUT_UNREGISTERED; + + RtlZeroMemory(&provider, sizeof(FWPM_PROVIDER0)); + provider.flags = persist ? FWPM_PROVIDER_FLAG_PERSISTENT : 0; + provider.providerKey = WIPF_GUID_PROVIDER; + provider.displayData.name = L"WipfProvider"; + provider.displayData.description = L"Windows IP Filter Provider"; + provider.serviceName = L"wipf"; + provider.providerData.size = sizeof(WIPF_PROV_DATA); + provider.providerData.data = (UINT8 *) &provider_data; + + RtlZeroMemory(&ocallout4, sizeof(FWPM_CALLOUT0)); + ocallout4.calloutKey = WIPF_GUID_CALLOUT_CONNECT_V4; + ocallout4.displayData.name = L"WipfCalloutConnect4"; + ocallout4.displayData.description = L"Windows IP Filter Callout Connect V4"; + ocallout4.providerKey = (GUID *) &WIPF_GUID_PROVIDER; + ocallout4.applicableLayer = FWPM_LAYER_ALE_AUTH_CONNECT_V4; + + RtlZeroMemory(&icallout4, sizeof(FWPM_CALLOUT0)); + icallout4.calloutKey = WIPF_GUID_CALLOUT_ACCEPT_V4; + icallout4.displayData.name = L"WipfCalloutAccept4"; + icallout4.displayData.description = L"Windows IP Filter Callout Accept V4"; + icallout4.providerKey = (GUID *) &WIPF_GUID_PROVIDER; + icallout4.applicableLayer = FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4; + + RtlZeroMemory(&sublayer, sizeof(FWPM_SUBLAYER0)); + sublayer.subLayerKey = WIPF_GUID_SUBLAYER; + sublayer.displayData.name = L"WipfSublayer"; + sublayer.displayData.description = L"Windows IP Filter Sublayer"; + sublayer.providerKey = (GUID *) &WIPF_GUID_PROVIDER; + + RtlZeroMemory(&ofilter4, sizeof(FWPM_FILTER0)); + ofilter4.flags = filter_flags; + ofilter4.filterKey = WIPF_GUID_FILTER_CONNECT_V4; + ofilter4.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4; + ofilter4.subLayerKey = WIPF_GUID_SUBLAYER; + ofilter4.displayData.name = L"WipfFilterConnect4"; + ofilter4.displayData.description = L"Windows IP Filter Connect V4"; + ofilter4.action.type = FWP_ACTION_CALLOUT_UNKNOWN; + ofilter4.action.calloutKey = WIPF_GUID_CALLOUT_CONNECT_V4; + + RtlZeroMemory(&ifilter4, sizeof(FWPM_FILTER0)); + ifilter4.flags = filter_flags; + ifilter4.filterKey = WIPF_GUID_FILTER_ACCEPT_V4; + ifilter4.layerKey = FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4; + ifilter4.subLayerKey = WIPF_GUID_SUBLAYER; + ifilter4.displayData.name = L"WipfFilterAccept4"; + ifilter4.displayData.description = L"Windows IP Filter Accept V4"; + ifilter4.action.type = FWP_ACTION_CALLOUT_UNKNOWN; + ifilter4.action.calloutKey = WIPF_GUID_CALLOUT_ACCEPT_V4; + + if ((status = FwpmTransactionBegin0(engine, 0)) + || (status = FwpmProviderAdd0(engine, &provider, NULL)) + || (status = FwpmCalloutAdd0(engine, &ocallout4, NULL, NULL)) + || (status = FwpmCalloutAdd0(engine, &icallout4, NULL, NULL)) + || (status = FwpmSubLayerAdd0(engine, &sublayer, NULL)) + || (status = FwpmFilterAdd0(engine, &ofilter4, NULL, NULL)) + || (status = FwpmFilterAdd0(engine, &ifilter4, NULL, NULL)) + || (status = FwpmTransactionCommit0(engine))) + FwpmTransactionAbort0(engine); + + end_close: + FwpmEngineClose0(engine); + + end: + return status; +} + diff --git a/test/log_read.lua b/test/log_read.lua index e52eac79..f51eb6c3 100644 --- a/test/log_read.lua +++ b/test/log_read.lua @@ -4,8 +4,35 @@ local sys = require"sys" local sock = require"sys.sock" local wipf = require"wipflua" +local util_conf = require"wipf.util.conf" local util_fs = require"wipf.util.fs" +local mem, win32 = sys.mem, sys.win32 + + +function set_conf(device) + local conf = util_conf.new_conf() + + conf:set_ip_include_all(true) + conf:set_ip_exclude_all(false) + + conf:set_app_log_blocked(true) + conf:set_app_block_all(true) + conf:set_app_allow_all(false) + + conf:set_ip_exclude[[ + 10.0.0.0/24 + 127.0.0.0/24 + 169.254.0.0/16 + 172.16.0.0/20 + 192.168.0.0/16 + ]] + + local buf = assert(mem.pointer():alloc()) + assert(conf:write(buf)) + + return device:ioctl(wipf.ioctl_setconf(), buf) +end function print_logs(buf) local size = buf:seek() @@ -33,12 +60,11 @@ end local device = assert(sys.handle():open(wipf.device_name(), "rw")) +assert(set_conf(device)) + local BUFSIZ = wipf.buffer_size() local buf = assert(sys.mem.pointer(BUFSIZ)) -assert(buf:write("test config")) -assert(device:ioctl(wipf.ioctl_setconf(), buf)) - while true do assert(device:ioctl(wipf.ioctl_getlog(), nil, buf)) print_logs(buf)