[git] GpgOL - branch, master, updated. gpgol-2.0.6-127-g88a3204

by Andre Heinecke cvs at cvs.gnupg.org
Wed Apr 11 13:19:00 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  88a3204d34b97430e7f1f80ebfe1f9f8e6fa9ddc (commit)
       via  dc48589b3d429d7d156c75b4e7bc784b140f40ce (commit)
      from  7cb3feaf64d3098a5bc56cad62576bb67e5d74bf (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 88a3204d34b97430e7f1f80ebfe1f9f8e6fa9ddc
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Apr 11 13:15:09 2018 +0200

    Change S/MIME behavior depending on Exchange ver.
    
    * src/oomhelp.cpp, src/oomhelp.h (get_ex_major_version_for_addr): New.
    * src/cryptcontroller.cpp (create_encrypt_attach): Accept
    exchange version as parameter. Change behavior accordingly.
    (CryptController::update_mail_mapi): Add handling for exchange ver.
    * src/mimemaker.cpp (create_top_encryption_header): Accept
    exchange ver.
    * src/mimemaker.h: Update accordingly.
    
    --
    This fixes 7cb3feaf which broke S/MIME encrypted send for
    older exchange versions and SMTP / IMAP. Because it unconditionally
    used different code to construct the encrypted message in the
    expectation that this would also work as an alternative.
    
    GnuPG-Bug-Id: T3884

diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp
index 5aa1022..bc308cb 100644
--- a/src/cryptcontroller.cpp
+++ b/src/cryptcontroller.cpp
@@ -825,11 +825,12 @@ create_sign_attach (sink_t sink, protocol_t protocol,
 
 static int
 create_encrypt_attach (sink_t sink, protocol_t protocol,
-                       GpgME::Data &encryptedData)
+                       GpgME::Data &encryptedData,
+                       int exchange_major_version)
 {
   char boundary[BOUNDARYSIZE+1];
   int rc = create_top_encryption_header (sink, protocol, boundary,
-                                         false);
+                                         false, exchange_major_version);
   // From here on use goto failure pattern.
   if (rc)
     {
@@ -838,7 +839,18 @@ create_encrypt_attach (sink_t sink, protocol_t protocol,
       return rc;
     }
 
-  rc = write_data (sink, encryptedData);
+  if (protocol == PROTOCOL_OPENPGP ||
+      exchange_major_version >= 15)
+    {
+      // With exchange 2016 we have to construct S/MIME
+      // differently and write the raw data here.
+      rc = write_data (sink, encryptedData);
+    }
+  else
+    {
+      const auto encStr = encryptedData.toString();
+      rc = write_b64 (sink, encStr.c_str(), encStr.size());
+    }
 
   if (rc)
     {
@@ -886,12 +898,20 @@ CryptController::update_mail_mapi ()
   sink->cb_data = &m_input;
   sink->writefnc = sink_data_write;
 
-  // For S/MIME encrypted mails we have to use the multipart/encrypted
+  // For S/MIME encrypted mails we have to use the application/pkcs7-mime
   // content type. Otherwise newer (2016) exchange servers will throw
   // an M2MCVT.StorageError.Exeption (See GnuPG-Bug-Id: T3853 )
+
+  // This means that the conversion / build of the mime structure also
+  // happens differently.
+  int exchange_major_version = get_ex_major_version_for_addr (
+                                        m_mail->get_cached_sender ().c_str ());
+
   std::string overrideMimeTag;
-  if (m_proto == GpgME::CMS && m_encrypt)
+  if (m_proto == GpgME::CMS && m_encrypt && exchange_major_version >= 15)
     {
+      log_debug ("%s:%s: CMS Encrypt with Exchange %i activating alternative.",
+                 SRCNAME, __func__, exchange_major_version);
       overrideMimeTag = "application/pkcs7-mime";
     }
 
@@ -909,6 +929,7 @@ CryptController::update_mail_mapi ()
   protocol_t protocol = m_proto == GpgME::CMS ?
                                    PROTOCOL_SMIME :
                                    PROTOCOL_OPENPGP;
+
   int rc = 0;
   /* Do we have override MIME ? */
   const auto overrideMime = m_mail->get_override_mime_data ();
@@ -918,11 +939,11 @@ CryptController::update_mail_mapi ()
     }
   else if (m_sign && m_encrypt)
     {
-      rc = create_encrypt_attach (sink, protocol, m_output);
+      rc = create_encrypt_attach (sink, protocol, m_output, exchange_major_version);
     }
   else if (m_encrypt)
     {
-      rc = create_encrypt_attach (sink, protocol, m_output);
+      rc = create_encrypt_attach (sink, protocol, m_output, exchange_major_version);
     }
   else if (m_sign)
     {
diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp
index ed961f7..1e4a5d6 100644
--- a/src/mimemaker.cpp
+++ b/src/mimemaker.cpp
@@ -1892,7 +1892,7 @@ sink_encryption_write_b64 (sink_t encsink, const void *data, size_t datalen)
    function.  */
 int
 create_top_encryption_header (sink_t sink, protocol_t protocol, char *boundary,
-                              bool is_inline)
+                              bool is_inline, int exchange_major_version)
 {
   int rc;
 
@@ -1915,26 +1915,31 @@ create_top_encryption_header (sink_t sink, protocol_t protocol, char *boundary,
   else if (protocol == PROTOCOL_SMIME)
     {
       *boundary = 0;
-      rc = 0;
-      /*
-        For S/MIME encrypted mails we do not use the S/MIME conversion
-        code anymore. With Exchange 2016 this no longer works. Instead
-        we set an override mime tag, the extended headers in OOM in
-        Mail::update_crypt_oom and let outlook convert the attachment
-        to base64.
-
-        A bit more details can be found in T3853 / T3884
-
-      rc = write_multistring (sink,
-                              "Content-Type: application/pkcs7-mime; "
-                              "smime-type=enveloped-data;\r\n"
-                              "\tname=\"smime.p7m\"\r\n"
-                              "Content-Disposition: attachment; filename=\"smime.p7m\"\r\n"
-                              "Content-Transfer-Encoding: base64\r\n"
-                              "MIME-Version: 1.0\r\n"
-                              "\r\n",
-                              NULL);
-      */
+      if (exchange_major_version >= 15)
+        {
+          /*
+             For S/MIME encrypted mails we do not use the S/MIME conversion
+             code anymore. With Exchange 2016 this no longer works. Instead
+             we set an override mime tag, the extended headers in OOM in
+             Mail::update_crypt_oom and let outlook convert the attachment
+             to base64.
+
+             A bit more details can be found in T3853 / T3884
+             */
+          rc = 0;
+        }
+      else
+        {
+          rc = write_multistring (sink,
+                                  "Content-Type: application/pkcs7-mime; "
+                                  "smime-type=enveloped-data;\r\n"
+                                  "\tname=\"smime.p7m\"\r\n"
+                                  "Content-Disposition: attachment; filename=\"smime.p7m\"\r\n"
+                                  "Content-Transfer-Encoding: base64\r\n"
+                                  "MIME-Version: 1.0\r\n"
+                                  "\r\n",
+                                  NULL);
+        }
     }
   else
     {
diff --git a/src/mimemaker.h b/src/mimemaker.h
index 4758bfd..eed47a3 100644
--- a/src/mimemaker.h
+++ b/src/mimemaker.h
@@ -77,7 +77,7 @@ int add_body_and_attachments (sink_t sink, LPMESSAGE message,
                               mapi_attach_item_t *att_table, Mail *mail,
                               const char *body, int n_att_usable);
 int create_top_encryption_header (sink_t sink, protocol_t protocol, char *boundary,
-                              bool is_inline = false);
+                              bool is_inline = false, int exchange_major_version = -1);
 
 /* Helper to write a boundary to the output sink.  The leading LF
    will be written as well.  */
diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp
index 51d025b..4ba8715 100644
--- a/src/oomhelp.cpp
+++ b/src/oomhelp.cpp
@@ -2034,3 +2034,26 @@ get_inline_body ()
 
   return body;
 }
+
+int
+get_ex_major_version_for_addr (const char *mbox)
+{
+  LPDISPATCH account = get_account_for_mail (mbox);
+  if (!account)
+    {
+      TRACEPOINT;
+      return -1;
+    }
+
+  char *version_str = get_oom_string (account, "ExchangeMailboxServerVersion");
+  gpgol_release (account);
+
+  if (!version_str)
+    {
+      return -1;
+    }
+  long int version = strtol (version_str, nullptr, 10);
+  xfree (version_str);
+
+  return (int) version;
+}
diff --git a/src/oomhelp.h b/src/oomhelp.h
index 3bf86a6..13faafb 100644
--- a/src/oomhelp.h
+++ b/src/oomhelp.h
@@ -343,6 +343,12 @@ char *get_sender_SenderEMailAddress (LPDISPATCH mailitem);
 
 /* Get the body of the active inline response */
 char *get_inline_body (void);
+
+/* Get the major version of the exchange server of the account for the
+   mail address "mbox". Returns -1 if no version could be detected
+   or exchange is not used.*/
+int get_ex_major_version_for_addr (const char *mbox);
+
 #ifdef __cplusplus
 char *get_sender_SendUsingAccount (LPDISPATCH mailitem, bool *r_is_GSuite);
 }

commit dc48589b3d429d7d156c75b4e7bc784b140f40ce
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Apr 11 10:13:33 2018 +0200

    Handle weirdly constructed PGP/MIME mails
    
    * src/mapihelp.cpp (get_msgcls_from_pgp_lines): Add return
    value for empty body.
    (get_msgcls_from_first_attachment): New. factored out.
    (change_message_class_ipm_note): Use get_msgcls_from_first_attachment.
    
    --
    This fixes the handling of mails that are:
    
    multipart/mixed
    ->application/pgp-encrypted
    ->application/octed-stream
    
    They also don't have a body. To avoid overhead in a
    normal unencrypted multipart mixed mail we only check
    for this structure if we don't have a body.
    
    GnuPG-Bug-Id: T3882

diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp
index 7e33823..1be66b6 100644
--- a/src/mapihelp.cpp
+++ b/src/mapihelp.cpp
@@ -630,9 +630,12 @@ mapi_get_body (LPMESSAGE message, size_t *r_nbytes)
 
 /* Look at the body of the MESSAGE and try to figure out whether this
    is a supported PGP message.  Returns the new message class or NULL
-   if it does not look like a PGP message.  */
+   if it does not look like a PGP message.
+
+   If r_nobody is not null it is set to true if no body was found.
+   */
 static char *
-get_msgcls_from_pgp_lines (LPMESSAGE message)
+get_msgcls_from_pgp_lines (LPMESSAGE message, bool *r_nobody = nullptr)
 {
   HRESULT hr;
   LPSTREAM stream;
@@ -649,6 +652,11 @@ get_msgcls_from_pgp_lines (LPMESSAGE message)
       return NULL;
     }
 
+  if (r_nobody)
+    {
+      *r_nobody = false;
+    }
+
   stream = mapi_get_body_as_stream (message);
   if (!stream)
     {
@@ -660,6 +668,10 @@ get_msgcls_from_pgp_lines (LPMESSAGE message)
         {
           log_error ("%s:%s: Failed to get  w_body stream. : hr=%#lx",
                      SRCNAME, __func__, hr);
+          if (r_nobody)
+            {
+              *r_nobody = true;
+            }
           return NULL;
         }
       else
@@ -979,6 +991,30 @@ get_first_attach_mime_tag (LPMESSAGE message)
 }
 
 
+/* Look at the first attachment's content type to determine the
+   messageclass. */
+static char *
+get_msgcls_from_first_attachment (LPMESSAGE message)
+{
+  char *ret = nullptr;
+  char *attach_mime = get_first_attach_mime_tag (message);
+  if (!attach_mime)
+    {
+      return nullptr;
+    }
+  if (!strcmp (attach_mime, "application/pgp-encrypted"))
+    {
+      ret = xstrdup ("IPM.Note.GpgOL.MultipartEncrypted");
+      xfree (attach_mime);
+    }
+  else if (!strcmp (attach_mime, "application/pgp-signature"))
+    {
+      ret = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
+      xfree (attach_mime);
+    }
+  return ret;
+}
+
 /* Helper for mapi_change_message_class.  Returns the new message
    class as an allocated string.
 
@@ -1022,22 +1058,7 @@ change_message_class_ipm_note (LPMESSAGE message)
       if (!newvalue)
         {
           /* So no PGP Inline. Lets look at the attachment. */
-          char *attach_mime = get_first_attach_mime_tag (message);
-          if (!attach_mime)
-            {
-              xfree (ct);
-              return nullptr;
-            }
-          if (!strcmp (attach_mime, "application/pgp-encrypted"))
-            {
-              newvalue = xstrdup ("IPM.Note.GpgOL.MultipartEncrypted");
-              xfree (attach_mime);
-            }
-          else if (!strcmp (attach_mime, "application/pgp-signature"))
-            {
-              newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
-              xfree (attach_mime);
-            }
+          newvalue = get_msgcls_from_first_attachment (message);
         }
     }
   else if (!ct || !strcmp (ct, "text/plain") ||
@@ -1046,10 +1067,21 @@ change_message_class_ipm_note (LPMESSAGE message)
            !strcmp (ct, "multipart/related") ||
            !strcmp (ct, "text/html"))
     {
+      bool has_no_body = false;
       /* It is quite common to have a multipart/mixed or alternative
          mail with separate encrypted PGP parts.  Look at the body to
          decide.  */
-      newvalue = get_msgcls_from_pgp_lines (message);
+      newvalue = get_msgcls_from_pgp_lines (message, &has_no_body);
+
+      if (!newvalue && has_no_body && !strcmp (ct, "multipart/mixed"))
+        {
+          /* This is uncommon. But some Exchanges might break a PGP/MIME mail
+             this way. Let's take a look at the attachments. Maybe it's
+             a PGP/MIME mail. */
+          log_debug ("%s:%s: Multipart mixed without body found. Looking at attachments.",
+                     SRCNAME, __func__);
+          newvalue = get_msgcls_from_first_attachment (message);
+        }
     }
 
   xfree (ct);

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

Summary of changes:
 src/cryptcontroller.cpp | 35 ++++++++++++++++++++-----
 src/mapihelp.cpp        | 70 +++++++++++++++++++++++++++++++++++--------------
 src/mimemaker.cpp       | 47 ++++++++++++++++++---------------
 src/mimemaker.h         |  2 +-
 src/oomhelp.cpp         | 23 ++++++++++++++++
 src/oomhelp.h           |  6 +++++
 6 files changed, 135 insertions(+), 48 deletions(-)


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




More information about the Gnupg-commits mailing list