Made some PIN pads work.
authorWerner Koch <wk@gnupg.org>
Mon, 20 Nov 2006 16:49:41 +0000 (16:49 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 20 Nov 2006 16:49:41 +0000 (16:49 +0000)
Some cleanups for 64 bit CPUs.

36 files changed:
ChangeLog
Makefile.am
NEWS
THANKS
agent/ChangeLog
agent/agent.h
agent/call-pinentry.c
agent/call-scd.c
agent/command-ssh.c
agent/command.c
agent/gpg-agent.c
agent/minip12.c
agent/protect.c
autogen.sh
common/ChangeLog
common/estream.c
common/iobuf.c
jnlib/ChangeLog
jnlib/logging.c
kbx/ChangeLog
kbx/kbxutil.c
m4/ChangeLog
m4/gnupg-pth.m4
scd/ChangeLog
scd/apdu.c
scd/app-openpgp.c
scd/app-p15.c
scd/ccid-driver.c
scd/command.c
scd/iso7816.c
scd/scdaemon.c
scd/scdaemon.h
tests/openpgp/ChangeLog
tests/openpgp/Makefile.am
tools/ChangeLog
tools/gpgconf-comp.c

index db8df3e..5a2d98b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * configure.ac (HAVE_ASSUAN_SET_IO_MONITOR): Test for it.
index 996ed02..c5dec14 100644 (file)
@@ -22,7 +22,7 @@
 
 ACLOCAL_AMFLAGS = -I m4 -I gl/m4
 AUTOMAKE_OPTIONS = dist-bzip2
-DISTCHECK_CONFIGURE_FLAGS = --enable-gpg
+DISTCHECK_CONFIGURE_FLAGS = --enable-symcryptrun
 
 EXTRA_DIST = scripts/config.rpath autogen.sh README.SVN
 DISTCLEANFILES = g10defs.h 
diff --git a/NEWS b/NEWS
index 3e2232f..0f589c9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,11 @@
 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)
 -------------------------------------------------
diff --git a/THANKS b/THANKS
index 40d1a34..868e755 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -90,6 +90,7 @@ Greg Troxel              gdt at ir.bbn.com
 Gregory Steuck            steuck at iname.com
 Harald Denker             harry at hal.westfalen.de
 Holger Baust               Holger.Baust at freenet-ag.de
+Henrik Nordstrom           henrik at henriknordstrom.net
 Hendrik Buschkamp         buschkamp at rheumanet.org
 Holger Schurig            holger at d.om.org
 Holger Smolinski          smolinsk at de.ibm.com
index 761b7b0..ddee4e5 100644 (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>
 
        * command.c (bump_key_eventcounter): New.
index 2b7f367..883924c 100644 (file)
@@ -112,6 +112,12 @@ struct scd_local_s;
 /* Collection of data per session (aka connection). */
 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). */
   struct server_local_s *server_local;
 
@@ -178,16 +184,15 @@ cache_mode_t;
 
 /*-- gpg-agent.c --*/
 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 --*/
 gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...);
 void bump_key_eventcounter (void);
 void bump_card_eventcounter (void);
-void start_command_handler (int, int);
+void start_command_handler (ctrl_t, int, int);
 
 /*-- command-ssh.c --*/
-void start_command_handler_ssh (int);
+void start_command_handler_ssh (ctrl_t, int);
 
 /*-- findkey.c --*/
 int agent_write_private_key (const unsigned char *grip,
index 7193db7..f22136f 100644 (file)
@@ -636,7 +636,7 @@ popup_message_thread (void *arg)
 /* 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
    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
    (after a timeout). */
 int 
@@ -723,8 +723,9 @@ agent_popup_message_stop (ctrl_t ctrl)
       if (rc == pid)
         assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
     }
-  else
-    kill (pid, SIGINT);
+  else if (pid > 0)
+    kill (pid, SIGKILL);  /* Need to use SIGKILL due to bad
+                             interaction of SIGINT with Pth. */
 
   /* Now wait for the thread to terminate. */
   rc = pth_join (popup_tid, NULL);
index 2f91e1e..53e4ced 100644 (file)
@@ -711,17 +711,19 @@ inq_needpin (void *opaque, const char *line)
         rc = assuan_send_data (parm->ctx, pin, pinlen);
       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;
