diff options
-rw-r--r-- | Makefile.am | 12 | ||||
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | src/journal/journal-qrcode.c | 127 | ||||
-rw-r--r-- | src/journal/journal-qrcode.h | 30 | ||||
-rw-r--r-- | src/journal/journalctl.c | 17 | ||||
-rw-r--r-- | src/shared/util.c | 1 |
6 files changed, 198 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index 166c357db2..69cdeb7145 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/configure.ac b/configure.ac index 3df43b91fd..52adb20e0b 100644 --- a/configure.ac +++ b/configure.ac @@ -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 index 0000000000..b4dab8e86a --- /dev/null +++ b/src/journal/journal-qrcode.c @@ -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 index 0000000000..da6244c160 --- /dev/null +++ b/src/journal/journal-qrcode.h @@ -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); diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 551cb311b5..b0d8258dd2 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -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; diff --git a/src/shared/util.c b/src/shared/util.c index cbf44ebdfd..041b759287 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -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; |