drop lots of old fashionned crypt settings.
[apps/madmutt.git] / lib-crypt / crypt-gpgme.c
index 949d1eb..7c24186 100644 (file)
@@ -14,8 +14,6 @@
 
 #include <lib-lib/lib-lib.h>
 
-#ifdef CRYPT_BACKEND_GPGME
-
 #ifdef HAVE_LOCALE_H
 #  include <locale.h>
 #endif
 #include <gpgme.h>
 
 #include <lib-mime/mime.h>
-
 #include <lib-ui/curses.h>
 #include <lib-ui/enter.h>
 #include <lib-ui/menu.h>
 
+#include "crypt.h"
+
 #include "lib.h"
 #include "alias.h"
-#include <lib-crypt/crypt.h>
 #include "handler.h"
 #include "copy.h"
 #include "pager.h"
 #include "recvattach.h"
 #include "sort.h"
-#include "crypt-gpgme.h"
-
-/*
- * Helper macros.
- */
-#define digitp(p)   (*(p) >= '0' && *(p) <= '9')
-#define hexdigitp(a) (digitp (a)                     \
-                      || (*(a) >= 'A' && *(a) <= 'F')  \
-                      || (*(a) >= 'a' && *(a) <= 'f'))
-#define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
-                     *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
-#define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
 
 /* Values used for comparing addresses. */
 #define CRYPT_KV_VALID    1
@@ -96,6 +82,28 @@ typedef struct crypt_entry {
 static struct crypt_cache *id_defaults = NULL;
 static gpgme_key_t signature_key = NULL;
 
+/* Initialization.  */
+void crypt_init(void)
+{
+    /* Make sure that gpg-agent is running.  */
+    if (!getenv ("GPG_AGENT_INFO")) {
+        mutt_error ("\nUsing GPGME backend, although no gpg-agent is running");
+        if (mutt_any_key_to_continue (NULL) == -1)
+            mutt_exit (1);
+    }
+}
+
+/* Show a message that a backend will be invoked. */
+void crypt_invoke_message (int type)
+{
+    if (type & APPLICATION_PGP) {
+        mutt_message _("Invoking PGP...");
+    }
+    else if (type & APPLICATION_SMIME) {
+        mutt_message _("Invoking S/MIME...");
+    }
+}
+
 /*
  * General helper functions.
  */
@@ -685,9 +693,7 @@ static void print_time (time_t t, STATE * s)
   state_attach_puts (p, s);
 }
 
-/* 
- * Implementation of `sign_message'.
- */
+/* Implementation of `sign_message'. */
 
 /* Sign the MESSAGE in body A either using OpenPGP or S/MIME when
    USE_SMIME is passed as true.  Returns the new body or NULL on
@@ -781,12 +787,12 @@ static BODY *sign_message (BODY * a, int use_smime)
 }
 
 
-BODY *pgp_gpgme_sign_message (BODY * a)
+BODY *crypt_pgp_sign_message (BODY * a)
 {
   return sign_message (a, 0);
 }
 
-BODY *smime_gpgme_sign_message (BODY * a)
+BODY *crypt_smime_sign_message (BODY * a)
 {
   return sign_message (a, 1);
 }
@@ -797,7 +803,7 @@ BODY *smime_gpgme_sign_message (BODY * a)
 
 /* Encrypt the mail body A to all keys given as space separated keyids
    or fingerprints in KEYLIST and return the encrypted body.  */
-BODY *pgp_gpgme_encrypt_message (BODY * a, char *keylist, int sign)
+BODY *crypt_pgp_encrypt_message (BODY * a, char *keylist, int sign)
 {
   char *outfile = NULL;
   BODY *t;
@@ -857,7 +863,7 @@ BODY *pgp_gpgme_encrypt_message (BODY * a, char *keylist, int sign)
 
 /* Encrypt the mail body A to all keys given as space separated
    fingerprints in KEYLIST and return the S/MIME encrypted body.  */
-BODY *smime_gpgme_build_smime_entity (BODY * a, char *keylist)
+BODY *crypt_smime_build_smime_entity (BODY * a, char *keylist)
 {
   char *outfile = NULL;
   BODY *t;
@@ -898,9 +904,7 @@ BODY *smime_gpgme_build_smime_entity (BODY * a, char *keylist)
 }
 
 
-/* 
- * Implementation of `verify_one'.
- */
+/* Implementation of `verify_one'. */
 
 /* Display the common attributes of the signature summary SUM.
    Return 1 if there is is a severe warning.
@@ -1297,12 +1301,12 @@ static int verify_one (BODY * sigbdy, STATE * s,
   return badsig ? 1 : anywarn ? 2 : 0;
 }
 
-int pgp_gpgme_verify_one (BODY * sigbdy, STATE * s, const char *tempfile)
+int crypt_pgp_verify_one (BODY * sigbdy, STATE * s, const char *tempfile)
 {
   return verify_one (sigbdy, s, tempfile, 0);
 }
 
-int smime_gpgme_verify_one (BODY * sigbdy, STATE * s, const char *tempfile)
+int crypt_smime_verify_one (BODY * sigbdy, STATE * s, const char *tempfile)
 {
   return verify_one (sigbdy, s, tempfile, 1);
 }
@@ -1447,7 +1451,7 @@ restart:
 
 /* Decrypt a PGP/MIME message in FPIN and B and return a new body and
    the stream in CUR and FPOUT.  Returns 0 on success. */
-int pgp_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur)
+int crypt_pgp_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur)
 {
   char tempfile[_POSIX_PATH_MAX];
   STATE s;
@@ -1485,7 +1489,7 @@ int pgp_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur)
 
 /* Decrypt a S/MIME message in FPIN and B and return a new body and
    the stream in CUR and FPOUT.  Returns 0 on success. */
