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 <jfer...@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 d044a8c..e54e258 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7489,7 +7489,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 eb5de7b..3936a14 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1639,7 +1639,8 @@ qemuDomainAttachChrDeviceAssignAddr(virDomainDefPtr def,
     return ret;
 }
 
-int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
+int qemuDomainAttachChrDevice(virConnectPtr conn,
+                              virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
                               virDomainChrDefPtr chr)
 {
@@ -1653,8 +1654,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 &&
@@ -1678,11 +1682,29 @@ 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.disableTLS) {
+        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 0a5f068..f84908f 100644
--- a/tests/qemuhotplugtest.c
+++ b/tests/qemuhotplugtest.c
@@ -117,7 +117,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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to