[git] GpgOL - branch, master, updated. gpgol-2.0.6-88-g2f39fe2

by Andre Heinecke cvs at cvs.gnupg.org
Tue Mar 13 16:49:16 CET 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG extension for MS Outlook".

The branch, master has been updated
       via  2f39fe219c6810b51a1b428a4618b861e2d427c1 (commit)
       via  6754d87330659d0cc47c5340fd17f358977fb3b3 (commit)
      from  f63db085c5d86839bb5ed8b4203b4c7b5f28975e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 2f39fe219c6810b51a1b428a4618b861e2d427c1
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Tue Mar 13 16:41:45 2018 +0100

    Implement forwarding crypto mails with attachments
    
    * src/application-events.cpp (EVENT_SINK_INVOKE): Invalidate last
    mail in the next UI Loop.
    * src/mail.cpp (Mail::update_body): Safety check for parser. Keep
    parser around.
    (Mail::invalidate_last_mail): New. Clear cached last mail ptr.
    * src/mail.h: Update accordingly.
    * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Extend write
    event to detect forward of mails with attachments.
    * src/oomhelp.cpp (get_inline_body): New.
    * src/oomhelp.h: Update accordingly.
    * src/windowmessages.cpp, src/windowmessages.h
    (INVALIDATE_LAST_MAIL, REVERT_MAIL): New messages.
    * src/wks-helper.cpp (WKSHelper::send_mail): Check if last
    mail was invalidated.
    
    --
    This is a first working draft of forwarding crypto mails
    with attachments. As we don't see the forward event before
    we get the write event (that we have to cancel usually) we
    now have some extra magic to detect the forward based on
    an ItemLoad of an empty mail in the same UI loop as the
    write event. This is pretty magic but it works.
    
    Once we detect the forward we save the mail and then immediately
    revert it and save it again. This has the usual uglyness of
    reverting (sync) but works and allows to forward mails.
    
    GnuPG-Bug-Id: T3836

diff --git a/src/application-events.cpp b/src/application-events.cpp
index c000a86..1100934 100644
--- a/src/application-events.cpp
+++ b/src/application-events.cpp
@@ -33,6 +33,7 @@
 #include "oomhelp.h"
 #include "mail.h"
 #include "gpgoladdin.h"
+#include "windowmessages.h"
 
 /* Application Events */
 BEGIN_EVENT_SINK(ApplicationEvents, IDispatch)
@@ -91,6 +92,7 @@ EVENT_SINK_INVOKE(ApplicationEvents)
           log_debug ("%s:%s: Creating mail object for item: %p",
                      SRCNAME, __func__, mailItem);
           new Mail (mailItem);
+          do_in_ui_thread_async (INVALIDATE_LAST_MAIL, nullptr);
           break;
         }
       case Quit:
diff --git a/src/mail.cpp b/src/mail.cpp
index 13b984d..d4e7e10 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -922,6 +922,12 @@ void find_and_replace(std::string& source, const std::string &find,
 void
 Mail::update_body()
 {
+  if (!m_parser)
+    {
+      TRACEPOINT;
+      return;
+    }
+
   const auto error = m_parser->get_formatted_error ();
   if (!error.empty())
     {
@@ -1076,9 +1082,6 @@ Mail::parsing_done()
                  SRCNAME, __func__);
     }
 
-  /* Invalidate UI to set the correct sig status. */
-  m_parser = nullptr;
-
   log_debug ("%s:%s: Delayed invalidate to update sigstate.",
              SRCNAME, __func__);
   CloseHandle(CreateThread (NULL, 0, delayed_invalidate_ui, (LPVOID) this, 0,
@@ -2589,6 +2592,13 @@ Mail::get_last_mail ()
 
 // static
 void
+Mail::invalidate_last_mail ()
+{
+  s_last_mail = nullptr;
+}
+
+// static
+void
 Mail::locate_all_crypto_recipients()
 {
   if (!opt.autoresolve)
diff --git a/src/mail.h b/src/mail.h
index f8cdbab..90f042e 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -92,6 +92,8 @@ public:
   */
   static Mail* get_last_mail ();
 
+  static void invalidate_last_mail ();
+
   /** @brief looks for existing Mail objects.
 
     @returns A reference to an existing mailitem or NULL in case none
@@ -446,9 +448,9 @@ public:
   /** Get the mime data that should be used when sending. */
   std::string get_override_mime_data () const { return m_mime_data; }
 
+  void update_body ();
 private:
   void update_categories ();
-  void update_body ();
   void update_sigstate ();
 
   LPDISPATCH m_mailitem;
diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index 2360789..7933826 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -480,6 +480,45 @@ EVENT_SINK_INVOKE(MailItemEvents)
 
           if (m_mail->is_crypto_mail () && !m_mail->needs_save ())
             {
+              Mail *last_mail = Mail::get_last_mail ();
+              if (Mail::is_valid_ptr (last_mail))
+                {
+                  /* We want to identify here if there was a mail created that
+                     should receive the contents of this mail. For this we check
+                     for a write in the same loop as a mail creation.
+                     Now when switching from one mail to another this is also what
+                     happens. The new mail is loaded and the old mail is written.
+                     To distinguish the two we check that the new mail does not have
+                     an entryID, a Subject and No Size. Maybe just size or entryID
+                     would be enough but better save then sorry.
+
+                     Security consideration: Worst case we pass the write here but
+                     an unload follows before we get the scheduled revert. This
+                     would leak plaintext.
+
+                     Similarly if we crash or Outlook is closed before we see this
+                     revert. */
+                  const std::string lastSubject = last_mail->get_subject ();
+                  char *lastEntryID = get_oom_string (last_mail->item (), "EntryID");
+                  int lastSize = get_oom_int (last_mail->item (), "Size");
+                  std::string lastEntryStr;
+                  if (lastEntryID)
+                    {
+                      lastEntryStr = lastEntryID;
+                      xfree (lastEntryID);
+                    }
+
+                  if (!lastSize && !lastEntryStr.size () && !lastSubject.size ())
+                    {
+                      log_debug ("%s:%s: Write in the same loop as empty load."
+                                 " Pass but schedule revert.",
+                                 SRCNAME, __func__);
+
+                      Mail::invalidate_last_mail ();
+                      do_in_ui_thread_async (REVERT_MAIL, m_mail);
+                      return S_OK;
+                    }
+                }
               /* We cancel the write event to stop outlook from excessively
                  syncing our changes.
                  if smime support is disabled and we still have an smime
diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp
index ba3d89f..51d025b 100644
--- a/src/oomhelp.cpp
+++ b/src/oomhelp.cpp
@@ -2002,3 +2002,35 @@ get_sender_SenderEMailAddress (LPDISPATCH mailitem)
   xfree (type);
   return nullptr;
 }
+
+char *
+get_inline_body ()
+{
+  LPDISPATCH app = GpgolAddin::get_instance ()->get_application ();
+  if (!app)
+    {
+      TRACEPOINT;
+      return nullptr;
+    }
+
+  LPDISPATCH explorer = get_oom_object (app, "ActiveExplorer");
+
+  if (!explorer)
+    {
+      TRACEPOINT;
+      return nullptr;
+    }
+
+  LPDISPATCH inlineResponse = get_oom_object (explorer, "ActiveInlineResponse");
+  gpgol_release (explorer);
+
+  if (!inlineResponse)
+    {
+      return nullptr;
+    }
+
+  char *body = get_oom_string (inlineResponse, "Body");
+  gpgol_release (inlineResponse);
+
+  return body;
+}
diff --git a/src/oomhelp.h b/src/oomhelp.h
index 2af096b..cbc36ca 100644
--- a/src/oomhelp.h
+++ b/src/oomhelp.h
@@ -338,6 +338,9 @@ LPDISPATCH get_account_for_mail (const char *mbox);
 char *get_sender_CurrentUser (LPDISPATCH mailitem);
 char *get_sender_Sender (LPDISPATCH mailitem);
 char *get_sender_SenderEMailAddress (LPDISPATCH mailitem);
+
+/* Get the body of the active inline response */
+char *get_inline_body (void);
 #ifdef __cplusplus
 char *get_sender_SendUsingAccount (LPDISPATCH mailitem, bool *r_is_GSuite);
 }
diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp
index b0e2311..af55d11 100644
--- a/src/windowmessages.cpp
+++ b/src/windowmessages.cpp
@@ -68,6 +68,34 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
               mail->locate_keys();
               break;
             }
+          case (REVERT_MAIL):
+            {
+              auto mail = (Mail*) ctx->data;
+              if (!Mail::is_valid_ptr (mail))
+                {
+                  log_debug ("%s:%s: Revert mail for mail which is gone.",
+                             SRCNAME, __func__);
+                  break;
+                }
+
+              mail->set_needs_save (true);
+              /* Some magic here. Accessing any existing inline body cements
+                 it. Otherwise updating the body through the revert also changes
+                 the body of a inline mail. */
+              char *inlineBody = get_inline_body ();
+              xfree (inlineBody);
+
+              // Does the revert.
+              log_debug ("%s:%s: Revert mail. Invoking save.",
+                         SRCNAME, __func__);
+              invoke_oom_method (mail->item (), "Save", NULL);
+              log_debug ("%s:%s: Revert mail. Save done. Updating body..",
+                         SRCNAME, __func__);
+              mail->update_body ();
+              log_debug ("%s:%s: Revert mail done.",
+                         SRCNAME, __func__);
+              break;
+            }
           case (INVALIDATE_UI):
             {
               log_debug ("%s:%s: Invalidating UI",
@@ -77,6 +105,13 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
                          SRCNAME, __func__);
               break;
             }
+          case (INVALIDATE_LAST_MAIL):
+            {
+              log_debug ("%s:%s: Invalidating last mail",
+                         SRCNAME, __func__);
+              Mail::invalidate_last_mail ();
+              break;
+            }
           case (CLOSE):
             {
               auto mail = (Mail*) ctx->data;
@@ -114,6 +149,8 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
                 }
               // Finaly this should pass.
               invoke_oom_method (mail->item (), "Send", NULL);
+              log_debug ("%s:%s:  Send for %p completed.",
+                         SRCNAME, __func__, mail);
               // Allow the WKS helper to queue a notification.
               WKSHelper::instance()->allow_notify ();
               break;
diff --git a/src/windowmessages.h b/src/windowmessages.h
index 979f0b4..56d9db8 100644
--- a/src/windowmessages.h
+++ b/src/windowmessages.h
@@ -50,6 +50,8 @@ typedef enum _gpgol_wmsg_type
   CRYPTO_DONE, /* Sign / Encrypt done. */
   WKS_NOTIFY, /* Show a WKS Notification. */
   BRING_TO_FRONT, /* Bring the active Outlook window to the front. */
+  INVALIDATE_LAST_MAIL,
+  REVERT_MAIL,
 } gpgol_wmsg_type;
 
 typedef struct
diff --git a/src/wks-helper.cpp b/src/wks-helper.cpp
index 16d42ba..52c05c1 100644
--- a/src/wks-helper.cpp
+++ b/src/wks-helper.cpp
@@ -623,6 +623,12 @@ WKSHelper::send_mail (const std::string &mimeData) const
      a Hack! :-) */
   auto last_mail = Mail::get_last_mail ();
 
+  if (!Mail::is_valid_ptr (last_mail))
+    {
+      log_error ("%s:%s: Invalid last mail %p.",
+                 SRCNAME, __func__, last_mail);
+      return -1;
+    }
   last_mail->set_override_mime_data (mimeData);
   last_mail->set_crypt_state (Mail::NeedsSecondAfterWrite);
 

commit 6754d87330659d0cc47c5340fd17f358977fb3b3
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Tue Mar 13 16:38:54 2018 +0100

    Improve error handling on enc/sign errors
    
    * src/cryptcontroller.cpp (CryptController::do_crypto):
    Improve error handling.
    * src/mail.cpp (do_crypt): Use correct window and hide overlay /
    destroy crypter before showing the error. Add better text for
    general "Crypto failed" error.

diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp
index da23de4..da60c3b 100644
--- a/src/cryptcontroller.cpp
+++ b/src/cryptcontroller.cpp
@@ -517,7 +517,8 @@ CryptController::do_crypto ()
       gpgol_message_box (nullptr,
                          utf8_gettext ("Failure to resolve keys."),
                          utf8_gettext ("GpgOL"), MB_OK);
-      return ret;
+      // Error handled, return as canceled.
+      return -2;
     }
   if (ret == -2)
     {
@@ -539,7 +540,7 @@ CryptController::do_crypto ()
     {
       log_error ("%s:%s: Failure to create context.",
                  SRCNAME, __func__);
-      gpgol_message_box (nullptr,
+      gpgol_message_box (m_mail->get_window (),
                          "Failure to create context.",
                          utf8_gettext ("GpgOL"), MB_OK);
       return -1;
diff --git a/src/mail.cpp b/src/mail.cpp
index ba2b501..13b984d 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -748,20 +748,27 @@ do_crypt (LPVOID arg)
       return 0;
     }
 
-  mail->set_window_enabled (true);
-
   if (rc == -1)
     {
-      gpgol_message_box (nullptr,
-                         "Crypto failed",
+      mail->reset_crypter ();
+      crypter = nullptr;
+      gpgol_message_box (mail->get_window (),
+                         utf8_gettext ("Sign / Encrypt failed.\n\n"
+                         "This is usually caused by an error in your system.\n"
+                         "Please refer to the Gpg4win compendium how to enable debugging in GpgOL,"
+                         "or ask your Administrator for support."),
                          _("GpgOL"), MB_OK);
     }
+
+  mail->set_window_enabled (true);
+
   if (rc)
     {
       log_debug ("%s:%s: crypto failed for: %p with: %i",
                  SRCNAME, __func__, arg, rc);
       mail->set_crypt_state (Mail::NoCryptMail);
       mail->reset_crypter ();
+      crypter = nullptr;
       gpgrt_lock_unlock (&dtor_lock);
       return rc;
     }

-----------------------------------------------------------------------

Summary of changes:
 src/application-events.cpp |  2 ++
 src/cryptcontroller.cpp    |  5 +++--
 src/mail.cpp               | 31 ++++++++++++++++++++++++-------
 src/mail.h                 |  4 +++-
 src/mailitem-events.cpp    | 39 +++++++++++++++++++++++++++++++++++++++
 src/oomhelp.cpp            | 32 ++++++++++++++++++++++++++++++++
 src/oomhelp.h              |  3 +++
 src/windowmessages.cpp     | 37 +++++++++++++++++++++++++++++++++++++
 src/windowmessages.h       |  2 ++
 src/wks-helper.cpp         |  6 ++++++
 10 files changed, 151 insertions(+), 10 deletions(-)


hooks/post-receive
-- 
GnuPG extension for MS Outlook
http://git.gnupg.org




More information about the Gnupg-commits mailing list