[git] GpgOL - branch, nomapi, updated. gpgol-1.4.0-85-g0499861

by Andre Heinecke cvs at cvs.gnupg.org
Fri Oct 14 15:15:08 CEST 2016


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, nomapi has been updated
       via  0499861a0dda3fd159d93e3638550e7fcd768501 (commit)
       via  04be440d4d1aad06a6d6f2f9f91a56b4be53d2eb (commit)
       via  d299d6357ed98e31914bfc3cfe09f681b3deb73a (commit)
       via  d3a2f213e0fd0ac0771d57d7af474332b81c63f9 (commit)
       via  cf5689b2cd8226a440e8dbc8b17e226186e52781 (commit)
       via  6cb1c3fd4f31fa90a1cc003a4ae162c89614add4 (commit)
      from  fb3c90c8852edf41ac97ef3e821228dc4a54bafe (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 0499861a0dda3fd159d93e3638550e7fcd768501
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Oct 14 14:42:40 2016 +0200

    Start implementation of ribbon base sigstate
    
    * src/gpgoladdin.cpp (GpgolRibbonExtender::GetIDsOfNames): Register
    new names.
    (GpgolRibbonExtender::Invoke): Handle new names.
    (GetCustomUI_MIME): Reactivate Read code. Use new callbacks.
    (Mail::Mail): Do not cache sig validity.
    (Mail::get_valid_sig): Get Sig / UID pair of the valid sig.
    (Mail::is_valid_sig): Use get_valid_sig.
    (Mail::is_signed): Fix use of temporary parser object.
    (Mail::set_uid): Set uid to be identifyable from callbacks.
    (Mail::get_signature_status): Format string for supertip.
    * src/mail.h: Update accordingly.
    * src/ribbon-callbacks.cpp (get_crypt_status): Removed.
    (get_mail_from_control): New. Helper to resolve the Mail object.
    (MY_MAIL_GETTER): Helper macro for common task.
    (get_is_signed, get_sig_label, get_sig_ttip, get_sig_stip): New
    callbacks.
    (launch_cert_details): Dummy.
    
    --
    This shows the signature state (currently only for valid signatures)
    in the GpgOL ribbon when reading mails. The UID is used to
    identify the according Mail object that belongs to a read inspector.

diff --git a/src/gpgoladdin.cpp b/src/gpgoladdin.cpp
index 21cf950..ac5d399 100644
--- a/src/gpgoladdin.cpp
+++ b/src/gpgoladdin.cpp
@@ -528,10 +528,13 @@ GpgolRibbonExtender::GetIDsOfNames (REFIID riid, LPOLESTR *rgszNames,
       ID_MAPPER (L"signMimeEx", ID_CMD_MIME_SIGN_EX)
       ID_MAPPER (L"getEncryptPressedEx", ID_GET_ENCRYPT_PRESSED_EX)
       ID_MAPPER (L"getSignPressedEx", ID_GET_SIGN_PRESSED_EX)
-      ID_MAPPER (L"ribbonLoaded", ID_ON_LOAD);
+      ID_MAPPER (L"ribbonLoaded", ID_ON_LOAD)
       ID_MAPPER (L"openOptions", ID_CMD_OPEN_OPTIONS)
-      ID_MAPPER (L"getSigStatus", ID_GET_SIG_STATUS)
-      ID_MAPPER (L"getEncStatus", ID_GET_ENC_STATUS)
+      ID_MAPPER (L"getSigLabel", ID_GET_SIG_LABEL)
+      ID_MAPPER (L"getSigSTip", ID_GET_SIG_STIP)
+      ID_MAPPER (L"getSigTip", ID_GET_SIG_TTIP)
+      ID_MAPPER (L"launchDetails", ID_LAUNCH_CERT_DETAILS)
+      ID_MAPPER (L"getIsSigned", ID_GET_IS_SIGNED)
     }
 
   if (cNames > 1)
@@ -603,11 +606,17 @@ GpgolRibbonExtender::Invoke (DISPID dispid, REFIID riid, LCID lcid,
       case ID_GET_SIGN_PRESSED_EX:
         return get_crypt_pressed (parms->rgvarg[0].pdispVal, OP_SIGN,
                                   result, true);
-      case ID_GET_ENC_STATUS:
-        return get_crypt_status (parms->rgvarg[0].pdispVal, OP_ENCRYPT,
-                                 result);
-      case ID_GET_SIG_STATUS:
-        return get_crypt_status (parms->rgvarg[0].pdispVal, OP_SIGN, result);
+      case ID_GET_SIG_STIP:
+        return get_sig_stip (parms->rgvarg[0].pdispVal, result);
+      case ID_GET_SIG_TTIP:
+        return get_sig_ttip (parms->rgvarg[0].pdispVal, result);
+      case ID_GET_SIG_LABEL:
+        return get_sig_label (parms->rgvarg[0].pdispVal, result);
+      case ID_LAUNCH_CERT_DETAILS:
+        return launch_cert_details (parms->rgvarg[0].pdispVal, result);
+      case ID_GET_IS_SIGNED:
+        return get_is_signed (parms->rgvarg[0].pdispVal, result);
+
       case ID_ON_LOAD:
           {
             g_ribbon_uis.push_back (parms->rgvarg[0].pdispVal);
@@ -663,16 +672,6 @@ GetCustomUI_MIME (BSTR RibbonID, BSTR * RibbonXml)
     _("Sign the message and all attachments before sending.");
   const char *optsSTip =
     _("Open the settings dialog for GpgOL.");
-#if 0
-  const char *encryptedTTip =
-    "If this is toggled the message was encrypted. (this is development UI)";
-  const char *encryptedSTip =
-    "TODO insert more details here";
-  const char *signedTTip =
-    "If this is toggled the message was signed. (this is development UI)";
-  const char *signedSTip =
-    "TODO insert more details here";
-#endif
   log_debug ("%s:%s: GetCustomUI_MIME for id: %ls", SRCNAME, __func__, RibbonID);
 
   if (!RibbonXml || !RibbonID)
@@ -724,27 +723,19 @@ GetCustomUI_MIME (BSTR RibbonID, BSTR * RibbonXml)
       gpgrt_asprintf (&buffer,
         "<customUI xmlns=\"http://schemas.microsoft.com/office/2009/07/customui\""
         " onLoad=\"ribbonLoaded\">"
-#if 0
         " <ribbon>"
         "   <tabs>"
         "    <tab idMso=\"TabReadMessage\">"
         "     <group id=\"general\""
         "            label=\"%s\">"
-        "       <toggleButton id=\"idEncrypted\""
-        "               getImage=\"btnCryptStatus\""
-        "               size=\"large\""
-        "               label=\"%s\""
-        "               screentip=\"%s\""
-        "               supertip=\"%s\""
-        "               getEnabled=\"getEncStatus\"/>"
         "       <button id=\"idSigned\""
         "               getImage=\"btnSignLarge\""
         "               size=\"large\""
-        "               label=\"%s\""
-        "               screentip=\"%s\""
-        "               supertip=\"%s\""
-        "               onAction=\"verifyBody\""
-        "               getEnabled=\"getSigStatus\"/>"
+        "               getLabel=\"getSigLabel\""
+        "               getScreentip=\"getSigTip\""
+        "               getSupertip=\"getSigSTip\""
+        "               onAction=\"launchDetails\""
+        "               getEnabled=\"getIsSigned\"/>"
         "       <dialogBoxLauncher>"
         "         <button id=\"optsBtn\""
         "                 onAction=\"openOptions\""
@@ -754,7 +745,6 @@ GetCustomUI_MIME (BSTR RibbonID, BSTR * RibbonXml)
         "    </tab>"
         "   </tabs>"
         " </ribbon>"
-#endif
         "<contextMenus>"
         " <contextMenu idMso=\"ContextMenuAttachments\">"
         "   <button id=\"gpgol_decrypt\""
@@ -764,12 +754,8 @@ GetCustomUI_MIME (BSTR RibbonID, BSTR * RibbonXml)
         " </contextMenu>"
         "</contextMenus>"
         "</customUI>",
-#if 0
         _("GpgOL"),
-        _("Encrypted"), encryptedTTip, encryptedSTip,
-        _("Signed"), signedTTip, signedSTip,
         optsSTip,
-#endif
         _("Decrypt")
         );
     }
diff --git a/src/mail.cpp b/src/mail.cpp
index 953d085..e50b466 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -85,7 +85,6 @@ Mail::Mail (LPDISPATCH mailitem) :
     m_crypt_successful(false),
     m_is_smime(false),
     m_is_smime_checked(false),
-    m_is_valid_sig(false),
     m_moss_position(0),
     m_sender(NULL),
     m_type(MSGTYPE_UNKNOWN)
@@ -560,8 +559,6 @@ Mail::parsing_done()
   m_verify_result = m_parser->verify_result ();
   m_needs_wipe = true;
 
-  /* Check our validity */
-  is_valid_sig ();
   /* Set categories according to the result. */
   update_categories();
 
@@ -875,26 +872,30 @@ Mail::close_inspector ()
   return 0;
 }
 
-bool
-Mail::is_valid_sig ()
+const std::pair <Signature, UserID>
+Mail::get_valid_sig ()
 {
   const char *sender = get_sender();
+  std::pair <Signature, UserID> ret;
 
-  static bool sig_checked;
-
-  if (m_verify_result.isNull())
+  if (!sender)
     {
-      return false;
+      log_error ("%s:%s:%i", SRCNAME, __func__, __LINE__);
+      return ret;
     }
-  if (sig_checked)
+
+  if (m_verify_result.isNull())
     {
-      return m_is_valid_sig;
+      log_debug ("%s:%s: No verify result.",
+                 SRCNAME, __func__);
+      return ret;
     }
 
-  if (m_verify_result.error() || !sender)
+  if (m_verify_result.error())
     {
-      m_is_valid_sig = false;
-      sig_checked = true;
+      log_debug ("%s:%s: verify error.",
+                 SRCNAME, __func__);
+      return ret;
     }
 
   for (const auto sig: m_verify_result.signatures())
@@ -942,13 +943,20 @@ Mail::is_valid_sig ()
                 }
               log_debug ("%s:%s: Classified sender as verified",
                          SRCNAME, __func__);
-              m_is_valid_sig = true;
-              break;
+              return std::pair<Signature, UserID> (sig, uid);
             }
         }
     }
