diff options
author | Dan Nicholson <nicholson@endlessm.com> | 2020-01-21 12:43:35 -0700 |
---|---|---|
committer | Dan Nicholson <dbn@endlessos.org> | 2023-02-07 14:50:47 -0700 |
commit | 6f8669331d8dffa05296135443116268d21bac54 (patch) | |
tree | 69f98778460ff8d8f6e344936d568d310e440ca3 /src | |
parent | 6cc75a6c1e2e72d536568e17a6a45ca6cd629630 (diff) | |
download | ostree-6f8669331d8dffa05296135443116268d21bac54.tar.gz |
repo: Prevent publishing summary without matching signature
Use a temporary directory for the summary and signature file in
`ostree_repo_regenerate_metadata` so that the summary file isn't
published if signing fails. This prevents publishing a summary without a
signature file or leaving a mismatched signature file in place.
Diffstat (limited to 'src')
-rw-r--r-- | src/libostree/ostree-repo.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 81d3e612..4dbec47b 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -43,6 +43,7 @@ #include "ostree-repo-static-delta-private.h" #include "ot-fs-utils.h" #include "ostree-autocleanups.h" +#include "ostree-sign-private.h" #include <locale.h> #include <glib/gstdio.h> @@ -6543,8 +6544,17 @@ regenerate_metadata (OstreeRepo *self, if (!ostree_repo_static_delta_reindex (self, 0, NULL, cancellable, error)) return FALSE; + /* Create the summary and signature in a temporary directory so that + * the summary isn't published without a matching signature. + */ + g_auto(GLnxTmpDir) summary_tmpdir = { 0, }; + if (!glnx_mkdtempat (self->tmp_dir_fd, "summary-XXXXXX", 0777, + &summary_tmpdir, error)) + return FALSE; + g_debug ("Using summary tmpdir %s", summary_tmpdir.path); + if (!_ostree_repo_file_replace_contents (self, - self->repo_dir_fd, + summary_tmpdir.fd, "summary", g_variant_get_data (summary), g_variant_get_size (summary), @@ -6552,18 +6562,45 @@ regenerate_metadata (OstreeRepo *self, error)) return FALSE; - if (!ot_ensure_unlinked_at (self->repo_dir_fd, "summary.sig", error)) - return FALSE; - if (gpg_key_ids != NULL && - !ostree_repo_add_gpg_signature_summary (self, (const char **) gpg_key_ids, gpg_homedir, - cancellable, error)) + !_ostree_repo_add_gpg_signature_summary_at (self, summary_tmpdir.fd, + (const char **) gpg_key_ids, gpg_homedir, + cancellable, error)) return FALSE; if (sign_keys != NULL && - !ostree_sign_summary (sign, self, sign_keys, cancellable, error)) + !_ostree_sign_summary_at (sign, self, summary_tmpdir.fd, sign_keys, + cancellable, error)) return FALSE; + /* Rename them into place */ + if (!glnx_renameat (summary_tmpdir.fd, "summary", + self->repo_dir_fd, "summary", + error)) + return glnx_prefix_error (error, "Unable to rename summary file: "); + + if (gpg_key_ids != NULL || sign_keys != NULL) + { + if (!glnx_renameat (summary_tmpdir.fd, "summary.sig", + self->repo_dir_fd, "summary.sig", + error)) + { + /* Delete an existing signature since it no longer corresponds + * to the published summary. + */ + g_debug ("Deleting existing unmatched summary.sig file"); + (void) ot_ensure_unlinked_at (self->repo_dir_fd, "summary.sig", NULL); + + return glnx_prefix_error (error, "Unable to rename summary signature file: "); + } + } + else + { + g_debug ("Deleting existing unmatched summary.sig file"); + if (!ot_ensure_unlinked_at (self->repo_dir_fd, "summary.sig", error)) + return glnx_prefix_error (error, "Unable to delete summary signature file: "); + } + return TRUE; } |