Add SPICE support for QEMU driver configuration file

In common with VNC, the QEMU driver configuration file is used
specify the host level TLS certificate location and a default
password / listen address

* src/qemu/qemu.conf: Add spice_listen, spice_tls,
  spice_tls_x509_cert_dir & spice_password config params
* src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Parsing of
  spice config parameters and updating -spice arg generation
  to use them
* tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args,
  tests/qemuxml2argvtest.c: Expand test case to cover driver
  level configuration
This commit is contained in:
Daniel P. Berrange 2010-03-05 20:31:50 +00:00
parent ed0d9f6c0c
commit b5c9920955
6 changed files with 123 additions and 5 deletions

View File

@ -80,6 +80,46 @@
# SPICE is configured to listen on 127.0.0.1 by default.
# To make it listen on all public interfaces, uncomment
# this next option.
#
# NB, strong recommendation to enable TLS + x509 certificate
# verification when allowing public access
#
# spice_listen = "0.0.0.0"
# Enable use of TLS encryption on the SPICE server.
#
# It is necessary to setup CA and issue a server certificate
# before enabling this.
#
# spice_tls = 1
# Use of TLS requires that x509 certificates be issued. The
# default it to keep them in /etc/pki/libvirt-spice. This directory
# must contain
#
# ca-cert.pem - the CA master certificate
# server-cert.pem - the server certificate signed with ca-cert.pem
# server-key.pem - the server private key
#
# This option allows the certificate directory to be changed
#
# spice_tls_x509_cert_dir = "/etc/pki/libvirt-spice"
# The default SPICE password. This parameter is only used if the
# per-domain XML config does not already provide a password. To
# allow access without passwords, leave this commented out. An
# empty string will still enable passwords, but be rejected by
# QEMU effectively preventing any use of SPICE. Obviously change
# this example here before you set this
#
# spice_password = "XYZ12345"
# The default security driver is SELinux. If SELinux is disabled
# on the host, then the security driver will automatically disable

View File

@ -116,6 +116,15 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
return -1;
}
if (!(driver->spiceListen = strdup("127.0.0.1"))) {
virReportOOMError();
return -1;
}
if (!(driver->spiceTLSx509certdir = strdup(SYSCONF_DIR "/pki/libvirt-spice"))) {
virReportOOMError();
return -1;
}
#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
/* For privileged driver, try and find hugepage mount automatically.
* Non-privileged driver requires admin to create a dir for the
@ -219,6 +228,43 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
}
}
p = virConfGetValue (conf, "spice_tls");
CHECK_TYPE ("spice_tls", VIR_CONF_LONG);
if (p) driver->spiceTLS = p->l;
p = virConfGetValue (conf, "spice_tls_x509_cert_dir");
CHECK_TYPE ("spice_tls_x509_cert_dir", VIR_CONF_STRING);
if (p && p->str) {
VIR_FREE(driver->spiceTLSx509certdir);
if (!(driver->spiceTLSx509certdir = strdup(p->str))) {
virReportOOMError();
virConfFree(conf);
return -1;
}
}
p = virConfGetValue (conf, "spice_listen");
CHECK_TYPE ("spice_listen", VIR_CONF_STRING);
if (p && p->str) {
VIR_FREE(driver->spiceListen);
if (!(driver->spiceListen = strdup(p->str))) {
virReportOOMError();
virConfFree(conf);
return -1;
}
}
p = virConfGetValue (conf, "spice_password");
CHECK_TYPE ("spice_password", VIR_CONF_STRING);
if (p && p->str) {
VIR_FREE(driver->spicePassword);
if (!(driver->spicePassword = strdup(p->str))) {
virReportOOMError();
virConfFree(conf);
return -1;
}
}
p = virConfGetValue (conf, "user");
CHECK_TYPE ("user", VIR_CONF_STRING);
if (!(user = strdup(p && p->str ? p->str : QEMU_USER))) {
@ -5082,11 +5128,25 @@ int qemudBuildCommandLine(virConnectPtr conn,
virBufferVSprintf(&opt, "port=%u", def->graphics[0]->data.spice.port);
if (def->graphics[0]->data.spice.tlsPort)
if (driver->spiceTLS && def->graphics[0]->data.spice.tlsPort != -1)
virBufferVSprintf(&opt, ",tls-port=%u", def->graphics[0]->data.spice.tlsPort);
if (def->graphics[0]->data.spice.listenAddr)
virBufferVSprintf(&opt, ",addr=%s", def->graphics[0]->data.spice.listenAddr);
else if (driver->spiceListen)
virBufferVSprintf(&opt, ",addr=%s", driver->spiceListen);
/* In the password case we set it via monitor command, to avoid
* making it visible on CLI, so there's no use of password=XXX
* in this bit of the code */
if (!def->graphics[0]->data.spice.passwd &&
!driver->spicePassword)
virBufferAddLit(&opt, ",disable-ticketing");
if (driver->spiceTLS)
virBufferVSprintf(&opt, ",x509-dir=%s",
driver->spiceTLSx509certdir);
if (virBufferError(&opt))
goto no_memory;

View File

@ -141,6 +141,10 @@ struct qemud_driver {
char *vncListen;
char *vncPassword;
char *vncSASLdir;
unsigned int spiceTLS : 1;
char *spiceTLSx509certdir;
char *spiceListen;
char *spicePassword;
char *hugetlbfs_mount;
char *hugepage_path;

View File

@ -3942,13 +3942,22 @@ static int qemudStartVMDaemon(virConnectPtr conn,
} else if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
vm->def->graphics[0]->data.spice.autoport) {
int port = qemudNextFreePort(driver, 5900);
int tlsPort = port == -1 ? -1 : qemudNextFreePort(driver, port + 1);
if (port < 0 || tlsPort < 0) {
int tlsPort = -1;
if (port < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Unable to find unused SPICE ports"));
"%s", _("Unable to find an unused SPICE port"));
goto cleanup;
}
if (driver->spiceTLS) {
tlsPort = qemudNextFreePort(driver, port + 1);
if (tlsPort < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Unable to find an unused SPICE TLS port"));
goto cleanup;
}
}
vm->def->graphics[0]->data.spice.port = port;
vm->def->graphics[0]->data.spice.tlsPort = tlsPort;
}

View File

@ -1 +1 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice /usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1 -vga qxl -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice /usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,x509-dir=/etc/pki/libvirt-spice -vga qxl -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -214,6 +214,11 @@ mymain(int argc, char **argv)
return EXIT_FAILURE;
if ((driver.hugepage_path = strdup("/dev/hugepages/libvirt/qemu")) == NULL)
return EXIT_FAILURE;
driver.spiceTLS = 1;
if (!(driver.spiceTLSx509certdir = strdup("/etc/pki/libvirt-spice")))
return EXIT_FAILURE;
if (!(driver.spicePassword = strdup("123456")))
return EXIT_FAILURE;
# define DO_TEST_FULL(name, extraFlags, migrateFrom, expectError) \
do { \