287 void block(
const std::wstring &openvpn_app_path,
288 NET_IFINDEX itf_index,
293 FWPM_FILTER0 filter = {};
294 FWPM_FILTER_CONDITION0 condition[2] = {};
295 FWPM_FILTER_CONDITION0 match_openvpn = {};
296 FWPM_FILTER_CONDITION0 match_port_53 = {};
297 FWPM_FILTER_CONDITION0 match_interface = {};
298 FWPM_FILTER_CONDITION0 match_loopback = {};
299 FWPM_FILTER_CONDITION0 match_not_loopback = {};
310 FWPM_SUBLAYER0 subLayer = {};
312 subLayer.displayData.name =
const_cast<wchar_t *
>(L
"OpenVPN");
313 subLayer.displayData.description =
const_cast<wchar_t *
>(L
"OpenVPN");
315 subLayer.weight = 0x100;
318 const DWORD status = ::FwpmSubLayerAdd0(
engineHandle(), &subLayer, NULL);
319 if (status != ERROR_SUCCESS)
320 OPENVPN_THROW(wfp_error,
"FwpmSubLayerAdd0 failed with status=0x" << std::hex << status);
324 match_openvpn.fieldKey = FWPM_CONDITION_ALE_APP_ID;
325 match_openvpn.matchType = FWP_MATCH_EQUAL;
326 match_openvpn.conditionValue.type = FWP_BYTE_BLOB_TYPE;
327 match_openvpn.conditionValue.byteBlob = openvpn_app_id_blob.get();
329 match_port_53.fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
330 match_port_53.matchType = FWP_MATCH_EQUAL;
331 match_port_53.conditionValue.type = FWP_UINT16;
332 match_port_53.conditionValue.uint16 = 53;
334 match_interface.fieldKey = FWPM_CONDITION_IP_LOCAL_INTERFACE;
335 match_interface.matchType = FWP_MATCH_EQUAL;
336 match_interface.conditionValue.type = FWP_UINT64;
337 match_interface.conditionValue.uint64 = &itf_luid.Value;
339 match_loopback.fieldKey = FWPM_CONDITION_FLAGS;
340 match_loopback.matchType = FWP_MATCH_FLAGS_ALL_SET;
341 match_loopback.conditionValue.type = FWP_UINT32;
342 match_loopback.conditionValue.uint32 = FWP_CONDITION_FLAG_IS_LOOPBACK;
344 match_not_loopback.fieldKey = FWPM_CONDITION_FLAGS;
345 match_not_loopback.matchType = FWP_MATCH_FLAGS_NONE_SET;
346 match_not_loopback.conditionValue.type = FWP_UINT32;
347 match_not_loopback.conditionValue.uint32 = FWP_CONDITION_FLAG_IS_LOOPBACK;
351 filter.displayData.name =
const_cast<wchar_t *
>(L
"OpenVPN");
352 filter.weight.type = FWP_UINT8;
353 filter.weight.uint8 = 0xF;
354 filter.filterCondition = condition;
357 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
358 filter.action.type = FWP_ACTION_PERMIT;
359 filter.numFilterConditions = 1;
360 condition[0] = match_openvpn;
362 log <<
"permit IPv4 requests from OpenVPN app" << std::endl;
366 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
368 log <<
"permit IPv6 requests from OpenVPN app" << std::endl;
372 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
373 filter.action.type = FWP_ACTION_BLOCK;
374 filter.weight.type = FWP_EMPTY;
375 filter.numFilterConditions = 1;
376 condition[0] = match_not_loopback;
379 filter.numFilterConditions = 2;
380 condition[1] = match_port_53;
383 log <<
"block IPv4 requests from other apps" << std::endl;
387 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
389 log <<
"block IPv6 requests from other apps" << std::endl;
393 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
394 filter.action.type = FWP_ACTION_PERMIT;
395 filter.numFilterConditions = 1;
396 condition[0] = match_interface;
398 log <<
"allow IPv4 traffic from TAP" << std::endl;
402 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
404 log <<
"allow IPv6 traffic from TAP" << std::endl;
409 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
410 filter.action.type = FWP_ACTION_BLOCK;
411 filter.weight.type = FWP_EMPTY;
412 filter.numFilterConditions = 2;
413 condition[0] = match_loopback;
414 condition[1] = match_port_53;
416 log <<
"block IPv4 DNS requests to loopback from other apps" << std::endl;
420 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
422 log <<
"block IPv6 DNS requests to loopback from other apps" << std::endl;