diff options
Diffstat (limited to 'src/openvpn/win32.c')
-rw-r--r-- | src/openvpn/win32.c | 285 |
1 files changed, 87 insertions, 198 deletions
diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index e17cca1..00bc7ac 100644 --- a/src/openvpn/win32.c +++ b/src/openvpn/win32.c @@ -35,7 +35,7 @@ #include "syshead.h" -#ifdef WIN32 +#ifdef _WIN32 #include "buffer.h" #include "error.h" @@ -43,34 +43,20 @@ #include "sig.h" #include "win32.h" #include "misc.h" +#include "openvpn-msg.h" #include "memdbg.h" -#include "win32_wfp.h" - #ifdef HAVE_VERSIONHELPERS_H #include <versionhelpers.h> #else #include "compat-versionhelpers.h" #endif -/* WFP function pointers. Initialized in win_wfp_init_funcs() */ -func_ConvertInterfaceIndexToLuid ConvertInterfaceIndexToLuid = NULL; -func_FwpmEngineOpen0 FwpmEngineOpen0 = NULL; -func_FwpmEngineClose0 FwpmEngineClose0 = NULL; -func_FwpmFilterAdd0 FwpmFilterAdd0 = NULL; -func_FwpmSubLayerAdd0 FwpmSubLayerAdd0 = NULL; -func_FwpmSubLayerDeleteByKey0 FwpmSubLayerDeleteByKey0 = NULL; -func_FwpmFreeMemory0 FwpmFreeMemory0 = NULL; -func_FwpmGetAppIdFromFileName0 FwpmGetAppIdFromFileName0 = NULL; - -/* - * WFP firewall name. - */ -WCHAR * FIREWALL_NAME = L"OpenVPN"; /* GLOBAL */ +#include "block_dns.h" /* - * WFP handle and GUID. + * WFP handle */ static HANDLE m_hEngineHandle = NULL; /* GLOBAL */ @@ -119,7 +105,6 @@ init_win32 (void) } window_title_clear (&window_title); win32_signal_clear (&win32_signal); - netcmd_semaphore_init (); } void @@ -598,7 +583,7 @@ win32_signal_get (struct win32_signal *ws) if (ret) { siginfo_static.signal_received = ret; - siginfo_static.hard = true; + siginfo_static.source = SIG_SOURCE_HARD; } } return ret; @@ -765,6 +750,10 @@ void netcmd_semaphore_lock (void) { const int timeout_seconds = 600; + + if (!netcmd_semaphore.hand) + netcmd_semaphore_init (); + if (!semaphore_lock (&netcmd_semaphore, timeout_seconds * 1000)) msg (M_FATAL, "Cannot lock net command semaphore"); } @@ -773,6 +762,8 @@ void netcmd_semaphore_release (void) { semaphore_release (&netcmd_semaphore); + /* netcmd_semaphore has max count of 1 - safe to close after release */ + semaphore_close (&netcmd_semaphore); } /* @@ -1106,211 +1097,109 @@ win_get_tempdir() return tmpdir; } -bool -win_wfp_init_funcs () +static bool +win_block_dns_service (bool add, int index, const HANDLE pipe) { - /* Initialize all WFP-related function pointers */ - HMODULE iphlpapiHandle; - HMODULE fwpuclntHandle; - - iphlpapiHandle = LoadLibrary("iphlpapi.dll"); - if (iphlpapiHandle == NULL) - { - msg (M_NONFATAL, "Can't load iphlpapi.dll"); - return false; - } + DWORD len; + bool ret = false; + ack_message_t ack; + struct gc_arena gc = gc_new (); - fwpuclntHandle = LoadLibrary("fwpuclnt.dll"); - if (fwpuclntHandle == NULL) - { - msg (M_NONFATAL, "Can't load fwpuclnt.dll"); - return false; - } - - ConvertInterfaceIndexToLuid = (func_ConvertInterfaceIndexToLuid)GetProcAddress(iphlpapiHandle, "ConvertInterfaceIndexToLuid"); - FwpmFilterAdd0 = (func_FwpmFilterAdd0)GetProcAddress(fwpuclntHandle, "FwpmFilterAdd0"); - FwpmEngineOpen0 = (func_FwpmEngineOpen0)GetProcAddress(fwpuclntHandle, "FwpmEngineOpen0"); - FwpmEngineClose0 = (func_FwpmEngineClose0)GetProcAddress(fwpuclntHandle, "FwpmEngineClose0"); - FwpmSubLayerAdd0 = (func_FwpmSubLayerAdd0)GetProcAddress(fwpuclntHandle, "FwpmSubLayerAdd0"); - FwpmSubLayerDeleteByKey0 = (func_FwpmSubLayerDeleteByKey0)GetProcAddress(fwpuclntHandle, "FwpmSubLayerDeleteByKey0"); - FwpmFreeMemory0 = (func_FwpmFreeMemory0)GetProcAddress(fwpuclntHandle, "FwpmFreeMemory0"); - FwpmGetAppIdFromFileName0 = (func_FwpmGetAppIdFromFileName0)GetProcAddress(fwpuclntHandle, "FwpmGetAppIdFromFileName0"); - - if (!ConvertInterfaceIndexToLuid || - !FwpmFilterAdd0 || - !FwpmEngineOpen0 || - !FwpmEngineClose0 || - !FwpmSubLayerAdd0 || - !FwpmSubLayerDeleteByKey0 || - !FwpmFreeMemory0 || - !FwpmGetAppIdFromFileName0) - { - msg (M_NONFATAL, "Can't get address for all WFP-related procedures."); - return false; - } + block_dns_message_t data = { + .header = { + (add ? msg_add_block_dns : msg_del_block_dns), + sizeof (block_dns_message_t), + 0 }, + .iface = { .index = index, .name = "" } + }; - return true; -} + if (!WriteFile (pipe, &data, sizeof (data), &len, NULL) || + !ReadFile (pipe, &ack, sizeof (ack), &len, NULL)) + { + msg (M_WARN, "Block_DNS: could not talk to service: %s [%lu]", + strerror_win32 (GetLastError (), &gc), GetLastError ()); + goto out; + } -bool -win_wfp_add_filter (HANDLE engineHandle, - const FWPM_FILTER0 *filter, - PSECURITY_DESCRIPTOR sd, - UINT64 *id) -{ - if (FwpmFilterAdd0(engineHandle, filter, sd, id) != ERROR_SUCCESS) + if (ack.error_number != NO_ERROR) { - msg (M_NONFATAL, "Can't add WFP filter"); - return false; + msg (M_WARN, "Block_DNS: %s block dns filters using service failed: %s [status=0x%x if_index=%d]", + (add ? "adding" : "deleting"), strerror_win32 (ack.error_number, &gc), + ack.error_number, data.iface.index); + goto out; } - return true; + + ret = true; + msg (M_INFO, "%s outside dns using service succeeded.", (add ? "Blocking" : "Unblocking")); +out: + gc_free (&gc); + return ret; } -bool -win_wfp_block_dns (const NET_IFINDEX index) +static void +block_dns_msg_handler (DWORD err, const char *msg) { - FWPM_SESSION0 session = {0}; - FWPM_SUBLAYER0 SubLayer = {0}; - NET_LUID tapluid; - UINT64 filterid; - WCHAR openvpnpath[MAX_PATH]; - FWP_BYTE_BLOB *openvpnblob = NULL; - FWPM_FILTER0 Filter = {0}; - FWPM_FILTER_CONDITION0 Condition[2] = {0}; - - /* Add temporary filters which don't survive reboots or crashes. */ - session.flags = FWPM_SESSION_FLAG_DYNAMIC; - - dmsg (D_LOW, "Opening WFP engine"); + struct gc_arena gc = gc_new (); - if (FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &m_hEngineHandle) != ERROR_SUCCESS) + if (err == 0) { - msg (M_NONFATAL, "Can't open WFP engine"); - return false; + msg (M_INFO, "%s", msg); + } + else + { + msg (M_WARN, "Error in add_block_dns_filters(): %s : %s [status=0x%lx]", + msg, strerror_win32 (err, &gc), err); } - if (UuidCreate(&SubLayer.subLayerKey) != NO_ERROR) - return false; + gc_free (&gc); +} - /* Populate packet filter layer information. */ - SubLayer.displayData.name = FIREWALL_NAME; - SubLayer.displayData.description = FIREWALL_NAME; - SubLayer.flags = 0; - SubLayer.weight = 0x100; +bool +win_wfp_block_dns (const NET_IFINDEX index, const HANDLE msg_channel) +{ + WCHAR openvpnpath[MAX_PATH]; + bool ret = false; + DWORD status; - /* Add packet filter to our interface. */ - dmsg (D_LOW, "Adding WFP sublayer"); - if (FwpmSubLayerAdd0(m_hEngineHandle, &SubLayer, NULL) != ERROR_SUCCESS) + if (msg_channel) { - msg (M_NONFATAL, "Can't add WFP sublayer"); - return false; + dmsg (D_LOW, "Using service to add block dns filters"); + ret = win_block_dns_service (true, index, msg_channel); + goto out; } - dmsg (D_LOW, "Blocking DNS using WFP"); - if (ConvertInterfaceIndexToLuid(index, &tapluid) != NO_ERROR) + status = GetModuleFileNameW (NULL, openvpnpath, sizeof(openvpnpath)); + if (status == 0 || status == sizeof(openvpnpath)) { - msg (M_NONFATAL, "Can't convert interface index to LUID"); - return false; + msg (M_WARN|M_ERRNO, "block_dns: cannot get executable path"); + goto out; } - dmsg (D_LOW, "Tap Luid: %I64d", tapluid.Value); - - /* Get OpenVPN path. */ - GetModuleFileNameW(NULL, openvpnpath, MAX_PATH); - - if (FwpmGetAppIdFromFileName0(openvpnpath, &openvpnblob) != ERROR_SUCCESS) - return false; - - /* Prepare filter. */ - Filter.subLayerKey = SubLayer.subLayerKey; - 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; - - 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; - - /* Add filter condition to our interface. */ - if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid)) - goto err; - dmsg (D_LOW, "Filter (Permit OpenVPN IPv4 DNS) added with ID=%I64d", filterid); - - /* Second filter. Permit IPv6 DNS queries from OpenVPN itself. */ - Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6; - - /* Add filter condition to our interface. */ - if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid)) - goto err; - dmsg (D_LOW, "Filter (Permit OpenVPN IPv6 DNS) added with ID=%I64d", filterid); - - /* 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; - - if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid)) - goto err; - dmsg (D_LOW, "Filter (Block IPv4 DNS) added with ID=%I64d", filterid); - - /* Forth filter. Block all IPv6 DNS queries. */ - Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6; - - if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid)) - goto err; - dmsg (D_LOW, "Filter (Block IPv6 DNS) added with ID=%I64d", filterid); - - /* Fifth filter. Permit IPv4 DNS queries from TAP. */ - 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; - - /* Add filter condition to our interface. */ - if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid)) - goto err; - dmsg (D_LOW, "Filter (Permit IPv4 DNS queries from TAP) added with ID=%I64d", filterid); - - /* Sixth filter. Permit IPv6 DNS queries from TAP. */ - Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6; - - /* Add filter condition to our interface. */ - if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid)) - goto err; - dmsg (D_LOW, "Filter (Permit IPv6 DNS queries from TAP) added with ID=%I64d", filterid); - - FwpmFreeMemory0((void **)&openvpnblob); - return true; - err: - FwpmFreeMemory0((void **)&openvpnblob); - return false; + status = add_block_dns_filters (&m_hEngineHandle, index, openvpnpath, + block_dns_msg_handler); + ret = (status == 0); + +out: + + return ret; } bool -win_wfp_uninit() +win_wfp_uninit(const HANDLE msg_channel) { dmsg (D_LOW, "Uninitializing WFP"); - if (m_hEngineHandle) { - FwpmEngineClose0(m_hEngineHandle); + + if (msg_channel) + { + msg (D_LOW, "Using service to delete block dns filters"); + win_block_dns_service (false, -1, msg_channel); + } + else + { + delete_block_dns_filters (m_hEngineHandle); m_hEngineHandle = NULL; - } + } + return true; } |