diff --git a/.gitignore b/.gitignore index e349d8f..3ce6307 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ opencryptoki-2.3.1.tar.gz /opencryptoki-3.15.0.tar.gz /opencryptoki-3.15.1.tar.gz /opencryptoki-3.16.0.tar.gz +/opencryptoki-3.17.0.tar.gz diff --git a/opencryptoki-3.16.0-19f56d12b302b87e1dacf613cc61a063ad209d15.patch b/opencryptoki-3.16.0-19f56d12b302b87e1dacf613cc61a063ad209d15.patch deleted file mode 100644 index e7872d6..0000000 --- a/opencryptoki-3.16.0-19f56d12b302b87e1dacf613cc61a063ad209d15.patch +++ /dev/null @@ -1,136 +0,0 @@ -commit 19f56d12b302b87e1dacf613cc61a063ad209d15 -Author: Ingo Franzki -Date: Fri Feb 12 15:57:20 2021 +0100 - - Fix compile warning when compiling pkcsslotd with -DDEV and/or -DTHREADED - - Signed-off-by: Ingo Franzki - -diff --git a/usr/sbin/pkcsslotd/garbage_linux.c b/usr/sbin/pkcsslotd/garbage_linux.c -index d4878c3b..a4dd9713 100644 ---- a/usr/sbin/pkcsslotd/garbage_linux.c -+++ b/usr/sbin/pkcsslotd/garbage_linux.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #include "log.h" - #include "slotmgr.h" -@@ -80,8 +81,8 @@ BOOL StartGCThread(Slot_Mgr_Shr_t *MemPtr) - #ifdef DEV - // Only development builds - LogLog("StartGCThread: garbage collection thread started as ID " -- "%d (%#x) by ID %d (%#x)", -- GCThread, GCThread, pthread_self(), pthread_self()); -+ "%lu by ID %lu", -+ GCThread, pthread_self()); - #endif - - return TRUE; -@@ -115,8 +116,8 @@ BOOL StopGCThread(void *Ptr) - return FALSE; - } - -- DbgLog(DL0, "StopGCThread: tid %d is stopping the garbage collection " -- "thread (tid %d)", -+ DbgLog(DL0, "StopGCThread: tid %lu is stopping the garbage collection " -+ "thread (tid %lu)", - pthread_self(), GCThread); - - /* Cause the GC thread to be cancelled */ -@@ -245,7 +246,7 @@ void GCCancel(void *Ptr) - UNUSED(Ptr); - - /* Yeah, yeah. Doesn't do anything, but I had plans */ -- DbgLog(DL3, "GCCancel: tid: %d running cleanup routine", pthread_self()); -+ DbgLog(DL3, "GCCancel: tid: %lu running cleanup routine", pthread_self()); - - return; - } -@@ -268,7 +269,7 @@ BOOL CheckForGarbage(Slot_Mgr_Shr_t *MemPtr) - - ASSERT(MemPtr != NULL_PTR); - #ifdef DEV -- DbgLog(DL5, "Thread %d is checking for garbage", pthread_self()); -+ DbgLog(DL5, "Thread %lu is checking for garbage", pthread_self()); - #endif /* DEV */ - - -@@ -326,9 +327,9 @@ BOOL CheckForGarbage(Slot_Mgr_Shr_t *MemPtr) - if (*pProcSessions > 0) { - - #ifdef DEV -- DbgLog(DL2, "GC: Invalid pid (%d) is holding %d sessions " -+ DbgLog(DL2, "GC: Invalid pid (%d) is holding %u sessions " - "open on slot %d. Global session count for this " -- "slot is %d", -+ "slot is %u", - pProc->proc_id, *pProcSessions, SlotIndex, - *pGlobalSessions); - #endif /* DEV */ -@@ -338,9 +339,9 @@ BOOL CheckForGarbage(Slot_Mgr_Shr_t *MemPtr) - WarnLog("Garbage Collection: Illegal values in table " - "for defunct process"); - DbgLog(DL0, "Garbage collection: A process " -- "( Index: %d, pid: %d ) showed %d sessions " -- "open on slot %s, but the global count for this " -- "slot is only %d", -+ "( Index: %d, pid: %d ) showed %u sessions " -+ "open on slot %d, but the global count for this " -+ "slot is only %u", - ProcIndex, pProc->proc_id, *pProcSessions, - SlotIndex, *pGlobalSessions); - #endif /* DEV */ -@@ -395,14 +396,8 @@ int Stat2Proc(int pid, proc_t *p) - char fbuf[800]; // about 40 fields, 64-bit decimal is about 20 chars - char *tmp; - int fd, num; -- // FILE *fp; -- -- // sprintf(buf, "%s/%d/stat", PROC_BASE, pid); -- // if( (fp = fopen(buf, "r")) == NULL ) -- // return FALSE; - - sprintf(fbuf, "%s/%d/stat", PROC_BASE, pid); -- printf("Buff = %s \n", fbuf); - fflush(stdout); - if ((fd = open(fbuf, O_RDONLY, 0)) == -1) - return FALSE; -diff --git a/usr/sbin/pkcsslotd/log.c b/usr/sbin/pkcsslotd/log.c -index 0214f952..0394cc7d 100644 ---- a/usr/sbin/pkcsslotd/log.c -+++ b/usr/sbin/pkcsslotd/log.c -@@ -463,8 +463,8 @@ BOOL PKCS_Log(pLogHandle phLog, char *fmt, va_list ap) - #endif /* DEV */ - - if (WriteNow) { -- fprintf(stderr, "%s[%d.%d]: %s\n", pInfo->Descrip, getpid(), -- (int) pthread_self(), buf); -+ fprintf(stderr, "%s[%d.%lu]: %s\n", pInfo->Descrip, getpid(), -+ pthread_self(), buf); - } - } - -@@ -482,7 +482,7 @@ BOOL PKCS_Log(pLogHandle phLog, char *fmt, va_list ap) - GetCurrentTimeString(timebuf); - - /* Date/Time stamp, descrip, Error message */ -- fprintf(fd, "%s %s[%d.%d]: ", timebuf, pInfo->Descrip, getpid(), -+ fprintf(fd, "%s %s[%d.%lu]: ", timebuf, pInfo->Descrip, getpid(), - pthread_self()); - fprintf(fd, "%s\n", buf); - fflush(fd); -diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c -index 94288f13..efbfe8fd 100644 ---- a/usr/sbin/pkcsslotd/slotmgr.c -+++ b/usr/sbin/pkcsslotd/slotmgr.c -@@ -660,7 +660,6 @@ int main(int argc, char *argv[], char *envp[]) - */ - - #if !defined(NOGARBAGE) -- printf("Start garbage \n"); - /* start garbage collection thread */ - if (!StartGCThread(shmp)) { - term_socket_server(); diff --git a/opencryptoki-3.16.0-1fdd0e4497b0078e73e0004e3492db647c7c458b.patch b/opencryptoki-3.16.0-1fdd0e4497b0078e73e0004e3492db647c7c458b.patch deleted file mode 100644 index 264f27d..0000000 --- a/opencryptoki-3.16.0-1fdd0e4497b0078e73e0004e3492db647c7c458b.patch +++ /dev/null @@ -1,2304 +0,0 @@ -commit 1fdd0e4497b0078e73e0004e3492db647c7c458b -Author: Ingo Franzki -Date: Wed Feb 24 15:47:05 2021 +0100 - - EP11: Handle APQN events to update APQN version, CP infos and target - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c -index 52f95d7a..728fedd5 100644 ---- a/usr/lib/ep11_stdll/ep11_specific.c -+++ b/usr/lib/ep11_stdll/ep11_specific.c -@@ -38,6 +38,7 @@ - #include "ock_syslog.h" - #include "ec_defs.h" - #include "p11util.h" -+#include "events.h" - - #include - #include -@@ -197,19 +198,27 @@ typedef struct { - - #define MAX_RETRY_COUNT 100 - --#define RETRY_START do { \ -+#define RETRY_START(rc, tokdata) \ -+ do { \ - int retry_count; \ -+ ep11_target_info_t* target_info = \ -+ get_target_info((tokdata)); \ -+ if (target_info == NULL) \ -+ (rc) = CKR_FUNCTION_FAILED; \ - for(retry_count = 0; \ -+ target_info != NULL && \ - retry_count < MAX_RETRY_COUNT; \ - retry_count ++) { - - #define RETRY_END(rc, tokdata, session) if ((rc) != CKR_SESSION_CLOSED) \ - break; \ - (rc) = ep11tok_relogin_session( \ -- tokdata, session); \ -+ (tokdata), (session)); \ - if ((rc) != CKR_OK) \ - break; \ - } \ -+ put_target_info((tokdata), \ -+ target_info); \ - } while (0); - - #define CKF_EP11_HELPER_SESSION 0x80000000 -@@ -248,7 +257,6 @@ typedef struct ep11_card_version { - } ep11_card_version_t; - - static CK_RV ep11tok_get_ep11_library_version(CK_VERSION *lib_version); --static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata); - static void free_card_versions(ep11_card_version_t *card_version); - static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type, - const CK_VERSION *ep11_lib_version, -@@ -476,16 +484,23 @@ static CK_RV handle_all_ep11_cards(ep11_target_t * ep11_targets, - #define PKEY_MODE_ENABLE4NONEXTR 2 - - typedef struct { -+ volatile unsigned long ref_count; - target_t target; -+ ep11_card_version_t *card_versions; -+ CK_ULONG used_firmware_API_version; -+ unsigned char control_points[XCP_CP_BYTES]; -+ size_t control_points_len; -+ size_t max_control_point_index; -+ CK_CHAR serialNumber[16]; -+} ep11_target_info_t; -+ -+typedef struct { - ep11_target_t target_list; - CK_BYTE raw2key_wrap_blob[MAX_BLOBSIZE]; - size_t raw2key_wrap_blob_l; - int cka_sensitive_default_true; - char cp_filter_config_filename[PATH_MAX]; - cp_config_t *cp_config; -- unsigned char control_points[XCP_CP_BYTES]; -- size_t control_points_len; -- size_t max_control_point_index; - int strict_mode; - int vhsm_mode; - int optimize_single_ops; -@@ -497,12 +512,14 @@ typedef struct { - char digest_libica_path[PATH_MAX]; - libica_t libica; - CK_VERSION ep11_lib_version; -- ep11_card_version_t *card_versions; -- CK_ULONG used_firmware_API_version; -- CK_CHAR serialNumber[16]; -+ volatile ep11_target_info_t *target_info; -+ pthread_rwlock_t target_rwlock; - } ep11_private_data_t; - --static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata); -+static ep11_target_info_t *get_target_info(STDLL_TokData_t *tokdata); -+static void put_target_info(STDLL_TokData_t *tokdata, -+ ep11_target_info_t *target_info); -+static CK_RV refresh_target_info(STDLL_TokData_t *tokdata); - - static CK_RV get_ep11_target_for_apqn(uint_32 adapter, uint_32 domain, - target_t *target, uint64_t flags); -@@ -704,8 +721,13 @@ static CK_RV ep11tok_pkey_get_firmware_mk_vp(STDLL_TokData_t *tokdata) - CK_BYTE blob[MAX_BLOBSIZE]; - size_t blobsize = sizeof(blob); - CK_ATTRIBUTE *pkey_attr = NULL, *blob_attr=NULL; -+ ep11_target_info_t* target_info; - CK_RV ret; - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - /* Check if CPACF_WRAP mech supported */ - if (ep11tok_is_mechanism_supported(tokdata, CKM_IBM_CPACF_WRAP) != CKR_OK) { - TRACE_INFO("CKM_IBM_CPACF_WRAP not supported on this system.\n"); -@@ -717,7 +739,7 @@ static CK_RV ep11tok_pkey_get_firmware_mk_vp(STDLL_TokData_t *tokdata) - - /* Create an AES testkey with CKA_IBM_PROTKEY_EXTRACTABLE */ - ret = dll_m_GenerateKey(&mech, tmpl, tmpl_len, NULL, 0, -- blob, &blobsize, csum, &csum_l, ep11_data->target); -+ blob, &blobsize, csum, &csum_l, target_info->target); - if (ret != CKR_OK) { - TRACE_ERROR("dll_m_GenerateKey failed with rc=0x%lx\n",ret); - goto done; -@@ -749,6 +771,8 @@ done: - if (blob_attr) - free(blob_attr); - -+ put_target_info(tokdata, target_info); -+ - return ret; - } - -@@ -1337,7 +1361,7 @@ static CK_RV ab_unwrap_update_template(STDLL_TokData_t * tokdata, - OBJECT *obj, - CK_KEY_TYPE keytype) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; -+ ep11_target_info_t* target_info; - CK_RV rc; - CK_BBOOL trusted, encrypt, decrypt, wrap, unwrap, sign, sign_recover, - verify, verify_recover, derive, extractable, local, -@@ -1367,9 +1391,16 @@ static CK_RV ab_unwrap_update_template(STDLL_TokData_t * tokdata, - CK_ATTRIBUTE *attr; - CK_BBOOL cktrue = TRUE; - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - rc = dll_m_GetAttributeValue(blob, blob_len, attrs, - sizeof(attrs) / sizeof(CK_ATTRIBUTE), -- ep11_data->target); -+ target_info->target); -+ -+ put_target_info(tokdata, target_info); -+ - if (rc != CKR_OK) { - TRACE_ERROR("Retrieving attributes from AB unwrapped key failed, rc=0x%lx\n", - rc); -@@ -2117,10 +2148,10 @@ static CK_RV rawkey_2_blob(STDLL_TokData_t * tokdata, SESSION * sess, - * calls the ep11 lib (which in turns sends the request to the card), - * all m_ function are ep11 functions - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, &mech, key, -- ksize, cipher, &clen, ep11_data->target); -+ ksize, cipher, &clen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -2146,12 +2177,12 @@ static CK_RV rawkey_2_blob(STDLL_TokData_t * tokdata, SESSION * sess, - /* the encrypted key is decrypted and a blob is build, - * card accepts only blobs as keys - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, clen, ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, ep11_pin_blob_len, &mech, - new_p_attrs, new_attrs_len, blob, blen, csum, -- &cslen, ep11_data->target); -+ &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -2194,14 +2225,20 @@ rawkey_2_blob_end: - CK_RV token_specific_rng(STDLL_TokData_t * tokdata, CK_BYTE * output, - CK_ULONG bytes) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - -- CK_RV rc = dll_m_GenerateRandom(output, bytes, ep11_data->target); -+ CK_RV rc = dll_m_GenerateRandom(output, bytes, target_info->target); - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s output=%p bytes=%lu rc=0x%lx\n", - __func__, (void *)output, bytes, rc); - } -+ -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -2215,6 +2252,7 @@ static CK_RV make_wrapblob(STDLL_TokData_t * tokdata, CK_ATTRIBUTE * tmpl_in, - { - ep11_private_data_t *ep11_data = tokdata->private_data; - CK_MECHANISM mech = { CKM_AES_KEY_GEN, NULL_PTR, 0 }; -+ ep11_target_info_t* target_info; - CK_BYTE csum[MAX_CSUMSIZE]; - size_t csum_l = sizeof(csum); - CK_RV rc; -@@ -2225,11 +2263,15 @@ static CK_RV make_wrapblob(STDLL_TokData_t * tokdata, CK_ATTRIBUTE * tmpl_in, - return CKR_OK; - } - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - ep11_data->raw2key_wrap_blob_l = sizeof(ep11_data->raw2key_wrap_blob); - rc = dll_m_GenerateKey(&mech, tmpl_in, tmpl_len, NULL, 0, - ep11_data->raw2key_wrap_blob, - &ep11_data->raw2key_wrap_blob_l, csum, &csum_l, -- ep11_data->target); -+ target_info->target); - - - if (rc != CKR_OK) { -@@ -2240,6 +2282,7 @@ static CK_RV make_wrapblob(STDLL_TokData_t * tokdata, CK_ATTRIBUTE * tmpl_in, - __func__, ep11_data->raw2key_wrap_blob_l, rc); - } - -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -2479,6 +2522,14 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber, - if (ep11_data == NULL) - return CKR_HOST_MEMORY; - -+ if (pthread_rwlock_init(&ep11_data->target_rwlock, NULL) != 0) { -+ TRACE_DEVEL("Target Lock init failed.\n"); -+ OCK_SYSLOG(LOG_ERR, "%s: Failed to initialize the target lock\n", -+ __func__); -+ rc = CKR_CANT_LOCK; -+ goto error; -+ } -+ - tokdata->private_data = ep11_data; - - /* read ep11 specific config file with user specified -@@ -2513,13 +2564,28 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber, - } - #endif - -- rc = ep11tok_get_ep11_version(tokdata); -- if (rc != CKR_OK) -+ rc = ep11tok_get_ep11_library_version(&ep11_data->ep11_lib_version); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s Failed to get the Ep11 library version " -+ "(ep11tok_get_ep11_library_version rc=0x%lx)\n", __func__, -+ rc); -+ OCK_SYSLOG(LOG_ERR, "%s: Failed to get the EP11 library version " -+ "rc=0x%lx\n", __func__, rc); - goto error; -+ } - -- rc = ep11tok_setup_target(tokdata); -- if (rc != CKR_OK) -+ TRACE_INFO("%s Host library version: %d.%d\n", __func__, -+ ep11_data->ep11_lib_version.major, -+ ep11_data->ep11_lib_version.minor); -+ -+ rc = refresh_target_info(tokdata); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s Failed to get the target info (refresh_target_info " -+ "rc=0x%lx)\n", __func__, rc); -+ OCK_SYSLOG(LOG_ERR, "%s: Failed to get the target info rc=0x%lx\n", -+ __func__, rc); - goto error; -+ } - - if (ep11_data->digest_libica) { - rc = ep11tok_load_libica(tokdata); -@@ -2530,18 +2596,6 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber, - ep11_data->msa_level = get_msa_level(); - TRACE_INFO("MSA level = %i\n", ep11_data->msa_level); - -- ep11_data->control_points_len = sizeof(ep11_data->control_points); -- rc = get_control_points(tokdata, ep11_data->control_points, -- &ep11_data->control_points_len, -- &ep11_data->max_control_point_index); -- if (rc != CKR_OK) { -- TRACE_ERROR("%s Failed to get the control points (get_control_points " -- "rc=0x%lx)\n", __func__, rc); -- OCK_SYSLOG(LOG_ERR, "%s: Failed to get the control points rc=0x%lx\n", -- __func__, rc); -- goto error; -- } -- - /* create an AES key needed for importing keys - * (encrypt by wrap_key and m_UnwrapKey by wrap key) - */ -@@ -2600,10 +2654,14 @@ CK_RV ep11tok_final(STDLL_TokData_t * tokdata) - TRACE_INFO("ep11 %s running\n", __func__); - - if (ep11_data != NULL) { -- if (dll_m_rm_module != NULL) -- dll_m_rm_module(NULL, ep11_data->target); -+ if (ep11_data->target_info != NULL) { -+ if (dll_m_rm_module != NULL) -+ dll_m_rm_module(NULL, ep11_data->target_info->target); -+ free_card_versions(ep11_data->target_info->card_versions); -+ free((void* )ep11_data->target_info); -+ } -+ pthread_rwlock_destroy(&ep11_data->target_rwlock); - free_cp_config(ep11_data->cp_config); -- free_card_versions(ep11_data->card_versions); - free(ep11_data); - tokdata->private_data = NULL; - } -@@ -2619,7 +2677,6 @@ static CK_RV make_maced_spki(STDLL_TokData_t *tokdata, SESSION * sess, - CK_BYTE *spki, CK_ULONG spki_len, - CK_BYTE *maced_spki, CK_ULONG *maced_spki_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - unsigned char *ep11_pin_blob = NULL; - CK_ULONG ep11_pin_blob_len = 0; - ep11_session_t *ep11_session = (ep11_session_t *) sess->private_data; -@@ -2712,11 +2769,11 @@ static CK_RV make_maced_spki(STDLL_TokData_t *tokdata, SESSION * sess, - ep11_get_pin_blob(ep11_session, object_is_session_object(pub_key_obj), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(spki, spki_len, NULL, 0, NULL, 0, - ep11_pin_blob, ep11_pin_blob_len, &mech, - p_attrs, attrs_len, maced_spki, maced_spki_len, -- csum, &cslen, ep11_data->target); -+ csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -2870,11 +2927,11 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess, - } - - /* encrypt */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, &mech_w, - data, data_len, cipher, &cipher_l, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, sess) - - TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n", -@@ -2901,12 +2958,12 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess, - /* calls the card, it decrypts the private RSA key, - * reads its BER format and builds a blob. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, cipher_l, ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, ep11_pin_blob_len, &mech_w, - new_p_attrs, new_attrs_len, blob, blob_size, -- csum, &cslen, ep11_data->target); -+ csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -3101,11 +3158,11 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess, - } - - /* encrypt */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, - &mech_w, data, data_len, -- cipher, &cipher_l, ep11_data->target); -+ cipher, &cipher_l, target_info->target); - RETRY_END(rc, tokdata, sess) - - TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n", -@@ -3133,14 +3190,14 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess, - /* calls the card, it decrypts the private EC key, - * reads its BER format and builds a blob. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, cipher_l, - ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, - ep11_pin_blob_len, &mech_w, - new_p_attrs, new_attrs_len, blob, -- blob_size, csum, &cslen, ep11_data->target); -+ blob_size, csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -3295,11 +3352,11 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess, - } - - /* encrypt */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, - &mech_w, data, data_len, -- cipher, &cipher_l, ep11_data->target); -+ cipher, &cipher_l, target_info->target); - RETRY_END(rc, tokdata, sess) - - -@@ -3327,14 +3384,14 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess, - /* calls the card, it decrypts the private EC key, - * reads its BER format and builds a blob. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, cipher_l, - ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, - ep11_pin_blob_len, &mech_w, - new_p_attrs, new_attrs_len, blob, -- blob_size, csum, &cslen, ep11_data->target); -+ blob_size, csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -3478,11 +3535,11 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess, - } - - /* encrypt */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, - &mech_w, data, data_len, -- cipher, &cipher_l, ep11_data->target); -+ cipher, &cipher_l, target_info->target); - RETRY_END(rc, tokdata, sess) - - TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n", -@@ -3509,14 +3566,14 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess, - /* calls the card, it decrypts the private EC key, - * reads its BER format and builds a blob. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, cipher_l, - ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, - ep11_pin_blob_len, &mech_w, - new_p_attrs, new_attrs_len, blob, -- blob_size, csum, &cslen, ep11_data->target); -+ blob_size, csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -3666,11 +3723,11 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess, - } - - /* encrypt */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, - &mech_w, data, data_len, -- cipher, &cipher_l, ep11_data->target); -+ cipher, &cipher_l, target_info->target); - RETRY_END(rc, tokdata, sess) - - TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n", -@@ -3699,14 +3756,14 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess, - /* calls the card, it decrypts the private Dilithium key, - * reads its BER format and builds a blob. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, cipher_l, - ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, - ep11_pin_blob_len, &mech_w, - new_p_attrs, new_attrs_len, blob, -- blob_size, csum, &cslen, ep11_data->target); -+ blob_size, csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -3884,7 +3941,6 @@ CK_RV ep11tok_generate_key(STDLL_TokData_t * tokdata, SESSION * session, - CK_MECHANISM_PTR mech, CK_ATTRIBUTE_PTR attrs, - CK_ULONG attrs_len, CK_OBJECT_HANDLE_PTR handle) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_BYTE blob[MAX_BLOBSIZE]; - size_t blobsize = sizeof(blob); - CK_BYTE csum[MAX_CSUMSIZE]; -@@ -3936,10 +3992,10 @@ CK_RV ep11tok_generate_key(STDLL_TokData_t * tokdata, SESSION * session, - ep11_get_pin_blob(ep11_session, ep11_is_session_object(attrs, attrs_len), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_GenerateKey(mech, new_attrs2, new_attrs2_len, ep11_pin_blob, - ep11_pin_blob_len, blob, &blobsize, -- csum, &csum_len, ep11_data->target); -+ csum, &csum_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4354,6 +4410,7 @@ CK_RV token_specific_sha_init(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - size_t state_len = MAX(MAX_DIGEST_STATE_BYTES, sizeof(libica_sha_context_t)); - CK_BYTE *state; - libica_sha_context_t *libica_ctx; -+ ep11_target_info_t* target_info; - - state = calloc(state_len, 1); /* freed by dig_mgr.c */ - if (!state) { -@@ -4361,15 +4418,21 @@ CK_RV token_specific_sha_init(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - return CKR_HOST_MEMORY; - } - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - if (ep11tok_libica_digest_available(ep11_data, mech->mechanism)) { - libica_ctx = (libica_sha_context_t *)state; - state_len = sizeof(libica_sha_context_t); - libica_ctx->first = CK_TRUE; - rc = get_sha_block_size(mech->mechanism, &libica_ctx->block_size); - } else { -- rc = dll_m_DigestInit(state, &state_len, mech, ep11_data->target); -+ rc = dll_m_DigestInit(state, &state_len, mech, target_info->target); - } - -+ put_target_info(tokdata, target_info); -+ - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s rc=0x%lx\n", __func__, rc); -@@ -4399,6 +4462,11 @@ CK_RV token_specific_sha(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - { - ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - if (ep11tok_libica_digest_available(ep11_data, c->mech.mechanism)) { - rc = ep11tok_libica_digest(ep11_data, c->mech.mechanism, -@@ -4408,7 +4476,7 @@ CK_RV token_specific_sha(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - SHA_MSG_PART_ONLY); - } else { - rc = dll_m_Digest(c->context, c->context_len, in_data, in_data_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - } - - if (rc != CKR_OK) { -@@ -4417,6 +4485,8 @@ CK_RV token_specific_sha(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - } else { - TRACE_INFO("%s rc=0x%lx\n", __func__, rc); - } -+ -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -4430,6 +4500,11 @@ CK_RV token_specific_sha_update(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - CK_ULONG out_len = sizeof(temp_out); - CK_ULONG len; - CK_RV rc = CKR_OK; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - if (ep11tok_libica_digest_available(ep11_data, c->mech.mechanism)) { - if (libica_ctx->offset > 0 || in_data_len < libica_ctx->block_size) { -@@ -4479,7 +4554,7 @@ CK_RV token_specific_sha_update(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - } - } else { - rc = dll_m_DigestUpdate(c->context, c->context_len, -- in_data, in_data_len, ep11_data->target); -+ in_data, in_data_len, target_info->target); - } - - out: -@@ -4489,6 +4564,8 @@ out: - } else { - TRACE_INFO("%s rc=0x%lx\n", __func__, rc); - } -+ -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -4499,6 +4576,11 @@ CK_RV token_specific_sha_final(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - ep11_private_data_t *ep11_data = tokdata->private_data; - libica_sha_context_t *libica_ctx = (libica_sha_context_t *)c->context; - CK_RV rc; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - if (ep11tok_libica_digest_available(ep11_data, c->mech.mechanism)) { - rc = ep11tok_libica_digest(ep11_data, c->mech.mechanism, -@@ -4510,7 +4592,7 @@ CK_RV token_specific_sha_final(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - SHA_MSG_PART_FINAL); - } else { - rc = dll_m_DigestFinal(c->context, c->context_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - } - - if (rc != CKR_OK) { -@@ -4520,6 +4602,7 @@ CK_RV token_specific_sha_final(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - TRACE_INFO("%s rc=0x%lx\n", __func__, rc); - } - -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -4528,7 +4611,6 @@ CK_RV token_specific_rsa_sign(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *out_data, CK_ULONG *out_data_len, - OBJECT *key_obj) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - size_t keyblobsize = 0; - CK_BYTE *keyblob; -@@ -4544,9 +4626,9 @@ CK_RV token_specific_rsa_sign(STDLL_TokData_t *tokdata, SESSION *session, - mech.pParameter = NULL; - mech.ulParameterLen = 0; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignSingle(keyblob, keyblobsize, &mech, in_data, in_data_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4563,7 +4645,6 @@ CK_RV token_specific_rsa_verify(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *signature, CK_ULONG sig_len, - OBJECT *key_obj) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *spki; - size_t spki_len = 0; -@@ -4579,9 +4660,9 @@ CK_RV token_specific_rsa_verify(STDLL_TokData_t *tokdata, SESSION *session, - mech.pParameter = NULL; - mech.ulParameterLen = 0; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifySingle(spki, spki_len, &mech, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4598,7 +4679,6 @@ CK_RV token_specific_rsa_pss_sign(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *in_data, CK_ULONG in_data_len, - CK_BYTE *sig, CK_ULONG *sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - size_t keyblobsize = 0; - CK_BYTE *keyblob; -@@ -4616,9 +4696,9 @@ CK_RV token_specific_rsa_pss_sign(STDLL_TokData_t *tokdata, SESSION *session, - mech.ulParameterLen = ctx->mech.ulParameterLen; - mech.pParameter = ctx->mech.pParameter; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignSingle(keyblob, keyblobsize, &mech, in_data, in_data_len, -- sig, sig_len, ep11_data->target); -+ sig, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4638,7 +4718,6 @@ CK_RV token_specific_rsa_pss_verify(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *in_data, CK_ULONG in_data_len, - CK_BYTE *signature, CK_ULONG sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *spki; - size_t spki_len = 0; -@@ -4656,9 +4735,9 @@ CK_RV token_specific_rsa_pss_verify(STDLL_TokData_t *tokdata, SESSION *session, - mech.ulParameterLen = ctx->mech.ulParameterLen; - mech.pParameter = ctx->mech.pParameter; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifySingle(spki, spki_len, &mech, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4678,7 +4757,6 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *out_data, CK_ULONG *out_data_len, - OBJECT *key_obj ) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - SIGN_VERIFY_CONTEXT *ctx = &(session->sign_ctx); - CK_RV rc; - size_t keyblobsize = 0; -@@ -4707,9 +4785,9 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *session, - mech.pParameter = NULL; - mech.ulParameterLen = 0; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignSingle(keyblob, keyblobsize, &mech, in_data, in_data_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4728,7 +4806,6 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *out_data, CK_ULONG out_data_len, - OBJECT *key_obj ) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - SIGN_VERIFY_CONTEXT *ctx = &(session->verify_ctx); - CK_RV rc; - CK_BYTE *spki; -@@ -4757,9 +4834,9 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, SESSION *session, - mech.pParameter = NULL; - mech.ulParameterLen = 0; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifySingle(spki, spki_len, &mech, in_data, in_data_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4784,7 +4861,6 @@ CK_RV token_specific_reencrypt_single(STDLL_TokData_t *tokdata, - CK_BYTE *in_data, CK_ULONG in_data_len, - CK_BYTE *out_data, CK_ULONG *out_data_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *decr_key, *encr_key; - size_t decr_key_len = 0, encr_key_len = 0; -@@ -4813,10 +4889,10 @@ CK_RV token_specific_reencrypt_single(STDLL_TokData_t *tokdata, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_ReencryptSingle(decr_key, decr_key_len, encr_key, encr_key_len, - decr_mech, encr_mech, in_data, in_data_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4892,7 +4968,6 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session, - CK_OBJECT_HANDLE_PTR handle, CK_ATTRIBUTE_PTR attrs, - CK_ULONG attrs_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *keyblob; - size_t keyblobsize; -@@ -4920,6 +4995,8 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session, - CK_ULONG privlen; - int curve_type; - CK_BBOOL allocated = FALSE; -+ ep11_target_info_t* target_info; -+ CK_ULONG used_firmware_API_version; - - memset(newblob, 0, sizeof(newblob)); - -@@ -5009,7 +5086,15 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session, - * then we can pass the mechanism parameters as-is, otherwise we still - * need to use the old way. - */ -- if (ep11_data->used_firmware_API_version <= 2) { -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ -+ used_firmware_API_version = target_info->used_firmware_API_version; -+ -+ put_target_info(tokdata, target_info); -+ -+ if (used_firmware_API_version <= 2) { - if (ecdh1_parms->kdf != CKD_NULL) { - TRACE_ERROR("%s KDF for CKM_ECDH1_DERIVE not supported: %lu\n", - __func__, ecdh1_parms->kdf); -@@ -5133,11 +5218,11 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session, - ep11_get_pin_blob(ep11_session, ep11_is_session_object(attrs, attrs_len), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = - dll_m_DeriveKey(mech, new_attrs2, new_attrs2_len, keyblob, keyblobsize, - NULL, 0, ep11_pin_blob, ep11_pin_blob_len, newblob, -- &newblobsize, csum, &cslen, ep11_data->target); -+ &newblobsize, csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -5231,7 +5316,6 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata, - CK_ULONG ulPrivateKeyAttributeCount, - CK_SESSION_HANDLE h) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE publblob[MAX_BLOBSIZE]; - size_t publblobsize = sizeof(publblob); -@@ -5418,13 +5502,13 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata, - ulPrivateKeyAttributeCount)), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_GenerateKeyPair(pMechanism, - new_publ_attrs, new_publ_attrs_len, - new_priv_attrs, new_priv_attrs_len, - ep11_pin_blob, ep11_pin_blob_len, - privblob, &privblobsize, -- publblob, &publblobsize, ep11_data->target); -+ publblob, &publblobsize, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -5543,7 +5627,6 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata, - CK_ULONG ulPrivateKeyAttributeCount, - CK_SESSION_HANDLE h) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE publblob[MAX_BLOBSIZE]; - size_t publblobsize = sizeof(publblob); -@@ -5752,13 +5835,13 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata, - ulPrivateKeyAttributeCount)), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_GenerateKeyPair(pMechanism, - new_publ_attrs2, new_publ_attrs2_len, - new_priv_attrs2, new_priv_attrs2_len, - ep11_pin_blob, ep11_pin_blob_len, privblob, - &privblobsize, publblob, &publblobsize, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -5866,7 +5949,6 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t * tokdata, - CK_ULONG ulPrivateKeyAttributeCount, - CK_SESSION_HANDLE h) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_ATTRIBUTE *attr = NULL; - CK_ATTRIBUTE *n_attr = NULL; -@@ -5967,13 +6049,13 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t * tokdata, - ulPrivateKeyAttributeCount)), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_GenerateKeyPair(pMechanism, - new_publ_attrs2, new_publ_attrs2_len, - new_priv_attrs2, new_priv_attrs2_len, - ep11_pin_blob, ep11_pin_blob_len, - privkey_blob, &privkey_blob_len, spki, -- &spki_len, ep11_data->target); -+ &spki_len, target_info->target); - RETRY_END(rc, tokdata, sess) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, sess); -@@ -6225,7 +6307,6 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t * tokdata, - CK_ULONG ulPrivateKeyAttributeCount, - CK_SESSION_HANDLE h) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_ATTRIBUTE *attr = NULL; - CK_BYTE privkey_blob[MAX_BLOBSIZE]; -@@ -6308,13 +6389,13 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t * tokdata, - ulPrivateKeyAttributeCount)), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_GenerateKeyPair(pMechanism, - new_publ_attrs2, new_publ_attrs2_len, - new_priv_attrs2, new_priv_attrs2_len, - ep11_pin_blob, ep11_pin_blob_len, - privkey_blob, &privkey_blob_len, spki, -- &spki_len, ep11_data->target); -+ &spki_len, target_info->target); - RETRY_END(rc, tokdata, sess) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, sess); -@@ -6914,7 +6995,6 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session, - CK_MECHANISM * mech, CK_BBOOL recover_mode, - CK_OBJECT_HANDLE key) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - size_t keyblobsize = 0; - CK_BYTE *keyblob; -@@ -6980,9 +7060,9 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignInit(ep11_sign_state, &ep11_sign_state_l, -- mech, keyblob, keyblobsize, ep11_data->target); -+ mech, keyblob, keyblobsize, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7017,7 +7097,6 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session, - CK_ULONG in_data_len, CK_BYTE * signature, - CK_ULONG * sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->sign_ctx; - size_t keyblobsize = 0; -@@ -7049,9 +7128,9 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_Sign(ctx->context, ctx->context_len, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7073,7 +7152,6 @@ done: - CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE * in_data, CK_ULONG in_data_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->sign_ctx; - size_t keyblobsize = 0; -@@ -7095,9 +7173,9 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignUpdate(ctx->context, ctx->context_len, in_data, -- in_data_len, ep11_data->target); -+ in_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7120,7 +7198,6 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BBOOL length_only, CK_BYTE * signature, - CK_ULONG * sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->sign_ctx; - size_t keyblobsize = 0; -@@ -7139,9 +7216,9 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignFinal(ctx->context, ctx->context_len, signature, sig_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7169,7 +7246,6 @@ CK_RV ep11tok_sign_single(STDLL_TokData_t *tokdata, SESSION *session, - size_t keyblobsize = 0; - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; -- ep11_private_data_t *ep11_data = tokdata->private_data; - - UNUSED(length_only); - -@@ -7186,9 +7262,9 @@ CK_RV ep11tok_sign_single(STDLL_TokData_t *tokdata, SESSION *session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignSingle(keyblob, keyblobsize, mech, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -7209,7 +7285,6 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session, - CK_MECHANISM * mech, CK_BBOOL recover_mode, - CK_OBJECT_HANDLE key) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *spki; - size_t spki_len = 0; -@@ -7285,9 +7360,9 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifyInit(ep11_sign_state, &ep11_sign_state_l, mech, -- spki, spki_len, ep11_data->target); -+ spki, spki_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7320,7 +7395,6 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE * in_data, CK_ULONG in_data_len, - CK_BYTE * signature, CK_ULONG sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->verify_ctx; - size_t keyblobsize = 0; -@@ -7353,9 +7427,9 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_Verify(ctx->context, ctx->context_len, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7377,7 +7451,6 @@ done: - CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE * in_data, CK_ULONG in_data_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->verify_ctx; - size_t keyblobsize = 0; -@@ -7399,9 +7472,9 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifyUpdate(ctx->context, ctx->context_len, in_data, -- in_data_len, ep11_data->target); -+ in_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7423,7 +7496,6 @@ done: - CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE * signature, CK_ULONG sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->verify_ctx; - size_t keyblobsize = 0; -@@ -7442,9 +7514,9 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifyFinal(ctx->context, ctx->context_len, signature, -- sig_len, ep11_data->target); -+ sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7471,7 +7543,6 @@ CK_RV ep11tok_verify_single(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *spki; - size_t spki_len = 0; - OBJECT *key_obj = NULL; -- ep11_private_data_t *ep11_data = tokdata->private_data; - - rc = h_opaque_2_blob(tokdata, key, &spki, &spki_len, &key_obj, READ_LOCK); - if (rc != CKR_OK) { -@@ -7495,9 +7566,9 @@ CK_RV ep11tok_verify_single(STDLL_TokData_t *tokdata, SESSION *session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifySingle(spki, spki_len, mech, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -7517,7 +7588,6 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR output_part, - CK_ULONG_PTR p_output_part_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->decr_ctx; - CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE); -@@ -7538,10 +7608,10 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_DecryptFinal(ctx->context, ctx->context_len, - output_part, p_output_part_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7564,7 +7634,6 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR input_data, CK_ULONG input_data_len, - CK_BYTE_PTR output_data, CK_ULONG_PTR p_output_data_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->decr_ctx; - CK_BBOOL length_only = (output_data == NULL ? CK_TRUE : CK_FALSE); -@@ -7586,10 +7655,10 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_Decrypt(ctx->context, ctx->context_len, input_data, - input_data_len, output_data, p_output_data_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7613,7 +7682,6 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR output_part, - CK_ULONG_PTR p_output_part_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->decr_ctx; - CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE); -@@ -7640,10 +7708,10 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_DecryptUpdate(ctx->context, ctx->context_len, - input_part, input_part_len, output_part, -- p_output_part_len, ep11_data->target); -+ p_output_part_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7671,7 +7739,6 @@ CK_RV ep11tok_decrypt_single(STDLL_TokData_t *tokdata, SESSION *session, - size_t keyblobsize = 0; - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; -- ep11_private_data_t *ep11_data = tokdata->private_data; - - UNUSED(length_only); - -@@ -7688,10 +7755,10 @@ CK_RV ep11tok_decrypt_single(STDLL_TokData_t *tokdata, SESSION *session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_DecryptSingle(keyblob, keyblobsize, mech, input_data, - input_data_len, output_data, p_output_data_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -7711,7 +7778,6 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR output_part, - CK_ULONG_PTR p_output_part_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->encr_ctx; - CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE); -@@ -7732,10 +7798,10 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptFinal(ctx->context, ctx->context_len, - output_part, p_output_part_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7758,7 +7824,6 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR input_data, CK_ULONG input_data_len, - CK_BYTE_PTR output_data, CK_ULONG_PTR p_output_data_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->encr_ctx; - CK_BBOOL length_only = (output_data == NULL ? CK_TRUE : CK_FALSE); -@@ -7780,10 +7845,10 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_Encrypt(ctx->context, ctx->context_len, input_data, - input_data_len, output_data, p_output_data_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7807,7 +7872,6 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR output_part, - CK_ULONG_PTR p_output_part_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->encr_ctx; - CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE); -@@ -7834,10 +7898,10 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptUpdate(ctx->context, ctx->context_len, - input_part, input_part_len, output_part, -- p_output_part_len, ep11_data->target); -+ p_output_part_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7865,7 +7929,6 @@ CK_RV ep11tok_encrypt_single(STDLL_TokData_t *tokdata, SESSION *session, - size_t keyblobsize = 0; - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; -- ep11_private_data_t *ep11_data = tokdata->private_data; - - UNUSED(length_only); - -@@ -7893,10 +7956,10 @@ CK_RV ep11tok_encrypt_single(STDLL_TokData_t *tokdata, SESSION *session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(keyblob, keyblobsize, mech, input_data, - input_data_len, output_data, p_output_data_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -7916,7 +7979,6 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session, - CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE key, - int op) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - CK_BYTE *blob; - size_t blob_len = 0; -@@ -7979,9 +8041,9 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session, - - if (op == DECRYPT) { - ENCR_DECR_CONTEXT *ctx = &session->decr_ctx; -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_DecryptInit(ep11_state, &ep11_state_l, mech, blob, -- blob_len, ep11_data->target); -+ blob_len, target_info->target); - RETRY_END(rc, tokdata, session) - ctx->key = key; - ctx->active = TRUE; -@@ -8012,9 +8074,9 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session, - goto error; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptInit(ep11_state, &ep11_state_l, mech, blob, -- blob_len, ep11_data->target); -+ blob_len, target_info->target); - RETRY_END(rc, tokdata, session) - ctx->key = key; - ctx->active = TRUE; -@@ -8092,7 +8154,6 @@ CK_RV ep11tok_wrap_key(STDLL_TokData_t * tokdata, SESSION * session, - CK_OBJECT_HANDLE key, CK_BYTE_PTR wrapped_key, - CK_ULONG_PTR p_wrapped_key_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *wrapping_blob; - size_t wrapping_blob_len; -@@ -8192,11 +8253,11 @@ CK_RV ep11tok_wrap_key(STDLL_TokData_t * tokdata, SESSION * session, - * (wrapping blob). The wrapped key can be processed by any PKCS11 - * implementation. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = - dll_m_WrapKey(wrap_target_blob, wrap_target_blob_len, wrapping_blob, - wrapping_blob_len, sign_blob, sign_blob_len, mech, -- wrapped_key, p_wrapped_key_len, ep11_data->target); -+ wrapped_key, p_wrapped_key_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -8228,7 +8289,6 @@ CK_RV ep11tok_unwrap_key(STDLL_TokData_t * tokdata, SESSION * session, - CK_OBJECT_HANDLE wrapping_key, - CK_OBJECT_HANDLE_PTR p_key) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *wrapping_blob, *temp; - size_t wrapping_blob_len; -@@ -8388,13 +8448,13 @@ CK_RV ep11tok_unwrap_key(STDLL_TokData_t * tokdata, SESSION * session, - /* we need a blob for the new key created by unwrapping, - * the wrapped key comes in BER - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(wrapped_key, wrapped_key_len, wrapping_blob, - wrapping_blob_len, verifyblob, verifyblobsize, - ep11_pin_blob, - ep11_pin_blob_len, mech, new_attrs2, new_attrs2_len, - keyblob, &keyblobsize, csum, &cslen, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -8657,21 +8717,25 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata, - CK_MECHANISM_TYPE_PTR pMechanismList, - CK_ULONG_PTR pulCount) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = 0; - CK_ULONG counter = 0, size = 0; - CK_MECHANISM_TYPE_PTR mlist = NULL; - CK_ULONG i; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - /* size querry */ - if (pMechanismList == NULL) { - rc = dll_m_GetMechanismList(0, pMechanismList, pulCount, -- ep11_data->target); -+ target_info->target); - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #1\n", - __func__, rc); -- return rc; -+ goto out; - } - - /* adjust the size according to the ban list, -@@ -8693,16 +8757,16 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata, - sizeof(CK_MECHANISM_TYPE) * counter); - if (!mlist) { - TRACE_ERROR("%s Memory allocation failed\n", __func__); -- return CKR_HOST_MEMORY; -+ rc = CKR_HOST_MEMORY; -+ goto out; - } -- rc = dll_m_GetMechanismList(0, mlist, &counter, ep11_data->target); -+ rc = dll_m_GetMechanismList(0, mlist, &counter, target_info->target); - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #2\n", - __func__, rc); -- free(mlist); - if (rc != CKR_BUFFER_TOO_SMALL) -- return rc; -+ goto out; - } - } while (rc == CKR_BUFFER_TOO_SMALL); - -@@ -8722,12 +8786,12 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata, - * that comes as parameter, this is a 'reduced size', - * ep11 would complain about insufficient list size - */ -- rc = dll_m_GetMechanismList(0, mlist, &counter, ep11_data->target); -+ rc = dll_m_GetMechanismList(0, mlist, &counter, target_info->target); - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #3\n", - __func__, rc); -- return rc; -+ goto out; - } - - /* -@@ -8744,17 +8808,17 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata, - sizeof(CK_MECHANISM_TYPE) * counter); - if (!mlist) { - TRACE_ERROR("%s Memory allocation failed\n", __func__); -- return CKR_HOST_MEMORY; -+ rc = CKR_HOST_MEMORY; -+ goto out; - } - /* all the card has */ -- rc = dll_m_GetMechanismList(0, mlist, &counter, ep11_data->target); -+ rc = dll_m_GetMechanismList(0, mlist, &counter, target_info->target); - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #4\n", - __func__, rc); -- free(mlist); - if (rc != CKR_BUFFER_TOO_SMALL) -- return rc; -+ goto out; - } - } while (rc == CKR_BUFFER_TOO_SMALL); - -@@ -8775,8 +8839,10 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata, - rc = CKR_BUFFER_TOO_SMALL; - } - -+out: - if (mlist) - free(mlist); -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -8790,6 +8856,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - CK_BBOOL found = FALSE; - CK_ULONG i; - int status; -+ CK_RV rc = CKR_OK; -+ ep11_target_info_t* target_info; - - for (i = 0; i < supported_mech_list_len; i++) { - if (type == ep11_supported_mech_list[i]) { -@@ -8804,13 +8872,18 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - return CKR_MECHANISM_INVALID; - } - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - if (check_cps_for_mechanism(ep11_data->cp_config, -- type, ep11_data->control_points, -- ep11_data->control_points_len, -- ep11_data->max_control_point_index) != CKR_OK) { -+ type, target_info->control_points, -+ target_info->control_points_len, -+ target_info->max_control_point_index) != CKR_OK) { - TRACE_INFO("%s Mech '%s' banned due to control point\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - - switch(type) { -@@ -8840,14 +8913,17 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (status == -1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - - case CKM_RSA_PKCS_OAEP: - /* CKM_RSA_PKCS_OAEP is not supported with EP11 host library <= 1.3 */ -- if (compare_ck_version(&ep11_data->ep11_lib_version, &ver1_3) <= 0) -- return CKR_MECHANISM_INVALID; -+ if (compare_ck_version(&ep11_data->ep11_lib_version, &ver1_3) <= 0) { -+ rc = CKR_MECHANISM_INVALID; -+ goto out; -+ } - break; - - case CKM_IBM_SHA3_224: -@@ -8863,7 +8939,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (status != 1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - -@@ -8876,7 +8953,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (status != 1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - -@@ -8887,7 +8965,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (compare_ck_version(&ep11_data->ep11_lib_version, &ver3) < 0) { - TRACE_INFO("%s Mech '%s' banned due to host library version\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - - status = check_required_versions(tokdata, edwards_req_versions, -@@ -8895,7 +8974,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (status != 1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - -@@ -8903,14 +8983,16 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (compare_ck_version(&ep11_data->ep11_lib_version, &ver3) <= 0) { - TRACE_INFO("%s Mech '%s' banned due to host library version\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - status = check_required_versions(tokdata, ibm_dilithium_req_versions, - NUM_DILITHIUM_REQ); - if (status != 1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - -@@ -8919,19 +9001,23 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - TRACE_INFO("%s Mech '%s' banned due to host library version\n", - __func__, ep11_get_ckm(type)); - -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - status = check_required_versions(tokdata, ibm_cpacf_wrap_req_versions, - NUM_CPACF_WRAP_REQ); - if (status != 1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - } - -- return CKR_OK; -+out: -+ put_target_info(tokdata, target_info); -+ return rc; - } - - CK_RV ep11tok_is_mechanism_supported_ex(STDLL_TokData_t *tokdata, -@@ -8976,9 +9062,9 @@ CK_RV ep11tok_get_mechanism_info(STDLL_TokData_t * tokdata, - CK_MECHANISM_TYPE type, - CK_MECHANISM_INFO_PTR pInfo) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - int status; -+ ep11_target_info_t* target_info; - - rc = ep11tok_is_mechanism_supported(tokdata, type); - if (rc != CKR_OK) { -@@ -8987,7 +9073,14 @@ CK_RV ep11tok_get_mechanism_info(STDLL_TokData_t * tokdata, - return rc; - } - -- rc = dll_m_GetMechanismInfo(0, type, pInfo, ep11_data->target); -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ -+ rc = dll_m_GetMechanismInfo(0, type, pInfo, target_info->target); -+ -+ put_target_info(tokdata, target_info); -+ - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s m_GetMechanismInfo(0x%lx) failed with rc=0x%lx\n", -@@ -10265,6 +10358,11 @@ static CK_RV generate_ep11_session_id(STDLL_TokData_t * tokdata, - CK_MECHANISM mech; - CK_ULONG len; - libica_sha_context_t ctx; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - session_id_data.handle = session->handle; - gettimeofday(&session_id_data.timeofday, NULL); -@@ -10286,7 +10384,9 @@ static CK_RV generate_ep11_session_id(STDLL_TokData_t * tokdata, - rc = dll_m_DigestSingle(&mech, (CK_BYTE_PTR)&session_id_data, - sizeof(session_id_data), - ep11_session->session_id, &len, -- ep11_data->target); -+ target_info->target); -+ -+ put_target_info(tokdata, target_info); - - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -10964,7 +11064,7 @@ static CK_RV get_card_type(uint_32 adapter, CK_ULONG *type) - - typedef struct query_version - { -- ep11_private_data_t *ep11_data; -+ ep11_target_info_t *target_info; - CK_CHAR serialNumber[16]; - CK_BBOOL first; - CK_BBOOL error; -@@ -11005,7 +11105,7 @@ static CK_RV version_query_handler(uint_32 adapter, uint_32 domain, - } - - /* Try to find existing version info for this card type */ -- card_version = qv->ep11_data->card_versions; -+ card_version = qv->target_info->card_versions; - while (card_version != NULL) { - if (card_version->card_type == card_type) - break; -@@ -11050,8 +11150,8 @@ static CK_RV version_query_handler(uint_32 adapter, uint_32 domain, - card_version->firmware_version = xcp_info.firmwareVersion; - #endif - -- card_version->next = qv->ep11_data->card_versions; -- qv->ep11_data->card_versions = card_version; -+ card_version->next = qv->target_info->card_versions; -+ qv->target_info->card_versions = card_version; - } else { - /* - * Version info for this card type is already available, so check this -@@ -11134,23 +11234,16 @@ static CK_RV ep11tok_get_ep11_library_version(CK_VERSION *lib_version) - return CKR_OK; - } - --static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata) -+static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata, -+ ep11_target_info_t *target_info) - { - ep11_private_data_t *ep11_data = tokdata->private_data; - ep11_card_version_t *card_version; - query_version_t qv; - CK_RV rc; - -- rc = ep11tok_get_ep11_library_version(&ep11_data->ep11_lib_version); -- if (rc != CKR_OK) -- return rc; -- -- TRACE_INFO("%s Host library version: %d.%d\n", __func__, -- ep11_data->ep11_lib_version.major, -- ep11_data->ep11_lib_version.minor); -- - memset(&qv, 0, sizeof(qv)); -- qv.ep11_data = ep11_data; -+ qv.target_info = target_info; - qv.first = TRUE; - - rc = handle_all_ep11_cards(&ep11_data->target_list, version_query_handler, -@@ -11169,18 +11262,18 @@ static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata) - return CKR_DEVICE_ERROR; - } - -- memcpy(ep11_data->serialNumber, qv.serialNumber, -- sizeof(ep11_data->serialNumber)); -+ memcpy(target_info->serialNumber, qv.serialNumber, -+ sizeof(target_info->serialNumber)); - -- TRACE_INFO("%s Serial number: %.16s\n", __func__, ep11_data->serialNumber); -+ TRACE_INFO("%s Serial number: %.16s\n", __func__, target_info->serialNumber); - - /* EP11 host lib version <= 2 only support API version 2 */ - if (ep11_data->ep11_lib_version.major <= 2) -- ep11_data->used_firmware_API_version = 2; -+ target_info->used_firmware_API_version = 2; - else -- ep11_data->used_firmware_API_version = 0; -+ target_info->used_firmware_API_version = 0; - -- card_version = ep11_data->card_versions; -+ card_version = target_info->card_versions; - while (card_version != NULL) { - TRACE_INFO("%s Card type: CEX%luP\n", __func__, - card_version->card_type); -@@ -11190,19 +11283,19 @@ static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata) - card_version->firmware_version.major, - card_version->firmware_version.minor); - -- if (ep11_data->used_firmware_API_version == 0) -- ep11_data->used_firmware_API_version = -+ if (target_info->used_firmware_API_version == 0) -+ target_info->used_firmware_API_version = - card_version->firmware_API_version; - else -- ep11_data->used_firmware_API_version = -- MIN(ep11_data->used_firmware_API_version, -+ target_info->used_firmware_API_version = -+ MIN(target_info->used_firmware_API_version, - card_version->firmware_API_version); - - card_version = card_version->next; - } - - TRACE_INFO("%s Used Firmware API: %lu\n", __func__, -- ep11_data->used_firmware_API_version); -+ target_info->used_firmware_API_version); - - return CKR_OK; - } -@@ -11220,20 +11313,29 @@ static void free_card_versions(ep11_card_version_t *card_version) - } - } - --void ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata, -+CK_RV ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata, - CK_TOKEN_INFO_PTR pInfo) - { - ep11_private_data_t *ep11_data = tokdata->private_data; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - /* - * report the EP11 firmware version as hardware version, and - * the EP11 host library version as firmware version - */ -- if (ep11_data->card_versions != NULL) -- pInfo->hardwareVersion = ep11_data->card_versions->firmware_version; -+ if (target_info->card_versions != NULL) -+ pInfo->hardwareVersion = target_info->card_versions->firmware_version; - pInfo->firmwareVersion = ep11_data->ep11_lib_version; -- memcpy(pInfo->serialNumber, ep11_data->serialNumber, -+ memcpy(pInfo->serialNumber, target_info->serialNumber, - sizeof(pInfo->serialNumber)); -+ -+ put_target_info(tokdata, target_info); -+ -+ return CKR_OK; - } - - /** -@@ -11247,13 +11349,17 @@ static int check_required_versions(STDLL_TokData_t *tokdata, - const version_req_t req[], - CK_ULONG num_req) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_ULONG i, max_card_type = 0, min_card_type = 0xFFFFFFFF; - CK_BBOOL req_not_fullfilled = CK_FALSE; - CK_BBOOL req_fullfilled = CK_FALSE; - ep11_card_version_t *card_version; -+ ep11_target_info_t* target_info; - int status; - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - for (i = 0; i < num_req; i++) { - status = check_card_version(tokdata, req[i].card_type, - req[i].min_lib_version, -@@ -11268,7 +11374,7 @@ static int check_required_versions(STDLL_TokData_t *tokdata, - } - - /* Are card types < min_card_type present? */ -- card_version = ep11_data->card_versions; -+ card_version = target_info->card_versions; - while (card_version != NULL) { - if (card_version->card_type < min_card_type) - req_not_fullfilled = CK_TRUE; -@@ -11276,7 +11382,7 @@ static int check_required_versions(STDLL_TokData_t *tokdata, - } - - /* Are card types > max_card_type present? */ -- card_version = ep11_data->card_versions; -+ card_version = target_info->card_versions; - while (card_version != NULL) { - if (card_version->card_type > max_card_type) { - /* -@@ -11285,9 +11391,10 @@ static int check_required_versions(STDLL_TokData_t *tokdata, - * So all others must also meet the version requirements or be - * not present. - */ -+ status = 1; - if (req_not_fullfilled == CK_TRUE) -- return -1; -- return 1; -+ status = -1; -+ goto out; - } - card_version = card_version->next; - } -@@ -11298,13 +11405,19 @@ static int check_required_versions(STDLL_TokData_t *tokdata, - * At least one don't meet the requirements, so all other must not - * fulfill the requirements, too, or are not present. - */ -+ status = 0; - if (req_fullfilled == CK_TRUE) -- return -1; -- return 0; -+ status = -1; -+ goto out; - } else { - /* All of the cards that are present fulfill the requirements */ -- return 1; -+ status = 1; -+ goto out; - } -+ -+out: -+ put_target_info(tokdata, target_info); -+ return status; - } - - /** -@@ -11320,6 +11433,8 @@ static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type, - { - ep11_private_data_t *ep11_data = tokdata->private_data; - ep11_card_version_t *card_version; -+ ep11_target_info_t* target_info; -+ int status = 1; - - TRACE_DEBUG("%s checking versions for CEX%luP cards.\n", __func__, card_type); - -@@ -11331,21 +11446,28 @@ static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type, - } - } - -- card_version = ep11_data->card_versions; -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return -1; -+ -+ card_version = target_info->card_versions; - while (card_version != NULL) { - if (card_version->card_type == card_type) - break; - card_version = card_version->next; - } - -- if (card_version == NULL) -- return -1; -+ if (card_version == NULL) { -+ status = -1; -+ goto out; -+ } - - if (firmware_version != NULL) { - if (compare_ck_version(&card_version->firmware_version, - firmware_version) < 0) { - TRACE_DEBUG("%s firmware_version is less than required\n", __func__); -- return 0; -+ status = 0; -+ goto out; - } - } - -@@ -11353,53 +11475,57 @@ static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type, - if (card_version->firmware_API_version < *firmware_API_version) { - TRACE_DEBUG("%s firmware_API_version is less than required\n", - __func__); -- return 0; -+ status = 0; -+ goto out; - } - } - -- return 1; -+ out: -+ put_target_info(tokdata, target_info); -+ return status; - } - --static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata) -+static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata, -+ ep11_target_info_t *target_info) - { - ep11_private_data_t *ep11_data = tokdata->private_data; - struct XCP_Module module; -- CK_RV rc; -+ CK_RV rc = CKR_OK; - short i; - - if (dll_m_add_module == NULL) { - TRACE_WARNING("%s Function dll_m_add_module is not available, falling " - "back to old target handling\n", __func__); - -- if (ep11_data->used_firmware_API_version > 2) { -+ if (target_info->used_firmware_API_version > 2) { - TRACE_ERROR("%s selecting an API version is not possible with old " - "target handling\n", __func__); - return CKR_FUNCTION_FAILED; - } - -- ep11_data->target = (target_t)&ep11_data->target_list; -+ target_info->target = (target_t)&ep11_data->target_list; - return CKR_OK; - } - -- if (ep11_data->used_firmware_API_version > 2 && -+ if (target_info->used_firmware_API_version > 2 && - ep11_data->ep11_lib_version.major < 3) { - TRACE_ERROR("%s selecting an API version is not possible with an EP11" - " host library version < 3.0\n", __func__); - return CKR_FUNCTION_FAILED; - } - -- ep11_data->target = XCP_TGT_INIT; -+ target_info->target = XCP_TGT_INIT; - memset(&module, 0, sizeof(module)); - module.version = ep11_data->ep11_lib_version.major >= 3 ? XCP_MOD_VERSION_2 - : XCP_MOD_VERSION_1; - module.flags = XCP_MFL_VIRTUAL | XCP_MFL_MODULE; -- module.api = ep11_data->used_firmware_API_version; -+ module.api = target_info->used_firmware_API_version; - - TRACE_DEVEL("%s XCP_MOD_VERSION: %u\n", __func__, module.version); - - if (ep11_data->target_list.length == 0) { - /* APQN_ANY: Create an empty module group */ -- rc = dll_m_add_module(&module, &ep11_data->target); -+ rc = dll_m_add_module(&module, &target_info->target); - if (rc != CKR_OK) { - TRACE_ERROR("%s dll_m_add_module (ANY) failed: rc=%ld\n", - __func__, rc); -@@ -11414,11 +11540,12 @@ static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata) - XCPTGTMASK_SET_DOM(module.domainmask, - ep11_data->target_list.apqns[2 * i + 1]); - -- rc = dll_m_add_module(&module, &ep11_data->target); -+ rc = dll_m_add_module(&module, &target_info->target); - if (rc != CKR_OK) { - TRACE_ERROR("%s dll_m_add_module (%02x.%04x) failed: rc=%ld\n", - __func__, ep11_data->target_list.apqns[2 * i], - ep11_data->target_list.apqns[2 * i + 1], rc); -+ dll_m_rm_module(NULL, target_info->target); - return CKR_FUNCTION_FAILED; - } - } -@@ -11494,6 +11621,7 @@ CK_RV token_specific_set_attribute_values(STDLL_TokData_t *tokdata, OBJECT *obj, - CK_ULONG num_attributes = 0; - CK_ATTRIBUTE *attr; - CK_RV rc; -+ ep11_target_info_t* target_info; - - rc = template_attribute_get_ulong(obj->template, CKA_CLASS, &class); - if (rc != CKR_OK) { -@@ -11575,9 +11703,18 @@ CK_RV token_specific_set_attribute_values(STDLL_TokData_t *tokdata, OBJECT *obj, - goto out; - } - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) { -+ rc = CKR_FUNCTION_FAILED; -+ goto out; -+ } -+ - rc = dll_m_SetAttributeValue(ibm_opaque_attr->pValue, - ibm_opaque_attr->ulValueLen, attributes, -- num_attributes, ep11_data->target); -+ num_attributes, target_info->target); -+ -+ put_target_info(tokdata, target_info); -+ - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s m_SetAttributeValue failed rc=0x%lx\n", -@@ -11601,3 +11738,233 @@ out: - return rc; - } - -+/* -+ * ATTENTION: This function is called in a separate thread. All actions -+ * performed by this function must be thread save and use locks to lock -+ * against concurrent access by other threads. -+ */ -+static CK_RV ep11tok_handle_apqn_event(STDLL_TokData_t *tokdata, -+ unsigned int event_type, -+ event_udev_apqn_data_t *apqn_data) -+{ -+ ep11_private_data_t *ep11_data = tokdata->private_data; -+ CK_BBOOL found = FALSE; -+ CK_RV rc = CKR_OK; -+ char name[20]; -+ int i; -+ -+ /* Is it one of the configured APQNs ?*/ -+ if (ep11_data->target_list.length > 0) { -+ /* APQN_WHITELIST is specified */ -+ for (i = 0; i < ep11_data->target_list.length; i++) { -+ if (ep11_data->target_list.apqns[2 * i] == apqn_data->card && -+ ep11_data->target_list.apqns[2 * i + 1] == apqn_data->domain) { -+ found = TRUE; -+ break; -+ } -+ } -+ } else { -+ /* APQN_ANY is specified */ -+ found = TRUE; -+ if (event_type == EVENT_TYPE_APQN_ADD) { -+ snprintf(name, sizeof(name), "card%02x", apqn_data->card); -+ if (is_card_ep11_and_online(name) != CKR_OK) -+ found = FALSE; /* Not an EP11 APQN */ -+ } -+ } -+ if (!found) -+ return CKR_OK; -+ -+ TRACE_DEVEL("%s Refreshing target infos due to event for APQN %02x.%04x\n", -+ __func__, apqn_data->card, apqn_data->domain); -+ -+ rc = refresh_target_info(tokdata); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s Failed to get the target infos (refresh_target_info " -+ "rc=0x%lx)\n", __func__, rc); -+ OCK_SYSLOG(LOG_ERR, "%s: Failed to get the target info rc=0x%lx\n", -+ __func__, rc); -+ return rc; -+ } -+ -+ return CKR_OK; -+} -+ -+/* -+ * Called by the event thread, on receipt of an event. -+ * -+ * ATTENTION: This function is called in a separate thread. All actions -+ * performed by this function must be thread save and use locks to lock -+ * against concurrent access by other threads. -+ */ -+CK_RV token_specific_handle_event(STDLL_TokData_t *tokdata, -+ unsigned int event_type, -+ unsigned int event_flags, -+ const char *payload, -+ unsigned int payload_len) -+{ -+ UNUSED(event_flags); -+ -+ switch (event_type) { -+ case EVENT_TYPE_APQN_ADD: -+ case EVENT_TYPE_APQN_REMOVE: -+ if (payload_len != sizeof(event_udev_apqn_data_t)) -+ return CKR_FUNCTION_FAILED; -+ return ep11tok_handle_apqn_event(tokdata, event_type, -+ (event_udev_apqn_data_t *)payload); -+ -+ default: -+ return CKR_FUNCTION_NOT_SUPPORTED; -+ } -+ -+ return CKR_OK; -+} -+ -+/* -+ * Refreshes the target info using the currently configured and available -+ * APQNs. Registers the newly allocated target info as the current one in a -+ * thread save way and gives back the previous one so that it is release when -+ * no longer used (i.e. by a concurrently running thread). -+ */ -+static CK_RV refresh_target_info(STDLL_TokData_t *tokdata) -+{ -+ ep11_private_data_t *ep11_data = tokdata->private_data; -+ volatile ep11_target_info_t *prev_info; -+ ep11_target_info_t *target_info; -+ CK_RV rc; -+ -+ target_info = calloc(1, sizeof(ep11_target_info_t)); -+ if (target_info == NULL) { -+ TRACE_ERROR("%s Memory allocation failed\n", __func__); -+ return CKR_HOST_MEMORY; -+ } -+ -+ target_info->ref_count = 1; -+ -+ /* Get the version info freshly with the current set of APQNs */ -+ rc = ep11tok_get_ep11_version(tokdata, target_info); -+ if (rc != 0) -+ goto error; -+ -+ /* Get the control points freshly with the current set of APQNs */ -+ target_info->control_points_len = sizeof(target_info->control_points); -+ rc = get_control_points(tokdata, target_info->control_points, -+ &target_info->control_points_len, -+ &target_info->max_control_point_index); -+ if (rc != 0) -+ goto error; -+ -+ /* Setup the group target freshly with the current set of APQNs */ -+ rc = ep11tok_setup_target(tokdata, target_info); -+ if (rc != CKR_OK) -+ goto error; -+ -+ /* Set the new one as the current one (locked against concurrent get's) */ -+ if (pthread_rwlock_wrlock(&ep11_data->target_rwlock) != 0) { -+ TRACE_DEVEL("Target Write-Lock failed.\n"); -+ rc = CKR_CANT_LOCK; -+ goto error; -+ } -+ -+ prev_info = ep11_data->target_info; -+ ep11_data->target_info = target_info; -+ -+ if (pthread_rwlock_unlock(&ep11_data->target_rwlock) != 0) { -+ TRACE_DEVEL("Target Unlock failed.\n"); -+ return CKR_CANT_LOCK; -+ } -+ -+ /* Release the previous one */ -+ if (prev_info != NULL) -+ put_target_info(tokdata, (ep11_target_info_t *)prev_info); -+ -+ return CKR_OK; -+ -+error: -+ free_card_versions(target_info->card_versions); -+ free((void *)target_info); -+ return rc; -+} -+ -+/* -+ * Get the current EP11 target info. -+ * Do NOT use the ep11_data->target_info directly, always get a copy using -+ * this function. This will increment the reference count of the target info, -+ * and return the current target info in a thread save way. -+ * When no longer needed, put it back using put_target_info(). -+ */ -+static ep11_target_info_t *get_target_info(STDLL_TokData_t *tokdata) -+{ -+ ep11_private_data_t *ep11_data = tokdata->private_data; -+ volatile ep11_target_info_t *target_info; -+#ifdef DEBUG -+ unsigned long ref_count; -+#endif -+ -+ /* -+ * Lock until we have obtained the current target info and have -+ * increased the reference counter -+ */ -+ if (pthread_rwlock_rdlock(&ep11_data->target_rwlock) != 0) { -+ TRACE_DEVEL("Target Read-Lock failed.\n"); -+ return NULL; -+ } -+ -+ target_info = *((void * volatile *)&ep11_data->target_info); -+ if (target_info == NULL) { -+ TRACE_ERROR("%s: target_info is NULL\n", __func__); -+ return NULL; -+ } -+ -+#ifdef DEBUG -+ ref_count = __sync_add_and_fetch(&target_info->ref_count, 1); -+ -+ TRACE_DEBUG("%s: target_info: %p ref_count: %lu\n", __func__, -+ (void *)target_info, ref_count); -+#else -+ __sync_add_and_fetch(&target_info->ref_count, 1); -+#endif -+ -+ if (pthread_rwlock_unlock(&ep11_data->target_rwlock) != 0) { -+ TRACE_DEVEL("Target Unlock failed.\n"); -+ return NULL; -+ } -+ -+ return (ep11_target_info_t *)target_info; -+} -+ -+/* -+ * Give back an EP11 target info. This will decrement the reference count, -+ * and will free it if the reference count reaches zero. -+ */ -+static void put_target_info(STDLL_TokData_t *tokdata, -+ ep11_target_info_t *target_info) -+{ -+ ep11_private_data_t *ep11_data = tokdata->private_data; -+ unsigned long ref_count; -+ -+ if (target_info == NULL) -+ return; -+ -+ if (target_info->ref_count > 0) { -+ ref_count = __sync_sub_and_fetch(&target_info->ref_count, 1); -+ -+ TRACE_DEBUG("%s: target_info: %p ref_count: %lu\n", __func__, -+ (void *)target_info, ref_count); -+ } else { -+ TRACE_WARNING("%s: target_info: %p ref_count already 0.\n", __func__, -+ (void *)target_info); -+ ref_count = 0; -+ } -+ -+ if (ref_count == 0 && target_info != ep11_data->target_info) { -+ TRACE_DEBUG("%s: target_info: %p is freed\n", __func__, -+ (void *)target_info); -+ -+ if (dll_m_rm_module != NULL) -+ dll_m_rm_module(NULL, target_info->target); -+ free_card_versions(target_info->card_versions); -+ free(target_info); -+ } -+} -+ -diff --git a/usr/lib/ep11_stdll/ep11_specific.h b/usr/lib/ep11_stdll/ep11_specific.h -index 55fc023c..343f4b3d 100644 ---- a/usr/lib/ep11_stdll/ep11_specific.h -+++ b/usr/lib/ep11_stdll/ep11_specific.h -@@ -161,7 +161,7 @@ CK_BBOOL ep11tok_libica_mech_available(STDLL_TokData_t *tokdata, - CK_MECHANISM_TYPE mech, - CK_OBJECT_HANDLE hKey); - --void ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata, -+CK_RV ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata, - CK_TOKEN_INFO_PTR pInfo); - - CK_BBOOL ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session, -diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c -index 4e592363..cd12604e 100644 ---- a/usr/lib/ep11_stdll/new_host.c -+++ b/usr/lib/ep11_stdll/new_host.c -@@ -298,7 +298,7 @@ CK_RV SC_GetTokenInfo(STDLL_TokData_t *tokdata, CK_SLOT_ID sid, - goto done; - } - copy_token_contents_sensibly(pInfo, tokdata->nv_token_data); -- ep11tok_copy_firmware_info(tokdata, pInfo); -+ rc = ep11tok_copy_firmware_info(tokdata, pInfo); - - /* Set the time */ - now = time((time_t *) NULL); -diff --git a/usr/lib/ep11_stdll/tok_struct.h b/usr/lib/ep11_stdll/tok_struct.h -index 2c0af9cf..01268c67 100644 ---- a/usr/lib/ep11_stdll/tok_struct.h -+++ b/usr/lib/ep11_stdll/tok_struct.h -@@ -137,7 +137,7 @@ token_spec_t token_specific = { - &token_specific_reencrypt_single, - &token_specific_set_attribute_values, - &token_specific_set_attrs_for_new_object, -- NULL, // handle_event -+ &token_specific_handle_event, - }; - - #endif diff --git a/opencryptoki-3.16.0-342dfbeb8275f5ea6ed52dd3f30126614ec1d037.patch b/opencryptoki-3.16.0-342dfbeb8275f5ea6ed52dd3f30126614ec1d037.patch deleted file mode 100644 index 76ce00d..0000000 --- a/opencryptoki-3.16.0-342dfbeb8275f5ea6ed52dd3f30126614ec1d037.patch +++ /dev/null @@ -1,2159 +0,0 @@ -commit 342dfbeb8275f5ea6ed52dd3f30126614ec1d037 -Author: Ingo Franzki -Date: Mon Feb 15 14:33:07 2021 +0100 - - Event support: pkcsslotd changes - - Signed-off-by: Ingo Franzki - -diff --git a/configure.ac b/configure.ac -index e0ae4a82..a0b098e1 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -234,6 +234,12 @@ AC_ARG_WITH([systemd], - AS_HELP_STRING([--with-systemd@<:@=DIR@:>@],[systemd system unit files location]), - [], - [with_systemd=no]) -+ -+dnl --- libudev development files -+AC_ARG_WITH([libudev], -+ AS_HELP_STRING([--with-libudev@<:@=DIR@:>@],[libudev development files location]), -+ [], -+ [with_libudev=check]) - - dnl --- - dnl --- -@@ -438,6 +444,46 @@ fi - AC_SUBST([XCRYPTOLINZ_CFLAGS]) - AC_SUBST([XCRYPTOLINZ_LIBS]) - -+dnl --- with_libudev -+LIBUDEV_CFLAGS= -+LIBUDEV_LIBS= -+if test "x$with_libudev" != "xno"; then -+ if test "x$with_libudev" != "xyes" -a "x$with_libudev" != "xcheck"; then -+ LIBUDEV_CFLAGS="-I$with_libudev" -+ LIBUDEV_LIBS="-L$with_libudev" -+ fi -+ old_cflags="$CFLAGS" -+ old_libs="$LIBS" -+ CFLAGS="$CFLAGS $LIBUDEV_CFLAGS" -+ LIBS="$LIBS $LIBUDEV_LIBS" -+ # Use libudev only on s390 platforms, only s390 emits AP related uevents -+ case $target in -+ *s390x* | *s390*) -+ CFLAGS="$CFLAGS -DWITH_LIBUDEV" -+ ;; -+ *) -+ if test "x$with_libudev" != "xyes"; then -+ with_libudev=no -+ echo "Default to 'with_libudev=no' on non-s390 platforms" -+ fi -+ ;; -+ esac -+ if test "x$with_libudev" != "xno"; then -+ AC_CHECK_HEADER([libudev.h], [with_libudev=yes], [ -+ AC_MSG_ERROR([Build with libudev requested but libudev headers couldn't be found]) -+ ]) -+ AC_CHECK_LIB([udev], [udev_monitor_new_from_netlink], [with_libudev=yes], [ -+ AC_MSG_ERROR([Build with libudev requested but libudev libraries couldn't be found]) -+ ]) -+ fi -+ if test "x$with_libudev" = "xno"; then -+ CFLAGS="$old_cflags" -+ LIBS="$old_libs" -+ fi -+fi -+AC_SUBST([LIBUDEV_CFLAGS]) -+AC_SUBST([LIBUDEV_LIBS]) -+AM_CONDITIONAL([HAVE_LIBUDEV], [test "x$with_libudev" = "xyes"]) - - dnl --- - dnl --- Now check enabled features, while making sure every required -@@ -649,6 +695,7 @@ echo " Daemon build: $enable_daemon" - echo " Library build: $enable_library" - echo " Systemd service: $enable_systemd" - echo " Build with locks: $enable_locks" -+echo " Build with libudev: $with_libudev" - echo " Build p11sak tool: $enable_p11sak" - echo " token migrate tool: $enable_pkcstok_migrate" - echo -diff --git a/usr/include/slotmgr.h b/usr/include/slotmgr.h -index 4d038435..e37368a5 100644 ---- a/usr/include/slotmgr.h -+++ b/usr/include/slotmgr.h -@@ -31,6 +31,7 @@ - #define OCK_API_LOCK_FILE LOCKDIR_PATH "/LCK..APIlock" - - #define PROC_SOCKET_FILE_PATH "/var/run/pkcsslotd.socket" -+#define ADMIN_SOCKET_FILE_PATH "/var/run/pkcsslotd.admin.socket" - - #define PID_FILE_PATH "/var/run/pkcsslotd.pid" - #define OCK_CONFIG OCK_CONFDIR "/opencryptoki.conf" -@@ -45,6 +46,7 @@ - - #define NUMBER_SLOTS_MANAGED 1024 - #define NUMBER_PROCESSES_ALLOWED 1000 -+#define NUMBER_ADMINS_ALLOWED 1000 - - // - // Per Process Data structure -diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h -index 69eb59f3..d7edcb3c 100644 ---- a/usr/sbin/pkcsslotd/pkcsslotd.h -+++ b/usr/sbin/pkcsslotd/pkcsslotd.h -@@ -92,5 +92,8 @@ int init_socket_server(); - int term_socket_server(); - int init_socket_data(Slot_Mgr_Socket_t *sp); - int socket_connection_handler(int timeout_secs); -+#ifdef DEV -+void dump_socket_handler(); -+#endif - - #endif /* _SLOTMGR_H */ -diff --git a/usr/sbin/pkcsslotd/pkcsslotd.mk b/usr/sbin/pkcsslotd/pkcsslotd.mk -index 2d36b4a9..c574edf8 100644 ---- a/usr/sbin/pkcsslotd/pkcsslotd.mk -+++ b/usr/sbin/pkcsslotd/pkcsslotd.mk -@@ -8,6 +8,9 @@ CLEANFILES += usr/lib/common/parser.c usr/lib/common/parser.h \ - usr/lib/common/parser.output usr/lib/common/lexer.c - - usr_sbin_pkcsslotd_pkcsslotd_LDFLAGS = -lpthread -lcrypto -+if HAVE_LIBUDEV -+usr_sbin_pkcsslotd_pkcsslotd_LDFLAGS += -ludev -+endif - - usr_sbin_pkcsslotd_pkcsslotd_CFLAGS = -DPROGRAM_NAME=\"$(@)\" \ - -I${srcdir}/usr/include -I${srcdir}/usr/lib/common \ -diff --git a/usr/sbin/pkcsslotd/signal.c b/usr/sbin/pkcsslotd/signal.c -index 49482a2f..17167632 100644 ---- a/usr/sbin/pkcsslotd/signal.c -+++ b/usr/sbin/pkcsslotd/signal.c -@@ -21,7 +21,7 @@ - extern BOOL IsValidProcessEntry(pid_t_64 pid, time_t_64 RegTime); - - static int SigsToIntercept[] = { -- SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, -+ SIGHUP, SIGINT, SIGQUIT, SIGALRM, - SIGTERM, SIGTSTP, SIGTTIN, - SIGTTOU, SIGUSR1, SIGUSR2, SIGPROF - }; -@@ -32,8 +32,11 @@ static int SigsToIntercept[] = { - /* SIGCHLD - Don't want to exit. Should never receive, but we do, apparently - * when something tries to cancel the GC Thread */ - -+/* SIGPIPE - Don't want to exit. May happen when a connection to an admin -+ * event sender or a process is closed before all events are delivered. */ -+ - static int SigsToIgnore[] = { -- SIGCHLD, -+ SIGCHLD, SIGPIPE, - }; - - -@@ -71,6 +74,10 @@ void slotdGenericSignalHandler(int Signal) - CheckForGarbage(shmp); - #endif - -+#ifdef DEV -+ dump_socket_handler(); -+#endif -+ - for (procindex = 0; (procindex < NUMBER_PROCESSES_ALLOWED); procindex++) { - - Slot_Mgr_Proc_t_64 *pProc = &(shmp->proc_table[procindex]); -diff --git a/usr/sbin/pkcsslotd/socket_server.c b/usr/sbin/pkcsslotd/socket_server.c -index 1fae0b95..41408670 100644 ---- a/usr/sbin/pkcsslotd/socket_server.c -+++ b/usr/sbin/pkcsslotd/socket_server.c -@@ -1,4 +1,6 @@ - /* -+ * COPYRIGHT (c) International Business Machines Corp. 2013, 2021 -+ * - * This program is provided under the terms of the Common Public License, - * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this - * software constitutes recipient's acceptance of CPL-1.0 terms which can be -@@ -12,6 +14,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -19,32 +23,1225 @@ - #include - #include - #include -+#include -+ -+#if defined(__GNUC__) && __GNUC__ >= 7 || defined(__clang__) && __clang_major__ >= 12 -+ #define FALL_THROUGH __attribute__ ((fallthrough)) -+#else -+ #define FALL_THROUGH ((void)0) -+#endif -+ -+#ifdef WITH_LIBUDEV -+#include -+#endif - - #include "log.h" - #include "slotmgr.h" - #include "pkcsslotd.h" - #include "apictl.h" -+#include "dlist.h" -+#include "events.h" -+ -+#define MAX_EPOLL_EVENTS 128 -+ -+#ifdef WITH_LIBUDEV -+#define UDEV_RECV_BUFFFER_SIZE 512 * 1024 -+#define UDEV_SUBSYSTEM_AP "ap" -+#define UDEV_ACTION_BIND "bind" -+#define UDEV_ACTION_UNBIND "unbind" -+#define UDEV_ACTION_DEVTYPE_APQN "ap_queue" -+#define UDEV_PROERTY_DEVTYPE "DEV_TYPE" -+#endif -+ -+struct epoll_info { -+ int (* notify)(int events, void *private); -+ void (* free)(void *private); -+ void *private; -+ unsigned long ref_count; -+}; -+ -+struct listener_info { -+ int socket; -+ const char *file_path; -+ int (* new_conn)(int socket, struct listener_info *listener); -+ struct epoll_info ep_info; -+ unsigned long num_clients; -+ unsigned long max_num_clients; -+}; -+ -+enum xfer_state { -+ XFER_IDLE = 0, -+ XFER_RECEIVE = 1, -+ XFER_SEND = 2, -+}; -+ -+struct client_info { -+ int socket; -+ int (* xfer_complete)(void *client); -+ void (* hangup)(void *client); -+ void (* free)(void *client); -+ void *client; -+ struct epoll_info ep_info; -+ enum xfer_state xfer_state; -+ char *xfer_buffer; -+ size_t xfer_size; -+ size_t xfer_offset; -+}; -+ -+enum proc_state { -+ PROC_INITIAL_SEND = 0, -+ PROC_WAIT_FOR_EVENT = 1, -+ PROC_SEND_EVENT = 2, -+ PROC_SEND_PAYLOAD = 3, -+ PROC_RECEIVE_REPLY = 4, -+ PROC_HANGUP = 5, -+}; -+ -+struct proc_conn_info { -+ struct client_info client_info; -+ enum proc_state state; -+ DL_NODE *events; -+ struct event_info *event; -+ event_reply_t reply; -+}; -+ -+enum admin_state { -+ ADMIN_RECEIVE_EVENT = 0, -+ ADMIN_RECEIVE_PAYLOAD = 1, -+ ADMIN_EVENT_DELIVERED = 2, -+ ADMIN_SEND_REPLY = 3, -+ ADMIN_WAIT_FOR_EVENT_LIMIT = 4, -+ ADMIN_HANGUP = 5, -+}; -+ -+struct admin_conn_info { -+ struct client_info client_info; -+ enum admin_state state; -+ struct event_info *event; -+}; -+ -+#ifdef WITH_LIBUDEV -+struct udev_mon { -+ struct udev *udev; -+ struct udev_monitor *mon; -+ int socket; -+ struct epoll_info ep_info; -+ struct event_info *delayed_event; -+}; -+#endif -+ -+struct event_info { -+ event_msg_t event; -+ char *payload; -+ event_reply_t reply; -+ unsigned long proc_ref_count; /* # of processes using this event */ -+ struct admin_conn_info *admin_ref; /* Admin connection to send reply back */ -+}; -+ -+static int epoll_fd = -1; -+static struct listener_info proc_listener; -+static DL_NODE *proc_connections = NULL; -+static struct listener_info admin_listener; -+static DL_NODE *admin_connections = NULL; -+#ifdef WITH_LIBUDEV -+static struct udev_mon udev_mon; -+#endif -+static DL_NODE *pending_events = NULL; -+static unsigned long pending_events_count = 0; -+ -+#define MAX_PENDING_EVENTS 1024 -+ -+/* -+ * Iterate over all connections in a safe way. Before actually iterating, -+ * increment the ref count of ALL connections, because any processing may -+ * cause any of the connections to be hang-up, and thus freed and removed -+ * from the list. We need to make sure that while we are iterating over the -+ * connections, none of them gets removed from the list. -+ */ -+#define FOR_EACH_CONN_SAFE_BEGIN(list, conn) { \ -+ DL_NODE *_node, *_next; \ -+ _node = dlist_get_first(list); \ -+ while (_node != NULL) { \ -+ conn = _node->data; \ -+ _next = dlist_next(_node); \ -+ client_socket_get(&(conn)->client_info); \ -+ _node = _next; \ -+ } \ -+ _node = dlist_get_first(list); \ -+ while (_node != NULL) { \ -+ conn = _node->data; \ -+ _next = dlist_next(_node); -+ -+#define FOR_EACH_CONN_SAFE_END(list, conn) \ -+ _node = _next; \ -+ } \ -+ _node = dlist_get_first(list); \ -+ while (_node != NULL) { \ -+ conn = _node->data; \ -+ _next = dlist_next(_node); \ -+ client_socket_put(&(conn)->client_info); \ -+ _node = _next; \ -+ } \ -+ } -+ -+ -+ -+static void listener_socket_close(int socketfd, const char *file_path); -+static int listener_client_hangup(struct listener_info *listener); -+static void event_delivered(struct event_info *event); -+static int client_socket_notify(int events, void *private); -+static void client_socket_free(void *private); -+static int proc_xfer_complete(void *client); -+static int proc_start_deliver_event(struct proc_conn_info *conn); -+static int proc_deliver_event(struct proc_conn_info *conn, -+ struct event_info *event); -+static int proc_event_delivered(struct proc_conn_info *conn, -+ struct event_info *event); -+static inline void proc_get(struct proc_conn_info *conn); -+static inline void proc_put(struct proc_conn_info *conn); -+static void proc_hangup(void *client); -+static void proc_free(void *client); -+static int admin_xfer_complete(void *client); -+static void admin_event_limit_underrun(struct admin_conn_info *conn); -+static int admin_event_delivered(struct admin_conn_info *conn, -+ struct event_info *event); -+static inline void admin_get(struct admin_conn_info *conn); -+static inline void admin_put(struct admin_conn_info *conn); -+static void admin_hangup(void *client); -+static void admin_free(void *client); -+#ifdef WITH_LIBUDEV -+static void udev_mon_term(struct udev_mon *udev_mon); -+static int udev_mon_notify(int events, void *private); -+#endif -+ -+static void epoll_info_init(struct epoll_info *epoll_info, -+ int (* notify)(int events, void *private), -+ void (* free_cb)(void *private), -+ void *private) -+{ -+ epoll_info->ref_count = 1; -+ epoll_info->notify = notify; -+ epoll_info->free = free_cb; -+ epoll_info->private = private; -+} -+ -+static void epoll_info_get(struct epoll_info *epoll_info) -+{ -+ epoll_info->ref_count++; -+ -+ DbgLog(DL3, "%s: private: %p, ref_count: %lu", __func__, -+ epoll_info->private, epoll_info->ref_count); -+} -+ -+static void epoll_info_put(struct epoll_info *epoll_info) -+{ -+ if (epoll_info->ref_count > 0) -+ epoll_info->ref_count--; -+ -+ DbgLog(DL3, "%s: private: %p, ref_count: %lu", __func__, -+ epoll_info->private, epoll_info->ref_count); -+ -+ if (epoll_info->ref_count == 0 && epoll_info->free != NULL) -+ epoll_info->free(epoll_info->private); -+} -+ -+static int client_socket_init(int socket, int (* xfer_complete)(void *client), -+ void (* hangup)(void *client), -+ void (* free_cb)(void *client), void *client, -+ struct client_info *client_info) -+{ -+ struct epoll_event evt; -+ int rc, err; -+ -+ if (xfer_complete == NULL || hangup == NULL) -+ return -EINVAL; -+ -+ epoll_info_init(&client_info->ep_info, client_socket_notify, -+ client_socket_free, client_info); -+ client_info->socket = socket; -+ client_info->xfer_complete = xfer_complete; -+ client_info->hangup = hangup; -+ client_info->free = free_cb; -+ client_info->client = client; -+ client_info->xfer_state = XFER_IDLE; -+ -+ rc = fcntl(socket, F_SETFL, O_NONBLOCK); -+ if (rc < 0) { -+ err = errno; -+ InfoLog("%s: Failed to set client socket %d to non-blocking, errno " -+ "%d (%s).", __func__, socket, err, strerror(err)); -+ return -err; -+ } -+ -+ evt.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLERR | EPOLLET; -+ evt.data.ptr = &client_info->ep_info; -+ rc = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket, &evt); -+ if (rc != 0) { -+ err = errno; -+ InfoLog("%s: Failed to add client socket %d to epoll, errno %d (%s).", -+ __func__, socket, err, strerror(err)); -+ close(socket); -+ return -err; -+ } -+ -+ return 0; -+} -+ -+static inline void client_socket_get(struct client_info *client_info) -+{ -+ epoll_info_get(&client_info->ep_info); -+} -+ -+static inline void client_socket_put(struct client_info *client_info) -+{ -+ epoll_info_put(&client_info->ep_info); -+} -+ -+static void client_socket_term(struct client_info *client_info) -+{ -+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_info->socket, NULL); -+ close(client_info->socket); -+ client_info->socket = -1; -+} -+ -+static int client_socket_notify(int events, void *private) -+{ -+ struct client_info *client_info = private; -+ ssize_t num; -+ int rc, err, socket = client_info->socket; -+ -+ DbgLog(DL3, "%s: Epoll event on client %p socket %d: events: 0x%x xfer: %d", -+ __func__, client_info, socket, events, client_info->xfer_state); -+ -+ if (socket < 0) -+ return -ENOTCONN; -+ -+ if (events & (EPOLLHUP | EPOLLERR)) { -+ DbgLog(DL3, "EPOLLHUP | EPOLLERR"); -+ -+ client_info->hangup(client_info->client); -+ client_info = NULL; /* client_info may have been freed by now */ -+ return 0; -+ } -+ -+ if (client_info->xfer_state == XFER_RECEIVE && (events & EPOLLIN)) { -+ DbgLog(DL3, "%s: EPOLLIN: buffer: %p size: %lu ofs: %lu", __func__, -+ client_info->xfer_buffer, client_info->xfer_size, -+ client_info->xfer_offset); -+ -+ num = read(client_info->socket, -+ client_info->xfer_buffer + client_info->xfer_offset, -+ client_info->xfer_size - client_info->xfer_offset); -+ if (num <= 0) { -+ err = errno; -+ -+ DbgLog(DL3, "%s: read failed with: num: %d errno: %d (%s)", -+ __func__, num, num < 0 ? err : 0, -+ num < 0 ? strerror(err) : "none"); -+ -+ if (num < 0 && err == EWOULDBLOCK) -+ return 0; /* Will be continued when socket becomes readable */ -+ -+ /* assume connection closed by peer */ -+ client_info->hangup(client_info->client); -+ client_info = NULL; /* client_info may have been freed by now */ -+ return 0; -+ } else { -+ DbgLog(DL3, "%s: %lu bytes received", __func__, num); -+ -+ client_info->xfer_offset += num; -+ -+ DbgLog(DL3, "%s: %lu bytes left", __func__, -+ client_info->xfer_size - client_info->xfer_offset); -+ -+ if (client_info->xfer_offset >= client_info->xfer_size) { -+ client_info->xfer_state = XFER_IDLE; -+ client_info->xfer_buffer = NULL; -+ client_info->xfer_size = 0; -+ client_info->xfer_offset = 0; -+ -+ client_socket_get(client_info); -+ rc = client_info->xfer_complete(client_info->client); -+ if (rc != 0) { -+ InfoLog("%s: xfer_complete callback failed for client " -+ "socket %d, rc: %d", __func__, socket, -+ rc); -+ client_info->hangup(client_info->client); -+ } -+ client_socket_put(client_info); -+ client_info = NULL; /* client_info may have been freed by now */ -+ return rc; -+ } -+ return 0; -+ } -+ } -+ -+ if (client_info->xfer_state == XFER_SEND && (events & EPOLLOUT)) { -+ DbgLog(DL3, "%s: EPOLLOUT: buffer: %p size: %lu ofs: %lu", __func__, -+ client_info->xfer_buffer, client_info->xfer_size, -+ client_info->xfer_offset); -+ -+ num = write(client_info->socket, -+ client_info->xfer_buffer + client_info->xfer_offset, -+ client_info->xfer_size - client_info->xfer_offset); -+ if (num < 0) { -+ err = errno; -+ -+ DbgLog(DL3, "%s: write failed with: errno: %d (%s)", __func__, err, -+ strerror(err)); -+ -+ if (err == EWOULDBLOCK) -+ return 0; /* Will be continued when socket becomes writable */ -+ -+ /* assume connection closed by peer */ -+ client_info->hangup(client_info->client); -+ client_info = NULL; /* client_info may have been freed by now */ -+ return 0; -+ } else { -+ DbgLog(DL3, "%s: %lu bytes sent", __func__, num); -+ -+ client_info->xfer_offset += num; -+ -+ DbgLog(DL3, "%s: %lu bytes left", __func__, -+ client_info->xfer_size - client_info->xfer_offset); -+ -+ if (client_info->xfer_offset >= client_info->xfer_size) { -+ client_info->xfer_state = XFER_IDLE; -+ client_info->xfer_buffer = NULL; -+ client_info->xfer_size = 0; -+ client_info->xfer_offset = 0; -+ -+ client_socket_get(client_info); -+ rc = client_info->xfer_complete(client_info->client); -+ if (rc != 0) { -+ InfoLog("%s: xfer_complete callback failed for client " -+ "socket %d, rc: %d", __func__, socket, -+ rc); -+ client_info->hangup(client_info->client); -+ } -+ client_socket_put(client_info); -+ client_info = NULL; /* client_info may have been freed by now */ -+ return rc; -+ } -+ return 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static void client_socket_free(void *private) -+{ -+ struct client_info *client_info = private; -+ -+ DbgLog(DL3, "%s: %p", __func__, client_info); -+ -+ if (client_info->free != NULL) -+ client_info->free(client_info->client); -+} -+ -+static int client_socket_receive(struct client_info *client_info, -+ void *buffer, size_t size) -+{ -+ if (client_info->socket < 0) -+ return -ENOTCONN; -+ -+ client_info->xfer_state = XFER_RECEIVE; -+ client_info->xfer_buffer = (char *)buffer; -+ client_info->xfer_size = size; -+ client_info->xfer_offset = 0; -+ -+ DbgLog(DL3, "%s: Start receive on client socket %d: buffer: %p size: %lu", -+ __func__, client_info->socket, buffer, size); -+ -+ return client_socket_notify(EPOLLIN, client_info); -+} -+ -+ -+static int client_socket_send(struct client_info *client_info, -+ void *buffer, size_t size) -+{ -+ if (client_info->socket < 0) -+ return -ENOTCONN; -+ -+ client_info->xfer_state = XFER_SEND; -+ client_info->xfer_buffer = (char *)buffer; -+ client_info->xfer_size = size; -+ client_info->xfer_offset = 0; -+ -+ DbgLog(DL3, "%s: Start send on client socket %d: buffer: %p size: %lu", -+ __func__, client_info->socket, buffer, size); -+ -+ return client_socket_notify(EPOLLOUT, client_info); -+} -+ -+static struct event_info *event_new(unsigned int payload_len, -+ struct admin_conn_info *admin_conn) -+{ -+ struct event_info *event; -+ -+ event = calloc(1, sizeof(struct event_info)); -+ if (event == NULL) { -+ ErrLog("%s: Failed to allocate the event", __func__); -+ return NULL; -+ } -+ -+ event->event.version = EVENT_VERSION_1; -+ event->event.payload_len = payload_len; -+ if (payload_len > 0) { -+ event->payload = malloc(payload_len); -+ if (event->payload == NULL) { -+ ErrLog("%s: Failed to allocate the event payload", __func__); -+ free(event); -+ return NULL; -+ } -+ } -+ -+ event->reply.version = EVENT_VERSION_1; -+ -+ if (admin_conn != NULL) -+ admin_get(admin_conn); -+ event->admin_ref = admin_conn; -+ -+ DbgLog(DL3, "%s: allocated event: %p", __func__, event); -+ return event; -+} -+ -+static void event_limit_underrun() -+{ -+ struct admin_conn_info *conn; -+ -+ DbgLog(DL3, "%s: pending_events_count: %lu", __func__, pending_events_count); -+ -+#ifdef WITH_LIBUDEV -+ /* Notify the udev monitor */ -+ udev_mon_notify(EPOLLIN, &udev_mon); -+#endif -+ -+ /* Notify all admin connections */ -+ FOR_EACH_CONN_SAFE_BEGIN(admin_connections, conn) { -+ admin_event_limit_underrun(conn); -+ } -+ FOR_EACH_CONN_SAFE_END(admin_connections, conn) -+} -+ -+static void event_free(struct event_info *event) -+{ -+ DbgLog(DL3, "%s: free event: %p", __func__, event); -+ -+ if (event->payload != NULL) -+ free(event->payload); -+ free(event); -+} -+ -+static int event_add_to_pending_list(struct event_info *event) -+{ -+ DL_NODE *list; -+ -+ list = dlist_add_as_last(pending_events, event); -+ if (list == NULL) { -+ ErrLog("%s: failed add event to list of pending events", __func__); -+ return -ENOMEM; -+ } -+ pending_events = list; -+ -+ pending_events_count++; -+ -+ return 0; -+} -+ -+static void event_remove_from_pending_list(struct event_info *event) -+{ -+ DL_NODE *node; -+ int trigger = 0; -+ -+ node = dlist_find(pending_events, event); -+ if (node != NULL) { -+ pending_events = dlist_remove_node(pending_events, node); -+ -+ if (pending_events_count >= MAX_PENDING_EVENTS) -+ trigger = 1; -+ -+ if (pending_events_count > 0) -+ pending_events_count--; -+ -+ if (trigger) -+ event_limit_underrun(); -+ } -+} -+ -+static int event_start_deliver(struct event_info *event) -+{ -+ struct proc_conn_info *conn; -+ int rc; -+ -+ DbgLog(DL3, "%s: event: %p", __func__, event); -+ -+ if (pending_events_count >= MAX_PENDING_EVENTS) { -+ InfoLog("%s: Max pending events reached", __func__); -+ return -ENOSPC; -+ } -+ -+ /* Add event of the list of pending events */ -+ rc = event_add_to_pending_list(event); -+ if (rc != 0) -+ return rc; -+ -+ /* -+ * Need to increment the event's ref count here, proc_deliver_event() may -+ * already complete the event delivery for one process, which then would -+ * free the event but it needs to be passed to other processes here, too. -+ */ -+ event->proc_ref_count++; -+ FOR_EACH_CONN_SAFE_BEGIN(proc_connections, conn) { -+ rc = proc_deliver_event(conn, event); -+ if (rc != 0) -+ proc_hangup(conn); -+ } -+ FOR_EACH_CONN_SAFE_END(proc_connections, conn) -+ event->proc_ref_count--; -+ -+ DbgLog(DL3, "%s: proc_ref_count: %u", __func__, event->proc_ref_count); -+ -+ if (event->proc_ref_count == 0) -+ event_delivered(event); -+ -+ return 0; -+} -+ -+static void event_delivered(struct event_info *event) -+{ -+ struct admin_conn_info *conn; -+ int rc; -+ -+ DbgLog(DL3, "%s: event: %p", __func__, event); -+ -+ event_remove_from_pending_list(event); -+ -+ /* Notify owning admin connection (if available), free otherwise */ -+ if (event->admin_ref != NULL) { -+ conn = event->admin_ref; -+ admin_get(conn); -+ rc = admin_event_delivered(conn, event); -+ if (rc != 0) { -+ admin_hangup(conn); -+ event_free(event); -+ } -+ admin_put(conn); -+ } else { -+ event_free(event); -+ } -+} -+ -+static int proc_new_conn(int socket, struct listener_info *listener) -+{ -+ struct proc_conn_info *conn; -+ struct event_info *event; -+ DL_NODE *list, *node; -+ int rc = 0; -+ -+ UNUSED(listener); -+ -+ DbgLog(DL0, "%s: Accepted connection from process: socket: %d", __func__, -+ socket); -+ -+ conn = calloc(1, sizeof(struct proc_conn_info)); -+ if (conn == NULL) { -+ ErrLog("%s: Failed to to allocate memory for the process connection", -+ __func__); -+ return -ENOMEM; -+ /* Caller will close socket */ -+ } -+ -+ DbgLog(DL3, "%s: process conn: %p", __func__, conn); -+ -+ /* Add currently pending events to this connection */ -+ node = dlist_get_first(pending_events); -+ while (node != NULL) { -+ event = (struct event_info *)node->data; -+ DbgLog(DL3, "%s: event: %p", __func__, event); -+ -+ list = dlist_add_as_last(conn->events, event); -+ if (list == NULL) { -+ ErrLog("%s: failed add event to list of process's pending events", -+ __func__); -+ rc = -ENOMEM; -+ goto out; -+ } -+ conn->events = list; -+ -+ event->proc_ref_count++; -+ -+ node = dlist_next(node); -+ } -+ -+ conn->state = PROC_INITIAL_SEND; -+ -+ rc = client_socket_init(socket, proc_xfer_complete, proc_hangup, proc_free, -+ conn, &conn->client_info); -+ if (rc != 0) -+ goto out; -+ -+ /* Add it to the process connections list */ -+ list = dlist_add_as_first(proc_connections, conn); -+ if (list == NULL) { -+ rc = -ENOMEM; -+ goto out; -+ } -+ proc_connections = list; -+ -+ proc_get(conn); -+ rc = client_socket_send(&conn->client_info, &socketData, -+ sizeof(socketData)); -+ proc_put(conn); -+ conn = NULL; /* conn may have been freed by now */ -+ -+out: -+ if (rc != 0 && conn != NULL) { -+ proc_hangup(conn); -+ rc = 0; /* Don't return an error, we have already handled it */ -+ } -+ -+ return rc; -+} -+ -+static int proc_xfer_complete(void *client) -+{ -+ struct proc_conn_info *conn = client; -+ int rc; -+ -+ DbgLog(DL0, "%s: Xfer completed: process: %p socket: %d state: %d", -+ __func__, conn, conn->client_info.socket, conn->state); -+ -+ /* -+ * A non-zero return code returned by this function causes the caller to -+ * call proc_hangup(). Thus, no need to call proc_hangup() ourselves. -+ */ -+ -+ switch (conn->state) { -+ case PROC_INITIAL_SEND: -+ conn->state = PROC_WAIT_FOR_EVENT; -+ rc = proc_start_deliver_event(conn); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ -+ case PROC_WAIT_FOR_EVENT: -+ /* handled in proc_start_deliver_event */ -+ break; -+ -+ case PROC_SEND_EVENT: -+ if (conn->event == NULL) { -+ TraceLog("%s: No current event to handle", __func__); -+ return -EINVAL; -+ } -+ -+ if (conn->event->event.payload_len > 0) { -+ conn->state = PROC_SEND_PAYLOAD; -+ rc = client_socket_send(&conn->client_info, conn->event->payload, -+ conn->event->event.payload_len); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ } -+ FALL_THROUGH; -+ /* fall through */ -+ -+ case PROC_SEND_PAYLOAD: -+ if (conn->event == NULL) { -+ TraceLog("%s: No current event to handle", __func__); -+ return -EINVAL; -+ } -+ -+ if (conn->event->event.flags & EVENT_FLAGS_REPLY_REQ) { -+ conn->state = PROC_RECEIVE_REPLY; -+ rc = client_socket_receive(&conn->client_info, &conn->reply, -+ sizeof(conn->reply)); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ } -+ FALL_THROUGH; -+ /* fall through */ -+ -+ case PROC_RECEIVE_REPLY: -+ if (conn->event == NULL) { -+ TraceLog("%s: No current event to handle", __func__); -+ return -EINVAL; -+ } -+ -+ if (conn->event->event.flags & EVENT_FLAGS_REPLY_REQ) { -+ if (conn->reply.version != EVENT_VERSION_1) { -+ InfoLog("%s: Reply has a wrong version: %u", __func__, -+ conn->reply.version); -+ return -EINVAL; -+ } -+ -+ /* Update reply counters in event */ -+ conn->event->reply.positive_replies += conn->reply.positive_replies; -+ conn->event->reply.negative_replies += conn->reply.negative_replies; -+ conn->event->reply.nothandled_replies += -+ conn->reply.nothandled_replies; -+ } -+ -+ conn->state = PROC_WAIT_FOR_EVENT; -+ -+ rc = proc_event_delivered(conn, conn->event); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ -+ case PROC_HANGUP: -+ break; -+ } -+ -+ return 0; -+} -+ -+static int proc_start_deliver_event(struct proc_conn_info *conn) -+{ -+ DL_NODE *node; -+ int rc; -+ -+ if (conn->state != PROC_WAIT_FOR_EVENT) -+ return 0; -+ -+ node = dlist_get_first(conn->events); -+ if (node == NULL) -+ return 0; -+ -+ conn->event = node->data; -+ memset(&conn->reply, 0, sizeof(conn->reply)); -+ -+ DbgLog(DL3, "%s: process: %p event: %p", __func__, conn, conn->event); -+ -+ conn->state = PROC_SEND_EVENT; -+ rc = client_socket_send(&conn->client_info, &conn->event->event, -+ sizeof(conn->event->event)); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+} -+ -+static int proc_deliver_event(struct proc_conn_info *conn, -+ struct event_info *event) -+{ -+ DL_NODE *list; -+ int rc; -+ -+ DbgLog(DL3, "%s: process: %p event: %p", __func__, conn, event); -+ -+ if (conn->state == PROC_HANGUP) -+ return 0; -+ -+ /* Add to process's event list and incr. reference count */ -+ list = dlist_add_as_last(conn->events, event); -+ if (list == NULL) { -+ ErrLog("%s: failed add event to list of process's pending events", -+ __func__); -+ return -ENOMEM; -+ } -+ conn->events = list; -+ -+ event->proc_ref_count++; -+ -+ rc = proc_start_deliver_event(conn); -+ return rc; -+} -+ -+static int proc_event_delivered(struct proc_conn_info *conn, -+ struct event_info *event) -+{ -+ DL_NODE *node; -+ int rc; -+ -+ DbgLog(DL3, "%s: process: %p event: %p", __func__, conn, event); -+ -+ conn->event = NULL; -+ -+ /* Remove from process's event list and decr. reference count */ -+ node = dlist_find(conn->events, event); -+ if (node != NULL) { -+ conn->events = dlist_remove_node(conn->events, node); -+ event->proc_ref_count--; -+ } -+ -+ DbgLog(DL3, "%s: proc_ref_count: %u", __func__, event->proc_ref_count); -+ -+ if (event->proc_ref_count == 0) -+ event_delivered(event); -+ -+ /* Deliver further pending events, if any */ -+ rc = proc_start_deliver_event(conn); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+} -+ -+static inline void proc_get(struct proc_conn_info *conn) -+{ -+ client_socket_get(&conn->client_info); -+} -+ -+static inline void proc_put(struct proc_conn_info *conn) -+{ -+ client_socket_put(&conn->client_info); -+} -+ -+static void proc_hangup(void *client) -+{ -+ struct proc_conn_info *conn = client; -+ struct event_info *event; -+ DL_NODE *node; -+ -+ DbgLog(DL0, "%s: process: %p socket: %d state: %d", __func__, conn, -+ conn->client_info.socket, conn->state); -+ -+ if (conn->state == PROC_HANGUP) -+ return; -+ conn->state = PROC_HANGUP; -+ -+ /* Unlink all pending events */ -+ while ((node = dlist_get_first(conn->events)) != NULL) { -+ event = node->data; -+ /* We did not handle this event */ -+ event->reply.nothandled_replies++; -+ proc_event_delivered(conn, event); -+ } -+ -+ client_socket_term(&conn->client_info); -+ proc_put(conn); -+} -+ -+static void proc_free(void *client) -+{ -+ struct proc_conn_info *conn = client; -+ DL_NODE *node; -+ -+ /* Remove it from the process connections list */ -+ node = dlist_find(proc_connections, conn); -+ if (node != NULL) { -+ proc_connections = dlist_remove_node(proc_connections, node); -+ listener_client_hangup(&proc_listener); -+ } -+ -+ DbgLog(DL0, "%s: process: %p", __func__, conn); -+ free(conn); -+} -+ -+static int admin_new_conn(int socket, struct listener_info *listener) -+{ -+ struct admin_conn_info *conn; -+ DL_NODE *list; -+ int rc = 0; -+ -+ UNUSED(listener); -+ -+ DbgLog(DL0, "%s: Accepted connection from admin: socket: %d", __func__, -+ socket); -+ -+ conn = calloc(1, sizeof(struct admin_conn_info)); -+ if (conn == NULL) { -+ ErrLog("%s: Failed to to allocate memory for the admin connection", -+ __func__); -+ return -ENOMEM; -+ /* Caller will close socket */ -+ } -+ -+ DbgLog(DL3, "%s: admin conn: %p", __func__, conn); -+ -+ conn->state = ADMIN_RECEIVE_EVENT; -+ -+ rc = client_socket_init(socket, admin_xfer_complete, admin_hangup, -+ admin_free, conn, &conn->client_info); -+ if (rc != 0) -+ goto out; -+ -+ conn->event = event_new(0, conn); -+ if (conn->event == NULL) { -+ ErrLog("%s: Failed to allocate a new event", __func__); -+ rc = -ENOMEM; -+ goto out; -+ } -+ -+ /* Add it to the admin connections list */ -+ list = dlist_add_as_first(admin_connections, conn); -+ if (list == NULL) { -+ ErrLog("%s: Failed to add connection to list of admin connections", -+ __func__); -+ rc = -ENOMEM; -+ goto out; -+ } -+ admin_connections = list; -+ -+ admin_get(conn); -+ rc = client_socket_receive(&conn->client_info, &conn->event->event, -+ sizeof(conn->event->event)); -+ admin_put(conn); -+ conn = NULL; /* conn may have been freed by now */ -+ -+out: -+ if (rc != 0 && conn != NULL) { -+ admin_hangup(conn); -+ rc = 0; /* Don't return an error, we have already handled it */ -+ } -+ -+ return rc; -+} -+ -+static int admin_xfer_complete(void *client) -+{ -+ struct admin_conn_info *conn = client; -+ int rc; -+ -+ DbgLog(DL0, "%s: Xfer completed: admin: %p socket: %d state: %d", -+ __func__, conn, conn->client_info.socket, conn->state); -+ -+ /* -+ * A non-zero return code returned by this function causes the caller to -+ * call admin_hangup(). Thus, no need to call admin_hangup() ourselves. -+ */ -+ -+ if (conn->event == NULL) { -+ TraceLog("%s: No current event", __func__); -+ return -EINVAL; -+ } -+ -+ switch (conn->state) { -+ case ADMIN_RECEIVE_EVENT: -+ /* We have received the event from the admin */ -+ DbgLog(DL3, "%s: Event version: %u", __func__, -+ conn->event->event.version); -+ DbgLog(DL3, "%s: Event type: 0x%08x", __func__, -+ conn->event->event.type); -+ DbgLog(DL3, "%s: Event flags: 0x%08x", __func__, -+ conn->event->event.flags); -+ DbgLog(DL3, "%s: Event token_type: 0x%08x", __func__, -+ conn->event->event.token_type); -+ DbgLog(DL3, "%s: Event token_name: '%.32s'", __func__, -+ conn->event->event.token_label); -+ DbgLog(DL3, "%s: Event process_id: %u", __func__, -+ conn->event->event.process_id); -+ DbgLog(DL3, "%s: Event payload_len: %u", __func__, -+ conn->event->event.payload_len); -+ -+ if (conn->event->event.version != EVENT_VERSION_1) { -+ InfoLog("%s: Admin event has invalid version: %d", __func__, -+ conn->event->event.version); -+ return -EINVAL; -+ } -+ if (conn->event->event.payload_len > EVENT_MAX_PAYLOAD_LENGTH) { -+ InfoLog("%s: Admin event payload is too large: %u", __func__, -+ conn->event->event.payload_len); -+ return -EMSGSIZE; -+ } -+ -+ if (conn->event->event.payload_len > 0) { -+ conn->event->payload = malloc(conn->event->event.payload_len); -+ if (conn->event->payload == NULL) { -+ ErrLog("%s: Failed to allocate the payload buffer", __func__); -+ return -ENOMEM; -+ } -+ -+ conn->state = ADMIN_RECEIVE_PAYLOAD; -+ rc = client_socket_receive(&conn->client_info, conn->event->payload, -+ conn->event->event.payload_len); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ } -+ FALL_THROUGH; -+ /* fall through */ -+ -+ case ADMIN_RECEIVE_PAYLOAD: -+ /* We have received the payload (if any) from the admin */ -+ conn->state = ADMIN_EVENT_DELIVERED; -+ rc = event_start_deliver(conn->event); -+ if (rc != 0) { -+ if (rc == -ENOSPC) { -+ /* Event limit reached, delay */ -+ conn->state = ADMIN_WAIT_FOR_EVENT_LIMIT; -+ return 0; -+ } -+ return rc; -+ } -+ break; -+ -+ case ADMIN_WAIT_FOR_EVENT_LIMIT: -+ /* This state is handled in admin_event_limit_underrun() */ -+ break; -+ -+ case ADMIN_EVENT_DELIVERED: -+ /* This state is handled in admin_event_delivered() */ -+ break; -+ -+ case ADMIN_SEND_REPLY: -+ /* The reply has been sent to the admin */ -+ if (conn->event->admin_ref != NULL) -+ admin_put(conn->event->admin_ref); -+ conn->event->admin_ref = NULL; -+ event_free(conn->event); -+ -+ conn->event = event_new(0, conn); -+ if (conn->event == NULL) { -+ ErrLog("%s: Failed to allocate a new event", __func__); -+ return -ENOMEM; -+ } -+ -+ conn->state = ADMIN_RECEIVE_EVENT; -+ rc = client_socket_receive(&conn->client_info, &conn->event->event, -+ sizeof(conn->event->event)); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ -+ case ADMIN_HANGUP: -+ break; -+ } -+ -+ return 0; -+} -+ -+static void admin_event_limit_underrun(struct admin_conn_info *conn) -+{ -+ int rc; -+ -+ DbgLog(DL3, "%s: admin: %p state: %d", __func__, conn, conn->state); -+ -+ if (conn->state != ADMIN_WAIT_FOR_EVENT_LIMIT) -+ return; -+ -+ conn->state = ADMIN_EVENT_DELIVERED; -+ -+ rc = event_start_deliver(conn->event); -+ if (rc != 0) { -+ if (rc == -ENOSPC) { -+ /* Event limit reached, delay */ -+ conn->state = ADMIN_WAIT_FOR_EVENT_LIMIT; -+ return; -+ } -+ admin_hangup(conn); -+ } -+} -+ -+static int admin_event_delivered(struct admin_conn_info *conn, -+ struct event_info *event) -+{ -+ int rc; -+ -+ DbgLog(DL3, "%s: admin: %p event: %p", __func__, conn, event); -+ -+ /* -+ * A non-zero return code returned by this function causes the caller to -+ * call admin_hangup(). Thus, no need to call admin_hangup() ourselves. -+ */ -+ -+ if (conn->state != ADMIN_EVENT_DELIVERED) { -+ TraceLog("%s: wrong state: %d", __func__, conn->state); -+ return -EINVAL; -+ } -+ -+ if (event->event.flags & EVENT_FLAGS_REPLY_REQ) { -+ if (conn->event != event) { -+ TraceLog("%s: event not the current event", __func__); -+ return -EINVAL; -+ } -+ -+ DbgLog(DL3, "%s: Reply version: %u", __func__, -+ event->reply.version); -+ DbgLog(DL3, "%s: Reply positive: %lu", __func__, -+ event->reply.positive_replies); -+ DbgLog(DL3, "%s: Reply negative: %lu", __func__, -+ event->reply.negative_replies); -+ DbgLog(DL3, "%s: Reply not-handled: %lu", __func__, -+ event->reply.nothandled_replies); -+ -+ conn->state = ADMIN_SEND_REPLY; -+ rc = client_socket_send(&conn->client_info, &event->reply, -+ sizeof(event->reply)); -+ return rc; -+ } -+ -+ /* No reply required, free the event, and receive the next one */ -+ if (event->admin_ref != NULL) -+ admin_put(event->admin_ref); -+ event->admin_ref = NULL; -+ event_free(event); -+ -+ conn->event = event_new(0, conn); -+ if (conn->event == NULL) { -+ ErrLog("%s: Failed to allocate a new event", __func__); -+ return -ENOMEM; -+ } -+ -+ conn->state = ADMIN_RECEIVE_EVENT; -+ rc = client_socket_receive(&conn->client_info, &conn->event->event, -+ sizeof(conn->event->event)); -+ return rc; -+} -+ -+static inline void admin_get(struct admin_conn_info *conn) -+{ -+ client_socket_get(&conn->client_info); -+} -+ -+static inline void admin_put(struct admin_conn_info *conn) -+{ -+ client_socket_put(&conn->client_info); -+} -+ -+static void admin_hangup(void *client) -+{ -+ struct admin_conn_info *conn = client; -+ -+ DbgLog(DL0, "%s: admin: %p socket: %d state: %d", __func__, conn, -+ conn->client_info.socket, conn->state); -+ -+ if (conn->state == ADMIN_HANGUP) -+ return; -+ conn->state = ADMIN_HANGUP; -+ -+ /* Unlink pending event (if any) */ -+ if (conn->event != NULL) { -+ if (conn->event->admin_ref != NULL) -+ admin_put(conn->event->admin_ref); -+ conn->event->admin_ref = NULL; -+ if (conn->event->proc_ref_count == 0) { -+ event_remove_from_pending_list(conn->event); -+ event_free(conn->event); -+ } -+ conn->event = NULL; -+ } -+ -+ client_socket_term(&conn->client_info); -+ admin_put(conn); -+} -+ -+static void admin_free(void *client) -+{ -+ struct admin_conn_info *conn = client; -+ DL_NODE *node; - --int proc_listener_socket = -1; -+ /* Remove it from the admin connections list */ -+ node = dlist_find(admin_connections, conn); -+ if (node != NULL) { -+ admin_connections = dlist_remove_node(admin_connections, node); -+ listener_client_hangup(&admin_listener); -+ } - --static void close_listener_socket(int socketfd, const char *file_path); -+ DbgLog(DL0, "%s: admin: %p", __func__, conn); -+ free(conn); -+} - --// Creates the daemon's listener socket, to which clients will connect and --// retrieve slot information through. Returns the file descriptor of the --// created socket. --static int create_listener_socket(const char *file_path) -+static int listener_socket_create(const char *file_path) - { - struct sockaddr_un address; - struct group *grp; -- int socketfd; -+ int listener_socket, err; - -- socketfd = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); -- if (socketfd < 0) { -- ErrLog("Failed to create listener socket, errno 0x%X.", errno); -+ listener_socket = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); -+ if (listener_socket < 0) { -+ err = errno; -+ ErrLog("%s: Failed to create listener socket, errno %d (%s).", -+ __func__, err, strerror(err)); - return -1; - } - if (unlink(file_path) && errno != ENOENT) { -- ErrLog("Failed to unlink socket file, errno 0x%X.", errno); -+ err = errno; -+ ErrLog("%s: Failed to unlink socket file, errno %d (%s).", __func__, -+ err, strerror(err)); - goto error; - } - -@@ -52,50 +1249,389 @@ static int create_listener_socket(const char *file_path) - address.sun_family = AF_UNIX; - strcpy(address.sun_path, file_path); - -- if (bind(socketfd, -+ if (bind(listener_socket, - (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) { -- ErrLog("Failed to bind to socket, errno 0x%X.", errno); -+ err = errno; -+ ErrLog("%s: Failed to bind to socket, errno %d (%s).", __func__, err, -+ strerror(err)); - goto error; - } - // make socket file part of the pkcs11 group, and write accessable - // for that group - grp = getgrnam("pkcs11"); - if (!grp) { -- ErrLog("Group PKCS#11 does not exist"); -+ ErrLog("%s: Group PKCS#11 does not exist", __func__); - goto error; - } - if (chown(file_path, 0, grp->gr_gid)) { -- ErrLog("Could not change file group on socket, errno 0x%X.", errno); -+ err = errno; -+ ErrLog("%s: Could not change file group on socket, errno %d (%s).", -+ __func__, err, strerror(err)); - goto error; - } - if (chmod(file_path, -- S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP | S_IXUSR | S_IXGRP)) { -- ErrLog("Could not change file permissions on socket, errno 0x%X.", -- errno); -+ S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP)) { -+ err = errno; -+ ErrLog("%s: Could not change file permissions on socket, errno %d (%s).", -+ __func__, err, strerror(err)); - goto error; - } - -- if (listen(socketfd, 20) != 0) { -- ErrLog("Failed to listen to socket, errno 0x%X.", errno); -+ if (listen(listener_socket, 20) != 0) { -+ err = errno; -+ ErrLog("%s: Failed to listen to socket, errno %d (%s).", __func__, err, -+ strerror(err)); - goto error; - } - -- return socketfd; -+ return listener_socket; - - error: -- if (socketfd >= 0) -- close_listener_socket(socketfd, file_path); -+ if (listener_socket >= 0) -+ listener_socket_close(listener_socket, file_path); - - return -1; - } - - --static void close_listener_socket(int socketfd, const char *file_path) -+static void listener_socket_close(int listener_socket, const char *file_path) - { -- close(socketfd); -+ close(listener_socket); - unlink(file_path); - } - -+ -+ -+static int listener_notify(int events, void *private) -+{ -+ struct listener_info *listener = private; -+ struct sockaddr_un address; -+ socklen_t address_length = sizeof(address); -+ int client_socket, rc, err; -+ -+ if ((events & EPOLLIN) == 0) -+ return 0; -+ -+ /* epoll is edge triggered. We must call accept until we get EWOULDBLOCK */ -+ while (listener->num_clients < listener->max_num_clients) { -+ client_socket = accept(listener->socket, (struct sockaddr *) &address, -+ &address_length); -+ if (client_socket < 0) { -+ err = errno; -+ if (err == EWOULDBLOCK) -+ break; -+ InfoLog("%s: Failed to accept connection on socket %d, errno %d (%s).", -+ __func__, listener->socket, err, strerror(err)); -+ return -err; -+ } -+ -+ rc = listener->new_conn(client_socket, listener); -+ if (rc != 0) { -+ TraceLog("%s: new_conn callback failed for client socket %d, rc: %d", -+ __func__, client_socket, rc); -+ close(client_socket); -+ continue; -+ } -+ -+ listener->num_clients++; -+ } -+ -+ return 0; -+} -+ -+static int listener_client_hangup(struct listener_info *listener) -+{ -+ int rc, trigger = 0; -+ -+ if (listener->num_clients >= listener->max_num_clients) -+ trigger = 1; /* We were at max clients, trigger accept now */ -+ -+ if (listener->num_clients > 0) -+ listener->num_clients--; -+ -+ if (trigger && listener->num_clients < listener->max_num_clients) { -+ rc = listener_notify(EPOLLIN, listener); -+ if (rc != 0) -+ return rc; -+ } -+ -+ return 0; -+} -+ -+static int listener_create(const char *file_path, -+ struct listener_info *listener, -+ int (* new_conn)(int socket, -+ struct listener_info *listener), -+ unsigned long max_num_clients) -+{ -+ struct epoll_event evt; -+ int rc, err; -+ -+ if (listener == NULL || new_conn == NULL) -+ return FALSE; -+ -+ memset(listener, 0, sizeof(*listener)); -+ epoll_info_init(&listener->ep_info, listener_notify, NULL, listener); -+ listener->file_path = file_path; -+ listener->new_conn = new_conn; -+ listener->max_num_clients = max_num_clients; -+ -+ listener->socket = listener_socket_create(file_path); -+ if (listener->socket < 0) -+ return FALSE; -+ -+ evt.events = EPOLLIN | EPOLLET; -+ evt.data.ptr = &listener->ep_info; -+ rc = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listener->socket, &evt); -+ if (rc != 0) { -+ err = errno; -+ TraceLog("%s: Failed add listener socket %d to epoll, errno %d (%s).", -+ __func__, listener->socket, err, strerror(err)); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+static void listener_term(struct listener_info *listener) -+{ -+ if (listener == NULL || listener->socket < 0) -+ return; -+ -+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, listener->socket, NULL); -+ listener_socket_close(listener->socket, listener->file_path); -+} -+ -+#ifdef WITH_LIBUDEV -+ -+static int udev_mon_init(const char *subsystem, struct udev_mon *udev_mon) -+{ -+ struct epoll_event evt; -+ int rc, err; -+ -+ if (subsystem == NULL || udev_mon == NULL) -+ return FALSE; -+ -+ udev_mon->delayed_event = 0; -+ -+ udev_mon->udev = udev_new(); -+ if (udev_mon->udev == NULL) { -+ ErrLog("%s: udev_new failed", __func__); -+ goto error; -+ } -+ -+ udev_mon->mon = udev_monitor_new_from_netlink(udev_mon->udev, "udev"); -+ if (udev_mon->mon == NULL) { -+ ErrLog("%s: udev_monitor_new_from_netlink failed", __func__); -+ goto error; -+ } -+ -+ /* -+ * Try to increase the receive buffer size. This may fail if the required -+ * privileges are not given. Ignore if it fails. -+ */ -+ udev_monitor_set_receive_buffer_size(udev_mon->mon, UDEV_RECV_BUFFFER_SIZE); -+ -+ rc = udev_monitor_filter_add_match_subsystem_devtype(udev_mon->mon, -+ subsystem, NULL); -+ if (rc != 0) { -+ ErrLog("%s: udev_monitor_filter_add_match_subsystem_devtype failed: " -+ "rc=%d", __func__, rc); -+ goto error; -+ } -+ -+ rc = udev_monitor_enable_receiving(udev_mon->mon); -+ if (rc != 0) { -+ ErrLog("%s: udev_monitor_enable_receiving failed: rc=%d", __func__, rc); -+ goto error; -+ } -+ -+ udev_mon->socket = udev_monitor_get_fd(udev_mon->mon); -+ if (udev_mon->socket < 0) { -+ ErrLog("%s: udev_monitor_get_fd failed", __func__); -+ goto error; -+ } -+ -+ epoll_info_init(&udev_mon->ep_info, udev_mon_notify, NULL, udev_mon); -+ -+ evt.events = EPOLLIN | EPOLLET; -+ evt.data.ptr = &udev_mon->ep_info; -+ rc = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, udev_mon->socket, &evt); -+ if (rc != 0) { -+ err = errno; -+ ErrLog("%s: Failed add udev_mon socket %d to epoll, errno %d (%s).", -+ __func__, udev_mon->socket, err, strerror(err)); -+ goto error; -+ } -+ -+ /* Epoll is edge triggered, thus try to receive once */ -+ rc = udev_mon_notify(EPOLLIN, udev_mon); -+ if (rc != 0) -+ goto error; -+ -+ return TRUE; -+ -+error: -+ udev_mon_term(udev_mon); -+ return FALSE; -+} -+ -+ -+static int udev_mon_handle_device(struct udev_mon *udev_mon, -+ struct udev_device *dev) -+{ -+ const char *action, *devname, *devpath, *devtype, *dev_type_prop; -+ unsigned int card, domain, dev_type; -+ struct event_info *event; -+ event_udev_apqn_data_t *apqn_data; -+ int rc; -+ -+ UNUSED(udev_mon); -+ -+ action = udev_device_get_action(dev); -+ devname = udev_device_get_sysname(dev); -+ devpath = udev_device_get_devpath(dev); -+ devtype = udev_device_get_devtype(dev); -+ dev_type_prop = udev_device_get_property_value(dev, UDEV_PROERTY_DEVTYPE); -+ -+ if (action == NULL || devname == NULL || devpath == NULL || -+ devtype == NULL || dev_type_prop == NULL) -+ return 0; -+ -+ DbgLog(DL3, "%s: Uevent: ACTION=%s DEVNAME=%s DEVPATH=%s DEVTYPE=%s " -+ "DEV_TYPE=%s", __func__, action, devname, devpath, devtype, -+ dev_type_prop); -+ -+ /* We are only interested in bind and unbind events ... */ -+ if (strcmp(action, UDEV_ACTION_BIND) != 0 && -+ strcmp(action, UDEV_ACTION_UNBIND) != 0) -+ return 0; -+ -+ /* ... for an APQN device */ -+ if (strcmp(devtype, UDEV_ACTION_DEVTYPE_APQN) != 0) -+ return 0; -+ -+ if (sscanf(devname, "%x.%x", &card, &domain) != 2) { -+ TraceLog("%s: failed to parse APQN from DEVNAME: %s", __func__, devname); -+ return -EIO; -+ } -+ if (sscanf(dev_type_prop, "%x", &dev_type) != 1) { -+ TraceLog("%s: failed to parse DEV_TYPE: %s", __func__, dev_type_prop); -+ return -EIO; -+ } -+ -+ event = event_new(sizeof(event_udev_apqn_data_t), NULL); -+ if (event == NULL) { -+ ErrLog("%s: failed to allocate an event", __func__); -+ return -ENOMEM; -+ } -+ -+ if (strcmp(udev_device_get_action(dev), UDEV_ACTION_BIND) == 0) -+ event->event.type = EVENT_TYPE_APQN_ADD; -+ else -+ event->event.type = EVENT_TYPE_APQN_REMOVE; -+ event->event.flags = EVENT_FLAGS_NONE; -+ event->event.token_type = EVENT_TOK_TYPE_ALL; -+ memset(event->event.token_label, ' ', -+ sizeof(event->event.token_label)); -+ -+ apqn_data = (event_udev_apqn_data_t *)event->payload; -+ apqn_data->card = card; -+ apqn_data->domain = domain; -+ apqn_data->device_type = dev_type; -+ -+ DbgLog(DL3, "%s: Event version: %u", __func__, event->event.version); -+ DbgLog(DL3, "%s: Event type: 0x%08x", __func__, event->event.type); -+ DbgLog(DL3, "%s: Event flags: 0x%08x", __func__, event->event.flags); -+ DbgLog(DL3, "%s: Event token_type: 0x%08x", __func__, -+ event->event.token_type); -+ DbgLog(DL3, "%s: Event token_name: '%.32s'", __func__, -+ event->event.token_label); -+ DbgLog(DL3, "%s: Event process_id: %u", __func__, event->event.process_id); -+ DbgLog(DL3, "%s: Event payload_len: %u", __func__, -+ event->event.payload_len); -+ -+ DbgLog(DL3, "%s: Payload: card: %u", __func__, apqn_data->card); -+ DbgLog(DL3, "%s: Payload: domain: %u", __func__, apqn_data->domain); -+ DbgLog(DL3, "%s: Payload: dev.type: %u", __func__, apqn_data->device_type); -+ -+ rc = event_start_deliver(event); -+ if (rc != 0) { -+ if (rc == -ENOSPC) { -+ /* Event limit reached, delay event delivery */ -+ udev_mon->delayed_event = event; -+ return -ENOSPC; -+ } -+ event_free(event); -+ return rc; -+ } -+ -+ return 0; -+} -+ -+static int udev_mon_notify(int events, void *private) -+{ -+ struct udev_mon *udev_mon = private; -+ struct udev_device *dev; -+ struct event_info *event; -+ int rc; -+ -+ DbgLog(DL3, "%s: Epoll event on udev_mon socket %d: events: 0x%x", -+ __func__, udev_mon->socket, events); -+ -+ if (udev_mon->delayed_event != NULL) { -+ /* Deliver delayed event first */ -+ event = udev_mon->delayed_event; -+ udev_mon->delayed_event = NULL; -+ -+ rc = event_start_deliver(event); -+ if (rc != 0) { -+ if (rc == -ENOSPC) { -+ /* Event limit reached, delay event delivery */ -+ udev_mon->delayed_event = event; -+ return 0; -+ } -+ event_free(event); -+ return rc; -+ } -+ } -+ -+ while (1) { -+ dev = udev_monitor_receive_device(udev_mon->mon); -+ if (dev == NULL) -+ break; /* this is just like EWOULDBLOCK */ -+ -+ rc = udev_mon_handle_device(udev_mon, dev); -+ if (rc != 0) -+ TraceLog("%s: udev_mon_handle_device failed, rc: %d", __func__, rc); -+ -+ udev_device_unref(dev); -+ -+ /* If event limit reached, stop receiving more events */ -+ if (rc == -ENOSPC) -+ break; -+ }; -+ -+ return 0; -+} -+ -+static void udev_mon_term(struct udev_mon *udev_mon) -+{ -+ if (udev_mon == NULL) -+ return; -+ -+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, udev_mon->socket, NULL); -+ if (udev_mon->udev != NULL) -+ udev_unref(udev_mon->udev); -+ if (udev_mon->mon != NULL) -+ udev_monitor_unref(udev_mon->mon); -+ -+ if (udev_mon->delayed_event != NULL) -+ event_free(udev_mon->delayed_event); -+} -+ -+#endif -+ - int init_socket_data(Slot_Mgr_Socket_t *socketData) - { - unsigned int processed = 0; -@@ -106,7 +1642,7 @@ int init_socket_data(Slot_Mgr_Socket_t *socketData) - - /* check that we read in correct amount of slots */ - if (processed != NumberSlotsInDB) { -- ErrLog("Failed to populate slot info.\n"); -+ ErrLog("%s: Failed to populate slot info.", __func__); - return FALSE; - } - -@@ -115,72 +1651,277 @@ int init_socket_data(Slot_Mgr_Socket_t *socketData) - - int socket_connection_handler(int timeout_secs) - { -- int returnVal; -- fd_set set; -- struct timeval timeout; -- -- FD_ZERO(&set); -- FD_SET(proc_listener_socket, &set); -+ struct epoll_event events[MAX_EPOLL_EVENTS]; -+ int num_events, i, rc, err; -+ struct epoll_info *info; - -- timeout.tv_sec = timeout_secs; -- timeout.tv_usec = 0; -- -- returnVal = select(proc_listener_socket + 1, &set, NULL, NULL, &timeout); -- if (returnVal == -1) { -- ErrLog("select failed on socket connection, errno 0x%X.", errno); -- return FALSE; -- } else if (returnVal == 0) { -- // select call timed out, return -- return FALSE; -- } else { -- struct sockaddr_un address; -- socklen_t address_length = sizeof(address); -- -- int connectionfd = accept(proc_listener_socket, -- (struct sockaddr *) &address, -- &address_length); -- if (connectionfd < 0) { -- if (errno != EAGAIN && errno != EWOULDBLOCK) { -- /* These errors are allowed since -- * socket is non-blocking -- */ -- ErrLog("Failed to accept socket connection, errno 0x%X.", -- errno); -- } -+ do { -+ num_events = epoll_wait(epoll_fd, events, MAX_EPOLL_EVENTS, -+ timeout_secs * 1000); -+ if (num_events < 0) { -+ err = errno; -+ if (err == EINTR) -+ continue; -+ ErrLog("%s: epoll_wait failed, errno %d (%s).", __func__, err, -+ strerror(err)); - return FALSE; - } - -- DbgLog(DL0, "Accepted connection from process: socket: %d", -- connectionfd); -+ /* -+ * Inc ref count of all epoll_infos returned by epoll before handling -+ * any of them via notify. The notify callback may hangup any of -+ * the connections associated with the returned epoll_infos, and we -+ * need to avoid them getting freed before we all handled them. -+ */ -+ for (i = 0; i < num_events; i++) -+ epoll_info_get(events[i].data.ptr); - -- if (write(connectionfd, &socketData, sizeof(socketData)) != -- sizeof(socketData)) { -- ErrLog("Failed to write socket data, errno 0x%X.", errno); -- close(connectionfd); -- return FALSE; -+ for (i = 0; i < num_events; i++) { -+ info = events[i].data.ptr; -+ if (info == NULL || info->notify == NULL) -+ continue; -+ -+ rc = info->notify(events[i].events, info->private); -+ if (rc != 0) -+ TraceLog("%s: notify callback failed, rc: %d", __func__, rc); -+ -+ epoll_info_put(info); - } -- close(connectionfd); -- return TRUE; -- } -+ } while (num_events > 0 && rc == 0); /* num_events = 0: timeout */ -+ -+ return TRUE; - } - - int init_socket_server() - { -- proc_listener_socket = create_listener_socket(PROC_SOCKET_FILE_PATH); -- if (proc_listener_socket < 0) -+ int err; -+ -+ epoll_fd = epoll_create1(0); -+ if (epoll_fd < 0) { -+ err = errno; -+ ErrLog("%s: Failed to open epoll socket, errno %d (%s).", __func__, err, -+ strerror(err)); -+ return FALSE; -+ } -+ -+ if (!listener_create(PROC_SOCKET_FILE_PATH, &proc_listener, -+ proc_new_conn, NUMBER_PROCESSES_ALLOWED)) { -+ term_socket_server(); -+ return FALSE; -+ } -+ -+ if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener, -+ admin_new_conn, NUMBER_ADMINS_ALLOWED)) { -+ term_socket_server(); - return FALSE; -+ } -+ -+#ifdef WITH_LIBUDEV -+ if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) { -+ term_socket_server(); -+ return FALSE; -+ } -+#endif - -- DbgLog(DL0, "Socket server started"); -+ DbgLog(DL0, "%s: Socket server started", __func__); - - return TRUE; - } - - int term_socket_server() - { -- if (proc_listener_socket >= 0) -- close_listener_socket(proc_listener_socket, PROC_SOCKET_FILE_PATH); -+ DL_NODE *node, *next; -+ -+#ifdef WITH_LIBUDEV -+ udev_mon_term(&udev_mon); -+#endif -+ -+ listener_term(&proc_listener); -+ listener_term(&admin_listener); -+ -+ node = dlist_get_first(proc_connections); -+ while (node != NULL) { -+ next = dlist_next(node); -+ proc_hangup(node->data); -+ node = next; -+ } -+ dlist_purge(proc_connections); - -- DbgLog(DL0, "Socket server stopped"); -+ node = dlist_get_first(admin_connections); -+ while (node != NULL) { -+ next = dlist_next(node); -+ admin_hangup(node->data); -+ node = next; -+ } -+ dlist_purge(admin_connections); -+ -+ node = dlist_get_first(pending_events); -+ while (node != NULL) { -+ next = dlist_next(node); -+ event_free((struct event_info *)node->data); -+ node = next; -+ } -+ dlist_purge(pending_events); -+ -+ if (epoll_fd >= 0) -+ close(epoll_fd); -+ epoll_fd = -1; -+ -+ DbgLog(DL0, "%s: Socket server stopped", __func__); - - return TRUE; - } -+ -+#ifdef DEV -+ -+static void dump_listener(struct listener_info *listener) -+{ -+ DbgLog(DL0, " socket: %d", listener->socket); -+ DbgLog(DL0, " file_path: %s", listener->file_path); -+ DbgLog(DL0, " ep_info.ref_count: %lu", listener->ep_info.ref_count); -+ DbgLog(DL0, " num_clients: %lu", listener->num_clients); -+ DbgLog(DL0, " max_num_clients: %lu", listener->max_num_clients); -+} -+ -+static void dump_event_msg(event_msg_t *event, int indent) -+{ -+ DbgLog(DL0, "%*sevent version: %u", indent, "", event->version); -+ DbgLog(DL0, "%*sevent type: %08x", indent, "", event->type); -+ DbgLog(DL0, "%*sevent flags: %08x", indent, "", event->flags); -+ DbgLog(DL0, "%*sevent token_type: %08x", indent, "", event->token_type); -+ DbgLog(DL0, "%*sevent token_label: '%.32s'", indent, "", event->token_label); -+ DbgLog(DL0, "%*sevent process_id: %lu", indent, "", event->process_id); -+ DbgLog(DL0, "%*sevent payload_len: %u", indent, "", event->payload_len); -+} -+ -+static void dump_event_reply(event_reply_t *reply, int indent) -+{ -+ DbgLog(DL0, "%*sreply version: %u", indent, "", reply->version); -+ DbgLog(DL0, "%*sreply positive_replies: %u", indent, "", reply->positive_replies); -+ DbgLog(DL0, "%*sreply negative_replies: %u", indent, "", reply->negative_replies); -+ DbgLog(DL0, "%*sreply nothandled_replies: %u", indent, "", reply->nothandled_replies); -+} -+ -+static void dump_event_info(struct event_info *event, int indent) -+{ -+ dump_event_msg(&event->event, indent); -+ dump_event_reply(&event->reply, indent); -+ DbgLog(DL0, "%*sproc_ref_count: %lu", indent, "", event->proc_ref_count); -+ if (event->admin_ref != NULL) -+ DbgLog(DL0, "%*sadmin_ref: %p", indent, "", event->admin_ref); -+ else -+ DbgLog(DL0, "%*sadmin_ref: None", indent, ""); -+} -+ -+static void dump_proc_conn(struct proc_conn_info *proc_conn) -+{ -+ DL_NODE *node; -+ unsigned long i; -+ -+ DbgLog(DL0, " socket: %d", proc_conn->client_info.socket); -+ DbgLog(DL0, " state: %d", proc_conn->state); -+ DbgLog(DL0, " ref-count: %lu", proc_conn->client_info.ep_info.ref_count); -+ DbgLog(DL0, " xfer state: %d", proc_conn->client_info.xfer_state); -+ DbgLog(DL0, " xfer size: %d", proc_conn->client_info.xfer_size); -+ DbgLog(DL0, " xfer offset: %d", proc_conn->client_info.xfer_offset); -+ DbgLog(DL0, " pending events:"); -+ node = dlist_get_first(proc_conn->events); -+ i = 1; -+ while (node != NULL) { -+ DbgLog(DL0, " event %lu (%p):", i, node->data); -+ dump_event_info(node->data, 10); -+ node = dlist_next(node); -+ i++; -+ } -+ if (proc_conn->event != NULL) { -+ DbgLog(DL0, " current event:"); -+ dump_event_info(proc_conn->event, 8); -+ DbgLog(DL0, " current reply:"); -+ dump_event_reply(&proc_conn->reply, 8); -+ } else { -+ DbgLog(DL0, " current event: none"); -+ } -+} -+ -+static void dump_admin_conn(struct admin_conn_info *admin_conn) -+{ -+ DbgLog(DL0, " socket: %d", admin_conn->client_info.socket); -+ DbgLog(DL0, " state: %d", admin_conn->state); -+ DbgLog(DL0, " ref-count: %lu", admin_conn->client_info.ep_info.ref_count); -+ DbgLog(DL0, " xfer state: %d", admin_conn->client_info.xfer_state); -+ DbgLog(DL0, " xfer size: %d", admin_conn->client_info.xfer_size); -+ DbgLog(DL0, " xfer offset: %d", admin_conn->client_info.xfer_offset); -+ if (admin_conn->event != NULL) { -+ DbgLog(DL0, " current event (%p):", admin_conn->event); -+ dump_event_info(admin_conn->event, 8); -+ } else { -+ DbgLog(DL0, " current event: none"); -+ } -+} -+ -+#ifdef WITH_LIBUDEV -+void dump_udev_mon(struct udev_mon *udev_mon) -+{ -+ DbgLog(DL0, " socket: %d", udev_mon->socket); -+ DbgLog(DL0, " udev: %p", udev_mon->udev); -+ DbgLog(DL0, " mon: %p", udev_mon->mon); -+ DbgLog(DL0, " ep_info.ref_count: %lu", udev_mon->ep_info.ref_count); -+ if (udev_mon->delayed_event != NULL) { -+ DbgLog(DL0, " delayed_event (%p):", udev_mon->delayed_event); -+ dump_event_info(udev_mon->delayed_event, 6); -+ } else { -+ DbgLog(DL0, " delayed_event: node"); -+ } -+} -+#endif -+ -+void dump_socket_handler() -+{ -+ DL_NODE *node; -+ unsigned long i; -+ -+ DbgLog(DL0, "%s: Dump of socket handler data:", __func__); -+ DbgLog(DL0, " epoll_fd: %d", epoll_fd); -+ -+ DbgLog(DL0, " proc_listener (%p): ", &proc_listener); -+ dump_listener(&proc_listener); -+ -+ DbgLog(DL0, " proc_connections: "); -+ node = dlist_get_first(proc_connections); -+ i = 1; -+ while (node != NULL) { -+ DbgLog(DL0, " proc_connection %lu (%p): ", i, node->data); -+ dump_proc_conn(node->data); -+ i++; -+ node = dlist_next(node); -+ } -+ -+ DbgLog(DL0, " admin_listener (%p): ", &admin_listener); -+ dump_listener(&admin_listener); -+ -+ DbgLog(DL0, " admin_connections: "); -+ node = dlist_get_first(admin_connections); -+ i = 1; -+ while (node != NULL) { -+ DbgLog(DL0, " admin_connection %lu (%p): ", i, node->data); -+ dump_admin_conn(node->data); -+ i++; -+ node = dlist_next(node); -+ } -+ -+#ifdef WITH_LIBUDEV -+ DbgLog(DL0, " udev_mon (%p): ", &udev_mon); -+ dump_udev_mon(&udev_mon); -+#endif -+ -+ DbgLog(DL0, " pending events (%lu): ", pending_events_count); -+ node = dlist_get_first(pending_events); -+ i = 1; -+ while (node != NULL) { -+ DbgLog(DL0, " event %lu (%p): ", i, node->data); -+ dump_event_info(node->data, 6); -+ i++; -+ node = dlist_next(node); -+ } -+} -+#endif diff --git a/opencryptoki-3.16.0-4e3b43c3d8844402c04a66b55c6c940f965109f0.patch b/opencryptoki-3.16.0-4e3b43c3d8844402c04a66b55c6c940f965109f0.patch deleted file mode 100644 index 8a3d581..0000000 --- a/opencryptoki-3.16.0-4e3b43c3d8844402c04a66b55c6c940f965109f0.patch +++ /dev/null @@ -1,47 +0,0 @@ -commit 4e3b43c3d8844402c04a66b55c6c940f965109f0 -Author: Ingo Franzki -Date: Mon May 3 10:05:07 2021 +0200 - - SOFT: Check the EC Key on C_CreateObject and C_DeriveKey - - When constructing an OpenSSL EC public or private key from PKCS#11 - attributes or ECDH public data, check that the key is valid, i.e. that - the point is on the curve. - - This prevents one from creating an EC key object via C_CreateObject with - invalid key data. It also prevents C_DeriveKey to derive a secret using - ECDH with an EC public key (public data) that uses a different curve - or is invalid by other means. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/soft_stdll/soft_specific.c b/usr/lib/soft_stdll/soft_specific.c -index c30be1da..aeff39a9 100644 ---- a/usr/lib/soft_stdll/soft_specific.c -+++ b/usr/lib/soft_stdll/soft_specific.c -@@ -4365,6 +4365,12 @@ static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data, - goto out; - } - -+ if (!EC_KEY_check_key(ec_key)) { -+ TRACE_ERROR("EC_KEY_check_key failed\n"); -+ rc = CKR_PUBLIC_KEY_INVALID; -+ goto out; -+ } -+ - out: - if (allocated && ecpoint != NULL) - free(ecpoint); -@@ -4404,6 +4410,12 @@ static CK_RV fill_ec_key_from_privkey(EC_KEY *ec_key, const CK_BYTE *data, - goto out; - } - -+ if (!EC_KEY_check_key(ec_key)) { -+ TRACE_ERROR("EC_KEY_check_key failed\n"); -+ rc = CKR_FUNCTION_FAILED; -+ goto out; -+ } -+ - out: - if (point != NULL) - EC_POINT_free(point); diff --git a/opencryptoki-3.16.0-5824364d995e5d2418f885ee57e377e11d1b3302.patch b/opencryptoki-3.16.0-5824364d995e5d2418f885ee57e377e11d1b3302.patch deleted file mode 100644 index c38fef0..0000000 --- a/opencryptoki-3.16.0-5824364d995e5d2418f885ee57e377e11d1b3302.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit 5824364d995e5d2418f885ee57e377e11d1b3302 -Author: Ingo Franzki -Date: Wed Jul 7 13:44:46 2021 +0200 - - pkcstok_migrate: Quote strings with spaces in opencryptoki.conf - - When modifying opencryptoki.conf during token migration, put quotes - around strings that contain spaces, e.g. for the slot description and - manufacturer. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -index 94fd1196..3df1596e 100644 ---- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -@@ -2107,7 +2107,10 @@ static int parseupdate_key_str(void *private, int tok, const char *val) - { - struct parseupdate *u = (struct parseupdate *)private; - -- if (tok != KW_TOKVERSION) -+ if (tok != KW_HWVERSION && tok != KW_FWVERSION && -+ strchr(val, ' ') != NULL) -+ fprintf(u->f, " %s = \"%s\"", keyword_token_to_str(tok), val); -+ else if (tok != KW_TOKVERSION) - fprintf(u->f, " %s = %s", keyword_token_to_str(tok), val); - return 0; - } diff --git a/opencryptoki-3.16.0-69244a5e0d9dfec3ef534b19b89a541576bb17dc.patch b/opencryptoki-3.16.0-69244a5e0d9dfec3ef534b19b89a541576bb17dc.patch deleted file mode 100644 index 0494a35..0000000 --- a/opencryptoki-3.16.0-69244a5e0d9dfec3ef534b19b89a541576bb17dc.patch +++ /dev/null @@ -1,23 +0,0 @@ -commit 69244a5e0d9dfec3ef534b19b89a541576bb17dc -Author: Ingo Franzki -Date: Tue Feb 9 10:47:57 2021 +0100 - - TRACE: Use gettid() if SYS_gettid is not defined - - Also print the thread ID in the trace, if SYS_gettid is not defined. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/common/trace.c b/usr/lib/common/trace.c -index 678c0b96..bdc5256a 100644 ---- a/usr/lib/common/trace.c -+++ b/usr/lib/common/trace.c -@@ -33,6 +33,8 @@ - - #ifdef SYS_gettid - #define __gettid() syscall(SYS_gettid) -+#else -+#define __gettid() gettid() - #endif - - pthread_mutex_t tlmtx = PTHREAD_MUTEX_INITIALIZER; diff --git a/opencryptoki-3.16.0-7b7d83c571ceb3050969359817d4145600f14ae8.patch b/opencryptoki-3.16.0-7b7d83c571ceb3050969359817d4145600f14ae8.patch deleted file mode 100644 index 86ba3f0..0000000 --- a/opencryptoki-3.16.0-7b7d83c571ceb3050969359817d4145600f14ae8.patch +++ /dev/null @@ -1,367 +0,0 @@ -commit 7b7d83c571ceb3050969359817d4145600f14ae8 -Author: Ingo Franzki -Date: Fri Apr 9 17:07:31 2021 +0200 - - Check CKF_LIBRARY_CANT_CREATE_OS_THREADS at C_Initialize - - Fail if flag CKF_LIBRARY_CANT_CREATE_OS_THREADS is set at C_Initialize, - and event support is enabled (this is the default). We need to use pthreads - for the event thread, so we can't work if CKF_LIBRARY_CANT_CREATE_OS_THREADS - is set. Fail with CKR_NEED_TO_CREATE_THREADS if so. - - The event support can be globally disabled using keyword 'disable-event-support' - in opencryptoki.conf. This disables pkcsslots to accept admin connections, - and it does not monitor for AP UDEV events (on s390 platform). No event - thread is started in the opencryptoki processes, thus we can accept if flag - CKF_LIBRARY_CANT_CREATE_OS_THREADS is set in that case. - - Signed-off-by: Ingo Franzki - -diff --git a/man/man5/opencryptoki.conf.5.in b/man/man5/opencryptoki.conf.5.in -index 71218f79..7dc676ab 100644 ---- a/man/man5/opencryptoki.conf.5.in -+++ b/man/man5/opencryptoki.conf.5.in -@@ -10,8 +10,16 @@ pkcs#11 slots. At startup, the pkcsslotd daemon parses this file to - determine which slots will be made available. - - .SH SYNTAX --This file is made up of slot descriptions. Each slot description --is composed of a slot number, brackets and key-value pairs. -+This file is made up of optional global definitions, and slot descriptions. -+ -+The following global definitions are valid: -+ -+.TP -+.BR disable-event-support -+If this keyword is specified the openCryptoki event support is disabled. -+ -+.P -+Each slot description is composed of a slot number, brackets and key-value pairs. - - slot number - { -diff --git a/usr/include/slotmgr.h b/usr/include/slotmgr.h -index e37368a5..451a8cf1 100644 ---- a/usr/include/slotmgr.h -+++ b/usr/include/slotmgr.h -@@ -99,6 +99,7 @@ typedef struct { - LW_SHM_TYPE *shm_addr; // token specific shm address - } Slot_Info_t; - -+#define FLAG_EVENT_SUPPORT_DISABLED 0x01 - - #ifdef PKCS64 - -@@ -200,6 +201,7 @@ typedef struct { - - typedef struct { - uint8 num_slots; -+ uint8 flags; - CK_INFO_64 ck_info; - Slot_Info_t_64 slot_info[NUMBER_SLOTS_MANAGED]; - } Slot_Mgr_Socket_t; -@@ -214,6 +216,7 @@ typedef struct { - - typedef struct { - uint8 num_slots; -+ uint8 flags; - CK_INFO ck_info; - Slot_Info_t slot_info[NUMBER_SLOTS_MANAGED]; - } Slot_Mgr_Socket_t; -diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c -index 2873a20a..6517ca6c 100644 ---- a/usr/lib/api/api_interface.c -+++ b/usr/lib/api/api_interface.c -@@ -308,7 +308,8 @@ void parent_fork_after() - return; - - /* Restart the event thread in the parent when fork is complete */ -- if (Anchor->event_thread == 0) -+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 && -+ Anchor->event_thread == 0) - start_event_thread(); - } - -@@ -2752,13 +2753,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - goto error; - } - } -- // If we EVER need to create threads from this library we must -- // check the Flags for the Can_Create_OS_Threads flag -- // Right now the library DOES NOT create threads and therefore this -- // check is irrelavant. -- if (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) { -- TRACE_DEVEL("Can't create OS threads...This is OK\n"); -- } -+ - // Since this is an initialization path, we will be verbose in the - // code rather than efficient. - // -@@ -2848,7 +2843,21 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - rc = CKR_FUNCTION_FAILED; - goto error_shm; - } -- // Initialize structure values -+ -+ if (pVoid != NULL) { -+ pArg = (CK_C_INITIALIZE_ARGS *) pVoid; -+ -+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 && -+ (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) != 0) { -+ TRACE_ERROR("Flag CKF_LIBRARY_CANT_CREATE_OS_THREADS is set and " -+ "event support is enabled\n"); -+ OCK_SYSLOG(LOG_ERR, "C_Initialize: Application specified that " -+ "library can't create OS threads. PKCS11 Module requires " -+ "to create threads when event support is enabled.\n"); -+ rc = CKR_NEED_TO_CREATE_THREADS; -+ goto error; -+ } -+ } - - //Register with pkcsslotd - if (!API_Register()) { -@@ -2867,7 +2876,8 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - } - - /* Start event receiver thread */ -- if (start_event_thread() != 0) { -+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 && -+ start_event_thread() != 0) { - TRACE_ERROR("Failed to start event thread\n"); - - // unload all the STDLL's from the application -diff --git a/usr/lib/common/configparser.h b/usr/lib/common/configparser.h -index 13ca648d..b3c32496 100644 ---- a/usr/lib/common/configparser.h -+++ b/usr/lib/common/configparser.h -@@ -35,6 +35,7 @@ typedef int (*end_slot_f)(void *private); - typedef int (*key_str_f)(void *private, int tok, const char *val); - typedef int (*key_vers_f)(void *private, int tok, unsigned int vers); - typedef void (*eolcomment_f)(void *private, const char *comment); -+typedef void (*disab_event_supp_f)(void *private); - /* - * Report an error. If the error is not reported by the parser itself - * but via one of the parse functions, \c parsermsg will be \c NULL. -@@ -52,6 +53,7 @@ typedef void (*error_f)(void *private, int line, const char *parsermsg); - */ - struct parsefuncs { - ockversion_f version; -+ disab_event_supp_f disab_event_supp; - eol_f eol; - begin_slot_f begin_slot; - end_slot_f end_slot; -diff --git a/usr/lib/common/lexer.l b/usr/lib/common/lexer.l -index b35a0b72..38cbcb70 100644 ---- a/usr/lib/common/lexer.l -+++ b/usr/lib/common/lexer.l -@@ -69,6 +69,7 @@ extern char *configparse_strdup(const char *s); - - version return OCKVERSION; - slot return SLOT; -+disable-event-support return DISABLE_EVENT_SUPPORT; - - [^\"= \t\n]+ { - yylval.str = configparse_strdup(yytext); -diff --git a/usr/lib/common/parser.y b/usr/lib/common/parser.y -index 86806fcb..40c3994d 100644 ---- a/usr/lib/common/parser.y -+++ b/usr/lib/common/parser.y -@@ -65,7 +65,7 @@ int lookup_keyword(const char *key); - int err; - } - --%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF -+%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF DISABLE_EVENT_SUPPORT - %token STRING - %token KEYWORD - %token INTEGER -@@ -81,6 +81,7 @@ config_file: - - sections: - version_def eolcomment -+ | disable_event_support_def eolcomment - | SLOT INTEGER BEGIN_DEF - { - if (parsefuncs->begin_slot && parsefuncs->begin_slot(parsedata, $2, 0)) { -@@ -125,6 +126,13 @@ version_def: - } - configparse_freestringsfrom($2); - } -+ -+disable_event_support_def: -+ DISABLE_EVENT_SUPPORT -+ { -+ if (parsefuncs->disab_event_supp) -+ parsefuncs->disab_event_supp(parsedata); -+ } - - line_def: - STRING EQUAL TOKVERSION -diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h -index d7edcb3c..1dd0bac9 100644 ---- a/usr/sbin/pkcsslotd/pkcsslotd.h -+++ b/usr/sbin/pkcsslotd/pkcsslotd.h -@@ -88,7 +88,7 @@ int XProcLock(void); - int XProcUnLock(void); - int CreateXProcLock(void); - --int init_socket_server(); -+int init_socket_server(int event_support_disabled); - int term_socket_server(); - int init_socket_data(Slot_Mgr_Socket_t *sp); - int socket_connection_handler(int timeout_secs); -diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c -index efbfe8fd..3b328a6c 100644 ---- a/usr/sbin/pkcsslotd/slotmgr.c -+++ b/usr/sbin/pkcsslotd/slotmgr.c -@@ -34,6 +34,7 @@ int shmid; - key_t tok; - Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED]; - unsigned int NumberSlotsInDB = 0; -+int event_support_disabled = 0; - - Slot_Info_t_64 *psinfo; - -@@ -467,6 +468,13 @@ static int slotmgr_key_vers(void *private, int tok, unsigned int vers) - return 1; - } - -+static void slotmgr_disab_event_supp(void *private) -+{ -+ UNUSED(private); -+ -+ event_support_disabled = 1; -+} -+ - static void slotmgr_parseerror(void *private, int line, const char *parsermsg) - { - struct parse_data *d = (struct parse_data *)private; -@@ -480,6 +488,7 @@ static struct parsefuncs slotmgr_parsefuncs = { - .end_slot = slotmgr_end_slot, - .key_str = slotmgr_key_str, - .key_vers = slotmgr_key_vers, -+ .disab_event_supp = slotmgr_disab_event_supp, - .parseerror = slotmgr_parseerror - }; - -@@ -568,7 +577,7 @@ int main(int argc, char *argv[], char *envp[]) - if (!XProcUnLock()) - return 4; - -- if (!init_socket_server()) { -+ if (!init_socket_server(event_support_disabled)) { - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -@@ -582,6 +591,8 @@ int main(int argc, char *argv[], char *envp[]) - DestroySharedMemory(); - return 6; - } -+ if (event_support_disabled) -+ socketData.flags |= FLAG_EVENT_SUPPORT_DISABLED; - - /* Create customized token directories */ - psinfo = &socketData.slot_info[0]; -diff --git a/usr/sbin/pkcsslotd/socket_server.c b/usr/sbin/pkcsslotd/socket_server.c -index 41408670..3aa40267 100644 ---- a/usr/sbin/pkcsslotd/socket_server.c -+++ b/usr/sbin/pkcsslotd/socket_server.c -@@ -139,12 +139,12 @@ struct event_info { - }; - - static int epoll_fd = -1; --static struct listener_info proc_listener; -+static struct listener_info proc_listener = { .socket = -1 }; - static DL_NODE *proc_connections = NULL; --static struct listener_info admin_listener; -+static struct listener_info admin_listener = { .socket = -1 }; - static DL_NODE *admin_connections = NULL; - #ifdef WITH_LIBUDEV --static struct udev_mon udev_mon; -+static struct udev_mon udev_mon = { .socket = -1 }; - #endif - static DL_NODE *pending_events = NULL; - static unsigned long pending_events_count = 0; -@@ -1620,6 +1620,9 @@ static void udev_mon_term(struct udev_mon *udev_mon) - if (udev_mon == NULL) - return; - -+ if (udev_mon->socket < 0) -+ return; -+ - epoll_ctl(epoll_fd, EPOLL_CTL_DEL, udev_mon->socket, NULL); - if (udev_mon->udev != NULL) - udev_unref(udev_mon->udev); -@@ -1636,6 +1639,7 @@ int init_socket_data(Slot_Mgr_Socket_t *socketData) - { - unsigned int processed = 0; - -+ socketData->flags = 0; - PopulateCKInfo(&(socketData->ck_info)); - socketData->num_slots = NumberSlotsInDB; - PopulateSlotInfo(socketData->slot_info, &processed); -@@ -1692,7 +1696,7 @@ int socket_connection_handler(int timeout_secs) - return TRUE; - } - --int init_socket_server() -+int init_socket_server(int event_support_disabled) - { - int err; - -@@ -1710,18 +1714,20 @@ int init_socket_server() - return FALSE; - } - -- if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener, -- admin_new_conn, NUMBER_ADMINS_ALLOWED)) { -- term_socket_server(); -- return FALSE; -- } -+ if (!event_support_disabled) { -+ if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener, -+ admin_new_conn, NUMBER_ADMINS_ALLOWED)) { -+ term_socket_server(); -+ return FALSE; -+ } - - #ifdef WITH_LIBUDEV -- if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) { -- term_socket_server(); -- return FALSE; -- } -+ if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) { -+ term_socket_server(); -+ return FALSE; -+ } - #endif -+ } - - DbgLog(DL0, "%s: Socket server started", __func__); - -diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -index 7c225730..94fd1196 100644 ---- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -@@ -2066,6 +2066,13 @@ static int parseupdate_ockversion(void *private, const char *version) - return 0; - } - -+static void parseupdate_disab_event_supp(void *private) -+{ -+ struct parseupdate *u = (struct parseupdate *)private; -+ -+ fprintf(u->f, "disable-event-support"); -+} -+ - static void parseupdate_eol(void *private) - { - struct parseupdate *u = (struct parseupdate *)private; -@@ -2124,6 +2131,7 @@ static void parseupdate_eolcomment(void *private, const char *comment) - - static struct parsefuncs parseupdatefuncs = { - .version = parseupdate_ockversion, -+ .disab_event_supp = parseupdate_disab_event_supp, - .eol = parseupdate_eol, - .begin_slot = parseupdate_begin_slot, - .end_slot = parseupdate_end_slot, diff --git a/opencryptoki-3.16.0-b048be548508dd1958bb7271568f388d0f6cbcf8.patch b/opencryptoki-3.16.0-b048be548508dd1958bb7271568f388d0f6cbcf8.patch deleted file mode 100644 index fd0c13c..0000000 --- a/opencryptoki-3.16.0-b048be548508dd1958bb7271568f388d0f6cbcf8.patch +++ /dev/null @@ -1,1023 +0,0 @@ -commit b048be548508dd1958bb7271568f388d0f6cbcf8 -Author: Ingo Franzki -Date: Mon Feb 8 16:50:00 2021 +0100 - - Event support: API and token level changes - - Signed-off-by: Ingo Franzki - -diff --git a/usr/include/apictl.h b/usr/include/apictl.h -index 8898cae3..81c65dad 100644 ---- a/usr/include/apictl.h -+++ b/usr/include/apictl.h -@@ -57,6 +57,8 @@ typedef struct { - API_Slot_t SltList[NUMBER_SLOTS_MANAGED]; - DLL_Load_t DLLs[NUMBER_SLOTS_MANAGED]; // worst case we have a separate DLL - // per slot -+ int socketfd; -+ pthread_t event_thread; - } API_Proc_Struct_t; - - #endif -diff --git a/usr/include/events.h b/usr/include/events.h -new file mode 100644 -index 00000000..dac6ad52 ---- /dev/null -+++ b/usr/include/events.h -@@ -0,0 +1,83 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "local_types.h" -+#include "pkcs32.h" -+ -+#ifndef _EVENTS_H -+#define _EVENTS_H -+ -+typedef struct { -+ unsigned int version; /* EVENT_VERSION_xxx */ -+ unsigned int type; /* EVENT_TYPE_xxx */ -+ unsigned int flags; /* EVENT_FLAGS_xxx */ -+ unsigned int token_type; /* Destination token type: EVENT_TOK_TYPE_xxx */ -+ char token_label[member_size(CK_TOKEN_INFO_32, label)]; -+ /* Label of destination token (or blanks) */ -+ pid_t process_id; /* Process ID of destination process (or 0) */ -+ unsigned int payload_len; /* Length of payload in bytes */ -+ /* Followed by payload_len bytes of payload (event specific) */ -+} __attribute__ ((__packed__)) event_msg_t; -+ -+typedef struct { -+ unsigned int version; /* EVENT_VERSION_xxx */ -+ unsigned int positive_replies; /* Number of tokens that replied a */ -+ unsigned int negative_replies; /* positive, or negative feedback, */ -+ unsigned int nothandled_replies; /* or that did not handle the event. */ -+ /* Note: Only tokens matching the event -+ * destination fields (pid, label, -+ * token-type) are counted. */ -+} __attribute__ ((__packed__)) event_reply_t; -+ -+/* Event and reply versions */ -+#define EVENT_VERSION_1 1 -+ -+/* Event classes (encoded into event type) */ -+#define EVENT_CLASS_MASK 0xffff0000 -+#define EVENT_CLASS_UDEV 0x00010000 -+#define EVENT_CLASS_ADMIN 0x00020000 -+ -+/* Event types */ -+#define EVENT_TYPE_APQN_ADD EVENT_CLASS_UDEV + 0x00000001 -+#define EVENT_TYPE_APQN_REMOVE EVENT_CLASS_UDEV + 0x00000002 -+ -+/* Event flags */ -+#define EVENT_FLAGS_NONE 0x00000000 -+#define EVENT_FLAGS_REPLY_REQ 0x00000001 -+ -+/* Event token destination types */ -+#define EVENT_TOK_TYPE_ALL 0x00000000 -+#define EVENT_TOK_TYPE_CCA 0x00000001 -+#define EVENT_TOK_TYPE_EP11 0x00000002 -+ -+/* Maximum event payload length 128k */ -+#define EVENT_MAX_PAYLOAD_LENGTH (128 * 1024) -+ -+/* Event payload for EVENT_TYPE_APQN_ADD and EVENT_TYPE_APQN_REMOVE */ -+typedef struct { -+ unsigned short card; -+ unsigned short domain; -+ unsigned int device_type; /* from uevent DEV_TYPE property */ -+} __attribute__ ((__packed__)) event_udev_apqn_data_t; -+ -+/* AP device types */ -+#define AP_DEVICE_TYPE_CEX3A 8 -+#define AP_DEVICE_TYPE_CEX3C 9 -+#define AP_DEVICE_TYPE_CEX4 10 -+#define AP_DEVICE_TYPE_CEX5 11 -+#define AP_DEVICE_TYPE_CEX6 12 -+#define AP_DEVICE_TYPE_CEX7 13 -+ -+#endif -diff --git a/usr/include/include.mk b/usr/include/include.mk -index a36afb25..79e593d7 100644 ---- a/usr/include/include.mk -+++ b/usr/include/include.mk -@@ -7,4 +7,5 @@ opencryptokiinclude_HEADERS = \ - - noinst_HEADERS += \ - usr/include/apictl.h usr/include/local_types.h \ -- usr/include/pkcs32.h usr/include/slotmgr.h usr/include/stdll.h -+ usr/include/pkcs32.h usr/include/slotmgr.h usr/include/stdll.h \ -+ usr/include/events.h -diff --git a/usr/include/local_types.h b/usr/include/local_types.h -index f03c6629..c7c7f5ec 100644 ---- a/usr/include/local_types.h -+++ b/usr/include/local_types.h -@@ -11,6 +11,8 @@ - #ifndef __LOCAL_TYPES - #define __LOCAL_TYPES - -+#define member_size(type, member) sizeof(((type *)0)->member) -+ - typedef unsigned char uint8; - - typedef unsigned short uint16; -diff --git a/usr/include/stdll.h b/usr/include/stdll.h -index 57f6c6e8..9a3b760c 100644 ---- a/usr/include/stdll.h -+++ b/usr/include/stdll.h -@@ -350,6 +350,11 @@ typedef CK_RV (CK_PTR ST_C_IBM_ReencryptSingle)(STDLL_TokData_t *tokdata, - CK_BYTE_PTR pReencryptedData, - CK_ULONG_PTR pulReencryptedDataLen); - -+typedef CK_RV (CK_PTR ST_C_HandleEvent)(STDLL_TokData_t *tokdata, -+ unsigned int event_type, -+ unsigned int event_flags, -+ const char *payload, -+ unsigned int payload_len); - - struct ST_FCN_LIST { - -@@ -424,6 +429,9 @@ struct ST_FCN_LIST { - ST_C_CancelFunction ST_CancelFunction; - - ST_C_IBM_ReencryptSingle ST_IBM_ReencryptSingle; -+ -+ /* The functions defined below are not part of the external API */ -+ ST_C_HandleEvent ST_HandleEvent; - }; - - typedef struct ST_FCN_LIST STDLL_FcnList_t; -diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c -index f1ee9132..b74b763f 100644 ---- a/usr/lib/api/api_interface.c -+++ b/usr/lib/api/api_interface.c -@@ -286,7 +286,31 @@ void child_fork_initializer() - if (Anchor != NULL) - C_Finalize(NULL); - in_child_fork_initializer = FALSE; -- } -+} -+ -+void parent_fork_prepare() -+{ -+ if (Anchor == NULL) -+ return; -+ -+ /* -+ * Stop the event thread in the fork parent, since having the event thread -+ * active when a fork is performed causes various problems (e.g. deadlocks -+ * in glibc). -+ */ -+ if (Anchor->event_thread > 0) -+ stop_event_thread(); -+} -+ -+void parent_fork_after() -+{ -+ if (Anchor == NULL) -+ return; -+ -+ /* Restart the event thread in the parent when fork is complete */ -+ if (Anchor->event_thread == 0) -+ start_event_thread(); -+} - - //------------------------------------------------------------------------ - // API function C_CancelFunction -@@ -1501,6 +1525,20 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved) - - shData = &(Anchor->SocketDataP); - -+ /* -+ * Stop the event thread and close the socket. -+ * If C_Finalize is called as part of the fork initializer, don't stop -+ * the thread, since a forked process does not have any threads, and don't -+ * close the socket, as this would close the connection of the parent -+ * process to the pkcsslotd as well. -+ * */ -+ if (!in_child_fork_initializer) { -+ if (Anchor->event_thread > 0) -+ stop_event_thread(); -+ if (Anchor->socketfd >= 0) -+ close(Anchor->socketfd); -+ } -+ - // unload all the STDLL's from the application - // This is in case the APP decides to do the re-initialize and - // continue on -@@ -2642,6 +2680,8 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - CK_C_INITIALIZE_ARGS *pArg; - char fcnmap = 0; - CK_RV rc = CKR_OK; -+ CK_SLOT_ID slotID; -+ API_Slot_t *sltp; - - /* - * Lock so that only one thread can run C_Initialize or C_Finalize at -@@ -2674,6 +2714,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - // This must be done prior to all goto error calls, else bt_destroy() - // will fail because it accesses uninitialized memory when t->size > 0. - memset(Anchor, 0, sizeof(API_Proc_Struct_t)); -+ Anchor->socketfd = -1; - - TRACE_DEBUG("Anchor allocated at %s\n", (char *) Anchor); - -@@ -2789,11 +2830,21 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - } - TRACE_DEBUG("Shared memory %p \n", Anchor->SharedMemP); - -- if (!init_socket_data()) { -+ /* Connect to slot daemon and retrieve slot infos */ -+ Anchor->socketfd = connect_socket(SOCKET_FILE_PATH); -+ if (Anchor->socketfd < 0) { - OCK_SYSLOG(LOG_ERR, "C_Initialize: Module failed to create a " - "socket. Verify that the slot management daemon is " - "running.\n"); -- TRACE_ERROR("Cannot attach to socket.\n"); -+ TRACE_ERROR("Failed to connect to slot daemon\n"); -+ rc = CKR_FUNCTION_FAILED; -+ goto error_shm; -+ } -+ -+ if (!init_socket_data(Anchor->socketfd)) { -+ OCK_SYSLOG(LOG_ERR, "C_Initialize: Module failed to retrieve slot " -+ "infos from slot deamon.\n"); -+ TRACE_ERROR("Failed to receive slot infos from socket.\n"); - rc = CKR_FUNCTION_FAILED; - goto error_shm; - } -@@ -2810,15 +2861,35 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - } - // - // load all the slot DLL's here -- { -- CK_SLOT_ID slotID; -- API_Slot_t *sltp; -+ for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { -+ sltp = &(Anchor->SltList[slotID]); -+ slot_loaded[slotID] = DL_Load_and_Init(sltp, slotID); -+ } - -+ /* Start event receiver thread */ -+ if (start_event_thread() != 0) { -+ TRACE_ERROR("Failed to start event thread\n"); -+ -+ // unload all the STDLL's from the application -+ // This is in case the APP decides to do the re-initialize and -+ // continue on - for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { - sltp = &(Anchor->SltList[slotID]); -- slot_loaded[slotID] = DL_Load_and_Init(sltp, slotID); -+ if (slot_loaded[slotID]) { -+ if (sltp->pSTfini) { -+ // call the terminate function.. -+ sltp->pSTfini(sltp->TokData, slotID, -+ &Anchor->SocketDataP.slot_info[slotID], -+ &trace, 0); -+ } -+ } -+ DL_UnLoad(sltp, slotID); - } - -+ API_UnRegister(); -+ -+ rc = CKR_FUNCTION_FAILED; -+ goto error_shm; - } - - pthread_mutex_unlock(&GlobMutex); -@@ -2829,6 +2900,8 @@ error_shm: - - error: - bt_destroy(&Anchor->sess_btree); -+ if (Anchor->socketfd >= 0) -+ close(Anchor->socketfd); - - free((void *) Anchor); - Anchor = NULL; -@@ -5052,7 +5125,8 @@ void api_init(void) - { - // Should only have to do the atfork stuff at load time... - if (!Initialized) { -- pthread_atfork(NULL, NULL, (void (*)()) child_fork_initializer); -+ pthread_atfork(parent_fork_prepare, parent_fork_after, -+ child_fork_initializer); - Initialized = 1; - } - } -diff --git a/usr/lib/api/apiproto.h b/usr/lib/api/apiproto.h -index 871f3778..8523fb8e 100644 ---- a/usr/lib/api/apiproto.h -+++ b/usr/lib/api/apiproto.h -@@ -50,6 +50,9 @@ void CK_Info_From_Internal(CK_INFO_PTR dest, CK_INFO_PTR_64 src); - int sessions_exist(CK_SLOT_ID); - - void CloseAllSessions(CK_SLOT_ID slot_id, CK_BBOOL in_fork_initializer); --int init_socket_data(); -+int connect_socket(const char *file_path); -+int init_socket_data(int socketfd); -+int start_event_thread(); -+int stop_event_thread(); - - #endif -diff --git a/usr/lib/api/socket_client.c b/usr/lib/api/socket_client.c -index 6bacf151..e344ddbf 100644 ---- a/usr/lib/api/socket_client.c -+++ b/usr/lib/api/socket_client.c -@@ -23,114 +23,421 @@ - #include - #include - #include -+#include -+#include - - #include "apiproto.h" - #include "slotmgr.h" - #include "apictl.h" -+#include "trace.h" - #include "ock_syslog.h" -+#include "events.h" - - extern API_Proc_Struct_t *Anchor; --// --// Will fill out the Slot_Mgr_Socket_t structure in the Anchor global data --// structure with the values passed by the pkcsslotd via a socket RPC. --int init_socket_data() -+ -+int connect_socket(const char *file_path) - { - int socketfd; - struct sockaddr_un daemon_address; - struct stat file_info; - struct group *grp; -- int n; -- unsigned int bytes_received = 0; -- Slot_Mgr_Socket_t *daemon_socket_data = NULL; -- int ret = FALSE; - -- if (stat(SOCKET_FILE_PATH, &file_info)) { -+ if (stat(file_path, &file_info)) { - OCK_SYSLOG(LOG_ERR, -- "init_socket_data: failed to find socket file, errno=%d", -+ "connect_socket: failed to find socket file, errno=%d", - errno); -- return FALSE; -+ return -1; - } - - grp = getgrnam("pkcs11"); - if (!grp) { - OCK_SYSLOG(LOG_ERR, -- "init_socket_data: pkcs11 group does not exist, errno=%d", -+ "connect_socket: pkcs11 group does not exist, errno=%d", - errno); -- return FALSE; -+ return -1; - } - - if (file_info.st_uid != 0 || file_info.st_gid != grp->gr_gid) { - OCK_SYSLOG(LOG_ERR, -- "init_socket_data: incorrect permissions on socket file"); -- return FALSE; -+ "connect_socket: incorrect permissions on socket file"); -+ return -1; - } - - if ((socketfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - OCK_SYSLOG(LOG_ERR, -- "init_socket_data: failed to create socket, errno=%d", -+ "connect_socket: failed to create socket, errno=%d", - errno); -- return FALSE; -+ return -1; - } - - memset(&daemon_address, 0, sizeof(struct sockaddr_un)); - daemon_address.sun_family = AF_UNIX; -- strcpy(daemon_address.sun_path, SOCKET_FILE_PATH); -+ strcpy(daemon_address.sun_path, file_path); - - if (connect(socketfd, (struct sockaddr *) &daemon_address, - sizeof(struct sockaddr_un)) != 0) { - OCK_SYSLOG(LOG_ERR, -- "init_socket_data: failed to connect to slotmanager daemon, " -+ "connect_socket: failed to connect to slotmanager daemon, " - "errno=%d", - errno); -- goto exit; -- } -- // allocate data buffer -- daemon_socket_data = -- (Slot_Mgr_Socket_t *) malloc(sizeof(*daemon_socket_data)); -- if (!daemon_socket_data) { -- OCK_SYSLOG(LOG_ERR, "init_socket_data: failed to \ -- allocate %lu bytes \ -- for daemon data, errno=%d", -- sizeof(*daemon_socket_data), errno); -- goto exit; -+ goto error; - } - -- while (bytes_received < sizeof(*daemon_socket_data)) { -- n = read(socketfd, ((char *) daemon_socket_data) + bytes_received, -- sizeof(*daemon_socket_data) - bytes_received); -+ return socketfd; -+ -+error: -+ close(socketfd); -+ return -1; -+} -+ -+static ssize_t read_all(int socketfd, char *buffer, size_t size) -+{ -+ size_t bytes_received = 0; -+ ssize_t n; -+ -+ while (bytes_received < size) { -+ n = read(socketfd, buffer + bytes_received, size - bytes_received); - if (n < 0) { - // read error - if (errno == EINTR) - continue; -- OCK_SYSLOG(LOG_ERR, "init_socket_data: read error \ -- on daemon socket, errno=%d", errno); -- goto exit; -- } else if (n == 0) { -- // eof but we still expect some bytes -- OCK_SYSLOG(LOG_ERR, "init_socket_data: read returned \ -- with eof but we still \ -- expect %lu bytes from daemon", -- sizeof(*daemon_socket_data) - bytes_received); -- goto exit; -- } else { -- // n > 0, we got some bytes -- bytes_received += n; -+ return -errno; - } -+ if (n == 0) -+ break; -+ -+ bytes_received += n; - } - -- ret = TRUE; -+ return bytes_received; -+} -+ -+static ssize_t send_all(int socketfd, char *buffer, size_t size) -+{ -+ size_t bytes_sent = 0; -+ ssize_t n; - -- // copy the Slot_Mgr_Socket_t struct into global -- // Anchor SocketDataPdata buffer -- memcpy(&(Anchor->SocketDataP), daemon_socket_data, -- sizeof(*daemon_socket_data)); -+ while (bytes_sent < size) { -+ n = send(socketfd, buffer + bytes_sent, size - bytes_sent, 0); -+ if (n < 0) { -+ // send error -+ if (errno == EINTR) -+ continue; -+ return -errno; -+ } -+ if (n == 0) -+ break; - --exit: -- //free the data buffer after copy -- if (daemon_socket_data) -- free(daemon_socket_data); -+ bytes_sent += n; -+ } - -- close(socketfd); -+ return bytes_sent; -+} -+ -+// -+// Will fill out the Slot_Mgr_Socket_t structure in the Anchor global data -+// structure with the values passed by the pkcsslotd via a socket RPC. -+int init_socket_data(int socketfd) -+{ -+ ssize_t n; -+ int ret = TRUE; -+ -+ n = read_all(socketfd, (char *)&Anchor->SocketDataP, -+ sizeof(Anchor->SocketDataP)); -+ if (n < 0) { -+ // read error -+ OCK_SYSLOG(LOG_ERR, "init_socket_data: read error \ -+ on daemon socket, errno=%d", -n); -+ ret = FALSE; -+ } -+ if (n != sizeof(Anchor->SocketDataP)) { -+ // eof but we still expect some bytes -+ OCK_SYSLOG(LOG_ERR, "init_socket_data: read returned \ -+ with eof but we still \ -+ expect %lu bytes from daemon", -+ sizeof(Anchor->SocketDataP) - n); -+ ret = FALSE; -+ } - - return ret; - } -+ -+static bool match_token_label_filter(event_msg_t *event, API_Slot_t *sltp) -+{ -+ if (event->token_label[0] == ' ' || event->token_label[0] == '\0') -+ return true; -+ -+ return memcmp(event->token_label, -+ sltp->TokData->nv_token_data->token_info.label, -+ sizeof(event->token_label)) == 0; -+} -+ -+struct type_model { -+ unsigned int type; -+ char model[member_size(CK_TOKEN_INFO_32, model)]; -+}; -+ -+static const struct type_model type_model_flt[] = { -+ { .type = EVENT_TOK_TYPE_CCA, .model = "CCA " }, -+ { .type = EVENT_TOK_TYPE_EP11, .model = "EP11 " }, -+}; -+ -+static bool match_token_type_filter(event_msg_t *event, API_Slot_t *sltp) -+{ -+ size_t i; -+ -+ if (event->token_type == EVENT_TOK_TYPE_ALL) -+ return true; -+ -+ for (i = 0; i < sizeof(type_model_flt) / sizeof(struct type_model); i++) { -+ if (memcmp(sltp->TokData->nv_token_data->token_info.model, -+ type_model_flt[i].model, -+ sizeof(type_model_flt[i].model)) == 0 && -+ (event->token_type & type_model_flt[i].type) != 0) -+ return true; -+ } -+ -+ return false; -+} -+ -+static int handle_event(API_Proc_Struct_t *anchor, event_msg_t *event, -+ char *payload, event_reply_t *reply) -+{ -+ CK_SLOT_ID slotID; -+ API_Slot_t *sltp; -+ CK_RV rc; -+ -+ /* If its not for our process, ignore it, don't increment reply counters */ -+ if (event->process_id != 0 && event->process_id != anchor->Pid) -+ return 0; -+ -+ for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { -+ sltp = &anchor->SltList[slotID]; -+ if (sltp->DLLoaded == FALSE || sltp->FcnList == NULL) -+ continue; -+ -+ if (!match_token_label_filter(event, sltp)) -+ continue; -+ if (!match_token_type_filter(event, sltp)) -+ continue; -+ -+ if (sltp->FcnList->ST_HandleEvent != NULL) -+ rc = sltp->FcnList->ST_HandleEvent(sltp->TokData, event->type, -+ event->flags, payload, -+ event->payload_len); -+ else -+ rc = CKR_FUNCTION_NOT_SUPPORTED; -+ -+ TRACE_DEVEL("Slot %lu ST_HandleEvent rc: 0x%lx\n", slotID, rc); -+ switch (rc) { -+ case CKR_OK: -+ reply->positive_replies++; -+ break; -+ case CKR_FUNCTION_NOT_SUPPORTED: -+ reply->nothandled_replies++; -+ break; -+ default: -+ reply->negative_replies++; -+ break; -+ } -+ } -+ -+ return 0; -+} -+ -+static void event_thread_cleanup(void *arg) -+{ -+ API_Proc_Struct_t *anchor = arg; -+ -+ UNUSED(anchor); -+ -+ TRACE_DEVEL("Event thread %lu terminating\n", pthread_self()); -+} -+ -+static void *event_thread(void *arg) -+{ -+ API_Proc_Struct_t *anchor = arg; -+ int oldstate, oldtype; -+ struct pollfd pollfd; -+ event_msg_t event; -+ char *payload; -+ event_reply_t reply; -+ ssize_t num; -+ int rc; -+ -+ UNUSED(arg); -+ -+ TRACE_DEVEL("Event thread %lu running\n", pthread_self()); -+ -+ if (anchor->socketfd < 0) { -+ TRACE_ERROR("socket is already closed.\n"); -+ TRACE_DEVEL("Event thread %lu terminating\n", pthread_self()); -+ return NULL; -+ } -+ -+ /* Enable cancellation */ -+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); -+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); -+ pthread_cleanup_push(event_thread_cleanup, anchor); -+ -+ pollfd.fd = anchor->socketfd; -+ pollfd.events = POLLIN | POLLHUP | POLLERR; -+ -+ while (1) { -+ pollfd.revents = 0; -+ rc = poll(&pollfd, 1, -1); -+ if (rc < 0) { -+ if (errno == EINTR) -+ continue; -+ TRACE_ERROR("poll failed: %d\n", errno); -+ break; -+ } -+ -+ if (rc == 0) -+ continue; -+ -+ if (pollfd.revents & (POLLHUP | POLLERR)) { -+ TRACE_ERROR("Error on socket, possibly closed by slot daemon\n"); -+ break; -+ } -+ if ((pollfd.revents & POLLIN) == 0) -+ continue; -+ -+ /* Disable for cancellation while we are working on an event */ -+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); -+ -+ TRACE_DEVEL("Receive new event ....\n"); -+ -+ num = read_all(anchor->socketfd, (char *)&event, sizeof(event)); -+ if (num != sizeof(event)) { -+ TRACE_ERROR("Error receiving the event, rc: %ld\n", num); -+ break; -+ } -+ -+ TRACE_DEBUG("Event version: %u\n", event.version); -+ TRACE_DEBUG("Event type: 0x%08x\n", event.type); -+ TRACE_DEBUG("Event flags: 0x%08x\n", event.flags); -+ TRACE_DEBUG("Event token_type: 0x%08x\n", event.token_type); -+ TRACE_DEBUG("Event token_name: '%.32s'\n", event.token_label); -+ TRACE_DEBUG("Event process_id: %u\n", event.process_id); -+ TRACE_DEBUG("Event payload_len: %u\n", event.payload_len); -+ -+ if (event.version != EVENT_VERSION_1) { -+ TRACE_ERROR("Event version invalid: %u\n", event.version); -+ break; -+ } -+ -+ payload = NULL; -+ if (event.payload_len > 0) { -+ payload = malloc(event.payload_len); -+ if (payload == NULL) { -+ TRACE_ERROR("Failed to allocate buffer for event payload\n"); -+ break; -+ } -+ -+ num = read_all(anchor->socketfd, payload, event.payload_len); -+ if (num != event.payload_len) { -+ TRACE_ERROR("Error receiving the event payload, rc: %ld\n", num); -+ if (payload != NULL) -+ free(payload); -+ break; -+ } -+ -+ TRACE_DEBUG("Event payload:\n"); -+ TRACE_DEBUG_DUMP(" ", payload, event.payload_len); -+ } -+ -+ memset(&reply, 0, sizeof(reply)); -+ reply.version = EVENT_VERSION_1; -+ rc = handle_event(anchor, &event, payload, &reply); -+ if (rc != 0) { -+ TRACE_ERROR("Error handling the event, rc: %d\n", rc); -+ if (payload != NULL) -+ free(payload); -+ break; -+ } -+ -+ TRACE_DEBUG("Reply version: %u\n", reply.version); -+ TRACE_DEBUG("Reply positive: %u\n", reply.positive_replies); -+ TRACE_DEBUG("Reply negative: %u\n", reply.negative_replies); -+ TRACE_DEBUG("Reply not-handled: %u\n", reply.nothandled_replies); -+ -+ if (event.flags & EVENT_FLAGS_REPLY_REQ) { -+ num = send_all(anchor->socketfd, (char *)&reply, sizeof(reply)); -+ if (num != sizeof(reply)) { -+ TRACE_ERROR("Error sending the event reply, rc: %ld\n", num); -+ if (payload != NULL) -+ free(payload); -+ break; -+ } -+ } -+ -+ if (payload != NULL) -+ free(payload); -+ -+ /* Re-enable for and test if we got canceled in the meantime */ -+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); -+ pthread_testcancel(); -+ } -+ -+ /* -+ * Close the socket if we encounter an unrecoverable error (e.g. received -+ * invalid event) and stop the thread because of that. -+ * If the thread is stopped via stop_event_thread(), then it gets canceled -+ * via pthread_cancel(), and will not reach this place, thus the socket is -+ * not closed. This is intended, and the socket will then be closed by -+ * C_Finalize(). The atfork 'prepare' handler in the parent process also -+ * stops the thread (via stop_event_thread()), and the socket must not be -+ * closed in this case, because the thread is restarted in the atfork -+ * 'parent' handler, and should continue to receive events from the -+ * socket. -+ */ -+ close(anchor->socketfd); -+ anchor->socketfd = -1; -+ -+ pthread_cleanup_pop(1); -+ return NULL; -+} -+ -+int start_event_thread() -+{ -+ int rc; -+ -+ rc = pthread_create(&Anchor->event_thread, NULL, event_thread, Anchor); -+ if (rc != 0) { -+ OCK_SYSLOG(LOG_ERR, "start_event_thread: pthread_create failed, " -+ "errno=%d", rc); -+ TRACE_ERROR("Failed to start event thread, errno=%d\n", rc); -+ return rc; -+ } -+ -+ TRACE_DEVEL("Event thread %lu has been started\n", Anchor->event_thread); -+ return 0; -+} -+ -+int stop_event_thread() -+{ -+ int rc; -+ void *status; -+ -+ TRACE_DEVEL("Canceling event thread %lu\n", Anchor->event_thread); -+ rc = pthread_cancel(Anchor->event_thread); -+ if (rc != 0 && rc != ESRCH) -+ return rc; -+ -+ TRACE_DEVEL("Waiting for event thread %lu to terminate\n", -+ Anchor->event_thread); -+ rc = pthread_join(Anchor->event_thread, &status); -+ if (rc != 0) -+ return rc; -+ -+ if (status != PTHREAD_CANCELED) { -+ TRACE_ERROR("Event thread was stopped, but did not return the " -+ "expected status\n"); -+ } -+ -+ TRACE_DEVEL("Event thread %lu has terminated\n", Anchor->event_thread); -+ -+ Anchor->event_thread = 0; -+ return 0; -+} -diff --git a/usr/lib/cca_stdll/tok_struct.h b/usr/lib/cca_stdll/tok_struct.h -index 2b43fa8e..182e2ac2 100644 ---- a/usr/lib/cca_stdll/tok_struct.h -+++ b/usr/lib/cca_stdll/tok_struct.h -@@ -134,6 +134,7 @@ token_spec_t token_specific = { - &token_specific_reencrypt_single, - NULL, // set_attribute_values - NULL, // set_attrs_for_new_object -+ NULL, // handle_event - }; - - #endif -diff --git a/usr/lib/common/new_host.c b/usr/lib/common/new_host.c -index aae00984..a3749d26 100644 ---- a/usr/lib/common/new_host.c -+++ b/usr/lib/common/new_host.c -@@ -4039,6 +4039,24 @@ done: - return rc; - } - -+CK_RV SC_HandleEvent(STDLL_TokData_t *tokdata, unsigned int event_type, -+ unsigned int event_flags, const char *payload, -+ unsigned int payload_len) -+{ -+ CK_RV rc; -+ -+ if (token_specific.t_handle_event == NULL) -+ return CKR_FUNCTION_NOT_SUPPORTED; -+ -+ rc = token_specific.t_handle_event(tokdata, event_type, event_flags, -+ payload, payload_len); -+ -+ TRACE_INFO("SC_HandleEvent: rc = 0x%08lx, event_type = 0x%08x, " -+ "event_flags = 0x%08x\n", rc, event_type, event_flags); -+ -+ return rc; -+} -+ - void SC_SetFunctionList(void) - { - function_list.ST_Initialize = ST_Initialize; -@@ -4104,4 +4122,6 @@ void SC_SetFunctionList(void) - function_list.ST_CancelFunction = NULL; // SC_CancelFunction; - - function_list.ST_IBM_ReencryptSingle = SC_IBM_ReencryptSingle; -+ -+ function_list.ST_HandleEvent = SC_HandleEvent; - } -diff --git a/usr/lib/common/tok_spec_struct.h b/usr/lib/common/tok_spec_struct.h -index 30ffcf02..0e90d411 100644 ---- a/usr/lib/common/tok_spec_struct.h -+++ b/usr/lib/common/tok_spec_struct.h -@@ -278,6 +278,10 @@ struct token_specific_struct { - - CK_RV(*t_set_attrs_for_new_object) (STDLL_TokData_t *, CK_OBJECT_CLASS, - CK_ULONG, TEMPLATE *); -+ -+ CK_RV(*t_handle_event) (STDLL_TokData_t *tokdata, unsigned int event_type, -+ unsigned int event_flags, const char *payload, -+ unsigned int payload_len); - }; - - typedef struct token_specific_struct token_spec_t; -diff --git a/usr/lib/common/tok_specific.h b/usr/lib/common/tok_specific.h -index ffb72909..997fa7e1 100644 ---- a/usr/lib/common/tok_specific.h -+++ b/usr/lib/common/tok_specific.h -@@ -326,4 +326,10 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *, - CK_OBJECT_CLASS, CK_ULONG, - TEMPLATE *); - -+CK_RV token_specific_handle_event(STDLL_TokData_t *tokdata, -+ unsigned int event_type, -+ unsigned int event_flags, -+ const char *payload, -+ unsigned int payload_len); -+ - #endif -diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c -index 6fcef68a..4e592363 100644 ---- a/usr/lib/ep11_stdll/new_host.c -+++ b/usr/lib/ep11_stdll/new_host.c -@@ -4262,6 +4262,24 @@ done: - return rc; - } - -+CK_RV SC_HandleEvent(STDLL_TokData_t *tokdata, unsigned int event_type, -+ unsigned int event_flags, const char *payload, -+ unsigned int payload_len) -+{ -+ CK_RV rc; -+ -+ if (token_specific.t_handle_event == NULL) -+ return CKR_FUNCTION_NOT_SUPPORTED; -+ -+ rc = token_specific.t_handle_event(tokdata, event_type, event_flags, -+ payload, payload_len); -+ -+ TRACE_INFO("SC_HandleEvent: rc = 0x%08lx, event_type = 0x%08x, " -+ "event_flags = 0x%08x\n", rc, event_type, event_flags); -+ -+ return rc; -+} -+ - void SC_SetFunctionList(void) - { - function_list.ST_Initialize = ST_Initialize; -@@ -4327,4 +4345,6 @@ void SC_SetFunctionList(void) - function_list.ST_CancelFunction = NULL; // SC_CancelFunction; - - function_list.ST_IBM_ReencryptSingle = SC_IBM_ReencryptSingle; -+ -+ function_list.ST_HandleEvent = SC_HandleEvent; - } -diff --git a/usr/lib/ep11_stdll/tok_struct.h b/usr/lib/ep11_stdll/tok_struct.h -index 51aae6fb..2c0af9cf 100644 ---- a/usr/lib/ep11_stdll/tok_struct.h -+++ b/usr/lib/ep11_stdll/tok_struct.h -@@ -137,6 +137,7 @@ token_spec_t token_specific = { - &token_specific_reencrypt_single, - &token_specific_set_attribute_values, - &token_specific_set_attrs_for_new_object, -+ NULL, // handle_event - }; - - #endif -diff --git a/usr/lib/ica_s390_stdll/tok_struct.h b/usr/lib/ica_s390_stdll/tok_struct.h -index 13ee72c9..a260a276 100644 ---- a/usr/lib/ica_s390_stdll/tok_struct.h -+++ b/usr/lib/ica_s390_stdll/tok_struct.h -@@ -147,6 +147,7 @@ token_spec_t token_specific = { - NULL, // reencrypt_single - NULL, // set_attribute_values - NULL, // set_attrs_for_new_object -+ NULL, // handle_event - }; - - #endif -diff --git a/usr/lib/icsf_stdll/new_host.c b/usr/lib/icsf_stdll/new_host.c -index 0f93ce5c..cfef7425 100644 ---- a/usr/lib/icsf_stdll/new_host.c -+++ b/usr/lib/icsf_stdll/new_host.c -@@ -3332,6 +3332,24 @@ done: - return rc; - } - -+CK_RV SC_HandleEvent(STDLL_TokData_t *tokdata, unsigned int event_type, -+ unsigned int event_flags, const char *payload, -+ unsigned int payload_len) -+{ -+ CK_RV rc; -+ -+ if (token_specific.t_handle_event == NULL) -+ return CKR_FUNCTION_NOT_SUPPORTED; -+ -+ rc = token_specific.t_handle_event(tokdata, event_type, event_flags, -+ payload, payload_len); -+ -+ TRACE_INFO("SC_HandleEvent: rc = 0x%08lx, event_type = 0x%08x, " -+ "event_flags = 0x%08x\n", rc, event_type, event_flags); -+ -+ return rc; -+} -+ - void SC_SetFunctionList(void) - { - function_list.ST_Initialize = ST_Initialize; -@@ -3397,4 +3415,6 @@ void SC_SetFunctionList(void) - function_list.ST_CancelFunction = NULL; // SC_CancelFunction; - - function_list.ST_IBM_ReencryptSingle = SC_IBM_ReencryptSingle; -+ -+ function_list.ST_HandleEvent = SC_HandleEvent; - } -diff --git a/usr/lib/icsf_stdll/tok_struct.h b/usr/lib/icsf_stdll/tok_struct.h -index fb1619ee..0f930a29 100644 ---- a/usr/lib/icsf_stdll/tok_struct.h -+++ b/usr/lib/icsf_stdll/tok_struct.h -@@ -129,6 +129,7 @@ token_spec_t token_specific = { - NULL, // reencrypt_single - NULL, // set_attribute_values - NULL, // set_attrs_for_new_object -+ NULL, // handle_event - }; - - #endif -diff --git a/usr/lib/soft_stdll/tok_struct.h b/usr/lib/soft_stdll/tok_struct.h -index acf7c5d7..e43df038 100644 ---- a/usr/lib/soft_stdll/tok_struct.h -+++ b/usr/lib/soft_stdll/tok_struct.h -@@ -172,6 +172,7 @@ token_spec_t token_specific = { - NULL, // reencrypt_single - NULL, // set_attribute_values - NULL, // set_attrs_for_new_object -+ NULL, // handle_event - }; - - #endif -diff --git a/usr/lib/tpm_stdll/tok_struct.h b/usr/lib/tpm_stdll/tok_struct.h -index d48b93e5..8903f123 100644 ---- a/usr/lib/tpm_stdll/tok_struct.h -+++ b/usr/lib/tpm_stdll/tok_struct.h -@@ -120,4 +120,5 @@ struct token_specific_struct token_specific = { - NULL, // reencrypt_single - NULL, // set_attribute_values - NULL, // set_attrs_for_new_object -+ NULL, // handle_event - }; diff --git a/opencryptoki-3.16.0-b07505993dd8b2f367cf3b630f6da186e4e8550d.patch b/opencryptoki-3.16.0-b07505993dd8b2f367cf3b630f6da186e4e8550d.patch deleted file mode 100644 index 6936783..0000000 --- a/opencryptoki-3.16.0-b07505993dd8b2f367cf3b630f6da186e4e8550d.patch +++ /dev/null @@ -1,37 +0,0 @@ -commit b07505993dd8b2f367cf3b630f6da186e4e8550d -Author: Ingo Franzki -Date: Wed Feb 10 15:12:25 2021 +0100 - - Avoid deadlock in dlclose() after a fork - - Calling dlclose() in a atfork handler may cause a deadlock. - dlclose() may itself modify the atfork handler table to remove - any fork handlers that the to be unloaded library has registered. - Since the atfork handler table is currently locked when we are in - an atfork handler, this would produce a deadlock. - - Skip the dlclose() if we are in an atfork handler to avoid the deadlock. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c -index 3ccb6d41..f1ee9132 100644 ---- a/usr/lib/api/api_interface.c -+++ b/usr/lib/api/api_interface.c -@@ -1516,7 +1516,15 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved) - } - } - -- DL_UnLoad(sltp, slotID); -+ /* -+ * Calling dlclose() in a atfork handler may cause a deadlock. -+ * dlclose() may itself modify the atfork handler table to remove -+ * any fork handlers that the to be unloaded library has registered. -+ * Since the atfork handler table is currently locked when we are in -+ * an atfork handler, this would produce a deadlock. -+ */ -+ if (!in_child_fork_initializer) -+ DL_UnLoad(sltp, slotID); - } - - // Un register from Slot D diff --git a/opencryptoki-3.16.0-bf812c652c49d7e248b115d121a4f7f6568941a2.patch b/opencryptoki-3.16.0-bf812c652c49d7e248b115d121a4f7f6568941a2.patch deleted file mode 100644 index f5a7617..0000000 --- a/opencryptoki-3.16.0-bf812c652c49d7e248b115d121a4f7f6568941a2.patch +++ /dev/null @@ -1,21 +0,0 @@ -commit bf812c652c49d7e248b115d121a4f7f6568941a2 -Author: Ingo Franzki -Date: Tue Apr 6 13:41:55 2021 +0200 - - Update travis yaml file to install libudev development files - - Signed-off-by: Ingo Franzki - -diff --git a/.travis.yml b/.travis.yml -index d2907246..fd4092e3 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -5,7 +5,7 @@ language: c - - before_install: - - sudo apt-get -qq update -- - sudo apt-get install -y expect trousers libldap2-dev libtspi-dev wget -+ - sudo apt-get install -y expect trousers libldap2-dev libtspi-dev wget libudev-dev - - sudo wget https://launchpad.net/ubuntu/+archive/primary/+files/libica3_3.4.0-0ubuntu1_s390x.deb - - sudo wget https://launchpad.net/ubuntu/+archive/primary/+files/libica-dev_3.4.0-0ubuntu1_s390x.deb - - sudo dpkg -i libica3_3.4.0-0ubuntu1_s390x.deb || true # icatok needs libica >= 3.3 diff --git a/opencryptoki-3.16.0-c79e899d77a5724635a9d4451a34a240e2c7e891.patch b/opencryptoki-3.16.0-c79e899d77a5724635a9d4451a34a240e2c7e891.patch deleted file mode 100644 index d515e15..0000000 --- a/opencryptoki-3.16.0-c79e899d77a5724635a9d4451a34a240e2c7e891.patch +++ /dev/null @@ -1,462 +0,0 @@ -commit c79e899d77a5724635a9d4451a34a240e2c7e891 -Author: Ingo Franzki -Date: Fri Apr 16 13:41:41 2021 +0200 - - Fix potential deadlock situation with double read-locks - - Do not get and read-lock an object twice within the same thread via - function object_mgr_find_in_map1(), as this would read-lock the object - twice. - - This could cause a deadlock situation, when in-between the first - and the second call to object_mgr_find_in_map1() the token object is - modified by another process. The second object_mgr_find_in_map1() would - detect that the object has been modified (object_mgr_check_shm()), and - would try to re-load the object from the disk. For re-loading, the - object is unlocked once, and a write-lock is acquired instead. - However, if the current thread has read-locked the object twice, but - releases only one read-lock, then it will never get the write lock, - because it still owns the read lock itself. - - To avoid this situation, release the read-lock before calling another - function that also acquires the read lock of the object. That way, only - one read-lock is held by the current thread, and re-loading the object - will not cause a deadlock. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/common/decr_mgr.c b/usr/lib/common/decr_mgr.c -index 317ef995..9842302b 100644 ---- a/usr/lib/common/decr_mgr.c -+++ b/usr/lib/common/decr_mgr.c -@@ -540,6 +540,10 @@ CK_RV decr_mgr_init(STDLL_TokData_t *tokdata, - } - memset(ctx->context, 0x0, sizeof(AES_GCM_CONTEXT)); - -+ /* Release obj lock, token specific aes-gcm may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = aes_gcm_init(tokdata, sess, ctx, mech, key_handle, 0); - if (rc) { - TRACE_ERROR("Could not initialize AES_GCM parms.\n"); -diff --git a/usr/lib/common/encr_mgr.c b/usr/lib/common/encr_mgr.c -index d3ecdeee..3e85ceab 100644 ---- a/usr/lib/common/encr_mgr.c -+++ b/usr/lib/common/encr_mgr.c -@@ -537,6 +537,10 @@ CK_RV encr_mgr_init(STDLL_TokData_t *tokdata, - } - memset(ctx->context, 0x0, sizeof(AES_GCM_CONTEXT)); - -+ /* Release obj lock, token specific aes-gcm may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = aes_gcm_init(tokdata, sess, ctx, mech, key_handle, 1); - if (rc != CKR_OK) { - TRACE_ERROR("Could not initialize AES_GCM parms.\n"); -diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c -index 1652f90a..e35b383c 100644 ---- a/usr/lib/common/mech_rsa.c -+++ b/usr/lib/common/mech_rsa.c -@@ -602,6 +602,10 @@ CK_RV rsa_oaep_crypt(STDLL_TokData_t *tokdata, SESSION *sess, - goto done; - } - -+ /* Release obj lock, token specific rsa-oaep may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = token_specific.t_rsa_oaep_encrypt(tokdata, ctx, in_data, - in_data_len, out_data, - out_data_len, hash, hlen); -@@ -625,6 +629,10 @@ CK_RV rsa_oaep_crypt(STDLL_TokData_t *tokdata, SESSION *sess, - goto done; - } - -+ /* Release obj lock, token specific rsa-oaep may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = token_specific.t_rsa_oaep_decrypt(tokdata, ctx, in_data, - in_data_len, out_data, - out_data_len, hash, hlen); -@@ -1331,6 +1339,10 @@ CK_RV rsa_pss_sign(STDLL_TokData_t *tokdata, SESSION *sess, - goto done; - } - -+ /* Release obj lock, token specific rsa_pss may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = token_specific.t_rsa_pss_sign(tokdata, sess, ctx, in_data, in_data_len, - out_data, out_data_len); - if (rc != CKR_OK) -@@ -1389,6 +1401,10 @@ CK_RV rsa_pss_verify(STDLL_TokData_t *tokdata, SESSION *sess, - goto done; - } - -+ /* Release obj lock, token specific rsa_pss may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = token_specific.t_rsa_pss_verify(tokdata, sess, ctx, in_data, - in_data_len, signature, sig_len); - if (rc != CKR_OK) -diff --git a/usr/lib/common/sign_mgr.c b/usr/lib/common/sign_mgr.c -index 937a371a..c7268e01 100644 ---- a/usr/lib/common/sign_mgr.c -+++ b/usr/lib/common/sign_mgr.c -@@ -424,6 +424,10 @@ CK_RV sign_mgr_init(STDLL_TokData_t *tokdata, - ctx->context_len = 0; - ctx->context = NULL; - -+ /* Release obj lock, token specific hmac-sign may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = hmac_sign_init(tokdata, sess, mech, key); - if (rc != CKR_OK) { - TRACE_ERROR("Failed to initialize hmac.\n"); -diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c -index 3ac3768a..52f95d7a 100644 ---- a/usr/lib/ep11_stdll/ep11_specific.c -+++ b/usr/lib/ep11_stdll/ep11_specific.c -@@ -6948,6 +6948,13 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session, - rc = ep11tok_pkey_check(tokdata, session, key_obj, mech); - switch (rc) { - case CKR_OK: -+ /* -+ * Release obj lock, sign_mgr_init or ep11tok_sign_verify_init_ibm_ed -+ * may re-acquire the lock -+ */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - /* Note that Edwards curves in general are not yet supported in - * opencryptoki. These two special IBM specific ED mechs are only - * supported by the ep11token, so let's keep them local here. */ -@@ -7029,11 +7036,16 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session, - * opencryptoki. These two special IBM specific ED mechs are only - * supported by the ep11token, so let's keep them local here. */ - if (ctx->mech.mechanism == CKM_IBM_ED25519_SHA512 || -- ctx->mech.mechanism == CKM_IBM_ED448_SHA3) -+ ctx->mech.mechanism == CKM_IBM_ED448_SHA3) { - rc = pkey_ibm_ed_sign(key_obj, in_data, in_data_len, signature, sig_len); -- else -+ } else { -+ /* Release obj lock, sign_mgr_sign may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = sign_mgr_sign(tokdata, session, length_only, ctx, in_data, - in_data_len, signature, sig_len); -+ } - goto done; /* no ep11 fallback possible */ - } - -@@ -7071,6 +7083,11 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session, - if (!in_data || !in_data_len) - return CKR_OK; - -+ if (ctx->pkey_active) { -+ rc = sign_mgr_sign_update(tokdata, session, ctx, in_data, in_data_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7078,11 +7095,6 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = sign_mgr_sign_update(tokdata, session, ctx, in_data, in_data_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_SignUpdate(ctx->context, ctx->context_len, in_data, - in_data_len, ep11_data->target); -@@ -7115,6 +7127,11 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -+ if (ctx->pkey_active) { -+ rc = sign_mgr_sign_final(tokdata, session, length_only, ctx, signature, sig_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7122,11 +7139,6 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = sign_mgr_sign_final(tokdata, session, length_only, ctx, signature, sig_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_SignFinal(ctx->context, ctx->context_len, signature, sig_len, - ep11_data->target); -@@ -7241,6 +7253,13 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session, - rc = ep11tok_pkey_check(tokdata, session, key_obj, mech); - switch (rc) { - case CKR_OK: -+ /* -+ * Release obj lock, verify_mgr_init or ep11tok_sign_verify_init_ibm_ed -+ * may re-acquire the lock -+ */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - /* Note that Edwards curves in general are not yet supported in - * opencryptoki. These two special IBM specific ED mechs are only - * supported by the ep11token, so let's keep them local here. */ -@@ -7320,12 +7339,17 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session, - * opencryptoki. These two special IBM specific ED mechs are only - * supported by the ep11token, so let's keep them local here. */ - if (ctx->mech.mechanism == CKM_IBM_ED25519_SHA512 || -- ctx->mech.mechanism == CKM_IBM_ED448_SHA3) -+ ctx->mech.mechanism == CKM_IBM_ED448_SHA3) { - rc = pkey_ibm_ed_verify(key_obj, in_data, in_data_len, - signature, sig_len); -- else -+ } else { -+ /* Release obj lock, verify_mgr_verify may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = verify_mgr_verify(tokdata, session, ctx, in_data, - in_data_len, signature, sig_len); -+ } - goto done; /* no ep11 fallback possible */ - } - -@@ -7363,6 +7387,11 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session, - if (!in_data || !in_data_len) - return CKR_OK; - -+ if (ctx->pkey_active) { -+ rc = verify_mgr_verify_update(tokdata, session, ctx, in_data, in_data_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7370,11 +7399,6 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = verify_mgr_verify_update(tokdata, session, ctx, in_data, in_data_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_VerifyUpdate(ctx->context, ctx->context_len, in_data, - in_data_len, ep11_data->target); -@@ -7406,6 +7430,11 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -+ if (ctx->pkey_active) { -+ rc = verify_mgr_verify_final(tokdata, session, ctx, signature, sig_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7413,11 +7442,6 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = verify_mgr_verify_final(tokdata, session, ctx, signature, sig_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_VerifyFinal(ctx->context, ctx->context_len, signature, - sig_len, ep11_data->target); -@@ -7501,6 +7525,12 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -+ if (ctx->pkey_active) { -+ rc = decr_mgr_decrypt_final(tokdata, session, length_only, -+ ctx, output_part, p_output_part_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7508,12 +7538,6 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = decr_mgr_decrypt_final(tokdata, session, length_only, -- ctx, output_part, p_output_part_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_DecryptFinal(ctx->context, ctx->context_len, - output_part, p_output_part_len, -@@ -7548,13 +7572,6 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -- READ_LOCK); -- if (rc != CKR_OK) { -- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -- return rc; -- } -- - if (ctx->pkey_active) { - rc = decr_mgr_decrypt(tokdata, session, length_only, ctx, - input_data, input_data_len, output_data, -@@ -7562,6 +7579,13 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -+ READ_LOCK); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -+ return rc; -+ } -+ - RETRY_START - rc = dll_m_Decrypt(ctx->context, ctx->context_len, input_data, - input_data_len, output_data, p_output_data_len, -@@ -7602,13 +7626,6 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - return CKR_OK; /* nothing to update, keep context */ - } - -- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -- READ_LOCK); -- if (rc != CKR_OK) { -- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -- return rc; -- } -- - if (ctx->pkey_active) { - rc = decr_mgr_decrypt_update(tokdata, session, length_only, - ctx, input_part, input_part_len, -@@ -7616,6 +7633,13 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -+ READ_LOCK); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -+ return rc; -+ } -+ - RETRY_START - rc = dll_m_DecryptUpdate(ctx->context, ctx->context_len, - input_part, input_part_len, output_part, -@@ -7695,6 +7719,12 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -+ if (ctx->pkey_active) { -+ rc = encr_mgr_encrypt_final(tokdata, session, length_only, -+ ctx, output_part, p_output_part_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7702,12 +7732,6 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = encr_mgr_encrypt_final(tokdata, session, length_only, -- ctx, output_part, p_output_part_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_EncryptFinal(ctx->context, ctx->context_len, - output_part, p_output_part_len, -@@ -7742,13 +7766,6 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -- READ_LOCK); -- if (rc != CKR_OK) { -- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -- return rc; -- } -- - if (ctx->pkey_active) { - rc = encr_mgr_encrypt(tokdata, session, length_only, ctx, - input_data, input_data_len, output_data, -@@ -7756,6 +7773,13 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -+ READ_LOCK); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -+ return rc; -+ } -+ - RETRY_START - rc = dll_m_Encrypt(ctx->context, ctx->context_len, input_data, - input_data_len, output_data, p_output_data_len, -@@ -7796,13 +7820,6 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - return CKR_OK; /* nothing to update, keep context */ - } - -- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -- READ_LOCK); -- if (rc != CKR_OK) { -- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -- return rc; -- } -- - if (ctx->pkey_active) { - rc = encr_mgr_encrypt_update(tokdata, session, length_only, ctx, - input_part, input_part_len, output_part, -@@ -7810,6 +7827,13 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -+ READ_LOCK); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -+ return rc; -+ } -+ - RETRY_START - rc = dll_m_EncryptUpdate(ctx->context, ctx->context_len, - input_part, input_part_len, output_part, -@@ -7921,6 +7945,10 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session, - rc = ep11tok_pkey_check(tokdata, session, key_obj, mech); - switch (rc) { - case CKR_OK: -+ /* Release obj lock, encr/decr_mgr_init may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - if (op == DECRYPT) { - rc = decr_mgr_init(tokdata, session, &session->decr_ctx, - OP_DECRYPT_INIT, mech, key); diff --git a/opencryptoki-3.16.0-d2f137cce5e6efb123842509352c7c49f889c67f.patch b/opencryptoki-3.16.0-d2f137cce5e6efb123842509352c7c49f889c67f.patch deleted file mode 100644 index 8f1477c..0000000 --- a/opencryptoki-3.16.0-d2f137cce5e6efb123842509352c7c49f889c67f.patch +++ /dev/null @@ -1,104 +0,0 @@ -commit d2f137cce5e6efb123842509352c7c49f889c67f -Author: Ingo Franzki -Date: Thu Jul 22 15:55:02 2021 +0200 - - pkcstok_migrate: Rework string quoting for opencryptoki.conf migration - - Due to the way the parser works, a slot description like - 'description = "slot"' works, but not without quotes ('description = slot'). - The word 'slot' is treated as a keyword if not quoted (besides other keywords, - too), so if the word 'slot' would appear in an unquoted string, the - configuration file would fail to parse. - - Always quote the value of 'description' and 'manufacturer'. Quote the - value of 'stdll', 'confname', and 'tokname' if it contains spaces, and - never quote the value of 'hwversion', 'firmwareversion', and 'tokversion'. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -index a29dc8f7..853986e8 100644 ---- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -@@ -2060,7 +2060,7 @@ done: - */ - static int parseupdate_ockversion(void *private, const char *version) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - fprintf(u->f, "version %s", version); - return 0; -@@ -2075,14 +2075,14 @@ static void parseupdate_disab_event_supp(void *private) - - static void parseupdate_eol(void *private) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - fputc('\n', u->f); - } - - static int parseupdate_begin_slot(void *private, int slot, int nl_before_begin) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - u->activeslot = (slot == u->slotnum); - if (nl_before_begin) -@@ -2094,7 +2094,7 @@ static int parseupdate_begin_slot(void *private, int slot, int nl_before_begin) - - static int parseupdate_end_slot(void *private) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - if (u->activeslot) - fprintf(u->f, " tokversion = 3.12\n"); -@@ -2105,19 +2105,32 @@ static int parseupdate_end_slot(void *private) - - static int parseupdate_key_str(void *private, int tok, const char *val) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - -- if (tok != KW_HWVERSION && tok != KW_FWVERSION && -- strchr(val, ' ') != NULL) -+ switch (tok) { -+ case KW_SLOTDESC: -+ case KW_MANUFID: - fprintf(u->f, " %s = \"%s\"", keyword_token_to_str(tok), val); -- else if (tok != KW_TOKVERSION) -+ break; -+ case KW_STDLL: -+ case KW_CONFNAME: -+ case KW_TOKNAME: -+ if (strchr(val, ' ') != NULL) -+ fprintf(u->f, " %s = \"%s\"", keyword_token_to_str(tok), val); -+ else -+ fprintf(u->f, " %s = %s", keyword_token_to_str(tok), val); -+ break; -+ case KW_HWVERSION: -+ case KW_FWVERSION: - fprintf(u->f, " %s = %s", keyword_token_to_str(tok), val); -+ break; -+ } - return 0; - } - - static int parseupdate_key_vers(void *private, int tok, unsigned int vers) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - if (tok == KW_TOKVERSION && !u->activeslot) - fprintf(u->f, " %s = %d.%d", keyword_token_to_str(tok), -@@ -2127,7 +2140,7 @@ static int parseupdate_key_vers(void *private, int tok, unsigned int vers) - - static void parseupdate_eolcomment(void *private, const char *comment) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - fprintf(u->f, "#%s", comment); - } diff --git a/opencryptoki-3.16.0-d7de5092247a0efc2c397f12977a7c9925420143.patch b/opencryptoki-3.16.0-d7de5092247a0efc2c397f12977a7c9925420143.patch deleted file mode 100644 index 40a4962..0000000 --- a/opencryptoki-3.16.0-d7de5092247a0efc2c397f12977a7c9925420143.patch +++ /dev/null @@ -1,239 +0,0 @@ -commit d7de5092247a0efc2c397f12977a7c9925420143 -Author: Ingo Franzki -Date: Tue Feb 16 17:15:20 2021 +0100 - - TESTCASES: Add event support tests - - Signed-off-by: Ingo Franzki - -diff --git a/testcases/misc_tests/events.c b/testcases/misc_tests/events.c -new file mode 100644 -index 00000000..fecc7bfe ---- /dev/null -+++ b/testcases/misc_tests/events.c -@@ -0,0 +1,190 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+ -+#include -+#include -+#include -+ -+#include "event_client.h" -+#include "regress.h" -+#include "defs.h" -+ -+const char payload[20] = "12345678901234567890"; -+ -+static inline void init_event_destination(struct event_destination *dest, -+ unsigned int token_type, -+ const char *label, -+ pid_t process_id) -+{ -+ size_t len; -+ -+ dest->token_type = token_type; -+ dest->process_id = process_id; -+ -+ memset(dest->token_label, ' ', sizeof(dest->token_label)); -+ if (label != NULL) { -+ len = strlen(label); -+ memcpy(dest->token_label, label, len > sizeof(dest->token_label) ? -+ sizeof(dest->token_label) : len); -+ } -+} -+ -+int main(int argc, char **argv) -+{ -+ CK_C_INITIALIZE_ARGS cinit_args; -+ int rc, fd = -1, ret = 1; -+ struct event_destination dest; -+ struct event_reply reply; -+ -+ UNUSED(argc); -+ UNUSED(argv); -+ -+ rc = do_GetFunctionList(); -+ if (!rc) { -+ testcase_error("do_getFunctionList(), rc=%s", p11_get_ckr(rc)); -+ return rc; -+ } -+ -+ /* -+ * Initialize Opencryptoki in this process, so that at least one -+ * process is receiving the events. -+ */ -+ memset(&cinit_args, 0x0, sizeof(cinit_args)); -+ cinit_args.flags = CKF_OS_LOCKING_OK; -+ funcs->C_Initialize(&cinit_args); -+ -+ testcase_setup(0); -+ testcase_begin("Starting event tests"); -+ -+ // Test fork before C_Initialize -+ testcase_new_assertion(); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, NULL, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (simple, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (simple, one-shot)"); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, sizeof(payload), payload, -+ NULL, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (payload, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (payload, one-shot)"); -+ -+ init_event_destination(&dest, EVENT_TOK_TYPE_CCA, NULL, 0); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, &dest, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (token-type, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (token-type, one-shot)"); -+ -+ init_event_destination(&dest, EVENT_TOK_TYPE_ALL, "cca", 0); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, &dest, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (token-label, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (token-label, one-shot)"); -+ -+ init_event_destination(&dest, EVENT_TOK_TYPE_ALL, NULL, 12345); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, &dest, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (pid, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (pid, one-shot)"); -+ -+ memset(&reply, 0, sizeof(reply)); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_REPLY_REQ, 0, NULL, NULL, &reply); -+ if (rc != 0) { -+ testcase_fail("send_event (reply, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ printf("Reply: positive_replies: %lu\n", reply.positive_replies); -+ printf(" negative_replies: %lu\n", reply.negative_replies); -+ printf(" nothandled_replies: %lu\n", reply.nothandled_replies); -+ if (reply.positive_replies + reply.negative_replies + -+ reply.nothandled_replies == 0) { -+ testcase_fail("send_event (reply, one-shot) replies all zero"); -+ goto out; -+ } -+ testcase_pass("send_event (reply, one-shot)"); -+ -+ -+ fd = init_event_client(); -+ if (fd < 0) { -+ testcase_fail("init_event_client rc = %d (%s)", fd, strerror(-fd)); -+ goto out; -+ } -+ testcase_pass("init_event_client()"); -+ -+ rc = send_event(fd, 0x12345, EVENT_FLAGS_NONE, 0, NULL, NULL, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (simple) rc = %d (%s)", rc, strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (simple)"); -+ -+ rc = send_event(fd, 0x12345, EVENT_FLAGS_NONE, sizeof(payload), payload, -+ NULL, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (payload) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (payload)"); -+ -+ memset(&reply, 0, sizeof(reply)); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_REPLY_REQ, 0, NULL, NULL, &reply); -+ if (rc != 0) { -+ testcase_fail("send_event (reply) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ printf("Reply: positive_replies: %lu\n", reply.positive_replies); -+ printf(" negative_replies: %lu\n", reply.negative_replies); -+ printf(" nothandled_replies: %lu\n", reply.nothandled_replies); -+ if (reply.positive_replies + reply.negative_replies + -+ reply.nothandled_replies == 0) { -+ testcase_fail("send_event (reply) replies all zero"); -+ goto out; -+ } -+ testcase_pass("send_event (reply)"); -+ -+ term_event_client(fd); -+ fd = -1; -+ -+ ret = 0; -+ -+out: -+ if (fd >= 0) -+ term_event_client(fd); -+ -+ funcs->C_Finalize(NULL); -+ -+ testcase_print_result(); -+ return ret; -+} -diff --git a/testcases/misc_tests/misc_tests.mk b/testcases/misc_tests/misc_tests.mk -index 3de11ebe..fb7cc0a1 100644 ---- a/testcases/misc_tests/misc_tests.mk -+++ b/testcases/misc_tests/misc_tests.mk -@@ -7,7 +7,8 @@ noinst_PROGRAMS += \ - testcases/misc_tests/fork testcases/misc_tests/multi_instance \ - testcases/misc_tests/obj_lock testcases/misc_tests/tok2tok_transport \ - testcases/misc_tests/obj_lock testcases/misc_tests/reencrypt \ -- testcases/misc_tests/cca_export_import_test -+ testcases/misc_tests/cca_export_import_test \ -+ testcases/misc_tests/events - - testcases_misc_tests_obj_mgmt_tests_CFLAGS = ${testcases_inc} - testcases_misc_tests_obj_mgmt_tests_LDADD = \ -@@ -73,3 +74,8 @@ testcases_misc_tests_cca_export_import_test_LDADD = \ - testcases/common/libcommon.la - testcases_misc_tests_cca_export_import_test_SOURCES = \ - testcases/misc_tests/cca_export_import_test.c -+ -+testcases_misc_tests_events_CFLAGS = ${testcases_inc} -+testcases_misc_tests_events_LDADD = testcases/common/libcommon.la -+testcases_misc_tests_events_SOURCES = testcases/misc_tests/events.c \ -+ usr/lib/common/event_client.c -diff --git a/testcases/ock_tests.sh.in b/testcases/ock_tests.sh.in -index 64c77a7d..6558b031 100755 ---- a/testcases/ock_tests.sh.in -+++ b/testcases/ock_tests.sh.in -@@ -53,6 +53,7 @@ OCK_TESTS+=" pkcs11/findobjects pkcs11/generate_keypair" - OCK_TESTS+=" pkcs11/get_interface pkcs11/getobjectsize pkcs11/sess_opstate" - OCK_TESTS+=" misc_tests/fork misc_tests/obj_mgmt_tests" - OCK_TESTS+=" misc_tests/obj_mgmt_lock_tests misc_tests/reencrypt" -+OCK_TESTS+=" misc_tests/events" - OCK_TEST="" - OCK_BENCHS="pkcs11/*bench" - diff --git a/opencryptoki-3.16.0-d929fe8470e99f4dcbbd889e7aa87e147d0d5b48.patch b/opencryptoki-3.16.0-d929fe8470e99f4dcbbd889e7aa87e147d0d5b48.patch deleted file mode 100644 index 5e9a346..0000000 --- a/opencryptoki-3.16.0-d929fe8470e99f4dcbbd889e7aa87e147d0d5b48.patch +++ /dev/null @@ -1,619 +0,0 @@ -commit d929fe8470e99f4dcbbd889e7aa87e147d0d5b48 -Author: Ingo Franzki -Date: Fri Feb 12 11:25:21 2021 +0100 - - Externalize linked list functions - - Externalize the linked list functions (dlist_xxx), so that they - can also be used on pkcsslotd. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/cca_stdll/cca_stdll.mk b/usr/lib/cca_stdll/cca_stdll.mk -index bd230b9f..c5e86fa7 100644 ---- a/usr/lib/cca_stdll/cca_stdll.mk -+++ b/usr/lib/cca_stdll/cca_stdll.mk -@@ -35,7 +35,8 @@ opencryptoki_stdll_libpkcs11_cca_la_SOURCES = \ - usr/lib/common/mech_ssl3.c usr/lib/common/verify_mgr.c \ - usr/lib/common/p11util.c usr/lib/common/sw_crypt.c \ - usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \ -- usr/lib/cca_stdll/cca_specific.c usr/lib/common/attributes.c -+ usr/lib/cca_stdll/cca_specific.c usr/lib/common/attributes.c \ -+ usr/lib/common/dlist.c - - if ENABLE_LOCKS - opencryptoki_stdll_libpkcs11_cca_la_SOURCES += \ -diff --git a/usr/lib/common/dlist.c b/usr/lib/common/dlist.c -new file mode 100644 -index 00000000..1fee1ea9 ---- /dev/null -+++ b/usr/lib/common/dlist.c -@@ -0,0 +1,218 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dlist.h" -+#include "host_defs.h" -+#include "h_extern.h" -+ -+ -+// Function: dlist_add_as_first() -+// -+// Adds the specified node to the start of the list -+// -+// Returns: pointer to the start of the list -+// -+DL_NODE *dlist_add_as_first(DL_NODE *list, void *data) -+{ -+ DL_NODE *node = NULL; -+ -+ if (!data) -+ return list; -+ -+ node = (DL_NODE *) malloc(sizeof(DL_NODE)); -+ if (!node) -+ return NULL; -+ -+ node->data = data; -+ node->prev = NULL; -+ node->next = list; -+ if (list) -+ list->prev = node; -+ -+ return node; -+} -+ -+// Function: dlist_add_as_last() -+// -+// Adds the specified node to the end of the list -+// -+// Returns: pointer to the start of the list -+// -+DL_NODE *dlist_add_as_last(DL_NODE *list, void *data) -+{ -+ DL_NODE *node = NULL; -+ -+ if (!data) -+ return list; -+ -+ node = (DL_NODE *) malloc(sizeof(DL_NODE)); -+ if (!node) -+ return NULL; -+ -+ node->data = data; -+ node->next = NULL; -+ -+ if (!list) { -+ node->prev = NULL; -+ return node; -+ } else { -+ DL_NODE *temp = dlist_get_last(list); -+ temp->next = node; -+ node->prev = temp; -+ -+ return list; -+ } -+} -+ -+// Function: dlist_find() -+// -+DL_NODE *dlist_find(DL_NODE *list, void *data) -+{ -+ DL_NODE *node = list; -+ -+ while (node && node->data != data) -+ node = node->next; -+ -+ return node; -+} -+ -+// Function: dlist_get_first() -+// -+// Returns the last node in the list or NULL if list is empty -+// -+DL_NODE *dlist_get_first(DL_NODE *list) -+{ -+ DL_NODE *temp = list; -+ -+ if (!list) -+ return NULL; -+ -+ while (temp->prev != NULL) -+ temp = temp->prev; -+ -+ return temp; -+} -+ -+// Function: dlist_get_last() -+// -+// Returns the last node in the list or NULL if list is empty -+// -+DL_NODE *dlist_get_last(DL_NODE *list) -+{ -+ DL_NODE *temp = list; -+ -+ if (!list) -+ return NULL; -+ -+ while (temp->next != NULL) -+ temp = temp->next; -+ -+ return temp; -+} -+ -+// -+// -+CK_ULONG dlist_length(DL_NODE *list) -+{ -+ DL_NODE *temp = list; -+ CK_ULONG len = 0; -+ -+ while (temp) { -+ len++; -+ temp = temp->next; -+ } -+ -+ return len; -+} -+ -+// -+// -+DL_NODE *dlist_next(DL_NODE *node) -+{ -+ if (!node) -+ return NULL; -+ -+ return node->next; -+} -+ -+// -+// -+DL_NODE *dlist_prev(DL_NODE *node) -+{ -+ if (!node) -+ return NULL; -+ -+ return node->prev; -+} -+ -+// -+// -+void dlist_purge(DL_NODE *list) -+{ -+ DL_NODE *node; -+ -+ if (!list) -+ return; -+ -+ do { -+ node = list->next; -+ free(list); -+ list = node; -+ } while (list); -+} -+ -+// Function: dlist_remove_node() -+// -+// Attempts to remove the specified node from the list. The caller is -+// responsible for freeing the data associated with the node prior to -+// calling this routine -+// -+DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node) -+{ -+ DL_NODE *temp = list; -+ -+ if (!list || !node) -+ return NULL; -+ -+ // special case: removing head of the list -+ // -+ if (list == node) { -+ temp = list->next; -+ if (temp) -+ temp->prev = NULL; -+ -+ free(list); -+ return temp; -+ } -+ // we have no guarantee that the node is in the list -+ // so search through the list to find it -+ // -+ while ((temp != NULL) && (temp->next != node)) -+ temp = temp->next; -+ -+ if (temp != NULL) { -+ DL_NODE *next = node->next; -+ -+ temp->next = next; -+ if (next) -+ next->prev = temp; -+ -+ free(node); -+ } -+ -+ return list; -+} -diff --git a/usr/lib/common/dlist.h b/usr/lib/common/dlist.h -new file mode 100644 -index 00000000..eda4af9c ---- /dev/null -+++ b/usr/lib/common/dlist.h -@@ -0,0 +1,32 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+ -+ -+#ifndef _DLIST_H_ -+#define _DLIST_H_ -+ -+#include "pkcs11types.h" -+#include "defs.h" -+ -+// linked-list routines -+// -+DL_NODE *dlist_add_as_first(DL_NODE *list, void *data); -+DL_NODE *dlist_add_as_last(DL_NODE *list, void *data); -+DL_NODE *dlist_find(DL_NODE *list, void *data); -+DL_NODE *dlist_get_first(DL_NODE *list); -+DL_NODE *dlist_get_last(DL_NODE *list); -+CK_ULONG dlist_length(DL_NODE *list); -+DL_NODE *dlist_next(DL_NODE *list); -+DL_NODE *dlist_prev(DL_NODE *list); -+void dlist_purge(DL_NODE *list); -+DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node); -+ -+#endif -diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h -index 63aff79f..5e251d95 100644 ---- a/usr/lib/common/h_extern.h -+++ b/usr/lib/common/h_extern.h -@@ -24,6 +24,7 @@ - #define _H_EXTERN_H - - #include -+#include "dlist.h" - - // global variables - // -@@ -1759,19 +1760,6 @@ int ec_point_from_public_data(const CK_BYTE *data, CK_ULONG data_len, - CK_BBOOL *allocated, CK_BYTE **ec_point, - CK_ULONG *ec_point_len); - --// linked-list routines --// --DL_NODE *dlist_add_as_first(DL_NODE *list, void *data); --DL_NODE *dlist_add_as_last(DL_NODE *list, void *data); --DL_NODE *dlist_find(DL_NODE *list, void *data); --DL_NODE *dlist_get_first(DL_NODE *list); --DL_NODE *dlist_get_last(DL_NODE *list); --CK_ULONG dlist_length(DL_NODE *list); --DL_NODE *dlist_next(DL_NODE *list); --DL_NODE *dlist_prev(DL_NODE *list); --void dlist_purge(DL_NODE *list); --DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node); -- - CK_RV attach_shm(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id); - CK_RV detach_shm(STDLL_TokData_t *tokdata, CK_BBOOL ignore_ref_count); - -diff --git a/usr/lib/common/utility.c b/usr/lib/common/utility.c -index 38d8d959..b2c6ee50 100644 ---- a/usr/lib/common/utility.c -+++ b/usr/lib/common/utility.c -@@ -40,203 +40,6 @@ - #include - #include - --// Function: dlist_add_as_first() --// --// Adds the specified node to the start of the list --// --// Returns: pointer to the start of the list --// --DL_NODE *dlist_add_as_first(DL_NODE *list, void *data) --{ -- DL_NODE *node = NULL; -- -- if (!data) -- return list; -- -- node = (DL_NODE *) malloc(sizeof(DL_NODE)); -- if (!node) -- return NULL; -- -- node->data = data; -- node->prev = NULL; -- node->next = list; -- if (list) -- list->prev = node; -- -- return node; --} -- --// Function: dlist_add_as_last() --// --// Adds the specified node to the end of the list --// --// Returns: pointer to the start of the list --// --DL_NODE *dlist_add_as_last(DL_NODE *list, void *data) --{ -- DL_NODE *node = NULL; -- -- if (!data) -- return list; -- -- node = (DL_NODE *) malloc(sizeof(DL_NODE)); -- if (!node) -- return NULL; -- -- node->data = data; -- node->next = NULL; -- -- if (!list) { -- node->prev = NULL; -- return node; -- } else { -- DL_NODE *temp = dlist_get_last(list); -- temp->next = node; -- node->prev = temp; -- -- return list; -- } --} -- --// Function: dlist_find() --// --DL_NODE *dlist_find(DL_NODE *list, void *data) --{ -- DL_NODE *node = list; -- -- while (node && node->data != data) -- node = node->next; -- -- return node; --} -- --// Function: dlist_get_first() --// --// Returns the last node in the list or NULL if list is empty --// --DL_NODE *dlist_get_first(DL_NODE *list) --{ -- DL_NODE *temp = list; -- -- if (!list) -- return NULL; -- -- while (temp->prev != NULL) -- temp = temp->prev; -- -- return temp; --} -- --// Function: dlist_get_last() --// --// Returns the last node in the list or NULL if list is empty --// --DL_NODE *dlist_get_last(DL_NODE *list) --{ -- DL_NODE *temp = list; -- -- if (!list) -- return NULL; -- -- while (temp->next != NULL) -- temp = temp->next; -- -- return temp; --} -- --// --// --CK_ULONG dlist_length(DL_NODE *list) --{ -- DL_NODE *temp = list; -- CK_ULONG len = 0; -- -- while (temp) { -- len++; -- temp = temp->next; -- } -- -- return len; --} -- --// --// --DL_NODE *dlist_next(DL_NODE *node) --{ -- if (!node) -- return NULL; -- -- return node->next; --} -- --// --// --DL_NODE *dlist_prev(DL_NODE *node) --{ -- if (!node) -- return NULL; -- -- return node->prev; --} -- --// --// --void dlist_purge(DL_NODE *list) --{ -- DL_NODE *node; -- -- if (!list) -- return; -- -- do { -- node = list->next; -- free(list); -- list = node; -- } while (list); --} -- --// Function: dlist_remove_node() --// --// Attempts to remove the specified node from the list. The caller is --// responsible for freeing the data associated with the node prior to --// calling this routine --// --DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node) --{ -- DL_NODE *temp = list; -- -- if (!list || !node) -- return NULL; -- -- // special case: removing head of the list -- // -- if (list == node) { -- temp = list->next; -- if (temp) -- temp->prev = NULL; -- -- free(list); -- return temp; -- } -- // we have no guarantee that the node is in the list -- // so search through the list to find it -- // -- while ((temp != NULL) && (temp->next != node)) -- temp = temp->next; -- -- if (temp != NULL) { -- DL_NODE *next = node->next; -- -- temp->next = next; -- if (next) -- next->prev = temp; -- -- free(node); -- } -- -- return list; --} -- - CK_RV CreateXProcLock(char *tokname, STDLL_TokData_t *tokdata) - { - char lockfile[PATH_MAX]; -diff --git a/usr/lib/ep11_stdll/ep11_stdll.mk b/usr/lib/ep11_stdll/ep11_stdll.mk -index bc617124..b5574d9e 100644 ---- a/usr/lib/ep11_stdll/ep11_stdll.mk -+++ b/usr/lib/ep11_stdll/ep11_stdll.mk -@@ -36,7 +36,7 @@ opencryptoki_stdll_libpkcs11_ep11_la_SOURCES = \ - usr/lib/common/utility.c usr/lib/common/trace.c \ - usr/lib/common/mech_list.c usr/lib/common/shared_memory.c \ - usr/lib/common/attributes.c usr/lib/common/sw_crypt.c \ -- usr/lib/common/profile_obj.c \ -+ usr/lib/common/profile_obj.c usr/lib/common/dlist.c \ - usr/lib/common/pkey_utils.c \ - usr/lib/ep11_stdll/new_host.c usr/lib/ep11_stdll/ep11_specific.c - -diff --git a/usr/lib/ica_s390_stdll/ica_s390_stdll.mk b/usr/lib/ica_s390_stdll/ica_s390_stdll.mk -index d8448486..8f467e11 100644 ---- a/usr/lib/ica_s390_stdll/ica_s390_stdll.mk -+++ b/usr/lib/ica_s390_stdll/ica_s390_stdll.mk -@@ -34,7 +34,7 @@ opencryptoki_stdll_libpkcs11_ica_la_SOURCES = \ - usr/lib/common/verify_mgr.c usr/lib/common/trace.c \ - usr/lib/common/mech_list.c usr/lib/common/shared_memory.c \ - usr/lib/common/profile_obj.c usr/lib/common/attributes.c \ -- usr/lib/ica_s390_stdll/ica_specific.c -+ usr/lib/ica_s390_stdll/ica_specific.c usr/lib/common/dlist.c - - if ENABLE_LOCKS - opencryptoki_stdll_libpkcs11_ica_la_SOURCES += \ -diff --git a/usr/lib/icsf_stdll/icsf_stdll.mk b/usr/lib/icsf_stdll/icsf_stdll.mk -index 788478c2..21c64f9a 100644 ---- a/usr/lib/icsf_stdll/icsf_stdll.mk -+++ b/usr/lib/icsf_stdll/icsf_stdll.mk -@@ -43,7 +43,7 @@ opencryptoki_stdll_libpkcs11_icsf_la_SOURCES = \ - usr/lib/common/mech_ssl3.c usr/lib/common/verify_mgr.c \ - usr/lib/common/mech_list.c usr/lib/common/shared_memory.c \ - usr/lib/common/attributes.c usr/lib/icsf_stdll/new_host.c \ -- usr/lib/common/profile_obj.c \ -+ usr/lib/common/profile_obj.c usr/lib/common/dlist.c \ - usr/lib/icsf_stdll/pbkdf.c usr/lib/icsf_stdll/icsf_specific.c \ - usr/lib/icsf_stdll/icsf_config_parse.y \ - usr/lib/icsf_stdll/icsf_config_lexer.l \ -diff --git a/usr/lib/soft_stdll/soft_stdll.mk b/usr/lib/soft_stdll/soft_stdll.mk -index cea802b5..ac401539 100644 ---- a/usr/lib/soft_stdll/soft_stdll.mk -+++ b/usr/lib/soft_stdll/soft_stdll.mk -@@ -32,7 +32,8 @@ opencryptoki_stdll_libpkcs11_sw_la_SOURCES = \ - usr/lib/common/utility.c usr/lib/common/verify_mgr.c \ - usr/lib/common/trace.c usr/lib/common/mech_list.c \ - usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \ -- usr/lib/soft_stdll/soft_specific.c usr/lib/common/attributes.c -+ usr/lib/soft_stdll/soft_specific.c usr/lib/common/attributes.c \ -+ usr/lib/common/dlist.c - - if ENABLE_LOCKS - opencryptoki_stdll_libpkcs11_sw_la_SOURCES += \ -diff --git a/usr/lib/tpm_stdll/tpm_stdll.mk b/usr/lib/tpm_stdll/tpm_stdll.mk -index f199a103..0e0eb024 100644 ---- a/usr/lib/tpm_stdll/tpm_stdll.mk -+++ b/usr/lib/tpm_stdll/tpm_stdll.mk -@@ -34,7 +34,8 @@ opencryptoki_stdll_libpkcs11_tpm_la_SOURCES = \ - usr/lib/common/verify_mgr.c usr/lib/common/mech_list.c \ - usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \ - usr/lib/tpm_stdll/tpm_specific.c usr/lib/common/attributes.c \ -- usr/lib/tpm_stdll/tpm_openssl.c usr/lib/tpm_stdll/tpm_util.c -+ usr/lib/tpm_stdll/tpm_openssl.c usr/lib/tpm_stdll/tpm_util.c \ -+ usr/lib/common/dlist.c - - if ENABLE_LOCKS - opencryptoki_stdll_libpkcs11_tpm_la_SOURCES += \ -diff --git a/usr/sbin/pkcscca/pkcscca.mk b/usr/sbin/pkcscca/pkcscca.mk -index a223265f..cc40f819 100644 ---- a/usr/sbin/pkcscca/pkcscca.mk -+++ b/usr/sbin/pkcscca/pkcscca.mk -@@ -36,7 +36,7 @@ usr_sbin_pkcscca_pkcscca_SOURCES = \ - usr/lib/common/p11util.c usr/lib/common/sw_crypt.c \ - usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \ - usr/lib/common/attributes.c usr/lib/common/mech_rng.c \ -- usr/lib/common/pkcs_utils.c \ -+ usr/lib/common/pkcs_utils.c usr/lib/common/dlist.c \ - usr/sbin/pkcscca/pkcscca.c - - -diff --git a/usr/sbin/pkcsslotd/pkcsslotd.mk b/usr/sbin/pkcsslotd/pkcsslotd.mk -index 4f0e3c56..2d36b4a9 100644 ---- a/usr/sbin/pkcsslotd/pkcsslotd.mk -+++ b/usr/sbin/pkcsslotd/pkcsslotd.mk -@@ -21,5 +21,6 @@ usr_sbin_pkcsslotd_pkcsslotd_SOURCES = \ - usr/sbin/pkcsslotd/socket_server.c - - nodist_usr_sbin_pkcsslotd_pkcsslotd_SOURCES = \ -- usr/lib/common/parser.h usr/lib/common/parser.c usr/lib/common/lexer.c -+ usr/lib/common/parser.h usr/lib/common/parser.c usr/lib/common/lexer.c \ -+ usr/lib/common/dlist.c - usr/sbin/pkcsslotd/slotmgr.$(OBJEXT): usr/lib/common/parser.h diff --git a/opencryptoki-3.16.0-e88a9de3128df1c4b89bd4c7312c15bb3eb34593.patch b/opencryptoki-3.16.0-e88a9de3128df1c4b89bd4c7312c15bb3eb34593.patch deleted file mode 100644 index a3bf6ea..0000000 --- a/opencryptoki-3.16.0-e88a9de3128df1c4b89bd4c7312c15bb3eb34593.patch +++ /dev/null @@ -1,25 +0,0 @@ -commit e88a9de3128df1c4b89bd4c7312c15bb3eb34593 -Author: Ingo Franzki -Date: Thu Jul 8 15:18:30 2021 +0200 - - pkcstok_migrate: Don't remove 'tokversion = x.y' during migration - - When migrating a slot the opencryptoki.conf file is modified. If it - contains slots that already contain the 'tokversion = x.y' keyword, - this is accidentally removed when migrating another slot. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -index 3df1596e..05081aff 100644 ---- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -@@ -2119,7 +2119,7 @@ static int parseupdate_key_vers(void *private, int tok, unsigned int vers) - { - struct parseupdate *u = (struct parseupdate *)private; - -- if (tok != KW_TOKVERSION) -+ if (tok == KW_TOKVERSION && !u->activeslot) - fprintf(u->f, " %s = %d.%d", keyword_token_to_str(tok), - vers >> 16, vers & 0xffu); - return 0; diff --git a/opencryptoki-3.16.0-e9548127edae313da7840bcb87fd0afd04549c2e.patch b/opencryptoki-3.16.0-e9548127edae313da7840bcb87fd0afd04549c2e.patch deleted file mode 100644 index 8e81324..0000000 --- a/opencryptoki-3.16.0-e9548127edae313da7840bcb87fd0afd04549c2e.patch +++ /dev/null @@ -1,310 +0,0 @@ -commit e9548127edae313da7840bcb87fd0afd04549c2e -Author: Ingo Franzki -Date: Mon Feb 8 15:26:23 2021 +0100 - - pkcsslotd: Refactoring in preparation for event support - - No functional change so far, just making things a bit bore clearer. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/include/slotmgr.h b/usr/include/slotmgr.h -index 3950a9a3..4d038435 100644 ---- a/usr/include/slotmgr.h -+++ b/usr/include/slotmgr.h -@@ -30,7 +30,7 @@ - #define TOK_PATH SBIN_PATH "/pkcsslotd" - #define OCK_API_LOCK_FILE LOCKDIR_PATH "/LCK..APIlock" - --#define SOCKET_FILE_PATH "/var/run/pkcsslotd.socket" -+#define PROC_SOCKET_FILE_PATH "/var/run/pkcsslotd.socket" - - #define PID_FILE_PATH "/var/run/pkcsslotd.pid" - #define OCK_CONFIG OCK_CONFDIR "/opencryptoki.conf" -diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c -index b74b763f..2873a20a 100644 ---- a/usr/lib/api/api_interface.c -+++ b/usr/lib/api/api_interface.c -@@ -2831,7 +2831,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - TRACE_DEBUG("Shared memory %p \n", Anchor->SharedMemP); - - /* Connect to slot daemon and retrieve slot infos */ -- Anchor->socketfd = connect_socket(SOCKET_FILE_PATH); -+ Anchor->socketfd = connect_socket(PROC_SOCKET_FILE_PATH); - if (Anchor->socketfd < 0) { - OCK_SYSLOG(LOG_ERR, "C_Initialize: Module failed to create a " - "socket. Verify that the slot management daemon is " -diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h -index 813db9f4..69eb59f3 100644 ---- a/usr/sbin/pkcsslotd/pkcsslotd.h -+++ b/usr/sbin/pkcsslotd/pkcsslotd.h -@@ -61,7 +61,6 @@ extern key_t tok; - extern Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED]; - extern unsigned int NumberSlotsInDB; - --extern int socketfd; - extern Slot_Mgr_Socket_t socketData; - - -@@ -89,9 +88,9 @@ int XProcLock(void); - int XProcUnLock(void); - int CreateXProcLock(void); - --int CreateListenerSocket(void); --int InitSocketData(Slot_Mgr_Socket_t *sp); --int SocketConnectionHandler(int socketfd, int timeout_secs); --void DetachSocketListener(int socketfd); -+int init_socket_server(); -+int term_socket_server(); -+int init_socket_data(Slot_Mgr_Socket_t *sp); -+int socket_connection_handler(int timeout_secs); - - #endif /* _SLOTMGR_H */ -diff --git a/usr/sbin/pkcsslotd/signal.c b/usr/sbin/pkcsslotd/signal.c -index cf7b9087..49482a2f 100644 ---- a/usr/sbin/pkcsslotd/signal.c -+++ b/usr/sbin/pkcsslotd/signal.c -@@ -101,7 +101,7 @@ void slotdGenericSignalHandler(int Signal) - - InfoLog("Exiting on %s (%d; %#x)", SignalConst(Signal), Signal, Signal); - -- DetachSocketListener(socketfd); -+ term_socket_server(); - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c -index ea5c86f5..94288f13 100644 ---- a/usr/sbin/pkcsslotd/slotmgr.c -+++ b/usr/sbin/pkcsslotd/slotmgr.c -@@ -37,7 +37,6 @@ unsigned int NumberSlotsInDB = 0; - - Slot_Info_t_64 *psinfo; - --int socketfd; - Slot_Mgr_Socket_t socketData; - - struct dircheckinfo_s { -@@ -569,15 +568,15 @@ int main(int argc, char *argv[], char *envp[]) - if (!XProcUnLock()) - return 4; - -- if ((socketfd = CreateListenerSocket()) < 0) { -+ if (!init_socket_server()) { - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); - return 5; - } - -- if (!InitSocketData(&socketData)) { -- DetachSocketListener(socketfd); -+ if (!init_socket_data(&socketData)) { -+ term_socket_server(); - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -@@ -598,7 +597,7 @@ int main(int argc, char *argv[], char *envp[]) - if (Daemon) { - pid_t pid; - if ((pid = fork()) < 0) { -- DetachSocketListener(socketfd); -+ term_socket_server(); - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -@@ -643,7 +642,7 @@ int main(int argc, char *argv[], char *envp[]) - * the daemonization process redefines our handler for (at least) SIGTERM - */ - if (!SetupSignalHandlers()) { -- DetachSocketListener(socketfd); -+ term_socket_server(); - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -@@ -664,7 +663,7 @@ int main(int argc, char *argv[], char *envp[]) - printf("Start garbage \n"); - /* start garbage collection thread */ - if (!StartGCThread(shmp)) { -- DetachSocketListener(socketfd); -+ term_socket_server(); - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -@@ -684,7 +683,7 @@ int main(int argc, char *argv[], char *envp[]) - #if !(THREADED) && !(NOGARBAGE) - CheckForGarbage(shmp); - #endif -- SocketConnectionHandler(socketfd, 10); -+ socket_connection_handler(10); - } - - /************************************************************* -diff --git a/usr/sbin/pkcsslotd/socket_server.c b/usr/sbin/pkcsslotd/socket_server.c -index ae0eff92..1fae0b95 100644 ---- a/usr/sbin/pkcsslotd/socket_server.c -+++ b/usr/sbin/pkcsslotd/socket_server.c -@@ -25,10 +25,14 @@ - #include "pkcsslotd.h" - #include "apictl.h" - -+int proc_listener_socket = -1; -+ -+static void close_listener_socket(int socketfd, const char *file_path); -+ - // Creates the daemon's listener socket, to which clients will connect and - // retrieve slot information through. Returns the file descriptor of the - // created socket. --int CreateListenerSocket(void) -+static int create_listener_socket(const char *file_path) - { - struct sockaddr_un address; - struct group *grp; -@@ -39,53 +43,60 @@ int CreateListenerSocket(void) - ErrLog("Failed to create listener socket, errno 0x%X.", errno); - return -1; - } -- if (unlink(SOCKET_FILE_PATH) && errno != ENOENT) { -+ if (unlink(file_path) && errno != ENOENT) { - ErrLog("Failed to unlink socket file, errno 0x%X.", errno); -- close(socketfd); -- return -1; -+ goto error; - } - - memset(&address, 0, sizeof(struct sockaddr_un)); - address.sun_family = AF_UNIX; -- strcpy(address.sun_path, SOCKET_FILE_PATH); -+ strcpy(address.sun_path, file_path); - - if (bind(socketfd, - (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) { - ErrLog("Failed to bind to socket, errno 0x%X.", errno); -- close(socketfd); -- return -1; -+ goto error; - } - // make socket file part of the pkcs11 group, and write accessable - // for that group - grp = getgrnam("pkcs11"); - if (!grp) { - ErrLog("Group PKCS#11 does not exist"); -- DetachSocketListener(socketfd); -- return -1; -+ goto error; - } -- if (chown(SOCKET_FILE_PATH, 0, grp->gr_gid)) { -+ if (chown(file_path, 0, grp->gr_gid)) { - ErrLog("Could not change file group on socket, errno 0x%X.", errno); -- DetachSocketListener(socketfd); -- return -1; -+ goto error; - } -- if (chmod(SOCKET_FILE_PATH, -+ if (chmod(file_path, - S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP | S_IXUSR | S_IXGRP)) { - ErrLog("Could not change file permissions on socket, errno 0x%X.", - errno); -- DetachSocketListener(socketfd); -- return -1; -+ goto error; - } - - if (listen(socketfd, 20) != 0) { - ErrLog("Failed to listen to socket, errno 0x%X.", errno); -- DetachSocketListener(socketfd); -- return -1; -+ goto error; - } - - return socketfd; -+ -+error: -+ if (socketfd >= 0) -+ close_listener_socket(socketfd, file_path); -+ -+ return -1; -+} -+ -+ -+static void close_listener_socket(int socketfd, const char *file_path) -+{ -+ close(socketfd); -+ unlink(file_path); - } - --int InitSocketData(Slot_Mgr_Socket_t *socketData) -+int init_socket_data(Slot_Mgr_Socket_t *socketData) - { - unsigned int processed = 0; - -@@ -102,19 +113,19 @@ int InitSocketData(Slot_Mgr_Socket_t *socketData) - return TRUE; - } - --int SocketConnectionHandler(int socketfd, int timeout_secs) -+int socket_connection_handler(int timeout_secs) - { - int returnVal; - fd_set set; - struct timeval timeout; - - FD_ZERO(&set); -- FD_SET(socketfd, &set); -+ FD_SET(proc_listener_socket, &set); - - timeout.tv_sec = timeout_secs; - timeout.tv_usec = 0; - -- returnVal = select(socketfd + 1, &set, NULL, NULL, &timeout); -+ returnVal = select(proc_listener_socket + 1, &set, NULL, NULL, &timeout); - if (returnVal == -1) { - ErrLog("select failed on socket connection, errno 0x%X.", errno); - return FALSE; -@@ -125,7 +136,7 @@ int SocketConnectionHandler(int socketfd, int timeout_secs) - struct sockaddr_un address; - socklen_t address_length = sizeof(address); - -- int connectionfd = accept(socketfd, -+ int connectionfd = accept(proc_listener_socket, - (struct sockaddr *) &address, - &address_length); - if (connectionfd < 0) { -@@ -138,6 +149,10 @@ int SocketConnectionHandler(int socketfd, int timeout_secs) - } - return FALSE; - } -+ -+ DbgLog(DL0, "Accepted connection from process: socket: %d", -+ connectionfd); -+ - if (write(connectionfd, &socketData, sizeof(socketData)) != - sizeof(socketData)) { - ErrLog("Failed to write socket data, errno 0x%X.", errno); -@@ -149,8 +164,23 @@ int SocketConnectionHandler(int socketfd, int timeout_secs) - } - } - --void DetachSocketListener(int socketfd) -+int init_socket_server() - { -- close(socketfd); -- unlink(SOCKET_FILE_PATH); -+ proc_listener_socket = create_listener_socket(PROC_SOCKET_FILE_PATH); -+ if (proc_listener_socket < 0) -+ return FALSE; -+ -+ DbgLog(DL0, "Socket server started"); -+ -+ return TRUE; -+} -+ -+int term_socket_server() -+{ -+ if (proc_listener_socket >= 0) -+ close_listener_socket(proc_listener_socket, PROC_SOCKET_FILE_PATH); -+ -+ DbgLog(DL0, "Socket server stopped"); -+ -+ return TRUE; - } diff --git a/opencryptoki-3.16.0-fa94a16116d8382a987ddf9e8cdd88027dd1f647.patch b/opencryptoki-3.16.0-fa94a16116d8382a987ddf9e8cdd88027dd1f647.patch deleted file mode 100644 index 30a506a..0000000 --- a/opencryptoki-3.16.0-fa94a16116d8382a987ddf9e8cdd88027dd1f647.patch +++ /dev/null @@ -1,287 +0,0 @@ -commit fa94a16116d8382a987ddf9e8cdd88027dd1f647 -Author: Ingo Franzki -Date: Tue Feb 16 17:13:34 2021 +0100 - - Event support: Add event client - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/common/common.mk b/usr/lib/common/common.mk -index 2178ad45..882c84f4 100644 ---- a/usr/lib/common/common.mk -+++ b/usr/lib/common/common.mk -@@ -4,7 +4,7 @@ noinst_HEADERS += \ - usr/lib/common/shared_memory.h usr/lib/common/tok_spec_struct.h \ - usr/lib/common/trace.h usr/lib/common/h_extern.h \ - usr/lib/common/sw_crypt.h usr/lib/common/defs.h \ -- usr/lib/common/p11util.h \ -+ usr/lib/common/p11util.h usr/lib/common/event_client.h \ - usr/lib/common/list.h usr/lib/common/tok_specific.h - - usr/lib/common/lexer.c: usr/lib/common/parser.h -diff --git a/usr/lib/common/event_client.c b/usr/lib/common/event_client.c -new file mode 100644 -index 00000000..86117b84 ---- /dev/null -+++ b/usr/lib/common/event_client.c -@@ -0,0 +1,215 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "slotmgr.h" -+#include "event_client.h" -+ -+static int connect_socket(const char *file_path) -+{ -+ int socketfd; -+ struct sockaddr_un daemon_address; -+ struct stat file_info; -+ struct group *grp; -+ int rc; -+ -+ if (stat(file_path, &file_info)) -+ return -errno; -+ -+ grp = getgrnam("pkcs11"); -+ if (!grp) -+ return -errno; -+ -+ if (file_info.st_uid != 0 || file_info.st_gid != grp->gr_gid) -+ return -EPERM; -+ -+ if ((socketfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) -+ return -errno; -+ -+ memset(&daemon_address, 0, sizeof(struct sockaddr_un)); -+ daemon_address.sun_family = AF_UNIX; -+ strcpy(daemon_address.sun_path, file_path); -+ -+ if (connect(socketfd, (struct sockaddr *) &daemon_address, -+ sizeof(struct sockaddr_un)) != 0) { -+ rc = -errno; -+ goto error; -+ } -+ -+ return socketfd; -+ -+error: -+ close(socketfd); -+ return rc; -+} -+ -+static ssize_t read_all(int socketfd, char *buffer, size_t size) -+{ -+ size_t bytes_received = 0; -+ ssize_t n; -+ -+ while (bytes_received < size) { -+ n = read(socketfd, buffer + bytes_received, size - bytes_received); -+ if (n < 0) { -+ // read error -+ if (errno == EINTR) -+ continue; -+ return -errno; -+ } -+ if (n == 0) -+ break; -+ -+ bytes_received += n; -+ } -+ -+ return bytes_received; -+} -+ -+static ssize_t send_all(int socketfd, char *buffer, size_t size) -+{ -+ size_t bytes_sent = 0; -+ ssize_t n; -+ -+ while (bytes_sent < size) { -+ n = send(socketfd, buffer + bytes_sent, size - bytes_sent, 0); -+ if (n < 0) { -+ // send error -+ if (errno == EINTR) -+ continue; -+ return -errno; -+ } -+ if (n == 0) -+ break; -+ -+ bytes_sent += n; -+ } -+ -+ return bytes_sent; -+} -+ -+/* -+ * Initialize an admin connection to the pkcsslotd. -+ * Returns a file descriptor representing the connection, or a negative errno -+ * in case of an error. -+ */ -+int init_event_client() -+{ -+ int fd; -+ -+ fd = connect_socket(ADMIN_SOCKET_FILE_PATH); -+ -+ return fd; -+} -+ -+/* -+ * Send an event though the admin connection to the pkcsslotd, and thus to -+ * all active token instances. -+ * If parameter fd is < 0, then a connection to pkcsslotd is established -+ * inside the function and closed before return. This is for a one shot event. -+ * Otherwise, pass a file descriptor received from init_event_client(). This -+ * is to send multiple events. -+ * Event type is mandatory, flags can be zero. -+ * The event payload is optional, if payload_len is non-zero, then payload must -+ * point to a buffer containing the payload to send with the event. -+ * The event destination can be used to selectively send the event to certain -+ * token instances only. If destination is NULL, it is sent to all token -+ * instances. -+ * If flag EVENT_FLAGS_REPLY_REQ is on in the flags parameter, then it is waited -+ * until all active token instances have replied. The combined result of the -+ * replies from the token instances is returned in the reply structure. -+ * Parameter reply must be non-NULL if flag EVENT_FLAGS_REPLY_REQ is set. -+ * Returns zero for success, or a negative errno in case of an error. In most -+ * error cases the connection to the pkcsslotd is out of sequence and can no -+ * longer be used to send further events. -+ */ -+int send_event(int fd, unsigned int type, unsigned int flags, -+ unsigned int payload_len, const char *payload, -+ const struct event_destination *destination, -+ struct event_reply *reply) -+{ -+ event_msg_t event_msg; -+ event_reply_t event_reply; -+ int rc, term = 0; -+ -+ if (payload_len > 0 && payload == NULL) -+ return -EINVAL; -+ if ((flags & EVENT_FLAGS_REPLY_REQ) && reply == NULL) -+ return -EINVAL; -+ if (payload_len > EVENT_MAX_PAYLOAD_LENGTH) -+ return -EMSGSIZE; -+ -+ if (fd < 0) { -+ fd = init_event_client(); -+ if (fd < 0) -+ return fd; -+ term = 1; -+ } -+ -+ memset(&event_msg, 0, sizeof(event_msg)); -+ event_msg.version = EVENT_VERSION_1; -+ event_msg.type = type; -+ event_msg.flags = flags; -+ if (destination != NULL) { -+ event_msg.token_type = destination->token_type; -+ memcpy(event_msg.token_label, destination->token_label, -+ sizeof(event_msg.token_label)); -+ event_msg.process_id = destination->process_id; -+ } else { -+ memset(event_msg.token_label, ' ', sizeof(event_msg.token_label)); -+ } -+ event_msg.payload_len = payload_len; -+ -+ rc = send_all(fd, (char *)&event_msg, sizeof(event_msg)); -+ if (rc < 0) -+ goto out; -+ -+ if (payload_len > 0) { -+ rc = send_all(fd, (char *)payload, payload_len); -+ if (rc < 0) -+ goto out; -+ } -+ -+ if (flags & EVENT_FLAGS_REPLY_REQ) { -+ rc = read_all(fd, (char *)&event_reply, sizeof(event_reply)); -+ if (rc < 0) -+ goto out; -+ -+ reply->positive_replies = event_reply.positive_replies; -+ reply->negative_replies = event_reply.negative_replies; -+ reply->nothandled_replies = event_reply.nothandled_replies; -+ } -+ -+ rc = 0; -+ -+out: -+ if (term) -+ term_event_client(fd); -+ -+ return rc; -+} -+ -+/* -+ * Terminate the admin connection to the pkcsslotd. -+ */ -+void term_event_client(int fd) -+{ -+ if (fd >= 0) -+ close(fd); -+} -+ -diff --git a/usr/lib/common/event_client.h b/usr/lib/common/event_client.h -new file mode 100644 -index 00000000..2e4917b0 ---- /dev/null -+++ b/usr/lib/common/event_client.h -@@ -0,0 +1,39 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+ -+#ifndef _EVENT_CLIENT_H_ -+#define _EVENT_CLIENT_H_ -+ -+#include "events.h" -+ -+struct event_destination { -+ unsigned int token_type; /* Destination token type: EVENT_TOK_TYPE_xxx */ -+ char token_label[member_size(event_msg_t, token_label)]; -+ /* Label of destination token (or blanks) */ -+ pid_t process_id; /* Process ID of destination process (or 0) */ -+}; -+ -+struct event_reply { -+ unsigned long positive_replies; -+ unsigned long negative_replies; -+ unsigned long nothandled_replies; -+}; -+ -+int init_event_client(); -+ -+int send_event(int fd, unsigned int type, unsigned int flags, -+ unsigned int payload_len, const char *payload, -+ const struct event_destination *destination, -+ struct event_reply *reply); -+ -+void term_event_client(int fd); -+ -+#endif diff --git a/opencryptoki-3.16.0-pkcstok_migrate-detection_if_pkcsslotd_is_still_running.patch b/opencryptoki-3.16.0-pkcstok_migrate-detection_if_pkcsslotd_is_still_running.patch deleted file mode 100644 index 128ea06..0000000 --- a/opencryptoki-3.16.0-pkcstok_migrate-detection_if_pkcsslotd_is_still_running.patch +++ /dev/null @@ -1,106 +0,0 @@ -commit 5951869263b556280da53498270cf4826f779c5b -Author: Ingo Franzki -Date: Tue Jul 13 09:05:22 2021 +0200 - - pkcstok_migrate: Fix detection if pkcsslotd is still running - - Change the code to use the pid file that pkcsslotd creates, and check - if the process with the pid contained in the pid file still exists and - runs pkcsslotd. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -index 05081aff..a29dc8f7 100644 ---- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -@@ -2474,54 +2474,53 @@ static CK_RV backup_repository(const char *data_store) - */ - static CK_BBOOL pkcsslotd_running(void) - { -- DIR *dir; - FILE *fp; -- struct dirent* ent; - char* endptr; -- char buf[PATH_MAX]; -+ long lpid; - char fname[PATH_MAX]; -+ char buf[PATH_MAX]; -+ char* first; - - TRACE_INFO("Checking if pkcsslotd is running ...\n"); -- if (!(dir = opendir("/proc"))) { -- TRACE_WARN("Cannot open /proc, i.e. cannot check if pkcsslotd is running.\n"); -- return CK_TRUE; -+ -+ fp = fopen(PID_FILE_PATH, "r"); -+ if (fp == NULL) { -+ TRACE_INFO("Pid file '%s' not existent, pkcsslotd is not running\n", -+ PID_FILE_PATH); -+ return CK_FALSE; - } - -- while ((ent = readdir(dir)) != NULL) { -- /* if endptr is not a null character, the directory is not -- * entirely numeric, so ignore it */ -- long lpid = strtol(ent->d_name, &endptr, 10); -- if (*endptr != '\0') { -- continue; -- } -+ if (fgets(buf, sizeof(buf), fp) == NULL) { -+ TRACE_WARN("Cannot read pid file '%s': %s\n", PID_FILE_PATH, -+ strerror(errno)); -+ fclose(fp); -+ return CK_FALSE; -+ } -+ fclose(fp); - -- /* try to open the cmdline file */ -- snprintf(fname, sizeof(fname), "/proc/%ld/cmdline", lpid); -- fp = fopen(fname, "r"); -- if (!fp) { -- warnx("fopen(%s) failed, errno=%s", fname, strerror(errno)); -- return CK_TRUE; -- } -+ lpid = strtol(buf, &endptr, 10); -+ if (*endptr != '\0' && *endptr != '\n') { -+ TRACE_WARN("Failed to parse pid file '%s': %s\n", PID_FILE_PATH, -+ buf); -+ return CK_FALSE; -+ } - -- /* check the first token in the file: the program pathname */ -- if (fgets(buf, sizeof(buf), fp) != NULL) { -- char* first = strtok(buf, " "); -- if (!first) { -- TRACE_WARN("Cannot read program name from %s, i.e. cannot check if pkcsslotd is running.\n", -- fname); -- return CK_TRUE; -- } -- if (strstr(first, "pkcsslotd") != NULL) { -- fclose(fp); -- closedir(dir); -- return CK_TRUE; -- } -- } -+ snprintf(fname, sizeof(fname), "/proc/%ld/cmdline", lpid); -+ fp = fopen(fname, "r"); -+ if (fp == NULL) { -+ TRACE_INFO("Stale pid file, pkcsslotd is not running\n"); -+ return CK_FALSE; -+ } -+ -+ if (fgets(buf, sizeof(buf), fp) == NULL) { -+ TRACE_INFO("Failed to read '%s'\n", fname); - fclose(fp); -+ return CK_FALSE; - } -+ fclose(fp); - -- closedir(dir); -- return CK_FALSE; -+ first = strtok(buf, " "); -+ return (first != NULL && strstr(first, "pkcsslotd") != NULL); - } - - /** diff --git a/opencryptoki.spec b/opencryptoki.spec index e3ca16b..4d38aef 100644 --- a/opencryptoki.spec +++ b/opencryptoki.spec @@ -1,7 +1,7 @@ Name: opencryptoki -Summary: Implementation of the PKCS#11 (Cryptoki) specification v2.11 -Version: 3.16.0 -Release: 5%{?dist} +Summary: Implementation of the PKCS#11 (Cryptoki) specification v3.0 +Version: 3.17.0 +Release: 1%{?dist} License: CPL URL: https://github.com/opencryptoki/opencryptoki Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz @@ -16,33 +16,12 @@ Patch1: opencryptoki-3.11.0-lockdir.patch #Patch100: %%{name}-3.2-no-undefined.patch # upstream patches -Patch200: opencryptoki-3.16.0-4e3b43c3d8844402c04a66b55c6c940f965109f0.patch -Patch201: opencryptoki-3.16.0-c79e899d77a5724635a9d4451a34a240e2c7e891.patch -Patch202: opencryptoki-3.16.0-69244a5e0d9dfec3ef534b19b89a541576bb17dc.patch -Patch203: opencryptoki-3.16.0-b07505993dd8b2f367cf3b630f6da186e4e8550d.patch -Patch204: opencryptoki-3.16.0-b048be548508dd1958bb7271568f388d0f6cbcf8.patch -Patch205: opencryptoki-3.16.0-e9548127edae313da7840bcb87fd0afd04549c2e.patch -Patch206: opencryptoki-3.16.0-d929fe8470e99f4dcbbd889e7aa87e147d0d5b48.patch -Patch207: opencryptoki-3.16.0-19f56d12b302b87e1dacf613cc61a063ad209d15.patch -Patch208: opencryptoki-3.16.0-342dfbeb8275f5ea6ed52dd3f30126614ec1d037.patch -Patch209: opencryptoki-3.16.0-fa94a16116d8382a987ddf9e8cdd88027dd1f647.patch -Patch210: opencryptoki-3.16.0-d7de5092247a0efc2c397f12977a7c9925420143.patch -Patch211: opencryptoki-3.16.0-1fdd0e4497b0078e73e0004e3492db647c7c458b.patch -Patch212: opencryptoki-3.16.0-bf812c652c49d7e248b115d121a4f7f6568941a2.patch -Patch213: opencryptoki-3.16.0-7b7d83c571ceb3050969359817d4145600f14ae8.patch -Patch214: opencryptoki-3.16.0-pkcstok_migrate-detection_if_pkcsslotd_is_still_running.patch -Patch215: opencryptoki-3.16.0-5824364d995e5d2418f885ee57e377e11d1b3302.patch -Patch216: opencryptoki-3.16.0-e88a9de3128df1c4b89bd4c7312c15bb3eb34593.patch -Patch217: opencryptoki-3.16.0-d2f137cce5e6efb123842509352c7c49f889c67f.patch - -# PIDfile below legacy directory /var/run/ -Patch300: opencryptoki-pkcsslotd-pidfile.patch Requires(pre): coreutils Requires: (selinux-policy >= 34.9-1 if selinux-policy-targeted) BuildRequires: gcc BuildRequires: gcc-c++ -BuildRequires: openssl-devel +BuildRequires: openssl-devel >= 1.1.1 %if 0%{?tmptok} BuildRequires: trousers-devel %endif @@ -65,7 +44,7 @@ Requires(postun): systemd %description -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -78,7 +57,7 @@ Summary: The run-time libraries for opencryptoki package Requires(pre): shadow-utils %description libs -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -104,7 +83,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description swtok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -120,7 +99,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description tpmtok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -136,7 +115,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description icsftok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -153,7 +132,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description icatok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -170,7 +149,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description ccatok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -187,7 +166,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description ep11tok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -344,6 +323,9 @@ fi %changelog +* Tue Oct 19 2021 Than Ngo - 3.17.0-1 +- rebase to 3.17.0 + * Tue Sep 14 2021 Sahana Prasad - 3.16.0-5 - Rebuilt with OpenSSL 3.0.0 diff --git a/sources b/sources index d0cd91a..7bfc995 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (opencryptoki-3.16.0.tar.gz) = e7f54653bf8b57f7fb713c03aafe07e44a028d7ca10f68a3049e0353014c379a0c1aeda19329f5da4974cc6f2f7c906f4964586abd682cc867eccecc05f134a4 +SHA512 (opencryptoki-3.17.0.tar.gz) = 1e80f4cebfffef1b50f3a29577c003e3a3ac68f9c93c3fd49537dad5ab82d02ab54f62fa73e93cd20f2ea1517eb4aa3a0ac167df3597bb801e8781a4162f9d01