-  sig_checked = true;
-  return m_is_valid_sig;
+  log_debug ("%s:%s: No signature with enough trust.",
+             SRCNAME, __func__);
+  return ret;
+}
+
+bool
+Mail::is_valid_sig ()
+{
+   const auto pair = get_valid_sig();
+   return !pair.first.isNull() && !pair.second.isNull();
 }
 
 void
@@ -969,7 +977,7 @@ Mail::update_categories ()
       remove_category (m_mailitem, decCategory);
     }
 
-  if (m_is_valid_sig)
+  if (is_valid_sig())
     {
       add_category (m_mailitem, verifyCategory);
     }
@@ -983,10 +991,75 @@ Mail::update_categories ()
 bool
 Mail::is_signed()
 {
-  if (!m_parser)
+  return m_verify_result.numSignatures() > 0;
+}
+
+int
+Mail::set_uid()
+{
+  if (!m_uid.empty())
     {
-      return false;
+      return 0;
+    }
+  char *uid = get_unique_id (m_mailitem, 1);
+
+  if (!uid)
+    {
+      log_debug ("%s:%s: Failed to get uid for %p",
+                 SRCNAME, __func__, m_mailitem);
+      return -1;
+    }
+  m_uid = uid;
+  xfree (uid);
+  g_uid_map.insert (std::pair<std::string, Mail *> (m_uid, this));
+  return 0;
+}
+
+std::string
+Mail::get_signature_status()
+{
+  std::string message;
+  if (!is_signed())
+    {
+      return _("This message is not signed.\nYou cannot be sure who wrote the message.");
+    }
+
+  const auto pair = get_valid_sig ();
+  const auto sig = pair.first;
+  const auto uid = pair.second;
+  char *buf;
+  bool isOpenPGP = sig.key().protocol() == Protocol::OpenPGP;
+  if (!sig.isNull () && !uid.isNull ())
+    {
+      /* We are valid */
+      gpgrt_asprintf (&buf, _("The signature is valid because:\n\nThe used %s %s"),
+                      isOpenPGP ? _("key") : _("certificate"),
+                      sig.validity() == Signature::Validity::Ultimate ?
+                      _("is marked as your own.") :
+                      sig.validity() == Signature::Validity::Full && isOpenPGP ?
+                      _("was certified by enough trusted keys.") :
+                      "");
+      message += buf;
+      xfree (buf);
+      if (sig.validity() == Signature::Validity::Full && !isOpenPGP)
+        {
+          gpgrt_asprintf (&buf, _("is cerified by the trusted issuer:\n'%s'\n"),
+                          sig.key().issuerName());
+          message += buf;
+          xfree (buf);
+        }
+      else if (sig.validity() == Signature::Validity::Marginal)
+        {
+          gpgrt_asprintf (&buf, _("was consistently used for %i messages since %lu."),
+                          uid.tofuInfo().signCount (), uid.tofuInfo().signFirst());
+          message += buf;
+          xfree (buf);
+        }
     }
-  const auto result = m_parser->verify_result ();
-  return result.numSignatures() > 0;
+  message += "\n\n";
+  gpgrt_asprintf (&buf, _("Click here for details about the %s."),
+                  isOpenPGP ? _("key") : _("certificate."));
+  message += buf;
+  xfree (buf);
+  return message;
 }
