locked
WFP - Executing code on PASSIVE_LEVEL RRS feed

  • Question

  • Hi All,

    I am implementing a filter driver . Actually, I have two callouts in my driver.

    1. FWPS_LAYER_ALE_FLOW_ESTABLISHED_Vx layer

    2. FWPM_LAYER_STREAM_V4

    In FWPS_LAYER_ALE_FLOW_ESTABLISHED_Vx layer, I would get the address, port , flowHandle and processId values and fills a connection information data structure. Also I need to create a GUID for the connection. For that I am using ExUuidCreate method. I need to get the user information for the connection as well. So I get the current process and identify the primary token. From that, the token groups will also be identified. The methods I use for these are PsReferencePrimaryToken(PsGetCurrentProcess()), ZwQueryInformationToken(), RtlLengthSid(),RtlCopyMemory() etc. Once I got all these information in the connection information structure, I would associate the callout driver-defined context with a data flow and set the classify out action type to continue ( classifyOut->actionType = FWP_ACTION_CONTINUE; )

    Basically I am not blocking anything at this layer.

    In FWPM_LAYER_STREAM_V4 layer, the asscoicated data flow will be retreived and blocked based on certain conditions.

    Since   ExUuidCreate, ZwQueryInformationToken(), RtlLengthSid etc. must be called on PASSIVE_LEVEL and < DISPATCH_LEVEL, I need to either go for pending the operation (which is not good at the FLOW_ESTABLISHED layer) and need to move everything to  FWPS_LAYER_ALE_AUTH_CONNECT_Vx and FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_Vx layers) or  to move calling ZwQueryInformationToken(...) to asynchronous worker without pending of WFP requests.

    1. Could you please advise me what would be the best option according to the business requirements here ?

    2. Also please could you advise whether we can call asynchronous worker multiple times (for getting the connection GUID and user information) or is it fine if I do multiple operations inside the worker ?.

    3. Understanding my filter requirements, could you please advise me whether I am following the right approach?

    Any help is greatly appreciated .Thanks in advance.

    Regards,

    Krishnanand


    Thursday, June 23, 2011 12:42 PM

All replies

  • You should pend at the ALE_AUTH_CONNECT & ALE_RECV_ACCEPT layers.  Do your PASSIVE_LEVEL calls.  When you unpend, you would then do your flow association @ ALE_FLOW_ESTABLISHED.

    You can queue as many work items as you need.  It is also fine to do all of your processing in a single work item.  Queueing multiple work items just means you need to wait until all are finished.

     

    Hope this helps,

     


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Friday, June 24, 2011 6:11 PM
    Moderator
  • Hi Dusty,

    Thank you so much for your answer.

    Since the pending approach needs a lot of changes from my existing code base ,currently I am planning to move the calls which should be at PASSIVE_LEVEL to a work queue using IoAllocateWorkItem  and IoQueueWorkItem (from ALE_FLOW_ESTABLISHED). Hope this helps to execute the methods at PASSIVE_LEVEL and the flow waits till the work item is freed using IoFreeWorkItem.

    Could you please correct me if I my assumption is wrong ?

    Thanks,

    Krishnanand

    Monday, June 27, 2011 4:17 AM
  • The only problem I see is you don't know when your work item will finish.  That is one of the reasons you need to pend.  Are you finishing the classify at FLOW_ESTABLISHED and using another method to associate?  You shouldn't be pending at FLOW_ESTABLISHED.  If you are waiting inside the FLOW_ESTABLISHED classify for the workitem to finish, then this is very bad design and will likely lead to a deadlock and DPC timeouts.

     

     


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Monday, June 27, 2011 5:30 PM
    Moderator
  • Thank you for the reply .

    I am not finishing the classify at FLOW_ESTABLISHED layer. The order of method calls at my FLOW_ESTABLISHED layer is as follows.
     {
    ………………………………….
    // Queue the work item IoQueueWorkItem(pIOWorkItem,DequeueHandler, DelayedWorkQueue, pQueuedWorkItem);
    // Associate the flow context status = FwpsFlowAssociateContext(flowHandle, FWPS_LAYER_STREAM_V4, streamId, (UINT64) data);
     TRACE(INFO, ("Associated the flow context"));

     classifyOut->actionType = FWP_ACTION_CONTINUE;
     }
    The methods that have to be called at the PASSIVE_LEVEL will be called in DequeueHandler method .
    I had assumed FwpsFlowAssociateContext will be called only after the processing ends in DequeueHandler method ie in a synchronous way.
    I have one more callout FWPS_LAYER_STREAM_V4 where the associated data flow will be retrieved and blocked based on certain conditions.
    I guess I have no other option left with other than moving everything from FLOW_ESTABLISHED layer to ALE_AUTH_CONNECT & ALE_RECV_ACCEPT layers.
    Is it possible to associate the flow context from ALE_AUTH_CONNECT and ALE_RECV_ACCEPT layers and continue the processing from FWPS_LAYER_STREAM_V4 layer ?

    Thanks in advance.

    Regards,
    Krishnanand

    Tuesday, June 28, 2011 5:20 AM
  • You can associate flow anywhere you are indicated a valid flow handle.  both AUTH_CONNECT and AUTH_RECV_ACCEPT indicate this to you.

    Hope this helps,

     


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Tuesday, June 28, 2011 4:58 PM
    Moderator
  • Thank you so much for the reply.
    Actually my intention was to block certain sites and port depending up on the users (only TCP). So I chose to have the ALE_FLOW_ESTABLISHED and FWPS_LAYER_STREAM callouts in my driver.
    If I replace the ALE_FLOW_ESTABLISHED layer, can I achieve the same with ALE_CONNECT layer ? . Should I register callouts on  both ALE_CONNECT and ALE_RECV_ACCEPT ?
    Basically I don't want to block the packets at this layer. All I want is to create a data structure which stores the connection information (including the user info and the Guid generated , both needs to be called at PASSIVE_LEVEL) and associate the data flow context  so that the  FWPS_LAYER_STREAM_V4 will be able to check the data and allow the user to access it based on some configuration.

    I went through the 'Inspect' sample code from WDK. There are methods to clone reinject  inbound and outbound.
    Could you please tell me whether that is required for my requirement (explained above) ?

    Please note that I am working on Windows7 and I have seen forums saying about  issue of Inspect sample on Windows7 as follows.

    http://social.msdn.microsoft.com/Forums/en-US/wfp/thread/126f48c9-3963-4fe6-a0e5-a87c1e953936 .

    Thanks in advance.

    Thanks,
    Krishnanand



    Wednesday, June 29, 2011 8:23 AM
  • You are looking at this as an either / or.  You should likely implement CONNECT & RECV_ACCEPT (to do your pending, create your context), FLOW_ESTABLISHED to associate your context, and Stream to parse the HTTP info.  Inspect deals with Packet Injection.  You would be better served by the StmEdit Sample.

     

    Hope this helps,


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Wednesday, June 29, 2011 5:02 PM
    Moderator
  • Hi Dusty,

    Many thanks for the help. I will follow like this.

    Thanks and Regards,

    Krishnanand

    Thursday, June 30, 2011 10:44 AM
  • Hi Dusty,

    Apologies for asking this  again .
    As you said, I can create a flow context at CONNECT & RECV_ACCEPT  layer. But how can I get the same context at FLOW_ESTABLISHED to associate the context at that layer ? Did you mean to associate the context  from ALE_AUTH connect  layer and re associate it at the FLOW_ESTABLISHED layer again?
    I am very much new to the driver programming , please help me on this.

    Thanks,
    Krishnanand

    Wednesday, July 6, 2011 1:13 PM