From: Michael Tremer Date: Sun, 2 Feb 2025 16:36:50 +0000 (+0000) Subject: repo: Load metadata into memory and verify it X-Git-Tag: 0.9.30~174 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=af0c2db14dbb716844a429071d7ab494a25cc854;p=pakfire.git repo: Load metadata into memory and verify it Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/repo.c b/src/pakfire/repo.c index 019a2d13..2be82477 100644 --- a/src/pakfire/repo.c +++ b/src/pakfire/repo.c @@ -759,7 +759,60 @@ ERROR: return r; } +static int pakfire_repo_verify_metadata( + struct pakfire_repo* self, const struct pakfire_buffer* repomd) { + struct pakfire_buffer signature = {}; + struct pakfire_xfer* xfer = NULL; + FILE* f = NULL; + int r; + + // Create a new xfer + r = pakfire_repo_xfer_create(&xfer, self, "repomd.json.sig"); + if (r < 0) + goto ERROR; + + // Write the signature to a buffer + r = pakfire_xfer_set_output_buffer(xfer, &signature.data, &signature.length); + if (r < 0) + goto ERROR; + + // Perform the transfer + r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS); + if (r < 0) + goto ERROR; + + // Fail if we could not fetch any data + if (!signature.data) { + ERROR(self->ctx, "Could not fetch repository signature\n"); + r = -ENODATA; + goto ERROR; + } + + // Map the signature in a file handle + f = fmemopen(signature.data, signature.length, "r"); + if (!f) { + r = -errno; + goto ERROR; + } + + // Verify the downloaded metadata + r = pakfire_key_verify(self->appdata->key, f, repomd->data, repomd->length); + if (r < 0) + goto ERROR; + +ERROR: + if (xfer) + pakfire_xfer_unref(xfer); + if (f) + fclose(f); + if (signature.data) + free(signature.data); + + return r; +} + static int pakfire_repo_download_metadata(struct pakfire_repo* repo, const char* path, int force) { + struct pakfire_buffer repomd = {}; struct pakfire_xfer* xfer = NULL; int r; @@ -793,23 +846,32 @@ static int pakfire_repo_download_metadata(struct pakfire_repo* repo, const char* } // Create a new transfer - r = pakfire_repo_xfer_create(&xfer, repo, "repodata/repomd.json"); - if (r) + r = pakfire_repo_xfer_create(&xfer, repo, "repomd.json"); + if (r < 0) goto ERROR; // Set the output path - r = pakfire_xfer_set_output_path(xfer, path); - if (r) + r = pakfire_xfer_set_output_buffer(xfer, &repomd.data, &repomd.length); + if (r < 0) goto ERROR; // Perform the transfer r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS); - if (r) + if (r < 0) goto ERROR; + // Verify the downloaded data + if (repo->appdata->key) { + r = pakfire_repo_verify_metadata(repo, &repomd); + if (r < 0) + goto ERROR; + } + ERROR: if (xfer) pakfire_xfer_unref(xfer); + if (repomd.data) + free(repomd.data); return r; }