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,
oS2KCount,
oAutoExpandSecmem,
oListenBacklog,
oWriteEnvFile
};
@ -255,6 +256,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_op_u (oAutoExpandSecmem, "auto-expand-secmem", "@"),
ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
/* Dummy options for backward compatibility. */
ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"),
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_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. */
static char *default_display;
@ -1245,6 +1252,10 @@ main (int argc, char **argv )
(unsigned int)pargs.r.ret_ulong, 0);
break;
case oListenBacklog:
listen_backlog = pargs.r.ret_int;
break;
case oDebugQuickRandom:
/* Only used by the first stage command line parser. */
break;
@ -2248,9 +2259,10 @@ create_server_socket (char *name, int primary, int cygwin,
log_error (_("can't set permissions of '%s': %s\n"),
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(). */
assuan_sock_close (fd);
xfree (unaddr);

View File

@ -541,7 +541,17 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
#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;
struct stat sb;
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
* 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++)
{
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"])
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
#

View File

@ -151,6 +151,7 @@ enum cmd_and_opt_values {
oResolverTimeout,
oConnectTimeout,
oConnectQuickTimeout,
oListenBacklog,
aTest
};
@ -256,6 +257,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_i (oResolverTimeout, "resolver-timeout", "@"),
ARGPARSE_s_i (oConnectTimeout, "connect-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 "
"of all commands and options)\n")),
@ -296,6 +298,10 @@ static const char *redir_socket_name;
POSIX systems). */
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. */
static int cleanup_socket;
@ -1019,6 +1025,10 @@ main (int argc, char **argv)
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;
}
}
@ -1271,9 +1281,10 @@ main (int argc, char **argv)
log_error (_("can't set permissions of '%s': %s\n"),
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);
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
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
@opindex allow-version-check
Allow Dirmngr to connect to @code{https://versions.gnupg.org} to get

View File

@ -31,8 +31,7 @@
#
# Example file:
#==========
# :staff gpg-agent allow-mark-trusted [change]
# gpg-agent min-passphrase-len 6
# :staff gpg-agent min-passphrase-len 6 [change]
#
# * gpg-agent min-passphrase-len [no-change] 8
# gpg-agent min-passphrase-nonalpha [no-change] 1
@ -42,9 +41,9 @@
# gpg-agent enforce-passphrase-constraints [no-change]
# gpg-agent max-cache-ttl [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
# gpg compliance [no-change]
# gpgsm compliance [no-change]
#===========
# 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

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
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}
@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
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}
@opindex log-file
Append all logging output to @var{file}. This is very helpful in

View File

@ -1,6 +1,6 @@
/* cipher.c - En-/De-ciphering filter
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
* 2006, 2009 Free Software Foundation, Inc.
* Copyright (C) 1998-2003, 2006, 2009 Free Software Foundation, Inc.
* Copyright (C) 1998-2003, 2006, 2009, 2017 Werner koch
*
* This file is part of GnuPG.
*
@ -16,6 +16,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: GPL-3.0+
*/
#include <config.h>
@ -39,124 +40,145 @@
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;
PACKET pkt;
PKT_encrypted ed;
byte temp[18];
unsigned int blocksize;
unsigned int nprefix;
gcry_error_t err;
PACKET pkt;
PKT_encrypted ed;
byte temp[18];
unsigned int blocksize;
unsigned int nprefix;
blocksize = openpgp_cipher_get_algo_blklen (cfx->dek->algo);
if ( blocksize < 8 || blocksize > 16 )
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");
}
blocksize = openpgp_cipher_get_algo_blklen (cfx->dek->algo);
if ( blocksize < 8 || blocksize > 16 )
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)
{
char buf[20];
snprintf (buf, sizeof buf, "%d %d", ed.mdc_method, cfx->dek->algo);
write_status_text (STATUS_BEGIN_ENCRYPTION, buf);
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");
}
else if (!opt.no_mdc_warn)
{
log_info ("WARNING: "
"encrypting without integrity protection is dangerous\n");
}
init_packet( &pkt );
pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED;
pkt.pkt.encrypted = &ed;
if( build_packet( a, &pkt ))
log_bug("build_packet(ENCR_DATA) failed\n");
nprefix = blocksize;
gcry_randomize (temp, nprefix, GCRY_STRONG_RANDOM );
temp[nprefix] = temp[nprefix-2];
temp[nprefix+1] = temp[nprefix-1];
print_cipher_algo_note( cfx->dek->algo );
err = openpgp_cipher_open (&cfx->cipher_hd,
cfx->dek->algo,
GCRY_CIPHER_MODE_CFB,
(GCRY_CIPHER_SECURE
| ((cfx->dek->use_mdc || cfx->dek->algo >= 100)?
0 : GCRY_CIPHER_ENABLE_SYNC)));
if (err) {
/* We should never get an error here cause we already checked,
* that the algorithm is available. */
BUG();
write_status_printf (STATUS_BEGIN_ENCRYPTION, "%d %d",
ed.mdc_method, cfx->dek->algo);
init_packet (&pkt);
pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED;
pkt.pkt.encrypted = &ed;
if (build_packet( a, &pkt))
log_bug ("build_packet(ENCR_DATA) failed\n");
nprefix = blocksize;
gcry_randomize (temp, nprefix, GCRY_STRONG_RANDOM );
temp[nprefix] = temp[nprefix-2];
temp[nprefix+1] = temp[nprefix-1];
print_cipher_algo_note (cfx->dek->algo);
err = openpgp_cipher_open (&cfx->cipher_hd,
cfx->dek->algo,
GCRY_CIPHER_MODE_CFB,
(GCRY_CIPHER_SECURE
| ((cfx->dek->use_mdc || cfx->dek->algo >= 100)?
0 : GCRY_CIPHER_ENABLE_SYNC)));
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 );*/
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);
cfx->header=1;
cfx->short_blklen_warn = (blocksize < 16);
cfx->short_blklen_count = nprefix+2;
cfx->wrote_header = 1;
}
/****************
* This filter is used to en/de-cipher data with a conventional algorithm
/*
* This filter is used to en/de-cipher data with a symmetric algorithm
*/
int
cipher_filter( void *opaque, int control,
IOBUF a, byte *buf, size_t *ret_len)
cipher_filter (void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len)
{
size_t size = *ret_len;
cipher_filter_context_t *cfx = opaque;
int rc=0;
cipher_filter_context_t *cfx = opaque;
size_t size = *ret_len;
int rc = 0;
if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */
rc = -1; /* not yet used */
if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */
{
rc = -1; /* not yet used */
}
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
log_assert(a);
if( !cfx->header ) {
write_header( cfx, a );
else if (control == IOBUFCTRL_FLUSH) /* encrypt */
{
log_assert (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 );
/* 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_cipher_close (cfx->cipher_hd);
}
else if (control == IOBUFCTRL_DESC)
{
mem2str (buf, "cipher_filter", *ret_len);
}
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" );
}
gcry_cipher_close (cfx->cipher_hd);
}
else if( control == IOBUFCTRL_DESC ) {
mem2str (buf, "cipher_filter", *ret_len);
}
return rc;
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;
hexfpr = hexfingerprint (pk, NULL, 0);
if (!hexfpr)
{
err = gpg_error_from_syserror ();
goto leave;
}
hexdata = bin2hex (data, datalen, NULL);
if (!hexdata)
{

View File

@ -92,10 +92,11 @@ typedef struct {
DEK *dek;
u32 datalen;
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;
byte enchash[20];
int create_mdc; /* flag will be set by the cipher filter */
} 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.
This function also checks for and warns about duplicate entries in
the keydb, which can occur if the user has configured multiple
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
group).
USE is the operation for which the key is required. It must be
either PUBKEY_USAGE_ENC, PUBKEY_USAGE_SIG, PUBKEY_USAGE_CERT or
PUBKEY_USAGE_AUTH.
XXX: Currently, only PUBKEY_USAGE_ENC and PUBKEY_USAGE_SIG are
implemented.
INCLUDE_UNUSABLE indicates whether disabled keys are allowed.
(Recipients specified with --encrypt-to and --hidden-encrypt-to may
be disabled. It is possible to edit disabled keys.)
SOURCE is the context in which SEARCH_TERMS was specified, e.g.,
"--encrypt-to", etc. If this function is called interactively,
then this should be NULL.
If WARN_POSSIBLY_AMBIGUOUS is set, then emits a warning if the user
does not specify a long key id or a fingerprint.
The results are placed in *KEYS. *KEYS must be NULL! */
*
* This function also checks for and warns about duplicate entries in
* the keydb, which can occur if the user has configured multiple
* 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
* group).
*
* USE is the operation for which the key is required. It must be
* either PUBKEY_USAGE_ENC, PUBKEY_USAGE_SIG, PUBKEY_USAGE_CERT or
* PUBKEY_USAGE_AUTH.
*
* INCLUDE_UNUSABLE indicates whether disabled keys are allowed.
* (Recipients specified with --encrypt-to and --hidden-encrypt-to may
* be disabled. It is possible to edit disabled keys.)
*
* SOURCE is the context in which SEARCH_TERMS was specified, e.g.,
* "--encrypt-to", etc. If this function is called interactively,
* then this should be NULL.
*
* If WARN_POSSIBLY_AMBIGUOUS is set, then emits a warning if the user
* does not specify a long key id or a fingerprint.
*
* The results are placed in *KEYS. *KEYS must be NULL!
*
* Fixme: Currently, only PUBKEY_USAGE_ENC and PUBKEY_USAGE_SIG are
* implemented. */
gpg_error_t
get_pubkeys (ctrl_t ctrl,
char *search_terms, int use, int include_unusable, char *source,
@ -448,30 +449,23 @@ get_pubkeys (ctrl_t ctrl,
pubkey_t *r_keys)
{
/* We show a warning when a key appears multiple times in the DB.
This can happen for two reasons:
- The user has configured multiple keyrings or keyboxes.
- The keyring or keybox has been corrupted in some way, e.g., a
bug or a random process changing them.
For each duplicate, we only want to show the key once. Hence,
this list. */
* This can happen for two reasons:
*
* - The user has configured multiple keyrings or keyboxes.
*
* - The keyring or keybox has been corrupted in some way, e.g., a
* bug or a random process changing them.
*
* For each duplicate, we only want to show the key once. Hence,
* this list. */
static strlist_t key_dups;
/* USE transformed to a string. */
char *use_str;
gpg_error_t err;
char *use_str; /* USE transformed to a string. */
KEYDB_SEARCH_DESC desc;
GETKEY_CTX ctx;
pubkey_t results = NULL;
pubkey_t r;
int count;
char fingerprint[2 * MAX_FINGERPRINT_LEN + 1];
if (DBG_LOOKUP)
@ -503,7 +497,7 @@ get_pubkeys (ctrl_t ctrl,
search_terms, gpg_strerror (err));
if (!opt.quiet && source)
log_info (_("(check argument of option '%s')\n"), source);
goto out;
goto leave;
}
if (warn_possibly_ambiguous
@ -523,8 +517,16 @@ get_pubkeys (ctrl_t ctrl,
count = 0;
do
{
PKT_public_key *pk = xmalloc_clear (sizeof *pk);
PKT_public_key *pk;
KBNODE kb;
pk = xtrycalloc (1, sizeof *pk);
if (!pk)
{
err = gpg_error_from_syserror ();
goto leave;
}
pk->req_usage = use;
if (! ctx)
@ -533,17 +535,14 @@ get_pubkeys (ctrl_t ctrl,
else
err = getkey_next (ctrl, ctx, pk, &kb);
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
/* No more results. */
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) /* No more results. */
{
xfree (pk);
break;
}
else if (err)
/* An error (other than "not found"). */
else if (err) /* An error (other than "not found"). */
{
log_error (_("error looking up: %s\n"),
gpg_strerror (err));
log_error (_("error looking up: %s\n"), gpg_strerror (err));
xfree (pk);
break;
}
@ -551,7 +550,13 @@ get_pubkeys (ctrl_t ctrl,
/* Another result! */
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->keyblock = kb;
r->next = results;
@ -570,8 +575,7 @@ get_pubkeys (ctrl_t ctrl,
}
if (! results && gpg_err_code (err) == GPG_ERR_NOT_FOUND)
/* No match. */
{
{ /* No match. */
if (DBG_LOOKUP)
log_debug ("%s: '%s' not found.\n", __func__, search_terms);
@ -579,15 +583,15 @@ get_pubkeys (ctrl_t ctrl,
if (!opt.quiet && source)
log_info (_("(check argument of option '%s')\n"), source);
goto out;
goto leave;
}
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
/* No more matches. */
;
; /* No more matches. */
else if (err)
/* Some other error. An error message was already printed
out. Free RESULTS and continue. */
goto out;
{ /* Some other error. An error message was already printed out.
* Free RESULTS and continue. */
goto leave;
}
/* Check for duplicates. */
if (DBG_LOOKUP)
@ -607,8 +611,7 @@ get_pubkeys (ctrl_t ctrl,
{
if (cmp_public_keys (r->keyblock->pkt->pkt.public_key,
r2->keyblock->pkt->pkt.public_key) != 0)
/* Not a dup. */
{
{ /* Not a dup. */
prevp = &r2->next;
next = r2->next;
continue;
@ -652,7 +655,7 @@ get_pubkeys (ctrl_t ctrl,
fingerprint, sizeof fingerprint));
}
out:
leave:
if (err)
pubkeys_free (results);
else
@ -723,8 +726,13 @@ get_pubkey (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
/* More init stuff. */
if (!pk)
{
pk = xmalloc_clear (sizeof *pk);
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,"S2 "); /* 3DES */
/* The default hash algo order is:
SHA-256, SHA-384, SHA-512, SHA-224, SHA-1.
*/
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA256))
strcat (dummy_string, "H8 ");
if (personal)
{
/* The default internal hash algo order is:
* SHA-256, SHA-384, SHA-512, SHA-224, SHA-1.
*/
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA256))
strcat (dummy_string, "H8 ");
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA384))
strcat (dummy_string, "H9 ");
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA384))
strcat (dummy_string, "H9 ");
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA512))
strcat (dummy_string, "H10 ");
if (!openpgp_md_test_algo (DIGEST_ALGO_SHA512))
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, "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);
fprbuf = hexfingerprint (sk, NULL, 0);
if (!fprbuf)
{
err = gpg_error_from_syserror ();
goto leave;
}
write_status_text_and_buffer (STATUS_BACKUP_KEY_CREATED, fprbuf,
fname, strlen (fname), 0);
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
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
buffer. In the latter case BUFLEN describes the length of the
buffer; if this is too short the function terminates the process.
Returns a malloc'ed string or BUFFER. A suitable length for BUFFER
is (2*MAX_FINGERPRINT_LEN + 1). */
* 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
* buffer. In the latter case BUFLEN describes the length of the
* buffer; if this is too short the function terminates the process.
* Returns a malloc'ed string or BUFFER. A suitable length for BUFFER
* is (2*MAX_FINGERPRINT_LEN + 1). */
char *
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);
if (!buffer)
buffer = xmalloc (2 * len + 1);
{
buffer = xtrymalloc (2 * len + 1);
if (!buffer)
return NULL;
}
else if (buflen < 2*len+1)
log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
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
* Fixme: We don't distinguish between malloc failure and no-default-recipient.
*/
static char *
default_recipient(ctrl_t ctrl)
default_recipient (ctrl_t ctrl)
{
PKT_public_key *pk;
byte fpr[MAX_FINGERPRINT_LEN+1];
size_t n;
char *p;
int i;
PKT_public_key *pk;
char *result;
if( opt.def_recipient )
return xstrdup( opt.def_recipient );
if( !opt.def_recipient_self )
return NULL;
pk = xmalloc_clear( sizeof *pk );
i = get_seckey_default (ctrl, pk);
if( i ) {
free_public_key( pk );
return NULL;
if (opt.def_recipient)
return xtrystrdup (opt.def_recipient);
if (!opt.def_recipient_self)
return NULL;
pk = xtrycalloc (1, sizeof *pk );
if (!pk)
return NULL;
if (get_seckey_default (ctrl, pk))
{
free_public_key (pk);
return NULL;
}
n = MAX_FINGERPRINT_LEN;
fingerprint_from_pk( pk, fpr, &n );
free_public_key( pk );
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;
result = hexfingerprint (pk, NULL, 0);
free_public_key (pk);
return result;
}
static int
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 ());
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 (dir);