diff --git a/src/mail.h b/src/mail.h
index fcacfba..e715504 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -25,6 +25,7 @@
 #include "mapihelp.h"
 #include "gpgme++/verificationresult.h"
 #include "gpgme++/decryptionresult.h"
+#include "gpgme++/key.h"
 
 #include <string>
 #include <future>
@@ -210,11 +211,27 @@ public:
     signature. Regardless of the validity of the mail */
   bool is_signed ();
 
-  /** Returns true if the mail was verified and the validity
+  /** Returns a non null signature / uid if the mail was verified and the validity
     was high enough that we treat it as "verified sender" in
-    the UI. */
+    the UI. The signature / uid pair returned is the signature that was used
+    to determine the verified sender in that case. */
+  const std::pair<GpgME::Signature, GpgME::UserID> get_valid_sig ();
+
+  /** Small helper to check if get_valid_sig returns non null results. */
   bool is_valid_sig ();
 
+  /** Get UID gets UniqueID property of this mail. Returns
+    an empty string if the uid was not set with set uid.*/
+  const std::string & get_uid () const { return m_uid; }
+
+  /** Returns 0 on success if the mail has a uid alrady or sets
+    the uid. Setting only succeeds if the OOM is currently
+    accessible. Returns -1 on error. */
+  int set_uid ();
+
+  /** Returns a localized string describing the signature state
+    of this mail. */
+  std::string get_signature_status ();
 private:
   void update_categories ();
   void update_body ();
@@ -226,8 +243,7 @@ private:
        m_needs_save,   /* A property was changed but not by us. */
        m_crypt_successful, /* We successfuly performed crypto on the item. */
        m_is_smime, /* This is an smime mail. */
-       m_is_smime_checked, /* it was checked if this is an smime mail */
-       m_is_valid_sig; /* We treat the signature as valid (verified) */
+       m_is_smime_checked; /* it was checked if this is an smime mail */
   int m_moss_position; /* The number of the original message attachment. */
   char *m_sender;
   msgtype_t m_type; /* Our messagetype as set in mapi */
diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp
index 12f40e7..f9c47d7 100644
--- a/src/ribbon-callbacks.cpp
+++ b/src/ribbon-callbacks.cpp
@@ -47,6 +47,7 @@
 #include "filetype.h"
 #include "gpgolstr.h"
 #include "message.h"
+#include "mail.h"
 
 #define OPAQUE_SIGNED_MARKER "-----BEGIN PGP MESSAGE-----"
 
@@ -1402,78 +1403,151 @@ done:
   return S_OK;
 }
 
