Commit dc5a8093 authored by Werner Koch's avatar Werner Koch

More work on the dirmngr. It now builds for W32 and W32CE and quick

tests show that it works on W32.
parent be622bd2
2010-08-05 Werner Koch <wk@g10code.com>
* configure.ac (AH_BOTTOM): Remove HTTP_USE_ESTREAM.
2010-08-02 Werner Koch <wk@g10code.com>
* configure.ac: Require libksba 1.1.0 due to the use of
......
2010-08-06 Werner Koch <wk@g10code.com>
* homedir.c (dirmngr_socket_name) [W32CE]: Base on default homedir.
(gnupg_cachedir) [W32CE]: Drop drive letter.
* http.c (http_open_document): Rename to _http_open_document and
add arg ERRSOURCE. Pass ERRSOURCE to all called funcs.
(http_wait_response, http_open, http_parse_uri): Likewise.
(do_parse_uri, parse_response, store_header): Change to return an
gpg_err_code_t. Change callers.
(send_request): Add arg ERRSOURCE. Change callers.
* http.h (http_open_document, http_wait_response, http_open)
(http_parse_uri): Define as macro.
2010-08-05 Werner Koch <wk@g10code.com>
* estream.h (es_asprintf, es_vasprintf): Add lost prototyps.
......
......@@ -412,7 +412,12 @@ gnupg_cachedir (void)
dir = tmp;
}
else
dir = "c:\\temp\\cache\\dirmngr";
{
dir = "c:\\temp\\cache\\gnupg";
#ifdef HAVE_W32CE_SYSTEM
dir += 2;
#endif
}
}
return dir;
#else /*!HAVE_W32_SYSTEM*/
......@@ -430,6 +435,12 @@ dirmngr_socket_name (void)
if (!name)
{
char *p;
# ifdef HAVE_W32CE_SYSTEM
const char *s1, *s2;
s1 = default_homedir ();
# else
char s1[MAX_PATH];
const char *s2;
......@@ -440,9 +451,13 @@ dirmngr_socket_name (void)
that. */
if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1) < 0)
strcpy (s1, "C:\\WINDOWS");
# endif
s2 = DIRSEP_S "S.dirmngr";
name = xmalloc (strlen (s1) + strlen (s2) + 1);
strcpy (stpcpy (name, s1), s2);
for (p=name; *p; p++)
if (*p == '/')
*p = '\\';
}
return name;
#else /*!HAVE_W32_SYSTEM*/
......
This diff is collapsed.
......@@ -70,33 +70,44 @@ typedef struct http_context_s *http_t;
void http_register_tls_callback (gpg_error_t (*cb) (http_t, void *, int));
gpg_error_t http_parse_uri (parsed_uri_t *ret_uri, const char *uri);
gpg_error_t _http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
gpg_err_source_t errsource);
#define http_parse_uri(a,b) \
_http_parse_uri ((a), (b), GPG_ERR_SOURCE_DEFAULT)
void http_release_parsed_uri (parsed_uri_t uri);
gpg_error_t http_open (http_t *r_hd, http_req_t reqtype,
const char *url,
const char *auth,
unsigned int flags,
const char *proxy,
void *tls_context,
const char *srvtag,
strlist_t headers);
gpg_error_t _http_open (http_t *r_hd, http_req_t reqtype,
const char *url,
const char *auth,
unsigned int flags,
const char *proxy,
void *tls_context,
const char *srvtag,
strlist_t headers,
gpg_err_source_t errsource);
#define http_open(a,b,c,d,e,f,g,h,i) \
_http_open ((a),(b),(c),(d),(e),(f),(g),(h),(i), GPG_ERR_SOURCE_DEFAULT)
void http_start_data (http_t hd);
gpg_error_t http_wait_response (http_t hd);
gpg_error_t _http_wait_response (http_t hd, gpg_err_source_t errsource);
#define http_wait_response(a) \
_http_wait_response ((a), GPG_ERR_SOURCE_DEFAULT)
void http_close (http_t hd, int keep_read_stream);
gpg_error_t http_open_document (http_t *r_hd,
const char *document,
const char *auth,
unsigned int flags,
const char *proxy,
void *tls_context,
const char *srvtag,
strlist_t headers);
gpg_error_t _http_open_document (http_t *r_hd,
const char *document,
const char *auth,
unsigned int flags,
const char *proxy,
void *tls_context,
const char *srvtag,
strlist_t headers,
gpg_err_source_t errsource);
#define http_open_document(a,b,c,d,e,f,g,h) \
_http_open_document ((a),(b),(c),(d),(e),(f),(g),(h), GPG_ERR_SOURCE_DEFAULT)
estream_t http_get_read_ptr (http_t hd);
estream_t http_get_write_ptr (http_t hd);
......
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
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -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;
......
/* 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;
}
......@@ -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 */
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment