Discussion:
[PATCH 0/5] Cleanups for the GPGME crypto backend
Werner Koch
2018-12-03 07:41:51 UTC
Permalink
Hi,

here is my first set of patches to cleanup some bit rot in the gpgme
interface of Mutt. The actual visible thing is a fix to the listing of
imported keys. That listing of imported keys to the console must have
stopped working on 2014-12-31 due to a fix for bug #3698, which was
needed due to a not fully working stub code introduced in 2008.

The patches now require GPGME 1.4.0 which was released more than 5 years
ago. I don't thing that this should be any problem, in fact for
security reason it would even be better to require a very decent
version. But that can be done later.

Some brief remarks:

Nuke trailing white space from the crypt-* files.

Well, this is kind of optional but I don't really like changes in white
spaces and in particular trailing white spaces. They clutter up all
diff output.

Require GPGME version 1.2.0 and drop useless HAVE macros.

This removes HAVE_foo macros related to GPGME which are not actually
used. 1.2.0 was released 9 years ago.

Always use the gpgme_new wrapper in crypt-gpgme.

This makes the code more readable.

Try to avoid creation of temp. directory for key import.

Since gpgme 1.9 it is possible to list keys directly without importing
them to a the keyring. If Mutt is build with at least gpgme 1.9.0 this
new feature is used.

Improve the console output for extract-keys and speed up import.

The actual change. This also fixed a bug in the real import code which
listed _all_ keys in the keyring to a temporary file and copied that one
to stdout. The former commit avoided the output to stdout. So
importing keys will be much faster if you have a large keyring.


Salam-Shalom,

Werner


Werner Koch (5):
Nuke trailing white space from the crypt-* files.
Require GPGME version 1.2.0 and drop useless HAVE macros.
Always use the gpgme_new wrapper in crypt-gpgme.
Try to avoid creation of temp. directory for key import.
Improve the console output for extract-keys and speed up import.

configure.ac | 14 +-
crypt-gpgme.c | 776 ++++++++++++++++++++++++++++++----------------
crypt-gpgme.h | 6 +-
crypt-mod-pgp-classic.c | 10 +-
crypt-mod-pgp-gpgme.c | 14 +-
crypt-mod-smime-classic.c | 10 +-
crypt-mod-smime-gpgme.c | 10 +-
crypt-mod.c | 4 +-
crypt-mod.h | 14 +-
crypt.c | 96 +++---
cryptglue.c | 18 +-
11 files changed, 605 insertions(+), 367 deletions(-)

--
2.11.0
Werner Koch
2018-12-03 07:41:56 UTC
Permalink
The listing of imported keys to the console must have stopped working
on 2014-12-31 due to a fix for bug #3698, commit
bbc5acb6de0ca56d7e8366402d68a1a919ca9b23 which was needed due to a
not fully working stub code introduced in 2008 with commit
a4b3a60dd63bc7af7927025b2d1344530ca89aa9.

The latter commit also introduced a bug in the import code which
listed all keys in the keyring to a temporary file and copied that one
to stdout. The former commit avoided the output to stdout.

The fix here is to use pgp_gpgme_extract_keys only for extracting
information about the key and don't re-use the same code for importing
keys. We now import the keys directly in pgp_gpgme_invoke_import and
we print the fingerprint and status flags for all imported keys. That
information available from GPGME for ages (0.3.1 from 2003).
The user id is unfortunately not printed; that would require a lookup
of the newly imported key. Can be done with another patch.
---
crypt-gpgme.c | 113 +++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 85 insertions(+), 28 deletions(-)

diff --git a/crypt-gpgme.c b/crypt-gpgme.c
index 515d81b3..f727292b 100644
--- a/crypt-gpgme.c
+++ b/crypt-gpgme.c
@@ -2228,7 +2228,7 @@ int smime_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur)
return *cur? 0:-1;
}

-static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
+static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp)
{
/* Before gpgme 1.9.0 and gpg 2.1.14 there was no side-effect free
* way to view key data in GPGME, so we import the key into a
@@ -2257,7 +2257,7 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)

tmpctx = create_gpgme_context (0);

- if (dryrun && legacy_api)
+ if (legacy_api)
{
snprintf (tmpdir, sizeof(tmpdir), "%s/mutt-gpgme-XXXXXX", Tempdir);
if (!mkdtemp (tmpdir))
@@ -2284,15 +2284,6 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
}
}

- if (!dryrun || legacy_api)
- {
- if ((err = gpgme_op_import (tmpctx, keydata)) != GPG_ERR_NO_ERROR)
- {
- dprint (1, (debugfile, "Error importing key\n"));
- goto err_tmpdir;
- }
- }
-
mutt_mktemp (tmpfile, sizeof (tmpfile));
*fp = safe_fopen (tmpfile, "w+");
if (!*fp)
@@ -2303,7 +2294,7 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
unlink (tmpfile);

#if GPGME_VERSION_NUMBER >= 0x010900 /* 1.9.0 */
- if (dryrun && !legacy_api)
+ if (!legacy_api)
err = gpgme_op_keylist_from_data_start (tmpctx, keydata, 0);
else
#endif /* gpgme >= 1.9.0 */
@@ -2351,7 +2342,7 @@ err_fp:
if (rc)
safe_fclose (fp);
err_tmpdir:
- if (dryrun && legacy_api)
+ if (legacy_api)
mutt_rmtree (tmpdir);
err_ctx:
gpgme_release (tmpctx);
@@ -2359,6 +2350,7 @@ err_ctx:
return rc;
}

+
/* Check that 'b' is a complete line containing 'a' followed by either LF or CRLF.
*
* returns:
@@ -2466,37 +2458,102 @@ int pgp_gpgme_check_traditional (FILE *fp, BODY *b, int just_one)

void pgp_gpgme_invoke_import (const char *fname)
{
- gpgme_data_t keydata;
+ gpgme_ctx_t ctx;
+ gpgme_data_t keydata = NULL;
gpgme_error_t err;
- FILE* in;
- FILE* out;
+ FILE *in = NULL;
+ gpgme_import_result_t impres;
+ gpgme_import_status_t st;
+ int any;
+
+ ctx = create_gpgme_context (0);

if (!(in = safe_fopen (fname, "r")))
- return;
+ {
+ mutt_perror (fname);
+ goto leave;
+ }
+
/* Note that the stream, "in", needs to be kept open while the keydata
- * is used.
- */
+ * is used. */
if ((err = gpgme_data_new_from_stream (&keydata, in)) != GPG_ERR_NO_ERROR)
{
- safe_fclose (&in);
mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err));
mutt_sleep (1);
- return;
+ goto leave;
}

- if (pgp_gpgme_extract_keys (keydata, &out, 0))
+ err = gpgme_op_import (ctx, keydata);
+ if (err)
{
- mutt_error (_("Error extracting key data!\n"));
+ mutt_error (_("error importing key: %s\n"), gpgme_strerror (err));
mutt_sleep (1);
+ goto leave;
}
- else
+
+ /* Print infos about the imported keys to stdout. */
+ impres = gpgme_op_import_result (ctx);
+ if (!impres)
{
- fseek (out, 0, SEEK_SET);
- mutt_copy_stream (out, stdout);
+ fputs ("oops: no import result returned\n", stdout);
+ goto leave;
}
+
+ for (st = impres->imports; st; st = st->next)
+ {
+ if (st->result)
+ continue;
+ printf ("key %s imported (", NONULL (st->fpr));
+ /* Note that we use the singular even if it is possible that
+ * several uids etc are new. This simply looks better. */
+ any = 0;
+ if (st->status & GPGME_IMPORT_SECRET)
+ {
+ printf ("secret parts");
+ any = 1;
+ }
+ if ((st->status & GPGME_IMPORT_NEW))
+ {
+ printf ("%snew key", any? ", ":"");
+ any = 1;
+ }
+ if ((st->status & GPGME_IMPORT_UID))
+ {
+ printf ("%snew uid", any? ", ":"");
+ any = 1;
+ }
+ if ((st->status & GPGME_IMPORT_SIG))
+ {
+ printf ("%snew sig", any? ", ":"");
+ any = 1;
+ }
+ if ((st->status & GPGME_IMPORT_SUBKEY))
+ {
+ printf ("%snew subkey", any? ", ":"");
+ any = 1;
+ }
+ printf ("%s)\n", any? "":"not changed");
+ /* Fixme: Should we lookup each imported key and print more infos? */
+ }
+ /* Now print keys which failed the import. Unfortunately in most
+ * cases gpg will bail out early and not tell gpgme about. */
+ /* FIXME: We could instead use the new GPGME_AUDITLOG_DIAG to show
+ * the actual gpg diagnostics. But I fear that would clutter the
+ * output too much. Maybe a dedicated prompt or option to do this
+ * would be helpful. */
+ for (st = impres->imports; st; st = st->next)
+ {
+ if (!st->result)
+ continue;
+ printf ("key %s import failed: %s\n", NONULL (st->fpr),
+ gpgme_strerror (st->result));
+ }
+ fflush (stdout);
+
+ leave:
+ gpgme_release (ctx);
gpgme_data_release (keydata);
safe_fclose (&in);
- safe_fclose (&out);
}


@@ -2641,7 +2698,7 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
/* Invoke PGP if needed */
if (pgp_keyblock)
{
- pgp_gpgme_extract_keys (armored_data, &pgpout, 1);
+ pgp_gpgme_extract_keys (armored_data, &pgpout);
}
else if (!clearsign || (s->flags & MUTT_VERIFY))
{
--
2.11.0
Werner Koch
2018-12-03 07:41:54 UTC
Permalink
The wrapper is much more convenient and there is no need to sometimes
use gpgme_new directly. The perceived advantage on not bailing out in
an out-of-core condition is not realistic because other small amounts
of memory are allocated all over mutt anyway and thus function will
terminate the process as well.

This patch also changes the minimum version of gpgme to 1.4.0. This
is so that we can always pass NULL to functions like gpgme_release.
Further 1.4.0 has new functions which we may soon like to use.
---
configure.ac | 4 +--
crypt-gpgme.c | 111 ++++++++++++++++++++++++----------------------------------
2 files changed, 47 insertions(+), 68 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8ab8b0c3..892de59f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -129,11 +129,11 @@ AC_ARG_ENABLE(gpgme, AS_HELP_STRING([--enable-gpgme],[Enable GPGME support]),

if test x"$enable_gpgme" = xyes; then
AC_MSG_RESULT(yes)
- AM_PATH_GPGME(1.2.0, AC_DEFINE(CRYPT_BACKEND_GPGME, 1,
+ AM_PATH_GPGME(1.4.0, AC_DEFINE(CRYPT_BACKEND_GPGME, 1,
[Defined, if GPGME support is enabled]),
[gpgme_found=no])
if test x"$gpgme_found" = xno; then
- AC_MSG_ERROR([*** GPGME not found or version is older than 1.2 ***])
+ AC_MSG_ERROR([*** GPGME not found or version is older than 1.4 ***])
else
MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS crypt-gpgme.o crypt-mod-pgp-gpgme.o crypt-mod-smime-gpgme.o"
fi
diff --git a/crypt-gpgme.c b/crypt-gpgme.c
index 55488357..ab0e2eec 100644
--- a/crypt-gpgme.c
+++ b/crypt-gpgme.c
@@ -61,6 +61,7 @@
# include <sys/resource.h>
#endif

+
/*
* Helper macros.
*/
@@ -644,57 +645,50 @@ static gpgme_key_t *create_recipient_set (const char *keylist,
gpgme_key_t key = NULL;
gpgme_ctx_t context = NULL;

- err = gpgme_new (&context);
- if (! err)
- err = gpgme_set_protocol (context, protocol);
-
- if (! err)
- {
- s = keylist;
- do {
- while (*s == ' ')
- s++;
- for (i=0; *s && *s != ' ' && i < sizeof(buf)-1;)
- buf[i++] = *s++;
- buf[i] = 0;
- if (*buf)
- {
- if (i>1 && buf[i-1] == '!')
- {
- /* The user selected to override the validity of that
- key. */
- buf[i-1] = 0;
-
- err = gpgme_get_key (context, buf, &key, 0);
- if (! err)
- key->uids->validity = GPGME_VALIDITY_FULL;
- buf[i-1] = '!';
- }
- else
- err = gpgme_get_key (context, buf, &key, 0);
+ context = create_gpgme_context ((protocol == GPGME_PROTOCOL_CMS));
+ s = keylist;
+ do {
+ while (*s == ' ')
+ s++;
+ for (i=0; *s && *s != ' ' && i < sizeof(buf)-1;)
+ buf[i++] = *s++;
+ buf[i] = 0;
+ if (*buf)
+ {
+ if (i>1 && buf[i-1] == '!')
+ {
+ /* The user selected to override the validity of that
+ key. */
+ buf[i-1] = 0;
+
+ err = gpgme_get_key (context, buf, &key, 0);
+ if (! err)
+ key->uids->validity = GPGME_VALIDITY_FULL;
+ buf[i-1] = '!';
+ }
+ else
+ err = gpgme_get_key (context, buf, &key, 0);

- safe_realloc (&rset, sizeof (*rset) * (rset_n + 1));
- if (! err)
- rset[rset_n++] = key;
- else
- {
- mutt_error (_("error adding recipient `%s': %s\n"),
- buf, gpgme_strerror (err));
- rset[rset_n] = NULL;
- free_recipient_set (&rset);
- gpgme_release (context);
- return NULL;
+ safe_realloc (&rset, sizeof (*rset) * (rset_n + 1));
+ if (! err)
+ rset[rset_n++] = key;
+ else
+ {
+ mutt_error (_("error adding recipient `%s': %s\n"),
+ buf, gpgme_strerror (err));
+ rset[rset_n] = NULL;
+ free_recipient_set (&rset);
+ gpgme_release (context);
+ return NULL;
}
- }
- } while (*s);
- }
+ }
+ } while (*s);

/* NULL terminate. */
safe_realloc (&rset, sizeof (*rset) * (rset_n + 1));
rset[rset_n++] = NULL;

- if (context)
- gpgme_release (context);
+ gpgme_release (context);

return rset;
}
@@ -2048,11 +2042,11 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
int rc = -1;
time_t tt;

- if ((err = gpgme_new (&tmpctx)) != GPG_ERR_NO_ERROR)
- {
- dprint (1, (debugfile, "Error creating GPGME context\n"));
- return rc;
- }
+#if GPGME_VERSION_NUMBER >= 0x010900 /* 1.9.0 */
+
+#endif
+
+ tmpctx = create_gpgme_context (0);

if (dryrun)
{
@@ -3717,15 +3711,7 @@ verify_key (crypt_key_t *key)

print_key_info (key->kobj, fp);

- err = gpgme_new (&listctx);
- if (err)
- {
- fprintf (fp, "Internal error: can't create gpgme context: %s\n",
- gpgme_strerror (err));
- goto leave;
- }
- if ((key->flags & KEYFLAG_ISX509))
- gpgme_set_protocol (listctx, GPGME_PROTOCOL_CMS);
+ listctx = create_gpgme_context ((key->flags & KEYFLAG_ISX509));

k = key->kobj;
gpgme_key_ref (k);
@@ -3840,14 +3826,7 @@ static crypt_key_t *get_candidates (LIST * hints, unsigned int app, int secret)
if (!pattern)
return NULL;

- err = gpgme_new (&ctx);
- if (err)
- {
- mutt_error (_("gpgme_new failed: %s"), gpgme_strerror (err));
- FREE (&pattern);
- return NULL;
- }
-
+ ctx = create_gpgme_context (0);
db = NULL;
kend = &db;
--
2.11.0
Werner Koch
2018-12-03 07:41:55 UTC
Permalink
Since gpgme 1.9.0 it is possible to list keys directly from a file
without importing it into gpg' own keyring. This patch implements
this in a backward compatible way.

Unfortunately we need to check for a suitable gpgme version at build
time and also for a suitable gpg version at runtime. This is
implemented by a version check which requires to call or include code
taken from libgpg-error (aka gpgrt). However this library is anyway a
dependency of gpgme and thus does not pose any extra burden.

The functions parse_version_number, parse_version_string, and
cmp_version_strings are taken from libgpg-error's repo at 2018-11-20.
Libgpg-error is distributed under the LGPL-2.1-or-later.
---
crypt-gpgme.c | 252 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 238 insertions(+), 14 deletions(-)

diff --git a/crypt-gpgme.c b/crypt-gpgme.c
index ab0e2eec..515d81b3 100644
--- a/crypt-gpgme.c
+++ b/crypt-gpgme.c
@@ -3,7 +3,7 @@
* Copyright (C) 1998-2000 Thomas Roessler <***@does-not-exist.org>
* Copyright (C) 2001 Thomas Roessler <***@does-not-exist.org>
* Oliver Ehli <***@acm.org>
- * Copyright (C) 2002-2004 g10 Code GmbH
+ * Copyright (C) 2002-2004, 2018 g10 Code GmbH
* Copyright (C) 2010,2012-2013 Michael R. Elkins <***@sigpipe.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -139,7 +139,6 @@ digit_or_letter (const unsigned char *s)
|| (*s >= 'a' && *s <= 'z'));
}

-
/* Print the utf-8 encoded string BUF of length LEN bytes to stream
FP. Convert the character set. */
static void
@@ -160,6 +159,182 @@ print_utf8 (FILE *fp, const char *buf, size_t len)
}


+/* Compare function for version strings. The return value is
+ * like strcmp(). LEVEL may be
+ * 0 - reserved
+ * 1 - format is "<major><patchlevel>".
+ * 2 - format is "<major>.<minor><patchlevel>".
+ * 3 - format is "<major>.<minor>.<micro><patchlevel>".
+ * To ignore the patchlevel in the comparison add 10 to LEVEL. To get
+ * a reverse sorting order use a negative number. */
+#if GPGRT_VERSION_NUMBER >= 0x012100 /* gpgme >= 1.33 */
+static int
+cmp_version_strings (const char *a, const char *b, int level)
+{
+ return gpgrt_cmp_version (a, b, level);
+}
+#else /* gpgme < 1.33 */
+/* This function parses the first portion of the version number S and
+ * stores it at NUMBER. On success, this function returns a pointer
+ * into S starting with the first character, which is not part of the
+ * initial number portion; on failure, NULL is returned. */
+static const char *parse_version_number (const char *s, int *number)
+{
+ int val = 0;
+
+ if (*s == '0' && digitp (s+1))
+ return NULL; /* Leading zeros are not allowed. */
+ for (; digitp (s); s++)
+ {
+ val *= 10;
+ val += *s - '0';
+ }
+ *number = val;
+ return val < 0 ? NULL : s;
+}
+/* This function breaks up the complete string-representation of the
+ * version number S, which is of the following struture: <major
+ * number>.<minor number>.<micro number><patch level>. The major,
+ * minor and micro number components will be stored in *MAJOR, *MINOR
+ * and *MICRO. If MINOR or MICRO is NULL the version number is
+ * assumed to have just 1 respective 2 parts.
+ *
+ * On success, the last component, the patch level, will be returned;
+ * in failure, NULL will be returned. */
+static const char *parse_version_string (const char *s, int *major,
+ int *minor, int *micro)
+{
+ s = parse_version_number (s, major);
+ if (!s)
+ return NULL;
+ if (!minor)
+ {
+ if (*s == '.')
+ s++;
+ }
+ else
+ {
+ if (*s != '.')
+ return NULL;
+ s++;
+ s = parse_version_number (s, minor);
+ if (!s)
+ return NULL;
+ if (!micro)
+ {
+ if (*s == '.')
+ s++;
+ }
+ else
+ {
+ if (*s != '.')
+ return NULL;
+ s++;
+ s = parse_version_number (s, micro);
+ if (!s)
+ return NULL;
+ }
+ }
+ return s; /* patchlevel */
+}
+/* Substitute for the gpgrt based implementation.
+ * See above for a description. */
+static int
+cmp_version_strings (const char *a, const char *b, int level)
+{
+ int a_major, a_minor, a_micro;
+ int b_major, b_minor, b_micro;
+ const char *a_plvl, *b_plvl;
+ int r;
+ int ignore_plvl;
+ int positive, negative;
+
+ if (level < 0)
+ {
+ positive = -1;
+ negative = 1;
+ level = 0 - level;
+ }
+ else
+ {
+ positive = 1;
+ negative = -1;
+ }
+ if ((ignore_plvl = (level > 9)))
+ level %= 10;
+
+ a_major = a_minor = a_micro = 0;
+ a_plvl = parse_version_string (a, &a_major,
+ level > 1? &a_minor : NULL,
+ level > 2? &a_micro : NULL);
+ if (!a_plvl)
+ a_major = a_minor = a_micro = 0; /* Error. */
+
+ b_major = b_minor = b_micro = 0;
+ b_plvl = parse_version_string (b, &b_major,
+ level > 1? &b_minor : NULL,
+ level > 2? &b_micro : NULL);
+ if (!b_plvl)
+ b_major = b_minor = b_micro = 0;
+
+ if (!ignore_plvl)
+ {
+ if (!a_plvl && !b_plvl)
+ return negative; /* Put invalid strings at the end. */
+ if (a_plvl && !b_plvl)
+ return positive;
+ if (!a_plvl && b_plvl)
+ return negative;
+ }
+
+ if (a_major > b_major)
+ return positive;
+ if (a_major < b_major)
+ return negative;
+
+ if (a_minor > b_minor)
+ return positive;
+ if (a_minor < b_minor)
+ return negative;
+
+ if (a_micro > b_micro)
+ return positive;
+ if (a_micro < b_micro)
+ return negative;
+
+ if (ignore_plvl)
+ return 0;
+
+ for (; *a_plvl && *b_plvl; a_plvl++, b_plvl++)
+ {
+ if (*a_plvl == '.' && *b_plvl == '.')
+ {
+ r = strcmp (a_plvl, b_plvl);
+ if (!r)
+ return 0;
+ else if ( r > 0 )
+ return positive;
+ else
+ return negative;
+ }
+ else if (*a_plvl == '.')
+ return negative; /* B is larger. */
+ else if (*b_plvl == '.')
+ return positive; /* A is larger. */
+ else if (*a_plvl != *b_plvl)
+ break;
+ }
+ if (*a_plvl == *b_plvl)
+ return 0;
+ else if ((*(signed char *)a_plvl - *(signed char *)b_plvl) > 0)
+ return positive;
+ else
+ return negative;
+}
+#endif /* gpgme < 1.33 */
+
+
+
/*
* Key management.
*/
@@ -411,6 +586,7 @@ static gpgme_ctx_t create_gpgme_context (int for_smime)
return ctx;
}

+
/* Create a new gpgme data object. This is a wrapper to die on
error. */
static gpgme_data_t create_gpgme_data (void)
@@ -429,6 +605,35 @@ static gpgme_data_t create_gpgme_data (void)
return data;
}

+
+/* Return true if the OpenPGP engine's version is at least VERSION. */
+static int have_gpg_version (const char *version)
+{
+ static char *engine_version;
+
+ if (!engine_version)
+ {
+ gpgme_ctx_t ctx;
+ gpgme_engine_info_t engineinfo;
+
+ ctx = create_gpgme_context (0);
+ engineinfo = gpgme_ctx_get_engine_info (ctx);
+ while (engineinfo && engineinfo->protocol != GPGME_PROTOCOL_OpenPGP)
+ engineinfo = engineinfo->next;
+ if (!engineinfo)
+ {
+ dprint (1, (debugfile, "Error finding GPGME PGP engine\n"));
+ engine_version = safe_strdup ("0.0.0");
+ }
+ else
+ engine_version = safe_strdup (engineinfo->version);
+ gpgme_release (ctx);
+ }
+
+ return cmp_version_strings (engine_version, version, 3) >= 0;
+}
+
+
/* Create a new GPGME Data object from the mail body A. With CONVERT
passed as true, the lines are converted to CR,LF if required.
Return NULL on error or the gpgme_data_t object on success. */
@@ -2025,8 +2230,10 @@ int smime_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur)

static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
{
- /* there's no side-effect free way to view key data in GPGME,
- * so we import the key into a temporary keyring */
+ /* Before gpgme 1.9.0 and gpg 2.1.14 there was no side-effect free
+ * way to view key data in GPGME, so we import the key into a
+ * temporary keyring if we detect an older system. */
+ int legacy_api;
char tmpdir[_POSIX_PATH_MAX];
char tmpfile[_POSIX_PATH_MAX];
gpgme_ctx_t tmpctx;
@@ -2042,13 +2249,15 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
int rc = -1;
time_t tt;

-#if GPGME_VERSION_NUMBER >= 0x010900 /* 1.9.0 */
-
+#if GPGME_VERSION_NUMBER >= 0x010900 /* gpgme >= 1.9.0 */
+ legacy_api = !have_gpg_version ("2.1.14");
+#else /* gpgme < 1.9.0 */
+ legacy_api = 1;
#endif

tmpctx = create_gpgme_context (0);

- if (dryrun)
+ if (dryrun && legacy_api)
{
snprintf (tmpdir, sizeof(tmpdir), "%s/mutt-gpgme-XXXXXX", Tempdir);
if (!mkdtemp (tmpdir))
@@ -2075,11 +2284,14 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
}
}

- if ((err = gpgme_op_import (tmpctx, keydata)) != GPG_ERR_NO_ERROR)
- {
- dprint (1, (debugfile, "Error importing key\n"));
- goto err_tmpdir;
- }
+ if (!dryrun || legacy_api)
+ {
+ if ((err = gpgme_op_import (tmpctx, keydata)) != GPG_ERR_NO_ERROR)
+ {
+ dprint (1, (debugfile, "Error importing key\n"));
+ goto err_tmpdir;
+ }
+ }

mutt_mktemp (tmpfile, sizeof (tmpfile));
*fp = safe_fopen (tmpfile, "w+");
@@ -2090,7 +2302,14 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
}
unlink (tmpfile);

- err = gpgme_op_keylist_start (tmpctx, NULL, 0);
+#if GPGME_VERSION_NUMBER >= 0x010900 /* 1.9.0 */
+ if (dryrun && !legacy_api)
+ err = gpgme_op_keylist_from_data_start (tmpctx, keydata, 0);
+ else
+#endif /* gpgme >= 1.9.0 */
+ {
+ err = gpgme_op_keylist_start (tmpctx, NULL, 0);
+ }
while (!err)
{
if ((err = gpgme_op_keylist_next (tmpctx, &key)))
@@ -2132,7 +2351,7 @@ err_fp:
if (rc)
safe_fclose (fp);
err_tmpdir:
- if (dryrun)
+ if (dryrun && legacy_api)
mutt_rmtree (tmpdir);
err_ctx:
gpgme_release (tmpctx);
@@ -2270,6 +2489,11 @@ void pgp_gpgme_invoke_import (const char *fname)
mutt_error (_("Error extracting key data!\n"));
mutt_sleep (1);
}
+ else
+ {
+ fseek (out, 0, SEEK_SET);
+ mutt_copy_stream (out, stdout);
+ }
gpgme_data_release (keydata);
safe_fclose (&in);
safe_fclose (&out);
--
2.11.0
Werner Koch
2018-12-03 07:41:53 UTC
Permalink
GPGME 1.2.0 was released nearly 10 years ago and thus we can really
demand this version. For various reasons it would be advisable to
require a decent version but that is a different thing and needs to be
done in a separate patch.

HAVE_GPGME_OP_EXPORT_KEYS and HAVE_GPGME_PKA_TRUST are not anymore
needed because they are supported by that GPGME version.

Signed-off-by: Werner Koch <***@gnupg.org>
---
configure.ac | 14 ++------------
crypt-gpgme.c | 6 ------
crypt-mod-pgp-classic.c | 2 +-
crypt-mod-pgp-gpgme.c | 6 ------
4 files changed, 3 insertions(+), 25 deletions(-)

diff --git a/configure.ac b/configure.ac
index d8aebe33..8ab8b0c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -129,22 +129,12 @@ AC_ARG_ENABLE(gpgme, AS_HELP_STRING([--enable-gpgme],[Enable GPGME support]),

if test x"$enable_gpgme" = xyes; then
AC_MSG_RESULT(yes)
- AM_PATH_GPGME(1.0.0, AC_DEFINE(CRYPT_BACKEND_GPGME, 1,
+ AM_PATH_GPGME(1.2.0, AC_DEFINE(CRYPT_BACKEND_GPGME, 1,
[Defined, if GPGME support is enabled]),
[gpgme_found=no])
if test x"$gpgme_found" = xno; then
- AC_MSG_ERROR([*** GPGME not found ***])
+ AC_MSG_ERROR([*** GPGME not found or version is older than 1.2 ***])
else
- AM_PATH_GPGME(1.1.1, AC_DEFINE(HAVE_GPGME_PKA_TRUST, 1,
- [Define if GPGME supports PKA]))
- #needed to get GPGME_LIBS and al correctly
- AM_PATH_GPGME(1.0.0, AC_DEFINE(CRYPT_BACKEND_GPGME, 1,
- [Define if you use GPGME to support OpenPGP]))
- dnl AC_CHECK_FUNCS([gpgme_op_export_keys])
- saved_LIBS="$LIBS"
- LIBS="$LIBS $GPGME_LIBS"
- AC_CHECK_FUNCS([gpgme_op_export_keys])
- LIBS="$saved_LIBS"
MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS crypt-gpgme.o crypt-mod-pgp-gpgme.o crypt-mod-smime-gpgme.o"
fi
else
diff --git a/crypt-gpgme.c b/crypt-gpgme.c
index 83293ec6..55488357 100644
--- a/crypt-gpgme.c
+++ b/crypt-gpgme.c
@@ -1236,8 +1236,6 @@ static int show_sig_summary (unsigned long sum,
state_puts ("\n", s);
}

-#ifdef HAVE_GPGME_PKA_TRUST
-
if (option (OPTCRYPTUSEPKA))
{
if (sig->pka_trust == 1 && sig->pka_address)
@@ -1255,8 +1253,6 @@ static int show_sig_summary (unsigned long sum,
}
}

-#endif
-
return severe;
}

@@ -4642,7 +4638,6 @@ char *smime_gpgme_findkeys (ADDRESS *adrlist, int oppenc_mode)
return find_keys (adrlist, APPLICATION_SMIME, oppenc_mode);
}

-#ifdef HAVE_GPGME_OP_EXPORT_KEYS
BODY *pgp_gpgme_make_key_attachment (char *tempf)
{
crypt_key_t *key = NULL;
@@ -4703,7 +4698,6 @@ bail:

return att;
}
-#endif

/*
* Implementation of `init'.
diff --git a/crypt-mod-pgp-classic.c b/crypt-mod-pgp-classic.c
index b0534afe..41c59d99 100644
--- a/crypt-mod-pgp-classic.c
+++ b/crypt-mod-pgp-classic.c
@@ -119,7 +119,7 @@ struct crypt_module_specs crypt_mod_pgp_classic =
crypt_mod_pgp_sign_message,
crypt_mod_pgp_verify_one,
crypt_mod_pgp_send_menu,
- NULL,
+ NULL, /* (set_sender) */

crypt_mod_pgp_encrypt_message,
crypt_mod_pgp_make_key_attachment,
diff --git a/crypt-mod-pgp-gpgme.c b/crypt-mod-pgp-gpgme.c
index 5521db97..a6b44d25 100644
--- a/crypt-mod-pgp-gpgme.c
+++ b/crypt-mod-pgp-gpgme.c
@@ -95,12 +95,10 @@ static BODY *crypt_mod_pgp_encrypt_message (BODY *a, char *keylist, int sign)
return pgp_gpgme_encrypt_message (a, keylist, sign);
}

-#ifdef HAVE_GPGME_OP_EXPORT_KEYS
static BODY *crypt_mod_pgp_make_key_attachment (char *tempf)
{
return pgp_gpgme_make_key_attachment (tempf);
}
-#endif

static void crypt_mod_pgp_set_sender (const char *sender)
{
@@ -125,11 +123,7 @@ struct crypt_module_specs crypt_mod_pgp_gpgme =

/* PGP specific. */
crypt_mod_pgp_encrypt_message,
-#ifdef HAVE_GPGME_OP_EXPORT_KEYS
crypt_mod_pgp_make_key_attachment,
-#else
- NULL,
-#endif
crypt_mod_pgp_check_traditional,
NULL, /* pgp_traditional_encryptsign */
NULL, /* pgp_invoke_getkeys */
--
2.11.0
Werner Koch
2018-12-03 07:41:52 UTC
Permalink
---
crypt-gpgme.c | 334 +++++++++++++++++++++++-----------------------
crypt-gpgme.h | 6 +-
crypt-mod-pgp-classic.c | 8 +-
crypt-mod-pgp-gpgme.c | 8 +-
crypt-mod-smime-classic.c | 10 +-
crypt-mod-smime-gpgme.c | 10 +-
crypt-mod.c | 4 +-
crypt-mod.h | 14 +-
crypt.c | 96 ++++++-------
cryptglue.c | 18 +--
10 files changed, 254 insertions(+), 254 deletions(-)

diff --git a/crypt-gpgme.c b/crypt-gpgme.c
index 47be23bb..83293ec6 100644
--- a/crypt-gpgme.c
+++ b/crypt-gpgme.c
@@ -10,12 +10,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program 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 General Public License for more details.
- *
+ *
* You should have received a copy of the GNU 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.
@@ -272,7 +272,7 @@ static char crypt_flags (int flags)
return 'd';
else if (flags & KEYFLAG_CRITICAL)
return 'c';
- else
+ else
return ' ';
}

