Merge branch 'master' into justus/pyme3

This commit is contained in:
Justus Winter 2016-05-10 13:03:34 +02:00
commit f531608539
64 changed files with 3302 additions and 988 deletions

View File

@ -3,7 +3,7 @@ Homepage: http://www.gnupg.org/related_software/gpgme/
Download: ftp://ftp.gnupg.org/gcrypt/gpgme/
Repository: git://git.gnupg.org/gpgme.git
Maintainer: Werner Koch <wk@gnupg.org>
Bug reports: http://bugs.gnupg.org (use category "gpgme")
Bug reports: https://bugs.gnupg.org (use category "gpgme")
Security related bug reports: security@gnupg.org
License (software): LGPLv2.1+
License (manual+tools): GPLv3+

52
NEWS
View File

@ -1,6 +1,56 @@
Noteworthy changes in version 1.6.0 (unreleased) [C__/A__/R_]
Noteworthy changes in version 1.6.1 (unreleased) [C25/A14/R_]
------------------------------------------------
* New function to format a GnuPG style public key algorithm string.
* Interface changes relative to the 1.6.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_pubkey_algo_string NEW.
GPGME_PK_EDDSA NEW.
Noteworthy changes in version 1.6.0 (2015-08-26) [C25/A14/R0]
------------------------------------------------
* Added gpgme_set_offline to do a key listinging w/o requiring CRL.
* Added gpgme_set_status_cb to allow a user to see some status
messages.
* Added an export mode for secret keys.
* More precise error codes are returned if GnuPG >= 2.1.8 is used.
* The passphrase handler for the loopback mode has been improved and may
also be used with genkey.
* [w32] The standard GnuPG 2.1 install directory is now seached for
gpgconf.exe before a registry specified directory and the Gpg4win
install directory.
* [w32] gpgme-w32spawn.exe will now only be searched in the gpgme DLL
directory.
* Interface changes relative to the 1.5.1 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_set_offline NEW.
gpgme_get_offline NEW.
gpgme_set_status_cb NEW.
gpgme_get_status_cb NEW.
GPGME_EXPORT_MODE_SECRET NEW
GPGME_EXPORT_MODE_RAW NEW.
GPGME_EXPORT_MODE_PKCS12 NEW.
Noteworthy changes in version 1.5.5 (2015-06-08) [C24/A13/R4]
------------------------------------------------
* Fixed crash in key listings for user ids with a backslash.
* Fixed regression for GPGSM use with GnuPG < 2.1.
* Properly set signature summary for revoked OpenPGP keys.
Noteworthy changes in version 1.5.4 (2015-04-13) [C24/A13/R3]
------------------------------------------------

View File

@ -86,11 +86,17 @@ sub check_msg($$)
2 <= @line && length $line[1]
and return 'second line must be empty';
# See git-commit(1), this is the --cleanup=scissors option. Everything
# after and including this line gets ignored.
my $marker = '# ------------------------ >8 ------------------------';
# Limit line length to allow for the ChangeLog's leading TAB.
foreach my $line (@line)
{
72 < length $line && $line =~ /^[^#]/
and return 'line longer than 72 characters';
last if $line eq $marker;
}
return '';

View File

@ -1,7 +1,7 @@
# configure.ac for GPGME
# Copyright (C) 2000 Werner Koch (dd9jn)
# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
# 2009, 2010, 2011, 2012, 2013 g10 Code GmbH
# 2009, 2010, 2011, 2012, 2013, 2014, 2015 g10 Code GmbH
#
# This file is part of GPGME.
#
@ -29,7 +29,7 @@ min_automake_version="1.14"
# for the LT versions.
m4_define(mym4_version_major, [1])
m4_define(mym4_version_minor, [6])
m4_define(mym4_version_micro, [0])
m4_define(mym4_version_micro, [1])
# Below is m4 magic to extract and compute the revision number, the
# decimalized short revision number, a beta version string, and a flag
@ -55,11 +55,11 @@ AC_INIT([gpgme],[mym4_full_version],[http://bugs.gnupg.org])
# (Interfaces added: AGE++)
# (Interfaces removed/changed: AGE=0)
#
LIBGPGME_LT_CURRENT=24
LIBGPGME_LT_CURRENT=25
# Subtract 2 from this value if you want to make the LFS transition an
# ABI break. [Note to self: Remove this comment with the next regular break.]
LIBGPGME_LT_AGE=13
LIBGPGME_LT_REVISION=3
LIBGPGME_LT_AGE=14
LIBGPGME_LT_REVISION=0
# If the API is changed in an incompatible way: increment the next counter.
GPGME_CONFIG_API_VERSION=1
@ -260,11 +260,21 @@ changequote([,])dnl
BUILD_FILEVERSION="${BUILD_FILEVERSION}mym4_revision_dec"
AC_SUBST(BUILD_FILEVERSION)
BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
AC_ARG_ENABLE([build-timestamp],
AC_HELP_STRING([--enable-build-timestamp],
[set an explicit build timestamp for reproducibility.
(default is the current time in ISO-8601 format)]),
[if test "$enableval" = "yes"; then
BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
else
BUILD_TIMESTAMP="$enableval"
fi],
[BUILD_TIMESTAMP="<none>"])
AC_SUBST(BUILD_TIMESTAMP)
AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP",
[The time this package was configured for a build])
#
# Options to disable some regression tests
#

View File

@ -23,11 +23,34 @@
the big picture. Omit the leading TABs that you're used to seeing
in a "real" ChangeLog file, but keep the maximum line length at 72
or smaller, so that the generated ChangeLog lines, each with its
leading TAB, will not exceed 80 columns.
leading TAB, will not exceed 80 columns. If you want to add text
which shall not be copied to the ChangeLog, separate it by a line
consisting of two dashes at the begin of a line.
Note that ./autogen.sh installs a git hook to do some basic syntax
checking on the commit log message.
Typo fixes and documentation updates don't need a ChangeLog entry;
thus you would use a commit message like
#+begin_example
Fix typo in a comment
--
#+end_example
The marker line here is important; without it the first line would
appear in the ChangeLog.
If you exceptionally need to have longer lines in a commit log you may
do this after this scissor line:
#+begin_example
# ------------------------ >8 ------------------------
#+end_example
(hash, blank, 24 dashes, blank, scissor, blank, 24 dashes).
Note that such a comment will be removed if the git commit option
=--cleanup-scissor= is used.
** License policy
GPGME is currently licensed under the LGPLv2.1+ with tools and the
@ -73,6 +96,29 @@
need. If you really need to do it, use a separate commit for such a
change.
- C99 syntax should not be used; stick to C90.
- Please do not use C++ =//= style comments.
- Try to fit lines into 80 columns.
- Ignore signed/unsigned pointer mismatches
- No arithmetic on void pointers; cast to char* first.
** Commit log keywords
- GnuPG-bug-id :: Values are comma or space delimited bug numbers
from bug.gnupg.org pertaining to this commit.
- Debian-bug-id :: Same as above but from the Debian bug tracker.
- CVE-id :: CVE id number pertaining to this commit.
- Regression-due-to :: Commit id of the regression fixed by this commit.
- Fixes-commit :: Commit id this commit fixes.
- Reported-by :: Value is a name or mail address of a bug reporte.
- Suggested-by :: Value is a name or mail address of someone how
suggested this change.
- Co-authored-by :: Name or mail address of a co-author
- Some-comments-by :: Name or mail address of the author of
additional comments (commit log or code).
- Proofread-by :: Sometimes used by translation commits.
- Signed-off-by :: Name or mail address of the developer
* Debug hints
- Use gpgme-tool for manual tests.

View File

@ -189,10 +189,12 @@ Context Attributes
* Crypto Engine:: Configuring the crypto engine.
* ASCII Armor:: Requesting @acronym{ASCII} armored output.
* Text Mode:: Choosing canonical text mode.
* Offline Mode:: Choosing offline mode.
* Included Certificates:: Including a number of certificates.
* Key Listing Mode:: Selecting key listing mode.
* Passphrase Callback:: Getting the passphrase from the user.
* Progress Meter Callback:: Being informed about the progress.
* Status Message Callback:: Status messages received from gpg.
* Locale:: Setting the locale of a context.
Key Management
@ -699,6 +701,16 @@ directory part is used as the default installation directory; the
@code{.exe} suffix is added by GPGME. Use forward slashed even under
Windows.
@item "w32-inst-dir"
On Windows GPGME needs to know its installation directory to find its
spawn helper. This is in general no problem because a DLL has this
information. Some applications however link statically to GPGME and
thus GPGME can only figure out the installation directory of this
application which may be wrong in certain cases. By supplying an
installation directory as value to this flag, GPGME will assume that
that directory is the installation directory. This flag has no effect
on non-Windows platforms.
@end table
This function returns @code{0} on success. In contrast to other
@ -1159,6 +1171,9 @@ Algorithm as defined by FIPS 186-2 and RFC-6637.
This value indicates ECDH, the Eliptic Curve Diffie-Hellmann
encryption algorithm as defined by RFC-6637.
@item GPGME_PK_EDDSA
This value indicates the EdDSA algorithm.
@end table
@end deftp
@ -1172,6 +1187,14 @@ If @var{algo} is not a valid public key algorithm, @code{NULL} is
returned.
@end deftypefun
@deftypefun {char *} gpgme_pubkey_algo_string (@w{gpgme_subkey_t @var{key}})
The function @code{gpgme_pubkey_algo_string} is a convenience function
to build and return an algorithm string in the same way GnuPG does
(e.g. ``rsa2048'' or ``ed25519''). The caller must free the result
using @code{gpgme_free}. On error (e.g. invalid argument or memory
exhausted), the function returns NULL and sets @code{ERRNO}.
@end deftypefun
@node Hash Algorithms
@section Hash Algorithms
@ -1952,9 +1975,11 @@ case, the data object @var{dh} is destroyed.
@deftypefun void gpgme_free (@w{void *@var{buffer}})
The function @code{gpgme_free} releases the memory returned by
@code{gpgme_data_release_and_get_mem}. It should be used instead of
the system libraries @code{free} function in case different allocators
are used in a single program.
@code{gpgme_data_release_and_get_mem} and
@code{gpgme_pubkey_algo_string}. It should be used instead of the
system libraries @code{free} function in case different allocators are
used by a program. This is often the case if gpgme is used under
Windows as a DLL.
@end deftypefun
@ -2285,10 +2310,12 @@ started. In fact, these references are accessed through the
* Crypto Engine:: Configuring the crypto engine.
* ASCII Armor:: Requesting @acronym{ASCII} armored output.
* Text Mode:: Choosing canonical text mode.
* Offline Mode:: Choosing offline mode.
* Included Certificates:: Including a number of certificates.
* Key Listing Mode:: Selecting key listing mode.
* Passphrase Callback:: Getting the passphrase from the user.
* Progress Meter Callback:: Being informed about the progress.
* Status Message Callback:: Status messages received from gpg.
* Locale:: Setting the locale of a context.
@end menu
@ -2413,6 +2440,37 @@ valid pointer.
@end deftypefun
@node Offline Mode
@subsection Offline Mode
@cindex context, offline mode
@cindex offline mode
@deftypefun void gpgme_set_offline (@w{gpgme_ctx_t @var{ctx}}, @w{int @var{yes}})
The function @code{gpgme_set_offline} specifies if offline mode
should be used. By default, offline mode is not used.
The offline mode specifies if dirmngr should be used to do additional
validation that might require connections to external services.
(e.g. CRL / OCSP checks).
Offline mode only affects the keylist mode @code{GPGME_KEYLIST_MODE_VALIDATE}
and is only relevant to the CMS crypto engine. Offline mode
is ignored otherwise.
This option may be extended in the future to completely disable
the use of dirmngr for any engine.
Offline mode is disabled if @var{yes} is zero, and enabled
otherwise.
@end deftypefun
@deftypefun int gpgme_get_offline (@w{gpgme_ctx_t @var{ctx}})
The function @code{gpgme_get_offline} returns 1 if offline
mode is enabled, and @code{0} if it is not, or if @var{ctx} is not a
valid pointer.
@end deftypefun
@node Included Certificates
@subsection Included Certificates
@cindex certificates, included
@ -2642,6 +2700,43 @@ the corresponding value will not be returned.
@end deftypefun
@node Status Message Callback
@subsection Status Message Callback
@cindex callback, status message
@cindex status message callback
@deftp {Data type} {gpgme_error_t (*gpgme_status_cb_t)(void *@var{hook}, const char *@var{keyword}, const char *@var{args})}
@tindex gpgme_status_cb_t
The @code{gpgme_status_cb_t} type is the type of function usable as
a status message callback function.
The argument @var{keyword} is the name of the status message while the
@var{args} argument contains any arguments for the status message.
If an error occurs, return the corresponding @code{gpgme_error_t}
value. Otherwise, return @code{0}.
@end deftp
@deftypefun void gpgme_set_status_cb (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_status_cb_t @var{statusfunc}}, @w{void *@var{hook_value}})
The function @code{gpgme_set_status_cb} sets the function that is used when a
status message is received from gpg to @var{statusfunc}. The function
@var{statusfunc} needs to be implemented by the user, and whenever it is
called, it is called with its first argument being @var{hook_value}. By
default, no status message callback function is set.
The user can disable the use of a status message callback function by calling
@code{gpgme_set_status_cb} with @var{statusfunc} being @code{NULL}.
@end deftypefun
@deftypefun void gpgme_get_status_cb (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_status_cb_t *@var{statusfunc}}, @w{void **@var{hook_value}})
The function @code{gpgme_get_status_cb} returns the function that is used to
process status messages from gpg in @var{*statusfunc}, and the first argument
for this function in @var{*hook_value}. If no status message callback is set,
or @var{ctx} is not a valid pointer, @code{NULL} is returned in both
variables.
@end deftypefun
@node Locale
@subsection Locale
@cindex locale, default
@ -2766,7 +2861,7 @@ True if the secret key is stored on a smart card.
The serial number of a smart card holding this key or @code{NULL}.
@item char *curve
For ECC algoritms the name of the curve.
For ECC algorithms the name of the curve.
@end table
@end deftp
@ -3628,6 +3723,21 @@ keys it removes all signatures except for the latest self-signatures.
For X.509 keys it has no effect.
@item GPGME_EXPORT_MODE_SECRET
Instead of exporting the public key, the secret key is exported. This
may not be combined with @code{GPGME_EXPORT_MODE_EXTERN}. For X.509
the export format is PKCS#8.
@item GPGME_EXPORT_MODE_RAW
If this flag is used with @code{GPGME_EXPORT_MODE_SECRET} for an X.509
key the export format will be changed to PKCS#1. This flag may not be
used with OpenPGP.
@item GPGME_EXPORT_MODE_PKCS12
If this flag is used with @code{GPGME_EXPORT_MODE_SECRET} for an X.509
key the export format will be changed to PKCS#12 which also includes
the certificate. This flag may not be used with OpenPGP.
@end table
@ -3700,7 +3810,7 @@ for the context @var{ctx}, or, if that is not set, by the encoding
specified for @var{keydata}.
The keys to export are taken form the @code{NULL} terminated array
@var{keys}. Only keys of the the currently selected protocol of
@var{keys}. Only keys of the currently selected protocol of
@var{ctx} which do have a fingerprint set are considered for export.
Other keys specified by the @var{keys} are ignored. In particular
OpenPGP keys retrieved via an external key listing are not included.
@ -3773,7 +3883,7 @@ permanent which have been retrieved from an external source (i.e. using
for the usual workaround of exporting and then importing a key to make
an X.509 key permanent.}
Only keys of the the currently selected protocol of @var{ctx} are
Only keys of the currently selected protocol of @var{ctx} are
considered for import. Other keys specified by the @var{keys} are
ignored. As of now all considered keys must have been retrieved using
the same method, that is the used key listing mode must be identical.
@ -3860,34 +3970,34 @@ The number of keys without user ID.
@item int imported
The total number of imported keys.
@item imported_rsa
@item int imported_rsa
The number of imported RSA keys.
@item unchanged
@item int unchanged
The number of unchanged keys.
@item new_user_ids
@item int new_user_ids
The number of new user IDs.
@item new_sub_keys
@item int new_sub_keys
The number of new sub keys.
@item new_signatures
@item int new_signatures
The number of new signatures.
@item new_revocations
@item int new_revocations
The number of new revocations.
@item secret_read
@item int secret_read
The total number of secret keys read.
@item secret_imported
@item int secret_imported
The number of imported secret keys.
@item secret_unchanged
@item int secret_unchanged
The number of unchanged secret keys.
@item not_imported
@item int not_imported
The number of keys not imported.
@item gpgme_import_status_t imports
@ -6037,16 +6147,16 @@ operation in the context @var{ctx}. This only works if you use the
global event loop or your own event loop.
If you use the global event loop, you must not call @code{gpgme_wait}
or @code{gpgme_wait} during cancellation. After successful
during cancellation. After successful
cancellation, you can call @code{gpgme_wait} (optionally waiting on
@var{ctx}), and the context @var{ctx} will appear as if it had
finished with the error code @code{GPG_ERR_CANCEL}.
If you use your an external event loop, you must ensure that no I/O
If you use an external event loop, you must ensure that no I/O
callbacks are invoked for this context (for example by halting the
event loop). On successful cancellation, all registered I/O callbacks
for this context will be unregistered, and a @code{GPGME_EVENT_DONE}
event with the error code @code{GPG_ERR_CANCEL} will be signaled.
event with the error code @code{GPG_ERR_CANCEL} will be signalled.
The function returns an error code if the cancellation failed (in this
case the state of @var{ctx} is not modified).
@ -6116,15 +6226,15 @@ you run your tests only with play data.
@include gpl.texi
@node Function and Data Index
@unnumbered Function and Data Index
@printindex fn
@node Concept Index
@unnumbered Concept Index
@printindex cp
@node Function and Data Index
@unnumbered Function and Data Index
@printindex fn
@bye

