[git] GpgOL - branch, master, updated. gpgol-2.0.6-111-g97ee667

by Andre Heinecke cvs at cvs.gnupg.org
Mon Mar 26 17:42:46 CEST 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  97ee667a0c24649233554cd6df9572cb2406bf91 (commit)
       via  2f05d4ed802a62c0cc0d8f4632ff5cfe4b4c6ea1 (commit)
       via  4c5eed30882963283caa1b82626d8ccd6a682490 (commit)
       via  e67c03636889a1ef81de3601788f25dcf4d39370 (commit)
       via  9d10ff22928a089347d4ad1393aea08366917659 (commit)
       via  e62b003f83bc41375edd421d0ee0046f129accfe (commit)
       via  71334bacf78074889138d9328a18a205e8fd86cd (commit)
       via  b2727a00c02520ca603f5c1dad0d181348f2c63f (commit)
       via  a683aac7f165e2fb97006e634afd53639bf57fef (commit)
       via  52c80aec174d6c0329e0dce0acf72e282e3b6c9a (commit)
       via  a80c7502c45b2fc516b9b31e90dc3b858527850a (commit)
      from  88e76e1675dc10ab88d5541f716ea54e00d61b40 (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 97ee667a0c24649233554cd6df9572cb2406bf91
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 17:41:39 2018 +0200

    s/is_inline_response/async_crypt_disabled/
    
    --
    This should make it more clear and avoid a PGP/Inline <> Inline
    Editor misunderstanding.

diff --git a/src/mail.cpp b/src/mail.cpp
index 4acc4e8..9d96bb6 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -92,7 +92,7 @@ Mail::Mail (LPDISPATCH mailitem) :
     m_is_gsuite(false),
     m_crypt_state(NoCryptMail),
     m_window(nullptr),
-    m_is_inline_response(false),
+    m_async_crypt_disabled(false),
     m_is_forwarded_crypto_mail(false)
 {
   if (get_mail_for_item (mailitem))
@@ -704,7 +704,7 @@ do_parsing (LPVOID arg)
 /* How encryption is done:
 
    There are two modes of encryption. Synchronous and Async.
-   If async is used depends on the value of mail->is_inline_response.
+   If async is used depends on the value of mail->async_crypt_disabled.
 
    Synchronous crypto:
 
@@ -841,7 +841,7 @@ do_crypt (LPVOID arg)
       return rc;
     }
 
-  if (!mail->is_inline_response ())
+  if (!mail->async_crypt_disabled ())
     {
       mail->set_crypt_state (Mail::NeedsUpdateInOOM);
       gpgrt_lock_unlock (&dtor_lock);
@@ -1230,7 +1230,7 @@ Mail::encrypt_sign_start ()
       return -1;
     }
 
-  if (!m_is_inline_response)
+  if (!m_async_crypt_disabled)
     {
       CloseHandle(CreateThread (NULL, 0, do_crypt,
                                 (LPVOID) this, 0,
@@ -2537,7 +2537,7 @@ Mail::update_crypt_mapi()
     }
 
   /** If sync we need the crypter in update_crypt_oom */
-  if (!is_inline_response ())
+  if (!async_crypt_disabled ())
     {
       // We don't need the crypter anymore.
       reset_crypter ();
@@ -2594,7 +2594,7 @@ Mail::update_crypt_oom()
     }
   /** When doing async update_crypt_mapi follows and needs
     the crypter. */
-  if (is_inline_response ())
+  if (async_crypt_disabled ())
     {
       reset_crypter ();
     }
@@ -2650,7 +2650,7 @@ Mail::check_inline_response ()
  * For now we treat every mail as an inline response to disable async
  * encryption. :-( For more details see: T3838 */
 #ifdef DO_ASYNC_CRYPTO
-  m_is_inline_response = false;
+  m_async_crypt_disabled = false;
   LPDISPATCH app = GpgolAddin::get_instance ()->get_application ();
   if (!app)
     {
@@ -2686,14 +2686,14 @@ Mail::check_inline_response ()
     {
       log_debug ("%s:%s: Detected inline response for '%p'",
                  SRCNAME, __func__, this);
-      m_is_inline_response = true;
+      m_async_crypt_disabled = true;
     }
   xfree (inlineSubject);
 #else
-  m_is_inline_response = true;
+  m_async_crypt_disabled = true;
 #endif
 
-  return m_is_inline_response;
+  return m_async_crypt_disabled;
 }
 
 // static
diff --git a/src/mail.h b/src/mail.h
index 37b9efd..d267d8b 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -424,13 +424,13 @@ public:
     from the OOM.
 
     We need synchronous encryption for inline responses. */
-  bool is_inline_response () { return m_is_inline_response; }
+  bool async_crypt_disabled () { return m_async_crypt_disabled; }
 
   /** Check through OOM if the current mail is an inline
     response.
 
     Caches the state which can then be queried through
-    is_inline_response
+    async_crypt_disabled
   */
   bool check_inline_response ();
 
@@ -510,7 +510,7 @@ private:
   std::string m_inline_body;
   CryptState m_crypt_state;
   HWND m_window;
-  bool m_is_inline_response;
+  bool m_async_crypt_disabled;
   std::string m_mime_data;
   bool m_is_forwarded_crypto_mail; /* Is this a forward of a crypto mail */
 };
diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index 9ebe696..2a96166 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -365,7 +365,7 @@ EVENT_SINK_INVOKE(MailItemEvents)
               // Save the Mail
               invoke_oom_method (m_object, "Save", NULL);
 
-              if (!m_mail->is_inline_response ())
+              if (!m_mail->async_crypt_disabled ())
                 {
                   // The afterwrite in the save should have triggered
                   // the encryption. We cancel send for our asyncness.

commit 2f05d4ed802a62c0cc0d8f4632ff5cfe4b4c6ea1
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 17:39:51 2018 +0200

    s/should_inline_crypt/do_pgp_inline/
    
    --
    Make it more clear.

diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp
index 3e343e0..34b3af3 100644
--- a/src/cryptcontroller.cpp
+++ b/src/cryptcontroller.cpp
@@ -68,7 +68,7 @@ CryptController::CryptController (Mail *mail, bool encrypt, bool sign,
     m_proto (proto)
 {
   log_debug ("%s:%s: CryptController ctor for %p encrypt %i sign %i inline %i.",
-             SRCNAME, __func__, mail, encrypt, sign, mail->should_inline_crypt ());
+             SRCNAME, __func__, mail, encrypt, sign, mail->do_pgp_inline ());
   m_recipient_addrs = mail->take_cached_recipients ();
 }
 
@@ -119,7 +119,7 @@ CryptController::collect_data ()
       return -1;
     }
 
-  bool do_inline = m_mail->should_inline_crypt ();
+  bool do_inline = m_mail->do_pgp_inline ();
 
   if (n_att_usable && do_inline)
     {
@@ -127,7 +127,7 @@ CryptController::collect_data ()
                  " Using PGP MIME",
                  SRCNAME, __func__);
       do_inline = false;
-      m_mail->set_should_inline_crypt (false);
+      m_mail->set_do_pgp_inline (false);
     }
   else if (do_inline)
     {
@@ -528,14 +528,14 @@ CryptController::do_crypto ()
       // Cancel
       return -2;
     }
-  bool do_inline = m_mail->should_inline_crypt ();
+  bool do_inline = m_mail->do_pgp_inline ();
 
   if (m_proto == GpgME::CMS && do_inline)
     {
       log_debug ("%s:%s: Inline for S/MIME not supported. Switching to mime.",
                  SRCNAME, __func__);
       do_inline = false;
-      m_mail->set_should_inline_crypt (false);
+      m_mail->set_do_pgp_inline (false);
       m_bodyInput = GpgME::Data(GpgME::Data::null);
     }
 
@@ -864,7 +864,7 @@ CryptController::update_mail_mapi ()
 {
   log_debug ("%s:%s", SRCNAME, __func__);
 
-  if (m_mail->should_inline_crypt ())
+  if (m_mail->do_pgp_inline ())
     {
       // Nothing to do for inline.
       log_debug ("%s:%s: Inline mail. No MAPI update.",
@@ -952,7 +952,7 @@ std::string
 CryptController::get_inline_data ()
 {
   std::string ret;
-  if (!m_mail->should_inline_crypt ())
+  if (!m_mail->do_pgp_inline ())
     {
       return ret;
     }
diff --git a/src/mail.cpp b/src/mail.cpp
index 9dda977..4acc4e8 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -2581,7 +2581,7 @@ Mail::update_crypt_oom()
       return;
     }
 
-  if (should_inline_crypt ())
+  if (do_pgp_inline ())
     {
       if (inline_body_to_body ())
         {
diff --git a/src/mail.h b/src/mail.h
index e295188..37b9efd 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -383,10 +383,10 @@ public:
   int check_attachments () const;
 
   /** Check if the mail should be encrypted "inline" */
-  bool should_inline_crypt () const {return m_do_inline;}
+  bool do_pgp_inline () const {return m_do_inline;}
 
   /** Check if the mail should be encrypted "inline" */
-  void set_should_inline_crypt (bool value) {m_do_inline = value;}
+  void set_do_pgp_inline (bool value) {m_do_inline = value;}
 
   /** Append data to a cached inline body. Helper to do this
      on MAPI level and later add it through OOM */
diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index 55a4ebe..9ebe696 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -385,7 +385,7 @@ EVENT_SINK_INVOKE(MailItemEvents)
                     {
                       m_mail->set_crypt_state (Mail::WantsSendMIME);
                     }
-                  if (m_mail->should_inline_crypt () && m_mail->crypt_state () != Mail::WantsSendInline)
+                  if (m_mail->do_pgp_inline () && m_mail->crypt_state () != Mail::WantsSendInline)
                     {
                       log_debug ("%s:%s: Message %p mail %p cancelling send - "
                                  "Invalid state.",
diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp
index 449a74e..2108230 100644
--- a/src/mimemaker.cpp
+++ b/src/mimemaker.cpp
@@ -1972,7 +1972,7 @@ mime_encrypt (LPMESSAGE message, HWND hwnd,
   int n_att_usable;
   engine_filter_t filter = NULL;
   char *my_sender = NULL;
-  bool is_inline = mail && mail->should_inline_crypt ();
+  bool is_inline = mail && mail->do_pgp_inline ();
 
   memset (sink, 0, sizeof *sink);
   memset (encsink, 0, sizeof *encsink);

commit 4c5eed30882963283caa1b82626d8ccd6a682490
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 17:35:16 2018 +0200

    Fix sending PGP/Inline synchronously
    
    * src/common.h: Add error code.
    * src/mail.cpp (Mail::update_crypt_mapi): Don't reset crypter
    if in sync mode.
    (Mail::update_crypt_oom): Reset crypter in sync mode.
    * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Check that
    states for inline mail are as expected or bug out.
    
    --
    For synchonous inline encrypted the cryptcontroller was
    deleted too early. This caused body_to_body to fail and
    ultimately lead to an unencrypted mail.
    
    This fixes:
    GnuPG-Bug-Id: T3863

diff --git a/src/common.h b/src/common.h
index e9cdb2a..bd55a13 100644
--- a/src/common.h
+++ b/src/common.h
@@ -158,6 +158,7 @@ void gpgol_bug (HWND parent, int code);
 #define ERR_WANTS_SEND_MIME_BODY 2
 #define ERR_WANTS_SEND_INLINE_BODY 3
 #define ERR_INLINE_BODY_TO_BODY 4
+#define ERR_INLINE_BODY_INV_STATE 5
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/mail.cpp b/src/mail.cpp
index dc11082..9dda977 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -2535,8 +2535,13 @@ Mail::update_crypt_mapi()
     {
       m_crypt_state = WantsSendMIME;
     }
-  // We don't need the crypter anymore.
-  reset_crypter ();
+
+  /** If sync we need the crypter in update_crypt_oom */
+  if (!is_inline_response ())
+    {
+      // We don't need the crypter anymore.
+      reset_crypter ();
+    }
 }
 
 /** Checks in OOM if the body is either
@@ -2572,6 +2577,7 @@ Mail::update_crypt_oom()
     {
       log_debug ("%s:%s: invalid state %i",
                  SRCNAME, __func__, m_crypt_state);
+      reset_crypter ();
       return;
     }
 
@@ -2586,6 +2592,12 @@ Mail::update_crypt_oom()
           return;
         }
     }
+  /** When doing async update_crypt_mapi follows and needs
+    the crypter. */
+  if (is_inline_response ())
+    {
+      reset_crypter ();
+    }
 
   const auto pair = has_crypt_or_empty_body_oom (this);
   if (pair.first)
diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index 611c6ec..55a4ebe 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -385,6 +385,16 @@ EVENT_SINK_INVOKE(MailItemEvents)
                     {
                       m_mail->set_crypt_state (Mail::WantsSendMIME);
                     }
+                  if (m_mail->should_inline_crypt () && m_mail->crypt_state () != Mail::WantsSendInline)
+                    {
+                      log_debug ("%s:%s: Message %p mail %p cancelling send - "
+                                 "Invalid state.",
+                                 SRCNAME, __func__, m_object, m_mail);
+                      gpgol_bug (m_mail->get_window (),
+                                 ERR_INLINE_BODY_INV_STATE);
+                      *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE;
+                      break;
+                    }
                 }
             }
 

commit e67c03636889a1ef81de3601788f25dcf4d39370
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 17:16:40 2018 +0200

    Add bug error if body_to_body failed
    
    * src/mail.cpp (Mail::update_crypt_oom): Check for and
    handle error in inline_body_to_body.
    
    --
    GnuPG-Bug-Id: T3863

diff --git a/src/common.h b/src/common.h
index 7f13d04..e9cdb2a 100644
--- a/src/common.h
+++ b/src/common.h
@@ -157,6 +157,7 @@ void gpgol_bug (HWND parent, int code);
 #define ERR_CRYPT_RESOLVER_FAILED 1
 #define ERR_WANTS_SEND_MIME_BODY 2
 #define ERR_WANTS_SEND_INLINE_BODY 3
+#define ERR_INLINE_BODY_TO_BODY 4
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/mail.cpp b/src/mail.cpp
index 4431eab..dc11082 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -2579,8 +2579,11 @@ Mail::update_crypt_oom()
     {
       if (inline_body_to_body ())
         {
-          log_debug ("%s:%s: Inline body to body failed %p.",
+          log_error ("%s:%s: Inline body to body failed %p.",
                      SRCNAME, __func__, this);
+          gpgol_bug (get_active_hwnd(), ERR_INLINE_BODY_TO_BODY);
+          m_crypt_state = NoCryptMail;
+          return;
         }
     }
 

commit 9d10ff22928a089347d4ad1393aea08366917659
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 16:57:20 2018 +0200

    Add safety check to prevent unencrypted send
    
    * src/mail.cpp (Mail::has_crypted_or_empty_body): New.
    (Mail::update_crypt_oom): Use it.
    (has_crypt_or_empty_body_oom): New helper.
    * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Check if
    body is empty or a crypt message before passing send on
    a crypto mail.
    
    --
    GnuPG-Bug-Id: T3863
    
    The idea is to check as a last ditch if before sending
    a mail that "should" be encrypted if it has either
    an empty body or a PGP/Inline body.
    This won't help of course for empty mails with attachments
    but should work in most cases.
    
    The codepath is never hit intentional so the error
    message points to a bug. It's just an additional
    saveguard.

diff --git a/src/mail.cpp b/src/mail.cpp
index 3855300..4431eab 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -2539,6 +2539,30 @@ Mail::update_crypt_mapi()
   reset_crypter ();
 }
 
+/** Checks in OOM if the body is either
+  empty or contains the -----BEGIN tag.
+  pair.first -> true if body starts with -----BEGIN
+  pair.second -> true if body is empty. */
+static std::pair<bool, bool>
+has_crypt_or_empty_body_oom (Mail *mail)
+{
+  auto body = mail->get_body();
+  std::pair<bool, bool> ret;
+  ret.first = false;
+  ret.second = false;
+  ltrim (body);
+  if (body.size() > 10 && !strncmp (body.c_str(), "-----BEGIN", 10))
+    {
+      ret.first = true;
+      return ret;
+    }
+  if (!body.size())
+    {
+      ret.second = true;
+    }
+  return ret;
+}
+
 void
 Mail::update_crypt_oom()
 {
@@ -2559,8 +2583,9 @@ Mail::update_crypt_oom()
                      SRCNAME, __func__, this);
         }
     }
-  const auto body = get_body();
-  if (body.size() > 10 && !strncmp (body.c_str(), "-----BEGIN", 10))
+
+  const auto pair = has_crypt_or_empty_body_oom (this);
+  if (pair.first)
     {
       log_debug ("%s:%s: Looks like inline body. You can pass %p.",
                  SRCNAME, __func__, this);
@@ -2752,3 +2777,64 @@ Mail::remove_our_attachments ()
     }
   return ret;
 }
+
+/* We are very verbose because if we fail it might mean
+   that we have leaked plaintext -> critical. */
+bool
+Mail::has_crypted_or_empty_body ()
+{
+  const auto pair = has_crypt_or_empty_body_oom (this);
+
+  if (pair.first /* encrypted marker */)
+    {
+      log_debug ("%s:%s: Crypt Marker detected in OOM body. Return true %p.",
+                 SRCNAME, __func__, this);
+      return true;
+    }
+
+  if (!pair.second)
+    {
+      log_debug ("%s:%s: Unexpected content detected. Return false %p.",
+                 SRCNAME, __func__, this);
+      return false;
+    }
+
+  // Pair second == true (is empty) can happen on OOM error.
+  LPMESSAGE message = get_oom_base_message (m_mailitem);
+  if (!message && pair.second)
+    {
+      if (message)
+        {
+          gpgol_release (message);
+        }
+      return true;
+    }
+
+  size_t r_nbytes = 0;
+  char *mapi_body = mapi_get_body (message, &r_nbytes);
+  gpgol_release (message);
+
+  if (!mapi_body || !r_nbytes)
+    {
+      // Body or bytes are null. we are empty.
+      xfree (mapi_body);
+      log_debug ("%s:%s: MAPI error or empty message. Return true. %p.",
+                 SRCNAME, __func__, this);
+      return true;
+    }
+  if (r_nbytes > 10 && !strncmp (mapi_body, "-----BEGIN", 10))
+    {
+      // Body is crypt.
+      log_debug ("%s:%s: MAPI Crypt marker detected. Return true. %p.",
+                 SRCNAME, __func__, this);
+      xfree (mapi_body);
+      return true;
+    }
+
+  xfree (mapi_body);
+
+  log_debug ("%s:%s: Found mapi body. Return false. %p.",
+             SRCNAME, __func__, this);
+
+  return false;
+}
diff --git a/src/mail.h b/src/mail.h
index 51604d0..e295188 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -460,6 +460,18 @@ public:
     Returns 0 on success. Works in OOM. */
   int remove_our_attachments ();
 
+  /** Check both OOM and MAPI if the body is either empty or
+    encrypted. Won't abort on OOM or MAPI errors, so it can be
+    used in both states. But will return false if a body
+    was detected or in the OOM the MAPI Base Message. This
+    is intended as a saveguard before sending a mail.
+
+    This function should not be used to detected the necessity
+    of encryption and is only an extra check to catch unexpected
+    errors.
+    */
+  bool has_crypted_or_empty_body ();
+
   void update_body ();
 private:
   void update_categories ();
diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index 2dbde79..611c6ec 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -390,6 +390,17 @@ EVENT_SINK_INVOKE(MailItemEvents)
 
           if (m_mail->crypt_state () == Mail::WantsSendInline)
             {
+              if (!m_mail->has_crypted_or_empty_body())
+                {
+                  log_debug ("%s:%s: Message %p mail %p cancelling send - "
+                             "not encrypted or not empty body detected.",
+                             SRCNAME, __func__, m_object, m_mail);
+                  gpgol_bug (m_mail->get_window (),
+                             ERR_WANTS_SEND_INLINE_BODY);
+                  m_mail->set_crypt_state (Mail::NoCryptMail);
+                  *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE;
+                  break;
+                }
               log_debug ("%s:%s: Passing send event for no-mime message %p.",
                          SRCNAME, __func__, m_object);
               break;
@@ -397,6 +408,17 @@ EVENT_SINK_INVOKE(MailItemEvents)
 
           if (m_mail->crypt_state () == Mail::WantsSendMIME)
             {
+              if (!m_mail->has_crypted_or_empty_body())
+                {
+                  gpgol_bug (m_mail->get_window (),
+                             ERR_WANTS_SEND_MIME_BODY);
+                  log_debug ("%s:%s: Message %p mail %p cancelling send mime - "
+                             "not encrypted or not empty body detected.",
+                             SRCNAME, __func__, m_object, m_mail);
+                  m_mail->set_crypt_state (Mail::NoCryptMail);
+                  *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE;
+                  break;
+                }
               /* Now we adress T3656 if Outlooks internal S/MIME is somehow
                * mixed in (even if it is enabled and then disabled) it might
                * cause strange behavior in that it sends the plain message

commit e62b003f83bc41375edd421d0ee0046f129accfe
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 16:56:28 2018 +0200

    Check for error on encrypt_sign_start
    
    * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Check error
    of encrypt_sign_start.

diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index 273c842..2dbde79 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -577,7 +577,12 @@ EVENT_SINK_INVOKE(MailItemEvents)
             {
               /* Seen the first after write. Advance the state */
               m_mail->set_crypt_state (Mail::NeedsActualCrypt);
-              m_mail->encrypt_sign_start ();
+              if (m_mail->encrypt_sign_start ())
+                {
+                  log_debug ("%s:%s: Encrypt sign start failes.",
+                             SRCNAME, __func__);
+                  m_mail->set_crypt_state (Mail::NoCryptMail);
+                }
               return S_OK;
             }
           if (m_mail->crypt_state () == Mail::NeedsSecondAfterWrite)

commit 71334bacf78074889138d9328a18a205e8fd86cd
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 16:55:35 2018 +0200

    Handle encrypt / sign on empty message
    
    * src/cryptcontroller.cpp (CryptController::collect_data):
    Handle empty message.

diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp
index da2454f..3e343e0 100644
--- a/src/cryptcontroller.cpp
+++ b/src/cryptcontroller.cpp
@@ -111,7 +111,9 @@ CryptController::collect_data ()
   int n_att_usable = count_usable_attachments (att_table);
   if (!n_att_usable && !body)
     {
-      log_error ("%s:%s: encrypt empty message", SRCNAME, __func__);
+      gpgol_message_box (m_mail->get_window(),
+                         utf8_gettext ("Can't encrypt / sign an empty message."),
+                         utf8_gettext ("GpgOL"), MB_OK);
       gpgol_release (message);
       xfree (body);
       return -1;

commit b2727a00c02520ca603f5c1dad0d181348f2c63f
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 16:41:00 2018 +0200

    Abort if mail has no body and no attachments
    
    * src/cryptcontroller.cpp (CryptController::collect_data):
    Abort if no body and no attachments.

diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp
index d26501d..da2454f 100644
--- a/src/cryptcontroller.cpp
+++ b/src/cryptcontroller.cpp
@@ -97,7 +97,7 @@ CryptController::collect_data ()
   if (body && !*body)
     {
       xfree (body);
-      body = NULL;
+      body = nullptr;
     }
 
   LPMESSAGE message = get_oom_base_message (m_mail->item ());
@@ -111,7 +111,10 @@ CryptController::collect_data ()
   int n_att_usable = count_usable_attachments (att_table);
   if (!n_att_usable && !body)
     {
-      log_debug ("%s:%s: encrypt empty message", SRCNAME, __func__);
+      log_error ("%s:%s: encrypt empty message", SRCNAME, __func__);
+      gpgol_release (message);
+      xfree (body);
+      return -1;
     }
 
   bool do_inline = m_mail->should_inline_crypt ();

commit a683aac7f165e2fb97006e634afd53639bf57fef
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 16:13:36 2018 +0200

    Add gpgol_bug helper function
    
    * src/common.c, src/common.h (gpgol_bug): New.
    * src/mail.cpp (do_crypt): Use it.
    
    --
    This is a little helper to reuse the same message if we
    think a user visible error / bug should be done.

diff --git a/src/common.c b/src/common.c
index adda352..6f1ac56 100644
--- a/src/common.c
+++ b/src/common.c
@@ -1058,6 +1058,22 @@ gpgol_message_box (HWND parent, const char *utf8_text,
   return ret;
 }
 
+void
+gpgol_bug (HWND parent, int code)
+{
+  const char *bugmsg = utf8_gettext ("Operation failed.\n\n"
+                "This is usually caused by a bug in GpgOL or an error in your setup.\n"
+                "Please see https://www.gpg4win.org/reporting-bugs.html "
+                "or ask your Administrator for support.");
+  char *with_code;
+  gpgrt_asprintf (&with_code, "%s\nCode: %i", bugmsg, code);
+  gpgol_message_box (parent,
+                     with_code,
+                     _("GpgOL Error"), MB_OK);
+  xfree (with_code);
+  return;
+}
+
 static char*
 expand_path (const char *path)
 {
diff --git a/src/common.h b/src/common.h
index c8e32df..7f13d04 100644
--- a/src/common.h
+++ b/src/common.h
@@ -150,6 +150,13 @@ void bring_to_front (HWND wid);
 
 int gpgol_message_box (HWND parent, const char *utf8_text,
                        const char *utf8_caption, UINT type);
+
+/* Show a bug message with the code. */
+void gpgol_bug (HWND parent, int code);
+
+#define ERR_CRYPT_RESOLVER_FAILED 1
+#define ERR_WANTS_SEND_MIME_BODY 2
+#define ERR_WANTS_SEND_INLINE_BODY 3
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/mail.cpp b/src/mail.cpp
index 0cd9259..3855300 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -824,12 +824,8 @@ do_crypt (LPVOID arg)
     {
       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);
+      gpgol_bug (mail->get_window (),
+                 ERR_CRYPT_RESOLVER_FAILED);
     }
 
   mail->set_window_enabled (true);

commit 52c80aec174d6c0329e0dce0acf72e282e3b6c9a
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 16:12:40 2018 +0200

    Document how encryption is done in do_crypt
    
    * src/mail.cpp (do_crypt): Add explaining comment about the
    states.

diff --git a/src/mail.cpp b/src/mail.cpp
index 6e0a8c8..0cd9259 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -701,6 +701,77 @@ do_parsing (LPVOID arg)
   return 0;
 }
 
+/* How encryption is done:
+
+   There are two modes of encryption. Synchronous and Async.
+   If async is used depends on the value of mail->is_inline_response.
+
+   Synchronous crypto:
+
+   > Send Event < | State NoCryptMail
+   Needs Crypto ? (get_gpgol_draft_info_flags != 0)
+
+   -> No:
+      Pass send -> unencrypted mail.
+
+   -> Yes:
+      mail->update_oom_data
+      State = Mail::NeedsFirstAfterWrite
+      check_inline_response
+      invoke_oom_method (m_object, "Save", NULL);
+
+      > Write Event <
+      Pass because is_crypto_mail is false (not a decrypted mail)
+
+      > AfterWrite Event < | State NeedsFirstAfterWrite
+      State = NeedsActualCrypo
+      encrypt_sign_start
+        collect_input_data
+        -> Check if Inline PGP should be used
+        do_crypt
+          -> Resolve keys / do crypto
+
+          State = NeedsUpdateInMAPI
+          update_crypt_mapi
+          crypter->update_mail_mapi
+           if (inline) (Meaning PGP/Inline)
+          <-- do nothing.
+           else
+            build MSOXSMIME attachment and clear body / attachments.
+
+          State = NeedsUpdateInOOM
+      <- Back to Send Event
+      update_crypt_oom
+        -> Cleans body or sets PGP/Inline body. (inline_body_to_body)
+      State = WantsSendMIME or WantsSendInline
+
+      -> Saftey check "has_crypted_or_empty_body"
+      -> If MIME Mail do the T3656 check.
+
+    Send.
+
+    State order for "inline_response" (sync) Mails.
+    NoCryptMail
+    NeedsFirstAfterWrite
+    NeedsActualCrypto
+    NeedsUpdateInMAPI
+    NeedsUpdateInOOM
+    WantsSendMIME (or inline for PGP Inline)
+    -> Send.
+
+    State order for async Mails
+    NoCryptMail
+    NeedsFirstAfterWrite
+    NeedsActualCrypto
+    -> Cancel Send.
+    Windowmessages -> Crypto Done
+    NeedsUpdateInOOM
+    NeedsSecondAfterWrite
+    trigger Save.
+    NeedsUpdateInMAPI
+    WantsSendMIME
+    trigger Send.
+*/
 static DWORD WINAPI
 do_crypt (LPVOID arg)
 {
@@ -724,7 +795,7 @@ do_crypt (LPVOID arg)
       return -1;
     }
 
-  /* This takes a shared ptr of parser. So the parser is
+  /* This takes a shared ptr of crypter. So the crypter is
      still valid when the mail is deleted. */
   auto crypter = mail->crypter();
   gpgrt_lock_unlock (&dtor_lock);

commit a80c7502c45b2fc516b9b31e90dc3b858527850a
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Mar 26 08:47:57 2018 +0200

    Don't carry around inline crypt state twice
    
    * src/cryptcontroller.cpp, src/cryptcontroller.h: Replace
    m_inline member variable with access to Mail::should_inline_crypt.
    * src/mail.h: Add set_should_inline_crypt.
    * src/mail.cpp: Update callers.
    
    --
    Having two inline states adds complexity and might lead to
    wrong results. E.g. Mail::should_inline_crypt would not change
    when the cryptcontroller detected attachments.
    
    GnuPG-Bug-Id: T3863

diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp
index dc07146..d26501d 100644
--- a/src/cryptcontroller.cpp
+++ b/src/cryptcontroller.cpp
@@ -60,16 +60,15 @@ create_sign_attach (sink_t sink, protocol_t protocol,
   from this.
 */
 CryptController::CryptController (Mail *mail, bool encrypt, bool sign,
-                                  bool doInline, GpgME::Protocol proto):
+                                  GpgME::Protocol proto):
     m_mail (mail),
     m_encrypt (encrypt),
     m_sign (sign),
-    m_inline (doInline),
     m_crypto_success (false),
     m_proto (proto)
 {
   log_debug ("%s:%s: CryptController ctor for %p encrypt %i sign %i inline %i.",
-             SRCNAME, __func__, mail, encrypt, sign, doInline);
+             SRCNAME, __func__, mail, encrypt, sign, mail->should_inline_crypt ());
   m_recipient_addrs = mail->take_cached_recipients ();
 }
 
@@ -115,14 +114,17 @@ CryptController::collect_data ()
       log_debug ("%s:%s: encrypt empty message", SRCNAME, __func__);
     }
 
-  if (n_att_usable && m_inline)
+  bool do_inline = m_mail->should_inline_crypt ();
+
+  if (n_att_usable && do_inline)
     {
       log_debug ("%s:%s: PGP Inline not supported for attachments."
                  " Using PGP MIME",
                  SRCNAME, __func__);
-      m_inline = false;
+      do_inline = false;
+      m_mail->set_should_inline_crypt (false);
     }
-  else if (m_inline)
+  else if (do_inline)
     {
       /* Inline. Use Body as input.
         We need to collect also our mime structure for S/MIME
@@ -521,12 +523,14 @@ CryptController::do_crypto ()
       // Cancel
       return -2;
     }
+  bool do_inline = m_mail->should_inline_crypt ();
 
-  if (m_proto == GpgME::CMS && m_inline)
+  if (m_proto == GpgME::CMS && do_inline)
     {
       log_debug ("%s:%s: Inline for S/MIME not supported. Switching to mime.",
                  SRCNAME, __func__);
-      m_inline = false;
+      do_inline = false;
+      m_mail->set_should_inline_crypt (false);
       m_bodyInput = GpgME::Data(GpgME::Data::null);
     }
 
@@ -549,11 +553,11 @@ CryptController::do_crypto ()
   ctx->setTextMode (m_proto == GpgME::OpenPGP);
   ctx->setArmor (m_proto == GpgME::OpenPGP);
 
-  if (m_encrypt && m_sign && m_inline)
+  if (m_encrypt && m_sign && do_inline)
     {
       // Sign encrypt combined
       const auto result_pair = ctx->signAndEncrypt (m_recipients,
-                                                    m_inline ? m_bodyInput : m_input,
+                                                    do_inline ? m_bodyInput : m_input,
                                                     m_output,
                                                     GpgME::Context::AlwaysTrust);
 
@@ -634,7 +638,7 @@ CryptController::do_crypto ()
     }
   else if (m_encrypt)
     {
-      const auto result = ctx->encrypt (m_recipients, m_inline ? m_bodyInput : m_input,
+      const auto result = ctx->encrypt (m_recipients, do_inline ? m_bodyInput : m_input,
                                         m_output,
                                         GpgME::Context::AlwaysTrust);
       if (result.error())
@@ -652,8 +656,8 @@ CryptController::do_crypto ()
     }
   else if (m_sign)
     {
-      const auto result = ctx->sign (m_inline ? m_bodyInput : m_input, m_output,
-                                     m_inline ? GpgME::Clearsigned :
+      const auto result = ctx->sign (do_inline ? m_bodyInput : m_input, m_output,
+                                     do_inline ? GpgME::Clearsigned :
                                      GpgME::Detached);
       if (result.error())
         {
@@ -855,7 +859,7 @@ CryptController::update_mail_mapi ()
 {
   log_debug ("%s:%s", SRCNAME, __func__);
 
-  if (m_inline)
+  if (m_mail->should_inline_crypt ())
     {
       // Nothing to do for inline.
       log_debug ("%s:%s: Inline mail. No MAPI update.",
@@ -943,7 +947,7 @@ std::string
 CryptController::get_inline_data ()
 {
   std::string ret;
-  if (!m_inline)
+  if (!m_mail->should_inline_crypt ())
     {
       return ret;
     }
diff --git a/src/cryptcontroller.h b/src/cryptcontroller.h
index 9398c5b..67b67c4 100644
--- a/src/cryptcontroller.h
+++ b/src/cryptcontroller.h
@@ -40,7 +40,7 @@ class CryptController
 public:
   /** @brief Construct a Crypthelper for a Mail object. */
   CryptController (Mail *mail, bool encrypt, bool sign,
-                   bool inlineCrypt, GpgME::Protocol proto);
+                   GpgME::Protocol proto);
   ~CryptController ();
 
   /** @brief Collect the data from the mail into the internal
@@ -79,7 +79,7 @@ private:
   Mail *m_mail;
   GpgME::Data m_input, m_bodyInput, m_signedData, m_output;
   std::string m_micalg;
-  bool m_encrypt, m_sign, m_inline, m_crypto_success;
+  bool m_encrypt, m_sign, m_crypto_success;
   GpgME::Protocol m_proto;
   GpgME::Key m_signer_key;
   std::vector<GpgME::Key> m_recipients;
diff --git a/src/mail.cpp b/src/mail.cpp
index 7e8360f..6e0a8c8 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -1150,7 +1150,7 @@ Mail::encrypt_sign_start ()
   GpgME::Protocol proto = opt.enable_smime ? GpgME::UnknownProtocol: GpgME::OpenPGP;
   m_crypter = std::shared_ptr <CryptController> (new CryptController (this, flags & 1,
                                                                       flags & 2,
-                                                                      m_do_inline, proto));
+                                                                      proto));
 
   // Careful from here on we have to check every
   // error condition with window enabling again.
@@ -2447,7 +2447,7 @@ Mail::update_crypt_mapi()
                      SRCNAME, __func__);
           m_crypter = std::shared_ptr <CryptController> (new CryptController (this, false,
                                                                               false,
-                                                                              false, GpgME::UnknownProtocol));
+                                                                              GpgME::UnknownProtocol));
         }
       else
         {
diff --git a/src/mail.h b/src/mail.h
index 7410f61..51604d0 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -385,6 +385,9 @@ public:
   /** Check if the mail should be encrypted "inline" */
   bool should_inline_crypt () const {return m_do_inline;}
 
+  /** Check if the mail should be encrypted "inline" */
+  void set_should_inline_crypt (bool value) {m_do_inline = value;}
+
   /** Append data to a cached inline body. Helper to do this
      on MAPI level and later add it through OOM */
   void append_to_inline_body (const std::string &data);

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

Summary of changes:
 src/common.c            |  16 ++++
 src/common.h            |   9 ++
 src/cryptcontroller.cpp |  43 ++++++----
 src/cryptcontroller.h   |   4 +-
 src/mail.cpp            | 212 +++++++++++++++++++++++++++++++++++++++++++-----
 src/mail.h              |  23 +++++-
 src/mailitem-events.cpp |  41 +++++++++-
 src/mimemaker.cpp       |   2 +-
 8 files changed, 302 insertions(+), 48 deletions(-)


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




More information about the Gnupg-commits mailing list