opensc includes a flexible user interface code libopensc/ui.c and ui.h.
here is what it does and what I changed.

* in ctx.c the language is set to "en" with a call to locale().
  In my opinion this should be done - if at all - by the apps using
  opensc and interacting with the user, not by opensc directly.
* in ui.c there are several types of messages. we have only DEBUG
  left, so I removed all others and threw out the code to check for
  type.
* scconf, pkcs15init and opensc-pkcs11 do not use the ui code.
  only libopensc uses one function: to print messages. 
  and pkcs15-init uses the get_pin function.
* I think get_pin code interacting with the user should be in the
  tools/ directory, not part of a shared library or pkcs#11 module.
  so I seperated that code.
* I removed all the other unused functions.
* ui.c/h has a shared library interface via opensc.conf, so you
  can configure a plugin, it will load that plugin and use the
  functions there instead of the build-in ones. 
  noone uses that, as far as I know, thus I'm removing that indirection
  for opensc (remember: only the log code uses one function for
  printing messsages).
* for pkcs15-init I don't think such a code to use an alternate
  implementation of get_pin in needed at all, so I remove the
  indirections tool.

the result:
60 new lines of code in log.c, >400 lines in ui.c gone, ui.h gone.
new files tools/ui.c and ui.h with 80 / 120 lines.

do you think the changes are ok so far? then I will commit them.

further changes to discuss:
* most of the new code in log.c is the new use_color function.
  can we remove that one? I'm no fan of the coloring code, it
  causes more trouble than it is worth for me.
* since only pkcs15-init uses ui.c/h I would fold those files
  into pkcs15-init instead of having new files.

if noone objects I will implement these changes too.

Regards, Andreas
diff -udrNPp --exclude=.svn opensc.orig/src/libopensc/Makefile.am opensc/src/libopensc/Makefile.am
--- opensc.orig/src/libopensc/Makefile.am	2010-02-03 07:53:02.000000000 +0100
+++ opensc/src/libopensc/Makefile.am	2010-02-03 07:49:49.000000000 +0100
@@ -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) $
 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 -udrNPp --exclude=.svn opensc.orig/src/libopensc/ctx.c opensc/src/libopensc/ctx.c
--- opensc.orig/src/libopensc/ctx.c	2010-02-01 08:03:26.000000000 +0100
+++ opensc/src/libopensc/ctx.c	2010-02-03 07:31:40.000000000 +0100
@@ -247,10 +247,6 @@ static int load_parameters(sc_context_t 
 		list = list->next;
 	}
 
-	val = scconf_get_str(block, "preferred_language", "en");
-	if (val)
-		sc_ui_set_language(ctx, val);
-
 	return err;
 }
 
diff -udrNPp --exclude=.svn opensc.orig/src/libopensc/internal.h opensc/src/libopensc/internal.h
--- opensc.orig/src/libopensc/internal.h	2010-02-01 08:03:26.000000000 +0100
+++ opensc/src/libopensc/internal.h	2010-02-03 07:12:49.000000000 +0100
@@ -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
diff -udrNPp --exclude=.svn opensc.orig/src/libopensc/libopensc.exports opensc/src/libopensc/libopensc.exports
--- opensc.orig/src/libopensc/libopensc.exports	2010-02-03 07:53:02.000000000 +0100
+++ opensc/src/libopensc/libopensc.exports	2010-02-03 07:11:26.000000000 +0100
@@ -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 -udrNPp --exclude=.svn opensc.orig/src/libopensc/log.c opensc/src/libopensc/log.c
--- opensc.orig/src/libopensc/log.c	2010-02-01 08:03:26.000000000 +0100
+++ opensc/src/libopensc/log.c	2010-02-03 07:28:54.000000000 +0100
@@ -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 ty
 	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
 	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;
+	assert(ctx != NULL);
 
-	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
 	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 -udrNPp --exclude=.svn opensc.orig/src/libopensc/ui.c opensc/src/libopensc/ui.c
