Merge branch 'STABLE-BRANCH-2-2' into master

--

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2017-12-18 16:38:02 +01:00
commit c817e75028
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
20 changed files with 429 additions and 252 deletions

View File

@ -136,6 +136,7 @@ enum cmd_and_opt_values
oDisableCheckOwnSocket, oDisableCheckOwnSocket,
oS2KCount, oS2KCount,
oAutoExpandSecmem, oAutoExpandSecmem,
oListenBacklog,
oWriteEnvFile oWriteEnvFile
}; };
@ -255,6 +256,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_op_u (oAutoExpandSecmem, "auto-expand-secmem", "@"), ARGPARSE_op_u (oAutoExpandSecmem, "auto-expand-secmem", "@"),
ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
/* Dummy options for backward compatibility. */ /* Dummy options for backward compatibility. */
ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"), ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"),
ARGPARSE_s_n (oUseStandardSocket, "use-standard-socket", "@"), ARGPARSE_s_n (oUseStandardSocket, "use-standard-socket", "@"),
@ -371,6 +374,10 @@ static assuan_sock_nonce_t socket_nonce_extra;
static assuan_sock_nonce_t socket_nonce_browser; static assuan_sock_nonce_t socket_nonce_browser;
static assuan_sock_nonce_t socket_nonce_ssh; static assuan_sock_nonce_t socket_nonce_ssh;
/* Value for the listen() backlog argument. We use the same value for
* all sockets - 64 is on current Linux half of the default maximum.
* Let's try this as default. Change at runtime with --listen-backlog. */
static int listen_backlog = 64;
/* Default values for options passed to the pinentry. */ /* Default values for options passed to the pinentry. */
static char *default_display; static char *default_display;
@ -1245,6 +1252,10 @@ main (int argc, char **argv )
(unsigned int)pargs.r.ret_ulong, 0); (unsigned int)pargs.r.ret_ulong, 0);
break; break;
case oListenBacklog:
listen_backlog = pargs.r.ret_int;
break;
case oDebugQuickRandom: case oDebugQuickRandom:
/* Only used by the first stage command line parser. */ /* Only used by the first stage command line parser. */
break; break;
@ -2248,9 +2259,10 @@ create_server_socket (char *name, int primary, int cygwin,
log_error (_("can't set permissions of '%s': %s\n"), log_error (_("can't set permissions of '%s': %s\n"),
unaddr->sun_path, strerror (errno)); unaddr->sun_path, strerror (errno));
if (listen (FD2INT(fd), 5 ) == -1) if (listen (FD2INT(fd), listen_backlog ) == -1)
{ {
log_error (_("listen() failed: %s\n"), strerror (errno)); log_error ("listen(fd,%d) failed: %s\n",
listen_backlog, strerror (errno));
*name = 0; /* Inhibit removal of the socket by cleanup(). */ *name = 0; /* Inhibit removal of the socket by cleanup(). */
assuan_sock_close (fd); assuan_sock_close (fd);
xfree (unaddr); xfree (unaddr);

View File

@ -541,7 +541,17 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
#else /* Unix and stat(2) available. */ #else /* Unix and stat(2) available. */
static const char * const bases[] = { "/run", "/var/run", NULL}; static const char * const bases[] = {
#ifdef USE_RUN_GNUPG_USER_SOCKET
"/run/gnupg",
#endif
"/run",
#ifdef USE_RUN_GNUPG_USER_SOCKET
"/var/run/gnupg",
#endif
"/var/run",
NULL
};
int i; int i;
struct stat sb; struct stat sb;
char prefix[13 + 1 + 20 + 6 + 1]; char prefix[13 + 1 + 20 + 6 + 1];
@ -559,7 +569,7 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
* as a background process with no (desktop) user logged in. Thus * as a background process with no (desktop) user logged in. Thus
* we better don't do that. */ * we better don't do that. */
/* Check whether we have a /run/user dir. */ /* Check whether we have a /run/[gnupg/]user dir. */
for (i=0; bases[i]; i++) for (i=0; bases[i]; i++)
{ {
snprintf (prefix, sizeof prefix, "%s/user/%u", snprintf (prefix, sizeof prefix, "%s/user/%u",

View File

@ -1738,6 +1738,22 @@ if test x"$gnupg_builddir_envvar" = x"yes"; then
[This is only used with "make distcheck"]) [This is only used with "make distcheck"])
fi fi
#
# To avoid problems with systemd cleaning up the /run/user directory,
# this option will make GnuPG try to use /run/gnupg/user as socket dir
# before /run/user
#
AC_ARG_ENABLE(run-gnupg-user-socket,
AC_HELP_STRING([--enable-run-gnupg-user-socket],
[try /run/gnupg/user for sockets prior to /run/user]),
use_run_gnupg_user_socket=$enableval)
if test x"$use_run_gnupg_user_socket" = x"yes"; then
AC_DEFINE(USE_RUN_GNUPG_USER_SOCKET, 1,
[If defined try /run/gnupg/user before /run/user])
fi
# #
# Decide what to build # Decide what to build
# #

View File

@ -151,6 +151,7 @@ enum cmd_and_opt_values {
oResolverTimeout, oResolverTimeout,
oConnectTimeout, oConnectTimeout,
oConnectQuickTimeout, oConnectQuickTimeout,
oListenBacklog,
aTest aTest
}; };
@ -256,6 +257,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_i (oResolverTimeout, "resolver-timeout", "@"), ARGPARSE_s_i (oResolverTimeout, "resolver-timeout", "@"),
ARGPARSE_s_i (oConnectTimeout, "connect-timeout", "@"), ARGPARSE_s_i (oConnectTimeout, "connect-timeout", "@"),
ARGPARSE_s_i (oConnectQuickTimeout, "connect-quick-timeout", "@"), ARGPARSE_s_i (oConnectQuickTimeout, "connect-quick-timeout", "@"),
ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing " ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing "
"of all commands and options)\n")), "of all commands and options)\n")),
@ -296,6 +298,10 @@ static const char *redir_socket_name;
POSIX systems). */ POSIX systems). */
static assuan_sock_nonce_t socket_nonce; static assuan_sock_nonce_t socket_nonce;
/* Value for the listen() backlog argument.
* Change at runtime with --listen-backlog. */
static int listen_backlog = 64;
/* Only if this flag has been set will we remove the socket file. */ /* Only if this flag has been set will we remove the socket file. */
static int cleanup_socket; static int cleanup_socket;
@ -1019,6 +1025,10 @@ main (int argc, char **argv)
case oSocketName: socket_name = pargs.r.ret_str; break; case oSocketName: socket_name = pargs.r.ret_str; break;
case oListenBacklog:
listen_backlog = pargs.r.ret_int;
break;
default : pargs.err = configfp? 1:2; break; default : pargs.err = configfp? 1:2; break;
} }
} }
@ -1271,9 +1281,10 @@ main (int argc, char **argv)
log_error (_("can't set permissions of '%s': %s\n"), log_error (_("can't set permissions of '%s': %s\n"),
serv_addr.sun_path, strerror (errno)); serv_addr.sun_path, strerror (errno));
if (listen (FD2INT (fd), 5) == -1) if (listen (FD2INT (fd), listen_backlog) == -1)
{ {
log_error (_("listen() failed: %s\n"), strerror (errno)); log_error ("listen(fd,%d) failed: %s\n",
listen_backlog, strerror (errno));
assuan_sock_close (fd); assuan_sock_close (fd);
dirmngr_exit (1); dirmngr_exit (1);
} }