View File

@ -1,7 +1,7 @@
@node Library Copying
@unnumbered GNU Lesser General Public License
@cindex LGPL, Lesser General Public License
@cindex LGPL, GNU Lesser General Public License
@center Version 2.1, February 1999
@display
@ -16,7 +16,7 @@ as the successor of the GNU Library Public License, version 2, hence the
version number 2.1.]
@end display
@section Preamble
@heading Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@ -119,7 +119,7 @@ former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
@iftex
@section TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@heading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end iftex
@ifinfo
@center GNU LESSER GENERAL PUBLIC LICENSE
@ -476,12 +476,7 @@ decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
@iftex
@heading NO WARRANTY
@end iftex
@ifinfo
@center NO WARRANTY
@end ifinfo
@item
BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
@ -515,7 +510,7 @@ DAMAGES.
@end ifinfo
@page
@section How to Apply These Terms to Your New Libraries
@heading How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that

View File

@ -128,6 +128,7 @@ endif
AM_CPPFLAGS = @GPG_ERROR_CFLAGS@ @QT4_CORE_CFLAGS@
AM_CFLAGS = @LIBASSUAN_CFLAGS@ @GLIB_CFLAGS@ @QT4_CORE_CFLAGS@
gpgme_tool_SOURCES = gpgme-tool.c argparse.c argparse.h
gpgme_tool_LDADD = libgpgme.la @LIBASSUAN_LIBS@

1609
src/argparse.c Normal file

File diff suppressed because it is too large Load Diff

203
src/argparse.h Normal file
View File

