[svn] GpgOL - r274 - in trunk: . po src

svn author wk cvs at cvs.gnupg.org
Thu Oct 23 21:19:31 CEST 2008


Author: wk
Date: 2008-10-23 21:19:31 +0200 (Thu, 23 Oct 2008)
New Revision: 274

Modified:
   trunk/NEWS
   trunk/po/de.po
   trunk/po/sv.po
   trunk/src/ChangeLog
   trunk/src/mapihelp.cpp
   trunk/src/mapihelp.h
   trunk/src/message-events.cpp
   trunk/src/message.cpp
   trunk/src/mimeparser.c
   trunk/src/mimeparser.h
Log:
Fixed PGP clear sign message verification.
Delete stale attachemnt when forwarding a message.


Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-10-17 19:04:00 UTC (rev 273)
+++ trunk/src/ChangeLog	2008-10-23 19:19:31 UTC (rev 274)
@@ -1,3 +1,17 @@
+2008-10-23  Werner Koch  <wk at g10code.com>
+
+	* mapihelp.cpp (mapi_delete_gpgol_body_attachment): New.
+	* message-events.cpp (OnWriteComplete): Remove a body attachment.
+
+	* message.cpp (message_display_handler): Do not display PGP
+	clearsigned messages.
+	(message_display_handler): Do not update GpgOLStatus; it is not
+	used anyway.
+	(pgp_mime_from_clearsigned): Fix bogus trailing white space
+	removal code.  Insert an empty line.
+	* mimeparser.c (mime_verify): Add arg MIMEHACK.
+	(message_verify): Use it.
+
 2008-10-17  Werner Koch  <wk at g10code.com>
 
 	* recipient-dialog.c (load_rsetbox): Remove superfluous check on

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2008-10-17 19:04:00 UTC (rev 273)
+++ trunk/NEWS	2008-10-23 19:19:31 UTC (rev 274)
@@ -3,7 +3,9 @@
 
  * Fixed a regression in the last release with opaque signatures.
 
+ * Fixed PGP cleartext signature verification.
 
+
 Noteworthy changes for version 0.10.15 (2008-08-06)
 ===================================================
 

Modified: trunk/po/de.po  [not shown]
Modified: trunk/po/sv.po  [not shown]
Modified: trunk/src/mapihelp.cpp
===================================================================
--- trunk/src/mapihelp.cpp	2008-10-17 19:04:00 UTC (rev 273)
+++ trunk/src/mapihelp.cpp	2008-10-23 19:19:31 UTC (rev 274)
@@ -1482,6 +1482,7 @@
   if ( PROP_TYPE (propval->ulPropTag) == PT_STRING8 )
     {
       const char *s = propval->Value.lpszA;
+
       if (!strncmp (s, "IPM.Note.GpgOL", 14) && (!s[14] || s[14] =='.'))
         {
           s += 14;
@@ -2837,6 +2838,96 @@
 }
 
 
+/* Delete a possible body atatchment.  Returns true if an atatchment
+   has been deleted.  */
+int
+mapi_delete_gpgol_body_attachment (LPMESSAGE message)
+{    
+  HRESULT hr;
+  SizedSPropTagArray (1L, propAttNum) = { 1L, {PR_ATTACH_NUM} };
+  LPMAPITABLE mapitable;
+  LPSRowSet   mapirows;
+  unsigned int pos, n_attach;
+  ULONG moss_tag;
+  int found = 0;
+
+  if (get_gpgolattachtype_tag (message, &moss_tag) )
+    return 0;
+
+  hr = message->GetAttachmentTable (0, &mapitable);
+  if (FAILED (hr))
+    {
+      log_debug ("%s:%s: GetAttachmentTable failed: hr=%#lx",
+                 SRCNAME, __func__, hr);
+      return 0;
+    }
+      
+  hr = HrQueryAllRows (mapitable, (LPSPropTagArray)&propAttNum,
+                       NULL, NULL, 0, &mapirows);
+  if (FAILED (hr))
+    {
+      log_debug ("%s:%s: HrQueryAllRows failed: hr=%#lx",
+                 SRCNAME, __func__, hr);
+      mapitable->Release ();
+      return 0;
+    }
+  n_attach = mapirows->cRows > 0? mapirows->cRows : 0;
+  if (!n_attach)
+    {
+      FreeProws (mapirows);
+      mapitable->Release ();
+      return 0; /* No Attachments.  */
+    }
+
+  for (pos=0; pos < n_attach; pos++) 
+    {
+      LPATTACH att;
+
+      if (mapirows->aRow[pos].cValues < 1)
+        {
+          log_error ("%s:%s: invalid row at pos %d", SRCNAME, __func__, pos);
+          continue;
+        }
+      if (mapirows->aRow[pos].lpProps[0].ulPropTag != PR_ATTACH_NUM)
+        {
+          log_error ("%s:%s: invalid prop at pos %d", SRCNAME, __func__, pos);
+          continue;
+        }
+      hr = message->OpenAttach (mapirows->aRow[pos].lpProps[0].Value.l,
+                                NULL, MAPI_BEST_ACCESS, &att);	
+      if (FAILED (hr))
+        {
+          log_error ("%s:%s: can't open attachment %d (%ld): hr=%#lx",
+                     SRCNAME, __func__, pos, 
+                     mapirows->aRow[pos].lpProps[0].Value.l, hr);
+          continue;
+        }
+      if (has_gpgol_body_name (att)
+          && get_gpgolattachtype (att, moss_tag) == ATTACHTYPE_FROMMOSS)
+        {
+          att->Release ();
+          hr = message->DeleteAttach (mapirows->aRow[pos].lpProps[0].Value.l,
+                                      0, NULL, 0);
+          if (hr)
+            log_error ("%s:%s: DeleteAttach failed: hr=%#lx\n",
+                         SRCNAME, __func__, hr); 
+          else
+            {
+              log_debug ("%s:%s: body attachment deleted\n", 
+                         SRCNAME, __func__); 
+              found = 1;
+              
+            }
+          break;
+        }
+      att->Release ();
+    }
+  FreeProws (mapirows);
+  mapitable->Release ();
+  return found;
+}
+
+
 /* Copy the attachment ITEM of the message MESSAGE verbatim to the
    PR_BODY property.  Returns 0 on success.  This function does not
    call SaveChanges. */

Modified: trunk/src/mapihelp.h
===================================================================
--- trunk/src/mapihelp.h	2008-10-17 19:04:00 UTC (rev 273)
+++ trunk/src/mapihelp.h	2008-10-23 19:19:31 UTC (rev 274)
@@ -159,6 +159,7 @@
                                       char **r_body, size_t *r_nbytes,
                                       int *r_ishtml, int *r_protected);
 
