internal cleanups and reworked the preview decryption
authorWerner Koch <wk@gnupg.org>
Thu, 1 Dec 2005 19:24:32 +0000 (19:24 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 1 Dec 2005 19:24:32 +0000 (19:24 +0000)
src/ChangeLog
src/display.cpp
src/display.h
src/engine-gpgme.c
src/engine.h
src/gpgmsg.cpp
src/gpgmsg.hh
src/olflange.cpp
src/olflange.h
src/pgpmime.c
src/pgpmime.h

index 99577c9..a3ec1fa 100644 (file)
@@ -1,3 +1,28 @@
+2005-12-01  Werner Koch  <wk@g10code.com>
+
+       * engine-gpgme.c (op_decrypt_stream_to_gpgme, decrypt_stream) 
+       (op_decrypt): Add arg PREVIEW_MODE.
+       * pgpmime.c (pgpmime_decrypt): New arg PREVIEW_MODE.
+       (struct pgpmime_context): New field PREVIEW.
+       (message_cb, plaintext_handler): Handle preview mode.
+       * gpgmsg.cpp (class GpgMsgImpl): Renamed SILENT to PREVIEW.
+       (setSilent): Renamed to ..
+       (setPreview): .. this.
+       (decrypt): Handle preview mode.  Display a string while decrypting
+       PGP/MIME messages.
+
+       * display.cpp (update_display): New arg TEXT.
+       * gpgmsg.cpp (class GpgMsgImpl): Removed BODY_PLAIN and BODY.
+       (getDisplayText): Removed.
+       (loadBody): Changes to return the allocated body.
+       (getOrigText): Removed.
+       (getMessageType): Rewritten to take the body text as argument.
+       (decrypt): Pass plaintext directly to update_display.  Free
+       plaintext.
+       (sign, encrypt_and_sign): Likewise.
+
+       * olflange.cpp (OnWriteComplete): Always delete PR_BODY on error.
+
 2005-11-30  Werner Koch  <wk@g10code.com>
 
        * gpgmsg.cpp: Made more strings translatable.
index 0465100..e8699a9 100644 (file)
@@ -129,45 +129,46 @@ find_message_window (HWND parent)
 }
 
 
-/* Update the display using the message MSG.  Return 0 on success. */
+/* Update the display with TEXT using the message MSG.  Return 0 on
+   success. */
 int
-update_display (HWND hwnd, GpgMsg *msg, void *exchange_cb, bool is_html)
+update_display (HWND hwnd, GpgMsg *msg, void *exchange_cb, 
+                bool is_html, const char *text)
 {
   HWND window;
 
   window = find_message_window (hwnd);
   if (window)
     {
-      const char *string, *s;
+      const char *s;
 
       log_debug ("%s:%s: window handle %p\n", SRCNAME, __func__, window);
-      string = msg->getDisplayText ();
       
       /* Decide whether we need to use the Unicode version. */
-      for (s=string; *s && !(*s & 0x80); s++)
+      for (s=text; *s && !(*s & 0x80); s++)
         ;
       if (*s)
         {
-          wchar_t *tmp = utf8_to_wchar (string);
+          wchar_t *tmp = utf8_to_wchar (text);
           SetWindowTextW (window, tmp);
           xfree (tmp);
         }
       else
-        SetWindowTextA (window, string);
+        SetWindowTextA (window, text);
       log_debug ("%s:%s: window text is now `%s'",
-                 SRCNAME, __func__, string);
+                 SRCNAME, __func__, text);
       return 0;
     }
   else if (exchange_cb && !opt.compat.no_oom_write)
     {
       log_debug ("updating display using OOM");
       return put_outlook_property (exchange_cb, is_html? "HTMLBody":"Body",
-                                   msg->getDisplayText ());
+                                   text);
     }
   else
     {
-      log_debug ("%s: window handle not found for parent %p\n",
-                 __func__, hwnd);
+      log_debug ("%s:%s: window handle not found for parent %p\n",
+                 SRCNAME, __func__, hwnd);
       return -1;
     }
 }