@ -0,0 +1,203 @@
/* argparse.h - Argument parser for option handling.
* Copyright (C) 1998,1999,2000,2001,2006 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 either
*
* - the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at
* your option) any later version.
*
* or
*
* - the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* or both in parallel, as here.
*
* 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 copies of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GNUPG_COMMON_ARGPARSE_H
#define GNUPG_COMMON_ARGPARSE_H
#include <stdio.h>
typedef struct
{
int *argc; /* Pointer to ARGC (value subject to change). */
char ***argv; /* Pointer to ARGV (value subject to change). */
unsigned int flags; /* Global flags. May be set prior to calling the
parser. The parser may change the value. */
int err; /* Print error description for last option.
Either 0, ARGPARSE_PRINT_WARNING or
ARGPARSE_PRINT_ERROR. */
int r_opt; /* Returns option code. */
int r_type; /* Returns type of option value. */
union {
int ret_int;
long ret_long;
unsigned long ret_ulong;
char *ret_str;
} r; /* Return values */
struct {
int idx;
int inarg;
int stopped;
const char *last;
void *aliases;
const void *cur_alias;
void *iio_list;
} internal; /* Private - do not change. */
} ARGPARSE_ARGS;
typedef struct
{
int short_opt;
const char *long_opt;
unsigned int flags;
const char *description; /* Optional option description. */
} ARGPARSE_OPTS;
/* Global flags (ARGPARSE_ARGS). */
#define ARGPARSE_FLAG_KEEP 1 /* Do not remove options form argv. */
#define ARGPARSE_FLAG_ALL 2 /* Do not stop at last option but return
remaining args with R_OPT set to -1. */
#define ARGPARSE_FLAG_MIXED 4 /* Assume options and args are mixed. */
#define ARGPARSE_FLAG_NOSTOP 8 /* Do not stop processing at "--". */
#define ARGPARSE_FLAG_ARG0 16 /* Do not skip the first arg. */
#define ARGPARSE_FLAG_ONEDASH 32 /* Allow long options with one dash. */
#define ARGPARSE_FLAG_NOVERSION 64 /* No output for "--version". */
#define ARGPARSE_FLAG_STOP_SEEN 256 /* Set to true if a "--" has been seen. */
/* Flags for each option (ARGPARSE_OPTS). The type code may be
ORed with the OPT flags. */
#define ARGPARSE_TYPE_NONE 0 /* Does not take an argument. */
#define ARGPARSE_TYPE_INT 1 /* Takes an int argument. */
#define ARGPARSE_TYPE_STRING 2 /* Takes a string argument. */
#define ARGPARSE_TYPE_LONG 3 /* Takes a long argument. */
#define ARGPARSE_TYPE_ULONG 4 /* Takes an unsigned long argument. */
#define ARGPARSE_OPT_OPTIONAL (1<<3) /* Argument is optional. */
#define ARGPARSE_OPT_PREFIX (1<<4) /* Allow 0x etc. prefixed values. */
#define ARGPARSE_OPT_IGNORE (1<<6) /* Ignore command or option. */
#define ARGPARSE_OPT_COMMAND (1<<7) /* The argument is a command. */
#define ARGPARSE_TYPE_MASK 7 /* Mask for the type values (internal). */
/* A set of macros to make option definitions easier to read. */
#define ARGPARSE_x(s,l,t,f,d) \
{ (s), (l), ARGPARSE_TYPE_ ## t | (f), (d) }
#define ARGPARSE_s(s,l,t,d) \
{ (s), (l), ARGPARSE_TYPE_ ## t, (d) }
#define ARGPARSE_s_n(s,l,d) \
{ (s), (l), ARGPARSE_TYPE_NONE, (d) }
#define ARGPARSE_s_i(s,l,d) \
{ (s), (l), ARGPARSE_TYPE_INT, (d) }
#define ARGPARSE_s_s(s,l,d) \
{ (s), (l), ARGPARSE_TYPE_STRING, (d) }
#define ARGPARSE_s_l(s,l,d) \
{ (s), (l), ARGPARSE_TYPE_LONG, (d) }
#define ARGPARSE_s_u(s,l,d) \
{ (s), (l), ARGPARSE_TYPE_ULONG, (d) }
#define ARGPARSE_o(s,l,t,d) \
{ (s), (l), (ARGPARSE_TYPE_ ## t | ARGPARSE_OPT_OPTIONAL), (d) }
#define ARGPARSE_o_n(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_OPTIONAL), (d) }
#define ARGPARSE_o_i(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_INT | ARGPARSE_OPT_OPTIONAL), (d) }
#define ARGPARSE_o_s(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_STRING | ARGPARSE_OPT_OPTIONAL), (d) }
#define ARGPARSE_o_l(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_LONG | ARGPARSE_OPT_OPTIONAL), (d) }
#define ARGPARSE_o_u(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_ULONG | ARGPARSE_OPT_OPTIONAL), (d) }
#define ARGPARSE_p(s,l,t,d) \
{ (s), (l), (ARGPARSE_TYPE_ ## t | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_p_n(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_p_i(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_INT | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_p_s(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_STRING | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_p_l(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_LONG | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_p_u(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_ULONG | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_op(s,l,t,d) \
{ (s), (l), (ARGPARSE_TYPE_ ## t \
| ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_op_n(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_NONE \
| ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_op_i(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_INT \
| ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_op_s(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_STRING \
| ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_op_l(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_LONG \
| ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_op_u(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_ULONG \
| ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
#define ARGPARSE_c(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_COMMAND), (d) }
#define ARGPARSE_ignore(s,l) \
{ (s), (l), (ARGPARSE_OPT_IGNORE), "@" }
#define ARGPARSE_group(s,d) \
{ (s), NULL, 0, (d) }
#define ARGPARSE_end() { 0, NULL, 0, NULL }
/* Other constants. */
#define ARGPARSE_PRINT_WARNING 1
#define ARGPARSE_PRINT_ERROR 2
/* Error values. */
#define ARGPARSE_IS_ARG (-1)
#define ARGPARSE_INVALID_OPTION (-2)
#define ARGPARSE_MISSING_ARG (-3)
#define ARGPARSE_KEYWORD_TOO_LONG (-4)
#define ARGPARSE_READ_ERROR (-5)
#define ARGPARSE_UNEXPECTED_ARG (-6)
#define ARGPARSE_INVALID_COMMAND (-7)
#define ARGPARSE_AMBIGUOUS_OPTION (-8)
#define ARGPARSE_AMBIGUOUS_COMMAND (-9)
#define ARGPARSE_INVALID_ALIAS (-10)
#define ARGPARSE_OUT_OF_CORE (-11)
#define ARGPARSE_INVALID_ARG (-12)
int arg_parse (ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
int optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
void usage (int level);
const char *strusage (int level);
void set_strusage (const char *(*f)( int ));
void argparse_register_outfnc (int (*fnc)(int, const char *));
#endif /*GNUPG_COMMON_ARGPARSE_H*/

View File

@ -98,6 +98,9 @@ struct gpgme_context
/* True if text mode should be used. */
unsigned int use_textmode : 1;
/* True if offline mode should be used. */
unsigned int offline : 1;
/* Flags for keylist mode. */
gpgme_keylist_mode_t keylist_mode;
@ -132,6 +135,10 @@ struct gpgme_context
gpgme_progress_cb_t progress_cb;
void *progress_cb_value;
/* The user provided status callback and its hook value. */
gpgme_status_cb_t status_cb;
void *status_cb_value;
/* A list of file descriptors in active use by the current
operation. */
struct fd_table fdt;

View File

@ -427,6 +427,7 @@ _gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol)
case 18: algo = GPGME_PK_ECDH; break;
case 19: algo = GPGME_PK_ECDSA; break;
case 20: break;
case 22: algo = GPGME_PK_EDDSA; break;
default: algo = 0; break; /* Unknown. */
}
}

View File

@ -146,7 +146,7 @@ gpgme_data_new_from_file (gpgme_data_t *r_dh, const char *fname, int copy)
static int
gpgme_error_to_errno (gpgme_error_t err)
{
int res = gpg_err_code_to_errno (err);
int res = gpg_err_code_to_errno (gpg_err_code (err));
if (!err)
{

View File

@ -271,7 +271,8 @@ gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len)
}
/* Release the memory returned by gpgme_data_release_and_get_mem(). */
/* Release the memory returned by gpgme_data_release_and_get_mem() and
some other functions. */
void
gpgme_free (void *buffer)
{

View File

@ -46,6 +46,7 @@
#include "util.h"
#include "ath.h"
#include "sema.h"
#include "sys-util.h"
#include "debug.h"
@ -80,11 +81,12 @@ _gpgme_debug_frame_begin (void)
#endif
}
void _gpgme_debug_frame_end (void)
int _gpgme_debug_frame_end (void)
{
#ifdef FRAME_NR
frame_nr--;
#endif
return 0;
}
@ -206,7 +208,16 @@ debug_init (void)
UNLOCK (debug_lock);
if (debug_level > 0)
_gpgme_debug (DEBUG_INIT, "gpgme_debug: level=%d\n", debug_level);
{
_gpgme_debug (DEBUG_INIT, "gpgme_debug: level=%d\n", debug_level);
#ifdef HAVE_W32_SYSTEM
{
const char *name = _gpgme_get_inst_dir ();
_gpgme_debug (DEBUG_INIT, "gpgme_debug: gpgme='%s'\n",
name? name: "?");
}
#endif
}
}
@ -223,8 +234,17 @@ _gpgme_debug_subsystem_init (void)
/* Log the formatted string FORMAT at debug level LEVEL or higher. */
void
/* Log the formatted string FORMAT at debug level LEVEL or higher.
*
* Returns: 0
*
* Note that we always return 0 because the old TRACE macro evaluated
* to 0 which issues a warning with newer gcc version about an unused
* values. By using a return value of this function this can be
* avoided. Fixme: It might be useful to check whether the return
* value from the TRACE macros are actually used somewhere.
*/
int
_gpgme_debug (int level, const char *format, ...)
{
va_list arg_ptr;
@ -232,7 +252,7 @@ _gpgme_debug (int level, const char *format, ...)
saved_errno = errno;
if (debug_level < level)
return;
return 0;
va_start (arg_ptr, format);
LOCK (debug_lock);
@ -273,6 +293,7 @@ _gpgme_debug (int level, const char *format, ...)
fflush (errfp);
gpg_err_set_errno (saved_errno);
return 0;
}

View File

@ -64,7 +64,7 @@ int _gpgme_debug_set_debug_envvar (const char *value);
void _gpgme_debug_subsystem_init (void);
/* Log the formatted string FORMAT at debug level LEVEL or higher. */
void _gpgme_debug (int level, const char *format, ...);
int _gpgme_debug (int level, const char *format, ...);
/* Start a new debug line in *LINE, logged at level LEVEL or higher,
and starting with the formatted string FORMAT. */
@ -82,7 +82,7 @@ void _gpgme_debug_buffer (int lvl, const char *const fmt,
size_t len);
void _gpgme_debug_frame_begin (void);
void _gpgme_debug_frame_end (void);
int _gpgme_debug_frame_end (void);
static inline gpgme_error_t
_gpgme_trace_gpgme_error (gpgme_error_t err, const char *file, int line)
@ -108,82 +108,80 @@ _gpgme_trace_gpgme_error (gpgme_error_t err, const char *file, int line)
#define TRACE_BEG(lvl, name, tag) \
_TRACE (lvl, name, tag); \
_gpgme_debug (_gpgme_trace_level, "%s: enter: %s=%p\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag), 0
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag)
#define TRACE_BEG0(lvl, name, tag, fmt) \
_TRACE (lvl, name, tag); \
_gpgme_debug (_gpgme_trace_level, "%s: enter: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag), 0
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag)
#define TRACE_BEG1(lvl, name, tag, fmt, arg1) \
_TRACE (lvl, name, tag); \
_gpgme_debug (_gpgme_trace_level, "%s: enter: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1), 0
arg1)
#define TRACE_BEG2(lvl, name, tag, fmt, arg1, arg2) \
_TRACE (lvl, name, tag); \
_gpgme_debug (_gpgme_trace_level, "%s: enter: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2), 0
arg1, arg2)
#define TRACE_BEG3(lvl, name, tag, fmt, arg1, arg2, arg3) \
_TRACE (lvl, name, tag); \
_gpgme_debug (_gpgme_trace_level, "%s: enter: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2, arg3), 0
arg1, arg2, arg3)
#define TRACE_BEG4(lvl, name, tag, fmt, arg1, arg2, arg3, arg4) \
_TRACE (lvl, name, tag); \
_gpgme_debug (_gpgme_trace_level, "%s: enter: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2, arg3, arg4), 0
arg1, arg2, arg3, arg4)
#define TRACE_BEG5(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, arg5) \
_TRACE (lvl, name, tag); \
_gpgme_debug (_gpgme_trace_level, "%s: enter: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2, arg3, arg4, arg5), 0
arg1, arg2, arg3, arg4, arg5)
#define TRACE_BEG7(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, \
arg5, arg6, arg7) \
_TRACE (lvl, name, tag); \
_gpgme_debug (_gpgme_trace_level, "%s: enter: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2, arg3, arg4, arg5, \
arg6, arg7), 0
arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define TRACE_BEG8(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, \
arg5, arg6, arg7, arg8) \
_TRACE (lvl, name, tag); \
_gpgme_debug (_gpgme_trace_level, "%s: enter: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2, arg3, arg4, arg5, \
arg6, arg7, arg8), 0
arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
#define TRACE(lvl, name, tag) \
_gpgme_debug_frame_begin (), \
_gpgme_debug (lvl, "%s: call: %s=%p\n", \
name, STRINGIFY (tag), (void *) (uintptr_t) tag), \
_gpgme_debug_frame_end (), 0
_gpgme_debug_frame_end ()
#define TRACE0(lvl, name, tag, fmt) \
_gpgme_debug_frame_begin (), \
_gpgme_debug (lvl, "%s: call: %s=%p, " fmt "\n", \
name, STRINGIFY (tag), (void *) (uintptr_t) tag), \
_gpgme_debug_frame_end (), 0
_gpgme_debug_frame_end ()
#define TRACE1(lvl, name, tag, fmt, arg1) \
_gpgme_debug_frame_begin (), \
_gpgme_debug (lvl, "%s: call: %s=%p, " fmt "\n", \
name, STRINGIFY (tag), (void *) (uintptr_t) tag, arg1), \
_gpgme_debug_frame_end (), 0
_gpgme_debug_frame_end ()
#define TRACE2(lvl, name, tag, fmt, arg1, arg2) \
_gpgme_debug_frame_begin (), \
_gpgme_debug (lvl, "%s: call: %s=%p, " fmt "\n", \
name, STRINGIFY (tag), (void *) (uintptr_t) tag, arg1, \
arg2), _gpgme_debug_frame_end (), 0
arg2), _gpgme_debug_frame_end ()
#define TRACE3(lvl, name, tag, fmt, arg1, arg2, arg3) \
_gpgme_debug_frame_begin (), \
_gpgme_debug (lvl, "%s: call: %s=%p, " fmt "\n", \
name, STRINGIFY (tag), (void *) (uintptr_t) tag, arg1, \
arg2, arg3), _gpgme_debug_frame_end (), 0
arg2, arg3), _gpgme_debug_frame_end ()
#define TRACE6(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
_gpgme_debug_frame_begin (), \
_gpgme_debug (lvl, "%s: call: %s=%p, " fmt "\n", \
name, STRINGIFY (tag), (void *) (uintptr_t) tag, arg1, \
arg2, arg3, arg4, arg5, arg6), \
_gpgme_debug_frame_end (), 0
_gpgme_debug_frame_end ()
#define TRACE_ERR(err) \
err == 0 ? (TRACE_SUC ()) : \
@ -203,53 +201,52 @@ _gpgme_trace_gpgme_error (gpgme_error_t err, const char *file, int line)
#define TRACE_SUC() \
_gpgme_debug (_gpgme_trace_level, "%s: leave\n", \
_gpgme_trace_func), _gpgme_debug_frame_end (), 0
_gpgme_trace_func), _gpgme_debug_frame_end ()
#define TRACE_SUC0(fmt) \
_gpgme_debug (_gpgme_trace_level, "%s: leave: " fmt "\n", \
_gpgme_trace_func), _gpgme_debug_frame_end (), 0
_gpgme_trace_func), _gpgme_debug_frame_end ()
#define TRACE_SUC1(fmt, arg1) \
_gpgme_debug (_gpgme_trace_level, "%s: leave: " fmt "\n", \
_gpgme_trace_func, arg1), _gpgme_debug_frame_end (), 0
_gpgme_trace_func, arg1), _gpgme_debug_frame_end ()
#define TRACE_SUC2(fmt, arg1, arg2) \
_gpgme_debug (_gpgme_trace_level, "%s: leave: " fmt "\n", \
_gpgme_trace_func, arg1, arg2), _gpgme_debug_frame_end (), 0
_gpgme_trace_func, arg1, arg2), _gpgme_debug_frame_end ()
#define TRACE_SUC5(fmt, arg1, arg2, arg3, arg4, arg5) \
_gpgme_debug (_gpgme_trace_level, "%s: leave: " fmt "\n", \
_gpgme_trace_func, arg1, arg2, arg3, arg4, arg5), \
_gpgme_debug_frame_end (), 0
_gpgme_debug_frame_end ()
#define TRACE_SUC6(fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
_gpgme_debug (_gpgme_trace_level, "%s: leave: " fmt "\n", \
_gpgme_trace_func, arg1, arg2, arg3, arg4, arg5, arg6), \
_gpgme_debug_frame_end (), 0
_gpgme_debug_frame_end ()
#define TRACE_LOG(fmt) \
_gpgme_debug (_gpgme_trace_level, "%s: check: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag), 0
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag)
#define TRACE_LOG1(fmt, arg1) \
_gpgme_debug (_gpgme_trace_level, "%s: check: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1), 0
arg1)
#define TRACE_LOG2(fmt, arg1, arg2) \
_gpgme_debug (_gpgme_trace_level, "%s: check: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2), 0
arg1, arg2)
#define TRACE_LOG3(fmt, arg1, arg2, arg3) \
_gpgme_debug (_gpgme_trace_level, "%s: check: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2, arg3), 0
arg1, arg2, arg3)
#define TRACE_LOG4(fmt, arg1, arg2, arg3, arg4) \
_gpgme_debug (_gpgme_trace_level, "%s: check: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2, arg3, arg4), 0
arg1, arg2, arg3, arg4)
#define TRACE_LOG5(fmt, arg1, arg2, arg3, arg4, arg5) \
_gpgme_debug (_gpgme_trace_level, "%s: check: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2, arg3, arg4, arg5), 0
arg1, arg2, arg3, arg4, arg5)
#define TRACE_LOG6(fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
_gpgme_debug (_gpgme_trace_level, "%s: check: %s=%p, " fmt "\n", \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
arg1, arg2, arg3, arg4, arg5, \
arg6), 0
arg1, arg2, arg3, arg4, arg5, arg6)
#define TRACE_LOGBUF(buf, len) \
_gpgme_debug_buffer (_gpgme_trace_level, "%s: check: %s", \

View File

@ -38,6 +38,9 @@ typedef struct
{
struct _gpgme_op_decrypt_result result;
/* The error code from a FAILURE status line or 0. */
gpg_error_t failure_code;
int okay;
int failed;
@ -192,6 +195,10 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
switch (code)
{
case GPGME_STATUS_FAILURE:
opd->failure_code = _gpgme_parse_failure (args);
break;
case GPGME_STATUS_EOF:
/* FIXME: These error values should probably be attributed to
the underlying crypto engine (as error source). */
@ -199,6 +206,8 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
return gpg_error (GPG_ERR_DECRYPT_FAILED);
else if (!opd->okay)
return gpg_error (GPG_ERR_NO_DATA);
else if (opd->failure_code)
return opd->failure_code;
break;
case GPGME_STATUS_DECRYPTION_INFO:
@ -291,6 +300,16 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
err = _gpgme_parse_plaintext (args, &opd->result.file_name);
if (err)
return err;
break;
case GPGME_STATUS_INQUIRE_MAXLEN:
if (ctx->status_cb)
{
err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
if (err)
return err;
}
break;
default:
break;

View File

@ -64,8 +64,40 @@ delete_status_handler (void *priv, gpgme_status_code_t code, char *args)
case DELETE_Ambiguous_Specification:
return gpg_error (GPG_ERR_AMBIGUOUS_NAME);
default:
return gpg_error (GPG_ERR_GENERAL);
}
return gpg_error (GPG_ERR_GENERAL);
}
else if (code == GPGME_STATUS_ERROR)
{
/* Some error stati are informational, so we don't return an
error code if we are not ready to process this status. */
gpgme_error_t err;
char *where = strchr (args, ' ');
char *which;
if (where)
{
*where = '\0';
which = where + 1;
where = strchr (which, ' ');
if (where)
*where = '\0';
where = args;
}
else
return trace_gpg_error (GPG_ERR_INV_ENGINE);
err = atoi (which);
if (!strcmp (where, "delete_key.secret")
&& (gpg_err_code (err) == GPG_ERR_CANCELED
|| gpg_err_code (err) == GPG_ERR_FULLY_CANCELED))
{
/* This indicates a user cancellation on the confirmation dialog. */
return gpg_error (gpg_err_code (err));
}
}
return 0;

View File

@ -36,6 +36,9 @@ typedef struct
{
struct _gpgme_op_encrypt_result result;
/* The error code from a FAILURE status line or 0. */
gpg_error_t failure_code;
/* A pointer to the next pointer of the last invalid recipient in
the list. This makes appending new invalid recipients painless
while preserving the order. */
@ -114,9 +117,15 @@ _gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code,
switch (code)
{
case GPGME_STATUS_FAILURE:
opd->failure_code = _gpgme_parse_failure (args);
break;
case GPGME_STATUS_EOF:
if (opd->result.invalid_recipients)
return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
if (opd->failure_code)
return opd->failure_code;
break;
case GPGME_STATUS_INV_RECP:

View File

@ -282,12 +282,10 @@ llass_new (void **engine, const char *file_name, const char *home_dir)
char *dft_ttytype = NULL;
rc = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname));
if (rc)
{
err = gpg_error_from_errno (rc);
goto leave;
}
else
/* Even though isatty() returns 1, ttyname_r() may fail in many
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{

View File

@ -85,10 +85,12 @@ struct engine_ops
gpgme_error_t (*import) (void *engine, gpgme_data_t keydata,
gpgme_key_t *keyarray);
gpgme_error_t (*keylist) (void *engine, const char *pattern,
int secret_only, gpgme_keylist_mode_t mode);
int secret_only, gpgme_keylist_mode_t mode,
int engine_flags);
gpgme_error_t (*keylist_ext) (void *engine, const char *pattern[],
int secret_only, int reserved,
gpgme_keylist_mode_t mode);
gpgme_keylist_mode_t mode,
int engine_flags);
gpgme_error_t (*sign) (void *engine, gpgme_data_t in, gpgme_data_t out,
gpgme_sig_mode_t mode, int use_armor,
int use_textmode, int include_certs,

View File

@ -286,12 +286,10 @@ g13_new (void **engine, const char *file_name, const char *home_dir)
int rc;
rc = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname));
if (rc)
{
err = gpg_error_from_errno (rc);
goto leave;
}
else
/* Even though isatty() returns 1, ttyname_r() may fail in many
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{

View File

@ -513,6 +513,8 @@ gpg_new (void **engine, const char *file_name, const char *home_dir)
rc = add_arg (gpg, dft_display);
free (dft_display);
if (rc)
goto leave;
}
if (isatty (1))
@ -520,9 +522,10 @@ gpg_new (void **engine, const char *file_name, const char *home_dir)
int err;
err = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname));
if (err)
rc = gpg_error_from_errno (err);
else
/* Even though isatty() returns 1, ttyname_r() may fail in many
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!err)
{
if (*dft_ttyname)
{
@ -547,9 +550,9 @@ gpg_new (void **engine, const char *file_name, const char *home_dir)
free (dft_ttytype);
}
if (rc)
goto leave;
}
if (rc)
goto leave;
}
leave:
@ -1456,7 +1459,7 @@ gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
err = add_data (gpg, ciph, -1, 0);
if (!err)
start (gpg);
err = start (gpg);
return err;
}
@ -1479,7 +1482,7 @@ gpg_delete (void *engine, gpgme_key_t key, int allow_secret)
}
if (!err)
start (gpg);
err = start (gpg);
return err;
}
@ -1497,7 +1500,7 @@ gpg_passwd (void *engine, gpgme_key_t key, unsigned int flags)
if (!err)
err = add_arg (gpg, key->subkeys->fpr);
if (!err)
start (gpg);
err = start (gpg);
return err;
}
@ -1793,7 +1796,8 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
gpgme_error_t err = 0;
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|GPGME_EXPORT_MODE_MINIMAL)))
|GPGME_EXPORT_MODE_MINIMAL
|GPGME_EXPORT_MODE_SECRET)))
return gpg_error (GPG_ERR_NOT_SUPPORTED);
if ((mode & GPGME_EXPORT_MODE_MINIMAL))
@ -1807,7 +1811,10 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
}
else
{
err = add_arg (gpg, "--export");
if ((mode & GPGME_EXPORT_MODE_SECRET))
err = add_arg (gpg, "--export-secret-keys");
else
err = add_arg (gpg, "--export");
if (!err && use_armor)
err = add_arg (gpg, "--armor");
if (!err)
@ -2194,6 +2201,7 @@ gpg_keylist_preprocess (char *line, char **r_line)
{
*dst++ = '\\';
*dst++ = '\\';
src++;
}
else
*(dst++) = *(src++);
@ -2278,7 +2286,7 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
static gpgme_error_t
gpg_keylist (void *engine, const char *pattern, int secret_only,
gpgme_keylist_mode_t mode)
gpgme_keylist_mode_t mode, int engine_flags)
{
engine_gpg_t gpg = engine;
gpgme_error_t err;
@ -2297,7 +2305,7 @@ gpg_keylist (void *engine, const char *pattern, int secret_only,
static gpgme_error_t
gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
int reserved, gpgme_keylist_mode_t mode)
int reserved, gpgme_keylist_mode_t mode, int engine_flags)
{
engine_gpg_t gpg = engine;
gpgme_error_t err;
@ -2363,7 +2371,7 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
err = add_data (gpg, out, 1, 1);
if (!err)
start (gpg);
err = start (gpg);
return err;
}

View File

@ -408,12 +408,10 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
int rc;
rc = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname));
if (rc)
{
err = gpg_error_from_errno (rc);
goto leave;
}
else
/* Even though isatty() returns 1, ttyname_r() may fail in many
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{
@ -564,7 +562,7 @@ gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
engine_status_handler_t status_fnc,
void *status_fnc_value)
{
gpg_error_t err;
gpg_error_t err, cb_err;
char *line;
size_t linelen;
@ -572,6 +570,7 @@ gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
if (err)
return err;
cb_err = 0;
do
{
err = assuan_read_line (ctx, &line, &linelen);
@ -584,32 +583,45 @@ gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
if (linelen >= 2
&& line[0] == 'O' && line[1] == 'K'
&& (line[2] == '\0' || line[2] == ' '))
return 0;
return cb_err;
else if (linelen >= 4
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
&& line[3] == ' ')
err = atoi (&line[4]);
{
/* We prefer a callback generated error because that one is
more related to gpgme and thus probably more important
than the error returned by the engine. */
err = cb_err? cb_err : atoi (&line[4]);
}
else if (linelen >= 2
&& line[0] == 'S' && line[1] == ' ')
{
char *rest;
gpgme_status_code_t r;
/* After an error from a status callback we skip all further
status lines. */
if (!cb_err)
{
char *rest;
gpgme_status_code_t r;
rest = strchr (line + 2, ' ');
if (!rest)
rest = line + linelen; /* set to an empty string */
else
*(rest++) = 0;
rest = strchr (line + 2, ' ');
if (!rest)
rest = line + linelen; /* set to an empty string */
else
*(rest++) = 0;
r = _gpgme_parse_status (line + 2);
r = _gpgme_parse_status (line + 2);
if (r >= 0 && status_fnc)
err = status_fnc (status_fnc_value, r, rest);
else
err = gpg_error (GPG_ERR_GENERAL);
if (r >= 0 && status_fnc)
cb_err = status_fnc (status_fnc_value, r, rest);
}
}
else
err = gpg_error (GPG_ERR_GENERAL);
{
/* Invalid line or INQUIRY. We can't do anything else than
to stop. As with ERR we prefer a status callback
generated error code, though. */
err = cb_err ? cb_err : gpg_error (GPG_ERR_GENERAL);
}
}
while (!err);
@ -1275,17 +1287,23 @@ gpgsm_export (void *engine, const char *pattern, gpgme_export_mode_t mode,
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
if (mode)
return gpg_error (GPG_ERR_NOT_SUPPORTED);
if (!pattern)
pattern = "";
cmd = malloc (7 + strlen (pattern) + 1);
cmd = malloc (7 + 9 + 9 + strlen (pattern) + 1);
if (!cmd)
return gpg_error_from_syserror ();
strcpy (cmd, "EXPORT ");
strcpy (&cmd[7], pattern);
if ((mode & GPGME_EXPORT_MODE_SECRET))
{
strcat (cmd, "--secret ");
if ((mode & GPGME_EXPORT_MODE_RAW))
strcat (cmd, "--raw ");
else if ((mode & GPGME_EXPORT_MODE_PKCS12))
strcat (cmd, "--pkcs12 ");
}
strcat (cmd, pattern);
gpgsm->output_cb.data = keydata;
err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor"
@ -1309,16 +1327,13 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
engine_gpgsm_t gpgsm = engine;
gpgme_error_t err = 0;
char *line;
/* Length is "EXPORT " + p + '\0'. */
int length = 7 + 1;
/* Length is "EXPORT " + "--secret " + "--pkcs12 " + p + '\0'. */
int length = 7 + 9 + 9 + 1;
char *linep;
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
if (mode)
return gpg_error (GPG_ERR_NOT_SUPPORTED);
if (pattern && *pattern)
{
const char **pat = pattern;
@ -1343,7 +1358,15 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
return gpg_error_from_syserror ();
strcpy (line, "EXPORT ");
linep = &line[7];
if ((mode & GPGME_EXPORT_MODE_SECRET))
{
strcat (line, "--secret ");
if ((mode & GPGME_EXPORT_MODE_RAW))
strcat (line, "--raw ");
else if ((mode & GPGME_EXPORT_MODE_PKCS12))
strcat (line, "--pkcs12 ");
}
linep = &line[strlen (line)];
if (pattern && *pattern)
{
@ -1528,7 +1551,7 @@ gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
static gpgme_error_t
gpgsm_keylist (void *engine, const char *pattern, int secret_only,
gpgme_keylist_mode_t mode)
gpgme_keylist_mode_t mode, int engine_flags)
{
engine_gpgsm_t gpgsm = engine;
char *line;
@ -1585,6 +1608,11 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
"OPTION with-secret=1":
"OPTION with-secret=0" ,
NULL, NULL);
gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
(engine_flags & GPGME_ENGINE_FLAG_OFFLINE)?
"OPTION offline=1":
"OPTION offline=0" ,
NULL, NULL);
/* Length is "LISTSECRETKEYS " + p + '\0'. */
@ -1615,7 +1643,7 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
static gpgme_error_t
gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
int reserved, gpgme_keylist_mode_t mode)
int reserved, gpgme_keylist_mode_t mode, int engine_flags)
{
engine_gpgsm_t gpgsm = engine;
char *line;
@ -1655,7 +1683,11 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
"OPTION with-secret=1":
"OPTION with-secret=0" ,
NULL, NULL);
gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
(engine_flags & GPGME_ENGINE_FLAG_OFFLINE)?
"OPTION offline=1":
"OPTION offline=0" ,
NULL, NULL);
if (pattern && *pattern)
{

View File

@ -326,12 +326,10 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir)
int rc;
rc = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname));
if (rc)
{
err = gpg_error_from_errno (rc);
goto leave;
}
else
/* Even though isatty() returns 1, ttyname_r() may fail in many
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{

View File

@ -726,7 +726,8 @@ _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
gpgme_error_t
_gpgme_engine_op_keylist (engine_t engine, const char *pattern,
int secret_only, gpgme_keylist_mode_t mode)
int secret_only, gpgme_keylist_mode_t mode,
int engine_flags)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
@ -734,14 +735,15 @@ _gpgme_engine_op_keylist (engine_t engine, const char *pattern,
if (!engine->ops->keylist)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode);
return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode,
engine_flags);
}
gpgme_error_t
_gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
int secret_only, int reserved,
gpgme_keylist_mode_t mode)
gpgme_keylist_mode_t mode, int engine_flags)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
@ -750,7 +752,7 @@ _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
reserved, mode);
reserved, mode, engine_flags);
}

View File

@ -113,12 +113,14 @@ gpgme_error_t _gpgme_engine_op_import (engine_t engine,
gpgme_error_t _gpgme_engine_op_keylist (engine_t engine,
const char *pattern,
int secret_only,
gpgme_keylist_mode_t mode);
gpgme_keylist_mode_t mode,
int engine_flags);
gpgme_error_t _gpgme_engine_op_keylist_ext (engine_t engine,
const char *pattern[],
int secret_only,
int reserved,
gpgme_keylist_mode_t mode);
gpgme_keylist_mode_t mode,
int engine_flags);
gpgme_error_t _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in,
gpgme_data_t out, gpgme_sig_mode_t mode,
int use_armor, int use_textmode,
@ -170,5 +172,8 @@ gpgme_error_t _gpgme_engine_op_spawn (engine_t engine,
gpgme_data_t dataerr,
unsigned int flags);
/* The available engine option flags. */
#define GPGME_ENGINE_FLAG_OFFLINE 1
#endif /* ENGINE_H */