-/* Get the encrypt / sign status of this mail. */
-HRESULT get_crypt_status (LPDISPATCH ctrl, int flags, VARIANT *result)
+static Mail *
+get_mail_from_control (LPDISPATCH ctrl)
 {
   HRESULT hr;
   LPDISPATCH context = NULL,
              mailitem = NULL;
-  LPMESSAGE message = NULL;
-  char *sigstat;
-
-  /* First the usual defensive check about our parameters */
-  if (!ctrl || !result)
+  if (!ctrl)
     {
       log_error ("%s:%s:%i", SRCNAME, __func__, __LINE__);
-      return E_FAIL;
+      return NULL;
     }
-
-  result->vt = VT_BOOL | VT_BYREF;
-  result->pboolVal = (VARIANT_BOOL*) xmalloc (sizeof (VARIANT_BOOL));
-
   hr = getContext (ctrl, &context);
 
   if (hr)
     {
       log_error ("%s:%s:%i : hresult %lx", SRCNAME, __func__, __LINE__,
                  hr);
-      return E_FAIL;
+      return NULL;
     }
 
   mailitem = get_oom_object (context, "CurrentItem");
-
+  gpgol_release (context);
   if (!mailitem)
     {
       log_error ("%s:%s: Failed to get mailitem.",
                  SRCNAME, __func__);
-      goto done;
+      return NULL;
     }
 
-  message = get_oom_base_message (mailitem);
+  /* Get the uid of this item. */
+  char *uid = get_unique_id (mailitem, 0);
+  gpgol_release (mailitem);
+  if (!uid)
+    {
+      log_oom ("%s:%s: Failed to get uid for %p .",
+               SRCNAME, __func__, mailitem);
+      return NULL;
+    }
 
-  if (!message)
+  auto ret = Mail::get_mail_for_uid (uid);
+  xfree (uid);
+  if (!ret)
     {
-      log_error ("%s:%s: No message found.",
+      log_error ("%s:%s: Failed to find mail %p in map.",
+                 SRCNAME, __func__, mailitem);
+    }
+  gpgol_release (mailitem);
+  return ret;
+}
+
+/* Helper to reduce code duplication.*/
+#define MY_MAIL_GETTER \
+  if (!ctrl || !result) \
+    { \
+      log_error ("%s:%s:%i", SRCNAME, __func__, __LINE__); \
+      return E_FAIL; \
+    } \
+  const auto mail = get_mail_from_control (ctrl); \
+  if (!mail) \
+    { \
+      log_oom ("%s:%s:%i Failed to get mail", \
+               SRCNAME, __func__, __LINE__); \
+    }
+
+HRESULT get_is_signed (LPDISPATCH ctrl, VARIANT *result)
+{
+  MY_MAIL_GETTER
+
+  result->vt = VT_BOOL | VT_BYREF;
+  result->pboolVal = (VARIANT_BOOL*) xmalloc (sizeof (VARIANT_BOOL));
+  *(result->pboolVal) = !mail ? VARIANT_FALSE :
+                        mail->is_signed () ? VARIANT_TRUE : VARIANT_FALSE;
+
+  return S_OK;
+}
+
+HRESULT get_sig_label (LPDISPATCH ctrl, VARIANT *result)
+{
+  MY_MAIL_GETTER
+
+  result->vt = VT_BSTR;
+  wchar_t *w_result;
+  if (!mail)
+    {
+      log_debug ("%s:%s: No mail.",
                  SRCNAME, __func__);
-      goto done;
     }
+  if (mail && mail->is_valid_sig ())
+    {
+      w_result = utf8_to_wchar (_("Verified Sender"));
+    }
+  else
+    {
+      w_result = utf8_to_wchar (_("Unverified Sender"));
+    }
+  result->bstrVal = SysAllocString (w_result);
+  xfree (w_result);
+  return S_OK;
+}
 
-  sigstat = mapi_get_sig_status (message);
-  /* sigstat will never be NULL */
-  if (flags & OP_SIGN)
+HRESULT get_sig_ttip (LPDISPATCH ctrl, VARIANT *result)
+{
+  MY_MAIL_GETTER
+
+  result->vt = VT_BSTR;
+  wchar_t *w_result;
+  if (mail && mail->is_signed ())
     {
-      *(result->pboolVal) = *sigstat == '!' ? VARIANT_TRUE : VARIANT_FALSE;
+      char *buf;
+      gpgrt_asprintf (&buf, _("This is a signed %s message."),
+                      mail->is_smime() ? _("S/MIME") : _("OpenPGP"));
+      w_result = utf8_to_wchar (buf);
+      xfree(buf);
     }
-  else if (flags & OP_ENCRYPT)
+  else
     {
-      msgtype_t type = mapi_get_message_type (message);
-      /* FIXME: This reports encrypted for Opaque signed messages ! */
-      if (type == MSGTYPE_GPGOL_OPAQUE_ENCRYPTED ||
-          type == MSGTYPE_GPGOL_PGP_MESSAGE ||
-          type == MSGTYPE_GPGOL_MULTIPART_ENCRYPTED)
-        {
-          *(result->pboolVal) = VARIANT_TRUE;
-        }
-      else
-        {
-          *(result->pboolVal) = VARIANT_FALSE;
-        }
+      w_result = utf8_to_wchar (_("This message is not cryptographically signed"));
     }
+  result->bstrVal = SysAllocString (w_result);
+  xfree (w_result);
+  return S_OK;
+}
 
-done:
-  gpgol_release (context);
-  gpgol_release (mailitem);
-  gpgol_release (message);
+HRESULT get_sig_stip (LPDISPATCH ctrl, VARIANT *result)
+{
+  MY_MAIL_GETTER
 
+  result->vt = VT_BSTR;
+  if (!mail)
+    {
+      log_debug ("%s:%s: No mail.",
+                 SRCNAME, __func__);
+      result->bstrVal = SysAllocString (L"");
+      return S_OK;
+    }
+  const auto message = mail->get_signature_status ();
+  wchar_t *w_message = utf8_to_wchar (message.c_str());
+  result->bstrVal = SysAllocString (w_message);
+  xfree (w_message);
+  return S_OK;
+}
+
+HRESULT launch_cert_details (LPDISPATCH ctrl, VARIANT *result)
+{
+  (void) ctrl;
+  (void) result;
   return S_OK;
 }
diff --git a/src/ribbon-callbacks.h b/src/ribbon-callbacks.h
index 0c72f74..8dad389 100644
--- a/src/ribbon-callbacks.h
+++ b/src/ribbon-callbacks.h
@@ -42,12 +42,15 @@
 #define ID_GET_ENCRYPT_PRESSED  16
 #define ID_ON_LOAD              17
 #define ID_CMD_OPEN_OPTIONS     18
-#define ID_GET_SIG_STATUS       19
-#define ID_GET_ENC_STATUS       20
+#define ID_GET_IS_SIGNED        19
 #define ID_CMD_MIME_SIGN_EX     21
 #define ID_CMD_MIME_ENCRYPT_EX  22
 #define ID_GET_SIGN_PRESSED_EX  23
 #define ID_GET_ENCRYPT_PRESSED_EX 24
+#define ID_GET_SIG_STIP         25
+#define ID_GET_SIG_TTIP         26
+#define ID_GET_SIG_LABEL        27
+#define ID_LAUNCH_CERT_DETAILS  28
 
 #define ID_BTN_CERTMANAGER       IDI_KEY_MANAGER_64_PNG
 #define ID_BTN_DECRYPT           IDI_DECRYPT_16_PNG
@@ -77,8 +80,16 @@ HRESULT verifyBody (LPDISPATCH ctrl);
 HRESULT get_crypt_pressed (LPDISPATCH ctrl, int flags, VARIANT *result, bool is_explorer);
 /* Mark the mail to be mime encrypted on send. Flags as above */
 HRESULT mark_mime_action (LPDISPATCH ctrl, int flags, bool is_explorer);
-/* Get the general crypto status / if the buttons should be toggled. */
-HRESULT get_crypt_status (LPDISPATCH ctrl, int flags, VARIANT *result);
+/* Check the if the mail was signed. Returns BOOL */
+HRESULT get_is_signed (LPDISPATCH ctrl, VARIANT *result);
+/* Get the label for the signature. Returns BSTR */
+HRESULT get_sig_label (LPDISPATCH ctrl, VARIANT *result);
+/* Get the tooltip for the signature. Returns BSTR */
+HRESULT get_sig_ttip (LPDISPATCH ctrl, VARIANT *result);
+/* Get the supertip for the signature. Returns BSTR */
+HRESULT get_sig_stip (LPDISPATCH ctrl, VARIANT *result);
+/* Show a certificate details dialog. Returns nothing. */
+HRESULT launch_cert_details (LPDISPATCH ctrl, VARIANT *result);
 /* Callback to get our own control reference */
 HRESULT ribbon_loaded (LPDISPATCH ctrl);
 #endif

commit 04be440d4d1aad06a6d6f2f9f91a56b4be53d2eb
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Oct 14 14:36:37 2016 +0200

    Add UID to mails / mail objects
    
    * src/Makefile.am: Link librpcrt4 for uid functions.
    * src/mail.cpp (g_uid_map): New.
    (Mail::~Mail): Remove from uid map if added.
    (Mail::get_mail_for_uid): New. Get Mail object for uid.
    (Mail::is_mail_valid, Mail::is_valid_ptr): Renamd is_mail_valid
    to is_valid_ptr to avoid confusion.
    (Mail::decrypt_verify): Set uid.
    * src/mail.h: Update accordingly.
    * src/oomhelp.cpp (generate_uid, get_unique_id): New.
    (set_pa_variant): Changed to put_pa_string.
    * src/oomhelp.h: Update accordingly.
    (GPGOL_UID_DASL): Declare.
    * src/windowmessages.cpp (gpgol_window_proc): Use is_mail_valid.
    
    --
    The unique identifier allows us to find the according mail object
    even if the pointer to the mailitem differs. This is usefull
    because mailitem pointers obtained over the ribbon context differ
    from the one we get on ItemLoad.

diff --git a/src/Makefile.am b/src/Makefile.am
index 8613260..6909886 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -131,7 +131,7 @@ gpgol_LDADD = $(srcdir)/gpgol.def  \
 	-L . -lgpgmepp -lgpgme -lassuan -lgpg-error \
 	-lmapi32 -lshell32 -lgdi32 -lcomdlg32 \
 	-lole32 -loleaut32 -lws2_32 -ladvapi32 \
-	-luuid -lgdiplus
+	-luuid -lgdiplus -lrpcrt4
 
 resource.o: resource.rc versioninfo.rc dialogs.rc dialogs.h
 
diff --git a/src/mail.cpp b/src/mail.cpp
index 5b55093..953d085 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -45,6 +45,7 @@
 using namespace GpgME;
 
 static std::map<LPDISPATCH, Mail*> g_mail_map;
+static std::map<std::string, Mail*> g_uid_map;
 
 #define COPYBUFSIZE (8 * 1024)
 
@@ -122,6 +123,15 @@ Mail::~Mail()
       g_mail_map.erase (it);
     }
 
