]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/test-journal-verify.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
8 #include "journal-file.h"
9 #include "journal-verify.h"
12 #include "terminal-util.h"
16 #define N_ENTRIES 6000
17 #define RANDOM_RANGE 77
19 static void bit_toggle(const char *fn
, uint64_t p
) {
24 fd
= open(fn
, O_RDWR
|O_CLOEXEC
);
27 r
= pread(fd
, &b
, 1, p
/8);
32 r
= pwrite(fd
, &b
, 1, p
/8);
38 static int raw_verify(const char *fn
, const char *verification_key
) {
42 r
= journal_file_open(-1, fn
, O_RDONLY
, 0666, true, (uint64_t) -1, !!verification_key
, NULL
, NULL
, NULL
, NULL
, &f
);
46 r
= journal_file_verify(f
, verification_key
, NULL
, NULL
, NULL
, false);
47 (void) journal_file_close(f
);
52 int main(int argc
, char *argv
[]) {
53 char t
[] = "/tmp/journal-XXXXXX";
56 const char *verification_key
= argv
[1];
57 usec_t from
= 0, to
= 0, total
= 0;
58 char a
[FORMAT_TIMESTAMP_MAX
];
59 char b
[FORMAT_TIMESTAMP_MAX
];
60 char c
[FORMAT_TIMESPAN_MAX
];
64 /* journal_file_open requires a valid machine id */
65 if (access("/etc/machine-id", F_OK
) != 0)
66 return log_tests_skipped("/etc/machine-id not found");
68 test_setup_logging(LOG_DEBUG
);
70 assert_se(mkdtemp(t
));
71 assert_se(chdir(t
) >= 0);
73 log_info("Generating...");
75 assert_se(journal_file_open(-1, "test.journal", O_RDWR
|O_CREAT
, 0666, true, (uint64_t) -1, !!verification_key
, NULL
, NULL
, NULL
, NULL
, &f
) == 0);
77 for (n
= 0; n
< N_ENTRIES
; n
++) {
79 struct dual_timestamp ts
;
82 dual_timestamp_get(&ts
);
84 assert_se(asprintf(&test
, "RANDOM=%lu", random() % RANDOM_RANGE
));
86 iovec
.iov_base
= (void*) test
;
87 iovec
.iov_len
= strlen(test
);
89 assert_se(journal_file_append_entry(f
, &ts
, NULL
, &iovec
, 1, NULL
, NULL
, NULL
) == 0);
94 (void) journal_file_close(f
);
96 log_info("Verifying...");
98 assert_se(journal_file_open(-1, "test.journal", O_RDONLY
, 0666, true, (uint64_t) -1, !!verification_key
, NULL
, NULL
, NULL
, NULL
, &f
) == 0);
99 /* journal_file_print_header(f); */
100 journal_file_dump(f
);
102 assert_se(journal_file_verify(f
, verification_key
, &from
, &to
, &total
, true) >= 0);
104 if (verification_key
&& JOURNAL_HEADER_SEALED(f
->header
))
105 log_info("=> Validated from %s to %s, %s missing",
106 format_timestamp(a
, sizeof(a
), from
),
107 format_timestamp(b
, sizeof(b
), to
),
108 format_timespan(c
, sizeof(c
), total
> to
? total
- to
: 0, 0));
110 (void) journal_file_close(f
);
112 if (verification_key
) {
113 log_info("Toggling bits...");
115 assert_se(stat("test.journal", &st
) >= 0);
117 for (p
= 38448*8+0; p
< ((uint64_t) st
.st_size
* 8); p
++) {
118 bit_toggle("test.journal", p
);
120 log_info("[ %"PRIu64
"+%"PRIu64
"]", p
/ 8, p
% 8);
122 if (raw_verify("test.journal", verification_key
) >= 0)
123 log_notice(ANSI_HIGHLIGHT_RED
">>>> %"PRIu64
" (bit %"PRIu64
") can be toggled without detection." ANSI_NORMAL
, p
/ 8, p
% 8);
125 bit_toggle("test.journal", p
);
129 log_info("Exiting...");
131 assert_se(rm_rf(t
, REMOVE_ROOT
|REMOVE_PHYSICAL
) >= 0);