1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
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.
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.
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/>.
34 #include <sys/ioctl.h>
42 #include <systemd/sd-journal.h>
45 #include "logs-show.h"
47 #include "path-util.h"
52 #include "journal-internal.h"
53 #include "journal-def.h"
54 #include "journal-verify.h"
55 #include "journal-authenticate.h"
56 #include "journal-qrcode.h"
58 #include "unit-name.h"
61 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
63 static OutputMode arg_output = OUTPUT_SHORT;
64 static bool arg_pager_end = false;
65 static bool arg_follow = false;
66 static bool arg_full = true;
67 static bool arg_all = false;
68 static bool arg_no_pager = false;
69 static int arg_lines = -1;
70 static bool arg_no_tail = false;
71 static bool arg_quiet = false;
72 static bool arg_merge = false;
73 static bool arg_boot = false;
74 static sd_id128_t arg_boot_id = {};
75 static int arg_boot_offset = 0;
76 static bool arg_dmesg = false;
77 static const char *arg_cursor = NULL;
78 static const char *arg_after_cursor = NULL;
79 static bool arg_show_cursor = false;
80 static const char *arg_directory = NULL;
81 static char **arg_file = NULL;
82 static int arg_priorities = 0xFF;
83 static const char *arg_verify_key = NULL;
85 static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
86 static bool arg_force = false;
88 static usec_t arg_since, arg_until;
89 static bool arg_since_set = false, arg_until_set = false;
90 static char **arg_system_units = NULL;
91 static char **arg_user_units = NULL;
92 static const char *arg_field = NULL;
93 static bool arg_catalog = false;
94 static bool arg_reverse = false;
95 static int arg_journal_type = 0;
96 static const char *arg_root = NULL;
97 static const char *arg_machine = NULL;
108 ACTION_UPDATE_CATALOG,
110 } arg_action = ACTION_SHOW;
112 typedef struct boot_id_t {
118 static void pager_open_if_enabled(void) {
123 pager_open(arg_pager_end);
126 static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset) {
127 sd_id128_t id = SD_ID128_NULL;
130 if (strlen(x) >= 32) {
134 r = sd_id128_from_string(t, &id);
138 if (*x != '-' && *x != '+' && *x != 0)
142 r = safe_atoi(x, &off);
147 r = safe_atoi(x, &off);
161 static int help(void) {
163 pager_open_if_enabled();
165 printf("%s [OPTIONS...] [MATCHES...]\n\n"
166 "Query the journal.\n\n"
168 " --system Show only the system journal\n"
169 " --user Show only the user journal for the current user\n"
170 " -M --machine=CONTAINER Operate on local container\n"
171 " --since=DATE Start showing entries on or newer than the specified date\n"
172 " --until=DATE Stop showing entries on or older than the specified date\n"
173 " -c --cursor=CURSOR Start showing entries from the specified cursor\n"
174 " --after-cursor=CURSOR Start showing entries from after the specified cursor\n"
175 " --show-cursor Print the cursor after all the entries\n"
176 " -b --boot[=ID] Show data only from ID or, if unspecified, the current boot\n"
177 " --list-boots Show terse information about recorded boots\n"
178 " -k --dmesg Show kernel message log from the current boot\n"
179 " -u --unit=UNIT Show data only from the specified unit\n"
180 " --user-unit=UNIT Show data only from the specified user session unit\n"
181 " -p --priority=RANGE Show only messages within the specified priority range\n"
182 " -e --pager-end Immediately jump to end of the journal in the pager\n"
183 " -f --follow Follow the journal\n"
184 " -n --lines[=INTEGER] Number of journal entries to show\n"
185 " --no-tail Show all lines, even in follow mode\n"
186 " -r --reverse Show the newest entries first\n"
187 " -o --output=STRING Change journal output mode (short, short-iso,\n"
188 " short-precise, short-monotonic, verbose,\n"
189 " export, json, json-pretty, json-sse, cat)\n"
190 " -x --catalog Add message explanations where available\n"
191 " --no-full Ellipsize fields\n"
192 " -a --all Show all fields, including long and unprintable\n"
193 " -q --quiet Do not show privilege warning\n"
194 " --no-pager Do not pipe output into a pager\n"
195 " -m --merge Show entries from all available journals\n"
196 " -D --directory=PATH Show journal files from directory\n"
197 " --file=PATH Show journal file\n"
198 " --root=ROOT Operate on catalog files underneath the root ROOT\n"
200 " --interval=TIME Time interval for changing the FSS sealing key\n"
201 " --verify-key=KEY Specify FSS verification key\n"
202 " --force Force overriding of the FSS key pair with --setup-keys\n"
205 " -h --help Show this help text\n"
206 " --version Show package version\n"
207 " --new-id128 Generate a new 128-bit ID\n"
208 " --header Show journal header information\n"
209 " --disk-usage Show total disk usage of all journal files\n"
210 " -F --field=FIELD List all values that a specified field takes\n"
211 " --list-catalog Show message IDs of all entries in the message catalog\n"
212 " --dump-catalog Show entries in the message catalog\n"
213 " --update-catalog Update the message catalog database\n"
215 " --setup-keys Generate a new FSS key pair\n"
216 " --verify Verify journal file consistency\n"
218 , program_invocation_short_name);
223 static int parse_argv(int argc, char *argv[]) {
253 static const struct option options[] = {
254 { "help", no_argument, NULL, 'h' },
255 { "version" , no_argument, NULL, ARG_VERSION },
256 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
257 { "pager-end", no_argument, NULL, 'e' },
258 { "follow", no_argument, NULL, 'f' },
259 { "force", no_argument, NULL, ARG_FORCE },
260 { "output", required_argument, NULL, 'o' },
261 { "all", no_argument, NULL, 'a' },
262 { "full", no_argument, NULL, 'l' },
263 { "no-full", no_argument, NULL, ARG_NO_FULL },
264 { "lines", optional_argument, NULL, 'n' },
265 { "no-tail", no_argument, NULL, ARG_NO_TAIL },
266 { "new-id128", no_argument, NULL, ARG_NEW_ID128 },
267 { "quiet", no_argument, NULL, 'q' },
268 { "merge", no_argument, NULL, 'm' },
269 { "boot", optional_argument, NULL, 'b' },
270 { "list-boots", no_argument, NULL, ARG_LIST_BOOTS },
271 { "this-boot", optional_argument, NULL, 'b' }, /* deprecated */
272 { "dmesg", no_argument, NULL, 'k' },
273 { "system", no_argument, NULL, ARG_SYSTEM },
274 { "user", no_argument, NULL, ARG_USER },
275 { "directory", required_argument, NULL, 'D' },
276 { "file", required_argument, NULL, ARG_FILE },
277 { "root", required_argument, NULL, ARG_ROOT },
278 { "header", no_argument, NULL, ARG_HEADER },
279 { "priority", required_argument, NULL, 'p' },
280 { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
281 { "interval", required_argument, NULL, ARG_INTERVAL },
282 { "verify", no_argument, NULL, ARG_VERIFY },
283 { "verify-key", required_argument, NULL, ARG_VERIFY_KEY },
284 { "disk-usage", no_argument, NULL, ARG_DISK_USAGE },
285 { "cursor", required_argument, NULL, 'c' },
286 { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR },
287 { "show-cursor", no_argument, NULL, ARG_SHOW_CURSOR },
288 { "since", required_argument, NULL, ARG_SINCE },
289 { "until", required_argument, NULL, ARG_UNTIL },
290 { "unit", required_argument, NULL, 'u' },
291 { "user-unit", required_argument, NULL, ARG_USER_UNIT },
292 { "field", required_argument, NULL, 'F' },
293 { "catalog", no_argument, NULL, 'x' },
294 { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG },
295 { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG },
296 { "update-catalog", no_argument, NULL, ARG_UPDATE_CATALOG },
297 { "reverse", no_argument, NULL, 'r' },
298 { "machine", required_argument, NULL, 'M' },
307 while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:u:F:xrM:", options, NULL)) >= 0) {
315 puts(PACKAGE_STRING);
316 puts(SYSTEMD_FEATURES);
324 arg_pager_end = true;
336 arg_output = output_mode_from_string(optarg);
337 if (arg_output < 0) {
338 log_error("Unknown output format '%s'.", optarg);
342 if (arg_output == OUTPUT_EXPORT ||
343 arg_output == OUTPUT_JSON ||
344 arg_output == OUTPUT_JSON_PRETTY ||
345 arg_output == OUTPUT_JSON_SSE ||
346 arg_output == OUTPUT_CAT)
365 r = safe_atoi(optarg, &arg_lines);
366 if (r < 0 || arg_lines < 0) {
367 log_error("Failed to parse lines '%s'", optarg);
373 /* Hmm, no argument? Maybe the next
374 * word on the command line is
375 * supposed to be the argument? Let's
376 * see if there is one, and is
377 * parsable as a positive
381 safe_atoi(argv[optind], &n) >= 0 &&
397 arg_action = ACTION_NEW_ID128;
412 r = parse_boot_descriptor(optarg, &arg_boot_id, &arg_boot_offset);
414 log_error("Failed to parse boot descriptor '%s'", optarg);
419 /* Hmm, no argument? Maybe the next
420 * word on the command line is
421 * supposed to be the argument? Let's
422 * see if there is one and is parsable
423 * as a boot descriptor... */
426 parse_boot_descriptor(argv[optind], &arg_boot_id, &arg_boot_offset) >= 0)
433 arg_action = ACTION_LIST_BOOTS;
437 arg_boot = arg_dmesg = true;
441 arg_journal_type |= SD_JOURNAL_SYSTEM;
445 arg_journal_type |= SD_JOURNAL_CURRENT_USER;
449 arg_machine = optarg;
453 arg_directory = optarg;
457 r = glob_extend(&arg_file, optarg);
459 log_error("Failed to add paths: %s", strerror(-r));
472 case ARG_AFTER_CURSOR:
473 arg_after_cursor = optarg;
476 case ARG_SHOW_CURSOR:
477 arg_show_cursor = true;
481 arg_action = ACTION_PRINT_HEADER;
485 arg_action = ACTION_VERIFY;
489 arg_action = ACTION_DISK_USAGE;
498 arg_action = ACTION_SETUP_KEYS;
503 arg_action = ACTION_VERIFY;
504 arg_verify_key = optarg;
509 r = parse_sec(optarg, &arg_interval);
510 if (r < 0 || arg_interval <= 0) {
511 log_error("Failed to parse sealing key change interval: %s", optarg);
520 log_error("Forward-secure sealing not available.");
527 dots = strstr(optarg, "..");
533 a = strndup(optarg, dots - optarg);
537 from = log_level_from_string(a);
538 to = log_level_from_string(dots + 2);
541 if (from < 0 || to < 0) {
542 log_error("Failed to parse log level range %s", optarg);
549 for (i = from; i <= to; i++)
550 arg_priorities |= 1 << i;
552 for (i = to; i <= from; i++)
553 arg_priorities |= 1 << i;
559 p = log_level_from_string(optarg);
561 log_error("Unknown log level %s", optarg);
567 for (i = 0; i <= p; i++)
568 arg_priorities |= 1 << i;
575 r = parse_timestamp(optarg, &arg_since);
577 log_error("Failed to parse timestamp: %s", optarg);
580 arg_since_set = true;
584 r = parse_timestamp(optarg, &arg_until);
586 log_error("Failed to parse timestamp: %s", optarg);
589 arg_until_set = true;
593 r = strv_extend(&arg_system_units, optarg);
599 r = strv_extend(&arg_user_units, optarg);
612 case ARG_LIST_CATALOG:
613 arg_action = ACTION_LIST_CATALOG;
616 case ARG_DUMP_CATALOG:
617 arg_action = ACTION_DUMP_CATALOG;
620 case ARG_UPDATE_CATALOG:
621 arg_action = ACTION_UPDATE_CATALOG;
632 assert_not_reached("Unhandled option");
636 if (arg_follow && !arg_no_tail && arg_lines < 0)
639 if (!!arg_directory + !!arg_file + !!arg_machine > 1) {
640 log_error("Please specify either -D/--directory= or --file= or -M/--machine=, not more than one.");
644 if (arg_since_set && arg_until_set && arg_since > arg_until) {
645 log_error("--since= must be before --until=.");
649 if (!!arg_cursor + !!arg_after_cursor + !!arg_since_set > 1) {
650 log_error("Please specify only one of --since=, --cursor=, and --after-cursor.");
654 if (arg_follow && arg_reverse) {
655 log_error("Please specify either --reverse= or --follow=, not both.");
662 static int generate_new_id128(void) {
667 r = sd_id128_randomize(&id);
669 log_error("Failed to generate ID: %s", strerror(-r));
673 printf("As string:\n"
674 SD_ID128_FORMAT_STR "\n\n"
676 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
678 "#define MESSAGE_XYZ SD_ID128_MAKE(",
679 SD_ID128_FORMAT_VAL(id),
680 SD_ID128_FORMAT_VAL(id));
681 for (i = 0; i < 16; i++)
682 printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
683 fputs(")\n\n", stdout);
685 printf("As Python constant:\n"
687 ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n",
688 SD_ID128_FORMAT_VAL(id));
693 static int add_matches(sd_journal *j, char **args) {
698 STRV_FOREACH(i, args) {
702 r = sd_journal_add_disjunction(j);
703 else if (path_is_absolute(*i)) {
704 _cleanup_free_ char *p, *t = NULL, *t2 = NULL;
706 _cleanup_free_ char *interpreter = NULL;
709 p = canonicalize_file_name(*i);
712 if (stat(path, &st) < 0) {
713 log_error("Couldn't stat file: %m");
717 if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
718 if (executable_is_script(path, &interpreter) > 0) {
719 _cleanup_free_ char *comm;
721 comm = strndup(basename(path), 15);
725 t = strappend("_COMM=", comm);
727 /* Append _EXE only if the interpreter is not a link.
728 Otherwise it might be outdated often. */
729 if (lstat(interpreter, &st) == 0 &&
730 !S_ISLNK(st.st_mode)) {
731 t2 = strappend("_EXE=", interpreter);
736 t = strappend("_EXE=", path);
737 } else if (S_ISCHR(st.st_mode))
738 asprintf(&t, "_KERNEL_DEVICE=c%u:%u", major(st.st_rdev), minor(st.st_rdev));
739 else if (S_ISBLK(st.st_mode))
740 asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev));
742 log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
749 r = sd_journal_add_match(j, t, 0);
751 r = sd_journal_add_match(j, t2, 0);
753 r = sd_journal_add_match(j, *i, 0);
756 log_error("Failed to add match '%s': %s", *i, strerror(-r));
764 static int boot_id_cmp(const void *a, const void *b) {
767 _a = ((const boot_id_t *)a)->first;
768 _b = ((const boot_id_t *)b)->first;
770 return _a < _b ? -1 : (_a > _b ? 1 : 0);
773 static int list_boots(sd_journal *j) {
776 unsigned int count = 0;
778 size_t length, allocated = 0;
780 _cleanup_free_ boot_id_t *all_ids = NULL;
782 r = sd_journal_query_unique(j, "_BOOT_ID");
786 SD_JOURNAL_FOREACH_UNIQUE(j, data, length) {
787 if (length < strlen("_BOOT_ID="))
790 if (!GREEDY_REALLOC(all_ids, allocated, count + 1))
793 id = &all_ids[count];
795 r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id);
799 r = sd_journal_add_match(j, data, length);
803 r = sd_journal_seek_head(j);
807 r = sd_journal_next(j);
813 r = sd_journal_get_realtime_usec(j, &id->first);
817 r = sd_journal_seek_tail(j);
821 r = sd_journal_previous(j);
827 r = sd_journal_get_realtime_usec(j, &id->last);
833 sd_journal_flush_matches(j);
836 qsort_safe(all_ids, count, sizeof(boot_id_t), boot_id_cmp);
838 /* numbers are one less, but we need an extra char for the sign */
839 w = DECIMAL_STR_WIDTH(count - 1) + 1;
841 for (id = all_ids, i = 0; id < all_ids + count; id++, i++) {
842 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
844 printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n",
846 SD_ID128_FORMAT_VAL(id->id),
847 format_timestamp(a, sizeof(a), id->first),
848 format_timestamp(b, sizeof(b), id->last));
854 static int get_relative_boot_id(sd_journal *j, sd_id128_t *boot_id, int relative) {
857 unsigned int count = 0;
858 size_t length, allocated = 0;
859 boot_id_t ref_boot_id = {SD_ID128_NULL}, *id;
860 _cleanup_free_ boot_id_t *all_ids = NULL;
865 r = sd_journal_query_unique(j, "_BOOT_ID");
869 SD_JOURNAL_FOREACH_UNIQUE(j, data, length) {
870 if (length < strlen("_BOOT_ID="))
873 if (!GREEDY_REALLOC(all_ids, allocated, count + 1))
876 id = &all_ids[count];
878 r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id);
882 r = sd_journal_add_match(j, data, length);
886 r = sd_journal_seek_head(j);
890 r = sd_journal_next(j);
896 r = sd_journal_get_realtime_usec(j, &id->first);
900 if (sd_id128_equal(id->id, *boot_id))
905 sd_journal_flush_matches(j);
908 qsort_safe(all_ids, count, sizeof(boot_id_t), boot_id_cmp);
910 if (sd_id128_equal(*boot_id, SD_ID128_NULL)) {
911 if (relative > (int) count || relative <= -(int)count)
912 return -EADDRNOTAVAIL;
914 *boot_id = all_ids[(relative <= 0)*count + relative - 1].id;
916 id = bsearch(&ref_boot_id, all_ids, count, sizeof(boot_id_t), boot_id_cmp);
919 relative <= 0 ? (id - all_ids) + relative < 0 :
920 (id - all_ids) + relative >= (int) count)
921 return -EADDRNOTAVAIL;
923 *boot_id = (id + relative)->id;
929 static int add_boot(sd_journal *j) {
930 char match[9+32+1] = "_BOOT_ID=";
938 if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, SD_ID128_NULL))
939 return add_match_this_boot(j, arg_machine);
941 r = get_relative_boot_id(j, &arg_boot_id, arg_boot_offset);
943 if (sd_id128_equal(arg_boot_id, SD_ID128_NULL))
944 log_error("Failed to look up boot %+i: %s", arg_boot_offset, strerror(-r));
946 log_error("Failed to look up boot ID "SD_ID128_FORMAT_STR"%+i: %s",
947 SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, strerror(-r));
951 sd_id128_to_string(arg_boot_id, match + 9);
953 r = sd_journal_add_match(j, match, sizeof(match) - 1);
955 log_error("Failed to add match: %s", strerror(-r));
959 r = sd_journal_add_conjunction(j);
966 static int add_dmesg(sd_journal *j) {
973 r = sd_journal_add_match(j, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel"));
975 log_error("Failed to add match: %s", strerror(-r));
979 r = sd_journal_add_conjunction(j);
986 static int add_units(sd_journal *j) {
987 _cleanup_free_ char *u = NULL;
993 STRV_FOREACH(i, arg_system_units) {
994 u = unit_name_mangle(*i, MANGLE_NOGLOB);
997 r = add_matches_for_unit(j, u);
1000 r = sd_journal_add_disjunction(j);
1005 STRV_FOREACH(i, arg_user_units) {
1006 u = unit_name_mangle(*i, MANGLE_NOGLOB);
1010 r = add_matches_for_user_unit(j, u, getuid());
1014 r = sd_journal_add_disjunction(j);
1020 r = sd_journal_add_conjunction(j);
1027 static int add_priorities(sd_journal *j) {
1028 char match[] = "PRIORITY=0";
1032 if (arg_priorities == 0xFF)
1035 for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
1036 if (arg_priorities & (1 << i)) {
1037 match[sizeof(match)-2] = '0' + i;
1039 r = sd_journal_add_match(j, match, strlen(match));
1041 log_error("Failed to add match: %s", strerror(-r));
1046 r = sd_journal_add_conjunction(j);
1053 static int setup_keys(void) {
1055 size_t mpk_size, seed_size, state_size, i;
1056 uint8_t *mpk, *seed, *state;
1058 int fd = -1, r, attr = 0;
1059 sd_id128_t machine, boot;
1060 char *p = NULL, *k = NULL;
1065 r = stat("/var/log/journal", &st);
1066 if (r < 0 && errno != ENOENT && errno != ENOTDIR) {
1067 log_error("stat(\"%s\") failed: %m", "/var/log/journal");
1071 if (r < 0 || !S_ISDIR(st.st_mode)) {
1072 log_error("%s is not a directory, must be using persistent logging for FSS.",
1073 "/var/log/journal");
1074 return r < 0 ? -errno : -ENOTDIR;
1077 r = sd_id128_get_machine(&machine);
1079 log_error("Failed to get machine ID: %s", strerror(-r));
1083 r = sd_id128_get_boot(&boot);
1085 log_error("Failed to get boot ID: %s", strerror(-r));
1089 if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
1090 SD_ID128_FORMAT_VAL(machine)) < 0)
1093 if (access(p, F_OK) >= 0) {
1097 log_error("unlink(\"%s\") failed: %m", p);
1102 log_error("Sealing key file %s exists already. (--force to recreate)", p);
1108 if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
1109 SD_ID128_FORMAT_VAL(machine)) < 0) {
1114 mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
1115 mpk = alloca(mpk_size);
1117 seed_size = FSPRG_RECOMMENDED_SEEDLEN;
1118 seed = alloca(seed_size);
1120 state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
1121 state = alloca(state_size);
1123 fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
1125 log_error("Failed to open /dev/random: %m");
1130 log_info("Generating seed...");
1131 l = loop_read(fd, seed, seed_size, true);
1132 if (l < 0 || (size_t) l != seed_size) {
1133 log_error("Failed to read random seed: %s", strerror(EIO));
1138 log_info("Generating key pair...");
1139 FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
1141 log_info("Generating sealing key...");
1142 FSPRG_GenState0(state, mpk, seed, seed_size);
1144 assert(arg_interval > 0);
1146 n = now(CLOCK_REALTIME);
1149 close_nointr_nofail(fd);
1150 fd = mkostemp(k, O_WRONLY|O_CLOEXEC|O_NOCTTY);
1152 log_error("Failed to open %s: %m", k);
1157 /* Enable secure remove, exclusion from dump, synchronous
1158 * writing and in-place updating */
1159 if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0)
1160 log_warning("FS_IOC_GETFLAGS failed: %m");
1162 attr |= FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL;
1164 if (ioctl(fd, FS_IOC_SETFLAGS, &attr) < 0)
1165 log_warning("FS_IOC_SETFLAGS failed: %m");
1168 memcpy(h.signature, "KSHHRHLP", 8);
1169 h.machine_id = machine;
1171 h.header_size = htole64(sizeof(h));
1172 h.start_usec = htole64(n * arg_interval);
1173 h.interval_usec = htole64(arg_interval);
1174 h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
1175 h.fsprg_state_size = htole64(state_size);
1177 l = loop_write(fd, &h, sizeof(h), false);
1178 if (l < 0 || (size_t) l != sizeof(h)) {
1179 log_error("Failed to write header: %s", strerror(EIO));
1184 l = loop_write(fd, state, state_size, false);
1185 if (l < 0 || (size_t) l != state_size) {
1186 log_error("Failed to write state: %s", strerror(EIO));
1191 if (link(k, p) < 0) {
1192 log_error("Failed to link file: %m");
1200 "The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n"
1201 "the following local file. This key file is automatically updated when the\n"
1202 "sealing key is advanced. It should not be used on multiple hosts.\n"
1206 "Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n"
1207 "at a safe location and should not be saved locally on disk.\n"
1208 "\n\t" ANSI_HIGHLIGHT_RED_ON, p);
1211 for (i = 0; i < seed_size; i++) {
1212 if (i > 0 && i % 3 == 0)
1214 printf("%02x", ((uint8_t*) seed)[i]);
1217 printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
1220 char tsb[FORMAT_TIMESPAN_MAX], *hn;
1223 ANSI_HIGHLIGHT_OFF "\n"
1224 "The sealing key is automatically changed every %s.\n",
1225 format_timespan(tsb, sizeof(tsb), arg_interval, 0));
1227 hn = gethostname_malloc();
1230 hostname_cleanup(hn, false);
1231 fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
1233 fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
1235 #ifdef HAVE_QRENCODE
1236 /* If this is not an UTF-8 system don't print any QR codes */
1237 if (is_locale_utf8()) {
1238 fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
1239 print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
1249 close_nointr_nofail(fd);
1260 log_error("Forward-secure sealing not available.");
1265 static int verify(sd_journal *j) {
1272 log_show_color(true);
1274 HASHMAP_FOREACH(f, j->files, i) {
1276 usec_t first, validated, last;
1279 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
1280 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
1283 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
1285 /* If the key was invalid give up right-away. */
1288 log_warning("FAIL: %s (%s)", f->path, strerror(-k));
1291 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
1292 log_info("PASS: %s", f->path);
1294 if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
1295 if (validated > 0) {
1296 log_info("=> Validated from %s to %s, final %s entries not sealed.",
1297 format_timestamp(a, sizeof(a), first),
1298 format_timestamp(b, sizeof(b), validated),
1299 format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
1300 } else if (last > 0)
1301 log_info("=> No sealing yet, %s of entries not sealed.",
1302 format_timespan(c, sizeof(c), last - first, 0));
1304 log_info("=> No sealing yet, no entries in file.");
1313 static int access_check_var_log_journal(sd_journal *j) {
1314 _cleanup_strv_free_ char **g = NULL;
1320 have_access = in_group("systemd-journal") > 0;
1323 /* Let's enumerate all groups from the default ACL of
1324 * the directory, which generally should allow access
1325 * to most journal files too */
1326 r = search_acl_groups(&g, "/var/log/journal/", &have_access);
1333 if (strv_isempty(g))
1334 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1335 " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
1336 " turn off this notice.");
1338 _cleanup_free_ char *s = NULL;
1340 r = strv_extend(&g, "systemd-journal");
1347 s = strv_join(g, "', '");
1351 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1352 " Users in the groups '%s' can see all messages.\n"
1353 " Pass -q to turn off this notice.", s);
1361 static int access_check(sd_journal *j) {
1368 if (set_isempty(j->errors)) {
1369 if (hashmap_isempty(j->files))
1370 log_notice("No journal files were found.");
1374 if (set_contains(j->errors, INT_TO_PTR(-EACCES))) {
1376 /* If /var/log/journal doesn't even exist,
1377 * unprivileged users have no access at all */
1378 if (access("/var/log/journal", F_OK) < 0 &&
1380 in_group("systemd-journal") <= 0) {
1381 log_error("Unprivileged users cannot access messages, unless persistent log storage is\n"
1382 "enabled. Users in the 'systemd-journal' group may always access messages.");
1386 /* If /var/log/journal exists, try to pring a nice
1387 notice if the user lacks access to it */
1388 if (!arg_quiet && geteuid() != 0) {
1389 r = access_check_var_log_journal(j);
1394 if (geteuid() != 0 && in_group("systemd-journal") <= 0) {
1395 log_error("Unprivileged users cannot access messages. Users in the 'systemd-journal' group\n"
1396 "group may access messages.");
1401 if (hashmap_isempty(j->files)) {
1402 log_error("No journal files were opened due to insufficient permissions.");
1407 SET_FOREACH(code, j->errors, it) {
1410 err = -PTR_TO_INT(code);
1414 log_warning("Error was encountered while opening journal files: %s",
1421 int main(int argc, char *argv[]) {
1423 _cleanup_journal_close_ sd_journal *j = NULL;
1424 bool need_seek = false;
1425 sd_id128_t previous_boot_id;
1426 bool previous_boot_id_valid = false, first_line = true;
1428 bool ellipsized = false;
1430 setlocale(LC_ALL, "");
1431 log_parse_environment();
1434 r = parse_argv(argc, argv);
1438 signal(SIGWINCH, columns_lines_cache_reset);
1440 if (arg_action == ACTION_NEW_ID128) {
1441 r = generate_new_id128();
1445 if (arg_action == ACTION_SETUP_KEYS) {
1450 if (arg_action == ACTION_UPDATE_CATALOG ||
1451 arg_action == ACTION_LIST_CATALOG ||
1452 arg_action == ACTION_DUMP_CATALOG) {
1454 const char* database = CATALOG_DATABASE;
1455 _cleanup_free_ char *copy = NULL;
1457 copy = strjoin(arg_root, "/", CATALOG_DATABASE, NULL);
1462 path_kill_slashes(copy);
1466 if (arg_action == ACTION_UPDATE_CATALOG) {
1467 r = catalog_update(database, arg_root, catalog_file_dirs);
1469 log_error("Failed to list catalog: %s", strerror(-r));
1471 bool oneline = arg_action == ACTION_LIST_CATALOG;
1474 r = catalog_list_items(stdout, database,
1475 oneline, argv + optind);
1477 r = catalog_list(stdout, database, oneline);
1479 log_error("Failed to list catalog: %s", strerror(-r));
1486 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
1488 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
1489 else if (arg_machine)
1490 r = sd_journal_open_container(&j, arg_machine, 0);
1492 r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
1494 log_error("Failed to open %s: %s",
1495 arg_directory ? arg_directory : arg_file ? "files" : "journal",
1497 return EXIT_FAILURE;
1500 r = access_check(j);
1502 return EXIT_FAILURE;
1504 if (arg_action == ACTION_VERIFY) {
1509 if (arg_action == ACTION_PRINT_HEADER) {
1510 journal_print_header(j);
1511 return EXIT_SUCCESS;
1514 if (arg_action == ACTION_DISK_USAGE) {
1516 char sbytes[FORMAT_BYTES_MAX];
1518 r = sd_journal_get_usage(j, &bytes);
1520 return EXIT_FAILURE;
1522 printf("Journals take up %s on disk.\n",
1523 format_bytes(sbytes, sizeof(sbytes), bytes));
1524 return EXIT_SUCCESS;
1527 if (arg_action == ACTION_LIST_BOOTS) {
1532 /* add_boot() must be called first!
1533 * It may need to seek the journal to find parent boot IDs. */
1536 return EXIT_FAILURE;
1540 return EXIT_FAILURE;
1543 strv_free(arg_system_units);
1544 strv_free(arg_user_units);
1547 return EXIT_FAILURE;
1549 r = add_priorities(j);
1551 return EXIT_FAILURE;
1553 r = add_matches(j, argv + optind);
1555 return EXIT_FAILURE;
1557 if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) {
1558 _cleanup_free_ char *filter;
1560 filter = journal_make_match_string(j);
1561 log_debug("Journal filter: %s", filter);
1568 r = sd_journal_set_data_threshold(j, 0);
1570 log_error("Failed to unset data size threshold");
1571 return EXIT_FAILURE;
1574 r = sd_journal_query_unique(j, arg_field);
1576 log_error("Failed to query unique data objects: %s", strerror(-r));
1577 return EXIT_FAILURE;
1580 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1583 if (arg_lines >= 0 && n_shown >= arg_lines)
1586 eq = memchr(data, '=', size);
1588 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
1590 printf("%.*s\n", (int) size, (const char*) data);
1595 return EXIT_SUCCESS;
1598 /* Opening the fd now means the first sd_journal_wait() will actually wait */
1600 r = sd_journal_get_fd(j);
1602 return EXIT_FAILURE;
1605 if (arg_cursor || arg_after_cursor) {
1606 r = sd_journal_seek_cursor(j, arg_cursor ? arg_cursor : arg_after_cursor);
1608 log_error("Failed to seek to cursor: %s", strerror(-r));
1609 return EXIT_FAILURE;
1612 r = sd_journal_next_skip(j, 1 + !!arg_after_cursor);
1614 r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor);
1616 if (arg_after_cursor && r < 2 && !arg_follow)
1617 /* We couldn't find the next entry after the cursor. */
1620 } else if (arg_since_set && !arg_reverse) {
1621 r = sd_journal_seek_realtime_usec(j, arg_since);
1623 log_error("Failed to seek to date: %s", strerror(-r));
1624 return EXIT_FAILURE;
1626 r = sd_journal_next(j);
1628 } else if (arg_until_set && arg_reverse) {
1629 r = sd_journal_seek_realtime_usec(j, arg_until);
1631 log_error("Failed to seek to date: %s", strerror(-r));
1632 return EXIT_FAILURE;
1634 r = sd_journal_previous(j);
1636 } else if (arg_lines >= 0) {
1637 r = sd_journal_seek_tail(j);
1639 log_error("Failed to seek to tail: %s", strerror(-r));
1640 return EXIT_FAILURE;
1643 r = sd_journal_previous_skip(j, arg_lines);
1645 } else if (arg_reverse) {
1646 r = sd_journal_seek_tail(j);
1648 log_error("Failed to seek to tail: %s", strerror(-r));
1649 return EXIT_FAILURE;
1652 r = sd_journal_previous(j);
1655 r = sd_journal_seek_head(j);
1657 log_error("Failed to seek to head: %s", strerror(-r));
1658 return EXIT_FAILURE;
1661 r = sd_journal_next(j);
1665 log_error("Failed to iterate through journal: %s", strerror(-r));
1666 return EXIT_FAILURE;
1670 pager_open_if_enabled();
1674 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
1676 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
1678 log_error("Failed to get cutoff: %s", strerror(-r));
1684 printf("-- Logs begin at %s. --\n",
1685 format_timestamp(start_buf, sizeof(start_buf), start));
1687 printf("-- Logs begin at %s, end at %s. --\n",
1688 format_timestamp(start_buf, sizeof(start_buf), start),
1689 format_timestamp(end_buf, sizeof(end_buf), end));
1694 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
1699 r = sd_journal_next(j);
1701 r = sd_journal_previous(j);
1703 log_error("Failed to iterate through journal: %s", strerror(-r));
1710 if (arg_until_set && !arg_reverse) {
1713 r = sd_journal_get_realtime_usec(j, &usec);
1715 log_error("Failed to determine timestamp: %s", strerror(-r));
1718 if (usec > arg_until)
1722 if (arg_since_set && arg_reverse) {
1725 r = sd_journal_get_realtime_usec(j, &usec);
1727 log_error("Failed to determine timestamp: %s", strerror(-r));
1730 if (usec < arg_since)
1737 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
1739 if (previous_boot_id_valid &&
1740 !sd_id128_equal(boot_id, previous_boot_id))
1741 printf("%s-- Reboot --%s\n",
1742 ansi_highlight(), ansi_highlight_off());
1744 previous_boot_id = boot_id;
1745 previous_boot_id_valid = true;
1750 arg_all * OUTPUT_SHOW_ALL |
1751 arg_full * OUTPUT_FULL_WIDTH |
1752 on_tty() * OUTPUT_COLOR |
1753 arg_catalog * OUTPUT_CATALOG;
1755 r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized);
1757 if (r == -EADDRNOTAVAIL)
1759 else if (r < 0 || ferror(stdout))
1766 if (arg_show_cursor) {
1767 _cleanup_free_ char *cursor = NULL;
1769 r = sd_journal_get_cursor(j, &cursor);
1770 if (r < 0 && r != -EADDRNOTAVAIL)
1771 log_error("Failed to get cursor: %s", strerror(-r));
1773 printf("-- cursor: %s\n", cursor);
1779 r = sd_journal_wait(j, (uint64_t) -1);
1781 log_error("Couldn't wait for journal event: %s", strerror(-r));
1791 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;