Disable async encryption for mails with attachs
authorAndre Heinecke <aheinecke@intevation.de>
Thu, 13 Sep 2018 09:07:56 +0000 (11:07 +0200)
committerAndre Heinecke <aheinecke@intevation.de>
Thu, 13 Sep 2018 09:07:56 +0000 (11:07 +0200)
* src/mail.cpp (check_inline_response): Disable async crypt
if mail has attachments.
* src/windowmessage.cpp (CRYPTO_DONE): Clarify that the
fallback to MAPI is a very very last resort.

--
This commit sacrifices usability (async encryption) for
stability. We now use the old sync crypt code when attachments
are added to a crypto mail to avoid errors that occured
for some attachments.
As there does not appear to be a detectable pattern or
value for which attachments the write in the second send
fails we block async crypt for all attachments.

GnuPG-Bug-Id: T4131

src/mail.cpp
src/windowmessages.cpp

index 720ec3f..328989d 100644 (file)
@@ -3064,6 +3064,61 @@ Mail::check_inline_response ()
 #endif
 
   m_async_crypt_disabled = false;
+
+
+  LPDISPATCH attachments = get_oom_object (m_mailitem, "Attachments");
+  if (attachments)
+    {
+      /* This is horrible. But. For some kinds of attachments (we
+         got reports about Office attachments the write in the
+         send event triggered by our crypto done code fails with
+         an exception. There does not appear to be a detectable
+         pattern when this happens.
+         As we can't be sure and do not know for which attachments
+         this really happens we do not use async crypt for any
+         mails with attachments. :-/
+         Better be save (not crash) instead of nice (async).
+
+         TODO: Figure this out.
+
+         The log goes like this. We pass the send event. That triggers
+         a write, which we pass. And then that fails. So it looks like
+         moving to Outbox fails. Because we can save as much as we
+         like before that.
+
+         Using the IMessage::SubmitMessage MAPI interface works, but
+         as it is unstable in our current implementation we do not
+         want to use it.
+
+         mailitem-events.cpp:Invoke: Passing send event for mime-encrypted message 12B7C6E0.
+         application-events.cpp:Invoke: Unhandled Event: f002
+         mailitem-events.cpp:Invoke: Write : 0ED4D058
+         mailitem-events.cpp:Invoke: Passing write event.
+         oomhelp.cpp:invoke_oom_method_with_parms_type: Method 'Send' invokation failed: 0x80020009
+         oomhelp.cpp:dump_excepinfo: Exception:
+         wCode: 0x1000
+         wReserved: 0x0
+         source: Microsoft Outlook
+         desc: The operation failed.  The messaging interfaces have returned an unknown error. If the problem persists, restart Outlook.
+         help: null
+         helpCtx: 0x0
+         deferredFill: 00000000
+         scode: 0x80040119
+      */
+
+      int count = get_oom_int (attachments, "Count");
+      gpgol_release (attachments);
+
+      if (count)
+        {
+          m_async_crypt_disabled = true;
+          log_debug ("%s:%s: Detected attachments. "
+                     "Disabling async crypt due to T4131.",
+                     SRCNAME, __func__);
+          return m_async_crypt_disabled;
+        }
+   }
+
   LPDISPATCH app = GpgolAddin::get_instance ()->get_application ();
   if (!app)
     {
index 9991eba..bb349b5 100644 (file)
@@ -168,8 +168,14 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
               if (invoke_oom_method (mail->item (), "Send", NULL))
                 {
                   log_error ("%s:%s: Send failed for %p. "
-                             "Trying SubmitMessage instead.",
+                             "Trying SubmitMessage instead.\n"
+                             "This will likely crash.",
                              SRCNAME, __func__, mail);
+
+                  /* What we do here is similar to the T3656 workaround
+                     in mailitem-events.cpp. In our tests this works but
+                     is unstable. So we only use it as a very very last
+                     resort. */
                   auto mail_message = get_oom_base_message (mail->item());
                   if (!mail_message)
                     {