All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>, qemu-block@nongnu.org
Subject: [Qemu-devel] [PATCH v3 11/13] nbd: enable use of TLS with NBD block driver
Date: Tue, 19 Jan 2016 13:09:21 +0000	[thread overview]
Message-ID: <1453208963-16834-12-git-send-email-berrange@redhat.com> (raw)
In-Reply-To: <1453208963-16834-1-git-send-email-berrange@redhat.com>

This modifies the NBD driver so that it is possible to request
use of TLS. This is done by providing the 'tls-creds' parameter
with the ID of a previously created QCryptoTLSCreds object.

For example

  $QEMU -object tls-creds-x509,id=tls0,endpoint=client,\
                dir=/home/berrange/security/qemutls \
        -drive driver=nbd,host=localhost,port=9000,tls-creds=tls0

The client will drop the connection if the NBD server does not
provide TLS.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 block/nbd-client.c | 10 ++++---
 block/nbd-client.h |  2 ++
 block/nbd.c        | 78 +++++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 78 insertions(+), 12 deletions(-)

diff --git a/block/nbd-client.c b/block/nbd-client.c
index f7bacfd..024d5f3 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -378,8 +378,12 @@ void nbd_client_close(BlockDriverState *bs)
     nbd_teardown_connection(bs);
 }
 
-int nbd_client_init(BlockDriverState *bs, QIOChannelSocket *sioc,
-                    const char *export, Error **errp)
+int nbd_client_init(BlockDriverState *bs,
+                    QIOChannelSocket *sioc,
+                    const char *export,
+                    QCryptoTLSCreds *tlscreds,
+                    const char *hostname,
+                    Error **errp)
 {
     NbdClientSession *client = nbd_get_client_session(bs);
     int ret;
@@ -390,7 +394,7 @@ int nbd_client_init(BlockDriverState *bs, QIOChannelSocket *sioc,
 
     ret = nbd_receive_negotiate(QIO_CHANNEL(sioc), export,
                                 &client->nbdflags,
-                                NULL, NULL,
+                                tlscreds, hostname,
                                 &client->ioc,
                                 &client->size, errp);
     if (ret < 0) {
diff --git a/block/nbd-client.h b/block/nbd-client.h
index e8b3283..53f116d 100644
--- a/block/nbd-client.h
+++ b/block/nbd-client.h
@@ -39,6 +39,8 @@ NbdClientSession *nbd_get_client_session(BlockDriverState *bs);
 int nbd_client_init(BlockDriverState *bs,
                     QIOChannelSocket *sock,
                     const char *export_name,
+                    QCryptoTLSCreds *tlscreds,
+                    const char *hostname,
                     Error **errp);
 void nbd_client_close(BlockDriverState *bs);
 
diff --git a/block/nbd.c b/block/nbd.c
index 072fc5f..c17415f 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -259,36 +259,92 @@ static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr,
     return sioc;
 }
 
+
+static QCryptoTLSCreds *nbd_get_tls_creds(const char *id, Error **errp)
+{
+    Object *obj;
+    QCryptoTLSCreds *creds;
+
+    obj = object_resolve_path_component(
+        object_get_objects_root(), id);
+    if (!obj) {
+        error_setg(errp, "No TLS credentials with id '%s'",
+                   id);
+        return NULL;
+    }
+    creds = (QCryptoTLSCreds *)
+        object_dynamic_cast(obj, TYPE_QCRYPTO_TLS_CREDS);
+    if (!creds) {
+        error_setg(errp, "Object with id '%s' is not TLS credentials",
+                   id);
+        return NULL;
+    }
+
+    if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
+        error_setg(errp,
+                   "Expecting TLS credentials with a client endpoint");
+        return NULL;
+    }
+    object_ref(obj);
+    return creds;
+}
+
+
 static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
                     Error **errp)
 {
     BDRVNBDState *s = bs->opaque;
     char *export = NULL;
-    int result;
-    QIOChannelSocket *sioc;
+    QIOChannelSocket *sioc = NULL;
     SocketAddress *saddr;
+    const char *tlscredsid;
+    QCryptoTLSCreds *tlscreds = NULL;
+    const char *hostname = NULL;
+    int ret = -EINVAL;
 
     /* Pop the config into our state object. Exit if invalid. */
     saddr = nbd_config(s, options, &export, errp);
     if (!saddr) {
-        return -EINVAL;
+        goto error;
+    }
+
+    tlscredsid = g_strdup(qdict_get_try_str(options, "tls-creds"));
+    if (tlscredsid) {
+        qdict_del(options, "tls-creds");
+        tlscreds = nbd_get_tls_creds(tlscredsid, errp);
+        if (!tlscreds) {
+            goto error;
+        }
+
+        if (saddr->type != SOCKET_ADDRESS_KIND_INET) {
+            error_setg(errp, "TLS only supported over IP sockets");
+            goto error;
+        }
+        hostname = saddr->u.inet->host;
     }
 
     /* establish TCP connection, return error if it fails
      * TODO: Configurable retry-until-timeout behaviour.
      */
     sioc = nbd_establish_connection(saddr, errp);
-    qapi_free_SocketAddress(saddr);
     if (!sioc) {
-        g_free(export);
-        return -ECONNREFUSED;
+        ret = -ECONNREFUSED;
+        goto error;
     }
 
     /* NBD handshake */
-    result = nbd_client_init(bs, sioc, export, errp);
-    object_unref(OBJECT(sioc));
+    ret = nbd_client_init(bs, sioc, export,
+                          tlscreds, hostname, errp);
+ error:
+    if (sioc) {
+        object_unref(OBJECT(sioc));
+    }
+    if (tlscreds) {
+        object_unref(OBJECT(tlscreds));
+    }
+    qapi_free_SocketAddress(saddr);
     g_free(export);
-    return result;
+    return ret;
 }
 
 static int nbd_co_readv(BlockDriverState *bs, int64_t sector_num,
@@ -350,6 +406,7 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
     const char *host   = qdict_get_try_str(options, "host");
     const char *port   = qdict_get_try_str(options, "port");
     const char *export = qdict_get_try_str(options, "export");
+    const char *tlscreds = qdict_get_try_str(options, "tls-creds");
 
     qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("nbd")));
 
