From 01f5a4c3169f19d8648a80e913bc4d570e96346d Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Fri, 5 Dec 2008 02:37:04 +0000 Subject: Added config file support. --- src/Makefile.am | 1 + src/config.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/module.c | 75 ++++++++++++++++++++++++-------------- src/msg.c | 18 +++++++--- src/p11-tests.c | 17 ++++++--- src/p11-tests.h | 16 +++++++-- src/session.c | 15 ++++++-- 7 files changed, 213 insertions(+), 39 deletions(-) create mode 100644 src/config.c diff --git a/src/Makefile.am b/src/Makefile.am index 49a9801..e9cfd0e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,7 @@ bin_PROGRAMS = p11-tests p11_tests_LDADD = -ldl p11_tests_SOURCES = \ check.c \ + config.c \ module.c \ msg.c \ p11-tests.c \ diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..65cc70c --- /dev/null +++ b/src/config.c @@ -0,0 +1,110 @@ + +#include "config.h" + +#include "p11-tests.h" + +#include +#include +#include +#include + +static char* config_data = NULL; + +static char* +trim(char* data) +{ + char *t; + while(*data && isspace(*data)) + ++data; + + t = data + strlen(data); + while(t > data && isspace(*(t - 1))) + { + t--; + *t = 0; + } + + return data; +} + +void +p11t_config_parse(const char* filename) +{ + char* name = NULL; + char* value = NULL; + char* next; + FILE* f = NULL; + long len; + char* p; + char* t; + + f = fopen(filename, "r"); + if(f == NULL) + p11t_msg_exit(1, "couldn't open config file: %s", filename); + + /* Figure out size */ + if(fseek(f, 0, SEEK_END) == -1 || (len = ftell(f)) == -1 || fseek(f, 0, SEEK_SET) == -1) + p11t_msg_exit(1, "couldn't seek config file: %s", filename); + + assert(!config_data); + config_data = malloc(len + 2); + if(!config_data) + p11t_msg_exit(1, "out of memory"); + + /* And read in one block */ + if(fread(config_data, 1, len, f) != len) + p11t_msg_exit(1, "couldn't read config file: %s", filename); + + fclose(f); + + /* Null terminate the data */ + config_data[len] = '\n'; + config_data[len + 1] = 0; + + next = config_data; + + /* Go through lines and process them */ + while((t = strchr(next, '\n')) != NULL) + { + *t = 0; + p = next; /* Do this before cleaning below */ + next = t + 1; + + t = trim(p); + + name = NULL; + value = NULL; + + /* Empty lines / comments at start / comments without continuation */ + if(!*t || *p == '#') + continue; + + /* Look for the break between name = value on the same line */ + t = p + strcspn(p, ":="); + if(!*t) + { + fprintf(stderr, "p11-test: invalid config line: %s", p); + exit(1); + } + + /* Null terminate and split value part */ + *t = 0; + t++; + + name = trim(p); + value = t; + + if(name && value) + { + p11t_module_config(name, value); + p11t_session_config(name, value); + } + } +} + +void +p11t_config_cleanup(void) +{ + free(config_data); + config_data = NULL; +} diff --git a/src/module.c b/src/module.c index c20bd3c..e2b2185 100644 --- a/src/module.c +++ b/src/module.c @@ -11,9 +11,13 @@ static void *module = NULL; CK_FUNCTION_LIST_PTR p11t_module_funcs = NULL; + +static const char *init_string = NULL; static CK_C_INITIALIZE_ARGS init_args; +static void (*init_func)(void) = NULL; static int is_initialized = 0; + static CK_RV create_mutex(void **mutex) { @@ -162,12 +166,6 @@ p11t_module_load(const char *filename) if(rv != CKR_OK) p11t_msg_fatal("couldn't get function list: %s", p11t_msg_rv(rv)); - /* Make sure we have a compatible version */ - if(p11t_module_funcs->version.major != CRYPTOKI_VERSION_MAJOR) - p11t_msg_fatal("incompatible version of pkcs11 module: %d.%d", - (int)p11t_module_funcs->version.major, - (int)p11t_module_funcs->version.minor); - /** C_GetFunctionList */ rv = (p11t_module_funcs->C_GetFunctionList)(&list); if(rv != CKR_OK) @@ -178,7 +176,7 @@ p11t_module_load(const char *filename) p11t_msg_print("function lists returned directly and recursively differ"); } -static void +static int initialize_common(const char *mode) { CK_RV rv; @@ -193,34 +191,38 @@ initialize_common(const char *mode) { if(rv != CKR_CANT_LOCK) p11t_msg_print("C_Initialize failed (%s): %s", mode, p11t_msg_rv(rv)); + return 0; } else { is_initialized = 1; + return 1; } } static void -initialize_locking_1(const char *initstr) +initialize_locking_1(void) { /** - Locking: no threads */ memset(&init_args, 0, sizeof (init_args)); - init_args.pReserved = (void*)initstr; - initialize_common("locking mode 1: no threads"); + init_args.pReserved = (void*)init_string; + if(initialize_common("locking mode 1: no threads")) + init_func = initialize_locking_1; } static void -initialize_locking_2(const char *initstr) +initialize_locking_2(void) { /** - Locking: os locking */ memset(&init_args, 0, sizeof (init_args)); init_args.flags = CKF_OS_LOCKING_OK; - init_args.pReserved = (void*)initstr; - initialize_common("locking mode 2: os locking"); + init_args.pReserved = (void*)init_string; + if(initialize_common("locking mode 2: os locking")) + init_func = initialize_locking_2; } static void -initialize_locking_3(const char *initstr) +initialize_locking_3(void) { /** - Locking: app locking */ memset(&init_args, 0, sizeof (init_args)); @@ -229,12 +231,13 @@ initialize_locking_3(const char *initstr) init_args.DestroyMutex = destroy_mutex; init_args.LockMutex = lock_mutex; init_args.UnlockMutex = unlock_mutex; - init_args.pReserved = (void*)initstr; - initialize_common("locking mode 3: app locking"); + init_args.pReserved = (void*)init_string; + if(initialize_common("locking mode 3: app locking")) + init_func = initialize_locking_3; } static void -initialize_locking_4(const char *initstr) +initialize_locking_4(void) { /** - Locking: either locking */ memset(&init_args, 0, sizeof (init_args)); @@ -243,12 +246,13 @@ initialize_locking_4(const char *initstr) init_args.DestroyMutex = destroy_mutex; init_args.LockMutex = lock_mutex; init_args.UnlockMutex = unlock_mutex; - init_args.pReserved = (void*)initstr; - initialize_common("locking mode 4: either locking"); + init_args.pReserved = (void*)init_string; + if(initialize_common("locking mode 4: either locking")) + init_func = initialize_locking_4; } void -p11t_module_initialize(const char *initstr) +p11t_module_initialize(void) { CK_INFO info; CK_RV rv; @@ -257,24 +261,30 @@ p11t_module_initialize(const char *initstr) /** - Calls without initializing */ rv = (p11t_module_funcs->C_GetInfo)(&info); - p11t_check_returns("shouldn't run without initialize: %s", rv, CKR_CRYPTOKI_NOT_INITIALIZED); + p11t_check_returns("C_GetInfo: shouldn't run without initialize", rv, CKR_CRYPTOKI_NOT_INITIALIZED); /** - NULL argument */ rv = (p11t_module_funcs->C_Initialize) (NULL); p11t_check_returns("should succeed with null argument", rv, CKR_OK); + is_initialized = 1; p11t_module_finalize(); /** - Multiple initialize with C_Finalize between */ - initialize_locking_1(initstr); + initialize_locking_1(); + p11t_module_finalize(); + initialize_locking_2(); p11t_module_finalize(); - initialize_locking_2(initstr); + initialize_locking_3(); p11t_module_finalize(); - initialize_locking_3(initstr); + initialize_locking_4(); p11t_module_finalize(); - initialize_locking_4(initstr); + /* Actually initialize with whatever succeeded last */ + if(!init_func) + p11t_msg_fatal("no initialize succeded cannot continue"); + (init_func)(); if(!is_initialized) - p11t_msg_fatal("liberal locking strategy failed, can't continue"); + p11t_msg_fatal("couldn't initialize pkcs11 module"); /** - Double initialize in a row */ rv = (p11t_module_funcs->C_Initialize) (&init_args); @@ -296,6 +306,10 @@ p11t_module_finalize(void) /** C_Finalize */ if(is_initialized) { + /** - With invalid argument */ + rv = p11t_module_funcs->C_Finalize(&rv); + p11t_check_returns("C_Finalize bad argument", rv, CKR_ARGUMENTS_BAD); + /** - Normal call */ assert(p11t_module_funcs); rv = p11t_module_funcs->C_Finalize(NULL); @@ -305,7 +319,7 @@ p11t_module_finalize(void) /** - Double finalize in a row */ rv = p11t_module_funcs->C_Finalize(NULL); - p11t_check_returns("C_Finalize", rv, CKR_CRYPTOKI_NOT_INITIALIZED); + p11t_check_returns("C_Finalize not initialized", rv, CKR_CRYPTOKI_NOT_INITIALIZED); } void @@ -315,3 +329,10 @@ p11t_module_unload(void) dlclose(module); module = NULL; } + +void +p11t_module_config(const char *name, const char *value) +{ + if(strcmp(name, "init-string") == 0) + init_string = value; +} diff --git a/src/msg.c b/src/msg.c index 600f217..ef218bf 100644 --- a/src/msg.c +++ b/src/msg.c @@ -113,12 +113,12 @@ p11t_msg_va(const char *message, va_list va) int len; if(the_prefix) - fprintf(stderr, "%s: ", the_prefix); - vfprintf(stderr, message, va); + fprintf(stdout, "%s: ", the_prefix); + vfprintf(stdout, message, va); len = strlen(message); if(len && message[len - 1] != '\n') - fputc('\n', stderr); - fflush(stderr); + fputc('\n', stdout); + fflush(stdout); } void @@ -140,6 +140,16 @@ p11t_msg_fatal(const char *message, ...) exit(1); } +void +p11t_msg_exit(int code, const char *message, ...) +{ + va_list va; + va_start(va, message); + p11t_msg_va(message, va); + va_end(va); + exit(code); +} + void p11t_msg_prefix(const char *prefix) { diff --git a/src/p11-tests.c b/src/p11-tests.c index a77ccea..65414dd 100644 --- a/src/p11-tests.c +++ b/src/p11-tests.c @@ -9,19 +9,23 @@ static void usage() { - fprintf(stderr, "usage: p11-tests module [init_string]\n"); + fprintf(stderr, "usage: p11-tests [-f config] module\n"); exit(2); } int main(int argc, char* argv[]) { + const char *config = NULL; int ch; - while((ch = getopt(argc, argv, "")) != -1) + while((ch = getopt(argc, argv, "f")) != -1) { switch(ch) { + case 'f': + config = optarg; + break; case '?': default: usage(); @@ -32,12 +36,15 @@ main(int argc, char* argv[]) argc -= optind; argv += optind; - if(argc < 1 || argc > 2) + if(argc != 1) usage(); + if(config) + p11t_config_parse(config); + /* Basic module tests */ p11t_module_load(argv[0]); - p11t_module_initialize(argc == 2 ? argv[1] : NULL); + p11t_module_initialize(); p11t_slot_tests(); p11t_session_tests(); @@ -46,5 +53,7 @@ main(int argc, char* argv[]) p11t_module_finalize(); p11t_module_unload(); + p11t_config_cleanup(); + return 0; } diff --git a/src/p11-tests.h b/src/p11-tests.h index 21b6064..6256bd5 100644 --- a/src/p11-tests.h +++ b/src/p11-tests.h @@ -7,7 +7,7 @@ #include #define CK_INVALID ((CK_ULONG)-1) -\ + /* ------------------------------------------------------------------- * msg.c */ @@ -17,6 +17,7 @@ const char* p11t_msg_rv(CK_RV rv); void p11t_msg_va(const char *message, va_list va); void p11t_msg_print(const char *message, ...); void p11t_msg_fatal(const char *message, ...); +void p11t_msg_exit(int code, const char *message, ...); void p11t_msg_prefix(const char *prefix); #define p11t_msg_here() \ @@ -41,22 +42,33 @@ int p11t_check_flag(const char *message, CK_ULONG flags, CK_ULONG flag); int p11t_check_nflag(const char *message, CK_ULONG flags, CK_ULONG nflag); +/* ------------------------------------------------------------------- + * config.c + */ + +void p11t_config_parse(const char* filename); +void p11t_config_cleanup(void); + /* ------------------------------------------------------------------- * module.c */ extern CK_FUNCTION_LIST_PTR p11t_module_funcs; +void p11t_module_config(const char *name, const char *value); + void p11t_module_load(const char *filename); void p11t_module_unload(void); -void p11t_module_initialize(const char *initstr); +void p11t_module_initialize(void); void p11t_module_finalize(void); /* ------------------------------------------------------------------- * session.c */ +void p11t_session_config(const char *name, const char *value); + void p11t_session_tests(void); /* ------------------------------------------------------------------- diff --git a/src/session.c b/src/session.c index 414a50e..a11fb50 100644 --- a/src/session.c +++ b/src/session.c @@ -3,6 +3,10 @@ #include "p11-tests.h" +#include + +static const char *login_pin = NULL; + void session_info(CK_SESSION_HANDLE session, CK_SLOT_ID slot, CK_FLAGS flags, CK_STATE state) { @@ -51,11 +55,11 @@ session_main(CK_SLOT_ID slot) /** C_OpenSession */ /** - Invalid slot */ - rv = (p11t_module_funcs->C_OpenSession)((CK_SLOT_ID)-5, 0, NULL, NULL, &session_ro); + rv = (p11t_module_funcs->C_OpenSession)((CK_SLOT_ID)-5, CKF_SERIAL_SESSION, NULL, NULL, &session_ro); p11t_check_returns("C_OpenSession with invalid slot", rv, CKR_SLOT_ID_INVALID); /** - Null arguments */ - rv = (p11t_module_funcs->C_OpenSession)(slot, 0, NULL, NULL, NULL); + rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, NULL); p11t_check_returns("C_OpenSession with invalid slot", rv, CKR_ARGUMENTS_BAD); /** - No flags */ @@ -163,3 +167,10 @@ p11t_session_tests() session_main(slot); } } + +void +p11t_session_config(const char *name, const char *value) +{ + if(strcmp(name, "login-pin") == 0) + login_pin = value; +} -- cgit v1.2.3