diff options
Diffstat (limited to 'src/openvpn/block_dns.c')
-rw-r--r-- | src/openvpn/block_dns.c | 380 |
1 files changed, 196 insertions, 184 deletions
diff --git a/src/openvpn/block_dns.c b/src/openvpn/block_dns.c index cb3ce88..e31765e 100644 --- a/src/openvpn/block_dns.c +++ b/src/openvpn/block_dns.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> * 2015-2016 <iam@valdikss.org.ru> * 2016 Selva Nair <selva.nair@gmail.com> * @@ -53,60 +53,60 @@ #define FWPM_SESSION_FLAG_DYNAMIC 0x00000001 #endif -// c38d57d1-05a7-4c33-904f-7fbceee60e82 +/* c38d57d1-05a7-4c33-904f-7fbceee60e82 */ DEFINE_GUID( - FWPM_LAYER_ALE_AUTH_CONNECT_V4, - 0xc38d57d1, - 0x05a7, - 0x4c33, - 0x90, 0x4f, 0x7f, 0xbc, 0xee, 0xe6, 0x0e, 0x82 -); - -// 4a72393b-319f-44bc-84c3-ba54dcb3b6b4 + FWPM_LAYER_ALE_AUTH_CONNECT_V4, + 0xc38d57d1, + 0x05a7, + 0x4c33, + 0x90, 0x4f, 0x7f, 0xbc, 0xee, 0xe6, 0x0e, 0x82 + ); + +/* 4a72393b-319f-44bc-84c3-ba54dcb3b6b4 */ DEFINE_GUID( - FWPM_LAYER_ALE_AUTH_CONNECT_V6, - 0x4a72393b, - 0x319f, - 0x44bc, - 0x84, 0xc3, 0xba, 0x54, 0xdc, 0xb3, 0xb6, 0xb4 -); - -// d78e1e87-8644-4ea5-9437-d809ecefc971 + FWPM_LAYER_ALE_AUTH_CONNECT_V6, + 0x4a72393b, + 0x319f, + 0x44bc, + 0x84, 0xc3, 0xba, 0x54, 0xdc, 0xb3, 0xb6, 0xb4 + ); + +/* d78e1e87-8644-4ea5-9437-d809ecefc971 */ DEFINE_GUID( - FWPM_CONDITION_ALE_APP_ID, - 0xd78e1e87, - 0x8644, - 0x4ea5, - 0x94, 0x37, 0xd8, 0x09, 0xec, 0xef, 0xc9, 0x71 -); - -// c35a604d-d22b-4e1a-91b4-68f674ee674b + FWPM_CONDITION_ALE_APP_ID, + 0xd78e1e87, + 0x8644, + 0x4ea5, + 0x94, 0x37, 0xd8, 0x09, 0xec, 0xef, 0xc9, 0x71 + ); + +/* c35a604d-d22b-4e1a-91b4-68f674ee674b */ DEFINE_GUID( - FWPM_CONDITION_IP_REMOTE_PORT, - 0xc35a604d, - 0xd22b, - 0x4e1a, - 0x91, 0xb4, 0x68, 0xf6, 0x74, 0xee, 0x67, 0x4b -); - -// 4cd62a49-59c3-4969-b7f3-bda5d32890a4 + FWPM_CONDITION_IP_REMOTE_PORT, + 0xc35a604d, + 0xd22b, + 0x4e1a, + 0x91, 0xb4, 0x68, 0xf6, 0x74, 0xee, 0x67, 0x4b + ); + +/* 4cd62a49-59c3-4969-b7f3-bda5d32890a4 */ DEFINE_GUID( - FWPM_CONDITION_IP_LOCAL_INTERFACE, - 0x4cd62a49, - 0x59c3, - 0x4969, - 0xb7, 0xf3, 0xbd, 0xa5, 0xd3, 0x28, 0x90, 0xa4 -); + FWPM_CONDITION_IP_LOCAL_INTERFACE, + 0x4cd62a49, + 0x59c3, + 0x4969, + 0xb7, 0xf3, 0xbd, 0xa5, 0xd3, 0x28, 0x90, 0xa4 + ); /* UUID of WFP sublayer used by all instances of openvpn - 2f660d7e-6a37-11e6-a181-001e8c6e04a2 */ + * 2f660d7e-6a37-11e6-a181-001e8c6e04a2 */ DEFINE_GUID( - OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER, - 0x2f660d7e, - 0x6a37, - 0x11e6, - 0xa1, 0x81, 0x00, 0x1e, 0x8c, 0x6e, 0x04, 0xa2 -); + OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER, + 0x2f660d7e, + 0x6a37, + 0x11e6, + 0xa1, 0x81, 0x00, 0x1e, 0x8c, 0x6e, 0x04, 0xa2 + ); static WCHAR *FIREWALL_NAME = L"OpenVPN"; @@ -114,45 +114,49 @@ static WCHAR *FIREWALL_NAME = L"OpenVPN"; * Default msg handler does nothing */ static inline void -default_msg_handler (DWORD err, const char *msg) +default_msg_handler(DWORD err, const char *msg) { - return; + return; } #define CHECK_ERROR(err, msg) \ - if (err) { msg_handler (err, msg); goto out; } + if (err) { msg_handler(err, msg); goto out; } /* * Add a persistent sublayer with specified uuid. */ static DWORD -add_sublayer (GUID uuid) +add_sublayer(GUID uuid) { - FWPM_SESSION0 session; - HANDLE engine = NULL; - DWORD err = 0; - FWPM_SUBLAYER0 sublayer; + FWPM_SESSION0 session; + HANDLE engine = NULL; + DWORD err = 0; + FWPM_SUBLAYER0 sublayer; - memset (&session, 0, sizeof(session)); - memset (&sublayer, 0, sizeof(sublayer)); + memset(&session, 0, sizeof(session)); + memset(&sublayer, 0, sizeof(sublayer)); - err = FwpmEngineOpen0 (NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engine); - if (err != ERROR_SUCCESS) - goto out; + err = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engine); + if (err != ERROR_SUCCESS) + { + goto out; + } - sublayer.subLayerKey = uuid; - sublayer.displayData.name = FIREWALL_NAME; - sublayer.displayData.description = FIREWALL_NAME; - sublayer.flags = 0; - sublayer.weight = 0x100; + sublayer.subLayerKey = uuid; + sublayer.displayData.name = FIREWALL_NAME; + sublayer.displayData.description = FIREWALL_NAME; + sublayer.flags = 0; + sublayer.weight = 0x100; - /* Add sublayer to the session */ - err = FwpmSubLayerAdd0 (engine, &sublayer, NULL); + /* Add sublayer to the session */ + err = FwpmSubLayerAdd0(engine, &sublayer, NULL); out: - if (engine) - FwpmEngineClose0 (engine); - return err; + if (engine) + { + FwpmEngineClose0(engine); + } + return err; } /* @@ -173,160 +177,168 @@ out: */ DWORD -add_block_dns_filters (HANDLE *engine_handle, - int index, - const WCHAR *exe_path, - block_dns_msg_handler_t msg_handler +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) + 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 (0, "Block_DNS: Using existing sublayer"); - FwpmFreeMemory0 ((void **)&sublayer_ptr); + msg_handler = default_msg_handler; } - 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"); + /* 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 = 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"); + 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; + /* 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; + /* 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[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; + 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"); + 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; + /* 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"); + 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"); + 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; + /* 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"); + 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; + /* 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"); + 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"); + 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 */ + /* 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; + 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; + 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"); + 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; + /* 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"); + 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"); + msg_handler(0, "Block_DNS: Added permit filters for TAP interface"); out: - if (openvpnblob) - FwpmFreeMemory0 ((void **)&openvpnblob); + if (openvpnblob) + { + FwpmFreeMemory0((void **)&openvpnblob); + } - if (err && *engine_handle) + if (err && *engine_handle) { - FwpmEngineClose0 (*engine_handle); - *engine_handle = NULL; + FwpmEngineClose0(*engine_handle); + *engine_handle = NULL; } - return err; + return err; } DWORD -delete_block_dns_filters (HANDLE engine_handle) +delete_block_dns_filters(HANDLE engine_handle) { - DWORD err = 0; - /* - * For dynamic sessions closing the engine removes all filters added in the session - */ - if (engine_handle) + DWORD err = 0; + /* + * For dynamic sessions closing the engine removes all filters added in the session + */ + if (engine_handle) { - err = FwpmEngineClose0(engine_handle); + err = FwpmEngineClose0(engine_handle); } - return err; + return err; } -#endif +#endif /* ifdef _WIN32 */ |