@@ -180,7 +181,7 @@ set_message_body (LPMESSAGE message, const char *string, bool is_html)
 {
   HRESULT hr;
   SPropValue prop;
-  SPropTagArray proparray;
+  //SPropTagArray proparray;
   const char *s;
   
   assert (message);
index 8ba19dd..270ea52 100644 (file)
@@ -28,7 +28,8 @@ int is_html_body (const char *body);
 
 char *add_html_line_endings (const char *body);
 
-int update_display (HWND hwnd, GpgMsg *msg, void *exchange_cb, bool is_html);
+int update_display (HWND hwnd, GpgMsg *msg, void *exchange_cb,
+                    bool is_html, const char *text);
 
 int set_message_body (LPMESSAGE message, const char *string, bool is_html);
 
index cef7912..aa27ca9 100644 (file)
@@ -486,7 +486,7 @@ op_sign_stream (LPSTREAM instream, LPSTREAM outstream, int mode,
    signature verification will get printed to it. */
 int 
 op_decrypt (const char *inbuf, char **outbuf, int ttl, const char *filename,
-            gpgme_data_t attestation)
+            gpgme_data_t attestation, int preview_mode)
 {
   struct decrypt_key_s dk;
   gpgme_data_t in = NULL;
@@ -513,12 +513,17 @@ op_decrypt (const char *inbuf, char **outbuf, int ttl, const char *filename,
 
   gpgme_set_passphrase_cb (ctx, passphrase_callback_box, &dk);
   dk.ctx = ctx;
-  err = gpgme_op_decrypt_verify (ctx, in, out);
+  if (preview_mode)
+    err = gpgme_op_decrypt (ctx, in, out);
+  else
+    err = gpgme_op_decrypt_verify (ctx, in, out);
   dk.ctx = NULL;
   update_passphrase_cache (err, &dk);
 
   /* Act upon the result of the decryption operation. */
-  if (!err) 
+  if (!err && preview_mode) 
+    ;
+  else if (!err) 
     {
       /* Decryption succeeded.  Store the result at OUTBUF. */
       gpgme_verify_result_t res;
@@ -577,7 +582,8 @@ leave:
    will get printed to it. */
 static int
 decrypt_stream (gpgme_data_t in, gpgme_data_t out, int ttl,
-                const char *filename, gpgme_data_t attestation)
+                const char *filename, gpgme_data_t attestation, 
+                int preview_mode)
 {    
   struct decrypt_key_s dk;
   gpgme_ctx_t ctx = NULL;
@@ -592,11 +598,16 @@ decrypt_stream (gpgme_data_t in, gpgme_data_t out, int ttl,
 
   gpgme_set_passphrase_cb (ctx, passphrase_callback_box, &dk);
   dk.ctx = ctx;
-  err = gpgme_op_decrypt_verify (ctx, in, out);
+  if (preview_mode)
+    err = gpgme_op_decrypt (ctx, in, out);
+  else
+    err = gpgme_op_decrypt_verify (ctx, in, out);
   dk.ctx = NULL;
   update_passphrase_cache (err, &dk);
   /* Act upon the result of the decryption operation. */
-  if (!err) 
+  if (!err && preview_mode) 
+    ;
+  else if (!err) 
     {
       gpgme_verify_result_t res;
 
@@ -656,7 +667,7 @@ op_decrypt_stream (LPSTREAM instream, LPSTREAM outstream, int ttl,
   if (!err)
     err = gpgme_data_new_from_cbs (&out, &cbs, outstream);
   if (!err)
-    err = decrypt_stream (in, out, ttl, filename, attestation);
+    err = decrypt_stream (in, out, ttl, filename, attestation, 0);
 
   if (in)
     gpgme_data_release (in);
@@ -689,7 +700,7 @@ op_decrypt_stream_to_buffer (LPSTREAM instream, char **outbuf, int ttl,
   if (!err)
     err = gpgme_data_new (&out);
   if (!err)
-    err = decrypt_stream (in, out, ttl, filename, attestation);
+    err = decrypt_stream (in, out, ttl, filename, attestation, 0);
   if (!err)
     {
       /* Return the buffer but first make sure it is a string. */
@@ -714,7 +725,8 @@ op_decrypt_stream_to_buffer (LPSTREAM instream, char **outbuf, int ttl,
    outputs. */
 int
 op_decrypt_stream_to_gpgme (LPSTREAM instream, gpgme_data_t out, int ttl,
-                            const char *filename, gpgme_data_t attestation)
+                            const char *filename, gpgme_data_t attestation,
+                            int preview_mode)
 {
   struct gpgme_data_cbs cbs;
   gpgme_data_t in = NULL;
@@ -725,7 +737,7 @@ op_decrypt_stream_to_gpgme (LPSTREAM instream, gpgme_data_t out, int ttl,
 
   err = gpgme_data_new_from_cbs (&in, &cbs, instream);
   if (!err)
-    err = decrypt_stream (in, out, ttl, filename, attestation);
+    err = decrypt_stream (in, out, ttl, filename, attestation, preview_mode);
 
   if (in)
     gpgme_data_release (in);
index 746321e..d082fcb 100644 (file)
@@ -57,15 +57,16 @@ int op_sign_stream (LPSTREAM instream, LPSTREAM outstream, int mode,
                     gpgme_key_t sign_key, int ttl);
 
 int op_decrypt (const char *inbuf, char **outbuf, int ttl,
-                const char *filename, gpgme_data_t attestation);
+                const char *filename, gpgme_data_t attestation, 
+                int preview_mode);
 int op_decrypt_stream (LPSTREAM instream, LPSTREAM outstream, int ttl,
                        const char *filename, gpgme_data_t attestation);
 int op_decrypt_stream_to_buffer (LPSTREAM instream, char **outbuf, int ttl,
                                  const char *filename,
                                  gpgme_data_t attestation);
 int op_decrypt_stream_to_gpgme (LPSTREAM instream, gpgme_data_t out, int ttl,
-                                const char *filename,
-                                gpgme_data_t attestation);
+                                const char *filename, gpgme_data_t attestation,
+                                int preview_mode);
 
 int op_verify (const char *inbuf, char **outbuf, const char *filename,
                gpgme_data_t attestation);
index ca8c83b..6bcf65b 100644 (file)
@@ -98,11 +98,9 @@ public:
   {
     message = NULL;
     exchange_cb = NULL;
-    body = NULL;
-    body_plain = NULL;
     is_pgpmime = false;
     has_attestation = false;
-    silent = false;
+    preview = false;
 
     attestation = NULL;
 
@@ -114,8 +112,6 @@ public:
   {
     if (message)
       message->Release ();
-    xfree (body);
-    xfree (body_plain);
 
     if (attestation)
       gpgme_data_release (attestation);
@@ -162,15 +158,13 @@ public:
     exchange_cb = cb;
   }
   
-  void setSilent (bool value)
+  void setPreview (bool value)
   {
-    silent = value;
+    preview = value;
   }
 
-  openpgp_t getMessageType (void);
+  openpgp_t getMessageType (const char *s);
   bool hasAttachments (void);
-  const char *getOrigText (bool want_html);
-  const char *GpgMsgImpl::getDisplayText (void);
   const char *getPlainText (void);
 
   int decrypt (HWND hwnd);
@@ -200,12 +194,10 @@ public:
 private:
   LPMESSAGE message;  /* Pointer to the message. */
   void *exchange_cb;  /* Call back used with the display function. */
-  char *body;         /* utf-8 encoded body string or NULL. */
-  char *body_plain;   /* Plaintext version of BODY or NULL. */
   bool is_pgpmime;    /* True if the message is a PGP/MIME encrypted one. */
   bool has_attestation;/* True if we found an attestation attachment. */
-  bool silent;        /* Don't pop up message boxes.  Currently this
-                         is only used with decryption.  */
+  bool preview;       /* Don't pop up message boxes and run only a
+                         body decryption. */
 
   /* If not NULL, collect attestation information here. */
   gpgme_data_t attestation;
@@ -218,7 +210,7 @@ private:
     LPSRowSet   rows;     /* The retrieved set of rows from the table. */
   } attach;
   
-  void loadBody (bool want_html);
+  char *loadBody (bool want_html);
   bool isPgpmimeVersionPart (int pos);
   void writeAttestation (void);
   attach_info_t gatherAttachmentInfo (void);
@@ -363,9 +355,9 @@ text_from_attach_info (attach_info_t table, const char *format,
 
 
 \f
-/* Load the body and make it available as an UTF8 string in the
-   instance variable BODY.  */
-void
+/* Load the body from the MAP and return it as an UTF8 string.
+   Returns NULL on error.  */
+char *
 GpgMsgImpl::loadBody (bool want_html)
 {
   HRESULT hr;
@@ -374,9 +366,10 @@ GpgMsgImpl::loadBody (bool want_html)
 //   SPropValue prop;
   STATSTG statInfo;
   ULONG nread;
+  char *body = NULL;
 
-  if (body || !message)
-    return;
+  if (!message)
+    return NULL;
 
   hr = HrGetOneProp ((LPMAPIPROP)message,
                      want_html? PR_BODY_HTML : PR_BODY, &lpspvFEID);
@@ -418,7 +411,7 @@ GpgMsgImpl::loadBody (bool want_html)
                 goto ready;
             }
           
-          return;
+          return NULL;
         }
       
       hr = stream->Stat (&statInfo, STATFLAG_NONAME);
@@ -426,7 +419,7 @@ GpgMsgImpl::loadBody (bool want_html)
         {
           log_debug ("%s:%s: Stat failed: hr=%#lx", SRCNAME, __func__, hr);
           stream->Release ();
-          return;
+          return NULL;
         }
       
       /* Fixme: We might want to read only the first 1k to decide
@@ -439,9 +432,8 @@ GpgMsgImpl::loadBody (bool want_html)
         {
           log_debug ("%s:%s: Read failed: hr=%#lx", SRCNAME, __func__, hr);
           xfree (body);
-          body = NULL;
           stream->Release ();
-          return;
+          return NULL;
         }
       body[nread] = 0;
       body[nread+1] = 0;
@@ -449,13 +441,12 @@ GpgMsgImpl::loadBody (bool want_html)
         {
           log_debug ("%s:%s: not enough bytes returned\n", SRCNAME, __func__);
           xfree (body);
-          body = NULL;
           stream->Release ();
-          return;
+          return NULL;
         }
       stream->Release ();
       
-      /* FIXME: We need to optimize this. */
+      /* FIXME: We should to optimize this. */
       {
         char *tmp;
         tmp = wchar_to_utf8 ((wchar_t*)body);
@@ -481,6 +472,7 @@ GpgMsgImpl::loadBody (bool want_html)
 //   if (FAILED (hr))
 //     log_debug ("%s:%s: updating message access to 0x%08lx failed: hr=%#lx",
 //                    SRCNAME, __func__, prop.Value.l, hr);
+  return body;
 }
 
 
@@ -561,60 +553,31 @@ set_subject (LPMESSAGE obj, const char *string)
 #endif
 
 
-/* Return the type of a message. */
+/* Return the type of a message with the body text in TEXT. */
 openpgp_t
-GpgMsgImpl::getMessageType (void)
+GpgMsgImpl::getMessageType (const char *text)
 {
   const char *s;
-  
-  loadBody (false);
-  
-  if (!body || !(s = strstr (body, "BEGIN PGP ")))
+
+  if (!text || !(s = strstr (text, "BEGIN PGP ")))
     return OPENPGP_NONE;
 
   /* (The extra strstr() above is just a simple optimization.) */
-  if (strstr (body, "BEGIN PGP MESSAGE"))
+  if (strstr (text, "BEGIN PGP MESSAGE"))
     return OPENPGP_MSG;
-  else if (strstr (body, "BEGIN PGP SIGNED MESSAGE"))
+  else if (strstr (text, "BEGIN PGP SIGNED MESSAGE"))
     return OPENPGP_CLEARSIG;
-  else if (strstr (body, "BEGIN PGP SIGNATURE"))
+  else if (strstr (text, "BEGIN PGP SIGNATURE"))
     return OPENPGP_SIG;
-  else if (strstr (body, "BEGIN PGP PUBLIC KEY"))
+  else if (strstr (text, "BEGIN PGP PUBLIC KEY"))
     return OPENPGP_PUBKEY;
-  else if (strstr (body, "BEGIN PGP PRIVATE KEY"))
+  else if (strstr (text, "BEGIN PGP PRIVATE KEY"))
     return OPENPGP_SECKEY;
   else
     return OPENPGP_NONE;
 }
 
 
-/* Return the body text as received or composed.  This is guaranteed
-   to never return NULL.  */
-const char *
-GpgMsgImpl::getOrigText (bool want_html)
-{
-  loadBody (want_html);
-  
-  return body? body : "";
-}
-
-
-/* Return the text of the message to be used for the display.  The
-   message objects has intrinsic knowledge about the correct text.  */
-const char *
-GpgMsgImpl::getDisplayText (void)
-{
-  loadBody (false);
-
-  if (body_plain)
-    return body_plain;
-  else if (body)
-    return body;
-  else
-    return "";
-}
-
-
 
 /* Return an array of strings with the recipients of the message. On
    success a malloced array is returned containing allocated strings
@@ -857,7 +820,7 @@ GpgMsgImpl::writeAttestation (void)
 
 
 /* Decrypt the message MSG and update the window.  HWND identifies the
-   current window. */
+   current window.  */
 int 
 GpgMsgImpl::decrypt (HWND hwnd)
 {
@@ -872,8 +835,12 @@ GpgMsgImpl::decrypt (HWND hwnd)
   unsigned int n_signed = 0;
   HRESULT hr;
   int pgpmime_succeeded = 0;
+  char *body;
 
-  mtype = getMessageType ();
+  /* Load the body text into BODY.  Note that body may be NULL but in
+     this case MTYPE will be OPENPGP_NONE. */
+  body = loadBody (false);
+  mtype = getMessageType (body);
 
   /* Check whether this possibly encrypted message has encrypted
      attachments.  We check right now because we need to get into the
@@ -915,20 +882,20 @@ GpgMsgImpl::decrypt (HWND hwnd)
       if (!opt.compat.old_reply_hack
           && (s = msgcache_get_from_mapi (message, &refhandle)))
         {
-          xfree (body_plain);
-          body_plain = xstrdup (s);
-          update_display (hwnd, this, exchange_cb, is_html_body (s));
+          update_display (hwnd, this, exchange_cb, is_html_body (s), s);
           msgcache_unref (refhandle);
           log_debug ("%s:%s: leave (already decrypted)\n", SRCNAME, __func__);
         }
       else
         {
-          MessageBox (hwnd, _("No valid OpenPGP data found."),
-                      _("Decryption"), MB_ICONWARNING|MB_OK);
+          if (!preview)
+            MessageBox (hwnd, _("No valid OpenPGP data found."),
+                        _("Decryption"), MB_ICONWARNING|MB_OK);
           log_debug ("%s:%s: leave (no OpenPGP data)\n", SRCNAME, __func__);
         }
       
       release_attach_info (table);
+      xfree (body);
       return 0;
     }
 
@@ -942,10 +909,9 @@ GpgMsgImpl::decrypt (HWND hwnd)
       log_debug ("%s:%s: we already have an attestation\n",
                  SRCNAME, __func__);
     }
-  else if (!attestation && !opt.compat.no_attestation)
+  else if (!attestation && !opt.compat.no_attestation && !preview)
     gpgme_data_new (&attestation);
   
-
   /* Process according to type of message. */
   if (is_pgpmime)
     {
@@ -953,15 +919,25 @@ GpgMsgImpl::decrypt (HWND hwnd)
       int method;
       LPSTREAM from;
       
+      /* If there is no body text (this should be the case for
+         PGP/MIME), display a message to indicate that this is such a
+         message.  This is useful in case of such messages with
+         longish attachments which might take long to decrypt. */
+      if (!body || !*body)
+        update_display (hwnd, this, exchange_cb, 0, 
+                        _("[This is a PGP/MIME message]"));        
+
       hr = message->OpenAttach (1, NULL, MAPI_BEST_ACCESS, &att);      
       if (FAILED (hr))
         {
           log_error ("%s:%s: can't open PGP/MIME attachment 2: hr=%#lx",
                      SRCNAME, __func__, hr);
-          MessageBox (hwnd, _("Problem decrypting PGP/MIME message"),
-                      _("Decryption"), MB_ICONERROR|MB_OK);
+          if (!preview)
+            MessageBox (hwnd, _("Problem decrypting PGP/MIME message"),
+                        _("Decryption"), MB_ICONERROR|MB_OK);
           log_debug ("%s:%s: leave (PGP/MIME problem)\n", SRCNAME, __func__);
           release_attach_info (table);
+          xfree (body);
           return gpg_error (GPG_ERR_GENERAL);
         }
 
@@ -970,11 +946,13 @@ GpgMsgImpl::decrypt (HWND hwnd)
         {
           log_error ("%s:%s: unsupported method %d for PGP/MIME attachment 2",
                      SRCNAME, __func__, method);
-          MessageBox (hwnd, _("Problem decrypting PGP/MIME message"),
-                      _("Decryption"), MB_ICONERROR|MB_OK);
+          if (!preview)
+            MessageBox (hwnd, _("Problem decrypting PGP/MIME message"),
+                        _("Decryption"), MB_ICONERROR|MB_OK);
           log_debug ("%s:%s: leave (bad PGP/MIME method)\n",SRCNAME,__func__);
           att->Release ();
           release_attach_info (table);
+          xfree (body);
           return gpg_error (GPG_ERR_GENERAL);
         }
 
@@ -984,27 +962,34 @@ GpgMsgImpl::decrypt (HWND hwnd)
         {
           log_error ("%s:%s: can't open data of attachment 2: hr=%#lx",
                      SRCNAME, __func__, hr);
-          MessageBox (hwnd, _("Problem decrypting PGP/MIME message"),
-                      _("Decryption"), MB_ICONERROR|MB_OK);
+          if (!preview)
+            MessageBox (hwnd, _("Problem decrypting PGP/MIME message"),
+                        _("Decryption"), MB_ICONERROR|MB_OK);
           log_debug ("%s:%s: leave (OpenProperty failed)\n",SRCNAME,__func__);
           att->Release ();
           release_attach_info (table);
+          xfree (body);
           return gpg_error (GPG_ERR_GENERAL);
         }
 
       err = pgpmime_decrypt (from, opt.passwd_ttl, &plaintext, attestation,
-                             hwnd);
+                             hwnd, preview);
       
       from->Release ();
       att->Release ();
       if (!err)
         pgpmime_succeeded = 1;
     }
-  else if (mtype == OPENPGP_CLEARSIG)
-    err = op_verify (getOrigText (false), NULL, NULL, attestation);
-  else if (*getOrigText(false))
-    err = op_decrypt (getOrigText (false), &plaintext, opt.passwd_ttl,
-                      NULL, attestation);
+  else if (mtype == OPENPGP_CLEARSIG )
+    {
+      assert (body);
+      err = preview? 0 : op_verify (body, NULL, NULL, attestation);
+    }
+  else if (body && *body)
+    {
+      err = op_decrypt (body, &plaintext, opt.passwd_ttl, NULL,
+                        attestation, preview);
+    }
   else
     err = gpg_error (GPG_ERR_NO_DATA);
   if (err)
@@ -1014,7 +999,7 @@ GpgMsgImpl::decrypt (HWND hwnd)
       else if (mtype == OPENPGP_CLEARSIG)
         MessageBox (hwnd, op_strerror (err),
                     _("Verification Failure"), MB_ICONERROR|MB_OK);
-      else
+      else if (!preview)
         MessageBox (hwnd, op_strerror (err),
                     _("Decryption Failure"), MB_ICONERROR|MB_OK);
     }
@@ -1036,12 +1021,11 @@ GpgMsgImpl::decrypt (HWND hwnd)
       if (opt.compat.old_reply_hack)
         set_message_body (message, plaintext, is_html);
 
-      xfree (body_plain);
-      body_plain = plaintext;
-      plaintext = NULL;
-      msgcache_put (body_plain, 0, message);
+      msgcache_put (plaintext, 0, message);
 
-      if (opt.save_decrypted_attach)
+      if (preview)
+        update_display (hwnd, this, exchange_cb, is_html, plaintext);
+      else if (opt.save_decrypted_attach)
         {
           /* User wants us to replace the encrypted message with the
              plaintext version. */
@@ -1049,10 +1033,10 @@ GpgMsgImpl::decrypt (HWND hwnd)
           if (FAILED (hr))
             log_debug ("%s:%s: SaveChanges failed: hr=%#lx",
                        SRCNAME, __func__, hr);
-          update_display (hwnd, this, exchange_cb, is_html);
+          update_display (hwnd, this, exchange_cb, is_html, plaintext);
           
         }
-      else if (!silent && update_display (hwnd, this, exchange_cb, is_html)) 
+      else if (update_display (hwnd, this, exchange_cb, is_html, plaintext))
         {
           const char *s = 
             _("The message text cannot be displayed.\n"
@@ -1078,7 +1062,7 @@ GpgMsgImpl::decrypt (HWND hwnd)
   /* If we have signed attachments.  Ask whether the signatures should
      be verified; we do this is case of large attachments where
      verification might take long. */
-  if (!silent && n_signed && !pgpmime_succeeded)
+  if (!preview && n_signed && !pgpmime_succeeded)
     {
       /* TRANSLATORS: Keep the @LIST@ verbatim on a separate line; it
          will be expanded to a list of atatchment names. */
@@ -1104,7 +1088,7 @@ GpgMsgImpl::decrypt (HWND hwnd)
         }
     }
 
-  if (!silent && n_encrypted && !pgpmime_succeeded)
+  if (!preview && n_encrypted && !pgpmime_succeeded)
     {
       /* TRANSLATORS: Keep the @LIST@ verbatim on a separate line; it
          will be expanded to a list of atatchment names. */
@@ -1127,9 +1111,12 @@ GpgMsgImpl::decrypt (HWND hwnd)
         }
     }
 
-  writeAttestation ();
+  if (!preview)
+    writeAttestation ();
 
   release_attach_info (table);
+  xfree (plaintext);
+  xfree (body);
   log_debug ("%s:%s: leave (rc=%d)\n", SRCNAME, __func__, err);
   return err;
 }
@@ -1143,7 +1130,7 @@ int
 GpgMsgImpl::sign (HWND hwnd)
 {
   HRESULT hr;
-  const char *plaintext;
+  char *plaintext;
   char *signedtext = NULL;
   int err = 0;
   gpgme_key_t sign_key = NULL;
@@ -1153,9 +1140,11 @@ GpgMsgImpl::sign (HWND hwnd)
   
   /* We don't sign an empty body - a signature on a zero length string
      is pretty much useless. */
-  if (!*(plaintext = getOrigText (false)) && !hasAttachments ()) 
+  plaintext = loadBody (false);
+  if ( (!plaintext || !*plaintext) && !hasAttachments ()) 
     {
       log_debug ("%s:%s: leave (empty)", SRCNAME, __func__);
+      xfree (plaintext);
       return 0; 
     }
 
@@ -1163,10 +1152,11 @@ GpgMsgImpl::sign (HWND hwnd)
   if (signer_dialog_box (&sign_key, NULL, 0) == -1)
     {
       log_debug ("%s.%s: leave (dialog failed)\n", SRCNAME, __func__);
+      xfree (plaintext);
       return gpg_error (GPG_ERR_CANCELED);  
     }
 
-  if (*plaintext)
+  if (plaintext && *plaintext)
     {
       err = op_sign (plaintext, &signedtext, 
                      OP_SIG_CLEAR, sign_key, opt.passwd_ttl);
@@ -1194,7 +1184,7 @@ GpgMsgImpl::sign (HWND hwnd)
 
   /* Now that we successfully processed the attachments, we can save
      the changes to the body.  */
-  if (*plaintext)
+  if (plaintext && *plaintext)
     {
       err = set_message_body (message, signedtext, 0);
       if (err)
@@ -1226,6 +1216,7 @@ GpgMsgImpl::sign (HWND hwnd)
  leave:
   xfree (signedtext);
   gpgme_key_release (sign_key);
+  xfree (plaintext);
   log_debug ("%s:%s: leave (err=%s)\n", SRCNAME, __func__, op_strerror (err));
   return err;
 }
@@ -1234,7 +1225,7 @@ GpgMsgImpl::sign (HWND hwnd)
 \f
 /* Encrypt and optionally sign (if SIGN_FLAG is true) the entire
    message including all attachments.  If WANT_HTML is true, the text
-   to encrypt will be taken from the html property. Returns 0 on
+   to encrypt will also be taken from the html property. Returns 0 on
    success. */
 int 
 GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
@@ -1243,7 +1234,7 @@ GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
   HRESULT hr;
   gpgme_key_t *keys = NULL;
   gpgme_key_t sign_key = NULL;
-  const char *plaintext;
+  char *plaintext;
   char *ciphertext = NULL;
   char **recipients = NULL;
   char **unknown = NULL;
@@ -1251,10 +1242,11 @@ GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
   size_t n_keys, n_unknown, n_recp;
   SPropValue prop;
     
-  
-  if (!*(plaintext = getOrigText (want_html)) && !hasAttachments ()) 
+  plaintext = loadBody (false);
+  if ( (!plaintext || !*plaintext) && !hasAttachments ()) 
     {
       log_debug ("%s:%s: leave (empty)", SRCNAME, __func__);
+      xfree (plaintext);
       return 0; 
     }
 
@@ -1264,6 +1256,7 @@ GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
       if (signer_dialog_box (&sign_key, NULL, 1) == -1)
         {
           log_debug ("%s.%s: leave (dialog failed)\n", SRCNAME, __func__);
+          xfree (plaintext);
           return gpg_error (GPG_ERR_CANCELED);  
         }
     }
@@ -1311,7 +1304,7 @@ GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
                    i, keyid_from_key (keys[i]), userid_from_key (keys[i]));
     }
 
-  if (*plaintext)
+  if (plaintext && *plaintext)
     {
       err = op_encrypt (plaintext, &ciphertext, 
                         keys, sign_key, opt.passwd_ttl);
@@ -1363,7 +1356,7 @@ GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
 
   /* Now that we successfully processed the attachments, we can save
      the changes to the body.  */
-  if (*plaintext)
+  if (plaintext && *plaintext)
     {
       if (want_html)
         {
@@ -1415,6 +1408,7 @@ GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
   free_string_array (recipients);
   free_string_array (unknown);
   xfree (ciphertext);
+  xfree (plaintext);
   log_debug ("%s:%s: leave (err=%s)\n", SRCNAME, __func__, op_strerror (err));
   return err;
 }
index 782578b..f6c5459 100644 (file)
@@ -50,25 +50,15 @@ public:
   /* Set the callback for Exchange. */
   virtual void setExchangeCallback (void *cb) = 0;
 
-  /* Don't pop up any message boxes. */
-  virtual void setSilent (bool value) = 0;
+  /* Don't pop up any message boxes and run the decryption only on the body. */
+  virtual void setPreview (bool value) = 0;
 
   /* Return the type of the message. */
-  virtual openpgp_t getMessageType (void) = 0;
+  virtual openpgp_t getMessageType (const char *text) = 0;
 
   /* Returns whether the message has any attachments. */
   virtual bool hasAttachments (void) = 0;
 
-  /* Return the body text as received or composed.  This is guaranteed
-     to never return NULL.  Usually getMessageType is used to check
-     whether there is a suitable message. */
-  virtual const char *getOrigText (bool want_html) = 0;
-
-  /* Return the text of the message to be used for the display.  The
-     message objects has intrinsic knowledge about the correct
-     text.  */
-  virtual const char *getDisplayText (void) = 0;
-
   /* Return a malloced array of malloced strings with the recipients
      of the message. Caller is responsible for freeing this array and
      the strings.  On failure NULL is returned.  */
index 1732916..2f8bf77 100644 (file)
@@ -781,6 +781,7 @@ CGPGExchExtMessageEvents::OnReadComplete (LPEXCHEXTCALLBACK pEECB,
   log_debug ("%s:%s: received\n", SRCNAME, __func__);
   if (opt.compat.preview_decryption)
     {
+      TRACEPOINT ();
       HRESULT hr;
       HWND hWnd = NULL;
       LPMESSAGE pMessage = NULL;
@@ -793,7 +794,7 @@ CGPGExchExtMessageEvents::OnReadComplete (LPEXCHEXTCALLBACK pEECB,
         {
           GpgMsg *m = CreateGpgMsg (pMessage);
           m->setExchangeCallback ((void*)pEECB);
-          m->setSilent (1);
+          m->setPreview (1);
           m->decrypt (hWnd);
           delete m;
        }
@@ -950,8 +951,10 @@ CGPGExchExtMessageEvents::OnWriteComplete (LPEXCHEXTCALLBACK pEECB,
 
       /* If we are encrypting we need to make sure that the other
          format gets deleted and is not actually sent in the clear.
-         Note that this otehr format is always HTML because we use the
-         regular PR_BODY for sending the _encrypted_ html. */
+         Note that this other format is always HTML because we have
+         moved that into an attachment and kept PR_BODY.  It seems
+         that OL always creates text and HTML if HTML has been
+         selected. */
       if (m_pExchExt->m_gpgEncrypt)
         {
           log_debug ("%s:%s: deleting possible extra property PR_BODY_HTML\n",
@@ -975,12 +978,13 @@ CGPGExchExtMessageEvents::OnWriteComplete (LPEXCHEXTCALLBACK pEECB,
                          SRCNAME, __func__,
                          m_want_html?"PR_BODY":"PR_BODY_HTML");
               proparray.cValues = 1;
-              proparray.aulPropTag[0] = m_want_html? PR_BODY_HTML : PR_BODY;
+              proparray.aulPropTag[0] = PR_BODY;
               hr = msg->DeleteProps (&proparray, NULL);
               if (hr != S_OK)
                 log_debug ("%s:%s: DeleteProps failed: hr=%#lx\n",
                            SRCNAME, __func__, hr);
-              /* FIXME: We should delete the attachments too. */
+              /* FIXME: We should delete the attachments too. 
+                 We really, really should do this!!!          */
             }
           
         }
@@ -1048,6 +1052,7 @@ CGPGExchExtCommands::CGPGExchExtCommands (CGPGExchExt* pParentInterface)
   m_lContext = 0; 
   m_nCmdEncrypt = 0;  
   m_nCmdSign = 0; 
+  m_nCmdPreviewDecrypt = 0;
   m_nToolbarButtonID1 = 0; 
   m_nToolbarButtonID2 = 0; 
   m_nToolbarBitmap1 = 0;
@@ -1359,6 +1364,13 @@ CGPGExchExtCommands::InstallCommands (
 
       m_nCmdEncrypt = *pnCommandIDBase;
       (*pnCommandIDBase)++;    
+
+      AppendMenu (hMenuTools, MF_STRING,
+                  *pnCommandIDBase, _("GPG decrypt preview"));
+
+      m_nCmdPreviewDecrypt = *pnCommandIDBase;
+      (*pnCommandIDBase)++;    
+      TRACEPOINT ();
       
       for (nTBIndex = nTBECnt-1; nTBIndex > -1; --nTBIndex)
         {
@@ -1448,7 +1460,12 @@ CGPGExchExtCommands::DoCommand (
     }
   
 
-
+  if (nCommandID == m_nCmdPreviewDecrypt && m_lContext == EECONTEXT_VIEWER)
+    {
+      opt.compat.preview_decryption = !opt.compat.preview_decryption;
+      return S_OK;
+    }
+  
   if ((nCommandID != m_nCmdEncrypt) 
       && (nCommandID != m_nCmdSign))
     return S_FALSE; 
index 3cb5666..c43ee2b 100644 (file)
@@ -132,6 +132,7 @@ private:
   
   UINT  m_nCmdEncrypt;
   UINT  m_nCmdSign;
+  UINT  m_nCmdPreviewDecrypt;
 
   UINT  m_nToolbarButtonID1;
   UINT  m_nToolbarButtonID2;     
index 561b147..a4e227d 100644 (file)
@@ -88,6 +88,8 @@ struct pgpmime_context
   HWND hwnd;          /* A window handle to be used for message boxes etc. */
   rfc822parse_t msg;  /* The handle of the RFC822 parser. */
 
+  int preview;        /* Do only decryption and pop up no  message bozes.  */
+
   int nesting_level;  /* Current MIME nesting level. */
   int in_data;        /* We are currently in data (body or attachment). */
 
@@ -324,7 +326,8 @@ message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
                 }
               else /* Other type. */
                 {
-                  ctx->collect_attachment = 1;
+                  if (!ctx->preview)
+                    ctx->collect_attachment = 1;
                 }
 
             }
@@ -375,7 +378,7 @@ message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
               if (!gpgme_data_new (&ctx->body))
                 ctx->collect_body = 1;
             }
-          else
+          else if (!ctx->preview)
             ctx->collect_attachment = 1;
         }
 
@@ -403,9 +406,9 @@ message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
             }
         tryagain:
           xfree (ctx->filename);
-          ctx->filename = get_save_filename (ctx->hwnd, p);
+          ctx->filename = ctx->preview? NULL:get_save_filename (ctx->hwnd, p);
           if (!ctx->filename)
-            ctx->collect_attachment = 0; /* User das not want to save it. */
+            ctx->collect_attachment = 0; /* User does not want to save it. */
           else
             {
               hr = OpenStreamOnFile (MAPIAllocateBuffer, MAPIFreeBuffer,
@@ -416,7 +419,7 @@ message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
                   log_error ("%s:%s: can't create file `%s': hr=%#lx\n",
                              SRCNAME, __func__, ctx->filename, hr); 
                   MessageBox (ctx->hwnd, _("Error creating file\n"
-                              "Please select another one"),
+                                           "Please select another one"),
                               _("I/O-Error"), MB_ICONERROR|MB_OK);
                   goto tryagain;
                 }
@@ -549,8 +552,9 @@ plaintext_handler (void *handle, const void *buffer, size_t size)
                     {
                       log_debug ("%s:%s: Write failed: hr=%#lx",
                                  SRCNAME, __func__, hr);
-                      MessageBox (ctx->hwnd, _("Error writing file"),
-                                  _("I/O-Error"), MB_ICONERROR|MB_OK);
+                      if (!ctx->preview)
+                        MessageBox (ctx->hwnd, _("Error writing file"),
+                                    _("I/O-Error"), MB_ICONERROR|MB_OK);
                       ctx->parser_error = 1;
                       return 0; /* Error. */
                     }
@@ -572,10 +576,11 @@ plaintext_handler (void *handle, const void *buffer, size_t size)
    newly allocated body will be stored at BODY.  If ATTESTATION is not
    NULL a text with the result of the signature verification will get
    printed to it.  HWND is the window to be used for message box and
-   such. */
+   such.  In PREVIEW_MODE no verification will be done, no messages
+   saved and no messages boxes will pop up. */
 int
 pgpmime_decrypt (LPSTREAM instream, int ttl, char **body,
-                 gpgme_data_t attestation, HWND hwnd)
+                 gpgme_data_t attestation, HWND hwnd, int preview_mode)
 {
   gpg_error_t err;
   struct gpgme_data_cbs cbs;
@@ -590,6 +595,7 @@ pgpmime_decrypt (LPSTREAM instream, int ttl, char **body,
   ctx = xcalloc (1, sizeof *ctx + LINEBUFSIZE);
   ctx->linebufsize = LINEBUFSIZE;
   ctx->hwnd = hwnd;
+  ctx->preview = preview_mode;
 
   ctx->msg = rfc822parse_open (message_cb, ctx);
   if (!ctx->msg)
@@ -604,7 +610,8 @@ pgpmime_decrypt (LPSTREAM instream, int ttl, char **body,
     goto leave;
 
   err = op_decrypt_stream_to_gpgme (instream, plaintext, ttl,
-                                    _("[PGP/MIME message]"), attestation);
+                                    _("[PGP/MIME message]"), attestation,
+                                    preview_mode);
   if (!err && (ctx->parser_error || ctx->line_too_long))
     err = gpg_error (GPG_ERR_GENERAL);
 
index e295356..41f3263 100644 (file)
@@ -29,7 +29,8 @@ extern "C" {
 #endif
 
 int pgpmime_decrypt (LPSTREAM instream, int ttl, char **body,
-                     gpgme_data_t attestation, HWND hwnd);
+                     gpgme_data_t attestation, HWND hwnd,
+                     int preview_mode);