aboutsummaryrefslogtreecommitdiffstats
path: root/src/engine-gpg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine-gpg.c')
-rw-r--r--src/engine-gpg.c203
1 files changed, 189 insertions, 14 deletions
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 3b9a6ff5..173e940c 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -43,6 +43,7 @@
#include "sema.h"
#include "debug.h"
#include "data.h"
+#include "mbox-util.h"
#include "engine-backend.h"
@@ -145,6 +146,11 @@ struct engine_gpg
gpgme_pinentry_mode_t pinentry_mode;
char request_origin[10];
+ struct {
+ unsigned int no_symkey_cache : 1;
+ unsigned int offline : 1;
+ } flags;
+
/* NULL or the data object fed to --override_session_key-fd. */
gpgme_data_t override_session_key;
};
@@ -644,6 +650,12 @@ gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
}
else
*gpg->request_origin = 0;
+
+ 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"));
+
}
@@ -875,7 +887,8 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argc++;
if (!gpg->cmd.used)
argc++; /* --batch */
- argc += 2; /* --no-sk-comments, --request-origin */
+ argc += 4; /* --no-sk-comments, --request-origin, --no-symkey-cache */
+ /* --disable-dirmngr */
argv = calloc (argc + 1, sizeof *argv);
if (!argv)
@@ -937,6 +950,32 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argc++;
}
+ if (gpg->flags.no_symkey_cache)
+ {
+ argv[argc] = strdup ("--no-symkey-cache");
+ 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");
+ if (!argv[argc])
+ {
+ int saved_err = gpg_error_from_syserror ();
+ free (fd_data_map);
+ free_argv (argv);
+ return saved_err;
+ }
+ argc++;
+ }
+
if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0"))
{
const char *s = NULL;
@@ -1871,8 +1910,70 @@ gpg_edit (void *engine, int type, gpgme_key_t key, gpgme_data_t out,
}
+/* Add a single argument from a key to an -r option. */
+static gpg_error_t
+add_arg_recipient (engine_gpg_t gpg, gpgme_encrypt_flags_t flags,
+ gpgme_key_t key)
+{
+ gpg_error_t err;
+
+ if ((flags & GPGME_ENCRYPT_WANT_ADDRESS))
+ {
+ /* We have no way to figure out which mail address was
+ * requested. FIXME: It would be possible to figure this out by
+ * consulting the SENDER property of the context. */
+ err = gpg_error (GPG_ERR_INV_USER_ID);
+ }
+ else
+ err = add_arg (gpg, key->subkeys->fpr);
+
+ return err;
+}
+
+
+/* Add a single argument from a USERID string to an -r option. */
+static gpg_error_t
+add_arg_recipient_string (engine_gpg_t gpg, gpgme_encrypt_flags_t flags,
+ const char *userid, int useridlen)
+{
+ gpg_error_t err;
+
+ if ((flags & GPGME_ENCRYPT_WANT_ADDRESS))
+ {
+ char *tmpstr, *mbox;
+
+ tmpstr = malloc (useridlen + 1);
+ if (!tmpstr)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ memcpy (tmpstr, userid, useridlen);
+ tmpstr[useridlen] = 0;
+
+ mbox = _gpgme_mailbox_from_userid (tmpstr);
+ if (!mbox)
+ {
+ err = gpg_error_from_syserror ();
+ if (gpg_err_code (err) == GPG_ERR_EINVAL)
+ err = gpg_error (GPG_ERR_INV_USER_ID);
+ }
+ else
+ err = add_arg (gpg, mbox);
+
+ free (mbox);
+ free (tmpstr);
+ }
+ }
+ else
+ err = add_arg_len (gpg, NULL, userid, useridlen);
+
+ return err;
+}
+
+
static gpgme_error_t
-append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
+append_args_from_recipients (engine_gpg_t gpg, gpgme_encrypt_flags_t flags,
+ gpgme_key_t recp[])
{
gpgme_error_t err = 0;
int i = 0;
@@ -1884,7 +1985,7 @@ append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
if (!err)
err = add_arg (gpg, "-r");
if (!err)
- err = add_arg (gpg, recp[i]->subkeys->fpr);
+ err = add_arg_recipient (gpg, flags, recp[i]);
if (err)
break;
i++;
@@ -1893,17 +1994,86 @@ append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
}
+/* Take recipients from the LF delimited STRING and add -r args. */
+static gpg_error_t
+append_args_from_recipients_string (engine_gpg_t gpg,
+ gpgme_encrypt_flags_t flags,
+ const char *string)
+{
+ gpg_error_t err = 0;
+ gpgme_encrypt_flags_t orig_flags = flags;
+ int any = 0;
+ int ignore = 0;
+ int hidden = 0;
+ int file = 0;
+ const char *s;
+ int n;
+
+ do
+ {
+ /* Skip leading white space */
+ while (*string == ' ' || *string == '\t')
+ string++;
+ if (!*string)
+ break;
+
+ /* Look for the LF. */
+ s = strchr (string, '\n');
+ if (s)
+ n = s - string;
+ else
+ n = strlen (string);
+ while (n && (string[n-1] == ' ' || string[n-1] == '\t'))
+ n--;
+
+ if (!ignore && n == 2 && !memcmp (string, "--", 2))
+ ignore = 1;
+ else if (!ignore && n == 8 && !memcmp (string, "--hidden", 8))
+ hidden = 1;
+ else if (!ignore && n == 11 && !memcmp (string, "--no-hidden", 11))
+ hidden = 0;
+ else if (!ignore && n == 6 && !memcmp (string, "--file", 6))
+ {
+ file = 1;
+ /* Because the key is used as is we need to ignore this flag: */
+ flags &= ~GPGME_ENCRYPT_WANT_ADDRESS;
+ }
+ else if (!ignore && n == 9 && !memcmp (string, "--no-file", 9))
+ {
+ file = 0;
+ flags = orig_flags;
+ }
+ else if (n) /* Not empty - use it. */
+ {
+ err = add_arg (gpg, file? (hidden? "-F":"-f") : (hidden? "-R":"-r"));
+ if (!err)
+ err = add_arg_recipient_string (gpg, flags, string, n);
+ if (!err)
+ any = 1;
+ }
+
+ string += n + !!s;
+ }
+ while (!err);
+
+ if (!err && !any)
+ err = gpg_error (GPG_ERR_MISSING_KEY);
+ return err;
+}
+
+
static gpgme_error_t
-gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
+gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
+ gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
{
engine_gpg_t gpg = engine;
gpgme_error_t err = 0;
- if (recp)
+ if (recp || recpstring)
err = add_arg (gpg, "--encrypt");
- if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
+ if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || (!recp && !recpstring)))
err = add_arg (gpg, "--symmetric");
if (!err && use_armor)
@@ -1930,7 +2100,7 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
&& have_gpg_version (gpg, "2.1.14"))
err = add_arg (gpg, "--mimemode");
- if (recp)
+ if (recp || recpstring)
{
/* If we know that all recipients are valid (full or ultimate trust)
we can suppress further checks. */
@@ -1940,8 +2110,10 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
err = add_arg (gpg, "--no-encrypt-to");
- if (!err)
- err = append_args_from_recipients (gpg, recp);
+ if (!err && !recp && recpstring)
+ err = append_args_from_recipients_string (gpg, flags, recpstring);
+ else if (!err)
+ err = append_args_from_recipients (gpg, flags, recp);
}
/* Tell the gpg object about the data. */
@@ -1974,6 +2146,7 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
static gpgme_error_t
gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
+ const char *recpstring,
gpgme_encrypt_flags_t flags, gpgme_data_t plain,
gpgme_data_t ciph, int use_armor,
gpgme_ctx_t ctx /* FIXME */)
@@ -1981,10 +2154,10 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
engine_gpg_t gpg = engine;
gpgme_error_t err = 0;
- if (recp)
+ if (recp || recpstring)
err = add_arg (gpg, "--encrypt");
- if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
+ if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || (!recp && !recpstring)))
err = add_arg (gpg, "--symmetric");
if (!err)
@@ -2002,7 +2175,7 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
&& have_gpg_version (gpg, "2.1.14"))
err = add_arg (gpg, "--mimemode");
- if (recp)
+ if (recp || recpstring)
{
/* If we know that all recipients are valid (full or ultimate trust)
we can suppress further checks. */
@@ -2012,8 +2185,10 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
err = add_arg (gpg, "--no-encrypt-to");
- if (!err)
- err = append_args_from_recipients (gpg, recp);
+ if (!err && !recp && recpstring)
+ err = append_args_from_recipients_string (gpg, flags, recpstring);
+ else if (!err)
+ err = append_args_from_recipients (gpg, flags, recp);
}
if (!err)