[libvirt] [PATCH v5 6/9] conf: Add new secret element for tcp chardev

John Ferlan jferlan at redhat.com
Thu Aug 4 15:21:24 UTC 2016


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 at redhat.com>
---
 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




More information about the libvir-list mailing list