url.c ascii.c mutt_idna.c crypt-mod.c crypt-mod.h
mutt_LDADD = @MUTT_LIB_OBJECTS@ @LIBOBJS@ $(LIBIMAP) $(MUTTLIBS) \
- $(INTLLIBS) $(LIBICONV) $(LIBGPGME_LIBS)
+ $(INTLLIBS) $(LIBICONV) $(GPGME_LIBS)
mutt_DEPENDENCIES = @MUTT_LIB_OBJECTS@ @LIBOBJS@ $(LIBIMAPDEPS) \
$(INTLDEPS)
-DBINDIR=\"$(bindir)\" -DMUTTLOCALEDIR=\"$(datadir)/locale\" \
-DHAVE_CONFIG_H=1
-AM_CPPFLAGS=-I. -I$(top_srcdir) $(IMAP_INCLUDES) $(LIBGPGME_CFLAGS) -Iintl
+AM_CPPFLAGS=-I. -I$(top_srcdir) $(IMAP_INCLUDES) $(GPGME_CFLAGS) -Iintl
CPPFLAGS=@CPPFLAGS@ -I$(includedir)
The keys used are:
!: modified feature, -: deleted feature, +: new feature
+ + $crypt_use_pka (use GPGME PKA signature verification)
+
1.5.13 (2006-08-14):
- + thread patterns. Use ~(...) to match all threads that
- contain a message that matches ...
+ + thread patterns. Use ~(...) to match all threads that
+ contain a message that matches ...
1.5.12 (2006-07-14):
OPS='$(srcdir)/OPS'
+AC_MSG_CHECKING([whether to build with GPGME support])
AC_ARG_ENABLE(gpgme, AC_HELP_STRING([--enable-gpgme], [Enable GPGME support]),
[ if test x$enableval = xyes; then
- have_gpgme=yes
+ enable_gpgme=yes
fi
])
-AC_ARG_WITH(gpgme-prefix, AC_HELP_STRING([--with-gpgme-prefix=PFX], [prefix where GPGME is installed (optional)]),
-gpgme_config_prefix="$withval", gpgme_config_prefix="")
-
-if test x$have_gpgme = xyes; then
- if test x$gpgme_config_prefix != x; then
- GPGME_CONFIG="$gpgme_config_prefix/bin/gpgme-config"
- else
- AC_PATH_PROG(GPGME_CONFIG, gpgme-config, no)
- fi
- if test "x$GPGME_CONFIG" = "xno"; then
- AC_MSG_ERROR([GPGME not found])
- else
- LIBGPGME_CFLAGS=`$GPGME_CONFIG --cflags`
- LIBGPGME_LIBS=`$GPGME_CONFIG --libs`
- MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS crypt-gpgme.o crypt-mod-pgp-gpgme.o crypt-mod-smime-gpgme.o"
- AC_DEFINE(CRYPT_BACKEND_GPGME, 1, [Defined, if GPGME support is enabled])
- fi
+
+if test x"$enable_gpgme" = xyes; then
+ AC_MSG_RESULT(yes)
+ AM_PATH_GPGME(1.0.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 ***])
+ 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]))
+ MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS crypt-gpgme.o crypt-mod-pgp-gpgme.o crypt-mod-smime-gpgme.o"
+ fi
+else
+ AC_MSG_RESULT([no])
fi
-AC_SUBST(LIBGPGME_CFLAGS)
-AC_SUBST(LIBGPGME_LIBS)
AC_ARG_ENABLE(pgp, AC_HELP_STRING([--disable-pgp], [Disable PGP support]),
[ if test x$enableval = xno ; then
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+#define PKA_NOTATION_NAME "pka-address@gnupg.org"
+#define is_pka_notation(notation) (! strcmp ((notation)->name, \
+ PKA_NOTATION_NAME))
+
/* Values used for comparing addresses. */
#define CRYPT_KV_VALID 1
#define CRYPT_KV_ADDR 2
static struct crypt_cache *id_defaults = NULL;
static gpgme_key_t signature_key = NULL;
+static char *current_sender = NULL;
+
/*
* General helper functions.
return 0;
}
+static gpgme_error_t
+set_pka_sig_notation (gpgme_ctx_t ctx)
+{
+ gpgme_error_t err;
+
+ err = gpgme_sig_notation_add (ctx,
+ PKA_NOTATION_NAME, current_sender, 0);
+
+ if (err)
+ {
+ mutt_error (_("error setting PKA signature notation: %s\n"),
+ gpgme_strerror (err));
+ mutt_sleep (2);
+ }
+
+ return err;
+}
/* Encrypt the gpgme data object PLAINTEXT to the recipients in RSET
and return an allocated filename to a temporary file containing the
static char *encrypt_gpgme_object (gpgme_data_t plaintext, gpgme_key_t *rset,
int use_smime, int combined_signed)
{
- int err;
+ gpgme_error_t err;
gpgme_ctx_t ctx;
gpgme_data_t ciphertext;
char *outfile;
gpgme_release (ctx);
return NULL;
}
+
+ if (option (OPTCRYPTUSEPKA))
+ {
+ err = set_pka_sig_notation (ctx);
+ if (err)
+ {
+ gpgme_data_release (ciphertext);
+ gpgme_release (ctx);
+ return NULL;
+ }
+ }
+
err = gpgme_op_encrypt_sign (ctx, rset, GPGME_ENCRYPT_ALWAYS_TRUST,
plaintext, ciphertext);
}
return NULL;
}
+ if (option (OPTCRYPTUSEPKA))
+ {
+ err = set_pka_sig_notation (ctx);
+ if (err)
+ {
+ gpgme_data_release (signature);
+ gpgme_data_release (message);
+ gpgme_release (ctx);
+ return NULL;
+ }
+ }
+
err = gpgme_op_sign (ctx, message, signature, GPGME_SIG_MODE_DETACH );
mutt_need_hard_redraw ();
gpgme_data_release (message);
*/
static int show_sig_summary (unsigned long sum,
gpgme_ctx_t ctx, gpgme_key_t key, int idx,
- STATE *s)
+ STATE *s, gpgme_signature_t sig)
{
int severe = 0;
state_attach_puts ("\n", s);
}
+#ifdef HAVE_GPGME_PKA_TRUST
+
+ if (option (OPTCRYPTUSEPKA))
+ {
+ if (sig->pka_trust == 1 && sig->pka_address)
+ {
+ state_attach_puts (_("WARNING: PKA entry does not match "
+ "signer's address: "), s);
+ state_attach_puts (sig->pka_address, s);
+ state_attach_puts ("\n", s);
+ }
+ else if (sig->pka_trust == 2 && sig->pka_address)
+ {
+ state_attach_puts (_("PKA verified signer's address is: "), s);
+ state_attach_puts (sig->pka_address, s);
+ state_attach_puts ("\n", s);
+ }
+ }
+
+#endif
+
return severe;
}
state_attach_puts (_(" created: "), s);
print_time (created, s);
state_attach_puts ("\n", s);
- if (show_sig_summary (sum, ctx, key, idx, s))
+ if (show_sig_summary (sum, ctx, key, idx, s, sig))
anywarn = 1;
show_one_sig_validity (ctx, idx, s);
}
state_attach_puts (_("*BAD* signature claimed to be from: "), s);
state_attach_puts (uid, s);
state_attach_puts ("\n", s);
- show_sig_summary (sum, ctx, key, idx, s);
+ show_sig_summary (sum, ctx, key, idx, s, sig);
}
else if (!anybad && key && (key->protocol == GPGME_PROTOCOL_OpenPGP))
{ /* We can't decide (yellow) but this is a PGP key with a good
state_attach_puts ("\n", s);
show_one_sig_validity (ctx, idx, s);
show_fingerprint (key,s);
- if (show_sig_summary (sum, ctx, key, idx, s))
+ if (show_sig_summary (sum, ctx, key, idx, s, sig))
anywarn = 1;
}
else /* can't decide (yellow) */
{
state_attach_puts (_("Error checking signature"), s);
state_attach_puts ("\n", s);
- show_sig_summary (sum, ctx, key, idx, s);
+ show_sig_summary (sum, ctx, key, idx, s, sig);
}
if (key != signature_key)
gpgme_verify_result_t result;
gpgme_sig_notation_t notation;
gpgme_signature_t signature;
+ int non_pka_notations;
result = gpgme_op_verify_result (ctx);
if (result)
for (signature = result->signatures; signature;
signature = signature->next)
{
- if (signature->notations)
+ non_pka_notations = 0;
+ for (notation = signature->notations; notation;
+ notation = notation->next)
+ if (! is_pka_notation (notation))
+ non_pka_notations++;
+
+ if (non_pka_notations)
{
char buf[SHORT_STRING];
snprintf (buf, sizeof (buf),
for (notation = signature->notations; notation;
notation = notation->next)
{
+ if (is_pka_notation (notation))
+ continue;
+
if (notation->name)
{
state_attach_puts (notation->name, s);
return verify_sender (h, GPGME_PROTOCOL_CMS);
}
+void gpgme_set_sender (const char *sender)
+{
+ mutt_error ("[setting sender] mailbox: %s\n", sender);
+ FREE (¤t_sender);
+ current_sender = safe_strdup (sender);
+}
+
+
#endif
int smime_gpgme_send_menu (HEADER *msg, int *redraw);
int smime_gpgme_verify_sender (HEADER *h);
+
+void gpgme_set_sender (const char *sender);
+
#endif
crypt_mod_pgp_sign_message,
crypt_mod_pgp_verify_one,
crypt_mod_pgp_send_menu,
+ NULL,
crypt_mod_pgp_encrypt_message,
crypt_mod_pgp_make_key_attachment,
return pgp_gpgme_encrypt_message (a, keylist, sign);
}
+static void crypt_mod_pgp_set_sender (const char *sender)
+{
+ gpgme_set_sender (sender);
+}
+
struct crypt_module_specs crypt_mod_pgp_gpgme =
{ APPLICATION_PGP,
{
crypt_mod_pgp_sign_message,
crypt_mod_pgp_verify_one,
crypt_mod_pgp_send_menu,
+ crypt_mod_pgp_set_sender,
/* PGP specific. */
crypt_mod_pgp_encrypt_message,
crypt_mod_smime_sign_message,
crypt_mod_smime_verify_one,
crypt_mod_smime_send_menu,
+ NULL,
NULL, /* pgp_encrypt_message */
NULL, /* pgp_make_key_attachment */
crypt_mod_smime_sign_message,
crypt_mod_smime_verify_one,
crypt_mod_smime_send_menu,
+ NULL,
NULL, /* pgp_encrypt_message */
NULL, /* pgp_make_key_attachment */
typedef void (*crypt_func_init_t) (void);
+typedef void (*crypt_func_set_sender_t) (const char *sender);
/*
A structure to keep all crypto module fucntions together.
crypt_func_sign_message_t sign_message;
crypt_func_verify_one_t verify_one;
crypt_func_send_menu_t send_menu;
+ crypt_func_set_sender_t set_sender;
/* PGP specific functions. */
crypt_func_pgp_encrypt_message_t pgp_encrypt_message;
if ((WithCrypto & APPLICATION_PGP))
tmp_pgp_pbody = msg->content;
+ if (option (OPTCRYPTUSEPKA) && (msg->security & SIGN))
+ {
+ /* Set sender (necessary for e.g. PKA). */
+
+ if ((WithCrypto & APPLICATION_SMIME)
+ && (msg->security & APPLICATION_SMIME))
+ crypt_smime_set_sender (msg->env->from->mailbox);
+ else if ((WithCrypto & APPLICATION_PGP)
+ && (msg->security & APPLICATION_PGP))
+ crypt_pgp_set_sender (msg->env->from->mailbox);
+ }
+
if (msg->security & SIGN)
{
if ((WithCrypto & APPLICATION_SMIME)
(CRYPT_MOD_CALL (PGP, pgp_extract_keys_from_attachment_list)) (fp, tag, top);
}
+void crypt_pgp_set_sender (const char *sender)
+{
+ if (CRYPT_MOD_CALL_CHECK (PGP, set_sender))
+ (CRYPT_MOD_CALL (PGP, set_sender)) (sender);
+}
+
\f
+
/*
S/MIME
return 0;
}
+
+void crypt_smime_set_sender (const char *sender)
+{
+ if (CRYPT_MOD_CALL_CHECK (SMIME, set_sender))
+ (CRYPT_MOD_CALL (SMIME, set_sender)) (sender);
+}
{ "crypt_use_gpgme", DT_BOOL, R_NONE, OPTCRYPTUSEGPGME, 0 },
/*
** .pp
- ** This variable controls the use the GPGME enabled crypto backends.
- ** If it is set and Mutt was build with gpgme support, the gpgme code for
- ** S/MIME and PGP will be used instead of the classic code. Note, that
- ** you need to use this option in .muttrc as it won't have any effect when
+ ** This variable controls the use of the GPGME-enabled crypto backends.
+ ** If it is set and Mutt was built with gpgme support, the gpgme code for
+ ** S/MIME and PGP will be used instead of the classic code. Note that
+ ** you need to set this option in .muttrc; it won't have any effect when
** used interactively.
*/
-
+ { "crypt_use_pka", DT_BOOL, R_NONE, OPTCRYPTUSEPKA, 0 },
+ /*
+ ** .pp Controls whether mutt uses PKA
+ ** (http://www.g10code.de/docs/pka-intro.de.pdf) during signature
+ ** verification (only supported by the GPGME backend).
+ */
+
{ "crypt_autopgp", DT_BOOL, R_NONE, OPTCRYPTAUTOPGP, 1 },
/*
** .pp
OPTXMAILER,
OPTCRYPTUSEGPGME,
+ OPTCRYPTUSEPKA,
/* PGP options */
/* fixme: needs documentation */
void crypt_pgp_extract_keys_from_attachment_list (FILE *fp, int tag,BODY *top);
-
+void crypt_pgp_set_sender (const char *sender);
int crypt_smime_send_menu (HEADER *msg, int *redraw);
+void crypt_smime_set_sender (const char *sender);
+
/* fixme: needs documentation */
int crypt_smime_verify_one (BODY *sigbdy, STATE *s, const char *tempf);