Imported Upstream version 2.2.4 upstream/2.2.4
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 9 Feb 2021 07:00:31 +0000 (16:00 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 9 Feb 2021 07:00:31 +0000 (16:00 +0900)
74 files changed:
NEWS
agent/gpg-agent.c
agent/keyformat.txt
agent/protect.c
agent/t-protect.c
build-aux/speedo.mk
common/homedir.c
configure.ac
dirmngr/Makefile.am
dirmngr/dirmngr.c
dirmngr/dirmngr.h
dirmngr/domaininfo.c [new file with mode: 0644]
dirmngr/ks-action.c
dirmngr/misc.c
dirmngr/server.c
dirmngr/workqueue.c [new file with mode: 0644]
doc/HACKING
doc/dirmngr.texi
doc/examples/gpgconf.conf
doc/gpg-agent.texi
doc/gpg.texi
doc/scdaemon.texi
doc/tools.texi
doc/wks.texi
g10/cipher.c
g10/cpr.c
g10/distsigkey.gpg
g10/export.c
g10/filter.h
g10/getkey.c
g10/keygen.c
g10/keyid.c
g10/parse-packet.c
g10/pkclist.c
g10/revoke.c
g10/tofu.c
g10/trustdb.c
po/ca.po
po/cs.po
po/da.po
po/de.po
po/el.po
po/eo.po
po/es.po
po/et.po
po/fi.po
po/fr.po
po/gl.po
po/hu.po
po/id.po
po/it.po
po/ja.po
po/nb.po
po/nl.po
po/pl.po
po/pt.po
po/ro.po
po/ru.po
po/sk.po
po/sv.po
po/tr.po
po/uk.po
po/zh_CN.po
po/zh_TW.po
scd/apdu.c
scd/app.c
scd/ccid-driver.c
scd/scdaemon.c
sm/gpgsm.c
tools/applygnupgdefaults
tools/gpg-wks-server.c
tools/gpgconf-comp.c
tools/gpgconf.c
tools/gpgconf.h

diff --git a/NEWS b/NEWS
index 38a8da1..59b2a45 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,34 @@
+Noteworthy changes in version 2.2.4 (2017-12-20)
+------------------------------------------------
+
+  * gpg: Change default preferences to prefer SHA512.
+
+  * gpg: Print a warning when more than 150 MiB are encrypted using a
+    cipher with 64 bit block size.
+
+  * gpg: Print a warning if the MDC feature has not been used for a
+    message.
+
+  * gpg: Fix regular expression of domain addresses in trust
+    signatures. [#2923]
+
+  * agent: New option --auto-expand-secmem to help with high numbers
+    of concurrent connections.  Requires libgcrypt 1.8.2 for having
+    an effect.  [#3530]
+
+  * dirmngr: Cache responses of WKD queries.
+
+  * gpgconf: Add option --status-fd.
+
+  * wks: Add commands --check and --remove-key to gpg-wks-server.
+
+  * Increase the backlog parameter of the daemons to 64 and add
+    option --listen-backlog.
+
+  * New configure option --enable-run-gnupg-user-socket to first try a
+    socket directory which is not removed by systemd at session end.
+
+
 Noteworthy changes in version 2.2.3 (2017-11-20)
 ------------------------------------------------
 
@@ -16,6 +47,8 @@ Noteworthy changes in version 2.2.3 (2017-11-20)
   * agent: Improve robustness of the shutdown pending
     state. [Git#7ffedfab89]
 
+  See-also: gnupg-announce/2017q4/000417.html
+
 
 Noteworthy changes in version 2.2.2 (2017-11-07)
 ------------------------------------------------
index 0b2b982..a1964ec 100644 (file)
@@ -135,6 +135,8 @@ enum cmd_and_opt_values
   oDisableScdaemon,
   oDisableCheckOwnSocket,
   oS2KCount,
+  oAutoExpandSecmem,
+  oListenBacklog,
 
   oWriteEnvFile
 };
@@ -252,6 +254,10 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_u (oS2KCount, "s2k-count", "@"),
 
+  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", "@"),
@@ -368,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;
@@ -1025,6 +1035,7 @@ main (int argc, char **argv )
   assuan_set_malloc_hooks (&malloc_hooks);
   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
   assuan_sock_init ();
+  assuan_sock_set_system_hooks (ASSUAN_SYSTEM_NPTH);
   setup_libassuan_logging (&opt.debug, NULL);
 
   setup_libgcrypt_logging ();
@@ -1233,6 +1244,18 @@ main (int argc, char **argv )
           socket_name_browser = pargs.r.ret_str;
           break;
 
+        case oAutoExpandSecmem:
+          /* Try to enable this option.  It will officially only be
+           * supported by Libgcrypt 1.9 but 1.8.2 already supports it
+           * on the quiet and thus we use the numeric value value.  */
+          gcry_control (78 /*GCRYCTL_AUTO_EXPAND_SECMEM*/,
+                        (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;
@@ -2236,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);
index 68fbdbc..2e48b34 100644 (file)
@@ -271,7 +271,7 @@ to keys stored on a token:
    (comment whatever)
 )
 
-The currently used protocol is "ti-v1" (token info version 1).  The
+The currently used protocol is "t1-v1" (token info version 1).  The
 second list with the information has this layout:
 
 (card_serial_number id_string_of_key fixed_pin_length)
@@ -379,7 +379,7 @@ Example:
 (protected-shared-secret
    ((desc "List of system passphrases")
     (key "uid-1002" ("Knuth" "Donald Ervin Knuth"))
-    (key "uid-1001" ("Dijkstra" "Edsgar Wybe Dijkstra"))
+    (key "uid-1001" ("Dijkstra" "Edsger Wybe Dijkstra"))
     (key)
     (protected mode (parms) encrypted_octet_string)
     (protected-at "20100915T111722")
@@ -402,7 +402,7 @@ hashed:
 
    ((desc "List of system passphrases")
     (key "uid-1002" ("Knuth" "Donald Ervin Knuth"))
-    (key "uid-1001" ("Dijkstra" "Edsgar Wybe Dijkstra"))
+    (key "uid-1001" ("Dijkstra" "Edsger Wybe Dijkstra"))
     (key)
     (value 4:1002 "signal flags at the lock")
     (value 4:1001 "taocp")
index 9bb2da6..7b5abf2 100644 (file)
@@ -1494,7 +1494,7 @@ make_shadow_info (const char *serialno, const char *idstring)
 
 
 /* Create a shadow key from a public key.  We use the shadow protocol
-  "ti-v1" and insert the S-expressionn SHADOW_INFO.  The resulting
+  "t1-v1" and insert the S-expressionn SHADOW_INFO.  The resulting
   S-expression is returned in an allocated buffer RESULT will point
   to. The input parameters are expected to be valid canonicalized
   S-expressions */
index 92d312c..d17c193 100644 (file)
@@ -288,7 +288,7 @@ static void
 test_agent_shadow_key (void)
 {
 /* Create a shadow key from a public key.  We use the shadow protocol
-  "ti-v1" and insert the S-expressionn SHADOW_INFO.  The resulting
+  "t1-v1" and insert the S-expressionn SHADOW_INFO.  The resulting
   S-expression is returned in an allocated buffer RESULT will point
   to. The input parameters are expected to be valid canonicalized
   S-expressions */
index 7276787..2b3b72b 100644 (file)
@@ -514,7 +514,10 @@ else
 speedo_pkg_pinentry_configure = --enable-pinentry-gtk2
 endif
 speedo_pkg_pinentry_configure += \
-        --disable-pinentry-qt4 \
+        --disable-pinentry-qt5   \
+        --disable-pinentry-qt    \
+       --disable-pinentry-fltk  \
+       --disable-pinentry-tty   \
        CPPFLAGS=-I$(idir)/include   \
        LDFLAGS=-L$(idir)/lib        \
        CXXFLAGS=-static-libstdc++
index 149e1ec..a598900 100644 (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",
index fb6f0da..382ef1d 100644 (file)
@@ -28,7 +28,7 @@ min_automake_version="1.14"
 m4_define([mym4_package],[gnupg])
 m4_define([mym4_major], [2])
 m4_define([mym4_minor], [2])
-m4_define([mym4_micro], [3])
+m4_define([mym4_micro], [4])
 
 # To start a new development series, i.e a new major or minor number
 # you need to mark an arbitrary commit before the first beta release
@@ -1714,6 +1714,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
 #
index b404165..43f59bd 100644 (file)
@@ -16,6 +16,8 @@
 #
 # 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+
 
 ## Process this file with automake to produce Makefile.in
 
@@ -57,6 +59,8 @@ noinst_HEADERS = dirmngr.h crlcache.h crlfetch.h misc.h
 
 dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c   \
        certcache.c certcache.h \
+       domaininfo.c \
+       workqueue.c \
        loadswdb.c \
        cdb.h cdblib.c misc.c dirmngr-err.h  \
        ocsp.c ocsp.h validate.c validate.h  \
index 5317c21..17adae2 100644 (file)
@@ -17,6 +17,8 @@
  *
  * 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>
@@ -149,6 +151,7 @@ enum cmd_and_opt_values {
   oResolverTimeout,
   oConnectTimeout,
   oConnectQuickTimeout,
+  oListenBacklog,
   aTest
 };
 
@@ -254,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")),
@@ -294,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;
 
@@ -1017,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;
        }
     }
@@ -1132,7 +1144,7 @@ main (int argc, char **argv)
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       http_register_netactivity_cb (netactivity_action);
-      start_command_handler (ASSUAN_INVALID_FD);
+      start_command_handler (ASSUAN_INVALID_FD, 0);
       shutdown_reaper ();
     }
 #ifndef HAVE_W32_SYSTEM
@@ -1261,9 +1273,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);
         }
@@ -1871,6 +1884,7 @@ handle_signal (int signo)
 
     case SIGUSR1:
       cert_cache_print_stats ();
+      domaininfo_print_stats ();
       break;
 
     case SIGUSR2:
@@ -1936,7 +1950,10 @@ housekeeping_thread (void *arg)
       network_activity_seen = 0;
       if (opt.allow_version_check)
         dirmngr_load_swdb (&ctrlbuf, 0);
+      workqueue_run_global_tasks (&ctrlbuf, 1);
     }
+  else
+    workqueue_run_global_tasks (&ctrlbuf, 0);
 
   dirmngr_deinit_default_ctrl (&ctrlbuf);
 
@@ -2031,6 +2048,8 @@ check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
 static void *
 start_connection_thread (void *arg)
 {
+  static unsigned int last_session_id;
+  unsigned int session_id;
   union int_and_ptr_u argval;
   gnupg_fd_t fd;
 
@@ -2052,12 +2071,17 @@ start_connection_thread (void *arg)
   if (opt.verbose)
     log_info (_("handler for fd %d started\n"), FD2INT (fd));
 
-  start_command_handler (fd);
+  session_id = ++last_session_id;
+  if (!session_id)
+    session_id = ++last_session_id;
+  start_command_handler (fd, session_id);
 
   if (opt.verbose)
     log_info (_("handler for fd %d terminated\n"), FD2INT (fd));
   active_connections--;
 
+  workqueue_run_post_session_tasks (session_id);
+
 #ifndef HAVE_W32_SYSTEM
   argval.afd = ASSUAN_INVALID_FD;
   npth_setspecific (my_tlskey_current_fd, argval.aptr);
index 1f660de..5189f93 100644 (file)
@@ -17,6 +17,8 @@
  *
  * 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+
  */
 
 #ifndef DIRMNGR_H
@@ -226,9 +228,11 @@ ksba_cert_t get_cert_local_ski (ctrl_t ctrl,
 gpg_error_t get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr);
 int dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
                                 const char *msg);
-void start_command_handler (gnupg_fd_t fd);
+void start_command_handler (gnupg_fd_t fd, unsigned int session_id);
 gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...);
 gpg_error_t dirmngr_status_help (ctrl_t ctrl, const char *text);
+gpg_error_t dirmngr_status_helpf (ctrl_t ctrl, const char *format,
+                                  ...) GPGRT_ATTR_PRINTF(2,3);
 gpg_error_t dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
                                    const char *format,
                                    ...) GPGRT_ATTR_PRINTF(3,4);
@@ -248,4 +252,23 @@ gpg_error_t gnupg_http_tls_verify_cb (void *opaque,
 gpg_error_t dirmngr_load_swdb (ctrl_t ctrl, int force);
 
 
+/*-- domaininfo.c --*/
+void domaininfo_print_stats (void);
+int  domaininfo_is_wkd_not_supported (const char *domain);
+void domaininfo_set_no_name (const char *domain);
+void domaininfo_set_wkd_supported (const char *domain);
+void domaininfo_set_wkd_not_supported (const char *domain);
+void domaininfo_set_wkd_not_found (const char *domain);
+
+/*-- workqueue.c --*/
+typedef const char *(*wqtask_t)(ctrl_t ctrl, const char *args);
+
+void workqueue_dump_queue (ctrl_t ctrl);
+gpg_error_t workqueue_add_task (wqtask_t func, const char *args,
+                                unsigned int session_id, int need_network);
+void workqueue_run_global_tasks (ctrl_t ctrl, int with_network);
+void workqueue_run_post_session_tasks (unsigned int session_id);
+
+
+
 #endif /*DIRMNGR_H*/
diff --git a/dirmngr/domaininfo.c b/dirmngr/domaininfo.c
new file mode 100644 (file)
index 0000000..a2effff
--- /dev/null
@@ -0,0 +1,291 @@
+/* domaininfo.c - Gather statistics about accessed domains
+ * Copyright (C) 2017 Werner Koch
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0+
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dirmngr.h"
+
+
+/* Number of bucket for the hash array and limit for the length of a
+ * bucket chain.  For debugging values of 13 and 10 are more suitable
+ * and a command like
+ *   for j   in a b c d e f g h i j k l m n o p q r s t u v w z y z; do \
+ *     for i in a b c d e f g h i j k l m n o p q r s t u v w z y z; do \
+ *       gpg-connect-agent --dirmngr "wkd_get foo@$i.$j.gnupg.net" /bye \
+ *       >/dev/null ; done; done
+ * will quickly add a couple of domains.
+ */
+#define NO_OF_DOMAINBUCKETS  103
+#define MAX_DOMAINBUCKET_LEN  20
+
+
+/* Object to keep track of a domain name.  */
+struct domaininfo_s
+{
+  struct domaininfo_s *next;
+  unsigned int no_name:1;            /* Domain name not found.            */
+  unsigned int wkd_not_found:1;      /* A WKD query failed.               */
+  unsigned int wkd_supported:1;      /* One WKD entry was found.          */
+  unsigned int wkd_not_supported:1;  /* Definitely does not support WKD.  */
+  char name[1];
+};
+typedef struct domaininfo_s *domaininfo_t;
+
+/* And the hashed array.  */
+static domaininfo_t domainbuckets[NO_OF_DOMAINBUCKETS];
+
+
+/* The hash function we use.  Must not call a system function.  */
+static inline u32
+hash_domain (const char *domain)
+{
+  const unsigned char *s = (const unsigned char*)domain;
+  u32 hashval = 0;
+  u32 carry;
+
+  for (; *s; s++)
+    {
+      if (*s == '.')
+        continue;
+      hashval = (hashval << 4) + *s;
+      if ((carry = (hashval & 0xf0000000)))
+        {
+          hashval ^= (carry >> 24);
+          hashval ^= carry;
+        }
+    }
+
+  return hashval % NO_OF_DOMAINBUCKETS;
+}
+
+
+void
+domaininfo_print_stats (void)
+{
+  int bidx;
+  domaininfo_t di;
+  int count, no_name, wkd_not_found, wkd_supported, wkd_not_supported;
+  int len, minlen, maxlen;
+
+  count = no_name = wkd_not_found = wkd_supported = wkd_not_supported = 0;
+  maxlen = 0;
+  minlen = -1;
+  for (bidx = 0; bidx < NO_OF_DOMAINBUCKETS; bidx++)
+    {
+      len = 0;
+      for (di = domainbuckets[bidx]; di; di = di->next)
+        {
+          count++;
+          len++;
+          if (di->no_name)
+            no_name++;
+          if (di->wkd_not_found)
+            wkd_not_found++;
+          if (di->wkd_supported)
+            wkd_supported++;
+          if (di->wkd_not_supported)
+            wkd_not_supported++;
+        }
+      if (len > maxlen)
+        maxlen = len;
+      if (minlen == -1 || len < minlen)
+        minlen = len;
+    }
+  log_info ("domaininfo: items=%d chainlen=%d..%d nn=%d nf=%d ns=%d s=%d\n",
+            count,
+            minlen > 0? minlen : 0,
+            maxlen,
+            no_name, wkd_not_found, wkd_not_supported, wkd_supported);
+}
+
+
+/* Return true if DOMAIN definitely does not support WKD.  Noet that
+ * DOMAIN is expected to be lowercase.  */
+int
+domaininfo_is_wkd_not_supported (const char *domain)
+{
+  domaininfo_t di;
+
+  for (di = domainbuckets[hash_domain (domain)]; di; di = di->next)
+    if (!strcmp (di->name, domain))
+      return !!di->wkd_not_supported;
+
+  return 0;  /* We don't know.  */
+}
+
+
+/* Core update function.  DOMAIN is expected to be lowercase.
+ * CALLBACK is called to update the existing or the newly inserted
+ * item.  */
+static void
+insert_or_update (const char *domain,
+                  void (*callback)(domaininfo_t di, int insert_mode))
+{
+  domaininfo_t di;
+  domaininfo_t di_new;
+  domaininfo_t di_cut;
+  u32 hash;
+  int count;
+
+  hash = hash_domain (domain);
+  for (di = domainbuckets[hash]; di; di = di->next)
+    if (!strcmp (di->name, domain))
+      {
+        callback (di, 0);  /* Update */
+        return;
+      }
+
+  di_new = xtrycalloc (1, sizeof *di + strlen (domain));
+  if (!di_new)
+    return;  /* Out of core - we ignore this.  */
+  strcpy (di_new->name, domain);
+
+  /* Need to do another lookup because the malloc is a system call and
+   * thus the hash array may have been changed by another thread.  */
+  di_cut = NULL;
+  for (count=0, di = domainbuckets[hash]; di; di = di->next, count++)
+    if (!strcmp (di->name, domain))
+      {
+        callback (di, 0);  /* Update */
+        xfree (di_new);
+        return;
+      }
+
+  /* Before we insert we need to check whether the chain gets too long.  */
+  di_cut = NULL;
+  if (count >= MAX_DOMAINBUCKET_LEN)
+    {
+      for (count=0, di = domainbuckets[hash]; di; di = di->next, count++)
+        if (count >= MAX_DOMAINBUCKET_LEN/2)
+          {
+            di_cut = di->next;
+            di->next = NULL;
+            break;
+          }
+    }
+
+  /* Insert */
+  callback (di_new, 1);
+  di = di_new;
+  di->next = domainbuckets[hash];
+  domainbuckets[hash] = di;
+
+  /* Remove the rest of the cutted chain.  */
+  while (di_cut)
+    {
+      di = di_cut->next;
+      xfree (di_cut);
+      di_cut = di;
+    }
+}
+
+
+/* Helper for domaininfo_set_no_name.  */
+static void
+set_no_name_cb (domaininfo_t di, int insert_mode)
+{
+  (void)insert_mode;
+
+  di->no_name = 1;
+  /* Obviously the domain is in this case also not supported.  */
+  di->wkd_not_supported = 1;
+
+  /* The next should already be 0 but we clear it anyway in the case
+   * of a temporary DNS failure.  */
+  di->wkd_supported = 0;
+}
+
+
+/* Mark DOMAIN as not existent.  */
+void
+domaininfo_set_no_name (const char *domain)
+{
+  insert_or_update (domain, set_no_name_cb);
+}
+
+
+/* Helper for domaininfo_set_wkd_supported.  */
+static void
+set_wkd_supported_cb (domaininfo_t di, int insert_mode)
+{
+  (void)insert_mode;
+
+  di->wkd_supported = 1;
+  /* The next will already be set unless the domain enabled WKD in the
+   * meantime.  Thus we need to clear it.  */
+  di->wkd_not_supported = 0;
+}
+
+
+/* Mark DOMAIN as supporting WKD.  */
+void
+domaininfo_set_wkd_supported (const char *domain)
+{
+  insert_or_update (domain, set_wkd_supported_cb);
+}
+
+
+/* Helper for domaininfo_set_wkd_not_supported.  */
+static void
+set_wkd_not_supported_cb (domaininfo_t di, int insert_mode)
+{
+  (void)insert_mode;
+
+  di->wkd_not_supported = 1;
+  di->wkd_supported = 0;
+}
+
+
+/* Mark DOMAIN as not supporting WKD queries (e.g. no policy file).  */
+void
+domaininfo_set_wkd_not_supported (const char *domain)
+{
+  insert_or_update (domain, set_wkd_not_supported_cb);
+}
+
+
+
+/* Helper for domaininfo_set_wkd_not_found.  */
+static void
+set_wkd_not_found_cb (domaininfo_t di, int insert_mode)
+{
+  /* Set the not found flag but there is no need to do this if we
+   * already know that the domain either does not support WKD or we
+   * know that it supports WKD.  */
+  if (insert_mode)
+    di->wkd_not_found = 1;
+  else if (!di->wkd_not_supported && !di->wkd_supported)
+    di->wkd_not_found = 1;
+
+  /* Better clear this flag in case we had a DNS failure in the
+   * past.  */
+  di->no_name = 0;
+}
+
+
+/* Update a counter for DOMAIN to keep track of failed WKD queries.  */
+void
+domaininfo_set_wkd_not_found (const char *domain)
+{
+  insert_or_update (domain, set_wkd_not_found_cb);
+}
index 857aab1..38cd02f 100644 (file)
@@ -296,7 +296,8 @@ ks_action_get (ctrl_t ctrl, uri_item_t keyservers,
 
 
 /* Retrieve keys from URL and write the result to the provided output
-   stream OUTFP.  */
+ * stream OUTFP.  If OUTFP is NULL the data is written to the bit
+ * bucket. */
 gpg_error_t
 ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp)
 {
index 1716141..6291a9a 100644 (file)
@@ -636,7 +636,9 @@ armor_data (char **r_string, const void *data, size_t datalen)
   return 0;
 }
 
-/* Copy all data from IN to OUT.  */
+
+/* Copy all data from IN to OUT.  OUT may be NULL to use this fucntion
+ * as a dummy reader.  */
 gpg_error_t
 copy_stream (estream_t in, estream_t out)
 {
@@ -647,9 +649,8 @@ copy_stream (estream_t in, estream_t out)
     {
       if (!nread)
         return 0; /* EOF */
-      if (es_write (out, buffer, nread, NULL))
+      if (out && es_write (out, buffer, nread, NULL))
         break;
-
     }
   return gpg_error_from_syserror ();
 }
index 7ed6cde..3d0768b 100644 (file)
@@ -18,6 +18,8 @@
  *
  * 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>
@@ -78,7 +80,8 @@
 
 #define PARM_ERROR(t) assuan_set_error (ctx, \
                                         gpg_error (GPG_ERR_ASS_PARAMETER), (t))
-#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
+#define set_error(e,t) (ctx ? assuan_set_error (ctx, gpg_error (e), (t)) \
+                        /**/: gpg_error (e))
 
 
 
@@ -88,6 +91,9 @@ struct server_local_s
   /* Data used to associate an Assuan context with local server data */
   assuan_context_t assuan_ctx;
 
+  /* The session id (a counter).  */
+  unsigned int session_id;
+
   /* Per-session LDAP servers.  */
   ldap_server_t ldapservers;
 
@@ -123,6 +129,9 @@ static es_cookie_io_functions_t data_line_cookie_functions =
   };
 
 
+/* Local prototypes */
+static const char *task_check_wkd_support (ctrl_t ctrl, const char *domain);
+
 
 
 \f
@@ -820,24 +829,22 @@ cmd_dns_cert (assuan_context_t ctx, char *line)
 
 
 \f
-static const char hlp_wkd_get[] =
-  "WKD_GET [--submission-address|--policy-flags] <user_id>\n"
-  "\n"
-  "Return the key or other info for <user_id>\n"
-  "from the Web Key Directory.";
+/* Core of cmd_wkd_get and task_check_wkd_support.  If CTX is NULL
+ * this function will not write anything to the assuan output.  */
 static gpg_error_t
-cmd_wkd_get (assuan_context_t ctx, char *line)
+proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
 {
-  ctrl_t ctrl = assuan_get_pointer (ctx);
   gpg_error_t err = 0;
   char *mbox = NULL;
   char *domainbuf = NULL;
   char *domain;     /* Points to mbox or domainbuf.  */
+  char *domain_orig;/* Points to mbox.  */
   char sha1buf[20];
   char *uri = NULL;
   char *encodedhash = NULL;
   int opt_submission_addr;
   int opt_policy_flags;
+  int is_wkd_query;   /* True if this is a real WKD query.  */
   int no_log = 0;
   char portstr[20] = { 0 };
 
@@ -846,6 +853,7 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
   if (has_option (line, "--quick"))
     ctrl->timeout = opt.connect_quick_timeout;
   line = skip_options (line);
+  is_wkd_query = !(opt_policy_flags || opt_submission_addr);
 
   mbox = mailbox_from_userid (line);
   if (!mbox || !(domain = strchr (mbox, '@')))
@@ -854,6 +862,18 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
       goto leave;
     }
   *domain++ = 0;
+  domain_orig = domain;
+
+  /* First check whether we already know that the domain does not
+   * support WKD.  */
+  if (is_wkd_query)
+    {
+      if (domaininfo_is_wkd_not_supported (domain_orig))
+        {
+          err = gpg_error (GPG_ERR_NO_DATA);
+          goto leave;
+        }
+    }
 
   /* Check for SRV records.  */
   if (1)
