@@ -45,6 +45,7 @@
#define QEMU_NBD_OPT_DISCARD 3
#define QEMU_NBD_OPT_DETECT_ZEROES 4
#define QEMU_NBD_OPT_OBJECT 5
+#define QEMU_NBD_OPT_TLSCREDS 6
static NBDExport *exp;
static bool newproto;
@@ -57,6 +58,7 @@ static int shared = 1;
static int nb_fds;
static QIOChannelSocket *server_ioc;
static int server_watch = -1;
+static QCryptoTLSCreds *tlscreds;
static void usage(const char *name)
{
@@ -344,7 +346,7 @@ static gboolean nbd_accept(QIOChannel *ioc, GIOCondition cond, gpointer opaque)
}
if (nbd_client_new(newproto ? NULL : exp, cioc,
- NULL, NULL, nbd_client_closed)) {
+ tlscreds, NULL, nbd_client_closed)) {
nb_fds++;
nbd_update_server_watch();
}
@@ -426,6 +428,37 @@ static int object_create(void *opaque, QemuOpts *opts, Error **errp)
return 0;
}
+
+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_SERVER) {
+ error_setg(errp,
+ "Expecting TLS credentials with a server endpoint");
+ return NULL;
+ }
+ object_ref(obj);
+ return creds;
+}
+
+
int main(int argc, char **argv)
{
BlockBackend *blk;
@@ -465,6 +498,7 @@ int main(int argc, char **argv)
{ "verbose", 0, NULL, 'v' },
{ "object", 1, NULL, QEMU_NBD_OPT_OBJECT },
{ "exportname", 1, NULL, 'x' },
+ { "tls-creds", 1, NULL, QEMU_NBD_OPT_TLSCREDS },
{ NULL, 0, NULL, 0 }
};
int ch;
@@ -483,6 +517,7 @@ int main(int argc, char **argv)
QDict *options = NULL;
QemuOpts *opts;
const char *exportname = NULL;
+ const char *tlscredsid = NULL;
/* The client thread uses SIGTERM to interrupt the server. A signal
* handler ensures that "qemu-nbd -v -c" exits with a nice status code.
@@ -639,6 +674,9 @@ int main(int argc, char **argv)
exit(1);
}
break;
+ case QEMU_NBD_OPT_TLSCREDS:
+ tlscredsid = optarg;
+ break;
case '?':
errx(EXIT_FAILURE, "Try `%s --help' for more information.",
argv[0]);
@@ -657,6 +695,23 @@ int main(int argc, char **argv)
exit(1);
}
+ if (tlscredsid) {
+ if (!exportname) {
+ errx(EXIT_FAILURE, "Export name is required when using TLS");
+ }
+ if (sockpath) {
+ errx(EXIT_FAILURE, "TLS is only supported with IPv4/IPv6");
+ }
+ if (device) {
+ errx(EXIT_FAILURE, "TLS is not supported with a host device");
+ }
+ tlscreds = nbd_get_tls_creds(tlscredsid, &local_err);
+ if (local_err) {
+ errx(EXIT_FAILURE, "Failed to get TLS creds %s",
+ error_get_pretty(local_err));
+ }
+ }
+
if (disconnect) {
int nbdfd = open(argv[optind], O_RDWR);
if (nbdfd < 0) {
@@ -66,6 +66,10 @@ Export QEMU disk image using NBD protocol.
@item -x NAME, --exportname=NAME
set the NDB volume export name. This switches the server to use
the new style NBD protocol negotiation
+@item --tls-creds=ID
+ enable mandatory TLS encryption for the server by setting the ID
+ of the TLS credentials object previously created with the --object
+ option.
@item -v, --verbose
display extra debugging information
@item -h, --help
This modifies the qemu-nbd program so that it is possible to request the use of TLS with the server. It simply adds a new command line option --tls-creds which is used to provide the ID of a QCryptoTLSCreds object previously created via the --object command line option. For example qemu-nbd --object tls-creds-x509,id=tls0,endpoint=server,\ dir=/home/berrange/security/qemutls \ --tls-creds tls0 \ --exportname default Note that it is mandatory to supply the --exportname argument when requesting TLS, since it requires use of the new style NBD protocol where the client requests a volume name explicitly. TLS is only supported when using an IPv4/IPv6 socket listener. It is not possible to use with UNIX sockets, which includes when connecting the NBD server to a host device. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- qemu-nbd.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- qemu-nbd.texi | 4 ++++ 2 files changed, 60 insertions(+), 1 deletion(-)