Esempio n. 1
0
NTSTATUS
TLInspectAddFilter(
    IN const wchar_t* filterName,
    IN const wchar_t* filterDesc,
    IN const UINT8* remoteAddr,
    IN UINT64 context,
    IN const GUID* layerKey,
    IN const GUID* calloutKey
)
{
    NTSTATUS status = STATUS_SUCCESS;

    FWPM_FILTER0 filter = {0};
    FWPM_FILTER_CONDITION0 filterConditions[3] = {0};
    UINT conditionIndex;

    filter.layerKey = *layerKey;
    filter.displayData.name = (wchar_t*)filterName;
    filter.displayData.description = (wchar_t*)filterDesc;

    filter.action.type = FWP_ACTION_CALLOUT_TERMINATING;//FWP_ACTION_CALLOUT_UNKNOWN;//FWP_ACTION_CALLOUT_TERMINATING;
    filter.action.calloutKey = *calloutKey;
    filter.filterCondition = filterConditions;
    filter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL;//TL_INSPECT_SUBLAYER;
    filter.weight.type = FWP_EMPTY; // auto-weight.
    //filter.rawContext = context;

    //conditionIndex = 0;
    filter.filterCondition = NULL ;	//filterConditions;
    filter.numFilterConditions = 0 ; //1;

    /*   if (remoteAddr != NULL)
       {
          filterConditions[conditionIndex].fieldKey =
             FWPM_CONDITION_IP_REMOTE_ADDRESS;
          filterConditions[conditionIndex].matchType = FWP_MATCH_EQUAL;

          if (IsEqualGUID(layerKey, &FWPM_LAYER_ALE_AUTH_CONNECT_V4) ||
              IsEqualGUID(layerKey, &FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4) ||
              IsEqualGUID(layerKey, &FWPM_LAYER_INBOUND_TRANSPORT_V4) ||
              IsEqualGUID(layerKey, &FWPM_LAYER_OUTBOUND_TRANSPORT_V4))
          {
             filterConditions[conditionIndex].conditionValue.type = FWP_UINT32;
             filterConditions[conditionIndex].conditionValue.uint32 =
                *(UINT32*)remoteAddr;
          }
          else
          {
             filterConditions[conditionIndex].conditionValue.type =
                FWP_BYTE_ARRAY16_TYPE;
             filterConditions[conditionIndex].conditionValue.byteArray16 =
                (FWP_BYTE_ARRAY16*)remoteAddr;
          }

          conditionIndex++;
       }

       filter.numFilterConditions = conditionIndex;
    */
    status = FwpmFilterAdd0(
                 gEngineHandle,
                 &filter,
                 NULL,
                 NULL);

    return status;
}
Esempio n. 2
0
NTSTATUS
DDProxyAddFilter(
   IN const wchar_t* filterName,
   IN const wchar_t* filterDesc,
   IN const UINT8* remoteAddr,
   IN USHORT remotePort,
   IN FWP_DIRECTION direction,
   IN UINT64 context,
   IN const GUID* layerKey,
   IN const GUID* calloutKey
   )
{
   NTSTATUS status = STATUS_SUCCESS;

   FWPM_FILTER0 filter = {0};
   FWPM_FILTER_CONDITION0 filterConditions[3] = {0}; 
   UINT conditionIndex;

   filter.layerKey = *layerKey;
   filter.displayData.name = (wchar_t*)filterName;
   filter.displayData.description = (wchar_t*)filterDesc;

   filter.action.type = FWP_ACTION_CALLOUT_TERMINATING;
   filter.action.calloutKey = *calloutKey;
   filter.filterCondition = filterConditions;
   filter.subLayerKey = DD_PROXY_SUBLAYER;
   filter.weight.type = FWP_EMPTY; // auto-weight.
   filter.rawContext = context;

   conditionIndex = 0;

   if (remoteAddr != NULL)
   {
      filterConditions[conditionIndex].fieldKey = 
         FWPM_CONDITION_IP_REMOTE_ADDRESS;
      filterConditions[conditionIndex].matchType = FWP_MATCH_EQUAL;

      if (IsEqualGUID(layerKey, &FWPM_LAYER_DATAGRAM_DATA_V4) ||
          IsEqualGUID(layerKey, &FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4))
      {
         filterConditions[conditionIndex].conditionValue.type = FWP_UINT32;
         filterConditions[conditionIndex].conditionValue.uint32 = 
            *(UINT32*)remoteAddr;
      }
      else
      {
         filterConditions[conditionIndex].conditionValue.type = 
            FWP_BYTE_ARRAY16_TYPE;
         filterConditions[conditionIndex].conditionValue.byteArray16 = 
            (FWP_BYTE_ARRAY16*)remoteAddr;
      }

      conditionIndex++;
   }

   filterConditions[conditionIndex].fieldKey = FWPM_CONDITION_DIRECTION;
   filterConditions[conditionIndex].matchType = FWP_MATCH_EQUAL;
   filterConditions[conditionIndex].conditionValue.type = FWP_UINT32;
   filterConditions[conditionIndex].conditionValue.uint32 = direction;

   conditionIndex++;

   if (configInspectUdp)
   {
      filterConditions[conditionIndex].fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
      filterConditions[conditionIndex].matchType = FWP_MATCH_EQUAL;
      filterConditions[conditionIndex].conditionValue.type = FWP_UINT16;
      filterConditions[conditionIndex].conditionValue.uint16 = remotePort;
      
      conditionIndex++;
   }

   filter.numFilterConditions = conditionIndex;

   status = FwpmFilterAdd0(
               gEngineHandle,
               &filter,
               NULL,
               NULL);

   return status;
}
Esempio n. 3
0
DWORD
add_block_dns_filters(HANDLE *engine_handle,
                      int index,
                      const WCHAR *exe_path,
                      block_dns_msg_handler_t msg_handler
                      )
{
    FWPM_SESSION0 session = {0};
    FWPM_SUBLAYER0 *sublayer_ptr = NULL;
    NET_LUID tapluid;
    UINT64 filterid;
    FWP_BYTE_BLOB *openvpnblob = NULL;
    FWPM_FILTER0 Filter = {0};
    FWPM_FILTER_CONDITION0 Condition[2] = {0};
    DWORD err = 0;

    if (!msg_handler)
    {
        msg_handler = default_msg_handler;
    }

    /* Add temporary filters which don't survive reboots or crashes. */
    session.flags = FWPM_SESSION_FLAG_DYNAMIC;

    *engine_handle = NULL;

    err = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &session, engine_handle);
    CHECK_ERROR(err, "FwpEngineOpen: open fwp session failed");
    msg_handler(0, "Block_DNS: WFP engine opened");

    /* Check sublayer exists and add one if it does not. */
    if (FwpmSubLayerGetByKey0(*engine_handle, &OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER, &sublayer_ptr)
        == ERROR_SUCCESS)
    {
        msg_handler(0, "Block_DNS: Using existing sublayer");
        FwpmFreeMemory0((void **)&sublayer_ptr);
    }
    else
    {  /* Add a new sublayer -- as another process may add it in the meantime,
        * do not treat "already exists" as an error */
        err = add_sublayer(OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER);

        if (err == FWP_E_ALREADY_EXISTS || err == ERROR_SUCCESS)
        {
            msg_handler(0, "Block_DNS: Added a persistent sublayer with pre-defined UUID");
        }
        else
        {
            CHECK_ERROR(err, "add_sublayer: failed to add persistent sublayer");
        }
    }

    err = ConvertInterfaceIndexToLuid(index, &tapluid);
    CHECK_ERROR(err, "Convert interface index to luid failed");

    err = FwpmGetAppIdFromFileName0(exe_path, &openvpnblob);
    CHECK_ERROR(err, "Get byte blob for openvpn executable name failed");

    /* Prepare filter. */
    Filter.subLayerKey = OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER;
    Filter.displayData.name = FIREWALL_NAME;
    Filter.weight.type = FWP_UINT8;
    Filter.weight.uint8 = 0xF;
    Filter.filterCondition = Condition;
    Filter.numFilterConditions = 2;

    /* First filter. Permit IPv4 DNS queries from OpenVPN itself. */
    Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
    Filter.action.type = FWP_ACTION_PERMIT;

    Condition[0].fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
    Condition[0].matchType = FWP_MATCH_EQUAL;
    Condition[0].conditionValue.type = FWP_UINT16;
    Condition[0].conditionValue.uint16 = 53;

    Condition[1].fieldKey = FWPM_CONDITION_ALE_APP_ID;
    Condition[1].matchType = FWP_MATCH_EQUAL;
    Condition[1].conditionValue.type = FWP_BYTE_BLOB_TYPE;
    Condition[1].conditionValue.byteBlob = openvpnblob;

    err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
    CHECK_ERROR(err, "Add filter to permit IPv4 port 53 traffic from OpenVPN failed");

    /* Second filter. Permit IPv6 DNS queries from OpenVPN itself. */
    Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;

    err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
    CHECK_ERROR(err, "Add filter to permit IPv6 port 53 traffic from OpenVPN failed");

    msg_handler(0, "Block_DNS: Added permit filters for exe_path");

    /* Third filter. Block all IPv4 DNS queries. */
    Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
    Filter.action.type = FWP_ACTION_BLOCK;
    Filter.weight.type = FWP_EMPTY;
    Filter.numFilterConditions = 1;

    err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
    CHECK_ERROR(err, "Add filter to block IPv4 DNS traffic failed");

    /* Forth filter. Block all IPv6 DNS queries. */
    Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;

    err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
    CHECK_ERROR(err, "Add filter to block IPv6 DNS traffic failed");

    msg_handler(0, "Block_DNS: Added block filters for all interfaces");

    /* Fifth filter. Permit IPv4 DNS queries from TAP.
     * Use a non-zero weight so that the permit filters get higher priority
     * over the block filter added with automatic weighting */

    Filter.weight.type = FWP_UINT8;
    Filter.weight.uint8 = 0xE;
    Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
    Filter.action.type = FWP_ACTION_PERMIT;
    Filter.numFilterConditions = 2;

    Condition[1].fieldKey = FWPM_CONDITION_IP_LOCAL_INTERFACE;
    Condition[1].matchType = FWP_MATCH_EQUAL;
    Condition[1].conditionValue.type = FWP_UINT64;
    Condition[1].conditionValue.uint64 = &tapluid.Value;

    err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
    CHECK_ERROR(err, "Add filter to permit IPv4 DNS traffic through TAP failed");

    /* Sixth filter. Permit IPv6 DNS queries from TAP.
     * Use same weight as IPv4 filter */
    Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;

    err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
    CHECK_ERROR(err, "Add filter to permit IPv6 DNS traffic through TAP failed");

    msg_handler(0, "Block_DNS: Added permit filters for TAP interface");

out:

    if (openvpnblob)
    {
        FwpmFreeMemory0((void **)&openvpnblob);
    }

    if (err && *engine_handle)
    {
        FwpmEngineClose0(*engine_handle);
        *engine_handle = NULL;
    }

    return err;
}