cli/lib: remove support for GMime 2.4

It's becoming a maintenance burden to do anything things with the
crypto glue code twice, once for 2.4 and once for 2.6. I don't have
any 2.4 version available to test on my development machine anymore,
so the 2.4 specific code paths are likely not very well tested.
This commit is contained in:
David Bremner 2015-08-16 17:33:21 +02:00
parent cb08a2ee01
commit 005c2f0df1
7 changed files with 24 additions and 250 deletions

View file

@ -20,7 +20,7 @@ configure stage.
Dependencies Dependencies
------------ ------------
Notmuch depends on four libraries: Xapian, GMime 2.4 or 2.6, Notmuch depends on four libraries: Xapian, GMime 2.6,
Talloc, and zlib which are each described below: Talloc, and zlib which are each described below:
Xapian Xapian
@ -39,8 +39,8 @@ Talloc, and zlib which are each described below:
reading mail while notmuch would wait for Xapian when removing reading mail while notmuch would wait for Xapian when removing
the "inbox" and "unread" tags from messages in a thread. the "inbox" and "unread" tags from messages in a thread.
GMime 2.4 or 2.6 GMime 2.6
---------------- ----------
GMime provides decoding of MIME email messages for Notmuch. GMime provides decoding of MIME email messages for Notmuch.
Without GMime, Notmuch would not be able to extract and index Without GMime, Notmuch would not be able to extract and index

6
NEWS
View file

@ -1,6 +1,12 @@
Notmuch 0.21 (UNRELEASED) Notmuch 0.21 (UNRELEASED)
========================= =========================
General
-------
Notmuch now requires gmime >= 2.6.7. The gmime 2.4 series is no longer
supported.
Emacs Interface Emacs Interface
--------------- ---------------

49
configure vendored
View file