+  if (!m_uid.empty())
+    {
+      auto it2 = g_uid_map.find(m_uid);
+      if (it2 != g_uid_map.end())
+        {
+          g_uid_map.erase (it2);
+        }
+    }
+
   xfree (m_sender);
   gpgol_release(m_mailitem);
 }
@@ -142,8 +152,23 @@ Mail::get_mail_for_item (LPDISPATCH mailitem)
   return it->second;
 }
 
+Mail *
+Mail::get_mail_for_uid (const char *uid)
+{
+  if (!uid)
+    {
+      return NULL;
+    }
+  auto it = g_uid_map.find(std::string(uid));
+  if (it == g_uid_map.end())
+    {
+      return NULL;
+    }
+  return it->second;
+}
+
 bool
-Mail::is_mail_valid (const Mail *mail)
+Mail::is_valid_ptr (const Mail *mail)
 {
   auto it = g_mail_map.begin();
   while (it != g_mail_map.end())
@@ -452,7 +477,7 @@ Mail::decrypt_verify()
                  SRCNAME, __func__, m_mailitem);
       return 1;
     }
-
+  set_uid ();
   m_processed = true;
   /* Insert placeholder */
   char *placeholder_buf;
diff --git a/src/mail.h b/src/mail.h
index 75bd335..fcacfba 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -62,12 +62,21 @@ public:
   */
   static Mail* get_mail_for_item (LPDISPATCH mailitem);
 
+  /** @brief looks for existing Mail objects in the uid map.
+    Only objects for which set_uid has been called can be found
+    in the uid map. Get the UID of a mailitem thorugh get_unique_id
+
+    @returns A reference to an existing mailitem or NULL in case none
+    could be found.
+  */
+  static Mail* get_mail_for_uid (const char *uid);
+
   /** @brief looks for existing Mail objects.
 
     @returns A reference to an existing mailitem or NULL in case none
     could be found. Can be used to check if a mail object was destroyed.
   */
-  static bool is_mail_valid (const Mail *mail);
+  static bool is_valid_ptr (const Mail *mail);
 
   /** @brief wipe the plaintext from all known Mail objects.
     *
diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp
index 8e107c5..cca297b 100644
--- a/src/oomhelp.cpp
+++ b/src/oomhelp.cpp
@@ -25,6 +25,7 @@
 #include <windows.h>
 #include <olectl.h>
 #include <string>
+#include <rpc.h>
 
 #include "myexchext.h"
 #include "common.h"
@@ -813,7 +814,7 @@ get_oom_context_window (LPDISPATCH context)
 }
 
 int
-set_pa_variant (LPDISPATCH pDisp, const char *dasl_id, VARIANT *value)
+put_pa_string (LPDISPATCH pDisp, const char *dasl_id, const char *value)
 {
   LPDISPATCH propertyAccessor;
   VARIANT cVariant[2];
@@ -854,7 +855,10 @@ set_pa_variant (LPDISPATCH pDisp, const char *dasl_id, VARIANT *value)
   xfree (w_property);
 
   /* Variant 0 carries the data. */
-  VariantCopy (&cVariant[0], value);
+  wchar_t *w_value = utf8_to_wchar (value);
+  BSTR b_value = SysAllocString(w_value);
+  cVariant[0].vt = VT_BSTR;
+  cVariant[0].bstrVal = b_value;
 
   /* Variant 1 is the DASL as found out by experiments. */
   cVariant[1].vt = VT_BSTR;
@@ -868,6 +872,7 @@ set_pa_variant (LPDISPATCH pDisp, const char *dasl_id, VARIANT *value)
                                  DISPATCH_METHOD, &dispparams,
                                  &rVariant, &execpinfo, &argErr);
   SysFreeString (b_property);
+  SysFreeString (b_value);
   VariantClear (&cVariant[0]);
   gpgol_release (propertyAccessor);
   if (hr != S_OK)
@@ -1553,3 +1558,60 @@ remove_category (LPDISPATCH mail, const char *category)
 
   return put_oom_string (mail, "Categories", newstr.c_str ());
 }
