summaryrefslogtreecommitdiff
path: root/src/engine-gpg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine-gpg.c')
-rw-r--r--src/engine-gpg.c180
1 files changed, 118 insertions, 62 deletions
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 173e940..2833374 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -26,7 +26,6 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
-#include <errno.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
@@ -136,23 +135,24 @@ struct engine_gpg
char *keyword; /* what has been requested (malloced) */
engine_command_handler_t fnc;
void *fnc_value;
- /* The kludges never end. This is used to couple command handlers
- with output data in edit key mode. */
- gpgme_data_t linked_data;
- int linked_idx;
} cmd;
struct gpgme_io_cbs io_cbs;
gpgme_pinentry_mode_t pinentry_mode;
char request_origin[10];
+ char *auto_key_locate;
struct {
unsigned int no_symkey_cache : 1;
unsigned int offline : 1;
+ unsigned int ignore_mdc_error : 1;
} flags;
/* 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;
@@ -454,8 +454,10 @@ gpg_release (void *engine)
free_argv (gpg->argv);
if (gpg->cmd.keyword)
free (gpg->cmd.keyword);
+ free (gpg->auto_key_locate);
gpgme_data_release (gpg->override_session_key);
+ gpgme_data_release (gpg->diagnostics);
free (gpg);
}
@@ -503,8 +505,6 @@ gpg_new (void **engine, const char *file_name, const char *home_dir,
gpg->colon.fd[1] = -1;
gpg->cmd.fd = -1;
gpg->cmd.idx = -1;
- gpg->cmd.linked_data = NULL;
- gpg->cmd.linked_idx = -1;
/* Allocate the read buffer for the status pipe. */
gpg->status.bufsize = 1024;
@@ -626,6 +626,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);
@@ -651,11 +661,20 @@ gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
else
*gpg->request_origin = 0;
+ if (ctx->auto_key_locate && have_gpg_version (gpg, "2.1.18"))
+ {
+ if (gpg->auto_key_locate)
+ free (gpg->auto_key_locate);
+ gpg->auto_key_locate = _gpgme_strconcat ("--auto-key-locate=",
+ ctx->auto_key_locate, NULL);
+ }
+
gpg->flags.no_symkey_cache = (ctx->no_symkey_cache
&& have_gpg_version (gpg, "2.2.7"));
-
gpg->flags.offline = (ctx->offline && have_gpg_version (gpg, "2.1.23"));
+ gpg->flags.ignore_mdc_error = !!ctx->ignore_mdc_error;
+
}
@@ -793,14 +812,14 @@ command_handler (void *opaque, int fd)
-/* The Fnc will be called to get a value for one of the commands with
- a key KEY. If the Code passed to FNC is 0, the function may release
- resources associated with the returned value from another call. To
- match such a second call to a first call, the returned value from
- the first call is passed as keyword. */
+/* The FNC will be called to get a value for one of the commands with
+ * a key KEY. If the code passed to FNC is 0, the function may
+ * release resources associated with the returned value from another
+ * call. To match such a second call to a first call, the returned
+ * value from the first call is passed as keyword. */
static gpgme_error_t
gpg_set_command_handler (void *engine, engine_command_handler_t fnc,
- void *fnc_value, gpgme_data_t linked_data)
+ void *fnc_value)
{
engine_gpg_t gpg = engine;
gpgme_error_t rc;
@@ -819,7 +838,6 @@ gpg_set_command_handler (void *engine, engine_command_handler_t fnc,
gpg->cmd.fnc = fnc;
gpg->cmd.cb_data = (void *) &gpg->cmd;
gpg->cmd.fnc_value = fnc_value;
- gpg->cmd.linked_data = linked_data;
gpg->cmd.used = 1;
return 0;
}
@@ -950,6 +968,19 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argc++;
}
+ if (gpg->auto_key_locate)
+ {
+ argv[argc] = strdup (gpg->auto_key_locate);
+ if (!argv[argc])
+ {
+ int saved_err = gpg_error_from_syserror ();
+ free (fd_data_map);
+ free_argv (argv);
+ return saved_err;
+ }
+ argc++;
+ }
+
if (gpg->flags.no_symkey_cache)
{
argv[argc] = strdup ("--no-symkey-cache");
@@ -963,6 +994,19 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argc++;
}
+ if (gpg->flags.ignore_mdc_error)
+ {
+ argv[argc] = strdup ("--ignore-mdc-error");
+ if (!argv[argc])
+ {
+ int saved_err = gpg_error_from_syserror ();
+ free (fd_data_map);
+ free_argv (argv);
+ return saved_err;
+ }
+ argc++;
+ }
+
if (gpg->flags.offline)
{
argv[argc] = strdup ("--disable-dirmngr");
@@ -1039,10 +1083,10 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound ? 1 : 0)
== -1)
{
- int saved_errno = errno;
+ int saved_err = gpg_error_from_syserror ();
free (fd_data_map);
free_argv (argv);
- return gpg_error (saved_errno);
+ return saved_err;
}
if (_gpgme_io_set_close_notify (fds[0],
close_notify_handler, gpg)
@@ -1077,11 +1121,6 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
assert (gpg->cmd.idx == -1);
gpg->cmd.idx = datac;
}
- else if (gpg->cmd.linked_data == a->data)
- {
- assert (gpg->cmd.linked_idx == -1);
- gpg->cmd.linked_idx = datac;
- }
}
fd_data_map[datac].data = a->data;
@@ -1268,44 +1307,6 @@ read_status (engine_gpg_t gpg)
if (err)
return err;
}
-
- if (r == GPGME_STATUS_END_STREAM)
- {
- if (gpg->cmd.used)
- {
- /* Before we can actually add the
- command fd, we might have to flush
- the linked output data pipe. */
- if (gpg->cmd.linked_idx != -1
- && gpg->fd_data_map[gpg->cmd.linked_idx].fd
- != -1)
- {
- struct io_select_fd_s fds;
- fds.fd =
- gpg->fd_data_map[gpg->cmd.linked_idx].fd;
- fds.for_read = 1;
- fds.for_write = 0;
- fds.opaque = NULL;
- do
- {
- fds.signaled = 0;
- _gpgme_io_select (&fds, 1, 1);
- if (fds.signaled)
- _gpgme_data_inbound_handler
- (gpg->cmd.linked_data, fds.fd);
- }
- while (fds.signaled);
- }
-
- /* XXX We must check if there are any
- more fds active after removing this
- one. */
- (*gpg->io_cbs.remove)
- (gpg->fd_data_map[gpg->cmd.idx].tag);
- gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
- gpg->fd_data_map[gpg->cmd.idx].fd = -1;
- }
- }
}
}
/* To reuse the buffer for the next line we have to
@@ -2240,13 +2241,22 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
return gpg_error (GPG_ERR_NOT_SUPPORTED);
if ((mode & GPGME_EXPORT_MODE_MINIMAL))
- err = add_arg (gpg, "--export-options=export-minimal");
+ {
+ if ((mode & GPGME_EXPORT_MODE_NOUID))
+ err = add_arg (gpg, "--export-options=export-minimal,export-drop-uids");
+ else
+ err = add_arg (gpg, "--export-options=export-minimal");
+ }
+ else if ((mode & GPGME_EXPORT_MODE_NOUID))
+ err = add_arg (gpg, "--export-options=export-drop-uids");
if (err)
;
else if ((mode & GPGME_EXPORT_MODE_EXTERN))
{
err = add_arg (gpg, "--send-keys");
+ if (!err && (mode & GPGME_EXPORT_MODE_NOUID))
+ err = add_arg (gpg, "--keyserver-options=export-drop-uids");
}
else
{
@@ -3279,6 +3289,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 =
{
@@ -3316,7 +3372,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 */