summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--README1
-rw-r--r--TODO6
-rw-r--r--configure.ac2
-rw-r--r--src/core/build.h20
-rw-r--r--src/journal/journal-authenticate.c57
-rw-r--r--src/journal/journal-authenticate.h2
-rw-r--r--src/journal/journal-file.c18
-rw-r--r--src/journal/journal-verify.c71
-rw-r--r--src/journal/journalctl.c30
-rw-r--r--src/journal/test-journal-verify.c7
-rw-r--r--src/journal/test-journal.c2
12 files changed, 134 insertions, 86 deletions
diff --git a/Makefile.am b/Makefile.am
index 3eeb842afe..166c357db2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2402,8 +2402,6 @@ libsystemd_journal_la_SOURCES = \
src/journal/journal-vacuum.h \
src/journal/journal-verify.c \
src/journal/journal-verify.h \
- src/journal/journal-authenticate.c \
- src/journal/journal-authenticate.h \
src/journal/lookup3.c \
src/journal/lookup3.h \
src/journal/journal-send.c \
@@ -2455,6 +2453,8 @@ endif
if HAVE_GCRYPT
libsystemd_journal_la_SOURCES += \
+ src/journal/journal-authenticate.c \
+ src/journal/journal-authenticate.h \
src/journal/fsprg.c \
src/journal/fsprg.h
diff --git a/README b/README
index a5d569028d..334c597213 100644
--- a/README
+++ b/README
@@ -42,6 +42,7 @@ REQUIREMENTS:
libcap
PAM >= 1.1.2 (optional)
libcryptsetup (optional)
+ libgcrypt (optional)
libaudit (optional)
libacl (optional)
libselinux (optional)
diff --git a/TODO b/TODO
index 875a3db4d6..e16db6fa4d 100644
--- a/TODO
+++ b/TODO
@@ -254,8 +254,6 @@ Features:
* cleanup syslog 'priority' vs. 'level' wording
-* journal: if mmap() fails for mapping window try to unmap a a few older maps
-
* dbus upstream still refers to dbus.target and shouldn't
* when a service has the same env var set twice we actually store it twice and return that in systemctl show -p... We should only show the last setting
@@ -300,8 +298,6 @@ Features:
* journal: message catalog
-* journal: forward-secure signatures
-
* document the exit codes when services fail before they are exec()ed
* systemctl journal command
@@ -503,6 +499,4 @@ Scheduled for removal (or fixing):
* xxxOverridable dependencies
-* journald.conf: ImportKernel=
-
* prefdm.service
diff --git a/configure.ac b/configure.ac
index c1e88daa3f..3df43b91fd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -302,7 +302,7 @@ AC_SUBST(ACL_LIBS)
AM_CONDITIONAL([HAVE_ACL], [test "x$have_acl" != xno])
# ------------------------------------------------------------------------------
-AC_ARG_ENABLE([],
+AC_ARG_ENABLE([gcrypt],
AS_HELP_STRING([--disable-gcrypt],[Disable optional GCRYPT support]),
[case "${enableval}" in
yes) have_gcrypt=yes ;;
diff --git a/src/core/build.h b/src/core/build.h
index 0b38050bd4..4513a0bad7 100644
--- a/src/core/build.h
+++ b/src/core/build.h
@@ -63,4 +63,22 @@
#define _LIBCRYPTSETUP_FEATURE_ "-LIBCRYPTSETUP"
#endif
-#define SYSTEMD_FEATURES _PAM_FEATURE_ " " _LIBWRAP_FEATURE_ " " _AUDIT_FEATURE_ " " _SELINUX_FEATURE_ " " _IMA_FEATURE_ " " _SYSVINIT_FEATURE_ " " _LIBCRYPTSETUP_FEATURE_
+#ifdef HAVE_GCRYPT
+#define _GCRYPT_FEATURE_ "+GCRYPT"
+#else
+#define _GCRYPT_FEATURE_ "-GCRYPT"
+#endif
+
+#ifdef HAVE_ACL
+#define _ACL_FEATURE_ "+ACL"
+#else
+#define _ACL_FEATURE_ "-ACL"
+#endif
+
+#ifdef HAVE_XZ
+#define _XZ_FEATURE_ "+XZ"
+#else
+#define _XZ_FEATURE_ "-XZ"
+#endif
+
+#define SYSTEMD_FEATURES _PAM_FEATURE_ " " _LIBWRAP_FEATURE_ " " _AUDIT_FEATURE_ " " _SELINUX_FEATURE_ " " _IMA_FEATURE_ " " _SYSVINIT_FEATURE_ " " _LIBCRYPTSETUP_FEATURE_ " " _GCRYPT_FEATURE_ " " _ACL_FEATURE_ " " _XZ_FEATURE_
diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c
index ddcf856aec..93cc9d94a1 100644
--- a/src/journal/journal-authenticate.c
+++ b/src/journal/journal-authenticate.c
@@ -461,8 +461,59 @@ int journal_file_append_first_tag(JournalFile *f) {
return 0;
}
-bool journal_file_fss_enabled(JournalFile *f) {
- assert(f);
- return JOURNAL_HEADER_SEALED(f->header);
+int journal_file_parse_verification_key(JournalFile *f, const char *key) {
+ uint8_t *seed;
+ size_t seed_size, c;
+ const char *k;
+ int r;
+ unsigned long long start, interval;
+
+ seed_size = FSPRG_RECOMMENDED_SEEDLEN;
+ seed = malloc(seed_size);
+ if (!seed)
+ return -ENOMEM;
+
+ k = key;
+ for (c = 0; c < seed_size; c++) {
+ int x, y;
+
+ while (*k == '-')
+ k++;
+
+ x = unhexchar(*k);
+ if (x < 0) {
+ free(seed);
+ return -EINVAL;
+ }
+ k++;
+ y = unhexchar(*k);
+ if (y < 0) {
+ free(seed);
+ return -EINVAL;
+ }
+ k++;
+
+ seed[c] = (uint8_t) (x * 16 + y);
+ }
+
+ if (*k != '/') {
+ free(seed);
+ return -EINVAL;
+ }
+ k++;
+
+ r = sscanf(k, "%llx-%llx", &start, &interval);
+ if (r != 2) {
+ free(seed);
+ return -EINVAL;
+ }
+
+ f->fsprg_seed = seed;
+ f->fsprg_seed_size = seed_size;
+
+ f->fss_start_usec = start * interval;
+ f->fss_interval_usec = interval;
+
+ return 0;
}
diff --git a/src/journal/journal-authenticate.h b/src/journal/journal-authenticate.h
index 4f4f45b114..447c7b4657 100644
--- a/src/journal/journal-authenticate.h
+++ b/src/journal/journal-authenticate.h
@@ -36,7 +36,7 @@ int journal_file_hmac_put_header(JournalFile *f);
int journal_file_hmac_put_object(JournalFile *f, int type, uint64_t p);
int journal_file_fss_load(JournalFile *f);
-bool journal_file_fss_enabled(JournalFile *f);
+int journal_file_parse_verification_key(JournalFile *f, const char *key);
int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime);
int journal_file_fsprg_seek(JournalFile *f, uint64_t epoch);
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 760efaebbb..f01f12496c 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -64,9 +64,11 @@
void journal_file_close(JournalFile *f) {
assert(f);
+#ifdef HAVE_GCRYPT
/* Write the final tag */
if (f->seal && f->writable)
journal_file_append_tag(f);
+#endif
/* Sync everything to disk, before we mark the file offline */
if (f->mmap && f->fd >= 0)
@@ -764,9 +766,11 @@ static int journal_file_append_data(
if (r < 0)
return r;
+#ifdef HAVE_GCRYPT
r = journal_file_hmac_put_object(f, OBJECT_DATA, p);
if (r < 0)
return r;
+#endif
/* The linking might have altered the window, so let's
* refresh our pointer */
@@ -852,9 +856,11 @@ static int link_entry_into_array(JournalFile *f,
if (r < 0)
return r;
+#ifdef HAVE_GCRYPT
r = journal_file_hmac_put_object(f, OBJECT_ENTRY_ARRAY, q);
if (r < 0)
return r;
+#endif
o->entry_array.items[i] = htole64(p);
@@ -996,9 +1002,11 @@ static int journal_file_append_entry_internal(
o->entry.xor_hash = htole64(xor_hash);
o->entry.boot_id = f->header->boot_id;
+#ifdef HAVE_GCRYPT
r = journal_file_hmac_put_object(f, OBJECT_ENTRY, np);
if (r < 0)
return r;
+#endif
r = journal_file_link_entry(f, o, np);
if (r < 0)
@@ -1049,9 +1057,11 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st
ts->monotonic < le64toh(f->header->tail_entry_monotonic))
return -EINVAL;
+#ifdef HAVE_GCRYPT
r = journal_file_maybe_append_tag(f, ts->realtime);
if (r < 0)
return r;
+#endif
/* alloca() can't take 0, hence let's allocate at least one */
items = alloca(sizeof(EntryItem) * MAX(1, n_iovec));
@@ -2030,11 +2040,13 @@ int journal_file_open(
if (f->last_stat.st_size == 0 && f->writable) {
newly_created = true;
+#ifdef HAVE_GCRYPT
/* Try to load the FSPRG state, and if we can't, then
* just don't do sealing */
r = journal_file_fss_load(f);
if (r < 0)
f->seal = false;
+#endif
r = journal_file_init_header(f, template);
if (r < 0)
@@ -2064,11 +2076,13 @@ int journal_file_open(
goto fail;
}
+#ifdef HAVE_GCRYPT
if (!newly_created && f->writable) {
r = journal_file_fss_load(f);
if (r < 0)
goto fail;
}
+#endif
if (f->writable) {
if (metrics) {
@@ -2082,9 +2096,11 @@ int journal_file_open(
goto fail;
}
+#ifdef HAVE_GCRYPT
r = journal_file_hmac_setup(f);
if (r < 0)
goto fail;
+#endif
if (newly_created) {
r = journal_file_setup_field_hash_table(f);
@@ -2095,9 +2111,11 @@ int journal_file_open(
if (r < 0)
goto fail;
+#ifdef HAVE_GCRYPT
r = journal_file_append_first_tag(f);
if (r < 0)
goto fail;
+#endif
}
r = journal_file_map_field_hash_table(f);
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 6afeab9a80..a76384bdb2 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -22,6 +22,7 @@
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
+#include <stddef.h>
#include "util.h"
#include "macro.h"
@@ -37,7 +38,6 @@
*
* - evolve key even if nothing happened in regular intervals
*
- * - Allow building without libgcrypt
* - check with sparse
* - 64bit conversions
*
@@ -645,62 +645,6 @@ static int verify_entry_array(
return 0;
}
-static int journal_file_parse_verification_key(JournalFile *f, const char *key) {
- uint8_t *seed;
- size_t seed_size, c;
- const char *k;
- int r;
- unsigned long long start, interval;
-
- seed_size = FSPRG_RECOMMENDED_SEEDLEN;
- seed = malloc(seed_size);
- if (!seed)
- return -ENOMEM;
-
- k = key;
- for (c = 0; c < seed_size; c++) {
- int x, y;
-
- while (*k == '-')
- k++;
-
- x = unhexchar(*k);
- if (x < 0) {
- free(seed);
- return -EINVAL;
- }
- k++;
- y = unhexchar(*k);
- if (y < 0) {
- free(seed);
- return -EINVAL;
- }
- k++;
-
- seed[c] = (uint8_t) (x * 16 + y);
- }
-
- if (*k != '/') {
- free(seed);
- return -EINVAL;
- }
- k++;
-
- r = sscanf(k, "%llx-%llx", &start, &interval);
- if (r != 2) {
- free(seed);
- return -EINVAL;
- }
-
- f->fsprg_seed = seed;
- f->fsprg_seed_size = seed_size;
-
- f->fss_start_usec = start * interval;
- f->fss_interval_usec = interval;
-
- return 0;
-}
-
int journal_file_verify(
JournalFile *f,
const char *key,
@@ -724,11 +668,15 @@ int journal_file_verify(
assert(f);
if (key) {
+#ifdef HAVE_GCRYPT
r = journal_file_parse_verification_key(f, key);
if (r < 0) {
log_error("Failed to parse seed.");
return r;
}
+#else
+ return -ENOTSUP;
+#endif
} else if (f->seal)
return -ENOKEY;
@@ -936,9 +884,7 @@ int journal_file_verify(
n_entry_arrays++;
break;
- case OBJECT_TAG: {
- uint64_t q, rt;
-
+ case OBJECT_TAG:
if (!JOURNAL_HEADER_SEALED(f->header)) {
log_error("Tag object in file without sealing at %llu", (unsigned long long) p);
r = -EBADMSG;
@@ -957,7 +903,10 @@ int journal_file_verify(
goto fail;
}
+#ifdef HAVE_GCRYPT
if (f->seal) {
+ uint64_t q, rt;
+
log_debug("Checking tag %llu..", (unsigned long long) le64toh(o->tag.seqnum));
rt = f->fss_start_usec + o->tag.epoch * f->fss_interval_usec;
@@ -1014,13 +963,13 @@ int journal_file_verify(
last_tag_realtime = rt;
last_sealed_realtime = entry_realtime;
}
+#endif
last_tag = p + ALIGN64(le64toh(o->object.size));
last_epoch = le64toh(o->tag.epoch);
n_tags ++;
break;
- }
default:
n_weird ++;
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index e61ddf6d92..551cb311b5 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -62,7 +62,9 @@ static bool arg_this_boot = false;
static const char *arg_directory = NULL;
static int arg_priorities = 0xFF;
static const char *arg_verify_key = NULL;
+#ifdef HAVE_GCRYPT
static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
+#endif
static enum {
ACTION_SHOW,
@@ -93,11 +95,13 @@ static int help(void) {
"Commands:\n"
" --new-id128 Generate a new 128 Bit ID\n"
" --header Show journal header information\n"
+#ifdef HAVE_GCRYPT
" --setup-keys Generate new FSS key pair\n"
" --interval=TIME Time interval for changing the FSS sealing key\n"
" --verify Verify journal file consistency\n"
- " --verify-key=KEY Specify FSS verification key\n",
- program_invocation_short_name);
+ " --verify-key=KEY Specify FSS verification key\n"
+#endif
+ , program_invocation_short_name);
return 0;
}
@@ -215,13 +219,15 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_PRINT_HEADER;
break;
+ case ARG_VERIFY:
+ arg_action = ACTION_VERIFY;
+ break;
+
+#ifdef HAVE_GCRYPT
case ARG_SETUP_KEYS:
arg_action = ACTION_SETUP_KEYS;
break;
- case ARG_VERIFY:
- arg_action = ACTION_VERIFY;
- break;
case ARG_VERIFY_KEY:
arg_action = ACTION_VERIFY;
@@ -235,6 +241,13 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
break;
+#else
+ case ARG_SETUP_KEYS:
+ case ARG_VERIFY_KEY:
+ case ARG_INTERVAL:
+ log_error("Forward-secure sealing not available.");
+ return -ENOTSUP;
+#endif
case 'p': {
const char *dots;
@@ -617,7 +630,8 @@ finish:
return r;
#else
- log_error("Forward-secure journal verification not available.");
+ log_error("Forward-secure sealing not available.");
+ return -ENOTSUP;
#endif
}
@@ -633,7 +647,7 @@ static int verify(sd_journal *j) {
usec_t from, to, total;
#ifdef HAVE_GCRYPT
- if (!arg_verify_key && journal_file_fss_enabled(f))
+ if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
log_warning("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
#endif
@@ -648,7 +662,7 @@ static int verify(sd_journal *j) {
char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
log_info("PASS: %s", f->path);
- if (arg_verify_key && journal_file_fss_enabled(f))
+ if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
log_info("=> Validated from %s to %s, %s missing",
format_timestamp(a, sizeof(a), from),
format_timestamp(b, sizeof(b), to),
diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c
index ed6e21dc0c..b6677215c0 100644
--- a/src/journal/test-journal-verify.c
+++ b/src/journal/test-journal-verify.c
@@ -55,7 +55,7 @@ static int raw_verify(const char *fn, const char *verification_key) {
JournalFile *f;
int r;
- r = journal_file_open(fn, O_RDONLY, 0666, true, true, NULL, NULL, NULL, &f);
+ r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f);
if (r < 0)
return r;
@@ -107,18 +107,19 @@ int main(int argc, char *argv[]) {
log_info("Verifying...");
- assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, true, NULL, NULL, NULL, &f) == 0);
+ assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
/* journal_file_print_header(f); */
journal_file_dump(f);
assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0);
- if (verification_key && journal_file_fss_enabled(f)) {
+ if (verification_key && JOURNAL_HEADER_SEALED(f->header)) {
log_info("=> Validated from %s to %s, %s missing",
format_timestamp(a, sizeof(a), from),
format_timestamp(b, sizeof(b), to),
format_timespan(c, sizeof(c), total > to ? total - to : 0));
}
+
journal_file_close(f);
if (verification_key) {
diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c
index 05bb2ea8ed..2273500100 100644
--- a/src/journal/test-journal.c
+++ b/src/journal/test-journal.c
@@ -59,7 +59,9 @@ int main(int argc, char *argv[]) {
iovec.iov_len = strlen(test);
assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
+#ifdef HAVE_GCRYPT
journal_file_append_tag(f);
+#endif
journal_file_dump(f);
assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1);