Using the masterKey and if the capability exists build an -object secret command line to pass a masterKey file to qemu. The qemuBuildHasMasterKey is expected to be reused by other objects which would need to know not only if the masterKey has been provided, but if the secret object can be used for their own purposes. Additionally, generate qemuDomainGetMasterKeyAlias which will be used by later patches to define the 'keyid' (eg, masterKey) to be used by other secrets to provide the id to qemu for the master key. Although the path to the domain libDir and the masterKey file are created after qemuBuildCommandLine completes successfully, it's still possible to generate the path and use it. No different than code paths that use the domain libDir to create socket files (e.g. monitor.sock). Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/qemu/qemu_command.c | 67 ++++++++++++++++++++++ src/qemu/qemu_domain.c | 17 ++++++ src/qemu/qemu_domain.h | 2 + .../qemuxml2argvdata/qemuxml2argv-master-key.args | 23 ++++++++ tests/qemuxml2argvdata/qemuxml2argv-master-key.xml | 30 ++++++++++ tests/qemuxml2argvtest.c | 2 + 6 files changed, 141 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-master-key.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-master-key.xml diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index eb02553..04e75fd 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -151,6 +151,70 @@ VIR_ENUM_IMPL(qemuNumaPolicy, VIR_DOMAIN_NUMATUNE_MEM_LAST, "interleave"); /** + * qemuBuildHasMasterKey: + * @qemuCaps: QEMU binary capabilities + * + * Return true if this binary supports the secret -object, false otherwise. + */ +static bool +qemuBuildHasMasterKey(virQEMUCapsPtr qemuCaps) +{ + return virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_SECRET); +} + + +/** + * qemuBuildMasterKeyCommandLine: + * @cmd: the command to modify + * @qemuCaps qemu capabilities object + * @domainLibDir: location to find the master key + + * Formats the command line for a master key if available + * + * Returns 0 on success, -1 w/ error message on failure + */ +static int +qemuBuildMasterKeyCommandLine(virCommandPtr cmd, + virQEMUCapsPtr qemuCaps, + const char *domainLibDir) +{ + int ret = -1; + char *alias = NULL; + char *path = NULL; + + /* If the -object secret does not exist, then just return. This just + * means the domain won't be able to use a secret master key and is + * not a failure. + */ + if (!qemuBuildHasMasterKey(qemuCaps)) { + VIR_INFO("secret object is not supported by this QEMU binary"); + return 0; + } + + if (!(alias = qemuDomainGetMasterKeyAlias())) + return -1; + + /* Get the path... NB, the path will not exist yet as domainLibDir + * and the master secret file gets created after we've successfully + * built the command line + */ + if (!(path = qemuDomainGetMasterKeyFilePath(domainLibDir))) + goto cleanup; + + virCommandAddArg(cmd, "-object"); + virCommandAddArgFormat(cmd, "secret,id=%s,format=base64,file=%s", + alias, path); + + ret = 0; + + cleanup: + VIR_FREE(alias); + VIR_FREE(path); + return ret; +} + + +/** * qemuVirCommandGetFDSet: * @cmd: the command to modify * @fd: fd to reassign to the child @@ -9220,6 +9284,9 @@ qemuBuildCommandLine(virConnectPtr conn, if (!standalone) virCommandAddArg(cmd, "-S"); /* freeze CPU */ + if (qemuBuildMasterKeyCommandLine(cmd, qemuCaps, domainLibDir) < 0) + goto error; + if (enableFips) virCommandAddArg(cmd, "-enable-fips"); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 507ae9e..53d6705 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -468,6 +468,23 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo, } +/* qemuDomainGetMasterKeyAlias: + * + * Generate and return the masterKey alias + * + * Returns NULL or a string containing the master key alias + */ +char * +qemuDomainGetMasterKeyAlias(void) +{ + char *alias; + + ignore_value(VIR_STRDUP(alias, "masterKey0")); + + return alias; +} + + /* qemuDomainGetMasterKeyFilePath: * @libDir: Directory path to domain lib files * diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index b24acdf..60dbe82 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -550,6 +550,8 @@ int qemuDomainSetPrivatePaths(char **domainLibDir, const char *domainName, int domainId); +char *qemuDomainGetMasterKeyAlias(void); + char *qemuDomainGetMasterKeyFilePath(const char *libDir); int qemuDomainWriteMasterKeyFile(const char *libDir, const char *masterKey) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-master-key.args b/tests/qemuxml2argvdata/qemuxml2argv-master-key.args new file mode 100644 index 0000000..14a3597 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-master-key.args @@ -0,0 +1,23 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu \ +-name QEMUGuest1 \ +-S \ +-object secret,id=masterKey0,format=base64,\ +file=/tmp/lib/domain--1-QEMUGuest1/master.key \ +-M pc \ +-m 214 \ +-smp 2 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server,nowait \ +-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 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-master-key.xml b/tests/qemuxml2argvdata/qemuxml2argv-master-key.xml new file mode 100644 index 0000000..f2adb84 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-master-key.xml @@ -0,0 +1,30 @@ +<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'>2</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'> + <driver name='qemu' type='raw'/> + <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'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 4fac77d..a9d5975 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1897,6 +1897,8 @@ mymain(void) DO_TEST("debug-threads", QEMU_CAPS_NAME_DEBUG_THREADS); + DO_TEST("master-key", QEMU_CAPS_OBJECT_SECRET); + qemuTestDriverFree(&driver); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; -- 2.5.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list