changeset: 6403:ec93761e3e12
user:      Kevin McCarthy <[email protected]>
date:      Fri Jan 23 10:33:32 2015 -0800
link:      http://dev.mutt.org/hg/mutt/rev/ec93761e3e12

Implement mail-key, Esc-K, for gpgme. (closes #3488)

This patch implements the make-key-attachment function for gpgme,
modeled after the pgp version.

It also adds an optional tempf parameter to data_object_to_tempfile() so
the function can be reused for make-key-attachment.

diffs (192 lines):

diff -r b39219ffe75b -r ec93761e3e12 crypt-gpgme.c
--- a/crypt-gpgme.c     Mon Jan 19 15:58:38 2015 -0800
+++ b/crypt-gpgme.c     Fri Jan 23 10:33:32 2015 -0800
@@ -539,21 +539,27 @@
   return 0;
 }
 
-/* Copy a data object to a newly created temporay file and return that
-   filename. Caller must free.  With RET_FP not NULL, don't close the
-   stream but return it there. */
-static char *data_object_to_tempfile (gpgme_data_t data, FILE **ret_fp)
+/* Copy a data object to a temporary file.
+ * The tempfile name may be optionally passed in.
+ * If ret_fp is passed in, the file will be rewound, left open, and returned
+ * via that parameter.
+ * The tempfile name is returned, and must be freed.
+ */
+static char *data_object_to_tempfile (gpgme_data_t data, char *tempf, FILE 
**ret_fp)
 {
   int err;
-  char tempfile[_POSIX_PATH_MAX];
+  char tempfb[_POSIX_PATH_MAX];
   FILE *fp;
   size_t nread = 0;
 
-  mutt_mktemp (tempfile, sizeof (tempfile));
-  fp = safe_fopen (tempfile, "w+");
-  if (!fp)
+  if (!tempf)
     {
-      mutt_perror (tempfile);
+      mutt_mktemp (tempfb, sizeof (tempfb));
+      tempf = tempfb;
+    }
+  if ((fp = safe_fopen (tempf, tempf == tempfb ? "w+" : "a+")) == NULL)
+    {
+      mutt_perror _("Can't create temporary file");
       return NULL;
     }
 
@@ -567,9 +573,9 @@
         {
           if (fwrite (buf, nread, 1, fp) != 1)
             {
-              mutt_perror (tempfile);
+              mutt_perror (tempf);
               safe_fclose (&fp);
-              unlink (tempfile);
+              unlink (tempf);
               return NULL;
             }
         }
@@ -581,13 +587,13 @@
   if (nread == -1)
     {
       mutt_error (_("error reading data object: %s\n"), gpgme_strerror (err));
-      unlink (tempfile);
+      unlink (tempf);
       safe_fclose (&fp);
       return NULL;
     }
   if (ret_fp)
     *ret_fp = fp;
-  return safe_strdup (tempfile);
+  return safe_strdup (tempf);
 }
 
 
@@ -806,7 +812,7 @@
 
   gpgme_release (ctx);
 
-  outfile = data_object_to_tempfile (ciphertext, NULL);
+  outfile = data_object_to_tempfile (ciphertext, NULL, NULL);
   gpgme_data_release (ciphertext);
   return outfile;
 }
@@ -932,7 +938,7 @@
       return NULL;
   }
 
-  sigfile = data_object_to_tempfile (signature, NULL);
+  sigfile = data_object_to_tempfile (signature, NULL, NULL);
   gpgme_data_release (signature);
   if (!sigfile)
     {
@@ -2212,7 +2218,7 @@
   char *fname;
   FILE *fp;
 
-  fname = data_object_to_tempfile (data, &fp);
+  fname = data_object_to_tempfile (data, NULL, &fp);
   if (!fname)
     return;
   unlink (fname);
@@ -2405,7 +2411,7 @@
                                            "information --]\n\n"), s);
                     }
 
-                  tmpfname = data_object_to_tempfile (plaintext, &pgpout);
+                  tmpfname = data_object_to_tempfile (plaintext, NULL, 
&pgpout);
                   if (!tmpfname)
                     {
                       pgpout = NULL;
@@ -4463,6 +4469,63 @@
   return find_keys (to, cc, bcc, APPLICATION_SMIME);
 }
 
+BODY *pgp_gpgme_make_key_attachment (char *tempf)
+{
+  crypt_key_t *key = NULL;
+  gpgme_ctx_t context = NULL;
+  gpgme_key_t export_keys[2];
+  gpgme_data_t keydata = NULL;
+  gpgme_error_t err;
+  BODY *att = NULL;
+  char buff[LONG_STRING];
+  struct stat sb;
+
+  unset_option (OPTPGPCHECKTRUST);
+
+  key = crypt_ask_for_key (_("Please enter the key ID: "), NULL, 0,
+                           APPLICATION_PGP, NULL);
+  if (!key)
+    goto bail;
+  export_keys[0] = key->kobj;
+  export_keys[1] = NULL;
+
+  context = create_gpgme_context (0);
+  gpgme_set_armor (context, 1);
+  keydata = create_gpgme_data ();
+  err = gpgme_op_export_keys (context, export_keys, 0, keydata);
+  if (err != GPG_ERR_NO_ERROR)
+  {
+    mutt_error (_("Error exporting key: %s\n"), gpgme_strerror (err));
+    mutt_sleep (1);
+    goto bail;
+  }
+
+  tempf = data_object_to_tempfile (keydata, tempf, NULL);
+  if (!tempf)
+    goto bail;
+
+  att = mutt_new_body ();
+  /* tempf is a newly allocated string, so this is correct: */
+  att->filename = tempf;
+  att->unlink = 1;
+  att->use_disp = 0;
+  att->type = TYPEAPPLICATION;
+  att->subtype = safe_strdup ("pgp-keys");
+  snprintf (buff, sizeof (buff), _("PGP Key 0x%s."), crypt_keyid (key));
+  att->description = safe_strdup (buff);
+  mutt_update_encoding (att);
+
+  stat (tempf, &sb);
+  att->length = sb.st_size;
+
+bail:
+  crypt_free_key (&key);
+  gpgme_data_release (keydata);
+  gpgme_release (context);
+
+  return att;
+}
+
 /*
  * Implementation of `init'.
  */
diff -r b39219ffe75b -r ec93761e3e12 crypt-mod-pgp-gpgme.c
--- a/crypt-mod-pgp-gpgme.c     Mon Jan 19 15:58:38 2015 -0800
+++ b/crypt-mod-pgp-gpgme.c     Fri Jan 23 10:33:32 2015 -0800
@@ -95,6 +95,11 @@
   return pgp_gpgme_encrypt_message (a, keylist, sign);
 }
 
+static BODY *crypt_mod_pgp_make_key_attachment (char *tempf)
+{
+  return pgp_gpgme_make_key_attachment (tempf);
+}
+
 static void crypt_mod_pgp_set_sender (const char *sender)
 {
   gpgme_set_sender (sender);
@@ -118,7 +123,7 @@
 
       /* PGP specific.  */
       crypt_mod_pgp_encrypt_message,
-      NULL,                    /* pgp_make_key_attachment, */
+      crypt_mod_pgp_make_key_attachment,
       crypt_mod_pgp_check_traditional,
       NULL,                    /* pgp_traditional_encryptsign  */
       NULL, /* pgp_invoke_getkeys  */

Reply via email to