dirmngr (16 files)

cvs user wk cvs at cvs.gnupg.org
Fri Nov 19 16:21:14 CET 2004


    Date: Friday, November 19, 2004 @ 16:27:28
  Author: wk
    Path: /cvs/dirmngr/dirmngr

Modified: ChangeLog configure.ac src/ChangeLog src/certcache.c
          src/certcache.h src/crlcache.c src/crlcache.h src/crlfetch.c
          src/crlfetch.h src/dirmngr-client.c src/dirmngr.c src/dirmngr.h
          src/ldap.c src/server.c src/validate.c src/validate.h

* configure.ac: Require libassuan 0.6.8.

* dirmngr-client.c (status_cb): New.  Use it in very verbose mode.

* server.c (start_command_handler): Malloc the control structure
and properly release it.  Removed the primary_connection
hack. Cleanup running wrappers.
(dirmngr_status): Return an error code.
(dirmngr_tick): Return an error code and detect a
cancellation. Use wall time and not CPU time.
* validate.c (validate_cert_chain): Add CTRL arg and changed callers.
* crlcache.c (crl_cache_isvalid): 
* crlfetch.c (ca_cert_fetch, start_cert_fetch, crl_fetch_default) 
(crl_fetch): Ditto.
* ldap.c (ldap_wrapper, run_ldap_wrapper, url_fetch_ldap) 
(attr_fetch_ldap, start_cert_fetch_ldap): Ditto. 
(ldap_wrapper_release_context): Reset the stored CTRL.
(reader_callback): Periodically call dirmngr_tick.
(ldap_wrapper_release_context): Print an error message for read
errors.
(ldap_wrapper_connection_cleanup): New.


----------------------+
 ChangeLog            |    4 ++
 configure.ac         |    2 -
 src/ChangeLog        |   22 +++++++++++
 src/certcache.c      |    2 -
 src/certcache.h      |    3 +
 src/crlcache.c       |    6 +--
 src/crlcache.h       |    3 +
 src/crlfetch.c       |   18 ++++-----
 src/crlfetch.h       |   22 +++++++----
 src/dirmngr-client.c |   15 ++++++-
 src/dirmngr.c        |    6 ++-
 src/dirmngr.h        |    5 +-
 src/ldap.c           |   98 ++++++++++++++++++++++++++++++++++++++++---------
 src/server.c         |   95 ++++++++++++++++++++++++++++-------------------
 src/validate.c       |    4 +-
 src/validate.h       |    3 +
 16 files changed, 219 insertions(+), 89 deletions(-)


Index: dirmngr/ChangeLog
diff -u dirmngr/ChangeLog:1.76 dirmngr/ChangeLog:1.77
--- dirmngr/ChangeLog:1.76	Tue Nov 16 19:24:36 2004
+++ dirmngr/ChangeLog	Fri Nov 19 16:27:28 2004
@@ -1,3 +1,7 @@
+2004-11-19  Werner Koch  <wk at g10code.com>
+
+	* configure.ac: Require libassuan 0.6.8.
+
 2004-11-15  Werner Koch  <wk at g10code.com>
 
 	* tests/show-multi.c: New.
Index: dirmngr/configure.ac
diff -u dirmngr/configure.ac:1.61 dirmngr/configure.ac:1.62
--- dirmngr/configure.ac:1.61	Tue Nov 16 19:24:36 2004
+++ dirmngr/configure.ac	Fri Nov 19 16:27:28 2004
@@ -29,7 +29,7 @@
 NEED_LIBGCRYPT_API=1
 NEED_LIBGCRYPT_VERSION=1.1.94
 
-NEED_LIBASSUAN_VERSION=0.6.5
+NEED_LIBASSUAN_VERSION=0.6.8
 
 NEED_KSBA_VERSION=0.9.6
 
