https://bugzilla.redhat.com/show_bug.cgi?id=1300776
Complete the implementation of support for TLS encryption on
chardev TCP transports by adding the hotplug ability of a secret
to generate the passwordid for the TLS object
Likewise, add the ability to hot unplug that secret object as well
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/qemu/qemu_driver.c | 2 +-
src/qemu/qemu_hotplug.c | 62 +++++++++++++++++++++++++++++++++++++++++++++----
src/qemu/qemu_hotplug.h | 3 ++-
tests/qemuhotplugtest.c | 2 +-
4 files changed, 61 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 29a7e3f..aa2a974 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7569,7 +7569,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
break;
case VIR_DOMAIN_DEVICE_CHR:
- ret = qemuDomainAttachChrDevice(driver, vm,
+ ret = qemuDomainAttachChrDevice(conn, driver, vm,
dev->data.chr);
if (!ret) {
alias = dev->data.chr->info.alias;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 8e4057c..31a822d 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1638,7 +1638,8 @@ qemuDomainAttachChrDeviceAssignAddr(virDomainDefPtr def,
return ret;
}
-int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
+int qemuDomainAttachChrDevice(virConnectPtr conn,
+ virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainChrDefPtr chr)
{
@@ -1652,8 +1653,11 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
char *charAlias = NULL;
bool chardevAttached = false;
bool tlsobjAdded = false;
+ bool secobjAdded = false;
virJSONValuePtr tlsProps = NULL;
char *tlsAlias = NULL;
+ virJSONValuePtr secProps = NULL;
+ char *secAlias = NULL;
bool need_release = false;
if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
@@ -1677,12 +1681,30 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
if (qemuDomainChrPreInsert(vmdef, chr) < 0)
goto cleanup;
+ if (qemuDomainSecretChardevPrepare(conn, driver, priv, chr) < 0)
+ goto cleanup;
+
if (cfg->chardevTLS &&
dev->data.tcp.haveTLS == VIR_TRISTATE_BOOL_YES) {
+ qemuDomainChardevPrivatePtr chardevPriv =
+ QEMU_DOMAIN_CHARDEV_PRIVATE(chr);
+ qemuDomainSecretInfoPtr secinfo = chardevPriv->secinfo;
+
+ /* Add a secret object in order to access the TLS environment.
+ * The secinfo will only be created for serial TCP device. */
+ if (secinfo) {
+ if (qemuBuildSecretInfoProps(secinfo, &secProps) < 0)
+ goto cleanup;
+
+ if (!(secAlias = qemuDomainGetSecretAESAlias(chr->info.alias,
+ false)))
+ goto cleanup;
+ }
+
if (qemuBuildTLSx509BackendProps(cfg->chardevTLSx509certdir,
dev->data.tcp.listen,
cfg->chardevTLSx509verify,
- NULL,
+ secAlias,
priv->qemuCaps,
&tlsProps) < 0)
goto cleanup;
@@ -1693,6 +1715,15 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
}
qemuDomainObjEnterMonitor(driver, vm);
+ if (secAlias) {
+ rc = qemuMonitorAddObject(priv->mon, "secret",
+ secAlias, secProps);
+ secProps = NULL;
+ if (rc < 0)
+ goto exit_monitor;
+ secobjAdded = true;
+ }
+
if (tlsAlias) {
rc = qemuMonitorAddObject(priv->mon, "tls-creds-x509",
tlsAlias, tlsProps);
@@ -1723,6 +1754,8 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
qemuDomainReleaseDeviceAddress(vm, &chr->info, NULL);
VIR_FREE(tlsAlias);
virJSONValueFree(tlsProps);
+ VIR_FREE(secAlias);
+ virJSONValueFree(secProps);
VIR_FREE(charAlias);
VIR_FREE(devstr);
virObjectUnref(cfg);
@@ -1730,6 +1763,8 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
exit_monitor:
orig_err = virSaveLastError();
+ if (secobjAdded)
+ ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
if (tlsobjAdded)
ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
/* detach associated chardev on error */
@@ -4319,6 +4354,7 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
virDomainDefPtr vmdef = vm->def;
virDomainChrDefPtr tmpChr;
char *objAlias = NULL;
+ char *secAlias = NULL;
char *devstr = NULL;
if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
@@ -4332,9 +4368,21 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
sa_assert(tmpChr->info.alias);
- if (cfg->chardevTLS &&
- !(objAlias = qemuAliasTLSObjFromChardevAlias(tmpChr->info.alias)))
- goto cleanup;
+ if (cfg->chardevTLS) {
+ if (!(objAlias = qemuAliasTLSObjFromChardevAlias(tmpChr->info.alias)))
+ goto cleanup;
+
+ /* Best shot at this as the secinfo is destroyed after process launch
+ * and this path does not recreate it. Thus, if the config has the
+ * secret UUID and we have a serial TCP chardev, then formulate a
+ * secAlias which we'll attempt to destroy. */
+ if (cfg->chardevTLSx509haveUUID &&
+ tmpChr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
+ tmpChr->source.type == VIR_DOMAIN_CHR_TYPE_TCP &&
+ !(secAlias = qemuDomainGetSecretAESAlias(tmpChr->info.alias,
+ false)))
+ goto cleanup;
+ }
if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0)
goto cleanup;
@@ -4348,6 +4396,10 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
if (objAlias && qemuMonitorDelObject(priv->mon, objAlias) < 0)
goto exit_monitor;
+ /* If it fails, then so be it - it was a best shot */
+ if (secAlias)
+ ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
+
if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup;
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index b048cf4..8f23176 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -92,7 +92,8 @@ int qemuDomainAttachLease(virQEMUDriverPtr driver,
int qemuDomainDetachLease(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainLeaseDefPtr lease);
-int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
+int qemuDomainAttachChrDevice(virConnectPtr conn,
+ virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainChrDefPtr chr);
int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c
index 43eb1cf..14561a8 100644
--- a/tests/qemuhotplugtest.c
+++ b/tests/qemuhotplugtest.c
@@ -118,7 +118,7 @@ testQemuHotplugAttach(virDomainObjPtr vm,
ret = qemuDomainAttachDeviceDiskLive(NULL, &driver, vm, dev);
break;
case VIR_DOMAIN_DEVICE_CHR:
- ret = qemuDomainAttachChrDevice(&driver, vm, dev->data.chr);
+ ret = qemuDomainAttachChrDevice(NULL, &driver, vm, dev->data.chr);
break;
default:
VIR_TEST_VERBOSE("device type '%s' cannot be attached\n",
--
2.7.4