Made some PIN pads work.

Some cleanups for 64 bit CPUs.
This commit is contained in:
Werner Koch 2006-11-20 16:49:41 +00:00
parent 267d4c8fa7
commit 5885142c83
36 changed files with 502 additions and 171 deletions

View File

@ -1,3 +1,7 @@
2006-11-15 Werner Koch <wk@g10code.com>
* autogen.sh: Add convenience option --build-amd64.
2006-11-14 Werner Koch <wk@g10code.com> 2006-11-14 Werner Koch <wk@g10code.com>
* configure.ac (HAVE_ASSUAN_SET_IO_MONITOR): Test for it. * configure.ac (HAVE_ASSUAN_SET_IO_MONITOR): Test for it.

View File

@ -22,7 +22,7 @@
ACLOCAL_AMFLAGS = -I m4 -I gl/m4 ACLOCAL_AMFLAGS = -I m4 -I gl/m4
AUTOMAKE_OPTIONS = dist-bzip2 AUTOMAKE_OPTIONS = dist-bzip2
DISTCHECK_CONFIGURE_FLAGS = --enable-gpg DISTCHECK_CONFIGURE_FLAGS = --enable-symcryptrun
EXTRA_DIST = scripts/config.rpath autogen.sh README.SVN EXTRA_DIST = scripts/config.rpath autogen.sh README.SVN
DISTCLEANFILES = g10defs.h DISTCLEANFILES = g10defs.h

5
NEWS
View File

@ -1,6 +1,11 @@
Noteworthy changes in version 2.0.1 Noteworthy changes in version 2.0.1
------------------------------------------------- -------------------------------------------------
* Experimental support for the PIN pads of the SPR 532 and the Kaan
Advanced card readers. Add "disable-keypad" scdaemon.conf if you
don't want it. Does currently only work for the OpenPGP card and
the authentication and decrypt keys.
Noteworthy changes in version 2.0.0 (2006-11-11) Noteworthy changes in version 2.0.0 (2006-11-11)
------------------------------------------------- -------------------------------------------------

1
THANKS
View File

@ -90,6 +90,7 @@ Greg Troxel gdt at ir.bbn.com
Gregory Steuck steuck at iname.com Gregory Steuck steuck at iname.com
Harald Denker harry at hal.westfalen.de Harald Denker harry at hal.westfalen.de
Holger Baust Holger.Baust at freenet-ag.de Holger Baust Holger.Baust at freenet-ag.de
Henrik Nordstrom henrik at henriknordstrom.net
Hendrik Buschkamp buschkamp at rheumanet.org Hendrik Buschkamp buschkamp at rheumanet.org
Holger Schurig holger at d.om.org Holger Schurig holger at d.om.org
Holger Smolinski smolinsk at de.ibm.com Holger Smolinski smolinsk at de.ibm.com

View File

@ -1,3 +1,27 @@
2006-11-20 Werner Koch <wk@g10code.com>
* call-pinentry.c (agent_popup_message_stop): Use SIGKILL.
* call-scd.c (inq_needpin): Implement POPUPKEYPADPROMPT and
DISMISSKEYPADPROMPT.
2006-11-15 Werner Koch <wk@g10code.com>
* protect.c (make_shadow_info): Cast printf arg to unsigned int.
* minip12.c (parse_bag_encrypted_data): Ditto.
(parse_bag_data, p12_parse): Ditto.
* command-ssh.c (ssh_identity_register): Changed buffer_n to
size_t.
* agent.h (struct server_control_s): New field thread_startup.
* command.c (start_command_handler): Moved CTRL init code to ..
* gpg-agent.c (start_connection_thread): .. here.
(agent_deinit_default_ctrl): New.
(agent_init_default_ctrl): Made static.
(handle_connections): Allocate CTRL and pass it pth_spawn.
* command-ssh.c (start_command_handler_ssh): Moved CTRL init code
to ..
* gpg-agent.c (start_connection_thread_ssh): .. here.
2006-11-14 Werner Koch <wk@g10code.com> 2006-11-14 Werner Koch <wk@g10code.com>
* command.c (bump_key_eventcounter): New. * command.c (bump_key_eventcounter): New.

View File

@ -112,6 +112,12 @@ struct scd_local_s;
/* Collection of data per session (aka connection). */ /* Collection of data per session (aka connection). */
struct server_control_s struct server_control_s
{ {
/* Private data used to fire up the connection thread. We use this
structure do avoid an extra allocation for just a few bytes. */
struct {
int fd;
} thread_startup;
/* Private data of the server (command.c). */ /* Private data of the server (command.c). */
struct server_local_s *server_local; struct server_local_s *server_local;
@ -178,16 +184,15 @@ cache_mode_t;
/*-- gpg-agent.c --*/ /*-- gpg-agent.c --*/
void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */ void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */
void agent_init_default_ctrl (struct server_control_s *ctrl);
/*-- command.c --*/ /*-- command.c --*/
gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...); gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...);
void bump_key_eventcounter (void); void bump_key_eventcounter (void);
void bump_card_eventcounter (void); void bump_card_eventcounter (void);
void start_command_handler (int, int); void start_command_handler (ctrl_t, int, int);
/*-- command-ssh.c --*/ /*-- command-ssh.c --*/
void start_command_handler_ssh (int); void start_command_handler_ssh (ctrl_t, int);
/*-- findkey.c --*/ /*-- findkey.c --*/
int agent_write_private_key (const unsigned char *grip, int agent_write_private_key (const unsigned char *grip,

View File

@ -636,7 +636,7 @@ popup_message_thread (void *arg)
/* Pop up a message window similar to the confirm one but keep it open /* Pop up a message window similar to the confirm one but keep it open
until agent_popup_message_stop has been called. It is crucial for until agent_popup_message_stop has been called. It is crucial for
the caller to make sure that the stop function gets called as soon the caller to make sure that the stop function gets called as soon
as the message is not anymore required becuase the message is as the message is not anymore required because the message is
system modal and all other attempts to use the pinentry will fail system modal and all other attempts to use the pinentry will fail
(after a timeout). */ (after a timeout). */
int int
@ -723,8 +723,9 @@ agent_popup_message_stop (ctrl_t ctrl)
if (rc == pid) if (rc == pid)
assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1); assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
} }
else else if (pid > 0)
kill (pid, SIGINT); kill (pid, SIGKILL); /* Need to use SIGKILL due to bad
interaction of SIGINT with Pth. */
/* Now wait for the thread to terminate. */ /* Now wait for the thread to terminate. */
rc = pth_join (popup_tid, NULL); rc = pth_join (popup_tid, NULL);

View File

