From: Colin Walters Date: Thu, 8 Feb 2024 23:09:11 +0000 (-0500) Subject: lib: Move parsing of composefs config into otcore X-Git-Tag: archive/raspbian/2024.8-1+rpi1^2~7^2~5^2~8^2~3 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=7d9fa8e92a3e0fd78560a2d54a7ee12a5580e028;p=ostree.git lib: Move parsing of composefs config into otcore So it can be shared with the deployment path. Prep for dropping `ex-integrity.composefs`. --- diff --git a/src/libotcore/otcore-prepare-root.c b/src/libotcore/otcore-prepare-root.c index f7523ef6..12a85c08 100644 --- a/src/libotcore/otcore-prepare-root.c +++ b/src/libotcore/otcore-prepare-root.c @@ -19,6 +19,12 @@ #include "otcore.h" +// This key is used by default if present in the initramfs to verify +// the signature on the target commit object. When composefs is +// in use, the ostree commit metadata will contain the composefs image digest, +// which can be used to fully verify the target filesystem tree. +#define BINDING_KEYPATH "/etc/ostree/initramfs-root-binding.key" + static bool proc_cmdline_has_key_starting_with (const char *cmdline, const char *key) { @@ -137,3 +143,69 @@ otcore_load_config (int rootfs_fd, const char *filename, GError **error) return g_steal_pointer (&ret); } + +void +otcore_free_composefs_config (ComposefsConfig *config) +{ + g_ptr_array_unref (config->pubkeys); + g_free (config->signature_pubkey); + g_free (config); +} + +// Parse the [composefs] section of the prepare-root.conf. +ComposefsConfig * +otcore_load_composefs_config (GKeyFile *config, GError **error) +{ + GLNX_AUTO_PREFIX_ERROR ("Loading composefs config", error); + + g_autoptr (ComposefsConfig) ret = g_new0 (ComposefsConfig, 1); + + g_autofree char *enabled = g_key_file_get_value (config, OTCORE_PREPARE_ROOT_COMPOSEFS_KEY, + OTCORE_PREPARE_ROOT_ENABLED_KEY, NULL); + if (g_strcmp0 (enabled, "signed") == 0) + { + ret->enabled = OT_TRISTATE_YES; + ret->is_signed = true; + } + else if (!ot_keyfile_get_tristate_with_default (config, OTCORE_PREPARE_ROOT_COMPOSEFS_KEY, + OTCORE_PREPARE_ROOT_ENABLED_KEY, + OT_TRISTATE_MAYBE, &ret->enabled, error)) + return NULL; + + // Look for a key - we default to the initramfs binding path. + if (!ot_keyfile_get_value_with_default (config, OTCORE_PREPARE_ROOT_COMPOSEFS_KEY, + OTCORE_PREPARE_ROOT_KEYPATH_KEY, BINDING_KEYPATH, + &ret->signature_pubkey, error)) + return NULL; + + if (ret->is_signed) + { + ret->pubkeys = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref); + + g_autofree char *pubkeys = NULL; + gsize pubkeys_size; + + /* Load keys */ + + if (!g_file_get_contents (ret->signature_pubkey, &pubkeys, &pubkeys_size, error)) + return glnx_prefix_error_null (error, "Reading public key file '%s'", + ret->signature_pubkey); + + g_auto (GStrv) lines = g_strsplit (pubkeys, "\n", -1); + for (char **iter = lines; *iter; iter++) + { + const char *line = *iter; + if (!*line) + continue; + + gsize pubkey_size; + g_autofree guchar *pubkey = g_base64_decode (line, &pubkey_size); + g_ptr_array_add (ret->pubkeys, g_bytes_new_take (g_steal_pointer (&pubkey), pubkey_size)); + } + + if (ret->pubkeys->len == 0) + return glnx_null_throw (error, "public key file specified, but no public keys found"); + } + + return g_steal_pointer (&ret); +} diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h index 752c0758..d617a811 100644 --- a/src/libotcore/otcore.h +++ b/src/libotcore/otcore.h @@ -48,6 +48,18 @@ gboolean otcore_get_ostree_target (const char *cmdline, char **out_target, GErro GKeyFile *otcore_load_config (int rootfs, const char *filename, GError **error); +typedef struct +{ + OtTristate enabled; + gboolean is_signed; + char *signature_pubkey; + GPtrArray *pubkeys; +} ComposefsConfig; +void otcore_free_composefs_config (ComposefsConfig *config); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComposefsConfig, otcore_free_composefs_config) + +ComposefsConfig *otcore_load_composefs_config (GKeyFile *config, GError **error); + // Our directory with transient state (eventually /run/ostree-booted should be a link to // /run/ostree/booted) #define OTCORE_RUN_OSTREE "/run/ostree" @@ -70,6 +82,10 @@ GKeyFile *otcore_load_config (int rootfs, const char *filename, GError **error); // EROFS mount if we somehow leaked it (but it *should* be unmounted always). #define OSTREE_COMPOSEFS_LOWERMNT OTCORE_RUN_OSTREE_PRIVATE "/cfsroot-lower" +#define OTCORE_PREPARE_ROOT_COMPOSEFS_KEY "composefs" +#define OTCORE_PREPARE_ROOT_ENABLED_KEY "enabled" +#define OTCORE_PREPARE_ROOT_KEYPATH_KEY "keypath" + // The file written in the initramfs which contains an a{sv} of metadata // from ostree-prepare-root. #define OTCORE_RUN_BOOTED "/run/ostree-booted" diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c index 28e422f4..bf880e12 100644 --- a/src/switchroot/ostree-prepare-root.c +++ b/src/switchroot/ostree-prepare-root.c @@ -78,12 +78,6 @@ #define PREPARE_ROOT_CONFIG_PATH "ostree/prepare-root.conf" -// This key is used by default if present in the initramfs to verify -// the signature on the target commit object. When composefs is -// in use, the ostree commit metadata will contain the composefs image digest, -// which can be used to fully verify the target filesystem tree. -#define BINDING_KEYPATH "/etc/ostree/initramfs-root-binding.key" - #define SYSROOT_KEY "sysroot" #define READONLY_KEY "readonly" @@ -92,10 +86,6 @@ #define ETC_KEY "etc" #define TRANSIENT_KEY "transient" -#define COMPOSEFS_KEY "composefs" -#define ENABLED_KEY "enabled" -#define KEYPATH_KEY "keypath" - #define OSTREE_PREPARE_ROOT_DEPLOYMENT_MSG \ SD_ID128_MAKE (71, 70, 33, 6a, 73, ba, 46, 01, ba, d3, 1a, f8, 88, aa, 0d, f7) @@ -258,79 +248,6 @@ composefs_error_message (int errsv) #endif -typedef struct -{ - OtTristate enabled; - gboolean is_signed; - char *signature_pubkey; - GPtrArray *pubkeys; -} ComposefsConfig; - -static void -free_composefs_config (ComposefsConfig *config) -{ - g_ptr_array_unref (config->pubkeys); - g_free (config->signature_pubkey); - g_free (config); -} - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComposefsConfig, free_composefs_config) - -// Parse the [composefs] section of the prepare-root.conf. -static ComposefsConfig * -load_composefs_config (GKeyFile *config, GError **error) -{ - GLNX_AUTO_PREFIX_ERROR ("Loading composefs config", error); - - g_autoptr (ComposefsConfig) ret = g_new0 (ComposefsConfig, 1); - - g_autofree char *enabled = g_key_file_get_value (config, COMPOSEFS_KEY, ENABLED_KEY, NULL); - if (g_strcmp0 (enabled, "signed") == 0) - { - ret->enabled = OT_TRISTATE_YES; - ret->is_signed = true; - } - else if (!ot_keyfile_get_tristate_with_default (config, COMPOSEFS_KEY, ENABLED_KEY, - OT_TRISTATE_MAYBE, &ret->enabled, error)) - return NULL; - - // Look for a key - we default to the initramfs binding path. - if (!ot_keyfile_get_value_with_default (config, COMPOSEFS_KEY, KEYPATH_KEY, BINDING_KEYPATH, - &ret->signature_pubkey, error)) - return NULL; - - if (ret->is_signed) - { - ret->pubkeys = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref); - - g_autofree char *pubkeys = NULL; - gsize pubkeys_size; - - /* Load keys */ - - if (!g_file_get_contents (ret->signature_pubkey, &pubkeys, &pubkeys_size, error)) - return glnx_prefix_error_null (error, "Reading public key file '%s'", - ret->signature_pubkey); - - g_auto (GStrv) lines = g_strsplit (pubkeys, "\n", -1); - for (char **iter = lines; *iter; iter++) - { - const char *line = *iter; - if (!*line) - continue; - - gsize pubkey_size; - g_autofree guchar *pubkey = g_base64_decode (line, &pubkey_size); - g_ptr_array_add (ret->pubkeys, g_bytes_new_take (g_steal_pointer (&pubkey), pubkey_size)); - } - - if (ret->pubkeys->len == 0) - return glnx_null_throw (error, "public key file specified, but no public keys found"); - } - - return g_steal_pointer (&ret); -} - int main (int argc, char *argv[]) { @@ -362,7 +279,7 @@ main (int argc, char *argv[]) // We always parse the composefs config, because we want to detect and error // out if it's enabled, but not supported at compile time. - g_autoptr (ComposefsConfig) composefs_config = load_composefs_config (config, &error); + g_autoptr (ComposefsConfig) composefs_config = otcore_load_composefs_config (config, &error); if (!composefs_config) errx (EXIT_FAILURE, "%s", error->message);