36 #include <fwpmtypes.h>
47 #ifndef FWPM_SESSION_FLAG_DYNAMIC
48 #define FWPM_SESSION_FLAG_DYNAMIC 0x00000001
53 FWPM_LAYER_ALE_AUTH_CONNECT_V4,
57 0x90, 0x4f, 0x7f, 0xbc, 0xee, 0xe6, 0x0e, 0x82
62 FWPM_LAYER_ALE_AUTH_CONNECT_V6,
66 0x84, 0xc3, 0xba, 0x54, 0xdc, 0xb3, 0xb6, 0xb4
71 FWPM_CONDITION_ALE_APP_ID,
75 0x94, 0x37, 0xd8, 0x09, 0xec, 0xef, 0xc9, 0x71
80 FWPM_CONDITION_IP_REMOTE_PORT,
84 0x91, 0xb4, 0x68, 0xf6, 0x74, 0xee, 0x67, 0x4b
89 FWPM_CONDITION_IP_LOCAL_INTERFACE,
93 0xb7, 0xf3, 0xbd, 0xa5, 0xd3, 0x28, 0x90, 0xa4
102 0x86, 0xd7, 0xe9, 0x03, 0x68, 0x4a, 0xa8, 0x0c
108 OPENVPN_WFP_BLOCK_SUBLAYER,
112 0xa1, 0x81, 0x00, 0x1e, 0x8c, 0x6e, 0x04, 0xa2
126 #define OUT_ON_ERROR(err, msg) \
127 if (err) { msg_handler(err, msg); goto out; }
136 HANDLE engine = NULL;
138 FWPM_SUBLAYER0 sublayer;
141 memset(&sublayer, 0,
sizeof(sublayer));
143 err = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &
session, &engine);
144 if (err != ERROR_SUCCESS)
149 sublayer.subLayerKey = uuid;
153 sublayer.weight = 0x100;
156 err = FwpmSubLayerAdd0(engine, &sublayer, NULL);
161 FwpmEngineClose0(engine);
187 const WCHAR *exe_path,
192 FWPM_SUBLAYER0 *sublayer_ptr = NULL;
195 FWP_BYTE_BLOB *openvpnblob = NULL;
196 FWPM_FILTER0 Filter = {0};
197 FWPM_FILTER_CONDITION0 Condition[2];
198 FWPM_FILTER_CONDITION0 match_openvpn = {0};
199 FWPM_FILTER_CONDITION0 match_port_53 = {0};
200 FWPM_FILTER_CONDITION0 match_interface = {0};
201 FWPM_FILTER_CONDITION0 match_loopback = {0};
202 FWPM_FILTER_CONDITION0 match_not_loopback = {0};
213 *engine_handle = NULL;
215 err = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &
session, engine_handle);
216 OUT_ON_ERROR(err,
"FwpEngineOpen: open fwp session failed");
217 msg_handler(0,
"WFP Block: WFP engine opened");
220 if (FwpmSubLayerGetByKey0(*engine_handle, &OPENVPN_WFP_BLOCK_SUBLAYER, &sublayer_ptr)
223 msg_handler(0,
"WFP Block: Using existing sublayer");
224 FwpmFreeMemory0((
void **)&sublayer_ptr);
231 if (err == FWP_E_ALREADY_EXISTS || err == ERROR_SUCCESS)
233 msg_handler(0,
"WFP Block: Added a persistent sublayer with pre-defined UUID");
237 OUT_ON_ERROR(err,
"add_sublayer: failed to add persistent sublayer");
241 err = ConvertInterfaceIndexToLuid(index, &itf_luid);
242 OUT_ON_ERROR(err,
"Convert interface index to luid failed");
244 err = FwpmGetAppIdFromFileName0(exe_path, &openvpnblob);
245 OUT_ON_ERROR(err,
"Get byte blob for openvpn executable name failed");
248 match_openvpn.fieldKey = FWPM_CONDITION_ALE_APP_ID;
249 match_openvpn.matchType = FWP_MATCH_EQUAL;
250 match_openvpn.conditionValue.type = FWP_BYTE_BLOB_TYPE;
251 match_openvpn.conditionValue.byteBlob = openvpnblob;
253 match_port_53.fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
254 match_port_53.matchType = FWP_MATCH_EQUAL;
255 match_port_53.conditionValue.type = FWP_UINT16;
256 match_port_53.conditionValue.uint16 = 53;
258 match_interface.fieldKey = FWPM_CONDITION_IP_LOCAL_INTERFACE;
259 match_interface.matchType = FWP_MATCH_EQUAL;
260 match_interface.conditionValue.type = FWP_UINT64;
261 match_interface.conditionValue.uint64 = &itf_luid.Value;
263 match_loopback.fieldKey = FWPM_CONDITION_FLAGS;
264 match_loopback.matchType = FWP_MATCH_FLAGS_ALL_SET;
265 match_loopback.conditionValue.type = FWP_UINT32;
266 match_loopback.conditionValue.uint32 = FWP_CONDITION_FLAG_IS_LOOPBACK;
268 match_not_loopback.fieldKey = FWPM_CONDITION_FLAGS;
269 match_not_loopback.matchType = FWP_MATCH_FLAGS_NONE_SET;
270 match_not_loopback.conditionValue.type = FWP_UINT32;
271 match_not_loopback.conditionValue.uint32 = FWP_CONDITION_FLAG_IS_LOOPBACK;
274 Filter.subLayerKey = OPENVPN_WFP_BLOCK_SUBLAYER;
276 Filter.weight.type = FWP_UINT8;
277 Filter.weight.uint8 = 0xF;
278 Filter.filterCondition = Condition;
279 Filter.numFilterConditions = 1;
282 Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
283 Filter.action.type = FWP_ACTION_PERMIT;
284 Condition[0] = match_openvpn;
287 Filter.numFilterConditions = 2;
288 Condition[1] = match_port_53;
290 err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
291 OUT_ON_ERROR(err,
"Add filter to permit IPv4 traffic from OpenVPN failed");
294 Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
295 err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
296 OUT_ON_ERROR(err,
"Add filter to permit IPv6 traffic from OpenVPN failed");
298 msg_handler(0,
"WFP Block: Added permit filters for exe_path");
301 Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
302 Filter.action.type = FWP_ACTION_BLOCK;
303 Filter.weight.type = FWP_EMPTY;
304 Filter.numFilterConditions = 1;
305 Condition[0] = match_not_loopback;
308 Filter.numFilterConditions = 2;
309 Condition[1] = match_port_53;
311 err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
312 OUT_ON_ERROR(err,
"Add filter to block IPv4 traffic failed");
315 Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
316 err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
317 OUT_ON_ERROR(err,
"Add filter to block IPv6 traffic failed");
319 msg_handler(0,
"WFP Block: Added block filters for all interfaces");
324 Filter.weight.type = FWP_UINT8;
325 Filter.weight.uint8 = 0xE;
326 Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
327 Filter.action.type = FWP_ACTION_PERMIT;
328 Filter.numFilterConditions = 1;
329 Condition[0] = match_interface;
332 Filter.numFilterConditions = 2;
333 Condition[1] = match_port_53;
335 err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
336 OUT_ON_ERROR(err,
"Add filter to permit IPv4 traffic through VPN interface failed");
340 Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
341 err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
342 OUT_ON_ERROR(err,
"Add filter to permit IPv6 traffic through VPN interface failed");
344 msg_handler(0,
"WFP Block: Added permit filters for VPN interface");
347 Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
348 Filter.action.type = FWP_ACTION_BLOCK;
349 Filter.weight.type = FWP_EMPTY;
350 Filter.numFilterConditions = 2;
351 Condition[0] = match_loopback;
352 Condition[1] = match_port_53;
353 err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
354 OUT_ON_ERROR(err,
"Add filter to block IPv4 DNS traffic to loopback failed");
357 Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
358 err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
359 OUT_ON_ERROR(err,
"Add filter to block IPv6 DNS traffic to loopback failed");
361 msg_handler(0,
"WFP Block: Added block filters for DNS traffic to loopback");
366 FwpmFreeMemory0((
void **)&openvpnblob);
369 if (err && *engine_handle)
371 FwpmEngineClose0(*engine_handle);
372 *engine_handle = NULL;
387 err = FwpmEngineClose0(engine_handle);
407 MIB_IPINTERFACE_ROW ipiface;
408 InitializeIpInterfaceEntry(&ipiface);
409 ipiface.Family = family;
410 ipiface.InterfaceIndex = index;
416 err = GetIpInterfaceEntry(&ipiface);
421 if (err == NO_ERROR && ipiface.Metric <= INT_MAX)
425 *is_auto = ipiface.UseAutomaticMetric;
427 return (
int)ipiface.Metric;
447 MIB_IPINTERFACE_ROW ipiface;
448 InitializeIpInterfaceEntry(&ipiface);
449 ipiface.Family = family;
450 ipiface.InterfaceIndex = index;
451 err = GetIpInterfaceEntry(&ipiface);
454 if (family == AF_INET)
457 ipiface.SitePrefixLength = 0;
459 ipiface.Metric = metric;
462 ipiface.UseAutomaticMetric = TRUE;
466 ipiface.UseAutomaticMetric = FALSE;
468 err = SetIpInterfaceEntry(&ipiface);