]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/test-journal-verify.c
util: rework rm_rf() logic
[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"
31
32#define N_ENTRIES 6000
33#define RANDOM_RANGE 77
34
b72631e5
LP
35static void bit_toggle(const char *fn, uint64_t p) {
36 uint8_t b;
37 ssize_t r;
38 int fd;
39
40 fd = open(fn, O_RDWR|O_CLOEXEC);
787784c4 41 assert_se(fd >= 0);
b72631e5
LP
42
43 r = pread(fd, &b, 1, p/8);
787784c4 44 assert_se(r == 1);
b72631e5
LP
45
46 b ^= 1 << (p % 8);
47
48 r = pwrite(fd, &b, 1, p/8);
787784c4 49 assert_se(r == 1);
b72631e5 50
03e334a1 51 safe_close(fd);
b72631e5
LP
52}
53
54static int raw_verify(const char *fn, const char *verification_key) {
55 JournalFile *f;
56 int r;
57
feb12d3e 58 r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f);
b72631e5
LP
59 if (r < 0)
60 return r;
61
62 r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
63 journal_file_close(f);
64
65 return r;
66}
67
0284adc6
LP
68int main(int argc, char *argv[]) {
69 char t[] = "/tmp/journal-XXXXXX";
70 unsigned n;
71 JournalFile *f;
14d10188 72 const char *verification_key = argv[1];
b72631e5 73 usec_t from = 0, to = 0, total = 0;
6c7be122
LP
74 char a[FORMAT_TIMESTAMP_MAX];
75 char b[FORMAT_TIMESTAMP_MAX];
76 char c[FORMAT_TIMESPAN_MAX];
b72631e5
LP
77 struct stat st;
78 uint64_t p;
0284adc6 79
143bfdaf
HHPF
80 /* journal_file_open requires a valid machine id */
81 if (access("/etc/machine-id", F_OK) != 0)
82 return EXIT_TEST_SKIP;
83
0284adc6
LP
84 log_set_max_level(LOG_DEBUG);
85
86 assert_se(mkdtemp(t));
87 assert_se(chdir(t) >= 0);
88
89 log_info("Generating...");
90
14d10188 91 assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
0284adc6
LP
92
93 for (n = 0; n < N_ENTRIES; n++) {
94 struct iovec iovec;
95 struct dual_timestamp ts;
96 char *test;
97
98 dual_timestamp_get(&ts);
99
100 assert_se(asprintf(&test, "RANDOM=%lu", random() % RANDOM_RANGE));
101
102 iovec.iov_base = (void*) test;
103 iovec.iov_len = strlen(test);
104
105 assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
106
107 free(test);
108 }
109
110 journal_file_close(f);
111
112 log_info("Verifying...");
113
feb12d3e 114 assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
f7fab8a5
LP
115 /* journal_file_print_header(f); */
116 journal_file_dump(f);
3223f44f 117
b72631e5 118 assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0);
6c7be122 119
feb12d3e 120 if (verification_key && JOURNAL_HEADER_SEALED(f->header)) {
b72631e5
LP
121 log_info("=> Validated from %s to %s, %s missing",
122 format_timestamp(a, sizeof(a), from),
123 format_timestamp(b, sizeof(b), to),
2fa4092c 124 format_timespan(c, sizeof(c), total > to ? total - to : 0, 0));
b72631e5 125 }
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}