[Libguestfs] [PATCH libnbd 1/2] api: Add new API to read whether TLS was negotiated.

Richard W.M. Jones rjones at redhat.com
Tue Sep 17 10:02:32 UTC 2019


When LIBNBD_TLS_ALLOW is used we don't have a way to find out if TLS
was really negotiated.  This adds a flag and a way to read it back.

Unfortunately there is no test yet, because LIBNBD_TLS_ALLOW is not
tested -- it really should be but requires quite a complicated set of
tests because ideally we'd like to find out whether it falls back
correctly for all supported servers.
---
 TODO                                     |  3 +++
 generator/generator                      | 34 +++++++++++++++++++++---
 generator/states-newstyle-opt-starttls.c |  1 +
 lib/crypto.c                             |  6 +++++
 lib/internal.h                           |  3 +++
 5 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/TODO b/TODO
index 642d39f..21feb2f 100644
--- a/TODO
+++ b/TODO
@@ -17,6 +17,9 @@ NBD_INFO_BLOCK_SIZE.
 
 TLS should properly shut down the session (calling gnutls_bye).
 
+LIBNBD_TLS_ALLOW is not tested.  Related to this,
+nbd_get_tls_negotiated is not tested.
+
 Implement nbd_connect + systemd socket activation.
 
 Improve function trace output so that:
diff --git a/generator/generator b/generator/generator
index 87a8cdf..28248ed 100755
--- a/generator/generator
+++ b/generator/generator
@@ -1132,17 +1132,42 @@ TLS are not handled automatically.  Setting the level higher than
 zero will fail if libnbd was not compiled against gnutls; you can
 test whether this is the case with L<nbd_supports_tls(3)>.";
     example = Some "examples/encryption.c";
-    see_also = ["L<libnbd(3)/ENCRYPTION AND AUTHENTICATION>"];
+    see_also = ["L<libnbd(3)/ENCRYPTION AND AUTHENTICATION>";
+                "L<nbd_get_tls(3)>"; "L<nbd_get_tls_negotiated(3)>"];
   };
 
   "get_tls", {
     default_call with
     args = []; ret = RInt;
     may_set_error = false;
-    shortdesc = "get the current TLS setting";
+    shortdesc = "get the TLS request setting";
     longdesc = "\
-Get the current TLS setting.";
-    see_also = ["L<nbd_set_tls(3)>"];
+Get the TLS request setting.
+
+B<Note:> If you want to find out if TLS was actually negotiated
+on a particular connection use L<nbd_get_tls_negotiated(3)> instead.";
+    see_also = ["L<nbd_set_tls(3)>"; "L<nbd_get_tls_negotiated(3)>"];
+  };
+
+  "get_tls_negotiated", {
+    default_call with
+    args = []; ret = RBool;
+    permitted_states = [ Connected; Closed ];
+    shortdesc = "find out if TLS was negotiated on a connection";
+    longdesc = "\
+After connecting you may call this to find out if the
+connection is using TLS.
+
+This is only really useful if you set the TLS request mode
+to C<LIBNBD_TLS_ALLOW> (see L<nbd_set_tls(3)>), because in this
+mode we try to use TLS but fall back to unencrypted if it was
+not available.  This function will tell you if TLS was
+negotiated or not.
+
+In C<LIBNBD_TLS_REQUIRE> mode (the most secure) the connection
+would have failed if TLS could not be negotiated, and in
+C<LIBNBD_TLS_DISABLE> mode TLS is not tried.";
+    see_also = ["L<nbd_set_tls(3)>"; "L<nbd_get_tls(3)>"];
   };
 
   "set_tls_certificates", {
@@ -2527,6 +2552,7 @@ let first_version = [
   "can_fast_zero", (1, 2);
   "set_request_structured_replies", (1, 2);
   "get_request_structured_replies", (1, 2);
+  "get_tls_negotiated", (1, 2);
 
   (* These calls are proposed for a future version of libnbd, but
    * have not been added to any released version so far.
diff --git a/generator/states-newstyle-opt-starttls.c b/generator/states-newstyle-opt-starttls.c
index 0a18db0..a35e10b 100644
--- a/generator/states-newstyle-opt-starttls.c
+++ b/generator/states-newstyle-opt-starttls.c
@@ -116,6 +116,7 @@
   }
   if (r == 0) {
     /* Finished handshake. */
+    h->tls_negotiated = true;
     nbd_internal_crypto_debug_tls_enabled (h);
 
     /* Continue with option negotiation. */
diff --git a/lib/crypto.c b/lib/crypto.c
index c0a57d7..3274954 100644
--- a/lib/crypto.c
+++ b/lib/crypto.c
@@ -57,6 +57,12 @@ nbd_unlocked_get_tls (struct nbd_handle *h)
   return h->tls;
 }
 
+int
+nbd_unlocked_get_tls_negotiated (struct nbd_handle *h)
+{
+  return h->tls_negotiated;
+}
+
 int
 nbd_unlocked_set_tls_certificates (struct nbd_handle *h, const char *dir)
 {
diff --git a/lib/internal.h b/lib/internal.h
index ccaca32..eb76ac1 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -87,6 +87,9 @@ struct nbd_handle {
   uint64_t exportsize;
   uint16_t eflags;
 
+  /* Flag set by the state machine to tell whether TLS was negotiated. */
+  bool tls_negotiated;
+
   int64_t unique;               /* Used for generating cookie numbers. */
 
   /* For debugging. */
-- 
2.23.0




More information about the Libguestfs mailing list