mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-17 14:07:03 +01:00
Made some PIN pads work.
Some cleanups for 64 bit CPUs.
This commit is contained in:
parent
267d4c8fa7
commit
5885142c83
@ -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.
|
||||||
|
@ -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
5
NEWS
@ -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
1
THANKS
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
@ -1441,17 +1441,15 @@ 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)
|
||||||
{
|
{
|
||||||
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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++ = ')';
|
||||||
|
48
autogen.sh
48
autogen.sh
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
|
@ -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.
|
||||||
|
22
scd/apdu.c
22
scd/apdu.c
@ -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));
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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,13 +2451,31 @@ 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)
|
||||||
{
|
{
|
||||||
usb_clear_halt (handle->idev, handle->ep_bulk_in);
|
usb_clear_halt (handle->idev, handle->ep_bulk_in);
|
||||||
@ -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"))
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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 },
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user