View File

@ -282,6 +282,10 @@ default values are 15 and 2 seconds. Note that the timeout values are
for each connection attempt; the connection code will attempt to for each connection attempt; the connection code will attempt to
connect all addresses listed for a server. connect all addresses listed for a server.
@item --listen-backlog @var{n}
@opindex listen-backlog
Set the size of the queue for pending connections. The default is 64.
@item --allow-version-check @item --allow-version-check
@opindex allow-version-check @opindex allow-version-check
Allow Dirmngr to connect to @code{https://versions.gnupg.org} to get Allow Dirmngr to connect to @code{https://versions.gnupg.org} to get

View File

@ -31,8 +31,7 @@
# #
# Example file: # Example file:
#========== #==========
# :staff gpg-agent allow-mark-trusted [change] # :staff gpg-agent min-passphrase-len 6 [change]
# gpg-agent min-passphrase-len 6
# #
# * gpg-agent min-passphrase-len [no-change] 8 # * gpg-agent min-passphrase-len [no-change] 8
# gpg-agent min-passphrase-nonalpha [no-change] 1 # gpg-agent min-passphrase-nonalpha [no-change] 1
@ -42,9 +41,9 @@
# gpg-agent enforce-passphrase-constraints [no-change] # gpg-agent enforce-passphrase-constraints [no-change]
# gpg-agent max-cache-ttl [no-change] 10800 # gpg-agent max-cache-ttl [no-change] 10800
# gpg-agent max-cache-ttl-ssh [no-change] 10800 # gpg-agent max-cache-ttl-ssh [no-change] 10800
# gpg-agent allow-mark-trusted [default]
# gpg-agent allow-mark-trusted [no-change]
# gpgsm enable-ocsp # gpgsm enable-ocsp
# gpg compliance [no-change]
# gpgsm compliance [no-change]
#=========== #===========
# All users in the group "staff" are allowed to change the value for # All users in the group "staff" are allowed to change the value for
# --allow-mark-trusted; gpgconf's default is not to allow a change # --allow-mark-trusted; gpgconf's default is not to allow a change

View File

@ -563,6 +563,9 @@ Ignore requests to change the current @code{tty} or X window system's
@code{DISPLAY} variable respectively. This is useful to lock the @code{DISPLAY} variable respectively. This is useful to lock the
pinentry to pop up at the @code{tty} or display you started the agent. pinentry to pop up at the @code{tty} or display you started the agent.
@item --listen-backlog @var{n}
@opindex listen-backlog
Set the size of the queue for pending connections. The default is 64.
@anchor{option --extra-socket} @anchor{option --extra-socket}
@item --extra-socket @var{name} @item --extra-socket @var{name}

View File

@ -236,6 +236,12 @@ a list of categories see the Libassuan manual.
Don't detach the process from the console. This is mainly useful for Don't detach the process from the console. This is mainly useful for
debugging. debugging.
@item --listen-backlog @var{n}
@opindex listen-backlog
Set the size of the queue for pending connections. The default is 64.
This option has an effect only if @option{--multi-server} is also
used.
@item --log-file @var{file} @item --log-file @var{file}
@opindex log-file @opindex log-file
Append all logging output to @var{file}. This is very helpful in Append all logging output to @var{file}. This is very helpful in

View File

@ -1,6 +1,6 @@
/* cipher.c - En-/De-ciphering filter /* cipher.c - En-/De-ciphering filter
* Copyright (C) 1998, 1999, 2000, 2001, 2003, * Copyright (C) 1998-2003, 2006, 2009 Free Software Foundation, Inc.
* 2006, 2009 Free Software Foundation, Inc. * Copyright (C) 1998-2003, 2006, 2009, 2017 Werner koch
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -16,6 +16,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0+
*/ */
#include <config.h> #include <config.h>
@ -39,124 +40,145 @@
static void static void
write_header( cipher_filter_context_t *cfx, IOBUF a ) write_header (cipher_filter_context_t *cfx, iobuf_t a)
{ {
gcry_error_t err; gcry_error_t err;
PACKET pkt; PACKET pkt;
PKT_encrypted ed; PKT_encrypted ed;
byte temp[18]; byte temp[18];
unsigned int blocksize; unsigned int blocksize;
unsigned int nprefix; unsigned int nprefix;
blocksize = openpgp_cipher_get_algo_blklen (cfx->dek->algo); blocksize = openpgp_cipher_get_algo_blklen (cfx->dek->algo);
if ( blocksize < 8 || blocksize > 16 ) if ( blocksize < 8 || blocksize > 16 )
log_fatal("unsupported blocksize %u\n", blocksize ); log_fatal ("unsupported blocksize %u\n", blocksize);
memset( &ed, 0, sizeof ed );
ed.len = cfx->datalen;
ed.extralen = blocksize+2;
ed.new_ctb = !ed.len;
if( cfx->dek->use_mdc ) {
ed.mdc_method = DIGEST_ALGO_SHA1;
gcry_md_open (&cfx->mdc_hash, DIGEST_ALGO_SHA1, 0);
if ( DBG_HASHING )
gcry_md_debug (cfx->mdc_hash, "creatmdc");
}
memset (&ed, 0, sizeof ed);
ed.len = cfx->datalen;
ed.extralen = blocksize + 2;
ed.new_ctb = !ed.len;
if (cfx->dek->use_mdc)
{ {
char buf[20]; ed.mdc_method = DIGEST_ALGO_SHA1;
gcry_md_open (&cfx->mdc_hash, DIGEST_ALGO_SHA1, 0);
snprintf (buf, sizeof buf, "%d %d", ed.mdc_method, cfx->dek->algo); if (DBG_HASHING)
write_status_text (STATUS_BEGIN_ENCRYPTION, buf); gcry_md_debug (cfx->mdc_hash, "creatmdc");
}
else if (!opt.no_mdc_warn)
{
log_info ("WARNING: "
"encrypting without integrity protection is dangerous\n");
} }
init_packet( &pkt ); write_status_printf (STATUS_BEGIN_ENCRYPTION, "%d %d",
pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED; ed.mdc_method, cfx->dek->algo);
pkt.pkt.encrypted = &ed;
if( build_packet( a, &pkt )) init_packet (&pkt);
log_bug("build_packet(ENCR_DATA) failed\n"); pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED;
nprefix = blocksize; pkt.pkt.encrypted = &ed;
gcry_randomize (temp, nprefix, GCRY_STRONG_RANDOM ); if (build_packet( a, &pkt))
temp[nprefix] = temp[nprefix-2]; log_bug ("build_packet(ENCR_DATA) failed\n");
temp[nprefix+1] = temp[nprefix-1]; nprefix = blocksize;
print_cipher_algo_note( cfx->dek->algo ); gcry_randomize (temp, nprefix, GCRY_STRONG_RANDOM );
err = openpgp_cipher_open (&cfx->cipher_hd, temp[nprefix] = temp[nprefix-2];
cfx->dek->algo, temp[nprefix+1] = temp[nprefix-1];
GCRY_CIPHER_MODE_CFB, print_cipher_algo_note (cfx->dek->algo);
(GCRY_CIPHER_SECURE err = openpgp_cipher_open (&cfx->cipher_hd,
| ((cfx->dek->use_mdc || cfx->dek->algo >= 100)? cfx->dek->algo,
0 : GCRY_CIPHER_ENABLE_SYNC))); GCRY_CIPHER_MODE_CFB,
if (err) { (GCRY_CIPHER_SECURE
/* We should never get an error here cause we already checked, | ((cfx->dek->use_mdc || cfx->dek->algo >= 100)?
* that the algorithm is available. */ 0 : GCRY_CIPHER_ENABLE_SYNC)));
BUG(); if (err)
{
/* We should never get an error here cause we already checked,
* that the algorithm is available. */
BUG();
} }
/* log_hexdump ("thekey", cfx->dek->key, cfx->dek->keylen); */
gcry_cipher_setkey (cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen);
gcry_cipher_setiv (cfx->cipher_hd, NULL, 0);
/* log_hexdump ("prefix", temp, nprefix+2); */
if (cfx->mdc_hash) /* Hash the "IV". */
gcry_md_write (cfx->mdc_hash, temp, nprefix+2 );
gcry_cipher_encrypt (cfx->cipher_hd, temp, nprefix+2, NULL, 0);
gcry_cipher_sync (cfx->cipher_hd);
iobuf_write (a, temp, nprefix+2);
/* log_hexdump( "thekey", cfx->dek->key, cfx->dek->keylen );*/ cfx->short_blklen_warn = (blocksize < 16);
gcry_cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen ); cfx->short_blklen_count = nprefix+2;
gcry_cipher_setiv( cfx->cipher_hd, NULL, 0 );
/* log_hexdump( "prefix", temp, nprefix+2 ); */ cfx->wrote_header = 1;
if (cfx->mdc_hash) /* Hash the "IV". */
gcry_md_write (cfx->mdc_hash, temp, nprefix+2 );
gcry_cipher_encrypt (cfx->cipher_hd, temp, nprefix+2, NULL, 0);
gcry_cipher_sync (cfx->cipher_hd);
iobuf_write(a, temp, nprefix+2);
cfx->header=1;
} }
/*
/**************** * This filter is used to en/de-cipher data with a symmetric algorithm
* This filter is used to en/de-cipher data with a conventional algorithm
*/ */
int int
cipher_filter( void *opaque, int control, cipher_filter (void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len)
IOBUF a, byte *buf, size_t *ret_len)
{ {
size_t size = *ret_len; cipher_filter_context_t *cfx = opaque;
cipher_filter_context_t *cfx = opaque; size_t size = *ret_len;
int rc=0; int rc = 0;
if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */ if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */
rc = -1; /* not yet used */ {
rc = -1; /* not yet used */
} }
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */ else if (control == IOBUFCTRL_FLUSH) /* encrypt */
log_assert(a); {
if( !cfx->header ) { log_assert (a);
write_header( cfx, a ); if (!cfx->wrote_header)
write_header (cfx, a);
if (cfx->mdc_hash)
gcry_md_write (cfx->mdc_hash, buf, size);
gcry_cipher_encrypt (cfx->cipher_hd, buf, size, NULL, 0);
if (cfx->short_blklen_warn)
{
cfx->short_blklen_count += size;
if (cfx->short_blklen_count > (150 * 1024 * 1024))
{
log_info ("WARNING: encrypting more than %d MiB with algorithm "
"%s should be avoided\n", 150,
openpgp_cipher_algo_name (cfx->dek->algo));
cfx->short_blklen_warn = 0; /* Don't show again. */
}
}
rc = iobuf_write (a, buf, size);
}
else if (control == IOBUFCTRL_FREE)
{
if (cfx->mdc_hash)
{
byte *hash;
int hashlen = gcry_md_get_algo_dlen (gcry_md_get_algo(cfx->mdc_hash));
byte temp[22];
log_assert (hashlen == 20);
/* We must hash the prefix of the MDC packet here. */
temp[0] = 0xd3;
temp[1] = 0x14;
gcry_md_putc (cfx->mdc_hash, temp[0]);
gcry_md_putc (cfx->mdc_hash, temp[1]);
gcry_md_final (cfx->mdc_hash);
hash = gcry_md_read (cfx->mdc_hash, 0);
memcpy(temp+2, hash, 20);
gcry_cipher_encrypt (cfx->cipher_hd, temp, 22, NULL, 0);
gcry_md_close (cfx->mdc_hash); cfx->mdc_hash = NULL;
if (iobuf_write( a, temp, 22))
log_error ("writing MDC packet failed\n");
} }
if (cfx->mdc_hash)
gcry_md_write (cfx->mdc_hash, buf, size);
gcry_cipher_encrypt (cfx->cipher_hd, buf, size, NULL, 0);
rc = iobuf_write( a, buf, size );
}
else if( control == IOBUFCTRL_FREE ) {
if( cfx->mdc_hash ) {
byte *hash;
int hashlen = gcry_md_get_algo_dlen (gcry_md_get_algo
(cfx->mdc_hash));
byte temp[22];
log_assert( hashlen == 20 ); gcry_cipher_close (cfx->cipher_hd);
/* We must hash the prefix of the MDC packet here. */ }
temp[0] = 0xd3; else if (control == IOBUFCTRL_DESC)
temp[1] = 0x14; {
gcry_md_putc (cfx->mdc_hash, temp[0]); mem2str (buf, "cipher_filter", *ret_len);
gcry_md_putc (cfx->mdc_hash, temp[1]); }
gcry_md_final (cfx->mdc_hash); return rc;
hash = gcry_md_read (cfx->mdc_hash, 0);
memcpy(temp+2, hash, 20);
gcry_cipher_encrypt (cfx->cipher_hd, temp, 22, NULL, 0);
gcry_md_close (cfx->mdc_hash); cfx->mdc_hash = NULL;
if( iobuf_write( a, temp, 22 ) )
log_error("writing MDC packet failed\n" );
}
gcry_cipher_close (cfx->cipher_hd);
}
else if( control == IOBUFCTRL_DESC ) {
mem2str (buf, "cipher_filter", *ret_len);
}
return rc;
} }

