]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/journal/journal-verify.c
journal: add color to verification progress bar
[thirdparty/systemd.git] / src / journal / journal-verify.c
index f3182e876ea1bfef14bd732626cce9d2b25966e8..1a9a73092e4e21404012c6812131af78bdcd1f30 100644 (file)
 #include "journal-file.h"
 #include "journal-authenticate.h"
 #include "journal-verify.h"
+#include "lookup3.h"
+#include "compress.h"
+
+/* FIXME:
+ *
+ * - follow all chains
+ * - check for unreferenced objects
+ * - verify FSPRG
+ * - Allow building without libgcrypt
+ *
+ * */
 
 static int journal_file_object_verify(JournalFile *f, Object *o) {
         assert(f);
@@ -38,15 +49,43 @@ static int journal_file_object_verify(JournalFile *f, Object *o) {
          * possible field values. It does not follow any references to
          * other objects. */
 
+        if ((o->object.flags & OBJECT_COMPRESSED) &&
+            o->object.type != OBJECT_DATA)
+                return -EBADMSG;
+
         switch (o->object.type) {
-        case OBJECT_DATA:
+
+        case OBJECT_DATA: {
+                uint64_t h1, h2;
+
                 if (le64toh(o->data.entry_offset) <= 0 ||
                     le64toh(o->data.n_entries) <= 0)
                         return -EBADMSG;
 
                 if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0)
                         return -EBADMSG;
+
+                h1 = le64toh(o->data.hash);
+
+                if (o->object.flags & OBJECT_COMPRESSED) {
+                        void *b = NULL;
+                        uint64_t alloc = 0, b_size;
+
+                        if (!uncompress_blob(o->data.payload,
+                                             le64toh(o->object.size) - offsetof(Object, data.payload),
+                                             &b, &alloc, &b_size))
+                                return -EBADMSG;
+
+                        h2 = hash64(b, b_size);
+                        free(b);
+                } else
+                        h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload));
+
+                if (h1 != h2)
+                        return -EBADMSG;
+
                 break;
+        }
 
         case OBJECT_FIELD:
                 if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0)
@@ -107,11 +146,13 @@ static void draw_progress(uint64_t p, usec_t *last_usec) {
         j = (n * (unsigned) p) / 65535ULL;
         k = n - j;
 
-        fputs("\r\x1B[?25l", stdout);
+        fputs("\r\x1B[?25l" ANSI_HIGHLIGHT_GREEN_ON, stdout);
 
         for (i = 0; i < j; i++)
                 fputs("\xe2\x96\x88", stdout);
 
+        fputs(ANSI_HIGHLIGHT_OFF, stdout);
+
         for (i = 0; i < k; i++)
                 fputs("\xe2\x96\x91", stdout);
 
@@ -251,12 +292,6 @@ int journal_file_verify(JournalFile *f, const char *key) {
                         goto fail;
                 }
 
-                r = journal_file_hmac_put_object(f, -1, p);
-                if (r < 0) {
-                        log_error("Failed to calculate HMAC at %llu", (unsigned long long) p);
-                        goto fail;
-                }
-
                 if (o->object.flags & OBJECT_COMPRESSED &&
                     !(le32toh(f->header->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED)) {
                         log_error("Compressed object without compression at %llu", (unsigned long long) p);
@@ -264,10 +299,9 @@ int journal_file_verify(JournalFile *f, const char *key) {
                         goto fail;
                 }
 
-                if (o->object.flags & OBJECT_COMPRESSED &&
-                    o->object.type != OBJECT_DATA) {
-                        log_error("Compressed non-data object at %llu", (unsigned long long) p);
-                        r = -EBADMSG;
+                r = journal_file_hmac_put_object(f, -1, p);
+                if (r < 0) {
+                        log_error("Failed to calculate HMAC at %llu", (unsigned long long) p);
                         goto fail;
                 }