@@ -872,7 +892,8 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
       domainlen = strlen (domain);
       for (i = 0; i < srvscount; i++)
         {
-          log_debug ("srv: trying '%s:%hu'\n", srvs[i].target, srvs[i].port);
+          if (DBG_DNS)
+            log_debug ("srv: trying '%s:%hu'\n", srvs[i].target, srvs[i].port);
           targetlen = strlen (srvs[i].target);
           if ((targetlen > domainlen + 1
                && srvs[i].target[targetlen - domainlen - 1] == '.'
@@ -949,19 +970,52 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
   {
     estream_t outfp;
 
-    outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
-    if (!outfp)
+    outfp = ctx? es_fopencookie (ctx, "w", data_line_cookie_functions) : NULL;
+    if (!outfp && ctx)
       err = set_error (GPG_ERR_ASS_GENERAL,
                        "error setting up a data stream");
     else
       {
-        if (no_log)
-          ctrl->server_local->inhibit_data_logging = 1;
-        ctrl->server_local->inhibit_data_logging_now = 0;
-        ctrl->server_local->inhibit_data_logging_count = 0;
+        if (ctrl->server_local)
+          {
+            if (no_log)
+              ctrl->server_local->inhibit_data_logging = 1;
+            ctrl->server_local->inhibit_data_logging_now = 0;
+            ctrl->server_local->inhibit_data_logging_count = 0;
+          }
         err = ks_action_fetch (ctrl, uri, outfp);
         es_fclose (outfp);
-        ctrl->server_local->inhibit_data_logging = 0;
+        if (ctrl->server_local)
+          ctrl->server_local->inhibit_data_logging = 0;
+
+        /* Register the result under the domain name of MBOX. */
+        switch (gpg_err_code (err))
+          {
+          case 0:
+            domaininfo_set_wkd_supported (domain_orig);
+            break;
+
+          case GPG_ERR_NO_NAME:
+            /* There is no such domain.  */
+            domaininfo_set_no_name (domain_orig);
+            break;
+
+          case GPG_ERR_NO_DATA:
+            if (is_wkd_query && ctrl->server_local)
+              {
+                /* Mark that and schedule a check.  */
+                domaininfo_set_wkd_not_found (domain_orig);
+                workqueue_add_task (task_check_wkd_support, domain_orig,
+                                    ctrl->server_local->session_id, 1);
+              }
+            else if (opt_policy_flags) /* No policy file - no support.  */
+              domaininfo_set_wkd_not_supported (domain_orig);
+            break;
+
+          default:
+            /* Don't register other errors.  */
+            break;
+          }
       }
   }
 
@@ -970,10 +1024,50 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
   xfree (encodedhash);
   xfree (mbox);
   xfree (domainbuf);
+  return err;
+}
+
+
+static const char hlp_wkd_get[] =
+  "WKD_GET [--submission-address|--policy-flags] <user_id>\n"
+  "\n"
+  "Return the key or other info for <user_id>\n"
+  "from the Web Key Directory.";
+static gpg_error_t
+cmd_wkd_get (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+
+  err = proc_wkd_get (ctrl, ctx, line);
+
   return leave_cmd (ctx, err);
 }
 
 
+/* A task to check whether DOMAIN supports WKD.  This is done by
+ * checking whether the policy flags file can be read.  */
+static const char *
+task_check_wkd_support (ctrl_t ctrl, const char *domain)
+{
+  char *string;
+
+  if (!ctrl || !domain)
+    return "check_wkd_support";
+
+  string = strconcat ("--policy-flags foo@", domain, NULL);
+  if (!string)
+    log_error ("%s: %s\n", __func__, gpg_strerror (gpg_error_from_syserror ()));
+  else
+    {
+      proc_wkd_get (ctrl, NULL, string);
+      xfree (string);
+    }
+
+  return NULL;
+}
+
+
 \f
 static const char hlp_ldapserver[] =
   "LDAPSERVER <data>\n"
@@ -2388,12 +2482,15 @@ static const char hlp_getinfo[] =
   "pid         - Return the process id of the server.\n"
   "tor         - Return OK if running in Tor mode\n"
   "dnsinfo     - Return info about the DNS resolver\n"
-  "socket_name - Return the name of the socket.\n";
+  "socket_name - Return the name of the socket.\n"
+  "session_id  - Return the current session_id.\n"
+  "workqueue   - Inspect the work queue\n";
 static gpg_error_t
 cmd_getinfo (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   gpg_error_t err;
+  char numbuf[50];
 
   if (!strcmp (line, "version"))
     {
@@ -2402,8 +2499,6 @@ cmd_getinfo (assuan_context_t ctx, char *line)
     }
   else if (!strcmp (line, "pid"))
     {
-      char numbuf[50];
-
       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
       err = assuan_send_data (ctx, numbuf, strlen (numbuf));
     }
@@ -2412,6 +2507,11 @@ cmd_getinfo (assuan_context_t ctx, char *line)
       const char *s = dirmngr_get_current_socket_name ();
       err = assuan_send_data (ctx, s, strlen (s));
     }
+  else if (!strcmp (line, "session_id"))
+    {
+      snprintf (numbuf, sizeof numbuf, "%u", ctrl->server_local->session_id);
+      err = assuan_send_data (ctx, numbuf, strlen (numbuf));
+    }
   else if (!strcmp (line, "tor"))
     {
       int use_tor;
@@ -2447,6 +2547,11 @@ cmd_getinfo (assuan_context_t ctx, char *line)
         }
       err = 0;
     }
+  else if (!strcmp (line, "workqueue"))
+    {
+      workqueue_dump_queue (ctrl);
+      err = 0;
+    }
   else
     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
 
@@ -2574,9 +2679,10 @@ dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
 
 
 /* Startup the server and run the main command loop.  With FD = -1,
-   use stdin/stdout. */
+ * use stdin/stdout.  SESSION_ID is either 0 or a unique number
+ * identifying a session.  */
 void
-start_command_handler (assuan_fd_t fd)
+start_command_handler (assuan_fd_t fd, unsigned int session_id)
 {
   static const char hello[] = "Dirmngr " VERSION " at your service";
   static char *hello_line;
@@ -2653,6 +2759,8 @@ start_command_handler (assuan_fd_t fd)
   assuan_register_option_handler (ctx, option_handler);
   assuan_register_reset_notify (ctx, reset_notify);
 
+  ctrl->server_local->session_id = session_id;
+
   for (;;)
     {
       rc = assuan_accept (ctx);
@@ -2722,12 +2830,12 @@ dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
   gpg_error_t err = 0;
   va_list arg_ptr;
   const char *text;
+  assuan_context_t ctx;
 
   va_start (arg_ptr, keyword);
 
-  if (ctrl->server_local)
+  if (ctrl->server_local && (ctx = ctrl->server_local->assuan_ctx))
     {
-      assuan_context_t ctx = ctrl->server_local->assuan_ctx;
       char buf[950], *p;
       size_t n;
 
@@ -2752,16 +2860,15 @@ dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
 }
 
 
-/* Print a help status line.  TEXTLEN gives the length of the text
-   from TEXT to be printed.  The function splits text at LFs.  */
+/* Print a help status line.  The function splits text at LFs.  */
 gpg_error_t
 dirmngr_status_help (ctrl_t ctrl, const char *text)
 {
   gpg_error_t err = 0;
+  assuan_context_t ctx;
 
-  if (ctrl->server_local)
+  if (ctrl->server_local && (ctx = ctrl->server_local->assuan_ctx))
     {
-      assuan_context_t ctx = ctrl->server_local->assuan_ctx;
       char buf[950], *p;
       size_t n;
 
@@ -2783,6 +2890,26 @@ dirmngr_status_help (ctrl_t ctrl, const char *text)
 }
 
 
+/* Print a help status line using a printf like format.  The function
+ * splits text at LFs.  */
+gpg_error_t
+dirmngr_status_helpf (ctrl_t ctrl, const char *format, ...)
+{
+  va_list arg_ptr;
+  gpg_error_t err;
+  char *buf;
+
+  va_start (arg_ptr, format);
+  buf = es_vbsprintf (format, arg_ptr);
+  err = buf? 0 : gpg_error_from_syserror ();
+  va_end (arg_ptr);
+  if (!err)
+    err = dirmngr_status_help (ctrl, buf);
+  es_free (buf);
+  return err;
+}
+
+
 /* This function is similar to print_assuan_status but takes a CTRL
  * arg instead of an assuan context as first argument.  */
 gpg_error_t
@@ -2791,7 +2918,10 @@ dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
 {
   gpg_error_t err;
   va_list arg_ptr;
-  assuan_context_t ctx = ctrl->server_local->assuan_ctx;
+  assuan_context_t ctx;
+
+  if (!ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
+    return 0;
 
   va_start (arg_ptr, format);
   err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
diff --git a/dirmngr/workqueue.c b/dirmngr/workqueue.c
new file mode 100644 (file)
index 0000000..2cb8573
--- /dev/null
@@ -0,0 +1,214 @@
+/* workqueue.c - Maintain a queue of background tasks
+ * Copyright (C) 2017 Werner Koch
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0+
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dirmngr.h"
+
+
+/* An object for one item in the workqueue.  */
+struct wqitem_s
+{
+  struct wqitem_s *next;
+
+  /* This flag is set if the task requires network access.  */
+  unsigned int need_network:1;
+
+  /* The id of the session which created this task.  If this is 0 the
+   * task is not associated with a specific session.  */
+  unsigned int session_id;
+
+  /* The function to perform the backgrount task.  */
+  wqtask_t func;
+
+  /* A string with the string argument for that task.  */
+  char args[1];
+};
+typedef struct wqitem_s *wqitem_t;
+
+
+/* The workque is a simple linked list.  */
+static wqitem_t workqueue;
+
+
+/* Dump the queue using Assuan status comments.  */
+void
+workqueue_dump_queue (ctrl_t ctrl)
+{
+  wqitem_t saved_workqueue;
+  wqitem_t item;
+  unsigned int count;
+
+  /* Temporay detach the entiere workqueue so that other threads don't
+   * get into our way.  */
+  saved_workqueue = workqueue;
+  workqueue = NULL;
+
+  for (count=0, item = saved_workqueue; item; item = item->next)
+    count++;
+
+  dirmngr_status_helpf (ctrl, "wq: number of entries: %u", count);
+  for (item = saved_workqueue; item; item = item->next)
+    dirmngr_status_helpf (ctrl, "wq: sess=%u net=%d %s(\"%.100s%s\")",
+                          item->session_id, item->need_network,
+                          item->func? item->func (NULL, NULL): "nop",
+                          item->args, strlen (item->args) > 100? "[...]":"");
+
+  /* Restore then workqueue.  Actually we append the saved queue do a
+   * possibly updated workqueue.  */
+  if (!(item=workqueue))
+    workqueue = saved_workqueue;
+  else
+    {
+      while (item->next)
+        item = item->next;
+      item->next = saved_workqueue;
+    }
+}
+
+
+/* Append the task (FUNC,ARGS) to the work queue.  FUNC shall return
+ * its name when called with (NULL, NULL).  */
+gpg_error_t
+workqueue_add_task (wqtask_t func, const char *args, unsigned int session_id,
+                    int need_network)
+{
+  wqitem_t item, wi;
+
+  item = xtrycalloc (1, sizeof *item + strlen (args));
+  if (!item)
+    return gpg_error_from_syserror ();
+  strcpy (item->args, args);
+  item->func = func;
+  item->session_id = session_id;
+  item->need_network = !!need_network;
+
+  if (!(wi=workqueue))
+    workqueue = item;
+  else
+    {
+      while (wi->next)
+        wi = wi->next;
+      wi->next = item;
+    }
+  return 0;
+}
+
+
+/* Run the task described by ITEM.  ITEM must have been detached from
+ * the workqueue; its ownership is transferred to this fucntion.  */
+static void
+run_a_task (ctrl_t ctrl, wqitem_t item)
+{
+  log_assert (!item->next);
+
+  if (opt.verbose)
+    log_info ("session %u: running %s(\"%s%s\")\n",
+              item->session_id,
+              item->func? item->func (NULL, NULL): "nop",
+              item->args, strlen (item->args) > 100? "[...]":"");
+  if (item->func)
+    item->func (ctrl, item->args);
+
+  xfree (item);
+}
+
+
+/* Run tasks not associated with a session.  This is called from the
+ * ticker every few minutes.  If WITH_NETWORK is not set tasks which
+ * require the network are not run.  */
+void
+workqueue_run_global_tasks (ctrl_t ctrl, int with_network)
+{
+  wqitem_t item, prev;
+
+  with_network = !!with_network;
+
+  if (opt.verbose)
+    log_info ("running scheduled tasks%s\n", with_network?" (with network)":"");
+
+  for (;;)
+    {
+      prev = NULL;
+      for (item = workqueue; item; prev = item, item = item->next)
+        if (!item->session_id
+            && (!item->need_network || (item->need_network && with_network)))
+          break;
+      if (!item)
+        break;  /* No more tasks to run.  */
+
+      /* Detach that item from the workqueue.  */
+      if (!prev)
+        workqueue = item->next;
+      else
+        prev->next = item->next;
+      item->next = NULL;
+
+      /* Run the task.  */
+      run_a_task (ctrl, item);
+    }
+}
+
+
+/* Run tasks scheduled for running after a session.  Those tasks are
+ * identified by the SESSION_ID.  */
+void
+workqueue_run_post_session_tasks (unsigned int session_id)
+{
+  struct server_control_s ctrlbuf;
+  ctrl_t ctrl = NULL;
+  wqitem_t item, prev;
+
+  if (!session_id)
+    return;
+
+  for (;;)
+    {
+      prev = NULL;
+      for (item = workqueue; item; prev = item, item = item->next)
+        if (item->session_id == session_id)
+          break;
+      if (!item)
+        break;  /* No more tasks for this session.  */
+
+      /* Detach that item from the workqueue.  */
+      if (!prev)
+        workqueue = item->next;
+      else
+        prev->next = item->next;
+      item->next = NULL;
+
+      /* Create a CTRL object the first time we need it.  */
+      if (!ctrl)
+        {
+          memset (&ctrlbuf, 0, sizeof ctrlbuf);
+          ctrl = &ctrlbuf;
+          dirmngr_init_default_ctrl (ctrl);
+        }
+
+      /* Run the task.  */
+      run_a_task (ctrl, item);
+    }
+
+  dirmngr_deinit_default_ctrl (ctrl);
+}
index 62a6f95..bd16856 100644 (file)
@@ -224,6 +224,7 @@ Note that such a comment will be removed if the git commit option
   - CVE-id :: CVE id number pertaining to this commit.
   - Regression-due-to :: Commit id of the regression fixed by this commit.
   - Fixes-commit :: Commit id this commit fixes.
+  - Updates-commit :: Commit id this commit updates.
   - Reported-by :: Value is a name or mail address of a bug reporte.
   - Suggested-by :: Value is a name or mail address of someone how
                     suggested this change.
index 9654a0e..800955c 100644 (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
index f401602..95e463b 100644 (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
index afe2804..3e8bd89 100644 (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}
@@ -652,6 +655,17 @@ Select the digest algorithm used to compute ssh fingerprints that are
 communicated to the user, e.g. in pinentry dialogs.  OpenSSH has
 transitioned from using MD5 to the more secure SHA256.
 
+
+@item --auto-expand-secmem @var{n}
+@opindex auto-expand-secmem
+Allow Libgcrypt to expand its secure memory area as required.  The
+optional value @var{n} is a non-negative integer with a suggested size
+in bytes of each additionally allocated secure memory area.  The value
+is rounded up to the next 32 KiB; usual C style prefixes are allowed.
+For an heavy loaded gpg-agent with many concurrent connection this
+option avoids sign or decrypt errors due to out of secure memory error
+returns.
+
 @item --s2k-count @var{n}
 @opindex s2k-count
 Specify the iteration count used to protect the passphrase.  This
index bd45b04..35bb9a8 100644 (file)
@@ -196,11 +196,13 @@ Make a detached signature.
 @item --encrypt
 @itemx -e
 @opindex encrypt
-Encrypt data. This command may be combined with @option{--sign} (to
-sign and encrypt a message), @option{--symmetric} (to encrypt a
-message that can decrypted using a secret key or a passphrase), or
-@option{--sign} and @option{--symmetric} together (for a signed
-message that can be decrypted using a secret key or a passphrase).
+Encrypt data to one or more public keys. This command may be combined
+with @option{--sign} (to sign and encrypt a message),
+@option{--symmetric} (to encrypt a message that can decrypted using a
+secret key or a passphrase), or @option{--sign} and
+@option{--symmetric} together (for a signed message that can be
+decrypted using a secret key or a passphrase).  @option{--recipient}
+and related options specify which public keys to use for encryption.
 
 @item --symmetric
 @itemx -c
index 4c6bb93..a9e6d1e 100644 (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
index 5104bea..9301334 100644 (file)
@@ -407,6 +407,14 @@ changing.
 This means that the changes will take effect at run-time, as far as
 this is possible.  Otherwise, they will take effect at the next start
 of the respective backend programs.
+
+@item --status-fd @var{n}
+@opindex status-fd
+Write special status strings to the file descriptor @var{n}.  This
+program returns the status messages SUCCESS or FAILURE which are
+helpful when the caller uses a double fork approach and can't easily
+get the return code of the process.
+
 @manpause
 @end table
 
index 029dbf0..7f7d515 100644 (file)
@@ -174,18 +174,23 @@ Display a brief help page and exit.
 .br
 .B gpg-wks-server
 .RI [ options ]
+.B \-\-check-key
+.I user-id
+.br
+.B gpg-wks-server
+.RI [ options ]
 .B \-\-install-key
 .I file
 .br
 .B gpg-wks-server
 .RI [ options ]
 .B \-\-remove-key
-.I mailaddr
+.I user-id
 .br
 .B gpg-wks-server
 .RI [ options ]
 .B \-\-revoke-key
-.I mailaddr
+.I user-id
 @end ifset
 
 @mansect description
@@ -208,8 +213,22 @@ The command @option{--list-domains} prints all configured domains.
 Further it creates missing directories for the configuration and
 prints warnings pertaining to problems in the configuration.
 
-The commands @option{--install-key}, @option{--remove-key}, and
-@option{--revoke-key} are not yet functional.
+The command @option{--check-key} (or just @option{--check}) checks
+whether a key with the given user-id is installed.  The process return
+success in this case; to also print a diagnostic, use option
+@option{-v}.  If the key is not installed a diagnostics is printed and
+the process returns failure; to suppress the diagnostic, use option
+@option{-q}.  More than one user-id can be given; see also option
+@option{with-file}.
+
+The command @option{--remove-key} uninstalls a key from the WKD.  The
+process return success in this case; to also print a diagnostic, use
+option @option{-v}.  If the key is not installed a diagnostics is
+printed and the process returns failure; to suppress the diagnostic,
+use option @option{-q}.
+
+The commands @option{--install-key} and @option{--revoke-key} are not
+yet functional.
 
 
 @mansect options
@@ -237,6 +256,16 @@ Requires installation of that command.
 Write the created mail also to @var{file}. Note that the value
 @code{-} for @var{file} would write it to stdout.
 
+@item --with-dir
+@opindex with-dir
+Also print the directory name for each domain listed by command
+@option{--list-domains}.
+
+@item --with-file
+@opindex with-file
+With command @option{--check-key} print for each user-id, the address,
+'i' for installed key or 'n' for not installed key, and the filename.
+
 @item --verbose
 @opindex verbose
 Enable extra informational output.
index 655937f..b950d0c 100644 (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>
 
 
 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;
-
-    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");
+  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");
     }
-
+  else if (!opt.no_mdc_warn)
     {
-        char buf[20];
-
-        sprintf (buf, "%d %d", ed.mdc_method, cfx->dek->algo);
-        write_status_text (STATUS_BEGIN_ENCRYPTION, buf);
+      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 );
-       }
-       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_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" );
+  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");
        }
-       gcry_cipher_close (cfx->cipher_hd);
+
+      gcry_cipher_close (cfx->cipher_hd);
     }
-    else if( control == IOBUFCTRL_DESC ) {
-        mem2str (buf, "cipher_filter", *ret_len);
+  else if (control == IOBUFCTRL_DESC)
+    {
+      mem2str (buf, "cipher_filter", *ret_len);
     }
-    return rc;
+
+  return rc;
 }
index 1548720..a7fd1aa 100644 (file)
--- a/g10/cpr.c
+++ b/g10/cpr.c
@@ -425,11 +425,17 @@ do_get_from_fd ( const char *keyword, int hidden, int getbool )
     {
       if (i >= len-1 )
         {
+          /* On the first iteration allocate a new buffer.  If that
+           * buffer is too short at further iterations do a poor man's
+           * realloc.  */
           char *save = string;
           len += 100;
           string = hidden? xmalloc_secure ( len ) : xmalloc ( len );
           if (save)
-            memcpy (string, save, i );
+            {
+              memcpy (string, save, i);
+              xfree (save);
+            }
           else
             i = 0;
        }
index 17de53f..219b7ed 100644 (file)
Binary files a/g10/distsigkey.gpg and b/g10/distsigkey.gpg differ
index 8f6371b..c538dc1 100644 (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)
     {
index 275608d..9e4b1e5 100644 (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;
 
 
index f73e443..e31e023 100644 (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!  */
+/* 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.
+ *
+ * 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;
+        }
     }
 
 
index 38686b2..b42afa8 100644 (file)
@@ -384,19 +384,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_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_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_SHA256))
+                  strcat (dummy_string, "H8 ");
+              }
 
-           if (!openpgp_md_test_algo (DIGEST_ALGO_SHA224))
+            if (!openpgp_md_test_algo (DIGEST_ALGO_SHA224))
              strcat (dummy_string, "H11 ");
 
            strcat (dummy_string, "H2 "); /* SHA-1 */
@@ -4467,6 +4484,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);
index d733156..ba35ec2 100644 (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);
index 0b6ee8b..eee14f6 100644 (file)
@@ -3087,6 +3087,12 @@ parse_plaintext (IOBUF inp, int pkttype, unsigned long pktlen,
        else
          pt->name[i] = c;
     }
+  /* Fill up NAME so that a check with valgrind won't complain about
+   * reading from uninitalized memory.  This case may be triggred by
+   * corrupted packets.  */
+  for (; i < namelen; i++)
+    pt->name[i] = 0;
+
   pt->timestamp = read_32 (inp);
   if (pktlen)
     pktlen -= 4;
index 220936c..581cae4 100644 (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;
-
-    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;
+  PKT_public_key *pk;
+  char *result;
+
+  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)
 {
index 4578700..8465232 100644 (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);
 
index c183fc6..091d5b0 100644 (file)
@@ -3332,8 +3332,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);
@@ -3354,11 +3354,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)
     {
@@ -3384,7 +3393,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"
@@ -3396,9 +3405,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)
@@ -3436,7 +3445,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"
@@ -3450,9 +3459,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);
             }
         }
@@ -3463,6 +3472,7 @@ tofu_register_signature (ctrl_t ctrl,
         break;
     }
 
+ leave:
   if (rc)
     rollback_transaction (ctrl);
   else
@@ -3486,7 +3496,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)
@@ -3531,8 +3542,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)
@@ -3550,7 +3567,7 @@ tofu_register_encryption (ctrl_t ctrl,
           /* An error.  */
           rc = gpg_error (GPG_ERR_GENERAL);
           xfree (email);
-          goto die;
+          goto leave;
         }
 
 
@@ -3576,7 +3593,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"
@@ -3588,24 +3605,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;
@@ -3681,10 +3696,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)
@@ -3699,14 +3714,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;
 }
 
 
@@ -3720,7 +3741,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)
@@ -3744,6 +3768,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.  */
@@ -3889,6 +3915,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);
 
@@ -3958,6 +3986,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);
 
