mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-14 21:47:19 +02:00
Merge branch 'master' into gniibe/t6275
This commit is contained in:
commit
8e2207ecb9
104 changed files with 2231 additions and 1412 deletions
|
@ -83,7 +83,9 @@ gnupg_initialize_compliance (int gnupg_module_name)
|
|||
log_assert (! initialized);
|
||||
|
||||
/* We accept both OpenPGP-style and gcrypt-style algorithm ids.
|
||||
* Assert that they are compatible. */
|
||||
* Assert that they are compatible. At some places gcrypt ids are
|
||||
* used which can't be encoded in an OpenPGP algo octet; we also
|
||||
* assert this. */
|
||||
log_assert ((int) GCRY_PK_RSA == (int) PUBKEY_ALGO_RSA);
|
||||
log_assert ((int) GCRY_PK_RSA_E == (int) PUBKEY_ALGO_RSA_E);
|
||||
log_assert ((int) GCRY_PK_RSA_S == (int) PUBKEY_ALGO_RSA_S);
|
||||
|
@ -91,6 +93,9 @@ gnupg_initialize_compliance (int gnupg_module_name)
|
|||
log_assert ((int) GCRY_PK_DSA == (int) PUBKEY_ALGO_DSA);
|
||||
log_assert ((int) GCRY_PK_ECC == (int) PUBKEY_ALGO_ECDH);
|
||||
log_assert ((int) GCRY_PK_ELG == (int) PUBKEY_ALGO_ELGAMAL);
|
||||
log_assert ((int) GCRY_PK_ECDSA > 255);
|
||||
log_assert ((int) GCRY_PK_ECDH > 255);
|
||||
log_assert ((int) GCRY_PK_EDDSA > 255);
|
||||
log_assert ((int) GCRY_CIPHER_NONE == (int) CIPHER_ALGO_NONE);
|
||||
log_assert ((int) GCRY_CIPHER_IDEA == (int) CIPHER_ALGO_IDEA);
|
||||
log_assert ((int) GCRY_CIPHER_3DES == (int) CIPHER_ALGO_3DES);
|
||||
|
@ -159,6 +164,9 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
|
|||
case PUBKEY_ALGO_ECDH:
|
||||
case PUBKEY_ALGO_ECDSA:
|
||||
case PUBKEY_ALGO_EDDSA:
|
||||
case GCRY_PK_ECDSA:
|
||||
case GCRY_PK_ECDH:
|
||||
case GCRY_PK_EDDSA:
|
||||
algotype = is_ecc;
|
||||
break;
|
||||
|
||||
|
@ -211,7 +219,9 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
|
|||
|
||||
result = (curvename
|
||||
&& (algo == PUBKEY_ALGO_ECDH
|
||||
|| algo == PUBKEY_ALGO_ECDSA)
|
||||
|| algo == PUBKEY_ALGO_ECDSA
|
||||
|| algo == GCRY_PK_ECDH
|
||||
|| algo == GCRY_PK_ECDSA)
|
||||
&& (!strcmp (curvename, "brainpoolP256r1")
|
||||
|| !strcmp (curvename, "brainpoolP384r1")
|
||||
|| !strcmp (curvename, "brainpoolP512r1")));
|
||||
|
@ -292,6 +302,7 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
|||
break;
|
||||
|
||||
case PUBKEY_ALGO_ECDH:
|
||||
case GCRY_PK_ECDH:
|
||||
if (use == PK_USE_DECRYPTION)
|
||||
result = 1;
|
||||
else if (use == PK_USE_ENCRYPTION)
|
||||
|
@ -316,6 +327,7 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
|||
break;
|
||||
|
||||
case PUBKEY_ALGO_ECDSA:
|
||||
case GCRY_PK_ECDSA:
|
||||
if (use == PK_USE_VERIFICATION)
|
||||
result = 1;
|
||||
else
|
||||
|
@ -341,6 +353,10 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
|||
|
||||
|
||||
case PUBKEY_ALGO_EDDSA:
|
||||
if (use == PK_USE_VERIFICATION)
|
||||
result = 1;
|
||||
else /* We may not create such signatures in de-vs mode. */
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -45,7 +45,7 @@ enum gnupg_compliance_mode
|
|||
enum pk_use_case
|
||||
{
|
||||
PK_USE_ENCRYPTION, PK_USE_DECRYPTION,
|
||||
PK_USE_SIGNING, PK_USE_VERIFICATION,
|
||||
PK_USE_SIGNING, PK_USE_VERIFICATION
|
||||
};
|
||||
|
||||
/* Flags to distinguish public key algorithm variants. */
|
||||
|
|
|
@ -1110,6 +1110,20 @@ spawn_detached (gnupg_process_t process,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gnupg_spawn_helper (struct spawn_cb_arg *sca)
|
||||
{
|
||||
int *user_except = sca->arg;
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
if (user_except[0] == -1)
|
||||
sca->ask_inherit = 0;
|
||||
else
|
||||
sca->ask_inherit = 1;
|
||||
#else
|
||||
sca->except_fds = user_except;
|
||||
#endif
|
||||
}
|
||||
|
||||
gpg_err_code_t
|
||||
gnupg_process_spawn (const char *pgmname, const char *argv1[],
|
||||
unsigned int flags,
|
||||
|
|
|
@ -249,6 +249,9 @@ struct spawn_cb_arg {
|
|||
|
||||
#define GNUPG_PROCESS_STREAM_NONBLOCK (1 << 16)
|
||||
|
||||
/* Spawn helper. */
|
||||
void gnupg_spawn_helper (struct spawn_cb_arg *sca);
|
||||
|
||||
/* Spawn PGMNAME. */
|
||||
gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv[],
|
||||
unsigned int flags,
|
||||
|
|
|
@ -305,20 +305,6 @@ copy_buffer_flush (struct copy_buffer *c, estream_t sink)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_close_all (struct spawn_cb_arg *sca)
|
||||
{
|
||||
int *user_except = sca->arg;
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
if (user_except[0] == -1)
|
||||
sca->ask_inherit = 0;
|
||||
else
|
||||
sca->ask_inherit = 1;
|
||||
#else
|
||||
sca->except_fds = user_except;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Run the program PGMNAME with the command line arguments given in
|
||||
* the NULL terminates array ARGV. If INPUT is not NULL it will be
|
||||
* fed to stdin of the process. stderr is logged using log_info and
|
||||
|
@ -433,7 +419,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
|
|||
: GNUPG_PROCESS_STDIN_NULL)
|
||||
| GNUPG_PROCESS_STDOUT_PIPE
|
||||
| GNUPG_PROCESS_STDERR_PIPE),
|
||||
setup_close_all, exceptclose, &proc);
|
||||
gnupg_spawn_helper, exceptclose, &proc);
|
||||
gnupg_process_get_streams (proc, GNUPG_PROCESS_STREAM_NONBLOCK,
|
||||
input? &infp : NULL, &outfp, &errfp);
|
||||
if (extrapipe[0] != -1)
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
# if _WIN32_WINNT < 0x0600
|
||||
# define _WIN32_WINNT 0x0600 /* Required for SetProcessDEPPolicy. */
|
||||
# endif
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# endif
|
||||
|
@ -213,7 +216,21 @@ _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp)
|
|||
log_set_socket_dir_cb (gnupg_socketdir);
|
||||
|
||||
#if HAVE_W32_SYSTEM
|
||||
/* For Standard Windows we use our own parser for the command line
|
||||
/* Make sure that Data Execution Prevention is enabled. */
|
||||
if (GetSystemDEPPolicy () >= 2)
|
||||
{
|
||||
DWORD flags;
|
||||
BOOL perm;
|
||||
|
||||
if (!GetProcessDEPPolicy (GetCurrentProcess (), &flags, &perm))
|
||||
log_info ("error getting DEP policy: %s\n",
|
||||
w32_strerror (GetLastError()));
|
||||
else if (!(flags & PROCESS_DEP_ENABLE)
|
||||
&& !SetProcessDEPPolicy (PROCESS_DEP_ENABLE))
|
||||
log_info ("Warning: Enabling DEP failed: %s (%d,%d)\n",
|
||||
w32_strerror (GetLastError ()), (int)flags, (int)perm);
|
||||
}
|
||||
/* On Windows we use our own parser for the command line
|
||||
* so that we can return an array of utf-8 encoded strings. */
|
||||
prepare_w32_commandline (argcp, argvp);
|
||||
#else
|
||||
|
|
164
common/iobuf.c
164
common/iobuf.c
|
@ -1,7 +1,7 @@
|
|||
/* iobuf.c - File Handling for OpenPGP.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2008,
|
||||
* 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2015 g10 Code GmbH
|
||||
* Copyright (C) 2015, 2023 g10 Code GmbH
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -27,6 +27,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>
|
||||
|
@ -35,7 +36,6 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -95,6 +95,9 @@ typedef struct
|
|||
int eof_seen;
|
||||
int delayed_rc;
|
||||
int print_only_name; /* Flags indicating that fname is not a real file. */
|
||||
char peeked[32]; /* Read ahead buffer. */
|
||||
byte npeeked; /* Number of bytes valid in peeked. */
|
||||
byte upeeked; /* Number of bytes used from peeked. */
|
||||
char fname[1]; /* Name of the file. */
|
||||
} file_filter_ctx_t;
|
||||
|
||||
|
@ -207,7 +210,7 @@ fd_cache_invalidate (const char *fname)
|
|||
close_cache_t cc;
|
||||
int rc = 0;
|
||||
|
||||
assert (fname);
|
||||
log_assert (fname);
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("fd_cache_invalidate (%s)\n", fname);
|
||||
|
||||
|
@ -370,7 +373,7 @@ fd_cache_close (const char *fname, gnupg_fd_t fp)
|
|||
{
|
||||
close_cache_t cc;
|
||||
|
||||
assert (fp);
|
||||
log_assert (fp);
|
||||
if (!fname || !*fname)
|
||||
{
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
|
@ -411,7 +414,7 @@ fd_cache_open (const char *fname, const char *mode)
|
|||
{
|
||||
close_cache_t cc;
|
||||
|
||||
assert (fname);
|
||||
log_assert (fname);
|
||||
for (cc = close_cache; cc; cc = cc->next)
|
||||
{
|
||||
if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
|
||||
|
@ -458,7 +461,16 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
|
|||
if (control == IOBUFCTRL_UNDERFLOW)
|
||||
{
|
||||
log_assert (size); /* We need a buffer. */
|
||||
if (a->eof_seen)
|
||||
if (a->npeeked > a->upeeked)
|
||||
{
|
||||
nbytes = a->npeeked - a->upeeked;
|
||||
if (nbytes > size)
|
||||
nbytes = size;
|
||||
memcpy (buf, a->peeked + a->upeeked, nbytes);
|
||||
a->upeeked += nbytes;
|
||||
*ret_len = nbytes;
|
||||
}
|
||||
else if (a->eof_seen)
|
||||
{
|
||||
rc = -1;
|
||||
*ret_len = 0;
|
||||
|
@ -596,6 +608,73 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
|
|||
a->delayed_rc = 0;
|
||||
a->keep_open = 0;
|
||||
a->no_cache = 0;
|
||||
a->npeeked = 0;
|
||||
a->upeeked = 0;
|
||||
}
|
||||
else if (control == IOBUFCTRL_PEEK)
|
||||
{
|
||||
/* Peek on the input. */
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
unsigned long nread;
|
||||
|
||||
nbytes = 0;
|
||||
if (!ReadFile (f, a->peeked, sizeof a->peeked, &nread, NULL))
|
||||
{
|
||||
int ec = (int) GetLastError ();
|
||||
if (ec != ERROR_BROKEN_PIPE)
|
||||
{
|
||||
rc = gpg_error_from_errno (ec);
|
||||
log_error ("%s: read error: ec=%d\n", a->fname, ec);
|
||||
}
|
||||
a->npeeked = 0;
|
||||
}
|
||||
else if (!nread)
|
||||
{
|
||||
a->eof_seen = 1;
|
||||
a->npeeked = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
a->npeeked = nread;
|
||||
}
|
||||
|
||||
#else /* Unix */
|
||||
|
||||
int n;
|
||||
|
||||
peek_more:
|
||||
do
|
||||
{
|
||||
n = read (f, a->peeked + a->npeeked, sizeof a->peeked - a->npeeked);
|
||||
}
|
||||
while (n == -1 && errno == EINTR);
|
||||
if (n > 0)
|
||||
{
|
||||
a->npeeked += n;
|
||||
if (a->npeeked < sizeof a->peeked)
|
||||
goto peek_more;
|
||||
}
|
||||
else if (!n) /* eof */
|
||||
{
|
||||
if (a->npeeked)
|
||||
a->delayed_rc = -1;
|
||||
else
|
||||
a->eof_seen = 1;
|
||||
}
|
||||
else /* error */
|
||||
{
|
||||
rc = gpg_error_from_syserror ();
|
||||
if (gpg_err_code (rc) != GPG_ERR_EPIPE)
|
||||
log_error ("%s: read error: %s\n", a->fname, gpg_strerror (rc));
|
||||
if (a->npeeked)
|
||||
a->delayed_rc = rc;
|
||||
}
|
||||
#endif /* Unix */
|
||||
|
||||
size = a->npeeked < size? a->npeeked : size;
|
||||
memcpy (buf, a->peeked, size);
|
||||
*ret_len = size;
|
||||
rc = 0; /* Return success - the user needs to check ret_len. */
|
||||
}
|
||||
else if (control == IOBUFCTRL_DESC)
|
||||
{
|
||||
|
@ -632,7 +711,7 @@ file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf,
|
|||
|
||||
if (control == IOBUFCTRL_UNDERFLOW)
|
||||
{
|
||||
assert (size); /* We need a buffer. */
|
||||
log_assert (size); /* We need a buffer. */
|
||||
if (a->eof_seen)
|
||||
{
|
||||
rc = -1;
|
||||
|
@ -751,7 +830,7 @@ sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
|
|||
|
||||
if (control == IOBUFCTRL_UNDERFLOW)
|
||||
{
|
||||
assert (size); /* need a buffer */
|
||||
log_assert (size); /* need a buffer */
|
||||
if (a->eof_seen)
|
||||
{
|
||||
rc = -1;
|
||||
|
@ -846,7 +925,7 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
|
|||
size_t n = 0;
|
||||
|
||||
p = buf;
|
||||
assert (size); /* need a buffer */
|
||||
log_assert (size); /* need a buffer */
|
||||
if (a->eof) /* don't read any further */
|
||||
rc = -1;
|
||||
while (!rc && size)
|
||||
|
@ -974,7 +1053,7 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
|
|||
{ /* the complicated openpgp scheme */
|
||||
size_t blen, n, nbytes = size + a->buflen;
|
||||
|
||||
assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
|
||||
log_assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
|
||||
if (nbytes < OP_MIN_PARTIAL_CHUNK)
|
||||
{
|
||||
/* not enough to write a partial block out; so we store it */
|
||||
|
@ -998,12 +1077,12 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
|
|||
blen /= 2;
|
||||
c--;
|
||||
/* write the partial length header */
|
||||
assert (c <= 0x1f); /*;-) */
|
||||
log_assert (c <= 0x1f); /*;-) */
|
||||
c |= 0xe0;
|
||||
iobuf_put (chain, c);
|
||||
if ((n = a->buflen))
|
||||
{ /* write stuff from the buffer */
|
||||
assert (n == OP_MIN_PARTIAL_CHUNK);
|
||||
log_assert (n == OP_MIN_PARTIAL_CHUNK);
|
||||
if (iobuf_write (chain, a->buffer, n))
|
||||
rc = gpg_error_from_syserror ();
|
||||
a->buflen = 0;
|
||||
|
@ -1020,8 +1099,8 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
|
|||
/* store the rest in the buffer */
|
||||
if (!rc && nbytes)
|
||||
{
|
||||
assert (!a->buflen);
|
||||
assert (nbytes < OP_MIN_PARTIAL_CHUNK);
|
||||
log_assert (!a->buflen);
|
||||
log_assert (nbytes < OP_MIN_PARTIAL_CHUNK);
|
||||
if (!a->buffer)
|
||||
a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
|
||||
memcpy (a->buffer, p, nbytes);
|
||||
|
@ -1183,8 +1262,8 @@ iobuf_alloc (int use, size_t bufsize)
|
|||
iobuf_t a;
|
||||
static int number = 0;
|
||||
|
||||
assert (use == IOBUF_INPUT || use == IOBUF_INPUT_TEMP
|
||||
|| use == IOBUF_OUTPUT || use == IOBUF_OUTPUT_TEMP);
|
||||
log_assert (use == IOBUF_INPUT || use == IOBUF_INPUT_TEMP
|
||||
|| use == IOBUF_OUTPUT || use == IOBUF_OUTPUT_TEMP);
|
||||
if (bufsize == 0)
|
||||
{
|
||||
log_bug ("iobuf_alloc() passed a bufsize of 0!\n");
|
||||
|
@ -1304,7 +1383,7 @@ iobuf_temp_with_content (const char *buffer, size_t length)
|
|||
int i;
|
||||
|
||||
a = iobuf_alloc (IOBUF_INPUT_TEMP, length);
|
||||
assert (length == a->d.size);
|
||||
log_assert (length == a->d.size);
|
||||
/* memcpy (a->d.buf, buffer, length); */
|
||||
for (i=0; i < length; i++)
|
||||
a->d.buf[i] = buffer[i];
|
||||
|
@ -1335,7 +1414,7 @@ do_open (const char *fname, int special_filenames,
|
|||
int fd;
|
||||
byte desc[MAX_IOBUF_DESC];
|
||||
|
||||
assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT);
|
||||
log_assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT);
|
||||
|
||||
if (special_filenames
|
||||
/* NULL or '-'. */
|
||||
|
@ -1576,6 +1655,25 @@ iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
|
|||
return fd_cache_synchronize (ptrval);
|
||||
}
|
||||
}
|
||||
else if (cmd == IOBUF_IOCTL_PEEK)
|
||||
{
|
||||
/* Peek at a justed opened file. Use this only directly after a
|
||||
* file has been opened for reading. Don't use it after you did
|
||||
* a seek. This works only if just file filter has been
|
||||
* pushed. Expects a buffer wit size INTVAL at PTRVAL and returns
|
||||
* the number of bytes put into the buffer. */
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("iobuf-%d.%d: ioctl '%s' peek\n",
|
||||
a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a, desc));
|
||||
if (a->filter == file_filter && ptrval && intval)
|
||||
{
|
||||
file_filter_ctx_t *fcx = a->filter_ov;
|
||||
size_t len = intval;
|
||||
|
||||
if (!file_filter (fcx, IOBUFCTRL_PEEK, NULL, ptrval, &len))
|
||||
return (int)len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
|
@ -1755,13 +1853,13 @@ iobuf_pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
|
|||
if (a->use == IOBUF_INPUT_TEMP || a->use == IOBUF_OUTPUT_TEMP)
|
||||
{
|
||||
/* This should be the last filter in the pipeline. */
|
||||
assert (! a->chain);
|
||||
log_assert (! a->chain);
|
||||
return 0;
|
||||
}
|
||||
if (!a->filter)
|
||||
{ /* this is simple */
|
||||
b = a->chain;
|
||||
assert (b);
|
||||
log_assert (b);
|
||||
xfree (a->d.buf);
|
||||
xfree (a->real_fname);
|
||||
memcpy (a, b, sizeof *a);
|
||||
|
@ -1856,14 +1954,14 @@ underflow_target (iobuf_t a, int clear_pending_eof, size_t target)
|
|||
buffer. */
|
||||
return -1;
|
||||
|
||||
assert (a->use == IOBUF_INPUT);
|
||||
log_assert (a->use == IOBUF_INPUT);
|
||||
|
||||
a->e_d.used = 0;
|
||||
|
||||
/* If there is still some buffered data, then move it to the start
|
||||
of the buffer and try to fill the end of the buffer. (This is
|
||||
useful if we are called from iobuf_peek().) */
|
||||
assert (a->d.start <= a->d.len);
|
||||
log_assert (a->d.start <= a->d.len);
|
||||
a->d.len -= a->d.start;
|
||||
if (a->d.len)
|
||||
memmove (a->d.buf, &a->d.buf[a->d.start], a->d.len);
|
||||
|
@ -2027,7 +2125,7 @@ underflow_target (iobuf_t a, int clear_pending_eof, size_t target)
|
|||
}
|
||||
}
|
||||
|
||||
assert (a->d.start <= a->d.len);
|
||||
log_assert (a->d.start <= a->d.len);
|
||||
if (a->e_d.used > 0)
|
||||
return 0;
|
||||
if (a->d.start < a->d.len)
|
||||
|
@ -2107,7 +2205,7 @@ iobuf_readbyte (iobuf_t a)
|
|||
return -1;
|
||||
}
|
||||
|
||||
assert (a->d.start <= a->d.len);
|
||||
log_assert (a->d.start <= a->d.len);
|
||||
|
||||
if (a->nlimit && a->nbytes >= a->nlimit)
|
||||
return -1; /* forced EOF */
|
||||
|
@ -2119,7 +2217,7 @@ iobuf_readbyte (iobuf_t a)
|
|||
else if ((c = underflow (a, 1)) == -1)
|
||||
return -1; /* EOF */
|
||||
|
||||
assert (a->d.start <= a->d.len);
|
||||
log_assert (a->d.start <= a->d.len);
|
||||
|
||||
/* Note: if underflow doesn't return EOF, then it returns the first
|
||||
byte that was read and advances a->d.start appropriately. */
|
||||
|
@ -2244,8 +2342,8 @@ iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
|
|||
{
|
||||
int n = 0;
|
||||
|
||||
assert (buflen > 0);
|
||||
assert (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP);
|
||||
log_assert (buflen > 0);
|
||||
log_assert (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP);
|
||||
|
||||
if (buflen > a->d.size)
|
||||
/* We can't peek more than we can buffer. */
|
||||
|
@ -2261,7 +2359,7 @@ iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
|
|||
|
||||
/* Underflow consumes the first character (it's the return
|
||||
value). unget() it by resetting the "file position". */
|
||||
assert (a->d.start == 1);
|
||||
log_assert (a->d.start == 1);
|
||||
a->d.start = 0;
|
||||
}
|
||||
|
||||
|
@ -2296,7 +2394,7 @@ iobuf_writebyte (iobuf_t a, unsigned int c)
|
|||
if ((rc=filter_flush (a)))
|
||||
return rc;
|
||||
|
||||
assert (a->d.len < a->d.size);
|
||||
log_assert (a->d.len < a->d.size);
|
||||
a->d.buf[a->d.len++] = c;
|
||||
return 0;
|
||||
}
|
||||
|
@ -2397,8 +2495,8 @@ iobuf_writestr (iobuf_t a, const char *buf)
|
|||
int
|
||||
iobuf_write_temp (iobuf_t dest, iobuf_t source)
|
||||
{
|
||||
assert (source->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
|
||||
assert (dest->use == IOBUF_OUTPUT || dest->use == IOBUF_OUTPUT_TEMP);
|
||||
log_assert (source->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
|
||||
log_assert (dest->use == IOBUF_OUTPUT || dest->use == IOBUF_OUTPUT_TEMP);
|
||||
|
||||
iobuf_flush_temp (source);
|
||||
return iobuf_write (dest, source->d.buf, source->d.len);
|
||||
|
@ -2782,7 +2880,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
|
|||
NUL character in the buffer. This requires at least 2 bytes. We
|
||||
don't complicate the code by handling the stupid corner case, but
|
||||
simply assert that it can't happen. */
|
||||
assert (!buffer || length >= 2 || maxlen >= 2);
|
||||
log_assert (!buffer || length >= 2 || maxlen >= 2);
|
||||
|
||||
if (!buffer || length <= 1)
|
||||
/* must allocate a new buffer */
|
||||
|
@ -2853,7 +2951,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
|
|||
/* p is pointing at the last byte in the buffer. We
|
||||
always terminate the line with "\n\0" so overwrite
|
||||
the previous byte with a \n. */
|
||||
assert (p > buffer);
|
||||
log_assert (p > buffer);
|
||||
p[-1] = '\n';
|
||||
|
||||
/* Indicate truncation. */
|
||||
|
|
|
@ -106,6 +106,7 @@ enum
|
|||
IOBUFCTRL_FLUSH = 4,
|
||||
IOBUFCTRL_DESC = 5,
|
||||
IOBUFCTRL_CANCEL = 6,
|
||||
IOBUFCTRL_PEEK = 7,
|
||||
IOBUFCTRL_USER = 16
|
||||
};
|
||||
|
||||
|
@ -116,7 +117,8 @@ typedef enum
|
|||
IOBUF_IOCTL_KEEP_OPEN = 1, /* Uses intval. */
|
||||
IOBUF_IOCTL_INVALIDATE_CACHE = 2, /* Uses ptrval. */
|
||||
IOBUF_IOCTL_NO_CACHE = 3, /* Uses intval. */
|
||||
IOBUF_IOCTL_FSYNC = 4 /* Uses ptrval. */
|
||||
IOBUF_IOCTL_FSYNC = 4, /* Uses ptrval. */
|
||||
IOBUF_IOCTL_PEEK = 5 /* Uses intval and ptrval. */
|
||||
} iobuf_ioctl_t;
|
||||
|
||||
enum iobuf_use
|
||||
|
|
|
@ -154,6 +154,14 @@ map_static_macro_string (const char *string)
|
|||
membuf_t mb;
|
||||
char *p;
|
||||
|
||||
/* We use a hack if we don't use the fixed gpgrt 1.47
|
||||
* (commit 885a287a57cf060b4c5b441822c09d23b8dee2bd) */
|
||||
#if GPGRT_VERSION_NUMBER < 0x012f00
|
||||
if (string && !strncmp (string, "Project-Id-Version:", 19)
|
||||
&& strstr (string, "PO-Revision-Date:"))
|
||||
return "";
|
||||
#endif
|
||||
|
||||
if ((s = already_mapped (string)))
|
||||
return s;
|
||||
s = string;
|
||||
|
|
|
@ -418,7 +418,7 @@ decode_c_string (const char *src)
|
|||
/* Check whether (BUF,LEN) is valid header for an OpenPGP compressed
|
||||
* packet. LEN should be at least 6. */
|
||||
static int
|
||||
is_openpgp_compressed_packet (unsigned char *buf, size_t len)
|
||||
is_openpgp_compressed_packet (const unsigned char *buf, size_t len)
|
||||
{
|
||||
int c, ctb, pkttype;
|
||||
int lenbytes;
|
||||
|
@ -460,63 +460,64 @@ is_openpgp_compressed_packet (unsigned char *buf, size_t len)
|
|||
|
||||
|
||||
/*
|
||||
* Check if the file is compressed.
|
||||
* Check if the file is compressed. You need to pass the first bytes
|
||||
* of the file as (BUF,BUFLEN). Returns true if the buffer seems to
|
||||
* be compressed.
|
||||
*/
|
||||
int
|
||||
is_file_compressed (const char *s, int *ret_rc)
|
||||
is_file_compressed (const byte *buf, unsigned int buflen)
|
||||
{
|
||||
iobuf_t a;
|
||||
byte buf[6];
|
||||
int i;
|
||||
int rc = 0;
|
||||
int overflow;
|
||||
int i;
|
||||
|
||||
struct magic_compress_s {
|
||||
size_t len;
|
||||
byte magic[4];
|
||||
} magic[] = {
|
||||
{ 3, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */
|
||||
{ 3, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */
|
||||
{ 4, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */
|
||||
};
|
||||
struct magic_compress_s
|
||||
{
|
||||
byte len;
|
||||
byte extchk;
|
||||
byte magic[5];
|
||||
} magic[] =
|
||||
{
|
||||
{ 3, 0, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */
|
||||
{ 3, 0, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */
|
||||
{ 4, 0, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */
|
||||
{ 5, 0, { '%', 'P', 'D', 'F', '-'} }, /* PDF */
|
||||
{ 4, 1, { 0xff, 0xd8, 0xff, 0xe0 } }, /* Maybe JFIF */
|
||||
{ 5, 2, { 0x89, 'P','N','G', 0x0d} } /* Likely PNG */
|
||||
};
|
||||
|
||||
if ( iobuf_is_pipe_filename (s) || !ret_rc )
|
||||
return 0; /* We can't check stdin or no file was given */
|
||||
|
||||
a = iobuf_open( s );
|
||||
if ( a == NULL ) {
|
||||
*ret_rc = gpg_error_from_syserror ();
|
||||
return 0;
|
||||
}
|
||||
iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
|
||||
|
||||
if ( iobuf_get_filelength( a, &overflow ) < 6 && !overflow) {
|
||||
*ret_rc = 0;
|
||||
goto leave;
|
||||
if ( buflen < 6 )
|
||||
{
|
||||
return 0; /* Too short to check - assume uncompressed. */
|
||||
}
|
||||
|
||||
if ( iobuf_read( a, buf, 6 ) == -1 ) {
|
||||
*ret_rc = a->error;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
for ( i = 0; i < DIM( magic ); i++ ) {
|
||||
if ( !memcmp( buf, magic[i].magic, magic[i].len ) ) {
|
||||
*ret_rc = 0;
|
||||
rc = 1;
|
||||
goto leave;
|
||||
for ( i = 0; i < DIM (magic); i++ )
|
||||
{
|
||||
if (!memcmp( buf, magic[i].magic, magic[i].len))
|
||||
{
|
||||
switch (magic[i].extchk)
|
||||
{
|
||||
case 0:
|
||||
return 1; /* Is compressed. */
|
||||
case 1:
|
||||
if (buflen > 11 && !memcmp (buf + 6, "JFIF", 5))
|
||||
return 1; /* JFIF: this likely a compressed JPEG. */
|
||||
break;
|
||||
case 2:
|
||||
if (buflen > 8
|
||||
&& buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a)
|
||||
return 1; /* This is a PNG. */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_openpgp_compressed_packet (buf, 6))
|
||||
{
|
||||
*ret_rc = 0;
|
||||
rc = 1;
|
||||
}
|
||||
if (buflen >= 6 && is_openpgp_compressed_packet (buf, buflen))
|
||||
{
|
||||
return 1; /* Already compressed. */
|
||||
}
|
||||
|
||||
leave:
|
||||
iobuf_close( a );
|
||||
return rc;
|
||||
return 0; /* Not detected as compressed. */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -359,7 +359,7 @@ char *try_make_printable_string (const void *p, size_t n, int delim);
|
|||
char *make_printable_string (const void *p, size_t n, int delim);
|
||||
char *decode_c_string (const char *src);
|
||||
|
||||
int is_file_compressed (const char *s, int *ret_rc);
|
||||
int is_file_compressed (const byte *buf, unsigned int buflen);
|
||||
|
||||
int match_multistr (const char *multistr,const char *match);
|
||||
|
||||
|
|
|
@ -29,4 +29,4 @@ built on @BUILD_HOSTNAME@ at @BUILD_TIMESTAMP@\0"
|
|||
#define W32INFO_PRODUCTVERSION "@VERSION@\0"
|
||||
|
||||
#define W32INFO_LEGALCOPYRIGHT "Copyright \xa9 \
|
||||
2021 g10 Code GmbH\0"
|
||||
2023 g10 Code GmbH\0"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue