From: Michael Tremer Date: Wed, 24 Aug 2022 08:23:19 +0000 (+0000) Subject: file: Store any digests as an extended attribute X-Git-Tag: 0.9.28~386 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=399d14c2f4f5e3c2517a0042bf16c61f6af6b590;p=pakfire.git file: Store any digests as an extended attribute Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/db.c b/src/libpakfire/db.c index f3b096b64..d7c0f8424 100644 --- a/src/libpakfire/db.c +++ b/src/libpakfire/db.c @@ -2033,17 +2033,8 @@ static int pakfire_db_load_file_digest(struct pakfire_db* db, struct pakfire_fil // Length of the stored value const size_t length = sqlite3_column_bytes(stmt, field); - // Check if the digest has the correct length - if (pakfire_digest_length(type) != length) { - const char* path = pakfire_file_get_path(file); - - ERROR(db->pakfire, "%s: Digest has an incorrect size of %zu byte(s)\n", - path, length); - return 1; - } - // Store digest - return pakfire_file_set_digest(file, type, digest); + return pakfire_file_set_digest(file, type, digest, length); } static int pakfire_db_load_file(struct pakfire_db* db, struct pakfire_filelist* filelist, diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index b4cea79a7..a46e0a380 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -92,6 +92,20 @@ struct pakfire_file { //int is_datafile; }; +/* + Returns one if the digest is not all zeros. +*/ +#define pakfire_file_has_digest(digest) __pakfire_file_has_digest(digest, sizeof(digest)) + +static int __pakfire_file_has_digest(const unsigned char* digest, const size_t length) { + for (unsigned int i = 0; i < length; i++) { + if (digest[i]) + return 1; + } + + return 0; +} + PAKFIRE_EXPORT int pakfire_file_create(struct pakfire_file** file, struct pakfire* pakfire) { struct pakfire_file* f = calloc(1, sizeof(*f)); if (!f) @@ -127,16 +141,10 @@ ERROR: return r; } -static const struct pakfire_libarchive_digest { - enum pakfire_digests pakfire; - int libarchive; -} pakfire_libarchive_digests[] = { - { PAKFIRE_DIGEST_SHA512, ARCHIVE_ENTRY_DIGEST_SHA512 }, - { PAKFIRE_DIGEST_SHA256, ARCHIVE_ENTRY_DIGEST_SHA256 }, - { 0, 0 }, -}; - int pakfire_file_copy_archive_entry(struct pakfire_file* file, struct archive_entry* entry) { + const char* attr = NULL; + const void* value = NULL; + size_t size = 0; int r = 0; // Set abspath @@ -176,17 +184,26 @@ int pakfire_file_copy_archive_entry(struct pakfire_file* file, struct archive_en pakfire_file_set_ctime(file, archive_entry_ctime(entry)); pakfire_file_set_mtime(file, archive_entry_mtime(entry)); - // Copy digest - for (const struct pakfire_libarchive_digest* type = pakfire_libarchive_digests; - type->pakfire; type++) { - const unsigned char* digest = archive_entry_digest(entry, type->libarchive); - if (digest) { - r = pakfire_file_set_digest(file, type->pakfire, digest); + // Read any extended attributes + while (archive_entry_xattr_next(entry, &attr, &value, &size) == ARCHIVE_OK) { + // Digest: SHA-512 + if (strcmp(attr, "PAKFIRE.digests.sha512") == 0) { + r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_SHA512, value, size); + if (r) + goto ERROR; + + // Digest: SHA-256 + } else if (strcmp(attr, "PAKFIRE.digests.sha256") == 0) { + r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_SHA256, value, size); if (r) - return r; + goto ERROR; + + } else { + DEBUG(file->pakfire, "Received an unknown extended attribute: %s\n", attr); } } +ERROR: return r; } @@ -225,7 +242,17 @@ struct archive_entry* pakfire_file_archive_entry(struct pakfire_file* file) { archive_entry_set_ctime(entry, pakfire_file_get_ctime(file), 0); archive_entry_set_mtime(entry, pakfire_file_get_mtime(file), 0); - // XXX copy digest + // Copy digests + + // SHA-512 + if (pakfire_file_has_digest(file->digests.sha512)) + archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.sha512", + file->digests.sha512, sizeof(file->digests.sha512)); + + // SHA-256 + if (pakfire_file_has_digest(file->digests.sha256)) + archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.sha256", + file->digests.sha256, sizeof(file->digests.sha256)); return entry; } @@ -398,20 +425,6 @@ PAKFIRE_EXPORT void pakfire_file_set_mtime(struct pakfire_file* file, time_t tim file->st.st_mtime = time; } -/* - Returns one if the digest is not all zeros. -*/ -#define pakfire_file_has_digest(digest) __pakfire_file_has_digest(digest, sizeof(digest)) - -static int __pakfire_file_has_digest(const unsigned char* digest, const size_t length) { - for (unsigned int i = 0; i < length; i++) { - if (digest[i]) - return 1; - } - - return 0; -} - PAKFIRE_EXPORT const unsigned char* pakfire_file_get_digest( struct pakfire_file* file, const enum pakfire_digests type, size_t* length) { @@ -439,12 +452,20 @@ PAKFIRE_EXPORT const unsigned char* pakfire_file_get_digest( } PAKFIRE_EXPORT int pakfire_file_set_digest(struct pakfire_file* file, - const enum pakfire_digests type, const unsigned char* digest) { + const enum pakfire_digests type, const unsigned char* digest, const size_t length) { if (!digest) { errno = EINVAL; return 1; } + // Check buffer length + if (pakfire_digest_length(type) != length) { + ERROR(file->pakfire, "Digest has an incorrect length of %zu byte(s)\n", length); + errno = ENOMSG; + return 1; + } + + // Store the digest switch (type) { case PAKFIRE_DIGEST_SHA512: memcpy(file->digests.sha512, digest, sizeof(file->digests.sha512)); diff --git a/src/libpakfire/include/pakfire/file.h b/src/libpakfire/include/pakfire/file.h index 6ea3250bb..1df7d3727 100644 --- a/src/libpakfire/include/pakfire/file.h +++ b/src/libpakfire/include/pakfire/file.h @@ -74,7 +74,7 @@ const unsigned char* pakfire_file_get_digest(struct pakfire_file* file, char* pakfire_file_get_hexdigest(struct pakfire_file* file, const enum pakfire_digests type); int pakfire_file_set_digest(struct pakfire_file* file, - const enum pakfire_digests type, const unsigned char* digest); + const enum pakfire_digests type, const unsigned char* digest, const size_t length); struct pakfire_file* pakfire_file_parse_from_file(const char* list, unsigned int format);