@@ -357,21 +357,21 @@ static int crypt_id_matches_addr (ADDRESS *addr, ADDRESS *u_addr,
crypt_key_t *key)
{
int rv = 0;
-
+
if (crypt_id_is_valid (key))
rv |= CRYPT_KV_VALID;

if (crypt_id_is_strong (key))
rv |= CRYPT_KV_STRONGID;
-
+
if (addr->mailbox && u_addr->mailbox
&& mutt_strcasecmp (addr->mailbox, u_addr->mailbox) == 0)
rv |= CRYPT_KV_ADDR;
-
+
if (addr->personal && u_addr->personal
&& mutt_strcasecmp (addr->personal, u_addr->personal) == 0)
rv |= CRYPT_KV_STRING;
-
+
return rv;
}

@@ -418,7 +418,7 @@ static gpgme_data_t create_gpgme_data (void)
gpgme_data_t data;

err = gpgme_data_new (&data);
- if (err)
+ if (err)
{
mutt_error (_("error creating gpgme data object: %s\n"),
gpgme_strerror (err));
@@ -437,7 +437,7 @@ static gpgme_data_t body_to_data_object (BODY *a, int convert)
FILE *fptmp;
int err = 0;
gpgme_data_t data;
-
+
mutt_mktemp (tempfile, sizeof (tempfile));
fptmp = safe_fopen (tempfile, "w+");
if (!fptmp)
@@ -461,14 +461,14 @@ static gpgme_data_t body_to_data_object (BODY *a, int convert)
{
if (c == '\r')
hadcr = 1;
- else
+ else
{
if (c == '\n' && !hadcr)
{
buf[0] = '\r';
gpgme_data_write (data, buf, 1);
}
-
+
hadcr = 0;
}
/* FIXME: This is quite suboptimal */
@@ -484,7 +484,7 @@ static gpgme_data_t body_to_data_object (BODY *a, int convert)
err = gpgme_data_new_from_file (&data, tempfile, 1);
}
unlink (tempfile);
- if (err)
+ if (err)
{
mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err));
return NULL;
@@ -500,9 +500,9 @@ static gpgme_data_t file_to_data_object (FILE *fp, long offset, long length)
{
int err = 0;
gpgme_data_t data;
-
+
err = gpgme_data_new_from_filepart (&data, NULL, fp, offset, length);
- if (err)
+ if (err)
{
mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err));
return NULL;
@@ -659,12 +659,12 @@ static gpgme_key_t *create_recipient_set (const char *keylist,
buf[i] = 0;
if (*buf)
{
- if (i>1 && buf[i-1] == '!')
+ if (i>1 && buf[i-1] == '!')
{
/* The user selected to override the validity of that
key. */
buf[i-1] = 0;
-
+
err = gpgme_get_key (context, buf, &key, 0);
if (! err)
key->uids->validity = GPGME_VALIDITY_FULL;
@@ -692,7 +692,7 @@ static gpgme_key_t *create_recipient_set (const char *keylist,
/* NULL terminate. */
safe_realloc (&rset, sizeof (*rset) * (rset_n + 1));
rset[rset_n++] = NULL;
-
+
if (context)
gpgme_release (context);

@@ -784,7 +784,7 @@ static char *encrypt_gpgme_object (gpgme_data_t plaintext, gpgme_key_t *rset,
char *outfile;

ctx = create_gpgme_context (use_smime);
- if (!use_smime)
+ if (!use_smime)
gpgme_set_armor (ctx, 1);

ciphertext = create_gpgme_data ();
@@ -880,7 +880,7 @@ static void print_time(time_t t, STATE *s)
state_puts (p, s);
}

-/*
+/*
* Implementation of `sign_message'.
*/

@@ -988,7 +988,7 @@ static BODY *sign_message (BODY *a, int use_smime)
{
t->subtype = safe_strdup ("pkcs7-signature");
mutt_set_parameter ("name", "smime.p7s", &t->parameter);
- t->encoding = ENCBASE64;
+ t->encoding = ENCBASE64;
t->use_disp = 1;
t->disposition = DISPATTACH;
t->d_filename = safe_strdup ("smime.p7s");
@@ -1030,11 +1030,11 @@ BODY *pgp_gpgme_encrypt_message (BODY *a, char *keylist, int sign)
BODY *t;
gpgme_key_t *rset = NULL;
gpgme_data_t plaintext;
-
+
rset = create_recipient_set (keylist, GPGME_PROTOCOL_OpenPGP);
if (!rset)
return NULL;
-
+
if (sign)
convert_to_7bit (a);
plaintext = body_to_data_object (a, 0);
@@ -1043,7 +1043,7 @@ BODY *pgp_gpgme_encrypt_message (BODY *a, char *keylist, int sign)
free_recipient_set (&rset);
return NULL;
}
-
+
outfile = encrypt_gpgme_object (plaintext, rset, 0, sign);
gpgme_data_release (plaintext);
free_recipient_set (&rset);
@@ -1059,7 +1059,7 @@ BODY *pgp_gpgme_encrypt_message (BODY *a, char *keylist, int sign)

mutt_generate_boundary(&t->parameter);
mutt_set_parameter("protocol", "application/pgp-encrypted", &t->parameter);
-
+
t->parts = mutt_new_body ();
t->parts->type = TYPEAPPLICATION;
t->parts->subtype = safe_strdup ("pgp-encrypted");
@@ -1110,7 +1110,7 @@ BODY *smime_gpgme_build_smime_entity (BODY *a, char *keylist)
outfile = encrypt_gpgme_object (plaintext, rset, 1, 0);
gpgme_data_release (plaintext);
free_recipient_set (&rset);
- if (!outfile)
+ if (!outfile)
return NULL;

t = mutt_new_body ();
@@ -1126,12 +1126,12 @@ BODY *smime_gpgme_build_smime_entity (BODY *a, char *keylist)
t->unlink = 1; /*delete after sending the message */
t->parts=0;
t->next=0;
-
+
return t;
}


-/*
+/*
* Implementation of `verify_one'.
*/

@@ -1170,13 +1170,13 @@ static int show_sig_summary (unsigned long sum,
gpgme_verify_result_t result;
gpgme_signature_t sig;
unsigned int i;
-
+
result = gpgme_op_verify_result (ctx);

for (sig = result->signatures, i = 0; sig && (i < idx);
sig = sig->next, i++)
;
-
+
state_puts (_("Warning: The signature expired at: "), s);
print_time (sig ? sig->exp_timestamp : 0, s);
state_puts ("\n", s);
@@ -1412,7 +1412,7 @@ static void print_smime_keyinfo (const char* msg, gpgme_signature_t sig,
/* Show information about one signature. This function is called with
the context CTX of a successful verification operation and the
enumerator IDX which should start at 0 and increment for each
- call/signature.
+ call/signature.

Return values are: 0 for normal procession, 1 for a bad signature,
2 for a signature with a warning or -1 for no more signature. */
@@ -1445,7 +1445,7 @@ static int show_one_sig_status (gpgme_ctx_t ctx, int idx, STATE *s)
gpgme_key_unref (signature_key);
signature_key = NULL;
}
-
+
fpr = sig->fpr;
sum = sig->summary;

@@ -1549,7 +1549,7 @@ static int verify_one (BODY *sigbdy, STATE *s,
gpgme_data_set_encoding (signature, GPGME_DATA_ENCODING_BASE64);

err = gpgme_data_new_from_file (&message, tempfile, 1);
- if (err)
+ if (err)
{
gpgme_data_release (signature);
mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err));
@@ -1570,8 +1570,8 @@ static int verify_one (BODY *sigbdy, STATE *s,
if (err)
{
char buf[200];
-
- snprintf (buf, sizeof(buf)-1,
+
+ snprintf (buf, sizeof(buf)-1,
_("Error: verification failed: %s\n"),
gpgme_strerror (err));
state_puts (buf, s);
@@ -1655,10 +1655,10 @@ static int verify_one (BODY *sigbdy, STATE *s,
}

gpgme_release (ctx);
-
+
state_attach_puts (_("[-- End signature information --]\n\n"), s);
dprint (1, (debugfile, "verify_one: returning %d.\n", badsig));
-
+
return badsig? 1: anywarn? 2 : 0;
}

@@ -1752,8 +1752,8 @@ restart:
if ((s->flags & MUTT_DISPLAY))
{
char buf[200];
-
- snprintf (buf, sizeof(buf)-1,
+
+ snprintf (buf, sizeof(buf)-1,
_("[-- Error: decryption failed: %s --]\n\n"),
gpgme_strerror (err));
state_attach_puts (buf, s);
@@ -1779,7 +1779,7 @@ restart:
{
int res, idx;
int anybad = 0;
-
+
if (maybe_signed)
a->is_signed_data = 1;
if(r_is_signed)
@@ -1797,7 +1797,7 @@ restart:
}
if (!anybad && idx && r_is_signed && *r_is_signed)
*r_is_signed = anywarn? 2:1; /* Good signature. */
-
+
if ((s->flags & MUTT_DISPLAY))
state_attach_puts (_("[-- End signature "
"information --]\n\n"), s);
@@ -1814,7 +1814,7 @@ restart:
*/
fstat (fileno (fpout), &info);
tattach->length = info.st_size - tattach->offset;
-
+
tattach->warnsig = anywarn;

/* See if we need to recurse on this MIME part. */
@@ -1838,7 +1838,7 @@ int pgp_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur)
size_t saved_length;
FILE *decoded_fp = NULL;
int rv = 0;
-
+
first_part->goodsig = 0;
first_part->warnsig = 0;

@@ -1851,7 +1851,7 @@ int pgp_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur)
}
else
return -1;
-
+
memset (&s, 0, sizeof (s));
s.fpin = fpin;

@@ -1927,7 +1927,7 @@ int smime_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur)

if (b->parts)
return -1;
-
+
/* Decode the body - we need to pass binary CMS to the
backend. The backend allows for Base64 encoded data but it does
not allow for QP which I have seen in some messages. So better
@@ -1937,7 +1937,7 @@ int smime_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur)
saved_b_length = b->length;
memset (&s, 0, sizeof (s));
s.fpin = fpin;
- fseeko (s.fpin, b->offset, 0);
+ fseeko (s.fpin, b->offset, 0);
mutt_mktemp (tempfile, sizeof (tempfile));
if (!(tmpfp = safe_fopen (tempfile, "w+")))
{
@@ -1991,7 +1991,7 @@ int smime_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur)
saved_b_length = bb->length;
memset (&s, 0, sizeof (s));
s.fpin = *fpout;
- fseeko (s.fpin, bb->offset, 0);
+ fseeko (s.fpin, bb->offset, 0);
mutt_mktemp (tempfile, sizeof (tempfile));
if (!(tmpfp = safe_fopen (tempfile, "w+")))
{
@@ -2006,7 +2006,7 @@ int smime_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur)
bb->length = ftello (s.fpout);
bb->offset = 0;
rewind (tmpfp);
- safe_fclose (fpout);
+ safe_fclose (fpout);

memset (&s, 0, sizeof (s));
s.fpin = tmpfp;
@@ -2057,7 +2057,7 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
dprint (1, (debugfile, "Error creating GPGME context\n"));
return rc;
}
-
+
if (dryrun)
{
snprintf (tmpdir, sizeof(tmpdir), "%s/mutt-gpgme-XXXXXX", Tempdir);
@@ -2124,7 +2124,7 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
else
fprintf (*fp, "%s %5.5s %d/%8s %s\n", more ? "sub" : "pub",
gpgme_pubkey_algo_name (subkey->pubkey_algo), subkey->length,
- shortid, date);
+ shortid, date);
subkey = subkey->next;
more = 1;
}
@@ -2173,7 +2173,7 @@ static int line_compare(const char *a, size_t n, const char *b)
#define PUBLIC_KEY_BLOCK(_y) _LINE_COMPARE("PUBLIC KEY BLOCK-----", _y)
#define BEGIN_PGP_SIGNATURE(_y) _LINE_COMPARE("-----BEGIN PGP SIGNATURE-----", _y)

-/*
+/*
* Implementation of `pgp_check_traditional'.
*/

@@ -2182,10 +2182,10 @@ static int pgp_check_traditional_one_body (FILE *fp, BODY *b)
char tempfile[_POSIX_PATH_MAX];
char buf[HUGE_STRING];
FILE *tfp;
-
+
short sgn = 0;
short enc = 0;
-
+
if (b->type != TYPETEXT)
return 0;

@@ -2195,13 +2195,13 @@ static int pgp_check_traditional_one_body (FILE *fp, BODY *b)
unlink (tempfile);
return 0;
}
-
+
if ((tfp = fopen (tempfile, "r")) == NULL)
{
unlink (tempfile);
return 0;
}
-
+
while (fgets (buf, sizeof (buf), tfp))
{
if (!mutt_strncmp ("-----BEGIN PGP ", buf, 15))
@@ -2225,11 +2225,11 @@ static int pgp_check_traditional_one_body (FILE *fp, BODY *b)
return 0;

/* fix the content type */
-
+
mutt_set_parameter ("format", "fixed", &b->parameter);
mutt_set_parameter ("x-action", enc ? "pgp-encrypted" : "pgp-signed",
&b->parameter);
-
+
return 1;
}

@@ -2286,18 +2286,18 @@ void pgp_gpgme_invoke_import (const char *fname)
}


-/*
+/*
* Implementation of `application_handler'.
*/

-/*
+/*
Copy a clearsigned message, and strip the signature and PGP's
dash-escaping.
-
+
XXX - charset handling: We assume that it is safe to do
character set decoding first, dash decoding second here, while
we do it the other way around in the main handler.
-
+
(Note that we aren't worse than Outlook & Cie in this, and also
note that we can successfully handle anything produced by any
existing versions of mutt.) */
@@ -2321,7 +2321,7 @@ static void copy_clearsigned (gpgme_data_t data, STATE *s, char *charset)
* charset-hooks. Therefore we set flags to MUTT_ICONV_HOOK_FROM.
*/
fc = fgetconv_open (fp, charset, Charset, MUTT_ICONV_HOOK_FROM);
-
+
for (complete = 1, armor_header = 1;
fgetconvs (buf, sizeof (buf), fc) != NULL;
complete = strchr (buf, '\n') != NULL)
@@ -2335,23 +2335,23 @@ static void copy_clearsigned (gpgme_data_t data, STATE *s, char *charset)

if (BEGIN_PGP_SIGNATURE(buf))
break;
-
+
if (armor_header)
{
- if (buf[0] == '\n')
+ if (buf[0] == '\n')
armor_header = 0;
continue;
}
-
- if (s->prefix)
+
+ if (s->prefix)
state_puts (s->prefix, s);
-
+
if (buf[0] == '-' && buf[1] == ' ')
state_puts (buf + 2, s);
else
state_puts (buf, s);
}
-
+
fgetconv_close (&fc);
safe_fclose (&fp);
}
@@ -2384,20 +2384,20 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)

