summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-02-09 16:00:10 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-02-09 16:00:10 +0900
commit38e6451f41db54227426835fea3069d721d1a0a5 (patch)
treeaaf6506d5bf0178d9a2561f4f76af6eedf7d1881
parent8bffc2850be3e430e7f6faec136d31c6c815f93f (diff)
downloadgpg2-38e6451f41db54227426835fea3069d721d1a0a5.tar.gz
gpg2-38e6451f41db54227426835fea3069d721d1a0a5.tar.bz2
gpg2-38e6451f41db54227426835fea3069d721d1a0a5.zip
Imported Upstream version 2.1.13upstream/2.1.13
-rw-r--r--NEWS50
-rw-r--r--agent/agent.h1
-rw-r--r--agent/command-ssh.c4
-rw-r--r--agent/command.c69
-rw-r--r--agent/findkey.c12
-rw-r--r--agent/gpg-agent.c42
-rw-r--r--agent/preset-passphrase.c7
-rw-r--r--agent/protect-tool.c7
-rw-r--r--agent/trustlist.c24
-rwxr-xr-xautogen.sh2
-rwxr-xr-xbuild-aux/getswdb.sh4
-rw-r--r--build-aux/speedo.mk4
-rw-r--r--build-aux/speedo/w32/inst.nsi2
-rw-r--r--common/Makefile.am4
-rw-r--r--common/asshelp.c20
-rw-r--r--common/asshelp.h2
-rw-r--r--common/call-gpg.c8
-rw-r--r--common/ccparray.c147
-rw-r--r--common/ccparray.h51
-rw-r--r--common/exechelp-posix.c160
-rw-r--r--common/exechelp-w32.c26
-rw-r--r--common/exechelp-w32ce.c19
-rw-r--r--common/exechelp.h19
-rw-r--r--common/exectool.c211
-rw-r--r--common/exectool.h19
-rw-r--r--common/get-passphrase.c4
-rw-r--r--common/get-passphrase.h1
-rw-r--r--common/homedir.c272
-rw-r--r--common/logging.c15
-rw-r--r--common/openpgp-oid.c33
-rw-r--r--common/openpgpdefs.h2
-rw-r--r--common/status.h2
-rw-r--r--common/stringhelp.c38
-rw-r--r--common/stringhelp.h4
-rw-r--r--common/sysutils.c4
-rw-r--r--common/t-ccparray.c93
-rw-r--r--common/t-stringhelp.c78
-rw-r--r--common/util.h8
-rw-r--r--configure.ac27
-rw-r--r--dirmngr/Makefile.am9
-rw-r--r--dirmngr/dirmngr-client.c1
-rw-r--r--dirmngr/dirmngr.c29
-rw-r--r--dirmngr/dirmngr.h3
-rw-r--r--dirmngr/dirmngr_ldap.c15
-rw-r--r--dirmngr/http.c2
-rw-r--r--dirmngr/ldap-wrapper.c4
-rw-r--r--dirmngr/server.c25
-rw-r--r--doc/DETAILS38
-rw-r--r--doc/dirmngr.texi1
-rw-r--r--doc/gnupg.texi17
-rw-r--r--doc/gpg-agent.texi26
-rw-r--r--doc/gpg.texi163
-rw-r--r--doc/gpgsm.texi27
-rw-r--r--doc/opt-homedir.texi3
-rw-r--r--doc/scdaemon.texi3
-rw-r--r--doc/sysnotes.texi28
-rw-r--r--doc/tools.texi11
-rw-r--r--doc/yat2m.c1
-rw-r--r--g10/Makefile.am2
-rw-r--r--g10/build-packet.c10
-rw-r--r--g10/call-agent.c143
-rw-r--r--g10/call-agent.h11
-rw-r--r--g10/call-dirmngr.c1
-rw-r--r--g10/delkey.c8
-rw-r--r--g10/export.c261
-rw-r--r--g10/free-packet.c3
-rw-r--r--g10/getkey.c220
-rw-r--r--g10/gpg.c143
-rw-r--r--g10/gpg.h10
-rw-r--r--g10/gpgcompose.c8
-rw-r--r--g10/gpgsql.c (renamed from g10/sqlite.c)30
-rw-r--r--g10/gpgsql.h61
-rw-r--r--g10/gpgv.c30
-rw-r--r--g10/import.c2
-rw-r--r--g10/keydb.c2
-rw-r--r--g10/keydb.h2
-rw-r--r--g10/keyedit.c268
-rw-r--r--g10/keygen.c633
-rw-r--r--g10/keyid.c30
-rw-r--r--g10/keylist.c251
-rw-r--r--g10/keyserver.c6
-rw-r--r--g10/main.h12
-rw-r--r--g10/mainproc.c187
-rw-r--r--g10/migrate.c4
-rw-r--r--g10/options.h7
-rw-r--r--g10/packet.h11
-rw-r--r--g10/parse-packet.c18
-rw-r--r--g10/photoid.c13
-rw-r--r--g10/photoid.h5
-rw-r--r--g10/pkclist.c31
-rw-r--r--g10/progress.c60
-rw-r--r--g10/revoke.c16
-rw-r--r--g10/server.c4
-rw-r--r--g10/seskey.c9
-rw-r--r--g10/sig-check.c13
-rw-r--r--g10/sign.c155
-rw-r--r--g10/sqlite.h62
-rw-r--r--g10/tdbio.c5
-rw-r--r--g10/test-stubs.c24
-rw-r--r--g10/tofu.c1111
-rw-r--r--g10/tofu.h17
-rw-r--r--g10/trust.c31
-rw-r--r--g10/trustdb.c45
-rw-r--r--g10/trustdb.h27
-rw-r--r--g13/be-encfs.c4
-rw-r--r--g13/g13-common.h1
-rw-r--r--g13/g13-syshelp.c10
-rw-r--r--g13/g13.c15
-rw-r--r--g13/server.c4
-rw-r--r--kbx/keybox-defs.h1
-rw-r--r--po/ca.po55
-rw-r--r--po/cs.po60
-rw-r--r--po/da.po60
-rw-r--r--po/de.po62
-rw-r--r--po/el.po55
-rw-r--r--po/eo.po54
-rw-r--r--po/es.po60
-rw-r--r--po/et.po55
-rw-r--r--po/fi.po55
-rw-r--r--po/fr.po58
-rw-r--r--po/gl.po55
-rw-r--r--po/hu.po55
-rw-r--r--po/id.po63
-rw-r--r--po/it.po65
-rw-r--r--po/ja.po461
-rw-r--r--po/nb.po54
-rw-r--r--po/pl.po60
-rw-r--r--po/pt.po54
-rw-r--r--po/ro.po56
-rw-r--r--po/ru.po579
-rw-r--r--po/sk.po55
-rw-r--r--po/sv.po62
-rw-r--r--po/tr.po60
-rw-r--r--po/uk.po674
-rw-r--r--po/zh_CN.po56
-rw-r--r--po/zh_TW.po58
-rw-r--r--scd/command.c6
-rw-r--r--scd/scdaemon.c26
-rw-r--r--scd/scdaemon.h1
-rw-r--r--sm/call-agent.c1
-rw-r--r--sm/call-dirmngr.c2
-rw-r--r--sm/gpgsm.c25
-rw-r--r--sm/gpgsm.h1
-rw-r--r--sm/keydb.c2
-rw-r--r--sm/server.c4
-rw-r--r--tests/openpgp/Makefile.am4
-rwxr-xr-xtests/openpgp/export.test110
-rw-r--r--tests/openpgp/fake-pinentry.c216
-rw-r--r--tools/Makefile.am18
-rw-r--r--tools/gpg-check-pattern.c4
-rw-r--r--tools/gpg-connect-agent.c11
-rw-r--r--tools/gpgconf-comp.c4
-rw-r--r--tools/gpgconf.c74
-rw-r--r--tools/gpgtar-create.c52
-rw-r--r--tools/gpgtar-extract.c23
-rw-r--r--tools/gpgtar-list.c23
-rw-r--r--tools/rfc822parse.c7
-rw-r--r--tools/symcryptrun.c10
158 files changed, 6032 insertions, 3571 deletions
diff --git a/NEWS b/NEWS
index 4aa7a01..3c58883 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,53 @@
+Noteworthy changes in version 2.1.13 (2016-06-16)
+-------------------------------------------------
+
+ * gpg: New command --quick-addkey. Extend the --quick-gen-key
+ command.
+
+ * gpg: New --keyid-format "none" which is now also the default.
+
+ * gpg: New option --with-subkey-fingerprint.
+
+ * gpg: Include Signer's UID subpacket in signatures if the secret key
+ has been specified using a mail address and the new option
+ --disable-signer-uid is not used.
+
+ * gpg: Allow unattended deletion of a secret key.
+
+ * gpg: Allow export of non-passphrase protected secret keys.
+
+ * gpg: New status lines KEY_CONSIDERED and NOTATION_FLAGS.
+
+ * gpg: Change status line TOFU_STATS_LONG to use '~' as
+ a non-breaking-space character.
+
+ * gpg: Speedup key listings in Tofu mode.
+
+ * gpg: Make sure that the current and total values of a PROGRESS
+ status line are small enough.
+
+ * gpgsm: Allow the use of AES192 and SERPENT ciphers.
+
+ * dirmngr: Adjust WKD lookup to current specs.
+
+ * dirmngr: Fallback to LDAP v3 if v2 is is not supported.
+
+ * gpgconf: New commands --create-socketdir and --remove-socketdir,
+ new option --homedir.
+
+ * If a /run/user/$UID directory exists, that directory is now used
+ for IPC sockets instead of the GNUPGHOME directory. This fixes
+ problems with NFS and too long socket names and thus avoids the
+ need for redirection files.
+
+ * The Speedo build systems now uses the new versions.gnupg.org server
+ to retrieve the default package versions.
+
+ * Fix detection of libusb on FreeBSD.
+
+ * Speedup fd closing after a fork.
+
+
Noteworthy changes in version 2.1.12 (2016-05-04)
-------------------------------------------------
diff --git a/agent/agent.h b/agent/agent.h
index 0dcb201..42a580c 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -62,7 +62,6 @@ struct
int quiet; /* Be as quiet as possible */
int dry_run; /* Don't change any persistent data */
int batch; /* Batch mode */
- const char *homedir; /* Configuration directory name */
/* True if we handle sigusr2. */
int sigusr2_enabled;
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 0e1d9fc..e3cd4b9 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -897,7 +897,7 @@ open_control_file (ssh_control_file_t *r_cf, int append)
/* Note: As soon as we start to use non blocking functions here
(i.e. where Pth might switch threads) we need to employ a
mutex. */
- cf->fname = make_filename_try (opt.homedir, SSH_CONTROL_FILE_NAME, NULL);
+ cf->fname = make_filename_try (gnupg_homedir (), SSH_CONTROL_FILE_NAME, NULL);
if (!cf->fname)
{
err = gpg_error_from_syserror ();
@@ -2734,7 +2734,7 @@ ssh_handler_request_identities (ctrl_t ctrl,
{
char *dname;
- dname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
+ dname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, NULL);
if (!dname)
{
err = gpg_err_code_from_syserror ();
diff --git a/agent/command.c b/agent/command.c
index c94fdd3..de5b184 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -207,7 +207,7 @@ clear_nonce_cache (ctrl_t ctrl)
}
-/* This function is called by Libassuan whenever thee client sends a
+/* This function is called by Libassuan whenever the client sends a
reset. It has been registered similar to the other Assuan
commands. */
static gpg_error_t
@@ -857,7 +857,8 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
static const char hlp_genkey[] =
- "GENKEY [--no-protection] [--preset] [--inq-passwd] [<cache_nonce>]\n"
+ "GENKEY [--no-protection] [--preset] [--inq-passwd]\n"
+ " [--passwd-nonce=<s>] [<cache_nonce>]\n"
"\n"
"Generate a new key, store the secret part and return the public\n"
"part. Here is an example transaction:\n"
@@ -873,7 +874,8 @@ static const char hlp_genkey[] =
"When the --preset option is used the passphrase for the generated\n"
"key will be added to the cache. When --inq-passwd is used an inquire\n"
"with the keyword NEWPASSWD is used to request the passphrase for the\n"
- "new key.\n";
+ "new key. When a --passwd-nonce is used, the corresponding cached\n"
+ "passphrase is used to protect the new key.";
static gpg_error_t
cmd_genkey (assuan_context_t ctx, char *line)
{
@@ -885,10 +887,12 @@ cmd_genkey (assuan_context_t ctx, char *line)
unsigned char *newpasswd = NULL;
membuf_t outbuf;
char *cache_nonce = NULL;
+ char *passwd_nonce = NULL;
int opt_preset;
int opt_inq_passwd;
size_t n;
- char *p;
+ char *p, *pend;
+ int c;
if (ctrl->restricted)
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
@@ -896,6 +900,21 @@ cmd_genkey (assuan_context_t ctx, char *line)
no_protection = has_option (line, "--no-protection");
opt_preset = has_option (line, "--preset");
opt_inq_passwd = has_option (line, "--inq-passwd");
+ passwd_nonce = option_value (line, "--passwd-nonce");
+ if (passwd_nonce)
+ {
+ for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
+ ;
+ c = *pend;
+ *pend = '\0';
+ passwd_nonce = xtrystrdup (passwd_nonce);
+ *pend = c;
+ if (!passwd_nonce)
+ {
+ rc = gpg_error_from_syserror ();
+ goto leave;
+ }
+ }
line = skip_options (line);
p = line;
@@ -933,6 +952,8 @@ cmd_genkey (assuan_context_t ctx, char *line)
}
}
+ else if (passwd_nonce)
+ newpasswd = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
rc = agent_genkey (ctrl, cache_nonce, (char*)value, valuelen, no_protection,
newpasswd, opt_preset, &outbuf);
@@ -951,6 +972,7 @@ cmd_genkey (assuan_context_t ctx, char *line)
else
rc = write_and_clear_outbuf (ctx, &outbuf);
xfree (cache_nonce);
+ xfree (passwd_nonce);
return leave_cmd (ctx, rc);
}
@@ -1236,7 +1258,8 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
char *dirname;
struct dirent *dir_entry;
- dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
+ dirname = make_filename_try (gnupg_homedir (),
+ GNUPG_PRIVATE_KEYS_DIR, NULL);
if (!dirname)
{
err = gpg_error_from_syserror ();
@@ -1715,6 +1738,24 @@ cmd_passwd (assuan_context_t ctx, char *line)
else if (opt_verify)
{
/* All done. */
+ if (passphrase)
+ {
+ if (!passwd_nonce)
+ {
+ char buf[12];
+ gcry_create_nonce (buf, 12);
+ passwd_nonce = bin2hex (buf, 12, NULL);
+ }
+ if (passwd_nonce
+ && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
+ passphrase, CACHE_TTL_NONCE))
+ {
+ assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
+ xfree (ctrl->server_local->last_passwd_nonce);
+ ctrl->server_local->last_passwd_nonce = passwd_nonce;
+ passwd_nonce = NULL;
+ }
+ }
}
else
{
@@ -1785,6 +1826,7 @@ cmd_passwd (assuan_context_t ctx, char *line)
gcry_sexp_release (s_skey);
xfree (shadow_info);
xfree (cache_nonce);
+ xfree (passwd_nonce);
return leave_cmd (ctx, err);
}
@@ -2168,7 +2210,12 @@ static const char hlp_export_key[] =
"Export a secret key from the key store. The key will be encrypted\n"
"using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
"using the AESWRAP-128 algorithm. The caller needs to retrieve that key\n"
- "prior to using this command. The function takes the keygrip as argument.\n";
+ "prior to using this command. The function takes the keygrip as argument.\n"
+ "\n"
+ "If --openpgp is used, the secret key material will be exported in RFC 4880\n"
+ "compatible passphrase-protected form. Without --openpgp, the secret key\n"
+ "material will be exported in the clear (after prompting the user to unlock\n"
+ "it, if needed).\n";
static gpg_error_t
cmd_export_key (assuan_context_t ctx, char *line)
{
@@ -2333,8 +2380,9 @@ cmd_export_key (assuan_context_t ctx, char *line)
static const char hlp_delete_key[] =
"DELETE_KEY [--force] <hexstring_with_keygrip>\n"
"\n"
- "Delete a secret key from the key store.\n"
- "Unless --force is used the agent asks the user for confirmation.\n";
+ "Delete a secret key from the key store. If --force is used\n"
+ "and a loopback pinentry is allowed, the agent will not ask\n"
+ "the user for confirmation.";
static gpg_error_t
cmd_delete_key (assuan_context_t ctx, char *line)
{
@@ -2349,6 +2397,11 @@ cmd_delete_key (assuan_context_t ctx, char *line)
force = has_option (line, "--force");
line = skip_options (line);
+ /* If the use of a loopback pinentry has been disabled, we assume
+ * that a silent deletion of keys shall also not be allowed. */
+ if (!opt.allow_loopback_pinentry)
+ force = 0;
+
err = parse_keygrip (ctx, line, grip);
if (err)
goto leave;
diff --git a/agent/findkey.c b/agent/findkey.c
index a78709c..d3780b9 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -135,7 +135,8 @@ agent_write_private_key (const unsigned char *grip,
bin2hex (grip, 20, hexgrip);
strcpy (hexgrip+40, ".key");
- fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
+ fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
+ hexgrip, NULL);
/* FIXME: Write to a temp file first so that write failures during
key updates won't lead to a key loss. */
@@ -652,7 +653,8 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
bin2hex (grip, 20, hexgrip);
strcpy (hexgrip+40, ".key");
- fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
+ fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
+ hexgrip, NULL);
fp = es_fopen (fname, "rb");
if (!fp)
{
@@ -767,7 +769,8 @@ remove_key_file (const unsigned char *grip)
bin2hex (grip, 20, hexgrip);
strcpy (hexgrip+40, ".key");
- fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
+ fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
+ hexgrip, NULL);
if (gnupg_remove (fname))
err = gpg_error_from_syserror ();
xfree (fname);
@@ -1289,7 +1292,8 @@ agent_key_available (const unsigned char *grip)
bin2hex (grip, 20, hexgrip);
strcpy (hexgrip+40, ".key");
- fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
+ fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
+ hexgrip, NULL);
result = !access (fname, R_OK)? 0 : -1;
xfree (fname);
return result;
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index a950530..90b0eaf 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -1,6 +1,6 @@
/* gpg-agent.c - The GnuPG Agent
* Copyright (C) 2000-2007, 2009-2010 Free Software Foundation, Inc.
- * Copyright (C) 2000-2014 Werner Koch
+ * Copyright (C) 2000-2016 Werner Koch
*
* This file is part of GnuPG.
*
@@ -555,19 +555,10 @@ remove_socket (char *name, char *redir_name)
{
if (name && *name)
{
- char *p;
-
if (redir_name)
name = redir_name;
gnupg_remove (name);
- p = strrchr (name, '/');
- if (p)
- {
- *p = 0;
- rmdir (name);
- *p = '/';
- }
*name = 0;
}
}
@@ -804,8 +795,6 @@ main (int argc, char **argv )
if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
csh_style = 1;
- opt.homedir = default_homedir ();
-
/* Record some of the original environment strings. */
{
const char *s;
@@ -861,7 +850,7 @@ main (int argc, char **argv )
else if (pargs.r_opt == oNoOptions)
default_config = 0; /* --no-options */
else if (pargs.r_opt == oHomedir)
- opt.homedir = pargs.r.ret_str;
+ gnupg_set_homedir (pargs.r.ret_str);
else if (pargs.r_opt == oDebugQuickRandom)
{
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
@@ -878,8 +867,8 @@ main (int argc, char **argv )
*/
if (default_config)
- configname = make_filename (opt.homedir, GPG_AGENT_NAME EXTSEP_S "conf",
- NULL );
+ configname = make_filename (gnupg_homedir (),
+ GPG_AGENT_NAME EXTSEP_S "conf", NULL);
argc = orig_argc;
argv = orig_argv;
@@ -944,7 +933,7 @@ main (int argc, char **argv )
case oNoGreeting: /* Dummy option. */ break;
case oNoVerbose: opt.verbose = 0; break;
case oNoOptions: break; /* no-options */
- case oHomedir: opt.homedir = pargs.r.ret_str; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oNoDetach: nodetach = 1; break;
case oLogFile: logfile = pargs.r.ret_str; break;
case oCsh: csh_style = 1; break;
@@ -1029,9 +1018,6 @@ main (int argc, char **argv )
finalize_rereadable_options ();
- /* Turn the homedir into an absolute one. */
- opt.homedir = make_absfilename (opt.homedir, NULL);
-
/* Print a warning if an argument looks like an option. */
if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
{
@@ -1104,8 +1090,8 @@ main (int argc, char **argv )
char *filename_esc;
/* List options and default values in the GPG Conf format. */
- filename = make_filename (opt.homedir, GPG_AGENT_NAME EXTSEP_S "conf",
- NULL );
+ filename = make_filename (gnupg_homedir (),
+ GPG_AGENT_NAME EXTSEP_S "conf", NULL);
filename_esc = percent_escape (filename, NULL);
es_printf ("%s-%s.conf:%lu:\"%s\n",
@@ -1764,7 +1750,7 @@ create_socket_name (char *standard_name, int with_homedir)
char *name;
if (with_homedir)
- name = make_filename (opt.homedir, standard_name, NULL);
+ name = make_filename (gnupg_socketdir (), standard_name, NULL);
else
name = make_filename (standard_name, NULL);
if (strchr (name, PATHSEP_C))
@@ -1879,6 +1865,10 @@ create_server_socket (char *name, int primary, int cygwin,
agent_exit (2);
}
+ if (gnupg_chmod (unaddr->sun_path, "-rwx"))
+ log_error (_("can't set permissions of '%s': %s\n"),
+ unaddr->sun_path, strerror (errno));
+
if (listen (FD2INT(fd), 5 ) == -1)
{
log_error (_("listen() failed: %s\n"), strerror (errno));
@@ -1932,7 +1922,7 @@ create_directories (void)
const char *defhome = standard_homedir ();
char *home;
- home = make_filename (opt.homedir, NULL);
+ home = make_filename (gnupg_homedir (), NULL);
if ( stat (home, &statbuf) )
{
if (errno == ENOENT)
@@ -2731,7 +2721,7 @@ check_own_socket (void)
if (check_own_socket_running || shutdown_pending)
return; /* Still running or already shutting down. */
- sockname = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
+ sockname = make_filename_try (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
if (!sockname)
return; /* Out of memory. */
@@ -2757,7 +2747,9 @@ check_for_running_agent (int silent)
char *sockname;
assuan_context_t ctx = NULL;
- sockname = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
+ sockname = make_filename_try (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
+ if (!sockname)
+ return gpg_error_from_syserror ();
err = assuan_new (&ctx);
if (!err)
diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c
index 1ebf181..549ecc3 100644
--- a/agent/preset-passphrase.c
+++ b/agent/preset-passphrase.c
@@ -66,7 +66,6 @@ enum cmd_and_opt_values
aTest };
-static const char *opt_homedir;
static const char *opt_passphrase;
static ARGPARSE_OPTS opts[] = {
@@ -219,8 +218,6 @@ main (int argc, char **argv)
i18n_init ();
init_common_subsystems (&argc, &argv);
- opt_homedir = default_homedir ();
-
pargs.argc = &argc;
pargs.argv = &argv;
pargs.flags= 1; /* (do not remove the args) */
@@ -229,7 +226,7 @@ main (int argc, char **argv)
switch (pargs.r_opt)
{
case oVerbose: opt.verbose++; break;
- case oHomedir: opt_homedir = pargs.r.ret_str; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oPreset: cmd = oPreset; break;
case oForget: cmd = oForget; break;
@@ -248,7 +245,7 @@ main (int argc, char **argv)
/* Tell simple-pwquery about the the standard socket name. */
{
- char *tmp = make_filename (opt_homedir, GPG_AGENT_SOCK_NAME, NULL);
+ char *tmp = make_filename (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
simple_pw_set_socket (tmp);
xfree (tmp);
}
diff --git a/agent/protect-tool.c b/agent/protect-tool.c
index ad036ee..c2bf87d 100644
--- a/agent/protect-tool.c
+++ b/agent/protect-tool.c
@@ -86,7 +86,6 @@ struct rsa_secret_key_s
};
-static const char *opt_homedir;
static int opt_armor;
static int opt_canonical;
static int opt_store;
@@ -577,9 +576,6 @@ main (int argc, char **argv )
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
- opt_homedir = default_homedir ();
-
-
pargs.argc = &argc;
pargs.argv = &argv;
pargs.flags= 1; /* (do not remove the args) */
@@ -590,7 +586,7 @@ main (int argc, char **argv )
case oVerbose: opt.verbose++; break;
case oArmor: opt_armor=1; break;
case oCanonical: opt_canonical=1; break;
- case oHomedir: opt_homedir = pargs.r.ret_str; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oAgentProgram: opt_agent_program = pargs.r.ret_str; break;
@@ -634,7 +630,6 @@ main (int argc, char **argv )
/* Set the information which can't be taken from envvars. */
gnupg_prepare_get_passphrase (GPG_ERR_SOURCE_DEFAULT,
opt.verbose,
- opt_homedir,
opt_agent_program,
NULL, NULL, NULL);
diff --git a/agent/trustlist.c b/agent/trustlist.c
index af5f645..b8df3fd 100644
--- a/agent/trustlist.c
+++ b/agent/trustlist.c
@@ -344,7 +344,14 @@ read_trustfiles (void)
return gpg_error_from_syserror ();
tableidx = 0;
- fname = make_filename (opt.homedir, "trustlist.txt", NULL);
+ fname = make_filename_try (gnupg_homedir (), "trustlist.txt", NULL);
+ if (!fname)
+ {
+ err = gpg_error_from_syserror ();
+ xfree (table);
+ return err;
+ }
+
if ( access (fname, F_OK) )
{
if ( errno == ENOENT )
@@ -608,7 +615,10 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
trustlist with only admin priviliges to modify it. Of course
this is not a secure way of denying access, but it avoids the
usual clicking on an Okay button most users are used to. */
- fname = make_filename (opt.homedir, "trustlist.txt", NULL);
+ fname = make_filename_try (gnupg_homedir (), "trustlist.txt", NULL);
+ if (!fname)
+ return gpg_error_from_syserror ();
+
if ( access (fname, W_OK) && errno != ENOENT)
{
xfree (fname);
@@ -733,7 +743,15 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
return is_disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0;
}
- fname = make_filename (opt.homedir, "trustlist.txt", NULL);
+ fname = make_filename_try (gnupg_homedir (), "trustlist.txt", NULL);
+ if (!fname)
+ {
+ err = gpg_error_from_syserror ();
+ unlock_trusttable ();
+ xfree (fprformatted);
+ xfree (nameformatted);
+ return err;
+ }
if ( access (fname, F_OK) && errno == ENOENT)
{
fp = es_fopen (fname, "wx,mode=-rw-r");
diff --git a/autogen.sh b/autogen.sh
index 7d843bd..10cc203 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -423,7 +423,7 @@ if [ -d .git ]; then
[ -z "${SILENT}" ] && cat <<EOF
*** Activating trailing whitespace git pre-commit hook. ***
For more information see this thread:
- http://mail.gnome.org/archives/desktop-devel-list/2009-May/msg00084html
+ http://mail.gnome.org/archives/desktop-devel-list/2009-May/msg00084.html
To deactivate this pre-commit hook again move .git/hooks/pre-commit
and .git/hooks/pre-commit.sample out of the way.
EOF
diff --git a/build-aux/getswdb.sh b/build-aux/getswdb.sh
index 4a1730b..83ecdb2 100755
--- a/build-aux/getswdb.sh
+++ b/build-aux/getswdb.sh
@@ -11,9 +11,7 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# The URL of the file to retrieve.
-# (some wget versions seem to have problems with SubjectAltName, thus
-# we do not use www.gnupg.org)
-urlbase="https://gnupg.org/"
+urlbase="https://versions.gnupg.org/"
WGET=wget
GPGV=gpgv
diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk
index d286655..67ccbb4 100644
--- a/build-aux/speedo.mk
+++ b/build-aux/speedo.mk
@@ -448,7 +448,9 @@ speedo_pkg_libgcrypt_configure = --disable-static
speedo_pkg_libksba_configure = --disable-static
ifeq ($(TARGETOS),w32)
-speedo_pkg_gnupg_configure = --enable-gpg2-is-gpg --disable-g13 --disable-ntbtls
+speedo_pkg_gnupg_configure = \
+ --enable-gpg2-is-gpg --disable-g13 --disable-ntbtls \
+ --enable-build-timestamp
else
speedo_pkg_gnupg_configure = --disable-g13
endif
diff --git a/build-aux/speedo/w32/inst.nsi b/build-aux/speedo/w32/inst.nsi
index 2c671c2..24d5d4d 100644
--- a/build-aux/speedo/w32/inst.nsi
+++ b/build-aux/speedo/w32/inst.nsi
@@ -579,6 +579,7 @@ Section "GnuPG" SEC_gnupg
File "bin/gpgconf.exe"
File "bin/gpg-connect-agent.exe"
File "bin/gpgtar.exe"
+ File "libexec/gpg-preset-passphrase.exe"
ClearErrors
SetOverwrite try
@@ -1275,6 +1276,7 @@ Section "-un.gnupg"
Delete "$INSTDIR\bin\gpgconf.exe"
Delete "$INSTDIR\bin\gpg-connect-agent.exe"
Delete "$INSTDIR\bin\gpgtar.exe"
+ Delete "$INSTDIR\bin\gpg-preset-passphrase.exe"
Delete "$INSTDIR\share\gnupg\dirmngr-conf.skel"
Delete "$INSTDIR\share\gnupg\distsigkey.gpg"
diff --git a/common/Makefile.am b/common/Makefile.am
index 4a35f64..884c966 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -72,6 +72,7 @@ common_sources = \
xasprintf.c \
xreadline.c \
membuf.c membuf.h \
+ ccparray.c ccparray.h \
iobuf.c iobuf.h \
ttyio.c ttyio.h \
asshelp.c asshelp2.c asshelp.h \
@@ -156,7 +157,7 @@ module_tests = t-stringhelp t-timestuff \
t-convert t-percent t-gettime t-sysutils t-sexputil \
t-session-env t-openpgp-oid t-ssh-utils \
t-mapstrings t-zb32 t-mbox-util t-iobuf t-strlist \
- t-private-keys
+ t-private-keys t-ccparray
if !HAVE_W32CE_SYSTEM
module_tests += t-exechelp
endif
@@ -206,6 +207,7 @@ t_mbox_util_LDADD = $(t_common_ldadd)
t_iobuf_LDADD = $(t_common_ldadd)
t_strlist_LDADD = $(t_common_ldadd)
t_private_keys_LDADD = $(t_common_ldadd)
+t_ccparray_LDADD = $(t_common_ldadd)
# System specific test
if HAVE_W32_SYSTEM
diff --git a/common/asshelp.c b/common/asshelp.c
index f2b4402..5c32c6e 100644
--- a/common/asshelp.c
+++ b/common/asshelp.c
@@ -351,7 +351,6 @@ unlock_spawning (lock_spawn_t *lock, const char *name)
gpg_error_t
start_new_gpg_agent (assuan_context_t *r_ctx,
gpg_err_source_t errsource,
- const char *homedir,
const char *agent_program,
const char *opt_lc_ctype,
const char *opt_lc_messages,
@@ -375,7 +374,14 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
return err;
}
- sockname = make_absfilename (homedir, GPG_AGENT_SOCK_NAME, NULL);
+ sockname = make_filename_try (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
+ if (!sockname)
+ {
+ err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+ assuan_release (ctx);
+ return err;
+ }
+
err = assuan_socket_connect (ctx, sockname, 0, 0);
if (err && autostart)
{
@@ -418,7 +424,7 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
/* We better pass an absolute home directory to the agent just
in case gpg-agent does not convert the passed name to an
absolute one (which it should do). */
- abs_homedir = make_absfilename_try (homedir, NULL);
+ abs_homedir = make_absfilename_try (gnupg_homedir (), NULL);
if (!abs_homedir)
{
gpg_error_t tmperr = gpg_err_make (errsource,
@@ -455,7 +461,7 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
argv[i++] = "--daemon";
argv[i++] = NULL;
- if (!(err = lock_spawning (&lock, homedir, "agent", verbose))
+ if (!(err = lock_spawning (&lock, gnupg_homedir (), "agent", verbose))
&& assuan_socket_connect (ctx, sockname, 0, 0))
{
err = gnupg_spawn_process_detached (program? program : agent_program,
@@ -538,7 +544,6 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
gpg_error_t
start_new_dirmngr (assuan_context_t *r_ctx,
gpg_err_source_t errsource,
- const char *homedir,
const char *dirmngr_program,
int autostart,
int verbose, int debug,
@@ -605,7 +610,7 @@ start_new_dirmngr (assuan_context_t *r_ctx,
status_cb (status_cb_arg, STATUS_PROGRESS,
"starting_dirmngr ? 0 0", NULL);
- abs_homedir = make_absfilename (homedir, NULL);
+ abs_homedir = make_absfilename (gnupg_homedir (), NULL);
if (!abs_homedir)
{
gpg_error_t tmperr = gpg_err_make (errsource,
@@ -641,7 +646,7 @@ start_new_dirmngr (assuan_context_t *r_ctx,
TRY_SYSTEM_DAEMON should never be true because
dirmngr_user_socket_name() won't return NULL. */
- if (!(err = lock_spawning (&lock, homedir, "dirmngr", verbose))
+ if (!(err = lock_spawning (&lock, gnupg_homedir (), "dirmngr", verbose))
&& assuan_socket_connect (ctx, sockname, 0, 0))
{
err = gnupg_spawn_process_detached (dirmngr_program, argv, NULL);
@@ -678,7 +683,6 @@ start_new_dirmngr (assuan_context_t *r_ctx,
xfree (abs_homedir);
}
#else
- (void)homedir;
(void)dirmngr_program;
(void)verbose;
(void)status_cb;
diff --git a/common/asshelp.h b/common/asshelp.h
index 20414bd..4eb1d92 100644
--- a/common/asshelp.h
+++ b/common/asshelp.h
@@ -54,7 +54,6 @@ send_pinentry_environment (assuan_context_t ctx,
gpg_error_t
start_new_gpg_agent (assuan_context_t *r_ctx,
gpg_err_source_t errsource,
- const char *homedir,
const char *agent_program,
const char *opt_lc_ctype,
const char *opt_lc_messages,
@@ -68,7 +67,6 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
gpg_error_t
start_new_dirmngr (assuan_context_t *r_ctx,
gpg_err_source_t errsource,
- const char *homedir,
const char *dirmngr_program,
int autostart, int verbose, int debug,
gpg_error_t (*status_cb)(ctrl_t, int, ...),
diff --git a/common/call-gpg.c b/common/call-gpg.c
index f5a62ec..0bda1d3 100644
--- a/common/call-gpg.c
+++ b/common/call-gpg.c
@@ -430,9 +430,9 @@ _gpg_encrypt (ctrl_t ctrl,
assert ((reader_mb == NULL) != (cipher_stream == NULL));
/* Create two pipes. */
- err = gnupg_create_outbound_pipe (outbound_fds);
+ err = gnupg_create_outbound_pipe (outbound_fds, NULL, 0);
if (!err)
- err = gnupg_create_inbound_pipe (inbound_fds);
+ err = gnupg_create_inbound_pipe (inbound_fds, NULL, 0);
if (err)
{
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
@@ -614,9 +614,9 @@ _gpg_decrypt (ctrl_t ctrl,
assert ((reader_mb == NULL) != (plain_stream == NULL));
/* Create two pipes. */
- err = gnupg_create_outbound_pipe (outbound_fds);
+ err = gnupg_create_outbound_pipe (outbound_fds, NULL, 0);
if (!err)
- err = gnupg_create_inbound_pipe (inbound_fds);
+ err = gnupg_create_inbound_pipe (inbound_fds, NULL, 0);
if (err)
{
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
diff --git a/common/ccparray.c b/common/ccparray.c
new file mode 100644
index 0000000..490dbf5
--- /dev/null
+++ b/common/ccparray.c
@@ -0,0 +1,147 @@
+/* ccparray.c - A simple dynamic array for character pointer.
+ * Copyright (C) 2016 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ * - the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * or
+ *
+ * - the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdarg.h>
+
+#include "util.h"
+#include "ccparray.h"
+
+
+/* A simple implementation of a dynamic array of const char pointers.
+ * The example code:
+ *
+ * ccparray_t ccp;
+ * const char **argv;
+ * int i;
+ *
+ * ccparray_init (&ccp, 0);
+ * ccparray_put (&ccp, "First arg");
+ * ccparray_put (&ccp, "Second arg");
+ * ccparray_put (&ccp, NULL);
+ * ccparray_put (&ccp, "Fourth arg");
+ * argv = ccparray_get (&ccp, NULL);
+ * if (!argv)
+ * die ("error building array: %s\n", strerror (errno));
+ * for (i=0; argv[i]; i++)
+ * printf ("[%d] = '%s'\n", i, argv[i]);
+ * xfree (argv);
+ *
+ * will result in this output:
+ *
+ * [0] = 'First arg'
+ * [1] = 'Second arg'
+ *
+ * Note that allocation errors are detected but only returned with the
+ * final ccparray_get(); this helps not to clutter the code with out
+ * of core checks.
+ */
+
+void
+ccparray_init (ccparray_t *cpa, unsigned int initialsize)
+{
+ if (!initialsize)
+ cpa->size = 16;
+ else if (initialsize < (1<<16))
+ cpa->size = initialsize;
+ else
+ cpa->size = (1<<16);
+
+ cpa->count = 0;
+ cpa->out_of_core = 0;
+ cpa->array = xtrycalloc (cpa->size, sizeof *cpa->array);
+ if (!cpa->array)
+ cpa->out_of_core = errno;
+}
+
+
+void
+ccparray_put (ccparray_t *cpa, const char *value)
+{
+ if (cpa->out_of_core)
+ return;
+
+ if (cpa->count + 1 >= cpa->size)
+ {
+ const char **newarray;
+ size_t n, newsize;
+
+ if (cpa->size < 8)
+ newsize = 16;
+ else if (cpa->size < 4096)
+ newsize = 2 * cpa->size;
+ else if (cpa->size < (1<<16))
+ newsize = cpa->size + 2048;
+ else
+ {
+ cpa->out_of_core = ENOMEM;
+ return;
+ }
+
+ newarray = xtrycalloc (newsize, sizeof *newarray);
+ if (!newarray)
+ {
+ cpa->out_of_core = errno ? errno : ENOMEM;
+ return;
+ }
+ for (n=0; n < cpa->size; n++)
+ newarray[n] = cpa->array[n];
+ cpa->array = newarray;
+ cpa->size = newsize;
+
+ }
+ cpa->array[cpa->count++] = value;
+}
+
+
+const char **
+ccparray_get (ccparray_t *cpa, size_t *r_count)
+{
+ const char **result;
+
+ if (cpa->out_of_core)
+ {
+ if (cpa->array)
+ {
+ xfree (cpa->array);
+ cpa->array = NULL;
+ }
+ gpg_err_set_errno (cpa->out_of_core);
+ return NULL;
+ }
+
+ result= cpa->array;
+ if (r_count)
+ *r_count = cpa->count;
+ cpa->array = NULL;
+ cpa->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */
+ return result;
+}
diff --git a/common/ccparray.h b/common/ccparray.h
new file mode 100644
index 0000000..241d42d
--- /dev/null
+++ b/common/ccparray.h
@@ -0,0 +1,51 @@
+/* ccparray.c - A simple dynamic array for character pointer.
+ * Copyright (C) 2016 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ * - the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * or
+ *
+ * - the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_COMMON_CCPARRAY_H
+#define GNUPG_COMMON_CCPARRAY_H
+
+/* The definition of the structure is private, we only need it here,
+ * so it can be allocated on the stack. */
+struct _ccparray_private_s
+{
+ unsigned int count;
+ unsigned int size;
+ int out_of_core;
+ const char **array;
+};
+
+typedef struct _ccparray_private_s ccparray_t;
+
+
+void ccparray_init (ccparray_t *cpa, unsigned int initialsize);
+void ccparray_put (ccparray_t *cpa, const char *value);
+const char **ccparray_get (ccparray_t *cpa, size_t *r_nelems);
+
+
+#endif /*GNUPG_COMMON_CCPARRAY_H*/
diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c
index 6614eb7..aefb653 100644
--- a/common/exechelp-posix.c
+++ b/common/exechelp-posix.c
@@ -67,12 +67,31 @@
# include <sys/stat.h>
#endif
+#if __linux__
+# include <sys/types.h>
+# include <dirent.h>
+#endif /*__linux__ */
+
#include "util.h"
#include "i18n.h"
#include "sysutils.h"
#include "exechelp.h"
+/* Helper */
+static inline gpg_error_t
+my_error_from_syserror (void)
+{
+ return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+}
+
+static inline gpg_error_t
+my_error (int errcode)
+{
+ return gpg_err_make (default_errsource, errcode);
+}
+
+
/* Return the maximum number of currently allowed open file
descriptors. Only useful on POSIX systems but returns a value on
other systems too. */
@@ -83,6 +102,43 @@ get_max_fds (void)
#ifdef HAVE_GETRLIMIT
struct rlimit rl;
+ /* Under Linux we can figure out the highest used file descriptor by
+ * reading /proc/PID/fd. This is in the common cases much fast than
+ * for example doing 4096 close calls where almost all of them will
+ * fail. On a system with a limit of 4096 files and only 8 files
+ * open with the highest number being 10, we speedup close_all_fds
+ * from 125ms to 0.4ms including readdir.
+ *
+ * Another option would be to close the file descriptors as returned
+ * from reading that directory - however then we need to snapshot
+ * that list before starting to close them. */
+#ifdef __linux__
+ {
+ DIR *dir = NULL;
+ struct dirent *dir_entry;
+ const char *s;
+ int x;
+
+ dir = opendir ("/proc/self/fd");
+ if (dir)
+ {
+ while ((dir_entry = readdir (dir)))
+ {
+ s = dir_entry->d_name;
+ if ( *s < '0' || *s > '9')
+ continue;
+ x = atoi (s);
+ if (x > max_fds)
+ max_fds = x;
+ }
+ closedir (dir);
+ }
+ if (max_fds != -1)
+ return max_fds + 1;
+ }
+#endif /* __linux__ */
+
+
# ifdef RLIMIT_NOFILE
if (!getrlimit (RLIMIT_NOFILE, &rl))
max_fds = rl.rlim_max;
@@ -222,7 +278,7 @@ get_all_open_fds (void)
static void
do_exec (const char *pgmname, const char *argv[],
int fd_in, int fd_out, int fd_err,
- void (*preexec)(void) )
+ int *except, void (*preexec)(void) )
{
char **arg_list;
int i, j;
@@ -268,7 +324,7 @@ do_exec (const char *pgmname, const char *argv[],
}
/* Close all other files. */
- close_all_fds (3, NULL);
+ close_all_fds (3, except);
if (preexec)
preexec ();
@@ -285,64 +341,36 @@ do_create_pipe (int filedes[2])
if (pipe (filedes) == -1)
{
- err = gpg_error_from_syserror ();
+ err = my_error_from_syserror ();
filedes[0] = filedes[1] = -1;
}
return err;
}
-/* Portable function to create a pipe. Under Windows the write end is
- inheritable. */
-gpg_error_t
-gnupg_create_inbound_pipe (int filedes[2])
-{
- return do_create_pipe (filedes);
-}
-
-
-/* Portable function to create a pipe. Under Windows the read end is
- inheritable. */
-gpg_error_t
-gnupg_create_outbound_pipe (int filedes[2])
-{
- return do_create_pipe (filedes);
-}
-
-
-/* Portable function to create a pipe. Under Windows both ends are
- inheritable. */
-gpg_error_t
-gnupg_create_pipe (int filedes[2])
-{
- return do_create_pipe (filedes);
-}
-
-
static gpg_error_t
create_pipe_and_estream (int filedes[2], estream_t *r_fp,
- int outbound, int nonblock,
- gpg_err_source_t errsource)
+ int outbound, int nonblock)
{
gpg_error_t err;
if (pipe (filedes) == -1)
{
- err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+ err = my_error_from_syserror ();
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
filedes[0] = filedes[1] = -1;
*r_fp = NULL;
return err;
}
- if (outbound)
+ if (!outbound)
*r_fp = es_fdopen (filedes[0], nonblock? "r,nonblock" : "r");
else
*r_fp = es_fdopen (filedes[1], nonblock? "w,nonblock" : "w");
if (!*r_fp)
{
- err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+ err = my_error_from_syserror ();
log_error (_("error creating a stream for a pipe: %s\n"),
gpg_strerror (err));
close (filedes[0]);
@@ -354,12 +382,45 @@ create_pipe_and_estream (int filedes[2], estream_t *r_fp,
}
+/* Portable function to create a pipe. Under Windows the write end is
+ inheritable. If R_FP is not NULL, an estream is created for the
+ read end and stored at R_FP. */
+gpg_error_t
+gnupg_create_inbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
+{
+ if (r_fp)
+ return create_pipe_and_estream (filedes, r_fp, 0, nonblock);
+ else
+ return do_create_pipe (filedes);
+}
+
+
+/* Portable function to create a pipe. Under Windows the read end is
+ inheritable. If R_FP is not NULL, an estream is created for the
+ write end and stored at R_FP. */
+gpg_error_t
+gnupg_create_outbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
+{
+ if (r_fp)
+ return create_pipe_and_estream (filedes, r_fp, 1, nonblock);
+ else
+ return do_create_pipe (filedes);
+}
+
+
+/* Portable function to create a pipe. Under Windows both ends are
+ inheritable. */
+gpg_error_t
+gnupg_create_pipe (int filedes[2])
+{
+ return do_create_pipe (filedes);
+}
+
/* Fork and exec the PGMNAME, see exechelp.h for details. */
gpg_error_t
gnupg_spawn_process (const char *pgmname, const char *argv[],
- gpg_err_source_t errsource,
- void (*preexec)(void), unsigned int flags,
+ int *except, void (*preexec)(void), unsigned int flags,
estream_t *r_infp,
estream_t *r_outfp,
estream_t *r_errfp,
@@ -384,14 +445,14 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
if (r_infp)
{
- err = create_pipe_and_estream (inpipe, &infp, 0, nonblock, errsource);
+ err = create_pipe_and_estream (inpipe, &infp, 1, nonblock);
if (err)
return err;
}
if (r_outfp)
{
- err = create_pipe_and_estream (outpipe, &outfp, 1, nonblock, errsource);
+ err = create_pipe_and_estream (outpipe, &outfp, 0, nonblock);
if (err)
{
if (infp)
@@ -407,7 +468,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
if (r_errfp)
{
- err = create_pipe_and_estream (errpipe, &errfp, 1, nonblock, errsource);
+ err = create_pipe_and_estream (errpipe, &errfp, 0, nonblock);
if (err)
{
if (infp)
@@ -432,7 +493,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
*pid = fork ();
if (*pid == (pid_t)(-1))
{
- err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+ err = my_error_from_syserror ();
log_error (_("error forking process: %s\n"), gpg_strerror (err));
if (infp)
@@ -464,7 +525,8 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
gcry_control (GCRYCTL_TERM_SECMEM);
es_fclose (outfp);
es_fclose (errfp);
- do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1], preexec);
+ do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1],
+ except, preexec);
/*NOTREACHED*/
}
@@ -505,7 +567,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
*pid = fork ();
if (*pid == (pid_t)(-1))
{
- err = gpg_error_from_syserror ();
+ err = my_error_from_syserror ();
log_error (_("error forking process: %s\n"), strerror (errno));
return err;
}
@@ -514,7 +576,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
{
gcry_control (GCRYCTL_TERM_SECMEM);
/* Run child. */
- do_exec (pgmname, argv, infd, outfd, errfd, NULL);
+ do_exec (pgmname, argv, infd, outfd, errfd, NULL, NULL);
/*NOTREACHED*/
}
@@ -543,7 +605,7 @@ gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count,
r_exitcodes[i] = -1;
if (pids[i] == (pid_t)(-1))
- return gpg_error (GPG_ERR_INV_VALUE);
+ return my_error (GPG_ERR_INV_VALUE);
}
left = count;
@@ -638,16 +700,16 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
int i;
if (getuid() != geteuid())
- return gpg_error (GPG_ERR_BUG);
+ return my_error (GPG_ERR_BUG);
if (access (pgmname, X_OK))
- return gpg_error_from_syserror ();
+ return my_error_from_syserror ();
pid = fork ();
if (pid == (pid_t)(-1))
{
log_error (_("error forking process: %s\n"), strerror (errno));
- return gpg_error_from_syserror ();
+ return my_error_from_syserror ();
}
if (!pid)
{
@@ -667,7 +729,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
for (i=0; envp[i]; i++)
putenv (xstrdup (envp[i]));
- do_exec (pgmname, argv, -1, -1, -1, NULL);
+ do_exec (pgmname, argv, -1, -1, -1, NULL, NULL);
/*NOTREACHED*/
}
diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c
index 3e407d2..b2d2457 100644
--- a/common/exechelp-w32.c
+++ b/common/exechelp-w32.c
@@ -320,20 +320,28 @@ do_create_pipe (int filedes[2], int flags)
}
/* Portable function to create a pipe. Under Windows the write end is
- inheritable. */
+ inheritable. If R_FP is not NULL, an estream is created for the
+ read end and stored at R_FP. */
gpg_error_t
-gnupg_create_inbound_pipe (int filedes[2])
+gnupg_create_inbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
{
- return do_create_pipe (filedes, INHERIT_WRITE);
+ if (r_fp)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ else
+ return do_create_pipe (filedes, INHERIT_WRITE);
}
/* Portable function to create a pipe. Under Windows the read end is
- inheritable. */
+ inheritable. If R_FP is not NULL, an estream is created for the
+ write end and stored at R_FP. */
gpg_error_t
-gnupg_create_outbound_pipe (int filedes[2])
+gnupg_create_outbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
{
- return do_create_pipe (filedes, INHERIT_READ);
+ if (r_fp)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ else
+ return do_create_pipe (filedes, INHERIT_READ);
}
@@ -349,8 +357,7 @@ gnupg_create_pipe (int filedes[2])
/* Fork and exec the PGMNAME, see exechelp.h for details. */
gpg_error_t
gnupg_spawn_process (const char *pgmname, const char *argv[],
- gpg_err_source_t errsource,
- void (*preexec)(void), unsigned int flags,
+ int *except, void (*preexec)(void), unsigned int flags,
estream_t *r_infp,
estream_t *r_outfp,
estream_t *r_errfp,
@@ -379,6 +386,9 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
INVALID_HANDLE_VALUE};
int i;
es_syshd_t syshd;
+ gpg_err_source_t errsource = default_errsource;
+
+ (void)except; /* Not yet used. */
if (r_infp)
*r_infp = NULL;
diff --git a/common/exechelp-w32ce.c b/common/exechelp-w32ce.c
index e208f6e..9e72cef 100644
--- a/common/exechelp-w32ce.c
+++ b/common/exechelp-w32ce.c
@@ -450,18 +450,24 @@ create_inheritable_pipe (int filedes[2], int inherit_idx)
/* Portable function to create a pipe. Under Windows the write end is
inheritable (i.e. an rendezvous id). */
gpg_error_t
-gnupg_create_inbound_pipe (int filedes[2])
+gnupg_create_inbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
{
- return create_inheritable_pipe (filedes, 1);
+ if (r_fp)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ else
+ return create_inheritable_pipe (filedes, 1);
}
/* Portable function to create a pipe. Under Windows the read end is
inheritable (i.e. an rendezvous id). */
gpg_error_t
-gnupg_create_outbound_pipe (int filedes[2])
+gnupg_create_outbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
{
- return create_inheritable_pipe (filedes, 0);
+ if (r_fp)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ else
+ return create_inheritable_pipe (filedes, 0);
}
@@ -509,8 +515,7 @@ create_process (const char *pgmname, const char *cmdline,
/* Fork and exec the PGMNAME, see exechelp.h for details. */
gpg_error_t
gnupg_spawn_process (const char *pgmname, const char *argv[],
- gpg_err_source_t errsource,
- void (*preexec)(void), unsigned int flags,
+ int *except, void (*preexec)(void), unsigned int flags,
estream_t *r_infp,
estream_t *r_outfp,
estream_t *r_errfp,
@@ -534,7 +539,9 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
} errpipe = {INVALID_HANDLE_VALUE, 0};
estream_t outfp = NULL;
estream_t errfp = NULL;
+ gpg_err_source_t errsource = default_errsource;
+ (void)except; /* Not yet used. */
(void)preexec;
(void)flags;
diff --git a/common/exechelp.h b/common/exechelp.h
index 82224fd..c43cd25 100644
--- a/common/exechelp.h
+++ b/common/exechelp.h
@@ -52,12 +52,16 @@ int *get_all_open_fds (void);
/* Portable function to create a pipe. Under Windows the write end is
- inheritable. */
-gpg_error_t gnupg_create_inbound_pipe (int filedes[2]);
+ inheritable. If R_FP is not NULL, an estream is created for the
+ write end and stored at R_FP. */
+gpg_error_t gnupg_create_inbound_pipe (int filedes[2],
+ estream_t *r_fp, int nonblock);
/* Portable function to create a pipe. Under Windows the read end is
- inheritable. */
-gpg_error_t gnupg_create_outbound_pipe (int filedes[2]);
+ inheritable. If R_FP is not NULL, an estream is created for the
+ write end and stored at R_FP. */
+gpg_error_t gnupg_create_outbound_pipe (int filedes[2],
+ estream_t *r_fp, int nonblock);
/* Portable function to create a pipe. Under Windows both ends are
inheritable. */
@@ -86,6 +90,10 @@ gpg_error_t gnupg_create_pipe (int filedes[2]);
If PREEXEC is not NULL, the given function will be called right
before the exec.
+ IF EXCEPT is not NULL, it is expected to be an ordered list of file
+ descriptors, terminated by an entry with the value (-1). These
+ file descriptors won't be closed before spawning a new program.
+
Returns 0 on success or an error code. Calling gnupg_wait_process
and gnupg_release_process is required if the function succeeded.
@@ -112,8 +120,7 @@ gpg_error_t gnupg_create_pipe (int filedes[2]);
*/
gpg_error_t
gnupg_spawn_process (const char *pgmname, const char *argv[],
- gpg_err_source_t errsource,
- void (*preexec)(void), unsigned int flags,
+ int *execpt, void (*preexec)(void), unsigned int flags,
estream_t *r_infp,
estream_t *r_outfp,
estream_t *r_errfp,
diff --git a/common/exectool.c b/common/exectool.c
index 7b3a8f1..897450e 100644
--- a/common/exectool.c
+++ b/common/exectool.c
@@ -44,13 +44,17 @@
#include "exechelp.h"
#include "sysutils.h"
#include "util.h"
+#include "exectool.h"
typedef struct
{
const char *pgmname;
+ exec_tool_status_cb_t status_cb;
+ void *status_cb_value;
int cont;
- int used;
- char buffer[256];
+ size_t used;
+ size_t buffer_size;
+ char *buffer;
} read_and_log_buffer_t;
@@ -83,14 +87,37 @@ read_and_log_stderr (read_and_log_buffer_t *state, es_poll_t *fderr)
pname++;
else
pname = state->pgmname;
- /* If our pgmname plus colon is identical to the start of
- the output, print only the output. */
len = strlen (pname);
- if (!state->cont
+
+ if (state->status_cb
+ && !strncmp (state->buffer, "[GNUPG:] ", 9)
+ && state->buffer[9] >= 'A' && state->buffer[9] <= 'Z')
+ {
+ char *rest;
+
+ rest = strchr (state->buffer + 9, ' ');
+ if (!rest)
+ {
+ /* Set REST to an empty string. */
+ rest = state->buffer + strlen (state->buffer);
+ }
+ else
+ {
+ *rest++ = 0;
+ trim_spaces (rest);
+ }
+ state->status_cb (state->status_cb_value,
+ state->buffer + 9, rest);
+ }
+ else if (!state->cont
&& !strncmp (state->buffer, pname, len)
&& strlen (state->buffer) > strlen (pname)
&& state->buffer[len] == ':' )
- log_info ("%s\n", state->buffer);
+ {
+ /* PGMNAME plus colon is identical to the start of
+ the output: print only the output. */
+ log_info ("%s\n", state->buffer);
+ }
else
log_info ("%s%c %s\n",
pname, state->cont? '+':':', state->buffer);
@@ -123,10 +150,39 @@ read_and_log_stderr (read_and_log_buffer_t *state, es_poll_t *fderr)
}
else
{
- if (state->used >= sizeof state->buffer - 1)
+ if (state->used >= state->buffer_size - 1)
{
- read_and_log_stderr (state, NULL);
- state->cont = 1;
+ if (state->status_cb)
+ {
+ /* A status callback requires that we have a full
+ * line. Thus we need to enlarget the buffer in
+ * this case. */
+ char *newbuffer;
+ size_t newsize = state->buffer_size + 256;
+
+ newbuffer = xtrymalloc (newsize);
+ if (!newbuffer)
+ {
+ log_error ("error allocating memory for status cb: %s\n",
+ gpg_strerror (my_error_from_syserror ()));
+ /* We better disable the status CB in this case. */
+ state->status_cb = NULL;
+ read_and_log_stderr (state, NULL);
+ state->cont = 1;
+ }
+ else
+ {
+ memcpy (newbuffer, state->buffer, state->used);
+ xfree (state->buffer);
+ state->buffer = newbuffer;
+ state->buffer_size = newsize;
+ }
+ }
+ else
+ {
+ read_and_log_stderr (state, NULL);
+ state->cont = 1;
+ }
}
state->buffer[state->used++] = c;
}
@@ -188,7 +244,8 @@ copy_buffer_do_copy (struct copy_buffer *c, estream_t source, estream_t sink)
if (c->nread == 0)
return 0; /* Done copying. */
- err = es_write (sink, c->writep, c->nread, &nwritten);
+
+ err = sink? es_write (sink, c->writep, c->nread, &nwritten) : 0;
if (err)
{
if (errno == EAGAIN)
@@ -202,7 +259,7 @@ copy_buffer_do_copy (struct copy_buffer *c, estream_t source, estream_t sink)
c->nread -= nwritten;
assert (c->writep - c->buffer <= sizeof c->buffer);
- if (es_fflush (sink) && errno != EAGAIN)
+ if (sink && es_fflush (sink) && errno != EAGAIN)
err = my_error_from_syserror ();
return err;
@@ -228,41 +285,95 @@ copy_buffer_flush (struct copy_buffer *c, estream_t sink)
/* Run the program PGMNAME with the command line arguments given in
- the NULL terminates array ARGV. If INPUT is not NULL it will be
- fed to stdin of the process. stderr is logged using log_info and
- the process' stdout is written to OUTPUT. On error a diagnostic is
- printed, and an error code returned. */
+ * the NULL terminates array ARGV. If INPUT is not NULL it will be
+ * fed to stdin of the process. stderr is logged using log_info and
+ * the process' stdout is written to OUTPUT. If OUTPUT is NULL the
+ * output is discarded. If INEXTRA is given, an additional input
+ * stream will be passed to the child; to tell the child about this
+ * ARGV is scanned and the first occurrence of an argument
+ * "-&@INEXTRA@" is replaced by the concatenation of "-&" and the
+ * child's file descriptor of the pipe created for the INEXTRA stream.
+ *
+ * On error a diagnostic is printed and an error code returned. */
gpg_error_t
gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
- estream_t input,
- estream_t output)
+ estream_t input, estream_t inextra,
+ estream_t output,
+ exec_tool_status_cb_t status_cb,
+ void *status_cb_value)
{
gpg_error_t err;
pid_t pid;
estream_t infp = NULL;
+ estream_t extrafp = NULL;
estream_t outfp, errfp;
- es_poll_t fds[3];
+ es_poll_t fds[4];
+ int exceptclose[2];
+ int extrapipe[2] = {-1, -1};
+ char extrafdbuf[20];
+ const char *argsave = NULL;
+ int argsaveidx;
int count;
read_and_log_buffer_t fderrstate;
- struct copy_buffer cpbuf[2];
+ struct copy_buffer cpbuf_in, cpbuf_out, cpbuf_extra; /* Fixme: malloc them. */
memset (fds, 0, sizeof fds);
memset (&fderrstate, 0, sizeof fderrstate);
- copy_buffer_init (&cpbuf[0]);
- copy_buffer_init (&cpbuf[1]);
+ copy_buffer_init (&cpbuf_in);
+ copy_buffer_init (&cpbuf_out);
+ copy_buffer_init (&cpbuf_extra);
+
+ fderrstate.pgmname = pgmname;
+ fderrstate.status_cb = status_cb;
+ fderrstate.status_cb_value = status_cb_value;
+ fderrstate.buffer_size = 256;
+ fderrstate.buffer = xtrymalloc (fderrstate.buffer_size);
+ if (!fderrstate.buffer)
+ return my_error_from_syserror ();
+
+ if (inextra)
+ {
+ err = gnupg_create_outbound_pipe (extrapipe, &extrafp, 1);
+ if (err)
+ {
+ log_error ("error running outbound pipe for extra fp: %s\n",
+ gpg_strerror (err));
+ xfree (fderrstate.buffer);
+ return err;
+ }
+ exceptclose[0] = extrapipe[0]; /* Do not close in child. */
+ exceptclose[1] = -1;
+ /* Now find the argument marker and replace by the pipe's fd.
+ Yeah, that is an ugly non-thread safe hack but it safes us to
+ create a copy of the array. */
+ snprintf (extrafdbuf, sizeof extrafdbuf, "-&%d", extrapipe[0]);
+ for (argsaveidx=0; argv[argsaveidx]; argsaveidx++)
+ if (!strcmp (argv[argsaveidx], "-&@INEXTRA@"))
+ {
+ argsave = argv[argsaveidx];
+ argv[argsaveidx] = extrafdbuf;
+ break;
+ }
+ }
+ else
+ exceptclose[0] = -1;
- err = gnupg_spawn_process (pgmname, argv, GPG_ERR_SOURCE_DEFAULT,
- NULL, GNUPG_SPAWN_NONBLOCK,
+ err = gnupg_spawn_process (pgmname, argv,
+ exceptclose, NULL, GNUPG_SPAWN_NONBLOCK,
input? &infp : NULL,
&outfp, &errfp, &pid);
+ if (extrapipe[0] != -1)
+ close (extrapipe[0]);
+ if (argsave)
+ argv[argsaveidx] = argsave;
if (err)
{
log_error ("error running '%s': %s\n", pgmname, gpg_strerror (err));
+ es_fclose (extrafp);
+ xfree (fderrstate.buffer);
return err;
}
- fderrstate.pgmname = pgmname;
-
fds[0].stream = infp;
fds[0].want_write = 1;
if (!input)
@@ -271,6 +382,11 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
fds[1].want_read = 1;
fds[2].stream = errfp;
fds[2].want_read = 1;
+ fds[3].stream = extrafp;
+ fds[3].want_write = 1;
+ if (!inextra)
+ fds[3].ignore = 1;
+
/* Now read as long as we have something to poll. We continue
reading even after EOF or error on stdout so that we get the
other error messages or remaining outut. */
@@ -291,7 +407,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
if (fds[0].got_write)
{
- err = copy_buffer_do_copy (&cpbuf[0], input, fds[0].stream);
+ err = copy_buffer_do_copy (&cpbuf_in, input, fds[0].stream);
if (err)
{
log_error ("error feeding data to '%s': %s\n",
@@ -301,7 +417,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
if (es_feof (input))
{
- err = copy_buffer_flush (&cpbuf[0], fds[0].stream);
+ err = copy_buffer_flush (&cpbuf_in, fds[0].stream);
if (err)
{
log_error ("error feeding data to '%s': %s\n",
@@ -314,9 +430,35 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
}
}
+ if (fds[3].got_write)
+ {
+ log_assert (inextra);
+ err = copy_buffer_do_copy (&cpbuf_extra, inextra, fds[3].stream);
+ if (err)
+ {
+ log_error ("error feeding data to '%s': %s\n",
+ pgmname, gpg_strerror (err));
+ goto leave;
+ }
+
+ if (es_feof (inextra))
+ {
+ err = copy_buffer_flush (&cpbuf_extra, fds[3].stream);
+ if (err)
+ {
+ log_error ("error feeding data to '%s': %s\n",
+ pgmname, gpg_strerror (err));
+ goto leave;
+ }
+
+ fds[3].ignore = 1; /* ready. */
+ es_fclose (extrafp); extrafp = NULL;
+ }
+ }
+
if (fds[1].got_read)
{
- err = copy_buffer_do_copy (&cpbuf[1], fds[1].stream, output);
+ err = copy_buffer_do_copy (&cpbuf_out, fds[1].stream, output);
if (err)
{
log_error ("error reading data from '%s': %s\n",
@@ -329,7 +471,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
read_and_log_stderr (&fderrstate, fds + 2);
}
- err = copy_buffer_flush (&cpbuf[1], output);
+ err = copy_buffer_flush (&cpbuf_out, output);
if (err)
{
log_error ("error reading data from '%s': %s\n",
@@ -339,6 +481,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
read_and_log_stderr (&fderrstate, NULL); /* Flush. */
es_fclose (infp); infp = NULL;
+ es_fclose (extrafp); extrafp = NULL;
es_fclose (outfp); outfp = NULL;
es_fclose (errfp); errfp = NULL;
@@ -350,14 +493,18 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
gnupg_kill_process (pid);
es_fclose (infp);
+ es_fclose (extrafp);
es_fclose (outfp);
es_fclose (errfp);
if (pid != (pid_t)(-1))
gnupg_wait_process (pgmname, pid, 1, NULL);
gnupg_release_process (pid);
- copy_buffer_shred (&cpbuf[0]);
- copy_buffer_shred (&cpbuf[1]);
+ copy_buffer_shred (&cpbuf_in);
+ copy_buffer_shred (&cpbuf_out);
+ if (inextra)
+ copy_buffer_shred (&cpbuf_extra);
+ xfree (fderrstate.buffer);
return err;
}
@@ -408,7 +555,7 @@ gnupg_exec_tool (const char *pgmname, const char *argv[],
goto leave;
}
- err = gnupg_exec_tool_stream (pgmname, argv, input, output);
+ err = gnupg_exec_tool_stream (pgmname, argv, input, NULL, output, NULL, NULL);
if (err)
goto leave;
diff --git a/common/exectool.h b/common/exectool.h
index d9439aa..94091fd 100644
--- a/common/exectool.h
+++ b/common/exectool.h
@@ -32,6 +32,17 @@
#include <gpg-error.h>
+/* This callback can be used to process --status-fd outputs of GnuPG
+ * tools. OPAQUE can be used to communicate between the caller of the
+ * function and the callback. KEYWORD is the status keyword (see
+ * doc/DETAILS); it is never NULL. ARGS are the arguments of the
+ * status line and will also never be NULL; the caller may modify this
+ * string. */
+typedef void (*exec_tool_status_cb_t) (void *opaque,
+ const char *keyword,
+ char *args);
+
+
/* Run the program PGMNAME with the command line arguments given in
the NULL terminates array ARGV. If INPUT_STRING is not NULL it
will be fed to stdin of the process. stderr is logged using
@@ -48,9 +59,11 @@ gpg_error_t gnupg_exec_tool (const char *pgmname, const char *argv[],
the NULL terminates array ARGV. If INPUT is not NULL it will be
fed to stdin of the process. stderr is logged using log_info and
the process' stdout is written to OUTPUT. On error a diagnostic is
- printed, and an error code returned. */
+ printed, and an error code returned. INEXTRA is reserved. */
gpg_error_t gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
- estream_t input,
- estream_t output);
+ estream_t input, estream_t inextra,
+ estream_t output,
+ exec_tool_status_cb_t status_cb,
+ void *status_cb_value);
#endif /* GNUPG_COMMON_EXECTOOL_H */
diff --git a/common/get-passphrase.c b/common/get-passphrase.c
index f1517fb..8f3137b 100644
--- a/common/get-passphrase.c
+++ b/common/get-passphrase.c
@@ -47,7 +47,6 @@ static struct
{
gpg_err_source_t errsource;
int verbosity;
- const char *homedir;
const char *agent_program;
const char *lc_ctype;
const char *lc_messages;
@@ -62,7 +61,6 @@ static struct
void
gnupg_prepare_get_passphrase (gpg_err_source_t errsource,
int verbosity,
- const char *homedir,
const char *agent_program,
const char *opt_lc_ctype,
const char *opt_lc_messages,
@@ -70,7 +68,6 @@ gnupg_prepare_get_passphrase (gpg_err_source_t errsource,
{
agentargs.errsource = errsource;
agentargs.verbosity = verbosity;
- agentargs.homedir = homedir;
agentargs.agent_program = agent_program;
agentargs.lc_ctype = opt_lc_ctype;
agentargs.lc_messages = opt_lc_messages;
@@ -93,7 +90,6 @@ start_agent (void)
err = start_new_gpg_agent (&agent_ctx,
agentargs.errsource,
- agentargs.homedir,
agentargs.agent_program,
agentargs.lc_ctype,
agentargs.lc_messages,
diff --git a/common/get-passphrase.h b/common/get-passphrase.h
index a69262f..7e5cac0 100644
--- a/common/get-passphrase.h
+++ b/common/get-passphrase.h
@@ -34,7 +34,6 @@
void gnupg_prepare_get_passphrase (gpg_err_source_t errsource,
int verbosity,
- const char *homedir,
const char *agent_program,
const char *opt_lc_ctype,
const char *opt_lc_messages,
diff --git a/common/homedir.c b/common/homedir.c
index 5bf5173..9a69022 100644
--- a/common/homedir.c
+++ b/common/homedir.c
@@ -1,6 +1,6 @@
/* homedir.c - Setup the home directory.
* Copyright (C) 2004, 2006, 2007, 2010 Free Software Foundation, Inc.
- * Copyright (C) 2013 Werner Koch
+ * Copyright (C) 2013, 2016 Werner Koch
*
* This file is part of GnuPG.
*
@@ -53,10 +53,23 @@
#endif
#endif /*HAVE_W32_SYSTEM*/
+#ifdef HAVE_STAT
+#include <sys/stat.h> /* for stat() */
+#endif
+
#include "util.h"
#include "sysutils.h"
+#include "zb32.h"
+
+/* The GnuPG homedir. This is only accessed by the functions
+ * gnupg_homedir and gnupg_set_homedir. Malloced. */
+static char *the_gnupg_homedir;
+
+/* Flag indicating that home directory is not the default one. */
+static byte non_default_homedir;
+
#ifdef HAVE_W32_SYSTEM
/* A flag used to indicate that a control file for gpgconf has been
@@ -70,13 +83,13 @@
This flag is not used on Unix systems.
*/
-static int w32_portable_app;
+static byte w32_portable_app;
#endif /*HAVE_W32_SYSTEM*/
#ifdef HAVE_W32_SYSTEM
/* This flag is true if this process' binary has been installed under
bin and not in the root directory as often used before GnuPG 2.1. */
-static int w32_bin_is_bin;
+static byte w32_bin_is_bin;
#endif /*HAVE_W32_SYSTEM*/
@@ -144,6 +157,20 @@ w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
#endif /*HAVE_W32_SYSTEM*/
+/* Check whether DIR is the default homedir. */
+static int
+is_gnupg_default_homedir (const char *dir)
+{
+ int result;
+ char *a = make_absfilename (dir, NULL);
+ char *b = make_absfilename (GNUPG_DEFAULT_HOMEDIR, NULL);
+ result = !compare_filenames (a, b);
+ xfree (b);
+ xfree (a);
+ return result;
+}
+
+
/* Get the standard home directory. In general this function should
not be used as it does not consider a registry value (under W32) or
the GNUPGHOME environment variable. It is better to use
@@ -242,6 +269,8 @@ default_homedir (void)
#endif /*HAVE_W32_SYSTEM*/
if (!dir || !*dir)
dir = GNUPG_DEFAULT_HOMEDIR;
+ else if (!is_gnupg_default_homedir (dir))
+ non_default_homedir = 1;
return dir;
}
@@ -368,6 +397,241 @@ w32_commondir (void)
#endif /*HAVE_W32_SYSTEM*/
+/* Change the homedir. Some care must be taken to set this early
+ * enough because previous calls to gnupg_homedir may else return a
+ * different string. */
+void
+gnupg_set_homedir (const char *newdir)
+{
+ if (!newdir || !*newdir)
+ newdir = default_homedir ();
+ else if (!is_gnupg_default_homedir (newdir))
+ non_default_homedir = 1;
+ xfree (the_gnupg_homedir);
+ the_gnupg_homedir = make_absfilename (newdir, NULL);;
+}
+
+
+/* Return the homedir. The returned string is valid until another
+ * gnupg-set-homedir call. This is always an absolute directory name.
+ * The function replaces the former global var opt.homedir. */
+const char *
+gnupg_homedir (void)
+{
+ /* If a homedir has not been set, set it to the default. */
+ if (!the_gnupg_homedir)
+ the_gnupg_homedir = make_absfilename (default_homedir (), NULL);
+ return the_gnupg_homedir;
+}
+
+
+/* Return whether the home dir is the default one. */
+int
+gnupg_default_homedir_p (void)
+{
+ return !non_default_homedir;
+}
+
+
+/* Helper for gnupg-socketdir. This is a global function, so that
+ * gpgconf can use it for its --create-socketdir command. If
+ * SKIP_CHECKS is set permission checks etc. are not done. The
+ * function always returns a malloced directory name and stores these
+ * bit flags at R_INFO:
+ *
+ * 1 := Internal error, stat failed, out of core, etc.
+ * 2 := No /run/user directory.
+ * 4 := Directory not owned by the user, not a directory
+ * or wrong permissions.
+ * 8 := Same as 4 but for the subdir.
+ * 16 := mkdir failed
+ * 32 := Non default homedir; checking subdir.
+ * 64 := Subdir does not exist.
+ * 128 := Using homedir as fallback.
+ */
+char *
+_gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
+{
+#if defined(HAVE_W32_SYSTEM) || !defined(HAVE_STAT)
+
+ char *name;
+
+ (void)skip_checks;
+ *r_info = 0;
+ name = xstrdup (gnupg_homedir ());
+
+#else /* Unix and stat(2) available. */
+
+ static const char * const bases[] = { "/run", "/var/run", NULL};
+ int i;
+ struct stat sb;
+ char prefix[13 + 1 + 20 + 6 + 1];
+ const char *s;
+ char *name = NULL;
+
+ *r_info = 0;
+
+ /* First make sure that non_default_homedir can be set. */
+ gnupg_homedir ();
+
+ /* It has been suggested to first check XDG_RUNTIME_DIR envvar.
+ * However, the specs state that the lifetime of the directory MUST
+ * be bound to the user being logged in. Now GnuPG may also be run
+ * 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. */
+ for (i=0; bases[i]; i++)
+ {
+ snprintf (prefix, sizeof prefix, "%s/user/%u",
+ bases[i], (unsigned int)getuid ());
+ if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode))
+ break;
+ }
+ if (!bases[i])
+ {
+ *r_info |= 2; /* No /run/user directory. */
+ goto leave;
+ }
+
+ if (sb.st_uid != getuid ())
+ {
+ *r_info |= 4; /* Not owned by the user. */
+ if (!skip_checks)
+ goto leave;
+ }
+
+ if (strlen (prefix) + 7 >= sizeof prefix)
+ {
+ *r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */
+ goto leave;
+ }
+ strcat (prefix, "/gnupg");
+
+ /* Check whether the gnupg sub directory has proper permissions. */
+ if (stat (prefix, &sb))
+ {
+ if (errno != ENOENT)
+ {
+ *r_info |= 1; /* stat failed. */
+ goto leave;
+ }
+
+ /* Try to create the directory and check again. */
+ if (gnupg_mkdir (prefix, "-rwx"))
+ {
+ *r_info |= 16; /* mkdir failed. */
+ goto leave;
+ }
+ if (stat (prefix, &sb))
+ {
+ *r_info |= 1; /* stat failed. */
+ goto leave;
+ }
+ }
+ /* Check that it is a directory, owned by the user, and only the
+ * user has permissions to use it. */
+ if (!S_ISDIR(sb.st_mode)
+ || sb.st_uid != getuid ()
+ || (sb.st_mode & (S_IRWXG|S_IRWXO)))
+ {
+ *r_info |= 4; /* Bad permissions or not a directory. */
+ if (!skip_checks)
+ goto leave;
+ }
+
+ /* If a non default homedir is used, we check whether an
+ * corresponding sub directory below the socket dir is available
+ * and use that. We has the non default homedir to keep the new
+ * subdir short enough. */
+ if (non_default_homedir)
+ {
+ char sha1buf[20];
+ char *suffix;
+
+ *r_info |= 32; /* Testing subdir. */
+ s = gnupg_homedir ();
+ gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, s, strlen (s));
+ suffix = zb32_encode (sha1buf, 8*15);
+ if (!suffix)
+ {
+ *r_info |= 1; /* Out of core etc. */
+ goto leave;
+ }
+ name = strconcat (prefix, "/d.", suffix, NULL);
+ xfree (suffix);
+ if (!name)
+ {
+ *r_info |= 1; /* Out of core etc. */
+ goto leave;
+ }
+
+ /* Stat that directory and check constraints. Note that we
+ * do not auto create such a directory because we would not
+ * have a way to remove it. Thus the directory needs to be
+ * pre-created. The command
+ * gpgconf --create-socketdir
+ * can be used tocreate that directory. */
+ if (stat (name, &sb))
+ {
+ if (errno != ENOENT)
+ *r_info |= 1; /* stat failed. */
+ else
+ *r_info |= 64; /* Subdir does not exist. */
+ if (!skip_checks)
+ {
+ xfree (name);
+ name = NULL;
+ goto leave;
+ }
+ }
+ else if (!S_ISDIR(sb.st_mode)
+ || sb.st_uid != getuid ()
+ || (sb.st_mode & (S_IRWXG|S_IRWXO)))
+ {
+ *r_info |= 8; /* Bad permissions or subdir is not a directory. */
+ if (!skip_checks)
+ {
+ xfree (name);
+ name = NULL;
+ goto leave;
+ }
+ }
+ }
+ else
+ name = xstrdup (prefix);
+
+ leave:
+ /* If nothing works fall back to the homedir. */
+ if (!name)
+ {
+ *r_info |= 128; /* Fallback. */
+ name = xstrdup (gnupg_homedir ());
+ }
+
+#endif /* Unix */
+
+ return name;
+}
+
+
+/*
+ * Return the name of the socket dir. That is the directory used for
+ * the IPC local sockets. This is an absolute directory name.
+ */
+const char *
+gnupg_socketdir (void)
+{
+ static char *name;
+
+ if (!name)
+ {
+ unsigned int dummy;
+ name = _gnupg_socketdir_internal (0, &dummy);
+ }
+
+ return name;
+}
/* Return the name of the sysconfdir. This is a static string. This
@@ -601,7 +865,7 @@ dirmngr_user_socket_name (void)
static char *name;
if (!name)
- name = make_absfilename (default_homedir (), DIRMNGR_SOCK_NAME, NULL);
+ name = make_filename (gnupg_socketdir (), DIRMNGR_SOCK_NAME, NULL);
return name;
}
diff --git a/common/logging.c b/common/logging.c
index 9175b4f..b6bafc7 100644
--- a/common/logging.c
+++ b/common/logging.c
@@ -54,7 +54,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
-
+/* #include <execinfo.h> */
#define GNUPG_COMMON_NEED_AFLOCAL 1
#include "util.h"
@@ -748,6 +748,19 @@ do_logv (int level, int ignore_arg_ptr, const char *fmt, va_list arg_ptr)
if (missing_lf)
es_putc_unlocked ('\n', logstream );
es_funlockfile (logstream);
+ /* Using backtrace requires a configure test and to pass
+ * -rdynamic to gcc. Thus we do not enable it now. */
+ /* { */
+ /* void *btbuf[20]; */
+ /* int btidx, btlen; */
+ /* char **btstr; */
+
+ /* btlen = backtrace (btbuf, DIM (btbuf)); */
+ /* btstr = backtrace_symbols (btbuf, btlen); */
+ /* if (btstr) */
+ /* for (btidx=0; btidx < btlen; btidx++) */
+ /* log_debug ("[%d] %s\n", btidx, btstr[btidx]); */
+ /* } */
abort ();
}
else
diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c
index 1b6d5f3..7c93547 100644
--- a/common/openpgp-oid.c
+++ b/common/openpgp-oid.c
@@ -35,7 +35,7 @@
#include <assert.h>
#include "util.h"
-
+#include "openpgpdefs.h"
/* A table with all our supported OpenPGP curves. */
static struct {
@@ -43,10 +43,11 @@ static struct {
const char *oidstr; /* IETF formatted OID. */
unsigned int nbits; /* Nominal bit length of the curve. */
const char *alias; /* NULL or alternative name of the curve. */
+ int pubkey_algo; /* Required OpenPGP algo or 0 for ECDSA/ECDH. */
} oidtable[] = {
- { "Curve25519", "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519" },
- { "Ed25519", "1.3.6.1.4.1.11591.15.1", 255, "ed25519" },
+ { "Curve25519", "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519", PUBKEY_ALGO_ECDH },
+ { "Ed25519", "1.3.6.1.4.1.11591.15.1", 255, "ed25519", PUBKEY_ALGO_EDDSA },
{ "NIST P-256", "1.2.840.10045.3.1.7", 256, "nistp256" },
{ "NIST P-384", "1.3.132.0.34", 384, "nistp384" },
@@ -408,3 +409,29 @@ openpgp_enum_curves (int *iterp)
*iterp = idx;
return NULL;
}
+
+
+/* Return the Libgcrypt name for for the gpg curve NAME if supported.
+ * If R_ALGO is not NULL the required OpenPGP public key algo or 0 is
+ * stored at that address. NULL is returned if the curev is not
+ * supported. */
+const char *
+openpgp_is_curve_supported (const char *name, int *r_algo)
+{
+ int idx;
+
+ if (r_algo)
+ *r_algo = 0;
+ for (idx = 0; idx < DIM (oidtable) && oidtable[idx].name; idx++)
+ {
+ if (!strcmp (name, (oidtable[idx].alias? oidtable[idx].alias
+ /**/ : oidtable[idx].name))
+ && curve_supported_p (oidtable[idx].name))
+ {
+ if (r_algo)
+ *r_algo = oidtable[idx].pubkey_algo;
+ return oidtable[idx].name;
+ }
+ }
+ return NULL;
+}
diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h
index e200d6b..f8b86e1 100644
--- a/common/openpgpdefs.h
+++ b/common/openpgpdefs.h
@@ -106,7 +106,7 @@ typedef enum
SIGSUBPKT_PREF_HASH = 21, /* Preferred hash algorithms. */
SIGSUBPKT_PREF_COMPR = 22, /* Preferred compression algorithms. */
SIGSUBPKT_KS_FLAGS = 23, /* Key server preferences. */
- SIGSUBPKT_PREF_KS = 24, /* Preferred key server. */
+ SIGSUBPKT_PREF_KS = 24, /* Preferred keyserver. */
SIGSUBPKT_PRIMARY_UID = 25, /* Primary user id. */
SIGSUBPKT_POLICY = 26, /* Policy URL. */
SIGSUBPKT_KEY_FLAGS = 27, /* Key flags. */
diff --git a/common/status.h b/common/status.h
index 730a75c..f9771c2 100644
--- a/common/status.h
+++ b/common/status.h
@@ -96,6 +96,7 @@ enum
STATUS_SIG_CREATED,
STATUS_SESSION_KEY,
STATUS_NOTATION_NAME,
+ STATUS_NOTATION_FLAGS,
STATUS_NOTATION_DATA,
STATUS_POLICY_URL,
STATUS_KEY_CREATED,
@@ -105,6 +106,7 @@ enum
STATUS_INV_SGNR,
STATUS_NO_RECP,
STATUS_NO_SGNR,
+ STATUS_KEY_CONSIDERED,
STATUS_ALREADY_SIGNED,
STATUS_KEYEXPIRED,
diff --git a/common/stringhelp.c b/common/stringhelp.c
index 8b47a1c..0e96c9e 100644
--- a/common/stringhelp.c
+++ b/common/stringhelp.c
@@ -1329,6 +1329,44 @@ strtokenize (const char *string, const char *delim)
}
+/* Split a string into space delimited fields and remove leading and
+ * trailing spaces from each field. A pointer to each field is stored
+ * in ARRAY. Stop splitting at ARRAYSIZE fields. The function
+ * modifies STRING. The number of parsed fields is returned.
+ * Example:
+ *
+ * char *fields[2];
+ * if (split_fields (string, fields, DIM (fields)) < 2)
+ * return // Not enough args.
+ * foo (fields[0]);
+ * foo (fields[1]);
+ */
+int
+split_fields (char *string, char **array, int arraysize)
+{
+ int n = 0;
+ char *p, *pend;
+
+ for (p = string; *p == ' '; p++)
+ ;
+ do
+ {
+ if (n == arraysize)
+ break;
+ array[n++] = p;
+ pend = strchr (p, ' ');
+ if (!pend)
+ break;
+ *pend++ = 0;
+ for (p = pend; *p == ' '; p++)
+ ;
+ }
+ while (*p);
+
+ return n;
+}
+
+
/* Version number parsing. */
diff --git a/common/stringhelp.h b/common/stringhelp.h
index d9225a3..b6f4167 100644
--- a/common/stringhelp.h
+++ b/common/stringhelp.h
@@ -148,6 +148,10 @@ char **strsplit (char *string, char delim, char replacement, int *count);
/* Tokenize STRING using the set of delimiters in DELIM. */
char **strtokenize (const char *string, const char *delim);
+/* Split STRING into space delimited fields and store them in the
+ * provided ARRAY. */
+int split_fields (char *string, char **array, int arraysize);
+
/* Return True if MYVERSION is greater or equal than REQ_VERSION. */
int compare_version_strings (const char *my_version, const char *req_version);
diff --git a/common/sysutils.c b/common/sysutils.c
index 18625d0..0f7b7f5 100644
--- a/common/sysutils.c
+++ b/common/sysutils.c
@@ -628,7 +628,7 @@ gnupg_mkdir (const char *name, const char *modestr)
}
-/* A wrapper around mkdir which takes a string for the mode argument.
+/* A wrapper around chmod which takes a string for the mode argument.
This makes it easier to handle the mode argument which is not
defined on all systems. The format of the modestring is the same
as for gnupg_mkdir. */
@@ -636,6 +636,8 @@ int
gnupg_chmod (const char *name, const char *modestr)
{
#ifdef HAVE_W32_SYSTEM
+ (void)name;
+ (void)modestr;
return 0;
#else
return chmod (name, modestr_to_mode (modestr));
diff --git a/common/t-ccparray.c b/common/t-ccparray.c
new file mode 100644
index 0000000..0512346
--- /dev/null
+++ b/common/t-ccparray.c
@@ -0,0 +1,93 @@
+/* t-ccparray.c - Module test for ccparray.c
+ * Copyright (C) 2016 g10 Code GmbH
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+#include "ccparray.h"
+
+#define pass() do { ; } while(0)
+#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\
+ __FILE__,__LINE__, (a)); \
+ exit (1); \
+ } while(0)
+
+
+static void
+run_test_1 (void)
+{
+ ccparray_t ccp;
+ const char **argv;
+ size_t nelem;
+
+ ccparray_init (&ccp, 0);
+ ccparray_put (&ccp, "First arg");
+ ccparray_put (&ccp, "Second arg");
+ ccparray_put (&ccp, NULL);
+ ccparray_put (&ccp, "Fourth arg");
+ argv = ccparray_get (&ccp, &nelem);
+ if (!argv)
+ {
+ fprintf (stderr, "error building array: %s\n", strerror (errno));
+ exit (1);
+ }
+
+ if (nelem != 4)
+ fail (1);
+
+ /* for (i=0; argv[i]; i++) */
+ /* printf ("[%d] = '%s'\n", i, argv[i]); */
+ xfree (argv);
+}
+
+
+static void
+run_test_var (int count)
+{
+ ccparray_t ccp;
+ size_t nelem;
+ int i;
+
+ ccparray_init (&ccp, 0);
+ for (i=0; i < count; i++)
+ ccparray_put (&ccp, "An arg");
+ xfree (ccparray_get (&ccp, &nelem));
+ if (nelem != i)
+ fail (2);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ (void)argc;
+ (void)argv;
+
+ run_test_1 ();
+ run_test_var (0);
+ run_test_var (7);
+ run_test_var (8);
+ run_test_var (9);
+ run_test_var (4096);
+
+ return 0;
+}
diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c
index b4a41ac..4f4555e 100644
--- a/common/t-stringhelp.c
+++ b/common/t-stringhelp.c
@@ -34,6 +34,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <assert.h>
#ifdef HAVE_PWD_H
# include <pwd.h>
#endif
@@ -676,6 +677,82 @@ test_strtokenize (void)
}
}
+
+static void
+test_split_fields (void)
+{
+ struct {
+ const char *s;
+ int nfields;
+ const char *fields_expected[10];
+ } tv[] = {
+ {
+ "a bc cde fghi jklmn foo ", 6,
+ { "a", "bc", "cde", "fghi", "jklmn", "foo", NULL }
+ },
+ {
+ " a bc def ", 2,
+ { "a", "bc", "def", NULL }
+ },
+ {
+ " a bc def ", 3,
+ { "a", "bc", "def", NULL }
+ },
+ {
+ " a bc def ", 4,
+ { "a", "bc", "def", NULL }
+ },
+ {
+ "", 0,
+ { NULL }
+ }
+ };
+
+ int tidx;
+ char *fields[10];
+ int field_count_expected, nfields, field_count, i;
+ char *s2;
+
+ for (tidx = 0; tidx < DIM(tv); tidx++)
+ {
+ nfields = tv[tidx].nfields;
+ assert (nfields <= DIM (fields));
+
+ /* Count the fields. */
+ for (field_count_expected = 0;
+ tv[tidx].fields_expected[field_count_expected];
+ field_count_expected ++)
+ ;
+ if (field_count_expected > nfields)
+ field_count_expected = nfields;
+
+ /* We need to copy s since split_fields modifies in place. */
+ s2 = xstrdup (tv[tidx].s);
+ field_count = split_fields (s2, fields, nfields);
+
+ if (field_count != field_count_expected)
+ {
+ printf ("%s: tidx %d: expected %d, got %d\n",
+ __func__, tidx, field_count_expected, field_count);
+ fail (tidx * 1000);
+ }
+ else
+ {
+ for (i = 0; i < field_count_expected; i ++)
+ if (strcmp (tv[tidx].fields_expected[i], fields[i]))
+ {
+ printf ("%s: tidx %d, field %d: expected '%s', got '%s'\n",
+ __func__,
+ tidx, i, tv[tidx].fields_expected[i], fields[i]);
+ fail (tidx * 1000 + i + 1);
+ }
+ }
+
+ xfree (s2);
+ }
+}
+
+
static char *
stresc (char *s)
{
@@ -887,6 +964,7 @@ main (int argc, char **argv)
test_make_absfilename_try ();
test_strsplit ();
test_strtokenize ();
+ test_split_fields ();
test_compare_version_strings ();
test_format_text ();
diff --git a/common/util.h b/common/util.h
index 84a15ab..c84847a 100644
--- a/common/util.h
+++ b/common/util.h
@@ -214,12 +214,16 @@ int openpgp_oid_is_crv25519 (gcry_mpi_t a);
const char *openpgp_curve_to_oid (const char *name, unsigned int *r_nbits);
const char *openpgp_oid_to_curve (const char *oid, int canon);
const char *openpgp_enum_curves (int *idxp);
-
+const char *openpgp_is_curve_supported (const char *name, int *r_algo);
/*-- homedir.c --*/
const char *standard_homedir (void);
const char *default_homedir (void);
+void gnupg_set_homedir (const char *newdir);
+const char *gnupg_homedir (void);
+int gnupg_default_homedir_p (void);
+const char *gnupg_socketdir (void);
const char *gnupg_sysconfdir (void);
const char *gnupg_bindir (void);
const char *gnupg_libexecdir (void);
@@ -230,6 +234,8 @@ const char *gnupg_cachedir (void);
const char *dirmngr_sys_socket_name (void);
const char *dirmngr_user_socket_name (void);
+char *_gnupg_socketdir_internal (int skip_checks, unsigned *r_info);
+
/* All module names. We also include gpg and gpgsm for the sake for
gpgconf. */
#define GNUPG_MODULE_NAME_AGENT 1
diff --git a/configure.ac b/configure.ac
index 6aeca17..1b8a6fc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,7 +28,7 @@ min_automake_version="1.14"
m4_define([mym4_package],[gnupg])
m4_define([mym4_major], [2])
m4_define([mym4_minor], [1])
-m4_define([mym4_micro], [12])
+m4_define([mym4_micro], [13])
# 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
@@ -787,24 +787,28 @@ AM_PATH_KSBA("$NEED_KSBA_API:$NEED_KSBA_VERSION",have_ksba=yes,have_ksba=no)
if test "$use_ccid_driver" = auto || test "$use_ccid_driver" = yes; then
case "${host}" in
*-mingw32*)
+ LIBUSB_NAME=
LIBUSB_LIBS=
LIBUSB_CPPFLAGS=
;;
*-*-darwin*)
- LIBUSB_LIBS="-lusb-1.0 -Wl,-framework,CoreFoundation -Wl,-framework,IOKit"
+ LIBUSB_NAME=usb-1.0
+ LIBUSB_LIBS="-Wl,-framework,CoreFoundation -Wl,-framework,IOKit"
;;
*-*-freebsd*)
# FreeBSD has a native 1.0 compatible library by -lusb.
- LIBUSB_LIBS="-lusb"
+ LIBUSB_NAME=usb
+ LIBUSB_LIBS=
;;
*)
- LIBUSB_LIBS="-lusb-1.0"
+ LIBUSB_NAME=usb-1.0
+ LIBUSB_LIBS=
;;
esac
fi
-if test x"$LIBUSB_LIBS" != x ; then
- AC_CHECK_LIB(usb-1.0, libusb_init,
- [ LIBUSB_LIBS="$LIBUSB_LIBS"
+if test x"$LIBUSB_NAME" != x ; then
+ AC_CHECK_LIB($LIBUSB_NAME, libusb_init,
+ [ LIBUSB_LIBS="-l$LIBUSB_NAME $LIBUSB_LIBS"
have_libusb=yes ])
AC_MSG_CHECKING([libusb include dir])
usb_incdir_found="no"
@@ -1379,7 +1383,7 @@ AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe getaddrinfo])
AC_CHECK_FUNCS([ttyname rand ftello fsync stat lstat])
AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol \
memrchr isascii timegm getrusage setrlimit stat setlocale \
- flockfile funlockfile fopencookie funopen getpwnam getpwuid \
+ flockfile funlockfile getpwnam getpwuid \
getenv inet_pton strpbrk])
if test "$have_android_system" = yes; then
@@ -1772,12 +1776,13 @@ AC_ARG_ENABLE([build-timestamp],
BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
else
BUILD_TIMESTAMP="$enableval"
- fi],
- [BUILD_TIMESTAMP="<none>"])
+ fi
+ BUILD_HOSTNAME="$ac_hostname"],
+ [BUILD_TIMESTAMP="<none>"
+ BUILD_HOSTNAME="<anon>"])
AC_SUBST(BUILD_TIMESTAMP)
AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP",
[The time this package was configured for a build])
-BUILD_HOSTNAME="$ac_hostname"
AC_SUBST(BUILD_HOSTNAME)
diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am
index cbc0090..aaa9050 100644
--- a/dirmngr/Makefile.am
+++ b/dirmngr/Makefile.am
@@ -99,18 +99,17 @@ dirmngr_ldap_LDADD = $(libcommon) no-libgcrypt.o \
endif
dirmngr_client_SOURCES = dirmngr-client.c
-dirmngr_client_LDADD = $(libcommon) no-libgcrypt.o \
- $(LIBASSUAN_LIBS) \
- $(GPG_ERROR_LIBS) $(NETLIBS) $(LIBINTL) $(LIBICONV)
+dirmngr_client_LDADD = $(libcommon) \
+ $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
+ $(LIBGCRYPT_LIBS) $(NETLIBS) $(LIBINTL) $(LIBICONV)
dirmngr_client_LDFLAGS = $(extra_bin_ldflags)
-
no-libgcrypt.c : $(top_srcdir)/tools/no-libgcrypt.c
cat $(top_srcdir)/tools/no-libgcrypt.c > no-libgcrypt.c
t_common_src = t-support.h
-t_common_ldadd = $(libcommon) no-libgcrypt.o $(LIBASSUAN_LIBS) \
+t_common_ldadd = $(libcommon) $(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) \
$(GPG_ERROR_LIBS) $(NETLIBS) \
$(NTBTLS_LIBS) $(LIBGNUTLS_LIBS) \
$(DNSLIBS) $(LIBINTL) $(LIBICONV)
diff --git a/dirmngr/dirmngr-client.c b/dirmngr/dirmngr-client.c
index c6a33d7..9b004cc 100644
--- a/dirmngr/dirmngr-client.c
+++ b/dirmngr/dirmngr-client.c
@@ -298,7 +298,6 @@ main (int argc, char **argv )
err = start_new_dirmngr (&ctx,
GPG_ERR_SOURCE_DEFAULT,
- default_homedir (),
opt.dirmngr_program
? opt.dirmngr_program
: gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR),
diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
index f249d68..7e629db 100644
--- a/dirmngr/dirmngr.c
+++ b/dirmngr/dirmngr.c
@@ -795,9 +795,7 @@ main (int argc, char **argv)
if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
csh_style = 1;
- opt.homedir = default_homedir ();
-
- /* Now with NPth running we can set the logging callback. Our
+ /* Now with NPth running we can set the logging callback. Our
windows implementation does not yet feature the NPth TLS
functions. */
#ifndef HAVE_W32_SYSTEM
@@ -835,7 +833,7 @@ main (int argc, char **argv)
default_config = 0; /* --no-options */
else if (pargs.r_opt == oHomedir)
{
- opt.homedir = pargs.r.ret_str;
+ gnupg_set_homedir (pargs.r.ret_str);
homedir_seen = 1;
}
else if (pargs.r_opt == aDaemon)
@@ -862,9 +860,9 @@ main (int argc, char **argv)
if (opt.system_daemon && !homedir_seen)
{
#ifdef HAVE_W32CE_SYSTEM
- opt.homedir = DIRSEP_S "gnupg";
+ gnupg_set_homedir (DIRSEP_S "gnupg");
#else
- opt.homedir = gnupg_sysconfdir ();
+ gnupg_set_homedir (gnupg_sysconfdir ());
#endif
opt.homedir_cache = gnupg_cachedir ();
socket_name = dirmngr_sys_socket_name ();
@@ -875,7 +873,7 @@ main (int argc, char **argv)
socket_name = dirmngr_sys_socket_name ();
if (default_config)
- configname = make_filename (opt.homedir, DIRMNGR_NAME".conf", NULL );
+ configname = make_filename (gnupg_homedir (), DIRMNGR_NAME".conf", NULL );
argc = orig_argc;
argv = orig_argv;
@@ -989,7 +987,7 @@ main (int argc, char **argv)
greeting = 0;
if (!opt.homedir_cache)
- opt.homedir_cache = opt.homedir;
+ opt.homedir_cache = xstrdup (gnupg_homedir ());
if (greeting)
{
@@ -1019,7 +1017,8 @@ main (int argc, char **argv)
log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
}
- if (!access ("/etc/"DIRMNGR_NAME, F_OK) && !strncmp (opt.homedir, "/etc/", 5))
+ if (!access ("/etc/"DIRMNGR_NAME, F_OK)
+ && !strncmp (gnupg_homedir (), "/etc/", 5))
log_info
("NOTE: DirMngr is now a proper part of %s. The configuration and"
" other directory names changed. Please check that no other version"
@@ -1043,7 +1042,7 @@ main (int argc, char **argv)
#if USE_LDAP
if (!ldapfile)
{
- ldapfile = make_filename (opt.homedir,
+ ldapfile = make_filename (gnupg_homedir (),
opt.system_daemon?
"ldapservers.conf":"dirmngr_ldapservers.conf",
NULL);
@@ -1184,6 +1183,10 @@ main (int argc, char **argv)
}
cleanup_socket = 1;
+ if (gnupg_chmod (serv_addr.sun_path, "-rwx"))
+ log_error (_("can't set permissions of '%s': %s\n"),
+ serv_addr.sun_path, strerror (errno));
+
if (listen (FD2INT (fd), 5) == -1)
{
log_error (_("listen() failed: %s\n"), strerror (errno));
@@ -1396,7 +1399,7 @@ main (int argc, char **argv)
/* First the configuration file. This is not an option, but it
is vital information for GPG Conf. */
if (!opt.config_filename)
- opt.config_filename = make_filename (opt.homedir,
+ opt.config_filename = make_filename (gnupg_homedir (),
"dirmngr.conf", NULL );
filename = percent_escape (opt.config_filename, NULL);
@@ -1416,7 +1419,7 @@ main (int argc, char **argv)
and having both of them is thus problematic. --no-detach is
also only usable on the command line. --batch is unused. */
- filename = make_filename (opt.homedir,
+ filename = make_filename (gnupg_homedir (),
opt.system_daemon?
"ldapservers.conf":"dirmngr_ldapservers.conf",
NULL);
@@ -1658,7 +1661,7 @@ parse_ocsp_signer (const char *string)
{
if (string[0] == '.' && string[1] == '/' )
string += 2;
- fname = make_filename (opt.homedir, string, NULL);
+ fname = make_filename (gnupg_homedir (), string, NULL);
}
fp = es_fopen (fname, "r");
diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
index 6078884..8d90ae4 100644
--- a/dirmngr/dirmngr.h
+++ b/dirmngr/dirmngr.h
@@ -79,8 +79,7 @@ struct
int quiet; /* be as quiet as possible */
int dry_run; /* don't change any persistent data */
int batch; /* batch mode */
- const char *homedir; /* Configuration directory name */
- const char *homedir_cache; /* Ditto for cache files (/var/cache/dirmngr). */
+ const char *homedir_cache; /* Dir for cache files (/var/cache/dirmngr). */
char *config_filename; /* Name of a config file, which will be
reread on a HUP if it is not NULL. */
diff --git a/dirmngr/dirmngr_ldap.c b/dirmngr/dirmngr_ldap.c
index 6309413..c5702b1 100644
--- a/dirmngr/dirmngr_ldap.c
+++ b/dirmngr/dirmngr_ldap.c
@@ -641,10 +641,23 @@ fetch_ldap (my_opt_t myopt, const char *url, const LDAPURLDesc *ludp)
/* Fixme: Can we use MYOPT->user or is it shared with other theeads?. */
ret = my_ldap_simple_bind_s (ld, myopt->user, myopt->pass);
npth_protect ();
+#ifdef LDAP_VERSION3
+ if (ret == LDAP_PROTOCOL_ERROR)
+ {
+ /* Protocol error could mean that the server only supports v3. */
+ int version = LDAP_VERSION3;
+ if (myopt->verbose)
+ log_info ("protocol error; retrying bind with v3 protocol\n");
+ npth_unprotect ();
+ ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version);
+ ret = my_ldap_simple_bind_s (ld, myopt->user, myopt->pass);
+ npth_protect ();
+ }
+#endif
if (ret)
{
log_error (_("binding to '%s:%d' failed: %s\n"),
- host, port, strerror (errno));
+ host, port, ldap_err2string (ret));
ldap_unbind (ld);
return -1;
}
diff --git a/dirmngr/http.c b/dirmngr/http.c
index f0fcd0d..941ad4f 100644
--- a/dirmngr/http.c
+++ b/dirmngr/http.c
@@ -937,7 +937,7 @@ http_wait_response (http_t hd)
/* Shutdown one end of the socket is desired. As per HTTP/1.0 this
is not required but some very old servers (e.g. the original pksd
- key server didn't worked without it. */
+ keyserver didn't worked without it. */
if ((hd->flags & HTTP_FLAG_SHUTDOWN))
shutdown (hd->sock->fd, 1);
hd->in_data = 0;
diff --git a/dirmngr/ldap-wrapper.c b/dirmngr/ldap-wrapper.c
index c073f17..55fcd8b 100644
--- a/dirmngr/ldap-wrapper.c
+++ b/dirmngr/ldap-wrapper.c
@@ -695,10 +695,10 @@ ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[])
return err;
}
- err = gnupg_create_inbound_pipe (outpipe);
+ err = gnupg_create_inbound_pipe (outpipe, NULL, 0);
if (!err)
{
- err = gnupg_create_inbound_pipe (errpipe);
+ err = gnupg_create_inbound_pipe (errpipe, NULL, 0);
if (err)
{
close (outpipe[0]);
diff --git a/dirmngr/server.c b/dirmngr/server.c
index 80ce5b5..6eb6f1b 100644
--- a/dirmngr/server.c
+++ b/dirmngr/server.c
@@ -834,8 +834,6 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
uri = strconcat ("https://",
domain,
"/.well-known/openpgpkey/hu/",
- domain,
- "/",
encodedhash,
NULL);
if (!uri)
@@ -2442,22 +2440,13 @@ start_command_handler (assuan_fd_t fd)
if (!hello_line)
{
- size_t n;
- const char *cfgname;
-
- cfgname = opt.config_filename? opt.config_filename : "[none]";
-
- n = (30 + strlen (opt.homedir) + strlen (cfgname)
- + strlen (hello) + 1);
- hello_line = xmalloc (n+1);
- snprintf (hello_line, n,
- "Home: %s\n"
- "Config: %s\n"
- "%s",
- opt.homedir,
- cfgname,
- hello);
- hello_line[n] = 0;
+ hello_line = xtryasprintf
+ ("Home: %s\n"
+ "Config: %s\n"
+ "%s",
+ gnupg_homedir (),
+ opt.config_filename? opt.config_filename : "[none]",
+ hello);
}
ctrl->server_local->assuan_ctx = ctx;
diff --git a/doc/DETAILS b/doc/DETAILS
index 5ceab68..4b3f0af 100644
--- a/doc/DETAILS
+++ b/doc/DETAILS
@@ -341,10 +341,12 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
arguments in future versions.
** General status codes
-*** NEWSIG
+*** NEWSIG [<signers_uid>]
Is issued right before a signature verification starts. This is
- useful to define a context for parsing ERROR status messages. No
- arguments are currently defined.
+ useful to define a context for parsing ERROR status messages.
+ arguments are currently defined. If SIGNERS_UID is given and is
+ not "-" this is the percent escape value of the OpenPGP Signer's
+ User ID signature sub-packet.
*** GOODSIG <long_keyid_or_fpr> <username>
The signature with the keyid is good. For each signature only one
@@ -520,14 +522,17 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
letter 'T'.
*** NOTATION_
- There are actually two related status codes to convey notation
+ There are actually three related status codes to convey notation
data:
- NOTATION_NAME <name>
+ - NOTATION_FLAGS <critical> <human_readable>
- NOTATION_DATA <string>
- <name> and <string> are %XX escaped; the data may be split among
- several NOTATION_DATA lines.
+ <name> and <string> are %XX escaped. The data may be split among
+ several NOTATION_DATA lines. NOTATION_FLAGS is emitted after
+ NOTATION_NAME and gives the critical and human readable flags;
+ the flag values are either 0 or 1.
*** POLICY_URL <string>
Note that URL in <string> is %XX escaped.
@@ -548,7 +553,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
that case, this status tag does not appear.
*** ATTRIBUTE <arguments>
- The list or argemnts are:
+ The list or arguments are:
- <fpr>
- <octets>
- <type>
@@ -602,18 +607,29 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
- 13 :: Key disabled
- 14 :: Syntax error in specification
+ If no specific reason was given a previously emitted status code
+ KEY_CONSIDERED may be used to analyzed the problem.
+
Note that for historical reasons the INV_RECP status is also used
for gpgsm's SIGNER command where it relates to signer's of course.
Newer GnuPG versions are using INV_SGNR; applications should
ignore the INV_RECP during the sender's command processing once
they have seen an INV_SGNR. Different codes are used so that they
can be distinguish while doing an encrypt+sign operation.
+
*** NO_RECP <reserved>
Issued if no recipients are usable.
*** NO_SGNR <reserved>
Issued if no senders are usable.
+*** KEY_CONSIDERED <fpr> <flags>
+ Issued to explian the lookup of a key. FPR is the hexified
+ fingerprint of the primary key. The bit values for FLAGS are:
+
+ - 1 :: The key has not been selected.
+ - 2 :: All subkeys of the key are expired or have been revoked.
+
*** KEYEXPIRED <expire-timestamp>
The key has expired. expire-timestamp is the expiration time in
seconds since Epoch. This status line is not very useful because
@@ -677,7 +693,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
This status identifies the key and the userid for all following
Tofu information. The fingerprint is the fingerprint of the
- primary key and the mbox is in general the mailbox part of the
+ primary key and the mbox is in general the addr-spec part of the
userid encoded in UTF-8 and percent escaped.
*** TOFU_STATS <validity> <sign-count> 0 [<policy> [<tm1> <tm2>]]
@@ -719,8 +735,8 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
*** PKA_TRUST_
This is is one:
- - PKA_TRUST_GOOD <mailbox>
- - PKA_TRUST_BAD <mailbox>
+ - PKA_TRUST_GOOD <addr-spec>
+ - PKA_TRUST_BAD <addr-spec>
Depending on the outcome of the PKA check one of the above status
codes is emitted in addition to a =TRUST_*= status.
@@ -1250,7 +1266,7 @@ Status codes are:
/pks/lookup/<gnupg_formatierte_user_id>?op=<operation>
This can be implemented using Hurd's translator mechanism.
- However, I think the whole key server stuff has to be re-thought;
+ However, I think the whole keyserver stuff has to be re-thought;
I have some ideas and probably create a white paper.
** Algorithm names for the "keygen.algo" prompt
diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi
index 5b73d7b..e87442f 100644
--- a/doc/dirmngr.texi
+++ b/doc/dirmngr.texi
@@ -312,6 +312,7 @@ value to access HTTP servers.
@item --http-proxy @var{host}[:@var{port}]
@opindex http-proxy
+@efindex http_proxy
Use @var{host} and @var{port} to access HTTP servers. The use of this
option overrides the environment variable @env{http_proxy} regardless
whether @option{--honor-http-proxy} has been set.
diff --git a/doc/gnupg.texi b/doc/gnupg.texi
index d0e5199..c99c129 100644
--- a/doc/gnupg.texi
+++ b/doc/gnupg.texi
@@ -15,13 +15,22 @@
@macro mancont
@end macro
+
+
@c Create a separate index for command line options.
@defcodeindex op
-@c Merge the standard indexes into a single one.
+@c Create an index vor environment variables and files.
+@defcodeindex ef
+
+@c Merge the function index into the concept index.
@syncodeindex fn cp
+@c Merge the variable index into the concept index.
@syncodeindex vr cp
+@c Merge the keystroke index into the concept index.
@syncodeindex ky cp
+@c Merge the program index into the concept index.
@syncodeindex pg cp
+@c Merge the data type index into the concept index.
@syncodeindex tp cp
@c %**end of header
@copying
@@ -144,6 +153,7 @@ the administration and the architecture.
* Glossary:: Short description of terms used.
* Option Index:: Index to command line options.
+* Environment Index:: Index to environment variables and files.
* Index:: Index of concepts and symbol names.
@end menu
@@ -192,6 +202,11 @@ the administration and the architecture.
@printindex op
+@node Environment Index
+@unnumbered Environment Variable and File Index
+
+@printindex ef
+
@node Index
@unnumbered Index
diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
index 2989d3b..37774dd 100644
--- a/doc/gpg-agent.texi
+++ b/doc/gpg-agent.texi
@@ -85,6 +85,7 @@ gpg-connect-agent /bye
@end example
@noindent
+@efindex GPG_TTY
You should always add the following lines to your @code{.bashrc} or
whatever initialization file is used for all shell invocations:
@@ -295,6 +296,7 @@ debugging.
@itemx --csh
@opindex sh
@opindex csh
+@efindex SHELL
Format the info output in daemon mode for use with the standard Bourne
shell or the C-shell respectively. The default is to guess it based on
the environment variable @code{SHELL} which is correct in almost all
@@ -309,6 +311,7 @@ should in general not be used to avoid X-sniffing attacks.
@anchor{option --log-file}
@item --log-file @var{file}
@opindex log-file
+@efindex HKCU\Software\GNU\GnuPG:DefaultLogFile
Append all logging output to @var{file}. This is very helpful in seeing
what the agent actually does. If neither a log file nor a log file
descriptor has been set on a Windows platform, the Registry entry
@@ -337,6 +340,10 @@ internal cache of @command{gpg-agent} with passphrases.
Disallow or allow clients to use the loopback pinentry features; see
the option @option{pinentry-mode} for details. Allow is the default.
+The @option{--force} option of the Assuan command @command{DELETE_KEY}
+is also controlled by this option: The option is ignored if a loopback
+pinentry is disallowed.
+
@item --no-allow-external-cache
@opindex no-allow-external-cache
Tell Pinentry not to enable features which use an external cache for
@@ -609,7 +616,7 @@ agent. By default they may all be found in the current home directory
@table @file
@item gpg-agent.conf
-@cindex gpg-agent.conf
+@efindex gpg-agent.conf
This is the standard configuration file read by @command{gpg-agent} on
startup. It may contain any valid long option; the leading
two dashes may not be entered and the option may not be abbreviated.
@@ -619,6 +626,7 @@ agent. By default they may all be found in the current home directory
You should backup this file.
@item trustlist.txt
+@efindex trustlist.txt
This is the list of trusted keys. You should backup this file.
Comment lines, indicated by a leading hash mark, as well as empty
@@ -680,7 +688,7 @@ fails, try again using the chain validation model.
@item sshcontrol
-@cindex sshcontrol
+@efindex sshcontrol
This file is used when support for the secure shell agent protocol has
been enabled (@pxref{option --enable-ssh-support}). Only keys present in
this file are used in the SSH protocol. You should backup this file.
@@ -714,6 +722,7 @@ implicitly added to this list; i.e. there is no need to list them.
@end cartouche
@item private-keys-v1.d/
+@efindex private-keys-v1.d
This is the directory where gpg-agent stores the private keys. Each
key is stored in a file with the name made up of the keygrip and the
@@ -790,7 +799,7 @@ This signal is used for internal purposes.
@node Agent Examples
@section Examples
-It is important to set the GPG_TTY environment variable in
+It is important to set the environment variable @code{GPG_TTY} in
your login shell, for example in the @file{~/.bashrc} init script:
@cartouche
@@ -820,8 +829,17 @@ fi
@section Agent's Assuan Protocol
Note: this section does only document the protocol, which is used by
-GnuPG components; it does not deal with the ssh-agent protocol.
+GnuPG components; it does not deal with the ssh-agent protocol. To
+see the full specification of each command, use
+
+@example
+ gpg-connect-agent 'help COMMAND' /bye
+@end example
+@noindent
+or just 'help' to list all available commands.
+
+@noindent
The @command{gpg-agent} daemon is started on demand by the GnuPG
components.
diff --git a/doc/gpg.texi b/doc/gpg.texi
index 3cad361..be80450 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -342,7 +342,8 @@ fingerprints. This is the same output as @option{--list-keys} but with
the additional output of a line with the fingerprint. May also be
combined with @option{--list-sigs} or @option{--check-sigs}. If this
command is given twice, the fingerprints of all secondary keys are
-listed too.
+listed too. This command also forces pretty printing of fingerprints
+if the keyid format has been set to "none".
@item --list-packets
@opindex list-packets
@@ -376,13 +377,20 @@ safeguard against accidental deletion of multiple keys.
@item --delete-secret-keys @code{name}
@opindex delete-secret-keys
-Remove key from the secret keyring. In batch mode the key
-must be specified by fingerprint.
+gRemove key from the secret keyring. In batch mode the key must be
+specified by fingerprint. The option @option{--yes} can be used to
+advice gpg-agent not to request a confirmation. This extra
+pre-caution is done because @command{gpg} can't be sure that the
+secret key (as controlled by gpg-agent) is only used for the given
+OpenPGP public key.
+
@item --delete-secret-and-public-key @code{name}
@opindex delete-secret-and-public-key
Same as @option{--delete-key}, but if a secret key exists, it will be
removed first. In batch mode the key must be specified by fingerprint.
+The option @option{--yes} can be used to advice gpg-agent not to
+request a confirmation.
@item --export
@opindex export
@@ -592,7 +600,7 @@ This section explains the main commands for key management
@table @gnupgtabopt
-@item --quick-gen-key @code{user-id}
+@item --quick-gen-key @code{user-id} [@code{algo} [@code{usage} [@code{expire}]]]
@opindex quick-gen-key
This is a simple command to generate a standard key with one user id.
In contrast to @option{--gen-key} the key is generated directly
@@ -605,6 +613,13 @@ answer to a ``Continue?'' style confirmation prompt is required. In
case the user id already exists in the key ring a second prompt to
force the creation of the key will show up.
+If any of the optional arguments are given, only the primary key is
+created and no prompts are shown. For a description of these optional
+arguments see the command @code{--quick-addkey}. The @code{usage}
+accepts also the value ``cert'' which can be used to create a
+certification only primary key; the default is to a create
+certification and signing key.
+
If this command is used with @option{--batch},
@option{--pinentry-mode} has been set to @code{loopback}, and one of
the passphrase options (@option{--passphrase},
@@ -613,6 +628,35 @@ supplied passphrase is used for the new key and the agent does not ask
for it. To create a key without any protection @code{--passphrase ''}
may be used.
+@item --quick-addkey @code{fpr} [@code{algo} [@code{usage} [@code{expire}]]]
+@opindex quick-addkey
+Directly add a subkey to the key identified by the fingerprint
+@code{fpr}. Without the optional arguments an encryption subkey is
+added. If any of the arguments are given a more specific subkey is
+added.
+
+@code{algo} may be any of the supported algorithms or curve names given
+in the format as used by key listings. To use the default algorithm
+the string ``default'' or ``-'' can be used. Supported algorithms are
+``rsa'', ``dsa'', ``elg'', ``ed25519'', ``cv25519'', and other ECC
+curves. For example the string ``rsa'' adds an RSA key with the
+default key length; a string ``rsa4096'' requests that the key length
+is 4096 bits.
+
+Depending on the given @code{algo} the subkey may either be an
+encryption subkey or a signing subkey. If an algorithm is capable of
+signing and encryption and such a subkey is desired, a @code{usage}
+string must be given. This string is either ``default'' or ``-'' to
+keep the default or a comma delimited list of keywords: ``sign'' for a
+signing subkey, ``auth'' for an authentication subkey, and ``encr''
+for an encryption subkey (``encrypt'' can be used as alias for
+``encr''). The valid combinations depend on the algorithm.
+
+The @code{expire} argument can be used to specify an expiration date
+for the subkey. Several formats are supported; commonly the ISO
+YYYY-MM-DD format is used. The values ``never'', ``none'', or ``-''
+can be used for no expiration date.
+
@item --gen-key
@opindex gen-key
Generate a new key pair using the current default parameters. This is
@@ -629,6 +673,7 @@ There is also a feature which allows you to create keys in batch
mode. See the manual section ``Unattended key generation'' on how
to use this.
+
@item --gen-revoke @code{name}
@opindex gen-revoke
Generate a revocation certificate for the complete key. To only revoke
@@ -1247,8 +1292,8 @@ the opposite meaning. The options are:
Enable PKA lookups to verify sender addresses. Note that PKA is based
on DNS, and so enabling this option may disclose information on when
and what signatures are verified or to whom data is encrypted. This
- is similar to the "web bug" described for the auto-key-retrieve
- feature.
+ is similar to the "web bug" described for the @option{--auto-key-retrieve}
+ option.
@item pka-trust-increase
@opindex verify-options:pka-trust-increase
@@ -1296,9 +1341,10 @@ executing it from GnuPG does not make it secure.
@item --exec-path @code{string}
@opindex exec-path
+@efindex PATH
Sets a list of directories to search for photo viewers and keyserver
helpers. If not provided, keyserver helpers use the compiled-in
-default directory, and photo viewers use the $PATH environment
+default directory, and photo viewers use the @code{PATH} environment
variable.
Note, that on W32 system this value is ignored when searching for
keyserver helpers.
@@ -1635,13 +1681,34 @@ mechanisms, in the order they are to be tried:
@end table
-@item --keyid-format @code{short|0xshort|long|0xlong}
+@item --auto-key-retrieve
+@itemx --no-auto-key-retrieve
+@opindex auto-key-retrieve
+@opindex no-auto-key-retrieve
+This option enables the automatic retrieving of keys from a keyserver
+when verifying signatures made by keys that are not on the local
+keyring.
+
+If the method "wkd" is included in the list of methods given to
+@option{auto-key-locate}, the Signer's User ID is part of the
+signature, and the option @option{--disable-signer-uid} is not used,
+the "wkd" method may also be used to retrieve a key.
+
+Note that this option makes a "web bug" like behavior possible.
+Keyserver or Web Key Directory operators can see which keys you
+request, so by sending you a message signed by a brand new key (which
+you naturally will not have on your local keyring), the operator can
+tell both your IP address and the time when you verified the
+signature.
+
+@item --keyid-format @code{none|short|0xshort|long|0xlong}
@opindex keyid-format
-Select how to display key IDs. "short" is the traditional 8-character
-key ID. "long" is the more accurate (but less convenient)
-16-character key ID. Add an "0x" to either to include an "0x" at the
-beginning of the key ID, as in 0x99242560. Note that this option is
-ignored if the option --with-colons is used.
+Select how to display key IDs. "none" does not show the key ID at all
+but shows the fingerprint in a separate line. "short" is the
+traditional 8-character key ID. "long" is the more accurate (but less
+convenient) 16-character key ID. Add an "0x" to either to include an
+"0x" at the beginning of the key ID, as in 0x99242560. Note that this
+option is ignored if the option @option{--with-colons} is used.
@item --keyserver @code{name}
@opindex keyserver
@@ -1692,15 +1759,7 @@ are available for all keyserver types, some common options are:
used with HKP keyservers.
@item auto-key-retrieve
- This option enables the automatic retrieving of keys from a keyserver
- when verifying signatures made by keys that are not on the local
- keyring.
-
- Note that this option makes a "web bug" like behavior possible.
- Keyserver operators can see which keys you request, so by sending you
- a message signed by a brand new key (which you naturally will not have
- on your local keyring), the operator can tell both your IP address and
- the time when you verified the signature.
+ This is the same as the option @option{auto-key-retrieve}.
@item honor-keyserver-url
When using @option{--refresh-keys}, if the key in question has a preferred
@@ -1712,9 +1771,9 @@ are available for all keyserver types, some common options are:
refreshed. Thus this option is not enabled by default.
@item honor-pka-record
- If auto-key-retrieve is set, and the signature being verified has a
- PKA record, then use the PKA information to fetch the key. Defaults
- to "yes".
+ If @option{--auto-key-retrieve} is used, and the signature being
+ verified has a PKA record, then use the PKA information to fetch
+ the key. Defaults to "yes".
@item include-subkeys
When receiving a key, include subkeys as potential targets. Note that
@@ -1828,9 +1887,7 @@ file name.
@item --dirmngr-program @var{file}
@opindex dirmngr-program
Specify a dirmngr program to be used for keyserver access. The
-default value is @file{@value{BINDIR}/dirmngr}. This is only used as a
-fallback when the environment variable @code{DIRMNGR_INFO} is not set or
-a running dirmngr cannot be connected.
+default value is @file{@value{BINDIR}/dirmngr}.
@item --no-autostart
@opindex no-autostart
@@ -2231,6 +2288,14 @@ allow to convey suitable information for elliptic curves.
Same as the command @option{--fingerprint} but changes only the format
of the output and may be used together with another command.
+@item --with-subkey-fingerprint
+@opindex with-subkey-fingerprint
+If a fingerprint is printed for the primary key, this option forces
+printing of the fingerprint for all subkeys. This could also be
+achieved by using the @option{--with-fingerprint} twice but by using
+this option along with keyid-format "none" a compact fingerprint is
+printed.
+
@item --with-icao-spelling
@opindex with-icao-spelling
Print the ICAO spelling of the fingerprint in addition to the hex digits.
@@ -2290,6 +2355,14 @@ Disable the use of the modification detection code. Note that by
using this option, the encrypted message becomes vulnerable to a
message modification attack.
+@item --disable-signer-uid
+@opindex disable-signer-uid
+By default the user ID of the signing key is embedded in the data
+signature. As of now this is only done if the signing key has been
+specified with @option{local-user} using a mail address. This
+information can be helpful for verifier to locate the key; see
+option @option{--auto-key-retrieve}.
+
@item --personal-cipher-preferences @code{string}
@opindex personal-cipher-preferences
Set the list of personal cipher preferences to @code{string}. Use
@@ -3088,7 +3161,7 @@ current home directory (@pxref{option --homedir}).
@table @file
@item gpg.conf
- @cindex gpg.conf
+ @efindex gpg.conf
This is the standard configuration file read by @command{@gpgname} on
startup. It may contain any valid long option; the leading two dashes
may not be entered and the option may not be abbreviated. This default
@@ -3110,13 +3183,21 @@ files; They all live in in the current home directory (@pxref{option
@table @file
+ @item ~/.gnupg
+ @efindex ~/.gnupg
+ This is the default home directory which is used if neither the
+ environment variable @code{GNUPGHOME} nor the option
+ @option{--homedir} is given.
+
@item ~/.gnupg/pubring.gpg
+ @efindex pubring.gpg
The public keyring. You should backup this file.
@item ~/.gnupg/pubring.gpg.lock
The lock file for the public keyring.
@item ~/.gnupg/pubring.kbx
+ @efindex pubring.kbx
The public keyring using a different format. This file is sharred
with @command{gpgsm}. You should backup this file.
@@ -3124,13 +3205,19 @@ files; They all live in in the current home directory (@pxref{option
The lock file for @file{pubring.kbx}.
@item ~/.gnupg/secring.gpg
+ @efindex secring.gpg
A secret keyring as used by GnuPG versions before 2.1. It is not
used by GnuPG 2.1 and later.
+ @item ~/.gnupg/secring.gpg.lock
+ The lock file for the secret keyring.
+
@item ~/.gnupg/.gpg-v21-migrated
+ @efindex .gpg-v21-migrated
File indicating that a migration to GnuPG 2.1 has been done.
@item ~/.gnupg/trustdb.gpg
+ @efindex trustdb.gpg
The trust database. There is no need to backup this file; it is better
to backup the ownertrust values (@pxref{option --export-ownertrust}).
@@ -3138,12 +3225,11 @@ files; They all live in in the current home directory (@pxref{option
The lock file for the trust database.
@item ~/.gnupg/random_seed
+ @efindex random_seed
A file used to preserve the state of the internal random pool.
- @item ~/.gnupg/secring.gpg.lock
- The lock file for the secret keyring.
-
@item ~/.gnupg/openpgp-revocs.d/
+ @efindex openpgp-revocs.d
This is the directory where gpg stores pre-generated revocation
certificates. The file name corresponds to the OpenPGP fingerprint of
the respective key. It is suggested to backup those certificates and
@@ -3154,11 +3240,9 @@ files; They all live in in the current home directory (@pxref{option
this backup closed away.
@item @value{DATADIR}/options.skel
+ @efindex options.skel
The skeleton options file.
- @item @value{LIBDIR}/
- Default location for extensions.
-
@end table
@c man:.RE
@@ -3167,24 +3251,29 @@ Operation is further controlled by a few environment variables:
@table @asis
@item HOME
+ @efindex HOME
Used to locate the default home directory.
@item GNUPGHOME
+ @efindex GNUPGHOME
If set directory used instead of "~/.gnupg".
@item GPG_AGENT_INFO
- This variable was used by GnuPG versions before 2.1
+ This variable is obsolete; it was used by GnuPG versions before 2.1.
@item PINENTRY_USER_DATA
+ @efindex PINENTRY_USER_DATA
This value is passed via gpg-agent to pinentry. It is useful to convey
extra information to a custom pinentry.
@item COLUMNS
@itemx LINES
+ @efindex COLUMNS
+ @efindex LINES
Used to size some displays to the full size of the screen.
-
@item LANGUAGE
+ @efindex LANGUAGE
Apart from its use by GNU, it is used in the W32 version to override the
language selection done through the Registry. If used and set to a
valid and available language name (@var{langid}), the file with the
diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi
index b585975..2f6c297 100644
--- a/doc/gpgsm.texi
+++ b/doc/gpgsm.texi
@@ -357,9 +357,7 @@ suite hack and may thus not be used in the file name.
@item --dirmngr-program @var{file}
@opindex dirmngr-program
Specify a dirmngr program to be used for @acronym{CRL} checks. The
-default value is @file{@value{BINDIR}/dirmngr}. This is only used as a
-fallback when the environment variable @code{DIRMNGR_INFO} is not set or
-a running dirmngr cannot be connected.
+default value is @file{@value{BINDIR}/dirmngr}.
@item --prefer-system-dirmngr
@opindex prefer-system-dirmngr
@@ -800,7 +798,7 @@ current home directory (@pxref{option --homedir}).
@table @file
@item gpgsm.conf
-@cindex gpgsm.conf
+@efindex gpgsm.conf
This is the standard configuration file read by @command{gpgsm} on
startup. It may contain any valid long option; the leading two dashes
may not be entered and the option may not be abbreviated. This default
@@ -809,7 +807,7 @@ You should backup this file.
@item policies.txt
-@cindex policies.txt
+@efindex policies.txt
This is a list of allowed CA policies. This file should list the
object identifiers of the policies line by line. Empty lines and
lines starting with a hash mark are ignored. Policies missing in this
@@ -829,7 +827,7 @@ like this:
@c man:.RE
@item qualified.txt
-@cindex qualified.txt
+@efindex qualified.txt
This is the list of root certificates used for qualified certificates.
They are defined as certificates capable of creating legally binding
signatures in the same way as handwritten signatures are. Comments
@@ -865,7 +863,7 @@ Because this software has not yet been approved for use with such
certificates, appropriate notices will be shown to indicate this fact.
@item help.txt
-@cindex help.txt
+@efindex help.txt
This is plain text file with a few help entries used with
@command{pinentry} as well as a large list of help items for
@command{gpg} and @command{gpgsm}. The standard file has English help
@@ -879,7 +877,7 @@ For a reference of the help file's syntax, please see the installed
@item com-certs.pem
-@cindex com-certs.pem
+@efindex com-certs.pem
This file is a collection of common certificates used to populated a
newly created @file{pubring.kbx}. An administrator may replace this
file with a custom one. The format is a concatenation of PEM encoded
@@ -901,20 +899,20 @@ they all live in in the current home directory (@pxref{option
@table @file
@item pubring.kbx
-@cindex pubring.kbx
+@efindex pubring.kbx
This a database file storing the certificates as well as meta
information. For debugging purposes the tool @command{kbxutil} may be
used to show the internal structure of this file. You should backup
this file.
@item random_seed
-@cindex random_seed
+@efindex random_seed
This content of this file is used to maintain the internal state of the
random number generator across invocations. The same file is used by
other programs of this software too.
@item S.gpg-agent
-@cindex S.gpg-agent
+@efindex S.gpg-agent
If this file exists
@command{gpgsm} will first try to connect to this socket for
accessing @command{gpg-agent} before starting a new @command{gpg-agent}
@@ -1535,18 +1533,25 @@ set to the empty string, and if @code{<STRING>} is given it is set to
that string.
@item display
+@efindex DISPLAY
Set the session environment variable @code{DISPLAY} is set to @var{value}.
@item ttyname
+@efindex GPG_TTY
Set the session environment variable @code{GPG_TTY} is set to @var{value}.
@item ttytype
+@efindex TERM
Set the session environment variable @code{TERM} is set to @var{value}.
@item lc-ctype
+@efindex LC_CTYPE
Set the session environment variable @code{LC_CTYPE} is set to @var{value}.
@item lc-messages
+@efindex LC_MESSAGES
Set the session environment variable @code{LC_MESSAGES} is set to @var{value}.
@item xauthority
+@efindex XAUTHORITY
Set the session environment variable @code{XAUTHORITY} is set to @var{value}.
@item pinentry-user-data
+@efindex PINENTRY_USER_DATA
Set the session environment variable @code{PINENTRY_USER_DATA} is set
to @var{value}.
diff --git a/doc/opt-homedir.texi b/doc/opt-homedir.texi
index 7bcce46..e1ce077 100644
--- a/doc/opt-homedir.texi
+++ b/doc/opt-homedir.texi
@@ -1,6 +1,8 @@
@c This option is included at several places.
@item --homedir @var{dir}
@opindex homedir
+@efindex GNUPGHOME
+@efindex HKCU\Software\GNU\GnuPG:HomeDir
Set the name of the home directory to @var{dir}. If this option is not
used, the home directory defaults to @file{~/.gnupg}. It is only
recognized when given on the command line. It also overrides any home
@@ -12,6 +14,7 @@ On Windows systems it is possible to install GnuPG as a portable
application. In this case only this command line option is
considered, all other ways to set a home directory are ignored.
+@efindex gpgconf.ctl
To install GnuPG as a portable application under Windows, create an
empty file name @file{gpgconf.ctl} in the same directory as the tool
@file{gpgconf.exe}. The root of the installation is than that
diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi
index 7f1058b..5e53223 100644
--- a/doc/scdaemon.texi
+++ b/doc/scdaemon.texi
@@ -222,11 +222,12 @@ This option appends a thread ID to the PID in the log output.
@item --debug-assuan-log-cats @var{cats}
@opindex debug-assuan-log-cats
+@efindex ASSUAN_DEBUG
Changes the active Libassuan logging categories to @var{cats}. The
value for @var{cats} is an unsigned integer given in usual C-Syntax.
A value of of 0 switches to a default category. If this option is not
used the categories are taken from the environment variable
-@samp{ASSUAN_DEBUG}. Note that this option has only an effect if the
+@code{ASSUAN_DEBUG}. Note that this option has only an effect if the
Assuan debug flag has also been with the option @option{--debug}. For
a list of categories see the Libassuan manual.
diff --git a/doc/sysnotes.texi b/doc/sysnotes.texi
index a8cea87..dec07bd 100644
--- a/doc/sysnotes.texi
+++ b/doc/sysnotes.texi
@@ -11,28 +11,6 @@ right now, however there are probably a lot of smaller glitches we need
to fix first. The major problem areas are:
@itemize
-@item
-For logging to sockets and other internal operations the
-@code{fopencookie} function (@code{funopen} under *BSD) is used. This
-is a very convenient function which makes it possible to create outputs in
-a structures and easy maintainable way. The drawback however is that
-most proprietary OSes don't support this function. At g10@tie{}Code we
-have looked into several ways on how to overcome this limitation but no
-sufficiently easy and maintainable way has been found. Porting
-@emph{glibc} to a general POSIX system is of course an option and would
-make writing portable software much easier; this it has not yet been
-done and the system administrator would need to cope with the GNU
-specific admin things in addition to the generic ones of his system.
-
-We have now settled to use explicit stdio wrappers with a functionality
-similar to funopen. Although the code for this has already been written
-(@emph{libestream}), we have not yet changed GnuPG to use it.
-
-This means that on systems not supporting either @code{funopen} or
-@code{fopencookie}, logging to a socket won't work, prompts are not
-formatted as pretty as they should be and @command{gpgsm}'s
-@code{LISTKEYS} Assuan command does not work.
-
@item
We are planning to use file descriptor passing for interprocess
communication. This will allow us save a lot of resources and improve
@@ -78,9 +56,3 @@ The periodical smartcard status checking done by @command{scdaemon} is
not yet supported.
@end itemize
-
-
-
-
-
-
diff --git a/doc/tools.texi b/doc/tools.texi
index 425790e..8fdaa96 100644
--- a/doc/tools.texi
+++ b/doc/tools.texi
@@ -319,6 +319,17 @@ gpg-agent and scdaemon. Components which don't support reloading are
ignored. Note that as of now reload and kill have the same effect for
scdaemon.
+@item --create-socketdir
+@opindex create-socketdir
+Create a directory for sockets below /run/user or /var/run/user. This
+is command is only required if a non default home directory is used
+and the /run based sockets shall be used. For the default home
+directory GnUPG creates a directory on the fly.
+
+@item --remove-socketdir
+@opindex remove-socketdir
+Remove a directory created with command @option{--create-socketdir}.
+
@end table
diff --git a/doc/yat2m.c b/doc/yat2m.c
index 1634985..3de908c 100644
--- a/doc/yat2m.c
+++ b/doc/yat2m.c
@@ -705,6 +705,7 @@ proc_texi_cmd (FILE *fp, const char *command, const char *rest, size_t len,
{ "emph", 0, "\\fI", "\\fR" },
{ "w", 1 },
{ "c", 5 },
+ { "efindex", 1 },
{ "opindex", 1 },
{ "cpindex", 1 },
{ "cindex", 1 },
diff --git a/g10/Makefile.am b/g10/Makefile.am
index 18a1b69..fc33e83 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -74,7 +74,7 @@ trust_source = trustdb.c trustdb.h tdbdump.c tdbio.c tdbio.h
endif
if USE_TOFU
-tofu_source = tofu.h tofu.c sqlite.c sqlite.h
+tofu_source = tofu.h tofu.c gpgsql.c gpgsql.h
else
tofu_source =
endif
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 9b64967..2745734 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -301,6 +301,8 @@ write_fake_data (IOBUF out, gcry_mpi_t a)
if (!a)
return 0;
+ if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+ return 0; /* e.g. due to generating a key with wrong usage. */
p = gcry_mpi_get_opaque ( a, &n);
if (!p)
return 0; /* For example due to a read error in
@@ -329,7 +331,7 @@ do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
}
else
{
- write_header2( out, ctb, uid->len, 2 );
+ write_header2( out, ctb, uid->len, 0 );
rc = iobuf_write( out, uid->name, uid->len );
}
return rc;
@@ -1277,8 +1279,9 @@ sig_to_notation(PKT_signature *sig)
{
const byte *p;
size_t len;
- int seq=0,crit;
- struct notation *list=NULL;
+ int seq = 0;
+ int crit;
+ notation_t list = NULL;
/* See RFC 4880, 5.2.3.16 for the format of notation data. In
short, a notation has:
@@ -1323,6 +1326,7 @@ sig_to_notation(PKT_signature *sig)
n->value=xmalloc(n2+1);
memcpy(n->value,&p[8+n1],n2);
n->value[n2]='\0';
+ n->flags.human = 1;
}
else
/* Binary data. */
diff --git a/g10/call-agent.c b/g10/call-agent.c
index c5bd694..a023654 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -303,7 +303,6 @@ start_agent (ctrl_t ctrl, int for_card)
{
rc = start_new_gpg_agent (&agent_ctx,
GPG_ERR_SOURCE_DEFAULT,
- opt.homedir,
opt.agent_program,
opt.lc_ctype, opt.lc_messages,
opt.session_env,
@@ -1672,28 +1671,35 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
+struct keyinfo_data_parm_s
+{
+ char *serialno;
+ int cleartext;
+};
+
+
static gpg_error_t
keyinfo_status_cb (void *opaque, const char *line)
{
- char **serialno = opaque;
- const char *s, *s2;
+ struct keyinfo_data_parm_s *data = opaque;
+ int is_smartcard;
+ char *s;
- if ((s = has_leading_keyword (line, "KEYINFO")) && !*serialno)
+ if ((s = has_leading_keyword (line, "KEYINFO")) && data)
{
- s = strchr (s, ' ');
- if (s && s[1] == 'T' && s[2] == ' ' && s[3])
+ /* Parse the arguments:
+ * 0 1 2 3 4 5
+ * <keygrip> <type> <serialno> <idstr> <cached> <protection>
+ */
+ char *fields[6];
+
+ if (split_fields (s, fields, DIM (fields)) == 6)
{
- s += 3;
- s2 = strchr (s, ' ');
- if ( s2 > s )
- {
- *serialno = xtrymalloc ((s2 - s)+1);
- if (*serialno)
- {
- memcpy (*serialno, s, s2 - s);
- (*serialno)[s2 - s] = 0;
- }
- }
+ is_smartcard = (fields[1][0] == 'T');
+ if (is_smartcard && !data->serialno && strcmp (fields[2], "-"))
+ data->serialno = xtrystrdup (fields[2]);
+ /* 'P' for protected, 'C' for clear */
+ data->cleartext = (fields[5][0] == 'C');
}
}
return 0;
@@ -1702,13 +1708,20 @@ keyinfo_status_cb (void *opaque, const char *line)
/* Return the serial number for a secret key. If the returned serial
number is NULL, the key is not stored on a smartcard. Caller needs
- to free R_SERIALNO. */
+ to free R_SERIALNO.
+
+ if r_cleartext is not NULL, the referenced int will be set to 1 if
+ the agent's copy of the key is stored in the clear, or 0 otherwise
+*/
gpg_error_t
-agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
+agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
+ char **r_serialno, int *r_cleartext)
{
gpg_error_t err;
char line[ASSUAN_LINELENGTH];
- char *serialno = NULL;
+ struct keyinfo_data_parm_s keyinfo;
+
+ memset (&keyinfo, 0,sizeof keyinfo);
*r_serialno = NULL;
@@ -1723,17 +1736,21 @@ agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
line[DIM(line)-1] = 0;
err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
- keyinfo_status_cb, &serialno);
- if (!err && serialno)
+ keyinfo_status_cb, &keyinfo);
+ if (!err && keyinfo.serialno)
{
/* Sanity check for bad characters. */
- if (strpbrk (serialno, ":\n\r"))
+ if (strpbrk (keyinfo.serialno, ":\n\r"))
err = GPG_ERR_INV_VALUE;
}
if (err)
- xfree (serialno);
+ xfree (keyinfo.serialno);
else
- *r_serialno = serialno;
+ {
+ *r_serialno = keyinfo.serialno;
+ if (r_cleartext)
+ *r_cleartext = keyinfo.cleartext;
+ }
return err;
}
@@ -1805,7 +1822,7 @@ inq_genkey_parms (void *opaque, const char *line)
PASSPHRASE is not NULL the agent is requested to protect the key
with that passphrase instead of asking for one. */
gpg_error_t
-agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
+agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, char **passwd_nonce_addr,
const char *keyparms, int no_protection,
const char *passphrase, gcry_sexp_t *r_pubkey)
{
@@ -1827,19 +1844,26 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
return err;
dfltparm.ctx = agent_ctx;
- err = assuan_transact (agent_ctx, "RESET",
- NULL, NULL, NULL, NULL, NULL, NULL);
- if (err)
- return err;
+ if (passwd_nonce_addr && *passwd_nonce_addr)
+ ; /* A RESET would flush the passwd nonce cache. */
+ else
+ {
+ err = assuan_transact (agent_ctx, "RESET",
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if (err)
+ return err;
+ }
init_membuf (&data, 1024);
gk_parm.dflt = &dfltparm;
gk_parm.keyparms = keyparms;
gk_parm.passphrase = passphrase;
- snprintf (line, sizeof line, "GENKEY%s%s%s",
+ snprintf (line, sizeof line, "GENKEY%s%s%s%s%s",
no_protection? " --no-protection" :
passphrase ? " --inq-passwd" :
/* */ "",
+ passwd_nonce_addr && *passwd_nonce_addr? " --passwd-nonce=":"",
+ passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
cache_nonce_addr && *cache_nonce_addr? " ":"",
cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
cn_parm.cache_nonce_addr = cache_nonce_addr;
@@ -2284,13 +2308,15 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
/* Receive a secret key from the agent. HEXKEYGRIP is the hexified
keygrip, DESC a prompt to be displayed with the agent's passphrase
- question (needs to be plus+percent escaped). If CACHE_NONCE_ADDR
- is not NULL the agent is advised to first try a passphrase
- associated with that nonce. On success the key is stored as a
- canonical S-expression at R_RESULT and R_RESULTLEN. */
+ question (needs to be plus+percent escaped). if OPENPGP_PROTECTED
+ is not zero, ensure that the key material is returned in RFC
+ 4880-compatible passphrased-protected form. If CACHE_NONCE_ADDR is
+ not NULL the agent is advised to first try a passphrase associated
+ with that nonce. On success the key is stored as a canonical
+ S-expression at R_RESULT and R_RESULTLEN. */
gpg_error_t
agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
- char **cache_nonce_addr,
+ int openpgp_protected, char **cache_nonce_addr,
unsigned char **r_result, size_t *r_resultlen)
{
gpg_error_t err;
@@ -2320,7 +2346,8 @@ agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
return err;
}
- snprintf (line, DIM(line)-1, "EXPORT_KEY --openpgp %s%s %s",
+ snprintf (line, DIM(line)-1, "EXPORT_KEY %s%s%s %s",
+ openpgp_protected ? "--openpgp ":"",
cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
hexkeygrip);
@@ -2349,9 +2376,11 @@ agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
/* Ask the agent to delete the key identified by HEXKEYGRIP. If DESC
is not NULL, display DESC instead of the default description
- message. */
+ message. If FORCE is true the agent is advised not to ask for
+ confirmation. */
gpg_error_t
-agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc)
+agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
+ int force)
{
gpg_error_t err;
char line[ASSUAN_LINELENGTH];
@@ -2376,7 +2405,8 @@ agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc)
return err;
}
- snprintf (line, DIM(line)-1, "DELETE_KEY %s", hexkeygrip);
+ snprintf (line, DIM(line)-1, "DELETE_KEY%s %s",
+ force? " --force":"", hexkeygrip);
err = assuan_transact (agent_ctx, line, NULL, NULL,
default_inq_cb, &dfltparm,
NULL, NULL);
@@ -2386,13 +2416,14 @@ agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc)
/* Ask the agent to change the passphrase of the key identified by
- HEXKEYGRIP. If DESC is not NULL, display DESC instead of the
- default description message. If CACHE_NONCE_ADDR is not NULL the
- agent is advised to first try a passphrase associated with that
- nonce. If PASSWD_NONCE_ADDR is not NULL the agent will try to use
- the passphrase associated with that nonce. */
+ * HEXKEYGRIP. If DESC is not NULL, display DESC instead of the
+ * default description message. If CACHE_NONCE_ADDR is not NULL the
+ * agent is advised to first try a passphrase associated with that
+ * nonce. If PASSWD_NONCE_ADDR is not NULL the agent will try to use
+ * the passphrase associated with that nonce for the new passphrase.
+ * If VERIFY is true the passphrase is only verified. */
gpg_error_t
-agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
+agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc, int verify,
char **cache_nonce_addr, char **passwd_nonce_addr)
{
gpg_error_t err;
@@ -2411,7 +2442,6 @@ agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
if (!hexkeygrip || strlen (hexkeygrip) != 40)
return gpg_error (GPG_ERR_INV_VALUE);
-
if (desc)
{
snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
@@ -2421,12 +2451,18 @@ agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
return err;
}
- snprintf (line, DIM(line)-1, "PASSWD %s%s %s%s %s",
- cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
- cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
- passwd_nonce_addr && *passwd_nonce_addr? "--passwd-nonce=":"",
- passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
- hexkeygrip);
+ if (verify)
+ snprintf (line, DIM(line)-1, "PASSWD %s%s --verify %s",
+ cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
+ cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
+ hexkeygrip);
+ else
+ snprintf (line, DIM(line)-1, "PASSWD %s%s %s%s %s",
+ cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
+ cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
+ passwd_nonce_addr && *passwd_nonce_addr? "--passwd-nonce=":"",
+ passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
+ hexkeygrip);
cn_parm.cache_nonce_addr = cache_nonce_addr;
cn_parm.passwd_nonce_addr = passwd_nonce_addr;
err = assuan_transact (agent_ctx, line, NULL, NULL,
@@ -2435,6 +2471,7 @@ agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
return err;
}
+
/* Return the version reported by gpg-agent. */
gpg_error_t
agent_get_version (ctrl_t ctrl, char **r_version)
diff --git a/g10/call-agent.h b/g10/call-agent.h
index 208b75b..d85a6fd 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -153,10 +153,11 @@ gpg_error_t agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock);
/* Return infos about the secret key with HEXKEYGRIP. */
gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
- char **r_serialno);
+ char **r_serialno, int *r_cleartext);
/* Generate a new key. */
-gpg_error_t agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
+gpg_error_t agent_genkey (ctrl_t ctrl,
+ char **cache_nonce_addr, char **passwd_nonce_addr,
const char *keyparms, int no_protection,
const char *passphrase,
gcry_sexp_t *r_pubkey);
@@ -191,15 +192,17 @@ gpg_error_t agent_import_key (ctrl_t ctrl, const char *desc,
/* Receive a key from the agent. */
gpg_error_t agent_export_key (ctrl_t ctrl, const char *keygrip,
- const char *desc, char **cache_nonce_addr,
+ const char *desc, int openpgp_protected,
+ char **cache_nonce_addr,
unsigned char **r_result, size_t *r_resultlen);
/* Delete a key from the agent. */
gpg_error_t agent_delete_key (ctrl_t ctrl, const char *hexkeygrip,
- const char *desc);
+ const char *desc, int force);
/* Change the passphrase of a key. */
gpg_error_t agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
+ int verify,
char **cache_nonce_addr, char **passwd_nonce_addr);
/* Get the version reported by gpg-agent. */
gpg_error_t agent_get_version (ctrl_t ctrl, char **r_version);
diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
index d35a5cf..75a7f46 100644
--- a/g10/call-dirmngr.c
+++ b/g10/call-dirmngr.c
@@ -177,7 +177,6 @@ create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
*r_ctx = NULL;
err = start_new_dirmngr (&ctx,
GPG_ERR_SOURCE_DEFAULT,
- opt.homedir,
opt.dirmngr_program,
opt.autostart, opt.verbose, DBG_IPC,
NULL /*gpg_status2*/, ctrl);
diff --git a/g10/delkey.c b/g10/delkey.c
index f76277c..966c571 100644
--- a/g10/delkey.c
+++ b/g10/delkey.c
@@ -184,8 +184,14 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
prompt = gpg_format_keydesc (node->pkt->pkt.public_key,
FORMAT_KEYDESC_DELKEY, 1);
err = hexkeygrip_from_pk (node->pkt->pkt.public_key, &hexgrip);
+ /* NB: We require --yes to advise the agent not to
+ * request a confirmation. The rationale for this extra
+ * pre-caution is that since 2.1 the secret key may also
+ * be used for other protocols and thus deleting it from
+ * the gpg would also delete the key for other tools. */
if (!err)
- err = agent_delete_key (NULL, hexgrip, prompt);
+ err = agent_delete_key (NULL, hexgrip, prompt,
+ opt.answer_yes);
xfree (prompt);
xfree (hexgrip);
if (err)
diff --git a/g10/export.c b/g10/export.c
index 89604b4..b067376 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -391,6 +391,78 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
}
+/* Return an error if the key represented by the S-expression S_KEY
+ * and the OpenPGP key represented by PK do not use the same curve. */
+static gpg_error_t
+match_curve_skey_pk (gcry_sexp_t s_key, PKT_public_key *pk)
+{
+ gcry_sexp_t curve = NULL;
+ gcry_sexp_t flags = NULL;
+ char *curve_str = NULL;
+ char *flag;
+ const char *oidstr = NULL;
+ gcry_mpi_t curve_as_mpi = NULL;
+ gpg_error_t err;
+ int is_eddsa = 0;
+ int idx = 0;
+
+ if (!(pk->pubkey_algo==PUBKEY_ALGO_ECDH
+ || pk->pubkey_algo==PUBKEY_ALGO_ECDSA
+ || pk->pubkey_algo==PUBKEY_ALGO_EDDSA))
+ return gpg_error (GPG_ERR_PUBKEY_ALGO);
+
+ curve = gcry_sexp_find_token (s_key, "curve", 0);
+ if (!curve)
+ {
+ log_error ("no reported curve\n");
+ return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+ }
+ curve_str = gcry_sexp_nth_string (curve, 1);
+ gcry_sexp_release (curve); curve = NULL;
+ if (!curve_str)
+ {
+ log_error ("no curve name\n");
+ return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+ }
+ oidstr = openpgp_curve_to_oid (curve_str, NULL);
+ if (!oidstr)
+ {
+ log_error ("no OID known for curve '%s'\n", curve_str);
+ xfree (curve_str);
+ return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+ }
+ xfree (curve_str);
+ err = openpgp_oid_from_str (oidstr, &curve_as_mpi);
+ if (err)
+ return err;
+ if (gcry_mpi_cmp (pk->pkey[0], curve_as_mpi))
+ {
+ log_error ("curves do not match\n");
+ gcry_mpi_release (curve_as_mpi);
+ return gpg_error (GPG_ERR_INV_CURVE);
+ }
+ gcry_mpi_release (curve_as_mpi);
+ flags = gcry_sexp_find_token (s_key, "flags", 0);
+ if (flags)
+ {
+ for (idx = 1; idx < gcry_sexp_length (flags); idx++)
+ {
+ flag = gcry_sexp_nth_string (flags, idx);
+ if (flag && (strcmp ("eddsa", flag) == 0))
+ is_eddsa = 1;
+ gcry_free (flag);
+ }
+ }
+ if (is_eddsa != (pk->pubkey_algo == PUBKEY_ALGO_EDDSA))
+ {
+ log_error ("disagreement about EdDSA\n");
+ err = gpg_error (GPG_ERR_INV_CURVE);
+ }
+
+ return err;
+}
+
+
/* Return a canonicalized public key algoithms. This is used to
compare different flavors of algorithms (e.g. ELG and ELG_E are
considered the same). */
@@ -412,6 +484,175 @@ canon_pk_algo (enum gcry_pk_algos algo)
}
+/* Take a cleartext dump of a secret key in PK and change the
+ * parameter array in PK to include the secret parameters. */
+static gpg_error_t
+cleartext_secret_key_to_openpgp (gcry_sexp_t s_key, PKT_public_key *pk)
+{
+ gpg_error_t err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ gcry_sexp_t top_list;
+ gcry_sexp_t key = NULL;
+ char *key_type = NULL;
+ enum gcry_pk_algos pk_algo;
+ struct seckey_info *ski;
+ int idx, sec_start;
+ gcry_mpi_t pub_params[10] = { NULL };
+
+ /* we look for a private-key, then the first element in it tells us
+ the type */
+ top_list = gcry_sexp_find_token (s_key, "private-key", 0);
+ if (!top_list)
+ goto bad_seckey;
+ if (gcry_sexp_length(top_list) != 2)
+ goto bad_seckey;
+ key = gcry_sexp_nth (top_list, 1);
+ if (!key)
+ goto bad_seckey;
+ key_type = gcry_sexp_nth_string(key, 0);
+ pk_algo = gcry_pk_map_name (key_type);
+
+ log_assert (!pk->seckey_info);
+
+ pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
+ if (!ski)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ switch (canon_pk_algo (pk_algo))
+ {
+ case GCRY_PK_RSA:
+ if (!is_RSA (pk->pubkey_algo))
+ goto bad_pubkey_algo;
+ err = gcry_sexp_extract_param (key, NULL, "ne",
+ &pub_params[0],
+ &pub_params[1],
+ NULL);
+ for (idx=0; idx < 2 && !err; idx++)
+ if (gcry_mpi_cmp(pk->pkey[idx], pub_params[idx]))
+ err = gpg_error (GPG_ERR_BAD_PUBKEY);
+ if (!err)
+ {
+ for (idx = 2; idx < 6 && !err; idx++)
+ {
+ gcry_mpi_release (pk->pkey[idx]);
+ pk->pkey[idx] = NULL;
+ }
+ err = gcry_sexp_extract_param (key, NULL, "dpqu",
+ &pk->pkey[2],
+ &pk->pkey[3],
+ &pk->pkey[4],
+ &pk->pkey[5],
+ NULL);
+ }
+ if (!err)
+ {
+ for (idx = 2; idx < 6; idx++)
+ ski->csum += checksum_mpi (pk->pkey[idx]);
+ }
+ break;
+
+ case GCRY_PK_DSA:
+ if (!is_DSA (pk->pubkey_algo))
+ goto bad_pubkey_algo;
+ err = gcry_sexp_extract_param (key, NULL, "pqgy",
+ &pub_params[0],
+ &pub_params[1],
+ &pub_params[2],
+ &pub_params[3],
+ NULL);
+ for (idx=0; idx < 4 && !err; idx++)
+ if (gcry_mpi_cmp(pk->pkey[idx], pub_params[idx]))
+ err = gpg_error (GPG_ERR_BAD_PUBKEY);
+ if (!err)
+ {
+ gcry_mpi_release (pk->pkey[4]);
+ pk->pkey[4] = NULL;
+ err = gcry_sexp_extract_param (key, NULL, "x",
+ &pk->pkey[4],
+ NULL);
+ }
+ if (!err)
+ ski->csum += checksum_mpi (pk->pkey[4]);
+ break;
+
+ case GCRY_PK_ELG:
+ if (!is_ELGAMAL (pk->pubkey_algo))
+ goto bad_pubkey_algo;
+ err = gcry_sexp_extract_param (key, NULL, "pgy",
+ &pub_params[0],
+ &pub_params[1],
+ &pub_params[2],
+ NULL);
+ for (idx=0; idx < 3 && !err; idx++)
+ if (gcry_mpi_cmp(pk->pkey[idx], pub_params[idx]))
+ err = gpg_error (GPG_ERR_BAD_PUBKEY);
+ if (!err)
+ {
+ gcry_mpi_release (pk->pkey[3]);
+ pk->pkey[3] = NULL;
+ err = gcry_sexp_extract_param (key, NULL, "x",
+ &pk->pkey[3],
+ NULL);
+ }
+ if (!err)
+ ski->csum += checksum_mpi (pk->pkey[3]);
+ break;
+
+ case GCRY_PK_ECC:
+ err = match_curve_skey_pk (key, pk);
+ if (err)
+ goto leave;
+ if (!err)
+ err = gcry_sexp_extract_param (key, NULL, "q",
+ &pub_params[0],
+ NULL);
+ if (!err && (gcry_mpi_cmp(pk->pkey[1], pub_params[0])))
+ err = gpg_error (GPG_ERR_BAD_PUBKEY);
+
+ sec_start = 2;
+ if (pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+ sec_start += 1;
+ if (!err)
+ {
+ gcry_mpi_release (pk->pkey[sec_start]);
+ pk->pkey[sec_start] = NULL;
+ err = gcry_sexp_extract_param (key, NULL, "d",
+ &pk->pkey[sec_start],
+ NULL);
+ }
+
+ if (!err)
+ ski->csum += checksum_mpi (pk->pkey[sec_start]);
+ break;
+
+ default:
+ pk->seckey_info = NULL;
+ xfree (ski);
+ err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ break;
+ }
+
+ leave:
+ gcry_sexp_release (top_list);
+ gcry_sexp_release (key);
+ gcry_free (key_type);
+
+ for (idx=0; idx < DIM(pub_params); idx++)
+ gcry_mpi_release (pub_params[idx]);
+ return err;
+
+ bad_pubkey_algo:
+ err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+ goto leave;
+
+ bad_seckey:
+ err = gpg_error (GPG_ERR_BAD_SECKEY);
+ goto leave;
+}
+
+
/* Use the key transfer format given in S_PGP to create the secinfo
structure in PK and change the parameter array in PK to include the
secret parameters. */
@@ -831,12 +1072,17 @@ print_status_exported (PKT_public_key *pk)
*
* Since the key data from agant is encrypted, decrypt it by CIPHERHD.
* Then, parse the decrypted key data in transfer format, and put
- * secret papameters into PK.
+ * secret parameters into PK.
+ *
+ * If CLEARTEXT is 0, store the secret key material
+ * passphrase-protected. Otherwise, store secret key material in the
+ * clear.
*
* CACHE_NONCE_ADDR is used to share nonce for multple key retrievals.
*/
gpg_error_t
receive_seckey_from_agent (ctrl_t ctrl, gcry_cipher_hd_t cipherhd,
+ int cleartext,
char **cache_nonce_addr, const char *hexgrip,
PKT_public_key *pk)
{
@@ -852,7 +1098,7 @@ receive_seckey_from_agent (ctrl_t ctrl, gcry_cipher_hd_t cipherhd,
log_info ("key %s: asking agent for the secret parts\n", hexgrip);
prompt = gpg_format_keydesc (pk, FORMAT_KEYDESC_EXPORT,1);
- err = agent_export_key (ctrl, hexgrip, prompt, cache_nonce_addr,
+ err = agent_export_key (ctrl, hexgrip, prompt, !cleartext, cache_nonce_addr,
&wrappedkey, &wrappedkeylen);
xfree (prompt);
@@ -880,7 +1126,10 @@ receive_seckey_from_agent (ctrl_t ctrl, gcry_cipher_hd_t cipherhd,
err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
if (!err)
{
- err = transfer_format_to_openpgp (s_skey, pk);
+ if (cleartext)
+ err = cleartext_secret_key_to_openpgp (s_skey, pk);
+ else
+ err = transfer_format_to_openpgp (s_skey, pk);
gcry_sexp_release (s_skey);
}
@@ -924,6 +1173,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
gcry_cipher_hd_t cipherhd = NULL;
char *cache_nonce = NULL;
struct export_stats_s dummystats;
+ int cleartext = 0;
if (!stats)
stats = &dummystats;
@@ -1228,7 +1478,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
serialno = NULL;
}
else
- err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
+ err = agent_get_keyinfo (ctrl, hexgrip, &serialno, &cleartext);
if ((!err && serialno)
&& secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
@@ -1276,7 +1526,8 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
}
else if (!err)
{
- err = receive_seckey_from_agent (ctrl, cipherhd, &cache_nonce,
+ err = receive_seckey_from_agent (ctrl, cipherhd,
+ cleartext, &cache_nonce,
hexgrip, pk);
if (err)
{
diff --git a/g10/free-packet.c b/g10/free-packet.c
index 8176e36..3883f87 100644
--- a/g10/free-packet.c
+++ b/g10/free-packet.c
@@ -82,6 +82,7 @@ free_seckey_enc( PKT_signature *sig )
xfree (sig->pka_info->uri);
xfree (sig->pka_info);
}
+ xfree (sig->signers_uid);
xfree(sig);
}
@@ -258,6 +259,8 @@ copy_signature( PKT_signature *d, PKT_signature *s )
d->pka_info = s->pka_info? cp_pka_info (s->pka_info) : NULL;
d->hashed = cp_subpktarea (s->hashed);
d->unhashed = cp_subpktarea (s->unhashed);
+ if (s->signers_uid)
+ d->signers_uid = xstrdup (s->signers_uid);
if(s->numrevkeys)
{
d->revkey=NULL;
diff --git a/g10/getkey.c b/g10/getkey.c
index 907007b..ad0148e 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -38,6 +38,7 @@
#include "call-agent.h"
#include "host2net.h"
#include "mbox-util.h"
+#include "status.h"
#define MAX_PK_CACHE_ENTRIES PK_UID_CACHE_SIZE
#define MAX_UID_CACHE_ENTRIES PK_UID_CACHE_SIZE
@@ -46,6 +47,13 @@
#error We need the cache for key creation
#endif
+/* Flags values returned by the lookup code. Note that the values are
+ * directly used by the KEY_CONSIDERED status line. */
+#define LOOKUP_NOT_SELECTED (1<<0)
+#define LOOKUP_ALL_SUBKEYS_EXPIRED (1<<1) /* or revoked */
+
+
+/* A context object used by the lookup functions. */
struct getkey_ctx_s
{
/* Part of the search criteria: whether the search is an exact
@@ -3045,51 +3053,54 @@ merge_selfsigs (KBNODE keyblock)
/* See whether the key satisfies any additional requirements specified
- in CTX. If so, return 1 and set CTX->FOUND_KEY to an appropriate
- key or subkey. Otherwise, return 0 if there was no appropriate
- key.
-
- In case the primary key is not required, select a suitable subkey.
- We need the primary key if PUBKEY_USAGE_CERT is set in
- CTX->REQ_USAGE or we are in PGP6 or PGP7 mode and PUBKEY_USAGE_SIG
- is set in CTX->REQ_USAGE.
-
- If any of PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT
- are set in CTX->REQ_USAGE, we filter by the key's function.
- Concretely, if PUBKEY_USAGE_SIG and PUBKEY_USAGE_CERT are set, then
- we only return a key if it is (at least) either a signing or a
- certification key.
-
- If CTX->REQ_USAGE is set, then we reject any keys that are not good
- (i.e., valid, not revoked, not expired, etc.). This allows the
- getkey functions to be used for plain key listings.
-
- Sets the matched key's user id field (pk->user_id) to the user id
- that matched the low-level search criteria or NULL.
-
-
- This function needs to handle several different cases:
-
- 1. No requested usage and no primary key requested
- Examples for this case are that we have a keyID to be used
- for decrytion or verification.
- 2. No usage but primary key requested
- This is the case for all functions which work on an
- entire keyblock, e.g. for editing or listing
- 3. Usage and primary key requested
- FXME
- 4. Usage but no primary key requested
- FIXME
-
+ * in CTX. If so, return 1 and set CTX->FOUND_KEY to an appropriate
+ * key or subkey. Otherwise, return 0 if there was no appropriate
+ * key.
+ *
+ * In case the primary key is not required, select a suitable subkey.
+ * We need the primary key if PUBKEY_USAGE_CERT is set in
+ * CTX->REQ_USAGE or we are in PGP6 or PGP7 mode and PUBKEY_USAGE_SIG
+ * is set in CTX->REQ_USAGE.
+ *
+ * If any of PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT
+ * are set in CTX->REQ_USAGE, we filter by the key's function.
+ * Concretely, if PUBKEY_USAGE_SIG and PUBKEY_USAGE_CERT are set, then
+ * we only return a key if it is (at least) either a signing or a
+ * certification key.
+ *
+ * If CTX->REQ_USAGE is set, then we reject any keys that are not good
+ * (i.e., valid, not revoked, not expired, etc.). This allows the
+ * getkey functions to be used for plain key listings.
+ *
+ * Sets the matched key's user id field (pk->user_id) to the user id
+ * that matched the low-level search criteria or NULL. If R_FLAGS is
+ * not NULL set certain flags for more detailed error reporting. Used
+ * flags are:
+ * - LOOKUP_ALL_SUBKEYS_EXPIRED :: All Subkeys are expired or have
+ * been revoked.
+ *
+ * This function needs to handle several different cases:
+ *
+ * 1. No requested usage and no primary key requested
+ * Examples for this case are that we have a keyID to be used
+ * for decrytion or verification.
+ * 2. No usage but primary key requested
+ * This is the case for all functions which work on an
+ * entire keyblock, e.g. for editing or listing
+ * 3. Usage and primary key requested
+ * FIXME
+ * 4. Usage but no primary key requested
+ * FIXME
+ *
*/
-static KBNODE
-finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
+static kbnode_t
+finish_lookup (getkey_ctx_t ctx, kbnode_t keyblock, unsigned int *r_flags)
{
- KBNODE k;
+ kbnode_t k;
/* If CTX->EXACT is set, the key or subkey that actually matched the
low-level search criteria. */
- KBNODE foundk = NULL;
+ kbnode_t foundk = NULL;
/* The user id (if any) that matched the low-level search criteria. */
PKT_user_id *foundu = NULL;
@@ -3100,21 +3111,23 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
if signing data while --pgp6 or --pgp7 is on since pgp 6 and 7
do not understand signatures made by a signing subkey. PGP 8
does. */
- int req_prim = (ctx->req_usage & PUBKEY_USAGE_CERT) ||
- ((PGP6 || PGP7) && (ctx->req_usage & PUBKEY_USAGE_SIG));
+ int req_prim = ((ctx->req_usage & PUBKEY_USAGE_CERT)
+ || ((PGP6 || PGP7) && (ctx->req_usage & PUBKEY_USAGE_SIG)));
u32 curtime = make_timestamp ();
u32 latest_date;
- KBNODE latest_key;
+ kbnode_t latest_key;
PKT_public_key *pk;
-
log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
+ if (r_flags)
+ *r_flags = 0;
+
+ /* For an exact match mark the primary or subkey that matched the
+ low-level search criteria. */
if (ctx->exact)
- /* Get the key or subkey that matched the low-level search
- criteria. */
{
for (k = keyblock; k; k = k->next)
{
@@ -3154,24 +3167,28 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
latest_date = 0;
latest_key = NULL;
- /* Set latest_key to the latest (the one with the most recent
- timestamp) good (valid, not revoked, not expired, etc.) subkey.
-
- Don't bother if we are only looking for a primary key or we need
- an exact match and the exact match is not a subkey. */
+ /* Set LATEST_KEY to the latest (the one with the most recent
+ * timestamp) good (valid, not revoked, not expired, etc.) subkey.
+ *
+ * Don't bother if we are only looking for a primary key or we need
+ * an exact match and the exact match is not a subkey. */
if (req_prim || (foundk && foundk->pkt->pkttype != PKT_PUBLIC_SUBKEY))
;
else
{
- KBNODE nextk;
+ kbnode_t nextk;
+ int n_subkeys = 0;
+ int n_revoked_or_expired = 0;
/* Either start a loop or check just this one subkey. */
for (k = foundk ? foundk : keyblock; k; k = nextk)
{
if (foundk)
- /* If FOUNDK is not NULL, then only consider that exact
- key, i.e., don't iterate. */
- nextk = NULL;
+ {
+ /* If FOUNDK is not NULL, then only consider that exact
+ key, i.e., don't iterate. */
+ nextk = NULL;
+ }
else
nextk = k->next;
@@ -3182,24 +3199,35 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
if (DBG_LOOKUP)
log_debug ("\tchecking subkey %08lX\n",
(ulong) keyid_from_pk (pk, NULL));
+
if (!pk->flags.valid)
{
if (DBG_LOOKUP)
log_debug ("\tsubkey not valid\n");
continue;
}
+ if (!((pk->pubkey_usage & USAGE_MASK) & req_usage))
+ {
+ if (DBG_LOOKUP)
+ log_debug ("\tusage does not match: want=%x have=%x\n",
+ req_usage, pk->pubkey_usage);
+ continue;
+ }
+
+ n_subkeys++;
if (pk->flags.revoked)
{
if (DBG_LOOKUP)
log_debug ("\tsubkey has been revoked\n");
+ n_revoked_or_expired++;
continue;
}
if (pk->has_expired)
{
if (DBG_LOOKUP)
log_debug ("\tsubkey has expired\n");
+ n_revoked_or_expired++;
continue;
-
}
if (pk->timestamp > curtime && !opt.ignore_valid_from)
{
@@ -3208,14 +3236,6 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
continue;
}
- if (!((pk->pubkey_usage & USAGE_MASK) & req_usage))
- {
- if (DBG_LOOKUP)
- log_debug ("\tusage does not match: want=%x have=%x\n",
- req_usage, pk->pubkey_usage);
- continue;
- }
-
if (DBG_LOOKUP)
log_debug ("\tsubkey might be fine\n");
/* In case a key has a timestamp of 0 set, we make sure
@@ -3228,18 +3248,20 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
latest_key = k;
}
}
+ if (n_subkeys == n_revoked_or_expired && r_flags)
+ *r_flags |= LOOKUP_ALL_SUBKEYS_EXPIRED;
}
/* Check if the primary key is ok (valid, not revoke, not expire,
- matches requested usage) if:
-
- - we didn't find an appropriate subkey and we're not doing an
- exact search,
-
- - we're doing an exact match and the exact match was the
- primary key, or,
-
- - we're just considering the primary key. */
+ * matches requested usage) if:
+ *
+ * - we didn't find an appropriate subkey and we're not doing an
+ * exact search,
+ *
+ * - we're doing an exact match and the exact match was the
+ * primary key, or,
+ *
+ * - we're just considering the primary key. */
if ((!latest_key && !ctx->exact) || foundk == keyblock || req_prim)
{
if (DBG_LOOKUP && !foundk && !req_prim)
@@ -3250,6 +3272,12 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
if (DBG_LOOKUP)
log_debug ("\tprimary key not valid\n");
}
+ else if (!((pk->pubkey_usage & USAGE_MASK) & req_usage))
+ {
+ if (DBG_LOOKUP)
+ log_debug ("\tprimary key usage does not match: "
+ "want=%x have=%x\n", req_usage, pk->pubkey_usage);
+ }
else if (pk->flags.revoked)
{
if (DBG_LOOKUP)
@@ -3260,12 +3288,6 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
if (DBG_LOOKUP)
log_debug ("\tprimary key has expired\n");
}
- else if (!((pk->pubkey_usage & USAGE_MASK) & req_usage))
- {
- if (DBG_LOOKUP)
- log_debug ("\tprimary key usage does not match: "
- "want=%x have=%x\n", req_usage, pk->pubkey_usage);
- }
else /* Okay. */
{
if (DBG_LOOKUP)
@@ -3309,6 +3331,34 @@ found:
}
+/* Print a KEY_CONSIDERED status line. */
+static void
+print_status_key_considered (kbnode_t keyblock, unsigned int flags)
+{
+ char hexfpr[2*MAX_FINGERPRINT_LEN + 1];
+ kbnode_t node;
+ char flagbuf[20];
+
+ if (!is_status_enabled ())
+ return;
+
+ for (node=keyblock; node; node = node->next)
+ if (node->pkt->pkttype == PKT_PUBLIC_KEY
+ || node->pkt->pkttype == PKT_SECRET_KEY)
+ break;
+ if (!node)
+ {
+ log_error ("%s: keyblock w/o primary key\n", __func__);
+ return;
+ }
+
+ hexfingerprint (node->pkt->pkt.public_key, hexfpr, sizeof hexfpr);
+ snprintf (flagbuf, sizeof flagbuf, " %u", flags);
+ write_status_strings (STATUS_KEY_CONSIDERED, hexfpr, flagbuf, NULL);
+}
+
+
+
/* A high-level function to lookup keys.
This function builds on top of the low-level keydb API. It first
@@ -3329,6 +3379,7 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key,
int no_suitable_key = 0;
KBNODE keyblock = NULL;
KBNODE found_key = NULL;
+ unsigned int infoflags;
if (ret_keyblock)
*ret_keyblock = NULL;
@@ -3360,14 +3411,19 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key,
* merge_selfsigs. For secret keys, premerge transferred the
* keys to the keyblock. */
merge_selfsigs (keyblock);
- found_key = finish_lookup (ctx, keyblock);
+ found_key = finish_lookup (ctx, keyblock, &infoflags);
+ if (!found_key)
+ infoflags |= LOOKUP_NOT_SELECTED;
+ print_status_key_considered (keyblock, infoflags);
if (found_key)
{
no_suitable_key = 0;
goto found;
}
else
- no_suitable_key = 1;
+ {
+ no_suitable_key = 1;
+ }
skip:
/* Release resources and continue search. */
@@ -3381,7 +3437,7 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key,
keydb_disable_caching (ctx->kr_handle);
}
-found:
+ found:
if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
diff --git a/g10/gpg.c b/g10/gpg.c
index 006c95b..1f2d416 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -117,6 +117,7 @@ enum cmd_and_opt_values
aQuickSignKey,
aQuickLSignKey,
aQuickAddUid,
+ aQuickAddKey,
aListConfig,
aListGcryptConfig,
aGPGConfList,
@@ -181,6 +182,7 @@ enum cmd_and_opt_values
oNoAskCertLevel,
oFingerprint,
oWithFingerprint,
+ oWithSubkeyFingerprint,
oWithICAOSpelling,
oWithKeygrip,
oWithSecret,
@@ -394,6 +396,7 @@ enum cmd_and_opt_values
oWeakDigest,
oUnwrap,
oOnlySignTextIDs,
+ oDisableSignerUID,
oNoop
};
@@ -426,6 +429,7 @@ static ARGPARSE_OPTS opts[] = {
N_("quickly generate a new key pair")),
ARGPARSE_c (aQuickAddUid, "quick-adduid",
N_("quickly add a new user-id")),
+ ARGPARSE_c (aQuickAddKey, "quick-addkey", "@"),
ARGPARSE_c (aFullKeygen, "full-gen-key" ,
N_("full featured key pair generation")),
ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
@@ -444,10 +448,10 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_c (aPasswd, "passwd", N_("change a passphrase")),
ARGPARSE_c (aDesigRevoke, "desig-revoke","@" ),
ARGPARSE_c (aExport, "export" , N_("export keys") ),
- ARGPARSE_c (aSendKeys, "send-keys" , N_("export keys to a key server") ),
- ARGPARSE_c (aRecvKeys, "recv-keys" , N_("import keys from a key server") ),
+ ARGPARSE_c (aSendKeys, "send-keys" , N_("export keys to a keyserver") ),
+ ARGPARSE_c (aRecvKeys, "recv-keys" , N_("import keys from a keyserver") ),
ARGPARSE_c (aSearchKeys, "search-keys" ,
- N_("search for keys on a key server") ),
+ N_("search for keys on a keyserver") ),
ARGPARSE_c (aRefreshKeys, "refresh-keys",
N_("update all keys from a keyserver")),
ARGPARSE_c (aLocateKeys, "locate-keys", "@"),
@@ -547,6 +551,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oDisableMDC, "disable-mdc", "@"),
ARGPARSE_s_n (oNoDisableMDC, "no-disable-mdc", "@"),
+ ARGPARSE_s_n (oDisableSignerUID, "disable-signer-uid", "@"),
+
ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
ARGPARSE_s_n (oInteractive, "interactive", N_("prompt before overwriting")),
@@ -718,6 +724,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oUtf8Strings, "utf8-strings", "@"),
ARGPARSE_s_n (oNoUtf8Strings, "no-utf8-strings", "@"),
ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"),
+ ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprint", "@"),
+ ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"),
ARGPARSE_s_n (oWithICAOSpelling, "with-icao-spelling", "@"),
ARGPARSE_s_n (oWithKeygrip, "with-keygrip", "@"),
ARGPARSE_s_n (oWithSecret, "with-secret", "@"),
@@ -995,9 +1003,9 @@ my_strusage( int level )
case 31: p = "\nHome: "; break;
#ifndef __riscos__
- case 32: p = opt.homedir; break;
+ case 32: p = gnupg_homedir (); break;
#else /* __riscos__ */
- case 32: p = make_filename(opt.homedir, NULL); break;
+ case 32: p = make_filename(gnupg_homedir (), NULL); break;
#endif /* __riscos__ */
case 33: p = _("\nSupported algorithms:\n"); break;
case 34:
@@ -1175,18 +1183,6 @@ set_debug (const char *level)
}
-
-/* We need the home directory also in some other directories, so make
- sure that both variables are always in sync. */
-static void
-set_homedir (const char *dir)
-{
- if (!dir)
- dir = "";
- opt.homedir = dir;
-}
-
-
/* We set the screen dimensions for UI purposes. Do not allow screens
smaller than 80x24 for the sake of simplicity. */
static void
@@ -1407,7 +1403,8 @@ check_permissions (const char *path, int item)
could be rectified if the homedir itself had proper
permissions. */
if(item!=0 && homedir_cache>-1
- && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
+ && !ascii_strncasecmp (gnupg_homedir (), tmppath,
+ strlen (gnupg_homedir ())))
{
ret=homedir_cache;
goto end;
@@ -2046,6 +2043,9 @@ gpg_init_default_ctrl (ctrl_t ctrl)
static void
gpg_deinit_default_ctrl (ctrl_t ctrl)
{
+#ifdef USE_TOFU
+ tofu_closedbs (ctrl);
+#endif
gpg_dirmngr_deinit_session_data (ctrl);
}
@@ -2074,18 +2074,19 @@ get_default_configname (void)
break;
}
- configname = make_filename (opt.homedir, name, NULL);
+ configname = make_filename (gnupg_homedir (), name, NULL);
}
while (access (configname, R_OK));
xfree(name);
if (! configname)
- configname = make_filename (opt.homedir, GPG_NAME EXTSEP_S "conf", NULL);
+ configname = make_filename (gnupg_homedir (),
+ GPG_NAME EXTSEP_S "conf", NULL);
if (! access (configname, R_OK))
{
/* Print a warning when both config files are present. */
- char *p = make_filename (opt.homedir, "options", NULL);
+ char *p = make_filename (gnupg_homedir (), "options", NULL);
if (! access (p, R_OK))
log_info (_("Note: old default options file '%s' ignored\n"), p);
xfree (p);
@@ -2093,7 +2094,7 @@ get_default_configname (void)
else
{
/* Use the old default only if it exists. */
- char *p = make_filename (opt.homedir, "options", NULL);
+ char *p = make_filename (gnupg_homedir (), "options", NULL);
if (!access (p, R_OK))
{
xfree (configname);
@@ -2241,10 +2242,10 @@ main (int argc, char **argv)
opt.mangle_dos_filenames = 0;
opt.min_cert_level = 2;
set_screen_dimensions ();
- opt.keyid_format = KF_SHORT;
+ opt.keyid_format = KF_NONE;
opt.def_sig_expire = "0";
opt.def_cert_expire = "0";
- set_homedir (default_homedir ());
+ gnupg_set_homedir (NULL);
opt.passphrase_repeat = 1;
opt.emit_version = 1; /* Limit to the major number. */
opt.weak_digests = NULL;
@@ -2273,7 +2274,7 @@ main (int argc, char **argv)
opt.no_homedir_creation = 1;
}
else if( pargs.r_opt == oHomedir )
- set_homedir ( pargs.r.ret_str );
+ gnupg_set_homedir (pargs.r.ret_str);
else if( pargs.r_opt == oNoPermissionWarn )
opt.no_perm_warn=1;
else if (pargs.r_opt == oStrict )
@@ -2287,10 +2288,10 @@ main (int argc, char **argv)
}
#ifdef HAVE_DOSISH_SYSTEM
- if ( strchr (opt.homedir,'\\') ) {
- char *d, *buf = xmalloc (strlen (opt.homedir)+1);
- const char *s = opt.homedir;
- for (d=buf,s=opt.homedir; *s; s++)
+ if ( strchr (gnupg_homedir (), '\\') ) {
+ char *d, *buf = xmalloc (strlen (gnupg_homedir ())+1);
+ const char *s;
+ for (d=buf, s = gnupg_homedir (); *s; s++)
{
*d++ = *s == '\\'? '/': *s;
#ifdef HAVE_W32_SYSTEM
@@ -2299,7 +2300,7 @@ main (int argc, char **argv)
#endif
}
*d = 0;
- set_homedir (buf);
+ gnupg_set_homedir (buf);
}
#endif
@@ -2336,7 +2337,7 @@ main (int argc, char **argv)
pargs.flags= ARGPARSE_FLAG_KEEP;
/* By this point we have a homedir, and cannot change it. */
- check_permissions(opt.homedir,0);
+ check_permissions (gnupg_homedir (), 0);
next_pass:
if( configname ) {
@@ -2430,6 +2431,7 @@ main (int argc, char **argv)
case aStore:
case aQuickKeygen:
case aQuickAddUid:
+ case aQuickAddKey:
case aExportOwnerTrust:
case aImportOwnerTrust:
case aRebuildKeydbCaches:
@@ -2560,6 +2562,9 @@ main (int argc, char **argv)
opt.with_fingerprint = 1;
opt.fingerprint++;
break;
+ case oWithSubkeyFingerprint:
+ opt.with_subkey_fingerprint = 1;
+ break;
case oWithICAOSpelling:
opt.with_icao_spelling = 1;
break;
@@ -2797,6 +2802,9 @@ main (int argc, char **argv)
case oNoForceMDC: opt.force_mdc = 0; break;
case oDisableMDC: opt.disable_mdc = 1; break;
case oNoDisableMDC: opt.disable_mdc = 0; break;
+
+ case oDisableSignerUID: opt.flags.disable_signer_uid = 1; break;
+
case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break;
case oS2KDigest: s2k_digest_string = xstrdup(pargs.r.ret_str); break;
case oS2KCipher: s2k_cipher_string = xstrdup(pargs.r.ret_str); break;
@@ -3142,12 +3150,6 @@ main (int argc, char **argv)
opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
else
opt.keyserver_options.options&=~KEYSERVER_AUTO_KEY_RETRIEVE;
-
- deprecated_warning(configname,configlineno,
- pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve":
- "--no-auto-key-retrieve","--keyserver-options ",
- pargs.r_opt==oAutoKeyRetrieve?"auto-key-retrieve":
- "no-auto-key-retrieve");
break;
case oShowSessionKey: opt.show_session_key = 1; break;
case oOverrideSessionKey:
@@ -3250,6 +3252,8 @@ main (int argc, char **argv)
opt.keyid_format=KF_0xSHORT;
else if(ascii_strcasecmp(pargs.r.ret_str,"0xlong")==0)
opt.keyid_format=KF_0xLONG;
+ else if(ascii_strcasecmp(pargs.r.ret_str,"none")==0)
+ opt.keyid_format = KF_NONE;
else
log_error("unknown keyid-format '%s'\n",pargs.r.ret_str);
break;
@@ -3654,7 +3658,7 @@ main (int argc, char **argv)
/* Set the random seed file. */
if( use_random_seed ) {
- char *p = make_filename(opt.homedir, "random_seed", NULL );
+ char *p = make_filename (gnupg_homedir (), "random_seed", NULL );
gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
if (!access (p, F_OK))
register_secured_file (p);
@@ -3772,6 +3776,7 @@ main (int argc, char **argv)
case aDeleteSecretAndPublicKeys:
case aQuickKeygen:
case aQuickAddUid:
+ case aQuickAddKey:
case aFullKeygen:
case aKeygen:
case aImport:
@@ -4089,11 +4094,31 @@ main (int argc, char **argv)
break;
case aQuickKeygen:
- if (argc != 1 )
- wrong_args("--gen-key user-id");
- username = make_username (fname);
- quick_generate_keypair (ctrl, username);
- xfree (username);
+ {
+ const char *x_algo, *x_usage, *x_expire;
+
+ if (argc < 1 || argc > 4)
+ wrong_args("--quick-gen-key USER-ID [ALGO [USAGE [EXPIRE]]]");
+ username = make_username (fname);
+ argv++, argc--;
+ x_algo = "";
+ x_usage = "";
+ x_expire = "";
+ if (argc)
+ {
+ x_algo = *argv++; argc--;
+ if (argc)
+ {
+ x_usage = *argv++; argc--;
+ if (argc)
+ {
+ x_expire = *argv++; argc--;
+ }
+ }
+ }
+ quick_generate_keypair (ctrl, username, x_algo, x_usage, x_expire);
+ xfree (username);
+ }
break;
case aKeygen: /* generate a key */
@@ -4145,6 +4170,32 @@ main (int argc, char **argv)
}
break;
+ case aQuickAddKey:
+ {
+ const char *x_fpr, *x_algo, *x_usage, *x_expire;
+
+ if (argc < 1 || argc > 4)
+ wrong_args ("--quick-addkey FINGERPRINT [ALGO [USAGE [EXPIRE]]]");
+ x_fpr = *argv++; argc--;
+ x_algo = "";
+ x_usage = "";
+ x_expire = "";
+ if (argc)
+ {
+ x_algo = *argv++; argc--;
+ if (argc)
+ {
+ x_usage = *argv++; argc--;
+ if (argc)
+ {
+ x_expire = *argv++; argc--;
+ }
+ }
+ }
+ keyedit_quick_addkey (ctrl, x_fpr, x_algo, x_usage, x_expire);
+ }
+ break;
+
case aFastImport:
opt.import_options |= IMPORT_FAST;
case aImport:
@@ -4432,12 +4483,12 @@ main (int argc, char **argv)
case aUpdateTrustDB:
if( argc )
wrong_args("--update-trustdb");
- update_trustdb();
+ update_trustdb (ctrl);
break;
case aCheckTrustDB:
/* Old versions allowed for arguments - ignore them */
- check_trustdb();
+ check_trustdb (ctrl);
break;
case aFixTrustDB:
@@ -4586,7 +4637,7 @@ main (int argc, char **argv)
}
merge_keys_and_selfsig (kb);
- if (tofu_set_policy (kb, policy))
+ if (tofu_set_policy (ctrl, kb, policy))
g10_exit (1);
}
diff --git a/g10/gpg.h b/g10/gpg.h
index 5cd8366..c0f0a2d 100644
--- a/g10/gpg.h
+++ b/g10/gpg.h
@@ -63,6 +63,10 @@ typedef struct dirmngr_local_s *dirmngr_local_t;
typedef struct kbnode_struct *KBNODE;
typedef struct kbnode_struct *kbnode_t;
+/* TOFU database meta object. */
+struct tofu_dbs_s;
+typedef struct tofu_dbs_s *tofu_dbs_t;
+
/* Session control object. This object is passed to most functions to
convey the status of a session. Note that the defaults are set by
@@ -74,6 +78,12 @@ struct server_control_s
/* Local data for call-dirmngr.c */
dirmngr_local_t dirmngr_local;
+
+ /* Local data for tofu.c */
+ struct {
+ tofu_dbs_t dbs;
+ } tofu;
+
};
diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c
index d6f0307..cd5346f 100644
--- a/g10/gpgcompose.c
+++ b/g10/gpgcompose.c
@@ -1509,10 +1509,10 @@ static struct option sig_options[] = {
"that VALUE is a file to read the data from. "
"(RFC 4880, Section 5.2.3.16)" },
{ "--key-server-preferences", sig_big_endian_arg,
- "Big-endian number encoding the key server preferences. "
+ "Big-endian number encoding the keyserver preferences. "
"(RFC 4880, Section 5.2.3.17)" },
{ "--key-server", sig_string_arg,
- "The preferred key server. (RFC 4880, Section 5.2.3.18)" },
+ "The preferred keyserver. (RFC 4880, Section 5.2.3.18)" },
{ "--primary-user-id", sig_flag,
"Sets the primary user id flag. (RFC 4880, Section 5.2.3.19)" },
{ "--policy-uri", sig_string_arg,
@@ -2956,10 +2956,6 @@ main (int argc, char *argv[])
int processed;
ctrl_t ctrl;
- opt.homedir = default_homedir ();
- if (! opt.homedir)
- opt.homedir = "";
-
opt.ignore_time_conflict = 1;
/* Allow notations in the IETF space, for instance. */
opt.expert = 1;
diff --git a/g10/sqlite.c b/g10/gpgsql.c
index 90490c2..72f51b5 100644
--- a/g10/sqlite.c
+++ b/g10/gpgsql.c
@@ -1,4 +1,4 @@
-/* sqlite.c - SQLite helper functions.
+/* gpgsql.c - SQLite helper functions.
* Copyright (C) 2015 g10 Code GmbH
*
* This file is part of GnuPG.
@@ -26,15 +26,15 @@
#include "util.h"
#include "logging.h"
-#include "sqlite.h"
+#include "gpgsql.h"
/* This is a convenience function that combines sqlite3_mprintf and
sqlite3_exec. */
int
-sqlite3_exec_printf (sqlite3 *db,
- int (*callback)(void*,int,char**,char**), void *cookie,
- char **errmsg,
- const char *sql, ...)
+gpgsql_exec_printf (sqlite3 *db,
+ int (*callback)(void*,int,char**,char**), void *cookie,
+ char **errmsg,
+ const char *sql, ...)
{
va_list ap;
int rc;
@@ -56,12 +56,12 @@ sqlite3_exec_printf (sqlite3 *db,
}
int
-sqlite3_stepx (sqlite3 *db,
- sqlite3_stmt **stmtp,
- sqlite3_stepx_callback callback,
- void *cookie,
- char **errmsg,
- const char *sql, ...)
+gpgsql_stepx (sqlite3 *db,
+ sqlite3_stmt **stmtp,
+ gpgsql_stepx_callback callback,
+ void *cookie,
+ char **errmsg,
+ const char *sql, ...)
{
int rc;
int err = 0;
@@ -69,7 +69,7 @@ sqlite3_stepx (sqlite3 *db,
va_list va;
int args;
- enum sqlite_arg_type t;
+ enum gpgsql_arg_type t;
int i;
int cols;
@@ -128,7 +128,7 @@ sqlite3_stepx (sqlite3 *db,
{
for (i = 1; i <= args; i ++)
{
- t = va_arg (va, enum sqlite_arg_type);
+ t = va_arg (va, enum gpgsql_arg_type);
switch (t)
{
case SQLITE_ARG_INT:
@@ -169,7 +169,7 @@ sqlite3_stepx (sqlite3 *db,
}
}
- t = va_arg (va, enum sqlite_arg_type);
+ t = va_arg (va, enum gpgsql_arg_type);
log_assert (t == SQLITE_ARG_END);
va_end (va);
diff --git a/g10/gpgsql.h b/g10/gpgsql.h
new file mode 100644
index 0000000..a540684
--- /dev/null
+++ b/g10/gpgsql.h
@@ -0,0 +1,61 @@
+/* gpgsql.h - SQLite helper functions.
+ * Copyright (C) 2015 g10 Code GmbH
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_GPGSQL_H
+#define GNUPG_GPGSQL_H
+
+#include <sqlite3.h>
+
+enum gpgsql_arg_type
+ {
+ SQLITE_ARG_END = 0xdead001,
+ SQLITE_ARG_INT,
+ SQLITE_ARG_LONG_LONG,
+ SQLITE_ARG_STRING,
+ /* This takes two arguments: the blob as a void * and the length
+ of the blob as a long long. */
+ SQLITE_ARG_BLOB
+ };
+
+int gpgsql_exec_printf (sqlite3 *db,
+ int (*callback)(void*,int,char**,char**), void *cookie,
+ char **errmsg,
+ const char *sql, ...);
+
+typedef int (*gpgsql_stepx_callback) (void *cookie,
+ /* number of columns. */
+ int cols,
+ /* columns as text. */
+ char **values,
+ /* column names. */
+ char **names,
+ /* The prepared statement so
+ * that it is possible to use
+ * something like
+ * sqlite3_column_blob(). */
+ sqlite3_stmt *statement);
+
+int gpgsql_stepx (sqlite3 *db,
+ sqlite3_stmt **stmtp,
+ gpgsql_stepx_callback callback,
+ void *cookie,
+ char **errmsg,
+ const char *sql, ...);
+
+#endif /*GNUPG_GPGSQL_H*/
diff --git a/g10/gpgv.c b/g10/gpgv.c
index 2a53e69..2aed10c 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -79,7 +79,8 @@ static ARGPARSE_OPTS opts[] = {
N_("|FD|write status info to this FD")),
ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"),
ARGPARSE_s_s (oHomedir, "homedir", "@"),
- ARGPARSE_s_s (oWeakDigest, "weak-digest", "@"),
+ ARGPARSE_s_s (oWeakDigest, "weak-digest",
+ N_("|ALGO|reject signatures made with ALGO")),
ARGPARSE_end ()
};
@@ -168,7 +169,6 @@ main( int argc, char **argv )
opt.trust_model = TM_ALWAYS;
opt.batch = 1;
- opt.homedir = default_homedir ();
opt.weak_digests = NULL;
tty_no_terminal(1);
@@ -195,7 +195,7 @@ main( int argc, char **argv )
case oLoggerFD:
log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
break;
- case oHomedir: opt.homedir = pargs.r.ret_str; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oWeakDigest:
additional_weak_digest(pargs.r.ret_str);
break;
@@ -246,8 +246,9 @@ g10_exit( int rc )
* this utility assumes that all keys in the keyring are trustworthy
*/
int
-check_signatures_trust( PKT_signature *sig )
+check_signatures_trust (ctrl_t ctrl, PKT_signature *sig)
{
+ (void)ctrl;
(void)sig;
return 0;
}
@@ -279,22 +280,25 @@ cache_disabled_value(PKT_public_key *pk)
}
void
-check_trustdb_stale(void)
+check_trustdb_stale (ctrl_t ctrl)
{
+ (void)ctrl;
}
int
-get_validity_info (PKT_public_key *pk, PKT_user_id *uid)
+get_validity_info (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid)
{
+ (void)ctrl;
(void)pk;
(void)uid;
return '?';
}
unsigned int
-get_validity (PKT_public_key *pk, PKT_user_id *uid, PKT_signature *sig,
- int may_ask)
+get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
+ PKT_signature *sig, int may_ask)
{
+ (void)ctrl;
(void)pk;
(void)uid;
(void)sig;
@@ -310,8 +314,9 @@ trust_value_to_string (unsigned int value)
}
const char *
-uid_trust_string_fixed (PKT_public_key *key, PKT_user_id *uid)
+uid_trust_string_fixed (ctrl_t ctrl, PKT_public_key *key, PKT_user_id *uid)
{
+ (void)ctrl;
(void)key;
(void)uid;
return "err";
@@ -598,10 +603,12 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
}
gpg_error_t
-agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
+agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
+ char **r_serialno, int *r_cleartext)
{
(void)ctrl;
(void)hexkeygrip;
+ (void)r_cleartext;
*r_serialno = NULL;
return gpg_error (GPG_ERR_NO_SECKEY);
}
@@ -639,9 +646,10 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
}
gpg_error_t
-tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id,
+tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id,
enum tofu_policy *policy)
{
+ (void)ctrl;
(void)pk;
(void)user_id;
(void)policy;
diff --git a/g10/import.c b/g10/import.c
index 6707797..7c0d1e2 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -249,7 +249,7 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames,
interactive or by not setting no-auto-check-trustdb */
if (!(options & IMPORT_FAST))
- check_or_update_trustdb ();
+ check_or_update_trustdb (ctrl);
return rc;
}
diff --git a/g10/keydb.c b/g10/keydb.c
index 0164348..17ddd5d 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -666,7 +666,7 @@ keydb_add_resource (const char *url, unsigned int flags)
)
filename = make_filename (resname, NULL);
else
- filename = make_filename (opt.homedir, resname, NULL);
+ filename = make_filename (gnupg_homedir (), resname, NULL);
}
else
filename = xstrdup (resname);
diff --git a/g10/keydb.h b/g10/keydb.h
index 8896eea..a30cf7a 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -222,7 +222,7 @@ gpg_error_t keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);
/*-- pkclist.c --*/
void show_revocation_reason( PKT_public_key *pk, int mode );
-int check_signatures_trust( PKT_signature *sig );
+int check_signatures_trust (ctrl_t ctrl, PKT_signature *sig);
void release_pk_list (PK_LIST pk_list);
int build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list);
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 5461864..d05ea5d 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -1,6 +1,6 @@
/* keyedit.c - Edit properties of a key
* Copyright (C) 1998-2010 Free Software Foundation, Inc.
- * Copyright (C) 1998-2015 Werner Koch
+ * Copyright (C) 1998-2016 Werner Koch
* Copyright (C) 2015, 2016 g10 Code GmbH
*
* This file is part of GnuPG.
@@ -51,7 +51,8 @@
static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
int verbose);
-static void show_names (estream_t fp, KBNODE keyblock, PKT_public_key * pk,
+static void show_names (ctrl_t ctrl, estream_t fp,
+ kbnode_t keyblock, PKT_public_key * pk,
unsigned int flag, int with_prefs);
static void show_key_with_all_names (ctrl_t ctrl, estream_t fp,
KBNODE keyblock, int only_marked,
@@ -61,8 +62,8 @@ static void show_key_with_all_names (ctrl_t ctrl, estream_t fp,
static void show_key_and_fingerprint (kbnode_t keyblock, int with_subkeys);
static void show_key_and_grip (kbnode_t keyblock);
static void subkey_expire_warning (kbnode_t keyblock);
-static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name,
- const char *uidstr);
+static int menu_adduid (ctrl_t ctrl, kbnode_t keyblock,
+ int photo, const char *photo_name, const char *uidstr);
static void menu_deluid (KBNODE pub_keyblock);
static int menu_delsig (KBNODE pub_keyblock);
static int menu_clean (KBNODE keyblock, int self_only);
@@ -85,13 +86,13 @@ static int count_selected_uids (KBNODE keyblock);
static int real_uids_left (KBNODE keyblock);
static int count_selected_keys (KBNODE keyblock);
static int menu_revsig (KBNODE keyblock);
-static int menu_revuid (KBNODE keyblock);
+static int menu_revuid (ctrl_t ctrl, kbnode_t keyblock);
static int menu_revkey (KBNODE pub_keyblock);
static int menu_revsubkey (KBNODE pub_keyblock);
#ifndef NO_TRUST_MODELS
static int enable_disable_key (KBNODE keyblock, int disable);
#endif /*!NO_TRUST_MODELS*/
-static void menu_showphoto (KBNODE keyblock);
+static void menu_showphoto (ctrl_t ctrl, kbnode_t keyblock);
static int update_trust = 0;
@@ -350,8 +351,9 @@ sig_comparison (const void *av, const void *bv)
return 1;
ndataa = pubkey_get_nsig (a->pubkey_algo);
- ndatab = pubkey_get_nsig (a->pubkey_algo);
- log_assert (ndataa == ndatab);
+ ndatab = pubkey_get_nsig (b->pubkey_algo);
+ if (ndataa != ndatab)
+ return (ndataa < ndatab)? -1 : 1;
for (i = 0; i < ndataa; i ++)
{
@@ -570,7 +572,8 @@ check_all_keysigs (KBNODE kb, int only_selected, int only_selfsigs)
sig = n->pkt->pkt.signature;
- pending_desc = xasprintf (" sig: class: 0x%x, issuer: %s, timestamp: %s (%lld), digest: %02x %02x",
+ pending_desc = xasprintf (" sig: class: 0x%x, issuer: %s,"
+ " timestamp: %s (%lld), digest: %02x %02x",
sig->sig_class,
keystr (sig->keyid),
isotimestamp (sig->timestamp),
@@ -596,8 +599,9 @@ check_all_keysigs (KBNODE kb, int only_selected, int only_selfsigs)
{
if (pending_desc)
log_debug ("%s", pending_desc);
- log_debug (" Can't check signature allegedly issued by %s: %s\n",
- keystr (sig->keyid), gpg_strerror (err));
+ log_debug (" Can't check signature allegedly"
+ " issued by %s: %s\n",
+ keystr (sig->keyid), gpg_strerror (err));
}
missing_issuer ++;
break;
@@ -1688,7 +1692,7 @@ change_passphrase (ctrl_t ctrl, kbnode_t keyblock)
err = hexkeygrip_from_pk (pk, &hexgrip);
if (err)
goto leave;
- err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
+ err = agent_get_keyinfo (ctrl, hexgrip, &serialno, NULL);
if (!err && serialno)
; /* Key on card. */
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
@@ -1726,7 +1730,8 @@ change_passphrase (ctrl_t ctrl, kbnode_t keyblock)
goto leave;
desc = gpg_format_keydesc (pk, FORMAT_KEYDESC_NORMAL, 1);
- err = agent_passwd (ctrl, hexgrip, desc, &cache_nonce, &passwd_nonce);
+ err = agent_passwd (ctrl, hexgrip, desc, 0,
+ &cache_nonce, &passwd_nonce);
xfree (desc);
if (err)
@@ -2021,7 +2026,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
and run the stale check as early as possible. Note, that for
non- W32 platforms it is run indirectly trough a call to
get_validity (). */
- check_trustdb_stale ();
+ check_trustdb_stale (ctrl);
#endif
/* Get the public key */
@@ -2206,8 +2211,9 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
break;
case cmdCHECK:
- check_all_keysigs (keyblock, count_selected_uids (keyblock),
- !strcmp (arg_string, "selfsig"));
+ if (check_all_keysigs (keyblock, count_selected_uids (keyblock),
+ !strcmp (arg_string, "selfsig")))
+ modified = 1;
break;
case cmdSIGN:
@@ -2293,7 +2299,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
photo = 1;
/* fall through */
case cmdADDUID:
- if (menu_adduid (keyblock, photo, arg_string, NULL))
+ if (menu_adduid (ctrl, keyblock, photo, arg_string, NULL))
{
update_trust = 1;
redisplay = 1;
@@ -2346,7 +2352,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
break;
case cmdADDKEY:
- if (!generate_subkeypair (ctrl, keyblock))
+ if (!generate_subkeypair (ctrl, keyblock, NULL, NULL, NULL))
{
redisplay = 1;
modified = 1;
@@ -2422,7 +2428,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
else if (*arg_string == '~')
fname = make_filename (arg_string, NULL);
else
- fname = make_filename (opt.homedir, arg_string, NULL);
+ fname = make_filename (gnupg_homedir (), arg_string, NULL);
/* Open that file. */
a = iobuf_open (fname);
@@ -2535,7 +2541,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
n1 > 1 ? _("Really revoke all selected user IDs? (y/N) ")
: _("Really revoke this user ID? (y/N) ")))
{
- if (menu_revuid (keyblock))
+ if (menu_revuid (ctrl, keyblock))
{
modified = 1;
redisplay = 1;
@@ -2629,7 +2635,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
show_key_with_all_names (ctrl, NULL, keyblock, 0, 0, 0, 1, 0, 0);
tty_printf ("\n");
- if (edit_ownertrust (find_kbnode (keyblock,
+ if (edit_ownertrust (ctrl, find_kbnode (keyblock,
PKT_PUBLIC_KEY)->pkt->pkt.
public_key, 1))
{
@@ -2646,7 +2652,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
{
int count = count_selected_uids (keyblock);
log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
- show_names (NULL, keyblock, keyblock->pkt->pkt.public_key,
+ show_names (ctrl, NULL, keyblock, keyblock->pkt->pkt.public_key,
count ? NODFLG_SELUID : 0, 1);
}
break;
@@ -2655,7 +2661,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
{
int count = count_selected_uids (keyblock);
log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
- show_names (NULL, keyblock, keyblock->pkt->pkt.public_key,
+ show_names (ctrl, NULL, keyblock, keyblock->pkt->pkt.public_key,
count ? NODFLG_SELUID : 0, 2);
}
break;
@@ -2731,7 +2737,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
#endif /*!NO_TRUST_MODELS*/
case cmdSHOWPHOTO:
- menu_showphoto (keyblock);
+ menu_showphoto (ctrl, keyblock);
break;
case cmdCLEAN:
@@ -2861,7 +2867,7 @@ keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
#ifdef HAVE_W32_SYSTEM
/* See keyedit_menu for why we need this. */
- check_trustdb_stale ();
+ check_trustdb_stale (ctrl);
#endif
/* Search the key; we don't want the whole getkey stuff here. */
@@ -2912,7 +2918,7 @@ keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
fix_keyblock (&keyblock);
- if (menu_adduid (keyblock, 0, NULL, uidstring))
+ if (menu_adduid (ctrl, keyblock, 0, NULL, uidstring))
{
err = keydb_update_keyblock (kdbhd, keyblock);
if (err)
@@ -2932,6 +2938,75 @@ keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
}
+/* Find a keyblock by fingerprint because only this uniquely
+ * identifies a key and may thus be used to select a key for
+ * unattended subkey creation os key signing. */
+static gpg_error_t
+find_by_primary_fpr (ctrl_t ctrl, const char *fpr,
+ kbnode_t *r_keyblock, KEYDB_HANDLE *r_kdbhd)
+{
+ gpg_error_t err;
+ kbnode_t keyblock = NULL;
+ KEYDB_HANDLE kdbhd = NULL;
+ KEYDB_SEARCH_DESC desc;
+ byte fprbin[MAX_FINGERPRINT_LEN];
+ size_t fprlen;
+
+ *r_keyblock = NULL;
+ *r_kdbhd = NULL;
+
+ if (classify_user_id (fpr, &desc, 1)
+ || !(desc.mode == KEYDB_SEARCH_MODE_FPR
+ || desc.mode == KEYDB_SEARCH_MODE_FPR16
+ || desc.mode == KEYDB_SEARCH_MODE_FPR20))
+ {
+ log_error (_("\"%s\" is not a fingerprint\n"), fpr);
+ err = gpg_error (GPG_ERR_INV_NAME);
+ goto leave;
+ }
+ err = get_pubkey_byname (ctrl, NULL, NULL, fpr, &keyblock, &kdbhd, 1, 1);
+ if (err)
+ {
+ log_error (_("key \"%s\" not found: %s\n"), fpr, gpg_strerror (err));
+ goto leave;
+ }
+
+ /* Check that the primary fingerprint has been given. */
+ fingerprint_from_pk (keyblock->pkt->pkt.public_key, fprbin, &fprlen);
+ if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR16
+ && !memcmp (fprbin, desc.u.fpr, 16))
+ ;
+ else if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR
+ && !memcmp (fprbin, desc.u.fpr, 16)
+ && !desc.u.fpr[16]
+ && !desc.u.fpr[17]
+ && !desc.u.fpr[18]
+ && !desc.u.fpr[19])
+ ;
+ else if (fprlen == 20 && (desc.mode == KEYDB_SEARCH_MODE_FPR20
+ || desc.mode == KEYDB_SEARCH_MODE_FPR)
+ && !memcmp (fprbin, desc.u.fpr, 20))
+ ;
+ else
+ {
+ log_error (_("\"%s\" is not the primary fingerprint\n"), fpr);
+ err = gpg_error (GPG_ERR_INV_NAME);
+ goto leave;
+ }
+
+ *r_keyblock = keyblock;
+ keyblock = NULL;
+ *r_kdbhd = kdbhd;
+ kdbhd = NULL;
+ err = 0;
+
+ leave:
+ release_kbnode (keyblock);
+ keydb_release (kdbhd);
+ return err;
+}
+
+
/* Unattended key signing function. If the key specifified by FPR is
available and FPR is the primary fingerprint all user ids of the
key are signed using the default signing key. If UIDS is an empty
@@ -2946,7 +3021,6 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
kbnode_t keyblock = NULL;
KEYDB_HANDLE kdbhd = NULL;
int modified = 0;
- KEYDB_SEARCH_DESC desc;
PKT_public_key *pk;
kbnode_t node;
strlist_t sl;
@@ -2954,53 +3028,14 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
#ifdef HAVE_W32_SYSTEM
/* See keyedit_menu for why we need this. */
- check_trustdb_stale ();
+ check_trustdb_stale (ctrl);
#endif
/* We require a fingerprint because only this uniquely identifies a
key and may thus be used to select a key for unattended key
signing. */
- if (classify_user_id (fpr, &desc, 1)
- || !(desc.mode == KEYDB_SEARCH_MODE_FPR
- || desc.mode == KEYDB_SEARCH_MODE_FPR16
- || desc.mode == KEYDB_SEARCH_MODE_FPR20))
- {
- log_error (_("\"%s\" is not a fingerprint\n"), fpr);
- goto leave;
- }
- err = get_pubkey_byname (ctrl, NULL, NULL, fpr, &keyblock, &kdbhd, 1, 1);
- if (err)
- {
- log_error (_("key \"%s\" not found: %s\n"), fpr, gpg_strerror (err));
- goto leave;
- }
-
- /* Check that the primary fingerprint has been given. */
- {
- byte fprbin[MAX_FINGERPRINT_LEN];
- size_t fprlen;
-
- fingerprint_from_pk (keyblock->pkt->pkt.public_key, fprbin, &fprlen);
- if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR16
- && !memcmp (fprbin, desc.u.fpr, 16))
- ;
- else if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR
- && !memcmp (fprbin, desc.u.fpr, 16)
- && !desc.u.fpr[16]
- && !desc.u.fpr[17]
- && !desc.u.fpr[18]
- && !desc.u.fpr[19])
- ;
- else if (fprlen == 20 && (desc.mode == KEYDB_SEARCH_MODE_FPR20
- || desc.mode == KEYDB_SEARCH_MODE_FPR)
- && !memcmp (fprbin, desc.u.fpr, 20))
- ;
- else
- {
- log_error (_("\"%s\" is not the primary fingerprint\n"), fpr);
- goto leave;
- }
- }
+ if (find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd))
+ goto leave;
if (fix_keyblock (&keyblock))
modified++;
@@ -3126,6 +3161,67 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
}
+/* Unattended subkey creation function.
+ *
+ */
+void
+keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
+ const char *usagestr, const char *expirestr)
+{
+ gpg_error_t err;
+ kbnode_t keyblock;
+ KEYDB_HANDLE kdbhd;
+ int modified = 0;
+ PKT_public_key *pk;
+
+#ifdef HAVE_W32_SYSTEM
+ /* See keyedit_menu for why we need this. */
+ check_trustdb_stale (ctrl);
+#endif
+
+ /* We require a fingerprint because only this uniquely identifies a
+ * key and may thus be used to select a key for unattended subkey
+ * creation. */
+ if (find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd))
+ goto leave;
+
+ if (fix_keyblock (&keyblock))
+ modified++;
+
+ pk = keyblock->pkt->pkt.public_key;
+ if (pk->flags.revoked)
+ {
+ if (!opt.verbose)
+ show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
+ log_error ("%s%s", _("Key is revoked."), "\n");
+ goto leave;
+ }
+
+ /* Create the subkey. Noet that the called function already prints
+ * an error message. */
+ if (!generate_subkeypair (ctrl, keyblock, algostr, usagestr, expirestr))
+ modified = 1;
+ es_fflush (es_stdout);
+
+ /* Store. */
+ if (modified)
+ {
+ err = keydb_update_keyblock (kdbhd, keyblock);
+ if (err)
+ {
+ log_error (_("update failed: %s\n"), gpg_strerror (err));
+ goto leave;
+ }
+ }
+ else
+ log_info (_("Key not changed so no update needed.\n"));
+
+ leave:
+ release_kbnode (keyblock);
+ keydb_release (kdbhd);
+}
+
+
static void
tty_print_notations (int indent, PKT_signature * sig)
@@ -3369,7 +3465,7 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
es_putc ('e', fp);
else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks))
{
- int trust = get_validity_info (pk, NULL);
+ int trust = get_validity_info (ctrl, pk, NULL);
if (trust == 'u')
ulti_hack = 1;
es_putc (trust, fp);
@@ -3428,7 +3524,7 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
int uid_validity;
if (primary && !ulti_hack)
- uid_validity = get_validity_info (primary, uid);
+ uid_validity = get_validity_info (ctrl, primary, uid);
else
uid_validity = 'u';
es_fprintf (fp, "%c::::::::", uid_validity);
@@ -3482,7 +3578,7 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
{
#ifdef USE_TOFU
enum tofu_policy policy;
- if (! tofu_get_policy (primary, uid, &policy)
+ if (! tofu_get_policy (ctrl, primary, uid, &policy)
&& policy != TOFU_POLICY_NONE)
es_fprintf (fp, "%s", tofu_policy_str (policy));
#endif /*USE_TOFU*/
@@ -3495,8 +3591,8 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
static void
-show_names (estream_t fp,
- KBNODE keyblock, PKT_public_key * pk, unsigned int flag,
+show_names (ctrl_t ctrl, estream_t fp,
+ kbnode_t keyblock, PKT_public_key * pk, unsigned int flag,
int with_prefs)
{
KBNODE node;
@@ -3511,7 +3607,7 @@ show_names (estream_t fp,
if (!flag || (flag && (node->flag & flag)))
{
if (!(flag & NODFLG_MARK_A) && pk)
- tty_fprintf (fp, "%s ", uid_trust_string_fixed (pk, uid));
+ tty_fprintf (fp, "%s ", uid_trust_string_fixed (ctrl, pk, uid));
if (flag & NODFLG_MARK_A)
tty_fprintf (fp, " ");
@@ -3598,12 +3694,12 @@ show_key_with_all_names (ctrl_t ctrl, estream_t fp,
* output */
static int did_warn = 0;
- trust = get_validity_string (pk, NULL);
+ trust = get_validity_string (ctrl, pk, NULL);
otrust = get_ownertrust_string (pk);
/* Show a warning once */
if (!did_warn
- && (get_validity (pk, NULL, NULL, 0)
+ && (get_validity (ctrl, pk, NULL, NULL, 0)
& TRUST_FLAG_PENDING_CHECK))
{
did_warn = 1;
@@ -3670,7 +3766,7 @@ show_key_with_all_names (ctrl_t ctrl, estream_t fp,
have_seckey = 0;
}
else
- have_seckey = !agent_get_keyinfo (ctrl, hexgrip, &serialno);
+ have_seckey = !agent_get_keyinfo (ctrl, hexgrip, &serialno, NULL);
xfree (hexgrip);
}
@@ -3790,7 +3886,7 @@ show_key_with_all_names (ctrl_t ctrl, estream_t fp,
}
}
- show_names (fp,
+ show_names (ctrl, fp,
keyblock, primary, only_marked ? NODFLG_MARK_A : 0, with_prefs);
if (do_warn && !nowarn)
@@ -4035,8 +4131,8 @@ subkey_expire_warning (kbnode_t keyblock)
* user id.
*/
static int
-menu_adduid (kbnode_t pub_keyblock, int photo, const char *photo_name,
- const char *uidstring)
+menu_adduid (ctrl_t ctrl, kbnode_t pub_keyblock,
+ int photo, const char *photo_name, const char *uidstring)
{
PKT_user_id *uid;
PKT_public_key *pk = NULL;
@@ -4098,7 +4194,7 @@ menu_adduid (kbnode_t pub_keyblock, int photo, const char *photo_name,
}
}
- uid = generate_photo_id (pk, photo_name);
+ uid = generate_photo_id (ctrl, pk, photo_name);
}
else
uid = generate_user_id (pub_keyblock, uidstring);
@@ -6013,7 +6109,7 @@ reloop: /* (must use this, because we are modifing the list) */
/* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if
keyblock changed. */
static int
-menu_revuid (KBNODE pub_keyblock)
+menu_revuid (ctrl_t ctrl, kbnode_t pub_keyblock)
{
PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
KBNODE node;
@@ -6094,7 +6190,7 @@ menu_revuid (KBNODE pub_keyblock)
/* If the trustdb has an entry for this key+uid then the
trustdb needs an update. */
if (!update_trust
- && (get_validity (pk, uid, NULL, 0) & TRUST_MASK) >=
+ && (get_validity (ctrl, pk, uid, NULL, 0) & TRUST_MASK) >=
TRUST_UNDEFINED)
update_trust = 1;
#endif /*!NO_TRUST_MODELS*/
@@ -6256,7 +6352,7 @@ enable_disable_key (KBNODE keyblock, int disable)
static void
-menu_showphoto (KBNODE keyblock)
+menu_showphoto (ctrl_t ctrl, kbnode_t keyblock)
{
KBNODE node;
int select_all = !count_selected_uids (keyblock);
@@ -6293,7 +6389,7 @@ menu_showphoto (KBNODE keyblock)
"key %s (uid %d)\n"),
image_type_to_string (type, 1),
(ulong) size, keystr_from_pk (pk), count);
- show_photos (&uid->attribs[i], 1, pk, uid);
+ show_photos (ctrl, &uid->attribs[i], 1, pk, uid);
}
}
}
diff --git a/g10/keygen.c b/g10/keygen.c
index f9cbf21..74fd370 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -1,6 +1,6 @@
/* keygen.c - Generate a key pair
* Copyright (C) 1998-2007, 2009-2011 Free Software Foundation, Inc.
- * Copyright (C) 2014, 2015 Werner Koch
+ * Copyright (C) 2014, 2015, 2016 Werner Koch
*
* This file is part of GnuPG.
*
@@ -51,9 +51,11 @@
is inside the bounds enforced by ask_keysize and gen_xxx. */
#define DEFAULT_STD_ALGO PUBKEY_ALGO_RSA
#define DEFAULT_STD_KEYSIZE 2048
+#define DEFAULT_STD_KEYUSE (PUBKEY_USAGE_CERT|PUBKEY_USAGE_SIG)
#define DEFAULT_STD_CURVE NULL
#define DEFAULT_STD_SUBALGO PUBKEY_ALGO_RSA
#define DEFAULT_STD_SUBKEYSIZE 2048
+#define DEFAULT_STD_SUBKEYUSE PUBKEY_USAGE_ENC
#define DEFAULT_STD_SUBCURVE NULL
/* Flag bits used during key generation. */
@@ -134,6 +136,12 @@ static byte zip_prefs[MAX_PREFS];
static int nzip_prefs;
static int mdc_available,ks_modify;
+static gpg_error_t parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
+ const char *algostr, const char *usagestr,
+ const char *expirestr,
+ int *r_algo, unsigned int *r_usage,
+ u32 *r_expire,
+ unsigned int *r_nbits, char **r_curve);
static void do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
struct output_control_s *outctrl, int card );
static int write_keyblock (iobuf_t out, kbnode_t node);
@@ -158,11 +166,14 @@ print_status_key_created (int letter, PKT_public_key *pk, const char *handle)
if (letter || pk)
{
*p++ = letter;
- *p++ = ' ';
- fingerprint_from_pk (pk, array, &n);
- s = array;
- for (i=0; i < n ; i++, s++, p += 2)
- sprintf (p, "%02X", *s);
+ if (pk)
+ {
+ *p++ = ' ';
+ fingerprint_from_pk (pk, array, &n);
+ s = array;
+ for (i=0; i < n ; i++, s++, p += 2)
+ sprintf (p, "%02X", *s);
+ }
}
if (*handle)
{
@@ -1296,14 +1307,15 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip,
static int
common_gen (const char *keyparms, int algo, const char *algoelem,
kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey,
- int keygen_flags, const char *passphrase, char **cache_nonce_addr)
+ int keygen_flags, const char *passphrase,
+ char **cache_nonce_addr, char **passwd_nonce_addr)
{
int err;
PACKET *pkt;
PKT_public_key *pk;
gcry_sexp_t s_key;
- err = agent_genkey (NULL, cache_nonce_addr, keyparms,
+ err = agent_genkey (NULL, cache_nonce_addr, passwd_nonce_addr, keyparms,
!!(keygen_flags & KEYGEN_FLAG_NO_PROTECTION),
passphrase,
&s_key);
@@ -1364,7 +1376,8 @@ common_gen (const char *keyparms, int algo, const char *algoelem,
static int
gen_elg (int algo, unsigned int nbits, KBNODE pub_root,
u32 timestamp, u32 expireval, int is_subkey,
- int keygen_flags, const char *passphrase, char **cache_nonce_addr)
+ int keygen_flags, const char *passphrase,
+ char **cache_nonce_addr, char **passwd_nonce_addr)
{
int err;
char *keyparms;
@@ -1405,7 +1418,8 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root,
{
err = common_gen (keyparms, algo, "pgy",
pub_root, timestamp, expireval, is_subkey,
- keygen_flags, passphrase, cache_nonce_addr);
+ keygen_flags, passphrase,
+ cache_nonce_addr, passwd_nonce_addr);
xfree (keyparms);
}
@@ -1419,7 +1433,8 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root,
static gpg_error_t
gen_dsa (unsigned int nbits, KBNODE pub_root,
u32 timestamp, u32 expireval, int is_subkey,
- int keygen_flags, const char *passphrase, char **cache_nonce_addr)
+ int keygen_flags, const char *passphrase,
+ char **cache_nonce_addr, char **passwd_nonce_addr)
{
int err;
unsigned int qbits;
@@ -1492,7 +1507,8 @@ gen_dsa (unsigned int nbits, KBNODE pub_root,
{
err = common_gen (keyparms, PUBKEY_ALGO_DSA, "pqgy",
pub_root, timestamp, expireval, is_subkey,
- keygen_flags, passphrase, cache_nonce_addr);
+ keygen_flags, passphrase,
+ cache_nonce_addr, passwd_nonce_addr);
xfree (keyparms);
}
@@ -1507,7 +1523,8 @@ gen_dsa (unsigned int nbits, KBNODE pub_root,
static gpg_error_t
gen_ecc (int algo, const char *curve, kbnode_t pub_root,
u32 timestamp, u32 expireval, int is_subkey,
- int keygen_flags, const char *passphrase, char **cache_nonce_addr)
+ int keygen_flags, const char *passphrase,
+ char **cache_nonce_addr, char **passwd_nonce_addr)
{
gpg_error_t err;
char *keyparms;
@@ -1549,7 +1566,8 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root,
{
err = common_gen (keyparms, algo, "",
pub_root, timestamp, expireval, is_subkey,
- keygen_flags, passphrase, cache_nonce_addr);
+ keygen_flags, passphrase,
+ cache_nonce_addr, passwd_nonce_addr);
xfree (keyparms);
}
@@ -1563,7 +1581,8 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root,
static int
gen_rsa (int algo, unsigned int nbits, KBNODE pub_root,
u32 timestamp, u32 expireval, int is_subkey,
- int keygen_flags, const char *passphrase, char **cache_nonce_addr)
+ int keygen_flags, const char *passphrase,
+ char **cache_nonce_addr, char **passwd_nonce_addr)
{
int err;
char *keyparms;
@@ -1604,7 +1623,8 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root,
{
err = common_gen (keyparms, algo, "ne",
pub_root, timestamp, expireval, is_subkey,
- keygen_flags, passphrase, cache_nonce_addr);
+ keygen_flags, passphrase,
+ cache_nonce_addr, passwd_nonce_addr);
xfree (keyparms);
}
@@ -2017,88 +2037,47 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
}
-/* Ask for the key size. ALGO is the algorithm. If PRIMARY_KEYSIZE
- is not 0, the function asks for the size of the encryption
- subkey. */
-static unsigned
-ask_keysize (int algo, unsigned int primary_keysize)
+static void
+get_keysize_range (int algo,
+ unsigned int *min, unsigned int *def, unsigned int *max)
{
- unsigned int nbits;
- unsigned int min = 1024;
- unsigned int def = DEFAULT_STD_KEYSIZE;
- unsigned int max = 4096;
- int for_subkey = !!primary_keysize;
- int autocomp = 0;
-
- if (primary_keysize && !opt.expert)
- {
- /* Deduce the subkey size from the primary key size. */
- if (algo == PUBKEY_ALGO_DSA && primary_keysize > 3072)
- nbits = 3072; /* For performance reasons we don't support more
- than 3072 bit DSA. However we won't see this
- case anyway because DSA can't be used as an
- encryption subkey ;-). */
- else
- nbits = primary_keysize;
- autocomp = 1;
- goto leave;
- }
+ *min = 1024;
+ *def = DEFAULT_STD_KEYSIZE;
+ *max = 4096;
/* Deviations from the standard values. */
switch(algo)
{
case PUBKEY_ALGO_DSA:
- min = opt.expert? 768 : 1024;
- def=2048;
- max=3072;
+ *min = opt.expert? 768 : 1024;
+ *def=2048;
+ *max=3072;
break;
case PUBKEY_ALGO_ECDSA:
case PUBKEY_ALGO_ECDH:
- min=256;
- def=256;
- max=521;
+ *min=256;
+ *def=256;
+ *max=521;
break;
case PUBKEY_ALGO_EDDSA:
- min=255;
- def=255;
- max=441;
+ *min=255;
+ *def=255;
+ *max=441;
break;
}
+}
- tty_printf(_("%s keys may be between %u and %u bits long.\n"),
- openpgp_pk_algo_name (algo), min, max);
-
- for (;;)
- {
- char *prompt, *answer;
-
- if (for_subkey)
- prompt = xasprintf (_("What keysize do you want "
- "for the subkey? (%u) "), def);
- else
- prompt = xasprintf (_("What keysize do you want? (%u) "), def);
- answer = cpr_get ("keygen.size", prompt);
- cpr_kill_prompt ();
- nbits = *answer? atoi (answer): def;
- xfree(prompt);
- xfree(answer);
-
- if(nbits<min || nbits>max)
- tty_printf(_("%s keysizes must be in the range %u-%u\n"),
- openpgp_pk_algo_name (algo), min, max);
- else
- break;
- }
-
- tty_printf (_("Requested keysize is %u bits\n"), nbits);
- leave:
+/* Return a fixed up keysize depending on ALGO. */
+static unsigned int
+fixup_keysize (unsigned int nbits, int algo, int silent)
+{
if (algo == PUBKEY_ALGO_DSA && (nbits % 64))
{
nbits = ((nbits + 63) / 64) * 64;
- if (!autocomp)
+ if (!silent)
tty_printf (_("rounded up to %u bits\n"), nbits);
}
else if (algo == PUBKEY_ALGO_EDDSA)
@@ -2109,7 +2088,7 @@ ask_keysize (int algo, unsigned int primary_keysize)
nbits = 255;
else
nbits = 441;
- if (!autocomp)
+ if (!silent)
tty_printf (_("rounded to %u bits\n"), nbits);
}
}
@@ -2123,14 +2102,14 @@ ask_keysize (int algo, unsigned int primary_keysize)
nbits = 384;
else
nbits = 521;
- if (!autocomp)
+ if (!silent)
tty_printf (_("rounded to %u bits\n"), nbits);
}
}
else if ((nbits % 32))
{
nbits = ((nbits + 31) / 32) * 32;
- if (!autocomp)
+ if (!silent)
tty_printf (_("rounded up to %u bits\n"), nbits );
}
@@ -2138,6 +2117,66 @@ ask_keysize (int algo, unsigned int primary_keysize)
}
+/* Ask for the key size. ALGO is the algorithm. If PRIMARY_KEYSIZE
+ is not 0, the function asks for the size of the encryption
+ subkey. */
+static unsigned
+ask_keysize (int algo, unsigned int primary_keysize)
+{
+ unsigned int nbits;
+ unsigned int min, def, max;
+ int for_subkey = !!primary_keysize;
+ int autocomp = 0;
+
+ get_keysize_range (algo, &min, &def, &max);
+
+ if (primary_keysize && !opt.expert)
+ {
+ /* Deduce the subkey size from the primary key size. */
+ if (algo == PUBKEY_ALGO_DSA && primary_keysize > 3072)
+ nbits = 3072; /* For performance reasons we don't support more
+ than 3072 bit DSA. However we won't see this
+ case anyway because DSA can't be used as an
+ encryption subkey ;-). */
+ else
+ nbits = primary_keysize;
+ autocomp = 1;
+ goto leave;
+ }
+
+ tty_printf(_("%s keys may be between %u and %u bits long.\n"),
+ openpgp_pk_algo_name (algo), min, max);
+
+ for (;;)
+ {
+ char *prompt, *answer;
+
+ if (for_subkey)
+ prompt = xasprintf (_("What keysize do you want "
+ "for the subkey? (%u) "), def);
+ else
+ prompt = xasprintf (_("What keysize do you want? (%u) "), def);
+ answer = cpr_get ("keygen.size", prompt);
+ cpr_kill_prompt ();
+ nbits = *answer? atoi (answer): def;
+ xfree(prompt);
+ xfree(answer);
+
+ if(nbits<min || nbits>max)
+ tty_printf(_("%s keysizes must be in the range %u-%u\n"),
+ openpgp_pk_algo_name (algo), min, max);
+ else
+ break;
+ }
+
+ tty_printf (_("Requested keysize is %u bits\n"), nbits);
+
+ leave:
+ nbits = fixup_keysize (nbits, algo, autocomp);
+ return nbits;
+}
+
+
/* Ask for the curve. ALGO is the selected algorithm which this
function may adjust. Returns a malloced string with the name of
the curve. BOTH tells that gpg creates a primary and subkey. */
@@ -2724,7 +2763,8 @@ ask_user_id (int mode, int full, KBNODE keyblock)
static int
do_create (int algo, unsigned int nbits, const char *curve, KBNODE pub_root,
u32 timestamp, u32 expiredate, int is_subkey,
- int keygen_flags, const char *passphrase, char **cache_nonce_addr)
+ int keygen_flags, const char *passphrase,
+ char **cache_nonce_addr, char **passwd_nonce_addr)
{
gpg_error_t err;
@@ -2739,18 +2779,22 @@ do_create (int algo, unsigned int nbits, const char *curve, KBNODE pub_root,
if (algo == PUBKEY_ALGO_ELGAMAL_E)
err = gen_elg (algo, nbits, pub_root, timestamp, expiredate, is_subkey,
- keygen_flags, passphrase, cache_nonce_addr);
+ keygen_flags, passphrase,
+ cache_nonce_addr, passwd_nonce_addr);
else if (algo == PUBKEY_ALGO_DSA)
err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey,
- keygen_flags, passphrase, cache_nonce_addr);
+ keygen_flags, passphrase,
+ cache_nonce_addr, passwd_nonce_addr);
else if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH)
err = gen_ecc (algo, curve, pub_root, timestamp, expiredate, is_subkey,
- keygen_flags, passphrase, cache_nonce_addr);
+ keygen_flags, passphrase,
+ cache_nonce_addr, passwd_nonce_addr);
else if (algo == PUBKEY_ALGO_RSA)
err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey,
- keygen_flags, passphrase, cache_nonce_addr);
+ keygen_flags, passphrase,
+ cache_nonce_addr, passwd_nonce_addr);
else
BUG();
@@ -2885,6 +2929,52 @@ get_parameter_algo( struct para_data_s *para, enum para_name key,
return i;
}
+
+/* Parse a usage string. The usage keywords "auth", "sign", "encr"
+ * may be elimited by space, tab, or comma. On error -1 is returned
+ * instead of the usage flags/ */
+static int
+parse_usagestr (const char *usagestr)
+{
+ gpg_error_t err;
+ char **tokens = NULL;
+ const char *s;
+ int i;
+ unsigned int use = 0;
+
+ tokens = strtokenize (usagestr, " \t,");
+ if (!tokens)
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("strtokenize failed: %s\n", gpg_strerror (err));
+ return -1;
+ }
+
+ for (i=0; (s = tokens[i]); i++)
+ {
+ if (!*s)
+ ;
+ else if (!ascii_strcasecmp (s, "sign"))
+ use |= PUBKEY_USAGE_SIG;
+ else if (!ascii_strcasecmp (s, "encrypt")
+ || !ascii_strcasecmp (s, "encr"))
+ use |= PUBKEY_USAGE_ENC;
+ else if (!ascii_strcasecmp (s, "auth"))
+ use |= PUBKEY_USAGE_AUTH;
+ else if (!ascii_strcasecmp (s, "cert"))
+ use |= PUBKEY_USAGE_CERT;
+ else
+ {
+ xfree (tokens);
+ return -1; /* error */
+ }
+ }
+
+ xfree (tokens);
+ return use;
+}
+
+
/*
* Parse the usage parameter and set the keyflags. Returns -1 on
* error, 0 for no usage given or 1 for usage available.
@@ -2893,33 +2983,24 @@ static int
parse_parameter_usage (const char *fname,
struct para_data_s *para, enum para_name key)
{
- struct para_data_s *r = get_parameter( para, key );
- char *p, *pn;
- unsigned int use;
-
- if( !r )
- return 0; /* none (this is an optional parameter)*/
-
- use = 0;
- pn = r->u.value;
- while ( (p = strsep (&pn, " \t,")) ) {
- if ( !*p)
- ;
- else if ( !ascii_strcasecmp (p, "sign") )
- use |= PUBKEY_USAGE_SIG;
- else if ( !ascii_strcasecmp (p, "encrypt") )
- use |= PUBKEY_USAGE_ENC;
- else if ( !ascii_strcasecmp (p, "auth") )
- use |= PUBKEY_USAGE_AUTH;
- else {
- log_error("%s:%d: invalid usage list\n", fname, r->lnr );
- return -1; /* error */
- }
+ struct para_data_s *r = get_parameter( para, key );
+ int i;
+
+ if (!r)
+ return 0; /* none (this is an optional parameter)*/
+
+ i = parse_usagestr (r->u.value);
+ if (i == -1)
+ {
+ log_error ("%s:%d: invalid usage list\n", fname, r->lnr );
+ return -1; /* error */
}
- r->u.usage = use;
- return 1;
+
+ r->u.usage = i;
+ return 1;
}
+
static int
parse_revocation_key (const char *fname,
struct para_data_s *para, enum para_name key)
@@ -3409,13 +3490,20 @@ read_parameter_file (ctrl_t ctrl, const char *fname )
/* Helper for quick_generate_keypair. */
static struct para_data_s *
quickgen_set_para (struct para_data_s *para, int for_subkey,
- int algo, int nbits, const char *curve)
+ int algo, int nbits, const char *curve, unsigned int use)
{
struct para_data_s *r;
- r = xmalloc_clear (sizeof *r + 20);
+ r = xmalloc_clear (sizeof *r + 30);
r->key = for_subkey? pSUBKEYUSAGE : pKEYUSAGE;
- strcpy (r->u.value, for_subkey ? "encrypt" : "sign");
+ if (use)
+ snprintf (r->u.value, 30, "%s%s%s%s",
+ (use & PUBKEY_USAGE_ENC)? "encr " : "",
+ (use & PUBKEY_USAGE_SIG)? "sign " : "",
+ (use & PUBKEY_USAGE_AUTH)? "auth " : "",
+ (use & PUBKEY_USAGE_CERT)? "cert " : "");
+ else
+ strcpy (r->u.value, for_subkey ? "encr" : "sign");
r->next = para;
para = r;
r = xmalloc_clear (sizeof *r + 20);
@@ -3449,7 +3537,8 @@ quickgen_set_para (struct para_data_s *para, int for_subkey,
* Unattended generation of a standard key.
*/
void
-quick_generate_keypair (ctrl_t ctrl, const char *uid)
+quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
+ const char *usagestr, const char *expirestr)
{
gpg_error_t err;
struct para_data_s *para = NULL;
@@ -3460,6 +3549,7 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid)
memset (&outctrl, 0, sizeof outctrl);
use_tty = (!opt.batch && !opt.answer_yes
+ && !*algostr && !*usagestr && !*expirestr
&& !cpr_enabled ()
&& gnupg_isatty (fileno (stdin))
&& gnupg_isatty (fileno (stdout))
@@ -3520,12 +3610,39 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid)
}
}
- para = quickgen_set_para (para, 0,
- DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
- DEFAULT_STD_CURVE);
- para = quickgen_set_para (para, 1,
- DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
- DEFAULT_STD_SUBCURVE);
+ if (*algostr || *usagestr || *expirestr)
+ {
+ /* Extended unattended mode. Creates only the primary key. */
+ int algo;
+ unsigned int use;
+ u32 expire;
+ unsigned int nbits;
+ char *curve;
+
+ err = parse_algo_usage_expire (ctrl, 0, algostr, usagestr, expirestr,
+ &algo, &use, &expire, &nbits, &curve);
+ if (err)
+ {
+ log_error (_("Key generation failed: %s\n"), gpg_strerror (err) );
+ goto leave;
+ }
+
+ para = quickgen_set_para (para, 0, algo, nbits, curve, use);
+ r = xmalloc_clear (sizeof *r + 20);
+ r->key = pKEYEXPIRE;
+ r->u.expire = expire;
+ r->next = para;
+ para = r;
+ }
+ else
+ {
+ para = quickgen_set_para (para, 0,
+ DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
+ DEFAULT_STD_CURVE, 0);
+ para = quickgen_set_para (para, 1,
+ DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
+ DEFAULT_STD_SUBCURVE, 0);
+ }
/* If the pinentry loopback mode is not and we have a static
passphrase (i.e. set with --passphrase{,-fd,-file} while in batch
@@ -3543,6 +3660,7 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid)
}
proc_parameter_file (ctrl, para, "[internal]", &outctrl, 0);
+
leave:
release_parameter_list (para);
}
@@ -3786,10 +3904,10 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
, "--full-gen-key" );
para = quickgen_set_para (para, 0,
DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
- DEFAULT_STD_CURVE);
+ DEFAULT_STD_CURVE, 0);
para = quickgen_set_para (para, 1,
DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
- DEFAULT_STD_SUBCURVE);
+ DEFAULT_STD_SUBCURVE, 0);
}
@@ -3948,19 +4066,23 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk,
goto leave;
}
- err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_AESWRAP, 0);
+ err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
+ GCRY_CIPHER_MODE_AESWRAP, 0);
if (!err)
err = gcry_cipher_setkey (cipherhd, kek, keklen);
if (err)
{
- log_error ("error setting up an encryption context: %s\n", gpg_strerror (err));
+ log_error ("error setting up an encryption context: %s\n",
+ gpg_strerror (err));
goto leave;
}
- err = receive_seckey_from_agent (ctrl, cipherhd, &cache_nonce, hexgrip, sk);
+ err = receive_seckey_from_agent (ctrl, cipherhd, 0,
+ &cache_nonce, hexgrip, sk);
if (err)
{
- log_error ("error getting secret key from agent: %s\n", gpg_strerror (err));
+ log_error ("error getting secret key from agent: %s\n",
+ gpg_strerror (err));
goto leave;
}
@@ -4068,7 +4190,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
get_parameter_u32( para, pKEYEXPIRE ), 0,
outctrl->keygen_flags,
get_parameter_passphrase (para),
- &cache_nonce);
+ &cache_nonce, NULL);
else
err = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root,
&timestamp,
@@ -4131,7 +4253,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
get_parameter_u32 (para, pSUBKEYEXPIRE), 1,
s ? KEYGEN_FLAG_NO_PROTECTION : outctrl->keygen_flags,
get_parameter_passphrase (para),
- &cache_nonce);
+ &cache_nonce, NULL);
/* Get the pointer to the generated public subkey packet. */
if (!err)
{
@@ -4143,7 +4265,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
log_assert (sub_psk);
if (s)
- err = card_store_key_with_backup (ctrl, sub_psk, opt.homedir);
+ err = card_store_key_with_backup (ctrl,
+ sub_psk, gnupg_homedir ());
}
}
else
@@ -4260,12 +4383,144 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
}
+static gpg_error_t
+parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
+ const char *algostr, const char *usagestr,
+ const char *expirestr,
+ int *r_algo, unsigned int *r_usage, u32 *r_expire,
+ unsigned int *r_nbits, char **r_curve)
+{
+ int algo;
+ unsigned int use, nbits;
+ u32 expire;
+ int wantuse;
+ unsigned int min, def, max;
+ const char *curve = NULL;
+ int eccalgo = 0;
+
+ *r_curve = NULL;
+
+ nbits = 0;
+ /* Parse the algo string. */
+ if (!algostr || !*algostr
+ || !strcmp (algostr, "default") || !strcmp (algostr, "-"))
+ {
+ algo = for_subkey? DEFAULT_STD_SUBALGO : DEFAULT_STD_ALGO;
+ use = for_subkey? DEFAULT_STD_SUBKEYUSE : DEFAULT_STD_KEYUSE;
+ nbits = for_subkey?DEFAULT_STD_SUBKEYSIZE : DEFAULT_STD_KEYSIZE;
+ }
+ else if (*algostr == '&' && strlen (algostr) == 41)
+ {
+ /* Take algo from existing key. */
+ algo = check_keygrip (ctrl, algostr+1);
+ /* FIXME: We need the curve name as well. */
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ }
+ else if (!strncmp (algostr, "rsa", 3))
+ {
+ algo = PUBKEY_ALGO_RSA;
+ use = for_subkey? DEFAULT_STD_SUBKEYUSE : DEFAULT_STD_KEYUSE;
+ if (algostr[3])
+ nbits = atoi (algostr + 3);
+ }
+ else if (!strncmp (algostr, "elg", 3))
+ {
+ algo = PUBKEY_ALGO_ELGAMAL_E;
+ use = PUBKEY_USAGE_ENC;
+ if (algostr[3])
+ nbits = atoi (algostr + 3);
+ }
+ else if (!strncmp (algostr, "dsa", 3))
+ {
+ algo = PUBKEY_ALGO_DSA;
+ use = PUBKEY_USAGE_SIG;
+ if (algostr[3])
+ nbits = atoi (algostr + 3);
+ }
+ else if ((curve = openpgp_is_curve_supported (algostr, &algo)))
+ {
+ if (!algo)
+ {
+ algo = PUBKEY_ALGO_ECDH; /* Default ECC algorithm. */
+ eccalgo = 1; /* Remember - we may need to fix it up. */
+ }
+
+ if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA)
+ use = PUBKEY_USAGE_SIG;
+ else
+ use = PUBKEY_USAGE_ENC;
+ }
+ else
+ return gpg_error (GPG_ERR_INV_CURVE);
+
+ /* Parse the usage string. */
+ if (!usagestr || !*usagestr
+ || !strcmp (usagestr, "default") || !strcmp (usagestr, "-"))
+ ; /* Keep default usage */
+ else if ((wantuse = parse_usagestr (usagestr)) != -1)
+ {
+ use = wantuse;
+ if (eccalgo && !(use & PUBKEY_USAGE_ENC))
+ algo = PUBKEY_ALGO_ECDSA; /* Switch from ECDH to ECDSA. */
+ }
+ else
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ /* Make sure a primary key has the CERT usage. */
+ if (!for_subkey)
+ use |= PUBKEY_USAGE_CERT;
+
+ /* Check that usage is possible. */
+ if (/**/((use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH|PUBKEY_USAGE_CERT))
+ && !pubkey_get_nsig (algo))
+ || ((use & PUBKEY_USAGE_ENC)
+ && !pubkey_get_nenc (algo))
+ || (for_subkey && (use & PUBKEY_USAGE_CERT)))
+ return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+
+ /* Parse the expire string. */
+ if (!expirestr || !*expirestr || !strcmp (expirestr, "none")
+ || !strcmp (expirestr, "never") || !strcmp (expirestr, "-"))
+ expire = 0;
+ else
+ expire = parse_expire_string (expirestr);
+ if (expire == (u32)-1 )
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ /* Make sure the keysize is in the allowed range. */
+ get_keysize_range (algo, &min, &def, &max);
+ if (!nbits)
+ nbits = def;
+ else if (nbits < min)
+ nbits = min;
+ else if (nbits > max)
+ nbits = max;
+
+ nbits = fixup_keysize (nbits, algo, 1);
+
+ if (curve)
+ {
+ *r_curve = xtrystrdup (curve);
+ if (!*r_curve)
+ return gpg_error_from_syserror ();
+ }
+ *r_algo = algo;
+ *r_usage = use;
+ *r_expire = expire;
+ *r_nbits = nbits;
+ return 0;
+}
+
+
/* Add a new subkey to an existing key. Returns 0 if a new key has
- been generated and put into the keyblocks. */
+ been generated and put into the keyblocks. If any of ALGOSTR,
+ USAGESTR, or EXPIRESTR is NULL interactive mode is used. */
gpg_error_t
-generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock)
+generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
+ const char *usagestr, const char *expirestr)
{
gpg_error_t err = 0;
+ int interactive;
kbnode_t node;
PKT_public_key *pri_psk = NULL;
PKT_public_key *sub_psk = NULL;
@@ -4275,8 +4530,13 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock)
unsigned int nbits = 0;
char *curve = NULL;
u32 cur_time;
+ char *key_from_hexgrip = NULL;
char *hexgrip = NULL;
char *serialno = NULL;
+ char *cache_nonce = NULL;
+ char *passwd_nonce = NULL;
+
+ interactive = (!algostr || !usagestr || !expirestr);
/* Break out the primary key. */
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
@@ -4315,42 +4575,87 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock)
err = hexkeygrip_from_pk (pri_psk, &hexgrip);
if (err)
goto leave;
- if (agent_get_keyinfo (NULL, hexgrip, &serialno))
+ if (agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
{
- tty_printf (_("Secret parts of primary key are not available.\n"));
+ if (interactive)
+ tty_printf (_("Secret parts of primary key are not available.\n"));
+ else
+ log_info ( _("Secret parts of primary key are not available.\n"));
+ err = gpg_error (GPG_ERR_NO_SECKEY);
goto leave;
}
if (serialno)
- tty_printf (_("Secret parts of primary key are stored on-card.\n"));
-
- xfree (hexgrip);
- hexgrip = NULL;
- algo = ask_algo (ctrl, 1, NULL, &use, &hexgrip);
- log_assert (algo);
+ {
+ if (interactive)
+ tty_printf (_("Secret parts of primary key are stored on-card.\n"));
+ else
+ log_info ( _("Secret parts of primary key are stored on-card.\n"));
+ }
- if (hexgrip)
- nbits = 0;
- else if (algo == PUBKEY_ALGO_ECDSA
- || algo == PUBKEY_ALGO_EDDSA
- || algo == PUBKEY_ALGO_ECDH)
- curve = ask_curve (&algo, NULL);
- else
- nbits = ask_keysize (algo, 0);
+ if (interactive)
+ {
+ algo = ask_algo (ctrl, 1, NULL, &use, &key_from_hexgrip);
+ log_assert (algo);
+
+ if (key_from_hexgrip)
+ nbits = 0;
+ else if (algo == PUBKEY_ALGO_ECDSA
+ || algo == PUBKEY_ALGO_EDDSA
+ || algo == PUBKEY_ALGO_ECDH)
+ curve = ask_curve (&algo, NULL);
+ else
+ nbits = ask_keysize (algo, 0);
- expire = ask_expire_interval (0, NULL);
- if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay",
- _("Really create? (y/N) ")))
+ expire = ask_expire_interval (0, NULL);
+ if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay",
+ _("Really create? (y/N) ")))
+ {
+ err = gpg_error (GPG_ERR_CANCELED);
+ goto leave;
+ }
+ }
+ else /* Unattended mode. */
{
- err = gpg_error (GPG_ERR_CANCELED);
- goto leave;
+ err = parse_algo_usage_expire (ctrl, 1, algostr, usagestr, expirestr,
+ &algo, &use, &expire, &nbits, &curve);
+ if (err)
+ goto leave;
}
- if (hexgrip)
- err = do_create_from_keygrip (ctrl, algo, hexgrip,
- keyblock, cur_time, expire, 1);
+ /* Verify the passphrase now so that we get a cache item for the
+ * primary key passphrase. The agent also returns a passphrase
+ * nonce, which we can use to set the passphrase for the subkey to
+ * that of the primary key. */
+ {
+ char *desc = gpg_format_keydesc (pri_psk, FORMAT_KEYDESC_NORMAL, 1);
+ err = agent_passwd (ctrl, hexgrip, desc, 1 /*=verify*/,
+ &cache_nonce, &passwd_nonce);
+ xfree (desc);
+ }
+
+ /* Start creation. */
+ if (key_from_hexgrip)
+ {
+ err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip,
+ keyblock, cur_time, expire, 1);
+ }
else
- err = do_create (algo, nbits, curve,
- keyblock, cur_time, expire, 1, 0, NULL, NULL);
+ {
+ const char *passwd;
+
+ /* If the pinentry loopback mode is not and we have a static
+ passphrase (i.e. set with --passphrase{,-fd,-file} while in batch
+ mode), we use that passphrase for the new subkey. */
+ if (opt.pinentry_mode != PINENTRY_MODE_LOOPBACK
+ && have_static_passphrase ())
+ passwd = get_static_passphrase ();
+ else
+ passwd = NULL;
+
+ err = do_create (algo, nbits, curve,
+ keyblock, cur_time, expire, 1, 0,
+ passwd, &cache_nonce, &passwd_nonce);
+ }
if (err)
goto leave;
@@ -4360,16 +4665,21 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock)
sub_psk = node->pkt->pkt.public_key;
/* Write the binding signature. */
- err = write_keybinding (keyblock, pri_psk, sub_psk, use, cur_time, NULL);
+ err = write_keybinding (keyblock, pri_psk, sub_psk, use, cur_time,
+ cache_nonce);
if (err)
goto leave;
- write_status_text (STATUS_KEY_CREATED, "S");
+ print_status_key_created ('S', sub_psk, NULL);
+
leave:
+ xfree (key_from_hexgrip);
xfree (curve);
xfree (hexgrip);
xfree (serialno);
+ xfree (cache_nonce);
+ xfree (passwd_nonce);
if (err)
log_error (_("Key generation failed: %s\n"), gpg_strerror (err) );
return err;
@@ -4390,6 +4700,7 @@ generate_card_subkeypair (kbnode_t pub_keyblock,
u32 expire;
u32 cur_time;
struct para_data_s *para = NULL;
+ PKT_public_key *sub_pk = NULL;
log_assert (keyno >= 1 && keyno <= 3);
@@ -4456,8 +4767,6 @@ generate_card_subkeypair (kbnode_t pub_keyblock,
/* Get the pointer to the generated public subkey packet. */
if (!err)
{
- PKT_public_key *sub_pk = NULL;
-
for (node = pub_keyblock; node; node = node->next)
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
sub_pk = node->pkt->pkt.public_key;
@@ -4470,7 +4779,7 @@ generate_card_subkeypair (kbnode_t pub_keyblock,
if (err)
log_error (_("Key generation failed: %s\n"), gpg_strerror (err) );
else
- write_status_text (STATUS_KEY_CREATED, "S");
+ print_status_key_created ('S', sub_pk, NULL);
release_parameter_list (para);
return err;
}
diff --git a/g10/keyid.c b/g10/keyid.c
index bd808d2..e67f67f 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -333,10 +333,15 @@ format_keyid (u32 *keyid, int format, char *buffer, int len)
if (format == KF_DEFAULT)
format = opt.keyid_format;
if (format == KF_DEFAULT)
- format = KF_SHORT;
+ format = KF_NONE;
switch (format)
{
+ case KF_NONE:
+ if (len)
+ *buffer = 0;
+ break;
+
case KF_SHORT:
snprintf (buffer, len, "%08lX", (ulong)keyid[1]);
break;
@@ -375,10 +380,13 @@ keystrlen(void)
{
int format = opt.keyid_format;
if (format == KF_DEFAULT)
- format = KF_SHORT;
+ format = KF_NONE;
switch(format)
{
+ case KF_NONE:
+ return 0;
+
case KF_SHORT:
return 8;
@@ -401,22 +409,32 @@ const char *
keystr (u32 *keyid)
{
static char keyid_str[KEYID_STR_SIZE];
- return format_keyid (keyid, opt.keyid_format, keyid_str, sizeof (keyid_str));
-}
+ int format = opt.keyid_format;
+ if (format == KF_NONE)
+ format = KF_LONG;
+ return format_keyid (keyid, format, keyid_str, sizeof (keyid_str));
+}
+
+/* This function returns the key id of the main and possible the
+ * subkey as one string. It is used by error messages. */
const char *
keystr_with_sub (u32 *main_kid, u32 *sub_kid)
{
static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
char *p;
+ int format = opt.keyid_format;
+
+ if (format == KF_NONE)
+ format = KF_LONG;
- mem2str (buffer, keystr (main_kid), KEYID_STR_SIZE);
+ format_keyid (main_kid, format, buffer, KEYID_STR_SIZE);
if (sub_kid)
{
p = buffer + strlen (buffer);
*p++ = '/';
- mem2str (p, keystr (sub_kid), KEYID_STR_SIZE);
+ format_keyid (sub_kid, format, p, KEYID_STR_SIZE);
}
return buffer;
}
diff --git a/g10/keylist.c b/g10/keylist.c
index 1649991..0ac763d 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -130,7 +130,7 @@ public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode)
is very bad for W32 because of a sharing violation. For real OSes
it might lead to false results if we are later listing a keyring
which is associated with the inode of a deleted file. */
- check_trustdb_stale ();
+ check_trustdb_stale (ctrl);
#ifdef USE_TOFU
tofu_begin_batch_update ();
@@ -154,7 +154,7 @@ secret_key_list (ctrl_t ctrl, strlist_t list)
{
(void)ctrl;
- check_trustdb_stale ();
+ check_trustdb_stale (ctrl);
if (!list)
list_all (ctrl, 1, 0);
@@ -247,7 +247,7 @@ print_card_key_info (estream_t fp, kbnode_t keyblock)
log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
s2k_char = '?';
}
- else if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
+ else if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
s2k_char = serialno? '>':' ';
else
s2k_char = '#'; /* Key not found. */
@@ -401,7 +401,7 @@ void
show_notation (PKT_signature * sig, int indent, int mode, int which)
{
estream_t fp = mode ? log_get_stream () : es_stdout;
- struct notation *nd, *notations;
+ notation_t nd, notations;
if (which == 0)
which = 3;
@@ -448,6 +448,10 @@ show_notation (PKT_signature * sig, int indent, int mode, int which)
{
write_status_buffer (STATUS_NOTATION_NAME,
nd->name, strlen (nd->name), 0);
+ if (nd->flags.critical || nd->flags.human)
+ write_status_text (STATUS_NOTATION_FLAGS,
+ nd->flags.critical && nd->flags.human? "1 1" :
+ nd->flags.critical? "1 0" : "0 1");
write_status_buffer (STATUS_NOTATION_DATA,
nd->value, strlen (nd->value), 50);
}
@@ -1010,7 +1014,7 @@ list_keyblock_pka (ctrl_t ctrl, kbnode_t keyblock)
static void
-list_keyblock_print (KBNODE keyblock, int secret, int fpr,
+list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
struct keylist_context *listctx)
{
int rc;
@@ -1018,10 +1022,8 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr,
KBNODE node;
PKT_public_key *pk;
int skip_sigs = 0;
- int s2k_char;
char *hexgrip = NULL;
char *serialno = NULL;
- char pkstrbuf[PUBKEY_STRING_SIZE];
/* Get the keyid from the keyblock. */
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
@@ -1043,62 +1045,19 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr,
if (secret)
{
- if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
- s2k_char = serialno? '>':' ';
+ /* Encode some info about the secret key in SECRET. */
+ if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
+ secret = serialno? 3 : 1;
else
- s2k_char = '#'; /* Key not found. */
+ secret = 2; /* Key not found. */
}
- else
- s2k_char = ' ';
- check_trustdb_stale ();
-
-
- es_fprintf (es_stdout, "%s%c %s/%s %s",
- secret? "sec":"pub",
- s2k_char,
- pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
- keystr_from_pk (pk), datestr_from_pk (pk));
+ check_trustdb_stale (ctrl);
- if ((opt.list_options & LIST_SHOW_USAGE))
- {
- es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk, 0));
- }
- if (pk->flags.revoked)
- {
- es_fprintf (es_stdout, " [");
- es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk));
- es_fprintf (es_stdout, "]");
- }
- else if (pk->has_expired)
- {
- es_fprintf (es_stdout, " [");
- es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk));
- es_fprintf (es_stdout, "]");
- }
- else if (pk->expiredate)
- {
- es_fprintf (es_stdout, " [");
- es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk));
- es_fprintf (es_stdout, "]");
- }
+ /* Print the "pub" line and in KF_NONE mode the fingerprint. */
+ print_key_line (es_stdout, pk, secret);
-#if 0
- /* I need to think about this some more. It's easy enough to
- include, but it looks sort of confusing in the listing... */
- if (opt.list_options & LIST_SHOW_VALIDITY)
- {
- int validity = get_validity (pk, NULL, NULL, 0);
- es_fprintf (es_stdout, " [%s]", trust_value_to_string (validity));
- }
-#endif
-
- if (pk->pubkey_algo >= 100)
- es_fprintf (es_stdout, " [experimental algorithm %d]", pk->pubkey_algo);
-
- es_fprintf (es_stdout, "\n");
-
- if (fpr)
+ if (fpr && opt.keyid_format != KF_NONE)
print_fingerprint (NULL, pk, 0);
if (opt.with_keygrip && hexgrip)
@@ -1116,6 +1075,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr,
{
PKT_user_id *uid = node->pkt->pkt.user_id;
int indent;
+ int kl = opt.keyid_format == KF_NONE? 10 : keystrlen ();
if ((uid->is_expired || uid->is_revoked)
&& !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
@@ -1134,9 +1094,9 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr,
{
const char *validity;
- validity = uid_trust_string_fixed (pk, uid);
- indent = ((keystrlen () + (opt.legacy_list_mode? 9:11))
- - atoi (uid_trust_string_fixed (NULL, NULL)));
+ validity = uid_trust_string_fixed (ctrl, pk, uid);
+ indent = ((kl + (opt.legacy_list_mode? 9:11))
+ - atoi (uid_trust_string_fixed (ctrl, NULL, NULL)));
if (indent < 0 || indent > 40)
indent = 0;
@@ -1144,7 +1104,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr,
}
else
{
- indent = keystrlen () + (opt.legacy_list_mode? 10:12);
+ indent = kl + (opt.legacy_list_mode? 10:12);
es_fprintf (es_stdout, "uid%*s", indent, "");
}
@@ -1174,7 +1134,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr,
}
if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
- show_photos (uid->attribs, uid->numattribs, pk, uid);
+ show_photos (ctrl, uid->attribs, uid->numattribs, pk, uid);
}
else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
{
@@ -1200,44 +1160,15 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr,
}
if (secret)
{
- if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
- s2k_char = serialno? '>':' ';
+ if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
+ secret = serialno? 3 : 1;
else
- s2k_char = '#'; /* Key not found. */
+ secret = '2'; /* Key not found. */
}
- else
- s2k_char = ' ';
- es_fprintf (es_stdout, "%s%c %s/%s %s",
- secret? "ssb":"sub",
- s2k_char,
- pubkey_string (pk2, pkstrbuf, sizeof pkstrbuf),
- keystr_from_pk (pk2), datestr_from_pk (pk2));
-
- if ((opt.list_options & LIST_SHOW_USAGE))
- {
- es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk2, 0));
- }
- if (pk2->flags.revoked)
- {
- es_fprintf (es_stdout, " [");
- es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk2));
- es_fprintf (es_stdout, "]");
- }
- else if (pk2->has_expired)
- {
- es_fprintf (es_stdout, " [");
- es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk2));
- es_fprintf (es_stdout, "]");
- }
- else if (pk2->expiredate)
- {
- es_fprintf (es_stdout, " [");
- es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk2));
- es_fprintf (es_stdout, "]");
- }
- es_putc ('\n', es_stdout);
- if (fpr > 1)
+ /* Print the "sub" line. */
+ print_key_line (es_stdout, pk2, secret);
+ if (fpr > 1 || opt.with_subkey_fingerprint)
{
print_fingerprint (NULL, pk2, 0);
if (serialno)
@@ -1390,7 +1321,8 @@ print_revokers (estream_t fp, PKT_public_key * pk)
record (i.e. requested via --list-secret-key). If HAS_SECRET a
secret key is available even if SECRET is not set. */
static void
-list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
+list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
+ int secret, int has_secret, int fpr)
{
int rc;
KBNODE kbctx;
@@ -1422,7 +1354,8 @@ list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
}
stubkey = 0;
- if ((secret||has_secret) && agent_get_keyinfo (NULL, hexgrip, &serialno))
+ if ((secret || has_secret)
+ && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
stubkey = 1; /* Key not found. */
keyid_from_pk (pk, keyid);
@@ -1437,7 +1370,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
;
else
{
- trustletter = get_validity_info (pk, NULL);
+ trustletter = get_validity_info (ctrl, pk, NULL);
if (trustletter == 'u')
ulti_hack = 1;
es_putc (trustletter, es_stdout);
@@ -1519,7 +1452,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
int uid_validity;
if (!ulti_hack)
- uid_validity = get_validity_info (pk, uid);
+ uid_validity = get_validity_info (ctrl, pk, uid);
else
uid_validity = 'u';
es_fprintf (es_stdout, "%s:%c::::", str, uid_validity);
@@ -1544,7 +1477,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
{
#ifdef USE_TOFU
enum tofu_policy policy;
- if (! tofu_get_policy (pk, uid, &policy)
+ if (! tofu_get_policy (ctrl, pk, uid, &policy)
&& policy != TOFU_POLICY_NONE)
es_fprintf (es_stdout, "%s", tofu_policy_str (policy));
#endif /*USE_TOFU*/
@@ -1569,7 +1502,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
}
stubkey = 0;
if ((secret||has_secret)
- && agent_get_keyinfo (NULL, hexgrip, &serialno))
+ && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
stubkey = 1; /* Key not found. */
keyid_from_pk (pk2, keyid2);
@@ -1609,11 +1542,11 @@ list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
}
es_putc (':', es_stdout); /* End of field 15. */
es_putc (':', es_stdout); /* End of field 16. */
- if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
- || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
- || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+ if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
+ || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
+ || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
{
- char *curve = openpgp_oid_to_str (pk->pkey[0]);
+ char *curve = openpgp_oid_to_str (pk2->pkey[0]);
const char *name = openpgp_oid_to_curve (curve, 0);
if (!name)
name = curve;
@@ -1814,9 +1747,9 @@ list_keyblock (ctrl_t ctrl,
if (opt.print_pka_records || opt.print_dane_records)
list_keyblock_pka (ctrl, keyblock);
else if (opt.with_colons)
- list_keyblock_colon (keyblock, secret, has_secret, fpr);
+ list_keyblock_colon (ctrl, keyblock, secret, has_secret, fpr);
else
- list_keyblock_print (keyblock, secret, fpr, listctx);
+ list_keyblock_print (ctrl, keyblock, secret, fpr, listctx);
if (secret)
es_fflush (es_stdout);
}
@@ -1856,6 +1789,7 @@ print_icao_hexdigit (estream_t fp, int c)
* 3: direct use of tty but only primary key.
* 4: direct use of tty but only subkey.
* 10: Same as 0 but with_colons etc is ignored.
+ * 20: Same as 0 but using a compact format.
*
* Modes 1 and 2 will try and print both subkey and primary key
* fingerprints. A MODE with bit 7 set is used internally. If
@@ -1873,6 +1807,7 @@ print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
int primary = 0;
int with_colons = opt.with_colons;
int with_icao = opt.with_icao_spelling;
+ int compact = 0;
if (mode == 10)
{
@@ -1880,6 +1815,16 @@ print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
with_colons = 0;
with_icao = 0;
}
+ else if (mode == 20)
+ {
+ mode = 0;
+ with_colons = 0;
+ compact = 1;
+ }
+
+ if (!opt.fingerprint && !opt.with_fingerprint
+ && opt.with_subkey_fingerprint && opt.keyid_format == KF_NONE)
+ compact = 1;
if (pk->main_keyid[0] == pk->keyid[0]
&& pk->main_keyid[1] == pk->keyid[1])
@@ -1933,7 +1878,13 @@ print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
else
{
fp = override_fp? override_fp : es_stdout;
- text = _(" Key fingerprint =");
+ if (opt.keyid_format == KF_NONE)
+ {
+ text = " "; /* To indent ICAO spelling. */
+ compact = 1;
+ }
+ else
+ text = _(" Key fingerprint =");
}
hexfingerprint (pk, hexfpr, sizeof hexfpr);
@@ -1941,11 +1892,18 @@ print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
{
es_fprintf (fp, "fpr:::::::::%s:", hexfpr);
}
+ else if (compact && !opt.fingerprint && !opt.with_fingerprint)
+ {
+ tty_fprintf (fp, "%*s%s", 6, "", hexfpr);
+ }
else
{
char fmtfpr[MAX_FORMATTED_FINGERPRINT_LEN + 1];
format_hexfingerprint (hexfpr, fmtfpr, sizeof fmtfpr);
- tty_fprintf (fp, "%s %s", text, fmtfpr);
+ if (compact)
+ tty_fprintf (fp, "%*s%s", 6, "", fmtfpr);
+ else
+ tty_fprintf (fp, "%s %s", text, fmtfpr);
}
tty_fprintf (fp, "\n");
if (!with_colons && with_icao)
@@ -1992,6 +1950,75 @@ print_card_serialno (const char *serialno)
}
+/* Print a public or secret (sub)key line. Example:
+ *
+ * pub dsa2048 2007-12-31 [SC] [expires: 2018-12-31]
+ * 80615870F5BAD690333686D0F2AD85AC1E42B367
+ *
+ * Some global options may result in a different output format. If
+ * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and
+ * depending on the value a flag character is shown:
+ *
+ * 1 := ' ' Regular secret key
+ * 2 := '#' Stub secret key
+ * 3 := '>' Secret key is on a token.
+ */
+void
+print_key_line (estream_t fp, PKT_public_key *pk, int secret)
+{
+ char pkstrbuf[PUBKEY_STRING_SIZE];
+
+ tty_fprintf (fp, "%s%c %s",
+ pk->flags.primary? (secret? "sec":"pub")
+ /**/ : (secret? "ssb":"sub"),
+ secret == 2? '#' : secret == 3? '>' : ' ',
+ pubkey_string (pk, pkstrbuf, sizeof pkstrbuf));
+ if (opt.keyid_format != KF_NONE)
+ tty_fprintf (fp, "/%s", keystr_from_pk (pk));
+ tty_fprintf (fp, " %s", datestr_from_pk (pk));
+
+ if ((opt.list_options & LIST_SHOW_USAGE))
+ {
+ tty_fprintf (fp, " [%s]", usagestr_from_pk (pk, 0));
+ }
+ if (pk->flags.revoked)
+ {
+ tty_fprintf (fp, " [");
+ tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
+ tty_fprintf (fp, "]");
+ }
+ else if (pk->has_expired)
+ {
+ tty_fprintf (fp, " [");
+ tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
+ tty_fprintf (fp, "]");
+ }
+ else if (pk->expiredate)
+ {
+ tty_fprintf (fp, " [");
+ tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
+ tty_fprintf (fp, "]");
+ }
+
+#if 0
+ /* I need to think about this some more. It's easy enough to
+ include, but it looks sort of confusing in the listing... */
+ if (opt.list_options & LIST_SHOW_VALIDITY)
+ {
+ int validity = get_validity (ctrl, pk, NULL, NULL, 0);
+ tty_fprintf (fp, " [%s]", trust_value_to_string (validity));
+ }
+#endif
+
+ if (pk->pubkey_algo >= 100)
+ tty_fprintf (fp, " [experimental algorithm %d]", pk->pubkey_algo);
+
+ tty_fprintf (fp, "\n");
+
+ if (pk->flags.primary && opt.keyid_format == KF_NONE)
+ print_fingerprint (fp, pk, 20);
+}
+
void
set_attrib_fd (int fd)
diff --git a/g10/keyserver.c b/g10/keyserver.c
index 3486abb..d7105de 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -1464,7 +1464,7 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
/* If the original options didn't have fast import, and the trustdb
is dirty, rebuild. */
if(!(opt.keyserver_options.import_options&IMPORT_FAST))
- check_or_update_trustdb ();
+ check_or_update_trustdb (ctrl);
return err;
}
@@ -1841,7 +1841,7 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs)
/* Loop over all URLs in STRLIST and fetch the key at that URL. Note
- that the fetch operation ignores the configured key servers and
+ that the fetch operation ignores the configured keyservers and
instead directly retrieves the keys. */
int
keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
@@ -1885,7 +1885,7 @@ keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
/* If the original options didn't have fast import, and the trustdb
is dirty, rebuild. */
if (!(opt.keyserver_options.import_options&IMPORT_FAST))
- check_or_update_trustdb ();
+ check_or_update_trustdb (ctrl);
return 0;
}
diff --git a/g10/main.h b/g10/main.h
index 5b5947e..7b716ff 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -287,6 +287,8 @@ void keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
void keyedit_passwd (ctrl_t ctrl, const char *username);
void keyedit_quick_adduid (ctrl_t ctrl, const char *username,
const char *newuid);
+void keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
+ const char *usagestr, const char *expirestr);
void keyedit_quick_sign (ctrl_t ctrl, const char *fpr,
strlist_t uids, strlist_t locusr, int local);
void show_basic_key_info (KBNODE keyblock);
@@ -296,7 +298,8 @@ u32 parse_expire_string(const char *string);
u32 ask_expire_interval(int object,const char *def_expire);
u32 ask_expiredate(void);
unsigned int ask_key_flags (int algo, int subkey, unsigned int current);
-void quick_generate_keypair (ctrl_t ctrl, const char *uid);
+void quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
+ const char *usagestr, const char *expirestr);
void generate_keypair (ctrl_t ctrl, int full, const char *fname,
const char *card_serialno, int card_backup_key);
int keygen_set_std_prefs (const char *string,int personal);
@@ -311,7 +314,10 @@ int keygen_add_revkey(PKT_signature *sig, void *opaque);
gpg_error_t make_backsig (PKT_signature *sig, PKT_public_key *pk,
PKT_public_key *sub_pk, PKT_public_key *sub_psk,
u32 timestamp, const char *cache_nonce);
-gpg_error_t generate_subkeypair (ctrl_t ctrl, kbnode_t pub_keyblock);
+gpg_error_t generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock,
+ const char *algostr,
+ const char *usagestr,
+ const char *expirestr);
#ifdef ENABLE_CARD_SUPPORT
gpg_error_t generate_card_subkeypair (kbnode_t pub_keyblock,
int keyno, const char *serialno);
@@ -383,6 +389,7 @@ gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec,
void **r_data, size_t *r_datalen);
gpg_error_t receive_seckey_from_agent (ctrl_t ctrl, gcry_cipher_hd_t cipherhd,
+ int cleartext,
char **cache_nonce_addr, const char *hexgrip,
PKT_public_key *pk);
@@ -420,6 +427,7 @@ char *format_seckey_info (PKT_public_key *pk);
void print_seckey_info (PKT_public_key *pk);
void print_pubkey_info (estream_t fp, PKT_public_key *pk);
void print_card_key_info (estream_t fp, KBNODE keyblock);
+void print_key_line (estream_t fp, PKT_public_key *pk, int secret);
/*-- verify.c --*/
void print_file_status( int status, const char *name, int what );
diff --git a/g10/mainproc.c b/g10/mainproc.c
index d56790b..453d1b0 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -985,13 +985,10 @@ print_userid (PACKET *pkt)
static void
list_node (CTX c, kbnode_t node)
{
- int mainkey;
- char pkstrbuf[PUBKEY_STRING_SIZE];
-
if (!node)
;
- else if ((mainkey = (node->pkt->pkttype == PKT_PUBLIC_KEY))
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+ else if (node->pkt->pkttype == PKT_PUBLIC_KEY
+ || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
{
PKT_public_key *pk = node->pkt->pkt.public_key;
@@ -1000,10 +997,10 @@ list_node (CTX c, kbnode_t node)
u32 keyid[2];
keyid_from_pk( pk, keyid );
- if (mainkey)
+ if (pk->flags.primary)
c->trustletter = (opt.fast_list_mode?
- 0 : get_validity_info( pk, NULL));
- es_printf ("%s:", mainkey? "pub":"sub" );
+ 0 : get_validity_info (c->ctrl, pk, NULL));
+ es_printf ("%s:", pk->flags.primary? "pub":"sub" );
if (c->trustletter)
es_putc (c->trustletter, es_stdout);
es_printf (":%u:%d:%08lX%08lX:%s:%s::",
@@ -1012,33 +1009,19 @@ list_node (CTX c, kbnode_t node)
(ulong)keyid[0],(ulong)keyid[1],
colon_datestr_from_pk( pk ),
colon_strtime (pk->expiredate) );
- if (mainkey && !opt.fast_list_mode)
+ if (pk->flags.primary && !opt.fast_list_mode)
es_putc (get_ownertrust_info (pk), es_stdout);
es_putc (':', es_stdout);
+ es_putc ('\n', es_stdout);
}
else
- es_printf ("%s %s/%s %s",
- mainkey? "pub":"sub",
- pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
- keystr_from_pk (pk),
- datestr_from_pk (pk));
-
- if (pk->flags.revoked)
- {
- es_printf (" [");
- es_printf (_("revoked: %s"), revokestr_from_pk (pk));
- es_printf ("]\n");
- }
- else if( pk->expiredate && !opt.with_colons)
{
- es_printf (" [");
- es_printf (_("expires: %s"), expirestr_from_pk (pk));
- es_printf ("]\n");
+ print_key_line (es_stdout, pk, 0);
}
- else
- es_putc ('\n', es_stdout);
- if ((mainkey && opt.fingerprint) || opt.fingerprint > 1)
+ if (opt.keyid_format == KF_NONE && !opt.with_colons)
+ ; /* Already printed. */
+ else if ((pk->flags.primary && opt.fingerprint) || opt.fingerprint > 1)
print_fingerprint (NULL, pk, 0);
if (opt.with_colons)
@@ -1048,8 +1031,10 @@ list_node (CTX c, kbnode_t node)
node->next->pkt->pkt.ring_trust->trustval);
}
- if (mainkey)
+ if (pk->flags.primary)
{
+ int kl = opt.keyid_format == KF_NONE? 0 : keystrlen ();
+
/* Now list all userids with their signatures. */
for (node = node->next; node; node = node->next)
{
@@ -1064,7 +1049,7 @@ list_node (CTX c, kbnode_t node)
node->pkt->pkt.user_id->attrib_data?"uat":"uid");
else
es_printf ("uid%*s",
- (int)keystrlen ()+(opt.legacy_list_mode? 9:11),
+ kl + (opt.legacy_list_mode? 9:11),
"" );
print_userid (node->pkt);
if (opt.with_colons)
@@ -1086,7 +1071,7 @@ list_node (CTX c, kbnode_t node)
}
}
}
- else if ((mainkey = (node->pkt->pkttype == PKT_SECRET_KEY) )
+ else if (node->pkt->pkttype == PKT_SECRET_KEY
|| node->pkt->pkttype == PKT_SECRET_SUBKEY)
{
@@ -1556,6 +1541,19 @@ pka_uri_from_sig (CTX c, PKT_signature *sig)
}
+/* Return true if the AKL has the WKD method specified. */
+static int
+akl_has_wkd_method (void)
+{
+ struct akl *akl;
+
+ for (akl = opt.auto_key_locate; akl; akl = akl->next)
+ if (akl->type == AKL_WKD)
+ return 1;
+ return 0;
+}
+
+
static void
print_good_bad_signature (int statno, const char *keyid_str, kbnode_t un,
PKT_signature *sig, int rc)
@@ -1603,31 +1601,31 @@ check_sig_and_print (CTX c, kbnode_t node)
}
/* Check that the message composition is valid.
-
- Per RFC-2440bis (-15) allowed:
-
- S{1,n} -- detached signature.
- S{1,n} P -- old style PGP2 signature
- O{1,n} P S{1,n} -- standard OpenPGP signature.
- C P S{1,n} -- cleartext signature.
-
-
- O = One-Pass Signature packet.
- S = Signature packet.
- P = OpenPGP Message packet (Encrypted | Compressed | Literal)
- (Note that the current rfc2440bis draft also allows
- for a signed message but that does not work as it
- introduces ambiguities.)
- We keep track of these packages using the marker packet
- CTRLPKT_PLAINTEXT_MARK.
- C = Marker packet for cleartext signatures.
-
- We reject all other messages.
-
- Actually we are calling this too often, i.e. for verification of
- each message but better have some duplicate work than to silently
- introduce a bug here.
- */
+ *
+ * Per RFC-2440bis (-15) allowed:
+ *
+ * S{1,n} -- detached signature.
+ * S{1,n} P -- old style PGP2 signature
+ * O{1,n} P S{1,n} -- standard OpenPGP signature.
+ * C P S{1,n} -- cleartext signature.
+ *
+ *
+ * O = One-Pass Signature packet.
+ * S = Signature packet.
+ * P = OpenPGP Message packet (Encrypted | Compressed | Literal)
+ * (Note that the current rfc2440bis draft also allows
+ * for a signed message but that does not work as it
+ * introduces ambiguities.)
+ * We keep track of these packages using the marker packet
+ * CTRLPKT_PLAINTEXT_MARK.
+ * C = Marker packet for cleartext signatures.
+ *
+ * We reject all other messages.
+ *
+ * Actually we are calling this too often, i.e. for verification of
+ * each message but better have some duplicate work than to silently
+ * introduce a bug here.
+ */
{
kbnode_t n;
int n_onepass, n_sig;
@@ -1712,14 +1710,18 @@ check_sig_and_print (CTX c, kbnode_t node)
}
}
- write_status_text (STATUS_NEWSIG, NULL);
+ if (sig->signers_uid)
+ write_status_buffer (STATUS_NEWSIG,
+ sig->signers_uid, strlen (sig->signers_uid), 0);
+ else
+ write_status_text (STATUS_NEWSIG, NULL);
astr = openpgp_pk_algo_name ( sig->pubkey_algo );
if (keystrlen () > 8)
{
log_info (_("Signature made %s\n"), asctimestamp(sig->timestamp));
log_info (_(" using %s key %s\n"),
- astr? astr: "?",keystr(sig->keyid));
+ astr? astr: "?", keystr(sig->keyid));
}
else
log_info (_("Signature made %s using %s key ID %s\n"),
@@ -1728,8 +1730,7 @@ check_sig_and_print (CTX c, kbnode_t node)
rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey );
- /* If the key isn't found, check for a preferred keyserver */
-
+ /* If the key isn't found, check for a preferred keyserver. */
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY && sig->flags.pref_ks)
{
const byte *p;
@@ -1770,8 +1771,8 @@ check_sig_and_print (CTX c, kbnode_t node)
}
}
- /* If the preferred keyserver thing above didn't work, our second
- try is to use the URI from a DNS PKA record. */
+ /* If the avove methods didn't work, our next try is to use the URI
+ * from a DNS PKA record. */
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
&& (opt.keyserver_options.options & KEYSERVER_AUTO_KEY_RETRIEVE)
&& (opt.keyserver_options.options & KEYSERVER_HONOR_PKA_RECORD))
@@ -1790,17 +1791,55 @@ check_sig_and_print (CTX c, kbnode_t node)
{
glo_ctrl.in_auto_key_retrieve++;
res = keyserver_import_keyid (c->ctrl, sig->keyid, spec);
- glo_ctrl.in_auto_key_retrieve--;
- free_keyserver_spec (spec);
- if (!res)
- rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey );
+ glo_ctrl.in_auto_key_retrieve--;
+ free_keyserver_spec (spec);
+ if (!res)
+ rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey );
}
}
}
- /* If the preferred keyserver thing above didn't work and we got
- no information from the DNS PKA, this is a third try. */
+ /* If the above methods didn't work, our next try is to use locate
+ * the key via its fingerprint from a keyserver. This requires
+ * that the signers fingerprint is encoded in the signature. We
+ * favor this over the WKD method (to be tried next), because an
+ * arbitrary keyserver is less subject to web bug like
+ * monitoring. */
+ /* if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY */
+ /* && signature_hash_full_fingerprint (sig) */
+ /* && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE) */
+ /* && keyserver_any_configured (c->ctrl)) */
+ /* { */
+ /* int res; */
+
+ /* glo_ctrl.in_auto_key_retrieve++; */
+ /* res = keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver ); */
+ /* glo_ctrl.in_auto_key_retrieve--; */
+ /* if (!res) */
+ /* rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); */
+ /* } */
+
+ /* If the above methods didn't work, our next try is to retrieve the
+ * key from the WKD. */
+ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
+ && (opt.keyserver_options.options & KEYSERVER_AUTO_KEY_RETRIEVE)
+ && !opt.flags.disable_signer_uid
+ && akl_has_wkd_method ()
+ && sig->signers_uid)
+ {
+ int res;
+
+ glo_ctrl.in_auto_key_retrieve++;
+ res = keyserver_import_wkd (c->ctrl, sig->signers_uid, NULL, NULL);
+ glo_ctrl.in_auto_key_retrieve--;
+ /* Fixme: If the fingerprint is embedded in the signature,
+ * compare it to the fingerprint of the returned key. */
+ if (!res)
+ rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey );
+ }
+ /* If the above methods did't work, our next try is to use a
+ * keyserver. */
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
&& (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
&& keyserver_any_configured (c->ctrl))
@@ -1808,7 +1847,7 @@ check_sig_and_print (CTX c, kbnode_t node)
int res;
glo_ctrl.in_auto_key_retrieve++;
- res=keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver );
+ res = keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver );
glo_ctrl.in_auto_key_retrieve--;
if (!res)
rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey );
@@ -1871,7 +1910,7 @@ check_sig_and_print (CTX c, kbnode_t node)
does not print a LF we need to compute the validity
before calling that function. */
if ((opt.verify_options & VERIFY_SHOW_UID_VALIDITY))
- valid = get_validity (pk, un->pkt->pkt.user_id, NULL, 0);
+ valid = get_validity (c->ctrl, pk, un->pkt->pkt.user_id, NULL, 0);
else
valid = 0; /* Not used. */
@@ -1950,7 +1989,8 @@ check_sig_and_print (CTX c, kbnode_t node)
dump_attribs (un->pkt->pkt.user_id, pk);
if (opt.verify_options&VERIFY_SHOW_PHOTOS)
- show_photos (un->pkt->pkt.user_id->attribs,
+ show_photos (c->ctrl,
+ un->pkt->pkt.user_id->attribs,
un->pkt->pkt.user_id->numattribs,
pk ,un->pkt->pkt.user_id);
}
@@ -1973,7 +2013,8 @@ check_sig_and_print (CTX c, kbnode_t node)
actually ask the user to update any trust
information. */
valid = (trust_value_to_string
- (get_validity (pk, un->pkt->pkt.user_id, sig, 0)));
+ (get_validity (c->ctrl, pk,
+ un->pkt->pkt.user_id, sig, 0)));
log_printf (" [%s]\n",valid);
}
else
@@ -2061,7 +2102,7 @@ check_sig_and_print (CTX c, kbnode_t node)
{
if ((opt.verify_options & VERIFY_PKA_LOOKUPS))
pka_uri_from_sig (c, sig); /* Make sure PKA info is available. */
- rc = check_signatures_trust (sig);
+ rc = check_signatures_trust (c->ctrl, sig);
}
/* Print extra information about the signature. */
diff --git a/g10/migrate.c b/g10/migrate.c
index f4881b4..a9da5a0 100644
--- a/g10/migrate.c
+++ b/g10/migrate.c
@@ -49,10 +49,10 @@ migrate_secring (ctrl_t ctrl)
char *flagfile = NULL;
char *agent_version = NULL;
- secring = make_filename (opt.homedir, "secring" EXTSEP_S "gpg", NULL);
+ secring = make_filename (gnupg_homedir (), "secring" EXTSEP_S "gpg", NULL);
if (access (secring, F_OK))
goto leave; /* Does not exist or is not readable. */
- flagfile = make_filename (opt.homedir, V21_MIGRATION_FNAME, NULL);
+ flagfile = make_filename (gnupg_homedir (), V21_MIGRATION_FNAME, NULL);
if (!access (flagfile, F_OK))
goto leave; /* Does exist - fine. */
diff --git a/g10/options.h b/g10/options.h
index 0de0418..0a87b90 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -71,6 +71,7 @@ struct
int with_key_data;
int with_icao_spelling; /* Print ICAO spelling with fingerprints. */
int with_fingerprint; /* Option --with-fingerprint active. */
+ int with_subkey_fingerprint; /* Option --with-subkey-fingerprint active. */
int with_keygrip; /* Option --with-keygrip active. */
int with_secret; /* Option --with-secret active. */
int with_wkd_hash; /* Option --with-wkd-hash. */
@@ -105,7 +106,6 @@ struct
int marginals_needed;
int completes_needed;
int max_cert_depth;
- const char *homedir;
const char *agent_program;
const char *dirmngr_program;
@@ -137,7 +137,7 @@ struct
} compliance;
enum
{
- KF_DEFAULT, KF_SHORT, KF_LONG, KF_0xSHORT, KF_0xLONG
+ KF_DEFAULT, KF_NONE, KF_SHORT, KF_LONG, KF_0xSHORT, KF_0xLONG
} keyid_format;
int shm_coprocess;
const char *set_filename;
@@ -234,6 +234,7 @@ struct
unsigned int allow_multiple_messages:1;
unsigned int allow_weak_digest_algos:1;
unsigned int large_rsa:1;
+ unsigned int disable_signer_uid:1;
} flags;
/* Linked list of ways to find a key if the key isn't on the local
@@ -290,7 +291,7 @@ struct {
#define DBG_IPC_VALUE 1024 /* debug assuan communication */
#define DBG_CARD_IO_VALUE 2048 /* debug smart card I/O. */
#define DBG_CLOCK_VALUE 4096
-#define DBG_LOOKUP_VALUE 8192 /* debug the kety lookup */
+#define DBG_LOOKUP_VALUE 8192 /* debug the key lookup */
#define DBG_EXTPROG_VALUE 16384 /* debug external program calls */
/* Tests for the debugging flags. */
diff --git a/g10/packet.h b/g10/packet.h
index 194c134..8fb6fc4 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -230,6 +230,8 @@ typedef struct
int numrevkeys;
pka_info_t *pka_info; /* Malloced PKA data or NULL if not
available. See also flags.pka_tried. */
+ char *signers_uid; /* Malloced value of the SIGNERS_UID
+ * subpacket. */
subpktarea_t *hashed; /* All subpackets with hashed data (v4 only). */
subpktarea_t *unhashed; /* Ditto for unhashed data. */
/* First 2 bytes of the digest. (Serialized. Note: this is not
@@ -531,12 +533,14 @@ struct notation
/* The notation's name. */
char *name;
/* If the notation is human readable, then the value is stored here
- as a NUL-terminated string. */
+ as a NUL-terminated string. If it is not human readable a human
+ readable approximation of the binary value _may_ be stored
+ here. */
char *value;
/* Sometimes we want to %-expand the value. In these cases, we save
that transformed value here. */
char *altvalue;
- /* If the notation is not human readable, then the value is strored
+ /* If the notation is not human readable, then the value is stored
here. */
unsigned char *bdat;
/* The amount of data stored in BDAT.
@@ -552,6 +556,8 @@ struct notation
{
/* The notation is critical. */
unsigned int critical:1;
+ /* The notation is human readable. */
+ unsigned int human:1;
/* The notation should be deleted. */
unsigned int ignore:1;
} flags;
@@ -559,6 +565,7 @@ struct notation
/* A field to facilitate creating a list of notations. */
struct notation *next;
};
+typedef struct notation *notation_t;
/*-- mainproc.c --*/
void reset_literals_seen(void);
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index c77e409..e02238b 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -1374,12 +1374,12 @@ dump_sig_subpkt (int hashed, int type, int critical,
es_fprintf (listfp, " %d", buffer[i]);
break;
case SIGSUBPKT_KS_FLAGS:
- es_fputs ("key server preferences:", listfp);
+ es_fputs ("keyserver preferences:", listfp);
for (i = 0; i < length; i++)
es_fprintf (listfp, " %02X", buffer[i]);
break;
case SIGSUBPKT_PREF_KS:
- es_fputs ("preferred key server: ", listfp);
+ es_fputs ("preferred keyserver: ", listfp);
es_write_sanitized (listfp, buffer, length, ")", NULL);
break;
case SIGSUBPKT_PRIMARY_UID:
@@ -1915,6 +1915,20 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen,
if (p)
sig->flags.pref_ks = 1;
+ p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIGNERS_UID, &len);
+ if (p && len)
+ {
+ sig->signers_uid = xtrymalloc (len+1);
+ if (!sig->signers_uid)
+ {
+ rc = gpg_error_from_syserror ();
+ goto leave;
+ }
+ /* Note that we don't care about binary zeroes in the value. */
+ memcpy (sig->signers_uid, p, len);
+ sig->signers_uid[len] = 0;
+ }
+
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_NOTATION, NULL);
if (p)
sig->flags.notation = 1;
diff --git a/g10/photoid.c b/g10/photoid.c
index f6e625a..e188653 100644
--- a/g10/photoid.c
+++ b/g10/photoid.c
@@ -48,7 +48,7 @@
/* Generate a new photo id packet, or return NULL if canceled.
FIXME: Should we add a duplicates check similar to generate_user_id? */
PKT_user_id *
-generate_photo_id(PKT_public_key *pk,const char *photo_name)
+generate_photo_id (ctrl_t ctrl, PKT_public_key *pk,const char *photo_name)
{
PKT_user_id *uid;
int error=1,i;
@@ -163,7 +163,7 @@ generate_photo_id(PKT_public_key *pk,const char *photo_name)
"user" may not be able to dismiss a viewer window! */
if(opt.command_fd==-1)
{
- show_photos (uid->attribs, uid->numattribs, pk, uid);
+ show_photos (ctrl, uid->attribs, uid->numattribs, pk, uid);
switch(cpr_get_answer_yes_no_quit("photoid.jpeg.okay",
_("Is this photo correct (y/N/q)? ")))
{
@@ -286,9 +286,10 @@ static const char *get_default_photo_command(void)
}
#endif
+
void
-show_photos(const struct user_attribute *attrs, int count,
- PKT_public_key *pk, PKT_user_id *uid)
+show_photos (ctrl_t ctrl, const struct user_attribute *attrs, int count,
+ PKT_public_key *pk, PKT_user_id *uid)
{
#ifdef DISABLE_PHOTO_VIEWER
(void)attrs;
@@ -303,8 +304,8 @@ show_photos(const struct user_attribute *attrs, int count,
memset (&args, 0, sizeof(args));
args.pk = pk;
- args.validity_info = get_validity_info (pk, uid);
- args.validity_string = get_validity_string (pk, uid);
+ args.validity_info = get_validity_info (ctrl, pk, uid);
+ args.validity_string = get_validity_string (ctrl, pk, uid);
namehash_from_uid (uid);
args.namehash = uid->namehash;
diff --git a/g10/photoid.h b/g10/photoid.h
index ec2b55f..9fc758e 100644
--- a/g10/photoid.h
+++ b/g10/photoid.h
@@ -24,10 +24,11 @@
#include "packet.h"
-PKT_user_id *generate_photo_id(PKT_public_key *pk,const char *filename);
+PKT_user_id *generate_photo_id (ctrl_t ctrl,
+ PKT_public_key *pk,const char *filename);
int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len);
char *image_type_to_string(byte type,int style);
-void show_photos (const struct user_attribute *attrs, int count,
+void show_photos (ctrl_t ctrl, const struct user_attribute *attrs, int count,
PKT_public_key *pk, PKT_user_id *uid);
#endif /* !_PHOTOID_H_ */
diff --git a/g10/pkclist.c b/g10/pkclist.c
index de8897a..8efa954 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -178,7 +178,7 @@ show_revocation_reason( PKT_public_key *pk, int mode )
*/
#ifndef NO_TRUST_MODELS
static int
-do_edit_ownertrust (PKT_public_key *pk, int mode,
+do_edit_ownertrust (ctrl_t ctrl, PKT_public_key *pk, int mode,
unsigned *new_trust, int defer_help )
{
char *p;
@@ -189,7 +189,6 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
int min_num;
int did_help=defer_help;
unsigned int minimum = tdb_get_min_ownertrust (pk);
- char pkstrbuf[PUBKEY_STRING_SIZE];
switch(minimum)
{
@@ -222,13 +221,12 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
{
KBNODE keyblock, un;
- tty_printf(_("No trust value assigned to:\n"));
- tty_printf("%s/%s %s\n",
- pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
- keystr(keyid), datestr_from_pk( pk ) );
- p=get_user_id_native(keyid);
- tty_printf(_(" \"%s\"\n"),p);
- xfree(p);
+ tty_printf (_("No trust value assigned to:\n"));
+ print_key_line (NULL, pk, 0);
+
+ p = get_user_id_native(keyid);
+ tty_printf (_(" \"%s\"\n"),p);
+ xfree (p);
keyblock = get_pubkeyblock (keyid);
if (!keyblock)
@@ -248,7 +246,8 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
if((opt.verify_options&VERIFY_SHOW_PHOTOS)
&& un->pkt->pkt.user_id->attrib_data)
- show_photos (un->pkt->pkt.user_id->attribs,
+ show_photos (ctrl,
+ un->pkt->pkt.user_id->attribs,
un->pkt->pkt.user_id->numattribs, pk,
un->pkt->pkt.user_id);
@@ -376,14 +375,14 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
*/
#ifndef NO_TRUST_MODELS
int
-edit_ownertrust (PKT_public_key *pk, int mode )
+edit_ownertrust (ctrl_t ctrl, PKT_public_key *pk, int mode )
{
unsigned int trust = 0;
int no_help = 0;
for(;;)
{
- switch ( do_edit_ownertrust (pk, mode, &trust, no_help ) )
+ switch ( do_edit_ownertrust (ctrl, pk, mode, &trust, no_help ) )
{
case -1: /* quit */
return -1;
@@ -526,7 +525,7 @@ write_trust_status (int statuscode, int trustlevel)
* Returns an error code if we should not trust this signature.
*/
int
-check_signatures_trust( PKT_signature *sig )
+check_signatures_trust (ctrl_t ctrl, PKT_signature *sig)
{
PKT_public_key *pk = xmalloc_clear( sizeof *pk );
unsigned int trustlevel = TRUST_UNKNOWN;
@@ -553,7 +552,7 @@ check_signatures_trust( PKT_signature *sig )
log_info(_("WARNING: this key might be revoked (revocation key"
" not present)\n"));
- trustlevel = get_validity (pk, NULL, sig, 1);
+ trustlevel = get_validity (ctrl, pk, NULL, sig, 1);
if ( (trustlevel & TRUST_FLAG_REVOKED) )
{
@@ -845,7 +844,7 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
}
/* Key found and usable. Check validity. */
- trustlevel = get_validity (pk, pk->user_id, NULL, 1);
+ trustlevel = get_validity (ctrl, pk, pk->user_id, NULL, 1);
if ( (trustlevel & TRUST_FLAG_DISABLED) )
{
/* Key has been disabled. */
@@ -1183,7 +1182,7 @@ build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list)
{ /* Check validity of this key. */
int trustlevel;
- trustlevel = get_validity (pk, pk->user_id, NULL, 1);
+ trustlevel = get_validity (ctrl, pk, pk->user_id, NULL, 1);
if ( (trustlevel & TRUST_FLAG_DISABLED) )
{
tty_printf (_("Public key is disabled.\n") );
diff --git a/g10/progress.c b/g10/progress.c
index 21810a4..a1027b8 100644
--- a/g10/progress.c
+++ b/g10/progress.c
@@ -71,6 +71,49 @@ release_progress_context (progress_filter_context_t *pfx)
}
+static void
+write_status_progress (const char *what,
+ unsigned long current, unsigned long total)
+{
+ char buffer[50];
+
+ /* Although we use an unsigned long for the values, 32 bit
+ * applications using GPGME will use an "int" and thus are limited
+ * in the total size which can be represented. On Windows, where
+ * sizeof(int)==sizeof(long), this is even worse and will lead to an
+ * integer overflow for all files larger than 2 GiB. Although, the
+ * allowed value range of TOTAL and CURRENT is nowhere specified, we
+ * better protect applications from the need to handle negative
+ * values. The common usage pattern of the progress information is
+ * to display how many percent of the operation has been done and
+ * thus scaling CURRENT and TOTAL down before they get to large,
+ * should not have a noticeable effect except for rounding
+ * imprecision. */
+ if (total)
+ {
+ if (current > total)
+ current = total;
+
+ while (total > 1024*1024)
+ {
+ total /= 1024;
+ current /= 1024;
+ }
+ }
+ else
+ {
+ while (current > 1024*1024)
+ {
+ current /= 1024;
+ }
+ }
+
+ snprintf (buffer, sizeof buffer, "%.20s ? %lu %lu",
+ what? what : "?", current, total);
+ write_status_text (STATUS_PROGRESS, buffer);
+}
+
+
/****************
* The filter is used to report progress to the user.
*/
@@ -83,17 +126,11 @@ progress_filter (void *opaque, int control,
if (control == IOBUFCTRL_INIT)
{
- char buffer[50];
-
pfx->last = 0;
pfx->offset = 0;
pfx->last_time = make_timestamp ();
- sprintf (buffer, "%.20s ? %lu %lu",
- pfx->what? pfx->what : "?",
- pfx->offset,
- pfx->total);
- write_status_text (STATUS_PROGRESS, buffer);
+ write_status_progress (pfx->what, pfx->offset, pfx->total);
}
else if (control == IOBUFCTRL_UNDERFLOW)
{
@@ -113,14 +150,7 @@ progress_filter (void *opaque, int control,
if ((len == -1 && pfx->offset != pfx->last)
|| timestamp - pfx->last_time > 0)
{
- char buffer[50];
-
- sprintf (buffer, "%.20s ? %lu %lu",
- pfx->what? pfx->what : "?",
- pfx->offset,
- pfx->total);
- write_status_text (STATUS_PROGRESS, buffer);
-
+ write_status_progress (pfx->what, pfx->offset, pfx->total);
pfx->last = pfx->offset;
pfx->last_time = timestamp;
}
diff --git a/g10/revoke.c b/g10/revoke.c
index 3c6e158..218ca59 100644
--- a/g10/revoke.c
+++ b/g10/revoke.c
@@ -530,10 +530,10 @@ gen_standard_revoke (PKT_public_key *psk, const char *cache_nonce)
void *leadin;
size_t len;
u32 keyid[2];
- char pkstrbuf[PUBKEY_STRING_SIZE];
+ int kl;
char *orig_codeset;
- dir = get_openpgp_revocdir (opt.homedir);
+ dir = get_openpgp_revocdir (gnupg_homedir ());
tmpstr = hexfingerprint (psk, NULL, 0);
fname = xstrconcat (dir, DIRSEP_S, tmpstr, NULL);
xfree (tmpstr);
@@ -550,16 +550,16 @@ gen_standard_revoke (PKT_public_key *psk, const char *cache_nonce)
es_fprintf (memfp, "%s\n\n",
_("This is a revocation certificate for the OpenPGP key:"));
- es_fprintf (memfp, "pub %s/%s %s\n",
- pubkey_string (psk, pkstrbuf, sizeof pkstrbuf),
- keystr (keyid),
- datestr_from_pk (psk));
+ print_key_line (memfp, psk, 0);
- print_fingerprint (memfp, psk, 3);
+ if (opt.keyid_format != KF_NONE)
+ print_fingerprint (memfp, psk, 3);
+
+ kl = opt.keyid_format == KF_NONE? 0 : keystrlen ();
tmpstr = get_user_id (keyid, &len);
es_fprintf (memfp, "uid%*s%.*s\n\n",
- (int)keystrlen () + 10, "",
+ kl + 10, "",
(int)len, tmpstr);
xfree (tmpstr);
diff --git a/g10/server.c b/g10/server.c
index 9ec263f..771a8a7 100644
--- a/g10/server.c
+++ b/g10/server.c
@@ -695,12 +695,12 @@ gpg_server (ctrl_t ctrl)
assuan_set_pointer (ctx, ctrl);
if (opt.verbose || opt.debug)
{
- char *tmp = NULL;
+ char *tmp;
tmp = xtryasprintf ("Home: %s\n"
"Config: %s\n"
"%s",
- opt.homedir,
+ gnupg_homedir (),
"fixme: need config filename",
hello);
if (tmp)
diff --git a/g10/seskey.c b/g10/seskey.c
index c41a145..e5385af 100644
--- a/g10/seskey.c
+++ b/g10/seskey.c
@@ -211,9 +211,12 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits,
int i,n;
gcry_mpi_t a;
- if( len + asnlen + 4 > nframe )
- log_bug ("can't encode a %d bit MD into a %d bits frame, algo=%d\n",
- (int)(len*8), (int)nbits, algo);
+ if (len + asnlen + 4 > nframe)
+ {
+ log_error ("can't encode a %d bit MD into a %d bits frame, algo=%d\n",
+ (int)(len*8), (int)nbits, algo);
+ return NULL;
+ }
/* We encode the MD in this way:
*
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 290f19a..7000b48 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -797,15 +797,20 @@ check_signature_over_key_or_uid (PKT_public_key *signer,
*is_selfsig = 1;
}
else
- /* See if one of the subkeys was the signer (although this is
- extremely unlikely). */
{
kbnode_t ctx = NULL;
kbnode_t n;
- while ((n = walk_kbnode (kb, &ctx, PKT_PUBLIC_SUBKEY)))
+ /* See if one of the subkeys was the signer (although this
+ is extremely unlikely). */
+ while ((n = walk_kbnode (kb, &ctx, 0)))
{
- PKT_public_key *subk = n->pkt->pkt.public_key;
+ PKT_public_key *subk;
+
+ if (n->pkt->pkttype != PKT_PUBLIC_SUBKEY)
+ continue;
+
+ subk = n->pkt->pkt.public_key;
if (sig->keyid[0] == subk->keyid[0]
&& sig->keyid[1] == subk->keyid[1])
/* Issued by a subkey. */
diff --git a/g10/sign.c b/g10/sign.c
index 364634a..a4974be 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -40,7 +40,7 @@
#include "pkglue.h"
#include "sysutils.h"
#include "call-agent.h"
-
+#include "mbox-util.h"
#ifdef HAVE_DOSISH_SYSTEM
#define LF "\r\n"
@@ -59,92 +59,105 @@ static void
mk_notation_policy_etc (PKT_signature *sig,
PKT_public_key *pk, PKT_public_key *pksk)
{
- const char *string;
- char *s=NULL;
- strlist_t pu=NULL;
- struct notation *nd=NULL;
- struct expando_args args;
+ const char *string;
+ char *p = NULL;
+ strlist_t pu = NULL;
+ struct notation *nd = NULL;
+ struct expando_args args;
- log_assert(sig->version>=4);
+ log_assert (sig->version >= 4);
- memset(&args,0,sizeof(args));
- args.pk=pk;
- args.pksk=pksk;
+ memset (&args, 0, sizeof(args));
+ args.pk = pk;
+ args.pksk = pksk;
- /* notation data */
- if(IS_SIG(sig) && opt.sig_notations)
- nd=opt.sig_notations;
- else if( IS_CERT(sig) && opt.cert_notations )
- nd=opt.cert_notations;
+ /* Notation data. */
+ if (IS_SIG(sig) && opt.sig_notations)
+ nd = opt.sig_notations;
+ else if (IS_CERT(sig) && opt.cert_notations)
+ nd = opt.cert_notations;
- if(nd)
- {
- struct notation *i;
+ if (nd)
+ {
+ struct notation *item;
- for(i=nd;i;i=i->next)
- {
- i->altvalue=pct_expando(i->value,&args);
- if(!i->altvalue)
- log_error(_("WARNING: unable to %%-expand notation "
- "(too large). Using unexpanded.\n"));
- }
+ for (item = nd; item; item = item->next)
+ {
+ item->altvalue = pct_expando (item->value,&args);
+ if (!item->altvalue)
+ log_error (_("WARNING: unable to %%-expand notation "
+ "(too large). Using unexpanded.\n"));
+ }
- keygen_add_notations(sig,nd);
+ keygen_add_notations (sig, nd);
- for(i=nd;i;i=i->next)
- {
- xfree(i->altvalue);
- i->altvalue=NULL;
- }
- }
+ for (item = nd; item; item = item->next)
+ {
+ xfree (item->altvalue);
+ item->altvalue = NULL;
+ }
+ }
- /* set policy URL */
- if( IS_SIG(sig) && opt.sig_policy_url )
- pu=opt.sig_policy_url;
- else if( IS_CERT(sig) && opt.cert_policy_url )
- pu=opt.cert_policy_url;
+ /* Set policy URL. */
+ if (IS_SIG(sig) && opt.sig_policy_url)
+ pu = opt.sig_policy_url;
+ else if (IS_CERT(sig) && opt.cert_policy_url)
+ pu = opt.cert_policy_url;
- for(;pu;pu=pu->next)
- {
- string = pu->d;
+ for (; pu; pu = pu->next)
+ {
+ string = pu->d;
- s=pct_expando(string,&args);
- if(!s)
- {
- log_error(_("WARNING: unable to %%-expand policy URL "
- "(too large). Using unexpanded.\n"));
- s=xstrdup(string);
- }
+ p = pct_expando (string, &args);
+ if (!p)
+ {
+ log_error(_("WARNING: unable to %%-expand policy URL "
+ "(too large). Using unexpanded.\n"));
+ p = xstrdup(string);
+ }
- build_sig_subpkt(sig,SIGSUBPKT_POLICY|
- ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0),
- s,strlen(s));
+ build_sig_subpkt (sig, (SIGSUBPKT_POLICY
+ | ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0)),
+ p, strlen (p));
- xfree(s);
- }
+ xfree (p);
+ }
- /* preferred keyserver URL */
- if( IS_SIG(sig) && opt.sig_keyserver_url )
- pu=opt.sig_keyserver_url;
+ /* Preferred keyserver URL. */
+ if (IS_SIG(sig) && opt.sig_keyserver_url)
+ pu = opt.sig_keyserver_url;
- for(;pu;pu=pu->next)
- {
- string = pu->d;
+ for (; pu; pu = pu->next)
+ {
+ string = pu->d;
- s=pct_expando(string,&args);
- if(!s)
- {
- log_error(_("WARNING: unable to %%-expand preferred keyserver URL"
- " (too large). Using unexpanded.\n"));
- s=xstrdup(string);
- }
+ p = pct_expando (string, &args);
+ if (!p)
+ {
+ log_error (_("WARNING: unable to %%-expand preferred keyserver URL"
+ " (too large). Using unexpanded.\n"));
+ p = xstrdup (string);
+ }
- build_sig_subpkt(sig,SIGSUBPKT_PREF_KS|
- ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0),
- s,strlen(s));
+ build_sig_subpkt (sig, (SIGSUBPKT_PREF_KS
+ | ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0)),
+ p, strlen (p));
+ xfree (p);
+ }
- xfree(s);
- }
+ /* Set signer's user id. */
+ if (IS_SIG (sig) && !opt.flags.disable_signer_uid)
+ {
+ char *mbox;
+
+ /* For now we use the uid which was used to locate the key. */
+ if (pksk->user_id && (mbox = mailbox_from_userid (pksk->user_id->name)))
+ {
+ if (DBG_LOOKUP)
+ log_debug ("setting Signer's UID to '%s'\n", mbox);
+ build_sig_subpkt (sig, SIGSUBPKT_SIGNERS_UID, mbox, strlen (mbox));
+ }
+ }
}
@@ -346,7 +359,7 @@ openpgp_card_v1_p (PKT_public_key *pk)
}
xfree (pk->serialno);
- agent_get_keyinfo (NULL, hexgrip, &pk->serialno);
+ agent_get_keyinfo (NULL, hexgrip, &pk->serialno, NULL);
xfree (hexgrip);
pk->flags.serialno_valid = 1;
}
diff --git a/g10/sqlite.h b/g10/sqlite.h
deleted file mode 100644
index 753e37a..0000000
--- a/g10/sqlite.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* sqlite.h - SQLite helper functions.
- * Copyright (C) 2015 g10 Code GmbH
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GNUPG_SQLITE_H
-#define GNUPG_SQLITE_H
-
-#include <sqlite3.h>
-
-enum sqlite_arg_type
- {
- SQLITE_ARG_END = 0xdead001,
- SQLITE_ARG_INT,
- SQLITE_ARG_LONG_LONG,
- SQLITE_ARG_STRING,
- /* This takes two arguments: the blob as a void * and the length
- of the blob as a long long. */
- SQLITE_ARG_BLOB
- };
-
-
-int sqlite3_exec_printf (sqlite3 *db,
- int (*callback)(void*,int,char**,char**), void *cookie,
- char **errmsg,
- const char *sql, ...);
-
-typedef int (*sqlite3_stepx_callback) (void *cookie,
- /* number of columns. */
- int cols,
- /* columns as text. */
- char **values,
- /* column names. */
- char **names,
- /* The prepared statement so
- that it is possible to use
- something like
- sqlite3_column_blob(). */
- sqlite3_stmt *statement);
-
-int sqlite3_stepx (sqlite3 *db,
- sqlite3_stmt **stmtp,
- sqlite3_stepx_callback callback,
- void *cookie,
- char **errmsg,
- const char *sql, ...);
-
-#endif
diff --git a/g10/tdbio.c b/g10/tdbio.c
index 5fdd946..a414709 100644
--- a/g10/tdbio.c
+++ b/g10/tdbio.c
@@ -617,14 +617,15 @@ tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile)
if (!new_dbname)
{
- fname = make_filename (opt.homedir, "trustdb" EXTSEP_S GPGEXT_GPG, NULL);
+ fname = make_filename (gnupg_homedir (),
+ "trustdb" EXTSEP_S GPGEXT_GPG, NULL);
}
else if (*new_dbname != DIRSEP_C )
{
if (strchr (new_dbname, DIRSEP_C))
fname = make_filename (new_dbname, NULL);
else
- fname = make_filename (opt.homedir, new_dbname, NULL);
+ fname = make_filename (gnupg_homedir (), new_dbname, NULL);
}
else
{
diff --git a/g10/test-stubs.c b/g10/test-stubs.c
index 2edae18..42c91f8 100644
--- a/g10/test-stubs.c
+++ b/g10/test-stubs.c
@@ -58,8 +58,9 @@ g10_exit( int rc )
* this utility assumes that all keys in the keyring are trustworthy
*/
int
-check_signatures_trust( PKT_signature *sig )
+check_signatures_trust (ctrl_t ctrl, PKT_signature *sig)
{
+ (void)ctrl;
(void)sig;
return 0;
}
@@ -91,22 +92,25 @@ cache_disabled_value(PKT_public_key *pk)
}
void
-check_trustdb_stale(void)
+check_trustdb_stale (ctrl_t ctrl)
{
+ (void)ctrl;
}
int
-get_validity_info (PKT_public_key *pk, PKT_user_id *uid)
+get_validity_info (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid)
{
+ (void)ctrl;
(void)pk;
(void)uid;
return '?';
}
unsigned int
-get_validity (PKT_public_key *pk, PKT_user_id *uid, PKT_signature *sig,
- int may_ask)
+get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
+ PKT_signature *sig, int may_ask)
{
+ (void)ctrl;
(void)pk;
(void)uid;
(void)sig;
@@ -122,8 +126,9 @@ trust_value_to_string (unsigned int value)
}
const char *
-uid_trust_string_fixed (PKT_public_key *key, PKT_user_id *uid)
+uid_trust_string_fixed (ctrl_t ctrl, PKT_public_key *key, PKT_user_id *uid)
{
+ (void)ctrl;
(void)key;
(void)uid;
return "err";
@@ -410,10 +415,12 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
}
gpg_error_t
-agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
+agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
+ char **r_serialno, int *r_cleartext)
{
(void)ctrl;
(void)hexkeygrip;
+ (void)r_cleartext;
*r_serialno = NULL;
return gpg_error (GPG_ERR_NO_SECKEY);
}
@@ -451,9 +458,10 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
}
gpg_error_t
-tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id,
+tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id,
enum tofu_policy *policy)
{
+ (void)ctrl;
(void)pk;
(void)user_id;
(void)policy;
diff --git a/g10/tofu.c b/g10/tofu.c
index e591aa5..471aec6 100644
--- a/g10/tofu.c
+++ b/g10/tofu.c
@@ -39,7 +39,7 @@
#include "ttyio.h"
#include "trustdb.h"
#include "mkdir_p.h"
-#include "sqlite.h"
+#include "gpgsql.h"
#include "status.h"
#include "tofu.h"
@@ -84,8 +84,8 @@ enum db_type
theis case, NAME is either the normalized email address or the
fingerprint.
- To initialize this data structure, call opendbs(). When you are
- done, clean it up using closedbs(). To get a handle to a database,
+ To initialize this data structure, call opendbs(). Cleanup is done
+ when the CTRL object is released. To get a handle to a database,
use the getdb() function. This will either return an existing
handle or open a new DB connection, as appropriate. */
struct db
@@ -262,7 +262,7 @@ begin_transaction (struct db *db, int only_batch)
if (batch_update && ! db->batch_update)
{
- rc = sqlite3_stepx (db->db, &db->s.savepoint_batch,
+ rc = gpgsql_stepx (db->db, &db->s.savepoint_batch,
NULL, NULL, &err,
"savepoint batch;", SQLITE_ARG_END);
if (rc)
@@ -281,7 +281,7 @@ begin_transaction (struct db *db, int only_batch)
if (only_batch)
return 0;
- rc = sqlite3_stepx (db->db, &db->s.savepoint_inner,
+ rc = gpgsql_stepx (db->db, &db->s.savepoint_inner,
NULL, NULL, &err,
"savepoint inner;", SQLITE_ARG_END);
if (rc)
@@ -316,7 +316,7 @@ end_transaction (struct db *db, int only_batch)
{
db->batch_update = 0;
- rc = sqlite3_stepx (db->db, &db->s.savepoint_batch_commit,
+ rc = gpgsql_stepx (db->db, &db->s.savepoint_batch_commit,
NULL, NULL, &err,
"release batch;", SQLITE_ARG_END);
if (rc)
@@ -337,7 +337,7 @@ end_transaction (struct db *db, int only_batch)
if (only_batch)
return 0;
- rc = sqlite3_stepx (db->db, &db->s.savepoint_inner_commit,
+ rc = gpgsql_stepx (db->db, &db->s.savepoint_inner_commit,
NULL, NULL, &err,
"release inner;", SQLITE_ARG_END);
if (rc)
@@ -640,7 +640,7 @@ initdb (sqlite3 *db, enum db_type type)
* know why this occurred, we also set conflict to 0xbaddecaf.
*/
if (type == DB_EMAIL || type == DB_COMBINED)
- rc = sqlite3_exec_printf
+ rc = gpgsql_exec_printf
(db, NULL, NULL, &err,
"create table bindings\n"
" (oid INTEGER PRIMARY KEY AUTOINCREMENT,\n"
@@ -659,7 +659,7 @@ initdb (sqlite3 *db, enum db_type type)
Note: since the data is split on the email address, there is no
need to index the email column. */
- rc = sqlite3_exec_printf
+ rc = gpgsql_exec_printf
(db, NULL, NULL, &err,
"create table bindings\n"
" (oid INTEGER PRIMARY KEY AUTOINCREMENT,\n"
@@ -747,7 +747,7 @@ opendb (char *filename, enum db_type type)
log_assert (! filename);
log_assert (type == DB_COMBINED);
- filename = make_filename (opt.homedir, "tofu.db", NULL);
+ filename = make_filename (gnupg_homedir (), "tofu.db", NULL);
filename_free = 1;
}
else
@@ -782,7 +782,8 @@ opendb (char *filename, enum db_type type)
return db;
}
-struct dbs
+/* Definition of the Tofu dabase meta handle. */
+struct tofu_dbs_s
{
struct db *db;
};
@@ -814,7 +815,7 @@ link_db (struct db **head, struct db *db)
TYPE must be either DB_MAIL or DB_KEY. In the combined format, the
combined DB is always returned. */
static struct db *
-getdb (struct dbs *dbs, const char *name, enum db_type type)
+getdb (tofu_dbs_t dbs, const char *name, enum db_type type)
{
struct db *t = NULL;
char *name_sanitized = NULL;
@@ -894,10 +895,10 @@ getdb (struct dbs *dbs, const char *name, enum db_type type)
char *name_db;
/* Make the directory. */
- rc = gnupg_mkdir_p (opt.homedir, "tofu.d", type_str, prefix, NULL);
+ rc = gnupg_mkdir_p (gnupg_homedir (), "tofu.d", type_str, prefix, NULL);
if (rc)
{
- name_db = xstrconcat (opt.homedir, "tofu.d",
+ name_db = xstrconcat (gnupg_homedir (), "tofu.d",
type_str, prefix, NULL);
log_error (_("can't create directory '%s': %s\n"),
name_db, gpg_strerror (rc));
@@ -907,7 +908,7 @@ getdb (struct dbs *dbs, const char *name, enum db_type type)
name_db = xstrconcat (name_sanitized, ".db", NULL);
filename = make_filename
- (opt.homedir, "tofu.d", type_str, prefix, name_db, NULL);
+ (gnupg_homedir (), "tofu.d", type_str, prefix, name_db, NULL);
xfree (name_db);
}
}
@@ -980,12 +981,15 @@ closedb (struct db *db)
/* Create a new DB meta-handle. Returns NULL on error. */
/* FIXME: Change to return an error code for better reporting by the
caller. */
-static struct dbs *
-opendbs (void)
+static tofu_dbs_t
+opendbs (ctrl_t ctrl)
{
+ if (ctrl->tofu.dbs)
+ return ctrl->tofu.dbs;
+
if (opt.tofu_db_format == TOFU_DB_AUTO)
{
- char *filename = make_filename (opt.homedir, "tofu.db", NULL);
+ char *filename = make_filename (gnupg_homedir (), "tofu.db", NULL);
struct stat s;
int have_tofu_db = 0;
int have_tofu_d = 0;
@@ -1045,14 +1049,26 @@ opendbs (void)
}
}
- return xmalloc_clear (sizeof (struct dbs));
+ ctrl->tofu.dbs = xmalloc_clear (sizeof (struct tofu_dbs_s));
+ return ctrl->tofu.dbs;
}
+
/* Release all of the resources associated with a DB meta-handle. */
-static void
-closedbs (struct dbs *dbs)
+void
+tofu_closedbs (ctrl_t ctrl)
{
- if (dbs->db)
+ tofu_dbs_t dbs = ctrl->tofu.dbs;
+
+ if (!dbs)
+ return; /* Not initialized. */
+
+ if (dbs->db && dbs->db->type == DB_COMBINED)
+ {
+ log_assert (!dbs->db->next);
+ closedb (dbs->db);
+ }
+ else if (dbs->db)
{
struct db *old_head = db_cache;
struct db *db;
@@ -1103,7 +1119,8 @@ closedbs (struct dbs *dbs)
}
}
- xfree (dbs);
+ xfree (ctrl->tofu.dbs);
+ ctrl->tofu.dbs = NULL;
#if DEBUG_TOFU_CACHE
log_debug ("Queries: %d (prepares saved: %d)\n",
@@ -1142,7 +1159,7 @@ get_single_long_cb2 (void *cookie, int argc, char **argv, char **azColName,
If SHOW_OLD is set, the binding's old policy is displayed. */
static gpg_error_t
-record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
+record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email,
const char *user_id, enum tofu_policy policy, int show_old)
{
char *fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0);
@@ -1203,7 +1220,7 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
purposes, there is no need to start a transaction or to die if
there is a failure. */
{
- rc = sqlite3_stepx
+ rc = gpgsql_stepx
(db_email->db, &db_email->s.record_binding_get_old_policy,
get_single_long_cb2, &policy_old, &err,
"select policy from bindings where fingerprint = ? and email = ?",
@@ -1242,7 +1259,7 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
goto out;
}
- rc = sqlite3_stepx
+ rc = gpgsql_stepx
(db_email->db, &db_email->s.record_binding_update, NULL, NULL, &err,
"insert or replace into bindings\n"
" (oid, fingerprint, email, user_id, time, policy)\n"
@@ -1270,7 +1287,7 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
{
log_assert (opt.tofu_db_format == TOFU_DB_SPLIT);
- rc = sqlite3_stepx
+ rc = gpgsql_stepx
(db_key->db, &db_key->s.record_binding_update2, NULL, NULL, &err,
"insert or replace into bindings\n"
" (oid, fingerprint, email, user_id)\n"
@@ -1485,7 +1502,7 @@ time_ago_scale (signed long t)
if CONFLICT is not NULL. Returns _tofu_GET_POLICY_ERROR if an error
occurs. */
static enum tofu_policy
-get_policy (struct dbs *dbs, const char *fingerprint, const char *email,
+get_policy (tofu_dbs_t dbs, const char *fingerprint, const char *email,
char **conflict)
{
struct db *db;
@@ -1503,7 +1520,7 @@ get_policy (struct dbs *dbs, const char *fingerprint, const char *email,
(TOFU_POLICY_NONE cannot appear in the DB. Thus, if POLICY is
still TOFU_POLICY_NONE after executing the query, then the
result set was empty.) */
- rc = sqlite3_stepx (db->db, &db->s.get_policy_select_policy_and_conflict,
+ rc = gpgsql_stepx (db->db, &db->s.get_policy_select_policy_and_conflict,
strings_collect_cb2, &strlist, &err,
"select policy, conflict from bindings\n"
" where fingerprint = ? and email = ?",
@@ -1585,28 +1602,435 @@ get_policy (struct dbs *dbs, const char *fingerprint, const char *email,
return policy;
}
-/* Return the trust level (TRUST_NEVER, etc.) for the binding
- <FINGERPRINT, EMAIL> (email is already normalized). If no policy
- is registered, returns TOFU_POLICY_NONE. If an error occurs,
- returns _tofu_GET_TRUST_ERROR.
- USER_ID is the unadultered user id.
+/* Format the first part of a conflict message and return that as a
+ * malloced string. */
+static char *
+format_conflict_msg_part1 (int policy, const char *conflict,
+ const char *fingerprint, const char *email)
+{
+ estream_t fp;
+ char *binding;
+ int binding_shown = 0;
+ char *tmpstr, *text;
+
+ binding = xasprintf ("<%s, %s>", fingerprint, email);
+
+ fp = es_fopenmem (0, "rw,samethread");
+ if (!fp)
+ log_fatal ("error creating memory stream: %s\n",
+ gpg_strerror (gpg_error_from_syserror()));
+
+ if (policy == TOFU_POLICY_NONE)
+ {
+ es_fprintf (fp, _("The binding %s is NOT known."), binding);
+ es_fputs (" ", fp);
+ binding_shown = 1;
+ }
+ else if (policy == TOFU_POLICY_ASK
+ /* If there the conflict is with itself, then don't
+ * display this message. */
+ && conflict && strcmp (conflict, fingerprint))
+ {
+ es_fprintf (fp,
+ _("The key with fingerprint %s raised a conflict "
+ "with the binding %s."
+ " Since this binding's policy was 'auto', it was "
+ "changed to 'ask'."),
+ conflict, binding);
+ es_fputs (" ", fp);
+ binding_shown = 1;
+ }
+
+ /* TRANSLATORS: The %s%s is replaced by either a fingerprint and a
+ blank or by two empty strings. */
+ es_fprintf (fp,
+ _("Please indicate whether you believe the binding %s%s"
+ "is legitimate (the key belongs to the stated owner) "
+ "or a forgery (bad)."),
+ binding_shown ? "" : binding,
+ binding_shown ? "" : " ");
+ es_fputc ('\n', fp);
+
+ xfree (binding);
+
+ es_fputc (0, fp);
+ if (es_fclose_snatch (fp, (void **)&tmpstr, NULL))
+ log_fatal ("error snatching memory stream\n");
+ text = format_text (tmpstr, 0, 72, 80);
+ es_free (tmpstr);
+
+ return text;
+}
+
+
+/* Ask the user about the binding. There are three ways we could end
+ * up here:
+ *
+ * - This is a new binding and there is a conflict
+ * (policy == TOFU_POLICY_NONE && bindings_with_this_email_count > 0),
+ *
+ * - This is a new binding and opt.tofu_default_policy is set to
+ * ask. (policy == TOFU_POLICY_NONE && opt.tofu_default_policy ==
+ * TOFU_POLICY_ASK), or,
+ *
+ * - The policy is ask (the user deferred last time) (policy ==
+ * TOFU_POLICY_ASK).
+ */
+static void
+ask_about_binding (tofu_dbs_t dbs,
+ struct db *db,
+ enum tofu_policy *policy,
+ int *trust_level,
+ int bindings_with_this_email_count,
+ strlist_t bindings_with_this_email,
+ char *conflict,
+ const char *fingerprint,
+ const char *email,
+ const char *user_id)
+{
+ char *sqerr = NULL;
+ int rc;
+ estream_t fp;
+ strlist_t other_user_ids = NULL;
+ struct signature_stats *stats = NULL;
+ struct signature_stats *stats_iter = NULL;
+ char *prompt;
+ char *choices;
+ struct db *db_key;
+
+ fp = es_fopenmem (0, "rw,samethread");
+ if (!fp)
+ log_fatal ("error creating memory stream: %s\n",
+ gpg_strerror (gpg_error_from_syserror()));
+
+ {
+ char *text = format_conflict_msg_part1 (*policy, conflict,
+ fingerprint, email);
+ es_fputs (text, fp);
+ es_fputc ('\n', fp);
+ xfree (text);
+ }
+
+ /* Find other user ids associated with this key and whether the
+ * bindings are marked as good or bad. */
+ if (opt.tofu_db_format == TOFU_DB_SPLIT)
+ {
+ /* In the split format, we need to search in the fingerprint DB
+ * for all the emails associated with this key, not the email DB. */
+ db_key = getdb (dbs, fingerprint, DB_KEY);
+ }
+ else
+ db_key = db;
+
+ if (db_key)
+ {
+ rc = gpgsql_stepx
+ (db_key->db, &db_key->s.get_trust_gather_other_user_ids,
+ strings_collect_cb2, &other_user_ids, &sqerr,
+ opt.tofu_db_format == TOFU_DB_SPLIT
+ ? "select user_id, email from bindings where fingerprint = ?;"
+ : "select user_id, policy from bindings where fingerprint = ?;",
+ SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_END);
+ if (rc)
+ {
+ log_error (_("error gathering other user IDs: %s\n"), sqerr);
+ sqlite3_free (sqerr);
+ sqerr = NULL;
+ }
+ }
+
+ if (other_user_ids)
+ {
+ strlist_t strlist_iter;
+
+ es_fprintf (fp, _("Known user IDs associated with this key:\n"));
+ for (strlist_iter = other_user_ids;
+ strlist_iter;
+ strlist_iter = strlist_iter->next)
+ {
+ char *other_user_id = strlist_iter->d;
+ char *other_thing;
+ enum tofu_policy other_policy;
+
+ log_assert (strlist_iter->next);
+ strlist_iter = strlist_iter->next;
+ other_thing = strlist_iter->d;
+
+ if (opt.tofu_db_format == TOFU_DB_SPLIT)
+ other_policy = get_policy (dbs, fingerprint, other_thing, NULL);
+ else
+ other_policy = atoi (other_thing);
+
+ es_fprintf (fp, " %s (", other_user_id);
+ es_fprintf (fp, _("policy: %s"), tofu_policy_str (other_policy));
+ es_fprintf (fp, ")\n");
+ }
+ es_fprintf (fp, "\n");
+
+ free_strlist (other_user_ids);
+ }
+
+ /* Find other keys associated with this email address. */
+ /* FIXME: When generating the statistics, do we want the time
+ embedded in the signature (column 'sig_time') or the time that
+ we first verified the signature (column 'time'). */
+ rc = gpgsql_stepx
+ (db->db, &db->s.get_trust_gather_other_keys,
+ signature_stats_collect_cb, &stats, &sqerr,
+ "select fingerprint, policy, time_ago, count(*)\n"
+ " from (select bindings.*,\n"
+ " case\n"
+ /* From the future (but if its just a couple of hours in the
+ * future don't turn it into a warning)? Or should we use
+ * small, medium or large units? (Note: whatever we do, we
+ * keep the value in seconds. Then when we group, everything
+ * that rounds to the same number of seconds is grouped.) */
+ " when delta < -("STRINGIFY (TIME_AGO_FUTURE_IGNORE)") then -1\n"
+ " when delta < ("STRINGIFY (TIME_AGO_MEDIUM_THRESHOLD)")\n"
+ " then max(0,\n"
+ " round(delta / ("STRINGIFY (TIME_AGO_UNIT_SMALL)"))\n"
+ " * ("STRINGIFY (TIME_AGO_UNIT_SMALL)"))\n"
+ " when delta < ("STRINGIFY (TIME_AGO_LARGE_THRESHOLD)")\n"
+ " then round(delta / ("STRINGIFY (TIME_AGO_UNIT_MEDIUM)"))\n"
+ " * ("STRINGIFY (TIME_AGO_UNIT_MEDIUM)")\n"
+ " else round(delta / ("STRINGIFY (TIME_AGO_UNIT_LARGE)"))\n"
+ " * ("STRINGIFY (TIME_AGO_UNIT_LARGE)")\n"
+ " end time_ago,\n"
+ " delta time_ago_raw\n"
+ " from bindings\n"
+ " left join\n"
+ " (select *,\n"
+ " cast(strftime('%s','now') - sig_time as real) delta\n"
+ " from signatures) ss\n"
+ " on ss.binding = bindings.oid)\n"
+ " where email = ?\n"
+ " group by fingerprint, time_ago\n"
+ /* Make sure the current key is first. */
+ " order by fingerprint = ? asc, fingerprint desc, time_ago desc;\n",
+ SQLITE_ARG_STRING, email, SQLITE_ARG_STRING, fingerprint,
+ SQLITE_ARG_END);
+ if (rc)
+ {
+ strlist_t strlist_iter;
+
+ log_error (_("error gathering signature stats: %s\n"), sqerr);
+ sqlite3_free (sqerr);
+ sqerr = NULL;
- If MAY_ASK is set, then we may interact with the user. This is
- necessary if there is a conflict or the binding's policy is
- TOFU_POLICY_ASK. In the case of a conflict, we set the new
- conflicting binding's policy to TOFU_POLICY_ASK. In either case,
- we return TRUST_UNDEFINED. */
+ es_fprintf (fp, ngettext("The email address \"%s\" is"
+ " associated with %d key:\n",
+ "The email address \"%s\" is"
+ " associated with %d keys:\n",
+ bindings_with_this_email_count),
+ email, bindings_with_this_email_count);
+ for (strlist_iter = bindings_with_this_email;
+ strlist_iter;
+ strlist_iter = strlist_iter->next)
+ es_fprintf (fp, " %s\n", strlist_iter->d);
+ }
+ else
+ {
+ char *key = NULL;
+
+ if (! stats || strcmp (stats->fingerprint, fingerprint))
+ {
+ /* If we have already added this key to the DB, then it will
+ * be first (see the above select). Since the first key on
+ * the list is not this key, we must not yet have verified any
+ * messages signed by this key. Add a dummy entry. */
+ signature_stats_prepend (&stats, fingerprint, TOFU_POLICY_AUTO, 0, 0);
+ }
+
+ es_fprintf (fp, _("Statistics for keys with the email address \"%s\":\n"),
+ email);
+ for (stats_iter = stats; stats_iter; stats_iter = stats_iter->next)
+ {
+ if (! key || strcmp (key, stats_iter->fingerprint))
+ {
+ int this_key;
+ char *key_pp;
+
+ key = stats_iter->fingerprint;
+ this_key = strcmp (key, fingerprint) == 0;
+ key_pp = format_hexfingerprint (key, NULL, 0);
+ es_fprintf (fp, " %s (", key_pp);
+ if (this_key)
+ es_fprintf (fp, _("this key"));
+ else
+ es_fprintf (fp, _("policy: %s"),
+ tofu_policy_str (stats_iter->policy));
+ es_fputs ("):\n", fp);
+ xfree (key_pp);
+ }
+
+ es_fputs (" ", fp);
+ if (stats_iter->time_ago == -1)
+ es_fprintf (fp, ngettext("%ld message signed in the future.",
+ "%ld messages signed in the future.",
+ stats_iter->count), stats_iter->count);
+ else
+ {
+ long t_scaled = time_ago_scale (stats_iter->time_ago);
+
+ /* TANSLATORS: This string is concatenated with one of
+ * the day/week/month strings to form one sentence. */
+ es_fprintf (fp, ngettext("%ld message signed",
+ "%ld messages signed",
+ stats_iter->count), stats_iter->count);
+ if (!stats_iter->count)
+ es_fputs (".", fp);
+ else if (stats_iter->time_ago < TIME_AGO_UNIT_MEDIUM)
+ es_fprintf (fp, ngettext(" over the past %ld day.",
+ " over the past %ld days.",
+ t_scaled), t_scaled);
+ else if (stats_iter->time_ago < TIME_AGO_UNIT_LARGE)
+ es_fprintf (fp, ngettext(" over the past %ld week.",
+ " over the past %ld weeks.",
+ t_scaled), t_scaled);
+ else
+ es_fprintf (fp, ngettext(" over the past %ld month.",
+ " over the past %ld months.",
+ t_scaled), t_scaled);
+ }
+ es_fputs ("\n", fp);
+ }
+ }
+
+
+ if ((*policy == TOFU_POLICY_NONE && bindings_with_this_email_count > 0)
+ || (*policy == TOFU_POLICY_ASK && conflict))
+ {
+ /* This is a conflict. */
+
+ /* 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. */
+ char *text = _("TOFU detected a binding conflict");
+ char *textbuf;
+ if (!strcmp (text, "TOFU detected a binding conflict"))
+ {
+ /* No translation. Use the English text. */
+ text =
+ "Normally, there is only a single key associated with an email "
+ "address. However, people sometimes generate a new key if "
+ "their key is too old or they think it might be compromised. "
+ "Alternatively, a new key may indicate a man-in-the-middle "
+ "attack! Before accepting this key, you should talk to or "
+ "call the person to make sure this new key is legitimate.";
+ }
+ textbuf = format_text (text, 0, 72, 80);
+ es_fprintf (fp, "\n%s\n", text);
+ xfree (textbuf);
+ }
+
+ es_fputc ('\n', fp);
+
+ /* Add a NUL terminator. */
+ es_fputc (0, fp);
+ if (es_fclose_snatch (fp, (void **) &prompt, NULL))
+ log_fatal ("error snatching memory stream\n");
+
+ /* I think showing the large message once is sufficient. If we
+ * would move it right before the cpr_get many lines will scroll
+ * away and the user might not realize that he merely entered a
+ * wrong choise (because he does not see that either). As a small
+ * benefit we allow C-L to redisplay everything. */
+ tty_printf ("%s", prompt);
+ while (1)
+ {
+ char *response;
+
+ /* 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. */
+ choices = _("gG" "aA" "uU" "rR" "bB");
+ if (strlen (choices) != 10)
+ log_bug ("Bad TOFU conflict translation! Please report.");
+
+ response = cpr_get
+ ("tofu.conflict",
+ _("(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "));
+ trim_spaces (response);
+ cpr_kill_prompt ();
+ if (*response == CONTROL_L)
+ tty_printf ("%s", prompt);
+ else if (strlen (response) == 1)
+ {
+ char *choice = strchr (choices, *response);
+ if (choice)
+ {
+ int c = ((size_t) choice - (size_t) choices) / 2;
+
+ switch (c)
+ {
+ case 0: /* Good. */
+ *policy = TOFU_POLICY_GOOD;
+ *trust_level = tofu_policy_to_trust_level (*policy);
+ break;
+ case 1: /* Accept once. */
+ *policy = TOFU_POLICY_ASK;
+ *trust_level = tofu_policy_to_trust_level (TOFU_POLICY_GOOD);
+ break;
+ case 2: /* Unknown. */
+ *policy = TOFU_POLICY_UNKNOWN;
+ *trust_level = tofu_policy_to_trust_level (*policy);
+ break;
+ case 3: /* Reject once. */
+ *policy = TOFU_POLICY_ASK;
+ *trust_level = tofu_policy_to_trust_level (TOFU_POLICY_BAD);
+ break;
+ case 4: /* Bad. */
+ *policy = TOFU_POLICY_BAD;
+ *trust_level = tofu_policy_to_trust_level (*policy);
+ break;
+ default:
+ log_bug ("c should be between 0 and 4 but it is %d!", c);
+ }
+
+ if (record_binding (dbs, fingerprint, email, user_id,
+ *policy, 0))
+ {
+ /* If there's an error registering the
+ * binding, don't save the signature. */
+ *trust_level = _tofu_GET_TRUST_ERROR;
+ }
+ break;
+ }
+ }
+ xfree (response);
+ }
+
+ xfree (prompt);
+
+ signature_stats_free (stats);
+}
+
+
+/* Return the trust level (TRUST_NEVER, etc.) for the binding
+ * <FINGERPRINT, EMAIL> (email is already normalized). If no policy
+ * is registered, returns TOFU_POLICY_NONE. If an error occurs,
+ * returns _tofu_GET_TRUST_ERROR.
+ *
+ * PK is the public key object for FINGERPRINT.
+ *
+ * USER_ID is the unadulterated user id.
+ *
+ * If MAY_ASK is set, then we may interact with the user. This is
+ * necessary if there is a conflict or the binding's policy is
+ * TOFU_POLICY_ASK. In the case of a conflict, we set the new
+ * conflicting binding's policy to TOFU_POLICY_ASK. In either case,
+ * we return TRUST_UNDEFINED. */
static enum tofu_policy
-get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
+get_trust (tofu_dbs_t dbs, PKT_public_key *pk,
+ const char *fingerprint, const char *email,
const char *user_id, int may_ask)
{
- char *fingerprint_pp;
struct db *db;
enum tofu_policy policy;
char *conflict = NULL;
int rc;
- char *err = NULL;
+ char *sqerr = NULL;
strlist_t bindings_with_this_email = NULL;
int bindings_with_this_email_count;
int change_conflicting_to_ask = 0;
@@ -1629,46 +2053,12 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
if (! db)
return _tofu_GET_TRUST_ERROR;
- fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0);
-
policy = get_policy (dbs, fingerprint, email, &conflict);
if (policy == TOFU_POLICY_AUTO || policy == TOFU_POLICY_NONE)
- /* See if the key is ultimately trusted. If so, we're done. */
- {
- PKT_public_key *pk;
+ { /* See if the key is ultimately trusted. If so, we're done. */
u32 kid[2];
- char fpr_bin[MAX_FINGERPRINT_LEN+1];
- size_t fpr_bin_len;
- if (!hex2str (fingerprint, fpr_bin, sizeof fpr_bin, &fpr_bin_len))
- {
- log_error ("error converting fingerprint: %s\n",
- gpg_strerror (gpg_error_from_syserror ()));
- return _tofu_GET_TRUST_ERROR;
- }
-
- /* We need to lookup the key by fingerprint again so that we can
- properly extract the keyid. Extracting direct from the
- fingerprint works only for v4 keys and would assume that
- there is no collision in the low 64 bit. We can't guarantee
- the latter in case the Tofu DB is used with a different
- keyring. In any case the UTK stuff needs to be changed to
- use only fingerprints. */
- pk = xtrycalloc (1, sizeof *pk);
- if (!pk)
- {
- log_error (_("out of core\n"));
- return _tofu_GET_TRUST_ERROR;
- }
- rc = get_pubkey_byfprint_fast (pk, fpr_bin, fpr_bin_len);
- if (rc)
- {
- log_error (_("public key %s not found: %s\n"),
- fingerprint, gpg_strerror (rc));
- return _tofu_GET_TRUST_ERROR;
- }
keyid_from_pk (pk, kid);
- free_public_key (pk);
if (tdb_keyid_is_utk (kid))
{
@@ -1704,7 +2094,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
case TOFU_POLICY_UNKNOWN:
case TOFU_POLICY_BAD:
/* The saved judgement is auto -> auto, good, unknown or bad.
- We don't need to ask the user anything. */
+ * We don't need to ask the user anything. */
if (DBG_TRUST)
log_debug ("TOFU: Known binding <%s, %s>'s policy: %s\n",
fingerprint, email, tofu_policy_str (policy));
@@ -1723,7 +2113,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
case TOFU_POLICY_NONE:
/* The binding is new, we need to check for conflicts. Case #3
- below. */
+ * below. */
break;
case _tofu_GET_POLICY_ERROR:
@@ -1736,49 +2126,51 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
/* We get here if:
-
- 1. The saved policy is auto and the default policy is ask
- (get_policy() == TOFU_POLICY_AUTO
- && opt.tofu_default_policy == TOFU_POLICY_ASK)
-
- 2. The saved policy is ask (either last time the user selected
- accept once or reject once or there was a conflict and this
- binding's policy was changed from auto to ask)
- (policy == TOFU_POLICY_ASK), or,
-
- 3. We don't have a saved policy (policy == TOFU_POLICY_NONE)
- (need to check for a conflict).
+ *
+ * 1. The saved policy is auto and the default policy is ask
+ * (get_policy() == TOFU_POLICY_AUTO
+ * && opt.tofu_default_policy == TOFU_POLICY_ASK)
+ *
+ * 2. The saved policy is ask (either last time the user selected
+ * accept once or reject once or there was a conflict and this
+ * binding's policy was changed from auto to ask)
+ * (policy == TOFU_POLICY_ASK), or,
+ *
+ * 3. We don't have a saved policy (policy == TOFU_POLICY_NONE)
+ * (need to check for a conflict).
*/
/* Look for conflicts. This is needed in all 3 cases.
-
- Get the fingerprints of any bindings that share the email
- address. Note: if the binding in question is in the DB, it will
- also be returned. Thus, if the result set is empty, then this is
- a new binding. */
- rc = sqlite3_stepx
+ *
+ * Get the fingerprints of any bindings that share the email
+ * address. Note: if the binding in question is in the DB, it will
+ * also be returned. Thus, if the result set is empty, then this is
+ * a new binding. */
+ rc = gpgsql_stepx
(db->db, &db->s.get_trust_bindings_with_this_email,
- strings_collect_cb2, &bindings_with_this_email, &err,
+ strings_collect_cb2, &bindings_with_this_email, &sqerr,
"select distinct fingerprint from bindings where email = ?;",
SQLITE_ARG_STRING, email, SQLITE_ARG_END);
if (rc)
{
- log_error (_("error reading TOFU database: %s\n"), err);
+ log_error (_("error reading TOFU database: %s\n"), sqerr);
print_further_info ("listing fingerprints");
- sqlite3_free (err);
+ sqlite3_free (sqerr);
goto out;
}
bindings_with_this_email_count = strlist_length (bindings_with_this_email);
if (bindings_with_this_email_count == 0
&& opt.tofu_default_policy != TOFU_POLICY_ASK)
- /* New binding with no conflict and a concrete default policy.
-
- We've never observed a binding with this email address
- (BINDINGS_WITH_THIS_EMAIL_COUNT is 0 and the above query would return
- the current binding if it were in the DB) and we have a default
- policy, which is not to ask the user. */
{
+ /* New binding with no conflict and a concrete default policy.
+ *
+ * We've never observed a binding with this email address
+ * BINDINGS_WITH_THIS_EMAIL_COUNT is 0 and the above query would
+ * return the current binding if it were in the DB) and we have
+ * a default policy, which is not to ask the user.
+ */
+
/* If we've seen this binding, then we've seen this email and
policy couldn't possibly be TOFU_POLICY_NONE. */
log_assert (policy == TOFU_POLICY_NONE);
@@ -1801,18 +2193,20 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
}
if (policy == TOFU_POLICY_NONE)
- /* This is a new binding and we have a conflict. Mark any
- conflicting bindings that have an automatic policy as now
- requiring confirmation. Note: we delay this until after we ask
- for confirmation so that when the current policy is printed, it
- is correct. */
- change_conflicting_to_ask = 1;
+ {
+ /* This is a new binding and we have a conflict. Mark any
+ * conflicting bindings that have an automatic policy as now
+ * requiring confirmation. Note: we delay this until after we
+ * ask for confirmation so that when the current policy is
+ * printed, it is correct. */
+ change_conflicting_to_ask = 1;
+ }
if (! may_ask)
- /* We can only get here in the third case (no saved policy) and if
- there is a conflict. (If the policy was ask (cases #1 and #2)
- and we weren't allowed to ask, we'd have already exited). */
{
+ /* We can only get here in the third case (no saved policy) and
+ * if there is a conflict. (If the policy was ask (cases #1 and
+ * #2) and we weren't allowed to ask, we'd have already exited). */
log_assert (policy == TOFU_POLICY_NONE);
if (record_binding (dbs, fingerprint, email, user_id,
@@ -1824,412 +2218,52 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
goto out;
}
- /* If we get here, we need to ask the user about the binding. There
- are three ways we could end up here:
-
- - This is a new binding and there is a conflict
- (policy == TOFU_POLICY_NONE && bindings_with_this_email_count > 0),
-
- - This is a new binding and opt.tofu_default_policy is set to
- ask. (policy == TOFU_POLICY_NONE && opt.tofu_default_policy ==
- TOFU_POLICY_ASK), or,
-
- - The policy is ask (the user deferred last time) (policy ==
- TOFU_POLICY_ASK).
- */
- {
- int is_conflict =
- ((policy == TOFU_POLICY_NONE && bindings_with_this_email_count > 0)
- || (policy == TOFU_POLICY_ASK && conflict));
- estream_t fp;
- strlist_t other_user_ids = NULL;
- struct signature_stats *stats = NULL;
- struct signature_stats *stats_iter = NULL;
- char *prompt;
- char *choices;
-
- fp = es_fopenmem (0, "rw,samethread");
- if (! fp)
- log_fatal ("error creating memory stream: %s\n",
- gpg_strerror (gpg_error_from_syserror()));
-
- /* Format the first part of the message. */
- {
- estream_t fp1;
- char *binding = xasprintf ("<%s, %s>", fingerprint, email);
- int binding_shown = 0;
- char *tmpstr, *text;
-
- fp1 = es_fopenmem (0, "rw,samethread");
- if (!fp1)
- log_fatal ("error creating memory stream: %s\n",
- gpg_strerror (gpg_error_from_syserror()));
-
- if (policy == TOFU_POLICY_NONE)
- {
- es_fprintf (fp1, _("The binding %s is NOT known."), binding);
- es_fputs (" ", fp1);
- binding_shown = 1;
- }
- else if (policy == TOFU_POLICY_ASK
- /* If there the conflict is with itself, then don't
- display this message. */
- && conflict && strcmp (conflict, fingerprint) != 0)
- {
- es_fprintf (fp1,
- _("The key with fingerprint %s raised a conflict "
- "with the binding %s."
- " Since this binding's policy was 'auto', it was "
- "changed to 'ask'."),
- conflict, binding);
- es_fputs (" ", fp1);
- binding_shown = 1;
- }
-
- /* TRANSLATORS: The %s%s is replaced by either a fingerprint and a
- blank or by two empty strings. */
- es_fprintf (fp1,
- _("Please indicate whether you believe the binding %s%s"
- "is legitimate (the key belongs to the stated owner) "
- "or a forgery (bad)."),
- binding_shown ? "" : binding,
- binding_shown ? "" : " ");
- es_fputc ('\n', fp1);
-
- xfree (binding);
-
- es_fputc (0, fp1);
- if (es_fclose_snatch (fp1, (void **)&tmpstr, NULL))
- log_fatal ("error snatching memory stream\n");
- text = format_text (tmpstr, 0, 72, 80);
- es_free (tmpstr);
-
- es_fputs (text, fp);
- xfree (text);
- }
-
- es_fputc ('\n', fp);
-
- /* Find other user ids associated with this key and whether the
- bindings are marked as good or bad. */
- {
- struct db *db_key;
-
- if (opt.tofu_db_format == TOFU_DB_SPLIT)
- /* In the split format, we need to search in the fingerprint
- DB for all the emails associated with this key, not the
- email DB. */
- db_key = getdb (dbs, fingerprint, DB_KEY);
- else
- db_key = db;
-
- if (db_key)
- {
- rc = sqlite3_stepx
- (db_key->db, &db_key->s.get_trust_gather_other_user_ids,
- strings_collect_cb2, &other_user_ids, &err,
- opt.tofu_db_format == TOFU_DB_SPLIT
- ? "select user_id, email from bindings where fingerprint = ?;"
- : "select user_id, policy from bindings where fingerprint = ?;",
- SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_END);
- if (rc)
- {
- log_error (_("error gathering other user IDs: %s\n"), err);
- sqlite3_free (err);
- err = NULL;
- }
- }
- }
-
- if (other_user_ids)
- {
- strlist_t strlist_iter;
-
- es_fprintf (fp, _("Known user IDs associated with this key:\n"));
- for (strlist_iter = other_user_ids;
- strlist_iter;
- strlist_iter = strlist_iter->next)
- {
- char *other_user_id = strlist_iter->d;
- char *other_thing;
- enum tofu_policy other_policy;
-
- log_assert (strlist_iter->next);
- strlist_iter = strlist_iter->next;
- other_thing = strlist_iter->d;
-
- if (opt.tofu_db_format == TOFU_DB_SPLIT)
- other_policy = get_policy (dbs, fingerprint, other_thing, NULL);
- else
- other_policy = atoi (other_thing);
-
- es_fprintf (fp, " %s (", other_user_id);
- es_fprintf (fp, _("policy: %s"), tofu_policy_str (other_policy));
- es_fprintf (fp, ")\n");
- }
- es_fprintf (fp, "\n");
-
- free_strlist (other_user_ids);
- }
-
- /* Find other keys associated with this email address. */
- /* XXX: When generating the statistics, do we want the time
- embedded in the signature (column 'sig_time') or the time that
- we first verified the signature (column 'time'). */
- rc = sqlite3_stepx
- (db->db, &db->s.get_trust_gather_other_keys,
- signature_stats_collect_cb, &stats, &err,
- "select fingerprint, policy, time_ago, count(*)\n"
- " from (select bindings.*,\n"
- " case\n"
- /* From the future (but if its just a couple of hours in the
- future don't turn it into a warning)? Or should we use
- small, medium or large units? (Note: whatever we do, we
- keep the value in seconds. Then when we group, everything
- that rounds to the same number of seconds is grouped.) */
- " when delta < -("STRINGIFY (TIME_AGO_FUTURE_IGNORE)") then -1\n"
- " when delta < ("STRINGIFY (TIME_AGO_MEDIUM_THRESHOLD)")\n"
- " then max(0,\n"
- " round(delta / ("STRINGIFY (TIME_AGO_UNIT_SMALL)"))\n"
- " * ("STRINGIFY (TIME_AGO_UNIT_SMALL)"))\n"
- " when delta < ("STRINGIFY (TIME_AGO_LARGE_THRESHOLD)")\n"
- " then round(delta / ("STRINGIFY (TIME_AGO_UNIT_MEDIUM)"))\n"
- " * ("STRINGIFY (TIME_AGO_UNIT_MEDIUM)")\n"
- " else round(delta / ("STRINGIFY (TIME_AGO_UNIT_LARGE)"))\n"
- " * ("STRINGIFY (TIME_AGO_UNIT_LARGE)")\n"
- " end time_ago,\n"
- " delta time_ago_raw\n"
- " from bindings\n"
- " left join\n"
- " (select *,\n"
- " cast(strftime('%s','now') - sig_time as real) delta\n"
- " from signatures) ss\n"
- " on ss.binding = bindings.oid)\n"
- " where email = ?\n"
- " group by fingerprint, time_ago\n"
- /* Make sure the current key is first. */
- " order by fingerprint = ? asc, fingerprint desc, time_ago desc;\n",
- SQLITE_ARG_STRING, email, SQLITE_ARG_STRING, fingerprint,
- SQLITE_ARG_END);
- if (rc)
- {
- strlist_t strlist_iter;
-
- log_error (_("error gathering signature stats: %s\n"), err);
- sqlite3_free (err);
- err = NULL;
-
- es_fprintf (fp, ngettext("The email address \"%s\" is"
- " associated with %d key:\n",
- "The email address \"%s\" is"
- " associated with %d keys:\n",
- bindings_with_this_email_count),
- email, bindings_with_this_email_count);
- for (strlist_iter = bindings_with_this_email;
- strlist_iter;
- strlist_iter = strlist_iter->next)
- es_fprintf (fp, " %s\n", strlist_iter->d);
- }
- else
- {
- char *key = NULL;
-
- if (! stats || strcmp (stats->fingerprint, fingerprint) != 0)
- /* If we have already added this key to the DB, then it will
- be first (see the above select). Since the first key on
- the list is not this key, we must not yet have verified
- any messages signed by this key. Add a dummy entry. */
- signature_stats_prepend (&stats, fingerprint, TOFU_POLICY_AUTO, 0, 0);
-
- es_fprintf
- (fp, _("Statistics for keys with the email address \"%s\":\n"),
- email);
- for (stats_iter = stats; stats_iter; stats_iter = stats_iter->next)
- {
- if (! key || strcmp (key, stats_iter->fingerprint) != 0)
- {
- int this_key;
- char *key_pp;
- key = stats_iter->fingerprint;
- this_key = strcmp (key, fingerprint) == 0;
- key_pp = format_hexfingerprint (key, NULL, 0);
- es_fprintf (fp, " %s (", key_pp);
- if (this_key)
- es_fprintf (fp, _("this key"));
- else
- es_fprintf (fp, _("policy: %s"),
- tofu_policy_str (stats_iter->policy));
- es_fputs ("):\n", fp);
- xfree (key_pp);
- }
-
- es_fputs (" ", fp);
- if (stats_iter->time_ago == -1)
- es_fprintf (fp, ngettext("%ld message signed in the future.",
- "%ld messages signed in the future.",
- stats_iter->count), stats_iter->count);
- else
- {
- long t_scaled = time_ago_scale (stats_iter->time_ago);
-
- /* TANSLATORS: This string is concatenated with one of
- * the day/week/month strings to form one sentence. */
- es_fprintf (fp, ngettext("%ld message signed",
- "%ld messages signed",
- stats_iter->count), stats_iter->count);
- if (!stats_iter->count)
- es_fputs (".", fp);
- else if (stats_iter->time_ago < TIME_AGO_UNIT_MEDIUM)
- es_fprintf (fp, ngettext(" over the past %ld day.",
- " over the past %ld days.",
- t_scaled), t_scaled);
- else if (stats_iter->time_ago < TIME_AGO_UNIT_LARGE)
- es_fprintf (fp, ngettext(" over the past %ld week.",
- " over the past %ld weeks.",
- t_scaled), t_scaled);
- else
- es_fprintf (fp, ngettext(" over the past %ld month.",
- " over the past %ld months.",
- t_scaled), t_scaled);
- }
- es_fputs ("\n", fp);
- }
- }
-
- if (is_conflict)
- {
- /* 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. */
- const char *text = _("TOFU detected a binding conflict");
- char *textbuf;
- if (strcmp (text, "TOFU detected a binding conflict") == 0)
- /* No translation. Use the English text. */
- text =
- "Normally, there is only a single key associated with an email "
- "address. However, people sometimes generate a new key if "
- "their key is too old or they think it might be compromised. "
- "Alternatively, a new key may indicate a man-in-the-middle "
- "attack! Before accepting this key, you should talk to or "
- "call the person to make sure this new key is legitimate.";
- textbuf = format_text (text, 0, 72, 80);
- es_fprintf (fp, "\n%s\n", text);
- xfree (textbuf);
- }
-
- es_fputc ('\n', fp);
-
- /* Add a NUL terminator. */
- es_fputc (0, fp);
- if (es_fclose_snatch (fp, (void **) &prompt, NULL))
- log_fatal ("error snatching memory stream\n");
-
- /* I think showing the large message once is sufficient. If we
- would move it right before the cpr_get many lines will scroll
- away and the user might not realize that he merely entered a
- wrong choise (because he does not see that either). As a small
- benefit we allow C-L to redisplay everything. */
- tty_printf ("%s", prompt);
- while (1)
- {
- char *response;
-
- /* 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. */
- choices = _("gG" "aA" "uU" "rR" "bB");
- if (strlen (choices) != 10)
- log_bug ("Bad TOFU conflict translation! Please report.");
-
- response = cpr_get
- ("tofu.conflict",
- _("(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "));
- trim_spaces (response);
- cpr_kill_prompt ();
- if (*response == CONTROL_L)
- tty_printf ("%s", prompt);
- else if (strlen (response) == 1)
- {
- char *choice = strchr (choices, *response);
- if (choice)
- {
- int c = ((size_t) choice - (size_t) choices) / 2;
-
- switch (c)
- {
- case 0: /* Good. */
- policy = TOFU_POLICY_GOOD;
- trust_level = tofu_policy_to_trust_level (policy);
- break;
- case 1: /* Accept once. */
- policy = TOFU_POLICY_ASK;
- trust_level =
- tofu_policy_to_trust_level (TOFU_POLICY_GOOD);
- break;
- case 2: /* Unknown. */
- policy = TOFU_POLICY_UNKNOWN;
- trust_level = tofu_policy_to_trust_level (policy);
- break;
- case 3: /* Reject once. */
- policy = TOFU_POLICY_ASK;
- trust_level =
- tofu_policy_to_trust_level (TOFU_POLICY_BAD);
- break;
- case 4: /* Bad. */
- policy = TOFU_POLICY_BAD;
- trust_level = tofu_policy_to_trust_level (policy);
- break;
- default:
- log_bug ("c should be between 0 and 4 but it is %d!", c);
- }
-
- if (record_binding (dbs, fingerprint, email, user_id,
- policy, 0) != 0)
- /* If there's an error registering the
- binding, don't save the signature. */
- trust_level = _tofu_GET_TRUST_ERROR;
-
- break;
- }
- }
- xfree (response);
- }
-
- xfree (prompt);
-
- signature_stats_free (stats);
- }
+ /* If we get here, we need to ask the user about the binding. */
+ ask_about_binding (dbs, db,
+ &policy,
+ &trust_level,
+ bindings_with_this_email_count,
+ bindings_with_this_email,
+ conflict,
+ fingerprint,
+ email,
+ user_id);
out:
if (change_conflicting_to_ask)
{
if (! may_ask)
- /* If we weren't allowed to ask, also update this key as
- conflicting with itself. */
- rc = sqlite3_exec_printf
- (db->db, NULL, NULL, &err,
- "update bindings set policy = %d, conflict = %Q"
- " where email = %Q"
- " and (policy = %d or (policy = %d and fingerprint = %Q));",
- TOFU_POLICY_ASK, fingerprint, email, TOFU_POLICY_AUTO,
- TOFU_POLICY_ASK, fingerprint);
+ {
+ /* If we weren't allowed to ask, also update this key as
+ conflicting with itself. */
+ rc = gpgsql_exec_printf
+ (db->db, NULL, NULL, &sqerr,
+ "update bindings set policy = %d, conflict = %Q"
+ " where email = %Q"
+ " and (policy = %d or (policy = %d and fingerprint = %Q));",
+ TOFU_POLICY_ASK, fingerprint, email, TOFU_POLICY_AUTO,
+ TOFU_POLICY_ASK, fingerprint);
+ }
else
- rc = sqlite3_exec_printf
- (db->db, NULL, NULL, &err,
- "update bindings set policy = %d, conflict = %Q"
- " where email = %Q and fingerprint != %Q and policy = %d;",
- TOFU_POLICY_ASK, fingerprint, email, fingerprint, TOFU_POLICY_AUTO);
+ {
+ rc = gpgsql_exec_printf
+ (db->db, NULL, NULL, &sqerr,
+ "update bindings set policy = %d, conflict = %Q"
+ " where email = %Q and fingerprint != %Q and policy = %d;",
+ TOFU_POLICY_ASK, fingerprint, email, fingerprint,
+ TOFU_POLICY_AUTO);
+ }
+
if (rc)
{
- log_error (_("error changing TOFU policy: %s\n"), err);
- sqlite3_free (err);
- goto out;
+ log_error (_("error changing TOFU policy: %s\n"), sqerr);
+ sqlite3_free (sqerr);
+ sqerr = NULL;
}
}
xfree (conflict);
free_strlist (bindings_with_this_email);
- xfree (fingerprint_pp);
return trust_level;
}
@@ -2405,7 +2439,7 @@ write_stats_status (long messages, enum tofu_policy policy,
}
static void
-show_statistics (struct dbs *dbs, const char *fingerprint,
+show_statistics (tofu_dbs_t dbs, const char *fingerprint,
const char *email, const char *user_id,
const char *sig_exclude)
{
@@ -2421,7 +2455,7 @@ show_statistics (struct dbs *dbs, const char *fingerprint,
fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0);
- rc = sqlite3_exec_printf
+ rc = gpgsql_exec_printf
(db->db, strings_collect_cb, &strlist, &err,
"select count (*), strftime('%%s','now') - min (signatures.time),\n"
" strftime('%%s','now') - max (signatures.time)\n"
@@ -2542,15 +2576,18 @@ show_statistics (struct dbs *dbs, const char *fingerprint,
log_fatal ("error snatching memory stream\n");
msg = format_text (tmpmsg, 0, 72, 80);
es_free (tmpmsg);
- for (p=msg; *p; p++)
- if (*p == '~')
- *p = ' ';
/* Print a status line but suppress the trailing LF.
* Spaces are not percent escaped. */
if (*msg)
write_status_buffer (STATUS_TOFU_STATS_LONG,
msg, strlen (msg)-1, -1);
+
+ /* Remove the non-breaking space markers. */
+ for (p=msg; *p; p++)
+ if (*p == '~')
+ *p = ' ';
+
}
log_string (GPGRT_LOG_INFO, msg);
@@ -2643,14 +2680,13 @@ email_from_user_id (const char *user_id)
This function returns the binding's trust level on return. If an
error occurs, this function returns TRUST_UNKNOWN. */
int
-tofu_register (PKT_public_key *pk, const char *user_id,
+tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id,
const byte *sig_digest_bin, int sig_digest_bin_len,
time_t sig_time, const char *origin, int may_ask)
{
- struct dbs *dbs;
+ tofu_dbs_t dbs;
struct db *db;
char *fingerprint = NULL;
- char *fingerprint_pp = NULL;
char *email = NULL;
char *err = NULL;
int rc;
@@ -2661,7 +2697,7 @@ tofu_register (PKT_public_key *pk, const char *user_id,
sig_digest = make_radix64_string (sig_digest_bin, sig_digest_bin_len);
- dbs = opendbs ();
+ dbs = opendbs (ctrl);
if (! dbs)
{
log_error (_("error opening TOFU database: %s\n"),
@@ -2670,7 +2706,6 @@ tofu_register (PKT_public_key *pk, const char *user_id,
}
fingerprint = hexfingerprint (pk, NULL, 0);
- fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0);
if (! *user_id)
{
@@ -2686,7 +2721,7 @@ tofu_register (PKT_public_key *pk, const char *user_id,
/* It's necessary to get the trust so that we are certain that the
binding has been registered. */
- trust_level = get_trust (dbs, fingerprint, email, user_id, may_ask);
+ trust_level = get_trust (dbs, pk, fingerprint, email, user_id, may_ask);
if (trust_level == _tofu_GET_TRUST_ERROR)
/* An error. */
{
@@ -2711,7 +2746,7 @@ tofu_register (PKT_public_key *pk, const char *user_id,
/* If we've already seen this signature before, then don't add
it again. */
- rc = sqlite3_stepx
+ rc = gpgsql_stepx
(db->db, &db->s.register_already_seen,
get_single_unsigned_long_cb2, &c, &err,
"select count (*)\n"
@@ -2761,7 +2796,7 @@ tofu_register (PKT_public_key *pk, const char *user_id,
log_assert (c == 0);
- rc = sqlite3_stepx
+ rc = gpgsql_stepx
(db->db, &db->s.register_insert, NULL, NULL, &err,
"insert into signatures\n"
" (binding, sig_digest, origin, sig_time, time)\n"
@@ -2801,10 +2836,7 @@ tofu_register (PKT_public_key *pk, const char *user_id,
already_verified ? NULL : sig_digest);
xfree (email);
- xfree (fingerprint_pp);
xfree (fingerprint);
- if (dbs)
- closedbs (dbs);
xfree (sig_digest);
return trust_level;
@@ -2884,15 +2916,15 @@ tofu_wot_trust_combine (int tofu_base, int wot_base)
Returns TRUST_UNDEFINED if an error occurs. */
int
-tofu_get_validity (PKT_public_key *pk, const char *user_id,
+tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, const char *user_id,
int may_ask)
{
- struct dbs *dbs;
+ tofu_dbs_t dbs;
char *fingerprint = NULL;
char *email = NULL;
int trust_level = TRUST_UNDEFINED;
- dbs = opendbs ();
+ dbs = opendbs (ctrl);
if (! dbs)
{
log_error (_("error opening TOFU database: %s\n"),
@@ -2911,7 +2943,7 @@ tofu_get_validity (PKT_public_key *pk, const char *user_id,
email = email_from_user_id (user_id);
- trust_level = get_trust (dbs, fingerprint, email, user_id, may_ask);
+ trust_level = get_trust (dbs, pk, fingerprint, email, user_id, may_ask);
if (trust_level == _tofu_GET_TRUST_ERROR)
/* An error. */
trust_level = TRUST_UNDEFINED;
@@ -2922,9 +2954,6 @@ tofu_get_validity (PKT_public_key *pk, const char *user_id,
die:
xfree (email);
xfree (fingerprint);
- if (dbs)
- closedbs (dbs);
-
return trust_level;
}
@@ -2936,16 +2965,16 @@ tofu_get_validity (PKT_public_key *pk, const char *user_id,
Returns 0 on success and an error code otherwise. */
gpg_error_t
-tofu_set_policy (kbnode_t kb, enum tofu_policy policy)
+tofu_set_policy (ctrl_t ctrl, kbnode_t kb, enum tofu_policy policy)
{
- struct dbs *dbs;
+ tofu_dbs_t dbs;
PKT_public_key *pk;
char *fingerprint = NULL;
log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY);
pk = kb->pkt->pkt.public_key;
- dbs = opendbs ();
+ dbs = opendbs (ctrl);
if (! dbs)
{
log_error (_("error opening TOFU database: %s\n"),
@@ -2984,8 +3013,6 @@ tofu_set_policy (kbnode_t kb, enum tofu_policy policy)
}
xfree (fingerprint);
- closedbs (dbs);
-
return 0;
}
@@ -2997,13 +3024,13 @@ tofu_set_policy (kbnode_t kb, enum tofu_policy policy)
Returns 0 on success and an error code otherwise. */
gpg_error_t
-tofu_set_policy_by_keyid (u32 *keyid, enum tofu_policy policy)
+tofu_set_policy_by_keyid (ctrl_t ctrl, u32 *keyid, enum tofu_policy policy)
{
kbnode_t keyblock = get_pubkeyblock (keyid);
if (! keyblock)
return gpg_error (GPG_ERR_NO_PUBKEY);
- return tofu_set_policy (keyblock, policy);
+ return tofu_set_policy (ctrl, keyblock, policy);
}
/* Return the TOFU policy for the specified binding in *POLICY. If no
@@ -3014,10 +3041,10 @@ tofu_set_policy_by_keyid (u32 *keyid, enum tofu_policy policy)
Returns 0 on success and an error code otherwise. */
gpg_error_t
-tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id,
+tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id,
enum tofu_policy *policy)
{
- struct dbs *dbs;
+ tofu_dbs_t dbs;
char *fingerprint;
char *email;
@@ -3025,7 +3052,7 @@ tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id,
log_assert (pk->main_keyid[0] == pk->keyid[0]
&& pk->main_keyid[1] == pk->keyid[1]);
- dbs = opendbs ();
+ dbs = opendbs (ctrl);
if (! dbs)
{
log_error (_("error opening TOFU database: %s\n"),
@@ -3041,8 +3068,6 @@ tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id,
xfree (email);
xfree (fingerprint);
- closedbs (dbs);
-
if (*policy == _tofu_GET_POLICY_ERROR)
return gpg_error (GPG_ERR_GENERAL);
return 0;
diff --git a/g10/tofu.h b/g10/tofu.h
index 7ee1083..d3448b9 100644
--- a/g10/tofu.h
+++ b/g10/tofu.h
@@ -63,6 +63,7 @@ enum tofu_policy
_tofu_GET_POLICY_ERROR = 100
};
+
/* Return a string representation of a trust policy. Returns "???" if
POLICY is not valid. */
const char *tofu_policy_str (enum tofu_policy policy);
@@ -78,7 +79,7 @@ int tofu_policy_to_trust_level (enum tofu_policy policy);
interact with the user in the case of a conflict or if the
binding's policy is ask. This function returns the binding's trust
level. If an error occurs, it returns TRUST_UNKNOWN. */
-int tofu_register (PKT_public_key *pk, const char *user_id,
+int tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id,
const byte *sigs_digest, int sigs_digest_len,
time_t sig_time, const char *origin, int may_ask);
@@ -91,18 +92,21 @@ int tofu_wot_trust_combine (int tofu, int wot);
<PK, USER_ID>. If MAY_ASK is 1, then this function may
interact with the user. If not, TRUST_UNKNOWN is returned. If an
error occurs, TRUST_UNDEFINED is returned. */
-int tofu_get_validity (PKT_public_key *pk, const char *user_id, int may_ask);
+int tofu_get_validity (ctrl_t ctrl,
+ PKT_public_key *pk, const char *user_id, int may_ask);
/* Set the policy for all non-revoked user ids in the keyblock KB to
POLICY. */
-gpg_error_t tofu_set_policy (kbnode_t kb, enum tofu_policy policy);
+gpg_error_t tofu_set_policy (ctrl_t ctrl, kbnode_t kb, enum tofu_policy policy);
/* Set the TOFU policy for all non-revoked users in the key with the
key id KEYID to POLICY. */
-gpg_error_t tofu_set_policy_by_keyid (u32 *keyid, enum tofu_policy policy);
+gpg_error_t tofu_set_policy_by_keyid (ctrl_t ctrl,
+ u32 *keyid, enum tofu_policy policy);
/* Return the TOFU policy for the specified binding in *POLICY. */
-gpg_error_t tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id,
+gpg_error_t tofu_get_policy (ctrl_t ctrl,
+ PKT_public_key *pk, PKT_user_id *user_id,
enum tofu_policy *policy);
/* When doing a lot of DB activities (in particular, when listing
@@ -111,4 +115,7 @@ gpg_error_t tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id,
void tofu_begin_batch_update (void);
void tofu_end_batch_update (void);
+/* Release all of the resources associated with a DB meta-handle. */
+void tofu_closedbs (ctrl_t ctrl);
+
#endif /*G10_TOFU_H*/
diff --git a/g10/trust.c b/g10/trust.c
index 82de7cb..8790754 100644
--- a/g10/trust.c
+++ b/g10/trust.c
@@ -131,7 +131,7 @@ string_to_trust_value (const char *str)
const char *
-uid_trust_string_fixed (PKT_public_key *key, PKT_user_id *uid)
+uid_trust_string_fixed (ctrl_t ctrl, PKT_public_key *key, PKT_user_id *uid)
{
if (!key && !uid)
{
@@ -151,11 +151,12 @@ uid_trust_string_fixed (PKT_public_key *key, PKT_user_id *uid)
return _("[ expired]");
else if(key)
{
- switch (get_validity (key, uid, NULL, 0) & TRUST_MASK)
+ switch (get_validity (ctrl, key, uid, NULL, 0) & TRUST_MASK)
{
case TRUST_UNKNOWN: return _("[ unknown]");
case TRUST_EXPIRED: return _("[ expired]");
case TRUST_UNDEFINED: return _("[ undef ]");
+ case TRUST_NEVER: return _("[ never ]");
case TRUST_MARGINAL: return _("[marginal]");
case TRUST_FULLY: return _("[ full ]");
case TRUST_ULTIMATE: return _("[ultimate]");
@@ -274,19 +275,23 @@ revalidation_mark (void)
void
-check_trustdb_stale (void)
+check_trustdb_stale (ctrl_t ctrl)
{
#ifndef NO_TRUST_MODELS
- tdb_check_trustdb_stale ();
+ tdb_check_trustdb_stale (ctrl);
+#else
+ (void)ctrl;
#endif
}
void
-check_or_update_trustdb (void)
+check_or_update_trustdb (ctrl_t ctrl)
{
#ifndef NO_TRUST_MODELS
- tdb_check_or_update ();
+ tdb_check_or_update (ctrl);
+#else
+ (void)ctrl;
#endif
}
@@ -297,8 +302,8 @@ check_or_update_trustdb (void)
* otherwise, a reasonable value for the entire key is returned.
*/
unsigned int
-get_validity (PKT_public_key *pk, PKT_user_id *uid, PKT_signature *sig,
- int may_ask)
+get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
+ PKT_signature *sig, int may_ask)
{
int rc;
unsigned int validity;
@@ -330,7 +335,7 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid, PKT_signature *sig,
#ifdef NO_TRUST_MODELS
validity = TRUST_UNKNOWN;
#else
- validity = tdb_get_validity_core (pk, uid, main_pk, sig, may_ask);
+ validity = tdb_get_validity_core (ctrl, pk, uid, main_pk, sig, may_ask);
#endif
leave:
@@ -352,14 +357,14 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid, PKT_signature *sig,
int
-get_validity_info (PKT_public_key *pk, PKT_user_id *uid)
+get_validity_info (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid)
{
int trustlevel;
if (!pk)
return '?'; /* Just in case a NULL PK is passed. */
- trustlevel = get_validity (pk, uid, NULL, 0);
+ trustlevel = get_validity (ctrl, pk, uid, NULL, 0);
if ((trustlevel & TRUST_FLAG_REVOKED))
return 'r';
return trust_letter (trustlevel);
@@ -367,14 +372,14 @@ get_validity_info (PKT_public_key *pk, PKT_user_id *uid)
const char *
-get_validity_string (PKT_public_key *pk, PKT_user_id *uid)
+get_validity_string (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid)
{
int trustlevel;
if (!pk)
return "err"; /* Just in case a NULL PK is passed. */
- trustlevel = get_validity (pk, uid, NULL, 0);
+ trustlevel = get_validity (ctrl, pk, uid, NULL, 0);
if ((trustlevel & TRUST_FLAG_REVOKED))
return _("revoked");
return trust_value_to_string (trustlevel);
diff --git a/g10/trustdb.c b/g10/trustdb.c
index 195a006..527a23d 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -70,7 +70,7 @@ static struct key_item *utk_list; /* all ultimately trusted keys */
static int pending_check_trustdb;
-static int validate_keys (int interactive);
+static int validate_keys (ctrl_t ctrl, int interactive);
/**********************************************
@@ -494,7 +494,7 @@ init_trustdb ()
* when a check is due. This can be used to run the check from a crontab
*/
void
-check_trustdb ()
+check_trustdb (ctrl_t ctrl)
{
init_trustdb();
if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC
@@ -519,7 +519,7 @@ check_trustdb ()
}
}
- validate_keys (0);
+ validate_keys (ctrl, 0);
}
else
log_info (_("no need for a trustdb check with '%s' trust model\n"),
@@ -531,12 +531,12 @@ check_trustdb ()
* Recreate the WoT.
*/
void
-update_trustdb()
+update_trustdb (ctrl_t ctrl)
{
- init_trustdb();
+ init_trustdb ();
if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC
|| opt.trust_model == TM_TOFU_PGP || opt.trust_model == TM_TOFU)
- validate_keys (1);
+ validate_keys (ctrl, 1);
else
log_info (_("no need for a trustdb update with '%s' trust model\n"),
trust_model_string(opt.trust_model));
@@ -565,14 +565,14 @@ trustdb_pending_check(void)
/* If the trustdb is dirty, and we're interactive, update it.
Otherwise, check it unless no-auto-check-trustdb is set. */
void
-tdb_check_or_update (void)
+tdb_check_or_update (ctrl_t ctrl)
{
- if(trustdb_pending_check())
+ if (trustdb_pending_check ())
{
- if(opt.interactive)
- update_trustdb();
- else if(!opt.no_auto_check_trustdb)
- check_trustdb();
+ if (opt.interactive)
+ update_trustdb (ctrl);
+ else if (!opt.no_auto_check_trustdb)
+ check_trustdb (ctrl);
}
}
@@ -938,7 +938,7 @@ tdb_cache_disabled_value (PKT_public_key *pk)
void
-tdb_check_trustdb_stale (void)
+tdb_check_trustdb_stale (ctrl_t ctrl)
{
static int did_nextcheck=0;
@@ -968,7 +968,7 @@ tdb_check_trustdb_stale (void)
{
if (!opt.quiet)
log_info (_("checking the trustdb\n"));
- validate_keys (0);
+ validate_keys (ctrl, 0);
}
}
}
@@ -981,7 +981,8 @@ tdb_check_trustdb_stale (void)
* by the TOFU code to record statistics.
*/
unsigned int
-tdb_get_validity_core (PKT_public_key *pk, PKT_user_id *uid,
+tdb_get_validity_core (ctrl_t ctrl,
+ PKT_public_key *pk, PKT_user_id *uid,
PKT_public_key *main_pk,
PKT_signature *sig,
int may_ask)
@@ -1008,7 +1009,7 @@ tdb_get_validity_core (PKT_public_key *pk, PKT_user_id *uid,
if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS)
return TRUST_UNKNOWN;
- check_trustdb_stale();
+ check_trustdb_stale (ctrl);
if(opt.trust_model==TM_DIRECT)
{
@@ -1064,12 +1065,12 @@ tdb_get_validity_core (PKT_public_key *pk, PKT_user_id *uid,
user_ids ++;
if (sig)
- tl = tofu_register (main_pk, user_id->name,
+ tl = tofu_register (ctrl, main_pk, user_id->name,
sig->digest, sig->digest_len,
sig->timestamp, "unknown",
may_ask);
else
- tl = tofu_get_validity (main_pk, user_id->name, may_ask);
+ tl = tofu_get_validity (ctrl, main_pk, user_id->name, may_ask);
if (tl == TRUST_EXPIRED)
user_ids_expired ++;
@@ -1267,7 +1268,7 @@ enum_cert_paths_print (void **context, FILE *fp,
****************************************/
static int
-ask_ownertrust (u32 *kid,int minimum)
+ask_ownertrust (ctrl_t ctrl, u32 *kid, int minimum)
{
PKT_public_key *pk;
int rc;
@@ -1291,7 +1292,7 @@ ask_ownertrust (u32 *kid,int minimum)
}
else
{
- ot=edit_ownertrust(pk,0);
+ ot=edit_ownertrust (ctrl, pk, 0);
if(ot>0)
ot = tdb_get_ownertrust (pk);
else if(ot==0)
@@ -1881,7 +1882,7 @@ reset_trust_records(void)
*
*/
static int
-validate_keys (int interactive)
+validate_keys (ctrl_t ctrl, int interactive)
{
int rc = 0;
int quit=0;
@@ -1989,7 +1990,7 @@ validate_keys (int interactive)
if (interactive && k->ownertrust == TRUST_UNKNOWN)
{
- k->ownertrust = ask_ownertrust (k->kid,min);
+ k->ownertrust = ask_ownertrust (ctrl, k->kid,min);
if (k->ownertrust == (unsigned int)(-1))
{
diff --git a/g10/trustdb.h b/g10/trustdb.h
index 7e1307d..47d7b72 100644
--- a/g10/trustdb.h
+++ b/g10/trustdb.h
@@ -83,20 +83,22 @@ void register_trusted_key (const char *string);
const char *trust_value_to_string (unsigned int value);
int string_to_trust_value (const char *str);
-const char *uid_trust_string_fixed (PKT_public_key *key, PKT_user_id *uid);
+const char *uid_trust_string_fixed (ctrl_t ctrl,
+ PKT_public_key *key, PKT_user_id *uid);
unsigned int get_ownertrust (PKT_public_key *pk);
void update_ownertrust (PKT_public_key *pk, unsigned int new_trust);
int clear_ownertrusts (PKT_public_key *pk);
void revalidation_mark (void);
-void check_trustdb_stale (void);
-void check_or_update_trustdb (void);
+void check_trustdb_stale (ctrl_t ctrl);
+void check_or_update_trustdb (ctrl_t ctrl);
-unsigned int get_validity (PKT_public_key *pk, PKT_user_id *uid,
+unsigned int get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
PKT_signature *sig, int may_ask);
-int get_validity_info (PKT_public_key *pk, PKT_user_id *uid);
-const char *get_validity_string (PKT_public_key *pk, PKT_user_id *uid);
+int get_validity_info (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid);
+const char *get_validity_string (ctrl_t ctrl,
+ PKT_public_key *pk, PKT_user_id *uid);
void mark_usable_uid_certs (kbnode_t keyblock, kbnode_t uidnode,
u32 *main_kid, struct key_item *klist,
@@ -115,22 +117,23 @@ void tdb_register_trusted_keyid (u32 *keyid);
void tdb_register_trusted_key (const char *string);
/* Returns whether KID is on the list of ultimately trusted keys. */
int tdb_keyid_is_utk (u32 *kid);
-void check_trustdb (void);
-void update_trustdb (void);
+void check_trustdb (ctrl_t ctrl);
+void update_trustdb (ctrl_t ctrl);
int setup_trustdb( int level, const char *dbname );
void how_to_fix_the_trustdb (void);
const char *trust_model_string (int model);
void init_trustdb( void );
-void tdb_check_trustdb_stale (void);
+void tdb_check_trustdb_stale (ctrl_t ctrl);
void sync_trustdb( void );
void tdb_revalidation_mark (void);
int trustdb_pending_check(void);
-void tdb_check_or_update (void);
+void tdb_check_or_update (ctrl_t ctrl);
int tdb_cache_disabled_value (PKT_public_key *pk);
-unsigned int tdb_get_validity_core (PKT_public_key *pk, PKT_user_id *uid,
+unsigned int tdb_get_validity_core (ctrl_t ctrl,
+ PKT_public_key *pk, PKT_user_id *uid,
PKT_public_key *main_pk,
PKT_signature *sig, int may_ask);
@@ -158,6 +161,6 @@ void export_ownertrust(void);
void import_ownertrust(const char *fname);
/*-- pkclist.c --*/
-int edit_ownertrust (PKT_public_key *pk, int mode );
+int edit_ownertrust (ctrl_t ctrl, PKT_public_key *pk, int mode);
#endif /*G10_TRUSTDB_H*/
diff --git a/g13/be-encfs.c b/g13/be-encfs.c
index f59f4d9..a873541 100644
--- a/g13/be-encfs.c
+++ b/g13/be-encfs.c
@@ -246,9 +246,9 @@ run_encfs_tool (ctrl_t ctrl, enum encfs_cmds cmd,
if (err)
goto leave;
- err = gnupg_create_inbound_pipe (inbound);
+ err = gnupg_create_inbound_pipe (inbound, NULL, 0);
if (!err)
- err = gnupg_create_outbound_pipe (outbound);
+ err = gnupg_create_outbound_pipe (outbound, NULL, 0);
if (err)
{
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
diff --git a/g13/g13-common.h b/g13/g13-common.h
index 316b94a..a205081 100644
--- a/g13/g13-common.h
+++ b/g13/g13-common.h
@@ -55,7 +55,6 @@ struct
int quiet; /* Be as quiet as possible. */
int dry_run; /* Don't change any persistent data. */
- const char *homedir; /* Configuration directory name. */
const char *config_filename; /* Name of the used config file. */
/* Filename of the AGENT program. */
diff --git a/g13/g13-syshelp.c b/g13/g13-syshelp.c
index 645730f..f3c20f5 100644
--- a/g13/g13-syshelp.c
+++ b/g13/g13-syshelp.c
@@ -159,7 +159,7 @@ my_strusage( int level )
break;
case 31: p = "\nHome: "; break;
- case 32: p = opt.homedir; break;
+ case 32: p = gnupg_homedir (); break;
default: p = NULL; break;
}
@@ -269,7 +269,6 @@ main ( int argc, char **argv)
log_fatal ("error allocating session environment block: %s\n",
strerror (errno));
- opt.homedir = default_homedir ();
/* Fixme: We enable verbose mode here because there is currently no
way to do this when starting g13-syshelp. To fix that we should
add a g13-syshelp.conf file in /etc/gnupg. */
@@ -393,7 +392,7 @@ main ( int argc, char **argv)
case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
- case oHomedir: opt.homedir = pargs.r.ret_str; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oFakedSystemTime:
{
@@ -427,7 +426,8 @@ main ( int argc, char **argv)
configname = NULL;
if (!opt.config_filename)
- opt.config_filename = make_filename (opt.homedir, G13_NAME".conf", NULL);
+ opt.config_filename = make_filename (gnupg_homedir (),
+ G13_NAME".conf", NULL);
if (log_get_errorcount(0))
g13_exit(2);
@@ -472,7 +472,7 @@ main ( int argc, char **argv)
/* Set the standard GnuPG random seed file. */
if (use_random_seed)
{
- char *p = make_filename (opt.homedir, "random_seed", NULL);
+ char *p = make_filename (gnupg_homedir (), "random_seed", NULL);
gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
xfree(p);
}
diff --git a/g13/g13.c b/g13/g13.c
index 4489b2f..0499a18 100644
--- a/g13/g13.c
+++ b/g13/g13.c
@@ -247,7 +247,7 @@ my_strusage( int level )
break;
case 31: p = "\nHome: "; break;
- case 32: p = opt.homedir; break;
+ case 32: p = gnupg_homedir (); break;
default: p = NULL; break;
}
@@ -391,8 +391,6 @@ main ( int argc, char **argv)
log_fatal ("error allocating session environment block: %s\n",
strerror (errno));
- opt.homedir = default_homedir ();
-
/* First check whether we have a config file on the commandline. */
orig_argc = argc;
orig_argv = argv;
@@ -412,7 +410,7 @@ main ( int argc, char **argv)
else if (pargs.r_opt == oNoOptions)
default_config = 0; /* --no-options */
else if (pargs.r_opt == oHomedir)
- opt.homedir = pargs.r.ret_str;
+ gnupg_set_homedir (pargs.r.ret_str);
}
/* Initialize the secure memory. */
@@ -446,7 +444,7 @@ main ( int argc, char **argv)
/* Set the default option file */
if (default_config )
- configname = make_filename (opt.homedir, G13_NAME".conf", NULL);
+ configname = make_filename (gnupg_homedir (), G13_NAME".conf", NULL);
argc = orig_argc;
argv = orig_argv;
@@ -552,7 +550,7 @@ main ( int argc, char **argv)
}
break;
- case oHomedir: opt.homedir = pargs.r.ret_str; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
case oGpgProgram: opt.gpg_program = pargs.r.ret_str; break;
@@ -623,7 +621,8 @@ main ( int argc, char **argv)
configname = NULL;
if (!opt.config_filename)
- opt.config_filename = make_filename (opt.homedir, G13_NAME".conf", NULL);
+ opt.config_filename = make_filename (gnupg_homedir (),
+ G13_NAME".conf", NULL);
if (log_get_errorcount(0))
g13_exit(2);
@@ -690,7 +689,7 @@ main ( int argc, char **argv)
/* Set the standard GnuPG random seed file. */
if (use_random_seed)
{
- char *p = make_filename (opt.homedir, "random_seed", NULL);
+ char *p = make_filename (gnupg_homedir (), "random_seed", NULL);
gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
xfree(p);
}
diff --git a/g13/server.c b/g13/server.c
index 33885d6..a96ec6e 100644
--- a/g13/server.c
+++ b/g13/server.c
@@ -631,12 +631,12 @@ g13_server (ctrl_t ctrl)
if (opt.verbose || opt.debug)
{
- char *tmp = NULL;
+ char *tmp;
tmp = xtryasprintf ("Home: %s\n"
"Config: %s\n"
"%s",
- opt.homedir,
+ gnupg_homedir (),
opt.config_filename,
hello);
if (tmp)
diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h
index 6af5448..d74a7ef 100644
--- a/kbx/keybox-defs.h
+++ b/kbx/keybox-defs.h
@@ -140,7 +140,6 @@ typedef struct _keybox_openpgp_info *keybox_openpgp_info_t;
/* Don't know whether this is needed: */
/* static struct { */
-/* const char *homedir; */
/* int dry_run; */
/* int quiet; */
/* int verbose; */
diff --git a/po/ca.po b/po/ca.po
index 0a64bc4..66b33de 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -492,6 +492,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "error mentre s'enviava a «%s»: %s\n"
#, fuzzy, c-format
+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"
@@ -509,10 +513,6 @@ msgid "directory '%s' created\n"
msgstr "%s: s'ha creat el directori\n"
#, fuzzy, c-format
-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 "stat() failed for '%s': %s\n"
msgstr "base de dades de confiança: ha fallat la lectura (n=%d): %s\n"
@@ -2033,13 +2033,13 @@ msgstr "canvia la contrasenya"
msgid "export keys"
msgstr "exporta claus"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "exporta claus a un servidor de claus"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importa claus d'un servidor de claus"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "cerca claus en un servidor de claus"
msgid "update all keys from a keyserver"
@@ -2648,6 +2648,9 @@ msgstr "fes els conflictes de marques de temps només un avís"
msgid "|FD|write status info to this FD"
msgstr "|FD|escriu informació d'estat en aquest FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Forma d'ús: gpgv [opcions] [fitxers] (-h per a veure l'ajuda)"
@@ -4168,6 +4171,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "No hi ha cap ID amb l'índex %d\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "arrodonida fins a %u bits\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4184,11 +4192,6 @@ msgstr "Quina grandària voleu? (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "La grandària sol·licitada és %u bits\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "arrodonida fins a %u bits\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5913,14 +5916,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "error mentre s'enviava a «%s»: %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "no s'ha trobat la clau pública %08lX: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "error en la lectura de «%s»: %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5999,14 +5994,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -6014,6 +6009,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "error en la lectura de «%s»: %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "error en la creació de la contrasenya: %s\n"
@@ -6175,6 +6174,10 @@ msgstr ""
"no és necessària una comprovació de la base de dades de confiança\n"
"\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "no s'ha trobat la clau pública %08lX: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "si us plau, feu un --check-trustdb\n"
@@ -6253,6 +6256,10 @@ msgstr "desconeguda"
msgid "[ undef ]"
msgstr ""
+#, fuzzy
+msgid "[ never ]"
+msgstr "mai "
+
msgid "[marginal]"
msgstr ""
diff --git a/po/cs.po b/po/cs.po
index 535f74c..855b825 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -464,6 +464,12 @@ 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"
@@ -480,12 +486,6 @@ msgstr "nelze vytvořit adresář „%s“: %s\n"
msgid "directory '%s' created\n"
msgstr "adresář „%s“ vytvořen\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 "stat() failed for '%s': %s\n"
msgstr "volání stat() na „%s“ selhalo: %s\n"
@@ -1869,13 +1869,13 @@ msgstr "změnit heslo"
msgid "export keys"
msgstr "exportovat klíÄe"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "exportovat klíÄe na server klíÄů"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importovat klíÄe ze serveru klíÄů"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "vyhledat klíÄe na serveru klíÄů"
msgid "update all keys from a keyserver"
@@ -2453,6 +2453,9 @@ msgstr "pouze varování pÅ™i konfliktu Äasového razítka"
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 ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Použití: gpg [volby] [soubory] (-h pro pomoc)"
@@ -3853,6 +3856,10 @@ msgid "No key with this keygrip\n"
msgstr "KlÃ­Ä s takovým keygripem neexistuje\n"
#, c-format
+msgid "rounded to %u bits\n"
+msgstr "zaokrouhleno na %u bitů\n"
+
+#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "klÃ­Ä %s může mít délku v intervalu %u až %u bitů.\n"
@@ -3868,10 +3875,6 @@ msgstr "Jakou délku klíÄe si pÅ™ejete? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "Požadovaná délka klíÄe je %u bitů.\n"
-#, c-format
-msgid "rounded to %u bits\n"
-msgstr "zaokrouhleno na %u bitů\n"
-
msgid "Please select which elliptic curve you want:\n"
msgstr "Prosím, vyberte, kterou eliptickou křivku chcete:\n"
@@ -5533,15 +5536,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "chyba při odesílání dat: %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "veÅ™ejný klÃ­Ä %s nebyl nalezen: %s\n"
-
-#, fuzzy, c-format
-#| msgid "error setting OCSP target: %s\n"
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "chyba při nastavování cíle OCSP: %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5628,14 +5622,14 @@ msgstr[1] ""
msgstr[2] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5643,6 +5637,11 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+#| msgid "error setting OCSP target: %s\n"
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "chyba při nastavování cíle OCSP: %s\n"
+
+#, fuzzy, c-format
#| msgid "error creating a pipe: %s\n"
msgid "error changing TOFU policy: %s\n"
msgstr "chyba při vytváření roury: %s\n"
@@ -5807,6 +5806,10 @@ msgstr "není nutné kontrolovat databázi důvěry s modelem „%s“\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "není nutné aktualizovat databázi důvěry s modelem „%s“\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "veÅ™ejný klÃ­Ä %s nebyl nalezen: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "prosím proveÄte --check-trustdb\n"
@@ -5886,6 +5889,11 @@ msgstr "[ neznámá ]"
msgid "[ undef ]"
msgstr "[nedefinovaná]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "žádná"
+
msgid "[marginal]"
msgstr "[ ÄásteÄná ]"
diff --git a/po/da.po b/po/da.po
index 7e6ff4b..e7d4b68 100644
--- a/po/da.po
+++ b/po/da.po
@@ -499,6 +499,11 @@ msgstr "fejl ved indhentelse af nonce for soklen\n"
msgid "error binding socket to '%s': %s\n"
msgstr "fejl ved binding af sokkel til »%s«: %s\n"
+#, fuzzy, c-format
+#| msgid "Warning: unsafe permissions on %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"
@@ -519,11 +524,6 @@ msgid "directory '%s' created\n"
msgstr "mappe »%s« oprettet\n"
#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgid "can't set permissions of '%s': %s\n"
-msgstr "Advarsel: usikre rettigheder på %s »%s«\n"
-
-#, fuzzy, c-format
#| msgid "stat() failed for `%s': %s\n"
msgid "stat() failed for '%s': %s\n"
msgstr "stat() mislykkedes for »%s«: %s\n"
@@ -1985,13 +1985,13 @@ msgstr "ændr en adgangsfrase"
msgid "export keys"
msgstr "eksporter nøgler"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "eksporter nøgler til en nøgletjener"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importer nøgler fra en nøgleserver"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "søg efter nøgler på en nøgleserver"
msgid "update all keys from a keyserver"
@@ -2593,6 +2593,9 @@ msgstr "giv kun tidsstempelkonflikter en advarsel"
msgid "|FD|write status info to this FD"
msgstr "|FD|skriv statusinformation til denne FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Brug: gpgv [tilvalg] [filer] (-h for hjælp)"
@@ -4065,6 +4068,11 @@ msgstr "Ikke et gyldigt nøglegreb (forventer 40 hex cifre)\n"
msgid "No key with this keygrip\n"
msgstr "Ingen nøgle med dette nøglegreb\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "afrundet op til %u bit\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "%s nøgler kan være mellem %u og %u bit lange.\n"
@@ -4081,11 +4089,6 @@ msgstr "Hvilken nøglestørrelse ønsker du? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "Ønsket nøglestørrelse er %u bit\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "afrundet op til %u bit\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5783,15 +5786,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "fejl under afsendelse af %s-kommando: %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "offentlig nøgle %s blev ikke fundet: %s\n"
-
-#, fuzzy, c-format
-#| msgid "error storing flags: %s\n"
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "fejl ved lagring af flag: %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5872,14 +5866,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5887,6 +5881,11 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+#| msgid "error storing flags: %s\n"
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "fejl ved lagring af flag: %s\n"
+
+#, fuzzy, c-format
#| msgid "error creating a pipe: %s\n"
msgid "error changing TOFU policy: %s\n"
msgstr "fejl ved oprettelse af datakanal: %s\n"
@@ -6048,6 +6047,10 @@ msgid "no need for a trustdb update with '%s' trust model\n"
msgstr ""
"intet behov for en opdatering af trustdb med troværdighedsmodellen »%s«\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "offentlig nøgle %s blev ikke fundet: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "udfør venligst en --check-trustdb\n"
@@ -6126,6 +6129,11 @@ msgstr "[ ukendt]"
msgid "[ undef ]"
msgstr "[ ej def]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "aldrig"
+
msgid "[marginal]"
msgstr "[marginal]"
diff --git a/po/de.po b/po/de.po
index f5886ef..8bbd5d3 100644
--- 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: 2016-05-04 11:03+0200\n"
+"PO-Revision-Date: 2016-06-16 17:04+0200\n"
"Last-Translator: Werner Koch <wk@gnupg.org>\n"
"Language-Team: German <de@li.org>\n"
"Language: de\n"
@@ -451,6 +451,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "Der Socket kann nicht an `%s' gebunden werden: %s\n"
#, c-format
+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"
@@ -467,10 +471,6 @@ msgid "directory '%s' created\n"
msgstr "Verzeichnis `%s' erzeugt\n"
#, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "Zugriffsrechte für '%s' können nicht gesetzt werden: %s\n"
-
-#, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "stat()-Aufruf für `%s' fehlgeschlagen: %s\n"
@@ -1861,13 +1861,13 @@ msgstr "Die Passphrase ändern"
msgid "export keys"
msgstr "Schlüssel exportieren"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "Schlüssel zu einem Schlü.server exportieren"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "Schlüssel von einem Schlü.server importieren"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "Schlüssel auf einem Schlü.server suchen"
msgid "update all keys from a keyserver"
@@ -2446,6 +2446,9 @@ msgstr "differierende Zeitangaben sind kein Fehler"
msgid "|FD|write status info to this FD"
msgstr "|FD|Statusinfo auf FD (Dateihandle) ausgeben"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr "|ALGO|Weise mit ALGO erstellte Signaturen zurück"
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Aufruf: gpgv [Optionen] [Dateien] (-h für Hilfe)"
@@ -3871,6 +3874,10 @@ msgid "No key with this keygrip\n"
msgstr "Kein Schlüssel mit diesem \"Keygrip\"\n"
#, c-format
+msgid "rounded to %u bits\n"
+msgstr "gerundet auf %u Bit\n"
+
+#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "%s-Schlüssel können zwischen %u und %u Bit lang sein.\n"
@@ -3886,10 +3893,6 @@ msgstr "Welche Schlüssellänge wünschen Sie? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "Die verlangte Schlüssellänge beträgt %u Bit\n"
-#, c-format
-msgid "rounded to %u bits\n"
-msgstr "gerundet auf %u Bit\n"
-
msgid "Please select which elliptic curve you want:\n"
msgstr "Bitte wählen Sie, welche elliptische Kurve Sie möchten:\n"
@@ -5553,14 +5556,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "Fehler beim Schreiben der TOFU Datenbank: %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "Öffentlicher Schlüssel %s nicht gefunden: %s\n"
-
-#, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "Fehler beim Setzen der TOFU Binding Vertrauensstufe auf %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr "Die Bindung %s ist NICHT bekannt."
@@ -5641,8 +5636,8 @@ msgstr[0] " innerhalb des letzten Monats."
msgstr[1] " innerhalb der letzten %ld Monate."
#. 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.
+#. * 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 ""
"Normalerweise ist lediglich ein Schlüssel mit einer Email-Adresse "
@@ -5654,8 +5649,8 @@ msgstr ""
"ob der neue Schlüssel legitim ist."
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr "gGaAuUlLfF"
@@ -5663,6 +5658,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr "(G)ut, einmal (A)kzeptieren, (U)nbekannt, einmal ab(L)ehnen, (F)alsch?"
#, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "Fehler beim Setzen der TOFU Binding Vertrauensstufe auf %s\n"
+
+#, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "Fehler beim Ändern der TOFU Richtlinie: %s\n"
@@ -5843,6 +5842,10 @@ msgstr "\"Trust-DB\"-Überprüfung ist beim `%s'-Vertrauensmodell nicht nötig\n
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "\"Trust-DB\"-Änderung ist beim `%s'-Vertrauensmodell nicht nötig\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "Öffentlicher Schlüssel %s nicht gefunden: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "Bitte ein --check-trustdb durchführen\n"
@@ -5912,22 +5915,25 @@ msgid "[ revoked]"
msgstr "[ widerrufen]"
msgid "[ expired]"
-msgstr "[ verfallen]"
+msgstr "[ verfallen ]"
msgid "[ unknown]"
-msgstr "[ unbekannt]"
+msgstr "[ unbekannt ]"
msgid "[ undef ]"
msgstr "[undefiniert]"
+msgid "[ never ]"
+msgstr "[ niemals ]"
+
msgid "[marginal]"
-msgstr "[ marginal]"
+msgstr "[ marginal ]"
msgid "[ full ]"
msgstr "[vollständig]"
msgid "[ultimate]"
-msgstr "[ ultimativ]"
+msgstr "[ ultimativ ]"
msgid ""
"the signature could not be verified.\n"
diff --git a/po/el.po b/po/el.po
index d4316dd..7e3fcf2 100644
--- a/po/el.po
+++ b/po/el.po
@@ -462,6 +462,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "óöÜëìá óôç áðïóôïëÞ ðñïò ôï `%s': %s\n"
#, fuzzy, c-format
+msgid "can't set permissions of '%s': %s\n"
+msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëåßò Üäåéåò óôï %s \"%s\"\n"
+
+#, fuzzy, c-format
msgid "listen() failed: %s\n"
msgstr "ç åíçìÝñùóç áðÝôõ÷å: %s\n"
@@ -479,10 +483,6 @@ msgid "directory '%s' created\n"
msgstr "%s: êáôÜëïãïò äçìéïõñãÞèçêå\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëåßò Üäåéåò óôï %s \"%s\"\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "trustdb: read áðÝôõ÷å (n=%d): %s\n"
@@ -1963,13 +1963,13 @@ msgstr "áëëáãÞ ôçò öñÜóçò êëåéäß"
msgid "export keys"
msgstr "åîáãùãÞ êëåéäéþí"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "åîáãùãÞ êëåéäéþí óå Ýíá äéáêïìéóôÞ êëåéäéþí"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "åéóáãùãÞ êëåéäéþí áðü Ýíá äéáêïìéóôÞ êëåéäéþí"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "áíáæÞôçóç êëåéäéþí óå Ýíá äéáêïìéóôÞ êëåéäéþí"
msgid "update all keys from a keyserver"
@@ -2570,6 +2570,9 @@ msgstr "ïñéóìüò ôùí óõãêñïýóåùí þñáò (timestamp) ìüíï óáí ðñïåéäïðïßçóç"
msgid "|FD|write status info to this FD"
msgstr "|FD|åããñáöÞ ôùí ðëçñïöïñéþí êáôÜóôáóçò óôï FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "×ñÞóç: gpgv [åðéëïãÝò] [áñ÷åßá] (-h ãéá âïÞèåéá)"
@@ -4070,6 +4073,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Äåí õðÜñ÷åé user ID ìå äåßêôç %d\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "óôñïããõëïðïéÞèçêå Ýùò ôá %u bits\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4086,11 +4094,6 @@ msgstr "Ôé ìÝãåèïò êëåéäéïý èá èÝëáôå; (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "Ôï ìÝãåèïò êëåéäéïý ðïõ æçôÞèçêå åßíáé %u bits\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "óôñïããõëïðïéÞèçêå Ýùò ôá %u bits\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5778,14 +5781,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "óöÜëìá óôç áðïóôïëÞ ðñïò ôï `%s': %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "ôï äçìüóéï êëåéäß %08lX äåí âñÝèçêå: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5864,14 +5859,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5879,6 +5874,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "óöÜëìá óôç äçìéïõñãßá ôçò öñÜóçò êëåéäß: %s\n"
@@ -6034,6 +6033,10 @@ msgstr "äåí õðÜñ÷åé áíÜãêç ãéá Ýëåã÷ï ôçò trustdb\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "äåí õðÜñ÷åé áíÜãêç ãéá Ýëåã÷ï ôçò trustdb\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "ôï äçìüóéï êëåéäß %08lX äåí âñÝèçêå: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "ðáñáêáëþ êÜíôå Ýíá --check-trustdb\n"
@@ -6112,6 +6115,10 @@ msgstr "Üãíùóôï"
msgid "[ undef ]"
msgstr ""
+#, fuzzy
+msgid "[ never ]"
+msgstr "ðïôÝ "
+
msgid "[marginal]"
msgstr ""
diff --git a/po/eo.po b/po/eo.po
index 43b29a8..f8e64f5 100644
--- a/po/eo.po
+++ b/po/eo.po
@@ -463,6 +463,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "eraro dum sendo al '%s': %s\n"
#, fuzzy, c-format
+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"
@@ -479,10 +483,6 @@ msgid "directory '%s' created\n"
msgstr "%s: dosierujo kreita\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "Averto: malsekuraj permesoj sur %s \"%s\"\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "fido-datenaro: lego malsukcesis (n=%d): %s\n"
@@ -1949,13 +1949,13 @@ msgstr "þanøi la pasfrazon"
msgid "export keys"
msgstr "eksporti þlosilojn"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "eksporti þlosilojn al þlosilservilo"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importi þlosilojn de þlosilservilo"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "seræi þlosilojn æe þlosilservilo"
msgid "update all keys from a keyserver"
@@ -2556,6 +2556,9 @@ msgstr "malkongruo de tempostampoj"
msgid "|FD|write status info to this FD"
msgstr "|FD|skribi statusinformojn al FD (dosierpriskribilo)"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
#, fuzzy
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Uzado: gpg [opcioj] [dosieroj] (-h por helpo)"
@@ -4046,6 +4049,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Mankas uzantidentigilo kun indekso %d\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "rondigita øis %u bitoj\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4062,11 +4070,6 @@ msgstr "Kiun þlosilgrandon vi deziras? (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "Petita þlosilgrando estas %u bitoj\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "rondigita øis %u bitoj\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5724,14 +5727,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "eraro dum sendo al '%s': %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "publika þlosilo %08lX ne trovita: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "eraro dum legado de '%s': %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5810,14 +5805,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5825,6 +5820,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "eraro dum legado de '%s': %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "eraro dum kreado de pasfrazo: %s\n"
@@ -5978,6 +5977,10 @@ msgstr "kontrolo de fido-datenaro ne estas bezonata\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "kontrolo de fido-datenaro ne estas bezonata\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "publika þlosilo %08lX ne trovita: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr ""
@@ -6054,6 +6057,9 @@ msgstr "nekonata versio"
msgid "[ undef ]"
msgstr ""
+msgid "[ never ]"
+msgstr ""
+
msgid "[marginal]"
msgstr ""
diff --git a/po/es.po b/po/es.po
index 09fc298..385ea2b 100644
--- a/po/es.po
+++ b/po/es.po
@@ -515,6 +515,11 @@ msgstr "error obteniendo valor único para el socket\n"
msgid "error binding socket to '%s': %s\n"
msgstr "error enlazando el socket con `%s': %s\n"
+#, fuzzy, c-format
+#| msgid "Warning: unsafe permissions on %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"
@@ -535,11 +540,6 @@ msgid "directory '%s' created\n"
msgstr "directorio `%s' creado\n"
#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgid "can't set permissions of '%s': %s\n"
-msgstr "Aviso: permisos inseguros en %s \"%s\"\n"
-
-#, fuzzy, c-format
#| msgid "stat() failed for `%s': %s\n"
msgid "stat() failed for '%s': %s\n"
msgstr "stat() falló para `%s': %s\n"
@@ -2004,13 +2004,13 @@ msgstr "cambia una frase contraseña"
msgid "export keys"
msgstr "exporta claves"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "exporta claves a un servidor de claves"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importa claves desde un servidor de claves"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "busca claves en un servidor de claves"
msgid "update all keys from a keyserver"
@@ -2622,6 +2622,9 @@ msgstr "hacer que los conflictos de fecha-hora sean sólo un aviso"
msgid "|FD|write status info to this FD"
msgstr "|DF|escribe información de estado en este descriptor de fichero"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Uso: gpgv [opciones] [ficheros] (-h para ayuda)"
@@ -4066,6 +4069,11 @@ msgstr "No es un keygrip válido (se esperaban 40 dígitos hex)\n"
msgid "No key with this keygrip\n"
msgstr "No hay claves con ese keygrip\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "redondeados a %u bits\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "las claves %s pueden tener entre %u y %u bits de longitud.\n"
@@ -4082,11 +4090,6 @@ msgstr "¿De qué tamaño quiere la clave? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "El tamaño requerido es de %u bits\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "redondeados a %u bits\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5776,15 +5779,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "error enviando orden %s: %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "clave pública %s no encontrada: %s\n"
-
-#, fuzzy, c-format
-#| msgid "error storing flags: %s\n"
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "error almacenando parámetros: %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5865,14 +5859,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5880,6 +5874,11 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+#| msgid "error storing flags: %s\n"
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "error almacenando parámetros: %s\n"
+
+#, fuzzy, c-format
#| msgid "error creating a pipe: %s\n"
msgid "error changing TOFU policy: %s\n"
msgstr "error creando tubería: %s\n"
@@ -6044,6 +6043,10 @@ msgstr ""
"no es necesario comprobar la base de datos de confianza\n"
"con el modelo `%s'\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "clave pública %s no encontrada: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "por favor haga un --check-trustdb\n"
@@ -6124,6 +6127,11 @@ msgstr "[desconocida]"
msgid "[ undef ]"
msgstr "[no definida]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "nunca"
+
msgid "[marginal]"
msgstr "[ dudosa ]"
diff --git a/po/et.po b/po/et.po
index ccd011b..4ca6566 100644
--- a/po/et.po
+++ b/po/et.po
@@ -460,6 +460,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "viga teate saatmisel serverile `%s': %s\n"
#, fuzzy, c-format
+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"
@@ -477,10 +481,6 @@ msgid "directory '%s' created\n"
msgstr "%s: kataloog on loodud\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "HOIATUS: ebaturvalised õigused %s \"%s\"\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "trustdb: lugemine ebaõnnestus (n=%d): %s\n"
@@ -1956,13 +1956,13 @@ msgstr "muuda parooli"
msgid "export keys"
msgstr "ekspordi võtmed"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "ekspordi võtmed võtmeserverisse"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "impordi võtmed võtmeserverist"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "otsi võtmeid võtmeserverist"
msgid "update all keys from a keyserver"
@@ -2555,6 +2555,9 @@ msgstr "teata ajatemplite konfliktist ainult hoiatusega"
msgid "|FD|write status info to this FD"
msgstr "|FP|kirjuta olekuinfo sellesse failipidemesse"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Kasuta: gpgv [võtmed] [failid] (-h näitab abiinfot)"
@@ -4031,6 +4034,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Kasutaja ID numbriga %d puudub\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "ümardatud üles %u bitini\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4047,11 +4055,6 @@ msgstr "Millist võtmepikkust te soovite? (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "Soovitud võtmepikkus on %u bitti\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "ümardatud üles %u bitini\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5703,14 +5706,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "viga teate saatmisel serverile `%s': %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "ei leia avalikku võtit %08lX: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "viga `%s' lugemisel: %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5789,14 +5784,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5804,6 +5799,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "viga `%s' lugemisel: %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "viga parooli loomisel: %s\n"
@@ -5957,6 +5956,10 @@ msgstr "trustdb kontrolliks puudub vajadus\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "trustdb kontrolliks puudub vajadus\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "ei leia avalikku võtit %08lX: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "palun tehke --check-trustdb\n"
@@ -6034,6 +6037,10 @@ msgstr "tundmatu"
msgid "[ undef ]"
msgstr ""
+#, fuzzy
+msgid "[ never ]"
+msgstr "mitte kunagi"
+
msgid "[marginal]"
msgstr ""
diff --git a/po/fi.po b/po/fi.po
index 48b8b2e..1b93bce 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -477,6 +477,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "virhe lähettäessä kohteeseen \"%s\": %s\n"
#, fuzzy, c-format
+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"
@@ -494,10 +498,6 @@ msgid "directory '%s' created\n"
msgstr "%s: hakemisto luotu\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "VAROITUS: oikeudet kohteessa %s \"%s\" eivät ole turvallisia\"\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "trustdb: luku epäonnistui (n=%d): %s\n"
@@ -1971,13 +1971,13 @@ msgstr "muuta salasanaa"
msgid "export keys"
msgstr "vie avaimia"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "vie avaimia palvelimelle"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "nouda avaimia avainpalvelimelta"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "etsi avaimia avainpalvelimelta"
msgid "update all keys from a keyserver"
@@ -2571,6 +2571,9 @@ msgstr "käsittele aikaleimakonfliktit pelkkinä varoituksina"
msgid "|FD|write status info to this FD"
msgstr "|FD|tilatiedot kirjoitetaan FD:iin"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Käyttö: gpgv [valitsimet] [tiedostot] (-h näyttää ohjeen)"
@@ -4057,6 +4060,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Indeksillä %d ei löydy käyttäjätunnusta\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "pyöristetty %u bittiin\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4073,11 +4081,6 @@ msgstr "Minkä kokoisen avaimen haluat? (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "Halutun avaimen koko on %u bittiä\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "pyöristetty %u bittiin\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5761,14 +5764,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "virhe lähettäessä kohteeseen \"%s\": %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "julkista avainta %08lX ei löydy: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5847,14 +5842,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5862,6 +5857,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "virhe luotaessa salasanaa: %s\n"
@@ -6016,6 +6015,10 @@ msgstr "trustdb:n tarkistusta ei tarvita\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "trustdb:n tarkistusta ei tarvita\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "julkista avainta %08lX ei löydy: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "tee --check-trustdb, kiitos\n"
@@ -6093,6 +6096,10 @@ msgstr "tuntematon "
msgid "[ undef ]"
msgstr ""
+#, fuzzy
+msgid "[ never ]"
+msgstr "ei koskaan"
+
msgid "[marginal]"
msgstr ""
diff --git a/po/fr.po b/po/fr.po
index 33eea36..94ac188 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -461,6 +461,11 @@ msgstr "erreur de lecture du « nonce » de la socket\n"
msgid "error binding socket to '%s': %s\n"
msgstr "erreur de lien de la socket à « %s » : %s\n"
+#, fuzzy, c-format
+#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
+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"
@@ -477,11 +482,6 @@ msgstr "impossible de créer le répertoire « %s » : %s\n"
msgid "directory '%s' created\n"
msgstr "répertoire « %s » créé\n"
-#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-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 "stat() failed for '%s': %s\n"
msgstr "échec de stat() pour « %s » : %s\n"
@@ -1898,13 +1898,13 @@ msgstr "modifier une phrase secrète"
msgid "export keys"
msgstr "exporter les clefs"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "exporter les clefs vers un serveur de clefs"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importer les clefs d'un serveur de clefs"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "chercher les clefs avec un serveur de clefs"
msgid "update all keys from a keyserver"
@@ -2496,6 +2496,9 @@ msgstr "convertir les conflits de date en avertissements"
msgid "|FD|write status info to this FD"
msgstr "|FD|écrire l'état sur ce descripteur"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Utilisation : gpgv [options] [fichiers] (-h pour l'aide)"
@@ -3930,6 +3933,10 @@ msgid "No key with this keygrip\n"
msgstr "Pas de clef avec ce keygrip\n"
#, c-format
+msgid "rounded to %u bits\n"
+msgstr "arrondie à %u bits\n"
+
+#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "les clefs %s peuvent faire une taille comprise entre %u et %u bits.\n"
@@ -3945,10 +3952,6 @@ msgstr "Quelle taille de clef désirez-vous ? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "La taille demandée est %u bits\n"
-#, c-format
-msgid "rounded to %u bits\n"
-msgstr "arrondie à %u bits\n"
-
msgid "Please select which elliptic curve you want:\n"
msgstr "Sélectionnez le type de courbe elliptique désiré :\n"
@@ -5669,15 +5672,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "erreur d'envoi de données : %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "clef publique %s introuvable : %s\n"
-
-#, fuzzy, c-format
-#| msgid "error setting OCSP target: %s\n"
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "erreur de configuration de la cible OCSP : %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5758,14 +5752,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5773,6 +5767,11 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+#| msgid "error setting OCSP target: %s\n"
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "erreur de configuration de la cible OCSP : %s\n"
+
+#, fuzzy, c-format
#| msgid "error creating a pipe: %s\n"
msgid "error changing TOFU policy: %s\n"
msgstr "erreur de création d'un tube : %s\n"
@@ -5936,6 +5935,10 @@ msgstr ""
"inutile de mettre à jour la base de confiance avec le modèle de\n"
" confiance « %s »\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "clef publique %s introuvable : %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "veuillez faire un --check-trustdb\n"
@@ -6014,6 +6017,11 @@ msgstr "[ inconnue]"
msgid "[ undef ]"
msgstr "[indéfinie]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "jamais"
+
msgid "[marginal]"
msgstr "[marginale]"
diff --git a/po/gl.po b/po/gl.po
index 7ea0c18..915deaf 100644
--- a/po/gl.po
+++ b/po/gl.po
@@ -464,6 +464,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "erro ao enviar a `%s': %s\n"
#, fuzzy, c-format
+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"
@@ -481,10 +485,6 @@ msgid "directory '%s' created\n"
msgstr "%s: directorio creado\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "AVISO: permisos inseguros en %s \"%s\"\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "base de datos de confianza: fallou a lectura (n=%d): %s\n"
@@ -1964,13 +1964,13 @@ msgstr "cambia-lo contrasinal"
msgid "export keys"
msgstr "exportar chaves"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "exportar chaves a un servidor de chaves"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importar chaves dun servidor de chaves"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "buscar chaves nun servidor de chaves"
msgid "update all keys from a keyserver"
@@ -2565,6 +2565,9 @@ msgstr "converte-los conflictos de selo de data nun aviso"
msgid "|FD|write status info to this FD"
msgstr "|DF|escribi-la información de estado a este DF"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Uso: gpgv [opcións] [ficheiros] (-h para ve-la axuda)"
@@ -4068,6 +4071,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Non hai ID de usuario con índice %d\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "redondeado a %u bits\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4084,11 +4092,6 @@ msgstr "¿Qué tamaño de chave quere? (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "O tamaño de chave requerido son %u bits\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "redondeado a %u bits\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5767,14 +5770,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "erro ao enviar a `%s': %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "non se atopou a chave pública %08lX: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "erro lendo `%s': %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5853,14 +5848,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5868,6 +5863,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "erro lendo `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "erro ao crea-lo contrasinal: %s\n"
@@ -6022,6 +6021,10 @@ msgstr "non se precisa comproba-la base de datos de confianza\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "non se precisa comproba-la base de datos de confianza\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "non se atopou a chave pública %08lX: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "por favor, execute con --check-trustdb\n"
@@ -6099,6 +6102,10 @@ msgstr "descoñecido"
msgid "[ undef ]"
msgstr ""
+#, fuzzy
+msgid "[ never ]"
+msgstr "nunca "
+
msgid "[marginal]"
msgstr ""
diff --git a/po/hu.po b/po/hu.po
index 539aa00..a37b430 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -460,6 +460,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "Hiba %s-ra/-re küldéskor: %s\n"
#, fuzzy, c-format
+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"
@@ -477,10 +481,6 @@ msgid "directory '%s' created\n"
msgstr "%s: Könyvtárat létrehoztam.\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "FIGYELEM: nem biztonságos engedélyek: %s \"%s\"\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "Bizalmi adatbázis: olvasás sikertelen (n=%d): %s.\n"
@@ -1952,13 +1952,13 @@ msgstr "jelszóváltoztatás"
msgid "export keys"
msgstr "kulcsok exportálása"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "kulcsok exportálása kulcsszerverre"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "kulcsok importálása kulcsszerverrõl"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "kulcsok keresése kulcsszerveren"
msgid "update all keys from a keyserver"
@@ -2553,6 +2553,9 @@ msgstr "idõbélyeg-konfliktus esetén csak figyelmeztessen"
msgid "|FD|write status info to this FD"
msgstr "|ÁL|állapotinformációk írása ÁL állományleíróra"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Használat: gpgv [opciók] [fájlok] (-h a súgóhoz)"
@@ -4033,6 +4036,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Nincs %d indexû felhasználóazonosító!\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "Felkerekítve %u bitre.\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4049,11 +4057,6 @@ msgstr "Milyen kulcsméretet szeretne? (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "A kívánt kulcsméret %u bit.\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "Felkerekítve %u bitre.\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5734,14 +5737,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "Hiba %s-ra/-re küldéskor: %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "A(z) %08lX nyilvános kulcsot nem találom: %s.\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "Hiba \"%s\" olvasásakor: %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5820,14 +5815,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5835,6 +5830,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "Hiba \"%s\" olvasásakor: %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "Hiba a jelszó létrehozásakor: %s.\n"
@@ -5989,6 +5988,10 @@ msgstr "Nincs szükség a bizalmi adatbázis ellenõrzésére.\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "Nincs szükség a bizalmi adatbázis ellenõrzésére.\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "A(z) %08lX nyilvános kulcsot nem találom: %s.\n"
+
msgid "please do a --check-trustdb\n"
msgstr "Kérem, hajtson végre egy --check-trustdb parancsot!\n"
@@ -6066,6 +6069,10 @@ msgstr "Ismeretlen módú"
msgid "[ undef ]"
msgstr ""
+#, fuzzy
+msgid "[ never ]"
+msgstr "soha "
+
msgid "[marginal]"
msgstr ""
diff --git a/po/id.po b/po/id.po
index c017cd4..04a3e98 100644
--- a/po/id.po
+++ b/po/id.po
@@ -344,7 +344,7 @@ msgstr ""
#, fuzzy
msgid "use a log file for the server"
-msgstr "cari kunci di key server"
+msgstr "cari kunci di keyserver"
msgid "|PGM|use PGM as the PIN-Entry program"
msgstr ""
@@ -465,6 +465,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "kesalahan mengirim ke `%s': %s\n"
#, fuzzy, c-format
+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"
@@ -482,10 +486,6 @@ msgid "directory '%s' created\n"
msgstr "%s: direktori tercipta\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "Peringatan: permisi tidak aman pada %s \"%s\"\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "trustdb: read failed (n=%d): %s\n"
@@ -1955,14 +1955,14 @@ msgstr "ubah passphrase"
msgid "export keys"
msgstr "ekspor kunci"
-msgid "export keys to a key server"
-msgstr "ekspor kunci ke key server"
+msgid "export keys to a keyserver"
+msgstr "ekspor kunci ke keyserver"
-msgid "import keys from a key server"
-msgstr "impor kunci dari key server"
+msgid "import keys from a keyserver"
+msgstr "impor kunci dari keyserver"
-msgid "search for keys on a key server"
-msgstr "cari kunci di key server"
+msgid "search for keys on a keyserver"
+msgstr "cari kunci di keyserver"
msgid "update all keys from a keyserver"
msgstr "update semua kunci dari keyserver"
@@ -2558,6 +2558,9 @@ msgstr "buat timestamp konflik hanya sebagai peringatan"
msgid "|FD|write status info to this FD"
msgstr "|FD|tulis info status ke FD ini"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Pemakaian: gpgv [opsi] [file] (-h untuk bantuan)"
@@ -4042,6 +4045,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Tidak ada ID user dengan index %d\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "dibulatkan hingga %u bit\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4058,11 +4066,6 @@ msgstr "Keysize yang anda inginkan? (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "Keysize yang diminta adalah %u bit\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "dibulatkan hingga %u bit\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5724,14 +5727,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "kesalahan mengirim ke `%s': %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "kunci publik %08lX tidak ditemukan: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "kesalahan membaca `%s': %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5810,14 +5805,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5825,6 +5820,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "kesalahan membaca `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "kesalahan penciptaan passphrase: %s\n"
@@ -5978,6 +5977,10 @@ msgstr "tidak perlu memeriksa trustdb\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "tidak perlu memeriksa trustdb\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "kunci publik %08lX tidak ditemukan: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "lakukanlah --check-trustdb\n"
@@ -6055,6 +6058,10 @@ msgstr "tidak dikenal"
msgid "[ undef ]"
msgstr ""
+#, fuzzy
+msgid "[ never ]"
+msgstr "tidak pernah..."
+
msgid "[marginal]"
msgstr ""
diff --git a/po/it.po b/po/it.po
index 6b30fbd..86317d9 100644
--- a/po/it.po
+++ b/po/it.po
@@ -339,7 +339,7 @@ msgstr ""
#, fuzzy
msgid "use a log file for the server"
-msgstr "cerca delle chiavi su un key server"
+msgstr "cerca delle chiavi su un keyserver"
msgid "|PGM|use PGM as the PIN-Entry program"
msgstr ""
@@ -460,6 +460,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "errore leggendo `%s': %s\n"
#, fuzzy, c-format
+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"
@@ -477,10 +481,6 @@ msgid "directory '%s' created\n"
msgstr "%s: directory creata\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "ATTENZIONE: i permessi \"%s\" di %s sono insicuri\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "trustdb: read fallita (n=%d): %s\n"
@@ -1962,17 +1962,17 @@ msgstr "cambia la passphrase"
msgid "export keys"
msgstr "esporta delle chiavi"
-msgid "export keys to a key server"
-msgstr "esporta le chiavi a un key server"
+msgid "export keys to a keyserver"
+msgstr "esporta le chiavi a un keyserver"
-msgid "import keys from a key server"
-msgstr "importa le chiavi da un key server"
+msgid "import keys from a keyserver"
+msgstr "importa le chiavi da un keyserver"
-msgid "search for keys on a key server"
-msgstr "cerca delle chiavi su un key server"
+msgid "search for keys on a keyserver"
+msgstr "cerca delle chiavi su un keyserver"
msgid "update all keys from a keyserver"
-msgstr "aggiorna tutte le chiavi da un key server"
+msgstr "aggiorna tutte le chiavi da un keyserver"
msgid "import/merge keys"
msgstr "importa/aggiungi delle chiavi"
@@ -2564,6 +2564,9 @@ msgstr "segnala i conflitti di data solo con un avvertimento"
msgid "|FD|write status info to this FD"
msgstr "|FD|scrivi le informazioni di stato sul FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Uso: gpgv [opzioni] [file] (-h per l'aiuto)"
@@ -4057,6 +4060,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Nessun user ID con l'indice %d\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "arrotondate a %u bit\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4073,11 +4081,6 @@ msgstr "Di che dimensioni vuoi la chiave? (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "La dimensione richiesta della chiave è %u bit\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "arrotondate a %u bit\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5765,14 +5768,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "errore leggendo `%s': %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "chiave pubblica %08lX non trovata: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "errore leggendo `%s': %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5851,14 +5846,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5866,6 +5861,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "errore leggendo `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "errore nella creazione della passhprase: %s\n"
@@ -6020,6 +6019,10 @@ msgstr "non è necessario un controllo del trustdb\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "non è necessario un controllo del trustdb\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "chiave pubblica %08lX non trovata: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "per favore usa --check-trustdb\n"
@@ -6097,6 +6100,10 @@ msgstr "sconosciuto"
msgid "[ undef ]"
msgstr ""
+#, fuzzy
+msgid "[ never ]"
+msgstr "mai "
+
msgid "[marginal]"
msgstr ""
diff --git a/po/ja.po b/po/ja.po
index e138ede..7f284e1 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -4,13 +4,13 @@
# IIDA Yosiaki <iida@gnu.org>, 1999, 2000, 2002, 2003, 2004.
# Yoshihiro Kajiki <kajiki@ylug.org>, 1999.
# Takashi P.KATOH, 2002.
-# NIIBE Yutaka <gniibe@fsij.org>, 2013, 2014, 2015.
+# NIIBE Yutaka <gniibe@fsij.org>, 2013, 2014, 2015, 2016.
#
msgid ""
msgstr ""
-"Project-Id-Version: gnupg 2.1.10\n"
+"Project-Id-Version: gnupg 2.1.12\n"
"Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2015-12-21 21:21+0900\n"
+"PO-Revision-Date: 2016-06-07 14:12+0900\n"
"Last-Translator: NIIBE Yutaka <gniibe@fsij.org>\n"
"Language-Team: none\n"
"Language: ja\n"
@@ -361,10 +361,8 @@ msgstr "クライアントãŒéµã«\"trusted\"マークをã¤ã‘ã‚‹ã“ã¨ã‚’èªã
msgid "allow presetting passphrase"
msgstr "パスフレーズã®äº‹å‰è¨­å®šã‚’èªã‚ã‚‹"
-#, fuzzy
-#| msgid "allow caller to override the pinentry"
msgid "disallow caller to override the pinentry"
-msgstr "pinentryより優先ã—ã¦ãƒ‘スフレーズ入力をèªã‚ã‚‹"
+msgstr "pinentryより優先ã—ã¦ãƒ‘スフレーズ入力をèªã‚ãªã„"
msgid "allow passphrase to be prompted through Emacs"
msgstr "Emacsを通ã˜ã¦ãƒ‘スフレーズを催促ã™ã‚‹ã“ã¨ã‚’èªã‚ã‚‹"
@@ -434,6 +432,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "'%s'ã§ã‚½ã‚±ãƒƒãƒˆã®ãƒã‚¤ãƒ³ãƒ‰ã®ã‚¨ãƒ©ãƒ¼: %s\n"
#, c-format
+msgid "can't set permissions of '%s': %s\n"
+msgstr "'%s'ã®è¨±å¯ãŒè¨­å®šã§ãã¾ã›ã‚“: %s\n"
+
+#, c-format
msgid "listen() failed: %s\n"
msgstr "listen() ã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n"
@@ -449,11 +451,6 @@ msgstr "ディレクトリ'%s'ãŒä½œæˆã§ãã¾ã›ã‚“: %s\n"
msgid "directory '%s' created\n"
msgstr "ディレクトリ'%s'ãŒä½œæˆã•ã‚Œã¾ã—ãŸ\n"
-#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgid "can't set permissions of '%s': %s\n"
-msgstr "警告: '%s'ã®å®‰å…¨ã§ãªã„è¨±å¯ \"%s\"\n"
-
#, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "'%s'ã§stat()ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s\n"
@@ -709,10 +706,9 @@ msgstr "パイプã®ã‚¹ãƒˆãƒªãƒ¼ãƒ ä½œæˆã‚¨ãƒ©ãƒ¼: %s\n"
msgid "error forking process: %s\n"
msgstr "プロセスforkエラー: %s\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 "プロセス%dã®çµ‚了待ã¡ãŒå¤±æ•—: %s\n"
+msgstr "プロセスã®çµ‚了待ã¡ãŒå¤±æ•—: %s\n"
#, c-format
msgid "error running '%s': probably not installed\n"
@@ -750,10 +746,9 @@ msgstr "ユーザã«ã‚ˆã‚‹å–消ã—\n"
msgid "problem with the agent\n"
msgstr "エージェントã«éšœå®³\n"
-#, fuzzy, c-format
-#| msgid "problem with the agent: %s\n"
+#, c-format
msgid "problem with the agent (unexpected response \"%s\")\n"
-msgstr "エージェントã«å•é¡Œ: %s\n"
+msgstr "エージェントã«å•é¡Œ (予期ã—ãªã„応答 \"%s\")\n"
#, c-format
msgid "can't disable core dumps: %s\n"
@@ -1154,10 +1149,9 @@ msgstr ""
"外装ã®ä¸­ã«quoted printable文字ãŒã‚ã‚Šã¾ã™ã€‚ãŠãらããƒã‚°ã®ã‚ã‚‹MTAãŒä½¿ã‚ã‚ŒãŸã®ã§"
"ã—ょã†\n"
-#, fuzzy, c-format
-#| msgid "not human readable"
+#, c-format
msgid "[ not human readable (%zu bytes: %s%s) ]"
-msgstr "人ã«ã¯èª­ã‚ã¾ã›ã‚“"
+msgstr "[ 人ã«ã¯èª­ã‚ã¾ã›ã‚“ (%zuãƒã‚¤ãƒˆ: %s%s) ]"
msgid ""
"a notation name must have only printable characters or spaces, and end with "
@@ -1174,18 +1168,11 @@ msgstr "ユーザ注釈åã¯ã€ä¸€ã¤ã‚ˆã‚Šå¤§ãã„'@'文字をå«ã‚“ã§ã¯ãª
msgid "a notation value must not use any control characters\n"
msgstr "注釈åã®å€¤ã«åˆ¶å¾¡æ–‡å­—を使ã£ã¦ã¯ã„ã‘ã¾ã›ã‚“\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 "ユーザ注釈åã¯ã€ä¸€ã¤ã‚ˆã‚Šå¤§ãã„'@'文字をå«ã‚“ã§ã¯ãªã‚Šã¾ã›ã‚“\n"
+msgstr "ユーザ注釈åã¯ã€'='ã®æ–‡å­—ã‚’å«ã‚“ã§ã¯ãªã‚Šã¾ã›ã‚“\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 ""
-"注釈åã«ã¯å°å­—å¯èƒ½ãªæ–‡å­—ã‹ç©ºç™½ã®ã¿ã‚’使ã„ã€'='ã§çµ‚ã‚らãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“\n"
+msgstr "注釈åã«ã¯å°å­—å¯èƒ½ãªæ–‡å­—ã‹ç©ºç™½ã®ã¿ã‚’使ã‚ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“\n"
msgid "WARNING: invalid notation data found\n"
msgstr "*警告*: 無効ãªæ³¨é‡ˆãƒ‡ãƒ¼ã‚¿ã‚’発見\n"
@@ -1197,19 +1184,17 @@ msgstr "プロキシ%sã®ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã¸ã®å•ã„åˆã‚ã›ãŒå¤±æ•—ã—ã¾ã
msgid "Enter passphrase: "
msgstr "パスフレーズを入力: "
-#, fuzzy, c-format
-#| msgid "error creating keyring '%s': %s\n"
+#, c-format
msgid "error getting version from '%s': %s\n"
-msgstr "éµãƒªãƒ³ã‚°'%s'ã®ä½œæˆã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "%s'ã‹ã‚‰ãƒãƒ¼ã‚¸ãƒ§ãƒ³å–得エラー: %s\n"
#, c-format
msgid "server '%s' is older than us (%s < %s)"
-msgstr ""
+msgstr "サーãƒ'%s'ã¯ã“ã¡ã‚‰ã‚ˆã‚Šå¤ã„ã§ã™(%s < %s)"
-#, fuzzy, c-format
-#| msgid "WARNING: %s overrides %s\n"
+#, c-format
msgid "WARNING: %s\n"
-msgstr "*警告*: %sã¯%sより優先\n"
+msgstr "*警告*: %s\n"
#, c-format
msgid "OpenPGP card not available: %s\n"
@@ -1692,24 +1677,17 @@ msgstr "[ユーザIDãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“]"
msgid "(check argument of option '%s')\n"
msgstr "(オプション'%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 ""
-"警告: 値'%s'(オプション'%s'ã«å¯¾ã™ã‚‹)ã¯é•·ã„éµIDã‹ãƒ•ã‚£ãƒ³ã‚¬ãƒ¼ãƒ—リントã§ã‚ã‚‹ã¹ã"
-"ã§ã™ã€‚\n"
+msgstr "警告: '%s'ã¯é•·ã„éµIDã‹ãƒ•ã‚£ãƒ³ã‚¬ãƒ¼ãƒ—リントã§ã‚ã‚‹ã¹ãã§ã™ã€‚\n"
-#, fuzzy, c-format
-#| msgid "error closing %s: %s\n"
+#, c-format
msgid "error looking up: %s\n"
-msgstr "'%s'ã§ã‚¯ãƒ­ãƒ¼ã‚ºã®ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "検索ã®ã‚¨ãƒ©ãƒ¼: %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 "éµãƒªãƒ³ã‚°æŽ¢ç´¢ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "警告: %sã¯éµãƒªãƒ³ã‚°ã«%d回出ç¾ã—ã¾ã™\n"
#, c-format
msgid "automatically retrieved '%s' via %s\n"
@@ -1726,19 +1704,17 @@ msgstr "フィンガープリントãŒã‚ã‚Šã¾ã›ã‚“"
msgid "secret key \"%s\" not found: %s\n"
msgstr "秘密éµ\"%s\"ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %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 "デフォルトã®ç§˜å¯†éµã¨ã—ã¦\"%s\"を用ã„ã¾ã™\n"
+msgstr "警告: デフォルトã®ç§˜å¯†éµã¨ã—㦠'%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 "デフォルトã®ç§˜å¯†éµã¨ã—ã¦\"%s\"を用ã„ã¾ã™\n"
+msgstr "デフォルトã®ç½²å用ã®ç§˜å¯†éµã¨ã—ã¦\"%s\"を用ã„ã¾ã™\n"
#, c-format
msgid "all values passed to '%s' ignored\n"
-msgstr ""
+msgstr "'%s'ã«æ¸¡ã•ã‚ŒãŸã™ã¹ã¦ã®å€¤ã¯ç„¡è¦–ã•ã‚Œã¾ã—ãŸ\n"
#, c-format
msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n"
@@ -1826,13 +1802,13 @@ msgstr "パスフレーズã®å¤‰æ›´"
msgid "export keys"
msgstr "éµã‚’エクスãƒãƒ¼ãƒˆã™ã‚‹"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "éµã‚µãƒ¼ãƒã«éµã‚’エクスãƒãƒ¼ãƒˆã™ã‚‹"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "éµã‚µãƒ¼ãƒã‹ã‚‰éµã‚’インãƒãƒ¼ãƒˆã™ã‚‹"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "éµã‚µãƒ¼ãƒã®éµã‚’検索ã™ã‚‹"
msgid "update all keys from a keyserver"
@@ -1859,10 +1835,8 @@ msgstr "メッセージ・ダイジェストを表示"
msgid "run in server mode"
msgstr "サーãƒãƒ»ãƒ¢ãƒ¼ãƒ‰ã§å®Ÿè¡Œ"
-#, 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 "|VALUE|TOFUãƒãƒªã‚·ãƒ¼ã‚’éµã«è¨­å®šã™ã‚‹(good, unknown, bad, ask, auto)"
+msgstr "|VALUE|TOFUãƒãƒªã‚·ãƒ¼ã‚’éµã«è¨­å®šã™ã‚‹"
msgid "create ascii armored output"
msgstr "ASCIIå½¢å¼ã®å¤–装を作æˆ"
@@ -2333,10 +2307,9 @@ msgstr "éµã‚µãƒ¼ãƒã‹ã‚‰ã®å—ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n"
msgid "key export failed: %s\n"
msgstr "éµã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n"
-#, fuzzy, c-format
-#| msgid "key export failed: %s\n"
+#, c-format
msgid "export as ssh key failed: %s\n"
-msgstr "éµã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n"
+msgstr "sshéµã¨ã—ã¦ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n"
#, c-format
msgid "keyserver search failed: %s\n"
@@ -2390,6 +2363,9 @@ msgstr "日時ã®çŸ›ç›¾ã‚’警告ã ã‘ã«ã—ã¾ã™"
msgid "|FD|write status info to this FD"
msgstr "|FD|ã“ã®FDã«ã‚¹ãƒ†ã‚¤ã‚¿ã‚¹æƒ…報を書ã出ã™"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr "|ALGO|ALGOã§ä½œæˆã•ã‚ŒãŸç½²åを拒絶ã™ã‚‹"
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "使ã„æ–¹: gpgv [オプション] [ファイル] (ヘルプ㯠-h)"
@@ -2811,56 +2787,50 @@ msgstr "[失効]"
msgid "[self-signature]"
msgstr "[自己署å]"
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
+#, c-format
msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "éµ%s: サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„公開éµã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã§ã™\n"
+msgstr "サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„公開éµã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ (%d)ã®ç½²åã¯ç¢ºèªã§ãã¾ã›ã‚“: %s.\n"
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
+#, c-format
msgid ""
"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "カードã¯ãƒ€ã‚¤ã‚¸ã‚§ã‚¹ãƒˆãƒ»ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ  %s をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“\n"
+msgstr ""
+"サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„メッセージ・ダイジェスト(%d)ã®ç½²åã¯ç¢ºèªã§ãã¾ã›ã‚“: %s.\n"
-#, fuzzy
-#| msgid "Good signature from"
msgid " (reordered signatures follow)"
-msgstr "æ­£ã—ã„ç½²å"
+msgstr "(順番を変ãˆãŸç½²åãŒç¶šãã¾ã™)"
-#, fuzzy, c-format
-#| msgid "key %s: %s\n"
+#, c-format
msgid "key %s:\n"
-msgstr "éµ %s: %s\n"
+msgstr "éµ %s:\n"
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
+#, c-format
msgid "%d duplicate signature removed\n"
msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "ユーザID \"%s\": %d ã®ç½²åãŒé™¤åŽ»ã•ã‚Œã¾ã—ãŸ\n"
+msgstr[0] "%d個ã®é‡è¤‡ã—ãŸç½²åãŒé™¤åŽ»ã•ã‚Œã¾ã—ãŸ\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個ã®ç½²åを検査ã—ã¾ã›ã‚“\n"
+msgstr[0] "éµãŒãªã„ãŸã‚%d個ã®ç½²åã¯æ¤œæŸ»ã—ã¾ã›ã‚“\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個\n"
+msgstr[0] "%d個ã®ä¸æ­£ãªç½²å\n"
-#, fuzzy, c-format
-#| msgid "Good signature from"
+#, c-format
msgid "%d signature reordered\n"
msgid_plural "%d signatures reordered\n"
-msgstr[0] "æ­£ã—ã„ç½²å"
+msgstr[0] "%d個ã®æ­£ã—ã„ç½²å\n"
#, c-format
msgid ""
"Warning: errors found and only checked self-signatures, run '%s' to check "
"all signatures.\n"
msgstr ""
+"警告: エラーãŒã‚ã‚Šã€è‡ªå·±ç½²åã ã‘確èªã—ã¾ã—ãŸã€‚'%s'を実行ã—ã¦ã™ã¹ã¦ã®ç½²åを確"
+"èªãã ã•ã„。\n"
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3296,10 +3266,9 @@ msgstr "\"%s\"ã¯ãƒ•ã‚£ãƒ³ã‚¬ãƒ¼ãƒ—リントã§ã¯ã‚ã‚Šã¾ã›ã‚“\n"
msgid "\"%s\" is not the primary fingerprint\n"
msgstr "\"%s\" ã¯ãƒ—ライマリ・フィンガープリントã§ã¯ã‚ã‚Šã¾ã›ã‚“\n"
-#, fuzzy, c-format
-#| msgid "read error in '%s': %s\n"
+#, c-format
msgid "Invalid user ID '%s': %s\n"
-msgstr "'%s'ã§èª­ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "無効ãªãƒ¦ãƒ¼ã‚¶ID '%s': %s\n"
msgid "No matching user IDs."
msgstr "マッãƒã™ã‚‹ãƒ¦ãƒ¼ã‚¶IDã¯ã‚ã‚Šã¾ã›ã‚“。"
@@ -3426,8 +3395,7 @@ msgstr "ã“ã®ä¸æ˜Žã®ç½²åを削除ã—ã¾ã™ã‹? (y/N/q)"
msgid "Really delete this self-signature? (y/N)"
msgstr "ã“ã®è‡ªå·±ç½²åを本当ã«å‰Šé™¤ã—ã¾ã™ã‹? (y/N)"
-#, fuzzy, c-format
-#| msgid "Deleted %d signature.\n"
+#, c-format
msgid "Deleted %d signature.\n"
msgid_plural "Deleted %d signatures.\n"
msgstr[0] "%d個ã®ç½²åを削除ã—ã¾ã—ãŸã€‚\n"
@@ -3442,8 +3410,7 @@ msgstr "無効"
msgid "User ID \"%s\" compacted: %s\n"
msgstr "ユーザID \"%s\" ã¯ã€ã‚³ãƒ³ãƒ‘クトã«ãªã‚Šã¾ã—ãŸ: %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] "ユーザID \"%s\": %d ã®ç½²åãŒé™¤åŽ»ã•ã‚Œã¾ã—ãŸ\n"
@@ -3764,6 +3731,10 @@ msgid "No key with this keygrip\n"
msgstr "ã“ã®keygripã®éµã¯ã‚ã‚Šã¾ã›ã‚“\n"
#, c-format
+msgid "rounded to %u bits\n"
+msgstr "%uビットã«åˆ‡ã‚Šä¸Šã’ã¾ã™\n"
+
+#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "%s éµã¯ %u ã‹ã‚‰ %u ビットã®é•·ã•ã§å¯èƒ½ã§ã™ã€‚\n"
@@ -3779,10 +3750,6 @@ msgstr "éµé•·ã¯? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "è¦æ±‚ã•ã‚ŒãŸéµé•·ã¯%uビット\n"
-#, c-format
-msgid "rounded to %u bits\n"
-msgstr "%uビットã«åˆ‡ã‚Šä¸Šã’ã¾ã™\n"
-
msgid "Please select which elliptic curve you want:\n"
msgstr "ã”希望ã®æ¥•å††æ›²ç·šã‚’é¸æŠžã—ã¦ãã ã•ã„:\n"
@@ -4066,23 +4033,20 @@ msgstr "クリティカルãªç½²å注釈: "
msgid "Signature notation: "
msgstr "ç½²å注釈: "
-#, fuzzy, c-format
-#| msgid "%d good signatures\n"
+#, c-format
msgid "%d good signature\n"
msgid_plural "%d good signatures\n"
msgstr[0] "æ­£ã—ã„ç½²å%d個\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個ã®ç½²åを検査ã—ã¾ã›ã‚“\n"
+msgstr[0] "エラーã®ãŸã‚%d個ã®ç½²åを検査ã—ã¾ã›ã‚“\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] "*警告*: %lu éµãŒãã®å¤§ãã•ã®ãŸã‚スキップã•ã‚Œã¾ã—ãŸ\n"
+msgstr[0] "*警告*: %lu個ã®éµãŒãã®å¤§ãã•ã®ãŸã‚スキップã•ã‚Œã¾ã—ãŸ\n"
msgid "Keyring"
msgstr "éµãƒªãƒ³ã‚°"
@@ -4115,23 +4079,20 @@ msgstr " ã‚«ãƒ¼ãƒ‰ã‚·ãƒªã‚¢ãƒ«ç•ªå· ="
msgid "caching keyring '%s'\n"
msgstr "éµãƒªãƒ³ã‚°'%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個ã®éµã¾ã§ã‚­ãƒ£ãƒƒã‚·ãƒ¥æ¸ˆ (%lu個ã®ç½²å)\n"
+msgstr[0] "ã“ã‚Œã¾ã§%lu個ã®éµã‚’キャッシュã—ã¾ã—㟠(%lu個ã®ç½²å)\n"
-#, fuzzy, c-format
-#| msgid "flush the cache"
+#, c-format
msgid "%lu key cached"
msgid_plural "%lu keys cached"
-msgstr[0] "キャッシュをフラッシュã—ã¾ã™"
+msgstr[0] "%lu個ã®éµã‚’キャッシュã—ã¾ã—ãŸ"
-#, fuzzy, c-format
-#| msgid "1 bad signature\n"
+#, c-format
msgid " (%lu signature)\n"
msgid_plural " (%lu signatures)\n"
-msgstr[0] "ä¸æ­£ãªç½²å1個\n"
+msgstr[0] " (%lu個ã®ä¸æ­£ãªç½²å)\n"
#, c-format
msgid "%s: keyring created\n"
@@ -4172,8 +4133,7 @@ msgstr "無効ãªéµã‚µãƒ¼ãƒãƒ»ãƒ—ロトコルã§ã™ (us %d!=handler %d)\n"
msgid "\"%s\" not a key ID: skipping\n"
msgstr "\"%s\"éµIDã§ã¯ã‚ã‚Šã¾ã›ã‚“: スキップã—ã¾ã™\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] "%d本ã®éµã‚’%sã‹ã‚‰æ›´æ–°\n"
@@ -4200,10 +4160,8 @@ msgstr "éµ%sã‚’%sã‹ã‚‰ã‚µãƒ¼ãƒ%sã«è¦æ±‚\n"
msgid "requesting key %s from %s\n"
msgstr "éµ%sã‚’%sã«è¦æ±‚\n"
-#, fuzzy
-#| msgid "invalid keyserver options\n"
msgid "no keyserver known\n"
-msgstr "無効ãªéµã‚µãƒ¼ãƒãƒ»ã‚ªãƒ—ションã§ã™\n"
+msgstr "éµã‚µãƒ¼ãƒãŒã‚ã‹ã‚Šã¾ã›ã‚“\n"
#, c-format
msgid "sending key %s to %s\n"
@@ -4414,18 +4372,16 @@ msgstr "*警告*: ダイジェスト・アルゴリズム %s ã¯å»ƒæ­¢ã•ã‚Œã¦ã
msgid "Note: signatures using the %s algorithm are rejected\n"
msgstr "注æ„: アルゴリズム %s を用ã„ãŸç½²åã¯æ‹’å¦ã•ã‚Œã¾ã—ãŸ\n"
-#, fuzzy, c-format
-#| msgid "%s:%u: read error: %s\n"
+#, c-format
msgid "(reported error: %s)\n"
-msgstr "%s:%u: 読ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "(報告ã•ã‚ŒãŸã‚¨ãƒ©ãƒ¼: %s)\n"
-#, fuzzy, c-format
-#| msgid "read error in '%s': %s\n"
+#, c-format
msgid "(reported error: %s <%s>)\n"
-msgstr "'%s'ã§èª­ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "(報告ã•ã‚ŒãŸã‚¨ãƒ©ãƒ¼: %s <%s>)\n"
msgid "(further info: "
-msgstr ""
+msgstr "(より詳細ãªæƒ…å ±: "
#, c-format
msgid "%s:%d: deprecated option \"%s\"\n"
@@ -4814,10 +4770,9 @@ msgstr "%s: スキップ: 公開éµã¯ä½¿ç”¨ç¦æ­¢ã§ã™\n"
msgid "%s: skipped: public key already present\n"
msgstr "%s: スキップ: 公開éµã¯ã‚‚ã†ã‚ã‚Šã¾ã™\n"
-#, fuzzy, c-format
-#| msgid "can't connect to '%s': %s\n"
+#, c-format
msgid "can't encrypt to '%s'\n"
-msgstr "'%s'ã¸æŽ¥ç¶šã§ãã¾ã›ã‚“: %s\n"
+msgstr "'%s'ã«æš—å·åŒ–ã§ãã¾ã›ã‚“\n"
#, c-format
msgid "option '%s' given, but no valid default keys given\n"
@@ -4959,13 +4914,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 ""
+"失効証明書㯠\"殺ã™ã‚¹ã‚¤ãƒƒãƒ\" ã®ã‚ˆã†ãªã‚‚ã®ã§ã€éµãŒãれ以上使ãˆãªã„\n"
+"よã†ã«å…¬ã«å®£è¨€ã™ã‚‹ã‚‚ã®ã§ã™ã€‚一度発行ã•ã‚Œã‚‹ã¨ã€ãã®ã‚ˆã†ãªå¤±åŠ¹è¨¼æ˜Žæ›¸ã¯\n"
+"撤回ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
-#, 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"
@@ -4975,26 +4927,21 @@ msgid ""
msgstr ""
"秘密éµã®ã‚³ãƒ³ãƒ—ロマイズや紛失ã®å ´åˆã€ã“れを使ã£ã¦ã“ã®éµã‚’失効ã•ã›ã¾ã™ã€‚\n"
"ã—ã‹ã—ã€ç§˜å¯†éµãŒã¾ã ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ã§ã‚ã‚‹å ´åˆã€æ–°ã—ã„失効証明書を生æˆã—ã€\n"
-"失効ã®ç†ç”±ã‚’ã¤ã‘ã‚‹æ–¹ãŒã‚ˆã„ã§ã—ょã†ã€‚"
+"失効ã®ç†ç”±ã‚’ã¤ã‘ã‚‹æ–¹ãŒã‚ˆã„ã§ã—ょã†ã€‚詳細ã¯ã€GnuPGマニュアルã®gpgコマンド \"--"
+"gen-revoke\"ã®è¨˜è¿°ã‚’ã”覧ãã ã•ã„。"
-#, 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 ""
-"ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’誤ã£ã¦ä½¿ã†ã®ã‚’é¿ã‘ã‚‹ãŸã‚ã€ä»¥ä¸‹ã§ã¯ã‚³ãƒ­ãƒ³ãŒ5ã¤ã®ãƒ€ãƒƒã‚·ãƒ¥ã®å‰ã«æŒ¿"
-"å…¥ã•ã‚Œã¾ã™ã€‚\n"
-"ã“ã®å¤±åŠ¹è¨¼æ˜Žæ›¸ã‚’使ã†å‰ã«ã¯ãƒ†ã‚¯ã‚¹ãƒˆãƒ»ã‚¨ãƒ‡ã‚£ã‚¿ã§ã“ã®ã‚³ãƒ­ãƒ³ã‚’削除ã—ã¦ãã ã•ã„。"
+"ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’誤ã£ã¦ä½¿ã†ã®ã‚’é¿ã‘ã‚‹ãŸã‚ã€ä»¥ä¸‹ã§ã¯ã‚³ãƒ­ãƒ³ãŒ5ã¤ã®ãƒ€ãƒƒã‚·ãƒ¥\n"
+"ã®å‰ã«æŒ¿å…¥ã•ã‚Œã¾ã™ã€‚ã“ã®å¤±åŠ¹è¨¼æ˜Žæ›¸ã‚’インãƒãƒ¼ãƒˆã—ã¦å…¬é–‹ã™ã‚‹å‰ã«ã€ãƒ†ã‚¯\n"
+"スト・エディタã§ã“ã®ã‚³ãƒ­ãƒ³ã‚’削除ã—ã¦ãã ã•ã„。"
-#, fuzzy, c-format
-#| msgid "Revocation certificate created.\n"
+#, c-format
msgid "revocation certificate stored as '%s.rev'\n"
-msgstr "失効証明書を作æˆã€‚\n"
+msgstr "失効証明書を '%s.rev' ã«ä¿ç®¡ã—ã¾ã—ãŸã€‚\n"
#, c-format
msgid "secret key \"%s\" not found\n"
@@ -5088,34 +5035,28 @@ msgstr "詳細ã¯%sã‚’ã”覧ãã ã•ã„\n"
msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
msgstr "*警告*: 無効ãªç›¸äº’証明ãŒã€ç½²å副éµ%sã«ã‚ã‚Šã¾ã™\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] "公開éµ%sã¯ã€ç½²åよりも%lu秒新ã—ã„ã‚‚ã®ã§ã™\n"
+msgstr[0] "公開éµ%sã¯ã€ç½²åよりも%lu秒ã€æ–°ã—ã„ã‚‚ã®ã§ã™\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] "公開éµ%sã¯ã€ç½²åよりも%lu秒新ã—ã„ã‚‚ã®ã§ã™\n"
+msgstr[0] "公開éµ%sã¯ã€ç½²åよりも%luæ—¥ã€æ–°ã—ã„ã‚‚ã®ã§ã™\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] "éµ%sã¯%lu秒未æ¥ã«ã§ãã¾ã—㟠(時間歪曲ã‹æ™‚計ã®éšœå®³ã§ã—ょã†)\n"
+msgstr[0] "éµ%sã¯%lu秒ã€æœªæ¥ã«ã§ãã¾ã—㟠(時間歪曲ã‹æ™‚計ã®éšœå®³ã§ã—ょã†)\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] "éµ%sã¯%lu秒未æ¥ã«ã§ãã¾ã—㟠(時間歪曲ã‹æ™‚計ã®éšœå®³ã§ã—ょã†)\n"
+msgstr[0] "éµ%sã¯%luæ—¥ã€æœªæ¥ã«ã§ãã¾ã—㟠(時間歪曲ã‹æ™‚計ã®éšœå®³ã§ã—ょã†)\n"
#, c-format
msgid "Note: signature key %s expired %s\n"
@@ -5334,204 +5275,192 @@ msgstr "%d文字以上ã®é•·ã•ã®ãƒ†ã‚­ã‚¹ãƒˆè¡Œã¯ã€å–り扱ãˆã¾ã›ã‚“\n"
msgid "input line longer than %d characters\n"
msgstr "入力行ã®é•·ã•ãŒ%d文字を超ãˆã¦ã„ã¾ã™\n"
-#, fuzzy, c-format
-#| msgid "error sending standard options: %s\n"
+#, c-format
msgid "error beginning transaction on TOFU database: %s\n"
-msgstr "標準オプションをé€ä¿¡ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "TOFUデータベースã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³é–‹å§‹ã‚¨ãƒ©ãƒ¼: %s\n"
#, c-format
msgid "error committing transaction on TOFU database: %s\n"
-msgstr ""
+msgstr "TOFUデータベースã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚³ãƒŸãƒƒãƒˆã®ã‚¨ãƒ©ãƒ¼: %s\n"
#, c-format
msgid "error rolling back transaction on TOFU database: %s\n"
-msgstr ""
+msgstr "TOFUデータベースã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ã®ã‚¨ãƒ©ãƒ¼: %s\n"
-#, fuzzy, c-format
-#| msgid "unsupported algorithm: %s"
+#, c-format
msgid "unsupported TOFU database version: %s\n"
-msgstr "サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„アルゴリズム: %s"
+msgstr "サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„TOFUデータベースãƒãƒ¼ã‚¸ãƒ§ãƒ³: %s\n"
-#, fuzzy, c-format
-#| msgid "error sending data: %s\n"
+#, c-format
msgid "error reading TOFU database: %s\n"
-msgstr "データé€ä¿¡ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "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 "base64エンコーディングã®æ›¸ãè¾¼ã¿ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "TOFUデータベースã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³åˆ¤å®šã‚¨ãƒ©ãƒ¼: %s\n"
-#, fuzzy, c-format
-#| msgid "error initializing reader object: %s\n"
+#, c-format
msgid "error initializing TOFU database: %s\n"
-msgstr "リーダ・オブジェクトã®åˆæœŸåŒ–エラー: %s\n"
+msgstr "TOFUデータベースã®åˆæœŸåŒ–エラー: %s\n"
-#, fuzzy, c-format
-#| msgid "error opening '%s': %s\n"
+#, c-format
msgid "error opening TOFU database '%s': %s\n"
-msgstr "'%s'ã‚’é–‹ãéš›ã€ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "TOFUデータベースã®ã‚ªãƒ¼ãƒ—ンã§ã‚¨ãƒ©ãƒ¼ '%s': %s\n"
msgid "Warning: Home directory contains both tofu.db and tofu.d.\n"
-msgstr ""
+msgstr "警告: tofu.db 㨠tofu.d ã®ä¸¡æ–¹ãŒãƒ›ãƒ¼ãƒ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ã‚ã‚Šã¾ã™ã€‚\n"
msgid "Using split format for TOFU database\n"
-msgstr ""
-
-#, fuzzy, c-format
-#| msgid "error sending data: %s\n"
-msgid "error updating TOFU database: %s\n"
-msgstr "データé€ä¿¡ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "TOFUデータベースã«åˆ†å‰²ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã‚’使用\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "公開éµ%sãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s\n"
-
-#, fuzzy, c-format
-#| msgid "error setting OCSP target: %s\n"
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "OCSPターゲットã®è¨­å®šã‚¨ãƒ©ãƒ¼: %s\n"
+msgid "error updating TOFU database: %s\n"
+msgstr "TOFUデータベースã®æ›´æ–°ã‚¨ãƒ©ãƒ¼: %s\n"
#, c-format
msgid "The binding %s is NOT known."
-msgstr ""
+msgstr "%sã®ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ã¯ä¸æ˜Žã§ã™ã€‚"
#, c-format
msgid ""
"The key with fingerprint %s raised a conflict with the binding %s. Since "
"this binding's policy was 'auto', it was changed to 'ask'."
msgstr ""
+"éµã®ãƒ•ã‚£ãƒ³ã‚¬ãƒ¼ãƒ—リント%sãŒãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°%sã¨è¡çªã—ã¾ã—ãŸã€‚ã“ã®ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°"
+"ãƒãƒªã‚·ãƒ¼ã¯'auto'ã ã£ãŸã®ã§ã€'ask'ã«å¤‰æ›´ã•ã‚Œã¾ã—ãŸã€‚"
#, c-format
msgid ""
"Please indicate whether you believe the binding %s%sis legitimate (the key "
"belongs to the stated owner) or a forgery (bad)."
msgstr ""
+"ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°%s%sãŒé©åˆ‡(éµã¯è¿°ã¹ã‚‰ã‚ŒãŸæ‰€æœ‰è€…ã«å±žã™ã‚‹)ã‹ã€å½ã‚‰ã‚ŒãŸã‚‚ã®ã‹(ダ"
+"メ)ã‹ã‚’指示ã—ã¦ãã ã•ã„。"
-#, fuzzy, c-format
-#| msgid "error getting responder ID: %s\n"
+#, c-format
msgid "error gathering other user IDs: %s\n"
-msgstr "応答IDã®å–得エラー: %s\n"
+msgstr "ã»ã‹ã®ãƒ¦ãƒ¼ã‚¶IDã®åŽé›†ã‚¨ãƒ©ãƒ¼: %s\n"
msgid "Known user IDs associated with this key:\n"
-msgstr ""
+msgstr "ã“ã®éµã«çµã³ã¤ã‘られãŸçŸ¥ã‚‰ã‚Œã¦ã„るユーザID:\n"
-#, fuzzy, c-format
-#| msgid "validity: %s"
+#, c-format
msgid "policy: %s"
-msgstr "有効性: %s"
+msgstr "ãƒãƒªã‚·ãƒ¼: %s"
-#, fuzzy, c-format
-#| msgid "error getting stored flags: %s\n"
+#, c-format
msgid "error gathering signature stats: %s\n"
-msgstr "ä¿å­˜ã•ã‚ŒãŸãƒ•ãƒ©ã‚°ã®å–得エラー: %s\n"
+msgstr "ç½²åã®çµ±è¨ˆã®åŽé›†ã‚¨ãƒ©ãƒ¼: %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[0] "é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹\"%s\"ã¯%d個ã®éµã«çµã³ã¤ã‘られã¾ã™:\n"
#, c-format
msgid "Statistics for keys with the email address \"%s\":\n"
-msgstr ""
+msgstr "ã“ã®é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹\"%s\"ã®éµã®çµ±è¨ˆ:\n"
-#, fuzzy
-#| msgid "list keys"
msgid "this key"
-msgstr "éµã®ä¸€è¦§"
+msgstr "ã“ã®éµ"
#, c-format
msgid "%ld message signed in the future."
msgid_plural "%ld messages signed in the future."
-msgstr[0] ""
+msgstr[0] "%ld個ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒæœªæ¥ã«ç½²åã•ã‚Œã¾ã—ãŸã€‚"
-#, fuzzy, c-format
-#| msgid "print message digests"
+#, c-format
msgid "%ld message signed"
msgid_plural "%ld messages signed"
-msgstr[0] "メッセージ・ダイジェストを表示"
+msgstr[0] "%ld個ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã«ç½²åã—ã¾ã—ãŸ"
#, c-format
msgid " over the past %ld day."
msgid_plural " over the past %ld days."
-msgstr[0] ""
+msgstr[0] "éŽåŽ»%ldæ—¥ã«ã€‚"
#, c-format
msgid " over the past %ld week."
msgid_plural " over the past %ld weeks."
-msgstr[0] ""
+msgstr[0] "éŽåŽ»%ld週間ã«ã€‚"
#, c-format
msgid " over the past %ld month."
msgid_plural " over the past %ld months."
-msgstr[0] ""
+msgstr[0] "éŽåŽ»%ld月ã«ã€‚"
#. 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.
+#. * 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ã¯ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ã®è¡çªã‚’検出ã—ã¾ã—ãŸ"
#. 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.
+#. * 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 ""
+"(G)ood-良, (A)ccept once-一度ã ã‘良, (U)nknown-ä¸æ˜Ž, (R)eject once-一度ã ã‘"
+"å¦, (B)ad-ダメ? "
-#, fuzzy, c-format
-#| msgid "error creating a pipe: %s\n"
+#, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "TOFUデータベースã®ä¿¡ç”¨ãƒ¬ãƒ™ãƒ«ã®è¨­å®šã‚¨ãƒ©ãƒ¼: %s\n"
+
+#, c-format
msgid "error changing TOFU policy: %s\n"
-msgstr "パイプã®ä½œæˆã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "TOFUãƒãƒªã‚·ãƒ¼ã®ä½œæˆã‚¨ãƒ©ãƒ¼: %s\n"
#. TRANSLATORS: The tilde ('~') is used here to indicate a
#. * non-breakable space
#, c-format
msgid "%d~year"
msgid_plural "%d~years"
-msgstr[0] ""
+msgstr[0] "%d~å¹´"
#, c-format
msgid "%d~month"
msgid_plural "%d~months"
-msgstr[0] ""
+msgstr[0] "%d~月"
#, c-format
msgid "%d~day"
msgid_plural "%d~days"
-msgstr[0] ""
+msgstr[0] "%d~月"
#, c-format
msgid "%d~hour"
msgid_plural "%d~hours"
-msgstr[0] ""
+msgstr[0] "%d~時間"
#, c-format
msgid "%d~minute"
msgid_plural "%d~minutes"
-msgstr[0] ""
+msgstr[0] "%d~分"
#, c-format
msgid "%d~second"
msgid_plural "%d~seconds"
-msgstr[0] ""
+msgstr[0] "%d~秒"
#, c-format
msgid "Have never verified a message signed by key %s!\n"
-msgstr ""
+msgstr "éµ%sã§ç½²åã•ã‚ŒãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’検証ã—ãŸã“ã¨ã¯ä¸€åº¦ã‚‚ã‚ã‚Šã¾ã›ã‚“!\n"
#, c-format
msgid ""
"Failed to collect signature statistics for \"%s\"\n"
"(key %s)\n"
msgstr ""
+"\"%s\"ã®ç½²åã®çµ±è¨ˆã‚’åŽé›†ã™ã‚‹ã“ã¨ã«å¤±æ•—ã—ã¾ã—ãŸ\n"
+"(éµ %s)\n"
-#, fuzzy, c-format
-#| msgid "print message digests"
+#, c-format
msgid "Verified %ld messages signed by \"%s\"."
-msgstr "メッセージ・ダイジェストを表示"
+msgstr "%ld個ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’検証ã—ã¾ã—ãŸ(\"%s\"ã§ç½²åã•ã‚ŒãŸã‚‚ã®)。"
#, c-format
msgid ""
@@ -5540,17 +5469,18 @@ msgid ""
msgid_plural ""
"Verified %ld messages signed by \"%s\"\n"
"in the past %s."
-msgstr[0] ""
+msgstr[0] "メッセージを%ld回検証ã—ã¾ã—ãŸ(\"%s\"ã§ç½²åã•ã‚ŒãŸã‚‚ã®ã€‚ã‹ã¤ã¦ %s)。"
#, c-format
msgid "The most recent message was verified %s ago."
-msgstr ""
+msgstr "ã‚‚ã£ã¨ã‚‚最近ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯%så‰ã«æ¤œè¨¼ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Warning: we've have yet to see a message signed by this key!\n"
-msgstr ""
+msgstr "警告: ã“ã®éµã§ç½²åã•ã‚ŒãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’検証ã—ãŸã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“!\n"
msgid "Warning: we've only seen a single message signed by this key!\n"
msgstr ""
+"警告: ã“ã®éµã§ç½²åã•ã‚ŒãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’検証ã—ãŸã“ã¨ã¯ä¸€åº¦ã—ã‹ã‚ã‚Šã¾ã›ã‚“!\n"
#, c-format
msgid ""
@@ -5566,11 +5496,15 @@ msgid_plural ""
" %s\n"
"to mark it as being bad.\n"
msgstr[0] ""
+"警告: ã“ã®éµã§ç½²åã•ã‚ŒãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’%ld回以上見ãŸã¨æ€ã†å ´åˆã€å½è€…ã®å¯èƒ½æ€§ãŒã‚"
+"ã‚Šã¾ã™! å°‘æ•°ã®ãƒãƒªã‚¨ãƒ¼ã‚·ãƒ§ãƒ³ã§ã“ã®é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’注æ„æ·±ã検査ã—ã¦ãã ã•"
+"ã„。ã“ã®éµãŒç–‘ã‚れる場åˆã€\n"
+" %s\n"
+"ã§ãƒ€ãƒ¡ã¨ãƒžãƒ¼ã‚¯ã—ã¦ãã ã•ã„。\n"
-#, fuzzy, c-format
-#| msgid "error sending data: %s\n"
+#, c-format
msgid "error opening TOFU database: %s\n"
-msgstr "データé€ä¿¡ã‚¨ãƒ©ãƒ¼: %s\n"
+msgstr "TOFUデータベースã®ã‚ªãƒ¼ãƒ—ンã§ã‚¨ãƒ©ãƒ¼: %s\n"
#, c-format
msgid "'%s' is not a valid long keyID\n"
@@ -5629,23 +5563,25 @@ msgstr "信用モデル'%s'ã§ä¿¡ç”¨ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ¤œæŸ»ã¯ã€ä¸è¦ã§ã
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "信用モデル'%s'ã§ä¿¡ç”¨ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ›´æ–°ã¯ã€ä¸è¦ã§ã™\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "公開éµ%sãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "--check-trustdbを実行ã—ã¦ãã ã•ã„\n"
msgid "checking the trustdb\n"
msgstr "信用データベースã®æ¤œæŸ»\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個ã®éµã‚’処ç†\n"
+msgstr[0] "%d個ã®éµã‚’処ç†"
-#, 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] "%d本ã®éµã‚’å‡¦ç† (ã†ã¡%d本ã®æœ‰åŠ¹æ€§æ•°ã‚’クリア)\n"
+msgstr[0] " (ã†ã¡%d本ã®æœ‰åŠ¹æ€§æ•°ã‚’クリア)\n"
msgid "no ultimately trusted keys found\n"
msgstr "究極的ã«ä¿¡ç”¨ã™ã‚‹éµãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n"
@@ -5669,7 +5605,7 @@ msgid "undefined"
msgstr "未定義"
msgid "never"
-msgstr "æ–­ã˜ã¦ãªã—"
+msgstr "å…¨ããªã—"
msgid "marginal"
msgstr "ã¾ãã¾ã"
@@ -5703,6 +5639,9 @@ msgstr "[ ä¸æ˜Ž ]"
msgid "[ undef ]"
msgstr "[ 未定義 ]"
+msgid "[ never ]"
+msgstr "[å…¨ããªã—]"
+
msgid "[marginal]"
msgstr "[ã¾ãã¾ã]"
@@ -5849,8 +5788,7 @@ msgstr "カードã‹ã‚‰CHVステイタスã®å–å¾—ã§ã‚¨ãƒ©ãƒ¼\n"
msgid "card is permanently locked!\n"
msgstr "カードãŒæ°¸ä¹…ã«ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã¾ã™!\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"
@@ -5931,8 +5869,7 @@ msgstr "éµç”Ÿæˆã®é–“ã€ãŠå¾…ã¡ãã ã•ã„ ...\n"
msgid "generating key failed\n"
msgstr "éµã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸ\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] "éµã®ç”ŸæˆãŒå®Œäº†ã—ã¾ã—㟠(%d秒)\n"
@@ -8029,10 +7966,8 @@ msgstr "|N|N日後ã«ãƒ‘スフレーズを期é™åˆ‡ã‚Œã¨ã™ã‚‹"
msgid "do not allow the reuse of old passphrases"
msgstr "å¤ã„パスフレーズをå†ä½¿ç”¨ã™ã‚‹ã“ã¨ã‚’èªã‚ãªã„"
-#, fuzzy
-#| msgid "|N|set LDAP timeout to N seconds"
msgid "|N|set the Pinentry timeout to N seconds"
-msgstr "|N|LDAPã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã‚’N秒ã¨ã™ã‚‹"
+msgstr "|N|Pinentryã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã‚’N秒ã¨ã™ã‚‹"
msgid "|NAME|use NAME as default secret key"
msgstr "|NAME|デフォルトã®ç§˜å¯†éµã¨ã—ã¦NAMEを用ã„ã‚‹"
@@ -8324,12 +8259,6 @@ msgstr ""
#~ msgid "you found a bug ... (%s:%d)\n"
#~ msgstr "ã‚ãªãŸã¯ãƒã‚°ã‚’発見ã—ã¾ã—㟠... (%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] "有効ãªè‡ªå·±ç½²åã®ãªã„ユーザIDã‚’%d個検出\n"
-
#~ msgid "moving a key signature to the correct place\n"
#~ msgstr "éµã®ç½²åã‚’æ­£ã—ã„場所ã«ç§»å‹•ã—ã¾ã™\n"
diff --git a/po/nb.po b/po/nb.po
index 970241e..9844310 100644
--- a/po/nb.po
+++ b/po/nb.po
@@ -466,6 +466,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "feil ved søking etter tillitspost i «%s»: %s\n"
#, fuzzy, c-format
+msgid "can't set permissions of '%s': %s\n"
+msgstr "ADVARSEL: utrygge rettigheter på utvidelsen «%s»\n"
+
+#, fuzzy, c-format
msgid "listen() failed: %s\n"
msgstr "oppdatering mislyktes: %s\n"
@@ -484,10 +488,6 @@ msgid "directory '%s' created\n"
msgstr "katalogen «%s» ble opprettet\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "ADVARSEL: utrygge rettigheter på utvidelsen «%s»\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "fstat(%d) mislyktes in %s: %s\n"
@@ -1915,13 +1915,13 @@ msgstr "endre passfrasen"
msgid "export keys"
msgstr "eksportere nøkler"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "eksportere nøkler til en nøkkelserver"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importere nøkler fra en nøkkelserver"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "søke etter nøkler på en nøkkelserver"
msgid "update all keys from a keyserver"
@@ -2533,6 +2533,9 @@ msgstr "la konflikter mellom tidsstempler bare være en advarsel"
msgid "|FD|write status info to this FD"
msgstr "|FD|skrive statusinfo til denne FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Bruksmåte: gpgv [valg] [filer] (-h for hjelp)"
@@ -3933,6 +3936,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr ""
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "rundet opp til %u bits\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -3949,11 +3957,6 @@ msgstr "Hvilken nøkkelstørrelse vil du ha? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "Ønsket nøkkelstørrelse er %u bits\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "rundet opp til %u bits\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5604,14 +5607,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "feil ved lesing av «%s»: %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "fant ikke offentlig nøkkel %s: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "feil ved lesing av «%s»: %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5690,14 +5685,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5705,6 +5700,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "feil ved lesing av «%s»: %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "feil ved opprettelse av passfrase: %s\n"
@@ -5858,6 +5857,10 @@ msgstr ""
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr ""
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "fant ikke offentlig nøkkel %s: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr ""
@@ -5931,6 +5934,9 @@ msgstr "[ ukjent]"
msgid "[ undef ]"
msgstr "[ udef ]"
+msgid "[ never ]"
+msgstr ""
+
msgid "[marginal]"
msgstr ""
diff --git a/po/pl.po b/po/pl.po
index 2b8c12c..075ec76 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -488,6 +488,11 @@ msgstr "b³±d podczas pobierania nonce z gniazda\n"
msgid "error binding socket to '%s': %s\n"
msgstr "b³±d podczas przypisywania gniazda do ,,%s'': %s\n"
+#, fuzzy, c-format
+#| msgid "Warning: unsafe permissions on %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"
@@ -508,11 +513,6 @@ msgid "directory '%s' created\n"
msgstr "katalog ,,%s'' utworzony\n"
#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgid "can't set permissions of '%s': %s\n"
-msgstr "Ostrze¿enie: niebezpieczne prawa dostêpu do %s ,,%s''\n"
-
-#, fuzzy, c-format
#| msgid "stat() failed for `%s': %s\n"
msgid "stat() failed for '%s': %s\n"
msgstr "stat() nie powiod³o siê dla ,,%s'': %s\n"
@@ -1970,13 +1970,13 @@ msgstr "zmiana has³a"
msgid "export keys"
msgstr "eksport kluczy do pliku"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "eksport kluczy do serwera kluczy"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "import kluczy z serwera kluczy"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "szukanie kluczy na serwerze"
msgid "update all keys from a keyserver"
@@ -2601,6 +2601,9 @@ msgstr "nie traktowaæ konfliktu datowników jako b³êdu"
msgid "|FD|write status info to this FD"
msgstr "|FD|pisanie opisu stanu do deskryptora FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Wywo³anie: gpgv [opcje] [pliki] (-h podaje pomoc)"
@@ -4077,6 +4080,11 @@ msgstr "Nieprawid³owy uchwyt klucza (oczekiwano 40 cyfr szesnastkowych)\n"
msgid "No key with this keygrip\n"
msgstr "Brak klucza o tym uchwycie\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "zaokr±glono do %u bitów\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "Klucze %s bêd± mia³y od %u do %u bitów d³ugo¶ci.\n"
@@ -4093,11 +4101,6 @@ msgstr "Jakiej d³ugo¶ci klucz wygenerowaæ? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "¯±dana d³ugo¶æ klucza to %u bitów.\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "zaokr±glono do %u bitów\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5825,15 +5828,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "b³±d wysy³ania polecenia %s: %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "klucz publiczny %s nie odnaleziony: %s\n"
-
-#, fuzzy, c-format
-#| msgid "error storing flags: %s\n"
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "b³±d zapisywania flag: %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5920,14 +5914,14 @@ msgstr[1] ""
msgstr[2] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5935,6 +5929,11 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+#| msgid "error storing flags: %s\n"
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "b³±d zapisywania flag: %s\n"
+
+#, fuzzy, c-format
#| msgid "error creating a pipe: %s\n"
msgid "error changing TOFU policy: %s\n"
msgstr "b³±d tworzenia potoku: %s\n"
@@ -6102,6 +6101,10 @@ msgstr "sprawdzanie bazy jest niepotrzebne przy modelu zaufania ,,%s''\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "aktualizacja bazy jest niepotrzebna przy modelu zaufania ,,%s''\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "klucz publiczny %s nie odnaleziony: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "nale¿y uruchomiæ gpg z opcj± ,,--check-trustdb''\n"
@@ -6184,6 +6187,11 @@ msgstr "[ nieznane ]"
msgid "[ undef ]"
msgstr "[ nieokre¶lone ]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "nigdy"
+
msgid "[marginal]"
msgstr "[ marginalne ]"
diff --git a/po/pt.po b/po/pt.po
index c271492..e20d484 100644
--- a/po/pt.po
+++ b/po/pt.po
@@ -465,6 +465,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "erro ao enviar para `%s': %s\n"
#, fuzzy, c-format
+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"
@@ -481,10 +485,6 @@ msgid "directory '%s' created\n"
msgstr "%s: directoria criada\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "base de dados de confiança: leitura falhou (n=%d): %s\n"
@@ -1954,13 +1954,13 @@ msgstr "muda a frase secreta"
msgid "export keys"
msgstr "exportar chaves"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "exportar chaves para um servidor de chaves"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importar chaves de um servidor de chaves"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "procurar chaves num servidor de chaves"
msgid "update all keys from a keyserver"
@@ -2561,6 +2561,9 @@ msgstr ""
"|DF|escrever informações de estado para o\n"
"descritor de ficheiro DF"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
#, fuzzy
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)"
@@ -4043,6 +4046,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Nenhum ID de utilizador com índice %d\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "arredondado para %u bits\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4059,11 +4067,6 @@ msgstr "Qual o tamanho de chave desejado? (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "O tamanho de chave pedido é %u bits\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "arredondado para %u bits\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5734,14 +5737,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "erro ao enviar para `%s': %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "chave pública %08lX não encontrada: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "erro na leitura de `%s': %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5820,14 +5815,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5835,6 +5830,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "erro na leitura de `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "erro na criação da frase secreta: %s\n"
@@ -5990,6 +5989,10 @@ msgstr "não é necessária uma verificação da base de dados de confiança\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "não é necessária uma verificação da base de dados de confiança\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "chave pública %08lX não encontrada: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr ""
@@ -6068,6 +6071,9 @@ msgstr "versão desconhecida"
msgid "[ undef ]"
msgstr ""
+msgid "[ never ]"
+msgstr ""
+
msgid "[marginal]"
msgstr ""
diff --git a/po/ro.po b/po/ro.po
index 79d9bae..9f54576 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -475,6 +475,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "eroare trimitere la `%s': %s\n"
#, fuzzy, c-format
+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"
@@ -493,10 +497,6 @@ msgid "directory '%s' created\n"
msgstr "director `%s' creat\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "AVERTISMENT: permisiuni nesigure (unsafe) pentru extensia `%s'\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "fstat(%d) a eºuat în %s: %s\n"
@@ -1954,13 +1954,13 @@ msgstr "schimbã fraza-parolã"
msgid "export keys"
msgstr "exportã chei"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "exportã chei pentru un server de chei"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importã chei de la un server de chei"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "cautã pentru chei pe un server de chei"
msgid "update all keys from a keyserver"
@@ -2586,6 +2586,9 @@ msgstr "dã numai un avertisment la conflicte de timestamp"
msgid "|FD|write status info to this FD"
msgstr "|FD|scrie informaþii de stare în acest FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Folosire: gpgv [opþiuni] [fiºiere] (-h pentru ajutor)"
@@ -4043,6 +4046,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Nici o subcheie cu indicele %d\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "rotunjitã prin adaos la %u biþi\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "cheile %s pot avea lungimea între %u ºi %u biþi.\n"
@@ -4059,11 +4067,6 @@ msgstr "Ce lungime de cheie doriþi? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "Lungimea cheii necesarã este %u biþi\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "rotunjitã prin adaos la %u biþi\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5754,14 +5757,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "eroare trimitere la `%s': %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "cheia publicã %s nu a fost gãsitã: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "eroare la citire `%s': %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5840,14 +5835,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5855,6 +5850,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "eroare la citire `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "eroare la crearea frazei-parolã: %s\n"
@@ -6011,6 +6010,10 @@ msgstr "nu e nevoie de o verificare trustdb cu modelul de încredere `%s'\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "nu e nevoie de o actualizare trustdb cu modelul de încredere `%s'\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "cheia publicã %s nu a fost gãsitã: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "vã rugãm faceþi un --check-trustdb\n"
@@ -6089,6 +6092,11 @@ msgstr "[necunoscutã]"
msgid "[ undef ]"
msgstr "[ nedef ]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "niciodatã"
+
msgid "[marginal]"
msgstr "[marginal]"
diff --git a/po/ru.po b/po/ru.po
index f311cd1..7997837 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -23,7 +23,7 @@ msgstr ""
#, c-format
msgid "failed to acquire the pinentry lock: %s\n"
-msgstr "Ñбой при блокировке Ð´Ð»Ñ Ð²Ð²Ð¾Ð´Ð° PIN: %s\n"
+msgstr "Ñбой при блокировке Ð´Ð»Ñ Ð²Ð²Ð¾Ð´Ð° паролÑ: %s\n"
#. TRANSLATORS: These are labels for buttons etc used in
#. Pinentries. An underscore indicates that the next letter
@@ -371,10 +371,9 @@ msgstr "не позволÑÑ‚ÑŒ клиентам помечать ключи кÐ
msgid "allow presetting passphrase"
msgstr "разрешить предуÑтанавливать фразу-пароль"
-#, fuzzy
-#| msgid "allow caller to override the pinentry"
msgid "disallow caller to override the pinentry"
-msgstr "разрешить клиентам замещать Ñобой pinentry"
+msgstr ""
+"не позволÑÑ‚ÑŒ вызывающей программе замещать Ñобой программу ввода паролÑ"
msgid "allow passphrase to be prompted through Emacs"
msgstr "разрешить ввод фразы-Ð¿Ð°Ñ€Ð¾Ð»Ñ Ñ‡ÐµÑ€ÐµÐ· Emacs"
@@ -444,6 +443,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "ошибка ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ Ñокета Ñ '%s': %s\n"
#, c-format
+msgid "can't set permissions of '%s': %s\n"
+msgstr "не удалоÑÑŒ задать права доÑтупа Ð´Ð»Ñ '%s': %s\n"
+
+#, c-format
msgid "listen() failed: %s\n"
msgstr "Ñбой listen(): %s\n"
@@ -459,11 +462,6 @@ msgstr "не могу Ñоздать каталог '%s': %s\n"
msgid "directory '%s' created\n"
msgstr "Ñоздан каталог '%s'\n"
-#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgid "can't set permissions of '%s': %s\n"
-msgstr "Внимание: небезопаÑные права доÑтупа %s \"%s\"\n"
-
#, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "Ñбой stat() Ð´Ð»Ñ '%s': %s\n"
@@ -678,15 +676,15 @@ msgstr ""
"Удаление его может лишить Ð’Ð°Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾Ñти доÑтупа к удаленным машинам."
msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "DSA требует длины Ñ…Ñша, кратной 8 битам\n"
+msgstr "DSA требует длины хеша, кратной 8 битам\n"
#, c-format
msgid "%s key uses an unsafe (%u bit) hash\n"
-msgstr "%s ключ иÑпользует небезопаÑный (%u бит) Ñ…Ñш\n"
+msgstr "%s ключ иÑпользует небезопаÑный (%u бит) хеш\n"
#, c-format
msgid "a %zu bit hash is not valid for a %u bit %s key\n"
-msgstr "%zu-битный Ñ…Ñш недопуÑтим Ð´Ð»Ñ %u-битного ключа %s\n"
+msgstr "%zu-битный хеш недопуÑтим Ð´Ð»Ñ %u-битного ключа %s\n"
#, c-format
msgid "checking created signature failed: %s\n"
@@ -705,7 +703,7 @@ msgstr "алгоритм защиты %d (%s) не поддерживаетÑÑ\
#, c-format
msgid "protection hash algorithm %d (%s) is not supported\n"
-msgstr "Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ñ‹ %d (%s) не поддерживаетÑÑ\n"
+msgstr "хеш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ñ‹ %d (%s) не поддерживаетÑÑ\n"
#, c-format
msgid "error creating a pipe: %s\n"
@@ -719,10 +717,9 @@ msgstr "ошибка при Ñоздании потока Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° к
msgid "error forking process: %s\n"
msgstr "ошибка при дублировании процеÑÑа: %s\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 "Ñбой при ожидании Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑа %d: %s\n"
+msgstr "Ñбой при ожидании Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑа: %s\n"
#, c-format
msgid "error running '%s': probably not installed\n"
@@ -760,10 +757,9 @@ msgstr "прервано пользователем\n"
msgid "problem with the agent\n"
msgstr "проблема Ñ Ð°Ð³ÐµÐ½Ñ‚Ð¾Ð¼\n"
-#, fuzzy, c-format
-#| msgid "problem with the agent: %s\n"
+#, c-format
msgid "problem with the agent (unexpected response \"%s\")\n"
-msgstr "проблема Ñ Ð°Ð³ÐµÐ½Ñ‚Ð¾Ð¼: %s\n"
+msgstr "проблема Ñ Ð°Ð³ÐµÐ½Ñ‚Ð¾Ð¼ (неожиданный ответ \"%s\")\n"
#, c-format
msgid "can't disable core dumps: %s\n"
@@ -931,7 +927,7 @@ msgstr "Данные уÑпешно подпиÑаны"
#, c-format
msgid "data hash algorithm: %s"
-msgstr "Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…: %s"
+msgstr "хеш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…: %s"
#, c-format
msgid "Signer %d"
@@ -939,7 +935,7 @@ msgstr "ПодпиÑÑŒ %d"
#, c-format
msgid "attr hash algorithm: %s"
-msgstr "Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð²: %s"
+msgstr "хеш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð²: %s"
msgid "Data decryption succeeded"
msgstr "Данные уÑпешно раÑшифрованы"
@@ -958,7 +954,7 @@ msgstr "Разбор данных завершен"
#, c-format
msgid "bad data hash algorithm: %s"
-msgstr "недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…: %s"
+msgstr "недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…ÐµÑˆ-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…: %s"
#, c-format
msgid "Signature %d"
@@ -1162,45 +1158,34 @@ msgstr ""
"Ñимвол quoted printable в текÑтовом формате - иÑпорчено почтовой "
"программой?\n"
-#, fuzzy, c-format
-#| msgid "not human readable"
+#, c-format
msgid "[ not human readable (%zu bytes: %s%s) ]"
-msgstr "не Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ‡ÐµÐ»Ð¾Ð²ÐµÐºÐ¾Ð¼"
+msgstr "[ не Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ‡ÐµÐ»Ð¾Ð²ÐµÐºÐ¾Ð¼ (%zu байт: %s%s) ]"
msgid ""
"a notation name must have only printable characters or spaces, and end with "
"an '='\n"
msgstr ""
-"Ð¸Ð¼Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ Ñодержать только печатные Ñимволы или пробелы и "
+"Ð¸Ð¼Ñ Ð·Ð°Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ Ñодержать только печатные Ñимволы или пробелы и "
"заканчиватьÑÑ Ð·Ð½Ð°ÐºÐ¾Ð¼ '='\n"
msgid "a user notation name must contain the '@' character\n"
-msgstr "Ð¸Ð¼Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ Ñодержать Ñимвол '@'\n"
+msgstr "Ð¸Ð¼Ñ Ð·Ð°Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ Ñодержать Ñимвол '@'\n"
msgid "a notation name must not contain more than one '@' character\n"
-msgstr ""
-"Ð¸Ð¼Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ должно Ñодержать более одного Ñимвола '@'\n"
+msgstr "Ð¸Ð¼Ñ Ð·Ð°Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð½Ðµ должно Ñодержать более одного Ñимвола '@'\n"
msgid "a notation value must not use any control characters\n"
-msgstr "в значении Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð½Ðµ должно быть управлÑющих Ñимволов\n"
+msgstr "в текÑте Ð·Ð°Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð½Ðµ должно быть управлÑющих Ñимволов\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 ""
-"Ð¸Ð¼Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ должно Ñодержать более одного Ñимвола '@'\n"
+msgstr "Ð¸Ð¼Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð½Ðµ должно Ñодержать Ñимвола '='\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 ""
-"Ð¸Ð¼Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ Ñодержать только печатные Ñимволы или пробелы и "
-"заканчиватьÑÑ Ð·Ð½Ð°ÐºÐ¾Ð¼ '='\n"
+msgstr "Ð¸Ð¼Ñ Ð·Ð°Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ Ñодержать только печатные Ñимволы или пробелы\n"
msgid "WARNING: invalid notation data found\n"
-msgstr "Внимание: найдена недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ„Ð¾Ñ€Ð¼Ð° запиÑи примечаниÑ\n"
+msgstr "Внимание: найдена недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ„Ð¾Ñ€Ð¼Ð° запиÑи замечаниÑ\n"
#, c-format
msgid "failed to proxy %s inquiry to client\n"
@@ -1836,13 +1821,13 @@ msgstr "Ñменить фразу-пароль"
msgid "export keys"
msgstr "ÑкÑпортировать ключи"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "ÑкÑпортировать ключи на Ñервер ключей"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "импортировать ключи Ñ Ñервера ключей"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "иÑкать ключи на Ñервере ключей"
msgid "update all keys from a keyserver"
@@ -1864,17 +1849,13 @@ msgid "update the trust database"
msgstr "обновить таблицу довериÑ"
msgid "print message digests"
-msgstr "вывеÑти Ñ…Ñши Ñообщений"
+msgstr "вывеÑти хеши Ñообщений"
msgid "run in server mode"
msgstr "запуÑк в режиме Ñервера"
-#, 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 ""
-"|VALUE|уÑтановить правила TOFU Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° (good - хороший, unknown - "
-"неизвеÑтно, bad - плохой, ask - Ñпрашивать, auto - автоматичеÑки)"
+msgstr "|VALUE|уÑтановить правила TOFU Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð°"
msgid "create ascii armored output"
msgstr "вывод в текÑтовом формате"
@@ -1955,7 +1936,7 @@ msgid "Cipher: "
msgstr "Симметричные шифры: "
msgid "Hash: "
-msgstr "Ð¥Ñш-функции: "
+msgstr "Хеш-функции: "
msgid "Compression: "
msgstr "Ðлгоритмы ÑжатиÑ: "
@@ -2045,13 +2026,13 @@ msgid "show policy URLs during signature listings"
msgstr "показать в ÑпиÑке подпиÑей URL правил"
msgid "show all notations during signature listings"
-msgstr "показать в ÑпиÑке подпиÑей вÑе примечаниÑ"
+msgstr "показать в ÑпиÑке подпиÑей вÑе замечаниÑ"
msgid "show IETF standard notations during signature listings"
-msgstr "показать в ÑпиÑке подпиÑей Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ñтандарта IETF"
+msgstr "показать в ÑпиÑке подпиÑей Ð·Ð°Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ñтандарта IETF"
msgid "show user-supplied notations during signature listings"
-msgstr "показать в ÑпиÑке подпиÑей пользовательÑкие примечаниÑ"
+msgstr "показать в ÑпиÑке подпиÑей пользовательÑкие замечаниÑ"
msgid "show preferred keyserver URLs during signature listings"
msgstr "показать в ÑпиÑке подпиÑей URL предпочтительных Ñерверов ключей"
@@ -2103,7 +2084,7 @@ msgstr "'%s' - не допуÑтимый Ñрок дейÑÑ‚Ð²Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐ
#, c-format
msgid "invalid pinentry mode '%s'\n"
-msgstr "недопуÑтимый режим ввода PIN '%s'\n"
+msgstr "недопуÑтимый режим ввода Ð¿Ð°Ñ€Ð¾Ð»Ñ '%s'\n"
#, c-format
msgid "'%s' is not a valid character set\n"
@@ -2147,13 +2128,13 @@ msgid "show policy URLs during signature verification"
msgstr "показать при проверке подпиÑи URL правил"
msgid "show all notations during signature verification"
-msgstr "показать при проверке подпиÑей вÑе примечаниÑ"
+msgstr "показать при проверке подпиÑей вÑе замечаниÑ"
msgid "show IETF standard notations during signature verification"
-msgstr "показать при проверке подпиÑей Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ñтандарта IETF"
+msgstr "показать при проверке подпиÑей Ð·Ð°Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ñтандарта IETF"
msgid "show user-supplied notations during signature verification"
-msgstr "показать при проверке подпиÑей пользовательÑкие примечаниÑ"
+msgstr "показать при проверке подпиÑей пользовательÑкие замечаниÑ"
msgid "show preferred keyserver URLs during signature verification"
msgstr "показать при проверке подпиÑей URL предпочтительных Ñерверов ключей"
@@ -2218,13 +2199,13 @@ msgid "selected cipher algorithm is invalid\n"
msgstr "выбран недопуÑтимый алгоритм шифрованиÑ\n"
msgid "selected digest algorithm is invalid\n"
-msgstr "выбрана недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…Ñш-функциÑ\n"
+msgstr "выбрана недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…ÐµÑˆ-функциÑ\n"
msgid "selected compression algorithm is invalid\n"
msgstr "выбран недопуÑтимый алгоритм ÑжатиÑ\n"
msgid "selected certification digest algorithm is invalid\n"
-msgstr "выбрана недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð»Ñ Ñертификации\n"
+msgstr "выбрана недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…ÐµÑˆ-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð»Ñ Ñертификации\n"
msgid "completes-needed must be greater than 0\n"
msgstr "completes-needed должен быть больше 0\n"
@@ -2254,7 +2235,7 @@ msgid "invalid personal cipher preferences\n"
msgstr "недопуÑтимые личные Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ ÑˆÐ¸Ñ„Ñ€Ð°\n"
msgid "invalid personal digest preferences\n"
-msgstr "недопуÑтимые личные Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ…Ñш-функции\n"
+msgstr "недопуÑтимые личные Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ…ÐµÑˆ-функции\n"
msgid "invalid personal compress preferences\n"
msgstr "недопуÑтимые личные Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð°Ð»Ð³Ð¾Ñ€Ð¸Ñ‚Ð¼Ð¾Ð² ÑжатиÑ\n"
@@ -2269,7 +2250,7 @@ msgstr "шифрование '%s' в режиме %s иÑпользовать н
#, c-format
msgid "you may not use digest algorithm '%s' while in %s mode\n"
-msgstr "Ñ…Ñш-функцию '%s' в режиме %s иÑпользовать нельзÑ\n"
+msgstr "хеш-функцию '%s' в режиме %s иÑпользовать нельзÑ\n"
#, c-format
msgid "you may not use compression algorithm '%s' while in %s mode\n"
@@ -2379,7 +2360,7 @@ msgstr "ошибка Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² текÑтовый форм
#, c-format
msgid "invalid hash algorithm '%s'\n"
-msgstr "недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ '%s'\n"
+msgstr "недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…ÐµÑˆ-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ '%s'\n"
#, c-format
msgid "error parsing key specification '%s': %s\n"
@@ -2413,6 +2394,9 @@ msgstr "при неÑоответÑтвии метки времени - толь
msgid "|FD|write status info to this FD"
msgstr "|FD|выводить информацию в файл Ñ Ð´ÐµÑкриптором FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Вызов: gpgv [параметры] [файлы] (-h Ð´Ð»Ñ Ð¿Ð¾Ð´Ñказки)"
@@ -2537,7 +2521,7 @@ msgstr " \"%s\": предпочитает шифр %s\n"
#, c-format
msgid " \"%s\": preference for digest algorithm %s\n"
-msgstr " \"%s\": предпочитает Ñ…Ñш-функцию %s\n"
+msgstr " \"%s\": предпочитает хеш-функцию %s\n"
#, c-format
msgid " \"%s\": preference for compression algorithm %s\n"
@@ -2838,35 +2822,30 @@ msgstr "[отзыв]"
msgid "[self-signature]"
msgstr "[ÑамоподпиÑÑŒ]"
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
+#, c-format
msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "ключ %s: алгоритм Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼ ключом не поддерживаетÑÑ\n"
+msgstr ""
+"не удалоÑÑŒ проверить подпиÑÑŒ: алгоритм Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼ ключом %d не "
+"поддерживаетÑÑ: %s.\n"
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
+#, c-format
msgid ""
"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "карта не поддерживает Ñ…Ñш-функцию %s\n"
+msgstr "не удалоÑÑŒ проверить подпиÑÑŒ: хеш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %d не поддерживаетÑÑ: %s.\n"
-#, fuzzy
-#| msgid "Good signature from"
msgid " (reordered signatures follow)"
-msgstr "Ð¥Ð¾Ñ€Ð¾ÑˆÐ°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ пользователÑ"
+msgstr "(порÑдок подпиÑей изменен)"
-#, fuzzy, c-format
-#| msgid "key %s: %s\n"
+#, c-format
msgid "key %s:\n"
-msgstr "ключ %s: %s\n"
+msgstr "ключ %s:\n"
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
-#| msgid_plural "User ID \"%s\": %d signatures removed\n"
+#, c-format
msgid "%d duplicate signature removed\n"
msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\": %d подпиÑÑŒ удалена\n"
-msgstr[1] "ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\": %d подпиÑи удалены\n"
-msgstr[2] "ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\": %d подпиÑей удалено\n"
+msgstr[0] "%d Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ удалена\n"
+msgstr[1] "%d повторные подпиÑи удалены\n"
+msgstr[2] "%d повторных подпиÑей удалено\n"
#, c-format
msgid "%d signature not checked due to a missing key\n"
@@ -2882,19 +2861,20 @@ msgstr[0] "%d Ð¿Ð»Ð¾Ñ…Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ\n"
msgstr[1] "%d плохих подпиÑи\n"
msgstr[2] "%d плохих подпиÑей\n"
-#, fuzzy, c-format
-#| msgid "Good signature from"
+#, c-format
msgid "%d signature reordered\n"
msgid_plural "%d signatures reordered\n"
-msgstr[0] "Ð¥Ð¾Ñ€Ð¾ÑˆÐ°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ пользователÑ"
-msgstr[1] "Ð¥Ð¾Ñ€Ð¾ÑˆÐ°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ пользователÑ"
-msgstr[2] "Ð¥Ð¾Ñ€Ð¾ÑˆÐ°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ пользователÑ"
+msgstr[0] "ПорÑдок %d подпиÑи изменен\n"
+msgstr[1] "ПорÑдок %d подпиÑей изменен\n"
+msgstr[2] "ПорÑдок %d подпиÑей изменен\n"
#, c-format
msgid ""
"Warning: errors found and only checked self-signatures, run '%s' to check "
"all signatures.\n"
msgstr ""
+"Внимание: обнаружены ошибки, проверÑлиÑÑŒ только ÑамоподпиÑи; Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ "
+"вÑех подпиÑей выполните '%s'.\n"
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3174,7 +3154,7 @@ msgstr ""
"уÑтановить URL предпочтительного Ñервера ключей Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ… ID пользователÑ"
msgid "set a notation for the selected user IDs"
-msgstr "уÑтановить примечание Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ… ID пользователÑ"
+msgstr "уÑтановить замечание Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ… ID пользователÑ"
msgid "change the passphrase"
msgstr "Ñменить фразу-пароль"
@@ -3338,10 +3318,9 @@ msgstr "\"%s\" - не отпечаток\n"
msgid "\"%s\" is not the primary fingerprint\n"
msgstr "\"%s\" - не первичный отпечаток\n"
-#, fuzzy, c-format
-#| msgid "invalid value\n"
+#, c-format
msgid "Invalid user ID '%s': %s\n"
-msgstr "недопуÑтимое значение\n"
+msgstr "ÐедопуÑтимый ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ '%s': %s\n"
msgid "No matching user IDs."
msgstr "Ðет подходÑщих ID пользователей."
@@ -3350,7 +3329,7 @@ msgid "Nothing to sign.\n"
msgstr "ПодпиÑывать нечего.\n"
msgid "Digest: "
-msgstr "Ð¥Ñш: "
+msgstr "Хеш: "
msgid "Features: "
msgstr "ХарактериÑтики: "
@@ -3362,7 +3341,7 @@ msgid "Preferred keyserver: "
msgstr "Предпочтительный Ñервер ключей: "
msgid "Notations: "
-msgstr "ПримечаниÑ: "
+msgstr "ЗамечаниÑ: "
msgid "There are no preferences on a PGP 2.x-style user ID.\n"
msgstr "Ð’ ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ‚Ð¸Ð¿Ð° PGP 2.x не может быть предпочтений.\n"
@@ -3575,7 +3554,7 @@ msgid "Are you sure you want to delete it? (y/N) "
msgstr "Ð’Ñ‹ дейÑтвительно хотите удалить его? (y/N) "
msgid "Enter the notation: "
-msgstr "Введите примечание: "
+msgstr "Введите замечание: "
msgid "Proceed? (y/N) "
msgstr "Продолжить? (y/N) "
@@ -3586,7 +3565,7 @@ msgstr "Ðет ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ Ð¸Ð½Ð´ÐµÐºÑом %d\n"
#, c-format
msgid "No user ID with hash %s\n"
-msgstr "Ðет ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ Ñ…Ñшем %s\n"
+msgstr "Ðет ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ Ñ…ÐµÑˆÐµÐ¼ %s\n"
#, c-format
msgid "No subkey with key ID '%s'.\n"
@@ -3668,7 +3647,7 @@ msgid "too many cipher preferences\n"
msgstr "Ñлишком много шифровых предпочтений\n"
msgid "too many digest preferences\n"
-msgstr "Ñлишком много предпочтений Ð´Ð»Ñ Ñ…Ñш-функций\n"
+msgstr "Ñлишком много предпочтений Ð´Ð»Ñ Ñ…ÐµÑˆ-функций\n"
msgid "too many compression preferences\n"
msgstr "Ñлишком много предпочтений Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð¾Ð² ÑжатиÑ\n"
@@ -3698,7 +3677,7 @@ msgid ""
"WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n"
msgstr ""
"Внимание: некоторые реализации OpenPGP не могут обрабатывать ключи DSA Ñ "
-"такой длиной Ñ…Ñша\n"
+"такой длиной хеша\n"
msgid "Sign"
msgstr "ПодпиÑать"
@@ -3813,6 +3792,10 @@ msgid "No key with this keygrip\n"
msgstr "Ðет ключа Ñ Ñ‚Ð°ÐºÐ¸Ð¼ кодом\n"
#, c-format
+msgid "rounded to %u bits\n"
+msgstr "округлен до %u бит\n"
+
+#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "длина ключей %s может быть от %u до %u бит.\n"
@@ -3828,10 +3811,6 @@ msgstr "Какой размер ключа Вам необходим? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "Запрошенный размер ключа - %u бит\n"
-#, c-format
-msgid "rounded to %u bits\n"
-msgstr "округлен до %u бит\n"
-
msgid "Please select which elliptic curve you want:\n"
msgstr "Выберите ÑллиптичеÑкую кривую:\n"
@@ -4118,10 +4097,10 @@ msgid "Critical preferred keyserver: "
msgstr "КритичеÑкий предпочтительный Ñервер ключей: "
msgid "Critical signature notation: "
-msgstr "КритичеÑкое примечание к подпиÑи: "
+msgstr "КритичеÑкое замечание к подпиÑи: "
msgid "Signature notation: "
-msgstr "Примечание к подпиÑи: "
+msgstr "Замечание к подпиÑи: "
#, c-format
msgid "%d good signature\n"
@@ -4152,7 +4131,7 @@ msgid "skipped \"%s\": %s\n"
msgstr "пропущено \"%s\": %s\n"
msgid "Primary key fingerprint:"
-msgstr "Отпечаток главного ключа:"
+msgstr "Отпечаток первичного ключа:"
msgid " Subkey fingerprint:"
msgstr " Отпечаток подключа:"
@@ -4160,7 +4139,7 @@ msgstr " Отпечаток подключа:"
#. TRANSLATORS: this should fit into 24 bytes so that the
#. * fingerprint data is properly aligned with the user ID
msgid " Primary key fingerprint:"
-msgstr " Отпечаток главного ключа:"
+msgstr " Отпечаток первичного ключа:"
msgid " Subkey fingerprint:"
msgstr " Отпечаток подключа:"
@@ -4289,7 +4268,7 @@ msgstr "ÑеанÑовый ключ зашифрован по %s\n"
#, c-format
msgid "passphrase generated with unknown digest algorithm %d\n"
-msgstr "фраза-пароль Ñоздана Ñ Ð½ÐµÐ·Ð½Ð°ÐºÐ¾Ð¼Ð¾Ð¹ Ñ…Ñш-функцией %d\n"
+msgstr "фраза-пароль Ñоздана Ñ Ð½ÐµÐ·Ð½Ð°ÐºÐ¾Ð¼Ð¾Ð¹ хеш-функцией %d\n"
#, c-format
msgid "public key is %s\n"
@@ -4408,7 +4387,7 @@ msgstr "ПодпиÑÑŒ дейÑтвительна до %s\n"
#, c-format
msgid "%s signature, digest algorithm %s%s%s\n"
-msgstr "формат подпиÑи: %s, Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s%s%s\n"
+msgstr "формат подпиÑи: %s, хеш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s%s%s\n"
msgid "binary"
msgstr "двоичный"
@@ -4470,15 +4449,15 @@ msgstr ""
#, c-format
msgid "WARNING: using experimental digest algorithm %s\n"
-msgstr "Внимание: иÑпользуетÑÑ ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s\n"
+msgstr "Внимание: иÑпользуетÑÑ ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…ÐµÑˆ-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s\n"
#, c-format
msgid "WARNING: digest algorithm %s is deprecated\n"
-msgstr "Внимание: Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s не рекомендуетÑÑ\n"
+msgstr "Внимание: хеш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s не рекомендуетÑÑ\n"
#, c-format
msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "Замечание: подпиÑи Ñ Ñ…Ñш-функцией %s игнорируютÑÑ\n"
+msgstr "Замечание: подпиÑи Ñ Ñ…ÐµÑˆ-функцией %s игнорируютÑÑ\n"
#, c-format
msgid "(reported error: %s)\n"
@@ -4541,7 +4520,7 @@ msgstr "Открытый ключ ECDSA бывает в кодировке SEC,
#, c-format
msgid "unknown weak digest '%s'\n"
-msgstr "неизвеÑтный Ñлабый Ñ…Ñш '%s'\n"
+msgstr "неизвеÑтный Ñлабый хеш '%s'\n"
#, c-format
msgid "File '%s' exists. "
@@ -5122,14 +5101,14 @@ msgstr ""
#, c-format
msgid "%s key %s uses an unsafe (%zu bit) hash\n"
-msgstr "ключ %s %s иÑпользует небезопаÑный (%zu-битный) Ñ…Ñш\n"
+msgstr "ключ %s %s иÑпользует небезопаÑный (%zu-битный) хеш\n"
#, c-format
msgid "%s key %s requires a %zu bit or larger hash (hash is %s)\n"
-msgstr "Ключ %s %s требует %zu-битного или более длинного Ñ…Ñша (Ñ…Ñш %s)\n"
+msgstr "Ключ %s %s требует %zu-битного или более длинного хеша (хеш %s)\n"
msgid "WARNING: signature digest conflict in message\n"
-msgstr "Внимание: конфликт Ñ…Ñшей подпиÑей в Ñообщении\n"
+msgstr "Внимание: конфликт хешей подпиÑей в Ñообщении\n"
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
@@ -5210,7 +5189,7 @@ msgstr "ключ %s: нет подключа Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи ÑвÑзи п
#, c-format
msgid "WARNING: unable to %%-expand notation (too large). Using unexpanded.\n"
msgstr ""
-"Внимание: не могу развернуть %% в примечании (Ñлишком длинное).\n"
+"Внимание: не могу развернуть %% в замечании (Ñлишком длинное).\n"
" ИÑпользую неразвернутым.\n"
#, c-format
@@ -5236,7 +5215,7 @@ msgstr "подпиÑÑŒ %s/%s Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\"\n"
msgid ""
"WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n"
msgstr ""
-"Внимание: иÑпользование Ñ…Ñш-функции %s (%d) нарушает Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ "
+"Внимание: иÑпользование хеш-функции %s (%d) нарушает Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ "
"получателÑ\n"
msgid "signing:"
@@ -5350,7 +5329,7 @@ msgstr "%s: недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° довериÑ\n"
#, c-format
msgid "%s: failed to create hashtable: %s\n"
-msgstr "%s: Ñбой ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ Ñ…Ñшей: %s\n"
+msgstr "%s: Ñбой ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ хешей: %s\n"
#, c-format
msgid "%s: error updating version record: %s\n"
@@ -5454,27 +5433,16 @@ msgid "error updating TOFU database: %s\n"
msgstr "ошибка Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ð°Ð·Ñ‹ данных TOFU: %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "открытый ключ %s не найден: %s\n"
-
-#, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "ошибка уÑтановки ÑƒÑ€Ð¾Ð²Ð½Ñ Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ Ð¿Ñ€Ð¸Ð²Ñзки TOFU в %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr "ПривÑзка %s неизвеÑтна."
-#, fuzzy, c-format
-#| msgid ""
-#| "The key %s raised a conflict with this binding (%s). Since this "
-#| "binding's policy was 'auto', it was changed to 'ask'."
+#, c-format
msgid ""
"The key with fingerprint %s raised a conflict with the binding %s. Since "
"this binding's policy was 'auto', it was changed to 'ask'."
msgstr ""
-"Ключ %s противоречит Ñтой привÑзке (%s). ПоÑкольку правило привÑзки было "
-"'автоматичеÑки', оно изменилоÑÑŒ на 'Ñпрашивать'."
+"Ключ Ñ Ð¾Ñ‚Ð¿ÐµÑ‡Ð°Ñ‚ÐºÐ¾Ð¼ %s противоречит Ñтой привÑзке %s. ПоÑкольку правило "
+"привÑзки было 'автоматичеÑки', оно изменилоÑÑŒ на 'Ñпрашивать'."
#, c-format
msgid ""
@@ -5549,8 +5517,8 @@ msgstr[1] " за %ld прошедших меÑÑца."
msgstr[2] " за %ld прошедших меÑÑцев."
#. 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.
+#. * 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 ""
"Обычно Ñ ÐºÐ¾Ð½ÐºÑ€ÐµÑ‚Ð½Ñ‹Ð¼ адреÑом Ñлектронной почты ÑвÑзан только один ключ. "
@@ -5561,8 +5529,8 @@ msgstr ""
"правомерен."
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr "gGaAuUrRbB"
@@ -5571,86 +5539,74 @@ msgstr ""
"(G)Хороший, (A)Пока принÑÑ‚ÑŒ, (U)ÐеÑÑно, (R)Пока отвергнуть, (B)Плохой? "
#, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "ошибка уÑтановки ÑƒÑ€Ð¾Ð²Ð½Ñ Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ Ð¿Ñ€Ð¸Ð²Ñзки TOFU в %s\n"
+
+#, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "ошибка при Ñмене правила TOFU: %s\n"
#. TRANSLATORS: The tilde ('~') is used here to indicate a
#. * non-breakable space
-#, fuzzy, c-format
-#| msgid "%d year"
-#| msgid_plural "%d years"
+#, c-format
msgid "%d~year"
msgid_plural "%d~years"
-msgstr[0] "%d год"
-msgstr[1] "%d года"
-msgstr[2] "%d лет"
+msgstr[0] "%d~год"
+msgstr[1] "%d~года"
+msgstr[2] "%d~лет"
-#, fuzzy, c-format
-#| msgid "%d month"
-#| msgid_plural "%d months"
+#, c-format
msgid "%d~month"
msgid_plural "%d~months"
-msgstr[0] "%d меÑÑц"
-msgstr[1] "%d меÑÑца"
-msgstr[2] "%d меÑÑцев"
+msgstr[0] "%d~меÑÑц"
+msgstr[1] "%d~меÑÑца"
+msgstr[2] "%d~меÑÑцев"
#, c-format
msgid "%d~day"
msgid_plural "%d~days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d~день"
+msgstr[1] "%d~днÑ"
+msgstr[2] "%d~дней"
-#, fuzzy, c-format
-#| msgid "%d hour"
-#| msgid_plural "%d hours"
+#, c-format
msgid "%d~hour"
msgid_plural "%d~hours"
-msgstr[0] "%d чаÑ"
-msgstr[1] "%d чаÑа"
-msgstr[2] "%d чаÑов"
+msgstr[0] "%d~чаÑ"
+msgstr[1] "%d~чаÑа"
+msgstr[2] "%d~чаÑов"
-#, fuzzy, c-format
-#| msgid "%d minute"
-#| msgid_plural "%d minutes"
+#, c-format
msgid "%d~minute"
msgid_plural "%d~minutes"
-msgstr[0] "%d минута"
-msgstr[1] "%d минуты"
-msgstr[2] "%d минут"
+msgstr[0] "%d~минута"
+msgstr[1] "%d~минуты"
+msgstr[2] "%d~минут"
-#, fuzzy, c-format
-#| msgid "%d second"
-#| msgid_plural "%d seconds"
+#, c-format
msgid "%d~second"
msgid_plural "%d~seconds"
-msgstr[0] "%d Ñекунда"
-msgstr[1] "%d Ñекунды"
-msgstr[2] "%d Ñекунд"
+msgstr[0] "%d~Ñекунда"
+msgstr[1] "%d~Ñекунды"
+msgstr[2] "%d~Ñекунд"
#, c-format
msgid "Have never verified a message signed by key %s!\n"
msgstr "СообщениÑ, подпиÑанные ключом %s, никогда не проверÑлиÑÑŒ!\n"
-#, fuzzy, c-format
-#| msgid "Failed to collect signature statistics for \"%s\" (key %s)\n"
+#, c-format
msgid ""
"Failed to collect signature statistics for \"%s\"\n"
"(key %s)\n"
-msgstr "Ðе удалоÑÑŒ Ñобрать ÑтатиÑтику Ð´Ð»Ñ \"%s\" (ключ %s)\n"
+msgstr ""
+"Ðе удалоÑÑŒ Ñобрать ÑтатиÑтику подпиÑей Ð´Ð»Ñ \"%s\"\n"
+"(ключ %s)\n"
-#, fuzzy, c-format
-#| msgid "Verified 0 messages signed by \"%s\" (key: %s, policy: %s)."
+#, c-format
msgid "Verified %ld messages signed by \"%s\"."
-msgstr "Проверено 0 Ñообщений, подпиÑанных \"%s\" (ключ: %s, правило: %s)."
-
-#, fuzzy, c-format
-#| msgid ""
-#| "Verified %ld message signed by \"%s\" (key: %s, policy: %s) in the past "
-#| "%s."
-#| msgid_plural ""
-#| "Verified %ld messages signed by \"%s\" (key: %s, policy: %s) in the past "
-#| "%s."
+msgstr "Проверено %ld Ñообщений, подпиÑанных \"%s\"."
+
+#, c-format
msgid ""
"Verified %ld message signed by \"%s\"\n"
"in the past %s."
@@ -5658,11 +5614,14 @@ msgid_plural ""
"Verified %ld messages signed by \"%s\"\n"
"in the past %s."
msgstr[0] ""
-"Проверено %ld Ñообщение, подпиÑанное \"%s\" (ключ: %s, правило: %s) за %s."
+"Проверено %ld Ñообщение, подпиÑанное \"%s\"\n"
+" за %s."
msgstr[1] ""
-"Проверены %ld ÑообщениÑ, подпиÑанные \"%s\" (ключ: %s, правило: %s) за %s."
+"Проверены %ld ÑообщениÑ, подпиÑанные \"%s\"\n"
+" за %s."
msgstr[2] ""
-"Проверено %ld Ñообщений, подпиÑанных \"%s\" (ключ: %s, правило: %s) за %s."
+"Проверено %ld Ñообщений, подпиÑанных \"%s\"\n"
+" за %s."
#, c-format
msgid "The most recent message was verified %s ago."
@@ -5692,8 +5651,23 @@ msgid_plural ""
" %s\n"
"to mark it as being bad.\n"
msgstr[0] ""
+"Внимание: еÑли вы видели больше %ld ÑообщениÑ, подпиÑанного Ñтим ключом, "
+"Ñтот ключ может быть подделкой! Внимательно проверьте, не внеÑены ли в Ð°Ð´Ñ€ÐµÑ "
+"Ñлектронной почты небольшие изменениÑ. Ð’ Ñлучае подозрений пометьте ключ как "
+"некачеÑтвенный командой\n"
+" %s\n"
msgstr[1] ""
+"Внимание: еÑли вы видели больше %ld Ñообщений, подпиÑанных Ñтим ключом, Ñтот "
+"ключ может быть подделкой! Внимательно проверьте, не внеÑены ли в Ð°Ð´Ñ€ÐµÑ "
+"Ñлектронной почты небольшие изменениÑ. Ð’ Ñлучае подозрений пометьте ключ как "
+"некачеÑтвенный командой\n"
+" %s\n"
msgstr[2] ""
+"Внимание: еÑли вы видели больше %ld Ñообщений, подпиÑанных Ñтим ключом, Ñтот "
+"ключ может быть подделкой! Внимательно проверьте, не внеÑены ли в Ð°Ð´Ñ€ÐµÑ "
+"Ñлектронной почты небольшие изменениÑ. Ð’ Ñлучае подозрений пометьте ключ как "
+"некачеÑтвенный командой\n"
+" %s\n"
#, c-format
msgid "error opening TOFU database: %s\n"
@@ -5757,6 +5731,10 @@ msgstr "проверÑÑ‚ÑŒ таблицу Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ Ð¿Ñ€Ð¸ модели дÐ
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "обновлÑÑ‚ÑŒ таблицу Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ Ð¿Ñ€Ð¸ модели Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ '%s' не нужно\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "открытый ключ %s не найден: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "выполните --check-trustdb, пожалуйÑта\n"
@@ -5834,6 +5812,11 @@ msgstr "[ неизвеÑтно ]"
msgid "[ undef ]"
msgstr "[неопределено]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "никогда"
+
msgid "[marginal]"
msgstr "[ ограничено ]"
@@ -6083,7 +6066,7 @@ msgstr "отпечаток на карте не Ñовпадает Ñ Ð·Ð°Ð¿Ñ€Ð¾
#, c-format
msgid "card does not support digest algorithm %s\n"
-msgstr "карта не поддерживает Ñ…Ñш-функцию %s\n"
+msgstr "карта не поддерживает хеш-функцию %s\n"
#, c-format
msgid "signatures created so far: %lu\n"
@@ -6350,7 +6333,7 @@ msgstr "иÑпользуетÑÑ Ñхема проверки: %s"
#, c-format
msgid "a %u bit hash is not valid for a %u bit %s key\n"
-msgstr "%u-битный Ñ…Ñш недопуÑтим Ð´Ð»Ñ %u-битного ключа %s\n"
+msgstr "%u-битный хеш недопуÑтим Ð´Ð»Ñ %u-битного ключа %s\n"
msgid "(this is the MD2 algorithm)\n"
msgstr "(Ñто алгоритм MD2)\n"
@@ -6454,7 +6437,7 @@ msgstr "Ñтрока %d: ошибка Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ ÐºÐ¾Ð´Ð° подпиÑÑ‹
#, c-format
msgid "line %d: invalid hash algorithm given\n"
-msgstr "Ñтрока %d: задана недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…Ñш-функциÑ\n"
+msgstr "Ñтрока %d: задана недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…ÐµÑˆ-функциÑ\n"
#, c-format
msgid "line %d: invalid authority-key-id\n"
@@ -6699,7 +6682,7 @@ msgid "|NAME|use cipher algorithm NAME"
msgstr "|NAME|иÑпользовать алгоритм ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ NAME"
msgid "|NAME|use message digest algorithm NAME"
-msgstr "|NAME|иÑпользовать Ñ…Ñш-функцию NAME"
+msgstr "|NAME|иÑпользовать хеш-функцию NAME"
msgid "Usage: @GPGSM@ [options] [files] (-h for help)"
msgstr "Вызов: @GPGSM@ [параметры] [файлы] (-h Ð´Ð»Ñ Ð¿Ð¾Ð´Ñказки)"
@@ -6844,11 +6827,11 @@ msgstr ""
#, c-format
msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n"
-msgstr "Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %d (%s) Ð´Ð»Ñ %d не поддерживаетÑÑ; иÑпользую %s\n"
+msgstr "хеш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %d (%s) Ð´Ð»Ñ %d не поддерживаетÑÑ; иÑпользую %s\n"
#, c-format
msgid "hash algorithm used for signer %d: %s (%s)\n"
-msgstr "Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи %d: %s (%s)\n"
+msgstr "хеш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи %d: %s (%s)\n"
#, c-format
msgid "checking for qualified certificate failed: %s\n"
@@ -6867,7 +6850,7 @@ msgstr " Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ñертификата Ñ ID 0x%08lX\n"
msgid ""
"invalid signature: message digest attribute does not match computed one\n"
msgstr ""
-"недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ: атрибут Ñ…Ñш-функции ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð½Ðµ ÑоответÑтвует "
+"недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ: атрибут хеш-функции ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð½Ðµ ÑоответÑтвует "
"вычиÑленному\n"
msgid "Good signature from"
@@ -7050,7 +7033,7 @@ msgstr "запиÑÑŒ неподдерживаемого типа в '%s', ÑÑ‚Ñ€
#, c-format
msgid "invalid issuer hash in '%s' line %u\n"
-msgstr "неправильный Ñ…Ñш Ð¸Ð·Ð´Ð°Ñ‚ÐµÐ»Ñ Ð² '%s', Ñтрока %u\n"
+msgstr "неправильный хеш Ð¸Ð·Ð´Ð°Ñ‚ÐµÐ»Ñ Ð² '%s', Ñтрока %u\n"
#, c-format
msgid "no issuer DN in '%s' line %u\n"
@@ -7062,7 +7045,7 @@ msgstr "недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° времени в '%s', Ñтрока
#, c-format
msgid "WARNING: invalid cache file hash in '%s' line %u\n"
-msgstr "Внимание: недопуÑтимый Ñ…Ñш файла буфера в '%s', Ñтрока %u\n"
+msgstr "Внимание: недопуÑтимый хеш файла буфера в '%s', Ñтрока %u\n"
msgid "detected errors in cache dir file\n"
msgstr "в файле каталога буфера обнаружены ошибки\n"
@@ -7084,15 +7067,15 @@ msgstr "ошибка Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ '%s' в '%s': %s\n"
#, c-format
msgid "can't hash '%s': %s\n"
-msgstr "невозможно получить Ñ…Ñш '%s': %s\n"
+msgstr "невозможно получить хеш '%s': %s\n"
#, c-format
msgid "error setting up MD5 hash context: %s\n"
-msgstr "ошибка уÑтановки контекÑта Ñ…Ñша MD5: %s\n"
+msgstr "ошибка уÑтановки контекÑта хеша MD5: %s\n"
#, c-format
msgid "error hashing '%s': %s\n"
-msgstr "ошибка при получении Ñ…Ñша '%s': %s\n"
+msgstr "ошибка при получении хеша '%s': %s\n"
#, c-format
msgid "invalid formatted checksum for '%s'\n"
@@ -7181,7 +7164,7 @@ msgstr "ошибка Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… из файла буферÐ
#, c-format
msgid "unknown hash algorithm '%s'\n"
-msgstr "недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…Ñш-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ '%s'\n"
+msgstr "недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ…ÐµÑˆ-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ '%s'\n"
#, c-format
msgid "gcry_md_open for algorithm %d failed: %s\n"
@@ -7922,7 +7905,7 @@ msgstr "ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¾Ñ‚Ð²ÐµÑ‚Ñ‡Ð¸ÐºÐ° OCSP на '%s': %s\n"
#, c-format
msgid "hashing the OCSP response for '%s' failed: %s\n"
-msgstr "Ñбой Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ…Ñша ответа OCSP Ð´Ð»Ñ '%s': %s\n"
+msgstr "Ñбой Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ…ÐµÑˆÐ° ответа OCSP Ð´Ð»Ñ '%s': %s\n"
msgid "not signed by a default OCSP signer's certificate"
msgstr "не подпиÑано оÑновным Ñертификатом подпиÑывающего OCSP"
@@ -7975,7 +7958,7 @@ msgstr "иÑпользуетÑÑ Ð¾Ñ‚Ð²ÐµÑ‚Ñ‡Ð¸Ðº OCSP '%s'\n"
#, c-format
msgid "failed to establish a hashing context for OCSP: %s\n"
-msgstr "Ñбой при уÑтановлении контекÑта Ñ…Ñша Ð´Ð»Ñ OCSP: %s\n"
+msgstr "Ñбой при уÑтановлении контекÑта хеша Ð´Ð»Ñ OCSP: %s\n"
#, c-format
msgid "error getting OCSP status for target certificate: %s\n"
@@ -8086,7 +8069,7 @@ msgid "certificate chain is good\n"
msgstr "Ñ…Ð¾Ñ€Ð¾ÑˆÐ°Ñ Ñ†ÐµÐ¿Ð¾Ñ‡ÐºÐ° Ñертификатов\n"
msgid "DSA requires the use of a 160 bit hash algorithm\n"
-msgstr "DSA требует 160-битной Ñ…Ñш-функции\n"
+msgstr "DSA требует 160-битной хеш-функции\n"
msgid "certificate should not have been used for CRL signing\n"
msgstr ""
@@ -8206,7 +8189,7 @@ msgid "do not allow the reuse of old passphrases"
msgstr "не разрешать повторное иÑпользование Ñтарых фраз-паролей"
msgid "|N|set the Pinentry timeout to N seconds"
-msgstr "|N|уÑтановить Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð²Ð²Ð¾Ð´Ð° PIN N Ñекунд"
+msgstr "|N|уÑтановить Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð²Ð²Ð¾Ð´Ð° Ð¿Ð°Ñ€Ð¾Ð»Ñ N Ñекунд"
msgid "|NAME|use NAME as default secret key"
msgstr "|NAME|иÑпользовать NAME как оÑновной Ñекретный ключ"
@@ -8497,193 +8480,3 @@ msgid ""
msgstr ""
"СинтакÑиÑ: gpg-check-pattern [параметры] файл_образцов\n"
"Проверить фразу-пароль, поÑтупающую из stdin, по файлу образцов\n"
-
-#~ msgid "you found a bug ... (%s:%d)\n"
-#~ msgstr "Вы нашли ошибку в программе ... (%s:%d)\n"
-
-#~ msgid "%d user ID without valid self-signature detected\n"
-#~ msgid_plural "%d user IDs without valid self-signatures detected\n"
-#~ msgstr[0] "обнаружен %d ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð±ÐµÐ· дейÑтвительной ÑамоподпиÑи\n"
-#~ msgstr[1] "обнаружены %d ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð±ÐµÐ· дейÑтвительной ÑамоподпиÑи\n"
-#~ msgstr[2] "обнаружено %d ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð±ÐµÐ· дейÑтвительной ÑамоподпиÑи\n"
-
-#~ msgid "moving a key signature to the correct place\n"
-#~ msgstr "перемещение подпиÑи ключа в нужное меÑто\n"
-
-#~ msgid "%d day"
-#~ msgid_plural "%d days"
-#~ msgstr[0] "%d день"
-#~ msgstr[1] "%d днÑ"
-#~ msgstr[2] "%d дней"
-
-# I believe the translation produces an equivalent Russian output
-# for that code snippet in g10/tofu.c -- ineiev
-#~ msgid "TOFU: few signatures %d message %s"
-#~ msgid_plural "TOFU: few signatures %d messages %s"
-#~ msgstr[0] ""
-#~ "Внимание: еÑли Ð’Ñ‹ думаете, что видели больше %d ÑообщениÑ, подпиÑанного "
-#~ "Ñтим ключом, то Ñтот ключ может быть подделкой! Проверьте внимательно, не "
-#~ "внеÑены ли в Ð°Ð´Ñ€ÐµÑ Ñлектронной почты небольшие Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ (напр., "
-#~ "дополнительные пробелы). Ð’ Ñлучае подозрений отметьте его как плохой Ñ "
-#~ "помощью '%s'.\n"
-#~ " "
-#~ msgstr[1] ""
-#~ "Внимание: еÑли Ð’Ñ‹ думаете, что видели больше %d Ñообщений, подпиÑанных "
-#~ "Ñтим ключом, то Ñтот ключ может быть подделкой! Проверьте внимательно, не "
-#~ "внеÑены ли в Ð°Ð´Ñ€ÐµÑ Ñлектронной почты небольшие Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ (напр., "
-#~ "дополнительные пробелы). Ð’ Ñлучае подозрений отметьте его как плохой Ñ "
-#~ "помощью '%s'.\n"
-#~ " "
-#~ msgstr[2] ""
-#~ "Внимание: еÑли Ð’Ñ‹ думаете, что видели больше %d Ñообщений, подпиÑанных "
-#~ "Ñтим ключом, то Ñтот ключ может быть подделкой! Проверьте внимательно, не "
-#~ "внеÑены ли в Ð°Ð´Ñ€ÐµÑ Ñлектронной почты небольшие Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ (напр., "
-#~ "дополнительные пробелы). Ð’ Ñлучае подозрений отметьте его как плохой Ñ "
-#~ "помощью '%s'.\n"
-#~ " "
-
-#~ msgid "key specification '%s' is ambiguous\n"
-#~ msgstr "ÑÐ¿ÐµÑ†Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð° '%s' неоднозначна\n"
-
-#~ msgid "'%s' matches at least:\n"
-#~ msgstr "'%s' ÑоответÑтвует по меньшей мере:\n"
-
-#~ msgid "%d signatures not checked due to missing keys\n"
-#~ msgstr "%d подпиÑей не проверено за отÑутÑтвием ключей\n"
-
-#~ msgid "%d signatures not checked due to errors\n"
-#~ msgstr "%d подпиÑей не проверено из-за ошибок\n"
-
-#~ msgid "1 user ID without valid self-signature detected\n"
-#~ msgstr "обнаружен 1 ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð±ÐµÐ· дейÑтвительной ÑамоподпиÑи\n"
-
-#~ msgid "Deleted %d signatures.\n"
-#~ msgstr "Удалено %d подпиÑей.\n"
-
-#~ msgid "User ID \"%s\": %d signatures removed\n"
-#~ msgstr "ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\": %d подпиÑей удалено\n"
-
-#~ msgid ""
-#~ "You need a Passphrase to protect your secret key.\n"
-#~ "\n"
-#~ msgstr ""
-#~ "Ð”Ð»Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ñ‹ Ñекретного ключа необходима фраза-пароль.\n"
-#~ "\n"
-
-#~ msgid ""
-#~ "Please enter a passphrase to protect the off-card backup of the new "
-#~ "encryption key."
-#~ msgstr ""
-#~ "Введите фразу-пароль Ð´Ð»Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ñ‹ архивной копии нового ключа Ð´Ð»Ñ "
-#~ "шифрованиÑ."
-
-#~ msgid "passphrase not correctly repeated; try again"
-#~ msgstr "фраза-пароль повторена неверно; попробуйте еще раз"
-
-#~ msgid "%s.\n"
-#~ msgstr "%s.\n"
-
-#~ msgid ""
-#~ "You don't want a passphrase - this is probably a *bad* idea!\n"
-#~ "I will do it anyway. You can change your passphrase at any time,\n"
-#~ "using this program with the option \"--edit-key\".\n"
-#~ "\n"
-#~ msgstr ""
-#~ "Хотите обойтиÑÑŒ без фразы-паролÑ? Скорее вÑего, Ñто ПЛОХÐЯ мыÑль!\n"
-#~ "Работа будет продолжена. Ð’Ñ‹ можете Ñменить фразу-пароль в любое времÑ,\n"
-#~ "запуÑтив данную программу Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ \"--edit-key\".\n"
-#~ "\n"
-
-#~ msgid "storing key onto card failed: %s\n"
-#~ msgstr "Ñбой ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð° на карте: %s\n"
-
-#~ msgid "1 good signature\n"
-#~ msgstr "1 Ñ…Ð¾Ñ€Ð¾ÑˆÐ°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ\n"
-
-#~ msgid "renaming '%s' to '%s' failed: %s\n"
-#~ msgstr "Ñбой при переименовании '%s' в '%s': %s\n"
-
-#~ msgid "%lu keys cached (%lu signatures)\n"
-#~ msgstr "%lu ключей помещено в буфер (%lu подпиÑей)\n"
-
-#~ msgid "refreshing 1 key from %s\n"
-#~ msgstr "обновление 1 ключа из %s\n"
-
-#~ msgid "sending key %s to %s server %s\n"
-#~ msgstr "отправка ключа %s на Ñервер %s %s\n"
-
-#~ msgid "public key %s is %lu seconds newer than the signature\n"
-#~ msgstr "открытый ключ %s на %lu Ñекунд новее подпиÑи\n"
-
-#~ msgid ""
-#~ "key %s was created %lu seconds in the future (time warp or clock "
-#~ "problem)\n"
-#~ msgstr ""
-#~ "ключ %s Ñоздан на %lu Ñекунд в будущем (Ð¿ÐµÑ‚Ð»Ñ Ð²Ð¾ времени или проблемы Ñ "
-#~ "чаÑами)\n"
-
-#~ msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n"
-#~ msgstr ""
-#~ "требуетÑÑ %d Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð½Ñ‹Ð¼ доверием, %d Ñ Ð¿Ð¾Ð»Ð½Ñ‹Ð¼, модель Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ %s\n"
-
-#~ msgid "cleared passphrase cached with ID: %s\n"
-#~ msgstr "в буфере Ñброшена фраза-пароль Ñ Ð¸Ð½Ð´ÐµÐºÑом %s\n"
-
-#, fuzzy
-#~| msgid "failed to store the key: %s\n"
-#~ msgid "Failed to open the keyring DB.\n"
-#~ msgstr "Ñбой ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð°: %s\n"
-
-#, fuzzy
-#~| msgid "failed to open '%s': %s\n"
-#~ msgid "Failed to parse '%s'.\n"
-#~ msgstr "не могу открыть '%s': %s\n"
-
-#, fuzzy
-#~| msgid "error locking keybox: %s\n"
-#~ msgid "error looking up secret key \"%s\": %s\n"
-#~ msgstr "ошибка блокировки щита Ñ ÐºÐ»ÑŽÑ‡Ð°Ð¼Ð¸: %s\n"
-
-#~ msgid "Please select at most one subkey.\n"
-#~ msgstr "Выделите не более одного подключа.\n"
-
-#~ msgid "apparently no running dirmngr\n"
-#~ msgstr "видимо, dirmngr не работает\n"
-
-#~ msgid "no running dirmngr - starting one\n"
-#~ msgstr "dirmngr не выполнÑетÑÑ - запуÑк\n"
-
-#~ msgid "malformed %s environment variable\n"
-#~ msgstr "Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ %s\n"
-
-#~ msgid "dirmngr protocol version %d is not supported\n"
-#~ msgstr "протокол dirmngr верÑии %d не поддерживаетÑÑ\n"
-
-#~ msgid "can't connect to the dirmngr - trying fall back\n"
-#~ msgstr "не могу подключитьÑÑ Ðº dirmngr - пробую запаÑной вариант\n"
-
-#~ msgid "export keys in an S-expression based format"
-#~ msgstr "ÑкÑпортировать ключи в формате на оÑнове S-выражений"
-
-#~ msgid "Directory Manager"
-#~ msgstr "Управление каталогами"
-
-#~ msgid "toggle between the secret and public key listings"
-#~ msgstr "переключение между проÑмотром открытых и закрытых ключей"
-
-#~ msgid "Please use the command \"toggle\" first.\n"
-#~ msgstr "Сначала воÑпользуйтеÑÑŒ командой \"toggle\".\n"
-
-#~ msgid "Passphrase"
-#~ msgstr "Фраза-пароль"
-
-#~ msgid "use temporary files to pass data to keyserver helpers"
-#~ msgstr "передавать данные в Ñервер Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ временных файлов"
-
-#~ msgid "do not delete temporary files after using them"
-#~ msgstr "не удалÑÑ‚ÑŒ временные файлы поÑле иÑпользованиÑ"
-
-#~ msgid "WARNING: keyserver option '%s' is not used on this platform\n"
-#~ msgstr ""
-#~ "Ð’ÐИМÐÐИЕ: параметр Ñервера ключей `%s' на данной платформе не "
-#~ "иÑпользуетÑÑ\n"
diff --git a/po/sk.po b/po/sk.po
index 3bf2c2b..bf23106 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -465,6 +465,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "chyba pri posielaní na `%s': %s\n"
#, fuzzy, c-format
+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"
@@ -482,10 +486,6 @@ msgid "directory '%s' created\n"
msgstr "%s: adresár vytvorený\n"
#, fuzzy, c-format
-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 "stat() failed for '%s': %s\n"
msgstr "databáza dôvery: procedúra read() (n=%d) zlyhala: %s\n"
@@ -1960,13 +1960,13 @@ msgstr "zmeni» heslo"
msgid "export keys"
msgstr "exportova» kµúèe"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "exportova» kµúèe na server kµúèov"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importova» kµúèe zo servera kµúèov"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "vyhµada» kµúèe na serveri kµúèov"
msgid "update all keys from a keyserver"
@@ -2571,6 +2571,9 @@ msgstr "konflikt èasového razítka"
msgid "|FD|write status info to this FD"
msgstr "|FD|zapísa» informácie o stave do tohto FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Pou¾itie: gpgv [mo¾nosti] [súbory] (-h pre pomoc)"
@@ -4053,6 +4056,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "Neexistuje identifikátor u¾ívateµa s indexom %d\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "zaokrúhlené na %u bitov\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr ""
@@ -4069,11 +4077,6 @@ msgstr "Akú veµkos» kµúèa si prajete? (1024) "
msgid "Requested keysize is %u bits\n"
msgstr "Po¾adovaná då¾ka kµúèa je %u bitov.\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "zaokrúhlené na %u bitov\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5749,14 +5752,6 @@ msgstr ""
msgid "error updating TOFU database: %s\n"
msgstr "chyba pri posielaní na `%s': %s\n"
-#, fuzzy, c-format
-msgid "public key %s not found: %s\n"
-msgstr "verejný kµúè %08lX nebol nájdený: %s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "chyba pri èítaní `%s': %s\n"
-
#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5835,14 +5830,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5850,6 +5845,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "chyba pri èítaní `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "chyba pri vytváraní hesla: %s\n"
@@ -6004,6 +6003,10 @@ msgstr "nie je nutné kontrolova» databázu dôvery\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "nie je nutné kontrolova» databázu dôvery\n"
+#, fuzzy, c-format
+msgid "public key %s not found: %s\n"
+msgstr "verejný kµúè %08lX nebol nájdený: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "prosím vykonajte --check-trustdb\n"
@@ -6081,6 +6084,10 @@ msgstr "neznáme"
msgid "[ undef ]"
msgstr ""
+#, fuzzy
+msgid "[ never ]"
+msgstr "nikdy "
+
msgid "[marginal]"
msgstr ""
diff --git a/po/sv.po b/po/sv.po
index a88dd81..996912a 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -516,6 +516,12 @@ msgstr "fel vid hämtning av nonce för uttaget\n"
msgid "error binding socket to '%s': %s\n"
msgstr "fel när \"%s\" bands till uttag: %s\n"
+# Extension är vad? FIXME
+#, fuzzy, c-format
+#| msgid "Warning: unsafe permissions on %s \"%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"
@@ -535,12 +541,6 @@ msgstr "%s: kan inte skapa katalog: %s\n"
msgid "directory '%s' created\n"
msgstr "katalogen \"%s\" skapades\n"
-# Extension är vad? FIXME
-#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgid "can't set permissions of '%s': %s\n"
-msgstr "Varning: osäkra rättigheter på %s \"%s\"\n"
-
#, fuzzy, c-format
#| msgid "stat() failed for `%s': %s\n"
msgid "stat() failed for '%s': %s\n"
@@ -2019,13 +2019,13 @@ msgstr "ändra en lösenfras"
msgid "export keys"
msgstr "exportera nycklar"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "exportera nycklar till en nyckelserver"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "importera nycklar från en nyckelserver"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "sök efter nycklar hos en nyckelserver"
msgid "update all keys from a keyserver"
@@ -2652,6 +2652,9 @@ msgstr "utfärda enbart en varning när tidsstämpeln är orimlig"
msgid "|FD|write status info to this FD"
msgstr "|FD|skriv statusinformation till denna FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Användning: gpgv [flaggor] [filer] (-h för hjälp)"
@@ -4129,6 +4132,11 @@ msgstr "Inte en giltig nyckelhash (förväntade 40 hexadecimala siffror)\n"
msgid "No key with this keygrip\n"
msgstr "Ingen nyckel med denna nyckelhash\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "avrundade uppåt till %u bitar\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "%s-nycklar kan vara mellan %u och %u bitar långa.\n"
@@ -4145,11 +4153,6 @@ msgstr "Vilken nyckelstorlek vill du ha? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "Den efterfrågade nyckelstorleken är %u bitar\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "avrundade uppåt till %u bitar\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5882,15 +5885,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "fel vid sändning av %s-kommando: %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "publika nyckeln %s hittades inte: %s\n"
-
-#, fuzzy, c-format
-#| msgid "error storing flags: %s\n"
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "fel vid lagring av flaggor: %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5971,14 +5965,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5986,6 +5980,11 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+#| msgid "error storing flags: %s\n"
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "fel vid lagring av flaggor: %s\n"
+
+#, fuzzy, c-format
#| msgid "error creating a pipe: %s\n"
msgid "error changing TOFU policy: %s\n"
msgstr "fel när ett rör skapades: %s\n"
@@ -6151,6 +6150,10 @@ msgid "no need for a trustdb update with '%s' trust model\n"
msgstr ""
"det behövs ingen uppdatering av tillitsdatabasen med tillitsmodellen \"%s\"\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "publika nyckeln %s hittades inte: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "gör en kontroll av tillitsdatabasen --check-trustdb\n"
@@ -6241,6 +6244,11 @@ msgstr "[ okänt ]"
msgid "[ undef ]"
msgstr "[ odefinierad ]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "aldrig"
+
msgid "[marginal]"
msgstr "[ marginell ]"
diff --git a/po/tr.po b/po/tr.po
index c9417fb..c40022d 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -483,6 +483,11 @@ msgstr "soket için tuz alınırken hata\n"
msgid "error binding socket to '%s': %s\n"
msgstr "soket `%s'e bağlanırken hata: %s\n"
+#, fuzzy, c-format
+#| msgid "Warning: unsafe permissions on %s \"%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"
@@ -503,11 +508,6 @@ msgid "directory '%s' created\n"
msgstr "dizin `%s' oluÅŸturuldu\n"
#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgid "can't set permissions of '%s': %s\n"
-msgstr "UYARI: %s üzerinde izinler güvensiz: \"%s\"\n"
-
-#, fuzzy, c-format
#| msgid "stat() failed for `%s': %s\n"
msgid "stat() failed for '%s': %s\n"
msgstr "%s için stat() başarısız oldu: %s\n"
@@ -1964,13 +1964,13 @@ msgstr "anahtar parolası değiştirir"
msgid "export keys"
msgstr "anahtarları gönderir"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "anahtarları bir anahtar sunucusuna gönderir"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "anahtarları bir anahtar sunucusundan indirir"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "bir anahtar sunucusunda anahtarları arar"
msgid "update all keys from a keyserver"
@@ -2580,6 +2580,9 @@ msgstr "zaman damgası çelişkilerini uyarı olarak bildirir"
msgid "|FD|write status info to this FD"
msgstr "|FD|durum bilgisini bu FD'ye yazar"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "Kullanımı: gpgv [seçenekler] [dosyalar] (yardım için -h)"
@@ -4083,6 +4086,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "%d indisli bir yardımcı anahtar yok\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "%u bite yuvarlandı\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "%s anahtarları %u bit ile %u bit arasında olmalı.\n"
@@ -4099,11 +4107,6 @@ msgstr "Ä°stediÄŸiniz anahtar uzunluÄŸu nedir? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "Ä°stenen anahtar uzunluÄŸu: %u bit\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "%u bite yuvarlandı\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5808,15 +5811,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "%s komutu gönderilirken hata: %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "genel anahtar %s yok: %s\n"
-
-#, fuzzy, c-format
-#| msgid "error storing flags: %s\n"
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "bayraklar saklanırken hata: %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5897,14 +5891,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5912,6 +5906,11 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+#| msgid "error storing flags: %s\n"
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "bayraklar saklanırken hata: %s\n"
+
+#, fuzzy, c-format
#| msgid "error creating a pipe: %s\n"
msgid "error changing TOFU policy: %s\n"
msgstr "boru oluÅŸturulurken hata: %s\n"
@@ -6072,6 +6071,10 @@ msgstr "`%s' güvence modelli güvence veritabanı sınaması için gereksiz\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "`%s' güvence modelli güvence veritabanı güncellemesi için gereksiz\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "genel anahtar %s yok: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "lütfen bir --check-trustdb yapın\n"
@@ -6151,6 +6154,11 @@ msgstr "[ bilinmeyen ]"
msgid "[ undef ]"
msgstr "[ tanımsız ]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "asla "
+
msgid "[marginal]"
msgstr "[ şöyle böyle ]"
diff --git a/po/uk.po b/po/uk.po
index b2d6860..0a1fdef 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -2,12 +2,12 @@
# Copyright (C) 2011 Free Software Foundation, Inc.
# This file is distributed under the same license as the GnuPG package.
#
-# Yuri Chornoivan <yurchor@ukr.net>, 2011, 2014, 2015.
+# Yuri Chornoivan <yurchor@ukr.net>, 2011, 2014, 2015, 2016.
msgid ""
msgstr ""
"Project-Id-Version: GNU gnupg 2.1.0\n"
"Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2015-10-23 19:33+0300\n"
+"PO-Revision-Date: 2016-05-10 18:21+0300\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
"Language: uk\n"
@@ -366,10 +366,8 @@ msgstr "заборонити клієнтам позначати ключі Ñк
msgid "allow presetting passphrase"
msgstr "дозволити попереднє вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ"
-#, fuzzy
-#| msgid "allow caller to override the pinentry"
msgid "disallow caller to override the pinentry"
-msgstr "дозволити функції виклику перевизначати pinentry"
+msgstr "заборонити функції виклику перевизначати pinentry"
msgid "allow passphrase to be prompted through Emacs"
msgstr "дозволити запит Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð· Emacs"
@@ -439,6 +437,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "помилка під Ñ‡Ð°Ñ Ñпроби прив’ÑÐ·ÑƒÐ²Ð°Ð½Ð½Ñ Ñокета до «%s»: %s\n"
#, c-format
+msgid "can't set permissions of '%s': %s\n"
+msgstr "не вдалоÑÑ Ð²Ñтановити права доÑтупу до «%s»: %s\n"
+
+#, c-format
msgid "listen() failed: %s\n"
msgstr "помилка listen(): %s\n"
@@ -454,11 +456,6 @@ msgstr "не вдалоÑÑ Ñтворити каталог «%s»: %s\n"
msgid "directory '%s' created\n"
msgstr "Ñтворено каталог «%s»\n"
-#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgid "can't set permissions of '%s': %s\n"
-msgstr "Увага: Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð² доÑтупу не Ñ” безпечним Ð´Ð»Ñ %s — «%s»\n"
-
#, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "помилка stat() щодо «%s»: %s\n"
@@ -721,10 +718,9 @@ msgstr "помилка під Ñ‡Ð°Ñ Ñпроби ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑ
msgid "error forking process: %s\n"
msgstr "помилка під Ñ‡Ð°Ñ Ñпроби Ñ€Ð¾Ð·Ð³Ð°Ð»ÑƒÐ¶ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу: %s\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 "не вдалоÑÑ Ð´Ð¾Ñ‡ÐµÐºÐ°Ñ‚Ð¸ÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу %d: %s\n"
+msgstr "не вдалоÑÑ Ð´Ð¾Ñ‡ÐµÐºÐ°Ñ‚Ð¸ÑÑ Ð¿ÐµÑ€ÐµÑ€Ð¸Ð²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу: %s\n"
#, c-format
msgid "error running '%s': probably not installed\n"
@@ -763,10 +759,9 @@ msgstr "ÑкаÑовано кориÑтувачем\n"
msgid "problem with the agent\n"
msgstr "проблема з агентом\n"
-#, fuzzy, c-format
-#| msgid "problem with the agent: %s\n"
+#, c-format
msgid "problem with the agent (unexpected response \"%s\")\n"
-msgstr "проблема з агентом: %s\n"
+msgstr "проблема із агентом (неочікувана відповідь «%s»)\n"
#, c-format
msgid "can't disable core dumps: %s\n"
@@ -1166,10 +1161,9 @@ msgstr ""
"Ñимволи quoted printable у кодуванні ASCII — ймовірно, викориÑтано "
"помилковий MTA\n"
-#, fuzzy, c-format
-#| msgid "not human readable"
+#, c-format
msgid "[ not human readable (%zu bytes: %s%s) ]"
-msgstr "незручне Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ"
+msgstr "[ незручне Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ (%zu байтів: %s%s) ]"
msgid ""
"a notation name must have only printable characters or spaces, and end with "
@@ -1187,19 +1181,11 @@ msgstr "назва примітки не повинна міÑтити більÑ
msgid "a notation value must not use any control characters\n"
msgstr "у значенні примітки не повинно міÑтитиÑÑ ÐºÐµÑ€Ñ–Ð²Ð½Ð¸Ñ… Ñимволів\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 "назва примітки не повинна міÑтити більше за один Ñимвол «@»\n"
+msgstr "назва Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ може міÑтити Ñимволів «=»\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 ""
-"назва примітки має ÑкладатиÑÑ Ð· друкованих Ñимволів або пробілів Ñ– "
-"завершуватиÑÑ Ñимволом «=»\n"
+msgstr "назва примітки має ÑкладатиÑÑ Ð· друкованих Ñимволів або пробілів\n"
msgid "WARNING: invalid notation data found\n"
msgstr "УВÐГÐ: виÑвлено некоректні дані примітки\n"
@@ -1211,19 +1197,17 @@ msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ð¿ÑƒÑтити через прокÑÑ– запÐ
msgid "Enter passphrase: "
msgstr "Введіть пароль: "
-#, fuzzy, c-format
-#| msgid "error creating keyring '%s': %s\n"
+#, c-format
msgid "error getting version from '%s': %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñховища ключів «%s»: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… щодо верÑÑ–Ñ— з «%s»: %s\n"
#, c-format
msgid "server '%s' is older than us (%s < %s)"
-msgstr ""
+msgstr "Ñервер «%s» має верÑÑ–ÑŽ, Ñтарішу за нашу (%s < %s)"
-#, fuzzy, c-format
-#| msgid "WARNING: %s overrides %s\n"
+#, c-format
msgid "WARNING: %s\n"
-msgstr "УВÐГÐ: %s перевизначає %s\n"
+msgstr "УВÐГÐ: %s\n"
#, c-format
msgid "OpenPGP card not available: %s\n"
@@ -1525,10 +1509,9 @@ msgstr "ключ «%s» не знайдено: %s\n"
msgid "error reading keyblock: %s\n"
msgstr "помилка під Ñ‡Ð°Ñ Ñпроби Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð°: %s\n"
-#, fuzzy, c-format
-#| msgid "key \"%s\" not found: %s\n"
+#, c-format
msgid "key \"%s\" not found\n"
-msgstr "ключ «%s» не знайдено: %s\n"
+msgstr "ключ «%s» не знайдено\n"
msgid "(unless you specify the key by fingerprint)\n"
msgstr "(Ñкщо ключ не задано відбитком)\n"
@@ -1721,24 +1704,22 @@ msgstr "помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Â«%s»: %s.\n"
msgid "[User ID not found]"
msgstr "[Ідентифікатор не знайдено]"
-#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
+#, c-format
msgid "(check argument of option '%s')\n"
-msgstr "не вказано аргументу до параметра «%.50s»\n"
+msgstr "(перевірте аргумент параметра «%s»)\n"
#, c-format
msgid "Warning: '%s' should be a long key ID or a fingerprint\n"
msgstr ""
+"ПопередженнÑ: «%s» має бути довгим ідентифікатором ключа або відбитком\n"
-#, fuzzy, c-format
-#| msgid "error closing %s: %s\n"
+#, c-format
msgid "error looking up: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби закрити %s: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ: %s\n"
-#, fuzzy, c-format
-#| msgid "error creating keyring '%s': %s\n"
+#, c-format
msgid "Warning: %s appears in the keyring %d times\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñховища ключів «%s»: %s\n"
+msgstr "ПопередженнÑ: Ð·Ð°Ð¿Ð¸Ñ %s наÑвний у Ñховищі %d разів\n"
#, c-format
msgid "automatically retrieved '%s' via %s\n"
@@ -1755,19 +1736,17 @@ msgstr "Без відбитка"
msgid "secret key \"%s\" not found: %s\n"
msgstr "закритий ключ «%s» не знайдено: %s\n"
-#, fuzzy, c-format
-#| msgid "|NAME|use NAME as default secret key"
+#, c-format
msgid "Warning: not using '%s' as default key: %s\n"
-msgstr "|NAME|викориÑтовувати вказаний типовий закритий ключ"
+msgstr "ПопередженнÑ: «%s» не викориÑтовуєтьÑÑ Ñк типовий ключ: %s\n"
-#, fuzzy, c-format
-#| msgid "|NAME|use NAME as default secret key"
+#, c-format
msgid "using \"%s\" as default secret key for signing\n"
-msgstr "|NAME|викориÑтовувати вказаний типовий закритий ключ"
+msgstr "викориÑтовуємо «%s» Ñк типовий закритий ключ Ð´Ð»Ñ Ð¿Ñ–Ð´Ð¿Ð¸ÑуваннÑ\n"
#, c-format
msgid "all values passed to '%s' ignored\n"
-msgstr ""
+msgstr "уÑÑ– значеннÑ, передані «%s», проігноровано\n"
#, c-format
msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n"
@@ -1857,13 +1836,13 @@ msgstr "змінити пароль"
msgid "export keys"
msgstr "екÑпортувати ключі"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "екÑпортувати ключі на Ñервер ключів"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "імпортувати ключі з Ñервера ключів"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "шукати ключі на Ñервері ключів"
msgid "update all keys from a keyserver"
@@ -1890,10 +1869,8 @@ msgstr "показати контрольні Ñуми повідомлень"
msgid "run in server mode"
msgstr "запуÑтити у режимі Ñервера"
-#, 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 "вÑтановити правила TOFU Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° (good, unknown, bad, ask, auto)"
+msgstr "|VALUE|вÑтановити вказане правило TOFU Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð°"
msgid "create ascii armored output"
msgstr "Ñтворити дані у форматі ASCII"
@@ -2100,17 +2077,15 @@ msgstr "показувати назву Ñховища ключів у ÑпиÑÐ
msgid "show expiration dates during signature listings"
msgstr "показувати дати Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñтроків дії у ÑпиÑку підпиÑів"
-#, fuzzy
-#| msgid "Available keys:\n"
msgid "available TOFU policies:\n"
-msgstr "ДоÑтупні ключі:\n"
+msgstr "можливі варіанти правил TOFU:\n"
#, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "невідомі правила TOFU «%s»\n"
msgid "(use \"help\" to list choices)\n"
-msgstr ""
+msgstr "(команда «help» виводить ÑпиÑок можливих варіантів)\n"
#, c-format
msgid "unknown TOFU DB format '%s'\n"
@@ -2403,10 +2378,9 @@ msgstr "помилка під Ñ‡Ð°Ñ Ñпроби Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…
msgid "key export failed: %s\n"
msgstr "помилка під Ñ‡Ð°Ñ Ñпроби екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð°: %s\n"
-#, fuzzy, c-format
-#| msgid "key export failed: %s\n"
+#, c-format
msgid "export as ssh key failed: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð°: %s\n"
+msgstr "Ñпроба екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° ssh зазнала невдачі: %s\n"
#, c-format
msgid "keyserver search failed: %s\n"
@@ -2428,16 +2402,13 @@ msgstr "помилка Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñƒ формат ASCII: %s\n"
msgid "invalid hash algorithm '%s'\n"
msgstr "некоректний алгоритм Ñ…ÐµÑˆÑƒÐ²Ð°Ð½Ð½Ñ Â«%s»\n"
-#, fuzzy, c-format
-#| msgid "error loading certificate '%s': %s\n"
+#, c-format
msgid "error parsing key specification '%s': %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñертифіката «%s»: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби обробки Ñпецифікації ключа «%s»: %s\n"
-#, fuzzy, c-format
-#| msgid ""
-#| "'%s' does not appear to be a valid key id, fingerprint or key grip.\n"
+#, c-format
msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n"
-msgstr "«%s» не є коректним ідентифікатором ключа, відбитком або keygrip.\n"
+msgstr "«%s» не є коректним ідентифікатором ключа, відбитком або кодом\n"
msgid "[filename]"
msgstr "[назва файла]"
@@ -2463,6 +2434,9 @@ msgstr "Ñупроводжувати конфлікти чаÑових познÐ
msgid "|FD|write status info to this FD"
msgstr "запиÑувати до деÑкриптора файла дані щодо Ñтану"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "ВикориÑтаннÑ: gpgv [параметри] [файли] (-h — довідка)"
@@ -2748,6 +2722,8 @@ msgstr "ключ %s: закритий ключ з некоректним шифÑ
#, c-format
msgid "To migrate '%s', with each smartcard, run: %s\n"
msgstr ""
+"Ð”Ð»Ñ Ð¿ÐµÑ€ÐµÐ½ÐµÑÐµÐ½Ð½Ñ Â«%s» на кожній із карток пам’ÑÑ‚Ñ– Ñлід виконати таку команду: "
+"%s\n"
#, c-format
msgid "key %s: no public key - can't apply revocation certificate\n"
@@ -2877,10 +2853,9 @@ msgstr "Ñтворено Ñховище ключів «%s»\n"
msgid "keyblock resource '%s': %s\n"
msgstr "реÑÑƒÑ€Ñ Ð±Ð»Ð¾ÐºÑƒ ключів «%s»: %s\n"
-#, fuzzy, c-format
-#| msgid "error opening '%s': %s\n"
+#, c-format
msgid "error opening key DB: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Â«%s»: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби відкрити базу даних ключів: %s\n"
#, c-format
msgid "failed to rebuild keyring cache: %s\n"
@@ -2892,64 +2867,61 @@ msgstr "[відкликаннÑ]"
msgid "[self-signature]"
msgstr "[ÑамопідпиÑ]"
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
+#, c-format
msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "ключ %s: непідтримуваний алгоритм ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¾Ð³Ð¾ ключа\n"
+msgstr ""
+"неможливо перевірити Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ñ–Ð· непідтримуваним алгоритмом ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ "
+"відкритого ключа (%d): %s.\n"
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
+#, c-format
msgid ""
"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "карткою не підтримуєтьÑÑ Ð°Ð»Ð³Ð¾Ñ€Ð¸Ñ‚Ð¼ контрольних Ñум %s\n"
+msgstr ""
+"неможливо перевірити Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ñ–Ð· непідтримуваним алгоритмом ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ "
+"контрольної Ñуми %d: %s.\n"
-#, fuzzy
-#| msgid "Good signature from"
msgid " (reordered signatures follow)"
-msgstr "Правильний Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð²Ñ–Ð´"
+msgstr " (нижче наведено перевпорÑдковані підпиÑи)"
-#, fuzzy, c-format
-#| msgid "key %s: %s\n"
+#, c-format
msgid "key %s:\n"
-msgstr "ключ %s: %s\n"
+msgstr "ключ %s:\n"
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
+#, c-format
msgid "%d duplicate signature removed\n"
msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Ідентифікатор кориÑтувача «%s»: вилучено %d підпиÑ\n"
-msgstr[1] "Ідентифікатор кориÑтувача «%s»: вилучено %d підпиÑ\n"
-msgstr[2] "Ідентифікатор кориÑтувача «%s»: вилучено %d підпиÑ\n"
+msgstr[0] "вилучено %d дублікат підпиÑу\n"
+msgstr[1] "вилучено %d дублікати підпиÑів\n"
+msgstr[2] "вилучено %d дублікатів підпиÑів\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 Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð½Ðµ перевірено через те, що немає ключа\n"
-msgstr[1] "1 Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð½Ðµ перевірено через те, що немає ключа\n"
-msgstr[2] "1 Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð½Ðµ перевірено через те, що немає ключа\n"
+msgstr[0] "%d Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð½Ðµ перевірено через те, що немає ключа\n"
+msgstr[1] "%d підпиÑи не перевірено через те, що немає ключа\n"
+msgstr[2] "%d підпиÑів не перевірено через те, що немає ключа\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 помилкових підпиÑів\n"
-msgstr[1] "%d помилкових підпиÑів\n"
+msgstr[0] "%d помилкових підпиÑ\n"
+msgstr[1] "%d помилкових підпиÑи\n"
msgstr[2] "%d помилкових підпиÑів\n"
-#, fuzzy, c-format
-#| msgid "Good signature from"
+#, c-format
msgid "%d signature reordered\n"
msgid_plural "%d signatures reordered\n"
-msgstr[0] "Правильний Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð²Ñ–Ð´"
-msgstr[1] "Правильний Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð²Ñ–Ð´"
-msgstr[2] "Правильний Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð²Ñ–Ð´"
+msgstr[0] "перевпорÑдковано %d підпиÑ\n"
+msgstr[1] "перевпорÑдковано %d підпиÑи\n"
+msgstr[2] "перевпорÑдковано %d підпиÑів\n"
#, c-format
msgid ""
"Warning: errors found and only checked self-signatures, run '%s' to check "
"all signatures.\n"
msgstr ""
+"ПопередженнÑ: виÑвлено помилки, перевірка виконувалаÑÑ Ð»Ð¸ÑˆÐµ Ð´Ð»Ñ "
+"ÑамопідпиÑуваннÑ, віддайте команду «%s», щоб перевірити уÑÑ– підпиÑи.\n"
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -2985,7 +2957,7 @@ msgstr ""
#, c-format
msgid "Skipping user ID \"%s\", which is not a text ID.\n"
-msgstr ""
+msgstr "ПропуÑкаємо ідентифікатор кориÑтувача «%s», Ñкий не Ñ” текÑтовим.\n"
#, c-format
msgid "User ID \"%s\" is revoked."
@@ -3294,10 +3266,8 @@ msgstr "Ключ відкликано."
msgid "Really sign all user IDs? (y/N) "
msgstr "ПідпиÑати вÑÑ– ідентифікатори кориÑтувача? (y/N або Ñ‚/Ð) "
-#, fuzzy
-#| msgid "Really sign all user IDs? (y/N) "
msgid "Really sign all text user IDs? (y/N) "
-msgstr "ПідпиÑати вÑÑ– ідентифікатори кориÑтувача? (y/N або Ñ‚/Ð) "
+msgstr "ПідпиÑати вÑÑ– текÑтові ідентифікатори кориÑтувача? (y/N або Ñ‚/Ð) "
msgid "Hint: Select the user IDs to sign\n"
msgstr "Підказка: виберіть ідентифікатори кориÑтувача Ð´Ð»Ñ Ð¿Ñ–Ð´Ð¿Ð¸ÑуваннÑ\n"
@@ -3405,10 +3375,9 @@ msgstr "«%s» не є відбитком\n"
msgid "\"%s\" is not the primary fingerprint\n"
msgstr "«%s» не Ñ” оÑновним відбитком\n"
-#, fuzzy, c-format
-#| msgid "invalid value\n"
+#, c-format
msgid "Invalid user ID '%s': %s\n"
-msgstr "некоректне значеннÑ\n"
+msgstr "Ðекоректний ідентифікатор кориÑтувача «%s»: %s\n"
msgid "No matching user IDs."
msgstr "Ðемає відповідних ідентифікаторів кориÑтувачів."
@@ -3538,13 +3507,12 @@ msgstr "Вилучити цей невідомий підпиÑ? (y/N/q або Ñ
msgid "Really delete this self-signature? (y/N)"
msgstr "Вилучити цей ÑамопідпиÑ? (y/N або Ñ‚/Ð)"
-#, fuzzy, c-format
-#| msgid "Deleted %d signature.\n"
+#, c-format
msgid "Deleted %d signature.\n"
msgid_plural "Deleted %d signatures.\n"
msgstr[0] "Вилучено %d підпиÑ.\n"
-msgstr[1] "Вилучено %d підпиÑ.\n"
-msgstr[2] "Вилучено %d підпиÑ.\n"
+msgstr[1] "Вилучено %d підпиÑи.\n"
+msgstr[2] "Вилучено %d підпиÑів.\n"
msgid "Nothing deleted.\n"
msgstr "Ðічого не вилучено.\n"
@@ -3556,13 +3524,12 @@ msgstr "некоректний"
msgid "User ID \"%s\" compacted: %s\n"
msgstr "Ідентифікатор кориÑтувача «%s» ущільнено: %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] "Ідентифікатор кориÑтувача «%s»: вилучено %d підпиÑ\n"
-msgstr[1] "Ідентифікатор кориÑтувача «%s»: вилучено %d підпиÑ\n"
-msgstr[2] "Ідентифікатор кориÑтувача «%s»: вилучено %d підпиÑ\n"
+msgstr[1] "Ідентифікатор кориÑтувача «%s»: вилучено %d підпиÑів\n"
+msgstr[2] "Ідентифікатор кориÑтувача «%s»: вилучено %d підпиÑів\n"
#, c-format
msgid "User ID \"%s\": already minimized\n"
@@ -3606,15 +3573,12 @@ msgstr ""
"Ви Ñправді бажаєте призначити цей ключ Ñк підпиÑане відкликаннÑ? (y/N або Ñ‚/"
"Ð) "
-#, fuzzy
-#| msgid ""
-#| "Are you sure you want to appoint this key as a designated revoker? (y/N) "
msgid ""
"Are you sure you want to change the expiration time for multiple subkeys? (y/"
"N) "
msgstr ""
-"Ви Ñправді бажаєте призначити цей ключ Ñк підпиÑане відкликаннÑ? (y/N або Ñ‚/"
-"Ð) "
+"Ви Ñправді хочете змінити Ñ‡Ð°Ñ Ð²Ð¸Ñ‡ÐµÑ€Ð¿Ð°Ð½Ð½Ñ Ñтроку дії Ð´Ð»Ñ Ð´ÐµÐºÑ–Ð»ÑŒÐºÐ¾Ñ… підключів? "
+"(y/N або Ñ‚/Ð) "
msgid "Changing expiration time for a subkey.\n"
msgstr "Зміна чаÑу Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñтроку дії Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡Ð°.\n"
@@ -3665,10 +3629,9 @@ msgstr "Ідентифікатора кориÑтувача з індекÑом
msgid "No user ID with hash %s\n"
msgstr "Ідентифікатора кориÑтувача з хешем %s не Ñ–Ñнує\n"
-#, fuzzy, c-format
-#| msgid "No subkey with index %d\n"
+#, c-format
msgid "No subkey with key ID '%s'.\n"
-msgstr "Підключа з індекÑом %d не Ñ–Ñнує\n"
+msgstr "Піключа із ідентифікатором ключа «%s» не Ñ–Ñнує.\n"
#, c-format
msgid "No subkey with index %d\n"
@@ -3894,6 +3857,10 @@ msgid "No key with this keygrip\n"
msgstr "Ðемає ключів з таким значеннÑм keygrip\n"
#, c-format
+msgid "rounded to %u bits\n"
+msgstr "округлено до %u бітів\n"
+
+#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "ключі %s можуть мати довжину від %u до %u бітів.\n"
@@ -3909,10 +3876,6 @@ msgstr "Якою має бути довжина ключа? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "Запитана довжина ключа — %u бітів\n"
-#, c-format
-msgid "rounded to %u bits\n"
-msgstr "округлено до %u бітів\n"
-
msgid "Please select which elliptic curve you want:\n"
msgstr "Вкажіть потрібну вам еліптичну криву:\n"
@@ -4018,7 +3981,7 @@ msgstr "Ðекоректний Ñимвол у імені\n"
#, c-format
msgid "The characters '%s' and '%s' may not appear in name\n"
-msgstr ""
+msgstr "Ðе можна викориÑтовувати Ñимволи «%s» Ñ– «%s» у назві\n"
msgid "Name may not start with a digit\n"
msgstr "Ð†Ð¼â€™Ñ Ð½Ðµ може починатиÑÑ Ð· цифри\n"
@@ -4208,30 +4171,26 @@ msgstr "Критична примітка підпиÑу: "
msgid "Signature notation: "
msgstr "Примітка підпиÑу: "
-#, fuzzy, c-format
-#| msgid "%d good signatures\n"
+#, c-format
msgid "%d good signature\n"
msgid_plural "%d good signatures\n"
-msgstr[0] "%d добрих підпиÑів\n"
-msgstr[1] "%d добрих підпиÑів\n"
+msgstr[0] "%d добрий підпиÑ\n"
+msgstr[1] "%d добрих підпиÑи\n"
msgstr[2] "%d добрих підпиÑів\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 Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð½Ðµ перевірено через помилку\n"
-msgstr[1] "1 Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð½Ðµ перевірено через помилку\n"
-msgstr[2] "1 Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð½Ðµ перевірено через помилку\n"
+msgstr[0] "%d Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð½Ðµ перевірено через помилку\n"
+msgstr[1] "%d підпиÑи не перевірено через помилку\n"
+msgstr[2] "%d підпиÑів не перевірено через помилку\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] ""
-"ПопередженнÑ: %lu ключів пропущено через їхній надто великий розмір\n"
+msgstr[0] "ПопередженнÑ: %lu ключ пропущено через надто великий розмір\n"
msgstr[1] ""
-"ПопередженнÑ: %lu ключів пропущено через їхній надто великий розмір\n"
+"ПопередженнÑ: %lu ключі пропущено через їхній надто великий розмір\n"
msgstr[2] ""
"ПопередженнÑ: %lu ключів пропущено через їхній надто великий розмір\n"
@@ -4266,29 +4225,26 @@ msgstr "Серійний номер картки ="
msgid "caching keyring '%s'\n"
msgstr "ÐºÐµÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ñховища ключів «%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 ключів (%lu підпиÑів)\n"
-msgstr[1] "зараз кешовано %lu ключів (%lu підпиÑів)\n"
+msgstr[0] "зараз кешовано %lu ключів (%lu підпиÑ)\n"
+msgstr[1] "зараз кешовано %lu ключів (%lu підпиÑи)\n"
msgstr[2] "зараз кешовано %lu ключів (%lu підпиÑів)\n"
-#, fuzzy, c-format
-#| msgid "flush the cache"
+#, c-format
msgid "%lu key cached"
msgid_plural "%lu keys cached"
-msgstr[0] "Ñпорожнити кеш"
-msgstr[1] "Ñпорожнити кеш"
-msgstr[2] "Ñпорожнити кеш"
+msgstr[0] "кешовано %lu ключ"
+msgstr[1] "кешовано %lu ключі"
+msgstr[2] "кешовано %lu ключів"
-#, fuzzy, c-format
-#| msgid "1 bad signature\n"
+#, c-format
msgid " (%lu signature)\n"
msgid_plural " (%lu signatures)\n"
-msgstr[0] "1 помилковий підпиÑ\n"
-msgstr[1] "1 помилковий підпиÑ\n"
-msgstr[2] "1 помилковий підпиÑ\n"
+msgstr[0] " (%lu підпиÑ)\n"
+msgstr[1] " (%lu підпиÑи)\n"
+msgstr[2] " (%lu підпиÑів)\n"
#, c-format
msgid "%s: keyring created\n"
@@ -4330,12 +4286,11 @@ msgstr "некоректний протокол Ñервера ключів (нÐ
msgid "\"%s\" not a key ID: skipping\n"
msgstr "«%s» не Ñ” ідентифікатором ключа: пропуÑкаємо\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] "оновлюємо %d ключів з %s\n"
-msgstr[1] "оновлюємо %d ключів з %s\n"
+msgstr[0] "оновлюємо %d ключ з %s\n"
+msgstr[1] "оновлюємо %d ключі з %s\n"
msgstr[2] "оновлюємо %d ключів з %s\n"
#, c-format
@@ -4361,10 +4316,8 @@ msgstr "надÑилаємо запит щодо ключа %s до %s ÑервÐ
msgid "requesting key %s from %s\n"
msgstr "надÑилаємо запит щодо ключа %s з %s\n"
-#, fuzzy
-#| msgid "invalid keyserver options\n"
msgid "no keyserver known\n"
-msgstr "некоректні параметри Ñервера ключів\n"
+msgstr "немає відомих Ñерверів ключів\n"
#, c-format
msgid "sending key %s to %s\n"
@@ -4584,18 +4537,16 @@ msgstr "УВÐГÐ: алгоритм обчиÑÐ»ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð¸Ñ…
msgid "Note: signatures using the %s algorithm are rejected\n"
msgstr "ЗауваженнÑ: підпиÑи за допомогою алгоритму %s відкинуто\n"
-#, fuzzy, c-format
-#| msgid "%s:%u: read error: %s\n"
+#, c-format
msgid "(reported error: %s)\n"
-msgstr "%s:%u: помилка під Ñ‡Ð°Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ: %s\n"
+msgstr "(повідомлена помилка: %s)\n"
-#, fuzzy, c-format
-#| msgid "read error in '%s': %s\n"
+#, c-format
msgid "(reported error: %s <%s>)\n"
-msgstr "помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñƒ «%s»: %s\n"
+msgstr "(повідомлена помилка: %s <%s>)\n"
msgid "(further info: "
-msgstr ""
+msgstr "(подальша інформаціÑ: "
#, c-format
msgid "%s:%d: deprecated option \"%s\"\n"
@@ -4646,10 +4597,9 @@ msgid "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n"
msgstr ""
"Відкритий ключ ECDSA має зберігатиÑÑ Ñƒ кодуванні SEC кратному 8-бітовому\n"
-#, fuzzy, c-format
-#| msgid "Unknown signature type '%s'\n"
+#, c-format
msgid "unknown weak digest '%s'\n"
-msgstr "Ðевідомий тип підпиÑу «%s»\n"
+msgstr "невідома Ñлабка контрольна Ñума «%s»\n"
#, c-format
msgid "File '%s' exists. "
@@ -4993,20 +4943,17 @@ msgstr "%s: пропущено: відкритий ключ вимкнено\n"
msgid "%s: skipped: public key already present\n"
msgstr "%s: пропущено: відкритий ключ вже Ñ–Ñнує\n"
-#, fuzzy, c-format
-#| msgid "can't connect to '%s': %s\n"
+#, c-format
msgid "can't encrypt to '%s'\n"
-msgstr "не вдалоÑÑ Ð²Ñтановити Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· «%s»: %s\n"
+msgstr "не вдалоÑÑ Ð·Ð°ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ñ‚Ð¸ до «%s»\n"
-#, fuzzy, c-format
-#| msgid "line %d: invalid date given\n"
+#, c-format
msgid "option '%s' given, but no valid default keys given\n"
-msgstr "Ñ€Ñдок %d: вказано некоректну дату\n"
+msgstr "вказано параметр «%s», але не вказано коректних типових ключів\n"
-#, fuzzy, c-format
-#| msgid "line %d: invalid date given\n"
+#, c-format
msgid "option '%s' given, but option '%s' not given\n"
-msgstr "Ñ€Ñдок %d: вказано некоректну дату\n"
+msgstr "вказано параметр «%s», але не вказано параметр «%s»\n"
msgid "You did not specify a user ID. (you may use \"-r\")\n"
msgstr ""
@@ -5142,13 +5089,11 @@ 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 ""
+"Сертифікат Ð²Ñ–Ð´ÐºÐ»Ð¸ÐºÐ°Ð½Ð½Ñ Ñ” Ñвоєрідним «апаратним вимикачем» длÑ\n"
+"відкритого оголошеннÑ, що ключ не можна більше викориÑтовувати.\n"
+"Такий Ñертифікат Ð²Ñ–Ð´ÐºÐ»Ð¸ÐºÐ°Ð½Ð½Ñ Ð½Ðµ можна ÑкаÑовувати піÑÐ»Ñ Ð¹Ð¾Ð³Ð¾\n"
+"оприлюдненнÑ."
-#, 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"
@@ -5159,13 +5104,10 @@ msgstr ""
"СкориÑтайтеÑÑ Ñ†Ð¸Ð¼ Ð´Ð»Ñ Ð²Ñ–Ð´ÐºÐ»Ð¸ÐºÐ°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа у випадку його\n"
"компрометації або втрати закритої чаÑтини. Втім, Ñкщо доÑтуп до\n"
"закритого ключа не втрачено, краще Ñтворити новий Ñертифікат\n"
-"Ð²Ñ–Ð´ÐºÐ»Ð¸ÐºÐ°Ð½Ð½Ñ Ñ– вказати причину відкликаннÑ."
+"Ð²Ñ–Ð´ÐºÐ»Ð¸ÐºÐ°Ð½Ð½Ñ Ñ– вказати причину відкликаннÑ. Докладніший опиÑ\n"
+"можна знайти у розділах підручника з GnuPG щодо команди\n"
+"gpg «--gen-revoke»."
-#, 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"
@@ -5173,29 +5115,27 @@ msgid ""
msgstr ""
"Щоб уникнути випадкового викориÑÑ‚Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ файла, перед п’Ñтьма\n"
"дефіÑами нижче додано двокрапку. Вилучіть цю двокрапку у текÑтовому\n"
-"редакторі, перш ніж ÑкориÑтатиÑÑ Ñ†Ð¸Ð¼ Ñертифікатом відкликаннÑ."
+"редакторі, перш ніж імпортувати або оприлюднювати цей Ñертифікат\n"
+"відкликаннÑ."
-#, fuzzy, c-format
-#| msgid "Revocation certificate created.\n"
+#, c-format
msgid "revocation certificate stored as '%s.rev'\n"
-msgstr "Створено Ñертифікат відкликаннÑ.\n"
+msgstr "Ñертифікат Ð²Ñ–Ð´ÐºÐ»Ð¸ÐºÐ°Ð½Ð½Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð¾ Ñк «%s.rev»\n"
-#, fuzzy, c-format
-#| msgid "secret key \"%s\" not found: %s\n"
+#, c-format
msgid "secret key \"%s\" not found\n"
-msgstr "закритий ключ «%s» не знайдено: %s\n"
+msgstr "закритий ключ «%s» не знайдено\n"
#. TRANSLATORS: The %s prints a key specification which
#. for example has been given at the command line. Several lines
#. lines with secret key infos are printed after this message.
#, c-format
msgid "'%s' matches multiple secret keys:\n"
-msgstr ""
+msgstr "«%s» відповідає декільком закритим ключам:\n"
-#, fuzzy, c-format
-#| msgid "error creating keyring '%s': %s\n"
+#, c-format
msgid "error searching the keyring: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñховища ключів «%s»: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби пошуку у Ñховищі ключів: %s\n"
msgid "Create a revocation certificate for this key? (y/N) "
msgstr "Створити Ñертифікат Ð²Ñ–Ð´ÐºÐ»Ð¸ÐºÐ°Ð½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа? (y/N або Ñ‚/Ð) "
@@ -5277,25 +5217,21 @@ msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
msgstr ""
"УВÐГÐ: підпиÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡Ð° %s міÑтить некоректну перехреÑну Ñертифікацію\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] "відкритий ключ %s Ñ” на %lu Ñекунду новішим за підпиÑ\n"
-msgstr[1] "відкритий ключ %s Ñ” на %lu Ñекунду новішим за підпиÑ\n"
-msgstr[2] "відкритий ключ %s Ñ” на %lu Ñекунду новішим за підпиÑ\n"
+msgstr[1] "відкритий ключ %s Ñ” на %lu Ñекунди новішим за підпиÑ\n"
+msgstr[2] "відкритий ключ %s Ñ” на %lu Ñекунд новішим за підпиÑ\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] "відкритий ключ %s Ñ” на %lu Ñекунду новішим за підпиÑ\n"
-msgstr[1] "відкритий ключ %s Ñ” на %lu Ñекунду новішим за підпиÑ\n"
-msgstr[2] "відкритий ключ %s Ñ” на %lu Ñекунду новішим за підпиÑ\n"
+msgstr[0] "відкритий ключ %s Ñ” на %lu день новішим за підпиÑ\n"
+msgstr[1] "відкритий ключ %s Ñ” на %lu дні новішим за підпиÑ\n"
+msgstr[2] "відкритий ключ %s Ñ” на %lu днів новішим за підпиÑ\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 ""
@@ -5310,20 +5246,18 @@ msgstr[2] ""
"ключ %s було Ñтворено з позначкою на %lu Ñекунду у майбутньому (чаÑова Ð¿ÐµÑ‚Ð»Ñ "
"або проблема з годинником)\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] ""
-"ключ %s було Ñтворено з позначкою на %lu Ñекунду у майбутньому (чаÑова Ð¿ÐµÑ‚Ð»Ñ "
+"ключ %s було Ñтворено з позначкою на %lu день у майбутньому (чаÑова Ð¿ÐµÑ‚Ð»Ñ "
"або проблема з годинником)\n"
msgstr[1] ""
-"ключ %s було Ñтворено з позначкою на %lu Ñекунду у майбутньому (чаÑова Ð¿ÐµÑ‚Ð»Ñ "
-"або проблема з годинником)\n"
+"ключ %s було Ñтворено з позначкою на %lu дні у майбутньому (чаÑова Ð¿ÐµÑ‚Ð»Ñ Ð°Ð±Ð¾ "
+"проблема з годинником)\n"
msgstr[2] ""
-"ключ %s було Ñтворено з позначкою на %lu Ñекунду у майбутньому (чаÑова Ð¿ÐµÑ‚Ð»Ñ "
+"ключ %s було Ñтворено з позначкою на %lu днів у майбутньому (чаÑова Ð¿ÐµÑ‚Ð»Ñ "
"або проблема з годинником)\n"
#, c-format
@@ -5553,228 +5487,226 @@ msgstr ""
msgid "input line longer than %d characters\n"
msgstr "Ñ€Ñдок вхідних даних довший за %d Ñимволів\n"
-#, fuzzy, c-format
-#| msgid "error sending standard options: %s\n"
+#, c-format
msgid "error beginning transaction on TOFU database: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñтандартних параметрів: %s\n"
+msgstr ""
+"помилка під Ñ‡Ð°Ñ Ñпроби розпочати внеÑÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½ до бази даних TOFU: %s\n"
#, c-format
msgid "error committing transaction on TOFU database: %s\n"
-msgstr ""
+msgstr "помилка під Ñ‡Ð°Ñ Ð²Ð½ÐµÑÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½ до бази даних TOFU: %s\n"
#, c-format
msgid "error rolling back transaction on TOFU database: %s\n"
-msgstr ""
+msgstr "помилка під Ñ‡Ð°Ñ ÑкаÑÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ð½ у базі даних TOFU: %s\n"
-#, fuzzy, c-format
-#| msgid "unsupported algorithm: %s"
+#, c-format
msgid "unsupported TOFU database version: %s\n"
-msgstr "непідтримуваний алгоритм: %s"
+msgstr "непідтримувана верÑÑ–Ñ Ð±Ð°Ð·Ð¸ даних TOFU: %s\n"
-#, fuzzy, c-format
-#| msgid "error sending data: %s\n"
+#, c-format
msgid "error reading TOFU database: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð±Ð°Ð·Ð¸ даних 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 "помилка під Ñ‡Ð°Ñ Ñпроби запиÑу у кодуванні base64: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñ— бази даних TOFU: %s\n"
-#, fuzzy, c-format
-#| msgid "error initializing reader object: %s\n"
+#, c-format
msgid "error initializing TOFU database: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби ініціалізації об’єкта читаннÑ: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби ініціалізації бази даних TOFU: %s\n"
-#, fuzzy, c-format
-#| msgid "error opening '%s': %s\n"
+#, c-format
msgid "error opening TOFU database '%s': %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Â«%s»: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби відкрити бази даних TOFU «%s»: %s\n"
msgid "Warning: Home directory contains both tofu.db and tofu.d.\n"
msgstr ""
+"ПопередженнÑ: у домашньому каталозі міÑÑ‚ÑÑ‚ÑŒÑÑ Ñк tofu.db, так Ñ– tofu.d.\n"
msgid "Using split format for TOFU database\n"
-msgstr ""
-
-#, fuzzy, c-format
-#| msgid "error sending data: %s\n"
-msgid "error updating TOFU database: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…: %s\n"
+msgstr "ВикориÑтовуємо розділений формат Ð´Ð»Ñ Ð±Ð°Ð·Ð¸ даних TOFU\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "відкритий ключ %s не знайдено: %s\n"
-
-#, fuzzy, c-format
-#| msgid "error setting OCSP target: %s\n"
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° OCSP: %s\n"
+msgid "error updating TOFU database: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð±Ð°Ð·Ð¸ даних TOFU: %s\n"
#, c-format
msgid "The binding %s is NOT known."
-msgstr ""
+msgstr "Прив’Ñзка %s Ñ” невідомою."
#, c-format
msgid ""
"The key with fingerprint %s raised a conflict with the binding %s. Since "
"this binding's policy was 'auto', it was changed to 'ask'."
msgstr ""
+"Ключ із відбитком %s конфліктує із прив’Ñзкою %s. ОÑкільки правилами цієї "
+"прив’Ñзки визначалоÑÑ Â«Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾Â», Ñ—Ñ… змінено на «запитувати»."
#, c-format
msgid ""
"Please indicate whether you believe the binding %s%sis legitimate (the key "
"belongs to the stated owner) or a forgery (bad)."
msgstr ""
+"Будь лаÑка, вкажіть, чи вважаєте прив’Ñзку %s%sчинною (ключ належить "
+"декларованому влаÑнику) чи підробною (помилковою)."
-#, fuzzy, c-format
-#| msgid "error getting responder ID: %s\n"
+#, c-format
msgid "error gathering other user IDs: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ–Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ‚Ð¾Ñ€Ð° відповідача: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ñ–Ð½ÑˆÐ¸Ñ… ідентифікаторів кориÑтувачів: %s\n"
msgid "Known user IDs associated with this key:\n"
-msgstr ""
+msgstr "Відомі ідентифікатори кориÑтувачів, пов’Ñзані із цим ключем:\n"
-#, fuzzy, c-format
-#| msgid "validity: %s"
+#, c-format
msgid "policy: %s"
-msgstr "чинніÑÑ‚ÑŒ: %s"
+msgstr "правило: %s"
-#, fuzzy, c-format
-#| msgid "error getting stored flags: %s\n"
+#, c-format
msgid "error gathering signature stats: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð¸Ñ… прапорців: %s\n"
+msgstr ""
+"помилка під Ñ‡Ð°Ñ Ñпроби зібрати ÑтатиÑтичні дані щодо підпиÑуваннÑ: %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] "ÐдреÑу електронної пошти «%s» пов’Ñзано із %d ключем:\n"
+msgstr[1] "ÐдреÑу електронної пошти «%s» пов’Ñзано із %d ключами:\n"
+msgstr[2] "ÐдреÑу електронної пошти «%s» пов’Ñзано із %d ключами:\n"
#, c-format
msgid "Statistics for keys with the email address \"%s\":\n"
-msgstr ""
+msgstr "СтатиÑтичні дані Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ñ–Ð² із адреÑою електронної пошти «%s»:\n"
-#, fuzzy
-#| msgid "list keys"
msgid "this key"
-msgstr "показати ÑпиÑок ключів"
+msgstr "цей ключ"
#, c-format
msgid "%ld message signed in the future."
msgid_plural "%ld messages signed in the future."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%ld Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñано у майбутньому."
+msgstr[1] "%ld Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñано у майбутньому."
+msgstr[2] "%ld повідомлень підпиÑано у майбутньому."
-#, fuzzy, c-format
-#| msgid "print message digests"
+#, c-format
msgid "%ld message signed"
msgid_plural "%ld messages signed"
-msgstr[0] "показати контрольні Ñуми повідомлень"
-msgstr[1] "показати контрольні Ñуми повідомлень"
-msgstr[2] "показати контрольні Ñуми повідомлень"
+msgstr[0] "підпиÑано %ld повідомленнÑ"
+msgstr[1] "підпиÑано %ld повідомленнÑ"
+msgstr[2] "підпиÑано %ld повідомлень"
#, c-format
msgid " over the past %ld day."
msgid_plural " over the past %ld days."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] " протÑгом %ld попереднього днÑ."
+msgstr[1] " протÑгом %ld попередніх днів."
+msgstr[2] " протÑгом %ld попередніх днів."
#, c-format
msgid " over the past %ld week."
msgid_plural " over the past %ld weeks."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] " протÑгом %ld попереднього тижнÑ."
+msgstr[1] " протÑгом %ld попередніх тижнів."
+msgstr[2] " протÑгом %ld попередніх тижнів."
#, c-format
msgid " over the past %ld month."
msgid_plural " over the past %ld months."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] " протÑгом %ld попереднього міÑÑцÑ."
+msgstr[1] " протÑгом %ld попередніх міÑÑців."
+msgstr[2] " протÑгом %ld попередніх міÑÑців."
#. 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.
+#. * 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 ""
+"Зазвичай, з певною адреÑою електронної пошти пов’Ñзано лише один ключ. Втім, "
+"іноді Ñтворюють новий ключ, коли, наприклад, ключ Ñ” надто заÑтарілим або "
+"влаÑник вважає, що ключ може бути Ñкомпрометовано. Якщо ж таких обÑтавин не "
+"передбачаєтьÑÑ, ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð°Ð¹Ð²Ð¾Ð³Ð¾ ключа може означати, що хтоÑÑŒ намагаєтьÑÑ "
+"втрутитиÑÑ Ñ– перехопити дані. Перш ніж приймати такий ключ, варто зв’ÑзатиÑÑ "
+"із влаÑником Ñ– переконатиÑÑ, що новий ключ Ñ” чинним."
#. 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.
+#. * 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 ""
+"(G)Добрий, (A)ПрийнÑти одноразово, (U)Ðевідомий, (R)Відкинути одноразово, "
+"(B)Поганий? "
-#, fuzzy, c-format
-#| msgid "error creating a pipe: %s\n"
+#, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr ""
+"помилка під Ñ‡Ð°Ñ Ñпроби вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ€Ñ–Ð²Ð½Ñ Ð´Ð¾Ð²Ñ–Ñ€Ð¸ до прив’Ñзки TOFU до %s\n"
+
+#, c-format
msgid "error changing TOFU policy: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñƒ: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби змінити правила TOFU: %s\n"
#. TRANSLATORS: The tilde ('~') is used here to indicate a
#. * non-breakable space
#, c-format
msgid "%d~year"
msgid_plural "%d~years"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d~рік"
+msgstr[1] "%d~роки"
+msgstr[2] "%d~років"
#, c-format
msgid "%d~month"
msgid_plural "%d~months"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d~міÑÑць"
+msgstr[1] "%d~міÑÑці"
+msgstr[2] "%d~міÑÑців"
#, c-format
msgid "%d~day"
msgid_plural "%d~days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d~день"
+msgstr[1] "%d~дні"
+msgstr[2] "%d~днів"
#, c-format
msgid "%d~hour"
msgid_plural "%d~hours"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d~година"
+msgstr[1] "%d~години"
+msgstr[2] "%d~годин"
#, c-format
msgid "%d~minute"
msgid_plural "%d~minutes"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d~хвилина"
+msgstr[1] "%d~хвилини"
+msgstr[2] "%d~хвилин"
#, c-format
msgid "%d~second"
msgid_plural "%d~seconds"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d~Ñекунда"
+msgstr[1] "%d~Ñекунди"
+msgstr[2] "%d~Ñекунд"
#, c-format
msgid "Have never verified a message signed by key %s!\n"
-msgstr ""
+msgstr "Ðіколи не перевірÑлоÑÑ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ, підпиÑане ключем %s!\n"
#, c-format
msgid ""
"Failed to collect signature statistics for \"%s\"\n"
"(key %s)\n"
msgstr ""
+"Ðе вдалоÑÑ Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ ÑтатиÑтичні дані щодо підпиÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Â«%s»\n"
+"(ключ %s)\n"
-#, fuzzy, c-format
-#| msgid "print message digests"
+#, c-format
msgid "Verified %ld messages signed by \"%s\"."
-msgstr "показати контрольні Ñуми повідомлень"
+msgstr "Перевірено %ld повідомлень, підпиÑаних «%s»."
#, c-format
msgid ""
@@ -5784,18 +5716,24 @@ msgid_plural ""
"Verified %ld messages signed by \"%s\"\n"
"in the past %s."
msgstr[0] ""
+"Перевірено %ld повідомленнÑ, підпиÑане «%s»,\n"
+"протÑгом такого Ñтроку: %s."
msgstr[1] ""
+"Перевірено %ld повідомленнÑ, підпиÑаних «%s»,\n"
+"протÑгом такого Ñтроку: %s."
msgstr[2] ""
+"Перевірено %ld повідомлень, підпиÑаних «%s»,\n"
+"протÑгом такого Ñтроку: %s."
#, c-format
msgid "The most recent message was verified %s ago."
-msgstr ""
+msgstr "ОÑтаннє Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¾ перевірено %s тому."
msgid "Warning: we've have yet to see a message signed by this key!\n"
-msgstr ""
+msgstr "ПопередженнÑ: повідомлень, Ñкі було б підпиÑано цим ключем, не було!\n"
msgid "Warning: we've only seen a single message signed by this key!\n"
-msgstr ""
+msgstr "ПопередженнÑ: цим ключем було підпиÑано лише одне повідомленнÑ!\n"
#, c-format
msgid ""
@@ -5811,13 +5749,30 @@ msgid_plural ""
" %s\n"
"to mark it as being bad.\n"
msgstr[0] ""
+"ПопередженнÑ: Ñкщо вам здаєтьÑÑ, що у Ð²Ð°Ñ Ð±ÑƒÐ»Ð¾ понад %ld повідомленнÑ, "
+"підпиÑане цим ключем, цей ключ може бути підробним! Уважно перевірте, чи "
+"точно вказано адреÑу електронної пошти. Якщо ключ Ñ” підозріливим, "
+"ÑкориÑтайтеÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾ÑŽ\n"
+" %s\n"
+"Ð´Ð»Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° Ñк помилкового.\n"
msgstr[1] ""
+"ПопередженнÑ: Ñкщо вам здаєтьÑÑ, що у Ð²Ð°Ñ Ð±ÑƒÐ»Ð¾ понад %ld повідомленнÑ, "
+"підпиÑане цим ключем, цей ключ може бути підробним! Уважно перевірте, чи "
+"точно вказано адреÑу електронної пошти. Якщо ключ Ñ” підозріливим, "
+"ÑкориÑтайтеÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾ÑŽ\n"
+" %s\n"
+"Ð´Ð»Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° Ñк помилкового.\n"
msgstr[2] ""
+"ПопередженнÑ: Ñкщо вам здаєтьÑÑ, що у Ð²Ð°Ñ Ð±ÑƒÐ»Ð¾ понад %ld повідомлень, "
+"підпиÑане цим ключем, цей ключ може бути підробним! Уважно перевірте, чи "
+"точно вказано адреÑу електронної пошти. Якщо ключ Ñ” підозріливим, "
+"ÑкориÑтайтеÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾ÑŽ\n"
+" %s\n"
+"Ð´Ð»Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° Ñк помилкового.\n"
-#, fuzzy, c-format
-#| msgid "error sending data: %s\n"
+#, c-format
msgid "error opening TOFU database: %s\n"
-msgstr "помилка під Ñ‡Ð°Ñ Ñпроби надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…: %s\n"
+msgstr "помилка під Ñ‡Ð°Ñ Ñпроби відкрити бази даних TOFU: %s\n"
#, c-format
msgid "'%s' is not a valid long keyID\n"
@@ -5879,27 +5834,29 @@ msgstr "потреби у перевірці trustdb на оÑнові модеÐ
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "потреби у оновленні trustdb на оÑнові моделі довіри «%s» немає\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "відкритий ключ %s не знайдено: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "будь лаÑка, ÑкориÑтайтеÑÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ --check-trustdb\n"
msgid "checking the trustdb\n"
msgstr "перевірка trustdb\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 ключів\n"
-msgstr[1] "оброблено %lu ключів\n"
-msgstr[2] "оброблено %lu ключів\n"
+msgstr[0] "оброблено %d ключ"
+msgstr[1] "оброблено %d ключі"
+msgstr[2] "оброблено %d ключів"
-#, 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] "Оброблено %d ключів (очищено %d значень чинноÑÑ‚Ñ–)\n"
-msgstr[1] "Оброблено %d ключів (очищено %d значень чинноÑÑ‚Ñ–)\n"
-msgstr[2] "Оброблено %d ключів (очищено %d значень чинноÑÑ‚Ñ–)\n"
+msgstr[0] " (очищено %d Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‡Ð¸Ð½Ð½Ð¾ÑÑ‚Ñ–)\n"
+msgstr[1] " (очищено %d Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‡Ð¸Ð½Ð½Ð¾ÑÑ‚Ñ–)\n"
+msgstr[2] " (очищено %d значень чинноÑÑ‚Ñ–)\n"
msgid "no ultimately trusted keys found\n"
msgstr "не знайдено ключів з необмеженою довірою\n"
@@ -5957,6 +5914,11 @@ msgstr "[невідома]"
msgid "[ undef ]"
msgstr "[не визн.]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "ніколи"
+
msgid "[marginal]"
msgstr "[неповна ]"
@@ -6117,16 +6079,15 @@ msgstr "помилка Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñтану CHV з картки\n"
msgid "card is permanently locked!\n"
msgstr "картку заблоковано!\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] ""
-"залишилоÑÑ %d Ñпроб Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–Ñтративного пінкоду перед тим, Ñк "
+"залишилаÑÑ %d Ñпроба Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–Ñтративного пінкоду перед тим, Ñк "
"картку буде оÑтаточно заблоковано\n"
msgstr[1] ""
-"залишилоÑÑ %d Ñпроб Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–Ñтративного пінкоду перед тим, Ñк "
+"залишилоÑÑ %d Ñпроби Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–Ñтративного пінкоду перед тим, Ñк "
"картку буде оÑтаточно заблоковано\n"
msgstr[2] ""
"залишилоÑÑ %d Ñпроб Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–Ñтративного пінкоду перед тим, Ñк "
@@ -6209,12 +6170,11 @@ msgstr "зачекайте на Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡
msgid "generating key failed\n"
msgstr "помилка під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð°\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] "ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° завершено (за %d Ñекунд)\n"
-msgstr[1] "ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° завершено (за %d Ñекунд)\n"
+msgstr[0] "ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° завершено (за %d Ñекунду)\n"
+msgstr[1] "ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° завершено (за %d Ñекунди)\n"
msgstr[2] "ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° завершено (за %d Ñекунд)\n"
msgid "invalid structure of OpenPGP card (DO 0x93)\n"
@@ -8338,10 +8298,8 @@ msgstr "|N|завершувати Ñтрок дії паролів за вказ
msgid "do not allow the reuse of old passphrases"
msgstr "не дозволÑти повторне викориÑÑ‚Ð°Ð½Ð½Ñ Ñтарих паролів"
-#, fuzzy
-#| msgid "|N|set LDAP timeout to N seconds"
msgid "|N|set the Pinentry timeout to N seconds"
-msgstr "|N|вÑтановити вказаний Ñ‡Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… від LDAP"
+msgstr "|N|вÑтановити вказаний Ñ‡Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Pinentry у Ñекундах"
msgid "|NAME|use NAME as default secret key"
msgstr "|NAME|викориÑтовувати вказаний типовий закритий ключ"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 3d5f8bc..034ee5c 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -473,6 +473,10 @@ msgid "error binding socket to '%s': %s\n"
msgstr "在‘%s’中寻找信任度记录时出错:%s\n"
#, fuzzy, c-format
+msgid "can't set permissions of '%s': %s\n"
+msgstr "警告:扩展模å—‘%s’æƒé™ä¸å®‰å…¨\n"
+
+#, fuzzy, c-format
msgid "listen() failed: %s\n"
msgstr "更新失败:%s\n"
@@ -491,10 +495,6 @@ msgid "directory '%s' created\n"
msgstr "已创建目录‘%s’\n"
#, fuzzy, c-format
-msgid "can't set permissions of '%s': %s\n"
-msgstr "警告:扩展模å—‘%s’æƒé™ä¸å®‰å…¨\n"
-
-#, fuzzy, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "fstat(%d) 在 %s 中出错:%s\n"
@@ -1924,13 +1924,13 @@ msgstr "更改密ç "
msgid "export keys"
msgstr "导出密钥"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "把密钥导出到æŸä¸ªå…¬é’¥æœåŠ¡å™¨ä¸Š"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "从公钥æœåŠ¡å™¨ä¸Šå¯¼å…¥å¯†é’¥"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "在公钥æœåŠ¡å™¨ä¸Šæœå¯»å¯†é’¥"
msgid "update all keys from a keyserver"
@@ -2531,6 +2531,9 @@ msgstr "把时间戳矛盾仅视为警告"
msgid "|FD|write status info to this FD"
msgstr "|FD|把状æ€ä¿¡æ¯å†™å…¥æ–‡ä»¶æ述符 FD"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "用法:gpgv [选项] [文件] (用 -h 求助)"
@@ -3948,6 +3951,11 @@ msgstr ""
msgid "No key with this keygrip\n"
msgstr "没有索引为 %d çš„å­é’¥\n"
+#, fuzzy, c-format
+#| msgid "rounded up to %u bits\n"
+msgid "rounded to %u bits\n"
+msgstr "èˆå…¥åˆ° %u ä½\n"
+
#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "%s 密钥长度应在 %u ä½ä¸Ž %u ä½ä¹‹é—´ã€‚\n"
@@ -3964,11 +3972,6 @@ msgstr "您想è¦ç”¨å¤šå¤§çš„密钥尺寸?(%u)"
msgid "Requested keysize is %u bits\n"
msgstr "您所è¦æ±‚的密钥尺寸是 %u ä½\n"
-#, fuzzy, c-format
-#| msgid "rounded up to %u bits\n"
-msgid "rounded to %u bits\n"
-msgstr "èˆå…¥åˆ° %u ä½\n"
-
#, fuzzy
#| msgid "Please select what kind of key you want:\n"
msgid "Please select which elliptic curve you want:\n"
@@ -5599,14 +5602,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "读å–‘%s’时出错:%s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "找ä¸åˆ°å…¬é’¥ %s:%s\n"
-
-#, fuzzy, c-format
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "读å–‘%s’时出错:%s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5685,14 +5680,14 @@ msgstr[0] ""
msgstr[1] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5700,6 +5695,10 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "读å–‘%s’时出错:%s\n"
+
+#, fuzzy, c-format
msgid "error changing TOFU policy: %s\n"
msgstr "生æˆå¯†ç çš„时候å‘生错误:%s\n"
@@ -5855,6 +5854,10 @@ msgstr "使用‘%s’信任模型时ä¸éœ€è¦æ£€æŸ¥ä¿¡ä»»åº¦æ•°æ®åº“\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "使用‘%s’信任模型时ä¸éœ€è¦æ›´æ–°ä¿¡ä»»åº¦æ•°æ®åº“\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "找ä¸åˆ°å…¬é’¥ %s:%s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "请执行一次 --check-trustdb\n"
@@ -5932,6 +5935,11 @@ msgstr "[ 未知 ]"
msgid "[ undef ]"
msgstr "[未定义]"
+#, fuzzy
+#| msgid "never"
+msgid "[ never ]"
+msgstr "从ä¸"
+
msgid "[marginal]"
msgstr "[ 勉强 ]"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 22aebfa..984ef55 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -440,6 +440,11 @@ msgstr "為 socket å–å¾— nonce 時出錯\n"
msgid "error binding socket to '%s': %s\n"
msgstr "ç¶å®š socket 至 '%s' 時出錯: %s\n"
+#, fuzzy, c-format
+#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
+msgid "can't set permissions of '%s': %s\n"
+msgstr "警告: %s çš„æ¬Šé™ \"%s\" 並ä¸å®‰å…¨\n"
+
#, c-format
msgid "listen() failed: %s\n"
msgstr "listen() 失敗: %s\n"
@@ -456,11 +461,6 @@ msgstr "無法建立目錄 '%s': %s\n"
msgid "directory '%s' created\n"
msgstr "目錄 '%s' 已建立\n"
-#, fuzzy, c-format
-#| msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgid "can't set permissions of '%s': %s\n"
-msgstr "警告: %s çš„æ¬Šé™ \"%s\" 並ä¸å®‰å…¨\n"
-
#, c-format
msgid "stat() failed for '%s': %s\n"
msgstr "'%s' 的 stat() 失敗: %s\n"
@@ -1823,13 +1823,13 @@ msgstr "更改密語"
msgid "export keys"
msgstr "匯出金鑰"
-msgid "export keys to a key server"
+msgid "export keys to a keyserver"
msgstr "把金鑰匯出至金鑰伺æœå™¨"
-msgid "import keys from a key server"
+msgid "import keys from a keyserver"
msgstr "從金鑰伺æœå™¨åŒ¯å…¥é‡‘é‘°"
-msgid "search for keys on a key server"
+msgid "search for keys on a keyserver"
msgstr "在金鑰伺æœå™¨ä¸Šæœå°‹é‡‘é‘°"
msgid "update all keys from a keyserver"
@@ -2388,6 +2388,9 @@ msgstr "僅把時間戳å°çŸ›ç›¾è¦–為警告"
msgid "|FD|write status info to this FD"
msgstr "|檔案æè¿°|把狀態資訊寫入此指定檔案æè¿°"
+msgid "|ALGO|reject signatures made with ALGO"
+msgstr ""
+
msgid "Usage: gpgv [options] [files] (-h for help)"
msgstr "用法: gpgv [é¸é …] [檔案] (或用 -h 求助)"
@@ -3774,6 +3777,10 @@ msgid "No key with this keygrip\n"
msgstr "沒有金鑰有此金鑰鑰柄\n"
#, c-format
+msgid "rounded to %u bits\n"
+msgstr "加大到 %u ä½å…ƒ\n"
+
+#, c-format
msgid "%s keys may be between %u and %u bits long.\n"
msgstr "%s 金鑰的長度å¯èƒ½ä»‹æ–¼ %u ä½å…ƒå’Œ %u ä½å…ƒä¹‹é–“.\n"
@@ -3789,10 +3796,6 @@ msgstr "你想è¦ç”¨å¤šå¤§çš„金鑰尺寸? (%u) "
msgid "Requested keysize is %u bits\n"
msgstr "你所è¦æ±‚的金鑰尺寸是 %u ä½å…ƒ\n"
-#, c-format
-msgid "rounded to %u bits\n"
-msgstr "加大到 %u ä½å…ƒ\n"
-
msgid "Please select which elliptic curve you want:\n"
msgstr "è«‹é¸æ“‡ä½ è¦ä½¿ç”¨çš„橢圓曲線:\n"
@@ -5390,15 +5393,6 @@ msgid "error updating TOFU database: %s\n"
msgstr "é€å‡ºè³‡æ–™æ™‚出錯: %s\n"
#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "找ä¸åˆ°å…¬é‘° %s: %s\n"
-
-#, fuzzy, c-format
-#| msgid "error setting OCSP target: %s\n"
-msgid "error setting TOFU binding's trust level to %s\n"
-msgstr "設定 OCSP 目標時出錯: %s\n"
-
-#, c-format
msgid "The binding %s is NOT known."
msgstr ""
@@ -5473,14 +5467,14 @@ msgid_plural " over the past %ld months."
msgstr[0] ""
#. 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.
+#. * 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 ""
#. 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.
+#. * version of the hotkey) for each of the five choices. If
+#. * there is only one choice in your language, repeat it.
msgid "gGaAuUrRbB"
msgstr ""
@@ -5488,6 +5482,11 @@ msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? "
msgstr ""
#, fuzzy, c-format
+#| msgid "error setting OCSP target: %s\n"
+msgid "error setting TOFU binding's trust level to %s\n"
+msgstr "設定 OCSP 目標時出錯: %s\n"
+
+#, fuzzy, c-format
#| msgid "error creating a pipe: %s\n"
msgid "error changing TOFU policy: %s\n"
msgstr "建立管é“時出錯: %s\n"
@@ -5635,6 +5634,10 @@ msgstr "在 '%s' 信任模型中並ä¸éœ€è¦æª¢æŸ¥ä¿¡ä»»è³‡æ–™åº«\n"
msgid "no need for a trustdb update with '%s' trust model\n"
msgstr "在 '%s' 信任模型中並ä¸éœ€è¦æ›´æ–°ä¿¡ä»»è³‡æ–™åº«\n"
+#, c-format
+msgid "public key %s not found: %s\n"
+msgstr "找ä¸åˆ°å…¬é‘° %s: %s\n"
+
msgid "please do a --check-trustdb\n"
msgstr "è«‹åšä¸€æ¬¡ --check-trustdb\n"
@@ -5715,6 +5718,11 @@ msgstr "未知"
msgid "[ undef ]"
msgstr ""
+#, fuzzy
+#| msgid "never "
+msgid "[ never ]"
+msgstr "æ°¸é ä¸éŽæœŸ"
+
msgid "[marginal]"
msgstr ""
diff --git a/scd/command.c b/scd/command.c
index 72ff132..a4a2ba0 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -2281,7 +2281,7 @@ update_reader_status_file (int set_card_removed_flag)
depends on how client sessions will associate the reader
status with their session. */
snprintf (templ, sizeof templ, "reader_%d.status", vr->slot);
- fname = make_filename (opt.homedir, templ, NULL );
+ fname = make_filename (gnupg_homedir (), templ, NULL );
fp = fopen (fname, "w");
if (fp)
{
@@ -2300,7 +2300,7 @@ update_reader_status_file (int set_card_removed_flag)
char *homestr, *envstr;
gpg_error_t err;
- homestr = make_filename (opt.homedir, NULL);
+ homestr = make_filename (gnupg_homedir (), NULL);
if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
log_error ("out of core while building environment\n");
else
@@ -2323,7 +2323,7 @@ update_reader_status_file (int set_card_removed_flag)
(status & 2)? "PRESENT": "NOCARD");
args[8] = NULL;
- fname = make_filename (opt.homedir, "scd-event", NULL);
+ fname = make_filename (gnupg_homedir (), "scd-event", NULL);
err = gnupg_spawn_process_detached (fname, args, envs);
if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
log_error ("failed to run event handler '%s': %s\n",
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index e8218ca..9c11cad 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -371,18 +371,10 @@ cleanup (void)
if (socket_name && *socket_name)
{
char *name;
- char *p;
name = redir_socket_name? redir_socket_name : socket_name;
gnupg_remove (name);
- p = strrchr (name, '/');
- if (p)
- {
- *p = 0;
- rmdir (name);
- *p = '/';
- }
*socket_name = 0;
}
}
@@ -463,8 +455,6 @@ main (int argc, char **argv )
if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
csh_style = 1;
- opt.homedir = default_homedir ();
-
/* Check whether we have a config file on the commandline */
orig_argc = argc;
orig_argv = argv;
@@ -484,7 +474,7 @@ main (int argc, char **argv )
else if (pargs.r_opt == oNoOptions)
default_config = 0; /* --no-options */
else if (pargs.r_opt == oHomedir)
- opt.homedir = pargs.r.ret_str;
+ gnupg_set_homedir (pargs.r.ret_str);
}
/* initialize the secure memory. */
@@ -497,7 +487,7 @@ main (int argc, char **argv )
if (default_config)
- configname = make_filename (opt.homedir, SCDAEMON_NAME EXTSEP_S "conf",
+ configname = make_filename (gnupg_homedir (), SCDAEMON_NAME EXTSEP_S "conf",
NULL );
@@ -582,7 +572,7 @@ main (int argc, char **argv )
case oNoGreeting: nogreeting = 1; break;
case oNoVerbose: opt.verbose = 0; break;
case oNoOptions: break; /* no-options */
- case oHomedir: opt.homedir = pargs.r.ret_str; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oNoDetach: nodetach = 1; break;
case oLogFile: logfile = pargs.r.ret_str; break;
case oCsh: csh_style = 1; break;
@@ -674,8 +664,8 @@ main (int argc, char **argv )
if (config_filename)
filename = xstrdup (config_filename);
else
- filename = make_filename (opt.homedir, SCDAEMON_NAME EXTSEP_S "conf",
- NULL);
+ filename = make_filename (gnupg_homedir (),
+ SCDAEMON_NAME EXTSEP_S "conf", NULL);
filename_esc = percent_escape (filename, NULL);
es_printf ("%s-%s.conf:%lu:\"%s\n",
@@ -1044,7 +1034,7 @@ create_socket_name (char *standard_name)
{
char *name;
- name = make_filename (opt.homedir, standard_name, NULL);
+ name = make_filename (gnupg_socketdir (), standard_name, NULL);
if (strchr (name, PATHSEP_C))
{
log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
@@ -1122,6 +1112,10 @@ create_server_socket (const char *name, char **r_redir_name,
scd_exit (2);
}
+ if (gnupg_chmod (unaddr->sun_path, "-rwx"))
+ log_error (_("can't set permissions of '%s': %s\n"),
+ unaddr->sun_path, strerror (errno));
+
if (listen (FD2INT(fd), 5 ) == -1)
{
log_error (_("listen() failed: %s\n"),
diff --git a/scd/scdaemon.h b/scd/scdaemon.h
index 1a95ba7..448cb84 100644
--- a/scd/scdaemon.h
+++ b/scd/scdaemon.h
@@ -51,7 +51,6 @@ struct
int quiet; /* Be as quiet as possible. */
int dry_run; /* Don't change any persistent data. */
int batch; /* Batch mode. */
- const char *homedir; /* Configuration directory name. */
const char *ctapi_driver; /* Library to access the ctAPI. */
const char *pcsc_driver; /* Library to access the PC/SC system. */
const char *reader_port; /* NULL or reder port to use. */
diff --git a/sm/call-agent.c b/sm/call-agent.c
index 8c1c727..c7facbb 100644
--- a/sm/call-agent.c
+++ b/sm/call-agent.c
@@ -133,7 +133,6 @@ start_agent (ctrl_t ctrl)
{
rc = start_new_gpg_agent (&agent_ctx,
GPG_ERR_SOURCE_DEFAULT,
- opt.homedir,
opt.agent_program,
opt.lc_ctype, opt.lc_messages,
opt.session_env,
diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
index 881c484..7e26c3a 100644
--- a/sm/call-dirmngr.c
+++ b/sm/call-dirmngr.c
@@ -248,7 +248,7 @@ start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r)
to take care of the implicit option sending caching. */
err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT,
- opt.homedir, opt.dirmngr_program,
+ opt.dirmngr_program,
opt.autostart, opt.verbose, DBG_IPC,
gpgsm_status2, ctrl);
if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_DIRMNGR)
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index fc6d1c7..9b7dd4b 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -211,8 +211,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_c (aKeygen, "gen-key", N_("generate a new key pair")),
ARGPARSE_c (aDeleteKey, "delete-keys",
N_("remove keys from the public keyring")),
-/*ARGPARSE_c (aSendKeys, "send-keys", N_("export keys to a key server")),*/
-/*ARGPARSE_c (aRecvKeys, "recv-keys", N_("import keys from a key server")),*/
+/*ARGPARSE_c (aSendKeys, "send-keys", N_("export keys to a keyserver")),*/
+/*ARGPARSE_c (aRecvKeys, "recv-keys", N_("import keys from a keyserver")),*/
ARGPARSE_c (aImport, "import", N_("import certificates")),
ARGPARSE_c (aExport, "export", N_("export certificates")),
@@ -581,7 +581,7 @@ my_strusage( int level )
break;
case 31: p = "\nHome: "; break;
- case 32: p = opt.homedir; break;
+ case 32: p = gnupg_homedir (); break;
case 33: p = _("\nSupported algorithms:\n"); break;
case 34:
if (!ciphers)
@@ -964,8 +964,6 @@ main ( int argc, char **argv)
remember to update the Gpgconflist entry as well. */
opt.def_cipher_algoid = DEFAULT_CIPHER_ALGO;
- opt.homedir = default_homedir ();
-
/* First check whether we have a config file on the commandline */
orig_argc = argc;
@@ -989,7 +987,7 @@ main ( int argc, char **argv)
opt.no_homedir_creation = 1;
}
else if (pargs.r_opt == oHomedir)
- opt.homedir = pargs.r.ret_str;
+ gnupg_set_homedir (pargs.r.ret_str);
else if (pargs.r_opt == aCallProtectTool)
break; /* This break makes sure that --version and --help are
passed to the protect-tool. */
@@ -1024,9 +1022,10 @@ main ( int argc, char **argv)
/* Set the default option file */
if (default_config )
- configname = make_filename (opt.homedir, GPGSM_NAME EXTSEP_S "conf", NULL);
+ configname = make_filename (gnupg_homedir (),
+ GPGSM_NAME EXTSEP_S "conf", NULL);
/* Set the default policy file */
- opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL);
+ opt.policy_file = make_filename (gnupg_homedir (), "policies.txt", NULL);
argc = orig_argc;
argv = orig_argv;
@@ -1304,7 +1303,7 @@ main ( int argc, char **argv)
}
break;
case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
- case oHomedir: opt.homedir = pargs.r.ret_str; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
case oDisplay:
@@ -1468,7 +1467,7 @@ main ( int argc, char **argv)
configname = NULL;
if (!opt.config_filename)
- opt.config_filename = make_filename (opt.homedir,
+ opt.config_filename = make_filename (gnupg_homedir (),
GPGSM_NAME EXTSEP_S "conf",
NULL);
@@ -1560,6 +1559,8 @@ main ( int argc, char **argv)
else if (!strcmp (opt.def_cipher_algoid, "AES")
|| !strcmp (opt.def_cipher_algoid, "AES128"))
opt.def_cipher_algoid = "2.16.840.1.101.3.4.1.2";
+ else if (!strcmp (opt.def_cipher_algoid, "AES192") )
+ opt.def_cipher_algoid = "2.16.840.1.101.3.4.1.22";
else if (!strcmp (opt.def_cipher_algoid, "AES256") )
opt.def_cipher_algoid = "2.16.840.1.101.3.4.1.42";
else if (!strcmp (opt.def_cipher_algoid, "SERPENT")
@@ -1567,7 +1568,7 @@ main ( int argc, char **argv)
opt.def_cipher_algoid = "1.3.6.1.4.1.11591.13.2.2";
else if (!strcmp (opt.def_cipher_algoid, "SERPENT192") )
opt.def_cipher_algoid = "1.3.6.1.4.1.11591.13.2.22";
- else if (!strcmp (opt.def_cipher_algoid, "SERPENT192") )
+ else if (!strcmp (opt.def_cipher_algoid, "SERPENT256") )
opt.def_cipher_algoid = "1.3.6.1.4.1.11591.13.2.42";
else if (!strcmp (opt.def_cipher_algoid, "SEED") )
opt.def_cipher_algoid = "1.2.410.200004.1.4";
@@ -1605,7 +1606,7 @@ main ( int argc, char **argv)
/* Set the random seed file. */
if (use_random_seed)
{
- char *p = make_filename (opt.homedir, "random_seed", NULL);
+ char *p = make_filename (gnupg_homedir (), "random_seed", NULL);
gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
xfree(p);
}
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 5aad4b1..9751df4 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -61,7 +61,6 @@ struct
int dry_run; /* don't change any persistent data */
int no_homedir_creation;
- const char *homedir; /* Configuration directory name */
const char *config_filename; /* Name of the used config file. */
const char *agent_program;
diff --git a/sm/keydb.c b/sm/keydb.c
index 495eb49..8a1efd4 100644
--- a/sm/keydb.c
+++ b/sm/keydb.c
@@ -287,7 +287,7 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created)
if (strchr(resname, DIRSEP_C) )
filename = make_filename (resname, NULL);
else
- filename = make_filename (opt.homedir, resname, NULL);
+ filename = make_filename (gnupg_homedir (), resname, NULL);
}
else
filename = xstrdup (resname);
diff --git a/sm/server.c b/sm/server.c
index a43ff34..8b4a29c 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -1308,7 +1308,7 @@ gpgsm_server (certlist_t default_recplist)
}
if (opt.verbose || opt.debug)
{
- char *tmp = NULL;
+ char *tmp;
/* Fixme: Use the really used socket name. */
if (asprintf (&tmp,
@@ -1316,7 +1316,7 @@ gpgsm_server (certlist_t default_recplist)
"Config: %s\n"
"DirmngrInfo: %s\n"
"%s",
- opt.homedir,
+ gnupg_homedir (),
opt.config_filename,
(dirmngr_user_socket_name ()
? dirmngr_user_socket_name ()
diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am
index bab0b7d..bb1047d 100644
--- a/tests/openpgp/Makefile.am
+++ b/tests/openpgp/Makefile.am
@@ -57,6 +57,7 @@ TESTS = version.test mds.test \
import.test ecc.test 4gb-packet.test \
$(sqlite3_dependent_tests) \
gpgtar.test use-exact-key.test default-key.test \
+ export.test \
finish.test
@@ -123,7 +124,8 @@ CLEANFILES = prepared.stamp x y yy z out err $(data_files) \
*.test.log gpg_dearmor gpg.conf gpg-agent.conf S.gpg-agent \
pubring.gpg pubring.gpg~ pubring.kbx pubring.kbx~ \
secring.gpg pubring.pkr secring.skr \
- gnupg-test.stop random_seed gpg-agent.log tofu.db
+ gnupg-test.stop random_seed gpg-agent.log tofu.db \
+ passphrases
clean-local:
-rm -rf private-keys-v1.d openpgp-revocs.d tofu.d gpgtar.d
diff --git a/tests/openpgp/export.test b/tests/openpgp/export.test
new file mode 100755
index 0000000..9776760
--- /dev/null
+++ b/tests/openpgp/export.test
@@ -0,0 +1,110 @@
+#!/bin/sh
+
+. $srcdir/defs.inc || exit 3
+
+check_exported_public_key()
+{
+ $GPG --list-packets $1 >$1.packets
+ grep '^:public key packet:' $1.packets >/dev/null
+ grep "^ keyid: .*$KEY$" $1.packets >/dev/null
+ grep '^:user ID packet:' $1.packets >/dev/null
+ grep "^:signature packet:.*keyid.*$KEY" $1.packets >/dev/null
+ rm $1.packets
+}
+
+check_armored_public_key()
+{
+ grep '^-----BEGIN PGP PUBLIC KEY BLOCK-----$' $1 >/dev/null
+ grep '^-----END PGP PUBLIC KEY BLOCK-----$' $1 >/dev/null
+ check_exported_public_key $1
+}
+
+check_exported_private_key()
+{
+ $GPG --list-packets $1 >$1.packets
+ grep '^:secret key packet:' $1.packets >/dev/null
+ grep "^ keyid: .*$KEY$" $1.packets >/dev/null
+ grep '^:user ID packet:' $1.packets >/dev/null
+ grep "^:signature packet:.*keyid.*$KEY" $1.packets >/dev/null
+ rm $1.packets
+}
+
+check_armored_private_key()
+{
+ grep '^-----BEGIN PGP PRIVATE KEY BLOCK-----$' $1 >/dev/null
+ grep '^-----END PGP PRIVATE KEY BLOCK-----$' $1 >/dev/null
+ check_exported_private_key $1
+}
+
+logfile="`pwd`/pinentry.log"
+ppfile="`pwd`/passphrases"
+rm -f -- $logfile $ppfile
+touch $ppfile
+
+prepare_passphrase()
+{
+ echo $* >>$ppfile
+}
+
+prepare_passphrase_confirm()
+{
+ echo "fake-entry being started to CONFIRM the weak phrase" >>$ppfile
+}
+
+assert_passphrases_consumed()
+{
+ if test -s $ppfile; then
+ echo "Expected $ppfile to be empty, but these are enqueued:" >&2
+ cat "$ppfile" >&2
+ exit 1
+ fi
+ rm -f -- $logfile
+}
+
+export PINENTRY_USER_DATA="--logfile=$logfile --passphrasefile=$ppfile"
+
+info "Checking key export."
+for KEY in D74C5F22 C40FDECF ECABF51D
+do
+ progress $KEY
+
+ $GPG --export $KEY >$KEY.public
+ check_exported_public_key $KEY.public
+ rm $KEY.public
+
+ $GPG --armor --export $KEY >$KEY.public
+ check_armored_public_key $KEY.public
+ rm $KEY.public
+
+ # test without --armor:
+
+ if [ $KEY = D74C5F22 ]; then
+ # Key D74C5F22 is protected by a passphrase. Prepare this
+ # one. Currently, GnuPG does not ask for an export passphrase
+ # in this case.
+ prepare_passphrase "$usrpass1"
+ fi
+
+ $GPG --export-secret-keys $KEY >$KEY.private
+ check_exported_private_key $KEY.private
+ rm $KEY.private
+
+ assert_passphrases_consumed
+
+ # test with --armor:
+
+ if [ $KEY = D74C5F22 ]; then
+ # Key D74C5F22 is protected by a passphrase. Prepare this
+ # one. Currently, GnuPG does not ask for an export passphrase
+ # in this case.
+ prepare_passphrase "$usrpass1"
+ fi
+
+ $GPG --armor --export-secret-keys $KEY >$KEY.private
+ check_armored_private_key $KEY.private
+ rm $KEY.private
+
+ assert_passphrases_consumed
+done
+
+progress_end
diff --git a/tests/openpgp/fake-pinentry.c b/tests/openpgp/fake-pinentry.c
index b8aa848..a651726 100644
--- a/tests/openpgp/fake-pinentry.c
+++ b/tests/openpgp/fake-pinentry.c
@@ -21,30 +21,208 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
+
+FILE *log_stream;
+
+int
+reply (const char *fmt, ...)
+{
+ int result;
+ va_list ap;
+
+ if (log_stream)
+ {
+ fprintf (log_stream, "> ");
+ va_start (ap, fmt);
+ vfprintf (log_stream, fmt, ap);
+ va_end (ap);
+ }
+ va_start (ap, fmt);
+ result = vprintf (fmt, ap);
+ va_end (ap);
+
+ return result;
+}
+
+/* Return the first line from FNAME, removing it from the file. */
+char *
+get_passphrase (const char *fname)
+{
+ char *passphrase = NULL;
+ size_t fname_len;
+ char *fname_new;
+ FILE *source, *sink;
+ char linebuf[80];
+
+ fname_len = strlen (fname);
+ fname_new = malloc (fname_len + 5);
+ if (fname_new == NULL)
+ {
+ perror ("malloc");
+ exit (1);
+ }
+ snprintf (fname_new, fname_len + 5, "%s.new", fname);
+
+ source = fopen (fname, "r");
+ if (! source)
+ {
+ perror (fname);
+ exit (1);
+ }
+
+ sink = fopen (fname_new, "w");
+ if (! sink)
+ {
+ perror (fname_new);
+ exit (1);
+ }
+
+ while (fgets (linebuf, sizeof linebuf, source))
+ {
+ linebuf[sizeof linebuf - 1] = 0;
+ if (passphrase == NULL)
+ {
+ passphrase = strdup (linebuf);
+ if (passphrase == NULL)
+ {
+ perror ("strdup");
+ exit (1);
+ }
+ }
+ else
+ fputs (linebuf, sink);
+ }
+
+ if (ferror (source))
+ {
+ perror (fname);
+ exit (1);
+ }
+
+ if (ferror (sink))
+ {
+ perror (fname_new);
+ exit (1);
+ }
+
+ fclose (source);
+ fclose (sink);
+ rename (fname_new, fname);
+ return passphrase;
+}
+
+
+#define spacep(p) (*(p) == ' ' || *(p) == '\t')
+
+/* Skip over options in LINE.
+
+ Blanks after the options are also removed. Options are indicated
+ by two leading dashes followed by a string consisting of non-space
+ characters. The special option "--" indicates an explicit end of
+ options; all what follows will not be considered an option. The
+ first no-option string also indicates the end of option parsing. */
+char *
+skip_options (const char *line)
+{
+ while (spacep (line))
+ line++;
+ while (*line == '-' && line[1] == '-')
+ {
+ while (*line && !spacep (line))
+ line++;
+ while (spacep (line))
+ line++;
+ }
+ return (char*) line;
+}
+
+
+/* Return a pointer to the argument of the option with NAME. If such
+ an option is not given, NULL is returned. */
+char *
+option_value (const char *line, const char *name)
+{
+ char *s;
+ int n = strlen (name);
+
+ s = strstr (line, name);
+ if (s && s >= skip_options (line))
+ return NULL;
+ if (s && (s == line || spacep (s-1))
+ && s[n] && (spacep (s+n) || s[n] == '='))
+ {
+ s += n + 1;
+ s += strspn (s, " ");
+ if (*s && !spacep(s))
+ return s;
+ }
+ return NULL;
+}
int
main (int argc, char **argv)
{
- static char *passphrase;
- char *p;
+ char *args;
+ char *logfile;
+ char *passphrasefile;
+ char *passphrase;
+ /* We get our options via PINENTRY_USER_DATA. */
(void) argc, (void) argv;
setvbuf (stdin, NULL, _IOLBF, BUFSIZ);
setvbuf (stdout, NULL, _IOLBF, BUFSIZ);
- if (!passphrase)
+ args = getenv ("PINENTRY_USER_DATA");
+ if (! args)
+ args = "";
+
+ logfile = option_value (args, "--logfile");
+ if (logfile)
+ {
+ char *p = logfile, more;
+ while (*p && ! spacep (p))
+ p++;
+ more = !! *p;
+ *p = 0;
+ args = more ? p+1 : p;
+
+ log_stream = fopen (logfile, "a");
+ if (! log_stream)
+ {
+ perror (logfile);
+ return 1;
+ }
+ }
+
+ passphrasefile = option_value (args, "--passphrasefile");
+ if (passphrasefile)
{
- passphrase = getenv ("PINENTRY_USER_DATA");
- if (!passphrase)
- passphrase = "";
- for (p=passphrase; *p; p++)
- if (*p == '\r' || *p == '\n')
- *p = '.';
- printf ("# Passphrase='%s'\n", passphrase);
+ char *p = passphrasefile, more;
+ while (*p && ! spacep (p))
+ p++;
+ more = !! *p;
+ *p = 0;
+ args = more ? p+1 : p;
+
+ passphrase = get_passphrase (passphrasefile);
+ if (! passphrase)
+ {
+ reply ("# Passphrasefile '%s' is empty. Terminating.\n",
+ passphrasefile);
+ return 1;
+ }
+
+ p = passphrase + strlen (passphrase) - 1;
+ if (*p == '\n')
+ *p = 0;
}
+ else
+ passphrase = skip_options (args);
- printf ("OK - what's up?\n");
+ reply ("# fake-pinentry started. Passphrase='%s'.\n", passphrase);
+ reply ("OK - what's up?\n");
while (! feof (stdin))
{
@@ -53,15 +231,23 @@ main (int argc, char **argv)
if (fgets (buffer, sizeof buffer, stdin) == NULL)
break;
+ if (log_stream)
+ fprintf (log_stream, "< %s", buffer);
+
if (strncmp (buffer, "GETPIN", 6) == 0)
- printf ("D %s\nOK\n", passphrase);
+ reply ("D %s\n", passphrase);
else if (strncmp (buffer, "BYE", 3) == 0)
{
- printf ("OK\n");
+ reply ("OK\n");
break;
}
- else
- printf ("OK\n");
+
+ reply ("OK\n");
}
+
+ reply ("# Connection terminated.\n");
+ if (log_stream)
+ fclose (log_stream);
+
return 0;
}
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 39c0f9c..d43ede8 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -17,7 +17,7 @@
# along with this program; if not, see <http://www.gnu.org/licenses/>.
EXTRA_DIST = \
- Manifest watchgnupg.c \
+ Manifest watchgnupg.c no-libgcrypt.c \
addgnupghome applygnupgdefaults \
lspgpot mail-signed-keys convert-from-106 sockprox.c \
ccidmon.c ChangeLog-2011 gpg-connect-agent-w32info.rc
@@ -91,12 +91,12 @@ gpgsplit_LDADD = $(common_libs) \
$(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
$(ZLIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV)
-gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c
+gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c
# common sucks in gpg-error, will they, nil they (some compilers
# do not eliminate the supposed-to-be-unused-inline-functions).
gpgconf_LDADD = $(maybe_commonpth_libs) $(opt_libassuan_libs) \
- $(LIBINTL) $(GPG_ERROR_LIBS) $(NETLIBS) \
+ $(LIBINTL) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(NETLIBS) \
$(LIBICONV) $(W32SOCKLIBS)
gpgconf_LDFLAGS = $(extra_bin_ldflags)
@@ -111,10 +111,11 @@ symcryptrun_LDADD = $(LIBUTIL_LIBS) $(common_libs) $(pwquery_libs) \
watchgnupg_SOURCES = watchgnupg.c
watchgnupg_LDADD = $(NETLIBS)
-gpg_connect_agent_SOURCES = gpg-connect-agent.c no-libgcrypt.c
-# FIXME: remove PTH_LIBS (why do we need them at all?)
+gpg_connect_agent_SOURCES = gpg-connect-agent.c
+# FIXME: remove NPTH_LIBS (why do we need them at all?)
gpg_connect_agent_LDADD = ../common/libgpgrl.a $(common_libs) \
- $(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
+ $(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) \
+ $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
$(LIBREADLINE) $(LIBINTL) $(NETLIBS) $(LIBICONV) \
$(resource_objs)
@@ -130,10 +131,9 @@ gpgtar_SOURCES = \
gpgtar.c gpgtar.h \
gpgtar-create.c \
gpgtar-extract.c \
- gpgtar-list.c \
- no-libgcrypt.c
+ gpgtar-list.c
gpgtar_CFLAGS = $(GPG_ERROR_CFLAGS)
-gpgtar_LDADD = $(libcommon) $(GPG_ERROR_LIBS) \
+gpgtar_LDADD = $(libcommon) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
$(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS)
diff --git a/tools/gpg-check-pattern.c b/tools/gpg-check-pattern.c
index fbf30a2..37283a1 100644
--- a/tools/gpg-check-pattern.c
+++ b/tools/gpg-check-pattern.c
@@ -181,8 +181,6 @@ main (int argc, char **argv )
setup_libgcrypt_logging ();
gcry_control (GCRYCTL_INIT_SECMEM, 4096, 0);
- opt.homedir = default_homedir ();
-
pargs.argc = &argc;
pargs.argv = &argv;
pargs.flags= 1; /* (do not remove the args) */
@@ -191,7 +189,7 @@ main (int argc, char **argv )
switch (pargs.r_opt)
{
case oVerbose: opt.verbose++; break;
- case oHomedir: opt.homedir = pargs.r.ret_str; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oCheck: opt.checkonly = 1; break;
case oNull: opt.null = 1; break;
diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c
index 2e00b8f..1cd554f 100644
--- a/tools/gpg-connect-agent.c
+++ b/tools/gpg-connect-agent.c
@@ -209,7 +209,7 @@ my_strusage( int level )
"Connect to a running agent and send commands\n");
break;
case 31: p = "\nHome: "; break;
- case 32: p = opt.homedir; break;
+ case 32: p = gnupg_homedir (); break;
case 33: p = "\n"; break;
default: p = NULL; break;
@@ -555,7 +555,7 @@ get_var_ext (const char *name)
log_error ("getcwd failed: %s\n", strerror (errno));
}
else if (!strcmp (s, "homedir"))
- result = make_filename (opt.homedir, NULL);
+ result = xstrdup (gnupg_homedir ());
else if (!strcmp (s, "sysconfdir"))
result = xstrdup (gnupg_sysconfdir ());
else if (!strcmp (s, "bindir"))
@@ -1181,7 +1181,6 @@ main (int argc, char **argv)
assuan_set_gpg_err_source (0);
- opt.homedir = default_homedir ();
opt.autostart = 1;
opt.connect_flags = 1;
@@ -1196,7 +1195,7 @@ main (int argc, char **argv)
case oQuiet: opt.quiet = 1; break;
case oVerbose: opt.verbose++; break;
case oNoVerbose: opt.verbose = 0; break;
- case oHomedir: opt.homedir = pargs.r.ret_str; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
case oNoAutostart: opt.autostart = 0; break;
@@ -1225,7 +1224,7 @@ main (int argc, char **argv)
in particular handy on Windows. */
if (opt.use_uiserver)
{
- opt.raw_socket = make_absfilename (opt.homedir, "S.uiserver", NULL);
+ opt.raw_socket = make_absfilename (gnupg_homedir (), "S.uiserver", NULL);
}
/* Print a warning if an argument looks like an option. */
@@ -2209,7 +2208,6 @@ start_agent (void)
if (opt.use_dirmngr)
err = start_new_dirmngr (&ctx,
GPG_ERR_SOURCE_DEFAULT,
- opt.homedir,
opt.dirmngr_program,
opt.autostart,
!opt.quiet, 0,
@@ -2217,7 +2215,6 @@ start_agent (void)
else
err = start_new_gpg_agent (&ctx,
GPG_ERR_SOURCE_DEFAULT,
- opt.homedir,
opt.agent_program,
NULL, NULL,
session_env,
diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index 4dd10a4..3d456a9 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -1626,7 +1626,7 @@ gc_component_check_options (int component, estream_t out, const char *conf_file)
result = 0;
errlines = NULL;
- err = gnupg_spawn_process (pgmname, argv, GPG_ERR_SOURCE_DEFAULT, NULL, 0,
+ err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
NULL, NULL, &errfp, &pid);
if (err)
result |= 1; /* Program could not be run. */
@@ -1965,7 +1965,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
argv[0] = "--gpgconf-list";
argv[1] = NULL;
- err = gnupg_spawn_process (pgmname, argv, GPG_ERR_SOURCE_DEFAULT, NULL, 0,
+ err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
NULL, &outfp, NULL, &pid);
if (err)
{
diff --git a/tools/gpgconf.c b/tools/gpgconf.c
index 180c88a..2b177e2 100644
--- a/tools/gpgconf.c
+++ b/tools/gpgconf.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "gpgconf.h"
#include "i18n.h"
@@ -53,6 +54,8 @@ enum cmd_and_opt_values
aListDirs,
aLaunch,
aKill,
+ aCreateSocketDir,
+ aRemoveSocketDir,
aReload
};
@@ -78,6 +81,8 @@ static ARGPARSE_OPTS opts[] =
{ aReload, "reload", 256, N_("reload all or a given component")},
{ aLaunch, "launch", 256, N_("launch a given component")},
{ aKill, "kill", 256, N_("kill a given component")},
+ { aCreateSocketDir, "create-socketdir", 256, "@"},
+ { aRemoveSocketDir, "remove-socketdir", 256, "@"},
{ 301, NULL, 0, N_("@\nOptions:\n ") },
@@ -87,6 +92,7 @@ static ARGPARSE_OPTS opts[] =
{ oDryRun, "dry-run", 0, N_("do not make any changes") },
{ oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") },
/* hidden options */
+ { oHomedir, "homedir", 2, "@" },
{ oNoVerbose, "no-verbose", 0, "@"},
{0}
};
@@ -176,6 +182,7 @@ main (int argc, char **argv)
break;
case oVerbose: opt.verbose++; break;
case oNoVerbose: opt.verbose = 0; break;
+ case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case aListDirs:
case aListComponents:
@@ -189,6 +196,8 @@ main (int argc, char **argv)
case aReload:
case aLaunch:
case aKill:
+ case aCreateSocketDir:
+ case aRemoveSocketDir:
cmd = pargs.r_opt;
break;
@@ -375,18 +384,77 @@ main (int argc, char **argv)
}
{
- char *tmp = make_filename (default_homedir (),
+ char *tmp = make_filename (gnupg_socketdir (),
GPG_AGENT_SOCK_NAME, NULL);
es_fprintf (outfp, "agent-socket:%s\n", gc_percent_escape (tmp));
xfree (tmp);
}
{
- /* We need to use make_filename to expand a possible "~/". */
- char *tmp = make_filename (default_homedir (), NULL);
+ char *tmp = xstrdup (gnupg_homedir ());
es_fprintf (outfp, "homedir:%s\n", gc_percent_escape (tmp));
xfree (tmp);
}
break;
+
+ case aCreateSocketDir:
+ {
+ char *socketdir;
+ unsigned int flags;
+
+ /* Make sure that the top /run/user/UID/gnupg dir has been
+ * created. */
+ gnupg_socketdir ();
+
+ /* Check the /var/run dir. */
+ socketdir = _gnupg_socketdir_internal (1, &flags);
+ if ((flags & 64) && !opt.dry_run)
+ {
+ /* No sub dir - create it. */
+ if (gnupg_mkdir (socketdir, "-rwx"))
+ gc_error (1, errno, "error creating '%s'", socketdir);
+ /* Try again. */
+ socketdir = _gnupg_socketdir_internal (1, &flags);
+ }
+
+ /* Give some info. */
+ if ( (flags & ~32) || opt.verbose || opt.dry_run)
+ {
+ log_info ("socketdir is '%s'\n", socketdir);
+ if ((flags & 1)) log_info ("\tgeneral error\n");
+ if ((flags & 2)) log_info ("\tno /run/user dir\n");
+ if ((flags & 4)) log_info ("\tbad permissions\n");
+ if ((flags & 8)) log_info ("\tbad permissions (subdir)\n");
+ if ((flags & 16)) log_info ("\tmkdir failed\n");
+ if ((flags & 32)) log_info ("\tnon-default homedir\n");
+ if ((flags & 64)) log_info ("\tno such subdir\n");
+ if ((flags & 128)) log_info ("\tusing homedir as fallback\n");
+ }
+
+ if ((flags & ~32) && !opt.dry_run)
+ gc_error (1, 0, "error creating socket directory");
+
+ xfree (socketdir);
+ }
+ break;
+
+ case aRemoveSocketDir:
+ {
+ char *socketdir;
+ unsigned int flags;
+
+ /* Check the /var/run dir. */
+ socketdir = _gnupg_socketdir_internal (1, &flags);
+ if ((flags & 128))
+ log_info ("ignoring request to remove non /run/user socket dir\n");
+ else if (opt.dry_run)
+ ;
+ else if (rmdir (socketdir))
+ gc_error (1, errno, "error removing '%s'", socketdir);
+
+ xfree (socketdir);
+ }
+ break;
+
}
if (outfp != es_stdout)
diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c
index 968dca6..6adc1f5 100644
--- a/tools/gpgtar-create.c
+++ b/tools/gpgtar-create.c
@@ -38,6 +38,7 @@
#include "i18n.h"
#include "../common/exectool.h"
#include "../common/sysutils.h"
+#include "../common/ccparray.h"
#include "gpgtar.h"
#ifndef HAVE_LSTAT
@@ -888,8 +889,8 @@ gpgtar_create (char **inpattern, int encrypt, int sign)
if (encrypt || sign)
{
- int i;
strlist_t arg;
+ ccparray_t ccp;
const char **argv;
err = es_fseek (outstream, 0, SEEK_SET);
@@ -899,46 +900,39 @@ gpgtar_create (char **inpattern, int encrypt, int sign)
/* '--encrypt' may be combined with '--symmetric', but 'encrypt'
is set either way. Clear it if no recipients are specified.
XXX: Fix command handling. */
- if (opt.symmetric && opt.recipients == NULL)
- encrypt = 0;
-
- argv = xtrycalloc (strlist_length (opt.gpg_arguments)
- + 2 * strlist_length (opt.recipients)
- + 1 + !!encrypt + !!sign + 2 * !!opt.user
- + !!opt.symmetric,
- sizeof *argv);
- if (argv == NULL)
- {
- err = gpg_error_from_syserror ();
- goto leave;
- }
- i = 0;
+ if (opt.symmetric && opt.recipients == NULL)
+ encrypt = 0;
+
+ ccparray_init (&ccp, 0);
if (encrypt)
- argv[i++] = "--encrypt";
+ ccparray_put (&ccp, "--encrypt");
if (sign)
- argv[i++] = "--sign";
+ ccparray_put (&ccp, "--sign");
if (opt.user)
{
- argv[i++] = "--local-user";
- argv[i++] = opt.user;
+ ccparray_put (&ccp, "--local-user");
+ ccparray_put (&ccp, opt.user);
}
if (opt.symmetric)
- argv[i++] = "--symmetric";
+ ccparray_put (&ccp, "--symmetric");
for (arg = opt.recipients; arg; arg = arg->next)
{
- argv[i++] = "--recipient";
- argv[i++] = arg->d;
+ ccparray_put (&ccp, "--recipient");
+ ccparray_put (&ccp, arg->d);
}
for (arg = opt.gpg_arguments; arg; arg = arg->next)
- argv[i++] = arg->d;
- argv[i++] = NULL;
- assert (i == strlist_length (opt.gpg_arguments)
- + 2 * strlist_length (opt.recipients)
- + 1 + !!encrypt + !!sign + 2 * !!opt.user
- + !!opt.symmetric);
+ ccparray_put (&ccp, arg->d);
+
+ ccparray_put (&ccp, NULL);
+ argv = ccparray_get (&ccp, NULL);
+ if (!argv)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
err = gnupg_exec_tool_stream (opt.gpg_program, argv,
- outstream, cipher_stream);
+ outstream, NULL, cipher_stream, NULL, NULL);
xfree (argv);
if (err)
goto leave;
diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c
index 95f2b56..866215b 100644
--- a/tools/gpgtar-extract.c
+++ b/tools/gpgtar-extract.c
@@ -30,6 +30,7 @@
#include "i18n.h"
#include "../common/exectool.h"
#include "../common/sysutils.h"
+#include "../common/ccparray.h"
#include "gpgtar.h"
@@ -299,8 +300,8 @@ gpgtar_extract (const char *filename, int decrypt)
if (decrypt)
{
- int i;
strlist_t arg;
+ ccparray_t ccp;
const char **argv;
cipher_stream = stream;
@@ -311,22 +312,22 @@ gpgtar_extract (const char *filename, int decrypt)
goto leave;
}
- argv = xtrycalloc (strlist_length (opt.gpg_arguments) + 2,
- sizeof *argv);
- if (argv == NULL)
+ ccparray_init (&ccp, 0);
+
+ ccparray_put (&ccp, "--decrypt");
+ for (arg = opt.gpg_arguments; arg; arg = arg->next)
+ ccparray_put (&ccp, arg->d);
+
+ ccparray_put (&ccp, NULL);
+ argv = ccparray_get (&ccp, NULL);
+ if (!argv)
{
err = gpg_error_from_syserror ();
goto leave;
}
- i = 0;
- argv[i++] = "--decrypt";
- for (arg = opt.gpg_arguments; arg; arg = arg->next)
- argv[i++] = arg->d;
- argv[i++] = NULL;
- assert (i == strlist_length (opt.gpg_arguments) + 2);
err = gnupg_exec_tool_stream (opt.gpg_program, argv,
- cipher_stream, stream);
+ cipher_stream, NULL, stream, NULL, NULL);
xfree (argv);
if (err)
goto leave;
diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c
index 25c70d2..1d59d9c 100644
--- a/tools/gpgtar-list.c
+++ b/tools/gpgtar-list.c
@@ -27,6 +27,7 @@
#include "i18n.h"
#include "gpgtar.h"
#include "../common/exectool.h"
+#include "../common/ccparray.h"
@@ -299,8 +300,8 @@ gpgtar_list (const char *filename, int decrypt)
if (decrypt)
{
- int i;
strlist_t arg;
+ ccparray_t ccp;
const char **argv;
cipher_stream = stream;
@@ -311,22 +312,22 @@ gpgtar_list (const char *filename, int decrypt)
goto leave;
}
- argv = xtrycalloc (strlist_length (opt.gpg_arguments) + 2,
- sizeof *argv);
- if (argv == NULL)
+ ccparray_init (&ccp, 0);
+
+ ccparray_put (&ccp, "--decrypt");
+ for (arg = opt.gpg_arguments; arg; arg = arg->next)
+ ccparray_put (&ccp, arg->d);
+
+ ccparray_put (&ccp, NULL);
+ argv = ccparray_get (&ccp, NULL);
+ if (!argv)
{
err = gpg_error_from_syserror ();
goto leave;
}
- i = 0;
- argv[i++] = "--decrypt";
- for (arg = opt.gpg_arguments; arg; arg = arg->next)
- argv[i++] = arg->d;
- argv[i++] = NULL;
- assert (i == strlist_length (opt.gpg_arguments) + 2);
err = gnupg_exec_tool_stream (opt.gpg_program, argv,
- cipher_stream, stream);
+ cipher_stream, NULL, stream, NULL, NULL);
xfree (argv);
if (err)
goto leave;
diff --git a/tools/rfc822parse.c b/tools/rfc822parse.c
index f911bd2..215ab52 100644
--- a/tools/rfc822parse.c
+++ b/tools/rfc822parse.c
@@ -1117,7 +1117,7 @@ dump_structure (rfc822parse_t msg, part_t part, int indent)
{
rfc822parse_field_t ctx;
part_t save_part; /* ugly hack - we should have a function to
- get part inforation. */
+ get part information. */
const char *s;
save_part = msg->current_part;
@@ -1177,8 +1177,13 @@ show_event (rfc822parse_event_t event)
case RFC822PARSE_T2BODY: s= "T2Body"; break;
case RFC822PARSE_FINISH: s= "Finish"; break;
case RFC822PARSE_RCVD_SEEN: s= "Rcvd_Seen"; break;
+ case RFC822PARSE_LEVEL_DOWN: s= "Level_Down"; break;
+ case RFC822PARSE_LEVEL_UP: s= "Level_Up"; break;
case RFC822PARSE_BOUNDARY: s= "Boundary"; break;
case RFC822PARSE_LAST_BOUNDARY: s= "Last_Boundary"; break;
+ case RFC822PARSE_BEGIN_HEADER: s= "Begin_Header"; break;
+ case RFC822PARSE_PREAMBLE: s= "Preamble"; break;
+ case RFC822PARSE_EPILOGUE: s= "Epilogue"; break;
default: s= "***invalid event***"; break;
}
printf ("*** got RFC822 event %s\n", s);
diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c
index 4b90cd2..3732b39 100644
--- a/tools/symcryptrun.c
+++ b/tools/symcryptrun.c
@@ -214,7 +214,7 @@ my_strusage (int level)
"Call a simple symmetric encryption tool\n");
break;
case 31: p = "\nHome: "; break;
- case 32: p = opt.homedir; break;
+ case 32: p = gnupg_homedir (); break;
case 33: p = "\n"; break;
default: p = NULL; break;
@@ -896,8 +896,6 @@ main (int argc, char **argv)
i18n_init();
init_common_subsystems (&argc, &argv);
- opt.homedir = default_homedir ();
-
/* Check whether we have a config file given on the commandline */
orig_argc = argc;
orig_argv = argv;
@@ -915,11 +913,11 @@ main (int argc, char **argv)
else if (pargs.r_opt == oNoOptions)
default_config = 0; /* --no-options */
else if (pargs.r_opt == oHomedir)
- opt.homedir = pargs.r.ret_str;
+ gnupg_set_homedir (pargs.r.ret_str);
}
if (default_config)
- configname = make_filename (opt.homedir, "symcryptrun.conf", NULL );
+ configname = make_filename (gnupg_homedir (), "symcryptrun.conf", NULL );
argc = orig_argc;
argv = orig_argv;
@@ -1010,7 +1008,7 @@ main (int argc, char **argv)
/* Tell simple-pwquery about the the standard socket name. */
{
- char *tmp = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
+ char *tmp = make_filename (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
simple_pw_set_socket (tmp);
xfree (tmp);
}