]> granicus.if.org Git - mutt/commitdiff
Make $fcc_attach work correctly when sending PGP-encrypted
authorThomas Roessler <roessler@does-not-exist.org>
Thu, 27 Aug 1998 16:13:38 +0000 (16:13 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Thu, 27 Aug 1998 16:13:38 +0000 (16:13 +0000)
messages.  Hack by Liviu.

pgp.c
pgp.h
protos.h
send.c
sendlib.c

diff --git a/pgp.c b/pgp.c
index 28c1fac8ce6a1ae0f021526d9325b4be1dd842b2..35b17038aff9f089a630fc366015893060b88ac3 100644 (file)
--- a/pgp.c
+++ b/pgp.c
@@ -1181,6 +1181,8 @@ char *pgp_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
   return (keylist);
 }
 
+/* Warning: "a" is no longer free()d in this routine, you need
+ * to free() it later.  This is necessary for $fcc_attach. */
 BODY *pgp_encrypt_message (BODY *a, char *keylist, int sign)
 {
   char buf[LONG_STRING];
@@ -1305,14 +1307,11 @@ BODY *pgp_encrypt_message (BODY *a, char *keylist, int sign)
   t->parts->next->use_disp = 0;
   t->parts->next->unlink = 1; /* delete after sending the message */
 
-  mutt_free_body (&a); /* no longer needed! */
-
   return (t);
 }
 
