Your message dated Sun, 14 May 2017 06:53:40 +0000
with message-id <e1d9npq-0005cx...@respighi.debian.org>
and subject line unblock openvpn
has caused the Debian Bug report #862526,
regarding unblock: openvpn/2.4.0-5
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
862526: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=862526
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock

Hi

Please unblock package openvpn

The update fixes security issues, in CVE-2017-7478 which is
pre-authentication (and does not affect stable version).

Detail are in
https://community.openvpn.net/openvpn/wiki/QuarkslabAndCryptographyEngineerAudits

Changelog:

+openvpn (2.4.0-5) unstable; urgency=high
+
+  * Change typo fix in command line help.
+  * SECURITY UPDATE: pre-authentication denial-of-service vulnerability
+    (both client and server) from a too-large control packet.
+    - debian/patches/CVE-2017-7478.patch: Do not assert on too-large
+      control packet
+    - CVE-2017-7478
+  * SECURITY UPDATE: authenticated remote DoS vulnerability due to
+    packet ID rollover
+    - debian/patches/CVE-2017-7479-prereq.patch: merge
+      packet_id_alloc_outgoing() into packet_id_write()
+    - debian/patches/CVE-2017-7479.patch: do not assert when packet ID
+      rollover occurs
+    - CVE-2017-7479
+  * SECURITY UPDATE: auth tokens left in memory after de-auth
+    - debian/patches/wipe_tokens_on_de-auth.patch: always wipe token
+      as soon as a TLS session is considered broken.
+   * Kudos to Steve Beattie <sbeat...@ubuntu.com> for doing all the
+     backporting work for this upload.
+
+ -- Alberto Gonzalez Iniesta <a...@inittab.org>  Thu, 11 May 2017 14:15:21 
+0200

unblock openvpn/2.4.0-5

Attached is as well the complete debdiff.

Regards,
Salvatore
diff -Nru openvpn-2.4.0/debian/changelog openvpn-2.4.0/debian/changelog
--- openvpn-2.4.0/debian/changelog	2017-02-02 14:15:42.000000000 +0100
+++ openvpn-2.4.0/debian/changelog	2017-05-11 14:15:21.000000000 +0200
@@ -1,3 +1,26 @@
+openvpn (2.4.0-5) unstable; urgency=high
+
+  * Change typo fix in command line help.
+  * SECURITY UPDATE: pre-authentication denial-of-service vulnerability
+    (both client and server) from a too-large control packet.
+    - debian/patches/CVE-2017-7478.patch: Do not assert on too-large
+      control packet
+    - CVE-2017-7478
+  * SECURITY UPDATE: authenticated remote DoS vulnerability due to
+    packet ID rollover
+    - debian/patches/CVE-2017-7479-prereq.patch: merge
+      packet_id_alloc_outgoing() into packet_id_write()
+    - debian/patches/CVE-2017-7479.patch: do not assert when packet ID
+      rollover occurs
+    - CVE-2017-7479
+  * SECURITY UPDATE: auth tokens left in memory after de-auth
+    - debian/patches/wipe_tokens_on_de-auth.patch: always wipe token
+      as soon as a TLS session is considered broken.
+   * Kudos to Steve Beattie <sbeat...@ubuntu.com> for doing all the
+     backporting work for this upload.
+
+ -- Alberto Gonzalez Iniesta <a...@inittab.org>  Thu, 11 May 2017 14:15:21 +0200
+
 openvpn (2.4.0-4) unstable; urgency=medium
 
   * Add NEWS entries on possible 2.4 migration issues.
