Some work on porting dirmngr (unfinished)

Ported gpgtar to W32.
This commit is contained in:
Werner Koch 2010-07-16 13:19:45 +00:00
parent 20a24312b0
commit 8b8925a2bd
34 changed files with 865 additions and 2791 deletions

View File

@ -103,13 +103,13 @@ if [ "$myhost" = "w32" ]; then
w32root="$w32ce_root"
[ -z "$w32root" ] && w32root="$HOME/w32ce_root"
toolprefixes="$w32ce_toolprefixes arm-mingw32ce"
extraoptions="--disable-scdaemon --disable-zip --disable-ldap --disable-dirmngr $w32ce_extraoptions"
extraoptions="--disable-scdaemon --disable-zip $w32ce_extraoptions"
;;
*)
[ -z "$w32root" ] && w32root="$HOME/w32root"
toolprefixes="$w32_toolprefixes i586-mingw32msvc"
toolprefixes="$toolprefixes i386-mingw32msvc mingw32"
extraoptions="$w32_extraoptions"
extraoptions="--enable-gpgtar $w32_extraoptions"
;;
esac
echo "Using $w32root as standard install directory" >&2

View File

@ -1,3 +1,32 @@
2010-07-16 Werner Koch <wk@g10code.com>
* http.h (HTTP_FLAG_IGNORE_CL): Add flag .
* http.c (WITHOUT_GNU_PTH): Test macro for Pth support.
(http_parse_uri): s/xcalloc/xtrycalloc/.
(send_request): Replace of discrete allocation and sprintf by
xtryasprintf.
(http_wait_response): Replace HTTP_FLAG_NO_SHUTDOWN by
HTTP_FLAG_SHUTDOWN to change the default to no shutdown.
(cookie_read) [HAVE_PTH]: Use pth_read.
(longcounter_t): New.
(struct cookie_s): Add support for content length. Turn flag
fields into bit types.
(parse_response): Parse content length header.
(cookie_read): Take care of the content length.
2010-07-08 Werner Koch <wk@g10code.com>
* estream.c (estream_functions_file): Remove and replace by
identical estream_functions_fd.
2010-07-06 Werner Koch <wk@g10code.com>
* util.h (b64state): Add field STREAM.
* b64enc.c (b64enc_start): Factor code out to ..
(enc_start): new.
(b64enc_start_es, my_fputs): New.
(b64enc_write, b64enc_finish): Support estream.
2010-06-24 Werner Koch <wk@g10code.com>
* asshelp.c (lock_agent_spawning) [W32]: Use CreateMutexW.

View File

@ -1,5 +1,5 @@
/* b64enc.c - Simple Base64 encoder.
* Copyright (C) 2001, 2003, 2004, 2008 Free Software Foundation, Inc.
* Copyright (C) 2001, 2003, 2004, 2008, 2010 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -136,20 +136,13 @@ static const u32 crc_table[256] = {
};
/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL
and not an empty string, this string will be used as the title for
the armor lines, with TITLE being an empty string, we don't write
the header lines and furthermore even don't write any linefeeds.
If TITLE starts with "PGP " the OpenPGP CRC checksum will be
written as well. With TITLE beeing NULL, we merely don't write
header but make sure that lines are not too long. Note, that we
don't write any output unless at least one byte get written using
b64enc_write. */
gpg_error_t
b64enc_start (struct b64state *state, FILE *fp, const char *title)
static gpg_error_t
enc_start (struct b64state *state, FILE *fp, estream_t stream,
const char *title)
{
memset (state, 0, sizeof *state);
state->fp = fp;
state->stream = stream;
if (title && !*title)
state->flags |= B64ENC_NO_LINEFEEDS;
else if (title)
@ -167,6 +160,39 @@ b64enc_start (struct b64state *state, FILE *fp, const char *title)
}
/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL
and not an empty string, this string will be used as the title for
the armor lines, with TITLE being an empty string, we don't write
the header lines and furthermore even don't write any linefeeds.
If TITLE starts with "PGP " the OpenPGP CRC checksum will be
written as well. With TITLE beeing NULL, we merely don't write
header but make sure that lines are not too long. Note, that we
don't write any output unless at least one byte get written using
b64enc_write. */
gpg_error_t
b64enc_start (struct b64state *state, FILE *fp, const char *title)
{
return enc_start (state, fp, NULL, title);
}
/* Same as b64enc_start but takes an estream. */
gpg_error_t
b64enc_start_es (struct b64state *state, estream_t fp, const char *title)
{
return enc_start (state, NULL, fp, title);
}
static int
my_fputs (const char *string, struct b64state *state)
{
if (state->stream)
return es_fputs (string, state->stream);
else
return fputs (string, state->fp);
}
/* Write NBYTES from BUFFER to the Base 64 stream identified by
STATE. With BUFFER and NBYTES being 0, merely do a fflush on the
stream. */
@ -176,13 +202,13 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
unsigned char radbuf[4];
int idx, quad_count;
const unsigned char *p;
FILE *fp = state->fp;
if (!nbytes)
{
if (buffer && fflush (fp))
goto write_error;
if (buffer)
if (state->stream? es_fflush (state->stream) : fflush (state->fp))
goto write_error;
return 0;
}
@ -190,12 +216,12 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
{
if (state->title)
{
if ( fputs ("-----BEGIN ", fp) == EOF
|| fputs (state->title, fp) == EOF
|| fputs ("-----\n", fp) == EOF)
if ( my_fputs ("-----BEGIN ", state) == EOF
|| my_fputs (state->title, state) == EOF
|| my_fputs ("-----\n", state) == EOF)
goto write_error;
if ( (state->flags & B64ENC_USE_PGPCRC)
&& fputs ("\n", fp) == EOF)
&& my_fputs ("\n", state) == EOF)
goto write_error;
}
@ -228,16 +254,27 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
tmp[3] = bintoasc[radbuf[2]&077];
for (idx=0; idx < 4; idx++)
putc (tmp[idx], fp);
idx = 0;
if (ferror (fp))
goto write_error;
if (state->stream)
{
for (idx=0; idx < 4; idx++)
es_putc (tmp[idx], state->stream);
idx = 0;
if (es_ferror (state->stream))
goto write_error;
}
else
{
for (idx=0; idx < 4; idx++)
putc (tmp[idx], state->fp);
idx = 0;
if (ferror (state->fp))
goto write_error;
}
if (++quad_count >= (64/4))
{
quad_count = 0;
if (!(state->flags & B64ENC_NO_LINEFEEDS)
&& fputs ("\n", fp) == EOF)
&& my_fputs ("\n", state) == EOF)
goto write_error;
}
}
@ -251,20 +288,19 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
return gpg_error_from_syserror ();
}
gpg_error_t
b64enc_finish (struct b64state *state)
{
gpg_error_t err = 0;
unsigned char radbuf[4];
int idx, quad_count;
FILE *fp;
char tmp[4];
if (!(state->flags & B64ENC_DID_HEADER))
goto cleanup;
/* Flush the base64 encoding */
fp = state->fp;
idx = state->idx;
quad_count = state->quad_count;
assert (idx < 4);
@ -285,17 +321,28 @@ b64enc_finish (struct b64state *state)
tmp[2] = bintoasc[((radbuf[1] << 2) & 074) & 077];
tmp[3] = '=';
}
for (idx=0; idx < 4; idx++)
putc (tmp[idx], fp);
idx = 0;
if (ferror (fp))
goto write_error;
if (state->stream)
{
for (idx=0; idx < 4; idx++)
es_putc (tmp[idx], state->stream);
idx = 0;
if (es_ferror (state->stream))
goto write_error;
}
else
{
for (idx=0; idx < 4; idx++)
putc (tmp[idx], state->fp);
idx = 0;
if (ferror (state->fp))
goto write_error;
}
if (++quad_count >= (64/4))
{
quad_count = 0;
if (!(state->flags & B64ENC_NO_LINEFEEDS)
&& fputs ("\n", fp) == EOF)
&& my_fputs ("\n", state) == EOF)
goto write_error;
}
}
@ -303,13 +350,13 @@ b64enc_finish (struct b64state *state)
/* Finish the last line and write the trailer. */
if (quad_count
&& !(state->flags & B64ENC_NO_LINEFEEDS)
&& fputs ("\n", fp) == EOF)
&& my_fputs ("\n", state) == EOF)
goto write_error;
if ( (state->flags & B64ENC_USE_PGPCRC) )
{
/* Write the CRC. */
putc ('=', fp);
my_fputs ("=", state);
radbuf[0] = state->crc >>16;
radbuf[1] = state->crc >> 8;
radbuf[2] = state->crc;
@ -317,20 +364,30 @@ b64enc_finish (struct b64state *state)
tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
tmp[3] = bintoasc[radbuf[2]&077];
for (idx=0; idx < 4; idx++)
putc (tmp[idx], fp);
if (ferror (fp))
goto write_error;
if (state->stream)
{
for (idx=0; idx < 4; idx++)
es_putc (tmp[idx], state->stream);
if (es_ferror (state->stream))
goto write_error;
}
else
{
for (idx=0; idx < 4; idx++)
putc (tmp[idx], state->fp);
if (ferror (state->fp))
goto write_error;
}
if (!(state->flags & B64ENC_NO_LINEFEEDS)
&& fputs ("\n", fp) == EOF)
&& my_fputs ("\n", state) == EOF)
goto write_error;
}
if (state->title)
{
if ( fputs ("-----END ", fp) == EOF
|| fputs (state->title, fp) == EOF
|| fputs ("-----\n", fp) == EOF)
if ( my_fputs ("-----END ", state) == EOF
|| my_fputs (state->title, state) == EOF
|| my_fputs ("-----\n", state) == EOF)
goto write_error;
}
@ -346,6 +403,7 @@ b64enc_finish (struct b64state *state)
state->title = NULL;
}
state->fp = NULL;
state->stream = NULL;
return err;
}

View File

@ -994,7 +994,7 @@ es_func_fp_seek (void *cookie, off_t *offset, int whence)
return 0;
}
/* Destroy function for fd objects. */
/* Destroy function for FILE* objects. */
static int
es_func_fp_destroy (void *cookie)
{
@ -1076,14 +1076,6 @@ es_func_file_create (void **cookie, int *filedes,
return err;
}
static es_cookie_io_functions_t estream_functions_file =
{
es_func_fd_read,
es_func_fd_write,
es_func_fd_seek,
es_func_fd_destroy
};
static int
es_convert_mode (const char *mode, unsigned int *modeflags)
@ -2197,7 +2189,7 @@ es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode)
goto out;
create_called = 1;
err = es_create (&stream, cookie, fd, estream_functions_file, modeflags, 0);
err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0);
if (err)
goto out;
@ -2207,7 +2199,7 @@ es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode)
out:
if (err && create_called)
(*estream_functions_file.func_close) (cookie);
(*estream_functions_fd.func_close) (cookie);
return stream;
}
@ -2519,7 +2511,7 @@ es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode,
goto leave;
create_called = 1;
es_initialize (stream, cookie, fd, estream_functions_file, modeflags);
es_initialize (stream, cookie, fd, estream_functions_fd, modeflags);
leave:

View File

