Change crypt_get_keys() to query autocrypt.
When oppenc_mode is set, we still query the original keyring
regardless, because the compose menu can still run oppenc even if
autocrypt is on.
Since mutt_autocrypt_ui_recommendation() checks each key as part of
making the recommendation, add a keylist parameter and use that
function.
Add gpgme changes to use the autocrypt context for encryption.
Postpone work:
* Change mutt_protect() to have a postpone parameter. Remove the
manual toggling of the SIGN bit outside the call when postponing.
* Since autocrypt doesn't set the SIGN bit, this allows us to turn off
signing inside mutt_protect() for both normal and autocrypt mode.
* Set the autocrypt postpone key in AutocryptDefaultKey.
Write autocrypt and gossip headers in outgoing emails.
return rv;
}
-autocrypt_rec_t mutt_autocrypt_ui_recommendation (HEADER *hdr)
+/* Returns the recommendation. If the recommendataion is > NO and
+ * keylist is not NULL, keylist will be populated with the autocrypt
+ * keyids
+ */
+autocrypt_rec_t mutt_autocrypt_ui_recommendation (HEADER *hdr, char **keylist)
{
autocrypt_rec_t rv = AUTOCRYPT_REC_OFF;
AUTOCRYPT_ACCOUNT *account = NULL;
AUTOCRYPT_PEER *peer = NULL;
ADDRESS *recip, *recips = NULL, *last = NULL;
int all_encrypt = 1, has_discourage = 0;
+ BUFFER *keylist_buf = NULL;
+ const char *matching_key;
if (!option (OPTAUTOCRYPT) ||
mutt_autocrypt_init (0) ||
if (mutt_autocrypt_db_account_get (hdr->env->from, &account) <= 0)
goto cleanup;
+ keylist_buf = mutt_buffer_pool_get ();
+ mutt_buffer_addstr (keylist_buf, account->keyid);
+
last = rfc822_append (&recips, hdr->env->to, 0);
last = rfc822_append (last ? &last : &recips, hdr->env->cc, 0);
rfc822_append (last ? &last : &recips, hdr->env->bcc, 0);
if (mutt_autocrypt_gpgme_is_valid_key (peer->keyid))
{
+ matching_key = peer->keyid;
+
if (!(peer->last_seen && peer->autocrypt_timestamp) ||
(peer->last_seen - peer->autocrypt_timestamp > 35 * 24 * 60 * 60))
{
}
else if (mutt_autocrypt_gpgme_is_valid_key (peer->gossip_keyid))
{
+ matching_key = peer->gossip_keyid;
+
has_discourage = 1;
all_encrypt = 0;
}
else
goto cleanup;
+ if (mutt_buffer_len (keylist_buf))
+ mutt_buffer_addch (keylist_buf, ' ');
+ mutt_buffer_addstr (keylist_buf, matching_key);
+
mutt_autocrypt_db_peer_free (&peer);
}
else
rv = AUTOCRYPT_REC_AVAILABLE;
+ if (keylist)
+ mutt_str_replace (keylist, mutt_b2s (keylist_buf));
+
cleanup:
mutt_autocrypt_db_account_free (&account);
rfc822_free_address (&recips);
mutt_autocrypt_db_peer_free (&peer);
+ mutt_buffer_pool_release (&keylist_buf);
+ return rv;
+}
+
+int mutt_autocrypt_set_sign_as_default_key (HEADER *hdr)
+{
+ int rv = -1;
+ AUTOCRYPT_ACCOUNT *account = NULL;
+
+ if (!option (OPTAUTOCRYPT) ||
+ mutt_autocrypt_init (0) ||
+ !hdr ||
+ !hdr->env->from ||
+ hdr->env->from->next)
+ return -1;
+
+ if (mutt_autocrypt_db_account_get (hdr->env->from, &account) <= 0)
+ goto cleanup;
+ if (!account->keyid)
+ goto cleanup;
+
+ mutt_str_replace (&AutocryptSignAs, account->keyid);
+ mutt_str_replace (&AutocryptDefaultKey, account->keyid);
+
+ rv = 0;
+
+cleanup:
+ mutt_autocrypt_db_account_free (&account);
+ return rv;
+}
+
+
+static void write_autocrypt_header_line (FILE *fp, const char *addr,
+ int prefer_encrypt,
+ const char *keydata)
+{
+ int count = 0;
+
+ fprintf (fp, "addr=%s; ", addr);
+ if (prefer_encrypt)
+ fputs ("prefer-encrypt=mutual; ", fp);
+ fputs ("keydata=\n", fp);
+
+ while (*keydata)
+ {
+ count = 0;
+ fputs ("\t", fp);
+ while (*keydata && count < 75)
+ {
+ fputc (*keydata, fp);
+ count++;
+ keydata++;
+ }
+ fputs ("\n", fp);
+ }
+}
+
+int mutt_autocrypt_write_autocrypt_header (ENVELOPE *env, FILE *fp)
+{
+ int rv = -1;
+ AUTOCRYPT_ACCOUNT *account = NULL;
+
+ if (!option (OPTAUTOCRYPT) ||
+ mutt_autocrypt_init (0) ||
+ !env ||
+ !env->from ||
+ env->from->next)
+ return -1;
+
+ if (mutt_autocrypt_db_account_get (env->from, &account) <= 0)
+ goto cleanup;
+ if (!account->keydata)
+ goto cleanup;
+
+ fputs ("Autocrypt: ", fp);
+ write_autocrypt_header_line (fp, account->email_addr, account->prefer_encrypt,
+ account->keydata);
+
+ rv = 0;
+
+cleanup:
+ mutt_autocrypt_db_account_free (&account);
+ return rv;
+}
+
+int mutt_autocrypt_write_gossip_headers (ENVELOPE *env, FILE *fp)
+{
+ AUTOCRYPTHDR *gossip;
+
+ if (!option (OPTAUTOCRYPT) ||
+ mutt_autocrypt_init (0) ||
+ !env)
+ return -1;
+
+ for (gossip = env->autocrypt_gossip; gossip; gossip = gossip->next)
+ {
+ fputs ("Autocrypt-Gossip: ", fp);
+ write_autocrypt_header_line (fp, gossip->addr, 0, gossip->keydata);
+ }
+
+ return 0;
+}
+
+int mutt_autocrypt_generate_gossip_list (HEADER *hdr)
+{
+ int rv = -1;
+ AUTOCRYPT_PEER *peer = NULL;
+ AUTOCRYPT_ACCOUNT *account = NULL;
+ ADDRESS *recip, *recips = NULL, *last = NULL;
+ AUTOCRYPTHDR *gossip;
+ const char *keydata, *addr;
+ ENVELOPE *mime_headers;
+
+ if (!option (OPTAUTOCRYPT) ||
+ mutt_autocrypt_init (0) ||
+ !hdr)
+ return -1;
+
+ mime_headers = hdr->content->mime_headers;
+ if (!mime_headers)
+ mime_headers = hdr->content->mime_headers = mutt_new_envelope ();
+ mutt_free_autocrypthdr (&mime_headers->autocrypt_gossip);
+
+ last = rfc822_append (&recips, hdr->env->to, 0);
+ last = rfc822_append (last ? &last : &recips, hdr->env->cc, 0);
+
+ for (recip = recips; recip; recip = recip->next)
+ {
+ /* At this point, we just accept missing keys and include what
+ * we can. */
+ if (mutt_autocrypt_db_peer_get (recip, &peer) <= 0)
+ continue;
+
+ keydata = NULL;
+ if (mutt_autocrypt_gpgme_is_valid_key (peer->keyid))
+ keydata = peer->keydata;
+ else if (mutt_autocrypt_gpgme_is_valid_key (peer->gossip_keyid))
+ keydata = peer->gossip_keydata;
+
+ if (keydata)
+ {
+ gossip = mutt_new_autocrypthdr ();
+ gossip->addr = safe_strdup (peer->email_addr);
+ gossip->keydata = safe_strdup (keydata);
+ gossip->next = mime_headers->autocrypt_gossip;
+ mime_headers->autocrypt_gossip = gossip;
+ }
+
+ mutt_autocrypt_db_peer_free (&peer);
+ }
+
+ for (recip = hdr->env->reply_to; recip; recip = recip->next)
+ {
+ addr = keydata = NULL;
+ if (mutt_autocrypt_db_account_get (recip, &account) > 0)
+ {
+ addr = account->email_addr;
+ keydata = account->keydata;
+ }
+ else if (mutt_autocrypt_db_peer_get (recip, &peer) > 0)
+ {
+ addr = peer->email_addr;
+ if (mutt_autocrypt_gpgme_is_valid_key (peer->keyid))
+ keydata = peer->keydata;
+ else if (mutt_autocrypt_gpgme_is_valid_key (peer->gossip_keyid))
+ keydata = peer->gossip_keydata;
+ }
+
+ if (keydata)
+ {
+ gossip = mutt_new_autocrypthdr ();
+ gossip->addr = safe_strdup (addr);
+ gossip->keydata = safe_strdup (keydata);
+ gossip->next = mime_headers->autocrypt_gossip;
+ mime_headers->autocrypt_gossip = gossip;
+ }
+ mutt_autocrypt_db_account_free (&account);
+ mutt_autocrypt_db_peer_free (&peer);
+ }
+
+ rfc822_free_address (&recips);
+ mutt_autocrypt_db_account_free (&account);
+ mutt_autocrypt_db_peer_free (&peer);
return rv;
}
void mutt_autocrypt_cleanup (void);
int mutt_autocrypt_process_autocrypt_header (HEADER *hdr, ENVELOPE *env);
int mutt_autocrypt_process_gossip_header (HEADER *hdr, ENVELOPE *env);
-autocrypt_rec_t mutt_autocrypt_ui_recommendation (HEADER *hdr);
+autocrypt_rec_t mutt_autocrypt_ui_recommendation (HEADER *hdr, char **keylist);
+int mutt_autocrypt_set_sign_as_default_key (HEADER *hdr);
+int mutt_autocrypt_write_autocrypt_header (ENVELOPE *env, FILE *fp);
+int mutt_autocrypt_write_gossip_headers (ENVELOPE *env, FILE *fp);
+int mutt_autocrypt_generate_gossip_list (HEADER *hdr);
#endif
{
case 1:
msg->security |= (AUTOCRYPT | AUTOCRYPT_OVERRIDE);
- msg->security &= ~(ENCRYPT | SIGN | OPPENCRYPT);
+ msg->security &= ~(ENCRYPT | SIGN | OPPENCRYPT | INLINE);
break;
case 2:
msg->security &= ~AUTOCRYPT;
#ifdef USE_AUTOCRYPT
mutt_window_move (MuttIndexWindow, HDR_AUTOCRYPT, 0);
mutt_window_clrtoeol (MuttIndexWindow);
- SETCOLOR (MT_COLOR_COMPOSE_HEADER);
- printw ("%*s", HeaderPadding[HDR_AUTOCRYPT], _(Prompts[HDR_AUTOCRYPT]));
- NORMAL_COLOR;
- if (option (OPTAUTOCRYPT) && (msg->security & AUTOCRYPT))
- {
- SETCOLOR (MT_COLOR_COMPOSE_SECURITY_ENCRYPT);
- addstr (_("Encrypt"));
- }
- else
+ if (option (OPTAUTOCRYPT))
{
- SETCOLOR (MT_COLOR_COMPOSE_SECURITY_NONE);
- addstr (_("Off"));
- }
+ SETCOLOR (MT_COLOR_COMPOSE_HEADER);
+ printw ("%*s", HeaderPadding[HDR_AUTOCRYPT], _(Prompts[HDR_AUTOCRYPT]));
+ NORMAL_COLOR;
+ if (msg->security & AUTOCRYPT)
+ {
+ SETCOLOR (MT_COLOR_COMPOSE_SECURITY_ENCRYPT);
+ addstr (_("Encrypt"));
+ }
+ else
+ {
+ SETCOLOR (MT_COLOR_COMPOSE_SECURITY_NONE);
+ addstr (_("Off"));
+ }
- SETCOLOR (MT_COLOR_COMPOSE_HEADER);
- mutt_window_mvprintw (MuttIndexWindow, HDR_AUTOCRYPT, 40, "%s",
- _("Recommendation: "));
- NORMAL_COLOR;
- printw ("%s", _(AutocryptRecUiFlags[rd->autocrypt_rec]));
+ SETCOLOR (MT_COLOR_COMPOSE_HEADER);
+ mutt_window_mvprintw (MuttIndexWindow, HDR_AUTOCRYPT, 40, "%s",
+ _("Recommendation: "));
+ NORMAL_COLOR;
+ printw ("%s", _(AutocryptRecUiFlags[rd->autocrypt_rec]));
+ }
#endif
}
crypt_opportunistic_encrypt (msg);
#ifdef USE_AUTOCRYPT
- rd->autocrypt_rec = mutt_autocrypt_ui_recommendation (msg);
-
- /* Anything that enables ENCRYPT or SIGN, or turns on SMIME
- * overrides autocrypt, be it oppenc or the user having turned on
- * those flags manually. */
- if (msg->security & (ENCRYPT | SIGN | APPLICATION_SMIME))
- msg->security &= ~(AUTOCRYPT | AUTOCRYPT_OVERRIDE);
- else
+ if (option (OPTAUTOCRYPT))
{
- if (!(msg->security & AUTOCRYPT_OVERRIDE))
+ rd->autocrypt_rec = mutt_autocrypt_ui_recommendation (msg, NULL);
+
+ /* Anything that enables ENCRYPT or SIGN, or turns on SMIME
+ * overrides autocrypt, be it oppenc or the user having turned on
+ * those flags manually. */
+ if (msg->security & (ENCRYPT | SIGN | APPLICATION_SMIME))
+ msg->security &= ~(AUTOCRYPT | AUTOCRYPT_OVERRIDE);
+ else
{
- if (rd->autocrypt_rec == AUTOCRYPT_REC_YES)
- msg->security |= AUTOCRYPT;
- else
- msg->security &= ~AUTOCRYPT;
+ if (!(msg->security & AUTOCRYPT_OVERRIDE))
+ {
+ if (rd->autocrypt_rec == AUTOCRYPT_REC_YES)
+ {
+ msg->security |= AUTOCRYPT;
+ msg->security &= ~INLINE;
+ }
+ else
+ msg->security &= ~AUTOCRYPT;
+ }
}
}
- /* TODO:
- * - autocrypt menu for manually enabling/disabling (turns on override)
- * - deal with pgp and smime menu and their effects on security->AUTOCRYPT
- * when encryption or signing is enabled or if switch to smime mode
- */
#endif
redraw_crypt_lines (rd);
#ifdef USE_AUTOCRYPT
case OP_COMPOSE_AUTOCRYPT_MENU:
+ if (!option (OPTAUTOCRYPT))
+ break;
+
if ((WithCrypto & APPLICATION_SMIME)
&& (msg->security & APPLICATION_SMIME))
{
}
}
+#ifdef USE_AUTOCRYPT
+ /* This is a fail-safe to make sure the bit isn't somehow turned
+ * on. The user could have disabled the option after setting AUTOCRYPT,
+ * or perhaps resuming or replying to an autocrypt message.
+ */
+ if (!option (OPTAUTOCRYPT))
+ msg->security &= ~AUTOCRYPT;
+#endif
+
mutt_pop_current_menu (menu);
mutt_menuDestroy (&menu);
gpgme_ctx_t ctx;
err = gpgme_new (&ctx);
+
+#ifdef USE_AUTOCRYPT
+ if (!err && option (OPTAUTOCRYPTGPGME))
+ err = gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_OpenPGP, NULL,
+ AutocryptDir);
+#endif
+
if (err)
{
mutt_error (_("error creating gpgme context: %s\n"), gpgme_strerror (err));
if (for_smime)
signid = SmimeSignAs ? SmimeSignAs : SmimeDefaultKey;
+#ifdef USE_AUTOCRYPT
+ else if (option (OPTAUTOCRYPTGPGME))
+ signid = AutocryptSignAs;
+#endif
else
signid = PgpSignAs ? PgpSignAs : PgpDefaultKey;
#include "copy.h"
#include "mutt_crypt.h"
+#ifdef USE_AUTOCRYPT
+#include "autocrypt.h"
+#endif
+
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
}
-
-int mutt_protect (HEADER *msg, char *keylist)
+/* In postpone mode, signing is automatically disabled. */
+int mutt_protect (HEADER *msg, char *keylist, int postpone)
{
BODY *pbody = NULL, *tmp_pbody = NULL;
BODY *tmp_smime_pbody = NULL;
BODY *tmp_pgp_pbody = NULL;
ENVELOPE *protected_headers = NULL;
- int flags = (WithCrypto & APPLICATION_PGP)? msg->security: 0;
+ int security, sign, has_retainable_sig = 0;
int i;
if (!WithCrypto)
return -1;
- if (!(msg->security & (ENCRYPT | SIGN)))
+ security = msg->security;
+ sign = security & (AUTOCRYPT | SIGN);
+ if (postpone)
+ {
+ sign = 0;
+ security &= ~SIGN;
+ }
+
+ if (!(security & (ENCRYPT | AUTOCRYPT)) && !sign)
return 0;
- if ((msg->security & SIGN) && !crypt_valid_passphrase (msg->security))
+ if (sign &&
+ !(security & AUTOCRYPT) &&
+ !crypt_valid_passphrase (security))
return (-1);
- if ((WithCrypto & APPLICATION_PGP) && ((msg->security & PGPINLINE) == PGPINLINE))
+ if ((WithCrypto & APPLICATION_PGP) &&
+ !(security & AUTOCRYPT) &&
+ ((security & PGPINLINE) == PGPINLINE))
{
if ((msg->content->type != TYPETEXT) ||
ascii_strcasecmp (msg->content->subtype, "plain"))
{
/* they really want to send it inline... go for it */
if (!isendwin ()) mutt_endwin _("Invoking PGP...");
- pbody = crypt_pgp_traditional_encryptsign (msg->content, flags, keylist);
+ pbody = crypt_pgp_traditional_encryptsign (msg->content, security, keylist);
if (pbody)
{
msg->content = pbody;
if ((WithCrypto & APPLICATION_PGP))
tmp_pgp_pbody = msg->content;
- if (option (OPTCRYPTUSEPKA) && (msg->security & SIGN))
+ if (option (OPTCRYPTUSEPKA) && sign)
{
/* Set sender (necessary for e.g. PKA). */
if ((WithCrypto & APPLICATION_SMIME)
- && (msg->security & APPLICATION_SMIME))
+ && (security & APPLICATION_SMIME))
crypt_smime_set_sender (msg->env->from->mailbox);
else if ((WithCrypto & APPLICATION_PGP)
- && (msg->security & APPLICATION_PGP))
+ && (security & APPLICATION_PGP))
crypt_pgp_set_sender (msg->env->from->mailbox);
}
msg->content->mime_headers = protected_headers;
}
- if (msg->security & SIGN)
+ /* A note about msg->content->mime_headers. If postpone or send
+ * fails, the mime_headers is cleared out before returning to the
+ * compose menu. So despite the "robustness" code above and in the
+ * gen_gossip_list function below, mime_headers will not be set when
+ * entering mutt_protect().
+ *
+ * This is important to note because the user could toggle
+ * $crypt_protected_headers_write or $autocrypt off back in the
+ * compose menu. We don't want mutt_write_rfc822_header() to write
+ * stale data from one option if the other is set.
+ */
+#ifdef USE_AUTOCRYPT
+ if (option (OPTAUTOCRYPT) &&
+ !postpone &&
+ (security & AUTOCRYPT))
+ {
+ mutt_autocrypt_generate_gossip_list (msg);
+ }
+#endif
+
+ if (sign)
{
if ((WithCrypto & APPLICATION_SMIME)
- && (msg->security & APPLICATION_SMIME))
+ && (security & APPLICATION_SMIME))
{
if (!(tmp_pbody = crypt_smime_sign_message (msg->content)))
goto bail;
}
if ((WithCrypto & APPLICATION_PGP)
- && (msg->security & APPLICATION_PGP)
- && (!(flags & ENCRYPT) || option (OPTPGPRETAINABLESIG)))
+ && (security & APPLICATION_PGP)
+ && (!(security & (ENCRYPT | AUTOCRYPT)) || option (OPTPGPRETAINABLESIG)))
{
if (!(tmp_pbody = crypt_pgp_sign_message (msg->content)))
goto bail;
- flags &= ~SIGN;
+ has_retainable_sig = 1;
+ sign = 0;
pbody = tmp_pgp_pbody = tmp_pbody;
}
if (WithCrypto
- && (msg->security & APPLICATION_SMIME)
- && (msg->security & APPLICATION_PGP))
+ && (security & APPLICATION_SMIME)
+ && (security & APPLICATION_PGP))
{
/* here comes the draft ;-) */
}
}
- if (msg->security & ENCRYPT)
+ if (security & (ENCRYPT | AUTOCRYPT))
{
if ((WithCrypto & APPLICATION_SMIME)
- && (msg->security & APPLICATION_SMIME))
+ && (security & APPLICATION_SMIME))
{
if (!(tmp_pbody = crypt_smime_build_smime_entity (tmp_smime_pbody,
keylist)))
}
if ((WithCrypto & APPLICATION_PGP)
- && (msg->security & APPLICATION_PGP))
+ && (security & APPLICATION_PGP))
{
- if (!(pbody = crypt_pgp_encrypt_message (tmp_pgp_pbody, keylist,
- flags & SIGN)))
+ if (!(pbody = crypt_pgp_encrypt_message (msg, tmp_pgp_pbody, keylist,
+ sign)))
{
/* did we perform a retainable signature? */
- if (flags != msg->security)
+ if (has_retainable_sig)
{
/* remove the outer multipart layer */
tmp_pgp_pbody = mutt_remove_multipart (tmp_pgp_pbody);
* signatures.
*/
- if (flags != msg->security)
+ if (has_retainable_sig)
{
tmp_pgp_pbody = mutt_remove_multipart (tmp_pgp_pbody);
mutt_free_body (&tmp_pgp_pbody->next);
if (!WithCrypto)
return 0;
+ *keylist = NULL;
+
+#ifdef USE_AUTOCRYPT
+ if (!oppenc_mode && (msg->security & AUTOCRYPT))
+ {
+ if (mutt_autocrypt_ui_recommendation (msg, keylist) <= AUTOCRYPT_REC_NO)
+ return (-1);
+ return (0);
+ }
+#endif
+
if ((WithCrypto & APPLICATION_PGP))
set_option (OPTPGPCHECKTRUST);
rfc822_qualify (adrlist, fqdn);
adrlist = mutt_remove_duplicates (adrlist);
- *keylist = NULL;
-
if (oppenc_mode || (msg->security & ENCRYPT))
{
if ((WithCrypto & APPLICATION_PGP)
#include "crypt-mod.h"
+#ifdef USE_AUTOCRYPT
+#include "autocrypt.h"
+#endif
+
/*
Generic
#endif
#ifdef CRYPT_BACKEND_GPGME
+#include "crypt-gpgme.h"
extern struct crypt_module_specs crypt_mod_pgp_gpgme;
extern struct crypt_module_specs crypt_mod_smime_gpgme;
#endif
/* Warning: A is no longer freed in this routine, you need to free it
later. This is necessary for $fcc_attach. */
-BODY *crypt_pgp_encrypt_message (BODY *a, char *keylist, int sign)
+BODY *crypt_pgp_encrypt_message (HEADER *msg, BODY *a, char *keylist, int sign)
{
+#ifdef USE_AUTOCRYPT
+ BODY *result;
+
+ if (msg->security & AUTOCRYPT)
+ {
+ if (mutt_autocrypt_set_sign_as_default_key (msg))
+ return NULL;
+
+ set_option (OPTAUTOCRYPTGPGME);
+ result = pgp_gpgme_encrypt_message (a, keylist, sign);
+ unset_option (OPTAUTOCRYPTGPGME);
+
+ return result;
+ }
+#endif
+
if (CRYPT_MOD_CALL_CHECK (PGP, pgp_encrypt_message))
return (CRYPT_MOD_CALL (PGP, pgp_encrypt_message)) (a, keylist, sign);
WHERE char *AttachFormat;
#ifdef USE_AUTOCRYPT
WHERE char *AutocryptDir;
+WHERE char *AutocryptSignAs; /* This is used in crypt-gpgme.c */
+WHERE char *AutocryptDefaultKey; /* Used for postponing messages */
#endif
WHERE char *Charset;
WHERE char *ComposeFormat;
OPTPGPCHECKTRUST, /* (pseudo) used by pgp_select_key () */
OPTDONTHANDLEPGPKEYS, /* (pseudo) used to extract PGP keys */
OPTIGNOREMACROEVENTS, /* (pseudo) don't process macro/push/exec events while set */
+ OPTAUTOCRYPTGPGME, /* (pseudo) use Autocrypt context inside crypt-gpgme.c */
OPTMAX
};
/* Some prototypes -- old crypt.h. */
-int mutt_protect (HEADER *, char *);
+int mutt_protect (HEADER *, char *, int);
int mutt_is_multipart_encrypted (BODY *);
/* Warning: A is no longer freed in this routine, you need to free it
later. This is necessary for $fcc_attach. */
-BODY *crypt_pgp_encrypt_message (BODY *a, char *keylist, int sign);
+BODY *crypt_pgp_encrypt_message (HEADER *msg, BODY *a, char *keylist, int sign);
/* Invoke the PGP command to import a key. */
void crypt_pgp_invoke_import (const char *fname);
flags |= OPPENCRYPT;
break;
+ case 'a':
+ case 'A':
+#ifdef USE_AUTOCRYPT
+ flags |= AUTOCRYPT;
+#endif
+ break;
+
+ case 'z':
+ case 'Z':
+#ifdef USE_AUTOCRYPT
+ flags |= AUTOCRYPT_OVERRIDE;
+#endif
+ break;
+
case 's':
case 'S':
flags |= SIGN;
#include "rfc3676.h"
#include "attach.h"
+#ifdef USE_AUTOCRYPT
+#include "autocrypt.h"
+#endif
+
#include <ctype.h>
#include <stdlib.h>
#include <locale.h>
* Protected Headers. */
if (!option (OPTFCCBEFORESEND))
{
- if (WithCrypto && (msg->security & (ENCRYPT | SIGN)) && option (OPTFCCCLEAR))
+ if (WithCrypto &&
+ (msg->security & (ENCRYPT | SIGN | AUTOCRYPT))
+ && option (OPTFCCCLEAR))
{
msg->content = clear_content;
- msg->security &= ~(ENCRYPT | SIGN);
+ msg->security &= ~(ENCRYPT | SIGN | AUTOCRYPT);
mutt_free_envelope (&msg->content->mime_headers);
}
msg->content->type == TYPEMULTIPART)
{
if (WithCrypto
- && (msg->security & (ENCRYPT | SIGN))
+ && (msg->security & (ENCRYPT | SIGN | AUTOCRYPT))
&& (mutt_strcmp (msg->content->subtype, "encrypted") == 0 ||
mutt_strcmp (msg->content->subtype, "signed") == 0))
{
/* this means writing only the main part */
msg->content = clear_content->parts;
- if (mutt_protect (msg, pgpkeylist) == -1)
+ if (mutt_protect (msg, pgpkeylist, 0) == -1)
{
/* we can't do much about it at this point, so
* fallback to saving the whole thing to fcc
{
char *pgpkeylist = NULL;
char *encrypt_as = NULL;
- int is_signed;
BODY *clear_content = NULL;
if (!Postponed)
mutt_encode_descriptions (msg->content, 1);
- if (WithCrypto && option (OPTPOSTPONEENCRYPT) && (msg->security & ENCRYPT))
+ if (WithCrypto && option (OPTPOSTPONEENCRYPT) &&
+ (msg->security & (ENCRYPT | AUTOCRYPT)))
{
if ((WithCrypto & APPLICATION_PGP) && (msg->security & APPLICATION_PGP))
encrypt_as = PgpDefaultKey;
if (!encrypt_as)
encrypt_as = PostponeEncryptAs;
- if (encrypt_as)
+#ifdef USE_AUTOCRYPT
+ if (msg->security & AUTOCRYPT)
{
- is_signed = msg->security & SIGN;
- if (is_signed)
- msg->security &= ~SIGN;
+ if (mutt_autocrypt_set_sign_as_default_key (msg))
+ return -1;
+ encrypt_as = AutocryptDefaultKey;
+ }
+#endif
+ if (encrypt_as)
+ {
pgpkeylist = safe_strdup (encrypt_as);
clear_content = msg->content;
- if (mutt_protect (msg, pgpkeylist) == -1)
+ if (mutt_protect (msg, pgpkeylist, 1) == -1)
{
- if (is_signed)
- msg->security |= SIGN;
FREE (&pgpkeylist);
msg->content = mutt_remove_multipart (msg->content);
decode_descriptions (msg->content);
return -1;
}
- if (is_signed)
- msg->security |= SIGN;
FREE (&pgpkeylist);
-
mutt_encode_descriptions (msg->content, 0);
}
}
*/
if (WithCrypto && (msg->security == 0) && !(flags & (SENDBATCH | SENDMAILX | SENDPOSTPONED | SENDRESEND)))
{
- if (option (OPTCRYPTAUTOSIGN))
- msg->security |= SIGN;
- if (option (OPTCRYPTAUTOENCRYPT))
- msg->security |= ENCRYPT;
- if (option (OPTCRYPTREPLYENCRYPT) && cur && (cur->security & ENCRYPT))
- msg->security |= ENCRYPT;
- if (option (OPTCRYPTREPLYSIGN) && cur && (cur->security & SIGN))
- msg->security |= SIGN;
- if (option (OPTCRYPTREPLYSIGNENCRYPTED) && cur && (cur->security & ENCRYPT))
- msg->security |= SIGN;
- if ((WithCrypto & APPLICATION_PGP) &&
- ((msg->security & (ENCRYPT | SIGN)) || option (OPTCRYPTOPPORTUNISTICENCRYPT)))
- {
- if (option (OPTPGPAUTOINLINE))
- msg->security |= INLINE;
- if (option (OPTPGPREPLYINLINE) && cur && (cur->security & INLINE))
- msg->security |= INLINE;
+ if (
+#ifdef USE_AUTOCRYPT
+ option (OPTAUTOCRYPT)
+#else
+ 0
+#endif
+ && cur && (cur->security & AUTOCRYPT))
+ {
+ msg->security |= (AUTOCRYPT | AUTOCRYPT_OVERRIDE);
+ }
+ else
+ {
+ if (option (OPTCRYPTAUTOSIGN))
+ msg->security |= SIGN;
+ if (option (OPTCRYPTAUTOENCRYPT))
+ msg->security |= ENCRYPT;
+ if (option (OPTCRYPTREPLYENCRYPT) && cur && (cur->security & ENCRYPT))
+ msg->security |= ENCRYPT;
+ if (option (OPTCRYPTREPLYSIGN) && cur && (cur->security & SIGN))
+ msg->security |= SIGN;
+ if (option (OPTCRYPTREPLYSIGNENCRYPTED) && cur && (cur->security & ENCRYPT))
+ msg->security |= SIGN;
+ if ((WithCrypto & APPLICATION_PGP) &&
+ ((msg->security & (ENCRYPT | SIGN)) || option (OPTCRYPTOPPORTUNISTICENCRYPT)))
+ {
+ if (option (OPTPGPAUTOINLINE))
+ msg->security |= INLINE;
+ if (option (OPTPGPREPLYINLINE) && cur && (cur->security & INLINE))
+ msg->security |= INLINE;
+ }
}
if (msg->security || option (OPTCRYPTOPPORTUNISTICENCRYPT))
* or OPTCRYPTREPLYENCRYPT, then don't enable opportunistic encrypt for
* the message.
*/
- if (! (msg->security & ENCRYPT))
+ if (! (msg->security & (ENCRYPT|AUTOCRYPT)))
{
msg->security |= OPPENCRYPT;
crypt_opportunistic_encrypt(msg);
if (WithCrypto)
{
- if (msg->security & (ENCRYPT | SIGN))
+ if (msg->security & (ENCRYPT | SIGN | AUTOCRYPT))
{
/* save the decrypted attachments */
clear_content = msg->content;
if ((crypt_get_keys (msg, &pgpkeylist, 0) == -1) ||
- mutt_protect (msg, pgpkeylist) == -1)
+ mutt_protect (msg, pgpkeylist, 0) == -1)
{
msg->content = mutt_remove_multipart (msg->content);
{
if (!WithCrypto)
;
- else if ((msg->security & ENCRYPT) ||
+ else if ((msg->security & (ENCRYPT | AUTOCRYPT)) ||
((msg->security & SIGN)
&& msg->content->type == TYPEAPPLICATION))
{
#include "mutt_idna.h"
#include "buffy.h"
+#ifdef USE_AUTOCRYPT
+#include "autocrypt.h"
+#endif
+
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
if (a->encoding != ENC7BIT)
fprintf(f, "Content-Transfer-Encoding: %s\n", ENCODING (a->encoding));
- if (option (OPTCRYPTPROTHDRSWRITE) && a->mime_headers)
+ if ((option (OPTCRYPTPROTHDRSWRITE)
+#ifdef USE_AUTOCRYPT
+ || option (OPTAUTOCRYPT)
+#endif
+ ) &&
+ a->mime_headers)
+ {
mutt_write_rfc822_header (f, a->mime_headers, NULL, MUTT_WRITE_HEADER_MIME, 0, 0);
+ }
/* Do NOT add the terminator here!!! */
return (ferror (f) ? -1 : 0);
fputc ('\n', fp);
}
+#ifdef USE_AUTOCRYPT
+ if (option (OPTAUTOCRYPT))
+ {
+ if (mode == MUTT_WRITE_HEADER_NORMAL)
+ mutt_autocrypt_write_autocrypt_header (env, fp);
+ if (mode == MUTT_WRITE_HEADER_MIME)
+ mutt_autocrypt_write_gossip_headers (env, fp);
+ }
+#endif
+
/* Add any user defined headers */
for (; tmp; tmp = tmp->next)
{
}
if (hdr->security & INLINE)
fputc ('I', msg->fp);
+#ifdef USE_AUTOCRYPT
+ if (hdr->security & AUTOCRYPT)
+ fputc ('A', msg->fp);
+ if (hdr->security & AUTOCRYPT_OVERRIDE)
+ fputc ('Z', msg->fp);
+#endif
fputc ('\n', msg->fp);
}