View File

@ -120,9 +120,24 @@ export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
op_data_t opd;
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|GPGME_EXPORT_MODE_MINIMAL)))
|GPGME_EXPORT_MODE_MINIMAL
|GPGME_EXPORT_MODE_SECRET
|GPGME_EXPORT_MODE_RAW
|GPGME_EXPORT_MODE_PKCS12)))
return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */
if ((mode & GPGME_EXPORT_MODE_SECRET))
{
if ((mode & GPGME_EXPORT_MODE_EXTERN))
return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
if ((mode & GPGME_EXPORT_MODE_RAW)
&& (mode & GPGME_EXPORT_MODE_PKCS12))
return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
if (ctx->protocol != GPGME_PROTOCOL_CMS
&& (mode & (GPGME_EXPORT_MODE_RAW|GPGME_EXPORT_MODE_PKCS12)))
return gpg_error (GPG_ERR_INV_FLAG); /* Only supported for X.509. */
}
if ((mode & GPGME_EXPORT_MODE_EXTERN))
{
@ -199,9 +214,25 @@ export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],
op_data_t opd;
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|GPGME_EXPORT_MODE_MINIMAL)))
|GPGME_EXPORT_MODE_MINIMAL
|GPGME_EXPORT_MODE_SECRET
|GPGME_EXPORT_MODE_RAW
|GPGME_EXPORT_MODE_PKCS12)))
return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */
if ((mode & GPGME_EXPORT_MODE_SECRET))
{
if ((mode & GPGME_EXPORT_MODE_EXTERN))
return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
if ((mode & GPGME_EXPORT_MODE_RAW)
&& (mode & GPGME_EXPORT_MODE_PKCS12))
return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
if (ctx->protocol != GPGME_PROTOCOL_CMS
&& (mode & (GPGME_EXPORT_MODE_RAW|GPGME_EXPORT_MODE_PKCS12)))
return gpg_error (GPG_ERR_INV_FLAG); /* Only supported for X.509. */
}
if ((mode & GPGME_EXPORT_MODE_EXTERN))
{
if (keydata)

View File

@ -35,7 +35,7 @@
The functions to provide my either be NULL if not required or
similar to the unistd function with the exception of using the
cookie instead of the fiel descripor.
cookie instead of the file descriptor.
*/

View File

@ -37,6 +37,9 @@ typedef struct
{
struct _gpgme_op_genkey_result result;
/* The error code from a FAILURE status line or 0. */
gpg_error_t failure_code;
/* The key parameters passed to the crypto engine. */
gpgme_data_t key_parameter;
} *op_data_t;
@ -118,10 +121,25 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
}
break;
case GPGME_STATUS_FAILURE:
opd->failure_code = _gpgme_parse_failure (args);
break;
case GPGME_STATUS_EOF:
/* FIXME: Should return some more useful error value. */
if (!opd->result.primary && !opd->result.sub)
return gpg_error (GPG_ERR_GENERAL);
else if (opd->failure_code)
return opd->failure_code;
break;
case GPGME_STATUS_INQUIRE_MAXLEN:
if (ctx->status_cb)
{
err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
if (err)
return err;
}
break;
default:
@ -186,6 +204,14 @@ genkey_start (gpgme_ctx_t ctx, int synchronous, const char *parms,
_gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
if (ctx->passphrase_cb)
{
err = _gpgme_engine_set_command_handler
(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
if (err)
return err;
}
return _gpgme_engine_op_genkey (ctx->engine, opd->key_parameter,
ctx->use_armor, pubkey, seckey);
}

View File

@ -32,12 +32,10 @@
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#include <assuan.h>
#include "argparse.h"
#include "gpgme.h"
/* GCC attributes. */
@ -59,421 +57,6 @@
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
#ifndef HAVE_ARGP_H
/* Minimal argp implementation. */
/* Differences to ARGP:
argp_program_version: Required.
argp_program_bug_address: Required.
argp_program_version_hook: Not supported.
argp_err_exit_status: Required.
struct argp: Children and help_filter not supported.
argp_domain: Not supported.
struct argp_option: Group not supported. Options are printed in
order given. Flags OPTION_ALIAS, OPTION_DOC and OPTION_NO_USAGE
are not supported.
argp_parse: No flags are supported (ARGP_PARSE_ARGV0, ARGP_NO_ERRS,
ARGP_NO_ARGS, ARGP_IN_ORDER, ARGP_NO_HELP, ARGP_NO_EXIT,
ARGP_LONG_ONLY, ARGP_SILENT). ARGP must not be NULL.
argp_help: Flag ARGP_HELP_LONG_ONLY not supported.
argp_state: argc, argv, next may not be modified and should not be used. */
extern const char *argp_program_version;
extern const char *argp_program_bug_address;
extern error_t argp_err_exit_status;
struct argp_option
{
const char *name;
int key;
const char *arg;
#define OPTION_ARG_OPTIONAL 0x1
#define OPTION_HIDDEN 0x2
int flags;
const char *doc;
int group;
};
struct argp;
struct argp_state
{
const struct argp *const root_argp;
int argc;
char **argv;
int next;
unsigned flags;
unsigned arg_num;
int quoted;
void *input;
void **child_inputs;
void *hook;
char *name;
FILE *err_stream;
FILE *out_stream;
void *pstate;
};
#ifdef EDEADLK
# define ARGP_ERR_UNKNOWN EDEADLK /* POSIX */
#else
# define ARGP_ERR_UNKNOWN EDEADLOCK /* *GNU/kFreebsd does not define this) */
#endif
#define ARGP_KEY_ARG 0
#define ARGP_KEY_ARGS 0x1000006
#define ARGP_KEY_END 0x1000001
#define ARGP_KEY_NO_ARGS 0x1000002
#define ARGP_KEY_INIT 0x1000003
#define ARGP_KEY_FINI 0x1000007
#define ARGP_KEY_SUCCESS 0x1000004
#define ARGP_KEY_ERROR 0x1000005
typedef error_t (*argp_parser_t) (int key, char *arg, struct argp_state *state);
struct argp
{
const struct argp_option *options;
argp_parser_t parser;
const char *args_doc;
const char *doc;
const struct argp_child *children;
char *(*help_filter) (int key, const char *text, void *input);
const char *argp_domain;
};
#define ARGP_HELP_USAGE ARGP_HELP_SHORT_USAGE
#define ARGP_HELP_SHORT_USAGE 0x02
#define ARGP_HELP_SEE 0x04
#define ARGP_HELP_LONG 0x08
#define ARGP_HELP_PRE_DOC 0x10
#define ARGP_HELP_POST_DOC 0x20
#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
#define ARGP_HELP_BUG_ADDR 0x40
#define ARGP_HELP_EXIT_ERR 0x100
#define ARGP_HELP_EXIT_OK 0x200
#define ARGP_HELP_STD_ERR (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
#define ARGP_HELP_STD_USAGE \
(ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
#define ARGP_HELP_STD_HELP \
(ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
| ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
void argp_error (const struct argp_state *state,
const char *fmt, ...) GT_GCC_A_PRINTF(2, 3);
char *
_argp_pname (char *name)
{
char *pname = name;
char *bname = strrchr (pname, '/');
if (! bname)
bname = strrchr (pname, '\\');
if (bname)
pname = bname + 1;
return pname;
}
void
_argp_state_help (const struct argp *argp, const struct argp_state *state,
FILE *stream, unsigned flags, char *name)
{
if (state)
name = state->name;
if (flags & ARGP_HELP_SHORT_USAGE)
fprintf (stream, "Usage: %s [OPTIONS...] %s\n", name, argp->args_doc);
if (flags & ARGP_HELP_SEE)
fprintf (stream, "Try `%s --help' or `%s --usage' for more information.\n",
name, name);
if (flags & ARGP_HELP_PRE_DOC)
{
char buf[1024];
char *end;
strncpy (buf, argp->doc, sizeof (buf));
buf[sizeof (buf) - 1] = '\0';
end = strchr (buf, '\v');
if (end)
*end = '\0';
fprintf (stream, "%s\n%s", buf, buf[0] ? "\n" : "");
}
if (flags & ARGP_HELP_LONG)
{
const struct argp_option *opt = argp->options;
while (opt->key)
{
#define NSPACES 29
char spaces[NSPACES + 1] = " ";
int len = 0;
fprintf (stream, " ");
len += 2;
if (isascii (opt->key))
{
fprintf (stream, "-%c", opt->key);
len += 2;
if (opt->name)
{
fprintf (stream, ", ");
len += 2;
}
}
if (opt->name)
{
fprintf (stream, "--%s", opt->name);
len += 2 + strlen (opt->name);
}
if (opt->arg && (opt->flags & OPTION_ARG_OPTIONAL))
{
fprintf (stream, "[=%s]", opt->arg);
len += 3 + strlen (opt->arg);
}
else if (opt->arg)
{
fprintf (stream, "=%s", opt->arg);
len += 1 + strlen (opt->arg);
}
if (len >= NSPACES)
len = NSPACES - 1;
spaces[NSPACES - len] = '\0';
fprintf (stream, "%s%s\n", spaces, opt->doc);
opt++;
}
fprintf (stream, " -?, --help Give this help list\n");
fprintf (stream, " --usage Give a short usage "
"message\n");
}
if (flags & ARGP_HELP_POST_DOC)
{
char buf[1024];
char *end;
strncpy (buf, argp->doc, sizeof (buf));
buf[sizeof (buf) - 1] = '\0';
end = strchr (buf, '\v');
if (end)
{
end++;
if (*end)
fprintf (stream, "\n%s\n", end);
}
fprintf (stream, "\nMandatory or optional arguments to long options are also mandatory or optional\n");
fprintf (stream, "for any corresponding short options.\n");
}
if (flags & ARGP_HELP_BUG_ADDR)
fprintf (stream, "\nReport bugs to %s.\n", argp_program_bug_address);
if (flags & ARGP_HELP_EXIT_ERR)
exit (argp_err_exit_status);
if (flags & ARGP_HELP_EXIT_OK)
exit (0);
}
void
argp_usage (const struct argp_state *state)
{
_argp_state_help (state->root_argp, state, state->err_stream,
ARGP_HELP_STD_USAGE, state->name);
}
void
argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
{
_argp_state_help (state->root_argp, state, stream, flags, state->name);
}
void
argp_error (const struct argp_state *state, const char *fmt, ...)
{
va_list ap;
fprintf (state->err_stream, "%s: ", state->name);
va_start (ap, fmt);
vfprintf (state->err_stream, fmt, ap);
va_end (ap);
fprintf (state->err_stream, "\n");
argp_state_help (state, state->err_stream, ARGP_HELP_STD_ERR);
exit (argp_err_exit_status);
}
void
argp_help (const struct argp *argp, FILE *stream, unsigned flags, char *name)
{
_argp_state_help (argp, NULL, stream, flags, name);
}
error_t
argp_parse (const struct argp *argp, int argc,
char **argv, unsigned flags, int *arg_index, void *input)
{
int rc = 0;
struct argp_state state = { argp, argc, argv, 1, flags, 0, 0, input,
NULL, NULL, _argp_pname (argv[0]),
stderr, stdout, NULL };
/* All non-option arguments are collected at the beginning of
&argv[1] during processing. This is a counter for their number. */
int non_opt_args = 0;
rc = argp->parser (ARGP_KEY_INIT, NULL, &state);
if (rc && rc != ARGP_ERR_UNKNOWN)
goto argperror;
while (state.next < state.argc - non_opt_args)
{
int idx = state.next;
state.next++;
if (! strcasecmp (state.argv[idx], "--"))
{
state.quoted = idx;
continue;
}
if (state.quoted || state.argv[idx][0] != '-')
{
char *arg_saved = state.argv[idx];
non_opt_args++;
memmove (&state.argv[idx], &state.argv[idx + 1],
(state.argc - 1 - idx) * sizeof (char *));
state.argv[argc - 1] = arg_saved;
state.next--;
}
else if (! strcasecmp (state.argv[idx], "--help")
|| !strcmp (state.argv[idx], "-?"))
{
argp_state_help (&state, state.out_stream, ARGP_HELP_STD_HELP);
}
else if (! strcasecmp (state.argv[idx], "--usage"))
{
argp_state_help (&state, state.out_stream,
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
}
else if (! strcasecmp (state.argv[idx], "--version")
|| !strcmp (state.argv[idx], "-V"))
{
fprintf (state.out_stream, "%s\n", argp_program_version);
exit (0);
}
else
{
/* Search for option and call parser with its KEY. */
int key = ARGP_KEY_ARG; /* Just some dummy value. */
const struct argp_option *opt = argp->options;
char *arg = NULL;
int found = 0;
/* Check for --opt=value syntax. */
arg = strchr (state.argv[idx], '=');
if (arg)
{
*arg = '\0';
arg++;
}
if (state.argv[idx][1] != '-')
key = state.argv[idx][1];
while (! found && opt->key)
{
if (key == opt->key
|| (key == ARGP_KEY_ARG
&& ! strcasecmp (&state.argv[idx][2], opt->name)))
{
if (arg && !opt->arg)
argp_error (&state, "Option %s does not take an argument",
state.argv[idx]);
if (opt->arg && state.next < state.argc
&& state.argv[idx + 1][0] != '-')
{
arg = state.argv[idx + 1];
state.next++;
}
if (opt->arg && !(opt->flags & OPTION_ARG_OPTIONAL))
argp_error (&state, "Option %s requires an argument",
state.argv[idx]);
rc = argp->parser (opt->key, arg, &state);
if (rc == ARGP_ERR_UNKNOWN)
break;
else if (rc)
goto argperror;
found = 1;
}
opt++;
}
if (! found)
argp_error (&state, "Unknown option %s", state.argv[idx]);
}
}
while (state.next < state.argc)
{
/* Call parser for all non-option args. */
int idx = state.next;
state.next++;
rc = argp->parser (ARGP_KEY_ARG, state.argv[idx], &state);
if (rc && rc != ARGP_ERR_UNKNOWN)
goto argperror;
if (rc == ARGP_ERR_UNKNOWN)
{
int old_next = state.next;
rc = argp->parser (ARGP_KEY_ARGS, NULL, &state);
if (rc == ARGP_ERR_UNKNOWN)
{
argp_error (&state, "Too many arguments");
goto argperror;
}
if (! rc && state.next == old_next)
{
state.arg_num += state.argc - state.next;
state.next = state.argc;
}
}
else
state.arg_num++;
}
if (state.arg_num == 0)
{
rc = argp->parser (ARGP_KEY_NO_ARGS, NULL, &state);
if (rc && rc != ARGP_ERR_UNKNOWN)
goto argperror;
}
if (state.next == state.argc)
{
rc = argp->parser (ARGP_KEY_END, NULL, &state);
if (rc && rc != ARGP_ERR_UNKNOWN)
goto argperror;
}
rc = argp->parser (ARGP_KEY_FINI, NULL, &state);
if (rc && rc != ARGP_ERR_UNKNOWN)
goto argperror;
rc = 0;
argp->parser (ARGP_KEY_SUCCESS, NULL, &state);
argperror:
if (rc)
{
argp_error (&state, "unexpected error: %s", strerror (rc));
argp->parser (ARGP_KEY_ERROR, NULL, &state);
}
argp->parser (ARGP_KEY_FINI, NULL, &state);
if (arg_index)
*arg_index = state.next - 1;
return 0;
}
#endif
/* MEMBUF */
@ -3054,7 +2637,7 @@ cmd_import (assuan_context_t ctx, char *line)
static const char hlp_export[] =
"EXPORT [--extern] [--minimal] [<pattern>]\n"
"EXPORT [--extern] [--minimal] [--secret [--pkcs12] [--raw]] [<pattern>]\n"
"\n"
"Export the keys described by PATTERN. Write the\n"
"the output to the object set by the last OUTPUT command.";
@ -3082,6 +2665,12 @@ cmd_export (assuan_context_t ctx, char *line)
mode |= GPGME_EXPORT_MODE_EXTERN;
if (has_option (line, "--minimal"))
mode |= GPGME_EXPORT_MODE_MINIMAL;
if (has_option (line, "--secret"))
mode |= GPGME_EXPORT_MODE_SECRET;
if (has_option (line, "--raw"))
mode |= GPGME_EXPORT_MODE_RAW;
if (has_option (line, "--pkcs12"))
mode |= GPGME_EXPORT_MODE_PKCS12;
line = skip_options (line);
@ -3716,77 +3305,50 @@ gpgme_server (gpgme_tool_t gt)
/* MAIN PROGRAM STARTS HERE. */
const char *argp_program_version = VERSION;
const char *argp_program_bug_address = "bug-gpgme@gnupg.org";
error_t argp_err_exit_status = 1;
static char doc[] = "GPGME Tool -- Assuan server exposing GPGME operations";
static char args_doc[] = "COMMAND [OPTIONS...]";
static struct argp_option options[] = {
{ "server", 's', 0, 0, "Server mode" },
{ "gpg-binary", 501, "FILE", 0, "Use FILE for the GPG backend" },
{ 0 }
};
static error_t parse_options (int key, char *arg, struct argp_state *state);
static struct argp argp = { options, parse_options, args_doc, doc };
struct args
static const char *
my_strusage( int level )
{
enum { CMD_DEFAULT, CMD_SERVER } cmd;
const char *gpg_binary;
};
const char *p;
void
args_init (struct args *args)
{
memset (args, '\0', sizeof (*args));
args->cmd = CMD_DEFAULT;
}
static error_t
parse_options (int key, char *arg, struct argp_state *state)
{
struct args *args = state->input;
switch (key)
switch (level)
{
case 's':
args->cmd = CMD_SERVER;
case 11: p = "gpgme-tool"; break;
case 13: p = PACKAGE_VERSION; break;
case 14: p = "Copyright (C) 2015 g10 Code GmbH"; break;
case 19: p = "Please report bugs to <" PACKAGE_BUGREPORT ">.\n"; break;
case 1:
case 40:
p = "Usage: gpgme-tool [OPTIONS] [COMMANDS]";
break;
case 501:
args->gpg_binary = arg;
case 41:
p = "GPGME Tool -- Assuan server exposing GPGME operations\n";
break;
#if 0
case ARGP_KEY_ARG:
if (state->arg_num >= 2)
argp_usage (state);
printf ("Arg[%i] = %s\n", state->arg_num, arg);
case 42:
p = "1"; /* Flag print 40 as part of 41. */
break;
case ARGP_KEY_END:
if (state->arg_num < 2)
argp_usage (state);
break;
#endif
default:
return ARGP_ERR_UNKNOWN;
default: p = NULL; break;
}
return 0;
return p;
}
int
main (int argc, char *argv[])
{
struct args args;
static ARGPARSE_OPTS opts[] = {
ARGPARSE_c ('s', "server", "Server mode"),
ARGPARSE_s_s(501, "gpg-binary", "|FILE|Use FILE for the GPG backend"),
ARGPARSE_c (502, "lib-version", "Show library version"),
ARGPARSE_end()
};
ARGPARSE_ARGS pargs = { &argc, &argv, 0 };
enum { CMD_DEFAULT, CMD_SERVER, CMD_LIBVERSION } cmd = CMD_DEFAULT;
const char *gpg_binary = NULL;
struct gpgme_tool gt;
gpg_error_t err;
int needgt = 1;
set_strusage (my_strusage);
#ifdef HAVE_SETLOCALE
setlocale (LC_ALL, "");
@ -3799,34 +3361,56 @@ main (int argc, char *argv[])
gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
#endif
args_init (&args);
argp_parse (&argp, argc, argv, 0, 0, &args);
log_init ();
if (args.gpg_binary)
while (arg_parse (&pargs, opts))
{
if (access (args.gpg_binary, X_OK))
switch (pargs.r_opt)
{
case 's': cmd = CMD_SERVER; break;
case 501: gpg_binary = pargs.r.ret_str; break;
case 502: cmd = CMD_LIBVERSION; break;
default:
pargs.err = ARGPARSE_PRINT_WARNING;
break;
}
}
if (cmd == CMD_LIBVERSION)
needgt = 0;
if (needgt && gpg_binary)
{
if (access (gpg_binary, X_OK))
err = gpg_error_from_syserror ();
else
err = gpgme_set_engine_info (GPGME_PROTOCOL_OpenPGP,
args.gpg_binary, NULL);
gpg_binary, NULL);
if (err)
log_error (1, err, "error witching OpenPGP engine to '%s'",
args.gpg_binary);
gpg_binary);
}
gt_init (&gt);
if (needgt)
gt_init (&gt);
switch (args.cmd)
switch (cmd)
{
case CMD_DEFAULT:
case CMD_SERVER:
gpgme_server (&gt);
break;
case CMD_LIBVERSION:
printf ("Version from header: %s (0x%06x)\n",
GPGME_VERSION, GPGME_VERSION_NUMBER);
printf ("Version from binary: %s\n", gpgme_check_version (NULL));
printf ("Copyright blurb ...:%s\n", gpgme_check_version ("\x01\x01"));
break;
}
gpgme_release (gt.ctx);
if (needgt)
gpgme_release (gt.ctx);
#ifdef HAVE_W32CE_SYSTEM
/* Give the buggy ssh server time to flush the output buffers. */
@ -3835,4 +3419,3 @@ main (int argc, char *argv[])
return 0;
}

View File

@ -1,7 +1,7 @@
/* gpgme.c - GnuPG Made Easy.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2012,
2014 g10 Code GmbH
2014, 2015 g10 Code GmbH
This file is part of GPGME.
@ -75,6 +75,8 @@ gpgme_set_global_flag (const char *name, const char *value)
return _gpgme_set_default_gpgconf_name (value);
else if (!strcmp (name, "gpg-name"))
return _gpgme_set_default_gpg_name (value);
else if (!strcmp (name, "w32-inst-dir"))
return _gpgme_set_override_inst_dir (value);
else
return -1;
}
@ -91,7 +93,7 @@ gpgme_new (gpgme_ctx_t *r_ctx)
TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx);
if (_gpgme_selftest)
return TRACE_ERR (gpgme_error (_gpgme_selftest));
return TRACE_ERR (_gpgme_selftest);
if (!r_ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
@ -472,6 +474,30 @@ gpgme_get_textmode (gpgme_ctx_t ctx)
}
/* Enable offline mode for this context. In offline mode dirmngr
will be disabled. */
void
gpgme_set_offline (gpgme_ctx_t ctx, int offline)
{
TRACE2 (DEBUG_CTX, "gpgme_set_offline", ctx, "offline=%i (%s)",
offline, offline ? "yes" : "no");
if (!ctx)
return;
ctx->offline = offline;
}
/* Return the state of the offline flag. */
int
gpgme_get_offline (gpgme_ctx_t ctx)
{
TRACE2 (DEBUG_CTX, "gpgme_get_offline", ctx, "ctx->offline=%i (%s)",
ctx->offline, ctx->offline ? "yes" : "no");
return ctx->offline;
}
/* Set the number of certifications to include in an S/MIME message.
The default is GPGME_INCLUDE_CERTS_DEFAULT. -1 means all certs,
and -2 means all certs except the root cert. */
@ -632,6 +658,47 @@ gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *r_cb,
}
/* This function sets a callback function to be used as a status
message forwarder. */
void
gpgme_set_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t cb, void *cb_value)
{
TRACE2 (DEBUG_CTX, "gpgme_set_status_cb", ctx, "status_cb=%p/%p",
cb, cb_value);
if (!ctx)
return;
ctx->status_cb = cb;
ctx->status_cb_value = cb_value;
}
/* This function returns the callback function to be used as a
status message forwarder. */
void
gpgme_get_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t *r_cb,
void **r_cb_value)
{
TRACE2 (DEBUG_CTX, "gpgme_get_status_cb", ctx, "ctx->status_cb=%p/%p",
ctx ? ctx->status_cb : NULL, ctx ? ctx->status_cb_value : NULL);
if (r_cb)
*r_cb = NULL;
if (r_cb_value)
*r_cb_value = NULL;
if (!ctx || !ctx->status_cb)
return;
if (r_cb)
*r_cb = ctx->status_cb;
if (r_cb_value)
*r_cb_value = ctx->status_cb_value;
}
/* Set the I/O callback functions for CTX to IO_CBS. */
void
gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
@ -929,41 +996,70 @@ gpgme_sig_notation_get (gpgme_ctx_t ctx)
return ctx->sig_notations;
}
/* Return a public key algorithm string made of the algorithm and size
or the curve name. May return NULL on error. Caller must free the
result using gpgme_free. */
char *
gpgme_pubkey_algo_string (gpgme_subkey_t subkey)
{
const char *prefix = NULL;
char *result;
if (!subkey)
{
gpg_err_set_errno (EINVAL);
return NULL;
}
switch (subkey->pubkey_algo)
{
case GPGME_PK_RSA:
case GPGME_PK_RSA_E:
case GPGME_PK_RSA_S: prefix = "rsa"; break;
case GPGME_PK_ELG_E: prefix = "elg"; break;
case GPGME_PK_DSA: prefix = "dsa"; break;
case GPGME_PK_ELG: prefix = "xxx"; break;
case GPGME_PK_ECC:
case GPGME_PK_ECDH:
case GPGME_PK_ECDSA:
case GPGME_PK_EDDSA: prefix = ""; break;
}
if (prefix && *prefix)
{
char buffer[40];
snprintf (buffer, sizeof buffer, "%s%u", prefix, subkey->length);
result = strdup (buffer);
}
else if (prefix && subkey->curve && *subkey->curve)
result = strdup (subkey->curve);
else if (prefix)
result = strdup ("E_error");
else
result = strdup ("unknown");
return result;
}
const char *
gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
{
switch (algo)
{
case GPGME_PK_RSA:
return "RSA";
case GPGME_PK_RSA_E:
return "RSA-E";
case GPGME_PK_RSA_S:
return "RSA-S";
case GPGME_PK_ELG_E:
return "ELG-E";
case GPGME_PK_DSA:
return "DSA";
case GPGME_PK_ECC:
return "ECC";
case GPGME_PK_ELG:
return "ELG";
case GPGME_PK_ECDSA:
return "ECDSA";
case GPGME_PK_ECDH:
return "ECDH";
default:
return NULL;
case GPGME_PK_RSA: return "RSA";
case GPGME_PK_RSA_E: return "RSA-E";
case GPGME_PK_RSA_S: return "RSA-S";
case GPGME_PK_ELG_E: return "ELG-E";
case GPGME_PK_DSA: return "DSA";
case GPGME_PK_ECC: return "ECC";
case GPGME_PK_ELG: return "ELG";
case GPGME_PK_ECDSA: return "ECDSA";
case GPGME_PK_ECDH: return "ECDH";
case GPGME_PK_EDDSA: return "EdDSA";
default: return NULL;
}
}

