remove ui code from library.

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3992 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
aj 2010-02-04 06:19:52 +00:00
parent 314a31f867
commit b113b90000
10 changed files with 179 additions and 486 deletions

View File

@ -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 \

View File

@ -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;
}

View File

@ -33,7 +33,6 @@ extern "C" {
#include "opensc.h"
#include "simclist.h"
#include "log.h"
#include "ui.h"
#include "cards.h"
#include <assert.h>
#ifdef _WIN32

View File

@ -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

View File

@ -35,6 +35,7 @@
#ifdef HAVE_IO_H
#include <io.h>
#endif
#include <pthread.h>
/* 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)

View File

@ -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 <okir@lse.de>
*/
#include "internal.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#include <compat_getpass.h>
#include <ltdl.h>
/*
* 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);
}

View File

@ -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)

View File

@ -63,10 +63,10 @@
#include <opensc/pkcs15-init.h>
#include <opensc/keycache.h>
#include <opensc/log.h>
#include <opensc/ui.h>
#include <opensc/cards.h>
#include <compat_getpass.h>
#include "util.h"
#include "ui.h"
#include <compat_strlcpy.h>

121
src/tools/ui.c Normal file
View File

@ -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 <okir@lse.de>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#include <compat_getpass.h>
#include <ltdl.h>
#include <opensc/log.h>
#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;
}

View File

@ -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