Merge pull request #25224 from poettering/measure-append

add --append= switch to systemd-measure
This commit is contained in:
Yu Watanabe
2022-12-15 21:47:29 +09:00
committed by GitHub
7 changed files with 103 additions and 15 deletions
+24 -1
View File
@@ -33,12 +33,14 @@ static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_PRETTY_AUTO|JSON_FORM
static PagerFlags arg_pager_flags = 0;
static bool arg_current = false;
static char **arg_phase = NULL;
static char *arg_append = NULL;
STATIC_DESTRUCTOR_REGISTER(arg_banks, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
STATIC_DESTRUCTOR_REGISTER(arg_private_key, freep);
STATIC_DESTRUCTOR_REGISTER(arg_public_key, freep);
STATIC_DESTRUCTOR_REGISTER(arg_phase, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_append, freep);
static inline void free_sections(char*(*sections)[_UNIFIED_SECTION_MAX]) {
for (UnifiedSection c = 0; c < _UNIFIED_SECTION_MAX; c++)
@@ -73,6 +75,7 @@ static int help(int argc, char *argv[], void *userdata) {
" --public-key=KEY Public key (PEM) to validate against\n"
" --json=MODE Output as JSON\n"
" -j Same as --json=pretty on tty, --json=short otherwise\n"
" --append=PATH Load specified JSON signature, and append new signature to it\n"
"\n%3$sUKI PE Section Options:%4$s %3$sUKI PE Section%4$s\n"
" --linux=PATH Path to Linux kernel image file %7$s .linux\n"
" --osrel=PATH Path to os-release file %7$s .osrel\n"
@@ -128,6 +131,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_TPM2_DEVICE,
ARG_JSON,
ARG_PHASE,
ARG_APPEND,
};
static const struct option options[] = {
@@ -148,6 +152,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "public-key", required_argument, NULL, ARG_PUBLIC_KEY },
{ "json", required_argument, NULL, ARG_JSON },
{ "phase", required_argument, NULL, ARG_PHASE },
{ "append", required_argument, NULL, ARG_APPEND },
{}
};
@@ -254,6 +259,13 @@ static int parse_argv(int argc, char *argv[]) {
break;
}
case ARG_APPEND:
r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_append);
if (r < 0)
return r;
break;
case '?':
return -EINVAL;
@@ -623,6 +635,8 @@ static int verb_calculate(int argc, char *argv[], void *userdata) {
if (!arg_sections[UNIFIED_SECTION_LINUX] && !arg_current)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Either --linux= or --current must be specified, refusing.");
if (arg_append)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "The --append= switch is only supported for 'sign', not 'calculate'.");
assert(!strv_isempty(arg_banks));
assert(!strv_isempty(arg_phase));
@@ -728,6 +742,15 @@ static int verb_sign(int argc, char *argv[], void *userdata) {
assert(!strv_isempty(arg_banks));
assert(!strv_isempty(arg_phase));
if (arg_append) {
r = json_parse_file(NULL, arg_append, 0, &v, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to parse '%s': %m", arg_append);
if (!json_variant_is_object(v))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File '%s' is not a valid JSON object, refusing.", arg_append);
}
/* When signing we only support JSON output */
arg_json_format_flags &= ~JSON_FORMAT_OFF;
@@ -936,7 +959,7 @@ static int verb_sign(int argc, char *argv[], void *userdata) {
_cleanup_(json_variant_unrefp) JsonVariant *av = NULL;
av = json_variant_ref(json_variant_by_key(v, p->bank));
r = json_variant_append_array(&av, bv);
r = json_variant_append_array_nodup(&av, bv);
if (r < 0) {
log_error_errno(r, "Failed to append JSON object: %m");
goto finish;
+21 -1
View File
@@ -2093,7 +2093,6 @@ int json_variant_append_array(JsonVariant **v, JsonVariant *element) {
assert(v);
assert(element);
if (!*v || json_variant_is_null(*v))
blank = true;
else if (json_variant_is_array(*v))
@@ -2151,6 +2150,27 @@ int json_variant_append_array(JsonVariant **v, JsonVariant *element) {
return 0;
}
JsonVariant *json_variant_find(JsonVariant *haystack, JsonVariant *needle) {
JsonVariant *i;
/* Find a json object in an array. Returns NULL if not found, or if the array is not actually an array. */
JSON_VARIANT_ARRAY_FOREACH(i, haystack)
if (json_variant_equal(i, needle))
return i;
return NULL;
}
int json_variant_append_array_nodup(JsonVariant **v, JsonVariant *element) {
assert(v);
if (json_variant_find(*v, element))
return 0;
return json_variant_append_array(v, element);
}
int json_variant_strv(JsonVariant *v, char ***ret) {
char **l = NULL;
bool sensitive;
+3
View File
@@ -210,7 +210,10 @@ int json_variant_set_field_unsigned(JsonVariant **v, const char *field, uint64_t
int json_variant_set_field_boolean(JsonVariant **v, const char *field, bool b);
int json_variant_set_field_strv(JsonVariant **v, const char *field, char **l);
JsonVariant *json_variant_find(JsonVariant *haystack, JsonVariant *needle);
int json_variant_append_array(JsonVariant **v, JsonVariant *element);
int json_variant_append_array_nodup(JsonVariant **v, JsonVariant *element);
int json_variant_merge(JsonVariant **v, JsonVariant *m);
+25
View File
@@ -726,4 +726,29 @@ TEST(json_array_append_without_source) {
json_array_append_with_source_one(false);
}
TEST(json_array_append_nodup) {
_cleanup_(json_variant_unrefp) JsonVariant *l = NULL, *s = NULL, *wd = NULL, *nd = NULL;
assert_se(json_build(&l, JSON_BUILD_STRV(STRV_MAKE("foo", "bar", "baz", "bar", "baz", "foo", "qux", "baz"))) >= 0);
assert_se(json_build(&s, JSON_BUILD_STRV(STRV_MAKE("foo", "bar", "baz", "qux"))) >= 0);
assert_se(!json_variant_equal(l, s));
assert_se(json_variant_elements(l) == 8);
assert_se(json_variant_elements(s) == 4);
JsonVariant *i;
JSON_VARIANT_ARRAY_FOREACH(i, l) {
assert_se(json_variant_append_array(&wd, i) >= 0);
assert_se(json_variant_append_array_nodup(&nd, i) >= 0);
}
assert_se(json_variant_elements(wd) == 8);
assert_se(json_variant_equal(l, wd));
assert_se(!json_variant_equal(s, wd));
assert_se(json_variant_elements(nd) == 4);
assert_se(!json_variant_equal(l, nd));
assert_se(json_variant_equal(s, nd));
}
DEFINE_TEST_MAIN(LOG_DEBUG);