chiark / gitweb /
journal: make libgcrypt dependency optional
authorLennart Poettering <lennart@poettering.net>
Mon, 20 Aug 2012 14:51:46 +0000 (16:51 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 20 Aug 2012 14:51:46 +0000 (16:51 +0200)
12 files changed:
Makefile.am
README
TODO
configure.ac
src/core/build.h
src/journal/journal-authenticate.c
src/journal/journal-authenticate.h
src/journal/journal-file.c
src/journal/journal-verify.c
src/journal/journalctl.c
src/journal/test-journal-verify.c
src/journal/test-journal.c

index 3eeb842..166c357 100644 (file)
@@ -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 a5d5690..334c597 100644 (file)
--- 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 875a3db..e16db6f 100644 (file)
--- 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
index c1e88da..3df43b9 100644 (file)
@@ -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 ;;
index 0b38050..4513a0b 100644 (file)
 #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_
index ddcf856..93cc9d9 100644 (file)
@@ -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;
 }
index 4f4f45b..447c7b4 100644 (file)
@@ -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);
index 760efae..f01f124 100644 (file)
 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);
index 6afeab9..a76384b 100644 (file)
@@ -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 ++;
index e61ddf6..551cb31 100644 (file)
@@ -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),
index ed6e21d..b667721 100644 (file)
@@ -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) {
index 05bb2ea..2273500 100644 (file)
@@ -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);