[Openvpn-devel] TAP-Windows MTU issues

2014-10-29 Thread David Woodhouse
It looks like on Windows, OpenVPN ignores the MTU it's supposed to be
using and just queries the TAP driver for its MTU.

I suspect this was done in the past because there was no way to *set*
the MTU that Windows was expected to use.

That is no longer the case; recent versions of Windows let you do it by:
netsh interface ipv[46] set subinterface $DEVICE mtu=$MTU store=active

I do this in OpenConnect on Windows, and I suspect OpenVPN should too.

I'm left with the question of what to do on older versions of Windows
where we can't configure the MTU. One option which occurs to me is that
we could actually send Windows back an ICMP 'too big' message when it
receives a packet which is larger than the VPN MTU. This is horrid, but
hey, it's Windows. We *already* do horrider things in TAP-Windows to
fake ARP and ND.

What do you think?

-- 
dwmw2


smime.p7s
Description: S/MIME cryptographic signature


[Openvpn-devel] [PATCH] Peer-id patch v2

2014-10-29 Thread Lev Stipakov
Added new packet format P_DATA_V2, which includes peer-id. If server
supports, client sends all data packets in the new format. When data
packet arrives, server identifies peer by peer-id. If peer's ip/port has
changed, server assumes that client has floated, verifies HMAC and
updates ip/port in internal structs.
---
 src/openvpn/crypto.c |  66 
 src/openvpn/crypto.h |   3 ++
 src/openvpn/init.c   |  10 -
 src/openvpn/mudp.c   | 111 +--
 src/openvpn/multi.c  |   6 +++
 src/openvpn/multi.h  |   2 +
 src/openvpn/options.c|   9 +++-
 src/openvpn/options.h|   8 +++-
 src/openvpn/push.c   |  16 ++-
 src/openvpn/ssl.c|  66 +---
 src/openvpn/ssl.h|   9 +++-
 src/openvpn/ssl_common.h |   4 ++
 12 files changed, 269 insertions(+), 41 deletions(-)

diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index ef2bde1..0f1a36f 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -223,6 +223,30 @@ err:
   return;
 }

+int verify_hmac(struct buffer *buf, struct key_ctx *ctx, int offset)
+{
+  uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext computed 
locally */
+  int hmac_len = 0;
+
+  hmac_ctx_reset(ctx->hmac);
+  /* Assume the length of the input HMAC */
+  hmac_len = hmac_ctx_size (ctx->hmac);
+
+  /* Authentication fails if insufficient data in packet for HMAC */
+  if (buf->len - offset < hmac_len)
+return 0;
+
+  hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len + offset,
+   BLEN (buf) - hmac_len - offset);
+  hmac_ctx_final (ctx->hmac, local_hmac);
+
+  /* Compare locally computed HMAC with packet HMAC */
+  if (memcmp_constant_time (local_hmac, BPTR (buf) + offset, hmac_len) == 0)
+return hmac_len;
+
+  return 0;
+}
+
 /*
  * If (opt->flags & CO_USE_IV) is not NULL, we will read an IV from the packet.
  *
@@ -249,25 +273,9 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
   /* Verify the HMAC */
   if (ctx->hmac)
{
- int hmac_len;
- uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext 
computed locally */
-
- hmac_ctx_reset(ctx->hmac);
-
- /* Assume the length of the input HMAC */
- hmac_len = hmac_ctx_size (ctx->hmac);
-
- /* Authentication fails if insufficient data in packet for HMAC */
- if (buf->len < hmac_len)
-   CRYPT_ERROR ("missing authentication info");
-
- hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len, BLEN (buf) - 
hmac_len);
- hmac_ctx_final (ctx->hmac, local_hmac);
-
- /* Compare locally computed HMAC with packet HMAC */
- if (memcmp_constant_time (local_hmac, BPTR (buf), hmac_len))
+ int hmac_len = verify_hmac(buf, ctx, 0);
+ if (hmac_len == 0)
CRYPT_ERROR ("packet HMAC authentication failed");
-
  ASSERT (buf_advance (buf, hmac_len));
}

@@ -392,6 +400,28 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
 }

 /*
+ * This verifies if a packet and its HMAC fit to a crypto context.
+ *
+ * On success true is returned.
+ */
+bool
+crypto_test_hmac (struct buffer *buf, const struct crypto_options *opt)
+{
+  if (buf->len > 0 && opt->key_ctx_bi)
+{
+  struct key_ctx *ctx = >key_ctx_bi->decrypt;
+
+  /* Verify the HMAC */
+  if (ctx->hmac)
+   {
+ /* sizeof(uint32_t) comes from peer_id (3 bytes) and opcode (1 byte) 
*/
+ return verify_hmac(buf, ctx, sizeof(uint32_t)) != 0;
+   }
+}
+  return false;
+}
+
+/*
  * How many bytes will we add to frame buffer for a given
  * set of crypto options?
  */
diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h
index bf2f802..3c4e59d 100644
--- a/src/openvpn/crypto.h
+++ b/src/openvpn/crypto.h
@@ -275,6 +275,9 @@ bool openvpn_decrypt (struct buffer *buf, struct buffer 
work,
  const struct crypto_options *opt,
  const struct frame* frame);

+
+bool crypto_test_hmac (struct buffer *buf, const struct crypto_options *opt);
+
 /** @} name Functions for performing security operations on data channel 
packets */

 void crypto_adjust_frame_parameters(struct frame *frame,
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index a673be5..3811e09 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -1718,7 +1718,8 @@ pull_permission_mask (const struct context *c)
 | OPT_P_MESSAGES
 | OPT_P_EXPLICIT_NOTIFY
 | OPT_P_ECHO
-| OPT_P_PULL_MODE;
+| OPT_P_PULL_MODE
+| OPT_P_PEER_ID;

   if (!c->options.route_nopull)
 flags |= (OPT_P_ROUTE | OPT_P_IPWIN32);
@@ -1795,6 +1796,13 @@ do_deferred_options (struct context *c, const unsigned 
int found)
 msg (D_PUSH, "OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options 
modified");
   if (found & OPT_P_SETENV)
 msg (D_PUSH, "OPTIONS IMPORT: environment modified");
+
+  if (found & OPT_P_PEER_ID)
+{
+  msg (D_PUSH,