@@ -3994,6 +4024,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 = ?"
index 92c1ca5..0a98c12 100644 (file)
@@ -1505,6 +1505,10 @@ store_validation_status (ctrl_t ctrl, int depth,
 /* Returns a sanitized copy of the regexp (which might be "", but not
    NULL). */
 #ifndef DISABLE_REGEX
+/* Operator charactors except '.' and backslash.
+   See regex(7) on BSD.  */
+#define REGEXP_OPERATOR_CHARS "^[$()|*+?{"
+
 static char *
 sanitize_regexp(const char *old)
 {
@@ -1544,7 +1548,7 @@ sanitize_regexp(const char *old)
     {
       if(!escaped && old[start]=='\\')
        escaped=1;
-      else if(!escaped && old[start]!='.')
+      else if (!escaped && strchr (REGEXP_OPERATOR_CHARS, old[start]))
        new[idx++]='\\';
       else
        escaped=0;
index 4d9ce66..a65380c 100644 (file)
--- a/po/ca.po
+++ b/po/ca.po
@@ -496,10 +496,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "AVÍS: els permissos són insegurs en %s «%s»\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "ha fallat l'actualització: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "s'està escrivint la clau secreta a «%s»\n"
 
@@ -9154,6 +9150,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "ha fallat l'actualització: %s\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "clau %08lX: l'algoritme de clau pública no és suportat\n"
index 24d54c7..4693f73 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -3,7 +3,8 @@
 #               2005 Free Software Foundation, Inc.
 # Magda Procházková <magda@math.muni.cz> 2001,
 # Roman Pavlik <rp@tns.cz> 2001, 2002, 2003, 2004, 2005.
-# Petr Pisar <petr.pisar@atlas.cz>, 2009, 2010, 2011, 2013, 2014, 2015.
+# Petr Pisar <petr.pisar@atlas.cz>, 2009, 2010, 2011, 2013, 2014, 2015, 2016.
+# Petr Pisar <petr.pisar@atlas.cz>, 2017.
 #
 # A "%%0A" is used by Pinentry to insert a line break. The double percent
 # sign is actually needed because it is also a printf format string. If you
@@ -24,6 +25,7 @@
 # zákon o elektronickém podpisu, <http://portal.gov.cz/zakon/227/2000>:
 # kvalifikovaný certifikát/podpis
 #
+# administrator → správce
 # cache → keš
 # distribution point → místo distribuce
 # DP (distribution point (of CRL)) → DP
@@ -33,9 +35,9 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg2 2.1.10\n"
+"Project-Id-Version: gnupg2 2.2.1\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2017-11-02 17:38+0100\n"
+"PO-Revision-Date: 2017-11-17 10:33+01:00\n"
 "Last-Translator: Petr Pisar <petr.pisar@atlas.cz>\n"
 "Language-Team: Czech <gnupg-i18n@gnupg.org>\n"
 "Language: cs\n"
@@ -174,10 +176,9 @@ msgstr "na kartě není autentizační klíč pro SSH: %s\n"
 msgid "no suitable card key found: %s\n"
 msgstr "nenalezen žádný vhodný klíč karty: %s\n"
 
-#, fuzzy, c-format
-#| msgid "error getting stored flags: %s\n"
+#, c-format
 msgid "error getting list of cards: %s\n"
-msgstr "chyba při získání uložených příznaků: %s\n"
+msgstr "chyba při získávání seznamu karet: %s\n"
 
 #, c-format
 msgid ""
@@ -329,10 +330,8 @@ msgstr "poběží v režimu démona (na pozadí)"
 msgid "run in server mode (foreground)"
 msgstr "poběží v režimu serveru (na popředí)"
 
-#, fuzzy
-#| msgid "run in server mode"
 msgid "run in supervised mode"
-msgstr "pracovat v režimu serveru"
+msgstr "poběží v režimu dohledu"
 
 msgid "verbose"
 msgstr "upovídaný režim"
@@ -388,10 +387,8 @@ msgstr "nedovolit klientům označovat klíče za „důvěryhodné“"
 msgid "allow presetting passphrase"
 msgstr "umožnit přednastavení hesla"
 
-#, fuzzy
-#| msgid "allow caller to override the pinentry"
 msgid "disallow caller to override the pinentry"
-msgstr "umožnit volajícímu přebít pinentry"
+msgstr "zmemožnit volajícímu přebít pinentry"
 
 msgid "allow passphrase to be prompted through Emacs"
 msgstr "umožnit zadání hesla skrze Emacs"
@@ -400,7 +397,7 @@ msgid "enable ssh support"
 msgstr "zapnout podporu pro OpenSSH"
 
 msgid "|ALGO|use ALGO to show ssh fingerprints"
-msgstr ""
+msgstr "|ALGORITMUS|ukazovat otkisky SSH pomocí ALGORITMU"
 
 msgid "enable putty support"
 msgstr "zapnout podporu pro PuTTY"
@@ -464,15 +461,9 @@ msgstr "chyba při získávání soli pro socket\n"
 msgid "error binding socket to '%s': %s\n"
 msgstr "chyba při přilepování socketu na „%s“: %s\n"
 
-# TODO: i18n of first %s
-#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgid "can't set permissions of '%s': %s\n"
-msgstr "Varování: přístupová práva %s „%s“ nejsou bezpečná\n"
-
 #, c-format
-msgid "listen() failed: %s\n"
-msgstr "volání listen() selhalo: %s\n"
+msgid "can't set permissions of '%s': %s\n"
+msgstr "přístupová práva „%s“ nelze nastavit: %s\n"
 
 #, c-format
 msgid "listening on socket '%s'\n"
@@ -756,10 +747,9 @@ msgstr "chyba v běhu „%s“: návratový kód %d\n"
 msgid "error running '%s': terminated\n"
 msgstr "chyba v běhu „%s“: násilně ukončeno\n"
 
-#, fuzzy, c-format
-#| msgid "waiting for process %d to terminate failed: %s\n"
+#, c-format
 msgid "waiting for processes to terminate failed: %s\n"
-msgstr "čekání na konec procesu %d se nezdařilo: %s\n"
+msgstr "čekání na ukončení procesu se nezdařilo: %s\n"
 
 #, c-format
 msgid "error getting exit code of process %d: %s\n"
@@ -786,10 +776,9 @@ msgstr "Varování: vlastnictví %s „%s“ není nastaveno bezpečně\n"
 msgid "Warning: unsafe permissions on %s \"%s\"\n"
 msgstr "Varování: přístupová práva %s „%s“ nejsou bezpečná\n"
 
-#, fuzzy, c-format
-#| msgid "waiting for the agent to come up ... (%ds)\n"
+#, c-format
 msgid "waiting for file '%s' to become accessible ...\n"
-msgstr "čeká se na agenta… (%d s)\n"
+msgstr "čekání, až se soubor „%s“ stane přístupným…\n"
 
 #, c-format
 msgid "renaming '%s' to '%s' failed: %s\n"
@@ -1190,10 +1179,10 @@ msgstr ""
 "neplatný znak (quoted-printable) v ASCII kódování – pravděpodobně byl použit "
 "špatný MTA\n"
 
-#, fuzzy, c-format
-#| msgid "not human readable"
+# TODO: Pluralize
+#, c-format
 msgid "[ not human readable (%zu bytes: %s%s) ]"
-msgstr "není v přímo čitelném formátu"
+msgstr "[ nečitelné pro lidi (%zu bajtů: %s%s) ]"
 
 msgid ""
 "a notation name must have only printable characters or spaces, and end with "
@@ -1211,19 +1200,11 @@ msgstr "jméno uživatele nesmí obsahovat více než jeden znak „@“\n"
 msgid "a notation value must not use any control characters\n"
 msgstr "hodnota nemůže obsahovat žádné kontrolní znaky\n"
 
-#, fuzzy
-#| msgid "a notation name must not contain more than one '@' character\n"
 msgid "a notation name may not contain an '=' character\n"
-msgstr "jméno uživatele nesmí obsahovat více než jeden znak „@“\n"
+msgstr "jméno uživatele nesmí obsahovat znak „=“\n"
 
-#, fuzzy
-#| msgid ""
-#| "a notation name must have only printable characters or spaces, and end "
-#| "with an '='\n"
 msgid "a notation name must have only printable characters or spaces\n"
-msgstr ""
-"symbolické jméno smí obsahovat pouze písmena, číslice, tečky nebo podtržítka "
-"a musí končit znakem „=“\n"
+msgstr "jméno uživatele musí obsahovat pouze tisknutelné znaky nebo mezery\n"
 
 msgid "WARNING: invalid notation data found\n"
 msgstr "VAROVÁNÍ: nalezen neplatný formát zápisu data\n"
@@ -1235,32 +1216,29 @@ msgstr "předání dotazu %s klientovi se nezdařilo\n"
 msgid "Enter passphrase: "
 msgstr "Vložte heslo: "
 
-#, fuzzy, c-format
-#| msgid "error creating keyring '%s': %s\n"
+#, c-format
 msgid "error getting version from '%s': %s\n"
-msgstr "chyba při vytváření souboru klíčů (keyring) „%s“: %s\n"
+msgstr "chyba při získávání verze z „%s“: %s\n"
 
 #, c-format
 msgid "server '%s' is older than us (%s < %s)"
-msgstr ""
+msgstr "server „%s“ je starší než my (%s < %s)"
 
-#, fuzzy, c-format
-#| msgid "WARNING: "
+#, c-format
 msgid "WARNING: %s\n"
-msgstr "VAROVÁNÍ: "
+msgstr "VAROVÁNÍ: %s\n"
 
 msgid "Note: Outdated servers may lack important security fixes.\n"
 msgstr ""
+"Poznámka: Zastaralé servery mohou postrádat důležité bezpečnostní opravy.\n"
 
-#, fuzzy, c-format
-#| msgid "Please use the command \"toggle\" first.\n"
+#, c-format
 msgid "Note: Use the command \"%s\" to restart them.\n"
-msgstr "Prosím, nejdříve použijte příkaz „toggle“ (přepnout).\n"
+msgstr "Poznámka: Restartovat je můžete příkazem „%s“.\n"
 
-#, fuzzy, c-format
-#| msgid "%s does not yet work with %s\n"
+#, c-format
 msgid "%s is not compliant with %s mode\n"
-msgstr "%s dosud není funkční s %s\n"
+msgstr "%s není v souladu s režimem %s\n"
 
 #, c-format
 msgid "OpenPGP card not available: %s\n"
@@ -1271,7 +1249,7 @@ msgid "OpenPGP card no. %s detected\n"
 msgstr "Nalezena OpenPGP karta číslo %s\n"
 
 msgid "can't do this in batch mode\n"
-msgstr "nelze provést v dávkovém módu\n"
+msgstr "nelze provést v dávkovém režimu\n"
 
 msgid "This command is only available for version 2 cards\n"
 msgstr "Tento příkaz je dostupný pouze pro karty verze 2\n"
@@ -1283,7 +1261,7 @@ msgid "Your selection? "
 msgstr "Váš výběr? "
 
 msgid "[not set]"
-msgstr "[není nastaven]"
+msgstr "[není nastaveno]"
 
 msgid "male"
 msgstr "muž"
@@ -1430,7 +1408,7 @@ msgid ""
 "You should change them using the command --change-pin\n"
 msgstr ""
 "Prosím nezapomeňte, že tovární nastavení PINů je\n"
-"   PIN = „%s“     PIN administrátora = „%s“\n"
+"   PIN = „%s“     PIN správce = „%s“\n"
 "Měli byste je změnit příkazem --change-pin\n"
 
 msgid "Please select the type of key to generate:\n"
@@ -1449,7 +1427,7 @@ msgid "Invalid selection.\n"
 msgstr "Neplatný výběr.\n"
 
 msgid "Please select where to store the key:\n"
-msgstr "Prosím vyberte místo pro uchování klíče:\n"
+msgstr "Prosím vyberte, kam uložit klíč:\n"
 
 #, c-format
 msgid "KEYTOCARD failed: %s\n"
@@ -1472,7 +1450,7 @@ msgid "quit this menu"
 msgstr "ukončit toto menu"
 
 msgid "show admin commands"
-msgstr "zobraz administrátorské příkazy"
+msgstr "zobraz příkazy správce"
 
 msgid "show this help"
 msgstr "ukázat tuto pomoc"
@@ -1523,13 +1501,13 @@ msgid "gpg/card> "
 msgstr "gpg/karta> "
 
 msgid "Admin-only command\n"
-msgstr "pouze administrátorské příkazy\n"
+msgstr "pouze příkazy správce\n"
 
 msgid "Admin commands are allowed\n"
-msgstr "administrátorské příkazy jsou povoleny\n"
+msgstr "příkazy správce jsou povoleny\n"
 
 msgid "Admin commands are not allowed\n"
-msgstr "administrátorské příkazy nejsou povoleny\n"
+msgstr "příkazy správce nejsou povoleny\n"
 
 msgid "Invalid command  (try \"help\")\n"
 msgstr "Neplatný příkaz (zkuste „help“)\n"
@@ -1557,7 +1535,7 @@ msgid "(unless you specify the key by fingerprint)\n"
 msgstr "(dokud neurčíte klíč jeho otiskem)\n"
 
 msgid "can't do this in batch mode without \"--yes\"\n"
-msgstr "bez parametru „--yes“ to nemohu v dávkovém módu provést\n"
+msgstr "bez parametru „--yes“ to nelze v dávkovém režimu provést\n"
 
 msgid "Delete this key from the keyring? (y/N) "
 msgstr "Smazat tento klíč ze souboru klíčů? (a/N) "
@@ -1598,7 +1576,7 @@ msgid "error creating passphrase: %s\n"
 msgstr "chyba při vytváření hesla: %s\n"
 
 msgid "can't use a symmetric ESK packet due to the S2K mode\n"
-msgstr "v módu S2K nelze použít symetrický ESK paket\n"
+msgstr "v režimu S2K nelze použít symetrický ESK paket\n"
 
 #, c-format
 msgid "using cipher %s\n"
@@ -1622,15 +1600,13 @@ msgid ""
 msgstr ""
 "VAROVÁNÍ: vyžádaná symetrická šifra %s (%d) nevyhovuje předvolbám příjemce\n"
 
-#, fuzzy, c-format
-#| msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+#, c-format
 msgid "cipher algorithm '%s' may not be used in %s mode\n"
-msgstr "použití šifrovacího algoritmu „%s“ v módu %s není dovoleno\n"
+msgstr "šifrovací algoritmus „%s“ se nesmí používat v režimu %s\n"
 
-#, fuzzy, c-format
-#| msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
+#, c-format
 msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
-msgstr "VAROVÁNÍ: „%s%s“ je zastaralý parametr – neúčinkuje\n"
+msgstr "VAROVÁNÍ: klíč %s není vhodný pro šifrování v režimu %s\n"
 
 #, c-format
 msgid ""
@@ -1648,10 +1624,9 @@ msgstr "vyžádaná symetrická šifra %s (%d) nevyhovuje předvolbám příjemc
 msgid "%s/%s encrypted for: \"%s\"\n"
 msgstr "%s/%s zašifrovaný pro: „%s“\n"
 
-#, fuzzy, c-format
-#| msgid "you may not use %s while in %s mode\n"
+#, c-format
 msgid "option '%s' may not be used in %s mode\n"
-msgstr "použití %s není v módu %s dovoleno\n"
+msgstr "volba „%s“ se nesmí používat v režimu %s\n"
 
 #, c-format
 msgid "%s encrypted data\n"
@@ -1728,7 +1703,7 @@ msgid "remove as much as possible from key during export"
 msgstr "odstranit při exportu z klíče vše, co lze"
 
 msgid "use the GnuPG key backup format"
-msgstr ""
+msgstr "použít záložní formát klíče GnuPG"
 
 msgid " - skipped"
 msgstr " – přeskočeno"
@@ -1763,24 +1738,17 @@ msgstr "[ID uživatele nenalezeno]"
 msgid "(check argument of option '%s')\n"
 msgstr "(zkontrolujte argument volby „%s“)\n"
 
-#, fuzzy, c-format
-#| msgid ""
-#| "Warning: value '%s' for option '%s' should be a long key ID or a "
-#| "fingerprint\n"
+#, c-format
 msgid "Warning: '%s' should be a long key ID or a fingerprint\n"
-msgstr ""
-"Pozor: hodnota „%s“ volby „%s“ by měla být\n"
-"dlouhý identifikátor klíče nebo jeho otisk\n"
+msgstr "Pozor: „%s“ by měl být dlouhý identifikátor klíče nebo jeho otisk\n"
 
-#, fuzzy, c-format
-#| msgid "error closing %s: %s\n"
+#, c-format
 msgid "error looking up: %s\n"
-msgstr "chyba při zavírání chyba %s: %s\n"
+msgstr "chyba při vyhledávání: %s\n"
 
-#, fuzzy, c-format
-#| msgid "error searching the keyring: %s\n"
+#, c-format
 msgid "Warning: %s appears in the keyring %d times\n"
-msgstr "chyba při prohledávání souboru klíčů (keyring): %s\n"
+msgstr "Pozor: %s se nachází v souboru klíčů (keyring) %dkrát\n"
 
 #, c-format
 msgid "automatically retrieved '%s' via %s\n"
@@ -1797,19 +1765,17 @@ msgstr "Chybí otisk"
 msgid "secret key \"%s\" not found: %s\n"
 msgstr "tajný klíč „%s“ nenalezen: %s\n"
 
-#, fuzzy, c-format
-#| msgid "using \"%s\" as default secret key\n"
+#, c-format
 msgid "Warning: not using '%s' as default key: %s\n"
-msgstr "jako výchozí tajný klíč se použije „%s“\n"
+msgstr "Pozor: jako výchozí klíč se nepoužije „%s“: %s\n"
 
-#, fuzzy, c-format
-#| msgid "using \"%s\" as default secret key\n"
+#, c-format
 msgid "using \"%s\" as default secret key for signing\n"
-msgstr "jako výchozí tajný klíč se použije „%s“\n"
+msgstr "jako výchozí tajný klíč pro podepisování se použije „%s“\n"
 
 #, c-format
 msgid "all values passed to '%s' ignored\n"
-msgstr ""
+msgstr "všechny hodnoty předány „%s“ se ignorují\n"
 
 # c-format
 #, c-format
@@ -1820,10 +1786,9 @@ msgstr "Neplatný klíč %s změněn na platný pomocí --always-non-selfsigned-
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "používám podklíč %s místo primárního klíče %s\n"
 
-#, fuzzy, c-format
-#| msgid "invalid argument for option \"%.50s\"\n"
+#, c-format
 msgid "valid values for option '%s':\n"
-msgstr "neplatný argument u volby „%.50s“\n"
+msgstr "platné hodnoty pro volbu „%s“:\n"
 
 msgid "make a signature"
 msgstr "vytvořit podpis"
@@ -1870,15 +1835,11 @@ msgstr "rychle vytvořit nový pár klíčů"
 msgid "quickly add a new user-id"
 msgstr "rychle přidat novou identitu uživatele"
 
-#, fuzzy
-#| msgid "quickly add a new user-id"
 msgid "quickly revoke a user-id"
-msgstr "rychle přidat novou identitu uživatele"
+msgstr "rychle odvolat identitu uživatele"
 
-#, fuzzy
-#| msgid "quickly generate a new key pair"
 msgid "quickly set a new expiration date"
-msgstr "rychle vytvořit nový pár klíčů"
+msgstr "rychle nastavit nové datum konce platnosti"
 
 msgid "full featured key pair generation"
 msgstr "komplexní vytvoření páru klíčů"
@@ -1946,15 +1907,11 @@ msgstr "vypsat hash zprávy"
 msgid "run in server mode"
 msgstr "pracovat v režimu serveru"
 
-#, fuzzy
-#| msgid "|VALUE|set the TOFU policy for a key (good, unknown, bad, ask, auto)"
 msgid "|VALUE|set the TOFU policy for a key"
-msgstr ""
-"|HODNOTA|nastavit TOFU politiku klíči (good [dobrý], unknown [neznámý], bad "
-"[špatný], ask [zeptat se], auto)"
+msgstr "|HODNOTA|nastavit TOFU politiku klíči"
 
 msgid "create ascii armored output"
-msgstr "vytvoř výstup zakódovaný pomocí ASCII"
+msgstr "vytvořit výstup zapsaný v ASCII"
 
 msgid "|USER-ID|encrypt for USER-ID"
 msgstr "|ID_UŽIVATELE|šifrovat pro ID_UŽIVATELE"
@@ -1966,7 +1923,7 @@ msgid "|N|set compress level to N (0 disables)"
 msgstr "|N|nastavit úroveň komprese na N (0 – žádná)"
 
 msgid "use canonical text mode"
-msgstr "použít kanonický textový mód"
+msgstr "použít kanonický textový režim"
 
 msgid "|FILE|write output to FILE"
 msgstr "|SOUBOR|zapsat výstup do SOUBORU"
@@ -1985,18 +1942,8 @@ msgid ""
 "(See the man page for a complete listing of all commands and options)\n"
 msgstr ""
 "@\n"
-"(Pro kompletní seznam všech příkazů a možností použijte manuálové stránky.)\n"
+"(Pro úplný seznam všech příkazů a voleb nahlédněte do manuálové stránky.)\n"
 
-#, fuzzy
-#| msgid ""
-#| "@\n"
-#| "Examples:\n"
-#| "\n"
-#| " -se -r Bob [file]          sign and encrypt for user Bob\n"
-#| " --clear-sign [file]         make a clear text signature\n"
-#| " --detach-sign [file]       make a detached signature\n"
-#| " --list-keys [names]        show keys\n"
-#| " --fingerprint [names]      show fingerprints\n"
 msgid ""
 "@\n"
 "Examples:\n"
@@ -2008,11 +1955,13 @@ msgid ""
 " --fingerprint [names]      show fingerprints\n"
 msgstr ""
 "@\n"
+"Příklady:\n"
+"\n"
 " -se -r Bob [soubor]        podepsat a zašifrovat pro uživatele Bob\n"
-" --clear-sign [soubor]       vytvořit podpis čitelného dokumentu\n"
+" --clearsign [soubor]       vytvořit podpis čitelného dokumentu\n"
 " --detach-sign [soubor]     vytvořit podpis oddělený od dokumentu\n"
-" --list-keys [jména]        vypsat klíče\n"
-" --fingerprint [jména]      vypsat otisky\n"
+" --list-keys [jména]        ukázat klíče\n"
+" --fingerprint [jména]      ukázat otisky\n"
 
 msgid "Usage: @GPG@ [options] [files] (-h for help)"
 msgstr "Použití: @GPG@ [možnosti] [soubory] (-h pro nápovědu)"
@@ -2182,10 +2131,9 @@ msgstr "Poznámka: %s není pro normální použití!\n"
 msgid "'%s' is not a valid signature expiration\n"
 msgstr "„%s“ není platná doba expirace podpisu\n"
 
-#, fuzzy, c-format
-#| msgid "line %d: not a valid email address\n"
+#, c-format
 msgid "\"%s\" is not a proper mail address\n"
-msgstr "řádek %d: neplatná e-mailová adresa\n"
+msgstr "„%s“ není správná e-mailová adresa\n"
 
 #, c-format
 msgid "invalid pinentry mode '%s'\n"
@@ -2212,10 +2160,9 @@ msgstr "%s:%d: neplatný parametr pro import\n"
 msgid "invalid import options\n"
 msgstr "neplatný parametr pro import\n"
 
-#, fuzzy, c-format
-#| msgid "invalid list options\n"
+#, c-format
 msgid "invalid filter option: %s\n"
-msgstr "neplatný parametr pro výpis\n"
+msgstr "neplatná volba filtru: %s\n"
 
 #, c-format
 msgid "%s:%d: invalid export options\n"
@@ -2333,10 +2280,10 @@ msgstr ""
 "nebo 3\n"
 
 msgid "Note: simple S2K mode (0) is strongly discouraged\n"
-msgstr "Poznámka: jednoduchý mód S2K (0) je důrazně nedoporučován\n"
+msgstr "Poznámka: jednoduchý režim S2K (0) je důrazně nedoporučován\n"
 
 msgid "invalid S2K mode; must be 0, 1 or 3\n"
-msgstr "neplatný mód S2K; musí být 0, 1 nebo 3\n"
+msgstr "neplatný režim S2K; musí být 0, 1 nebo 3\n"
 
 msgid "invalid default preferences\n"
 msgstr "neplatné implicitní předvolby\n"
@@ -2354,15 +2301,13 @@ msgstr "neplatné uživatelské předvolby pro komprimaci\n"
 msgid "%s does not yet work with %s\n"
 msgstr "%s dosud není funkční s %s\n"
 
-#, fuzzy, c-format
-#| msgid "you may not use digest algorithm '%s' while in %s mode\n"
+#, c-format
 msgid "digest algorithm '%s' may not be used in %s mode\n"
-msgstr "použití hashovacího algoritmu „%s“ v módu %s není dovoleno\n"
+msgstr "hashovací algoritmus „%s“ se nesmí používat v režimu %s\n"
 
-#, fuzzy, c-format
-#| msgid "you may not use compression algorithm '%s' while in %s mode\n"
+#, c-format
 msgid "compression algorithm '%s' may not be used in %s mode\n"
-msgstr "použití kompresního algoritmu „%s“ v módu %s není dovoleno\n"
+msgstr "kompresní algoritmus „%s“ se nesmí používat v režimu %s\n"
 
 #, c-format
 msgid "failed to initialize the TrustDB: %s\n"
@@ -2379,18 +2324,16 @@ msgstr "symetrické šifrování „%s“ se nepovedlo: %s\n"
 msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
 msgstr "nelze použít --symmetric --encrypt s příkazem --s2k-mode 0\n"
 
-#, fuzzy, c-format
-#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, c-format
 msgid "you cannot use --symmetric --encrypt in %s mode\n"
-msgstr "nelze použít --symmetric --encrypt v módu %s\n"
+msgstr "nelze použít --symmetric --encrypt v režimu %s\n"
 
 msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
 msgstr "nelze použít --symmetric --sign --encrypt s příkazem --s2k-mode 0\n"
 
-#, fuzzy, c-format
-#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, c-format
 msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
-msgstr "nelze použít --symmetric --sign --encrypt v módu %s\n"
+msgstr "nelze použít --symmetric --sign --encrypt v režimu %s\n"
 
 #, c-format
 msgid "keyserver send failed: %s\n"
@@ -2404,10 +2347,9 @@ msgstr "získání dat z serveru klíčů se nezdařilo: %s\n"
 msgid "key export failed: %s\n"
 msgstr "export klíče se nepodařil: %s\n"
 
-#, fuzzy, c-format
-#| msgid "key export failed: %s\n"
+#, c-format
 msgid "export as ssh key failed: %s\n"
-msgstr "export klíče se nepodařil: %s\n"
+msgstr "export jako SSH klíč se nepodařil: %s\n"
 
 #, c-format
 msgid "keyserver search failed: %s\n"
@@ -2438,7 +2380,7 @@ msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n"
 msgstr "„%s“ nevypadá jako platné ID klíče, otisk klíče nebo keygrip\n"
 
 msgid "WARNING: no command supplied.  Trying to guess what you mean ...\n"
-msgstr ""
+msgstr "POZOR: nezadán žádný příkaz. Váš záměr bude odhadnut…\n"
 
 msgid "Go ahead and type your message ...\n"
 msgstr "Začněte psát svou zprávu…\n"
@@ -2462,7 +2404,7 @@ msgid "|FD|write status info to this FD"
 msgstr "|FD|zapsat informace o stavu do tohoto FD"
 
 msgid "|ALGO|reject signatures made with ALGO"
-msgstr ""
+msgstr "|ALGORITMUS|zamítnout podpisy založené na ALGORITMU"
 
 msgid "Usage: gpgv [options] [files] (-h for help)"
 msgstr "Použití: gpg [volby] [soubory] (-h pro pomoc)"
@@ -2493,10 +2435,8 @@ msgstr "nemazat údaje o důvěře během importu"
 msgid "do not update the trustdb after import"
 msgstr "neaktualizovat databázi důvěry po importu"
 
-#, fuzzy
-#| msgid "show key fingerprint"
 msgid "show key during import"
-msgstr "vypsat otisk klíče"
+msgstr "při importu ukázat klíč"
 
 msgid "only accept updates to existing keys"
 msgstr "přijímat aktualizace pouze u existujících klíčů"
@@ -2508,17 +2448,13 @@ msgid "remove as much as possible from key after import"
 msgstr "odstranit po importu z klíče vše, co lze"
 
 msgid "run import filters and export key immediately"
-msgstr ""
+msgstr "spustit importní filtry a exportovat klíč okamžitě"
 
-#, fuzzy
-#| msgid "assume input is in binary format"
 msgid "assume the GnuPG key backup format"
-msgstr "předpokládat vstup v binárním formátu"
+msgstr "předpokládat vstup ve formátu zálohy klíčů GnuPG"
 
-#, fuzzy
-#| msgid "show key fingerprint"
 msgid "repair keys on import"
-msgstr "vypsat otisk klíče"
+msgstr "při importu opravit klíče"
 
 #, c-format
 msgid "skipping block of type %d\n"
@@ -2810,15 +2746,15 @@ msgstr "klíč %s: smazána vícenásobná vazba podklíče\n"
 
 #, c-format
 msgid "key %s: no subkey for key revocation\n"
-msgstr "klíč %s: neexistuje podklíč pro revokaci klíče\n"
+msgstr "klíč %s: neexistuje podklíč pro odvolání klíče\n"
 
 #, c-format
 msgid "key %s: invalid subkey revocation\n"
-msgstr "klíč %s: neplatný revokační podklíč\n"
+msgstr "klíč %s: neplatný odvolací podklíč\n"
 
 #, c-format
 msgid "key %s: removed multiple subkey revocation\n"
-msgstr "klíč %s: smazána vícenásobná revokace podklíče\n"
+msgstr "klíč %s: vícenásobná odvolání podklíče smazáno\n"
 
 #, c-format
 msgid "key %s: skipped user ID \"%s\"\n"
@@ -2854,12 +2790,11 @@ msgstr "klíč %s: objeven duplikovaný identifikátor uživatele - sloučen\n"
 
 #, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
-msgstr ""
-"VAROVÁNÍ: klíč %s může být revokován: zkouším získat revokační klíč %s\n"
+msgstr "VAROVÁNÍ: klíč %s může být odvolán: zkouším získat revokační klíč %s\n"
 
 #, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
-msgstr "VAROVÁNÍ: klíč %s může být revokován: revokační klíč %s nenalezen.\n"
+msgstr "VAROVÁNÍ: klíč %s může být odvolán: revokační klíč %s nenalezen.\n"
 
 #, c-format
 msgid "key %s: \"%s\" revocation certificate added\n"
@@ -2898,7 +2833,7 @@ msgid "failed to rebuild keyring cache: %s\n"
 msgstr "selhalo obnovení vyrovnávací paměti klíčů: %s\n"
 
 msgid "[revocation]"
-msgstr "[revokace]"
+msgstr "[odvolání]"
 
 msgid "[self-signature]"
 msgstr "[podpis klíče jím samým]"
@@ -2942,7 +2877,7 @@ msgstr "Přeskakuje se ID uživatele „%s“, což není textové ID.\n"
 
 #, c-format
 msgid "User ID \"%s\" is revoked."
-msgstr "Uživatelské ID „%s“ je revokováno."
+msgstr "Uživatelské ID „%s“ je odvoláno."
 
 msgid "Are you sure you still want to sign it? (y/N) "
 msgstr "Jste si jistý(á), že stále chcete podepsat tento klíč? (a/N) "
@@ -3238,7 +3173,7 @@ msgstr ""
 "  podpis (nrsign) nebo libovolnou jejich kombinací (ltsign, tnrsign, atd.).\n"
 
 msgid "Key is revoked."
-msgstr "Klíč revokován."
+msgstr "Klíč je odvolán."
 
 msgid "Really sign all user IDs? (y/N) "
 msgstr "Opravdu podepsat všechny id uživatele? (a/N) "
@@ -3255,7 +3190,7 @@ msgstr "Neznámý typ podpisu „%s“\n"
 
 #, c-format
 msgid "This command is not allowed while in %s mode.\n"
-msgstr "Tento příkaz není v módů %s dovolený.\n"
+msgstr "Tento příkaz není v režimu %s dovolen.\n"
 
 msgid "You must select at least one user ID.\n"
 msgstr "Musíte vybrat alespoň jeden id uživatele.\n"
@@ -3302,19 +3237,19 @@ msgid "Do you really want to delete this key? (y/N) "
 msgstr "Opravdu chcete smazat tento klíč? (a/N) "
 
 msgid "Really revoke all selected user IDs? (y/N) "
-msgstr "Opravdu revokovat všechny vybrané id uživatele? (a/N) "
+msgstr "Opravdu odvolat všechna vybraná ID uživatele? (a/N) "
 
 msgid "Really revoke this user ID? (y/N) "
-msgstr "Opravdu revokovat tento id uživatele? (a/N) "
+msgstr "Opravdu odvolat toto ID uživatele? (a/N) "
 
 msgid "Do you really want to revoke the entire key? (y/N) "
-msgstr "Opravdu chcete revokovat celý klíč? (a/N) "
+msgstr "Opravdu chcete odvolat celý klíč? (a/N) "
 
 msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgstr "Opravdu chcete revokovat vybrané podklíče? (a/N) "
+msgstr "Opravdu chcete odvolat vybrané podklíče? (a/N) "
 
 msgid "Do you really want to revoke this subkey? (y/N) "
-msgstr "Opravdu chcete revokovat tento podklíč? (a/N) "
+msgstr "Opravdu chcete odvolat tento podklíč? (a/N) "
 
 msgid "Owner trust may not be set while using a user provided trust database\n"
 msgstr ""
@@ -3343,20 +3278,16 @@ msgstr "aktualizace selhala: %s\n"
 msgid "Key not changed so no update needed.\n"
 msgstr "Klíč nebyl změněn, takže není potřeba jej aktualizovat.\n"
 
-#, fuzzy
-#| msgid "You can't delete the last user ID!\n"
 msgid "cannot revoke the last valid user ID.\n"
-msgstr "Nemůžete smazat poslední id uživatele!\n"
+msgstr "poslední platné ID uživatele nelze odvolat.\n"
 
-#, fuzzy, c-format
-#| msgid "checking the trust list failed: %s\n"
+#, c-format
 msgid "revoking the user ID failed: %s\n"
-msgstr "kontrola seznamu důvěry se nepodařila: %s\n"
+msgstr "odvolání ID uživatele se nepodařilo: %s\n"
 
-#, fuzzy, c-format
-#| msgid "checking the trust list failed: %s\n"
+#, c-format
 msgid "setting the primary user ID failed: %s\n"
-msgstr "kontrola seznamu důvěry se nepodařila: %s\n"
+msgstr "nastavení primárního ID uživatele se nepodařilo: %s\n"
 
 #, c-format
 msgid "\"%s\" is not a fingerprint\n"
@@ -3366,10 +3297,9 @@ msgstr "„%s“ není otisk\n"
 msgid "\"%s\" is not the primary fingerprint\n"
 msgstr "„%s“ není primární otisk\n"
 
-#, fuzzy, c-format
-#| msgid "read error in '%s': %s\n"
+#, c-format
 msgid "Invalid user ID '%s': %s\n"
-msgstr "chyba při čtení v „%s“: %s\n"
+msgstr "Neplatné ID uživatele „%s“: %s\n"
 
 msgid "No matching user IDs."
 msgstr "Žádný identifikátor uživatele neodpovídá."
@@ -3377,20 +3307,17 @@ msgstr "Žádný identifikátor uživatele neodpovídá."
 msgid "Nothing to sign.\n"
 msgstr "Nic na podepsání.\n"
 
-#, fuzzy, c-format
-#| msgid "'%s' is not a valid signature expiration\n"
+#, c-format
 msgid "'%s' is not a valid expiration time\n"
-msgstr "„%s“ není platná doba expirace podpisu\n"
+msgstr "„%s“ není platná doba expirace\n"
 
-#, fuzzy, c-format
-#| msgid "\"%s\" is not a fingerprint\n"
+#, c-format
 msgid "\"%s\" is not a proper fingerprint\n"
-msgstr "„%s“ není otisk\n"
+msgstr "„%s“ není řádný otisk\n"
 
-#, fuzzy, c-format
-#| msgid "key \"%s\" not found\n"
+#, c-format
 msgid "subkey \"%s\" not found\n"
-msgstr "klíč „%s“ nenalezen\n"
+msgstr "podklíč „%s“ nenalezen\n"
 
 msgid "Digest: "
 msgstr "Hash: "
@@ -3412,11 +3339,11 @@ msgstr "Uživatelský ID formátu PGP 2.x nemá žádné předvolby\n"
 
 #, c-format
 msgid "The following key was revoked on %s by %s key %s\n"
-msgstr "V %s byl následující klíč revokován %s klíčem %s\n"
+msgstr "V %s byl následující klíč odvolán %s klíčem %s\n"
 
 #, c-format
 msgid "This key may be revoked by %s key %s"
-msgstr "Tento klíč může být revokován %s klíčem %s "
+msgstr "Tento klíč může být odvolán %s klíčem %s "
 
 msgid "(sensitive)"
 msgstr "(citlivá informace)"
@@ -3427,7 +3354,7 @@ msgstr "vytvořen: %s"
 
 #, c-format
 msgid "revoked: %s"
-msgstr "revokován: %s"
+msgstr "odvolán: %s"
 
 #, c-format
 msgid "expired: %s"
@@ -3511,13 +3438,12 @@ msgstr "Smazat tento neznámý podpis? (a/N/u)"
 msgid "Really delete this self-signature? (y/N)"
 msgstr "Opravdu smazat tento podpis podepsaný sebou samým? (a/N)"
 
-#, fuzzy, c-format
-#| msgid "Deleted %d signature.\n"
+#, c-format
 msgid "Deleted %d signature.\n"
 msgid_plural "Deleted %d signatures.\n"
 msgstr[0] "Smazán %d podpis.\n"
-msgstr[1] "Smazán %d podpis.\n"
-msgstr[2] "Smazán %d podpis.\n"
+msgstr[1] "Smazány %d podpisy.\n"
+msgstr[2] "Smazáno %d podpisů.\n"
 
 msgid "Nothing deleted.\n"
 msgstr "Nic nebylo smazáno.\n"
@@ -3529,13 +3455,12 @@ msgstr "neplatný"
 msgid "User ID \"%s\" compacted: %s\n"
 msgstr "Uživatelské ID „%s“ směstnáno: %s\n"
 
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
+#, c-format
 msgid "User ID \"%s\": %d signature removed\n"
 msgid_plural "User ID \"%s\": %d signatures removed\n"
-msgstr[0] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
-msgstr[1] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
-msgstr[2] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
+msgstr[0] "Uživatelské ID „%s“: odstraněn %d podpis\n"
+msgstr[1] "Uživatelské ID „%s“: odstraněny %d podpisy\n"
+msgstr[2] "Uživatelské ID „%s“: odstraněno %d podpisů\n"
 
 #, c-format
 msgid "User ID \"%s\": already minimized\n"
@@ -3550,31 +3475,31 @@ msgid ""
 "cause\n"
 "         some versions of PGP to reject this key.\n"
 msgstr ""
-"VAROVÁNÍ: Toto je PGP2 klíč. Přidání 'pověření revokace' může v některých\n"
+"VAROVÁNÍ: Toto je PGP2 klíč. Přidání pověřeého odvolatele může v některých\n"
 "          verzích PGP vést k odmítnutí tohoto klíče.\n"
 
 msgid "You may not add a designated revoker to a PGP 2.x-style key.\n"
-msgstr "Neměli by jste přidávat 'pověření revokace' k PGP2 klíči.\n"
+msgstr "K PGP2 klíči byste neměli přidávat pověřeného odvolatele.\n"
 
 msgid "Enter the user ID of the designated revoker: "
-msgstr "Vložte identifikátor uživatele pověřeného revokací: "
+msgstr "Vložte identifikátor pověřeného odvolatele: "
 
 msgid "cannot appoint a PGP 2.x style key as a designated revoker\n"
-msgstr "klíč formátu PGP 2.x nelze pověřit revokací\n"
+msgstr "klíč formátu PGP 2.x nelze pověřit odvoláním\n"
 
 msgid "you cannot appoint a key as its own designated revoker\n"
-msgstr "klíč nelze pověřit revokací jím samým\n"
+msgstr "klíč nelze pověřit odvoláním sama sebe\n"
 
 msgid "this key has already been designated as a revoker\n"
-msgstr "tento klíč již byl pověřen revokací\n"
+msgstr "tento klíč již byl určen jako odvolatel\n"
 
 msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n"
 msgstr ""
-"VAROVÁNÍ: ustanovení klíče „pověřeným odvolatelem“ je nevratná operace!\n"
+"VAROVÁNÍ: ustanovení klíče pověřeným odvolatelem je nevratná operace!\n"
 
 msgid ""
 "Are you sure you want to appoint this key as a designated revoker? (y/N) "
-msgstr "Jste si jistí, že tento klíč chcete pověřit revokací? (a/N) "
+msgstr "Jste si jistí, že tento klíč chcete pověřit odvoláním? (a/N) "
 
 msgid ""
 "Are you sure you want to change the expiration time for multiple subkeys? (y/"
@@ -3652,10 +3577,10 @@ msgid "This signature expired on %s.\n"
 msgstr "Platnost podpisu vyprší %s.\n"
 
 msgid "Are you sure you still want to revoke it? (y/N) "
-msgstr "Jste si jistý, že jej chcete stále revokovat? (a/N) "
+msgstr "Jste si jisti, že jej chcete stále odvolat? (a/N) "
 
 msgid "Create a revocation certificate for this signature? (y/N) "
-msgstr "Vytvořit pro tento podpis revokační certifikát? (a/N)"
+msgstr "Vytvořit pro tento podpis odvolací certifikát? (a/N)"
 
 msgid "Not signed by you.\n"
 msgstr "Nepodepsáno vámi.\n"
@@ -3669,50 +3594,47 @@ msgstr " (neodvolatelné)"
 
 #, c-format
 msgid "revoked by your key %s on %s\n"
-msgstr "revokováno vaším klíčem %s v %s\n"
+msgstr "odvoláno vaším klíčem %s v %s\n"
 
 msgid "You are about to revoke these signatures:\n"
-msgstr "Chystáte se revokovat tyto podpisy:\n"
+msgstr "Chystáte se odvolat tyto podpisy:\n"
 
 msgid "Really create the revocation certificates? (y/N) "
-msgstr "Opravdu vytvořit revokační certifikáty? (a/N) "
+msgstr "Opravdu vytvořit odvolací certifikáty? (a/N) "
 
 msgid "no secret key\n"
 msgstr "neexistuje tajný klíč\n"
 
 #, c-format
 msgid "tried to revoke a non-user ID: %s\n"
-msgstr ""
+msgstr "pokud odvolat ID neuživatele: %s\n"
 
 #, c-format
 msgid "user ID \"%s\" is already revoked\n"
-msgstr "uživatelské ID „%s“ je již revokováno\n"
+msgstr "uživatelské ID „%s“ je již odvoláno\n"
 
 #, c-format
 msgid "WARNING: a user ID signature is dated %d seconds in the future\n"
 msgstr "VAROVÁNÍ: podpis ID uživatele je datován %d sekund v budoucnosti\n"
 
-#, fuzzy
-#| msgid "You can't delete the last user ID!\n"
 msgid "Cannot revoke the last valid user ID.\n"
-msgstr "Nemůžete smazat poslední id uživatele!\n"
+msgstr "Poslední platné ID uživatele nelze odvolat.\n"
 
 #, c-format
 msgid "Key %s is already revoked.\n"
-msgstr "Klíč %s je již revokován.\n"
+msgstr "Klíč %s je již odvolán.\n"
 
 #, c-format
 msgid "Subkey %s is already revoked.\n"
-msgstr "Podklíč %s je již revokován.\n"
+msgstr "Podklíč %s je již odvolán.\n"
 
 #, c-format
 msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "Zobrazuji %s fotografický ID o velikosti %ld pro klíč %s (uid %d)\n"
 
-#, fuzzy, c-format
-#| msgid "invalid argument for option \"%.50s\"\n"
+#, c-format
 msgid "invalid value for option '%s'\n"
-msgstr "neplatný argument u volby „%.50s“\n"
+msgstr "neplatný argument u volby „%s“\n"
 
 #, c-format
 msgid "preference '%s' duplicated\n"
@@ -3920,7 +3842,7 @@ msgstr ""
 "      <n>y = doba platnosti podpisu skončí za n let\n"
 
 msgid "Key is valid for? (0) "
-msgstr "Klíč je platný pro? (0) "
+msgstr "Klíč je platný po? (0) "
 
 #, c-format
 msgid "Signature is valid for? (%s) "
@@ -4178,45 +4100,40 @@ msgstr "Kritická podepisovací notace: "
 msgid "Signature notation: "
 msgstr "Podepisovací notace: "
 
-#, fuzzy, c-format
-#| msgid "%d good signatures\n"
+#, c-format
 msgid "%d good signature\n"
 msgid_plural "%d good signatures\n"
-msgstr[0] "%d dobrých podpisů\n"
-msgstr[1] "%d dobrých podpisů\n"
+msgstr[0] "%d dobrý podpis\n"
+msgstr[1] "%d dobré podpisy\n"
 msgstr[2] "%d dobrých podpisů\n"
 
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
+#, c-format
 msgid "%d bad signature\n"
 msgid_plural "%d bad signatures\n"
-msgstr[0] "%d špatných podpisů\n"
-msgstr[1] "%d Å¡patných podpisů\n"
+msgstr[0] "%d špatný podpis\n"
+msgstr[1] "%d Å¡patné podpisy\n"
 msgstr[2] "%d špatných podpisů\n"
 
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
+#, c-format
 msgid "%d signature not checked due to a missing key\n"
 msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 podpis neověřen, protože chybí klíč\n"
-msgstr[1] "1 podpis neověřen, protože chybí klíč\n"
-msgstr[2] "1 podpis neověřen, protože chybí klíč\n"
+msgstr[0] "%d podpis neověřen, protože chybí klíč\n"
+msgstr[1] "%d podpisy neověřeny, protože chybí klíče\n"
+msgstr[2] "%d podpisů neověřeno, protože chybí klíče\n"
 
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to an error\n"
+#, c-format
 msgid "%d signature not checked due to an error\n"
 msgid_plural "%d signatures not checked due to errors\n"
-msgstr[0] "1 podpis neověřen, protože vznikla chyba\n"
-msgstr[1] "1 podpis neověřen, protože vznikla chyba\n"
-msgstr[2] "1 podpis neověřen, protože vznikla chyba\n"
+msgstr[0] "%d podpis neověřen, protože došlo k chybě\n"
+msgstr[1] "%d podpisy neověřeny, protože došlo k chybám\n"
+msgstr[2] "%d podpisů neověřeno, protože došlo k chybám\n"
 
-#, fuzzy, c-format
-#| msgid "Warning: %lu key(s) skipped due to their large size\n"
+#, c-format
 msgid "Warning: %lu key skipped due to its large size\n"
 msgid_plural "Warning: %lu keys skipped due to their large sizes\n"
-msgstr[0] "Pozor: %lu klíč(ů) přeskočen(o) kvůli jejich přílišné velikosti\n"
-msgstr[1] "Pozor: %lu klíč(ů) přeskočen(o) kvůli jejich přílišné velikosti\n"
-msgstr[2] "Pozor: %lu klíč(ů) přeskočen(o) kvůli jejich přílišné velikosti\n"
+msgstr[0] "Pozor: %lu klíč přeskočen kvůli jeho přílišné velikosti\n"
+msgstr[1] "Pozor: %lu klíče přeskočeny kvůli jejich přílišné velikosti\n"
+msgstr[2] "Pozor: %lu klíčů přeskočeno kvůli jejich přílišné velikosti\n"
 
 msgid "Keyring"
 msgstr "Soubor klíčů (keyring)"
@@ -4245,29 +4162,26 @@ msgstr "  Sériové číslo karty ="
 msgid "caching keyring '%s'\n"
 msgstr "zapamatovává se soubor klíčů „%s“\n"
 
-#, fuzzy, c-format
-#| msgid "%lu keys cached so far (%lu signatures)\n"
+#, c-format
 msgid "%lu keys cached so far (%lu signature)\n"
 msgid_plural "%lu keys cached so far (%lu signatures)\n"
-msgstr[0] "%lu klíčů již uloženo v keši (%lu podpisů)\n"
-msgstr[1] "%lu klíčů již uloženo v keši (%lu podpisů)\n"
+msgstr[0] "%lu klíčů již uloženo v keši (%lu podpis)\n"
+msgstr[1] "%lu klíčů již uloženo v keši (%lu podpisy)\n"
 msgstr[2] "%lu klíčů již uloženo v keši (%lu podpisů)\n"
 
-#, fuzzy, c-format
-#| msgid "flush the cache"
+#, c-format
 msgid "%lu key cached"
 msgid_plural "%lu keys cached"
-msgstr[0] "vyprázdní keš"
-msgstr[1] "vyprázdní keš"
-msgstr[2] "vyprázdní keš"
+msgstr[0] "%lu klíč uložen v keši"
+msgstr[1] "%lu klíče uloženy v keši"
+msgstr[2] "%lu klíčů uloženo v keši"
 
-#, fuzzy, c-format
-#| msgid "1 bad signature\n"
+#, c-format
 msgid " (%lu signature)\n"
 msgid_plural " (%lu signatures)\n"
-msgstr[0] "1 špatný podpis\n"
-msgstr[1] "1 špatný podpis\n"
-msgstr[2] "1 špatný podpis\n"
+msgstr[0] " (%lu podpis)\n"
+msgstr[1] " (%lu podpisy)\n"
+msgstr[2] " (%lu podpisů)\n"
 
 #, c-format
 msgid "%s: keyring created\n"
@@ -4308,13 +4222,12 @@ msgstr "neplatný protokol serveru klíčů (naše %d!=obsluha %d)\n"
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "„%s“ není ID klíče: přeskočeno\n"
 
-#, fuzzy, c-format
-#| msgid "refreshing %d keys from %s\n"
+#, c-format
 msgid "refreshing %d key from %s\n"
 msgid_plural "refreshing %d keys from %s\n"
-msgstr[0] "aktualizuji %d klíčů z %s\n"
-msgstr[1] "aktualizuji %d klíčů z %s\n"
-msgstr[2] "aktualizuji %d klíčů z %s\n"
+msgstr[0] "aktualizuje se %d klíč z %s\n"
+msgstr[1] "aktualizují se %d klíče z %s\n"
+msgstr[2] "aktualizuje se %d klíčů z %s\n"
 
 #, c-format
 msgid "WARNING: unable to refresh key %s via %s: %s\n"
@@ -4332,16 +4245,14 @@ msgstr "žádný server klíčů není znám (použijte volbu --keyserver)\n"
 
 #, c-format
 msgid "requesting key %s from %s server %s\n"
-msgstr "požaduji klíč %s ze %s server %s\n"
+msgstr "požaduji klíč %s z %s serveru %s\n"
 
 #, c-format
 msgid "requesting key %s from %s\n"
 msgstr "požaduji klíč %s z %s\n"
 
-#, fuzzy
-#| msgid "no keyserver action!\n"
 msgid "no keyserver known\n"
-msgstr "žádná operace se serverem klíčů!\n"
+msgstr "není znám žádný server s klíči\n"
 
 #, c-format
 msgid "skipped \"%s\": %s\n"
@@ -4476,10 +4387,9 @@ msgstr "               použití %s klíče %s\n"
 msgid "Signature made %s using %s key ID %s\n"
 msgstr "Podpis vytvořen %s pomocí klíče %s s ID uživatele %s\n"
 
-#, fuzzy, c-format
-#| msgid "                aka \"%s\""
+#, c-format
 msgid "               issuer \"%s\"\n"
-msgstr "                alias „%s“"
+msgstr "               vydavatel „%s“\n"
 
 msgid "Key available at: "
 msgstr "Klíč k dispozici na: "
@@ -4491,10 +4401,9 @@ msgstr "[nejistý]"
 msgid "                aka \"%s\""
 msgstr "                alias „%s“"
 
-#, fuzzy, c-format
-#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+#, c-format
 msgid "WARNING: This key is not suitable for signing in %s mode\n"
-msgstr "VAROVÁNÍ: Tento klíč není certifikován důvěryhodným podpisem!\n"
+msgstr "POZOR: Tento klíč se nehodí na podepisování v režimu %s\n"
 
 #, c-format
 msgid "Signature expired %s\n"
@@ -4573,18 +4482,16 @@ msgstr "VAROVÁNÍ: vyžádaný algoritmus %s není doporučen\n"
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Poznámka: podpisy používající algoritmus %s jsou zamítány\n"
 
-#, fuzzy, c-format
-#| msgid "%s:%u: read error: %s\n"
+#, c-format
 msgid "(reported error: %s)\n"
-msgstr "%s:%u: chyba čtení: %s\n"
+msgstr "(nahlášená chyba: %s)\n"
 
-#, fuzzy, c-format
-#| msgid "read error in '%s': %s\n"
+#, c-format
 msgid "(reported error: %s <%s>)\n"
-msgstr "chyba při čtení v „%s“: %s\n"
+msgstr "(nahlášená chyba: %s <%s>)\n"
 
 msgid "(further info: "
-msgstr ""
+msgstr "(podrobnosti: "
 
 #, c-format
 msgid "%s:%d: deprecated option \"%s\"\n"
@@ -4851,25 +4758,18 @@ msgstr "Tento klíč pravděpodobně náleží uvedenému uživateli\n"
 msgid "This key belongs to us\n"
 msgstr "Tento klíč náleží nám (máme odpovídající tajný klíč)\n"
 
-#, fuzzy, c-format
-#| msgid "root certificate has now been marked as trusted\n"
+#, c-format
 msgid "%s: This key is bad!  It has been marked as untrusted!\n"
-msgstr "kořenový certifikát byl nyní označen za důvěryhodný\n"
+msgstr "%s: Tento klíč je špatný! Byl označen jako nedůvěryhodný!\n"
 
-#, fuzzy
-#| msgid ""
-#| "It is NOT certain that the key belongs to the person named\n"
-#| "in the user ID.  If you *really* know what you are doing,\n"
-#| "you may answer the next question with yes.\n"
 msgid ""
 "This key is bad!  It has been marked as untrusted!  If you\n"
 "*really* know what you are doing, you may answer the next\n"
 "question with yes.\n"
 msgstr ""
-"NENÍ jisté, zda tento klíč patří osobě, jejíž jméno je uvedeno\n"
-"v uživatelském ID. Pokud *skutečně* víte, co děláte, můžete na\n"
-"následující otázku odpovědět ano\n"
-"\n"
+"Tento klíč je špatný! Byl označen jako nedůvěryhodný!\n"
+"Pokud *skutečně* víte, co děláte, můžete na\n"
+"následující otázku odpovědět ano.\n"
 
 msgid ""
 "It is NOT certain that the key belongs to the person named\n"
@@ -4878,8 +4778,7 @@ msgid ""
 msgstr ""
 "NENÍ jisté, zda tento klíč patří osobě, jejíž jméno je uvedeno\n"
 "v uživatelském ID. Pokud *skutečně* víte, co děláte, můžete na\n"
-"následující otázku odpovědět ano\n"
-"\n"
+"následující otázku odpovědět ano.\n"
 
 msgid "Use this key anyway? (y/N) "
 msgstr "Použít přesto tento klíč? (a/N) "
@@ -4956,10 +4855,9 @@ msgstr "%s: přeskočeno: veřejný klíč je neplatný (disabled)\n"
 msgid "%s: skipped: public key already present\n"
 msgstr "%s: přeskočeno: veřejný klíč je již obsažen v databázi\n"
 
-#, fuzzy, c-format
-#| msgid "can't connect to '%s': %s\n"
+#, c-format
 msgid "can't encrypt to '%s'\n"
-msgstr "nelze se připojit k „%s“: %s\n"
+msgstr "nelze zašifrovat pro „%s“\n"
 
 #, c-format
 msgid "option '%s' given, but no valid default keys given\n"
@@ -4970,8 +4868,7 @@ msgid "option '%s' given, but option '%s' not given\n"
 msgstr "zadána volba „%s“, ale chybí volba „%s“\n"
 
 msgid "You did not specify a user ID. (you may use \"-r\")\n"
-msgstr ""
-"Nespecifikoval jste identifikátor uživatele (user ID). Můžete použít \"-r\"\n"
+msgstr "Nezadali jste identifikátor uživatele (můžete použít \"-r\")\n"
 
 msgid "Current recipients:\n"
 msgstr "Aktuální příjemci:\n"
@@ -5034,17 +4931,16 @@ msgstr "nelze otevřít podepsaná data „%s“\n"
 msgid "can't open signed data fd=%d: %s\n"
 msgstr "nelze otevřít podepsaná data na deskriptoru=%d: %s\n"
 
-#, fuzzy, c-format
-#| msgid "certificate is not usable for encryption\n"
+#, c-format
 msgid "key %s is not suitable for decryption in %s mode\n"
-msgstr "certifikát není použitelný pro šifrování\n"
+msgstr "klíč %s se nehodí na rozšifrování v režimu %s\n"
 
 #, c-format
 msgid "anonymous recipient; trying secret key %s ...\n"
-msgstr "anonymní adresát; zkouším tajný klíč %s…\n"
+msgstr "anonymní adresát; zkusí se tajný klíč %s…\n"
 
 msgid "okay, we are the anonymous recipient.\n"
-msgstr "o.k., my jsme anonymní adresát.\n"
+msgstr "dobrá, my jsme anonymní adresát.\n"
 
 msgid "old encoding of the DEK is not supported\n"
 msgstr "staré kódování DEK není podporováno\n"
@@ -5106,13 +5002,10 @@ msgid ""
 "declare that a key shall not anymore be used.  It is not possible\n"
 "to retract such a revocation certificate once it has been published."
 msgstr ""
+"Odovolací certifikát je svým způsoben „bezpečnostní vypínač“, který\n"
+"veřejně prohlašuje, že klíč by se již neměl používat. Jednou zveřejněný\n"
+"odvolací certifikát již nelze vzít zpět."
 
-#, fuzzy
-#| msgid ""
-#| "Use it to revoke this key in case of a compromise or loss of\n"
-#| "the secret key.  However, if the secret key is still accessible,\n"
-#| "it is better to generate a new revocation certificate and give\n"
-#| "a reason for the revocation."
 msgid ""
 "Use it to revoke this key in case of a compromise or loss of\n"
 "the secret key.  However, if the secret key is still accessible,\n"
@@ -5122,26 +5015,24 @@ msgid ""
 msgstr ""
 "Použijte jej pro odvolání tohoto klíče v případě zneužití nebo ztráty\n"
 "soukromého klíče. Avšak bude-li soukromý klíč stále přístupný, bude\n"
-"lepší vytvořit nový revokační certifikát s vysvětlením odvolání."
+"lepší vytvořit nový odvolací certifikát s odůvodněním odvolání.\n"
+"Podrobnosti naleznete v manuálu GnuPG u popisu příkazu\n"
+"„gpg --generate-revocation“."
 
-#, fuzzy
-#| msgid ""
-#| "To avoid an accidental use of this file, a colon has been inserted\n"
-#| "before the 5 dashes below.  Remove this colon with a text editor\n"
-#| "before making use of this revocation certificate."
 msgid ""
 "To avoid an accidental use of this file, a colon has been inserted\n"
 "before the 5 dashes below.  Remove this colon with a text editor\n"
 "before importing and publishing this revocation certificate."
 msgstr ""
-"Aby se zabránilo nechtěnému použití tohoto souboru, před 5 pomlček byla\n"
-"vložena dvojtečka. Před použitím tohoto revokačního certifikátu odstraňte\n"
-"tuto dvojtečku textovým editorem."
+"Aby se zabránilo nechtěnému použití tohoto souboru, níže před 5 pomlček "
+"byla\n"
+"vložena dvojtečka. Před importem a zveřejněním tohoto odvolacího "
+"certifikátu\n"
+"odstraňte tuto dvojtečku textovým editorem."
 
-#, fuzzy, c-format
-#| msgid "Revocation certificate created.\n"
+#, c-format
 msgid "revocation certificate stored as '%s.rev'\n"
-msgstr "Revokační certifikát vytvořen.\n"
+msgstr "odvolací certifikát uložen jako „%s.rev“\n"
 
 #, c-format
 msgid "secret key \"%s\" not found\n"
@@ -5222,10 +5113,9 @@ msgstr "%s klíč %s vyžaduje hash o délce %zu nebo více bitů (hash je %s)\
 msgid "WARNING: signature digest conflict in message\n"
 msgstr "VAROVÁNÍ: konflikt hashe podpisu ve zprávě\n"
 
-#, fuzzy, c-format
-#| msgid "you may not use %s while in %s mode\n"
+#, c-format
 msgid "key %s may not be used for signing in %s mode\n"
-msgstr "použití %s není v módu %s dovoleno\n"
+msgstr "klíč %s se nesmí používat v režimu %s\n"
 
 #, c-format
 msgid "WARNING: signing subkey %s is not cross-certified\n"
@@ -5239,54 +5129,48 @@ msgstr "více informací naleznete na adrese %s\n"
 msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
 msgstr "VAROVÁNÍ: podepisovací podklíč %s má neplatnou křížovou certifikaci\n"
 
-#, fuzzy, c-format
-#| msgid "public key %s is %lu second newer than the signature\n"
+#, c-format
 msgid "public key %s is %lu second newer than the signature\n"
 msgid_plural "public key %s is %lu seconds newer than the signature\n"
-msgstr[0] "veřejný klíč %s je o %lu sekund novější než podpis\n"
-msgstr[1] "veřejný klíč %s je o %lu sekund novější než podpis\n"
+msgstr[0] "veřejný klíč %s je o %lu sekundu novější než podpis\n"
+msgstr[1] "veřejný klíč %s je o %lu sekundy novější než podpis\n"
 msgstr[2] "veřejný klíč %s je o %lu sekund novější než podpis\n"
 
-#, fuzzy, c-format
-#| msgid "public key %s is %lu second newer than the signature\n"
+#, c-format
 msgid "public key %s is %lu day newer than the signature\n"
 msgid_plural "public key %s is %lu days newer than the signature\n"
-msgstr[0] "veřejný klíč %s je o %lu sekund novější než podpis\n"
-msgstr[1] "veřejný klíč %s je o %lu sekund novější než podpis\n"
-msgstr[2] "veřejný klíč %s je o %lu sekund novější než podpis\n"
+msgstr[0] "veřejný klíč %s je o %lu den novější než podpis\n"
+msgstr[1] "veřejný klíč %s je o %lu dny novější než podpis\n"
+msgstr[2] "veřejný klíč %s je o %lu dnů novější než podpis\n"
 
-#, fuzzy, c-format
-#| msgid ""
-#| "key %s was created %lu second in the future (time warp or clock problem)\n"
+#, c-format
 msgid ""
 "key %s was created %lu second in the future (time warp or clock problem)\n"
 msgid_plural ""
 "key %s was created %lu seconds in the future (time warp or clock problem)\n"
 msgstr[0] ""
-"klíč %s byl vytvořen %lu sekund v budoucnosti (došlo ke změně času nebo\n"
-"je problém se systémovým časem)\n"
+"klíč %s byl vytvořen %lu sekundu v budoucnosti (došlo ke změně času nebo\n"
+"je problém s hodinami)\n"
 msgstr[1] ""
-"klíč %s byl vytvořen %lu sekund v budoucnosti (došlo ke změně času nebo\n"
-"je problém se systémovým časem)\n"
+"klíč %s byl vytvořen %lu sekundy v budoucnosti (došlo ke změně času nebo\n"
+"je problém s hodinami)\n"
 msgstr[2] ""
 "klíč %s byl vytvořen %lu sekund v budoucnosti (došlo ke změně času nebo\n"
-"je problém se systémovým časem)\n"
+"je problém s hodinami)\n"
 
-#, fuzzy, c-format
-#| msgid ""
-#| "key %s was created %lu second in the future (time warp or clock problem)\n"
+#, c-format
 msgid "key %s was created %lu day in the future (time warp or clock problem)\n"
 msgid_plural ""
 "key %s was created %lu days in the future (time warp or clock problem)\n"
 msgstr[0] ""
-"klíč %s byl vytvořen %lu sekund v budoucnosti (došlo ke změně času nebo\n"
-"je problém se systémovým časem)\n"
+"klíč %s byl vytvořen %lu den v budoucnosti (došlo ke změně času nebo\n"
+"je problém s hodinami)\n"
 msgstr[1] ""
-"klíč %s byl vytvořen %lu sekund v budoucnosti (došlo ke změně času nebo\n"
-"je problém se systémovým časem)\n"
+"klíč %s byl vytvořen %lu dny v budoucnosti (došlo ke změně času nebo\n"
+"je problém s hodinami)\n"
 msgstr[2] ""
-"klíč %s byl vytvořen %lu sekund v budoucnosti (došlo ke změně času nebo\n"
-"je problém se systémovým časem)\n"
+"klíč %s byl vytvořen %lu dnů v budoucnosti (došlo ke změně času nebo\n"
+"je problém s hodinami)\n"
 
 #, c-format
 msgid "Note: signature key %s expired %s\n"
@@ -5515,339 +5399,320 @@ msgstr "nemohu pracovat s řádky delšími než %d znaků\n"
 msgid "input line longer than %d characters\n"
 msgstr "vstupní řádek je delší než %d znaků\n"
 
-#, fuzzy, c-format
-#| msgid "error sending standard options: %s\n"
+#, c-format
 msgid "error beginning transaction on TOFU database: %s\n"
-msgstr "chyba při odesílání standardního parametru: %s\n"
+msgstr "chyba při zahájení transakce v databázi TOFU: %s\n"
 
 #, c-format
 msgid "error committing transaction on TOFU database: %s\n"
-msgstr ""
+msgstr "chyba při potvrzování transakce v datázi TOFU: %s\n"
 
 #, c-format
 msgid "error rolling back transaction on TOFU database: %s\n"
-msgstr ""
+msgstr "chyba při odvolávání transakce v databázi TOFU: %s\n"
 
-#, fuzzy, c-format
-#| msgid "unsupported algorithm: %s"
+#, c-format
 msgid "unsupported TOFU database version: %s\n"
-msgstr "nepodporovaný algoritmus: %s"
+msgstr "nepodporovaná verze databáze TOFU: %s\n"
 
-#, fuzzy, c-format
-#| msgid "error creating temporary file: %s\n"
+#, c-format
 msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n"
-msgstr "chyba při vytváření dočasného souboru: %s\n"
+msgstr "chyba při vytváření TOFU tabulky „ultimately_trusted_keys“: %s\n"
 
 msgid "TOFU DB error"
-msgstr ""
+msgstr "Chyba databáze TOFU"
 
-#, fuzzy, c-format
-#| msgid "error sending data: %s\n"
+#, c-format
 msgid "error reading TOFU database: %s\n"
-msgstr "chyba při odesílání dat: %s\n"
+msgstr "chyba při čtení databáze TOFU: %s\n"
 
-#, fuzzy, c-format
-#| msgid "error writing base64 encoding: %s\n"
+#, c-format
 msgid "error determining TOFU database's version: %s\n"
-msgstr "chyba při zápisu kódování base64: %s\n"
+msgstr "chyba při zjišťování databáze TOFU: %s\n"
 
-#, fuzzy, c-format
-#| msgid "error initializing reader object: %s\n"
+#, c-format
 msgid "error initializing TOFU database: %s\n"
-msgstr "chyba při inicializaci čtecího objektu: %s\n"
+msgstr "chyba při inicializaci databáze TOFU: %s\n"
 
-#, fuzzy, c-format
-#| msgid "error sending data: %s\n"
+#, c-format
 msgid "error creating 'encryptions' TOFU table: %s\n"
-msgstr "chyba při odesílání dat: %s\n"
+msgstr "chyba při vytváření TOFU tabulky „encryptions“: %s\n"
 
+# ??? Typo: error adding
 #, c-format
 msgid "adding column effective_policy to bindings DB: %s\n"
-msgstr ""
+msgstr "přidávání sloupce effective_policy do vazeb databáze: %s\n"
 
-#, fuzzy, c-format
-#| msgid "error opening '%s': %s\n"
+#, c-format
 msgid "error opening TOFU database '%s': %s\n"
-msgstr "chyba při otevírání „%s“: %s\n"
+msgstr "chyba při otevírání databáze TOFU „%s“: %s\n"
 
-#, fuzzy, c-format
-#| msgid "error sending data: %s\n"
+#, c-format
 msgid "error updating TOFU database: %s\n"
-msgstr "chyba při odesílání dat: %s\n"
+msgstr "chyba při aktualizaci databáze TOFU: %s\n"
 
 #, c-format
 msgid ""
 "This is the first time the email address \"%s\" is being used with key %s."
-msgstr ""
+msgstr "Toto je poprvé, co se e-mailová adresa „%s“ používá s klíčem %s."
 
 #, c-format
 msgid "The email address \"%s\" is associated with %d key!"
 msgid_plural "The email address \"%s\" is associated with %d keys!"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "E-mailová adresa „%s“ je přidružena k %d klíči!"
+msgstr[1] "E-mailová adresa „%s“ je přidružena k %d klíčům!"
+msgstr[2] "E-mailová adresa „%s“ je přidružena k %d klíčům!"
 
 msgid "  Since this binding's policy was 'auto', it has been changed to 'ask'."
 msgstr ""
+"  Protože pravidlo této vazby bylo „auto“, bylo změněno na „ask“ (zeptat se)."
 
 #, c-format
 msgid ""
 "Please indicate whether this email address should be associated with key %s "
 "or whether you think someone is impersonating \"%s\"."
 msgstr ""
+"Prosím naznačte, jestli tato e-mailová adresa má být spojována s klíčem %s "
+"nebo jestli si mylíste, že někdo se vydává za „%s“\n"
+"."
 
-#, fuzzy, c-format
-#| msgid "error getting responder ID: %s\n"
+#, c-format
 msgid "error gathering other user IDs: %s\n"
-msgstr "chyba při zjišťování ID odpovídače: %s\n"
+msgstr "chyba při sběru dalších ID uživetele: %s\n"
 
-#, fuzzy
-#| msgid "list key and user IDs"
 msgid "This key's user IDs:\n"
-msgstr "vypsat seznam klíčů a id uživatelů"
+msgstr "ID uživatelů tohoto klíče:\n"
 
-#, fuzzy, c-format
-#| msgid "validity: %s"
+#, c-format
 msgid "policy: %s"
-msgstr "platnost: %s"
+msgstr "politika: %s"
 
-#, fuzzy, c-format
-#| msgid "error getting stored flags: %s\n"
+#, c-format
 msgid "error gathering signature stats: %s\n"
-msgstr "chyba při získání uložených příznaků: %s\n"
+msgstr "chyba při sběru údajů o podpisech: %s\n"
 
 #, c-format
 msgid "The email address \"%s\" is associated with %d key:\n"
 msgid_plural "The email address \"%s\" is associated with %d keys:\n"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "E-mailová adresa „%s“ je spojena s %d klíčem:\n"
+msgstr[1] "E-mailová adresa „%s“ je spojena s %d klíči:\n"
+msgstr[2] "E-mailová adresa „%s“ je spojena s %d klíči:\n"
 
 #, c-format
 msgid "Statistics for keys with the email address \"%s\":\n"
-msgstr ""
+msgstr "Statistika pro klíče s e-mailovou adresou „%s“:\n"
 
-#, fuzzy
-#| msgid "list keys"
 msgid "this key"
-msgstr "vypsat seznam klíčů"
+msgstr "tento klíč"
 
-#, fuzzy, c-format
-#| msgid "print message digests"
+#, c-format
 msgid "Verified %d message."
 msgid_plural "Verified %d messages."
-msgstr[0] "vypsat hash zprávy"
-msgstr[1] "vypsat hash zprávy"
-msgstr[2] "vypsat hash zprávy"
+msgstr[0] "%d zpráva ověřena."
+msgstr[1] "%d zprávy ověřeny."
+msgstr[2] "%d zpráv ověřeno."
 
-#, fuzzy, c-format
-#| msgid "encrypted with %lu passphrases\n"
+#, c-format
 msgid "Encrypted %d message."
 msgid_plural "Encrypted %d messages."
-msgstr[0] "zašifrováno s heslem %lu\n"
-msgstr[1] "zašifrováno s heslem %lu\n"
-msgstr[2] "zašifrováno s heslem %lu\n"
+msgstr[0] "%d zpráva zašifrována."
+msgstr[1] "%d zprávy zašifrovýny."
+msgstr[2] "%d zpráv zašifrováno."
 
-#, fuzzy, c-format
-#| msgid "print message digests"
+#, c-format
 msgid "Verified %d message in the future."
 msgid_plural "Verified %d messages in the future."
-msgstr[0] "vypsat hash zprávy"
-msgstr[1] "vypsat hash zprávy"
-msgstr[2] "vypsat hash zprávy"
+msgstr[0] "Ověřena %d zpráva v budoucnosti."
+msgstr[1] "Ověřeny %d zprávy v budoucnosti."
+msgstr[2] "Ověřeno %d zpráv v budoucnosti."
 
-#, fuzzy, c-format
-#| msgid "print message digests"
+#, c-format
 msgid "Encrypted %d message in the future."
 msgid_plural "Encrypted %d messages in the future."
-msgstr[0] "vypsat hash zprávy"
-msgstr[1] "vypsat hash zprávy"
-msgstr[2] "vypsat hash zprávy"
+msgstr[0] "Zašifrována %d zpráva v budoucnosti."
+msgstr[1] "Zašifrovány %d zprávy v budoucnosti."
+msgstr[2] "Zašifrováno %d zpráv v budoucnosti."
 
 #, c-format
 msgid "Messages verified over the past %d day: %d."
 msgid_plural "Messages verified over the past %d days: %d."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Ověřeno zpráv za poslední %d den: %d."
+msgstr[1] "Ověřeno zpráv za poslední %d dny: %d."
+msgstr[2] "Ověřeno zpráv za posledních %d dnů: %d."
 
 #, c-format
 msgid "Messages encrypted over the past %d day: %d."
 msgid_plural "Messages encrypted over the past %d days: %d."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Zašifrováno zpráv za poslední %d den: %d."
+msgstr[1] "Zašifrováno zpráv za poslední %d dny: %d."
+msgstr[2] "Zašifrováno zpráv za posledních %d dnů: %d."
 
 #, c-format
 msgid "Messages verified over the past %d month: %d."
 msgid_plural "Messages verified over the past %d months: %d."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Ověřeno zpráv za poslední %d měsíc: %d."
+msgstr[1] "Ověřeno zpráv za poslední %d měsíce: %d."
+msgstr[2] "Ověřeno zpráv za posledních %d měsíců: %d."
 
 #, c-format
 msgid "Messages encrypted over the past %d month: %d."
 msgid_plural "Messages encrypted over the past %d months: %d."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Zašifrováno zpráv za poslední %d měsíc: %d."
+msgstr[1] "Zašifrováno zpráv za poslední %d měsíce: %d."
+msgstr[2] "Zašifrováno zpráv za posledních %d měsíců: %d."
 
 #, c-format
 msgid "Messages verified over the past %d year: %d."
 msgid_plural "Messages verified over the past %d years: %d."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Zpráv ověřeno za poslední %d rok: %d."
+msgstr[1] "Zpráv ověřeno za poslední %d roky: %d."
+msgstr[2] "Zpráv ověřeno za posledních %d roků: %d."
 
 #, c-format
 msgid "Messages encrypted over the past %d year: %d."
 msgid_plural "Messages encrypted over the past %d years: %d."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Ověřeno zpráv za poslední %d rok: %d."
+msgstr[1] "Ověřeno zpráv za poslední %d roky: %d."
+msgstr[2] "Ověřeno zpráv za posledních %d roků: %d."
 
 #, c-format
 msgid "Messages verified in the past: %d."
-msgstr ""
+msgstr "Zpráv ověřeno v minulosti: %d."
 
-#, fuzzy, c-format
-#| msgid "print message digests"
+#, c-format
 msgid "Messages encrypted in the past: %d."
-msgstr "vypsat hash zprávy"
+msgstr "Zpráv zašifrovno v minulosti: %d."
 
 #. TRANSLATORS: Please translate the text found in the source
 #. * file below.  We don't directly internationalize that text so
 #. * that we can tweak it without breaking translations.
 msgid "TOFU detected a binding conflict"
-msgstr ""
+msgstr "TOFU objevilo konflikt ve vazbě"
 
 #. TRANSLATORS: Two letters (normally the lower and upper case
 #. * version of the hotkey) for each of the five choices.  If
 #. * there is only one choice in your language, repeat it.
 msgid "gGaAuUrRbB"
-msgstr ""
+msgstr "gGaAuUrRbB"
 
 msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
-msgstr ""
+msgstr "(D)obrý, (P)řijmout jednou, (N)eznámý, (O)dmítnout jednou, špa(T)ný? "
 
 msgid "Defaulting to unknown.\n"
-msgstr ""
+msgstr "Použíje se výchozí volba neznýmý.\n"
 
 msgid "TOFU db corruption detected.\n"
-msgstr ""
+msgstr "Zjistěno poškození databýze TOFU.\n"
 
-#, fuzzy, c-format
-#| msgid "error writing key: %s\n"
+#, c-format
 msgid "resetting keydb: %s\n"
-msgstr "chyba při zápisu klíče: %s\n"
+msgstr "databáze klíčů se resetuje: %s\n"
 
-#, fuzzy, c-format
-#| msgid "error setting OCSP target: %s\n"
+#, c-format
 msgid "error setting TOFU binding's policy to %s\n"
-msgstr "chyba při nastavování cíle OCSP: %s\n"
+msgstr "chyba při nastavování politiky vazby TOFU na %s\n"
 
-#, fuzzy, c-format
-#| msgid "error creating a pipe: %s\n"
+#, c-format
 msgid "error changing TOFU policy: %s\n"
-msgstr "chyba při vytváření roury: %s\n"
+msgstr "chyba při měnění politiky TOFU: %s\n"
 
+# These strings are used as an argument in "Verified 2 signatures in past %s."
 #, c-format
 msgid "%lld~year"
 msgid_plural "%lld~years"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%lld~roku"
+msgstr[1] "%lld~roků"
+msgstr[2] "%lld~roků"
 
 #, c-format
 msgid "%lld~month"
 msgid_plural "%lld~months"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%lld~měsíce"
+msgstr[1] "%lld~měsíců"
+msgstr[2] "%lld~měsíců"
 
 #, c-format
 msgid "%lld~week"
 msgid_plural "%lld~weeks"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%lld~týdne"
+msgstr[1] "%lld~týdnů"
+msgstr[2] "%lld~týdnů"
 
 #, c-format
 msgid "%lld~day"
 msgid_plural "%lld~days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%lld~dne"
+msgstr[1] "%lld~dnů"
+msgstr[2] "%lld~dnů"
 
 #, c-format
 msgid "%lld~hour"
 msgid_plural "%lld~hours"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%lld~hodiny"
+msgstr[1] "%lld~hodin"
+msgstr[2] "%lld~hodin"
 
 #, c-format
 msgid "%lld~minute"
 msgid_plural "%lld~minutes"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%lld~minuty"
+msgstr[1] "%lld~minut"
+msgstr[2] "%lld~minut"
 
 #, c-format
 msgid "%lld~second"
 msgid_plural "%lld~seconds"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%lld~sekundy"
+msgstr[1] "%lld~sekund"
+msgstr[2] "%lld~sekund"
 
 #, c-format
 msgid "%s: Verified 0~signatures and encrypted 0~messages."
-msgstr ""
+msgstr "%s: Ověřeno 0~podpisů a zašifrováno 0~zpráv."
 
-#, fuzzy, c-format
-#| msgid "Deleted %d signatures.\n"
+#, c-format
 msgid "%s: Verified 0 signatures."
-msgstr "Smazáno %d podpisů.\n"
+msgstr "%s: Ověřeno 0 podpisů."
 
-#, fuzzy, c-format
-#| msgid "print message digests"
+# The final %s is replaced by a string like "7~months".
+#, c-format
 msgid "%s: Verified %ld~signature in the past %s."
 msgid_plural "%s: Verified %ld~signatures in the past %s."
-msgstr[0] "vypsat hash zprávy"
-msgstr[1] "vypsat hash zprávy"
-msgstr[2] "vypsat hash zprávy"
+msgstr[0] "%s: Ověřen %ld~podpis za poslední období %s."
+msgstr[1] "%s: Ověřeny %ld~podpisy za poslední období %s."
+msgstr[2] "%s: Ověřeno %ld~podpisů za poslední období %s."
 
-#, fuzzy
-#| msgid "encrypted with %lu passphrases\n"
 msgid "Encrypted 0 messages."
-msgstr "zašifrováno s heslem %lu\n"
+msgstr "Zašifrováno 0 zpráv."
 
-#, fuzzy, c-format
-#| msgid "print message digests"
+#, c-format
 msgid "Encrypted %ld~message in the past %s."
 msgid_plural "Encrypted %ld~messages in the past %s."
-msgstr[0] "vypsat hash zprávy"
-msgstr[1] "vypsat hash zprávy"
-msgstr[2] "vypsat hash zprávy"
+msgstr[0] "Zašifrována %ld~zpráva za poslední období %s."
+msgstr[1] "Zašifrovány %ld~zprávy za poslední období %s."
+msgstr[2] "Zašifrováno %ld~zpráv za poslední období %s."
 
-#, fuzzy, c-format
-#| msgid "validity: %s"
+#, c-format
 msgid "(policy: %s)"
-msgstr "platnost: %s"
+msgstr "(politika: %s)"
 
 msgid ""
 "Warning: we have yet to see a message signed using this key and user id!\n"
 msgstr ""
+"Pozor: ještě musíme vidět zprávu podepsanou tímto klíčem a idenitou "
+"uživatele!\n"
 
 msgid ""
 "Warning: we've only seen one message signed using this key and user id!\n"
 msgstr ""
+"Pozor: viděli jsme pouze jednu zprávu podepsanou tímto klíčem a idenitou\n"
+"uživatele!\n"
 
 msgid "Warning: you have yet to encrypt a message to this key!\n"
-msgstr ""
+msgstr "Pozor: ješte je třeba zašifrovat zprávu tímto klíčem!\n"
 
 msgid "Warning: you have only encrypted one message to this key!\n"
-msgstr ""
+msgstr "Pozor: tímto klíčem jste zašifrovali pouze jednu zprávu!\n"
 
 #, c-format
 msgid ""
@@ -5863,22 +5728,37 @@ msgid_plural ""
 "  %s\n"
 "to mark it as being bad.\n"
 msgstr[0] ""
+"Pozor: Pokud si myslíte, že jste viděli více podpisů tímto klíčem a "
+"identitou uživatele, pak tento klíč může být podvrh! Pečlivě prozkoumejte e-"
+"mailovou adresu. Jestliže je klíč podezřelý, použijte příkaz\n"
+"  %s\n"
+"k označení, že je špatný.\n"
 msgstr[1] ""
+"Pozor: Pokud si myslíte, že jste viděli více podpisů tímto klíčem a s těmito "
+"identitami uživatele, pak tento klíč může být podvrh! Pečlivě prozkoumejte e-"
+"mailové adresy. Jestliže je klíč podezřelý, použijte příkaz\n"
+"  %s\n"
+"k označení, že je špatný.\n"
 msgstr[2] ""
+"Pozor: Pokud si myslíte, že jste viděli více podpisů tímto klíčem a s těmito "
+"identitami uživatele, pak tento klíč může být podvrh! Pečlivě prozkoumejte e-"
+"mailové adresy. Jestliže je klíč podezřelý, použijte příkaz\n"
+"  %s\n"
+"k označení, že je špatný.\n"
 
-#, fuzzy, c-format
-#| msgid "error sending data: %s\n"
+#, c-format
 msgid "error opening TOFU database: %s\n"
-msgstr "chyba při odesílání dat: %s\n"
+msgstr "chyba při otevírání databáze TOFU: %s\n"
 
 #, c-format
 msgid "WARNING: Encrypting to %s, which has no non-revoked user ids\n"
 msgstr ""
+"POZOR: Šifruje se pro %s, kterýžto nemá neodvolané identity uživatele\n"
 
-#, fuzzy, c-format
-#| msgid "error writing public keyring '%s': %s\n"
+#, c-format
 msgid "error setting policy for key %s, user id \"%s\": %s"
-msgstr "chyba při zápisu do souboru veřejných klíčů „%s“: %s\n"
+msgstr ""
+"chyba při nastavování politiky pro klíč %s a identitu uživatele „%s“: %s"
 
 #, c-format
 msgid "'%s' is not a valid long keyID\n"
@@ -5948,21 +5828,19 @@ msgstr "prosím proveďte --check-trustdb\n"
 msgid "checking the trustdb\n"
 msgstr "kontroluji databázi důvěry\n"
 
-#, fuzzy, c-format
-#| msgid "%lu keys processed so far\n"
+#, c-format
 msgid "%d key processed"
 msgid_plural "%d keys processed"
-msgstr[0] "%lu klíče byly doposud zpracovány\n"
-msgstr[1] "%lu klíče byly doposud zpracovány\n"
-msgstr[2] "%lu klíče byly doposud zpracovány\n"
+msgstr[0] "zpracován %d klíč"
+msgstr[1] "zpracovány %d klíče"
+msgstr[2] "zpracováno %d klíčů"
 
-#, fuzzy, c-format
-#| msgid "%d keys processed (%d validity counts cleared)\n"
+#, c-format
 msgid " (%d validity count cleared)\n"
 msgid_plural " (%d validity counts cleared)\n"
-msgstr[0] "zpracováno %d klíčů (%d validit vymazáno)\n"
-msgstr[1] "zpracováno %d klíčů (%d validit vymazáno)\n"
-msgstr[2] "zpracováno %d klíčů (%d validit vymazáno)\n"
+msgstr[0] " (vymazáno %d počítadlo platnosti)\n"
+msgstr[1] " (vymazána %d počítadla platnosti)\n"
+msgstr[2] " (vymazáno %d počítadel platnosti)\n"
 
 msgid "no ultimately trusted keys found\n"
 msgstr "žádný absolutně důvěryhodný klíč nebyl nalezen\n"
@@ -6021,10 +5899,8 @@ msgstr "[  neznámá   ]"
 msgid "[  undef ]"
 msgstr "[nedefinovaná]"
 
-#, fuzzy
-#| msgid "never"
 msgid "[  never ]"
-msgstr "žádná"
+msgstr "[   nikdy    ]"
 
 msgid "[marginal]"
 msgstr "[  částečná  ]"
@@ -6135,15 +6011,13 @@ msgid "error retrieving CHV status from card\n"
 msgstr "chyba při získání CHV z karty\n"
 
 msgid "response does not contain the RSA modulus\n"
-msgstr "odpověď neobsahuje RSA modulus\n"
+msgstr "odpověď neobsahuje modulus RSA\n"
 
 msgid "response does not contain the RSA public exponent\n"
-msgstr "odpověď neobsahuje veřejný RSA exponent\n"
+msgstr "odpověď neobsahuje veřejný exponent RSA\n"
 
-#, fuzzy
-#| msgid "response does not contain the EC public point\n"
 msgid "response does not contain the EC public key\n"
-msgstr "odpověď neobsahuje veřejný bod EC\n"
+msgstr "odpověď neobsahuje veřejný klíč EC\n"
 
 msgid "response does not contain the public key data\n"
 msgstr "odpověď neobsahuje veřejný klíč\n"
@@ -6157,32 +6031,29 @@ msgstr "čtení veřejného klíče se nezdařilo: %s\n"
 #. * the %s at the start and end of the string.
 #, c-format
 msgid "%sNumber\1f: %s%%0AHolder\1f: %s%%0ACounter\1f: %lu%s"
-msgstr ""
+msgstr "%sČíslo\1f: %s%%0ADržitel\1f: %s%%0APočítadlo\1f: %lu%s"
 
 #, c-format
 msgid "%sNumber\1f: %s%%0AHolder\1f: %s%s"
-msgstr ""
+msgstr "%sČíslo\1f: %s%%0ADržitel\1f: %s%s"
 
 #. TRANSLATORS: This is the number of remaining attempts to
 #. * enter a PIN.  Use %%0A (double-percent,0A) for a linefeed.
 #, c-format
 msgid "Remaining attempts: %d"
-msgstr ""
+msgstr "Zbývá pokusů: %d"
 
 #, c-format
 msgid "using default PIN as %s\n"
-msgstr "používám implicitní PIN jako %s\n"
+msgstr "použije se výchozí PIN jako %s\n"
 
 #, c-format
 msgid "failed to use default PIN as %s: %s - disabling further default use\n"
 msgstr ""
-"použití implicitního PINu jako %s selhalo: %s – vypínám jeho budoucí "
-"použití\n"
+"použití výchozího PINu jako %s selhalo: %s – vypínám jeho budoucí použití\n"
 
-#, fuzzy
-#| msgid "||Please enter the PIN"
 msgid "||Please unlock the card"
-msgstr "||Prosím vložte PIN"
+msgstr "||Prosím, odemkněte kartu"
 
 #, c-format
 msgid "PIN for CHV%d is too short; minimum length is %d\n"
@@ -6195,17 +6066,16 @@ msgstr "ověření CHV%d se nezdařilo: %s\n"
 msgid "card is permanently locked!\n"
 msgstr "karta je trvale uzamčena!\n"
 
-#, fuzzy, c-format
-#| msgid "%d Admin PIN attempts remaining before card is permanently locked\n"
+#, c-format
 msgid "%d Admin PIN attempt remaining before card is permanently locked\n"
 msgid_plural ""
 "%d Admin PIN attempts remaining before card is permanently locked\n"
 msgstr[0] ""
-"Do trvalého uzamčení karty zůstává %d pokusů o zadání PINu administrátora\n"
+"Do trvalého uzamčení karty zůstává %d pokus na zadání PINu správce\n"
 msgstr[1] ""
-"Do trvalého uzamčení karty zůstává %d pokusů o zadání PINu administrátora\n"
+"Do trvalého uzamčení karty zůstávají %d pokusy na zadání PINu správce\n"
 msgstr[2] ""
-"Do trvalého uzamčení karty zůstává %d pokusů o zadání PINu administrátora\n"
+"Do trvalého uzamčení karty zůstává %d pokusů na zadání PINu správce\n"
 
 #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at
 #. the start of the string.  Use %0A (single percent) for a linefeed.
@@ -6213,7 +6083,7 @@ msgid "|A|Please enter the Admin PIN"
 msgstr "|A|Prosím, zadejte PIN správce"
 
 msgid "access to admin commands is not configured\n"
-msgstr "přístup k administrátorským příkazům není nakonfigurován\n"
+msgstr "přístup k příkazům správce není nakonfigurován\n"
 
 msgid "||Please enter the PIN"
 msgstr "||Prosím vložte PIN"
@@ -6281,12 +6151,11 @@ msgstr "prosím počkejte než bude klíč vygenerován…\n"
 msgid "generating key failed\n"
 msgstr "generování klíče se nezdařilo\n"
 
-#, fuzzy, c-format
-#| msgid "key generation completed (%d seconds)\n"
+#, c-format
 msgid "key generation completed (%d second)\n"
 msgid_plural "key generation completed (%d seconds)\n"
-msgstr[0] "generování klíče dokončeno (%d sekund)\n"
-msgstr[1] "generování klíče dokončeno (%d sekund)\n"
+msgstr[0] "generování klíče dokončeno (%d sekunda)\n"
+msgstr[1] "generování klíče dokončeno (%d sekundy)\n"
 msgstr[2] "generování klíče dokončeno (%d sekund)\n"
 
 msgid "invalid structure of OpenPGP card (DO 0x93)\n"
@@ -7149,10 +7018,9 @@ msgid "    runtime cached certificates: %u\n"
 msgstr "za běhu nakešovaných certifikátů: %u\n"
 
 # XXX: Align with msgid "permanently loaded certificates:"
-#, fuzzy, c-format
-#| msgid "    runtime cached certificates: %u\n"
+#, c-format
 msgid "           trusted certificates: %u (%u,%u,%u,%u)\n"
-msgstr "za běhu nakešovaných certifikátů: %u\n"
+msgstr "       důvěryhodných certifikátů: %u (%u,%u,%u,%u)\n"
 
 msgid "certificate already cached\n"
 msgstr "certifikát již v keši\n"
@@ -7736,7 +7604,7 @@ msgid "allow sending OCSP requests"
 msgstr "povolí odesílání OCSP dotazů"
 
 msgid "allow online software version check"
-msgstr ""
+msgstr "povolí kontrolu verze softwaru po síti"
 
 msgid "inhibit the use of HTTP"
 msgstr "zakáže použití HTTP"
@@ -8371,7 +8239,7 @@ msgid "Options enforcing a passphrase policy"
 msgstr "Volby vynucující politiku hesel"
 
 msgid "do not allow bypassing the passphrase policy"
-msgstr "nedovolit obejít politiku hesel"
+msgstr "nedovolit obejití politiky hesel"
 
 msgid "|N|set minimal required length for new passphrases to N"
 msgstr "|N|nastavit minimální vyžadovanou délku nových hesel na N"
@@ -8388,10 +8256,8 @@ msgstr "|N|omezit platnost hesla na N dnů"
 msgid "do not allow the reuse of old passphrases"
 msgstr "nedovolit opakovat stará hesla"
 
-#, fuzzy
-#| msgid "|N|set LDAP timeout to N seconds"
 msgid "|N|set the Pinentry timeout to N seconds"
-msgstr "|N|nastaví časový limit pro LDAP na N sekund"
+msgstr "|N|nastavit časový limit pro Pinentry na N sekund"
 
 msgid "|NAME|use NAME as default secret key"
 msgstr "|NÁZEV|použít NÁZEV jako implicitní tajný klíč"
@@ -8447,33 +8313,23 @@ msgstr "Seznam LDAP serverů"
 msgid "Configuration for OCSP"
 msgstr "Nastavení OCSP"
 
-#, fuzzy
-#| msgid "GPG for OpenPGP"
 msgid "OpenPGP"
-msgstr "GPG pro OpenPGP"
+msgstr "OpenPGP"
 
 msgid "Private Keys"
-msgstr ""
+msgstr "Soukromé klíče"
 
-#, fuzzy
-#| msgid "Smartcard Daemon"
 msgid "Smartcards"
-msgstr "Démon pro čipové karty"
+msgstr "Čipové karty"
 
-#, fuzzy
-#| msgid "GPG for S/MIME"
 msgid "S/MIME"
-msgstr "GPG pro S/MIME"
+msgstr "S/MIME"
 
-#, fuzzy
-#| msgid "network error"
 msgid "Network"
-msgstr "chyba sítě"
+msgstr "Síť"
 
-#, fuzzy
-#| msgid "PIN and Passphrase Entry"
 msgid "Passphrase Entry"
-msgstr "Zadávání kódu PIN a hesla"
+msgstr "Pole pro heslo"
 
 msgid "Component not suitable for launching"
 msgstr "Komponenta není vhodná pro spuštění"
@@ -8485,15 +8341,13 @@ msgstr "Selhalo externí ověření komponenty %s"
 msgid "Note that group specifications are ignored\n"
 msgstr "Vezměte na vědomí, že určení skupiny se ignoruje\n"
 
-#, fuzzy, c-format
-#| msgid "error closing '%s': %s\n"
+#, c-format
 msgid "error closing '%s'\n"
-msgstr "chyba při uzavírání „%s“: %s\n"
+msgstr "chyba při uzavírání „%s“\n"
 
-#, fuzzy, c-format
-#| msgid "error hashing '%s': %s\n"
+#, c-format
 msgid "error parsing '%s'\n"
-msgstr "chyba při výpočtu haše „%s“: %s\n"
+msgstr "chyba při rozboru „%s“\n"
 
 msgid "list all components"
 msgstr "vypsat všechny komponenty"
@@ -8513,10 +8367,8 @@ msgstr "|KOMPONENTA|zkontrolovat volby"
 msgid "apply global default values"
 msgstr "aplikovat globální implicitní hodnoty"
 
-#, fuzzy
-#| msgid "|FILE|take policy information from FILE"
 msgid "|FILE|update configuration files using FILE"
-msgstr "|SOUBOR|vzít politiky ze SOUBORU"
+msgstr "|SOUBOR|aktualizovat konfigurační soubory pomocí SOUBORU"
 
 msgid "get the configuration directories for @GPGCONF@"
 msgstr "získat adresáře s nastavením @GPGCONF@"
@@ -8527,10 +8379,8 @@ msgstr "vypsat globální konfigurační soubor"
 msgid "check global configuration file"
 msgstr "zkontrolovat globální konfigurační soubor"
 
-#, fuzzy
-#| msgid "update the trust database"
 msgid "query the software version database"
-msgstr "aktualizovat databázi důvěry"
+msgstr "dotázat se databázi verzí softwaru"
 
 msgid "reload all or a given component"
 msgstr "znovu načíst všechny nebo zadané komponenty"
@@ -8710,9 +8560,27 @@ msgstr ""
 "Syntaxe: gpg-check-pattern [volby] soubor_se_vzorem\n"
 "Prověří heslo zadané na vstupu proti souboru se vzory\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "volání listen() selhalo: %s\n"
+
+#~ msgid "shadowing the key failed: %s\n"
+#~ msgstr "výroba stínového klíče se nezdařila: %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "neuzurpovat si klávesnici a myš"
 
+#~ msgid "communication problem with gpg-agent\n"
+#~ msgstr "problémy v komunikaci s gpg-agentem\n"
+
+#~ msgid "canceled by user\n"
+#~ msgstr "zrušeno uživatelem\n"
+
+#~ msgid "problem with the agent\n"
+#~ msgstr "problém s agentem\n"
+
+#~ msgid "you found a bug ... (%s:%d)\n"
+#~ msgstr "našli jste chybu… (%s:%d)\n"
+
 #~ msgid "Error: URL too long (limit is %d characters).\n"
 #~ msgstr "Chyba: URL je příliš dlouhé (limit je %d znaků).\n"
 
@@ -8722,64 +8590,20 @@ msgstr ""
 #~ msgid "Error: Private DO too long (limit is %d characters).\n"
 #~ msgstr "Chyba: Privátní DO je příliš dlouhé (limit je %d znaků).\n"
 
-#, fuzzy
-#~| msgid "key %s: unsupported public key algorithm\n"
-#~ msgid ""
-#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-#~ msgstr "klíč %s: nepodporovaný algoritmus veřejného klíče\n"
-
-#, fuzzy
-#~| msgid "card does not support digest algorithm %s\n"
-#~ msgid ""
-#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
-#~ msgstr "karta nepodporuje hashovací algoritmus %s\n"
-
-#, fuzzy
-#~| msgid "Good signature from"
-#~ msgid " (reordered signatures follow)"
-#~ msgstr "Dobrý podpis od"
-
-#, fuzzy
-#~| msgid "key %s: %s\n"
-#~ msgid "key %s:\n"
-#~ msgstr "klíč %s: %s\n"
-
-#, fuzzy
-#~| msgid "User ID \"%s\": %d signature removed\n"
-#~ msgid "%d duplicate signature removed\n"
-#~ msgid_plural "%d duplicate signatures removed\n"
-#~ msgstr[0] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
-#~ msgstr[1] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
-#~ msgstr[2] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
-
-#, fuzzy
-#~| msgid "Good signature from"
-#~ msgid "%d signature reordered\n"
-#~ msgid_plural "%d signatures reordered\n"
-#~ msgstr[0] "Dobrý podpis od"
-#~ msgstr[1] "Dobrý podpis od"
-#~ msgstr[2] "Dobrý podpis od"
-
-#~ msgid "new configuration file '%s' created\n"
-#~ msgstr "vytvořen nový konfigurační soubor „%s“\n"
-
-#~ msgid "WARNING: options in '%s' are not yet active during this run\n"
-#~ msgstr ""
-#~ "VAROVÁNÍ: nastavení z „%s“ nejsou při tomto spuštění zatím aktivní\n"
+#~ msgid "available TOFU policies:\n"
+#~ msgstr "dostupné politiky TOFU:\n"
 
-#, fuzzy
-#~| msgid "Key generation failed: %s\n"
-#~ msgid "User ID revocation failed: %s\n"
-#~ msgstr "Vytvoření klíče se nepodařilo: %s\n"
+#~ msgid "unknown TOFU DB format '%s'\n"
+#~ msgstr "neznámý formát „%s“ databáze TOFU\n"
 
-#~ msgid "||Please enter the PIN%%0A[sigs done: %lu]"
-#~ msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
+#~ msgid "key specification '%s' is ambiguous\n"
+#~ msgstr "výběr klíče pomocí „%s“ není jednoznačné\n"
 
-#~ msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]"
-#~ msgstr "|A|Prosím, zadejte PIN správce%%0A[zbývá pokusů: %d]"
+#~ msgid "'%s' matches at least:\n"
+#~ msgstr "„%s“ odpovídá přinejmenším:\n"
 
-#~ msgid "DSA requires the use of a 160 bit hash algorithm\n"
-#~ msgstr "DSA požaduje použití 160bitového hašovacího algoritmu\n"
+#~ msgid "libgcrypt is too old (need %s, have %s)\n"
+#~ msgstr "libgcrypt je příliš stará (potřebuji %s, mám %s)\n"
 
 #~ msgid "--store [filename]"
 #~ msgstr "--store [jméno souboru]"
@@ -8805,8 +8629,8 @@ msgstr ""
 #~ msgid "--sign --symmetric [filename]"
 #~ msgstr "--sign --symmetric [jméno souboru]"
 
-#~ msgid "--clear-sign [filename]"
-#~ msgstr "--clear-sign [jméno souboru]"
+#~ msgid "--clearsign [filename]"
+#~ msgstr "--clearsign [jméno souboru]"
 
 #~ msgid "--decrypt [filename]"
 #~ msgstr "--decrypt [jméno souboru]"
@@ -8826,112 +8650,24 @@ msgstr ""
 #~ msgid "[filename]"
 #~ msgstr "[jméno souboru]"
 
-#~ msgid "shadowing the key failed: %s\n"
-#~ msgstr "výroba stínového klíče se nezdařila: %s\n"
-
-#~ msgid "available TOFU policies:\n"
-#~ msgstr "dostupné politiky TOFU:\n"
-
-#, fuzzy
-#~| msgid "print message digests"
-#~ msgid "%ld message signed"
-#~ msgid_plural "%ld messages signed"
-#~ msgstr[0] "vypsat hash zprávy"
-#~ msgstr[1] "vypsat hash zprávy"
-#~ msgstr[2] "vypsat hash zprávy"
-
-#~ msgid "GPG Agent"
-#~ msgstr "Agent GPG"
-
-#~ msgid "Key Acquirer"
-#~ msgstr "Stahovač klíčů"
-
-#~ msgid "communication problem with gpg-agent\n"
-#~ msgstr "problémy v komunikaci s gpg-agentem\n"
-
-#~ msgid "canceled by user\n"
-#~ msgstr "zrušeno uživatelem\n"
-
-#~ msgid "problem with the agent\n"
-#~ msgstr "problém s agentem\n"
-
-#, fuzzy
-#~| msgid "problem with the agent: %s\n"
-#~ msgid "problem with the agent (unexpected response \"%s\")\n"
-#~ msgstr "problém s agentem: %s\n"
-
-#~ msgid "unknown TOFU DB format '%s'\n"
-#~ msgstr "neznámý formát „%s“ databáze TOFU\n"
+#~ msgid "%d signatures not checked due to missing keys\n"
+#~ msgstr "%d podpisů neověřených, protože chybí klíč\n"
 
-#~ msgid "libgcrypt is too old (need %s, have %s)\n"
-#~ msgstr "libgcrypt je příliš stará (potřebuji %s, mám %s)\n"
+#~ msgid "%d signatures not checked due to errors\n"
+#~ msgstr "%d podpisů neověřených, protože vznikly chyby\n"
 
-#~ msgid ""
-#~ "Please enter the passphrase to unlock the secret key for the OpenPGP "
-#~ "certificate:\n"
-#~ "\"%.*s\"\n"
-#~ "%u-bit %s key, ID %s,\n"
-#~ "created %s%s.\n"
-#~ msgstr ""
-#~ "Prosím, zadejte heslo, abyste odemkli tajný klíč příslušející OpenPGP "
-#~ "certifikátu:\n"
-#~ "„%.*s“\n"
-#~ "Klíč o délce %u bitů, typ %s, ID %s\n"
-#~ "vytvořený %s%s.\n"
+#~ msgid "1 user ID without valid self-signature detected\n"
+#~ msgstr "objeven 1 identifikátor uživatele bez platného podpisu jím samým\n"
 
-#~ msgid ""
-#~ "You need a passphrase to unlock the secret key for\n"
-#~ "user: \"%s\"\n"
+#~ msgid "%d user IDs without valid self-signatures detected\n"
 #~ msgstr ""
-#~ "Musíte znát heslo, abyste odemkli tajný klíč pro\n"
-#~ "uživatele: „%s“\n"
-
-#~ msgid "%u-bit %s key, ID %s, created %s"
-#~ msgstr "délka %u bitů, typ %s, klíč %s, vytvořený %s"
-
-#~ msgid "         (subkey on main key ID %s)"
-#~ msgstr "         (podklíč na hlavním klíči ID %s)"
-
-#~ msgid "can't access directory '%s': %s\n"
-#~ msgstr "k adresáři „%s“ nelze přistoupit: %s\n"
-
-#~ msgid "run as windows service (background)"
-#~ msgstr "poběží jako služba Windows (na pozadí)"
-
-#~ msgid "running in compatibility mode - certificate chain not checked!\n"
-#~ msgstr "provoz v režimu kompatibility – řetěz certifikátů nezkontrolován!\n"
-
-#~ msgid "you found a bug ... (%s:%d)\n"
-#~ msgstr "našli jste chybu… (%s:%d)\n"
-
-#, fuzzy
-#~| msgid "%d user IDs without valid self-signatures detected\n"
-#~ msgid "%d user ID without valid self-signature detected\n"
-#~ msgid_plural "%d user IDs without valid self-signatures detected\n"
-#~ msgstr[0] ""
-#~ "objeveno %d identifikátorů uživatele bez platného podpisu jím samým\n"
-#~ msgstr[1] ""
-#~ "objeveno %d identifikátorů uživatele bez platného podpisu jím samým\n"
-#~ msgstr[2] ""
 #~ "objeveno %d identifikátorů uživatele bez platného podpisu jím samým\n"
 
 #~ msgid "moving a key signature to the correct place\n"
 #~ msgstr "přesunuji podpis klíče na správné místo\n"
 
-#~ msgid "key specification '%s' is ambiguous\n"
-#~ msgstr "výběr klíče pomocí „%s“ není jednoznačné\n"
-
-#~ msgid "'%s' matches at least:\n"
-#~ msgstr "„%s“ odpovídá přinejmenším:\n"
-
-#~ msgid "%d signatures not checked due to missing keys\n"
-#~ msgstr "%d podpisů neověřených, protože chybí klíč\n"
-
-#~ msgid "%d signatures not checked due to errors\n"
-#~ msgstr "%d podpisů neověřených, protože vznikly chyby\n"
-
-#~ msgid "1 user ID without valid self-signature detected\n"
-#~ msgstr "objeven 1 identifikátor uživatele bez platného podpisu jím samým\n"
+#~ msgid "Deleted %d signatures.\n"
+#~ msgstr "Smazáno %d podpisů.\n"
 
 #~ msgid "User ID \"%s\": %d signatures removed\n"
 #~ msgstr "Uživatelské ID „%s“: %d podpisů odstraněno\n"
@@ -8982,6 +8718,39 @@ msgstr ""
 #~ msgid "sending key %s to %s server %s\n"
 #~ msgstr "posílám klíč %s na %s server %s\n"
 
+#~ msgid "new configuration file '%s' created\n"
+#~ msgstr "vytvořen nový konfigurační soubor „%s“\n"
+
+#~ msgid "WARNING: options in '%s' are not yet active during this run\n"
+#~ msgstr ""
+#~ "VAROVÁNÍ: nastavení z „%s“ nejsou při tomto spuštění zatím aktivní\n"
+
+#~ msgid ""
+#~ "Please enter the passphrase to unlock the secret key for the OpenPGP "
+#~ "certificate:\n"
+#~ "\"%.*s\"\n"
+#~ "%u-bit %s key, ID %s,\n"
+#~ "created %s%s.\n"
+#~ msgstr ""
+#~ "Prosím, zadejte heslo, abyste odemkli tajný klíč příslušející OpenPGP "
+#~ "certifikátu:\n"
+#~ "„%.*s“\n"
+#~ "Klíč o délce %u bitů, typ %s, ID %s\n"
+#~ "vytvořený %s%s.\n"
+
+#~ msgid ""
+#~ "You need a passphrase to unlock the secret key for\n"
+#~ "user: \"%s\"\n"
+#~ msgstr ""
+#~ "Musíte znát heslo, abyste odemkli tajný klíč pro\n"
+#~ "uživatele: „%s“\n"
+
+#~ msgid "%u-bit %s key, ID %s, created %s"
+#~ msgstr "délka %u bitů, typ %s, klíč %s, vytvořený %s"
+
+#~ msgid "         (subkey on main key ID %s)"
+#~ msgstr "         (podklíč na hlavním klíči ID %s)"
+
 #~ msgid "public key %s is %lu seconds newer than the signature\n"
 #~ msgstr "veřejný klíč %s je o %lu sekund novější než podpis\n"
 
@@ -8995,6 +8764,30 @@ msgstr ""
 #~ msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n"
 #~ msgstr "požadováno %d částečné důvěry a %d úplné důvěry, model %s\n"
 
+#~ msgid "||Please enter the PIN%%0A[sigs done: %lu]"
+#~ msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
+
+#~ msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]"
+#~ msgstr "|A|Prosím, zadejte PIN správce%%0A[zbývá pokusů: %d]"
+
+#~ msgid "can't access directory '%s': %s\n"
+#~ msgstr "k adresáři „%s“ nelze přistoupit: %s\n"
+
+#~ msgid "run as windows service (background)"
+#~ msgstr "poběží jako služba Windows (na pozadí)"
+
+#~ msgid "running in compatibility mode - certificate chain not checked!\n"
+#~ msgstr "provoz v režimu kompatibility – řetěz certifikátů nezkontrolován!\n"
+
+#~ msgid "DSA requires the use of a 160 bit hash algorithm\n"
+#~ msgstr "DSA požaduje použití 160bitového hašovacího algoritmu\n"
+
+#~ msgid "GPG Agent"
+#~ msgstr "Agent GPG"
+
+#~ msgid "Key Acquirer"
+#~ msgstr "Stahovač klíčů"
+
 #~ msgid "Passphrase"
 #~ msgstr "Heslo"
 
@@ -9997,7 +9790,7 @@ msgstr ""
 #~ "na aktuální seznam předvoleb. Časová razítka všech dotčených podpisů\n"
 #~ "klíčů jimi samotnými budou posunuty o jednu vteřinu dopředu.\n"
 
-#~ msgid "Please enter the passphrase; this is a secret sentence \n"
+#~ msgid "Please enter the passhrase; this is a secret sentence \n"
 #~ msgstr "Prosím, vložte heslo; toto je tajná věta \n"
 
 #~ msgid ""
index abc1257..e30e3b6 100644 (file)
--- a/po/da.po
+++ b/po/da.po
@@ -505,10 +505,6 @@ msgstr "fejl ved binding af sokkel til »%s«: %s\n"
 msgid "can't set permissions of '%s': %s\n"
 msgstr "Advarsel: usikre rettigheder på %s »%s«\n"
 
-#, c-format
-msgid "listen() failed: %s\n"
-msgstr "listen() mislykkedes: %s\n"
-
 #, fuzzy, c-format
 #| msgid "listening on socket `%s'\n"
 msgid "listening on socket '%s'\n"
@@ -9213,6 +9209,9 @@ msgstr ""
 "Syntaks: gpg-check-pattern [tilvalg] mønsterfil\n"
 "Kontroller en adgangsfrase angivet på stdin mod mønsterfilen\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "listen() mislykkedes: %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "fang ikke tastatur og mus"
 
index e974ddc..4351d32 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnupg-2.1.0\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2017-11-02 17:36+0100\n"
+"PO-Revision-Date: 2017-12-19 12:28+0100\n"
 "Last-Translator: Werner Koch <wk@gnupg.org>\n"
 "Language-Team: German <de@li.org>\n"
 "Language: de\n"
@@ -453,10 +453,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "Zugriffsrechte für '%s' können nicht gesetzt werden: %s\n"
 
 #, c-format
-msgid "listen() failed: %s\n"
-msgstr "Der listen()-Aufruf ist fehlgeschlagen: %s\n"
-
-#, c-format
 msgid "listening on socket '%s'\n"
 msgstr "Es wird auf Socket `%s' gehört\n"
 
@@ -955,7 +951,7 @@ msgid "Data decryption succeeded"
 msgstr "Entschlüsselung der Daten erfolgreich"
 
 msgid "Encryption algorithm supported"
-msgstr "Verschlüsselungsverfahren %d%s wird nicht unterstützt"
+msgstr "Verschlüsselungsverfahren wird unterstützt"
 
 msgid "Data verification succeeded"
 msgstr "Prüfung der Signatur erfolgreich"
@@ -8759,6 +8755,9 @@ msgstr ""
 "Syntax: gpg-check-pattern [optionen] Musterdatei\n"
 "Die von stdin gelesene Passphrase gegen die Musterdatei prüfen\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "Der listen()-Aufruf ist fehlgeschlagen: %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "Tastatur und Maus nicht \"grabben\""
 
index cc9439e..749b333 100644 (file)
--- a/po/el.po
+++ b/po/el.po
@@ -467,10 +467,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: μη ασφαλείς άδειες στο %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "η ενημέρωση απέτυχε: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "εγγραφή του μυστικού κλειδιού στο `%s'\n"
 
@@ -8980,6 +8976,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "η ενημέρωση απέτυχε: %s\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "κλειδί %08lX: μη υποστηριζόμενος αλγόριθμος δημοσίου κλειδιού\n"
index 611b987..002e2dc 100644 (file)
--- a/po/eo.po
+++ b/po/eo.po
@@ -467,10 +467,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "Averto: malsekuraj permesoj sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "aktualigo malsukcesis: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "skribas sekretan ŝlosilon al '%s'\n"
 
@@ -8921,6 +8917,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "aktualigo malsukcesis: %s\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "ŝlosilo %08lX: nerealigita publikŝlosila metodo\n"
index 76d3952..a631ced 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -521,10 +521,6 @@ msgstr "error enlazando el socket con `%s': %s\n"
 msgid "can't set permissions of '%s': %s\n"
 msgstr "Aviso: permisos inseguros en %s \"%s\"\n"
 
-#, c-format
-msgid "listen() failed: %s\n"
-msgstr "listen() falló: %s\n"
-
 #, fuzzy, c-format
 #| msgid "listening on socket `%s'\n"
 msgid "listening on socket '%s'\n"
@@ -9252,6 +9248,9 @@ msgstr ""
 "Compara frase contraseña dada en entrada estándar con un fichero de "
 "patrones\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "listen() falló: %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "no acaparar teclado y ratón"
 
index 66e905b..b6a12e4 100644 (file)
--- a/po/et.po
+++ b/po/et.po
@@ -464,10 +464,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "HOIATUS: ebaturvalised õigused %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "uuendamine ebaõnnestus: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "kirjutan salajase võtme faili `%s'\n"
 
@@ -8896,6 +8892,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "uuendamine ebaõnnestus: %s\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "võti %08lX: mittetoetatud avaliku võtme algoritm\n"
index 15f7ce7..96ed735 100644 (file)
--- a/po/fi.po
+++ b/po/fi.po
@@ -481,10 +481,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "VAROITUS: oikeudet kohteessa %s \"%s\" eivät ole turvallisia\"\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "päivitys epäonnistui: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "kirjoitan salaisen avaimen kohteeseen \"%s\"\n"
 
@@ -8958,6 +8954,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "päivitys epäonnistui: %s\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "avain %08lX: julkisen avaimen algoritmia ei tueta\n"
index fa1e87f..30f61bb 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -468,10 +468,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "Avertissement : les droits de %s ne sont pas sûrs « %s »\n"
 
 #, c-format
-msgid "listen() failed: %s\n"
-msgstr "échec de listen() : %s\n"
-
-#, c-format
 msgid "listening on socket '%s'\n"
 msgstr "écoute sur la socket « %s »\n"
 
@@ -8935,6 +8931,9 @@ msgstr ""
 "Vérifier une phrase secrète donnée sur l'entrée standard par rapport à "
 "ficmotif\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "échec de listen() : %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "ne pas capturer le clavier et la souris"
 
index 3b18702..ac878c6 100644 (file)
--- a/po/gl.po
+++ b/po/gl.po
@@ -468,10 +468,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "AVISO: permisos inseguros en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "a actualización fallou: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "gravando a chave secreta en `%s'\n"
 
@@ -8987,6 +8983,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "a actualización fallou: %s\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "chave %08lX: algoritmo de chave pública non soportado\n"
index f18609d..4afd8ef 100644 (file)
--- a/po/hu.po
+++ b/po/hu.po
@@ -464,10 +464,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "FIGYELEM: nem biztonságos engedélyek: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "Frissítés sikertelen: %s.\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "Írom a titkos kulcsot a %s állományba.\n"
 
@@ -8926,6 +8922,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "Frissítés sikertelen: %s.\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "%08lX kulcs: Nem támogatott nyilvános kulcsú algoritmus!\n"
index 635ed7d..e3f4b50 100644 (file)
--- a/po/id.po
+++ b/po/id.po
@@ -469,10 +469,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "Peringatan: permisi tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "gagal memperbarui: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "menulis kunci rahasia ke `%s'\n"
 
@@ -8919,6 +8915,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "gagal memperbarui: %s\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "kunci %08lX: algoritma publik key tidak didukung\n"
index fc43244..1eb3a79 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -464,10 +464,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "ATTENZIONE: i permessi \"%s\" di %s sono insicuri\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "aggiornamento fallito: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "scrittura della chiave segreta in `%s'\n"
 
@@ -8960,6 +8956,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "aggiornamento fallito: %s\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "chiave %08lX: algoritmo a chiave pubblica non gestito\n"
index 26c032f..ac4ad78 100644 (file)
--- a/po/ja.po
+++ b/po/ja.po
@@ -8,9 +8,9 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg 2.2.2\n"
+"Project-Id-Version: gnupg 2.2.3\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2017-11-07 11:11+0900\n"
+"PO-Revision-Date: 2017-12-18 14:07+0900\n"
 "Last-Translator: NIIBE Yutaka <gniibe@fsij.org>\n"
 "Language-Team: none\n"
 "Language: ja\n"
@@ -434,10 +434,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "'%s'の許可が設定できません: %s\n"
 
 #, c-format
-msgid "listen() failed: %s\n"
-msgstr "listen() に失敗しました: %s\n"
-
-#, c-format
 msgid "listening on socket '%s'\n"
 msgstr "ソケット'%s'でlisten\n"
 
@@ -1340,10 +1336,10 @@ msgstr "暗号化鍵の鍵長は? (%u) "
 msgid "What keysize do you want for the Authentication key? (%u) "
 msgstr "認証鍵の鍵長は? (%u) "
 
-#, fuzzy, c-format
-#| msgid "The card will now be re-configured to generate a key of %u bits\n"
+#, c-format
 msgid "The card will now be re-configured to generate a key of type: %s\n"
-msgstr "今、%uビットの鍵を生成するようにカードは再コンフィグされました\n"
+msgstr ""
+"カードは、今、こちらのタイプの鍵を生成するように再コンフィグされました: %s\n"
 
 #, c-format
 msgid "rounded up to %u bits\n"
@@ -3775,10 +3771,10 @@ msgid "invalid value\n"
 msgstr "無効な値\n"
 
 msgid "Key does not expire at all\n"
-msgstr "%sは無期限です\n"
+msgstr "は無期限です\n"
 
 msgid "Signature does not expire at all\n"
-msgstr "%署名は無期限です\n"
+msgstr "署名は無期限です\n"
 
 #, c-format
 msgid "Key expires at %s\n"
@@ -8323,6 +8319,9 @@ msgstr ""
 "形式: gpg-check-pattern [オプション] パターンファイル\n"
 "パターンファイルに対して標準入力のパスフレーズを確認する\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "listen() に失敗しました: %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "キーボードとマウスを占有しない"
 
index 8be6724..eea3fd7 100644 (file)
--- a/po/nb.po
+++ b/po/nb.po
@@ -438,10 +438,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "klarte ikke å endre tillatelser til «%s»: %s\n"
 
 #, c-format
-msgid "listen() failed: %s\n"
-msgstr "listen() mislyktes: %s\n"
-
-#, c-format
 msgid "listening on socket '%s'\n"
 msgstr "lytter på sokkel «%s»\n"
 
@@ -8440,6 +8436,9 @@ msgstr ""
 "Syntaks: gpg-check-pattern [valg] mønsterfil\n"
 "Kontroller passordfrase oppgitt på standard innkanal mot valgt mønsterfil\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "listen() mislyktes: %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "ikke bruk tastatur og mus"
 
index 6c447ec..f8a53e8 100644 (file)
--- a/po/nl.po
+++ b/po/nl.po
@@ -30,7 +30,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnupg 2.0.28\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2015-06-07 16:56+0200\n"
+"PO-Revision-Date: 2017-12-19 12:28+0100\n"
 "Last-Translator: Frans Spiesschaert <Frans.Spiesschaert@yucom.be>\n"
 "Language-Team: Debian Dutch l10n Team <debian-l10n-dutch@lists.debian.org>\n"
 "Language: nl\n"
@@ -6501,7 +6501,7 @@ msgid "keybox `%s' created\n"
 msgstr "sleuteldoosje `%s' is aangemaakt\n"
 
 msgid "failed to get the fingerprint\n"
-msgstr "opvragen van de vingerafdruk is mislukt: %s\n"
+msgstr "opvragen van de vingerafdruk is mislukt\n"
 
 #, c-format
 msgid "problem looking for existing certificate: %s\n"
index ef392ac..74ade4f 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -494,10 +494,6 @@ msgstr "błąd podczas przypisywania gniazda do ,,%s'': %s\n"
 msgid "can't set permissions of '%s': %s\n"
 msgstr "Ostrzeżenie: niebezpieczne prawa dostępu do %s ,,%s''\n"
 
-#, c-format
-msgid "listen() failed: %s\n"
-msgstr "listen() nie powiodło się: %s\n"
-
 #, fuzzy, c-format
 #| msgid "listening on socket `%s'\n"
 msgid "listening on socket '%s'\n"
@@ -9281,6 +9277,9 @@ msgstr ""
 "Składnia: gpg-check-pattern [opcje] plik-wzorców\n"
 "Sprawdzanie hasła ze standardowego wejścia względem pliku wzorców\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "listen() nie powiodło się: %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "nie przechwytywanie klawiatury i myszy"
 
index 3caa5ca..dab31d8 100644 (file)
--- a/po/pt.po
+++ b/po/pt.po
@@ -469,10 +469,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "actualização falhou: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "a escrever chave privada para `%s'\n"
 
@@ -8928,6 +8924,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "actualização falhou: %s\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "chave %08lX: algoritmo de chave pública não suportado\n"
index 30a9924..bf4daec 100644 (file)
--- a/po/ro.po
+++ b/po/ro.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnupg 1.4.2rc1\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2005-05-31 22:00-0500\n"
+"PO-Revision-Date: 2017-12-19 12:30+0100\n"
 "Last-Translator: Laurentiu Buzdugan <lbuz@rolix.org>\n"
 "Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
 "Language: ro\n"
@@ -479,10 +479,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "AVERTISMENT: permisiuni nesigure (unsafe) pentru extensia `%s'\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "actualizarea a eşuat: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "scriu cheia secretă în `%s'\n"
 
@@ -3078,8 +3074,9 @@ msgstr ""
 msgid "User ID \"%s\" is revoked."
 msgstr "ID utilizator \"%s\" a fost revocat."
 
+#, fuzzy
 msgid "Are you sure you still want to sign it? (y/N) "
-msgstr "Sunteţi sigur(ă) că doriţi să ştergeţi permanent \"%s\"? (d/N)"
+msgstr "Sunteţi sigur(ă) că doriţi să ştergeţi permanent? (d/N)"
 
 msgid "  Unable to sign.\n"
 msgstr "  Nu pot semna.\n"
@@ -9002,6 +8999,10 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
+#, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "actualizarea a eşuat: %s\n"
+
 #~ msgid "Error: URL too long (limit is %d characters).\n"
 #~ msgstr "Eroare: URL prea lung (limita este de %d caractere).\n"
 
index a2d0383..793bb0b 100644 (file)
--- a/po/ru.po
+++ b/po/ru.po
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: GnuPG 2.2.0\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2017-11-02 17:41+0100\n"
+"PO-Revision-Date: 2017-12-13 17:41+0100\n"
 "Last-Translator: Ineiev <ineiev@gnu.org>\n"
 "Language-Team: Russian <gnupg-ru@gnupg.org>\n"
 "Language: ru\n"
@@ -445,10 +445,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "не удалось задать права доступа для '%s': %s\n"
 
 #, c-format
-msgid "listen() failed: %s\n"
-msgstr "сбой listen(): %s\n"
-
-#, c-format
 msgid "listening on socket '%s'\n"
 msgstr "слушаем сокет '%s'\n"
 
@@ -1349,10 +1345,9 @@ msgstr "Какой Вам нужен размер ключа для шифров
 msgid "What keysize do you want for the Authentication key? (%u) "
 msgstr "Какой Вам нужен размер ключа для удостоверения личности? (%u) "
 
-#, fuzzy, c-format
-#| msgid "The card will now be re-configured to generate a key of %u bits\n"
+#, c-format
 msgid "The card will now be re-configured to generate a key of type: %s\n"
-msgstr "Теперь карта будет перенастроена на генерацию ключа длиной %u бит\n"
+msgstr "Теперь карта будет перенастроена на генерацию ключа типа %s\n"
 
 #, c-format
 msgid "rounded up to %u bits\n"
@@ -8583,6 +8578,9 @@ msgstr ""
 "Синтаксис: gpg-check-pattern [параметры] файл_образцов\n"
 "Проверить фразу-пароль, поступающую из stdin, по файлу образцов\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "сбой listen(): %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "не захватывать клавиатуру и мышь"
 
index 6880122..cb0a41f 100644 (file)
--- a/po/sk.po
+++ b/po/sk.po
@@ -469,10 +469,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "VAROVANIE: prístupové práva pre %s nie sú nastavené bezpečne \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "aktualizácia zlyhala: %s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "zapisujem tajný kľúč do `%s'\n"
 
@@ -4951,6 +4947,7 @@ msgstr "\"%s\" nie je súbor JPEG\n"
 msgid "Is this photo correct (y/N/q)? "
 msgstr "Je táto fotografia správna (a/N/u)? "
 
+#, fuzzy
 msgid "unable to display photo ID!\n"
 msgstr "nemožno nastaviť exec-path na %s\n"
 
@@ -8950,6 +8947,10 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "aktualizácia zlyhala: %s\n"
+
+#, fuzzy
 #~ msgid ""
 #~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
 #~ msgstr "kľúč %08lX: nepodporovaný algoritmus verejného kľúča\n"
index 8d94c9a..d5da7ca 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -523,10 +523,6 @@ msgstr "fel när \"%s\" bands till uttag: %s\n"
 msgid "can't set permissions of '%s': %s\n"
 msgstr "Varning: osäkra rättigheter på %s \"%s\"\n"
 
-#, c-format
-msgid "listen() failed: %s\n"
-msgstr "listen() misslyckades: %s\n"
-
 #, fuzzy, c-format
 #| msgid "listening on socket `%s'\n"
 msgid "listening on socket '%s'\n"
@@ -9359,6 +9355,9 @@ msgstr ""
 "Syntax: gpg-check-pattern [flaggor] mönsterfil\n"
 "Kontrollera en lösenfras angiven på standard in mot mönsterfilen\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "listen() misslyckades: %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "fånga inte tangentbord och mus"
 
index cc77eb9..f5e08eb 100644 (file)
--- a/po/tr.po
+++ b/po/tr.po
@@ -489,10 +489,6 @@ msgstr "soket `%s'e bağlanırken hata: %s\n"
 msgid "can't set permissions of '%s': %s\n"
 msgstr "UYARI: %s üzerinde izinler güvensiz: \"%s\"\n"
 
-#, c-format
-msgid "listen() failed: %s\n"
-msgstr "soket dinleme başarısız: %s\n"
-
 #, fuzzy, c-format
 #| msgid "listening on socket `%s'\n"
 msgid "listening on socket '%s'\n"
@@ -9265,6 +9261,9 @@ msgstr ""
 "Standart girdiden verilen anahtar parolasını örüntü dosyasıyla "
 "karşılaştırır\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "soket dinleme başarısız: %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "klavye ve fare gaspedilmez"
 
index 9316d81..2881bb2 100644 (file)
--- a/po/uk.po
+++ b/po/uk.po
@@ -440,10 +440,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "не вдалося встановити права доступу до «%s»: %s\n"
 
 #, c-format
-msgid "listen() failed: %s\n"
-msgstr "помилка listen(): %s\n"
-
-#, c-format
 msgid "listening on socket '%s'\n"
 msgstr "очікування даних на сокеті «%s»\n"
 
@@ -8693,6 +8689,9 @@ msgstr ""
 "Синтаксис: gpg-check-pattern [параметри] файл_шаблонів\n"
 "Перевірити пароль, вказаний у stdin, за допомогою файла_шаблонів\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "помилка listen(): %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "не захоплювати керування клавіатурою і мишею"
 
index 4b3954c..9caeaef 100644 (file)
@@ -477,10 +477,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "警告:扩展模块‘%s’权限不安全\n"
 
 #, fuzzy, c-format
-msgid "listen() failed: %s\n"
-msgstr "更新失败:%s\n"
-
-#, fuzzy, c-format
 msgid "listening on socket '%s'\n"
 msgstr "正在将私钥写至`%s'\n"
 
@@ -8826,6 +8822,10 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
+#, fuzzy
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "更新失败:%s\n"
+
 #~ msgid "Error: URL too long (limit is %d characters).\n"
 #~ msgstr "错误:URL 太长(至多 %d 个字符)\n"
 
index f997fa1..51b3798 100644 (file)
@@ -447,10 +447,6 @@ msgid "can't set permissions of '%s': %s\n"
 msgstr "警告: %s 的權限 \"%s\" 並不安全\n"
 
 #, c-format
-msgid "listen() failed: %s\n"
-msgstr "listen() 失敗: %s\n"
-
-#, c-format
 msgid "listening on socket '%s'\n"
 msgstr "正在候聽 socket '%s'\n"
 
@@ -8476,6 +8472,9 @@ msgstr ""
 "語法: gpg-check-pattern [選項] 樣式檔案\n"
 "用樣式檔案來檢查由標準輸入給定的密語\n"
 
+#~ msgid "listen() failed: %s\n"
+#~ msgstr "listen() 失敗: %s\n"
+
 #~ msgid "do not grab keyboard and mouse"
 #~ msgstr "不要奪取鍵盤及滑鼠"
 
index 97624eb..c50afbd 100644 (file)
@@ -1497,8 +1497,13 @@ open_ccid_reader (struct dev_list *dl)
   err = ccid_open_reader (dl->portstr, dl->idx, dl->ccid_table,
                           &slotp->ccid.handle, &slotp->rdrname);
   if (!err)
-    err = ccid_get_atr (slotp->ccid.handle,
-                        slotp->atr, sizeof slotp->atr, &slotp->atrlen);
+    {
+      err = ccid_get_atr (slotp->ccid.handle,
+                          slotp->atr, sizeof slotp->atr, &slotp->atrlen);
+      if (err)
+        ccid_close_reader (slotp->ccid.handle);
+    }
+
   if (err)
     {
       slotp->used = 0;
index ec04b40..f3f1205 100644 (file)
--- a/scd/app.c
+++ b/scd/app.c
@@ -323,7 +323,7 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
   if (scan || !app_top)
     {
       struct dev_list *l;
-      int periodical_check_needed = 0;
+      int new_app = 0;
 
       /* Scan the devices to find new device(s).  */
       err = apdu_dev_list_start (opt.reader_port, &l);
@@ -349,8 +349,7 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
             {
               err = app_new_register (slot, ctrl, name,
                                       periodical_check_needed_this);
-              if (periodical_check_needed_this)
-                periodical_check_needed = 1;
+              new_app++;
             }
 
           if (err)
@@ -359,9 +358,8 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
 
       apdu_dev_list_finish (l);
 
-      /* If periodical check is needed for new device(s), kick the
-       scdaemon loop.  */
-      if (periodical_check_needed)
+      /* If new device(s), kick the scdaemon loop.  */
+      if (new_app)
         scd_kick_the_loop ();
     }
 
index 9c22f51..4f4a32d 100644 (file)
@@ -1661,9 +1661,6 @@ ccid_open_usb_reader (const char *spec_reader_name,
         }
     }
 
-  if ((*handle)->ep_intr >= 0)
-    ccid_setup_intr (*handle);
-
   rc = ccid_vendor_specific_init (*handle);
 
  leave:
@@ -2311,6 +2308,11 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits, int on_wire)
      no need to send on wire.  */
   if (!on_wire && !ccid_require_get_status (handle))
     {
+      /* Setup interrupt transfer at the initial call of slot_status
+         with ON_WIRE == 0 */
+      if (handle->transfer == NULL && handle->ep_intr >= 0)
+        ccid_setup_intr (handle);
+
       *statusbits = 0;
       return 0;
     }
@@ -3748,7 +3750,7 @@ main (int argc, char **argv)
   if (!no_poll)
     ccid_poll (ccid);
   fputs ("getting slot status ...\n", stderr);
-  rc = ccid_slot_status (ccid, &slotstat);
+  rc = ccid_slot_status (ccid, &slotstat, 1);
   if (rc)
     {
       print_error (rc);
index 60d539d..3ad2657 100644 (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;
@@ -1003,6 +1013,7 @@ handle_signal (int signo)
 
     case SIGCONT:
       /* Nothing.  */
+      log_debug ("SIGCONT received - breaking select\n");
       break;
 
     case SIGTERM:
@@ -1127,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), ) == -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);
     }