Index: dirmngr/src/ChangeLog
diff -u dirmngr/src/ChangeLog:1.23 dirmngr/src/ChangeLog:1.24
--- dirmngr/src/ChangeLog:1.23	Thu Nov 18 20:15:33 2004
+++ dirmngr/src/ChangeLog	Fri Nov 19 16:27:28 2004
@@ -1,3 +1,25 @@
+2004-11-19  Werner Koch  <wk at g10code.com>
+
+	* dirmngr-client.c (status_cb): New.  Use it in very verbose mode.
+
+	* server.c (start_command_handler): Malloc the control structure
+	and properly release it.  Removed the primary_connection
+	hack. Cleanup running wrappers.
+	(dirmngr_status): Return an error code.
+	(dirmngr_tick): Return an error code and detect a
+	cancellation. Use wall time and not CPU time.
+	* validate.c (validate_cert_chain): Add CTRL arg and changed callers.
+	* crlcache.c (crl_cache_isvalid): 
+	* crlfetch.c (ca_cert_fetch, start_cert_fetch, crl_fetch_default) 
+	(crl_fetch): Ditto.
+	* ldap.c (ldap_wrapper, run_ldap_wrapper, url_fetch_ldap) 
+	(attr_fetch_ldap, start_cert_fetch_ldap): Ditto. 
+	(ldap_wrapper_release_context): Reset the stored CTRL.
+	(reader_callback): Periodically call dirmngr_tick.
+	(ldap_wrapper_release_context): Print an error message for read
+	errors.
+	(ldap_wrapper_connection_cleanup): New.
+
 2004-11-18  Werner Koch  <wk at g10code.com>
 
 	* dirmngr.c (main): Do not cd / if not running detached.
Index: dirmngr/src/certcache.c
diff -u dirmngr/src/certcache.c:1.3 dirmngr/src/certcache.c:1.4
--- dirmngr/src/certcache.c:1.3	Thu Nov 18 20:15:33 2004
+++ dirmngr/src/certcache.c	Fri Nov 19 16:27:28 2004
@@ -583,7 +583,7 @@
    and return it at R_CERT.  Returns 0 on success or
    GPG_ERR_NOT_FOUND.  */
 gpg_error_t
-find_issuing_cert (ksba_cert_t cert, ksba_cert_t *r_cert)
+find_issuing_cert (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t *r_cert)
 {
   gpg_error_t err;
   char *issuer_dn;
Index: dirmngr/src/certcache.h
diff -u dirmngr/src/certcache.h:1.2 dirmngr/src/certcache.h:1.3
--- dirmngr/src/certcache.h:1.2	Thu Nov 18 16:37:48 2004
+++ dirmngr/src/certcache.h	Fri Nov 19 16:27:28 2004
@@ -55,7 +55,8 @@
 /* Given the certificate CERT locate the issuer for this certificate
    and return it at R_CERT.  Returns 0 on success or
    GPG_ERR_NOT_FOUND.  */
-gpg_error_t find_issuing_cert (ksba_cert_t cert, ksba_cert_t *r_cert);
+gpg_error_t find_issuing_cert (ctrl_t ctrl,
+                               ksba_cert_t cert, ksba_cert_t *r_cert);
 
 
 
Index: dirmngr/src/crlcache.c
diff -u dirmngr/src/crlcache.c:1.47 dirmngr/src/crlcache.c:1.48
--- dirmngr/src/crlcache.c:1.47	Thu Nov 18 16:37:48 2004
+++ dirmngr/src/crlcache.c	Fri Nov 19 16:27:28 2004
@@ -1135,7 +1135,7 @@
    that invoking this function several times won't load the CRL over
    and over.  */
 crl_cache_result_t 
-crl_cache_isvalid (const char *issuer_hash, const char *serialno,
+crl_cache_isvalid (ctrl_t ctrl, const char *issuer_hash, const char *serialno,
                    int force_refresh)
 {
   crl_cache_t cache = get_current_cache ();
@@ -1282,7 +1282,7 @@
     log_debug ("certificate for CRL issuer not returned by caller"
                " - doing lookup\n");
 
-  err = ca_cert_fetch (issuer, &reader);
+  err = ca_cert_fetch (ctrl, issuer, &reader);
   if (err)
     {
       log_error (_("error fetching certificate for issuer: %s\n"),
@@ -1553,7 +1553,7 @@
                            gpg_strerror (err));
                 goto failure;
               }
-            err = validate_cert_chain (issuer_cert, NULL);
+            err = validate_cert_chain (ctrl, issuer_cert, NULL);
             if (err)
               {
                 log_error (_("error checking validity of CRL "
Index: dirmngr/src/crlcache.h
diff -u dirmngr/src/crlcache.h:1.22 dirmngr/src/crlcache.h:1.23
--- dirmngr/src/crlcache.h:1.22	Tue Nov 16 19:24:35 2004
+++ dirmngr/src/crlcache.h	Fri Nov 19 16:27:28 2004
@@ -56,7 +56,8 @@
 void crl_cache_deinit (void);
 int crl_cache_flush(void);
 
-crl_cache_result_t crl_cache_isvalid (const char *issuer_hash,
+crl_cache_result_t crl_cache_isvalid (ctrl_t ctrl,
+                                      const char *issuer_hash,
                                       const char *cert_id,
                                       int force_refresh);
 
Index: dirmngr/src/crlfetch.c
diff -u dirmngr/src/crlfetch.c:1.19 dirmngr/src/crlfetch.c:1.20
--- dirmngr/src/crlfetch.c:1.19	Tue Nov 16 19:24:35 2004
+++ dirmngr/src/crlfetch.c	Fri Nov 19 16:27:28 2004
@@ -34,7 +34,7 @@
    object in READER.  Note that this reader object should be closed
    only using ldap_close_reader. */
 gpg_error_t
-crl_fetch (const char *url, ksba_reader_t *reader)
+crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
 {
   gpg_error_t err;
   parsed_uri_t uri;
@@ -103,7 +103,7 @@
     {
       const char *s;
 
-      err = url_fetch_ldap (url, NULL, 0, reader);
+      err = url_fetch_ldap (ctrl, url, NULL, 0, reader);
 /*       if (err) */
 /*         { */
 /*           /\* If the function failed we try again using our default */
@@ -142,26 +142,26 @@
 /* Fetch CRL for ISSUER using a default server. Return the entire CRL
    as a newly opened stream returned in R_FP. */
 gpg_error_t
-crl_fetch_default (const char *issuer, ksba_reader_t *reader)
+crl_fetch_default (ctrl_t ctrl, const char *issuer, ksba_reader_t *reader)
 {
-  return  attr_fetch_ldap (issuer, "certificateRevocationList;binary",
-                           reader);
+  return attr_fetch_ldap (ctrl, issuer, "certificateRevocationList;binary",
+                          reader);
 }
 
 
 /* Fetch a CA certificate for DN using the default server. */
 int
-ca_cert_fetch (const char *dn, ksba_reader_t *reader)
+ca_cert_fetch (ctrl_t ctrl, const char *dn, ksba_reader_t *reader)
 {
-  return attr_fetch_ldap (dn, "cACertificate;binary", reader);
+  return attr_fetch_ldap (ctrl, dn, "cACertificate;binary", reader);
 }
 
 
 gpg_error_t
-start_cert_fetch (cert_fetch_context_t *context,
+start_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context,
                   strlist_t patterns, const ldap_server_t server)
 {
-  return start_cert_fetch_ldap (context, patterns, server);
+  return start_cert_fetch_ldap (ctrl, context, patterns, server);
 }
 
 gpg_error_t
Index: dirmngr/src/crlfetch.h
diff -u dirmngr/src/crlfetch.h:1.11 dirmngr/src/crlfetch.h:1.12
--- dirmngr/src/crlfetch.h:1.11	Tue Nov 16 19:24:35 2004
+++ dirmngr/src/crlfetch.h	Fri Nov 19 16:27:28 2004
@@ -31,18 +31,20 @@
 
 
 /* Fetch CRL from URL. */
-gpg_error_t crl_fetch (const char* url, ksba_reader_t *reader);
+gpg_error_t crl_fetch (ctrl_t ctrl, const char* url, ksba_reader_t *reader);
 
 /* Fetch CRL for ISSUER using default server. */
-gpg_error_t crl_fetch_default (const char* issuer, ksba_reader_t *reader);
+gpg_error_t crl_fetch_default (ctrl_t ctrl,
+                               const char* issuer, ksba_reader_t *reader);
 
 
 /* Fetch cert for DN. */
-int ca_cert_fetch (const char *dn, ksba_reader_t *reader);
+int ca_cert_fetch (ctrl_t ctrl, const char *dn, ksba_reader_t *reader);
 
 
 /* Query the server for certs matching patterns. */
-gpg_error_t start_cert_fetch (cert_fetch_context_t *context,
+gpg_error_t start_cert_fetch (ctrl_t ctrl,
+                              cert_fetch_context_t *context,
                               strlist_t patterns,
                               const ldap_server_t server);
 gpg_error_t fetch_next_cert(cert_fetch_context_t context,
@@ -57,14 +59,18 @@
 /*-- ldap.c --*/
 void *ldap_wrapper_thread (void*);
 void ldap_wrapper_release_context (ksba_reader_t reader);
+void ldap_wrapper_connection_cleanup (ctrl_t);
 
-gpg_error_t url_fetch_ldap (const char *url, const char *host, int port,
-                            ksba_reader_t *reader);
-gpg_error_t attr_fetch_ldap (const char *dn, const char *attr,
+gpg_error_t url_fetch_ldap (ctrl_t ctrl,
+                            const char *url, const char *host, int port,
                             ksba_reader_t *reader);
+gpg_error_t attr_fetch_ldap (ctrl_t ctrl,
+                             const char *dn, const char *attr,
+                             ksba_reader_t *reader);
 
 
-gpg_error_t start_cert_fetch_ldap(cert_fetch_context_t *context,
+gpg_error_t start_cert_fetch_ldap(ctrl_t ctrl,
+                                  cert_fetch_context_t *context,
                                   strlist_t patterns,
                                   const ldap_server_t server );
 gpg_error_t fetch_next_cert_ldap (cert_fetch_context_t context,
Index: dirmngr/src/dirmngr-client.c
diff -u dirmngr/src/dirmngr-client.c:1.2 dirmngr/src/dirmngr-client.c:1.3
--- dirmngr/src/dirmngr-client.c:1.2	Thu Nov 18 16:37:48 2004
+++ dirmngr/src/dirmngr-client.c	Fri Nov 19 16:27:28 2004
@@ -305,6 +305,15 @@
 }
 
 
+/* Print status line from the assuan protocol.  */
+static assuan_error_t
+status_cb (void *opaque, const char *line)
+{
+  if (opt.verbose > 2)
+    log_info (_("got status: `%s'\n"), line);
+  return 0;
+}
+
 /* Try to connect to the dirmngr via socket or fork it off and work by
    pipes.  Handle the server's initial greeting */
 static assuan_context_t
@@ -513,7 +522,7 @@
 
   ae = assuan_transact (ctx, opt.use_ocsp? "CHECKOCSP":"CHECKCRL", NULL, NULL,
                         inq_cert, &parm,
-                        NULL, NULL);
+                        status_cb, NULL);
   if (opt.verbose > 1)
     log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay");
   return map_assuan_err (ae);
@@ -534,7 +543,7 @@
 
   ae = assuan_transact (ctx, "CACHECERT", NULL, NULL,
                         inq_cert, &parm,
-                        NULL, NULL);
+                        status_cb, NULL);
   if (opt.verbose > 1)
     log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay");
   return map_assuan_err (ae);
@@ -555,7 +564,7 @@
 
   ae = assuan_transact (ctx, "VALIDATE", NULL, NULL,
                         inq_cert, &parm,
-                        NULL, NULL);
+                        status_cb, NULL);
   if (opt.verbose > 1)
     log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay");
   return map_assuan_err (ae);
Index: dirmngr/src/dirmngr.c
diff -u dirmngr/src/dirmngr.c:1.43 dirmngr/src/dirmngr.c:1.44
--- dirmngr/src/dirmngr.c:1.43	Thu Nov 18 20:15:33 2004
+++ dirmngr/src/dirmngr.c	Fri Nov 19 16:27:28 2004
@@ -862,14 +862,18 @@
   else if (cmd == aFetchCRL)
     {
       ksba_reader_t reader;
+      struct server_control_s ctrlbuf;
 
       if (argc != 1)
         wrong_args ("--fetch-crl URL");
 
+      memset (&ctrlbuf, 0, sizeof ctrlbuf);
+      dirmngr_init_default_ctrl (&ctrlbuf);
+
       launch_ripper_thread ();
       cert_cache_init ();
       crl_cache_init ();
-      rc = crl_fetch (argv[0], &reader);
+      rc = crl_fetch (&ctrlbuf, argv[0], &reader);
       if (rc)
         log_error (_("fetching CRL from `%s' failed: %s\n"),
                      argv[0], gpg_strerror (rc));
Index: dirmngr/src/dirmngr.h
diff -u dirmngr/src/dirmngr.h:1.19 dirmngr/src/dirmngr.h:1.20
--- dirmngr/src/dirmngr.h:1.19	Tue Nov 16 19:24:35 2004
+++ dirmngr/src/dirmngr.h	Fri Nov 19 16:27:28 2004
@@ -110,6 +110,7 @@
 struct server_local_s;
 
 struct server_control_s {
+  int refcount;      /* Count additional references to this object.  */
   int no_server;     /* We are not running under server control. */
   int status_fd;     /* Only for non-server mode. */
   struct server_local_s *server_local;
@@ -127,8 +128,8 @@
 ksba_cert_t get_cert_local (ctrl_t ctrl, const char *issuer);
 ksba_cert_t get_issuing_cert_local (ctrl_t ctrl, const char *issuer);
 void start_command_handler (int fd);
-void dirmngr_status (ctrl_t ctrl, const char *keyword, ...);
-void dirmngr_tick (ctrl_t ctrl);
+gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...);
+gpg_error_t dirmngr_tick (ctrl_t ctrl);
 
 
 #endif /*DIRMNGR_H*/
Index: dirmngr/src/ldap.c
diff -u dirmngr/src/ldap.c:1.34 dirmngr/src/ldap.c:1.35
--- dirmngr/src/ldap.c:1.34	Thu Nov 18 16:37:48 2004
+++ dirmngr/src/ldap.c	Fri Nov 19 16:27:28 2004
@@ -67,9 +67,13 @@
   struct wrapper_context_s *next;
 
   pid_t pid;    /* The pid of the wrapper process. */
+  int printable_pid; /* Helper to print diagnostics after the process has
+                        been cleaned up. */
   int fd;       /* Connected with stdout of the ldap wrapper.  */
-  int fd_error; /* Set to the errno of the last read error if any.  */
-  int log_fd;   /* Connected with stdoerr of the ldap wrapper.  */
+  gpg_error_t fd_error; /* Set to the gpg_error of the last read error
+                           if any.  */
+  int log_fd;   /* Connected with stderr of the ldap wrapper.  */
+  ctrl_t ctrl;  /* Connection data. */
   int ready;    /* Internally used to mark to be removed contexts. */
   ksba_reader_t reader; /* The ksba reader object or NULL. */
   char *line;     /* Used to print the log lines (malloced). */
@@ -341,13 +345,40 @@
             ctx->fd = -1;
             close (fd);
           }
+        if (ctx->ctrl)
+          {
+            ctx->ctrl->refcount--;
+            ctx->ctrl = NULL;
+          }
+        if (ctx->fd_error)
+          log_info (_("reading from ldap wrapper %d failed: %s\n"),
+                    ctx->printable_pid, gpg_strerror (ctx->fd_error));
         break;
       }
 }
 
+/* Cleanup all resources hel by the connection associated with
+   CTRL.  This is used after a cancel to kill running wrappers.  */
+void
+ldap_wrapper_connection_cleanup (ctrl_t ctrl)
+{
+  struct wrapper_context_s *ctx;
+
+  for (ctx=wrapper_list; ctx; ctx=ctx->next)
+    if (ctx->ctrl && ctx->ctrl == ctrl)
+      {
+        ctx->ctrl->refcount--;
+        ctx->ctrl = NULL;
+        if (ctx->pid != (pid_t)(-1))
+          kill (ctx->pid, SIGTERM);
+        if (ctx->fd_error)
+          log_info (_("reading from ldap wrapper %d failed: %s\n"),
+                    ctx->printable_pid, gpg_strerror (ctx->fd_error));
+      }
+}
 
 
-/* This is the callback used by the ldap wrapper to feed the ksab
+/* This is the callback used by the ldap wrapper to feed the ksba
    reader with the wrappers stdout.  See the description of
    ksba_reader_set_cb for details.  */
 static int 
@@ -356,7 +387,7 @@
   struct wrapper_context_s *ctx = cb_value;
   size_t nleft = count;
 
-  /* FIXME: We might want to add some internal buffering becuase the
+  /* FIXME: We might want to add some internal buffering because the
      ksba code does not not any buffering for itself (because a ksba
      reader may be detached from another stream to read other data and
      the it would be cumbersome to get back already buffered
@@ -366,7 +397,7 @@
     return -1; /* Rewind is not supported. */
 
   /* If we ever encountered a read error don't allow to continue and
-     possible overwrite the last error cause.  Bail out alos if the
+     possible overwrite the last error cause.  Bail out also if the
      file descriptor has been closed. */
   if (ctx->fd_error || ctx->fd == -1)
     {
@@ -376,26 +407,50 @@
 
   while (nleft > 0)
     {
-      int n = pth_read ( ctx->fd, buffer, nleft );
-      if (n < 0 && errno == EINTR)
-        n = 0;
+      int n;
+      pth_event_t evt;
+      gpg_error_t err;
+
+      evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0) );
+      n = pth_read_ev ( ctx->fd, buffer, nleft, evt);
+      if (n < 0 && evt && pth_event_occurred (evt) )
+        {
+          n = 0;
+          err = dirmngr_tick (ctx->ctrl);
+          if (err)
+            {
+              ctx->fd_error = err;
+              close (ctx->fd);
+              ctx->fd = -1;
+              if (evt)
+                pth_event_free (evt, PTH_FREE_THIS);
+              return -1;
+            }
+
+        }
       else if (n < 0)
         {
-          ctx->fd_error = errno;
+          ctx->fd_error = gpg_error_from_errno (errno);
           close (ctx->fd);
           ctx->fd = -1;
+          if (evt)
+            pth_event_free (evt, PTH_FREE_THIS);
           return -1;
         }
       else if (!n)
         {
           if (nleft == count)
             {
+              if (evt)
+                pth_event_free (evt, PTH_FREE_THIS);
               return -1; /* EOF. */
             }
           break; 
         }
       nleft -= n;
       buffer += n;
+      if (evt)
+        pth_event_free (evt, PTH_FREE_THIS);
     }
   *nread = count - nleft;
 
@@ -439,7 +494,7 @@
    that confidential.
   */
 static gpg_error_t
-ldap_wrapper (ksba_reader_t *reader, const char *argv[])
+ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[])
 {
   gpg_error_t err;
   pid_t pid;
@@ -570,8 +625,11 @@
       return err;
     }
   ctx->pid = pid;
+  ctx->printable_pid = (int)pid;
   ctx->fd = rp[0];
   ctx->log_fd = rp2[0];
+  ctx->ctrl = ctrl;
+  ctrl->refcount++;
 
   err = ksba_reader_new (reader);
   if (!err)
@@ -599,7 +657,8 @@
 /* Perform an LDAP query.  Returns an gpg error code or 0 on success.
    The function returns a new stream at R_FP. */
 static gpg_error_t
-run_ldap_wrapper (const char *host, int port, 
+run_ldap_wrapper (ctrl_t ctrl, 
+                  const char *host, int port, 
                   const char *user, const char *pass,
                   const char *dn, const char *filter, const char *attr,
                   const char *url,
@@ -653,7 +712,7 @@
   argv[argc++] = url? url : "ldap://";
   argv[argc] = NULL;
     
-  return ldap_wrapper (reader, argv);
+  return ldap_wrapper (ctrl, reader, argv);
 }
 
 
@@ -663,10 +722,11 @@
    reader is returned.  If HOST or PORT ar not 0, they are used to
    override the values from the URL. */
 gpg_error_t
-url_fetch_ldap (const char *url, const char *host, int port,
+url_fetch_ldap (ctrl_t ctrl, const char *url, const char *host, int port,
                 ksba_reader_t *reader)
 {
-  return run_ldap_wrapper (host, port,
+  return run_ldap_wrapper (ctrl,
+                           host, port,
                            NULL, NULL,
                            NULL, NULL, NULL, url,
                            reader);
@@ -684,7 +744,8 @@
 /* Perform an LDAP query on all configured servers.  On error the
    error code of the last try is returned.  */
 gpg_error_t
-attr_fetch_ldap (const char *dn, const char *attr, ksba_reader_t *reader)
+attr_fetch_ldap (ctrl_t ctrl,
+                 const char *dn, const char *attr, ksba_reader_t *reader)
 {
   struct ldap_server_s *server;
   gpg_error_t err = gpg_error (GPG_ERR_CONFIGURATION);
@@ -692,7 +753,8 @@
   *reader = NULL;
   for (server = opt.ldapservers; server; server = server->next)
     {
-      err = run_ldap_wrapper (server->host, server->port,
+      err = run_ldap_wrapper (ctrl,
+                              server->host, server->port,
                               server->user, server->pass,
                               dn, "objectClass=*", attr, NULL,
                               reader);
@@ -878,7 +940,7 @@
    the SERVER.  This function retruns an error code or 0 and a CONTEXT
    on success. */
 gpg_error_t
-start_cert_fetch_ldap (cert_fetch_context_t *context,
+start_cert_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *context,
                        strlist_t patterns, const ldap_server_t server)
 {
   gpg_error_t err;
@@ -973,7 +1035,7 @@
   if (!*context)
     return gpg_error_from_errno (errno);
 
-  err = ldap_wrapper (&(*context)->reader, argv);
+  err = ldap_wrapper (ctrl, &(*context)->reader, argv);
 
   if (err)
     {
Index: dirmngr/src/server.c
diff -u dirmngr/src/server.c:1.44 dirmngr/src/server.c:1.45
--- dirmngr/src/server.c:1.44	Thu Nov 18 16:37:48 2004
+++ dirmngr/src/server.c	Fri Nov 19 16:27:28 2004
@@ -47,14 +47,9 @@
 #define PARM_ERROR(t) assuan_set_error (ctx, ASSUAN_Parameter_Error, (t))
 
 
-/* We keep track of the primary client using us.  This is mainly a
-   hack to send the progress info back. */
-static ctrl_t primary_connection;
-
 /* Data used to associate an Assuan context with local server data */
 struct server_local_s {
   ASSUAN_CONTEXT assuan_ctx;
-  int message_fd;
 };
 
 
@@ -237,7 +232,7 @@
       ksba_name_release (issuername); issuername = NULL;
       any_dist_point = 1;
       
-      err = crl_fetch (distpoint_uri, &reader);
+      err = crl_fetch (ctrl, distpoint_uri, &reader);
       if (err)
         {
           log_error (_("crl_fetch via DP failed: %s\n"), gpg_strerror (err));
@@ -275,7 +270,7 @@
           goto leave;
         }
 
-      err = crl_fetch_default (issuer, &reader);
+      err = crl_fetch_default (ctrl, issuer, &reader);
       if (err)
           {
             log_error (_("crl_fetch via issuer failed: %s\n"),
@@ -434,7 +429,8 @@
     }
   else
     {
-      switch (crl_cache_isvalid (issuerhash, serialno,
+      switch (crl_cache_isvalid (ctrl,
+                                 issuerhash, serialno,
                                  ctrl->force_crl_refresh))
         {
         case CRL_CACHE_VALID:
@@ -643,7 +639,8 @@
     int reloaded = 0;
 
   again:
-    switch (crl_cache_isvalid (issuerhash_hex, serialno,
+    switch (crl_cache_isvalid (ctrl,
+                               issuerhash_hex, serialno,
                                ctrl->force_crl_refresh))
       {
       case CRL_CACHE_VALID:
@@ -729,6 +726,7 @@
 static int
 cmd_lookup (assuan_context_t ctx, char *line)
 {
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   gpg_error_t err = 0;
   assuan_error_t ae;
   char *p;
@@ -775,7 +773,7 @@
                    ldapserver->base?ldapserver->base : "[default]");
 
       /* Fetch certificates matching pattern */
-      err = start_cert_fetch (&fetch_context, list, ldapserver);
+      err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
       if (err)
         {
           log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
@@ -1003,7 +1001,7 @@
   if(err)
     goto leave;
 
-  err = validate_cert_chain (cert, NULL);
+  err = validate_cert_chain (ctrl, cert, NULL);
 
  leave:
   if (err)
@@ -1053,10 +1051,20 @@
 {
   int rc;
   assuan_context_t ctx;
-  struct server_control_s ctrl;
+  ctrl_t ctrl;
 
-  memset (&ctrl, 0, sizeof ctrl);
-  dirmngr_init_default_ctrl (&ctrl);
+  ctrl = xtrycalloc (1, sizeof *ctrl);
+  if (ctrl)
+    ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
+  if (!ctrl || !ctrl->server_local)
+    {
+      log_error (_("can't allocate control structure: %s\n"),
+                 strerror (errno));
+      xfree (ctrl);
+      return;
+    }
+    
+  dirmngr_init_default_ctrl (ctrl);
 
   if (fd == -1)
     {
@@ -1088,17 +1096,12 @@
   assuan_set_hello_line (ctx, "Dirmngr " VERSION " at your service");
   assuan_register_option_handler (ctx, option_handler);
 
-  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->assuan_ctx = ctx;
+  assuan_set_pointer (ctx, ctrl);
 
   if (DBG_ASSUAN)
     assuan_set_log_stream (ctx, log_get_stream ());
 
-  if (!primary_connection)
-    primary_connection = &ctrl;
-
   for (;;) 
     {
       rc = assuan_accept (ctx);
@@ -1118,20 +1121,29 @@
         }
     }
   
-  if (primary_connection == &ctrl)
-    primary_connection = NULL;
-
+  ldap_wrapper_connection_cleanup (ctrl);
 
+  ctrl->server_local->assuan_ctx = NULL;
   assuan_deinit_server (ctx);
+
+  if (ctrl->refcount)
+    log_error ("oops: connection control structure still referenced (%d)\n",
+               ctrl->refcount);
+  else
+    {
+      xfree (ctrl->server_local);
+      xfree (ctrl);
+    }
 }
 
 
 /* Send a status line back to the client.  KEYWORD is the status
    keyword, the optioal string argumenst are blank separated added to
    the line, the last argument must be a NULL. */
-void
+gpg_error_t
 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
 {
+  gpg_error_t err = 0;
   va_list arg_ptr;
   const char *text;
 
@@ -1156,34 +1168,41 @@
             *p++ = *text++;
         }
       *p = 0;
-      assuan_write_status (ctx, keyword, buf);
+      err = map_assuan_err (assuan_write_status (ctx, keyword, buf));
     }
 
   va_end (arg_ptr);
+  return err;
 }
 
 
 /* Note, that we ignore CTRL for now but use the first connection to
    send the progress info back. */
-void
+gpg_error_t
 dirmngr_tick (ctrl_t ctrl)
 {
-  static clock_t next_tick = 0;
-  clock_t now = clock ();
+  static time_t next_tick = 0;
+  gpg_error_t err = 0;
+  time_t now = time (NULL);
 
   if (!next_tick)
     {
-      next_tick = now + CLOCKS_PER_SEC;
-      if (next_tick < now)
-        next_tick = 0;
+      next_tick = now + 1;
     }
   else if ( now > next_tick )
     {
-      next_tick = now + CLOCKS_PER_SEC;
-      if (next_tick < now)
-        next_tick = 0;
-      
-      if (primary_connection)
-        dirmngr_status (primary_connection, "PROGRESS", "tick", "? 0 0", NULL);
+      if (ctrl)
+        {
+          err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
+          if (err)
+            {
+              /* Take this as in indication for a cancel request.  */
+              err = gpg_error (GPG_ERR_CANCELED);
+            }
+          now = time (NULL);
+        }
+
+      next_tick = now + 1;
     }
+  return err;
 }
Index: dirmngr/src/validate.c
diff -u dirmngr/src/validate.c:1.2 dirmngr/src/validate.c:1.3
--- dirmngr/src/validate.c:1.2	Thu Nov 18 16:37:48 2004
+++ dirmngr/src/validate.c	Fri Nov 19 16:27:28 2004
@@ -172,7 +172,7 @@
 
  /* FIXME: We need to check for evoked certifciates too.  */
 gpg_error_t
-validate_cert_chain (ksba_cert_t cert, ksba_isotime_t r_exptime)
+validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
 {
   gpg_error_t err = 0;
   int depth = 0, maxdepth;
@@ -334,7 +334,7 @@
 
       /* Find the next cert up the tree. */
       ksba_cert_release (issuer_cert); issuer_cert = NULL;
-      err = find_issuing_cert (subject_cert, &issuer_cert);
+      err = find_issuing_cert (ctrl, subject_cert, &issuer_cert);
       if (err)
         {
           if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
Index: dirmngr/src/validate.h
diff -u dirmngr/src/validate.h:1.1 dirmngr/src/validate.h:1.2
--- dirmngr/src/validate.h:1.1	Tue Nov 16 19:24:35 2004
+++ dirmngr/src/validate.h	Fri Nov 19 16:27:28 2004
@@ -24,7 +24,8 @@
 
 /* Validate the certificate CHAIN up to the trust anchor. Optionally
    return the closest expiration time in R_EXPTIME. */
-gpg_error_t validate_cert_chain (ksba_cert_t cert, ksba_isotime_t r_exptime);
+gpg_error_t validate_cert_chain (ctrl_t ctrl,
+                                 ksba_cert_t cert, ksba_isotime_t r_exptime);
 
 /* Return 0 if the certificate CERT is usable for certification.  */
 gpg_error_t cert_use_cert_p (ksba_cert_t cert);




More information about the Gnupg-commits mailing list