]> git.proxmox.com Git - systemd.git/commitdiff
Enable p11kit
authorLuca Boccassi <bluca@debian.org>
Mon, 19 Dec 2022 16:19:37 +0000 (17:19 +0100)
committerLuca Boccassi <bluca@debian.org>
Tue, 20 Dec 2022 21:00:40 +0000 (22:00 +0100)
Backport patch to dlopen-ify p11kit support and enable it.

Closes: #1023635
debian/control
debian/patches/p11kit-switch-to-dlopen.patch [new file with mode: 0644]
debian/patches/series
debian/rules
debian/tests/control

index faf73536c6ea8fedf2a28cb8e2090cbc97d953e3..a8876d04dbeb607c6a77948a9f67542c9b28e491 100644 (file)
@@ -56,6 +56,7 @@ Build-Depends: debhelper-compat (= 13),
                libzstd-dev (>= 1.4.0),
                libtss2-dev <!stage1>,
                libfido2-dev <!stage1>,
+               libp11-kit-dev <!stage1>,
                libssl-dev <!stage1>,
                libqrencode-dev <!stage1>,
                linux-base <!nocheck>,
@@ -84,6 +85,7 @@ Suggests: systemd-container,
           systemd-boot,
           systemd-resolved,
           libfido2-1,
+          libp11-kit0,
           libqrencode4,
           libtss2-esys-3.0.2-0,
           libtss2-mu0,