index 0feda90..b505be1 100644 (file)
@@ -1450,6 +1450,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,
@@ -1786,6 +1787,7 @@ main ( int argc, char **argv)
            proc_parameters actually implements.  */
         es_printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
                    "RSA-2048");
+        es_printf ("compliance:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, "gnupg");
 
       }
       break;
index 54365ce..316509f 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Apply defaults from /etc/gnupg/gpg.conf to all users             -*- sh -*-
+# Apply defaults from /etc/gnupg/gpgconf.conf to all users       -*- sh -*-
 #
 # Copyright 2007 Free Software Foundation, Inc.
 #
index 7e3f050..0b1d642 100644 (file)
@@ -66,11 +66,14 @@ enum cmd_and_opt_values
     aInstallKey,
     aRevokeKey,
     aRemoveKey,
+    aCheck,
 
     oGpgProgram,
     oSend,
     oFrom,
     oHeader,
+    oWithDir,
+    oWithFile,
 
     oDummy
   };
@@ -86,12 +89,15 @@ static ARGPARSE_OPTS opts[] = {
               ("run regular jobs")),
   ARGPARSE_c (aListDomains, "list-domains",
               ("list configured domains")),
+  ARGPARSE_c (aCheck, "check",
+              ("check whether a key is installed")),
+  ARGPARSE_c (aCheck, "check-key", "@"),
   ARGPARSE_c (aInstallKey, "install-key",
-              "|FILE|install a key from FILE into the WKD"),
+              "install a key from FILE into the WKD"),
   ARGPARSE_c (aRemoveKey, "remove-key",
-              "|ADDR|remove the key ADDR from the WKD"),
+              "remove a key from the WKD"),
   ARGPARSE_c (aRevokeKey, "revoke-key",
-              "|ADDR|mark the key ADDR in the WKD as revoked"),
+              "mark a key as revoked"),
 
   ARGPARSE_group (301, ("@\nOptions:\n ")),
 
