]> git.ipfire.org Git - pakfire.git/commitdiff
repo: Sign the repository metadata instead of the database
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 1 Feb 2025 16:18:24 +0000 (16:18 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 1 Feb 2025 16:18:24 +0000 (16:18 +0000)
I don't think that there is any chance that we will be able to get rid
of the JSON object.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/repo.c

index aa19f84c94ee6145dc3a148b118e6892ae5940da..58141da4a9917a34a49bc3ac129a9f45d70baa2f 100644 (file)
@@ -1964,59 +1964,15 @@ int pakfire_repo_refresh(struct pakfire_repo* repo, int force) {
        return 0;
 }
 
-static int pakfire_repo_sign_database(struct pakfire_repo* repo, struct pakfire_key* key,
-               const char* database_path) {
-       char signature_path[PATH_MAX];
-       FILE* f = NULL;
-       FILE* s = NULL;
-       int r;
-
-       // Compose the signature path
-       r = pakfire_string_format(signature_path, "%s.sig", database_path);
-       if (r)
-               return r;
-
-       // Open the signature file for writing
-       s = fopen(signature_path, "w");
-       if (!s) {
-               ERROR(repo->ctx, "Could not open %s for writing: %m\n", signature_path);
-               r = 1;
-               goto ERROR;
-       }
-
-       // Open the database for reading
-       f = fopen(database_path, "r");
-       if (!f) {
-               ERROR(repo->ctx, "Could not open %s for reading: %m\n", database_path);
-               r = 1;
-               goto ERROR;
-       }
-
-       // Create the signature
-       r = pakfire_key_sign(key, s, f, "Database Signature");
-       if (r) {
-               ERROR(repo->ctx, "Could not sign the database: %m\n");
-               goto ERROR;
-       }
-
-ERROR:
-       if (f)
-               fclose(f);
-       if (s)
-               fclose(s);
-
-       return r;
-}
-
-static int pakfire_repo_write_database(struct pakfire_repo* repo, struct pakfire_key* key,
-               const char* path, char* filename, size_t length) {
+static int pakfire_repo_write_database(
+               struct pakfire_repo* repo, char* filename, size_t length) {
        char database[PATH_MAX];
        char tmp[PATH_MAX];
        int r;
 
        // Create path for a temporary database export file
-       r = pakfire_string_format(tmp, "%s/repodata/.pakfire-solv.XXXXXX", path);
-       if (r)
+       r = pakfire_repo_path(repo, tmp, "%s", "repodata/.pakfire-solv.XXXXXX");
+       if (r < 0)
                return r;
 
        // Create a temporary file to write to
@@ -2052,28 +2008,20 @@ static int pakfire_repo_write_database(struct pakfire_repo* repo, struct pakfire
        }
 
        // Make final database path
-       r = pakfire_string_format(database, "%s/repodata/%s", path, filename);
-       if (r) {
+       r = pakfire_repo_path(repo, database, "repodata/%s", filename);
+       if (r < 0) {
                ERROR(repo->ctx, "Could not join database path: %m\n");
                goto ERROR;
        }
 
        // Link database to its destination
        r = link(tmp, database);
-       if (r) {
+       if (r < 0) {
                ERROR(repo->ctx, "Could not link database %s: %m\n", database);
+               r = -errno;
                goto ERROR;
        }
 
-       // Sign the database
-       if (key) {
-               r = pakfire_repo_sign_database(repo, key, database);
-               if (r) {
-                       ERROR(repo->ctx, "Could not sign the database: %m\n");
-                       goto ERROR;
-               }
-       }
-
 ERROR:
        if (f)
                fclose(f);
@@ -2084,33 +2032,38 @@ ERROR:
        return r;
 }
 
-int pakfire_repo_write_metadata(struct pakfire_repo* repo, struct pakfire_key* key) {
+int pakfire_repo_write_metadata(struct pakfire_repo* self, struct pakfire_key* key) {
        struct json_object* repomd = NULL;
+       char repomd_path[PATH_MAX];
+       char sigpath[PATH_MAX];
+       char database[PATH_MAX];
        FILE* f = NULL;
+       FILE* s = NULL;
        int r = 1;
 
        // This can only be called for local repositories
-       if (!pakfire_repo_is_local(repo)) {
-               errno = ENOTSUP;
-               return 1;
-       }
+       if (!pakfire_repo_is_local(self))
+               return -ENOTSUP;
 
-       // Fetch the base path
-       const char* path = pakfire_repo_get_path(repo);
-       if (!path)
-               return 1;
+       // Make path to repomd.json
+       r = pakfire_repo_path(self, repomd_path, "%s", "repodata/repomd.json");
+       if (r < 0)
+               goto ERROR;
 
-       char database[PATH_MAX];
+       // Make the signature path
+       r = pakfire_string_format(sigpath, "%s.sig", repomd_path);
+       if (r < 0)
+               goto ERROR;
 
        // Write the database
-       r = pakfire_repo_write_database(repo, key, path, database, sizeof(database));
-       if (r)
-               return r;
+       r = pakfire_repo_write_database(self, database, sizeof(database));
+       if (r < 0)
+               goto ERROR;
 
        // Compose JSON object
        repomd = json_object_new_object();
        if (!repomd) {
-               ERROR(repo->ctx, "Could not allocate a new JSON object: %m\n");
+               ERROR(self->ctx, "Could not allocate a new JSON object: %m\n");
                r = 1;
                goto ERROR;
        }
@@ -2118,14 +2071,14 @@ int pakfire_repo_write_metadata(struct pakfire_repo* repo, struct pakfire_key* k
        // Set version
        struct json_object* repomd_version = json_object_new_int64(0);
        if (!repomd_version) {
-               ERROR(repo->ctx, "Could not create version: %m\n");
+               ERROR(self->ctx, "Could not create version: %m\n");
                r = 1;
                goto ERROR;
        }
 
        r = json_object_object_add(repomd, "version", repomd_version);
        if (r) {
-               ERROR(repo->ctx, "Could not add version to repomd.json: %m\n");
+               ERROR(self->ctx, "Could not add version to repomd.json: %m\n");
                goto ERROR;
        }
 
@@ -2134,61 +2087,73 @@ int pakfire_repo_write_metadata(struct pakfire_repo* repo, struct pakfire_key* k
        // Set revision
        struct json_object* repomd_revision = json_object_new_int64(revision);
        if (!repomd_revision) {
-               ERROR(repo->ctx, "Could not create revision: %m\n");
+               ERROR(self->ctx, "Could not create revision: %m\n");
                r = 1;
                goto ERROR;
        }
 
        r = json_object_object_add(repomd, "revision", repomd_revision);
        if (r) {
-               ERROR(repo->ctx, "Could not add revision to repomd.json: %m\n");
+               ERROR(self->ctx, "Could not add revision to repomd.json: %m\n");
                goto ERROR;
        }
 
        // Set database
        struct json_object* repomd_database = json_object_new_string(database);
        if (!repomd_database) {
-               ERROR(repo->ctx, "Could not create database string: %m\n");
+               ERROR(self->ctx, "Could not create database string: %m\n");
                r = 1;
                goto ERROR;
        }
 
        r = json_object_object_add(repomd, "database", repomd_database);
        if (r) {
-               ERROR(repo->ctx, "Could not add database to repomd.json: %m\n");
+               ERROR(self->ctx, "Could not add database to repomd.json: %m\n");
                goto ERROR;
        }
 
        // XXX database hash is missing
 
-       char repomd_path[PATH_MAX];
-
-       // Make path to repomd.json
-       r = pakfire_string_format(repomd_path, "%s/repodata/repomd.json", path);
-       if (r)
-               goto ERROR;
-
        // Open repomd.json for writing
-       f = fopen(repomd_path, "w");
+       f = fopen(repomd_path, "w+");
        if (!f) {
-               ERROR(repo->ctx, "Could not open %s for writing: %m\n", repomd_path);
-               r = 1;
+               ERROR(self->ctx, "Could not open %s for writing: %m\n", repomd_path);
+               r = -errno;
                goto ERROR;
        }
 
        // Write out repomd.json
        r = json_object_to_fd(fileno(f), repomd, JSON_C_TO_STRING_PRETTY);
        if (r) {
-               ERROR(repo->ctx, "Could not write repomd.json: %m\n");
+               ERROR(self->ctx, "Could not write repomd.json: %m\n");
                goto ERROR;
        }
 
+       // Open the signature path for writing
+       s = fopen(sigpath, "w");
+       if (!s) {
+               ERROR(self->ctx, "Could not open %s for writing: %m\n", sigpath);
+               r = -errno;
+               goto ERROR;
+       }
+
+       // Sign the metadata
+       if (key) {
+               r = pakfire_key_sign(key, s, f, NULL);
+               if (r < 0) {
+                       ERROR(self->ctx, "Could not sign the repository: %s\n", strerror(-r));
+                       goto ERROR;
+               }
+       }
+
        // Success
        r = 0;
 
 ERROR:
        if (f)
                fclose(f);
+       if (s)
+               fclose(s);
        json_object_put(repomd);
 
        return r;