@ -711,17 +711,19 @@ inq_needpin (void *opaque, const char *line)
rc = assuan_send_data (parm->ctx, pin, pinlen); rc = assuan_send_data (parm->ctx, pin, pinlen);
xfree (pin); xfree (pin);
} }
else if (!strncmp (line, "KEYPADINFO", 10) && (line[10] == ' ' || !line[10])) else if (!strncmp (line, "POPUPKEYPADPROMPT", 17)
&& (line[17] == ' ' || !line[17]))
{ {
size_t code; line += 17;
char *endp;
code = strtoul (line+10, &endp, 10);
line = endp;
while (*line == ' ') while (*line == ' ')
line++; line++;
rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, code); rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, 1);
}
else if (!strncmp (line, "DISMISSKEYPADPROMPT", 19)
&& (line[19] == ' ' || !line[19]))
{
rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0);
} }
else else
{ {

View File

@ -2329,7 +2329,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
unsigned char key_grip_raw[20]; unsigned char key_grip_raw[20];
char key_grip[41]; char key_grip[41];
unsigned char *buffer = NULL; unsigned char *buffer = NULL;
unsigned int buffer_n; size_t buffer_n;
char *description = NULL; char *description = NULL;
char *comment = NULL; char *comment = NULL;
unsigned int i; unsigned int i;
@ -2821,32 +2821,28 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
/* Start serving client on SOCK_CLIENT. */ /* Start serving client on SOCK_CLIENT. */
void void
start_command_handler_ssh (int sock_client) start_command_handler_ssh (ctrl_t ctrl, int sock_client)
{ {
struct server_control_s ctrl;
estream_t stream_sock; estream_t stream_sock;
gpg_error_t err; gpg_error_t err;
int ret; int ret;
/* Setup control structure. */ /* Setup control structure. */
ctrl->connection_fd = sock_client;
memset (&ctrl, 0, sizeof (ctrl));
agent_init_default_ctrl (&ctrl);
ctrl.connection_fd = sock_client;
/* Because the ssh protocol does not send us information about the /* Because the ssh protocol does not send us information about the
the current TTY setting, we resort here to use those from startup the current TTY setting, we resort here to use those from startup
or those explictly set. */ or those explictly set. */
if (!ctrl.display && opt.startup_display) if (!ctrl->display && opt.startup_display)
ctrl.display = strdup (opt.startup_display); ctrl->display = strdup (opt.startup_display);
if (!ctrl.ttyname && opt.startup_ttyname) if (!ctrl->ttyname && opt.startup_ttyname)
ctrl.ttyname = strdup (opt.startup_ttyname); ctrl->ttyname = strdup (opt.startup_ttyname);
if (!ctrl.ttytype && opt.startup_ttytype) if (!ctrl->ttytype && opt.startup_ttytype)
ctrl.ttytype = strdup (opt.startup_ttytype); ctrl->ttytype = strdup (opt.startup_ttytype);
if (!ctrl.lc_ctype && opt.startup_lc_ctype) if (!ctrl->lc_ctype && opt.startup_lc_ctype)
ctrl.lc_ctype = strdup (opt.startup_lc_ctype); ctrl->lc_ctype = strdup (opt.startup_lc_ctype);
if (!ctrl.lc_messages && opt.startup_lc_messages) if (!ctrl->lc_messages && opt.startup_lc_messages)
ctrl.lc_messages = strdup (opt.startup_lc_messages); ctrl->lc_messages = strdup (opt.startup_lc_messages);
/* Create stream from socket. */ /* Create stream from socket. */
@ -2870,20 +2866,14 @@ start_command_handler_ssh (int sock_client)
} }
/* Main processing loop. */ /* Main processing loop. */
while ( !ssh_request_process (&ctrl, stream_sock) ) while ( !ssh_request_process (ctrl, stream_sock) )
; ;
/* Reset the SCD in case it has been used. */ /* Reset the SCD in case it has been used. */
agent_reset_scd (&ctrl); agent_reset_scd (ctrl);
out: out:
if (stream_sock) if (stream_sock)
es_fclose (stream_sock); es_fclose (stream_sock);
free (ctrl.display);
free (ctrl.ttyname);
free (ctrl.ttytype);
free (ctrl.lc_ctype);
free (ctrl.lc_messages);
} }

View File

@ -1441,18 +1441,16 @@ register_commands (assuan_context_t ctx)
} }
/* Startup the server. If LISTEN_FD and FD is given as -1, this is a simple /* Startup the server. If LISTEN_FD and FD is given as -1, this is a
piper server, otherwise it is a regular server */ simple piper server, otherwise it is a regular server. CTRL is the
control structure for this connection; it has only the basic
intialization. */
void void
start_command_handler (int listen_fd, int fd) start_command_handler (ctrl_t ctrl, int listen_fd, int fd)
{ {
int rc; int rc;
assuan_context_t ctx; assuan_context_t ctx;
struct server_control_s ctrl;
memset (&ctrl, 0, sizeof ctrl);
agent_init_default_ctrl (&ctrl);
if (listen_fd == -1 && fd == -1) if (listen_fd == -1 && fd == -1)
{ {
int filedes[2]; int filedes[2];
@ -1468,7 +1466,7 @@ start_command_handler (int listen_fd, int fd)
else else
{ {
rc = assuan_init_socket_server_ext (&ctx, fd, 2); rc = assuan_init_socket_server_ext (&ctx, fd, 2);
ctrl.connection_fd = fd; ctrl->connection_fd = fd;
} }
if (rc) if (rc)
{ {
@ -1484,12 +1482,12 @@ start_command_handler (int listen_fd, int fd)
agent_exit (2); agent_exit (2);
} }
assuan_set_pointer (ctx, &ctrl); assuan_set_pointer (ctx, ctrl);
ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
ctrl.server_local->assuan_ctx = ctx; ctrl->server_local->assuan_ctx = ctx;
ctrl.server_local->message_fd = -1; ctrl->server_local->message_fd = -1;
ctrl.server_local->use_cache_for_signing = 1; ctrl->server_local->use_cache_for_signing = 1;
ctrl.digest.raw_value = 0; ctrl->digest.raw_value = 0;
if (DBG_ASSUAN) if (DBG_ASSUAN)
assuan_set_log_stream (ctx, log_get_stream ()); assuan_set_log_stream (ctx, log_get_stream ());
@ -1520,22 +1518,14 @@ start_command_handler (int listen_fd, int fd)
} }
/* Reset the SCD if needed. */ /* Reset the SCD if needed. */
agent_reset_scd (&ctrl); agent_reset_scd (ctrl);
/* Reset the pinentry (in case of popup messages). */ /* Reset the pinentry (in case of popup messages). */
agent_reset_query (&ctrl); agent_reset_query (ctrl);
/* Cleanup. */
assuan_deinit_server (ctx); assuan_deinit_server (ctx);
if (ctrl.display) xfree (ctrl->server_local);
free (ctrl.display); ctrl->server_local = NULL;
if (ctrl.ttyname)
free (ctrl.ttyname);
if (ctrl.ttytype)
free (ctrl.ttytype);
if (ctrl.lc_ctype)
free (ctrl.lc_ctype);
if (ctrl.lc_messages)
free (ctrl.lc_messages);
xfree (ctrl.server_local);
} }

View File