@@ -104,6 +110,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oFrom, "from", "|ADDR|use ADDR as the default sender"),
   ARGPARSE_s_s (oHeader, "header" ,
                 "|NAME=VALUE|add \"NAME: VALUE\" as header to all mails"),
+  ARGPARSE_s_n (oWithDir, "with-dir", "@"),
+  ARGPARSE_s_n (oWithFile, "with-file", "@"),
 
   ARGPARSE_end ()
 };
@@ -132,6 +140,13 @@ struct server_ctx_s
 };
 typedef struct server_ctx_s *server_ctx_t;
 
+
+/* Flag for --with-dir.  */
+static int opt_with_dir;
+/* Flag for --with-file.  */
+static int opt_with_file;
+
+
 /* Prototypes.  */
 static gpg_error_t get_domain_list (strlist_t *r_list);
 
@@ -142,6 +157,7 @@ static gpg_error_t command_list_domains (void);
 static gpg_error_t command_install_key (const char *fname);
 static gpg_error_t command_remove_key (const char *mailaddr);
 static gpg_error_t command_revoke_key (const char *mailaddr);
+static gpg_error_t command_check_key (const char *mailaddr);
 static gpg_error_t command_cron (void);
 
 
@@ -220,10 +236,17 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
         case oOutput:
           opt.output = pargs->r.ret_str;
           break;
