mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
Merge branch 'STABLE-BRANCH-2-4' into master
This commit is contained in:
commit
334f5d95c8
89 changed files with 3260 additions and 1400 deletions
|
@ -505,7 +505,8 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
|
|||
if (ec != ERROR_BROKEN_PIPE)
|
||||
{
|
||||
rc = gpg_error_from_errno (ec);
|
||||
log_error ("%s: read error: ec=%d\n", a->fname, ec);
|
||||
log_error ("%s: read error: %s (ec=%d)\n",
|
||||
a->fname, gpg_strerror (rc), ec);
|
||||
}
|
||||
}
|
||||
else if (!nread)
|
||||
|
@ -573,9 +574,10 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
|
|||
{
|
||||
if (size && !WriteFile (f, p, nbytes, &n, NULL))
|
||||
{
|
||||
int ec = (int) GetLastError ();
|
||||
rc = gpg_error_from_errno (ec);
|
||||
log_error ("%s: write error: ec=%d\n", a->fname, ec);
|
||||
int ec = gnupg_w32_set_errno (-1);
|
||||
rc = gpg_error_from_syserror ();
|
||||
log_error ("%s: write error: %s (ec=%d)\n",
|
||||
a->fname, gpg_strerror (rc), ec);
|
||||
break;
|
||||
}
|
||||
p += n;
|
||||
|
@ -634,7 +636,8 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
|
|||
if (ec != ERROR_BROKEN_PIPE)
|
||||
{
|
||||
rc = gpg_error_from_errno (ec);
|
||||
log_error ("%s: read error: ec=%d\n", a->fname, ec);
|
||||
log_error ("%s: read error: %s (ec=%d)\n",
|
||||
a->fname, gpg_strerror (rc), ec);
|
||||
}
|
||||
a->npeeked = 0;
|
||||
}
|
||||
|
@ -883,7 +886,8 @@ sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
|
|||
if (n == SOCKET_ERROR)
|
||||
{
|
||||
int ec = (int) WSAGetLastError ();
|
||||
rc = gpg_error_from_errno (ec);
|
||||
gnupg_w32_set_errno (ec);
|
||||
rc = gpg_error_from_syserror ();
|
||||
log_error ("socket write error: ec=%d\n", ec);
|
||||
break;
|
||||
}
|
||||
|
@ -2606,13 +2610,10 @@ iobuf_set_limit (iobuf_t a, off_t nlimit)
|
|||
}
|
||||
|
||||
|
||||
|
||||
off_t
|
||||
iobuf_get_filelength (iobuf_t a, int *overflow)
|
||||
/* Return the length of the file behind A. If there is no file, return 0. */
|
||||
uint64_t
|
||||
iobuf_get_filelength (iobuf_t a)
|
||||
{
|
||||
if (overflow)
|
||||
*overflow = 0;
|
||||
|
||||
/* Hmmm: file_filter may have already been removed */
|
||||
for ( ; a->chain; a = a->chain )
|
||||
;
|
||||
|
@ -2625,56 +2626,18 @@ iobuf_get_filelength (iobuf_t a, int *overflow)
|
|||
gnupg_fd_t fp = b->fp;
|
||||
|
||||
#if defined(HAVE_W32_SYSTEM)
|
||||
ulong size;
|
||||
static int (* __stdcall get_file_size_ex) (void *handle,
|
||||
LARGE_INTEGER *r_size);
|
||||
static int get_file_size_ex_initialized;
|
||||
LARGE_INTEGER exsize;
|
||||
|
||||
if (!get_file_size_ex_initialized)
|
||||
{
|
||||
void *handle;
|
||||
|
||||
handle = dlopen ("kernel32.dll", RTLD_LAZY);
|
||||
if (handle)
|
||||
{
|
||||
get_file_size_ex = dlsym (handle, "GetFileSizeEx");
|
||||
if (!get_file_size_ex)
|
||||
dlclose (handle);
|
||||
}
|
||||
get_file_size_ex_initialized = 1;
|
||||
}
|
||||
|
||||
if (get_file_size_ex)
|
||||
{
|
||||
/* This is a newer system with GetFileSizeEx; we use this
|
||||
then because it seem that GetFileSize won't return a
|
||||
proper error in case a file is larger than 4GB. */
|
||||
LARGE_INTEGER exsize;
|
||||
|
||||
if (get_file_size_ex (fp, &exsize))
|
||||
{
|
||||
if (!exsize.u.HighPart)
|
||||
return exsize.u.LowPart;
|
||||
if (overflow)
|
||||
*overflow = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((size=GetFileSize (fp, NULL)) != 0xffffffff)
|
||||
return size;
|
||||
}
|
||||
if (GetFileSizeEx (fp, &exsize))
|
||||
return exsize.QuadPart;
|
||||
log_error ("GetFileSize for handle %p failed: %s\n",
|
||||
fp, w32_strerror (-1));
|
||||
#else /*!HAVE_W32_SYSTEM*/
|
||||
{
|
||||
struct stat st;
|
||||
struct stat st;
|
||||
|
||||
if ( !fstat (fp, &st) )
|
||||
return st.st_size;
|
||||
log_error("fstat() failed: %s\n", strerror(errno) );
|
||||
}
|
||||
if ( !fstat (fp, &st) )
|
||||
return st.st_size;
|
||||
log_error("fstat() failed: %s\n", strerror(errno) );
|
||||
#endif /*!HAVE_W32_SYSTEM*/
|
||||
}
|
||||
|
||||
|
|
|
@ -584,12 +584,8 @@ size_t iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen);
|
|||
size_t iobuf_copy (iobuf_t dest, iobuf_t source);
|
||||
|
||||
/* Return the size of any underlying file. This only works with
|
||||
file_filter based pipelines.
|
||||
|
||||
On Win32, it is sometimes not possible to determine the size of
|
||||
files larger than 4GB. In this case, *OVERFLOW (if not NULL) is
|
||||
set to 1. Otherwise, *OVERFLOW is set to 0. */
|
||||
off_t iobuf_get_filelength (iobuf_t a, int *overflow);
|
||||
file_filter based pipelines. */
|
||||
uint64_t iobuf_get_filelength (iobuf_t a);
|
||||
#define IOBUF_FILELENGTH_LIMIT 0xffffffff
|
||||
|
||||
/* Return the file descriptor designating the underlying file. This
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* kska-io-support.c - Supporting functions for ksba reader and writer
|
||||
* Copyright (C) 2001-2005, 2007, 2010-2011, 2017 Werner Koch
|
||||
* Copyright (C) 2006 g10 Code GmbH
|
||||
* Copyright (C) 2006, 2023 g10 Code GmbH
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -26,6 +26,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||
* SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later)
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@ -96,6 +97,15 @@ struct writer_cb_parm_s
|
|||
|
||||
char *pem_name; /* Malloced. */
|
||||
|
||||
struct {
|
||||
gnupg_ksba_progress_cb_t cb;
|
||||
ctrl_t ctrl;
|
||||
u32 last_time; /* last time reported */
|
||||
uint64_t last; /* last amount reported */
|
||||
uint64_t current; /* current amount */
|
||||
uint64_t total; /* total amount */
|
||||
} progress;
|
||||
|
||||
int wrote_begin;
|
||||
int did_finish;
|
||||
|
||||
|
@ -110,6 +120,7 @@ struct writer_cb_parm_s
|
|||
|
||||
/* Context for this module's functions. */
|
||||
struct gnupg_ksba_io_s {
|
||||
int is_writer; /* True if this context refers a writer object. */
|
||||
union {
|
||||
struct reader_cb_parm_s rparm;
|
||||
struct writer_cb_parm_s wparm;
|
||||
|
@ -527,6 +538,33 @@ simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
|
|||
|
||||
|
||||
|
||||
/* Call the progress callback if its time. We do this very 2 seconds
|
||||
* or if FORCE is set. However, we also require that at least 64KiB
|
||||
* have been written to avoid unnecessary progress lines for small
|
||||
* files. */
|
||||
static gpg_error_t
|
||||
update_write_progress (struct writer_cb_parm_s *parm, size_t count, int force)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
u32 timestamp;
|
||||
|
||||
parm->progress.current += count;
|
||||
if (parm->progress.current >= (64*1024))
|
||||
{
|
||||
timestamp = make_timestamp ();
|
||||
if (force || (timestamp - parm->progress.last_time > 1))
|
||||
{
|
||||
parm->progress.last = parm->progress.current;
|
||||
parm->progress.last_time = timestamp;
|
||||
err = parm->progress.cb (parm->progress.ctrl,
|
||||
parm->progress.current,
|
||||
parm->progress.total);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
base64_writer_cb (void *cb_value, const void *buffer, size_t count)
|
||||
{
|
||||
|
@ -535,6 +573,8 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
|
|||
int i, c, idx, quad_count;
|
||||
const unsigned char *p;
|
||||
estream_t stream = parm->stream;
|
||||
int rc;
|
||||
size_t nleft;
|
||||
|
||||
if (!count)
|
||||
return 0;
|
||||
|
@ -557,7 +597,7 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
|
|||
for (i=0; i < idx; i++)
|
||||
radbuf[i] = parm->base64.radbuf[i];
|
||||
|
||||
for (p=buffer; count; p++, count--)
|
||||
for (p=buffer, nleft = count; nleft; p++, nleft--)
|
||||
{
|
||||
radbuf[idx++] = *p;
|
||||
if (idx > 2)
|
||||
|
@ -583,7 +623,11 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
|
|||
parm->base64.idx = idx;
|
||||
parm->base64.quad_count = quad_count;
|
||||
|
||||
return es_ferror (stream)? gpg_error_from_syserror () : 0;
|
||||
rc = es_ferror (stream)? gpg_error_from_syserror () : 0;
|
||||
/* Note that we use the unencoded count for the progress. */
|
||||
if (!rc && parm->progress.cb)
|
||||
rc = update_write_progress (parm, count, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -594,13 +638,16 @@ plain_writer_cb (void *cb_value, const void *buffer, size_t count)
|
|||
{
|
||||
struct writer_cb_parm_s *parm = cb_value;
|
||||
estream_t stream = parm->stream;
|
||||
int rc;
|
||||
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
es_write (stream, buffer, count, NULL);
|
||||
|
||||
return es_ferror (stream)? gpg_error_from_syserror () : 0;
|
||||
rc = es_ferror (stream)? gpg_error_from_syserror () : 0;
|
||||
if (!rc && parm->progress.cb)
|
||||
rc = update_write_progress (parm, count, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -610,6 +657,7 @@ base64_finish_write (struct writer_cb_parm_s *parm)
|
|||
unsigned char *radbuf;
|
||||
int c, idx, quad_count;
|
||||
estream_t stream = parm->stream;
|
||||
int rc;
|
||||
|
||||
if (!parm->wrote_begin)
|
||||
return 0; /* Nothing written or we are not called in base-64 mode. */
|
||||
|
@ -656,7 +704,10 @@ base64_finish_write (struct writer_cb_parm_s *parm)
|
|||
es_fputs ("-----\n", stream);
|
||||
}
|
||||
|
||||
return es_ferror (stream)? gpg_error_from_syserror () : 0;
|
||||
rc = es_ferror (stream)? gpg_error_from_syserror () : 0;
|
||||
if (!rc && parm->progress.cb)
|
||||
rc = update_write_progress (parm, 0, 1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -788,6 +839,7 @@ gnupg_ksba_create_writer (gnupg_ksba_io_t *ctx, unsigned int flags,
|
|||
*ctx = xtrycalloc (1, sizeof **ctx);
|
||||
if (!*ctx)
|
||||
return gpg_error_from_syserror ();
|
||||
(*ctx)->is_writer = 1;
|
||||
|
||||
rc = ksba_writer_new (&w);
|
||||
if (rc)
|
||||
|
@ -865,3 +917,37 @@ gnupg_ksba_destroy_writer (gnupg_ksba_io_t ctx)
|
|||
xfree (ctx->u.wparm.pem_name);
|
||||
xfree (ctx);
|
||||
}
|
||||
|
||||
|
||||
/* Set a callback to the writer object. CTRL will be bassed to the
|
||||
* callback. */
|
||||
void
|
||||
gnupg_ksba_set_progress_cb (gnupg_ksba_io_t ctx,
|
||||
gnupg_ksba_progress_cb_t cb, ctrl_t ctrl)
|
||||
{
|
||||
struct writer_cb_parm_s *parm;
|
||||
|
||||
if (!ctx || !ctx->is_writer)
|
||||
return; /* Currently only supported for writer objects. */
|
||||
parm = &ctx->u.wparm;
|
||||
|
||||
parm->progress.cb = cb;
|
||||
parm->progress.ctrl = ctrl;
|
||||
parm->progress.last_time = 0;
|
||||
parm->progress.last = 0;
|
||||
parm->progress.current = 0;
|
||||
parm->progress.total = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Update the total count for the progress thingy. */
|
||||
void
|
||||
gnupg_ksba_set_total (gnupg_ksba_io_t ctx, uint64_t total)
|
||||
{
|
||||
struct writer_cb_parm_s *parm;
|
||||
|
||||
if (!ctx || !ctx->is_writer)
|
||||
return; /* Currently only supported for writer objects. */
|
||||
parm = &ctx->u.wparm;
|
||||
parm->progress.total = total;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||
* SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later)
|
||||
*/
|
||||
|
||||
#ifndef GNUPG_KSBA_IO_SUPPORT_H
|
||||
|
@ -42,6 +43,10 @@
|
|||
/* Context object. */
|
||||
typedef struct gnupg_ksba_io_s *gnupg_ksba_io_t;
|
||||
|
||||
/* Progress callback type. */
|
||||
typedef gpg_error_t (*gnupg_ksba_progress_cb_t)(ctrl_t ctrl,
|
||||
uint64_t current,
|
||||
uint64_t total);
|
||||
|
||||
|
||||
gpg_error_t gnupg_ksba_create_reader (gnupg_ksba_io_t *ctx,
|
||||
|
@ -57,10 +62,13 @@ gpg_error_t gnupg_ksba_create_writer (gnupg_ksba_io_t *ctx,
|
|||
const char *pem_name,
|
||||
estream_t stream,
|
||||
ksba_writer_t *r_writer);
|
||||
|
||||
gpg_error_t gnupg_ksba_finish_writer (gnupg_ksba_io_t ctx);
|
||||
void gnupg_ksba_destroy_writer (gnupg_ksba_io_t ctx);
|
||||
|
||||
void gnupg_ksba_set_progress_cb (gnupg_ksba_io_t ctx,
|
||||
gnupg_ksba_progress_cb_t cb, ctrl_t ctrl);
|
||||
void gnupg_ksba_set_total (gnupg_ksba_io_t ctx, uint64_t total);
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -616,7 +616,7 @@ nve_next_value (nve_t entry, const char *name)
|
|||
|
||||
/* Return the string for the first entry in NVC with NAME. If an
|
||||
* entry with NAME is missing in NVC or its value is the empty string
|
||||
* NULL is returned. Note that the The returned string is a pointer
|
||||
* NULL is returned. Note that the the returned string is a pointer
|
||||
* into NVC. */
|
||||
const char *
|
||||
nvc_get_string (nvc_t nvc, const char *name)
|
||||
|
|
|
@ -1689,10 +1689,16 @@ format_text (const char *text_in, int target_cols, int max_cols)
|
|||
}
|
||||
|
||||
|
||||
/* Substitute environment variables in STRING and return a new string.
|
||||
* On error the function returns NULL. */
|
||||
/* Substitute variables in STRING and return a new string. GETVAL is
|
||||
* a function which maps NAME to its value; that value is a string
|
||||
* which may not change during the execution time of this function.
|
||||
* If GETVAL returns NULL substitute_vars returns NULL and the caller
|
||||
* may inspect ERRNO for the reason. In all other error cases this
|
||||
* function also returns NULL. Caller must free the returned string. */
|
||||
char *
|
||||
substitute_envvars (const char *string)
|
||||
substitute_vars (const char *string,
|
||||
const char *(*getval)(void *cookie, const char *name),
|
||||
void *cookie)
|
||||
{
|
||||
char *line, *p, *pend;
|
||||
const char *value;
|
||||
|
@ -1743,19 +1749,22 @@ substitute_envvars (const char *string)
|
|||
{
|
||||
int save = *pend;
|
||||
*pend = 0;
|
||||
value = getenv (p+2);
|
||||
value = getval (cookie, p+2);
|
||||
*pend++ = save;
|
||||
}
|
||||
else
|
||||
{
|
||||
int save = *pend;
|
||||
*pend = 0;
|
||||
value = getenv (p+1);
|
||||
value = getval (cookie, p+1);
|
||||
*pend = save;
|
||||
}
|
||||
|
||||
if (!value)
|
||||
value = "";
|
||||
{
|
||||
xfree (result);
|
||||
return NULL;
|
||||
}
|
||||
valuelen = strlen (value);
|
||||
if (valuelen <= pend - p)
|
||||
{
|
||||
|
@ -1791,3 +1800,26 @@ substitute_envvars (const char *string)
|
|||
leave:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Helper for substitute_envvars. */
|
||||
static const char *
|
||||
subst_getenv (void *cookie, const char *name)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
(void)cookie;
|
||||
|
||||
s = getenv (name);
|
||||
return s? s : "";
|
||||
}
|
||||
|
||||
|
||||
/* Substitute environment variables in STRING and return a new string.
|
||||
* On error the function returns NULL. */
|
||||
char *
|
||||
substitute_envvars (const char *string)
|
||||
{
|
||||
return substitute_vars (string, subst_getenv, NULL);
|
||||
|
||||
}
|
||||
|
|
|
@ -169,7 +169,10 @@ int compare_version_strings (const char *my_version, const char *req_version);
|
|||
/* Format a string so that it fits within about TARGET_COLS columns. */
|
||||
char *format_text (const char *text, int target_cols, int max_cols);
|
||||
|
||||
/* Substitute environmen variabales in STRING. */
|
||||
/* Substitute variables in STRING. */
|
||||
char *substitute_vars (const char *string,
|
||||
const char *(*getval)(void *cookie, const char *name),
|
||||
void *cookie);
|
||||
char *substitute_envvars (const char *string);
|
||||
|
||||
|
||||
|
|
|
@ -327,9 +327,10 @@ map_w32_to_errno (DWORD w32_err)
|
|||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
||||
|
||||
/* Set ERRNO from the Windows error. EC may be -1 to use the last error. */
|
||||
/* Set ERRNO from the Windows error. EC may be -1 to use the last
|
||||
* error. Returns the Windows error code. */
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
void
|
||||
int
|
||||
gnupg_w32_set_errno (int ec)
|
||||
{
|
||||
/* FIXME: Replace by gpgrt_w32_set_errno. */
|
||||
|
|
|
@ -111,7 +111,7 @@ int gnupg_inotify_has_name (int fd, const char *name);
|
|||
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
void gnupg_w32_set_errno (int ec);
|
||||
int gnupg_w32_set_errno (int ec);
|
||||
void *w32_get_user_sid (void);
|
||||
|
||||
#include "../common/w32help.h"
|
||||
|
|
|
@ -150,13 +150,16 @@ find_tlv_unchecked (const unsigned char *buffer, size_t length,
|
|||
|
||||
|
||||
/* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag
|
||||
and the length part from the TLV triplet. Update BUFFER and SIZE
|
||||
on success. */
|
||||
* and the length part from the TLV triplet. Update BUFFER and SIZE
|
||||
* on success. Note that this function does not check that the value
|
||||
* fits into the provided buffer; this allows to work on the TL part
|
||||
* of a TLV. */
|
||||
gpg_error_t
|
||||
parse_ber_header (unsigned char const **buffer, size_t *size,
|
||||
int *r_class, int *r_tag,
|
||||
int *r_constructed, int *r_ndef,
|
||||
size_t *r_length, size_t *r_nhdr){
|
||||
size_t *r_length, size_t *r_nhdr)
|
||||
{
|
||||
int c;
|
||||
unsigned long tag;
|
||||
const unsigned char *buf = *buffer;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue