- Added new user interface code (not used yet)
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1553 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
f730572f34
commit
5791395e74
|
@ -13,7 +13,7 @@ bin_SCRIPTS = opensc-config
|
|||
|
||||
lib_LTLIBRARIES = libopensc.la
|
||||
libopensc_la_SOURCES = \
|
||||
sc.c ctx.c log.c errors.c portability.c module.c \
|
||||
sc.c ctx.c ui.c log.c errors.c portability.c module.c \
|
||||
asn1.c base64.c sec.c card.c iso7816.c dir.c padding.c \
|
||||
\
|
||||
pkcs15.c pkcs15-cert.c pkcs15-data.c pkcs15-pin.c \
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <opensc/opensc.h>
|
||||
#include <opensc/scdl.h>
|
||||
#include <opensc/log.h>
|
||||
#include <opensc/ui.h>
|
||||
#include "internal.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_context_t *, const char *,
|
||||
const char *,
|
||||
const sc_ui_get_pin_info_t *, char **);
|
||||
typedef int sc_ui_get_pin_pair_fn_t(sc_context_t *, const char *,
|
||||
const char *,
|
||||
const sc_ui_get_pin_info_t *, char **,
|
||||
const sc_ui_get_pin_info_t *, char **);
|
||||
|
||||
static int sc_ui_get_func(sc_context_t *, const char *, void **);
|
||||
static int sc_ui_get_pin_default(sc_context_t *, const char *,
|
||||
const char *,
|
||||
const sc_ui_get_pin_info_t *, char **);
|
||||
static int sc_ui_get_pin_pair_default(sc_context_t *, const char *,
|
||||
const char *,
|
||||
const sc_ui_get_pin_info_t *, char **,
|
||||
const sc_ui_get_pin_info_t *, char **);
|
||||
|
||||
/*
|
||||
* Retrieve a PIN from the user.
|
||||
*/
|
||||
int
|
||||
sc_ui_get_pin(sc_context_t *ctx, const char *name, const char *prompt,
|
||||
const sc_ui_get_pin_info_t *info, char **out)
|
||||
{
|
||||
static sc_ui_get_pin_fn_t *get_pin_fn;
|
||||
int r;
|
||||
|
||||
if (!get_pin_fn) {
|
||||
void *addr;
|
||||
|
||||
r = sc_ui_get_func(ctx,
|
||||
"sc_ui_get_pin_handler",
|
||||
&addr);
|
||||
if (r < 0)
|
||||
return r;
|
||||
get_pin_fn = (sc_ui_get_pin_fn_t *) addr;
|
||||
if (get_pin_fn == NULL)
|
||||
get_pin_fn = sc_ui_get_pin_default;
|
||||
}
|
||||
|
||||
return get_pin_fn(ctx, name, prompt, info, out);
|
||||
}
|
||||
|
||||
int
|
||||
sc_ui_get_pin_pair(sc_context_t *ctx, const char *name, const char *prompt,
|
||||
const sc_ui_get_pin_info_t *old_info, char **old_out,
|
||||
const sc_ui_get_pin_info_t *new_info, char **new_out)
|
||||
{
|
||||
static sc_ui_get_pin_pair_fn_t *get_pin_pair_fn;
|
||||
int r;
|
||||
|
||||
if (!get_pin_pair_fn) {
|
||||
void *addr;
|
||||
|
||||
r = sc_ui_get_func(ctx,
|
||||
"sc_ui_get_pin_pair_handler",
|
||||
&addr);
|
||||
if (r < 0)
|
||||
return r;
|
||||
get_pin_pair_fn = (sc_ui_get_pin_pair_fn_t *) addr;
|
||||
if (get_pin_pair_fn == NULL)
|
||||
get_pin_pair_fn = sc_ui_get_pin_pair_default;
|
||||
}
|
||||
|
||||
return get_pin_pair_fn(ctx, name, prompt,
|
||||
old_info, old_out,
|
||||
new_info, new_out);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
int
|
||||
sc_ui_get_func(sc_context_t *ctx, const char *name, void **ret)
|
||||
{
|
||||
int r;
|
||||
|
||||
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;
|
||||
|
||||
r = sc_module_open(ctx, &sc_ui_lib_handle, lib_name);
|
||||
if (r < 0) {
|
||||
sc_error(ctx,
|
||||
"Unable to open user interface library %s\n",
|
||||
lib_name);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return sc_module_get_address(ctx, sc_ui_lib_handle, ret, name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Default ui functions
|
||||
*/
|
||||
int
|
||||
sc_ui_get_pin_default(sc_context_t *ctx, const char *name,
|
||||
const char *prompt,
|
||||
const sc_ui_get_pin_info_t *info,
|
||||
char **out)
|
||||
{
|
||||
const char *name_hint;
|
||||
|
||||
if ((name_hint = info->name_hint) == NULL)
|
||||
name_hint = "PIN";
|
||||
|
||||
if (prompt) {
|
||||
printf("%s%s.\n", prompt,
|
||||
(info->flags & SC_UI_PIN_OPTIONAL)? "" :
|
||||
" (Optional - press return for no PIN)");
|
||||
}
|
||||
|
||||
*out = NULL;
|
||||
while (1) {
|
||||
char buffer[64], *pin;
|
||||
size_t len;
|
||||
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"Please enter %s: ", name_hint);
|
||||
|
||||
if ((pin = getpass(buffer)) == NULL)
|
||||
return SC_ERROR_INTERNAL;
|
||||
|
||||
len = strlen(pin);
|
||||
if (len == 0 && (info->flags & SC_UI_PIN_OPTIONAL))
|
||||
return SC_ERROR_KEYPAD_CANCELLED;
|
||||
|
||||
if (info->flags & SC_UI_PIN_CHECK_LENGTH) {
|
||||
if (len < info->min_len) {
|
||||
fprintf(stderr,
|
||||
"PIN too short (min %u characters)\n",
|
||||
info->min_len);
|
||||
continue;
|
||||
}
|
||||
if (len > info->max_len) {
|
||||
fprintf(stderr,
|
||||
"PIN too long (max %u characters)\n",
|
||||
info->max_len);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
*out = strdup(pin);
|
||||
memset(pin, 0, len);
|
||||
|
||||
if (!(info->flags & SC_UI_PIN_RETYPE))
|
||||
break;
|
||||
|
||||
pin = getpass("Please type again to verify: ");
|
||||
if (!strcmp(*out, pin)) {
|
||||
memset(pin, 0, len);
|
||||
break;
|
||||
}
|
||||
|
||||
free(*out);
|
||||
*out = NULL;
|
||||
|
||||
if (!(info->flags & SC_UI_PIN_MISMATCH_RETRY)) {
|
||||
fprintf(stderr, "PINs do not match.\n");
|
||||
return SC_ERROR_KEYPAD_PIN_MISMATCH;
|
||||
}
|
||||
|
||||
memset(pin, 0, strlen(pin));
|
||||
|
||||
/* Currently, there's no way out of this dialog.
|
||||
* We should allow the user to bail out after n
|
||||
* attempts. */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sc_ui_get_pin_pair_default(sc_context_t *ctx, const char *name,
|
||||
const char *prompt,
|
||||
const sc_ui_get_pin_info_t *old_info, char **old_out,
|
||||
const sc_ui_get_pin_info_t *new_info, char **new_out)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (prompt)
|
||||
printf("%s\n", prompt);
|
||||
|
||||
r = sc_ui_get_pin_default(ctx, "foo", NULL, old_info, old_out);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sc_ui_get_pin_default(ctx, "foo", NULL, new_info, new_out);
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* User interface layer.
|
||||
*
|
||||
* Copyright (C) 2003 Olaf Kirch <okir@lse.de>
|
||||
*/
|
||||
|
||||
#ifndef _SC_UI_H
|
||||
#define _SC_UI_H
|
||||
|
||||
#include <opensc/opensc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct sc_ui_get_pin_info {
|
||||
const char * name_hint; /* PIN/PUK/old PIN etc */
|
||||
int flags;
|
||||
unsigned int min_len, max_len;
|
||||
} sc_ui_get_pin_info_t;
|
||||
|
||||
#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? */
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* @name Dialog name, can be used by the dialog backend
|
||||
* to retrieve additional resources such as help
|
||||
* texts, icons etc.
|
||||
* @prompt Text prompt that is displayed if there's no
|
||||
* GUI backend configured.
|
||||
* @info Additional info on the dialog to display.
|
||||
* @out PIN entered by the user; must be freed.
|
||||
* NULL if dialog was canceled.
|
||||
*/
|
||||
extern int sc_ui_get_pin(sc_context_t *ctx,
|
||||
const char *name,
|
||||
const char *prompt,
|
||||
const sc_ui_get_pin_info_t *info,
|
||||
char **out);
|
||||
|
||||
/*
|
||||
* PIN pair dialog. Can be used for PIN change/unblock, but
|
||||
* also to enter a PIN/PUK pair.
|
||||
*
|
||||
* @name Dialog name, can be used by the dialog backend
|
||||
* to retrieve additional resources such as help
|
||||
* texts, icons etc.
|
||||
* @prompt Text prompt that is displayed if there's no
|
||||
* GUI backend configured.
|
||||
* @old_info Additional info on the dialog to display.
|
||||
* @old_out PIN entered by the user; must be freed.
|
||||
* NULL if dialog was canceled.
|
||||
* @new_info Additional info on the dialog to display.
|
||||
* @new_out PIN entered by the user; must be freed.
|
||||
* NULL if dialog was canceled.
|
||||
*/
|
||||
extern int sc_ui_get_pin_pair(sc_context_t *ctx,
|
||||
const char *name,
|
||||
const char *prompt,
|
||||
const sc_ui_get_pin_info_t *old_info,
|
||||
char **old_out,
|
||||
const sc_ui_get_pin_info_t *new_info,
|
||||
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 */
|
Loading…
Reference in New Issue