瀏覽代碼

block/nbd: support override of hostname for TLS certificate validation

When connecting to an NBD server with TLS and x509 credentials,
the client must validate the hostname it uses for the connection,
against that published in the server's certificate. If the client
is tunnelling its connection over some other channel, however, the
hostname it uses may not match the info reported in the server's
certificate. In such a case, the user needs to explicitly set an
override for the hostname to use for certificate validation.

This is achieved by adding a 'tls-hostname' property to the NBD
block driver.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20220304193610.3293146-4-berrange@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Daniel P. Berrangé 3 年之前
父節點
當前提交
a0cd6d2972
共有 2 個文件被更改,包括 18 次插入3 次删除
  1. 15 3
      block/nbd.c
  2. 3 0
      qapi/block-core.json

+ 15 - 3
block/nbd.c

@@ -90,9 +90,10 @@ typedef struct BDRVNBDState {
     uint32_t reconnect_delay;
     uint32_t reconnect_delay;
     uint32_t open_timeout;
     uint32_t open_timeout;
     SocketAddress *saddr;
     SocketAddress *saddr;
-    char *export, *tlscredsid;
+    char *export;
+    char *tlscredsid;
     QCryptoTLSCreds *tlscreds;
     QCryptoTLSCreds *tlscreds;
-    const char *tlshostname;
+    char *tlshostname;
     char *x_dirty_bitmap;
     char *x_dirty_bitmap;
     bool alloc_depth;
     bool alloc_depth;
 
 
@@ -121,6 +122,8 @@ static void nbd_clear_bdrvstate(BlockDriverState *bs)
     s->export = NULL;
     s->export = NULL;
     g_free(s->tlscredsid);
     g_free(s->tlscredsid);
     s->tlscredsid = NULL;
     s->tlscredsid = NULL;
+    g_free(s->tlshostname);
+    s->tlshostname = NULL;
     g_free(s->x_dirty_bitmap);
     g_free(s->x_dirty_bitmap);
     s->x_dirty_bitmap = NULL;
     s->x_dirty_bitmap = NULL;
 }
 }
@@ -1765,6 +1768,11 @@ static QemuOptsList nbd_runtime_opts = {
             .type = QEMU_OPT_STRING,
             .type = QEMU_OPT_STRING,
             .help = "ID of the TLS credentials to use",
             .help = "ID of the TLS credentials to use",
         },
         },
+        {
+            .name = "tls-hostname",
+            .type = QEMU_OPT_STRING,
+            .help = "Override hostname for validating TLS x509 certificate",
+        },
         {
         {
             .name = "x-dirty-bitmap",
             .name = "x-dirty-bitmap",
             .type = QEMU_OPT_STRING,
             .type = QEMU_OPT_STRING,
@@ -1836,7 +1844,10 @@ static int nbd_process_options(BlockDriverState *bs, QDict *options,
             error_setg(errp, "TLS only supported over IP sockets");
             error_setg(errp, "TLS only supported over IP sockets");
             goto error;
             goto error;
         }
         }
-        s->tlshostname = s->saddr->u.inet.host;
+        s->tlshostname = g_strdup(qemu_opt_get(opts, "tls-hostname"));
+        if (!s->tlshostname) {
+            s->tlshostname = g_strdup(s->saddr->u.inet.host);
+        }
     }
     }
 
 
     s->x_dirty_bitmap = g_strdup(qemu_opt_get(opts, "x-dirty-bitmap"));
     s->x_dirty_bitmap = g_strdup(qemu_opt_get(opts, "x-dirty-bitmap"));
@@ -2038,6 +2049,7 @@ static const char *const nbd_strong_runtime_opts[] = {
     "port",
     "port",
     "export",
     "export",
     "tls-creds",
     "tls-creds",
+    "tls-hostname",
     "server.",
     "server.",
 
 
     NULL
     NULL

+ 3 - 0
qapi/block-core.json

@@ -4079,6 +4079,8 @@
 #
 #
 # @tls-creds: TLS credentials ID
 # @tls-creds: TLS credentials ID
 #
 #
+# @tls-hostname: TLS hostname override for certificate validation (Since 7.0)
+#
 # @x-dirty-bitmap: A metadata context name such as "qemu:dirty-bitmap:NAME"
 # @x-dirty-bitmap: A metadata context name such as "qemu:dirty-bitmap:NAME"
 #                  or "qemu:allocation-depth" to query in place of the
 #                  or "qemu:allocation-depth" to query in place of the
 #                  traditional "base:allocation" block status (see
 #                  traditional "base:allocation" block status (see
@@ -4109,6 +4111,7 @@
   'data': { 'server': 'SocketAddress',
   'data': { 'server': 'SocketAddress',
             '*export': 'str',
             '*export': 'str',
             '*tls-creds': 'str',
             '*tls-creds': 'str',
+            '*tls-hostname': 'str',
             '*x-dirty-bitmap': { 'type': 'str', 'features': [ 'unstable' ] },
             '*x-dirty-bitmap': { 'type': 'str', 'features': [ 'unstable' ] },
             '*reconnect-delay': 'uint32',
             '*reconnect-delay': 'uint32',
             '*open-timeout': 'uint32' } }
             '*open-timeout': 'uint32' } }