-int pgp_protect (HEADER *msg)
+int pgp_protect (HEADER *msg, char **pgpkeylist)
 {
-  char *pgpkeylist = NULL;
   BODY *pbody = NULL;
 
   /* Do a quick check to make sure that we can find all of the encryption
@@ -1323,7 +1322,7 @@ int pgp_protect (HEADER *msg)
 
   if (msg->pgp & PGPENCRYPT)
   {
-    if ((pgpkeylist = pgp_findKeys (msg->env->to, msg->env->cc, msg->env->bcc)) == NULL)
+    if ((*pgpkeylist = pgp_findKeys (msg->env->to, msg->env->cc, msg->env->bcc)) == NULL)
       return (-1);
   }
 
@@ -1333,10 +1332,12 @@ int pgp_protect (HEADER *msg)
   endwin ();
   if (msg->pgp & PGPENCRYPT)
   {
-    pbody = pgp_encrypt_message (msg->content, pgpkeylist, msg->pgp & PGPSIGN);
-    safe_free ((void **) &pgpkeylist);
+    pbody = pgp_encrypt_message (msg->content, *pgpkeylist, msg->pgp & PGPSIGN);
     if (!pbody)
+    {
+      FREE (pgpkeylist);
       return (-1);
+    }
   }
   else if (msg->pgp & PGPSIGN)
   {
diff --git a/pgp.h b/pgp.h
index 06d3be9aa07bd70d263e26c996bc4050fadd723f..22d747c15f090de515f603e81e32da6159c6e432 100644 (file)
--- a/pgp.h
+++ b/pgp.h
@@ -153,7 +153,9 @@ WHERE short PgpTimeout;
 
 
 BODY *pgp_decrypt_part (BODY *, STATE *, FILE *);
+BODY *pgp_encrypt_message (BODY *, char *, int);
 BODY *pgp_make_key_attachment (char *);
+BODY *pgp_sign_message (BODY *);
 
 const char *pgp_pkalg_to_mic(const char *);
 
@@ -167,7 +169,7 @@ struct pgp_vinfo *pgp_get_vinfo(enum pgp_ops);
 int mutt_check_pgp (HEADER *h);
 int mutt_parse_pgp_hdr (char *, int);
 
-int pgp_protect (HEADER *);
+int pgp_protect (HEADER *, char **);
 int pgp_query (BODY *);
 int pgp_valid_passphrase (void);
 
index 0b6c1496bc12bc41220341b6550b2f17edf7c51f..9a9ed0b6103181df18d24d695854c221cec1af51 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -156,6 +156,7 @@ void mutt_normalize_time (struct tm *);
 void mutt_parse_mime_message (CONTEXT *ctx, HEADER *);
 void mutt_pipe_message_to_state (HEADER *, STATE *);
 void mutt_perror (const char *);
+void mutt_prepare_envelope (ENVELOPE *);
 void mutt_pretty_mailbox (char *);
 void mutt_pretty_size (char *, size_t, long);
 void mutt_print_message (HEADER *);
@@ -170,6 +171,7 @@ void mutt_select_fcc (char *, size_t, HEADER *);
 void mutt_select_file (char *, size_t, int);
 void mutt_send_hook (HEADER *);
 void mutt_set_flag (CONTEXT *, HEADER *, int, int);
+void mutt_set_followup_to (ENVELOPE *);
 void mutt_shell_escape (void);
 void mutt_show_error (void);
 void mutt_signal_init (void);
@@ -213,6 +215,7 @@ int mutt_get_field (char *, char *, size_t, int);
 int mutt_get_password (char *, char *, size_t);
 int mutt_get_postponed (CONTEXT *, HEADER *, HEADER **);
 int mutt_index_menu (int);
+int mutt_invoke_sendmail (ADDRESS *, ADDRESS *, ADDRESS *, const char *, int);
 int mutt_is_autoview (char *);
 int mutt_is_mail_list (ADDRESS *);
 int mutt_is_message_type(int, const char *);
@@ -242,7 +245,6 @@ int mutt_save_attachment (FILE *, BODY *, char *, int, HEADER *);
 int mutt_save_message (HEADER *, int, int, int *);
 int mutt_search_command (int, int);
 int mutt_send_menu (HEADER *, char *, size_t, HEADER *);
-int mutt_send_message (HEADER *, const char *);
 int mutt_strcmp (const char *, const char *);
 int mutt_thread_set_flag (HEADER *, int, int, int);
 int mutt_view_attachment (FILE*, BODY *, int);
diff --git a/send.c b/send.c
index 91dbf2c45fdbf248a4b018b3a15b7666143f8408..2a15e5320b1331b82ba0e7a49748b991070286ca 100644 (file)
--- a/send.c
+++ b/send.c
@@ -18,6 +18,7 @@
 
 #include "mutt.h"
 #include "mutt_curses.h"
+#include "rfc2047.h"
 #include "keymap.h"
 #include "mime.h"
 #include "mailbox.h"
 #include <sys/wait.h>
 #include <dirent.h>
 
-extern char RFC822Specials[];
-
-
-
-
 #ifdef _PGPPATH
 #include "pgp.h"
 #endif
@@ -713,7 +709,7 @@ generate_body (FILE *tempfp,        /* stream for outgoing message */
   return (0);
 }
 
-static void mutt_set_followup_to (ENVELOPE *e)
+void mutt_set_followup_to (ENVELOPE *e)
 {
   ADDRESS *t = NULL;
 
@@ -798,6 +794,58 @@ static ADDRESS *mutt_default_from (void)
   return (adr);
 }
 
