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(a)redhat.com>
---
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