From b113b9000003b144777287123494745b4b909661 Mon Sep 17 00:00:00 2001 From: aj Date: Thu, 4 Feb 2010 06:19:52 +0000 Subject: [PATCH] remove ui code from library. git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3992 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/Makefile.am | 4 +- src/libopensc/ctx.c | 4 - src/libopensc/internal.h | 1 - src/libopensc/libopensc.exports | 5 - src/libopensc/log.c | 65 ++++- src/libopensc/ui.c | 429 -------------------------------- src/tools/Makefile.am | 2 +- src/tools/pkcs15-init.c | 2 +- src/tools/ui.c | 121 +++++++++ src/{libopensc => tools}/ui.h | 32 --- 10 files changed, 179 insertions(+), 486 deletions(-) delete mode 100644 src/libopensc/ui.c create mode 100644 src/tools/ui.c rename src/{libopensc => tools}/ui.h (71%) diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 7da60c66..be32adb9 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -8,7 +8,7 @@ bin_SCRIPTS = opensc-config lib_LTLIBRARIES = libopensc.la openscinclude_HEADERS = \ opensc.h pkcs15.h \ - cardctl.h asn1.h log.h ui.h \ + cardctl.h asn1.h log.h \ errors.h types.h compression.h noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem.h \ internal-winscard.h p15card-helper.h @@ -21,7 +21,7 @@ AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_OPENCT_CFLAGS) \ INCLUDES = -I$(top_builddir)/src/include -I$(top_srcdir)/src/common libopensc_la_SOURCES = \ - sc.c ctx.c ui.c log.c errors.c \ + sc.c ctx.c log.c errors.c \ asn1.c base64.c sec.c card.c iso7816.c dir.c padding.c apdu.c \ \ pkcs15.c pkcs15-cert.c pkcs15-data.c pkcs15-pin.c \ diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 2e6ed21a..957ecd4a 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -247,10 +247,6 @@ static int load_parameters(sc_context_t *ctx, scconf_block *block, list = list->next; } - val = scconf_get_str(block, "preferred_language", "en"); - if (val) - sc_ui_set_language(ctx, val); - return err; } diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index b861a451..ce78056f 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -33,7 +33,6 @@ extern "C" { #include "opensc.h" #include "simclist.h" #include "log.h" -#include "ui.h" #include "cards.h" #include #ifdef _WIN32 diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index ebb575de..90880845 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -227,11 +227,6 @@ sc_set_card_driver sc_set_security_env sc_strerror sc_transmit_apdu -sc_ui_display_debug -sc_ui_display_error -sc_ui_get_pin -sc_ui_get_pin_pair -sc_ui_set_language sc_unlock sc_update_binary sc_update_dir diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 0cf5852b..cfbbf039 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -35,6 +35,7 @@ #ifdef HAVE_IO_H #include #endif +#include /* Although not used, we need this for consistent exports */ void _sc_debug(sc_context_t *ctx, const char *format, ...) @@ -55,9 +56,39 @@ void sc_do_log(sc_context_t *ctx, int type, const char *file, int line, const ch va_end(ap); } +/* + * Default debug/error message output + */ +static int +use_color(sc_context_t *ctx, FILE * outf) +{ + static const char *terms[] = { "linux", "xterm", "Eterm", "rxvt", "rxvt-unicode" }; + static char *term = NULL; + int term_count = sizeof(terms) / sizeof(terms[0]); + int do_color, i; + + if (!isatty(fileno(outf))) + return 0; + if (term == NULL) { + term = getenv("TERM"); + if (term == NULL) + return 0; + } + + do_color = 0; + for (i = 0; i < term_count; i++) { + if (strcmp(terms[i], term) == 0) { + do_color = 1; + break; + } + } + + return do_color; +} + + void sc_do_log_va(sc_context_t *ctx, int type, const char *file, int line, const char *func, const char *format, va_list args) { - int (*display_fn)(sc_context_t *, const char *); char buf[1836], *p; int r; size_t left; @@ -68,19 +99,17 @@ void sc_do_log_va(sc_context_t *ctx, int type, const char *file, int line, const struct timeval tv; char time_string[40]; #endif + const char *color_pfx = "", *color_sfx = ""; + FILE *outf = NULL; + int n; + assert(ctx != NULL); - switch (type) { - case SC_LOG_TYPE_DEBUG: - if (ctx->debug == 0) - return; - display_fn = &sc_ui_display_debug; - break; - - default: + if (type != SC_LOG_TYPE_DEBUG) + return; + if (ctx->debug == 0) return; - } p = buf; left = sizeof(buf); @@ -117,7 +146,21 @@ void sc_do_log_va(sc_context_t *ctx, int type, const char *file, int line, const p += r; left -= r; - display_fn(ctx, buf); + outf = ctx->debug_file; + if (outf == NULL) + return; + + if (use_color(ctx, outf)) { + color_sfx = "\33[0m"; + color_pfx = "\33[00;32m"; + } + + fprintf(outf, "%s%s%s", color_pfx, buf, color_sfx); + n = strlen(buf); + if (n == 0 || buf[n-1] != '\n') + fprintf(outf, "\n"); + fflush(outf); + return; } void sc_hex_dump(sc_context_t *ctx, const u8 * in, size_t count, char *buf, size_t len) diff --git a/src/libopensc/ui.c b/src/libopensc/ui.c deleted file mode 100644 index e743b8a4..00000000 --- a/src/libopensc/ui.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * User interface layer. This library adds an abstraction layer to - * user interaction, allowing to configure at run time with ui - * to use (tty, qt, gnome, win32, ...) - * - * Dynamically loads user interface libraries for different platforms, - * if configured. Otherwise, uses default functions that communicate - * with the user through stdin/stdout. - * - * Copyright (C) 2003 Olaf Kirch - */ - -#include "internal.h" -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_LOCALE_H -#include -#endif -#include -#include - -/* - * We keep a global shared library handle here. - * This is ugly; we should somehow tie this to the sc_context. - */ -static void * sc_ui_lib_handle = NULL; -static int sc_ui_lib_loaded = 0; - -typedef int sc_ui_get_pin_fn_t(sc_ui_hints_t *, char **); -typedef int sc_ui_get_pin_pair_fn_t(sc_ui_hints_t *, - char **, char **); -typedef int sc_ui_display_fn_t(sc_context_t *, const char *); - -static int sc_ui_get_func(sc_context_t *, const char *, void **); -static int sc_ui_get_pin_default(sc_ui_hints_t *, char **); -static int sc_ui_get_pin_pair_default(sc_ui_hints_t *, - char **, char **); -static int sc_ui_display_error_default(sc_context_t *, const char *); -static int sc_ui_display_debug_default(sc_context_t *, const char *); - -static int __sc_ui_read_pin(sc_context_t *, const char *, - const char *label, int flags, - sc_pkcs15_pin_info_t *pin_info, - char **out); - -/* - * Set the language - */ -int -sc_ui_set_language(sc_context_t *ctx, const char *lang) -{ - if (ctx->preferred_language) - free(ctx->preferred_language); - ctx->preferred_language = NULL; - if (lang) - ctx->preferred_language = strdup(lang); - return 0; -} - -/* - * Retrieve a PIN from the user. - */ -int -sc_ui_get_pin(sc_ui_hints_t *hints, char **out) -{ - static sc_ui_get_pin_fn_t *get_pin_fn, **t_fn = &get_pin_fn; - int r; - - if (!get_pin_fn) { - void *addr; - - r = sc_ui_get_func(hints->card->ctx, - "sc_ui_get_pin_handler", - &addr); - if (r < 0) - return r; - *(void **)(t_fn) = addr; - if (get_pin_fn == NULL) - get_pin_fn = sc_ui_get_pin_default; - } - - return get_pin_fn(hints, out); -} - -int -sc_ui_get_pin_pair(sc_ui_hints_t *hints, char **old_out, char **new_out) -{ - static sc_ui_get_pin_pair_fn_t *get_pin_pair_fn, **t_fn = &get_pin_pair_fn; - int r; - - if (!get_pin_pair_fn) { - void *addr; - - r = sc_ui_get_func(hints->card->ctx, - "sc_ui_get_pin_pair_handler", - &addr); - if (r < 0) - return r; - *(void **)(t_fn) = addr; - if (get_pin_pair_fn == NULL) - get_pin_pair_fn = sc_ui_get_pin_pair_default; - } - - return get_pin_pair_fn(hints, old_out, new_out); -} - -int -sc_ui_display_error(sc_context_t *ctx, const char *msg) -{ - static sc_ui_display_fn_t *display_fn, **t_fn = &display_fn; - int r; - - if (!display_fn) { - void *addr; - - r = sc_ui_get_func(ctx, - "sc_ui_display_error_handler", - &addr); - if (r < 0) - return r; - *(void **)(t_fn) = addr; - if (display_fn == NULL) - display_fn = sc_ui_display_error_default; - } - - return display_fn(ctx, msg); -} - -int -sc_ui_display_debug(sc_context_t *ctx, const char *msg) -{ - static sc_ui_display_fn_t *display_fn, **t_fn = &display_fn; - int r; - - if (!display_fn) { - void *addr; - - r = sc_ui_get_func(ctx, - "sc_ui_display_debug_handler", - &addr); - if (r < 0) - return r; - *(void **)t_fn = addr; - if (display_fn == NULL) - display_fn = sc_ui_display_debug_default; - } - - return display_fn(ctx, msg); -} - -/* - * Get the named functions from the user interface - * library. If no library is configured, or if the - * libray doesn't define the named symbol, fall back - * to the default function - */ -static int sc_ui_get_func(sc_context_t *ctx, const char *name, void **ret) -{ - *ret = NULL; - if (!sc_ui_lib_handle && !sc_ui_lib_loaded) { - const char *lib_name = NULL; - scconf_block *blk; - int i; - - /* Prevent recursion */ - sc_ui_lib_loaded = 1; - - for (i = 0; (blk = ctx->conf_blocks[i]); i++) { - lib_name = scconf_get_str(blk, - "user_interface", - NULL); - if (lib_name) - break; - } - - if (!lib_name) - return 0; - - sc_ui_lib_handle = lt_dlopen(lib_name); - if (!sc_ui_lib_handle) { - sc_debug(ctx, - "Unable to open user interface library '%s': %s\n", - lib_name, lt_dlerror()); - return SC_ERROR_INTERNAL; - } - } - - if (sc_ui_lib_handle == NULL) - return 0; - - *ret = lt_dlsym(sc_ui_lib_handle, name); - - return *ret ? SC_SUCCESS : SC_ERROR_UNKNOWN; -} - -/* - * Default ui functions - */ -static int sc_ui_get_pin_default(sc_ui_hints_t *hints, char **out) -{ - sc_context_t *ctx = hints->card->ctx; - sc_pkcs15_pin_info_t *pin_info; - const char *label, *language = "en"; - int flags = hints->flags; - - pin_info = hints->info.pin; - if (!(label = hints->obj_label)) { - if (pin_info == NULL) { - label = "PIN"; - } else if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { - label = "Security Officer PIN"; - } else { - label = "User PIN"; - } - } - - if (hints->p15card) { - /* TBD: get preferredCard from TokenInfo */ - } - -#if defined(HAVE_SETLOCALE) && !defined(_WIN32) - setlocale(LC_MESSAGES, language); -#else - (void) language; -#endif - - return __sc_ui_read_pin(ctx, hints->prompt, label, - flags, pin_info, out); -} - -static int sc_ui_get_pin_pair_default(sc_ui_hints_t *hints, char **old_out, - char **new_out) -{ - sc_context_t *ctx = hints->card->ctx; - sc_pkcs15_pin_info_t *pin_info; - const char *label, *language = "en"; - int r, flags = hints->flags, old_flags; - - if (hints->prompt) - printf("%s\n", hints->prompt); - - pin_info = hints->info.pin; - if (!(label = hints->obj_label)) { - if (pin_info == NULL) { - label = "PIN"; - } else if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { - label = "Security Officer PIN"; - } else { - label = "User PIN"; - } - } - - if (hints->p15card) { - /* TBD: get preferredCard from TokenInfo */ - } - -#if defined(HAVE_SETLOCALE) && !defined(_WIN32) - setlocale(LC_MESSAGES, language); -#else - (void) language; -#endif - - old_flags = flags; - if (hints->usage == SC_UI_USAGE_UNBLOCK_PIN - || hints->usage == SC_UI_USAGE_CHANGE_PIN) { - old_flags &= ~(SC_UI_PIN_RETYPE|SC_UI_PIN_CHECK_LENGTH); - } - - r = __sc_ui_read_pin(ctx, NULL, label, old_flags, NULL, old_out); - if (r >= 0) - r = __sc_ui_read_pin(ctx, NULL, label, flags, NULL, new_out); - - return r; -} - -static int __sc_ui_read_pin(sc_context_t *ctx, const char *prompt, - const char *label, int flags, - sc_pkcs15_pin_info_t *pin_info, - char **out) -{ - if (prompt) { - printf("%s", prompt); - if (flags & SC_UI_PIN_OPTIONAL) - printf(" (Optional - press return for no PIN)"); - printf(".\n"); - } - - *out = NULL; - while (1) { - char buffer[64], *pin; - size_t len; - - snprintf(buffer, sizeof(buffer), - "Please enter %s: ", label); - - if ((pin = getpass(buffer)) == NULL) - return SC_ERROR_INTERNAL; - - len = strlen(pin); - if (len == 0 && (flags & SC_UI_PIN_OPTIONAL)) - return 0; - - if (pin_info && (flags & SC_UI_PIN_CHECK_LENGTH)) { - if (len < pin_info->min_length) { - fprintf(stderr, - "PIN too short (min %lu characters)\n", - (unsigned long) pin_info->min_length); - continue; - } - if (pin_info->max_length - && len > pin_info->max_length) { - fprintf(stderr, - "PIN too long (max %lu characters)\n", - (unsigned long) pin_info->max_length); - continue; - } - } - - *out = strdup(pin); - sc_mem_clear(pin, len); - - if (!(flags & SC_UI_PIN_RETYPE)) - break; - - pin = getpass("Please type again to verify: "); - if (!strcmp(*out, pin)) { - sc_mem_clear(pin, len); - break; - } - - free(*out); - *out = NULL; - - if (!(flags & SC_UI_PIN_MISMATCH_RETRY)) { - fprintf(stderr, "PINs do not match.\n"); - return SC_ERROR_KEYPAD_PIN_MISMATCH; - } - - fprintf(stderr, - "Sorry, the two pins did not match. " - "Please try again.\n"); - sc_mem_clear(pin, strlen(pin)); - - /* Currently, there's no way out of this dialog. - * We should allow the user to bail out after n - * attempts. */ - } - - return 0; -} - -/* - * Default debug/error message output - */ -static int -use_color(sc_context_t *ctx, FILE * outf) -{ - static const char *terms[] = { "linux", "xterm", "Eterm", "rxvt", "rxvt-unicode" }; - static char *term = NULL; - int term_count = sizeof(terms) / sizeof(terms[0]); - int do_color, i; - - if (!isatty(fileno(outf))) - return 0; - if (term == NULL) { - term = getenv("TERM"); - if (term == NULL) - return 0; - } - - do_color = 0; - for (i = 0; i < term_count; i++) { - if (strcmp(terms[i], term) == 0) { - do_color = 1; - break; - } - } - - return do_color; -} - -static int -sc_ui_display_msg(sc_context_t *ctx, int type, const char *msg) -{ - const char *color_pfx = "", *color_sfx = ""; - FILE *outf = NULL; - int n; - - switch (type) { - case SC_LOG_TYPE_DEBUG: - outf = ctx->debug_file; - break; - } - if (outf == NULL) - return 0; - - if (use_color(ctx, outf)) { - color_sfx = "\33[0m"; - switch (type) { - case SC_LOG_TYPE_ERROR: - color_pfx = "\33[01;31m"; - break; - case SC_LOG_TYPE_DEBUG: - color_pfx = "\33[00;32m"; - break; - } - } - - fprintf(outf, "%s%s%s", color_pfx, msg, color_sfx); - n = strlen(msg); - if (n == 0 || msg[n-1] != '\n') - fprintf(outf, "\n"); - fflush(outf); - return 0; -} - -static int sc_ui_display_error_default(sc_context_t *ctx, const char *msg) -{ - return sc_ui_display_msg(ctx, SC_LOG_TYPE_ERROR, msg); -} - -static int sc_ui_display_debug_default(sc_context_t *ctx, const char *msg) -{ - return sc_ui_display_msg(ctx, SC_LOG_TYPE_DEBUG, msg); -} diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 001287f8..87939fda 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -33,7 +33,7 @@ pkcs15_crypt_SOURCES = pkcs15-crypt.c util.c pkcs15_crypt_LDADD = $(OPTIONAL_OPENSSL_LIBS) cryptoflex_tool_SOURCES = cryptoflex-tool.c util.c cryptoflex_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) -pkcs15_init_SOURCES = pkcs15-init.c util.c +pkcs15_init_SOURCES = pkcs15-init.c util.c ui.c ui.h pkcs15_init_LDADD = $(OPTIONAL_OPENSSL_LIBS) cardos_tool_SOURCES = cardos-tool.c util.c cardos_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 0220d663..c0c68a07 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -63,10 +63,10 @@ #include #include #include -#include #include #include #include "util.h" +#include "ui.h" #include diff --git a/src/tools/ui.c b/src/tools/ui.c new file mode 100644 index 00000000..0c8215bc --- /dev/null +++ b/src/tools/ui.c @@ -0,0 +1,121 @@ +/* + * User interface layer. This library adds an abstraction layer to + * user interaction, allowing to configure at run time with ui + * to use (tty, qt, gnome, win32, ...) + * + * Dynamically loads user interface libraries for different platforms, + * if configured. Otherwise, uses default functions that communicate + * with the user through stdin/stdout. + * + * Copyright (C) 2003 Olaf Kirch + */ + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_LOCALE_H +#include +#endif +#include +#include +#include +#include "ui.h" + +/* + * Retrieve a PIN from the user. + */ +int sc_ui_get_pin(sc_ui_hints_t *hints, char **out) +{ + sc_context_t *ctx = hints->card->ctx; + sc_pkcs15_pin_info_t *pin_info; + const char *label; + int flags = hints->flags; + + pin_info = hints->info.pin; + if (!(label = hints->obj_label)) { + if (pin_info == NULL) { + label = "PIN"; + } else if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { + label = "Security Officer PIN"; + } else { + label = "User PIN"; + } + } + + if (hints->p15card) { + /* TBD: get preferredCard from TokenInfo */ + } + + if (hints->prompt) { + printf("%s", hints->prompt); + if (flags & SC_UI_PIN_OPTIONAL) + printf(" (Optional - press return for no PIN)"); + printf(".\n"); + } + + *out = NULL; + while (1) { + char buffer[64], *pin; + size_t len; + + snprintf(buffer, sizeof(buffer), + "Please enter %s: ", label); + + if ((pin = getpass(buffer)) == NULL) + return SC_ERROR_INTERNAL; + + len = strlen(pin); + if (len == 0 && (flags & SC_UI_PIN_OPTIONAL)) + return 0; + + if (pin_info && (flags & SC_UI_PIN_CHECK_LENGTH)) { + if (len < pin_info->min_length) { + fprintf(stderr, + "PIN too short (min %lu characters)\n", + (unsigned long) pin_info->min_length); + continue; + } + if (pin_info->max_length + && len > pin_info->max_length) { + fprintf(stderr, + "PIN too long (max %lu characters)\n", + (unsigned long) pin_info->max_length); + continue; + } + } + + *out = strdup(pin); + sc_mem_clear(pin, len); + + if (!(flags & SC_UI_PIN_RETYPE)) + break; + + pin = getpass("Please type again to verify: "); + if (!strcmp(*out, pin)) { + sc_mem_clear(pin, len); + break; + } + + free(*out); + *out = NULL; + + if (!(flags & SC_UI_PIN_MISMATCH_RETRY)) { + fprintf(stderr, "PINs do not match.\n"); + return SC_ERROR_KEYPAD_PIN_MISMATCH; + } + + fprintf(stderr, + "Sorry, the two pins did not match. " + "Please try again.\n"); + sc_mem_clear(pin, strlen(pin)); + + /* Currently, there's no way out of this dialog. + * We should allow the user to bail out after n + * attempts. */ + } + + return 0; +} diff --git a/src/libopensc/ui.h b/src/tools/ui.h similarity index 71% rename from src/libopensc/ui.h rename to src/tools/ui.h index e526b1ad..ff360657 100644 --- a/src/libopensc/ui.h +++ b/src/tools/ui.h @@ -66,11 +66,6 @@ typedef struct sc_ui_hints { } info; } sc_ui_hints_t; -/* - * Specify the dialog language, if the backend is localized. - */ -extern int sc_ui_set_language(sc_context_t *, const char *); - /* * Retrieve a PIN from the user. * @@ -80,33 +75,6 @@ extern int sc_ui_set_language(sc_context_t *, const char *); */ extern int sc_ui_get_pin(sc_ui_hints_t *hints, char **out); -/* - * PIN pair dialog. Can be used for PIN change/unblock, but - * also to enter a PIN/PUK pair. - * - * @hints dialog hints - * @old_out PIN entered by the user; must be freed. - * NULL if dialog was canceled. - * @new_out PIN entered by the user; must be freed. - * NULL if dialog was canceled. - */ -extern int sc_ui_get_pin_pair(sc_ui_hints_t *hints, - char **old_out, char **new_out); - -/* - * Other ui functions, not fully spec'ed yet - */ -extern int sc_ui_display_question(sc_context_t *ctx, - const char *name, - const char *prompt); -extern int sc_ui_display_message(sc_context_t *ctx, - const char *name, - const char *message); -extern int sc_ui_display_error(sc_context_t *ctx, - const char *msg); -extern int sc_ui_display_debug(sc_context_t *ctx, - const char *msg); - #ifdef __cplusplus } #endif