+        case oWithDir:
+          opt_with_dir = 1;
+          break;
+        case oWithFile:
+          opt_with_file = 1;
+          break;
 
        case aReceive:
         case aCron:
         case aListDomains:
+        case aCheck:
         case aInstallKey:
         case aRemoveKey:
         case aRevokeKey:
@@ -243,7 +266,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
 int
 main (int argc, char **argv)
 {
-  gpg_error_t err;
+  gpg_error_t err, firsterr;
   ARGPARSE_ARGS pargs;
   enum cmd_and_opt_values cmd;
 
@@ -360,16 +383,29 @@ main (int argc, char **argv)
 
     case aRemoveKey:
       if (argc != 1)
-        wrong_args ("--remove-key MAILADDR");
+        wrong_args ("--remove-key USER-ID");
       err = command_remove_key (*argv);
       break;
 
     case aRevokeKey:
       if (argc != 1)
-        wrong_args ("--revoke-key MAILADDR");
+        wrong_args ("--revoke-key USER-ID");
       err = command_revoke_key (*argv);
       break;
 
+    case aCheck:
+      if (!argc)
+        wrong_args ("--check USER-IDs");
+      firsterr = 0;
+      for (; argc; argc--, argv++)
+        {
+          err = command_check_key (*argv);
+          if (!firsterr)
+            firsterr = err;
+        }
+      err = firsterr;
+      break;
+
     default:
       usage (1);
       err = gpg_error (GPG_ERR_BUG);
@@ -1776,7 +1812,11 @@ command_list_domains (void)
       domain = strrchr (sl->d, '/');
       log_assert (domain);
       domain++;
-      es_printf ("%s\n", domain);
+      if (opt_with_dir)
+        es_printf ("%s %s\n", domain, sl->d);
+      else
+        es_printf ("%s\n", domain);
+
 
       /* Check that the required directories are there.  */
       for (i=0; i < DIM (requireddirs); i++)
@@ -1900,12 +1940,140 @@ command_install_key (const char *fname)
 }
 
 