View File

@ -3336,8 +3336,8 @@ tofu_register_signature (ctrl_t ctrl,
char *fingerprint = NULL;
strlist_t user_id;
char *email = NULL;
char *err = NULL;
char *sig_digest;
char *sqlerr = NULL;
char *sig_digest = NULL;
unsigned long c;
dbs = opendbs (ctrl);
@ -3358,11 +3358,20 @@ tofu_register_signature (ctrl_t ctrl,
log_assert (pk_is_primary (pk));
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);
if (!fingerprint)
{
rc = gpg_error_from_syserror ();
goto leave;
}
if (! origin)
/* The default origin is simply "unknown". */
origin = "unknown";
origin = "unknown"; /* The default origin is simply "unknown". */
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. */
rc = gpgsql_stepx
(dbs->db, &dbs->s.register_already_seen,
get_single_unsigned_long_cb2, &c, &err,
get_single_unsigned_long_cb2, &c, &sqlerr,
"select count (*)\n"
" from signatures left join bindings\n"
" on signatures.binding = bindings.oid\n"
@ -3400,9 +3409,9 @@ tofu_register_signature (ctrl_t ctrl,
GPGSQL_ARG_END);
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");
sqlite3_free (err);
sqlite3_free (sqlerr);
rc = gpg_error (GPG_ERR_GENERAL);
}
else if (c > 1)
@ -3440,7 +3449,7 @@ tofu_register_signature (ctrl_t ctrl,
log_assert (c == 0);
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"
" (binding, sig_digest, origin, sig_time, time)\n"
" values\n"
@ -3454,9 +3463,9 @@ tofu_register_signature (ctrl_t ctrl,
GPGSQL_ARG_END);
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");
sqlite3_free (err);
sqlite3_free (sqlerr);
rc = gpg_error (GPG_ERR_GENERAL);
}
}
@ -3467,6 +3476,7 @@ tofu_register_signature (ctrl_t ctrl,
break;
}
leave:
if (rc)
rollback_transaction (ctrl);
else
@ -3490,7 +3500,8 @@ tofu_register_encryption (ctrl_t ctrl,
int free_user_id_list = 0;
char *fingerprint = NULL;
strlist_t user_id;
char *err = NULL;
char *sqlerr = NULL;
int in_batch = 0;
dbs = opendbs (ctrl);
if (! dbs)
@ -3535,8 +3546,14 @@ tofu_register_encryption (ctrl_t ctrl,
}
fingerprint = hexfingerprint (pk, NULL, 0);
if (!fingerprint)
{
rc = gpg_error_from_syserror ();
goto leave;
}
tofu_begin_batch_update (ctrl);
in_batch = 1;
tofu_resume_batch_transaction (ctrl);
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. */
rc = gpg_error (GPG_ERR_GENERAL);
xfree (email);
goto die;
goto leave;
}
@ -3580,7 +3597,7 @@ tofu_register_encryption (ctrl_t ctrl,
free_strlist (conflict_set);
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"
" (binding, time)\n"
" values\n"
@ -3592,24 +3609,22 @@ tofu_register_encryption (ctrl_t ctrl,
GPGSQL_ARG_END);
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");
sqlite3_free (err);
sqlite3_free (sqlerr);
rc = gpg_error (GPG_ERR_GENERAL);
}
xfree (email);
}
die:
tofu_end_batch_update (ctrl);
if (kb)
release_kbnode (kb);
leave:
if (in_batch)
tofu_end_batch_update (ctrl);
release_kbnode (kb);
if (free_user_id_list)
free_strlist (user_id_list);
xfree (fingerprint);
return rc;
@ -3685,10 +3700,10 @@ tofu_write_tfs_record (ctrl_t ctrl, estream_t fp,
PKT_public_key *pk, const char *user_id)
{
time_t now = gnupg_get_time ();
gpg_error_t err;
gpg_error_t err = 0;
tofu_dbs_t dbs;
char *fingerprint;
char *email;
char *email = NULL;
enum tofu_policy policy;
if (!*user_id)
@ -3703,14 +3718,20 @@ tofu_write_tfs_record (ctrl_t ctrl, estream_t fp,
}
fingerprint = hexfingerprint (pk, NULL, 0);
if (!fingerprint)
{
err = gpg_error_from_syserror ();
goto leave;
}
email = email_from_user_id (user_id);
policy = get_policy (ctrl, dbs, pk, fingerprint, user_id, email, NULL, now);
show_statistics (dbs, fingerprint, email, policy, fp, 0, now);
leave:
xfree (email);
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
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
tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list,
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);
if (!fingerprint)
log_fatal ("%s: malloc failed\n", __func__);
tofu_begin_batch_update (ctrl);
/* 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__);
fingerprint = hexfingerprint (pk, NULL, 0);
if (!fingerprint)
return gpg_error_from_syserror ();
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);
if (!fingerprint)
return gpg_error_from_syserror ();
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);
if (!fingerprint)
return gpg_error_from_syserror ();
rc = gpgsql_stepx (dbs->db, NULL, NULL, NULL, &sqlerr,
"update bindings set effective_policy = ?"

View File

@ -99,6 +99,7 @@ enum cmd_and_opt_values
oDenyAdmin,
oDisableApplication,
oEnablePinpadVarlen,
oListenBacklog
};
@ -156,6 +157,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oEnablePinpadVarlen, "enable-pinpad-varlen",
N_("use variable length input for pinpad")),
ARGPARSE_s_s (oHomedir, "homedir", "@"),
ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
ARGPARSE_end ()
};
@ -224,6 +226,10 @@ static char *redir_socket_name;
POSIX systems). */
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
static HANDLE the_event;
#else
@ -594,6 +600,10 @@ main (int argc, char **argv )
case oEnablePinpadVarlen: opt.enable_pinpad_varlen = 1; break;
case oListenBacklog:
listen_backlog = pargs.r.ret_int;
break;
default:
pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
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"),
unaddr->sun_path, strerror (errno));
if (listen (FD2INT(fd), 5 ) == -1)
if (listen (FD2INT(fd), listen_backlog) == -1)
{
log_error (_("listen() failed: %s\n"),
gpg_strerror (gpg_error_from_syserror ()));
log_error ("listen(fd, %d) failed: %s\n",
listen_backlog, gpg_strerror (gpg_error_from_syserror ()));
assuan_sock_close (fd);
scd_exit (2);
}

View File

@ -1456,6 +1456,7 @@ main ( int argc, char **argv)
{
struct gnupg_compliance_option compliance_options[] =
{
{ "gnupg", CO_GNUPG },
{ "de-vs", CO_DE_VS }
};
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,
NULL, NULL,
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,
GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
{ "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,
NULL, NULL,
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",
GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,