mirror of
https://github.com/stefanberger/swtpm.git
synced 2026-01-12 00:43:41 +00:00
swtpm_setup: Add support for --profile parameter
Add support for the --profile parameter that allows a user to select a profile for the TPM 2 instance. The profile parameter must be a string-formatted JSON map describing the profile to use. Resolves: https://github.com/stefanberger/libtpms/issues/284 Resolves: https://github.com/stefanberger/swtpm/issues/710 Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
parent
3a49ce1302
commit
df11aeb6b9
@ -193,6 +193,31 @@ size is used.
|
||||
This option allows the reconfiguration of the active PCR banks of a
|
||||
TPM 2 using the I<--pcr-banks> option.
|
||||
|
||||
=item B<--profile <json-profile>>
|
||||
|
||||
Configure a TPM 2 with the given profile. Example profiles look
|
||||
like this:
|
||||
|
||||
{"Name": "null"}
|
||||
|
||||
{"Name": "default-v1"}
|
||||
|
||||
{
|
||||
"Name": "custom",
|
||||
"Algorithms":"rsa,rsa-min-size=1024,tdes-min-size=128,hmac,aes,\
|
||||
aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,\
|
||||
sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,\
|
||||
sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,\
|
||||
ecc,ecc-min-size=192,ecc-nist,ecc-bn,symcipher,camellia,\
|
||||
camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb"
|
||||
}
|
||||
|
||||
|
||||
The JSON profile must contain the 'name' field with a name of a profile
|
||||
supported by libtpms. The profile may contain an algorithms field with a
|
||||
list of algorithms to enable. Unknown fields in the JSON profile will be
|
||||
ignored.
|
||||
|
||||
=item B<--print-capabilities> (since v0.2)
|
||||
|
||||
Print capabilities that were added to swtpm_setup after version 0.1.
|
||||
|
||||
@ -117,16 +117,54 @@ oom:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
static int get_profile_data(const char *info_data, JsonReader *jr,
|
||||
GString *gstr, const char *member,
|
||||
const char *prefix, const char *suffix)
|
||||
{
|
||||
g_string_append_printf(gstr, "%s: { \"canbedisabled\": ", prefix);
|
||||
|
||||
if (!json_reader_read_member(jr, member)) {
|
||||
logprintf(STDERR_FILENO,
|
||||
"Missing '%s' field: %s\n",
|
||||
member, info_data);
|
||||
return -1;
|
||||
}
|
||||
if (!json_reader_read_member(jr, "CanBeDisabled")) {
|
||||
logprintf(STDERR_FILENO,
|
||||
"Missing 'CanBeDisabled' field under '%s': %s\n",
|
||||
member, info_data);
|
||||
return -1;
|
||||
}
|
||||
g_string_append_printf(gstr, "\"%s\", \"implemented\": ",
|
||||
json_reader_get_string_value(jr));
|
||||
json_reader_end_member(jr);
|
||||
if (!json_reader_read_member(jr, "Implemented")) {
|
||||
logprintf(STDERR_FILENO,
|
||||
"Missing 'Implemented' field under '%s': %s\n",
|
||||
member, info_data);
|
||||
return -1;
|
||||
}
|
||||
g_string_append_printf(gstr, "\"%s\" }%s",
|
||||
json_reader_get_string_value(jr),
|
||||
suffix);
|
||||
json_reader_end_member(jr);
|
||||
json_reader_end_member(jr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_profiles(gchar **profiles)
|
||||
{
|
||||
char *info_data = TPMLIB_GetInfo(TPMLIB_INFO_AVAILABLE_PROFILES);
|
||||
char *info_data = TPMLIB_GetInfo(TPMLIB_INFO_AVAILABLE_PROFILES |
|
||||
TPMLIB_INFO_RUNTIME_ALGORITHMS |
|
||||
TPMLIB_INFO_RUNTIME_COMMANDS);
|
||||
JsonParser *jp = NULL;
|
||||
JsonReader *jr = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
JsonNode *root;
|
||||
gint i, num;
|
||||
int ret = 0;
|
||||
GString *gstr = g_string_new(NULL);
|
||||
GString *gstr = g_string_new("\"names\": [ ");
|
||||
|
||||
jp = json_parser_new();
|
||||
|
||||
@ -155,11 +193,18 @@ static int get_profiles(gchar **profiles)
|
||||
goto error_unref_jr;
|
||||
}
|
||||
g_string_append_printf(gstr, "%s\"%s\"",
|
||||
i > 0 ? ", " : " ",
|
||||
i > 0 ? ", " : "",
|
||||
json_reader_get_string_value(jr));
|
||||
json_reader_end_element(jr);
|
||||
json_reader_end_element(jr);
|
||||
}
|
||||
json_reader_end_member(jr);
|
||||
|
||||
if (get_profile_data(info_data, jr, gstr,
|
||||
"RuntimeAlgorithms", " ], \"algorithms\"", "") ||
|
||||
get_profile_data(info_data, jr, gstr,
|
||||
"RuntimeCommands", ", \"commands\"", " "))
|
||||
goto error_unref_jr;
|
||||
|
||||
|
||||
error_unref_jr:
|
||||
@ -218,7 +263,7 @@ int capabilities_print_json(bool cusetpm, TPMLIB_TPMVersion tpmversion)
|
||||
"\"features\": [ "
|
||||
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
|
||||
" ], "
|
||||
"\"profiles\": [%s ], "
|
||||
"\"profiles\": { %s}, "
|
||||
"\"version\": \"" VERSION "\" "
|
||||
"}",
|
||||
with_tpm1,
|
||||
|
||||
@ -8,6 +8,7 @@ MY_CFLAGS = @MY_CFLAGS@
|
||||
MY_LDFLAGS = @MY_LDFLAGS@
|
||||
|
||||
noinst_HEADERS = \
|
||||
profile.h \
|
||||
swtpm.h \
|
||||
swtpm_setup.h \
|
||||
swtpm_setup_utils.h
|
||||
@ -16,6 +17,7 @@ bin_PROGRAMS = \
|
||||
swtpm_setup
|
||||
|
||||
swtpm_setup_SOURCES = \
|
||||
profile.c \
|
||||
swtpm.c \
|
||||
swtpm_setup.c \
|
||||
swtpm_setup_utils.c \
|
||||
|
||||
108
src/swtpm_setup/profile.c
Normal file
108
src/swtpm_setup/profile.c
Normal file
@ -0,0 +1,108 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* profile.c: TPM 2 profile handling
|
||||
*
|
||||
* Author: Stefan Berger, stefanb@linux.ibm.com
|
||||
*
|
||||
* Copyright (c) IBM Corporation, 2022
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
#include "profile.h"
|
||||
#include "swtpm_utils.h"
|
||||
|
||||
/* Return the names of the supported profiles */
|
||||
static
|
||||
int get_profile_names(const gchar *swtpm_capabilities_json, gchar ***profile_names)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
JsonParser *jp = NULL;
|
||||
JsonReader *jr = NULL;
|
||||
JsonNode *root;
|
||||
gint i, num;
|
||||
int ret = 1;
|
||||
|
||||
jp = json_parser_new();
|
||||
if (!json_parser_load_from_data(jp, swtpm_capabilities_json, -1, &error)) {
|
||||
logerr(gl_LOGFILE, "Could not parse capabilities JSON '%s': %s\n",
|
||||
swtpm_capabilities_json, error->message);
|
||||
goto error_unref_jp;
|
||||
}
|
||||
|
||||
root = json_parser_get_root(jp);
|
||||
jr = json_reader_new(root);
|
||||
|
||||
if (!json_reader_read_member(jr, "profiles")) {
|
||||
logerr(gl_LOGFILE, "Missing 'profiles' field: %s\n",
|
||||
swtpm_capabilities_json);
|
||||
goto error_unref_jr;
|
||||
}
|
||||
if (!json_reader_read_member(jr, "names")) {
|
||||
logerr(gl_LOGFILE, "Missing 'names' field under 'profiles': %s\n",
|
||||
swtpm_capabilities_json);
|
||||
goto error_unref_jr;
|
||||
}
|
||||
|
||||
num = json_reader_count_elements(jr);
|
||||
if (num < 0) {
|
||||
logerr(gl_LOGFILE, "Number of profile names is bad (%d)\n",
|
||||
num);
|
||||
goto error_unref_jr;
|
||||
}
|
||||
|
||||
*profile_names = g_malloc0((num + 1) * sizeof(char *));
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!json_reader_read_element(jr, i)) {
|
||||
logerr(gl_LOGFILE, "Could not parse JSON list: %s\n", error->message);
|
||||
goto error_str_array_free;
|
||||
}
|
||||
(*profile_names)[i] = g_strdup(json_reader_get_string_value(jr));
|
||||
json_reader_end_element(jr);
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
|
||||
error_unref_jr:
|
||||
g_object_unref(jr);
|
||||
|
||||
error_unref_jp:
|
||||
g_object_unref(jp);
|
||||
|
||||
return ret;
|
||||
|
||||
error_str_array_free:
|
||||
g_strfreev(*profile_names);
|
||||
|
||||
goto error_unref_jr;
|
||||
}
|
||||
|
||||
int check_json_profile(const gchar *swtpm_capabilities_json, const char *json_profile)
|
||||
{
|
||||
gchar **profile_names = NULL;
|
||||
g_autofree gchar *name = NULL;
|
||||
int idx;
|
||||
int ret;
|
||||
|
||||
ret = json_get_map_value(json_profile, "Name", &name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = get_profile_names(swtpm_capabilities_json, &profile_names);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
idx = strv_strcmp(profile_names, name);
|
||||
if (idx < 0) {
|
||||
logerr(gl_LOGFILE, "swtpm does not support a profile with name '%s'\n", name);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
error:
|
||||
g_strfreev(profile_names);
|
||||
|
||||
return ret;
|
||||
}
|
||||
17
src/swtpm_setup/profile.h
Normal file
17
src/swtpm_setup/profile.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* profile.h: TPM 2 profile handling
|
||||
*
|
||||
* Author: Stefan Berger, stefanb@linux.ibm.com
|
||||
*
|
||||
* Copyright (c) IBM Corporation, 2022
|
||||
*/
|
||||
|
||||
#ifndef SWTPM_SETUP_PROFILE_H
|
||||
#define SWTPM_SETUP_PROFILE_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
int check_json_profile(const gchar *swtpm_capabilities_json, const char *json_profile);
|
||||
|
||||
#endif /* SWTPM_SETUP_PROFILE_H */
|
||||
@ -76,6 +76,7 @@ static void swtpm_close_comm(struct swtpm *self, bool all)
|
||||
static int swtpm_start(struct swtpm *self)
|
||||
{
|
||||
g_autofree gchar *tpmstate = g_strdup_printf("backend-uri=%s", self->state_path);
|
||||
g_autofree gchar *json_profile = NULL;
|
||||
g_autofree gchar *pidfile_arg = NULL;
|
||||
g_autofree gchar *server_fd = NULL;
|
||||
g_autofree gchar *ctrl_fd = NULL;
|
||||
@ -118,6 +119,12 @@ static int swtpm_start(struct swtpm *self)
|
||||
argv = concat_arrays(argv, (gchar*[]){"--key", keyopts, NULL}, TRUE);
|
||||
}
|
||||
|
||||
if (self->json_profile != NULL) {
|
||||
json_profile = g_strdup_printf("profile=%s", self->json_profile);
|
||||
argv = concat_arrays(argv, (gchar*[]){"--profile", json_profile, NULL}, TRUE);
|
||||
logit(self->logfile, "Apply profile: %s\n", self->json_profile);
|
||||
}
|
||||
|
||||
if (gl_LOGFILE != NULL) {
|
||||
logop = g_strdup_printf("file=%s", gl_LOGFILE);
|
||||
argv = concat_arrays(argv, (gchar*[]){"--log", logop, NULL}, TRUE);
|
||||
@ -2009,7 +2016,7 @@ static void swtpm_init(struct swtpm *swtpm,
|
||||
gchar **swtpm_exec_l, const gchar *state_path,
|
||||
const gchar *keyopts, const gchar *logfile,
|
||||
int *fds_to_pass, size_t n_fds_to_pass,
|
||||
gboolean is_tpm2)
|
||||
gboolean is_tpm2, const gchar *json_profile)
|
||||
{
|
||||
swtpm->cops = &swtpm_cops;
|
||||
swtpm->swtpm_exec_l = swtpm_exec_l;
|
||||
@ -2019,6 +2026,7 @@ static void swtpm_init(struct swtpm *swtpm,
|
||||
swtpm->fds_to_pass = fds_to_pass;
|
||||
swtpm->n_fds_to_pass = n_fds_to_pass;
|
||||
swtpm->is_tpm2 = is_tpm2;
|
||||
swtpm->json_profile = json_profile;
|
||||
|
||||
swtpm->pid = -1;
|
||||
swtpm->ctrl_fds[0] = swtpm->ctrl_fds[1] = -1;
|
||||
@ -2032,7 +2040,7 @@ struct swtpm12 *swtpm12_new(gchar **swtpm_exec_l, const gchar *state_path,
|
||||
struct swtpm12 *swtpm12 = g_malloc0(sizeof(struct swtpm12));
|
||||
|
||||
swtpm_init(&swtpm12->swtpm, swtpm_exec_l, state_path, keyopts, logfile,
|
||||
fds_to_pass, n_fds_to_pass, FALSE);
|
||||
fds_to_pass, n_fds_to_pass, FALSE, NULL);
|
||||
swtpm12->ops = &swtpm_tpm12_ops;
|
||||
|
||||
return swtpm12;
|
||||
@ -2040,12 +2048,13 @@ struct swtpm12 *swtpm12_new(gchar **swtpm_exec_l, const gchar *state_path,
|
||||
|
||||
struct swtpm2 *swtpm2_new(gchar **swtpm_exec_l, const gchar *state_path,
|
||||
const gchar *keyopts, const gchar *logfile,
|
||||
int *fds_to_pass, size_t n_fds_to_pass)
|
||||
int *fds_to_pass, size_t n_fds_to_pass,
|
||||
const gchar *json_profile)
|
||||
{
|
||||
struct swtpm2 *swtpm2 = g_malloc0(sizeof(struct swtpm2));
|
||||
|
||||
swtpm_init(&swtpm2->swtpm, swtpm_exec_l, state_path, keyopts, logfile,
|
||||
fds_to_pass, n_fds_to_pass, TRUE);
|
||||
fds_to_pass, n_fds_to_pass, TRUE, json_profile);
|
||||
swtpm2->ops = &swtpm_tpm2_ops;
|
||||
|
||||
return swtpm2;
|
||||
|
||||
@ -68,6 +68,7 @@ struct swtpm {
|
||||
const int *fds_to_pass;
|
||||
size_t n_fds_to_pass;
|
||||
gboolean is_tpm2;
|
||||
const char *json_profile;
|
||||
|
||||
GPid pid;
|
||||
int ctrl_fds[2];
|
||||
@ -90,7 +91,8 @@ struct swtpm12 *swtpm12_new(gchar **swtpm_prg_l, const gchar *tpm_state_path,
|
||||
|
||||
struct swtpm2 *swtpm2_new(gchar **swtpm_prg_l, const gchar *tpm_state_path,
|
||||
const gchar *swtpm_keyopts, const gchar *logfile,
|
||||
int *fds_to_pass, size_t n_fds_to_pass);
|
||||
int *fds_to_pass, size_t n_fds_to_pass,
|
||||
const gchar *profile_rules);
|
||||
|
||||
void swtpm_free(struct swtpm *);
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
|
||||
#include <libtpms/tpm_nvfilename.h>
|
||||
|
||||
#include "profile.h"
|
||||
#include "swtpm.h"
|
||||
#include "swtpm_conf.h"
|
||||
#include "swtpm_utils.h"
|
||||
@ -548,14 +549,14 @@ static int init_tpm2(unsigned long flags, gchar **swtpm_prg_l, const gchar *conf
|
||||
const gchar *tpm2_state_path, const gchar *vmid, const gchar *pcr_banks,
|
||||
const gchar *swtpm_keyopt, int *fds_to_pass, size_t n_fds_to_pass,
|
||||
unsigned int rsa_keysize, const gchar *certsdir,
|
||||
const gchar *user_certsdir)
|
||||
const gchar *user_certsdir, const gchar *json_profile)
|
||||
{
|
||||
struct swtpm2 *swtpm2;
|
||||
struct swtpm *swtpm;
|
||||
int ret;
|
||||
|
||||
swtpm2 = swtpm2_new(swtpm_prg_l, tpm2_state_path, swtpm_keyopt, gl_LOGFILE,
|
||||
fds_to_pass, n_fds_to_pass);
|
||||
fds_to_pass, n_fds_to_pass, json_profile);
|
||||
if (swtpm2 == NULL)
|
||||
return 1;
|
||||
swtpm = &swtpm2->swtpm;
|
||||
@ -978,6 +979,9 @@ static void usage(const char *prgname, const char *default_config_file)
|
||||
" The active PCR banks can be changed but no new keys will\n"
|
||||
" be created.\n"
|
||||
"\n"
|
||||
"--profile <json-profile>\n"
|
||||
" : Configure swtpm with the given profile.\n"
|
||||
"\n"
|
||||
"--version : Display version and exit\n"
|
||||
"\n"
|
||||
"--help,-h : Display this help screen\n\n",
|
||||
@ -1098,6 +1102,18 @@ static int get_rsa_keysize_caps(unsigned long flags, gchar **swtpm_prg_l,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int validate_json_profile(gchar **swtpm_prg_l, const char *json_profile)
|
||||
{
|
||||
g_autofree gchar *standard_output = NULL;
|
||||
int ret;
|
||||
|
||||
ret = get_swtpm_capabilities(swtpm_prg_l, TRUE, &standard_output);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return check_json_profile(standard_output, json_profile);
|
||||
}
|
||||
|
||||
/* Print the JSON object of swtpm_setup's capabilities */
|
||||
static int print_capabilities(char **swtpm_prg_l, gboolean swtpm_has_tpm12,
|
||||
gboolean swtpm_has_tpm2)
|
||||
@ -1122,7 +1138,10 @@ static int print_capabilities(char **swtpm_prg_l, gboolean swtpm_has_tpm12,
|
||||
"\"features\": [ %s%s\"cmdarg-keyfile-fd\", \"cmdarg-pwdfile-fd\", \"tpm12-not-need-root\""
|
||||
", \"cmdarg-write-ek-cert-files\", \"cmdarg-create-config-files\""
|
||||
", \"cmdarg-reconfigure-pcr-banks\""
|
||||
"%s ], "
|
||||
"%s"
|
||||
", \"cmdarg-profile\""
|
||||
""
|
||||
" ], "
|
||||
"\"version\": \"" VERSION "\" "
|
||||
"}\n",
|
||||
swtpm_has_tpm12 ? "\"tpm-1.2\", " : "",
|
||||
@ -1244,6 +1263,7 @@ int main(int argc, char *argv[])
|
||||
{"version", no_argument, NULL, '1'},
|
||||
{"print-capabilities", no_argument, NULL, 'y'},
|
||||
{"reconfigure", no_argument, NULL, 'R'},
|
||||
{"profile", required_argument, NULL, 'I'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
@ -1272,6 +1292,7 @@ int main(int argc, char *argv[])
|
||||
g_autofree gchar *runas = NULL;
|
||||
g_autofree gchar *certsdir = NULL;
|
||||
g_autofree gchar *user_certsdir = NULL;
|
||||
g_autofree gchar *json_profile = NULL;
|
||||
gchar *tmp;
|
||||
gchar **swtpm_prg_l = NULL;
|
||||
gchar **tmp_l = NULL;
|
||||
@ -1457,6 +1478,10 @@ int main(int argc, char *argv[])
|
||||
case 'R': /* --reconfigure */
|
||||
flags |= SETUP_RECONFIGURE_F;
|
||||
break;
|
||||
case 'I': /* --profile */
|
||||
g_free(json_profile);
|
||||
json_profile = g_strdup(optarg);
|
||||
break;
|
||||
case '?':
|
||||
case 'h': /* --help */
|
||||
usage(argv[0], config_file);
|
||||
@ -1484,7 +1509,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
g_free(tmp);
|
||||
|
||||
|
||||
ret = get_supported_tpm_versions(swtpm_prg_l, &swtpm_has_tpm12, &swtpm_has_tpm2);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
@ -1615,6 +1639,14 @@ int main(int argc, char *argv[])
|
||||
pcr_banks = get_default_pcr_banks(config_file_lines);
|
||||
}
|
||||
|
||||
if ((flags & SETUP_TPM2_F) != 0 && json_profile) {
|
||||
if (validate_json_profile(swtpm_prg_l, json_profile) != 0)
|
||||
goto error;
|
||||
} else if (json_profile) {
|
||||
logerr(gl_LOGFILE, "There's no --profile support for TPM 1.2\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (cipher != NULL) {
|
||||
if (strcmp(cipher, "aes-128-cbc") != 0 &&
|
||||
strcmp(cipher, "aes-cbc") != 0 &&
|
||||
@ -1729,7 +1761,7 @@ int main(int argc, char *argv[])
|
||||
} else {
|
||||
ret = init_tpm2(flags, swtpm_prg_l, config_file, tpm_state_path, vmid, pcr_banks,
|
||||
swtpm_keyopt, fds_to_pass, n_fds_to_pass, rsa_keysize, certsdir,
|
||||
user_certsdir);
|
||||
user_certsdir, json_profile);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
|
||||
@ -17,11 +17,13 @@ libswtpm_utils_la_CFLAGS = \
|
||||
$(MY_CFLAGS) \
|
||||
$(CFLAGS) \
|
||||
$(HARDENING_CFLAGS) \
|
||||
$(GLIB_CFLAGS)
|
||||
$(GLIB_CFLAGS) \
|
||||
$(JSON_GLIB_CFLAGS)
|
||||
|
||||
libswtpm_utils_la_LDFLAGS = \
|
||||
$(MY_LDFLAGS) \
|
||||
$(HARDENING_LDFLAGS)
|
||||
$(HARDENING_LDFLAGS) \
|
||||
$(JSON_GLIB_LIBS)
|
||||
|
||||
libswtpm_utils_la_SOURCES = \
|
||||
swtpm_utils.c
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
#include "swtpm_utils.h"
|
||||
|
||||
@ -440,3 +441,51 @@ int check_directory_access(const gchar *directory, int mode, const struct passwd
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int json_get_map_value(const char *json_input, const char *field_name,
|
||||
gchar **value)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
JsonParser *jp = NULL;
|
||||
JsonReader *jr = NULL;
|
||||
JsonNode *root;
|
||||
int ret = -1;
|
||||
|
||||
jp = json_parser_new();
|
||||
if (!json_parser_load_from_data(jp, json_input, -1, &error)) {
|
||||
logerr(gl_LOGFILE,
|
||||
"Could not parse JSON '%s': %s\n", json_input, error->message);
|
||||
goto error_unref_jp;
|
||||
}
|
||||
|
||||
root = json_parser_get_root(jp);
|
||||
jr = json_reader_new(root);
|
||||
|
||||
if (!json_reader_read_member(jr, field_name)) {
|
||||
logerr(gl_LOGFILE, "Missing '%s' field in '%s'\n",
|
||||
field_name, json_input);
|
||||
goto error_unref_jr;
|
||||
}
|
||||
*value = g_strdup(json_reader_get_string_value(jr));
|
||||
|
||||
ret = 0;
|
||||
|
||||
error_unref_jr:
|
||||
g_object_unref(jr);
|
||||
|
||||
error_unref_jp:
|
||||
g_object_unref(jp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int strv_strcmp(gchar *const*str_array, const gchar *s)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; str_array[i]; i++) {
|
||||
if (strcmp(str_array[i], s) == 0)
|
||||
return (int)i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -55,4 +55,9 @@ gchar *str_replace(const char *in, const char *torep, const char *rep);
|
||||
|
||||
int check_directory_access(const gchar *directory, int mode, const struct passwd *curr_user);
|
||||
|
||||
int json_get_map_value(const char *json_input, const char *field_name,
|
||||
gchar **value);
|
||||
|
||||
int strv_strcmp(gchar *const*str_array, const gchar *s);
|
||||
|
||||
#endif /* SWTPM_UTILS_H */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user