-      char *endp;
-
-      code = strtoul (line+10, &endp, 10);
-      line = endp;
+      line += 17;
       while (*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
     {
index 1adf8ba..b44dc21 100644 (file)
@@ -2329,7 +2329,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
   unsigned char key_grip_raw[20];
   char key_grip[41];
   unsigned char *buffer = NULL;
-  unsigned int buffer_n;
+  size_t buffer_n;
   char *description = NULL;
   char *comment = NULL;
   unsigned int i;
@@ -2821,32 +2821,28 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
 
 /* Start serving client on SOCK_CLIENT.  */
 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;
   gpg_error_t err;
   int ret;
 
   /* Setup control structure.  */
-
-  memset (&ctrl, 0, sizeof (ctrl));
-  agent_init_default_ctrl (&ctrl);
-  ctrl.connection_fd = sock_client;
+  ctrl->connection_fd = sock_client;
 
   /* Because the ssh protocol does not send us information about the
      the current TTY setting, we resort here to use those from startup
      or those explictly set.  */
-  if (!ctrl.display && opt.startup_display)
-    ctrl.display = strdup (opt.startup_display);
-  if (!ctrl.ttyname && opt.startup_ttyname)
-    ctrl.ttyname = strdup (opt.startup_ttyname);
-  if (!ctrl.ttytype && opt.startup_ttytype)
-    ctrl.ttytype = strdup (opt.startup_ttytype);
-  if (!ctrl.lc_ctype && opt.startup_lc_ctype)
-    ctrl.lc_ctype = strdup (opt.startup_lc_ctype);
-  if (!ctrl.lc_messages && opt.startup_lc_messages)
-    ctrl.lc_messages = strdup (opt.startup_lc_messages);
+  if (!ctrl->display && opt.startup_display)
+    ctrl->display = strdup (opt.startup_display);
+  if (!ctrl->ttyname && opt.startup_ttyname)
+    ctrl->ttyname = strdup (opt.startup_ttyname);
+  if (!ctrl->ttytype && opt.startup_ttytype)
+    ctrl->ttytype = strdup (opt.startup_ttytype);
+  if (!ctrl->lc_ctype && opt.startup_lc_ctype)
+    ctrl->lc_ctype = strdup (opt.startup_lc_ctype);
+  if (!ctrl->lc_messages && opt.startup_lc_messages)
+    ctrl->lc_messages = strdup (opt.startup_lc_messages);
 
 
   /* Create stream from socket.  */
@@ -2870,20 +2866,14 @@ start_command_handler_ssh (int sock_client)
     }
 
   /* 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. */
-  agent_reset_scd (&ctrl);
+  agent_reset_scd (ctrl);
 
 
  out:
   if (stream_sock)
     es_fclose (stream_sock);
-
-  free (ctrl.display);
-  free (ctrl.ttyname);
-  free (ctrl.ttytype);
-  free (ctrl.lc_ctype);
-  free (ctrl.lc_messages);
 }
index d28dd7c..63f41c3 100644 (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
-   piper server, otherwise it is a regular server */
+/* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
+   simple piper server, otherwise it is a regular server.  CTRL is the
+   control structure for this connection; it has only the basic
+   intialization. */
 void
-start_command_handler (int listen_fd, int fd)
+start_command_handler (ctrl_t ctrl, int listen_fd, int fd)
 {
   int rc;
   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)
     {
       int filedes[2];
@@ -1468,7 +1466,7 @@ start_command_handler (int listen_fd, int fd)
   else 
     {
       rc = assuan_init_socket_server_ext (&ctx, fd, 2);
-      ctrl.connection_fd = fd;
+      ctrl->connection_fd = fd;
     }
   if (rc)
     {
@@ -1484,12 +1482,12 @@ start_command_handler (int listen_fd, int fd)
       agent_exit (2);
     }
 
-  assuan_set_pointer (ctx, &ctrl);
-  ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
-  ctrl.server_local->assuan_ctx = ctx;
-  ctrl.server_local->message_fd = -1;
-  ctrl.server_local->use_cache_for_signing = 1;
-  ctrl.digest.raw_value = 0;
+  assuan_set_pointer (ctx, ctrl);
+  ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
+  ctrl->server_local->assuan_ctx = ctx;
+  ctrl->server_local->message_fd = -1;
+  ctrl->server_local->use_cache_for_signing = 1;
+  ctrl->digest.raw_value = 0;
 
   if (DBG_ASSUAN)
     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. */
-  agent_reset_scd (&ctrl);
+  agent_reset_scd (ctrl);
 
   /* Reset the pinentry (in case of popup messages). */
-  agent_reset_query (&ctrl);
+  agent_reset_query (ctrl);
 
+  /* Cleanup.  */
   assuan_deinit_server (ctx);
-  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);
-  xfree (ctrl.server_local);
+  xfree (ctrl->server_local);
+  ctrl->server_local = NULL;
 }
 
index 793bc91..75ffb70 100644 (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 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 int check_for_running_agent (int);
 
@@ -813,8 +816,21 @@ main (int argc, char **argv )
 
 
   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)
     ; /* NOTREACHED */
@@ -1073,8 +1089,8 @@ agent_exit (int rc)
 }
 
 
-void
-agent_init_default_ctrl (struct server_control_s *ctrl)
+static void
+agent_init_default_ctrl (ctrl_t ctrl)
 {
   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
    obviously not thread-safe and should only be called from the PTH
    signal handler. 
@@ -1437,17 +1468,20 @@ handle_signal (int signo)
 static void *
 start_connection_thread (void *arg)
 {
-  int fd = (int)arg;
+  ctrl_t ctrl = arg;
 
+  agent_init_default_ctrl (ctrl);
   if (opt.verbose)
     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)
     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;
 }
 
@@ -1456,17 +1490,20 @@ start_connection_thread (void *arg)
 static void *
 start_connection_thread_ssh (void *arg)
 {
-  int fd = (int)arg;
+  ctrl_t ctrl = arg;
 
+  agent_init_default_ctrl (ctrl);
   if (opt.verbose)
     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)
     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;
 }
 
@@ -1584,24 +1621,35 @@ handle_connections (int listen_fd, int listen_fd_ssh)
 
       if (FD_ISSET (listen_fd, &read_fdset))
        {
+          ctrl_t ctrl;
+
           plen = sizeof paddr;
          fd = pth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
          if (fd == -1)
            {
              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 
             {
               char threadname[50];
+
               snprintf (threadname, sizeof threadname-1,
                         "conn fd=%d (gpg)", fd);
               threadname[sizeof threadname -1] = 0;
               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",
                              strerror (errno) );
                   close (fd);
+                  xfree (ctrl);
                 }
             }
           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))
        {
+          ctrl_t ctrl;
+
           plen = sizeof paddr;
          fd = pth_accept (listen_fd_ssh, (struct sockaddr *)&paddr, &plen);
          if (fd == -1)
            {
              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
             {
               char threadname[50];
+
+              agent_init_default_ctrl (ctrl);
               snprintf (threadname, sizeof threadname-1,
                         "conn fd=%d (ssh)", fd);
               threadname[sizeof threadname -1] = 0;
               pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
-
-              if (!pth_spawn (tattr, start_connection_thread_ssh, (void*)fd))
+              ctrl->thread_startup.fd = fd;
+              if (!pth_spawn (tattr, start_connection_thread_ssh, ctrl) )
                 {
                   log_error ("error spawning ssh connection handler: %s\n",
                              strerror (errno) );
                   close (fd);
+                  xfree (ctrl);
                 }
             }
           fd = -1;
index 2da1180..25a38b9 100644 (file)
@@ -888,7 +888,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
   gcry_free (plain);
   gcry_free (cram_buffer);
   log_error ("encryptedData error at \"%s\", offset %u\n",
-             where, (p - p_start)+startoffset);
+             where, (unsigned int)((p - p_start)+startoffset));
   if (bad_pass)
     {
       /* 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);
   log_error ( "data error at \"%s\", offset %u\n",
-              where, (p - buffer) + startoffset);
+              where, (unsigned int)((p - buffer) + startoffset));
   if (r_consumed)
     *r_consumed = consumed;
   return NULL;
@@ -1309,7 +1309,8 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
   gcry_free (cram_buffer);
   return result;
  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)
     {
       int i;
index 19f6ccb..2bb38f3 100644 (file)
@@ -861,7 +861,7 @@ make_shadow_info (const char *serialno, const char *idstring)
   p = stpcpy (p, numbuf);
   for (s=serialno; *s && s[1]; s += 2)
     *(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, idstring);
   *p++ = ')';
index 2636c08..8a20b1a 100755 (executable)
@@ -93,7 +93,55 @@ if test "$1" = "--build-w32"; then
 fi
 # ***** 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
index 25af948..5ff12da 100644 (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>
 
        * Makefile.am (t_convert_DEPENDENCIES): Add libcommon.  From
index e056cb7..e00191e 100644 (file)
@@ -46,6 +46,9 @@
 #endif
 
 #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>
 #endif
 
@@ -59,6 +62,7 @@ void *memrchr (const void *block, int c, size_t size);
 
 #include <estream.h>
 
+
 \f
 
 /* 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_free_t) (void *mem);
 
+#ifdef HAVE_FOPENCOOKIE
+typedef ssize_t my_funopen_hook_ret_t;
+#else
+typedef int     my_funopen_hook_ret_t;
+#endif
+
+
 \f
 
 /* Buffer management layer.  */
@@ -1651,7 +1662,7 @@ doreadline (estream_t ES__RESTRICT stream, size_t max_length,
 
 /* Helper for esprint. */
 #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)
 {
   estream_t stream = cookie_arg;
index 113d35b..c017026 100644 (file)
@@ -271,7 +271,7 @@ fd_cache_close (const char *fname, FILEP_OR_FD fp)
       close (fp);
 #endif
       if (DBG_IOBUF)
-       log_debug ("fd_cache_close (%p) real\n", (void *) fp);
+       log_debug ("fd_cache_close (%d) real\n", fp);
       return;
     }
   /* try to reuse a slot */
index 65e7d47..6834089 100644 (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>
 
        * stringhelp.c (memrchr) [!HAVE_MEMRCHR]: Provide a replacement.
@@ -5,7 +10,7 @@
 2006-09-27  Werner Koch  <wk@g10code.com>
 
        * 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.
 
        * stringhelp.h (isascii): New.
index dce5ab2..0df4422 100644 (file)
 #define USE_FUNWRITER 1
 #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 int log_socket = -1;
 static char prefix_buffer[80];
@@ -111,7 +118,7 @@ writen (int fd, const void *buffer, size_t nbytes)
 }
 
 
-static in
+static my_funopen_hook_ret_
 fun_writer (void *cookie_arg, const char *buffer, size_t size)
 {
   struct fun_cookie_s *cookie = cookie_arg;
index 52962ea..bb1a38a 100644 (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>
 
        * keybox-search.c (blob_x509_has_grip, has_keygrip): New.
index 19d3560..73d10e3 100644 (file)
@@ -367,7 +367,7 @@ dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image)
       u = &info->uids;
       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;
         }
       while (u);
index 4b034d7..20bb2c8 100644 (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>
 
        * libassuan.m4: Updated from libassuan SVN.
index 00db177..4afdcc4 100644 (file)
@@ -91,6 +91,7 @@ AC_DEFUN([GNUPG_PATH_PTH],
   fi
   AC_PATH_PROG(PTH_CONFIG, pth-config, no)
   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 "$PTH_CONFIG" != "no"; then
     GNUPG_PTH_VERSION_CHECK($tmp)
index f637e5a..3c1c373 100644 (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>
 
        * scdaemon.h (GCRY_MD_USER_TLS_MD5SHA1): New.
index 242849a..e83ce3c 100644 (file)
@@ -222,6 +222,11 @@ static char (* DLSTDCALL CT_close) (unsigned short ctn);
 #define PCSC_E_READER_UNAVAILABLE      0x80100017
 #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
 {
@@ -739,7 +744,7 @@ pcsc_error_to_sw (long ec)
 {
   int rc;
 
-  switch (ec)
+  switch ( PCSC_ERR_MASK (ec) )
     {
     case 0:  rc = 0; break;
 
@@ -834,7 +839,8 @@ reset_pcsc_reader (int slot)
       sw = SW_HOST_GENERAL_ERROR;
       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)
     {
       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;
     }
   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)
     {
       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;
     }
   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)
     {
       log_error ("pcsc_transmit failed: %s (0x%lx)\n",
@@ -1283,7 +1291,8 @@ close_pcsc_reader (int slot)
       goto command_failed;
     }
   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)
     log_error ("pcsc_close failed: %s (0x%lx)\n",
                pcsc_error_string (err), err);
@@ -1470,7 +1479,8 @@ open_pcsc_reader (const char *portstr)
                  (unsigned long)len);
       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)
     {
       log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err));
index 466f37c..6c2eb82 100644 (file)
@@ -1291,27 +1291,52 @@ verify_chv2 (app_t app,
     {
       char *pinvalue;
       iso7816_pininfo_t pininfo;
+      int did_keypad = 0;
 
       memset (&pininfo, 0, sizeof pininfo);
       pininfo.mode = 1;
       pininfo.minlen = 6;
 
-      rc = pincb (pincb_arg, "PIN", &pinvalue); 
-      if (rc)
+      if (!opt.disable_keypad
+          && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
         {
-          log_info (_("PIN callback returned error: %s\n"), gpg_strerror (rc));
-          return rc;
+          /* The reader supports the verify command through the keypad. */
+          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);
         }
-
-      if (strlen (pinvalue) < 6)
+      else
         {
-          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);
+          /* 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));
         }
 
-      rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
       if (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;
 
-      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));
           if (gpg_err_code (rc) == GPG_ERR_BAD_PIN)
index f11de59..4752262 100644 (file)
@@ -692,7 +692,8 @@ read_ef_odf (app_t app, unsigned short odf_fid)
     }
 
   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);
   return 0;
index e990f75..35fedfd 100644 (file)
@@ -200,7 +200,8 @@ enum {
   VENDOR_CHERRY = 0x046a,
   VENDOR_SCM    = 0x04e6,
   VENDOR_OMNIKEY= 0x076b,
-  VENDOR_GEMPC  = 0x08e6
+  VENDOR_GEMPC  = 0x08e6,
+  VENDOR_KAAN   = 0x0d46
 };
 
 /* 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);
       if (fd == -1)
         {
-          log_debug ("failed to open `%s': %s\n",
+          DEBUGOUT_2 ("failed to open `%s': %s\n",
                      transports[i].name, strerror (errno));
           continue;
         }
-      log_debug ("opened `%s': fd=%d\n", transports[i].name, fd);
 
       rid = malloc (strlen (transports[i].name) + 30 + 10);
       if (!rid)
@@ -1047,7 +1047,6 @@ scan_or_find_devices (int readerno, const char *readerid,
         }
       free (rid);
       close (fd);
-      log_debug ("closed fd %d\n", fd);
     }
 
   if (scan_mode)
@@ -1208,10 +1207,7 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid)
       if (idev)
         usb_close (idev);
       if (dev_fd != -1)
-        {
-          close (dev_fd);
-          log_debug ("closed fd %d\n", dev_fd);
-        }
+        close (dev_fd);
       free (*handle);
       *handle = NULL;
     }
@@ -1254,7 +1250,6 @@ do_close_reader (ccid_driver_t handle)
   if (handle->dev_fd != -1)
     {
       close (handle->dev_fd);
-      log_debug ("closed fd %d\n", handle->dev_fd);
       handle->dev_fd = -1;
     }
 }
@@ -1324,10 +1319,7 @@ ccid_shutdown_reader (ccid_driver_t handle)
         usb_close (handle->idev);
       handle->idev = NULL;
       if (handle->dev_fd != -1)
-        {
-          close (handle->dev_fd);
-          log_debug ("closed fd %d\n", handle->dev_fd);
-        }
+        close (handle->dev_fd);
       handle->dev_fd = -1;
     }
 
@@ -2369,10 +2361,24 @@ ccid_transceive_secure (ccid_driver_t handle,
       || pinlen_min > pinlen_max)
     return CCID_DRIVER_ERR_INV_VALUE;
 
-  /* We have only tested this with an SCM reader so better don't risk
-     anything and do not allow the use with other readers. */
-  if (handle->id_vendor != VENDOR_SCM)
-    return CCID_DRIVER_ERR_NOT_SUPPORTED;
+  /* We have only tested a few readers so better don't risk anything
+     and do not allow the use with other readers. */
+  switch (handle->id_vendor)
+    {
+    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)
     return 0; /* Success */
@@ -2390,7 +2396,7 @@ ccid_transceive_secure (ccid_driver_t handle,
   msg[0] = PC_to_RDR_Secure;
   msg[5] = 0; /* slot */
   msg[6] = seqno = handle->seqno++;
-  msg[7] = 4; /* bBWI */
+  msg[7] = 0; /* bBWI */
   msg[8] = 0; /* RFU */
   msg[9] = 0; /* RFU */
   msg[10] = 0; /* Perform PIN verification. */
@@ -2411,8 +2417,8 @@ ccid_transceive_secure (ccid_driver_t handle,
       msg[14] = 0x00; /* bmPINLengthFormat:
                          Units are bytes, position is 0. */
     }
-  msg[15] = pinlen_min;   /* wPINMaxExtraDigit-Minimum.  */
-  msg[16] = pinlen_max;   /* wPINMaxExtraDigit-Maximum.  */
+  msg[15] = pinlen_max;   /* wPINMaxExtraDigit-Maximum.  */
+  msg[16] = pinlen_min;   /* wPINMaxExtraDigit-Minimum.  */
   msg[17] = 0x02; /* bEntryValidationCondition:
                      Validation key pressed */
   if (pinlen_min && pinlen_max && pinlen_min == pinlen_max)
@@ -2424,13 +2430,14 @@ ccid_transceive_secure (ccid_driver_t handle,
   /* bTeoProlog follows: */
   msg[22] = handle->nonnull_nad? ((1 << 4) | 0): 0;
   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:  */
   msg[25] = apdu_buf[0]; /* CLA */
   msg[26] = apdu_buf[1]; /* INS */
   msg[27] = apdu_buf[2]; /* P1 */
   msg[28] = apdu_buf[3]; /* P2 */
   msglen = 29;
+  /* An EDC is not required. */
   set_msg_len (msg, msglen - 10);
 
   DEBUGOUT ("sending");
@@ -2444,12 +2451,30 @@ ccid_transceive_secure (ccid_driver_t handle,
   
   msg = recv_buffer;
   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)
     return rc;
   
   tpdu = msg + 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) 
     {
@@ -2595,7 +2620,7 @@ main (int argc, char **argv)
 {
   int rc;
   ccid_driver_t ccid;
-  unsigned int slotstat;
+  int slotstat;
   unsigned char result[512];
   size_t resultlen;
   int no_pinpad = 0;
@@ -2623,7 +2648,7 @@ main (int argc, char **argv)
         }
       else if ( !strcmp (*argv, "--debug"))
         {
-          ccid_set_debug_level (1);
+          ccid_set_debug_level (ccid_set_debug_level (-1)+1);
           argc--; argv++;
         }
       else if ( !strcmp (*argv, "--no-poll"))
index 5116461..0dbd32d 100644 (file)
@@ -721,6 +721,31 @@ pin_cb (void *opaque, const char *info, char **retstr)
   unsigned char *value;
   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;
   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
    server, otherwise it is a regular server. */
 void
-scd_command_handler (int fd)
+scd_command_handler (ctrl_t ctrl, int fd)
 {
   int rc;
   assuan_context_t ctx;
-  struct server_control_s ctrl;
-
-  memset (&ctrl, 0, sizeof ctrl);
-  scd_init_default_ctrl (&ctrl);
   
   if (fd == -1)
     {
@@ -1622,20 +1643,20 @@ scd_command_handler (int fd)
 
   /* Allocate and initialize the server object.  Put it into the list
      of active sessions. */
-  ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
-  ctrl.server_local->next_session = session_list;
-  session_list = ctrl.server_local;
-  ctrl.server_local->ctrl_backlink = &ctrl;
-  ctrl.server_local->assuan_ctx = ctx;
+  ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
+  ctrl->server_local->next_session = session_list;
+  session_list = ctrl->server_local;
+  ctrl->server_local->ctrl_backlink = ctrl;
+  ctrl->server_local->assuan_ctx = ctx;
 
   if (DBG_ASSUAN)
     assuan_set_log_stream (ctx, log_get_stream ());
 
   /* We open the reader right at startup so that the ticker is able to
      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. */
@@ -1661,23 +1682,24 @@ scd_command_handler (int fd)
     }
 
   /* Cleanup.  */
-  do_reset (&ctrl, 0); 
+  do_reset (ctrl, 0); 
 
   /* Release the server object.  */
-  if (session_list == ctrl.server_local)
-    session_list = ctrl.server_local->next_session;
+  if (session_list == ctrl->server_local)
+    session_list = ctrl->server_local->next_session;
   else
     {
       struct server_local_s *sl;
       
       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;
       if (!sl->next_session)
           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.  */
   assuan_deinit_server (ctx);
index 250ee40..943961d 100644 (file)
@@ -235,7 +235,7 @@ iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo)
   sw = apdu_check_keypad (slot, command, 
                           pininfo->mode, pininfo->minlen, pininfo->maxlen,
                           pininfo->padlen);
-  return map_sw (sw);
+  return iso7816_map_sw (sw);
 }
 
 
index 0ee3f4b..6993b75 100644 (file)
@@ -600,7 +600,7 @@ main (int argc, char **argv )
       printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE );
 #endif
       printf ("allow-admin:%lu:\n", GC_OPT_FLAG_NONE );
-
+      printf ("disable-keypad:%lu:\n", GC_OPT_FLAG_NONE );
 
       scd_exit (0);
     }
@@ -615,6 +615,7 @@ main (int argc, char **argv )
   if (pipe_server)
     { 
       /* This is the simple pipe based server */
+      ctrl_t ctrl;
       pth_attr_t tattr;
       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_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",
                      strerror (errno) );
+          xfree (ctrl);
           scd_exit (2);
         }
 
@@ -810,12 +820,18 @@ scd_exit (int rc)
 }
 
 
-void
+static void
 scd_init_default_ctrl (ctrl_t ctrl)
 {
   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
    process.  If no socket is available, return NULL. */
@@ -1007,23 +1023,26 @@ create_server_socket (int is_standard_name, const char *name)
 static void *
 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"), fd);
+    log_info (_("handler for fd %d started\n"), ctrl->thread_startup.fd);
 
-  scd_command_handler (fd);
+  scd_command_handler (ctrl, ctrl->thread_startup.fd);
 
   if (opt.verbose)
-    log_info (_("handler for fd %d terminated\n"), fd);
+    log_info (_("handler for fd %d terminated\n"), ctrl->thread_startup.fd);
 
   /* If this thread is the pipe connection thread, flag that a
      shutdown is required.  With the next ticker event and given that
      no other connections are running the shutdown will then
      happen. */
-  if (fd == -1)
+  if (ctrl->thread_startup.fd == -1)
     shutdown_pending = 1;
   
+  scd_deinit_default_ctrl (ctrl);
+  xfree (ctrl);
   return NULL;
 }
 
@@ -1137,23 +1156,33 @@ handle_connections (int listen_fd)
 
       if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
        {
+          ctrl_t ctrl;
+
           plen = sizeof paddr;
          fd = pth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
          if (fd == -1)
            {
              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
             {
               char threadname[50];
+
               snprintf (threadname, sizeof threadname-1, "conn fd=%d", fd);
               threadname[sizeof threadname -1] = 0;
               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",
                              strerror (errno) );
+                  xfree (ctrl);
                   close (fd);
                 }
             }
index 2d20b02..7e5b9fb 100644 (file)
@@ -90,6 +90,12 @@ struct app_ctx_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. */
   struct server_local_s *server_local;
 
@@ -115,11 +121,10 @@ typedef struct app_ctx_s *app_t;
 
 /*-- scdaemon.c --*/
 void scd_exit (int rc);
-void scd_init_default_ctrl (ctrl_t ctrl);
 const char *scd_get_socket_name (void);
 
 /*-- command.c --*/
-void scd_command_handler (int);
+void scd_command_handler (ctrl_t, int);
 void send_status_info (ctrl_t ctrl, const char *keyword, ...)
      GNUPG_GCC_A_SENTINEL(1);
 void scd_update_reader_status_file (void);
index 0688bf1..5518b6c 100644 (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>
 
        * signencrypt.test: Need to prepend srcdir to the file name
index dac3df5..070a083 100644 (file)
@@ -100,7 +100,7 @@ data-80000:
 plain-large:
        cat $(srcdir)/../../doc/HACKING \
            $(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
 random_seed:
index 435c397..34bba91 100644 (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>
 
        * symcryptrun.c: Include signal.h and include pth.h only if test
index 65cdc0a..d88c967 100644 (file)
@@ -530,7 +530,7 @@ static gc_option_t gc_options_scdaemon[] =
    { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
      "gnupg", "do not use the internal CCID driver",
      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",
      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },