mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 06:05:27 +00:00
smartcard: turn on qemu support
* src/qemu/qemu_command.c (qemuBuildCommandLine): Emit smartcard options. (qemuAssignDeviceAliases): Assign an alias for smartcards. (qemuBuildControllerDevStr): Manage the usb-ccid controller. * tests/qemuxml2argvtest.c (mymain): Add new tests. * tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.args: New file. * tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.args: Likewise. * tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough.args: Likewise. * tests/qemuxml2argvdata/qemuxml2argv-smartcard-controller.args: Likewise.
This commit is contained in:
parent
32e52134ff
commit
f5fd9baac1
@ -638,6 +638,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, unsigned long long qemuCmdFlags)
|
||||
if (virAsprintf(&def->channels[i]->info.alias, "channel%d", i) < 0)
|
||||
goto no_memory;
|
||||
}
|
||||
for (i = 0; i < def->nsmartcards ; i++) {
|
||||
if (virAsprintf(&def->smartcards[i]->info.alias, "smartcard%d", i) < 0)
|
||||
goto no_memory;
|
||||
}
|
||||
if (def->console) {
|
||||
if (virAsprintf(&def->console->info.alias, "console%d", i) < 0)
|
||||
goto no_memory;
|
||||
@ -1002,8 +1006,9 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
|
||||
|
||||
/* Disk controllers (SCSI only for now) */
|
||||
for (i = 0; i < def->ncontrollers ; i++) {
|
||||
/* FDC lives behind the ISA bridge */
|
||||
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC)
|
||||
/* FDC lives behind the ISA bridge; CCID is a usb device */
|
||||
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC ||
|
||||
def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_CCID)
|
||||
continue;
|
||||
|
||||
/* First IDE controller lives on the PIIX3 at slot=1, function=1,
|
||||
@ -1511,6 +1516,10 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def,
|
||||
}
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
|
||||
virBufferVSprintf(&buf, "usb-ccid,id=ccid%d", def->idx);
|
||||
break;
|
||||
|
||||
/* We always get an IDE controller, whether we want it or not. */
|
||||
case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
|
||||
default:
|
||||
@ -3434,6 +3443,109 @@ qemuBuildCommandLine(virConnectPtr conn,
|
||||
}
|
||||
}
|
||||
|
||||
if (def->nsmartcards) {
|
||||
/* -device usb-ccid was already emitted along with other
|
||||
* controllers. For now, qemu handles only one smartcard. */
|
||||
virDomainSmartcardDefPtr smartcard = def->smartcards[0];
|
||||
char *devstr;
|
||||
virBuffer opt = VIR_BUFFER_INITIALIZER;
|
||||
int j;
|
||||
const char *database;
|
||||
|
||||
if (def->nsmartcards > 1 ||
|
||||
smartcard->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID ||
|
||||
smartcard->info.addr.ccid.controller != 0 ||
|
||||
smartcard->info.addr.ccid.slot != 0) {
|
||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("this QEMU binary lacks multiple smartcard "
|
||||
"support"));
|
||||
virBufferFreeAndReset(&opt);
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (smartcard->type) {
|
||||
case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
|
||||
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) ||
|
||||
!(qemuCmdFlags & QEMUD_CMD_FLAG_CCID_EMULATED)) {
|
||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("this QEMU binary lacks smartcard host "
|
||||
"mode support"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
virBufferAddLit(&opt, "ccid-card-emulated,backend=nss-emulated");
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
|
||||
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) ||
|
||||
!(qemuCmdFlags & QEMUD_CMD_FLAG_CCID_EMULATED)) {
|
||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("this QEMU binary lacks smartcard host "
|
||||
"mode support"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
virBufferAddLit(&opt, "ccid-card-emulated,backend=certificates");
|
||||
for (j = 0; j < VIR_DOMAIN_SMARTCARD_NUM_CERTIFICATES; j++) {
|
||||
if (strchr(smartcard->data.cert.file[j], ',')) {
|
||||
virBufferFreeAndReset(&opt);
|
||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("invalid certificate name: %s"),
|
||||
smartcard->data.cert.file[j]);
|
||||
goto error;
|
||||
}
|
||||
virBufferVSprintf(&opt, ",cert%d=%s", j + 1,
|
||||
smartcard->data.cert.file[j]);
|
||||
}
|
||||
if (smartcard->data.cert.database) {
|
||||
if (strchr(smartcard->data.cert.database, ',')) {
|
||||
virBufferFreeAndReset(&opt);
|
||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("invalid database name: %s"),
|
||||
smartcard->data.cert.database);
|
||||
goto error;
|
||||
}
|
||||
database = smartcard->data.cert.database;
|
||||
} else {
|
||||
database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
|
||||
}
|
||||
virBufferVSprintf(&opt, ",database=%s", database);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
|
||||
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) ||
|
||||
!(qemuCmdFlags & QEMUD_CMD_FLAG_CCID_PASSTHRU)) {
|
||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("this QEMU binary lacks smartcard "
|
||||
"passthrough mode support"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
virCommandAddArg(cmd, "-chardev");
|
||||
if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru,
|
||||
smartcard->info.alias))) {
|
||||
virBufferFreeAndReset(&opt);
|
||||
goto error;
|
||||
}
|
||||
virCommandAddArg(cmd, devstr);
|
||||
VIR_FREE(devstr);
|
||||
|
||||
virBufferVSprintf(&opt, "ccid-card-passthru,chardev=char%s",
|
||||
smartcard->info.alias);
|
||||
break;
|
||||
|
||||
default:
|
||||
qemuReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("unexpected smartcard type %d"),
|
||||
smartcard->type);
|
||||
virBufferFreeAndReset(&opt);
|
||||
goto error;
|
||||
}
|
||||
virCommandAddArg(cmd, "-device");
|
||||
virBufferVSprintf(&opt, ",id=%s,bus=ccid0.0", smartcard->info.alias);
|
||||
virCommandAddArgBuffer(cmd, &opt);
|
||||
}
|
||||
|
||||
if (!def->nserials) {
|
||||
/* If we have -device, then we set -nodefault already */
|
||||
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE))
|
||||
|
@ -0,0 +1,7 @@
|
||||
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
|
||||
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev \
|
||||
socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon \
|
||||
chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device \
|
||||
usb-ccid,id=ccid0 -device \
|
||||
ccid-card-emulated,backend=nss-emulated,id=smartcard0,bus=ccid0.0 -usb \
|
||||
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2
|
@ -0,0 +1,8 @@
|
||||
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
|
||||
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev \
|
||||
socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon \
|
||||
chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device \
|
||||
usb-ccid,id=ccid0 -device \
|
||||
ccid-card-emulated,backend=certificates,cert1=cert1,cert2=cert2,cert3=cert3\
|
||||
,database=/etc/pki/nssdb,id=smartcard0,bus=ccid0.0 -usb -device \
|
||||
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2
|
7
tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.args
Normal file
7
tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.args
Normal file
@ -0,0 +1,7 @@
|
||||
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
|
||||
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev \
|
||||
socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon \
|
||||
chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device \
|
||||
usb-ccid,id=ccid0 -device \
|
||||
ccid-card-emulated,backend=nss-emulated,id=smartcard0,bus=ccid0.0 -usb \
|
||||
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2
|
@ -0,0 +1,8 @@
|
||||
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
|
||||
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev \
|
||||
socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon \
|
||||
chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device \
|
||||
usb-ccid,id=ccid0 -chardev \
|
||||
socket,id=charsmartcard0,host=127.0.0.1,port=2001,server,nowait \
|
||||
-device ccid-card-passthru,chardev=charsmartcard0,id=smartcard0,bus=ccid0.0 \
|
||||
-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2
|
@ -408,6 +408,19 @@ mymain(int argc, char **argv)
|
||||
DO_TEST("console-virtio", QEMUD_CMD_FLAG_DEVICE |
|
||||
QEMUD_CMD_FLAG_NODEFCONFIG, false);
|
||||
|
||||
DO_TEST("smartcard-host",
|
||||
QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE |
|
||||
QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_CCID_EMULATED, false);
|
||||
DO_TEST("smartcard-host-certificates",
|
||||
QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE |
|
||||
QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_CCID_EMULATED, false);
|
||||
DO_TEST("smartcard-passthrough-tcp",
|
||||
QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE |
|
||||
QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_CCID_PASSTHRU, false);
|
||||
DO_TEST("smartcard-controller",
|
||||
QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE |
|
||||
QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_CCID_EMULATED, false);
|
||||
|
||||
DO_TEST("smbios", QEMUD_CMD_FLAG_SMBIOS_TYPE, false);
|
||||
|
||||
DO_TEST("watchdog", 0, false);
|
||||
|
Loading…
Reference in New Issue
Block a user