]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/test-journal-verify.c
remove unused includes
[thirdparty/systemd.git] / src / journal / test-journal-verify.c
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"
28 #include "journal-file.h"
29 #include "journal-verify.h"
30
31 #define N_ENTRIES 6000
32 #define RANDOM_RANGE 77
33
34 static void bit_toggle(const char *fn, uint64_t p) {
35 uint8_t b;
36 ssize_t r;
37 int fd;
38
39 fd = open(fn, O_RDWR|O_CLOEXEC);
40 assert_se(fd >= 0);
41
42 r = pread(fd, &b, 1, p/8);
43 assert_se(r == 1);
44
45 b ^= 1 << (p % 8);
46
47 r = pwrite(fd, &b, 1, p/8);
48 assert_se(r == 1);
49
50 safe_close(fd);
51 }
52
53 static int raw_verify(const char *fn, const char *verification_key) {
54 JournalFile *f;
55 int r;
56
57 r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f);
58 if (r < 0)
59 return r;
60
61 r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
62 journal_file_close(f);
63
64 return r;
65 }
66
67 int main(int argc, char *argv[]) {
68 char t[] = "/tmp/journal-XXXXXX";
69 unsigned n;
70 JournalFile *f;
71 const char *verification_key = argv[1];
72 usec_t from = 0, to = 0, total = 0;
73 char a[FORMAT_TIMESTAMP_MAX];
74 char b[FORMAT_TIMESTAMP_MAX];
75 char c[FORMAT_TIMESPAN_MAX];
76 struct stat st;
77 uint64_t p;
78
79 /* journal_file_open requires a valid machine id */
80 if (access("/etc/machine-id", F_OK) != 0)
81 return EXIT_TEST_SKIP;
82
83 log_set_max_level(LOG_DEBUG);
84
85 assert_se(mkdtemp(t));
86 assert_se(chdir(t) >= 0);
87
88 log_info("Generating...");
89
90 assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
91
92 for (n = 0; n < N_ENTRIES; n++) {
93 struct iovec iovec;
94 struct dual_timestamp ts;
95 char *test;
96
97 dual_timestamp_get(&ts);
98
99 assert_se(asprintf(&test, "RANDOM=%lu", random() % RANDOM_RANGE));
100
101 iovec.iov_base = (void*) test;
102 iovec.iov_len = strlen(test);
103
104 assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
105
106 free(test);
107 }
108
109 journal_file_close(f);
110
111 log_info("Verifying...");
112
113 assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
114 /* journal_file_print_header(f); */
115 journal_file_dump(f);
116
117 assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0);
118
119 if (verification_key && JOURNAL_HEADER_SEALED(f->header)) {
120 log_info("=> Validated from %s to %s, %s missing",
121 format_timestamp(a, sizeof(a), from),
122 format_timestamp(b, sizeof(b), to),
123 format_timespan(c, sizeof(c), total > to ? total - to : 0, 0));
124 }
125
126 journal_file_close(f);
127
128 if (verification_key) {
129 log_info("Toggling bits...");
130
131 assert_se(stat("test.journal", &st) >= 0);
132
133 for (p = 38448*8+0; p < ((uint64_t) st.st_size * 8); p ++) {
134 bit_toggle("test.journal", p);
135
136 log_info("[ %"PRIu64"+%"PRIu64"]", p / 8, p % 8);
137
138 if (raw_verify("test.journal", verification_key) >= 0)
139 log_notice(ANSI_HIGHLIGHT_RED_ON ">>>> %"PRIu64" (bit %"PRIu64") can be toggled without detection." ANSI_HIGHLIGHT_OFF, p / 8, p % 8);
140
141 bit_toggle("test.journal", p);
142 }
143 }
144
145 log_info("Exiting...");
146
147 assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
148
149 return 0;
150 }