[Openvpn-devel,v4,12/35] dco: check that pulled options are compatible

Message ID 20220804064016.20414-1-a@unstable.cc
State Accepted
Headers show
Series None | expand

Commit Message

Antonio Quartulli Aug. 3, 2022, 8:40 p.m. UTC
A server may push options that are not compatible with DCO.
In this case we should log a message and bail out.

Signed-off-by: Antonio Quartulli <a@unstable.cc>
---

Changes from v3:
* move pull-option-check to before opening the tun device, for earlier
  bail out
* fix typ0 in error message (missing blank)

Changes from v2:
* split if condition on two lines

Changes from v1:
* move check_dco_pull_options() to dco.c (renamed to
  dco_check_pull_options())
* make options argument const
* add msglevel as first argument
---
 src/openvpn/dco.c  | 12 ++++++++++++
 src/openvpn/dco.h  | 17 +++++++++++++++++
 src/openvpn/init.c |  9 +++++++++
 3 files changed, 38 insertions(+)

Comments

Gert Doering Aug. 3, 2022, 11:47 p.m. UTC | #1
Acked-by: Gert Doering <gert@greenie.muc.de>

Thanks for shuffling this around a bit :-)

Tis is the same code change as v3, with a bit of reformatting in the
message and comment, and it's applied in "part1" now (do_deferred_options()).

Does nothing if DCO is not available (not compiled in / no kernel support),
does the right thing on DCO active with "--pull-filter ignore peer-id":

2022-08-04 10:30:38 Pushed option removed by filter: 'peer-id 0'
2022-08-04 10:30:38 OPTIONS IMPORT: timers and/or timeouts modified
2022-08-04 10:30:38 OPTIONS IMPORT: compression parms modified
2022-08-04 10:30:38 OPTIONS IMPORT: --ifconfig/up options modified
2022-08-04 10:30:38 OPTIONS IMPORT: route options modified
2022-08-04 10:30:38 OPTIONS IMPORT: data channel crypto options modified
2022-08-04 10:30:38 OPTIONS IMPORT: Server did not request DATA_V2 packet format required for data channel offload
2022-08-04 10:30:38 OPTIONS ERROR: pushed options are incompatible with data channel offload. Use --disable-dco to connect to this server
2022-08-04 10:30:38 ERROR: Failed to apply push options


As discused on IRC, I have changed D_TLS_ERRORS to D_PUSH_ERRORS - which
is also "level 1", but fits the intent better.

Your patch has been applied to the master branch.

commit 46f6a7e8b6daf02bebe4a46498665274f1673ac0
Author: Antonio Quartulli
Date:   Thu Aug 4 08:40:16 2022 +0200

     dco: check that pulled options are compatible

     Signed-off-by: Antonio Quartulli <a@unstable.cc>
     Acked-by: Gert Doering <gert@greenie.muc.de>
     Message-Id: <20220804064016.20414-1-a@unstable.cc>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24797.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c
index b92a0e9c..8c22b7ea 100644
--- a/src/openvpn/dco.c
+++ b/src/openvpn/dco.c
@@ -370,4 +370,16 @@  dco_check_option_conflict(int msglevel, const struct options *o)
     return true;
 }
 
+bool
+dco_check_pull_options(int msglevel, const struct options *o)
+{
+    if (!o->use_peer_id)
+    {
+        msg(msglevel, "OPTIONS IMPORT: Server did not request DATA_V2 packet "
+            "format required for data channel offload");
+        return false;
+    }
+    return true;
+}
+
 #endif /* defined(ENABLE_DCO) */
diff --git a/src/openvpn/dco.h b/src/openvpn/dco.h
index b926e236..fbb35906 100644
--- a/src/openvpn/dco.h
+++ b/src/openvpn/dco.h
@@ -65,6 +65,17 @@  bool dco_available(int msglevel);
  */
 bool dco_check_option_conflict(int msglevel, const struct options *o);
 
+/**
+ * Check whether any of the options pushed by the server is not supported by
+ * our current dco implementation. If so print a warning at warning level
+ * for the first conflicting option found and return false.
+ *
+ * @param msglevel  the msg level to use to print the warnings
+ * @param o         the options struct that hold the options
+ * @return          true if no conflict was detected, false otherwise
+ */
+bool dco_check_pull_options(int msglevel, const struct options *o);
+
 /**
  * Initialize the DCO context
  *
@@ -156,6 +167,12 @@  dco_check_option_conflict(int msglevel, const struct options *o)
     return false;
 }
 
+static inline bool
+dco_check_pull_options(int msglevel, const struct options *o)
+{
+    return false;
+}
+
 static inline bool
 ovpn_dco_init(int mode, dco_context_t *dco)
 {
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index de8faeb4..4423e162 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -2382,6 +2382,15 @@  do_deferred_options(struct context *c, const unsigned int found)
         }
     }
 
+    /* Check if pushed options are compatible with DCO, if enabled */
+    if (dco_enabled(&c->options)
+        && !dco_check_pull_options(D_TLS_ERRORS, &c->options))
+    {
+        msg(D_TLS_ERRORS, "OPTIONS ERROR: pushed options are incompatible with "
+            "data channel offload. Use --disable-dco to connect to this server");
+        return false;
+    }
+
     return true;
 }