[git] GpgOL - branch, master, updated. gpgol-1.2.0-76-g9207e8f

by Andre Heinecke cvs at cvs.gnupg.org
Fri Oct 30 15:01:24 CET 2015


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  9207e8fb039b4dd4fc9c8e924f46fe9e1f223da0 (commit)
       via  55c2d14b39e67bf722ac29cd4854ab3dcd0d85fa (commit)
       via  c351c76ad43ffb3b59900c8c48256bf911495820 (commit)
      from  691aa0a716e615d7f119f3b62390c906a0280973 (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 9207e8fb039b4dd4fc9c8e924f46fe9e1f223da0
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Oct 30 14:49:38 2015 +0100

    Factor logic out of event handler
    
    * src/Makefile.am: Add mail.h and mail.cpp
    * src/mail.cpp, src/mail.h: New. Class containing information and
      functionality to work with mails.
    * src/application-events.cpp (EVENT_SINK_INVOKE): Create mail objects
      on ItemLoad event for Mailitems.
    * src/mailitem-events.cpp (HTML_TEMPLATE): Move to mail.cpp
      (BEGIN_EVENT_SINK): Reduce member variables.
      (MailItemEvents::MailItemEvents): Less initializations.
      (MailItemEvents::handle_read): Moved to Mail::insert_plaintext.
      (MailItemEvents::handle_before_read): Moved to Mail::process_message
      (do_crypto_on_item): Moved to Mail::do_crypto
      (needs_crypto): Moved to Mail::needs_crypto
      (EVENT_SINK_INVOKE): Get reference to according mail object.
      (EVENT_SINK_INVOKE): Call Mail methods according to events.
      (EVENT_SINK_INVOKE): Wipe code moved to Mail::wipe
    
    --
    mailitem-events should only "respond to events" from now on.
    Encapsulating all information about a Mail in a single class makes
    sense as we can keep track of data independently of events. The
    mix of state variables (e.g. needs_wipe) in the event handler
    made it difficult to access that information from anywhere.
    Additionally we now keep track of all Mail items loaded with
    our Event sinks set and expose them through Mail::get_mail_for_item.
    This should help solving problems like "wiping all plaintext on
    unload"

diff --git a/src/Makefile.am b/src/Makefile.am
index d66c39e..ff96120 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -84,7 +84,8 @@ gpgol_SOURCES = \
 	mailitem-events.cpp \
 	attachment.h attachment.cpp \
 	windowmessages.h windowmessages.cpp \
-	gpgolstr.h gpgolstr.cpp
+	gpgolstr.h gpgolstr.cpp \
+	mail.h mail.cpp
 
 
 #treeview_SOURCES = treeview.c
diff --git a/src/application-events.cpp b/src/application-events.cpp
index 196e6ed..4fe89cc 100644
--- a/src/application-events.cpp
+++ b/src/application-events.cpp
@@ -23,10 +23,10 @@
    in their invoke methods.
 */
 #include "eventsink.h"
-#include "eventsinks.h"
 #include "ocidl.h"
 #include "common.h"
 #include "oomhelp.h"
+#include "mail.h"
 
 /* Application Events */
 BEGIN_EVENT_SINK(ApplicationEvents, IDispatch)
@@ -63,7 +63,6 @@ EVENT_SINK_INVOKE(ApplicationEvents)
       case ItemLoad:
         {
           LPDISPATCH mailItem;
-          LPDISPATCH mailEventSink;
           /* The mailItem should be the first argument */
           if (!parms || parms->cArgs != 1 ||
               parms->rgvarg[0].vt != VT_DISPATCH)
@@ -83,23 +82,9 @@ EVENT_SINK_INVOKE(ApplicationEvents)
                          SRCNAME, __func__);
               break;
             }
-          log_debug ("%s:%s: Installing event sink on mailitem: %p",
+          log_debug ("%s:%s: Creating mail object for item: %p",
                      SRCNAME, __func__, mailItem);
-          mailEventSink = install_MailItemEvents_sink (mailItem);
-          /* TODO figure out what we need to do with the event sink.
-             Does it need to be Released at some point? What happens
-             on unload? */
-          if (!mailEventSink)
-            {
-              log_error ("%s:%s: Failed to install MailItemEvents sink.",
-                         SRCNAME, __func__);
-            }
-          else
-            {
-              log_debug ("%s:%s: MailItem event handler installed.",
-                         SRCNAME, __func__);
-            }
-          mailItem->Release ();
+          new Mail (mailItem);
           break;
         }
       default:
diff --git a/src/gpgoladdin.cpp b/src/gpgoladdin.cpp
index 81e43b3..5ba8a72 100644
--- a/src/gpgoladdin.cpp
+++ b/src/gpgoladdin.cpp
@@ -167,7 +167,7 @@ GpgolAddin::~GpgolAddin (void)
              SRCNAME, __func__);
 
   m_ribbonExtender->Release ();