@@ -384,6 +441,9 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
     if (export) {
         qdict_put_obj(opts, "export", QOBJECT(qstring_from_str(export)));
     }
+    if (tlscreds) {
+        qdict_put_obj(opts, "tls-creds", QOBJECT(qstring_from_str(tlscreds)));
+    }
 
     bs->full_open_options = opts;
 }
-- 
2.5.0

  parent reply	other threads:[~2016-01-19 13:09 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-19 13:09 [Qemu-devel] [PATCH v3 00/13] Implement TLS support to QEMU NBD server & client Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 01/13] nbd: convert block client to use I/O channels for connection setup Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 02/13] nbd: convert qemu-nbd server " Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 03/13] nbd: convert blockdev NBD " Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 04/13] nbd: convert to using I/O channels for actual socket I/O Daniel P. Berrange
2016-01-19 16:08   ` Paolo Bonzini
2016-01-19 16:52     ` Daniel P. Berrange
2016-01-19 18:00       ` Paolo Bonzini
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 05/13] nbd: invert client logic for negotiating protocol version Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 06/13] nbd: make server compliant with fixed newstyle spec Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 07/13] nbd: make client request fixed new style if advertized Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 08/13] nbd: allow setting of an export name for qemu-nbd server Daniel P. Berrange
2016-01-19 16:12   ` Paolo Bonzini
2016-01-19 16:48     ` Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 09/13] nbd: pick first exported volume if no export name is requested Daniel P. Berrange
2016-01-19 16:14   ` Paolo Bonzini
2016-01-19 16:44     ` Daniel P. Berrange
2016-01-21 10:30       ` Paolo Bonzini
2016-01-21 14:26         ` Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 10/13] nbd: implement TLS support in the protocol negotiation Daniel P. Berrange
2016-01-19 13:09 ` Daniel P. Berrange [this message]
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 12/13] nbd: enable use of TLS with qemu-nbd server Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 13/13] nbd: enable use of TLS with nbd-server-start command Daniel P. Berrange

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1453208963-16834-12-git-send-email-berrange@redhat.com \
    --to=berrange@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.