Skip to contentSkip to conversation

Fix problems with NCP and --inetd.

PATCH Superseded Gert Doering 3 participants 5 messages Aug 22, 2016 – Aug 23, 2016

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix problems with NCP and --inetd.

NCP only works with --pull or --mode server, leading to breakage in --inetd mode (because that has --tls-server, but not --mode server, but clients can still ask for PUSH_REQUEST).

Fix by turning off o->ncp_enable unless (pull or mode server), and double-fix by logging an appropriate message and refusing to change ciphers if the server has already set up its keys.

Trac #715

---
 src/openvpn/options.c |  8 ++++++++
 src/openvpn/push.c    | 21 ++++++++++++++++-----
 2 files changed, 24 insertions(+), 5 deletions(-)
src/openvpn/options.c +8 -0
index c100d4c..a2b22f4 100644
@@ -2614,6 +2614,14 @@ options_postprocess_mutate (struct options *o)
       if (streq (o->dh_file, "none"))
 	o->dh_file = NULL;
     }
+
+  /* cipher negotiation (NCP) currently assumes --pull or --mode server */
+  if ( o->ncp_enabled &&
+        ! (o->pull || o->mode == MODE_SERVER) )
+    {
+      msg( M_WARN, "disabling NCP mode (--ncp-disable) because not in P2MP client or server mode" );
+      o->ncp_enabled = false;
+    }
 #endif
 
 #if ENABLE_MANAGEMENT
src/openvpn/push.c +16 -5
index 000c82f..4bdede9 100644
@@ -321,11 +321,22 @@ prepare_push_reply (struct options *o, struct tls_multi *tls_multi)
   /* Push cipher if client supports Negotiable Crypto Parameters */
   if (tls_peer_info_ncp_ver (peer_info) >= 2 && o->ncp_enabled)
     {
-      /* Push the first cipher from --ncp-ciphers to the client.
-       * TODO: actual negotiation, instead of server dictatorship. */
-      char *push_cipher = string_alloc(o->ncp_ciphers, &o->gc);
-      o->ciphername = strtok (push_cipher, ":");
-      push_option_fmt(o, M_USAGE, "cipher %s", o->ciphername);
+      /* if we have already created our key, we cannot change our own
+       * cipher, so disable NCP and warn = explain why
+       */
+      struct tls_session *session = &tls_multi->session[TM_ACTIVE];
+      if ( session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized )
+	{
+	   msg( M_INFO, "PUSH: client wants to negotiate cipher (NCP), but server has already generated data channel keys, ignoring client request" );
+	}
+      else
+	{
+	  /* Push the first cipher from --ncp-ciphers to the client.
+	   * TODO: actual negotiation, instead of server dictatorship. */
+	  char *push_cipher = string_alloc(o->ncp_ciphers, &o->gc);
+	  o->ciphername = strtok (push_cipher, ":");
+	  push_option_fmt(o, M_USAGE, "cipher %s", o->ciphername);
+	}
     }
   return true;
 }
Signature · 1 line
2.7.3
#1 lore raw
Quoted 68 lines · Gert Doering

NCP only works with --pull or --mode server, leading to breakage in --inetd mode (because that has --tls-server, but not --mode server, but clients can still ask for PUSH_REQUEST).

Fix by turning off o->ncp_enable unless (pull or mode server), and double-fix by logging an appropriate message and refusing to change ciphers if the server has already set up its keys.

Trac #715

---
 src/openvpn/options.c |  8 ++++++++
 src/openvpn/push.c    | 21 ++++++++++++++++-----
 2 files changed, 24 insertions(+), 5 deletions(-)
src/openvpn/options.c +8 -0
index c100d4c..a2b22f4 100644
@@ -2614,6 +2614,14 @@ options_postprocess_mutate (struct options *o)
       if (streq (o->dh_file, "none"))
        o->dh_file = NULL;
     }
+
+  /* cipher negotiation (NCP) currently assumes --pull or --mode server */
+  if ( o->ncp_enabled &&
+        ! (o->pull || o->mode == MODE_SERVER) )
+    {
+      msg( M_WARN, "disabling NCP mode (--ncp-disable) because not in P2MP client or server mode" );
+      o->ncp_enabled = false;
+    }
 #endif
 
 #if ENABLE_MANAGEMENT
