mirror of
https://github.com/tnodir/fort
synced 2024-11-15 01:47:47 +00:00
Driver: Fix log writing.
This commit is contained in:
parent
32ce57febe
commit
bf193d5b82
@ -5,11 +5,11 @@
|
||||
#include "../wipflog.c"
|
||||
|
||||
typedef struct wipf_buffer {
|
||||
UINT32 top, size;
|
||||
PVOID data;
|
||||
UINT32 top;
|
||||
PCHAR data;
|
||||
|
||||
PIRP irp; /* pending */
|
||||
PVOID out;
|
||||
PCHAR out;
|
||||
ULONG out_len;
|
||||
|
||||
KSPIN_LOCK lock;
|
||||
@ -19,6 +19,9 @@ typedef struct wipf_buffer {
|
||||
static void
|
||||
wipf_buffer_init (PWIPF_BUFFER buf)
|
||||
{
|
||||
buf->data = ExAllocatePoolWithTag(NonPagedPool, WIPF_BUFFER_SIZE,
|
||||
WIPF_BUFFER_POOL_TAG);
|
||||
|
||||
KeInitializeSpinLock(&buf->lock);
|
||||
}
|
||||
|
||||
@ -29,26 +32,25 @@ wipf_buffer_close (PWIPF_BUFFER buf)
|
||||
ExFreePoolWithTag(buf->data, WIPF_BUFFER_POOL_TAG);
|
||||
|
||||
buf->data = NULL;
|
||||
buf->size = 0;
|
||||
buf->top = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
wipf_buffer_write (PWIPF_BUFFER buf, UINT32 remote_ip, UINT64 pid,
|
||||
wipf_buffer_write (PWIPF_BUFFER buf, UINT32 remote_ip, UINT32 pid,
|
||||
UINT32 path_len, const PVOID path,
|
||||
PIRP *irp, NTSTATUS *irp_status, ULONG_PTR *info)
|
||||
{
|
||||
UINT32 len = WIPF_LOG_SIZE(path_len);
|
||||
UINT32 size;
|
||||
UINT32 len;
|
||||
KIRQL irq;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
if (len > WIPF_BUFFER_SIZE) {
|
||||
if (path_len > WIPF_LOG_PATH_MAX) {
|
||||
path_len = 0; /* drop too long path */
|
||||
len = WIPF_LOG_SIZE(0);
|
||||
}
|
||||
|
||||
len = WIPF_LOG_SIZE(path_len);
|
||||
|
||||
KeAcquireSpinLock(&buf->lock, &irq);
|
||||
|
||||
/* Try to directly write to pending client */
|
||||
@ -69,41 +71,14 @@ wipf_buffer_write (PWIPF_BUFFER buf, UINT32 remote_ip, UINT64 pid,
|
||||
}
|
||||
}
|
||||
|
||||
size = buf->size;
|
||||
|
||||
if (len > size - buf->top) {
|
||||
size *= 2;
|
||||
}
|
||||
if (size > WIPF_BUFFER_SIZE_MAX) {
|
||||
if (len > WIPF_BUFFER_SIZE - buf->top) {
|
||||
status = STATUS_BUFFER_TOO_SMALL;
|
||||
goto end; /* drop on overflow of buffer */
|
||||
}
|
||||
|
||||
/* resize the buffer */
|
||||
if (size != buf->size) {
|
||||
PVOID data = ExAllocatePoolWithTag(NonPagedPool, size, WIPF_BUFFER_POOL_TAG);
|
||||
if (data == NULL) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto end; /* drop on OOM */
|
||||
}
|
||||
|
||||
/* move old data to the new place */
|
||||
{
|
||||
const UINT32 top = buf->top;
|
||||
|
||||
RtlCopyMemory(data, buf->data, top);
|
||||
wipf_buffer_close(buf);
|
||||
|
||||
buf->data = data;
|
||||
buf->size = size;
|
||||
buf->top = top;
|
||||
}
|
||||
goto end; /* drop on buffer overflow */
|
||||
}
|
||||
|
||||
wipf_log_write(buf->data + buf->top, remote_ip, pid, path_len, path);
|
||||
buf->top += len;
|
||||
|
||||
wipf_log_write(buf->data, remote_ip, pid, path_len, path);
|
||||
|
||||
end:
|
||||
KeReleaseSpinLock(&buf->lock, irq);
|
||||
|
||||
|
@ -27,6 +27,8 @@ typedef struct wipf_device {
|
||||
UINT32 connect4_id;
|
||||
UINT32 accept4_id;
|
||||
|
||||
BOOL active;
|
||||
|
||||
WIPF_BUFFER buffer;
|
||||
|
||||
PWIPF_CONF_REF volatile conf_ref;
|
||||
@ -125,9 +127,6 @@ wipf_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
UNUSED(layerData);
|
||||
UNUSED(flowContext);
|
||||
|
||||
if (!(filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT))
|
||||
return;
|
||||
|
||||
conf_ref = wipf_conf_ref_take();
|
||||
|
||||
if (conf_ref == NULL)
|
||||
@ -139,8 +138,7 @@ wipf_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
path_len = inMetaValues->processPath->size;
|
||||
path = inMetaValues->processPath->data;
|
||||
|
||||
if (!(flags & FWP_CONDITION_FLAG_IS_LOOPBACK)
|
||||
&& local_ip != remote_ip) {
|
||||
if (!(flags & FWP_CONDITION_FLAG_IS_LOOPBACK)) {
|
||||
blocked = wipf_conf_ipblocked(&conf_ref->conf, remote_ip,
|
||||
path_len, path, ¬ify);
|
||||
} else {
|
||||
@ -155,6 +153,9 @@ wipf_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
|
||||
} else {
|
||||
classifyOut->actionType = FWP_ACTION_CONTINUE;
|
||||
if ((filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)) {
|
||||
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
|
||||
}
|
||||
|
||||
if (notify) {
|
||||
PIRP irp = NULL;
|
||||
@ -162,10 +163,10 @@ wipf_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
ULONG_PTR info;
|
||||
|
||||
wipf_buffer_write(&g_device->buffer, remote_ip,
|
||||
inMetaValues->processId, path_len, path,
|
||||
(UINT32) inMetaValues->processId, path_len, path,
|
||||
&irp, &irp_status, &info);
|
||||
|
||||
if (irp) {
|
||||
if (irp != NULL) {
|
||||
wipf_request_complete_info(irp, irp_status, info);
|
||||
}
|
||||
}
|
||||
@ -218,6 +219,9 @@ wipf_callout_install (PDEVICE_OBJECT device)
|
||||
FWPS_CALLOUT0 c;
|
||||
NTSTATUS status;
|
||||
|
||||
if (g_device->active)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
RtlZeroMemory(&c, sizeof(FWPS_CALLOUT0));
|
||||
|
||||
c.notifyFn = wipf_callout_notify;
|
||||
@ -229,7 +233,7 @@ wipf_callout_install (PDEVICE_OBJECT device)
|
||||
|
||||
status = FwpsCalloutRegister0(device, &c, &g_device->connect4_id);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_TRACE_LEVEL, "wipf: Register Connect V4: Error: %d\n", status);
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "WIPF: Register Connect V4: Error: %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -240,10 +244,12 @@ wipf_callout_install (PDEVICE_OBJECT device)
|
||||
|
||||
status = FwpsCalloutRegister0(device, &c, &g_device->accept4_id);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_TRACE_LEVEL, "wipf: Register Accept V4: Error: %d\n", status);
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "WIPF: Register Accept V4: Error: %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
g_device->active = TRUE;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -257,9 +263,11 @@ wipf_callout_remove (void)
|
||||
if (g_device->accept4_id) {
|
||||
FwpsCalloutUnregisterById0(g_device->accept4_id);
|
||||
}
|
||||
|
||||
g_device->active = FALSE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
static NTSTATUS
|
||||
wipf_provider_install (void)
|
||||
{
|
||||
FWPM_PROVIDER0 provider;
|
||||
@ -269,32 +277,33 @@ wipf_provider_install (void)
|
||||
HANDLE engine;
|
||||
NTSTATUS status;
|
||||
|
||||
memset(&provider, 0, sizeof(FWPM_PROVIDER0));
|
||||
RtlZeroMemory(&provider, sizeof(FWPM_PROVIDER0));
|
||||
provider.providerKey = WIPF_GUID_PROVIDER;
|
||||
provider.displayData.name = L"WipfProvider";
|
||||
provider.displayData.description = L"Windows IP Filter Provider";
|
||||
|
||||
memset(&ocallout4, 0, sizeof(FWPM_CALLOUT0));
|
||||
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;
|
||||
|
||||
memset(&icallout4, 0, sizeof(FWPM_CALLOUT0));
|
||||
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;
|
||||
|
||||
memset(&sublayer, 0, sizeof(FWPM_SUBLAYER0));
|
||||
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;
|
||||
|
||||
memset(&ofilter4, 0, sizeof(FWPM_FILTER0));
|
||||
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;
|
||||
@ -303,7 +312,8 @@ wipf_provider_install (void)
|
||||
ofilter4.action.type = FWP_ACTION_CALLOUT_UNKNOWN;
|
||||
ofilter4.action.calloutKey = WIPF_GUID_CALLOUT_CONNECT_V4;
|
||||
|
||||
memset(&ifilter4, 0, sizeof(FWPM_FILTER0));
|
||||
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;
|
||||
@ -323,15 +333,16 @@ wipf_provider_install (void)
|
||||
|| !NT_SUCCESS(status = FwpmFilterAdd0(engine, &ofilter4, NULL, NULL))
|
||||
|| !NT_SUCCESS(status = FwpmFilterAdd0(engine, &ifilter4, NULL, NULL))
|
||||
|| !NT_SUCCESS(status = FwpmTransactionCommit0(engine))
|
||||
) {
|
||||
)
|
||||
FwpmTransactionAbort0(engine);
|
||||
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "wipf: Provider Install: Error: %d\n", status);
|
||||
}
|
||||
|
||||
FwpmEngineClose0(engine);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "WIPF: Provider Install: Error: %d\n", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -340,7 +351,7 @@ wipf_provider_remove (void)
|
||||
{
|
||||
HANDLE engine;
|
||||
|
||||
if (!FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, NULL, &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);
|
||||
@ -356,7 +367,7 @@ wipf_device_create (PDEVICE_OBJECT device, PIRP irp)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
status = wipf_provider_install();
|
||||
status = wipf_callout_install(device);
|
||||
|
||||
wipf_request_complete(irp, status);
|
||||
|
||||
@ -378,7 +389,7 @@ wipf_device_cleanup (PDEVICE_OBJECT device, PIRP irp)
|
||||
{
|
||||
UNUSED(device);
|
||||
|
||||
wipf_provider_remove();
|
||||
wipf_callout_remove();
|
||||
|
||||
wipf_buffer_close(&g_device->buffer);
|
||||
wipf_conf_ref_set(NULL);
|
||||
@ -450,6 +461,10 @@ wipf_device_control (PDEVICE_OBJECT device, PIRP irp)
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "WIPF: Device Control: Error: %d\n", status);
|
||||
}
|
||||
|
||||
wipf_request_complete_info(irp, status, info);
|
||||
|
||||
return status;
|
||||
@ -460,7 +475,7 @@ wipf_driver_unload (PDRIVER_OBJECT driver)
|
||||
{
|
||||
UNICODE_STRING device_link;
|
||||
|
||||
wipf_callout_remove();
|
||||
wipf_provider_remove();
|
||||
|
||||
RtlInitUnicodeString(&device_link, DOS_DEVICE_NAME);
|
||||
IoDeleteSymbolicLink(&device_link);
|
||||
@ -504,12 +519,13 @@ DriverEntry (PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
|
||||
|
||||
KeInitializeSpinLock(&g_device->conf_lock);
|
||||
|
||||
status = wipf_callout_install(device);
|
||||
wipf_provider_remove();
|
||||
status = wipf_provider_install();
|
||||
}
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "wipf: Entry: Error: %d\n", status);
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "WIPF: Entry: Error: %d\n", status);
|
||||
wipf_driver_unload(driver);
|
||||
}
|
||||
|
||||
|
@ -52,18 +52,42 @@ wipf_lua_ioctl_setconf (lua_State *L)
|
||||
* Returns: number
|
||||
*/
|
||||
static int
|
||||
wipf_lua_buffer_size_max (lua_State *L)
|
||||
wipf_lua_buffer_size (lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, WIPF_BUFFER_SIZE_MAX);
|
||||
lua_pushinteger(L, WIPF_BUFFER_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Arguments: output (ludata), remote_ip (number),
|
||||
* pid (number), path (string)
|
||||
* Returns: length (number)
|
||||
*/
|
||||
static int
|
||||
wipf_lua_log_write (lua_State *L)
|
||||
{
|
||||
char *out = lua_touserdata(L, 1);
|
||||
const int remote_ip = lua_tointeger(L, 2);
|
||||
const int pid = lua_tointeger(L, 3);
|
||||
size_t path_len;
|
||||
const char *path = lua_tolstring(L, 4, &path_len);
|
||||
|
||||
if (out) {
|
||||
wipf_log_write(out, remote_ip, pid, path_len, path);
|
||||
|
||||
lua_pushinteger(L, WIPF_LOG_SIZE(path_len));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static luaL_Reg wipf_lib[] = {
|
||||
{"device_name", wipf_lua_device_name},
|
||||
{"ioctl_getlog", wipf_lua_ioctl_getlog},
|
||||
{"ioctl_setconf", wipf_lua_ioctl_setconf},
|
||||
{"buffer_size_max", wipf_lua_buffer_size_max},
|
||||
{"buffer_size", wipf_lua_buffer_size},
|
||||
{"log_write", wipf_lua_log_write},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
/* Windows IP Filter Log */
|
||||
|
||||
#define WIPF_BUFFER_SIZE 2 * 1024
|
||||
#define WIPF_BUFFER_SIZE_MAX 32 * 1024
|
||||
#define WIPF_BUFFER_SIZE 8 * 1024
|
||||
#define WIPF_LOG_PATH_MAX 256
|
||||
|
||||
#define WIPF_LOG_SIZE(path_len) \
|
||||
(sizeof(UINT32) + sizeof(UINT64) + sizeof(UINT32) + (path_len))
|
||||
(sizeof(UINT32) + sizeof(UINT32) + sizeof(UINT32) + (path_len))
|
||||
|
||||
|
||||
static void
|
||||
wipf_log_write (char *p, UINT32 remote_ip, UINT64 pid,
|
||||
wipf_log_write (char *p, UINT32 remote_ip, UINT32 pid,
|
||||
UINT32 path_len, const char *path)
|
||||
{
|
||||
*((UINT32 *) p)++ = remote_ip;
|
||||
*((UINT64 *) p)++ = pid;
|
||||
*((UINT32 *) p)++ = pid;
|
||||
*((UINT32 *) p)++ = path_len;
|
||||
|
||||
if (path_len) {
|
||||
@ -21,11 +21,11 @@ wipf_log_write (char *p, UINT32 remote_ip, UINT64 pid,
|
||||
}
|
||||
|
||||
static void
|
||||
wipf_log_read (const char **p, UINT32 *remote_ip, UINT64 *pid,
|
||||
wipf_log_read (const char **p, UINT32 *remote_ip, UINT32 *pid,
|
||||
UINT32 *path_len, const char **path)
|
||||
{
|
||||
*remote_ip = *((UINT32 *) *p)++;
|
||||
*pid = *((UINT64 *) *p)++;
|
||||
*pid = *((UINT32 *) *p)++;
|
||||
*path_len = *((UINT32 *) *p)++;
|
||||
|
||||
if (*path_len) {
|
||||
|
@ -6,7 +6,7 @@ local wipf = require"wipflua"
|
||||
|
||||
local device = assert(sys.handle():open(wipf.device_name(), "rw"))
|
||||
|
||||
local BUFSIZ = wipf.buffer_size_max()
|
||||
local BUFSIZ = wipf.buffer_size()
|
||||
local buf = assert(sys.mem.pointer(BUFSIZ))
|
||||
|
||||
assert(buf:write("test config"))
|
||||
|
21
test/log_test.lua
Normal file
21
test/log_test.lua
Normal file
@ -0,0 +1,21 @@
|
||||
-- WIPF Log Tests
|
||||
|
||||
local sys = require"sys"
|
||||
local wipf = require"wipflua"
|
||||
|
||||
|
||||
print"-- Log Write"
|
||||
do
|
||||
local path = "/test"
|
||||
local outlen = 12 + #path
|
||||
local bufsize = outlen + 4
|
||||
local buf = assert(sys.mem.pointer(bufsize))
|
||||
buf:memset(0, bufsize)
|
||||
buf[outlen] = 127
|
||||
assert(wipf.log_write(buf:getptr(), 1, 2, path) == outlen)
|
||||
assert(buf:tostring(#path, 12) == path)
|
||||
assert(buf[outlen] == 127)
|
||||
print("OK")
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user