NTSTATUS PerformPendAuthorization(_Inout_ CLASSIFY_DATA** ppClassifyData, _Inout_ PEND_DATA** ppPendData, _Inout_ INJECTION_DATA** ppInjectionData) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> PerformPendAuthorization()\n"); #endif /// DBG NT_ASSERT(ppClassifyData); NT_ASSERT(ppPendData); NT_ASSERT(ppInjectionData); NT_ASSERT(*ppClassifyData); NT_ASSERT(*ppPendData); NTSTATUS status = STATUS_SUCCESS; NET_BUFFER_LIST* pNBL = (*ppPendData)->pNBL; UINT32 finalAction = (*ppPendData)->pPendAuthorizationData->finalAction; UINT32 delay = (*ppPendData)->pPendAuthorizationData->delay; BOOLEAN reInjected = FALSE; if(delay && KeGetCurrentIrql() < DISPATCH_LEVEL) KrnlHlprWorkItemSleep(delay); #pragma warning(push) #pragma warning(disable: 6001) /// *ppPendData initialized prior to call to this function /// Completes the Pend KrnlHlprPendDataDestroy(ppPendData); #pragma warning(pop) if(pNBL && finalAction == FWP_ACTION_PERMIT) { status = PrvCloneAuthorizedNBLAndInject(ppClassifyData, ppInjectionData); if(status != STATUS_SUCCESS) { DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! PerformPendAuthorization : PrvCloneAuthorizedNBLAndInject() [status: %#x]\n", status); } else reInjected = TRUE; } #pragma warning(push) #pragma warning(disable: 6001) /// *ppClassifyData initialized prior to call to this function if(!reInjected) KrnlHlprClassifyDataDestroyLocalCopy(ppClassifyData); #pragma warning(pop) #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- PerformPendAuthorization() [status: %#x]\n", status); #endif /// DBG return status; };
_IRQL_requires_same_ VOID ClassifyPendAuthorization(_In_ const FWPS_INCOMING_VALUES* pClassifyValues, _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata, _Inout_opt_ VOID* pNetBufferList, _In_ const FWPS_FILTER* pFilter, _In_ UINT64 flowContext, _Inout_ FWPS_CLASSIFY_OUT* pClassifyOut) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> ClassifyPendAuthorization()\n"); #endif /// DBG NT_ASSERT(pClassifyValues); NT_ASSERT(pMetadata); NT_ASSERT(pFilter); NT_ASSERT(pClassifyOut); NT_ASSERT(pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V6 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6); NT_ASSERT(pFilter->providerContext); NT_ASSERT(pFilter->providerContext->type == FWPM_GENERAL_CONTEXT); NT_ASSERT(pFilter->providerContext->dataBuffer); NT_ASSERT(pFilter->providerContext->dataBuffer->size == sizeof(PC_PEND_AUTHORIZATION_DATA)); NT_ASSERT(pFilter->providerContext->dataBuffer->data); NTSTATUS status = STATUS_SUCCESS; PC_PEND_AUTHORIZATION_DATA* pPendAuthorizationData = (PC_PEND_AUTHORIZATION_DATA*)pFilter->providerContext->dataBuffer->data; /// RESOURCE_ASSIGNTMENT & AUTH_LISTEN will Reauthorize after the completion of the pend. /// AUTH_CONNECT's completeOperation will trigger a Reauthorization if(KrnlHlprFwpsIncomingValueConditionFlagsAreSet(pClassifyValues, FWP_CONDITION_FLAG_IS_REAUTHORIZE)) { if(pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE) pClassifyOut->actionType = pPendAuthorizationData->finalAction; } else { BOOLEAN actionSet = FALSE; if(pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE) { INJECTION_DATA* pInjectionData = 0; PEND_DATA* pPendData = 0; #pragma warning(push) #pragma warning(disable: 6014) /// pInjectionData will be freed in completionFn using PendAuthorizationCompletionDataDestroy if(pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6) { status = KrnlHlprInjectionDataCreate(&pInjectionData, pClassifyValues, pMetadata, (NET_BUFFER_LIST*)pNetBufferList); HLPR_BAIL_ON_FAILURE(status); } #pragma warning(pop) /// AUTH_RECV_ACCEPT's injection will be indicative of PERMIT if(pInjectionData && pInjectionData->injectionState == FWPS_PACKET_INJECTED_BY_SELF) { pClassifyOut->actionType = pPendAuthorizationData->finalAction; actionSet = TRUE; } else { #pragma warning(push) #pragma warning(disable: 6014) /// pInjectionData will be freed in completionFn using PendAuthorizationCompletionDataDestroy status = KrnlHlprPendDataCreate(&pPendData, pMetadata, (NET_BUFFER_LIST*)pNetBufferList, pFilter); HLPR_BAIL_ON_FAILURE(status); #pragma warning(pop) status = TriggerPendAuthorizationOutOfBand(pClassifyValues, pMetadata, pNetBufferList, 0, pFilter, flowContext, pClassifyOut, pInjectionData, pPendData, pPendAuthorizationData); } HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS) { DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! ClassifyPendAuthorization() [status: %#x]\n", status); if(pInjectionData) KrnlHlprInjectionDataDestroy(&pInjectionData); if(pPendData) KrnlHlprPendDataDestroy(&pPendData); } if(!actionSet) { pClassifyOut->actionType = FWP_ACTION_BLOCK; pClassifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; } } } #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- ClassifyPendAuthorization()\n"); #endif /// DBG return; }
NTSTATUS KrnlHlprPendDataCreate(_Outptr_ PEND_DATA** ppPendData, _In_ const FWPS_INCOMING_VALUES* pClassifyValues, _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata, _In_opt_ NET_BUFFER_LIST* pNBL, _In_ const FWPS_FILTER* pFilter, _In_opt_ VOID* pClassifyContext, /* 0 */ _In_opt_ FWPS_CLASSIFY_OUT* pClassifyOut) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprPendDataCreate()\n"); #endif /// DBG NT_ASSERT(ppPendData); NT_ASSERT(pClassifyValues); NT_ASSERT(pMetadata); NT_ASSERT(pFilter); NTSTATUS status = STATUS_SUCCESS; HLPR_NEW(*ppPendData, PEND_DATA, WFPSAMPLER_SYSLIB_TAG); HLPR_BAIL_ON_ALLOC_FAILURE(*ppPendData, status); status = KrnlHlprPendDataPopulate(*ppPendData, pClassifyValues, pMetadata, pNBL, pFilter, pClassifyContext, pClassifyOut); HLPR_BAIL_LABEL: #pragma warning(push) #pragma warning(disable: 6001) /// *ppPendData initialized with calls to HLPR_NEW & KrnlHlprPendDataPopulate if(status != STATUS_SUCCESS && *ppPendData) KrnlHlprPendDataDestroy(ppPendData); #pragma warning(pop) #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprPendDataCreate() [status: %#x]\n", status); #endif /// DBG return status; }