@ -211,6 +211,9 @@ static char *create_socket_name (int use_standard_socket,
static int create_server_socket (int is_standard_name, const char *name); static int create_server_socket (int is_standard_name, const char *name);
static void create_directories (void); static void create_directories (void);
static void agent_init_default_ctrl (ctrl_t ctrl);
static void agent_deinit_default_ctrl (ctrl_t ctrl);
static void handle_connections (int listen_fd, int listen_fd_ssh); static void handle_connections (int listen_fd, int listen_fd_ssh);
static int check_for_running_agent (int); static int check_for_running_agent (int);
@ -813,8 +816,21 @@ main (int argc, char **argv )
if (pipe_server) if (pipe_server)
{ /* this is the simple pipe based server */ {
start_command_handler (-1, -1); /* This is the simple pipe based server */
ctrl_t ctrl;
ctrl = xtrycalloc (1, sizeof *ctrl);
if (!ctrl)
{
log_error ("error allocating connection control data: %s\n",
strerror (errno) );
agent_exit (1);
}
agent_init_default_ctrl (ctrl);
start_command_handler (ctrl, -1, -1);
agent_deinit_default_ctrl (ctrl);
xfree (ctrl);
} }
else if (!is_daemon) else if (!is_daemon)
; /* NOTREACHED */ ; /* NOTREACHED */
@ -1073,8 +1089,8 @@ agent_exit (int rc)
} }
void static void
agent_init_default_ctrl (struct server_control_s *ctrl) agent_init_default_ctrl (ctrl_t ctrl)
{ {
ctrl->connection_fd = -1; ctrl->connection_fd = -1;
@ -1103,6 +1119,21 @@ agent_init_default_ctrl (struct server_control_s *ctrl)
} }
static void
agent_deinit_default_ctrl (ctrl_t ctrl)
{
if (ctrl->display)
free (ctrl->display);
if (ctrl->ttyname)
free (ctrl->ttyname);
if (ctrl->ttytype)
free (ctrl->ttytype);
if (ctrl->lc_ctype)
free (ctrl->lc_ctype);
if (ctrl->lc_messages)
free (ctrl->lc_messages);
}
/* Reread parts of the configuration. Note, that this function is /* Reread parts of the configuration. Note, that this function is
obviously not thread-safe and should only be called from the PTH obviously not thread-safe and should only be called from the PTH
signal handler. signal handler.
@ -1437,17 +1468,20 @@ handle_signal (int signo)
static void * static void *
start_connection_thread (void *arg) start_connection_thread (void *arg)
{ {
int fd = (int)arg; ctrl_t ctrl = arg;
agent_init_default_ctrl (ctrl);
if (opt.verbose) if (opt.verbose)
log_info (_("handler 0x%lx for fd %d started\n"), log_info (_("handler 0x%lx for fd %d started\n"),
(long)pth_self (), fd); (long)pth_self (), ctrl->thread_startup.fd);
start_command_handler (-1, fd); start_command_handler (ctrl, -1, ctrl->thread_startup.fd);
if (opt.verbose) if (opt.verbose)
log_info (_("handler 0x%lx for fd %d terminated\n"), log_info (_("handler 0x%lx for fd %d terminated\n"),
(long)pth_self (), fd); (long)pth_self (), ctrl->thread_startup.fd);
agent_deinit_default_ctrl (ctrl);
xfree (ctrl);
return NULL; return NULL;
} }
@ -1456,17 +1490,20 @@ start_connection_thread (void *arg)
static void * static void *
start_connection_thread_ssh (void *arg) start_connection_thread_ssh (void *arg)
{ {
int fd = (int)arg; ctrl_t ctrl = arg;
agent_init_default_ctrl (ctrl);
if (opt.verbose) if (opt.verbose)
log_info (_("ssh handler 0x%lx for fd %d started\n"), log_info (_("ssh handler 0x%lx for fd %d started\n"),
(long)pth_self (), fd); (long)pth_self (), ctrl->thread_startup.fd);
start_command_handler_ssh (fd); start_command_handler_ssh (ctrl, ctrl->thread_startup.fd);
if (opt.verbose) if (opt.verbose)
log_info (_("ssh handler 0x%lx for fd %d terminated\n"), log_info (_("ssh handler 0x%lx for fd %d terminated\n"),
(long)pth_self (), fd); (long)pth_self (), ctrl->thread_startup.fd);
agent_deinit_default_ctrl (ctrl);
xfree (ctrl);
return NULL; return NULL;
} }
@ -1584,24 +1621,35 @@ handle_connections (int listen_fd, int listen_fd_ssh)
if (FD_ISSET (listen_fd, &read_fdset)) if (FD_ISSET (listen_fd, &read_fdset))
{ {
ctrl_t ctrl;
plen = sizeof paddr; plen = sizeof paddr;
fd = pth_accept (listen_fd, (struct sockaddr *)&paddr, &plen); fd = pth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
if (fd == -1) if (fd == -1)
{ {
log_error ("accept failed: %s\n", strerror (errno)); log_error ("accept failed: %s\n", strerror (errno));
} }
else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) )
{
log_error ("error allocating connection control data: %s\n",
strerror (errno) );
close (fd);
}
else else
{ {
char threadname[50]; char threadname[50];
snprintf (threadname, sizeof threadname-1, snprintf (threadname, sizeof threadname-1,
"conn fd=%d (gpg)", fd); "conn fd=%d (gpg)", fd);
threadname[sizeof threadname -1] = 0; threadname[sizeof threadname -1] = 0;
pth_attr_set (tattr, PTH_ATTR_NAME, threadname); pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
if (!pth_spawn (tattr, start_connection_thread, (void*)fd)) ctrl->thread_startup.fd = fd;
if (!pth_spawn (tattr, start_connection_thread, ctrl))
{ {
log_error ("error spawning connection handler: %s\n", log_error ("error spawning connection handler: %s\n",
strerror (errno) ); strerror (errno) );
close (fd); close (fd);
xfree (ctrl);
} }
} }
fd = -1; fd = -1;
@ -1609,25 +1657,36 @@ handle_connections (int listen_fd, int listen_fd_ssh)
if (listen_fd_ssh != -1 && FD_ISSET (listen_fd_ssh, &read_fdset)) if (listen_fd_ssh != -1 && FD_ISSET (listen_fd_ssh, &read_fdset))
{ {
ctrl_t ctrl;
plen = sizeof paddr; plen = sizeof paddr;
fd = pth_accept (listen_fd_ssh, (struct sockaddr *)&paddr, &plen); fd = pth_accept (listen_fd_ssh, (struct sockaddr *)&paddr, &plen);
if (fd == -1) if (fd == -1)
{ {
log_error ("accept failed for ssh: %s\n", strerror (errno)); log_error ("accept failed for ssh: %s\n", strerror (errno));
} }
else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) )
{
log_error ("error allocating connection control data: %s\n",
strerror (errno) );
close (fd);
}
else else
{ {
char threadname[50]; char threadname[50];
agent_init_default_ctrl (ctrl);
snprintf (threadname, sizeof threadname-1, snprintf (threadname, sizeof threadname-1,
"conn fd=%d (ssh)", fd); "conn fd=%d (ssh)", fd);
threadname[sizeof threadname -1] = 0; threadname[sizeof threadname -1] = 0;
pth_attr_set (tattr, PTH_ATTR_NAME, threadname); pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
ctrl->thread_startup.fd = fd;
if (!pth_spawn (tattr, start_connection_thread_ssh, (void*)fd)) if (!pth_spawn (tattr, start_connection_thread_ssh, ctrl) )
{ {
log_error ("error spawning ssh connection handler: %s\n", log_error ("error spawning ssh connection handler: %s\n",
strerror (errno) ); strerror (errno) );
close (fd); close (fd);
xfree (ctrl);
} }
} }
fd = -1; fd = -1;

View File

@ -888,7 +888,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
gcry_free (plain); gcry_free (plain);
gcry_free (cram_buffer); gcry_free (cram_buffer);
log_error ("encryptedData error at \"%s\", offset %u\n", log_error ("encryptedData error at \"%s\", offset %u\n",
where, (p - p_start)+startoffset); where, (unsigned int)((p - p_start)+startoffset));
if (bad_pass) if (bad_pass)
{ {
/* Note, that the following string might be used by other programs /* Note, that the following string might be used by other programs
@ -1133,7 +1133,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
} }
gcry_free (cram_buffer); gcry_free (cram_buffer);
log_error ( "data error at \"%s\", offset %u\n", log_error ( "data error at \"%s\", offset %u\n",
where, (p - buffer) + startoffset); where, (unsigned int)((p - buffer) + startoffset));
if (r_consumed) if (r_consumed)
*r_consumed = consumed; *r_consumed = consumed;
return NULL; return NULL;
@ -1309,7 +1309,8 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
gcry_free (cram_buffer); gcry_free (cram_buffer);
return result; return result;
bailout: bailout:
log_error ("error at \"%s\", offset %u\n", where, (p - p_start)); log_error ("error at \"%s\", offset %u\n",
where, (unsigned int)(p - p_start));
if (result) if (result)
{ {
int i; int i;

View File

@ -861,7 +861,7 @@ make_shadow_info (const char *serialno, const char *idstring)
p = stpcpy (p, numbuf); p = stpcpy (p, numbuf);
for (s=serialno; *s && s[1]; s += 2) for (s=serialno; *s && s[1]; s += 2)
*(unsigned char *)p++ = xtoi_2 (s); *(unsigned char *)p++ = xtoi_2 (s);
sprintf (numbuf, "%d:", strlen (idstring)); sprintf (numbuf, "%u:", (unsigned int)strlen (idstring));
p = stpcpy (p, numbuf); p = stpcpy (p, numbuf);
p = stpcpy (p, idstring); p = stpcpy (p, idstring);
*p++ = ')'; *p++ = ')';

View File

@ -93,7 +93,55 @@ if test "$1" = "--build-w32"; then
fi fi
# ***** end W32 build script ******* # ***** end W32 build script *******
# ***** AMD64 cross build script *******
# Used to cross-compile for AMD64 (for testing)
if test "$1" = "--build-amd64"; then
tmp=`dirname $0`
tsdir=`cd "$tmp"; pwd`
shift
if [ ! -f $tsdir/scripts/config.guess ]; then
echo "$tsdir/scripts/config.guess not found" >&2
exit 1
fi
build=`$tsdir/scripts/config.guess`
[ -z "$amd64root" ] && amd64root="$HOME/amd64root"
echo "Using $amd64root as standard install directory" >&2
# Locate the cross compiler
crossbindir=
for host in x86_64-linux-gnu amd64-linux-gnu; do
if ${host}-gcc --version >/dev/null 2>&1 ; then
crossbindir=/usr/${host}/bin
conf_CC="CC=${host}-gcc"
break;
fi
done
if [ -z "$crossbindir" ]; then
echo "Cross compiler kit not installed" >&2
echo "Stop." >&2
exit 1
fi
if [ -f "$tsdir/config.log" ]; then
if ! head $tsdir/config.log | grep "$host" >/dev/null; then
echo "Please run a 'make distclean' first" >&2
exit 1
fi
fi
$tsdir/configure --enable-maintainer-mode --prefix=${amd64root} \
--host=${host} --build=${build} \
--with-gpg-error-prefix=${amd64root} \
--with-ksba-prefix=${amd64root} \
--with-libgcrypt-prefix=${amd64root} \
--with-libassuan-prefix=${amd64root} \
--with-zlib=/usr/x86_64-linux-gnu/usr \
--with-pth-prefix=/usr/x86_64-linux-gnu/usr
rc=$?
exit $rc
fi
# ***** end AMD64 cross build script *******
# Grep the required versions from configure.ac # Grep the required versions from configure.ac

View File

@ -1,3 +1,11 @@
2006-11-15 Werner Koch <wk@g10code.com>
* estream.c: Disabled Pth soft mapping.
(my_funopen_hook_ret_t): New.
(print_fun_writer): Use it here.
* iobuf.c (fd_cache_close): Use %d instead of %p for debug output.
2006-11-03 Werner Koch <wk@g10code.com> 2006-11-03 Werner Koch <wk@g10code.com>
* Makefile.am (t_convert_DEPENDENCIES): Add libcommon. From * Makefile.am (t_convert_DEPENDENCIES): Add libcommon. From

View File

@ -46,6 +46,9 @@
#endif #endif
#ifdef HAVE_PTH #ifdef HAVE_PTH
/* We explicitly need to disable soft mapping as Debian currently
enables it for no reason. */
# define PTH_SYSCALL_SOFT 0
# include <pth.h> # include <pth.h>
#endif #endif
@ -59,6 +62,7 @@ void *memrchr (const void *block, int c, size_t size);
#include <estream.h> #include <estream.h>
/* Generally used types. */ /* Generally used types. */
@ -66,6 +70,13 @@ void *memrchr (const void *block, int c, size_t size);
typedef void *(*func_realloc_t) (void *mem, size_t size); typedef void *(*func_realloc_t) (void *mem, size_t size);
typedef void (*func_free_t) (void *mem); typedef void (*func_free_t) (void *mem);
#ifdef HAVE_FOPENCOOKIE
typedef ssize_t my_funopen_hook_ret_t;
#else
typedef int my_funopen_hook_ret_t;
#endif
/* Buffer management layer. */ /* Buffer management layer. */
@ -1651,7 +1662,7 @@ doreadline (estream_t ES__RESTRICT stream, size_t max_length,
/* Helper for esprint. */ /* Helper for esprint. */
#if defined(HAVE_FOPENCOOKIE) || defined(HAVE_FUNOPEN) #if defined(HAVE_FOPENCOOKIE) || defined(HAVE_FUNOPEN)
static int static my_funopen_hook_ret_t
print_fun_writer (void *cookie_arg, const char *buffer, size_t size) print_fun_writer (void *cookie_arg, const char *buffer, size_t size)
{ {
estream_t stream = cookie_arg; estream_t stream = cookie_arg;

View File

@ -271,7 +271,7 @@ fd_cache_close (const char *fname, FILEP_OR_FD fp)
close (fp); close (fp);
#endif #endif
if (DBG_IOBUF) if (DBG_IOBUF)
log_debug ("fd_cache_close (%p) real\n", (void *) fp); log_debug ("fd_cache_close (%d) real\n", fp);
return; return;
} }
/* try to reuse a slot */ /* try to reuse a slot */

View File

@ -1,3 +1,8 @@
2006-11-15 Werner Koch <wk@g10code.com>
* logging.c (my_funopen_hook_ret_t): New.
(fun_writer): Use it.
2006-10-19 Werner Koch <wk@g10code.com> 2006-10-19 Werner Koch <wk@g10code.com>
* stringhelp.c (memrchr) [!HAVE_MEMRCHR]: Provide a replacement. * stringhelp.c (memrchr) [!HAVE_MEMRCHR]: Provide a replacement.
@ -5,7 +10,7 @@
2006-09-27 Werner Koch <wk@g10code.com> 2006-09-27 Werner Koch <wk@g10code.com>
* mischelp.c: New. * mischelp.c: New.
(timegm): Copied from gnupg 1.4, Changed from LGPL to GPL. Fixed (timegm): Copied from gnupg 1.4, changed from GPL to LGPL. Fixed
a memory leak. a memory leak.
* stringhelp.h (isascii): New. * stringhelp.h (isascii): New.

View File

@ -48,6 +48,13 @@
#define USE_FUNWRITER 1 #define USE_FUNWRITER 1
#endif #endif
#ifdef HAVE_FOPENCOOKIE
typedef ssize_t my_funopen_hook_ret_t;
#else
typedef int my_funopen_hook_ret_t;
#endif
static FILE *logstream; static FILE *logstream;
static int log_socket = -1; static int log_socket = -1;
static char prefix_buffer[80]; static char prefix_buffer[80];
@ -111,7 +118,7 @@ writen (int fd, const void *buffer, size_t nbytes)
} }
static int static my_funopen_hook_ret_t
fun_writer (void *cookie_arg, const char *buffer, size_t size) fun_writer (void *cookie_arg, const char *buffer, size_t size)
{ {
struct fun_cookie_s *cookie = cookie_arg; struct fun_cookie_s *cookie = cookie_arg;

View File

@ -1,3 +1,7 @@
2006-11-15 Werner Koch <wk@g10code.com>
* kbxutil.c (dump_openpgp_key): Cast printf argument.
2006-10-20 Werner Koch <wk@g10code.com> 2006-10-20 Werner Koch <wk@g10code.com>
* keybox-search.c (blob_x509_has_grip, has_keygrip): New. * keybox-search.c (blob_x509_has_grip, has_keygrip): New.

View File

@ -367,7 +367,7 @@ dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image)
u = &info->uids; u = &info->uids;
do do
{ {
printf ("uid\t\t%.*s\n", u->len, image + u->off); printf ("uid\t\t%.*s\n", (int)u->len, image + u->off);
u = u->next; u = u->next;
} }
while (u); while (u);

View File

@ -1,3 +1,8 @@
2006-11-17 Werner Koch <wk@g10code.com>
* gnupg-pth.m4: Make sure that have_w32_system is set to no by
default.
2006-11-14 Werner Koch <wk@g10code.com> 2006-11-14 Werner Koch <wk@g10code.com>
* libassuan.m4: Updated from libassuan SVN. * libassuan.m4: Updated from libassuan SVN.

View File

@ -91,6 +91,7 @@ AC_DEFUN([GNUPG_PATH_PTH],
fi fi
AC_PATH_PROG(PTH_CONFIG, pth-config, no) AC_PATH_PROG(PTH_CONFIG, pth-config, no)
tmp=ifelse([$1], ,1.3.7,$1) tmp=ifelse([$1], ,1.3.7,$1)
test -z "$have_w32_system" && have_w32_system="no"
if test "$have_w32_system" = no; then if test "$have_w32_system" = no; then
if test "$PTH_CONFIG" != "no"; then if test "$PTH_CONFIG" != "no"; then
GNUPG_PTH_VERSION_CHECK($tmp) GNUPG_PTH_VERSION_CHECK($tmp)

View File

@ -1,3 +1,37 @@
2006-11-20 Werner Koch <wk@g10code.com>
* app-openpgp.c (verify_chv2): Support for keypads (only CHV2).
* ccid-driver.c (ccid_transceive_secure): Made it work for Kaan
and SCM.
2006-11-17 Werner Koch <wk@g10code.com>
* ccid-driver.c (scan_or_find_devices): Use DEBUGOUT_2 instead of
log_debug. Removed few other log_debug.
* iso7816.c (iso7816_check_keypad): Allow for a SW of 0.
* command.c (pin_cb): New mode to prompt for a keypad entry.
* scdaemon.c (main) <gpgconf-list>: Add disable-keypad.
2006-11-15 Werner Koch <wk@g10code.com>
* app-p15.c (read_ef_odf): Cast one printf arg.
* scdaemon.h (struct server_control_s): Add field THREAD_STARTUP.
* command.c (scd_command_handler): Add new arg CTRL.
* scdaemon.c (scd_init_default_ctrl): Made static.
(scd_deinit_default_ctrl): New.
(start_connection_thread): Call init/deinit of ctrl.
(handle_connections): Allocate CTRL.
* apdu.c (PCSC_ERR_MASK): New.
(reset_pcsc_reader, pcsc_get_status, pcsc_send_apdu)
(close_pcsc_reader, open_pcsc_reader): Use it after shifting error
values. Reported by Henrik Nordstrom. Fixes bug #724.
2006-10-24 Werner Koch <wk@g10code.com> 2006-10-24 Werner Koch <wk@g10code.com>
* scdaemon.h (GCRY_MD_USER_TLS_MD5SHA1): New. * scdaemon.h (GCRY_MD_USER_TLS_MD5SHA1): New.

View File

@ -222,6 +222,11 @@ static char (* DLSTDCALL CT_close) (unsigned short ctn);
#define PCSC_E_READER_UNAVAILABLE 0x80100017 #define PCSC_E_READER_UNAVAILABLE 0x80100017
#define PCSC_W_REMOVED_CARD 0x80100069 #define PCSC_W_REMOVED_CARD 0x80100069
/* The PC/SC error is defined as a long as per specs. Due to left
shifts bit 31 will get sign extended. We use this mask to fix
it. */
#define PCSC_ERR_MASK(a) ((a) & 0xffffffff)
struct pcsc_io_request_s struct pcsc_io_request_s
{ {
@ -739,7 +744,7 @@ pcsc_error_to_sw (long ec)
{ {
int rc; int rc;
switch (ec) switch ( PCSC_ERR_MASK (ec) )
{ {
case 0: rc = 0; break; case 0: rc = 0; break;
@ -834,7 +839,8 @@ reset_pcsc_reader (int slot)
sw = SW_HOST_GENERAL_ERROR; sw = SW_HOST_GENERAL_ERROR;
goto command_failed; goto command_failed;
} }
err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
| (msgbuf[7] << 8 ) | msgbuf[8]);
if (err) if (err)
{ {
log_error ("PC/SC RESET failed: %s (0x%lx)\n", log_error ("PC/SC RESET failed: %s (0x%lx)\n",
@ -981,7 +987,8 @@ pcsc_get_status (int slot, unsigned int *status)
goto command_failed; goto command_failed;
} }
len -= 4; /* Already read the error code. */ len -= 4; /* Already read the error code. */
err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
| (msgbuf[7] << 8 ) | msgbuf[8]);
if (err) if (err)
{ {
log_error ("pcsc_status failed: %s (0x%lx)\n", log_error ("pcsc_status failed: %s (0x%lx)\n",
@ -1151,7 +1158,8 @@ pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
goto command_failed; goto command_failed;
} }
len -= 4; /* Already read the error code. */ len -= 4; /* Already read the error code. */
err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
| (msgbuf[7] << 8 ) | msgbuf[8]);
if (err) if (err)
{ {
log_error ("pcsc_transmit failed: %s (0x%lx)\n", log_error ("pcsc_transmit failed: %s (0x%lx)\n",
@ -1283,7 +1291,8 @@ close_pcsc_reader (int slot)
goto command_failed; goto command_failed;
} }
len -= 4; /* Already read the error code. */ len -= 4; /* Already read the error code. */
err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
| (msgbuf[7] << 8 ) | msgbuf[8]);
if (err) if (err)
log_error ("pcsc_close failed: %s (0x%lx)\n", log_error ("pcsc_close failed: %s (0x%lx)\n",
pcsc_error_string (err), err); pcsc_error_string (err), err);
@ -1470,7 +1479,8 @@ open_pcsc_reader (const char *portstr)
(unsigned long)len); (unsigned long)len);
goto command_failed; goto command_failed;
} }
err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
| (msgbuf[7] << 8 ) | msgbuf[8]);
if (err) if (err)
{ {
log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err)); log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err));

View File

@ -1291,27 +1291,52 @@ verify_chv2 (app_t app,
{ {
char *pinvalue; char *pinvalue;
iso7816_pininfo_t pininfo; iso7816_pininfo_t pininfo;
int did_keypad = 0;
memset (&pininfo, 0, sizeof pininfo); memset (&pininfo, 0, sizeof pininfo);
pininfo.mode = 1; pininfo.mode = 1;
pininfo.minlen = 6; pininfo.minlen = 6;
rc = pincb (pincb_arg, "PIN", &pinvalue); if (!opt.disable_keypad
if (rc) && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
{ {
log_info (_("PIN callback returned error: %s\n"), gpg_strerror (rc)); /* The reader supports the verify command through the keypad. */
return rc; did_keypad = 1;
rc = pincb (pincb_arg,
_("||Please enter your PIN at the reader's keypad"),
NULL);
if (rc)
{
log_info (_("PIN callback returned error: %s\n"),
gpg_strerror (rc));
return rc;
}
rc = iso7816_verify_kp (app->slot, 0x82, "", 0, &pininfo);
/* Dismiss the prompt. */
pincb (pincb_arg, NULL, NULL);
}
else
{
/* The reader has no keypad or we don't want to use it. */
rc = pincb (pincb_arg, "PIN", &pinvalue);
if (rc)
{
log_info (_("PIN callback returned error: %s\n"),
gpg_strerror (rc));
return rc;
}
if (strlen (pinvalue) < 6)
{
log_error (_("PIN for CHV%d is too short;"
" minimum length is %d\n"), 2, 6);
xfree (pinvalue);
return gpg_error (GPG_ERR_BAD_PIN);
}
rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
} }
if (strlen (pinvalue) < 6)
{
log_error (_("PIN for CHV%d is too short;"
" minimum length is %d\n"), 2, 6);
xfree (pinvalue);
return gpg_error (GPG_ERR_BAD_PIN);
}
rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
if (rc) if (rc)
{ {
log_error (_("verify CHV%d failed: %s\n"), 2, gpg_strerror (rc)); log_error (_("verify CHV%d failed: %s\n"), 2, gpg_strerror (rc));
@ -1321,7 +1346,7 @@ verify_chv2 (app_t app,
} }
app->did_chv2 = 1; app->did_chv2 = 1;
if (!app->did_chv1 && !app->force_chv1) if (!app->did_chv1 && !app->force_chv1 && !did_keypad)
{ {
rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) if (gpg_err_code (rc) == GPG_ERR_BAD_PIN)

View File

@ -692,7 +692,8 @@ read_ef_odf (app_t app, unsigned short odf_fid)
} }
if (buflen) if (buflen)
log_info ("warning: %u bytes of garbage detected at end of ODF\n", buflen); log_info ("warning: %u bytes of garbage detected at end of ODF\n",
(unsigned int)buflen);
xfree (buffer); xfree (buffer);
return 0; return 0;

View File

@ -200,7 +200,8 @@ enum {
VENDOR_CHERRY = 0x046a, VENDOR_CHERRY = 0x046a,
VENDOR_SCM = 0x04e6, VENDOR_SCM = 0x04e6,
VENDOR_OMNIKEY= 0x076b, VENDOR_OMNIKEY= 0x076b,
VENDOR_GEMPC = 0x08e6 VENDOR_GEMPC = 0x08e6,
VENDOR_KAAN = 0x0d46
}; };
/* A list and a table with special transport descriptions. */ /* A list and a table with special transport descriptions. */
@ -990,11 +991,10 @@ scan_or_find_devices (int readerno, const char *readerid,
fd = open (transports[i].name, O_RDWR); fd = open (transports[i].name, O_RDWR);
if (fd == -1) if (fd == -1)
{ {
log_debug ("failed to open `%s': %s\n", DEBUGOUT_2 ("failed to open `%s': %s\n",
transports[i].name, strerror (errno)); transports[i].name, strerror (errno));
continue; continue;
} }
log_debug ("opened `%s': fd=%d\n", transports[i].name, fd);
rid = malloc (strlen (transports[i].name) + 30 + 10); rid = malloc (strlen (transports[i].name) + 30 + 10);
if (!rid) if (!rid)
@ -1047,7 +1047,6 @@ scan_or_find_devices (int readerno, const char *readerid,
} }
free (rid); free (rid);
close (fd); close (fd);
log_debug ("closed fd %d\n", fd);
} }
if (scan_mode) if (scan_mode)
@ -1208,10 +1207,7 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid)
if (idev) if (idev)
usb_close (idev); usb_close (idev);
if (dev_fd != -1) if (dev_fd != -1)
{ close (dev_fd);
close (dev_fd);
log_debug ("closed fd %d\n", dev_fd);
}
free (*handle); free (*handle);
*handle = NULL; *handle = NULL;
} }
@ -1254,7 +1250,6 @@ do_close_reader (ccid_driver_t handle)
if (handle->dev_fd != -1) if (handle->dev_fd != -1)
{ {
close (handle->dev_fd); close (handle->dev_fd);
log_debug ("closed fd %d\n", handle->dev_fd);
handle->dev_fd = -1; handle->dev_fd = -1;
} }
} }
@ -1324,10 +1319,7 @@ ccid_shutdown_reader (ccid_driver_t handle)
usb_close (handle->idev); usb_close (handle->idev);
handle->idev = NULL; handle->idev = NULL;
if (handle->dev_fd != -1) if (handle->dev_fd != -1)
{ close (handle->dev_fd);
close (handle->dev_fd);
log_debug ("closed fd %d\n", handle->dev_fd);
}
handle->dev_fd = -1; handle->dev_fd = -1;
} }
@ -2369,10 +2361,24 @@ ccid_transceive_secure (ccid_driver_t handle,
|| pinlen_min > pinlen_max) || pinlen_min > pinlen_max)
return CCID_DRIVER_ERR_INV_VALUE; return CCID_DRIVER_ERR_INV_VALUE;
/* We have only tested this with an SCM reader so better don't risk /* We have only tested a few readers so better don't risk anything
anything and do not allow the use with other readers. */ and do not allow the use with other readers. */
if (handle->id_vendor != VENDOR_SCM) switch (handle->id_vendor)
return CCID_DRIVER_ERR_NOT_SUPPORTED; {
case VENDOR_SCM: /* Tested with SPR 532. */
case VENDOR_KAAN: /* Tested with KAAN Advanced (1.02). */
break;
/* The CHERRY XX44 does not yet work. I have not investigated it
closer because there is another problem: It echos a "*" for
each entered character and we somehow need to arrange that it
doesn't get to the tty at all. Given thate are running
without a control terminal there is not much we can do about.
A weird hack using pinentry comes in mind but I doubnt that
this is a clean solution. Need to contact Cherry.
*/
default:
return CCID_DRIVER_ERR_NOT_SUPPORTED;
}
if (testmode) if (testmode)
return 0; /* Success */ return 0; /* Success */
@ -2390,7 +2396,7 @@ ccid_transceive_secure (ccid_driver_t handle,
msg[0] = PC_to_RDR_Secure; msg[0] = PC_to_RDR_Secure;
msg[5] = 0; /* slot */ msg[5] = 0; /* slot */
msg[6] = seqno = handle->seqno++; msg[6] = seqno = handle->seqno++;
msg[7] = 4; /* bBWI */ msg[7] = 0; /* bBWI */
msg[8] = 0; /* RFU */ msg[8] = 0; /* RFU */
msg[9] = 0; /* RFU */ msg[9] = 0; /* RFU */
msg[10] = 0; /* Perform PIN verification. */ msg[10] = 0; /* Perform PIN verification. */
@ -2411,8 +2417,8 @@ ccid_transceive_secure (ccid_driver_t handle,
msg[14] = 0x00; /* bmPINLengthFormat: msg[14] = 0x00; /* bmPINLengthFormat:
Units are bytes, position is 0. */ Units are bytes, position is 0. */
} }
msg[15] = pinlen_min; /* wPINMaxExtraDigit-Minimum. */ msg[15] = pinlen_max; /* wPINMaxExtraDigit-Maximum. */
msg[16] = pinlen_max; /* wPINMaxExtraDigit-Maximum. */ msg[16] = pinlen_min; /* wPINMaxExtraDigit-Minimum. */
msg[17] = 0x02; /* bEntryValidationCondition: msg[17] = 0x02; /* bEntryValidationCondition:
Validation key pressed */ Validation key pressed */
if (pinlen_min && pinlen_max && pinlen_min == pinlen_max) if (pinlen_min && pinlen_max && pinlen_min == pinlen_max)
@ -2424,13 +2430,14 @@ ccid_transceive_secure (ccid_driver_t handle,
/* bTeoProlog follows: */ /* bTeoProlog follows: */
msg[22] = handle->nonnull_nad? ((1 << 4) | 0): 0; msg[22] = handle->nonnull_nad? ((1 << 4) | 0): 0;
msg[23] = ((handle->t1_ns & 1) << 6); /* I-block */ msg[23] = ((handle->t1_ns & 1) << 6); /* I-block */
msg[24] = 4; /* apdulen. */ msg[24] = 0; /* The apdulen will be filled in by the reader. */
/* APDU follows: */ /* APDU follows: */
msg[25] = apdu_buf[0]; /* CLA */ msg[25] = apdu_buf[0]; /* CLA */
msg[26] = apdu_buf[1]; /* INS */ msg[26] = apdu_buf[1]; /* INS */
msg[27] = apdu_buf[2]; /* P1 */ msg[27] = apdu_buf[2]; /* P1 */
msg[28] = apdu_buf[3]; /* P2 */ msg[28] = apdu_buf[3]; /* P2 */
msglen = 29; msglen = 29;
/* An EDC is not required. */
set_msg_len (msg, msglen - 10); set_msg_len (msg, msglen - 10);
DEBUGOUT ("sending"); DEBUGOUT ("sending");
@ -2444,12 +2451,30 @@ ccid_transceive_secure (ccid_driver_t handle,
msg = recv_buffer; msg = recv_buffer;
rc = bulk_in (handle, msg, sizeof recv_buffer, &msglen, rc = bulk_in (handle, msg, sizeof recv_buffer, &msglen,
RDR_to_PC_DataBlock, seqno, 5000, 0); RDR_to_PC_DataBlock, seqno, 30000, 0);
if (rc) if (rc)
return rc; return rc;
tpdu = msg + 10; tpdu = msg + 10;
tpdulen = msglen - 10; tpdulen = msglen - 10;
if (handle->apdu_level)
{
if (resp)
{
if (tpdulen > maxresplen)
{
DEBUGOUT_2 ("provided buffer too short for received data "
"(%u/%u)\n",
(unsigned int)tpdulen, (unsigned int)maxresplen);
return CCID_DRIVER_ERR_INV_VALUE;
}
memcpy (resp, tpdu, tpdulen);
*nresp = tpdulen;
}
return 0;
}
if (tpdulen < 4) if (tpdulen < 4)
{ {
@ -2595,7 +2620,7 @@ main (int argc, char **argv)
{ {
int rc; int rc;
ccid_driver_t ccid; ccid_driver_t ccid;
unsigned int slotstat; int slotstat;
unsigned char result[512]; unsigned char result[512];
size_t resultlen; size_t resultlen;
int no_pinpad = 0; int no_pinpad = 0;
@ -2623,7 +2648,7 @@ main (int argc, char **argv)
} }
else if ( !strcmp (*argv, "--debug")) else if ( !strcmp (*argv, "--debug"))
{ {
ccid_set_debug_level (1); ccid_set_debug_level (ccid_set_debug_level (-1)+1);
argc--; argv++; argc--; argv++;
} }
else if ( !strcmp (*argv, "--no-poll")) else if ( !strcmp (*argv, "--no-poll"))

View File

@ -721,6 +721,31 @@ pin_cb (void *opaque, const char *info, char **retstr)
unsigned char *value; unsigned char *value;
size_t valuelen; size_t valuelen;
if (!retstr)
{
/* We prompt for keypad entry. To make sure that the popup has
been show we use an inquire and not just a status message.
We ignore any value returned. */
if (info)
{
log_debug ("prompting for keypad entry '%s'\n", info);
rc = asprintf (&command, "POPUPKEYPADPROMPT %s", info);
if (rc < 0)
return gpg_error (gpg_err_code_from_errno (errno));
rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
free (command);
}
else
{
log_debug ("dismiss keypad entry prompt\n");
rc = assuan_inquire (ctx, "DISMISSKEYPADPROMPT",
&value, &valuelen, MAXLEN_PIN);
}
if (!rc)
xfree (value);
return rc;
}
*retstr = NULL; *retstr = NULL;
log_debug ("asking for PIN '%s'\n", info); log_debug ("asking for PIN '%s'\n", info);
@ -1584,14 +1609,10 @@ register_commands (assuan_context_t ctx)
/* Startup the server. If FD is given as -1 this is simple pipe /* Startup the server. If FD is given as -1 this is simple pipe
server, otherwise it is a regular server. */ server, otherwise it is a regular server. */
void void
scd_command_handler (int fd) scd_command_handler (ctrl_t ctrl, int fd)
{ {
int rc; int rc;
assuan_context_t ctx; assuan_context_t ctx;
struct server_control_s ctrl;
memset (&ctrl, 0, sizeof ctrl);
scd_init_default_ctrl (&ctrl);
if (fd == -1) if (fd == -1)
{ {
@ -1622,20 +1643,20 @@ scd_command_handler (int fd)
/* Allocate and initialize the server object. Put it into the list /* Allocate and initialize the server object. Put it into the list
of active sessions. */ of active sessions. */
ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
ctrl.server_local->next_session = session_list; ctrl->server_local->next_session = session_list;
session_list = ctrl.server_local; session_list = ctrl->server_local;
ctrl.server_local->ctrl_backlink = &ctrl; ctrl->server_local->ctrl_backlink = ctrl;
ctrl.server_local->assuan_ctx = ctx; ctrl->server_local->assuan_ctx = ctx;
if (DBG_ASSUAN) if (DBG_ASSUAN)
assuan_set_log_stream (ctx, log_get_stream ()); assuan_set_log_stream (ctx, log_get_stream ());
/* We open the reader right at startup so that the ticker is able to /* We open the reader right at startup so that the ticker is able to
update the status file. */ update the status file. */
if (ctrl.reader_slot == -1) if (ctrl->reader_slot == -1)
{ {
ctrl.reader_slot = get_reader_slot (); ctrl->reader_slot = get_reader_slot ();
} }
/* Command processing loop. */ /* Command processing loop. */
@ -1661,23 +1682,24 @@ scd_command_handler (int fd)
} }
/* Cleanup. */ /* Cleanup. */
do_reset (&ctrl, 0); do_reset (ctrl, 0);
/* Release the server object. */ /* Release the server object. */
if (session_list == ctrl.server_local) if (session_list == ctrl->server_local)
session_list = ctrl.server_local->next_session; session_list = ctrl->server_local->next_session;
else else
{ {
struct server_local_s *sl; struct server_local_s *sl;
for (sl=session_list; sl->next_session; sl = sl->next_session) for (sl=session_list; sl->next_session; sl = sl->next_session)
if (sl->next_session == ctrl.server_local) if (sl->next_session == ctrl->server_local)
break; break;
if (!sl->next_session) if (!sl->next_session)
BUG (); BUG ();
sl->next_session = ctrl.server_local->next_session; sl->next_session = ctrl->server_local->next_session;
} }
xfree (ctrl.server_local); xfree (ctrl->server_local);
ctrl->server_local = NULL;
/* Release the Assuan context. */ /* Release the Assuan context. */
assuan_deinit_server (ctx); assuan_deinit_server (ctx);

View File

@ -235,7 +235,7 @@ iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo)
sw = apdu_check_keypad (slot, command, sw = apdu_check_keypad (slot, command,
pininfo->mode, pininfo->minlen, pininfo->maxlen, pininfo->mode, pininfo->minlen, pininfo->maxlen,
pininfo->padlen); pininfo->padlen);
return map_sw (sw); return iso7816_map_sw (sw);
} }

View File

@ -600,7 +600,7 @@ main (int argc, char **argv )
printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE ); printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE );
#endif #endif
printf ("allow-admin:%lu:\n", GC_OPT_FLAG_NONE ); printf ("allow-admin:%lu:\n", GC_OPT_FLAG_NONE );
printf ("disable-keypad:%lu:\n", GC_OPT_FLAG_NONE );
scd_exit (0); scd_exit (0);
} }
@ -615,6 +615,7 @@ main (int argc, char **argv )
if (pipe_server) if (pipe_server)
{ {
/* This is the simple pipe based server */ /* This is the simple pipe based server */
ctrl_t ctrl;
pth_attr_t tattr; pth_attr_t tattr;
int fd = -1; int fd = -1;
@ -656,10 +657,19 @@ main (int argc, char **argv )
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 512*1024); pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 512*1024);
pth_attr_set (tattr, PTH_ATTR_NAME, "pipe-connection"); pth_attr_set (tattr, PTH_ATTR_NAME, "pipe-connection");
if (!pth_spawn (tattr, start_connection_thread, (void*)(-1))) ctrl = xtrycalloc (1, sizeof *ctrl);
if ( !ctrl )
{
log_error ("error allocating connection control data: %s\n",
strerror (errno) );
scd_exit (2);
}
ctrl->thread_startup.fd = -1;
if ( !pth_spawn (tattr, start_connection_thread, ctrl) )
{ {
log_error ("error spawning pipe connection handler: %s\n", log_error ("error spawning pipe connection handler: %s\n",
strerror (errno) ); strerror (errno) );
xfree (ctrl);
scd_exit (2); scd_exit (2);
} }
@ -810,12 +820,18 @@ scd_exit (int rc)
} }
void static void
scd_init_default_ctrl (ctrl_t ctrl) scd_init_default_ctrl (ctrl_t ctrl)
{ {
ctrl->reader_slot = -1; ctrl->reader_slot = -1;
} }
static void
scd_deinit_default_ctrl (ctrl_t ctrl)
{
}
/* Return the name of the socket to be used to connect to this /* Return the name of the socket to be used to connect to this
process. If no socket is available, return NULL. */ process. If no socket is available, return NULL. */
@ -1007,23 +1023,26 @@ create_server_socket (int is_standard_name, const char *name)
static void * static void *
start_connection_thread (void *arg) start_connection_thread (void *arg)
{ {
int fd = (int)arg; ctrl_t ctrl = arg;
scd_init_default_ctrl (ctrl);
if (opt.verbose)
log_info (_("handler for fd %d started\n"), ctrl->thread_startup.fd);
scd_command_handler (ctrl, ctrl->thread_startup.fd);
if (opt.verbose) if (opt.verbose)
log_info (_("handler for fd %d started\n"), fd); log_info (_("handler for fd %d terminated\n"), ctrl->thread_startup.fd);
scd_command_handler (fd);
if (opt.verbose)
log_info (_("handler for fd %d terminated\n"), fd);
/* If this thread is the pipe connection thread, flag that a /* If this thread is the pipe connection thread, flag that a
shutdown is required. With the next ticker event and given that shutdown is required. With the next ticker event and given that
no other connections are running the shutdown will then no other connections are running the shutdown will then
happen. */ happen. */
if (fd == -1) if (ctrl->thread_startup.fd == -1)
shutdown_pending = 1; shutdown_pending = 1;
scd_deinit_default_ctrl (ctrl);
xfree (ctrl);
return NULL; return NULL;
} }
@ -1137,23 +1156,33 @@ handle_connections (int listen_fd)
if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset)) if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
{ {
ctrl_t ctrl;
plen = sizeof paddr; plen = sizeof paddr;
fd = pth_accept (listen_fd, (struct sockaddr *)&paddr, &plen); fd = pth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
if (fd == -1) if (fd == -1)
{ {
log_error ("accept failed: %s\n", strerror (errno)); log_error ("accept failed: %s\n", strerror (errno));
} }
else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) )
{
log_error ("error allocating connection control data: %s\n",
strerror (errno) );
close (fd);
}
else else
{ {
char threadname[50]; char threadname[50];
snprintf (threadname, sizeof threadname-1, "conn fd=%d", fd); snprintf (threadname, sizeof threadname-1, "conn fd=%d", fd);
threadname[sizeof threadname -1] = 0; threadname[sizeof threadname -1] = 0;
pth_attr_set (tattr, PTH_ATTR_NAME, threadname); pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
ctrl->thread_startup.fd = fd;
if (!pth_spawn (tattr, start_connection_thread, (void*)fd)) if (!pth_spawn (tattr, start_connection_thread, ctrl))
{ {
log_error ("error spawning connection handler: %s\n", log_error ("error spawning connection handler: %s\n",
strerror (errno) ); strerror (errno) );
xfree (ctrl);
close (fd); close (fd);
} }
} }

