Index: build/libcackey_wrap.c.in ================================================================== --- build/libcackey_wrap.c.in +++ build/libcackey_wrap.c.in @@ -1,13 +1,13 @@ #define _GNU_SOURCE #include #include "config.h" -#include #include #include +#include #define CK_PTR * #define CK_DEFINE_FUNCTION(returnType, name) returnType name #define CK_DECLARE_FUNCTION(returnType, name) returnType name #define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name) @@ -20,55 +20,78 @@ #ifndef CACKEY_LIBRARY_FILE #define CACKEY_LIBRARY_FILE "libcackey_g.so" #endif +void abort(void); +void free(void *ptr); + static void *libcackey_wrap_handle = NULL_PTR; -static void libcackey_wrap_init(void); - -static CK_RV libcackey_wrap_createmutex(CK_VOID_PTR_PTR ppMutex) { - int (*create_mutex)(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); - pthread_mutex_t *pthread_mutex; - int pthread_retval; - - libcackey_wrap_init(); - - pthread_mutex = malloc(sizeof(*pthread_mutex)); - - create_mutex = dlsym(libcackey_wrap_handle, "pthread_mutex_init"); - pthread_retval = create_mutex(pthread_mutex, NULL); - if (pthread_retval != 0) { - return(CKR_GENERAL_ERROR); - } - - *ppMutex = pthread_mutex; +typedef enum { + LIBCACKEY_WRAP_MUTEX_UNINIT = 0, + LIBCACKEY_WRAP_MUTEX_INIT, + LIBCACKEY_WRAP_MUTEX_UNLOCKED, + LIBCACKEY_WRAP_MUTEX_LOCKED, +} libcackey_wrap_mutexes_states_t; +static libcackey_wrap_mutexes_states_t libcackey_wrap_mutexes[16] = {LIBCACKEY_WRAP_MUTEX_UNINIT}; + +typedef libcackey_wrap_mutexes_states_t *pthread_mutex_t; +typedef int pthread_mutexattr_t; + +int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr) { + libcackey_wrap_mutexes_states_t *mutex_; + int idx; + + for (idx = 0; idx < (sizeof(libcackey_wrap_mutexes) / sizeof(libcackey_wrap_mutexes[0])); idx++) { + if (libcackey_wrap_mutexes[idx] == LIBCACKEY_WRAP_MUTEX_UNINIT) { + libcackey_wrap_mutexes[idx] = LIBCACKEY_WRAP_MUTEX_INIT; + mutex_ = &libcackey_wrap_mutexes[idx]; + break; + } + } + + if (!mutex_) { + return(1); + } + + *mutex = mutex_; + + return(0); +} + +int pthread_mutex_destroy(pthread_mutex_t *mutex) { + **mutex = LIBCACKEY_WRAP_MUTEX_UNINIT; + + return(0); +} + +int pthread_mutex_lock(pthread_mutex_t *mutex) { + struct timespec sleeptime; + + while (**mutex == LIBCACKEY_WRAP_MUTEX_LOCKED) { + sleeptime.tv_sec = 0; + sleeptime.tv_nsec = 1000000; + nanosleep(&sleeptime, NULL); +fprintf(stderr, "mutex %p is locked\n", mutex); fflush(stderr); + /* Do nothing */ + } + +fprintf(stderr, "locking mutex %p\n", mutex); fflush(stderr); + **mutex = LIBCACKEY_WRAP_MUTEX_LOCKED; +fprintf(stderr, "locked mutex %p\n", mutex); fflush(stderr); return(CKR_OK); } -#define libcackey_wrap_genericmutexfunc(funcName, pthreadName) \ - static CK_RV funcName(CK_VOID_PTR pMutex) { \ - int (*func)(pthread_mutex_t *mutex); \ - pthread_mutex_t *pthread_mutex; \ - int pthread_retval; \ - libcackey_wrap_init(); \ - pthread_mutex = pMutex; \ - func = dlsym(libcackey_wrap_handle, pthreadName); \ - pthread_retval = func(pthread_mutex); \ - if (pthread_retval != 0) { \ - return(CKR_GENERAL_ERROR); \ - } \ - if (strcmp(pthreadName, "pthread_mutex_destroy") == 0) { \ - free(pthread_mutex); \ - } \ - return(CKR_OK); \ - } - -libcackey_wrap_genericmutexfunc(libcackey_wrap_destroymutex, "pthread_mutex_destroy") -libcackey_wrap_genericmutexfunc(libcackey_wrap_lockmutex, "pthread_mutex_lock") -libcackey_wrap_genericmutexfunc(libcackey_wrap_unlockmutex, "pthread_mutex_unlock") +int pthread_mutex_unlock(pthread_mutex_t *mutex) { +fprintf(stderr, "unlocking mutex %p\n", mutex); fflush(stderr); + **mutex = LIBCACKEY_WRAP_MUTEX_UNLOCKED; +fprintf(stderr, "unlocked mutex %p\n", mutex); fflush(stderr); + + return(CKR_OK); +} static void libcackey_wrap_init(void) { Dl_info libinfo; int dladdr_ret; char *library, *libraryDir, *libraryDirLastSlash; @@ -106,10 +129,11 @@ *libraryDirLastSlash = '\0'; asprintf(&library, "%s/" CACKEY_LIBRARY_FILE, libraryDir); libcackey_wrap_handle = dlmopen(LM_ID_NEWLM, library, RTLD_LOCAL | RTLD_NOW); + libcackey_wrap_handle = dlmopen(LM_ID_NEWLM, , RTLD_LOCAL | RTLD_NOW); if (!libcackey_wrap_handle) { fprintf(stderr, "Unable to load \"%s\": %s\n", library, dlerror()); abort(); Index: build/make-libcackey_wrap ================================================================== --- build/make-libcackey_wrap +++ build/make-libcackey_wrap @@ -39,38 +39,19 @@ echo $'\t'"CK_RV (*func)($(echo "${args}" | tr $'\n' ',' | sed 's@,*$@@;s@,@, @g'));" case "${function}" in C_Finalize) echo $'\t''CK_RV retval;' ;; - C_Initialize) - echo $'\t''CK_C_INITIALIZE_ARGS CK_PTR args, localargs;' - ;; C_GetFunctionList) echo $'\t''CK_RV retval;' echo $'\t''CK_FUNCTION_LIST_PTR pFunctionList;' ;; esac echo '' echo $'\t''libcackey_wrap_init();' - if [ "${function}" = 'C_Initialize' ]; then - echo '' - echo $'\t''if (pInitArgs) {' - echo $'\t\t''args = pInitArgs;' - echo $'\t\t''if ((args->flags & CKF_OS_LOCKING_OK) == CKF_OS_LOCKING_OK) {' -#echo 'fprintf(stderr, "replacing=%p\n", pInitArgs); fflush(stderr); abort();' - echo $'\t\t\t''memcpy(&localargs, args, sizeof(*args));' - echo $'\t\t\t''localargs.CreateMutex = libcackey_wrap_createmutex;' - echo $'\t\t\t''localargs.DestroyMutex = libcackey_wrap_destroymutex;' - echo $'\t\t\t''localargs.LockMutex = libcackey_wrap_lockmutex;' - echo $'\t\t\t''localargs.UnlockMutex = libcackey_wrap_unlockmutex;' - echo $'\t\t\t''localargs.flags &= ~CKF_OS_LOCKING_OK;' - echo $'\t\t\t''pInitArgs = &localargs;' - echo $'\t\t''}' - echo $'\t''}' - fi echo '' echo $'\t'"func = dlsym(libcackey_wrap_handle, \"${function}\");" echo '' if [ "${function}" = 'C_Finalize' ]; then echo $'\t'"retval = func($argNamesList);" Index: test.c ================================================================== --- test.c +++ test.c @@ -555,13 +555,13 @@ } printf("\n"); } } - chk_rv = C_OpenSession(slots[0], CKF_SERIAL_SESSION, NULL, NULL, &hSession); + chk_rv = C_OpenSession(slots[1], CKF_SERIAL_SESSION, NULL, NULL, &hSession); if (chk_rv == CKR_OK) { - chk_rv = C_GetTokenInfo(slots[0], &tokenInfo); + chk_rv = C_GetTokenInfo(slots[1], &tokenInfo); if (chk_rv != CKR_OK) { return(1); } if ((tokenInfo.flags & CKF_LOGIN_REQUIRED) == CKF_LOGIN_REQUIRED && (tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {