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