-  m_applicationEventSink->Release ();
+  m_applicationEventSink->Release() ;
 
   if (!m_disabled)
     {
diff --git a/src/mail.cpp b/src/mail.cpp
new file mode 100644
index 0000000..1e7d9bc
--- /dev/null
+++ b/src/mail.cpp
@@ -0,0 +1,282 @@
+/* @file mail.h
+ * @brief High level class to work with Outlook Mailitems.
+ *
+ *    Copyright (C) 2015 Intevation GmbH
+ *
+ * This file is part of GpgOL.
+ *
+ * GpgOL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GpgOL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "common.h"
+#include "mail.h"
+#include "eventsinks.h"
+#include "attachment.h"
+#include "mapihelp.h"
+#include "message.h"
+
+#include <map>
+
+static std::map<LPDISPATCH, Mail*> g_mail_map;
+
+/* TODO: Localize this once it is less bound to change.
+   TODO: Use a dedicated message for failed decryption. */
+#define HTML_TEMPLATE  \
+"<html><head></head><body>" \
+"<table border=\"0\" width=\"100%\" cellspacing=\"1\" cellpadding=\"1\" bgcolor=\"#0069cc\">" \
+"<tr>" \
+"<td bgcolor=\"#0080ff\">" \
+"<p><span style=\"font-weight:600; background-color:#0080ff;\"><center>This message is encrypted</center><span></p></td></tr>" \
+"<tr>" \
+"<td bgcolor=\"#e0f0ff\">" \
+"<center>" \
+"<br/>You can decrypt this message with GnuPG" \
+"<br/>Open this message to decrypt it." \
+"<br/>Opening any attachments while this message is shown will only give you access to encrypted data. </center>" \
+"<br/><br/>If you have GpgOL (The GnuPG Outlook plugin installed) this message should have been automatically decrypted." \
+"<br/>Reasons that you still see this message can be: " \
+"<ul>" \
+"<li>Decryption failed: <ul><li> Refer to the Decrypt / Verify popup window for details.</li></ul></li>" \
+"<li>Outlook tried to save the decrypted content:" \
+" <ul> "\
+" <li>To protect your data GpgOL encrypts a message when it is saved by Outlook.</li>" \
+" <li>You will need to restart Outlook to allow GpgOL to decrypt this message again.</li>" \
+" </ul>" \
+"<li>GpgOL is not activated: <ul><li>Check under Options -> Add-Ins -> COM-Add-Ins to see if this is the case.</li></ul></li>" \
+"</ul>"\
+"</td></tr>" \
+"</table></body></html>"
+
+Mail::Mail (LPDISPATCH mailitem) :
+    m_mailitem(mailitem),
+    m_processed(false),
+    m_needs_wipe(false),
+    m_crypt_successful(false)
+{
+  if (get_mail_for_item (mailitem))
+    {
+      log_error ("Mail object for item: %p already exists. Bug.",
+                 mailitem);
+      return;
+    }
+
+  m_event_sink = install_MailItemEvents_sink (mailitem);
+  if (!m_event_sink)
+    {
+      /* Should not happen but in that case we don't add us to the list
+         and just release the Mail item. */
+      log_error ("%s:%s: Failed to install MailItemEvents sink.",
+                 SRCNAME, __func__);
+      mailitem->Release ();
+      return;
+    }
+  g_mail_map.insert (std::pair<LPDISPATCH, Mail *> (mailitem, this));
+}
+
+int
+Mail::process_message ()
+{
+  int err;
+  LPMESSAGE message = get_oom_base_message (m_mailitem);
+  if (!message)
+    {
+      log_error ("%s:%s: Failed to get base message.",
+                 SRCNAME, __func__);
+      return 0;
+    }
+  log_oom_extra ("%s:%s: GetBaseMessage OK.",
+                 SRCNAME, __func__);
+  err = message_incoming_handler (message, NULL,
+                                  false);
+  m_processed = (err == 1) || (err == 2);
+
+  log_debug ("%s:%s: incoming handler status: %i",
+             SRCNAME, __func__, err);
+  message->Release ();
+  return 0;
+}
+
+Mail::~Mail()
+{
+  std::map<LPDISPATCH, Mail *>::iterator it;
+
+  detach_MailItemEvents_sink (m_event_sink);
+
+  it = g_mail_map.find(m_mailitem);
+  if (it != g_mail_map.end())
+    {
+      g_mail_map.erase (it);
+    }
+
+  m_mailitem->Release ();
+}
+
+Mail *
+Mail::get_mail_for_item (LPDISPATCH mailitem)
+{
+  if (!mailitem)
+    {
+      return NULL;
+    }
+  std::map<LPDISPATCH, Mail *>::iterator it;
+  it = g_mail_map.find(mailitem);
+  if (it == g_mail_map.end())
+    {
+      return NULL;
+    }
+  return it->second;
+}
+
+int
+Mail::insert_plaintext ()
+{
+  int err = 0;
+  int is_html, was_protected = 0;
+  char *body = NULL;
+
+  if (!m_processed)
+    {
+      return 0;
+    }
+
+  /* Outlook somehow is confused about the attachment
+     table of our sent mails. The securemessage interface
+     gives us access to the real attach table but the attachment
+     table of the message itself is broken. */
+  LPMESSAGE base_message = get_oom_base_message (m_mailitem);
+  if (!base_message)
+    {
+      log_error ("%s:%s: Failed to get base message",
+                 SRCNAME, __func__);
+      return 0;
+    }
+  err = mapi_get_gpgol_body_attachment (base_message, &body, NULL,
+                                        &is_html, &was_protected);
+  m_needs_wipe = was_protected;
+  if (err || !body)
+    {
+      log_error ("%s:%s: Failed to get body attachment. Err: %i",
+                 SRCNAME, __func__, err);
+      put_oom_string (m_mailitem, "HTMLBody", HTML_TEMPLATE);
+      err = -1;
+      goto done;
+    }
+  if (put_oom_string (m_mailitem, is_html ? "HTMLBody" : "Body", body))
+    {
+      log_error ("%s:%s: Failed to modify body of item.",
+                 SRCNAME, __func__);
+      err = -1;
+    }
+
+  xfree (body);
+  /* TODO: unprotect attachments does not work for sent mails
+     as the attachment table of the mapiitem is invalid.
+     We need to somehow get outlook to use the attachment table
+     of the base message and and then decrypt those.
+     This will probably mean removing all attachments for the
+     message and adding the attachments from the base message then
+     we can call unprotect_attachments as usual. */
+  if (unprotect_attachments (m_mailitem))
+    {
+      log_error ("%s:%s: Failed to unprotect attachments.",
+                 SRCNAME, __func__);
+      err = -1;
+    }
+
+done:
+  RELDISP (base_message);
+  return err;
+}
+
+int
+Mail::do_crypto ()
+{
+  int err = -1,
+      flags = 0;
+  if (!needs_crypto())
+    {
+      return 0;
+    }
+  LPMESSAGE message = get_oom_base_message (m_mailitem);
+  if (!message)
+    {
+      log_error ("%s:%s: Failed to get base message.",
+                 SRCNAME, __func__);
+      return err;
+    }
+  flags = get_gpgol_draft_info_flags (message);
+  if (flags == 3)
+    {
+      log_debug ("%s:%s: Sign / Encrypting message",
+                 SRCNAME, __func__);
+      err = message_sign_encrypt (message, PROTOCOL_UNKNOWN,
+                                  NULL);
+    }
+  else if (flags == 2)
+    {
+      err = message_sign (message, PROTOCOL_UNKNOWN,
+                          NULL);
+    }
+  else if (flags == 1)
+    {
+      err = message_encrypt (message, PROTOCOL_UNKNOWN,
+                             NULL);
+    }
+  else
+    {
+      log_debug ("%s:%s: Unknown flags for crypto: %i",
+                 SRCNAME, __func__, flags);
+    }
+  log_debug ("%s:%s: Status: %i",
+             SRCNAME, __func__, err);
+  message->Release ();
+  m_crypt_successful = !err;
+  return err;
+}
+
+bool
+Mail::needs_crypto ()
+{
+  LPMESSAGE message = get_oom_message (m_mailitem);
+  bool ret;
+  if (!message)
+    {
+      log_error ("%s:%s: Failed to get message.",
+                 SRCNAME, __func__);
+      return false;
+    }
+  ret = get_gpgol_draft_info_flags (message);
+  message->Release ();
+  return ret;
+}
+
+int
+Mail::wipe ()
+{
+  if (!m_needs_wipe)
+    {
+      return 0;
+    }
+  log_debug ("%s:%s: Removing plaintext from mailitem: %p.",
+             SRCNAME, __func__, m_mailitem);
+  if (put_oom_string (m_mailitem, "HTMLBody",
+                      HTML_TEMPLATE) ||
+      protect_attachments (m_mailitem))
+    {
+      return -1;
+    }
+  m_needs_wipe = false;
+  return 0;
+}
diff --git a/src/mail.h b/src/mail.h
new file mode 100644
index 0000000..019e9bb
--- /dev/null
+++ b/src/mail.h
@@ -0,0 +1,107 @@
+/* @file mail.h
+ * @brief High level class to work with Outlook Mailitems.
+ *
+ *    Copyright (C) 2015 Intevation GmbH
+ *
+ * This file is part of GpgOL.
+ *
+ * GpgOL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GpgOL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef MAIL_H
+#define MAIL_H
+
+#include "oomhelp.h"
+
+/** @brief Data wrapper around a mailitem.
+ *
+ * This class is intended to bundle all that we know about
+ * a Mail. Due to the restrictions in Outlook we sometimes may
+ * need additional information that is not available at the time
+ * like the sender address of an exchange account in the afterWrite
+ * event.
+ *
+ * This class bundles such information and also provides a way to
+ * access the event handler of a mail.
+ */
+class Mail
+{
+public:
+  /** @brief Construct a mail object for the item.
+    *
+    * This also installs the event sink for this item.
+    *
+    * The mail object takes ownership of the mailitem
+    * reference. Do not Release it! */
+  Mail (LPDISPATCH mailitem);
+
+  ~Mail ();
+
+  /** @brief looks for existing Mail objects for the OOM mailitem.
+
+    @returns A reference to an existing mailitem or NULL in case none
+    could be found.
+  */
+  static Mail* get_mail_for_item (LPDISPATCH mailitem);
+
+  /** @brief Reference to the mailitem. Do not Release! */
+  LPDISPATCH item () { return m_mailitem; }
+
+  /** @brief Process the message. Ususally to be called from BeforeRead.
+   *
+   * This function assumes that the base message interface can be accessed
+   * and calles the MAPI Message handling which creates the GpgOL style
+   * attachments and sets up the message class etc.
+   *
+   * Sets the was_encrypted / processed variables.
+   *
+   * @returns 0 on success.
+   */
+  int process_message ();
+
+  /** @brief Replace the body with the plaintext and session decrypts
+   * attachments.
+   *
+   * Sets the needs_wipe variable.
+   *
+   * @returns 0 on success. */
+  int insert_plaintext ();
+
+  /** @brief do crypto operations as selected by the user.
+   *
+   * Initiates the crypto operations according to the gpgol
+   * draft info flags.
+   *
+   * @returns 0 on success. */
+  int do_crypto ();
+
+  /** @brief Necessary crypto operations were completed successfully. */
+  bool crypto_successful () { return !needs_crypto() || m_crypt_successful; }
+
+  /** @brief Message should be encrypted and or signed. */
+  bool needs_crypto ();
+
+  /** @brief wipe the plaintext from the message and ecnrypt attachments.
+   *
+   * @returns 0 on success; */
+  int wipe ();
+
+private:
+  LPDISPATCH m_mailitem;
+  LPDISPATCH m_event_sink;
+  char * m_sender_addr;
+  bool m_processed,    /* The message has been porcessed by us.  */
+       m_needs_wipe,   /* We have added plaintext to the mesage. */
+       m_crypt_successful; /* We successfuly performed crypto on the item. */
+};
+#endif // MAIL_H
diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index 2c002b2..e187d60 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -22,43 +22,12 @@
 #include "eventsink.h"
 #include "eventsinks.h"
 #include "mymapi.h"
-#include "message.h"
 #include "oomhelp.h"
 #include "ocidl.h"
-#include "attachment.h"
-#include "mapihelp.h"
-#include "gpgoladdin.h"
 #include "windowmessages.h"
+#include "mail.h"
 
 
-/* TODO: Localize this once it is less bound to change.
-   TODO: Use a dedicated message for failed decryption. */
-#define HTML_TEMPLATE  \
-"<html><head></head><body>" \
-"<table border=\"0\" width=\"100%\" cellspacing=\"1\" cellpadding=\"1\" bgcolor=\"#0069cc\">" \
-"<tr>" \
-"<td bgcolor=\"#0080ff\">" \
-"<p><span style=\"font-weight:600; background-color:#0080ff;\"><center>This message is encrypted</center><span></p></td></tr>" \
-"<tr>" \
-"<td bgcolor=\"#e0f0ff\">" \
-"<center>" \
-"<br/>You can decrypt this message with GnuPG" \
-"<br/>Open this message to decrypt it." \
-"<br/>Opening any attachments while this message is shown will only give you access to encrypted data. </center>" \
-"<br/><br/>If you have GpgOL (The GnuPG Outlook plugin installed) this message should have been automatically decrypted." \
-"<br/>Reasons that you still see this message can be: " \
-"<ul>" \
-"<li>Decryption failed: <ul><li> Refer to the Decrypt / Verify popup window for details.</li></ul></li>" \
-"<li>Outlook tried to save the decrypted content:" \
-" <ul> "\
-" <li>To protect your data GpgOL encrypts a message when it is saved by Outlook.</li>" \
-" <li>You will need to restart Outlook to allow GpgOL to decrypt this message again.</li>" \
-" </ul>" \
-"<li>GpgOL is not activated: <ul><li>Check under Options -> Add-Ins -> COM-Add-Ins to see if this is the case.</li></ul></li>" \
-"</ul>"\
-"</td></tr>" \
-"</table></body></html>"
-
 typedef enum
   {
     AfterWrite = 0xFC8D,
@@ -94,15 +63,8 @@ BEGIN_EVENT_SINK(MailItemEvents, IDispatch)
 /* We are still in the class declaration */
 
 private:
-  bool m_send_seen,   /* The message is about to be submitted */
-       m_want_html,    /* Encryption of HTML is desired. */
-       m_processed,    /* The message has been porcessed by us.  */
-       m_needs_wipe,   /* We have added plaintext to the mesage. */
-       m_was_encrypted, /* The original message was encrypted.  */
-       m_crypt_successful; /* We successfuly performed crypto on the item. */
-
-  HRESULT handle_before_read();
-  HRESULT handle_read();
+  Mail * m_mail; /* The mail object related to this mailitem */
+  bool m_send_seen;   /* The message is about to be submitted */
 };
 
 MailItemEvents::MailItemEvents() :
@@ -110,10 +72,8 @@ MailItemEvents::MailItemEvents() :
     m_pCP(NULL),
     m_cookie(0),
     m_ref(1),
-    m_send_seen(false),
-    m_want_html(false),
-    m_processed(false),
-    m_crypt_successful(false)
+    m_mail(NULL),
+    m_send_seen (false)
 {
 }
 
@@ -125,127 +85,7 @@ MailItemEvents::~MailItemEvents()
     m_object->Release();
 }
 
-HRESULT
-MailItemEvents::handle_read()
-{
-  int err;
-  int is_html, was_protected = 0;
-  char *body = NULL;
-  /* Outlook somehow is confused about the attachment
-     table of our sent mails. The securemessage interface
-     gives us access to the real attach table but the attachment
-     table of the message itself is broken. */
-  LPMESSAGE base_message = get_oom_base_message (m_object);
-  if (!base_message)
-    {
-      log_error ("%s:%s: Failed to get base message \n",
-                 SRCNAME, __func__);
-      return S_OK;
-    }
-  err = mapi_get_gpgol_body_attachment (base_message, &body, NULL,
-                                        &is_html, &was_protected);
-  if (err || !body)
-    {
-      log_error ("%s:%s: Failed to get body attachment of \n",
-                 SRCNAME, __func__);
-      put_oom_string (m_object, "HTMLBody", HTML_TEMPLATE);
-      goto done;
-    }
-  if (put_oom_string (m_object, is_html ? "HTMLBody" : "Body", body))
-    {
-      log_error ("%s:%s: Failed to modify body of item. \n",
-                 SRCNAME, __func__);
-    }
-
-  xfree (body);
-  /* TODO: unprotect attachments does not work for sent mails
-     as the attachment table of the mapiitem is invalid.
-     We need to somehow get outlook to use the attachment table
-     of the base message and and then decrypt those.
-     This will probably mean removing all attachments for the
-     message and adding the attachments from the base message then
-     we can call unprotect_attachments as usual. */
-  if (unprotect_attachments (m_object))
-    {
-      log_error ("%s:%s: Failed to unprotect attachments. \n",
-                 SRCNAME, __func__);
-    }
-
-done:
-  RELDISP (base_message);
-  return S_OK;
-}
-
-/* Before read is the time where we can access the underlying
-   base message. So this is where we create our attachment. */
-HRESULT
-MailItemEvents::handle_before_read()
-{
-  int err;
-  LPMESSAGE message = get_oom_base_message (m_object);
-  if (!message)
-    {
-      log_error ("%s:%s: Failed to get base message.",
-                 SRCNAME, __func__);
-      return S_OK;
-    }
-  log_oom_extra ("%s:%s: GetBaseMessage OK.",
-                 SRCNAME, __func__);
-  err = message_incoming_handler (message, NULL,
-                                  false);
-  m_processed = (err == 1) || (err == 2);
-  m_was_encrypted = err == 2;
-
-  log_debug ("%s:%s: incoming handler status: %i",
-             SRCNAME, __func__, err);
-  message->Release ();
-  return S_OK;
-}
-
-
-static int
-do_crypto_on_item (LPDISPATCH mailitem)
-{
-  int err = -1,
-      flags = 0;
-  LPMESSAGE message = get_oom_base_message (mailitem);
-  if (!message)
-    {
-      log_error ("%s:%s: Failed to get base message.",
-                 SRCNAME, __func__);
-      return err;
-    }
-  flags = get_gpgol_draft_info_flags (message);
-  if (flags == 3)
-    {
-      log_debug ("%s:%s: Sign / Encrypting message",
-                 SRCNAME, __func__);
-      err = message_sign_encrypt (message, PROTOCOL_UNKNOWN,
-                                  NULL);
-    }
-  else if (flags == 2)
-    {
-      err = message_sign (message, PROTOCOL_UNKNOWN,
-                          NULL);
-    }
-  else if (flags == 1)
-    {
-      err = message_encrypt (message, PROTOCOL_UNKNOWN,
-                             NULL);
-    }
-  else
-    {
-      log_debug ("%s:%s: Unknown flags for crypto: %i",
-                 SRCNAME, __func__, flags);
-    }
-  log_debug ("%s:%s: Status: %i",
-             SRCNAME, __func__, err);
-  message->Release ();
-  return err;
-}
-
-
-DWORD WINAPI
+static DWORD WINAPI
 request_send (LPVOID arg)
 {
   log_debug ("%s:%s: requesting send for: %p",
@@ -261,21 +101,6 @@ request_send (LPVOID arg)
   return 0;
 }
 
-static bool
-needs_crypto (LPDISPATCH mailitem)
-{
-  LPMESSAGE message = get_oom_message (mailitem);
-  bool ret;
-  if (!message)
-    {
-      log_error ("%s:%s: Failed to get message.",
-                 SRCNAME, __func__);
-      return false;
-    }
-  ret = get_gpgol_draft_info_flags (message);
-  message->Release ();
-  return ret;
-}
 
 /* The main Invoke function. The return value of this
    function does not appear to have any effect on outlook
@@ -288,20 +113,35 @@ needs_crypto (LPDISPATCH mailitem)
 EVENT_SINK_INVOKE(MailItemEvents)
 {
   USE_INVOKE_ARGS
+  if (!m_mail)
+    {
+      m_mail = Mail::get_mail_for_item (m_object);
+      if (!m_mail)
+        {
+          log_error ("%s:%s: mail event without mail object known. Bug.",
+                     SRCNAME, __func__);
+          return S_OK;
+        }
+    }
   switch(dispid)
     {
       case BeforeRead:
         {
-          return handle_before_read();
+          if (m_mail->process_message ())
+            {
+              log_error ("%s:%s: Process message failed.",
+                         SRCNAME, __func__);
+            }
+          break;
         }
       case Read:
         {
-          if (m_processed)
+          if (m_mail->insert_plaintext ())
             {
-              m_needs_wipe = m_was_encrypted;
-              handle_read();
+              log_error ("%s:%s: Failed to insert plaintext into oom.",
+                         SRCNAME, __func__);
             }
-          return S_OK;
+          break;
         }
       case Send:
         {
@@ -326,7 +166,7 @@ EVENT_SINK_INVOKE(MailItemEvents)
                         SRCNAME, __func__);
              break;
            }
-          if (!needs_crypto (m_object) || m_crypt_successful)
+          if (m_mail->crypto_successful ())
             {
                log_debug ("%s:%s: Passing send event for message %p.",
                           SRCNAME, __func__, m_object);
@@ -355,23 +195,16 @@ EVENT_SINK_INVOKE(MailItemEvents)
                       SRCNAME, __func__);
              break;
            }
-          if (m_processed && m_needs_wipe && !m_send_seen)
+
+          if (m_mail->wipe ())
             {
-              log_debug ("%s:%s: Message %p removing plaintext from Message.",
-                         SRCNAME, __func__, m_object);
-              if (put_oom_string (m_object, "HTMLBody",
-                                  HTML_TEMPLATE) ||
-                  protect_attachments (m_object))
-                {
-                  /* An error cleaning the mail should not happen normally.
-                     But just in case there is an error we cancel the
-                     write here. */
-                  log_debug ("%s:%s: Failed to remove plaintext.",
-                             SRCNAME, __func__);
-                  *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE;
-                  return E_ABORT;
-                }
-              m_needs_wipe = false;
+              /* An error cleaning the mail should not happen normally.
+                 But just in case there is an error we cancel the
+                 write here. */
+              log_debug ("%s:%s: Failed to remove plaintext.",
+                         SRCNAME, __func__);
+              *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE;
+              return E_ABORT;
             }
           break;
         }