-/* Remove the key with mail address MAILADDR.  */
+/* Return the filename and optioanlly the addrspec for USERID at
+ * R_FNAME and R_ADDRSPEC.  R_ADDRSPEC might also be set on error.  */
 static gpg_error_t
-command_remove_key (const char *mailaddr)
+fname_from_userid (const char *userid, char **r_fname, char **r_addrspec)
 {
-  (void)mailaddr;
-  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+  gpg_error_t err;
+  char *addrspec = NULL;
+  const char *domain;
+  char *hash = NULL;
+  const char *s;
+  char shaxbuf[32]; /* Used for SHA-1 and SHA-256 */
+
+  *r_fname = NULL;
+  if (r_addrspec)
+    *r_addrspec = NULL;
+
+  addrspec = mailbox_from_userid (userid);
+  if (!addrspec)
+    {
+      if (opt.verbose)
+        log_info ("\"%s\" is not a proper mail address\n", userid);
+      err = gpg_error (GPG_ERR_INV_USER_ID);
+      goto leave;
+    }
+
+  domain = strchr (addrspec, '@');
+  log_assert (domain);
+  domain++;
+
+  /* Hash user ID and create filename.  */
+  s = strchr (addrspec, '@');
+  log_assert (s);
+  gcry_md_hash_buffer (GCRY_MD_SHA1, shaxbuf, addrspec, s - addrspec);
+  hash = zb32_encode (shaxbuf, 8*20);
+  if (!hash)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  *r_fname = make_filename_try (opt.directory, domain, "hu", hash, NULL);
+  if (!*r_fname)
+    err = gpg_error_from_syserror ();
+  else
+    err = 0;
+
+ leave:
+  if (r_addrspec && addrspec)
+    *r_addrspec = addrspec;
+  else
+    xfree (addrspec);
+  xfree (hash);
+  return err;
+}
+
+
+/* Check whether the key with USER_ID is installed.  */
+static gpg_error_t
+command_check_key (const char *userid)
+{
+  gpg_error_t err;
+  char *addrspec = NULL;
+  char *fname = NULL;
+
+  err = fname_from_userid (userid, &fname, &addrspec);
+  if (err)
+    goto leave;
+
+  if (access (fname, R_OK))
+    {
+      err = gpg_error_from_syserror ();
+      if (opt_with_file)
+        es_printf ("%s n %s\n", addrspec, fname);
+      if (gpg_err_code (err) == GPG_ERR_ENOENT)
+        {
+          if (!opt.quiet)
+            log_info ("key for '%s' is NOT installed\n", addrspec);
+          log_inc_errorcount ();
+          err = 0;
+        }
+      else
+        log_error ("error stating '%s': %s\n", fname, gpg_strerror (err));
+      goto leave;
+    }
+
+  if (opt_with_file)
+    es_printf ("%s i %s\n", addrspec, fname);
+
+  if (opt.verbose)
+    log_info ("key for '%s' is installed\n", addrspec);
+  err = 0;
+
+ leave:
+  xfree (fname);
+  xfree (addrspec);
+  return err;
+}
+
+
+/* Remove the key with mail address in USERID.  */
+static gpg_error_t
+command_remove_key (const char *userid)
+{
+  gpg_error_t err;
+  char *addrspec = NULL;
+  char *fname = NULL;
+
+  err = fname_from_userid (userid, &fname, &addrspec);
+  if (err)
+    goto leave;
+
+  if (gnupg_remove (fname))
+    {
+      err = gpg_error_from_syserror ();
+      if (gpg_err_code (err) == GPG_ERR_ENOENT)
+        {
+          if (!opt.quiet)
+            log_info ("key for '%s' is not installed\n", addrspec);
+          log_inc_errorcount ();
+          err = 0;
+        }
+      else
+        log_error ("error removing '%s': %s\n", fname, gpg_strerror (err));
+      goto leave;
+    }
+
+  if (opt.verbose)
+    log_info ("key for '%s' removed\n", addrspec);
+  err = 0;
+
+ leave:
+  xfree (fname);
+  xfree (addrspec);
+  return err;
 }
 
 