fseeko (s->fpin, m->offset, 0);
last_pos = m->offset;
-
+
for (bytes = m->length; bytes > 0;)
{
if (fgets (buf, sizeof (buf), s->fpin) == NULL)
break;
-
+
offset = ftello (s->fpin);
bytes -= (offset - last_pos); /* don't rely on mutt_strlen(buf) */
last_pos = offset;
-
+
if (!mutt_strncmp ("-----BEGIN PGP ", buf, 15))
{
clearsign = 0;
-
+
if (MESSAGE(buf + 15))
needpass = 1;
else if (SIGNED_MESSAGE(buf + 15))
@@ -2409,7 +2409,7 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
{
needpass = 0;
pgp_keyblock = 1;
- }
+ }
else
{
/* XXX - we may wish to recode here */
@@ -2418,10 +2418,10 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
state_puts (buf, s);
continue;
}
-
+
have_any_sigs = (have_any_sigs
|| (clearsign && (s->flags & MUTT_VERIFY)));
-
+
/* Copy PGP material to an data container */
armored_data = file_to_data_object (s->fpin, m->offset, m->length);
/* Invoke PGP if needed */
@@ -2461,8 +2461,8 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
if (err)
{
char errbuf[200];
-
- snprintf (errbuf, sizeof(errbuf)-1,
+
+ snprintf (errbuf, sizeof(errbuf)-1,
_("Error: decryption/verification failed: %s\n"),
gpgme_strerror (err));
state_puts (errbuf, s);
@@ -2499,7 +2499,7 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
}
if (!anybad && idx)
maybe_goodsig = 1;
-
+
state_attach_puts (_("[-- End signature "
"information --]\n\n"), s);
}
@@ -2519,13 +2519,13 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
gpgme_data_release (plaintext);
gpgme_release (ctx);
}
-
+
/*
* Now, copy cleartext to the screen. NOTE - we expect that PGP
- * outputs utf-8 cleartext. This may not always be true, but it
+ * outputs utf-8 cleartext. This may not always be true, but it
* seems to be a reasonable guess.
*/
-
+
if(s->flags & MUTT_DISPLAY)
{
if (needpass)
@@ -2537,7 +2537,7 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
state_attach_puts (_("[-- BEGIN PGP SIGNED MESSAGE --]\n\n"),
s);
}
-
+
if (clearsign)
{
copy_clearsigned (armored_data, s, body_charset);
@@ -2556,7 +2556,7 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
}
fgetconv_close (&fc);
}
-
+
if (s->flags & MUTT_DISPLAY)
{
state_putc ('\n', s);
@@ -2567,7 +2567,7 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
else
state_attach_puts (_("[-- END PGP SIGNED MESSAGE --]\n"), s);
}
-
+
gpgme_data_release (armored_data);
if (pgpout)
{
@@ -2585,7 +2585,7 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
}

m->goodsig = (maybe_goodsig && have_any_sigs);
-
+
if (needpass == -1)
{
state_attach_puts (_("[-- Error: could not find beginning"
@@ -2597,7 +2597,7 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
return err;
}

-/*
+/*
* Implementation of `encrypted_handler'.
*/

@@ -2612,7 +2612,7 @@ int pgp_gpgme_encrypted_handler (BODY *a, STATE *s)
BODY *tattach;
int is_signed;
int rc = 0;
-
+
dprint (2, (debugfile, "Entering pgp_encrypted handler\n"));

mutt_mktemp (tempfile, sizeof (tempfile));
@@ -2634,7 +2634,7 @@ int pgp_gpgme_encrypted_handler (BODY *a, STATE *s)
_("[-- The following data is PGP/MIME signed and encrypted --]\n\n"):
_("[-- The following data is PGP/MIME encrypted --]\n\n"),
s);
-
+
{
FILE *savefp = s->fpin;
s->fpin = fpout;
@@ -2642,14 +2642,14 @@ int pgp_gpgme_encrypted_handler (BODY *a, STATE *s)
s->fpin = savefp;
}

- /*
+ /*
* if a multipart/signed is the _only_ sub-part of a
* multipart/encrypted, cache signature verification
* status.
*/
if (mutt_is_multipart_signed (tattach) && !tattach->next)
a->goodsig |= tattach->goodsig;
-
+
if (s->flags & MUTT_DISPLAY)
{
state_puts ("\n", s);
@@ -2686,7 +2686,7 @@ int smime_gpgme_application_handler (BODY *a, STATE *s)
int rc = 0;

dprint (2, (debugfile, "Entering smime_encrypted handler\n"));
-
+
a->warnsig = 0;
mutt_mktemp (tempfile, sizeof (tempfile));
if (!(fpout = safe_fopen (tempfile, "w+")))
@@ -2707,7 +2707,7 @@ int smime_gpgme_application_handler (BODY *a, STATE *s)
_("[-- The following data is S/MIME signed --]\n\n"):
_("[-- The following data is S/MIME encrypted --]\n\n"),
s);
-
+
{
FILE *savefp = s->fpin;
s->fpin = fpout;
@@ -2715,7 +2715,7 @@ int smime_gpgme_application_handler (BODY *a, STATE *s)
s->fpin = savefp;
}

- /*
+ /*
* if a multipart/signed is the _only_ sub-part of a
* multipart/encrypted, cache signature verification
* status.
@@ -2742,18 +2742,18 @@ int smime_gpgme_application_handler (BODY *a, STATE *s)

mutt_free_body (&tattach);
}
-
+
safe_fclose (&fpout);
mutt_unlink(tempfile);
dprint (2, (debugfile, "Leaving smime_encrypted handler\n"));
-
+
return rc;
}


/*
* Format an entry on the CRYPT key selection menu.
- *
+ *
* %n number
* %k key id %K key id of the principal key
* %u user id
@@ -2794,7 +2794,7 @@ static const char *crypt_entry_fmt (char *dest,

kflags = (key->flags /*| (pkey->flags & KEYFLAG_RESTRICTIONS)
| uid->flags*/);
-
+
switch (ascii_tolower (op))
{
case '[':
@@ -2971,17 +2971,17 @@ static const char *crypt_entry_fmt (char *dest,
mutt_FormatString (dest, destlen, col, cols, elsestring, mutt_attach_fmt, data, 0);
return (src);
}
-
+
/* Used by the display function to format a line. */
static void crypt_entry (char *s, size_t l, MUTTMENU * menu, int num)
{
crypt_key_t **key_table = (crypt_key_t **) menu->data;
crypt_entry_t entry;
-
+
entry.key = key_table[num];
entry.num = num + 1;

- mutt_FormatString (s, l, 0, MuttIndexWindow->cols, NONULL (PgpEntryFormat), crypt_entry_fmt,
+ mutt_FormatString (s, l, 0, MuttIndexWindow->cols, NONULL (PgpEntryFormat), crypt_entry_fmt,
(unsigned long) &entry, MUTT_FORMAT_ARROWCURSOR);
}

@@ -3120,10 +3120,10 @@ static void
print_dn_parts (FILE *fp, struct dn_array_s *dn)
{
static const char * const stdpart[] = {
- "CN", "OU", "O", "STREET", "L", "ST", "C", NULL
+ "CN", "OU", "O", "STREET", "L", "ST", "C", NULL
};
int any=0, any2=0, i;
-
+
for (i=0; stdpart[i]; i++)
{
if (any)
@@ -3198,7 +3198,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string)
{ /* pair */
s++;
if (*s == ',' || *s == '=' || *s == '+'
- || *s == '<' || *s == '>' || *s == '#' || *s == ';'
+ || *s == '<' || *s == '>' || *s == '#' || *s == ';'
|| *s == '\\' || *s == '\"' || *s == ' ')
n++;
else if (hexdigitp (s) && hexdigitp (s+1))
@@ -3213,7 +3213,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string)
return NULL; /* invalid encoding */
else if (*s == ',' || *s == '=' || *s == '+'
|| *s == '<' || *s == '>' || *s == '#' || *s == ';' )
- break;
+ break;
else
n++;
}
@@ -3223,7 +3223,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string)
for (s=string; n; s++, n--)
{
if (*s == '\\')
- {
+ {
s++;
if (hexdigitp (s))
{
@@ -3328,9 +3328,9 @@ parse_and_print_user_id (FILE *fp, const char *userid)
struct dn_array_s *dn = parse_dn ((const unsigned char *)userid);
if (!dn)
fputs (_("[Can't display this user ID (invalid DN)]"), fp);
- else
+ else
{
- print_dn_parts (fp, dn);
+ print_dn_parts (fp, dn);
for (i=0; dn[i].key; i++)
{
FREE (&dn[i].key);
@@ -3700,7 +3700,7 @@ static void print_key_info (gpgme_key_t key, FILE *fp)


/* Show detailed information about the selected key */
-static void
+static void
verify_key (crypt_key_t *key)
{
FILE *fp;
@@ -3748,7 +3748,7 @@ verify_key (crypt_key_t *key)
goto leave;
}
gpgme_op_keylist_end (listctx);
-
+
print_key_info (k, fp);
if (!--maxdepth)
{
@@ -3768,7 +3768,7 @@ verify_key (crypt_key_t *key)
mutt_do_pager (cmd, tempfile, 0, NULL);
}

-/*
+/*
* Implementation of `findkeys'.
*/

@@ -3843,9 +3843,9 @@ static crypt_key_t *get_candidates (LIST * hints, unsigned int app, int secret)
pattern = list_to_pattern (hints);
if (!pattern)
return NULL;
-
+
err = gpgme_new (&ctx);
- if (err)
+ if (err)
{
mutt_error (_("gpgme_new failed: %s"), gpgme_strerror (err));
FREE (&pattern);
@@ -3854,7 +3854,7 @@ static crypt_key_t *get_candidates (LIST * hints, unsigned int app, int secret)

db = NULL;
kend = &db;
-
+
if ((app & APPLICATION_PGP))
{
/* Its all a mess. That old GPGME expects different things
@@ -3884,7 +3884,7 @@ static crypt_key_t *get_candidates (LIST * hints, unsigned int app, int secret)
for (n=0; patarr[n]; n++)
FREE (&patarr[n]);
FREE (&patarr);
- if (err)
+ if (err)
{
mutt_error (_("gpgme_op_keylist_start failed: %s"),
gpgme_strerror (err));
@@ -3896,7 +3896,7 @@ static crypt_key_t *get_candidates (LIST * hints, unsigned int app, int secret)
while (!(err = gpgme_op_keylist_next (ctx, &key)) )
{
unsigned int flags = 0;
-
+
if (key_check_cap (key, KEY_CAP_CAN_ENCRYPT))
flags |= KEYFLAG_CANENCRYPT;
if (key_check_cap (key, KEY_CAP_CAN_SIGN))
@@ -3959,7 +3959,7 @@ static crypt_key_t *get_candidates (LIST * hints, unsigned int app, int secret)
/* and now look for x509 certificates */
gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
err = gpgme_op_keylist_start (ctx, pattern, 0);
- if (err)
+ if (err)
{
mutt_error (_("gpgme_op_keylist_start failed: %s"),
gpgme_strerror (err));
@@ -3976,7 +3976,7 @@ static crypt_key_t *get_candidates (LIST * hints, unsigned int app, int secret)
flags |= KEYFLAG_CANENCRYPT;
if (key_check_cap (key, KEY_CAP_CAN_SIGN))
flags |= KEYFLAG_CANSIGN;
-
+
for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
{
k = safe_calloc (1, sizeof *k);
@@ -4017,7 +4017,7 @@ static LIST *crypt_add_string_to_hints (LIST *hints, const char *str)
if (strlen (t) > 3)
hints = mutt_add_list (hints, t);
}
-
+
FREE (&scratch);
return hints;
}
@@ -4026,7 +4026,7 @@ static LIST *crypt_add_string_to_hints (LIST *hints, const char *str)
will be set to true on return if the user did override the the
key's validity. */
static crypt_key_t *crypt_select_key (crypt_key_t *keys,
- ADDRESS * p, const char *s,
+ ADDRESS * p, const char *s,
unsigned int app, int *forced_valid)
{
int keymax;
@@ -4051,13 +4051,13 @@ static crypt_key_t *crypt_select_key (crypt_key_t *keys,
unusable = 1;
continue;
}
-
+
if (i == keymax)
{
keymax += 20;
safe_realloc (&key_table, sizeof (crypt_key_t*)*keymax);
}
-
+
key_table[i++] = k;
}

@@ -4132,7 +4132,7 @@ static crypt_key_t *crypt_select_key (crypt_key_t *keys,
/* L10N:
e.g. 'S/MIME keys matching "Michael Elkins".' */
snprintf (buf, sizeof (buf), _("%s \"%s\"."), ts, s);
- menu->title = buf;
+ menu->title = buf;
}

mutt_clear_error ();
@@ -4146,11 +4146,11 @@ static crypt_key_t *crypt_select_key (crypt_key_t *keys,
verify_key (key_table[menu->current]);
menu->redraw = REDRAW_FULL;
break;
-
+
case OP_VIEW_ID:
mutt_message ("%s", key_table[menu->current]->uid);
break;
-
+
case OP_GENERIC_SELECT_ENTRY:
/* FIXME make error reporting more verbose - this should be
easy because gpgme provides more information */
@@ -4163,33 +4163,33 @@ static crypt_key_t *crypt_select_key (crypt_key_t *keys,
break;
}
}
-
+
if (option (OPTPGPCHECKTRUST) &&
(!crypt_id_is_valid (key_table[menu->current])
|| !crypt_id_is_strong (key_table[menu->current])))
{
const char *warn_s;
char buff[LONG_STRING];
-
+
if (key_table[menu->current]->flags & KEYFLAG_CANTUSE)
warn_s = N_("ID is expired/disabled/revoked.");
- else
+ else
{
warn_s = "??";
switch (key_table[menu->current]->validity)
{
- case GPGME_VALIDITY_UNKNOWN:
- case GPGME_VALIDITY_UNDEFINED:
+ case GPGME_VALIDITY_UNKNOWN:
+ case GPGME_VALIDITY_UNDEFINED:
warn_s = N_("ID has undefined validity.");
break;
- case GPGME_VALIDITY_NEVER:
+ case GPGME_VALIDITY_NEVER:
warn_s = N_("ID is not valid.");
break;
- case GPGME_VALIDITY_MARGINAL:
+ case GPGME_VALIDITY_MARGINAL:
warn_s = N_("ID is only marginally valid.");
break;
- case GPGME_VALIDITY_FULL:
- case GPGME_VALIDITY_ULTIMATE:
+ case GPGME_VALIDITY_FULL:
+ case GPGME_VALIDITY_ULTIMATE:
break;
}
}
@@ -4197,30 +4197,30 @@ static crypt_key_t *crypt_select_key (crypt_key_t *keys,
snprintf (buff, sizeof (buff),
_("%s Do you really want to use the key?"),
_(warn_s));
-
+
if (mutt_yesorno (buff, 0) != 1)
{
mutt_clear_error ();
break;
}
*forced_valid = 1;
- }
+ }

k = crypt_copy_key (key_table[menu->current]);
done = 1;
break;
-
+
case OP_EXIT:
k = NULL;
done = 1;
break;
}
}
-
+
mutt_pop_current_menu (menu);
mutt_menuDestroy (&menu);
FREE (&key_table);
-
+
return k;
}

@@ -4241,7 +4241,7 @@ static crypt_key_t *crypt_getkeybyaddr (ADDRESS * a, short abilities,
crypt_key_t *a_valid_addrmatch_key = NULL;
crypt_key_t *matches = NULL;
crypt_key_t **matches_endp = &matches;
-
+
*forced_valid = 0;

if (a && a->mailbox)
@@ -4254,10 +4254,10 @@ static crypt_key_t *crypt_getkeybyaddr (ADDRESS * a, short abilities,
keys = get_candidates (hints, app, (abilities & KEYFLAG_CANSIGN) );

mutt_free_list (&hints);
-
+
if (!keys)
return NULL;
-
+
dprint (5, (debugfile, "crypt_getkeybyaddr: looking for %s <%s>.",
a->personal, a->mailbox));

@@ -4265,7 +4265,7 @@ static crypt_key_t *crypt_getkeybyaddr (ADDRESS * a, short abilities,
{
dprint (5, (debugfile, " looking at key: %s `%.15s'\n",
crypt_keyid (k), k->uid));
-
+
if (abilities && !(k->flags & abilities))
{
dprint (5, (debugfile, " insufficient abilities: Has %x, want %x\n",
@@ -4281,7 +4281,7 @@ static crypt_key_t *crypt_getkeybyaddr (ADDRESS * a, short abilities,
for (p = r; p; p = p->next)
{
int validity = crypt_id_matches_addr (a, p, k);
-
+
if (validity & CRYPT_KV_MATCH) /* something matches */
{
match = 1;
@@ -4302,7 +4302,7 @@ static crypt_key_t *crypt_getkeybyaddr (ADDRESS * a, short abilities,
}
}
rfc822_free_address (&r);
-
+
if (match)
{
crypt_key_t *tmp;
@@ -4316,9 +4316,9 @@ static crypt_key_t *crypt_getkeybyaddr (ADDRESS * a, short abilities,
a_valid_addrmatch_key = tmp;
}
}
-
+
crypt_free_key (&keys);
-
+
if (matches)
{
if (oppenc_mode)
@@ -4331,17 +4331,17 @@ static crypt_key_t *crypt_getkeybyaddr (ADDRESS * a, short abilities,
k = NULL;
}
else if (the_strong_valid_key && !multi)
- {
- /*
+ {
+ /*
* There was precisely one strong match on a valid ID.
- *
+ *
* Proceed without asking the user.
*/
k = crypt_copy_key (the_strong_valid_key);
}
- else
+ else
{
- /*
+ /*
* Else: Ask the user.
*/
k = crypt_select_key (matches, a, NULL, app, forced_valid);
@@ -4349,9 +4349,9 @@ static crypt_key_t *crypt_getkeybyaddr (ADDRESS * a, short abilities,

crypt_free_key (&matches);
}
- else
+ else
k = NULL;
-
+
return k;
}

@@ -4403,17 +4403,17 @@ static crypt_key_t *crypt_getkeybystr (char *p, short abilities,
matches_endp = &tmp->next;
}
}
-
+
FREE (&pfcopy);
crypt_free_key (&keys);
-
+
if (matches)
{
k = crypt_select_key (matches, NULL, p, app, forced_valid);
crypt_free_key (&matches);
return k;
}
-
+
return NULL;
}

@@ -4422,8 +4422,8 @@ static crypt_key_t *crypt_getkeybystr (char *p, short abilities,
default. ABILITIES describe the required key abilities (sign,
encrypt) and APP the type of the requested key; ether S/MIME or
PGP. Return a copy of the key or NULL if not found. */
-static crypt_key_t *crypt_ask_for_key (char *tag,
- char *whatfor,
+static crypt_key_t *crypt_ask_for_key (char *tag,
+ char *whatfor,
short abilities,
unsigned int app,
int *forced_valid)
@@ -4442,7 +4442,7 @@ static crypt_key_t *crypt_ask_for_key (char *tag,
resp[0] = 0;
if (whatfor)
{
-
+
for (l = id_defaults; l; l = l->next)
if (!mutt_strcasecmp (whatfor, l->what))
{
@@ -4457,7 +4457,7 @@ static crypt_key_t *crypt_ask_for_key (char *tag,
resp[0] = 0;
if (mutt_get_field (tag, resp, sizeof (resp), MUTT_CLEAR) != 0)
return NULL;
-
+
if (whatfor)
{
if (l)
@@ -4471,10 +4471,10 @@ static crypt_key_t *crypt_ask_for_key (char *tag,
l->dflt = safe_strdup (resp);
}
}
-
+
if ((key = crypt_getkeybystr (resp, abilities, app, forced_valid)))
return key;
-
+
BEEP ();
}
/* not reached */
@@ -4536,7 +4536,7 @@ static char *find_keys (ADDRESS *adrlist, unsigned int app, int oppenc_mode)
}

/* check for e-mail address */
- if ((t = strchr (crypt_hook_val, '@')) &&
+ if ((t = strchr (crypt_hook_val, '@')) &&
(addr = rfc822_parse_adrlist (NULL, crypt_hook_val)))
{
if (fqdn)
@@ -4545,11 +4545,11 @@ static char *find_keys (ADDRESS *adrlist, unsigned int app, int oppenc_mode)
}
else if (! oppenc_mode)
{
-#if 0
- k_info = crypt_getkeybystr (crypt_hook_val, KEYFLAG_CANENCRYPT,
+#if 0
+ k_info = crypt_getkeybystr (crypt_hook_val, KEYFLAG_CANENCRYPT,
*r_application, &forced_valid);
#else
- k_info = crypt_getkeybystr (crypt_hook_val, KEYFLAG_CANENCRYPT,
+ k_info = crypt_getkeybystr (crypt_hook_val, KEYFLAG_CANENCRYPT,
app, &forced_valid);
#endif
}
@@ -4580,7 +4580,7 @@ static char *find_keys (ADDRESS *adrlist, unsigned int app, int oppenc_mode)
if ((k_info == NULL) && (! oppenc_mode))
{
snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox);
-
+
k_info = crypt_ask_for_key (buf, q->mailbox,
KEYFLAG_CANENCRYPT,
#if 0
@@ -4608,7 +4608,7 @@ static char *find_keys (ADDRESS *adrlist, unsigned int app, int oppenc_mode)
if (!(k_info->flags & KEYFLAG_ISX509))
*r_application &= ~APPLICATION_SMIME;
#endif
-
+
bypass_selection:
keylist_size += mutt_strlen (keyID) + 4 + 1;
safe_realloc (&keylist, keylist_size);
diff --git a/crypt-gpgme.h b/crypt-gpgme.h
index bb283a50..a2e06b86 100644
--- a/crypt-gpgme.h
+++ b/crypt-gpgme.h
@@ -1,16 +1,16 @@
-/*
+/*
* Copyright (C) 2004 g10 Code GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program 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 General Public License for more details.
- *
+ *
* You should have received a copy of the GNU 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.
diff --git a/crypt-mod-pgp-classic.c b/crypt-mod-pgp-classic.c
index 37dd1771..b0534afe 100644
--- a/crypt-mod-pgp-classic.c
+++ b/crypt-mod-pgp-classic.c
@@ -1,22 +1,22 @@
-/*
+/*
* Copyright (C) 2004 g10 Code GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program 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 General Public License for more details.
- *
+ *
* You should have received a copy of the GNU 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.
*/

-/*
+/*
This is a crytpo module wrapping the classic pgp code.
*/

diff --git a/crypt-mod-pgp-gpgme.c b/crypt-mod-pgp-gpgme.c
index b56fcdba..5521db97 100644
--- a/crypt-mod-pgp-gpgme.c
+++ b/crypt-mod-pgp-gpgme.c
@@ -1,22 +1,22 @@
-/*
+/*
* Copyright (C) 2004 g10 Code GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program 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 General Public License for more details.
- *
+ *
* You should have received a copy of the GNU 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.
*/

-/*
+/*
This is a crytpo module wrapping the gpgme based pgp code.
*/

diff --git a/crypt-mod-smime-classic.c b/crypt-mod-smime-classic.c
index b671b926..99952d40 100644
--- a/crypt-mod-smime-classic.c
+++ b/crypt-mod-smime-classic.c
@@ -1,22 +1,22 @@
-/*
+/*
* Copyright (C) 2004 g10 Code GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program 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 General Public License for more details.
- *
+ *
* You should have received a copy of the GNU 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.
*/

-/*
+/*
This is a crytpo module wrapping the classic smime code.
*/

@@ -109,7 +109,7 @@ struct crypt_module_specs crypt_mod_smime_classic =
NULL, /* pgp_invoke_getkeys */
NULL, /* pgp_invoke_import */
NULL, /* pgp_extract_keys_from_attachment_list */
-
+
crypt_mod_smime_getkeys,
crypt_mod_smime_verify_sender,
crypt_mod_smime_build_smime_entity,
diff --git a/crypt-mod-smime-gpgme.c b/crypt-mod-smime-gpgme.c
index a3063632..e8fda3e7 100644
--- a/crypt-mod-smime-gpgme.c
+++ b/crypt-mod-smime-gpgme.c
@@ -1,22 +1,22 @@
-/*
+/*
* Copyright (C) 2004 g10 Code GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program 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 General Public License for more details.
- *
+ *
* You should have received a copy of the GNU 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.
*/

-/*
+/*
This is a crytpo module wrapping the gpgme based smime code.
*/

@@ -107,7 +107,7 @@ struct crypt_module_specs crypt_mod_smime_gpgme =
NULL, /* pgp_invoke_getkeys */
NULL, /* pgp_invoke_import */
NULL, /* pgp_extract_keys_from_attachment_list */
-
+
NULL, /* smime_getkeys */
crypt_mod_smime_verify_sender,
crypt_mod_smime_build_smime_entity,
diff --git a/crypt-mod.c b/crypt-mod.c
index 0000356c..644cd3df 100644
--- a/crypt-mod.c
+++ b/crypt-mod.c
@@ -5,12 +5,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program 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 General Public License for more details.
- *
+ *
* You should have received a copy of the GNU 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.
diff --git a/crypt-mod.h b/crypt-mod.h
index 2b8ba4b8..08934a63 100644
--- a/crypt-mod.h
+++ b/crypt-mod.h
@@ -5,12 +5,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program 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 General Public License for more details.
- *
+ *
* You should have received a copy of the GNU 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.
@@ -25,7 +25,7 @@
#define CRYPTO_SUPPORT(identifier) (WithCrypto & APPLICATION_ ## identifier)


-/*
+/*
Type definitions for crypto module functions.
*/
typedef void (*crypt_func_void_passphrase_t) (void);
@@ -50,7 +50,7 @@ typedef BODY *(*crypt_func_pgp_encrypt_message_t) (BODY *a, char *keylist,
typedef void (*crypt_func_pgp_invoke_import_t) (const char *fname);
typedef int (*crypt_func_verify_one_t) (BODY *sigbdy, STATE *s,
const char *tempf);
-typedef void (*crypt_func_pgp_extract_keys_from_attachment_list_t)
+typedef void (*crypt_func_pgp_extract_keys_from_attachment_list_t)
(FILE *fp, int tag, BODY *top);

typedef int (*crypt_func_send_menu_t) (HEADER *msg);
@@ -106,7 +106,7 @@ typedef struct crypt_module_functions


/*
- A structure to describe a crypto module.
+ A structure to describe a crypto module.
*/
typedef struct crypt_module_specs
{
@@ -116,8 +116,8 @@ typedef struct crypt_module_specs



-/*
- High Level crypto module interface.
+/*
+ High Level crypto module interface.
*/

void crypto_module_register (crypt_module_specs_t specs);
diff --git a/crypt.c b/crypt.c
index 11a668b4..d5899075 100644
--- a/crypt.c
+++ b/crypt.c
@@ -10,12 +10,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program 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 General Public License for more details.
- *
+ *
* You should have received a copy of the GNU 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.
@@ -276,7 +276,7 @@ int mutt_protect (HEADER *msg, char *keylist)
return (-1);
}

- /* destroy temporary signature envelope when doing retainable
+ /* destroy temporary signature envelope when doing retainable
* signatures.

*/
@@ -295,8 +295,8 @@ int mutt_protect (HEADER *msg, char *keylist)
}


-
-
+
+
int mutt_is_multipart_signed (BODY *b)
{
char *p;
@@ -314,7 +314,7 @@ int mutt_is_multipart_signed (BODY *b)
if ((WithCrypto & APPLICATION_PGP)
&& !(ascii_strcasecmp (p, "application/pgp-signature")))
return PGPSIGN;
-
+
if ((WithCrypto & APPLICATION_SMIME)
&& !(ascii_strcasecmp (p, "application/x-pkcs7-signature")))
return SMIMESIGN;
@@ -324,20 +324,20 @@ int mutt_is_multipart_signed (BODY *b)

return 0;
}
-
-
+
+
int mutt_is_multipart_encrypted (BODY *b)
{
if ((WithCrypto & APPLICATION_PGP))
{
char *p;
-
+
if (!b || b->type != TYPEMULTIPART ||
!b->subtype || ascii_strcasecmp (b->subtype, "encrypted") ||
!(p = mutt_get_parameter ("protocol", b->parameter)) ||
ascii_strcasecmp (p, "application/pgp-encrypted"))
return 0;
-
+
return PGPENCRYPT;
}

@@ -410,7 +410,7 @@ int mutt_is_application_pgp (BODY *m)
{
int t = 0;
char *p;
-
+
if (m->type == TYPEAPPLICATION)
{
if (!ascii_strcasecmp (m->subtype, "pgp") || !ascii_strcasecmp (m->subtype, "x-pgp-message"))
@@ -419,7 +419,7 @@ int mutt_is_application_pgp (BODY *m)
&& (!ascii_strcasecmp (p, "sign") || !ascii_strcasecmp (p, "signclear")))
t |= PGPSIGN;

- if ((p = mutt_get_parameter ("format", m->parameter)) &&
+ if ((p = mutt_get_parameter ("format", m->parameter)) &&
!ascii_strcasecmp (p, "keys-only"))
t |= PGPKEY;

@@ -435,7 +435,7 @@ int mutt_is_application_pgp (BODY *m)
else if (m->type == TYPETEXT && ascii_strcasecmp ("plain", m->subtype) == 0)
{
if (((p = mutt_get_parameter ("x-mutt-action", m->parameter))
- || (p = mutt_get_parameter ("x-action", m->parameter))
+ || (p = mutt_get_parameter ("x-action", m->parameter))
|| (p = mutt_get_parameter ("action", m->parameter)))
&& !ascii_strncasecmp ("pgp-sign", p, 8))
t |= PGPSIGN;
@@ -472,7 +472,7 @@ int mutt_is_application_smime (BODY *m)
return (SMIMESIGN|SMIMEOPAQUE);
else return 0;
}
- /* Netscape 4.7 uses
+ /* Netscape 4.7 uses
* Content-Description: S/MIME Encrypted Message
* instead of Content-Type parameter
*/
@@ -487,7 +487,7 @@ int mutt_is_application_smime (BODY *m)

if (!t) t = m->d_filename;
if (!t) t = m->filename;
- if (!t)
+ if (!t)
{
if (complain)
mutt_message (_("S/MIME messages with no hints on content are unsupported."));
@@ -504,7 +504,7 @@ int mutt_is_application_smime (BODY *m)
#if 0
return SMIMEENCRYPT;
#else
- /* Not sure if this is the correct thing to do, but
+ /* Not sure if this is the correct thing to do, but
it's required for compatibility with Outlook */
return (SMIMESIGN|SMIMEOPAQUE);
#endif
@@ -527,7 +527,7 @@ int crypt_query (BODY *m)

if (!WithCrypto)
return 0;
-
+
if (!m)
return 0;

@@ -549,14 +549,14 @@ int crypt_query (BODY *m)
if (t && m->goodsig)
t |= GOODSIGN;
}
-
+
if (m->type == TYPEMULTIPART)
{
t |= mutt_is_multipart_encrypted(m);
t |= mutt_is_multipart_signed (m);
t |= mutt_is_malformed_multipart_pgp_encrypted (m);

- if (t && m->goodsig)
+ if (t && m->goodsig)
t |= GOODSIGN;
}

@@ -564,17 +564,17 @@ int crypt_query (BODY *m)
{
BODY *p;
int u, v, w;
-
+
u = m->parts ? 0xffffffff : 0; /* Bits set in all parts */
w = 0; /* Bits set in any part */
-
+
for (p = m->parts; p; p = p->next)
{
v = crypt_query (p);
u &= v; w |= v;
}
t |= u | (w & ~GOODSIGN);
-
+
if ((w & GOODSIGN) && !(u & GOODSIGN))
t |= PARTSIGN;
}
@@ -600,7 +600,7 @@ int crypt_write_signed(BODY *a, STATE *s, const char *tempfile)
mutt_perror (tempfile);
return -1;
}
-
+
fseeko (s->fpin, a->hdr_offset, 0);
bytes = a->length + a->offset - a->hdr_offset;
hadcr = 0;
@@ -608,21 +608,21 @@ int crypt_write_signed(BODY *a, STATE *s, const char *tempfile)
{
if ((c = fgetc (s->fpin)) == EOF)
break;
-
+
bytes--;
-
+
if (c == '\r')
hadcr = 1;
- else
+ else
{
if (c == '\n' && !hadcr)
fputc ('\r', fp);
-
+
hadcr = 0;
}
-
+
fputc (c, fp);
-
+
}
safe_fclose (&fp);

@@ -647,7 +647,7 @@ void convert_to_7bit (BODY *a)
}
else if ((WithCrypto & APPLICATION_PGP) && option (OPTPGPSTRICTENC))
convert_to_7bit (a->parts);
- }
+ }
else if (a->type == TYPEMESSAGE &&
ascii_strcasecmp(a->subtype, "delivery-status"))
{
@@ -659,7 +659,7 @@ void convert_to_7bit (BODY *a)
else if (a->encoding == ENCBINARY)
a->encoding = ENCBASE64;
else if (a->content && a->encoding != ENCBASE64 &&
- (a->content->from || (a->content->space &&
+ (a->content->from || (a->content->space &&
option (OPTPGPSTRICTENC))))
a->encoding = ENCQUOTEDPRINTABLE;
a = a->next;
@@ -706,10 +706,10 @@ void crypt_extract_keys_from_messages (HEADER * h)
if ((WithCrypto & APPLICATION_PGP)
&& (Context->hdrs[Context->v2r[i]]->security & APPLICATION_PGP))
{
- mutt_copy_message (fpout, Context, Context->hdrs[Context->v2r[i]],
+ mutt_copy_message (fpout, Context, Context->hdrs[Context->v2r[i]],
MUTT_CM_DECODE|MUTT_CM_CHARCONV, 0);
fflush(fpout);
-
+
mutt_endwin (_("Trying to extract PGP keys...\n"));
crypt_pgp_invoke_import (tempfname);
}
@@ -770,7 +770,7 @@ void crypt_extract_keys_from_messages (HEADER * h)

fflush(fpout);
if (h->env->from) tmp = mutt_expand_aliases (h->env->from);
- else if (h->env->sender) tmp = mutt_expand_aliases (h->env->sender);
+ else if (h->env->sender) tmp = mutt_expand_aliases (h->env->sender);
mbox = tmp ? tmp->mailbox : NULL;
if (mbox) /* else ? */
{
@@ -780,7 +780,7 @@ void crypt_extract_keys_from_messages (HEADER * h)
}
}
}
-
+
safe_fclose (&fpout);
if (isendwin())
mutt_any_key_to_continue (NULL);
@@ -855,7 +855,7 @@ int crypt_get_keys (HEADER *msg, char **keylist, int oppenc_mode)
}

rfc822_free_address (&adrlist);
-
+
return (0);
}

@@ -918,7 +918,7 @@ int mutt_signed_handler (BODY *a, STATE *s)
char tempfile[_POSIX_PATH_MAX];
int signed_type;
int inconsistent = 0;
-
+
BODY *b = a;
BODY **signatures = NULL;
int sigcnt = 0;
@@ -977,9 +977,9 @@ int mutt_signed_handler (BODY *a, STATE *s)

if (s->flags & MUTT_DISPLAY)
{
-
+
crypt_fetch_signatures (&signatures, a->next, &sigcnt);
-
+
if (sigcnt)
{
mutt_mktemp (tempfile, sizeof (tempfile));
@@ -988,23 +988,23 @@ int mutt_signed_handler (BODY *a, STATE *s)
for (i = 0; i < sigcnt; i++)
{
if ((WithCrypto & APPLICATION_PGP)
- && signatures[i]->type == TYPEAPPLICATION
+ && signatures[i]->type == TYPEAPPLICATION
&& !ascii_strcasecmp (signatures[i]->subtype, "pgp-signature"))
{
if (crypt_pgp_verify_one (signatures[i], s, tempfile) != 0)
goodsig = 0;
-
+
continue;
}

if ((WithCrypto & APPLICATION_SMIME)
- && signatures[i]->type == TYPEAPPLICATION
+ && signatures[i]->type == TYPEAPPLICATION
&& (!ascii_strcasecmp(signatures[i]->subtype, "x-pkcs7-signature")
|| !ascii_strcasecmp(signatures[i]->subtype, "pkcs7-signature")))
{
if (crypt_smime_verify_one (signatures[i], s, tempfile) != 0)
goodsig = 0;
-
+
continue;
}

@@ -1013,12 +1013,12 @@ int mutt_signed_handler (BODY *a, STATE *s)
TYPE(signatures[i]), signatures[i]->subtype);
}
}
-
+
mutt_unlink (tempfile);

b->goodsig = goodsig;
b->badsig = !goodsig;
-
+
/* Now display the signed body */
state_attach_puts (_("[-- The following data is signed --]\n\n"), s);

@@ -1028,12 +1028,12 @@ int mutt_signed_handler (BODY *a, STATE *s)
else
state_attach_puts (_("[-- Warning: Can't find any signatures. --]\n\n"), s);
}
-
+
rc = mutt_body_handler (a, s);
-
+
if (s->flags & MUTT_DISPLAY && sigcnt)
state_attach_puts (_("\n[-- End of signed data --]\n"), s);
-
+
return rc;
}

diff --git a/cryptglue.c b/cryptglue.c
index 2379fe33..6d549f9f 100644
--- a/cryptglue.c
+++ b/cryptglue.c
@@ -6,12 +6,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program 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 General Public License for more details.
- *
+ *
* You should have received a copy of the GNU 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.
@@ -38,7 +38,7 @@
#include "crypt-mod.h"

/*
-
+
Generic

*/
@@ -130,7 +130,7 @@ int crypt_has_module_backend (int type)



-/*
+/*

PGP

@@ -167,7 +167,7 @@ int crypt_pgp_application_pgp_handler (BODY *m, STATE *s)
{
if (CRYPT_MOD_CALL_CHECK (PGP, application_handler))
return (CRYPT_MOD_CALL (PGP, application_handler)) (m, s);
-
+
return -1;
}

@@ -176,7 +176,7 @@ int crypt_pgp_encrypted_handler (BODY *a, STATE *s)
{
if (CRYPT_MOD_CALL_CHECK (PGP, encrypted_handler))
return (CRYPT_MOD_CALL (PGP, encrypted_handler)) (a, s);
-
+
return -1;
}

@@ -287,9 +287,9 @@ void crypt_pgp_set_sender (const char *sender)



-/*
+/*

- S/MIME
+ S/MIME

*/

@@ -323,7 +323,7 @@ int crypt_smime_application_smime_handler (BODY *m, STATE *s)
{
if (CRYPT_MOD_CALL_CHECK (SMIME, application_handler))
return (CRYPT_MOD_CALL (SMIME, application_handler)) (m, s);
-
+
return -1;
}
--
2.11.0
Kevin J. McCarthy
2018-12-04 20:01:35 UTC
Permalink
Post by Werner Koch
here is my first set of patches to cleanup some bit rot in the gpgme
interface of Mutt.
Thank you Werner! I will take a look at these patches today and
tomorrow.

[I sent a private email to Werner yesterday acknowledging the patches,
but didn't want the list to think I was ignoring them].

-Kevin
--
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C 5308 ADEF 7684 8031 6BDA
Kevin J. McCarthy
2018-12-05 04:25:05 UTC
Permalink
Post by Werner Koch
here is my first set of patches to cleanup some bit rot in the gpgme
interface of Mutt. The actual visible thing is a fix to the listing of
imported keys. That listing of imported keys to the console must have
stopped working on 2014-12-31 due to a fix for bug #3698, which was
needed due to a not fully working stub code introduced in 2008.
The patches now require GPGME 1.4.0 which was released more than 5 years
ago. I don't thing that this should be any problem, in fact for
security reason it would even be better to require a very decent
version. But that can be done later.
Thanks for the patches. I've pushed all these up.

I only have one question, for PATCH 4/5. Since we require GPGME 1.4.0+
now, do we need to include the legacy versions of cmp_version_strings(),
parse_version_string(), and parse_version_number() inside crypt-gpgme.c?
--
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C 5308 ADEF 7684 8031 6BDA
ilf
2018-12-05 08:22:00 UTC
Permalink
Thanks for this work!
Post by Werner Koch
The patches now require GPGME 1.4.0 which was released more than 5
years ago. I don't thing that this should be any problem, in fact for
security reason it would even be better to require a very decent
version. But that can be done later.
I agree. When Mutt gets patches now, they should work for current - or
only slightly - older GPGME versions. The most prominent reason to use
older releases are OS distros that ship and support releases from the
time of their freeze. But if they don't upgrade GPGME, then they don't
update Mutt either.

GPGME 1.8.0 has been released two years ago. I think it's very
reasonable to have a future Mutt release to require that version.

At least by default. If anyone has a valid use-case maybe a fallback
option could support 1.6.0, which is over three years old.

What do you think?
--
ilf

If you upload your address book to "the cloud", I don't want to be in it.
Loading...