View File

@ -217,5 +217,13 @@ EXPORTS
gpgme_op_spawn_start @163
gpgme_op_spawn @164
gpgme_set_offline @165
gpgme_get_offline @166
gpgme_set_status_cb @167
gpgme_get_status_cb @168
gpgme_pubkey_algo_string @169
; END

View File

@ -1,36 +1,28 @@
/* gpgme.h - Public interface to GnuPG Made Easy. -*- c -*-
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009
2010, 2011, 2012, 2013, 2014 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
GPGME 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, see <http://www.gnu.org/licenses/>.
Generated from gpgme.h.in for @GPGME_CONFIG_HOST@. */
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001-2015 g10 Code GmbH
*
* This file is part of GPGME.
*
* GPGME is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* GPGME 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Generated from gpgme.h.in for @GPGME_CONFIG_HOST@.
*/
#ifndef GPGME_H
#define GPGME_H
#ifdef __GNUC__
#define _GPGME_INLINE __inline__
#elif __STDC_VERSION__ >= 199901L
#define _GPGME_INLINE inline
#else
#define _GPGME_INLINE
#endif
/* Include stdio.h for the FILE type definition. */
#include <stdio.h>
#include <time.h>
@ -38,38 +30,12 @@
#ifdef __cplusplus
extern "C" {
#if 0 /* just to make Emacs auto-indent happy */
#if 0 /*(Make Emacsen's auto-indent happy.)*/
}
#endif
#endif /* __cplusplus */
@INSERT__TYPEDEFS_FOR_GPGME_H@
/* Check for compiler features. */
#if __GNUC__
#define _GPGME_GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#if _GPGME_GCC_VERSION > 30100
#define _GPGME_DEPRECATED __attribute__ ((__deprecated__))
#endif
#endif
#ifndef _GPGME_DEPRECATED
#define _GPGME_DEPRECATED
#endif
/* The macro _GPGME_DEPRECATED_OUTSIDE_GPGME suppresses warnings for
fields we must access in GPGME for ABI compatibility. */
#ifdef _GPGME_IN_GPGME
#define _GPGME_DEPRECATED_OUTSIDE_GPGME
#else
#define _GPGME_DEPRECATED_OUTSIDE_GPGME _GPGME_DEPRECATED
#endif
/* The version of this header should match the one of the library. Do
not use this symbol in your application, use gpgme_check_version
instead. The purpose of this macro is to let autoconf (using the
@ -81,6 +47,52 @@ extern "C" {
API incompatibilities. */
#define GPGME_VERSION_NUMBER @VERSION_NUMBER@
/* System specific typedefs. */
@INSERT__TYPEDEFS_FOR_GPGME_H@
/*
* Check for compiler features.
*/
#ifdef GPGRT_INLINE
# define _GPGME_INLINE GPGRT_INLINE
#elif defined(__GNUC__)
# define _GPGME_INLINE __inline__
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
# define _GPGME_INLINE inline
#else
# define _GPGME_INLINE
#endif
#ifdef GPGRT_ATTR_DEPRECATED
# define _GPGME_DEPRECATED GPGRT_ATTR_DEPRECATED
#elif defined(__GNUC__)
# define _GPGME_GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
# if _GPGME_GCC_VERSION > 30100
# define _GPGME_DEPRECATED __attribute__ ((__deprecated__))
# else
# define _GPGME_DEPRECATED
# endif
#else
# define _GPGME_DEPRECATED
#endif
/* The macro _GPGME_DEPRECATED_OUTSIDE_GPGME suppresses warnings for
fields we must access in GPGME for ABI compatibility. */
#ifdef _GPGME_IN_GPGME
#define _GPGME_DEPRECATED_OUTSIDE_GPGME
#else
#define _GPGME_DEPRECATED_OUTSIDE_GPGME _GPGME_DEPRECATED
#endif
/* Check for a matching _FILE_OFFSET_BITS definition. */
#if @NEED__FILE_OFFSET_BITS@
#ifndef _FILE_OFFSET_BITS
@ -94,7 +106,9 @@ extern "C" {
/* Some opaque data types used by GPGME. */
/*
* Some opaque data types used by GPGME.
*/
/* The context holds some global state and configuration options, as
well as the results of a crypto operation. */
@ -105,8 +119,11 @@ typedef struct gpgme_context *gpgme_ctx_t;
struct gpgme_data;
typedef struct gpgme_data *gpgme_data_t;
/* Wrappers for the libgpg-error library. */
/*
* Wrappers for the libgpg-error library.
*/
typedef gpg_error_t gpgme_error_t;
typedef gpg_err_code_t gpgme_err_code_t;
@ -196,7 +213,12 @@ gpgme_error_from_syserror (void)
return gpgme_error (gpgme_err_code_from_syserror ());
}
/*
* Various constants and types
*/
/* The possible encoding mode of gpgme_data_t objects. */
typedef enum
{
@ -210,6 +232,7 @@ typedef enum
}
gpgme_data_encoding_t;
/* Known data types. */
typedef enum
{
@ -226,7 +249,7 @@ typedef enum
}
gpgme_data_type_t;
/* Public key algorithms. */
typedef enum
{
@ -238,7 +261,8 @@ typedef enum
GPGME_PK_ECC = 18,
GPGME_PK_ELG = 20,
GPGME_PK_ECDSA = 301,
GPGME_PK_ECDH = 302
GPGME_PK_ECDH = 302,
GPGME_PK_EDDSA = 303
}
gpgme_pubkey_algo_t;
@ -264,7 +288,7 @@ typedef enum
}
gpgme_hash_algo_t;
/* The possible signature stati. Deprecated, use error value in sig
status. */
typedef enum
@ -292,7 +316,7 @@ typedef enum
}
gpgme_sig_mode_t;
/* The available key and signature attributes. Deprecated, use the
individual result structures instead. */
typedef enum
@ -333,7 +357,7 @@ typedef enum
_gpgme_attr_t;
typedef _gpgme_attr_t gpgme_attr_t _GPGME_DEPRECATED;
/* The available validities for a trust item or key. */
typedef enum
{
@ -346,7 +370,7 @@ typedef enum
}
gpgme_validity_t;
/* The available protocols. */
typedef enum
{
@ -364,7 +388,7 @@ gpgme_protocol_t;
/* Convenience macro for the surprisingly mixed spelling. */
#define GPGME_PROTOCOL_OPENPGP GPGME_PROTOCOL_OpenPGP
/* The available keylist mode flags. */
#define GPGME_KEYLIST_MODE_LOCAL 1
#define GPGME_KEYLIST_MODE_EXTERN 2
@ -376,7 +400,7 @@ gpgme_protocol_t;
typedef unsigned int gpgme_keylist_mode_t;
/* The pinentry modes. */
typedef enum
{
@ -388,59 +412,21 @@ typedef enum
}
gpgme_pinentry_mode_t;
/* The available export mode flags. */
#define GPGME_EXPORT_MODE_EXTERN 2
#define GPGME_EXPORT_MODE_MINIMAL 4
#define GPGME_EXPORT_MODE_SECRET 16
#define GPGME_EXPORT_MODE_RAW 32
#define GPGME_EXPORT_MODE_PKCS12 64
typedef unsigned int gpgme_export_mode_t;
/* Flags for the audit log functions. */
#define GPGME_AUDITLOG_HTML 1
#define GPGME_AUDITLOG_WITH_HELP 128
/* Signature notations. */
/* The available signature notation flags. */
#define GPGME_SIG_NOTATION_HUMAN_READABLE 1
#define GPGME_SIG_NOTATION_CRITICAL 2
typedef unsigned int gpgme_sig_notation_flags_t;
struct _gpgme_sig_notation
{
struct _gpgme_sig_notation *next;
/* If NAME is a null pointer, then VALUE contains a policy URL
rather than a notation. */
char *name;
/* The value of the notation data. */
char *value;
/* The length of the name of the notation data. */
int name_len;
/* The length of the value of the notation data. */
int value_len;
/* The accumulated flags. */
gpgme_sig_notation_flags_t flags;
/* Notation data is human-readable. */
unsigned int human_readable : 1;
/* Notation data is critical. */
unsigned int critical : 1;
/* Internal to GPGME, do not use. */
int _unused : 30;
};
typedef struct _gpgme_sig_notation *gpgme_sig_notation_t;
/* The possible stati for the edit operation. */
typedef enum
{
@ -544,11 +530,56 @@ typedef enum
GPGME_STATUS_PINENTRY_LAUNCHED = 88,
GPGME_STATUS_ATTRIBUTE = 89,
GPGME_STATUS_BEGIN_SIGNING = 90,
GPGME_STATUS_KEY_NOT_CREATED = 91
GPGME_STATUS_KEY_NOT_CREATED = 91,
GPGME_STATUS_INQUIRE_MAXLEN = 92,
GPGME_STATUS_FAILURE = 93
}
gpgme_status_code_t;
/* The available signature notation flags. */
#define GPGME_SIG_NOTATION_HUMAN_READABLE 1
#define GPGME_SIG_NOTATION_CRITICAL 2
typedef unsigned int gpgme_sig_notation_flags_t;
struct _gpgme_sig_notation
{
struct _gpgme_sig_notation *next;
/* If NAME is a null pointer, then VALUE contains a policy URL
rather than a notation. */
char *name;
/* The value of the notation data. */
char *value;
/* The length of the name of the notation data. */
int name_len;
/* The length of the value of the notation data. */
int value_len;
/* The accumulated flags. */
gpgme_sig_notation_flags_t flags;
/* Notation data is human-readable. */
unsigned int human_readable : 1;
/* Notation data is critical. */
unsigned int critical : 1;
/* Internal to GPGME, do not use. */
int _unused : 30;
};
typedef struct _gpgme_sig_notation *gpgme_sig_notation_t;
/*
* Public structures.
*/
/* The engine information structure. */
struct _gpgme_engine_info
{
@ -571,7 +602,7 @@ struct _gpgme_engine_info
};
typedef struct _gpgme_engine_info *gpgme_engine_info_t;
/* A subkey from a key. */
struct _gpgme_subkey
{
@ -826,8 +857,20 @@ struct _gpgme_key
typedef struct _gpgme_key *gpgme_key_t;
/* An invalid key object. */
struct _gpgme_invalid_key
{
struct _gpgme_invalid_key *next;
char *fpr;
gpgme_error_t reason;
};
typedef struct _gpgme_invalid_key *gpgme_invalid_key_t;
/* Types for callback functions. */
/*
* Types for callback functions.
*/
/* Request a passphrase from the user. */
typedef gpgme_error_t (*gpgme_passphrase_cb_t) (void *hook,
@ -839,6 +882,11 @@ typedef gpgme_error_t (*gpgme_passphrase_cb_t) (void *hook,
typedef void (*gpgme_progress_cb_t) (void *opaque, const char *what,
int type, int current, int total);
/* Status messages from gpg. */
typedef gpgme_error_t (*gpgme_status_cb_t) (void *opaque, const char *keyword,
const char *args);
/* Interact with the user about an edit operation. */
typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque,
gpgme_status_code_t status,
@ -847,7 +895,9 @@ typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque,
/* Context management functions. */
/*
* Context management functions.
*/
/* Create a new context and return it in CTX. */
gpgme_error_t gpgme_new (gpgme_ctx_t *ctx);
@ -887,6 +937,12 @@ void gpgme_set_textmode (gpgme_ctx_t ctx, int yes);
/* Return non-zero if text mode is set in CTX. */
int gpgme_get_textmode (gpgme_ctx_t ctx);
/* If YES is non-zero, enable offline mode in CTX, disable it otherwise. */
void gpgme_set_offline (gpgme_ctx_t ctx, int yes);
/* Return non-zero if offline mode is set in CTX. */
int gpgme_get_offline (gpgme_ctx_t ctx);
/* Use whatever the default of the backend crypto engine is. */
#define GPGME_INCLUDE_CERTS_DEFAULT -256
@ -930,6 +986,16 @@ void gpgme_set_progress_cb (gpgme_ctx_t c, gpgme_progress_cb_t cb,
void gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *cb,
void **hook_value);
/* Set the status callback function in CTX to CB. HOOK_VALUE is
passed as first argument to thes status callback function. */
void gpgme_set_status_cb (gpgme_ctx_t c, gpgme_status_cb_t cb,
void *hook_value);
/* Get the current status callback function in *CB and the current
hook value in *HOOK_VALUE. */
void gpgme_get_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t *cb,
void **hook_value);
/* This function sets the locale for the context CTX, or the default
locale if CTX is a null pointer. */
gpgme_error_t gpgme_set_locale (gpgme_ctx_t ctx, int category,
@ -947,16 +1013,6 @@ gpgme_error_t gpgme_ctx_set_engine_info (gpgme_ctx_t ctx,
const char *file_name,
const char *home_dir);
/* Return a statically allocated string with the name of the public
key algorithm ALGO, or NULL if that name is not known. */
const char *gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo);
/* Return a statically allocated string with the name of the hash
algorithm ALGO, or NULL if that name is not known. */
const char *gpgme_hash_algo_name (gpgme_hash_algo_t algo);
/* Delete all signers from CTX. */
void gpgme_signers_clear (gpgme_ctx_t ctx);
@ -995,7 +1051,7 @@ const char *gpgme_get_sig_string_attr (gpgme_ctx_t c, int idx,
gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key)
_GPGME_DEPRECATED;
/* Clear all notation data from the context. */
void gpgme_sig_notation_clear (gpgme_ctx_t ctx);
@ -1011,8 +1067,11 @@ gpgme_error_t gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
/* Get the sig notations for this context. */
gpgme_sig_notation_t gpgme_sig_notation_get (gpgme_ctx_t ctx);
/* Run control. */
/*
* Run control.
*/
/* The type of an I/O callback function. */
typedef gpgme_error_t (*gpgme_io_cb_t) (void *data, int fd);
@ -1085,8 +1144,17 @@ gpgme_ctx_t gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang);
gpgme_ctx_t gpgme_wait_ext (gpgme_ctx_t ctx, gpgme_error_t *status,
gpgme_error_t *op_err, int hang);
/* Cancel a pending asynchronous operation. */
gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx);
/* Cancel a pending operation asynchronously. */
gpgme_error_t gpgme_cancel_async (gpgme_ctx_t ctx);
/* Functions to handle data objects. */
/*
* Functions to handle data objects.
*/
/* Read up to SIZE bytes into buffer BUFFER from the data object with
the handle HANDLE. Return the number of characters read, 0 on EOF
@ -1151,7 +1219,8 @@ gpgme_error_t gpgme_data_new_from_mem (gpgme_data_t *r_dh,
size is returned in R_LEN. */
char *gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len);
/* Release the memory returned by gpgme_data_release_and_get_mem(). */
/* Release the memory returned by gpgme_data_release_and_get_mem() and
some other functions. */
void gpgme_free (void *buffer);
gpgme_error_t gpgme_data_new_from_cbs (gpgme_data_t *dh,
@ -1209,14 +1278,20 @@ gpgme_error_t gpgme_data_new_from_filepart (gpgme_data_t *r_dh,
gpgme_data_seek instead. */
gpgme_error_t gpgme_data_rewind (gpgme_data_t dh) _GPGME_DEPRECATED;
/* Key and trust functions. */
/*
* Key and trust functions.
*/
/* Get the key with the fingerprint FPR from the crypto backend. If
SECRET is true, get the secret key. */
gpgme_error_t gpgme_get_key (gpgme_ctx_t ctx, const char *fpr,
gpgme_key_t *r_key, int secret);
/* Create a dummy key to specify an email address. */
gpgme_error_t gpgme_key_from_uid (gpgme_key_t *key, const char *name);
/* Acquire a reference to KEY. */
void gpgme_key_ref (gpgme_key_t key);
@ -1259,26 +1334,12 @@ unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx,
const void *reserved, int idx)
_GPGME_DEPRECATED;
/* Crypto Operations. */
/* Cancel a pending asynchronous operation. */
gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx);
/* Cancel a pending operation asynchronously. */
gpgme_error_t gpgme_cancel_async (gpgme_ctx_t ctx);
struct _gpgme_invalid_key
{
struct _gpgme_invalid_key *next;
char *fpr;
gpgme_error_t reason;
};
typedef struct _gpgme_invalid_key *gpgme_invalid_key_t;
/*
* Encryption.
*/
/* Encryption. */
struct _gpgme_op_encrypt_result
{
/* The list of invalid recipients. */
@ -1322,7 +1383,9 @@ gpgme_error_t gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
gpgme_data_t plain, gpgme_data_t cipher);
/* Decryption. */
/*
* Decryption.
*/
struct _gpgme_recipient
{
@ -1379,7 +1442,10 @@ gpgme_error_t gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
gpgme_data_t plain);
/* Signing. */
/*
* Signing.
*/
struct _gpgme_new_signature
{
struct _gpgme_new_signature *next;
@ -1435,7 +1501,9 @@ gpgme_error_t gpgme_op_sign (gpgme_ctx_t ctx,
gpgme_sig_mode_t mode);
/* Verify. */
/*
* Verify.
*/
/* Flags used for the SUMMARY field in a gpgme_signature_t. */
typedef enum
@ -1450,7 +1518,7 @@ typedef enum
GPGME_SIGSUM_CRL_MISSING = 0x0100, /* CRL not available. */
GPGME_SIGSUM_CRL_TOO_OLD = 0x0200, /* Available CRL is too old. */
GPGME_SIGSUM_BAD_POLICY = 0x0400, /* A policy was not met. */
GPGME_SIGSUM_SYS_ERROR = 0x0800 /* A system error occured. */
GPGME_SIGSUM_SYS_ERROR = 0x0800 /* A system error occurred. */
}
gpgme_sigsum_t;
@ -1524,22 +1592,15 @@ gpgme_error_t gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig,
gpgme_data_t plaintext);
/* Import. */
/*
* Import/Export
*/
/* The key was new. */
#define GPGME_IMPORT_NEW 1
/* The key contained new user IDs. */
#define GPGME_IMPORT_UID 2
/* The key contained new signatures. */
#define GPGME_IMPORT_SIG 4
/* The key contained new sub keys. */
#define GPGME_IMPORT_SUBKEY 8
/* The key contained a secret key. */
#define GPGME_IMPORT_SECRET 16
#define GPGME_IMPORT_NEW 1 /* The key was new. */
#define GPGME_IMPORT_UID 2 /* The key contained new user IDs. */
#define GPGME_IMPORT_SIG 4 /* The key contained new signatures. */
#define GPGME_IMPORT_SUBKEY 8 /* The key contained new sub keys. */
#define GPGME_IMPORT_SECRET 16 /* The key contained a secret key. */
struct _gpgme_import_status
@ -1549,7 +1610,7 @@ struct _gpgme_import_status
/* Fingerprint. */
char *fpr;
/* If a problem occured, the reason why the key could not be
/* If a problem occurred, the reason why the key could not be
imported. Otherwise GPGME_No_Error. */
gpgme_error_t result;
@ -1560,7 +1621,7 @@ struct _gpgme_import_status
};
typedef struct _gpgme_import_status *gpgme_import_status_t;
/* Import. */
/* Import result object. */
struct _gpgme_op_import_result
{
/* Number of considered keys. */
@ -1624,7 +1685,6 @@ gpgme_error_t gpgme_op_import_keys_start (gpgme_ctx_t ctx, gpgme_key_t keys[]);
gpgme_error_t gpgme_op_import_keys (gpgme_ctx_t ctx, gpgme_key_t keys[]);
/* Export the keys found by PATTERN into KEYDATA. */
gpgme_error_t gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern,
gpgme_export_mode_t mode,
@ -1653,7 +1713,10 @@ gpgme_error_t gpgme_op_export_keys (gpgme_ctx_t ctx,
/* Key generation. */
/*
* Key generation.
*/
struct _gpgme_op_genkey_result
{
/* A primary key was generated. */
@ -1681,7 +1744,7 @@ gpgme_error_t gpgme_op_genkey (gpgme_ctx_t ctx, const char *parms,
/* Retrieve a pointer to the result of the genkey operation. */
gpgme_genkey_result_t gpgme_op_genkey_result (gpgme_ctx_t ctx);
/* Delete KEY from the keyring. If ALLOW_SECRET is non-zero, secret
keys are also deleted. */
gpgme_error_t gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key,
@ -1689,7 +1752,12 @@ gpgme_error_t gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key,
gpgme_error_t gpgme_op_delete (gpgme_ctx_t ctx, const gpgme_key_t key,
int allow_secret);
/*
* Key Edit interface
*/
/* Edit the key KEY. Send status and command requests to FNC and
output of edit commands to OUT. */
gpgme_error_t gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
@ -1709,27 +1777,11 @@ gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
gpgme_data_t out);
/* Flags for the spawn operations. */
#define GPGME_SPAWN_DETACHED 1
#define GPGME_SPAWN_ALLOW_SET_FG 2
/* Run the command FILE with the arguments in ARGV. Connect stdin to
DATAIN, stdout to DATAOUT, and STDERR to DATAERR. If one the data
streams is NULL, connect to /dev/null instead. */
gpgme_error_t gpgme_op_spawn_start (gpgme_ctx_t ctx,
const char *file, const char *argv[],
gpgme_data_t datain,
gpgme_data_t dataout, gpgme_data_t dataerr,
unsigned int flags);
gpgme_error_t gpgme_op_spawn (gpgme_ctx_t ctx,
const char *file, const char *argv[],
gpgme_data_t datain,
gpgme_data_t dataout, gpgme_data_t dataerr,
unsigned int flags);
/* Key management functions. */
/*
* Key listing
*/
struct _gpgme_op_keylist_result
{
unsigned int truncated : 1;
@ -1766,7 +1818,9 @@ gpgme_error_t gpgme_op_passwd (gpgme_ctx_t ctx, gpgme_key_t key,
/* Trust items and operations. */
/*
* Trust items and operations.
*/
struct _gpgme_trust_item
{
@ -1841,7 +1895,12 @@ int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what,
const void *reserved, int idx)
_GPGME_DEPRECATED;
/*
* Audit log
*/
/* Return the auditlog for the current session. This may be called
after a successful or failed operation. If no audit log is
available GPG_ERR_NO_DATA is returned. */
@ -1852,7 +1911,33 @@ gpgme_error_t gpgme_op_getauditlog (gpgme_ctx_t ctx, gpgme_data_t output,
/* Low-level Assuan protocol access. */
/*
* Spawn interface
*/
/* Flags for the spawn operations. */
#define GPGME_SPAWN_DETACHED 1
#define GPGME_SPAWN_ALLOW_SET_FG 2
/* Run the command FILE with the arguments in ARGV. Connect stdin to
DATAIN, stdout to DATAOUT, and STDERR to DATAERR. If one the data
streams is NULL, connect to /dev/null instead. */
gpgme_error_t gpgme_op_spawn_start (gpgme_ctx_t ctx,
const char *file, const char *argv[],
gpgme_data_t datain,
gpgme_data_t dataout, gpgme_data_t dataerr,
unsigned int flags);
gpgme_error_t gpgme_op_spawn (gpgme_ctx_t ctx,
const char *file, const char *argv[],
gpgme_data_t datain,
gpgme_data_t dataout, gpgme_data_t dataerr,
unsigned int flags);
/*
* Low-level Assuan protocol access.
*/
typedef gpgme_error_t (*gpgme_assuan_data_cb_t)
(void *opaque, const void *data, size_t datalen);
@ -1911,7 +1996,10 @@ gpgme_op_assuan_transact (gpgme_ctx_t ctx,
void *status_cb_value) _GPGME_DEPRECATED;
/* Crypto container support. */
/*
* Crypto container support.
*/
struct _gpgme_op_vfs_mount_result
{
char *mount_dir;
@ -1932,7 +2020,9 @@ gpgme_error_t gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
unsigned int flags, gpgme_error_t *op_err);
/* Interface to gpgconf(1). */
/*
* Interface to gpgconf(1).
*/
/* The expert level at which a configuration option or group of
options should be displayed. See the gpgconf(1) documentation for
@ -2096,15 +2186,11 @@ gpgme_error_t gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p);
follow chained components! */
gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp);
/* UIServer support. */
/* Create a dummy key to specify an email address. */
gpgme_error_t gpgme_key_from_uid (gpgme_key_t *key, const char *name);
/* Various functions. */
/*
* Various functions.
*/
/* Set special global flags; consult the manual before use. */
int gpgme_set_global_flag (const char *name, const char *value);
@ -2139,19 +2225,32 @@ gpgme_error_t gpgme_set_engine_info (gpgme_protocol_t proto,
const char *file_name,
const char *home_dir);
/* Engine support functions. */
/* Verify that the engine implementing PROTO is installed and
available. */
gpgme_error_t gpgme_engine_check_version (gpgme_protocol_t proto);
/* Reference counting for result objects. */
void gpgme_result_ref (void *result);
void gpgme_result_unref (void *result);
/* Return a public key algorithm string (e.g. "rsa2048"). Caller must
free using gpgme_free. */
char *gpgme_pubkey_algo_string (gpgme_subkey_t subkey);
/* Return a statically allocated string with the name of the public
key algorithm ALGO, or NULL if that name is not known. */
const char *gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo);
/* Return a statically allocated string with the name of the hash
algorithm ALGO, or NULL if that name is not known. */
const char *gpgme_hash_algo_name (gpgme_hash_algo_t algo);
/* Deprecated types. */
/*
* Deprecated types.
*/
typedef gpgme_ctx_t GpgmeCtx _GPGME_DEPRECATED;
typedef gpgme_data_t GpgmeData _GPGME_DEPRECATED;
typedef gpgme_error_t GpgmeError _GPGME_DEPRECATED;

View File

@ -889,6 +889,7 @@ gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
gpgme_error_t err;
void *hook;
op_data_t opd;
int flags = 0;
TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_start", ctx,
"pattern=%s, secret_only=%i", pattern, secret_only);
@ -913,8 +914,11 @@ gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
if (err)
return TRACE_ERR (err);
if (ctx->offline)
flags |= GPGME_ENGINE_FLAG_OFFLINE;
err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
ctx->keylist_mode);
ctx->keylist_mode, flags);
return TRACE_ERR (err);
}
@ -929,6 +933,7 @@ gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
gpgme_error_t err;
void *hook;
op_data_t opd;
int flags = 0;
TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_ext_start", ctx,
"secret_only=%i, reserved=0x%x", secret_only, reserved);
@ -952,8 +957,12 @@ gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
if (err)
return TRACE_ERR (err);
if (ctx->offline)
flags |= GPGME_ENGINE_FLAG_OFFLINE;
err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
reserved, ctx->keylist_mode);
reserved, ctx->keylist_mode,
flags);
return TRACE_ERR (err);
}

View File

@ -92,6 +92,14 @@ GPGME_1.1 {
gpgme_op_spawn_start;
gpgme_op_spawn;
gpgme_set_offline;
gpgme_get_offline;
gpgme_set_status_cb;
gpgme_get_status_cb;
gpgme_pubkey_algo_string;
};

View File

@ -337,3 +337,27 @@ _gpgme_parse_plaintext (char *args, char **filenamep)
}
return 0;
}
/* Parse a FAILURE status line and return the error code. ARGS is
modified to contain the location part. */
gpgme_error_t
_gpgme_parse_failure (char *args)
{
char *where, *which;
where = strchr (args, ' ');
if (!where)
return trace_gpg_error (GPG_ERR_INV_ENGINE);
*where = '\0';
which = where + 1;
where = strchr (which, ' ');
if (where)
*where = '\0';
where = args;
return atoi (which);
}

View File

@ -65,6 +65,10 @@ gpgme_error_t _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key);
FILENAMEP. */
gpgme_error_t _gpgme_parse_plaintext (char *args, char **filenamep);
/* Parse a FAILURE status line and return the error code. ARGS is
modified to contain the location part. */
gpgme_error_t _gpgme_parse_failure (char *args);
/* From verify.c. */

View File

@ -41,6 +41,7 @@ typedef struct
char *uid_hint;
char *passphrase_info;
int bad_passphrase;
char *maxlen;
} *op_data_t;
@ -53,6 +54,7 @@ release_op_data (void *hook)
free (opd->passphrase_info);
if (opd->uid_hint)
free (opd->uid_hint);
free (opd->maxlen);
}
@ -73,6 +75,11 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
switch (code)
{
case GPGME_STATUS_INQUIRE_MAXLEN:
free (opd->maxlen);
if (!(opd->maxlen = strdup (args)))
return gpg_error_from_syserror ();
break;
case GPGME_STATUS_USERID_HINT:
if (opd->uid_hint)
free (opd->uid_hint);
@ -109,6 +116,31 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
return gpg_error (GPG_ERR_BAD_PASSPHRASE);
break;
case GPGME_STATUS_ERROR:
/* We abuse this status handler to forward ERROR status codes to
the caller. This should better be done in a generic handler,
but for now this is sufficient. */
if (ctx->status_cb)
{
err = ctx->status_cb (ctx->status_cb_value, "ERROR", args);
if (err)
return err;
}
break;
case GPGME_STATUS_FAILURE:
/* We abuse this status handler to forward FAILURE status codes
to the caller. This should better be done in a generic
handler, but for now this is sufficient. */
if (ctx->status_cb)
{
err = ctx->status_cb (ctx->status_cb_value, "FAILURE", args);
if (err)
return err;
}
break;
default:
/* Ignore all other codes. */
break;
@ -141,9 +173,14 @@ _gpgme_passphrase_command_handler (void *priv, gpgme_status_code_t code,
if (processed)
*processed = 1;
err = ctx->passphrase_cb (ctx->passphrase_cb_value,
opd->uid_hint, opd->passphrase_info,
opd->bad_passphrase, fd);
if (ctx->status_cb && opd->maxlen)
err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN",
opd->maxlen);
if (!err)
err = ctx->passphrase_cb (ctx->passphrase_cb_value,
opd->uid_hint, opd->passphrase_info,
opd->bad_passphrase, fd);
/* Reset bad passphrase flag, in case it is correct now. */
opd->bad_passphrase = 0;

View File

@ -30,6 +30,9 @@
typedef struct
{
/* The error code from a FAILURE status line or 0. */
gpg_error_t failure_code;
int success_seen;
int error_seen;
} *op_data_t;
@ -92,6 +95,10 @@ passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
opd->success_seen = 1;
break;
case GPGME_STATUS_FAILURE:
opd->failure_code = _gpgme_parse_failure (args);
break;
case GPGME_STATUS_EOF:
/* In case the OpenPGP engine does not properly implement the
passwd command we won't get a success status back and thus we
@ -102,6 +109,8 @@ passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
if (ctx->protocol == GPGME_PROTOCOL_OpenPGP
&& !opd->error_seen && !opd->success_seen)
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
else if (opd->failure_code)
err = opd->failure_code;
break;
default:
@ -139,6 +148,14 @@ passwd_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key,
_gpgme_engine_set_status_handler (ctx->engine, passwd_status_handler, ctx);
if (ctx->passphrase_cb)
{
err = _gpgme_engine_set_command_handler
(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
if (err)
return err;
}
return _gpgme_engine_op_passwd (ctx->engine, key, flags);
}

View File

@ -23,6 +23,9 @@
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <string.h>
#include <assert.h>
#include <errno.h>
@ -331,6 +334,16 @@ get_max_fds (void)
fds = 1024;
}
/* AIX returns INT32_MAX instead of a proper value. We assume that
* this is always an error and use a more reasonable limit. */
#ifdef INT32_MAX
if (fds == INT32_MAX)
{
source = "aix-fix";
fds = 1024;
}
#endif
TRACE2 (DEBUG_SYSIO, "gpgme:max_fds", 0, "max fds=%i (%s)", fds, source);
return fds;
}

