diff --git a/src/home/homectl-pkcs11.c b/src/home/homectl-pkcs11.c index 95cf932936..c6aaa2e6d6 100644 --- a/src/home/homectl-pkcs11.c +++ b/src/home/homectl-pkcs11.c @@ -201,143 +201,3 @@ int identity_add_pkcs11_key_data(JsonVariant **v, const char *uri) { return 0; } - -#if HAVE_P11KIT -static int list_callback( - CK_FUNCTION_LIST *m, - CK_SESSION_HANDLE session, - CK_SLOT_ID slot_id, - const CK_SLOT_INFO *slot_info, - const CK_TOKEN_INFO *token_info, - P11KitUri *uri, - 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; - Table *t = userdata; - int uri_result, r; - - assert(slot_info); - assert(token_info); - - /* 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 - * and such, and it's typically not what people want to bind their home directories to.) */ - if (!FLAGS_SET(token_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT)) - return -EAGAIN; - - token_label = pkcs11_token_label(token_info); - if (!token_label) - return log_oom(); - - token_manufacturer_id = pkcs11_token_manufacturer_id(token_info); - if (!token_manufacturer_id) - return log_oom(); - - token_model = pkcs11_token_model(token_info); - if (!token_model) - return log_oom(); - - token_uri = uri_from_token_info(token_info); - if (!token_uri) - return log_oom(); - - uri_result = 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)); - - r = table_add_many( - t, - TABLE_STRING, token_uri_string, - TABLE_STRING, token_label, - TABLE_STRING, token_manufacturer_id, - TABLE_STRING, token_model); - if (r < 0) - return table_log_add_error(r); - - return -EAGAIN; /* keep scanning */ -} -#endif - -int list_pkcs11_tokens(void) { -#if HAVE_P11KIT - _cleanup_(table_unrefp) Table *t = NULL; - int r; - - t = table_new("uri", "label", "manufacturer", "model"); - if (!t) - return log_oom(); - - r = pkcs11_find_token(NULL, list_callback, t); - if (r < 0 && r != -EAGAIN) - return r; - - if (table_get_rows(t) <= 1) { - log_info("No suitable PKCS#11 tokens found."); - return 0; - } - - r = table_print(t, stdout); - if (r < 0) - return log_error_errno(r, "Failed to show device table: %m"); - - return 0; -#else - return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "PKCS#11 tokens not supported on this build."); -#endif -} - -#if HAVE_P11KIT -static int auto_callback( - CK_FUNCTION_LIST *m, - CK_SESSION_HANDLE session, - CK_SLOT_ID slot_id, - const CK_SLOT_INFO *slot_info, - const CK_TOKEN_INFO *token_info, - P11KitUri *uri, - void *userdata) { - - _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL; - char **t = userdata; - int uri_result; - - assert(slot_info); - assert(token_info); - - if (!FLAGS_SET(token_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT)) - return -EAGAIN; - - if (*t) - return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), - "More than one suitable PKCS#11 token found."); - - token_uri = uri_from_token_info(token_info); - if (!token_uri) - return log_oom(); - - uri_result = 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 0; -} -#endif - -int find_pkcs11_token_auto(char **ret) { -#if HAVE_P11KIT - int r; - - r = pkcs11_find_token(NULL, auto_callback, ret); - if (r == -EAGAIN) - return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "No suitable PKCS#11 tokens found."); - if (r < 0) - return r; - - return 0; -#else - return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "PKCS#11 tokens not supported on this build."); -#endif -} diff --git a/src/home/homectl.c b/src/home/homectl.c index 7cfda7ed2f..e10cfaf2a4 100644 --- a/src/home/homectl.c +++ b/src/home/homectl.c @@ -3146,7 +3146,7 @@ static int parse_argv(int argc, char *argv[]) { const char *p; if (streq(optarg, "list")) - return list_pkcs11_tokens(); + return pkcs11_list_tokens(); /* If --pkcs11-token-uri= is specified we always drop everything old */ FOREACH_STRING(p, "pkcs11TokenUri", "pkcs11EncryptedKey") { @@ -3163,7 +3163,7 @@ static int parse_argv(int argc, char *argv[]) { if (streq(optarg, "auto")) { _cleanup_free_ char *found = NULL; - r = find_pkcs11_token_auto(&found); + r = pkcs11_find_token_auto(&found); if (r < 0) return r; r = strv_consume(&arg_pkcs11_token_uri, TAKE_PTR(found)); diff --git a/src/shared/pkcs11-util.c b/src/shared/pkcs11-util.c index fc59f98701..27c209cdf8 100644 --- a/src/shared/pkcs11-util.c +++ b/src/shared/pkcs11-util.c @@ -5,6 +5,7 @@ #include "ask-password-api.h" #include "escape.h" #include "fd-util.h" +#include "format-table.h" #include "io-util.h" #include "memory-util.h" #if HAVE_OPENSSL @@ -1010,6 +1011,143 @@ int pkcs11_acquire_certificate( return 0; } +#endif +static int list_callback( + CK_FUNCTION_LIST *m, + CK_SESSION_HANDLE session, + CK_SLOT_ID slot_id, + const CK_SLOT_INFO *slot_info, + const CK_TOKEN_INFO *token_info, + P11KitUri *uri, + 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; + Table *t = userdata; + int uri_result, r; + + assert(slot_info); + assert(token_info); + + /* 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 + * and such, and it's typically not what people want to bind their home directories to.) */ + if (!FLAGS_SET(token_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT)) + return -EAGAIN; + + token_label = pkcs11_token_label(token_info); + if (!token_label) + return log_oom(); + + token_manufacturer_id = pkcs11_token_manufacturer_id(token_info); + if (!token_manufacturer_id) + return log_oom(); + + token_model = pkcs11_token_model(token_info); + if (!token_model) + return log_oom(); + + token_uri = uri_from_token_info(token_info); + if (!token_uri) + return log_oom(); + + uri_result = 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)); + + r = table_add_many( + t, + TABLE_STRING, token_uri_string, + TABLE_STRING, token_label, + TABLE_STRING, token_manufacturer_id, + TABLE_STRING, token_model); + if (r < 0) + return table_log_add_error(r); + + return -EAGAIN; /* keep scanning */ +} #endif + +int pkcs11_list_tokens(void) { +#if HAVE_P11KIT + _cleanup_(table_unrefp) Table *t = NULL; + int r; + + t = table_new("uri", "label", "manufacturer", "model"); + if (!t) + return log_oom(); + + r = pkcs11_find_token(NULL, list_callback, t); + if (r < 0 && r != -EAGAIN) + return r; + + if (table_get_rows(t) <= 1) { + log_info("No suitable PKCS#11 tokens found."); + return 0; + } + + r = table_print(t, stdout); + if (r < 0) + return log_error_errno(r, "Failed to show device table: %m"); + + return 0; +#else + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), + "PKCS#11 tokens not supported on this build."); #endif +} + +#if HAVE_P11KIT +static int auto_callback( + CK_FUNCTION_LIST *m, + CK_SESSION_HANDLE session, + CK_SLOT_ID slot_id, + const CK_SLOT_INFO *slot_info, + const CK_TOKEN_INFO *token_info, + P11KitUri *uri, + void *userdata) { + + _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL; + char **t = userdata; + int uri_result; + + assert(slot_info); + assert(token_info); + + if (!FLAGS_SET(token_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT)) + return -EAGAIN; + + if (*t) + return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), + "More than one suitable PKCS#11 token found."); + + token_uri = uri_from_token_info(token_info); + if (!token_uri) + return log_oom(); + + uri_result = 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 0; +} +#endif + +int pkcs11_find_token_auto(char **ret) { +#if HAVE_P11KIT + int r; + + r = pkcs11_find_token(NULL, auto_callback, ret); + if (r == -EAGAIN) + return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "No suitable PKCS#11 tokens found."); + if (r < 0) + return r; + + return 0; +#else + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), + "PKCS#11 tokens not supported on this build."); +#endif +} diff --git a/src/shared/pkcs11-util.h b/src/shared/pkcs11-util.h index 990368a41b..3fa2505deb 100644 --- a/src/shared/pkcs11-util.h +++ b/src/shared/pkcs11-util.h @@ -50,3 +50,6 @@ int pkcs11_acquire_certificate(const char *uri, const char *askpw_friendly_name, #endif #endif + +int pkcs11_list_tokens(void); +int pkcs11_find_token_auto(char **ret);