On Fri, Jul 12, 2019 at 12:23:44PM -0400, Stefan Berger wrote:
> Run 'swtpm socket --print-capabilities' and
> 'swtpm_setup --print-capabilities' to get the JSON object of the
> features the programs are supporting and parse them into a bitmap.
>
> Signed-off-by: Stefan Berger <[email protected]>
> ---
> src/libvirt_private.syms | 2 +
> src/util/virtpm.c | 134 +++++++++++++++++++++++++++++++++++++--
> src/util/virtpm.h | 15 +++++
> 3 files changed, 147 insertions(+), 4 deletions(-)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 5b3c176862..5200adae3f 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -3181,6 +3181,8 @@ virTPMEmulatorInit;
> virTPMGetSwtpm;
> virTPMGetSwtpmIoctl;
> virTPMGetSwtpmSetup;
> +virTPMSwtpmFeatureTypeFromString;
> +virTPMSwtpmSetupFeatureTypeFromString;
>
>
> # util/virtypedparam.h
> diff --git a/src/util/virtpm.c b/src/util/virtpm.c
> index e4735f9c4d..692033e899 100644
> --- a/src/util/virtpm.c
> +++ b/src/util/virtpm.c
> @@ -27,9 +27,22 @@
> #include "viralloc.h"
> #include "virfile.h"
> #include "virtpm.h"
> +#include "vircommand.h"
> +#include "virbitmap.h"
> +#include "virjson.h"
>
> #define VIR_FROM_THIS VIR_FROM_NONE
>
> +VIR_ENUM_IMPL(virTPMSwtpmFeature,
> + VIR_TPM_SWTPM_FEATURE_LAST,
> + "cmdarg-pwd-fd",
> +);
> +
> +VIR_ENUM_IMPL(virTPMSwtpmSetupFeature,
> + VIR_TPM_SWTPM_SETUP_FEATURE_LAST,
> + "cmdarg-pwdfile-fd",
> +);
> +
> /**
> * virTPMCreateCancelPath:
> * @devpath: Path to the TPM device
> @@ -74,17 +87,22 @@ virTPMCreateCancelPath(const char *devpath)
> }
>
> /*
> - * executables for the swtpm; to be found on the host
> + * executables for the swtpm; to be found on the host along with
> + * capabilties bitmap
> */
> static char *swtpm_path;
> static struct stat swtpm_stat;
> +static virBitmapPtr swtpm_caps;
>
> static char *swtpm_setup;
> static struct stat swtpm_setup_stat;
> +static virBitmapPtr swtpm_setup_caps;
>
> static char *swtpm_ioctl;
> static struct stat swtpm_ioctl_stat;
>
> +typedef int (*TypeFromStringFn)(const char *);
> +
> const char *
> virTPMGetSwtpm(void)
> {
> @@ -109,6 +127,99 @@ virTPMGetSwtpmIoctl(void)
> return swtpm_ioctl;
> }
>
> +/* virTPMExecGetCaps
> + *
> + * Execute the prepared command and parse the returned JSON object
> + * to get the capabilities supported by the executable.
> + * A JSON object like this is expected:
> + *
> + * {
> + * "type": "swtpm",
> + * "features": [
> + * "cmdarg-seccomp",
> + * "cmdarg-key-fd",
> + * "cmdarg-pwd-fd"
> + * ]
> + * }
> + */
> +static virBitmapPtr
> +virTPMExecGetCaps(virCommandPtr cmd,
> + TypeFromStringFn typeFromStringFn)
> +{
> + int exitstatus;
> + virBitmapPtr bitmap;
> + VIR_AUTOFREE(char *) outbuf = NULL;
> + VIR_AUTOPTR(virJSONValue) json = NULL;
> + virJSONValuePtr featureList;
> + virJSONValuePtr item;
> + size_t idx;
> + const char *str;
> + int typ;
> +
> + virCommandSetOutputBuffer(cmd, &outbuf);
> + if (virCommandRun(cmd, &exitstatus) < 0)
> + return NULL;
> +
> + if (!(bitmap = virBitmapNewEmpty()))
> + return NULL;
> +
> + /* older version does not support --print-capabilties -- that's fine */
> + if (exitstatus != 0)
> + return bitmap;
We can't distinguish from an old version that lacks --print-capabilties and
from a new version that crashed when running --print-capabilties. The latter
shouldn't happen in general, but I thin kwe ought to at least put a VIR_DEBUG
in here to make it obvious we're treating this as if we hit an old binary
when looking at logs.
> +
> + json = virJSONValueFromString(outbuf);
> + if (!json)
> + goto error_bad_json;
> +
> + featureList = virJSONValueObjectGetArray(json, "features");
> + if (!featureList)
> + goto error_bad_json;
> +
> + if (!virJSONValueIsArray(featureList))
> + goto error_bad_json;
> +
> + for (idx = 0; idx < virJSONValueArraySize(featureList); idx++) {
> + item = virJSONValueArrayGet(featureList, idx);
> + if (!item)
> + continue;
> +
> + str = virJSONValueGetString(item);
> + if (!str)
> + goto error_bad_json;
> + typ = typeFromStringFn(str);
> + if (typ < 0)
> + continue;
> +
> + if (virBitmapSetBitExpand(bitmap, typ) < 0)
> + goto cleanup;
> + }
> +
> + cleanup:
> + return bitmap;
> +
> + error_bad_json:
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Unexpected JSON format: %s"), outbuf);
> + goto cleanup;
> +}
> @@ -142,7 +261,7 @@ virTPMEmulatorInit(void)
> size_t i;
>
> for (i = 0; i < ARRAY_CARDINALITY(prgs); i++) {
> - char *path;
> + VIR_AUTOFREE(char *) path = NULL;
> bool findit = *prgs[i].path == NULL;
> struct stat statbuf;
> char *tmp;
> @@ -174,18 +293,25 @@ virTPMEmulatorInit(void)
> virReportError(VIR_ERR_INTERNAL_ERROR,
> _("%s is not an executable"),
> path);
> - VIR_FREE(path);
> return -1;
> }
> if (stat(path, prgs[i].stat) < 0) {
> virReportSystemError(errno,
> _("Could not stat %s"), path);
> - VIR_FREE(path);
> return -1;
> }
If you re-post this series, just use VIR_AUTOFREE straightaway
in the earlier patch.
With the debug line added
Reviewed-by: Daniel P. Berrangé <[email protected]>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
--
libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list