mirror of
https://github.com/tnodir/fort
synced 2024-11-15 07:45:22 +00:00
Driver: Refactor filters provider.
This commit is contained in:
parent
20889f3664
commit
5553441a21
@ -1,11 +1,5 @@
|
||||
/* Fort Firewall Driver Provider (Un)Registration */
|
||||
|
||||
typedef struct fort_prov_data {
|
||||
UINT32 version : 24;
|
||||
UINT32 is_boot : 1;
|
||||
} FORT_PROV_DATA, *PFORT_PROV_DATA;
|
||||
|
||||
|
||||
static DWORD
|
||||
fort_prov_open (HANDLE *enginep)
|
||||
{
|
||||
@ -19,8 +13,13 @@ fort_prov_close (HANDLE engine)
|
||||
}
|
||||
|
||||
static void
|
||||
fort_prov_delete (HANDLE engine)
|
||||
fort_prov_unregister (void)
|
||||
{
|
||||
HANDLE engine;
|
||||
|
||||
if (fort_prov_open(&engine))
|
||||
return;
|
||||
|
||||
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_CONNECT_V4);
|
||||
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_ACCEPT_V4);
|
||||
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_FLOW_V4);
|
||||
@ -30,61 +29,37 @@ fort_prov_delete (HANDLE engine)
|
||||
FwpmCalloutDeleteByKey0(engine, (GUID *) &FORT_GUID_CALLOUT_ACCEPT_V4);
|
||||
FwpmCalloutDeleteByKey0(engine, (GUID *) &FORT_GUID_CALLOUT_FLOW_V4);
|
||||
FwpmProviderDeleteByKey0(engine, (GUID *) &FORT_GUID_PROVIDER);
|
||||
|
||||
fort_prov_close(engine);
|
||||
}
|
||||
|
||||
static void
|
||||
fort_prov_unregister (void)
|
||||
fort_prov_flow_unregister (void)
|
||||
{
|
||||
HANDLE engine;
|
||||
|
||||
if (fort_prov_open(&engine))
|
||||
return;
|
||||
|
||||
fort_prov_delete(engine);
|
||||
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_FLOW_V4);
|
||||
|
||||
fort_prov_close(engine);
|
||||
}
|
||||
|
||||
static DWORD
|
||||
fort_prov_register (BOOL is_boot, BOOL *is_bootp)
|
||||
fort_prov_register (BOOL is_boot)
|
||||
{
|
||||
FWPM_PROVIDER0 *old_provider, provider;
|
||||
FWPM_PROVIDER0 provider;
|
||||
FWPM_CALLOUT0 ocallout4, icallout4, fcallout4;
|
||||
FWPM_SUBLAYER0 sublayer;
|
||||
FWPM_FILTER0 ofilter4, ifilter4, ffilter4;
|
||||
FWPM_FILTER0 ofilter4, ifilter4;
|
||||
HANDLE engine;
|
||||
FORT_PROV_DATA provider_data;
|
||||
UINT32 filter_flags;
|
||||
DWORD status;
|
||||
|
||||
if ((status = fort_prov_open(&engine)))
|
||||
goto end;
|
||||
|
||||
if (!(status = FwpmProviderGetByKey0(
|
||||
engine, (GUID *) &FORT_GUID_PROVIDER, &old_provider))) {
|
||||
PFORT_PROV_DATA old_provider_data =
|
||||
(PFORT_PROV_DATA) old_provider->providerData.data;
|
||||
|
||||
if (old_provider_data) {
|
||||
provider_data = *old_provider_data;
|
||||
}
|
||||
|
||||
FwpmFreeMemory0((void **) &old_provider);
|
||||
|
||||
if (old_provider_data) {
|
||||
is_boot = is_bootp ? provider_data.is_boot : is_boot;
|
||||
|
||||
if (is_boot == provider_data.is_boot
|
||||
&& provider_data.version == APP_VERSION)
|
||||
goto end_close;
|
||||
|
||||
fort_prov_delete(engine);
|
||||
}
|
||||
}
|
||||
|
||||
provider_data.version = APP_VERSION;
|
||||
provider_data.is_boot = is_boot;
|
||||
|
||||
filter_flags = is_boot ? 0 : FWPM_FILTER_FLAG_PERMIT_IF_CALLOUT_UNREGISTERED;
|
||||
|
||||
RtlZeroMemory(&provider, sizeof(FWPM_PROVIDER0));
|
||||
@ -93,8 +68,6 @@ fort_prov_register (BOOL is_boot, BOOL *is_bootp)
|
||||
provider.displayData.name = (PWCHAR) L"FortProvider";
|
||||
provider.displayData.description = (PWCHAR) L"Fort Firewall Provider";
|
||||
provider.serviceName = (PWCHAR) L"fortfw";
|
||||
provider.providerData.size = sizeof(FORT_PROV_DATA);
|
||||
provider.providerData.data = (UINT8 *) &provider_data;
|
||||
|
||||
RtlZeroMemory(&ocallout4, sizeof(FWPM_CALLOUT0));
|
||||
ocallout4.calloutKey = FORT_GUID_CALLOUT_CONNECT_V4;
|
||||
@ -143,6 +116,34 @@ fort_prov_register (BOOL is_boot, BOOL *is_bootp)
|
||||
ifilter4.action.type = FWP_ACTION_CALLOUT_UNKNOWN;
|
||||
ifilter4.action.calloutKey = FORT_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 = FwpmCalloutAdd0(engine, &fcallout4, NULL, NULL))
|
||||
|| (status = FwpmSubLayerAdd0(engine, &sublayer, NULL))
|
||||
|| (status = FwpmFilterAdd0(engine, &ofilter4, NULL, NULL))
|
||||
|| (status = FwpmFilterAdd0(engine, &ifilter4, NULL, NULL))
|
||||
|| (status = FwpmTransactionCommit0(engine))) {
|
||||
FwpmTransactionAbort0(engine);
|
||||
}
|
||||
|
||||
fort_prov_close(engine);
|
||||
|
||||
end:
|
||||
return status;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
fort_prov_flow_register (void)
|
||||
{
|
||||
FWPM_FILTER0 ffilter4;
|
||||
HANDLE engine;
|
||||
DWORD status;
|
||||
|
||||
if ((status = fort_prov_open(&engine)))
|
||||
goto end;
|
||||
|
||||
RtlZeroMemory(&ffilter4, sizeof(FWPM_FILTER0));
|
||||
ffilter4.filterKey = FORT_GUID_FILTER_FLOW_V4;
|
||||
ffilter4.layerKey = FWPM_LAYER_STREAM_V4;
|
||||
@ -153,29 +154,38 @@ fort_prov_register (BOOL is_boot, BOOL *is_bootp)
|
||||
ffilter4.action.calloutKey = FORT_GUID_CALLOUT_FLOW_V4;
|
||||
|
||||
if ((status = FwpmTransactionBegin0(engine, 0))
|
||||
|| (status = FwpmProviderAdd0(engine, &provider, NULL))
|
||||
|| (status = FwpmCalloutAdd0(engine, &ocallout4, NULL, NULL))
|
||||
|| (status = FwpmCalloutAdd0(engine, &icallout4, NULL, NULL))
|
||||
|| (status = FwpmCalloutAdd0(engine, &fcallout4, NULL, NULL))
|
||||
|| (status = FwpmSubLayerAdd0(engine, &sublayer, NULL))
|
||||
|| (status = FwpmFilterAdd0(engine, &ofilter4, NULL, NULL))
|
||||
|| (status = FwpmFilterAdd0(engine, &ifilter4, NULL, NULL))
|
||||
|| (status = FwpmFilterAdd0(engine, &ffilter4, NULL, NULL))
|
||||
|| (status = FwpmTransactionCommit0(engine))) {
|
||||
FwpmTransactionAbort0(engine);
|
||||
}
|
||||
|
||||
end_close:
|
||||
fort_prov_close(engine);
|
||||
|
||||
if (is_bootp) {
|
||||
*is_bootp = is_boot;
|
||||
}
|
||||
|
||||
end:
|
||||
return status;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
fort_prov_is_boot (void)
|
||||
{
|
||||
HANDLE engine;
|
||||
BOOL is_boot = FALSE;
|
||||
|
||||
if (!fort_prov_open(&engine)) {
|
||||
FWPM_PROVIDER0 *provider;
|
||||
|
||||
if (!FwpmProviderGetByKey0(engine, (GUID *) &FORT_GUID_PROVIDER, &provider)) {
|
||||
is_boot = (provider->flags & FWPM_PROVIDER_FLAG_PERSISTENT);
|
||||
|
||||
FwpmFreeMemory0((void **) &provider);
|
||||
}
|
||||
|
||||
fort_prov_close(engine);
|
||||
}
|
||||
|
||||
return is_boot;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
fort_prov_reauth (void)
|
||||
{
|
||||
|
@ -290,20 +290,18 @@ fort_callout_install (PDEVICE_OBJECT device)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (g_device->conf_flags.log_stat) {
|
||||
/* IPv4 flow callout */
|
||||
c.calloutKey = FORT_GUID_CALLOUT_FLOW_V4;
|
||||
c.classifyFn = fort_callout_flow_v4;
|
||||
/* IPv4 flow callout */
|
||||
c.calloutKey = FORT_GUID_CALLOUT_FLOW_V4;
|
||||
c.classifyFn = fort_callout_flow_v4;
|
||||
|
||||
c.flowDeleteFn = fort_callout_flow_delete_v4;
|
||||
c.flags = FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW;
|
||||
c.flowDeleteFn = fort_callout_flow_delete_v4;
|
||||
c.flags = FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW;
|
||||
|
||||
status = FwpsCalloutRegister0(device, &c, &g_device->flow4_id);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
|
||||
"FORT: Register Flow V4: Error: %d\n", status);
|
||||
return status;
|
||||
}
|
||||
status = FwpsCalloutRegister0(device, &c, &g_device->flow4_id);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
|
||||
"FORT: Register Flow V4: Error: %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
@ -328,6 +326,61 @@ fort_callout_remove (void)
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
fort_callout_force_reauth (PDEVICE_OBJECT device,
|
||||
FORT_CONF_FLAGS old_conf_flags)
|
||||
{
|
||||
const FORT_CONF_FLAGS conf_flags = g_device->conf_flags;
|
||||
BOOL prov_changed = FALSE;
|
||||
NTSTATUS status;
|
||||
|
||||
// Check provider filters
|
||||
if (old_conf_flags.prov_boot != conf_flags.prov_boot) {
|
||||
fort_prov_unregister();
|
||||
|
||||
old_conf_flags.log_stat = 0; // flow filter unregistered
|
||||
|
||||
status = fort_prov_register(conf_flags.prov_boot);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
|
||||
"FORT: Prov. Register: Error: %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
prov_changed = TRUE;
|
||||
}
|
||||
|
||||
// Check flow filter
|
||||
if (old_conf_flags.log_stat != conf_flags.log_stat) {
|
||||
if (old_conf_flags.log_stat) {
|
||||
fort_prov_flow_unregister();
|
||||
}
|
||||
|
||||
if (conf_flags.log_stat) {
|
||||
status = fort_prov_flow_register();
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
|
||||
"FORT: Prov. Flow Register: Error: %d\n", status);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
prov_changed = TRUE;
|
||||
}
|
||||
|
||||
// Check reauth filter
|
||||
if (!prov_changed) {
|
||||
status = fort_prov_reauth();
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
|
||||
"FORT: Prov. Reauth: Error: %d\n", status);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
fort_device_create (PDEVICE_OBJECT device, PIRP irp)
|
||||
{
|
||||
@ -356,6 +409,7 @@ fort_device_cleanup (PDEVICE_OBJECT device, PIRP irp)
|
||||
UNUSED(device);
|
||||
|
||||
fort_callout_remove();
|
||||
fort_prov_reauth();
|
||||
|
||||
fort_conf_ref_set(NULL);
|
||||
|
||||
@ -399,8 +453,10 @@ fort_device_control (PDEVICE_OBJECT device, PIRP irp)
|
||||
if (conf_ref == NULL) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
} else {
|
||||
const FORT_CONF_FLAGS old_conf_flags = g_device->conf_flags;
|
||||
|
||||
fort_conf_ref_set(conf_ref);
|
||||
status = fort_prov_reauth();
|
||||
status = fort_callout_force_reauth(device, old_conf_flags);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -411,8 +467,10 @@ fort_device_control (PDEVICE_OBJECT device, PIRP irp)
|
||||
|
||||
if (conf_flags->driver_version == FORT_DRIVER_VERSION
|
||||
&& len == sizeof(FORT_CONF_FLAGS)) {
|
||||
const FORT_CONF_FLAGS old_conf_flags = g_device->conf_flags;
|
||||
|
||||
fort_conf_ref_flags_set(conf_flags);
|
||||
status = fort_prov_reauth();
|
||||
status = fort_callout_force_reauth(device, old_conf_flags);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -530,11 +588,12 @@ DriverEntry (PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
|
||||
|
||||
// Register filters provider
|
||||
{
|
||||
BOOL is_boot = FALSE;
|
||||
|
||||
status = fort_prov_register(FALSE, &is_boot);
|
||||
const BOOL is_boot = fort_prov_is_boot();
|
||||
|
||||
g_device->conf_flags.prov_boot = is_boot;
|
||||
|
||||
fort_prov_unregister(); // to upgrade from old version
|
||||
status = fort_prov_register(is_boot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ bool FortCommon::confAppBlocked(const void *drvConf,
|
||||
|
||||
uint FortCommon::provRegister(bool isBoot)
|
||||
{
|
||||
return fort_prov_register(isBoot, NULL);
|
||||
return fort_prov_register(isBoot);
|
||||
}
|
||||
|
||||
void FortCommon::provUnregister()
|
||||
|
Loading…
Reference in New Issue
Block a user