diff --git a/debian/patches/p11kit-switch-to-dlopen.patch b/debian/patches/p11kit-switch-to-dlopen.patch
new file mode 100644 (file)
index 0000000..8669ff2
--- /dev/null
@@ -0,0 +1,743 @@
+From: Luca Boccassi <bluca@debian.org>
+Date: Sat, 17 Dec 2022 01:33:46 +0000
+Subject: p11kit: switch to dlopen()
+
+---
+ meson.build               |   2 +
+ src/shared/meson.build    |   2 +-
+ src/shared/pkcs11-util.c  | 215 ++++++++++++++++++++++++++++++++++------------
+ src/shared/pkcs11-util.h  |  28 +++++-
+ src/test/meson.build      |   4 +-
+ src/test/test-dlopen-so.c |   5 ++
+ test/test-functions       |   6 +-
+ 7 files changed, 202 insertions(+), 60 deletions(-)
+
+diff --git a/meson.build b/meson.build
+index 3570494..b7768d9 100644
+--- a/meson.build
++++ b/meson.build
+@@ -1445,8 +1445,10 @@ if want_p11kit != 'false' and not skip_deps
+                                version : '>= 0.23.3',
+                                required : want_p11kit == 'true')
+         have = libp11kit.found()
++        libp11kit_cflags = libp11kit.partial_dependency(includes: true, compile_args: true)
+ else
+         have = false
++        libp11kit_cflags = []
+         libp11kit = []
+ endif
+ conf.set10('HAVE_P11KIT', have)
+diff --git a/src/shared/meson.build b/src/shared/meson.build
+index 9e11e13..0fb2afd 100644
+--- a/src/shared/meson.build
++++ b/src/shared/meson.build
+@@ -459,7 +459,7 @@ libshared_deps = [threads,
+                   liblz4,
+                   libmount,
+                   libopenssl,
+-                  libp11kit,
++                  libp11kit_cflags,
+                   libpam,
+                   librt,
+                   libseccomp,
+diff --git a/src/shared/pkcs11-util.c b/src/shared/pkcs11-util.c
+index f5f6617..4d7edf8 100644
+--- a/src/shared/pkcs11-util.c
++++ b/src/shared/pkcs11-util.c
+@@ -3,6 +3,7 @@
+ #include <fcntl.h>
+ #include "ask-password-api.h"
++#include "dlfcn-util.h"
+ #include "env-util.h"
+ #include "escape.h"
+ #include "fd-util.h"
+@@ -40,17 +41,59 @@ bool pkcs11_uri_valid(const char *uri) {
+ #if HAVE_P11KIT
++static void *p11kit_dl = NULL;
++
++char *(*sym_p11_kit_module_get_name)(CK_FUNCTION_LIST *module);
++void (*sym_p11_kit_modules_finalize_and_release)(CK_FUNCTION_LIST **modules);
++CK_FUNCTION_LIST **(*sym_p11_kit_modules_load_and_initialize)(int flags);
++const char *(*sym_p11_kit_strerror)(CK_RV rv);
++int (*sym_p11_kit_uri_format)(P11KitUri *uri, P11KitUriType uri_type, char **string);
++void (*sym_p11_kit_uri_free)(P11KitUri *uri);
++CK_ATTRIBUTE_PTR (*sym_p11_kit_uri_get_attributes)(P11KitUri *uri, CK_ULONG *n_attrs);
++CK_INFO_PTR (*sym_p11_kit_uri_get_module_info)(P11KitUri *uri);
++CK_SLOT_INFO_PTR (*sym_p11_kit_uri_get_slot_info)(P11KitUri *uri);
++CK_TOKEN_INFO_PTR (*sym_p11_kit_uri_get_token_info)(P11KitUri *uri);
++int (*sym_p11_kit_uri_match_token_info)(const P11KitUri *uri, const CK_TOKEN_INFO *token_info);
++const char *(*sym_p11_kit_uri_message)(int code);
++P11KitUri *(*sym_p11_kit_uri_new)(void);
++int (*sym_p11_kit_uri_parse)(const char *string, P11KitUriType uri_type, P11KitUri *uri);
++
++int dlopen_p11kit(void) {
++        return dlopen_many_sym_or_warn(
++                        &p11kit_dl,
++                        "libp11-kit.so.0", LOG_DEBUG,
++                        DLSYM_ARG(p11_kit_module_get_name),
++                        DLSYM_ARG(p11_kit_modules_finalize_and_release),
++                        DLSYM_ARG(p11_kit_modules_load_and_initialize),
++                        DLSYM_ARG(p11_kit_strerror),
++                        DLSYM_ARG(p11_kit_uri_format),
++                        DLSYM_ARG(p11_kit_uri_free),
++                        DLSYM_ARG(p11_kit_uri_get_attributes),
++                        DLSYM_ARG(p11_kit_uri_get_module_info),
++                        DLSYM_ARG(p11_kit_uri_get_slot_info),
++                        DLSYM_ARG(p11_kit_uri_get_token_info),
++                        DLSYM_ARG(p11_kit_uri_match_token_info),
++                        DLSYM_ARG(p11_kit_uri_message),
++                        DLSYM_ARG(p11_kit_uri_new),
++                        DLSYM_ARG(p11_kit_uri_parse));
++}
++
+ int uri_from_string(const char *p, P11KitUri **ret) {
+-        _cleanup_(p11_kit_uri_freep) P11KitUri *uri = NULL;
++        _cleanup_(sym_p11_kit_uri_freep) P11KitUri *uri = NULL;
++        int r;
+         assert(p);
+         assert(ret);
+-        uri = p11_kit_uri_new();
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
++        uri = sym_p11_kit_uri_new();
+         if (!uri)
+                 return -ENOMEM;
+-        if (p11_kit_uri_parse(p, P11_KIT_URI_FOR_ANY, uri) != P11_KIT_URI_OK)
++        if (sym_p11_kit_uri_parse(p, P11_KIT_URI_FOR_ANY, uri) != P11_KIT_URI_OK)
+                 return -EINVAL;
+         *ret = TAKE_PTR(uri);
+@@ -62,11 +105,14 @@ P11KitUri *uri_from_module_info(const CK_INFO *info) {
+         assert(info);
+-        uri = p11_kit_uri_new();
++        if (dlopen_p11kit() < 0)
++                return NULL;
++
++        uri = sym_p11_kit_uri_new();
+         if (!uri)
+                 return NULL;
+-        *p11_kit_uri_get_module_info(uri) = *info;
++        *sym_p11_kit_uri_get_module_info(uri) = *info;
+         return uri;
+ }
+@@ -75,11 +121,14 @@ P11KitUri *uri_from_slot_info(const CK_SLOT_INFO *slot_info) {
+         assert(slot_info);
+-        uri = p11_kit_uri_new();
++        if (dlopen_p11kit() < 0)
++                return NULL;
++
++        uri = sym_p11_kit_uri_new();
+         if (!uri)
+                 return NULL;
+-        *p11_kit_uri_get_slot_info(uri) = *slot_info;
++        *sym_p11_kit_uri_get_slot_info(uri) = *slot_info;
+         return uri;
+ }
+@@ -88,11 +137,14 @@ P11KitUri *uri_from_token_info(const CK_TOKEN_INFO *token_info) {
+         assert(token_info);
+-        uri = p11_kit_uri_new();
++        if (dlopen_p11kit() < 0)
++                return NULL;
++
++        uri = sym_p11_kit_uri_new();
+         if (!uri)
+                 return NULL;
+-        *p11_kit_uri_get_token_info(uri) = *token_info;
++        *sym_p11_kit_uri_get_token_info(uri) = *token_info;
+         return uri;
+ }
+@@ -184,15 +236,20 @@ int pkcs11_token_login_by_pin(
+                 size_t pin_size) {
+         CK_RV rv;
++        int r;
+         assert(m);
+         assert(token_info);
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
+         if (FLAGS_SET(token_info->flags, CKF_PROTECTED_AUTHENTICATION_PATH)) {
+                 rv = m->C_Login(session, CKU_USER, NULL, 0);
+                 if (rv != CKR_OK)
+                         return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                               "Failed to log into security token '%s': %s", token_label, p11_kit_strerror(rv));
++                                               "Failed to log into security token '%s': %s", token_label, sym_p11_kit_strerror(rv));
+                 log_info("Successfully logged into security token '%s' via protected authentication path.", token_label);
+                 return 0;
+@@ -217,7 +274,7 @@ int pkcs11_token_login_by_pin(
+                                        "PIN has been locked, please reset PIN of security token '%s'.", token_label);
+         if (!IN_SET(rv, CKR_PIN_INCORRECT, CKR_PIN_LEN_RANGE))
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to log into security token '%s': %s", token_label, p11_kit_strerror(rv));
++                                       "Failed to log into security token '%s': %s", token_label, sym_p11_kit_strerror(rv));
+         return log_notice_errno(SYNTHETIC_ERRNO(ENOLCK),
+                                 "PIN for token '%s' is incorrect, please try again.",
+@@ -238,7 +295,7 @@ int pkcs11_token_login(
+                 char **ret_used_pin) {
+         _cleanup_free_ char *token_uri_string = NULL, *token_uri_escaped = NULL, *id = NULL, *token_label = NULL;
+-        _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL;
++        _cleanup_(sym_p11_kit_uri_freep) P11KitUri *token_uri = NULL;
+         CK_TOKEN_INFO updated_token_info;
+         int uri_result, r;
+         CK_RV rv;
+@@ -246,6 +303,10 @@ int pkcs11_token_login(
+         assert(m);
+         assert(token_info);
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
+         token_label = pkcs11_token_label(token_info);
+         if (!token_label)
+                 return log_oom();
+@@ -254,9 +315,9 @@ int pkcs11_token_login(
+         if (!token_uri)
+                 return log_oom();
+-        uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string);
++        uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string);
+         if (uri_result != P11_KIT_URI_OK)
+-                return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result));
++                return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result));
+         r = pkcs11_token_login_by_pin(m, session, token_info, token_label, /* pin= */ NULL, 0);
+         if (r == 0 && ret_used_pin)
+@@ -335,7 +396,7 @@ int pkcs11_token_login(
+                         if (rv != CKR_OK)
+                                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+                                                        "Failed to acquire updated security token information for slot %lu: %s",
+-                                                       slotid, p11_kit_strerror(rv));
++                                                       slotid, sym_p11_kit_strerror(rv));
+                         token_info = &updated_token_info;
+                 }
+@@ -356,12 +417,17 @@ int pkcs11_token_find_x509_certificate(
+         CK_ATTRIBUTE *attributes = NULL;
+         CK_OBJECT_HANDLE objects[2];
+         CK_RV rv, rv2;
++        int r;
+         assert(m);
+         assert(search_uri);
+         assert(ret_object);
+-        attributes = p11_kit_uri_get_attributes(search_uri, &n_attributes);
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
++        attributes = sym_p11_kit_uri_get_attributes(search_uri, &n_attributes);
+         for (a = 0; a < n_attributes; a++) {
+                 /* We use the URI's included match attributes, but make them more strict. This allows users
+@@ -434,16 +500,16 @@ int pkcs11_token_find_x509_certificate(
+         rv = m->C_FindObjectsInit(session, attributes, n_attributes);
+         if (rv != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to initialize object find call: %s", p11_kit_strerror(rv));
++                                       "Failed to initialize object find call: %s", sym_p11_kit_strerror(rv));
+         rv = m->C_FindObjects(session, objects, ELEMENTSOF(objects), &n_objects);
+         rv2 = m->C_FindObjectsFinal(session);
+         if (rv != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to find objects: %s", p11_kit_strerror(rv));
++                                       "Failed to find objects: %s", sym_p11_kit_strerror(rv));
+         if (rv2 != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to finalize object find call: %s", p11_kit_strerror(rv));
++                                       "Failed to finalize object find call: %s", sym_p11_kit_strerror(rv));
+         if (n_objects == 0)
+                 return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
+                                        "Failed to find selected X509 certificate on token.");
+@@ -471,11 +537,16 @@ int pkcs11_token_read_x509_certificate(
+         _cleanup_(X509_freep) X509 *x509 = NULL;
+         X509_NAME *name = NULL;
+         const unsigned char *p;
++        int r;
++
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
+         rv = m->C_GetAttributeValue(session, object, &attribute, 1);
+         if (rv != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to read X.509 certificate size off token: %s", p11_kit_strerror(rv));
++                                       "Failed to read X.509 certificate size off token: %s", sym_p11_kit_strerror(rv));
+         buffer = malloc(attribute.ulValueLen);
+         if (!buffer)
+@@ -486,7 +557,7 @@ int pkcs11_token_read_x509_certificate(
+         rv = m->C_GetAttributeValue(session, object, &attribute, 1);
+         if (rv != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to read X.509 certificate data off token: %s", p11_kit_strerror(rv));
++                                       "Failed to read X.509 certificate data off token: %s", sym_p11_kit_strerror(rv));
+         p = attribute.pValue;
+         x509 = d2i_X509(NULL, &p, attribute.ulValueLen);
+@@ -520,12 +591,17 @@ int pkcs11_token_find_private_key(
+         CK_ATTRIBUTE *attributes = NULL;
+         CK_OBJECT_HANDLE objects[2];
+         CK_RV rv, rv2;
++        int r;
+         assert(m);
+         assert(search_uri);
+         assert(ret_object);
+-        attributes = p11_kit_uri_get_attributes(search_uri, &n_attributes);
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
++        attributes = sym_p11_kit_uri_get_attributes(search_uri, &n_attributes);
+         for (a = 0; a < n_attributes; a++) {
+                 /* We use the URI's included match attributes, but make them more strict. This allows users
+@@ -624,16 +700,16 @@ int pkcs11_token_find_private_key(
+         rv = m->C_FindObjectsInit(session, attributes, n_attributes);
+         if (rv != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to initialize object find call: %s", p11_kit_strerror(rv));
++                                       "Failed to initialize object find call: %s", sym_p11_kit_strerror(rv));
+         rv = m->C_FindObjects(session, objects, ELEMENTSOF(objects), &n_objects);
+         rv2 = m->C_FindObjectsFinal(session);
+         if (rv != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to find objects: %s", p11_kit_strerror(rv));
++                                       "Failed to find objects: %s", sym_p11_kit_strerror(rv));
+         if (rv2 != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to finalize object find call: %s", p11_kit_strerror(rv));
++                                       "Failed to finalize object find call: %s", sym_p11_kit_strerror(rv));
+         if (n_objects == 0)
+                 return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
+                                        "Failed to find selected private key suitable for decryption on token.");
+@@ -660,6 +736,7 @@ int pkcs11_token_decrypt_data(
+         _cleanup_(erase_and_freep) CK_BYTE *dbuffer = NULL;
+         CK_ULONG dbuffer_size = 0;
+         CK_RV rv;
++        int r;
+         assert(m);
+         assert(encrypted_data);
+@@ -667,10 +744,14 @@ int pkcs11_token_decrypt_data(
+         assert(ret_decrypted_data);
+         assert(ret_decrypted_data_size);
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
+         rv = m->C_DecryptInit(session, (CK_MECHANISM*) &mechanism, object);
+         if (rv != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to initialize decryption on security token: %s", p11_kit_strerror(rv));
++                                       "Failed to initialize decryption on security token: %s", sym_p11_kit_strerror(rv));
+         dbuffer_size = encrypted_data_size; /* Start with something reasonable */
+         dbuffer = malloc(dbuffer_size);
+@@ -689,7 +770,7 @@ int pkcs11_token_decrypt_data(
+         }
+         if (rv != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to decrypt key on security token: %s", p11_kit_strerror(rv));
++                                       "Failed to decrypt key on security token: %s", sym_p11_kit_strerror(rv));
+         log_info("Successfully decrypted key with security token.");
+@@ -709,6 +790,10 @@ int pkcs11_token_acquire_rng(
+         assert(m);
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
+         /* While we are at it, let's read some RNG data from the PKCS#11 token and pass it to the kernel
+          * random pool. This should be cheap if we are talking to the device already. Note that we don't
+          * credit any entropy, since we don't know about the quality of the pkcs#11 token's RNG. Why bother
+@@ -725,7 +810,7 @@ int pkcs11_token_acquire_rng(
+         rv = m->C_GenerateRandom(session, buffer, rps);
+         if (rv != CKR_OK)
+                 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
+-                                       "Failed to generate RNG data on security token: %s", p11_kit_strerror(rv));
++                                       "Failed to generate RNG data on security token: %s", sym_p11_kit_strerror(rv));
+         r = random_write_entropy(-1, buffer, rps, false);
+         if (r < 0)
+@@ -761,7 +846,7 @@ static int token_process(
+         rv = m->C_OpenSession(slotid, CKF_SERIAL_SESSION, NULL, NULL, &session);
+         if (rv != CKR_OK)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
+-                                       "Failed to create session for security token '%s': %s", token_label, p11_kit_strerror(rv));
++                                       "Failed to create session for security token '%s': %s", token_label, sym_p11_kit_strerror(rv));
+         if (callback)
+                 r = callback(m, session, slotid, slot_info, token_info, search_uri, userdata);
+@@ -770,7 +855,7 @@ static int token_process(
+         rv = m->C_CloseSession(session);
+         if (rv != CKR_OK)
+-                log_warning("Failed to close session on PKCS#11 token, ignoring: %s", p11_kit_strerror(rv));
++                log_warning("Failed to close session on PKCS#11 token, ignoring: %s", sym_p11_kit_strerror(rv));
+         return r;
+ }
+@@ -782,21 +867,25 @@ static int slot_process(
+                 pkcs11_find_token_callback_t callback,
+                 void *userdata) {
+-        _cleanup_(p11_kit_uri_freep) P11KitUri* slot_uri = NULL, *token_uri = NULL;
++        _cleanup_(sym_p11_kit_uri_freep) P11KitUri* slot_uri = NULL, *token_uri = NULL;
+         _cleanup_free_ char *token_uri_string = NULL;
+         CK_TOKEN_INFO token_info;
+         CK_SLOT_INFO slot_info;
+-        int uri_result;
++        int uri_result, r;
+         CK_RV rv;
+         assert(m);
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
+         /* We return -EAGAIN for all failures we can attribute to a specific slot in some way, so that the
+          * caller might try other slots before giving up. */
+         rv = m->C_GetSlotInfo(slotid, &slot_info);
+         if (rv != CKR_OK) {
+-                log_warning("Failed to acquire slot info for slot %lu, ignoring slot: %s", slotid, p11_kit_strerror(rv));
++                log_warning("Failed to acquire slot info for slot %lu, ignoring slot: %s", slotid, sym_p11_kit_strerror(rv));
+                 return -EAGAIN;
+         }
+@@ -807,9 +896,9 @@ static int slot_process(
+         if (DEBUG_LOGGING) {
+                 _cleanup_free_ char *slot_uri_string = NULL;
+-                uri_result = p11_kit_uri_format(slot_uri, P11_KIT_URI_FOR_ANY, &slot_uri_string);
++                uri_result = sym_p11_kit_uri_format(slot_uri, P11_KIT_URI_FOR_ANY, &slot_uri_string);
+                 if (uri_result != P11_KIT_URI_OK) {
+-                        log_warning("Failed to format slot URI, ignoring slot: %s", p11_kit_uri_message(uri_result));
++                        log_warning("Failed to format slot URI, ignoring slot: %s", sym_p11_kit_uri_message(uri_result));
+                         return -EAGAIN;
+                 }
+@@ -821,7 +910,7 @@ static int slot_process(
+                 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
+                                        "Token not present in slot, ignoring.");
+         } else if (rv != CKR_OK) {
+-                log_warning("Failed to acquire token info for slot %lu, ignoring slot: %s", slotid, p11_kit_strerror(rv));
++                log_warning("Failed to acquire token info for slot %lu, ignoring slot: %s", slotid, sym_p11_kit_strerror(rv));
+                 return -EAGAIN;
+         }
+@@ -829,13 +918,13 @@ static int slot_process(
+         if (!token_uri)
+                 return log_oom();
+-        uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string);
++        uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string);
+         if (uri_result != P11_KIT_URI_OK) {
+-                log_warning("Failed to format slot URI: %s", p11_kit_uri_message(uri_result));
++                log_warning("Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result));
+                 return -EAGAIN;
+         }
+-        if (search_uri && !p11_kit_uri_match_token_info(search_uri, &token_info))
++        if (search_uri && !sym_p11_kit_uri_match_token_info(search_uri, &token_info))
+                 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
+                                        "Found non-matching token with URI %s.",
+                                        token_uri_string);
+@@ -858,8 +947,8 @@ static int module_process(
+                 pkcs11_find_token_callback_t callback,
+                 void *userdata) {
++        _cleanup_(sym_p11_kit_uri_freep) P11KitUri* module_uri = NULL;
+         _cleanup_free_ char *name = NULL, *module_uri_string = NULL;
+-        _cleanup_(p11_kit_uri_freep) P11KitUri* module_uri = NULL;
+         _cleanup_free_ CK_SLOT_ID *slotids = NULL;
+         CK_ULONG n_slotids = 0;
+         int uri_result;
+@@ -870,11 +959,15 @@ static int module_process(
+         assert(m);
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
+         /* We ignore most errors from modules here, in order to skip over faulty modules: one faulty module
+          * should not have the effect that we don't try the others anymore. We indicate such per-module
+          * failures with -EAGAIN, which let's the caller try the next module. */
+-        name = p11_kit_module_get_name(m);
++        name = sym_p11_kit_module_get_name(m);
+         if (!name)
+                 return log_oom();
+@@ -882,7 +975,7 @@ static int module_process(
+         rv = m->C_GetInfo(&info);
+         if (rv != CKR_OK) {
+-                log_warning("Failed to get info on PKCS#11 module, ignoring module: %s", p11_kit_strerror(rv));
++                log_warning("Failed to get info on PKCS#11 module, ignoring module: %s", sym_p11_kit_strerror(rv));
+                 return -EAGAIN;
+         }
+@@ -890,9 +983,9 @@ static int module_process(
+         if (!module_uri)
+                 return log_oom();
+-        uri_result = p11_kit_uri_format(module_uri, P11_KIT_URI_FOR_ANY, &module_uri_string);
++        uri_result = sym_p11_kit_uri_format(module_uri, P11_KIT_URI_FOR_ANY, &module_uri_string);
+         if (uri_result != P11_KIT_URI_OK) {
+-                log_warning("Failed to format module URI, ignoring module: %s", p11_kit_uri_message(uri_result));
++                log_warning("Failed to format module URI, ignoring module: %s", sym_p11_kit_uri_message(uri_result));
+                 return -EAGAIN;
+         }
+@@ -900,7 +993,7 @@ static int module_process(
+         rv = pkcs11_get_slot_list_malloc(m, &slotids, &n_slotids);
+         if (rv != CKR_OK) {
+-                log_warning("Failed to get slot list, ignoring module: %s", p11_kit_strerror(rv));
++                log_warning("Failed to get slot list, ignoring module: %s", sym_p11_kit_strerror(rv));
+                 return -EAGAIN;
+         }
+         if (n_slotids == 0)
+@@ -926,10 +1019,14 @@ int pkcs11_find_token(
+                 pkcs11_find_token_callback_t callback,
+                 void *userdata) {
+-        _cleanup_(p11_kit_modules_finalize_and_releasep) CK_FUNCTION_LIST **modules = NULL;
+-        _cleanup_(p11_kit_uri_freep) P11KitUri *search_uri = NULL;
++        _cleanup_(sym_p11_kit_modules_finalize_and_releasep) CK_FUNCTION_LIST **modules = NULL;
++        _cleanup_(sym_p11_kit_uri_freep) P11KitUri *search_uri = NULL;
+         int r;
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
+         /* Execute the specified callback for each matching token found. If nothing is found returns
+          * -EAGAIN. Logs about all errors, except for EAGAIN, which the caller has to log about. */
+@@ -939,7 +1036,7 @@ int pkcs11_find_token(
+                         return log_error_errno(r, "Failed to parse PKCS#11 URI '%s': %m", pkcs11_uri);
+         }
+-        modules = p11_kit_modules_load_and_initialize(0);
++        modules = sym_p11_kit_modules_load_and_initialize(0);
+         if (!modules)
+                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize pkcs11 modules");
+@@ -1053,13 +1150,17 @@ static int list_callback(
+                 void *userdata) {
+         _cleanup_free_ char *token_uri_string = NULL, *token_label = NULL, *token_manufacturer_id = NULL, *token_model = NULL;
+-        _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL;
++        _cleanup_(sym_p11_kit_uri_freep) P11KitUri *token_uri = NULL;
+         Table *t = userdata;
+         int uri_result, r;
+         assert(slot_info);
+         assert(token_info);
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
+         /* We only care about hardware devices here with a token inserted. Let's filter everything else
+          * out. (Note that the user can explicitly specify non-hardware tokens if they like, but during
+          * enumeration we'll filter those, since software tokens are typically the system certificate store
+@@ -1083,9 +1184,9 @@ static int list_callback(
+         if (!token_uri)
+                 return log_oom();
+-        uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string);
++        uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string);
+         if (uri_result != P11_KIT_URI_OK)
+-                return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result));
++                return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result));
+         r = table_add_many(
+                         t,
+@@ -1139,13 +1240,17 @@ static int auto_callback(
+                 P11KitUri *uri,
+                 void *userdata) {
+-        _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL;
++        _cleanup_(sym_p11_kit_uri_freep) P11KitUri *token_uri = NULL;
+         char **t = userdata;
+-        int uri_result;
++        int uri_result, r;
+         assert(slot_info);
+         assert(token_info);
++        r = dlopen_p11kit();
++        if (r < 0)
++                return r;
++
+         if (!FLAGS_SET(token_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT))
+                 return -EAGAIN;
+@@ -1157,9 +1262,9 @@ static int auto_callback(
+         if (!token_uri)
+                 return log_oom();
+-        uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, t);
++        uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, t);
+         if (uri_result != P11_KIT_URI_OK)
+-                return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result));
++                return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result));
+         return 0;
+ }
+diff --git a/src/shared/pkcs11-util.h b/src/shared/pkcs11-util.h
+index f8195d7..ac2ee08 100644
+--- a/src/shared/pkcs11-util.h
++++ b/src/shared/pkcs11-util.h
+@@ -15,14 +15,30 @@
+ bool pkcs11_uri_valid(const char *uri);
+ #if HAVE_P11KIT
++
++extern char *(*sym_p11_kit_module_get_name)(CK_FUNCTION_LIST *module);
++extern void (*sym_p11_kit_modules_finalize_and_release)(CK_FUNCTION_LIST **modules);
++extern CK_FUNCTION_LIST **(*sym_p11_kit_modules_load_and_initialize)(int flags);
++extern const char *(*sym_p11_kit_strerror)(CK_RV rv);
++extern int (*sym_p11_kit_uri_format)(P11KitUri *uri, P11KitUriType uri_type, char **string);
++extern void (*sym_p11_kit_uri_free)(P11KitUri *uri);
++extern CK_ATTRIBUTE_PTR (*sym_p11_kit_uri_get_attributes)(P11KitUri *uri, CK_ULONG *n_attrs);
++extern CK_INFO_PTR (*sym_p11_kit_uri_get_module_info)(P11KitUri *uri);
++extern CK_SLOT_INFO_PTR (*sym_p11_kit_uri_get_slot_info)(P11KitUri *uri);
++extern CK_TOKEN_INFO_PTR (*sym_p11_kit_uri_get_token_info)(P11KitUri *uri);
++extern int (*sym_p11_kit_uri_match_token_info)(const P11KitUri *uri, const CK_TOKEN_INFO *token_info);
++extern const char *(*sym_p11_kit_uri_message)(int code);
++extern P11KitUri *(*sym_p11_kit_uri_new)(void);
++extern int (*sym_p11_kit_uri_parse)(const char *string, P11KitUriType uri_type, P11KitUri *uri);
++
+ int uri_from_string(const char *p, P11KitUri **ret);
+ P11KitUri *uri_from_module_info(const CK_INFO *info);
+ P11KitUri *uri_from_slot_info(const CK_SLOT_INFO *slot_info);
+ P11KitUri *uri_from_token_info(const CK_TOKEN_INFO *token_info);
+-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(P11KitUri*, p11_kit_uri_free, NULL);
+-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(CK_FUNCTION_LIST**, p11_kit_modules_finalize_and_release, NULL);
++DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(P11KitUri*, sym_p11_kit_uri_free, NULL);
++DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(CK_FUNCTION_LIST**, sym_p11_kit_modules_finalize_and_release, NULL);
+ CK_RV pkcs11_get_slot_list_malloc(CK_FUNCTION_LIST *m, CK_SLOT_ID **ret_slotids, CK_ULONG *ret_n_slotids);
+@@ -72,6 +88,14 @@ int pkcs11_crypt_device_callback(
+                 P11KitUri *uri,
+                 void *userdata);
++int dlopen_p11kit(void);
++
++#else
++
++static inline int dlopen_p11kit(void) {
++        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "p11kit support is not compiled in.");
++}
++
+ #endif
+ typedef struct {
+diff --git a/src/test/meson.build b/src/test/meson.build
+index 2a4dfe2..082566b 100644
+--- a/src/test/meson.build
++++ b/src/test/meson.build
+@@ -74,7 +74,9 @@ tests += [
+          [],
+          core_includes],
+-        [files('test-dlopen-so.c')],
++        [files('test-dlopen-so.c'),
++         [],
++         libp11kit_cflags],
+         [files('test-job-type.c'),
+          [libcore,
+diff --git a/src/test/test-dlopen-so.c b/src/test/test-dlopen-so.c
+index 85dbb81..55728c2 100644
+--- a/src/test/test-dlopen-so.c
++++ b/src/test/test-dlopen-so.c
+@@ -11,6 +11,7 @@
+ #include "macro.h"
+ #include "main-func.h"
+ #include "pcre2-util.h"
++#include "pkcs11-util.h"
+ #include "pwquality-util.h"
+ #include "qrcode-util.h"
+ #include "tests.h"
+@@ -60,6 +61,10 @@ static int run(int argc, char **argv) {
+         assert_se(dlopen_pcre2() >= 0);
+ #endif
++#if HAVE_P11KIT
++        assert_se(dlopen_p11kit() >= 0);
++#endif
++
+         return 0;
+ }
+diff --git a/test/test-functions b/test/test-functions
+index 194cd68..2a6a494 100644
+--- a/test/test-functions
++++ b/test/test-functions
+@@ -1275,7 +1275,7 @@ install_missing_libraries() {
+     local lib path
+     # A number of dependencies is now optional via dlopen, so the install
+     # script will not pick them up, since it looks at linkage.
+-    for lib in libcryptsetup libidn libidn2 pwquality libqrencode tss2-esys tss2-rc tss2-mu tss2-tcti-device libfido2 libbpf libelf libdw xkbcommon; do
++    for lib in libcryptsetup libidn libidn2 pwquality libqrencode tss2-esys tss2-rc tss2-mu tss2-tcti-device libfido2 libbpf libelf libdw xkbcommon p11-kit-1; do
+         ddebug "Searching for $lib via pkg-config"
+         if pkg-config --exists "$lib"; then
+                 path="$(pkg-config --variable=libdir "$lib")"
+@@ -1287,6 +1287,10 @@ install_missing_libraries() {
+                 if ! [[ ${lib} =~ ^lib ]]; then
+                         lib="lib${lib}"
+                 fi
++                # p11-kit-1's .so doesn't have the API level in the name
++                if [[ ${lib} =~ p11-kit-1$ ]]; then
++                        lib="libp11-kit"
++                fi
+                 # Some pkg-config files are broken and give out the wrong paths
+                 # (eg: libcryptsetup), so just ignore them
+                 inst_libs "${path}/${lib}.so" || true
index 48f125c5eb4ab708cf4b074d312c97406810d132..661f0c480a264cfdceb00182173bca921dfae870 100644 (file)
@@ -1,3 +1,4 @@
+p11kit-switch-to-dlopen.patch
 debian/Use-Debian-specific-config-files.patch
 debian/Bring-tmpfiles.d-tmp.conf-in-line-with-Debian-defaul.patch
 debian/Make-run-lock-tmpfs-an-API-fs.patch
index 66fb7abb7f2bdb8641270937d4e882414c1cfc2a..a8974b294da3e0655159d3b73fabf18efcd913b0 100755 (executable)
@@ -67,7 +67,6 @@ CONFFLAGS = \
        -Dxkbcommon=false \
        -Dwheel-group=false \
        -Dpwquality=false \
-       -Dp11kit=false \
        -Doomd=true \
        -Durlify=true \
        -Dgnutls=false \
@@ -118,6 +117,7 @@ CONFFLAGS += \
        -Ddns-over-tls=openssl \
        -Dlibfido2=true \
        -Dtpm2=true \
+       -Dp11kit=true \
        -Dqrencode=true \
        -Dhomed=true \
        -Duserdb=true \
@@ -138,6 +138,7 @@ CONFFLAGS += \
        -Dopenssl=false \
        -Dlibfido2=false \
        -Dtpm2=false \
+       -Dp11kit=false \
        -Dqrencode=false \
        -Dhomed=false \
        -Duserdb=false \
index e7c99be98222bbda2e40cd171c7263169709025f..4ea2933e5c5f88ab7109da4d270f8286cb1d3ef7 100644 (file)
@@ -172,6 +172,7 @@ Depends: systemd-tests,
   libtss2-dev,
   libfido2-dev,
   libqrencode-dev,
+  libp11-kit-dev,
   python3-pexpect,
   screen,
   swtpm,