+
+static char *
+generate_uid ()
+{
+  UUID uuid;
+  UuidCreate (&uuid);
+
+  unsigned char *str;
+  UuidToStringA (&uuid, &str);
+
+  char *ret = strdup ((char*)str);
+  RpcStringFreeA (&str);
+
+  return ret;
+}
+
+char *
+get_unique_id (LPDISPATCH mail, int create)
+{
+  if (!mail)
+    {
+      return NULL;
+    }
+
+  /* Get the User Properties. */
+  char *uid = get_pa_string (mail, GPGOL_UID_DASL);
+  if (!uid)
+    {
+      log_debug ("%s:%s: No uuid found for '%p'",
+                 SRCNAME, __func__, mail);
+      if (!create)
+        {
+          return NULL;
+        }
+    }
+  else
+    {
+      log_debug ("%s:%s: Found uid '%s' for '%p'",
+                 SRCNAME, __func__, uid, mail);
+      return uid;
+    }
+  char *newuid = generate_uid ();
+  int ret = put_pa_string (mail, GPGOL_UID_DASL, newuid);
+
+  if (ret)
+    {
+      log_debug ("%s:%s: failed to set uid '%s' for '%p'",
+                 SRCNAME, __func__, newuid, mail);
+      xfree (newuid);
+      return NULL;
+    }
+
+
+  log_debug ("%s:%s: '%p' has now the uid: '%s' ",
+             SRCNAME, __func__, mail, newuid);
+  return newuid;
+}
diff --git a/src/oomhelp.h b/src/oomhelp.h
index 8654505..e9ab03a 100644
--- a/src/oomhelp.h
+++ b/src/oomhelp.h
@@ -85,6 +85,9 @@ DEFINE_OLEGUID(IID_IOleWindow,                0x00000114, 0, 0);
 #define GPGOL_ATTACHTYPE_DASL \
   "http://schemas.microsoft.com/mapi/string/" \
   "{31805AB8-3E92-11DC-879C-00061B031004}/GpgOL Attach Type/0x00000003"
+#define GPGOL_UID_DASL \
+  "http://schemas.microsoft.com/mapi/string/" \
+  "{31805AB8-3E92-11DC-879C-00061B031004}/GpgOL UID/0x0000001F"
 #define PR_ATTACH_DATA_BIN_DASL \
   "http://schemas.microsoft.com/mapi/proptag/0x37010102"
 #define PR_BODY_W_DASL \
@@ -182,7 +185,7 @@ get_pa_int (LPDISPATCH pDisp, const char *property, int *rInt);
    property.
 */
 int
-set_pa_variant (LPDISPATCH pDisp, const char *dasl_id, VARIANT *value);
+put_pa_string (LPDISPATCH pDisp, const char *dasl_id, const char *value);
 
 /* Look up a variant with the propertyAccessor interface */
 int
@@ -276,6 +279,15 @@ add_category (LPDISPATCH mail, const char *category);
 int
 remove_category (LPDISPATCH mail, const char *category);
 
+/* Get a unique identifier for a mail object. The
+   uuid is a custom property. If create is set
+   a new uuid will be added if none exists and the
+   value of that uuid returned.
+
+   Return value has to be freed by the caller.
+   */
+char *
+get_unique_id (LPDISPATCH mail, int create);
 
 #ifdef __cplusplus
 }
diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp
index db7b243..7825e9c 100644
--- a/src/windowmessages.cpp
+++ b/src/windowmessages.cpp
@@ -63,7 +63,7 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
           case (PARSING_DONE):
             {
               auto mail = (Mail*) ctx->data;
-              if (!Mail::is_mail_valid (mail))
+              if (!Mail::is_valid_ptr (mail))
                 {
                   log_debug ("%s:%s: Parsing done for mail which is gone.",
                              SRCNAME, __func__);

commit d299d6357ed98e31914bfc3cfe09f681b3deb73a
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Oct 14 10:22:51 2016 +0200

    Dont fail if placeholder can't be inserted
    
    * src/mail.cpp (decrypt_verify): Don't fail if placeholder
    can't be inserted.
    
    --
    There needs to be more fixes for failures to insert html as it
    fails when HTML mails are disabled in Outlook. Which is a good
    security setting.

diff --git a/src/mail.cpp b/src/mail.cpp
index 42d9f35..5b55093 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -470,8 +470,6 @@ Mail::decrypt_verify()
     {
       log_error ("%s:%s: Failed to modify html body of item.",
                  SRCNAME, __func__);
-      xfree (placeholder_buf);
-      return 1;
     }
   xfree (placeholder_buf);
 

commit d3a2f213e0fd0ac0771d57d7af474332b81c63f9
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Oct 14 10:20:46 2016 +0200

    Store decrypt / verify results in mail
    
    * src/mail.cpp (Mail::is_signed): New. Check if signed at all.
    (Mail::is_valid_sig): New. Check if signature is valid.
    (Mail::update_categories): Use member variables / new functions.
    (is_valid_sig): Removed.

diff --git a/src/mail.cpp b/src/mail.cpp
index 4e33c06..42d9f35 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -84,6 +84,7 @@ Mail::Mail (LPDISPATCH mailitem) :
     m_crypt_successful(false),
     m_is_smime(false),
     m_is_smime_checked(false),
+    m_is_valid_sig(false),
     m_moss_position(0),
     m_sender(NULL),
     m_type(MSGTYPE_UNKNOWN)
@@ -531,7 +532,13 @@ Mail::update_body()
 void
 Mail::parsing_done()
 {
+  /* Store the results. */
+  m_decrypt_result = m_parser->decrypt_result ();
+  m_verify_result = m_parser->verify_result ();
   m_needs_wipe = true;
+
+  /* Check our validity */
+  is_valid_sig ();
   /* Set categories according to the result. */
   update_categories();
 
@@ -845,14 +852,29 @@ Mail::close_inspector ()
   return 0;
 }
 
-static bool
-is_valid_sig (const VerificationResult &result, const char *sender)
+bool
+Mail::is_valid_sig ()
 {
-  if (result.error() || !sender)
+  const char *sender = get_sender();
+
+  static bool sig_checked;
+
+  if (m_verify_result.isNull())
     {
       return false;
     }
-  for (const auto sig: result.signatures())
+  if (sig_checked)
+    {
+      return m_is_valid_sig;
+    }
+
+  if (m_verify_result.error() || !sender)
+    {
+      m_is_valid_sig = false;
+      sig_checked = true;
+    }
+
+  for (const auto sig: m_verify_result.signatures())
     {
       if (sig.validity() != Signature::Validity::Marginal &&
           sig.validity() != Signature::Validity::Full &&
@@ -897,20 +919,21 @@ is_valid_sig (const VerificationResult &result, const char *sender)
                 }
               log_debug ("%s:%s: Classified sender as verified",
                          SRCNAME, __func__);
-              return true;
+              m_is_valid_sig = true;
+              break;
             }
         }
     }
-  return false;
+  sig_checked = true;
+  return m_is_valid_sig;
 }
 
 void
 Mail::update_categories ()
 {
-  const auto dec_result = m_parser->decrypt_result();
   const char *decCategory = _("GpgOL: Encrypted Message");
   const char *verifyCategory = _("GpgOL: Verified Sender");
-  if (dec_result.numRecipients())
+  if (m_decrypt_result.numRecipients())
     {
       /* We use the number of recipients as we don't care
          if decryption was successful or not for this category */
@@ -923,10 +946,7 @@ Mail::update_categories ()
       remove_category (m_mailitem, decCategory);
     }
 
-  const auto ver_result = m_parser->verify_result();
-  const char *sender = get_sender();
-
-  if (is_valid_sig (ver_result, sender))
+  if (m_is_valid_sig)
     {
       add_category (m_mailitem, verifyCategory);
     }
@@ -936,3 +956,14 @@ Mail::update_categories ()
     }
   return;
 }
