aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndre Heinecke <[email protected]>2018-07-04 13:39:01 +0000
committerAndre Heinecke <[email protected]>2018-07-05 09:29:36 +0000
commita2458806f8bf04b66795e1dde765b42fe1ef6797 (patch)
tree0eebff2f24f9f8bfdce1871b4041bccd293773d9 /src
parentcpp: Fix memory of DecryptionResult::symkeyAlgo (diff)
downloadgpgme-a2458806f8bf04b66795e1dde765b42fe1ef6797.tar.gz
gpgme-a2458806f8bf04b66795e1dde765b42fe1ef6797.zip
core: Add gpg auditlog to get diagnostics
* src/engine-gpg.c (engine_gpg): Add diagnostics member. (gpg_release): Release diagnostics data. (gpg_new): Set up logger-fd and diagnostics. (gpg_getauditlog): New. Copy diagnostics to a user data. (engine_ops): Add getauditlog. * src/engine-gpgsm.c (gpgsm_getauditlog): Return not implemented for GPGME_AUDITLOG_DIAG. * src/getauditlog.c (getauditlog_start): Don't reset engine for diagnostics. * src/gpgme.h.in (GPGME_AUDITLOG_DIAG): New. (GPGME_AUDITLOG_DEFAULT): New alias to 0. * tests/run-decrypt.c (show_usage, main): Add --diagnostics. * doc/gpgme.texi(Additional Logs): Document getauditlog. -- This enables users of GPGME to get more verbose information from gpg which can assist users in figuring out a problem that was before hidden behind a generalized error like "Decryption Failed". For GPGSM it is not yet available as it is problematic to get it properly in server mode and GPGSM already had the original audit log mechanism in place. GPGME_AUDITLOG_DEFAULT was added for a more explicit documentation.
Diffstat (limited to 'src')
-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
4 files changed, 72 insertions, 4 deletions
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