@@ -380,8 +213,8 @@ EVENT_SINK_INVOKE(MailItemEvents)
           if (m_send_seen)
             {
               m_send_seen = false;
-              m_crypt_successful = !do_crypto_on_item (m_object);
-              if (m_crypt_successful)
+              m_mail->do_crypto ();
+              if (m_mail->crypto_successful ())
                 {
                   /* We can't trigger a Send event in the current state.
                      Appearently Outlook locks some methods in some events.
@@ -396,12 +229,9 @@ EVENT_SINK_INVOKE(MailItemEvents)
         }
       case Unload:
         {
-          log_debug ("%s:%s: Unloading event handler for msg: %p.",
+          log_debug ("%s:%s: Removing Mail for message: %p.",
                      SRCNAME, __func__, m_object);
-          detach_MailItemEvents_sink (this);
-          delete this;
-          log_debug ("%s:%s: Unloaded.",
-                     SRCNAME, __func__);
+          delete m_mail;
           return S_OK;
         }
       default:

commit 55c2d14b39e67bf722ac29cd4854ab3dcd0d85fa
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Oct 30 14:46:54 2015 +0100

    Fix recipient lookup for SMTP addresses
    
    * src/message.cpp (get_recipients): Look for SMTP address property
    and also the EMAIL address property.
    
    --
    For SMTP Addresses in the EMAIL address property the STMP address
    is not set. So we check first for SMTP (which handles exchange)
    and if we don't find that property we use the EMAIL value as before.

diff --git a/src/message.cpp b/src/message.cpp
index e1eca26..34dd48f 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -1112,9 +1112,8 @@ message_decrypt (LPMESSAGE message, msgtype_t msgtype, int force, HWND hwnd)
 static char **
 get_recipients (LPMESSAGE message)
 {
-  ULONG addr_prop = g_ol_version_major > 13 ? PR_SMTP_ADDRESS :
-                                              PR_EMAIL_ADDRESS;
-  static SizedSPropTagArray (1L, PropRecipientNum) = {1L, {addr_prop}};
+  static SizedSPropTagArray (2L, PropRecipientNum) = {2L, {PR_SMTP_ADDRESS,
+                                                           PR_EMAIL_ADDRESS}};
   HRESULT hr;
   LPMAPITABLE lpRecipientTable = NULL;
   LPSRowSet lpRecipientRows = NULL;
@@ -1148,28 +1147,40 @@ get_recipients (LPMESSAGE message)
 
   for (rowidx=0, rsetidx=0; rowidx < lpRecipientRows->cRows; rowidx++)
     {
-      if (!lpRecipientRows->aRow[rowidx].cValues)
-        continue;
-      row = lpRecipientRows->aRow[rowidx].lpProps;
-
-      switch (PROP_TYPE (row->ulPropTag))
+      bool found_one = false;
+      for (int colidx = 0; colidx < lpRecipientRows->aRow[rowidx].cValues;
+           colidx++)
         {
-        case PT_UNICODE:
-          if ((rset[rsetidx] = wchar_to_utf8 (row->Value.lpszW)))
-            rsetidx++;
-          else
-            log_debug ("%s:%s: error converting recipient to utf8\n",
-                       SRCNAME, __func__);
-          break;
-      
-        case PT_STRING8: /* Assume ASCII. */
-          rset[rsetidx++] = xstrdup (row->Value.lpszA);
-          break;
-          
-        default:
-          log_debug ("%s:%s: proptag=0x%08lx not supported\n",
-                     SRCNAME, __func__, row->ulPropTag);
-          break;
+          row = lpRecipientRows->aRow[rowidx].lpProps;
+
+          switch (PROP_TYPE (row->ulPropTag))
+            {
+            case PT_UNICODE:
+              if ((rset[rsetidx] = wchar_to_utf8 (row->Value.lpszW)))
+                {
+                  rsetidx++;
+                  found_one = true;
+                }
+              else
+                log_debug ("%s:%s: error converting recipient to utf8\n",
+                           SRCNAME, __func__);
+              break;
+
+            case PT_STRING8: /* Assume ASCII. */
+              rset[rsetidx++] = xstrdup (row->Value.lpszA);
+              found_one = true;
+              break;
+
+            default:
+              log_debug ("%s:%s: proptag=0x%08lx not supported\n",
+                         SRCNAME, __func__, row->ulPropTag);
+              break;
+            }
+          if (found_one)
+            {
+              break;
+            }
+
         }
     }
 

commit c351c76ad43ffb3b59900c8c48256bf911495820
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Oct 28 12:40:44 2015 +0100

    Fix recipient address lookup for Exchange addrs
    
    * src/gpgoladdin.cpp (GpgolAddin::OnConnection): Store major version.
    * src/main.c: Define major version variable.
    * src/message.cpp (get_recipients): Use SMTP addr property for new
      versions.
    * src/mymapitags.h: Define SMTP_ADDRESS property ids.
    * src/olflange.cpp (GpgolExt:Install): Store major version.
    * src/oomhelp.h: Rename PR_SMTP_ADDRESS URI to PR_STMP_ADDRESS_DASL.
    * src/oomhelp.cpp (get_oom_recipients): Update accordingly.
    * src/ribbon-callbacks.cpp (do_composer_action, do_reader_action),
      (attachEncryptedFile): Update accordingly.
    * src/util.h: Declare major version variable.
    
    --
    We can't use the OOM Recipient objects here as this is not
    accessible in the after write event. This still leaves the
    sender lookup to be done. There appears to be no MAPI property
    that contains the SMTP Address of the sender when sending mails
    through exchange.

diff --git a/src/gpgoladdin.cpp b/src/gpgoladdin.cpp
index 74b7fcc..81e43b3 100644
--- a/src/gpgoladdin.cpp
+++ b/src/gpgoladdin.cpp
@@ -235,6 +235,8 @@ GpgolAddin::OnConnection (LPDISPATCH Application, ext_ConnectMode ConnectMode,
   log_debug ("%s:%s:   using GPGME %s\n",
              SRCNAME, __func__, version);
 
+  g_ol_version_major = atoi (version);
+
   if (!version || !strlen (version) ||
       (strncmp (version, "14", 2) &&
        strncmp (version, "15", 2) &&
diff --git a/src/main.c b/src/main.c
index 5e3a05d..6e7eb79 100644
--- a/src/main.c
+++ b/src/main.c
@@ -53,6 +53,9 @@ static char *the_session_marker;
 static char *get_locale_dir (void);
 static void drop_locale_dir (char *locale_dir);
 
+/* The major version of Outlook we are attached to */
+int g_ol_version_major;
+
 
 

 /* Initialization of gloabl options.  These are merely the defaults
diff --git a/src/message.cpp b/src/message.cpp
index 9344246..e1eca26 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -1112,7 +1112,9 @@ message_decrypt (LPMESSAGE message, msgtype_t msgtype, int force, HWND hwnd)
 static char **
 get_recipients (LPMESSAGE message)
 {
-  static SizedSPropTagArray (1L, PropRecipientNum) = {1L, {PR_EMAIL_ADDRESS}};
+  ULONG addr_prop = g_ol_version_major > 13 ? PR_SMTP_ADDRESS :
+                                              PR_EMAIL_ADDRESS;
+  static SizedSPropTagArray (1L, PropRecipientNum) = {1L, {addr_prop}};
   HRESULT hr;
   LPMAPITABLE lpRecipientTable = NULL;
   LPSRowSet lpRecipientRows = NULL;
diff --git a/src/mymapitags.h b/src/mymapitags.h
index 7eda9b4..c85ce37 100644
--- a/src/mymapitags.h
+++ b/src/mymapitags.h
@@ -838,6 +838,9 @@
 #define PR_INITIAL_DETAILS_PANE               PROP_TAG( PT_LONG,        0x3F08)
 #define PR_MSG_EDITOR_FORMAT                  PROP_TAG( PT_LONG,        0x5903)
 #define PR_ATTACHMENT_HIDDEN                  PROP_TAG( PT_BOOLEAN,     0x7ffe)
+#define PR_SMTP_ADDRESS                       PROP_TAG( PT_TSTRING,     0x39fe)
+#define PR_SMTP_ADDRESS_W                     PROP_TAG( PT_UNICODE,     0x39fe)
+#define PR_SMTP_ADDRESS_A                     PROP_TAG( PT_STRING8,     0x39fe)
 
 #define PROP_ID_SECURE_MIN                0x67F0
 #define PROP_ID_SECURE_MAX                0x67FF
diff --git a/src/olflange.cpp b/src/olflange.cpp
index f24b134..3850d06 100644
--- a/src/olflange.cpp
+++ b/src/olflange.cpp
@@ -686,6 +686,7 @@ GpgolExt::Install(LPEXCHEXTCALLBACK pEECB, ULONG lContext, ULONG lFlags)
           if (disp)
             {
               olversion = get_oom_string (disp, "Version");
+              g_ol_version_major = atoi (olversion);
               disp->Release ();
             }
           obj->Release ();
diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp
index a04b4be..7ba2775 100644
--- a/src/oomhelp.cpp
+++ b/src/oomhelp.cpp
@@ -903,7 +903,7 @@ get_oom_recipients (LPDISPATCH recipients)
           char *address,
                *resolved;
           address = get_oom_string (recipient, "Address");
-          resolved = get_pa_string (recipient, PR_SMTP_ADDRESS);
+          resolved = get_pa_string (recipient, PR_SMTP_ADDRESS_DASL);
           if (resolved)
             {
               xfree (address);
diff --git a/src/oomhelp.h b/src/oomhelp.h
index 66c9cab..9d2a3b3 100644
--- a/src/oomhelp.h
+++ b/src/oomhelp.h
@@ -77,8 +77,8 @@ DEFINE_OLEGUID(IID_IUnknown,                  0x00000000, 0, 0);
 DEFINE_OLEGUID(IID_IDispatch,                 0x00020400, 0, 0);
 DEFINE_OLEGUID(IID_IOleWindow,                0x00000114, 0, 0);
 
-#ifndef PR_SMTP_ADDRESS
-#define PR_SMTP_ADDRESS "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
+#ifndef PR_SMTP_ADDRESS_DASL
+#define PR_SMTP_ADDRESS_DASL "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
 #endif
 
 #ifdef __cplusplus
diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp
index 8af2a30..e9182fe 100644
--- a/src/ribbon-callbacks.cpp
+++ b/src/ribbon-callbacks.cpp
@@ -296,7 +296,7 @@ do_composer_action (LPDISPATCH ctrl, int flags)
   engine_set_session_number (filter, session_number);
   engine_set_session_title (filter, _("GpgOL"));
 
-  senderAddr = get_pa_string (sender, PR_SMTP_ADDRESS);
+  senderAddr = get_pa_string (sender, PR_SMTP_ADDRESS_DASL);
 
   if (flags & OP_ENCRYPT)
     {
@@ -732,7 +732,7 @@ do_reader_action (LPDISPATCH ctrl, int flags)
         {
           /* Not SMTP, fall back to try getting the property. */
           LPDISPATCH sender = get_oom_object (mailItem, "Sender");
-          senderAddr = get_pa_string (sender, PR_SMTP_ADDRESS);
+          senderAddr = get_pa_string (sender, PR_SMTP_ADDRESS_DASL);
           RELDISP (sender);
         }
       xfree (addrType);
@@ -742,7 +742,7 @@ do_reader_action (LPDISPATCH ctrl, int flags)
       /* If the message has not been sent we might be composing
          in this case use the current address */
       LPDISPATCH sender = get_oom_object (mailItem, "Session.CurrentUser");
-      senderAddr = get_pa_string (sender, PR_SMTP_ADDRESS);
+      senderAddr = get_pa_string (sender, PR_SMTP_ADDRESS_DASL);
       RELDISP (sender);
     }
 
@@ -1127,7 +1127,7 @@ attachEncryptedFile (LPDISPATCH ctrl, int flags)
       goto failure;
     }
 
-  senderAddr = get_pa_string (sender, PR_SMTP_ADDRESS);
+  senderAddr = get_pa_string (sender, PR_SMTP_ADDRESS_DASL);
 
   curWindow = get_oom_context_window (context);
 
diff --git a/src/util.h b/src/util.h
index 88ff7bd..3dfab5f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -170,7 +170,7 @@ _gpgol_stpcpy (char *a, const char *b)
 #define stpcpy(a,b) _gpgol_stpcpy ((a), (b))
 #endif /*!HAVE_STPCPY*/
 
-
+extern int g_ol_version_major;
 
 #ifdef __cplusplus
 }

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

Summary of changes:
 src/Makefile.am            |   3 +-
 src/application-events.cpp |  21 +---
 src/gpgoladdin.cpp         |   4 +-
 src/mail.cpp               | 282 +++++++++++++++++++++++++++++++++++++++++++++
 src/mail.h                 | 107 +++++++++++++++++
 src/mailitem-events.cpp    | 250 +++++++---------------------------------
 src/main.c                 |   3 +
 src/message.cpp            |  57 +++++----
 src/mymapitags.h           |   3 +
 src/olflange.cpp           |   1 +
 src/oomhelp.cpp            |   2 +-
 src/oomhelp.h              |   4 +-
 src/ribbon-callbacks.cpp   |   8 +-
 src/util.h                 |   2 +-
 14 files changed, 487 insertions(+), 260 deletions(-)
 create mode 100644 src/mail.cpp
 create mode 100644 src/mail.h


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




More information about the Gnupg-commits mailing list