Define, parse, and format a key secret element for a chardev tcp backend. This secret will be used in conjunction with the chartcp_tls_x509_cert_dir in order to provide the secret to the TLS encrypted TCP chardev. <secret type='tls' usage='tlsexample'/> Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- docs/formatdomain.html.in | 29 ++++++++++++ docs/schemas/domaincommon.rng | 21 +++++++++ src/conf/domain_conf.c | 35 +++++++++++++++ src/conf/domain_conf.h | 3 ++ ...uxml2argv-serial-tcp-tlsx509-secret-chardev.xml | 51 ++++++++++++++++++++++ ...ml2xmlout-serial-tcp-tlsx509-secret-chardev.xml | 1 + tests/qemuxml2xmltest.c | 1 + 7 files changed, 141 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml create mode 120000 tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-secret-chardev.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fa88839..b1d9741 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -6097,6 +6097,35 @@ qemu-kvm -net nic,model=? /dev/null </devices> ...</pre> + <p> + <span class="since">Since 2.2.0,</span> some hypervisors support using + a TLS X.509 certificate environment in order to encrypt the TCP + connection. In order to provide the passphrase for the certificates, + provide a <code>secret</code> element. The <code>secret</code> element + takes two required attributes <code>type</code> and either + <code>UUID</code> or <code>usage</code>. The supported <code>type</code> + is a "passphrase" secret referenced via either attribute + <code>uuid</code> or <code>usage</code>. + </p> +<pre> + ... + <devices> + <serial type="tcp"> + <source mode="connect" host="0.0.0.0" service="2445"/> + <protocol type="raw"/> + <secret type='passphrase' usage='keyexample'/> + <target port="1"/> + </serial> + ... + <serial type="tcp"> + <source mode="bind" host="127.0.0.1" service="2445"/> + <protocol type="raw"/> + <target port="1"/> + <secret type='passphrase' usage='keyexample'/> + </serial> + </devices> + ...</pre> + <h6><a name="elementsCharUDP">UDP network console</a></h6> <p> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index cb9f134..5702e3b 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3264,6 +3264,9 @@ <ref name="qemucdevTgtDef"/> </optional> <optional> + <ref name="qemucdevSecret"/> + </optional> + <optional> <ref name="alias"/> </optional> <optional> @@ -3315,6 +3318,24 @@ </element> </define> + <define name="qemucdevSecret"> + <element name='secret'> + <attribute name='type'> + <choice> + <value>tls</value> + </choice> + </attribute> + <choice> + <attribute name='uuid'> + <ref name="UUID"/> + </attribute> + <attribute name='usage'> + <ref name='genericName'/> + </attribute> + </choice> + </element> + </define> + <define name="qemucdevSrcTypeChoice"> <choice> <value>dev</value> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e58046b..53e5bae 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1899,6 +1899,7 @@ virDomainChrSourceDefClear(virDomainChrSourceDefPtr def) case VIR_DOMAIN_CHR_TYPE_TCP: VIR_FREE(def->data.tcp.host); VIR_FREE(def->data.tcp.service); + virSecretLookupDefClear(&def->data.tcp.seclookupdef); break; case VIR_DOMAIN_CHR_TYPE_UNIX: @@ -1955,6 +1956,10 @@ virDomainChrSourceDefCopy(virDomainChrSourceDefPtr dest, if (VIR_STRDUP(dest->data.tcp.service, src->data.tcp.service) < 0) return -1; + + if (virSecretLookupDefCopy(&dest->data.tcp.seclookupdef, + &src->data.tcp.seclookupdef) < 0) + return -1; break; case VIR_DOMAIN_CHR_TYPE_UNIX: @@ -9867,6 +9872,8 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, char *master = NULL; char *slave = NULL; char *append = NULL; + xmlNodePtr secret = NULL; + char *sectypestr = NULL; int remaining = 0; while (cur != NULL) { @@ -9956,6 +9963,8 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, } else if (xmlStrEqual(cur->name, BAD_CAST "protocol")) { if (!protocol) protocol = virXMLPropString(cur, "type"); + } else if (xmlStrEqual(cur->name, BAD_CAST "secret")) { + secret = cur; } else { remaining++; } @@ -10059,6 +10068,25 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, goto error; } + if (secret) { + + if (!(sectypestr = virXMLPropString(secret, "type"))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing TCP chardev secret type")); + goto error; + } + if ((def->data.tcp.sectype = + virSecretUsageTypeFromString(sectypestr)) != + VIR_SECRET_USAGE_TYPE_TLS) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid TCP chardev secret type '%s'"), + sectypestr); + goto error; + } + if (virSecretLookupParseSecret(secret, + &def->data.tcp.seclookupdef) < 0) + goto error; + } break; case VIR_DOMAIN_CHR_TYPE_UDP: @@ -10133,6 +10161,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, VIR_FREE(append); VIR_FREE(logappend); VIR_FREE(logfile); + VIR_FREE(sectypestr); return remaining; @@ -21157,6 +21186,12 @@ virDomainChrSourceDefFormat(virBufferPtr buf, virBufferAsprintf(buf, "<protocol type='%s'/>\n", virDomainChrTcpProtocolTypeToString( def->data.tcp.protocol)); + if (def->data.tcp.sectype == VIR_SECRET_USAGE_TYPE_TLS) { + const char *typestr = + virSecretUsageTypeToString(def->data.tcp.sectype); + virSecretLookupFormatSecret(buf, typestr, + &def->data.tcp.seclookupdef); + } break; case VIR_DOMAIN_CHR_TYPE_UNIX: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index b25e219..0b48b8e 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -53,6 +53,7 @@ # include "virprocess.h" # include "virgic.h" # include "virperf.h" +# include "virsecret.h" # include "virtypedparam.h" /* forward declarations of all device types, required by @@ -1092,6 +1093,8 @@ struct _virDomainChrSourceDef { bool listen; int protocol; bool tlscreds; + int sectype; /* virSecretUsage */ + virSecretLookupTypeDef seclookupdef; } tcp; struct { char *bindHost; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml new file mode 100644 index 0000000..62bc151 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml @@ -0,0 +1,51 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <serial type='udp'> + <source mode='bind' host='127.0.0.1' service='1111'/> + <source mode='connect' host='127.0.0.1' service='2222'/> + <target port='0'/> + </serial> + <serial type='tcp'> + <source mode='connect' host='127.0.0.1' service='5555'/> + <protocol type='raw'/> + <secret type='tls' usage='mycluster_myname'/> + <target port='0'/> + </serial> + <console type='udp'> + <source mode='bind' host='127.0.0.1' service='1111'/> + <source mode='connect' host='127.0.0.1' service='2222'/> + <target type='serial' port='0'/> + </console> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-secret-chardev.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-secret-chardev.xml new file mode 120000 index 0000000..974d3fb --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-secret-chardev.xml @@ -0,0 +1 @@ +../qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 85241b9..67e5857 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -541,6 +541,7 @@ mymain(void) DO_TEST("serial-udp"); DO_TEST("serial-tcp-telnet"); DO_TEST("serial-tcp-tlsx509-chardev"); + DO_TEST("serial-tcp-tlsx509-secret-chardev"); DO_TEST("serial-many"); DO_TEST("serial-spiceport"); DO_TEST("serial-spiceport-nospice"); -- 2.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list