activating via FIDO2, PKCS#11, TPM2, i.e. mechanisms natively supported by
`systemd-cryptsetup`. Defaults to enabled.
+* `$SYSTEMD_CRYPTSETUP_TOKEN_PATH` – takes a path to a directory in the file
+ system. If specified overrides where libcryptsetup will look for token
+ modules (.so). This is useful for debugging token modules: set this
+ environment variable to the build directory and you are set.
+
Various tools that read passwords from the TTY, such as `systemd-cryptenroll`
and `homectl`:
int (*sym_crypt_header_restore)(struct crypt_device *cd, const char *requested_type, const char *backup_file);
int (*sym_crypt_volume_key_keyring)(struct crypt_device *cd, int enable);
+/* Unfortunately libcryptsetup provides neither an environment variable to redirect where to look for token
+ * modules, nor does it have an API to change the token lookup path at runtime. The maintainers suggest using
+ * ELF interposition instead (see https://gitlab.com/cryptsetup/cryptsetup/-/issues/846). Hence let's do
+ * that: let's interpose libcryptsetup's crypt_token_external_path() function with our own, that *does*
+ * honour an environment variable where to look for tokens. This is tremendously useful for debugging
+ * libcryptsetup tokens: set the environment variable to your build dir and you can easily test token modules
+ * without jumping through various hoops. */
+
+/* Do this only on new enough compilers that actually support the "symver" attribute. Given this is a debug
+ * feature, let's simply not bother on older compilers */
+#if defined __has_attribute
+#if __has_attribute(symver)
+const char *my_crypt_token_external_path(void); /* prototype for our own implementation */
+
+/* We use the "symver" attribute to mark this implementation as the default implementation, and drop the
+ * SD_SHARED namespace we by default attach to our symbols via a version script. */
+__attribute__((symver("crypt_token_external_path@@")))
+_public_ const char *my_crypt_token_external_path(void) {
+ const char *e;
+
+ e = secure_getenv("SYSTEMD_CRYPTSETUP_TOKEN_PATH");
+ if (e)
+ return e;
+
+ /* Now chain invoke the original implementation. */
+ if (cryptsetup_dl) {
+ typeof(crypt_token_external_path) *func;
+ func = (typeof(crypt_token_external_path)*) dlsym(cryptsetup_dl, "crypt_token_external_path");
+ if (func)
+ return func();
+ }
+
+ return NULL;
+}
+#endif
+#endif
+
static void cryptsetup_log_glue(int level, const char *msg, void *usrptr) {
switch (level) {