summaryrefslogtreecommitdiffstats
path: root/src/shared/cryptsetup-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-08-28 21:27:45 +0200
committerLennart Poettering <lennart@poettering.net>2020-09-02 15:04:06 +0200
commit0d12936d9a351660ecaa94361b181d10f92d464f (patch)
tree75fbc8e1fe4d58f99b46b7efad774b52924027c7 /src/shared/cryptsetup-util.c
parentshared: rename crypt-util.c → cryptsetup-util.c (diff)
downloadsystemd-0d12936d9a351660ecaa94361b181d10f92d464f.tar.xz
systemd-0d12936d9a351660ecaa94361b181d10f92d464f.zip
shared: make libcryptsetup dep dlopen
Let's make libcryptsetup a dlopen() style dep for PID 1 (i.e. for RootImage= and stuff), systemd-growfs and systemd-repart. (But leave to be a regulra dep in systemd-cryptsetup, systemd-veritysetup and systemd-homed since for them the libcryptsetup support is not auxiliary but pretty much at the core of what they do.) This should be useful for container images that want systemd in the payload but don't care for the cryptsetup logic since dm-crypt and stuff isn't available in containers anyway. Fixes: #8249
Diffstat (limited to 'src/shared/cryptsetup-util.c')
-rw-r--r--src/shared/cryptsetup-util.c81
1 files changed, 79 insertions, 2 deletions
diff --git a/src/shared/cryptsetup-util.c b/src/shared/cryptsetup-util.c
index 9bc85a1739..9d86478b06 100644
--- a/src/shared/cryptsetup-util.c
+++ b/src/shared/cryptsetup-util.c
@@ -1,10 +1,79 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#if HAVE_LIBCRYPTSETUP
+#include "alloc-util.h"
#include "cryptsetup-util.h"
+#include "dlfcn-util.h"
#include "log.h"
+static void *cryptsetup_dl = NULL;
+
+int (*sym_crypt_activate_by_passphrase)(struct crypt_device *cd, const char *name, int keyslot, const char *passphrase, size_t passphrase_size, uint32_t flags);
+#if HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
+int (*sym_crypt_activate_by_signed_key)(struct crypt_device *cd, const char *name, const char *volume_key, size_t volume_key_size, const char *signature, size_t signature_size, uint32_t flags);
+#endif
+int (*sym_crypt_activate_by_volume_key)(struct crypt_device *cd, const char *name, const char *volume_key, size_t volume_key_size, uint32_t flags);
+int (*sym_crypt_deactivate_by_name)(struct crypt_device *cd, const char *name, uint32_t flags);
+int (*sym_crypt_format)(struct crypt_device *cd, const char *type, const char *cipher, const char *cipher_mode, const char *uuid, const char *volume_key, size_t volume_key_size, void *params);
+void (*sym_crypt_free)(struct crypt_device *cd);
+const char *(*sym_crypt_get_dir)(void);
+int (*sym_crypt_get_verity_info)(struct crypt_device *cd, struct crypt_params_verity *vp);
+int (*sym_crypt_init)(struct crypt_device **cd, const char *device);
+int (*sym_crypt_init_by_name)(struct crypt_device **cd, const char *name);
+int (*sym_crypt_keyslot_add_by_volume_key)(struct crypt_device *cd, int keyslot, const char *volume_key, size_t volume_key_size, const char *passphrase, size_t passphrase_size);
+int (*sym_crypt_load)(struct crypt_device *cd, const char *requested_type, void *params);
+int (*sym_crypt_resize)(struct crypt_device *cd, const char *name, uint64_t new_size);
+int (*sym_crypt_set_data_device)(struct crypt_device *cd, const char *device);
+void (*sym_crypt_set_debug_level)(int level);
+void (*sym_crypt_set_log_callback)(struct crypt_device *cd, void (*log)(int level, const char *msg, void *usrptr), void *usrptr);
+int (*sym_crypt_volume_key_get)(struct crypt_device *cd, int keyslot, char *volume_key, size_t *volume_key_size, const char *passphrase, size_t passphrase_size);
+
+int dlopen_cryptsetup(void) {
+ _cleanup_(dlclosep) void *dl = NULL;
+ int r;
+
+ if (cryptsetup_dl)
+ return 0; /* Already loaded */
+
+ dl = dlopen("libcryptsetup.so.12", RTLD_LAZY);
+ if (!dl)
+ return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
+ "libcryptsetup support is not installed: %s", dlerror());
+
+ r = dlsym_many_and_warn(
+ dl,
+ LOG_DEBUG,
+ &sym_crypt_activate_by_passphrase, "crypt_activate_by_passphrase",
+#if HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
+ &sym_crypt_activate_by_signed_key, "crypt_activate_by_signed_key",
+#endif
+ &sym_crypt_activate_by_volume_key, "crypt_activate_by_volume_key",
+ &sym_crypt_deactivate_by_name, "crypt_deactivate_by_name",
+ &sym_crypt_format, "crypt_format",
+ &sym_crypt_free, "crypt_free",
+ &sym_crypt_get_dir, "crypt_get_dir",
+ &sym_crypt_get_verity_info, "crypt_get_verity_info",
+ &sym_crypt_init, "crypt_init",
+ &sym_crypt_init_by_name, "crypt_init_by_name",
+ &sym_crypt_keyslot_add_by_volume_key, "crypt_keyslot_add_by_volume_key",
+ &sym_crypt_load, "crypt_load",
+ &sym_crypt_resize, "crypt_resize",
+ &sym_crypt_set_data_device, "crypt_set_data_device",
+ &sym_crypt_set_debug_level, "crypt_set_debug_level",
+ &sym_crypt_set_log_callback, "crypt_set_log_callback",
+ &sym_crypt_volume_key_get, "crypt_volume_key_get",
+ NULL);
+ if (r < 0)
+ return r;
+
+ /* Note that we never release the reference here, because there's no real reason to, after all this
+ * was traditionally a regular shared library dependency which lives forever too. */
+ cryptsetup_dl = TAKE_PTR(dl);
+ return 1;
+}
+
static void cryptsetup_log_glue(int level, const char *msg, void *usrptr) {
+
switch (level) {
case CRYPT_LOG_NORMAL:
level = LOG_NOTICE;
@@ -27,8 +96,16 @@ static void cryptsetup_log_glue(int level, const char *msg, void *usrptr) {
}
void cryptsetup_enable_logging(struct crypt_device *cd) {
- crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
- crypt_set_debug_level(DEBUG_LOGGING ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
+ if (!cd)
+ return;
+
+ if (dlopen_cryptsetup() < 0) /* If this fails, let's gracefully ignore the issue, this is just debug
+ * logging after all, and if this failed we already generated a debug
+ * log message that should help to track things down. */
+ return;
+
+ sym_crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
+ sym_crypt_set_debug_level(DEBUG_LOGGING ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
}
#endif