-int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b,
+int crypt_smime_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b,
                               BODY ** cur)
 {
   char tempfile[_POSIX_PATH_MAX];
@@ -1658,14 +1662,14 @@ static int pgp_check_traditional_one_body (FILE * fp, BODY * b,
   return 1;
 }
 
-int pgp_gpgme_check_traditional (FILE * fp, BODY * b, int tagged_only)
+int crypt_pgp_check_traditional (FILE * fp, BODY * b, int tagged_only)
 {
   int rv = 0;
   int r;
 
   for (; b; b = b->next) {
     if (is_multipart (b))
-      rv = (pgp_gpgme_check_traditional (fp, b->parts, tagged_only) || rv);
+      rv = (crypt_pgp_check_traditional (fp, b->parts, tagged_only) || rv);
     else if (b->type == TYPETEXT) {
       if ((r = mutt_is_application_pgp (b)))
         rv = (rv || r);
@@ -1677,9 +1681,7 @@ int pgp_gpgme_check_traditional (FILE * fp, BODY * b, int tagged_only)
 }
 
 
-/* 
- * Implementation of `application_handler'.
- */
+/* Implementation of `application_handler'. */
 
 /* 
   Copy a clearsigned message, and strip the signature and PGP's
@@ -1742,7 +1744,7 @@ static void copy_clearsigned (gpgme_data_t data, STATE * s, char *charset)
 
 
 /* Support for classic_application/pgp */
-int pgp_gpgme_application_handler (BODY * m, STATE * s)
+int crypt_pgp_application_pgp_handler (BODY * m, STATE * s)
 {
   int needpass = -1, pgp_keyblock = 0;
   int clearsign = 0;
@@ -1966,12 +1968,10 @@ int pgp_gpgme_application_handler (BODY * m, STATE * s)
   return (err);
 }
 
-/* 
- * Implementation of `encrypted_handler'.
- */
+/* Implementation of `encrypted_handler'. */
 
 /* MIME handler for pgp/mime encrypted messages. */
-int pgp_gpgme_encrypted_handler (BODY * a, STATE * s)
+int crypt_pgp_encrypted_handler (BODY * a, STATE * s)
 {
   char tempfile[_POSIX_PATH_MAX];
   FILE *fpout;
@@ -2045,7 +2045,7 @@ int pgp_gpgme_encrypted_handler (BODY * a, STATE * s)
 }
 
 /* Support for application/smime */
-int smime_gpgme_application_handler (BODY * a, STATE * s)
+int crypt_smime_application_smime_handler (BODY * a, STATE * s)
 {
   char tempfile[_POSIX_PATH_MAX];
   FILE *fpout;
@@ -2511,7 +2511,7 @@ static const unsigned char *parse_dn_part (struct dn_array_s *array,
 
   if (*string == '#') {         /* hexstring */
     string++;
-    for (s = string; hexdigitp (s); s++)
+    for (s = string; hexval(*s) >= 0; s++)
       s++;
     n = s - string;
     if (!n || (n & 1))
@@ -2520,7 +2520,7 @@ static const unsigned char *parse_dn_part (struct dn_array_s *array,
     p = p_new(unsigned char, n + 1);
     array->value = (char *) p;
     for (s1 = string; n; s1 += 2, n--)
-      *p++ = xtoi_2 (s1);
+      *p++ = (hexval(*s1) << 8) | hexval(*s1);
     *p = 0;
   }
   else {                        /* regular v3 quoted string */
@@ -2531,7 +2531,7 @@ static const unsigned char *parse_dn_part (struct dn_array_s *array,
             || *s == '<' || *s == '>' || *s == '#' || *s == ';'
             || *s == '\\' || *s == '\"' || *s == ' ')
           n++;
-        else if (hexdigitp (s) && hexdigitp (s + 1)) {
+        else if (hexval(*s) >= 0 && hexval(*s + 1) >= 0) {
           s++;
           n++;
         }
@@ -2552,8 +2552,8 @@ static const unsigned char *parse_dn_part (struct dn_array_s *array,
     for (s = string; n; s++, n--) {
       if (*s == '\\') {
         s++;
-        if (hexdigitp (s)) {
-          *p++ = xtoi_2 (s);
+        if (hexval(*s) >= 0) {
+          *p++ = (hexval(*s) << 8) | hexval(*s + 1);
           s++;
         }
         else
@@ -2975,10 +2975,7 @@ leave:
   mutt_do_pager (cmd, tempfile, 0, NULL);
 }
 
-/* 
- * Implementation of `findkeys'.
- */
-
+/* Implementation of `findkeys'. */
 
 /* Convert string_list_t into a pattern string suitable to be passed to GPGME.
    We need to convert spaces in an item into a '+' and '%' into
@@ -3718,40 +3715,16 @@ static char *find_keys (address_t * to, address_t * cc, address_t * bcc,
   return (keylist);
 }
 
-char *pgp_gpgme_findkeys (address_t * to, address_t * cc, address_t * bcc)
+char *crypt_pgp_findkeys (address_t * to, address_t * cc, address_t * bcc)
 {
   return find_keys (to, cc, bcc, APPLICATION_PGP);
 }
 
-char *smime_gpgme_findkeys (address_t * to, address_t * cc, address_t * bcc)
+char *crypt_smime_findkeys (address_t * to, address_t * cc, address_t * bcc)
 {
   return find_keys (to, cc, bcc, APPLICATION_SMIME);
 }
 
-/*
- * Implementation of `init'.
- */
-
-/* Initialization.  */
-static void init_gpgme (void)
-{
-  /* Make sure that gpg-agent is running.  */
-  if (!getenv ("GPG_AGENT_INFO")) {
-    mutt_error ("\nUsing GPGME backend, although no gpg-agent is running");
-    if (mutt_any_key_to_continue (NULL) == -1)
-      mutt_exit (1);
-  }
-}
-
-void pgp_gpgme_init (void)
-{
-  init_gpgme ();
-}
-
-void smime_gpgme_init (void)
-{
-}
-
 static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime)
 {
   crypt_key_t *p;
@@ -3827,17 +3800,17 @@ static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime)
   return (msg->security);
 }
 
-int pgp_gpgme_send_menu (HEADER * msg, int *redraw)
+int crypt_pgp_send_menu(HEADER * msg, int *redraw)
 {
-  return gpgme_send_menu (msg, redraw, 0);
+  return gpgme_send_menu(msg, redraw, 0);
 }
 
-int smime_gpgme_send_menu (HEADER * msg, int *redraw)
+int crypt_smime_send_menu(HEADER * msg, int *redraw)
 {
   return gpgme_send_menu (msg, redraw, 1);
 }
 
-static int verify_sender (HEADER * h, gpgme_protocol_t protocol __attribute__((unused)))
+int crypt_smime_verify_sender (HEADER * h)
 {
   address_t *sender = NULL;
   unsigned int ret = 1;
@@ -3882,9 +3855,79 @@ static int verify_sender (HEADER * h, gpgme_protocol_t protocol __attribute__((u
   return ret;
 }
 
-int smime_gpgme_verify_sender (HEADER * h)
+static void invoke_import(const char *fname, int smime)
+{
+    gpgme_ctx_t ctx = create_gpgme_context(smime);
+    gpgme_data_t data;
+    gpgme_error_t err;
+
+    err = gpgme_data_new_from_file(&data, fname, 1);
+    if (err) {
+        mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err));
+        gpgme_release(ctx);
+        return;
+    }
+
+    err = gpgme_op_import(ctx, data);
+    if (err) {
+        mutt_error(_("error importing gpg data: %s\n"), gpgme_strerror(err));
+        gpgme_data_release(data);
+        gpgme_release(ctx);
+        return;
+    }
+
+    gpgme_data_release(data);
+    gpgme_release(ctx);
+    return;
+}
+
+void crypt_pgp_invoke_import(const char *fname)
 {
-  return verify_sender (h, GPGME_PROTOCOL_CMS);
+    invoke_import(fname, 0);
+}
+
+void crypt_smime_invoke_import(const char *fname)
+{
+    invoke_import(fname, 1);
+}
+
+static void pgp_extract_keys_from_attachment (FILE * fp, BODY * top)
+{
+  STATE s;
+  FILE *tempfp;
+  char tempfname[_POSIX_PATH_MAX];
+
+  tempfp = m_tempfile(tempfname, sizeof(tempfname), NONULL(MCore.tmpdir), NULL);
+  if (tempfp == NULL) {
+    mutt_perror (_("Can't create temporary file"));
+    return;
+  }
+
+  p_clear(&s, 1);
+
+  s.fpin = fp;
+  s.fpout = tempfp;
+
+  mutt_body_handler (top, &s);
+
+  m_fclose(&tempfp);
+  crypt_pgp_invoke_import(tempfname);
+  mutt_unlink (tempfname);
+}
+
+void crypt_pgp_extract_keys_from_attachment_list(FILE * fp, int tag, BODY * top)
+{
+  mutt_endwin (NULL);
+  set_option (OPTDONTHANDLEPGPKEYS);
+
+  for (; top; top = top->next) {
+    if (!tag || top->tagged)
+      pgp_extract_keys_from_attachment (fp, top);
+
+    if (!tag)
+      break;
+  }
+
+  unset_option (OPTDONTHANDLEPGPKEYS);
 }
 
-#endif