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;
}
// 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;
}