@@ -1913,6 +2081,7 @@ command_remove_key (const char *mailaddr)
 static gpg_error_t
 command_revoke_key (const char *mailaddr)
 {
-  (void)mailaddr;
-  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+  /* Remove should be different from removing but we have not yet
+   * defined a suitable way to do this.  */
+  return command_remove_key (mailaddr);
 }
index 9ce752b..f705f3a 100644 (file)
@@ -48,6 +48,7 @@
 #include "../common/i18n.h"
 #include "../common/exechelp.h"
 #include "../common/sysutils.h"
+#include "../common/status.h"
 
 #include "../common/gc-opt-flags.h"
 #include "gpgconf.h"
@@ -99,7 +100,7 @@ gc_error (int status, int errnum, const char *fmt, ...)
     {
       log_printf (NULL);
       log_printf ("fatal error (exit status %i)\n", status);
-      exit (status);
+      gpgconf_failure (gpg_error_from_errno (errnum));
     }
 }
 
@@ -714,7 +715,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 +834,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,
@@ -1307,7 +1311,7 @@ gc_component_launch (int component)
     {
       es_fputs (_("Component not suitable for launching"), es_stderr);
       es_putc ('\n', es_stderr);
-      exit (1);
+      gpgconf_failure (0);
     }
 
   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
@@ -3754,6 +3758,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
             {
               gc_error (0, 0, "missing rule at '%s', line %d", fname, lineno);
               result = -1;
+              gpgconf_write_status (STATUS_WARNING,
+                                    "gpgconf.conf %d file '%s' line %d "
+                                    "missing rule",
+                                    GPG_ERR_SYNTAX, fname, lineno);
               continue;
             }
           *p++ = 0;
@@ -3783,6 +3791,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         {
           gc_error (0, 0, "missing component at '%s', line %d",
                     fname, lineno);
+          gpgconf_write_status (STATUS_WARNING,
+                                "gpgconf.conf %d file '%s' line %d "
+                                " missing component",
+                                GPG_ERR_NO_NAME, fname, lineno);
           result = -1;
           continue;
         }
@@ -3794,6 +3806,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         {
           gc_error (0, 0, "unknown component at '%s', line %d",
                     fname, lineno);
+          gpgconf_write_status (STATUS_WARNING,
+                                "gpgconf.conf %d file '%s' line %d "
+                                "unknown component",
+                                GPG_ERR_UNKNOWN_NAME, fname, lineno);
           result = -1;
         }
 
@@ -3806,6 +3822,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         {
           gc_error (0, 0, "missing option at '%s', line %d",
                     fname, lineno);
+          gpgconf_write_status (STATUS_WARNING,
+                                "gpgconf.conf %d file '%s' line %d "
+                                "missing option",
+                                GPG_ERR_INV_NAME, fname, lineno);
           result = -1;
           continue;
         }
@@ -3818,6 +3838,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
             {
               gc_error (0, 0, "unknown option at '%s', line %d",
                         fname, lineno);
+              gpgconf_write_status (STATUS_WARNING,
+                                    "gpgconf.conf %d file '%s' line %d "
+                                    "unknown option",
+                                    GPG_ERR_UNKNOWN_OPTION, fname, lineno);
               result = -1;
             }
         }
@@ -3834,6 +3858,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
             {
               gc_error (0, 0, "syntax error in rule at '%s', line %d",
                         fname, lineno);
+              gpgconf_write_status (STATUS_WARNING,
+                                    "gpgconf.conf %d file '%s' line %d "
+                                    "syntax error in rule",
+                                    GPG_ERR_SYNTAX, fname, lineno);
               result = -1;
               continue;
             }
index 09b2a76..59085d8 100644 (file)
@@ -29,6 +29,7 @@
 #include "../common/i18n.h"
 #include "../common/sysutils.h"
 #include "../common/init.h"
+#include "../common/status.h"
 
 
 /* Constants to identify the commands and options. */
@@ -45,6 +46,7 @@ enum cmd_and_opt_values
     oNoVerbose = 500,
     oHomedir,
     oBuilddir,
+    oStatusFD,
 
     aListComponents,
     aCheckPrograms,
@@ -100,6 +102,7 @@ static ARGPARSE_OPTS opts[] =
     { oQuiet, "quiet",      0, N_("quiet") },
     { oDryRun, "dry-run",   0, N_("do not make any changes") },
     { oRuntime, "runtime",  0, N_("activate changes at runtime, if possible") },
+  ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")),
     /* hidden options */
     { oHomedir, "homedir", 2, "@" },
     { oBuilddir, "build-prefix", 2, "@" },
@@ -110,6 +113,11 @@ static ARGPARSE_OPTS opts[] =
   };
 
 
+/* The stream to output the status information.  Status Output is disabled if
+ * this is NULL.  */
+static estream_t statusfp;
+
+
 /* Print usage information and provide strings for help. */
 static const char *
 my_strusage( int level )
@@ -159,6 +167,60 @@ get_outfp (estream_t *fp)
 }
 
 
+/* Set the status FD.  */
+static void
+set_status_fd (int fd)
+{
+  static int last_fd = -1;
+
+  if (fd != -1 && last_fd == fd)
+    return;
+
+  if (statusfp && statusfp != es_stdout && statusfp != es_stderr)
+    es_fclose (statusfp);
+  statusfp = NULL;
+  if (fd == -1)
+    return;
+
+  if (fd == 1)
+    statusfp = es_stdout;
+  else if (fd == 2)
+    statusfp = es_stderr;
+  else
+    statusfp = es_fdopen (fd, "w");
+  if (!statusfp)
+    {
+      log_fatal ("can't open fd %d for status output: %s\n",
+                 fd, gpg_strerror (gpg_error_from_syserror ()));
+    }
+  last_fd = fd;
+}
+
+
+/* Write a status line with code NO followed by the output of the
+ * printf style FORMAT.  The caller needs to make sure that LFs and
+ * CRs are not printed.  */
+void
+gpgconf_write_status (int no, const char *format, ...)
+{
+  va_list arg_ptr;
+
+  if (!statusfp)
+    return;  /* Not enabled.  */
+
+  es_fputs ("[GNUPG:] ", statusfp);
+  es_fputs (get_status_string (no), statusfp);
+  if (format)
+    {
+      es_putc (' ', statusfp);
+      va_start (arg_ptr, format);
+      es_vfprintf (statusfp, format, arg_ptr);
+      va_end (arg_ptr);
+    }
+  es_putc ('\n', statusfp);
+}
+
+
 static void
 list_dirs (estream_t fp, char **names)
 {
@@ -493,6 +555,9 @@ main (int argc, char **argv)
         case oHomedir:   gnupg_set_homedir (pargs.r.ret_str); break;
         case oBuilddir:  gnupg_set_builddir (pargs.r.ret_str); break;
         case oNull:      opt.null = 1; break;
+        case oStatusFD:
+          set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
+          break;
 
        case aListDirs:
         case aListComponents:
@@ -518,7 +583,7 @@ main (int argc, char **argv)
     }
 
   if (log_get_errorcount (0))
-    exit (2);
+    gpgconf_failure (GPG_ERR_USER_2);
 
   /* Print a warning if an argument looks like an option.  */
   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
@@ -554,7 +619,7 @@ main (int argc, char **argv)
          es_putc ('\n', es_stderr);
          es_fputs (_("Need one component argument"), es_stderr);
          es_putc ('\n', es_stderr);
-         exit (2);
+         gpgconf_failure (GPG_ERR_USER_2);
        }
       else
        {
@@ -563,7 +628,7 @@ main (int argc, char **argv)
            {
              es_fputs (_("Component not found"), es_stderr);
              es_putc ('\n', es_stderr);
-             exit (1);
+             gpgconf_failure (0);
            }
           if (cmd == aCheckOptions)
            gc_component_check_options (idx, get_outfp (&outfp), NULL);
@@ -571,7 +636,7 @@ main (int argc, char **argv)
             {
               gc_component_retrieve_options (idx);
               if (gc_process_gpgconf_conf (NULL, 1, 0, NULL))
-                exit (1);
+                gpgconf_failure (0);
               if (cmd == aListOptions)
                 gc_component_list_options (idx, get_outfp (&outfp));
               else if (cmd == aChangeOptions)
@@ -589,14 +654,14 @@ main (int argc, char **argv)
          es_putc ('\n', es_stderr);
          es_fputs (_("Need one component argument"), es_stderr);
          es_putc ('\n', es_stderr);
-         exit (2);
+         gpgconf_failure (GPG_ERR_USER_2);
        }
       else if (!strcmp (fname, "all"))
         {
           if (cmd == aLaunch)
             {
               if (gc_component_launch (-1))
-                exit (1);
+                gpgconf_failure (0);
             }
           else
             {
@@ -613,12 +678,12 @@ main (int argc, char **argv)
             {
               es_fputs (_("Component not found"), es_stderr);
               es_putc ('\n', es_stderr);
-              exit (1);
+              gpgconf_failure (0);
             }
           else if (cmd == aLaunch)
             {
               if (gc_component_launch (idx))
-                exit (1);
+                gpgconf_failure (0);
             }
           else
             {
@@ -646,7 +711,7 @@ main (int argc, char **argv)
             {
               es_fputs (_("Component not found"), es_stderr);
               es_putc ('\n', es_stderr);
-              exit (1);
+              gpgconf_failure (0);
             }
           else
             {
@@ -657,12 +722,12 @@ main (int argc, char **argv)
 
     case aListConfig:
       if (gc_process_gpgconf_conf (fname, 0, 0, get_outfp (&outfp)))
-        exit (1);
+        gpgconf_failure (0);
       break;
 
     case aCheckConfig:
       if (gc_process_gpgconf_conf (fname, 0, 0, NULL))
-        exit (1);
+        gpgconf_failure (0);
       break;
 
     case aApplyDefaults:
@@ -672,17 +737,17 @@ main (int argc, char **argv)
          es_putc ('\n', es_stderr);
          es_fputs (_("No argument allowed"), es_stderr);
          es_putc ('\n', es_stderr);
-         exit (2);
+         gpgconf_failure (GPG_ERR_USER_2);
        }
       gc_component_retrieve_options (-1);
       if (gc_process_gpgconf_conf (NULL, 1, 1, NULL))
-        exit (1);
+        gpgconf_failure (0);
       break;
 
     case aApplyProfile:
       gc_component_retrieve_options (-1);
       if (gc_apply_profile (fname))
-        exit (1);
+        gpgconf_failure (0);
       break;
 
     case aListDirs:
@@ -697,7 +762,7 @@ main (int argc, char **argv)
        {
          es_fprintf (es_stderr, "usage: %s --query-swdb NAME [VERSION]\n",
                       GPGCONF_NAME);
-         exit (2);
+         gpgconf_failure (GPG_ERR_USER_2);
        }
       get_outfp (&outfp);
       query_swdb (outfp, fname, argc > 1? argv[1] : NULL);
@@ -804,5 +869,22 @@ main (int argc, char **argv)
     if (es_fclose (outfp))
       gc_error (1, errno, "error closing '%s'", opt.outfile);
 
+
+  if (log_get_errorcount (0))
+    gpgconf_failure (0);
+  else
+    gpgconf_write_status (STATUS_SUCCESS, NULL);
   return 0;
 }
+
+
+void
+gpgconf_failure (gpg_error_t err)
+{
+  if (!err)
+    err = gpg_error (GPG_ERR_GENERAL);
+  gpgconf_write_status
+    (STATUS_FAILURE, "- %u",
+     gpg_err_code (err) == GPG_ERR_USER_2? GPG_ERR_EINVAL : err);
+  exit (gpg_err_code (err) == GPG_ERR_USER_2? 2 : 1);
+}
index d6d7627..8a061ef 100644 (file)
@@ -36,6 +36,10 @@ struct
 } opt;
 
 
+/*-- gpgconf.c --*/
+void gpgconf_write_status (int no, const char *format,
+                           ...) GPGRT_ATTR_PRINTF(2,3);
+void gpgconf_failure (gpg_error_t err) GPGRT_ATTR_NORETURN;
 
 /*-- gpgconf-comp.c --*/