From 4dbd2fbdfebbd610f9376a2a60472d4061e5b3c4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 22 Nov 2007 16:44:37 +0000 Subject: [PATCH] New API gpgme_op_getauditlog. --- AUTHORS | 1 + NEWS | 6 +++- assuan/assuan-buffer.c | 4 +-- assuan/mkerrors | 32 +++++++++++++---- gpgme/ChangeLog | 12 +++++++ gpgme/Makefile.am | 2 +- gpgme/engine-backend.h | 4 ++- gpgme/engine-gpgsm.c | 36 +++++++++++++++++++ gpgme/engine.c | 14 ++++++++ gpgme/engine.h | 4 +++ gpgme/getauditlog.c | 81 ++++++++++++++++++++++++++++++++++++++++++ gpgme/gpgme.def | 3 ++ gpgme/gpgme.h | 15 ++++++++ gpgme/libgpgme.vers | 3 ++ gpgme/rungpg.c | 1 + tests/gpgsm/t-verify.c | 17 +++++++++ 16 files changed, 224 insertions(+), 11 deletions(-) create mode 100644 gpgme/getauditlog.c diff --git a/AUTHORS b/AUTHORS index f948079..188792d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2,6 +2,7 @@ Package: gpgme Maintainer: Marcus Brinkmann Bug reports: bug-gpgme@gnupg.org Security related bug reports: security@gnupg.org +License: LGPLv2.1+ FSF diff --git a/NEWS b/NEWS index 3e9f4e6..d64a3eb 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ Noteworthy changes in version 1.1.6 (unreleased) * Interface changes relative to the 1.1.1 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_signature_t EXTENDED: New field chain_model. + gpgme_op_getauditlog_start NEW. + gpgme_op_getauditlog NEW. + GPGME_AUDITLOG_HTML NEW. + GPGME_AUDITLOG_WITH_HELP NEW. Noteworthy changes in version 1.1.5 (2007-07-09) @@ -1192,7 +1196,7 @@ Noteworthy changes in version 0.2.1 (2001-04-02) * Made the W32 support more robust. - Copyright 2001, 2002, 2003, 2004, 2005 g10 Code GmbH + Copyright 2001, 2002, 2003, 2004, 2005, 2007 g10 Code GmbH This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/assuan/assuan-buffer.c b/assuan/assuan-buffer.c index b06025b..1fad0b5 100644 --- a/assuan/assuan-buffer.c +++ b/assuan/assuan-buffer.c @@ -135,10 +135,10 @@ _assuan_read_line (assuan_context_t ctx) if (rc) { if (ctx->log_fp) - fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s]\n", + fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s (%d)]\n", assuan_get_assuan_log_prefix (), (unsigned int)getpid (), ctx->inbound.fd, - strerror (errno)); + strerror (errno), errno); return _assuan_error (ASSUAN_Read_Error); } if (!nread) diff --git a/assuan/mkerrors b/assuan/mkerrors index 5748541..28451f6 100755 --- a/assuan/mkerrors +++ b/assuan/mkerrors @@ -16,9 +16,7 @@ # 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, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - +# License along with this program; if not, see . cat < 0 && errno < 4096) + { + n = (EAGAIN | (1 << 15)); + break; + } default: n = 270; /*GPG_ERR_ASS_READ_ERROR*/ break; } break; @@ -98,6 +107,12 @@ _assuan_error (int oldcode) switch (errno) { case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/ break; + case EAGAIN: + if (errno > 0 && errno < 4096) + { + n = (EAGAIN | (1 << 15)); + break; + } default: n = 271; /*GPG_ERR_ASS_WRITE_ERROR*/ break; } break; @@ -111,7 +126,12 @@ _assuan_error (int oldcode) an error is indeed returned. */ n = 16381; /*GPG_ERR_MISSING_ERRNO*/ break; - case ENOMEM: n = (1 << 15) | 86; break; + case ENOMEM: + if (errno > 0 && errno < 4096) + { + n = (ENOMEM | (1 << 15)); + break; + } default: n = 16382; /*GPG_ERR_UNKNOWN_ERRNO*/ break; diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index e6366c3..03f72a9 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,15 @@ +2007-11-22 Werner Koch + + * gpgme.h (gpgme_op_getauditlog_start, gpgme_op_getauditlog): New. + * libgpgme.vers: Ditto. + * gpgme.def: Ditto. + * getauditlog.c: New. + * engine-backend.h (struct engine_ops): Add member GETAUDITLOG. + * engine-gpgsm.c (gpgsm_getauditlog): New. + (_gpgme_engine_ops_gpgsm): Insert new function. + (gpgsm_new): Try to enable audit log support. + * rungpg.c (_gpgme_engine_ops_gpg): Insert dummy entry. + 2007-11-20 Werner Koch * op-support.c (_gpgme_parse_inv_recp): Add new reason code 11. diff --git a/gpgme/Makefile.am b/gpgme/Makefile.am index 18b44de..f74dffe 100644 --- a/gpgme/Makefile.am +++ b/gpgme/Makefile.am @@ -98,7 +98,7 @@ main_sources = \ encrypt.c encrypt-sign.c decrypt.c decrypt-verify.c verify.c \ sign.c passphrase.c progress.c \ key.c keylist.c trust-item.c trustlist.c \ - import.c export.c genkey.c delete.c edit.c \ + import.c export.c genkey.c delete.c edit.c getauditlog.c \ engine.h engine-backend.h engine.c rungpg.c status-table.h \ $(gpgsm_components) sema.h priv-io.h $(system_components) \ debug.c debug.h gpgme.c version.c error.c diff --git a/gpgme/engine-backend.h b/gpgme/engine-backend.h index 052e724..f1b4dc0 100644 --- a/gpgme/engine-backend.h +++ b/gpgme/engine-backend.h @@ -94,7 +94,9 @@ struct engine_ops gpgme_error_t (*verify) (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, gpgme_data_t plaintext); - + gpgme_error_t (*getauditlog) (void *engine, gpgme_data_t output, + unsigned int flags); + void (*set_io_cbs) (void *engine, gpgme_io_cbs_t io_cbs); void (*io_event) (void *engine, gpgme_event_io_t type, void *type_data); diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index f024916..ffb6d3f 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -515,6 +515,15 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir) } } + /* Ask gpgsm to enable the audit log support. */ + if (!err) + { + err = assuan_transact (gpgsm->assuan_ctx, "OPTION enable-audit-log=1", + NULL, NULL, NULL, NULL, NULL, NULL); + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION) + err = 0; /* This is an optional feature of gpgsm. */ + } + #if !USE_DESCRIPTOR_PASSING if (!err && (_gpgme_io_set_close_notify (gpgsm->input_cb.fd, @@ -1704,6 +1713,32 @@ gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, } +/* Send the GETAUDITLOG command. The result is saved to a gpgme data + object. */ +static gpgme_error_t +gpgsm_getauditlog (void *engine, gpgme_data_t output, unsigned int flags) +{ + engine_gpgsm_t gpgsm = engine; + gpgme_error_t err = 0; + + if (!gpgsm || !output) + return gpg_error (GPG_ERR_INV_VALUE); + + gpgsm->output_cb.data = output; + err = gpgsm_set_fd (gpgsm, OUTPUT_FD, 0); + if (err) + return err; + + gpgsm_clear_fd (gpgsm, INPUT_FD); + gpgsm_clear_fd (gpgsm, MESSAGE_FD); + + err = start (gpgsm, "GETAUDITLOG"); + + return err; +} + + + static void gpgsm_set_status_handler (void *engine, engine_status_handler_t fnc, void *fnc_value) @@ -1782,6 +1817,7 @@ struct engine_ops _gpgme_engine_ops_gpgsm = gpgsm_sign, NULL, /* trustlist */ gpgsm_verify, + gpgsm_getauditlog, gpgsm_set_io_cbs, gpgsm_io_event, gpgsm_cancel diff --git a/gpgme/engine.c b/gpgme/engine.c index a64b462..ef7147d 100644 --- a/gpgme/engine.c +++ b/gpgme/engine.c @@ -710,6 +710,20 @@ _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig, } +gpgme_error_t +_gpgme_engine_op_getauditlog (engine_t engine, gpgme_data_t output, + unsigned int flags) +{ + if (!engine) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!engine->ops->getauditlog) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + return (*engine->ops->getauditlog) (engine->engine, output, flags); +} + + void _gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs) { diff --git a/gpgme/engine.h b/gpgme/engine.h index 1fe24f5..6c636e0 100644 --- a/gpgme/engine.h +++ b/gpgme/engine.h @@ -123,6 +123,10 @@ gpgme_error_t _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig, gpgme_data_t signed_text, gpgme_data_t plaintext); +gpgme_error_t _gpgme_engine_op_getauditlog (engine_t engine, + gpgme_data_t output, + unsigned int flags); + void _gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs); void _gpgme_engine_io_event (engine_t engine, diff --git a/gpgme/getauditlog.c b/gpgme/getauditlog.c new file mode 100644 index 0000000..e48637b --- /dev/null +++ b/gpgme/getauditlog.c @@ -0,0 +1,81 @@ +/* getauditlog.c - Retrieve the audit log. + Copyright (C) 2007 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 . + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include "gpgme.h" +#include "context.h" +#include "ops.h" + + +static gpgme_error_t +getauditlog_status_handler (void *priv, gpgme_status_code_t code, char *args) +{ + return 0; +} + + +static gpgme_error_t +getauditlog_start (gpgme_ctx_t ctx, int synchronous, + gpgme_data_t output, unsigned int flags) +{ + gpgme_error_t err; + + if (!output) + return gpg_error (GPG_ERR_INV_VALUE); + + err = _gpgme_op_reset (ctx, synchronous); + if (err) + return err; + + _gpgme_engine_set_status_handler (ctx->engine, + getauditlog_status_handler, ctx); + + return _gpgme_engine_op_getauditlog (ctx->engine, output, flags); +} + + + +/* 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. This is the asynchronous + variant. */ +gpgme_error_t +gpgme_op_getauditlog_start (gpgme_ctx_t ctx, + gpgme_data_t output, unsigned int flags) +{ + return getauditlog_start (ctx, 0, output, flags); +} + + +/* 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. This is the synchronous + variant. */ +gpgme_error_t +gpgme_op_getauditlog (gpgme_ctx_t ctx, gpgme_data_t output, unsigned int flags) +{ + gpgme_error_t err = getauditlog_start (ctx, 1, output, flags); + if (!err) + err = _gpgme_wait_one (ctx); + return err; +} + diff --git a/gpgme/gpgme.def b/gpgme/gpgme.def index bb2caf2..57dbe40 100644 --- a/gpgme/gpgme.def +++ b/gpgme/gpgme.def @@ -156,5 +156,8 @@ EXPORTS gpgme_get_giochannel @121 gpgme_get_fdptr @122 + gpgme_op_getauditlog_start @123 + gpgme_op_getauditlog @124 + ; END diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index 5daac08..b867419 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -314,6 +314,11 @@ gpgme_protocol_t; typedef unsigned int gpgme_keylist_mode_t; + +/* Flags for the audit log functions. */ +#define GPGME_AUDITLOG_HTML 1 +#define GPGME_AUDITLOG_WITH_HELP 128 + /* Signature notations. */ @@ -1638,6 +1643,16 @@ int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what, const void *reserved, int idx) _GPGME_DEPRECATED; + +/* 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. */ +gpgme_error_t gpgme_op_getauditlog_start (gpgme_ctx_t ctx, gpgme_data_t output, + unsigned int flags); +gpgme_error_t gpgme_op_getauditlog (gpgme_ctx_t ctx, gpgme_data_t output, + unsigned int flags); + + /* Various functions. */ diff --git a/gpgme/libgpgme.vers b/gpgme/libgpgme.vers index da90a77..9f18daf 100644 --- a/gpgme/libgpgme.vers +++ b/gpgme/libgpgme.vers @@ -36,6 +36,9 @@ GPGME_1.1 { gpgme_sig_notation_get; gpgme_free; + + gpgme_op_getauditlog_start; + gpgme_op_getauditlog; }; diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index 8e1b73a..c54da3a 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -2120,6 +2120,7 @@ struct engine_ops _gpgme_engine_ops_gpg = gpg_sign, gpg_trustlist, gpg_verify, + NULL, gpg_set_io_cbs, gpg_io_event, gpg_cancel diff --git a/tests/gpgsm/t-verify.c b/tests/gpgsm/t-verify.c index 369bb6b..88d5f37 100644 --- a/tests/gpgsm/t-verify.c +++ b/tests/gpgsm/t-verify.c @@ -108,6 +108,21 @@ check_result (gpgme_verify_result_t result, int summary, char *fpr, } +static void +show_auditlog (gpgme_ctx_t ctx) +{ + gpgme_error_t err; + gpgme_data_t data; + + err = gpgme_data_new (&data); + fail_if_err (err); + err = gpgme_op_getauditlog (ctx, data, 0); + fail_if_err (err); + gpgme_data_release (data); +} + + + int main (int argc, char **argv) { @@ -135,6 +150,8 @@ main (int argc, char **argv) "3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E", GPG_ERR_NO_ERROR, GPGME_VALIDITY_FULL); + show_auditlog (ctx); + /* Checking a manipulated message. */ gpgme_data_release (text); err = gpgme_data_new_from_mem (&text, test_text1f, strlen (test_text1f), 0); -- 2.26.2