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