[libvirt] [PATCH v9 1/5] domain: Add optional 'tls' attribute for TCP chardev

John Ferlan jferlan at redhat.com
Fri Oct 14 20:23:04 UTC 2016


Add an optional "tls='yes|no'" attribute for a TCP chardev for the
express purpose to disable setting up TLS for the specific chardev in
the event the qemu.conf settings have enabled hypervisor wide TLS for
serial TCP chardevs.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 docs/formatdomain.html.in                          | 21 +++++++++
 docs/schemas/domaincommon.rng                      |  5 +++
 src/conf/domain_conf.c                             | 22 +++++++++-
 src/conf/domain_conf.h                             |  1 +
 src/qemu/qemu_command.c                            |  3 +-
 src/qemu/qemu_hotplug.c                            |  3 +-
 ...uxml2argv-serial-tcp-tlsx509-chardev-notls.args | 30 +++++++++++++
 ...muxml2argv-serial-tcp-tlsx509-chardev-notls.xml | 50 ++++++++++++++++++++++
 .../qemuxml2argv-serial-tcp-tlsx509-chardev.xml    |  2 +-
 tests/qemuxml2argvtest.c                           |  3 ++
 ...xml2xmlout-serial-tcp-tlsx509-chardev-notls.xml |  1 +
 .../qemuxml2xmlout-serial-tcp-tlsx509-chardev.xml  |  2 +-
 tests/qemuxml2xmltest.c                            |  1 +
 13 files changed, 139 insertions(+), 5 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev-notls.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev-notls.xml
 create mode 120000 tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-chardev-notls.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 9051178..6145d65 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -6204,6 +6204,27 @@ qemu-kvm -net nic,model=? /dev/null
   </devices>
   ...</pre>
 
+    <p>
+      <span class="since">Since 2.4.0,</span> the optional attribute
+      <code>tls</code> can be used to control whether a serial chardev
+      TCP communication channel would utilize a hypervisor configured
+      TLS X.509 certificate environment in order to encrypt the data
+      channel. For the QEMU hypervisor usage of TLS is controlled by the
+      <code>chardev_tls</code> setting in file /etc/libvirt/qemu.conf. If
+      enabled, then by setting this attribute to "no" will disable usage
+      of the TLS environment for this particular serial TCP data channel.
+    </p>
+<pre>
+  ...
+  <devices>
+    <serial type="tcp">
+      <source mode='connect' host="127.0.0.1" service="5555" tls="yes"/>
+      <protocol type="raw"/>
+      <target port="0"/>
+    </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 3106510..e6741bb 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3453,6 +3453,11 @@
             <ref name="virOnOff"/>
           </attribute>
         </optional>