+int   mapi_delete_gpgol_body_attachment (LPMESSAGE message);
 
 int   mapi_attachment_to_body (LPMESSAGE message, mapi_attach_item_t *item);
 

Modified: trunk/src/message-events.cpp
===================================================================
--- trunk/src/message-events.cpp	2008-10-17 19:04:00 UTC (rev 273)
+++ trunk/src/message-events.cpp	2008-10-23 19:19:31 UTC (rev 274)
@@ -387,7 +387,14 @@
       else if (!m_pExchExt->m_gpgEncrypt && m_pExchExt->m_gpgSign)
         rc = message_sign (msg, proto, hWnd);
       else
-        rc = 0;
+        {
+          /* In case this is a forward message which is not to be
+             signed or encrypted we need to remove a possible body
+             attachment.  */
+          if (mapi_delete_gpgol_body_attachment (msg))
+            mapi_save_changes (msg, KEEP_OPEN_READWRITE);
+          rc = 0;
+        }
       
       if (rc)
         {

Modified: trunk/src/message.cpp
===================================================================
--- trunk/src/message.cpp	2008-10-17 19:04:00 UTC (rev 273)
+++ trunk/src/message.cpp	2008-10-23 19:19:31 UTC (rev 274)
@@ -154,28 +154,46 @@
   LPMDB mdb = NULL;
   int ishtml, wasprotected = false;
   char *body;
-  
+
   hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
   if (SUCCEEDED (hr))
     {
-      err = mapi_get_gpgol_body_attachment (message, &body, NULL, 
-                                            &ishtml, &wasprotected);
-      if (!err && body)
+      if (mapi_get_message_type (message) == MSGTYPE_GPGOL_CLEAR_SIGNED)
         {
-          put_outlook_property (eecb, "GpgOLStatus", 
-                                mapi_get_sig_status (message));
-
-          update_display (hwnd, eecb, wasprotected, ishtml, body);
+          /* We used to display the clearsigned data in the processed
+             form, that is without the PGP lines and without the dash
+             escaping.  However, this poses the problem that the user
+             does not notice that he is viewing a mail which was
+             signed using a deprecated method and - far worse - it
+             might update the PR_BODY and thus all signature
+             information will get lost.  Of course we could save the
+             body away first like we do it with encrypted mails, but
+             that is too much overhead and GpgOL will always be
+             required to show such a message, which contrdicts the
+             very reason of clearsigned messages.  */
+          log_debug ("%s:%s: skipping display update for ClearSigned\n",
+                     SRCNAME, __func__);
         }
       else
         {
-          put_outlook_property (eecb, "GpgOLStatus", "?");
-          update_display (hwnd, NULL, 0, 0, 
-                          _("[Crypto operation failed - "
-                            "can't show the body of the message]"));
+          err = mapi_get_gpgol_body_attachment (message, &body, NULL, 
+                                                &ishtml, &wasprotected);
+          if (!err && body)
+            {
+              /* put_outlook_property (eecb, "GpgOLStatus",            */
+              /*                       mapi_get_sig_status (message)); */
+              
+              update_display (hwnd, eecb, wasprotected, ishtml, body);
+            }
+          else
+            {
+              /* put_outlook_property (eecb, "GpgOLStatus", "?"); */
+              update_display (hwnd, NULL, 0, 0, 
+                              _("[Crypto operation failed - "
+                                "can't show the body of the message]"));
+            }
+          xfree (body);
         }
-      xfree (body);
-  
     }
   else
     log_debug_w32 (hr, "%s:%s: error getting message", SRCNAME, __func__);
@@ -307,7 +325,10 @@
 /* Convert the clear signed message from INPUT into a PGP/MIME signed
    message and return it in a new allocated buffer.  OUTPUTLEN
    received the valid length of that buffer; the buffer is guaranteed
-   to be Nul terminated.  */
+   to be Nul terminated.  Note: Because we need to insert an empty
+   line to indicate the end of MIME headers, the signature won't
+   verify unless we tell the signature verification routine to skip
+   this first line.  */
 static char *
 pgp_mime_from_clearsigned (LPSTREAM input, size_t *outputlen)
 {
@@ -332,7 +353,7 @@
             "Content-Type: multipart/signed; boundary=\"%s\";\r\n"
             "              protocol=\"application/pgp-signature\"\r\n"
             "\r\n"
-            "--%s\r\n", boundary, boundary);
+            "--%s\r\n\r\n", boundary, boundary);
   snprintf (sig_header, sizeof sig_header,
             "--%s\r\n"
             "Content-Type: application/pgp-signature\r\n"
@@ -397,16 +418,19 @@
           while (*p && *p != '\n')
             {
               if (*p == ' ' || *p == '\t' || *p == '\r')
-                mark = p;
+                {
+                  if (!mark)
+                    mark = dest;
+                }
               else
                 mark = NULL;
               *dest++ = *p++;
             }
           if (mark)
-            *mark =0; /* Remove trailing white space.  */
+            dest = mark;
           if (*p == '\n')
             {
-              if (p[-1] == '\r')
+              if (p > p0 && p[-1] == '\r')
                 *dest++ = '\r';
               *dest++ = '\n';
             }
@@ -497,6 +521,7 @@
   size_t inbuflen = 0;
   protocol_t protocol = PROTOCOL_UNKNOWN;
   int err;
+  int mimehack = 0;
 
   switch (msgtype)
     {
@@ -560,6 +585,7 @@
       if (!inbuf)
         return -1;
       protocol = PROTOCOL_OPENPGP;
+      mimehack = 1; /* Required for our made up PGP/MIME.  */
     }
   else if (msgtype == MSGTYPE_GPGOL_OPAQUE_SIGNED)
     {
@@ -636,7 +662,7 @@
     err = mime_verify_opaque (protocol, opaquestream,
                               NULL, 0, message, hwnd, 0, 0);
   else
-    err = mime_verify (protocol, inbuf, inbuflen, message, hwnd, 0);
+    err = mime_verify (protocol, inbuf, inbuflen, message, hwnd, 0, mimehack);
   log_debug ("mime_verify%s returned %d", opaquestream? "_opaque":"", err);
   if (err && opt.enable_debug)
     {

Modified: trunk/src/mimeparser.c
===================================================================
--- trunk/src/mimeparser.c	2008-10-17 19:04:00 UTC (rev 273)
+++ trunk/src/mimeparser.c	2008-10-23 19:19:31 UTC (rev 274)
@@ -1168,9 +1168,12 @@
 
 
 
+/* FIXME: Needs documentation!
+
+   MIMEHACK make the verification code ignore the first two bytes.  */
 int
 mime_verify (protocol_t protocol, const char *message, size_t messagelen, 
-             LPMESSAGE mapi_message, HWND hwnd, int preview_mode)
+             LPMESSAGE mapi_message, HWND hwnd, int preview_mode, int mimehack)
 {
   gpg_error_t err = 0;
   mime_context_t ctx;
@@ -1241,7 +1244,7 @@
   /* Now actually verify the signature. */
   if (!err && ctx->signed_data && signature)
     {
-      gpgme_data_seek (ctx->signed_data, 0, SEEK_SET);
+      gpgme_data_seek (ctx->signed_data, mimehack? 2:0, SEEK_SET);
       
       if ((err=engine_create_filter (&filter, NULL, NULL)))
         goto leave;

Modified: trunk/src/mimeparser.h
===================================================================
--- trunk/src/mimeparser.h	2008-10-17 19:04:00 UTC (rev 273)
+++ trunk/src/mimeparser.h	2008-10-23 19:19:31 UTC (rev 274)
@@ -30,7 +30,7 @@
 
 int mime_verify (protocol_t protocol, const char *message, size_t messagelen, 
                  LPMESSAGE mapi_message, 
-                 HWND hwnd, int preview_mode);
+                 HWND hwnd, int preview_mode, int mimehack);
 int mime_verify_opaque (protocol_t protocol, LPSTREAM instream, 
                         const char *inbuffer, size_t inbufferlen,
                         LPMESSAGE mapi_message, HWND hwnd, int preview_mode,




More information about the Gnupg-commits mailing list