[PATCH 6/6] qemu: Add the ability to hotplug the TLS X.509 environment

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If the incoming XML defined a path to a TLS X.509 certificate environment,
add the necessary 'tls-creds-x509' object to the VIR_DOMAIN_CHR_TYPE_TCP
character device.

Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx>
---
 src/qemu/qemu_command.c      | 69 +++++++++++++++++++++++++++++++-------------
 src/qemu/qemu_command.h      |  6 ++++
 src/qemu/qemu_hotplug.c      | 27 ++++++++++++++++-
 src/qemu/qemu_monitor_json.c |  9 ++++++
 4 files changed, 90 insertions(+), 21 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3656683..c3e17cf 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -704,23 +704,21 @@ qemuBuildRBDSecinfoURI(virBufferPtr buf,
 /* qemuBuildTLSx509BackendProps:
  * @tlspath: path to the TLS credentials
  * @listen: boolen listen for client or server setting
- * @alias: Alias for the parent (this code will add a "_tls0" to alias)
+ * @qemuCaps: capabilities
  * @propsret: json properties to return
  *
  * Create a backend string for the tls-creds-x509 object.
  *
  * Returns 0 on success, -1 on failure with error set.
  */
-static int
+int
 qemuBuildTLSx509BackendProps(const char *tlspath,
                              bool listen,
-                             const char *inalias,
                              virQEMUCapsPtr qemuCaps,
                              virJSONValuePtr *propsret)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     char *path = NULL;
-    char *alias = NULL;
     int ret = -1;
 
     if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_TLS_CREDS_X509)) {
@@ -734,9 +732,6 @@ qemuBuildTLSx509BackendProps(const char *tlspath,
         goto cleanup;
     path = virBufferContentAndReset(&buf);
 
-    if (virAsprintf(&alias, "obj%s_tls0", inalias) < 0)
-        goto cleanup;
-
     if (virJSONValueObjectCreate(propsret,
                                  "s:dir", path,
                                  "s:endpoint", (listen ? "server": "client"),
@@ -748,7 +743,51 @@ qemuBuildTLSx509BackendProps(const char *tlspath,
  cleanup:
     virBufferFreeAndReset(&buf);
     VIR_FREE(path);
+    return ret;
+}
+
+
+/* qemuBuildTLSx509CommandLine:
+ * @cmd: Pointer to command
+ * @tlspath: path to the TLS credentials
+ * @listen: boolen listen for client or server setting
+ * @inalias: Alias for the parent (this code will add a "_tls0" to alias)
+ * @qemuCaps: capabilities
+ *
+ * Create the command line for a TLS object
+ *
+ * Returns 0 on success, -1 on failure with error set.
+ */
+static int
+qemuBuildTLSx509CommandLine(virCommandPtr cmd,
+                            const char *tlspath,
+                            bool listen,
+                            const char *inalias,
+                            virQEMUCapsPtr qemuCaps)
+{
+    int ret = -1;
+    char *alias = NULL;
+    virJSONValuePtr props = NULL;
+    char *tmp = NULL;
+
+    if (qemuBuildTLSx509BackendProps(tlspath, listen, qemuCaps, &props) < 0)
+        return -1;
+
+    if (virAsprintf(&alias, "obj%s_tls0", inalias) < 0)
+        goto cleanup;
+
+    if (!(tmp = virQEMUBuildObjectCommandlineFromJSON("tls-creds-x509",
+                                                      alias, props)))
+        goto cleanup;
+
+    virCommandAddArgList(cmd, "-object", tmp, NULL);
+
+    ret = 0;
+
+ cleanup:
+    virJSONValueFree(props);
     VIR_FREE(alias);
+    VIR_FREE(tmp);
     return ret;
 }
 
@@ -4721,7 +4760,6 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
                        virQEMUCapsPtr qemuCaps)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
-    virJSONValuePtr props = NULL;
     bool telnet;
 
     switch (dev->type) {
@@ -4800,19 +4838,11 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
                           dev->data.tcp.listen ? ",server,nowait" : "");
 
         if (dev->data.tcp.tlspath) {
-            char *tmp;
-            if (qemuBuildTLSx509BackendStr(dev->data.tcp.tlspath,
-                                           dev->data.tcp.listen,
-                                           alias, qemuCaps, &props) < 0)
+            if (qemuBuildTLSx509CommandLine(cmd, dev->data.tcp.tlspath,
+                                            dev->data.tcp.listen,
+                                            alias, qemuCaps) < 0)
                 goto error;
 
-            if (!(tmp = virQEMUBuildObjectCommandlineFromJSON("tls-creds-x509",
-                                                              alias, props)))
-                goto error;
-
-            virCommandAddArgList(cmd, "-object", tmp, NULL);
-            VIR_FREE(tmp);
-
             virBufferAsprintf(&buf, ",tls-creds=obj%s_tls0", alias);
         }
         break;
@@ -4870,7 +4900,6 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
 
  error:
     virBufferFreeAndReset(&buf);
-    virJSONValueFree(props);
     return NULL;
 }
 
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index f0ffe21..ea5c728 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -61,6 +61,12 @@ virCommandPtr qemuBuildCommandLine(virQEMUDriverPtr driver,
                                    const char *domainLibDir)
     ATTRIBUTE_NONNULL(15);
 
+/* Generate the object properties for a tls-creds-x509 */
+int qemuBuildTLSx509BackendProps(const char *tlspath,
+                                 bool listen,
+                                 virQEMUCapsPtr qemuCaps,
+                                 virJSONValuePtr *propsret);
+
 /* Generate '-device' string for chardev device */
 int
 qemuBuildChrDeviceStr(char **deviceStr,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 7d05073..c9e9d3b 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1499,7 +1499,10 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainDefPtr vmdef = vm->def;
     char *devstr = NULL;
+    virDomainChrSourceDefPtr dev = &chr->source;
     char *charAlias = NULL;
+    virJSONValuePtr props = NULL;
+    char *objAlias = NULL;
     bool need_release = false;
 
     if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
@@ -1523,8 +1526,25 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
     if (qemuDomainChrPreInsert(vmdef, chr) < 0)
         goto cleanup;
 
+    if (dev->data.tcp.tlspath) {
+
+        if (qemuBuildTLSx509BackendProps(dev->data.tcp.tlspath,
+                                         dev->data.tcp.listen,
+                                         priv->qemuCaps,
+                                         &props) < 0)
+            goto cleanup;
+
+        if (virAsprintf(&objAlias, "obj%s_tls0", chr->info.alias) < 0)
+            goto cleanup;
+    }
+
     qemuDomainObjEnterMonitor(driver, vm);
-    if (qemuMonitorAttachCharDev(priv->mon, charAlias, &chr->source) < 0)
+
+    if (objAlias && qemuMonitorAddObject(priv->mon, "tls-creds-x509",
+                                         objAlias, props) < 0)
+        goto failobject;
+
+    if (qemuMonitorAttachCharDev(priv->mon, charAlias, dev) < 0)
         goto failchardev;
 
     if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
@@ -1542,6 +1562,8 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
         qemuDomainChrInsertPreAllocCleanup(vm->def, chr);
     if (ret < 0 && need_release)
         qemuDomainReleaseDeviceAddress(vm, &chr->info, NULL);
+    VIR_FREE(objAlias);
+    virJSONValueFree(props);
     VIR_FREE(charAlias);
     VIR_FREE(devstr);
     return ret;
@@ -1550,6 +1572,9 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
     /* detach associated chardev on error */
     qemuMonitorDetachCharDev(priv->mon, charAlias);
  failchardev:
+    /* Remove the object */
+    ignore_value(qemuMonitorDelObject(priv->mon, objAlias));
+ failobject:
     ignore_value(qemuDomainObjExitMonitor(driver, vm));
     goto audit;
 }
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 380ddab..81e89cc 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6137,6 +6137,7 @@ qemuMonitorJSONAttachCharDevCommand(const char *chrID,
     virJSONValuePtr data = NULL;
     virJSONValuePtr addr = NULL;
     const char *backend_type = NULL;
+    char *tlsalias = NULL;
     bool telnet;
 
     if (!(backend = virJSONValueNewObject()) ||
@@ -6182,6 +6183,13 @@ qemuMonitorJSONAttachCharDevCommand(const char *chrID,
             virJSONValueObjectAppendBoolean(data, "telnet", telnet) < 0 ||
             virJSONValueObjectAppendBoolean(data, "server", chr->data.tcp.listen) < 0)
             goto error;
+        if (chr->data.tcp.tlspath) {
+            if (virAsprintf(&tlsalias, "obj%s_tls0", chrID) < 0)
+                goto error;
+
+            if (virJSONValueObjectAppendString(data, "tls-creds", tlsalias) < 0)
+                goto error;
+        }
         break;
 
     case VIR_DOMAIN_CHR_TYPE_UDP:
@@ -6247,6 +6255,7 @@ qemuMonitorJSONAttachCharDevCommand(const char *chrID,
     return ret;
 
  error:
+    VIR_FREE(tlsalias);
     virJSONValueFree(addr);
     virJSONValueFree(data);
     virJSONValueFree(backend);
-- 
2.5.5

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



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]