From patchwork Tue Jan 9 00:48:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "plaisthos (Code Review)" X-Patchwork-Id: 3555 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7301:2791:b0:100:d2e5:60d with SMTP id hm17csp5582855dyb; Mon, 8 Jan 2024 16:49:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IGnQUiLoJSNJco2f6kwTa23kkoh8ZTsvdfGDIjtbRjLZg/KJYTK7mAb9v2xkpHbVq2SnUxh X-Received: by 2002:a05:6a20:d408:b0:199:36bf:df9e with SMTP id il8-20020a056a20d40800b0019936bfdf9emr8539973pzb.4.1704761389674; Mon, 08 Jan 2024 16:49:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704761389; cv=none; d=google.com; s=arc-20160816; b=WxC2oYQ2owHQYWpFkE2E2WfG9pw0kaqI/P3h4ga5kqHMKdst0Cw2MExLkCip2T3/r8 DvfvbczJMc7P6Lb2Z2k3bLtsOZioAYJbJ/5VZdmKwapXlFulmdoxX4+cLgk8zanLez3C VfxtxuY6MGO5Vzzz3W09vDvsDxKZ43ife9S0GEnMBLRU6VdBtDlcGFhCRntD2HiZA+QU r72HworIVy/hhI+dSrYcnuXl8mSY+mPx2OMbnhkn6Vpl94N8NIAFCXQA1pNJHRPGS7GK SlEkYn/vKFHQ8k5/yP2cGV1ZykY2AFLaNMkUb8PgX32sNPrvl12009uhXlmZ5+rOCdeO qFDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:cc:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:user-agent :mime-version:message-id:references:auto-submitted:to:date:from :dkim-signature:dkim-signature:dkim-signature; bh=Q3BkW9yN+t3hhITEeKGuH7hU/iVp3DmuVIQqzLqw5Kk=; fh=U7wEyxtwz2o5+UdevFSA47vNeG9knhWH0KV//QhD5a0=; b=RtIRWjoKda06iVGyuJohzEJ2EYvPy1PCZdreTmetErNXy1zqBPPDPBy414SLSDQmqu OI8UEwl0omqMOahP7cQFvQwJ8kVNXJQEngxKSw7wSKMsVX0mJEjt1HeA8bwTz4Caq44A +JxpZw9CSxChiALCWiWu4dZj3kL8k7jMGAbCuGiHeaAHQ79ZQMeJGRoxEZ7uQW9JrKM1 FqiGkv7GEtH8Xk4H3r1B4YKsoT50B58fx1FN1neoBB9Ot1EA5mPnDIGvwakRYw84YZB2 uNZct3J71MqwJ332d1kxn8FzXr2Tf6DHNPdRWB2Q6Z3G9xhEvgm/GbBeYG+bPlVxlQiC n0ZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=YoqR1KPO; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=XNJqJA9X; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=d6Y6ttwj; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=openvpn.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id n51-20020a056a000d7300b006da55c943basi594376pfv.281.2024.01.08.16.49.49 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 08 Jan 2024 16:49:49 -0800 (PST) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=YoqR1KPO; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=XNJqJA9X; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=d6Y6ttwj; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=openvpn.net Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1rN0Ix-0006Iy-0s; Tue, 09 Jan 2024 00:49:19 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1rN0Iv-0006Ir-LR for openvpn-devel@lists.sourceforge.net; Tue, 09 Jan 2024 00:49:17 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Content-Transfer-Encoding:MIME-Version :Message-ID:Reply-To:References:Subject:List-Unsubscribe:List-Id:Cc:To:Date: From:Sender:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help: List-Subscribe:List-Post:List-Owner:List-Archive; bh=M7c8E7cwwLCIIBPhMOlIMl9fVusxPByuzqkC3K4Uyiw=; b=YoqR1KPO1/1PTZK68EUAe9TJrj ms6PAw/fsvWRv7YaoxXSv7VY3ZwfvRCYwEyCIEmv53bn9qDTr3ffpboyjL4SODry8vy4rNcUxZRa3 jzGfgs8riQZ5AoREor88C2c+Gj0upgh6zSsPEIUaA3ZFpE3XR23JZXuGuUYA4xQ6qtM8=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Reply-To: References:Subject:List-Unsubscribe:List-Id:Cc:To:Date:From:Sender:Content-ID :Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To: Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help:List-Subscribe:List-Post: List-Owner:List-Archive; bh=M7c8E7cwwLCIIBPhMOlIMl9fVusxPByuzqkC3K4Uyiw=; b=X NJqJA9XPhptf3/payIhN+KH72XR6WQcWKFZsaC/RNZe/OMegfGenqwrc4fEoTRHZV6O/pY6QT7Z1C j9847/H9jozujMbqDj9eOexLZRLc5jlURWtGnYLl7uqnU3nxo15nVDmfe2og3lsMqH5L7z5PK+6Dw pbrJPNQEpjDsap4s=; Received: from mail-wm1-f47.google.com ([209.85.128.47]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1rN0Im-0000GK-E0 for openvpn-devel@lists.sourceforge.net; Tue, 09 Jan 2024 00:49:17 +0000 Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-40e4d64a431so3324705e9.0 for ; Mon, 08 Jan 2024 16:49:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvpn.net; s=google; t=1704761337; x=1705366137; darn=lists.sourceforge.net; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from:from:to:cc :subject:date:message-id:reply-to; bh=M7c8E7cwwLCIIBPhMOlIMl9fVusxPByuzqkC3K4Uyiw=; b=d6Y6ttwjv/eDlqHRccW+jVfJO6VvmLzGBSO5bcNOri66ZYukpeLpDhWHVbqbOAsOnJ AsuFIxWwI9OleUnc2rV10YuNbuB2jrasbh0/8N6uo4hZWx+GLDEssqZSu6OJrDAKi5EU vy51BtkpPsmx0ma/TaHC90oNTw7Te9RG6DZZhItSgcQ7IcEbppxi/FZddLQtTj4Oows5 RIp+pnIkm1wGQeQcUq3SoseTE8ikQR5JDznLUvJ6xOYDhvL4/aEJEb8BTYP8qCz1r6wY cX9cLcnbAxdI2X2I+z11wbPdITL0h3zCE0KGzHIMEXyvtcbiP7FDsLKZRciRLdC+0rPG i48Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704761337; x=1705366137; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=M7c8E7cwwLCIIBPhMOlIMl9fVusxPByuzqkC3K4Uyiw=; b=rUJnGdMPx3J+2TYCeIYpFc+10Z+fMmakhbGhoZ+rI/c17ML4o6oN8vi2P8eAZVltlA 5ex/WJeiLhwz/sYW1ApPF7FlmoM/lxkIwXFVwwItOVAoI2I3gRTATIIOd1InlKjCICR4 VqWU7F4iWoHaLWDx+W+mrf5nbJSlNhwWFkZiv3fNzyQwcDC6UmTDq9tdWzM38C4uKvY3 eTi5/sTOYbx0eDwRKtuBVZ2IygVznTJl5jrhg0ECNr6grOhNbDG8BDms/9i1wE5dlAaG ldb5vwnuKSBL6Sx1oaN3l9QcLKpHBk2L3Oi5+gsbleTd+7O70p10gtsLLn7cJanfjqAO rXAw== X-Gm-Message-State: AOJu0Yz4qzkj9SOezeCaK04++JTXsnJH+VW79uzTbuiwlJkdRjqB8Sp6 VcRenVoGbQgsgotWJC000u2Wri25zo3HmA== X-Received: by 2002:a05:600c:3d0e:b0:40e:49b6:d1b0 with SMTP id bh14-20020a05600c3d0e00b0040e49b6d1b0mr815690wmb.70.1704761336281; Mon, 08 Jan 2024 16:48:56 -0800 (PST) Received: from gerrit.openvpn.in (ec2-18-159-0-78.eu-central-1.compute.amazonaws.com. [18.159.0.78]) by smtp.gmail.com with ESMTPSA id hg24-20020a05600c539800b0040e38859c47sm1440093wmb.16.2024.01.08.16.48.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jan 2024 16:48:55 -0800 (PST) From: "d12fk (Code Review)" X-Google-Original-From: "d12fk (Code Review)" X-Gerrit-PatchSet: 1 Date: Tue, 9 Jan 2024 00:48:54 +0000 To: plaisthos , flichtenheld Auto-Submitted: auto-generated X-Gerrit-MessageType: newchange X-Gerrit-Change-Id: Ic9bf797bfc7e2d471998a84cb0f071db3e4832ba X-Gerrit-Change-Number: 489 X-Gerrit-Project: openvpn X-Gerrit-ChangeURL: X-Gerrit-Commit: 539ee8bccd943d7da756cfc4e499378b686b5407 References: Message-ID: <2b1c779f10bc36e410aa0fee2c30a78564824cdf-HTML@gerrit.openvpn.net> MIME-Version: 1.0 User-Agent: Gerrit/3.8.2 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.128.47 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.128.47 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 WEIRD_PORT URI: Uses non-standard port number for HTTP 0.0 HTML_MESSAGE BODY: HTML included in message -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid 0.0 T_KAM_HTML_FONT_INVALID Test for Invalidly Named or Formatted Colors in HTML -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1rN0Im-0000GK-E0 Subject: [Openvpn-devel] [L] Change in openvpn[master]: Windows: enforce 'block-local' with WFP filters X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: heiko@openvpn.net, arne-openvpn@rfc2549.org, openvpn-devel@lists.sourceforge.net, frank@lichtenheld.com Cc: openvpn-devel Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1787571879260444780?= X-GMAIL-MSGID: =?utf-8?q?1787571879260444780?= X-getmail-filter-classifier: gerrit message type newchange Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/489?usp=email to review the following change. Change subject: Windows: enforce 'block-local' with WFP filters ...................................................................... Windows: enforce 'block-local' with WFP filters In an attempt to better defend against the TunnelCrack attacks, enforce that no traffic can pass to anything else than the VPN interface when the 'block-local' flags is given with either --redirect-gateway or --redirect-private. Reuse much of the existing --block-outside-dns code, but make it more general, so that it can also block any traffic, not just port 53. Uses the Windows Filtering Platform for enforcement in addition to the routes redirecting the networks into the tunnel. Change-Id: Ic9bf797bfc7e2d471998a84cb0f071db3e4832ba Signed-off-by: Heiko Hund --- M CMakeLists.txt M doc/man-sections/vpn-network-options.rst M include/openvpn-msg.h M src/openvpn/Makefile.am M src/openvpn/init.c M src/openvpn/route.c M src/openvpn/route.h M src/openvpn/tun.c R src/openvpn/wfp_block.c R src/openvpn/wfp_block.h M src/openvpn/win32.c M src/openvpn/win32.h M src/openvpnserv/CMakeLists.txt M src/openvpnserv/Makefile.am M src/openvpnserv/interactive.c 15 files changed, 299 insertions(+), 213 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/89/489/1 diff --git a/CMakeLists.txt b/CMakeLists.txt index bc46c27..e560ef3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -352,8 +352,6 @@ src/openvpn/base64.c src/openvpn/base64.h src/openvpn/basic.h - src/openvpn/block_dns.h - src/openvpn/block_dns.c src/openvpn/buffer.c src/openvpn/buffer.h src/openvpn/circ_list.h @@ -533,6 +531,8 @@ src/openvpn/ssl_util.h src/openvpn/vlan.c src/openvpn/vlan.h + src/openvpn/wfp_block.c + src/openvpn/wfp_block.h src/openvpn/win32.c src/openvpn/win32-util.c src/openvpn/win32.h diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index 41d367b..630e8f5 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -352,6 +352,9 @@ Block access to local LAN when the tunnel is active, except for the LAN gateway itself. This is accomplished by routing the local LAN (except for the LAN gateway address) into the tunnel. + On Windows WFP filters are added in addition to the routes which + block access to resources not routed through the VPN adapter. + Push this flag to defend against the TunnelCrack attacks. :code:`ipv6` Redirect IPv6 routing into the tunnel. This works similar to diff --git a/include/openvpn-msg.h b/include/openvpn-msg.h index a1464cd..0fa0cb5 100644 --- a/include/openvpn-msg.h +++ b/include/openvpn-msg.h @@ -24,6 +24,9 @@ #ifndef OPENVPN_MSG_H_ #define OPENVPN_MSG_H_ +#include +#include + typedef enum { msg_acknowledgement, msg_add_address, @@ -35,8 +38,8 @@ msg_add_nbt_cfg, msg_del_nbt_cfg, msg_flush_neighbors, - msg_add_block_dns, - msg_del_block_dns, + msg_add_wfp_block, + msg_del_wfp_block, msg_register_dns, msg_enable_dhcp, msg_register_ring_buffers, @@ -61,6 +64,11 @@ char name[256]; } interface_t; +typedef enum { + wfp_block_local = 1<<0, + wfp_block_dns = 1<<1 +} wfp_block_flags_t; + typedef struct { message_header_t header; short family; @@ -120,8 +128,9 @@ typedef struct { message_header_t header; + wfp_block_flags_t flags; interface_t iface; -} block_dns_message_t; +} wfp_block_message_t; typedef struct { message_header_t header; diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index b953961..6bf3862 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -156,6 +156,6 @@ $(OPTIONAL_DL_LIBS) \ $(OPTIONAL_INOTIFY_LIBS) if WIN32 -openvpn_SOURCES += openvpn_win32_resources.rc block_dns.c block_dns.h ring_buffer.h +openvpn_SOURCES += openvpn_win32_resources.rc wfp_block.c wfp_block.h ring_buffer.h openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4 -lncrypt -lsetupapi -lbcrypt endif diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 9e2b3845..4108e8c 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1916,12 +1916,15 @@ c->c2.es); #if defined(_WIN32) - if (c->options.block_outside_dns) + /* Fortify 'redirect-gateway block-local' with firewall rules? */ + bool block_local = do_block_local(c->c1.route_list); + + if (c->options.block_outside_dns || block_local) { - dmsg(D_LOW, "Blocking outside DNS"); - if (!win_wfp_block_dns(c->c1.tuntap->adapter_index, c->options.msg_channel)) + BOOL dns_only = !block_local; + if (!win_wfp_block(c->c1.tuntap->adapter_index, c->options.msg_channel, dns_only)) { - msg(M_FATAL, "Blocking DNS failed!"); + msg(M_FATAL, "WFP: blocking failed!"); } } #endif @@ -1965,12 +1968,15 @@ c->c2.es); } #if defined(_WIN32) - if (c->options.block_outside_dns) + /* Fortify 'redirect-gateway block-local' with firewall rules? */ + bool block_local = do_block_local(c->c1.route_list); + + if (c->options.block_outside_dns || block_local) { - dmsg(D_LOW, "Blocking outside DNS"); - if (!win_wfp_block_dns(c->c1.tuntap->adapter_index, c->options.msg_channel)) + BOOL dns_only = !block_local; + if (!win_wfp_block(c->c1.tuntap->adapter_index, c->options.msg_channel, dns_only)) { - msg(M_FATAL, "Blocking DNS failed!"); + msg(M_FATAL, "WFP: blocking failed!"); } } #endif @@ -2093,7 +2099,7 @@ c->c2.es); #if defined(_WIN32) - if (c->options.block_outside_dns) + if (c->options.block_outside_dns || do_block_local(c->c1.route_list)) { if (!win_wfp_uninit(adapter_index, c->options.msg_channel)) { @@ -2132,7 +2138,7 @@ } #if defined(_WIN32) - if (c->options.block_outside_dns) + if (c->options.block_outside_dns || do_block_local(c->c1.route_list)) { if (!win_wfp_uninit(adapter_index, c->options.msg_channel)) { diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 6c027d9..19457ea 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -25,6 +25,7 @@ * Support routines for adding/deleting network routes. */ #include +#include #ifdef HAVE_CONFIG_H #include "config.h" @@ -74,7 +75,13 @@ #endif -static void delete_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx); +static bool add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, + const struct route_gateway_info *rgi, const struct env_set *es, + openvpn_net_ctx_t *ctx); + +static void delete_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, + const struct route_gateway_info *rgi, const struct env_set *es, + openvpn_net_ctx_t *ctx); static void get_bypass_addresses(struct route_bypass *rb, const unsigned int flags); @@ -566,9 +573,7 @@ const struct route_gateway_address *gateway, in_addr_t target) { - const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED); - if ((rl->rgi.flags & rgi_needed) == rgi_needed - && rl->rgi.gateway.netmask < 0xFFFFFFFF) + if (rl->rgi.gateway.netmask < 0xFFFFFFFF) { struct route_ipv4 *r1, *r2; unsigned int l2; @@ -593,39 +598,41 @@ } static void -add_block_local(struct route_list *rl) +add_block_local_routes(struct route_list *rl) { - const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED); - if ((rl->flags & RG_BLOCK_LOCAL) - && (rl->rgi.flags & rgi_needed) == rgi_needed - && (rl->spec.flags & RTSA_REMOTE_ENDPOINT) - && rl->spec.remote_host_local != TLA_LOCAL) - { - size_t i; - #ifndef TARGET_ANDROID - /* add bypass for gateway addr */ - add_bypass_address(&rl->spec.bypass, rl->rgi.gateway.addr); + /* add bypass for gateway addr */ + add_bypass_address(&rl->spec.bypass, rl->rgi.gateway.addr); #endif - /* block access to local subnet */ - add_block_local_item(rl, &rl->rgi.gateway, rl->spec.remote_endpoint); + /* block access to local subnet */ + add_block_local_item(rl, &rl->rgi.gateway, rl->spec.remote_endpoint); - /* process additional subnets on gateway interface */ - for (i = 0; i < rl->rgi.n_addrs; ++i) + /* process additional subnets on gateway interface */ + size_t i; + for (i = 0; i < rl->rgi.n_addrs; ++i) + { + const struct route_gateway_address *gwa = &rl->rgi.addrs[i]; + /* omit the add/subnet in &rl->rgi which we processed above */ + if (!((rl->rgi.gateway.addr & rl->rgi.gateway.netmask) == (gwa->addr & gwa->netmask) + && rl->rgi.gateway.netmask == gwa->netmask)) { - const struct route_gateway_address *gwa = &rl->rgi.addrs[i]; - /* omit the add/subnet in &rl->rgi which we processed above */ - if (!((rl->rgi.gateway.addr & rl->rgi.gateway.netmask) == (gwa->addr & gwa->netmask) - && rl->rgi.gateway.netmask == gwa->netmask)) - { - add_block_local_item(rl, gwa, rl->spec.remote_endpoint); - } + add_block_local_item(rl, gwa, rl->spec.remote_endpoint); } } } bool +do_block_local(const struct route_list *rl) +{ + const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED); + return (rl->flags & RG_BLOCK_LOCAL) + && (rl->rgi.flags & rgi_needed) == rgi_needed + && (rl->spec.flags & RTSA_REMOTE_ENDPOINT) + && rl->spec.remote_host_local != TLA_LOCAL; +} + +bool init_route_list(struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, @@ -698,7 +705,10 @@ if (rl->flags & RG_ENABLE) { - add_block_local(rl); + if (do_block_local(rl)) + { + add_block_local_routes(rl); + } get_bypass_addresses(&rl->spec.bypass, rl->flags); #ifdef ENABLE_DEBUG print_bypass_addresses(&rl->spec.bypass); @@ -1241,6 +1251,7 @@ } rl6->iflags |= RL_ROUTES_ADDED; } + return ret; } diff --git a/src/openvpn/route.h b/src/openvpn/route.h index 71b4cf4..7112936 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -243,6 +243,18 @@ struct iroute_ipv6 *next; }; +/** + * Get the decision whether to block traffic to local networks while the VPN + * is connected. This definatly returns false when not redirecting the gateway + * or when the 'block-local' flag is not set. Also checks for other + * prerequisites to redirect local networks into the tunnel. + * + * @param rl const pointer to the struct route_list to base the decision on. + * + * @return boolean indicating whether local traffic should be blocked. + */ +bool do_block_local(const struct route_list *rl); + struct route_option_list *new_route_option_list(struct gc_arena *a); struct route_ipv6_option_list *new_route_ipv6_option_list(struct gc_arena *a); @@ -263,10 +275,6 @@ void delete_route_ipv6(const struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx); -bool add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, - const struct route_gateway_info *rgi, const struct env_set *es, - openvpn_net_ctx_t *ctx); - void add_route_to_option_list(struct route_option_list *l, const char *network, const char *netmask, diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 8e96149..aa78c23 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -44,7 +44,7 @@ #include "manage.h" #include "route.h" #include "win32.h" -#include "block_dns.h" +#include "wfp_block.h" #include "networking.h" #include "memdbg.h" diff --git a/src/openvpn/block_dns.c b/src/openvpn/wfp_block.c similarity index 70% rename from src/openvpn/block_dns.c rename to src/openvpn/wfp_block.c index 05b2599..f694924 100644 --- a/src/openvpn/block_dns.c +++ b/src/openvpn/wfp_block.c @@ -37,7 +37,8 @@ #include #include #include -#include "block_dns.h" + +#include "wfp_block.h" /* * WFP-related defines and GUIDs not in mingw32 @@ -92,10 +93,19 @@ 0xb7, 0xf3, 0xbd, 0xa5, 0xd3, 0x28, 0x90, 0xa4 ); +/* 632ce23b-5167-435c-86d7-e903684aa80c */ +DEFINE_GUID( + FWPM_CONDITION_FLAGS, + 0x632ce23b, + 0x5167, + 0x435c, + 0x86, 0xd7, 0xe9, 0x03, 0x68, 0x4a, 0xa8, 0x0c + ); + /* UUID of WFP sublayer used by all instances of openvpn * 2f660d7e-6a37-11e6-a181-001e8c6e04a2 */ DEFINE_GUID( - OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER, + OPENVPN_WFP_BLOCK_SUBLAYER, 0x2f660d7e, 0x6a37, 0x11e6, @@ -113,7 +123,7 @@ return; } -#define CHECK_ERROR(err, msg) \ +#define OUT_ON_ERROR(err, msg) \ if (err) { msg_handler(err, msg); goto out; } /* @@ -159,31 +169,36 @@ * OR * (ii) processes with the specified executable path * The firewall filters added here are automatically removed when the process exits or - * on calling delete_block_dns_filters(). + * on calling delete_wfp_block_filters(). * Arguments: * engine_handle : On successful return contains the handle for a newly opened fwp session * in which the filters are added. - * May be closed by passing to delete_block_dns_filters to remove the filters. + * May be closed by passing to delete_wfp_block_filters to remove the filters. * index : The index of adapter for which traffic is permitted. * exe_path : Path of executable for which traffic is permitted. * msg_handler : An optional callback function for error reporting. + * dns_only : Whether the blocking filters should apply for DNS only. * Returns 0 on success, a non-zero status code of the last failed action on failure. */ DWORD -add_block_dns_filters(HANDLE *engine_handle, +add_wfp_block_filters(HANDLE *engine_handle, int index, const WCHAR *exe_path, - block_dns_msg_handler_t msg_handler - ) + wfp_block_msg_handler_t msg_handler, + BOOL dns_only) { FWPM_SESSION0 session = {0}; FWPM_SUBLAYER0 *sublayer_ptr = NULL; - NET_LUID tapluid; + NET_LUID itf_luid; UINT64 filterid; FWP_BYTE_BLOB *openvpnblob = NULL; FWPM_FILTER0 Filter = {0}; - FWPM_FILTER_CONDITION0 Condition[2] = {0}; + FWPM_FILTER_CONDITION0 Condition[2]; + FWPM_FILTER_CONDITION0 match_openvpn = {0}; + FWPM_FILTER_CONDITION0 match_port_53 = {0}; + FWPM_FILTER_CONDITION0 match_interface = {0}; + FWPM_FILTER_CONDITION0 match_not_loopback = {0}; DWORD err = 0; if (!msg_handler) @@ -197,116 +212,127 @@ *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"); + OUT_ON_ERROR(err, "FwpEngineOpen: open fwp session failed"); + msg_handler(0, "WFP Block: WFP engine opened"); /* Check sublayer exists and add one if it does not. */ - if (FwpmSubLayerGetByKey0(*engine_handle, &OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER, &sublayer_ptr) + if (FwpmSubLayerGetByKey0(*engine_handle, &OPENVPN_WFP_BLOCK_SUBLAYER, &sublayer_ptr) == ERROR_SUCCESS) { - msg_handler(0, "Block_DNS: Using existing sublayer"); + msg_handler(0, "WFP Block: 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); + err = add_sublayer(OPENVPN_WFP_BLOCK_SUBLAYER); if (err == FWP_E_ALREADY_EXISTS || err == ERROR_SUCCESS) { - msg_handler(0, "Block_DNS: Added a persistent sublayer with pre-defined UUID"); + msg_handler(0, "WFP Block: Added a persistent sublayer with pre-defined UUID"); } else { - CHECK_ERROR(err, "add_sublayer: failed to add persistent sublayer"); + OUT_ON_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, &itf_luid); + OUT_ON_ERROR(err, "Convert interface index to luid failed"); err = FwpmGetAppIdFromFileName0(exe_path, &openvpnblob); - CHECK_ERROR(err, "Get byte blob for openvpn executable name failed"); + OUT_ON_ERROR(err, "Get byte blob for openvpn executable name failed"); + + /* Prepare match conditions */ + match_openvpn.fieldKey = FWPM_CONDITION_ALE_APP_ID; + match_openvpn.matchType = FWP_MATCH_EQUAL; + match_openvpn.conditionValue.type = FWP_BYTE_BLOB_TYPE; + match_openvpn.conditionValue.byteBlob = openvpnblob; + + match_port_53.fieldKey = FWPM_CONDITION_IP_REMOTE_PORT; + match_port_53.matchType = FWP_MATCH_EQUAL; + match_port_53.conditionValue.type = FWP_UINT16; + match_port_53.conditionValue.uint16 = 53; + + match_interface.fieldKey = FWPM_CONDITION_IP_LOCAL_INTERFACE; + match_interface.matchType = FWP_MATCH_EQUAL; + match_interface.conditionValue.type = FWP_UINT64; + match_interface.conditionValue.uint64 = &itf_luid.Value; + + match_not_loopback.fieldKey = FWPM_CONDITION_FLAGS; + match_not_loopback.matchType = FWP_MATCH_FLAGS_NONE_SET; + match_not_loopback.conditionValue.type = FWP_UINT32; + match_not_loopback.conditionValue.uint32 = FWP_CONDITION_FLAG_IS_LOOPBACK; /* Prepare filter. */ - Filter.subLayerKey = OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER; + Filter.subLayerKey = OPENVPN_WFP_BLOCK_SUBLAYER; Filter.displayData.name = FIREWALL_NAME; Filter.weight.type = FWP_UINT8; Filter.weight.uint8 = 0xF; Filter.filterCondition = Condition; - Filter.numFilterConditions = 2; + Filter.numFilterConditions = 1; - /* First filter. Permit IPv4 DNS queries from OpenVPN itself. */ + /* First filter. Permit IPv4 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; - + Condition[0] = match_openvpn; + if (dns_only) + { + Filter.numFilterConditions = 2; + Condition[1] = match_port_53; + } err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid); - CHECK_ERROR(err, "Add filter to permit IPv4 port 53 traffic from OpenVPN failed"); + OUT_ON_ERROR(err, "Add filter to permit IPv4 traffic from OpenVPN failed"); - /* Second filter. Permit IPv6 DNS queries from OpenVPN itself. */ + /* Second filter. Permit IPv6 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"); + OUT_ON_ERROR(err, "Add filter to permit IPv6 traffic from OpenVPN failed"); - msg_handler(0, "Block_DNS: Added permit filters for exe_path"); + msg_handler(0, "WFP Block: Added permit filters for exe_path"); - /* Third filter. Block all IPv4 DNS queries. */ + /* Third filter. Block IPv4 to port 53 or all besided loopback. */ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4; Filter.action.type = FWP_ACTION_BLOCK; Filter.weight.type = FWP_EMPTY; Filter.numFilterConditions = 1; - + Condition[0] = dns_only ? match_port_53 : match_not_loopback; err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid); - CHECK_ERROR(err, "Add filter to block IPv4 DNS traffic failed"); + OUT_ON_ERROR(err, "Add filter to block IPv4 traffic failed"); - /* Forth filter. Block all IPv6 DNS queries. */ + /* Forth filter. Block IPv6 to port 53 or all besides loopback */ 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"); + OUT_ON_ERROR(err, "Add filter to block IPv6 traffic failed"); - msg_handler(0, "Block_DNS: Added block filters for all interfaces"); + msg_handler(0, "WFP Block: Added block filters for all interfaces"); - /* Fifth filter. Permit IPv4 DNS queries from TAP. + /* Fifth filter. Permit IPv4 for the VPN interface. * 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; - - 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; - + Filter.numFilterConditions = 1; + Condition[0] = match_interface; + if (dns_only) + { + Filter.numFilterConditions = 2; + Condition[1] = match_port_53; + } err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid); - CHECK_ERROR(err, "Add filter to permit IPv4 DNS traffic through TAP failed"); + OUT_ON_ERROR(err, "Add filter to permit IPv4 traffic through VPN interface failed"); - /* Sixth filter. Permit IPv6 DNS queries from TAP. + /* Sixth filter. Permit IPv6 for the VPN interface. * 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"); + OUT_ON_ERROR(err, "Add filter to permit IPv6 traffic through VPN interface failed"); - msg_handler(0, "Block_DNS: Added permit filters for TAP interface"); + msg_handler(0, "WFP Block: Added permit filters for VPN interface"); out: - if (openvpnblob) { FwpmFreeMemory0((void **)&openvpnblob); @@ -322,7 +348,7 @@ } DWORD -delete_block_dns_filters(HANDLE engine_handle) +delete_wfp_block_filters(HANDLE engine_handle) { DWORD err = 0; /* diff --git a/src/openvpn/block_dns.h b/src/openvpn/wfp_block.h similarity index 83% rename from src/openvpn/block_dns.h rename to src/openvpn/wfp_block.h index 89b88d6..60c9171 100644 --- a/src/openvpn/block_dns.h +++ b/src/openvpn/wfp_block.h @@ -23,20 +23,24 @@ #ifdef _WIN32 -#ifndef OPENVPN_BLOCK_DNS_H -#define OPENVPN_BLOCK_DNS_H +#ifndef WFP_BLOCK_H +#define WFP_BLOCK_H + +#include +#include +#include /* Any value less than 5 should work fine. 3 is chosen without any real reason. */ -#define BLOCK_DNS_IFACE_METRIC 3 +#define WFP_BLOCK_IFACE_METRIC 3 -typedef void (*block_dns_msg_handler_t) (DWORD err, const char *msg); +typedef void (*wfp_block_msg_handler_t) (DWORD err, const char *msg); DWORD -delete_block_dns_filters(HANDLE engine); +delete_wfp_block_filters(HANDLE engine); DWORD -add_block_dns_filters(HANDLE *engine, int iface_index, const WCHAR *exe_path, - block_dns_msg_handler_t msg_handler_callback); +add_wfp_block_filters(HANDLE *engine, int iface_index, const WCHAR *exe_path, + wfp_block_msg_handler_t msg_handler_callback, BOOL dns_only); /** * Return interface metric value for the specified interface index. @@ -65,5 +69,5 @@ set_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family, const ULONG metric); -#endif /* ifndef OPENVPN_BLOCK_DNS_H */ +#endif /* ifndef WFP_BLOCK_H */ #endif /* ifdef _WIN32 */ diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index 6b7ba5e..9d08554 100644 --- a/src/openvpn/win32.c +++ b/src/openvpn/win32.c @@ -34,6 +34,9 @@ #ifdef _WIN32 +#include +#include + #include "buffer.h" #include "error.h" #include "mtu.h" @@ -47,7 +50,7 @@ #include -#include "block_dns.h" +#include "wfp_block.h" /* * WFP handle @@ -1138,43 +1141,19 @@ } static bool -win_block_dns_service(bool add, int index, const HANDLE pipe) +win_get_exe_path(PWCHAR path, DWORD size) { - bool ret = false; - ack_message_t ack; - struct gc_arena gc = gc_new(); - - 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 = "" } - }; - - if (!send_msg_iservice(pipe, &data, sizeof(data), &ack, "Block_DNS")) + DWORD status = GetModuleFileNameW(NULL, path, size); + if (status == 0 || status == size) { - goto out; + msg(M_WARN|M_ERRNO, "cannot get executable path"); + return false; } - - if (ack.error_number != NO_ERROR) - { - 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; - } - - ret = true; - msg(M_INFO, "%s outside dns using service succeeded.", (add ? "Blocking" : "Unblocking")); -out: - gc_free(&gc); - return ret; + return true; } static void -block_dns_msg_handler(DWORD err, const char *msg) +win_wfp_msg_handler(DWORD err, const char *msg) { struct gc_arena gc = gc_new(); @@ -1184,15 +1163,52 @@ } else { - msg(M_WARN, "Error in add_block_dns_filters(): %s : %s [status=0x%lx]", + msg(M_WARN, "Error in WFP: %s : %s [status=0x%lx]", msg, strerror_win32(err, &gc), err); } gc_free(&gc); } +static bool +win_wfp_block_service(bool add, bool dns_only, int index, const HANDLE pipe) +{ + bool ret = false; + ack_message_t ack; + struct gc_arena gc = gc_new(); + + wfp_block_message_t data = { + .header = { + (add ? msg_add_wfp_block : msg_del_wfp_block), + sizeof(wfp_block_message_t), + 0 + }, + .flags = dns_only ? wfp_block_dns : wfp_block_local, + .iface = { .index = index, .name = "" } + }; + + if (!send_msg_iservice(pipe, &data, sizeof(data), &ack, "WFP block")) + { + goto out; + } + + if (ack.error_number != NO_ERROR) + { + msg(M_WARN, "WFP block: %s block 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; + } + + ret = true; + msg(M_INFO, "%s WFP block filters using service succeeded.", (add ? "Adding" : "Deleting")); +out: + gc_free(&gc); + return ret; +} + bool -win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel) +win_wfp_block(const NET_IFINDEX index, const HANDLE msg_channel, BOOL dns_only) { WCHAR openvpnpath[MAX_PATH]; bool ret = false; @@ -1200,20 +1216,19 @@ if (msg_channel) { - dmsg(D_LOW, "Using service to add block dns filters"); - ret = win_block_dns_service(true, index, msg_channel); + dmsg(D_LOW, "Using service to add WFP block filters"); + ret = win_wfp_block_service(true, dns_only, index, msg_channel); goto out; } - status = GetModuleFileNameW(NULL, openvpnpath, _countof(openvpnpath)); - if (status == 0 || status == _countof(openvpnpath)) + ret = win_get_exe_path(openvpnpath, _countof(openvpnpath)); + if (ret == false) { - msg(M_WARN|M_ERRNO, "block_dns: cannot get executable path"); goto out; } - status = add_block_dns_filters(&m_hEngineHandle, index, openvpnpath, - block_dns_msg_handler); + status = add_wfp_block_filters(&m_hEngineHandle, index, openvpnpath, + win_wfp_msg_handler, dns_only); if (status == 0) { int is_auto = 0; @@ -1227,10 +1242,10 @@ { tap_metric_v6 = 0; } - status = set_interface_metric(index, AF_INET, BLOCK_DNS_IFACE_METRIC); + status = set_interface_metric(index, AF_INET, WFP_BLOCK_IFACE_METRIC); if (!status) { - set_interface_metric(index, AF_INET6, BLOCK_DNS_IFACE_METRIC); + set_interface_metric(index, AF_INET6, WFP_BLOCK_IFACE_METRIC); } } @@ -1248,12 +1263,12 @@ if (msg_channel) { - msg(D_LOW, "Using service to delete block dns filters"); - win_block_dns_service(false, index, msg_channel); + msg(D_LOW, "Using service to delete WFP block filters"); + win_wfp_block_service(false, false, index, msg_channel); } else { - delete_block_dns_filters(m_hEngineHandle); + delete_wfp_block_filters(m_hEngineHandle); m_hEngineHandle = NULL; if (tap_metric_v4 >= 0) { diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h index aa8513b..92b3528 100644 --- a/src/openvpn/win32.h +++ b/src/openvpn/win32.h @@ -25,8 +25,10 @@ #ifndef OPENVPN_WIN32_H #define OPENVPN_WIN32_H -#include +#include +#include +#include "syshead.h" #include "mtu.h" #include "openvpn-msg.h" #include "argv.h" @@ -286,7 +288,7 @@ /* call self in a subprocess */ void fork_to_self(const char *cmdline); -bool win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel); +bool win_wfp_block(const NET_IFINDEX index, const HANDLE msg_channel, BOOL dns_only); bool win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel); diff --git a/src/openvpnserv/CMakeLists.txt b/src/openvpnserv/CMakeLists.txt index 17cd90c..154e17c 100644 --- a/src/openvpnserv/CMakeLists.txt +++ b/src/openvpnserv/CMakeLists.txt @@ -17,7 +17,7 @@ interactive.c service.c service.h validate.c validate.h - ../openvpn/block_dns.c ../openvpn/block_dns.h + ../openvpn/wfp_block.c ../openvpn/wfp_block.h openvpnserv_resources.rc ../openvpn/ring_buffer.h ) diff --git a/src/openvpnserv/Makefile.am b/src/openvpnserv/Makefile.am index d8ba4eb..49ad8aa 100644 --- a/src/openvpnserv/Makefile.am +++ b/src/openvpnserv/Makefile.am @@ -33,6 +33,6 @@ interactive.c \ service.c service.h \ validate.c validate.h \ - $(top_srcdir)/src/openvpn/block_dns.c $(top_srcdir)/src/openvpn/block_dns.h \ + $(top_srcdir)/src/openvpn/wfp_block.c $(top_srcdir)/src/openvpn/wfp_block.h \ openvpnserv_resources.rc \ $(top_srcdir)/src/openvpn/ring_buffer.h diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c index 32c8996..68a8106 100644 --- a/src/openvpnserv/interactive.c +++ b/src/openvpnserv/interactive.c @@ -38,7 +38,7 @@ #include "openvpn-msg.h" #include "validate.h" -#include "block_dns.h" +#include "wfp_block.h" #include "ring_buffer.h" #define IO_TIMEOUT 2000 /*ms*/ @@ -84,7 +84,7 @@ typedef enum { address, route, - block_dns, + wfp_block, undo_dns4, undo_dns6, undo_domain, @@ -99,7 +99,7 @@ int index; int metric_v4; int metric_v6; -} block_dns_data_t; +} wfp_block_data_t; typedef struct { struct tun_ring *send_ring; @@ -774,74 +774,76 @@ } static DWORD -DeleteBlockDNS(const block_dns_message_t *msg, undo_lists_t *lists) +DeleteWfpBlock(const wfp_block_message_t *msg, undo_lists_t *lists) { DWORD err = 0; - block_dns_data_t *interface_data = RemoveListItem(&(*lists)[block_dns], CmpAny, NULL); + wfp_block_data_t *block_data = RemoveListItem(&(*lists)[wfp_block], CmpAny, NULL); - if (interface_data) + if (block_data) { - err = delete_block_dns_filters(interface_data->engine); - if (interface_data->metric_v4 >= 0) + err = delete_wfp_block_filters(block_data->engine); + if (block_data->metric_v4 >= 0) { set_interface_metric(msg->iface.index, AF_INET, - interface_data->metric_v4); + block_data->metric_v4); } - if (interface_data->metric_v6 >= 0) + if (block_data->metric_v6 >= 0) { set_interface_metric(msg->iface.index, AF_INET6, - interface_data->metric_v6); + block_data->metric_v6); } - free(interface_data); + free(block_data); } else { - MsgToEventLog(M_ERR, TEXT("No previous block DNS filters to delete")); + MsgToEventLog(M_ERR, TEXT("No previous block filters to delete")); } return err; } static DWORD -AddBlockDNS(const block_dns_message_t *msg, undo_lists_t *lists) +AddWfpBlock(const wfp_block_message_t *msg, undo_lists_t *lists) { DWORD err = 0; - block_dns_data_t *interface_data = NULL; + wfp_block_data_t *block_data = NULL; HANDLE engine = NULL; LPCWSTR exe_path; + BOOL dns_only; exe_path = settings.exe_path; + dns_only = (msg->flags == wfp_block_dns); - err = add_block_dns_filters(&engine, msg->iface.index, exe_path, BlockDNSErrHandler); + err = add_wfp_block_filters(&engine, msg->iface.index, exe_path, BlockDNSErrHandler, dns_only); if (!err) { - interface_data = malloc(sizeof(block_dns_data_t)); - if (!interface_data) + block_data = malloc(sizeof(wfp_block_data_t)); + if (!block_data) { err = ERROR_OUTOFMEMORY; goto out; } - interface_data->engine = engine; - interface_data->index = msg->iface.index; + block_data->engine = engine; + block_data->index = msg->iface.index; int is_auto = 0; - interface_data->metric_v4 = get_interface_metric(msg->iface.index, - AF_INET, &is_auto); + block_data->metric_v4 = get_interface_metric(msg->iface.index, + AF_INET, &is_auto); if (is_auto) { - interface_data->metric_v4 = 0; + block_data->metric_v4 = 0; } - interface_data->metric_v6 = get_interface_metric(msg->iface.index, - AF_INET6, &is_auto); + block_data->metric_v6 = get_interface_metric(msg->iface.index, + AF_INET6, &is_auto); if (is_auto) { - interface_data->metric_v6 = 0; + block_data->metric_v6 = 0; } - err = AddListItem(&(*lists)[block_dns], interface_data); + err = AddListItem(&(*lists)[wfp_block], block_data); if (!err) { err = set_interface_metric(msg->iface.index, AF_INET, - BLOCK_DNS_IFACE_METRIC); + WFP_BLOCK_IFACE_METRIC); if (!err) { /* for IPv6, we intentionally ignore errors, because @@ -850,12 +852,12 @@ * (if OpenVPN wants IPv6 ifconfig, we'll fail there) */ set_interface_metric(msg->iface.index, AF_INET6, - BLOCK_DNS_IFACE_METRIC); + WFP_BLOCK_IFACE_METRIC); } if (err) { /* delete the filters, remove undo item and free interface data */ - DeleteBlockDNS(msg, lists); + DeleteWfpBlock(msg, lists); engine = NULL; } } @@ -864,23 +866,23 @@ out: if (err && engine) { - delete_block_dns_filters(engine); - free(interface_data); + delete_wfp_block_filters(engine); + free(block_data); } return err; } static DWORD -HandleBlockDNSMessage(const block_dns_message_t *msg, undo_lists_t *lists) +HandleWfpBlockMessage(const wfp_block_message_t *msg, undo_lists_t *lists) { - if (msg->header.type == msg_add_block_dns) + if (msg->header.type == msg_add_wfp_block) { - return AddBlockDNS(msg, lists); + return AddWfpBlock(msg, lists); } else { - return DeleteBlockDNS(msg, lists); + return DeleteWfpBlock(msg, lists); } } @@ -1616,7 +1618,7 @@ address_message_t address; route_message_t route; flush_neighbors_message_t flush_neighbors; - block_dns_message_t block_dns; + wfp_block_message_t wfp_block; dns_cfg_message_t dns; enable_dhcp_message_t dhcp; register_ring_buffers_message_t rrb; @@ -1665,11 +1667,11 @@ } break; - case msg_add_block_dns: - case msg_del_block_dns: - if (msg.header.size == sizeof(msg.block_dns)) + case msg_add_wfp_block: + case msg_del_wfp_block: + if (msg.header.size == sizeof(msg.wfp_block)) { - ack.error_number = HandleBlockDNSMessage(&msg.block_dns, lists); + ack.error_number = HandleWfpBlockMessage(&msg.wfp_block, lists); } break; @@ -1723,7 +1725,7 @@ Undo(undo_lists_t *lists) { undo_type_t type; - block_dns_data_t *interface_data; + wfp_block_data_t *interface_data; for (type = 0; type < _undo_type_max; type++) { list_item_t **pnext = &(*lists)[type]; @@ -1756,9 +1758,9 @@ SetDNSDomain(item->data, "", NULL); break; - case block_dns: - interface_data = (block_dns_data_t *)(item->data); - delete_block_dns_filters(interface_data->engine); + case wfp_block: + interface_data = (wfp_block_data_t *)(item->data); + delete_wfp_block_filters(interface_data->engine); if (interface_data->metric_v4 >= 0) { set_interface_metric(interface_data->index, AF_INET,