[Openvpn-devel] [PATCH] Make ValdikSS's DNS leak fix platform agnostic

2015-12-10 Thread Fish Wang
Based on release/2.3 branch and ValdikSS's v9 patch, this patch is
cross-compiled on Linux and tested on Windows XP/10. The VC project
file is left untouched - you might want to add rpcrt4.lib to compile
and link it under MSVC.

Take ValdikSS's patch for "block-outside-dns" option and
make it Windows-version-agnostic.
---
 src/openvpn/Makefile.am |   2 +-
 src/openvpn/init.c  |   4 -
 src/openvpn/options.c   |  17 +--
 src/openvpn/win32.c | 309 +++-
 src/openvpn/win32.h |   1 +
 5 files changed, 315 insertions(+), 18 deletions(-)

diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 2e602f1..149a533 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -123,5 +123,5 @@ openvpn_LDADD = \
  $(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi
-lrpcrt4 -lwinmm
 endif
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index e8a96c2..960535d 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -1468,14 +1468,12 @@ do_open_tun (struct context *c)
  "up",
  c->c2.es);

-#if _WIN32_WINNT >= 0x0600
   if (c->options.block_outside_dns)
   {
 dmsg (D_LOW, "Blocking outside DNS");
 if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
 msg (M_FATAL, "Blocking DNS failed!");
   }
-#endif

   /* possibly add routes */
   if (!c->options.route_delay_defined)
@@ -1603,13 +1601,11 @@ do_close_tun (struct context *c, bool force)
  "down",
  c->c2.es);

-#if _WIN32_WINNT >= 0x0600
 if (c->options.block_outside_dns)
 {
 if (!win_wfp_uninit())
 msg (M_FATAL, "Uninitialising WFP failed!");
 }
-#endif

/* actually close tun/tap device based on --down-pre flag */
if (c->options.down_pre)
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 3a6aacd..d675390 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -715,9 +715,7 @@ static const char usage_message[] =
   "   optional parameter controls the initial
state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table
and net adapter list\n"
   "  after TAP adapter is up and routes have been added.\n"
-#if _WIN32_WINNT >= 0x0600
   "--block-outside-dns   : Block DNS on other network adapters to
prevent DNS leaks\n"
-#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -1682,9 +1680,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
-#if _WIN32_WINNT >= 0x0600
   SHOW_BOOL (block_outside_dns);
-#endif
   show_tuntap_options (>tuntap_options);
 #endif
 #endif
@@ -6252,13 +6248,20 @@ add_option (struct options *options,
   VERIFY_PERMISSION (OPT_P_IPWIN32);
   options->tuntap_options.register_dns = true;
 }
-#if _WIN32_WINNT >= 0x0600
   else if (streq (p[0], "block-outside-dns") && !p[1])
 {
   VERIFY_PERMISSION (OPT_P_IPWIN32);
-  options->block_outside_dns = true;
+  if (win_wfp_init_funcs())
+  {
+options->block_outside_dns = true;
+  }
+  else
+  {
+msg (msglevel, "Failed to enable --block-outside-dns. "
+   "Maybe WFP is not supported on your system?");
+   goto err;
+  }
 }
-#endif
   else if (streq (p[0], "rdns-internal"))
  /* standalone method for internal use
   *
diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c
index 9402361..f4d0433 100644
--- a/src/openvpn/win32.c
+++ b/src/openvpn/win32.c
@@ -49,11 +49,10 @@
 /*
  * WFP-related defines and GUIDs.
  */
-#if _WIN32_WINNT >= 0x0600
-#include 
 #include 
-#include 
 #include 
+#include 
+#include 

 #ifndef FWPM_SESSION_FLAG_DYNAMIC
 #define FWPM_SESSION_FLAG_DYNAMIC 0x0001
@@ -104,6 +103,264 @@ DEFINE_GUID(
0xb7, 0xf3, 0xbd, 0xa5, 0xd3, 0x28, 0x90, 0xa4
 );