@ -1,6 +1,6 @@
/* http.c - HTTP protocol handler
* Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006,
* 2009 Free Software Foundation, Inc.
* 2009, 2010 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -57,6 +57,16 @@
# include <netdb.h>
#endif /*!HAVE_W32_SYSTEM*/
#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */
# undef HAVE_PTH
# undef USE_GNU_PTH
#endif
#ifdef HAVE_PTH
# include <pth.h>
#endif
#ifdef HTTP_USE_GNUTLS
# include <gnutls/gnutls.h>
/* For non-understandable reasons GNUTLS dropped the _t suffix from
@ -75,13 +85,13 @@ typedef gnutls_transport_ptr gnutls_transport_ptr_t;
#include "i18n.h"
#include "http.h"
#ifdef USE_DNS_SRV
#include "srv.h"
# include "srv.h"
#else /*!USE_DNS_SRV*/
/* If we are not compiling with SRV record support we provide stub
data structures. */
#ifndef MAXDNAME
#define MAXDNAME 1025
#endif
/* If we are not compiling with SRV record support we provide stub
data structures. */
# ifndef MAXDNAME
# define MAXDNAME 1025
# endif
struct srventry
{
unsigned short priority;
@ -110,6 +120,15 @@ struct srventry
"01234567890@" \
"!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
/* A long counter type. */
#ifdef HAVE_STRTOULL
typedef unsigned long long longcounter_t;
# define counter_strtoul(a) strtoull ((a), NULL, 10)
#else
typedef unsigned long longcounter_t;
# define counter_strtoul(a) strtoul ((a), NULL, 10)
#endif
/* Define a prefix to map stream functions to the estream library. */
#ifdef HTTP_USE_ESTREAM
#define P_ES(a) es_ ## a
@ -152,9 +171,19 @@ static es_cookie_io_functions_t cookie_functions =
struct cookie_s
{
int fd; /* File descriptor or -1 if already closed. */
gnutls_session_t tls_session; /* TLS session context or NULL if not used. */
int keep_socket; /* Flag to communicate with teh close handler. */
/* File descriptor or -1 if already closed. */
int fd;
/* TLS session context or NULL if not used. */
gnutls_session_t tls_session;
/* The remaining content length and a flag telling whether to use
the content length. */
longcounter_t content_length;
unsigned int content_length_valid:1;
/* Flag to communicate with the close handler. */
unsigned int keep_socket:1;
};
typedef struct cookie_s *cookie_t;
@ -180,17 +209,18 @@ struct http_context_s
{
unsigned int status_code;
int sock;
int in_data;
unsigned int in_data:1;
unsigned int is_http_0_9:1;
#ifdef HTTP_USE_ESTREAM
estream_t fp_read;
estream_t fp_write;
void *write_cookie;
void *read_cookie;
#else /*!HTTP_USE_ESTREAM*/
FILE *fp_read;
FILE *fp_write;
#endif /*!HTTP_USE_ESTREAM*/
void *tls_context;
int is_http_0_9;
parsed_uri_t uri;
http_req_t req_type;
char *buffer; /* Line buffer. */
@ -417,7 +447,10 @@ http_wait_response (http_t hd)
hd->write_cookie = NULL;
#endif
if (!(hd->flags & HTTP_FLAG_NO_SHUTDOWN))
/* Shutdown one end of the socket is desired. As per HTTP/1.0 this
is not required but some very old servers (e.g. the original pksd
key server didn't worked without it. */
if ((hd->flags & HTTP_FLAG_SHUTDOWN))
shutdown (hd->sock, 1);
hd->in_data = 0;
@ -537,7 +570,9 @@ http_get_status_code (http_t hd)
gpg_error_t
http_parse_uri (parsed_uri_t * ret_uri, const char *uri)
{
*ret_uri = xcalloc (1, sizeof **ret_uri + strlen (uri));
*ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
if (!*ret_uri)
return gpg_error_from_syserror ();
strcpy ((*ret_uri)->buffer, uri);
return do_parse_uri (*ret_uri, 0);
}
@ -980,29 +1015,16 @@ send_request (http_t hd, const char *auth,
if (!p)
return gpg_error_from_syserror ();
request = xtrymalloc (2 * strlen (server)
+ strlen (p)
+ (authstr?strlen(authstr):0)
+ (proxy_authstr?strlen(proxy_authstr):0)
+ 100);
if (!request)
{
err = gpg_error_from_syserror ();
xfree (p);
xfree (authstr);
xfree (proxy_authstr);
return err;
}
if (http_proxy && *http_proxy)
{
sprintf (request, "%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s",
hd->req_type == HTTP_REQ_GET ? "GET" :
hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
server, port, *p == '/' ? "" : "/", p,
authstr ? authstr : "",
proxy_authstr ? proxy_authstr : "");
request = xtryasprintf
("%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s",
hd->req_type == HTTP_REQ_GET ? "GET" :
hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
server, port, *p == '/' ? "" : "/", p,
authstr ? authstr : "",
proxy_authstr ? proxy_authstr : "");
}
else
{
@ -1011,16 +1033,24 @@ send_request (http_t hd, const char *auth,
if (port == 80)
*portstr = 0;
else
sprintf (portstr, ":%u", port);
snprintf (portstr, sizeof portstr, ":%u", port);
sprintf (request, "%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
hd->req_type == HTTP_REQ_GET ? "GET" :
hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
*p == '/' ? "" : "/", p, server, portstr,
authstr? authstr:"");
request = xtryasprintf
("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
hd->req_type == HTTP_REQ_GET ? "GET" :
hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
*p == '/' ? "" : "/", p, server, portstr,
authstr? authstr:"");
}
xfree (p);
if (!request)
{
err = gpg_error_from_syserror ();
xfree (authstr);
xfree (proxy_authstr);
return err;
}
#ifdef HTTP_USE_ESTREAM
@ -1072,18 +1102,16 @@ send_request (http_t hd, const char *auth,
function and only then assign a stdio stream. This allows for
better error reporting that through standard stdio means. */
err = write_server (hd->sock, request, strlen (request));
if(err==0)
for(;headers;headers=headers->next)
if (!err)
for (;headers;headers=headers->next)
{
err = write_server( hd->sock, headers->d, strlen(headers->d) );
if(err)
err = write_server (hd->sock, headers->d, strlen(headers->d));
if (err)
break;
err = write_server( hd->sock, "\r\n", 2 );
if(err)
err = write_server (hd->sock, "\r\n", 2);
if (err)
break;
}
if (!err)
{
hd->fp_write = fdopen (hd->sock, "w");
@ -1351,9 +1379,7 @@ store_header (http_t hd, char *line)
is valid as along as HD has not been closed and no othe request has
been send. If the header was not found, NULL is returned. Name
must be canonicalized, that is the first letter of each dash
delimited part must be uppercase and all other letters lowercase.
Note that the context must have been opened with the
HTTP_FLAG_NEED_HEADER. */
delimited part must be uppercase and all other letters lowercase. */
const char *
http_get_header (http_t hd, const char *name)
{
@ -1376,6 +1402,8 @@ parse_response (http_t hd)
{
char *line, *p, *p2;
size_t maxlen, len;
cookie_t cookie = hd->read_cookie;
const char *s;
/* Delete old header lines. */
while (hd->headers)
@ -1447,7 +1475,7 @@ parse_response (http_t hd)
if ( (hd->flags & HTTP_FLAG_LOG_RESP) )
log_info ("RESP: `%.*s'\n",
(int)strlen(line)-(*line&&line[1]?2:0),line);
if ( (hd->flags & HTTP_FLAG_NEED_HEADER) && *line )
if (*line)
{
gpg_error_t err = store_header (hd, line);
if (err)
@ -1456,6 +1484,17 @@ parse_response (http_t hd)
}
while (len && *line);
cookie->content_length_valid = 0;
if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
{
s = http_get_header (hd, "Content-Length");
if (s)
{
cookie->content_length_valid = 1;
cookie->content_length = counter_strtoul (s);
}
}
return 0;
}
@ -1601,6 +1640,7 @@ connect_server (const char *server, unsigned short port,
}
}
#else
(void)flags;
(void)srvtag;
#endif /*USE_DNS_SRV*/
@ -1739,6 +1779,7 @@ write_server (int sock, const char *data, size_t length)
{
int nleft;
/* FIXME: We would better use pth I/O functions. */
nleft = length;
while (nleft > 0)
{
@ -1787,6 +1828,14 @@ cookie_read (void *cookie, void *buffer, size_t size)
cookie_t c = cookie;
int nread;
if (c->content_length_valid)
{
if (!c->content_length)
return 0; /* EOF */
if (c->content_length < size)
size = c->content_length;
}
#ifdef HTTP_USE_GNUTLS
if (c->tls_session)
{
@ -1817,7 +1866,9 @@ cookie_read (void *cookie, void *buffer, size_t size)
{
do
{
#ifdef HAVE_W32_SYSTEM
#ifdef HAVE_PTH
nread = pth_read (c->fd, buffer, size);
#elif defined(HAVE_W32_SYSTEM)
/* Under Windows we need to use recv for a socket. */
nread = recv (c->fd, buffer, size, 0);
#else
@ -1827,6 +1878,14 @@ cookie_read (void *cookie, void *buffer, size_t size)
while (nread == -1 && errno == EINTR);
}
if (c->content_length_valid && nread > 0)
{
if (nread < c->content_length)
c->content_length -= nread;
else
c->content_length = 0;
}
return nread;
}
@ -2028,9 +2087,7 @@ main (int argc, char **argv)
http_release_parsed_uri (uri);
uri = NULL;
rc = http_open_document (&hd, *argv, NULL,
HTTP_FLAG_NO_SHUTDOWN | HTTP_FLAG_NEED_HEADER,
NULL, tls_session);
rc = http_open_document (&hd, *argv, NULL, 0, NULL, tls_session);
if (rc)
{
log_error ("can't get `%s': %s\n", *argv, gpg_strerror (rc));

View File

@ -1,6 +1,6 @@
/* http.h - HTTP protocol handler
* Copyright (C) 1999, 2000, 2001, 2003,
* 2006 Free Software Foundation, Inc.
* Copyright (C) 1999, 2000, 2001, 2003, 2006,
* 2010 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -62,9 +62,9 @@ http_req_t;
enum
{
HTTP_FLAG_TRY_PROXY = 1,
HTTP_FLAG_NO_SHUTDOWN = 2,
HTTP_FLAG_LOG_RESP = 4,
HTTP_FLAG_NEED_HEADER = 8
HTTP_FLAG_SHUTDOWN = 2,
HTTP_FLAG_LOG_RESP = 8,
HTTP_FLAG_IGNORE_CL = 32
};
struct http_context_s;

View File

@ -27,6 +27,9 @@
#ifndef GPG_ERR_MISSING_KEY
#define GPG_ERR_MISSING_KEY 181
#endif
#ifndef GPG_ERR_LIMIT_REACHED
#define GPG_ERR_LIMIT_REACHED 183
#endif
/* Hash function used with libksba. */
#define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
@ -128,6 +131,7 @@ struct b64state
int idx;
int quad_count;
FILE *fp;
estream_t stream;
char *title;
unsigned char radbuf[4];
u32 crc;
@ -136,6 +140,8 @@ struct b64state
};
gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title);
gpg_error_t b64enc_start_es (struct b64state *state, estream_t fp,
const char *title);
gpg_error_t b64enc_write (struct b64state *state,
const void *buffer, size_t nbytes);
gpg_error_t b64enc_finish (struct b64state *state);

View File

@ -1,3 +1,26 @@
2010-07-16 Werner Koch <wk@g10code.com>
* http.c, http.h: Remove.
* dirmngr-err.h: New.
* dirmngr.h: Include dirmngr-err.h instead of gpg-error.h
* cdblib.c: Replace assignments to ERRNO by a call to
gpg_err_set_errno. Include dirmngr-err.h.
(cdb_free) [__MINGW32CE__]: Do not use get_osfhandle.
* dirmngr.c [!HAVE_SIGNAL_H]: Don't include signal.h.
(USE_W32_SERVICE): New. Use this to control the use of the W32
service system.
2010-07-06 Werner Koch <wk@g10code.com>
* dirmngr.c (main): Print note on directory name changes.
Replace almost all uses of stdio by estream.
* b64dec.c, b64enc.c: Remove. They are duplicated in ../common/.
2010-06-28 Werner Koch <wk@g10code.com>
* dirmngr_ldap.c (my_i18n_init): Remove.

View File

@ -38,7 +38,7 @@ noinst_HEADERS = dirmngr.h crlcache.h crlfetch.h misc.h
dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \
ldapserver.h ldapserver.c certcache.c certcache.h \
b64dec.c cdb.h cdblib.c ldap.c http.c http.h misc.c \
cdb.h cdblib.c ldap.c misc.c dirmngr-err.h \
ocsp.c ocsp.h validate.c validate.h
dirmngr_LDADD = $(libcommonpth) ../gl/libgnu.a $(DNSLIBS) $(LIBASSUAN_LIBS) \
@ -56,7 +56,7 @@ dirmngr_ldap_LDFLAGS =
dirmngr_ldap_LDADD = $(libcommon) ../gl/libgnu.a $(DNSLIBS) \
$(GPG_ERROR_LIBS) $(LDAPLIBS) $(LIBINTL) $(LIBICONV)
dirmngr_client_SOURCES = dirmngr-client.c b64enc.c no-libgcrypt.c
dirmngr_client_SOURCES = dirmngr-client.c no-libgcrypt.c
dirmngr_client_LDADD = $(libcommon) ../gl/libgnu.a $(LIBASSUAN_LIBS) \
$(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV)

View File

@ -1,217 +0,0 @@
/* b64dec.c - Simple Base64 decoder.
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "i18n.h"
#include "util.h"
/* The reverse base-64 list used for base-64 decoding. */
static unsigned char const asctobin[128] =
{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
};
enum decoder_states
{
s_init, s_idle, s_lfseen, s_begin,
s_b64_0, s_b64_1, s_b64_2, s_b64_3,
s_waitendtitle, s_waitend
};
/* Initialize the context for the base64 decoder. If TITLE is NULL a
plain base64 decoding is done. If it is the empty string the
decoder will skip everything until a "-----BEGIN " line has been
seen, decoding ends at a "----END " line.
Not yet implemented: If TITLE is either "PGP" or begins with "PGP "
the PGP armor lines are skipped as well. */
gpg_error_t
b64dec_start (struct b64state *state, const char *title)
{
memset (state, 0, sizeof *state);
if (title)
{
if (!strncmp (title, "PGP", 3) && (!title[3] || title[3] == ' '))
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
state->title = xtrystrdup (title);
if (!state->title)
return gpg_error_from_syserror ();
state->idx = s_init;
}
else
state->idx = s_b64_0;
return 0;
}
/* Do in-place decoding of base-64 data of LENGTH in BUFFER. Stores the
new length of the buffer at R_NBYTES. */
gpg_error_t
b64dec_proc (struct b64state *state, void *buffer, size_t length,
size_t *r_nbytes)
{
enum decoder_states ds = state->idx;
unsigned char val = state->radbuf[0];
int pos = state->quad_count;
char *d, *s;
if (state->stop_seen)
{
*r_nbytes = 0;
return gpg_error (GPG_ERR_EOF);
}
for (s=d=buffer; length && !state->stop_seen; length--, s++)
{
switch (ds)
{
case s_idle:
if (*s == '\n')
{
ds = s_lfseen;
pos = 0;
}
break;
case s_init:
ds = s_lfseen;
case s_lfseen:
if (*s != "-----BEGIN "[pos])
ds = s_idle;
else if (pos == 10)
ds = s_begin;
else
pos++;
break;
case s_begin:
if (*s == '\n')
ds = s_b64_0;
break;
case s_b64_0:
case s_b64_1:
case s_b64_2:
case s_b64_3:
{
int c;
if (*s == '-' && state->title)
{
/* Not a valid Base64 character: assume end
header. */
ds = s_waitend;
}
else if (*s == '=')
{
/* Pad character: stop */
if (ds == s_b64_1)
*d++ = val;
ds = state->title? s_waitendtitle : s_waitend;
}
else if (*s == '\n' || *s == ' ' || *s == '\r' || *s == '\t')
; /* Skip white spaces. */
else if ( (*s & 0x80)
|| (c = asctobin[*(unsigned char *)s]) == 255)
{
/* Skip invalid encodings. */
state->invalid_encoding = 1;
}
else if (ds == s_b64_0)
{
val = c << 2;
ds = s_b64_1;
}
else if (ds == s_b64_1)
{
val |= (c>>4)&3;
*d++ = val;
val = (c<<4)&0xf0;
ds = s_b64_2;
}
else if (ds == s_b64_2)
{
val |= (c>>2)&15;
*d++ = val;
val = (c<<6)&0xc0;
ds = s_b64_3;
}
else
{
val |= c&0x3f;
*d++ = val;
ds = s_b64_0;
}
}
break;
case s_waitendtitle:
if (*s == '-')
ds = s_waitend;
break;
case s_waitend:
if ( *s == '\n')
state->stop_seen = 1;
break;
default:
BUG();
}
}
state->idx = ds;
state->radbuf[0] = val;
state->quad_count = pos;
*r_nbytes = (d -(char*) buffer);
return 0;
}
/* This function needs to be called before releasing the decoder
state. It may return an error code in case an encoding error has
been found during decoding. */
gpg_error_t
b64dec_finish (struct b64state *state)
{
xfree (state->title);
state->title = NULL;
return state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0;
}

View File

@ -1,213 +0,0 @@
/* b64enc.c - Simple Base64 encoder.
* Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "i18n.h"
#include "util.h"
#define B64ENC_DID_HEADER 1
#define B64ENC_DID_TRAILER 2
#define B64ENC_NO_LINEFEEDS 16
/* The base-64 character list */
static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL
and not an empty string, this string will be used as the title for
the armor lines, with TITLE being an empty string, we don't write
the header lines and furthermore even don't write any linefeeds.
With TITLE beeing NULL, we merely don't write header but make sure
that lines are not too long. Note, that we don't write any output
unless at least one byte get written using b64enc_write. */
gpg_error_t
b64enc_start (struct b64state *state, FILE *fp, const char *title)
{
memset (state, 0, sizeof *state);
state->fp = fp;
if (title && !*title)
state->flags |= B64ENC_NO_LINEFEEDS;
else if (title)
{
state->title = strdup (title);
if (!state->title)
return gpg_error_from_errno (errno);
}
return 0;
}
/* Write NBYTES from BUFFER to the Base 64 stream identified by
STATE. With BUFFER and NBYTES being 0, merely do a fflush on the
stream. */
gpg_error_t
b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
{
unsigned char radbuf[4];
int idx, quad_count;
const unsigned char *p;
FILE *fp = state->fp;
if (!nbytes)
{
if (buffer && fflush (fp))
goto write_error;
return 0;
}
if (!(state->flags & B64ENC_DID_HEADER))
{
if (state->title)
{
if ( fputs ("-----BEGIN ", fp) == EOF
|| fputs (state->title, fp) == EOF
|| fputs ("-----\n", fp) == EOF)
goto write_error;
}
state->flags |= B64ENC_DID_HEADER;
}
idx = state->idx;
quad_count = state->quad_count;
assert (idx < 4);
memcpy (radbuf, state->radbuf, idx);
for (p=buffer; nbytes; p++, nbytes--)
{
radbuf[idx++] = *p;
if (idx > 2)
{
char tmp[4];
tmp[0] = bintoasc[(*radbuf >> 2) & 077];
tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
tmp[3] = bintoasc[radbuf[2]&077];
for (idx=0; idx < 4; idx++)
putc (tmp[idx], fp);
idx = 0;
if (ferror (fp))
goto write_error;
if (++quad_count >= (64/4))
{
quad_count = 0;
if (!(state->flags & B64ENC_NO_LINEFEEDS)
&& fputs ("\n", fp) == EOF)
goto write_error;
}
}
}
memcpy (state->radbuf, radbuf, idx);
state->idx = idx;
state->quad_count = quad_count;
return 0;
write_error:
return gpg_error_from_errno (errno);
}
gpg_error_t
b64enc_finish (struct b64state *state)
{
gpg_error_t err = 0;
unsigned char radbuf[4];
int idx, quad_count;
FILE *fp;
if (!(state->flags & B64ENC_DID_HEADER))
goto cleanup;
/* Flush the base64 encoding */
fp = state->fp;
idx = state->idx;
quad_count = state->quad_count;
assert (idx < 4);
memcpy (radbuf, state->radbuf, idx);
if (idx)
{
char tmp[4];
tmp[0] = bintoasc[(*radbuf>>2)&077];
if (idx == 1)
{
tmp[1] = bintoasc[((*radbuf << 4) & 060) & 077];
tmp[2] = '=';
tmp[3] = '=';
}
else
{
tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
tmp[2] = bintoasc[((radbuf[1] << 2) & 074) & 077];
tmp[3] = '=';
}
for (idx=0; idx < 4; idx++)
putc (tmp[idx], fp);
idx = 0;
if (ferror (fp))
goto write_error;
if (++quad_count >= (64/4))
{
quad_count = 0;
if (!(state->flags & B64ENC_NO_LINEFEEDS)
&& fputs ("\n", fp) == EOF)
goto write_error;
}
}
/* Finish the last line and write the trailer. */
if (quad_count
&& !(state->flags & B64ENC_NO_LINEFEEDS)
&& fputs ("\n", fp) == EOF)
goto write_error;
if (state->title)
{
if ( fputs ("-----END ", fp) == EOF
|| fputs (state->title, fp) == EOF
|| fputs ("-----\n", fp) == EOF)
goto write_error;
}
goto cleanup;
write_error:
err = gpg_error_from_errno (errno);
cleanup:
if (state->title)
{
free (state->title);
state->title = NULL;
}
state->fp = NULL;
return err;
}

View File

@ -73,6 +73,8 @@
# endif
#endif
#include <sys/stat.h>
#include "dirmngr-err.h"
#include "cdb.h"
#ifndef EPROTO
@ -123,13 +125,17 @@ cdb_init(struct cdb *cdbp, int fd)
return -1;
/* trivial sanity check: at least toc should be here */
if (st.st_size < 2048) {
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
fsize = (unsigned)(st.st_size & 0xffffffffu);
/* memory-map file */
#ifdef _WIN32
# ifdef __MINGW32CE__
hFile = fd;
# else
hFile = (HANDLE) _get_osfhandle(fd);
#endif
if (hFile == (HANDLE) -1)
return -1;
hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
@ -177,7 +183,11 @@ cdb_free(struct cdb *cdbp)
HANDLE hFile, hMapping;
#endif
#ifdef _WIN32
#ifdef __MINGW32CE__
hFile = cdbp->cdb_fd;
#else
hFile = (HANDLE) _get_osfhandle(cdbp->cdb_fd);
#endif
hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
UnmapViewOfFile((void*) cdbp->cdb_mem);
CloseHandle(hMapping);
@ -199,7 +209,7 @@ int
cdb_read(const struct cdb *cdbp, void *buf, unsigned len, cdbi_t pos)
{
if (pos > cdbp->cdb_fsize || cdbp->cdb_fsize - pos < len) {
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
memcpy(buf, cdbp->cdb_mem + pos, len);
@ -243,7 +253,7 @@ cdb_find(struct cdb *cdbp, const void *key, cdbi_t klen)
|| pos > cdbp->cdb_fsize /* htab start within file ? */
|| httodo > cdbp->cdb_fsize - pos) /* entrie htab within file ? */
{
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
@ -258,19 +268,19 @@ cdb_find(struct cdb *cdbp, const void *key, cdbi_t klen)
return 0;
if (cdb_unpack(htp) == hval) {
if (pos > cdbp->cdb_fsize - 8) { /* key+val lengths */
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
if (cdb_unpack(cdbp->cdb_mem + pos) == klen) {
if (cdbp->cdb_fsize - klen < pos + 8) {
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
if (memcmp(key, cdbp->cdb_mem + pos + 8, klen) == 0) {
n = cdb_unpack(cdbp->cdb_mem + pos + 4);
pos += 8 + klen;
if (cdbp->cdb_fsize < n || cdbp->cdb_fsize - n < pos) {
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
cdbp->cdb_vpos = pos;
@ -331,7 +341,7 @@ cdb_findinit(struct cdb_find *cdbfp, struct cdb *cdbp,
|| pos > cdbp->cdb_fsize
|| cdbfp->cdb_httodo > cdbp->cdb_fsize - pos)
{
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
@ -368,12 +378,12 @@ cdb_findnext(struct cdb_find *cdbfp)
cdbfp->cdb_httodo -= 8;
if (n) {
if (pos > cdbp->cdb_fsize - 8) {
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
if (cdb_unpack(cdbp->cdb_mem + pos) == cdbfp->cdb_klen) {
if (cdbp->cdb_fsize - cdbfp->cdb_klen < pos + 8) {
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
if (memcmp(cdbfp->cdb_key,
@ -381,7 +391,7 @@ cdb_findnext(struct cdb_find *cdbfp)
n = cdb_unpack(cdbp->cdb_mem + pos + 4);
pos += 8 + cdbfp->cdb_klen;
if (cdbp->cdb_fsize < n || cdbp->cdb_fsize - n < pos) {
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
cdbp->cdb_vpos = pos;
@ -410,7 +420,7 @@ cdb_findnext(struct cdb_find *cdbfp)
|| pos > cdbp->cdb_fsize
|| cdbfp->cdb_httodo > cdbp->cdb_fsize - pos)
{
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
@ -425,7 +435,7 @@ cdb_findnext(struct cdb_find *cdbfp)
while (!pos);
if (pos > cdbp->cdb_fsize - 8)
{
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
@ -436,7 +446,7 @@ cdb_findnext(struct cdb_find *cdbfp)
n = 8 + cdbp->cdb_klen + cdbp->cdb_vlen;
if ( pos > cdbp->cdb_fsize || pos > cdbp->cdb_fsize - n)
{
errno = EPROTO;
gpg_err_set_errno (EPROTO);
return -1;
}
return 1; /* Found. */
@ -454,7 +464,7 @@ cdb_bread(int fd, void *buf, int len)
while(l < 0 && errno == EINTR);
if (l <= 0) {
if (!l)
errno = EIO;
gpg_err_set_errno (EIO);
return -1;
}
buf = (char*)buf + l;
@ -555,7 +565,7 @@ cdb_make_add(struct cdb_make *cdbmp,
struct cdb_rl *rl;
if (klen > 0xffffffff - (cdbmp->cdb_dpos + 8) ||
vlen > 0xffffffff - (cdbmp->cdb_dpos + klen + 8)) {
errno = ENOMEM;
gpg_err_set_errno (ENOMEM);
return -1;
}
hval = cdb_hash(key, klen);
@ -563,7 +573,7 @@ cdb_make_add(struct cdb_make *cdbmp,
if (!rl || rl->cnt >= sizeof(rl->rec)/sizeof(rl->rec[0])) {
rl = (struct cdb_rl*)malloc(sizeof(struct cdb_rl));
if (!rl) {
errno = ENOMEM;
gpg_err_set_errno (ENOMEM);
return -1;
}
rl->cnt = 0;
@ -603,7 +613,7 @@ cdb_make_put(struct cdb_make *cdbmp,
return -1;
if (c) {
if (flags == CDB_PUT_INSERT) {
errno = EEXIST;
gpg_err_set_errno (EEXIST);
return 1;
}
else if (flags == CDB_PUT_REPLACE) {
@ -621,7 +631,7 @@ cdb_make_put(struct cdb_make *cdbmp,
if (!rl || rl->cnt >= sizeof(rl->rec)/sizeof(rl->rec[0])) {
rl = (struct cdb_rl*)malloc(sizeof(struct cdb_rl));
if (!rl) {
errno = ENOMEM;
gpg_err_set_errno (ENOMEM);
return -1;
}
rl->cnt = 0;
@ -633,13 +643,13 @@ cdb_make_put(struct cdb_make *cdbmp,
break;
default:
errno = EINVAL;
gpg_err_set_errno (EINVAL);
return -1;
}
if (klen > 0xffffffff - (cdbmp->cdb_dpos + 8) ||
vlen > 0xffffffff - (cdbmp->cdb_dpos + klen + 8)) {
errno = ENOMEM;
gpg_err_set_errno (ENOMEM);
return -1;
}
rl->rec[c].hval = hval;
@ -812,7 +822,7 @@ cdb_make_finish_internal(struct cdb_make *cdbmp)
unsigned t, i;
if (((0xffffffff - cdbmp->cdb_dpos) >> 3) < cdbmp->cdb_rcnt) {
errno = ENOMEM;
gpg_err_set_errno (ENOMEM);
return -1;
}
@ -837,7 +847,7 @@ cdb_make_finish_internal(struct cdb_make *cdbmp)
/* allocate memory to hold max htable */
htab = (struct cdb_rec*)malloc((hsize + 2) * sizeof(struct cdb_rec));
if (!htab) {
errno = ENOENT;
gpg_err_set_errno (ENOENT);
return -1;
}
p = (unsigned char *)htab;

View File

@ -328,7 +328,7 @@ load_certs_from_dir (const char *dirname, int are_trusted)
struct dirent *ep;
char *p;
size_t n;
FILE *fp;
estream_t fp;
ksba_reader_t reader;
ksba_cert_t cert;
char *fname = NULL;
@ -353,7 +353,7 @@ load_certs_from_dir (const char *dirname, int are_trusted)
xfree (fname);
fname = make_filename (dirname, p, NULL);
fp = fopen (fname, "rb");
fp = es_fopen (fname, "rb");
if (!fp)
{
log_error (_("can't open `%s': %s\n"),
@ -367,7 +367,7 @@ load_certs_from_dir (const char *dirname, int are_trusted)
{
log_error (_("can't setup KSBA reader: %s\n"), gpg_strerror (err));
ksba_reader_release (reader);
fclose (fp);
es_fclose (fp);
continue;
}
@ -375,7 +375,7 @@ load_certs_from_dir (const char *dirname, int are_trusted)
if (!err)
err = ksba_cert_read_der (cert, reader);
ksba_reader_release (reader);
fclose (fp);
es_fclose (fp);
if (err)
{
log_error (_("can't parse certificate `%s': %s\n"),

View File

@ -218,7 +218,7 @@ create_directory_if_needed (const char *name)
log_error (_("error creating directory `%s': %s\n"),
fname, strerror (errno));
xfree (fname);
errno = save_errno;
gpg_err_set_errno (save_errno);
return -1;
}
}
@ -298,7 +298,7 @@ cleanup_cache_dir (int force)
removed, the function will read the last line of a file, even if
that is not terminated by a LF. */
static char *
next_line_from_file (FILE *fp, gpg_error_t *r_err)
next_line_from_file (estream_t fp, gpg_error_t *r_err)
{
char buf[300];
char *largebuf = NULL;
@ -311,7 +311,7 @@ next_line_from_file (FILE *fp, gpg_error_t *r_err)
*r_err = 0;
p = buf;
buflen = sizeof buf - 1;
while ((c=getc (fp)) != EOF && c != '\n')
while ((c=es_getc (fp)) != EOF && c != '\n')
{
if (len >= buflen)
{
@ -401,12 +401,12 @@ release_cache (crl_cache_t cache)
/* Open the dir file FNAME or create a new one if it does not yet
exist. */
static FILE *
static estream_t
open_dir_file (const char *fname)
{
FILE *fp;
estream_t fp;
fp = fopen (fname, "r");
fp = es_fopen (fname, "r");
if (!fp)
{
log_error (_("failed to open cache dir file `%s': %s\n"),
@ -416,22 +416,22 @@ open_dir_file (const char *fname)
if (create_directory_if_needed (NULL)
|| create_directory_if_needed (DBDIR_D))
return NULL;
fp = fopen (fname, "w");
fp = es_fopen (fname, "w");
if (!fp)
{
log_error (_("error creating new cache dir file `%s': %s\n"),
fname, strerror (errno));
return NULL;
}
fprintf (fp, "v:%d:\n", DBDIRVERSION);
if (ferror (fp))
es_fprintf (fp, "v:%d:\n", DBDIRVERSION);
if (es_ferror (fp))
{
log_error (_("error writing new cache dir file `%s': %s\n"),
fname, strerror (errno));
fclose (fp);
es_fclose (fp);
return NULL;
}
if (fclose (fp))
if (es_fclose (fp))
{
log_error (_("error closing new cache dir file `%s': %s\n"),
fname, strerror (errno));
@ -440,7 +440,7 @@ open_dir_file (const char *fname)
log_info (_("new cache dir file `%s' created\n"), fname);
fp = fopen (fname, "r");
fp = es_fopen (fname, "r");
if (!fp)
{
log_error (_("failed to re-open cache dir file `%s': %s\n"),
@ -454,13 +454,13 @@ open_dir_file (const char *fname)
/* Helper for open_dir. */
static gpg_error_t
check_dir_version (FILE **fpadr, const char *fname,
check_dir_version (estream_t *fpadr, const char *fname,
unsigned int *lineno,
int cleanup_on_mismatch)
{
char *line;
gpg_error_t lineerr = 0;
FILE *fp = *fpadr;
estream_t fp = *fpadr;
int created = 0;
retry:
@ -485,7 +485,7 @@ check_dir_version (FILE **fpadr, const char *fname,
if (!created && cleanup_on_mismatch)
{
log_error (_("old version of cache directory - cleaning up\n"));
fclose (fp);
es_fclose (fp);
*fpadr = NULL;
if (!cleanup_cache_dir (1))
{
@ -521,7 +521,7 @@ open_dir (crl_cache_t *r_cache)
char *fname;
char *line = NULL;
gpg_error_t lineerr = 0;
FILE *fp;
estream_t fp;
crl_cache_entry_t entry, *entrytail;
unsigned int lineno;
gpg_error_t err = 0;
@ -649,7 +649,7 @@ open_dir (crl_cache_t *r_cache)
log_error (_("error reading `%s': %s\n"), fname, gpg_strerror (err));
goto leave;
}
if (ferror (fp))
if (es_ferror (fp))
{
log_error (_("error reading `%s': %s\n"), fname, strerror (errno));
err = gpg_error (GPG_ERR_CONFIGURATION);
@ -695,8 +695,7 @@ open_dir (crl_cache_t *r_cache)
leave:
if (fp)
fclose (fp);
es_fclose (fp);
xfree (line);
xfree (fname);
if (err)
@ -709,54 +708,54 @@ open_dir (crl_cache_t *r_cache)
}
static void
write_percented_string (const char *s, FILE *fp)
write_percented_string (const char *s, estream_t fp)
{
for (; *s; s++)
if (*s == ':')
fputs ("%3A", fp);
es_fputs ("%3A", fp);
else if (*s == '\n')
fputs ("%0A", fp);
es_fputs ("%0A", fp);
else if (*s == '\r')
fputs ("%0D", fp);
es_fputs ("%0D", fp);
else
putc (*s, fp);
es_putc (*s, fp);
}
static void
write_dir_line_crl (FILE *fp, crl_cache_entry_t e)
write_dir_line_crl (estream_t fp, crl_cache_entry_t e)
{
if (e->invalid)
fprintf (fp, "i%d", e->invalid);
es_fprintf (fp, "i%d", e->invalid);
else if (e->user_trust_req)
putc ('u', fp);
es_putc ('u', fp);
else
putc ('c', fp);
putc (':', fp);
fputs (e->issuer_hash, fp);
putc (':', fp);
es_putc ('c', fp);
es_putc (':', fp);
es_fputs (e->issuer_hash, fp);
es_putc (':', fp);
write_percented_string (e->issuer, fp);
putc (':', fp);
es_putc (':', fp);
write_percented_string (e->url, fp);
putc (':', fp);
fwrite (e->this_update, 15, 1, fp);
putc (':', fp);
fwrite (e->next_update, 15, 1, fp);
putc (':', fp);
fputs (e->dbfile_hash, fp);
putc (':', fp);
es_putc (':', fp);
es_fwrite (e->this_update, 15, 1, fp);
es_putc (':', fp);
es_fwrite (e->next_update, 15, 1, fp);
es_putc (':', fp);
es_fputs (e->dbfile_hash, fp);
es_putc (':', fp);
if (e->crl_number)
fputs (e->crl_number, fp);
putc (':', fp);
es_fputs (e->crl_number, fp);
es_putc (':', fp);
if (e->authority_issuer)
write_percented_string (e->authority_issuer, fp);
putc (':', fp);
es_putc (':', fp);
if (e->authority_serialno)
fputs (e->authority_serialno, fp);
putc (':', fp);
es_fputs (e->authority_serialno, fp);
es_putc (':', fp);
if (e->check_trust_anchor && e->user_trust_req)
fputs (e->check_trust_anchor, fp);
putc ('\n', fp);
es_fputs (e->check_trust_anchor, fp);
es_putc ('\n', fp);
}
@ -768,7 +767,8 @@ update_dir (crl_cache_t cache)
char *tmpfname = NULL;
char *line = NULL;
gpg_error_t lineerr = 0;
FILE *fp, *fpout = NULL;
estream_t fp;
estream_t fpout = NULL;
crl_cache_entry_t e;
unsigned int lineno;
gpg_error_t err = 0;
@ -781,7 +781,7 @@ update_dir (crl_cache_t cache)
e->mark = 1;
lineno = 0;
fp = fopen (fname, "r");
fp = es_fopen (fname, "r");
if (!fp)
{
err = gpg_error_from_errno (errno);
@ -792,7 +792,7 @@ update_dir (crl_cache_t cache)
err = check_dir_version (&fp, fname, &lineno, 0);
if (err)
goto leave;
rewind (fp);
es_rewind (fp);
lineno = 0;
/* Create a temporary DIR file. */
@ -827,7 +827,7 @@ update_dir (crl_cache_t cache)
tmpfname = make_filename (opt.homedir_cache, DBDIR_D, tmpbuf, NULL);
xfree (tmpbuf);
}
fpout = fopen (tmpfname, "w");
fpout = es_fopen (tmpfname, "w");
if (!fpout)
{
err = gpg_error_from_errno (errno);
@ -868,30 +868,30 @@ update_dir (crl_cache_t cache)
{ /* We ignore entries we don't have in our cache
because they may have been added in the meantime
by other instances of dirmngr. */
fprintf (fpout, "# Next line added by "
"another process; our pid is %lu\n",
(unsigned long)getpid ());
fputs (line, fpout);
putc ('\n', fpout);
es_fprintf (fpout, "# Next line added by "
"another process; our pid is %lu\n",
(unsigned long)getpid ());
es_fputs (line, fpout);
es_putc ('\n', fpout);
}
}
else
{
fputs ("# Invalid line detected: ", fpout);
fputs (line, fpout);
putc ('\n', fpout);
es_fputs ("# Invalid line detected: ", fpout);
es_fputs (line, fpout);
es_putc ('\n', fpout);
}
}
else
{
/* Write out all non CRL lines as they are. */
fputs (line, fpout);
putc ('\n', fpout);
es_fputs (line, fpout);
es_putc ('\n', fpout);
}
xfree (line);
}
if (!ferror (fp) && !ferror (fpout) && !lineerr)
if (!es_ferror (fp) && !ferror (es_fpout) && !lineerr)
{
/* Write out the remaining entries. */
for (e= cache->entries; e; e = e->next)
@ -908,12 +908,12 @@ update_dir (crl_cache_t cache)
log_error (_("error reading `%s': %s\n"), fname, gpg_strerror (err));
goto leave;
}
if (ferror (fp))
if (es_ferror (fp))
{
err = gpg_error_from_errno (errno);
log_error (_("error reading `%s': %s\n"), fname, strerror (errno));
}
if (ferror (fpout))
if (es_ferror (fpout))
{
err = gpg_error_from_errno (errno);
log_error (_("error writing `%s': %s\n"), tmpfname, strerror (errno));
@ -922,9 +922,9 @@ update_dir (crl_cache_t cache)
goto leave;
/* Rename the files. */
fclose (fp);
es_fclose (fp);
fp = NULL;
if (fclose (fpout))
if (es_fclose (fpout))
{
err = gpg_error_from_errno (errno);
log_error (_("error closing `%s': %s\n"), tmpfname, strerror (errno));
@ -947,14 +947,13 @@ update_dir (crl_cache_t cache)
leave:
/* Fixme: Relinquish update lock. */
xfree (line);
if (fp)
fclose (fp);
es_fclose (fp);
xfree (fname);
if (fpout)
{
fclose (fpout);
es_fclose (fpout);
if (err && tmpfname)
remove (tmpfname);
gnupg_remove (tmpfname);
}
xfree (tmpfname);
return err;
@ -984,14 +983,14 @@ make_db_file_name (const char *issuer_hash)
static int
hash_dbfile (const char *fname, unsigned char *md5buffer)
{
FILE *fp;
estream_t fp;
char *buffer;
size_t n;
gcry_md_hd_t md5;
gpg_err_code_t err;
buffer = xtrymalloc (65536);
fp = buffer? fopen (fname, "rb") : NULL;
fp = buffer? es_fopen (fname, "rb") : NULL;
if (!fp)
{
log_error (_("can't hash `%s': %s\n"), fname, strerror (errno));
@ -1005,7 +1004,7 @@ hash_dbfile (const char *fname, unsigned char *md5buffer)
log_error (_("error setting up MD5 hash context: %s\n"),
gpg_strerror (err));
xfree (buffer);
fclose (fp);
es_fclose (fp);
return -1;
}
@ -1015,12 +1014,12 @@ hash_dbfile (const char *fname, unsigned char *md5buffer)
for (;;)
{
n = fread (buffer, 1, 65536, fp);
if (n < 65536 && ferror (fp))
n = es_fread (buffer, 1, 65536, fp);
if (n < 65536 && es_ferror (fp))
{
log_error (_("error hashing `%s': %s\n"), fname, strerror (errno));
xfree (buffer);
fclose (fp);
es_fclose (fp);
gcry_md_close (md5);
return -1;
}
@ -1028,7 +1027,7 @@ hash_dbfile (const char *fname, unsigned char *md5buffer)
break;
gcry_md_write (md5, buffer, n);
}
fclose (fp);
es_fclose (fp);
xfree (buffer);
gcry_md_final (md5);
@ -2017,7 +2016,7 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
*p = '.';
fname = make_filename (opt.homedir_cache, DBDIR_D, tmpfname, NULL);
xfree (tmpfname);
if (!remove (fname))
if (!gnupg_remove (fname))
log_info (_("removed stale temporary cache file `%s'\n"), fname);
else if (errno != ENOENT)
{
@ -2198,7 +2197,7 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
close (fd_cdb);
if (fname)
{
remove (fname);
gnupg_remove (fname);
xfree (fname);
}
xfree (newfname);
@ -2214,7 +2213,7 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
/* Print one cached entry E in a human readable format to stream
FP. Return 0 on success. */
static gpg_error_t
list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, FILE *fp)
list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, estream_t fp)
{
struct cdb_find cdbfp;
struct cdb *cdb;
@ -2222,44 +2221,46 @@ list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, FILE *fp)
int warn = 0;
const unsigned char *s;
fputs ("--------------------------------------------------------\n", fp );
fprintf (fp, _("Begin CRL dump (retrieved via %s)\n"), e->url );
fprintf (fp, " Issuer:\t%s\n", e->issuer );
fprintf (fp, " Issuer Hash:\t%s\n", e->issuer_hash );
fprintf (fp, " This Update:\t%s\n", e->this_update );
fprintf (fp, " Next Update:\t%s\n", e->next_update );
fprintf (fp, " CRL Number :\t%s\n", e->crl_number? e->crl_number: "none");
fprintf (fp, " AuthKeyId :\t%s\n",
e->authority_serialno? e->authority_serialno:"none");
es_fputs ("--------------------------------------------------------\n", fp );
es_fprintf (fp, _("Begin CRL dump (retrieved via %s)\n"), e->url );
es_fprintf (fp, " Issuer:\t%s\n", e->issuer );
es_fprintf (fp, " Issuer Hash:\t%s\n", e->issuer_hash );
es_fprintf (fp, " This Update:\t%s\n", e->this_update );
es_fprintf (fp, " Next Update:\t%s\n", e->next_update );
es_fprintf (fp, " CRL Number :\t%s\n", e->crl_number? e->crl_number: "none");
es_fprintf (fp, " AuthKeyId :\t%s\n",
e->authority_serialno? e->authority_serialno:"none");
if (e->authority_serialno && e->authority_issuer)
{
fputs (" \t", fp);
es_fputs (" \t", fp);
for (s=e->authority_issuer; *s; s++)
if (*s == '\x01')
fputs ("\n \t", fp);
es_fputs ("\n \t", fp);
else
putc (*s, fp);
putc ('\n', fp);
es_putc (*s, fp);
es_putc ('\n', fp);
}
fprintf (fp, " Trust Check:\t%s\n",
!e->user_trust_req? "[system]" :
e->check_trust_anchor? e->check_trust_anchor:"[missing]");
es_fprintf (fp, " Trust Check:\t%s\n",
!e->user_trust_req? "[system]" :
e->check_trust_anchor? e->check_trust_anchor:"[missing]");
if ((e->invalid & 1))
fprintf (fp, _(" ERROR: The CRL will not be used because it was still too old after an update!\n"));
es_fprintf (fp, _(" ERROR: The CRL will not be used "
"because it was still too old after an update!\n"));
if ((e->invalid & 2))
fprintf (fp, _(" ERROR: The CRL will not be used due to an unknown critical extension!\n"));
es_fprintf (fp, _(" ERROR: The CRL will not be used "
"due to an unknown critical extension!\n"));
if ((e->invalid & ~3))
fprintf (fp, _(" ERROR: The CRL will not be used\n"));
es_fprintf (fp, _(" ERROR: The CRL will not be used\n"));
cdb = lock_db_file (cache, e);
if (!cdb)
return gpg_error (GPG_ERR_GENERAL);
if (!e->dbfile_checked)
fprintf (fp, _(" ERROR: This cached CRL may has been tampered with!\n"));
es_fprintf (fp, _(" ERROR: This cached CRL may has been tampered with!\n"));
putc ('\n', fp);
es_putc ('\n', fp);
rc = cdb_findinit (&cdbfp, cdb, NULL, 0);
while (!rc && (rc=cdb_findnext (&cdbfp)) > 0 )
@ -2299,36 +2300,36 @@ list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, FILE *fp)
}
reason = *record;
fputs (" ", fp);
es_fputs (" ", fp);
for (i = 0; i < n; i++)
fprintf (fp, "%02X", keyrecord[i]);
fputs (":\t reasons( ", fp);
es_fprintf (fp, "%02X", keyrecord[i]);
es_fputs (":\t reasons( ", fp);
if (reason & KSBA_CRLREASON_UNSPECIFIED)
fputs( "unspecified ", fp ), any = 1;
es_fputs( "unspecified ", fp ), any = 1;
if (reason & KSBA_CRLREASON_KEY_COMPROMISE )
fputs( "key_compromise ", fp ), any = 1;
es_fputs( "key_compromise ", fp ), any = 1;
if (reason & KSBA_CRLREASON_CA_COMPROMISE )
fputs( "ca_compromise ", fp ), any = 1;
es_fputs( "ca_compromise ", fp ), any = 1;
if (reason & KSBA_CRLREASON_AFFILIATION_CHANGED )
fputs( "affiliation_changed ", fp ), any = 1;
es_fputs( "affiliation_changed ", fp ), any = 1;
if (reason & KSBA_CRLREASON_SUPERSEDED )
fputs( "superseeded", fp ), any = 1;
es_fputs( "superseeded", fp ), any = 1;
if (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION )
fputs( "cessation_of_operation", fp ), any = 1;
es_fputs( "cessation_of_operation", fp ), any = 1;
if (reason & KSBA_CRLREASON_CERTIFICATE_HOLD )
fputs( "certificate_hold", fp ), any = 1;
es_fputs( "certificate_hold", fp ), any = 1;
if (reason && !any)
fputs( "other", fp );
es_fputs( "other", fp );
fprintf (fp, ") rdate: %.15s\n", record+1);
es_fprintf (fp, ") rdate: %.15s\n", record+1);
}
if (rc)
log_error (_("error reading cache entry from db: %s\n"), strerror (rc));
unlock_db_file (cache, e);
fprintf (fp, _("End CRL dump\n") );
putc ('\n', fp);
es_fprintf (fp, _("End CRL dump\n") );
es_putc ('\n', fp);
return (rc||warn)? gpg_error (GPG_ERR_GENERAL) : 0;
}
@ -2337,7 +2338,7 @@ list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, FILE *fp)
/* Print the contents of the CRL CACHE in a human readable format to
stream FP. */
gpg_error_t
crl_cache_list (FILE *fp)
crl_cache_list (estream_t fp)
{
crl_cache_t cache = get_current_cache ();
crl_cache_entry_t entry;
@ -2357,10 +2358,10 @@ gpg_error_t
crl_cache_load (ctrl_t ctrl, const char *filename)
{
gpg_error_t err;
FILE *fp;
estream_t fp;
ksba_reader_t reader;
fp = fopen (filename, "r");
fp = es_fopen (filename, "r");
if (!fp)
{
err = gpg_error_from_errno (errno);
@ -2380,7 +2381,7 @@ crl_cache_load (ctrl_t ctrl, const char *filename)
}
err = crl_cache_insert (ctrl, filename, reader);
ksba_reader_release (reader);
fclose (fp);
es_fclose (fp);
return err;
}

View File

@ -60,7 +60,7 @@ gpg_error_t crl_cache_cert_isvalid (ctrl_t ctrl, ksba_cert_t cert,
gpg_error_t crl_cache_insert (ctrl_t ctrl, const char *url,
ksba_reader_t reader);
gpg_error_t crl_cache_list (FILE* fp);
gpg_error_t crl_cache_list (estream_t fp);
gpg_error_t crl_cache_load (ctrl_t ctrl, const char *filename);

View File

@ -193,9 +193,8 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
else
err = http_open_document (&hd, url, NULL,
(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
|HTTP_FLAG_NEED_HEADER
|(DBG_LOOKUP? HTTP_FLAG_LOG_RESP:0),
opt.http_proxy, NULL);
opt.http_proxy, NULL, NULL, NULL);
switch ( err? 99999 : http_get_status_code (hd) )
{

View File

@ -485,7 +485,7 @@ start_dirmngr (int only_daemon)
i=0;
if (log_get_fd () != -1)
no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
no_close_list[i++] = assuan_fd_from_posix_fd (es_fileno (es_stderr));
no_close_list[i] = -1;
/* Connect to the agent and perform initial handshaking. */

12
dirmngr/dirmngr-err.h Normal file
View File

@ -0,0 +1,12 @@
/* Definition of the gpg-error source. */
#ifndef DIRMNGR_ERR_H
#define DIRMNGR_ERR_H
#ifdef GPG_ERR_SOURCE_DEFAULT
#error GPG_ERR_SOURCE_DEFAULT already defined
#endif
#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_DIRMNGR
#include <gpg-error.h>
#endif /*DIRMNGR_ERR_H*/

View File

@ -37,7 +37,9 @@
#endif
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif
#include <pth.h>
@ -53,6 +55,16 @@
#include "ldapserver.h"
#include "asshelp.h"
/* The plain Windows version uses the windows service system. For
example to start the service you may use "sc start dirmngr".
WindowsCE does not support this; the service system over there is
based on a single process with all services being DLLs - we can't
support this easily. */
#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
# define USE_W32_SERVICE 1
#endif
enum cmd_and_opt_values {
aNull = 0,
oCsh = 'c',
@ -119,7 +131,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_c (aServer, "server", N_("run in server mode (foreground)") ),
ARGPARSE_c (aDaemon, "daemon", N_("run in daemon mode (background)") ),
#ifdef HAVE_W32_SYSTEM
#ifdef USE_W32_SERVICE
ARGPARSE_c (aService, "service", N_("run as windows service (background)")),
#endif
ARGPARSE_c (aListCRLs, "list-crls", N_("list the contents of the CRL cache")),
@ -374,9 +386,9 @@ set_debug (void)
static void
wrong_args (const char *text)
{
fputs (_("usage: dirmngr [options] "), stderr);
fputs (text, stderr);
putc ('\n', stderr);
es_fputs (_("usage: dirmngr [options] "), es_stderr);
es_fputs (text, es_stderr);
es_putc ('\n', es_stderr);
dirmngr_exit (2);
}
@ -514,7 +526,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
}
#ifdef HAVE_W32_SYSTEM
#ifdef USE_W32_SERVICE
/* The global status of our service. */
SERVICE_STATUS_HANDLE service_handle;
SERVICE_STATUS service_status;
@ -544,7 +556,7 @@ w32_service_control (DWORD control, DWORD event_type, LPVOID event_data,
}
return 0;
}
#endif /*HAVE_W32_SYSTEM*/
#endif /*USE_W32_SERVICE*/
#ifndef HAVE_W32_SYSTEM
static int
@ -559,14 +571,14 @@ pid_suffix_callback (unsigned long *r_suffix)
#endif /*!HAVE_W32_SYSTEM*/
#ifdef HAVE_W32_SYSTEM
#define main real_main
#ifdef USE_W32_SERVICE
# define main real_main
#endif
int
main (int argc, char **argv)
{
#ifdef HAVE_W32_SYSTEM
#undef main
#ifdef USE_W32_SERVICE
# undef main
#endif
enum cmd_and_opt_values cmd = 0;
ARGPARSE_ARGS pargs;
@ -589,7 +601,7 @@ main (int argc, char **argv)
int homedir_seen = 0;
struct assuan_malloc_hooks malloc_hooks;
#ifdef HAVE_W32_SYSTEM
#ifdef USE_W32_SERVICE
/* The option will be set by main() below if we should run as a
system daemon. */
if (opt.system_service)
@ -610,7 +622,7 @@ main (int argc, char **argv)
service_status.dwWaitHint = 10000; /* 10 seconds timeout. */
SetServiceStatus (service_handle, &service_status);
}
#endif /*HAVE_W32_SYSTEM*/
#endif /*USE_W32_SERVICE*/
set_strusage (my_strusage);
log_set_prefix ("dirmngr", 1|4);
@ -833,7 +845,7 @@ main (int argc, char **argv)
}
if (configfp)
{
fclose( configfp );
fclose (configfp);
configfp = NULL;
/* Keep a copy of the name so that it can be read on SIGHUP. */
opt.config_filename = configname;
@ -854,15 +866,22 @@ main (int argc, char **argv)
if (greeting)
{
fprintf (stderr, "%s %s; %s\n",
strusage(11), strusage(13), strusage(14) );
fprintf (stderr, "%s\n", strusage(15) );
es_fprintf (es_stderr, "%s %s; %s\n",
strusage(11), strusage(13), strusage(14) );
es_fprintf (es_stderr, "%s\n", strusage(15) );
}
#ifdef IS_DEVELOPMENT_VERSION
log_info ("NOTE: this is a development version!\n");
#endif
if (!access ("/etc/dirmngr", F_OK) && !strncmp (opt.homedir, "/etc/", 5))
log_info
("NOTE: DirMngr is now a proper part of GnuPG. The configuration and"
" other directory names changed. Please check that no other version"
" of dirmngr is still installed. To disable this warning, remove the"
" directory `/etc/dirmngr'.\n");
if (gnupg_faked_time_p ())
{
gnupg_isotime_t tbuf;
@ -975,7 +994,7 @@ main (int argc, char **argv)
rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
if (rc == -1 && errno == EADDRINUSE)
{
remove (socket_name);
gnupg_remove (socket_name);
rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
}
if (rc != -1
@ -1000,7 +1019,7 @@ main (int argc, char **argv)
if (opt.verbose)
log_info (_("listening on socket `%s'\n"), socket_name );
fflush (NULL);
es_fflush (NULL);
#ifdef HAVE_W32_SYSTEM
pid = getpid ();
@ -1085,7 +1104,7 @@ main (int argc, char **argv)
launch_reaper_thread ();
cert_cache_init ();
crl_cache_init ();
#ifdef HAVE_W32_SYSTEM
#ifdef USE_W32_SERVICE
if (opt.system_service)
{
service_status.dwCurrentState = SERVICE_RUNNING;
@ -1095,7 +1114,7 @@ main (int argc, char **argv)
handle_connections (fd);
assuan_sock_close (fd);
shutdown_reaper ();
#ifdef HAVE_W32_SYSTEM
#ifdef USE_W32_SERVICE
if (opt.system_service)
{
service_status.dwCurrentState = SERVICE_STOPPED;
@ -1110,7 +1129,7 @@ main (int argc, char **argv)
wrong_args ("--list-crls");
launch_reaper_thread ();
crl_cache_init ();
crl_cache_list (stdout);
crl_cache_list (es_stdout);
}
else if (cmd == aLoadCRL)
{
@ -1260,7 +1279,7 @@ main (int argc, char **argv)
}
#ifdef HAVE_W32_SYSTEM
#ifdef USE_W32_SERVICE
int
main (int argc, char *argv[])
{
@ -1291,7 +1310,7 @@ main (int argc, char *argv[])
return 0;
}
}
#endif
#endif /*USE_W32_SERVICE*/
static void
@ -1307,7 +1326,7 @@ cleanup (void)
{
cleanup_socket = 0;
if (socket_name && *socket_name)
remove (socket_name);
gnupg_remove (socket_name);
}
}
@ -1351,9 +1370,9 @@ parse_ldapserver_file (const char* filename)
ldap_server_t server, serverstart, *serverend;
int c;
unsigned int lineno = 0;
FILE *fp;
estream_t fp;
fp = fopen (filename, "r");
fp = es_fopen (filename, "r");
if (!fp)
{
log_error (_("error opening `%s': %s\n"), filename, strerror (errno));
@ -1362,18 +1381,18 @@ parse_ldapserver_file (const char* filename)
serverstart = NULL;
serverend = &serverstart;
while (fgets (buffer, sizeof buffer, fp))
while (es_fgets (buffer, sizeof buffer, fp))
{
lineno++;
if (!*buffer || buffer[strlen(buffer)-1] != '\n')
{
if (*buffer && feof (fp))
if (*buffer && es_feof (fp))
; /* Last line not terminated - continue. */
else
{
log_error (_("%s:%u: line too long - skipped\n"),
filename, lineno);
while ( (c=fgetc (fp)) != EOF && c != '\n')
while ( (c=es_fgetc (fp)) != EOF && c != '\n')
; /* Skip until end of line. */
continue;
}
@ -1393,9 +1412,9 @@ parse_ldapserver_file (const char* filename)
}
}
if (ferror (fp))
if (es_ferror (fp))
log_error (_("error reading `%s': %s\n"), filename, strerror (errno));
fclose (fp);
es_fclose (fp);
return serverstart;
}
@ -1406,7 +1425,7 @@ parse_ocsp_signer (const char *string)
{
gpg_error_t err;
char *fname;
FILE *fp;
estream_t fp;
char line[256];
char *p;
fingerprint_list_t list, *list_tail, item;
@ -1444,7 +1463,7 @@ parse_ocsp_signer (const char *string)
fname = make_filename (opt.homedir, string, NULL);
}
fp = fopen (fname, "r");
fp = es_fopen (fname, "r");
if (!fp)
{
err = gpg_error_from_syserror ();
@ -1457,16 +1476,16 @@ parse_ocsp_signer (const char *string)
list_tail = &list;
for (;;)
{
if (!fgets (line, DIM(line)-1, fp) )
if (!es_fgets (line, DIM(line)-1, fp) )
{
if (!feof (fp))
if (!es_feof (fp))
{
err = gpg_error_from_syserror ();
log_error (_("%s:%u: read error: %s\n"),
fname, lnr, gpg_strerror (err));
errflag = 1;
}
fclose (fp);
es_fclose (fp);
if (errflag)
{
while (list)
@ -1484,7 +1503,7 @@ parse_ocsp_signer (const char *string)
if (!*line || line[strlen(line)-1] != '\n')
{
/* Eat until end of line. */
while ( (c=getc (fp)) != EOF && c != '\n')
while ( (c=es_getc (fp)) != EOF && c != '\n')
;
err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
/* */: GPG_ERR_INCOMPLETE_LINE);

View File

@ -21,11 +21,7 @@
#ifndef DIRMNGR_H
#define DIRMNGR_H
#ifdef GPG_ERR_SOURCE_DEFAULT
#error GPG_ERR_SOURCE_DEFAULT already defined
#endif
#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_DIRMNGR
#include <gpg-error.h>
#include "./dirmngr-err.h"
#define map_assuan_err(a) \
map_assuan_err_with_source (GPG_ERR_SOURCE_DEFAULT, (a))
#include <errno.h>

View File

@ -25,7 +25,9 @@
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <signal.h>
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif
#include <errno.h>
#include <assert.h>
#include <sys/time.h>
@ -171,6 +173,7 @@ main (int argc, char **argv )
#ifdef HAVE_W32_SYSTEM
/* Yeah, right. Sigh. */
#error FIXME
_setmode (_fileno (stdout), _O_BINARY);
#endif
@ -313,7 +316,7 @@ print_ldap_entries (LDAP *ld, LDAPMessage *msg, char *want_attr)
if (opt.multi)
{ /* Write item marker. */
if (fwrite ("I\0\0\0\0", 5, 1, stdout) != 1)
if (es_fwrite ("I\0\0\0\0", 5, 1, es_stdout) != 1)
{
log_error (_("error writing to stdout: %s\n"),
strerror (errno));
@ -390,8 +393,8 @@ print_ldap_entries (LDAP *ld, LDAPMessage *msg, char *want_attr)
tmp[2] = (n >> 16);
tmp[3] = (n >> 8);
tmp[4] = (n);
if (fwrite (tmp, 5, 1, stdout) != 1
|| fwrite (attr, n, 1, stdout) != 1)
if (es_fwrite (tmp, 5, 1, es_stdout) != 1
|| es_fwrite (attr, n, 1, es_stdout) != 1)
{
log_error (_("error writing to stdout: %s\n"),
strerror (errno));
@ -415,7 +418,7 @@ print_ldap_entries (LDAP *ld, LDAPMessage *msg, char *want_attr)
tmp[3] = (n >> 8);
tmp[4] = (n);
if (fwrite (tmp, 5, 1, stdout) != 1)
if (es_fwrite (tmp, 5, 1, es_stdout) != 1)
{
log_error (_("error writing to stdout: %s\n"),
strerror (errno));
@ -429,8 +432,9 @@ print_ldap_entries (LDAP *ld, LDAPMessage *msg, char *want_attr)
/* Note: this does not work for STDOUT on a Windows
console, where it fails with "Not enough space" for
CRLs which are 52 KB or larger. */
if (fwrite (values[0]->bv_val, values[0]->bv_len,
1, stdout) != 1)
#warning still true - implement in estream
if (es_fwrite (values[0]->bv_val, values[0]->bv_len,
1, es_stdout) != 1)
{
log_error (_("error writing to stdout: %s\n"),
strerror (errno));
@ -452,8 +456,8 @@ print_ldap_entries (LDAP *ld, LDAPMessage *msg, char *want_attr)
if (cnt > MAX_CNT)
cnt = MAX_CNT;
if (fwrite (((char *) values[0]->bv_val) + n, cnt, 1,
stdout) != 1)
if (es_fwrite (((char *) values[0]->bv_val) + n, cnt, 1,
es_stdout) != 1)
{
log_error (_("error writing to stdout: %s\n"),
strerror (errno));
@ -572,7 +576,7 @@ fetch_ldap (const char *url, const LDAPURLDesc *ludp)
&opt.timeout, &msg);
if (rc == LDAP_SIZELIMIT_EXCEEDED && opt.multi)
{
if (fwrite ("E\0\0\0\x09truncated", 14, 1, stdout) != 1)
if (es_fwrite ("E\0\0\0\x09truncated", 14, 1, es_stdout) != 1)
{
log_error (_("error writing to stdout: %s\n"),
strerror (errno));

File diff suppressed because it is too large Load Diff

View File

@ -1,109 +0,0 @@
/* http.h - HTTP protocol handler
* Copyright (C) 1999, 2000, 2001, 2003,
* 2006 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
#ifndef GNUPG_COMMON_HTTP_H
#define GNUPG_COMMON_HTTP_H
#include <gpg-error.h>
#include "estream.h"
struct uri_tuple_s {
struct uri_tuple_s *next;
const char *name; /* A pointer into name. */
char *value; /* A pointer to value (a Nul is always appended). */
size_t valuelen; /* The real length of the value; we need it
because the value may contain embedded Nuls. */
int no_value; /* True if no value has been given in the URL. */
};
typedef struct uri_tuple_s *uri_tuple_t;
struct parsed_uri_s
{
/* All these pointers point into BUFFER; most stuff is not escaped. */
char *scheme; /* Pointer to the scheme string (lowercase). */
int use_tls; /* Whether TLS should be used. */
char *auth; /* username/password for basic auth */
char *host; /* Host (converted to lowercase). */
unsigned short port; /* Port (always set if the host is set). */
char *path; /* Path. */
uri_tuple_t params; /* ";xxxxx" */
uri_tuple_t query; /* "?xxx=yyy" */
char buffer[1]; /* Buffer which holds a (modified) copy of the URI. */
};
typedef struct parsed_uri_s *parsed_uri_t;
typedef enum
{
HTTP_REQ_GET = 1,
HTTP_REQ_HEAD = 2,
HTTP_REQ_POST = 3
}
http_req_t;
/* We put the flag values into an enum, so that gdb can display them. */
enum
{
HTTP_FLAG_TRY_PROXY = 1,
HTTP_FLAG_SHUTDOWN = 2,
HTTP_FLAG_TRY_SRV = 4,
HTTP_FLAG_LOG_RESP = 8,
HTTP_FLAG_NEED_HEADER = 16,
HTTP_FLAG_IGNORE_CL = 32
};
struct http_context_s;
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);
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);
void http_start_data (http_t hd);
gpg_error_t http_wait_response (http_t hd);
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);
estream_t http_get_read_ptr (http_t hd);
estream_t http_get_write_ptr (http_t hd);
unsigned int http_get_status_code (http_t hd);
const char *http_get_header (http_t hd, const char *name);
char *http_escape_string (const char *string, const char *specials);
#endif /*GNUPG_COMMON_HTTP_H*/

View File

@ -166,10 +166,8 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
once_more:
err = http_open (&http, HTTP_REQ_POST, url, NULL,
(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
|HTTP_FLAG_NEED_HEADER,
opt.http_proxy,
NULL);
(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0),
opt.http_proxy, NULL, NULL, NULL);
if (err)
{
log_error (_("error connecting to `%s': %s\n"), url, gpg_strerror (err));

View File

@ -1143,7 +1143,7 @@ static gpg_error_t
cmd_listcrls (assuan_context_t ctx, char *line)
{
gpg_error_t err;
FILE *fp = assuan_get_data_fp (ctx);
estream_t fp = assuan_get_data_fp (ctx);
(void)line;

View File

@ -527,12 +527,13 @@ Print message digest of algorithm ALGO for all given files or STDIN.
With the second form (or a deprecated "*" as algo) digests for all
available algorithms are printed.
@item --gen-random @code{0|1|2}
@item --gen-random @code{0|1|2} @code{count}
@opindex gen-random
Emit @var{count} random bytes of the given quality level. If count is
not given or zero, an endless sequence of random bytes will be emitted.
PLEASE, don't use this command unless you know what you are doing; it
may remove precious entropy from the system!
Emit @var{count} random bytes of the given quality level 0, 1 or 2. If
@var{count} is not given or zero, an endless sequence of random bytes
will be emitted. If used with @option{--armor} the output will be
base64 encoded. PLEASE, don't use this command unless you know what
you are doing; it may remove precious entropy from the system!
@item --gen-prime @code{mode} @code{bits}
@opindex gen-prime

View File

@ -83,7 +83,7 @@ else
pkgrep = ftp://ftp.gnupg.org/gcrypt
speedo_pkg_libgpg_error_tar = $(pkgrep)/libgpg-error/libgpg-error-1.8.tar.bz2
speedo_pkg_libassuan_tar = $(pkgrep)/libassuan/libassuan-2.0.0.tar.bz2
speedo_pkg_libgcrypt_tar = $(pkgrep)/libgcrypt/libgcrypt-1.4.5.tar.bz2
speedo_pkg_libgcrypt_tar = $(pkgrep)/libgcrypt/libgcrypt-1.4.6.tar.bz2
speedo_pkg_libksba_tar = $(pkgrep)/libksba/libksba-1.0.7.tar.bz2
speedo_pkg_gpgme_tar = $(pkgrep)/gpgme/gpgme-1.3.0.tar.bz2
endif

View File

@ -1,3 +1,11 @@
2010-07-16 Werner Koch <wk@g10code.com>
* gpgtar-create.c: Rewrite to better support W32.
2010-07-01 Werner Koch <wk@g10code.com>
* gpgtar.c: Add option --set-filename.
2010-06-24 Werner Koch <wk@g10code.com>
* gpgconf-comp.c (gpg_agent_runtime_change)

View File

@ -128,7 +128,8 @@ gpgtar_SOURCES = \
gpgtar-list.c \
no-libgcrypt.c
gpgtar_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
gpgtar_LDADD = $(commonpth_libs) $(PTH_LIBS) $(GPG_ERROR_LIBS)
#gpgtar_LDADD = $(commonpth_libs) $(PTH_LIBS) $(GPG_ERROR_LIBS)
gpgtar_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(W32SOCKLIBS)
# Make sure that all libs are build before we use them. This is

View File

@ -25,14 +25,14 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
/* #ifdef HAVE_W32_SYSTEM */
/* # define WIN32_LEAN_AND_MEAN */
/* # include <windows.h> */
/* #else /\*!HAVE_W32_SYSTEM*\/ */
#ifdef HAVE_W32_SYSTEM
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#else /*!HAVE_W32_SYSTEM*/
# include <unistd.h>
# include <pwd.h>
# include <grp.h>
/* #endif /\*!HAVE_W32_SYSTEM*\/ */
#endif /*!HAVE_W32_SYSTEM*/
#include <assert.h>
#include "i18n.h"
@ -58,9 +58,83 @@ struct scanctrl_s
/* Given a fresh header object HDR with only the name field set, try
to gather all available info. */
to gather all available info. This is the W32 version. */
#ifdef HAVE_W32_SYSTEM
static gpg_error_t
fillup_entry (tar_header_t hdr)
fillup_entry_w32 (tar_header_t hdr)
{
char *p;
wchar_t *wfname;
WIN32_FILE_ATTRIBUTE_DATA fad;
DWORD attr;
for (p=hdr->name; *p; p++)
if (*p == '/')
*p = '\\';
wfname = utf8_to_wchar (hdr->name);
for (p=hdr->name; *p; p++)
if (*p == '\\')
*p = '/';
if (!wfname)
{
log_error ("error utf8-ing `%s': %s\n", hdr->name, w32_strerror (-1));
return gpg_error_from_syserror ();
}
if (!GetFileAttributesExW (wfname, GetFileExInfoStandard, &fad))
{
log_error ("error stat-ing `%s': %s\n", hdr->name, w32_strerror (-1));
xfree (wfname);
return gpg_error_from_syserror ();
}
xfree (wfname);
attr = fad.dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_NORMAL))
hdr->typeflag = TF_REGULAR;
else if ((attr & FILE_ATTRIBUTE_DIRECTORY))
hdr->typeflag = TF_DIRECTORY;
else if ((attr & FILE_ATTRIBUTE_DEVICE))
hdr->typeflag = TF_NOTSUP;
else if ((attr & (FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_TEMPORARY)))
hdr->typeflag = TF_NOTSUP;
else
hdr->typeflag = TF_REGULAR;
/* Map some attributes to USTAR defined mode bits. */
hdr->mode = 0640; /* User may read and write, group only read. */
if ((attr & FILE_ATTRIBUTE_DIRECTORY))
hdr->mode |= 0110; /* Dirs are user and group executable. */
if ((attr & FILE_ATTRIBUTE_READONLY))
hdr->mode &= ~0200; /* Clear the user write bit. */
if ((attr & FILE_ATTRIBUTE_HIDDEN))
hdr->mode &= ~0707; /* Clear all user and other bits. */
if ((attr & FILE_ATTRIBUTE_SYSTEM))
hdr->mode |= 0004; /* Make it readable by other. */
/* Only set the size for a regular file. */
if (hdr->typeflag == TF_REGULAR)
hdr->size = (fad.nFileSizeHigh * (unsigned long long)(MAXDWORD+1)
+ fad.nFileSizeLow);
hdr->mtime = (((unsigned long long)fad.ftLastWriteTime.dwHighDateTime << 32)
| fad.ftLastWriteTime.dwLowDateTime);
if (!hdr->mtime)
hdr->mtime = (((unsigned long long)fad.ftCreationTime.dwHighDateTime << 32)
| fad.ftCreationTime.dwLowDateTime);
hdr->mtime -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01. */
hdr->mtime /= 10000000; /* Convert from 0.1us to seconds. */
return 0;
}
#endif /*HAVE_W32_SYSTEM*/
/* Given a fresh header obje`<ct HDR with only the name field set, try
to gather all available info. This is the POSIX version. */
#ifndef HAVE_W32_SYSTEM
static gpg_error_t
fillup_entry_posix (tar_header_t hdr)
{
gpg_error_t err;
struct stat sbuf;
@ -132,38 +206,36 @@ fillup_entry (tar_header_t hdr)
hdr->mtime = sbuf.st_mtime;
return 0;
}
#endif /*!HAVE_W32_SYSTEM*/
/* Add a new entry. The name of a director entry is ENTRYNAME; if
that is NULL, DNAME is the name of the directory itself. Under
Windows ENTRYNAME shall have backslashes replaced by standard
slashes. */
static gpg_error_t
add_entry (const char *dname, size_t dnamelen, struct dirent *de,
scanctrl_t scanctrl)
add_entry (const char *dname, const char *entryname, scanctrl_t scanctrl)
{
gpg_error_t err;
tar_header_t hdr;
char *p;
size_t dnamelen = strlen (dname);
assert (dnamelen);
hdr = xtrycalloc (1, sizeof *hdr + dnamelen + 1
+ (de? strlen (de->d_name) : 0));
+ (entryname? strlen (entryname) : 0) + 1);
if (!hdr)
{
err = gpg_error_from_syserror ();
log_error (_("error reading directory `%s': %s\n"),
dname, gpg_strerror (err));
return err;
}
return gpg_error_from_syserror ();
p = stpcpy (hdr->name, dname);
if (de)
if (entryname)
{
if (dname[dnamelen-1] != '/')
*p++ = '/';
strcpy (p, de->d_name);
strcpy (p, entryname);
}
else
{
@ -171,11 +243,10 @@ add_entry (const char *dname, size_t dnamelen, struct dirent *de,
hdr->name[dnamelen-1] = 0;
}
#ifdef HAVE_DOSISH_SYSTEM
for (p=hdr->name; *p; p++)
if (*p == '\\')
*p = '/';
err = fillup_entry_w32 (hdr);
#else
err = fillup_entry_posix (hdr);
#endif
err = fillup_entry (hdr);
if (err)
xfree (hdr);
else
@ -194,12 +265,101 @@ static gpg_error_t
scan_directory (const char *dname, scanctrl_t scanctrl)
{
gpg_error_t err = 0;
size_t dnamelen;
#ifdef HAVE_W32_SYSTEM
WIN32_FIND_DATAW fi;
HANDLE hd = INVALID_HANDLE_VALUE;
char *p;
if (!*dname)
return 0; /* An empty directory name has no entries. */
{
char *fname;
wchar_t *wfname;
fname = xtrymalloc (strlen (dname) + 2 + 2 + 1);
if (!fname)
{
err = gpg_error_from_syserror ();
goto leave;
}
if (!strcmp (dname, "/"))
strcpy (fname, "/*"); /* Trailing slash is not allowed. */
else if (!strcmp (dname, "."))
strcpy (fname, "*");
else if (*dname && dname[strlen (dname)-1] == '/')
strcpy (stpcpy (fname, dname), "*");
else if (*dname && dname[strlen (dname)-1] != '*')
strcpy (stpcpy (fname, dname), "/*");
else
strcpy (fname, dname);
for (p=fname; *p; p++)
if (*p == '/')
*p = '\\';
wfname = utf8_to_wchar (fname);
xfree (fname);
if (!wfname)
{
err = gpg_error_from_syserror ();
log_error (_("error reading directory `%s': %s\n"),
dname, gpg_strerror (err));
goto leave;
}
hd = FindFirstFileW (wfname, &fi);
if (hd == INVALID_HANDLE_VALUE)
{
err = gpg_error_from_syserror ();
log_error (_("error reading directory `%s': %s\n"),
dname, w32_strerror (-1));
xfree (wfname);
goto leave;
}
xfree (wfname);
}
do
{
char *fname = wchar_to_utf8 (fi.cFileName);
if (!fname)
{
err = gpg_error_from_syserror ();
log_error ("error utf8-ing filename: %s\n", w32_strerror (-1));
break;
}
for (p=fname; *p; p++)
if (*p == '\\')
*p = '/';
if (!strcmp (fname, "." ) || !strcmp (fname, ".."))
err = 0; /* Skip self and parent dir entry. */
else if (!strncmp (dname, "./", 2) && dname[2])
err = add_entry (dname+2, fname, scanctrl);
else
err = add_entry (dname, fname, scanctrl);
xfree (fname);
}
while (!err && FindNextFileW (hd, &fi));
if (err)
;
else if (GetLastError () == ERROR_NO_MORE_FILES)
err = 0;
else
{
err = gpg_error_from_syserror ();
log_error (_("error reading directory `%s': %s\n"),
dname, w32_strerror (-1));
}
leave:
if (hd != INVALID_HANDLE_VALUE)
FindClose (hd);
#else /*!HAVE_W32_SYSTEM*/
DIR *dir;
struct dirent *de;
dnamelen = strlen (dname);
if (!dnamelen)
if (!*dname)
return 0; /* An empty directory name has no entries. */
dir = opendir (dname);
@ -216,13 +376,14 @@ scan_directory (const char *dname, scanctrl_t scanctrl)
if (!strcmp (de->d_name, "." ) || !strcmp (de->d_name, ".."))
continue; /* Skip self and parent dir entry. */
err = add_entry (dname, dnamelen, de, scanctrl);
err = add_entry (dname, de->d_name, scanctrl);
if (err)
goto leave;
}
leave:
closedir (dir);
#endif /*!HAVE_W32_SYSTEM*/
return err;
}
@ -343,6 +504,9 @@ store_uname (char *buffer, size_t length, unsigned long uid)
if (!initialized || uid != lastuid)
{
#ifdef HAVE_W32_SYSTEM
mem2str (lastuname, uid? "user":"root", sizeof lastuname);
#else
struct passwd *pw = getpwuid (uid);
lastuid = uid;
@ -354,6 +518,7 @@ store_uname (char *buffer, size_t length, unsigned long uid)
log_info ("failed to get name for uid %lu\n", uid);
*lastuname = 0;
}
#endif
}
mem2str (buffer, lastuname, length);
}
@ -368,6 +533,9 @@ store_gname (char *buffer, size_t length, unsigned long gid)
if (!initialized || gid != lastgid)
{
#ifdef HAVE_W32_SYSTEM
mem2str (lastgname, gid? "users":"root", sizeof lastgname);
#else
struct group *gr = getgrgid (gid);
lastgid = gid;
@ -379,6 +547,7 @@ store_gname (char *buffer, size_t length, unsigned long gid)
log_info ("failed to get name for gid %lu\n", gid);
*lastgname = 0;
}
#endif
}
mem2str (buffer, lastgname, length);
}
@ -446,6 +615,7 @@ build_header (void *record, tar_header_t hdr)
store_uname (raw->uname, sizeof raw->uname, hdr->uid);
store_gname (raw->gname, sizeof raw->gname, hdr->gid);
#ifndef HAVE_W32_SYSTEM
if (hdr->typeflag == TF_SYMLINK)
{
int nread;
@ -460,7 +630,7 @@ build_header (void *record, tar_header_t hdr)
}
raw->linkname[nread] = 0;
}
#endif /*HAVE_W32_SYSTEM*/
/* Compute the checksum. */
memset (raw->checksum, ' ', sizeof raw->checksum);
@ -520,6 +690,8 @@ write_file (estream_t stream, tar_header_t hdr)
while (hdr->nrecords--)
{
nbytes = hdr->nrecords? RECORDSIZE : (hdr->size % RECORDSIZE);
if (!nbytes)
nbytes = RECORDSIZE;
nread = es_fread (record, 1, nbytes, infp);
if (nread != nbytes)
{
@ -572,24 +744,40 @@ gpgtar_create (char **inpattern)
struct scanctrl_s scanctrl_buffer;
scanctrl_t scanctrl = &scanctrl_buffer;
tar_header_t hdr, *start_tail;
estream_t outstream;
estream_t outstream = NULL;
memset (scanctrl, 0, sizeof *scanctrl);
scanctrl->flist_tail = &scanctrl->flist;
for (; (pattern = *inpattern); inpattern++)
{
char *pat, *p;
if (!*pattern)
continue;
pat = xtrystrdup (pattern);
if (!pat)
{
err = gpg_error_from_syserror ();
log_error ("memory allocation problem: %s\n", gpg_strerror (err));
goto leave;
}
for (p=pat; *p; p++)
if (*p == '\\')
*p = '/';
if (opt.verbose > 1)
log_info ("scanning `%s'\n", pattern);
log_info ("scanning `%s'\n", pat);
start_tail = scanctrl->flist_tail;
if (!pattern_valid_p (pattern))
log_error ("skipping invalid name `%s'\n", pattern);
else if (!add_entry (pattern, strlen (pattern), NULL, scanctrl)
if (!pattern_valid_p (pat))
log_error ("skipping invalid name `%s'\n", pat);
else if (!add_entry (pat, NULL, scanctrl)
&& *start_tail && ((*start_tail)->typeflag & TF_DIRECTORY))
scan_recursive (pattern, scanctrl);
scan_recursive (pat, scanctrl);
xfree (pat);
}
if (opt.outfile)

View File

@ -32,7 +32,6 @@
#include "gpgtar.h"
static gpg_error_t
extract_regular (estream_t stream, const char *dirname,
tar_header_t hdr)
@ -79,6 +78,8 @@ extract_regular (estream_t stream, const char *dirname,
/* Fixme: Set permissions etc. */
leave:
if (!err && opt.verbose)
log_info ("extracted `%s/'\n", fname);
es_fclose (outfp);
if (err && fname && outfp)
{
@ -96,7 +97,9 @@ extract_directory (const char *dirname, tar_header_t hdr)
{
gpg_error_t err;
char *fname;
size_t prefixlen;
prefixlen = strlen (dirname) + 1;
fname = strconcat (dirname, "/", hdr->name, NULL);
if (!fname)
{
@ -107,14 +110,40 @@ extract_directory (const char *dirname, tar_header_t hdr)
else
err = 0;
if (fname[strlen (fname)-1] == '/')
fname[strlen (fname)-1] = 0;
/* Note that we don't need to care about EEXIST because we always
extract into a new hierarchy. */
if (gnupg_mkdir (fname, "-rwx------"))
{
err = gpg_error_from_syserror ();
log_error ("error creating directory `%s': %s\n",
fname, gpg_strerror (err));
if (gpg_err_code (err) == GPG_ERR_ENOENT)
{
/* Try to create the directory with parents but keep the
original error code in case of a failure. */
char *p;
int rc = 0;
for (p = fname+prefixlen; (p = strchr (p, '/')); p++)
{
*p = 0;
rc = gnupg_mkdir (fname, "-rwx------");
*p = '/';
if (rc)
break;
}
if (!rc && !gnupg_mkdir (fname, "-rwx------"))
err = 0;
}
if (err)
log_error ("error creating directory `%s': %s\n",
fname, gpg_strerror (err));
}
leave:
if (!err && opt.verbose)
log_info ("created `%s/'\n", fname);
xfree (fname);
return err;
}
@ -155,7 +184,8 @@ extract (estream_t stream, const char *dirname, tar_header_t hdr)
{
char record[RECORDSIZE];
log_info ("unsupported file type for `%s' - skipped\n", hdr->name);
log_info ("unsupported file type %d for `%s' - skipped\n",
(int)hdr->typeflag, hdr->name);
for (err = 0, n=0; !err && n < hdr->nrecords; n++)
err = read_record (stream, record);
}
@ -171,9 +201,31 @@ static char *
create_directory (const char *dirprefix)
{
gpg_error_t err = 0;
char *prefix_buffer = NULL;
char *dirname = NULL;
size_t n;
int idx;
/* Remove common suffixes. */
n = strlen (dirprefix);
if (n > 4 && (!compare_filenames (dirprefix + n - 4, EXTSEP_S "gpg")
|| !compare_filenames (dirprefix + n - 4, EXTSEP_S "pgp")
|| !compare_filenames (dirprefix + n - 4, EXTSEP_S "asc")
|| !compare_filenames (dirprefix + n - 4, EXTSEP_S "pem")
|| !compare_filenames (dirprefix + n - 4, EXTSEP_S "p7e")))
{
prefix_buffer = xtrystrdup (dirprefix);
if (!prefix_buffer)
{
err = gpg_error_from_syserror ();
goto leave;
}
prefix_buffer[n-4] = 0;
dirprefix = prefix_buffer;
}
for (idx=1; idx < 5000; idx++)
{
xfree (dirname);
@ -184,14 +236,14 @@ create_directory (const char *dirprefix)
goto leave;
}
if (!gnupg_mkdir (dirname, "-rwx------"))
goto leave;
goto leave; /* Ready. */
if (errno != EEXIST && errno != ENOTDIR)
{
err = gpg_error_from_syserror ();
goto leave;
}
}
err = gpg_error_from_syserror ();
err = gpg_error (GPG_ERR_LIMIT_REACHED);
leave:
if (err)
@ -201,6 +253,7 @@ create_directory (const char *dirprefix)
xfree (dirname);
dirname = NULL;
}
xfree (prefix_buffer);
return dirname;
}
@ -217,9 +270,6 @@ gpgtar_extract (const char *filename)
if (filename)
{
dirprefix = strrchr (filename, '/');
if (dirprefix)
dirprefix++;
stream = es_fopen (filename, "rb");
if (!stream)
{
@ -231,6 +281,20 @@ gpgtar_extract (const char *filename)
else
stream = es_stdin; /* FIXME: How can we enforce binary mode? */
if (filename)
{
dirprefix = strrchr (filename, '/');
if (dirprefix)
dirprefix++;
}
else if (opt.filename)
{
dirprefix = strrchr (opt.filename, '/');
if (dirprefix)
dirprefix++;
}
if (!dirprefix || !*dirprefix)
dirprefix = "GPGARCH";

View File

@ -89,8 +89,7 @@ parse_header (const void *record, const char *filename)
for (namelen=0; namelen < sizeof raw->name && raw->name[namelen]; namelen++)
;
if (namelen == sizeof raw->name)
log_info ("%s: warning: name not terminated by a nul byte\n",
filename);
log_info ("%s: warning: name not terminated by a nul byte\n", filename);
for (n=namelen+1; n < sizeof raw->name; n++)
if (raw->name[n])
{

View File

@ -59,6 +59,7 @@ enum cmd_and_opt_values
aSignEncrypt,
oSkipCrypto,
oSetFilename,
aList
};
@ -82,6 +83,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")),
ARGPARSE_s_n (oSkipCrypto, "skip-crypto", N_("skip the crypto processing")),
ARGPARSE_s_s (oSetFilename, "set-filename", "@"),
ARGPARSE_end ()
};
@ -175,6 +177,7 @@ main (int argc, char **argv)
switch (pargs.r_opt)
{
case oOutput: opt.outfile = pargs.r.ret_str; break;
case oSetFilename: opt.filename = pargs.r.ret_str; break;
case oQuiet: opt.quiet = 1; break;
case oVerbose: opt.verbose++; break;
case oNoVerbose: opt.verbose = 0; break;
@ -208,6 +211,8 @@ main (int argc, char **argv)
if (argc > 1)
usage (1);
fname = argc ? *argv : NULL;
if (opt.filename)
log_info ("note: ignoring option --set-filename\n");
if (skip_crypto)
gpgtar_list (fname);
else
@ -217,6 +222,8 @@ main (int argc, char **argv)
case aEncrypt:
if (!argc)
usage (1);
if (opt.filename)
log_info ("note: ignoring option --set-filename\n");
if (skip_crypto)
gpgtar_create (argv);
else
@ -298,6 +305,7 @@ write_record (estream_t stream, const void *record)
/* Return true if FP is an unarmored OpenPGP message. Note that this
fucntion reads a few bytes from FP but pushes them back. */
#if 0
static int
openpgp_message_p (estream_t fp)
{
@ -332,7 +340,7 @@ openpgp_message_p (estream_t fp)
}
return 0;
}
#endif
@ -340,7 +348,8 @@ openpgp_message_p (estream_t fp)
static void
tar_and_encrypt (char **inpattern)
{
(void)inpattern;
log_error ("tar_and_encrypt has not yet been implemented\n");
}
@ -348,8 +357,8 @@ tar_and_encrypt (char **inpattern)
static void
decrypt_and_untar (const char *fname)
{
(void)fname;
log_error ("decrypt_and_untar has not yet been implemented\n");
}
@ -357,5 +366,6 @@ decrypt_and_untar (const char *fname)
static void
decrypt_and_list (const char *fname)
{
(void)fname;
log_error ("decrypt_and_list has not yet been implemented\n");
}

View File

@ -27,8 +27,9 @@ struct
{
int verbose;
int quiet;
char *outfile;
const char *outfile;
int symmetric;
const char *filename;
} opt;