36 #include <fwpmtypes.h> 
   46 #ifndef FWPM_SESSION_FLAG_DYNAMIC 
   47 #define FWPM_SESSION_FLAG_DYNAMIC 0x00000001 
   52     FWPM_LAYER_ALE_AUTH_CONNECT_V4,
 
   56     0x90, 0x4f, 0x7f, 0xbc, 0xee, 0xe6, 0x0e, 0x82
 
   61     FWPM_LAYER_ALE_AUTH_CONNECT_V6,
 
   65     0x84, 0xc3, 0xba, 0x54, 0xdc, 0xb3, 0xb6, 0xb4
 
   70     FWPM_CONDITION_ALE_APP_ID,
 
   74     0x94, 0x37, 0xd8, 0x09, 0xec, 0xef, 0xc9, 0x71
 
   79     FWPM_CONDITION_IP_REMOTE_PORT,
 
   83     0x91, 0xb4, 0x68, 0xf6, 0x74, 0xee, 0x67, 0x4b
 
   88     FWPM_CONDITION_IP_LOCAL_INTERFACE,
 
   92     0xb7, 0xf3, 0xbd, 0xa5, 0xd3, 0x28, 0x90, 0xa4
 
   98     OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER,
 
  102     0xa1, 0x81, 0x00, 0x1e, 0x8c, 0x6e, 0x04, 0xa2
 
  116 #define CHECK_ERROR(err, msg) \ 
  117     if (err) { msg_handler(err, msg); goto out; } 
  126     HANDLE engine = NULL;
 
  128     FWPM_SUBLAYER0 sublayer;
 
  131     memset(&sublayer, 0, 
sizeof(sublayer));
 
  133     err = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &
session, &engine);
 
  134     if (err != ERROR_SUCCESS)
 
  139     sublayer.subLayerKey = uuid;
 
  143     sublayer.weight = 0x100;
 
  146     err = FwpmSubLayerAdd0(engine, &sublayer, NULL);
 
  151         FwpmEngineClose0(engine);
 
  176                       const WCHAR *exe_path,
 
  181     FWPM_SUBLAYER0 *sublayer_ptr = NULL;
 
  184     FWP_BYTE_BLOB *openvpnblob = NULL;
 
  185     FWPM_FILTER0 Filter = {0};
 
  186     FWPM_FILTER_CONDITION0 Condition[2] = {0};
 
  197     *engine_handle = NULL;
 
  199     err = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &
session, engine_handle);
 
  200     CHECK_ERROR(err, 
"FwpEngineOpen: open fwp session failed");
 
  201     msg_handler(0, 
"Block_DNS: WFP engine opened");
 
  204     if (FwpmSubLayerGetByKey0(*engine_handle, &OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER, &sublayer_ptr)
 
  207         msg_handler(0, 
"Block_DNS: Using existing sublayer");
 
  208         FwpmFreeMemory0((
void **)&sublayer_ptr);
 
  215         if (err == FWP_E_ALREADY_EXISTS || err == ERROR_SUCCESS)
 
  217             msg_handler(0, 
"Block_DNS: Added a persistent sublayer with pre-defined UUID");
 
  221             CHECK_ERROR(err, 
"add_sublayer: failed to add persistent sublayer");
 
  225     err = ConvertInterfaceIndexToLuid(index, &tapluid);
 
  226     CHECK_ERROR(err, 
"Convert interface index to luid failed");
 
  228     err = FwpmGetAppIdFromFileName0(exe_path, &openvpnblob);
 
  229     CHECK_ERROR(err, 
"Get byte blob for openvpn executable name failed");
 
  232     Filter.subLayerKey = OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER;
 
  234     Filter.weight.type = FWP_UINT8;
 
  235     Filter.weight.uint8 = 0xF;
 
  236     Filter.filterCondition = Condition;
 
  237     Filter.numFilterConditions = 2;
 
  240     Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
 
  241     Filter.action.type = FWP_ACTION_PERMIT;
 
  243     Condition[0].fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
 
  244     Condition[0].matchType = FWP_MATCH_EQUAL;
 
  245     Condition[0].conditionValue.type = FWP_UINT16;
 
  246     Condition[0].conditionValue.uint16 = 53;
 
  248     Condition[1].fieldKey = FWPM_CONDITION_ALE_APP_ID;
 
  249     Condition[1].matchType = FWP_MATCH_EQUAL;
 
  250     Condition[1].conditionValue.type = FWP_BYTE_BLOB_TYPE;
 
  251     Condition[1].conditionValue.byteBlob = openvpnblob;
 
  253     err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
 
  254     CHECK_ERROR(err, 
"Add filter to permit IPv4 port 53 traffic from OpenVPN failed");
 
  257     Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
 
  259     err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
 
  260     CHECK_ERROR(err, 
"Add filter to permit IPv6 port 53 traffic from OpenVPN failed");
 
  262     msg_handler(0, 
"Block_DNS: Added permit filters for exe_path");
 
  265     Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
 
  266     Filter.action.type = FWP_ACTION_BLOCK;
 
  267     Filter.weight.type = FWP_EMPTY;
 
  268     Filter.numFilterConditions = 1;
 
  270     err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
 
  271     CHECK_ERROR(err, 
"Add filter to block IPv4 DNS traffic failed");
 
  274     Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
 
  276     err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
 
  277     CHECK_ERROR(err, 
"Add filter to block IPv6 DNS traffic failed");
 
  279     msg_handler(0, 
"Block_DNS: Added block filters for all interfaces");
 
  285     Filter.weight.type = FWP_UINT8;
 
  286     Filter.weight.uint8 = 0xE;
 
  287     Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
 
  288     Filter.action.type = FWP_ACTION_PERMIT;
 
  289     Filter.numFilterConditions = 2;
 
  291     Condition[1].fieldKey = FWPM_CONDITION_IP_LOCAL_INTERFACE;
 
  292     Condition[1].matchType = FWP_MATCH_EQUAL;
 
  293     Condition[1].conditionValue.type = FWP_UINT64;
 
  294     Condition[1].conditionValue.uint64 = &tapluid.Value;
 
  296     err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
 
  297     CHECK_ERROR(err, 
"Add filter to permit IPv4 DNS traffic through TAP failed");
 
  301     Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
 
  303     err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
 
  304     CHECK_ERROR(err, 
"Add filter to permit IPv6 DNS traffic through TAP failed");
 
  306     msg_handler(0, 
"Block_DNS: Added permit filters for TAP interface");
 
  312         FwpmFreeMemory0((
void **)&openvpnblob);
 
  315     if (err && *engine_handle)
 
  317         FwpmEngineClose0(*engine_handle);
 
  318         *engine_handle = NULL;
 
  333         err = FwpmEngineClose0(engine_handle);
 
  353     MIB_IPINTERFACE_ROW ipiface;
 
  354     InitializeIpInterfaceEntry(&ipiface);
 
  355     ipiface.Family = family;
 
  356     ipiface.InterfaceIndex = index;
 
  362     err = GetIpInterfaceEntry(&ipiface);
 
  367     if (err == NO_ERROR && ipiface.Metric <= INT_MAX)
 
  371             *is_auto = ipiface.UseAutomaticMetric;
 
  373         return (
int)ipiface.Metric;
 
  393     MIB_IPINTERFACE_ROW ipiface;
 
  394     InitializeIpInterfaceEntry(&ipiface);
 
  395     ipiface.Family = family;
 
  396     ipiface.InterfaceIndex = index;
 
  397     err = GetIpInterfaceEntry(&ipiface);
 
  400         if (family == AF_INET)
 
  403             ipiface.SitePrefixLength = 0;
 
  405         ipiface.Metric = metric;
 
  408             ipiface.UseAutomaticMetric = TRUE;
 
  412             ipiface.UseAutomaticMetric = FALSE;
 
  414         err = SetIpInterfaceEntry(&ipiface);