chiark / gitweb /
journalctl: output FSS key as QR code on generating
authorLennart Poettering <lennart@poettering.net>
Mon, 20 Aug 2012 20:02:19 +0000 (22:02 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 20 Aug 2012 20:02:19 +0000 (22:02 +0200)
Makefile.am
configure.ac
src/journal/journal-qrcode.c [new file with mode: 0644]
src/journal/journal-qrcode.h [new file with mode: 0644]
src/journal/journalctl.c
src/shared/util.c

index 166c357..69cdeb7 100644 (file)
@@ -2353,6 +2353,18 @@ journalctl_LDADD = \
        libsystemd-id128-internal.la \
        libsystemd-logs.la
 
+if HAVE_QRENCODE
+journalctl_SOURCES += \
+       src/journal/journal-qrcode.c \
+       src/journal/journal-qrcode.h
+
+journalctl_CFLAGS += \
+       $(QRENCODE_CFLAGS)
+
+journalctl_LDADD += \
+       $(QRENCODE_LIBS)
+endif
+
 test_journal_SOURCES = \
        src/journal/test-journal.c
 
index 3df43b9..52adb20 100644 (file)
@@ -384,6 +384,18 @@ fi
 AM_CONDITIONAL(HAVE_LIBCRYPTSETUP, [test "$have_libcryptsetup" = "yes"])
 
 # ------------------------------------------------------------------------------
+have_qrencode=no
+AC_ARG_ENABLE(qrencode, AS_HELP_STRING([--disable-qrencode], [disable qrencode support]))
+if test "x$enable_qrencode" != "xno"; then
+        PKG_CHECK_MODULES(QRENCODE, [ libqrencode ],
+                [AC_DEFINE(HAVE_QRENCODE, 1, [Define if qrencode is available]) have_qrencode=yes], have_qrencode=no)
+        if test "x$have_qrencode" = xno -a "x$enable_qrencode" = xyes; then
+                AC_MSG_ERROR([*** qrencode support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_QRENCODE, [test "$have_qrencode" = "yes"])
+
+# ------------------------------------------------------------------------------
 have_binfmt=no
 AC_ARG_ENABLE(binfmt, AS_HELP_STRING([--disable-binfmt], [disable binfmt tool]))
 if test "x$enable_binfmt" != "xno"; then
@@ -760,6 +772,7 @@ AC_MSG_RESULT([
         XZ:                      ${have_xz}
         ACL:                     ${have_acl}
         GCRYPT:                  ${have_gcrypt}
+        QRENCODE:                ${have_qrencode}
         binfmt:                  ${have_binfmt}
         vconsole:                ${have_vconsole}
         readahead:               ${have_readahead}
diff --git a/src/journal/journal-qrcode.c b/src/journal/journal-qrcode.c
new file mode 100644 (file)
index 0000000..b4dab8e
--- /dev/null
@@ -0,0 +1,127 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <qrencode.h>
+
+#include "journal-qrcode.h"
+
+#define WHITE_ON_BLACK "\033[40;37;1m"
+#define NORMAL "\033[0m"
+
+static void print_border(FILE *output, unsigned width) {
+        unsigned x, y;
+
+        /* Four rows of border */
+        for (y = 0; y < 4; y += 2) {
+                fputs(WHITE_ON_BLACK, output);
+
+                for (x = 0; x < 4 + width + 4; x++)
+                        fputs("\342\226\210", output);
+
+                fputs(NORMAL "\n", output);
+        }
+}
+
+int print_qr_code(FILE *output, const void *seed, size_t seed_size, uint64_t start, uint64_t interval, const char *hn, sd_id128_t mahcine) {
+        FILE *f;
+        char *url = NULL;
+        size_t url_size = 0, i;
+        QRcode* qr;
+        unsigned x, y;
+
+        assert(seed);
+        assert(seed_size > 0);
+
+        f = open_memstream(&url, &url_size);
+        if (!f)
+                return -ENOMEM;
+
+        fputs("fss://", f);
+
+        for (i = 0; i < seed_size; i++) {
+                if (i > 0 && i % 3 == 0)
+                        fputc('-', f);
+                fprintf(f, "%02x", ((uint8_t*) seed)[i]);
+        }
+
+        fprintf(f, "/%llx-%llx\n", (unsigned long long) start, (unsigned long long) interval);
+
+        if (hn)
+                fprintf(f, "?hostname=%s", hn);
+
+        if (ferror(f)) {
+                fclose(f);
+                free(url);
+                return -ENOMEM;
+        }
+
+        fclose(f);
+
+        qr = QRcode_encodeString(url, 0, QR_ECLEVEL_L, QR_MODE_8, 1);
+        free(url);
+
+        if (!qr)
+                return -ENOMEM;
+
+        print_border(output, qr->width);
+
+        for (y = 0; y < (unsigned) qr->width; y += 2) {
+                const uint8_t *row1, *row2;
+
+                row1 = qr->data + qr->width * y;
+                row2 = row1 + qr->width;
+
+                fputs(WHITE_ON_BLACK, output);
+                for (x = 0; x < 4; x++)
+                        fputs("\342\226\210", output);
+
+                for (x = 0; x < (unsigned) qr->width; x ++) {
+                        bool a, b;
+
+                        a = row1[x] & 1;
+                        b = (y+1) < (unsigned) qr->width ? (row2[x] & 1) : false;
+
+                        if (a && b)
+                                fputc(' ', output);
+                        else if (a)
+                                fputs("\342\226\204", output);
+                        else if (b)
+                                fputs("\342\226\200", output);
+                        else
+                                fputs("\342\226\210", output);
+                }
+
+                for (x = 0; x < 4; x++)
+                        fputs("\342\226\210", output);
+                fputs(NORMAL "\n", output);
+        }
+
+        print_border(output, qr->width);
+
+        QRcode_free(qr);
+        return 0;
+}
diff --git a/src/journal/journal-qrcode.h b/src/journal/journal-qrcode.h
new file mode 100644 (file)
index 0000000..da6244c
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+#include <systemd/sd-id128.h>
+
+int print_qr_code(FILE *f, const void *seed, size_t seed_size, uint64_t start, uint64_t interval, const char *hn, sd_id128_t machine);
index 551cb31..b0d8258 100644 (file)
@@ -46,6 +46,7 @@
 #include "journal-def.h"
 #include "journal-verify.h"
 #include "journal-authenticate.h"
+#include "journal-qrcode.h"
 #include "fsprg.h"
 
 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
@@ -607,12 +608,26 @@ static int setup_keys(void) {
         printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
 
         if (isatty(STDOUT_FILENO)) {
-                char tsb[FORMAT_TIMESPAN_MAX];
+                char tsb[FORMAT_TIMESPAN_MAX], *hn;
 
                 fprintf(stderr,
                         ANSI_HIGHLIGHT_OFF "\n"
                         "The sealing key is automatically changed every %s.\n",
                         format_timespan(tsb, sizeof(tsb), arg_interval));
+
+                hn = gethostname_malloc();
+
+                if (hn) {
+                        hostname_cleanup(hn);
+                        fprintf(stderr, "The keys have been generated for host %s (" SD_ID128_FORMAT_STR ").\n", hn, SD_ID128_FORMAT_VAL(machine));
+                } else
+                        fprintf(stderr, "The keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
+
+#ifdef HAVE_QRENCODE
+                fputc('\n', stderr);
+                print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
+#endif
+                free(hn);
         }
 
         r = 0;
index cbf44eb..041b759 100644 (file)
@@ -3089,7 +3089,6 @@ bool hostname_is_set(void) {
         return !isempty(u.nodename) && !streq(u.nodename, "(none)");
 }
 
-
 static char *lookup_uid(uid_t uid) {
         long bufsize;
         char *buf, *name;