security/openvpn: update to 2.4.9 (also for -mbedtls slave port)

At the same time, remove ASYNC_PUSH_LIBS workaround from [1].

Changelog (high-level):
https://github.com/OpenVPN/openvpn/blob/release/2.4/Changes.rst#version-249

Git changelog, marking the three fixes that were already in 2.4.8_3
as cherry-picks with a 1, 2, or 3 instead of "*" to correspond
with the PORTREVISION, and those with "-" that are specific to other systems,
say, Windows.

* 9b0dafca 2020-04-16 | Preparing release v2.4.9 (ChangeLog, version.m4, Changes.rst) (tag: v2.4.9) [Gert Doering]
3 f7b318f8 2020-04-15 | Fix illegal client float (CVE-2020-11810) [Lev Stipakov]
* 9bb285e3 2020-03-13 | Fix broken async push with NCP is used [Lev Stipakov]
- 5f8a9df1 2020-02-12 | Allow unicode search string in --cryptoapicert option [Selva Nair]
- 4658b3b6 2020-02-12 | Skip expired certificates in Windows certificate store [Selva Nair]
* df5ea7f1 2020-02-19 | Fix possible access of uninitialized pipe handles [Selva Nair]
* 1d9e0be2 2020-02-19 | Fix possibly uninitialized return value in GetOpenvpnSettings() [Selva Nair]
* 5ee76a8f 2020-03-28 | Fix OpenSSL 1.1.1 not using auto elliptic curve selection [Arne Schwabe]
* ed925c0a 2020-04-07 | OpenSSL: Fix --crl-verify not loading multiple CRLs in one file [Maxim Plotnikov]
* 2fe84732 2020-03-30 | When auth-user-pass file has no password query the management interface (if available). [Selva Nair]
* 908eae5c 2020-04-03 | Move querying username/password from management interface to a function [Selva Nair]
* 15bc476f 2020-04-02 | Fix OpenSSL error stack handling of tls_ctx_add_extra_certs [Arne Schwabe]
* 22df79bb 2020-04-01 | Fetch OpenSSL versions via source/old links [Arne Schwabe]
* 0efbd8e9 2020-03-31 | mbedTLS: Make sure TLS session survives move [Tom van Leeuwen]
* 33395693 2020-03-25 | docs: Add reference to X509_LOOKUP_hash_dir(3) [WGH]
* 7d19b2bb 2019-10-21 | Fix OpenSSL private key passphrase notices [Santtu Lakkala]
2 8484f37a 2020-03-14 | Fix building with --enable-async-push in FreeBSD [Lev Stipakov]
* 69bbfbdf 2020-02-18 | Swap the order of checks for validating interactive service user [Selva Nair]
* 0ba4f916 2019-11-09 | socks: use the right function when printing struct openvpn_sockaddr [Antonio Quartulli]
1 3bd91cd0 2019-10-30 | Fix broken fragmentation logic when using NCP [Lev Stipakov]

PR:		244286 [1]
MFH:		2020Q2 (patchlevel bugfix release)
This commit is contained in:
Matthias Andree 2020-04-17 18:38:44 +00:00
parent 8165354577
commit d21d4b9d5f
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=531957
4 changed files with 7 additions and 268 deletions

View file

@ -2,13 +2,12 @@
# $FreeBSD$
PORTNAME= openvpn
DISTVERSION= 2.4.8
# FIXME XXX check if 2.4.9 still needs ASYNC_PUSH_LIBS, see
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=244286#c6 and #c7
PORTREVISION?= 3
DISTVERSION= 2.4.9
PORTREVISION?= 0
CATEGORIES= security net net-vpn
MASTER_SITES= https://swupdate.openvpn.org/community/releases/ \
https://build.openvpn.net/downloads/releases/
https://build.openvpn.net/downloads/releases/ \
LOCAL/mandree
MAINTAINER= mandree@FreeBSD.org
COMMENT?= Secure IP/Ethernet tunnel daemon
@ -51,7 +50,6 @@ SMALL_DESC= Build a smaller executable with fewer features
ASYNC_PUSH_CONFIGURE_ENABLE= async-push
ASYNC_PUSH_LIB_DEPENDS= libinotify.so:devel/libinotify
ASYNC_PUSH_LIBS= -linotify
EASYRSA_RUN_DEPENDS= easy-rsa>=0:security/easy-rsa

View file

@ -1,3 +1,3 @@
TIMESTAMP = 1572606331
SHA256 (openvpn-2.4.8.tar.xz) = fb8ca66bb7807fff595fbdf2a0afd085c02a6aa47715c9aa3171002f9f1a3f91
SIZE (openvpn-2.4.8.tar.xz) = 952444
TIMESTAMP = 1587146198
SHA256 (openvpn-2.4.9.tar.xz) = 641f3add8694b2ccc39fd4fd92554e4f089ad16a8db6d2b473ec284839a5ebe2
SIZE (openvpn-2.4.9.tar.xz) = 954264

View file

@ -1,64 +0,0 @@
commit f7b318f811bb43c0d3aa7f337ec6242ed2c33881
Author: Lev Stipakov <lev@openvpn.net>
Date: Wed Apr 15 10:30:17 2020 +0300
Fix illegal client float (CVE-2020-11810)
There is a time frame between allocating peer-id and initializing data
channel key (which is performed on receiving push request or on async
push-reply) in which the existing peer-id float checks do not work right.
If a "rogue" data channel packet arrives during that time frame from
another address and with same peer-id, this would cause client to float
to that new address. This is because:
- tls_pre_decrypt() sets packet length to zero if
data channel key has not been initialized, which leads to
- openvpn_decrypt() returns true if packet length is zero,
which leads to
- process_incoming_link_part1() returns true, which
calls multi_process_float(), which commits float
Note that problem doesn't happen when data channel key is initialized,
since in this case openvpn_decrypt() returns false.
The net effect of this behaviour is that the VPN session for the
"victim client" is broken. Since the "attacker client" does not have
suitable keys, it can not inject or steal VPN traffic from the other
session. The time window is small and it can not be used to attack
a specific client's session, unless some other way is found to make it
disconnect and reconnect first.
CVE-2020-11810 has been assigned to acknowledge this risk.
Fix illegal float by adding buffer length check ("is this packet still
considered valid") before calling multi_process_float().
Trac: #1272
CVE: 2020-11810
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20200415073017.22839-1-lstipakov@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg19720.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit 37bc691e7d26ea4eb61a8a434ebd7a9ae76225ab)
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index 58607730..c8c9a40e 100644
--- ./src/openvpn/multi.c~
+++ ./src/openvpn/multi.c
@@ -2562,7 +2562,8 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst
orig_buf = c->c2.buf.data;
if (process_incoming_link_part1(c, lsi, floated))
{
- if (floated)
+ /* nonzero length means that we have a valid, decrypted packed */
+ if (floated && c->c2.buf.len > 0)
{
multi_process_float(m, m->pending);
}

View file

@ -1,195 +0,0 @@
From 3bd91cd0e68762b861c57cf37f144d8a11704e9d Mon Sep 17 00:00:00 2001
From: Lev Stipakov <lev@openvpn.net>
Date: Wed, 30 Oct 2019 14:44:59 +0200
Subject: [PATCH] Fix broken fragmentation logic when using NCP
This is the 2.4 backport of master patch (commit d22ba6b).
NCP negotiation replaces worst case crypto overhead
with actual one in data channel frame. That frame
params are used by mssfix. Fragment frame still contains
worst case overhead.
Without this patch, fragmentation logic incorrectly uses
max crypto overhead when calculating packet size. It exceeds
fragment size and openvpn peforms fragmentation:
> sudo tcpdump port 1194
13:59:06.956394 IP server.fi.openvpn > nat2.panoulu.net.openvpn: UDP,
length 652
13:59:06.956489 IP server.fi.openvpn > nat2.panoulu.net.openvpn: UDP,
length 648
This patch fixes fragmentation calculation by
setting actual crypto overhead, and no unnecessary
fragmentation is performed:
> sudo tcpdump port 1194
13:58:08.685915 IP server.fi.openvpn > nat2.panoulu.net.openvpn: UDP,
length 1272
13:58:08.686007 IP server.fi.openvpn > nat2.panoulu.net.openvpn: UDP,
length 1272
Trac #1140
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1572439499-16276-1-git-send-email-lstipakov@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg18975.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
---
src/openvpn/forward.c | 3 +++
src/openvpn/init.c | 12 +++++++++++-
src/openvpn/openvpn.h | 1 +
src/openvpn/push.c | 9 ++++++++-
src/openvpn/ssl.c | 19 ++++++++++++++++++-
src/openvpn/ssl.h | 13 ++++++++-----
6 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index 65f790fda..84bb58447 100644
--- ./src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -873,6 +873,9 @@ process_incoming_link_part1(struct context *c, struct link_socket_info *lsi, boo
if (is_hard_reset(opcode, c->options.key_method))
{
c->c2.frame = c->c2.frame_initial;
+#ifdef ENABLE_FRAGMENT
+ c->c2.frame_fragment = c->c2.frame_fragment_initial;
+#endif
}
interval_action(&c->c2.tmp_int);
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index d3785cabd..37b832ab0 100644
--- ./src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -2294,9 +2294,18 @@ do_deferred_options(struct context *c, const unsigned int found)
{
tls_poor_mans_ncp(&c->options, c->c2.tls_multi->remote_ciphername);
}
+ struct frame *frame_fragment = NULL;
+#ifdef ENABLE_FRAGMENT
+ if (c->options.ce.fragment)
+ {
+ frame_fragment = &c->c2.frame_fragment;
+ }
+#endif
+
/* Do not regenerate keys if server sends an extra push reply */
if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized
- && !tls_session_update_crypto_params(session, &c->options, &c->c2.frame))
+ && !tls_session_update_crypto_params(session, &c->options, &c->c2.frame,
+ frame_fragment))
{
msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto options");
return false;
@@ -3035,6 +3044,7 @@ do_init_frame(struct context *c)
*/
c->c2.frame_fragment = c->c2.frame;
frame_subtract_extra(&c->c2.frame_fragment, &c->c2.frame_fragment_omit);
+ c->c2.frame_fragment_initial = c->c2.frame_fragment;
#endif
#if defined(ENABLE_FRAGMENT) && defined(ENABLE_OCC)
diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h
index 77361833d..ed7975c35 100644
--- ./src/openvpn/openvpn.h
+++ b/src/openvpn/openvpn.h
@@ -269,6 +269,7 @@ struct context_2
/* Object to handle advanced MTU negotiation and datagram fragmentation */
struct fragment_master *fragment;
struct frame frame_fragment;
+ struct frame frame_fragment_initial;
struct frame frame_fragment_omit;
#endif
diff --git a/src/openvpn/push.c b/src/openvpn/push.c
index dd5bd4163..ba2fbe404 100644
--- ./src/openvpn/push.c
+++ b/src/openvpn/push.c
@@ -287,11 +287,18 @@ incoming_push_message(struct context *c, const struct buffer *buffer)
{
if (c->options.mode == MODE_SERVER)
{
+ struct frame *frame_fragment = NULL;
+#ifdef ENABLE_FRAGMENT
+ if (c->options.ce.fragment)
+ {
+ frame_fragment = &c->c2.frame_fragment;
+ }
+#endif
struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
/* Do not regenerate keys if client send a second push request */
if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized
&& !tls_session_update_crypto_params(session, &c->options,
- &c->c2.frame))
+ &c->c2.frame, frame_fragment))
{
msg(D_TLS_ERRORS, "TLS Error: initializing data channel failed");
goto error;
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 9696e9bab..7dcd9622f 100644
--- ./src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -1962,7 +1962,8 @@ tls_session_generate_data_channel_keys(struct tls_session *session)
bool
tls_session_update_crypto_params(struct tls_session *session,
- struct options *options, struct frame *frame)
+ struct options *options, struct frame *frame,
+ struct frame *frame_fragment)
{
if (!session->opt->server
&& 0 != strcmp(options->ciphername, session->opt->config_ciphername)
@@ -2006,6 +2007,22 @@ tls_session_update_crypto_params(struct tls_session *session,
frame_init_mssfix(frame, options);
frame_print(frame, D_MTU_INFO, "Data Channel MTU parms");
+ /*
+ * mssfix uses data channel framing, which at this point contains
+ * actual overhead. Fragmentation logic uses frame_fragment, which
+ * still contains worst case overhead. Replace it with actual overhead
+ * to prevent unneeded fragmentation.
+ */
+
+ if (frame_fragment)
+ {
+ frame_remove_from_extra_frame(frame_fragment, crypto_max_overhead());
+ crypto_adjust_frame_parameters(frame_fragment, &session->opt->key_type,
+ options->use_iv, options->replay, packet_id_long_form);
+ frame_set_mtu_dynamic(frame_fragment, options->ce.fragment, SET_MTU_UPPER_BOUND);
+ frame_print(frame_fragment, D_MTU_INFO, "Fragmentation MTU parms");
+ }
+
return tls_session_generate_data_channel_keys(session);
}
diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h
index 8066789b6..6672d43fb 100644
--- ./src/openvpn/ssl.h
+++ b/src/openvpn/ssl.h
@@ -475,15 +475,18 @@ void tls_update_remote_addr(struct tls_multi *multi,
* Update TLS session crypto parameters (cipher and auth) and derive data
* channel keys based on the supplied options.
*
- * @param session The TLS session to update.
- * @param options The options to use when updating session.
- * @param frame The frame options for this session (frame overhead is
- * adjusted based on the selected cipher/auth).
+ * @param session The TLS session to update.
+ * @param options The options to use when updating session.
+ * @param frame The frame options for this session (frame overhead is
+ * adjusted based on the selected cipher/auth).
+ * @param frame_fragment The fragment frame options.
*
* @return true if updating succeeded, false otherwise.
*/
bool tls_session_update_crypto_params(struct tls_session *session,
- struct options *options, struct frame *frame);
+ struct options *options,
+ struct frame *frame,
+ struct frame *frame_fragment);
/**
* "Poor man's NCP": Use peer cipher if it is an allowed (NCP) cipher.