--- opensc.orig/src/libopensc/ui.c	2010-02-01 08:03:26.000000000 +0100
+++ opensc/src/libopensc/ui.c	1970-01-01 01:00:00.000000000 +0100
@@ -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 <[email protected]>
- */
-
-#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);
-}
diff -udrNPp --exclude=.svn opensc.orig/src/libopensc/ui.h opensc/src/libopensc/ui.h
--- opensc.orig/src/libopensc/ui.h	2006-05-15 22:57:30.000000000 +0200
+++ opensc/src/libopensc/ui.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,114 +0,0 @@
-/*
- * ui.h: User interface layer
- *
- * Copyright (C) 2003  Olaf Kirch <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _SC_UI_H
-#define _SC_UI_H
-
-#include <opensc/opensc.h>
-#include <opensc/pkcs15.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Dialog types
- */
-#define SC_UI_USAGE_OTHER		0x0000
-#define SC_UI_USAGE_NEW_PIN		0x0001
-#define SC_UI_USAGE_UNBLOCK_PIN		0x0002
-#define SC_UI_USAGE_CHANGE_PIN		0x0003
-
-/*
- * Dialog flags
- */
-#define SC_UI_PIN_RETYPE		0x0001	/* new pin, retype */
-#define SC_UI_PIN_OPTIONAL		0x0002	/* new pin optional */
-#define SC_UI_PIN_CHECK_LENGTH		0x0004	/* check pin length */
-#define SC_UI_PIN_MISMATCH_RETRY	0x0008	/* retry if new pin mismatch? */
-
-
-/* Hints passed to user interface functions
- * M marks mandatory fields,
- * O marks optional fields
- */
-typedef struct sc_ui_hints {
-	const char *		prompt;		/* M: cmdline prompt */
-	const char *		dialog_name;	/* M: dialog name */
-	unsigned int		usage;		/* M: usage hint */
-	unsigned int		flags;		/* M: flags */
-	sc_card_t *		card;		/* M: card handle */
-	struct sc_pkcs15_card *	p15card;	/* O: pkcs15 handle */
-
-	/* We may not have a pkcs15 object yet when we get
-	 * here, but we may have an idea of what it's going to
-	 * look like. */
-	const char *		obj_label;	/* O: object (PIN) label */
-	union {
-	    struct sc_pkcs15_pin_info *pin;
-	} 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.
- *
- * @hints	dialog hints
- * @out		PIN entered by the user; must be freed.
- * 		NULL if dialog was canceled.
- */
-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
-
-#endif /* _SC_UI_H */
diff -udrNPp --exclude=.svn opensc.orig/src/tools/Makefile.am opensc/src/tools/Makefile.am
--- opensc.orig/src/tools/Makefile.am	2010-02-03 07:53:01.000000000 +0100
+++ opensc/src/tools/Makefile.am	2010-02-03 07:50:04.000000000 +0100
@@ -33,7 +33,7 @@ pkcs15_crypt_SOURCES = pkcs15-crypt.c ut
 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 -udrNPp --exclude=.svn opensc.orig/src/tools/pkcs15-init.c opensc/src/tools/pkcs15-init.c
--- opensc.orig/src/tools/pkcs15-init.c	2010-02-01 08:03:21.000000000 +0100
+++ opensc/src/tools/pkcs15-init.c	2010-02-03 07:33:36.000000000 +0100
@@ -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>
 
 
diff -udrNPp --exclude=.svn opensc.orig/src/tools/ui.c opensc/src/tools/ui.c
--- opensc.orig/src/tools/ui.c	1970-01-01 01:00:00.000000000 +0100
+++ opensc/src/tools/ui.c	2010-02-03 07:48:59.000000000 +0100
@@ -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 <[email protected]>
+ */
+
+#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;
+}
diff -udrNPp --exclude=.svn opensc.orig/src/tools/ui.h opensc/src/tools/ui.h
--- opensc.orig/src/tools/ui.h	1970-01-01 01:00:00.000000000 +0100
+++ opensc/src/tools/ui.h	2010-02-03 07:41:58.000000000 +0100
@@ -0,0 +1,82 @@
+/*
+ * ui.h: User interface layer
+ *
+ * Copyright (C) 2003  Olaf Kirch <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _SC_UI_H
+#define _SC_UI_H
+
+#include <opensc/opensc.h>
+#include <opensc/pkcs15.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Dialog types
+ */
+#define SC_UI_USAGE_OTHER		0x0000
+#define SC_UI_USAGE_NEW_PIN		0x0001
+#define SC_UI_USAGE_UNBLOCK_PIN		0x0002
+#define SC_UI_USAGE_CHANGE_PIN		0x0003
+
+/*
+ * Dialog flags
+ */
+#define SC_UI_PIN_RETYPE		0x0001	/* new pin, retype */
+#define SC_UI_PIN_OPTIONAL		0x0002	/* new pin optional */
+#define SC_UI_PIN_CHECK_LENGTH		0x0004	/* check pin length */
+#define SC_UI_PIN_MISMATCH_RETRY	0x0008	/* retry if new pin mismatch? */
+
+
+/* Hints passed to user interface functions
+ * M marks mandatory fields,
+ * O marks optional fields
+ */
+typedef struct sc_ui_hints {
+	const char *		prompt;		/* M: cmdline prompt */
+	const char *		dialog_name;	/* M: dialog name */
+	unsigned int		usage;		/* M: usage hint */
+	unsigned int		flags;		/* M: flags */
+	sc_card_t *		card;		/* M: card handle */
+	struct sc_pkcs15_card *	p15card;	/* O: pkcs15 handle */
+
+	/* We may not have a pkcs15 object yet when we get
+	 * here, but we may have an idea of what it's going to
+	 * look like. */
+	const char *		obj_label;	/* O: object (PIN) label */
+	union {
+	    struct sc_pkcs15_pin_info *pin;
+	} info;
+} sc_ui_hints_t;
+
+/*
+ * Retrieve a PIN from the user.
+ *
+ * @hints	dialog hints
+ * @out		PIN entered by the user; must be freed.
+ * 		NULL if dialog was canceled.
+ */
+extern int	sc_ui_get_pin(sc_ui_hints_t *hints, char **out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SC_UI_H */
_______________________________________________
opensc-devel mailing list
[email protected]
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to