aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--doc/gpgme.texi65
-rw-r--r--src/engine-gpg.c62
-rw-r--r--src/engine-gpgsm.c3
-rw-r--r--src/getauditlog.c9
-rw-r--r--src/gpgme.h.in2
-rw-r--r--tests/run-decrypt.c29
7 files changed, 168 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 6c33c258..9c641100 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ Noteworthy changes in version 1.11.2 (unreleased)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_decrypt_result_t EXTENDED: New field legacy_cipher_nomdc.
gpgme_set_ctx_flag EXTENDED: New flag 'ignore-mdc-error'.
+ GPGME_AUDITLOG_DEFAULT NEW.
+ GPGME_AUDITLOG_DIAG NEW.
cpp: DecryptionResult::sessionKey NEW.
cpp: DecryptionResult::symkeyAlgo NEW.
cpp: DecryptionResult::isLegacyCipherNoMDC New.
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index e3445a0e..3dac60d0 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -2426,6 +2426,7 @@ started. In fact, these references are accessed through the
* Progress Meter Callback:: Being informed about the progress.
* Status Message Callback:: Status messages received from gpg.
* Locale:: Setting the locale of a context.
+* Additional Logs:: Additional logs of a context.
@end menu
@@ -3155,6 +3156,70 @@ The function returns an error if not enough memory is available.
@end deftypefun
+@node Additional Logs
+@subsection Additional Logs
+@cindex auditlog, of the engine
+@cindex auditlog
+
+Additional logs can be associated with a context. These logs are
+engine specific and can be be obtained with @code{gpgme_op_getauditlog}.
+
+@deftypefun gpgme_error_t gpgme_op_getauditlog @
+ (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_data_t @var{output}}, @
+ @w{unsigned int @var{flags}})
+@since{1.1.1}
+
+The function @code{gpgme_op_getauditlog} is used to obtain additional
+logs as specified by @var{flags} into the @var{output} data. If
+
+The function returns the error code @code{GPG_ERR_NO_ERROR} if a
+log could be queried from the engine, and @code{GPG_ERR_NOT_IMPLEMENTED}
+if the log specified in @var{flags} is not available for this engine.
+If no log is available @code{GPG_ERR_NO_DATA} is returned.
+
+The value in @var{flags} is a bitwise-or combination of one or
+multiple of the following bit values:
+
+@table @code
+@item GPGME_AUDITLOG_DIAG
+@since{1.11.2}
+
+Obtain diagnostic output which would be written to @code{stderr} in
+interactive use of the engine. This can be used to provide additional
+diagnostic information in case of errors in other operations.
+
+Note: If log-file has been set in the configuration the log will
+be empty and @code{GPG_ERR_NO_DATA} will be returned.
+
+Implemented for: @code{GPGME_PROTOCOL_OpenPGP}
+
+@item GPGME_AUDITLOG_DEFAULT
+@since{1.11.2}
+
+This flag has the value 0 for compatibility reasons. Obtains additional
+information from the engine by issuing the @code{GETAUDITLOG} command.
+For @code{GPGME_PROTOCOL_CMS} this provides additional information about
+the X509 certificate chain.
+
+Implemented for: @code{GPGME_PROTOCOL_CMS}
+
+@item GPGME_AUDITLOG_HTML
+@since{1.1.1}
+
+Same as @code{GPGME_AUDITLOG_DEFAULT} but in HTML.
+
+Implemented for: @code{GPGME_PROTOCOL_CMS}
+@end table
+@end deftypefun
+
+@deftypefun gpgme_error_t gpgme_op_getauditlog_start @
+ (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_data_t @var{output}}, @
+ @w{unsigned int @var{flags}})
+@since{1.1.1}
+
+This is the asynchronous variant of @code{gpgme_op_getauditlog}.
+@end deftypefun
+
@node Key Management
@section Key Management
@cindex key management
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 802af08d..f096bcbf 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -149,6 +149,9 @@ struct engine_gpg
/* NULL or the data object fed to --override_session_key-fd. */
gpgme_data_t override_session_key;
+
+ /* Memory data containing diagnostics (--logger-fd) of gpg */
+ gpgme_data_t diagnostics;
};
typedef struct engine_gpg *engine_gpg_t;
@@ -452,6 +455,7 @@ gpg_release (void *engine)
free (gpg->cmd.keyword);
gpgme_data_release (gpg->override_session_key);
+ gpgme_data_release (gpg->diagnostics);
free (gpg);
}
@@ -620,6 +624,16 @@ gpg_new (void **engine, const char *file_name, const char *home_dir,
}
}
+ rc = gpgme_data_new (&gpg->diagnostics);
+ if (rc)
+ goto leave;
+
+ rc = add_arg (gpg, "--logger-fd");
+ if (rc)
+ goto leave;
+
+ rc = add_data (gpg, gpg->diagnostics, -2, 1);
+
leave:
if (rc)
gpg_release (gpg);
@@ -3243,6 +3257,52 @@ gpg_set_pinentry_mode (void *engine, gpgme_pinentry_mode_t mode)
}
+static gpgme_error_t
+gpg_getauditlog (void *engine, gpgme_data_t output, unsigned int flags)
+{
+ engine_gpg_t gpg = engine;
+#define MYBUFLEN 4096
+ char buf[MYBUFLEN];
+ int nread;
+ int any_written = 0;
+
+ if (!(flags & GPGME_AUDITLOG_DIAG))
+ {
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ }
+
+ if (!gpg || !output)
+ {
+ return gpg_error (GPG_ERR_INV_VALUE);
+ }
+
+ if (!gpg->diagnostics)
+ {
+ return gpg_error (GPG_ERR_GENERAL);
+ }
+
+ gpgme_data_rewind (gpg->diagnostics);
+
+ while ((nread = gpgme_data_read (gpg->diagnostics, buf, MYBUFLEN)) > 0)
+ {
+ any_written = 1;
+ if (gpgme_data_write (output, buf, nread) == -1)
+ return gpg_error_from_syserror ();
+ }
+ if (!any_written)
+ {
+ return gpg_error (GPG_ERR_NO_DATA);
+ }
+
+ if (nread == -1)
+ return gpg_error_from_syserror ();
+
+ gpgme_data_rewind (output);
+ return 0;
+#undef MYBUFLEN
+}
+
+
struct engine_ops _gpgme_engine_ops_gpg =
{
@@ -3280,7 +3340,7 @@ struct engine_ops _gpgme_engine_ops_gpg =
gpg_sign,
gpg_trustlist,
gpg_verify,
- NULL, /* getauditlog */
+ gpg_getauditlog,
NULL, /* opassuan_transact */
NULL, /* conf_load */
NULL, /* conf_save */
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index 84a9315d..3266e360 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -2064,6 +2064,9 @@ gpgsm_getauditlog (void *engine, gpgme_data_t output, unsigned int flags)
if (!gpgsm || !output)
return gpg_error (GPG_ERR_INV_VALUE);
+ if ((flags & GPGME_AUDITLOG_DIAG))
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
#if USE_DESCRIPTOR_PASSING
gpgsm->output_cb.data = output;
err = gpgsm_set_fd (gpgsm, OUTPUT_FD, 0);
diff --git a/src/getauditlog.c b/src/getauditlog.c
index dbaf260e..d70e66fd 100644
--- a/src/getauditlog.c
+++ b/src/getauditlog.c
@@ -47,9 +47,12 @@ getauditlog_start (gpgme_ctx_t ctx, int synchronous,
if (!output)
return gpg_error (GPG_ERR_INV_VALUE);
- err = _gpgme_op_reset (ctx, ((synchronous&255) | 256) );
- if (err)
- return err;
+ if (!(flags & GPGME_AUDITLOG_DIAG))
+ {
+ err = _gpgme_op_reset (ctx, ((synchronous&255) | 256) );
+ if (err)
+ return err;
+ }
_gpgme_engine_set_status_handler (ctx->engine,
getauditlog_status_handler, ctx);
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 5279f6a2..421199a9 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -404,7 +404,9 @@ typedef unsigned int gpgme_export_mode_t;
/* Flags for the audit log functions. */
+#define GPGME_AUDITLOG_DEFAULT 0
#define GPGME_AUDITLOG_HTML 1
+#define GPGME_AUDITLOG_DIAG 2
#define GPGME_AUDITLOG_WITH_HELP 128
diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c
index 99a15c7e..c9d9e72d 100644
--- a/tests/run-decrypt.c
+++ b/tests/run-decrypt.c
@@ -88,6 +88,7 @@ show_usage (int ex)
" --no-symkey-cache disable the use of that cache\n"
" --ignore-mdc-error allow decryption of legacy data\n"
" --unwrap remove only the encryption layer\n"
+ " --diagnostics print diagnostics\n"
, stderr);
exit (ex);
}
@@ -112,6 +113,7 @@ main (int argc, char **argv)
int no_symkey_cache = 0;
int ignore_mdc_error = 0;
int raw_output = 0;
+ int diagnostics = 0;
if (argc)
{ argc--; argv++; }
@@ -177,6 +179,11 @@ main (int argc, char **argv)
ignore_mdc_error = 1;
argc--; argv++;
}
+ else if (!strcmp (*argv, "--diagnostics"))
+ {
+ diagnostics = 1;
+ argc--; argv++;
+ }
else if (!strcmp (*argv, "--unwrap"))
{
flags |= GPGME_DECRYPT_UNWRAP;
@@ -283,6 +290,28 @@ main (int argc, char **argv)
err = gpgme_op_decrypt_ext (ctx, flags, in, out);
result = gpgme_op_decrypt_result (ctx);
+
+ if (diagnostics)
+ {
+ gpgme_data_t diag;
+ gpgme_error_t diag_err;
+
+ gpgme_data_new (&diag);
+ diag_err = gpgme_op_getauditlog (ctx, diag, GPGME_AUDITLOG_DIAG);
+ if (diag_err)
+ {
+ fprintf (stderr, PGM ": getting diagnostics failed: %s\n",
+ gpgme_strerror (diag_err));
+ }
+ else
+ {
+ fputs ("Begin Diagnostics:\n", stdout);
+ print_data (diag);
+ fputs ("End Diagnostics.\n", stdout);
+ }
+ gpgme_data_release (diag);
+ }
+
if (err)
{
fprintf (stderr, PGM ": decrypt failed: %s\n", gpgme_strerror (err));