DISTCLEANFILES = g10defs.h
-if BUILD_GPGSM
-kbx = kbx
-else
-kbx =
-endif
-
-
if BUILD_GPG
gpg = g10
else
tests =
endif
-SUBDIRS = m4 common ${kbx} \
+SUBDIRS = m4 common kbx \
${gpg} ${sm} ${agent} ${scd} ${g13} ${dirmngr} \
${tools} po ${doc} ${tests}
+Noteworthy changes in version 2.1.5 (2015-06-11)
+------------------------------------------------
+
+ * Support for an external passphrase cache.
+
+ * Support for the forthcoming version 3 OpenPGP smartcard.
+
+ * Manuals now show the actual used file names.
+
+ * Prepared for improved integration with Emacs.
+
+ * Code cleanups and minor bug fixes.
+
+
Noteworthy changes in version 2.1.4 (2015-05-12)
------------------------------------------------
- * gpg: Add command --quick-adduid to non-interacitivly add a new user
+ * gpg: Add command --quick-adduid to non-interactively add a new user
id to an existing key.
* gpg: Do no enable honor-keyserver-url by default. Make it work if
enabled.
- * gpg: Display the serial number in the --card-staus output again.
+ * gpg: Display the serial number in the --card-status output again.
* agent: Support for external password managers.
Add option --no-allow-external-cache.
to allow it to enable such a cache. */
int allow_external_cache;
+ /* If this global option is true, the Assuan option of Pinentry
+ allow-emacs-prompt is allowed. */
+ int allow_emacs_pinentry;
+
int keep_tty; /* Don't switch the TTY (for pinentry) on request */
int keep_display; /* Don't switch the DISPLAY (for pinentry) on request */
that we use a hack for cleanup handling in gpg-agent.c: If the
value is less than 2 the name has not yet been malloced. */
int extra_socket;
+
+ /* This global options indicates the use of an extra socket for web
+ browsers. Note that we use a hack for cleanup handling in
+ gpg-agent.c: If the value is less than 2 the name has not yet
+ been malloced. */
+ int browser_socket;
} opt;
gnupg_fd_t fd;
} thread_startup;
- /* Flag indicating the connection is run in restricted mode. */
+ /* Flag indicating the connection is run in restricted mode.
+ A value of 1 if used for --extra-socket,
+ a value of 2 is used for --browser-socket. */
int restricted;
/* Private data of the server (command.c). */
const char *keyinfo, cache_mode_t cache_mode);
int agent_get_passphrase (ctrl_t ctrl, char **retpass,
const char *desc, const char *prompt,
- const char *errtext, int with_qualitybar);
+ const char *errtext, int with_qualitybar,
+ const char *keyinfo, cache_mode_t cache_mode);
int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok,
const char *notokay, int with_cancel);
int agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn);
int agent_popup_message_start (ctrl_t ctrl,
const char *desc, const char *ok_btn);
void agent_popup_message_stop (ctrl_t ctrl);
-
+int agent_clear_passphrase (ctrl_t ctrl,
+ const char *keyinfo, cache_mode_t cache_mode);
/*-- cache.c --*/
void initialize_module_cache (void);
return unlock_pinentry (rc);
}
+ if (opt.allow_emacs_pinentry)
+ {
+ /* Indicate to the pinentry that it may read passphrase through
+ Emacs minibuffer, if possible. */
+ rc = assuan_transact (entry_ctx, "OPTION allow-emacs-prompt",
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
+ return unlock_pinentry (rc);
+ }
+
{
/* Provide a few default strings for use by the pinentries. This
int
agent_get_passphrase (ctrl_t ctrl,
char **retpass, const char *desc, const char *prompt,
- const char *errtext, int with_qualitybar)
+ const char *errtext, int with_qualitybar,
+ const char *keyinfo, cache_mode_t cache_mode)
{
int rc;
prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase");
+ /* If we have a KEYINFO string and are normal, user, or ssh cache
+ mode, we tell that the Pinentry so it may use it for own caching
+ purposes. Most pinentries won't have this implemented and thus
+ we do not error out in this case. */
+ if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
+ || cache_mode == CACHE_MODE_USER
+ || cache_mode == CACHE_MODE_SSH))
+ snprintf (line, DIM(line)-1, "SETKEYINFO %c/%s",
+ cache_mode == CACHE_MODE_USER? 'u' :
+ cache_mode == CACHE_MODE_SSH? 's' : 'n',
+ keyinfo);
+ else
+ snprintf (line, DIM(line)-1, "SETKEYINFO --clear");
+
+ rc = assuan_transact (entry_ctx, line,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
+ return unlock_pinentry (rc);
+
+
if (desc)
snprintf (line, DIM(line)-1, "SETDESC %s", desc);
else
/* Now we can close the connection. */
unlock_pinentry (0);
}
+
+int
+agent_clear_passphrase (ctrl_t ctrl,
+ const char *keyinfo, cache_mode_t cache_mode)
+{
+ int rc;
+ char line[ASSUAN_LINELENGTH];
+
+ if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL
+ || cache_mode == CACHE_MODE_USER
+ || cache_mode == CACHE_MODE_SSH)))
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ rc = start_pinentry (ctrl);
+ if (rc)
+ return rc;
+
+ snprintf (line, DIM(line)-1, "CLEARPASSPHRASE %c/%s",
+ cache_mode == CACHE_MODE_USER? 'u' :
+ cache_mode == CACHE_MODE_SSH? 's' : 'n',
+ keyinfo);
+ rc = assuan_transact (entry_ctx, line,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+
+ return unlock_pinentry (rc);
+}
xfree (ctrl->server_local->keydesc);
if (ctrl->restricted)
- ctrl->server_local->keydesc = strconcat
- (_("Note: Request from a remote site."), "%0A%0A", desc, NULL);
+ {
+ ctrl->server_local->keydesc = strconcat
+ ((ctrl->restricted == 2
+ ? _("Note: Request from the web browser.")
+ : _("Note: Request from a remote site.") ), "%0A%0A", desc, NULL);
+ }
else
ctrl->server_local->keydesc = xtrystrdup (desc);
if (!ctrl->server_local->keydesc)
if (!strcmp (desc, "X"))
desc = NULL;
- pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL) : NULL;
+ pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_USER) : NULL;
if (pw)
{
rc = send_back_passphrase (ctx, opt_data, pw);
next_try:
rc = agent_get_passphrase (ctrl, &response, desc, prompt,
repeat_errtext? repeat_errtext:errtext,
- opt_qualbar);
+ opt_qualbar, cacheid, CACHE_MODE_USER);
xfree (repeat_errtext);
repeat_errtext = NULL;
if (!rc)
char *response2;
rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
- errtext, 0);
+ errtext, 0,
+ cacheid, CACHE_MODE_USER);
if (rc)
break;
if (strcmp (response2, response))
agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER,
NULL, 0);
+
+ agent_clear_passphrase (ctrl, cacheid,
+ opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER);
+
return 0;
}
" ssh_socket_name - Return the name of the ssh socket.\n"
" scd_running - Return OK if the SCdaemon is already running.\n"
" s2k_count - Return the calibrated S2K count.\n"
+ " std_env_names - List the names of the standard environment.\n"
" std_session_env - List the standard session environment.\n"
" std_startup_env - List the standard startup environment.\n"
" cmd_has_option\n"
{
rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
}
+ else if (!strcmp (line, "std_env_names"))
+ {
+ int iterator;
+ const char *name;
+
+ iterator = 0;
+ while ((name = session_env_list_stdenvnames (&iterator, NULL)))
+ {
+ rc = assuan_send_data (ctx, name, strlen (name)+1);
+ if (!rc)
+ rc = assuan_send_data (ctx, NULL, 0);
+ if (rc)
+ break;
+ }
+ }
else if (!strcmp (line, "std_session_env")
|| !strcmp (line, "std_startup_env"))
{
oUseStandardSocket,
oNoUseStandardSocket,
oExtraSocket,
+ oBrowserSocket,
oFakedSystemTime,
oIgnoreCacheForSigning,
oAllowPresetPassphrase,
oAllowLoopbackPinentry,
oNoAllowExternalCache,
+ oAllowEmacsPinentry,
oKeepTTY,
oKeepDISPLAY,
oSSHSupport,
ARGPARSE_s_s (oExtraSocket, "extra-socket",
/* */ N_("|NAME|accept some commands via NAME")),
+ ARGPARSE_s_s (oBrowserSocket, "browser-socket", "@"),
+
ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
ARGPARSE_s_n (oBatch, "batch", "@"),
/* */ N_("allow presetting passphrase")),
ARGPARSE_s_n (oAllowLoopbackPinentry, "allow-loopback-pinentry",
N_("allow caller to override the pinentry")),
+ ARGPARSE_s_n (oAllowEmacsPinentry, "allow-emacs-pinentry",
+ /* */ N_("allow passphrase to be prompted through Emacs")),
ARGPARSE_s_n (oSSHSupport, "enable-ssh-support", N_("enable ssh support")),
ARGPARSE_s_n (oPuttySupport, "enable-putty-support",
static char *socket_name_extra;
static char *redir_socket_name_extra;
+/* Name of the optional browser socket used for native gpg-agent requests. */
+static char *socket_name_browser;
+static char *redir_socket_name_browser;
+
/* Name of the communication socket used for ssh-agent-emulation. */
static char *socket_name_ssh;
static char *redir_socket_name_ssh;
POSIX systems). */
static assuan_sock_nonce_t socket_nonce;
static assuan_sock_nonce_t socket_nonce_extra;
+static assuan_sock_nonce_t socket_nonce_browser;
static assuan_sock_nonce_t socket_nonce_ssh;
static void handle_connections (gnupg_fd_t listen_fd,
gnupg_fd_t listen_fd_extra,
+ gnupg_fd_t listen_fd_browser,
gnupg_fd_t listen_fd_ssh);
static void check_own_socket (void);
static int check_for_running_agent (int silent);
remove_socket (socket_name, redir_socket_name);
if (opt.extra_socket > 1)
remove_socket (socket_name_extra, redir_socket_name_extra);
+ if (opt.browser_socket > 1)
+ remove_socket (socket_name_browser, redir_socket_name_browser);
remove_socket (socket_name_ssh, redir_socket_name_ssh);
}
opt.ignore_cache_for_signing = 0;
opt.allow_mark_trusted = 1;
opt.allow_external_cache = 1;
+ opt.allow_emacs_pinentry = 0;
opt.disable_scdaemon = 0;
disable_check_own_socket = 0;
return 1;
case oNoAllowExternalCache: opt.allow_external_cache = 0;
break;
+ case oAllowEmacsPinentry: opt.allow_emacs_pinentry = 1;
+ break;
+
default:
return 0; /* not handled */
}
socket_name_extra = pargs.r.ret_str;
break;
+ case oBrowserSocket:
+ opt.browser_socket = 1; /* (1 = points into argv) */
+ socket_name_browser = pargs.r.ret_str;
+ break;
+
case oDebugQuickRandom:
/* Only used by the first stage command line parser. */
break;
#endif
es_printf ("allow-loopback-pinentry:%lu:\n",
GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
+ es_printf ("allow-emacs-pinentry:%lu:\n",
+ GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
agent_exit (0);
}
{ /* Regular server mode */
gnupg_fd_t fd;
gnupg_fd_t fd_extra = GNUPG_INVALID_FD;
+ gnupg_fd_t fd_browser = GNUPG_INVALID_FD;
gnupg_fd_t fd_ssh = GNUPG_INVALID_FD;
pid_t pid;
&socket_nonce_extra);
}
+ if (opt.browser_socket)
+ {
+ socket_name_browser = create_socket_name (socket_name_browser, 0);
+ opt.browser_socket = 2; /* Indicate that it has been malloced. */
+ fd_browser = create_server_socket (socket_name_browser, 0,
+ &redir_socket_name_browser,
+ &socket_nonce_browser);
+ }
+
if (opt.ssh_support)
{
socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME, 1);
the child should do this from now on */
if (opt.extra_socket)
*socket_name_extra = 0;
+ if (opt.browser_socket)
+ *socket_name_browser = 0;
if (opt.ssh_support)
*socket_name_ssh = 0;
#endif /*!HAVE_W32_SYSTEM*/
log_info ("%s %s started\n", strusage(11), strusage(13) );
- handle_connections (fd, fd_extra, fd_ssh);
+ handle_connections (fd, fd_extra, fd_browser, fd_ssh);
assuan_sock_close (fd);
}
static void *
-start_connection_thread (ctrl_t ctrl)
+do_start_connection_thread (ctrl_t ctrl)
{
- if (check_nonce (ctrl, &socket_nonce))
- {
- log_error ("handler 0x%lx nonce check FAILED\n",
- (unsigned long) npth_self());
- return NULL;
- }
-
agent_init_default_ctrl (ctrl);
if (opt.verbose)
log_info (_("handler 0x%lx for fd %d started\n"),
{
ctrl_t ctrl = arg;
- return start_connection_thread (ctrl);
+ if (check_nonce (ctrl, &socket_nonce))
+ {
+ log_error ("handler 0x%lx nonce check FAILED\n",
+ (unsigned long) npth_self());
+ return NULL;
+ }
+
+ return do_start_connection_thread (ctrl);
}
{
ctrl_t ctrl = arg;
+ if (check_nonce (ctrl, &socket_nonce_extra))
+ {
+ log_error ("handler 0x%lx nonce check FAILED\n",
+ (unsigned long) npth_self());
+ return NULL;
+ }
+
ctrl->restricted = 1;
- return start_connection_thread (ctrl);
+ return do_start_connection_thread (ctrl);
+}
+
+
+/* This is the browser socket connection thread's main function. */
+static void *
+start_connection_thread_browser (void *arg)
+{
+ ctrl_t ctrl = arg;
+
+ if (check_nonce (ctrl, &socket_nonce_browser))
+ {
+ log_error ("handler 0x%lx nonce check FAILED\n",
+ (unsigned long) npth_self());
+ return NULL;
+ }
+
+ ctrl->restricted = 2;
+ return do_start_connection_thread (ctrl);
}
static void
handle_connections (gnupg_fd_t listen_fd,
gnupg_fd_t listen_fd_extra,
+ gnupg_fd_t listen_fd_browser,
gnupg_fd_t listen_fd_ssh)
{
npth_attr_t tattr;
void *(*func) (void *arg);
gnupg_fd_t l_fd;
} listentbl[] = {
- { "std", start_connection_thread_std },
- { "extra",start_connection_thread_extra },
- { "ssh", start_connection_thread_ssh }
+ { "std", start_connection_thread_std },
+ { "extra", start_connection_thread_extra },
+ { "browser", start_connection_thread_browser },
+ { "ssh", start_connection_thread_ssh }
};
if (FD2INT (listen_fd_extra) > nfd)
nfd = FD2INT (listen_fd_extra);
}
+ if (listen_fd_browser != GNUPG_INVALID_FD)
+ {
+ FD_SET ( FD2INT(listen_fd_browser), &fdset);
+ if (FD2INT (listen_fd_browser) > nfd)
+ nfd = FD2INT (listen_fd_browser);
+ }
if (listen_fd_ssh != GNUPG_INVALID_FD)
{
FD_SET ( FD2INT(listen_fd_ssh), &fdset);
listentbl[0].l_fd = listen_fd;
listentbl[1].l_fd = listen_fd_extra;
- listentbl[2].l_fd = listen_fd_ssh;
+ listentbl[2].l_fd = listen_fd_browser;
+ listentbl[3].l_fd = listen_fd_ssh;
npth_clock_gettime (&abstime);
abstime.tv_sec += TIMERTICK_INTERVAL;
localedir = $(datadir)/locale
+# NB: AM_CFLAGS may also be used by tools running on the build
+# platform to create source files.
AM_CPPFLAGS += -DLOCALEDIR=\"$(localedir)\"
if ! HAVE_DOSISH_SYSTEM
};
-/* A list of environment vribales we pass from the actual user
+/* A list of environment variables we pass from the actual user
(e.g. gpgme) down to the pinentry. We do not handle the locale
settings because they do not only depend on envvars. */
static struct
modules (eg "scim-bridge"). */
{ "QT_IM_MODULE" }, /* Used by Qt to select qt input
modules (eg "xim"). */
+ { "INSIDE_EMACS" }, /* Set by Emacs before running a
+ process. */
{ "PINENTRY_USER_DATA", "pinentry-user-data"}
/* Used for communication with
non-standard Pinentries. */
m4_define([mym4_package],[gnupg])
m4_define([mym4_major], [2])
m4_define([mym4_minor], [1])
-m4_define([mym4_micro], [4])
+m4_define([mym4_micro], [5])
# 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
if (lineerr)
return lineerr;
- if (strtol (line+2, NULL, 10) != DBDIRVERSION)
+ /* The !line catches the case of an empty DIR file. We handle this
+ the same as a non-matching version. */
+ if (!line || strtol (line+2, NULL, 10) != DBDIRVERSION)
{
if (!created && cleanup_on_mismatch)
{
*** DECRYPTION_OKAY
The decryption process succeeded. This means, that either the
correct secret key has been used or the correct passphrase for a
- conventional encrypted message was given. The program itself may
+ symmetric encrypted message was given. The program itself may
return an errorcode because it may not be possible to verify a
signature for some reasons.
## Process this file with automake to produce Makefile.in
+AM_CPPFLAGS =
+
+include $(top_srcdir)/am/cmacros.am
+
examples = examples/README examples/scd-event examples/trustlist.txt \
examples/gpgconf.conf examples/pwpattern.list
gnupg-logo.eps gnupg-logo.pdf gnupg-logo.png gnupg-logo-tr.png\
gnupg-card-architecture.eps gnupg-card-architecture.png \
gnupg-card-architecture.pdf \
- FAQ gnupg7.texi \
+ FAQ gnupg7.texi mkdefsinc.c defsincdate \
opt-homedir.texi see-also-note.texi specify-user-id.texi \
gpgv.texi yat2m.c ChangeLog-2011 whats-new-in-2.1.txt
BUILT_SOURCES = gnupg-card-architecture.eps gnupg-card-architecture.png \
- gnupg-card-architecture.pdf
+ gnupg-card-architecture.pdf defsincdate
info_TEXINFOS = gnupg.texi
DVIPS = TEXINPUTS="$(srcdir)$(PATH_SEPARATOR)$$TEXINPUTS" dvips
-AM_MAKEINFOFLAGS = -I $(srcdir) --css-ref=/share/site.css -D gpgtwoone
+AM_MAKEINFOFLAGS = -I $(srcdir) --css-ref=/share/site.css
-YAT2M_OPTIONS = -I $(srcdir) -D gpgtwoone \
+YAT2M_OPTIONS = -I $(srcdir) \
--release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard 2.1"
myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \
watchgnupg_SOURCE = gnupg.texi
-CLEANFILES = yat2m
+CLEANFILES = yat2m mkdefsinc defs.inc
DISTCLEANFILES = gnupg.tmp gnupg.ops yat2m-stamp.tmp yat2m-stamp \
$(myman_pages) gnupg.7
yat2m: yat2m.c
$(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c
+mkdefsinc: mkdefsinc.c Makefile ../config.h
+ $(CC_FOR_BUILD) -I. -I.. -I$(srcdir) $(AM_CPPFLAGS) \
+ -o $@ $(srcdir)/mkdefsinc.c
+
.fig.png:
fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@
fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@
-yat2m-stamp: $(myman_sources)
+yat2m-stamp: $(myman_sources) defs.inc
@rm -f yat2m-stamp.tmp
@touch yat2m-stamp.tmp
for file in $(myman_sources) ; do \
yat2m-stamp: yat2m
-$(myman_pages) gnupg.7 : yat2m-stamp
+$(myman_pages) gnupg.7 : yat2m-stamp defs.inc
@if test -f $@; then :; else \
trap 'rm -rf yat2m-stamp yat2m-lock' 1 2 13 15; \
if mkdir yat2m-lock 2>/dev/null; then \
fi; \
fi
-# Make sure that gnupg.texi is touched if any other source file has
-# been modified. This is required so that the version.texi magic
-# updates the release date.
-gnupg.texi : $(gnupg_TEXINFOS)
- touch $(srcdir)/gnupg.texi
+dist-hook: defsincdate
+
+defsincdate: $(gnupg_TEXINFOS)
+ : >defsincdate ; \
+ if test -d $(top_srcdir)/.git; then \
+ (cd $(srcdir) && git log -1 --format='%ct' \
+ -- $(gnupg_TEXINFOS) 2>/dev/null) >>defsincdate; \
+ fi
+
+defs.inc : defsincdate Makefile mkdefsinc
+ incd="`test -f defsincdate || echo '$(srcdir)/'`defsincdate"; \
+ ./mkdefsinc -C $(srcdir) --date "`cat $$incd 2>/dev/null`" \
+ $(gnupg_TEXINFOS) >$@
+
online: gnupg.html gnupg.pdf
set -e; \
is thus often helpful. Note that the actual output depends on the
backend and may change from release to release.
-@ifset gpgtwoone
@item Logging on WindowsCE
For development, the best logging method on WindowsCE is the use of
tests it is better to make use of the logging facility provided by the
@command{gpgcedev} driver (part of libassuan); this is enabled by using
a log file name of @file{GPG2:}. (@pxref{option --log-file}).
-@end ifset
@end itemize
@cartouche
@smallexample
- /usr/local/libexec/gpg-protect-tool --p12-export \
+ @value{LIBEXECDIR}/gpg-protect-tool --p12-export \
~/.gnupg/private-keys-v1.d/@var{foo} >@var{foo}.p12
@end smallexample
@end cartouche
@cartouche
@smallexample
- /usr/local/libexec/gpg-protect-tool --p12-import --store @var{foo}.p12
+ @value{LIBEXECDIR}/gpg-protect-tool --p12-import --store @var{foo}.p12
@end smallexample
@end cartouche
@c This is part of the GnuPG manual.
@c For copying conditions, see the file gnupg.texi.
+@include defs.inc
+
@node Invoking DIRMNGR
@chapter Invoking DIRMNGR
@cindex DIRMNGR command options
@table @asis
@item With @code{--daemon} given on the commandline
-the directory named @file{/etc/gnupg} is used for configuration files
-and @file{/var/cache/gnupg} for cached CRLs.
+the directory named @file{@value{SYSCONFDIR}} is used for configuration files
+and @file{@value{LOCALCACHEDIR}} for cached CRLs.
@item Without @code{--daemon} given on the commandline
the directory named @file{.gnupg} directly below the home directory
out to the net to look for them. These certificates must also be
@acronym{DER} encoded and suffixed with @file{.crt} or @file{.der}.
-@item /var/run/gnupg
+@item @value{LOCALRUNDIR}
This directory is only used in the deprecated system daemon mode. It
keeps the socket file for accessing @command{dirmngr} services. The
name of the socket file will be @file{S.dirmngr}. Make sure that this
socket.
@item ~/.gnupg/crls.d
-@itemx /var/cache/gnupg/crls.d
+@itemx @value{LOCALCACHEDIR}/crls.d
The first directory is used to store cached CRLs. The @file{crls.d}
part will be created by dirmngr if it does not exists but you need to
make sure that the upper directory exists. The second directory is
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename gnupg.info
-@include version.texi
+@include defs.inc
@settitle Using the GNU Privacy Guard
@c A couple of macros with no effect on texinfo
* gpg2: (gnupg). OpenPGP encryption and signing tool.
* gpgsm: (gnupg). S/MIME encryption and signing tool.
* gpg-agent: (gnupg). The secret key daemon.
-@ifset gpgtwoone
* dirmngr: (gnupg). X.509 CRL and OCSP server.
* dirmngr-client: (gnupg). X.509 CRL and OCSP client.
-@end ifset
@end direntry
* Installation:: A short installation guide.
* Invoking GPG-AGENT:: How to launch the secret key daemon.
-@ifset gpgtwoone
* Invoking DIRMNGR:: How to launch the CRL and OCSP daemon.
-@end ifset
* Invoking GPG:: Using the OpenPGP protocol.
* Invoking GPGSM:: Using the S/MIME protocol.
* Invoking SCDAEMON:: How to handle Smartcards.
@include instguide.texi
@include gpg-agent.texi
-@ifset gpgtwoone
@include dirmngr.texi
-@end ifset
@include gpg.texi
@include gpgsm.texi
@include scdaemon.texi
@c This is part of the GnuPG manual.
@c For copying conditions, see the file gnupg.texi.
-@c Note that we use this texinfo file for all versions of GnuPG:
-@c 2.0 and 2.1. The macro "gpgtwoone" controls parts which are only
-@c valid for GnuPG 2.1 and later.
-
+@include defs.inc
@node Invoking GPG-AGENT
@chapter Invoking GPG-AGENT
@command{gpg} and @command{gpgsm} as well as for a couple of other
utilities.
-@ifset gpgtwoone
The agent is automatically started on demand by @command{gpg},
@command{gpgsm}, @command{gpgconf}, or @command{gpg-connect-agent}.
Thus there is no reason to start it manually. In case you want to use
@example
gpg-connect-agent /bye
@end example
-@end ifset
-
-@ifclear gpgtwoone
-@noindent
-The usual way to run the agent is from the @code{~/.xsession} file:
-
-@example
-eval $(gpg-agent --daemon)
-@end example
-@noindent
-If you don't use an X server, you can also put this into your regular
-startup file @code{~/.profile} or @code{.bash_profile}. It is best not
-to run multiple instance of the @command{gpg-agent}, so you should make
-sure that only one is running: @command{gpg-agent} uses an environment
-variable to inform clients about the communication parameters. You can
-write the content of this environment variable to a file so that you can
-test for a running agent. Here is an example using Bourne shell syntax:
-
-@smallexample
-gpg-agent --daemon --enable-ssh-support \
- --write-env-file "$@{HOME@}/.gpg-agent-info"
-@end smallexample
-
-This code should only be run once per user session to initially fire up
-the agent. In the example the optional support for the included Secure
-Shell agent is enabled and the information about the agent is written to
-a file in the HOME directory. Note that by running gpg-agent without
-arguments you may test whether an agent is already running; however such
-a test may lead to a race condition, thus it is not suggested.
-
-@noindent
-The second script needs to be run for each interactive session:
-
-@smallexample
-if [ -f "$@{HOME@}/.gpg-agent-info" ]; then
- . "$@{HOME@}/.gpg-agent-info"
- export GPG_AGENT_INFO
- export SSH_AUTH_SOCK
-fi
-@end smallexample
-
-@noindent
-It reads the data out of the file and exports the variables. If you
-don't use Secure Shell, you don't need the last two export statements.
-@end ifclear
@noindent
You should always add the following lines to your @code{.bashrc} or
under the default filename (which is system dependent) or use the
option @option{pinentry-program} to specify the full name of that program.
It is often useful to install a symbolic link from the actual used
-pinentry (e.g. @file{/usr/bin/pinentry-gtk}) to the expected
-one (e.g. @file{/usr/bin/pinentry}).
+pinentry (e.g. @file{@value{BINDIR}/pinentry-gtk}) to the expected
+one (e.g. @file{@value{BINDIR}/pinentry}).
@manpause
@noindent
@opindex daemon
Start the gpg-agent as a daemon; that is, detach it from the console
and run it in the background.
-@ifclear gpgtwoone
-Because @command{gpg-agent} prints out
-important information required for further use, a common way of
-invoking gpg-agent is: @code{eval $(gpg-agent --daemon)} to setup the
-environment variables. The option @option{--write-env-file} is
-another way commonly used to do this.
-@end ifclear
-Yet another way is creating
-a new process as a child of gpg-agent: @code{gpg-agent --daemon
-/bin/sh}. This way you get a new shell with the environment setup
-properly; if you exit from this shell, gpg-agent terminates as well.
+
+As an alternative you may create a new process as a child of
+gpg-agent: @code{gpg-agent --daemon /bin/sh}. This way you get a new
+shell with the environment setup properly; after you exit from this
+shell, gpg-agent terminates within a few seconds.
@end table
@mansect options
the environment variable @code{SHELL} which is correct in almost all
cases.
-@ifclear gpgtwoone
-@item --write-env-file @var{file}
-@opindex write-env-file
-Often it is required to connect to the agent from a process not being an
-inferior of @command{gpg-agent} and thus the environment variable with
-the socket name is not available. To help setting up those variables in
-other sessions, this option may be used to write the information into
-@var{file}. If @var{file} is not specified the default name
-@file{$@{HOME@}/.gpg-agent-info} will be used. The format is suitable
-to be evaluated by a Bourne shell like in this simple example:
-
-@example
-eval $(cat @var{file})
-eval $(cut -d= -f 1 < @var{file} | xargs echo export)
-@end example
-@end ifclear
-
@item --no-grab
@opindex no-grab
This option allows the use of @command{gpg-preset-passphrase} to seed the
internal cache of @command{gpg-agent} with passphrases.
-@ifset gpgtwoone
@anchor{option --allow-loopback-pinentry}
@item --allow-loopback-pinentry
@opindex allow-loopback-pinentry
Allow clients to use the loopback pinentry features; see the option
@option{pinentry-mode} for details.
-@end ifset
-@ifset gpgtwoone
@item --no-allow-external-cache
@opindex no-allow-external-cache
Tell Pinentry not to enable features which use an external cache for
which employs an additional external cache to implement such a policy.
By using this option the Pinentry is advised not to make use of such a
cache and instead always ask the user for the requested passphrase.
-@end ifset
+
+@item --allow-emacs-pinentry
+@opindex allow-emacs-pinentry
+Tell Pinentry to allow features to divert the passphrase entry to a
+running Emacs instance. How this is exactly handled depends on the
+version of the used Pinentry.
@item --ignore-cache-for-signing
@opindex ignore-cache-for-signing
disabling the ability to do smartcard operations. Note, that enabling
this option at runtime does not kill an already forked scdaemon.
-@ifset gpgtwoone
@item --disable-check-own-socket
@opindex disable-check-own-socket
@command{gpg-agent} employs a periodic self-test to detect a stolen
has taken over the socket and @command{gpg-agent} will then terminate
itself. This option may be used to disable this self-test for
debugging purposes.
-@end ifset
@item --use-standard-socket
@itemx --no-use-standard-socket
@opindex use-standard-socket
@opindex no-use-standard-socket
@opindex use-standard-socket-p
-@ifset gpgtwoone
Since GnuPG 2.1 the standard socket is always used. These options
have no more effect. The command @code{gpg-agent
--use-standard-socket-p} will thus always return success.
-@end ifset
-@ifclear gpgtwoone
-By enabling this option @command{gpg-agent} will listen on the socket
-named @file{S.gpg-agent}, located in the home directory, and not create
-a random socket below a temporary directory. Tools connecting to
-@command{gpg-agent} should first try to connect to the socket given in
-environment variable @var{GPG_AGENT_INFO} and then fall back to this
-socket. This option may not be used if the home directory is mounted on
-a remote file system which does not support special files like fifos or
-sockets.
-
-Note, that @option{--use-standard-socket} is the default on
-Windows systems.
-
-The default may be changed at build time. It is
-possible to test at runtime whether the agent has been configured for
-use with the standard socket by issuing the command @command{gpg-agent
---use-standard-socket-p} which returns success if the standard socket
-option has been enabled.
-@end ifclear
@item --display @var{string}
@itemx --ttyname @var{string}
that this file can't be changed inadvertently.
As a special feature a line @code{include-default} will include a global
-list of trusted certificates (e.g. @file{/etc/gnupg/trustlist.txt}).
+list of trusted certificates (e.g. @file{@value{SYSCONFDIR}/trustlist.txt}).
This global list is also used if the local list is not available.
It is possible to add further flags after the @code{S} for use by the
@end table
Note that on larger installations, it is useful to put predefined
-files into the directory @file{/etc/skel/.gnupg/} so that newly created
+files into the directory @file{@value{SYSCONFSKELDIR}} so that newly created
users start up with a working configuration. For existing users the
a small helper script is provided to create these files (@pxref{addgnupghome}).
@code{debug-pinentry},
@code{no-grab}, @code{pinentry-program}, @code{default-cache-ttl},
@code{max-cache-ttl}, @code{ignore-cache-for-signing},
-@code{no-allow-external-cache},
+@code{no-allow-external-cache}, @code{allow-emacs-pinentry},
@code{no-allow-mark-trusted}, @code{disable-scdaemon}, and
@code{disable-check-own-socket}. @code{scdaemon-program} is also
supported but due to the current implementation, which calls the
@node Agent Examples
@section Examples
-@ifset gpgtwoone
It is important to set the GPG_TTY environment variable in
your login shell, for example in the @file{~/.bashrc} init script:
fi
@end example
@end cartouche
-@end ifset
-
-@ifclear gpgtwoone
-The usual way to invoke @command{gpg-agent} is
-@example
-$ eval $(gpg-agent --daemon)
-@end example
-
-An alternative way is by replacing @command{ssh-agent} with
-@command{gpg-agent}. If for example @command{ssh-agent} is started as
-part of the Xsession initialization, you may simply replace
-@command{ssh-agent} by a script like:
-
-@cartouche
-@example
-#!/bin/sh
-
-exec /usr/local/bin/gpg-agent --enable-ssh-support --daemon \
- --write-env-file $@{HOME@}/.gpg-agent-info "$@@"
-@end example
-@end cartouche
-
-@noindent
-and add something like (for Bourne shells)
-
-@cartouche
-@example
- if [ -f "$@{HOME@}/.gpg-agent-info" ]; then
- . "$@{HOME@}/.gpg-agent-info"
- export GPG_AGENT_INFO
- export SSH_AUTH_SOCK
- fi
-@end example
-@end cartouche
-
-@noindent
-to your shell initialization file (e.g. @file{~/.bashrc}).
-@end ifclear
@c
@c 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.
-@ifset gpgtwoone
The @command{gpg-agent} daemon is started on demand by the GnuPG
components.
-@end ifset
-@ifclear gpgtwoone
-The @command{gpg-agent} should be started by the login shell and set an
-environment variable to tell clients about the socket to be used.
-Clients should deny to access an agent with a socket name which does
-not match its own configuration. An application may choose to start
-an instance of the gpg-agent if it does not figure that any has been
-started; it should not do this if a gpg-agent is running but not
-usable. Because @command{gpg-agent} can only be used in background mode, no
-special command line option is required to activate the use of the
-protocol.
-@end ifclear
To identify a key we use a thing called keygrip which is the SHA-1 hash
of an canonical encoded S-Expression of the public key as used in
different protocols, thereby saving space on the token used to keep the
secret keys.
-@ifset gpgtwoone
The @command{gpg-agent} may send status messages during a command or when
returning from a command to inform a client about the progress or result of an
operation. For example, the @var{INQUIRE_MAXLEN} status message may be sent
during a server inquire to inform the client of the maximum usable length of
the inquired data (which should not be exceeded).
-@end ifset
@menu
* Agent PKDECRYPT:: Decrypting a session key
* Agent ISTRUSTED:: Importing a Root Certificate
* Agent GET_PASSPHRASE:: Ask for a passphrase
* Agent CLEAR_PASSPHRASE:: Expire a cached passphrase
-@ifset gpgtwoone
* Agent PRESET_PASSPHRASE:: Set a passphrase for a keygrip
-@end ifset
* Agent GET_CONFIRMATION:: Ask for confirmation
* Agent HAVEKEY:: Check whether a key is available
* Agent LEARN:: Register a smartcard
of the PSE, a special export tool has to be used.
@example
-@ifset gpgtwoone
GENKEY [--no-protection] [--preset] [<cache_nonce>]
-@end ifset
-@ifclear gpgtwoone
- GENKEY
-@end ifclear
@end example
Invokes the key generation process and the server will then inquire
@end smallexample
@end cartouche
-@ifset gpgtwoone
The @option{--no-protection} option may be used to prevent prompting for a
passphrase to protect the secret key while leaving the secret key unprotected.
The @option{--preset} option may be used to add the passphrase to the cache
takes precedence over @option{--no-protection}; however if the client
sends a empty (zero-length) passphrase, this is identical to
@option{--no-protection}.
-@end ifset
@node Agent IMPORT
@subsection Importing a Secret Key
@subsection Ask for a passphrase
This function is usually used to ask for a passphrase to be used for
-conventional encryption, but may also be used by programs which need
+symmetric encryption, but may also be used by programs which need
special handling of passphrases. This command uses a syntax which helps
clients to use the agent with minimum effort.
Use this command to remove a cached passphrase.
@example
-@ifset gpgtwoone
CLEAR_PASSPHRASE [--mode=normal] <cache_id>
-@end ifset
-@ifclear gpgtwoone
- CLEAR_PASSPHRASE <cache_id>
-@end ifclear
@end example
-@ifset gpgtwoone
The @option{--mode=normal} option can be used to clear a @var{cache_id} that
was set by gpg-agent.
-@end ifset
-
-@ifset gpgtwoone
@node Agent PRESET_PASSPHRASE
@subsection Set a passphrase for a keygrip
number of seconds. A value of @code{-1} means infinate while @code{0} means
the default (currently only a timeout of -1 is allowed, which means to never
expire it).
-@end ifset
-
-
@node Agent GET_CONFIRMATION
@subsection Change a Passphrase
@example
-@ifset gpgtwoone
PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] [--preset] @var{keygrip}
-@end ifset
-@ifclear gpgtwoone
- PASSWD @var{keygrip}
-@end ifclear
@end example
This command is used to interactively change the passphrase of the key
-identified by the hex string @var{keygrip}.
-
-@ifset gpgtwoone
-The @option{--preset} option may be used to add the new passphrase to the
-cache using the default cache parameters.
-@end ifset
+identified by the hex string @var{keygrip}. The @option{--preset}
+option may be used to add the new passphrase to the cache using the
+default cache parameters.
@node Agent UPDATESTARTUPTTY
This does not need any value. It is used to enable the
PINENTRY_LAUNCHED inquiry.
-@ifset gpgtwoone
@item pinentry-mode
This option is used to change the operation mode of the pinentry. The
following values are defined:
Use the @xref{option --allow-loopback-pinentry}.
@end table
-@end ifset
-@ifset gpgtwoone
@item cache-ttl-opt-preset
This option sets the cache TTL for new entries created by GENKEY and
PASSWD commands when using the @option{--preset} option. It it is not
used a default value is used.
-@end ifset
-@ifset gpgtwoone
@item s2k-count
Instead of using the standard S2K count (which is computed on the
fly), the given S2K count is used for new keys or when changing the
option is valid for the entire session or until reset to 0. This
option is useful if the key is later used on boxes which are either
much slower or faster than the actual box.
-@end ifset
@end table
@c This is part of the GnuPG manual.
@c For copying conditions, see the file gnupg.texi.
-@c Note that we use this texinfo file for all GnuPG-2 branches.
-@c The macro "gpgtwoone" controls parts which are only
-@c valid for GnuPG 2.1 and later.
+@include defs.inc
@node Invoking GPG
@chapter Invoking GPG
@cindex command options
@cindex options, GPG command
-@c Begin algorithm defaults
-
-@ifclear gpgtwoone
-@set DEFSYMENCALGO CAST5
-@end ifclear
-
-@ifset gpgtwoone
-@set DEFSYMENCALGO AES128
-@end ifset
-
-@c End algorithm defaults
-
-
@macro gpgname
gpg2
@end macro
@itemx -c
@opindex symmetric
Encrypt with a symmetric cipher using a passphrase. The default
-symmetric cipher used is @value{DEFSYMENCALGO}, but may be chosen with the
+symmetric cipher used is @value{GPGSYMENCALGO}, but may be chosen with the
@option{--cipher-algo} option. This option may be combined with
@option{--sign} (for a signed and symmetrically encrypted message),
@option{--encrypt} (for a message that may be decrypted via a secret key
this command to export the key without the primary key to the main
machine.
-@ifset gpgtwoone
GnuPG may ask you to enter the passphrase for the key. This is
required because the internal protection method of the secret key is
different from the one specified by the OpenPGP protocol.
-@end ifset
-@ifclear gpgtwoone
-See the option @option{--simple-sk-checksum} if you want to import an
-exported secret key into ancient OpenPGP implementations.
-@end ifclear
@item --import
@itemx --fast-import
@table @gnupgtabopt
-@ifset gpgtwoone
@item --quick-gen-key @code{user-id}
@opindex quick-gen-key
This is a simple command to generate a standard key with one user id.
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.
-@end ifset
@item --gen-key
@opindex gen-key
Generate a new key pair using teh current default parameters. This is
the standard command to create a new key.
-@ifset gpgtwoone
@item --full-gen-key
@opindex gen-key
Generate a new key pair with dialogs for all options. This is an
extended version of @option{--gen-key}.
-@end ifset
There is also a feature which allows you to create keys in batch
mode. See the the manual section ``Unattended key generation'' on how
to use this.
non-exportable. This is a shortcut version of the subcommand "lsign"
from @option{--edit-key}.
-@ifset gpgtwoone
@item --quick-sign-key @code{fpr} [@code{names}]
@itemx --quick-lsign-key @code{fpr} [@code{names}]
@opindex quick-sign-key
full flexibility of the "sign" subcommand from @option{--edit-key}.
Its intended use is to help unattended key signing by utilizing a list
of verified fingerprints.
-@end ifset
-@ifset gpgtwoone
@item --quick-adduid @var{user-id} @var{new-user-id}
@opindex quick-adduid
This command adds a new user id to an existing key. In contrast to
@var{new-user-id} is added verbatim with only leading and trailing
white space removed, it is expected to be UTF-8 encoded, and no checks
on its form are applied.
-@end ifset
@item --passwd @var{user_id}
@opindex passwd
@item --secret-keyring @code{file}
@opindex secret-keyring
-@ifset gpgtwoone
This is an obsolete option and ignored. All secret keys are stored in
the @file{private-keys-v1.d} directory below the GnuPG home directory.
-@end ifset
-@ifclear gpgtwoone
-Same as @option{--keyring} but for the secret keyrings.
-@end ifclear
@item --primary-keyring @code{file}
@opindex primary-keyring
this option is not used with HKP keyservers, as they do not support
retrieving keys by subkey id.
-@ifclear gpgtwoone
- @item use-temp-files
- On most Unix-like platforms, GnuPG communicates with the keyserver
- helper program via pipes, which is the most efficient method. This
- option forces GnuPG to use temporary files to communicate. On some
- platforms (such as Win32 and RISC OS), this option is always enabled.
-@end ifclear
-
-@ifclear gpgtwoone
- @item keep-temp-files
- If using `use-temp-files', do not delete the temp files after using
- them. This option is useful to learn the keyserver communication
- protocol by reading the temporary files.
-@end ifclear
-
@item timeout
Tell the keyserver helper program how long (in seconds) to try and
perform a keyserver action before giving up. Note that performing
@item http-proxy=@code{value}
Set the proxy to use for HTTP and HKP keyservers.
-@ifset gpgtwoone
-This overrides any proxy defined in @file{dirmngr.conf}.
-@end ifset
-@ifclear gpgtwoone
-This overrides the "http_proxy" environment variable, if any.
-@end ifclear
-
-@ifclear gpgtwoone
- @item max-cert-size
- When retrieving a key via DNS CERT, only accept keys up to this size.
- Defaults to 16384 bytes.
-@end ifclear
+ This overrides any proxy defined in @file{dirmngr.conf}.
@item verbose
-@ifset gpgtwoone
-This option has no more function since GnuPG 2.1. Use the
-@code{dirmngr} configuration options instead.
-@end ifset
-@ifclear gpgtwoone
-Tell the keyserver helper program to be more verbose. This option can
-be repeated multiple times to increase the verbosity level.
-@end ifclear
+ This option has no more function since GnuPG 2.1. Use the
+ @code{dirmngr} configuration options instead.
@item debug
-@ifset gpgtwoone
-This option has no more function since GnuPG 2.1. Use the
-@code{dirmngr} configuration options instead.
-@end ifset
-@ifclear gpgtwoone
-Turn on debug output in the keyserver helper program. Note that the
-details of debug output depends on which keyserver helper program is
-being used, and in turn, on any libraries that the keyserver helper
-program uses internally (libcurl, openldap, etc).
-@end ifclear
+ This option has no more function since GnuPG 2.1. Use the
+ @code{dirmngr} configuration options instead.
@item check-cert
-@ifset gpgtwoone
-This option has no more function since GnuPG 2.1. Use the
-@code{dirmngr} configuration options instead.
-@end ifset
-@ifclear gpgtwoone
-Enable certificate checking if the keyserver presents one (for hkps or
-ldaps). Defaults to on.
-@end ifclear
+ This option has no more function since GnuPG 2.1. Use the
+ @code{dirmngr} configuration options instead.
@item ca-cert-file
-@ifset gpgtwoone
-This option has no more function since GnuPG 2.1. Use the
-@code{dirmngr} configuration options instead.
-@end ifset
-@ifclear gpgtwoone
- Provide a certificate store to override the system default. Only
- necessary if check-cert is enabled, and the keyserver is using a
- certificate that is not present in a system default certificate list.
-
- Note that depending on the SSL library that the keyserver helper is
- built with, this may actually be a directory or a file.
-@end ifclear
+ This option has no more function since GnuPG 2.1. Use the
+ @code{dirmngr} configuration options instead.
@end table
@opindex max-cert-depth
Maximum depth of a certification chain (default is 5).
-@ifclear gpgtwoone
-@item --simple-sk-checksum
-@opindex simple-sk-checksum
-Secret keys are integrity protected by using a SHA-1 checksum. This
-method is part of the upcoming enhanced OpenPGP specification but
-GnuPG already uses it as a countermeasure against certain attacks.
-Old applications don't understand this new format, so this option may
-be used to switch back to the old behaviour. Using this option bears
-a security risk. Note that using this option only takes effect when
-the secret key is encrypted - the simplest way to make this happen is
-to change the passphrase on the key (even changing it to the same
-value is acceptable).
-@end ifclear
-
@item --no-sig-cache
@opindex no-sig-cache
Do not cache the verification status of key signatures.
option @option{--list-dirs}. Note that the pipe symbol (@code{|}) is
used for a regression test suite hack and may thus not be used in the
file name.
-@ifclear gpgtwoone
-This is only used
-as a fallback when the environment variable @code{GPG_AGENT_INFO} is not
-set or a running agent cannot be connected.
-@end ifclear
-@ifset gpgtwoone
@item --dirmngr-program @var{file}
@opindex dirmngr-program
Specify a dirmngr program to be used for keyserver access. The
-default value is @file{/usr/sbin/dirmngr}. This is only used as a
+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.
-@end ifset
@item --no-autostart
@opindex no-autostart
Use @var{name} as the key to sign with. Note that this option overrides
@option{--default-key}.
-@ifset gpgtwoone
@item --try-secret-key @var{name}
@opindex try-secret-key
For hidden recipients GPG needs to know the keys to use for trial
pinentry for a lot keys to do the trial decryption. If you want to stop
all further trial decryption you may use close-window button instead of
the cancel button.
-@end ifset
@item --try-all-secrets
@opindex try-all-secrets
@c Since GnuPG 2.1 gpg-agent manages the secret key and thus the
@c export-reset-subkey-passwd hack is not anymore justified. Such use
- @c cases need to be implemented using a specialized secret key export
+ @c cases may be implemented using a specialized secret key export
@c tool.
-@ifclear gpgtwoone
- @item export-reset-subkey-passwd
- When using the @option{--export-secret-subkeys} command, this option resets
- the passphrases for all exported subkeys to empty. This is useful
- when the exported subkey is to be used on an unattended machine where
- a passphrase doesn't necessarily make sense. Defaults to no.
-@end ifclear
+ @c @item export-reset-subkey-passwd
+ @c When using the @option{--export-secret-subkeys} command, this option resets
+ @c the passphrases for all exported subkeys to empty. This is useful
+ @c when the exported subkey is to be used on an unattended machine where
+ @c a passphrase doesn't necessarily make sense. Defaults to no.
@item export-clean
Compact (remove all signatures from) user IDs on the key being
Since GnuPG 2.0.10, this mode is always used and thus this option is
obsolete; it does not harm to use it though.
-@ifset gpgtwoone
@item --legacy-list-mode
@opindex legacy-list-mode
Revert to the pre-2.1 public key list mode. This only affects the
human readable output and not the machine interface
(i.e. @code{--with-colons}). Note that the legacy format does not
allow to convey suitable information for elliptic curves.
-@end ifset
@item --with-fingerprint
@opindex with-fingerprint
Same as the command @option{--fingerprint} but changes only the format
of the output and may be used together with another command.
-@ifset gpgtwoone
-
@item --with-icao-spelling
@opindex with-icao-spelling
Print the ICAO spelling of the fingerprint in addition to the hex digits.
Include info about the presence of a secret key in public key listings
done with @code{--with-colons}.
-@end ifset
-
@end table
@c *******************************************
Mac to Windows, etc). @option{--no-textmode} disables this option, and
is the default.
-@ifclear gpgtwoone
-@item --force-v3-sigs
-@itemx --no-force-v3-sigs
-@opindex force-v3-sigs
-OpenPGP states that an implementation should generate v4 signatures
-but PGP versions 5 through 7 only recognize v4 signatures on key
-material. This option forces v3 signatures for signatures on data.
-Note that this option implies @option{--no-ask-sig-expire}, and unsets
-@option{--sig-policy-url}, @option{--sig-notation}, and
-@option{--sig-keyserver-url}, as these features cannot be used with v3
-signatures. @option{--no-force-v3-sigs} disables this option.
-Defaults to no.
-
-@item --force-v4-certs
-@itemx --no-force-v4-certs
-@opindex force-v4-certs
-Always use v4 key signatures even on v3 keys. This option also
-changes the default hash algorithm for v3 RSA keys from MD5 to SHA-1.
-@option{--no-force-v4-certs} disables this option.
-@end ifclear
-
-@ifset gpgtwoone
@item --force-v3-sigs
@itemx --no-force-v3-sigs
@item --force-v4-certs
@itemx --no-force-v4-certs
These options are obsolete and have no effect since GnuPG 2.1.
-@end ifset
@item --force-mdc
@opindex force-mdc
@item --s2k-cipher-algo @code{name}
@opindex s2k-cipher-algo
Use @code{name} as the cipher algorithm used to protect secret keys.
-The default cipher is @value{DEFSYMENCALGO}. This cipher is also used for
-conventional encryption if @option{--personal-cipher-preferences} and
-@option{--cipher-algo} is not given.
+The default cipher is @value{GPGSYMENCALGO}. This cipher is also used
+for symmetric encryption with a passphrase if
+@option{--personal-cipher-preferences} and @option{--cipher-algo} is
+not given.
@item --s2k-digest-algo @code{name}
@opindex s2k-digest-algo
passphrase (which is not recommended) will be used, a 1 adds a salt to
the passphrase and a 3 (the default) iterates the whole process a
number of times (see --s2k-count). Unless @option{--rfc1991} is used,
-this mode is also used for conventional encryption.
+this mode is also used for symmetric encryption with a passphrase.
@item --s2k-count @code{n}
@opindex s2k-count
--throw-keyids, and making signatures with signing subkeys as PGP 6
does not understand signatures made by signing subkeys.
-@ifclear gpgtwoone
-This option implies @option{--disable-mdc --escape-from-lines --force-v3-sigs}.
-@end ifclear
-@ifset gpgtwoone
This option implies @option{--disable-mdc --escape-from-lines}.
-@end ifset
@item --pgp7
@opindex pgp7
Note that this passphrase is only used if the option @option{--batch}
has also been given. This is different from GnuPG version 1.x.
-@ifset gpgtwoone
@item --pinentry-mode @code{mode}
@opindex pinentry-mode
Set the pinentry mode to @code{mode}. Allowed values for @code{mode}
Redirect Pinentry queries to the caller. Note that in contrast to
Pinentry the user is not prompted again if he enters a bad password.
@end table
-@end ifset
@item --command-fd @code{n}
@opindex command-fd
@c man:.RE
Note that on larger installations, it is useful to put predefined files
-into the directory @file{/etc/skel/.gnupg/} so that newly created users
-start up with a working configuration.
+into the directory @file{@value{SYSCONFSKELDIR}} so that
+newly created users start up with a working configuration.
For existing users a small
helper script is provided to create these files (@pxref{addgnupghome}).
@item ~/.gnupg/pubring.gpg.lock
The lock file for the public keyring.
-@ifset gpgtwoone
@item ~/.gnupg/pubring.kbx
The public keyring using a different format. This file is sharred
with @command{gpgsm}. You should backup this file.
@item ~/.gnupg/pubring.kbx.lock
The lock file for @file{pubring.kbx}.
-@end ifset
@item ~/.gnupg/secring.gpg
-@ifclear gpgtwoone
- The secret keyring. You should backup this file.
-@end ifclear
-@ifset gpgtwoone
A secret keyring as used by GnuPG versions before 2.1. It is not
used by GnuPG 2.1 and later.
@item ~/.gnupg/.gpg-v21-migrated
- File indicating that a migration to GnuPG 2.1 has taken place.
-@end ifset
+ File indicating that a migration to GnuPG 2.1 has been done.
@item ~/.gnupg/trustdb.gpg
The trust database. There is no need to backup this file; it is better
You should backup all files in this directory and take care to keep
this backup closed away.
- @item /usr[/local]/share/gnupg/options.skel
+ @item @value{DATADIR}/options.skel
The skeleton options file.
- @item /usr[/local]/lib/gnupg/
+ @item @value{LIBDIR}/
Default location for extensions.
@end table
If set directory used instead of "~/.gnupg".
@item GPG_AGENT_INFO
-@ifset gpgtwoone
This variable was used by GnuPG versions before 2.1
-@end ifset
-@ifclear gpgtwoone
- Used to locate the gpg-agent.
-
- The value consists of 3 colon delimited fields: The first is the path
- to the Unix Domain Socket, the second the PID of the gpg-agent and the
- protocol version which should be set to 1. When starting the gpg-agent
- as described in its documentation, this variable is set to the correct
- value. The option @option{--gpg-agent-info} can be used to override it.
-@end ifclear
@item PINENTRY_USER_DATA
This value is passed via gpg-agent to pinentry. It is useful to convey
@item %ask-passphrase
@itemx %no-ask-passphrase
-@ifclear gpgtwoone
-Enable (or disable) a mode where the command @option{passphrase} is
-ignored and instead the usual passphrase dialog is used. This does
-not make sense for batch key generation; however the unattended key
-generation feature is also used by GUIs and this feature relinquishes
-the GUI from implementing its own passphrase entry code. These are
-global control statements and affect all future key generations.
-@end ifclear
-@ifset gpgtwoone
This option is a no-op for GnuPG 2.1 and later.
-@end ifset
@item %no-protection
Using this option allows the creation of keys without any passphrase
@c This is part of the GnuPG manual.
@c For copying conditions, see the file gnupg.texi.
+@include defs.inc
+
@node Invoking GPGSM
@chapter Invoking GPGSM
@cindex GPGSM command options
@table @gnupgtabopt
@item --gen-key
@opindex gen-key
-@ifclear gpgtwoone
--This command allows the creation of a certificate signing request. It
--is commonly used along with the @option{--output} option to save the
--created CSR into a file. If used with the @option{--batch} a parameter
--file is used to create the CSR.
-@end ifclear
-@ifset gpgtwoone
This command allows the creation of a certificate signing request or a
self-signed certificate. It is commonly used along with the
@option{--output} option to save the created CSR or certificate into a
file. If used with the @option{--batch} a parameter file is used to
create the CSR or certificate and it is further possible to create
non-self-signed certificates.
-@end ifset
@item --list-keys
@itemx -k
format is not very secure and this command is only provided if there is
no other way to exchange the private key. (@pxref{option --p12-charset})
-@ifset gpgtwoone
@item --export-secret-key-p8 @var{key-id}
@itemx --export-secret-key-raw @var{key-id}
@opindex export-secret-key-p8
When used with the @code{--armor} option a few informational lines are
prepended to the output. These commands are useful to prepare a key
for use on a TLS server.
-@end ifset
@item --import [@var{files}]
@opindex import
default value is determined by running the command @command{gpgconf}.
Note that the pipe symbol (@code{|}) is used for a regression test
suite hack and may thus not be used in the file name.
-@ifclear gpgtwoone
-This is only used
-as a fallback when the environment variable @code{GPG_AGENT_INFO} is not
-set or a running agent cannot be connected.
-@end ifclear
@item --dirmngr-program @var{file}
@opindex dirmngr-program
Specify a dirmngr program to be used for @acronym{CRL} checks. The
-default value is @file{/usr/sbin/dirmngr}. This is only used as a
+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.
Include the keygrip in standard key listings. Note that the keygrip is
always listed in --with-colons mode.
-@ifset gpgtwoone
@item --with-secret
@opindex with-secret
Include info about the presence of a secret key in public key listings
done with @code{--with-colons}.
-@end ifset
@end table
in this file need to be listed also in @file{trustlist.txt}.
This is a global file an installed in the data directory
-(e.g. @file{/usr/share/gnupg/qualified.txt}). GnuPG installs a suitable
+(e.g. @file{@value{DATADIR}/qualified.txt}). GnuPG installs a suitable
file with root certificates as used in Germany. As new Root-CA
certificates may be issued over time, these entries may need to be
updated; new distributions of this software should come with an updated
@command{gpg} and @command{gpgsm}. The standard file has English help
texts; to install localized versions use filenames like @file{help.LL.txt}
with LL denoting the locale. GnuPG comes with a set of predefined help
-files in the data directory (e.g. @file{/usr/share/gnupg/help.de.txt})
+files in the data directory (e.g. @file{@value{DATADIR}/gnupg/help.de.txt})
and allows overriding of any help item by help files stored in the
-system configuration directory (e.g. @file{/etc/gnupg/help.de.txt}).
+system configuration directory (e.g. @file{@value{SYSCONFDIR}/help.de.txt}).
For a reference of the help file's syntax, please see the installed
@file{help.txt} file.
newly created @file{pubring.kbx}. An administrator may replace this
file with a custom one. The format is a concatenation of PEM encoded
X.509 certificates. This global file is installed in the data directory
-(e.g. @file{/usr/share/gnupg/com-certs.pem}).
+(e.g. @file{@value{DATADIR}/com-certs.pem}).
@end table
@item S.gpg-agent
@cindex S.gpg-agent
If this file exists
-@ifclear gpgtwoone
-and the environment variable @env{GPG_AGENT_INFO} is
-not set,
-@end ifclear
@command{gpgsm} will first try to connect to this socket for
accessing @command{gpg-agent} before starting a new @command{gpg-agent}
instance. Under Windows this socket (which in reality be a plain file
@node CSR and certificate creation
@subsection CSR and certificate creation
-@ifclear gpgtwoone
-@strong{Please notice}: The immediate creation of certificates is only
-supported by GnuPG version 2.1 or later. With a 2.0 version you may
-only create a CSR.
-@end ifclear
-
The command @option{--gen-key} may be used along with the option
@option{--batch} to either create a certificate signing request (CSR)
or an X.509 certificate. This is controlled by a parameter file; the
@c This is included by tools.texi.
@c
+@include defs.inc
+
@c Begin GnuPG 1.x specific stuff
@ifset gpgone
@macro gpgvname
@end example
This is to make sure that system wide configuration files are searched
-in the directory @file{/etc/gnupg} and variable data below @file{/var};
+in the directory @file{/etc} and variable data below @file{/var};
the default would be to also install them below @file{/usr/local} where
the binaries get installed. If you selected to use the
@option{--prefix=/} you obviously don't need those option as they are
--- /dev/null
+/* mkdefsinc.c - Tool to create defs.inc
+ * Copyright (C) 2015 g10 Code GmbH
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* This tool needs to be build with command line supplied -D options
+ for the various directory variables. See ../am/cmacros.am. It is
+ easier to do this in build file than to use fragile make rules and
+ a template file. */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define PGM "mkdefsinc"
+
+/* We include config.h after all include files because the config.h
+ values are not valid for the build platform but we need some values
+ nevertheless. */
+#include "config.h"
+/* When building for Windows some -D macros are not available. We
+ provide replacements here. */
+#ifdef HAVE_W32_SYSTEM
+# define GNUPG_BINDIR "INSTDIR/bin"
+# define GNUPG_LIBEXECDIR "INSTDIR/bin"
+# define GNUPG_LIBDIR "INSTDIR/lib/" PACKAGE_NAME
+# define GNUPG_DATADIR "INSTDIR/share/" PACKAGE_NAME
+# define GNUPG_SYSCONFDIR "APPDATA/GNU/etc/" PACKAGE_NAME
+# define GNUPG_LOCALSTATEDIR "APPDATA/GNU"
+#endif /*HAVE_W32_SYSTEM*/
+
+
+static int verbose;
+
+
+/* The usual free wrapper. */
+static void
+xfree (void *a)
+{
+ if (a)
+ free (a);
+}
+
+
+static char *
+xmalloc (size_t n)
+{
+ char *p;
+
+ p = malloc (n);
+ if (!p)
+ {
+ fputs (PGM ": out of core\n", stderr);
+ exit (1);
+ }
+ return p;
+}
+
+
+static char *
+xstrdup (const char *string)
+{
+ char *p;
+
+ p = xmalloc (strlen (string)+1);
+ strcpy (p, string);
+ return p;
+}
+
+
+/* Return a malloced string with the last modification date of the
+ FILES. Returns NULL on error. */
+static char *
+get_date_from_files (char **files)
+{
+ const char *file;
+ const char *usedfile = NULL;
+ struct stat sb;
+ struct tm *tp;
+ int errors = 0;
+ time_t stamp = 0;
+ char *result;
+
+ for (; (file = *files); files++)
+ {
+ if (!*file || !strcmp (file, ".") || !strcmp (file, ".."))
+ continue;
+ if (stat (file, &sb))
+ {
+ fprintf (stderr, PGM ": stat failed for '%s': %s\n",
+ file, strerror (errno));
+ errors = 1;
+ continue;
+ }
+ if (sb.st_mtime > stamp)
+ {
+ stamp = sb.st_mtime;
+ usedfile = file;
+ }
+ }
+ if (errors)
+ exit (1);
+
+ if (usedfile)
+ fprintf (stderr, PGM ": taking date from '%s'\n", usedfile);
+
+ tp = gmtime (&stamp);
+ if (!tp)
+ return NULL;
+ result = xmalloc (4+1+2+1+2+1);
+ snprintf (result, 4+1+2+1+2+1, "%04d-%02d-%02d",
+ tp->tm_year + 1900, tp->tm_mon+1, tp->tm_mday);
+ return result;
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ char *opt_date = NULL;
+ int monthoff;
+ char *p, *pend;
+ size_t n;
+
+ /* Option parsing. */
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("Usage: " PGM " [OPTION] [FILES]\n"
+ "Create defs.inc file.\nOptions:\n"
+ " -C DIR Change to DIR before doing anything\n"
+ " --date STRING Take publication date from STRING\n"
+ " --verbose Enable extra informational output\n"
+ " --help Display this help and exit\n"
+ , stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "-C"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ if (chdir (*argv))
+ {
+ fprintf (stderr, PGM ": chdir to '%s' failed: %s\n",
+ *argv, strerror (errno));
+ exit (1);
+ }
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--date"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ opt_date = xstrdup (*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strncmp (*argv, "--", 2))
+ {
+ fprintf (stderr, PGM ": unknown option '%s'\n", *argv);
+ exit (1);
+ }
+ }
+
+ if (opt_date && *opt_date)
+ {
+ time_t stamp;
+ struct tm *tp;
+
+ if (*opt_date == '2' && strlen (opt_date) >= 10
+ && opt_date[4] == '-' && opt_date[7] == '-')
+ {
+ opt_date[10] = 0;
+ }
+ else if ((stamp = strtoul (opt_date, NULL, 10)) > 0
+ && (tp = gmtime (&stamp)))
+ {
+ p = xmalloc (4+1+2+1+2+1);
+ snprintf (p, 4+1+2+1+2+1, "%04d-%02d-%02d",
+ tp->tm_year + 1900, tp->tm_mon+1, tp->tm_mday);
+ xfree (opt_date);
+ opt_date = p;
+ }
+ else
+ {
+ fprintf (stderr, PGM ": bad date '%s'\n", opt_date);
+ exit (1);
+ }
+ }
+ else
+ {
+ xfree (opt_date);
+ opt_date = argc? get_date_from_files (argv) : NULL;
+ }
+ if (!opt_date)
+ {
+ opt_date = xstrdup ("unknown");
+ monthoff = 0;
+ }
+ else
+ {
+ const char *month = "?";
+
+ switch (atoi (opt_date+5))
+ {
+ case 1: month = "January"; break;
+ case 2: month = "February"; break;
+ case 3: month = "March"; break;
+ case 4: month = "April"; break;
+ case 5: month = "May"; break;
+ case 6: month = "June"; break;
+ case 7: month = "July"; break;
+ case 8: month = "August"; break;
+ case 9: month = "September"; break;
+ case 10: month = "October"; break;
+ case 11: month = "November"; break;
+ case 12: month = "December"; break;
+ }
+ n = strlen (opt_date) + strlen (month) + 2 + 1;
+ p = xmalloc (n);
+ snprintf (p, n, "%d %n%s %d",
+ atoi (opt_date+8), &monthoff, month, atoi (opt_date));
+ xfree (opt_date);
+ opt_date = p;
+ }
+
+
+ fputs ("@c defs.inc -*- texinfo -*-\n"
+ "@c Common and build specific constants for the manuals.\n"
+ "@c This file has been created by " PGM ".\n", stdout);
+
+ fputs ("\n@c Directories\n\n", stdout);
+
+ fputs ("@set BINDIR " GNUPG_BINDIR "\n"
+ "@set LIBEXECDIR " GNUPG_LIBEXECDIR "\n"
+ "@set LIBDIR " GNUPG_LIBDIR "\n"
+ "@set DATADIR " GNUPG_DATADIR "\n"
+ "@set SYSCONFDIR " GNUPG_SYSCONFDIR "\n"
+ "@set LOCALSTATEDIR " GNUPG_LOCALSTATEDIR "\n"
+ "@set LOCALCACHEDIR " GNUPG_LOCALSTATEDIR
+ /* */ "/cache/" PACKAGE_NAME "\n"
+ "@set LOCALRUNDIR " GNUPG_LOCALSTATEDIR
+ /* */ "/run/" PACKAGE_NAME "\n"
+ , stdout);
+
+ p = xstrdup (GNUPG_SYSCONFDIR);
+ pend = strrchr (p, '/');
+ fputs ("@set SYSCONFSKELDIR ", stdout);
+ if (pend)
+ {
+ *pend = 0;
+ fputs (p, stdout);
+ }
+ fputs ("/skel/." PACKAGE_NAME "\n", stdout);
+ xfree (p);
+
+ fputs ("\n@c Version information a la version.texi\n\n", stdout);
+
+ printf ("@set UPDATED %s\n", opt_date);
+ printf ("@set UPDATED-MONTH %s\n", opt_date + monthoff);
+ printf ("@set EDITION %s\n", PACKAGE_VERSION);
+ printf ("@set VERSION %s\n", PACKAGE_VERSION);
+
+ fputs ("\n@c Algorithm defaults\n\n", stdout);
+
+ /* Fixme: Use a config.h macro here: */
+ fputs ("@set GPGSYMENCALGO AES-128\n", stdout);
+
+
+ fputs ("\n"
+ "@c Loc" "al Variables:\n"
+ "@c buffer-read-only: t\n"
+ "@c End:\n", stdout);
+
+ if (ferror (stdout))
+ {
+ fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno));
+ return 1;
+ }
+
+ return 0;
+}
directory; or, if @file{gpgconf.exe} has been installed directly below
a directory named @file{bin}, its parent directory. You also need to
make sure that the following directories exist and are writable:
-@file{ROOT/home} for the GnuPG home and @file{ROOT/var/cache/gnupg}
+@file{ROOT/home} for the GnuPG home and @file{ROOT@value{LOCALCACHEDIR}}
for internal cache files.
@c This is part of the GnuPG manual.
@c For copying conditions, see the file gnupg.texi.
+@include defs.inc
+
@node Invoking SCDAEMON
@chapter Invoking the SCDAEMON
@cindex SCDAEMON command options
regular user accounts are hosted on the machine.
A client connects to the SC-Daemon by connecting to the socket named
-@file{/var/run/scdaemon/socket}, configuration information is read from
-@var{/etc/scdaemon.conf}
+@file{@value{LOCALRUNDIR}/scdaemon/socket}, configuration information
+is read from @var{@value{SYSCONFDIR}/scdaemon.conf}
Each connection acts as one session, SC-Daemon takes care of
synchronizing access to a token between sessions.
@c This is part of the GnuPG manual.
@c For copying conditions, see the file GnuPG.texi.
+@include defs.inc
+
@node Helper Tools
@chapter Helper Tools
* gpgsm-gencert.sh:: Generate an X.509 certificate request.
* gpg-preset-passphrase:: Put a passphrase into the cache.
* gpg-connect-agent:: Communicate with a running agent.
-@ifset gpgtwoone
* dirmngr-client:: How to use the Dirmngr client tool.
-@end ifset
* gpgparsemail:: Parse a mail message into an annotated format
* symcryptrun:: Call a simple symmetric encryption tool.
* gpg-zip:: Encrypt or sign files into an archive.
a SIGHUP to the component. Components which don't support reloading are
ignored.
-@ifset gpgtwoone
@item --launch [@var{component}]
@opindex launch
If the @var{component} is not already running, start it.
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.
-@end ifset
@end table
used for a regression test suite hack and may thus not be used in the
file name.
-@ifset gpgtwoone
@item --dirmngr-program @var{file}
@opindex dirmngr-program
Specify the directory manager (keyserver client) program to be started
@opindex dirmngr
Connect to a running directory manager (keyserver client) instead of
to the gpg-agent. If a dirmngr is not running, start it.
-@end ifset
@item -S
@itemx --raw-socket @var{name}
@include see-also-note.texi
@end ifset
-@ifset gpgtwoone
@c
@c DIRMNGR-CLIENT
@c
@command{gpgsm}(1)
@include see-also-note.texi
@end ifset
-@end ifset
+
@c
@c GPGPARSEMAIL
}
if (!incfp)
- err ("can't open include file '%s':%s",
+ err ("can't open include file '%s': %s",
incname, strerror (errno));
else
{
include $(top_srcdir)/am/cmacros.am
-AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
+# We need KSBA_CFLAGS because that is included by keybox.h. See also
+# comments below for libksba.
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) \
+ $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
needed_libs = ../kbx/libkeybox.a $(libcommon)
#ifndef NO_TRUST_MODELS
case aListTrustDB:
if( !argc )
- list_trustdb(NULL);
+ list_trustdb (es_stdout, NULL);
else {
for( ; argc; argc--, argv++ )
- list_trustdb( *argv );
+ list_trustdb (es_stdout, *argv );
}
break;
int textmode );
PKT_plaintext *setup_plaintext_name(const char *filename,IOBUF iobuf);
-/*-- signal.c --*/
-void init_signals(void);
-void block_all_signals(void);
-void unblock_all_signals(void);
-
/*-- server.c --*/
int gpg_server (ctrl_t);
gpg_error_t gpg_proxy_pinentry_notify (ctrl_t ctrl,
c->dek = NULL;
}
}
- else if (is_ELGAMAL(enc->pubkey_algo)
- || enc->pubkey_algo == PUBKEY_ALGO_DSA
- || enc->pubkey_algo == PUBKEY_ALGO_ECDSA
- || enc->pubkey_algo == PUBKEY_ALGO_EDDSA
+ else if (enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E
|| enc->pubkey_algo == PUBKEY_ALGO_ECDH
- || is_RSA (enc->pubkey_algo)
+ || enc->pubkey_algo == PUBKEY_ALGO_RSA
+ || enc->pubkey_algo == PUBKEY_ALGO_RSA_E
|| enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL)
{
/* Note that we also allow type 20 Elgamal keys for decryption.
+++ /dev/null
-/* signal.c - signal handling
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- * 2005 Free Software Foundation, Inc.
- *
- * 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 <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "options.h"
-#include "status.h"
-#include "util.h"
-#include "main.h"
-#include "ttyio.h"
-
-#ifdef HAVE_DOSISH_SYSTEM
-void init_signals(void) {}
-#else
-static volatile int caught_fatal_sig = 0;
-static volatile int caught_sigusr1 = 0;
-
-static void
-init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign )
-{
-#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
- struct sigaction oact, nact;
-
- if (check_ign) {
- /* we don't want to change an IGN handler */
- sigaction (sig, NULL, &oact );
- if (oact.sa_handler == SIG_IGN )
- return;
- }
-
- nact.sa_handler = handler;
- sigemptyset (&nact.sa_mask);
- nact.sa_flags = 0;
- sigaction ( sig, &nact, NULL);
-#else
- RETSIGTYPE (*ohandler)(int);
-
- ohandler = signal (sig, handler);
- if (check_ign && ohandler == SIG_IGN) {
- /* Change it back if it was already set to IGN */
- signal (sig, SIG_IGN);
- }
-#endif
-}
-
-static RETSIGTYPE
-got_fatal_signal( int sig )
-{
- const char *s;
-
- if( caught_fatal_sig )
- raise( sig );
- caught_fatal_sig = 1;
-
- gcry_control (GCRYCTL_TERM_SECMEM );
-
- tty_cleanup_rl_after_signal ();
- tty_cleanup_after_signal ();
-
- /* Better don't translate these messages. */
- write(2, "\n", 1 );
- s = log_get_name(); if( s ) write(2, s, strlen(s) );
- write(2, ": ", 2 );
-
-#if HAVE_DECL_SYS_SIGLIST && defined(NSIG)
- s = (sig >= 0 && sig < NSIG) ? sys_siglist[sig] : "?";
- write (2, s, strlen(s) );
-#else
- write (2, "signal ", 7 );
- if (sig < 0 || sig >=100)
- write (2, "?", 1);
- else {
- if (sig >= 10)
- write (2, "0123456789"+(sig/10), 1 );
- write (2, "0123456789"+(sig%10), 1 );
- }
-#endif
- write(2, " caught ... exiting\n", 20 );
-
- /* Reset action to default action and raise signal again. */
- init_one_signal (sig, SIG_DFL, 0);
- dotlock_remove_lockfiles ();
-#ifdef __riscos__
- riscos_close_fds ();
-#endif /* __riscos__ */
- raise( sig );
-}
-
-
-static RETSIGTYPE
-got_usr_signal( int sig )
-{
- caught_sigusr1 = 1;
-}
-
-
-void
-init_signals()
-{
- init_one_signal (SIGINT, got_fatal_signal, 1 );
- init_one_signal (SIGHUP, got_fatal_signal, 1 );
- init_one_signal (SIGTERM, got_fatal_signal, 1 );
- init_one_signal (SIGQUIT, got_fatal_signal, 1 );
- init_one_signal (SIGSEGV, got_fatal_signal, 1 );
- init_one_signal (SIGUSR1, got_usr_signal, 0 );
- init_one_signal (SIGPIPE, SIG_IGN, 0 );
-}
-
-
-/* Disabled - see comment in tdbio.c:tdbio_begin_transaction() */
-#if 0
-static void
-do_block( int block )
-{
- static int is_blocked;
-#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
- static sigset_t oldmask;
-
- if( block ) {
- sigset_t newmask;
-
- if( is_blocked )
- log_bug("signals are already blocked\n");
- sigfillset( &newmask );
- sigprocmask( SIG_BLOCK, &newmask, &oldmask );
- is_blocked = 1;
- }
- else {
- if( !is_blocked )
- log_bug("signals are not blocked\n");
- sigprocmask( SIG_SETMASK, &oldmask, NULL );
- is_blocked = 0;
- }
-#else /*! HAVE_SIGPROCMASK && HAVE_SIGSET_T */
-
-#if defined(NSIG)
-#define SIGSMAX (NSIG)
-#elif defined(MAXSIG)
-#define SIGSMAX (MAXSIG+1)
-#else
-#error "define SIGSMAX to the number of signals on your platform plus one"
-#endif
-
- static void (*disposition[SIGSMAX])(int);
- int sig;
-
- if( block ) {
- if( is_blocked )
- log_bug("signals are already blocked\n");
- for (sig=1; sig < SIGSMAX; sig++) {
- disposition[sig] = sigset (sig, SIG_HOLD);
- }
- is_blocked = 1;
- }
- else {
- if( !is_blocked )
- log_bug("signals are not blocked\n");
- for (sig=1; sig < SIGSMAX; sig++) {
- sigset (sig, disposition[sig]);
- }
- is_blocked = 0;
- }
-#endif /*! HAVE_SIGPROCMASK && HAVE_SIGSET_T */
-}
-
-void
-block_all_signals()
-{
- do_block(1);
-}
-
-void
-unblock_all_signals()
-{
- do_block(0);
-}
-#endif
-
-#endif /* !HAVE_DOSISH_SYSTEM */
(x) >= 'A' && (x) <= 'F' ? ((x)-'A'+10) : ((x)-'a'+10))
-/****************
- * Wirte a record but die on error
+/*
+ * Write a record; die on error.
*/
static void
write_record( TRUSTREC *rec )
}
-/****************
- * Dump the entire trustdb or only the entries of one key.
+/*
+ * Dump the entire trustdb to FP or only the entries of one key.
*/
void
-list_trustdb( const char *username )
+list_trustdb (estream_t fp, const char *username)
{
TRUSTREC rec;
ulong recnum;
int i;
- es_printf ("TrustDB: %s\n", tdbio_get_dbname() );
- for(i=9+strlen(tdbio_get_dbname()); i > 0; i-- )
- es_putc ('-', es_stdout);
- es_putc ('\n', es_stdout);
- for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ )
- tdbio_dump_record (&rec, es_stdout);
+ es_fprintf (fp, "TrustDB: %s\n", tdbio_get_dbname ());
+ for (i = 9 + strlen (tdbio_get_dbname()); i > 0; i-- )
+ es_fputc ('-', fp);
+ es_putc ('\n', fp);
+ for (recnum=0; !tdbio_read_record (recnum, &rec, 0); recnum++)
+ tdbio_dump_record (&rec, fp);
}
}
any = 1;
}
}
- else if( rc == -1 ) { /* not found: insert */
+ else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) { /* insert */
log_info("inserting ownertrust of %u\n", otrust );
memset (&rec, 0, sizeof rec);
rec.recnum = tdbio_new_recnum ();
/* tdbio.c - trust database I/O operations
* Copyright (C) 1998-2002, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 1998-2015 Werner Koch
*
* This file is part of GnuPG.
*
#define strerror(a) ("[errno not available]")
#endif
-/****************
+/*
* Yes, this is a very simple implementation. We should really
* use a page aligned buffer and read complete pages.
* To implement a simple trannsaction system, this is sufficient.
*/
typedef struct cache_ctrl_struct *CACHE_CTRL;
-struct cache_ctrl_struct {
- CACHE_CTRL next;
- struct {
- unsigned used:1;
- unsigned dirty:1;
- } flags;
- ulong recno;
- char data[TRUST_RECORD_LEN];
+struct cache_ctrl_struct
+{
+ CACHE_CTRL next;
+ struct {
+ unsigned used:1;
+ unsigned dirty:1;
+ } flags;
+ ulong recno;
+ char data[TRUST_RECORD_LEN];
};
-#define MAX_CACHE_ENTRIES_SOFT 200 /* may be increased while in a */
-#define MAX_CACHE_ENTRIES_HARD 10000 /* transaction to this one */
+/* Size of the cache. The SOFT value is the general one. While in a
+ transaction this may not be sufficient and thus we may increase it
+ then up to the HARD limit. */
+#define MAX_CACHE_ENTRIES_SOFT 200
+#define MAX_CACHE_ENTRIES_HARD 10000
+
+
+/* The cache is controlled by these variables. */
static CACHE_CTRL cache_list;
static int cache_entries;
static int cache_is_dirty;
-/* a type used to pass infomation to cmp_krec_fpr */
-struct cmp_krec_fpr_struct {
- int pubkey_algo;
- const char *fpr;
- int fprlen;
+
+/* An object to pass infomation to cmp_krec_fpr. */
+struct cmp_krec_fpr_struct
+{
+ int pubkey_algo;
+ const char *fpr;
+ int fprlen;
};
-/* a type used to pass infomation to cmp_[s]dir */
-struct cmp_xdir_struct {
- int pubkey_algo;
- u32 keyid[2];
+/* An object used to pass infomation to cmp_[s]dir. */
+struct cmp_xdir_struct
+{
+ int pubkey_algo;
+ u32 keyid[2];
};
+/* The name of the trustdb file. */
static char *db_name;
+
+/* The handle for locking the trustdb file and a flag to record
+ whether a lock has been taken. */
static dotlock_t lockhandle;
static int is_locked;
+
+/* The file descriptor of the trustdb. */
static int db_fd = -1;
+
+/* A flag indicating that a transaction is active. */
static int in_transaction;
-static void open_db(void);
+
+\f
+static void open_db (void);
\f
+/*
+ * Take a lock on the trustdb file name. I a lock file can't be
+ * created the function terminates the process. Excvept for a
+ * different return code the function does nothing if the lock has
+ * already been taken.
+ *
+ * Returns: True if lock already exists, False if the lock has
+ * actually been taken.
+ */
+static int
+take_write_lock (void)
+{
+ if (!lockhandle)
+ lockhandle = dotlock_create (db_name, 0);
+ if (!lockhandle)
+ log_fatal ( _("can't create lock for '%s'\n"), db_name );
+
+ if (!is_locked)
+ {
+ if (dotlock_take (lockhandle, -1) )
+ log_fatal ( _("can't lock '%s'\n"), db_name );
+ else
+ is_locked = 1;
+ return 0;
+ }
+ else
+ return 1;
+}
+
+
+/*
+ * Release a lock from the trustdb file unless the global option
+ * --lock-once has been used.
+ */
+static void
+release_write_lock (void)
+{
+ if (!opt.lock_once)
+ if (!dotlock_release (lockhandle))
+ is_locked = 0;
+}
+\f
/*************************************
************* record cache **********
*************************************/
-/****************
- * Get the data from therecord cache and return a
- * pointer into that cache. Caller should copy
- * the return data. NULL is returned on a cache miss.
+/*
+ * Get the data from the record cache and return a pointer into that
+ * cache. Caller should copy the returned data. NULL is returned on
+ * a cache miss.
*/
static const char *
-get_record_from_cache( ulong recno )
+get_record_from_cache (ulong recno)
{
- CACHE_CTRL r;
+ CACHE_CTRL r;
- for( r = cache_list; r; r = r->next ) {
- if( r->flags.used && r->recno == recno )
- return r->data;
+ for (r = cache_list; r; r = r->next)
+ {
+ if (r->flags.used && r->recno == recno)
+ return r->data;
}
- return NULL;
+ return NULL;
}
+/*
+ * Write a cached item back to the trustdb file.
+ *
+ * Returns: 0 on success or an error code.
+ */
static int
-write_cache_item( CACHE_CTRL r )
+write_cache_item (CACHE_CTRL r)
{
- gpg_error_t err;
- int n;
-
- if( lseek( db_fd, r->recno * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
- err = gpg_error_from_syserror ();
- log_error(_("trustdb rec %lu: lseek failed: %s\n"),
- r->recno, strerror(errno) );
- return err;
+ gpg_error_t err;
+ int n;
+
+ if (lseek (db_fd, r->recno * TRUST_RECORD_LEN, SEEK_SET) == -1)
+ {
+ err = gpg_error_from_syserror ();
+ log_error (_("trustdb rec %lu: lseek failed: %s\n"),
+ r->recno, strerror (errno));
+ return err;
}
- n = write( db_fd, r->data, TRUST_RECORD_LEN);
- if( n != TRUST_RECORD_LEN ) {
- err = gpg_error_from_syserror ();
- log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
- r->recno, n, strerror(errno) );
- return err;
+ n = write (db_fd, r->data, TRUST_RECORD_LEN);
+ if (n != TRUST_RECORD_LEN)
+ {
+ err = gpg_error_from_syserror ();
+ log_error (_("trustdb rec %lu: write failed (n=%d): %s\n"),
+ r->recno, n, strerror (errno) );
+ return err;
}
- r->flags.dirty = 0;
- return 0;
+ r->flags.dirty = 0;
+ return 0;
}
-/****************
- * Put data into the cache. This function may flush the
- * some cache entries if there is not enough space available.
+
+/*
+ * Put data into the cache. This function may flush
+ * some cache entries if the cache is filled up.
+ *
+ * Returns: 0 on success or an error code.
*/
int
-put_record_into_cache( ulong recno, const char *data )
+put_record_into_cache (ulong recno, const char *data)
{
- CACHE_CTRL r, unused;
- int dirty_count = 0;
- int clean_count = 0;
-
- /* see whether we already cached this one */
- for( unused = NULL, r = cache_list; r; r = r->next ) {
- if( !r->flags.used ) {
- if( !unused )
- unused = r;
+ CACHE_CTRL r, unused;
+ int dirty_count = 0;
+ int clean_count = 0;
+
+ /* See whether we already cached this one. */
+ for (unused = NULL, r = cache_list; r; r = r->next)
+ {
+ if (!r->flags.used)
+ {
+ if (!unused)
+ unused = r;
}
- else if( r->recno == recno ) {
- if( !r->flags.dirty ) {
- /* Hmmm: should we use a a copy and compare? */
- if( memcmp(r->data, data, TRUST_RECORD_LEN ) ) {
- r->flags.dirty = 1;
- cache_is_dirty = 1;
+ else if (r->recno == recno)
+ {
+ if (!r->flags.dirty)
+ {
+ /* Hmmm: should we use a copy and compare? */
+ if (memcmp (r->data, data, TRUST_RECORD_LEN))
+ {
+ r->flags.dirty = 1;
+ cache_is_dirty = 1;
}
}
- memcpy( r->data, data, TRUST_RECORD_LEN );
- return 0;
+ memcpy (r->data, data, TRUST_RECORD_LEN);
+ return 0;
}
- if( r->flags.used ) {
- if( r->flags.dirty )
- dirty_count++;
- else
- clean_count++;
+ if (r->flags.used)
+ {
+ if (r->flags.dirty)
+ dirty_count++;
+ else
+ clean_count++;
}
}
- /* not in the cache: add a new entry */
- if( unused ) { /* reuse this entry */
- r = unused;
- r->flags.used = 1;
- r->recno = recno;
- memcpy( r->data, data, TRUST_RECORD_LEN );
- r->flags.dirty = 1;
- cache_is_dirty = 1;
- cache_entries++;
- return 0;
+
+ /* Not in the cache: add a new entry. */
+ if (unused)
+ {
+ /* Reuse this entry. */
+ r = unused;
+ r->flags.used = 1;
+ r->recno = recno;
+ memcpy (r->data, data, TRUST_RECORD_LEN);
+ r->flags.dirty = 1;
+ cache_is_dirty = 1;
+ cache_entries++;
+ return 0;
}
- /* see whether we reached the limit */
- if( cache_entries < MAX_CACHE_ENTRIES_SOFT ) { /* no */
- r = xmalloc( sizeof *r );
- r->flags.used = 1;
- r->recno = recno;
- memcpy( r->data, data, TRUST_RECORD_LEN );
- r->flags.dirty = 1;
- r->next = cache_list;
- cache_list = r;
- cache_is_dirty = 1;
- cache_entries++;
- return 0;
+
+ /* See whether we reached the limit. */
+ if (cache_entries < MAX_CACHE_ENTRIES_SOFT)
+ {
+ /* No: Put into cache. */
+ r = xmalloc (sizeof *r);
+ r->flags.used = 1;
+ r->recno = recno;
+ memcpy (r->data, data, TRUST_RECORD_LEN);
+ r->flags.dirty = 1;
+ r->next = cache_list;
+ cache_list = r;
+ cache_is_dirty = 1;
+ cache_entries++;
+ return 0;
}
- /* cache is full: discard some clean entries */
- if( clean_count ) {
- int n = clean_count / 3; /* discard a third of the clean entries */
- if( !n )
- n = 1;
- for( unused = NULL, r = cache_list; r; r = r->next ) {
- if( r->flags.used && !r->flags.dirty ) {
- if( !unused )
- unused = r;
- r->flags.used = 0;
- cache_entries--;
- if( !--n )
- break;
+
+ /* Cache is full: discard some clean entries. */
+ if (clean_count)
+ {
+ int n;
+
+ /* We discard a third of the clean entries. */
+ n = clean_count / 3;
+ if (!n)
+ n = 1;
+
+ for (unused = NULL, r = cache_list; r; r = r->next)
+ {
+ if (r->flags.used && !r->flags.dirty)
+ {
+ if (!unused)
+ unused = r;
+ r->flags.used = 0;
+ cache_entries--;
+ if (!--n)
+ break;
}
}
- assert( unused );
- r = unused;
- r->flags.used = 1;
- r->recno = recno;
- memcpy( r->data, data, TRUST_RECORD_LEN );
- r->flags.dirty = 1;
- cache_is_dirty = 1;
- cache_entries++;
- return 0;
+
+ /* Now put into the cache. */
+ assert (unused);
+ r = unused;
+ r->flags.used = 1;
+ r->recno = recno;
+ memcpy (r->data, data, TRUST_RECORD_LEN);
+ r->flags.dirty = 1;
+ cache_is_dirty = 1;
+ cache_entries++;
+ return 0;
}
- /* no clean entries: have to flush some dirty entries */
- if( in_transaction ) {
- /* but we can't do this while in a transaction
- * we increase the cache size instead */
- if( cache_entries < MAX_CACHE_ENTRIES_HARD ) { /* no */
- if( opt.debug && !(cache_entries % 100) )
- log_debug("increasing tdbio cache size\n");
- r = xmalloc( sizeof *r );
- r->flags.used = 1;
- r->recno = recno;
- memcpy( r->data, data, TRUST_RECORD_LEN );
- r->flags.dirty = 1;
- r->next = cache_list;
- cache_list = r;
- cache_is_dirty = 1;
- cache_entries++;
- return 0;
+
+ /* No clean entries: We have to flush some dirty entries. */
+ if (in_transaction)
+ {
+ /* But we can't do this while in a transaction. Thus we
+ * increase the cache size instead. */
+ if (cache_entries < MAX_CACHE_ENTRIES_HARD)
+ {
+ if (opt.debug && !(cache_entries % 100))
+ log_debug ("increasing tdbio cache size\n");
+ r = xmalloc (sizeof *r);
+ r->flags.used = 1;
+ r->recno = recno;
+ memcpy (r->data, data, TRUST_RECORD_LEN);
+ r->flags.dirty = 1;
+ r->next = cache_list;
+ cache_list = r;
+ cache_is_dirty = 1;
+ cache_entries++;
+ return 0;
}
- log_info(_("trustdb transaction too large\n"));
- return GPG_ERR_RESOURCE_LIMIT;
+ /* Hard limit for the cache size reached. */
+ log_info (_("trustdb transaction too large\n"));
+ return GPG_ERR_RESOURCE_LIMIT;
}
- if( dirty_count ) {
- int n = dirty_count / 5; /* discard some dirty entries */
- if( !n )
- n = 1;
- if( !is_locked ) {
- if( dotlock_take( lockhandle, -1 ) )
- log_fatal("can't acquire lock - giving up\n");
- else
- is_locked = 1;
- }
- for( unused = NULL, r = cache_list; r; r = r->next ) {
- if( r->flags.used && r->flags.dirty ) {
- int rc = write_cache_item( r );
- if( rc )
- return rc;
- if( !unused )
- unused = r;
- r->flags.used = 0;
- cache_entries--;
- if( !--n )
- break;
+
+ if (dirty_count)
+ {
+ int n;
+
+ /* Discard some dirty entries. */
+ n = dirty_count / 5;
+ if (!n)
+ n = 1;
+
+ take_write_lock ();
+ for (unused = NULL, r = cache_list; r; r = r->next)
+ {
+ if (r->flags.used && r->flags.dirty)
+ {
+ int rc;
+
+ rc = write_cache_item (r);
+ if (rc)
+ return rc;
+ if (!unused)
+ unused = r;
+ r->flags.used = 0;
+ cache_entries--;
+ if (!--n)
+ break;
}
}
- if( !opt.lock_once ) {
- if( !dotlock_release( lockhandle ) )
- is_locked = 0;
- }
- assert( unused );
- r = unused;
- r->flags.used = 1;
- r->recno = recno;
- memcpy( r->data, data, TRUST_RECORD_LEN );
- r->flags.dirty = 1;
- cache_is_dirty = 1;
- cache_entries++;
- return 0;
+ release_write_lock ();
+
+ /* Now put into the cache. */
+ assert (unused);
+ r = unused;
+ r->flags.used = 1;
+ r->recno = recno;
+ memcpy (r->data, data, TRUST_RECORD_LEN);
+ r->flags.dirty = 1;
+ cache_is_dirty = 1;
+ cache_entries++;
+ return 0;
}
- BUG();
+
+ /* We should never reach this. */
+ BUG();
}
+/* Return true if the cache is dirty. */
int
tdbio_is_dirty()
{
- return cache_is_dirty;
+ return cache_is_dirty;
}
-/****************
+/*
* Flush the cache. This cannot be used while in a transaction.
*/
int
if( !cache_is_dirty )
return 0;
- if( !is_locked ) {
- if( dotlock_take( lockhandle, -1 ) )
- log_fatal("can't acquire lock - giving up\n");
- else
- is_locked = 1;
- did_lock = 1;
- }
+ if (!take_write_lock ())
+ did_lock = 1;
+
for( r = cache_list; r; r = r->next ) {
if( r->flags.used && r->flags.dirty ) {
int rc = write_cache_item( r );
}
}
cache_is_dirty = 0;
- if( did_lock && !opt.lock_once ) {
- if( !dotlock_release (lockhandle) )
- is_locked = 0;
- }
+ if (did_lock)
+ release_write_lock ();
return 0;
}
-#if 0
-/* The transaction code is disabled in the 1.2.x branch, as it is not
- yet used. It will be enabled in 1.3.x. */
-/****************
+#if 0 /* Not yet used. */
+/*
* Simple transactions system:
* Everything between begin_transaction and end/cancel_transaction
* is not immediatly written but at the time of end_transaction.
*
+ * NOTE: The transaction code is disabled in the 1.2 branch, as it is
+ * not yet used.
*/
int
-tdbio_begin_transaction()
+tdbio_begin_transaction () /* Not yet used. */
{
- int rc;
+ int rc;
- if( in_transaction )
- log_bug("tdbio: nested transactions\n");
- /* flush everything out */
- rc = tdbio_sync();
- if( rc )
- return rc;
- in_transaction = 1;
- return 0;
+ if (in_transaction)
+ log_bug ("tdbio: nested transactions\n");
+ /* Flush everything out. */
+ rc = tdbio_sync();
+ if (rc)
+ return rc;
+ in_transaction = 1;
+ return 0;
}
int
-tdbio_end_transaction()
+tdbio_end_transaction () /* Not yet used. */
{
- int rc;
-
- if( !in_transaction )
- log_bug("tdbio: no active transaction\n");
- if( !is_locked ) {
- if( dotlock_take( lockhandle, -1 ) )
- log_fatal("can't acquire lock - giving up\n");
- else
- is_locked = 1;
- }
- block_all_signals();
- in_transaction = 0;
- rc = tdbio_sync();
- unblock_all_signals();
- if( !opt.lock_once ) {
- if( !dotlock_release (lockhandle) )
- is_locked = 0;
- }
- return rc;
+ int rc;
+
+ if (!in_transaction)
+ log_bug ("tdbio: no active transaction\n");
+ take_write_lock ();
+ gnupg_block_all_signals ();
+ in_transaction = 0;
+ rc = tdbio_sync();
+ gnupg_unblock_all_signals();
+ release_write_lock ();
+ return rc;
}
int
-tdbio_cancel_transaction()
+tdbio_cancel_transaction () /* Not yet used. */
{
- CACHE_CTRL r;
+ CACHE_CTRL r;
- if( !in_transaction )
- log_bug("tdbio: no active transaction\n");
+ if (!in_transaction)
+ log_bug ("tdbio: no active transaction\n");
- /* remove all dirty marked entries, so that the original ones
- * are read back the next time */
- if( cache_is_dirty ) {
- for( r = cache_list; r; r = r->next ) {
- if( r->flags.used && r->flags.dirty ) {
- r->flags.used = 0;
- cache_entries--;
+ /* Remove all dirty marked entries, so that the original ones are
+ * read back the next time. */
+ if (cache_is_dirty)
+ {
+ for (r = cache_list; r; r = r->next)
+ {
+ if (r->flags.used && r->flags.dirty)
+ {
+ r->flags.used = 0;
+ cache_entries--;
}
}
- cache_is_dirty = 0;
+ cache_is_dirty = 0;
}
- in_transaction = 0;
- return 0;
+ in_transaction = 0;
+ return 0;
}
-#endif
+#endif /* Not yet used. */
+
\f
/********************************************************
**************** cached I/O functions ******************
********************************************************/
+/* The cleanup handler for this module. */
static void
-cleanup(void)
+cleanup (void)
{
- if( is_locked ) {
- if( !dotlock_release (lockhandle) )
- is_locked = 0;
+ if (is_locked)
+ {
+ if (!dotlock_release (lockhandle))
+ is_locked = 0;
}
}
-/* Caller must sync */
+
+/*
+ * Update an existing trustdb record. The caller must call
+ * tdbio_sync.
+ *
+ * Returns: 0 on success or an error code.
+ */
int
tdbio_update_version_record (void)
{
TRUSTREC rec;
int rc;
- memset( &rec, 0, sizeof rec );
+ memset (&rec, 0, sizeof rec);
- rc=tdbio_read_record( 0, &rec, RECTYPE_VER);
- if(rc==0)
+ rc = tdbio_read_record (0, &rec, RECTYPE_VER);
+ if (!rc)
{
rec.r.ver.created = make_timestamp();
rec.r.ver.marginals = opt.marginals_needed;
return rc;
}
+
+/*
+ * Create and write the trustdb version record.
+ *
+ * Returns: 0 on success or an error code.
+ */
static int
create_version_record (void)
{
TRUSTREC rec;
int rc;
- memset( &rec, 0, sizeof rec );
+ memset (&rec, 0, sizeof rec);
rec.r.ver.version = 3;
- rec.r.ver.created = make_timestamp();
+ rec.r.ver.created = make_timestamp ();
rec.r.ver.marginals = opt.marginals_needed;
rec.r.ver.completes = opt.completes_needed;
rec.r.ver.cert_depth = opt.max_cert_depth;
- if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
+ if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC)
rec.r.ver.trust_model = opt.trust_model;
else
rec.r.ver.trust_model = TM_PGP;
rec.r.ver.min_cert_level = opt.min_cert_level;
rec.rectype = RECTYPE_VER;
rec.recnum = 0;
- rc = tdbio_write_record( &rec );
- if( !rc )
- tdbio_sync();
+ rc = tdbio_write_record (&rec);
+ if (!rc)
+ tdbio_sync ();
return rc;
}
-
+/*
+ * Set the file name for the trustdb to NEW_DBNAME and if CREATE is
+ * true create that file. If NEW_DBNAME is NULL a default name is
+ * used, if the it does not contain a path component separator ('/')
+ * the global GnuPG home directory is used.
+ *
+ * Returns: 0 on success or an error code.
+ *
+ * On the first call this function registers an atexit handler.
+ *
+ */
int
-tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
+tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile)
{
- char *fname;
- static int initialized = 0;
+ char *fname;
+ struct stat statbuf;
+ static int initialized = 0;
- if( !initialized ) {
- atexit( cleanup );
- initialized = 1;
+ if (!initialized)
+ {
+ atexit (cleanup);
+ initialized = 1;
}
- *r_nofile = 0;
+ *r_nofile = 0;
- if(new_dbname==NULL)
- fname=make_filename(opt.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);
- }
- else
+ if (!new_dbname)
+ {
+ fname = make_filename (opt.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);
+ }
+ else
+ {
fname = xstrdup (new_dbname);
+ }
+
+ xfree (db_name);
+ db_name = fname;
+
+ /* Quick check for (likely) case where there already is a
+ * trustdb.gpg. This check is not required in theory, but it helps
+ * in practice avoiding costly operations of preparing and taking
+ * the lock. */
+ if (!stat (fname, &statbuf) && statbuf.st_size > 0)
+ {
+ /* OK, we have the valid trustdb.gpg already. */
+ return 0;
+ }
+
+ take_write_lock ();
- if( access( fname, R_OK ) ) {
+ if (access (fname, R_OK))
+ {
#ifdef HAVE_W32CE_SYSTEM
/* We know how the cegcc implementation of access works ;-). */
if (GetLastError () == ERROR_FILE_NOT_FOUND)
else
gpg_err_set_errno (EIO);
#endif /*HAVE_W32CE_SYSTEM*/
- if( errno != ENOENT ) {
- log_error( _("can't access '%s': %s\n"), fname, strerror(errno) );
- xfree(fname);
- return GPG_ERR_TRUSTDB;
- }
- if (!create)
- *r_nofile = 1;
- else {
- FILE *fp;
- TRUSTREC rec;
- int rc;
- char *p = strrchr( fname, DIRSEP_C );
- mode_t oldmask;
- int save_slash;
+ if (errno != ENOENT)
+ log_fatal ( _("can't access '%s': %s\n"), fname, strerror (errno));
+
+ if (!create)
+ *r_nofile = 1;
+ else
+ {
+ FILE *fp;
+ TRUSTREC rec;
+ int rc;
+ char *p = strrchr (fname, DIRSEP_C);
+ mode_t oldmask;
+ int save_slash;
#if HAVE_W32_SYSTEM
- {
- /* Windows may either have a slash or a backslash. Take
- care of it. */
- char *pp = strrchr (fname, '/');
- if (!p || pp > p)
- p = pp;
- }
+ {
+ /* Windows may either have a slash or a backslash. Take
+ care of it. */
+ char *pp = strrchr (fname, '/');
+ if (!p || pp > p)
+ p = pp;
+ }
#endif /*HAVE_W32_SYSTEM*/
- assert (p);
- save_slash = *p;
- *p = 0;
- if( access( fname, F_OK ) ) {
- try_make_homedir( fname );
- if (access (fname, F_OK ))
- log_fatal (_("%s: directory does not exist!\n"), fname);
+ assert (p);
+ save_slash = *p;
+ *p = 0;
+ if (access (fname, F_OK))
+ {
+ try_make_homedir (fname);
+ if (access (fname, F_OK))
+ log_fatal (_("%s: directory does not exist!\n"), fname);
}
- *p = save_slash;
-
- xfree(db_name);
- db_name = fname;
-#ifdef __riscos__
- if( !lockhandle )
- lockhandle = dotlock_create (db_name, 0);
- if( !lockhandle )
- log_fatal( _("can't create lock for '%s'\n"), db_name );
- if( dotlock_make (lockhandle, -1) )
- log_fatal( _("can't lock '%s'\n"), db_name );
-#endif /* __riscos__ */
- oldmask=umask(077);
- if (is_secured_filename (fname)) {
- fp = NULL;
- gpg_err_set_errno (EPERM);
- }
- else
- fp =fopen( fname, "wb" );
- umask(oldmask);
- if( !fp )
- log_fatal (_("can't create '%s': %s\n"),
- fname, strerror (errno));
- fclose(fp);
- db_fd = open( db_name, O_RDWR | MY_O_BINARY );
- if( db_fd == -1 )
- log_fatal (_("can't open '%s': %s\n"),
- db_name, strerror (errno));
-
-#ifndef __riscos__
- if( !lockhandle )
- lockhandle = dotlock_create (db_name, 0);
- if( !lockhandle )
- log_fatal( _("can't create lock for '%s'\n"), db_name );
-#endif /* !__riscos__ */
-
- rc = create_version_record ();
- if( rc )
- log_fatal( _("%s: failed to create version record: %s"),
- fname, gpg_strerror (rc));
- /* and read again to check that we are okay */
- if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
- log_fatal( _("%s: invalid trustdb created\n"), db_name );
+ *p = save_slash;
- if( !opt.quiet )
- log_info(_("%s: trustdb created\n"), db_name);
-
- return 0;
+ oldmask = umask (077);
+ if (is_secured_filename (fname))
+ {
+ fp = NULL;
+ gpg_err_set_errno (EPERM);
+ }
+ else
+ fp = fopen (fname, "wb");
+ umask(oldmask);
+ if (!fp)
+ log_fatal (_("can't create '%s': %s\n"), fname, strerror (errno));
+ fclose (fp);
+
+ db_fd = open (db_name, O_RDWR | MY_O_BINARY);
+ if (db_fd == -1)
+ log_fatal (_("can't open '%s': %s\n"), db_name, strerror (errno));
+
+ rc = create_version_record ();
+ if (rc)
+ log_fatal (_("%s: failed to create version record: %s"),
+ fname, gpg_strerror (rc));
+
+ /* Read again to check that we are okay. */
+ if (tdbio_read_record (0, &rec, RECTYPE_VER))
+ log_fatal (_("%s: invalid trustdb created\n"), db_name);
+
+ if (!opt.quiet)
+ log_info (_("%s: trustdb created\n"), db_name);
}
}
- xfree(db_name);
- db_name = fname;
- return 0;
+
+ release_write_lock ();
+ return 0;
}
+/*
+ * Return the full name of the trustdb.
+ */
const char *
-tdbio_get_dbname()
+tdbio_get_dbname ()
{
- return db_name;
+ return db_name;
}
-
+/*
+ * Open the trustdb. This may only be called if it has not yet been
+ * opened and after a successful call to tdbio_set_dbname. On return
+ * the trustdb handle (DB_FD) is guaranteed to be open.
+ */
static void
-open_db()
+open_db ()
{
TRUSTREC rec;
assert( db_fd == -1 );
- if (!lockhandle )
- lockhandle = dotlock_create (db_name, 0);
- if (!lockhandle )
- log_fatal( _("can't create lock for '%s'\n"), db_name );
-#ifdef __riscos__
- if (dotlock_take (lockhandle, -1) )
- log_fatal( _("can't lock '%s'\n"), db_name );
-#endif /* __riscos__ */
#ifdef HAVE_W32CE_SYSTEM
{
DWORD prevrc = 0;
}
-/****************
- * Make a hashtable: type 0 = trust hash
+/*
+ * Append a new empty hashtable to the trustdb. TYPE gives the type
+ * of the hash table. The only defined type is 0 for a trust hash.
+ * On return the hashtable has been created, written, the version
+ * record update, and the data flushed to the disk. On a fatal error
+ * the function terminates the process.
*/
static void
create_hashtable( TRUSTREC *vr, int type )
{
- TRUSTREC rec;
- off_t offset;
- ulong recnum;
- int i, n, rc;
-
- offset = lseek( db_fd, 0, SEEK_END );
- if( offset == -1 )
- log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) );
- recnum = offset / TRUST_RECORD_LEN;
- assert(recnum); /* this is will never be the first record */
-
- if( !type )
- vr->r.ver.trusthashtbl = recnum;
-
- /* Now write the records */
- n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD;
- for(i=0; i < n; i++, recnum++ ) {
- memset( &rec, 0, sizeof rec );
- rec.rectype = RECTYPE_HTBL;
- rec.recnum = recnum;
- rc = tdbio_write_record( &rec );
- if( rc )
- log_fatal( _("%s: failed to create hashtable: %s\n"),
- db_name, gpg_strerror (rc));
+ TRUSTREC rec;
+ off_t offset;
+ ulong recnum;
+ int i, n, rc;
+
+ offset = lseek (db_fd, 0, SEEK_END);
+ if (offset == -1)
+ log_fatal ("trustdb: lseek to end failed: %s\n", strerror(errno));
+ recnum = offset / TRUST_RECORD_LEN;
+ assert (recnum); /* This is will never be the first record. */
+
+ if (!type)
+ vr->r.ver.trusthashtbl = recnum;
+
+ /* Now write the records making up the hash table. */
+ n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD;
+ for (i=0; i < n; i++, recnum++)
+ {
+ memset (&rec, 0, sizeof rec);
+ rec.rectype = RECTYPE_HTBL;
+ rec.recnum = recnum;
+ rc = tdbio_write_record (&rec);
+ if (rc)
+ log_fatal (_("%s: failed to create hashtable: %s\n"),
+ db_name, gpg_strerror (rc));
}
- /* update the version record */
- rc = tdbio_write_record( vr );
- if( !rc )
- rc = tdbio_sync();
- if( rc )
- log_fatal( _("%s: error updating version record: %s\n"),
- db_name, gpg_strerror (rc));
+ /* Update the version record and flush. */
+ rc = tdbio_write_record (vr);
+ if (!rc)
+ rc = tdbio_sync ();
+ if (rc)
+ log_fatal (_("%s: error updating version record: %s\n"),
+ db_name, gpg_strerror (rc));
}
+/*
+ * Check whether open trustdb matches the global trust options given
+ * for this process. On a read problem the process is terminated.
+ *
+ * Return: 1 for yes, 0 for no.
+ */
int
tdbio_db_matches_options()
{
static int yes_no = -1;
- if( yes_no == -1 )
+ if (yes_no == -1)
{
TRUSTREC vr;
int rc;
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
+ rc = tdbio_read_record (0, &vr, RECTYPE_VER);
if( rc )
log_fatal( _("%s: error reading version record: %s\n"),
db_name, gpg_strerror (rc) );
return yes_no;
}
+
+/*
+ * Read and return the trust model identifier from the trustdb. On a
+ * read problem the process is terminated.
+ */
byte
-tdbio_read_model(void)
+tdbio_read_model (void)
{
TRUSTREC vr;
int rc;
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
+ rc = tdbio_read_record (0, &vr, RECTYPE_VER );
+ if (rc)
+ log_fatal (_("%s: error reading version record: %s\n"),
db_name, gpg_strerror (rc) );
return vr.r.ver.trust_model;
}
-/****************
- * Return the nextstamp value.
+
+/*
+ * Read and return the nextstamp value from the trustdb. On a read
+ * problem the process is terminated.
*/
ulong
tdbio_read_nextcheck ()
{
- TRUSTREC vr;
- int rc;
+ TRUSTREC vr;
+ int rc;
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc));
- return vr.r.ver.nextcheck;
+ rc = tdbio_read_record (0, &vr, RECTYPE_VER);
+ if (rc)
+ log_fatal (_("%s: error reading version record: %s\n"),
+ db_name, gpg_strerror (rc));
+ return vr.r.ver.nextcheck;
}
-/* Return true when the stamp was actually changed. */
+
+/*
+ * Write the STAMP nextstamp timestamp to the trustdb. On a read or
+ * write problem the process is terminated.
+ *
+ * Return: True if the stamp actually changed.
+ */
int
tdbio_write_nextcheck (ulong stamp)
{
- TRUSTREC vr;
- int rc;
+ TRUSTREC vr;
+ int rc;
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
+ rc = tdbio_read_record (0, &vr, RECTYPE_VER);
+ if (rc)
+ log_fatal (_("%s: error reading version record: %s\n"),
+ db_name, gpg_strerror (rc));
- if (vr.r.ver.nextcheck == stamp)
- return 0;
+ if (vr.r.ver.nextcheck == stamp)
+ return 0;
- vr.r.ver.nextcheck = stamp;
- rc = tdbio_write_record( &vr );
- if( rc )
- log_fatal( _("%s: error writing version record: %s\n"),
- db_name, gpg_strerror (rc) );
- return 1;
+ vr.r.ver.nextcheck = stamp;
+ rc = tdbio_write_record( &vr );
+ if (rc)
+ log_fatal (_("%s: error writing version record: %s\n"),
+ db_name, gpg_strerror (rc));
+ return 1;
}
-/****************
- * Return the record number of the trusthash tbl or create a new one.
+/*
+ * Return the record number of the trusthash table or create one if it
+ * does not yet exist. On a read or write problem the process is
+ * terminated.
+ *
+ * Return: record number
*/
static ulong
get_trusthashrec(void)
{
- static ulong trusthashtbl; /* record number of the trust hashtable */
+ static ulong trusthashtbl; /* Record number of the trust hashtable. */
- if( !trusthashtbl ) {
- TRUSTREC vr;
- int rc;
+ if (!trusthashtbl)
+ {
+ TRUSTREC vr;
+ int rc;
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
- if( !vr.r.ver.trusthashtbl )
- create_hashtable( &vr, 0 );
+ rc = tdbio_read_record (0, &vr, RECTYPE_VER );
+ if (rc)
+ log_fatal (_("%s: error reading version record: %s\n"),
+ db_name, gpg_strerror (rc) );
+ if (!vr.r.ver.trusthashtbl)
+ create_hashtable (&vr, 0);
- trusthashtbl = vr.r.ver.trusthashtbl;
+ trusthashtbl = vr.r.ver.trusthashtbl;
}
- return trusthashtbl;
+
+ return trusthashtbl;
}
-/****************
- * Update a hashtable.
- * table gives the start of the table, key and keylen is the key,
- * newrecnum is the record number to insert.
+/*
+ * Update a hashtable in the trustdb. TABLE gives the start of the
+ * table, KEY and KEYLEN are the key, NEWRECNUM is the record number
+ * to insert into the table.
+ *
+ * Return: 0 on success or an error code.
*/
static int
-upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
+upd_hashtable (ulong table, byte *key, int keylen, ulong newrecnum)
{
- TRUSTREC lastrec, rec;
- ulong hashrec, item;
- int msb;
- int level=0;
- int rc, i;
-
- hashrec = table;
- next_level:
- msb = key[level];
- hashrec += msb / ITEMS_PER_HTBL_RECORD;
- rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL );
- if( rc ) {
- log_error("upd_hashtable: read failed: %s\n", gpg_strerror (rc) );
- return rc;
+ TRUSTREC lastrec, rec;
+ ulong hashrec, item;
+ int msb;
+ int level = 0;
+ int rc, i;
+
+ hashrec = table;
+ next_level:
+ msb = key[level];
+ hashrec += msb / ITEMS_PER_HTBL_RECORD;
+ rc = tdbio_read_record (hashrec, &rec, RECTYPE_HTBL);
+ if (rc)
+ {
+ log_error ("upd_hashtable: read failed: %s\n", gpg_strerror (rc));
+ return rc;
}
- item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
- if( !item ) { /* insert a new item into the hash table */
- rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = newrecnum;
- rc = tdbio_write_record( &rec );
- if( rc ) {
- log_error("upd_hashtable: write htbl failed: %s\n",
- gpg_strerror (rc) );
- return rc;
+ item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
+ if (!item) /* Insert a new item into the hash table. */
+ {
+ rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = newrecnum;
+ rc = tdbio_write_record (&rec);
+ if (rc)
+ {
+ log_error ("upd_hashtable: write htbl failed: %s\n",
+ gpg_strerror (rc));
+ return rc;
}
}
- else if( item != newrecnum ) { /* must do an update */
- lastrec = rec;
- rc = tdbio_read_record( item, &rec, 0 );
- if( rc ) {
- log_error( "upd_hashtable: read item failed: %s\n",
- gpg_strerror (rc) );
- return rc;
+ else if (item != newrecnum) /* Must do an update. */
+ {
+ lastrec = rec;
+ rc = tdbio_read_record (item, &rec, 0);
+ if (rc)
+ {
+ log_error ("upd_hashtable: read item failed: %s\n",
+ gpg_strerror (rc));
+ return rc;
}
- if( rec.rectype == RECTYPE_HTBL ) {
- hashrec = item;
- level++;
- if( level >= keylen ) {
- log_error( "hashtable has invalid indirections.\n");
- return GPG_ERR_TRUSTDB;
+ if (rec.rectype == RECTYPE_HTBL)
+ {
+ hashrec = item;
+ level++;
+ if (level >= keylen)
+ {
+ log_error ("hashtable has invalid indirections.\n");
+ return GPG_ERR_TRUSTDB;
}
- goto next_level;
+ goto next_level;
}
- else if( rec.rectype == RECTYPE_HLST ) { /* extend list */
- /* see whether the key is already in this list */
- for(;;) {
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- if( rec.r.hlst.rnum[i] == newrecnum ) {
- return 0; /* okay, already in the list */
+ else if (rec.rectype == RECTYPE_HLST) /* Extend the list. */
+ {
+ /* Check whether the key is already in this list. */
+ for (;;)
+ {
+ for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
+ {
+ if (rec.r.hlst.rnum[i] == newrecnum)
+ {
+ return 0; /* Okay, already in the list. */
}
}
- if( rec.r.hlst.next ) {
- rc = tdbio_read_record( rec.r.hlst.next,
- &rec, RECTYPE_HLST);
- if( rc ) {
- log_error ("upd_hashtable: read hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
+ if (rec.r.hlst.next)
+ {
+ rc = tdbio_read_record (rec.r.hlst.next, &rec, RECTYPE_HLST);
+ if (rc)
+ {
+ log_error ("upd_hashtable: read hlst failed: %s\n",
+ gpg_strerror (rc) );
+ return rc;
}
}
- else
- break; /* not there */
+ else
+ break; /* key is not in the list */
}
- /* find the next free entry and put it in */
- for(;;) {
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- if( !rec.r.hlst.rnum[i] ) {
- rec.r.hlst.rnum[i] = newrecnum;
- rc = tdbio_write_record( &rec );
- if( rc )
- log_error ("upd_hashtable: write hlst failed: %s\n",
- gpg_strerror (rc));
- return rc; /* done */
+
+ /* Find the next free entry and put it in. */
+ for (;;)
+ {
+ for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
+ {
+ if (!rec.r.hlst.rnum[i])
+ {
+ /* Empty slot found. */
+ rec.r.hlst.rnum[i] = newrecnum;
+ rc = tdbio_write_record (&rec);
+ if (rc)
+ log_error ("upd_hashtable: write hlst failed: %s\n",
+ gpg_strerror (rc));
+ return rc; /* Done. */
}
}
- if( rec.r.hlst.next ) {
- rc = tdbio_read_record( rec.r.hlst.next,
- &rec, RECTYPE_HLST );
- if( rc ) {
- log_error ("upd_hashtable: read hlst failed: %s\n",
- gpg_strerror (rc));
- return rc;
+
+ if (rec.r.hlst.next)
+ {
+ /* read the next reord of the list. */
+ rc = tdbio_read_record (rec.r.hlst.next, &rec, RECTYPE_HLST);
+ if (rc)
+ {
+ log_error ("upd_hashtable: read hlst failed: %s\n",
+ gpg_strerror (rc));
+ return rc;
}
}
- else { /* add a new list record */
- rec.r.hlst.next = item = tdbio_new_recnum();
- rc = tdbio_write_record( &rec );
- if( rc ) {
- log_error( "upd_hashtable: write hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
+ else
+ {
+ /* Append a new record to the list. */
+ rec.r.hlst.next = item = tdbio_new_recnum ();
+ rc = tdbio_write_record (&rec);
+ if (rc)
+ {
+ log_error ("upd_hashtable: write hlst failed: %s\n",
+ gpg_strerror (rc));
+ return rc;
}
- memset( &rec, 0, sizeof rec );
- rec.rectype = RECTYPE_HLST;
- rec.recnum = item;
- rec.r.hlst.rnum[0] = newrecnum;
- rc = tdbio_write_record( &rec );
- if( rc )
- log_error( "upd_hashtable: write ext hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc; /* done */
+ memset (&rec, 0, sizeof rec);
+ rec.rectype = RECTYPE_HLST;
+ rec.recnum = item;
+ rec.r.hlst.rnum[0] = newrecnum;
+ rc = tdbio_write_record (&rec);
+ if (rc)
+ log_error ("upd_hashtable: write ext hlst failed: %s\n",
+ gpg_strerror (rc));
+ return rc; /* Done. */
}
- } /* end loop over hlst slots */
- }
- else if( rec.rectype == RECTYPE_TRUST ) { /* insert a list record */
- if( rec.recnum == newrecnum ) {
- return 0;
- }
- item = rec.recnum; /* save number of key record */
- memset( &rec, 0, sizeof rec );
- rec.rectype = RECTYPE_HLST;
- rec.recnum = tdbio_new_recnum();
- rec.r.hlst.rnum[0] = item; /* old keyrecord */
- rec.r.hlst.rnum[1] = newrecnum; /* and new one */
- rc = tdbio_write_record( &rec );
- if( rc ) {
- log_error( "upd_hashtable: write new hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
- }
- /* update the hashtable record */
- lastrec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = rec.recnum;
- rc = tdbio_write_record( &lastrec );
- if( rc )
- log_error ("upd_hashtable: update htbl failed: %s\n",
- gpg_strerror (rc));
- return rc; /* ready */
+ } /* end loop over list slots */
+
}
- else {
- log_error( "hashtbl %lu: %lu/%d points to an invalid record %lu\n",
- table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
- list_trustdb(NULL);
- return GPG_ERR_TRUSTDB;
+ else if (rec.rectype == RECTYPE_TRUST) /* Insert a list record. */
+ {
+ if (rec.recnum == newrecnum)
+ {
+ return 0;
+ }
+ item = rec.recnum; /* Save number of key record. */
+ memset (&rec, 0, sizeof rec);
+ rec.rectype = RECTYPE_HLST;
+ rec.recnum = tdbio_new_recnum ();
+ rec.r.hlst.rnum[0] = item; /* Old key record */
+ rec.r.hlst.rnum[1] = newrecnum; /* and new key record */
+ rc = tdbio_write_record (&rec);
+ if (rc)
+ {
+ log_error( "upd_hashtable: write new hlst failed: %s\n",
+ gpg_strerror (rc) );
+ return rc;
+ }
+ /* Update the hashtable record. */
+ lastrec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = rec.recnum;
+ rc = tdbio_write_record (&lastrec);
+ if (rc)
+ log_error ("upd_hashtable: update htbl failed: %s\n",
+ gpg_strerror (rc));
+ return rc; /* Ready. */
+ }
+ else
+ {
+ log_error ("hashtbl %lu: %lu/%d points to an invalid record %lu\n",
+ table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
+ if (opt.verbose > 1)
+ list_trustdb (es_stderr, NULL);
+ return GPG_ERR_TRUSTDB;
}
}
- return 0;
+ return 0;
}
-/****************
- * Drop an entry from a hashtable
- * table gives the start of the table, key and keylen is the key,
+/*
+ * Drop an entry from a hashtable. TABLE gives the start of the
+ * table, KEY and KEYLEN are the key.
+ *
+ * Return: 0 on success or an error code.
*/
static int
-drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum )
+drop_from_hashtable (ulong table, byte *key, int keylen, ulong recnum)
{
- TRUSTREC rec;
- ulong hashrec, item;
- int msb;
- int level=0;
- int rc, i;
-
- hashrec = table;
- next_level:
- msb = key[level];
- hashrec += msb / ITEMS_PER_HTBL_RECORD;
- rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL );
- if( rc ) {
- log_error("drop_from_hashtable: read failed: %s\n",
- gpg_strerror (rc) );
- return rc;
+ TRUSTREC rec;
+ ulong hashrec, item;
+ int msb;
+ int level = 0;
+ int rc, i;
+
+ hashrec = table;
+ next_level:
+ msb = key[level];
+ hashrec += msb / ITEMS_PER_HTBL_RECORD;
+ rc = tdbio_read_record (hashrec, &rec, RECTYPE_HTBL );
+ if (rc)
+ {
+ log_error ("drop_from_hashtable: read failed: %s\n", gpg_strerror (rc));
+ return rc;
}
- item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
- if( !item ) /* not found - forget about it */
- return 0;
+ item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
+ if (!item)
+ return 0; /* Not found - forget about it. */
- if( item == recnum ) { /* tables points direct to the record */
- rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = 0;
- rc = tdbio_write_record( &rec );
- if( rc )
- log_error("drop_from_hashtable: write htbl failed: %s\n",
- gpg_strerror (rc) );
- return rc;
+ if (item == recnum) /* Table points direct to the record. */
+ {
+ rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = 0;
+ rc = tdbio_write_record( &rec );
+ if (rc)
+ log_error ("drop_from_hashtable: write htbl failed: %s\n",
+ gpg_strerror (rc));
+ return rc;
}
- rc = tdbio_read_record( item, &rec, 0 );
- if( rc ) {
- log_error( "drop_from_hashtable: read item failed: %s\n",
- gpg_strerror (rc) );
- return rc;
+ rc = tdbio_read_record (item, &rec, 0);
+ if (rc)
+ {
+ log_error ("drop_from_hashtable: read item failed: %s\n",
+ gpg_strerror (rc));
+ return rc;
}
- if( rec.rectype == RECTYPE_HTBL ) {
- hashrec = item;
- level++;
- if( level >= keylen ) {
- log_error( "hashtable has invalid indirections.\n");
- return GPG_ERR_TRUSTDB;
+ if (rec.rectype == RECTYPE_HTBL)
+ {
+ hashrec = item;
+ level++;
+ if (level >= keylen)
+ {
+ log_error ("hashtable has invalid indirections.\n");
+ return GPG_ERR_TRUSTDB;
}
- goto next_level;
+ goto next_level;
}
- if( rec.rectype == RECTYPE_HLST ) {
- for(;;) {
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- if( rec.r.hlst.rnum[i] == recnum ) {
- rec.r.hlst.rnum[i] = 0; /* drop */
- rc = tdbio_write_record( &rec );
- if( rc )
- log_error("drop_from_hashtable: write htbl failed: %s\n",
- gpg_strerror (rc));
- return rc;
+ if (rec.rectype == RECTYPE_HLST)
+ {
+ for (;;)
+ {
+ for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
+ {
+ if (rec.r.hlst.rnum[i] == recnum)
+ {
+ rec.r.hlst.rnum[i] = 0; /* Mark as free. */
+ rc = tdbio_write_record (&rec);
+ if (rc)
+ log_error("drop_from_hashtable: write htbl failed: %s\n",
+ gpg_strerror (rc));
+ return rc;
}
}
- if( rec.r.hlst.next ) {
- rc = tdbio_read_record( rec.r.hlst.next,
- &rec, RECTYPE_HLST);
- if( rc ) {
- log_error( "drop_from_hashtable: read hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
+ if (rec.r.hlst.next)
+ {
+ rc = tdbio_read_record (rec.r.hlst.next, &rec, RECTYPE_HLST);
+ if (rc)
+ {
+ log_error ("drop_from_hashtable: read hlst failed: %s\n",
+ gpg_strerror (rc));
+ return rc;
}
}
- else
- return 0; /* key not in table */
+ else
+ return 0; /* Key not in table. */
}
}
- log_error( "hashtbl %lu: %lu/%d points to wrong record %lu\n",
- table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
- return GPG_ERR_TRUSTDB;
+ log_error ("hashtbl %lu: %lu/%d points to wrong record %lu\n",
+ table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
+ return GPG_ERR_TRUSTDB;
}
-/****************
- * Lookup a record via the hashtable tablewith key/keylen and return the
- * result in rec. cmp() should return if the record is the desired one.
- * Returns -1 if not found, 0 if found or another errocode
+/*
+ * Lookup a record via the hashtable TABLE by (KEY,KEYLEN) and return
+ * the result in REC. The return value of CMP() should be True if the
+ * record is the desired one.
+ *
+ * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
*/
-static int
-lookup_hashtable( ulong table, const byte *key, size_t keylen,
+static gpg_error_t
+lookup_hashtable (ulong table, const byte *key, size_t keylen,
int (*cmpfnc)(const void*, const TRUSTREC *),
const void *cmpdata, TRUSTREC *rec )
{
- int rc;
- ulong hashrec, item;
- int msb;
- int level=0;
-
- hashrec = table;
- next_level:
- msb = key[level];
- hashrec += msb / ITEMS_PER_HTBL_RECORD;
- rc = tdbio_read_record( hashrec, rec, RECTYPE_HTBL );
- if( rc ) {
- log_error("lookup_hashtable failed: %s\n", gpg_strerror (rc) );
- return rc;
+ int rc;
+ ulong hashrec, item;
+ int msb;
+ int level = 0;
+
+ hashrec = table;
+ next_level:
+ msb = key[level];
+ hashrec += msb / ITEMS_PER_HTBL_RECORD;
+ rc = tdbio_read_record (hashrec, rec, RECTYPE_HTBL);
+ if (rc)
+ {
+ log_error("lookup_hashtable failed: %s\n", gpg_strerror (rc) );
+ return rc;
}
- item = rec->r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
- if( !item )
- return -1; /* not found */
+ item = rec->r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
+ if (!item)
+ return gpg_error (GPG_ERR_NOT_FOUND);
- rc = tdbio_read_record( item, rec, 0 );
- if( rc ) {
- log_error( "hashtable read failed: %s\n", gpg_strerror (rc) );
- return rc;
+ rc = tdbio_read_record (item, rec, 0);
+ if (rc)
+ {
+ log_error( "hashtable read failed: %s\n", gpg_strerror (rc) );
+ return rc;
}
- if( rec->rectype == RECTYPE_HTBL ) {
- hashrec = item;
- level++;
- if( level >= keylen ) {
- log_error("hashtable has invalid indirections\n");
- return GPG_ERR_TRUSTDB;
+ if (rec->rectype == RECTYPE_HTBL)
+ {
+ hashrec = item;
+ level++;
+ if (level >= keylen)
+ {
+ log_error ("hashtable has invalid indirections\n");
+ return GPG_ERR_TRUSTDB;
}
- goto next_level;
+ goto next_level;
}
- else if( rec->rectype == RECTYPE_HLST ) {
- for(;;) {
- int i;
-
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- if( rec->r.hlst.rnum[i] ) {
- TRUSTREC tmp;
+ else if (rec->rectype == RECTYPE_HLST)
+ {
+ for (;;)
+ {
+ int i;
- rc = tdbio_read_record( rec->r.hlst.rnum[i], &tmp, 0 );
- if( rc ) {
- log_error ("lookup_hashtable: read item failed: %s\n",
- gpg_strerror (rc));
- return rc;
+ for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
+ {
+ if (rec->r.hlst.rnum[i])
+ {
+ TRUSTREC tmp;
+
+ rc = tdbio_read_record (rec->r.hlst.rnum[i], &tmp, 0);
+ if (rc)
+ {
+ log_error ("lookup_hashtable: read item failed: %s\n",
+ gpg_strerror (rc));
+ return rc;
}
- if( (*cmpfnc)( cmpdata, &tmp ) ) {
- *rec = tmp;
- return 0;
+ if ((*cmpfnc)(cmpdata, &tmp))
+ {
+ *rec = tmp;
+ return 0;
}
}
}
- if( rec->r.hlst.next ) {
- rc = tdbio_read_record( rec->r.hlst.next, rec, RECTYPE_HLST );
- if( rc ) {
- log_error ("lookup_hashtable: read hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
+ if (rec->r.hlst.next)
+ {
+ rc = tdbio_read_record (rec->r.hlst.next, rec, RECTYPE_HLST);
+ if (rc)
+ {
+ log_error ("lookup_hashtable: read hlst failed: %s\n",
+ gpg_strerror (rc) );
+ return rc;
}
}
- else
- return -1; /* not found */
+ else
+ return gpg_error (GPG_ERR_NOT_FOUND);
}
}
+ if ((*cmpfnc)(cmpdata, rec))
+ return 0; /* really found */
- if( (*cmpfnc)( cmpdata, rec ) )
- return 0; /* really found */
-
- return -1; /* no: not found */
+ return gpg_error (GPG_ERR_NOT_FOUND); /* no: not found */
}
-/****************
- * Update the trust hashtbl or create the table if it does not exist
+/*
+ * Update the trust hash table TR or create the table if it does not
+ * exist.
+ *
+ * Return: 0 on success or an error code.
*/
static int
update_trusthashtbl( TRUSTREC *tr )
{
- return upd_hashtable( get_trusthashrec(),
- tr->r.trust.fingerprint, 20, tr->recnum );
+ return upd_hashtable (get_trusthashrec(),
+ tr->r.trust.fingerprint, 20, tr->recnum);
}
-
+/*
+ * Dump the trustdb record REC to stream FP.
+ */
void
tdbio_dump_record (TRUSTREC *rec, estream_t fp)
{
- int i;
- ulong rnum = rec->recnum;
+ int i;
+ ulong rnum = rec->recnum;
- es_fprintf ( fp, "rec %5lu, ", rnum );
+ es_fprintf (fp, "rec %5lu, ", rnum);
- switch( rec->rectype ) {
- case 0:
- es_fprintf (fp, "blank\n");
- break;
- case RECTYPE_VER:
- es_fprintf (fp,
+ switch (rec->rectype)
+ {
+ case 0:
+ es_fprintf (fp, "blank\n");
+ break;
+
+ case RECTYPE_VER:
+ es_fprintf (fp,
"version, td=%lu, f=%lu, m/c/d=%d/%d/%d tm=%d mcl=%d nc=%lu (%s)\n",
- rec->r.ver.trusthashtbl,
- rec->r.ver.firstfree,
- rec->r.ver.marginals,
- rec->r.ver.completes,
- rec->r.ver.cert_depth,
- rec->r.ver.trust_model,
- rec->r.ver.min_cert_level,
- rec->r.ver.nextcheck,
- strtimestamp(rec->r.ver.nextcheck)
- );
- break;
- case RECTYPE_FREE:
- es_fprintf (fp, "free, next=%lu\n", rec->r.free.next );
- break;
- case RECTYPE_HTBL:
- es_fprintf (fp, "htbl,");
- for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ )
- es_fprintf (fp, " %lu", rec->r.htbl.item[i] );
- es_putc ('\n', fp);
- break;
- case RECTYPE_HLST:
- es_fprintf (fp, "hlst, next=%lu,", rec->r.hlst.next );
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ )
- es_fprintf (fp, " %lu", rec->r.hlst.rnum[i] );
- es_putc ('\n', fp);
- break;
- case RECTYPE_TRUST:
- es_fprintf (fp, "trust ");
- for(i=0; i < 20; i++ )
- es_fprintf (fp, "%02X", rec->r.trust.fingerprint[i] );
- es_fprintf (fp, ", ot=%d, d=%d, vl=%lu\n", rec->r.trust.ownertrust,
- rec->r.trust.depth, rec->r.trust.validlist);
- break;
- case RECTYPE_VALID:
- es_fprintf (fp, "valid ");
- for(i=0; i < 20; i++ )
- es_fprintf(fp, "%02X", rec->r.valid.namehash[i] );
- es_fprintf (fp, ", v=%d, next=%lu\n", rec->r.valid.validity,
- rec->r.valid.next);
- break;
- default:
- es_fprintf (fp, "unknown type %d\n", rec->rectype );
- break;
+ rec->r.ver.trusthashtbl,
+ rec->r.ver.firstfree,
+ rec->r.ver.marginals,
+ rec->r.ver.completes,
+ rec->r.ver.cert_depth,
+ rec->r.ver.trust_model,
+ rec->r.ver.min_cert_level,
+ rec->r.ver.nextcheck,
+ strtimestamp(rec->r.ver.nextcheck)
+ );
+ break;
+
+ case RECTYPE_FREE:
+ es_fprintf (fp, "free, next=%lu\n", rec->r.free.next);
+ break;
+
+ case RECTYPE_HTBL:
+ es_fprintf (fp, "htbl,");
+ for (i=0; i < ITEMS_PER_HTBL_RECORD; i++)
+ es_fprintf (fp, " %lu", rec->r.htbl.item[i]);
+ es_putc ('\n', fp);
+ break;
+
+ case RECTYPE_HLST:
+ es_fprintf (fp, "hlst, next=%lu,", rec->r.hlst.next);
+ for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
+ es_fprintf (fp, " %lu", rec->r.hlst.rnum[i]);
+ es_putc ('\n', fp);
+ break;
+
+ case RECTYPE_TRUST:
+ es_fprintf (fp, "trust ");
+ for (i=0; i < 20; i++)
+ es_fprintf (fp, "%02X", rec->r.trust.fingerprint[i]);
+ es_fprintf (fp, ", ot=%d, d=%d, vl=%lu\n", rec->r.trust.ownertrust,
+ rec->r.trust.depth, rec->r.trust.validlist);
+ break;
+
+ case RECTYPE_VALID:
+ es_fprintf (fp, "valid ");
+ for (i=0; i < 20; i++)
+ es_fprintf(fp, "%02X", rec->r.valid.namehash[i]);
+ es_fprintf (fp, ", v=%d, next=%lu\n", rec->r.valid.validity,
+ rec->r.valid.next);
+ break;
+
+ default:
+ es_fprintf (fp, "unknown type %d\n", rec->rectype );
+ break;
}
}
-/****************
- * read the record with number recnum
- * returns: -1 on error, 0 on success
+
+/*
+ * Read the record with number RECNUM into the structure REC. If
+ * EXPECTED is not 0 reading any other record type will return an
+ * error.
+ *
+ * Return: 0 on success, -1 on EOF, or an error code.
*/
int
-tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
+tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected)
{
- byte readbuf[TRUST_RECORD_LEN];
- const byte *buf, *p;
- gpg_error_t err = 0;
- int n, i;
+ byte readbuf[TRUST_RECORD_LEN];
+ const byte *buf, *p;
+ gpg_error_t err = 0;
+ int n, i;
- if( db_fd == -1 )
- open_db();
- buf = get_record_from_cache( recnum );
- if( !buf ) {
- if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
- err = gpg_error_from_syserror ();
- log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) );
- return err;
+ if (db_fd == -1)
+ open_db ();
+
+ buf = get_record_from_cache( recnum );
+ if (!buf)
+ {
+ if (lseek (db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET) == -1)
+ {
+ err = gpg_error_from_syserror ();
+ log_error (_("trustdb: lseek failed: %s\n"), strerror (errno));
+ return err;
}
- n = read( db_fd, readbuf, TRUST_RECORD_LEN);
- if( !n ) {
- return -1; /* eof */
+ n = read (db_fd, readbuf, TRUST_RECORD_LEN);
+ if (!n)
+ {
+ return -1; /* eof */
}
- else if( n != TRUST_RECORD_LEN ) {
- err = gpg_error_from_syserror ();
- log_error(_("trustdb: read failed (n=%d): %s\n"), n,
- strerror(errno) );
- return err;
+ else if (n != TRUST_RECORD_LEN)
+ {
+ err = gpg_error_from_syserror ();
+ log_error (_("trustdb: read failed (n=%d): %s\n"),
+ n, strerror(errno));
+ return err;
}
- buf = readbuf;
+ buf = readbuf;
}
- rec->recnum = recnum;
- rec->dirty = 0;
- p = buf;
- rec->rectype = *p++;
- if( expected && rec->rectype != expected ) {
- log_error("%lu: read expected rec type %d, got %d\n",
- recnum, expected, rec->rectype );
- return gpg_error (GPG_ERR_TRUSTDB);
+ rec->recnum = recnum;
+ rec->dirty = 0;
+ p = buf;
+ rec->rectype = *p++;
+ if (expected && rec->rectype != expected)
+ {
+ log_error ("%lu: read expected rec type %d, got %d\n",
+ recnum, expected, rec->rectype);
+ return gpg_error (GPG_ERR_TRUSTDB);
}
- p++; /* skip reserved byte */
- switch( rec->rectype ) {
- case 0: /* unused (free) record */
- break;
- case RECTYPE_VER: /* version record */
- if( memcmp(buf+1, GPGEXT_GPG, 3 ) ) {
- log_error( _("%s: not a trustdb file\n"), db_name );
- err = gpg_error (GPG_ERR_TRUSTDB);
- }
- p += 2; /* skip "gpg" */
- rec->r.ver.version = *p++;
- rec->r.ver.marginals = *p++;
- rec->r.ver.completes = *p++;
- rec->r.ver.cert_depth = *p++;
- rec->r.ver.trust_model = *p++;
- rec->r.ver.min_cert_level = *p++;
- p += 2;
- rec->r.ver.created = buf32_to_ulong(p); p += 4;
- rec->r.ver.nextcheck = buf32_to_ulong(p); p += 4;
- p += 4;
- p += 4;
- rec->r.ver.firstfree =buf32_to_ulong(p); p += 4;
- p += 4;
- rec->r.ver.trusthashtbl =buf32_to_ulong(p); p += 4;
- if( recnum ) {
- log_error( _("%s: version record with recnum %lu\n"), db_name,
- (ulong)recnum );
- err = gpg_error (GPG_ERR_TRUSTDB);
- }
- else if( rec->r.ver.version != 3 ) {
- log_error( _("%s: invalid file version %d\n"), db_name,
- rec->r.ver.version );
- err = gpg_error (GPG_ERR_TRUSTDB);
- }
- break;
- case RECTYPE_FREE:
- rec->r.free.next = buf32_to_ulong(p); p += 4;
- break;
- case RECTYPE_HTBL:
- for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) {
- rec->r.htbl.item[i] = buf32_to_ulong(p); p += 4;
+ p++; /* Skip reserved byte. */
+ switch (rec->rectype)
+ {
+ case 0: /* unused (free) record */
+ break;
+
+ case RECTYPE_VER: /* version record */
+ if (memcmp(buf+1, GPGEXT_GPG, 3))
+ {
+ log_error (_("%s: not a trustdb file\n"), db_name );
+ err = gpg_error (GPG_ERR_TRUSTDB);
+ }
+ else
+ {
+ p += 2; /* skip "gpg" */
+ rec->r.ver.version = *p++;
+ rec->r.ver.marginals = *p++;
+ rec->r.ver.completes = *p++;
+ rec->r.ver.cert_depth = *p++;
+ rec->r.ver.trust_model = *p++;
+ rec->r.ver.min_cert_level = *p++;
+ p += 2;
+ rec->r.ver.created = buf32_to_ulong(p); p += 4;
+ rec->r.ver.nextcheck = buf32_to_ulong(p); p += 4;
+ p += 4;
+ p += 4;
+ rec->r.ver.firstfree =buf32_to_ulong(p); p += 4;
+ p += 4;
+ rec->r.ver.trusthashtbl =buf32_to_ulong(p); p += 4;
+ if (recnum)
+ {
+ log_error( _("%s: version record with recnum %lu\n"), db_name,
+ (ulong)recnum );
+ err = gpg_error (GPG_ERR_TRUSTDB);
+ }
+ else if (rec->r.ver.version != 3)
+ {
+ log_error( _("%s: invalid file version %d\n"), db_name,
+ rec->r.ver.version );
+ err = gpg_error (GPG_ERR_TRUSTDB);
+ }
+ }
+ break;
+
+ case RECTYPE_FREE:
+ rec->r.free.next = buf32_to_ulong(p); p += 4;
+ break;
+
+ case RECTYPE_HTBL:
+ for (i=0; i < ITEMS_PER_HTBL_RECORD; i++)
+ {
+ rec->r.htbl.item[i] = buf32_to_ulong(p); p += 4;
}
- break;
- case RECTYPE_HLST:
- rec->r.hlst.next = buf32_to_ulong(p); p += 4;
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- rec->r.hlst.rnum[i] = buf32_to_ulong(p); p += 4;
+ break;
+
+ case RECTYPE_HLST:
+ rec->r.hlst.next = buf32_to_ulong(p); p += 4;
+ for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
+ {
+ rec->r.hlst.rnum[i] = buf32_to_ulong(p); p += 4;
}
- break;
- case RECTYPE_TRUST:
- memcpy( rec->r.trust.fingerprint, p, 20); p+=20;
- rec->r.trust.ownertrust = *p++;
- rec->r.trust.depth = *p++;
- rec->r.trust.min_ownertrust = *p++;
- p++;
- rec->r.trust.validlist = buf32_to_ulong(p); p += 4;
- break;
- case RECTYPE_VALID:
- memcpy( rec->r.valid.namehash, p, 20); p+=20;
- rec->r.valid.validity = *p++;
- rec->r.valid.next = buf32_to_ulong(p); p += 4;
- rec->r.valid.full_count = *p++;
- rec->r.valid.marginal_count = *p++;
- break;
- default:
- log_error( "%s: invalid record type %d at recnum %lu\n",
- db_name, rec->rectype, (ulong)recnum );
- err = gpg_error (GPG_ERR_TRUSTDB);
- break;
+ break;
+
+ case RECTYPE_TRUST:
+ memcpy (rec->r.trust.fingerprint, p, 20); p+=20;
+ rec->r.trust.ownertrust = *p++;
+ rec->r.trust.depth = *p++;
+ rec->r.trust.min_ownertrust = *p++;
+ p++;
+ rec->r.trust.validlist = buf32_to_ulong(p); p += 4;
+ break;
+
+ case RECTYPE_VALID:
+ memcpy (rec->r.valid.namehash, p, 20); p+=20;
+ rec->r.valid.validity = *p++;
+ rec->r.valid.next = buf32_to_ulong(p); p += 4;
+ rec->r.valid.full_count = *p++;
+ rec->r.valid.marginal_count = *p++;
+ break;
+
+ default:
+ log_error ("%s: invalid record type %d at recnum %lu\n",
+ db_name, rec->rectype, (ulong)recnum);
+ err = gpg_error (GPG_ERR_TRUSTDB);
+ break;
}
- return err;
+ return err;
}
-/****************
- * Write the record at RECNUM
+
+/*
+ * Write the record from the struct REC.
+ *
+ * Return: 0 on success or an error code.
*/
int
tdbio_write_record( TRUSTREC *rec )
{
- byte buf[TRUST_RECORD_LEN], *p;
- int rc = 0;
- int i;
- ulong recnum = rec->recnum;
+ byte buf[TRUST_RECORD_LEN];
+ byte *p;
+ int rc = 0;
+ int i;
+ ulong recnum = rec->recnum;
- if( db_fd == -1 )
- open_db();
+ if (db_fd == -1)
+ open_db ();
- memset(buf, 0, TRUST_RECORD_LEN);
- p = buf;
- *p++ = rec->rectype; p++;
- switch( rec->rectype ) {
- case 0: /* unused record */
- break;
- case RECTYPE_VER: /* version record */
- if( recnum )
- BUG();
- memcpy(p-1, GPGEXT_GPG, 3 ); p += 2;
- *p++ = rec->r.ver.version;
- *p++ = rec->r.ver.marginals;
- *p++ = rec->r.ver.completes;
- *p++ = rec->r.ver.cert_depth;
- *p++ = rec->r.ver.trust_model;
- *p++ = rec->r.ver.min_cert_level;
- p += 2;
- ulongtobuf(p, rec->r.ver.created); p += 4;
- ulongtobuf(p, rec->r.ver.nextcheck); p += 4;
- p += 4;
- p += 4;
- ulongtobuf(p, rec->r.ver.firstfree ); p += 4;
- p += 4;
- ulongtobuf(p, rec->r.ver.trusthashtbl ); p += 4;
- break;
-
- case RECTYPE_FREE:
- ulongtobuf(p, rec->r.free.next); p += 4;
- break;
-
-
- case RECTYPE_HTBL:
- for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) {
- ulongtobuf( p, rec->r.htbl.item[i]); p += 4;
- }
- break;
+ memset (buf, 0, TRUST_RECORD_LEN);
+ p = buf;
+ *p++ = rec->rectype; p++;
- case RECTYPE_HLST:
- ulongtobuf( p, rec->r.hlst.next); p += 4;
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- ulongtobuf( p, rec->r.hlst.rnum[i]); p += 4;
+ switch (rec->rectype)
+ {
+ case 0: /* unused record */
+ break;
+
+ case RECTYPE_VER: /* version record */
+ if (recnum)
+ BUG ();
+ memcpy(p-1, GPGEXT_GPG, 3 ); p += 2;
+ *p++ = rec->r.ver.version;
+ *p++ = rec->r.ver.marginals;
+ *p++ = rec->r.ver.completes;
+ *p++ = rec->r.ver.cert_depth;
+ *p++ = rec->r.ver.trust_model;
+ *p++ = rec->r.ver.min_cert_level;
+ p += 2;
+ ulongtobuf(p, rec->r.ver.created); p += 4;
+ ulongtobuf(p, rec->r.ver.nextcheck); p += 4;
+ p += 4;
+ p += 4;
+ ulongtobuf(p, rec->r.ver.firstfree ); p += 4;
+ p += 4;
+ ulongtobuf(p, rec->r.ver.trusthashtbl ); p += 4;
+ break;
+
+ case RECTYPE_FREE:
+ ulongtobuf(p, rec->r.free.next); p += 4;
+ break;
+
+ case RECTYPE_HTBL:
+ for (i=0; i < ITEMS_PER_HTBL_RECORD; i++)
+ {
+ ulongtobuf( p, rec->r.htbl.item[i]); p += 4;
+ }
+ break;
+
+ case RECTYPE_HLST:
+ ulongtobuf( p, rec->r.hlst.next); p += 4;
+ for (i=0; i < ITEMS_PER_HLST_RECORD; i++ )
+ {
+ ulongtobuf( p, rec->r.hlst.rnum[i]); p += 4;
}
- break;
-
- case RECTYPE_TRUST:
- memcpy( p, rec->r.trust.fingerprint, 20); p += 20;
- *p++ = rec->r.trust.ownertrust;
- *p++ = rec->r.trust.depth;
- *p++ = rec->r.trust.min_ownertrust;
- p++;
- ulongtobuf( p, rec->r.trust.validlist); p += 4;
- break;
-
- case RECTYPE_VALID:
- memcpy( p, rec->r.valid.namehash, 20); p += 20;
- *p++ = rec->r.valid.validity;
- ulongtobuf( p, rec->r.valid.next); p += 4;
- *p++ = rec->r.valid.full_count;
- *p++ = rec->r.valid.marginal_count;
- break;
-
- default:
- BUG();
+ break;
+
+ case RECTYPE_TRUST:
+ memcpy (p, rec->r.trust.fingerprint, 20); p += 20;
+ *p++ = rec->r.trust.ownertrust;
+ *p++ = rec->r.trust.depth;
+ *p++ = rec->r.trust.min_ownertrust;
+ p++;
+ ulongtobuf( p, rec->r.trust.validlist); p += 4;
+ break;
+
+ case RECTYPE_VALID:
+ memcpy (p, rec->r.valid.namehash, 20); p += 20;
+ *p++ = rec->r.valid.validity;
+ ulongtobuf( p, rec->r.valid.next); p += 4;
+ *p++ = rec->r.valid.full_count;
+ *p++ = rec->r.valid.marginal_count;
+ break;
+
+ default:
+ BUG();
}
- rc = put_record_into_cache( recnum, buf );
- if( rc )
- ;
- else if( rec->rectype == RECTYPE_TRUST )
- rc = update_trusthashtbl( rec );
+ rc = put_record_into_cache (recnum, buf);
+ if (rc)
+ ;
+ else if (rec->rectype == RECTYPE_TRUST)
+ rc = update_trusthashtbl (rec);
- return rc;
+ return rc;
}
+
+/*
+ * Delete the record at record number RECNUm from the trustdb.
+ *
+ * Return: 0 on success or an error code.
+ */
int
-tdbio_delete_record( ulong recnum )
+tdbio_delete_record (ulong recnum)
{
- TRUSTREC vr, rec;
- int rc;
-
- /* Must read the record fist, so we can drop it from the hash tables */
- rc = tdbio_read_record( recnum, &rec, 0 );
- if( rc )
- ;
- else if( rec.rectype == RECTYPE_TRUST ) {
- rc = drop_from_hashtable( get_trusthashrec(),
- rec.r.trust.fingerprint, 20, rec.recnum );
- }
+ TRUSTREC vr, rec;
+ int rc;
- if( rc )
- return rc;
+ /* Must read the record fist, so we can drop it from the hash tables */
+ rc = tdbio_read_record (recnum, &rec, 0);
+ if (rc)
+ ;
+ else if (rec.rectype == RECTYPE_TRUST)
+ {
+ rc = drop_from_hashtable (get_trusthashrec(),
+ rec.r.trust.fingerprint, 20, rec.recnum);
+ }
- /* now we can chnage it to a free record */
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
-
- rec.recnum = recnum;
- rec.rectype = RECTYPE_FREE;
- rec.r.free.next = vr.r.ver.firstfree;
- vr.r.ver.firstfree = recnum;
- rc = tdbio_write_record( &rec );
- if( !rc )
- rc = tdbio_write_record( &vr );
+ if (rc)
return rc;
+
+ /* Now we can chnage it to a free record. */
+ rc = tdbio_read_record (0, &vr, RECTYPE_VER);
+ if (rc)
+ log_fatal (_("%s: error reading version record: %s\n"),
+ db_name, gpg_strerror (rc));
+
+ rec.recnum = recnum;
+ rec.rectype = RECTYPE_FREE;
+ rec.r.free.next = vr.r.ver.firstfree;
+ vr.r.ver.firstfree = recnum;
+ rc = tdbio_write_record (&rec);
+ if (!rc)
+ rc = tdbio_write_record (&vr);
+
+ return rc;
}
-/****************
- * create a new record and return its record number
+
+/*
+ * Create a new record and return its record number.
*/
ulong
-tdbio_new_recnum()
+tdbio_new_recnum ()
{
- off_t offset;
- ulong recnum;
- TRUSTREC vr, rec;
- int rc;
-
- /* look for unused records */
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
- if( vr.r.ver.firstfree ) {
- recnum = vr.r.ver.firstfree;
- rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE );
- if( rc ) {
- log_error( _("%s: error reading free record: %s\n"),
- db_name, gpg_strerror (rc) );
- return rc;
+ off_t offset;
+ ulong recnum;
+ TRUSTREC vr, rec;
+ int rc;
+
+ /* Look for unused records. */
+ rc = tdbio_read_record (0, &vr, RECTYPE_VER);
+ if (rc)
+ log_fatal( _("%s: error reading version record: %s\n"),
+ db_name, gpg_strerror (rc));
+ if (vr.r.ver.firstfree)
+ {
+ recnum = vr.r.ver.firstfree;
+ rc = tdbio_read_record (recnum, &rec, RECTYPE_FREE);
+ if (rc)
+ {
+ log_error (_("%s: error reading free record: %s\n"),
+ db_name, gpg_strerror (rc));
+ return rc;
}
- /* update dir record */
- vr.r.ver.firstfree = rec.r.free.next;
- rc = tdbio_write_record( &vr );
- if( rc ) {
- log_error (_("%s: error writing dir record: %s\n"),
- db_name, gpg_strerror (rc));
- return rc;
+ /* Update dir record. */
+ vr.r.ver.firstfree = rec.r.free.next;
+ rc = tdbio_write_record (&vr);
+ if (rc)
+ {
+ log_error (_("%s: error writing dir record: %s\n"),
+ db_name, gpg_strerror (rc));
+ return rc;
}
- /*zero out the new record */
- memset( &rec, 0, sizeof rec );
- rec.rectype = 0; /* unused record */
- rec.recnum = recnum;
- rc = tdbio_write_record( &rec );
- if( rc )
- log_fatal(_("%s: failed to zero a record: %s\n"),
- db_name, gpg_strerror (rc));
+ /* Zero out the new record. */
+ memset (&rec, 0, sizeof rec);
+ rec.rectype = 0; /* Mark as unused record (actually already done
+ my the memset). */
+ rec.recnum = recnum;
+ rc = tdbio_write_record (&rec);
+ if (rc)
+ log_fatal (_("%s: failed to zero a record: %s\n"),
+ db_name, gpg_strerror (rc));
}
- else { /* not found, append a new record */
- offset = lseek( db_fd, 0, SEEK_END );
- if( offset == -1 )
- log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) );
- recnum = offset / TRUST_RECORD_LEN;
- assert(recnum); /* this is will never be the first record */
- /* we must write a record, so that the next call to this function
- * returns another recnum */
- memset( &rec, 0, sizeof rec );
- rec.rectype = 0; /* unused record */
- rec.recnum = recnum;
- rc = 0;
- if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
- rc = gpg_error_from_syserror ();
- log_error(_("trustdb rec %lu: lseek failed: %s\n"),
- recnum, strerror(errno) );
+ else /* Not found - append a new record. */
+ {
+ offset = lseek (db_fd, 0, SEEK_END);
+ if (offset == (off_t)(-1))
+ log_fatal ("trustdb: lseek to end failed: %s\n", strerror (errno));
+ recnum = offset / TRUST_RECORD_LEN;
+ assert (recnum); /* this is will never be the first record */
+ /* We must write a record, so that the next call to this
+ * function returns another recnum. */
+ memset (&rec, 0, sizeof rec);
+ rec.rectype = 0; /* unused record */
+ rec.recnum = recnum;
+ rc = 0;
+ if (lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET) == -1)
+ {
+ rc = gpg_error_from_syserror ();
+ log_error (_("trustdb rec %lu: lseek failed: %s\n"),
+ recnum, strerror (errno));
}
- else {
- int n = write( db_fd, &rec, TRUST_RECORD_LEN);
- if( n != TRUST_RECORD_LEN ) {
- rc = gpg_error_from_syserror ();
- log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
- recnum, n, strerror(errno) );
+ else
+ {
+ int n;
+
+ n = write (db_fd, &rec, TRUST_RECORD_LEN);
+ if (n != TRUST_RECORD_LEN)
+ {
+ rc = gpg_error_from_syserror ();
+ log_error (_("trustdb rec %lu: write failed (n=%d): %s\n"),
+ recnum, n, strerror (errno));
}
}
- if( rc )
- log_fatal(_("%s: failed to append a record: %s\n"),
- db_name, gpg_strerror (rc));
+ if (rc)
+ log_fatal (_("%s: failed to append a record: %s\n"),
+ db_name, gpg_strerror (rc));
}
- return recnum ;
+
+ return recnum ;
}
+/* Helper function for tdbio_search_trust_byfpr. */
static int
cmp_trec_fpr ( const void *fpr, const TRUSTREC *rec )
{
}
-int
-tdbio_search_trust_byfpr( const byte *fingerprint, TRUSTREC *rec )
+/*
+ * Given a 20 byte FINGERPRINT search its trust record and return
+ * that at REC.
+ *
+ * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
+ */
+gpg_error_t
+tdbio_search_trust_byfpr (const byte *fingerprint, TRUSTREC *rec)
{
- int rc;
+ int rc;
- /* locate the trust record using the hash table */
- rc = lookup_hashtable( get_trusthashrec(), fingerprint, 20,
- cmp_trec_fpr, fingerprint, rec );
- return rc;
+ /* Locate the trust record using the hash table */
+ rc = lookup_hashtable (get_trusthashrec(), fingerprint, 20,
+ cmp_trec_fpr, fingerprint, rec );
+ return rc;
}
-int
+
+/*
+ * Given a primary public key object PK search its trust record and
+ * return that at REC.
+ *
+ * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
+ */
+gpg_error_t
tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec)
{
- byte fingerprint[MAX_FINGERPRINT_LEN];
- size_t fingerlen;
+ byte fingerprint[MAX_FINGERPRINT_LEN];
+ size_t fingerlen;
- fingerprint_from_pk( pk, fingerprint, &fingerlen );
- for (; fingerlen < 20; fingerlen++ )
- fingerprint[fingerlen] = 0;
- return tdbio_search_trust_byfpr (fingerprint, rec);
+ fingerprint_from_pk( pk, fingerprint, &fingerlen );
+ for (; fingerlen < 20; fingerlen++)
+ fingerprint[fingerlen] = 0;
+ return tdbio_search_trust_byfpr (fingerprint, rec);
}
+/*
+ * Terminate the process with a message about a corrupted trustdb.
+ */
void
-tdbio_invalid(void)
+tdbio_invalid (void)
{
log_error (_("Error: The trustdb is corrupted.\n"));
how_to_fix_the_trustdb ();
int tdbio_cancel_transaction(void);
int tdbio_delete_record( ulong recnum );
ulong tdbio_new_recnum(void);
-int tdbio_search_trust_byfpr(const byte *fingerprint, TRUSTREC *rec );
-int tdbio_search_trust_bypk(PKT_public_key *pk, TRUSTREC *rec );
+gpg_error_t tdbio_search_trust_byfpr (const byte *fingerprint, TRUSTREC *rec);
+gpg_error_t tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec);
void tdbio_how_to_fix (void);
void tdbio_invalid(void);
init_trustdb();
rc = tdbio_search_trust_bypk (pk, rec);
- if (rc == -1)
- return -1; /* no record yet */
if (rc)
{
- log_error ("trustdb: searching trust record failed: %s\n",
- gpg_strerror (rc));
+ if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
+ log_error ("trustdb: searching trust record failed: %s\n",
+ gpg_strerror (rc));
return rc;
}
tdb_get_ownertrust ( PKT_public_key *pk)
{
TRUSTREC rec;
- int rc;
+ gpg_error_t err;
if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS)
return TRUST_UNKNOWN;
- rc = read_trust_record (pk, &rec);
- if (rc == -1)
+ err = read_trust_record (pk, &rec);
+ if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
return TRUST_UNKNOWN; /* no record yet */
- if (rc)
+ if (err)
{
tdbio_invalid ();
- return rc; /* actually never reached */
+ return TRUST_UNKNOWN; /* actually never reached */
}
return rec.r.trust.ownertrust;
tdb_get_min_ownertrust (PKT_public_key *pk)
{
TRUSTREC rec;
- int rc;
+ gpg_error_t err;
if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS)
return TRUST_UNKNOWN;
- rc = read_trust_record (pk, &rec);
- if (rc == -1)
+ err = read_trust_record (pk, &rec);
+ if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
return TRUST_UNKNOWN; /* no record yet */
- if (rc)
+ if (err)
{
tdbio_invalid ();
- return rc; /* actually never reached */
+ return TRUST_UNKNOWN; /* actually never reached */
}
return rec.r.trust.min_ownertrust;
tdb_update_ownertrust (PKT_public_key *pk, unsigned int new_trust )
{
TRUSTREC rec;
- int rc;
+ gpg_error_t err;
if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS)
return;
- rc = read_trust_record (pk, &rec);
- if (!rc)
+ err = read_trust_record (pk, &rec);
+ if (!err)
{
if (DBG_TRUST)
log_debug ("update ownertrust from %u to %u\n",
do_sync ();
}
}
- else if (rc == -1)
+ else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
{ /* no record yet - create a new one */
size_t dummy;
write_record (&rec);
tdb_revalidation_mark ();
do_sync ();
- rc = 0;
+ err = 0;
}
else
{
{
PKT_public_key *pk;
TRUSTREC rec;
- int rc;
+ gpg_error_t err;
if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS)
return;
pk = xmalloc_clear (sizeof *pk);
- rc = get_pubkey (pk, kid);
- if (rc)
+ err = get_pubkey (pk, kid);
+ if (err)
{
- log_error(_("public key %s not found: %s\n"),keystr(kid),gpg_strerror (rc));
+ log_error (_("public key %s not found: %s\n"),
+ keystr (kid), gpg_strerror (err));
return;
}
- rc = read_trust_record (pk, &rec);
- if (!rc)
+ err = read_trust_record (pk, &rec);
+ if (!err)
{
if (DBG_TRUST)
log_debug ("key %08lX%08lX: update min_ownertrust from %u to %u\n",
do_sync ();
}
}
- else if (rc == -1)
+ else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
{ /* no record yet - create a new one */
size_t dummy;
write_record (&rec);
tdb_revalidation_mark ();
do_sync ();
- rc = 0;
+ err = 0;
}
else
{
}
-/* Clear the ownertrust and min_ownertrust values. Return true if a
- change actually happened. */
+/*
+ * Clear the ownertrust and min_ownertrust values.
+ *
+ * Return: True if a change actually happened.
+ */
int
tdb_clear_ownertrusts (PKT_public_key *pk)
{
TRUSTREC rec;
- int rc;
+ gpg_error_t err;
init_trustdb ();
if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS)
return 0;
- rc = read_trust_record (pk, &rec);
- if (!rc)
+ err = read_trust_record (pk, &rec);
+ if (!err)
{
if (DBG_TRUST)
{
return 1;
}
}
- else if (rc != -1)
+ else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
{
tdbio_invalid ();
}
int depth, int validity)
{
TRUSTREC trec, vrec;
- int rc;
+ gpg_error_t err;
ulong recno;
namehash_from_uid(uid);
- rc = read_trust_record (pk, &trec);
- if (rc && rc != -1)
+ err = read_trust_record (pk, &trec);
+ if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
{
tdbio_invalid ();
return;
}
- if (rc == -1) /* no record yet - create a new one */
+ if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
{
+ /* No record yet - create a new one. */
size_t dummy;
- rc = 0;
+ err = 0;
memset (&trec, 0, sizeof trec);
trec.recnum = tdbio_new_recnum ();
trec.rectype = RECTYPE_TRUST;
int
tdb_cache_disabled_value (PKT_public_key *pk)
{
- int rc;
+ gpg_error_t err;
TRUSTREC trec;
int disabled = 0;
if (trustdb_args.no_trustdb)
return 0; /* No trustdb => not disabled. */
- rc = read_trust_record (pk, &trec);
- if (rc && rc != -1)
+ err = read_trust_record (pk, &trec);
+ if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
{
tdbio_invalid ();
goto leave;
}
- if (rc == -1) /* no record found, so assume not disabled */
- goto leave;
+ if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
+ {
+ /* No record found, so assume not disabled. */
+ goto leave;
+ }
- if (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED)
+ if ((trec.r.trust.ownertrust & TRUST_FLAG_DISABLED))
disabled = 1;
/* Cache it for later so we don't need to look at the trustdb every
pk->flags.disabled_valid = 1;
leave:
- return disabled;
+ return disabled;
}
PKT_public_key *main_pk)
{
TRUSTREC trec, vrec;
- int rc;
+ gpg_error_t err;
ulong recno;
unsigned int validity;
goto leave;
}
- rc = read_trust_record (main_pk, &trec);
- if (rc && rc != -1)
+ err = read_trust_record (main_pk, &trec);
+ if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
{
tdbio_invalid ();
return 0;
}
- if (rc == -1) /* no record found */
+ if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
{
+ /* No record found. */
validity = TRUST_UNKNOWN;
goto leave;
}
- /* loop over all user IDs */
+ /* Loop over all user IDs */
recno = trec.r.trust.validlist;
validity = 0;
while (recno)
init_trustdb ();
- if(read_trust_record (pk, &trec)!=0)
+ if(read_trust_record (pk, &trec))
return;
/* loop over all user IDs */
int tdb_clear_ownertrusts (PKT_public_key *pk);
/*-- tdbdump.c --*/
-void list_trustdb(const char *username);
+void list_trustdb (estream_t fp, const char *username);
void export_ownertrust(void);
void import_ownertrust(const char *fname);
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
# Gènere? Nombre? ivb
# Werner FIXME: please add translator comment saying *what* is
# uncompressed so we know the gender. jm
msgid "trustdb: sync failed: %s\n"
msgstr "base de dades de confiança: no s'ha pogut sincronitzar: %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "no es pot crear el directori «%s»: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "no s'ha pogut obrir «%s»\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "reg de la base de dades de confiança %lu: ha fallat lseek: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: el directori no existeix!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "no es pot crear el directori «%s»: %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "no s'ha pogut obrir «%s»\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: no s'ha pogut crear un registre de versió: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
msgid "enable ssh support"
msgstr "zapnout podporu pro OpenSSH"
msgstr "databáze důvěry: synchronizace selhala %s\n"
#, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "pro „%s“ nelze vytvořit zámek\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "„%s“ nelze zamknout\n"
+
+#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "záznam v databázi důvěry %lu: lseek() se nepodařil: %s\n"
msgstr "%s: adresář neexistuje!\n"
#, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "pro „%s“ nelze vytvořit zámek\n"
-
-#, c-format
-msgid "can't lock '%s'\n"
-msgstr "„%s“ nelze zamknout\n"
-
-#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: nepodařilo se vytvořit záznam verze: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "enable ssh-agent emulation"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "trustdb: synkronisering mislykkedes: %s\n"
+#, fuzzy, c-format
+#| msgid "can't create lock for `%s'\n"
+msgid "can't create lock for '%s'\n"
+msgstr "kan ikke oprette lås for »%s«\n"
+
+#, fuzzy, c-format
+#| msgid "can't lock `%s'\n"
+msgid "can't lock '%s'\n"
+msgstr "kan ikke låse »%s«\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "trustdb rec %lu: lseek mislykkedes: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: mappe findes ikke!\n"
-#, fuzzy, c-format
-#| msgid "can't create lock for `%s'\n"
-msgid "can't create lock for '%s'\n"
-msgstr "kan ikke oprette lås for »%s«\n"
-
-#, fuzzy, c-format
-#| msgid "can't lock `%s'\n"
-msgid "can't lock '%s'\n"
-msgstr "kan ikke låse »%s«\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: kunne ikke oprette versionspost: %s"
msgstr ""
"Project-Id-Version: gnupg-2.1.0\n"
"Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2015-05-12 13:19+0200\n"
+"PO-Revision-Date: 2015-06-11 13:03+0200\n"
"Last-Translator: Werner Koch <wk@gnupg.org>\n"
"Language-Team: German <de@li.org>\n"
"Language: de\n"
msgid "allow caller to override the pinentry"
msgstr "Aufrufer darf das Pinentry ersetzen"
+msgid "allow passphrase to be prompted through Emacs"
+msgstr "Erlaube die Eingabe einer Passphrase über Emacs"
+
msgid "enable ssh support"
msgstr "SSH Unterstützung einschalten"
msgstr "\"Trust-DB\": sync fehlgeschlagen: %s\n"
#, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "Datei `%s' konnte nicht gesperrt werden\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "'%s' kann nicht gesperrt werden\n"
+
+#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "trustdb Satz %lu: lseek fehlgeschlagen: %s\n"
msgstr "%s: Verzeichnis existiert nicht!\n"
#, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "Datei `%s' konnte nicht gesperrt werden\n"
-
-#, c-format
-msgid "can't lock '%s'\n"
-msgstr "'%s' kann nicht gesperrt werden\n"
-
-#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: Fehler beim Erzeugen des Versionsatzes: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "trustdb: sync áðÝôõ÷å: %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "áäõíáìßá äçìéïõñãßáò ôïõ `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "áäõíáìßá ðñüóâáóçò ôïõ `%s'\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "trustdb rec %lu: áðïôõ÷ßá lseek: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: ï öÜêåëïò äåí õðÜñ÷åé!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "áäõíáìßá äçìéïõñãßáò ôïõ `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "áäõíáìßá ðñüóâáóçò ôïõ `%s'\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: áðïôõ÷ßá äçìéïõñãßáò ìéáò åããñáöÞò Ýêäïóçò: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "fido-datenaro: sync malsukcesis: %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "ne povas krei '%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "ne povas malfermi '%s'\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "fido-datenaro loko %lu: lseek malsukcesis: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: dosierujo ne ekzistas!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "ne povas krei '%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "ne povas malfermi '%s'\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: malsukcesis krei versiregistron: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "enable ssh-agent emulation"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "base de datos de confianza: fallo sincronización: %s\n"
+#, fuzzy, c-format
+#| msgid "can't create lock for `%s'\n"
+msgid "can't create lock for '%s'\n"
+msgstr "no se puede crear el bloqueo para `%s'\n"
+
+#, fuzzy, c-format
+#| msgid "can't lock `%s'\n"
+msgid "can't lock '%s'\n"
+msgstr "no se puede bloquear `%s'\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "registro base de datos de confianza %lu: lseek fallido: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: ¡el directorio no existe!\n"
-#, fuzzy, c-format
-#| msgid "can't create lock for `%s'\n"
-msgid "can't create lock for '%s'\n"
-msgstr "no se puede crear el bloqueo para `%s'\n"
-
-#, fuzzy, c-format
-#| msgid "can't lock `%s'\n"
-msgid "can't lock '%s'\n"
-msgstr "no se puede bloquear `%s'\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: fallo en la creación del registro de versión: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "trustdb: sync ebaõnnestus: %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "`%s' ei õnnestu luua: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "`%s' ei õnnestu avada\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "trustdb kirje %lu: lseek ebaõnnestus: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: kataloogi ei ole!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "`%s' ei õnnestu luua: %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "`%s' ei õnnestu avada\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: versioonikirje loomine ei õnnestu: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "trustdb: synkronointi epäonnistui: %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "tiedostoa \"%s\" ei voi luoda: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "tiedostoa \"%s\" ei voi avata\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "trustdb rec %lu: lseek epäonnistui: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: hakemistoa ei ole olemassa!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "tiedostoa \"%s\" ei voi luoda: %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "tiedostoa \"%s\" ei voi avata\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: versiotietueen luonti epäonnistui: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
msgid "enable ssh support"
msgstr "activer la prise en charge de SSH"
msgstr "base de confiance : échec de synchronisation : %s\n"
#, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "impossible de créer un verrou pour « %s »\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "impossible de verrouiller « %s »\n"
+
+#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "enregistrement de base de confiance %lu : échec de lseek : %s\n"
msgstr "%s : le répertoire n'existe pas.\n"
#, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "impossible de créer un verrou pour « %s »\n"
-
-#, c-format
-msgid "can't lock '%s'\n"
-msgstr "impossible de verrouiller « %s »\n"
-
-#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s : impossible de créer un enregistrement de version : %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "base de datos de confianza: fallou a sincronización: %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "non se pode crear `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "non se puido abrir `%s'\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "rexistro da base de datos de confianza %lu: lseek fallou: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: ¡o directorio non existe!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "non se pode crear `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "non se puido abrir `%s'\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: non se puido crea-lo rexistro de versión: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "Bizalmi adatbázis: szinkronizáció sikertelen: %s.\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "Nem tudom létrehozni a(z) \"%s\" állományt: %s.\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "Nem tudom megnyitni %s-t!\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "Bizalmi adatbázis %lu. rekord: lseek sikertelen: %s.\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: Könyvtár nem létezik!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "Nem tudom létrehozni a(z) \"%s\" állományt: %s.\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "Nem tudom megnyitni %s-t!\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: Nem sikerült verziórekordot létrehoznom: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "trustdb: gagal sync: %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "tidak dapat membuat %s: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "tidak dapat membuka `%s'\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "trustdb rec %lu: lseek gagal: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: direktori tidak ada!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "tidak dapat membuat %s: %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "tidak dapat membuka `%s'\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: gagal membuat catatan versi: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "trustdb: sync fallita: %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "impossibile creare `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "impossibile aprire `%s'\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "trustdb rec %lu: lseek fallita: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: la directory non esiste!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "impossibile creare `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "impossibile aprire `%s'\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: creazione del record della versione fallita: %s"
msgid "allow caller to override the pinentry"
msgstr "pinentryより優先してパスフレーズ入力を認める"
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
msgid "enable ssh support"
msgstr "sshサポートを有功にする"
msgstr "信用データベース: 同期に失敗しました: %s\n"
#, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "'%s'のロックを作成できません\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "'%s'がロックできません\n"
+
+#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "信用データベース レコード%lu: シークに失敗しました: %s\n"
msgstr "%s: ディレクトリがありません!\n"
#, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "'%s'のロックを作成できません\n"
-
-#, c-format
-msgid "can't lock '%s'\n"
-msgstr "'%s'がロックできません\n"
-
-#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: バージョン・レコードの作成に失敗しました: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
msgid "enable ssh support"
msgstr ""
msgid "trustdb: sync failed: %s\n"
msgstr ""
+#, fuzzy, c-format
+#| msgid "can't create lock for `%s'\n"
+msgid "can't create lock for '%s'\n"
+msgstr "kan ikke opprette lås for «%s»\n"
+
+#, fuzzy, c-format
+#| msgid "can't lock `%s'\n"
+msgid "can't lock '%s'\n"
+msgstr "kan ikke låse «%s»\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr ""
msgid "%s: directory does not exist!\n"
msgstr ""
-#, fuzzy, c-format
-#| msgid "can't create lock for `%s'\n"
-msgid "can't create lock for '%s'\n"
-msgstr "kan ikke opprette lås for «%s»\n"
-
-#, fuzzy, c-format
-#| msgid "can't lock `%s'\n"
-msgid "can't lock '%s'\n"
-msgstr "kan ikke låse «%s»\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr ""
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
msgid "enable ssh support"
msgstr ""
msgid "trustdb: sync failed: %s\n"
msgstr "baza zaufania: synchronizacja nie powiod³a siê %s\n"
+#, fuzzy, c-format
+#| msgid "can't create lock for `%s'\n"
+msgid "can't create lock for '%s'\n"
+msgstr "nie mo¿na utworzyæ blokady dla ,,%s''\n"
+
+#, fuzzy, c-format
+#| msgid "can't lock `%s'\n"
+msgid "can't lock '%s'\n"
+msgstr "nie mo¿na zablokowaæ ,,%s''\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "baza zaufania, wpis %lu: funkcja lseek() nie powiod³a siê: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: katalog nie istnieje!\n"
-#, fuzzy, c-format
-#| msgid "can't create lock for `%s'\n"
-msgid "can't create lock for '%s'\n"
-msgstr "nie mo¿na utworzyæ blokady dla ,,%s''\n"
-
-#, fuzzy, c-format
-#| msgid "can't lock `%s'\n"
-msgid "can't lock '%s'\n"
-msgstr "nie mo¿na zablokowaæ ,,%s''\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: stworzenie zapisu o wersji nie powiod³o siê: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "base de dados de confiança: sincronização falhou: %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "impossível criar `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "impossível abrir `%s'\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "base de dados de confiança rec %lu: lseek falhou: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: diretoria inexistente!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "impossível criar `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "impossível abrir `%s'\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: falha ao criar registo de versão: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "trustdb: sincronizarea a eºuat: %s\n"
+#, fuzzy, c-format
+#| msgid "can't create lock for `%s'\n"
+msgid "can't create lock for '%s'\n"
+msgstr "nu pot crea încuietoare (lock) pentru `%s'\n"
+
+#, fuzzy, c-format
+#| msgid "can't lock `%s'\n"
+msgid "can't lock '%s'\n"
+msgstr "nu pot încuia (lock) `%s'\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "trustdb rec %lu: lseek a eºuat: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: directorul nu existã!\n"
-#, fuzzy, c-format
-#| msgid "can't create lock for `%s'\n"
-msgid "can't create lock for '%s'\n"
-msgstr "nu pot crea încuietoare (lock) pentru `%s'\n"
-
-#, fuzzy, c-format
-#| msgid "can't lock `%s'\n"
-msgid "can't lock '%s'\n"
-msgstr "nu pot încuia (lock) `%s'\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: am eºuat sã creez înregistrare versiune: %s"
msgstr ""
"Project-Id-Version: GnuPG 2.1.0\n"
"Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2015-02-12 17:17+0000\n"
+"PO-Revision-Date: 2015-05-23 17:17+0000\n"
"Last-Translator: Ineiev <ineiev@gnu.org>\n"
"Language-Team: Russian <gnupg-ru@gnupg.org>\n"
"Language: ru\n"
msgid "|pinentry-label|_Cancel"
msgstr "|pinentry-label|Отмена (_C)"
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
msgid "|pinentry-label|_Yes"
-msgstr "|pinentry-label|_OK"
+msgstr "|pinentry-label|Да (_Y)"
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
msgid "|pinentry-label|_No"
-msgstr "|pinentry-label|_OK"
+msgstr "|pinentry-label|Нет (_N)"
msgid "|pinentry-label|PIN:"
msgstr "|pinentry-label|PIN:"
-#, fuzzy
-#| msgid "|pinentry-label|_Cancel"
msgid "|pinentry-label|_Save in password manager"
-msgstr "|pinentry-label|Ð\9eÑ\82мена (_C)"
+msgstr "|pinentry-label|СоÑ\85Ñ\80аниÑ\82Ñ\8c в диÑ\81пеÑ\82Ñ\87еÑ\80е паÑ\80олей (_S)"
-#, fuzzy
-#| msgid "Do you really want to permanently delete the OpenPGP secret key:"
msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Вы действительно хотите навсегда удалить закрытый ключ OpenPGP:"
+msgstr "Вы действительно хотите, чтобы фраза-пароль была видна на экране?"
msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
+msgstr "|pinentry-tt|Показывать фразу-пароль"
-#, fuzzy
-#| msgid "Enter new passphrase"
msgid "|pinentry-tt|Hide passphrase"
-msgstr "Введите новую фразу-пароль"
+msgstr "pinentry-tt|Скрывать фразу-пароль"
#. TRANSLATORS: This string is displayed by Pinentry as the label
#. for the quality bar.
msgid "do not use the SCdaemon"
msgstr "не использовать демон криптографических карт"
-#, fuzzy
-#| msgid "|NAME|connect to host NAME"
msgid "|NAME|accept some commands via NAME"
-msgstr "|NAME|подключиться к хосту NAME"
+msgstr "|NAME|принимать некоторые команды по NAME"
msgid "ignore requests to change the TTY"
msgstr "игнорировать запросы смены терминала"
msgid "do not use the PIN cache when signing"
msgstr "не использовать запомненный PIN при подписывании"
-#, fuzzy
-#| msgid "do not allow the reuse of old passphrases"
msgid "disallow the use of an external password cache"
-msgstr "не разрешать повторное использование старых фраз-паролей"
+msgstr "не позволять пользоваться внешней памятью паролей"
msgid "disallow clients to mark keys as \"trusted\""
msgstr "не позволять клиентам помечать ключи как \"доверенные\""
msgid "allow caller to override the pinentry"
msgstr "разрешить клиентам замещать собой pinentry"
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
msgid "enable ssh support"
msgstr "включить поддержку ssh"
msgid "quickly generate a new key pair"
msgstr "быстро создать новую пару ключей"
-#, fuzzy
-#| msgid "quickly generate a new key pair"
msgid "quickly add a new user-id"
-msgstr "быстро создать новую пару ключей"
+msgstr "быстро добавить новый ID пользователя"
msgid "full featured key pair generation"
msgstr "создание полноценной пары ключей"
msgstr "%s: таблица ключей создана\n"
msgid "override proxy options set for dirmngr"
-msgstr ""
+msgstr "переназначить настройки промежуточного сервера для dirmngr"
msgid "include revoked keys in search results"
msgstr "включить в результаты поиска отозванные ключи"
msgstr "искать по ID ключа, включая подключи"
msgid "override timeout options set for dirmngr"
-msgstr ""
+msgstr "переназначить настройки времени ожидания для dirmngr"
msgid "automatically retrieve keys when verifying signatures"
msgstr "автоматически получать ключи при проверке подписей"
msgstr "таблица доверия: сбой синхронизации: %s\n"
#, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "невозможно создать блокировку для '%s'\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "невозможно заблокировать '%s'\n"
+
+#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "таблица доверия, запись %lu: сбой lseek: %s\n"
msgstr "%s: каталог не существует!\n"
#, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "невозможно создать блокировку для '%s'\n"
-
-#, c-format
-msgid "can't lock '%s'\n"
-msgstr "невозможно заблокировать '%s'\n"
-
-#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: сбой создания записи о версии: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "databáza dôvery: synchronizácia zlyhala %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "nemô¾em vytvori» `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "nemo¾no otvori» `%s'\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "záznam v databáze dôvery %lu: lseek() sa nepodaril: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: adresár neexistuje!\n"
-#, fuzzy, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "nemô¾em vytvori» `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock '%s'\n"
-msgstr "nemo¾no otvori» `%s'\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: nepodarilo sa vytvori» záznam verzie: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "enable ssh-agent emulation"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "tillitsdatabas: synkronisering misslyckades: %s\n"
+#, fuzzy, c-format
+#| msgid "can't create lock for `%s'\n"
+msgid "can't create lock for '%s'\n"
+msgstr "kan inte skapa lås för \"%s\"\n"
+
+# se förra kommentaren
+#, fuzzy, c-format
+#| msgid "can't lock `%s'\n"
+msgid "can't lock '%s'\n"
+msgstr "kan inte låsa \"%s\"\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "tillitsdatabasposten %lu: lseek misslyckades: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: katalogen finns inte!\n"
-#, fuzzy, c-format
-#| msgid "can't create lock for `%s'\n"
-msgid "can't create lock for '%s'\n"
-msgstr "kan inte skapa lås för \"%s\"\n"
-
-# se förra kommentaren
-#, fuzzy, c-format
-#| msgid "can't lock `%s'\n"
-msgid "can't lock '%s'\n"
-msgstr "kan inte låsa \"%s\"\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: misslyckades med att skapa versionspost: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "enable ssh-agent emulation"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "güvence veritabanı: eşzamanlama başarısız: %s\n"
+#, fuzzy, c-format
+#| msgid "can't create lock for `%s'\n"
+msgid "can't create lock for '%s'\n"
+msgstr "`%s' için kilit oluşturulamıyor\n"
+
+#, fuzzy, c-format
+#| msgid "can't lock `%s'\n"
+msgid "can't lock '%s'\n"
+msgstr "`%s' kiltlenemedi\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "güvence veritabanı %lu kaydı: erişim başarısız: %s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s: dizin yok!\n"
-#, fuzzy, c-format
-#| msgid "can't create lock for `%s'\n"
-msgid "can't create lock for '%s'\n"
-msgstr "`%s' için kilit oluşturulamıyor\n"
-
-#, fuzzy, c-format
-#| msgid "can't lock `%s'\n"
-msgid "can't lock '%s'\n"
-msgstr "`%s' kiltlenemedi\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: sürüm kaydı oluşturmada başarısız: %s"
msgid "allow caller to override the pinentry"
msgstr "дозволити функції виклику перевизначати pinentry"
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
msgid "enable ssh support"
msgstr "увімкнути підтримку ssh"
msgstr "trustdb: помилка синхронізації: %s\n"
#, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "не вдалося створити блокування для «%s»\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "не вдалося заблокувати «%s»\n"
+
+#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "запис trustdb %lu: помилка lseek: %s\n"
msgstr "%s: каталогу не існує!\n"
#, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "не вдалося створити блокування для «%s»\n"
-
-#, c-format
-msgid "can't lock '%s'\n"
-msgstr "не вдалося заблокувати «%s»\n"
-
-#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: не вдалося створити запис щодо версії: %s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable ssh support"
msgid "trustdb: sync failed: %s\n"
msgstr "信任度数据库:同步失败:%s\n"
+#, fuzzy, c-format
+#| msgid "can't create lock for `%s'\n"
+msgid "can't create lock for '%s'\n"
+msgstr "不能为‘%s’创建锁定\n"
+
+#, fuzzy, c-format
+#| msgid "can't lock `%s'\n"
+msgid "can't lock '%s'\n"
+msgstr "无法锁定‘%s’\n"
+
#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "信任度数据库记录 %lu:lseek 失败:%s\n"
msgid "%s: directory does not exist!\n"
msgstr "%s:目录不存在!\n"
-#, fuzzy, c-format
-#| msgid "can't create lock for `%s'\n"
-msgid "can't create lock for '%s'\n"
-msgstr "不能为‘%s’创建锁定\n"
-
-#, fuzzy, c-format
-#| msgid "can't lock `%s'\n"
-msgid "can't lock '%s'\n"
-msgstr "无法锁定‘%s’\n"
-
#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s:建立版本记录失败:%s"
msgid "allow caller to override the pinentry"
msgstr ""
+msgid "allow passphrase to be prompted through Emacs"
+msgstr ""
+
msgid "enable ssh support"
msgstr "啟用 ssh 支援"
msgstr "信任資料庫: 同步化失敗: %s\n"
#, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "無法為 '%s' 建立鎖定\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "無法鎖定 '%s'\n"
+
+#, c-format
msgid "trustdb rec %lu: lseek failed: %s\n"
msgstr "信任資料庫記錄 %lu: 本機搜尋失敗: %s\n"
msgstr "%s: 目錄不存在!\n"
#, c-format
-msgid "can't create lock for '%s'\n"
-msgstr "無法為 '%s' 建立鎖定\n"
-
-#, c-format
-msgid "can't lock '%s'\n"
-msgstr "無法鎖定 '%s'\n"
-
-#, c-format
msgid "%s: failed to create version record: %s"
msgstr "%s: 建立版本記錄失敗: %s"
datalen = 0;
tp = privkey;
- tp += add_tlv (tp, 0x91, ecc_d_len); /* Tag 0x91??? */
+ tp += add_tlv (tp, 0x92, ecc_d_len);
datalen += ecc_d_len;
privkey_len = tp - privkey;
int exmode, le_value;
unsigned char *fixbuf = NULL;
int padind = 0;
+ int fixuplen = 0;
if (!keyidstr || !*keyidstr || !indatalen)
return gpg_error (GPG_ERR_INV_VALUE);
if (app->app_local->keyattr[1].key_type == KEY_TYPE_RSA)
{
- int fixuplen;
-
/* We might encounter a couple of leading zeroes in the
cryptogram. Due to internal use of MPIs these leading zeroes
are stripped. However the OpenPGP card expects exactly 128
}
}
else if (app->app_local->keyattr[1].key_type == KEY_TYPE_ECC)
- padind = -1;
+ {
+ fixuplen = 7;
+ fixbuf = xtrymalloc (fixuplen + indatalen);
+ if (!fixbuf)
+ return gpg_error_from_syserror ();
+
+ /* Build 'Cipher DO' */
+ fixbuf[0] = '\xa6';
+ fixbuf[1] = (char)(indatalen+5);
+ fixbuf[2] = '\x7f';
+ fixbuf[3] = '\x49';
+ fixbuf[4] = (char)(indatalen+2);
+ fixbuf[5] = '\x86';
+ fixbuf[6] = (char)indatalen;
+ memcpy (fixbuf+fixuplen, indata, indatalen);
+ indata = fixbuf;
+ indatalen = fixuplen + indatalen;
+
+ padind = -1;
+ }
else
return gpg_error (GPG_ERR_INV_VALUE);
privkeys/FD692BD59D6640A84C8422573D469F84F3B98E53.asc \
privkeys/76F7E2B35832976B50A27A282D9B87E44577EB66.asc \
privkeys/A0747D5F9425E6664F4FFBEED20FBCA79FDED2BD.asc \
- privkeys/0DD40284FF992CD24DC4AAC367037E066FCEE26A.asc
+ privkeys/0DD40284FF992CD24DC4AAC367037E066FCEE26A.asc \
+ privkeys/2BC997C0B8691D41D29A4EC81CCBCF08454E4961.asc \
+ privkeys/3C9D5ECA70130C2DBB1FC6AC0076BEEEC197716F.asc \
+ privkeys/449E644892C951A37525654730DD32C202079926.asc \
+ privkeys/58FFE844087634E62440224908BDE44BEA7EB730.asc \
+ privkeys/4DF9172D6FF428C97A0E9AA96F03E8BCE3B2F188.asc \
+ privkeys/9D7CD8F53F2F14C3E2177D1E9D1D11F39513A4A4.asc \
+ privkeys/6E6B7ED0BD4425018FFC54F3921D5467A3AE00EB.asc \
+ privkeys/C905D0AB6AE9655C5A35975939997BBF3325D6DD.asc \
+ privkeys/B2BAA7144303DF19BB6FDE23781DD3FDD97918D4.asc \
+ privkeys/CF60965BF51F67CF80DECE853E0D2D343468571D.asc \
+ privkeys/DF00E361D34F80868D06879AC21D7A7D4E4FAD76.asc
+
sample_keys = samplekeys/ecc-sample-1-pub.asc \
samplekeys/ecc-sample-2-pub.asc \
samplekeys/eddsa-sample-1-pub.asc \
samplekeys/eddsa-sample-1-sec.asc \
samplekeys/dda252ebb8ebe1af-1.asc \
- samplekeys/dda252ebb8ebe1af-2.asc
+ samplekeys/dda252ebb8ebe1af-2.asc \
+ samplekeys/whats-new-in-2.1.asc
EXTRA_DIST = defs.inc pinentry.sh $(TESTS) $(TEST_FILES) ChangeLog-2011 \
mkdemodirs signdemokey $(priv_keys) $(sample_keys)
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOnJzYSgxOm4yNTc6ALWn703ukwPA
+klb9+e/m8qGu/XewzQ5fnciZy+YA71aO1L0vg5idBqmWWhUZ1H2jMLpSmHGTsWvw
+v7OpIgsPcyIqmlJ/hXNFxYI/xS8Y9AzFlASs+DqmMOjBghE5crakHjS6JxtkBNK6
+efB3teA5WlD7oVJwhYMsUtkH8/OJq0Lml3sZaca3vDvm0CnEDlqr0pog6RiDxAmO
+gUO04ZcjaGVz9sb+U+coIe/qG1kJZFGdSpuV1BS79nyjMnmMfNt2uB0w9v1hnGrv
+MU7q+OaaP/ii8+tI01WOGn+KQsJp89PwgcnA8y57Up3zN6pDl9WF80uJL/J3FIe8
+RuaE4VBv76spKDE6ZTM6AQABKSg5OnByb3RlY3RlZDI1Om9wZW5wZ3AtczJrMy1z
+aGExLWFlcy1jYmMoKDQ6c2hhMTg6fMHJiYfEZhM4OjE5NzM3NjAwKTE2OuNRxs9I
+ktHtlDMTy6rWZJgpNzM2OlWwk5Xhn92HLSgS6iqiDLYg3NLreSQrnI4i2ujY97BD
+R62o3Li+mu2wO8zFy+zErpMAg1Xn8Cy5III9jQYznUfUCa4UbThAz4XnSTHkP2Ta
+/YunBqAnetFmj+HIeSpFcsUEY/MF9bKNuiEtA2Te0J1X6BYUMY163TxfkLZDTG51
+tyuEqn8n2B6fBu/Vjysyq95ohrrkvIkwIs3p1UOa4qgn+wbr4br8Bu6mf0+ClXoj
+nPCim1aQMrzZHyWYXgqnFjRnHW36lHpdWGqav7vV3+qbjzlVMldOGx24PH1bAYnS
+BD5eeMletc524qYBSxSIyItuReieymNNYAoF6Wf7ayDzDzf2pGrY55wIt6vH2J4D
+24M1ydvS99ibu80A8O/K7WuYHTcrzgPPmp6/aA3q8kxGFrHrAZ1r54yHPKbYnNWE
+v0BxNe0poaMZJKDQIoJT0mGEmlpS4lr/K58QyECIDN1nOVyKL7ixxsqjJI3G0ZY9
+vpOpXHzFIToA8U+/82e/qNUA7wkQMOhG2lF9AxyT5eEOEhCW8J7QZM+FO6ocplgH
+ZxwHa0ymv8Tj4yOVFNSo/ENJym1HGiyvjgnQS2MSZ5kIyVNuGI8AWPsWQJ6B/04p
+LE8apX775kVhvIX+DNU4Bnxnb7KtG2HovT9NxQIzIYcANC/rOKdOq2j5vS4XqHsB
+O66pV0JLa8TPD5iKDIzS2ONBxyKi2HqRg+xkEIpNBhvrQgGs2FzoRvivbjBOgwjp
+hRkX1dkF4axKWEPRuUhvlA7f/TzbHFtjbWyd5fm57j3BgsVj/EcSrGtpl5JQd4k7
+etSIWvtWWySZJPDXz7CW9Wh7W0ZXA76tmniLDeYl8lnMIYa6ylttTnuiW4hh3naH
+JFtWytL1ivCeo8iy5wGQ2X3Jp1C+Y4+lgR4pPE8w04y5Rzo8Jo3VSMWbeovn8djM
+qfXy6yH7H6qHYCO31IJxFfz89EuCE0EGrYUzDFr5KpUpKDEyOnByb3RlY3RlZC1h
+dDE1OjIwMTQxMTAzVDE3Mjk0MikpKQ==
+=jzZd
+-----END PGP ARMORED FILE-----
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOnJzYSgxOm4yNTc6AK8HhE8MmR/i
+QdHw5kcWa8Lm7henF1KdhF3Z5iDNeurFrDQsg/RFHJbaMyVCzCP/Jc4ayub2FzeS
+fJdKXrpMPAdaGjlbGLdY08Fc49E+7M79YQXgyGXhTm3kZa8bw+TfYnLJC6snxefG
+5YQqEpvV/mfvfQd6XXxDcn/u56YDJ5Lo7xRXmnd4Ifj6T1lF2KDQtDAB1vlpnuxE
+QfnAI8C8UpsxOWC1tSuQ5HIoFnwqAEfEiHH+P2YuHG6m4oyUfT7c11rHf8S01R9Q
+JQCr11Dn9WMAI/IHe67BsrbIAxG+9yeBhIkEShBBxdNqIt2FnE+sTmQHv+uiY4ya
+3ch63dvZ53MpKDE6ZTM6AQABKSg5OnByb3RlY3RlZDI1Om9wZW5wZ3AtczJrMy1z
+aGExLWFlcy1jYmMoKDQ6c2hhMTg6+Nvda1z6F404OjE5NzM3NjAwKTE2Og6NQq99
+p1NyYxcYgwRiATApNzIwOgzqYGEJNhmx149fV84cgLNbmIifZ48o+oywHbwdju0c
+oNmaBHv+Xkm/U5PG/CPYINJbFIewrxuNpGbW69VMfOi5nwcvIE2LouuRd4Ih7cYq
+ub9fjqIH9tO4AA4kkSA932AfJseLTZMcSqvSmyIE4GU6psDjQHuXur4ywKYX0iPi
+11hlhFtiARw4S3ToidPukg+SiEJV6Sec77BmQ2NG55FEB3GiM8m5LOMSPq+ZfxI9
+RmldLuyC5TfGWRgraR+3SU00gYkbAOjwlblHloQzoHquCpumujGvSxYolDsW32HO
+Eojy0k5iezdwbnpBmdWJbnI+qAQQ2wjmEFPKVPnOF4y1Nki+sRXrgFXGbgHwHbRN
+yMgRgMVeYycHhhEz5N+VwQ5yKE3hvIbD0dznD6Z8QAb4PXem929eJDz3FrR8gasN
+2udqDyHkczK3y5oJs4k82Fnmn3Rjfgddyo04SSf/1Gwg31y33Xh7dkdtU+NOt9s9
+wCu+nJhdbh/IH8fXPax2HuWY7q0EPlZQldbeBta4r+RWvNFFDAG8DK5uBHQqtKoV
+vV71ffPm30s4ysaSF4mqF3eIYLltPYNenvsYKpT/cn/3WvbLsKqMIOGytz3P8fQb
+49ZDGDyzT1rQDuJ2oDk7N+epZu+lna/nRo7UBEo+Tf7CkcTKQ97wY8tqqLUdclJr
+KJsIIutg8WgIx09Xvip1gfOAZV4s9V6aMejT32CBLSEmC86t/Tu+3HrstX2E3F8+
+Sc0gB5B62/PMSzCI3lgkjMRp6yCzm0cZkHSDHOSLpoEvSehV0Gv33DFBPNog8XVE
+A4H404JRMBHI5mKpYcYKv/o8ZpQgDGORMZYf5W9/LMF06QZGz36kPVyIwL2j8oCr
+0T0kp/ik8WZSV+BkwKON2fPkROQ7c7ZM+S/xcrpKEe40/dWtTZUABGhCL7IXwlqm
+u2nGS/Cfjmq3TRuRJAZFZykoMTI6cHJvdGVjdGVkLWF0MTU6MjAxNDExMDNUMTcy
+OTQxKSkp
+=04As
+-----END PGP ARMORED FILE-----
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDExOnByaXZhdGUta2V5KDM6ZWNjKDU6Y3VydmUxMDpOSVNUIFAtMjU2KSgxOnE2
+NToEOx/Lj6ZzYdOMdprseVCR/dwZaYPeInquOlapE22Udwppy4tQqj2jXDYH8d0Z
+5uRvT/FD5lpcW+Cv+BAoo2auuykoMTpkMzI6Xka+GGkZ6tp+azZo+LPj0inV0GnO
+vact0wafLNZvlQQpKSk=
+=Rgp0
+-----END PGP ARMORED FILE-----
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOnJzYSgxOm4yNTc6AMwChvrQ9TUc
+PtBbfK0UWOt2GZrzq7I0ZhcjfoxGD4UXxKNBxHcyb2cQYTh5tF4XqIv9d2Sys1c4
+fU2Rr6lnPDc6VpSLKoHZj76jWkcWVf80+MXFNVp/YqErQBMu/AkA/Cwk3hEgjqQI
+ZOo9awfBATJqGmW9y3Ct1IV8oM6SUOjYQ8CcIa2jpSNNq9rhXQjzTYUZHK4ayTmj
+mPvuqSxWahUsOZClA3GHpLZkFe9k2UJuVIUfhwYD4CyIR1nqlFfj87p/UEPs1264
+/RpBagz4G74BiLhiHQss8NXm1zWiRZ1xPyJIkrDm42JRQ+6gGf1qvk2tyS3Le4W+
+7sg3r08UExMpKDE6ZTM6AQABKSg5OnByb3RlY3RlZDI1Om9wZW5wZ3AtczJrMy1z
+aGExLWFlcy1jYmMoKDQ6c2hhMTg6xlhuUgeZDb84OjE5NzM3NjAwKTE2OilEwfz2
+SNwgLhCK76qARHgpNzIwOqgwKI52Qj5ABmkzDaJ3srvp4C6GnCFvosWjaNBZkLaX
+z2cGEh75T8Klm/RR8tXhXxHcl/b+UErb0CDRy6nQvMhU6LX+0hfk6t3M+wE+Wz/Q
+/uPoT5cdgWRUKBjCzSgH3DKwjBM8z8L14UCsZt17vEDVwE3jvAIo7DmvCjAKt4tP
+jyyBUMl8kn7HBAJkIthCnNZ3Egj1o5NqYVc6Dbh82x01lPh50EkNUOi2MANRxkCG
+Ycg8zeB7uaMwM7Hu+wtev+QMve3aoRVRGHIEbwzj6wl/OwmSROWmQxmLebs20dMD
+sdhaUkfGV2EFXSzgsK8q3zrWN7mkr/h5zs63kvsQnbsOU3ym+/OPgCOUSBm87Ggu
+GyUoIblgyzJHxNHN0x0RoFue3JE4CCZvsj+Cn9auwgniBCTMBHhanLm4+y4jMAdU
+CEdHV4m55FOG1i5AyNr9m8U3/SPzlHdPJ+9P/8hEJhcB6tbX7I43K8Wl+5I9yJI4
+p6gI7VQhLCjmpUihsnRdmFGfxneDxNNIlzDwPOoV0thfOoju15ofxNdDHCzWhiin
+2WVhQ60iHLT1Pfgk1htGs73wIFDsmHdJphmAscCq+uPDeDu34GPZi+DGQIndIlWw
+2Dx0QjvtV5DYYHL4AYKbvCrMhTF+2ECZB1WuwTRV3AaOS27GnaneWK6KURrAE8p+
+LSIvFya6g6tbjScflrLNBm+8n7/Iyq526IiwgxQC8g6t79AxxKBSarjw2RhQRi5Q
+PJymKlVvp+smFATNLMC+cjEFSP3zf+8a1gQnmSuaSY+UmhG/yakDlEmZzTRH5K4r
+rzgFvQhi4rZMCSBTy2I08IsIzeZhzpsrWmsTCnPIaFZ3VwzzabbLV2pwWda4hW0M
+vXf1SZwL02RujWISEiJ5ufPwm6eFwH1dNRvxSTN34cw53/cFyiuuETDx2/XIp7Ec
+ODuPCvJvsVjRUBQ6tdxkLSkoMTI6cHJvdGVjdGVkLWF0MTU6MjAxNDExMDRUMDg0
+MzIzKSkp
+=opty
+-----END PGP ARMORED FILE-----
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOnJzYSgxOm4yNTc6AKotlDIKDSEy
+vIjkWDdGHQCzm1ebRtyb15Ljkl17NV4biDAA+2qOrw3QJQ+6CfVpD8XEygXpBEv0
+16VgFuB5MsINHNE94dKAUc0R1uUwZljeINPQ2F/72t3SFiiBBGwY4AHDNn/zi6Rc
+M7JwjJW/pkkqcmvy1kA5kP18XA6wgY8NsyCa+H9ZJm5BK64MSGUEdscWykuHUW3z
+g6Dc8bST6OhlokclRWh9KVK0QRbqnlQeVP/E/Kv4LhnbXNB2GE2Yecah4rva/PNq
+2YZ9CfyuQHwSJQhb1h1MKLi57AAacgAhV6OcR1hM6We1Vh5JDFEj01DsIMC11S1Z
+zHYLXRWAec8pKDE6ZTM6AQABKSg5OnByb3RlY3RlZDI1Om9wZW5wZ3AtczJrMy1z
+aGExLWFlcy1jYmMoKDQ6c2hhMTg6O8dPH/PCXh04OjE5NzM3NjAwKTE2OhEO7X2q
+8iasv3iHvYbCdQcpNzIwOjBesXtjq+5LWL6zU5yqEK5GrykQBIHisxNK+2TA3vBM
+sb/646D5Za60r6rjAShVxIWa9c5rzmS+rITBVodTzAjOn2uj9k1TQNmqsWf/i3zj
+xe6puh6e0IIkAoMcHpRozSOHF1q5YDKfI7wjr8+u+TdROFhEhObQ1CXTnjTCx1aB
+oQG5AvybctPjSCdYxVujXmNjrgngZodiTxsE4OBG/bk2msK6GY+oJKgBCp/5m04Y
+DGDe2w9MDt7UcW0tlo2kHk5cwKPs/ziSu1gfaFqqOzFBdUc+gR5ikbzDF1vJ53W8
+3DwnzCSkuciBX8MeGiAfkR8f0WQsBStMNZewnCsPYeB20Cl8bTAtzs+X7LKzdSI2
+8gSkIV/GD3VwYw80cqn2eF+5cJKtKIV1nOxPRoXgcuWvNTL2nyLggaJDVusy3MKY
+O3yNnadWmA1XT8NMBx+yY1i0pCfmxWK5h/2F2cNbe21MyhlwgkGD8jVZCiW/NeCB
+VdpFHcqZz+rYchLTjs+LSoINKFiwoIpK54pMAuRO+E1y32Zo7XoZqyDkU/ip2iAK
+OaB5LTjl/GI5ISRBcsxbPXOxbNnUat+0p88T4Dj/V2ZJkubAwRIzgOE9p4TgHqlF
+2kkl+4rqqnooDUQ4ViEIUxjq2YIws9wkWAthMMcJVDgRcD8+G6IGAJ3tQlIaW9oA
+OVLsHcXdiFbcEE12m30CMI0uUQSavk+aO0qO1ZQRYtu9EipGWnjWs+0ZqcMaz9rj
+ACv6rvsts6puie3uvL+yzEuzpWC74e50kElF0MLVQropNY50hvXqrnKzoU5ppaNt
+W7q4vrtKZh7QOFt7mcG4oTSIpr0vTwBGl0YbrORviF1KdaW2sPHNfbL7hrTx1HlU
+3BnAM8b0kYz+NEJ1qxNUfymta5iZI21LebJNTWJIiiCBS33J73Cxr92UaafU3VRA
+jZRpavMXHHoesBZ78uDqAikoMTI6cHJvdGVjdGVkLWF0MTU6MjAxNDExMDRUMDg0
+MjM0KSkp
+=zQRC
+-----END PGP ARMORED FILE-----
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOnJzYSgxOm4yNTc6APL1FJVAgVOE
+iOLqgmqCWcCgIfl3FT/pBaLJYLO8NersRuygQ6ArAdNYar/h8MKnOkYCwlISr3fp
+Jtj6cpPrz6IU1K09HYEpVc6n1UbD5r25sDc9Ol8ztg5QPVP+ceA42nzpHAnMAW7E
+9dz5gsM/H6TlicF4qOT3rOfpBqDx1EHOaOS6pdnem7SwSQZ6RFetJotkXqEFfSNV
+lMTLqqysfk5kUW+jn7B4Jlpd7YWtlaLsPXyY1dFwi24VqpIiztOYRoWFObySrpZk
+wuPGkQ5P/Eqi/2+L7VKXNfODRI0NV6GX1FaQ96lIq0Y+z1EWojLwPb9JR2FLGqC+
+4/mm/W7Unf0pKDE6ZTM6AQABKSg5OnByb3RlY3RlZDI1Om9wZW5wZ3AtczJrMy1z
+aGExLWFlcy1jYmMoKDQ6c2hhMTg6vkrGYgB5EO44OjE5NzM3NjAwKTE2OuQHqFdP
++Q1Oz+cCYcb27DIpNzM2OjoNch/oeQ0jhPqg+yQ0z3Qf26SgZEKqsdozUsPbhBfs
+n4zjoOj3goT4DTFl/pCWL6lCMy56Tb2Ra7j/SUeKAqBSSwarsG6mrFktOQntpw34
+QWxaOc0dJEmy5/IqY0uz4vK6y8X0MWPTDPt0kxvi5Z74MQ1uVsC3ZnepSenLpr/W
+F38jEsq3CHO5rXUDrwMLLTqL0zE9bE4mgQkFIrzZ0UFM8iFi7cI+Yyp/esbZHubJ
+MqJD1QVf9TpA8OAVXPj+JEYljsqszvjqWbO5pceTyT3OxS0/t0GXeGkbhgS+42qw
+VOlZQe8r8Zs2MfJcGKwTGxS4HW218YZxZAan0eFOsVan+gKthNRGjvJzyy2w9foV
+OND0EOzkeBFDohjWN8ROkVI2z/DyG2WDoc2H7tiajWHTr31uhNlMXDLynhp+zoRV
+GfWIEsrfQiUcnuPyWP+tTyHoqTlAPOqeosxDsZfosEN/GRxgd3CFT1OBdgjd0YHc
+fB5Dfc8JtVvZwXECz6A2eXCOCUJ7ljRpNp4bxtnRoO9VAydWcgpAq8DjwkgiDqLR
+xYAvjAe6irEKNBKVocGV/zw03JvkqnYW7ChLr7sNfiJReFuiJXmWq1mYerOHo356
+LIaZsN0n7NW0OmQmAQmv2ezC1ZCMyjuIMKcDssTieln6Yi7NmmmRPCkkiWoK2XtC
+PVY6Q0gZ1zUysQ4O/Rcm3Nt+U8JUpeXvry0086f0sk0yEdzB0RbZFyYMWFzwNSW4
+VsYtxqvzPVmYHBO6UihvmPnCuwIpUBVpKjsXN3NiARlPk8uAzR/quOgLxVIX6leq
+1hT9DohrFGxP/O1SQhgD1xZfMRwJGo9J7OYA9JWRvZKguM6bJMYZ7Y+PJWZDfifG
+TuQLPq8eA7B2KXEzNjHt6tyyDmV/SsbEoUPZBmGqD59/4JJiHtRy5HJdEAJXTYul
+FpV6Fx4qVf6IjnH8ax8tmxLenGBomboigTofJFnz51MpKDEyOnByb3RlY3RlZC1h
+dDE1OjIwMTQxMTA0VDA4NDg1NikpKQ==
+=4K7Q
+-----END PGP ARMORED FILE-----
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDExOnByaXZhdGUta2V5KDM6ZWNjKDU6Y3VydmUxMDpOSVNUIFAtMjU2KSgxOnE2
+NToEMIx/SmNEvuSVkX0Xq60JBOTUT4qTr3ywNqUOSaKijgdYKjwkIF+jpD+7TfSW
+vMznIU/Ued6WdRrqtQbi4KVzdCkoMTpkMzM6AIbAgwG04OO3x2tqboQ8eGekVM24
+4oEWVVQjQwNeheokKSkp
+=RxSg
+-----END PGP ARMORED FILE-----
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOnJzYSgxOm4yNTc6AM0QnGL35Fvz
++RybOtdBOWPX8XHZ3CvPq0gr50pjtZGZLjlDe5Jf8oX24cGBVdFdILOlOglXNJX6
+Qz5WxNrZtU53vDfkgjA8flQXFqIlkxv2ZkjKP2S+Vgr9LjbrFxxWRlZY+XqMNahE
+jbfA9gLr1GG8gM7ABsU7O03/pR2q7iF/aDMKm8asN7+k4/tW11e5yZeQkc+aBz8z
+bhBCZ90jdfQr5jHQsJx9EOlrCWvDcnGojDXQBc2AflwuEJQHSHqPsy4E5KnMlpp8
+ZzFw2spfExWzNnEfZ/qQ9dXgnhdeNFmg/JRvgohreRExvO3yJiQMbH28UBTb/NBO
+e14F8j1XdfkpKDE6ZTM6AQABKSg5OnByb3RlY3RlZDI1Om9wZW5wZ3AtczJrMy1z
+aGExLWFlcy1jYmMoKDQ6c2hhMTg6kSqZ9Kag78g4OjE5NzM3NjAwKTE2OlKflmHj
+kP1iNdN0sAvT1dopNzM2OvOi7aAUszePhXP3b3zH60C9ygixV1MQIKMUTDlZkTFv
+uVwdyH8IsB5rwaIZV5kO9xOdTPZAUG+jw3i5vUJzVYb3tORlIQLMZl+cT6InABFm
+eZ0jC7n2i5qEGK5nb+7na4SRv7jOCDpvEvmX3UxYsx9OvnVq9ndNg0t95wDc8Yp4
+OuWQM56DoSmlfi8yvX8vdihp5XVqwvoKZNbXP17o0K2VjSBfWMW30mF+1MRVGZjj
+rji0TJA0747OQjYEVVi4Jyvd1Qd+Ao3QWkXm4TzeiRAOYKTy1g9+6mTpLr29IQPo
+Ljvea48pJK2YJM9FNoZUOA04Pv6n0w/CCSFMSGDJon8KATgTgkXFWlxhCEPqJxJL
+emruPGPIb3Qv05etKPjGyvxk7fm+5xBjpxU2Xwk6kUZOfuX9b8KkBWDBlBSSRV/w
+teH+vTVFG1ydDFoCbay4TzKIHRHwS93ME0L11GHLViXMD3tOG1BKudPD4JUxrHVa
+MFHKtkvfTEz6v4YPCCp84+cjrbOKhSabg6caNcD0rge7iFVN4BArs1B/akEN+E8i
+q3MoUv7lN6GC1XEiEvK/8NgDamwUtbRQfPyJizow4tJSWTm0SZdTlBrkdUgCgW2s
+2dTElthntFqGOpBj6AvxoUPpnKKUp4o1W97bqV4regz9g8iMSna+BrzfYMrt8AlB
+A4eKtYbjFS0aNzhDRJepATVh/DVsy4bm3XN5L5Lne5greOCRcIjmE6n2GOHjh4Y0
+/ba/hj4WKm2n63toXJlxJ1t1Db90qiH8ASn6Bgd6BR0NueIrYI+YJMoeG+NLjB2h
+Ag6rd+yyjLEqaxniJkz9lZvj1AmX0JX3hfC6q8I84ZUdQFyBVQIxeN8EsKeWh45c
+1bEgyecQx+PNmrEUa90OZpJt6V1mQhb2SCDBgSVpAGoI4N2J5NOJ8gm+plgLsMDT
+Q1xhmBNF67kVYmV+ljiOOCB9CluiR/i2STv75ydnuBkpKDEyOnByb3RlY3RlZC1h
+dDE1OjIwMTQxMTA0VDA4NDIzNCkpKQ==
+=1YfR
+-----END PGP ARMORED FILE-----
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOmVjYyg1OmN1cnZlNzpFZDI1NTE5
+KSg1OmZsYWdzNTplZGRzYSkoMTpxMzM6QJASwJYtt7iJ0ho9ryWXzi6FYfC5KR+p
+uwXT8cWoMCuCKSg5OnByb3RlY3RlZDI1Om9wZW5wZ3AtczJrMy1zaGExLWFlcy1j
+YmMoKDQ6c2hhMTg6vuifz6Hv4GM4OjE5NzM3NjAwKTE2OpcAZjV5+F/YlpOPgp1b
+WQUpOTY6qFMSoZCpIVdpOB9iKNKcrowuxl4tpSya+TVyDRedFeYEJgrcUjLFa5qt
+Eqi/0/ceDijJBz1HGyZ1mRWwGOzCqhd/8ccVQlQp66GqO8x4Na9uYtfNurj1a7Gv
+kdi+aQ+UKSgxMjpwcm90ZWN0ZWQtYXQxNToyMDE0MTEwM1QxODA1MzApKSk=
+=FCvp
+-----END PGP ARMORED FILE-----
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOnJzYSgxOm4yNTc6AL8OibB/4Jrv
+yu3WLmT9knI/wEmxSjU6PXn7xCyDgxXd45szIKV3uURsYVsexrIRr5y+uijOWq2J
+FunrhNV4sCGpRAnS3EA1y1zqFx7Ob0/k4bLvNn8UFNtblIlxqSjT2Oz2T5+4GAme
+Vo7Z49keWryDyMeo+J1cio0NacBwR5Ee+DL6NfGoSyYYHrrQOn9PCnASR/I7THMP
+4l729yHnVNHnsgA1t/plvgXJj2Vf4KTu8NFaXFbd5a2gW14+nv2kUTenQuHs3Nn9
+d9NQeXSZ3tWP7FvthgklO3bp+dmjbynDKacKQGWKFyYlnx/qNKRe9Wnr59vVSeyk
+tyA0pbyvYNcpKDE6ZTM6AQABKSg5OnByb3RlY3RlZDI1Om9wZW5wZ3AtczJrMy1z
+aGExLWFlcy1jYmMoKDQ6c2hhMTg6LskYBR0oJSs4OjE5NzM3NjAwKTE2OtX507Od
+8u583SoOhgpvTDopNzM2OqQsv6qf5uCTG0KqleH7oUveFKt4ucEElrAyAiHe8x4c
+5BIt9r2cz9yVyZjiolXC2zuGZMmt15odX+1vp9zUAaK5cFFFk8z6qEBEeFOP+4Ss
+iBeI2r3fHN+/mYMlyomBXV9bZ3ER3lio8iqdsnjkqFo+AfA3otGvrZNhXPa6GaLh
+1KRW3D3Lg97gp+GwrsQ5sRQ6EFBlGzg2YFWLFGO1txvQfLECEzQMZaej1S6XNKY0
+87LmmCNhyNvSP7WECb0PMwlXKDUEy7zjEK2VkGRSEg4Y8CmMFeW68Zrlvivcy01E
+KXQ2EpI0i9mxI/QnQa/6d4GAkuPywbJG4U/rgEDMwubHhp+QVNpU6JWy2KKnMVVf
+7Ln5KMKCOKh3ZcvRYUq1yen8ybEOKJ2nFZ5VQfmSSXvW5yDClQCe8PwwOY1a5nw/
+ODcPM4oeW8PmWncWNuhme/uicECa0wuJ4IGUKTyg/Vs4OLMjiXLwT1gblPEcfuws
++3A3o494JOEqnyyvfM3ZmHE+RYe9+OV6/1JFsIhSn9cWty/H26QpuFvN5D2cXXKU
+txuqC8MmovtCRzG/ASja68rc0NC7uACBRvb90v5tlDCFmBZAPJmFnBnB/OGqQOmF
+dFXGRJiauaKOwRtEzC0wyMdkB5+j4/oBj4Nt3Ua5Qbk1B5m5M4YfEX4c89G635O0
+cmO+c9ubv/oQSNcXnJmIDnIvwBXDMzS9psQp/LzIpXIpbJUU1tRclUL/LAQChhmS
+Isq2qP/s8jg8BNSjiXlRkLqg5xkcKuW757y725fiAOrNjDYYBNVC1XIPaVc1/Fkm
+T1Mcn0OuQ9Hwcj7C+lqcq7vSZkx6h5+YjvJ5uDUQvFVJMfoDbKMKsKuJ2qSK7ano
+ePtji6v9SylT9cSZnSngaar+j55JD/wocGlAcVOZ+fOkoo81wWAJ1+XNZX4YNQ+/
+naNT4eyAq9k+CqxZjDOSbdg/aoOzFPDkRpDrkQGq1IcpKDEyOnByb3RlY3RlZC1h
+dDE1OjIwMTQxMTA0VDA4NDg1NykpKQ==
+=MG45
+-----END PGP ARMORED FILE-----
--- /dev/null
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOnJzYSgxOm4yNTc6AK5ASAwdxvm1
+x0sD1PVAjVCEgo2oqT3mg/onopj3t3dVlBuEv23f+5/EoLTEIAE8ulGDCBQRw70X
+j4e5B87oc5DxBs2uiMGbCX8L7cEQuXVRRrwQR5kJI62iCle1prehdXTWFgZUBXwQ
+60GAGeft/MmznrUN4qy1qt7dp8eqOq9on9xA8uKzigCYEjRsGeScrFedAemg0so6
+AWbCSz6S1BbZKxYPilbG7VMvpA24kgPqQiiaZESlFt7iey04WE9v26vH5CExVqFl
++M+tAGIPw439X0leIpdidTWFdREw7DCkRBjZ8cWbLEIfhErco1mqlSxR1AvlSXnb
+yxerHQRO+KspKDE6ZTM6AQABKSg5OnByb3RlY3RlZDI1Om9wZW5wZ3AtczJrMy1z
+aGExLWFlcy1jYmMoKDQ6c2hhMTg6tIGQBN/WvYA4OjE5NzM3NjAwKTE2Olq8YLkU
+7sO9zkXVYdR0ApwpNzM2OneDiO9TEO0M//ms4Wh2ZDR/oOHF67pj9woAkW+en7vv
+r512xqgFV2m2b2aFTJYgeJwWJgVItmgmoM4RsbtL3CVSXrKRi4fi3VbwWEN0p4MI
+wOXkbdFFxywvEQjQoNEvvBFHTlLkRIHzugfhUJID4wNzcGq55LnH1zoyXdUorlhi
+dpJ7Y1QHjm7j3RBiTRpGXXOIwQkpTf4eNIIsOeaDTQVIhTh62UFzUY26NBftx0mC
+cYhFs0lOk7k482OnCkm712BejhvHOcs46Lhi9JwfY6j8QcgrIp4b2MyT8BOg1cIX
+vjD39tKJYh9SHWZlB694KZYqSmlr+RfhgLTNV7Oq4Il9JNhPgImG/ouE/O14j8W9
+MyIg7T8NhvYRt+sym9oijvxXb8Z7dD12RomxOZFAajrHMv349JAebUOSIxCBg082
+LNRleJKl7s8Dw5avgyc03kqAUageGOjRWsJvbSKLebKDUoLqEyyNiTNbbTru4oZb
+RyfqPftZkPymIQGS7rukohZ7cZHM8jT4Bf79VRvFAXQJ8IVGjHVvrwEbV0mOgin7
+i3n0hYsO8t3YvNtQZ6c2oTkhaeakYgebRKXSgWmLK/FcCtnftYuulPD/ApkcnGFa
+jqJcxKT6vNbsrp+YOlder0cZz7S+1qXkKP9iGuVUa6uG818pv4IZrrgWJP85ZUqj
+PV5Dy9QYQbd8HHxrDkWQ6xMdFM0049KZeNuKGnbv2gz27RUMf7U7eyj7QBuDCHwL
+Q3UHOXr5Db7bDepCOXBdjTxET2BzotOkn/pbNJN1wAa3UZB3ovFWo7vOwQCF1+nY
+AWAUxNm8W07SzBVZuCHxPsnMX8z501jz1f8yiKgDgG6JtCCESTIPnOj+7k+86eYV
+CXfgf3klgcruOTXCZwaUhQYEf7Rxyln8FoMD/5VoKWAIwUsbpMquhwbZmmq6nada
+owEctivvDKqlXNf5vREV76+OTpiFSpRDiX5cwWU/eG4pKDEyOnByb3RlY3RlZC1h
+dDE1OjIwMTQxMTA0VDA4NDMyMykpKQ==
+=3wKz
+-----END PGP ARMORED FILE-----
eddsa-sample-1-sec.asc Ditto, but as protected secret keyblock.
dda252ebb8ebe1af-1.asc rsa4096 key 1
dda252ebb8ebe1af-2.asc rsa4096 key 2 with a long keyid collision.
+whats-new-in-2.1.asc Collection of sample keys.
--- /dev/null
+These are the keys used in the whats-new-in-2.1 document. The private
+keys are in ../privkeys and protected with the passphrase "abc".
+
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2
+
+mQENBFRXu3wBCACvB4RPDJkf4kHR8OZHFmvC5u4XpxdSnYRd2eYgzXrqxaw0LIP0
+RRyW2jMlQswj/yXOGsrm9hc3knyXSl66TDwHWho5Wxi3WNPBXOPRPuzO/WEF4Mhl
+4U5t5GWvG8Pk32JyyQurJ8XnxuWEKhKb1f5n730Hel18Q3J/7uemAyeS6O8UV5p3
+eCH4+k9ZRdig0LQwAdb5aZ7sREH5wCPAvFKbMTlgtbUrkORyKBZ8KgBHxIhx/j9m
+LhxupuKMlH0+3Ndax3/EtNUfUCUAq9dQ5/VjACPyB3uuwbK2yAMRvvcngYSJBEoQ
+QcXTaiLdhZxPrE5kB7/romOMmt3Iet3b2edzABEBAAG0I0dsZW5uIEdyZWVud2Fs
+ZCA8Z2xlbm5AZXhhbXBsZS5vcmc+iQE3BBMBCAAhBQJUV7t8AhsDBQsJCAcCBhUI
+CQoLAgQWAgMBAh4BAheAAAoJEGNqG71o/QCIkEwIAKWeyVON5kWxC0gvwAyMBrma
+n96E9KACVLUlK5TSzrVilrpr73m0qqYrSL8DCBzUOUAe7HSXpcqwKkYxdq24UhHx
+z58JU7AHxYh8pKT0Cz7iUevAvA6v7Qppolvpf7OHjQbigWYY927/J70SnpINeVre
+VspDFyn2scYQSwduCTIVizB+dLigbgHpIDJ5dQ/PQ/2ofMs/np6m0E0oeQTL5b6B
+0cVJ+7DQIxZ+OU5RfGf/i5fEvADttheYOS3U8CmsvlyWkUUK3obUIDfj6pGz8BRO
+Ji1JjVvZ2WpcpSTU8htMxlcZAsnvhtv9F/KwwlvW8k0GMVsvTt21WjPAgc58j1K5
+AQ0EVFe7fAEIALWn703ukwPAklb9+e/m8qGu/XewzQ5fnciZy+YA71aO1L0vg5id
+BqmWWhUZ1H2jMLpSmHGTsWvwv7OpIgsPcyIqmlJ/hXNFxYI/xS8Y9AzFlASs+Dqm
+MOjBghE5crakHjS6JxtkBNK6efB3teA5WlD7oVJwhYMsUtkH8/OJq0Lml3sZaca3
+vDvm0CnEDlqr0pog6RiDxAmOgUO04ZcjaGVz9sb+U+coIe/qG1kJZFGdSpuV1BS7
+9nyjMnmMfNt2uB0w9v1hnGrvMU7q+OaaP/ii8+tI01WOGn+KQsJp89PwgcnA8y57
+Up3zN6pDl9WF80uJL/J3FIe8RuaE4VBv76sAEQEAAYkBHwQYAQgACQUCVFe7fAIb
+DAAKCRBjahu9aP0AiMT4CACJ/LyyvD3Z0g3ylzo57Fl5dKOgbR45owKuKIB70KoZ
+6tDGKmhWp/ZJqk25ZDzxGPaZKNnzj2pmZKgDW0WsXTpWlN9RXEEGglOvxC3wgm7p
+JQNSka8VbGujyc0RUM/CLuWr7O1NrXw/J4Fch1wbcFYVskI7OQO7UYPkAVlFRyB/
+FJVSpuQWnIjfffi7Z9lAk8tnzOMK+LdUJ3D2KupFYSqljWmzLEUAPY+FrGlSZ43U
+6G33FoYRQll4gzoQUUUDXBlzAxwGewvbuCNUI+YhcgVMmNNZPHz5IbSvE+oosIew
+LwG2NtCOIu5ceMnukLuo58u7sPkBhKlhsi5ltF0wXqF/mFIEVFfBNBMIKoZIzj0D
+AQcCAwQwjH9KY0S+5JWRfRerrQkE5NRPipOvfLA2pQ5JoqKOB1gqPCQgX6OkP7tN
+9Ja8zOchT9R53pZ1Guq1BuLgpXN0tCNFZHdhcmQgU25vd2RlbiA8ZWR3YXJkQGV4
+YW1wbGUub3JnPoh5BBMTCAAhBQJUV8E0AhsDBQsJCAcCBhUICQoLAgQWAgMBAh4B
+AheAAAoJENF5nnI4JmDjLWYBAO/m/yco7zu7mNlToHj3DEd1Ja0jQj5SZdCGgP7R
+5lnIAP0ZRzlUa458LdA4PbLEb4g2e1TduGkW0qoaC7Bb0huSUbhWBFRXwTQSCCqG
+SM49AwEHAgMEOx/Lj6ZzYdOMdprseVCR/dwZaYPeInquOlapE22Udwppy4tQqj2j
+XDYH8d0Z5uRvT/FD5lpcW+Cv+BAoo2auuwMBCAeIYQQYEwgACQUCVFfBNAIbDAAK
+CRDReZ5yOCZg4xsFAQDTK35zpEAe86ZZ7W/2sBqb1jHri1F1cfNWBaW0I40yXQEA
+5m4Hr2uu+5hb+fcdI9UFVc7rd/Lql3J4v8Sg3e5GVtiYMwRUV8PkFgkrBgEEAdpH
+DwEBB0CQEsCWLbe4idIaPa8ll84uhWHwuSkfqbsF0/HFqDArgrQhTGF1cmEgUG9p
+dHJhcyA8bGF1cmFAZXhhbXBsZS5vcmc+iHkEExYIACEFAlRXw+QCGwMFCwkIBwIG
+FQgJCgsCBBYCAwECHgECF4AACgkQqoExnlwa/CrojwD/Tx154eojS5dpLIJA0ckH
+/Xz3aUmj5bln1BhDgaifmBoA/RqPxVOfP4SXsUfqaR7TmaYpXnW4870yxtoObenY
+ptcFmQENBFRYkXMBCACqLZQyCg0hMryI5Fg3Rh0As5tXm0bcm9eS45JdezVeG4gw
+APtqjq8N0CUPugn1aQ/FxMoF6QRL9NelYBbgeTLCDRzRPeHSgFHNEdblMGZY3iDT
+0Nhf+9rd0hYogQRsGOABwzZ/84ukXDOycIyVv6ZJKnJr8tZAOZD9fFwOsIGPDbMg
+mvh/WSZuQSuuDEhlBHbHFspLh1Ft84Og3PG0k+joZaJHJUVofSlStEEW6p5UHlT/
+xPyr+C4Z21zQdhhNmHnGoeK72vzzatmGfQn8rkB8EiUIW9YdTCi4uewAGnIAIVej
+nEdYTOlntVYeSQxRI9NQ7CDAtdUtWcx2C10VgHnPABEBAAG0JkRhbmllbCBFbGxz
+YmVyZyA8ZWxsc2JlcmdAZXhhbXBsZS5vcmc+iQE3BBMBCAAhBQJUWJFzAhsDBQsJ
+CAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEHmy/xUtNRHxcRMH/iZ8HAkSd+U7r/z2
+De2h708tVYUqIXPZ1z35Tyfs6VQ7rLSscXrlJGssJDNrF4mKiKK+DjyKOA/omoos
+HXwpSRy1ERo1zkmJUiaizuGV1mCw49IugkrhmrTWacA5AvKPkRs+p0pZeqKnM6IJ
+VtrN62sA/EoBcoecbicW3swYiCzKROYNHiQMpojtshf0OP3lWT9s7jASaq0iz/t7
+iWtEkxOQJnuU2v+pt8uqDLWc0plQZpUGjktQZB5/h6vTpL9mqfnXTwwgvb/BVaG7
+KqmFMrJVjrB40NZtV2WbfS85jMMWUvsa0vrnfJgpuIvs8jH2TVVYw0Kvu5nhjM4j
+YjohWoe5AQ0EVFiRcwEIAM0QnGL35Fvz+RybOtdBOWPX8XHZ3CvPq0gr50pjtZGZ
+LjlDe5Jf8oX24cGBVdFdILOlOglXNJX6Qz5WxNrZtU53vDfkgjA8flQXFqIlkxv2
+ZkjKP2S+Vgr9LjbrFxxWRlZY+XqMNahEjbfA9gLr1GG8gM7ABsU7O03/pR2q7iF/
+aDMKm8asN7+k4/tW11e5yZeQkc+aBz8zbhBCZ90jdfQr5jHQsJx9EOlrCWvDcnGo
+jDXQBc2AflwuEJQHSHqPsy4E5KnMlpp8ZzFw2spfExWzNnEfZ/qQ9dXgnhdeNFmg
+/JRvgohreRExvO3yJiQMbH28UBTb/NBOe14F8j1XdfkAEQEAAYkBHwQYAQgACQUC
+VFiRcwIbDAAKCRB5sv8VLTUR8XybCACjbi+zlINJqoRPwDxukgfF60kW1wBMaSlN
+KajncxXSahlBFM0b++dPQi6DKNhXgR8kXH5ZI3538xs++4fBSg1lRQPKsYgsZhRn
+mg5eiujpQvZV4QgCvrshN8X97WKgcRXnYWcka90tqMCoZdMe5XntAix/ZNDuoZ2z
+7oNoA+9sg1Sxpu/bZXA47mL9KTL8Q08/4lzCYvEJHmUZh+eb/hn6ZYCSycydqfyd
+3J4zsE3nnt3v4DYrImqX9WEIO6FNgpWNLIHFINhRBxPvYYoDkuvm0RxLbYxcpHoT
+Z56rlwGTf0ZazFHfsGZYflJapvPWVTjkFJmB69oRyD5aMLQH1vsbmQENBFRYkaUB
+CADMAob60PU1HD7QW3ytFFjrdhma86uyNGYXI36MRg+FF8SjQcR3Mm9nEGE4ebRe
+F6iL/XdksrNXOH1Nka+pZzw3OlaUiyqB2Y++o1pHFlX/NPjFxTVaf2KhK0ATLvwJ
+APwsJN4RII6kCGTqPWsHwQEyahplvctwrdSFfKDOklDo2EPAnCGto6UjTava4V0I
+802FGRyuGsk5o5j77qksVmoVLDmQpQNxh6S2ZBXvZNlCblSFH4cGA+AsiEdZ6pRX
+4/O6f1BD7NduuP0aQWoM+Bu+AYi4Yh0LLPDV5tc1okWdcT8iSJKw5uNiUUPuoBn9
+ar5Nrckty3uFvu7IN69PFBMTABEBAAG0LURhbmllbCBFbGxzYmVyZyA8ZGFuaWVs
+LmVsbHNiZXJnQGV4YW1wbGUub3JnPokBNwQTAQgAIQUCVFiRpQIbAwULCQgHAgYV
+CAkKCwIEFgIDAQIeAQIXgAAKCRDMU3ZHkRuQqXyXCADDmu4ilC5JxJS1yKDRnktT
+HVCm+wtY2N3Jq8mJ1LGflHlG2u2CNHKBsEGTOzNQ7I2XHmlZcJ9UodcRxjVDIWHw
+W14zcRyFZov43cpokU8zRqlxeFzirT8vokGltQxRn36yJfB/F4eSCLULCnLIAQJ8
+TNhRcIC977k/sNC2dlXSus2KLNdlDXusZR4WgwGeVShXtnr0HLirt8JzdX/564nq
+4bpcuUqC/uryVy3vU3McAJ5YeCmjRN6Ep5NhphXhnYXczgn5SD90Ka6LfS8ssSd7
+DNFoEANZAHPhJyhoPo9hRPGF3x8PeuhoXRzyHg7qAU05aqNpT3B4ceQwMRIAmMsP
+uQENBFRYkaUBCACuQEgMHcb5tcdLA9T1QI1QhIKNqKk95oP6J6KY97d3VZQbhL9t
+3/ufxKC0xCABPLpRgwgUEcO9F4+HuQfO6HOQ8QbNrojBmwl/C+3BELl1UUa8EEeZ
+CSOtogpXtaa3oXV01hYGVAV8EOtBgBnn7fzJs561DeKstare3afHqjqvaJ/cQPLi
+s4oAmBI0bBnknKxXnQHpoNLKOgFmwks+ktQW2SsWD4pWxu1TL6QNuJID6kIommRE
+pRbe4nstOFhPb9urx+QhMVahZfjPrQBiD8ON/V9JXiKXYnU1hXURMOwwpEQY2fHF
+myxCH4RK3KNZqpUsUdQL5Ul528sXqx0ETvirABEBAAGJAR8EGAEIAAkFAlRYkaUC
+GwwACgkQzFN2R5EbkKlADAf+JjJbbo4FTeQG5qRtZCEfnJgcpQxF4Tnw/QTaENhC
+zr9nO9tBbzbo290ALB6sKt8EbTRIG8JidenhZkm89O7L7wNJh9aIl+yttNFD1Zrr
+YqbniAFAuQg/7xOy9xmt0vJOOdUQYYM4wzcIpQSy56AukLxv/phvNxBuL2HyTY38
+kadMDVc3BO1uMhFtSxsc23HACJIpH0UEGktNGqzePwiIaOA/bnpnyE1HCOZKg4Et
++eXf2eBqq0dO/vwTTK7aqRC+r4PGaQfJkvhuC1Sm0pFAs0Z9AaqaHodHHnS5S8EB
+ePMsSVCko5io9YQiQNbrIvw2U9z18kGzGsqGAqmqahd2spkBDQRUWJLxAQgA8vUU
+lUCBU4SI4uqCaoJZwKAh+XcVP+kFoslgs7w16uxG7KBDoCsB01hqv+Hwwqc6RgLC
+UhKvd+km2Ppyk+vPohTUrT0dgSlVzqfVRsPmvbmwNz06XzO2DlA9U/5x4DjafOkc
+CcwBbsT13PmCwz8fpOWJwXio5Pes5+kGoPHUQc5o5Lql2d6btLBJBnpEV60mi2Re
+oQV9I1WUxMuqrKx+TmRRb6OfsHgmWl3tha2Vouw9fJjV0XCLbhWqkiLO05hGhYU5
+vJKulmTC48aRDk/8SqL/b4vtUpc184NEjQ1XoZfUVpD3qUirRj7PURaiMvA9v0lH
+YUsaoL7j+ab9btSd/QARAQABtCZEYW5pZWwgRWxsc2JlcmcgPGVsbHNiZXJnQGV4
+YW1wbGUub3JnPokBNwQTAQgAIQUCVFiS8QIbAwULCQgHAgYVCAkKCwIEFgIDAQIe
+AQIXgAAKCRDMALUBvRmsHEcKCADbrI4XqQ2tDLGJ34X/sd35NZoe4ytGZX8MRwsv
+IuqWWvXiyczGLF+DB5hehMtuzVDtCBnaeWDqSg0XwaRm+QeR899LI0j4AADStC2T
+5kVgQxFUH6PABDjPxf2kMnEDfLPES5Ac9abLXhVI523rpOrlw2vINC8ooll/gSJk
+rRJNmhU7nov5PAKlBolYoYWO0+lgJ6qgv+1V2/4y3pCHr/JUKMXsN6sdKnBMWBuJ
+Gw6uXAB7Do268SAYxJwS2FIkCYUvS8B9io2kp6CWAMrXeYmyBoBJcZN9PpS4Y7C7
+Z750z8eHzk+KXK8KZGSpMi64GwN5USD946al6vbXgtAFN5dEiQEcBBABCAAGBQJU
+WJORAAoJEGNqG71o/QCIXeUH/RVFAj2ZFTOGscvlX+KNawmV5vxuK2ccf/voff6R
+NhPdZ1WblB7CocJPbJJ7c32lBPSlyL7apTZQMKvzry6U/KnWAiO11uTVn82+vDbu
+kXkpzF1KSv3UsEsUT3q03BR1BJxZwJhTovmwHjedXehPWTdI0+lOXq7YUqicTHN0
+7bfdnUe1wTogMzvSqBxVgh71pQ1hfdl7/FHeNEdIwqU0Q+YJDBhV1QsRPJ2cVRGg
+X9yp/HGTdmXZNCPKPzNqi+klEn8xT3VjAXfVkg4s7hWnkFtYr3a0kqtzSxMzvNcM
+VRY+KKxWICsTg5HIun53rlVeJfSfyI1BpQ3XQmJk9ro4P9q5AQ0EVFiS8QEIAL8O
+ibB/4Jrvyu3WLmT9knI/wEmxSjU6PXn7xCyDgxXd45szIKV3uURsYVsexrIRr5y+
+uijOWq2JFunrhNV4sCGpRAnS3EA1y1zqFx7Ob0/k4bLvNn8UFNtblIlxqSjT2Oz2
+T5+4GAmeVo7Z49keWryDyMeo+J1cio0NacBwR5Ee+DL6NfGoSyYYHrrQOn9PCnAS
+R/I7THMP4l729yHnVNHnsgA1t/plvgXJj2Vf4KTu8NFaXFbd5a2gW14+nv2kUTen
+QuHs3Nn9d9NQeXSZ3tWP7FvthgklO3bp+dmjbynDKacKQGWKFyYlnx/qNKRe9Wnr
+59vVSeyktyA0pbyvYNcAEQEAAYkBHwQYAQgACQUCVFiS8QIbDAAKCRDMALUBvRms
+HEEKB/9b+NMLDsBnNZUvJq/TEsD6vQ3IfVL9+YRh4H85iVYd+gNj3S2GlN8+3x3u
+wOik27PsWI3EZiLApMfvQdlj3xdQncjs6oApcpa8nVVWxAq0UDE5BRXOAwtXvlao
+pKPHRWyZQCJEBuNocNLGUb4l5LLKqWmKiJpHXYZKqjqfdJxVac/XLtg7Vujc1SBl
+hct7pyWb6stY1K0cR/UDqlYu/uMihHhga4W6ViMme9dM7vk/F32U4hGOoy+6SljW
+VTJUnf2N1X8vnPxJ4/vV7nEL/6NXsQzacvJ82cFfp1mFOFgdtGSVldAcJHgTEpbX
+PTgzPpanbg78WYNuT7+ZqlZYqj13
+=44AC
+-----END PGP PUBLIC KEY BLOCK-----
{ "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME,
GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing",
GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+ { "allow-emacs-pinentry", GC_OPT_FLAG_RUNTIME,
+ GC_LEVEL_ADVANCED,
+ "gnupg", "allow passphrase to be prompted through Emacs",
+ GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
{ "no-allow-external-cache", GC_OPT_FLAG_RUNTIME,
GC_LEVEL_BASIC, "gnupg", "disallow the use of an external password cache",
GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },