mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-12-22 09:24:54 +01:00
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:
parent
cb08a2ee01
commit
005c2f0df1
7 changed files with 24 additions and 250 deletions
6
INSTALL
6
INSTALL
|
@ -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
6
NEWS
|
@ -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
49
configure
vendored
|
@ -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}
|
||||||
|
|
||||||
|
|
25
crypto.c
25
crypto.c
|
@ -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 *
|
||||||
|
|
83
mime-node.c
83
mime-node.c
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue