mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
tpm: Parse the capabilities supported by swtpm and swtpm_setup
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 <stefanb@linux.ibm.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
01cf7a1bb9
commit
1f46dd4cba
@ -134,6 +134,8 @@ typedef enum {
|
|||||||
VIR_FROM_FIREWALLD = 68, /* Error from firewalld */
|
VIR_FROM_FIREWALLD = 68, /* Error from firewalld */
|
||||||
VIR_FROM_DOMAIN_CHECKPOINT = 69, /* Error from domain checkpoint */
|
VIR_FROM_DOMAIN_CHECKPOINT = 69, /* Error from domain checkpoint */
|
||||||
|
|
||||||
|
VIR_FROM_TPM = 70, /* Error from TPM */
|
||||||
|
|
||||||
# ifdef VIR_ENUM_SENTINELS
|
# ifdef VIR_ENUM_SENTINELS
|
||||||
VIR_ERR_DOMAIN_LAST
|
VIR_ERR_DOMAIN_LAST
|
||||||
# endif
|
# endif
|
||||||
|
@ -3181,6 +3181,8 @@ virTPMEmulatorInit;
|
|||||||
virTPMGetSwtpm;
|
virTPMGetSwtpm;
|
||||||
virTPMGetSwtpmIoctl;
|
virTPMGetSwtpmIoctl;
|
||||||
virTPMGetSwtpmSetup;
|
virTPMGetSwtpmSetup;
|
||||||
|
virTPMSwtpmFeatureTypeFromString;
|
||||||
|
virTPMSwtpmSetupFeatureTypeFromString;
|
||||||
|
|
||||||
|
|
||||||
# util/virtypedparam.h
|
# util/virtypedparam.h
|
||||||
|
@ -142,6 +142,8 @@ VIR_ENUM_IMPL(virErrorDomain,
|
|||||||
"Resource control",
|
"Resource control",
|
||||||
"FirewallD",
|
"FirewallD",
|
||||||
"Domain Checkpoint",
|
"Domain Checkpoint",
|
||||||
|
|
||||||
|
"TPM", /* 70 */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,8 +27,24 @@
|
|||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "virtpm.h"
|
#include "virtpm.h"
|
||||||
|
#include "vircommand.h"
|
||||||
|
#include "virbitmap.h"
|
||||||
|
#include "virjson.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_TPM
|
||||||
|
|
||||||
|
VIR_LOG_INIT("util.tpm");
|
||||||
|
|
||||||
|
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:
|
* virTPMCreateCancelPath:
|
||||||
@ -74,18 +90,23 @@ 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 virMutex swtpm_tools_lock = VIR_MUTEX_INITIALIZER;
|
static virMutex swtpm_tools_lock = VIR_MUTEX_INITIALIZER;
|
||||||
static char *swtpm_path;
|
static char *swtpm_path;
|
||||||
static struct stat swtpm_stat;
|
static struct stat swtpm_stat;
|
||||||
|
static virBitmapPtr swtpm_caps;
|
||||||
|
|
||||||
static char *swtpm_setup;
|
static char *swtpm_setup;
|
||||||
static struct stat swtpm_setup_stat;
|
static struct stat swtpm_setup_stat;
|
||||||
|
static virBitmapPtr swtpm_setup_caps;
|
||||||
|
|
||||||
static char *swtpm_ioctl;
|
static char *swtpm_ioctl;
|
||||||
static struct stat swtpm_ioctl_stat;
|
static struct stat swtpm_ioctl_stat;
|
||||||
|
|
||||||
|
typedef int (*TypeFromStringFn)(const char *);
|
||||||
|
|
||||||
char *
|
char *
|
||||||
virTPMGetSwtpm(void)
|
virTPMGetSwtpm(void)
|
||||||
{
|
{
|
||||||
@ -131,6 +152,101 @@ virTPMGetSwtpmIoctl(void)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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) {
|
||||||
|
VIR_DEBUG("Found swtpm that doesn't support --print-capabilities");
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virBitmapPtr
|
||||||
|
virTPMGetCaps(TypeFromStringFn typeFromStringFn,
|
||||||
|
const char *exec, const char *param1)
|
||||||
|
{
|
||||||
|
VIR_AUTOPTR(virCommand) cmd = NULL;
|
||||||
|
|
||||||
|
if (!(cmd = virCommandNew(exec)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (param1)
|
||||||
|
virCommandAddArg(cmd, param1);
|
||||||
|
virCommandAddArg(cmd, "--print-capabilities");
|
||||||
|
virCommandClearCaps(cmd);
|
||||||
|
|
||||||
|
return virTPMExecGetCaps(cmd, typeFromStringFn);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* virTPMEmulatorInit
|
* virTPMEmulatorInit
|
||||||
*
|
*
|
||||||
@ -145,16 +261,24 @@ virTPMEmulatorInit(void)
|
|||||||
const char *name;
|
const char *name;
|
||||||
char **path;
|
char **path;
|
||||||
struct stat *stat;
|
struct stat *stat;
|
||||||
|
const char *parm;
|
||||||
|
virBitmapPtr *caps;
|
||||||
|
TypeFromStringFn typeFromStringFn;
|
||||||
} prgs[] = {
|
} prgs[] = {
|
||||||
{
|
{
|
||||||
.name = "swtpm",
|
.name = "swtpm",
|
||||||
.path = &swtpm_path,
|
.path = &swtpm_path,
|
||||||
.stat = &swtpm_stat,
|
.stat = &swtpm_stat,
|
||||||
|
.parm = "socket",
|
||||||
|
.caps = &swtpm_caps,
|
||||||
|
.typeFromStringFn = virTPMSwtpmFeatureTypeFromString,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "swtpm_setup",
|
.name = "swtpm_setup",
|
||||||
.path = &swtpm_setup,
|
.path = &swtpm_setup,
|
||||||
.stat = &swtpm_setup_stat,
|
.stat = &swtpm_setup_stat,
|
||||||
|
.caps = &swtpm_setup_caps,
|
||||||
|
.typeFromStringFn = virTPMSwtpmSetupFeatureTypeFromString,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "swtpm_ioctl",
|
.name = "swtpm_ioctl",
|
||||||
@ -206,6 +330,14 @@ virTPMEmulatorInit(void)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
*prgs[i].path = path;
|
*prgs[i].path = path;
|
||||||
|
|
||||||
|
if (prgs[i].caps) {
|
||||||
|
*prgs[i].caps = virTPMGetCaps(prgs[i].typeFromStringFn,
|
||||||
|
path, prgs[i].parm);
|
||||||
|
path = NULL;
|
||||||
|
if (!*prgs[i].caps)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
path = NULL;
|
path = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,3 +26,18 @@ char *virTPMGetSwtpm(void);
|
|||||||
char *virTPMGetSwtpmSetup(void);
|
char *virTPMGetSwtpmSetup(void);
|
||||||
char *virTPMGetSwtpmIoctl(void);
|
char *virTPMGetSwtpmIoctl(void);
|
||||||
int virTPMEmulatorInit(void);
|
int virTPMEmulatorInit(void);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIR_TPM_SWTPM_FEATURE_CMDARG_PWD_FD,
|
||||||
|
|
||||||
|
VIR_TPM_SWTPM_FEATURE_LAST
|
||||||
|
} virTPMSwtpmFeature;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIR_TPM_SWTPM_SETUP_FEATURE_CMDARG_PWDFILE_FD,
|
||||||
|
|
||||||
|
VIR_TPM_SWTPM_SETUP_FEATURE_LAST
|
||||||
|
} virTPMSwtpmSetupFeature;
|
||||||
|
|
||||||
|
VIR_ENUM_DECL(virTPMSwtpmFeature);
|
||||||
|
VIR_ENUM_DECL(virTPMSwtpmSetupFeature);
|
||||||
|
Loading…
Reference in New Issue
Block a user