mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
nbd: enable use of TLS with nbd-server-start command
This modifies the nbd-server-start QMP command so that it is possible to request use of TLS. This is done by adding a new optional parameter "tls-creds" which provides the ID of a previously created QCryptoTLSCreds object instance. TLS is only supported when using an IPv4/IPv6 socket listener. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-Id: <1455129674-17255-17-git-send-email-berrange@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
145614a112
commit
ddffee3904
4 changed files with 105 additions and 25 deletions
122
blockdev-nbd.c
122
blockdev-nbd.c
|
@ -20,42 +20,126 @@
|
|||
#include "block/nbd.h"
|
||||
#include "io/channel-socket.h"
|
||||
|
||||
static QIOChannelSocket *server_ioc;
|
||||
static int server_watch = -1;
|
||||
typedef struct NBDServerData {
|
||||
QIOChannelSocket *listen_ioc;
|
||||
int watch;
|
||||
QCryptoTLSCreds *tlscreds;
|
||||
} NBDServerData;
|
||||
|
||||
static NBDServerData *nbd_server;
|
||||
|
||||
|
||||
static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
|
||||
gpointer opaque)
|
||||
{
|
||||
QIOChannelSocket *cioc;
|
||||
|
||||
if (!nbd_server) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc),
|
||||
NULL);
|
||||
if (!cioc) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
nbd_client_new(NULL, cioc, NULL, NULL, nbd_client_put);
|
||||
nbd_client_new(NULL, cioc,
|
||||
nbd_server->tlscreds, NULL,
|
||||
nbd_client_put);
|
||||
object_unref(OBJECT(cioc));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void qmp_nbd_server_start(SocketAddress *addr, Error **errp)
|
||||
|
||||
static void nbd_server_free(NBDServerData *server)
|
||||
{
|
||||
if (server_ioc) {
|
||||
if (!server) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (server->watch != -1) {
|
||||
g_source_remove(server->watch);
|
||||
}
|
||||
object_unref(OBJECT(server->listen_ioc));
|
||||
if (server->tlscreds) {
|
||||
object_unref(OBJECT(server->tlscreds));
|
||||
}
|
||||
|
||||
g_free(server);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void qmp_nbd_server_start(SocketAddress *addr,
|
||||
bool has_tls_creds, const char *tls_creds,
|
||||
Error **errp)
|
||||
{
|
||||
if (nbd_server) {
|
||||
error_setg(errp, "NBD server already running");
|
||||
return;
|
||||
}
|
||||
|
||||
server_ioc = qio_channel_socket_new();
|
||||
if (qio_channel_socket_listen_sync(server_ioc, addr, errp) < 0) {
|
||||
return;
|
||||
nbd_server = g_new0(NBDServerData, 1);
|
||||
nbd_server->watch = -1;
|
||||
nbd_server->listen_ioc = qio_channel_socket_new();
|
||||
if (qio_channel_socket_listen_sync(
|
||||
nbd_server->listen_ioc, addr, errp) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
server_watch = qio_channel_add_watch(QIO_CHANNEL(server_ioc),
|
||||
G_IO_IN,
|
||||
nbd_accept,
|
||||
NULL,
|
||||
NULL);
|
||||
if (has_tls_creds) {
|
||||
nbd_server->tlscreds = nbd_get_tls_creds(tls_creds, errp);
|
||||
if (!nbd_server->tlscreds) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (addr->type != SOCKET_ADDRESS_KIND_INET) {
|
||||
error_setg(errp, "TLS is only supported with IPv4/IPv6");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
nbd_server->watch = qio_channel_add_watch(
|
||||
QIO_CHANNEL(nbd_server->listen_ioc),
|
||||
G_IO_IN,
|
||||
nbd_accept,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
nbd_server_free(nbd_server);
|
||||
nbd_server = NULL;
|
||||
}
|
||||
|
||||
void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
|
||||
|
@ -64,7 +148,7 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
|
|||
BlockBackend *blk;
|
||||
NBDExport *exp;
|
||||
|
||||
if (!server_ioc) {
|
||||
if (!nbd_server) {
|
||||
error_setg(errp, "NBD server not running");
|
||||
return;
|
||||
}
|
||||
|
@ -110,12 +194,6 @@ void qmp_nbd_server_stop(Error **errp)
|
|||
{
|
||||
nbd_export_close_all();
|
||||
|
||||
if (server_watch != -1) {
|
||||
g_source_remove(server_watch);
|
||||
server_watch = -1;
|
||||
}
|
||||
if (server_ioc) {
|
||||
object_unref(OBJECT(server_ioc));
|
||||
server_ioc = NULL;
|
||||
}
|
||||
nbd_server_free(nbd_server);
|
||||
nbd_server = NULL;
|
||||
}
|
||||
|
|
2
hmp.c
2
hmp.c
|
@ -1793,7 +1793,7 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
qmp_nbd_server_start(addr, &local_err);
|
||||
qmp_nbd_server_start(addr, false, NULL, &local_err);
|
||||
qapi_free_SocketAddress(addr);
|
||||
if (local_err != NULL) {
|
||||
goto exit;
|
||||
|
|
|
@ -146,13 +146,15 @@
|
|||
# QEMU instance could refer to them as "nbd:HOST:PORT:exportname=NAME".
|
||||
#
|
||||
# @addr: Address on which to listen.
|
||||
# @tls-creds: (optional) ID of the TLS credentials object. Since 2.6
|
||||
#
|
||||
# Returns: error if the server is already running.
|
||||
#
|
||||
# Since: 1.3.0
|
||||
##
|
||||
{ 'command': 'nbd-server-start',
|
||||
'data': { 'addr': 'SocketAddress' } }
|
||||
'data': { 'addr': 'SocketAddress',
|
||||
'*tls-creds': 'str'} }
|
||||
|
||||
##
|
||||
# @nbd-server-add:
|
||||
|
|
|
@ -3825,7 +3825,7 @@ EQMP
|
|||
|
||||
{
|
||||
.name = "nbd-server-start",
|
||||
.args_type = "addr:q",
|
||||
.args_type = "addr:q,tls-creds:s?",
|
||||
.mhandler.cmd_new = qmp_marshal_nbd_server_start,
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue