Merge branch 'master' into passphrase-inquire

This commit is contained in:
Ben Kibbey 2015-08-14 20:56:14 -04:00
commit aa89252256
29 changed files with 304 additions and 98 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+

12
NEWS
View File

@ -1,7 +1,17 @@
Noteworthy changes in version 1.6.0 (unreleased) [C__/A__/R_]
Noteworthy changes in version 1.6.0 (unreleased) [C24/A13/R_]
------------------------------------------------
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

@ -59,7 +59,7 @@ LIBGPGME_LT_CURRENT=24
# 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_REVISION=4
# If the API is changed in an incompatible way: increment the next counter.
GPGME_CONFIG_API_VERSION=1

View File

@ -189,6 +189,7 @@ 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.
@ -2286,6 +2287,7 @@ 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.
@ -2415,6 +2417,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

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;

View File

@ -80,11 +80,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;
}
@ -223,8 +224,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 +242,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 +283,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

@ -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

@ -1456,7 +1456,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 +1479,7 @@ gpg_delete (void *engine, gpgme_key_t key, int allow_secret)
}
if (!err)
start (gpg);
err = start (gpg);
return err;
}
@ -1497,7 +1497,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;
}
@ -2194,6 +2194,7 @@ gpg_keylist_preprocess (char *line, char **r_line)
{
*dst++ = '\\';
*dst++ = '\\';
src++;
}
else
*(dst++) = *(src++);
@ -2278,7 +2279,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 +2298,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 +2364,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

@ -564,7 +564,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 +572,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 +585,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);
@ -1528,7 +1542,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 +1599,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 +1634,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 +1674,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

@ -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

@ -3728,6 +3728,7 @@ 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" },
{ "lib-version", 502, 0, 0, "Show library version" },
{ 0 }
};
@ -3736,7 +3737,7 @@ static struct argp argp = { options, parse_options, args_doc, doc };
struct args
{
enum { CMD_DEFAULT, CMD_SERVER } cmd;
enum { CMD_DEFAULT, CMD_SERVER, CMD_LIBVERSION } cmd;
const char *gpg_binary;
};
@ -3762,6 +3763,11 @@ parse_options (int key, char *arg, struct argp_state *state)
case 501:
args->gpg_binary = arg;
break;
case 502:
args->cmd = CMD_LIBVERSION;
break;
#if 0
case ARGP_KEY_ARG:
if (state->arg_num >= 2)
@ -3787,6 +3793,7 @@ main (int argc, char *argv[])
struct args args;
struct gpgme_tool gt;
gpg_error_t err;
int needgt = 1;
#ifdef HAVE_SETLOCALE
setlocale (LC_ALL, "");
@ -3804,7 +3811,10 @@ main (int argc, char *argv[])
argp_parse (&argp, argc, argv, 0, 0, &args);
log_init ();
if (args.gpg_binary)
if (args.cmd == CMD_LIBVERSION)
needgt = 0;
if (needgt && args.gpg_binary)
{
if (access (args.gpg_binary, X_OK))
err = gpg_error_from_syserror ();
@ -3816,7 +3826,8 @@ main (int argc, char *argv[])
args.gpg_binary);
}
gt_init (&gt);
if (needgt)
gt_init (&gt);
switch (args.cmd)
{
@ -3824,9 +3835,17 @@ main (int argc, char *argv[])
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. */

View File

@ -472,6 +472,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. */

View File

@ -218,7 +218,10 @@ EXPORTS
gpgme_op_spawn_start @163
gpgme_op_spawn @164
gpgme_set_status_cb @165
gpgme_get_status_cb @166
gpgme_set_offline @165
gpgme_get_offline @166
gpgme_set_status_cb @167
gpgme_get_status_cb @168
; END

View File

@ -893,6 +893,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

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

@ -93,6 +93,9 @@ GPGME_1.1 {
gpgme_op_spawn_start;
gpgme_op_spawn;
gpgme_set_offline;
gpgme_get_offline;
gpgme_set_status_cb;
gpgme_get_status_cb;
};

View File

@ -195,6 +195,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 +217,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;

View File

@ -23,7 +23,7 @@ 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@
LDADD = ../src/libgpgme.la @GPG_ERROR_LIBS@

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

@ -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)))