View File

@ -1430,6 +1430,11 @@ print_pka_or_dane_records (iobuf_t out, kbnode_t keyblock, PKT_public_key *pk,
char *hexfpr; char *hexfpr;
hexfpr = hexfingerprint (pk, NULL, 0); hexfpr = hexfingerprint (pk, NULL, 0);
if (!hexfpr)
{
err = gpg_error_from_syserror ();
goto leave;
}
hexdata = bin2hex (data, datalen, NULL); hexdata = bin2hex (data, datalen, NULL);
if (!hexdata) if (!hexdata)
{ {

View File

@ -92,10 +92,11 @@ typedef struct {
DEK *dek; DEK *dek;
u32 datalen; u32 datalen;
gcry_cipher_hd_t cipher_hd; gcry_cipher_hd_t cipher_hd;
int header; unsigned int wrote_header : 1;
unsigned int short_blklen_warn : 1;
unsigned long short_blklen_count;
gcry_md_hd_t mdc_hash; gcry_md_hd_t mdc_hash;
byte enchash[20]; byte enchash[20];
int create_mdc; /* flag will be set by the cipher filter */
} cipher_filter_context_t; } cipher_filter_context_t;

View File

@ -413,34 +413,35 @@ pubkeys_free (pubkey_t keys)
} }
} }
/* Returns all keys that match the search specification SEARCH_TERMS. /* Returns all keys that match the search specification SEARCH_TERMS.
*
This function also checks for and warns about duplicate entries in * This function also checks for and warns about duplicate entries in
the keydb, which can occur if the user has configured multiple * the keydb, which can occur if the user has configured multiple
keyrings or keyboxes or if a keyring or keybox was corrupted. * keyrings or keyboxes or if a keyring or keybox was corrupted.
*
Note: SEARCH_TERMS will not be expanded (i.e., it may not be a * Note: SEARCH_TERMS will not be expanded (i.e., it may not be a
group). * group).
*
USE is the operation for which the key is required. It must be * USE is the operation for which the key is required. It must be
either PUBKEY_USAGE_ENC, PUBKEY_USAGE_SIG, PUBKEY_USAGE_CERT or * either PUBKEY_USAGE_ENC, PUBKEY_USAGE_SIG, PUBKEY_USAGE_CERT or
PUBKEY_USAGE_AUTH. * PUBKEY_USAGE_AUTH.
*
XXX: Currently, only PUBKEY_USAGE_ENC and PUBKEY_USAGE_SIG are * INCLUDE_UNUSABLE indicates whether disabled keys are allowed.
implemented. * (Recipients specified with --encrypt-to and --hidden-encrypt-to may
* be disabled. It is possible to edit disabled keys.)
INCLUDE_UNUSABLE indicates whether disabled keys are allowed. *
(Recipients specified with --encrypt-to and --hidden-encrypt-to may * SOURCE is the context in which SEARCH_TERMS was specified, e.g.,
be disabled. It is possible to edit disabled keys.) * "--encrypt-to", etc. If this function is called interactively,
* then this should be NULL.
SOURCE is the context in which SEARCH_TERMS was specified, e.g., *
"--encrypt-to", etc. If this function is called interactively, * If WARN_POSSIBLY_AMBIGUOUS is set, then emits a warning if the user
then this should be NULL. * does not specify a long key id or a fingerprint.
*
If WARN_POSSIBLY_AMBIGUOUS is set, then emits a warning if the user * The results are placed in *KEYS. *KEYS must be NULL!
does not specify a long key id or a fingerprint. *
* Fixme: Currently, only PUBKEY_USAGE_ENC and PUBKEY_USAGE_SIG are
The results are placed in *KEYS. *KEYS must be NULL! */ * implemented. */
gpg_error_t gpg_error_t
get_pubkeys (ctrl_t ctrl, get_pubkeys (ctrl_t ctrl,
char *search_terms, int use, int include_unusable, char *source, char *search_terms, int use, int include_unusable, char *source,
@ -448,30 +449,23 @@ get_pubkeys (ctrl_t ctrl,
pubkey_t *r_keys) pubkey_t *r_keys)
{ {
/* We show a warning when a key appears multiple times in the DB. /* We show a warning when a key appears multiple times in the DB.
This can happen for two reasons: * This can happen for two reasons:
*
- The user has configured multiple keyrings or keyboxes. * - The user has configured multiple keyrings or keyboxes.
*
- The keyring or keybox has been corrupted in some way, e.g., a * - The keyring or keybox has been corrupted in some way, e.g., a
bug or a random process changing them. * bug or a random process changing them.
*
For each duplicate, we only want to show the key once. Hence, * For each duplicate, we only want to show the key once. Hence,
this list. */ * this list. */
static strlist_t key_dups; static strlist_t key_dups;
/* USE transformed to a string. */
char *use_str;
gpg_error_t err; gpg_error_t err;
char *use_str; /* USE transformed to a string. */
KEYDB_SEARCH_DESC desc; KEYDB_SEARCH_DESC desc;
GETKEY_CTX ctx; GETKEY_CTX ctx;
pubkey_t results = NULL; pubkey_t results = NULL;
pubkey_t r; pubkey_t r;
int count; int count;
char fingerprint[2 * MAX_FINGERPRINT_LEN + 1]; char fingerprint[2 * MAX_FINGERPRINT_LEN + 1];
if (DBG_LOOKUP) if (DBG_LOOKUP)
@ -503,7 +497,7 @@ get_pubkeys (ctrl_t ctrl,
search_terms, gpg_strerror (err)); search_terms, gpg_strerror (err));
if (!opt.quiet && source) if (!opt.quiet && source)
log_info (_("(check argument of option '%s')\n"), source); log_info (_("(check argument of option '%s')\n"), source);
goto out; goto leave;
} }
if (warn_possibly_ambiguous if (warn_possibly_ambiguous
@ -523,8 +517,16 @@ get_pubkeys (ctrl_t ctrl,
count = 0; count = 0;
do do
{ {
PKT_public_key *pk = xmalloc_clear (sizeof *pk); PKT_public_key *pk;
KBNODE kb; KBNODE kb;
pk = xtrycalloc (1, sizeof *pk);
if (!pk)
{
err = gpg_error_from_syserror ();
goto leave;
}
pk->req_usage = use; pk->req_usage = use;
if (! ctx) if (! ctx)
@ -533,17 +535,14 @@ get_pubkeys (ctrl_t ctrl,
else else
err = getkey_next (ctrl, ctx, pk, &kb); err = getkey_next (ctrl, ctx, pk, &kb);
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) /* No more results. */
/* No more results. */
{ {
xfree (pk); xfree (pk);
break; break;
} }
else if (err) else if (err) /* An error (other than "not found"). */
/* An error (other than "not found"). */
{ {
log_error (_("error looking up: %s\n"), log_error (_("error looking up: %s\n"), gpg_strerror (err));
gpg_strerror (err));
xfree (pk); xfree (pk);
break; break;
} }
@ -551,7 +550,13 @@ get_pubkeys (ctrl_t ctrl,
/* Another result! */ /* Another result! */
count ++; count ++;
r = xmalloc_clear (sizeof (*r)); r = xtrycalloc (1, sizeof (*r));
if (!r)
{
err = gpg_error_from_syserror ();
xfree (pk);
goto leave;
}
r->pk = pk; r->pk = pk;
r->keyblock = kb; r->keyblock = kb;
r->next = results; r->next = results;
@ -570,8 +575,7 @@ get_pubkeys (ctrl_t ctrl,
} }
if (! results && gpg_err_code (err) == GPG_ERR_NOT_FOUND) if (! results && gpg_err_code (err) == GPG_ERR_NOT_FOUND)
/* No match. */ { /* No match. */
{
if (DBG_LOOKUP) if (DBG_LOOKUP)
log_debug ("%s: '%s' not found.\n", __func__, search_terms); log_debug ("%s: '%s' not found.\n", __func__, search_terms);
@ -579,15 +583,15 @@ get_pubkeys (ctrl_t ctrl,
if (!opt.quiet && source) if (!opt.quiet && source)
log_info (_("(check argument of option '%s')\n"), source); log_info (_("(check argument of option '%s')\n"), source);
goto out; goto leave;
} }
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
/* No more matches. */ ; /* No more matches. */
;
else if (err) else if (err)
/* Some other error. An error message was already printed { /* Some other error. An error message was already printed out.
out. Free RESULTS and continue. */ * Free RESULTS and continue. */
goto out; goto leave;
}
/* Check for duplicates. */ /* Check for duplicates. */
if (DBG_LOOKUP) if (DBG_LOOKUP)
@ -607,8 +611,7 @@ get_pubkeys (ctrl_t ctrl,
{ {
if (cmp_public_keys (r->keyblock->pkt->pkt.public_key, if (cmp_public_keys (r->keyblock->pkt->pkt.public_key,
r2->keyblock->pkt->pkt.public_key) != 0) r2->keyblock->pkt->pkt.public_key) != 0)
/* Not a dup. */ { /* Not a dup. */
{
prevp = &r2->next; prevp = &r2->next;
next = r2->next; next = r2->next;
continue; continue;
@ -652,7 +655,7 @@ get_pubkeys (ctrl_t ctrl,
fingerprint, sizeof fingerprint)); fingerprint, sizeof fingerprint));
} }
out: leave:
if (err) if (err)
pubkeys_free (results); pubkeys_free (results);
else else
@ -723,8 +726,13 @@ get_pubkey (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
/* More init stuff. */ /* More init stuff. */
if (!pk) if (!pk)
{ {
pk = xmalloc_clear (sizeof *pk);
internal++; internal++;
pk = xtrycalloc (1, sizeof *pk);
if (!pk)
{
rc = gpg_error_from_syserror ();
goto leave;
}
} }

View File

@ -383,19 +383,36 @@ keygen_set_std_prefs (const char *string,int personal)
strcat(dummy_string,"S7 "); strcat(dummy_string,"S7 ");
strcat(dummy_string,"S2 "); /* 3DES */ strcat(dummy_string,"S2 "); /* 3DES */
/* The default hash algo order is: if (personal)
SHA-256, SHA-384, SHA-512, SHA-224, SHA-1. {
*/ /* The default internal hash algo order is:
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA256)) * SHA-256, SHA-384, SHA-512, SHA-224, SHA-1.
strcat (dummy_string, "H8 "); */
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA256))
strcat (dummy_string, "H8 ");
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA384)) if (!openpgp_md_test_algo (DIGEST_ALGO_SHA384))
strcat (dummy_string, "H9 "); strcat (dummy_string, "H9 ");
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA512)) if (!openpgp_md_test_algo (DIGEST_ALGO_SHA512))
strcat (dummy_string, "H10 "); strcat (dummy_string, "H10 ");
}
else
{
/* The default advertised hash algo order is:
* SHA-512, SHA-384, SHA-256, SHA-224, SHA-1.
*/
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA512))
strcat (dummy_string, "H10 ");
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA224)) if (!openpgp_md_test_algo (DIGEST_ALGO_SHA384))
strcat (dummy_string, "H9 ");
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA256))
strcat (dummy_string, "H8 ");
}
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA224))
strcat (dummy_string, "H11 "); strcat (dummy_string, "H11 ");
strcat (dummy_string, "H2 "); /* SHA-1 */ strcat (dummy_string, "H2 "); /* SHA-1 */
@ -4466,6 +4483,11 @@ card_write_key_to_backup_file (PKT_public_key *sk, const char *backup_dir)
log_info (_("Note: backup of card key saved to '%s'\n"), fname); log_info (_("Note: backup of card key saved to '%s'\n"), fname);
fprbuf = hexfingerprint (sk, NULL, 0); fprbuf = hexfingerprint (sk, NULL, 0);
if (!fprbuf)
{
err = gpg_error_from_syserror ();
goto leave;
}
write_status_text_and_buffer (STATUS_BACKUP_KEY_CREATED, fprbuf, write_status_text_and_buffer (STATUS_BACKUP_KEY_CREATED, fprbuf,
fname, strlen (fname), 0); fname, strlen (fname), 0);
xfree (fprbuf); xfree (fprbuf);

