[git] GpgOL - branch, master, updated. gpgol-1.3.0-20-g79bd708

by Andre Heinecke cvs at cvs.gnupg.org
Thu Dec 3 19:31:37 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  79bd708bcc0ac5ffa110aa82db0437a7f422c5c6 (commit)
       via  18dbd4d71794b585e2df9a280aba5238ee7a672e (commit)
       via  ed50501a22ac1a041989a5feb5713e0bacb055bf (commit)
       via  974114b0c273bb27a4c49251827da522d6d1cd9c (commit)
       via  c6335b081a2f5a1cceb285af507444e404fda92b (commit)
      from  94b331747d84196f524b633c2a23568cb0b69359 (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 79bd708bcc0ac5ffa110aa82db0437a7f422c5c6
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Thu Dec 3 19:24:56 2015 +0100

    Add Revert support for S/MIME mails.
    
    * src/revert.cpp (gpgol_mailitem_revert): Handle S/MIME mails.
    * src/mapihelp.h: Add missing prototype for get_gpgolmsgclass_tag.
    
    --
    For S/MIME it is really mostly a problem of removing the attachments.

diff --git a/src/mapihelp.h b/src/mapihelp.h
index a154d95..ad2ede1 100644
--- a/src/mapihelp.h
+++ b/src/mapihelp.h
@@ -103,6 +103,7 @@ int get_gpgolsigstatus_tag (LPMESSAGE message, ULONG *r_tag);
 int get_gpgolprotectiv_tag (LPMESSAGE message, ULONG *r_tag);
 int get_gpgollastdecrypted_tag (LPMESSAGE message, ULONG *r_tag);
 int get_gpgolmimeinfo_tag (LPMESSAGE message, ULONG *r_tag);
+int get_gpgolmsgclass_tag (LPMESSAGE message, ULONG *r_tag);
 
 int mapi_do_save_changes (LPMESSAGE message, ULONG flags, int only_del_body,
                           const char *dbg_file, const char *dbg_func);
diff --git a/src/revert.cpp b/src/revert.cpp
index 180a12e..80876e3 100644
--- a/src/revert.cpp
+++ b/src/revert.cpp
@@ -310,6 +310,7 @@ gpgol_mailitem_revert (LPDISPATCH mailitem)
   int del_cnt = 0;
   LPDISPATCH to_restore = NULL;
   int mosstmpl_found = 0;
+  int is_smime = 0;
 
   /* Check whether we need to care about this message.  */
   msgcls = get_pa_string (mailitem, PR_MESSAGE_CLASS_W_DASL);
@@ -344,12 +345,37 @@ gpgol_mailitem_revert (LPDISPATCH mailitem)
 
   if (msgtype != MSGTYPE_GPGOL_PGP_MESSAGE &&
       msgtype != MSGTYPE_GPGOL_MULTIPART_ENCRYPTED &&
-      msgtype != MSGTYPE_GPGOL_MULTIPART_SIGNED)
+      msgtype != MSGTYPE_GPGOL_MULTIPART_SIGNED &&
+      msgtype != MSGTYPE_GPGOL_OPAQUE_ENCRYPTED &&
+      msgtype != MSGTYPE_GPGOL_OPAQUE_SIGNED)
     {
       log_error ("%s:%s: Revert not supported for msgtype: %i",
                  SRCNAME, __func__, msgtype);
       goto done;
     }
+
+  is_smime = msgtype == MSGTYPE_GPGOL_OPAQUE_ENCRYPTED ||
+             msgtype == MSGTYPE_GPGOL_OPAQUE_SIGNED;
+
+  /* Check if it is an smime mail. Multipart signed can
+     also be true. */
+  if (!is_smime && msgtype == MSGTYPE_GPGOL_MULTIPART_SIGNED)
+    {
+      char *proto;
+      char *ct = mapi_get_message_content_type (message, &proto, NULL);
+      if (ct && proto)
+        {
+          is_smime = (!strcmp (proto, "application/pkcs7-signature") ||
+                      !strcmp (proto, "application/x-pkcs7-signature"));
+        }
+      else
+        {
+          log_error ("Protocol in multipart signed mail.");
+        }
+      xfree (proto);
+      xfree (ct);
+    }
+
   count = get_oom_int (attachments, "Count");
   to_delete = (LPDISPATCH*) xmalloc (count * sizeof (LPDISPATCH));
 
@@ -375,8 +401,17 @@ gpgol_mailitem_revert (LPDISPATCH mailitem)
 
       if (get_pa_int (attachment, GPGOL_ATTACHTYPE_DASL, (int*) &att_type))
         {
-          log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
-          goto done;
+          if (!is_smime && msgtype != MSGTYPE_GPGOL_OPAQUE_SIGNED)
+            {
+              /* The Opaque signed attachment does not have a gpgol type
+                 for some reason. So we fake this here */
+              att_type = ATTACHTYPE_MOSSTEMPL;
+            }
+          else
+            {
+              log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+              goto done;
+            }
         }
 
       switch (att_type)
@@ -429,6 +464,12 @@ gpgol_mailitem_revert (LPDISPATCH mailitem)
                      This means treating it as a MOSSTMPL */
                   mosstmpl_found = 1;
                 }
+              else if (is_smime)
+                {
+                  /* Same here. No restoration but just rebuilding from the
+                     attachment. */
+                  mosstmpl_found = 1;
+                }
               else
                 {
                   log_oom ("%s:%s: Skipping attachment with tag: %s", SRCNAME,
@@ -448,6 +489,11 @@ gpgol_mailitem_revert (LPDISPATCH mailitem)
             /* This is a newly created attachment containing a MIME structure
                other clients could handle */
             {
+              if (mosstmpl_found)
+                {
+                  log_error ("More then one mosstempl.");
+                  goto done;
+                }
               mosstmpl_found = 1;
               break;
             }
@@ -479,31 +525,69 @@ gpgol_mailitem_revert (LPDISPATCH mailitem)
          mosstmplate in which case we need to activate the
          MultipartSigned magic.*/
       prop.ulPropTag = PR_MESSAGE_CLASS_A;
-      // TODO handle disabled S/MIME and smime messages.
-      if (msgtype == MSGTYPE_GPGOL_MULTIPART_SIGNED)
+      if (is_smime)
+        {
+#if 0
+          /* FIXME this does not appear to work somehow. */
+          if (opt.enable_smime)
+            {
+              prop.Value.lpszA =
+                (char*) "IPM.Note.InfoPathForm.GpgOL.SMIME.MultipartSigned";
+              hr = HrSetOneProp (message, &prop);
+            }
+          else
+#endif
+            {
+              ULONG tag;
+              if (msgtype == MSGTYPE_GPGOL_MULTIPART_SIGNED)
+                prop.Value.lpszA = (char*) "IPM.Note.SMIME.MultipartSigned";
+              else
+                prop.Value.lpszA = (char*) "IPM.Note.SMIME";
+              hr = HrSetOneProp (message, &prop);
+
+              if (!get_gpgolmsgclass_tag (message, &tag))
+                {
+                  SPropTagArray proparray;
+                  proparray.cValues = 1;
+                  proparray.aulPropTag[0] = tag;
+                  hr = message->DeleteProps (&proparray, NULL);
+                  if (hr)
+                    {
+                      log_error ("%s:%s: deleteprops smime failed: hr=%#lx\n",
+                                 SRCNAME, __func__, hr);
+
+                    }
+                }
+            }
+        }
+      else if (msgtype == MSGTYPE_GPGOL_MULTIPART_SIGNED)
         {
           prop.Value.lpszA =
             (char*) "IPM.Note.InfoPathForm.GpgOLS.SMIME.MultipartSigned";
+          hr = HrSetOneProp (message, &prop);
         }
       else
         {
           prop.Value.lpszA =
             (char*) "IPM.Note.InfoPathForm.GpgOL.SMIME.MultipartSigned";
+          hr = HrSetOneProp (message, &prop);
         }
-      hr = HrSetOneProp (message, &prop);
       if (hr)
         {
           log_error ("%s:%s: error setting the message class: hr=%#lx\n",
                      SRCNAME, __func__, hr);
           goto done;
         }
+
       /* Backup the real message class */
-      if (mapi_set_gpgol_msg_class (message, msgcls))
+      if (!is_smime || opt.enable_smime)
         {
-          log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
-          goto done;
+          if (mapi_set_gpgol_msg_class (message, msgcls))
+            {
+              log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+              goto done;
+            }
         }
-
     }
 
   result = 0;

commit 18dbd4d71794b585e2df9a280aba5238ee7a672e
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Thu Dec 3 19:21:06 2015 +0100

    Try harder to save reverted mails
    
    * src/revert.cpp (finalize_mapi): Try several secons to store.
    
    --
    Sometimes we get an error object has changed here. This
    appears to be related to other MAPI io happening, and coincides
    with a busy disk. So we do some evil sleeping in the GUI thread.
    This actually works. If we don't and have errors
    there we are in a bad place as we don't know if the message has
    been reverted.

diff --git a/src/revert.cpp b/src/revert.cpp
index d925cf5..180a12e 100644
--- a/src/revert.cpp
+++ b/src/revert.cpp
@@ -241,6 +241,8 @@ static int finalize_mapi (LPMESSAGE message)
   HRESULT hr;
   SPropTagArray proparray;
   ULONG tag_id;
+  int save_tries;
+  int rc;
 
   if (get_gpgollastdecrypted_tag (message, &tag_id))
     {
@@ -259,10 +261,19 @@ static int finalize_mapi (LPMESSAGE message)
     }
 
   /* Save the changes. */
-  if (mapi_save_changes (message,
-                         FORCE_SAVE | KEEP_OPEN_READWRITE))
+  for (save_tries = 0, rc = 1; rc && save_tries < 10; save_tries++)
     {
-      log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+      rc = mapi_save_changes (message, FORCE_SAVE);
+      if (rc)
+        {
+          log_debug ("Failed try to save.");
+          Sleep (1000);
+        }
+    }
+  if (save_tries == 5)
+    {
+      log_error ("%s:%s: Saving restored message failed.",
+                 SRCNAME, __func__);
       return -1;
     }
 

commit ed50501a22ac1a041989a5feb5713e0bacb055bf
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Thu Dec 3 15:49:51 2015 +0100

    Add revert support for mulitpart signed PGP MIME
    
    * src/mimemaker.c (restore_msg_from_moss): Don't set gpgol
      msg_class.
    * src/revert.cpp (gpgol_mailitem_revert): Add support for
      MULTIPART_SIGNED.
    
    --
    Multipart signed is directly restore from the mosstmpl. This
    is very fragile though and only works good for mails sent by
    gpgol because Outlook mangles the innter MIME boundaries for
    mails from at least KMail and Enigmail. So the signature is
    broken after the mail went through outlook.

diff --git a/src/mimemaker.c b/src/mimemaker.c
index 057ff9b..235b844 100644
--- a/src/mimemaker.c
+++ b/src/mimemaker.c
@@ -2034,6 +2034,8 @@ restore_msg_from_moss (LPMESSAGE message, LPDISPATCH moss_att,
   int err = -1;
   char boundary[BOUNDARYSIZE+1];
 
+  (void)msgcls;
+
   LPATTACH new_attach = create_mapi_attachment (message,
                                                 sink);
   log_debug ("Restore message from moss called.");
@@ -2047,10 +2049,16 @@ restore_msg_from_moss (LPMESSAGE message, LPDISPATCH moss_att,
     {
       create_top_encryption_header (sink, PROTOCOL_SMIME, boundary);
     }
-  else
+  else if (type == MSGTYPE_GPGOL_MULTIPART_ENCRYPTED)
     {
       create_top_encryption_header (sink, PROTOCOL_OPENPGP, boundary);
     }
+  else
+    {
+      log_error ("%s:%s: Unsupported messagetype: %i",
+                 SRCNAME, __func__, type);
+      goto done;
+    }
 
   orig = get_pa_string (moss_att, PR_ATTACH_DATA_BIN_DASL);
 
@@ -2086,12 +2094,6 @@ restore_msg_from_moss (LPMESSAGE message, LPDISPATCH moss_att,
       goto done;
     }
 
-  if (mapi_set_gpgol_msg_class (message, msgcls))
-    {
-      log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
-      goto done;
-    }
-
   err = 0;
 done:
   xfree (orig);
diff --git a/src/revert.cpp b/src/revert.cpp
index 714da94..d925cf5 100644
--- a/src/revert.cpp
+++ b/src/revert.cpp
@@ -332,7 +332,8 @@ gpgol_mailitem_revert (LPDISPATCH mailitem)
   msgtype = mapi_get_message_type (message);
 
   if (msgtype != MSGTYPE_GPGOL_PGP_MESSAGE &&
-      msgtype != MSGTYPE_GPGOL_MULTIPART_ENCRYPTED)
+      msgtype != MSGTYPE_GPGOL_MULTIPART_ENCRYPTED &&
+      msgtype != MSGTYPE_GPGOL_MULTIPART_SIGNED)
     {
       log_error ("%s:%s: Revert not supported for msgtype: %i",
                  SRCNAME, __func__, msgtype);
@@ -397,17 +398,33 @@ gpgol_mailitem_revert (LPDISPATCH mailitem)
             {
               char *mime_tag = get_pa_string (attachment,
                                               PR_ATTACH_MIME_TAG_DASL);
-              if (mime_tag && !strcmp (mime_tag, "application/octet-stream"))
+              if (!mime_tag)
                 {
+                  log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+                }
+              else if (msgtype == MSGTYPE_GPGOL_MULTIPART_ENCRYPTED &&
+                       !strcmp (mime_tag, "application/octet-stream"))
+                {
+                  /* This is the body attachment of a multipart encrypted
+                     message. Rebuild the message. */
                   to_restore = attachment;
+                  to_delete[del_cnt++] = attachment;
+                }
+              else if (msgtype == MSGTYPE_GPGOL_MULTIPART_SIGNED &&
+                       mime_tag && !strcmp (mime_tag, "multipart/signed"))
+                {
+                  /* This is the MIME formatted MOSS attachment of a multipart
+                     signed message. Rebuild the MIME structure from that.
+                     This means treating it as a MOSSTMPL */
+                  mosstmpl_found = 1;
                 }
               else
                 {
                   log_oom ("%s:%s: Skipping attachment with tag: %s", SRCNAME,
                            __func__, mime_tag);
+                  to_delete[del_cnt++] = attachment;
                 }
               xfree (mime_tag);
-              to_delete[del_cnt++] = attachment;
               break;
             }
           case ATTACHTYPE_FROMMOSS:
@@ -452,8 +469,16 @@ gpgol_mailitem_revert (LPDISPATCH mailitem)
          MultipartSigned magic.*/
       prop.ulPropTag = PR_MESSAGE_CLASS_A;
       // TODO handle disabled S/MIME and smime messages.
-      prop.Value.lpszA =
-        (char*) "IPM.Note.InfoPathForm.GpgOL.SMIME.MultipartSigned";
+      if (msgtype == MSGTYPE_GPGOL_MULTIPART_SIGNED)
+        {
+          prop.Value.lpszA =
+            (char*) "IPM.Note.InfoPathForm.GpgOLS.SMIME.MultipartSigned";
+        }
+      else
+        {
+          prop.Value.lpszA =
+            (char*) "IPM.Note.InfoPathForm.GpgOL.SMIME.MultipartSigned";
+        }
       hr = HrSetOneProp (message, &prop);
       if (hr)
         {
@@ -461,6 +486,13 @@ gpgol_mailitem_revert (LPDISPATCH mailitem)
                      SRCNAME, __func__, hr);
           goto done;
         }
+      /* Backup the real message class */
+      if (mapi_set_gpgol_msg_class (message, msgcls))
+        {
+          log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+          goto done;
+        }
+
     }
 
   result = 0;

commit 974114b0c273bb27a4c49251827da522d6d1cd9c
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Thu Dec 3 15:44:30 2015 +0100

    Try yet another way to find sender address
    
    * src/mail.cpp (Mail::update_sender): Use SendUsingAccount.
    --
    Session.CurrentUser did not work for the case in which you
    are currently browsing the Folder of UserA and try to send
    a mail with UserB. SendUsingAccount appears more reliable.
    Also works with exchange.

diff --git a/src/mail.cpp b/src/mail.cpp
index 8c6f56d..7dc02f6 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -308,17 +308,17 @@ int
 Mail::update_sender ()
 {
   LPDISPATCH sender = NULL;
-  sender = get_oom_object (m_mailitem, "Session.CurrentUser");
+  sender = get_oom_object (m_mailitem, "SendUsingAccount");
 
   xfree (m_sender);
 
   if (!sender)
     {
-      log_error ("%s:%s: Failed to get sender object.",
+      log_debug ("%s:%s: Failed to get sender Account object.",
                  SRCNAME, __func__);
       return -1;
     }
-  m_sender = get_pa_string (sender, PR_SMTP_ADDRESS_DASL);
+  m_sender = get_oom_string (sender, "SmtpAddress");
 
   if (!m_sender)
     {

commit c6335b081a2f5a1cceb285af507444e404fda92b
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Thu Dec 3 15:38:10 2015 +0100

    Try harder to match outlooks internal filename enc
    
    * src/common.c (qp_encode): New. Simple quoted printable encoder.
      (b64_encode): Fix termination of return value.
    * src/common.h: Add prototype
    * src/mimemaker.c (utf8_to_rfc2047b): Use infer content encoding
      to switch between base64 and quoted printable.
    
    --
    As outlook rewrites the attachment filenames in unencrypted mails
    we have to guess how they will look so that we sign them correctly.
    If it turns out that this is to buggy we should probably replace
    non ascii characters in that case.

diff --git a/src/common.c b/src/common.c
index bf1c9e9..2142a80 100644
--- a/src/common.c
+++ b/src/common.c
@@ -818,6 +818,51 @@ qp_decode (char *buffer, size_t length, int *r_slbrk)
   return d - buffer;
 }
 
+/* Return the a quoted printable encoded version of the
+   input string. If outlen is not null the size of the
+   quoted printable string is returned. String will be
+   malloced and zero terminated. Aborts if the output
+   is more then three times the size of the input.
+   This is only basic and does not handle mutliline data. */
+char *
+qp_encode (const char *input, size_t inlen, size_t *r_outlen)
+{
+  size_t max_len = inlen * 3 +1;
+  char *outbuf = xmalloc (max_len);
+  size_t outlen = 0;
+  const unsigned char *p;
+
+  memset (outbuf, 0, max_len);
+
+  for (p = input; inlen; p++, inlen--)
+    {
+      if (*p >= '!' && *p <= '~' && *p != '=')
+        {
+          outbuf[outlen++] = *p;
+        }
+      else if (*p == ' ')
+        {
+          /* Outlook does it this way */
+          outbuf[outlen++] = '_';
+        }
+      else
+        {
+          outbuf[outlen++] = '=';
+          outbuf[outlen++] = tohex ((*p>>4)&15);
+          outbuf[outlen++] = tohex (*p&15);
+        }
+      if (outlen == max_len -1)
+        {
+          log_error ("Quoted printable too long. Bug.");
+          r_outlen = NULL;
+          return NULL;
+        }
+    }
+  if (r_outlen)
+    *r_outlen = outlen;
+  return outbuf;
+}
+
 
 /* Initialize the Base 64 decoder state.  */
 void b64_init (b64_state_t *state)
@@ -909,6 +954,7 @@ b64_encode (const char *input, size_t length)
       return NULL;
     }
   ret = xmalloc (out_len);
+  memset (ret, 0, out_len);
 
   for (i = 0, j = 0; i < length;)
     {
@@ -933,8 +979,6 @@ b64_encode (const char *input, size_t length)
       ret [j - 2] = '=';
     }
 
-  ret[++j] = '\0';
-  log_debug("Encoded to: %s ", ret);
   return ret;
 }
 
diff --git a/src/common.h b/src/common.h
index ea003b9..3d09446 100644
--- a/src/common.h
+++ b/src/common.h
@@ -197,6 +197,7 @@ const char *default_homedir (void);
 char *get_data_dir (void);
 
 size_t qp_decode (char *buffer, size_t length, int *r_slbrk);
+char *qp_encode (const char *input, size_t length, size_t* outlen);
 void b64_init (b64_state_t *state);
 size_t b64_decode (b64_state_t *state, char *buffer, size_t length);
 char * b64_encode (const char *input, size_t length);
diff --git a/src/mimemaker.c b/src/mimemaker.c
index 461d1e3..057ff9b 100644
--- a/src/mimemaker.c
+++ b/src/mimemaker.c
@@ -793,19 +793,45 @@ infer_content_encoding (const void *data, size_t datalen)
 static char *
 utf8_to_rfc2047b (const char *input)
 {
-  char *ret;
+  char *ret,
+       *encoded;
+  int inferred_encoding = 0;
   if (!input)
     {
       return NULL;
     }
-  char *b64_encoded = b64_encode (input, strlen (input));
-  if (gpgrt_asprintf (&ret, "=?UTF-8?B?%s?=", b64_encoded) == -1)
+  inferred_encoding = infer_content_encoding (input, strlen (input));
+  if (!inferred_encoding)
     {
-      log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
-      xfree (b64_encoded);
-      return NULL;
+      return xstrdup (input);
+    }
+  log_debug ("%s:%s: Encoding attachment filename. With: %s ",
+             SRCNAME, __func__, inferred_encoding == 2 ? "Base64" : "QP");
+
+  if (inferred_encoding == 2)
+    {
+      encoded = b64_encode (input, strlen (input));
+      if (gpgrt_asprintf (&ret, "=?utf-8?B?%s?=", encoded) == -1)
+        {
+          log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+          xfree (encoded);
+          return NULL;
+        }
+    }
+  else
+    {
+      /* There is a Bug here. If you encode 4 Byte UTF-8 outlook can't
+         handle it itself. And sends out a message with ?? inserted in
+         that place. This triggers an invalid signature. */
+      encoded = qp_encode (input, strlen (input), NULL);
+      if (gpgrt_asprintf (&ret, "=?utf-8?Q?%s?=", encoded) == -1)
+        {
+          log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+          xfree (encoded);
+          return NULL;
+        }
     }
-  xfree (b64_encoded);
+  xfree (encoded);
   return ret;
 }
 

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

Summary of changes:
 src/common.c    |  48 +++++++++++++++++-
 src/common.h    |   1 +
 src/mail.cpp    |   6 +--
 src/mapihelp.h  |   1 +
 src/mimemaker.c |  56 +++++++++++++++------
 src/revert.cpp  | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 6 files changed, 232 insertions(+), 31 deletions(-)


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




More information about the Gnupg-commits mailing list