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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list