+
+bool
+Mail::is_signed()
+{
+  if (!m_parser)
+    {
+      return false;
+    }
+  const auto result = m_parser->verify_result ();
+  return result.numSignatures() > 0;
+}
diff --git a/src/mail.h b/src/mail.h
index e76badd..75bd335 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -23,6 +23,8 @@
 
 #include "oomhelp.h"
 #include "mapihelp.h"
+#include "gpgme++/verificationresult.h"
+#include "gpgme++/decryptionresult.h"
 
 #include <string>
 #include <future>
@@ -194,6 +196,16 @@ public:
    handler.
   */
   void parsing_done ();
+
+  /** Returns true if the mail was verified and has at least one
+    signature. Regardless of the validity of the mail */
+  bool is_signed ();
+
+  /** Returns true if the mail was verified and the validity
+    was high enough that we treat it as "verified sender" in
+    the UI. */
+  bool is_valid_sig ();
+
 private:
   void update_categories ();
   void update_body ();
@@ -205,10 +217,14 @@ private:
        m_needs_save,   /* A property was changed but not by us. */
        m_crypt_successful, /* We successfuly performed crypto on the item. */
        m_is_smime, /* This is an smime mail. */
-       m_is_smime_checked; /* it was checked if this is an smime mail */
+       m_is_smime_checked, /* it was checked if this is an smime mail */
+       m_is_valid_sig; /* We treat the signature as valid (verified) */
   int m_moss_position; /* The number of the original message attachment. */
   char *m_sender;
   msgtype_t m_type; /* Our messagetype as set in mapi */
   ParseController *m_parser;
+  GpgME::VerificationResult m_verify_result;
+  GpgME::DecryptionResult m_decrypt_result;
+  std::string m_uid;
 };
 #endif // MAIL_H

commit cf5689b2cd8226a440e8dbc8b17e226186e52781
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Oct 14 10:10:24 2016 +0200

    Add some more oom helpers
    
    * src/oomhelp.cpp (get_strong_reference): New obtain a strong
    reference through the application object.
    (invoke_oom_method_with_params): New. Useful helper.
    (invoke_oom_method): Use invoke_oom_method_with_params.
    
    --
    The get_strong_reference code is left over from experiments how
    to fix the occassional crash when sending. Didn't work but it
    might be useful in the future.

diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp
index 32c83f9..8e107c5 100644
--- a/src/oomhelp.cpp
+++ b/src/oomhelp.cpp
@@ -1165,6 +1165,40 @@ get_object_by_id (LPDISPATCH pDisp, REFIID id)
   return disp;
 }
 
+LPDISPATCH
+get_strong_reference (LPDISPATCH mail)
+{
+  VARIANT var;
+  VariantInit (&var);
+  DISPPARAMS args;
+  VARIANT argvars[2];
+  VariantInit (&argvars[0]);
+  VariantInit (&argvars[1]);
+  argvars[1].vt = VT_DISPATCH;
+  argvars[1].pdispVal = mail;
+  argvars[0].vt = VT_INT;
+  argvars[0].intVal = 1;
+  args.cArgs = 2;
+  args.cNamedArgs = 0;
+  args.rgvarg = argvars;
+  LPDISPATCH ret = NULL;
+  if (!invoke_oom_method_with_parms (
+      GpgolAddin::get_instance()->get_application(),
+      "GetObjectReference", &var, &args))
+    {
+      ret = var.pdispVal;
+      log_oom ("%s:%s: Got strong ref %p for %p",
+               SRCNAME, __func__, ret, mail);
+    }
+  else
+    {
+      log_error ("%s:%s: Failed to get strong ref.",
+                 SRCNAME, __func__);
+    }
+  VariantClear (&var);
+  return ret;
+}
+
 LPMESSAGE
 get_oom_message (LPDISPATCH mailitem)
 {
@@ -1230,7 +1264,8 @@ get_oom_base_message (LPDISPATCH mailitem)
 }
 
 int
-invoke_oom_method (LPDISPATCH pDisp, const char *name, VARIANT *rVariant)
+invoke_oom_method_with_parms (LPDISPATCH pDisp, const char *name,
+                              VARIANT *rVariant, DISPPARAMS *params)
 {
   HRESULT hr;
   DISPID dispid;
@@ -1242,7 +1277,7 @@ invoke_oom_method (LPDISPATCH pDisp, const char *name, VARIANT *rVariant)
       DISPPARAMS dispparams = {NULL, NULL, 0, 0};
 
       hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                          DISPATCH_METHOD, &dispparams,
+                          DISPATCH_METHOD, params ? params : &dispparams,
                           rVariant, &execpinfo, NULL);
       if (hr != S_OK)
         {
@@ -1256,6 +1291,12 @@ invoke_oom_method (LPDISPATCH pDisp, const char *name, VARIANT *rVariant)
   return 0;
 }
 
