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