[libvirt] [PATCHv5 1/9] smartcard: add XML support for <smartcard> device

Eric Blake eblake at redhat.com
Fri Feb 4 04:01:12 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='bind' host='127.0.0.1' service='2001'/>
    <protocol type='raw'/>
  </smartcard>
</devices>

(As of this commit, the qemu hypervisor will be the first
implementation, but it only supports one smartcard.)

* 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.
* tests/qemuxml2argvdata/qemuxml2argv-smartcard-controller.xml:
Likewise.

---
Notes:
    v2: incoporate feedback from RFC, make passthrough type default to tcp
    v3: add optional <address> per <smartcard>, enhance <controller>
      to understand ccid, add optional <database> in mode hosts-certificates,
      optional <source> in mode hosts, add another test file, revert v2
      passthrough mode back to requiring explicit type
    v4: drop <source> in host mode, relax <certificate> in host-certificates,
      document default <database> directory
    v5: avoid rounding in tests
 docs/formatdomain.html.in                          |   95 +++++++++++++++++++-
 docs/schemas/domain.rng                            |   66 ++++++++++++++
 .../qemuxml2argv-smartcard-controller.xml          |   19 ++++
 .../qemuxml2argv-smartcard-host-certificates.xml   |   20 ++++
 .../qemuxml2argv-smartcard-host.xml                |   16 ++++
 .../qemuxml2argv-smartcard-passthrough-tcp.xml     |   19 ++++
 6 files changed, 234 insertions(+), 1 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smartcard-controller.xml
 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 db0b762..9f1bb5f 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -892,7 +892,7 @@

     <p>
       Each controller has a mandatory attribute <code>type</code>,
-      which must be one of "ide", "fdc", "scsi", "sata", or
+      which must be one of "ide", "fdc", "scsi", "sata", "ccid", or
       "virtio-serial", and a mandatory attribute <code>index</code>
       which is the decimal integer describing in which order the bus
       controller is encountered (for use in <code>controller</code>
@@ -991,6 +991,99 @@
       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>cert1</certificate>
+      <certificate>cert2</certificate>
+      <certificate>cert3</certificate>
+      <database>/etc/pki/nssdb/</database>
+    </smartcard>
+    <smartcard mode='passthrough' type='tcp'>
+      <source mode='bind' host='127.0.0.1' service='2001'/>
+      <protocol type='raw'/>
+      <address type='ccid' controller='0' slot='0'/>
+    </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>
+
+    <dl>
+      <dt><code>mode='host'</code></dt>
+      <dd>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.  See below about the use of an
+      optional <code><address></code> sub-element.</dd>
+
+      <dt><code>mode='host-certificates'</code></dt>
+      <dd>Rather than requiring a smartcard to be plugged into the
+      host, it is possible to provide three NSS certificate names
+      residing in a database on the host.  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
+      certificate names must be supplied as the content of each of
+      three <code><certificate></code> sub-elements.  An
+      additional sub-element <code><database></code> can specify
+      the absolute path to an alternate directory (matching
+      the <code>-d</code> option of the <code>certutil</code> command
+      when creating the certificates); if not present, it defaults to
+      /etc/pki/nssdb.</dd>
+
+      <dt><code>mode='passthrough'</code></dt>
+      <dd>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, matching one of the
+      supported <a href="#elementsConsole">serial device</a> types, to
+      describe the host side of the tunnel; <code>type='tcp'</code> is
+      typical.  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).</dd>
+    </dl>
+
+    <p>
+      Each mode supports an optional
+      sub-element <code><address></code>, which fine-tunes the
+      correlation between the smartcard and a ccid bus controller.
+      If present, the element must have an attribute
+      of <code>type='ccid'</code> as well as a <code>bus</code>
+      attribute listing the index of the bus that the smartcard
+      utilizes.  An optional <code>slot</code> attribute lists which
+      slot within the bus.  For now, qemu only supports at most one
+      smartcard, with an address of bus=0 slot=0.
+    </p>
+
     <h4><a name="elementsNICS">Network interfaces</a></h4>

 <pre>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 8a2e7c7..69fb432 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -749,6 +749,7 @@
                 <value>ide</value>
                 <value>scsi</value>
                 <value>sata</value>
+                <value>ccid</value>
               </choice>
             </attribute>
           </optional>
@@ -1632,6 +1633,51 @@
       </interleave>
     </element>
   </define>
+  <define name="smartcard">
+    <element name="smartcard">
+      <choice>
+        <group>
+          <attribute name="mode">
+            <value>host</value>
+          </attribute>
+          <!-- might need to add optional database element here later -->
+        </group>
+        <group>
+          <attribute name="mode">
+            <value>host-certificates</value>
+          </attribute>
+          <ref name='certificate'/>
+          <ref name='certificate'/>
+          <ref name='certificate'/>
+          <optional>
+            <element name="database">
+              <ref name="absDirPath"/>
+            </element>
+          </optional>
+        </group>
+        <group>
+          <attribute name="mode">
+            <value>passthrough</value>
+          </attribute>
+          <ref name="qemucdevSrcType"/>
+          <interleave>
+            <ref name="qemucdevSrcDef"/>
+            <optional>
+              <ref name="qemucdevTgtDef"/>
+            </optional>
+          </interleave>
+        </group>
+      </choice>
+      <optional>
+        <ref name="address"/>
+      </optional>
+    </element>
+  </define>
+  <define name="certificate">
+    <element name="certificate">
+      <text/>
+    </element>
+  </define>
   <define name="input">
     <element name="input">
       <attribute name="type">
@@ -1768,8 +1814,21 @@
       </attribute>
     </optional>
   </define>
+  <define name="ccidaddress">
+    <attribute name="controller">
+      <ref name="driveController"/>
+    </attribute>
+    <optional>
+      <attribute name="slot">
+        <ref name="driveUnit"/>
+      </attribute>
+    </optional>
+  </define>
   <!--
       Devices attached to a domain.
+      Sub-elements such as <alias> are not documented here, as they
+      can only exist when generated for a live domain and are ignored
+      when defining a domain.
     -->
   <define name="devices">
     <element name="devices">
@@ -1792,6 +1851,7 @@
             <ref name="parallel"/>
             <ref name="serial"/>
             <ref name="channel"/>
+            <ref name="smartcard"/>
           </choice>
         </zeroOrMore>
         <optional>
@@ -2021,6 +2081,12 @@
           </attribute>
           <ref name="virtioserialaddress"/>
         </group>
+        <group>
+          <attribute name="type">
+            <value>ccid</value>
+          </attribute>
+          <ref name="ccidaddress"/>
+        </group>
       </choice>
     </element>
   </define>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-controller.xml b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-controller.xml
new file mode 100644
index 0000000..2a53dbb
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-controller.xml
@@ -0,0 +1,19 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219136</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>
+    <controller type='ccid' index='0'/>
+    <smartcard mode='host'>
+      <address type='ccid' controller='0' slot='0'/>
+    </smartcard>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.xml b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.xml
new file mode 100644
index 0000000..5a9844b
--- /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>219136</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>cert1</certificate>
+      <certificate>cert2</certificate>
+      <certificate>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..95790f2
--- /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>219136</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..f133391
--- /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>219136</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='bind' host='127.0.0.1' service='2001'/>
+      <protocol type='raw'/>
+    </smartcard>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
-- 
1.7.4




More information about the libvir-list mailing list