]> git.ipfire.org Git - pakfire.git/commitdiff
file: Perform some basic verification tasks
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 19 Aug 2022 14:27:14 +0000 (14:27 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 19 Aug 2022 14:27:14 +0000 (14:27 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/file.c
src/libpakfire/filelist.c
src/libpakfire/include/pakfire/file.h

index 63b0d817db06c9644738eeeb904204ecccbff596..18b2663478cbd470afbc2b7b1492715ea24c1d29 100644 (file)
 #include <pakfire/string.h>
 #include <pakfire/util.h>
 
+enum pakfire_file_verification_status {
+       PAKFIRE_FILE_NOENT                = (1 << 0),
+       PAKFIRE_FILE_SIZE_DIFFERS         = (1 << 1),
+       PAKFIRE_FILE_OWNER_DIFFERS        = (1 << 2),
+       PAKFIRE_FILE_GROUP_DIFFERS        = (1 << 3),
+};
+
 struct pakfire_file {
        struct pakfire* pakfire;
        int nrefs;
@@ -78,6 +85,9 @@ struct pakfire_file {
                unsigned char sha256[SHA256_DIGEST_LENGTH];
        } digests;
 
+       // Verification Status
+       int verify_status;
+
        #warning TODO capabilities, config, data
        // capabilities
        //int is_configfile;
@@ -528,12 +538,82 @@ int pakfire_file_cleanup(struct pakfire_file* file) {
        return 0;
 }
 
+static int pakfire_file_verify_size(struct pakfire_file* file, const struct stat* st) {
+       // Nothing to do if size matches
+       if (file->size == st->st_size)
+               return 0;
+
+       // Size differs
+       file->verify_status |= PAKFIRE_FILE_SIZE_DIFFERS;
+
+       DEBUG(file->pakfire, "%s: Filesize differs (expected %zu, got %zu byte(s))\n",
+               file->path, file->size, st->st_size);
+
+       return 0;
+}
+
+static int pakfire_file_verify_ownership(struct pakfire_file* file, const struct stat* st) {
+       // Fetch UID/GID
+#if 0
+       const uid_t uid = pakfire_unmap_id(file->pakfire, st->st_uid);
+       const gid_t gid = pakfire_unmap_id(file->pakfire, st->st_gid);
+#else
+       const uid_t uid = st->st_uid;
+       const gid_t gid = st->st_gid;
+#endif
+
+       // Fetch owner & group
+       struct passwd* owner = pakfire_getpwnam(file->pakfire, file->user);
+       struct group*  group = pakfire_getgrnam(file->pakfire, file->group);
+
+       // Check if owner matches
+       if (!owner || owner->pw_uid != uid) {
+               file->verify_status |= PAKFIRE_FILE_OWNER_DIFFERS;
+
+               DEBUG(file->pakfire, "%s: Owner differs\n", file->path);
+       }
+
+       // Check if group matches
+       if (!group || group->gr_gid != gid) {
+               file->verify_status |= PAKFIRE_FILE_GROUP_DIFFERS;
+
+               DEBUG(file->pakfire, "%s: Group differs\n", file->path);
+       }
+
+       return 0;
+}
+
 /*
        Verify the file - i.e. does the metadata match what is on disk?
 */
-int pakfire_file_verify(struct pakfire_file* file) {
+int pakfire_file_verify(struct pakfire_file* file, int* status) {
+       struct stat st;
+       int r;
+
        DEBUG(file->pakfire, "Verifying %s...\n", file->path);
 
-       // XXX TODO
+       // stat() the file
+       r = lstat(file->abspath, &st);
+       if (r) {
+               // File does not exist
+               if (errno == ENOENT) {
+                       file->verify_status |= PAKFIRE_FILE_NOENT;
+                       return 1;
+               }
+
+               // Raise any other errors from stat()
+               return r;
+       }
+
+       // Verify size
+       r = pakfire_file_verify_size(file, &st);
+       if (r)
+               return r;
+
+       // Verify ownership
+       r = pakfire_file_verify_ownership(file, &st);
+       if (r)
+               return r;
+
        return 0;
 }
index d0f3dcfdde7c290106cc99574ddbed4dc158aa30..48145e7f6462fdccb388bc7745a71902a069b21b 100644 (file)
@@ -526,6 +526,7 @@ int pakfire_filelist_export(struct pakfire_filelist* list, FILE* f) {
 int pakfire_filelist_verify(struct pakfire_filelist* list, struct pakfire_filelist* errors) {
        struct pakfire_progressbar* progressbar = NULL;
        struct pakfire_file* file = NULL;
+       int status;
        int r;
 
        DEBUG(list->pakfire, "Verifying filelist (%zu file(s))...\n", list->size);
@@ -565,8 +566,12 @@ int pakfire_filelist_verify(struct pakfire_filelist* list, struct pakfire_fileli
                file = list->elements[i];
 
                // Verify the file
-               r = pakfire_file_verify(file);
-               if (r) {
+               r = pakfire_file_verify(file, &status);
+               if (r)
+                       goto ERROR;
+
+               // If the verification failed, we append it to the errors list
+               if (status) {
                        // Append the file to the error list
                        r = pakfire_filelist_append(errors, file);
                        if (r)
index 033d816b20a5015ec084c08cd007d42f8282a770..61b144a1944760b45f776ae5af0b400ba1492db5 100644 (file)
@@ -91,7 +91,7 @@ FILE* pakfire_file_open(struct pakfire_file* file);
 int pakfire_file_remove(struct pakfire_file* file);
 int pakfire_file_cleanup(struct pakfire_file* file);
 
-int pakfire_file_verify(struct pakfire_file* file);
+int pakfire_file_verify(struct pakfire_file* file, int* status);
 
 #endif