View File

@ -90,6 +90,12 @@ struct app_ctx_s;
struct server_control_s struct server_control_s
{ {
/* Private data used to fire up the connection thread. We use this
structure do avoid an extra allocation for just a few bytes. */
struct {
int fd;
} thread_startup;
/* Local data of the server; used only in command.c. */ /* Local data of the server; used only in command.c. */
struct server_local_s *server_local; struct server_local_s *server_local;
@ -115,11 +121,10 @@ typedef struct app_ctx_s *app_t;
/*-- scdaemon.c --*/ /*-- scdaemon.c --*/
void scd_exit (int rc); void scd_exit (int rc);
void scd_init_default_ctrl (ctrl_t ctrl);
const char *scd_get_socket_name (void); const char *scd_get_socket_name (void);
/*-- command.c --*/ /*-- command.c --*/
void scd_command_handler (int); void scd_command_handler (ctrl_t, int);
void send_status_info (ctrl_t ctrl, const char *keyword, ...) void send_status_info (ctrl_t ctrl, const char *keyword, ...)
GNUPG_GCC_A_SENTINEL(1); GNUPG_GCC_A_SENTINEL(1);
void scd_update_reader_status_file (void); void scd_update_reader_status_file (void);

View File

@ -1,3 +1,8 @@
2006-11-16 Werner Koch <wk@g10code.com>
* Makefile.am (plain-large): Use gpg.texi instead of FAQ which
won't be found as it is not a source file. Pointed out by Moritz.
2006-10-04 Werner Koch <wk@g10code.com> 2006-10-04 Werner Koch <wk@g10code.com>
* signencrypt.test: Need to prepend srcdir to the file name * signencrypt.test: Need to prepend srcdir to the file name

View File

@ -100,7 +100,7 @@ data-80000:
plain-large: plain-large:
cat $(srcdir)/../../doc/HACKING \ cat $(srcdir)/../../doc/HACKING \
$(srcdir)/../../doc/DETAILS \ $(srcdir)/../../doc/DETAILS \
$(srcdir)/../../doc/FAQ >plain-large $(srcdir)/../../doc/gpg.texi >plain-large
# To speed up key generation we create a dummy random seed file # To speed up key generation we create a dummy random seed file
random_seed: random_seed:

View File

@ -1,3 +1,7 @@
2006-11-17 Werner Koch <wk@g10code.com>
* gpgconf-comp.c: Made disable-keypad a basic option.
2006-11-03 Werner Koch <wk@g10code.com> 2006-11-03 Werner Koch <wk@g10code.com>
* symcryptrun.c: Include signal.h and include pth.h only if test * symcryptrun.c: Include signal.h and include pth.h only if test

View File

@ -530,7 +530,7 @@ static gc_option_t gc_options_scdaemon[] =
{ "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
"gnupg", "do not use the internal CCID driver", "gnupg", "do not use the internal CCID driver",
GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
{ "disable-keypad", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, { "disable-keypad", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
"gnupg", "do not use a reader's keypad", "gnupg", "do not use a reader's keypad",
GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },