summaryrefslogtreecommitdiffstats
path: root/dirmngr
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2010-08-06 15:52:01 +0200
committerWerner Koch <wk@gnupg.org>2010-08-06 15:52:01 +0200
commitdc5a80930b2c18011a40f1d929119c2545cc1124 (patch)
treea74bce4e2b437331578c2ab9f1568dcecc2acf21 /dirmngr
parentSimplified http.c. (diff)
downloadgnupg2-dc5a80930b2c18011a40f1d929119c2545cc1124.tar.xz
gnupg2-dc5a80930b2c18011a40f1d929119c2545cc1124.zip
More work on the dirmngr. It now builds for W32 and W32CE and quick
tests show that it works on W32.
Diffstat (limited to 'dirmngr')
-rw-r--r--dirmngr/ChangeLog21
-rw-r--r--dirmngr/certcache.c7
-rw-r--r--dirmngr/crlcache.c10
-rw-r--r--dirmngr/crlfetch.c4
-rw-r--r--dirmngr/dirmngr.c12
-rw-r--r--dirmngr/ldap-wrapper-ce.c2
-rw-r--r--dirmngr/misc.c47
-rw-r--r--dirmngr/misc.h10
-rw-r--r--dirmngr/server.c166
9 files changed, 217 insertions, 62 deletions
diff --git a/dirmngr/ChangeLog b/dirmngr/ChangeLog
index 57cc1c772..737ff35fa 100644
--- a/dirmngr/ChangeLog
+++ b/dirmngr/ChangeLog
@@ -1,3 +1,24 @@
+2010-08-06 Werner Koch <wk@g10code.com>
+
+ * dirmngr.c (JNLIB_NEED_AFLOCAL): Define macro.
+ (main): Use SUN_LEN macro.
+ (main) [W32]: Allow EEXIST in addition to EADDRINUSE.
+ (JNLIB_NEED_AFLOCAL):
+
+2010-08-05 Werner Koch <wk@g10code.com>
+
+ * server.c (set_error, leave_cmd): New.
+ (cmd_validate, cmd_ldapserver, cmd_isvalid, cmd_checkcrl)
+ (cmd_checkocsp, cmd_lookup, cmd_listcrls, cmd_cachecert): Use
+ leave_cmd.
+ (cmd_getinfo): New.
+ (data_line_cookie_write, data_line_cookie_close): New.
+ (cmd_listcrls): Replace assuan_get_data_fp by es_fopencookie.
+
+ * misc.c (create_estream_ksba_reader, my_estream_ksba_reader_cb): New.
+ * certcache.c (load_certs_from_dir): Use create_estream_ksba_reader.
+ * crlcache.c (crl_cache_load): Ditto.
+
2010-08-03 Werner Koch <wk@g10code.com>
* dirmngr_ldap.c (pth_enter, pth_leave) [USE_LDAPWRAPPER]: Turn
diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c
index 46d2ac365..d8528118e 100644
--- a/dirmngr/certcache.c
+++ b/dirmngr/certcache.c
@@ -360,13 +360,10 @@ load_certs_from_dir (const char *dirname, int are_trusted)
fname, strerror (errno));
continue;
}
- err = ksba_reader_new (&reader);
- if (!err)
- err = ksba_reader_set_file (reader, fp);
+
+ err = create_estream_ksba_reader (&reader, fp);
if (err)
{
- log_error (_("can't setup KSBA reader: %s\n"), gpg_strerror (err));
- ksba_reader_release (reader);
es_fclose (fp);
continue;
}
diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c
index 441ae9ee0..e08741924 100644
--- a/dirmngr/crlcache.c
+++ b/dirmngr/crlcache.c
@@ -2369,18 +2369,12 @@ crl_cache_load (ctrl_t ctrl, const char *filename)
return err;
}
- err = ksba_reader_new (&reader);
+ err = create_estream_ksba_reader (&reader, fp);
if (!err)
- err = ksba_reader_set_file (reader, fp);
- if (err)
{
- log_error (_("error initializing reader object: %s\n"),
- gpg_strerror (err));
+ err = crl_cache_insert (ctrl, filename, reader);
ksba_reader_release (reader);
- return err;
}
- err = crl_cache_insert (ctrl, filename, reader);
- ksba_reader_release (reader);
es_fclose (fp);
return err;
}
diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c
index 6c2762cac..83897a698 100644
--- a/dirmngr/crlfetch.c
+++ b/dirmngr/crlfetch.c
@@ -30,6 +30,7 @@
#include "http.h"
#include "estream.h"
+#include "ldap-wrapper.h"
/* For detecting armored CRLs received via HTTP (yes, such CRLS really
@@ -228,7 +229,8 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
pointer (or well the callback context) with the
reader. It is only required when closing the
reader thus there is no performance issue doing it
- this way. */
+ this way. FIXME: We now have a close notification
+ which might be used here. */
register_file_reader (*reader, cb_ctx);
http_close (hd, 1);
}
diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
index 52efb9be4..7aafc48ce 100644
--- a/dirmngr/dirmngr.c
+++ b/dirmngr/dirmngr.c
@@ -44,6 +44,7 @@
#define JNLIB_NEED_LOG_LOGV
+#define JNLIB_NEED_AFLOCAL
#include "dirmngr.h"
#include <assuan.h>
@@ -963,12 +964,17 @@ main (int argc, char **argv)
memset (&serv_addr, 0, sizeof serv_addr);
serv_addr.sun_family = AF_UNIX;
strcpy (serv_addr.sun_path, socket_name);
- len = (offsetof (struct sockaddr_un, sun_path)
- + strlen (serv_addr.sun_path) + 1);
+ len = SUN_LEN (&serv_addr);
rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
- if (rc == -1 && errno == EADDRINUSE)
+ if (rc == -1
+ && (errno == EADDRINUSE
+#ifdef HAVE_W32_SYSTEM
+ || errno == EEXIST
+#endif
+ ))
{
+ /* Fixme: We should test whether a dirmngr is already running. */
gnupg_remove (socket_name);
rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
}
diff --git a/dirmngr/ldap-wrapper-ce.c b/dirmngr/ldap-wrapper-ce.c
index b55153466..9e6f785de 100644
--- a/dirmngr/ldap-wrapper-ce.c
+++ b/dirmngr/ldap-wrapper-ce.c
@@ -199,7 +199,7 @@ outstream_reader_cb (void *cb_value, char *buffer, size_t count,
const char *src;
size_t nread = 0;
- if (!buffer && !count && !nread)
+ if (!buffer && !count && !r_nread)
return gpg_error (GPG_ERR_NOT_SUPPORTED); /* Rewind is not supported. */
*r_nread = 0;
diff --git a/dirmngr/misc.c b/dirmngr/misc.c
index 040d4434a..3d33bee58 100644
--- a/dirmngr/misc.c
+++ b/dirmngr/misc.c
@@ -1,6 +1,6 @@
/* misc.c - miscellaneous
* Copyright (C) 2002 Klarälvdalens Datakonsult AB
- * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
*
* This file is part of DirMngr.
*
@@ -484,3 +484,48 @@ host_and_port_from_url (const char *url, int *port)
return buf;
}
+
+/* A KSBA reader callback to read from an estream. */
+static int
+my_estream_ksba_reader_cb (void *cb_value, char *buffer, size_t count,
+ size_t *r_nread)
+{
+ estream_t fp = cb_value;
+
+ if (!fp)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ if (!buffer && !count && !r_nread)
+ {
+ es_rewind (fp);
+ return 0;
+ }
+
+ *r_nread = es_fread (buffer, 1, count, fp);
+ if (!*r_nread)
+ return -1; /* EOF or error. */
+ return 0; /* Success. */
+}
+
+
+/* Create a KSBA reader object and connect it to the estream FP. */
+gpg_error_t
+create_estream_ksba_reader (ksba_reader_t *r_reader, estream_t fp)
+{
+ gpg_error_t err;
+ ksba_reader_t reader;
+
+ *r_reader = NULL;
+ err = ksba_reader_new (&reader);
+ if (!err)
+ err = ksba_reader_set_cb (reader, my_estream_ksba_reader_cb, fp);
+ if (err)
+ {
+ log_error (_("error initializing reader object: %s\n"),
+ gpg_strerror (err));
+ ksba_reader_release (reader);
+ return err;
+ }
+ *r_reader = reader;
+ return 0;
+}
diff --git a/dirmngr/misc.h b/dirmngr/misc.h
index b721549ec..928bf78ae 100644
--- a/dirmngr/misc.h
+++ b/dirmngr/misc.h
@@ -73,15 +73,9 @@ void dump_cert (const char *text, ksba_cert_t cert);
URL. */
char *host_and_port_from_url (const char *url, int *port);
+/* Create a KSBA reader object and connect it to the estream FP. */
+gpg_error_t create_estream_ksba_reader (ksba_reader_t *r_reader, estream_t fp);
-#ifdef HAVE_FOPENCOOKIE
-/* We have to implement funopen in terms of glibc's fopencookie. */
-FILE *funopen(void *cookie,
- int (*readfn)(void *, char *, int),
- int (*writefn)(void *, const char *, int),
- fpos_t (*seekfn)(void *, fpos_t, int),
- int (*closefn)(void *));
-#endif /*HAVE_FOPENCOOKIE*/
#endif /* MISC_H */
diff --git a/dirmngr/server.c b/dirmngr/server.c
index ce0a5b3c8..584cae743 100644
--- a/dirmngr/server.c
+++ b/dirmngr/server.c
@@ -40,6 +40,7 @@
#include "certcache.h"
#include "validate.h"
#include "misc.h"
+#include "ldap-wrapper.h"
/* To avoid DoS attacks we limit the size of a certificate to
something reasonable. */
@@ -47,6 +48,7 @@
#define PARM_ERROR(t) assuan_set_error (ctx, \
gpg_error (GPG_ERR_ASS_PARAMETER), (t))
+#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
@@ -61,6 +63,20 @@ struct server_local_s
};
+/* Cookie definition for assuan data line output. */
+static ssize_t data_line_cookie_write (void *cookie,
+ const void *buffer, size_t size);
+static int data_line_cookie_close (void *cookie);
+static es_cookie_io_functions_t data_line_cookie_functions =
+ {
+ NULL,
+ data_line_cookie_write,
+ NULL,
+ data_line_cookie_close
+ };
+
+
+
/* Accessor for the local ldapservers variable. */
@@ -74,6 +90,55 @@ get_ldapservers_from_ctrl (ctrl_t ctrl)
}
+/* Helper to print a message while leaving a command. */
+static gpg_error_t
+leave_cmd (assuan_context_t ctx, gpg_error_t err)
+{
+ if (err)
+ {
+ const char *name = assuan_get_command_name (ctx);
+ if (!name)
+ name = "?";
+ if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
+ log_error ("command '%s' failed: %s\n", name,
+ gpg_strerror (err));
+ else
+ log_error ("command '%s' failed: %s <%s>\n", name,
+ gpg_strerror (err), gpg_strsource (err));
+ }
+ return err;
+}
+
+/* A write handler used by es_fopencookie to write assuan data
+ lines. */
+static ssize_t
+data_line_cookie_write (void *cookie, const void *buffer, size_t size)
+{
+ assuan_context_t ctx = cookie;
+
+ if (assuan_send_data (ctx, buffer, size))
+ {
+ gpg_err_set_errno (EIO);
+ return -1;
+ }
+
+ return size;
+}
+
+static int
+data_line_cookie_close (void *cookie)
+{
+ assuan_context_t ctx = cookie;
+
+ if (assuan_send_data (ctx, NULL, 0))
+ {
+ gpg_err_set_errno (EIO);
+ return -1;
+ }
+
+ return 0;
+}
+
/* Copy the % and + escaped string S into the buffer D and replace the
escape sequences. Note, that it is sufficient to allocate the
@@ -452,17 +517,17 @@ cmd_ldapserver (assuan_context_t ctx, char *line)
while (spacep (line))
line++;
if (*line == '\0')
- return PARM_ERROR (_("ldapserver missing"));
+ return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
server = ldapserver_parse_one (line, "", 0);
if (! server)
- return gpg_error (GPG_ERR_INV_ARG);
+ return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
last_next_p = &ctrl->server_local->ldapservers;
while (*last_next_p)
last_next_p = &(*last_next_p)->next;
*last_next_p = server;
- return 0;
+ return leave_cmd (ctx, 0);
}
@@ -522,7 +587,7 @@ cmd_isvalid (assuan_context_t ctx, char *line)
if (strlen (issuerhash) != 40)
{
xfree (issuerhash);
- return PARM_ERROR (_("serialno missing in cert ID"));
+ return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
}
ocsp_mode = 1;
}
@@ -574,10 +639,8 @@ cmd_isvalid (assuan_context_t ctx, char *line)
}
}
- if (err)
- log_error (_("command %s failed: %s\n"), "ISVALID", gpg_strerror (err));
xfree (issuerhash);
- return err;
+ return leave_cmd (ctx, err);
}
@@ -688,10 +751,8 @@ cmd_checkcrl (assuan_context_t ctx, char *line)
}
leave:
- if (err)
- log_error (_("command %s failed: %s\n"), "CHECKCRL", gpg_strerror (err));
ksba_cert_release (cert);
- return err;
+ return leave_cmd (ctx, err);
}
@@ -773,10 +834,8 @@ cmd_checkocsp (assuan_context_t ctx, char *line)
err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
leave:
- if (err)
- log_error (_("command %s failed: %s\n"), "CHECKOCSP", gpg_strerror (err));
ksba_cert_release (cert);
- return err;
+ return leave_cmd (ctx, err);
}
@@ -1066,10 +1125,7 @@ cmd_lookup (assuan_context_t ctx, char *line)
else
err = lookup_cert_by_pattern (ctx, line, single, cache_only);
- if (err)
- log_error (_("command %s failed: %s\n"), "LOOKUP", gpg_strerror (err));
-
- return err;
+ return leave_cmd (ctx, err);
}
@@ -1126,9 +1182,7 @@ cmd_loadcrl (assuan_context_t ctx, char *line)
}
}
- if (err)
- log_error (_("command %s failed: %s\n"), "LOADCRL", gpg_strerror (err));
- return err;
+ return leave_cmd (ctx, err);
}
@@ -1143,17 +1197,19 @@ static gpg_error_t
cmd_listcrls (assuan_context_t ctx, char *line)
{
gpg_error_t err;
- estream_t fp = assuan_get_data_fp (ctx);
+ estream_t fp;
(void)line;
+ fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
if (!fp)
- return PARM_ERROR (_("no data stream"));
-
- err = crl_cache_list (fp);
- if (err)
- log_error (_("command %s failed: %s\n"), "LISTCRLS", gpg_strerror (err));
- return err;
+ err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
+ else
+ {
+ err = crl_cache_list (fp);
+ es_fclose (fp);
+ }
+ return leave_cmd (ctx, err);
}
@@ -1204,10 +1260,8 @@ cmd_cachecert (assuan_context_t ctx, char *line)
err = cache_cert (cert);
leave:
- if (err)
- log_error (_("command %s failed: %s\n"), "CACHECERT", gpg_strerror (err));
ksba_cert_release (cert);
- return err;
+ return leave_cmd (ctx, err);
}
@@ -1273,14 +1327,57 @@ cmd_validate (assuan_context_t ctx, char *line)
err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL);
leave:
- if (err)
- log_error (_("command %s failed: %s\n"), "VALIDATE", gpg_strerror (err));
ksba_cert_release (cert);
- return err;
+ return leave_cmd (ctx, err);
}
+
+static const char hlp_getinfo[] =
+ "GETINFO <what>\n"
+ "\n"
+ "Multi purpose command to return certain information. \n"
+ "Supported values of WHAT are:\n"
+ "\n"
+ "version - Return the version of the program.\n"
+ "pid - Return the process id of the server.\n"
+ "\n"
+ "socket_name - Return the name of the socket.\n";
+static gpg_error_t
+cmd_getinfo (assuan_context_t ctx, char *line)
+{
+ gpg_error_t err;
+
+ if (!strcmp (line, "version"))
+ {
+ const char *s = VERSION;
+ err = assuan_send_data (ctx, s, strlen (s));
+ }
+ else if (!strcmp (line, "pid"))
+ {
+ char numbuf[50];
+
+ snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
+ err = assuan_send_data (ctx, numbuf, strlen (numbuf));
+ }
+ else if (!strcmp (line, "socket_name"))
+ {
+ const char *s = dirmngr_socket_name ();
+ if (s)
+ err = assuan_send_data (ctx, s, strlen (s));
+ else
+ err = gpg_error (GPG_ERR_NO_DATA);
+ }
+ else
+ err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
+
+ return leave_cmd (ctx, err);
+}
+
+
+
+
/* Tell the assuan library about our commands. */
static int
register_commands (assuan_context_t ctx)
@@ -1299,8 +1396,7 @@ register_commands (assuan_context_t ctx)
{ "LISTCRLS", cmd_listcrls, hlp_listcrls },
{ "CACHECERT", cmd_cachecert, hlp_cachecert },
{ "VALIDATE", cmd_validate, hlp_validate },
- { "INPUT", NULL },
- { "OUTPUT", NULL },
+ { "GETINFO", cmd_getinfo, hlp_getinfo },
{ NULL, NULL }
};
int i, j, rc;