>
> @@ -8546,6 +8561,18 @@ qemuBuildSerialCommandLine(virLogManagerPtr logManager,
>
> /* Use -chardev with -device if they are available */
> if (virQEMUCapsSupportsChardev(def, qemuCaps, serial)) {
> + qemuDomainChardevPrivatePtr chardevPriv =
> + QEMU_DOMAIN_CHARDEV_PRIVATE(serial);
> +
> + /* Add the secret object first if necessary. The
> + * secinfo is added only to a TCP serial device during
> + * qemuDomainSecretChardevPrepare. Subsequently called
> + * functions can just check the config fields */
> + if (serial->source.type == VIR_DOMAIN_CHR_TYPE_TCP &&
> + chardevPriv && chardevPriv->secinfo &&
> + qemuBuildObjectSecretCommandLine(cmd, chardevPriv->secinfo) <
0)
> + return -1;
> +
This should be used also for other chardev devices.
Easily done for parallels, consoles, and channel... IOW: Others that
call virDomainChrDefParseXML which calls virDomainChrDefNew(xmlopt) in
order to set up privateData.
Less easy for smartcard, rng, and redirdev's. Unfortunately the PRIVATE
stuff is based off a virDomainChrDefPtr while the smartcard, rng, and
redirdev's each use their own virDomain*DefPtr that includes a
virDomainChrSourceDefPtr (for RNG) or virDomainChrSourceDef (for
smartcard and redirdev).
BTW: The hotplug code for smartcard, rng, and redirdev isn't
implemented... Follow qemuDomainAttachChrDevice callers and you'll see
separate calls for redirdev, rng, and smartcard. Clearly I misread all
the various permutations...
Looks like I'll need to either implement privateData for
virDomainCharSourceDefPtr or duplicate what's done for ChrDef for
redevdir, rng, and smartcard. Neither is appealing...
John
> if (!(devstr = qemuBuildChrChardevStr(logManager,
cmd, cfg, def,
> &serial->source,
> serial->info.alias,
> diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
> index 2f2a6ff..a793fb6 100644
> --- a/src/qemu/qemu_command.h
> +++ b/src/qemu/qemu_command.h
> @@ -69,6 +69,7 @@ int qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
> int qemuBuildTLSx509BackendProps(const char *tlspath,
> bool isListen,
> bool verifypeer,
> + const char *secalias,
> virQEMUCapsPtr qemuCaps,
> virJSONValuePtr *propsret);
>
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 7b518c6..adc078b 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -1042,7 +1042,8 @@ qemuDomainSecretSetup(virConnectPtr conn,
> if (virCryptoHaveCipher(VIR_CRYPTO_CIPHER_AES256CBC) &&
> virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_SECRET) &&
> (secretUsageType == VIR_SECRET_USAGE_TYPE_CEPH ||
> - secretUsageType == VIR_SECRET_USAGE_TYPE_VOLUME)) {
> + secretUsageType == VIR_SECRET_USAGE_TYPE_VOLUME ||
> + secretUsageType == VIR_SECRET_USAGE_TYPE_TLS)) {
> if (qemuDomainSecretAESSetup(conn, priv, secinfo, srcalias,
> secretUsageType, username,
> seclookupdef, isLuks) < 0)
> @@ -1220,6 +1221,95 @@ qemuDomainSecretHostdevPrepare(virConnectPtr conn,
> }
>
>
> +/* qemuDomainSecretChardevDestroy:
> + * @disk: Pointer to a chardev definition
> + *
> + * Clear and destroy memory associated with the secret
> + */
> +void
> +qemuDomainSecretChardevDestroy(virDomainChrDefPtr chardev)
> +{
> + qemuDomainChardevPrivatePtr chardevPriv =
> + QEMU_DOMAIN_CHARDEV_PRIVATE(chardev);
> +
> + if (!chardevPriv || !chardevPriv->secinfo)
> + return;
> +
> + qemuDomainSecretInfoFree(&chardevPriv->secinfo);
> +}
> +
> +
> +/* qemuDomainSecretChardevPrepare:
> + * @conn: Pointer to connection
> + * @driver: Pointer to driver object
> + * @priv: pointer to domain private object
> + * @chardev: Pointer to a chardev definition
> + *
> + * For a TCP character device, generate a qemuDomainSecretInfo to be used
> + * by the command line code to generate the secret for the tls-creds to use.
> + *
> + * Returns 0 on success, -1 on failure
> + */
> +int
> +qemuDomainSecretChardevPrepare(virConnectPtr conn,
> + virQEMUDriverPtr driver,
> + qemuDomainObjPrivatePtr priv,
> + virDomainChrDefPtr chardev)
> +{
> + virQEMUDriverConfigPtr cfg;
> + virSecretLookupTypeDef seclookupdef = {0};
> + qemuDomainSecretInfoPtr secinfo = NULL;
> + char *charAlias = NULL;
> +
> + if (chardev->source.type != VIR_DOMAIN_CHR_TYPE_TCP)
> + return 0;
> +
> + cfg = virQEMUDriverGetConfig(driver);
> + if (qemuDomainSupportTLSChardevTCP(cfg, &chardev->source) &&
> + cfg->chardevTLSx509secretUUID) {
> + qemuDomainChardevPrivatePtr chardevPriv =
> + QEMU_DOMAIN_CHARDEV_PRIVATE(chardev);
> +
> + if (virUUIDParse(cfg->chardevTLSx509secretUUID,
> + seclookupdef.u.uuid) < 0) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("malformed chardev TLS secret uuid in
qemu.conf"));
> + goto error;
> + }
> + seclookupdef.type = VIR_SECRET_LOOKUP_TYPE_UUID;
> +
> + if (VIR_ALLOC(secinfo) < 0)
> + goto error;
> +
> + if (!(charAlias = qemuAliasChardevFromDevAlias(chardev->info.alias)))
> + goto error;
> +
> + if (qemuDomainSecretSetup(conn, priv, secinfo, charAlias,
> + VIR_SECRET_USAGE_TYPE_TLS, NULL,
> + &seclookupdef, false) < 0)
> + goto error;
> +
> + if (secinfo->type == VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("TLS X.509 requires encrypted secrets "
> + "to be supported"));
> + goto error;
> + }
> +
> + chardevPriv->secinfo = secinfo;
> + }
> +
> + VIR_FREE(charAlias);
> + virObjectUnref(cfg);
> + return 0;
> +
> + error:
> + virObjectUnref(cfg);
> + qemuDomainSecretInfoFree(&secinfo);
> + return -1;
> +}
> +
> +
> /* qemuDomainSecretDestroy:
> * @vm: Domain object
> *
> @@ -1236,11 +1326,15 @@ qemuDomainSecretDestroy(virDomainObjPtr vm)
>
> for (i = 0; i < vm->def->nhostdevs; i++)
> qemuDomainSecretHostdevDestroy(vm->def->hostdevs[i]);
> +
> + for (i = 0; i < vm->def->nserials; i++)
> + qemuDomainSecretChardevDestroy(vm->def->serials[i]);
This should iterate over all chardevs, not only over serial ...
> }
>
>
> /* qemuDomainSecretPrepare:
> * @conn: Pointer to connection
> + * @driver: Pointer to driver object
> * @vm: Domain object
> *
> * For any objects that may require an auth/secret setup, create a
> @@ -1253,6 +1347,7 @@ qemuDomainSecretDestroy(virDomainObjPtr vm)
> */
> int
> qemuDomainSecretPrepare(virConnectPtr conn,
> + virQEMUDriverPtr driver,
> virDomainObjPtr vm)
> {
> qemuDomainObjPrivatePtr priv = vm->privateData;
> @@ -1269,6 +1364,12 @@ qemuDomainSecretPrepare(virConnectPtr conn,
> return -1;
> }
>
> + for (i = 0; i < vm->def->nserials; i++) {
> + if (qemuDomainSecretChardevPrepare(conn, driver, priv,
> + vm->def->serials[i]) < 0)
> + return -1;
> + }
... and same here.
Pavel
> +
> return 0;
> }
>
> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index 156e0fc..1bb2f2d 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -726,11 +726,23 @@ int qemuDomainSecretHostdevPrepare(virConnectPtr conn,
> virDomainHostdevDefPtr hostdev)
> ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
>
> +void qemuDomainSecretChardevDestroy(virDomainChrDefPtr chardev)
> + ATTRIBUTE_NONNULL(1);
> +
> +int qemuDomainSecretChardevPrepare(virConnectPtr conn,
> + virQEMUDriverPtr driver,
> + qemuDomainObjPrivatePtr priv,
> + virDomainChrDefPtr chardev)
> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
> + ATTRIBUTE_NONNULL(4);
> +
> void qemuDomainSecretDestroy(virDomainObjPtr vm)
> ATTRIBUTE_NONNULL(1);
>
> -int qemuDomainSecretPrepare(virConnectPtr conn, virDomainObjPtr vm)
> - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
> +int qemuDomainSecretPrepare(virConnectPtr conn,
> + virQEMUDriverPtr driver,
> + virDomainObjPtr vm)
> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
>
> int qemuDomainDefValidateDiskLunSource(const virStorageSource *src)
> ATTRIBUTE_NONNULL(1);
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 9643a68..59c3b25 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -1734,6 +1734,7 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
> if (qemuBuildTLSx509BackendProps(cfg->chardevTLSx509certdir,
> dev->data.tcp.listen,
> cfg->chardevTLSx509verify,
> + NULL,
> priv->qemuCaps,
> &tlsProps) < 0)
> goto cleanup;
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index d641f33..643741d 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -5157,8 +5157,8 @@ qemuProcessPrepareDomain(virConnectPtr conn,
> if (qemuDomainMasterKeyCreate(vm) < 0)
> goto cleanup;
>
> - VIR_DEBUG("Add secrets to disks and hostdevs");
> - if (qemuDomainSecretPrepare(conn, vm) < 0)
> + VIR_DEBUG("Add secrets to disks, hostdevs, and chardevs");
> + if (qemuDomainSecretPrepare(conn, driver, vm) < 0)
> goto cleanup;
>
> for (i = 0; i < vm->def->nchannels; i++) {
> diff --git
a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
> new file mode 100644
> index 0000000..7f9fedb
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
> @@ -0,0 +1,38 @@
> +LC_ALL=C \
> +PATH=/bin \
> +HOME=/home/test \
> +USER=test \
> +LOGNAME=test \
> +QEMU_AUDIO_DRV=none \
> +/usr/bin/qemu \
> +-name QEMUGuest1 \
> +-S \
> +-object secret,id=masterKey0,format=raw,\
> +file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
> +-M pc \
> +-m 214 \
> +-smp 1,sockets=1,cores=1,threads=1 \
> +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
> +-nographic \
> +-nodefconfig \
> +-nodefaults \
> +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
> +server,nowait \
> +-mon chardev=charmonitor,id=monitor,mode=readline \
> +-no-acpi \
> +-boot c \
> +-usb \
> +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
> +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
> +-chardev udp,id=charserial0,host=127.0.0.1,port=2222,localaddr=127.0.0.1,\
> +localport=1111 \
> +-device isa-serial,chardev=charserial0,id=serial0 \
> +-object secret,id=charserial1-secret0,\
> +data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
> +keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
> +-object tls-creds-x509,id=objcharserial1_tls0,dir=/etc/pki/libvirt-chardev,\
> +endpoint=client,verify-peer=no,passwordid=charserial1-secret0 \
> +-chardev socket,id=charserial1,host=127.0.0.1,port=5555,\
> +tls-creds=objcharserial1_tls0 \
> +-device isa-serial,chardev=charserial1,id=serial1 \
> +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
> diff --git
a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml
b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml
> new file mode 100644
> index 0000000..23c244b
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml
> @@ -0,0 +1,50 @@
> +<domain type='qemu'>
> + <name>QEMUGuest1</name>
> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
> + <memory unit='KiB'>219136</memory>
> + <currentMemory unit='KiB'>219136</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='i686' machine='pc'>hvm</type>
> + <boot dev='hd'/>
> + </os>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu</emulator>
> + <disk type='block' device='disk'>
> + <source dev='/dev/HostVG/QEMUGuest1'/>
> + <target dev='hda' bus='ide'/>
> + <address type='drive' controller='0' bus='0'
target='0' unit='0'/>
> + </disk>
> + <controller type='usb' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x2'/>
> + </controller>
> + <controller type='ide' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x1'/>
> + </controller>
> + <controller type='pci' index='0'
model='pci-root'/>
> + <serial type='udp'>
> + <source mode='bind' host='127.0.0.1'
service='1111'/>
> + <source mode='connect' host='127.0.0.1'
service='2222'/>
> + <target port='0'/>
> + </serial>
> + <serial type='tcp'>
> + <source mode='connect' host='127.0.0.1'
service='5555' tls='yes'/>
> + <protocol type='raw'/>
> + <target port='0'/>
> + </serial>
> + <console type='udp'>
> + <source mode='bind' host='127.0.0.1'
service='1111'/>
> + <source mode='connect' host='127.0.0.1'
service='2222'/>
> + <target type='serial' port='0'/>
> + </console>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
> index 52d85fa..541a498 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -1170,6 +1170,23 @@ mymain(void)
> DO_TEST("serial-tcp-tlsx509-chardev-notls",
> QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG,
> QEMU_CAPS_OBJECT_TLS_CREDS_X509);
> + VIR_FREE(driver.config->chardevTLSx509certdir);
> + if (VIR_STRDUP_QUIET(driver.config->chardevTLSx509certdir,
"/etc/pki/libvirt-chardev") < 0)
> + return EXIT_FAILURE;
> + if (VIR_STRDUP_QUIET(driver.config->chardevTLSx509secretUUID,
> + "6fd3f62d-9fe7-4a4e-a869-7acd6376d8ea") < 0)
> + return EXIT_FAILURE;
> +# ifdef HAVE_GNUTLS_CIPHER_ENCRYPT
> + DO_TEST("serial-tcp-tlsx509-secret-chardev",
> + QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG,
> + QEMU_CAPS_OBJECT_SECRET,
> + QEMU_CAPS_OBJECT_TLS_CREDS_X509);
> +# else
> + DO_TEST_FAILURE("serial-tcp-tlsx509-secret-chardev",
> + QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG,
> + QEMU_CAPS_OBJECT_SECRET,
> + QEMU_CAPS_OBJECT_TLS_CREDS_X509);
> +# endif
> driver.config->chardevTLS = 0;
> VIR_FREE(driver.config->chardevTLSx509certdir);
> DO_TEST("serial-many-chardev",
> --
> 2.7.4
>
> --
> libvir-list mailing list
> libvir-list(a)redhat.com
>
https://www.redhat.com/mailman/listinfo/libvir-list