diff -Nru openvpn-2.4.0/debian/patches/CVE-2017-7478.patch openvpn-2.4.0/debian/patches/CVE-2017-7478.patch
--- openvpn-2.4.0/debian/patches/CVE-2017-7478.patch	1970-01-01 01:00:00.000000000 +0100
+++ openvpn-2.4.0/debian/patches/CVE-2017-7478.patch	2017-05-11 14:15:21.000000000 +0200
@@ -0,0 +1,55 @@
+From be66408610a52f81c9c895a8973958ead55a4e57 Mon Sep 17 00:00:00 2001
+From: Steffan Karger <steffan.kar...@fox-it.com>
+Date: Tue, 9 May 2017 15:40:25 +0300
+Subject: [PATCH] Don't assert out on receiving too-large control packets
+ (CVE-2017-xxx)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit 3c1b19e0 changed the maximum size of accepted control channel
+packets.  This was needed for crypto negotiation (which is needed for a
+nice transition to a new default cipher), but exposed a DoS
+vulnerability.  The vulnerability was found during the OpenVPN 2.4 code
+audit by Quarkslab (commisioned by OSTIF).
+
+To fix the issue, we should not ASSERT() on external input (in this case
+the received packet size), but instead gracefully error out and drop the
+invalid packet.
+
+Signed-off-by: Steffan Karger <steffan.kar...@fox-it.com>
+Signed-off-by: Samuli Seppänen <sam...@openvpn.net>
+
+CVE-2017-7478
+
+  Security
+  --------
+  - This release fixes a pre-authentication denial-of-service attack on both
+    clients and servers.  By sending a too-large control packet, OpenVPN 2.4.0 or
+    2.4.1 can be forced to hit an ASSERT() and stop the process.  If
+    ``--tls-auth`` or ``--tls-crypt`` is used, only attackers that have the
+    ``--tls-auth`` or ``--tls-crypt`` key can mount an attack. (CVE-2017-xxx)
+
+---
+ Changes.rst       | 8 ++++++++
+ src/openvpn/ssl.c | 7 ++++++-
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+Index: openvpn-2.4.0/src/openvpn/ssl.c
+===================================================================
+--- openvpn-2.4.0.orig/src/openvpn/ssl.c
++++ openvpn-2.4.0/src/openvpn/ssl.c
+@@ -3708,7 +3708,12 @@ tls_pre_decrypt(struct tls_multi *multi,
+                                 /* Save incoming ciphertext packet to reliable buffer */
+                                 struct buffer *in = reliable_get_buf(ks->rec_reliable);
+                                 ASSERT(in);
+-                                ASSERT(buf_copy(in, buf));
++                                if(!buf_copy(in, buf))
++                                {
++                                    msg(D_MULTI_DROPPED,
++                                        "Incoming control channel packet too big, dropping.");
++                                    goto error;
++                                }
+                                 reliable_mark_active_incoming(ks->rec_reliable, in, id, op);
+                             }
+ 
diff -Nru openvpn-2.4.0/debian/patches/CVE-2017-7479.patch openvpn-2.4.0/debian/patches/CVE-2017-7479.patch
--- openvpn-2.4.0/debian/patches/CVE-2017-7479.patch	1970-01-01 01:00:00.000000000 +0100
+++ openvpn-2.4.0/debian/patches/CVE-2017-7479.patch	2017-05-11 14:15:21.000000000 +0200
@@ -0,0 +1,193 @@
+From ac08b27cfa693d9be592bb2597c260635aee9e68 Mon Sep 17 00:00:00 2001
+From: Steffan Karger <steffan.kar...@fox-it.com>
+Date: Tue, 25 Apr 2017 10:00:44 +0200
+Subject: [PATCH 2/2] Drop packets instead of asserting out if packet id rolls
+ over
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Previously, if a mode was selected where packet ids are not allowed to roll
+over, but renegotiation does not succeed for some reason (e.g. no password
+entered in time, certificate expired or a malicious peer that refuses the
+renegotiaion on purpose) we would continue to use the old keys.  Until the
+packet ID would roll over and we would ASSERT() out.
+
+Given that this can be triggered on purpose by an authenticated peer, this
+is a fix for an authenticated remote DoS vulnerability.  An attack is
+rather inefficient though; a peer would need to get us to send 2^32
+packets (min-size packet is IP+UDP+OPCODE+PID+TAG (no payload), results in
+(20+8+1+4+16)×2^32 bytes, or approx. 196 GB).
+
+Signed-off-by: Steffan Karger <steffan.kar...@fox-it.com>
+
+CVE-2017-7479
+
+---
+ src/openvpn/crypto.c                      | 25 ++++++++++++++++---------
+ src/openvpn/packet_id.c                   | 22 ++++++++++++++++------
+ src/openvpn/packet_id.h                   |  1 +
+ src/openvpn/tls_crypt.c                   |  6 +++++-
+ tests/unit_tests/openvpn/test_packet_id.c | 11 +++++++++--
+ 5 files changed, 47 insertions(+), 18 deletions(-)
+
+Index: openvpn-2.4.0/src/openvpn/crypto.c
+===================================================================
+--- openvpn-2.4.0.orig/src/openvpn/crypto.c
++++ openvpn-2.4.0/src/openvpn/crypto.c
+@@ -93,7 +93,11 @@ openvpn_encrypt_aead(struct buffer *buf,
+         buf_set_write(&iv_buffer, iv, iv_len);
+ 
+         /* IV starts with packet id to make the IV unique for packet */
+-        ASSERT(packet_id_write(&opt->packet_id.send, &iv_buffer, false, false));
++        if (!packet_id_write(&opt->packet_id.send, &iv_buffer, false, false))
++        {
++            msg(D_CRYPT_ERRORS, "ENCRYPT ERROR: packet ID roll over");
++            goto err;
++        }
+ 
+         /* Remainder of IV consists of implicit part (unique per session) */
+         ASSERT(buf_write(&iv_buffer, ctx->implicit_iv, ctx->implicit_iv_len));
+@@ -194,11 +198,13 @@ openvpn_encrypt_v1(struct buffer *buf, s
+                 }
+ 
+                 /* Put packet ID in plaintext buffer */
+-                if (packet_id_initialized(&opt->packet_id))
++                if (packet_id_initialized(&opt->packet_id)
++                    && !packet_id_write(&opt->packet_id.send, buf,
++                                        opt->flags & CO_PACKET_ID_LONG_FORM,
++                                        true))
+                 {
+-                    ASSERT(packet_id_write(&opt->packet_id.send, buf,
+-                                           opt->flags & CO_PACKET_ID_LONG_FORM,
+-                                           true));
++                    msg(D_CRYPT_ERRORS, "ENCRYPT ERROR: packet ID roll over");
++                    goto err;
+                 }
+             }
+             else if (cipher_kt_mode_ofb_cfb(cipher_kt))
+@@ -258,11 +264,12 @@ openvpn_encrypt_v1(struct buffer *buf, s
+         }
+         else                            /* No Encryption */
+         {
+-            if (packet_id_initialized(&opt->packet_id))
++            if (packet_id_initialized(&opt->packet_id)
++                && !packet_id_write(&opt->packet_id.send, buf,
++                                    opt->flags & CO_PACKET_ID_LONG_FORM, true))
+             {
+-                ASSERT(packet_id_write(&opt->packet_id.send, buf,
+-                        BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM),
+-                        true));
++                msg(D_CRYPT_ERRORS, "ENCRYPT ERROR: packet ID roll over");
++                goto err;
+             }
+             if (ctx->hmac)
+             {
+Index: openvpn-2.4.0/src/openvpn/packet_id.c
+===================================================================
+--- openvpn-2.4.0.orig/src/openvpn/packet_id.c
++++ openvpn-2.4.0/src/openvpn/packet_id.c
+@@ -325,27 +325,37 @@ packet_id_read(struct packet_id_net *pin
+     return true;
+ }
+ 
+-static void
++static bool
+ packet_id_send_update(struct packet_id_send *p, bool long_form)
+ {
+     if (!p->time)
+     {
+         p->time = now;
+     }
+-    p->id++;
+-    if (!p->id)
++    if (p->id == PACKET_ID_MAX)
+     {
+-        ASSERT(long_form);
++        /* Packet ID only allowed to roll over if using long form and time has
++         * moved forward since last roll over.
++         */
++        if (!long_form || now <= p->time)
++        {
++            return false;
++        }
+         p->time = now;
+-        p->id = 1;
++        p->id = 0;
+     }
++    p->id++;
++    return true;
+ }
+ 
+ bool
+ packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form,
+         bool prepend)
+ {
+-    packet_id_send_update(p, long_form);
++    if (!packet_id_send_update(p, long_form))
++    {
++        return false;
++    }
+ 
+     const packet_id_type net_id = htonpid(p->id);
+     const net_time_t net_time = htontime(p->time);
+Index: openvpn-2.4.0/src/openvpn/packet_id.h
+===================================================================
+--- openvpn-2.4.0.orig/src/openvpn/packet_id.h
++++ openvpn-2.4.0/src/openvpn/packet_id.h
+@@ -50,6 +50,7 @@
+  * to for network transmission.
+  */
+ typedef uint32_t packet_id_type;
++#define PACKET_ID_MAX UINT32_MAX
+ typedef uint32_t net_time_t;
+ 
+ /*
+Index: openvpn-2.4.0/src/openvpn/tls_crypt.c
+===================================================================
+--- openvpn-2.4.0.orig/src/openvpn/tls_crypt.c
++++ openvpn-2.4.0/src/openvpn/tls_crypt.c
+@@ -95,7 +95,11 @@ tls_crypt_wrap(const struct buffer *src,
+          format_hex(BPTR(src), BLEN(src), 80, &gc));
+ 
+     /* Get packet ID */
+-    ASSERT(packet_id_write(&opt->packet_id.send, dst, true, false));
++    if (!packet_id_write(&opt->packet_id.send, dst, true, false))
++    {
++        msg(D_CRYPT_ERRORS, "TLS-CRYPT ERROR: packet ID roll over.");
++        goto err;
++    }
+ 
+     dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP AD: %s",
+          format_hex(BPTR(dst), BLEN(dst), 0, &gc));
+Index: openvpn-2.4.0/tests/unit_tests/openvpn/test_packet_id.c
+===================================================================
+--- openvpn-2.4.0.orig/tests/unit_tests/openvpn/test_packet_id.c
++++ openvpn-2.4.0/tests/unit_tests/openvpn/test_packet_id.c
+@@ -129,8 +129,7 @@ test_packet_id_write_short_wrap(void **s
+     struct test_packet_id_write_data *data = *state;
+ 
+     data->pis.id = ~0;
+-    expect_assert_failure(
+-            packet_id_write(&data->pis, &data->test_buf, false, false));
++    assert_false(packet_id_write(&data->pis, &data->test_buf, false, false));
+ }
+ 
+ static void
+@@ -139,8 +138,16 @@ test_packet_id_write_long_wrap(void **st
+     struct test_packet_id_write_data *data = *state;
+ 
+     data->pis.id = ~0;
++    data->pis.time = 5006;
++
++    /* Write fails if time did not change */
++    now = 5006;
++    assert_false(packet_id_write(&data->pis, &data->test_buf, true, false));
++
++    /* Write succeeds if time moved forward */
+     now = 5010;
+     assert_true(packet_id_write(&data->pis, &data->test_buf, true, false));
++
+     assert(data->pis.id == 1);
+     assert(data->pis.time == now);
+     assert_true(data->test_buf_data.buf_id == htonl(1));
diff -Nru openvpn-2.4.0/debian/patches/CVE-2017-7479-prereq.patch openvpn-2.4.0/debian/patches/CVE-2017-7479-prereq.patch
--- openvpn-2.4.0/debian/patches/CVE-2017-7479-prereq.patch	1970-01-01 01:00:00.000000000 +0100
+++ openvpn-2.4.0/debian/patches/CVE-2017-7479-prereq.patch	2017-05-11 14:15:21.000000000 +0200
@@ -0,0 +1,443 @@
+From a87e1431baccd49a9344cfc63ab7446c4317fa2f Mon Sep 17 00:00:00 2001
+From: Steffan Karger <steffan.kar...@fox-it.com>
+Date: Fri, 5 May 2017 19:44:51 +0200
+Subject: [PATCH] cleanup: merge packet_id_alloc_outgoing() into
+ packet_id_write()
+
+The functions packet_id_alloc_outgoing() and packet_id_write() were
+always called in tandem.  Instead of forcing the caller to allocate a
+packet_id_net to do so, merge the two functions.  This simplifies the API
+and reduces the chance on mistakes in the future.
+
+This patch adds unit tests to verify the behaviour of packet_id_write().
+Verifying that we assert out correctly required the change to mock_msg.c.
+
+Signed-off-by: Steffan Karger <steffan.kar...@fox-it.com>
+Acked-by: Gert Doering <g...@greenie.muc.de>
+Acked-by: David Sommerseth <dav...@openvpn.net>
+Message-Id: <1494006291-3522-1-git-send-email-steffan.kar...@fox-it.com>
+URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14541.html
+Signed-off-by: Gert Doering <g...@greenie.muc.de>
+
+[prerequisite for CVE-2017-7479. Adjusted to apply to 2.4.0 release -- sbeattie]
+
+---
+ src/openvpn/crypto.c                      |  20 ++--
+ src/openvpn/packet_id.c                   |  24 ++++-
+ src/openvpn/packet_id.h                   |  35 +++----
+ src/openvpn/tls_crypt.c                   |   6 +-
+ tests/unit_tests/openvpn/Makefile.am      |  13 ++-
+ tests/unit_tests/openvpn/mock_msg.c       |  15 ++-
+ tests/unit_tests/openvpn/test_packet_id.c | 168 ++++++++++++++++++++++++++++++
+ 7 files changed, 228 insertions(+), 53 deletions(-)
+ create mode 100644 tests/unit_tests/openvpn/test_packet_id.c
+
+Index: openvpn-2.4.0/src/openvpn/crypto.c
+===================================================================
+--- openvpn-2.4.0.orig/src/openvpn/crypto.c
++++ openvpn-2.4.0/src/openvpn/crypto.c
+@@ -85,7 +85,6 @@ openvpn_encrypt_aead(struct buffer *buf,
+     /* Prepare IV */
+     {
+         struct buffer iv_buffer;
+-        struct packet_id_net pin;
+         uint8_t iv[OPENVPN_MAX_IV_LENGTH] = {0};
+         const int iv_len = cipher_ctx_iv_length(ctx->cipher);
+ 
+@@ -94,8 +93,7 @@ openvpn_encrypt_aead(struct buffer *buf,
+         buf_set_write(&iv_buffer, iv, iv_len);
+ 
+         /* IV starts with packet id to make the IV unique for packet */
+-        packet_id_alloc_outgoing(&opt->packet_id.send, &pin, false);
+-        ASSERT(packet_id_write(&pin, &iv_buffer, false, false));
++        ASSERT(packet_id_write(&opt->packet_id.send, &iv_buffer, false, false));
+ 
+         /* Remainder of IV consists of implicit part (unique per session) */
+         ASSERT(buf_write(&iv_buffer, ctx->implicit_iv, ctx->implicit_iv_len));
+@@ -198,23 +196,21 @@ openvpn_encrypt_v1(struct buffer *buf, s
+                 /* Put packet ID in plaintext buffer */
+                 if (packet_id_initialized(&opt->packet_id))
+                 {
+-                    struct packet_id_net pin;
+-                    packet_id_alloc_outgoing(&opt->packet_id.send, &pin, BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM));
+-                    ASSERT(packet_id_write(&pin, buf, BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM), true));
++                    ASSERT(packet_id_write(&opt->packet_id.send, buf,
++                                           opt->flags & CO_PACKET_ID_LONG_FORM,
++                                           true));
+                 }
+             }
+             else if (cipher_kt_mode_ofb_cfb(cipher_kt))
+             {
+-                struct packet_id_net pin;
+                 struct buffer b;
+ 
+                 /* IV and packet-ID required for this mode. */
+                 ASSERT(opt->flags & CO_USE_IV);
+                 ASSERT(packet_id_initialized(&opt->packet_id));
+ 
+-                packet_id_alloc_outgoing(&opt->packet_id.send, &pin, true);
+                 buf_set_write(&b, iv_buf, iv_size);
+-                ASSERT(packet_id_write(&pin, &b, true, false));
++                ASSERT(packet_id_write(&opt->packet_id.send, &b, true, false));
+             }
+             else /* We only support CBC, CFB, or OFB modes right now */
+             {
+@@ -264,9 +260,9 @@ openvpn_encrypt_v1(struct buffer *buf, s
+         {
+             if (packet_id_initialized(&opt->packet_id))
+             {
+-                struct packet_id_net pin;
+-                packet_id_alloc_outgoing(&opt->packet_id.send, &pin, BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM));
+-                ASSERT(packet_id_write(&pin, buf, BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM), true));
++                ASSERT(packet_id_write(&opt->packet_id.send, buf,
++                        BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM),
++                        true));
+             }
+             if (ctx->hmac)
+             {
+Index: openvpn-2.4.0/src/openvpn/packet_id.c
+===================================================================
+--- openvpn-2.4.0.orig/src/openvpn/packet_id.c
++++ openvpn-2.4.0/src/openvpn/packet_id.c
+@@ -325,12 +325,30 @@ packet_id_read(struct packet_id_net *pin
+     return true;
+ }
+ 
++static void
++packet_id_send_update(struct packet_id_send *p, bool long_form)
++{
++    if (!p->time)
++    {
++        p->time = now;
++    }
++    p->id++;
++    if (!p->id)
++    {
++        ASSERT(long_form);
++        p->time = now;
++        p->id = 1;
++    }
++}
++
+ bool
+-packet_id_write(const struct packet_id_net *pin, struct buffer *buf, bool long_form, bool prepend)
++packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form,
++        bool prepend)
+ {
+-    packet_id_type net_id = htonpid(pin->id);
+-    net_time_t net_time = htontime(pin->time);
++    packet_id_send_update(p, long_form);
+ 
++    const packet_id_type net_id = htonpid(p->id);
++    const net_time_t net_time = htontime(p->time);
+     if (prepend)
+     {
+         if (long_form)
+Index: openvpn-2.4.0/src/openvpn/packet_id.h
+===================================================================
+--- openvpn-2.4.0.orig/src/openvpn/packet_id.h
++++ openvpn-2.4.0/src/openvpn/packet_id.h
+@@ -254,7 +254,18 @@ const char *packet_id_persist_print(cons
+ 
+ bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form);
+ 
+-bool packet_id_write(const struct packet_id_net *pin, struct buffer *buf, bool long_form, bool prepend);
++/**
++ * Write a packet ID to buf, and update the packet ID state.
++ *
++ * @param p             Packet ID state.
++ * @param buf           Buffer to write the packet ID too
++ * @param long_form     If true, also update and write time_t to buf
++ * @param prepend       If true, prepend to buffer, otherwise apppend.
++ *
++ * @return true if successful, false otherwise.
++ */
++bool packet_id_write(struct packet_id_send *p, struct buffer *buf,
++        bool long_form, bool prepend);
+ 
+ /*
+  * Inline functions.
+@@ -304,28 +315,6 @@ packet_id_close_to_wrapping(const struct
+     return p->id >= PACKET_ID_WRAP_TRIGGER;
+ }
+ 
+-/*
+- * Allocate an outgoing packet id.
+- * Sequence number ranges from 1 to 2^32-1.
+- * In long_form, a time_t is added as well.
+- */
+-static inline void
+-packet_id_alloc_outgoing(struct packet_id_send *p, struct packet_id_net *pin, bool long_form)
+-{
+-    if (!p->time)
+-    {
+-        p->time = now;
+-    }
+-    pin->id = ++p->id;
+-    if (!pin->id)
+-    {
+-        ASSERT(long_form);
+-        p->time = now;
+-        pin->id = p->id = 1;
+-    }
+-    pin->time = p->time;
+-}
+-
+ static inline bool
+ check_timestamp_delta(time_t remote, unsigned int max_delta)
+ {
+Index: openvpn-2.4.0/src/openvpn/tls_crypt.c
+===================================================================
+--- openvpn-2.4.0.orig/src/openvpn/tls_crypt.c
++++ openvpn-2.4.0/src/openvpn/tls_crypt.c
+@@ -95,11 +95,7 @@ tls_crypt_wrap(const struct buffer *src,
+          format_hex(BPTR(src), BLEN(src), 80, &gc));
+ 
+     /* Get packet ID */
+-    {
+-        struct packet_id_net pin;
+-        packet_id_alloc_outgoing(&opt->packet_id.send, &pin, true);
+-        packet_id_write(&pin, dst, true, false);
+-    }
++    ASSERT(packet_id_write(&opt->packet_id.send, dst, true, false));
+ 
+     dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP AD: %s",
+          format_hex(BPTR(dst), BLEN(dst), 0, &gc));
+Index: openvpn-2.4.0/tests/unit_tests/openvpn/Makefile.am
+===================================================================
+--- openvpn-2.4.0.orig/tests/unit_tests/openvpn/Makefile.am
++++ openvpn-2.4.0/tests/unit_tests/openvpn/Makefile.am
+@@ -1,6 +1,6 @@
+ AUTOMAKE_OPTIONS = foreign
+ 
+-check_PROGRAMS = argv_testdriver buffer_testdriver
++check_PROGRAMS = argv_testdriver buffer_testdriver packet_id_testdriver
+ 
+ if ENABLE_CRYPTO
+ check_PROGRAMS += tls_crypt_testdriver
+@@ -27,6 +27,17 @@ buffer_testdriver_SOURCES = test_buffer.
+ 	$(openvpn_srcdir)/buffer.c \
+ 	$(openvpn_srcdir)/platform.c
+ 
++packet_id_testdriver_CFLAGS  = @TEST_CFLAGS@ \
++	-I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \
++	$(OPTIONAL_CRYPTO_CFLAGS)
++packet_id_testdriver_LDFLAGS = @TEST_LDFLAGS@ \
++	$(OPTIONAL_CRYPTO_LIBS)
++packet_id_testdriver_SOURCES = test_packet_id.c mock_msg.c \
++	$(openvpn_srcdir)/buffer.c \
++	$(openvpn_srcdir)/otime.c \
++	$(openvpn_srcdir)/packet_id.c \
++	$(openvpn_srcdir)/platform.c
++
+ tls_crypt_testdriver_CFLAGS  = @TEST_CFLAGS@ \
+ 	-I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \
+ 	$(OPTIONAL_CRYPTO_CFLAGS)
+Index: openvpn-2.4.0/tests/unit_tests/openvpn/mock_msg.c
+===================================================================
+--- openvpn-2.4.0.orig/tests/unit_tests/openvpn/mock_msg.c
++++ openvpn-2.4.0/tests/unit_tests/openvpn/mock_msg.c
+@@ -29,9 +29,12 @@
+ #endif
+ 
+ #include <stdarg.h>
+-#include <stdbool.h>
++#include <stddef.h>
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <setjmp.h>
++#include <cmocka.h>
++
+ 
+ #include "errlevel.h"
+ #include "error.h"
+@@ -70,14 +73,8 @@ x_msg(const unsigned int flags, const ch
+ void
+ assert_failed(const char *filename, int line, const char *condition)
+ {
+-    if (condition)
+-    {
+-        printf("Assertion failed at %s:%d (%s)", filename, line, condition);
+-    }
+-    else
+-    {
+-        printf("Assertion failed at %s:%d", filename, line);
+-    }
++    mock_assert(false, condition ? condition : "", filename, line);
++    /* Keep compiler happy.  Should not happen, mock_assert() does not return */
+     exit(1);
+ }
+ 
+Index: openvpn-2.4.0/tests/unit_tests/openvpn/test_packet_id.c
+===================================================================
+--- /dev/null
++++ openvpn-2.4.0/tests/unit_tests/openvpn/test_packet_id.c
+@@ -0,0 +1,168 @@
++/*
++ *  OpenVPN -- An application to securely tunnel IP networks
++ *             over a single UDP port, with support for SSL/TLS-based
++ *             session authentication and key exchange,
++ *             packet encryption, packet authentication, and
++ *             packet compression.
++ *
++ *  Copyright (C) 2016 Fox Crypto B.V. <open...@fox-it.com>
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License version 2
++ *  as published by the Free Software Foundation.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program (see the file COPYING included with this
++ *  distribution); if not, write to the Free Software Foundation, Inc.,
++ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#elif defined(_MSC_VER)
++#include "config-msvc.h"
++#endif
++
++#include "syshead.h"
++
++#include <stdarg.h>
++#include <stddef.h>
++#include <setjmp.h>
++#include <cmocka.h>
++
++#include "packet_id.h"
++
++#include "mock_msg.h"
++
++struct test_packet_id_write_data {
++    struct {
++        uint32_t buf_id;
++        uint32_t buf_time;
++    } test_buf_data;
++    struct buffer test_buf;
++    struct packet_id_send pis;
++};
++
++static int
++test_packet_id_write_setup(void **state) {
++    struct test_packet_id_write_data *data =
++            calloc(1, sizeof(struct test_packet_id_write_data));
++
++    if (!data)
++    {
++        return -1;
++    }
++
++    data->test_buf.data = (void *) &data->test_buf_data;
++    data->test_buf.capacity = sizeof(data->test_buf_data);
++
++    *state = data;
++    return 0;
++}
++
++static int
++test_packet_id_write_teardown(void **state) {
++    free(*state);
++    return 0;
++}
++
++static void
++test_packet_id_write_short(void **state)
++{
++    struct test_packet_id_write_data *data = *state;
++
++    now = 5010;
++    assert_true(packet_id_write(&data->pis, &data->test_buf, false, false));
++    assert_true(data->pis.id == 1);
++    assert_true(data->test_buf_data.buf_id == htonl(1));
++    assert_true(data->test_buf_data.buf_time == 0);
++}
++
++static void
++test_packet_id_write_long(void **state)
++{
++    struct test_packet_id_write_data *data = *state;
++
++    now = 5010;
++    assert_true(packet_id_write(&data->pis, &data->test_buf, true, false));
++    assert(data->pis.id == 1);
++    assert(data->pis.time == now);
++    assert_true(data->test_buf_data.buf_id == htonl(1));
++    assert_true(data->test_buf_data.buf_time == htonl(now));
++}
++
++static void
++test_packet_id_write_short_prepend(void **state)
++{
++    struct test_packet_id_write_data *data = *state;
++
++    data->test_buf.offset = sizeof(packet_id_type);
++    now = 5010;
++    assert_true(packet_id_write(&data->pis, &data->test_buf, false, true));
++    assert_true(data->pis.id == 1);
++    assert_true(data->test_buf_data.buf_id == htonl(1));
++    assert_true(data->test_buf_data.buf_time == 0);
++}
++
++static void
++test_packet_id_write_long_prepend(void **state)
++{
++    struct test_packet_id_write_data *data = *state;
++
++    data->test_buf.offset = sizeof(data->test_buf_data);
++    now = 5010;
++    assert_true(packet_id_write(&data->pis, &data->test_buf, true, true));
++    assert(data->pis.id == 1);
++    assert(data->pis.time == now);
++    assert_true(data->test_buf_data.buf_id == htonl(1));
++    assert_true(data->test_buf_data.buf_time == htonl(now));
++}
++
++static void
++test_packet_id_write_short_wrap(void **state)
++{
++    struct test_packet_id_write_data *data = *state;
++
++    data->pis.id = ~0;
++    expect_assert_failure(
++            packet_id_write(&data->pis, &data->test_buf, false, false));
++}
++
++static void
++test_packet_id_write_long_wrap(void **state)
++{
++    struct test_packet_id_write_data *data = *state;
++
++    data->pis.id = ~0;
++    now = 5010;
++    assert_true(packet_id_write(&data->pis, &data->test_buf, true, false));
++    assert(data->pis.id == 1);
++    assert(data->pis.time == now);
++    assert_true(data->test_buf_data.buf_id == htonl(1));
++    assert_true(data->test_buf_data.buf_time == htonl(now));
++}
++
++int
++main(void) {
++    const struct CMUnitTest tests[] = {
++            cmocka_unit_test_setup_teardown(test_packet_id_write_short,
++                    test_packet_id_write_setup, test_packet_id_write_teardown),
++            cmocka_unit_test_setup_teardown(test_packet_id_write_long,
++                    test_packet_id_write_setup, test_packet_id_write_teardown),
++            cmocka_unit_test_setup_teardown(test_packet_id_write_short_prepend,
++                    test_packet_id_write_setup, test_packet_id_write_teardown),
++            cmocka_unit_test_setup_teardown(test_packet_id_write_long_prepend,
++                    test_packet_id_write_setup, test_packet_id_write_teardown),
++            cmocka_unit_test_setup_teardown(test_packet_id_write_short_wrap,
++                    test_packet_id_write_setup, test_packet_id_write_teardown),
++            cmocka_unit_test_setup_teardown(test_packet_id_write_long_wrap,
++                    test_packet_id_write_setup, test_packet_id_write_teardown),
++    };
++
++    return cmocka_run_group_tests_name("packet_id tests", tests, NULL, NULL);
++}
diff -Nru openvpn-2.4.0/debian/patches/match-manpage-and-command-help.patch openvpn-2.4.0/debian/patches/match-manpage-and-command-help.patch
--- openvpn-2.4.0/debian/patches/match-manpage-and-command-help.patch	1970-01-01 01:00:00.000000000 +0100
+++ openvpn-2.4.0/debian/patches/match-manpage-and-command-help.patch	2017-05-11 14:12:03.000000000 +0200
@@ -0,0 +1,25 @@
+From a88d8ba3e81ca34fc2675805a273cd85875c8973 Mon Sep 17 00:00:00 2001
+From: Arne Schwabe <a...@rfc2549.org>
+Date: Wed, 4 Jan 2017 19:18:46 +0100
+Subject: [PATCH] Change command help to match man page and implementation
+
+---
+ src/openvpn/options.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/openvpn/options.c b/src/openvpn/options.c
+index bfedb6a..80143e6 100644
+--- a/src/openvpn/options.c
++++ b/src/openvpn/options.c
+@@ -198,7 +198,7 @@ static const char usage_message[] =
+     "                  is established.  Multiple routes can be specified.\n"
+     "                  netmask default: 255.255.255.255\n"
+     "                  gateway default: taken from --route-gateway or --ifconfig\n"
+-    "                  Specify default by leaving blank or setting to \"nil\".\n"
++    "                  Specify default by leaving blank or setting to \"default\".\n"
+     "--route-ipv6 network/bits [gateway] [metric] :\n"
+     "                  Add IPv6 route to routing table after connection\n"
+     "                  is established.  Multiple routes can be specified.\n"
+-- 
+2.10.1 (Apple Git-78)
+
diff -Nru openvpn-2.4.0/debian/patches/route_default_nil.patch openvpn-2.4.0/debian/patches/route_default_nil.patch
--- openvpn-2.4.0/debian/patches/route_default_nil.patch	2016-11-21 09:54:08.000000000 +0100
+++ openvpn-2.4.0/debian/patches/route_default_nil.patch	1970-01-01 01:00:00.000000000 +0100
@@ -1,15 +0,0 @@
-Description: Fix small wording in man page.
-Author: Alberto Gonzalez Iniesta <a...@inittab.org>
-Index: openvpn/doc/openvpn.8
-===================================================================
---- openvpn.orig/doc/openvpn.8	2016-11-21 09:54:04.404957249 +0100
-+++ openvpn/doc/openvpn.8	2016-11-21 09:54:04.400957231 +0100
-@@ -973,7 +973,7 @@
- otherwise 0.
- 
- The default can be specified by leaving an option blank or setting
--it to "default".
-+it to "nil".
- 
- The
- .B network
diff -Nru openvpn-2.4.0/debian/patches/series openvpn-2.4.0/debian/patches/series
--- openvpn-2.4.0/debian/patches/series	2016-12-27 18:46:31.000000000 +0100
+++ openvpn-2.4.0/debian/patches/series	2017-05-11 14:15:21.000000000 +0200
@@ -1,5 +1,9 @@
 auth-pam_libpam_so_filename.patch
 debian_nogroup_for_sample_files.patch
 openvpn-pkcs11warn.patch
-route_default_nil.patch
 kfreebsd_support.patch
+match-manpage-and-command-help.patch
+CVE-2017-7478.patch
+CVE-2017-7479-prereq.patch
+CVE-2017-7479.patch
+wipe_tokens_on_de-auth.patch
diff -Nru openvpn-2.4.0/debian/patches/wipe_tokens_on_de-auth.patch openvpn-2.4.0/debian/patches/wipe_tokens_on_de-auth.patch
--- openvpn-2.4.0/debian/patches/wipe_tokens_on_de-auth.patch	1970-01-01 01:00:00.000000000 +0100
+++ openvpn-2.4.0/debian/patches/wipe_tokens_on_de-auth.patch	2017-05-11 14:15:21.000000000 +0200
@@ -0,0 +1,118 @@
+From daab0a9fa8ff4f40e8a34707db0ac156d49fbfcb Mon Sep 17 00:00:00 2001
+From: David Sommerseth <dav...@openvpn.net>
+Date: Tue, 28 Mar 2017 22:53:46 +0200
+Subject: [PATCH] auth-token: Ensure tokens are always wiped on de-auth
+
+If tls_deauthenticate() was called, it could in some scenarios leave the
+authentication token for a session in memory.  This change just ensures
+auth-tokens are always wiped as soon as a TLS session is considered
+broken.
+
+Signed-off-by: David Sommerseth <dav...@openvpn.net>
+
+Acked-by: Steffan Karger <stef...@karger.me>
+Message-Id: <20170328205346.18844-1-dav...@openvpn.net>
+URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14344.html
+Signed-off-by: David Sommerseth <dav...@openvpn.net>
+---
+ src/openvpn/ssl_verify.c | 47 +++++++++++++++++++++++++++--------------------
+ 1 file changed, 27 insertions(+), 20 deletions(-)
+
+Index: openvpn-2.4.0/src/openvpn/ssl_verify.c
+===================================================================
+--- openvpn-2.4.0.orig/src/openvpn/ssl_verify.c
++++ openvpn-2.4.0/src/openvpn/ssl_verify.c
+@@ -80,6 +80,28 @@ setenv_untrusted(struct tls_session *ses
+     setenv_link_socket_actual(session->opt->es, "untrusted", &session->untrusted_addr, SA_IP_PORT);
+ }
+ 
++
++/**
++ *  Wipes the authentication token out of the memory, frees and cleans up related buffers and flags
++ *
++ *  @param multi  Pointer to a multi object holding the auth_token variables
++ */
++static void
++wipe_auth_token(struct tls_multi *multi)
++{
++    if(multi)
++    {
++        if (multi->auth_token)
++        {
++            secure_memzero(multi->auth_token, AUTH_TOKEN_SIZE);
++            free(multi->auth_token);
++        }
++        multi->auth_token = NULL;
++        multi->auth_token_sent = false;
++    }
++}
++
++
+ /*
+  * Remove authenticated state from all sessions in the given tunnel
+  */
+@@ -88,10 +110,14 @@ tls_deauthenticate(struct tls_multi *mul
+ {
+     if (multi)
+     {
+-        int i, j;
+-        for (i = 0; i < TM_SIZE; ++i)
+-            for (j = 0; j < KS_SIZE; ++j)
++        wipe_auth_token(multi);
++        for (int i = 0; i < TM_SIZE; ++i)
++        {
++            for (int j = 0; j < KS_SIZE; ++j)
++            {
+                 multi->session[i].key[j].authenticated = false;
++            }
++        }
+     }
+ }
+ 
+@@ -1213,21 +1239,6 @@ verify_user_pass_management(struct tls_s
+ }
+ #endif /* ifdef MANAGEMENT_DEF_AUTH */
+ 
+-/**
+- *  Wipes the authentication token out of the memory, frees and cleans up related buffers and flags
+- *
+- *  @param multi  Pointer to a multi object holding the auth_token variables
+- */
+-static void
+-wipe_auth_token(struct tls_multi *multi)
+-{
+-    secure_memzero(multi->auth_token, AUTH_TOKEN_SIZE);
+-    free(multi->auth_token);
+-    multi->auth_token = NULL;
+-    multi->auth_token_sent = false;
+-}
+-
+-
+ /*
+  * Main username/password verification entry point
+  */
+@@ -1279,7 +1290,7 @@ verify_user_pass(struct user_pass *up, s
+         /* Ensure that the username has not changed */
+         if (!tls_lock_username(multi, up->username))
+         {
+-            wipe_auth_token(multi);
++            /* auth-token cleared in tls_lock_username() on failure */
+             ks->authenticated = false;
+             goto done;
+         }
+@@ -1300,7 +1311,6 @@ verify_user_pass(struct user_pass *up, s
+         if (memcmp_constant_time(multi->auth_token, up->password,
+                                  strlen(multi->auth_token)) != 0)
+         {
+-            wipe_auth_token(multi);
+             ks->authenticated = false;
+             tls_deauthenticate(multi);
+ 
+@@ -1472,6 +1482,7 @@ verify_final_auth_checks(struct tls_mult
+         if (!cn || !strcmp(cn, CCD_DEFAULT) || !test_file(path))
+         {
+             ks->authenticated = false;
++            wipe_auth_token(multi);
+             msg(D_TLS_ERRORS, "TLS Auth Error: --client-config-dir authentication failed for common name '%s' file='%s'",
+                 session->common_name,
+                 path ? path : "UNDEF");

--- End Message ---
--- Begin Message ---
Unblocked openvpn.

--- End Message ---

Reply via email to