+static int send_message (HEADER *msg)
+{  
+  char tempfile[_POSIX_PATH_MAX];
+  FILE *tempfp;
+  int i;
+
+  /* Write out the message in MIME form. */
+  mutt_mktemp (tempfile);
+  if ((tempfp = safe_fopen (tempfile, "w")) == NULL)
+    return (-1);
+
+  mutt_write_rfc822_header (tempfp, msg->env, msg->content, 0);
+  fputc ('\n', tempfp); /* tie off the header. */
+
+  if ((mutt_write_mime_body (msg->content, tempfp) == -1))
+  {
+    fclose(tempfp);
+    unlink (tempfile);
+    return (-1);
+  }
+  
+  if (fclose (tempfp) != 0)
+  {
+    mutt_perror (tempfile);
+    unlink (tempfile);
+    return (-1);
+  }
+
+  i = mutt_invoke_sendmail (msg->env->to, msg->env->cc, msg->env->bcc,
+                      tempfile, (msg->content->encoding == ENC8BIT));
+  return (i ? -1 : 0);
+}
+
+/* rfc2047 encode the content-descriptions */
+static void encode_descriptions (BODY *b)
+{
+  BODY *t;
+  char tmp[LONG_STRING];
+
+  for (t = b; t; t = t->next)
+  {
+    if (t->description)
+    {
+      rfc2047_encode_string (tmp, sizeof (tmp), (unsigned char *) t->description);
+      safe_free ((void **) &t->description);
+      t->description = safe_strdup (tmp);
+    }
+    if (t->parts)
+      encode_descriptions (t->parts);
+  }
+}
+
 void
 ci_send_message (int flags,            /* send mode */
                 HEADER *msg,           /* template to use for new message */
@@ -810,13 +858,13 @@ ci_send_message (int flags,               /* send mode */
   FILE *tempfp = NULL;
   BODY *pbody;
   int i, killfrom = 0;
-
-
-
 #ifdef _PGPPATH
+  BODY *save_content = NULL;
+  char *pgpkeylist = NULL;
   /* save current value of "pgp_sign_as" */
   char *signas = NULL;
   char *signmic = NULL;
+
   if (flags == SENDPOSTPONED)
   {
     signas = safe_strdup(PgpSignAs);
@@ -1132,12 +1180,13 @@ main_loop:
   if (msg->content->next)
     msg->content = mutt_make_multipart (msg->content);
 
-
-
 #ifdef _PGPPATH
   if (msg->pgp)
   {
-    if (pgp_protect (msg) != 0)
+    /* save the decrypted attachments */
+    save_content = msg->content;
+
+    if (pgp_protect (msg, &pgpkeylist) == -1)
     {
       if (msg->content->parts)
       {
@@ -1152,32 +1201,86 @@ main_loop:
   }
 #endif /* _PGPPATH */
 
+  if (!option (OPTNOCURSES) && ! (flags & SENDMAILX))
+    mutt_message ("Sending message...");
 
+  mutt_prepare_envelope (msg->env);
+  encode_descriptions (msg->content);
 
+  /* save a copy of the message, if necessary. */
   mutt_expand_path (fcc, sizeof (fcc));
+  if (strcmp ("/dev/null", fcc) != 0)
+  {
+    BODY *tmpbody = msg->content;
+#ifdef _PGPPATH
+    BODY *save_sig = NULL;
+    BODY *save_parts = NULL;
+#endif /* _PGPPATH */
 
-  if (!option (OPTNOCURSES) && ! (flags & SENDMAILX))
-    mutt_message ("Sending message...");
+    /* check to see if the user wants copies of all attachments */
+    if (!option (OPTFCCATTACH) && msg->content->type == TYPEMULTIPART)
+    {
+#ifdef _PGPPATH
+      if (strcmp (msg->content->subtype, "encrypted") == 0 ||
+         strcmp (msg->content->subtype, "signed") == 0)
+      {
+       if (save_content->type == TYPEMULTIPART)
+       {
+         if (!isendwin())
+           endwin ();
+         if (msg->pgp & PGPENCRYPT)
+         {
+           /* encrypt the main part again */
+           msg->content = pgp_encrypt_message (save_content->parts, 
+               pgpkeylist, msg->pgp & PGPSIGN);
+           /* not released in pgp_encrypt_message() */
+           mutt_free_body (&save_content->parts);
+           encode_descriptions (msg->content);
+           save_content->parts = msg->content;
+         }
+         else
+         {
+           /* save initial signature and attachments */
+           save_sig = msg->content->parts->next;
+           save_parts = msg->content->parts->parts->next;
+           /* sign the main part without attachments */
+           msg->content = pgp_sign_message (save_content->parts);
+           save_content = msg->content;
+         }
+       }
+      }
+      else
+#endif /* _PGPPATH */
+       msg->content = msg->content->parts;
+    }
 
-  if (msg->env->bcc && ! (msg->env->to || msg->env->cc))
-  {
-    /* some MTA's will put an Apparently-To: header field showing the Bcc:
-     * recipients if there is no To: or Cc: field, so attempt to suppress
-     * it by using an empty To: field.
-     */
-    msg->env->to = rfc822_new_address ();
-    msg->env->to->mailbox = safe_strdup ("undisclosed-recipients:;");
-    msg->env->to->group = 1;
-    msg->env->to->next = rfc822_new_address ();
-    buffer[0] = 0;
-    rfc822_cat (buffer, sizeof (buffer), msg->env->to->mailbox, RFC822Specials);
-    msg->env->to->mailbox = safe_strdup (buffer);
+    if (msg->content)
+      mutt_write_fcc (fcc, msg, NULL, 0);
+    msg->content = tmpbody;
+#ifdef _PGPPATH
+    if (save_sig)
+    {
+      /* cleanup the second signature structures */
+      mutt_free_body (&save_content->parts->next);
+      save_content->parts = NULL;
+      mutt_free_body (&save_content);
+      /* restore old signature and attachments */
+      msg->content->parts->next = save_sig;
+      msg->content->parts->parts->next = save_parts;
+    }
+#endif /* _PGPPATH */
   }
 
-  mutt_set_followup_to (msg->env);
+#ifdef _PGPPATH
+  if (msg->pgp & PGPENCRYPT)
+  {
+    /* cleanup structures from the first encryption */
+    mutt_free_body (&save_content);
+    FREE (&pgpkeylist);
+  }
+#endif /* _PGPPATH */
 
-  if (mutt_send_message (msg, fcc) == -1)
+  if (send_message (msg) == -1)
   {
     msg->content = remove_multipart (msg->content);
     goto main_loop;
@@ -1233,9 +1336,8 @@ cleanup:
   }
 #endif /* _PGPPATH */
    
-
-
   if (tempfp)
     fclose (tempfp);
   mutt_free_header (&msg);
+
 }
index 52ec8fb2191b6bfc7ca94bec4764fedd15e6d2f5..4bf9a5c14bc19e066625e027fc981b8bab707134 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
@@ -38,6 +38,8 @@
 #include <sysexits.h>
 #endif
 
+extern char RFC822Specials[];
+
 static struct sysexits
 {
   int v;
@@ -1277,25 +1279,6 @@ static void encode_headers (LIST *h)
   }
 }
 
-/* rfc2047 encode the content-descriptions */
-static void encode_descriptions (BODY *b)
-{
-  BODY *t;
-  char tmp[LONG_STRING];
-
-  for (t = b; t; t = t->next)
-  {
-    if (t->description)
-    {
-      rfc2047_encode_string (tmp, sizeof (tmp), (unsigned char *) t->description);
-      safe_free ((void **) &t->description);
-      t->description = safe_strdup (tmp);
-    }
-    if (t->parts)
-      encode_descriptions (t->parts);
-  }
-}
-
 const char *mutt_fqdn(short may_hide_host)
 {
   char *p = NULL, *q;
@@ -1547,8 +1530,8 @@ strsysexit(int e)
 }
 
 
-static int
-invoke_sendmail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */
+int
+mutt_invoke_sendmail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */
                 const char *msg, /* file containing message */
                 int eightbit) /* message contains 8bit chars */
 {
@@ -1677,74 +1660,46 @@ char *mutt_quote_string (const char *s)
   return (r);
 }
 
-int mutt_send_message (HEADER *msg, const char *fcc)
+void mutt_prepare_envelope (ENVELOPE *env)
 {
-  char tempfile[_POSIX_PATH_MAX], buffer[STRING];
-  FILE *tempfp;
-  int i;
+  char buffer[LONG_STRING];
 
-  /* Take care of 8-bit => 7-bit conversion. */
-  rfc2047_encode_adrlist (msg->env->to);
-  rfc2047_encode_adrlist (msg->env->cc);
-  rfc2047_encode_adrlist (msg->env->from);
-  rfc2047_encode_adrlist (msg->env->mail_followup_to);
-  if (msg->env->subject)
+  if (env->bcc && !(env->to || env->cc))
   {
-    rfc2047_encode_string (buffer, sizeof (buffer) - 1,
-                          (unsigned char *) msg->env->subject);
-    safe_free ((void **) &msg->env->subject);
-    msg->env->subject = safe_strdup (buffer);
+    /* some MTA's will put an Apparently-To: header field showing the Bcc:
+     * recipients if there is no To: or Cc: field, so attempt to suppress
+     * it by using an empty To: field.
+     */
+    env->to = rfc822_new_address ();
+    env->to->mailbox = safe_strdup ("undisclosed-recipients:;");
+    env->to->group = 1;
+    env->to->next = rfc822_new_address ();
+    buffer[0] = 0;
+    rfc822_cat (buffer, sizeof (buffer), env->to->mailbox, RFC822Specials);
+    env->to->mailbox = safe_strdup (buffer);
   }
-  encode_headers (msg->env->userhdrs);
-  encode_descriptions (msg->content);
 
-  if (!msg->env->message_id)
-    msg->env->message_id = mutt_gen_msgid ();
+  mutt_set_followup_to (env);
 
-  /* Write out the message in MIME form. */
-  mutt_mktemp (tempfile);
-  if ((tempfp = safe_fopen (tempfile, "w")) == NULL)
-    return (-1);
-
-  mutt_write_rfc822_header (tempfp, msg->env, msg->content, 0);
-  fputc ('\n', tempfp); /* tie off the header. */
-
-  if ((mutt_write_mime_body (msg->content, tempfp) == -1))
-  {
-    fclose(tempfp);
-    unlink (tempfile);
-    return (-1);
-  }
-  
-  if (fclose (tempfp) != 0)
-  {
-    mutt_perror (tempfile);
-    unlink (tempfile);
-    return (-1);
-  }
-
-  /* save a copy of the message, if necessary. */
-  if (*fcc && strcmp ("/dev/null", fcc) != 0)
+  /* Take care of 8-bit => 7-bit conversion. */
+  rfc2047_encode_adrlist (env->to);
+  rfc2047_encode_adrlist (env->cc);
+  rfc2047_encode_adrlist (env->from);
+  rfc2047_encode_adrlist (env->mail_followup_to);
+  if (env->subject)
   {
-    BODY *tmpbody = msg->content;
-
-    /* check to see if the user wants copies of all attachments */
-    if (msg->content->type == TYPEMULTIPART &&
-       strcmp (msg->content->subtype, "encrypted") &&
-       strcmp (msg->content->subtype, "signed") &&
-       !option (OPTFCCATTACH))
-      msg->content = msg->content->parts;
-
-    mutt_write_fcc (fcc, msg, NULL, 0);
-    msg->content = tmpbody;
+    rfc2047_encode_string (buffer, sizeof (buffer) - 1,
+                          (unsigned char *) env->subject);
+    safe_free ((void **) &env->subject);
+    env->subject = safe_strdup (buffer);
   }
+  encode_headers (env->userhdrs);
 
-  i = invoke_sendmail (msg->env->to, msg->env->cc, msg->env->bcc,
-                      tempfile,
-                      (msg->content->encoding == ENC8BIT));
-  return (i ? -1 : 0);
+  if (!env->message_id)
+    env->message_id = mutt_gen_msgid ();
 }
-
+  
 void mutt_bounce_message (HEADER *h, ADDRESS *to)
 {
   int i;
@@ -1779,7 +1734,7 @@ void mutt_bounce_message (HEADER *h, ADDRESS *to)
       mutt_copy_bytes (msg->fp, f, h->content->length);
       fclose (f);
 
-      invoke_sendmail (to, NULL, NULL, tempfile, h->content->encoding == ENC8BIT);
+      mutt_invoke_sendmail (to, NULL, NULL, tempfile, h->content->encoding == ENC8BIT);
     }
     mx_close_message (&msg);
   }