View File

@ -71,6 +71,15 @@ _gpgme_set_default_gpgconf_name (const char *name)
}
/* Dummy function - see w32-util.c for the actual code. */
int
_gpgme_set_override_inst_dir (const char *dir)
{
(void)dir;
return 0;
}
/* Find an executable program PGM along the envvar PATH. */
static char *
walk_path (const char *pgm)

View File

@ -39,6 +39,9 @@ typedef struct
{
struct _gpgme_op_sign_result result;
/* The error code from a FAILURE status line or 0. */
gpg_error_t failure_code;
/* A pointer to the next pointer of the last invalid signer in
the list. This makes appending new invalid signers painless
while preserving the order. */
@ -327,6 +330,10 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
opd->last_signer_p = &(*opd->last_signer_p)->next;
break;
case GPGME_STATUS_FAILURE:
opd->failure_code = _gpgme_parse_failure (args);
break;
case GPGME_STATUS_EOF:
/* The UI server does not send information about the created
signature. This is irrelevant for this protocol and thus we
@ -335,7 +342,12 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
else if (!opd->sig_created_seen
&& ctx->protocol != GPGME_PROTOCOL_UISERVER)
err = gpg_error (GPG_ERR_GENERAL);
err = opd->failure_code? opd->failure_code:gpg_error (GPG_ERR_GENERAL);
break;
case GPGME_STATUS_INQUIRE_MAXLEN:
if (ctx->status_cb)
err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
break;
default:
@ -369,6 +381,7 @@ sign_init_result (gpgme_ctx_t ctx, int ignore_inv_recp)
opd = hook;
if (err)
return err;
opd->failure_code = 0;
opd->last_signer_p = &opd->result.invalid_signers;
opd->last_sig_p = &opd->result.signatures;
opd->ignore_inv_recp = !!ignore_inv_recp;

View File

@ -66,6 +66,7 @@ static struct status_table_s status_table[] =
{ "ERRSIG", GPGME_STATUS_ERRSIG },
{ "EXPKEYSIG", GPGME_STATUS_EXPKEYSIG },
{ "EXPSIG", GPGME_STATUS_EXPSIG },
{ "FAILURE", GPGME_STATUS_FAILURE },
{ "FILE_DONE", GPGME_STATUS_FILE_DONE },
{ "FILE_ERROR", GPGME_STATUS_FILE_ERROR },
{ "FILE_START", GPGME_STATUS_FILE_START },
@ -80,6 +81,7 @@ static struct status_table_s status_table[] =
{ "IMPORT_PROBLEM", GPGME_STATUS_IMPORT_PROBLEM },
{ "IMPORT_RES", GPGME_STATUS_IMPORT_RES },
{ "IMPORTED", GPGME_STATUS_IMPORTED },
{ "INQUIRE_MAXLEN", GPGME_STATUS_INQUIRE_MAXLEN },
{ "INV_RECP", GPGME_STATUS_INV_RECP },
{ "INV_SGNR", GPGME_STATUS_INV_SGNR },
{ "KEY_CREATED", GPGME_STATUS_KEY_CREATED },

View File

@ -23,8 +23,13 @@
/*-- {posix,w32}-util.c --*/
int _gpgme_set_default_gpg_name (const char *name);
int _gpgme_set_default_gpgconf_name (const char *name);
int _gpgme_set_override_inst_dir (const char *dir);
char *_gpgme_get_gpg_path (void);
char *_gpgme_get_gpgconf_path (void);
#ifdef HAVE_W32_SYSTEM
const char *_gpgme_get_inst_dir (void);
#endif
#endif /* SYS_UTIL_H */

View File

@ -38,6 +38,9 @@ typedef struct
{
struct _gpgme_op_verify_result result;
/* The error code from a FAILURE status line or 0. */
gpg_error_t failure_code;
gpgme_signature_t current_sig;
int did_prepare_new_sig;
int only_newsig_seen;
@ -195,6 +198,10 @@ calc_sig_summary (gpgme_signature_t sig)
sum |= GPGME_SIGSUM_KEY_MISSING;
break;
case GPG_ERR_CERT_REVOKED:
sum |= GPGME_SIGSUM_KEY_REVOKED;
break;
case GPG_ERR_BAD_SIGNATURE:
case GPG_ERR_NO_ERROR:
break;
@ -213,6 +220,9 @@ calc_sig_summary (gpgme_signature_t sig)
break;
case GPG_ERR_CERT_REVOKED:
/* Note that this is a second way to set this flag. It may also
have been set due to a sig->status of STATUS_REVKEYSIG from
parse_new_sig. */
sum |= GPGME_SIGSUM_KEY_REVOKED;
break;
@ -762,6 +772,10 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
error code if we are not ready to process this status. */
return parse_error (sig, args, !!sig );
case GPGME_STATUS_FAILURE:
opd->failure_code = _gpgme_parse_failure (args);
break;
case GPGME_STATUS_EOF:
if (sig && !opd->did_prepare_new_sig)
calc_sig_summary (sig);
@ -788,6 +802,8 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
opd->current_sig = NULL;
}
opd->only_newsig_seen = 0;
if (opd->failure_code)
return opd->failure_code;
break;
case GPGME_STATUS_PLAINTEXT:

View File

@ -39,7 +39,7 @@ BEGIN
VALUE "FileDescription", "GPGME - GnuPG Made Easy\0"
VALUE "FileVersion", "@LIBGPGME_LT_CURRENT@.@LIBGPGME_LT_AGE@.@LIBGPGME_LT_REVISION@.@BUILD_REVISION@\0"
VALUE "InternalName", "gpgme\0"
VALUE "LegalCopyright", "Copyright © 2001-2013 g10 Code GmbH\0"
VALUE "LegalCopyright", "Copyright © 2001-2015 g10 Code GmbH\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "gpgme.dll\0"
VALUE "PrivateBuild", "\0"

View File

@ -98,7 +98,7 @@ static struct
FD is closed. This, together with the fact that dup'ed file
descriptors are closed before the file descriptors from which
they are dup'ed are closed, ensures that CHAN is always valid,
and shared among all file descriptors refering to the same
and shared among all file descriptors referring to the same
underlying object.
The logic behind this is that there is only one reason for us to

View File

@ -74,7 +74,7 @@ static struct
that dup'ed file descriptors are closed before the file
descriptors from which they are dup'ed are closed, ensures that
the handle or socket is always valid, and shared among all file
descriptors refering to the same underlying object.
descriptors referring to the same underlying object.
The logic behind this is that there is only one reason for us to
dup file descriptors anyway: to allow simpler book-keeping of
@ -978,7 +978,7 @@ _gpgme_io_write (int fd, const void *buffer, size_t count)
return TRACE_SYSRES (-1);
}
/* If no error occured, the number of bytes in the buffer must be
/* If no error occurred, the number of bytes in the buffer must be
zero. */
assert (!ctx->nbytes);
@ -1550,6 +1550,7 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
int debug_me = 0;
int tmp_fd;
char *tmp_name;
const char *spawnhelper;
TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_spawn", path,
"path=%s", path);
@ -1603,7 +1604,8 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
if ((flags & IOSPAWN_FLAG_DETACHED))
cr_flags |= DETACHED_PROCESS;
cr_flags |= GetPriorityClass (GetCurrentProcess ());
if (!CreateProcessA (_gpgme_get_w32spawn_path (),
spawnhelper = _gpgme_get_w32spawn_path ();
if (!CreateProcessA (spawnhelper,
arg_string,
&sec_attr, /* process security attributes */
&sec_attr, /* thread security attributes */
@ -1614,7 +1616,10 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
&si, /* startup information */
&pi)) /* returns process information */
{
TRACE_LOG1 ("CreateProcess failed: ec=%d", (int) GetLastError ());
int lasterr = (int)GetLastError ();
TRACE_LOG1 ("CreateProcess failed: ec=%d", lasterr);
if (lasterr == ERROR_INVALID_PARAMETER)
TRACE_LOG1 ("(is '%s' correctly installed?)", spawnhelper);
free (arg_string);
close (tmp_fd);
DeleteFileA (tmp_name);

View File

@ -85,7 +85,10 @@ static HMODULE my_hmodule;
binaries. The are set only once by gpgme_set_global_flag. */
static char *default_gpg_name;
static char *default_gpgconf_name;
/* If this variable is not NULL the value is assumed to be the
installation directory. The variable may only be set once by
gpgme_set_global_flag and accessed by _gpgme_get_inst_dir. */
static char *override_inst_dir;
#ifdef HAVE_ALLOW_SET_FOREGROUND_WINDOW
@ -347,6 +350,9 @@ _gpgme_get_inst_dir (void)
{
static char *inst_dir;
if (override_inst_dir)
return override_inst_dir;
LOCK (get_path_lock);
if (!inst_dir)
{
@ -397,48 +403,19 @@ find_program_in_dir (const char *dir, const char *name)
}
static char *
find_program_in_inst_dir (const char *inst_dir, const char *name)
{
char *result;
char *dir;
/* If an installation directory has been passed, this overrides a
location given by the registry. The idea here is that we prefer
a program installed alongside with gpgme. We don't want the
registry to override this to have a better isolation of an gpgme
aware applications for other effects. Note that the "Install
Directory" registry item has been used for ages in Gpg4win and
earlier GnuPG windows installers. It is technically not anymore
required. */
if (inst_dir)
{
result = find_program_in_dir (inst_dir, name);
if (result)
return result;
}
dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
"Software\\GNU\\GnuPG",
"Install Directory");
if (dir)
{
result = find_program_in_dir (dir, name);
free (dir);
return result;
}
return NULL;
}
static char *
find_program_at_standard_place (const char *name)
{
char path[MAX_PATH];
char *result = NULL;
/* See http://wiki.tcl.tk/17492 for details on compatibility. */
if (SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILES, 0))
/* See http://wiki.tcl.tk/17492 for details on compatibility.
We First try the generic place and then fallback to the x86
(i.e. 32 bit) place. This will prefer a 64 bit of the program
over a 32 bit version on 64 bit Windows if installed. */
if (SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILES, 0)
|| SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILESX86, 0))
{
result = malloc (strlen (path) + 1 + strlen (name) + 1);
if (result)
@ -490,30 +467,73 @@ _gpgme_set_default_gpgconf_name (const char *name)
}
/* Set the override installation directory. This function may only be
called by gpgme_set_global_flag. Returns 0 on success. */
int
_gpgme_set_override_inst_dir (const char *dir)
{
if (!override_inst_dir)
{
override_inst_dir = malloc (strlen (dir) + 1);
if (override_inst_dir)
{
strcpy (override_inst_dir, dir);
replace_slashes (override_inst_dir);
/* Remove a trailing slash. */
if (*override_inst_dir
&& override_inst_dir[strlen (override_inst_dir)-1] == '\\')
override_inst_dir[strlen (override_inst_dir)-1] = 0;
}
}
return !override_inst_dir;
}
/* Return the full file name of the GPG binary. This function is used
if gpgconf was not found and thus it can be assumed that gpg2 is
iff gpgconf was not found and thus it can be assumed that gpg2 is
not installed. This function is only called by get_gpgconf_item
and may not be called concurrently. */
char *
_gpgme_get_gpg_path (void)
{
char *gpg;
const char *inst_dir, *name;
char *gpg = NULL;
const char *name, *inst_dir;
name = default_gpg_name? get_basename (default_gpg_name) : "gpg.exe";
/* 1. Try to find gpg.exe in the installation directory of gpgme. */
inst_dir = _gpgme_get_inst_dir ();
gpg = find_program_in_inst_dir
(inst_dir,
default_gpg_name? get_basename (default_gpg_name) : "gpg.exe");
if (inst_dir)
{
gpg = find_program_in_dir (inst_dir, name);
}
/* 2. Try to find gpg.exe using that ancient registry key. */
if (!gpg)
{
name = (default_gpg_name? default_gpg_name
/* */ : "GNU\\GnuPG\\gpg.exe");
gpg = find_program_at_standard_place (name);
if (!gpg)
_gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpg_path: '%s' not found",
name);
char *dir;
dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
"Software\\GNU\\GnuPG",
"Install Directory");
if (dir)
{
gpg = find_program_in_dir (dir, name);
free (dir);
}
}
/* 3. Try to find gpg.exe below CSIDL_PROGRAM_FILES. */
if (!gpg)
{
name = default_gpg_name? default_gpg_name : "GNU\\GnuPG\\gpg.exe";
gpg = find_program_at_standard_place (name);
}
/* 4. Print a debug message if not found. */
if (!gpg)
_gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpg_path: '%s' not found", name);
return gpg;
}
@ -523,22 +543,52 @@ _gpgme_get_gpg_path (void)
char *
_gpgme_get_gpgconf_path (void)
{
char *gpgconf;
char *gpgconf = NULL;
const char *inst_dir, *name;
name = default_gpgconf_name? get_basename(default_gpgconf_name):"gpgconf.exe";
/* 1. Try to find gpgconf.exe in the installation directory of gpgme. */
inst_dir = _gpgme_get_inst_dir ();
gpgconf = find_program_in_inst_dir
(inst_dir,
default_gpgconf_name? get_basename (default_gpgconf_name) : "gpgconf.exe");
if (inst_dir)
{
gpgconf = find_program_in_dir (inst_dir, name);
}
/* 2. Try to find gpgconf.exe from GnuPG >= 2.1 below CSIDL_PROGRAM_FILES. */
if (!gpgconf)
{
name = (default_gpgconf_name? default_gpgconf_name
/* */ : "GNU\\GnuPG\\gpgconf.exe");
gpgconf = find_program_at_standard_place (name);
if (!gpgconf)
_gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpgconf_path: '%s' not found",
name);
const char *name2 = (default_gpgconf_name ? default_gpgconf_name
/**/ : "GnuPG\\bin\\gpgconf.exe");
gpgconf = find_program_at_standard_place (name2);
}
/* 3. Try to find gpgconf.exe using that ancient registry key. This
should eventually be removed. */
if (!gpgconf)
{
char *dir;
dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
"Software\\GNU\\GnuPG",
"Install Directory");
if (dir)
{
gpgconf = find_program_in_dir (dir, name);
free (dir);
}
}
/* 4. Try to find gpgconf.exe from Gpg4win below CSIDL_PROGRAM_FILES. */
if (!gpgconf)
{
gpgconf = find_program_at_standard_place ("GNU\\GnuPG\\gpgconf.exe");
}
/* 5. Print a debug message if not found. */
if (!gpgconf)
_gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpgconf_path: '%s' not found",name);
return gpgconf;
}
@ -552,10 +602,7 @@ _gpgme_get_w32spawn_path (void)
inst_dir = _gpgme_get_inst_dir ();
LOCK (get_path_lock);
if (!w32spawn_program)
w32spawn_program = find_program_in_inst_dir (inst_dir,"gpgme-w32spawn.exe");
if (!w32spawn_program)
w32spawn_program
= find_program_at_standard_place ("GNU\\GnuPG\\gpgme-w32spawn.exe");
w32spawn_program = find_program_in_dir (inst_dir, "gpgme-w32spawn.exe");
UNLOCK (get_path_lock);
return w32spawn_program;
}
@ -600,7 +647,7 @@ static const char letters[] =
does not exist at the time of the call to mkstemp. TMPL is
overwritten with the result. */
static int
mkstemp (char *tmpl)
my_mkstemp (char *tmpl)
{
int len;
char *XXXXXX;
@ -708,7 +755,7 @@ _gpgme_mkstemp (int *fd, char **name)
if (!tmpname)
return -1;
strcpy (stpcpy (tmpname, tmp), "\\gpgme-XXXXXX");
*fd = mkstemp (tmpname);
*fd = my_mkstemp (tmpname);
if (fd < 0)
{
free (tmpname);

View File

@ -206,7 +206,7 @@ _gpgme_wait_global_event_cb (void *data, gpgme_event_io_t type,
gpgme_error_t err = ctx_active (ctx);
if (err)
/* An error occured. Close all fds in this context, and
/* An error occurred. Close all fds in this context, and
send the error in a done event. */
_gpgme_cancel_with_err (ctx, err, 0);
}
@ -325,7 +325,7 @@ gpgme_wait_ext (gpgme_ctx_t ctx, gpgme_error_t *status,
err = _gpgme_run_io_cb (&fdt.fds[i], 0, &local_op_err);
if (err || local_op_err)
{
/* An error occured. Close all fds in this context,
/* An error occurred. Close all fds in this context,
and signal it. */
_gpgme_cancel_with_err (ictx, err, local_op_err);

View File

@ -89,7 +89,7 @@ _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond,
if (nr < 0)
{
/* An error occured. Close all fds in this context, and
/* An error occurred. Close all fds in this context, and
signal it. */
err = gpg_error_from_syserror ();
_gpgme_cancel_with_err (ctx, err, 0);
@ -116,7 +116,7 @@ _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond,
err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0, &op_err);
if (err)
{
/* An error occured. Close all fds in this context,
/* An error occurred. Close all fds in this context,
and signal it. */
_gpgme_cancel_with_err (ctx, err, 0);
@ -124,7 +124,7 @@ _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond,
}
else if (op_err)
{
/* An operational error occured. Cancel the current
/* An operational error occurred. Cancel the current
operation but not the session, and signal it. */
_gpgme_cancel_with_err (ctx, 0, op_err);

View File

@ -23,9 +23,10 @@ TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir)
TESTS = t-version t-data t-engine-info
EXTRA_DIST = t-data-1.txt t-data-2.txt ChangeLog-2011
EXTRA_DIST = start-stop-agent t-data-1.txt t-data-2.txt ChangeLog-2011
AM_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_CFLAGS@
AM_LDFLAGS = -no-install
LDADD = ../src/libgpgme.la @GPG_ERROR_LIBS@
noinst_HEADERS = run-support.h

View File

@ -22,7 +22,8 @@
GPG = gpg
GPG_AGENT = gpg-agent
TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) LC_ALL=C GPG_AGENT_INFO=
TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) LC_ALL=C GPG_AGENT_INFO= \
top_srcdir=$(top_srcdir)
# The keylist tests must come after the import and the edit test.
noinst_HEADERS = t-support.h
@ -43,7 +44,7 @@ TESTS = initial.test $(c_tests) final.test
CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \
gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \
random_seed S.gpg-agent .gpg-v21-migrated
random_seed S.gpg-agent .gpg-v21-migrated pubring-stamp
private_keys = \
13CD0F3BDF24BE53FE192D62F18737256FF6E4FD \
@ -53,11 +54,12 @@ private_keys = \
7A030357C0F253A5BBCD282FFC4E521B37558F5C
EXTRA_DIST = start-stop-agent initial.test final.test \
EXTRA_DIST = initial.test final.test \
pubdemo.asc secdemo.asc cipher-1.asc cipher-2.asc \
geheim.txt pubkey-1.asc seckey-1.asc pinentry $(private_keys)
AM_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_CFLAGS@
AM_LDFLAGS = -no-install
LDADD = ../../src/libgpgme.la
t_thread1_LDADD = ../../src/libgpgme-pthread.la -lpthread
@ -65,12 +67,16 @@ t_thread1_LDADD = ../../src/libgpgme-pthread.la -lpthread
noinst_PROGRAMS = $(c_tests) t-genkey
clean-local:
-$(srcdir)/start-stop-agent --stop
-$(top_srcdir)/tests/start-stop-agent --stop
-rm -fR private-keys-v1.d
check-local: ./gpg.conf ./gpg-agent.conf ./pubring.gpg \
check-local: ./gpg.conf ./gpg-agent.conf ./pubring-stamp \
./private-keys-v1.d/gpg-sample.stamp
# To guarantee that check-local is run before any tests we
# add this dependency:
initial.test : check-local
export GNUPGHOME := $(abs_builddir)
export GPG_AGENT_INFO :=
@ -82,11 +88,12 @@ export GPG_AGENT_INFO :=
done
echo x > ./private-keys-v1.d/gpg-sample.stamp
./pubring.gpg: $(srcdir)/pubdemo.asc
-$(GPG) --no-permission-warning \
--import $(srcdir)/pubdemo.asc
./pubring-stamp: $(srcdir)/pubdemo.asc
$(GPG) --no-permission-warning \
--import $(srcdir)/pubdemo.asc
-$(GPG) --no-permission-warning \
--import $(srcdir)/secdemo.asc
touch ./pubring-stamp
./gpg.conf:
# This is required for t-sig-notations.

View File

@ -1,4 +1,4 @@
#!/bin/sh
${srcdir}/start-stop-agent --stop
${top_srcdir}/tests/start-stop-agent --stop
exit 0

View File

@ -1,4 +1,4 @@
#!/bin/sh
${srcdir}/start-stop-agent --start
${top_srcdir}/tests/start-stop-agent --start
exit 0

View File

@ -21,20 +21,26 @@
GPGSM = gpgsm
TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) GPG_AGENT_INFO=
TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) LC_ALL=C GPG_AGENT_INFO= \
top_srcdir=$(top_srcdir)
noinst_HEADERS = t-support.h
TESTS = t-import t-keylist t-encrypt t-verify t-decrypt t-sign t-export
c_tests = t-import t-keylist t-encrypt t-verify t-decrypt t-sign t-export
TESTS = initial.test $(c_tests) final.test
EXTRA_DIST = cert_dfn_pca01.der cert_dfn_pca15.der cert_g10code_test1.der \
$(key_id)
$(key_id) initial.test final.test
AM_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_CFLAGS@
AM_LDFLAGS = -no-install
LDADD = ../../src/libgpgme.la
# We don't run t-genkey in the test suite, because it takes too long
# and needs a working pinentry.
noinst_PROGRAMS = $(TESTS) t-genkey cms-keylist cms-decrypt
noinst_PROGRAMS = $(c_tests) t-genkey cms-keylist cms-decrypt
key_id = 32100C27173EF6E9C4E9A25D3D69F86D37A4F939
@ -42,12 +48,16 @@ CLEANFILES = pubring.kbx pubring.kbx~ gpgsm.conf trustlist.txt \
random_seed S.gpg-agent
clean-local:
-gpg-connect-agent KILLAGENT /bye
-$(top_srcdir)/tests/start-stop-agent --stop
-rm -fR private-keys-v1.d
check-local: ./pubring.kbx ./gpgsm.conf \
./private-keys-v1.d/$(key_id).key ./trustlist.txt
# To guarantee that check-local is run before any tests we add this
# dependency:
initial.test : check-local
export GNUPGHOME := $(abs_builddir)
export GPG_AGENT_INFO :=