View File

@ -790,12 +790,12 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
/* Return an allocated buffer with the fingerprint of PK formatted as /* Return an allocated buffer with the fingerprint of PK formatted as
a plain hexstring. If BUFFER is NULL the result is a malloc'd * a plain hexstring. If BUFFER is NULL the result is a malloc'd
string. If BUFFER is not NULL the result will be copied into this * string. If BUFFER is not NULL the result will be copied into this
buffer. In the latter case BUFLEN describes the length of the * buffer. In the latter case BUFLEN describes the length of the
buffer; if this is too short the function terminates the process. * buffer; if this is too short the function terminates the process.
Returns a malloc'ed string or BUFFER. A suitable length for BUFFER * Returns a malloc'ed string or BUFFER. A suitable length for BUFFER
is (2*MAX_FINGERPRINT_LEN + 1). */ * is (2*MAX_FINGERPRINT_LEN + 1). */
char * char *
hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen) hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen)
{ {
@ -804,7 +804,11 @@ hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen)
fingerprint_from_pk (pk, fpr, &len); fingerprint_from_pk (pk, fpr, &len);
if (!buffer) if (!buffer)
buffer = xmalloc (2 * len + 1); {
buffer = xtrymalloc (2 * len + 1);
if (!buffer)
return NULL;
}
else if (buflen < 2*len+1) else if (buflen < 2*len+1)
log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen); log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
bin2hex (fpr, len, buffer); bin2hex (fpr, len, buffer);

View File

@ -730,40 +730,35 @@ key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk)
} }
/**************** /*
* Return a malloced string with a default recipient if there is any * Return a malloced string with a default recipient if there is any
* Fixme: We don't distinguish between malloc failure and no-default-recipient.
*/ */
static char * static char *
default_recipient(ctrl_t ctrl) default_recipient (ctrl_t ctrl)
{ {
PKT_public_key *pk; PKT_public_key *pk;
byte fpr[MAX_FINGERPRINT_LEN+1]; char *result;
size_t n;
char *p;
int i;
if( opt.def_recipient ) if (opt.def_recipient)
return xstrdup( opt.def_recipient ); return xtrystrdup (opt.def_recipient);
if( !opt.def_recipient_self )
return NULL; if (!opt.def_recipient_self)
pk = xmalloc_clear( sizeof *pk ); return NULL;
i = get_seckey_default (ctrl, pk); pk = xtrycalloc (1, sizeof *pk );
if( i ) { if (!pk)
free_public_key( pk ); return NULL;
return NULL; if (get_seckey_default (ctrl, pk))
{
free_public_key (pk);
return NULL;
} }
n = MAX_FINGERPRINT_LEN; result = hexfingerprint (pk, NULL, 0);
fingerprint_from_pk( pk, fpr, &n ); free_public_key (pk);
free_public_key( pk ); return result;
p = xmalloc( 2*n+3 );
*p++ = '0';
*p++ = 'x';
for(i=0; i < n; i++ )
sprintf( p+2*i, "%02X", fpr[i] );
p -= 2;
return p;
} }
static int static int
expand_id(const char *id,strlist_t *into,unsigned int flags) expand_id(const char *id,strlist_t *into,unsigned int flags)
{ {

View File

@ -536,7 +536,20 @@ gen_standard_revoke (ctrl_t ctrl, PKT_public_key *psk, const char *cache_nonce)
dir = get_openpgp_revocdir (gnupg_homedir ()); dir = get_openpgp_revocdir (gnupg_homedir ());
tmpstr = hexfingerprint (psk, NULL, 0); tmpstr = hexfingerprint (psk, NULL, 0);
fname = xstrconcat (dir, DIRSEP_S, tmpstr, NULL); if (!tmpstr)
{
rc = gpg_error_from_syserror ();
xfree (dir);
return rc;
}
fname = strconcat (dir, DIRSEP_S, tmpstr, NULL);
if (!fname)
{
rc = gpg_error_from_syserror ();
xfree (tmpstr);
xfree (dir);
return rc;
}
xfree (tmpstr); xfree (tmpstr);
xfree (dir); xfree (dir);

View File

@ -3336,8 +3336,8 @@ tofu_register_signature (ctrl_t ctrl,
char *fingerprint = NULL; char *fingerprint = NULL;
strlist_t user_id; strlist_t user_id;
char *email = NULL; char *email = NULL;
char *err = NULL; char *sqlerr = NULL;
char *sig_digest; char *sig_digest = NULL;
unsigned long c; unsigned long c;
dbs = opendbs (ctrl); dbs = opendbs (ctrl);
@ -3358,11 +3358,20 @@ tofu_register_signature (ctrl_t ctrl,
log_assert (pk_is_primary (pk)); log_assert (pk_is_primary (pk));
sig_digest = make_radix64_string (sig_digest_bin, sig_digest_bin_len); sig_digest = make_radix64_string (sig_digest_bin, sig_digest_bin_len);
if (!sig_digest)
{
rc = gpg_error_from_syserror ();
goto leave;
}
fingerprint = hexfingerprint (pk, NULL, 0); fingerprint = hexfingerprint (pk, NULL, 0);
if (!fingerprint)
{
rc = gpg_error_from_syserror ();
goto leave;
}
if (! origin) if (! origin)
/* The default origin is simply "unknown". */ origin = "unknown"; /* The default origin is simply "unknown". */
origin = "unknown";
for (user_id = user_id_list; user_id; user_id = user_id->next) for (user_id = user_id_list; user_id; user_id = user_id->next)
{ {
@ -3388,7 +3397,7 @@ tofu_register_signature (ctrl_t ctrl,
it again. */ it again. */
rc = gpgsql_stepx rc = gpgsql_stepx
(dbs->db, &dbs->s.register_already_seen, (dbs->db, &dbs->s.register_already_seen,
get_single_unsigned_long_cb2, &c, &err, get_single_unsigned_long_cb2, &c, &sqlerr,
"select count (*)\n" "select count (*)\n"
" from signatures left join bindings\n" " from signatures left join bindings\n"
" on signatures.binding = bindings.oid\n" " on signatures.binding = bindings.oid\n"
@ -3400,9 +3409,9 @@ tofu_register_signature (ctrl_t ctrl,
GPGSQL_ARG_END); GPGSQL_ARG_END);
if (rc) if (rc)
{ {
log_error (_("error reading TOFU database: %s\n"), err); log_error (_("error reading TOFU database: %s\n"), sqlerr);
print_further_info ("checking existence"); print_further_info ("checking existence");
sqlite3_free (err); sqlite3_free (sqlerr);
rc = gpg_error (GPG_ERR_GENERAL); rc = gpg_error (GPG_ERR_GENERAL);
} }
else if (c > 1) else if (c > 1)
@ -3440,7 +3449,7 @@ tofu_register_signature (ctrl_t ctrl,
log_assert (c == 0); log_assert (c == 0);
rc = gpgsql_stepx rc = gpgsql_stepx
(dbs->db, &dbs->s.register_signature, NULL, NULL, &err, (dbs->db, &dbs->s.register_signature, NULL, NULL, &sqlerr,
"insert into signatures\n" "insert into signatures\n"
" (binding, sig_digest, origin, sig_time, time)\n" " (binding, sig_digest, origin, sig_time, time)\n"
" values\n" " values\n"
@ -3454,9 +3463,9 @@ tofu_register_signature (ctrl_t ctrl,
GPGSQL_ARG_END); GPGSQL_ARG_END);
if (rc) if (rc)
{ {
log_error (_("error updating TOFU database: %s\n"), err); log_error (_("error updating TOFU database: %s\n"), sqlerr);
print_further_info ("insert signatures"); print_further_info ("insert signatures");
sqlite3_free (err); sqlite3_free (sqlerr);
rc = gpg_error (GPG_ERR_GENERAL); rc = gpg_error (GPG_ERR_GENERAL);
} }
} }
@ -3467,6 +3476,7 @@ tofu_register_signature (ctrl_t ctrl,
break; break;
} }
leave:
if (rc) if (rc)
rollback_transaction (ctrl); rollback_transaction (ctrl);
else else
@ -3490,7 +3500,8 @@ tofu_register_encryption (ctrl_t ctrl,
int free_user_id_list = 0; int free_user_id_list = 0;
char *fingerprint = NULL; char *fingerprint = NULL;
strlist_t user_id; strlist_t user_id;
char *err = NULL; char *sqlerr = NULL;
int in_batch = 0;
dbs = opendbs (ctrl); dbs = opendbs (ctrl);
if (! dbs) if (! dbs)
@ -3535,8 +3546,14 @@ tofu_register_encryption (ctrl_t ctrl,
} }
fingerprint = hexfingerprint (pk, NULL, 0); fingerprint = hexfingerprint (pk, NULL, 0);
if (!fingerprint)
{
rc = gpg_error_from_syserror ();
goto leave;
}
tofu_begin_batch_update (ctrl); tofu_begin_batch_update (ctrl);
in_batch = 1;
tofu_resume_batch_transaction (ctrl); tofu_resume_batch_transaction (ctrl);
for (user_id = user_id_list; user_id; user_id = user_id->next) for (user_id = user_id_list; user_id; user_id = user_id->next)
@ -3554,7 +3571,7 @@ tofu_register_encryption (ctrl_t ctrl,
/* An error. */ /* An error. */
rc = gpg_error (GPG_ERR_GENERAL); rc = gpg_error (GPG_ERR_GENERAL);
xfree (email); xfree (email);
goto die; goto leave;
} }
@ -3580,7 +3597,7 @@ tofu_register_encryption (ctrl_t ctrl,
free_strlist (conflict_set); free_strlist (conflict_set);
rc = gpgsql_stepx rc = gpgsql_stepx
(dbs->db, &dbs->s.register_encryption, NULL, NULL, &err, (dbs->db, &dbs->s.register_encryption, NULL, NULL, &sqlerr,
"insert into encryptions\n" "insert into encryptions\n"
" (binding, time)\n" " (binding, time)\n"
" values\n" " values\n"
@ -3592,24 +3609,22 @@ tofu_register_encryption (ctrl_t ctrl,
GPGSQL_ARG_END); GPGSQL_ARG_END);
if (rc) if (rc)
{ {
log_error (_("error updating TOFU database: %s\n"), err); log_error (_("error updating TOFU database: %s\n"), sqlerr);
print_further_info ("insert encryption"); print_further_info ("insert encryption");
sqlite3_free (err); sqlite3_free (sqlerr);
rc = gpg_error (GPG_ERR_GENERAL); rc = gpg_error (GPG_ERR_GENERAL);
} }
xfree (email); xfree (email);
} }
die: leave:
tofu_end_batch_update (ctrl); if (in_batch)
tofu_end_batch_update (ctrl);
if (kb)
release_kbnode (kb);
release_kbnode (kb);
if (free_user_id_list) if (free_user_id_list)
free_strlist (user_id_list); free_strlist (user_id_list);
xfree (fingerprint); xfree (fingerprint);
return rc; return rc;
@ -3685,10 +3700,10 @@ tofu_write_tfs_record (ctrl_t ctrl, estream_t fp,
PKT_public_key *pk, const char *user_id) PKT_public_key *pk, const char *user_id)
{ {
time_t now = gnupg_get_time (); time_t now = gnupg_get_time ();
gpg_error_t err; gpg_error_t err = 0;
tofu_dbs_t dbs; tofu_dbs_t dbs;
char *fingerprint; char *fingerprint;
char *email; char *email = NULL;
enum tofu_policy policy; enum tofu_policy policy;
if (!*user_id) if (!*user_id)
@ -3703,14 +3718,20 @@ tofu_write_tfs_record (ctrl_t ctrl, estream_t fp,
} }
fingerprint = hexfingerprint (pk, NULL, 0); fingerprint = hexfingerprint (pk, NULL, 0);
if (!fingerprint)
{
err = gpg_error_from_syserror ();
goto leave;
}
email = email_from_user_id (user_id); email = email_from_user_id (user_id);
policy = get_policy (ctrl, dbs, pk, fingerprint, user_id, email, NULL, now); policy = get_policy (ctrl, dbs, pk, fingerprint, user_id, email, NULL, now);
show_statistics (dbs, fingerprint, email, policy, fp, 0, now); show_statistics (dbs, fingerprint, email, policy, fp, 0, now);
leave:
xfree (email); xfree (email);
xfree (fingerprint); xfree (fingerprint);
return 0; return err;
} }
@ -3724,7 +3745,10 @@ tofu_write_tfs_record (ctrl_t ctrl, estream_t fp,
will be prompted to choose a policy. If MAY_ASK is 0 and the will be prompted to choose a policy. If MAY_ASK is 0 and the
policy is TOFU_POLICY_ASK, then TRUST_UNKNOWN is returned. policy is TOFU_POLICY_ASK, then TRUST_UNKNOWN is returned.
Returns TRUST_UNDEFINED if an error occurs. */ Returns TRUST_UNDEFINED if an error occurs.
Fixme: eturn an error code
*/
int int
tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list,
int may_ask) int may_ask)
@ -3748,6 +3772,8 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list,
} }
fingerprint = hexfingerprint (pk, NULL, 0); fingerprint = hexfingerprint (pk, NULL, 0);
if (!fingerprint)
log_fatal ("%s: malloc failed\n", __func__);
tofu_begin_batch_update (ctrl); tofu_begin_batch_update (ctrl);
/* Start the batch transaction now. */ /* Start the batch transaction now. */
@ -3893,6 +3919,8 @@ tofu_set_policy (ctrl_t ctrl, kbnode_t kb, enum tofu_policy policy)
log_bug ("%s: Passed a subkey, but expecting a primary key.\n", __func__); log_bug ("%s: Passed a subkey, but expecting a primary key.\n", __func__);
fingerprint = hexfingerprint (pk, NULL, 0); fingerprint = hexfingerprint (pk, NULL, 0);
if (!fingerprint)
return gpg_error_from_syserror ();
begin_transaction (ctrl, 0); begin_transaction (ctrl, 0);
@ -3962,6 +3990,8 @@ tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id,
} }
fingerprint = hexfingerprint (pk, NULL, 0); fingerprint = hexfingerprint (pk, NULL, 0);
if (!fingerprint)
return gpg_error_from_syserror ();
email = email_from_user_id (user_id->name); email = email_from_user_id (user_id->name);
@ -3998,6 +4028,8 @@ tofu_notice_key_changed (ctrl_t ctrl, kbnode_t kb)
} }
fingerprint = hexfingerprint (pk, NULL, 0); fingerprint = hexfingerprint (pk, NULL, 0);
if (!fingerprint)
return gpg_error_from_syserror ();
rc = gpgsql_stepx (dbs->db, NULL, NULL, NULL, &sqlerr, rc = gpgsql_stepx (dbs->db, NULL, NULL, NULL, &sqlerr,
"update bindings set effective_policy = ?" "update bindings set effective_policy = ?"

View File

@ -99,6 +99,7 @@ enum cmd_and_opt_values
oDenyAdmin, oDenyAdmin,
oDisableApplication, oDisableApplication,
oEnablePinpadVarlen, oEnablePinpadVarlen,
oListenBacklog
}; };
@ -156,6 +157,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oEnablePinpadVarlen, "enable-pinpad-varlen", ARGPARSE_s_n (oEnablePinpadVarlen, "enable-pinpad-varlen",
N_("use variable length input for pinpad")), N_("use variable length input for pinpad")),
ARGPARSE_s_s (oHomedir, "homedir", "@"), ARGPARSE_s_s (oHomedir, "homedir", "@"),
ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
ARGPARSE_end () ARGPARSE_end ()
}; };
@ -224,6 +226,10 @@ static char *redir_socket_name;
POSIX systems). */ POSIX systems). */
static assuan_sock_nonce_t socket_nonce; static assuan_sock_nonce_t socket_nonce;
/* Value for the listen() backlog argument. Change at runtime with
* --listen-backlog. */
static int listen_backlog = 64;
#ifdef HAVE_W32_SYSTEM #ifdef HAVE_W32_SYSTEM
static HANDLE the_event; static HANDLE the_event;
#else #else
@ -594,6 +600,10 @@ main (int argc, char **argv )
case oEnablePinpadVarlen: opt.enable_pinpad_varlen = 1; break; case oEnablePinpadVarlen: opt.enable_pinpad_varlen = 1; break;
case oListenBacklog:
listen_backlog = pargs.r.ret_int;
break;
default: default:
pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR; pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
break; break;
@ -1128,10 +1138,10 @@ create_server_socket (const char *name, char **r_redir_name,
log_error (_("can't set permissions of '%s': %s\n"), log_error (_("can't set permissions of '%s': %s\n"),
unaddr->sun_path, strerror (errno)); unaddr->sun_path, strerror (errno));
if (listen (FD2INT(fd), 5 ) == -1) if (listen (FD2INT(fd), listen_backlog) == -1)
{ {
log_error (_("listen() failed: %s\n"), log_error ("listen(fd, %d) failed: %s\n",
gpg_strerror (gpg_error_from_syserror ())); listen_backlog, gpg_strerror (gpg_error_from_syserror ()));
assuan_sock_close (fd); assuan_sock_close (fd);
scd_exit (2); scd_exit (2);
} }

View File

@ -1456,6 +1456,7 @@ main ( int argc, char **argv)
{ {
struct gnupg_compliance_option compliance_options[] = struct gnupg_compliance_option compliance_options[] =
{ {
{ "gnupg", CO_GNUPG },
{ "de-vs", CO_DE_VS } { "de-vs", CO_DE_VS }
}; };
int compliance = gnupg_parse_compliance_option (pargs.r.ret_str, int compliance = gnupg_parse_compliance_option (pargs.r.ret_str,

View File

@ -714,7 +714,7 @@ static gc_option_t gc_options_gpg[] =
{ "options", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, { "options", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
NULL, NULL, NULL, NULL,
GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG }, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
{ "compliance", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, { "compliance", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
NULL, NULL, NULL, NULL,
GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
{ "default-new-key-algo", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, { "default-new-key-algo", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
@ -833,6 +833,9 @@ static gc_option_t gc_options_gpgsm[] =
(GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE, (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
NULL, NULL, NULL, NULL,
GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM }, GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
{ "compliance", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
NULL, NULL,
GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
{ "Debug", { "Debug",
GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,