+int
+invoke_oom_method (LPDISPATCH pDisp, const char *name, VARIANT *rVariant)
+{
+  return invoke_oom_method_with_parms (pDisp, name, rVariant, NULL);
+}
+
 LPMAPISESSION
 get_oom_mapi_session ()
 {
diff --git a/src/oomhelp.h b/src/oomhelp.h
index 65a489f..8654505 100644
--- a/src/oomhelp.h
+++ b/src/oomhelp.h
@@ -218,6 +218,18 @@ get_oom_message (LPDISPATCH mailitem);
 LPMESSAGE
 get_oom_base_message (LPDISPATCH mailitem);
 
+/* Get a strong reference for a mail object by calling
+   Application.GetObjectReference with type strong. The
+   documentation is unclear what this acutally does.
+   This function is left over from experiments about
+   strong references. Maybe there is a use for them.
+   The reference we use in the Mail object is documented
+   as a Weak reference. But changing that does not appear
+   to make a difference.
+*/
+LPDISPATCH
+get_strong_reference (LPDISPATCH mail);
+
 /* Invoke a method of an outlook object.
    returns true on success false otherwise.
 
@@ -228,6 +240,20 @@ get_oom_base_message (LPDISPATCH mailitem);
 int
 invoke_oom_method (LPDISPATCH pDisp, const char *name, VARIANT *rVariant);
 
+/* Invoke a method of an outlook object.
+   returns true on success false otherwise.
+
+   rVariant should either point to a propery initialized
+   variant (initinalized wiht VariantInit) to hold
+   the return value or a pointer to NULL.
+
+   parms can optionally be used to provide a DISPPARAMS structure
+   with parameters for the function.
+   */
+int
+invoke_oom_method_with_parms (LPDISPATCH pDisp, const char *name,
+                              VARIANT *rVariant, DISPPARAMS *params);
+
 /* Try to obtain the mapisession through the Application.
   returns NULL on error.*/
 LPMAPISESSION

commit 6cb1c3fd4f31fa90a1cc003a4ae162c89614add4
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Oct 12 11:32:54 2016 +0200

    Fix last line handling of text mails
    
    * src/mimedataprovider.cpp (t2body): Store if we have a html part.
    (t2body): Improve debug output.
    (get_html_body): Only fetch last line if we have seen an html part.

diff --git a/src/mimedataprovider.cpp b/src/mimedataprovider.cpp
index e5dbe8f..44944bd 100644
--- a/src/mimedataprovider.cpp
+++ b/src/mimedataprovider.cpp
@@ -316,14 +316,16 @@ t2body (MimeDataProvider *provider, rfc822parse_t msg)
          sig_data has not been set yet).  We also do this only while
          in verify mode because we don't want to write a full MUA.  */
       ctx->collect_signature = 1;
-      log_mime_parser ("Collecting signature now");
+      log_mime_parser ("%s:%s: Collecting signature.",
+                       SRCNAME, __func__);
     }
   else if (ctx->nesting_level == 1 && ctx->is_encrypted
            && !strcmp (ctmain, "application")
            && (ctx->protocol == PROTOCOL_OPENPGP
                && !strcmp (ctsub, "octet-stream")))
     {
-      log_mime_parser ("Collecting encrypted data from now on");
+      log_mime_parser ("%s:%s: Collecting encrypted PGP data.",
+                       SRCNAME, __func__);
       ctx->collect_crypto_data = 1;
     }
   else /* Other type. */
@@ -335,6 +337,8 @@ t2body (MimeDataProvider *provider, rfc822parse_t msg)
           && (!strcmp (ctsub, "pkcs7-mime")
               || !strcmp (ctsub, "x-pkcs7-mime")))
         {
+          log_mime_parser ("%s:%s: Collecting crypted S/MIME data.",
+                           SRCNAME, __func__);
           ctx->collect_crypto_data = 1;
         }
     }
@@ -358,9 +362,18 @@ t2body (MimeDataProvider *provider, rfc822parse_t msg)
           ctx->body_seen = 2;
           ctx->collect_html_body = 1;
           ctx->collect_body = 0;
+          log_debug ("%s:%s: Collecting HTML body.",
+                     SRCNAME, __func__);
+          /* We need this crutch because of one liner html
+             mails which would not be collected by the line
+             collector if they dont have a linefeed at the
+             end. */
+          provider->set_has_html_body (true);
         }
       else
         {
+          log_debug ("%s:%s: Collecting text body.",
+                     SRCNAME, __func__);
           ctx->body_seen = 1;
           ctx->collect_body = 1;
           ctx->collect_html_body = 0;
@@ -372,6 +385,8 @@ t2body (MimeDataProvider *provider, rfc822parse_t msg)
       ctx->current_attachment = provider->create_attachment();
       ctx->collect_body = 0;
       ctx->collect_html_body = 0;
+      log_mime_parser ("%s:%s: Collecting attachment.",
+                       SRCNAME, __func__);
     }
 
   return 0;
@@ -483,7 +498,8 @@ message_cb (void *opaque, rfc822parse_event_t event,
 }
 
 MimeDataProvider::MimeDataProvider(bool no_headers) :
-  m_signature(nullptr)
+  m_signature(nullptr),
+  m_has_html_body(false)
 {
   m_mime_ctx = (mime_context_t) xcalloc (1, sizeof *m_mime_ctx);
   m_mime_ctx->msg = rfc822parse_open (message_cb, this);
@@ -891,6 +907,12 @@ const std::string &MimeDataProvider::get_body()
 
 const std::string &MimeDataProvider::get_html_body()
 {
+  if (!m_has_html_body)
+    {
+      /* Don't do the last line handling if we don't
+         have html */
+      return m_html_body;
+    }
   if (m_rawbuf.size())
     {
       /* If there was some data left in the rawbuf this could
diff --git a/src/mimedataprovider.h b/src/mimedataprovider.h
index 661e0ca..85d1127 100644
--- a/src/mimedataprovider.h
+++ b/src/mimedataprovider.h
@@ -115,6 +115,8 @@ public:
     {return m_attachments;}
   const std::string &get_html_charset() const;
   const std::string &get_body_charset() const;
+
+  void set_has_html_body(bool value) {m_has_html_body = value;}
 private:
 #ifdef HAVE_W32_SYSTEM
   /* Collect the data from mapi. */
@@ -144,5 +146,7 @@ private:
   std::string m_html_charset;
   /* Charset of body */
   std::string m_body_charset;
+  /* Do we have html at all */
+  bool m_has_html_body;
 };
 #endif // MIMEDATAPROVIDER_H

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

Summary of changes:
 src/Makefile.am          |   2 +-
 src/gpgoladdin.cpp       |  58 +++++++----------
 src/mail.cpp             | 161 ++++++++++++++++++++++++++++++++++++++++++-----
 src/mail.h               |  43 ++++++++++++-
 src/mimedataprovider.cpp |  28 ++++++++-
 src/mimedataprovider.h   |   4 ++
 src/oomhelp.cpp          | 111 ++++++++++++++++++++++++++++++--
 src/oomhelp.h            |  40 +++++++++++-
 src/ribbon-callbacks.cpp | 154 +++++++++++++++++++++++++++++++++------------
 src/ribbon-callbacks.h   |  19 ++++--
 src/windowmessages.cpp   |   2 +-
 11 files changed, 514 insertions(+), 108 deletions(-)


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




More information about the Gnupg-commits mailing list