src/openvpn/push.c +16 -6
index 000c82f..4bdede9 100644
@@ -321,11 +321,22 @@ prepare_push_reply (struct options *o, struct tls_multi *tls_multi)
   /* Push cipher if client supports Negotiable Crypto Parameters */
   if (tls_peer_info_ncp_ver (peer_info) >= 2 && o->ncp_enabled)
     {
-      /* Push the first cipher from --ncp-ciphers to the client.
-       * TODO: actual negotiation, instead of server dictatorship. */
-      char *push_cipher = string_alloc(o->ncp_ciphers, &o->gc);
-      o->ciphername = strtok (push_cipher, ":");
-      push_option_fmt(o, M_USAGE, "cipher %s", o->ciphername);
+      /* if we have already created our key, we cannot change our own
+       * cipher, so disable NCP and warn = explain why
+       */
+      struct tls_session *session = &tls_multi->session[TM_ACTIVE];
+      if ( session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized )
+       {
+          msg( M_INFO, "PUSH: client wants to negotiate cipher (NCP), but server has already generated data channel keys, ignoring client request" );
+       }
+      else
+       {
+         /* Push the first cipher from --ncp-ciphers to the client.
+          * TODO: actual negotiation, instead of server dictatorship. */
+         char *push_cipher = string_alloc(o->ncp_ciphers, &o->gc);
+         o->ciphername = strtok (push_cipher, ":");
+         push_option_fmt(o, M_USAGE, "cipher %s", o->ciphername);
+       }
     }
   return true;
 }
--
Quoted 1 line

2.7.3

I'd suggest to wrap the long lines, but otherwise this looks good. So, ACK.

-Steffan

#2 lore raw

PATCH v2 1/1 Fix problems with NCP and --inetd.

In reply to Gert Doering

NCP only works with --pull or --mode server, leading to breakage in --inetd mode (because that has --tls-server, but not --mode server, but clients can still ask for PUSH_REQUEST).

Fix by turning off o->ncp_enable unless (pull or mode server), and double-fix by logging an appropriate message and refusing to change ciphers if the server has already set up its keys.

v2: wrap long msg() text lines

Trac #715

---
 src/openvpn/options.c |  9 +++++++++
 src/openvpn/push.c    | 23 ++++++++++++++++++-----
 2 files changed, 27 insertions(+), 5 deletions(-)
src/openvpn/options.c +9 -0
index c100d4c..e052042 100644
@@ -2614,6 +2614,15 @@ options_postprocess_mutate (struct options *o)
       if (streq (o->dh_file, "none"))
 	o->dh_file = NULL;
     }
+
+  /* cipher negotiation (NCP) currently assumes --pull or --mode server */
+  if ( o->ncp_enabled &&
+        ! (o->pull || o->mode == MODE_SERVER) )
+    {
+      msg( M_WARN, "disabling NCP mode (--ncp-disable) because not "
+                   "in P2MP client or server mode" );
+      o->ncp_enabled = false;
+    }
 #endif
 
 #if ENABLE_MANAGEMENT
src/openvpn/push.c +18 -5
index 000c82f..a1b999e 100644
@@ -321,11 +321,24 @@ prepare_push_reply (struct options *o, struct tls_multi *tls_multi)
   /* Push cipher if client supports Negotiable Crypto Parameters */
   if (tls_peer_info_ncp_ver (peer_info) >= 2 && o->ncp_enabled)
     {
-      /* Push the first cipher from --ncp-ciphers to the client.
-       * TODO: actual negotiation, instead of server dictatorship. */
-      char *push_cipher = string_alloc(o->ncp_ciphers, &o->gc);
-      o->ciphername = strtok (push_cipher, ":");
-      push_option_fmt(o, M_USAGE, "cipher %s", o->ciphername);
+      /* if we have already created our key, we cannot change our own
+       * cipher, so disable NCP and warn = explain why
+       */
+      struct tls_session *session = &tls_multi->session[TM_ACTIVE];
+      if ( session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized )
+	{
+	   msg( M_INFO, "PUSH: client wants to negotiate cipher (NCP), but "
+			"server has already generated data channel keys, "
+			"ignoring client request" );
+	}
+      else
+	{
+	  /* Push the first cipher from --ncp-ciphers to the client.
+	   * TODO: actual negotiation, instead of server dictatorship. */
+	  char *push_cipher = string_alloc(o->ncp_ciphers, &o->gc);
+	  o->ciphername = strtok (push_cipher, ":");
+	  push_option_fmt(o, M_USAGE, "cipher %s", o->ciphername);
+	}
     }
   return true;
 }
Signature · 1 line
2.7.3
#3 lore raw
Quoted 1 line · Gert Doering

v2: wrap long msg() text lines

Thanks. ACK.

-Steffan

#4 lore raw
In reply to Gert Doering

Your patch has been applied to the master branch.

commit d90249f73353c175ed9e7dd0a450cd084a729e20

Author: Gert Doering
Date:   Mon Aug 22 22:24:47 2016 +0200
     Fix problems with NCP and --inetd.

     Trac: 715
     Signed-off-by: Gert Doering <[email protected]...>
     Acked-by: Steffan Karger <[email protected]...>
     Message-Id: [email protected]...
     URL: https://www.mail-archive.com/[email protected]/msg00060.html
     Signed-off-by: David Sommerseth <[email protected]...>

--
kind regards,

David Sommerseth