mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
More work on the dirmngr. It now builds for W32 and W32CE and quick
tests show that it works on W32.
This commit is contained in:
parent
be622bd268
commit
dc5a80930b
@ -1,3 +1,7 @@
|
||||
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
|
||||
|
@ -1,3 +1,17 @@
|
||||
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*/
|
||||
|
137
common/http.c
137
common/http.c
@ -131,21 +131,18 @@ typedef unsigned long longcounter_t;
|
||||
# define counter_strtoul(a) strtoul ((a), NULL, 10)
|
||||
#endif
|
||||
|
||||
#if defined(HTTP_USE_ESTREAM) && defined (__GNUC__)
|
||||
# warning HTTP_USE_ESTREAM is an obsolete macro
|
||||
#endif
|
||||
|
||||
#ifndef HTTP_USE_GNUTLS
|
||||
typedef void * gnutls_session_t;
|
||||
#endif
|
||||
|
||||
static gpg_error_t do_parse_uri (parsed_uri_t uri, int only_local_part);
|
||||
static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part);
|
||||
static int remove_escapes (char *string);
|
||||
static int insert_escapes (char *buffer, const char *string,
|
||||
const char *special);
|
||||
static uri_tuple_t parse_tuple (char *string);
|
||||
static gpg_error_t send_request (http_t hd, const char *auth,const char *proxy,
|
||||
const char *srvtag,strlist_t headers);
|
||||
const char *srvtag,strlist_t headers,
|
||||
gpg_err_source_t errsource);
|
||||
static char *build_rel_path (parsed_uri_t uri);
|
||||
static gpg_error_t parse_response (http_t hd);
|
||||
|
||||
@ -334,9 +331,10 @@ http_register_tls_callback ( gpg_error_t (*cb) (http_t, void *, int) )
|
||||
pointer for completing the the request and to wait for the
|
||||
response. */
|
||||
gpg_error_t
|
||||
http_open (http_t *r_hd, http_req_t reqtype, const char *url,
|
||||
_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)
|
||||
void *tls_context, const char *srvtag, strlist_t headers,
|
||||
gpg_err_source_t errsource)
|
||||
{
|
||||
gpg_error_t err;
|
||||
http_t hd;
|
||||
@ -344,7 +342,7 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
|
||||
*r_hd = NULL;
|
||||
|
||||
if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST))
|
||||
return gpg_error (GPG_ERR_INV_ARG);
|
||||
return gpg_err_make (errsource, GPG_ERR_INV_ARG);
|
||||
|
||||
/* Create the handle. */
|
||||
hd = xtrycalloc (1, sizeof *hd);
|
||||
@ -355,9 +353,9 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
|
||||
hd->flags = flags;
|
||||
hd->tls_context = tls_context;
|
||||
|
||||
err = http_parse_uri (&hd->uri, url);
|
||||
err = _http_parse_uri (&hd->uri, url, errsource);
|
||||
if (!err)
|
||||
err = send_request (hd, auth, proxy, srvtag, headers);
|
||||
err = send_request (hd, auth, proxy, srvtag, headers, errsource);
|
||||
|
||||
if (err)
|
||||
{
|
||||
@ -391,7 +389,7 @@ http_start_data (http_t hd)
|
||||
|
||||
|
||||
gpg_error_t
|
||||
http_wait_response (http_t hd)
|
||||
_http_wait_response (http_t hd, gpg_err_source_t errsource)
|
||||
{
|
||||
gpg_error_t err;
|
||||
cookie_t cookie;
|
||||
@ -402,7 +400,7 @@ http_wait_response (http_t hd)
|
||||
/* Close the write stream but keep the socket open. */
|
||||
cookie = hd->write_cookie;
|
||||
if (!cookie)
|
||||
return gpg_error (GPG_ERR_INTERNAL);
|
||||
return gpg_err_make (errsource, GPG_ERR_INTERNAL);
|
||||
|
||||
cookie->keep_socket = 1;
|
||||
es_fclose (hd->fp_write);
|
||||
@ -420,7 +418,7 @@ http_wait_response (http_t hd)
|
||||
/* Create a new cookie and a stream for reading. */
|
||||
cookie = xtrycalloc (1, sizeof *cookie);
|
||||
if (!cookie)
|
||||
return gpg_error_from_syserror ();
|
||||
return gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
cookie->fd = hd->sock;
|
||||
if (hd->uri->use_tls)
|
||||
cookie->tls_session = hd->tls_context;
|
||||
@ -431,7 +429,7 @@ http_wait_response (http_t hd)
|
||||
{
|
||||
xfree (cookie);
|
||||
hd->read_cookie = NULL;
|
||||
return gpg_error_from_syserror ();
|
||||
return gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
}
|
||||
|
||||
err = parse_response (hd);
|
||||
@ -444,18 +442,19 @@ http_wait_response (http_t hd)
|
||||
be used as an HTTP proxy and any enabled $http_proxy gets
|
||||
ignored. */
|
||||
gpg_error_t
|
||||
http_open_document (http_t *r_hd, const char *document,
|
||||
_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)
|
||||
void *tls_context, const char *srvtag, strlist_t headers,
|
||||
gpg_err_source_t errsource)
|
||||
{
|
||||
gpg_error_t err;
|
||||
|
||||
err = http_open (r_hd, HTTP_REQ_GET, document, auth, flags,
|
||||
proxy, tls_context, srvtag, headers);
|
||||
err = _http_open (r_hd, HTTP_REQ_GET, document, auth, flags,
|
||||
proxy, tls_context, srvtag, headers, errsource);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = http_wait_response (*r_hd);
|
||||
err = _http_wait_response (*r_hd, errsource);
|
||||
if (err)
|
||||
http_close (*r_hd, 0);
|
||||
|
||||
@ -513,13 +512,14 @@ http_get_status_code (http_t hd)
|
||||
* resources (even on error).
|
||||
*/
|
||||
gpg_error_t
|
||||
http_parse_uri (parsed_uri_t * ret_uri, const char *uri)
|
||||
_http_parse_uri (parsed_uri_t * ret_uri, const char *uri,
|
||||
gpg_err_source_t errsource)
|
||||
{
|
||||
*ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
|
||||
if (!*ret_uri)
|
||||
return gpg_error_from_syserror ();
|
||||
return gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
strcpy ((*ret_uri)->buffer, uri);
|
||||
return do_parse_uri (*ret_uri, 0);
|
||||
return gpg_err_make (errsource, do_parse_uri (*ret_uri, 0));
|
||||
}
|
||||
|
||||
void
|
||||
@ -539,7 +539,7 @@ http_release_parsed_uri (parsed_uri_t uri)
|
||||
}
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
static gpg_err_code_t
|
||||
do_parse_uri (parsed_uri_t uri, int only_local_part)
|
||||
{
|
||||
uri_tuple_t *tail;
|
||||
@ -557,13 +557,13 @@ do_parse_uri (parsed_uri_t uri, int only_local_part)
|
||||
|
||||
/* A quick validity check. */
|
||||
if (strspn (p, VALID_URI_CHARS) != n)
|
||||
return gpg_error (GPG_ERR_BAD_URI); /* Invalid characters found. */
|
||||
return GPG_ERR_BAD_URI; /* Invalid characters found. */
|
||||
|
||||
if (!only_local_part)
|
||||
{
|
||||
/* Find the scheme. */
|
||||
if (!(p2 = strchr (p, ':')) || p2 == p)
|
||||
return gpg_error (GPG_ERR_BAD_URI); /* No scheme. */
|
||||
return GPG_ERR_BAD_URI; /* No scheme. */
|
||||
*p2++ = 0;
|
||||
for (pp=p; *pp; pp++)
|
||||
*pp = tolower (*(unsigned char*)pp);
|
||||
@ -578,13 +578,13 @@ do_parse_uri (parsed_uri_t uri, int only_local_part)
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return gpg_error (GPG_ERR_INV_URI); /* Unsupported scheme */
|
||||
return GPG_ERR_INV_URI; /* Unsupported scheme */
|
||||
|
||||
p = p2;
|
||||
|
||||
/* Find the hostname */
|
||||
if (*p != '/')
|
||||
return gpg_error (GPG_ERR_INV_URI); /* Does not start with a slash. */
|
||||
return GPG_ERR_INV_URI; /* Does not start with a slash. */
|
||||
|
||||
p++;
|
||||
if (*p == '/') /* There seems to be a hostname. */
|
||||
@ -622,9 +622,9 @@ do_parse_uri (parsed_uri_t uri, int only_local_part)
|
||||
}
|
||||
|
||||
if ((n = remove_escapes (uri->host)) < 0)
|
||||
return gpg_error (GPG_ERR_BAD_URI);
|
||||
return GPG_ERR_BAD_URI;
|
||||
if (n != strlen (uri->host))
|
||||
return gpg_error (GPG_ERR_BAD_URI); /* Hostname incudes a Nul. */
|
||||
return GPG_ERR_BAD_URI; /* Hostname incudes a Nul. */
|
||||
p = p2 ? p2 : NULL;
|
||||
}
|
||||
} /* End global URI part. */
|
||||
@ -641,9 +641,9 @@ do_parse_uri (parsed_uri_t uri, int only_local_part)
|
||||
|
||||
uri->path = p;
|
||||
if ((n = remove_escapes (p)) < 0)
|
||||
return gpg_error (GPG_ERR_BAD_URI);
|
||||
return GPG_ERR_BAD_URI;
|
||||
if (n != strlen (p))
|
||||
return gpg_error (GPG_ERR_BAD_URI); /* Path includes a Nul. */
|
||||
return GPG_ERR_BAD_URI; /* Path includes a Nul. */
|
||||
p = p2 ? p2 : NULL;
|
||||
|
||||
if (!p || !*p)
|
||||
@ -658,7 +658,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part)
|
||||
if ((p2 = strchr (p, '&')))
|
||||
*p2++ = 0;
|
||||
if (!(elem = parse_tuple (p)))
|
||||
return gpg_error (GPG_ERR_BAD_URI);
|
||||
return GPG_ERR_BAD_URI;
|
||||
*tail = elem;
|
||||
tail = &elem->next;
|
||||
|
||||
@ -816,7 +816,8 @@ parse_tuple (char *string)
|
||||
*/
|
||||
static gpg_error_t
|
||||
send_request (http_t hd, const char *auth,
|
||||
const char *proxy,const char *srvtag,strlist_t headers)
|
||||
const char *proxy, const char *srvtag, strlist_t headers,
|
||||
gpg_err_source_t errsource)
|
||||
{
|
||||
gnutls_session_t tls_session;
|
||||
gpg_error_t err;
|
||||
@ -832,7 +833,7 @@ send_request (http_t hd, const char *auth,
|
||||
if (hd->uri->use_tls && !tls_session)
|
||||
{
|
||||
log_error ("TLS requested but no GNUTLS context provided\n");
|
||||
return gpg_error (GPG_ERR_INTERNAL);
|
||||
return gpg_err_make (errsource, GPG_ERR_INTERNAL);
|
||||
}
|
||||
|
||||
server = *hd->uri->host ? hd->uri->host : "localhost";
|
||||
@ -848,14 +849,13 @@ send_request (http_t hd, const char *auth,
|
||||
if (proxy)
|
||||
http_proxy = proxy;
|
||||
|
||||
err = http_parse_uri (&uri, http_proxy);
|
||||
err = _http_parse_uri (&uri, http_proxy, errsource);
|
||||
if (err)
|
||||
{
|
||||
log_error ("invalid HTTP proxy (%s): %s\n",
|
||||
http_proxy, gpg_strerror (err));
|
||||
http_release_parsed_uri (uri);
|
||||
return gpg_error (GPG_ERR_CONFIGURATION);
|
||||
|
||||
return gpg_err_make (errsource, GPG_ERR_CONFIGURATION);
|
||||
}
|
||||
|
||||
if (uri->auth)
|
||||
@ -866,7 +866,7 @@ send_request (http_t hd, const char *auth,
|
||||
uri->auth, strlen(uri->auth));
|
||||
if (!proxy_authstr)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
http_release_parsed_uri (uri);
|
||||
return err;
|
||||
}
|
||||
@ -887,9 +887,9 @@ send_request (http_t hd, const char *auth,
|
||||
if (hd->sock == -1)
|
||||
{
|
||||
xfree (proxy_authstr);
|
||||
return (save_errno
|
||||
? gpg_error_from_errno (save_errno)
|
||||
: gpg_error (GPG_ERR_NOT_FOUND));
|
||||
return gpg_err_make (errsource, (save_errno
|
||||
? gpg_err_code_from_errno (save_errno)
|
||||
: GPG_ERR_NOT_FOUND));
|
||||
}
|
||||
|
||||
#ifdef HTTP_USE_GNUTLS
|
||||
@ -907,7 +907,7 @@ send_request (http_t hd, const char *auth,
|
||||
{
|
||||
log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
|
||||
xfree (proxy_authstr);
|
||||
return gpg_error (GPG_ERR_NETWORK);
|
||||
return gpg_err_make (errsource, GPG_ERR_NETWORK);
|
||||
}
|
||||
|
||||
if (tls_callback)
|
||||
@ -934,7 +934,7 @@ send_request (http_t hd, const char *auth,
|
||||
if (!myauth)
|
||||
{
|
||||
xfree (proxy_authstr);
|
||||
return gpg_error_from_syserror ();
|
||||
return gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
}
|
||||
remove_escapes (myauth);
|
||||
}
|
||||
@ -952,13 +952,13 @@ send_request (http_t hd, const char *auth,
|
||||
if (!authstr)
|
||||
{
|
||||
xfree (proxy_authstr);
|
||||
return gpg_error_from_syserror ();
|
||||
return gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
}
|
||||
}
|
||||
|
||||
p = build_rel_path (hd->uri);
|
||||
if (!p)
|
||||
return gpg_error_from_syserror ();
|
||||
return gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
|
||||
if (http_proxy && *http_proxy)
|
||||
{
|
||||
@ -991,7 +991,7 @@ send_request (http_t hd, const char *auth,
|
||||
xfree (p);
|
||||
if (!request)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
xfree (authstr);
|
||||
xfree (proxy_authstr);
|
||||
return err;
|
||||
@ -1006,7 +1006,7 @@ send_request (http_t hd, const char *auth,
|
||||
cookie = xtrycalloc (1, sizeof *cookie);
|
||||
if (!cookie)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
goto leave;
|
||||
}
|
||||
cookie->fd = hd->sock;
|
||||
@ -1017,12 +1017,12 @@ send_request (http_t hd, const char *auth,
|
||||
hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
|
||||
if (!hd->fp_write)
|
||||
{
|
||||
err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
xfree (cookie);
|
||||
hd->write_cookie = NULL;
|
||||
err = gpg_error_from_syserror ();
|
||||
}
|
||||
else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
|
||||
err = gpg_error_from_syserror ();
|
||||
err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
else
|
||||
err = 0;
|
||||
|
||||
@ -1033,7 +1033,7 @@ send_request (http_t hd, const char *auth,
|
||||
if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
|
||||
|| (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1128,7 +1128,7 @@ capitalize_header_name (char *name)
|
||||
/* Store an HTTP header line in LINE away. Line continuation is
|
||||
supported as well as merging of headers with the same name. This
|
||||
function may modify LINE. */
|
||||
static gpg_error_t
|
||||
static gpg_err_code_t
|
||||
store_header (http_t hd, char *line)
|
||||
{
|
||||
size_t n;
|
||||
@ -1143,17 +1143,17 @@ store_header (http_t hd, char *line)
|
||||
line[--n] = 0;
|
||||
}
|
||||
if (!n) /* we are never called to hit this. */
|
||||
return gpg_error (GPG_ERR_BUG);
|
||||
return GPG_ERR_BUG;
|
||||
if (*line == ' ' || *line == '\t')
|
||||
{
|
||||
/* Continuation. This won't happen too often as it is not
|
||||
recommended. We use a straightforward implementaion. */
|
||||
if (!hd->headers)
|
||||
return gpg_error (GPG_ERR_PROTOCOL_VIOLATION);
|
||||
return GPG_ERR_PROTOCOL_VIOLATION;
|
||||
n += strlen (hd->headers->value);
|
||||
p = xtrymalloc (n+1);
|
||||
if (!p)
|
||||
return gpg_error_from_syserror ();
|
||||
return gpg_err_code_from_syserror ();
|
||||
strcpy (stpcpy (p, hd->headers->value), line);
|
||||
xfree (hd->headers->value);
|
||||
hd->headers->value = p;
|
||||
@ -1163,7 +1163,7 @@ store_header (http_t hd, char *line)
|
||||
capitalize_header_name (line);
|
||||
p = strchr (line, ':');
|
||||
if (!p)
|
||||
return gpg_error (GPG_ERR_PROTOCOL_VIOLATION);
|
||||
return GPG_ERR_PROTOCOL_VIOLATION;
|
||||
*p++ = 0;
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
@ -1178,7 +1178,7 @@ store_header (http_t hd, char *line)
|
||||
it is a comma separated list and merge them. */
|
||||
p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1);
|
||||
if (!p)
|
||||
return gpg_error_from_syserror ();
|
||||
return gpg_err_code_from_syserror ();
|
||||
strcpy (stpcpy (stpcpy (p, h->value), ","), value);
|
||||
xfree (h->value);
|
||||
h->value = p;
|
||||
@ -1188,13 +1188,13 @@ store_header (http_t hd, char *line)
|
||||
/* Append a new header. */
|
||||
h = xtrymalloc (sizeof *h + strlen (line));
|
||||
if (!h)
|
||||
return gpg_error_from_syserror ();
|
||||
return gpg_err_code_from_syserror ();
|
||||
strcpy (h->name, line);
|
||||
h->value = xtrymalloc (strlen (value)+1);
|
||||
if (!h->value)
|
||||
{
|
||||
xfree (h);
|
||||
return gpg_error_from_syserror ();
|
||||
return gpg_err_code_from_syserror ();
|
||||
}
|
||||
strcpy (h->value, value);
|
||||
h->next = hd->headers;
|
||||
@ -1226,7 +1226,7 @@ http_get_header (http_t hd, const char *name)
|
||||
* Parse the response from a server.
|
||||
* Returns: Errorcode and sets some files in the handle
|
||||
*/
|
||||
static gpg_error_t
|
||||
static gpg_err_code_t
|
||||
parse_response (http_t hd)
|
||||
{
|
||||
char *line, *p, *p2;
|
||||
@ -1250,11 +1250,12 @@ parse_response (http_t hd)
|
||||
len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
|
||||
line = hd->buffer;
|
||||
if (!line)
|
||||
return gpg_error_from_syserror (); /* Out of core. */
|
||||
return gpg_err_code_from_syserror (); /* Out of core. */
|
||||
if (!maxlen)
|
||||
return gpg_error (GPG_ERR_TRUNCATED); /* Line has been truncated. */
|
||||
return GPG_ERR_TRUNCATED; /* Line has been truncated. */
|
||||
if (!len)
|
||||
return gpg_error (GPG_ERR_EOF);
|
||||
return GPG_ERR_EOF;
|
||||
|
||||
if ((hd->flags & HTTP_FLAG_LOG_RESP))
|
||||
log_info ("RESP: `%.*s'\n",
|
||||
(int)strlen(line)-(*line&&line[1]?2:0),line);
|
||||
@ -1294,10 +1295,10 @@ parse_response (http_t hd)
|
||||
len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
|
||||
line = hd->buffer;
|
||||
if (!line)
|
||||
return gpg_error_from_syserror (); /* Out of core. */
|
||||
return gpg_err_code_from_syserror (); /* Out of core. */
|
||||
/* Note, that we can silently ignore truncated lines. */
|
||||
if (!len)
|
||||
return gpg_error (GPG_ERR_EOF);
|
||||
return GPG_ERR_EOF;
|
||||
/* Trim line endings of empty lines. */
|
||||
if ((*line == '\r' && line[1] == '\n') || *line == '\n')
|
||||
*line = 0;
|
||||
@ -1306,9 +1307,9 @@ parse_response (http_t hd)
|
||||
(int)strlen(line)-(*line&&line[1]?2:0),line);
|
||||
if (*line)
|
||||
{
|
||||
gpg_error_t err = store_header (hd, line);
|
||||
if (err)
|
||||
return err;
|
||||
gpg_err_code_t ec = store_header (hd, line);
|
||||
if (ec)
|
||||
return ec;
|
||||
}
|
||||
}
|
||||
while (len && *line);
|
||||
|
@ -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,
|
||||
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);
|
||||
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,
|
||||
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);
|
||||
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);
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
164
dirmngr/server.c
164
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 = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
|
||||
else
|
||||
{
|
||||
err = crl_cache_list (fp);
|
||||
if (err)
|
||||
log_error (_("command %s failed: %s\n"), "LISTCRLS", gpg_strerror (err));
|
||||
return err;
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user