Merge pull request #17454 from keszybz/journal-dlopen-cleanup

Journal dlopen cleanup and qrcode printing test
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-10-28 18:20:27 +01:00 committed by GitHub
commit a1989bd84b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 171 additions and 212 deletions

View File

@ -1561,21 +1561,11 @@ meson_apply_m4 = find_program('tools/meson-apply-m4.sh')
includes = include_directories('src/basic',
'src/boot',
'src/core',
'src/home',
'src/shared',
'src/systemd',
'src/journal',
'src/journal-remote',
'src/nspawn',
'src/resolve',
'src/timesync',
'src/time-wait-sync',
'src/login',
'src/udev',
'src/libudev',
'src/core',
'src/shutdown',
'src/xdg-autostart-generator',
'src/libsystemd-network',
'src/libsystemd/sd-bus',
'src/libsystemd/sd-device',
'src/libsystemd/sd-event',
@ -1584,7 +1574,17 @@ includes = include_directories('src/basic',
'src/libsystemd/sd-netlink',
'src/libsystemd/sd-network',
'src/libsystemd/sd-resolve',
'src/libsystemd-network',
'src/libudev',
'src/login',
'src/nspawn',
'src/resolve',
'src/shared',
'src/shutdown',
'src/systemd',
'src/time-wait-sync',
'src/timesync',
'src/udev',
'src/xdg-autostart-generator',
'.')
add_project_arguments('-include', 'config.h', language : 'c')

View File

@ -1,17 +1,12 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#if HAVE_QRENCODE
#include <qrencode.h>
#include "qrcode-util.h"
#endif
#include "dlfcn-util.h"
#include "errno-util.h"
#include "homectl-recovery-key.h"
#include "libcrypt-util.h"
#include "locale-util.h"
#include "memory-util.h"
#include "modhex.h"
#include "qrcode-util.h"
#include "random-util.h"
#include "strv.h"
#include "terminal-util.h"
@ -140,48 +135,6 @@ static int add_secret(JsonVariant **v, const char *password) {
return 0;
}
static int print_qr_code(const char *secret) {
#if HAVE_QRENCODE
QRcode* (*sym_QRcode_encodeString)(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
void (*sym_QRcode_free)(QRcode *qrcode);
_cleanup_(dlclosep) void *dl = NULL;
QRcode* qr;
int r;
/* If this is not an UTF-8 system or ANSI colors aren't supported/disabled don't print any QR
* codes */
if (!is_locale_utf8() || !colors_enabled())
return -EOPNOTSUPP;
dl = dlopen("libqrencode.so.4", RTLD_LAZY);
if (!dl)
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"QRCODE support is not installed: %s", dlerror());
r = dlsym_many_and_warn(
dl,
LOG_DEBUG,
&sym_QRcode_encodeString, "QRcode_encodeString",
&sym_QRcode_free, "QRcode_free",
NULL);
if (r < 0)
return r;
qr = sym_QRcode_encodeString(secret, 0, QR_ECLEVEL_L, QR_MODE_8, 0);
if (!qr)
return -ENOMEM;
fprintf(stderr, "\nYou may optionally scan the recovery key off screen:\n\n");
write_qrcode(stderr, qr);
fputc('\n', stderr);
sym_QRcode_free(qr);
#endif
return 0;
}
int identity_add_recovery_key(JsonVariant **v) {
_cleanup_(erase_and_freep) char *password = NULL, *hashed = NULL;
int r;
@ -240,7 +193,7 @@ int identity_add_recovery_key(JsonVariant **v) {
"whenever authentication is requested.\n", stderr);
fflush(stderr);
print_qr_code(password);
(void) print_qrcode(stderr, "You may optionally scan the recovery key off screen", password);
return 0;
}

View File

@ -1,97 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include <errno.h>
#include <qrencode.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "alloc-util.h"
#include "dlfcn-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "journal-qrcode.h"
#include "locale-util.h"
#include "macro.h"
#include "qrcode-util.h"
#include "terminal-util.h"
int print_qr_code(
FILE *output,
const char *prefix_text,
const void *seed,
size_t seed_size,
uint64_t start,
uint64_t interval,
const char *hn,
sd_id128_t machine) {
QRcode* (*sym_QRcode_encodeString)(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
void (*sym_QRcode_free)(QRcode *qrcode);
_cleanup_(dlclosep) void *dl = NULL;
_cleanup_free_ char *url = NULL;
_cleanup_fclose_ FILE *f = NULL;
size_t url_size = 0;
QRcode* qr;
int r;
assert(seed);
assert(seed_size > 0);
/* If this is not an UTF-8 system or ANSI colors aren't supported/disabled don't print any QR
* codes */
if (!is_locale_utf8() || !colors_enabled())
return -EOPNOTSUPP;
dl = dlopen("libqrencode.so.4", RTLD_LAZY);
if (!dl)
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"QRCODE support is not installed: %s", dlerror());
r = dlsym_many_and_warn(
dl,
LOG_DEBUG,
&sym_QRcode_encodeString, "QRcode_encodeString",
&sym_QRcode_free, "QRcode_free",
NULL);
if (r < 0)
return r;
f = open_memstream_unlocked(&url, &url_size);
if (!f)
return -ENOMEM;
fputs("fss://", f);
for (size_t i = 0; i < seed_size; i++) {
if (i > 0 && i % 3 == 0)
fputc('-', f);
fprintf(f, "%02x", ((uint8_t*) seed)[i]);
}
fprintf(f, "/%"PRIx64"-%"PRIx64"?machine=" SD_ID128_FORMAT_STR,
start,
interval,
SD_ID128_FORMAT_VAL(machine));
if (hn)
fprintf(f, ";hostname=%s", hn);
r = fflush_and_check(f);
if (r < 0)
return r;
f = safe_fclose(f);
qr = sym_QRcode_encodeString(url, 0, QR_ECLEVEL_L, QR_MODE_8, 1);
if (!qr)
return -ENOMEM;
if (prefix_text)
fputs(prefix_text, output);
write_qrcode(output, qr);
sym_QRcode_free(qr);
return 0;
}

View File

@ -1,9 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <inttypes.h>
#include <stdio.h>
#include "sd-id128.h"
int print_qr_code(FILE *f, const char *prefix_text, const void *seed, size_t seed_size, uint64_t start, uint64_t interval, const char *hn, sd_id128_t machine);

View File

@ -43,7 +43,6 @@
#include "io-util.h"
#include "journal-def.h"
#include "journal-internal.h"
#include "journal-qrcode.h"
#include "journal-util.h"
#include "journal-vacuum.h"
#include "journal-verify.h"
@ -60,6 +59,7 @@
#include "path-util.h"
#include "pcre2-dlopen.h"
#include "pretty-print.h"
#include "qrcode-util.h"
#include "random-util.h"
#include "rlimit-util.h"
#include "set.h"
@ -1779,6 +1779,53 @@ static int add_syslog_identifier(sd_journal *j) {
return 0;
}
static int format_journal_url(
const void *seed,
size_t seed_size,
uint64_t start,
uint64_t interval,
const char *hn,
sd_id128_t machine,
bool full,
char **ret_url) {
_cleanup_free_ char *url = NULL;
_cleanup_fclose_ FILE *f = NULL;
size_t url_size = 0;
int r;
assert(seed);
assert(seed_size > 0);
f = open_memstream_unlocked(&url, &url_size);
if (!f)
return -ENOMEM;
if (full)
fputs("fss://", f);
for (size_t i = 0; i < seed_size; i++) {
if (i > 0 && i % 3 == 0)
fputc('-', f);
fprintf(f, "%02x", ((uint8_t*) seed)[i]);
}
fprintf(f, "/%"PRIx64"-%"PRIx64, start, interval);
if (full) {
fprintf(f, "?machine=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(machine));
if (hn)
fprintf(f, ";hostname=%s", hn);
}
r = fflush_and_check(f);
if (r < 0)
return r;
f = safe_fclose(f);
*ret_url = TAKE_PTR(url);
return 0;
}
static int setup_keys(void) {
#if HAVE_GCRYPT
size_t mpk_size, seed_size, state_size;
@ -1893,7 +1940,11 @@ static int setup_keys(void) {
k = mfree(k);
_cleanup_free_ char *hn = NULL;
_cleanup_free_ char *hn = NULL, *key = NULL;
r = format_journal_url(seed, seed_size, n, arg_interval, hn, machine, false, &key);
if (r < 0)
return r;
if (on_tty()) {
hn = gethostname_malloc();
@ -1925,21 +1976,19 @@ static int setup_keys(void) {
fflush(stderr);
}
for (size_t i = 0; i < seed_size; i++) {
if (i > 0 && i % 3 == 0)
putchar('-');
printf("%02x", ((uint8_t*) seed)[i]);
}
printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
puts(key);
if (on_tty()) {
fprintf(stderr, "%s", ansi_normal());
#if HAVE_QRENCODE
(void) print_qr_code(stderr,
"\nTo transfer the verification key to your phone scan the QR code below:\n",
seed, seed_size,
n, arg_interval,
hn, machine);
_cleanup_free_ char *url = NULL;
r = format_journal_url(seed, seed_size, n, arg_interval, hn, machine, true, &url);
if (r < 0)
return r;
(void) print_qrcode(stderr,
"To transfer the verification key to your phone scan the QR code below",
url);
#endif
}

View File

@ -107,11 +107,6 @@ journalctl_sources = files('''
pcre2-dlopen.h
'''.split())
if conf.get('HAVE_QRENCODE') == 1
journalctl_sources += files('journal-qrcode.c',
'journal-qrcode.h')
endif
install_data('journald.conf',
install_dir : pkgsysconfdir)

View File

@ -195,6 +195,8 @@ shared_sources = files('''
ptyfwd.h
pwquality-util.c
pwquality-util.h
qrcode-util.c
qrcode-util.h
reboot-util.c
reboot-util.h
resize-fs.c
@ -304,13 +306,6 @@ if conf.get('HAVE_PAM') == 1
'''.split())
endif
if conf.get('HAVE_QRENCODE') == 1
shared_sources += files('''
qrcode-util.c
qrcode-util.h
'''.split())
endif
generate_ip_protocol_list = find_program('generate-ip-protocol-list.sh')
ip_protocol_list_txt = custom_target(
'ip-protocol-list.txt',

View File

@ -1,25 +1,27 @@
#include "qrcode-util.h"
#if HAVE_QRENCODE
#include <qrencode.h>
#include "dlfcn-util.h"
#include "locale-util.h"
#include "terminal-util.h"
#define ANSI_WHITE_ON_BLACK "\033[40;37;1m"
static void print_border(FILE *output, unsigned width) {
unsigned x, y;
/* Four rows of border */
for (y = 0; y < 4; y += 2) {
for (unsigned y = 0; y < 4; y += 2) {
fputs(ANSI_WHITE_ON_BLACK, output);
for (x = 0; x < 4 + width + 4; x++)
for (unsigned x = 0; x < 4 + width + 4; x++)
fputs("\342\226\210", output);
fputs(ANSI_NORMAL "\n", output);
}
}
void write_qrcode(FILE *output, QRcode *qr) {
unsigned x, y;
static void write_qrcode(FILE *output, QRcode *qr) {
assert(qr);
if (!output)
@ -27,17 +29,15 @@ void write_qrcode(FILE *output, QRcode *qr) {
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;
for (unsigned y = 0; y < (unsigned) qr->width; y += 2) {
const uint8_t *row1 = qr->data + qr->width * y;
const uint8_t *row2 = row1 + qr->width;
fputs(ANSI_WHITE_ON_BLACK, output);
for (x = 0; x < 4; x++)
for (unsigned x = 0; x < 4; x++)
fputs("\342\226\210", output);
for (x = 0; x < (unsigned) qr->width; x ++) {
for (unsigned x = 0; x < (unsigned) qr->width; x++) {
bool a, b;
a = row1[x] & 1;
@ -53,7 +53,7 @@ void write_qrcode(FILE *output, QRcode *qr) {
fputs("\342\226\210", output);
}
for (x = 0; x < 4; x++)
for (unsigned x = 0; x < 4; x++)
fputs("\342\226\210", output);
fputs(ANSI_NORMAL "\n", output);
}
@ -61,3 +61,45 @@ void write_qrcode(FILE *output, QRcode *qr) {
print_border(output, qr->width);
fflush(output);
}
int print_qrcode(FILE *out, const char *header, const char *string) {
QRcode* (*sym_QRcode_encodeString)(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
void (*sym_QRcode_free)(QRcode *qrcode);
_cleanup_(dlclosep) void *dl = NULL;
QRcode* qr;
int r;
/* If this is not an UTF-8 system or ANSI colors aren't supported/disabled don't print any QR
* codes */
if (!is_locale_utf8() || !colors_enabled())
return -EOPNOTSUPP;
dl = dlopen("libqrencode.so.4", RTLD_LAZY);
if (!dl)
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"QRCODE support is not installed: %s", dlerror());
r = dlsym_many_and_warn(
dl,
LOG_DEBUG,
&sym_QRcode_encodeString, "QRcode_encodeString",
&sym_QRcode_free, "QRcode_free",
NULL);
if (r < 0)
return r;
qr = sym_QRcode_encodeString(string, 0, QR_ECLEVEL_L, QR_MODE_8, 0);
if (!qr)
return -ENOMEM;
if (header)
fprintf(out, "\n%s:\n\n", header);
write_qrcode(out, qr);
fputc('\n', out);
sym_QRcode_free(qr);
return 0;
}
#endif

View File

@ -1,9 +1,13 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <stdio.h>
#include <errno.h>
#if HAVE_QRENCODE
#include <qrencode.h>
#include <stdio.h>
void write_qrcode(FILE *output, QRcode *qr);
int print_qrcode(FILE *out, const char *header, const char *string);
#else
static inline int print_qrcode(FILE *out, const char *header, const char *string) {
return -EOPNOTSUPP;
}
#endif

View File

@ -819,6 +819,10 @@ tests += [
[['src/test/test-psi-util.c'],
[],
[]],
[['src/test/test-qrcode-util.c'],
[libshared],
[libdl]],
]
############################################################

View File

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "locale-util.h"
#include "main-func.h"
#include "qrcode-util.h"
#include "tests.h"
static int run(int argc, char **argv) {
int r;
test_setup_logging(LOG_DEBUG);
assert_se(setenv("SYSTEMD_COLORS", "1", 1) == 0); /* Force the qrcode to be printed */
r = print_qrcode(stdout, "This should say \"TEST\"", "TEST");
if (r == -EOPNOTSUPP)
return log_tests_skipped("not supported");
if (r < 0)
return log_error_errno(r, "Failed to print QR code: %m");
return 0;
}
DEFINE_MAIN_FUNCTION(run);