+/* From fwptypes.h */
+
+#define FWP_ACTION_FLAG_TERMINATING (0x1000)
+#define FWP_ACTION_FLAG_NON_TERMINATING (0x2000)
+
+#define FWP_ACTION_BLOCK  (0x1 | FWP_ACTION_FLAG_TERMINATING)
+#define FWP_ACTION_PERMIT (0x2 | FWP_ACTION_FLAG_TERMINATING)
+
+typedef UINT32 FWP_ACTION_TYPE;
+
+typedef enum FWP_DATA_TYPE_ {
+FWP_EMPTY = 0,
+FWP_UINT8 = 1,
+FWP_UINT16 = 2,
+FWP_UINT32 = 3,
+FWP_UINT64 = 4,
+FWP_INT8 = 5,
+FWP_INT16 = 6,
+FWP_INT32 = 7,
+FWP_INT64 = 8,
+FWP_FLOAT = 9,
+FWP_DOUBLE = 10,
+FWP_BYTE_ARRAY16_TYPE = 11,
+FWP_BYTE_BLOB_TYPE = 12,
+FWP_SID = 13,
+FWP_SECURITY_DESCRIPTOR_TYPE = 14,
+FWP_TOKEN_INFORMATION_TYPE = 15,
+FWP_TOKEN_ACCESS_INFORMATION_TYPE = 16,
+FWP_UNICODE_STRING_TYPE = 17,
+FWP_BYTE_ARRAY6_TYPE = 18,
+

Re: [Openvpn-devel] [PATCH] Make ValdikSS's DNS leak fix platform agnostic

2015-12-10 Thread Fish Wang
Hi Gert,

A new patch will follow.

Best,
Fish

-Original Message-
From: Gert Doering [mailto:g...@greenie.muc.de] 
Sent: Thursday, December 10, 2015 12:56 AM
To: Fish Wang 
Cc: openvpn-devel ; i...@valdikss.org.ru
Subject: Re: [Openvpn-devel] [PATCH] Make ValdikSS's DNS leak fix platform
agnostic

Hi,

On Wed, Dec 09, 2015 at 05:30:14PM -0800, Fish Wang wrote:
> Based on release/2.3 branch, this patch is cross-compiled in MinGW and
> tested on Windows XP/10. The VC project file is left untouched - you might
> want to add rpcrt4.lib to compile and link it under MSVC.
> 
> Also, I didn't figure out how to keep ValdikSS's authorship of his code in
> the patch (sorry :-( ). Definitely no expert in git... Maybe I should
> generate a patch on top of his latest patch?

The latter is much better.  Use git release/2.3, apply ValdikSS' v8 patch on

top of that, and then do your changes - that way, proper author attribution
is there, and we can see much easier what you changed.  Right now this is
a long piece of code that differs only in a vew lines from "one of the
8 different patch versions from ValdikSS".  Hard to review.

thanks,

gert

-- 
USENET is *not* the non-clickable part of WWW!

//www.muc.de/~gert/
Gert Doering - Munich, Germany
g...@greenie.muc.de
fax: +49-89-35655025
g...@net.informatik.tu-muenchen.de




Re: [Openvpn-devel] [PATCH v8-master] Add Windows DNS Leak fix using WFP ('block-outside-dns')

2015-12-10 Thread Selva Nair
Hi,

On Thu, Dec 10, 2015 at 3:18 PM, ValdikSS  wrote:

> Use dynamic sessions.
>
> Many applications add filtering policy objects at start, and then delete
> these objects at stop. By using a dynamic session, you guarantee that these
> objects are deleted even if the application crashes. Furthermore, simply
> closing the engine handle at stop is more efficient than making individual
> calls to delete each object.
>
> Going by that just closing the engine appears good enough. I never tested
really changing the tapluid between a SIGHUP restart (how to trigger that)
to know whether any old filters hang around after a  _uninit. Anyway, those
are very unlikely cases and we cant guarad against everything up front.

I would say go for v9 with a simple closing of the engine.

Thanks,

Selva


Re: [Openvpn-devel] [PATCH v8-master] Add Windows DNS Leak fix using WFP ('block-outside-dns')

2015-12-10 Thread ValdikSS
I'm not totally sure about that, but I suppose it shouldn't leak.
Here's what Microsoft's Best Practice says:
> Use dynamic sessions.
>
> Many applications add filtering policy objects at start, and then delete 
> these objects at stop. By using a dynamic session, you guarantee that these 
> objects
> are deleted even if the application crashes. Furthermore, simply closing the 
> engine handle at stop is more efficient than making individual calls to delete
> each object.
>
https://msdn.microsoft.com/en-us/library/windows/desktop/bb442411%28v=vs.85%29.aspx

> If /session/.*flags* is set to *FWPM_SESSION_FLAG_DYNAMIC*, any WFP objects 
> added during the session are automatically deleted when the session ends. If 
> the
> session is not dynamic, the caller needs to explicitly delete all WFP objects 
> added during the session.
https://technet.microsoft.com/ru-ru/aa364040


On 12/10/2015 08:17 PM, Selva Nair wrote:
>
> On Thu, Dec 10, 2015 at 11:49 AM, ValdikSS  > wrote:
>
> Provided it doesn't leak memory. As the current implementation of 
> wfp_add_filter does return the id of the added filter (in ) , its 
> easy to save them
> into some globals and delete all the filters in wfp_uninit.
>
> However, If you are sure there is no leak, just closing the engine is fine.
>
> Other than this v8 is good to go.
>
> Selva
>
>
> --
>
>
> ___
> Openvpn-devel mailing list
> Openvpn-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openvpn-devel



signature.asc
Description: OpenPGP digital signature


Re: [Openvpn-devel] [PATCH v8-master] Add Windows DNS Leak fix using WFP ('block-outside-dns')

2015-12-10 Thread Selva Nair
On Thu, Dec 10, 2015 at 11:49 AM, ValdikSS  wrote:

> It's a very minor actually, FwpmSubLayerDeleteByKey0 is indeed fails every
> time but it doesn't break anything since we close the engine right after.
> Lev suggested to use a correct way with making a filter GUID and deleting
> it before deleting sublayer, but I'd better go with just closing the engine
> without deleting everything. I don't see any drawbacks, that should be
> perfectly OK for a dynamic session.


Provided it doesn't leak memory. As the current implementation of
wfp_add_filter does return the id of the added filter (in ) , its
easy to save them into some globals and delete all the filters in
wfp_uninit.

However, If you are sure there is no leak, just closing the engine is fine.

Other than this v8 is good to go.

Selva


[Openvpn-devel] [PATCH] Improve stdin prompting section, fixing CR prompting.

2015-12-10 Thread Wayne Davison
---
 src/openvpn/misc.c | 119 +
 1 file changed, 57 insertions(+), 62 deletions(-)

diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index bc411bf..83e10f7 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -1132,74 +1132,69 @@ get_user_pass_cr (struct user_pass *up,
   password_from_stdin = true;
 }

-  /*
-   * Get username/password from standard input?
-   */
-  if (username_from_stdin || password_from_stdin)
-   {
 #ifdef ENABLE_CLIENT_CR
- if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
-   {
- struct auth_challenge_info *ac = get_auth_challenge 
(auth_challenge, );
- if (ac)
-   {
- char *response = (char *) gc_malloc (USER_PASS_LEN, false, 
);
- struct buffer packed_resp;
-
- buf_set_write (_resp, (uint8_t*)up->password, 
USER_PASS_LEN);
- msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", ac->challenge_text);
- if (!get_console_input ("Response:", 
BOOL_CAST(ac->flags_ECHO), response, USER_PASS_LEN))
-   msg (M_FATAL, "ERROR: could not read challenge response 
from stdin");
- strncpynt (up->username, ac->user, USER_PASS_LEN);
- buf_printf (_resp, "CRV1::%s::%s", ac->state_id, 
response);
-   }
- else
-   {
- msg (M_FATAL, "ERROR: received malformed challenge request 
from server");
-   }
-   }
- else
+  if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
+{
+  struct auth_challenge_info *ac = get_auth_challenge (auth_challenge, 
);
+  if (ac)
+{
+  char *response = (char *) gc_malloc (USER_PASS_LEN, false, );
+  struct buffer packed_resp;
+
+  buf_set_write (_resp, (uint8_t*)up->password, 
USER_PASS_LEN);
+  msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", ac->challenge_text);
+  if (!get_console_input ("Response:", 
BOOL_CAST(ac->flags_ECHO), response, USER_PASS_LEN))
+msg (M_FATAL, "ERROR: could not read challenge response from 
stdin");
+  strncpynt (up->username, ac->user, USER_PASS_LEN);
+  buf_printf (_resp, "CRV1::%s::%s", ac->state_id, 
response);
+}
+  else
+{
+  msg (M_FATAL, "ERROR: received malformed challenge request from 
server");
+}
+}
+  else
 #endif
-   {
- struct buffer user_prompt = alloc_buf_gc (128, );
- struct buffer pass_prompt = alloc_buf_gc (128, );
-
- buf_printf (_prompt, "Enter %s Username:", prefix);
- buf_printf (_prompt, "Enter %s Password:", prefix);
-
- if (username_from_stdin && !(flags & GET_USER_PASS_PASSWORD_ONLY))
-   {
- if (!get_console_input (BSTR (_prompt), true, 
up->username, USER_PASS_LEN))
-   msg (M_FATAL, "ERROR: could not read %s username from 
stdin", prefix);
- if (strlen (up->username) == 0)
-   msg (M_FATAL, "ERROR: %s username is empty", prefix);
-   }
+{
+  if (username_from_stdin && !(flags & GET_USER_PASS_PASSWORD_ONLY))
+{
+  struct buffer user_prompt = alloc_buf_gc (128, );
+  buf_printf (_prompt, "Enter %s Username:", prefix);
+  if (!get_console_input (BSTR (_prompt), true, up->username, 
USER_PASS_LEN))
+msg (M_FATAL, "ERROR: could not read %s username from stdin", 
prefix);
+  if (strlen (up->username) == 0)
+msg (M_FATAL, "ERROR: %s username is empty", prefix);
+}

- if (password_from_stdin && !get_console_input (BSTR 
(_prompt), false, up->password, USER_PASS_LEN))
-   msg (M_FATAL, "ERROR: could not not read %s password from 
stdin", prefix);
+  if (password_from_stdin)
+{
+  struct buffer pass_prompt = alloc_buf_gc (128, );
+  buf_printf (_prompt, "Enter %s Password:", prefix);
+  if (!get_console_input (BSTR (_prompt), false, 
up->password, USER_PASS_LEN))
+msg (M_FATAL, "ERROR: could not not read %s password from 
stdin", prefix);
+}

 #ifdef ENABLE_CLIENT_CR
- if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE))
-   {
- char *response = (char *) gc_malloc (USER_PASS_LEN, false, 
);
- struct buffer packed_resp;
- char *pw64=NULL, *resp64=NULL;
-
- msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", auth_challenge);
- if (!get_console_input ("Response:", BOOL_CAST(flags & 
GET_USER_PASS_STATIC_CHALLENGE_ECHO), response, USER_PASS_LEN))
-   msg (M_FATAL, "ERROR: 

Re: [Openvpn-devel] [PATCH 1/2] Fix CR prompt with --auth-user-pass & support reading response.

2015-12-10 Thread Wayne Davison
On Thu, Dec 10, 2015 at 8:28 AM, Arne Schwabe  wrote:

> The scenario read the password from file and then ask the password per
> console seems a bit strange.
>

You mean read the password from a file and then ask for the CR from the
console.  If someone combines a server that issues a challenge with the
"--auth-user-pass FILE" option, neither dynamic nor static CR prompts ever
happen, and auth always fails.  This is because those CR sections are
inside the block that is only entered if username_from_stdin ||
password_from_stdin is true, and they are false when a file supplies the
values.  I'll post a patch that separates out just this fix and make it on
the change that moves the isatty() checks out of misc.c.  It is also
improved a bit from my prior patch set in that it moves the user_prompt and
pass_prompt vars into code blocks where they are used (so they don't get
set when they aren't needed).

..wayne..


Re: [Openvpn-devel] [PATCH v8-master] Add Windows DNS Leak fix using WFP ('block-outside-dns')

2015-12-10 Thread ValdikSS
No, I'm afraid it would fail by default  since DNS queries are (usually) made 
from svchost.exe. Whitelisting openvpn.exe is done to not to break OpenVPN on 
UDP
port 53. I could be incorrect tho.

On 12/10/2015 07:31 PM, Selva Nair wrote:
>
> On Thu, Dec 10, 2015 at 11:24 AM, ValdikSS  > wrote:
>
> Yes, I meant to leave the block all and permit openvpn.exe filters always on 
> and delete/re-add only the filters for the tun/tap interface. Well, its 
> probably
> just a cosmetic change, so no strong opinion.
>
> Selva
>
> ___
> Openvpn-devel mailing list
> Openvpn-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openvpn-devel



signature.asc
Description: OpenPGP digital signature


Re: [Openvpn-devel] Kickstarter campaign for auditing and improving security software, including OpenVPN

2015-12-10 Thread Samuli Seppänen



Hi,

Just to be on record, I managed to get in touch with ostif and got a
response.

Is this OSTIF a really serious organization?

I ask this because no contact addresses on their webpage though they
solicit donation. Email to webmas...@ostif.org
 bounces (no such user) etc. etc.. Many
pages on their website most often return something like "limited
access because max request exceeded by crawlers or humans".


It was caused by a misconfiguration of their cloudfare hosting setup.
I'm sorry if my post made anyone doubt their intentions. Derek from
ostif says he may be contacted at derek _AT_ ostif.org
 if any one here has queries about this project.

Selva


Hi,

I've talked with Derek quite a bit and don't have any reason to distrust 
him or OSTIF.org in general. They seem to be committed to the goals they 
state on the their website.


--
Samuli Seppänen
Community Manager
OpenVPN Technologies, Inc

irc freenode net: mattock



[Openvpn-devel] [PATCH applied] Re: Detect config lines that are too long and give a warning/error

2015-12-10 Thread Gert Doering
ACK.  Thanks.

Your patch has been applied to the master and release/2.3 branch.

commit 4baec3ee10b8d6826d5f076a9832a92a5cfe3676 (master)
commit 305c16c28d0ce7bc48c6e0abb18653241ddb910b (release/2.3)

Author: Arne Schwabe
List-Post: openvpn-devel@lists.sourceforge.net
Date:   Thu Dec 10 13:37:10 2015 +0100

 Detect config lines that are too long and give a warning/error

 Acked-by: Gert Doering 
 Message-Id: <1449751030-10703-1-git-send-email-a...@rfc2549.org>
 URL: http://article.gmane.org/gmane.network.openvpn.devel/10723
 Signed-off-by: Gert Doering 


--
kind regards,

Gert Doering




Re: [Openvpn-devel] [PATCH] Fix isatty() check for good.

2015-12-10 Thread Selva Nair
On Thu, Dec 10, 2015 at 9:42 AM, Selva Nair  wrote:

> I vaguely recall askpass behaves differently on linux than, say, bsd, so
> even if reading from a pipe (when no controlling tty) is possible, it may
> not always work. Will test it some other time..
>

Meant to say "getpass" not "askpass"

Selva


Re: [Openvpn-devel] [PATCH 1/2] Fix CR prompt with --auth-user-pass & support reading response.

2015-12-10 Thread Arne Schwabe


Am 08.12.15 um 19:28 schrieb Wayne Davison:
> Fixes a bug where there is no prompt for a dynamic (or static) challenge
> response when combining "--auth-retry interact" (or --static-challenge)
> with --auth-user-pass and the password is read from the file. It also
> extends the reading from the file to allow a response to be provided on
> the line after the password (which is nice for "push", "phone", etc.).
>
> NOTE: indentation left too deep on one big section so that changes are
> clearly seen.
Could you describe the scenario this patch fixes? The dynamic and static
challenge protocol are enabled if also the management interface is enabled.

The scenario read the password from file and then ask the password per
console seems a bit strange.

Arne



Re: [Openvpn-devel] [PATCH v8-master] Add Windows DNS Leak fix using WFP ('block-outside-dns')

2015-12-10 Thread Gert Doering
Hi,

On Thu, Dec 10, 2015 at 11:55:16AM +0200, Lev Stipakov wrote:
> Sorry for the late response.
[..]
> FwpmSubLayerDeleteByKey0 will likely fail if there is a filter 
> associated with sublayer. On the other side, FwpmEngineClose0 seems to 
> be enough to remove blocking.

So, is this something that needs to be fixed before we release 2.3.9, or
can it wait for improvement later on?

I just agreed with Samuli that we are going to release 2.3.9 on Monday,
and this should go in - so either I get a v9 "with nice and shiny" until
Sunday, or someone tells me "v8 is good enough, go for it"...

Thanks :-)

gert
-- 
USENET is *not* the non-clickable part of WWW!
   //www.muc.de/~gert/
Gert Doering - Munich, Germany g...@greenie.muc.de
fax: +49-89-35655025g...@net.informatik.tu-muenchen.de


signature.asc
Description: PGP signature


Re: [Openvpn-devel] [PATCH v8-master] Add Windows DNS Leak fix using WFP ('block-outside-dns')

2015-12-10 Thread ValdikSS
That would break name resolver on reconnection if remote is a hostname.

On 12/10/2015 06:53 PM, Selva Nair wrote:
>
> On Thu, Dec 10, 2015 at 4:55 AM, Lev Stipakov  > wrote:
>
> That sounds useful for yet another reason as well. Its only necessary to 
> delete and recreate the permit filters when the tun restarts. The block 
> filters need
> be set up only once.
>
> Selva
>
> ___
> Openvpn-devel mailing list
> Openvpn-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openvpn-devel



signature.asc
Description: OpenPGP digital signature


[Openvpn-devel] [PATCH applied] Re: Fix isatty() check for good.

2015-12-10 Thread Gert Doering
Patch has been applied to the master and release/2.3 branch.

commit 015fe7177181fb4944ddf33debcfcd20c62ba55a (master)
commit db55abd9e28546874edd78fa50df594a78e794b9 (release/2.3)

Author: Gert Doering
List-Post: openvpn-devel@lists.sourceforge.net
Date:   Wed Dec 9 21:03:55 2015 +0100

 Fix isatty() check for good.

 Signed-off-by: Gert Doering 
 Acked-by: Selva Nair 
 Message-Id: <1449691435-5928-1-git-send-email-g...@greenie.muc.de>
 URL: http://article.gmane.org/gmane.network.openvpn.devel/10709


--
kind regards,

Gert Doering




Re: [Openvpn-devel] [PATCH] Fix isatty() check for good.

2015-12-10 Thread Selva Nair
Hi,

As this fixes an important bug, please do merge as is.

I vaguely recall askpass behaves differently on linux than, say, bsd, so
even if reading from a pipe (when no controlling tty) is possible, it may
not always work. Will test it some other time..

On Thu, Dec 10, 2015 at 3:46 AM, Gert Doering  wrote:

> > Other than that, the patch does the right thing, and works well. Tested
> > using git- master with and without systemd. ACK from me.
>
> Given these two comments, shall we merge it "as it is", or do you want to
> suggest different text?  I'm fine with changing the text, but have no
> good suggestions.


Well, any wording is going to be incomplete, perhaps, so leave it as is..

Selva


[Openvpn-devel] [PATCHv2] Implement the compression V2 data format for stub and lz4.

2015-12-10 Thread Arne Schwabe
V2: Fix an unintended change in the old lz4 decompress code.

It has been tested against v3 server and again itself. From James Mail:

 Compression V2

   I have observed that compression in many cases, even when
   enabled, often does not produce packet size reduction
   because much of the packet data typically generated by web
   sessions is already compressed.  Further, the single byte that
   precedes the packet and indicates whether or not compression
   occurred has the unfortunate side effect of misaligning the IP
   packet in cases where compression did not occur.  To remedy this,
   I propose a Compression V2 header that is optimized for the
   case where compression does not occur.

   a. No compression occurred and first byte of IP/Ethernet packet
  is NOT 0x50 (0 bytes of overhead and maintains alignment):

[ uncompressed IP/Ethernet packet ]

   b. No compression occurred and first byte of IP/Ethernet packet
  is 0x50 (2 bytes of overhead but unlikely since no known
  IP packet can begin with 0x50):

[ 0x50 ] [ 0x00 ] [ uncompressed IP/Ethernet packet ]

   c. Compression occurred (2 bytes of overhead):

[ 0x50 ] [ compression Alg ID ] [ compressed IP/Ethernet packet ]

  Compression Alg ID is one-byte algorithm identifier
  for LZ4 (0x1), LZO (0x2), or Snappy (0x3).

   This approach has several beneficial effects:

   1. In the common case where compression does not occur, no
  compression op is required, therefore there is zero overhead.

   2. When compression does not occur, the IP/Ethernet packet
  alignment is retained.

   3. This technique does not require any byte swapping with
  the tail of the packet which can potentially incur an
  expensive cache miss.
---
 src/openvpn/comp-lz4.c | 195 +++--
 src/openvpn/comp-lz4.h |   1 +
 src/openvpn/comp.c |  81 +++-
 src/openvpn/comp.h |  13 
 src/openvpn/compstub.c |  52 +
 src/openvpn/options.c  |  10 +++
 6 files changed, 293 insertions(+), 59 deletions(-)

diff --git a/src/openvpn/comp-lz4.c b/src/openvpn/comp-lz4.c
index 4651148..91ab236 100644
--- a/src/openvpn/comp-lz4.c
+++ b/src/openvpn/comp-lz4.c
@@ -51,7 +51,7 @@ static void
 lz4_compress_init (struct compress_context *compctx)
 {
   msg (D_INIT_MEDIUM, "LZ4 compression initializing");
-  ASSERT(compctx->flags & COMP_F_SWAP);
+  ASSERT(compctx->flags & COMP_F_SWAP || compctx->flags & COMP_F_COMPV2);
 }

 static void
@@ -59,16 +59,12 @@ lz4_compress_uninit (struct compress_context *compctx)
 {
 }

-static void
-lz4_compress (struct buffer *buf, struct buffer work,
-  struct compress_context *compctx,
-  const struct frame* frame)
+static bool
+do_lz4_compress (struct buffer *buf,
+struct buffer *work,
+struct compress_context *compctx,
+const struct frame* frame)
 {
-  bool compressed = false;
-
-  if (buf->len <= 0)
-return;
-
   /*
* In order to attempt compression, length must be at least 
COMPRESS_THRESHOLD.
*/
@@ -78,33 +74,50 @@ lz4_compress (struct buffer *buf, struct buffer work,
   int zlen_max = ps + COMP_EXTRA_BUFFER (ps);
   int zlen;

-  ASSERT (buf_init (, FRAME_HEADROOM (frame)));
-  ASSERT (buf_safe (, zlen_max));
+  ASSERT (buf_init (work, FRAME_HEADROOM (frame)));
+  ASSERT (buf_safe (work, zlen_max));

   if (buf->len > ps)
{
  dmsg (D_COMP_ERRORS, "LZ4 compression buffer overflow");
  buf->len = 0;
- return;
+ return false;
}

-  zlen = LZ4_compress_limitedOutput((const char *)BPTR(buf), (char 
*)BPTR(), BLEN(buf), zlen_max );
+  zlen = LZ4_compress_limitedOutput((const char *)BPTR(buf), (char 
*)BPTR(work), BLEN(buf), zlen_max );

   if (zlen <= 0)
{
  dmsg (D_COMP_ERRORS, "LZ4 compression error");
  buf->len = 0;
- return;
+ return false;
}

-  ASSERT (buf_safe (, zlen));
-  work.len = zlen;
-  compressed = true;
+  ASSERT (buf_safe (work, zlen));
+  work->len = zlen;
+

-  dmsg (D_COMP, "LZ4 compress %d -> %d", buf->len, work.len);
+  dmsg (D_COMP, "LZ4 compress %d -> %d", buf->len, work->len);
   compctx->pre_compress += buf->len;
-  compctx->post_compress += work.len;
+  compctx->post_compress += work->len;
+  return true;
 }
+  return false;
+}
+
+
+static void
+lz4_compress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+  if (buf->len <= 0)
+return;
+  bool compressed = do_lz4_compress(buf, , compctx, frame);
+
+  /* On Error just return */
+  if (buf->len == 0)
+return;

   /* did compression save us anything? */
   {
@@ -128,13 +141,73 @@ lz4_compress (struct buffer *buf, struct buffer work,
   }
 }

+
+static void
+lz4v2_compress (struct buffer *buf, 

[Openvpn-devel] [PATCH] Ignore stamp-h2 we generate during build process

2015-12-10 Thread Arne Schwabe
---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index 0403ae8..e154092 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,4 @@ config-version.h
 nbproject
 test-driver
 compile
+stamp-h2
-- 
2.5.4 (Apple Git-61)




[Openvpn-devel] [PATCH] Detect config lines that are too long and give a warning/error

2015-12-10 Thread Arne Schwabe
This closes Trac ticket 631
---
 src/openvpn/options.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 4347525..be4ba52 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -3798,7 +3798,7 @@ read_config_file (struct options *options,
   const int max_recursive_levels = 10;
   FILE *fp;
   int line_num;
-  char line[OPTION_LINE_SIZE];
+  char line[OPTION_LINE_SIZE+1];
   char *p[MAX_PARMS];

   ++level;
@@ -3816,6 +3816,10 @@ read_config_file (struct options *options,
   int offset = 0;
  CLEAR (p);
  ++line_num;
+  if (strlen(line) == OPTION_LINE_SIZE)
+  msg (msglevel, "In %s:%d: Maximum optione line length (%d) 
exceeded, line starts with %s",
+   file, line_num, OPTION_LINE_SIZE, line);
+
   /* Ignore UTF-8 BOM at start of stream */
   if (line_num == 1 && strncmp (line, "\xEF\xBB\xBF", 3) == 0)
 offset = 3;
-- 
2.5.4 (Apple Git-61)




[Openvpn-devel] [PATCH] Replace ENABLE_CLIENT_CR with ENABLE_MANAGMENT with unconditionally enables it

2015-12-10 Thread Arne Schwabe
---
 src/openvpn/init.c   | 4 ++--
 src/openvpn/manage.c | 5 +
 src/openvpn/misc.c   | 9 -
 src/openvpn/misc.h   | 2 +-
 src/openvpn/options.c| 2 --
 src/openvpn/options.h| 2 +-
 src/openvpn/push.c   | 5 ++---
 src/openvpn/ssl.c| 8 
 src/openvpn/ssl.h| 2 +-
 src/openvpn/ssl_common.h | 2 +-
 src/openvpn/syshead.h| 7 ---
 11 files changed, 17 insertions(+), 31 deletions(-)

diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 7dfc4aa..b9a9075 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -421,7 +421,7 @@ init_query_passwords (const struct context *c)
   /* Auth user/pass input */
   if (c->options.auth_user_pass_file)
 {
-#ifdef ENABLE_CLIENT_CR
+#ifdef ENABLE_MANAGEMENT
   auth_user_pass_setup (c->options.auth_user_pass_file, 
>options.sc_info);
 #else
   auth_user_pass_setup (c->options.auth_user_pass_file, NULL);
@@ -2305,7 +2305,7 @@ do_init_crypto_tls (struct context *c, const unsigned int 
flags)
 #endif

 #if P2MP
-#ifdef ENABLE_CLIENT_CR
+#ifdef ENABLE_MANAGEMENT
   to.sci = >sc_info;
 #endif
 #endif
diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index dcb1bc1..891a498 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -3056,9 +3056,8 @@ management_query_user_pass (struct management *man,
   const char *alert_type = NULL;
   const char *prefix = NULL;
   unsigned int up_query_mode = 0;
-#ifdef ENABLE_CLIENT_CR
   const char *sc = NULL;
-#endif
+
   ret = true;
   man->persist.standalone_disabled = false; /* This is so M_CLIENT 
messages will be correctly passed through msg() */
   man->persist.special_state_msg = NULL;
@@ -3088,10 +3087,8 @@ management_query_user_pass (struct management *man,
  up_query_mode = UP_QUERY_USER_PASS;
  prefix = "PASSWORD";
  alert_type = "username/password";
-#ifdef ENABLE_CLIENT_CR
  if (static_challenge)
sc = static_challenge;
-#endif
}
   buf_printf (_msg, ">%s:Need '%s' %s",
  prefix,
diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index 5713d2e..52ef81a 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -1055,10 +1055,9 @@ get_user_pass_cr (struct user_pass *up,
  if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED)
management_auth_failure (management, prefix, "previous auth 
credentials failed");

-#ifdef ENABLE_CLIENT_CR
  if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE))
sc = auth_challenge;
-#endif
+
  if (!management_query_user_pass (management, up, prefix, flags, sc))
{
  if ((flags & GET_USER_PASS_NOFATAL) != 0)
@@ -1143,7 +1142,7 @@ get_user_pass_cr (struct user_pass *up,
{ msg(M_FATAL, "neither stdin nor stderr are a tty device, can't 
ask for %s password.  If you used --daemon, you need to use --askpass to make 
passphrase-protected keys work, and you can not use --auth-nocache.", prefix ); 
}
 #endif

-#ifdef ENABLE_CLIENT_CR
+#ifdef ENABLE_MANAGEMENT
  if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
{
  struct auth_challenge_info *ac = get_auth_challenge 
(auth_challenge, );
@@ -1184,7 +1183,7 @@ get_user_pass_cr (struct user_pass *up,
  if (password_from_stdin && !get_console_input (BSTR 
(_prompt), false, up->password, USER_PASS_LEN))
msg (M_FATAL, "ERROR: could not not read %s password from 
stdin", prefix);

-#ifdef ENABLE_CLIENT_CR
+#ifdef ENABLE_MANAGEMENT
  if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE))
{
  char *response = (char *) gc_malloc (USER_PASS_LEN, false, 
);
@@ -1223,7 +1222,7 @@ get_user_pass_cr (struct user_pass *up,
   return true;
 }

-#ifdef ENABLE_CLIENT_CR
+#ifdef ENABLE_MANAGEMENT

 /*
  * See management/management-notes.txt for more info on the
diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h
index dbe899e..5b853fa 100644
--- a/src/openvpn/misc.h
+++ b/src/openvpn/misc.h
@@ -207,7 +207,7 @@ struct user_pass
   char password[USER_PASS_LEN];
 };

-#ifdef ENABLE_CLIENT_CR
+#ifdef ENABLE_MANAGEMENT
 /*
  * Challenge response info on client as pushed by server.
  */
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 9481610..4347525 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -5960,7 +5960,6 @@ add_option (struct options *options,
   VERIFY_PERMISSION (OPT_P_GENERAL);
   auth_retry_set (msglevel, p[1]);
 }
-#ifdef ENABLE_CLIENT_CR
   else if (streq (p[0], "static-challenge") && p[1] && p[2] && !p[3])
 {
   VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -5969,7 +5968,6 @@ add_option (struct options *options,
options->sc_info.flags |= SC_ECHO;
 }
 #endif
-#endif
 #ifdef WIN32
   else if (streq (p[0], "win-sys") && p[1] && !p[2])
 {
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index 

Re: [Openvpn-devel] MSVC "parser stack overflow"

2015-12-10 Thread Gert Doering
Hi,

On Thu, Dec 10, 2015 at 10:58:33AM +0100, Gisle Vanem wrote:
> Gert Doering wrote:
> 
> > For the time being we just use a compiler that is not mainly a pain in the
> > back, solidly stuck in the last century before C99 - as in, none of the
> > core developers compile on windows, we all do cross-compilation with 
> > mingw64 on Linux.
> 
> Well, MSVC 2015 is pretty up-to-date WRT C99. So I think you should remove
> all the *.vcxproj and msvc-*.bat files to prevent more people getting
> the impression you care about Windows.

We provide a working build environment to make windows binaries.

We also provided working MSVC files that worked fine until Microsoft broke
their compiler - all older versions of MSVC can compile OpenVPN just fine
(we actually have quite a few commits in our tree to make compilation with
MSVC work, given it's non-support of this or that which works perfectly
well with gcc or clang).

But we're not going to invest large efforts into fixing something that
Microsoft broke.  If you find the magic option to increase their stack 
size which needs to be added to the vcxproj file - we're happy to add
that, but the onus for "it breaks with MSVC" is on who wants that
environment.

gert
-- 
USENET is *not* the non-clickable part of WWW!
   //www.muc.de/~gert/
Gert Doering - Munich, Germany g...@greenie.muc.de
fax: +49-89-35655025g...@net.informatik.tu-muenchen.de


signature.asc
Description: PGP signature


Re: [Openvpn-devel] MSVC "parser stack overflow"

2015-12-10 Thread Gisle Vanem
Gert Doering wrote:

> For the time being we just use a compiler that is not mainly a pain in the
> back, solidly stuck in the last century before C99 - as in, none of the
> core developers compile on windows, we all do cross-compilation with 
> mingw64 on Linux.

Well, MSVC 2015 is pretty up-to-date WRT C99. So I think you should remove
all the *.vcxproj and msvc-*.bat files to prevent more people getting
the impression you care about Windows.

-- 
--gv



Re: [Openvpn-devel] [PATCH v8-master] Add Windows DNS Leak fix using WFP ('block-outside-dns')

2015-12-10 Thread Lev Stipakov

Hi,

Sorry for the late response.

+bool
+win_wfp_uninit()
+{
+dmsg (D_LOW, "Uninitializing WFP");
+if (m_hEngineHandle) {
+FwpmSubLayerDeleteByKey0(m_hEngineHandle, _subLayerGUID);
+CLEAR(m_subLayerGUID);
+FwpmEngineClose0(m_hEngineHandle);
+m_hEngineHandle = NULL;


FwpmSubLayerDeleteByKey0 will likely fail if there is a filter 
associated with sublayer. On the other side, FwpmEngineClose0 seems to 
be enough to remove blocking.


I think the correct way would be to create GUID for filter same way as 
you did for sublayer and copy it to filter.filterKey. In uninit method, 
before deleting sublayer you call FwpmFilterDeleteByKey0 with that guid.


-Lev




Re: [Openvpn-devel] MSVC "parser stack overflow"

2015-12-10 Thread Arne Schwabe


Am 10.12.15 um 09:36 schrieb Gert Doering:
> Hi,
>
> On Wed, Dec 09, 2015 at 11:05:06PM +0100, Gisle Vanem wrote:
>> While compiling src/openvpn/options.c with MSVC 2015, I got this
>> error:
>>   src/openvpn/options.c(5944): fatal error C1026: parser stack overflow, 
>> program too complex
>>
>> I've also seen such error in GeoIP-lib due to all the 'if..else if' 
>> statements.
>> Can this be written using some kind of a table-lookup code instead?
> We could, certainly, if we had nothing else to do.
>
> For the time being we just use a compiler that is not mainly a pain in the
> back, solidly stuck in the last century before C99 - as in, none of the
> core developers compile on windows, we all do cross-compilation with 
> mingw64 on Linux.
>
Or use the experimental Clang frontend for MSVC codegen

http://blogs.msdn.com/b/vcblog/archive/2015/12/04/introducing-clang-with-microsoft-codegen-in-vs-2015-update-1.aspx

As Gert said, that code is old, reliable and well tested. And just about
quirky enough that it is no straighforward table-lookup code conversion.

Arne




Re: [Openvpn-devel] [PATCH] Make ValdikSS's DNS leak fix platform agnostic

2015-12-10 Thread Gert Doering
Hi,

On Wed, Dec 09, 2015 at 05:30:14PM -0800, Fish Wang wrote:
> Based on release/2.3 branch, this patch is cross-compiled in MinGW and
> tested on Windows XP/10. The VC project file is left untouched - you might
> want to add rpcrt4.lib to compile and link it under MSVC.
> 
> Also, I didn't figure out how to keep ValdikSS's authorship of his code in
> the patch (sorry :-( ). Definitely no expert in git... Maybe I should
> generate a patch on top of his latest patch?

The latter is much better.  Use git release/2.3, apply ValdikSS' v8 patch on 
top of that, and then do your changes - that way, proper author attribution
is there, and we can see much easier what you changed.  Right now this is
a long piece of code that differs only in a vew lines from "one of the
8 different patch versions from ValdikSS".  Hard to review.

thanks,

gert

-- 
USENET is *not* the non-clickable part of WWW!
   //www.muc.de/~gert/
Gert Doering - Munich, Germany g...@greenie.muc.de
fax: +49-89-35655025g...@net.informatik.tu-muenchen.de


signature.asc
Description: PGP signature


Re: [Openvpn-devel] [PATCH] Fix isatty() check for good.

2015-12-10 Thread Gert Doering
Hi,

On Thu, Dec 10, 2015 at 02:43:44AM -0500, Selva Nair wrote:
> Thanks for this fix. Systemd-ask-password now works!

Thanks :-)

> On Wed, Dec 9, 2015 at 3:03 PM, Gert Doering  wrote:
> 
> > +  if ( !isatty(0) && !isatty(2) )
> > +{
> > +  int fd = open( "/dev/tty", O_RDWR );
> > +  if ( fd < 0 )
> >
> 
> This doesn't allow for reading passwords from pipes -- not relevant if
> getpass doesn't fall back to a non-tty stdin if /dev/tty open fails -- does
> it? Not saying pipes should be supported --- whatever is consistent with
> getpass should be fine.

I'm not sure this is a use case we actually have - to trigger this, you'd
need to run openvpn like this

  echo mypass | openvpn 2>/dev/null

(so isatty(2) fails) *and* run it from an RC script or something else that
does not have a controlling tty.

Given that we broke this in 2.3.8 already, and the only complaints we heard
was "systemd is not working anymore" (apologies!), I think that scenario is
somewhat unlikely.


> > +   { msg(M_FATAL, "neither stdin nor stderr are a tty device and you
> > have neither a controlling tty nor systemd - can't ask for '%s'.  If you
> > used --daemon, you need to use --askpass to make passphrase-protected keys
> > work, and you can not use --auth-nocache.", prompt ); }
> > +  close(fd);
> >
> 
> The error message is still incomplete/confusing when the triggered by
> auth-user-pass
> without a filename (i.e stdin), and not by a passphrase-protected key. In
> the former case a reference to the need for management-query or a
> username-password
> file is helpful.
> 
> Other than that, the patch does the right thing, and works well. Tested
> using git- master with and without systemd. ACK from me.

Given these two comments, shall we merge it "as it is", or do you want to 
suggest different text?  I'm fine with changing the text, but have no 
good suggestions.

gert
-- 
USENET is *not* the non-clickable part of WWW!
   //www.muc.de/~gert/
Gert Doering - Munich, Germany g...@greenie.muc.de
fax: +49-89-35655025g...@net.informatik.tu-muenchen.de


signature.asc
Description: PGP signature


Re: [Openvpn-devel] MSVC "parser stack overflow"

2015-12-10 Thread Gert Doering
Hi,

On Wed, Dec 09, 2015 at 11:05:06PM +0100, Gisle Vanem wrote:
> While compiling src/openvpn/options.c with MSVC 2015, I got this
> error:
>   src/openvpn/options.c(5944): fatal error C1026: parser stack overflow, 
> program too complex
> 
> I've also seen such error in GeoIP-lib due to all the 'if..else if' 
> statements.
> Can this be written using some kind of a table-lookup code instead?

We could, certainly, if we had nothing else to do.

For the time being we just use a compiler that is not mainly a pain in the
back, solidly stuck in the last century before C99 - as in, none of the
core developers compile on windows, we all do cross-compilation with 
mingw64 on Linux.

gert
-- 
USENET is *not* the non-clickable part of WWW!
   //www.muc.de/~gert/
Gert Doering - Munich, Germany g...@greenie.muc.de
fax: +49-89-35655025g...@net.informatik.tu-muenchen.de


signature.asc
Description: PGP signature


Re: [Openvpn-devel] [PATCH] Fix isatty() check for good.

2015-12-10 Thread Selva Nair
Hi,

Thanks for this fix. Systemd-ask-password now works!

On Wed, Dec 9, 2015 at 3:03 PM, Gert Doering  wrote:

> +  if ( !isatty(0) && !isatty(2) )
> +{
> +  int fd = open( "/dev/tty", O_RDWR );
> +  if ( fd < 0 )
>

This doesn't allow for reading passwords from pipes -- not relevant if
getpass doesn't fall back to a non-tty stdin if /dev/tty open fails -- does
it? Not saying pipes should be supported --- whatever is consistent with
getpass should be fine.


> +   { msg(M_FATAL, "neither stdin nor stderr are a tty device and you
> have neither a controlling tty nor systemd - can't ask for '%s'.  If you
> used --daemon, you need to use --askpass to make passphrase-protected keys
> work, and you can not use --auth-nocache.", prompt ); }
> +  close(fd);
>

The error message is still incomplete/confusing when the triggered by
auth-user-pass
without a filename (i.e stdin), and not by a passphrase-protected key. In
the former case a reference to the need for management-query or a
username-password
file is helpful.

Other than that, the patch does the right thing, and works well. Tested
using git- master with and without systemd. ACK from me.

Selva


[Openvpn-devel] [PATCH] Make ValdikSS's DNS leak fix platform agnostic

2015-12-10 Thread Fish Wang
Based on release/2.3 branch, this patch is cross-compiled in MinGW and
tested on Windows XP/10. The VC project file is left untouched - you might
want to add rpcrt4.lib to compile and link it under MSVC.

Also, I didn't figure out how to keep ValdikSS's authorship of his code in
the patch (sorry :-( ). Definitely no expert in git... Maybe I should
generate a patch on top of his latest patch?

Take ValdikSS's patch for "block-outside-dns" option
and
make it Windows-version-agnostic. My code is pretty messy right now, will
send
out a secondary patch later after tidying WFP-related code.
---
 doc/openvpn.8   |  12 +-
 src/openvpn/Makefile.am |   2 +-
 src/openvpn/init.c  |  13 ++
 src/openvpn/openvpn.vcxproj |   0
 src/openvpn/options.c   |  11 +
 src/openvpn/options.h   |   1 +
 src/openvpn/win32.c | 520

 src/openvpn/win32.h |   4 +
 8 files changed, 560 insertions(+), 3 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj

diff --git a/doc/openvpn.8 b/doc/openvpn.8
index 8968c2e..9e4b01e 100644
--- a/doc/openvpn.8
+++ b/doc/openvpn.8
@@ -1119,8 +1119,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and
dhcp
+options like DNS servers.

 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5448,6 +5448,14 @@ adapter list to the syslog or log file after the
TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 2e602f1..149a533 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -123,5 +123,5 @@ openvpn_LDADD = \
  $(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lrpcrt4
-lwinmm
 endif
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index ceef4f7..960535d 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -1468,6 +1468,13 @@ do_open_tun (struct context *c)
  "up",
  c->c2.es);

+  if (c->options.block_outside_dns)
+  {
+dmsg (D_LOW, "Blocking outside DNS");
+if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+msg (M_FATAL, "Blocking DNS failed!");
+  }
+
   /* possibly add routes */
   if (!c->options.route_delay_defined)
  do_route (>options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1594,6 +1601,12 @@ do_close_tun (struct context *c, bool force)
  "down",
  c->c2.es);

+if (c->options.block_outside_dns)
+{
+if (!win_wfp_uninit())
+msg (M_FATAL, "Uninitialising WFP failed!");
+}
+
/* actually close tun/tap device based on --down-pre flag */
if (c->options.down_pre)
  do_close_tun_simple (c);
diff --git a/src/openvpn/openvpn.vcxproj b/src/openvpn/openvpn.vcxproj
old mode 100755
new mode 100644
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index f609aa6..564e670 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -715,6 +715,7 @@ static const char usage_message[] =
   "   optional parameter controls the initial state of
ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net
adapter list\n"
   "  after TAP adapter is up and routes have been added.\n"
+  "--block-outside-dns   : Block DNS on other network adapters to prevent
DNS leaks\n"
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -814,6 +815,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;   /* use network address as
internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1678,6 +1680,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options