diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 3c5cfbe7..8c042078 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1229,8 +1229,6 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo #ifdef _WIN32 char temp_path[PATH_MAX]; int temp_len; - long rc; - HKEY hKey; const char path_delim = '\\'; #else const char path_delim = '/'; @@ -1243,25 +1241,12 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo return sc_card_sm_unload(card); #ifdef _WIN32 - if (!module_path) { - rc = RegOpenKeyExA( HKEY_CURRENT_USER, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey ); - if( rc == ERROR_SUCCESS ) { - temp_len = PATH_MAX; - rc = RegQueryValueExA( hKey, "SmDir", NULL, NULL, (LPBYTE) temp_path, &temp_len); - if( (rc == ERROR_SUCCESS) && (temp_len < PATH_MAX) ) - module_path = temp_path; - RegCloseKey( hKey ); - } - } - if (!module_path) { - rc = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey ); - if( rc == ERROR_SUCCESS ) { - temp_len = PATH_MAX; - rc = RegQueryValueExA( hKey, "SmDir", NULL, NULL, (LPBYTE) temp_path, &temp_len); - if(rc == ERROR_SUCCESS && temp_len < PATH_MAX) - module_path = temp_path; - RegCloseKey( hKey ); - } + if (!module_path) { + temp_len = PATH_MAX; + rv = sc_ctx_win32_get_config_value(NULL, "SmDir", "Software\\OpenSC Project\\OpenSC", + temp_path, &temp_len); + if (rv == SC_SUCCESS) + module_path = temp_path; } #endif sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "SM module '%s' located in '%s'", in_module, module_path); diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 7045aa1a..03c92c75 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -129,6 +129,72 @@ struct _sc_ctx_options { }; +int +sc_ctx_win32_get_config_value(char *name_env, char *name_reg, char *name_key, + char *out, size_t *out_len) +{ +#ifdef _WIN32 + char temp[PATH_MAX + 1]; + char *value = NULL; + int temp_len = PATH_MAX; + int rv = SC_ERROR_INTERNAL; + long rc; + HKEY hKey; + + if (!out || !out_len) + return SC_ERROR_INVALID_ARGUMENTS; + + if (name_env) { + value = getenv(name_env); + if (value) + goto done; + } + + if (!name_reg) + return SC_ERROR_INVALID_ARGUMENTS; + + if (!name_key) + name_key = "Software\\OpenSC Project\\OpenSC"; + + rc = RegOpenKeyExA(HKEY_CURRENT_USER, name_key, 0, KEY_QUERY_VALUE, &hKey); + if (rc == ERROR_SUCCESS) { + temp_len = PATH_MAX; + rc = RegQueryValueEx( hKey, name_reg, NULL, NULL, (LPBYTE) temp, &temp_len); + if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX)) + value = temp; + RegCloseKey(hKey); + } + + if (!value) { + rc = RegOpenKeyExA( HKEY_LOCAL_MACHINE, name_key, 0, KEY_QUERY_VALUE, &hKey ); + if (rc == ERROR_SUCCESS) { + temp_len = PATH_MAX; + rc = RegQueryValueEx( hKey, name_reg, NULL, NULL, (LPBYTE) temp, &temp_len); + if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX)) + value = temp; + RegCloseKey(hKey); + } + } + +done: + if (value) { + if (strlen(value) >= *out_len) + return SC_ERROR_BUFFER_TOO_SMALL; + strcpy(out, value); + *out_len = strlen(out); + return SC_SUCCESS; + } + + memset(out, 0, *out_len); + *out_len = 0; + + return SC_ERROR_OBJECT_NOT_FOUND; +#else + return SC_ERROR_NOT_SUPPORTED; +#endif +} + + /* Simclist helper to locate readers by name */ static int reader_list_seeker(const void *el, const void *key) { const struct sc_reader *reader = (struct sc_reader *)el; @@ -325,8 +391,8 @@ static void load_reader_driver_options(sc_context_t *ctx) */ static const char *find_library(sc_context_t *ctx, const char *name) { - int i, log_warning; - const char *libname = NULL; + int i, log_warning; + const char *libname = NULL; scconf_block **blocks, *blk; for (i = 0; ctx->conf_blocks[i]; i++) { @@ -403,7 +469,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, const char *name } static int load_card_driver_options(sc_context_t *ctx, - struct sc_card_driver *driver) + struct sc_card_driver *driver) { scconf_block **blocks, *blk; int i; @@ -566,8 +632,6 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) #ifdef _WIN32 char temp_path[PATH_MAX]; DWORD temp_len; - long rc; - HKEY hKey; #endif /* Takes effect even when no config around */ @@ -577,34 +641,14 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) memset(ctx->conf_blocks, 0, sizeof(ctx->conf_blocks)); #ifdef _WIN32 - conf_path = getenv("OPENSC_CONF"); - if (!conf_path) { - rc = RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey); - if (rc == ERROR_SUCCESS) { - temp_len = PATH_MAX; - rc = RegQueryValueEx( hKey, "ConfigFile", NULL, NULL, (LPBYTE) temp_path, &temp_len); - if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX)) - conf_path = temp_path; - RegCloseKey(hKey); - } - } - - if (!conf_path) { - rc = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey ); - if (rc == ERROR_SUCCESS) { - temp_len = PATH_MAX; - rc = RegQueryValueEx( hKey, "ConfigFile", NULL, NULL, (LPBYTE) temp_path, &temp_len); - if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX)) - conf_path = temp_path; - RegCloseKey(hKey); - } - } - - if (!conf_path) { + temp_len = PATH_MAX; + r = sc_ctx_win32_get_config_value("OPENSC_CONF", "ConfigFile", "Software\\OpenSC Project\\OpenSC", + temp_path, &temp_len); + if (r) { sc_log(ctx, "process_config_file doesn't find opensc config file. Please set the registry key."); return; } - + conf_path = temp_path; #else conf_path = getenv("OPENSC_CONF"); if (!conf_path) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 248df73b..c6a3c743 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -82,6 +82,7 @@ sc_ctx_get_reader_by_name sc_ctx_get_reader_count sc_ctx_log_to_file sc_ctx_use_reader +sc_ctx_win32_get_config_value _sc_delete_reader sc_decipher sc_delete_file diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 898797b4..728e8e4e 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -776,6 +776,16 @@ int sc_release_context(sc_context_t *ctx); */ int sc_ctx_detect_readers(sc_context_t *ctx); +/** + * In windows: get configuration option from environment or from registers. + * @param env name of environment variable + * @param reg name of register value + * @param key path of register key + * @return SC_SUCCESS on success and an error code otherwise. + */ +int sc_ctx_win32_get_config_value(char *env, char *reg, char *key, char *out, + size_t *out_size); + /** * Returns a pointer to the specified sc_reader_t object * @param ctx OpenSC context diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 413e8cfc..60995e58 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -327,7 +327,7 @@ sc_profile_load(struct sc_profile *profile, const char *filename) scconf_context *conf; const char *profile_dir = NULL; char path[PATH_MAX]; - int res = 0, i; + int res = 0, i; #ifdef _WIN32 char temp_path[PATH_MAX]; DWORD temp_len; @@ -341,26 +341,15 @@ sc_profile_load(struct sc_profile *profile, const char *filename) if (profile_dir) break; } + if (!profile_dir) { #ifdef _WIN32 - rc = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey); - if (rc == ERROR_SUCCESS) { - temp_len = PATH_MAX; - rc = RegQueryValueEx(hKey, "ProfileDir", NULL, NULL, (LPBYTE) temp_path, &temp_len); - if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX)) - profile_dir = temp_path; - RegCloseKey(hKey); - } - if (!profile_dir) { - rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey); - if (rc == ERROR_SUCCESS) { - temp_len = PATH_MAX; - rc = RegQueryValueEx(hKey, "ProfileDir", NULL, NULL, (LPBYTE) temp_path, &temp_len); - if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX)) - profile_dir = temp_path; - RegCloseKey(hKey); - } - } + temp_len = PATH_MAX; + res = sc_ctx_win32_get_config_value(NULL, "ProfileDir", "Software\\OpenSC Project\\OpenSC", + temp_path, &temp_len); + if (res) + LOG_FUNC_RETURN(ctx, res); + profile_dir = temp_path; #else profile_dir = SC_PKCS15_PROFILE_DIRECTORY; #endif