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);