summaryrefslogtreecommitdiffstats
path: root/autocrypt
diff options
context:
space:
mode:
authorKevin McCarthy <kevin@8t8.us>2019-07-19 12:54:32 -0700
committerKevin McCarthy <kevin@8t8.us>2019-08-03 14:08:09 -0700
commit959628d079b6efaa9c724f9be83af3d6061fdae4 (patch)
treec6d3edc4ca66ae97dab6b3df502bf86a0e57c574 /autocrypt
parent009b62c9f773b82b20b6798be3125f471569f14d (diff)
Add autocrypt line to the compose menu.
Remove the hardcoded HDR_ATTACH offset calcuation, and add an explicit enum for the "-- Attachments" line to make loops and padding array sizes easier. Add security and recommendataion fields on the line. Add mutt_autocrypt_ui_recommendation, following the autocrypt spec guidelines.
Diffstat (limited to 'autocrypt')
-rw-r--r--autocrypt/autocrypt.c72
-rw-r--r--autocrypt/autocrypt.h10
-rw-r--r--autocrypt/autocrypt_gpgme.c26
-rw-r--r--autocrypt/autocrypt_private.h1
4 files changed, 109 insertions, 0 deletions
diff --git a/autocrypt/autocrypt.c b/autocrypt/autocrypt.c
index 228c24a6..dd3ccb82 100644
--- a/autocrypt/autocrypt.c
+++ b/autocrypt/autocrypt.c
@@ -22,6 +22,7 @@
#include "mutt.h"
#include "mutt_curses.h"
+#include "mutt_crypt.h"
#include "mime.h"
#include "mutt_idna.h"
#include "autocrypt.h"
@@ -437,3 +438,74 @@ cleanup:
return rv;
}
+
+autocrypt_rec_t mutt_autocrypt_ui_recommendation (HEADER *hdr)
+{
+ 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;
+
+ if (!option (OPTAUTOCRYPT) ||
+ mutt_autocrypt_init (0) ||
+ !hdr ||
+ !hdr->env->from ||
+ hdr->env->from->next)
+ return AUTOCRYPT_REC_OFF;
+
+ if (hdr->security & APPLICATION_SMIME)
+ return AUTOCRYPT_REC_OFF;
+
+ if (mutt_autocrypt_db_account_get (hdr->env->from, &account) <= 0)
+ goto cleanup;
+
+ 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);
+
+ rv = AUTOCRYPT_REC_NO;
+ if (!recips)
+ goto cleanup;
+
+ for (recip = recips; recip; recip = recip->next)
+ {
+ if (mutt_autocrypt_db_peer_get (recip, &peer) <= 0)
+ goto cleanup;
+
+ if (mutt_autocrypt_gpgme_is_valid_key (peer->keyid))
+ {
+ if (!(peer->last_seen && peer->autocrypt_timestamp) ||
+ (peer->last_seen - peer->autocrypt_timestamp > 35 * 24 * 60 * 60))
+ {
+ has_discourage = 1;
+ all_encrypt = 0;
+ }
+
+ if (!account->prefer_encrypt || !peer->prefer_encrypt)
+ all_encrypt = 0;
+ }
+ else if (mutt_autocrypt_gpgme_is_valid_key (peer->gossip_keyid))
+ {
+ has_discourage = 1;
+ all_encrypt = 0;
+ }
+ else
+ goto cleanup;
+
+ mutt_autocrypt_db_peer_free (&peer);
+ }
+
+ if (all_encrypt)
+ rv = AUTOCRYPT_REC_YES;
+ else if (has_discourage)
+ rv = AUTOCRYPT_REC_DISCOURAGE;
+ else
+ rv = AUTOCRYPT_REC_AVAILABLE;
+
+cleanup:
+ mutt_autocrypt_db_account_free (&account);
+ rfc822_free_address (&recips);
+ mutt_autocrypt_db_peer_free (&peer);
+ return rv;
+}
diff --git a/autocrypt/autocrypt.h b/autocrypt/autocrypt.h
index a2401bc3..2608277d 100644
--- a/autocrypt/autocrypt.h
+++ b/autocrypt/autocrypt.h
@@ -62,9 +62,19 @@ typedef struct
char *gossip_keydata;
} AUTOCRYPT_GOSSIP_HISTORY;
+typedef enum
+{
+ AUTOCRYPT_REC_OFF,
+ AUTOCRYPT_REC_NO,
+ AUTOCRYPT_REC_DISCOURAGE,
+ AUTOCRYPT_REC_AVAILABLE,
+ AUTOCRYPT_REC_YES
+} autocrypt_rec_t;
+
int mutt_autocrypt_init (int);
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);
#endif
diff --git a/autocrypt/autocrypt_gpgme.c b/autocrypt/autocrypt_gpgme.c
index 952f648b..84bb9ffc 100644
--- a/autocrypt/autocrypt_gpgme.c
+++ b/autocrypt/autocrypt_gpgme.c
@@ -212,3 +212,29 @@ cleanup:
mutt_buffer_pool_release (&raw_keydata);
return rv;
}
+
+int mutt_autocrypt_gpgme_is_valid_key (const char *keyid)
+{
+ int rv = 0;
+ gpgme_ctx_t ctx = NULL;
+ gpgme_key_t key = NULL;
+
+ if (!keyid)
+ return 0;
+
+ if (create_gpgme_context (&ctx))
+ goto cleanup;
+
+ if (gpgme_get_key (ctx, keyid, &key, 0))
+ goto cleanup;
+
+ rv = 1;
+ if (key->revoked || key->expired || key->disabled || key->invalid ||
+ !key->can_encrypt)
+ rv = 0;
+
+cleanup:
+ gpgme_key_unref (key);
+ gpgme_release (ctx);
+ return rv;
+}
diff --git a/autocrypt/autocrypt_private.h b/autocrypt/autocrypt_private.h
index 1ba51920..3e370da6 100644
--- a/autocrypt/autocrypt_private.h
+++ b/autocrypt/autocrypt_private.h
@@ -54,5 +54,6 @@ int mutt_autocrypt_schema_update (void);
int mutt_autocrypt_gpgme_init (void);
int mutt_autocrypt_gpgme_create_key (ADDRESS *addr, BUFFER *keyid, BUFFER *keydata);
int mutt_autocrypt_gpgme_import_key (const char *keydata, BUFFER *keyid);
+int mutt_autocrypt_gpgme_is_valid_key (const char *keyid);
#endif