@ -71,16 +71,6 @@ WITH_BASH=1
WITH_RUBY=1 WITH_RUBY=1
WITH_ZSH=1 WITH_ZSH=1
# Compatible GMime versions (with constraints).
# If using GMime 2.6, we need to have a version >= 2.6.5 to avoid a
# crypto bug. We need 2.6.7 for permissive "From " header handling.
GMIME_24_VERSION_CTR=''
GMIME_24_VERSION="gmime-2.4 $GMIME_24_VERSION_CTR"
GMIME_26_VERSION_CTR='>= 2.6.7'
GMIME_26_VERSION="gmime-2.6 $GMIME_26_VERSION_CTR"
WITH_GMIME_VERSIONS="$GMIME_26_VERSION;$GMIME_24_VERSION"
usage () usage ()
{ {
cat <<EOF cat <<EOF
@ -140,10 +130,6 @@ Fine tuning of some installation directories is available:
--bashcompletiondir=DIR Bash completions files [SYSCONFDIR/bash_completion.d] --bashcompletiondir=DIR Bash completions files [SYSCONFDIR/bash_completion.d]
--zshcompletiondir=DIR Zsh completions files [PREFIX/share/zsh/functions/Completion/Unix] --zshcompletiondir=DIR Zsh completions files [PREFIX/share/zsh/functions/Completion/Unix]
Some specific library versions can be specified (auto-detected otherwise):
--with-gmime-version=VERS Specify GMIME version (2.4 or 2.6)
Some features can be disabled (--with-feature=no is equivalent to Some features can be disabled (--with-feature=no is equivalent to
--without-feature) : --without-feature) :
@ -231,12 +217,6 @@ for option; do
fi fi
elif [ "${option}" = '--without-zsh-completion' ] ; then elif [ "${option}" = '--without-zsh-completion' ] ; then
WITH_ZSH=0 WITH_ZSH=0
elif [ "${option%%=*}" = '--with-gmime-version' ] ; then
if [ "${option#*=}" = '2.4' ]; then
WITH_GMIME_VERSIONS=$GMIME_24_VERSION
elif [ "${option#*=}" = '2.6' ]; then
WITH_GMIME_VERSIONS=$GMIME_26_VERSION
fi
elif [ "${option%%=*}" = '--build' ] ; then elif [ "${option%%=*}" = '--build' ] ; then
true true
elif [ "${option%%=*}" = '--host' ] ; then elif [ "${option%%=*}" = '--host' ] ; then
@ -391,20 +371,19 @@ if [ ${have_xapian} = "1" ]; then
esac esac
fi fi
# we need to have a version >= 2.6.5 to avoid a crypto bug. We need
# 2.6.7 for permissive "From " header handling.
GMIME_MINVER=2.6.7
printf "Checking for GMime development files... " printf "Checking for GMime development files... "
have_gmime=0 if pkg-config --exists "gmime-2.6 >= $GMIME_MINVER"; then
IFS=';' printf "Yes.\n"
for gmimepc in $WITH_GMIME_VERSIONS; do have_gmime=1
if pkg-config --exists $gmimepc; then gmime_cflags=$(pkg-config --cflags gmime-2.6)
printf "Yes ($gmimepc).\n" gmime_ldflags=$(pkg-config --libs gmime-2.6)
have_gmime=1 else
gmime_cflags=$(pkg-config --cflags $gmimepc) have_gmime=0
gmime_ldflags=$(pkg-config --libs $gmimepc)
break
fi
done
IFS=$DEFAULT_IFS
if [ "$have_gmime" = "0" ]; then
printf "No.\n" printf "No.\n"
errors=$((errors + 1)) errors=$((errors + 1))
fi fi
@ -640,7 +619,7 @@ EOF
echo echo
fi fi
if [ $have_gmime -eq 0 ]; then if [ $have_gmime -eq 0 ]; then
echo " Either GMime 2.4 library" $GMIME_24_VERSION_CTR "or GMime 2.6 library" $GMIME_26_VERSION_CTR echo " GMime 2.6 library >= $GMIME_MINVER"
echo " (including development files such as headers)" echo " (including development files such as headers)"
echo " http://spruce.sourceforge.net/gmime/" echo " http://spruce.sourceforge.net/gmime/"
echo echo
@ -1026,7 +1005,7 @@ LINKER_RESOLVES_LIBRARY_DEPENDENCIES = ${linker_resolves_library_dependencies}
XAPIAN_CXXFLAGS = ${xapian_cxxflags} XAPIAN_CXXFLAGS = ${xapian_cxxflags}
XAPIAN_LDFLAGS = ${xapian_ldflags} XAPIAN_LDFLAGS = ${xapian_ldflags}
# Flags needed to compile and link against GMime-2.4 # Flags needed to compile and link against GMime
GMIME_CFLAGS = ${gmime_cflags} GMIME_CFLAGS = ${gmime_cflags}
GMIME_LDFLAGS = ${gmime_ldflags} GMIME_LDFLAGS = ${gmime_ldflags}

View file

@ -20,8 +20,6 @@
#include "notmuch-client.h" #include "notmuch-client.h"
#ifdef GMIME_ATLEAST_26
/* Create a GPG context (GMime 2.6) */ /* Create a GPG context (GMime 2.6) */
static notmuch_crypto_context_t * static notmuch_crypto_context_t *
create_gpg_context (const char *gpgpath) create_gpg_context (const char *gpgpath)
@ -39,29 +37,6 @@ create_gpg_context (const char *gpgpath)
return gpgctx; return gpgctx;
} }
#else /* GMIME_ATLEAST_26 */
/* Create a GPG context (GMime 2.4) */
static notmuch_crypto_context_t *
create_gpg_context (const char* gpgpath)
{
GMimeSession *session;
notmuch_crypto_context_t *gpgctx;
session = g_object_new (g_mime_session_get_type (), NULL);
gpgctx = g_mime_gpg_context_new (session, gpgpath ? gpgpath : "gpg");
g_object_unref (session);
if (! gpgctx)
return NULL;
g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) gpgctx, FALSE);
return gpgctx;
}
#endif /* GMIME_ATLEAST_26 */
/* for the specified protocol return the context pointer (initializing /* for the specified protocol return the context pointer (initializing
* if needed) */ * if needed) */
notmuch_crypto_context_t * notmuch_crypto_context_t *

View file

@ -129,8 +129,6 @@ DONE:
return status; return status;
} }
#ifdef GMIME_ATLEAST_26
/* Signature list destructor (GMime 2.6) */ /* Signature list destructor (GMime 2.6) */
static int static int
_signature_list_free (GMimeSignatureList **proxy) _signature_list_free (GMimeSignatureList **proxy)
@ -205,87 +203,6 @@ node_decrypt_and_verify (mime_node_t *node, GMimeObject *part,
g_error_free (err); g_error_free (err);
} }
#else /* GMIME_ATLEAST_26 */
/* Signature validity destructor (GMime 2.4) */
static int
_signature_validity_free (GMimeSignatureValidity **proxy)
{
g_mime_signature_validity_free (*proxy);
return 0;
}
/* Set up signature validity destructor (GMime 2.4) */
static void
set_signature_validity_destructor (mime_node_t *node,
GMimeSignatureValidity *sig_validity)
{
GMimeSignatureValidity **proxy = talloc (node, GMimeSignatureValidity *);
if (proxy) {
*proxy = sig_validity;
talloc_set_destructor (proxy, _signature_validity_free);
}
}
/* Verify a signed mime node (GMime 2.4) */
static void
node_verify (mime_node_t *node, GMimeObject *part,
notmuch_crypto_context_t *cryptoctx)
{
GError *err = NULL;
GMimeSignatureValidity *sig_validity;
node->verify_attempted = TRUE;
sig_validity = g_mime_multipart_signed_verify
(GMIME_MULTIPART_SIGNED (part), cryptoctx, &err);
node->sig_validity = sig_validity;
if (sig_validity) {
set_signature_validity_destructor (node, sig_validity);
} else {
fprintf (stderr, "Failed to verify signed part: %s\n",
err ? err->message : "no error explanation given");
}
if (err)
g_error_free (err);
}
/* Decrypt and optionally verify an encrypted mime node (GMime 2.4) */
static void
node_decrypt_and_verify (mime_node_t *node, GMimeObject *part,
notmuch_crypto_context_t *cryptoctx)
{
GError *err = NULL;
GMimeMultipartEncrypted *encrypteddata = GMIME_MULTIPART_ENCRYPTED (part);
node->decrypt_attempted = TRUE;
node->decrypted_child = g_mime_multipart_encrypted_decrypt
(encrypteddata, cryptoctx, &err);
if (! node->decrypted_child) {
fprintf (stderr, "Failed to decrypt part: %s\n",
err ? err->message : "no error explanation given");
goto DONE;
}
node->decrypt_success = TRUE;
node->verify_attempted = TRUE;
/* The GMimeSignatureValidity returned here is a const, unlike the
* one returned by g_mime_multipart_signed_verify() in
* node_verify() above, so the destructor is not needed.
*/
node->sig_validity = g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
if (! node->sig_validity)
fprintf (stderr, "Failed to verify encrypted signed part: %s\n",
err ? err->message : "no error explanation given");
DONE:
if (err)
g_error_free (err);
}
#endif /* GMIME_ATLEAST_26 */
static mime_node_t * static mime_node_t *
_mime_node_create (mime_node_t *parent, GMimeObject *part) _mime_node_create (mime_node_t *parent, GMimeObject *part)
{ {

View file

@ -30,16 +30,7 @@
#include <gmime/gmime.h> #include <gmime/gmime.h>
/* GMIME_CHECK_VERSION in gmime 2.4 is not usable from the
* preprocessor (it calls a runtime function). But since
* GMIME_MAJOR_VERSION and friends were added in gmime 2.6, we can use
* these to check the version number. */
#ifdef GMIME_MAJOR_VERSION
#define GMIME_ATLEAST_26
typedef GMimeCryptoContext notmuch_crypto_context_t; typedef GMimeCryptoContext notmuch_crypto_context_t;
#else
typedef GMimeCipherContext notmuch_crypto_context_t;
#endif
#include "notmuch.h" #include "notmuch.h"
@ -394,17 +385,10 @@ struct mime_node {
/* True if signature verification on this part was attempted. */ /* True if signature verification on this part was attempted. */
notmuch_bool_t verify_attempted; notmuch_bool_t verify_attempted;
#ifdef GMIME_ATLEAST_26
/* The list of signatures for signed or encrypted containers. If /* The list of signatures for signed or encrypted containers. If
* there are no signatures, this will be NULL. */ * there are no signatures, this will be NULL. */
GMimeSignatureList* sig_list; GMimeSignatureList* sig_list;
#else
/* For signed or encrypted containers, the validity of the
* signature. May be NULL if signature verification failed. If
* there are simply no signatures, this will be non-NULL with an
* empty signers list. */
const GMimeSignatureValidity *sig_validity;
#endif
/* Internal: Context inherited from the root iterator. */ /* Internal: Context inherited from the root iterator. */
struct mime_node_context *ctx; struct mime_node_context *ctx;

View file

@ -334,8 +334,6 @@ show_text_part_content (GMimeObject *part, GMimeStream *stream_out,
g_object_unref(stream_filter); g_object_unref(stream_filter);
} }
#ifdef GMIME_ATLEAST_26
/* Get signature status string (GMime 2.6) */ /* Get signature status string (GMime 2.6) */
static const char* static const char*
signature_status_to_string (GMimeSignatureStatus x) signature_status_to_string (GMimeSignatureStatus x)
@ -427,91 +425,6 @@ format_part_sigstatus_sprinter (sprinter_t *sp, mime_node_t *node)
sp->end (sp); sp->end (sp);
} }
#else /* GMIME_ATLEAST_26 */
/* Get signature status string (GMime 2.4) */
static const char*
signer_status_to_string (GMimeSignerStatus x)
{
switch (x) {
case GMIME_SIGNER_STATUS_NONE:
return "none";
case GMIME_SIGNER_STATUS_GOOD:
return "good";
case GMIME_SIGNER_STATUS_BAD:
return "bad";
case GMIME_SIGNER_STATUS_ERROR:
return "error";
}
return "unknown";
}
/* Signature status sprinter (GMime 2.4) */
static void
format_part_sigstatus_sprinter (sprinter_t *sp, mime_node_t *node)
{
const GMimeSignatureValidity* validity = node->sig_validity;
sp->begin_list (sp);
if (!validity) {
sp->end (sp);
return;
}
const GMimeSigner *signer = g_mime_signature_validity_get_signers (validity);
while (signer) {
sp->begin_map (sp);
/* status */
sp->map_key (sp, "status");
sp->string (sp, signer_status_to_string (signer->status));
if (signer->status == GMIME_SIGNER_STATUS_GOOD)
{
if (signer->fingerprint) {
sp->map_key (sp, "fingerprint");
sp->string (sp, signer->fingerprint);
}
/* these dates are seconds since the epoch; should we
* provide a more human-readable format string? */
if (signer->created) {
sp->map_key (sp, "created");
sp->integer (sp, signer->created);
}
if (signer->expires) {
sp->map_key (sp, "expires");
sp->integer (sp, signer->expires);
}
/* output user id only if validity is FULL or ULTIMATE. */
/* note that gmime is using the term "trust" here, which
* is WRONG. It's actually user id "validity". */
if ((signer->name) && (signer->trust)) {
if ((signer->trust == GMIME_SIGNER_TRUST_FULLY) || (signer->trust == GMIME_SIGNER_TRUST_ULTIMATE)) {
sp->map_key (sp, "userid");
sp->string (sp, signer->name);
}
}
} else {
if (signer->keyid) {
sp->map_key (sp, "keyid");
sp->string (sp, signer->keyid);
}
}
if (signer->errors != GMIME_SIGNER_ERROR_NONE) {
sp->map_key (sp, "errors");
sp->integer (sp, signer->errors);
}
sp->end (sp);
signer = signer->next;
}
sp->end (sp);
}
#endif /* GMIME_ATLEAST_26 */
static notmuch_status_t static notmuch_status_t
format_part_text (const void *ctx, sprinter_t *sp, mime_node_t *node, format_part_text (const void *ctx, sprinter_t *sp, mime_node_t *node,
int indent, const notmuch_show_params_t *params) int indent, const notmuch_show_params_t *params)