[libvirt] [RFC: PATCH 1/n] smartcard: add XML support for <smartcard> device

Eric Blake eblake at redhat.com
Thu Jan 6 01:12:47 UTC 2011


Assuming a hypervisor that supports multiple smartcard devices in the
guest, this would be a valid XML description:

<devices>
  <smartcard mode='host'/>
  <smartcard mode='host-certificates'>
    <certificate>/path/to/cert1</certificate>
    <certificate>/path/to/cert2</certificate>
    <certificate>/path/to/cert3</certificate>
  </smartcard>
  <smartcard mode='passthrough' type='tcp'>
    <source mode='connect' host='127.0.0.1' service='2001'/>
    <protocol type='raw'/>
  </smartcard>
</devices>

* docs/formatdomain.html.in (Smartcard devices): New section.
* docs/schemas/domain.rng (smartcard): New define, used in
devices.
* tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.xml: New file
to test schema.
* tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.xml:
Likewise.
* tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-tcp.xml:
Likewise.
---

Figuring it's easier to discuss alternatives with a documentation
patch in hand, here's what I've got so far.  My next task is to
update conf/domain_conf.c to parse the new XML, then to teach
qemu/qemu_command.c how to represent it on the command line.

After that, I'll revisit figuring out how to support spicevmc
chardevs, for both vdagent and smartcard.

It looks like 'virsh domxml-from-native qemu-argv file' has
suffered some bit-rot, as it doesn't know how to parse existing
-chardev/-device pairings from valid qemu 0.12+ command lines;
so for now I will focus on the XML->native direction, and leave
improvements to the native->XML direction for another day.

 docs/formatdomain.html.in                          |   72 ++++++++++++++++++++
 docs/schemas/domain.rng                            |   35 ++++++++++
 .../qemuxml2argv-smartcard-host-certificates.xml   |   20 ++++++
 .../qemuxml2argv-smartcard-host.xml                |   16 +++++
 .../qemuxml2argv-smartcard-passthrough-tcp.xml     |   19 +++++
 5 files changed, 162 insertions(+), 0 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.xml
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.xml
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-tcp.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index e9fcea1..bf46106 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -799,6 +799,78 @@
       not used by qemu.</dd>
     </dl>

+    <h4><a name="elementsSmartcard">Smartcard devices</a></h4>
+
+    <p>
+      A virtual smartcard device can be supplied to the guest via the
+      <code>smartcard</code> element. A USB smartcard reader device on
+      the host cannot be used on a guest with simple device
+      passthrough, since it will then not be available on the host,
+      possibly locking the host computer when it is "removed".
+      Therefore, some hypervisors provide a specialized virtual device
+      that can present a smartcard interface to the guest, with
+      several modes for describing how credentials are obtained from
+      the host or even a from a channel created to a third-party
+      smartcard provider. <span class="since">Since 0.8.8</span>
+    </p>
+
+<pre>
+  ...
+  <devices>
+    <smartcard mode='host'/>
+    <smartcard mode='host-certificates'>
+      <certificate>/path/to/cert1</certificate>
+      <certificate>/path/to/cert2</certificate>
+      <certificate>/path/to/cert3</certificate>
+    </smartcard>
+    <smartcard mode='passthrough' type='tcp'>
+      <source mode='connect' host='127.0.0.1' service='2001'/>
+      <protocol type='raw'/>
+    </smartcard>
+  </devices>
+  ...
+</pre>
+
+    <p>
+      The <code><smartcard></code> element has a mandatory
+      attribute <code>mode</code>.  The following modes are supported;
+      in each mode, the guest sees a device on its USB bus that
+      behaves like a physical USB CCID (Chip/Smart Card Interface
+      Device) card.
+    </p>
+
+    <ul>
+      <li><code>mode='host'</code> — the simplest operation,
+      where the hypervisor relays all requests from the guest into
+      direct access to the host's smartcard via NSS.  No other
+      attributes or sub-elements are required.</li>
+
+      <li><code>mode='host-certificates'</code> — rather than
+      requiring a smartcard to be plugged into the host, it is
+      possible to provide three files residing on the host and
+      containing NSS certificates.  These certificates can be
+      generated via the command <code>certutil -d /etc/pki/nssdb -x -t
+      CT,CT,CT -S -s CN=cert1 -n cert1</code>, and the resulting three
+      files must be supplied as the content of each of
+      three <code><certificate></code> sub-elements.</li>
+
+      <li><code>mode='passthrough'</code> — rather than having
+      the hypervisor directly communicate with the host, it is
+      possible to tunnel all requests through a secondary character
+      device to a third-party provider (which may in turn be talking
+      to a smartcard or using three certificate files).  In this mode
+      of operation, an additional attribute <code>type</code> is
+      required, which matches the types of one of the
+      supported <a href="#elementsConsole">serial devices</a>.
+      Further sub-elements, such as <code><source></code> are
+      required according to the given type, although
+      a <code><target></code> sub-element is not required (since
+      the consumer of the character device is the hypervisor itself,
+      rather than a device visible in the guest).  Use
+      of <code>type='tcp'</code> is most common.</li>
+    </ul>
+
+
     <h4><a name="elementsNICS">Network interfaces</a></h4>

 <pre>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index a524e4b..385d1b6 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -1579,6 +1579,40 @@
       </interleave>
     </element>
   </define>
+  <define name="smartcard">
+    <element name="smartcard">
+      <choice>
+        <attribute name="mode">
+          <value>host</value>
+        </attribute>
+        <group>
+          <attribute name="mode">
+            <value>host-certificates</value>
+          </attribute>
+          <ref name='certificate'/>
+          <ref name='certificate'/>
+          <ref name='certificate'/>
+        </group>
+        <group>
+          <attribute name="mode">
+            <value>passthrough</value>
+          </attribute>
+          <ref name="qemucdevSrcType"/>
+          <interleave>
+            <ref name="qemucdevSrcDef"/>
+            <optional>
+              <ref name="qemucdevTgtDef"/>
+            </optional>
+          </interleave>
+        </group>
+      </choice>
+    </element>
+  </define>
+  <define name="certificate">
+    <element name="certificate">
+      <ref name="absFilePath"/>
+    </element>
+  </define>
   <define name="input">
     <element name="input">
       <attribute name="type">
@@ -1736,6 +1770,7 @@
             <ref name="parallel"/>
             <ref name="serial"/>
             <ref name="channel"/>
+            <ref name="smartcard"/>
           </choice>
         </zeroOrMore>
         <optional>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.xml b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.xml
new file mode 100644
index 0000000..f70395d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.xml
@@ -0,0 +1,20 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <smartcard mode='host-certificates'>
+      <certificate>/etc/pki/cert1</certificate>
+      <certificate>/etc/pki/cert2</certificate>
+      <certificate>/etc/pki/cert3</certificate>
+    </smartcard>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.xml b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.xml
new file mode 100644
index 0000000..faa2231
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.xml
@@ -0,0 +1,16 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <smartcard mode='host'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-tcp.xml b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-tcp.xml
new file mode 100644
index 0000000..8e2fa52
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-tcp.xml
@@ -0,0 +1,19 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <smartcard mode='passthrough' type='tcp'>
+      <source mode='connect' host='127.0.0.1' service='2001'/>
+      <protocol type='raw'/>
+    </smartcard>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
-- 
1.7.3.4




More information about the libvir-list mailing list