[libvirt] [PATCH 0/3] qemu: Allow turing of SSL verification for https/ftps drives

This is a followup to the qemu cookie series and should be applied on top of it. Since I already fixed a few things in the original series this would not apply cleanly, thus you can fetch it at: git fetch git://pipo.sk/pipo/libvirt.git qemu-ssl-verify-off Peter Krempa (3): conf: Use only one temporary string in virDomainDiskSourceParse conf: Add support for modifying ssl validation for https/ftps disks qemu: command: Implement ssl verification configuration docs/formatdomain.html.in | 9 ++++ docs/schemas/domaincommon.rng | 50 +++++++++++++++++++++- src/conf/domain_conf.c | 34 ++++++++++++--- src/qemu/qemu_command.c | 27 +++++++++++- src/util/virstoragefile.h | 1 + .../generic-disk-network-http.xml | 2 + .../qemuxml2argv-disk-drive-network-http.args | 2 +- .../qemuxml2argv-disk-drive-network-http.xml | 1 + 8 files changed, 114 insertions(+), 12 deletions(-) -- 2.12.2

--- src/conf/domain_conf.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 27d505d5b..a951282db 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7598,7 +7598,7 @@ virDomainDiskSourceParse(xmlNodePtr node, virStorageSourcePtr src) { int ret = -1; - char *protocol = NULL; + char *tmp = NULL; xmlNodePtr saveNode = ctxt->node; xmlNodePtr tmpnode; @@ -7615,17 +7615,18 @@ virDomainDiskSourceParse(xmlNodePtr node, src->path = virXMLPropString(node, "dir"); break; case VIR_STORAGE_TYPE_NETWORK: - if (!(protocol = virXMLPropString(node, "protocol"))) { + if (!(tmp = virXMLPropString(node, "protocol"))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing network source protocol type")); goto cleanup; } - if ((src->protocol = virStorageNetProtocolTypeFromString(protocol)) <= 0) { + if ((src->protocol = virStorageNetProtocolTypeFromString(tmp)) <= 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown protocol type '%s'"), protocol); + _("unknown protocol type '%s'"), tmp); goto cleanup; } + VIR_FREE(tmp); if (!(src->path = virXMLPropString(node, "name")) && src->protocol != VIR_STORAGE_NET_PROTOCOL_NBD) { @@ -7638,7 +7639,6 @@ virDomainDiskSourceParse(xmlNodePtr node, * as a part of the path. This is hard to work with when dealing with * relative names. Split out the volume into a separate variable */ if (src->path && src->protocol == VIR_STORAGE_NET_PROTOCOL_GLUSTER) { - char *tmp; if (!(tmp = strchr(src->path, '/')) || tmp == src->path) { virReportError(VIR_ERR_XML_ERROR, @@ -7653,6 +7653,7 @@ virDomainDiskSourceParse(xmlNodePtr node, goto cleanup; tmp[0] = '\0'; + tmp = NULL; } /* snapshot currently works only for remote disks */ @@ -7692,7 +7693,7 @@ virDomainDiskSourceParse(xmlNodePtr node, ret = 0; cleanup: - VIR_FREE(protocol); + VIR_FREE(tmp); ctxt->node = saveNode; return ret; } -- 2.12.2

To allow turning of verification of SSL cerificates add a new element <ssl> to the disk source XML which will allow configuring the validation process using the 'verify' attribute. --- docs/formatdomain.html.in | 9 ++++ docs/schemas/domaincommon.rng | 50 +++++++++++++++++++++- src/conf/domain_conf.c | 21 ++++++++- src/util/virstoragefile.h | 1 + .../generic-disk-network-http.xml | 2 + 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index ab70edff3..351122fe1 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2256,6 +2256,7 @@ <driver name='qemu' type='raw'/> <source protocol="https" name="url_path"> <host name="hostname" port="443"/> + <ssl verify="no"/> </source> <target dev='hdf' bus='ide' tray='open'/> <readonly/> @@ -2602,6 +2603,14 @@ possible to pass one or more cookies. The cookie name and value must conform to the HTTP specification. </dd> + <dt><code>ssl</code></dt> + <dd> + For <code>https</code> and <code>ftps</code> accessed storage it's + possible to tweak the SSL transport parameters with this element. + The <code>verify</code> attribute allows to turn on or of SSL + certificate validation. Supported values are <code>yes</code> and + <code>no</code>. <span class="since">Since 3.3.0</span> + </dd> </dl> <p> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index b2fa72381..e6bcd6835 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1574,13 +1574,41 @@ </element> </define> + <define name="diskSourceNetworkProtocolSSLVerify"> + <element name="ssl"> + <attribute name="verify"> + <ref name="virYesNo"/> + </attribute> + <empty/> + </element> + </define> + + <define name="diskSourceNetworkProtocolHTTPS"> + <element name="source"> + <interleave> + <attribute name="protocol"> + <choice> + <value>https</value> + </choice> + </attribute> + <attribute name="name"/> + <ref name="diskSourceNetworkHost"/> + <optional> + <ref name="diskSourceNetworkProtocolHTTPCookies"/> + </optional> + <optional> + <ref name="diskSourceNetworkProtocolSSLVerify"/> + </optional> + </interleave> + </element> + </define> + <define name="diskSourceNetworkProtocolHTTP"> <element name="source"> <interleave> <attribute name="protocol"> <choice> <value>http</value> - <value>https</value> </choice> </attribute> <attribute name="name"/> @@ -1592,6 +1620,23 @@ </element> </define> + <define name="diskSourceNetworkProtocolFTPS"> + <element name="source"> + <interleave> + <attribute name="protocol"> + <choice> + <value>ftps</value> + </choice> + </attribute> + <attribute name="name"/> + <ref name="diskSourceNetworkHost"/> + <optional> + <ref name="diskSourceNetworkProtocolSSLVerify"/> + </optional> + </interleave> + </element> + </define> + <define name="diskSourceNetworkProtocolSimple"> <element name="source"> <attribute name="protocol"> @@ -1599,7 +1644,6 @@ <value>sheepdog</value> <value>iscsi</value> <value>ftp</value> - <value>ftps</value> <value>tftp</value> </choice> </attribute> @@ -1646,6 +1690,8 @@ <ref name="diskSourceNetworkProtocolGluster"/> <ref name="diskSourceNetworkProtocolRBD"/> <ref name="diskSourceNetworkProtocolHTTP"/> + <ref name="diskSourceNetworkProtocolHTTPS"/> + <ref name="diskSourceNetworkProtocolFTPS"/> <ref name="diskSourceNetworkProtocolSimple"/> </choice> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a951282db..e750c0f07 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7671,6 +7671,20 @@ virDomainDiskSourceParse(xmlNodePtr node, if (virDomainStorageCookiesParse(tmpnode, ctxt, src) < 0) goto cleanup; } + + if ((src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS || + src->protocol == VIR_STORAGE_NET_PROTOCOL_FTPS) && + (tmp = virXPathString("string(./ssl/@verify)", ctxt))) { + int verify; + if ((verify = virTristateBoolTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid ssl verify mode '%s'"), tmp); + goto cleanup; + } + VIR_FREE(tmp); + + src->sslverify = verify; + } break; case VIR_STORAGE_TYPE_VOLUME: if (virDomainDiskSourcePoolDefParse(node, &src->srcpool) < 0) @@ -20892,7 +20906,8 @@ virDomainDiskSourceFormatNetwork(virBufferPtr buf, VIR_FREE(path); - if (src->nhosts == 0 && !src->snapshot && !src->configFile && src->ncookies == 0) { + if (src->nhosts == 0 && !src->snapshot && !src->configFile && + src->ncookies == 0 && src->sslverify == VIR_TRISTATE_BOOL_ABSENT) { virBufferAddLit(buf, "/>\n"); } else { virBufferAddLit(buf, ">\n"); @@ -20917,6 +20932,10 @@ virDomainDiskSourceFormatNetwork(virBufferPtr buf, if (virDomainDiskSourceFormatNetworkCookies(buf, src) < 0) return -1; + if (src->sslverify != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, "<ssl verify='%s'/>\n", + virTristateBoolTypeToString(src->sslverify)); + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</source>\n"); } diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 42d9eac61..4f7509cff 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -250,6 +250,7 @@ struct _virStorageSource { virStorageSourcePoolDefPtr srcpool; virStorageAuthDefPtr auth; virStorageEncryptionPtr encryption; + virTristateBool sslverify; char *driverName; int format; /* virStorageFileFormat in domain backing chains, but diff --git a/tests/genericxml2xmlindata/generic-disk-network-http.xml b/tests/genericxml2xmlindata/generic-disk-network-http.xml index c5da23604..0821b63df 100644 --- a/tests/genericxml2xmlindata/generic-disk-network-http.xml +++ b/tests/genericxml2xmlindata/generic-disk-network-http.xml @@ -25,6 +25,7 @@ <driver name='qemu' type='raw'/> <source protocol='https' name='test2.img'> <host name='example.org'/> + <ssl verify='no'/> </source> <target dev='vdb' bus='virtio'/> </disk> @@ -47,6 +48,7 @@ <cookie name='test'>testcookievalue</cookie> <cookie name='test2'>blurb</cookie> </cookies> + <ssl verify='yes'/> </source> <target dev='vdd' bus='virtio'/> </disk> -- 2.12.2

Allow disabling of SSL certificate validation for HTTPS and FTPS drives in qemu. --- src/qemu/qemu_command.c | 27 ++++++++++++++++++++-- .../qemuxml2argv-disk-drive-network-http.args | 2 +- .../qemuxml2argv-disk-drive-network-http.xml | 1 + 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 980559859..a54b48eaf 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1537,14 +1537,37 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk, case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: case VIR_STORAGE_NET_PROTOCOL_ISCSI: case VIR_STORAGE_NET_PROTOCOL_FTP: - case VIR_STORAGE_NET_PROTOCOL_FTPS: case VIR_STORAGE_NET_PROTOCOL_TFTP: case VIR_STORAGE_NET_PROTOCOL_SSH: case VIR_STORAGE_NET_PROTOCOL_LAST: break; - case VIR_STORAGE_NET_PROTOCOL_HTTP: + case VIR_STORAGE_NET_PROTOCOL_FTPS: + if (disk->src->sslverify != 0) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCK_CURL_OPTIONS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu does not support ssl options")); + goto cleanup; + } + + virBufferAsprintf(buf, "file.sslverify=%s,", + virTristateSwitchTypeToString(disk->src->sslverify)); + } + break; + case VIR_STORAGE_NET_PROTOCOL_HTTPS: + if (disk->src->sslverify != 0) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCK_CURL_OPTIONS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu does not support ssl options")); + goto cleanup; + } + + virBufferAsprintf(buf, "file.sslverify=%s,", + virTristateSwitchTypeToString(disk->src->sslverify)); + } + /* fallthrough */ + case VIR_STORAGE_NET_PROTOCOL_HTTP: if (disk->src->ncookies > 0) { if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCK_CURL_OPTIONS)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-http.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-http.args index fb4a3506f..e1bfd42a8 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-http.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-http.args @@ -30,7 +30,7 @@ file.cookie=test=testcookievalue; test2=blurb,format=raw,if=none,\ id=drive-virtio-disk2' \ -device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk2,\ id=virtio-disk2 \ --drive 'file=https://example.org:1234/test4.img,\ +-drive 'file=https://example.org:1234/test4.img,file.sslverify=off,\ file.cookie=test=testcookievalue; test2=blurb,format=raw,if=none,\ id=drive-virtio-disk3' \ -device virtio-blk-pci,bus=pci.0,addr=0x6,drive=drive-virtio-disk3,\ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-http.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-http.xml index c5da23604..114480024 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-http.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-http.xml @@ -47,6 +47,7 @@ <cookie name='test'>testcookievalue</cookie> <cookie name='test2'>blurb</cookie> </cookies> + <ssl verify='no'/> </source> <target dev='vdd' bus='virtio'/> </disk> -- 2.12.2
participants (1)
-
Peter Krempa