5
tests/gpgsm/final.test Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh
${top_srcdir}/tests/start-stop-agent --stop
exit 0

4
tests/gpgsm/initial.test Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
${top_srcdir}/tests/start-stop-agent --start
exit 0

View File

@ -43,7 +43,12 @@ show_usage (int ex)
fputs ("usage: " PGM " [options] USERIDS\n\n"
"Options:\n"
" --verbose run in verbose mode\n"
" --openpgp use OpenPGP protocol (default)\n"
" --cms use X.509 protocol\n"
" --extern send keys to the keyserver (TAKE CARE!)\n"
" --secret export secret keys instead of public keys\n"
" --raw use PKCS#1 as secret key format\n"
" --pkcs12 use PKCS#12 as secret key format\n"
, stderr);
exit (ex);
}
@ -59,6 +64,7 @@ main (int argc, char **argv)
gpgme_key_t keyarray[100];
int keyidx = 0;
gpgme_data_t out;
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
gpgme_export_mode_t mode = 0;
if (argc)
@ -79,9 +85,34 @@ main (int argc, char **argv)
verbose = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--openpgp"))
{
protocol = GPGME_PROTOCOL_OpenPGP;
argc--; argv++;
}
else if (!strcmp (*argv, "--cms"))
{
protocol = GPGME_PROTOCOL_CMS;
argc--; argv++;
}
else if (!strcmp (*argv, "--extern"))
{
mode |= GPGME_KEYLIST_MODE_EXTERN;
mode |= GPGME_EXPORT_MODE_EXTERN;
argc--; argv++;
}
else if (!strcmp (*argv, "--secret"))
{
mode |= GPGME_EXPORT_MODE_SECRET;
argc--; argv++;
}
else if (!strcmp (*argv, "--raw"))
{
mode |= GPGME_EXPORT_MODE_RAW;
argc--; argv++;
}
else if (!strcmp (*argv, "--pkcs12"))
{
mode |= GPGME_EXPORT_MODE_PKCS12;
argc--; argv++;
}
else if (!strncmp (*argv, "--", 2))
@ -92,11 +123,11 @@ main (int argc, char **argv)
if (!argc)
show_usage (1);
init_gpgme (GPGME_PROTOCOL_OpenPGP);
init_gpgme (protocol);
err = gpgme_new (&ctx);
fail_if_err (err);
gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP);
gpgme_set_protocol (ctx, protocol);
/* Lookup the keys. */
err = gpgme_op_keylist_ext_start (ctx, (const char**)argv, 0, 0);
@ -131,8 +162,10 @@ main (int argc, char **argv)
}
/* Now for the actual export. */
if ((mode & GPGME_KEYLIST_MODE_EXTERN))
if ((mode & GPGME_EXPORT_MODE_EXTERN))
printf ("sending keys to keyserver\n");
if ((mode & GPGME_EXPORT_MODE_SECRET))
printf ("exporting secret keys!\n");
err = gpgme_data_new (&out);
fail_if_err (err);

View File

@ -45,6 +45,7 @@ show_usage (int ex)
" --verbose run in verbose mode\n"
" --openpgp use the OpenPGP protocol (default)\n"
" --cms use the CMS protocol\n"
" --secret list only secret keys\n"
" --local use GPGME_KEYLIST_MODE_LOCAL\n"
" --extern use GPGME_KEYLIST_MODE_EXTERN\n"
" --sigs use GPGME_KEYLIST_MODE_SIGS\n"
@ -52,6 +53,7 @@ show_usage (int ex)
" --ephemeral use GPGME_KEYLIST_MODE_EPHEMERAL\n"
" --validate use GPGME_KEYLIST_MODE_VALIDATE\n"
" --import import all keys\n"
" --offline use offline mode\n"
, stderr);
exit (ex);
}
@ -70,6 +72,8 @@ main (int argc, char **argv)
gpgme_key_t keyarray[100];
int keyidx = 0;
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
int only_secret = 0;
int offline = 0;
if (argc)
{ argc--; argv++; }
@ -99,6 +103,11 @@ main (int argc, char **argv)
protocol = GPGME_PROTOCOL_CMS;
argc--; argv++;
}
else if (!strcmp (*argv, "--secret"))
{
only_secret = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--local"))
{
mode |= GPGME_KEYLIST_MODE_LOCAL;
@ -134,6 +143,11 @@ main (int argc, char **argv)
import = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--offline"))
{
offline = 1;
argc--; argv++;
}
else if (!strncmp (*argv, "--", 2))
show_usage (1);
@ -150,7 +164,9 @@ main (int argc, char **argv)
gpgme_set_keylist_mode (ctx, mode);
err = gpgme_op_keylist_start (ctx, argc? argv[0]:NULL, 0);
gpgme_set_offline (ctx, offline);
err = gpgme_op_keylist_start (ctx, argc? argv[0]:NULL, only_secret);
fail_if_err (err);
while (!(err = gpgme_op_keylist_next (ctx, &key)))

View File

@ -36,6 +36,14 @@
static int verbose;
static gpg_error_t
status_cb (void *opaque, const char *keyword, const char *value)
{
(void)opaque;
printf ("status_cb: %s %s\n", keyword, value);
return 0;
}
static void
print_result (gpgme_sign_result_t result, gpgme_sig_mode_t type)
@ -67,9 +75,11 @@ show_usage (int ex)
fputs ("usage: " PGM " [options] FILE\n\n"
"Options:\n"
" --verbose run in verbose mode\n"
" --status print status lines from the backend\n"
" --openpgp use the OpenPGP protocol (default)\n"
" --cms use the CMS protocol\n"
" --uiserver use the UI server\n"
" --loopback use a loopback pinentry\n"
" --key NAME use key NAME for signing\n"
, stderr);
exit (ex);
@ -87,6 +97,8 @@ main (int argc, char **argv)
gpgme_sig_mode_t sigmode = GPGME_SIG_MODE_NORMAL;
gpgme_data_t in, out;
gpgme_sign_result_t result;
int print_status = 0;
int use_loopback = 0;
if (argc)
{ argc--; argv++; }
@ -106,6 +118,11 @@ main (int argc, char **argv)
verbose = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--status"))
{
print_status = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--openpgp"))
{
protocol = GPGME_PROTOCOL_OpenPGP;
@ -129,6 +146,11 @@ main (int argc, char **argv)
key_string = *argv;
argc--; argv++;
}
else if (!strcmp (*argv, "--loopback"))
{
use_loopback = 1;
argc--; argv++;
}
else if (!strncmp (*argv, "--", 2))
show_usage (1);
@ -149,6 +171,10 @@ main (int argc, char **argv)
fail_if_err (err);
gpgme_set_protocol (ctx, protocol);
gpgme_set_armor (ctx, 1);
if (print_status)
gpgme_set_status_cb (ctx, status_cb, NULL);
if (use_loopback)
gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK);
if (key_string)
{

View File

@ -143,7 +143,7 @@ read_test (round_t round, gpgme_data_t data)
read = gpgme_data_read (data, buffer, sizeof (buffer));
if (read > 0)
{
fprintf (stderr, "%s:%d: (%i) gpgme_data_read succeded unexpectedly\n",
fprintf (stderr, "%s:%d: (%i) gpgme_data_read succeeded unexpectedly\n",
__FILE__, __LINE__, round);
exit (1);
}