]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/test-journal-verify.c
tree-wide: drop {} from one-line if blocks
[thirdparty/systemd.git] / src / journal / test-journal-verify.c
CommitLineData
0284adc6
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2012 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdio.h>
23#include <unistd.h>
24#include <fcntl.h>
25
26#include "util.h"
27#include "log.h"
c6878637 28#include "rm-rf.h"
0284adc6
LP
29#include "journal-file.h"
30#include "journal-verify.h"
288a74cc 31#include "terminal-util.h"
0284adc6
LP
32
33#define N_ENTRIES 6000
34#define RANDOM_RANGE 77
35
b72631e5
LP
36static void bit_toggle(const char *fn, uint64_t p) {
37 uint8_t b;
38 ssize_t r;
39 int fd;
40
41 fd = open(fn, O_RDWR|O_CLOEXEC);
787784c4 42 assert_se(fd >= 0);
b72631e5
LP
43
44 r = pread(fd, &b, 1, p/8);
787784c4 45 assert_se(r == 1);
b72631e5
LP
46
47 b ^= 1 << (p % 8);
48
49 r = pwrite(fd, &b, 1, p/8);
787784c4 50 assert_se(r == 1);
b72631e5 51
03e334a1 52 safe_close(fd);
b72631e5
LP
53}
54
55static int raw_verify(const char *fn, const char *verification_key) {
56 JournalFile *f;
57 int r;
58
feb12d3e 59 r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f);
b72631e5
LP
60 if (r < 0)
61 return r;
62
63 r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
64 journal_file_close(f);
65
66 return r;
67}
68
0284adc6
LP
69int main(int argc, char *argv[]) {
70 char t[] = "/tmp/journal-XXXXXX";
71 unsigned n;
72 JournalFile *f;
14d10188 73 const char *verification_key = argv[1];
b72631e5 74 usec_t from = 0, to = 0, total = 0;
6c7be122
LP
75 char a[FORMAT_TIMESTAMP_MAX];
76 char b[FORMAT_TIMESTAMP_MAX];
77 char c[FORMAT_TIMESPAN_MAX];
b72631e5
LP
78 struct stat st;
79 uint64_t p;
0284adc6 80
143bfdaf
HHPF
81 /* journal_file_open requires a valid machine id */
82 if (access("/etc/machine-id", F_OK) != 0)
83 return EXIT_TEST_SKIP;
84
0284adc6
LP
85 log_set_max_level(LOG_DEBUG);
86
87 assert_se(mkdtemp(t));
88 assert_se(chdir(t) >= 0);
89
90 log_info("Generating...");
91
14d10188 92 assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
0284adc6
LP
93
94 for (n = 0; n < N_ENTRIES; n++) {
95 struct iovec iovec;
96 struct dual_timestamp ts;
97 char *test;
98
99 dual_timestamp_get(&ts);
100
101 assert_se(asprintf(&test, "RANDOM=%lu", random() % RANDOM_RANGE));
102
103 iovec.iov_base = (void*) test;
104 iovec.iov_len = strlen(test);
105
106 assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
107
108 free(test);
109 }
110
111 journal_file_close(f);
112
113 log_info("Verifying...");
114
feb12d3e 115 assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
f7fab8a5
LP
116 /* journal_file_print_header(f); */
117 journal_file_dump(f);
3223f44f 118
b72631e5 119 assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0);
6c7be122 120
ece174c5 121 if (verification_key && JOURNAL_HEADER_SEALED(f->header))
b72631e5
LP
122 log_info("=> Validated from %s to %s, %s missing",
123 format_timestamp(a, sizeof(a), from),
124 format_timestamp(b, sizeof(b), to),
2fa4092c 125 format_timespan(c, sizeof(c), total > to ? total - to : 0, 0));
feb12d3e 126
0284adc6
LP
127 journal_file_close(f);
128
f7fab8a5
LP
129 if (verification_key) {
130 log_info("Toggling bits...");
b72631e5 131
f7fab8a5 132 assert_se(stat("test.journal", &st) >= 0);
b72631e5 133
f7fab8a5
LP
134 for (p = 38448*8+0; p < ((uint64_t) st.st_size * 8); p ++) {
135 bit_toggle("test.journal", p);
b72631e5 136
507f22bd 137 log_info("[ %"PRIu64"+%"PRIu64"]", p / 8, p % 8);
b72631e5 138
f7fab8a5 139 if (raw_verify("test.journal", verification_key) >= 0)
507f22bd 140 log_notice(ANSI_HIGHLIGHT_RED_ON ">>>> %"PRIu64" (bit %"PRIu64") can be toggled without detection." ANSI_HIGHLIGHT_OFF, p / 8, p % 8);
b72631e5 141
f7fab8a5
LP
142 bit_toggle("test.journal", p);
143 }
b72631e5
LP
144 }
145
0284adc6
LP
146 log_info("Exiting...");
147
c6878637 148 assert_se(rm_rf(t, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
0284adc6
LP
149
150 return 0;
151}