+        <optional>
+          <attribute name="tls">
+            <ref name="virYesNo"/>
+          </attribute>
+        </optional>
         <zeroOrMore>
           <ref name='devSeclabel'/>
         </zeroOrMore>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 93b34e0..9062544 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1997,6 +1997,8 @@ virDomainChrSourceDefCopy(virDomainChrSourceDefPtr dest,
 
         if (VIR_STRDUP(dest->data.tcp.service, src->data.tcp.service) < 0)
             return -1;
+
+        dest->data.tcp.haveTLS = src->data.tcp.haveTLS;
         break;
 
     case VIR_DOMAIN_CHR_TYPE_UNIX:
@@ -10038,6 +10040,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
     char *master = NULL;
     char *slave = NULL;
     char *append = NULL;
+    char *haveTLS = NULL;
     int remaining = 0;
 
     while (cur != NULL) {
@@ -10045,6 +10048,8 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
             if (xmlStrEqual(cur->name, BAD_CAST "source")) {
                 if (!mode)
                     mode = virXMLPropString(cur, "mode");
+                if (!haveTLS)
+                    haveTLS = virXMLPropString(cur, "tls");
 
                 switch ((virDomainChrType) def->type) {
                 case VIR_DOMAIN_CHR_TYPE_FILE:
@@ -10221,6 +10226,15 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
             def->data.tcp.listen = true;
         }
 
+        if (haveTLS &&
+            (def->data.tcp.haveTLS =
+             virTristateBoolTypeFromString(haveTLS)) <= 0) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("unknown chardev 'tls' setting '%s'"),
+                           haveTLS);
+            goto error;
+        }
+
         if (!protocol)
             def->data.tcp.protocol = VIR_DOMAIN_CHR_TCP_PROTOCOL_RAW;
         else if ((def->data.tcp.protocol =
@@ -10305,6 +10319,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
     VIR_FREE(append);
     VIR_FREE(logappend);
     VIR_FREE(logfile);
+    VIR_FREE(haveTLS);
 
     return remaining;
 
@@ -21453,7 +21468,12 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
         virBufferAsprintf(buf, "<source mode='%s' ",
                           def->data.tcp.listen ? "bind" : "connect");
         virBufferEscapeString(buf, "host='%s' ", def->data.tcp.host);
-        virBufferEscapeString(buf, "service='%s'/>\n", def->data.tcp.service);
+        virBufferEscapeString(buf, "service='%s'", def->data.tcp.service);
+        if (def->data.tcp.haveTLS != VIR_TRISTATE_BOOL_ABSENT)
+            virBufferAsprintf(buf, " tls='%s'",
+                    virTristateBoolTypeToString(def->data.tcp.haveTLS));
+        virBufferAddLit(buf, "/>\n");
+
         virBufferAsprintf(buf, "<protocol type='%s'/>\n",
                           virDomainChrTcpProtocolTypeToString(
                               def->data.tcp.protocol));
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3e85ae4..c34e046 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1094,6 +1094,7 @@ struct _virDomainChrSourceDef {
             bool listen;
             int protocol;
             bool tlscreds;
+            int haveTLS; /* enum virTristateBool */
         } tcp;
         struct {
             char *bindHost;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 21fd85c..aaf7018 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4939,7 +4939,8 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
         if (dev->data.tcp.listen)
             virBufferAdd(&buf, nowait ? ",server,nowait" : ",server", -1);
 
-        if (cfg->chardevTLS) {
+        if (cfg->chardevTLS &&
+            dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_NO) {
             char *objalias = NULL;
 
             if (qemuBuildTLSx509CommandLine(cmd, cfg->chardevTLSx509certdir,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 14af4e1..f4d7c17 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1729,7 +1729,8 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
     if (qemuDomainChrPreInsert(vmdef, chr) < 0)
         goto cleanup;
 
-    if (cfg->chardevTLS) {
+    if (cfg->chardevTLS &&
+        dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_NO) {
         if (qemuBuildTLSx509BackendProps(cfg->chardevTLSx509certdir,
                                          dev->data.tcp.listen,
                                          cfg->chardevTLSx509verify,
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev-notls.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev-notls.args
new file mode 100644
index 0000000..cac0d85
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev-notls.args
@@ -0,0 +1,30 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name QEMUGuest1 \
+-S \
+-M pc \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefconfig \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline \
+-no-acpi \
+-boot c \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
+-chardev udp,id=charserial0,host=127.0.0.1,port=2222,localaddr=127.0.0.1,\
+localport=1111 \
+-device isa-serial,chardev=charserial0,id=serial0 \
+-chardev socket,id=charserial1,host=127.0.0.1,port=5555 \
+-device isa-serial,chardev=charserial1,id=serial1 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev-notls.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev-notls.xml
new file mode 100644
index 0000000..debc69b
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev-notls.xml
@@ -0,0 +1,50 @@
+<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' tls='no'/>
+      <protocol type='raw'/>
+      <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/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.xml
index 1618b02..1d7896d 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.xml
@@ -27,7 +27,7 @@
       <target port='0'/>
     </serial>
     <serial type='tcp'>
-      <source mode='connect' host='127.0.0.1' service='5555'/>
+      <source mode='connect' host='127.0.0.1' service='5555' tls='yes'/>
       <protocol type='raw'/>
       <target port='0'/>
     </serial>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index e8438b4..c65c769 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1162,6 +1162,9 @@ mymain(void)
     DO_TEST("serial-tcp-tlsx509-chardev",
             QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG,
             QEMU_CAPS_OBJECT_TLS_CREDS_X509);
+    DO_TEST("serial-tcp-tlsx509-chardev-notls",
+            QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG,
+            QEMU_CAPS_OBJECT_TLS_CREDS_X509);
     driver.config->chardevTLS = 0;
     VIR_FREE(driver.config->chardevTLSx509certdir);
     DO_TEST("serial-many-chardev",
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-chardev-notls.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-chardev-notls.xml
new file mode 120000
index 0000000..26484c9
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-chardev-notls.xml
@@ -0,0 +1 @@
+../qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev-notls.xml
\ No newline at end of file
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-chardev.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-chardev.xml
index 832e2a2..23c244b 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-chardev.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-serial-tcp-tlsx509-chardev.xml
@@ -32,7 +32,7 @@
       <target port='0'/>
     </serial>
     <serial type='tcp'>
-      <source mode='connect' host='127.0.0.1' service='5555'/>
+      <source mode='connect' host='127.0.0.1' service='5555' tls='yes'/>
       <protocol type='raw'/>
       <target port='0'/>
     </serial>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 62bff8c..3ab4c50 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -534,6 +534,7 @@ mymain(void)
     DO_TEST("serial-udp", NONE);
     DO_TEST("serial-tcp-telnet", NONE);
     DO_TEST("serial-tcp-tlsx509-chardev", NONE);
+    DO_TEST("serial-tcp-tlsx509-chardev-notls", NONE);
     DO_TEST("serial-many", NONE);
     DO_TEST("serial-spiceport", NONE);
     DO_TEST("serial-spiceport-nospice", NONE);
-- 
2.7.4




More information about the libvir-list mailing list